From d3a553444e5585d91267aa02ce6ed60552b5c727 Mon Sep 17 00:00:00 2001 From: malenov Date: Thu, 12 Dec 2024 14:52:00 +0100 Subject: [PATCH 0001/1221] add support for enforcement of modes/parameters through external binary files --- apps/encoder.c | 59 +++++++++++++++++++++++++++++- lib_com/options.h | 3 +- lib_debug/debug.c | 18 +++++++++ lib_debug/debug.h | 4 ++ lib_enc/ivas_core_pre_proc_front.c | 43 ++++++++++++++++++++++ lib_enc/ivas_cpe_enc.c | 3 ++ lib_enc/ivas_decision_matrix_enc.c | 9 +++++ lib_enc/ivas_stat_enc.h | 6 +++ lib_enc/ivas_stereo_classifier.c | 9 +++++ lib_enc/lib_enc.c | 26 +++++++++++++ lib_enc/lib_enc.h | 3 ++ lib_enc/stat_enc.h | 5 ++- 12 files changed, 184 insertions(+), 4 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index 98fb9aaa2..0eae15fc1 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -45,6 +45,20 @@ #include "masa_file_reader.h" #include "wmc_auto.h" +#ifdef DEBUG_FORCE_DIR +/* Windows does not define the S_ISREG and S_ISDIR macros in stat.h, so we do. + We have to define _CRT_INTERNAL_NONSTDC_NAMES 1 before #including sys/stat.h + in order for Microsoft's stat.h to define names like S_IFMT, S_IFREG, and S_IFDIR, + rather than just defining _S_IFMT, _S_IFREG, and _S_IFDIR as it normally does. */ +#include +#if !defined( S_ISREG ) && defined( S_IFMT ) && defined( S_IFREG ) +#define S_ISREG( m ) ( ( (m) &S_IFMT ) == S_IFREG ) +#endif +#if !defined( S_ISDIR ) && defined( S_IFMT ) && defined( S_IFDIR ) +#define S_ISDIR( m ) ( ( (m) &S_IFMT ) == S_IFDIR ) +#endif +#endif + #define WMC_TOOL_SKIP /*------------------------------------------------------------------------------------------* @@ -184,6 +198,9 @@ int main( int16_t *pcmBuf = NULL; #ifdef DEBUGGING FILE *f_forcedModeProfile = NULL; +#ifdef DEBUG_FORCE_DIR + bool f_forceModeDir = false; +#endif #endif #ifdef WMOPS @@ -529,15 +546,42 @@ int main( #ifdef DEBUGGING IVAS_ENC_FORCED_MODE forcedMode = arg.forcedMode; int32_t force_profile_cnt = 0; +#ifdef DEBUG_FORCE_DIR + struct stat path_stat; +#endif if ( arg.forcedModeFile ) { +#ifdef DEBUG_FORCE_DIR + if ( stat( arg.forcedModeFile, &path_stat ) != 0 ) + { + fprintf( stderr, "\nError: The profile file/dir could not be opened: %s\n\n", arg.forcedModeFile ); + usage_enc(); + goto cleanup; + } + + /* check if it is a directory */ + if ( S_ISDIR( path_stat.st_mode ) ) + { + f_forceModeDir = true; + } + else + { + if ( ( f_forcedModeProfile = fopen( arg.forcedModeFile, "rb" ) ) == NULL ) + { + fprintf( stderr, "\nError: Incorrect mode specification or the profile file could not be opened: %s\n\n", arg.forcedModeFile ); + usage_enc(); + goto cleanup; + } + } +#else if ( ( f_forcedModeProfile = fopen( arg.forcedModeFile, "rb" ) ) == NULL ) { fprintf( stderr, "\nError: Incorrect mode specification or the profile file could not be opened: %s\n\n", arg.forcedModeFile ); usage_enc(); goto cleanup; } +#endif } #endif @@ -685,9 +729,17 @@ int main( } /* Force mode not set when configuring, set in first frame even if not reading from file */ - if ( f_forcedModeProfile || frame == 0 ) + if ( f_forcedModeProfile || +#ifdef DEBUG_FORCE_DIR + f_forceModeDir || +#endif + frame == 0 ) { - if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode +#ifdef DEBUG_FORCE_DIR + , arg.forcedModeFile +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_ENC_SetForcedMode failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); goto cleanup; @@ -1798,6 +1850,9 @@ static void usage_enc( void ) #ifdef DEBUGGING fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" ); fprintf( stdout, " alternatively, T can be a text file where each line contains \"nb_frames T\"\n" ); +#ifdef DEBUG_FORCE_DIR + fprintf( stdout, " or T can be a directory containing external binary files for modes/parameters enforcement\n" ); +#endif #endif #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK diff --git a/lib_com/options.h b/lib_com/options.h index 5ad891b9b..e57bee05d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -49,7 +49,8 @@ #ifdef DEBUGGING #define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ #define DEBUG_MODE_INFO_TWEAK /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */ -#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ +#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ +#define DEBUG_FORCE_DIR /* Force modes/parameters by reading from external binary files */ /*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ #endif diff --git a/lib_debug/debug.c b/lib_debug/debug.c index f1cfa928a..2608be30a 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -363,6 +363,13 @@ int16_t dbgread( { index = in_count; in_fileptr[index] = fopen( filename, "rb" ); +#ifdef DEBUG_FORCE_DIR + if ( in_fileptr[index] == NULL ) + { + /* file does not exist or could not be opened -> just return */ + return -1; + } +#endif in_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); strcpy( in_filename[index], filename ); in_count++; @@ -773,8 +780,19 @@ char *fname( { char idd[5] = ".idX"; idd[3] = (char) ( id + '0' ); +#ifdef DEBUG_FORCE_DIR + short len; +#endif strcpy( tmp_fname, dir ); +#ifdef DEBUG_FORCE_DIR + len = strlen( tmp_fname ); + if (tmp_fname[len - 1] != '/' && tmp_fname[len - 1] != '\\' ) + { + /* add trailing '/' slash */ + strcat( tmp_fname, "/" ); + } +#endif strcat( tmp_fname, file ); if ( enc_dec == DEC ) diff --git a/lib_debug/debug.h b/lib_debug/debug.h index e88def922..c1c978bfe 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -66,6 +66,10 @@ extern char debug_dir[6]; char *fname( char *dir, char *file, const int16_t n, const int16_t id, const int16_t enc_dec ); #endif +#ifdef DEBUG_FORCE_DIR +#define FORCE_DIR_MAX_LENGTH 255 /* maximum length of the directory for modes/parameters enforcement */ +#endif + /*------------------------------------------------------------------------------------------* * Read/write I/O tool *------------------------------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 05848dc4c..5b36b6bad 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1617,6 +1617,15 @@ ivas_error pre_proc_front_ivas_fx( st->vad_flag = wb_vad_ivas_fx( st, fr_bands_fx, &i, &i, &i, &snr_sum_he_fx, &localVAD_HE_SAD, &( st->flag_noisy_speech_snr ), Q_new, NULL, NULL, -MAX_16, -MAX_16 ); //-100000f == max 16bit float move16(); +#ifdef DEBUG_FORCE_DIR + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, 1, "res/force_vad_flag.enf" ); + + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->vad_flag, sizeof( int16_t ), 1, fname( st->force_dir, "force_vad_flag.enf", -1, -1, -1 ) ); + } +#endif + test(); IF( EQ_16( force_front_vad, 1 ) || EQ_16( front_vad_flag, 1 ) ) { @@ -1694,6 +1703,16 @@ ivas_error pre_proc_front_ivas_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, 1, "res/force_bwidth.enf" ); + + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->bwidth, sizeof( int16_t ), 1, fname( st->force_dir, "force_bwidth.enf", -1, -1, -1 ) ); + } +#endif + + /*----------------------------------------------------------------* * Noise energy down-ward update and total noise energy estimation * Long-term energies and relative frame energy updates @@ -2340,6 +2359,15 @@ ivas_error pre_proc_front_ivas_fx( smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, Etot_fx, lsp_new_fx, *cor_map_sum_fx /*Q8*/, epsP_fx, PS_fx, non_staX_fx, *relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, *epsP_fx_q, hSpMusClas->past_PS_Q ); +#ifdef DEBUG_FORCE_DIR + dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc1.enf" ); + + if ( st->force_dir[0] != '\0' ) + { + dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc1.enf", -1, -1, -1 ) ); + } +#endif + #ifdef DEBUGGING if ( st->idchan == 0 ) { @@ -2533,6 +2561,21 @@ ivas_error pre_proc_front_ivas_fx( ivas_smc_mode_selection_fx( st, element_brate, smc_dec, *relE_fx, Etot_fx, attack_flag, inp_12k8_fx, Q_new, S_map_fx, flag_spitch ); } +#ifdef DEBUG_FORCE_DIR + dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc2.enf" ); + dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision0.enf" ); + dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision1.enf" ); + dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); + + if ( st->force_dir[0] != '\0' ) + { + dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc2.enf", -1, -1, -1 ) ); + dbgread( &st->sp_aud_decision0, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision0.enf", -1, -1, -1 ) ); + dbgread( &st->sp_aud_decision1, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision1.enf", -1, -1, -1 ) ); + dbgread( &st->sp_aud_decision2, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision2.enf", -1, -1, -1 ) ); + } +#endif + /*----------------------------------------------------------------* * Final VAD correction (when HE-SAD is used instead of the normal VAD, * rewrite the VAD flag by VAD flag with DTX hangover for further processing) diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index f40980db9..60cf33e8a 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -210,6 +210,9 @@ ivas_error ivas_cpe_enc_fx( #ifdef DEBUGGING sts[n]->force = hEncoderConfig->force; sts[n]->id_element = cpe_id + st_ivas->nSCE; +#ifdef DEBUG_FORCE_DIR + sts[n]->force_dir = hEncoderConfig->force_dir; +#endif #endif } diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index 1da1b2272..d02defa6e 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -559,6 +559,15 @@ void ivas_decision_matrix_enc_fx( } #endif +#ifdef DEBUG_FORCE_DIR + dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core.enf" ); + + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core.enf", -1, -1, -1 ) ); + } +#endif + /* TCX not available at low bitrates -> replace it by GSC */ test(); IF( EQ_16( st->core, TCX_20_CORE ) && LT_32( st->total_brate, STEREO_TCX_MIN_RATE ) ) diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 538362f3e..a0e65e586 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -39,6 +39,9 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "ivas_stat_com.h" +#ifdef DEBUG_FORCE_DIR +#include "debug.h" +#endif /*----------------------------------------------------------------------------------* * DFT Stereo encoder structures @@ -1810,6 +1813,9 @@ typedef struct encoder_config_structure int16_t stereo_mode_cmdl; /* stereo mode forced from the command-line */ int16_t force; /* parameter to force specific "core" of the Core-Coder*/ int16_t mdct_stereo_mode_cmdl; /* mdct stereo mode forced from command-line, employed only when DEBUG_FORCE_MDCT_STEREO_MODE is activated */ +#ifdef DEBUG_FORCE_DIR + char force_dir[FORCE_DIR_MAX_LENGTH]; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ +#endif #endif diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index b63cf8de3..220c2355c 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -230,6 +230,15 @@ Word16 select_stereo_mode( } } +#ifdef DEBUG_FORCE_DIR + dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); + + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); + } +#endif + /* switch from LRTD to DFT when xtalk_decision goes from 0->1 (note: this special case is not handled in the xtalk classifier) */ test(); test(); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 6c8ec4e29..135d3a8df 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -2359,6 +2359,9 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ +#ifdef DEBUG_FORCE_DIR + ,const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ +#endif ) { int16_t newForced; @@ -2370,6 +2373,28 @@ ivas_error IVAS_ENC_SetForcedMode( return error; } +#ifdef DEBUG_FORCE_DIR + if ( forcedModeDir == NULL ) + { + hIvasEnc->st_ivas->hEncoderConfig->force_dir[0] = '\0'; + + if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasEnc->st_ivas->hEncoderConfig->force != newForced ) + { + hIvasEnc->st_ivas->hEncoderConfig->force = newForced; + hIvasEnc->switchingActive = true; + } + } + else + { + strcpy( hIvasEnc->st_ivas->hEncoderConfig->force_dir, forcedModeDir ); + hIvasEnc->st_ivas->hEncoderConfig->force = IVAS_ENC_FORCE_UNFORCED; + } +#else if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) { return error; @@ -2380,6 +2405,7 @@ ivas_error IVAS_ENC_SetForcedMode( hIvasEnc->st_ivas->hEncoderConfig->force = newForced; hIvasEnc->switchingActive = true; } +#endif return IVAS_ERR_OK; } diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 03a0bee9e..41ffa4a10 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -340,6 +340,9 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ +#ifdef DEBUG_FORCE_DIR + ,const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ +#endif ); #endif diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 7a792ae0f..4d517e0bb 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1988,7 +1988,10 @@ typedef struct enc_core_structure int16_t low_rate_mode; /* low-rate mode flag */ int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ #ifdef DEBUGGING - int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ + int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ +#ifdef DEBUG_FORCE_DIR + char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ +#endif #endif Word16 nTimeSlots; /* for CLDFB */ -- GitLab From fbe043f58a61fb23772da24b755b8924a696667d Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 12 Dec 2024 15:44:08 +0100 Subject: [PATCH 0002/1221] clang format --- apps/encoder.c | 17 +++++++++-------- lib_enc/lib_enc.c | 3 ++- lib_enc/stat_enc.h | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index 0eae15fc1..c3ba40381 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -561,7 +561,7 @@ int main( } /* check if it is a directory */ - if ( S_ISDIR( path_stat.st_mode ) ) + if ( S_ISDIR( path_stat.st_mode ) ) { f_forceModeDir = true; } @@ -729,17 +729,18 @@ int main( } /* Force mode not set when configuring, set in first frame even if not reading from file */ - if ( f_forcedModeProfile || + if ( f_forcedModeProfile || #ifdef DEBUG_FORCE_DIR - f_forceModeDir || -#endif - frame == 0 ) + f_forceModeDir || +#endif + frame == 0 ) { if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode #ifdef DEBUG_FORCE_DIR - , arg.forcedModeFile -#endif - ) ) != IVAS_ERR_OK ) + , + arg.forcedModeFile +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_ENC_SetForcedMode failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); goto cleanup; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 135d3a8df..67b30a97e 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -2360,7 +2360,8 @@ ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ #ifdef DEBUG_FORCE_DIR - ,const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ + , + const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ #endif ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 4d517e0bb..9dd9d3346 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1988,9 +1988,9 @@ typedef struct enc_core_structure int16_t low_rate_mode; /* low-rate mode flag */ int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ #ifdef DEBUGGING - int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ + int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ #ifdef DEBUG_FORCE_DIR - char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ + char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ #endif #endif Word16 nTimeSlots; /* for CLDFB */ -- GitLab From 77ac6379f479db5728140d39734d9f15849e86be Mon Sep 17 00:00:00 2001 From: malenov Date: Thu, 12 Dec 2024 16:11:48 +0100 Subject: [PATCH 0003/1221] make fname() visible without DEUBG_MODE_INFO on --- lib_debug/debug.c | 4 ++-- lib_debug/debug.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_debug/debug.c b/lib_debug/debug.c index 2608be30a..8053a7cd9 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -758,7 +758,7 @@ int16_t tweakdbgfolder( const char *filename, char *filename_mod, int16_t *textm #endif -#ifdef DEBUG_MODE_INFO +#ifdef DEBUGGING /*-------------------------------------------------------------------* * fname() * @@ -781,7 +781,7 @@ char *fname( char idd[5] = ".idX"; idd[3] = (char) ( id + '0' ); #ifdef DEBUG_FORCE_DIR - short len; + size_t len; #endif strcpy( tmp_fname, dir ); diff --git a/lib_debug/debug.h b/lib_debug/debug.h index c1c978bfe..92c510147 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -60,7 +60,7 @@ extern int16_t debug_level; #define DEBUG_LINE( level ) if ( 0 ) #endif -#ifdef DEBUG_MODE_INFO +#ifdef DEBUGGING extern char tmp_fname[]; extern char debug_dir[6]; char *fname( char *dir, char *file, const int16_t n, const int16_t id, const int16_t enc_dec ); -- GitLab From d9b02f271b8b02363a16bb8ba6a92d8ab25a32c5 Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 14 Jan 2025 10:37:45 +0100 Subject: [PATCH 0004/1221] make read/write operations exclusive --- lib_enc/ivas_core_pre_proc_front.c | 30 +++++++++++++++++++----------- lib_enc/ivas_decision_matrix_enc.c | 6 ++++-- lib_enc/ivas_stereo_classifier.c | 6 ++++-- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index b9e72f8fa..74af17216 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -825,12 +825,14 @@ ivas_error pre_proc_front_ivas_fx( move16(); #ifdef DEBUG_FORCE_DIR - dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, 1, "res/force_vad_flag.enf" ); - if ( st->force_dir[0] != '\0' ) { dbgread( &st->vad_flag, sizeof( int16_t ), 1, fname( st->force_dir, "force_vad_flag.enf", -1, -1, -1 ) ); } + else + { + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, 1, "res/force_vad_flag.enf" ); + } #endif test(); @@ -911,12 +913,14 @@ ivas_error pre_proc_front_ivas_fx( } #ifdef DEBUG_FORCE_DIR - dbgwrite( &st->bwidth, sizeof( int16_t ), 1, 1, "res/force_bwidth.enf" ); - if ( st->force_dir[0] != '\0' ) { dbgread( &st->bwidth, sizeof( int16_t ), 1, fname( st->force_dir, "force_bwidth.enf", -1, -1, -1 ) ); } + else + { + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, 1, "res/force_bwidth.enf" ); + } #endif @@ -1511,12 +1515,14 @@ ivas_error pre_proc_front_ivas_fx( smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, Etot_fx, lsp_new_fx, *cor_map_sum_fx /*Q8*/, epsP_fx, PS_fx, non_staX_fx, *relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, *epsP_fx_q, hSpMusClas->past_PS_Q ); /* Q0 */ #ifdef DEBUG_FORCE_DIR - dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc1.enf" ); - if ( st->force_dir[0] != '\0' ) { dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc1.enf", -1, -1, -1 ) ); } + else + { + dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc1.enf" ); + } #endif #ifdef DEBUGGING @@ -1726,11 +1732,6 @@ ivas_error pre_proc_front_ivas_fx( } #ifdef DEBUG_FORCE_DIR - dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc2.enf" ); - dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision0.enf" ); - dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision1.enf" ); - dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); - if ( st->force_dir[0] != '\0' ) { dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc2.enf", -1, -1, -1 ) ); @@ -1738,6 +1739,13 @@ ivas_error pre_proc_front_ivas_fx( dbgread( &st->sp_aud_decision1, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision1.enf", -1, -1, -1 ) ); dbgread( &st->sp_aud_decision2, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision2.enf", -1, -1, -1 ) ); } + else + { + dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc2.enf" ); + dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision0.enf" ); + dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision1.enf" ); + dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); + } #endif /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index b46361fc2..cb3248b93 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -256,12 +256,14 @@ void ivas_decision_matrix_enc_fx( #endif #ifdef DEBUG_FORCE_DIR - dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core.enf" ); - if ( st->force_dir[0] != '\0' ) { dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core.enf", -1, -1, -1 ) ); } + else + { + dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core.enf" ); + } #endif /* TCX not available at low bitrates -> replace it by GSC */ diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index 8391d99a2..96754c97d 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -218,12 +218,14 @@ Word16 select_stereo_mode( } #ifdef DEBUG_FORCE_DIR - dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) { dbgread( &element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); } + else + { + dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); + } #endif /* switch from LRTD to DFT when xtalk_decision goes from 0->1 (note: this special case is not handled in the xtalk classifier) */ -- GitLab From ebc2a47326dd706b0e4b2c7d97306908516a7560 Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 14 Jan 2025 10:43:42 +0100 Subject: [PATCH 0005/1221] force_element_mode.enf - read/write info in frame 0 --- lib_enc/ivas_cpe_enc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index e93d3caa0..7b7ab41bf 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -263,6 +263,19 @@ ivas_error ivas_cpe_enc_fx( { hCPE->element_mode = select_stereo_mode( hCPE, ivas_format ); /* Q0 */ } +#ifdef DEBUG_FORCE_DIR + else + { + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hCPE->element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); + } + } +#endif stereo_mode_combined_format_enc_fx( st_ivas, hCPE ); -- GitLab From 7611d58044dcbc5c657024208c4d55c6801342f2 Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 14 Jan 2025 15:56:11 +0100 Subject: [PATCH 0006/1221] fix the I/O interface --- apps/encoder.c | 3 +++ lib_enc/ivas_decision_matrix_enc.c | 26 ++++++++++++++++++++++++++ lib_enc/lib_enc.c | 4 ++-- lib_enc/lib_enc.h | 4 ++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index 4e7d55bce..36ba0bcd7 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -149,6 +149,9 @@ typedef struct #ifdef DEBUGGING IVAS_ENC_FORCED_MODE forcedMode; const char *forcedModeFile; +#ifdef DEBUG_FORCE_DIR + const char *forcedModeDir; +#endif #endif bool pca; bool ism_extended_metadata; diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index cb3248b93..08ce3cd21 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -354,6 +354,19 @@ void ivas_decision_matrix_enc_fx( } } } + +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->extl, sizeof( int16_t ), 1, fname( st->force_dir, "force_extl.enf", -1, -1, -1 ) ); + dbgread( &st->extl_brate, sizeof( int32_t ), 1, fname( st->force_dir, "force_extl_brate.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->extl, sizeof( int16_t ), 1, 1, "res/force_extl.enf" ); + dbgwrite( &st->extl_brate, sizeof( int32_t ), 1, 1, "res/force_extl_brate.enf" ); + } +#endif } /* SWB and FB */ @@ -451,6 +464,19 @@ void ivas_decision_matrix_enc_fx( move32(); } +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->extl, sizeof( int16_t ), 1, fname( st->force_dir, "force_extl.enf", -1, -1, -1 ) ); + dbgread( &st->extl_brate, sizeof( int32_t ), 1, fname( st->force_dir, "force_extl_brate.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->extl, sizeof( int16_t ), 1, 1, "res/force_extl.enf" ); + dbgwrite( &st->extl_brate, sizeof( int32_t ), 1, 1, "res/force_extl_brate.enf" ); + } +#endif + /* set IC-BWE bitrate */ test(); test(); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 63efaafb8..26fc04a5e 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1888,7 +1888,7 @@ ivas_error IVAS_ENC_SetForcedMode( } #ifdef DEBUG_FORCE_DIR - if ( forcedModeDir == NULL ) + if ( forcedMode < IVAS_ENC_FORCE_FILE ) { hIvasEnc->st_ivas->hEncoderConfig->force_dir[0] = '\0'; @@ -1903,7 +1903,7 @@ ivas_error IVAS_ENC_SetForcedMode( hIvasEnc->switchingActive = true; } } - else + else if ( forcedMode == IVAS_ENC_FORCE_DIR ) { strcpy( hIvasEnc->st_ivas->hEncoderConfig->force_dir, forcedModeDir ); hIvasEnc->st_ivas->hEncoderConfig->force = IVAS_ENC_FORCE_UNFORCED; diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 09262079b..69f794b69 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -129,6 +129,10 @@ typedef enum _IVAS_ENC_FORCED_MODE IVAS_ENC_FORCE_GSC, IVAS_ENC_FORCE_TCX, IVAS_ENC_FORCE_HQ, +#ifdef DEBUG_FORCE_DIR + IVAS_ENC_FORCE_FILE, + IVAS_ENC_FORCE_DIR, +#endif IVAS_ENC_FORCE_UNFORCED, IVAS_ENC_FORCE_UNDEFINED = 0xffff } IVAS_ENC_FORCED_MODE; -- GitLab From ffeb27b7a9395e71b2d08ef43af6d9c4373fae0a Mon Sep 17 00:00:00 2001 From: mave2802 <59919483+mave2802@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:13:32 +0100 Subject: [PATCH 0007/1221] increased accuracy for mixing matrix calculation by using seperate scalefactors for ref_power and cx_diag for each freq band (to avoid holes especially in the upper freq band region) --- lib_dec/ivas_ism_param_dec.c | 91 ++++++++++++------------------------ 1 file changed, 31 insertions(+), 60 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 9514e5e2a..5eaae88fe 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -177,25 +177,17 @@ static void ivas_param_ism_collect_slot_fx( Word16 exp_imag, const Word16 ch, Word32 ref_power_fx[], /*Q(31-exp_ref_power)*/ - Word16 *exp_ref_power, + Word16 exp_ref_power[], Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-exp_cx_diag)*/ - Word16 *exp_cx_diag ) + Word16 exp_cx_diag[][PARAM_ISM_MAX_DMX] ) { Word16 band_idx, bin_idx; Word16 brange[2]; Word32 tmp_fx; Word16 exp_tmp; - Word16 i, j; /* loop over parameter bands to collect transport channel energies */ - Word16 exp_ref_power_buf[CLDFB_NO_CHANNELS_MAX]; - Word16 exp_cx_diag_buf[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; - set16_fx( exp_ref_power_buf, *exp_ref_power, CLDFB_NO_CHANNELS_MAX ); - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - set16_fx( exp_cx_diag_buf[i], *exp_cx_diag, PARAM_ISM_MAX_DMX ); - } FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) { brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; @@ -216,50 +208,19 @@ static void ivas_param_ism_collect_slot_fx( Word16 exp_cx_diag_new = 0, exp_ref_power_new = 0; move16(); move16(); - cx_diag_fx[bin_idx][ch] = BASOP_Util_Add_Mant32Exp( cx_diag_fx[bin_idx][ch], exp_cx_diag_buf[bin_idx][ch], tmp_fx, exp_tmp, &exp_cx_diag_new ); + cx_diag_fx[bin_idx][ch] = BASOP_Util_Add_Mant32Exp( cx_diag_fx[bin_idx][ch], exp_cx_diag[bin_idx][ch], tmp_fx, exp_tmp, &exp_cx_diag_new ); move32(); - ref_power_fx[bin_idx] = BASOP_Util_Add_Mant32Exp( ref_power_fx[bin_idx], exp_ref_power_buf[bin_idx], tmp_fx, exp_tmp, &exp_ref_power_new ); + ref_power_fx[bin_idx] = BASOP_Util_Add_Mant32Exp( ref_power_fx[bin_idx], exp_ref_power[bin_idx], tmp_fx, exp_tmp, &exp_ref_power_new ); move32(); - exp_cx_diag_buf[bin_idx][ch] = exp_cx_diag_new; + exp_cx_diag[bin_idx][ch] = exp_cx_diag_new; move16(); - exp_ref_power_buf[bin_idx] = exp_ref_power_new; + exp_ref_power[bin_idx] = exp_ref_power_new; move16(); } } - - /*make common exponent*/ - Word16 max_exp_cx_diag = exp_cx_diag_buf[0][0], max_exp_ref_power = exp_ref_power_buf[0]; - move16(); - move16(); - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - FOR( j = 0; j < PARAM_ISM_MAX_DMX; j++ ) - { - max_exp_cx_diag = s_max( max_exp_cx_diag, exp_cx_diag_buf[i][j] ); - } - max_exp_ref_power = s_max( max_exp_ref_power, exp_ref_power_buf[i] ); - } - - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - FOR( j = 0; j < PARAM_ISM_MAX_DMX; j++ ) - { - cx_diag_fx[i][j] = L_shr_r( cx_diag_fx[i][j], sub( max_exp_cx_diag, exp_cx_diag_buf[i][j] ) ); // Q(31-max_exp_cx_diag) - move32(); - } - ref_power_fx[i] = L_shr_r( ref_power_fx[i], sub( max_exp_ref_power, exp_ref_power_buf[i] ) ); // Q(31-max_exp_ref_power) - move16(); - } - - *exp_cx_diag = max_exp_cx_diag; - move16(); - *exp_ref_power = max_exp_ref_power; - move16(); - return; } - static void ivas_param_ism_compute_mixing_matrix_fx( const Word16 nchan_ism, /* i : number of ISM channels */ PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */ @@ -268,9 +229,9 @@ static void ivas_param_ism_compute_mixing_matrix_fx( const Word16 nchan_transport, const Word16 nchan_out_woLFE, Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-cx_diag_e)*/ - Word16 cx_diag_e, + Word16 cx_diag_e[][PARAM_ISM_MAX_DMX], Word32 ref_power_fx[], /*Q(31-ref_power_e)*/ - Word16 ref_power_e, + Word16 ref_power_e[], Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-mixing_matrix_e)*/ Word16 mixing_matrix_e[CLDFB_NO_CHANNELS_MAX] ) { @@ -367,10 +328,10 @@ static void ivas_param_ism_compute_mixing_matrix_fx( } ELSE { - direct_power_fx[w] = Mpy_32_16_1( ref_power_fx[bin_idx], hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e) + direct_power_fx[w] = Mpy_32_16_1( ref_power_fx[bin_idx], hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e[bin_idx]) move32(); } - direct_power_e = ref_power_e; + direct_power_e = ref_power_e[bin_idx]; move16(); IF( direct_power_fx[w] != 0 ) { @@ -409,8 +370,20 @@ static void ivas_param_ism_compute_mixing_matrix_fx( move32(); } + /* equal cx diag exponents */ + Word16 max_exp_cx_diag = cx_diag_e[bin_idx][0]; + Word32 cx_diag_eq_exp_fx[PARAM_ISM_MAX_DMX]; + FOR( i = 1; i < PARAM_ISM_MAX_DMX; i++ ) + { + max_exp_cx_diag = s_max( max_exp_cx_diag, cx_diag_e[bin_idx][i] ); + } + FOR( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) + { + cx_diag_eq_exp_fx[i] = L_shr_r( cx_diag_fx[bin_idx][i], sub( max_exp_cx_diag, cx_diag_e[bin_idx][i] ) ); // Q(31-max_exp_cx_diag) + } + /* Compute mixing matrix */ - computeMixingMatricesISM_fx( nchan_transport, num_wave, nchan_out_woLFE, response_matrix_fx, response_matrix_e, direct_power_fx, direct_power_e, cx_diag_fx[bin_idx], cx_diag_e, cy_diag_fx, cy_diag_e, proto_matrix_fx, 1, + computeMixingMatricesISM_fx( nchan_transport, num_wave, nchan_out_woLFE, response_matrix_fx, response_matrix_e, direct_power_fx, direct_power_e, cx_diag_eq_exp_fx, max_exp_cx_diag, cy_diag_fx, cy_diag_e, proto_matrix_fx, 1, PARAM_MC_REG_SX_FX, PARAM_MC_REG_GHAT_FX, mixing_matrix_fx[bin_idx], &mixing_matrix_e[bin_idx] ); } } @@ -1070,7 +1043,6 @@ void ivas_param_ism_dec_digest_tc_fx( Word32 *transport_channels[], /* i : synthesized core-coder transport channels/DirAC output q_tc_in*/ Word16 q_tc_in ) { - Word16 exp_ref_power = 31, exp_cx_diag = 31; Word16 exp_real_tmp = 0, exp_imag_tmp = 0; move16(); move16(); @@ -1078,6 +1050,9 @@ void ivas_param_ism_dec_digest_tc_fx( move16(); Word32 ref_power_fx[CLDFB_NO_CHANNELS_MAX]; Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 exp_ref_power[CLDFB_NO_CHANNELS_MAX]; + Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 q_tc = q_tc_in; move16(); Word16 ch, nchan_transport, nchan_out, nchan_out_woLFE, i; @@ -1132,15 +1107,11 @@ void ivas_param_ism_dec_digest_tc_fx( ivas_dirac_dec_set_md_map_fx( st_ivas, nCldfbSlots ); /* set buffers to zero */ - FOR( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) - { - set_zero_fx( cx_diag_fx[bin_idx], PARAM_ISM_MAX_DMX ); - } - exp_cx_diag = 0; - move16(); + set_zero_fx(&cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX); + set16_zero_fx(&exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX); + set_zero_fx( ref_power_fx, CLDFB_NO_CHANNELS_MAX ); - exp_ref_power = 0; - move16(); + set16_zero_fx(&exp_ref_power[0], CLDFB_NO_CHANNELS_MAX); /* Frame-level Processing */ /* De-quantization */ @@ -1269,7 +1240,7 @@ void ivas_param_ism_dec_digest_tc_fx( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], exp_imag_tmp, ch, - ref_power_fx, &exp_ref_power, cx_diag_fx, &exp_cx_diag ); + ref_power_fx, exp_ref_power, cx_diag_fx, exp_cx_diag ); exp_real_tmp = add( exp_real_tmp, scale_factor_real ); exp_imag_tmp = add( exp_imag_tmp, scale_factor_imag ); -- GitLab From d9b2947a16fb0a0730687088c92cfc13f181b001 Mon Sep 17 00:00:00 2001 From: mave2802 <59919483+mave2802@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:26:20 +0100 Subject: [PATCH 0008/1221] complexity reductions --- lib_dec/ivas_ism_param_dec.c | 65 +++++++++++++++++------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 5eaae88fe..10f384638 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -176,8 +176,6 @@ static void ivas_param_ism_collect_slot_fx( Word32 *Cldfb_ImagBuffer_in_fx, /*Q(31-exp_imag)*/ Word16 exp_imag, const Word16 ch, - Word32 ref_power_fx[], /*Q(31-exp_ref_power)*/ - Word16 exp_ref_power[], Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-exp_cx_diag)*/ Word16 exp_cx_diag[][PARAM_ISM_MAX_DMX] ) { @@ -205,17 +203,13 @@ static void ivas_param_ism_collect_slot_fx( tmp_fx = BASOP_Util_Add_Mant32Exp( tmp_fx, exp_tmp, var1, add( exp_real, exp_real ), &exp_tmp ); tmp_fx = BASOP_Util_Add_Mant32Exp( tmp_fx, exp_tmp, var2, add( exp_imag, exp_imag ), &exp_tmp ); - Word16 exp_cx_diag_new = 0, exp_ref_power_new = 0; + Word16 exp_cx_diag_new; move16(); move16(); cx_diag_fx[bin_idx][ch] = BASOP_Util_Add_Mant32Exp( cx_diag_fx[bin_idx][ch], exp_cx_diag[bin_idx][ch], tmp_fx, exp_tmp, &exp_cx_diag_new ); move32(); - ref_power_fx[bin_idx] = BASOP_Util_Add_Mant32Exp( ref_power_fx[bin_idx], exp_ref_power[bin_idx], tmp_fx, exp_tmp, &exp_ref_power_new ); - move32(); exp_cx_diag[bin_idx][ch] = exp_cx_diag_new; move16(); - exp_ref_power[bin_idx] = exp_ref_power_new; - move16(); } } return; @@ -230,8 +224,6 @@ static void ivas_param_ism_compute_mixing_matrix_fx( const Word16 nchan_out_woLFE, Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-cx_diag_e)*/ Word16 cx_diag_e[][PARAM_ISM_MAX_DMX], - Word32 ref_power_fx[], /*Q(31-ref_power_e)*/ - Word16 ref_power_e[], Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-mixing_matrix_e)*/ Word16 mixing_matrix_e[CLDFB_NO_CHANNELS_MAX] ) { @@ -304,6 +296,27 @@ static void ivas_param_ism_compute_mixing_matrix_fx( set32_fx( cy_diag_fx, 0, nchan_out_woLFE ); set16_fx( cy_diag_e_arr, 0, nchan_out_woLFE ); + + /* equal cx diag exponents, compute ref power from cx_diag*/ + Word16 max_exp_cx_diag; + Word32 cx_diag_eq_exp_fx[PARAM_ISM_MAX_DMX]; + Word32 ref_power_fx; + Word16 ref_power_e, ref_power_e_new; + ref_power_fx = cx_diag_fx[bin_idx][0]; + ref_power_e = cx_diag_e[bin_idx][0]; + + FOR( i = 1; i < PARAM_ISM_MAX_DMX; i++ ) + { + ref_power_fx = BASOP_Util_Add_Mant32Exp( ref_power_fx, ref_power_e, cx_diag_fx[bin_idx][i], cx_diag_e[bin_idx][i], &ref_power_e_new ); + ref_power_e = ref_power_e_new; + } + max_exp_cx_diag = ref_power_e; + FOR( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) + { + cx_diag_eq_exp_fx[i] = L_shr_r( cx_diag_fx[bin_idx][i], sub( max_exp_cx_diag, cx_diag_e[bin_idx][i] ) ); // Q(31-max_exp_cx_diag) + } + + FOR( w = 0; w < num_wave; w++ ) { test(); @@ -313,25 +326,26 @@ static void ivas_param_ism_compute_mixing_matrix_fx( SWITCH( nchan_ism ) { case 2: - direct_power_fx[w] = L_shr_r( ref_power_fx[bin_idx], 1 ); + direct_power_fx[w] = L_shr_r( ref_power_fx, 1 ); move32(); BREAK; case 3: - direct_power_fx[w] = Mpy_32_16_1( ref_power_fx[bin_idx], 10923 ); // 10923 = 1/3f in Q15 + direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, 10923 ); // 10923 = 1/3f in Q15 move32(); BREAK; case 4: - direct_power_fx[w] = L_shr_r( ref_power_fx[bin_idx], 2 ); + direct_power_fx[w] = L_shr_r( ref_power_fx, 2 ); move32(); BREAK; } } ELSE { - direct_power_fx[w] = Mpy_32_16_1( ref_power_fx[bin_idx], hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e[bin_idx]) + direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e[bin_idx]) move32(); } - direct_power_e = ref_power_e[bin_idx]; + //direct_power_e = ref_power_e[bin_idx]; + direct_power_e = ref_power_e; move16(); IF( direct_power_fx[w] != 0 ) { @@ -370,18 +384,6 @@ static void ivas_param_ism_compute_mixing_matrix_fx( move32(); } - /* equal cx diag exponents */ - Word16 max_exp_cx_diag = cx_diag_e[bin_idx][0]; - Word32 cx_diag_eq_exp_fx[PARAM_ISM_MAX_DMX]; - FOR( i = 1; i < PARAM_ISM_MAX_DMX; i++ ) - { - max_exp_cx_diag = s_max( max_exp_cx_diag, cx_diag_e[bin_idx][i] ); - } - FOR( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) - { - cx_diag_eq_exp_fx[i] = L_shr_r( cx_diag_fx[bin_idx][i], sub( max_exp_cx_diag, cx_diag_e[bin_idx][i] ) ); // Q(31-max_exp_cx_diag) - } - /* Compute mixing matrix */ computeMixingMatricesISM_fx( nchan_transport, num_wave, nchan_out_woLFE, response_matrix_fx, response_matrix_e, direct_power_fx, direct_power_e, cx_diag_eq_exp_fx, max_exp_cx_diag, cy_diag_fx, cy_diag_e, proto_matrix_fx, 1, PARAM_MC_REG_SX_FX, PARAM_MC_REG_GHAT_FX, mixing_matrix_fx[bin_idx], &mixing_matrix_e[bin_idx] ); @@ -1048,9 +1050,7 @@ void ivas_param_ism_dec_digest_tc_fx( move16(); move16(); move16(); - Word32 ref_power_fx[CLDFB_NO_CHANNELS_MAX]; - Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; - Word16 exp_ref_power[CLDFB_NO_CHANNELS_MAX]; + Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; Word16 q_tc = q_tc_in; @@ -1110,9 +1110,6 @@ void ivas_param_ism_dec_digest_tc_fx( set_zero_fx(&cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX); set16_zero_fx(&exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX); - set_zero_fx( ref_power_fx, CLDFB_NO_CHANNELS_MAX ); - set16_zero_fx(&exp_ref_power[0], CLDFB_NO_CHANNELS_MAX); - /* Frame-level Processing */ /* De-quantization */ test(); @@ -1240,7 +1237,7 @@ void ivas_param_ism_dec_digest_tc_fx( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], exp_imag_tmp, ch, - ref_power_fx, exp_ref_power, cx_diag_fx, exp_cx_diag ); + cx_diag_fx, exp_cx_diag ); exp_real_tmp = add( exp_real_tmp, scale_factor_real ); exp_imag_tmp = add( exp_imag_tmp, scale_factor_imag ); @@ -1255,7 +1252,7 @@ void ivas_param_ism_dec_digest_tc_fx( } /* Compute mixing matrix */ - ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, ref_power_fx, exp_ref_power, + ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx ); pop_wmops(); -- GitLab From d86fd6130c852a67591e3fcf320433f11a4a3956 Mon Sep 17 00:00:00 2001 From: mave2802 <59919483+mave2802@users.noreply.github.com> Date: Thu, 23 Jan 2025 09:20:03 +0100 Subject: [PATCH 0009/1221] clang format --- lib_dec/ivas_ism_param_dec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 10f384638..c7fce8dd5 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -344,7 +344,7 @@ static void ivas_param_ism_compute_mixing_matrix_fx( direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e[bin_idx]) move32(); } - //direct_power_e = ref_power_e[bin_idx]; + // direct_power_e = ref_power_e[bin_idx]; direct_power_e = ref_power_e; move16(); IF( direct_power_fx[w] != 0 ) @@ -1050,8 +1050,8 @@ void ivas_param_ism_dec_digest_tc_fx( move16(); move16(); move16(); - Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; - Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; Word16 q_tc = q_tc_in; move16(); @@ -1107,8 +1107,8 @@ void ivas_param_ism_dec_digest_tc_fx( ivas_dirac_dec_set_md_map_fx( st_ivas, nCldfbSlots ); /* set buffers to zero */ - set_zero_fx(&cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX); - set16_zero_fx(&exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX); + set_zero_fx( &cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX ); + set16_zero_fx( &exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX ); /* Frame-level Processing */ /* De-quantization */ -- GitLab From b9a68dac1db96f835c597b26b4cc05ce49219174 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 23 Jan 2025 16:49:02 +0100 Subject: [PATCH 0010/1221] Add manual job for PEAQ encoder passthrough --- .gitlab-ci.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f62acb284..f9c890019 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,6 +47,7 @@ variables: - 'complexity' - 'coverage' - 'voip-be-test' + - 'peaq-enc-passthrough' default: @@ -95,6 +96,9 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'voip-be-test' variables: IVAS_PIPELINE_NAME: 'Voip BE test on $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'peaq-enc-passthrough' + variables: + IVAS_PIPELINE_NAME: 'PEAQ encoder pass-through test: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'schedule' # Scheduled in any branch variables: IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' @@ -1172,6 +1176,16 @@ ivas-pytest-renderer: - LEVEL_SCALING=1.0 <<: *ivas-pytest-anchor +peaq-enc-passthrough: + extends: + - .test-job-linux + rules: + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "peaq-enc-passthrough" + before_script: + - USE_LTV=0 + - TEST_SUITE="tests/test_enc_passthrough.py" + - LEVEL_SCALING=1.0 + <<: *ivas-pytest-anchor # --------------------------------------------------------------- # Various other tests -- GitLab From 5c80b92c1fb1f92bcfa72e03d08e28c7627559bf Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 23 Jan 2025 19:49:19 +0100 Subject: [PATCH 0011/1221] Fix in peaq-enc-passthrough --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f9c890019..9a9e1efb5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1183,6 +1183,7 @@ peaq-enc-passthrough: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "peaq-enc-passthrough" before_script: - USE_LTV=0 + - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="tests/test_enc_passthrough.py" - LEVEL_SCALING=1.0 <<: *ivas-pytest-anchor -- GitLab From d9575b5e78594cc6147889de70ebdd76cfccb1ed Mon Sep 17 00:00:00 2001 From: norvell Date: Thu, 30 Jan 2025 09:09:38 +0000 Subject: [PATCH 0012/1221] Set BASOP_CI_BRANCH_PC_REPO: "ci/bring-back-per-channel-odg" for testing of both PEAQ measurements in parallel --- .gitlab-ci.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9a9e1efb5..ebf6a3e91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ variables: REF_DECODER_PATH: "./IVAS_dec_ref" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" + BASOP_CI_BRANCH_PC_REPO: "ci/bring-back-per-channel-odg" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 @@ -32,6 +32,7 @@ variables: INSTR_DIR: "scripts/c-code_instrument" BUILD_WITH_DEBUG_MODE_INFO: "" ENCODER_TEST: "" + DELTA_ODG: "" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -314,9 +315,13 @@ stages: - *build-and-create-reference-outputs - comp_args="--mld --ssnr --odg" + - summary_args="MLD DIFF SSNR ODG" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi + - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG";fi - echo "$comp_args" + + ### run pytest - exit_code=0 - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? @@ -324,7 +329,7 @@ stages: - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME - mkdir $IMAGES_ARTIFACT_NAME - - for MEASURE in MLD DIFF SSNR ODG;do python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done + - for MEASURE in $summary_args;do python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME - if [ $USE_LTV -eq 1 ] && [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then @@ -1185,6 +1190,7 @@ peaq-enc-passthrough: - USE_LTV=0 - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="tests/test_enc_passthrough.py" + - DELTA_ODG="true" - LEVEL_SCALING=1.0 <<: *ivas-pytest-anchor -- GitLab From bd35dc1b3f7602aec02ac9577a04d2cbd8c1fc70 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 30 Jan 2025 12:40:22 +0100 Subject: [PATCH 0013/1221] Fix for parse_xml_report.py call --- .gitlab-ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ebf6a3e91..3c912285e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -316,18 +316,17 @@ stages: - comp_args="--mld --ssnr --odg" - summary_args="MLD DIFF SSNR ODG" + - ="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG";fi + - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - echo "$comp_args" - - ### run pytest - exit_code=0 - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME + - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME $REPORT_ARG - mkdir $IMAGES_ARTIFACT_NAME - for MEASURE in $summary_args;do python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME -- GitLab From f10b357e0b4c0bd06d7eb5d70863708e968ecb9d Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 30 Jan 2025 12:54:23 +0100 Subject: [PATCH 0014/1221] Fix syntax error --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c912285e..d5f6294f8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -316,7 +316,7 @@ stages: - comp_args="--mld --ssnr --odg" - summary_args="MLD DIFF SSNR ODG" - - ="" + - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - echo "$comp_args" -- GitLab From 2758b2ff44fa41e982a4754f010901a5458e2c5e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 30 Jan 2025 13:02:07 +0100 Subject: [PATCH 0015/1221] changes for eaasier debugging --- .gitlab-ci.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f62acb284..b73c26c61 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -291,6 +291,7 @@ stages: SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" script: + - set -euxo pipefail - *print-common-info - *update-scripts-repo - if [ $USE_LTV -eq 1 ]; then @@ -302,15 +303,19 @@ stages: - fi - python3 ci/remove_unsupported_testcases.py $PRM_FILES - - if [ $LEVEL_SCALING != "1.0" ];then + - if [ $LEVEL_SCALING != "1.0" ]; then - *apply-testv-scaling - fi - - if [ "$ENCODER_TEST" = "true" ]; then BUILD_WITH_DEBUG_MODE_INFO="true"; fi + - if [ "$ENCODER_TEST" = "true" ]; then + - BUILD_WITH_DEBUG_MODE_INFO="true" + - fi - *build-and-create-reference-outputs - comp_args="--mld --ssnr --odg" - - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi + - if [ "$ENCODER_TEST" = "true" ]; then + - comp_args="${comp_args} --enc_stats" + - fi - echo "$comp_args" ### run pytest -- GitLab From 2b6c98a54bef36c15a0d77674845d129d78d363e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 30 Jan 2025 15:03:46 +0100 Subject: [PATCH 0016/1221] add manual job for encoder downmix comparison --- .gitlab-ci.yml | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b73c26c61..60568840f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,12 +32,14 @@ variables: INSTR_DIR: "scripts/c-code_instrument" BUILD_WITH_DEBUG_MODE_INFO: "" ENCODER_TEST: "" + COMPARE_DMX: "" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' options: - 'default' - 'pytest-compare' + - 'pytest-compare-dmx' - 'pytest-compare-long' - 'pytest-compare-to-input' - 'pytest-saturation-smoke-test' @@ -222,6 +224,14 @@ stages: - if: $CI_PIPELINE_SOURCE == 'schedule' when: never +.rules-pytest-to-ref-enc-sort-dmx: + rules: + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare-dmx" + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + - if: $CI_PIPELINE_SOURCE == 'schedule' + when: never + .rules-pytest-to-main-short: rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main @@ -316,6 +326,11 @@ stages: - if [ "$ENCODER_TEST" = "true" ]; then - comp_args="${comp_args} --enc_stats" - fi + + # DMX comparison only in manual job with no other metrics + - if [ "$COMPARE_DMX" = "true" ]; then + - comp_args="--compare_enc_dmx" + - fi - echo "$comp_args" ### run pytest @@ -825,7 +840,7 @@ ivas-pytest-compare_to_ref-short-enc-lev-10: extends: #- .rules-pytest-to-ref-short - .rules-pytest-to-ref-enc-short-temp - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=0 - ENCODER_TEST="true" @@ -838,10 +853,50 @@ ivas-pytest-compare_to_ref-short-enc-lev+10: extends: #- .rules-pytest-to-ref-short - .rules-pytest-to-ref-enc-short-temp - - .test-job-linux + - .test-job-linux + before_script: + - USE_LTV=0 + - ENCODER_TEST="true" + - DUT_DECODER_PATH=./$REF_DECODER_PATH + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=3.162 + <<: *ivas-pytest-anchor + +# encoder dmx comparison jobs +ivas-pytest-compare_to_ref-dmx-short-enc: + extends: + - .rules-pytest-to-ref-enc-sort-dmx + - .test-job-linux + before_script: + - USE_LTV=0 + - ENCODER_TEST="true" + - COMPARE_DMX="true + - DUT_DECODER_PATH=./$REF_DECODER_PATH + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=1.0 + <<: *ivas-pytest-anchor + +ivas-pytest-compare_to_ref-dmx-short-enc-lev-10: + extends: + - .rules-pytest-to-ref-enc-sort-dmx + - .test-job-linux + before_script: + - USE_LTV=0 + - ENCODER_TEST="true" + - COMPARE_DMX="true + - DUT_DECODER_PATH=./$REF_DECODER_PATH + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=0.3162 + <<: *ivas-pytest-anchor + +ivas-pytest-compare_to_ref-dmx-short-enc-lev+10: + extends: + - .rules-pytest-to-ref-enc-sort-dmx + - .test-job-linux before_script: - USE_LTV=0 - ENCODER_TEST="true" + - COMPARE_DMX="true - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 -- GitLab From 6d7f0d619e3d0d4f8ba31fb6ea0605df17d1930e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 30 Jan 2025 15:05:53 +0100 Subject: [PATCH 0017/1221] fix workflow rules --- .gitlab-ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 60568840f..babe65e8e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ variables: options: - 'default' - 'pytest-compare' - - 'pytest-compare-dmx' + - 'pytest-compare-enc-dmx' - 'pytest-compare-long' - 'pytest-compare-to-input' - 'pytest-saturation-smoke-test' @@ -73,6 +73,9 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare' variables: IVAS_PIPELINE_NAME: 'Run comparison tools against float ref: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare-enc-dmx' + variables: + IVAS_PIPELINE_NAME: 'Run encoder dmx comparison against float ref: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare-long' variables: IVAS_PIPELINE_NAME: 'Run comparison tools against float ref (long test vectors): $CI_COMMIT_BRANCH' @@ -226,7 +229,7 @@ stages: .rules-pytest-to-ref-enc-sort-dmx: rules: - - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare-dmx" + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare-enc-dmx" - if: $CI_PIPELINE_SOURCE == 'push' when: never - if: $CI_PIPELINE_SOURCE == 'schedule' -- GitLab From 2462b2d8ce47286d7b39b9baf0f719089c547860 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 30 Jan 2025 15:12:24 +0100 Subject: [PATCH 0018/1221] fix missing "s --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index babe65e8e..bdc433d8b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -873,7 +873,7 @@ ivas-pytest-compare_to_ref-dmx-short-enc: before_script: - USE_LTV=0 - ENCODER_TEST="true" - - COMPARE_DMX="true + - COMPARE_DMX="true" - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 @@ -886,7 +886,7 @@ ivas-pytest-compare_to_ref-dmx-short-enc-lev-10: before_script: - USE_LTV=0 - ENCODER_TEST="true" - - COMPARE_DMX="true + - COMPARE_DMX="true" - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=0.3162 @@ -899,7 +899,7 @@ ivas-pytest-compare_to_ref-dmx-short-enc-lev+10: before_script: - USE_LTV=0 - ENCODER_TEST="true" - - COMPARE_DMX="true + - COMPARE_DMX="true" - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 -- GitLab From 06f8a2cd5f208feffe98ce79b876af5b84cbc3b9 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 30 Jan 2025 15:51:35 +0100 Subject: [PATCH 0019/1221] Reset BASOP_CI_BRANCH_PC_REPO: basop-ci-branch --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d5f6294f8..3d41cc11d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ variables: REF_DECODER_PATH: "./IVAS_dec_ref" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "ci/bring-back-per-channel-odg" + BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From 77781045aeca10f4b0b1c90f4204cf7e6e326281 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 30 Jan 2025 17:19:23 +0100 Subject: [PATCH 0020/1221] add debug printout --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bdc433d8b..1330d7e29 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -138,6 +138,7 @@ stages: - git checkout $REFERENCE_BRANCH - git pull - *activate-debug-mode-info-if-set + - cat lib_com/options.h - make clean - make -j - mv ./IVAS_cod ./$REF_ENCODER_PATH -- GitLab From f6ad23ea84c45f070d617269004d294764302b36 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 31 Jan 2025 11:06:11 +0100 Subject: [PATCH 0021/1221] add even more debug printouts --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1330d7e29..eddf0a574 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -168,6 +168,8 @@ stages: - enc_stats_arg="" - if [ "$ENCODER_TEST" = "true" ]; then enc_stats_arg="--enc_stats"; fi - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - ls tests/ref/param_file/enc/ + - ls tests/ref/sba_bs/pkt/ .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR -- GitLab From d12f883389f2aec74b2f6aecba85a6121e7ce15b Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 31 Jan 2025 11:14:03 +0100 Subject: [PATCH 0022/1221] add --compare_enc_dmx arg to ref run too --- .gitlab-ci.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eddf0a574..cf2b9268b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -165,11 +165,19 @@ stages: - python3 tests/create_short_testvectors.py # create references - exit_code=0 + - enc_stats_arg="" - - if [ "$ENCODER_TEST" = "true" ]; then enc_stats_arg="--enc_stats"; fi - - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - if [ "$ENCODER_TEST" = "true" ]; then + - enc_stats_arg="--enc_stats" + - fi + + - enc_dmx_arg="" + - if [ "$COMPARE_DMX" = "true" ]; then + - enc_dmx_arg="--compare_enc_dmx" + - fi + + - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg §enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - ls tests/ref/param_file/enc/ - - ls tests/ref/sba_bs/pkt/ .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR -- GitLab From 8c567d02ec1ddf4880c65a8fe84e1f0fd14accde Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 31 Jan 2025 13:20:22 +0100 Subject: [PATCH 0023/1221] remove WMC_TOOL_SKIP to allow complexity printout when WMOPS_DETAIL is activated --- lib_com/basop_util.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index cef466471..2cf026952 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -45,9 +45,6 @@ #include "basop_settings.h" #include "cnst.h" - -#define WMC_TOOL_SKIP - extern const Word32 SqrtTable[32]; // Q31 extern const Word16 SqrtDiffTable[32]; /* Q15 */ @@ -2653,6 +2650,3 @@ cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ) #endif return result; } - - -#undef WMC_TOOL_SKIP -- GitLab From 5132325643709bb1e5adaf2db3c97f1a0eed60ef Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 31 Jan 2025 17:32:30 +0100 Subject: [PATCH 0024/1221] fix typo --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cf2b9268b..5d03662d0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -176,7 +176,7 @@ stages: - enc_dmx_arg="--compare_enc_dmx" - fi - - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg §enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - ls tests/ref/param_file/enc/ .update-scripts-repo: &update-scripts-repo -- GitLab From 2b20dd87187e06d436b193e89268f883397d7567 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 3 Feb 2025 10:25:11 +0100 Subject: [PATCH 0025/1221] add dmx dump for stereo dmx evs mode --- lib_enc/lib_enc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index c78fbe107..319ebdf87 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1749,6 +1749,9 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } ELSE { +#ifdef DEBUG_MODE_INFO + dbgwrite( inputBuffer, sizeof( int16_t ), inputBufferSize, 1, strcat( fname( debug_dir, "ivas_input_dmx", 0, 1, ENC ), ".pcm" ) ); +#endif hCoreCoder->input_frame_fx = inputBufferSize; move32(); IF( NE_32( ( error = evs_enc_fx( hCoreCoder, inputBuffer, hCoreCoder->mem_hp20_in_fx, inputBufferSize ) ), IVAS_ERR_OK ) ) -- GitLab From 2c50f3e1ace391d0ba232402c6999476b0479438 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Feb 2025 17:03:59 +0530 Subject: [PATCH 0026/1221] Fix for 3GPP issue 1125: interfering talker flag not triggered on short test vector Link #1125 --- lib_com/ivas_rom_com_fx.c | 10 ++++++++++ lib_com/ivas_rom_com_fx.h | 1 + lib_com/options.h | 1 + lib_enc/ivas_stereo_ica_enc.c | 17 +++++++++++++++-- lib_enc/ivas_stereo_td_analysis.c | 15 ++++++++++++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index ac4736561..cc138d070 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1356,6 +1356,16 @@ const UWord32 tdm_ratio_tabl_fx[TDM_NQ + 1] = { 2147483647, 2147483647, 2147483647 }; +// Q30 +const Word32 tdm_ratio_tabl_fx_Q30[] = { + 0, 0, 11703786, 26306674, 46385648, 71940704, 102542344, 137868448, + 177596896, 221298192, 268435456, 318471840, 370977792, 425201760, 480714208, + 536870912, 593027584, 648540032, 702764032, 755270016, 805306368, 852443648, + 896144896, 935873344, 971199488, 1001801152, 1027356160, 1047435136, + 1062038016, 1073741824, 1073741824, 1073741824 +}; + + // Q24 const Word32 tdm_ratio_tabl_fx_Q24[TDM_NQ + 1] = { 0, 0, 182871, 411041, 724775, 1124073, 1602224, 2154194, diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index 88bbaabbc..e1f4d0a6e 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -108,6 +108,7 @@ extern const Word16 pow_10_icbwe_gsMappingDFT_tbl_fx[]; *----------------------------------------------------------------------------------*/ extern const UWord32 tdm_ratio_tabl_fx[TDM_NQ + 1]; +extern const Word32 tdm_ratio_tabl_fx_Q30[TDM_NQ + 1]; extern const Word32 tdm_ratio_tabl_fx_Q24[TDM_NQ + 1]; extern const UWord32 tdm_den_ratio_tabl_fx[]; extern const Word16 icbwe_gsMapping_tbl_fx[]; // Q12 diff --git a/lib_com/options.h b/lib_com/options.h index d5314dd12..573b619bf 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -105,6 +105,7 @@ #define FIX_1100_REMOVE_LPC_RESCALING /* VA: Remove the rescaling of LPC coefficient to Q12 as residu and syn-filt are already taking care of it*/ #define FIX_1133_IMPROVE_MC_MLD /* Ittiam: Correcting wrong updation of exponents in ivas_mc_paramupmix_param_est_enc_fx() */ #define FIX_ISSUE_1122 /* Ittiam: Fix issue 1122: corrected incorrect scaling of a buffer leading to incorrect metadata bits */ +#define FIX_ISSUE_1125 /* Ittiam: Fix issue 1125: interfering talker flag not triggered on short test vector */ #define FIX_1132_STACK_CORRUPTION /* Stack corruption issue due of extending index access*/ #define FIX_ISSUE_1092 /* Ittiam: Fix for Issue 1092: BASOP asserts in stereo fx encoder for selection test inputs*/ #define FIX_ISSUE_1135 /* Ittiam: Fix for Issue 1135: downmixing difference between float and fixed-point (DFT - stereo) */ diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 3f4696a06..67a575e44 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -2258,9 +2258,22 @@ static void unclr_calc_corr_features_fx( corrR = BASOP_Util_Add_Mant32Exp( corrR, corrR_exp, Mpy_32_32( buf2[i], mono_i ), add( sub( 31, q_com ), exp ), &corrR_exp ); /* Q31-corrR_exp */ ener = BASOP_Util_Add_Mant32Exp( ener, ener_exp, Mpy_32_32( mono_i, mono_i ), shl( exp, 1 ), &ener_exp ); - side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */ - ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); /* Q31-ener_side_exp */ + side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */ + ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); /* Q31-ener_side_exp */ + +#ifdef FIX_ISSUE_1125 + Word16 n1, n2, prod_i_exp; + Word32 x, y, prod_i; + n1 = norm_l( buf1[i] ); + n2 = norm_l( buf2[i] ); + x = L_shl( buf1[i], n1 ); // q: q_com + n1 + y = L_shl( buf2[i], n2 ); // q: q_com + n2 + prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31 + prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) ); + sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */ +#else sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); /* Q31-sum_prod_exp */ +#endif } /* average energy of L and R channels */ diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index 58e72c91e..901a5dd28 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -635,14 +635,23 @@ Word16 stereo_tdm_ener_analysis_fx( hStereoTD->tdm_last_LRTD_PriCh_cnt = add( hStereoTD->tdm_last_LRTD_PriCh_cnt, 1 ); move16(); } + +#ifdef FIX_ISSUE_1125 + ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 +#else ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 +#endif move32(); test(); IF( EQ_16( hStereoTD->tdm_SM_modi_flag, 1 ) && hStereoTD->tdm_LRTD_flag == 0 ) { idx = shr( add( hStereoTD->tdm_last_ratio_idx, add( LRTD_STEREO_MID_IS_PRIM, 1 ) ), 1 ); +#ifdef FIX_ISSUE_1125 + ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 +#else ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 +#endif move32(); } @@ -731,8 +740,12 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } - hCPE->hStereoClassif->ratio_L_fx = ratio_L_fx; /* Q15 */ + hCPE->hStereoClassif->ratio_L_fx = ratio_L_fx; /* 31 - ratio_L_e */ move32(); +#ifdef FIX_ISSUE_1125 + hCPE->hStereoClassif->ratio_L_e = 1; + move16(); +#endif return idx; } -- GitLab From ad130d5c18055c51c217a1928d77e098cb3667d4 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 3 Feb 2025 14:48:29 +0100 Subject: [PATCH 0027/1221] correct if condition for building with DEBUG_MODE_INFO --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d03662d0..632afd64f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -331,7 +331,7 @@ stages: - *apply-testv-scaling - fi - - if [ "$ENCODER_TEST" = "true" ]; then + - if [ "$COMPARE_DMX" = "true" ] || [ "$ENCODER_TEST" = "true" ]; then - BUILD_WITH_DEBUG_MODE_INFO="true" - fi - *build-and-create-reference-outputs -- GitLab From c33bd4db6c70dc6a104267dd99167301d117739e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Feb 2025 20:43:41 +0530 Subject: [PATCH 0028/1221] Clang formatting changes --- lib_enc/ivas_stereo_td_analysis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index 901a5dd28..e5bf2ea53 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -639,7 +639,7 @@ Word16 stereo_tdm_ener_analysis_fx( #ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 #else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 + ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 #endif move32(); -- GitLab From 4afd1667823633ebafd21d77ec1524f5db608e8d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 09:08:08 +0530 Subject: [PATCH 0029/1221] Fix for 3GPP issue 1135: downmixing difference between float and fixed-point (DFT - stereo) - 3 Link #1135 Fixed further saturations --- lib_enc/ivas_cpe_enc.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 5f04dc87f..c905e0e51 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -814,7 +814,6 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * DFT stereo: iDFT and resampling on both channels *----------------------------------------------------------------*/ - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { Word32 internal_Fs; @@ -838,11 +837,22 @@ ivas_error ivas_cpe_enc_fx( stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, sts[0]->input32_fx, &out_start_ind, &out_end_ind, 0, input_Fs, input_Fs, 0, NULL ); #ifdef FIX_ISSUE_1135 - Word16 common_q = s_min( sub( sts[0]->q_inp, 2 ), sts[0]->q_old_inp ); /* -2 from target Q-factor sts[0]->q_inp to avoid some saturations (issue 1135) */ - Word16 fir_delay_len = NS2SA( sts[0]->input_Fs, DELAY_FIR_RESAMPL_NS ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( common_q, sts[0]->q_old_inp ) ); // q_old_inp -> common_q + // Normalise the input buffer from Q15 + Word16 input_norm, q_inp32, common_q, fir_delay_len; + input_norm = L_norm_arr( sts[0]->input32_fx + out_start_ind, sub( out_end_ind, out_start_ind ) ); + q_inp32 = add( Q15, input_norm ); + fir_delay_len = NS2SA( sts[0]->input_Fs, DELAY_FIR_RESAMPL_NS ); + move16(); + + // Find common Q-factor between { q_inp, q_old_inp and q_inp32-16 } + common_q = s_min( s_min( sub( q_inp32, 16 ), sts[0]->q_inp ), sts[0]->q_old_inp ); + + // Rescale the old input, input and FIR delay section of input buffer + scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( common_q, sts[0]->q_old_inp ) ); // q_old_inp -> common_q Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, common_q ), Q15 ) ); // Q15 -> common_q - Scale_sig( sts[0]->input_fx + out_end_ind, add( sub( input_frame, out_end_ind ), fir_delay_len ), sub( common_q, sts[0]->q_inp ) ); // q_inp -> common_q + scale_sig( sts[0]->input_fx + out_end_ind, add( sub( input_frame, out_end_ind ), fir_delay_len ), sub( common_q, sts[0]->q_inp ) ); // q_inp -> common_q + + // Update the Q-factors sts[0]->q_inp = common_q; move16(); sts[0]->q_old_inp = common_q; -- GitLab From 459882db93dcc282eaf957f0d08de2e4d3bb0625 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 4 Feb 2025 09:21:00 +0100 Subject: [PATCH 0030/1221] remove dbg output --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7c1e19fe5..c97b8c711 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -184,7 +184,6 @@ stages: - fi - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - - ls tests/ref/param_file/enc/ .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR -- GitLab From 1cda1ff1f9e58ae31401ff8d0d18b595c4aa6d3b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 14:34:16 +0530 Subject: [PATCH 0031/1221] Few bug fixes and precision improvements --- lib_com/prot_fx.h | 35 ++++++--- lib_com/swb_tbe_com_fx.c | 133 ++++++++++++++++---------------- lib_com/syn_filt_fx.c | 86 +++++++++++++++++++-- lib_enc/acelp_core_enc_fx.c | 9 --- lib_enc/ivas_core_enc.c | 8 +- lib_enc/ivas_cpe_enc.c | 5 -- lib_enc/ivas_stereo_icbwe_enc.c | 132 ++++++++++++++++++------------- lib_enc/swb_pre_proc_fx.c | 2 +- lib_enc/swb_tbe_enc_fx.c | 87 ++++++++++++--------- 9 files changed, 304 insertions(+), 193 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 3c2b1395c..407c4ce85 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -2391,6 +2391,20 @@ void syn_filt_fx( const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */ ); /* 1 --> update of memory */ +void syn_filt_fx32( + const Word16 a_e, /* i : exp of LP coeffs Q0 */ + const Word32 a[], /* i : LP filter coefficients Q12 */ + const Word16 m, /* i : order of LP filter Q0 */ + const Word32 x[], /* i : input signal Qx */ + const Word16 x_e, /* i : input signal Qx */ + Word32 y[], /* o : output signal Qx */ + Word16 *y_e, /* o : output signal Qx */ + const Word16 l, /* i : size of filtering Q0 */ + Word32 mem[], /* i/o: initial filter states Qx */ + Word16 *mem_e, /* i/o: initial filter states Qx */ + const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */ +); + void E_UTIL_synthesis( const Word16 shift, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, Word16 mem[], const Word16 update, const Word16 m ); void E_UTIL_synthesis_fx( const Word16 shift, const Word32 a[], const Word32 x[], Word32 y[], const Word16 lg, Word32 mem[], const Word16 update, const Word16 m ); @@ -3006,15 +3020,18 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, const Word16 prev_bfi -#if 1 // def ADD_IVAS_TBE_CODE - , /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ +#if 1 // def ADD_IVAS_TBE_CODE + , /* i : previous frame was concealed */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 Q_EnvSHBres_4k, Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index aeca8dff1..deb37d9f3 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -760,14 +760,15 @@ void Calc_rc0_h( Word32 L_acc; Word16 *ptrs; Word16 acf0, acf1; - Word16 temp, sh_acf; + Word16 temp, sh_acf, tmp2; Word16 i; /* computation of the autocorrelation function acf */ L_acc = L_mult( h[0], h[0] ); FOR( i = 1; i < LONG_H_ST; i++ ) { - L_acc = L_mac( L_acc, h[i], h[i] ); + tmp2 = shr( h[i], 2 ); + L_acc = L_mac( L_acc, tmp2, tmp2 ); } sh_acf = norm_l( L_acc ); L_acc = L_shl( L_acc, sh_acf ); @@ -780,9 +781,9 @@ void Calc_rc0_h( L_acc = L_mult( temp, *ptrs ); FOR( i = 1; i < LONG_H_ST - 1; i++ ) { - temp = *ptrs++; + temp = shr( *ptrs++, 2 ); move16(); - L_acc = L_mac( L_acc, temp, *ptrs ); + L_acc = L_mac( L_acc, temp, shr( *ptrs, 2 ) ); } L_acc = L_shl( L_acc, sh_acf ); acf1 = extract_h( L_acc ); @@ -2849,10 +2850,13 @@ void GenShapedSHBExcitation_ivas_enc_fx( const Word16 element_mode, /* i : element mode */ const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ const Word32 extl_brate, /* i : extension layer bitarte */ const Word16 MSFlag, /* i : Multi Source flag */ Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 Q_EnvSHBres_4k, Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ Word16 *Env_error, /* o : error in SHB residual envelope modelling Q0 */ @@ -2872,6 +2876,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 excTmp2[L_FRAME16k]; Word16 *White_exc16k; + Word16 Q_White_exc16k; Word16 excNoisyEnv[L_FRAME16k]; Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ move16(); @@ -2899,7 +2904,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 White_exc16k_FB_temp[L_FRAME16k]; Word32 White_exc16k_32[L_FRAME16k]; Word16 White_exc16k_tmp[L_FRAME16k]; - Word16 Q_temp; Word16 prev_Q_bwe_exc_fb; Word16 chk1, chk2; chk1 = 0; @@ -3089,7 +3093,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } White_exc16k = exc16k; - move16(); Word16 Q_excTmp2 = add( getScaleFactor16( excTmp2, L_FRAME16k ), *Q_bwe_exc ); IF( *mem_csfilt ) { @@ -3168,12 +3171,12 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* generate gaussian (white) excitation */ FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k[k] = own_random( &bwe_seed[0] ); + White_exc16k[k] = own_random( &bwe_seed[0] ); // Q0 move16(); } /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; // Q31 move32(); move32(); pow22 = POW_EXC16k_WHTND_FX; @@ -3189,27 +3192,20 @@ void GenShapedSHBExcitation_ivas_enc_fx( // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); L_tmp = 0; move32(); + Q_White_exc16k = add( getScaleFactor16( White_exc16k, L_FRAME16k ), norm_l( temp_pow ) ); FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); + White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); // Q31 + Q0 - Q15 = Q16 move32(); - White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], sub( *Q_bwe_exc, NOISE_QADJ ) ) ); // Q_bwe_exc - NOISE_QADJ + White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q16 + Q_White_exc16k - Q16 = Q_White_exc16k move16(); L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); } - Q_temp = norm_l( L_tmp ); - IF( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } } ELSE #endif { /* create a random excitation - Reuse exc16k memory */ - White_exc16k = exc16k; - move16(); create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); // Q5 @@ -3222,12 +3218,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( move32(); L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); } - Q_temp = norm_l( L_tmp ); - IF( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ /* White_exc16k in Q6 */ @@ -3235,22 +3225,23 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* pow22=0.00001f */ tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); Word64 sum = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { /* White_exc16k[k] *= excNoisyEnv[k]; */ - White_exc16k[k] = mult_r( excNoisyEnv[k], shl( White_exc16k[k], 1 ) ); // Q_excTmp2 + 5 + 1 - 15 ==> Q_excTmp2 - 9 + White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 move16(); chk2 = s_or( chk2, White_exc16k[k] ); /* i: excNoisyEnv in (Q_excTmp2) */ /* i: White_exc16k in Q6 */ /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2-NOISE_QADJ)*/ + sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ } Q_pow22 = W_norm( sum ); - pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2-NOISE_QADJ)+Q_pow22-32 - Q_pow22 = sub( add( Q_pow22, shl( sub( Q_excTmp2, NOISE_QADJ ), 1 ) ), 32 ); - Scale_sig( White_exc16k, L_FRAME16k, sub( *Q_bwe_exc, Q_excTmp2 ) ); + pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); + Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); } #if 1 // def ADD_IVAS_TBE_CODE @@ -3272,7 +3263,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( { FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_tmp[k] = round_fx( L_shl( White_exc16k_32[k], *Q_bwe_exc ) ); + White_exc16k_tmp[k] = shl( White_exc16k[k], sub( *Q_bwe_exc, Q_White_exc16k ) ); move16(); } @@ -3298,8 +3289,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( move32(); temp1 = add( shl( *Q_bwe_exc, 1 ), 1 ); - temp2 = add( add( Q_shb, *Q_bwe_exc ), 1 ); - temp3 = add( shl( Q_shb, 1 ), 1 ); + temp2 = add( add( Q_EnvSHBres_4k, *Q_bwe_exc ), 1 ); + temp3 = add( shl( Q_EnvSHBres_4k, 1 ), 1 ); FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) { // c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); @@ -3474,7 +3465,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( #endif { Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, - ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); + Q_White_exc16k, pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); tmp = voiceFacEst[0]; tmp2 = MAX_16; move16(); @@ -3537,13 +3528,16 @@ void GenShapedSHBExcitation_ivas_enc_fx( move16(); } } -#if 1 // def ADD_IVAS_TBE_CODE +#if 1 // def ADD_IVAS_TBE_CODE + Scale_sig( White_exc16k, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); // Q_bwe_exc test(); IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) { /* save buffers for IC-BWE */ // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); + *nlExc16k_e = sub( 15, *Q_bwe_exc ); + move16(); // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); /*Word16 temp_fac = divide3232(L_shr(pow1, Q_pow1), pow22); Word16 temp_fac_exp = 0; @@ -3553,24 +3547,27 @@ void GenShapedSHBExcitation_ivas_enc_fx( // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); FOR( k = 0; k < L_FRAME16k; k++ ) { - mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); + mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); // Q_bwe_exc move16(); } + *mixExc16k_e = sub( 15, *Q_bwe_exc ); + move16(); } #endif - tmp = sub( Q_temp, 3 ); FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_FB[k] = White_exc16k[k]; /* Q_bwe_exc-NOISE_QADJ */ + White_exc16k_FB[k] = White_exc16k[k]; /* Q_bwe_exc */ + move16(); } prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; move16(); - *Q_bwe_exc_fb = sub( *Q_bwe_exc, NOISE_QADJ ); + *Q_bwe_exc_fb = *Q_bwe_exc; move16(); + deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ - /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ + /* i/o: White_exc16k (Q_bwe_exc) */ + /* i: tbe_demph (Q_bwe_exc) */ #if 1 // def ADD_IVAS_TBE_CODE test(); @@ -3585,34 +3582,39 @@ void GenShapedSHBExcitation_ivas_enc_fx( // old_scale = Sqrt16(old_scale, &old_scale_exp); // old_scale = shl(old_scale, old_scale_exp); //Q15 L_tmp = root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ); - old_scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 + IF( exp < 0 ) + { + L_tmp = L_shl( L_tmp, exp ); + exp = 0; + move16(); + } + old_scale = round_fx_sat( L_tmp ); // exp // new_scale = 1.0f; - new_scale = 32767; - move16(); + new_scale = shr( 32767, exp ); // exp // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); - step_scale = mult_r( sub( new_scale, old_scale ), 205 ); - scale = old_scale; + step_scale = mult_r( sub( new_scale, old_scale ), 205 ); // exp + scale = old_scale; // exp move16(); /* interpolate between the old and the new value of the mixing factor */ - old_fact = *prev_mix_factor; + old_fact = *prev_mix_factor; // Q15 move16(); - new_fact = mix_factor; + new_fact = mix_factor; // Q15 move16(); // step = (new_fact - old_fact) / (L_FRAME16k / 2); - step = mult_r( sub( new_fact, old_fact ), 205 ); - fact = old_fact; + step = mult_r( sub( new_fact, old_fact ), 205 ); // Q15 + fact = old_fact; // Q15 move16(); /* mixing of LB and gaussian excitation in the first half of the frame */ FOR( k = 0; k < L_FRAME16k / 2; k++ ) { // exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; // exc16kWhtnd[k] = add(mult_r(fact, mult(shl(White_exc16k[k], *Q_bwe_exc), scale)), mult_r(sub(32767, fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( fact, mult_r( White_exc16k[k], scale ) ), NOISE_QADJ ), - L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + L_tmp = L_add_sat( L_shl_sat( L_mult( fact, mult_r( White_exc16k[k], scale ) ), exp ), // Q15 + Q_bwe_exc + (Q15-exp) - Q15 + exp + Q1 + L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc + Q16 + exc16kWhtnd[k] = round_fx_sat( L_tmp ); // Q_bwe_exc move16(); - fact = add_sat( fact, step ); - scale = add_sat( scale, step_scale ); + fact = add_sat( fact, step ); // Q15 + scale = add_sat( scale, step_scale ); // exp } /* mixing of LB and gaussian excitation in the second half of the frame */ @@ -3620,14 +3622,14 @@ void GenShapedSHBExcitation_ivas_enc_fx( { // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; // exc16kWhtnd[k] = add(mult_r(new_fact, shl(White_exc16k[k], *Q_bwe_exc)), mult_r(sub(32767, new_fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( new_fact, White_exc16k[k] ), NOISE_QADJ ), - mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + L_tmp = L_add( L_mult( new_fact, White_exc16k[k] ), + mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc + Q15 + Q1 => Q_bwe_exc + Q16 + exc16kWhtnd[k] = round_fx( L_tmp ); // Q_bwe_exc move16(); } } // preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc } ELSE #endif @@ -3650,13 +3652,13 @@ void GenShapedSHBExcitation_ivas_enc_fx( FOR( k = 0; k < L_FRAME16k; k++ ) { /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); + L_tmp = L_mult( White_exc16k[k], scale ); // Q_bwe_exc + Q15 + Q1 => Q_bwe_exc + Q16 /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx_sat( L_shl_sat( L_tmp, NOISE_QADJ ) ); + exc16kWhtnd[k] = round_fx_sat( L_tmp ); // Q_bwe_exc move16(); /* exc16kWhtnd: Q_bwe_exc */ } - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc /* i/o: exc16kWhtnd (Q_bwe_exc) */ /* i/o: tbe_premph (Q_bwe_exc) */ } @@ -3721,9 +3723,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); + L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc)*/ + exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); // Q_bwe_exc move16(); /* Q_bwe_exc */ } @@ -3740,7 +3741,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( temp = div_s( temp, temp2 ); /* Q15 */ temp = mult_r( PREEMPH_FAC, temp ); - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); + PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); // Q_bwe_exc /* exc16kWhtnd: Q_bwe_exc; tbe_premph: Q_bwe_exc*/ } @@ -3753,7 +3754,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( IF( LT_32( bitrate, ACELP_24k40 ) ) #endif { - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); + syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); /* i: exc16kWhtnd in Q_bwe_exc */ /* o: excSHB in Q_bwe_exc */ } diff --git a/lib_com/syn_filt_fx.c b/lib_com/syn_filt_fx.c index 169ca5767..6e0f7e716 100644 --- a/lib_com/syn_filt_fx.c +++ b/lib_com/syn_filt_fx.c @@ -185,7 +185,8 @@ void syn_filt_fx( { Word16 i, j; Word16 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */ - Word16 s, *yy; + Word16 *yy; + Word32 s; Word16 q; Flag Overflow = 0; move16(); @@ -212,15 +213,16 @@ void syn_filt_fx( FOR( i = 0; i < l; i++ ) { - s = mult_r( shl_o( a0, q, &Overflow ), x[i] ); + s = L_mult( a0, x[i] ); FOR( j = 1; j <= m; j++ ) { - s = msu_ro( L_deposit_h( s ), shl_o( a[j], q, &Overflow ), yy[i - j], &Overflow ); + s = L_msu_sat( s, shr( a[j], shift ), yy[i - j] ); } - yy[i] = s; + s = L_shl_sat( s, q ); + yy[i] = extract_h( s ); move16(); - y[i] = s; + y[i] = extract_h( s ); move16(); } @@ -241,6 +243,80 @@ void syn_filt_fx( } +void syn_filt_fx32( + const Word16 a_e, /* i : exp of LP coeffs Q0 */ + const Word32 a[], /* i : LP filter coefficients Q12 */ + const Word16 m, /* i : order of LP filter Q0 */ + const Word32 x[], /* i : input signal Qx */ + const Word16 x_e, /* i : input signal Qx */ + Word32 y[], /* o : output signal Qx */ + Word16 *y_e, /* o : output signal Qx */ + const Word16 l, /* i : size of filtering Q0 */ + Word32 mem[], /* i/o: initial filter states Qx */ + Word16 *mem_e, /* i/o: initial filter states Qx */ + const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */ + ) /* 1 --> update of memory */ +{ + Word16 i, j; + Word64 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */ + Word64 s, *yy; + + yy = &buf[0]; + + /*------------------------------------------------------------------* + * copy initial filter states into synthesis buffer and do synthesis + *------------------------------------------------------------------*/ + + FOR( i = 0; i < m; i++ ) + { + *yy++ = W_deposit32_l( mem[i] ); + move32(); + } + + /*-----------------------------------------------------------------------* + * Do the filtering + *-----------------------------------------------------------------------*/ + Word64 max_val = 1; + FOR( i = 0; i < l; i++ ) + { + s = W_deposit32_l( x[i] ); + FOR( j = 1; j <= m; j++ ) + { + s = W_sub( s, W_mult0_32_32( a[j], W_extract_l( W_shr( yy[i - j], sub( 31, a_e ) ) ) ) ); + } + + yy[i] = s; + move32(); + if ( GT_64( W_abs( s ), max_val ) ) + { + max_val = W_abs( s ); + } + } + + Word16 norm = W_norm( max_val ); + + FOR( i = 0; i < l; i++ ) + { + y[i] = W_extract_l( W_shr( yy[i], sub( 32, norm ) ) ); + } + *y_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) ); + /*------------------------------------------------------------------* + * Update memory if required + *------------------------------------------------------------------*/ + + IF( update_m ) + { + FOR( i = 0; i < m; i++ ) + { + mem[i] = W_extract_l( W_shr( yy[l - m + i], sub( 32, norm ) ) ); + } + *mem_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) ); + } + + return; +} + + /* * E_UTIL_synthesis * diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 8f63c6612..6449367c8 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1102,15 +1102,6 @@ ivas_error acelp_core_enc_ivas_fx( /* update Aw[] coefficients */ weight_a_subfr_fx( shr( st->L_frame, 6 ), A, Aw, st->gamma, M ); } - IF( st->hLPDmem ) - { - st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); - move16(); - st->hLPDmem->q_lpd_old_exc = Q_new; - move16(); - st->hLPDmem->q_lpd_syn = Q_new; - move16(); - } test(); test(); diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index a25ee85c6..3bc869675 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -328,7 +328,6 @@ ivas_error ivas_core_enc_fx( /*---------------------------------------------------------------------* * Preprocessing (preparing) for ACELP/HQ core switching *---------------------------------------------------------------------*/ - core_switching_pre_enc_ivas_fx( st, old_inp_12k8_fx[n], sub( Q_new[n], 1 ), old_inp_16k_fx[n], sub( Q_new[n], 1 ), sts[0]->active_cnt, last_element_mode ); /*---------------------------------------------------------------------* @@ -794,13 +793,8 @@ ivas_error ivas_core_enc_fx( stereo_icBWE_preproc_fx( hCPE, input_frame, new_swb_speech_buffer_fx_16 /*tmp buffer*/, q_new_swb_speech_buffer ); q_new_swb_speech_buffer = add( q_new_swb_speech_buffer, 16 ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, input_frame, Q16 ); // q_new_swb_speech_buffer - Copy_Scale_sig_16_32_no_sat( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); -#else - Copy_Scale_sig_16_32_DEPREC( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, input_frame, Q16 ); // q_new_swb_speech_buffer - Copy_Scale_sig_16_32_DEPREC( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 -#endif + Copy_Scale_sig_16_32_no_sat( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 stereo_icBWE_enc_ivas_fx( hCPE, shb_speech_fx32, sub( Q31, Q_shb_spch ), new_swb_speech_buffer_fx, sub( Q31, q_new_swb_speech_buffer ), voice_factors_fx32[0] ); diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 5f04dc87f..0efc3f759 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -897,13 +897,8 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Front Pre-processing *----------------------------------------------------------------*/ - FOR( n = 0; n < n_CoreChannels; n++ ) { - FOR( Word16 i = 0; i < hCPE->hCoreCoder[n]->nb_subfr; i++ ) - { - Scale_sig( &A_fx[n][i * ( M + 1 )], M + 1, sub( norm_s( A_fx[n][i * ( M + 1 )] ), 2 ) ); // scaling to Q12 - } set16_fx( old_wsp_fx[n], 0, L_WSP ); q_old_wsp = Q15; move16(); diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index cc5f8453a..407f66cfe 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -286,7 +286,7 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( /* Quantize spec. mapping **/ Word16 specMapping16; - idx = usquant_fx( shr( u_fx, sub( 0, u_e ) ), &specMapping16, -19660, 6553, ( 1 << STEREO_ICBWE_SPBITS ) ); // -0.6 in in Q15 -> -19660, 0.2 in Q15 -> 6553 + idx = usquant_fx( shr( u_fx, sub( 0, u_e ) ), &specMapping16, -19660, 6553 >> 1, ( 1 << STEREO_ICBWE_SPBITS ) ); // -0.6 in in Q15 -> -19660, 0.2 in Q15 -> 6553 *specMapping_fx = L_deposit_h( specMapping16 ); move32(); @@ -347,15 +347,13 @@ static Word16 ic_bwe_enc_gsMapping_ivas_fx( temp2_fx32 = BASOP_Util_Add_Mant32Exp( temp2_fx32, temp2_exp, L_abs( synthSHB_nonref_fx[i] ), exp2, &temp2_exp ); /* Q31-temp2_exp */ } - - memEner_fx[0] = temp1_fx32; /* Q31-temp1_exp */ - memEner_fx[1] = L_shr( temp2_fx32, abs_s( sub( temp1_exp, temp2_exp ) ) ); /* Q31-temp1_exp */ + memEner_fx[0] = L_shr( temp1_fx32, sub( s_max( temp1_exp, temp2_exp ), temp1_exp ) ); + memEner_fx[1] = L_shr( temp2_fx32, sub( s_max( temp1_exp, temp2_exp ), temp2_exp ) ); move32(); move32(); *memEner_e = s_max( temp1_exp, temp2_exp ); move16(); - IF( temp2_fx32 == 0 ) { *gsMapping_fx = *gsMapping_fx; @@ -364,7 +362,7 @@ static Word16 ic_bwe_enc_gsMapping_ivas_fx( ELSE { L_mult = Mpy_32_32( relG_targ_fx, temp1_fx32 ); // relG_targ_e + temp1_e - temp1 = BASOP_Util_Divide3232_Scale( L_mult, temp1_fx32, &exp ); // exp = exp - ( relG_targ_e + temp1_e + temp2_e ) + temp1 = BASOP_Util_Divide3232_Scale( L_mult, temp2_fx32, &exp ); // exp = exp - ( relG_targ_e + temp1_e - temp2_e ) exp = add( exp, sub( add( relG_targ_e, temp1_exp ), temp2_exp ) ); *gsMapping_fx = L_deposit_h( temp1 ); // exp move32(); @@ -374,23 +372,44 @@ static Word16 ic_bwe_enc_gsMapping_ivas_fx( /* quantize the IC-BWE GS mapping*/ IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - temp2_fx = extract_l( L_shr( temp2_fx32, Q10 ) ); // Q15 + IF( LT_32( temp2_fx32, -( 2 << 25 ) ) ) + { + temp2_fx = -( 2 << 12 ); // Q12 + move16(); + } + ELSE IF( GT_32( temp2_fx32, 1 << 25 ) ) + { + temp2_fx = 1 << 12; // Q12 + move16(); + } + + temp2_fx = extract_h( L_shl_sat( temp2_fx32, Q3 ) ); // Q12 gsMapping_fx16 = 0; move16(); idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMapping_tbl_fx, ( 1 << STEREO_ICBWE_GSBITS ) ); // Q12 - // idx = squant_fx( temp2, gsMapping, icbwe_gsMapping_tbl_fx, 1 << STEREO_ICBWE_GSBITS ); } ELSE { - temp2_fx = extract_l( L_shr( temp2_fx32, Q10 ) ); // Q15 + IF( LT_32( temp2_fx32, -( 5 << 25 ) ) ) + { + temp2_fx = -( 5 << 12 ); // Q12 + move16(); + } + ELSE IF( GT_32( temp2_fx32, 1 << 25 ) ) + { + temp2_fx = 1 << 12; // Q12 + move16(); + } + + temp2_fx = extract_h( L_shl_sat( temp2_fx32, Q3 ) ); // Q12 gsMapping_fx16 = 0; move16(); - idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMappingDFT_tbl_fx, ( 1 << STEREO_ICBWE_GSBITS ) ); // Q12 + idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMappingDFT_tbl_fx, ( 1 << STEREO_ICBWE_GSBITS_DFT ) ); // Q12 } *gsMapping_fx = L_deposit_h( gsMapping_fx16 ); // Q28 move32(); Word16 e; - L_mult = Mult_32_16( *gsMapping_fx, 27213 /*=log2(10)*2^13*/ ); // Q27 + Q13 - Q15 -> Q26 + L_mult = Mult_32_16( *gsMapping_fx, 27213 /*=log2(10)*2^13*/ ); // Q28 + Q13 - Q15 -> Q26 *gsMapping_fx = BASOP_util_Pow2( L_mult, 5, &e ); /* Q31-e */ move32(); @@ -429,25 +448,24 @@ static void icbwe_dft_stereo_param_ivas_fx( nrg_R_fx = hStereoDft->nrg_R_fx; nrg_DMX_fx = hStereoDft->nrg_DMX_fx; - - hStereoICBWE->mem_nrg_L_fx[0] = nrg_L_fx[0]; // hStereoICBWE->nrg_L_fx_e[0] - hStereoICBWE->mem_nrg_R_fx[0] = nrg_R_fx[0]; // hStereoICBWE->nrg_R_fx_e[0] - hStereoICBWE->mem_nrg_DMX_fx[0] = nrg_DMX_fx[0]; // hStereoICBWE->nrg_DMX_fx_e[0] - hStereoICBWE->mem_nrg_L_fx[1] = L_shr( nrg_L_fx[1], abs_s( sub( hStereoDft->nrg_L_fx_e[0], hStereoDft->nrg_L_fx_e[1] ) ) ); // hStereoICBWE->nrg_L_fx_e[1] - hStereoICBWE->mem_nrg_R_fx[1] = L_shr( nrg_R_fx[1], abs_s( sub( hStereoDft->nrg_R_fx_e[0], hStereoDft->nrg_R_fx_e[1] ) ) ); // hStereoICBWE-> nrg_R_fx_e[1] - hStereoICBWE->mem_nrg_DMX_fx[1] = L_shr( nrg_DMX_fx[1], abs_s( sub( hStereoDft->nrg_DMX_fx_e[0], hStereoDft->nrg_DMX_fx_e[1] ) ) ); // hStereoICBWE->nrg_DMX_fx_e[1] - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); hStereoICBWE->mem_nrg_L_fx_e = s_max( hStereoDft->nrg_L_fx_e[0], hStereoDft->nrg_L_fx_e[1] ); hStereoICBWE->mem_nrg_R_fx_e = s_max( hStereoDft->nrg_R_fx_e[0], hStereoDft->nrg_R_fx_e[1] ); hStereoICBWE->mem_nrg_DMX_fx_e = s_max( hStereoDft->nrg_DMX_fx_e[0], hStereoDft->nrg_DMX_fx_e[1] ); move16(); move16(); move16(); + hStereoICBWE->mem_nrg_L_fx[0] = L_shr( nrg_L_fx[0], sub( hStereoICBWE->mem_nrg_L_fx_e, hStereoDft->nrg_L_fx_e[0] ) ); + hStereoICBWE->mem_nrg_R_fx[0] = L_shr( nrg_R_fx[0], sub( hStereoICBWE->mem_nrg_R_fx_e, hStereoDft->nrg_R_fx_e[0] ) ); + hStereoICBWE->mem_nrg_DMX_fx[0] = L_shr( nrg_DMX_fx[0], sub( hStereoICBWE->mem_nrg_DMX_fx_e, hStereoDft->nrg_DMX_fx_e[0] ) ); + hStereoICBWE->mem_nrg_L_fx[1] = L_shr( nrg_L_fx[1], sub( hStereoICBWE->mem_nrg_L_fx_e, hStereoDft->nrg_L_fx_e[1] ) ); + hStereoICBWE->mem_nrg_R_fx[1] = L_shr( nrg_R_fx[1], sub( hStereoICBWE->mem_nrg_R_fx_e, hStereoDft->nrg_R_fx_e[1] ) ); + hStereoICBWE->mem_nrg_DMX_fx[1] = L_shr( nrg_DMX_fx[1], sub( hStereoICBWE->mem_nrg_DMX_fx_e, hStereoDft->nrg_DMX_fx_e[1] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); Word16 sum_nrg_L_e = hStereoICBWE->mem_nrg_L_fx_e, sum_nrg_R_e = hStereoICBWE->mem_nrg_R_fx_e, sum_nrg_DMX_e = hStereoICBWE->mem_nrg_DMX_fx_e; sum_nrg_L_fx = sum_32_fx( hStereoICBWE->mem_nrg_L_fx, 2, &sum_nrg_L_e ); // hStereoICBWE->mem_nrg_L_fx_e @@ -510,9 +528,13 @@ static void icbwe_dft_stereo_param_ivas_fx( hStereoICBWE->prevSpecMapping_fx = spec_table_fx[spIndx]; // q31 /* ic bwe spec mapping application */ deemph_fx_32( 0, shb_synth_nonref_fx, extract_l( L_shr( hStereoICBWE->prevSpecMapping_fx, 16 ) ), L_FRAME16k, &hStereoICBWE->memShbSpecMapping_fx ); // shb_synth_nonref_e + hStereoICBWE->memShbSpecMapping_e = shb_synth_nonref_e; + move16(); } ELSE { + hStereoICBWE->memShbSpecMapping_e = 0; + move16(); hStereoICBWE->memShbSpecMapping_fx = 0; hStereoICBWE->prevSpecMapping_fx = 0; move32(); @@ -692,6 +714,8 @@ void stereo_icBWE_enc_ivas_fx( v_multc_fixed( voice_factors_fx, 1073741824, nlMixFac_fx, NB_SUBFR16k ); // Q31, 0.5 in Q31 -> 1073741824 } + Word16 L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR; + move16(); IF( st->flag_ACELP16k == 0 ) { nbSubFr = NB_SUBFR; @@ -701,6 +725,8 @@ void stereo_icBWE_enc_ivas_fx( { nbSubFr = NB_SUBFR16k; move16(); + L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR16k; + move16(); } Word16 exp_buf[L_FRAME16k]; @@ -728,11 +754,9 @@ void stereo_icBWE_enc_ivas_fx( temp2_fx = Sqrt32( L_sub( ONE_IN_Q31, nlMixFac_fx[i] ), &temp2_e ); /* Q31-temp2_e */ } - tmp = BASOP_Util_Divide1616_Scale( L_FRAME16k, nbSubFr, &exp ); /* Q15-exp */ - tmp = shr( tmp, sub( Q15, exp ) ); /* Q0 */ - FOR( j = 0; j < tmp; ( j++, k++ ) ) + FOR( j = 0; j < L_FRAME16k_by_nbSubFr; ( j++, k++ ) ) { - excSHB_nonref_fx[k] = extract_l( BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, hStereoICBWE->nlExc16k_fx[k] ), add( temp1_e, hStereoICBWE->nlExc16k_e ), Mpy_32_32( temp2_fx, hStereoICBWE->mixExc16k_fx[k] ), add( temp2_e, hStereoICBWE->mixExc16k_e ), &exp_buf[k] ) ); /* Q31-exp_buf */ + excSHB_nonref_fx[k] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, L_deposit_h( hStereoICBWE->nlExc16k_fx[k] ) ), add( temp1_e, hStereoICBWE->nlExc16k_e ), Mpy_32_32( temp2_fx, L_deposit_h( hStereoICBWE->mixExc16k_fx[k] ) ), add( temp2_e, hStereoICBWE->mixExc16k_e ), &exp_buf[k] ); /* Q31-exp_buf */ move32(); } } @@ -754,19 +778,13 @@ void stereo_icBWE_enc_ivas_fx( move32(); } /* LP synthesis */ - Word16 tmp_e = s_max( hCPE->hStereoICBWE->lpSHBRef_e, max_e ); - - Word32 lpSHBRef_fx32[LPC_SHB_ORDER + 1]; - Copy_Scale_sig32( hCPE->hStereoICBWE->lpSHBRef_fx, lpSHBRef_fx32, LPC_SHB_ORDER + 1, negate( sub( tmp_e, hCPE->hStereoICBWE->lpSHBRef_e ) ) ); /* Q31-tmp_e */ - Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, negate( sub( tmp_e, max_e ) ) ); /* Q31-tmp_e */ - // set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); - E_UTIL_synthesis_fx( 0, lpSHBRef_fx32, excSHB_nonref_fx, shb_synth_nonref_fx, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); + Copy_Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( hStereoICBWE->mem_lpc_shbsynth_nonref_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, sub( max_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + max_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); - shb_synth_nonref_e = tmp_e; - hStereoICBWE->mem_lpc_shbsynth_nonref_e = tmp_e; - move16(); - move16(); + syn_filt_fx32( hStereoICBWE->lpSHBRef_e, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER, excSHB_nonref_fx, max_e, shb_synth_nonref_fx, &shb_synth_nonref_e, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, &hStereoICBWE->mem_lpc_shbsynth_nonref_e, 1 ); } ELSE { @@ -777,11 +795,11 @@ void stereo_icBWE_enc_ivas_fx( shb_synth_nonref_e = shb_frame_ref_e; move16(); set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, 10 ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = 0; + move16(); } icbwe_dft_stereo_param_ivas_fx( hStereoICBWE, hStereoDft, st, shb_synth_nonref_fx, shb_synth_nonref_e ); - hStereoICBWE->memShbSpecMapping_e = shb_synth_nonref_e; - move16(); } ELSE { @@ -847,6 +865,8 @@ void stereo_icBWE_enc_ivas_fx( IF( ( NE_16( hStereoICBWE->prev_refChanIndx_bwe, hStereoICBWE->refChanIndx_bwe ) ) || NE_16( st->last_extl, st->extl ) || NE_16( st->flag_ACELP16k, 1 ) ) { hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->memShbSpecMapping_e = 0; + move16(); hStereoICBWE->memShbSpecMapping_fx = 0; move32(); move32(); @@ -916,6 +936,8 @@ void stereo_icBWE_enc_ivas_fx( v_multc_fixed( voice_factors_fx, 1073741824 /*0.5 in Q31*/, nlMixFac_fx, NB_SUBFR16k ); /* Q31 */ } + Word16 L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR; + move16(); IF( st->flag_ACELP16k == 0 ) { nbSubFr = NB_SUBFR; @@ -925,6 +947,8 @@ void stereo_icBWE_enc_ivas_fx( { nbSubFr = NB_SUBFR16k; move16(); + L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR16k; + move16(); } Word16 exp_buf[L_FRAME16k]; @@ -949,13 +973,13 @@ void stereo_icBWE_enc_ivas_fx( temp1_e = 0, temp2_e = 0; temp1_fx = Sqrt32( nlMixFac_fx[i], &temp1_e ); /* Q31-temp1_e */ temp2_fx = Sqrt32( L_sub( ONE_IN_Q31, nlMixFac_fx[i] ), &temp2_e ); /* Q31 */ - move32(); + move16(); move16(); } - FOR( j = 0; j < ( L_FRAME16k / nbSubFr ); ( j++, k++ ) ) + FOR( j = 0; j < L_FRAME16k_by_nbSubFr; ( j++, k++ ) ) { - excSHB_nonref_fx[k] = extract_l( BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, hStereoICBWE->nlExc16k_fx[k] ), temp1_e + hStereoICBWE->nlExc16k_e, Mpy_32_32( temp2_fx, hStereoICBWE->mixExc16k_fx[k] ), temp2_e + hStereoICBWE->mixExc16k_e, &exp_buf[k] ) ); /* Q31-exp_buf */ + excSHB_nonref_fx[k] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, L_deposit_h( hStereoICBWE->nlExc16k_fx[k] ) ), add( temp1_e, hStereoICBWE->nlExc16k_e ), Mpy_32_32( temp2_fx, L_deposit_h( hStereoICBWE->mixExc16k_fx[k] ) ), add( temp2_e, hStereoICBWE->mixExc16k_e ), &exp_buf[k] ); /* Q31-exp_buf */ move32(); } } @@ -977,18 +1001,12 @@ void stereo_icBWE_enc_ivas_fx( move32(); } /* LP synthesis */ + Copy_Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( hStereoICBWE->mem_lpc_shbsynth_nonref_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, sub( max_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + max_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); - Word16 tmp_e = s_max( hCPE->hStereoICBWE->lpSHBRef_e, max_e ); - - Word32 lpSHBRef_fx32[LPC_SHB_ORDER + 1]; - - Copy_Scale_sig32( hCPE->hStereoICBWE->lpSHBRef_fx, lpSHBRef_fx32, LPC_SHB_ORDER + 1, negate( sub( tmp_e, hCPE->hStereoICBWE->lpSHBRef_e ) ) ); /* Q31-tmp_e */ - Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, negate( sub( tmp_e, max_e ) ) ); /* Q31-tmp_e */ - - E_UTIL_synthesis_fx( 0, hStereoICBWE->lpSHBRef_fx, excSHB_nonref_fx, shb_synth_nonref_fx, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); - shb_synth_nonref_e = sub( 31, tmp_e ); - hStereoICBWE->mem_lpc_shbsynth_nonref_e = shb_synth_nonref_e; - move16(); + syn_filt_fx32( hStereoICBWE->lpSHBRef_e, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER, excSHB_nonref_fx, max_e, shb_synth_nonref_fx, &shb_synth_nonref_e, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, &hStereoICBWE->mem_lpc_shbsynth_nonref_e, 1 ); } ELSE { @@ -999,6 +1017,8 @@ void stereo_icBWE_enc_ivas_fx( shb_synth_nonref_e = shb_frame_ref_e; move16(); set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, 10 ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = 0; + move16(); } test(); @@ -1072,6 +1092,8 @@ void stereo_icBWE_init_enc_fx( /* unscaled & scaled SHB synthesis memory */ set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = 0; + move16(); /* inter-channel BWE spectral shape adj. */ hStereoICBWE->prevSpecMapping_fx = 0; diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 850ae0d31..3e9c07c23 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1276,7 +1276,7 @@ void swb_pre_proc_ivas_fx( Word16 exp_t; hCPE->hStereoICBWE->MSFlag = 0; /* Init the multi-source flag */ move16(); - v = Mpy_32_16_1( sum16_fx( st->voicing_fx, 3 ), 10923 /* 0.33333 in Q15 */ ); + v = Mpy_32_16_1( L_add( L_deposit_l( st->voicing_fx[0] ), L_add( L_deposit_l( st->voicing_fx[1] ), L_deposit_l( st->voicing_fx[2] ) ) ), 10923 /* 0.33333 in Q15 */ ); // t = log10f( ( hCPE->hStereoICBWE->icbweRefEner + 1e-6f ) / ( lbEner + 1e-6f ) ); t = L_deposit_h( BASOP_Util_Divide3232_Scale( L_add( hCPE->hStereoICBWE->icbweRefEner_fx, EPSILON_FX ), L_add( lbEner, EPSILON_FX ), &exp_t ) ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index a2965d5dc..1366ab4c5 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -607,9 +607,9 @@ void InitSWBencBuffer_ivas_fx( // TV2TV IVAS_CODE -> To be verify if it has to be moved to hBWE_TD - st_fx->prev_Q_bwe_exc = 31; + st_fx->prev_Q_bwe_exc = 15; move16(); - st_fx->prev_Q_bwe_syn = 31; + st_fx->prev_Q_bwe_syn = 15; move16(); set16_fx( st_fx->prev_lsp_wb_fx, 0, 6 ); set16_fx( st_fx->prev_lsp_wb_temp_fx, 0, 6 ); @@ -2940,7 +2940,7 @@ void swb_tbe_enc_ivas_fx( Word16 formant_fac_fx; // int16_t stab_check = 1; Word16 MSFlag; - Word16 *nlExc16k_fx, *mixExc16k_fx; + Word16 *nlExc16k_fx, *nlExc16k_e, *mixExc16k_fx, *mixExc16k_e; Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; @@ -2948,6 +2948,9 @@ void swb_tbe_enc_ivas_fx( Word16 acorr_EnvSHBres[ENVSHBRES_ACORR_MAX - ENVSHBRES_ACORR_MIN], *p_acorr, shb_env_tilt_fx; Word16 buf_EnvSHBres_fx[2 * L_FRAME4k], *p_buf, EnvSHBres_fx[L_FRAME16k], EnvSHBres_4k_fx[L_FRAME4k], EnvSHBres_4k_norm_fx[L_FRAME4k], env_mean_normf_fx[L_FRAME4k]; + Word32 tmp_buf[L_FRAME4k]; + Word16 Q_EnvSHBres_4k_norm = Q31; + move16(); Word16 GainShape_Interp_fx[NUM_SHB_SUBGAINS], GainShape_tilt_fx; /* Q15 */ Word16 seg_mean[4], den_seg_mean[4], *p_env, step; Word16 temp, scale_fx, scale_e, pow_e, tmp_e, tmp1_e; @@ -2994,14 +2997,18 @@ void swb_tbe_enc_ivas_fx( IF( st_fx->element_mode >= IVAS_CPE_DFT && hStereoICBWE != NULL ) { nlExc16k_fx = hStereoICBWE->nlExc16k_fx; + nlExc16k_e = &hStereoICBWE->nlExc16k_e; mixExc16k_fx = hStereoICBWE->mixExc16k_fx; + mixExc16k_e = &hStereoICBWE->mixExc16k_e; MSFlag = hStereoICBWE->MSFlag; move16(); } ELSE { nlExc16k_fx = NULL; + nlExc16k_e = NULL; mixExc16k_fx = NULL; + mixExc16k_e = NULL; MSFlag = 0; move16(); } @@ -3503,7 +3510,13 @@ void swb_tbe_enc_ivas_fx( /* normalize residual SHB envelope with its long-term mean envelope */ FOR( k = 0; k < L_FRAME4k; k++ ) { - EnvSHBres_4k_norm_fx[k] = mult( EnvSHBres_4k_fx[k], env_mean_normf_fx[k] ); + tmp_buf[k] = L_mult( EnvSHBres_4k_fx[k], env_mean_normf_fx[k] ); // Q_shb + Q15 + Q1 => Q_shb + Q16 + move32(); + } + Q_EnvSHBres_4k_norm = sub( getScaleFactor32( tmp_buf, L_FRAME4k ), 1 /* Guard bit */ ); + FOR( k = 0; k < L_FRAME4k; k++ ) + { + EnvSHBres_4k_norm_fx[k] = extract_h( L_shl( tmp_buf[k], Q_EnvSHBres_4k_norm ) ); // Q_shb + Q16 + Q_EnvSHBres_4k_norm - Q16 => Q_EnvSHBres_4k_norm + Q_shb move16(); } @@ -3515,15 +3528,16 @@ void swb_tbe_enc_ivas_fx( /* subtract mean value from the normalized SHB residual envelope */ p_buf = &buf_EnvSHBres_fx[L_FRAME4k]; - temp = mean_no_sat_fx( EnvSHBres_4k_norm_fx, L_FRAME4k ); + temp = mean_no_sat_fx( EnvSHBres_4k_norm_fx, L_FRAME4k ); // Q_EnvSHBres_4k_norm + Q_shb FOR( k = 0; k < L_FRAME4k; k++ ) { - *p_buf++ = sub( EnvSHBres_4k_norm_fx[k], temp ); + *p_buf++ = shr( sub( EnvSHBres_4k_norm_fx[k], temp ), Q_EnvSHBres_4k_norm ); // Q_shb move16(); } + Q_EnvSHBres_4k_norm = add( Q_EnvSHBres_4k_norm, Q_shb ); /* update memory */ - Copy( &buf_EnvSHBres_fx[L_FRAME4k], hBWE_TD->old_EnvSHBres_fx, L_FRAME4k ); + Copy( &buf_EnvSHBres_fx[L_FRAME4k], hBWE_TD->old_EnvSHBres_fx, L_FRAME4k ); // Q_shb /* calculate energy normalization factor for the auto-correlation function */ // pow0 = sum2_f( &buf_EnvSHBres[L_FRAME4k], L_FRAME4k ) + 1.0f; @@ -3673,7 +3687,7 @@ void swb_tbe_enc_ivas_fx( sc = sub( Q_bwe_exc, add( Q_new, Q_new ) ); /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + FOR( cnt = 0; cnt < L_FRAME32k + NL_BUFF_OFFSET; cnt++ ) { bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended[cnt], sc ) ); move16(); @@ -3697,8 +3711,8 @@ void swb_tbe_enc_ivas_fx( st_fx->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st_fx->extl, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_Q31, shb_res_gshape_fx, shb_res_fx, &vf_ind_fx, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0, st_fx->element_mode, st_fx->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st_fx->extl_brate, MSFlag, - EnvSHBres_4k_norm_fx, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), &Env_error_fx, Env_error_part_fx ); + &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0, st_fx->element_mode, st_fx->flag_ACELP16k, nlExc16k_fx, nlExc16k_e, mixExc16k_fx, mixExc16k_e, st_fx->extl_brate, MSFlag, + EnvSHBres_4k_norm_fx, Q_EnvSHBres_4k_norm, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), &Env_error_fx, Env_error_part_fx ); *Q_white_exc = Q_bwe_exc_fb; move16(); @@ -3904,47 +3918,48 @@ void swb_tbe_enc_ivas_fx( /* Gain frame adjustment factor */ /* log( (GainShape[0]) / (st->prev_wb_GainShape) )*/ - test(); - IF( GainShape_fx[0] && hBWE_TD->prev_swb_GainShape_fx ) + IF( hBWE_TD->prev_swb_GainShape_fx == 0 ) { - exp = norm_s( hBWE_TD->prev_swb_GainShape_fx ); - tmp = div_s( shl( 1, sub( 14, exp ) ), hBWE_TD->prev_swb_GainShape_fx ); - L_tmp = L_mult( GainShape_fx[0], tmp ); /*Q(30 - exp) */ - - exp1 = norm_l( L_tmp ); - frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); /*move16(); */ - exp1 = sub( exp, exp1 ); /*move16(); */ - L_tmp = Mpy_32_16( exp1, frac, 22713 ); - temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); + exp = 13 /* norm_s(3) */; + tmp = 21845 /* div_s( shl(1, sub(14, exp)), 3 /\* 0.0001 in Q15 *\/ ) */; } ELSE { - temp_swb_fac = 0; - move16(); + exp = norm_s( hBWE_TD->prev_swb_GainShape_fx ); + tmp = div_s( shl( 1, sub( 14, exp ) ), hBWE_TD->prev_swb_GainShape_fx ); } - L_feedback = L_mult0( temp_swb_fac, temp_swb_fac ); + + L_tmp = L_mult( GainShape_fx[0], tmp ); /*Q(30 - exp) */ + + exp1 = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); /*move16(); */ + exp1 = sub( exp, exp1 ); /*move16(); */ + L_tmp = Mpy_32_16( exp1, frac, 22713 ); + temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); + + L_feedback = L_mult( temp_swb_fac, temp_swb_fac ); FOR( i = 1; i < NUM_SHB_SUBGAINS; i++ ) { test(); - IF( GainShape_fx[i] && GainShape_fx[i - 1] ) + IF( GainShape_fx[i - 1] == 0 ) { - exp = norm_s( GainShape_fx[i - 1] ); - tmp = div_s( shl( 1, sub( 14, exp ) ), GainShape_fx[i - 1] ); - L_tmp = L_mult( GainShape_fx[i], tmp ); /* Q(30 - exp) */ - - exp1 = norm_l( L_tmp ); - frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); - exp1 = sub( exp, exp1 ); - L_tmp = Mpy_32_16( exp1, frac, 22713 ); - temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); + exp = 13 /* norm_s(3) */; + tmp = 21845 /* div_s( shl(1, sub(14, exp)), 3 /\* 0.0001 in Q15 *\/ ) */; } ELSE { - temp_swb_fac = 0; - move16(); + exp = norm_s( GainShape_fx[i - 1] ); + tmp = div_s( shl( 1, sub( 14, exp ) ), GainShape_fx[i - 1] ); } + L_tmp = L_mult( GainShape_fx[i], tmp ); /* Q(30 - exp) */ + + exp1 = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); + exp1 = sub( exp, exp1 ); + L_tmp = Mpy_32_16( exp1, frac, 22713 ); + temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); L_feedback = L_mac( L_feedback, temp_swb_fac, temp_swb_fac ); } -- GitLab From 39e4615bfb5de055570ba359a8d15ee9f86119f7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 14:37:46 +0530 Subject: [PATCH 0032/1221] Clang formatting changes --- lib_com/swb_tbe_com_fx.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index deb37d9f3..02fbe9764 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -2843,19 +2843,19 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 *Q_bwe_exc, Word16 *Q_bwe_exc_fb, const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ - const Word32 bitrate, /* i : bitrate */ - const Word16 prev_bfi, /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, /* i : bitrate */ + const Word16 prev_bfi, /* i : previous frame was concealed */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ Word16 Q_EnvSHBres_4k, Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ -- GitLab From 1c0f36f0aa732ca19ae34a0a0db2cd1bd35c8a5e Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 4 Feb 2025 10:30:01 +0100 Subject: [PATCH 0033/1221] refactor the usage of f_forceModeDir in the API --- apps/encoder.c | 115 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 36 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index 36ba0bcd7..56991959f 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -201,9 +201,6 @@ int main( int16_t *pcmBuf = NULL; #ifdef DEBUGGING FILE *f_forcedModeProfile = NULL; -#ifdef DEBUG_FORCE_DIR - bool f_forceModeDir = false; -#endif #endif #ifdef WMOPS @@ -541,42 +538,15 @@ int main( #ifdef DEBUGGING IVAS_ENC_FORCED_MODE forcedMode = arg.forcedMode; int32_t force_profile_cnt = 0; -#ifdef DEBUG_FORCE_DIR - struct stat path_stat; -#endif if ( arg.forcedModeFile ) { -#ifdef DEBUG_FORCE_DIR - if ( stat( arg.forcedModeFile, &path_stat ) != 0 ) - { - fprintf( stderr, "\nError: The profile file/dir could not be opened: %s\n\n", arg.forcedModeFile ); - usage_enc(); - goto cleanup; - } - - /* check if it is a directory */ - if ( S_ISDIR( path_stat.st_mode ) ) - { - f_forceModeDir = true; - } - else - { - if ( ( f_forcedModeProfile = fopen( arg.forcedModeFile, "rb" ) ) == NULL ) - { - fprintf( stderr, "\nError: Incorrect mode specification or the profile file could not be opened: %s\n\n", arg.forcedModeFile ); - usage_enc(); - goto cleanup; - } - } -#else if ( ( f_forcedModeProfile = fopen( arg.forcedModeFile, "rb" ) ) == NULL ) { fprintf( stderr, "\nError: Incorrect mode specification or the profile file could not be opened: %s\n\n", arg.forcedModeFile ); usage_enc(); goto cleanup; } -#endif } #endif @@ -724,16 +694,12 @@ int main( } /* Force mode not set when configuring, set in first frame even if not reading from file */ - if ( f_forcedModeProfile || -#ifdef DEBUG_FORCE_DIR - f_forceModeDir || -#endif - frame == 0 ) + if ( f_forcedModeProfile || frame == 0 ) { if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode #ifdef DEBUG_FORCE_DIR , - arg.forcedModeFile + arg.forcedModeDir #endif ) ) != IVAS_ERR_OK ) { @@ -906,6 +872,9 @@ static void initArgStruct( EncArguments *arg ) #ifdef DEBUGGING arg->forcedMode = IVAS_ENC_FORCE_UNFORCED; arg->forcedModeFile = NULL; +#ifdef DEBUG_FORCE_DIR + arg->forcedModeDir = NULL; +#endif #endif arg->pca = false; @@ -1046,6 +1015,28 @@ static bool parseCmdlIVAS_enc( arg->forcedMode = parseForcedMode( stmp ); +#ifdef DEBUG_FORCE_DIR + if ( arg->forcedMode < IVAS_ENC_FORCE_FILE ) + { + fprintf( stdout, "Forcing codec to: %s\n", argv[i + 1] ); + } + else if ( arg->forcedMode == IVAS_ENC_FORCE_FILE ) + { + arg->forcedModeFile = argv[i + 1]; + fprintf( stdout, "Force switching file: %s\n", argv[i + 1] ); + } + else if ( arg->forcedMode == IVAS_ENC_FORCE_DIR ) + { + arg->forcedModeDir = argv[i + 1]; + fprintf( stdout, "Forcing switching directory: %s\n", argv[i + 1] ); + } + else + { + fprintf( stderr, "\nError: The force switching profile file/dir %s does not exist or could not be opened!\n\n", argv[i + 1] ); + usage_enc(); + return false; + } +#else if ( arg->forcedMode == IVAS_ENC_FORCE_UNDEFINED ) { arg->forcedModeFile = argv[i + 1]; @@ -1055,6 +1046,7 @@ static bool parseCmdlIVAS_enc( { fprintf( stdout, "Forcing codec to: %s\n", argv[i + 1] ); } +#endif i += 2; } @@ -1958,8 +1950,58 @@ static bool readBitrate( static IVAS_ENC_FORCED_MODE parseForcedMode( char *forcedModeChar ) { +#ifdef DEBUG_FORCE_DIR + struct stat path_stat; +#endif + to_upper( forcedModeChar ); +#ifdef DEBUG_FORCE_DIR + if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) || + ( strcmp( forcedModeChar, "0" ) == 0 ) ) + { + return IVAS_ENC_FORCE_SPEECH; + } + else if ( ( strcmp( forcedModeChar, "MUSIC" ) == 0 ) || ( strcmp( forcedModeChar, "'MUSIC'" ) == 0 ) || ( strcmp( forcedModeChar, "AUDIO" ) == 0 ) || ( strcmp( forcedModeChar, "'AUDIO'" ) == 0 ) || ( strcmp( forcedModeChar, "1" ) == 0 ) ) + { + return IVAS_ENC_FORCE_MUSIC; + } + else if ( ( strcmp( forcedModeChar, "ACELP" ) == 0 ) || ( strcmp( forcedModeChar, "'ACELP'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_ACELP; + } + else if ( ( strcmp( forcedModeChar, "GSC" ) == 0 ) || ( strcmp( forcedModeChar, "'GSC'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_GSC; + } + else if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_TCX; + } + else if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_HQ; + } + else + { + if ( stat( forcedModeChar, &path_stat ) != 0 ) + { + return IVAS_ENC_FORCE_UNDEFINED; + } + + /* check if the argument represents an existing file or directory */ + if ( S_ISDIR( path_stat.st_mode ) ) + { + /* it's a directory */ + return IVAS_ENC_FORCE_DIR; + } + else + { + /* it's a file */ + return IVAS_ENC_FORCE_FILE; + } + } +#else if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) || ( strcmp( forcedModeChar, "0" ) == 0 ) ) { @@ -1987,6 +2029,7 @@ static IVAS_ENC_FORCED_MODE parseForcedMode( } return IVAS_ENC_FORCE_UNDEFINED; +#endif } -- GitLab From 892507207f592885bd65330f94d6b28a80ead298 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 16:21:11 +0530 Subject: [PATCH 0034/1221] EVS BE fix --- lib_com/prot_fx.h | 5 ++++ lib_com/swb_tbe_com_fx.c | 60 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 407c4ce85..572241d89 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -2880,6 +2880,11 @@ void Calc_rc0_h( Word16 *rc0 /* o : 1st parcor */ ); +void Calc_rc0_h_ivas_enc_fx( + Word16 *h, /* i : impulse response of composed filter */ + Word16 *rc0 /* o : 1st parcor */ +); + void PostShortTerm_fx( Word16 *sig_in, /* i : i signal (pointer to current subframe */ Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 02fbe9764..27ce60448 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -756,6 +756,64 @@ void Calc_rc0_h( Word16 *h, /* i : impulse response of composed filter */ Word16 *rc0 /* o : 1st parcor */ ) +{ + Word32 L_acc; + Word16 *ptrs; + Word16 acf0, acf1; + Word16 temp, sh_acf; + Word16 i; + + /* computation of the autocorrelation function acf */ + L_acc = L_mult( h[0], h[0] ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + L_acc = L_mac( L_acc, h[i], h[i] ); + } + sh_acf = norm_l( L_acc ); + L_acc = L_shl( L_acc, sh_acf ); + acf0 = extract_h( L_acc ); + + ptrs = h; + + temp = *ptrs++; + move16(); + L_acc = L_mult( temp, *ptrs ); + FOR( i = 1; i < LONG_H_ST - 1; i++ ) + { + temp = *ptrs++; + move16(); + L_acc = L_mac( L_acc, temp, *ptrs ); + } + L_acc = L_shl( L_acc, sh_acf ); + acf1 = extract_h( L_acc ); + + /* Compute 1st parcor */ + IF( acf0 == 0 ) + { + *rc0 = 0; + move16(); + return; + } + + IF( LT_16( acf0, abs_s( acf1 ) ) ) + { + *rc0 = 0; + move16(); + return; + } + *rc0 = div_s( abs_s( acf1 ), acf0 ); + move16(); + IF( acf1 > 0 ) + { + *rc0 = negate( *rc0 ); + move16(); + } +} + +void Calc_rc0_h_ivas_enc_fx( + Word16 *h, /* i : impulse response of composed filter */ + Word16 *rc0 /* o : 1st parcor */ +) { Word32 L_acc; Word16 *ptrs; @@ -869,7 +927,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( /* compute i.r. of composed filter apond2 / apond1 */ syn_filt_fx( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); /* compute 1st parcor */ - Calc_rc0_h( h, parcor0 ); + Calc_rc0_h_ivas_enc_fx( h, parcor0 ); /* compute g0 */ L_g0 = L_mult0( 1, abs_s( h[0] ) ); -- GitLab From 8926070a3e56e05d2f6724ef71f19517edb796bd Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 4 Feb 2025 13:19:07 +0100 Subject: [PATCH 0035/1221] fix force_dir initialization to empty string --- lib_enc/lib_enc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 26fc04a5e..631f7bf38 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1888,10 +1888,9 @@ ivas_error IVAS_ENC_SetForcedMode( } #ifdef DEBUG_FORCE_DIR + hIvasEnc->st_ivas->hEncoderConfig->force_dir[0] = '\0'; if ( forcedMode < IVAS_ENC_FORCE_FILE ) { - hIvasEnc->st_ivas->hEncoderConfig->force_dir[0] = '\0'; - if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) { return error; -- GitLab From 0fbfb763563067e4268166f85e8e2ca7fe2fb32c Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 4 Feb 2025 13:19:39 +0100 Subject: [PATCH 0036/1221] fix element_mode read/write location --- lib_enc/ivas_stereo_classifier.c | 65 ++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index 96754c97d..bf8f74b14 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -217,17 +217,6 @@ Word16 select_stereo_mode( } } -#ifdef DEBUG_FORCE_DIR - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); - } -#endif - /* switch from LRTD to DFT when xtalk_decision goes from 0->1 (note: this special case is not handled in the xtalk classifier) */ test(); test(); @@ -252,6 +241,17 @@ Word16 select_stereo_mode( } } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); + } +#endif + IF( NE_16( hCPE->last_element_mode, element_mode ) ) { test(); @@ -914,6 +914,16 @@ void unclr_classifier_td_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_unclr_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/force_unclr_decision.enf" ); + } +#endif return; } @@ -1021,6 +1031,16 @@ void unclr_classifier_dft_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_unclr_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/force_unclr_decision.enf" ); + } +#endif return; } @@ -1169,6 +1189,17 @@ void xtalk_classifier_td_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_xtalk_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/force_xtalk_decision.enf" ); + } +#endif + return; } @@ -1389,7 +1420,6 @@ void xtalk_classifier_dft_fx( move16(); } - /* updates */ hItd->prev_m1_fx = m1; move32(); @@ -1400,6 +1430,17 @@ void xtalk_classifier_dft_fx( hItd->prev_itd2 = itd2; move16(); +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_xtalk_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/force_xtalk_decision.enf" ); + } +#endif + return; } -- GitLab From 692b63b8957dcc33488c23796a6a1198085af17c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 21:29:39 +0530 Subject: [PATCH 0037/1221] Fix for 3GPP issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB Link #1214 --- lib_com/options.h | 1 + lib_enc/igf_enc.c | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 573b619bf..24f21262e 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -149,4 +149,5 @@ #define FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS /* FhG ivas_spar_com.c: Zeroes very small negative coeffs via L_shr_r (was L_shr) */ #define FIX_ISSUE_1237 /* VA: replacement of Copy_Scale_sig_16_32_DEPREC() that are doing 16 bits left shift by Copy_Scale_sig_16_32_no_sat() */ #define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ +#define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ #endif diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 2d03fde78..0c7badb13 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -718,8 +718,13 @@ static void IGF_CalculateEnvelope_ivas_fx( Word32 mean_y_fx_tmp = 0; move32(); mean_xy_fx = mean_x2_fx = 0; +#ifdef FIX_ISSUE_1214 + mean_x_e = 15; + mean_xy_e = mean_y_e = mean_x2_e = 31; +#else mean_x_e = mean_y_e = 15; mean_xy_e = mean_x2_e = 31; +#endif move16(); move16(); move16(); @@ -736,12 +741,20 @@ static void IGF_CalculateEnvelope_ivas_fx( mean_x_fx = add( mean_x_fx, x ); /*Q0*/ mean_x2_fx = L_add( mean_x2_fx, L_mult0( x, x ) ); /*Q0*/ - test(); +#ifdef FIX_ISSUE_1214 + /*y = 20.f * log10f( max( 1.f, powerSpectrum[i] ) );*/ + IF( LE_64( W_deposit32_l( pPowerSpectrum_fx[sb] ), W_shl( 1, ( sub( 31, e_ps[sb] ) ) ) ) ) + { + y = 0; + move16(); + } +#else /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) { y = imult1616( 20, ( -18 /* log10f(1e-018f) */ ) ); } +#endif ELSE { y = imult1616( 20, extract_l( L_shr( Mult_32_16( ( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps[sb], Q25 ) ) ), INV_Log2_10_Q15 ), Q25 ) ) ); /*Q0*/ @@ -1246,13 +1259,21 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); } } - tmp_tb_fx = shl_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - tmp_sb_fx = shl_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - +#ifdef FIX_ISSUE_1214 + tmp_tb_fx = shr_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + tmp_sb_fx = shr_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ + hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ +#else + tmp_tb_fx = shl_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + tmp_sb_fx = shl_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, tmp_tb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, tmp_tb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, tmp_sb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, tmp_sb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ +#endif hPrivateData->sfb_sb_e[sfb] = 2; hPrivateData->sfb_tb_e[sfb] = 2; move16(); -- GitLab From 654635c99b9ed66cf70fc80f5c2b5e4e5a1bd147 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 21:32:51 +0530 Subject: [PATCH 0038/1221] Fix for 3GPP issue 1219: Assert in ApplyFdCng_ivas_fx of BASOP decoder for float encoder MASA bitstream using DTX at 32 kbps Link #1219 --- lib_dec/fd_cng_dec_fx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index c164d9e06..c683b25b6 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -2690,10 +2690,9 @@ void perform_noise_estimation_dec_ivas_fx( } ELSE { - Word16 tmp = s_max( sub( hFdCngDec->msPeriodog_exp, getScaleFactor32( msPeriodog, npart ) ), sub( hFdCngDec->msNoiseEst_exp, getScaleFactor32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ) ) ) ); - Copy_Scale_sig32( msPeriodog, msNoiseEst, npart, sub( hFdCngDec->msPeriodog_exp, tmp ) ); /*Q31 - tmp*/ - scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, tmp ) ); /*Q31 - tmp*/ - hFdCngDec->msNoiseEst_exp = tmp; + Copy32( msPeriodog, msNoiseEst, npart ); + scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); + hFdCngDec->msNoiseEst_exp = hFdCngDec->msPeriodog_exp; move16(); } -- GitLab From 8f8938f987946fce3e58e6dedc49ee427f58572f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Feb 2025 22:29:09 +0530 Subject: [PATCH 0039/1221] Scaling fix in encode_audio call stack --- lib_enc/enc_pit_exc_fx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 9e3b817b1..e0d4f5016 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -579,6 +579,7 @@ void enc_pit_exc_ivas_fx( Word16 use_fcb; Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ + Word16 h1_q15[PIT_EXC_L_SUBFR + ( M + 1 )]; SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; @@ -768,8 +769,9 @@ void enc_pit_exc_ivas_fx( * Codebook target computation * (No LP filtering of the adaptive excitation) *-----------------------------------------------------------------*/ + Copy_Scale_sig( h1, h1_q15, L_subfr, 1 ); // Q14 -> Q15 - lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1, + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1_q15, xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) -- GitLab From f4632eb2a1b8eb313279790532b794dcde6ffccb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Feb 2025 12:12:36 +0530 Subject: [PATCH 0040/1221] Fix for 3GPP issue 1220: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder for float encoder MASA bitstream using DTX and rate switching Link #1220 --- lib_dec/ivas_stereo_switching_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 5d5b38d4d..ad6d58ebf 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -503,7 +503,7 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init_fx( st ); + td_cng_dec_init_ivas_fx( st ); } } -- GitLab From 230098538cbf864ec269555989e18b1abcdce707 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 5 Feb 2025 09:58:35 +0100 Subject: [PATCH 0041/1221] added minor WMOPS tuning for SVD module, extends MR1010 --- lib_com/options.h | 2 ++ lib_dec/ivas_svd_dec.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 573b619bf..2508663d9 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -150,3 +150,5 @@ #define FIX_ISSUE_1237 /* VA: replacement of Copy_Scale_sig_16_32_DEPREC() that are doing 16 bits left shift by Copy_Scale_sig_16_32_no_sat() */ #define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ #endif +#define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ + diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index dc1965a5b..663dba21f 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -919,6 +919,7 @@ static void ApplyRotation_fx( *g = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), add( c_e, x12_e ), Mpy_32_32( L_negate( s ), x11 ), add( s_e, x11_e ), g_e ); /* exp(g_e) */ move32(); +#ifndef FIX_MINOR_SVD_WMOPS_MR1010X FOR( ch = 0; ch < nChannels; ch++ ) { x11 = singularVector[ch][currentIndex2]; @@ -934,6 +935,24 @@ static void ApplyRotation_fx( singularVector[ch][currentIndex1] = L_shl_sat( singularVector[ch][currentIndex1], temp_exp ); /* exp(temp_exp) */ move32(); } +#else + Word32 s_neg = L_negate(s); + Word32 temp; + FOR( ch = 0; ch < nChannels; ch++ ) + { + x11 = singularVector[ch][currentIndex2]; + move32(); + x12 = singularVector[ch][currentIndex1]; + move32(); + temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ + singularVector[ch][currentIndex2] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ + move32(); + temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( s_neg, x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ + singularVector[ch][currentIndex1] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ + move32(); + } + +#endif return; } @@ -1160,6 +1179,7 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ L_temp = Sqrt32( norm_x, &L_temp_e ); L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); +#ifndef FIX_MINOR_SVD_WMOPS_MR1010X IF( singularVectors[currChannel][idx] >= 0 ) { ( *g ) = L_negate( L_temp ); @@ -1170,6 +1190,14 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ ( *g ) = L_negate( L_negate( L_temp ) ); move32(); } +#else + if ( singularVectors[currChannel][idx] >= 0 ) + { + L_temp = L_negate( L_temp ); + } + ( *g ) = L_temp ; + move32(); +#endif #ifndef FIX_1010_OPT_SINGLE_RESCALE r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[currChannel], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ @@ -1868,6 +1896,7 @@ static Word32 maxWithSign_fx( const Word32 a /* Qx */ ) { +#ifndef FIX_MINOR_SVD_WMOPS_MR1010X IF( GT_32( L_abs( a ), SVD_MINIMUM_VALUE_FX ) ) { return a; @@ -1880,6 +1909,18 @@ static Word32 maxWithSign_fx( { return SVD_MINIMUM_VALUE_FX; } +#else + Word32 result; + if (a >= 0) + { + result = L_max( a, SVD_MINIMUM_VALUE_FX ); + } + if (a < 0) + { + result = L_min( a, -SVD_MINIMUM_VALUE_FX ); + } + return result; +#endif } /*------------------------------------------------------------------------- -- GitLab From e4bcf47dc095ed5dbe27e1ad71625d633136af9f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Feb 2025 14:31:46 +0530 Subject: [PATCH 0042/1221] Q documentation, BASOP/instrumentation updates and bug fix in swb_bwe_enc_ivas_fx --- Workspace_msvc/lib_enc.vcxproj | 2 - Workspace_msvc/lib_enc.vcxproj.filters | 4 - lib_com/prot.h | 2 +- lib_com/prot_fx.h | 2 +- lib_enc/core_switching_enc.c | 2 + lib_enc/hvq_enc_fx.c | 13 +- lib_enc/igf_enc.c | 216 +++++++++++-------------- lib_enc/igf_enc_fx.c | 115 +++++++------ lib_enc/igf_scf_enc.c | 14 +- lib_enc/igf_scf_enc_fx.c | 14 +- lib_enc/init_enc.c | 8 +- lib_enc/init_enc_fx.c | 75 +++++---- lib_enc/inov_enc_fx.c | 5 +- lib_enc/isf_enc_amr_wb_fx.c | 9 +- lib_enc/nelp_enc_fx.c | 104 ++++++++---- lib_enc/nois_est.c | 46 ------ lib_enc/nois_est_fx.c | 142 +++++++++------- lib_enc/noise_adjust.c | 43 ----- lib_enc/stat_enc.h | 1 + lib_enc/swb_bwe_enc_fx.c | 8 +- 20 files changed, 424 insertions(+), 401 deletions(-) delete mode 100644 lib_enc/nois_est.c delete mode 100644 lib_enc/noise_adjust.c diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 1a706cfeb..75831970e 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -379,8 +379,6 @@ - - diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 907b5b945..ac23c810f 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -216,10 +216,6 @@ enc_all_c - - enc_all_c - - enc_all_c diff --git a/lib_com/prot.h b/lib_com/prot.h index 9985ca978..a2a2cdac3 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -8161,7 +8161,7 @@ void IGFEncApplyStereo( ); -void IGFEncResetTCX10BitCounter( +void IGFEncResetTCX10BitCounter_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ ); diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 572241d89..daf2c80d5 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -10887,7 +10887,7 @@ Word16 IGFEncWriteBitstream_ivas_fx( const Word16 isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ ); /*igf_scf_enc.c*/ -Word16 IGFSCFEncoderEncode( +Word16 IGFSCFEncoderEncode_ivas_fx( IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 bitCount, /* i : offset to the first bit in bitbuffer which should be readed by iisArithDecoderDecode function */ diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c index d58a60ab2..67c7a552f 100644 --- a/lib_enc/core_switching_enc.c +++ b/lib_enc/core_switching_enc.c @@ -431,7 +431,9 @@ void core_switching_pre_enc_ivas_fx( move16(); } hBWE_FD->EnergyLF_fx = 0; + hBWE_FD->EnergyLF_exp = 0; move32(); + move16(); hBWE_FD->prev_L_swb_norm1 = 8; move16(); /*8.0 in Q0 */ st_fx->EnergyLT_fx_exp = 30; diff --git a/lib_enc/hvq_enc_fx.c b/lib_enc/hvq_enc_fx.c index 5414329e2..54bc4fb58 100644 --- a/lib_enc/hvq_enc_fx.c +++ b/lib_enc/hvq_enc_fx.c @@ -13,7 +13,7 @@ #define HVQ_ENC_NOISE_DELTA ( (Word16) 3277 ) /* 0.1 in Q15 */ -static Word16 quant_lc( const Word16, Word16 * ); +static Word16 quant_lc_fx( const Word16, Word16 * ); /*--------------------------------------------------------------------------* @@ -149,7 +149,7 @@ Word16 hvq_enc_ivas_fx( /*o : Consumed bits adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */ noise_level[i] = extract_h( L_shr_o( acc, adjust, &Overflow ) ); /* noise_level[] in Q15 */ move16(); - q_noise_level_idx[i] = quant_lc( noise_level[i], &q_noise_level[i] ); + q_noise_level_idx[i] = quant_lc_fx( noise_level[i], &q_noise_level[i] ); move16(); } ELSE @@ -229,6 +229,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits Word16 tmp16, adjust; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif bits_used = 0; move16(); @@ -324,7 +325,9 @@ Word16 hvq_enc_fx( /*o : Consumed bits /* Number of bits required to adjust to Q15 */ adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */ noise_level[i] = extract_h( L_shr_o( acc, adjust, &Overflow ) ); /* noise_level[] in Q15 */ - q_noise_level_idx[i] = quant_lc( noise_level[i], &q_noise_level[i] ); + move16(); + q_noise_level_idx[i] = quant_lc_fx( noise_level[i], &q_noise_level[i] ); + move16(); } ELSE { @@ -337,6 +340,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits bits_used = add( bits_used, 2 ); noise_level[i] = q_noise_level[i]; /* in Q15 */ + move16(); } FOR( i = 0; i < HVQ_NF_GROUPS; i++ ) @@ -367,6 +371,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits } nBits = peak_vq_enc_fx( st_fx->hBstr, st_fx->bwidth, coefs, coefs_out, core_brate, sub( hvq_bits, bits_used ), Npeaks, ynrm, R, peaks, &nf_gains[0] ); + move16(); bits_used = add( bits_used, nBits ); return bits_used; } @@ -376,7 +381,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits * * Quantize the noise to one of the levels in {0, 0.1, 0.2, 0.3} *----------------------------------------------------------------------------*/ -static Word16 quant_lc( const Word16 x, Word16 *qx ) +static Word16 quant_lc_fx( const Word16 x, Word16 *qx ) { Word16 indx; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 0c7badb13..6cccea43b 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -51,11 +51,11 @@ #define INV_Log2_10_Q12 1233 /*1/log2(10) in Q12*/ #define INV_Log2_e_Q15 22713 /*1/log2(e) in Q15*/ /*-------------------------------------------------------------------* - * IGF_write_bit() + * IGF_write_bit_fx() * * write single bit to stream *-------------------------------------------------------------------*/ -static void IGF_write_bit( +static void IGF_write_bit_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 *bitCount, /* i/o: bit counter */ const Word16 value /* i : value */ @@ -88,11 +88,11 @@ static void IGF_write_bits( { IF( s_and( value, shl( 1, bits ) ) == 0 ) { - IGF_write_bit( hBstr, bitCount, 0 ); + IGF_write_bit_fx( hBstr, bitCount, 0 ); } ELSE { - IGF_write_bit( hBstr, bitCount, 1 ); + IGF_write_bit_fx( hBstr, bitCount, 1 ); } } @@ -290,27 +290,27 @@ static Word32 IGF_getTNR_fx( width = sub( stop, start ); FOR( i = start; i < stop; i++ ) { - rootSpec_e[sub( i, start )] = e_ps; + rootSpec_e[i - start] = e_ps; move16(); - rootSpec[sub( i, start )] = Sqrt32( powerSpectrum[i], &rootSpec_e[sub( i, start )] ); /*rootSpec[i - start] = sqrtf( powerSpectrum[i] );*/ + rootSpec[i - start] = Sqrt32( powerSpectrum[i], &rootSpec_e[i - start] ); /*rootSpec[i - start] = sqrtf( powerSpectrum[i] );*/ move32(); - avg = BASOP_Util_Add_Mant32Exp( avg, avg_e, rootSpec[sub( i, start )], rootSpec_e[sub( i, start )], &avg_e ); /*avg += rootSpec[i - start];resultant exponent is avg_e*/ + avg = BASOP_Util_Add_Mant32Exp( avg, avg_e, rootSpec[i - start], rootSpec_e[i - start], &avg_e ); /*avg += rootSpec[i - start];resultant exponent is avg_e*/ } avg = BASOP_Util_Divide3216_Scale( avg, width, &tmp_e ); /*avg /= width;*/ avg_e = add( 16, sub( add( avg_e, tmp_e ), 15 ) ); FOR( i = start; i < stop; i++ ) { - Word16 normSpec_e; /*stores resultant exponent for normSpec*/ - Word16 normSpec = BASOP_Util_Divide3232_Scale( rootSpec[sub( i, start )], avg, &normSpec_e ); /*rootSpec[i - start] / avg;*/ - normSpec_e = add( normSpec_e, sub( rootSpec_e[sub( i, start )], avg_e ) ); + Word16 normSpec_e; /*stores resultant exponent for normSpec*/ + Word16 normSpec = BASOP_Util_Divide3232_Scale( rootSpec[i - start], avg, &normSpec_e ); /*rootSpec[i - start] / avg;*/ + normSpec_e = add( normSpec_e, sub( rootSpec_e[i - start], avg_e ) ); IF( GT_32( normSpec, L_add( L_shl( 1, sub( 15, normSpec_e ) ), L_shl( adap, sub( e_adap, normSpec_e ) ) ) ) ) { - tonal = BASOP_Util_Add_Mant32Exp( tonal, tonal_e, rootSpec[sub( i, start )], rootSpec_e[sub( i, start )], &tonal_e ); /*tonal += rootSpec[i - start];*/ + tonal = BASOP_Util_Add_Mant32Exp( tonal, tonal_e, rootSpec[i - start], rootSpec_e[i - start], &tonal_e ); /*tonal += rootSpec[i - start];*/ } ELSE IF( LT_32( normSpec, L_shl( 1, sub( 15, normSpec_e ) ) ) ) { - noise = BASOP_Util_Add_Mant32Exp( noise, noise_e, rootSpec[sub( i, start )], rootSpec_e[sub( i, start )], &noise_e ); /*noise += rootSpec[i - start];*/ + noise = BASOP_Util_Add_Mant32Exp( noise, noise_e, rootSpec[i - start], rootSpec_e[i - start], &noise_e ); /*noise += rootSpec[i - start];*/ } } @@ -318,7 +318,6 @@ static Word32 IGF_getTNR_fx( IF( noise == 0 ) // To handle condition if denom = 0 { tonalToNoise = imult3216( L_shr( L_add( L_shl( 18 /* log10f(1e-018f) */, Q25 ), Mpy_32_16_1( L_add( BASOP_Util_Log2( tonal ), L_shl( tonal_e, Q25 ) ) /*Q25*/, INV_Log2_10_Q15 ) /*25+15-15*/ ), 3 ) /*Q22*/, 20 ); - move32(); } ELSE { @@ -482,7 +481,7 @@ static void IGF_CalculateEnvelope_ivas_fx( Word16 tmp_e; hPrivateData = &hIGFEnc->igfData; - hGrid = &hPrivateData->igfInfo.grid[(int16_t) igfGridIdx]; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; swb_offset = hGrid->swb_offset; IF( element_mode > EVS_MONO ) @@ -555,7 +554,6 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); move16(); move16(); - move16(); IF( pPowerSpectrum_fx != NULL ) { @@ -613,7 +611,6 @@ static void IGF_CalculateEnvelope_ivas_fx( gain = Mult_32_16( sfbEnergyTileR, temp ); // gain_e gain_e = add( tmp_e, sfbEnergyTileR_e ); - test(); IF( element_mode > EVS_MONO ) { test(); @@ -664,14 +661,17 @@ static void IGF_CalculateEnvelope_ivas_fx( Word16 tmp0, tmp2, tmp3, tmp4; Word16 tmp0_e, tmp2_e, tmp3_e, tmp4_e; tmp0 = shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], 2 ); - tmp0_e = hPrivateData->prevSFB_FIR_TB_e[sfb] + 2; + tmp0_e = add( hPrivateData->prevSFB_FIR_TB_e[sfb], 2 ); + move16(); tmp2 = shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], 2 ); - tmp2_e = hPrivateData->prevSFB_IIR_TB_e[sfb] + 2; + tmp2_e = add( hPrivateData->prevSFB_IIR_TB_e[sfb], 2 ); + move16(); tmp3 = shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], 2 ); - tmp3_e = hPrivateData->prevSFB_FIR_SB_e[sfb] + 2; + tmp3_e = add( hPrivateData->prevSFB_FIR_SB_e[sfb], 2 ); + move16(); tmp4 = shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], 2 ); - tmp4_e = hPrivateData->prevSFB_IIR_SB_e[sfb] + 2; - + tmp4_e = add( hPrivateData->prevSFB_IIR_SB_e[sfb], 2 ); + move16(); Word16 x1, x2; Word16 x1_e = BASOP_Util_Add_MantExp( tmp0, tmp0_e, tmp2, tmp2_e - 1, &x1 ); @@ -735,7 +735,6 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); move16(); - test(); FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ ) { mean_x_fx = add( mean_x_fx, x ); /*Q0*/ @@ -749,6 +748,7 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); } #else + /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) { @@ -877,8 +877,7 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); hPrivateData->prevDampingFactor_IIR_e[sfb] = dampingFactor_e; move16(); - test(); - IF( hPrivateData->dampingFactorSmoothing[sfb] > 0 ) + if ( hPrivateData->dampingFactorSmoothing[sfb] > 0 ) { hPrivateData->dampingFactorSmoothing[sfb] = sub( hPrivateData->dampingFactorSmoothing[sfb], 1 ); move16(); @@ -941,6 +940,7 @@ static void IGF_CalculateEnvelope_ivas_fx( ELSE { tmp_e = e_mdct; + move16(); sfbEnergyR = add_sat( EPSILON_FX, BASOP_Util_Divide3216_Scale( sum2_32_fx( pMDCTSpectrum_fx + swb_offset[sfb], width, &tmp_e ) /*exp: tmp_e*/, width, &sfbEnergyR_e ) ); // sfbEnergyR_e sfbEnergyR_e = add( sfbEnergyR_e, add( tmp_e, -15 ) ); gain = sfbEnergyR; // gain_e @@ -1069,7 +1069,7 @@ static void IGF_CalculateStereoEnvelope_fx( swb_offset = hGrid->swb_offset; move16(); - IF( NE_16( igfGridIdx, IGF_GRID_LB_NORM ) ) + IF( igfGridIdx != IGF_GRID_LB_NORM ) { FOR( sfbCnt = 0; sfbCnt < sub( hGrid->sfbWrap[hGrid->nTiles], hGrid->sfbWrap[0] ); sfbCnt++ ) { @@ -1097,7 +1097,7 @@ static void IGF_CalculateStereoEnvelope_fx( { FOR( sb = hGrid->sbWrap[0]; sb < swb_offset[hGrid->sfbWrap[hGrid->nTiles]]; sb++ ) { - /*hPrivateData->logSpec[sb] = max( 0, (int16_t) ( logf( max( FLT_MIN, pPowerSpectrum[sb] ) ) * INV_LOG_2 ) );*/ + /*hPrivateData->logSpec[sb] = max( 0, (Word16) ( logf( max( FLT_MIN, pPowerSpectrum[sb] ) ) * INV_LOG_2 ) );*/ IF( LE_32( 1, pPowerSpectrum_fx[sb] ) ) { hPrivateData->logSpec[sb] = s_max( 0, (Word16) L_shr( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( pPowerSpectrum_e, Q25 ) ), 25 ) ); @@ -1163,6 +1163,7 @@ static void IGF_CalculateStereoEnvelope_fx( tileSrcSpec_e = pPowerSpectrum_e; } move32(); + move16(); strt_cpy = add( strt_cpy, 1 ); } @@ -1234,10 +1235,10 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], diff_tb_e ); hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], diff_tb_e ); - hPrivateData->prevSFB_FIR_TB_e[sfb] = tmp_tb_e; - hPrivateData->prevSFB_IIR_TB_e[sfb] = tmp_tb_e; move16(); move16(); + hPrivateData->prevSFB_FIR_TB_e[sfb] = tmp_tb_e; + hPrivateData->prevSFB_IIR_TB_e[sfb] = tmp_tb_e; move16(); move16(); } @@ -1251,10 +1252,10 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], diff_sb_e ); hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], diff_sb_e ); - hPrivateData->prevSFB_FIR_SB_e[sfb] = tmp_sb_e; - hPrivateData->prevSFB_IIR_SB_e[sfb] = tmp_sb_e; move16(); move16(); + hPrivateData->prevSFB_FIR_SB_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_IIR_SB_e[sfb] = tmp_sb_e; move16(); move16(); } @@ -1274,14 +1275,12 @@ static void IGF_CalculateStereoEnvelope_fx( hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, tmp_sb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, tmp_sb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ #endif - hPrivateData->sfb_sb_e[sfb] = 2; - hPrivateData->sfb_tb_e[sfb] = 2; - move16(); - move16(); move16(); move16(); move16(); move16(); + hPrivateData->sfb_sb_e[sfb] = 2; + hPrivateData->sfb_tb_e[sfb] = 2; move16(); move16(); @@ -1312,10 +1311,11 @@ static void IGF_CalculateStereoEnvelope_fx( mean_x_fx = add( mean_x_fx, x ); /*Q0*/ mean_x2_fx = L_add( mean_x2_fx, L_mult0( x, x ) ); /*Q0*/ - /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ + /*y = 20 * (Word16) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) { y = 20 * ( -18 ); + move16(); } ELSE { @@ -1342,7 +1342,7 @@ static void IGF_CalculateStereoEnvelope_fx( /* determine whether strong tilt is due to a step in the spectrum (e.g. band limitation, no damping) or a tonal component close the band border (apply damping) by calculating SFM for a shift of 1/2 SFB width*/ threshold_fx = BASOP_Util_Divide1616_Scale( 60, width, &threshold_e ); /*stores resultant exponent for threshold_fx*/ - + test(); IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( slope_fx, add( slope_e, 16 ), negate( threshold_fx ), add( threshold_e, 16 ) ), -1 ) ) { Word16 shift = shr( width, 1 ); @@ -1381,7 +1381,8 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); move16(); } - + test(); + test(); IF( last_core_acelp || hPrivateData->wasTransient || EQ_32( hPrivateData->prevDampingFactor_IIR_fx[sfb], L_shl( -1, sub( 15, hPrivateData->prevDampingFactor_IIR_e[sfb] ) ) ) ) { tmp = BASOP_Util_Cmp_Mant32Exp( currDampingFactor_fx, currDampingFactor_e, 3277, 0 ); @@ -1525,11 +1526,15 @@ static void IGF_CalculateStereoEnvelope_fx( } /*gain=0.5f+log2f(gain)*2+16 becuase 2.885390081777927f=2*1/loge(2) so 2*1/loge(2)*loge(x) can be written as 2*log2(x)*/ gain_fx = L_add( ONE_IN_Q22, L_add( L_add( L_shr( BASOP_Util_Log2( gain_fx ), 1 ), L_shl( gain_e, Q24 ) ), L_shl( 16, Q23 ) ) ); /*Q23*/ - IF( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) ) + test(); + test(); + if ( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) ) { gain_fx = L_add( gain_fx, ONE_IN_Q21 ); /* better preservation of original HF band energy */ } - IF( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_64000_CPE ) ) ) + test(); + test(); + if ( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_64000_CPE ) ) ) { gain_fx = L_add( gain_fx, ONE_IN_Q20 ); } @@ -1588,33 +1593,33 @@ static Word16 IGF_WriteEnvelope( IF( *igfAllZero != 0 ) { - IGF_write_bit( hBstr, pBitOffset, 1 ); + IGF_write_bit_fx( hBstr, pBitOffset, 1 ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } IGFSCFEncoderReset_fx( &hPrivateData->hIGFSCFArithEnc ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } } ELSE { - IGF_write_bit( hBstr, pBitOffset, 0 ); + IGF_write_bit_fx( hBstr, pBitOffset, 0 ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } - *pBitOffset = IGFSCFEncoderEncode( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag ); + *pBitOffset = IGFSCFEncoderEncode_ivas_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag ); move16(); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } @@ -1710,7 +1715,7 @@ static void IGF_Whitening_ivas_fx( /* if current tile contains only a single SFB, reuse already computed SFM values */ test(); - IF( GT_16( element_mode, EVS_MONO ) && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) + IF( element_mode > EVS_MONO && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) { tmp = hPrivateData->SFM_tb_fx[p]; tmp_e = hPrivateData->sfb_tb_e[p]; @@ -1843,7 +1848,7 @@ static void IGF_Whitening_ivas_fx( ELSE { test(); - IF( GT_16( element_mode, EVS_MONO ) && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) + IF( element_mode > EVS_MONO && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) { SFM = shl( tmp, sub( tmp_e, 2 ) ); /*2Q13*/ } @@ -1875,7 +1880,7 @@ static void IGF_Whitening_ivas_fx( } } - IF( GT_16( element_mode, EVS_MONO ) ) + IF( element_mode > EVS_MONO ) { IF( last_core_acelp ) /* reset */ { @@ -1982,7 +1987,7 @@ static void IGF_Whitening_ivas_fx( } } - IF( GT_16( element_mode, EVS_MONO ) ) + IF( element_mode > EVS_MONO ) { IF( EQ_16( SFM, -ONE_IN_Q13 /*1.0f 2Q13*/ ) ) /* reset */ { @@ -2029,7 +2034,10 @@ static void IGF_Whitening_ivas_fx( break; } } - + test(); + test(); + test(); + test(); /* if tonality oscillates between two tiles, turn whitening off in both */ IF( ( ( pastSfmDiffSum_a > 0 && pastSfmDiffSum_b < 0 ) || ( pastSfmDiffSum_a < 0 && pastSfmDiffSum_b > 0 ) ) && @@ -2078,16 +2086,16 @@ static void IGF_Whitening_ivas_fx( /*-------------------------------------------------------------------* - * IGF_WriteWhiteningTile() + * IGF_WriteWhiteningTile_fx() * * write whitening levels into bitstream *-------------------------------------------------------------------*/ /*! r: number of bits written */ -static Word16 IGF_WriteWhiteningTile( /**< out: Q0 | number of bits written */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ +static Word16 IGF_WriteWhiteningTile_fx( /**< out: Q0 | number of bits written */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ ) { Word16 totBitCount; @@ -2121,17 +2129,17 @@ static Word16 IGF_WriteWhiteningTile( /**< out: Q0 | numb /*-------------------------------------------------------------------* - * IGF_WriteWhiteningLevels() + * IGF_WriteWhiteningLevels_fx() * * writes the whitening levels *-------------------------------------------------------------------*/ -static Word16 IGF_WriteWhiteningLevels( /**< out: Q0 | total number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ - const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ +static Word16 IGF_WriteWhiteningLevels_fx( /**< out: Q0 | total number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ + const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ ) { IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; @@ -2165,7 +2173,7 @@ static Word16 IGF_WriteWhiteningLevels( move16(); tmp32 = 0; move32(); - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -2188,11 +2196,12 @@ static Word16 IGF_WriteWhiteningLevels( { IGF_write_bits( hBstr, pBitOffset, 0, 1 ); } - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); p = 1; move16(); tmp32 = 0; move32(); + test(); IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) { isSame = 1; @@ -2205,7 +2214,7 @@ static Word16 IGF_WriteWhiteningLevels( isSame = 1; move16(); } - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -2224,7 +2233,7 @@ static Word16 IGF_WriteWhiteningLevels( IGF_write_bits( hBstr, pBitOffset, 1, 1 ); FOR( p = 1; p < nTiles; p++ ) { - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); } } ELSE IF( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) && NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) @@ -2240,16 +2249,16 @@ static Word16 IGF_WriteWhiteningLevels( /*-------------------------------------------------------------------* - * IGF_WriteFlatteningTrigger() + * IGF_WriteFlatteningTrigger_fx() * * write flattening trigger *-------------------------------------------------------------------*/ /*! r: number of bits written */ -static Word16 IGF_WriteFlatteningTrigger( /**< out: | number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ +static Word16 IGF_WriteFlatteningTrigger_fx( /**< out: | number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ ) { Word16 flatteningTrigger; @@ -2312,15 +2321,15 @@ Word16 IGFEncWriteBitstream_ivas_fx( isIndepFlag, /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ &igfAllZero ); /* o: *igfAllZero */ - IGF_WriteWhiteningLevels( hIGFEnc, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset, /* i: ptr to bitOffset counter */ - igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ - isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ + IGF_WriteWhiteningLevels_fx( hIGFEnc, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset, /* i: ptr to bitOffset counter */ + igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ + isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ - IGF_WriteFlatteningTrigger( hIGFEnc, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset ); /* i: ptr to bitOffset counter */ + IGF_WriteFlatteningTrigger_fx( hIGFEnc, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset ); /* i: ptr to bitOffset counter */ hIGFEnc->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount ); hIGFEnc->infoTotalBitsWritten = add( hIGFEnc->infoTotalBitsWritten, hIGFEnc->infoTotalBitsPerFrameWritten ); @@ -2329,34 +2338,6 @@ Word16 IGFEncWriteBitstream_ivas_fx( return hIGFEnc->infoTotalBitsPerFrameWritten; } -int16_t IGFEncWriteBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t *pBitOffset, /* i : ptr to bitOffset counter */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ -) -{ - int16_t igfAllZero; - int16_t startBitCount = *pBitOffset; - - hIGFEnc->infoTotalBitsPerFrameWritten = 0; - if ( isIndepFlag ) - { - hIGFEnc->infoTotalBitsWritten = 0; - } - - IGF_WriteEnvelope( hIGFEnc, hBstr, pBitOffset, igfGridIdx, isIndepFlag, &igfAllZero ); - - IGF_WriteWhiteningLevels( hIGFEnc, hBstr, pBitOffset, igfGridIdx, isIndepFlag ); - - IGF_WriteFlatteningTrigger( hIGFEnc, hBstr, pBitOffset ); - - hIGFEnc->infoTotalBitsPerFrameWritten = ( *pBitOffset - startBitCount ); - hIGFEnc->infoTotalBitsWritten += hIGFEnc->infoTotalBitsPerFrameWritten; - - return hIGFEnc->infoTotalBitsPerFrameWritten; -} /*-------------------------------------------------------------------* @@ -2534,12 +2515,12 @@ return; /*-------------------------------------------------------------------* - * IGFEncResetTCX10BitCounter() + * IGFEncResetTCX10BitCounter_ivas_fx() * * IGF reset bitstream bit counter for TCX10 modes *-------------------------------------------------------------------*/ -void IGFEncResetTCX10BitCounter( +void IGFEncResetTCX10BitCounter_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ ) { @@ -2548,7 +2529,8 @@ void IGFEncResetTCX10BitCounter( hPrivateData = &hIGFEnc->igfData; hPrivateData->igfBitstreamBits = 0; hIGFEnc->infoTotalBitsWritten = 0; - + move16(); + move16(); return; } @@ -2560,14 +2542,14 @@ void IGFEncResetTCX10BitCounter( *-------------------------------------------------------------------*/ /*! r: total number of bits written */ -int16_t IGFEncWriteConcatenatedBitstream( +Word16 IGFEncWriteConcatenatedBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ ) { IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - int16_t i; - int16_t bitsLeft; + Word16 i; + Word16 bitsLeft; UWord8 *pBitstream; hPrivateData = &hIGFEnc->igfData; @@ -2581,7 +2563,7 @@ int16_t IGFEncWriteConcatenatedBitstream( bitsLeft = hPrivateData->igfBitstreamBits & 0x7; if ( bitsLeft > 0 ) { - push_next_indice( hBstr, pBitstream[i] >> ( 8 - bitsLeft ), bitsLeft ); + push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); } return hIGFEnc->infoTotalBitsWritten; @@ -2622,7 +2604,6 @@ void IGFEncApplyMono_ivas_fx( Word16 common_pPowerSpectrum_exp = MIN16B; move16(); - test(); IF( st->last_core == ACELP_CORE ) { last_core_acelp = 1; @@ -2656,7 +2637,6 @@ void IGFEncApplyMono_ivas_fx( IGF_CalculateEnvelope_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, e_mdct, pPowerSpectrumParameter_fx, pPowerSpectrumParameter_exp, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, st->element_mode, att_fx ); - test(); IF( isTCX20 ) { pPowerSpectrumParameter_fx = pPowerSpectrum_fx; @@ -2740,7 +2720,7 @@ void IGFEncApplyStereo_fx( { sfbConf = &hStereoMdct->stbParamsTCX10; } - if ( EQ_16( sts[0]->last_core, ACELP_CORE ) ) + if ( sts[0]->last_core == ACELP_CORE ) { sfbConf = &hStereoMdct->stbParamsTCX20afterACELP; } diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 9e38d4d6c..268166ba9 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -17,7 +17,7 @@ /**********************************************************************/ /* write single bit to stream **************************************************************************/ -static void IGF_write_bit( +static void IGF_write_bit_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 *bitCount, /**< in/out: | bit counter */ Word16 bit /**< in: | value of bit */ @@ -44,11 +44,11 @@ static void IGF_write_bits( tmp = s_and( value, shl( 1, bits ) ); IF( tmp == 0 ) { - IGF_write_bit( hBstr, bitCount, 0 ); + IGF_write_bit_fx( hBstr, bitCount, 0 ); } ELSE { - IGF_write_bit( hBstr, bitCount, 1 ); + IGF_write_bit_fx( hBstr, bitCount, 1 ); } } @@ -96,6 +96,7 @@ static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< Word16 shift; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* initialize variables */ @@ -310,21 +311,21 @@ static void IGF_WriteEnvelope( /**< ou IF( *igfAllZero != 0 ) { - IGF_write_bit( hBstr, pBitOffset, 1 ); - IF( NULL == hBstr ) + IGF_write_bit_fx( hBstr, pBitOffset, 1 ); + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } IGFSCFEncoderReset_fx( &hPrivateData->hIGFSCFArithEnc ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } } ELSE { - IGF_write_bit( hBstr, pBitOffset, 0 ); - IF( NULL == hBstr ) + IGF_write_bit_fx( hBstr, pBitOffset, 0 ); + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } @@ -332,7 +333,7 @@ static void IGF_WriteEnvelope( /**< ou *pBitOffset = IGFSCFEncoderEncode_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag ); move16(); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } @@ -375,6 +376,8 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; Flag Carry = 0; + move32(); + move32(); #endif hPrivateData = &hInstance->igfData; @@ -412,13 +415,16 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou FOR( i = 0; i < igfBgn; i++ ) { Carry = 0; + move32(); highPassEner = L_add_co( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/, &Carry, &Overflow ); Overflow = 0; + move32(); L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); } highPassEner = norm_llQ31( L_c, highPassEner, highPassEner_exp ); /*Q20, highPassEner_exp*/ *highPassEner_exp = add( *highPassEner_exp, pPowerSpectrum_exp ); + move16(); test(); test(); if ( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) && @@ -477,9 +483,10 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou BASOP_SATURATE_WARNING_OFF_EVS L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl ); BASOP_SATURATE_WARNING_ON_EVS - IF( L_tmp < 0 ) + if ( L_tmp < 0 ) { pSpectrum[i] = L_deposit_l( 0 ); + move32(); } } @@ -487,7 +494,9 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ ) { pSpectrum[i] = L_deposit_l( 0 ); + move32(); pPowerSpectrum[i] = L_deposit_l( 0 ); + move32(); } FOR( sfb = startSfb; sfb < stopSfb; sfb++ ) @@ -772,7 +781,7 @@ Word16 IGF_getCrest( /**< ou tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/ crest = extract_h( tmp32 ); *crest_exp = add( sub( s, i ), 15 ); - + move16(); /* limit crest factor to a lower bound of 1, may overflow */ BASOP_SATURATE_WARNING_OFF_EVS tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */ @@ -816,6 +825,8 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; Flag Carry = 0; + move32(); + move32(); #endif L_c = 0; @@ -849,9 +860,10 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value num = L_add( num, L_deposit_l( n ) ); /*Q0*/ Carry = 0; + move32(); denom = L_add_co( energy[i], denom, &Carry, &Overflow ); Overflow = 0; - + move32(); L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); } @@ -890,7 +902,7 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value s = norm_l( SFM32 ); SFM = round_fx_sat( L_shl_sat( SFM32, s ) ); *SFM_exp = sub( *SFM_exp, s ); - + move16(); /**SFM_exp = s_min(*SFM_exp, 0);*/ IF( *SFM_exp > 0 ) { @@ -936,6 +948,7 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in { /* reset filter */ hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 ); + move32(); hPrivateData->prevSFM_IIR[p] = 0; move16(); @@ -959,6 +972,7 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in IF( powerSpectrum ) { Word16 nT = hGrid->nTiles; + move16(); SWITCH( hPrivateData->igfInfo.bitRateIndex ) { case IGF_BITRATE_WB_9600: @@ -1054,6 +1068,7 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in FOR( p = 0; p < IGF_MAX_TILES; p++ ) { hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 ); + move32(); hPrivateData->prevSFM_IIR[p] = 0; move16(); } @@ -1065,10 +1080,10 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in /**********************************************************************/ /* write whitening levels into bitstream **************************************************************************/ -static void IGF_WriteWhiteningTile( /**< out: Q0 | number of bits written */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ +static void IGF_WriteWhiteningTile_fx( /**< out: Q0 | number of bits written */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ ) { IF( EQ_32( whiteningLevel, IGF_WHITENING_MID ) ) @@ -1089,15 +1104,15 @@ static void IGF_WriteWhiteningTile( /**< ou } } -/**********************************************************************/ /* - writes the whitening levels - **************************************************************************/ -static void IGF_WriteWhiteningLevels( /**< out: Q0 | total number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ - const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ +/**********************************************************************/ /* + writes the whitening levels + **************************************************************************/ +static void IGF_WriteWhiteningLevels_fx( /**< out: Q0 | total number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ + const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ ) { IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; @@ -1126,7 +1141,7 @@ static void IGF_WriteWhiteningLevels( / move16(); tmp32 = 0; move32(); - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -1149,7 +1164,7 @@ static void IGF_WriteWhiteningLevels( / { IGF_write_bits( hBstr, pBitOffset, 0, 1 ); } - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); p = 1; move16(); tmp32 = 0; @@ -1159,7 +1174,7 @@ static void IGF_WriteWhiteningLevels( / isSame = 1; move16(); } - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -1177,7 +1192,7 @@ static void IGF_WriteWhiteningLevels( / IGF_write_bits( hBstr, pBitOffset, 1, 1 ); FOR( p = 1; p < nTiles; p++ ) { - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); } } ELSE @@ -1187,13 +1202,13 @@ static void IGF_WriteWhiteningLevels( / } } -/**********************************************************************/ /* - write flattening trigger - **************************************************************************/ -static void IGF_WriteFlatteningTrigger( /**< out: | number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ +/**********************************************************************/ /* + write flattening trigger + **************************************************************************/ +static void IGF_WriteFlatteningTrigger_fx( /**< out: | number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ ) { Word16 flatteningTrigger; @@ -1263,19 +1278,20 @@ Word16 IGFEncWriteBitstream_fx( /**< ou isIndepFlag, /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ &igfAllZero ); /* o: *igfAllZero */ - IGF_WriteWhiteningLevels( hInstance, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset, /* i: ptr to bitOffset counter */ - igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ - isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ + IGF_WriteWhiteningLevels_fx( hInstance, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset, /* i: ptr to bitOffset counter */ + igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ + isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ - IGF_WriteFlatteningTrigger( hInstance, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset ); /* i: ptr to bitOffset counter */ + IGF_WriteFlatteningTrigger_fx( hInstance, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset ); /* i: ptr to bitOffset counter */ hInstance->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount ); hInstance->infoTotalBitsWritten = add( hInstance->infoTotalBitsWritten, hInstance->infoTotalBitsPerFrameWritten ); - + move16(); + move16(); return hInstance->infoTotalBitsPerFrameWritten; } @@ -1373,7 +1389,7 @@ static void pack_bit_ivas_fx( move16(); } - IF( bit != 0 ) + if ( bit != 0 ) { **pt = (UWord8) s_or( **pt, *omask ); move16(); @@ -1422,6 +1438,7 @@ void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, move16(); omask = (UWord8) UL_lshr( 0x80, s_and( *pFrame_size, 0x7 ) ); + move16(); pFrame += *pFrame_size >> 3; /* bitstream packing (conversion of individual indices into a serial stream) */ @@ -1468,7 +1485,7 @@ void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /** hPrivateData = &hInstance->igfData; *next_ind = *next_ind - bsBits; - + move16(); indices_to_serial_generic( &ind_list_fx[*next_ind], bsBits, @@ -1476,7 +1493,7 @@ void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /** &hPrivateData->igfBitstreamBits ); *nb_bits = sub( *nb_bits, bsBits ); - + move16(); return; } diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index 04ca67979..e9ef96e1a 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -98,6 +98,7 @@ static void arith_encode_bits( 32767, /* disable the bit count limitation */ &hPrivateData->acState, bit ); + move16(); } } @@ -133,7 +134,7 @@ static void arith_encode_residual( &hPrivateData->acState, x, cumulativeFrequencyTable ); - + move16(); return; } @@ -146,6 +147,7 @@ static void arith_encode_residual( &hPrivateData->acState, 0, cumulativeFrequencyTable ); + move16(); } ELSE /* x > IGF_MAX_ENC_SEPARATE */ { @@ -156,6 +158,7 @@ static void arith_encode_residual( &hPrivateData->acState, IGF_SYMBOLS_IN_TABLE - 1, cumulativeFrequencyTable ); + move16(); } /* encode one of the tails of the distribution */ @@ -226,17 +229,20 @@ static void encode_sfe_vector( &hPrivateData->acState, shr( x[f], 2 ), (const UWord16 *) hPrivateData->cf_se00 ); + move16(); arith_encode_bits( hPrivateData, ptr, x[f] & 3, 2 ); /* LSBs as 2 bit raw */ } ELSE IF( EQ_16( f, 1 ) ) { pred = x[f - 1]; /* pred = b */ + move16(); arith_encode_residual( hPrivateData, ptr, x[f] - pred, hPrivateData->cf_se01, hPrivateData->cf_off_se01 ); } ELSE { /* f >= 2 */ - pred = x[f - 1]; /* pred = b */ + pred = x[f - 1]; /* pred = b */ + move16(); ctx = quant_ctx( sub( x[f - 1], x[f - 2] ) ); /* Q(b - e) */ arith_encode_residual( hPrivateData, ptr, sub( x[f], pred ), &hPrivateData->cf_se02[( IGF_SYMBOLS_IN_TABLE + 1 ) * ( IGF_CTX_OFFSET + ctx )], hPrivateData->cf_off_se02[IGF_CTX_OFFSET + ctx] ); } @@ -267,11 +273,11 @@ static void encode_sfe_vector( /*---------------------------------------------------------------------* - * IGFSCFEncoderEncode() + * IGFSCFEncoderEncode_ivas_fx() * * main IGF encoder function *---------------------------------------------------------------------*/ -Word16 IGFSCFEncoderEncode( +Word16 IGFSCFEncoderEncode_ivas_fx( IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 bitCount, /* i : offset to the first bit in bitbuffer which should be readed by iisArithDecoderDecode function */ diff --git a/lib_enc/igf_scf_enc_fx.c b/lib_enc/igf_scf_enc_fx.c index b8125cbd6..8659d53a1 100644 --- a/lib_enc/igf_scf_enc_fx.c +++ b/lib_enc/igf_scf_enc_fx.c @@ -45,8 +45,11 @@ void IGFSCFEncoderOpen_fx( set16_fx( hPublicData->prevSave, 0, 64 ); hPublicData->scfCountLongBlock[0] = sub( hIgfInfo->grid[0].swb_offset_len, 1 ); + move16(); hPublicData->scfCountLongBlock[1] = sub( hIgfInfo->grid[1].swb_offset_len, 1 ); + move16(); hPublicData->scfCountLongBlock[2] = sub( hIgfInfo->grid[2].swb_offset_len, 1 ); + move16(); hPublicData->t = 0; move16(); /* protect against the invalid request of starting encoding with a dependent block */ @@ -124,7 +127,7 @@ static void arith_encode_residual( &hPrivateData->acState_fx, x, cumulativeFrequencyTable ); - + move16(); return; } @@ -137,6 +140,7 @@ static void arith_encode_residual( &hPrivateData->acState_fx, 0, cumulativeFrequencyTable ); + move16(); } ELSE /* x > IGF_MAX_ENC_SEPARATE */ { @@ -147,6 +151,7 @@ static void arith_encode_residual( &hPrivateData->acState_fx, IGF_SYMBOLS_IN_TABLE - 1, cumulativeFrequencyTable ); + move16(); } /* encode one of the tails of the distribution */ @@ -216,6 +221,7 @@ static void encode_sfe_vector( &hPrivateData->acState_fx, shr( x[f], 2 ), (const UWord16 *) hPrivateData->cf_se00 ); + move16(); arith_encode_bits( hPrivateData, ptr, s_and( x[f], 3 ), 2 ); /* LSBs as 2 bit raw */ } ELSE IF( EQ_16( f, 1 ) ) @@ -233,7 +239,6 @@ static void encode_sfe_vector( /* (t == 0) && (f >= 2) */ prev_offset = sub( f, 1 ); res = sub( x[f], x[prev_offset] ); - move16(); /* pred = b */ ctx = quant_ctx( sub( x[prev_offset], x[sub( prev_offset, 1 )] ) ); /* Q(b - e) */ /* index1 is (IGF_SYMBOLS_IN_TABLE + 1) * (CTX_OFFSET + ctx) */ index1 = L_mac0( ( IGF_SYMBOLS_IN_TABLE + 1 ) * IGF_CTX_OFFSET, ( IGF_SYMBOLS_IN_TABLE + 1 ), ctx ); @@ -340,12 +345,13 @@ Word16 IGFSCFEncoderEncode_fx( hPublicData->ptrBitIndex, &hPublicData->acState_fx ); /* finish AC encoding */ hPublicData->bitCount = add( hPublicData->bitCount, hPublicData->ptrBitIndex ); - + move16(); + move16(); /* advance history */ Copy( sfe, hPublicData->prev, hPublicData->scfCountLongBlock[igfGridIdx] ); hPublicData->t = add( hPublicData->t, 1 ); - + move16(); /* copy the bits from the temporary bit buffer, if doRealEncoding is enabled */ IF( hBstr ) diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 7d046db5f..edd887afd 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -196,6 +196,7 @@ ivas_error init_encoder_ivas_fx( #if 1 // TODO: Float Initializations. To be removed later st->active_cnt = 0; + move16(); #endif st->pst_mem_deemp_err_fx = 0; @@ -387,6 +388,7 @@ ivas_error init_encoder_ivas_fx( set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); st->q_Bin_E_old = Q31; + move16(); set16_fx( st->hSignalBuf->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); st->exp_buf_speech_enc = 0; move16(); @@ -929,10 +931,12 @@ ivas_error init_encoder_ivas_fx( } set32_fx( st->hTcxEnc->spectrum_long_fx, 0, N_MAX ); st->hTcxEnc->spectrum_long_e = 0; - + move16(); /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; + move32(); + move32(); st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; move16(); move16(); @@ -1010,7 +1014,7 @@ ivas_error init_encoder_ivas_fx( igf_brate = element_brate; } move32(); - + test(); IF( EQ_16( st->codec_mode, MODE2 ) || GT_16( st->element_mode, EVS_MONO ) ) { st->igf = getIgfPresent_fx( st->element_mode, igf_brate, st->max_bwidth, st->rf_mode ); diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 73cade783..89bbdc898 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1,4 +1,4 @@ -/*==================================================================================== +/*==================================================================================== EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ @@ -29,6 +29,8 @@ ivas_error init_encoder_fx( Word16 idchan = 0; /* i : channel ID */ Word16 vad_only_flag = 0; /* i : channel ID */ + move16(); + move16(); ISM_MODE ism_mode = ISM_MODE_NONE; ivas_error error; // PMT("ism_mode, idchan, vad_only_flag to be move to function header") @@ -97,7 +99,7 @@ ivas_error init_encoder_fx( st_fx->last_core = -1; move16(); - IF( st_fx->Opt_AMR_WB ) + if ( st_fx->Opt_AMR_WB ) { st_fx->last_core = AMR_WB_CORE; move16(); @@ -141,7 +143,9 @@ ivas_error init_encoder_fx( st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; st->hBstr->nb_ind_tot = 0; + move16(); st->hBstr->nb_bits_tot = 0; + move16(); st->hBstr->st_ivas = st_ivas; #endif } @@ -157,7 +161,7 @@ ivas_error init_encoder_fx( Copy( GEWB_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); init_lvq_fx( st_fx->offset_scale1_fx, st_fx->offset_scale2_fx, st_fx->offset_scale1_p_fx, st_fx->offset_scale2_p_fx, st_fx->no_scales_fx, st_fx->no_scales_p_fx ); st_fx->next_force_safety_net = 0; - + move16(); st_fx->pstreaklen = 0; move16(); st_fx->streaklimit_fx = 32767; @@ -297,7 +301,7 @@ ivas_error init_encoder_fx( // st_fx->GSC_noisy_speech = 0; st_fx->GSC_IVAS_mode = 0; - + move16(); test(); test(); IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) @@ -350,7 +354,7 @@ ivas_error init_encoder_fx( test(); test(); test(); - IF( ( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || EQ_16( st_fx->element_mode, EVS_MONO ) ) && ( !vad_only_flag ) ) + IF( ( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) && ( !vad_only_flag ) ) { if ( ( st_fx->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) { @@ -386,7 +390,7 @@ ivas_error init_encoder_fx( st_fx->hVAD->L_snr_sum_vad_fx = 0; move32(); } - else + ELSE { st_fx->hVAD = NULL; } @@ -404,7 +408,9 @@ ivas_error init_encoder_fx( * Noise estimator *-----------------------------------------------------------------*/ // PMT("deal with idchan ") - IF( /*idchan == 0 ||*/ EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || EQ_16( st_fx->element_mode, EVS_MONO ) ) + test(); + test(); + IF( /*idchan == 0 ||*/ EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) { if ( ( st_fx->hNoiseEst = (NOISE_EST_HANDLE) malloc( sizeof( NOISE_EST_DATA ) ) ) == NULL ) { @@ -422,7 +428,8 @@ ivas_error init_encoder_fx( *-----------------------------------------------------------------*/ test(); test(); - IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || EQ_16( st_fx->element_mode, EVS_MONO ) ) + test(); + IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hSpMusClas = (SP_MUS_CLAS_HANDLE) malloc( sizeof( SP_MUS_CLAS_DATA ) ) ) == NULL ) { @@ -472,7 +479,7 @@ ivas_error init_encoder_fx( move16(); st_fx->coder_type_raw = VOICED; st_fx->last_coder_type_raw = st_fx->coder_type_raw; - + move16(); st_fx->is_ism_format = 0; move16(); if ( NE_16( ism_mode, ISM_MODE_NONE ) ) @@ -531,6 +538,8 @@ ivas_error init_encoder_fx( * LP-CNG *-----------------------------------------------------------------*/ + test(); + test(); test(); test(); test(); @@ -622,7 +631,7 @@ ivas_error init_encoder_fx( * SC-VBR parameters *-----------------------------------------------------------------*/ test(); - IF( st_fx->Opt_SC_VBR || EQ_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->Opt_SC_VBR || st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hSC_VBR = (SC_VBR_ENC_HANDLE) malloc( sizeof( SC_VBR_ENC_DATA ) ) ) == NULL ) { @@ -636,7 +645,7 @@ ivas_error init_encoder_fx( st_fx->hSC_VBR = NULL; } /* PLC encoder */ - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hPlcExt = (PLC_ENC_EVS_HANDLE) malloc( sizeof( PLC_ENC_EVS ) ) ) == NULL ) { @@ -710,8 +719,8 @@ ivas_error init_encoder_fx( // st_fx->cldfbSynTd = NULL; } - - IF( st_fx->Opt_RF_ON || EQ_16( st_fx->element_mode, EVS_MONO ) ) + test(); + IF( st_fx->Opt_RF_ON || st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hRF = (RF_ENC_HANDLE) malloc( sizeof( RF_ENC_DATA ) ) ) == NULL ) { @@ -752,6 +761,7 @@ ivas_error init_encoder_fx( *-----------------------------------------------------------------*/ // VE: reduction possible for MCT_CHAN_MODE_LFE channel - see I1-172 + test(); IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { IF( ( st_fx->hTcxEnc = (TCX_ENC_HANDLE) malloc( sizeof( TCX_ENC_DATA ) ) ) == NULL ) @@ -768,7 +778,7 @@ ivas_error init_encoder_fx( set16_fx( st_fx->hTcxEnc->old_out_fx, 0, L_FRAME32k ); st_fx->hTcxEnc->Q_old_out = 0; - + move16(); /* MDCT selector */ MDCT_selector_reset_fx( st_fx->hTcxEnc ); st_fx->hTcxEnc->Q_old_out = 0; @@ -782,7 +792,7 @@ ivas_error init_encoder_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); } } - else + ELSE { st_fx->hTcxEnc = NULL; // st_fx->hTcxCfg = NULL; @@ -838,7 +848,7 @@ ivas_error init_encoder_fx( move16(); } st_fx->rf_mode_last = st_fx->rf_mode; - + move16(); /* initialize RF indice buffers */ reset_rf_indices_fx( st_fx ); @@ -847,12 +857,11 @@ ivas_error init_encoder_fx( *-----------------------------------------------------------------*/ st_fx->last_sr_core = i_mult2( st_fx->last_L_frame, 50 ); - + move16(); /*-----------------------------------------------------------------* * IGF *-----------------------------------------------------------------*/ - test(); test(); IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { @@ -919,15 +928,23 @@ ivas_error init_encoder_fx( st_fx->sharpFlag = 0; move16(); - st_fx->tdm_LRTD_flag = 0; /* LRTD stereo mode flag */ - st_fx->cna_dirac_flag = 0; /* CNA in DirAC flag */ - st_fx->cng_sba_flag = 0; /* CNG in SBA flag */ - st_fx->GSC_IVAS_mode = 0; /* CNG in SBA flag */ - st_fx->element_mode = EVS_MONO; /* element mode */ + st_fx->tdm_LRTD_flag = 0; /* LRTD stereo mode flag */ + move16(); + st_fx->cna_dirac_flag = 0; /* CNA in DirAC flag */ + move16(); + st_fx->cng_sba_flag = 0; /* CNG in SBA flag */ + move16(); + st_fx->GSC_IVAS_mode = 0; /* CNG in SBA flag */ + move16(); + st_fx->element_mode = EVS_MONO; /* element mode */ + move16(); st_fx->last_element_mode = st_fx->element_mode; /* element mode */ - st_fx->element_brate = -1; /* element bitrate */ - // PMT("element_mode and element_brate should be initialized at a proper place in ivas_dec_init eventually") - st_fx->low_rate_mode = 0; /* low-rate mode flag */ + move16(); + st_fx->element_brate = -1; /* element bitrate */ + move32(); + // PMT("element_mode and element_brate should be initialized at a proper place in ivas_dec_init eventually") + st_fx->low_rate_mode = 0; /* low-rate mode flag */ + move16(); // st_fx->coder_type = GENERIC; /* low-rate mode flag */ set16_fx( st_fx->pitch, L_SUBFR, 3 ); @@ -936,10 +953,12 @@ ivas_error init_encoder_fx( #ifdef DEBUGGING st_fx->id_element = -1; /* element ID */ + move16(); #endif - st_fx->extl_orig = -1; /* extension layer */ + st_fx->extl_orig = -1; /* extension layer */ + move16(); st_fx->extl_brate_orig = 0; /* extension layer bitrate */ - + move32(); return error; } /*-----------------------------------------------------------------------* diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index a25675352..7964df4a8 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -155,6 +155,7 @@ Word16 inov_encode_fx( IF( st_fx->acelp_cfg.fcb_mode ) { /* set number of iterations in TD stereo, secondary channel */ + test(); if ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) { cmpl_flag = 1; @@ -245,7 +246,7 @@ Word16 inov_encode_fx( } } - if ( EQ_16( coder_type, INACTIVE ) ) + if ( coder_type == INACTIVE ) { cmpl_flag = 4; move16(); @@ -708,9 +709,7 @@ Word16 inov_encode_ivas_fx( E_ACELP_4t_ivas_fx( dn, cn, h2, Rw, (Word8) acelpautoc, code, st_fx->acelp_cfg.fixed_cdk_index[idx2], prm, L_frame, last_L_frame, st_fx->total_brate, i_subfr, cmpl_flag, st_fx->element_mode ); wordcnt = shr( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 4 ); - move16(); bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 15 ); - move16(); FOR( i = 0; i < wordcnt; i++ ) { diff --git a/lib_enc/isf_enc_amr_wb_fx.c b/lib_enc/isf_enc_amr_wb_fx.c index 505d3f290..047a7409c 100644 --- a/lib_enc/isf_enc_amr_wb_fx.c +++ b/lib_enc/isf_enc_amr_wb_fx.c @@ -122,7 +122,7 @@ void isf_enc_amr_wb_fx( * A(z) calculation *-------------------------------------------------------------------------------------*/ - if ( st->rate_switching_reset ) + IF( st->rate_switching_reset ) { Copy( isf_new, st->lsf_old_fx, M ); Copy( isp_new, st->lsp_old_fx, M ); @@ -171,7 +171,7 @@ static void qisf_ns_28b_fx( indice[3] = sub_VQ_fx( &isf[8], dico4_ns_28b_fx, 4, DICO4_NS_28b, &tmp ); move16(); indice[4] = add( sub_VQ_fx( &isf[12], dico5_ns_28b_fx + 4, 4, DICO5_NS_28b - 1, &tmp ), 1 ); /* First vector has a problem -> do not allow */ - + move16(); /* write indices to array */ push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 6 ); push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 6 ); @@ -241,9 +241,11 @@ static void qisf_2s_36b_fx( } tmp_ind[0] = sub_VQ_fx( &isf2[0], dico21_isf_36b_fx, 5, SIZE_BK21_36b, &min_err ); + move16(); temp = L_add( min_err, 0 ); tmp_ind[1] = sub_VQ_fx( &isf2[5], dico22_isf_36b_fx, 4, SIZE_BK22_36b, &min_err ); + move16(); temp = L_add( temp, min_err ); IF( LT_32( temp, distance ) ) @@ -369,10 +371,13 @@ static void qisf_2s_46b_fx( } tmp_ind[0] = sub_VQ_fx( &isf2[0], dico21_isf_46b_fx, 3, SIZE_BK21, &min_err ); + move16(); temp = L_add( min_err, 0 ); tmp_ind[1] = sub_VQ_fx( &isf2[3], dico22_isf_46b_fx, 3, SIZE_BK22, &min_err ); + move16(); temp = L_add( temp, min_err ); tmp_ind[2] = sub_VQ_fx( &isf2[6], dico23_isf_46b_fx, 3, SIZE_BK23, &min_err ); + move16(); temp = L_add( temp, min_err ); IF( LT_32( temp, distance ) ) { diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index a0f123b20..a0ed2f523 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -115,6 +115,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 move16(); /*(+1)=/2 in log */ L_tmp = Mpy_32_16( exp, frac, 4932 ); /*Q16 ; 0.5*log10(2) in Q15 */ G1[i] = round_fx( L_shl( L_tmp, 13 ) ); /*Q13 */ + move16(); } ELSE { @@ -147,9 +148,10 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ L_tmp = Pow2( 30, frac ); - exp = exp - 30; /*move16(); */ + exp = exp - 30; + move16(); Lexp[0] = L_shl( L_tmp, exp + 15 ); - + move32(); L_tmp = L_mult0( UVG1CB_fx[*iG1][1], 27213 ); /*Q26 */ L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ @@ -157,7 +159,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 L_tmp = Pow2( 30, frac ); exp = exp - 30; /*move16(); */ Lexp[1] = L_shl( L_tmp, exp + 15 ); - + move32(); FOR( i = 0; i < 2; i++ ) { @@ -169,6 +171,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 tmp = div_s( 16384, tmp ); /*Q(15+exp) */ L_tmp = L_shr( L_mult0( G[i * 5 + j], tmp ), exp + 3 ); /*Q12 */ G2[i * 5 + j] = extract_l( L_tmp ); /*Q12 */ + move16(); } } @@ -189,7 +192,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 temp = sub_sat( G2[ind], UVG2CB1_fx[j][k] ); Lacc = L_mac0_sat( Lacc, temp, temp ); /*Q24 */ } - ELSE IF( i == 1 ) + ELSE IF( EQ_16( i, 1 ) ) { /*mse += SQR(G2[i*5+k]-UVG2CB2[j][k]); */ ind = add( shr( extract_l( L_mult( i, 5 ) ), 1 ), k ); @@ -241,6 +244,7 @@ static void normalize_arr( Word16 *arr, Word16 *qf, Word16 size, Word16 hdr ) } *qf = norm_s( (Word16) max_s ); + move16(); test(); IF( ( *qf == 0 ) && ( ( (Word16) max_s ) == 0 ) ) { @@ -249,7 +253,7 @@ static void normalize_arr( Word16 *arr, Word16 *qf, Word16 size, Word16 hdr ) } *qf = *qf - hdr; - + move16(); FOR( i = 0; i < size; i++ ) { arr[i] = shl( arr[i], *qf ); @@ -299,41 +303,72 @@ void nelp_encoder_fx( { Word16 i, j; Word16 *ptr_fx = exc_fx; - Word16 lag = 25; /* to cover 25*9 + 31 */ - Word16 sqrt_inv_lag = 6554; /* sqrt(1/lag) in Q15 */ + Word16 lag = 25; /* to cover 25*9 + 31 */ + move16(); + Word16 sqrt_inv_lag = 6554; /* sqrt(1/lag) in Q15 */ + move16(); Word16 sqrt_inv_lframe_lag = 5885; /* sqrt(1/(L_FRAME-lag*9)) */ + move16(); Word16 Gains_fx[10], gain_fac_fx; Word16 iG1_fx, iG2_fx[2]; Word16 fid; Word16 fdbck_fx; Word32 var_dB_fx; Word32 E1_fx = 0, EL1_fx = 0, EH1_fx = 0, E2_fx = 0, E3_fx = 0, EL2_fx = 0, EH2_fx = 0; + move32(); /*E1_fx*/ + move32(); /*EL1_fx*/ + move32(); /*EH1_fx*/ + move32(); /*E2_fx*/ + move32(); /*E3_fx*/ + move32(); /*EL2_fx*/ + move32(); /*EH2_fx*/ Word32 RL_fx = 0, RH_fx = 0; + move32(); /*RL_fx*/ + move32(); /*RH_fx*/ Word16 R_fx = 0; + move16(); Word16 filtRes_fx[L_FRAME]; Word16 ptr_tmp_fx[L_FRAME]; Word16 qE1 = 0, qE2 = 0, qE3 = 0, qEL1 = 0, qEL2 = 0, qEH1 = 0, qEH2 = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); Word16 qIn = 0, qGain = 0, qf = 0, qf1 = 0, qNelpGain = 0; + move16(); + move16(); + move16(); + move16(); + move16(); Word16 exp1, exp2, tmp1, tmp2; Word16 f_Noise, etmp, e_Noise; Word16 max1 = 0; + move16(); Word32 l_nelp_gain_mem; Word32 Ltemp = 0, Ltemp1 = 0, L_tmp = 0, L_const_1; + move32(); + move32(); + move32(); Word16 BP1_ORDER; Word16 rf_flag; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; RF_ENC_HANDLE hRF = st_fx->hRF; rf_flag = st_fx->rf_mode; - + move16(); if ( EQ_16( hSC_VBR->last_nelp_mode, 1 ) && NE_16( st_fx->bwidth, st_fx->last_bwidth ) ) { hSC_VBR->last_nelp_mode = 0; + move16(); } qIn = *qIn1; @@ -453,6 +488,7 @@ void nelp_encoder_fx( Ltemp = L_shl_sat( L_tmp, sub( exp1, 12 ) ); /*Q3 */ } Gains_fx[i] = round_fx_sat( Ltemp ); + move16(); } @@ -477,11 +513,13 @@ void nelp_encoder_fx( } Gains_fx[i] = round_fx_sat( Ltemp ); + move16(); IF( EQ_16( reduce_gains, 1 ) ) { FOR( i = 0; i < 10; i++ ) { Gains_fx[i] = mult( Gains_fx[i], 19661 ); + move16(); } } @@ -512,8 +550,7 @@ void nelp_encoder_fx( L_tmp = L_max( L_tmp, 1 ); exp2 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ - exp2 = 30 - exp2 - qNelpGain; - move16(); + exp2 = sub( 30, add( exp2, qNelpGain ) ); tmp2 = Log2_norm_lc( L_tmp ); Ltemp1 = Mpy_32_16( exp2, tmp2, 9864 ); /*log(2) in Q13 format = Q0 format */ Ltemp1 = L_sub( Ltemp, Ltemp1 ); /*Q16 */ @@ -536,8 +573,7 @@ void nelp_encoder_fx( L_tmp = L_max( L_tmp, 1 ); exp2 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ - exp2 = 30 - exp2 - qGain; - move16(); + exp2 = sub( 30, add( exp2, qGain ) ); tmp2 = Log2_norm_lc( L_tmp ); Ltemp1 = Mpy_32_16( exp2, tmp2, 9864 ); /*log(2) in Q13 format = Q0 format */ Ltemp1 = L_sub( Ltemp, Ltemp1 ); /*Q16 */ @@ -614,7 +650,7 @@ void nelp_encoder_fx( } } - IF( exp1 == 31 ) + IF( EQ_16( exp1, 31 ) ) { L_const_1 = 0x7fffffff; move32(); @@ -644,7 +680,7 @@ void nelp_encoder_fx( } hSC_VBR->nelp_gain_mem_fx = round_fx( L_shl( l_nelp_gain_mem, 16 ) ); - + move16(); Scale_sig( &hSC_VBR->nelp_gain_mem_fx, 1, -qGain ); Scale_sig( Gains_fx, 10, -qGain ); qGain = 0; @@ -655,8 +691,11 @@ void nelp_encoder_fx( IF( EQ_16( rf_flag, 1 ) ) { hRF->rf_indx_nelp_iG1[0] = iG1_fx; + move16(); hRF->rf_indx_nelp_iG2[0][0] = iG2_fx[0]; + move16(); hRF->rf_indx_nelp_iG2[0][1] = iG2_fx[1]; + move16(); } ELSE { @@ -686,6 +725,7 @@ void nelp_encoder_fx( IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) ) { BP1_ORDER = 4; + move16(); Scale_sig( hSC_VBR->bp1_filt_mem_wb_fx, BP1_ORDER * 2, qGain - hSC_VBR->qprevGain_fx ); /*qf-qAdj */ pz_filter_sp_fx( bp1_num_coef_wb_fx, bp1_den_coef_wb_fx, ptr_fx, ptr_tmp_fx, hSC_VBR->bp1_filt_mem_wb_fx, BP1_ORDER, BP1_ORDER, L_FRAME, 2 ); Copy( ptr_tmp_fx, ptr_fx, L_FRAME ); @@ -700,6 +740,7 @@ void nelp_encoder_fx( Scale_sig( ptr_fx, L_FRAME, -1 ); /* bring exc to qgain-1 */ *qIn1 = qGain - 1; /* use this temp only in the parent */ + move16(); } E3_fx = L_deposit_l( 0 ); @@ -710,7 +751,7 @@ void nelp_encoder_fx( qE3 = 2 * qGain + 1; move16(); test(); - IF( st_fx->bwidth == WB || EQ_16( st_fx->bwidth, SWB ) ) + IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) ) { Scale_sig( hSC_VBR->shape1_filt_mem_fx, 10, ( qGain - hSC_VBR->qprevGain_fx ) ); pz_filter_sp_fx( shape1_num_coef_fx, shape1_den_coef_fx, ptr_fx, ptr_tmp_fx, hSC_VBR->shape1_filt_mem_fx, 10, 10, L_FRAME, 1 ); /*1 = (16-qformat of shape1 cofficient) */ @@ -768,6 +809,7 @@ void nelp_encoder_fx( Ltemp = L_mult0( R_fx, ptr_fx[i] ); Ltemp = L_shr_r( Ltemp, exp1 ); filtRes_fx[i] = round_fx_sat( L_shl_sat( Ltemp, 16 ) ); + move16(); } qf1 = qGain; @@ -792,6 +834,7 @@ void nelp_encoder_fx( Ltemp = L_mult0( R_fx, ptr_fx[i] ); Ltemp = L_shr_r( Ltemp, exp1 ); filtRes_fx[i] = round_fx_sat( L_shl_sat( Ltemp, 16 ) ); + move16(); } qf = qGain; @@ -814,8 +857,7 @@ void nelp_encoder_fx( { exp2 = norm_l( EL1_fx ); L_tmp = L_shl( EL1_fx, exp2 ); - exp2 = 30 - exp2 - qEL1; - move16(); + exp2 = sub( 30, add( exp2, qEL1 ) ); tmp1 = Log2_norm_lc( L_tmp ); Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ @@ -829,9 +871,8 @@ void nelp_encoder_fx( L_tmp = Mult_32_16( EL1_fx, tmp1 ); /*qEL1+30-qEL2-exp1-15=>15+qE1-qEL2-exp1 */ exp2 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ - exp2 = 30 - ( 30 + qEL1 - qEL2 - exp1 + exp2 ); - move16(); + L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ + exp2 = sub( add( qEL2, exp1 ), add( qEL1, exp2 ) ); /*30 - ( 30 + qEL1 - qEL2 - exp1 + exp2 )*/ tmp1 = Log2_norm_lc( L_tmp ); Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ @@ -842,8 +883,7 @@ void nelp_encoder_fx( { exp2 = norm_l( EH2_fx ); L_tmp = L_shl( EH2_fx, exp2 ); - exp2 = 30 - exp2 - qEH2; - move16(); + exp2 = sub( 30, add( exp2, qEH2 ) ); tmp1 = Log2_norm_lc( L_tmp ); Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ @@ -857,9 +897,8 @@ void nelp_encoder_fx( L_tmp = Mult_32_16( EH1_fx, tmp1 ); /*15+qEH1-qEH2-exp1 */ exp2 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp2 ); /*15+qEH1-qEH2-exp1+exp2 */ - exp2 = 30 - ( 30 + qEH1 - qEH2 - exp1 + exp2 ); - move16(); + L_tmp = L_shl( L_tmp, exp2 ); /*15+qEH1-qEH2-exp1+exp2 */ + exp2 = sub( add( qEH2, exp1 ), add( qEH1, exp2 ) ); /*30 - ( 30 + qEH1 - qEH2 - exp1 + exp2 )*/ tmp1 = Log2_norm_lc( L_tmp ); Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ @@ -955,12 +994,11 @@ void nelp_encoder_fx( L_tmp = Mult_32_16( E2_fx, tmp1 ); /*qE2+30-qE3-exp1-15=>15+qE2-qE3-exp1 */ exp2 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp2 ); /*15+qE2-qE3-exp1+exp2 */ - exp2 = 30 - ( 15 + qE2 - qE3 - exp1 + exp2 ); - move16(); - L_tmp = Isqrt_lc( L_tmp, &exp2 ); /*Q(31+exp2) */ + L_tmp = L_shl( L_tmp, exp2 ); /*15+qE2-qE3-exp1+exp2 */ + exp2 = add( 15, sub( add( qE3, exp1 ), add( qE2, exp2 ) ) ); /*30 - ( 15 + qE2 - qE3 - exp1 + exp2 )*/ + L_tmp = Isqrt_lc( L_tmp, &exp2 ); /*Q(31+exp2) */ R_fx = round_fx( L_tmp ); - exp1 = 31 - exp2 - 16 - 7; + exp1 = sub( 8, exp2 ); /*31 - exp2 - 16 - 7*/ move16(); } @@ -969,6 +1007,7 @@ void nelp_encoder_fx( L_tmp = L_mult0( R_fx, ptr_fx[i] ); L_tmp = L_shr_r( L_tmp, exp1 + 1 ); ptr_fx[i] = round_fx( L_shl( L_tmp, 16 ) ); + move16(); } *qIn1 = qGain - 1; move16(); @@ -1106,7 +1145,7 @@ void nelp_encoder_ivas_fx( IF( NE_16( hSC_VBR->last_nelp_mode, 1 ) ) { test(); - IF( st_fx->bwidth == WB || EQ_16( st_fx->bwidth, SWB ) ) + IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) ) { set16_fx( hSC_VBR->shape1_filt_mem_fx, 0, 10 ); set16_fx( hSC_VBR->shape2_filt_mem_fx, 0, 10 ); @@ -1171,7 +1210,6 @@ void nelp_encoder_ivas_fx( qGain = qIn; move16(); qGain = shl( qGain, 1 ); - move16(); FOR( i = 0; i < 9; i++ ) { @@ -1707,8 +1745,10 @@ void nelp_encoder_ivas_fx( L_tmp = L_mult0( R_fx, ptr_fx[i] ); L_tmp = L_shr_r( L_tmp, exp1 + 1 ); ptr_fx[i] = round_fx( L_shl( L_tmp, 16 ) ); + move16(); } *qIn1 = sub( qGain, 1 ); + move16(); } IF( EQ_16( rf_flag, 1 ) ) diff --git a/lib_enc/nois_est.c b/lib_enc/nois_est.c deleted file mode 100644 index 370e0aeef..000000000 --- a/lib_enc/nois_est.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-----------------------------------------------------------------* - * Local constants - *-----------------------------------------------------------------*/ diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index be86c0574..1e2131b29 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -90,6 +90,7 @@ static Word16 noise_est_ln_q8_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif L_tmp = L_add_o( L_enr, L_shl( (Word32) 1L, q_new_plus_q_scale ), &Overflow ); /* +1.0f */ @@ -188,7 +189,6 @@ void noise_est_init_fx( hNoiseEst->ave_enr_q = Q7; move16(); - move16(); hNoiseEst->totalNoise_fx = 0; move16(); hNoiseEst->first_noise_updt = 0; @@ -217,7 +217,8 @@ void noise_est_init_fx( hNoiseEst->Etot_st_est_fx = 5120; /* 20.0f in Q8 */ hNoiseEst->Etot_sq_st_est_fx = 1600; /* 400 in Q2 */ - //### + move16(); + move16(); hNoiseEst->epsP_0_2_lp_fx = 4096; /*1.0 Q12*/ move16(); @@ -244,7 +245,7 @@ void noise_est_init_fx( hNoiseEst->noise_char_fx = 0; move16(); hNoiseEst->multi_harm_limit_fx = THR_CORR_INIT_FX; - + move16(); hNoiseEst->Etot_lp_fx = 0; hNoiseEst->Etot_h_fx = 0; hNoiseEst->Etot_l_fx = 0; @@ -271,12 +272,17 @@ void noise_est_init_ivas_fx( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS hNoiseEst->first_noise_updt = 0; hNoiseEst->first_noise_updt_cnt = 0; - + move16(); + move16(); hNoiseEst->aEn = 6; hNoiseEst->aEn_inac_cnt = 0; hNoiseEst->harm_cor_cnt = 0; hNoiseEst->bg_cnt = 0; hNoiseEst->low_tn_track_cnt = 0; + move16(); + move16(); + move16(); + move16(); #endif FOR( i = 0; i < NB_BANDS; i++ ) { @@ -331,8 +337,8 @@ void noise_est_init_ivas_fx( hNoiseEst->Etot_st_est_fx = 5120; /* 20.0f in Q8 */ hNoiseEst->Etot_sq_st_est_fx = 1600; /* 400 in Q2 */ - //### - + move16(); + move16(); hNoiseEst->epsP_0_2_lp_fx = 4096; /*1.0 Q12*/ move16(); hNoiseEst->epsP_0_2_ad_lp_fx = 0; @@ -358,7 +364,7 @@ void noise_est_init_ivas_fx( hNoiseEst->noise_char_fx = 0; move16(); hNoiseEst->multi_harm_limit_fx = THR_CORR_INIT_FX; - + move16(); hNoiseEst->Etot_lp_fx = 0; hNoiseEst->Etot_h_fx = 0; hNoiseEst->Etot_l_fx = 0; @@ -383,12 +389,12 @@ void noise_est_init_ivas_fx( *-----------------------------------------------------------------*/ void noise_est_pre_fx( - const Word16 Etot, /* i : Energy of current frame */ - const Word16 ini_frame_fx, /* i : Frame number (init) */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t last_element_mode /* i : last element mode */ + const Word16 Etot, /* i : Energy of current frame */ + const Word16 ini_frame_fx, /* i : Frame number (init) */ + NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ + const Word16 idchan, /* i : channel ID */ + const Word16 element_mode, /* i : element mode */ + const Word16 last_element_mode /* i : last element mode */ ) { Word16 tmp; @@ -455,7 +461,8 @@ void noise_est_pre_fx( } hNoiseEst->Etot_l_fx = s_min( hNoiseEst->Etot_l_fx, Etot ); - + move16(); + test(); IF( LT_16( ini_frame_fx, 100 ) && LT_16( hNoiseEst->Etot_l_fx, hNoiseEst->Etot_l_lp_fx ) ) { /**Etot_l_lp = 0.1f * *Etot_l + (1.0f - 0.1) * *Etot_l_lp; */ @@ -478,10 +485,12 @@ void noise_est_pre_fx( { /* *Etot_l_lp = 0.02f * *Etot_l + (1.0f - 0.02f) * *Etot_l_lp; */ hNoiseEst->Etot_l_lp_fx = round_fx( L_mac( L_mult( 655, hNoiseEst->Etot_l_fx ), 32113, hNoiseEst->Etot_l_lp_fx ) ); + move16(); } } /**sign_dyn_lp = 0.1f * (*Etot_h - *Etot_l) + (1.0f - 0.1f) * *sign_dyn_lp;*/ hNoiseEst->sign_dyn_lp_fx = round_fx( L_mac( L_mult( 3277, sub_sat( hNoiseEst->Etot_h_fx, hNoiseEst->Etot_l_fx ) ), 29491, hNoiseEst->sign_dyn_lp_fx ) ); + move16(); } return; @@ -681,7 +690,7 @@ void noise_est_down_fx( e_Noise = sub( e_Noise, scale ); Ltmp = Mpy_32_16( e_Noise, f_Noise, LG10 ); *totalNoise = round_fx( L_shl( Ltmp, 10 ) ); /*Q8*/ - + move16(); /*-----------------------------------------------------------------* * Average energy per frame for each frequency band *-----------------------------------------------------------------*/ @@ -710,7 +719,7 @@ void noise_est_down_fx( tmpN[i] = Madd_32_16( L_tmp, bckr[i], ALPHAM1_FX ); move32(); /*Q_new+QSCALE*/ tmpN[i] = L_max( tmpN[i], e_min ); /* handle div by zero in find_tilt_fx */ - + move32(); /* if( tmpN[i] < bckr[i] ) { bckr[i] = tmpN[i]; }*/ /* Defend to increase noise estimate: keep as it is or decrease */ bckr[i] = L_max( L_min( bckr[i], tmpN[i] ), e_min ); @@ -729,10 +738,10 @@ void noise_est_down_fx( L_tmp = Mult_32_16( L_Etot_v, 655 ); /*.02 in Q15 , Q24+Q15+1 -16 ==> Q24 ) */ *Etot_v_h2 = round_fx( L_add( L_Etot_v_h2, L_tmp ) ); /*Q24->Q8*/ - + move16(); /* if (*Etot_v_h2 < 0.1f) { *Etot_v_h2 = 0.1f; } */ *Etot_v_h2 = s_max( *Etot_v_h2, 26 ); /* 0.1 in Q8*/ - + move16(); return; } @@ -945,6 +954,7 @@ void noise_est_fx( GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* @@ -958,7 +968,7 @@ void noise_est_fx( IF( hFrontVad == NULL ) #endif { - if ( hSpMusClas != NULL ) + IF( hSpMusClas != NULL ) { Ltmp = L_shr( lf_E[0], 3 ); FOR( i = 1; i < 8; i++ ) @@ -968,6 +978,7 @@ void noise_est_fx( IF( LT_32( Ltmp, L_shl( 1, add( Q_new, Q_SCALE - 2 ) ) ) ) { hSpMusClas->ener_RAT_fx = 0; + move16(); // PMT("hSpMusClas->ener_RAT_fx = 0, that should be validated") } ELSE @@ -989,9 +1000,10 @@ void noise_est_fx( { hSpMusClas->ener_RAT_fx = 32767; move16(); /*Q15*/ - if ( GE_16( wtmp1, wtmp ) ) + IF( GE_16( wtmp1, wtmp ) ) { hSpMusClas->ener_RAT_fx = div_s( wtmp, wtmp1 ); /*Q15*/ /* wtmp1 gte than wtmp */ + move16(); } } } @@ -1005,7 +1017,7 @@ void noise_est_fx( * order" spectral envelope => the epsP ratio is much less effective. *-----------------------------------------------------------------*/ - IF( NE_16( vad_bwidth_fx, NB ) ) /* WB input */ + IF( vad_bwidth_fx != NB ) /* WB input */ { th_eps = TH_EPS16_FX; move16(); /*Q11*/ @@ -1052,7 +1064,7 @@ void noise_est_fx( move16(); /* low correlation -> probably inactive signal */ } - move16(); /* Update */ + /* Update */ /*-----------------------------------------------------------------* * Multi-harmonic analysis @@ -1067,6 +1079,7 @@ void noise_est_fx( move16(); *loc_harm = multi_harm_fx( EspecdB, hNoiseEst->old_S_fx, hNoiseEst->cor_map_fx, &hNoiseEst->multi_harm_limit_fx, st_fx->total_brate, st_fx->bwidth, ( st_fx->hGSCEnc != NULL ) ? &hGSCEnc->cor_strong_limit : &i, &hSpMusClas->mean_avr_dyn_fx, &hSpMusClas->last_sw_dyn_fx, cor_map_sum, sp_floor, S_map ); + move16(); } } /*-----------------------------------------------------------------* @@ -1186,7 +1199,7 @@ void noise_est_fx( nchar_thr = THR_NCHAR_WB_FX; move16(); /* 1.0 Q11 */ - if ( EQ_16( vad_bwidth_fx, NB ) ) + if ( vad_bwidth_fx == NB ) { nchar_thr = THR_NCHAR_NB_FX; move16(); /* 1.0 Q11 */ @@ -1336,6 +1349,7 @@ void noise_est_fx( move16(); } } + test(); IF( GE_16( i, 2 ) && LE_16( i, 16 ) ) { IF( GE_16( ini_frame, 100 ) ) @@ -1369,7 +1383,7 @@ void noise_est_fx( lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ - if ( st_fx->ini_frame < 150 ) + IF( LT_16( st_fx->ini_frame, 150 ) ) { /* Allow use of quicker filter during init - if needed */ /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ @@ -1379,7 +1393,7 @@ void noise_est_fx( hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); move16(); } - else + ELSE { /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); @@ -1402,20 +1416,24 @@ void noise_est_fx( test(); test(); *st_harm_cor_cnt = add( *st_harm_cor_cnt, 1 ); + move16(); if ( ( Etot > 0 ) && ( ( *loc_harm > 0 ) || ( GT_16( round_fx( Ltmp ), COR_MAX_NNE_FX ) ) ) ) { *st_harm_cor_cnt = 0; move16(); } - - IF( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 ) ) || /* 15 in Q8 */ - ( GT_16( st_fx->ini_frame, 10 ) && - GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) ) /* 7 in Q8 */ + test(); + test(); + test(); + if ( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 ) ) || /* 15 in Q8 */ + ( GT_16( st_fx->ini_frame, 10 ) && + GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) ) /* 7 in Q8 */ ) { *st_harm_cor_cnt = 1; } - + test(); + test(); if ( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 ) && /* 30.0f in Q8 */ GT_16( st_E_var_est_fx, 32 ) /* 8.0f in Q2 */ @@ -1424,6 +1442,7 @@ void noise_est_fx( /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ *st_harm_cor_cnt = s_max( 1, shr( add( *st_harm_cor_cnt, 2 ), 1 ) ); + move16(); } @@ -1471,7 +1490,7 @@ void noise_est_fx( alpha = 4915; move16(); /*0.15 in Q15 */ hNoiseEst->epsP_0_2_lp_fx = noise_est_AR1_Qx( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx, alpha ); - + move16(); /* epsP_0_2_ad = (float) fabs(epsP_0_2 - st->epsP_0_2_lp ); */ epsP_0_2_ad = abs_s( sub( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx ) ); /* Q12 */ @@ -1487,7 +1506,7 @@ void noise_est_fx( alpha = shr( alpha, 1 ); /* 0.1 Q15 */ } hNoiseEst->epsP_0_2_ad_lp_fx = noise_est_AR1_Qx( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx, alpha ); - + move16(); /* epsP_0_2_ad_lp_max = max(epsP_0_2_ad,st->epsP_0_2_ad_lp);*/ epsP_0_2_ad_lp_max = s_max( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ); /* Q12 */ @@ -1523,9 +1542,9 @@ void noise_est_fx( move16(); /* 0.2 Q15 */ } hNoiseEst->epsP_2_16_lp_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx, alpha ); - + move16(); hNoiseEst->epsP_2_16_lp2_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp2_fx, 655 ); /* 0.02 */ - + move16(); epsP_2_16_dlp = sub( hNoiseEst->epsP_2_16_lp_fx, hNoiseEst->epsP_2_16_lp2_fx ); @@ -1542,7 +1561,7 @@ void noise_est_fx( move16(); /* 0.02 Q15 */ } hNoiseEst->epsP_2_16_dlp_lp2_fx = noise_est_AR1_Qx( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx, alpha ); - + move16(); /* epsP_2_16_dlp_max = max(epsP_2_16_dlp,st->epsP_2_16_dlp_lp2); */ epsP_2_16_dlp_max = s_max( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ); @@ -1560,14 +1579,14 @@ void noise_est_fx( move16(); } hNoiseEst->lt_tn_track_fx = noise_est_AR1_Qx( tmp2, hNoiseEst->lt_tn_track_fx, 983 ); /*0.03 in Q15 ,Q15 state*/ - + move16(); /* st->lt_tn_dist = 0.03f* (Etot - st->totalNoise) + 0.97f*st->lt_tn_dist; */ hNoiseEst->lt_tn_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_tn_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ - + move16(); /* st->lt_Ellp_dist = 0.03f* (Etot - st->Etot_l_lp) + 0.97f*st->lt_Ellp_dist;*/ tmp = sub( Etot, hNoiseEst->Etot_l_lp_fx ); /* Q8 */ hNoiseEst->lt_Ellp_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_Ellp_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ - + move16(); /* if (st->harm_cor_cnt == 0) { st->lt_haco_ev = 0.03f*1.0 + 0.97f*st->lt_haco_ev; @@ -1582,7 +1601,7 @@ void noise_est_fx( { hNoiseEst->lt_haco_ev_fx = mult_r( 32440, hNoiseEst->lt_haco_ev_fx ); /*.99 in Q15 , Q15 state */ } - + move16(); /* if (st->lt_tn_track < 0.05f) { st->low_tn_track_cnt++; @@ -1702,15 +1721,15 @@ void noise_est_fx( ( ( hNoiseEst->act_pred > 0.8f ) && ( non_sta2 > th_sta ) ) ) { /* active signal present - increment counter */ - hStereoClassif->aEn_raw[st->idchan] = hStereoClassif->aEn_raw[st->idchan] + 2; + hStereoClassif->aEn_raw[st->idchan] = add( hStereoClassif->aEn_raw[st->idchan], 2 ); } else { /* background noise present - decrement counter */ - hStereoClassif->aEn_raw[st->idchan] = hStereoClassif->aEn_raw[st->idchan] - 1; + hStereoClassif->aEn_raw[st->idchan] = sub( hStereoClassif->aEn_raw[st->idchan], 1 ); } - if ( hStereoClassif->aEn_raw[st->idchan] > 6 ) + if ( GT_16( hStereoClassif->aEn_raw[st->idchan], 6 ) ) { hStereoClassif->aEn_raw[st->idchan] = 6; } @@ -1956,13 +1975,20 @@ void noise_est_fx( test(); test(); test(); - if ( ( ( LT_16( hNoiseEst->act_pred_fx, 19333 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 7537 ) ) ) /* .59 in Q15 .23 in Q15 */ - || ( LT_16( hNoiseEst->act_pred_fx, 12452 ) ) /* .38 in Q15 */ - || ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 ) ) ) /* .15 in Q15 || 0.08 */ - || ( LT_16( non_staB, 50 * 256 ) ) /* 50.0 in Q8 */ - || aE_bgd != 0 || ( ( LT_16( Etot, 10752 ) ) /* 42 in Q8 */ - && ( GT_16( hNoiseEst->harm_cor_cnt, 10 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 11469 ) ) /* 0.35 in Q15 */ - && ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* 0.80 in Q15 */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( ( LT_16( hNoiseEst->act_pred_fx, 19333 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 7537 ) ) ) /* .59 in Q15 .23 in Q15 */ + || ( LT_16( hNoiseEst->act_pred_fx, 12452 ) ) /* .38 in Q15 */ + || ( ( st_fx->element_mode == EVS_MONO && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) || ( st_fx->element_mode > EVS_MONO && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 ) ) ) /* .15 in Q15 || 0.08 */ + || ( LT_16( non_staB, 50 * 256 ) ) /* 50.0 in Q8 */ + || aE_bgd != 0 || ( ( LT_16( Etot, 10752 ) ) /* 42 in Q8 */ + && ( GT_16( hNoiseEst->harm_cor_cnt, 10 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 11469 ) ) /* 0.35 in Q15 */ + && ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* 0.80 in Q15 */ ) ) { tmp = 1; @@ -1973,6 +1999,7 @@ void noise_est_fx( move16(); test(); test(); + test(); if ( ( LT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( hNoiseEst->harm_cor_cnt, 5 ) ) /* > 5 Q0 */ && ( LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) /* 7 in Q8 */ && ( NE_16( tmp, 0 ) ) ) @@ -2045,8 +2072,6 @@ void noise_est_fx( test(); test(); test(); - test(); - test(); IF( ( ( LT_16( hNoiseEst->act_pred_fx, 27853 ) ) /* 0.85 in Q15 */ && ( NE_16( aE_bgd, 0 ) ) && ( ( LT_16( hNoiseEst->lt_Ellp_dist_fx, 10 * 256 ) ) || ( NE_16( sd1_bgd, 0 ) ) ) /* 10.0 in Q8*/ && ( LT_16( hNoiseEst->lt_tn_dist_fx, 40 * 256 ) ) /* 40.0 in Q8*/ @@ -2061,6 +2086,7 @@ void noise_est_fx( updt_step = 32767; move16(); hNoiseEst->first_noise_updt = 1; + move16(); FOR( i = 0; i < NB_BANDS; i++ ) { hNoiseEst->bckr_fx[i] = tmpN[i]; @@ -2130,6 +2156,7 @@ void noise_est_fx( ELSE IF( ( aE_bgd != 0 ) || ( GT_16( hNoiseEst->harm_cor_cnt, 100 ) ) ) { hNoiseEst->first_noise_updt = add( hNoiseEst->first_noise_updt, 1 ); + move16(); } } ELSE @@ -2162,15 +2189,17 @@ void noise_est_fx( move16(); } hNoiseEst->lt_aEn_zero_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_aEn_zero_fx, 6554 ); /* alpha=0.2 , Q15 */ + move16(); } #ifdef IVAS_CODE - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->element_mode > EVS_MONO ) { test(); - if ( hNoiseEst->first_noise_updt_cnt_fx > 0 && LT_16( hNoiseEst->first_noise_updt_cnt_fx, 100 ) ) + IF( hNoiseEst->first_noise_updt_cnt_fx > 0 && LT_16( hNoiseEst->first_noise_updt_cnt_fx, 100 ) ) { hNoiseEst->first_noise_updt_cnt_fx = add( hNoiseEst->first_noise_updt_cnt_fx, 1 ); + move16(); } } #endif @@ -2389,7 +2418,7 @@ void noise_est_ivas_fx( move16(); /* low correlation -> probably inactive signal */ } - move16(); /* Update */ + /* Update */ /*-----------------------------------------------------------------* * Multi-harmonic analysis @@ -2825,7 +2854,8 @@ void noise_est_ivas_fx( *st_harm_cor_cnt = 1; move16(); } - + test(); + test(); IF( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 /* 30.0f in Q8 */ ) && GT_16( st_E_var_est_fx, 32 /* 8.0f in Q2 */ ) ) { /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ @@ -3564,7 +3594,7 @@ void noise_est_ivas_fx( IF( st_fx->element_mode > EVS_MONO ) { test(); - if ( hNoiseEst->first_noise_updt > 0 && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) + IF( hNoiseEst->first_noise_updt > 0 && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) { hNoiseEst->first_noise_updt_cnt = add( hNoiseEst->first_noise_updt_cnt, 1 ); move16(); diff --git a/lib_enc/noise_adjust.c b/lib_enc/noise_adjust.c deleted file mode 100644 index d441f6ead..000000000 --- a/lib_enc/noise_adjust.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 6440c1d64..0f1c2e906 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1026,6 +1026,7 @@ typedef struct fd_bwe_enc_structure Word32 prev_global_gain_fx; /* Q(2 * prev_Q_shb) */ Word16 modeCount; Word32 EnergyLF_fx; + Word16 EnergyLF_exp; Word16 mem_old_wtda_swb_fx; /* Q(-1) */ } FD_BWE_ENC_DATA, *FD_BWE_ENC_HANDLE; diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 60c6504a6..c7d99cc69 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -3113,17 +3113,19 @@ static Word16 SWB_BWE_encoding_ivas_fx( energy_fx = L_deposit_l( 0 ); FOR( i = 0; i < L; i++ ) { - energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*2*Q_slb_speech - 7 */ + energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*Q = 2 * Q_insig_lp - 7 */ } - IF( GT_32( Mult_32_16( energy_fx, 5958 ), hBWE_FD->EnergyLF_fx ) ) + if ( BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( energy_fx, 5958 /* 1/5.5f in Q15 */ ), sub( 31 + 7, shl( Q_insig_lp, 1 ) ), hBWE_FD->EnergyLF_fx, hBWE_FD->EnergyLF_exp ) > 0 ) { IsTransient_LF = 1; move16(); } hBWE_FD->EnergyLF_fx = energy_fx; + hBWE_FD->EnergyLF_exp = sub( 31 + 7, shl( Q_insig_lp, 1 ) ); move32(); + move16(); } /* tilt returned in Q24 go to Q11 */ @@ -4169,8 +4171,10 @@ void fd_bwe_enc_init_fx( hBWE_FD->modeCount = 0; move16(); hBWE_FD->EnergyLF_fx = 0; + hBWE_FD->EnergyLF_exp = 0; hBWE_FD->mem_old_wtda_swb_fx = 0; move32(); + move16(); move32(); hBWE_FD->prev_Q_input_lp = 0; -- GitLab From 539feaf6f37edd1cbcfd7b6a3f61f61ee1ff6b59 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 5 Feb 2025 10:30:00 +0100 Subject: [PATCH 0043/1221] fix clang-format issues --- lib_com/options.h | 1 - lib_dec/ivas_svd_dec.c | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 2508663d9..dcf5bd052 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,4 +151,3 @@ #define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ #endif #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ - diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 663dba21f..942a2b5b0 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -936,7 +936,7 @@ static void ApplyRotation_fx( move32(); } #else - Word32 s_neg = L_negate(s); + Word32 s_neg = L_negate( s ); Word32 temp; FOR( ch = 0; ch < nChannels; ch++ ) { @@ -945,10 +945,10 @@ static void ApplyRotation_fx( x12 = singularVector[ch][currentIndex1]; move32(); temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ - singularVector[ch][currentIndex2] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ + singularVector[ch][currentIndex2] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ move32(); temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( s_neg, x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ - singularVector[ch][currentIndex1] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ + singularVector[ch][currentIndex1] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ move32(); } @@ -1159,7 +1159,7 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ #ifndef FIX_1010_OPT_SINGLE_RESCALE sing_exp[jCh] = sub( add( invVal_e, sub( *singularVectors_e, *sig_x_e ) ), temp_e ); move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ #else singularVectors2_e[jCh][currChannel] = sub( add( invVal_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ), temp_e ); move16(); @@ -1178,7 +1178,7 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ move16(); L_temp = Sqrt32( norm_x, &L_temp_e ); L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 - //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); + //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); #ifndef FIX_MINOR_SVD_WMOPS_MR1010X IF( singularVectors[currChannel][idx] >= 0 ) { @@ -1191,12 +1191,12 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ move32(); } #else - if ( singularVectors[currChannel][idx] >= 0 ) - { - L_temp = L_negate( L_temp ); - } - ( *g ) = L_temp ; - move32(); + if ( singularVectors[currChannel][idx] >= 0 ) + { + L_temp = L_negate( L_temp ); + } + ( *g ) = L_temp; + move32(); #endif #ifndef FIX_1010_OPT_SINGLE_RESCALE @@ -1911,15 +1911,15 @@ static Word32 maxWithSign_fx( } #else Word32 result; - if (a >= 0) + if ( a >= 0 ) { result = L_max( a, SVD_MINIMUM_VALUE_FX ); } - if (a < 0) + if ( a < 0 ) { result = L_min( a, -SVD_MINIMUM_VALUE_FX ); } - return result; + return result; #endif } -- GitLab From a2399575fed3cae66b2328b7ee21e041de606d28 Mon Sep 17 00:00:00 2001 From: malenov Date: Mon, 18 Nov 2024 13:35:24 +0100 Subject: [PATCH 0044/1221] fix Hilbert filter issue by improving precision --- lib_com/options.h | 1 + lib_com/swb_tbe_com.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 24f21262e..cfc240323 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -150,4 +150,5 @@ #define FIX_ISSUE_1237 /* VA: replacement of Copy_Scale_sig_16_32_DEPREC() that are doing 16 bits left shift by Copy_Scale_sig_16_32_no_sat() */ #define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ #define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ +#define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ #endif diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 9b20512a2..4809e419d 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -69,7 +69,40 @@ void GenSHBSynth_fx_32( Word32 speech_buf_32k[L_FRAME32k]; Word16 i; +#ifdef FIX_881_HILBERT_FILTER + Word16 shift = 0; + Word32 maxm32, input_synspeech_temp[L_FRAME16k]; + + /* find the maximum value and derive the shift to improve precision of the Hilber filter */ + maxm32 = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + maxm32 = L_max( maxm32, L_abs( input_synspeech[i] ) ); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + maxm32 = L_max( maxm32, L_abs( state_lsyn_filt_shb_local[i] ) ); + } + + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); + } + + IF ( maxm32 != 0 ) + { + shift = sub( norm_l( maxm32 ), 3 ); + + Copy_Scale_sig32( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); + } + + Interpolate_allpass_steep_32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); +#else Interpolate_allpass_steep_32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); +#endif IF( EQ_16( L_frame, L_FRAME ) ) { @@ -92,6 +125,15 @@ void GenSHBSynth_fx_32( } } +#ifdef FIX_881_HILBERT_FILTER + IF ( maxm32 != 0 ) + { + Scale_sig32( shb_syn_speech_32k, L_FRAME32k, -shift ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, -shift ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, -shift ); + } +#endif + return; } void ScaleShapedSHB_32( -- GitLab From 45f33c0e717baa722e379b3a33dd79ff35cced70 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Mon, 18 Nov 2024 14:19:42 +0100 Subject: [PATCH 0045/1221] clang format --- lib_com/swb_tbe_com.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 4809e419d..6368c0b2d 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -90,7 +90,7 @@ void GenSHBSynth_fx_32( maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); } - IF ( maxm32 != 0 ) + IF( maxm32 != 0 ) { shift = sub( norm_l( maxm32 ), 3 ); @@ -126,7 +126,7 @@ void GenSHBSynth_fx_32( } #ifdef FIX_881_HILBERT_FILTER - IF ( maxm32 != 0 ) + IF( maxm32 != 0 ) { Scale_sig32( shb_syn_speech_32k, L_FRAME32k, -shift ); Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, -shift ); -- GitLab From 140433d16fadbfcbdffb22902754ef2921d12f52 Mon Sep 17 00:00:00 2001 From: malenov Date: Fri, 10 Jan 2025 14:28:52 +0100 Subject: [PATCH 0046/1221] just copy signal to temp buffer when maxm32 is 0 --- lib_com/swb_tbe_com.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 6368c0b2d..bc5538aeb 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -73,7 +73,7 @@ void GenSHBSynth_fx_32( Word16 shift = 0; Word32 maxm32, input_synspeech_temp[L_FRAME16k]; - /* find the maximum value and derive the shift to improve precision of the Hilber filter */ + /* find the maximum value and derive the shift to improve precision of the Hilbert filter */ maxm32 = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME16k; i++ ) { @@ -98,6 +98,10 @@ void GenSHBSynth_fx_32( Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); } + else + { + Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); + } Interpolate_allpass_steep_32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); #else -- GitLab From a7f9fcc5154eda4e05c5fdc5655da3f5144f70ae Mon Sep 17 00:00:00 2001 From: malenov Date: Wed, 5 Feb 2025 12:09:10 +0100 Subject: [PATCH 0047/1221] fix initialization of st->force_dir in ISM and SCE modes --- lib_enc/ivas_cpe_enc.c | 1 - lib_enc/ivas_init_enc.c | 3 +++ lib_enc/ivas_ism_enc.c | 3 +++ lib_enc/ivas_sce_enc.c | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 7b7ab41bf..4f8926eba 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -1198,7 +1198,6 @@ ivas_error ivas_cpe_enc_fx( } } - /*----------------------------------------------------------------* * Core Encoder *----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index d6a3597bd..02219c4e3 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -370,6 +370,9 @@ void copy_encoder_config_fx( #ifdef DEBUGGING st_fx->force = st_ivas->hEncoderConfig->force; +#ifdef DEBUG_FORCE_DIR + st_fx->force_dir = st_ivas->hEncoderConfig->force_dir; +#endif #endif st_fx->element_mode = st_ivas->hEncoderConfig->element_mode_init; /* Q0 */ diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 6f8fb2b9f..2fef5a1cb 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -197,6 +197,9 @@ ivas_error ivas_ism_enc_fx( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; st->id_element = sce_id; +#ifdef DEBUG_FORCE_DIR + st->force_dir = st_ivas->hEncoderConfig->force_dir; +#endif #endif move16(); move16(); diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index d43ed7438..7d76b2fd5 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -161,6 +161,9 @@ ivas_error ivas_sce_enc_fx( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; st->id_element = sce_id; +#ifdef DEBUG_FORCE_DIR + st->force_dir = st_ivas->hEncoderConfig->force_dir; +#endif #endif move16(); move16(); -- GitLab From 37fd2578548f0d2e979b9137bb19b93afc092aab Mon Sep 17 00:00:00 2001 From: norvell Date: Wed, 5 Feb 2025 12:00:37 +0000 Subject: [PATCH 0048/1221] Adding init of SKIP_REGRESSION_CHECK --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8aa6a8af5..cc2153f89 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,6 +32,7 @@ variables: INSTR_DIR: "scripts/c-code_instrument" BUILD_WITH_DEBUG_MODE_INFO: "" ENCODER_TEST: "" + SKIP_REGRESSION_CHECK: "" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' -- GitLab From 2544b74a62ee6b9f5c56f933790a04f2da22d8ae Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Feb 2025 19:46:23 +0530 Subject: [PATCH 0049/1221] Added missing instrumentation for MR !789 and bug fix in swb_tbe --- lib_com/swb_tbe_com.c | 11 ++++++----- lib_com/swb_tbe_com_fx.c | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index bc5538aeb..105c4db15 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -72,8 +72,9 @@ void GenSHBSynth_fx_32( #ifdef FIX_881_HILBERT_FILTER Word16 shift = 0; Word32 maxm32, input_synspeech_temp[L_FRAME16k]; + move16(); - /* find the maximum value and derive the shift to improve precision of the Hilbert filter */ + /* find the maximum value and derive the shift to improve precision of the Hilber filter */ maxm32 = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME16k; i++ ) { @@ -98,7 +99,7 @@ void GenSHBSynth_fx_32( Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); } - else + ELSE { Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); } @@ -132,9 +133,9 @@ void GenSHBSynth_fx_32( #ifdef FIX_881_HILBERT_FILTER IF( maxm32 != 0 ) { - Scale_sig32( shb_syn_speech_32k, L_FRAME32k, -shift ); - Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, -shift ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, -shift ); + Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); } #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 27ce60448..92271c1f1 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -3480,6 +3480,9 @@ void GenShapedSHBExcitation_ivas_enc_fx( { // g = 1.0f; g = MAX16B; /* Q15 */ + move16(); + g_e = 0; + move16(); } // else if ( g < shl( delta, ( 15 - g_e ) - 14 ) ) ELSE IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), delta, 17 ) < 0 ) @@ -3487,8 +3490,12 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* prevent low gains to be quantized to 0 as this is reserved for plosives */ // g = delta; g = shl( delta, 1 ); /* Q15 */ + g_e = 0; + move16(); } + g = shl_sat( g, g_e ); /* Q15 */ + *vf_ind = usquant_fx( g, &mix_factor, 0, delta, cbsize ); move16(); } -- GitLab From ad4102ca5c35af89ce2316ecfd99eb5c2dc81968 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Feb 2025 22:07:32 +0530 Subject: [PATCH 0050/1221] MSAN fix for decoder, mld improvement changes for stereo --- lib_dec/acelp_core_dec_ivas_fx.c | 2 ++ lib_enc/ivas_stereo_dft_enc.c | 10 ++++++---- lib_enc/ivas_stereo_ica_enc.c | 2 +- lib_enc/ivas_stereo_td_analysis.c | 14 +++++++------- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index ed32a115f..24427c5d2 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1874,7 +1874,9 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#ifndef MSAN_FIX Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); // Q_real-1 +#endif FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 90e9752f4..d532a9af1 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -1706,20 +1706,22 @@ void stereo_dft_enc_process_fx( IF( alpha_fx >= 0 ) { + c_fx = shr( c_fx, 1 ); + s_fx = shr( s_fx, 1 ); FOR( i = 1; i < hStereoDft->NFFT / 2; i++ ) { // tmp = s * c1 + c * s1; - tmp_fx = add_sat( mult_r( s_fx, c1_fx ), mult_r( c_fx, s1_fx ) ); // saturation expected + tmp_fx = add( mult_r( s_fx, c1_fx ), mult_r( c_fx, s1_fx ) ); // c = c * c1 - s * s1; - c_fx = sub_sat( mult_r( c_fx, c1_fx ), mult_r( s_fx, s1_fx ) ); // saturation expected + c_fx = sub( mult_r( c_fx, c1_fx ), mult_r( s_fx, s1_fx ) ); s_fx = tmp_fx; move16(); /*time shift of L*/ // tmp = pDFT_L[2 * i] * c - pDFT_L[2 * i + 1] * s; - tmp_32fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], c_fx ), DFT_L_e_tmp[2 * i], L_negate( Mpy_32_16_1( pDFT_L_fx[2 * i + 1], s_fx ) ), DFT_L_e_tmp[2 * i + 1], &tmp_e ); + tmp_32fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], c_fx ), add( DFT_L_e_tmp[2 * i], 1 ), L_negate( Mpy_32_16_1( pDFT_L_fx[2 * i + 1], s_fx ) ), add( DFT_L_e_tmp[2 * i + 1], 1 ), &tmp_e ); // pDFT_L[2 * i + 1] = pDFT_L[2 * i] * s + pDFT_L[2 * i + 1] * c; - pDFT_L_fx[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], s_fx ), DFT_L_e_tmp[2 * i], Mpy_32_16_1( pDFT_L_fx[2 * i + 1], c_fx ), DFT_L_e_tmp[2 * i + 1], &DFT_L_e_tmp[2 * i + 1] ); + pDFT_L_fx[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], s_fx ), add( DFT_L_e_tmp[2 * i], 1 ), Mpy_32_16_1( pDFT_L_fx[2 * i + 1], c_fx ), add( DFT_L_e_tmp[2 * i + 1], 1 ), &DFT_L_e_tmp[2 * i + 1] ); move32(); // pDFT_L[2 * i] = tmp; pDFT_L_fx[2 * i] = tmp_32fx; diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 67a575e44..5ee97f27c 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1892,7 +1892,7 @@ void stereo_tca_enc_fx( ELSE { v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/ - Copy32( ptrChanL_fx + add( prevNCShift, sub( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2 + Copy32( ptrChanL_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2 v_multc_fixed( ptrChanR_fx - add( lMemRecalc, lMemRecalc_SCh ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2 v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/ } diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index e5bf2ea53..49ac895ef 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -1722,7 +1722,6 @@ Word16 tdm_lp_comparison_fx( Word32 dist_fx, ftmp_fx; Word16 i; Word32 res_fx[L_FRAME16k]; - Word16 gb1 = find_guarded_bits_fx( M ); Word16 Q_A_SCh; Word32 *speech_fx = &speech_buff[M]; @@ -1733,8 +1732,8 @@ Word16 tdm_lp_comparison_fx( // residu( A_SCh, m, speech, res, L_frame ); Word16 gb = find_guarded_bits_fx( L_frame ); - scale_sig32( speech_buff, L_FRAME + M, gb1 ); /* Q_speech + gb1 */ - Word16 exp = sub( 31, Q_speech ); + scale_sig32( speech_buff, L_FRAME + M, Q4 ); /* Q_speech + 4 */ + Word16 exp = sub( Q27, Q_speech ); Word32 sum2_value = sum2_32_exp_fx( speech_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb IF( LT_16( exp, -5 ) ) /*maximum q to prevent 0.01 from saturating is 37, since we are adding it headroom of 1 is required*/ { @@ -1746,7 +1745,7 @@ Word16 tdm_lp_comparison_fx( Word32 temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); /* Q25 */ ener_sig_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 // ener_sig = log10f( sum2_f( speech, L_frame ) + 0.01f ); - exp = sub( 31, sub( Q_speech, gb1 ) ); + exp = sub( Q31, Q_speech ); sum2_value = sum2_32_exp_fx( res_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q16, &exp ); /* Q31-exp */ temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); /* Q25 */ @@ -1757,9 +1756,9 @@ Word16 tdm_lp_comparison_fx( /* Find prediction gain when resuing the Primary Channel LP filter */ // residu( A_PCh, m, speech, res, L_frame ); - scale_sig32( speech_buff, L_FRAME + M, negate( gb1 ) ); /* Q_speech */ + scale_sig32( speech_buff, L_FRAME + M, -4 ); /* Q_speech */ residu_ivas_fx( A_PCh_fx, sub( 14, norm_s( A_PCh_fx[0] ) ), m, speech_fx, res_fx, L_frame ); - exp = sub( 31, sub( Q_speech, gb1 ) ); + exp = sub( Q31, Q_speech ); sum2_value = sum2_32_exp_fx( res_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q16, &exp ); temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); /* Q25 */ @@ -1771,7 +1770,8 @@ Word16 tdm_lp_comparison_fx( /* Find Euclidian distance between the 2 filters */ dist_fx = 0; move16(); - gb = find_guarded_bits_fx( M ); + gb = 4; + move16(); FOR( i = 0; i < m; i++ ) { // ftmp = isp_SCh[i] - isp_PCh[i]; -- GitLab From 1e27039ccc7c4331876e997f74262588212b93fb Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 5 Feb 2025 18:41:50 +0100 Subject: [PATCH 0051/1221] increase timeout for ltv sanitizer tests --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cc2153f89..80edfcad6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,7 +23,7 @@ variables: PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 - TESTCASE_TIMEOUT_LTV_SANITIZERS: 6000 + TESTCASE_TIMEOUT_LTV_SANITIZERS: 7200 CI_REGRESSION_THRESH_MLD: "0.1" CI_REGRESSION_THRESH_MAX_ABS_DIFF: "50" CI_REGRESSION_THRESH_SSNR: "-1" -- GitLab From 4cacc9a846a7e826895e36d43cbb573e9c48a4b6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Feb 2025 12:36:04 +0530 Subject: [PATCH 0052/1221] Fix for 3GPP issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps Link #1245 --- lib_com/options.h | 1 + lib_enc/cng_enc_fx.c | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index fa1fd8f4e..ea2823ad7 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,5 +151,6 @@ #define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ #define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ #define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ +#define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ #endif #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 8a2495b40..4cfc193ec 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2024,13 +2024,23 @@ void CNG_enc_ivas_fx( /* convert log2 of residual signal energy */ /*enr = (float)log10( enr + 0.1f ) / (float)log10( 2.0f ); */ - hi = norm_l( L_ener ); - lo = Log2_norm_lc( L_shl( L_ener, hi ) ); - hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */ - hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */ - L_tmp = L_Comp( hi, lo ); /* Q16 */ - enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */ +#ifdef FIX_ISSUE_1245 + IF( L_ener == 0 ) + { + enr = -850; /*log(0.1) base 2 in Q8*/ + move16(); + } + ELSE +#endif + { + hi = norm_l( L_ener ); + lo = Log2_norm_lc( L_shl( L_ener, hi ) ); + hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */ + hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */ + L_tmp = L_Comp( hi, lo ); /* Q16 */ + enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */ + } /* update the circular buffer of old energies */ hTdCngEnc->cng_ener_hist_fx[hTdCngEnc->cng_hist_ptr] = enr; move16(); /* Q8 */ -- GitLab From 4817473b559d0464e7a695110745690c6f161dd0 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Feb 2025 12:39:29 +0530 Subject: [PATCH 0053/1221] Fix for 3GPP issue 1251: Basop Encoder: Spectral holes between 2-4 kHz and spectral differences for Unified Stereo @24kbps Link #1251 --- lib_com/stat_com.h | 2 +- lib_enc/fd_cng_enc.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 78d358be5..45a16dc1a 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -411,7 +411,7 @@ typedef struct Word16 psize_norm[NPART]; /* Partition sizes, fractional variable Q15-psize_norm_exp*/ Word16 psize_inv[NPART]; /* Inverse of partition sizes Q15*/ // Word16 FFTscalingFactor; /* Squared ratio between core signal analysis FFT and noise estimator FFT */ - Word16 scalingFactor; // Q15 + Word16 scalingFactor; // exp = -15 Word16 invScalingFactor; // Q15 Word16 nCLDFBpart; /* Number of CLDFB spectral partitions */ Word16 CLDFBpart[NPARTCLDFB]; /* CLDFB Partition upper boundaries (band indices starting from 0 above the core coder bands) */ diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 5c493876b..5fdc5e6f0 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -92,10 +92,12 @@ void perform_noise_estimation_enc_ivas_fx( move16(); assert( numSlots == 16 ); - Word32 numSlots_inv_fx = 134217728; + Word32 numSlots_inv_fx = 1073741824; // Q34 of .0625 move32(); Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; /* exp(peridog_exp) */ Word32 *ptr_per_fx = periodog; + Word64 periodog_64; + Word16 periodog_exp[PERIODOGLEN]; Word16 npart = hFdCngEnc->hFdCngCom->npart; /* Q0 */ move16(); Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; /* Q0 */ @@ -130,19 +132,19 @@ void perform_noise_estimation_enc_ivas_fx( SWITCH( input_Fs ) { case 8000: - scaleEB_fx = 62912; + scaleEB_fx = 251648; // Q35 move32(); BREAK; case 16000: - scaleEB_fx = 15728; + scaleEB_fx = 62912; // Q35 move32(); BREAK; case 32000: - scaleEB_fx = 3928; + scaleEB_fx = 15728; // Q35 move32(); BREAK; case 48000: - scaleEB_fx = 1744; + scaleEB_fx = 6991; // Q35 move32(); BREAK; default: @@ -151,8 +153,8 @@ void perform_noise_estimation_enc_ivas_fx( } ELSE { - scaleEB_fx = Mpy_32_16_1( numSlots_inv_fx, hFdCngEnc->hFdCngCom->scalingFactor ); - scaleEB_fx = L_shl( scaleEB_fx, 4 ); + scaleEB_fx = Mpy_32_32( numSlots_inv_fx, L_deposit_l( hFdCngEnc->hFdCngCom->scalingFactor ) ); // Q34 + Q30 - Q31 = Q33 + scaleEB_fx = L_shl( scaleEB_fx, 2 ); // Q35 } /* preemphasis compensation and grouping of per bin energies into msPeriodog */ @@ -167,22 +169,38 @@ void perform_noise_estimation_enc_ivas_fx( hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP ); move16(); + Word16 max_exp = -31; + move16(); + i = 0; + move16(); /* Adjust to the desired time resolution by averaging the periodograms over the time slots */ FOR( j = numCoreBands; j < regularStopBand; j++ ) { - *ptr_per_fx = Mpy_32_32( enerBuffer[j], scaleEB_fx ); /* exp(enerBuffer_exp) */ + periodog_64 = W_mult_32_32( enerBuffer[j], scaleEB_fx ); + Word16 scale = W_norm( periodog_64 ); + *ptr_per_fx = W_extract_h( W_shl( periodog_64, scale ) ); move32(); + periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) ); + move16(); + max_exp = s_max( max_exp, periodog_exp[i] ); ptr_per_fx++; - move16(); + i++; } - /* exponent for cldfb part of msPeriodog */ - hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP ); - move16(); + // hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP ); + // move16(); numBands = sub( regularStopBand, numCoreBands ); /* Q0 */ + FOR( i = 0; i < numBands; i++ ) + { + + periodog[i] = L_shr( periodog[i], sub( max_exp, periodog_exp[i] ) ); + move16(); + } + hFdCngEnc->hFdCngCom->exp_cldfb_periodog = max_exp; + move16(); IF( numBands > 0 ) { ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */ -- GitLab From bc4349ed7f54a1b6e46d0dd0c743577d02aa58c6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Feb 2025 13:29:03 +0530 Subject: [PATCH 0054/1221] Fix for LTV renderer crashes --- lib_rend/ivas_crend.c | 10 +++++----- lib_rend/ivas_dirac_rend.c | 14 -------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index d8cfec1d1..12bc769fa 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1854,8 +1854,8 @@ static ivas_error ivas_rend_crendConvolver( FOR( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max[i][j][m]; k++ ) { - tmp_out_re[k] = L_add( L_shl( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), 2 ), tmp_out_re[k] ); // Qx - tmp_out_im[k] = L_add( L_shl( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), 2 ), tmp_out_im[k] ); // Qx + tmp_out_re[k] = L_add( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), tmp_out_re[k] ); // Qx - 2 + tmp_out_im[k] = L_add( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), tmp_out_im[k] ); // Qx - 2 move32(); move32(); } @@ -1879,8 +1879,8 @@ static ivas_error ivas_rend_crendConvolver( pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_im_fx[j][offset]; // Q31 FOR( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max_diffuse[j][m]; k++ ) { - tmp_out_re[k] = L_add( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), tmp_out_re[k] ); // Qx - tmp_out_im[k] = L_add( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), tmp_out_im[k] ); // Qx + tmp_out_re[k] = L_add( L_shr( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), 2 ), tmp_out_re[k] ); // Qx - 2 + tmp_out_im[k] = L_add( L_shr( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), 2 ), tmp_out_im[k] ); // Qx - 2 move32(); move32(); } @@ -1888,7 +1888,7 @@ static ivas_error ivas_rend_crendConvolver( } ivas_imdft_fx( tmp_out_re, tmp_out_im, pOut, subframe_length ); - + scale_sig32( pOut, shl( subframe_length, 1 ), 2 ); #ifdef DEBUGGING dbgwrite_txt( (const float *) pOut, subframe_length << 1, "Fixed_imdft_out.txt", NULL ); #endif diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index ea507b4c7..cafd70966 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -4014,20 +4014,6 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); } - /*Buffer Scaling*/ - FOR( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) - { - FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - scale_sig32( Cldfb_RealBuffer_fx[ch][slot_idx], - hSpatParamRendCom->num_freq_bands, sub( 11, q_cldfb ) ); // q11 - scale_sig32( Cldfb_ImagBuffer_fx[ch][slot_idx], - hSpatParamRendCom->num_freq_bands, sub( 11, q_cldfb ) ); // q11 - } - } - q_cldfb = 11; - move16(); - Word16 reference_power_temp_q = getScaleFactor32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len ); scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, reference_power_temp_q ); /*DirAC_mem.reference_power_q + reference_power_temp_q*/ DirAC_mem.reference_power_q = add( DirAC_mem.reference_power_q, reference_power_temp_q ); -- GitLab From d87b85be7960ace2aa6b2a8b8a15c96d3c0dd5bb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Feb 2025 14:27:36 +0530 Subject: [PATCH 0055/1221] Bug fixes and precision improvements - 2 [x] fix for precision loss for bin_e in analy_sp [x] Correcting attackIndex --- lib_enc/analy_sp_fx.c | 18 +++++++-------- lib_enc/transient_detection_fx.c | 38 +++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index d31f2ff08..f0d940563 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -476,6 +476,8 @@ void ivas_analy_sp_fx( Word32 Ltmp; Word16 *pt_fft; Word16 exp, tmp; + Word16 resultant_q; + Word16 exp2; Word64 LEtot; LEtot = 0; move64(); @@ -679,16 +681,12 @@ void ivas_analy_sp_fx( } exp = L_norm_arr( Bin_E, L_FFT / 2 ); - IF( GE_16( exp, sub( *q_Bin_E, Q22 ) ) ) - { - scale_sig32( Bin_E, L_FFT / 2, sub( *q_Bin_E, Q22 ) ); // *q_Bin_E - } - ELSE - { - scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( Q22, *q_Bin_E ) ); // Q22 - *q_Bin_E = Q22; - move16(); - } + exp2 = L_norm_arr( Bin_E + L_FFT / 2, L_FFT / 2 ); + resultant_q = s_min( Q22, s_min( add( *q_Bin_E, exp2 ), add( exp, Q22 ) ) ); // calculating resultant q after scaling + scale_sig32( Bin_E, L_FFT / 2, sub( resultant_q, Q22 ) ); // Q22=>resultant_q + scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( resultant_q, *q_Bin_E ) ); // q_Bin_E=>resultant_q + *q_Bin_E = resultant_q; + move16(); return; } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 736d838c2..920cd508f 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -147,6 +147,7 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 Word16 i; Word16 bIsAttackPresent, attackIndex; Word16 attackRatioThreshold_1_5; + Word64 W_tmp1, W_tmp2, W_tmp3; (void) nPastSubblocks; (void) nSubblocks; @@ -161,7 +162,7 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 bIsAttackPresent = FALSE; attackIndex = -1; /* Search for the last attack in the subblocks */ - if ( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), + IF ( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) { move16(); @@ -172,7 +173,10 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 FOR( i = 0; i < NSUBBLOCKS; i++ ) { - IF( GT_32( L_shr( pSubblockNrg[i], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[i], attackRatioThreshold ) ) ) + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + + IF( GT_64( W_tmp1, W_tmp2 ) ) { if ( i < 6 ) { @@ -180,22 +184,44 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 bIsAttackPresent = TRUE; } - if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + IF ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) { move16(); attackIndex = i; + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 ); + W_tmp2 = W_add( W_tmp2, W_shr( W_tmp2, 3 ) ); // pAccSubblockNrg[i] * 1.125f + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + if ( s_and( (Word16) LT_64( W_tmp1, W_tmp2 ), s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) + { + attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ + } } } ELSE /* no attack, but set index anyway in case of strong energy increase */ { - IF( s_and( ( (Word16) GT_32( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 1 )], attackRatioThreshold_1_5 ) ) ), - ( L_sub( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 2 )], attackRatioThreshold_1_5 ) ) > 0 ) ) ) + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i - 1], attackRatioThreshold_1_5 ), 1 ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ( ATTACKTHRESHOLD_E + 1 ) ) ); + W_tmp3 = W_shr( W_mult_32_16( pAccSubblockNrg[i - 2], attackRatioThreshold_1_5 ), 1 ); + + IF( s_and( ( (Word16) GT_64( W_tmp1, W_tmp2 ) ), + ( W_sub( W_tmp1, W_tmp3 ) > 0 ) ) ) { - if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + IF ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) { move16(); attackIndex = i; + + W_tmp2 = W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold ); + W_tmp3= W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + + if ( s_and( (Word16) s_or( (Word16) LT_64( W_tmp1, W_tmp2 ), (Word16) + LT_64( W_tmp1, W_tmp3 ) ), + s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) + { + attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ + } } } } -- GitLab From 6e62492afa0fd5be6f58a3885b5db4386304edf4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Feb 2025 15:01:44 +0530 Subject: [PATCH 0056/1221] Clang formatting changes --- lib_enc/transient_detection_fx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 920cd508f..3e4b29acc 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -162,8 +162,8 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 bIsAttackPresent = FALSE; attackIndex = -1; /* Search for the last attack in the subblocks */ - IF ( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), - L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) + IF( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), + L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) { move16(); bIsAttackPresent = TRUE; @@ -173,7 +173,7 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 FOR( i = 0; i < NSUBBLOCKS; i++ ) { - W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1); + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 ); W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); IF( GT_64( W_tmp1, W_tmp2 ) ) @@ -184,7 +184,7 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 bIsAttackPresent = TRUE; } - IF ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) { move16(); attackIndex = i; @@ -207,17 +207,17 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 ( W_sub( W_tmp1, W_tmp3 ) > 0 ) ) ) { - IF ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) { move16(); attackIndex = i; W_tmp2 = W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold ); - W_tmp3= W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold ); + W_tmp3 = W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold ); W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); if ( s_and( (Word16) s_or( (Word16) LT_64( W_tmp1, W_tmp2 ), (Word16) - LT_64( W_tmp1, W_tmp3 ) ), + LT_64( W_tmp1, W_tmp3 ) ), s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) { attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ -- GitLab From 8d14bce5907700aa296db9634ad20e093adc309f Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 13:03:40 +0100 Subject: [PATCH 0057/1221] some push/pop wmops added, also addedd FIX_1072_SPEEDUP_gainpanning and FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB active --- lib_com/ivas_dirac_com.c | 51 +++++++++++++ lib_com/options.h | 6 +- lib_dec/ivas_dirac_dec.c | 23 ++++-- lib_rend/ivas_dirac_output_synthesis_dec.c | 89 +++++++++++++++++++++- 4 files changed, 160 insertions(+), 9 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index ebd958e1b..796fc8960 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -960,6 +960,7 @@ void computeDiffuseness_fixed( q_intensity = add( q_factor_intensity[0], min_q_shift2 ); move16(); + push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" ); FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) { /* Energy slow */ @@ -967,6 +968,28 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); + +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB + Word16 shift_q = sub( q_tmp, q_ene ); + Word32 shiftEquiv; + Word16 shift_qtotal; + if( shift_q < 0 ) + { + shiftEquiv = L_lshl( 0x80000000, shift_q ); + shift_qtotal = sub( min_q_shift1, 0 ); + } + if( shift_q >= 0 ) + { + shiftEquiv = L_add( 0x7FFFFFFF, 0 ); + shift_qtotal = sub( min_q_shift1, shift_q ); + } + FOR( k = 0; k < num_freq_bands; k++ ) + { + tmp = L_shl( p_tmp_c[k], shift_qtotal ); + energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); + move32(); + } +#else Word16 shift_q = sub( q_tmp, q_ene ); IF( shift_q < 0 ) { @@ -986,6 +1009,9 @@ void computeDiffuseness_fixed( move32(); } } +#endif + + q_ene = s_min( q_ene, q_tmp ); @@ -993,6 +1019,28 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB + if( shift_q >= 0 ) + { + shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); + shift_qtotal = sub( min_q_shift2, shift_q ); + } + if ( shift_q < 0 ) + { + shiftEquiv = L_lshl( 0x80000000, shift_q ); + shift_qtotal = sub( min_q_shift2, 0 ); + } + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = buffer_intensity[j][i]; + FOR( k = 0; k < num_freq_bands; k++ ) + { + tmp = L_shl( p_tmp[k], shift_qtotal ); + intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv ); + move32(); + } + } +#else IF( shift_q > 0 ) { FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) @@ -1019,8 +1067,11 @@ void computeDiffuseness_fixed( } } } +#endif + q_intensity = s_min( q_intensity, q_tmp ); } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" );/*/ min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) ); min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) ); diff --git a/lib_com/options.h b/lib_com/options.h index fa1fd8f4e..5dfebfaa6 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +//#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -153,3 +153,7 @@ #define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ #endif #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ + + +#define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ \ No newline at end of file diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 95cca12a0..318a3ec55 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2231,7 +2231,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); Word16 tmp1; - push_wmops( "ivas_dirac_dec_render" ); + push_wmops( "ivas_dirac_dec_render (IDR)" ); /* Initialize aux buffers */ hDirAC = st_ivas->hDirAC; @@ -2341,6 +2341,7 @@ void ivas_dirac_dec_render_sf_fx( } ELSE IF( !( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) { + push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" ); Word16 outchannels; idx_lfe = 0; move16(); @@ -2409,6 +2410,7 @@ void ivas_dirac_dec_render_sf_fx( } } } + pop_wmops(); /*push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" );*/ } size = imult1616( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); @@ -2555,7 +2557,7 @@ void ivas_dirac_dec_render_sf_fx( p_Rmat_fx = 0; move32(); } - + IF( ( hDirAC->hConfig->dec_param_estim == FALSE ) ) { Word16 *masa_band_mapping; @@ -2706,6 +2708,7 @@ void ivas_dirac_dec_render_sf_fx( } } + push_wmops( "(IDR) LOOP1" ); FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { index_slot = add( slot_idx_start, slot_idx ); @@ -2923,6 +2926,8 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: + pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; @@ -2932,6 +2937,7 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * Compute DirAC parameters at decoder side *-----------------------------------------------------------------*/ + push_wmops( "(IDR) LOOP1 DirACparams |" ); IF( EQ_16( hDirAC->hConfig->dec_param_estim, TRUE ) ) { Copy( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], sub( hSpatParamRendCom->num_freq_bands, hDirAC->hConfig->enc_param_start_band ) ); @@ -2980,8 +2986,11 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; move16(); + push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" ); computeDiffuseness_fixed( hDirACRend->buffer_intensity_real_fx, hDirACRend->buffer_energy_fx, num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], hDirACRend->q_buffer_intensity_real, hDirACRend->q_buffer_energy, &hSpatParamRendCom->q_diffuseness_vector ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" );/*/ } + pop_wmops(); /* push_wmops( "(IDR) LOOP1 DirACparams |" );*/ /*-----------------------------------------------------------------* * frequency domain decorrelation @@ -3083,6 +3092,7 @@ void ivas_dirac_dec_render_sf_fx( } /*Compute PSDs*/ + push_wmops( "(IDR) LOOP1 PSDs |" ); h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params ); h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state ); num_channels_dir = hDirACRend->num_outputs_dir; @@ -3165,6 +3175,7 @@ void ivas_dirac_dec_render_sf_fx( } ELSE { + push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" ); ivas_dirac_dec_output_synthesis_process_slot_fx( reference_power_fx, DirAC_mem.reference_power_q, p_onset_filter_fx, @@ -3182,6 +3193,7 @@ void ivas_dirac_dec_render_sf_fx( md_idx, hodirac_flag, hDirAC->hConfig->dec_param_estim ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" );/*/ } IF( hDirAC->hConfig->dec_param_estim ) @@ -3252,7 +3264,9 @@ void ivas_dirac_dec_render_sf_fx( v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); q_reference_power_smooth = sub( q_reference_power_smooth, 1 ); } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs |" );*/ } + pop_wmops(); /*push_wmops( "(IDR) LOOP1" );*/ minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) @@ -3581,7 +3595,6 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * CLDFB synthesis (and binaural rendering) *-----------------------------------------------------------------*/ - index_slot = slot_idx_start_cldfb_synth; move16(); @@ -3963,6 +3976,7 @@ void ivas_dirac_dec_render_sf_fx( } } + hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); move16(); hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); @@ -4077,8 +4091,7 @@ void ivas_dirac_dec_render_sf_fx( } } } - - pop_wmops(); + pop_wmops(); /*push_wmops( "ivas_dirac_dec_render (IDR)" );*/ return; } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 4686ca1e6..5b37ab7d9 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -710,11 +710,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } + push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" ); test(); IF( dec_param_estim == FALSE && hodirac_flag ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" ); v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */ v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/ Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx], @@ -737,19 +739,24 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); h_dirac_output_synthesis_state->direct_power_factor_q = 30; move16(); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" );/*/ } ELSE { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" ); ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], h_dirac_output_synthesis_state->direct_power_factor_fx, h_dirac_output_synthesis_state->diffuse_power_factor_fx, &h_dirac_output_synthesis_state->direct_power_factor_q, &h_dirac_output_synthesis_state->diffuse_power_factor_q ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" );*/ } } ELSE IF( EQ_16( dec_param_estim, TRUE ) ) { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" ); + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" ); /* compute direct responses */ ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom, hDirACRend, @@ -764,7 +771,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sh_rot_max_order, p_Rmat, hodirac_flag ); - + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" );*/ { IF( h_dirac_output_synthesis_state->direct_responses_square_fx ) { @@ -811,12 +818,14 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[kk] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; move16(); } - + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" ); FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ ) { Word16 k; IF( ch_idx != 0 ) { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" ); + ; Word32 a, c; Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c; Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab; @@ -906,6 +915,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ + + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -987,9 +998,12 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" );*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" );*/ } ELSE { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" ); Word32 sqr_inp, mpy_diff, sqr; Word16 sqr_exp; /*Diffuseness modellling nrg compensation*/ @@ -1027,6 +1041,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1 @@ -1060,8 +1075,12 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" );*/ + pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ } } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ + Word16 temp = MAX_16; /*q0*/ move16(); tmp16 = imult1616( num_freq_bands, num_channels_dir ); @@ -1078,9 +1097,21 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } free( Q_temp_cy_cross_dir_smooth_fx ); /*Directional gain (panning)*/ + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" ); + Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { +#ifdef FIX_1072_SPEEDUP_gainpanning /*is there any difference in any bitstream?*/ + Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); + FOR( Word16 kk = 0; kk < tmp16; kk++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], temp_q1 ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ + move32(); + } + h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; + move16(); +#else FOR( Word16 kk = 0; kk < tmp16; kk++ ) { h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ @@ -1088,7 +1119,53 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); +#endif + } +#ifdef FIX_1072_SPEEDUP_gainpanning + Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); + FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) + { + IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + { + Word16 i; + Word32 aux; + IF(temp_q1 < 0) + { + Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); + FOR( i = 0; i < num_freq_bands; i++ ) + { + aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] , aux, temp_q1_equiv ); + move32(); + } + } + ELSE + { + FOR( i = 0; i < num_freq_bands; i++ ) + { + aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + aux = L_shl( aux, temp_q1 ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux ); + move32(); + } + } + + } + ELSE + { + Word16 i; + FOR( i = 0; i < num_freq_bands; i++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + move32(); + } + } + + + } + +#else FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { v_mult_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx, @@ -1107,6 +1184,9 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ } +#endif + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" );*/ + /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) { @@ -1124,7 +1204,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/ } - + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3 <<-|" );/*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ return; } ELSE @@ -1143,7 +1224,9 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ diff_start_band = 0; move16(); -- GitLab From 6a2e3a1e83a250a8e6748af2bf6ad963f403cb30 Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:14:20 +0100 Subject: [PATCH 0058/1221] some introduction to more tunings :: FIX_1072_SPEEDUP_output_synthesis_procSlot - inactive --- lib_com/options.h | 5 +++-- lib_rend/ivas_dirac_output_synthesis_dec.c | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 5dfebfaa6..92144ade1 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -//#define WMOPS /* Activate complexity and memory counters */ +/*#define WMOPS*/ /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -156,4 +156,5 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ \ No newline at end of file +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ +//#define FIX_1072_SPEEDUP_output_synthesis_procSlot /* "-" */ \ No newline at end of file diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 5b37ab7d9..404f98b1b 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -942,7 +942,18 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } +#ifdef FIX_1072_SPEEDUP_output_synthesis_procSlot + q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + q_diff_c = sub( q_diffuseness, 4 ); + + mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 + mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 + mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 + + /*Todo: simplify so that mpy+add can be merged to madd*/ + sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ +#else mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 @@ -970,6 +981,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/ } } +#endif + sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) -- GitLab From b05d69a9edf078616466f69a705ceb5845b831c8 Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:16:18 +0100 Subject: [PATCH 0059/1221] cleaning up options.h --- lib_com/options.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 92144ade1..7e8912490 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -155,6 +155,5 @@ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ -#define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ -//#define FIX_1072_SPEEDUP_output_synthesis_procSlot /* "-" */ \ No newline at end of file +#define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* FhG: Minor WMOPS tuning, nonbe */ -- GitLab From 0917f3f7b1c455ae3c6fedf4c4e0830415137fbe Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:17:58 +0100 Subject: [PATCH 0060/1221] some more cleaning --- lib_com/ivas_dirac_com.c | 4 ++-- lib_com/options.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 796fc8960..97c8a88bd 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -969,7 +969,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; @@ -1019,7 +1019,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS if( shift_q >= 0 ) { shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); diff --git a/lib_com/options.h b/lib_com/options.h index 7e8912490..b47825b32 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,4 +156,4 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* FhG: Minor WMOPS tuning, nonbe */ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* FhG: Minor WMOPS tuning, nonbe */ -- GitLab From 491400705b0984e8379706dfd004e883507edee1 Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:22:03 +0100 Subject: [PATCH 0061/1221] apply clang format patch --- lib_com/ivas_dirac_com.c | 7 +++---- lib_dec/ivas_dirac_dec.c | 4 ++-- lib_rend/ivas_dirac_output_synthesis_dec.c | 12 ++++-------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 97c8a88bd..d03191084 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -973,12 +973,12 @@ void computeDiffuseness_fixed( Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; - if( shift_q < 0 ) + if ( shift_q < 0 ) { shiftEquiv = L_lshl( 0x80000000, shift_q ); shift_qtotal = sub( min_q_shift1, 0 ); } - if( shift_q >= 0 ) + if ( shift_q >= 0 ) { shiftEquiv = L_add( 0x7FFFFFFF, 0 ); shift_qtotal = sub( min_q_shift1, shift_q ); @@ -1012,7 +1012,6 @@ void computeDiffuseness_fixed( #endif - q_ene = s_min( q_ene, q_tmp ); /* Intensity slow */ @@ -1020,7 +1019,7 @@ void computeDiffuseness_fixed( shift_q = sub( q_tmp, q_intensity ); #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS - if( shift_q >= 0 ) + if ( shift_q >= 0 ) { shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); shift_qtotal = sub( min_q_shift2, shift_q ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 318a3ec55..81429927a 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2557,7 +2557,7 @@ void ivas_dirac_dec_render_sf_fx( p_Rmat_fx = 0; move32(); } - + IF( ( hDirAC->hConfig->dec_param_estim == FALSE ) ) { Word16 *masa_band_mapping; @@ -2926,7 +2926,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: - pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 404f98b1b..3f4111253 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1089,7 +1089,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" );*/ - pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ } } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ @@ -1133,7 +1133,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); #endif - } #ifdef FIX_1072_SPEEDUP_gainpanning Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); @@ -1143,13 +1142,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { Word16 i; Word32 aux; - IF(temp_q1 < 0) + IF( temp_q1 < 0 ) { Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] , aux, temp_q1_equiv ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv ); move32(); } } @@ -1163,7 +1162,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } - } ELSE { @@ -1174,8 +1172,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } - - } #else @@ -1237,7 +1233,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ -- GitLab From 59fd769bd56da5f9aec8aad04125283815b1a260 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 6 Feb 2025 14:30:48 +0000 Subject: [PATCH 0062/1221] Final cleanups before merge --- lib_com/ivas_dirac_com.c | 2 - lib_dec/ivas_dirac_dec.c | 21 ++-------- lib_rend/ivas_dirac_output_synthesis_dec.c | 45 ++-------------------- 3 files changed, 7 insertions(+), 61 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index d03191084..e07d36b1e 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -960,7 +960,6 @@ void computeDiffuseness_fixed( q_intensity = add( q_factor_intensity[0], min_q_shift2 ); move16(); - push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" ); FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) { /* Energy slow */ @@ -1070,7 +1069,6 @@ void computeDiffuseness_fixed( q_intensity = s_min( q_intensity, q_tmp ); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" );/*/ min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) ); min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 81429927a..95cca12a0 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2231,7 +2231,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); Word16 tmp1; - push_wmops( "ivas_dirac_dec_render (IDR)" ); + push_wmops( "ivas_dirac_dec_render" ); /* Initialize aux buffers */ hDirAC = st_ivas->hDirAC; @@ -2341,7 +2341,6 @@ void ivas_dirac_dec_render_sf_fx( } ELSE IF( !( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) { - push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" ); Word16 outchannels; idx_lfe = 0; move16(); @@ -2410,7 +2409,6 @@ void ivas_dirac_dec_render_sf_fx( } } } - pop_wmops(); /*push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" );*/ } size = imult1616( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); @@ -2708,7 +2706,6 @@ void ivas_dirac_dec_render_sf_fx( } } - push_wmops( "(IDR) LOOP1" ); FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { index_slot = add( slot_idx_start, slot_idx ); @@ -2926,8 +2923,6 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: - pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; @@ -2937,7 +2932,6 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * Compute DirAC parameters at decoder side *-----------------------------------------------------------------*/ - push_wmops( "(IDR) LOOP1 DirACparams |" ); IF( EQ_16( hDirAC->hConfig->dec_param_estim, TRUE ) ) { Copy( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], sub( hSpatParamRendCom->num_freq_bands, hDirAC->hConfig->enc_param_start_band ) ); @@ -2986,11 +2980,8 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; move16(); - push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" ); computeDiffuseness_fixed( hDirACRend->buffer_intensity_real_fx, hDirACRend->buffer_energy_fx, num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], hDirACRend->q_buffer_intensity_real, hDirACRend->q_buffer_energy, &hSpatParamRendCom->q_diffuseness_vector ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" );/*/ } - pop_wmops(); /* push_wmops( "(IDR) LOOP1 DirACparams |" );*/ /*-----------------------------------------------------------------* * frequency domain decorrelation @@ -3092,7 +3083,6 @@ void ivas_dirac_dec_render_sf_fx( } /*Compute PSDs*/ - push_wmops( "(IDR) LOOP1 PSDs |" ); h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params ); h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state ); num_channels_dir = hDirACRend->num_outputs_dir; @@ -3175,7 +3165,6 @@ void ivas_dirac_dec_render_sf_fx( } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" ); ivas_dirac_dec_output_synthesis_process_slot_fx( reference_power_fx, DirAC_mem.reference_power_q, p_onset_filter_fx, @@ -3193,7 +3182,6 @@ void ivas_dirac_dec_render_sf_fx( md_idx, hodirac_flag, hDirAC->hConfig->dec_param_estim ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" );/*/ } IF( hDirAC->hConfig->dec_param_estim ) @@ -3264,9 +3252,7 @@ void ivas_dirac_dec_render_sf_fx( v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); q_reference_power_smooth = sub( q_reference_power_smooth, 1 ); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs |" );*/ } - pop_wmops(); /*push_wmops( "(IDR) LOOP1" );*/ minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) @@ -3595,6 +3581,7 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * CLDFB synthesis (and binaural rendering) *-----------------------------------------------------------------*/ + index_slot = slot_idx_start_cldfb_synth; move16(); @@ -3976,7 +3963,6 @@ void ivas_dirac_dec_render_sf_fx( } } - hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); move16(); hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); @@ -4091,7 +4077,8 @@ void ivas_dirac_dec_render_sf_fx( } } } - pop_wmops(); /*push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + + pop_wmops(); return; } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 3f4111253..866badda0 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -710,13 +710,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } - push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" ); test(); IF( dec_param_estim == FALSE && hodirac_flag ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" ); v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */ v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/ Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx], @@ -739,24 +737,19 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); h_dirac_output_synthesis_state->direct_power_factor_q = 30; move16(); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" );/*/ } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" ); ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], h_dirac_output_synthesis_state->direct_power_factor_fx, h_dirac_output_synthesis_state->diffuse_power_factor_fx, &h_dirac_output_synthesis_state->direct_power_factor_q, &h_dirac_output_synthesis_state->diffuse_power_factor_q ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" );*/ } } ELSE IF( EQ_16( dec_param_estim, TRUE ) ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" ); - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" ); /* compute direct responses */ ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom, hDirACRend, @@ -771,7 +764,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sh_rot_max_order, p_Rmat, hodirac_flag ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" );*/ + { IF( h_dirac_output_synthesis_state->direct_responses_square_fx ) { @@ -818,14 +811,12 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[kk] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; move16(); } - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" ); + FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ ) { Word16 k; IF( ch_idx != 0 ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" ); - ; Word32 a, c; Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c; Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab; @@ -915,8 +906,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ - - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -942,22 +931,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } -#ifdef FIX_1072_SPEEDUP_output_synthesis_procSlot - q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - q_diff_c = sub( q_diffuseness, 4 ); mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - /*Todo: simplify so that mpy+add can be merged to madd*/ - sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ - -#else - mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 - mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 - mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); q_diff_c = sub( q_diffuseness, 4 ); @@ -981,8 +959,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/ } } -#endif - sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) @@ -1011,12 +987,9 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" );*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" );*/ } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" ); Word32 sqr_inp, mpy_diff, sqr; Word16 sqr_exp; /*Diffuseness modellling nrg compensation*/ @@ -1054,7 +1027,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1 @@ -1088,12 +1060,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" );*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ } } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ - Word16 temp = MAX_16; /*q0*/ move16(); tmp16 = imult1616( num_freq_bands, num_channels_dir ); @@ -1110,8 +1078,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } free( Q_temp_cy_cross_dir_smooth_fx ); /*Directional gain (panning)*/ - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" ); - Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { @@ -1192,9 +1158,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ } - #endif - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" );*/ /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) @@ -1213,8 +1177,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/ } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3 <<-|" );/*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ + return; } ELSE @@ -1233,9 +1196,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ diff_start_band = 0; move16(); -- GitLab From f5fe2f050dca5c506a610bb38f9290e5e057826f Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:53:56 +0100 Subject: [PATCH 0063/1221] Revert "apply clang format patch" This reverts commit 491400705b0984e8379706dfd004e883507edee1. --- lib_com/ivas_dirac_com.c | 7 ++++--- lib_dec/ivas_dirac_dec.c | 4 ++-- lib_rend/ivas_dirac_output_synthesis_dec.c | 12 ++++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index d03191084..97c8a88bd 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -973,12 +973,12 @@ void computeDiffuseness_fixed( Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; - if ( shift_q < 0 ) + if( shift_q < 0 ) { shiftEquiv = L_lshl( 0x80000000, shift_q ); shift_qtotal = sub( min_q_shift1, 0 ); } - if ( shift_q >= 0 ) + if( shift_q >= 0 ) { shiftEquiv = L_add( 0x7FFFFFFF, 0 ); shift_qtotal = sub( min_q_shift1, shift_q ); @@ -1012,6 +1012,7 @@ void computeDiffuseness_fixed( #endif + q_ene = s_min( q_ene, q_tmp ); /* Intensity slow */ @@ -1019,7 +1020,7 @@ void computeDiffuseness_fixed( shift_q = sub( q_tmp, q_intensity ); #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS - if ( shift_q >= 0 ) + if( shift_q >= 0 ) { shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); shift_qtotal = sub( min_q_shift2, shift_q ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 81429927a..318a3ec55 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2557,7 +2557,7 @@ void ivas_dirac_dec_render_sf_fx( p_Rmat_fx = 0; move32(); } - + IF( ( hDirAC->hConfig->dec_param_estim == FALSE ) ) { Word16 *masa_band_mapping; @@ -2926,7 +2926,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: - pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 3f4111253..404f98b1b 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1089,7 +1089,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" );*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ + pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ } } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ @@ -1133,6 +1133,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); #endif + } #ifdef FIX_1072_SPEEDUP_gainpanning Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); @@ -1142,13 +1143,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { Word16 i; Word32 aux; - IF( temp_q1 < 0 ) + IF(temp_q1 < 0) { Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] , aux, temp_q1_equiv ); move32(); } } @@ -1162,6 +1163,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } + } ELSE { @@ -1172,6 +1174,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } + + } #else @@ -1233,7 +1237,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ -- GitLab From 896f21e54f609aaaab580d12e6056add7a6b5899 Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:54:25 +0100 Subject: [PATCH 0064/1221] Revert "some more cleaning" This reverts commit 0917f3f7b1c455ae3c6fedf4c4e0830415137fbe. --- lib_com/ivas_dirac_com.c | 4 ++-- lib_com/options.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 97c8a88bd..796fc8960 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -969,7 +969,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; @@ -1019,7 +1019,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB if( shift_q >= 0 ) { shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); diff --git a/lib_com/options.h b/lib_com/options.h index b47825b32..7e8912490 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,4 +156,4 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* FhG: Minor WMOPS tuning, nonbe */ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* FhG: Minor WMOPS tuning, nonbe */ -- GitLab From ac90f9d69453b85c66a40220c4a4e6cc9b715d72 Mon Sep 17 00:00:00 2001 From: ber Date: Thu, 6 Feb 2025 15:54:47 +0100 Subject: [PATCH 0065/1221] Revert "cleaning up options.h" This reverts commit b05d69a9edf078616466f69a705ceb5845b831c8. --- lib_com/options.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 7e8912490..92144ade1 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -155,5 +155,6 @@ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ -#define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* FhG: Minor WMOPS tuning, nonbe */ +#define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ +//#define FIX_1072_SPEEDUP_output_synthesis_procSlot /* "-" */ \ No newline at end of file -- GitLab From 2c1b2511abdc3d0f23aca9a5b8d92818cac4aa5a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 6 Feb 2025 16:00:00 +0100 Subject: [PATCH 0066/1221] use dedicated ubsan suppression file for BASOP --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 80edfcad6..a14f9ba7d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -522,7 +522,7 @@ stages: - *build-reference-and-dut-binaries - make clean - make -j CLANG=$CLANG_NUM - - if [[ $CLANG_NUM == 3 ]]; then export UBSAN_OPTIONS="suppressions=scripts/ubsan.supp,report_error_type=1"; fi + - if [[ $CLANG_NUM == 3 ]]; then export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1"; fi - testcase_timeout=$TESTCASE_TIMEOUT_LTV_SANITIZERS - python3 -m pytest $TEST_SUITE -v --tb=no --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout $testcase_timeout --ref_encoder_path $DUT_ENCODER_PATH --ref_decoder_path $DUT_DECODER_PATH artifacts: -- GitLab From 61f9239eda5c8668495afb019252f60ae01b8e38 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 6 Feb 2025 14:50:35 +0100 Subject: [PATCH 0067/1221] increase job timeout for sanitizer jobs --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a14f9ba7d..0f1c85764 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -506,7 +506,7 @@ stages: .ivas-pytest-sanitizers-anchor: &ivas-pytest-sanitizers-anchor stage: test needs: ["build-codec-linux-make"] - timeout: "300 minutes" + timeout: "420 minutes" rules: - if: $CI_PIPELINE_SOURCE == 'push' when: never -- GitLab From 26535cc7362e4da1ecc419cb0e9e9a7cb09f86c6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Feb 2025 16:05:38 +0530 Subject: [PATCH 0068/1221] Stereo and MCH optimizations --- lib_com/cldfb.c | 2 +- lib_com/ivas_stereo_ica_com_fx.c | 62 +++++------ lib_com/ivas_tools.c | 124 ++++++++++++++-------- lib_com/options.h | 3 +- lib_dec/dec_tcx.c | 35 +++--- lib_dec/ivas_binRenderer_internal.c | 81 +++++++------- lib_dec/ivas_dirac_output_synthesis_cov.c | 57 +++------- lib_dec/ivas_svd_dec.c | 74 +++++++++++-- lib_rend/ivas_dirac_decorr_dec.c | 93 ++++++++-------- 9 files changed, 299 insertions(+), 232 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 5a3d2e1a2..b6eafd993 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1213,7 +1213,7 @@ void cldfbSynthesis_ivas_fx( /*cplxMult(&iBuffer[2*i], &iBuffer[2*i+1],-imagBuffer[k][2*i], imagBuffer[k][M1-1-2*i], rot_vctr_re[i], rot_vctr_im[i]);*/ iBuffer_fx[2 * i] = Msub_32_32( Mpy_32_32( ( L_negate( imagBuffer_fx[k][2 * i] ) ), rot_vctr_re_fx[i] ), imagBuffer_fx[k][( M1 - 1 ) - ( i * 2 )], rot_vctr_im_fx[i] ); // Qx move32(); - iBuffer_fx[2 * i + 1] = Madd_32_32( Mpy_32_32( ( L_negate( imagBuffer_fx[k][2 * i] ) ), rot_vctr_im_fx[i] ), imagBuffer_fx[k][( M1 - 1 ) - ( i * 2 )], rot_vctr_re_fx[i] ); // Qx + iBuffer_fx[2 * i + 1] = Msub_32_32( Mpy_32_32( imagBuffer_fx[k][( M1 - 1 ) - ( i * 2 )], rot_vctr_re_fx[i] ), imagBuffer_fx[k][2 * i], rot_vctr_im_fx[i] ); // Qx move32(); } diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index 3ebfd99c1..be9f35868 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -131,17 +131,7 @@ static void interpTargetChannel_fx( Word32 spread_factor2_fx; Word64 tempD1_fx, tempD2_fx; - d = negate( sub( currShift, prevShift ) ); - IF( d >= 0 ) - { - signShift = 1; - move16(); - } - ELSE - { - signShift = -1; - move16(); - } + d = sub( prevShift, currShift ); IF( d == 0 ) { @@ -149,6 +139,15 @@ static void interpTargetChannel_fx( return; } + signShift = 1; + move16(); + + if ( d < 0 ) + { + signShift = -1; + move16(); + } + N = L_shift_adapt; move16(); Word32 *table_pointer = NULL; @@ -207,7 +206,7 @@ static void interpTargetChannel_fx( FOR( j = lim1; j <= lim2; j++ ) { - ptr2_fx[i] = L_add( Mpy_32_32( win_fx[j * INTERP_FACTOR1 - i], ptr1_fx[j] ), ptr2_fx[i] ); // qsynth + ptr2_fx[i] = Madd_32_32( ptr2_fx[i], win_fx[j * INTERP_FACTOR1 - i], ptr1_fx[j] ); // qsynth move32(); } } @@ -225,44 +224,31 @@ static void interpTargetChannel_fx( tempD1_fx = W_deposit32_l( table_D1_pointer[abs( d )] ); // Q35 tempD2_fx = W_mult0_32_32( 3, table_D1_pointer[abs( d )] ); // Q35 - IF( EQ_16( signShift, 1 ) ) + tempF1_fx = -ONE_IN_Q12; // Q12 + move32(); + + if ( EQ_16( signShift, 1 ) ) { tempF1_fx = ONE_IN_Q12; // Q12 move32(); } - ELSE - { - tempF1_fx = -ONE_IN_Q12; // Q12 - move32(); - } + tempF1_fx = L_sub( imult3216( factor_fx, d ), tempF1_fx ); // Q12 - FOR( k = 0; k < sub( N, 1 ); k++ ) + FOR( k = 0; k < N - 1; k++ ) { - Word32 local = L_sub( W_extract_l( W_shr( W_mult0_32_32( tempF1_fx, spread_factor2_fx ), 31 ) ), ONE_IN_Q12 ); // Q12 - Word32 sign_local; - IF( local > 0 ) - { - sign_local = 1; - move32(); - } - ELSE - { - sign_local = -1; - move32(); - } - Word32 local_int = W_extract_l( W_shr( W_abs( local ), 12 ) ); // Q0 + Word32 local = Madd_32_32( -ONE_IN_Q12, tempF1_fx, spread_factor2_fx ); // Q12 + Word32 local_int = L_shr( local, 12 ); // Q0 Word32 res_a1, res_a2, res_a3; Word32 res_b1, res_b2, res_b3; Word32 res_c1, res_c2, res_c3; Word32 res_d1, res_d2, res_d3; - Word64 local_int_scaled; + Word32 local_int_scaled; Word64 res_a, res_b, res_c, res_d; Word64 tempa, tempb; Word64 mult_a_D1, mult_b_D2; - local_int = W_extract_l( W_mult0_32_32( sign_local, local_int ) ); // Q0 - local_int_scaled = W_deposit32_l( L_shl( local_int, 12 ) ); // Q12 - lim1 = extract_l( local_int ); // Q0 - IF( W_sub( local_int_scaled, local ) > 0 ) // Q21 + local_int_scaled = L_shl( local_int, 12 ); // Q12 + lim1 = extract_l( local_int ); // Q0 + if ( L_sub( local_int_scaled, local ) > 0 ) // Q12 { lim1 = sub( lim1, 1 ); // Q0 } @@ -387,7 +373,7 @@ static void targetCh_AlignStereoDFT_fx( } FOR( i = 0; i < L_shift_adapt; i++ ) { - target_fx[i] = L_add( Mpy_32_32( alpha_fx, fadeInBuff_fx[i] ), Mpy_32_32( L_sub( ONE_IN_Q31, alpha_fx ), fadeOutBuff_fx[i] ) ); // qsynth + target_fx[i] = Madd_32_32( Mpy_32_32( alpha_fx, fadeInBuff_fx[i] ), L_sub( ONE_IN_Q31, alpha_fx ), fadeOutBuff_fx[i] ); // qsynth move32(); alpha_fx = L_add_sat( alpha_fx, winSlope_fx ); // Q31 diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 8d486df04..d6210dfc7 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -942,6 +942,12 @@ Word16 matrix_product_mant_exp_fx( Word16 *Zp_fx_e = out_e; Word16 row, col; Word16 x_idx, y_idx; + Word64 temp; + Word16 temp_e; + Word16 prod_e = add( X_fx_e, Y_fx_e ); + + Word16 max_exp = -31; + move16(); /* Processing */ test(); @@ -957,17 +963,28 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < colsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); + FOR( k = 0; k < rowsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); - y_idx = add( k, imult1616( j, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); + x_idx = k + i * rowsX; + y_idx = k + j * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e } + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; + move16(); + } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -987,17 +1004,27 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < rowsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); - y_idx = add( j, imult1616( k, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); + x_idx = i + k * rowsX; + y_idx = j + k * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e + } + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; + move16(); } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -1017,18 +1044,27 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < colsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); - y_idx = add( j, imult1616( k, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); + x_idx = k + i * rowsX; + y_idx = j + k * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e } - + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; + move16(); + } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -1049,17 +1085,26 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < rowsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); - y_idx = add( k, imult1616( j, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); + x_idx = i + k * rowsX; + y_idx = k + j * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e + } + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -1070,18 +1115,11 @@ Word16 matrix_product_mant_exp_fx( move16(); } Zp_fx = Z_fx; /*Q31 - Zp_fx_e*/ + Zp_fx_e = out_e; - Word16 max_exp = -31; move16(); - FOR( j = 0; j < row; ++j ) - { - FOR( i = 0; i < col; ++i ) - { - max_exp = s_max( max_exp, *Zp_fx_e ); - Zp_fx_e++; - } - } - Zp_fx_e = out_e; + + *Z_fx_e = max_exp; move16(); FOR( j = 0; j < row; ++j ) diff --git a/lib_com/options.h b/lib_com/options.h index ea2823ad7..1b2c15f87 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -152,5 +152,6 @@ #define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ #define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ -#endif #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ +#define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ +#endif diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index ae0474f3d..708527df5 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -237,6 +237,7 @@ void decoder_tcx_imdct_fx( Word16 q_a_itf = 15; Word16 x_e = sub( 31, q_x ); move16(); + Word16 shift_q = sub( q_x, q_win ); /*-----------------------------------------------------------------* * Initializations @@ -364,9 +365,10 @@ void decoder_tcx_imdct_fx( IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { + Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); - Copy32( x_fx, x_tmp_fx, s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ) ); // q_x - Copy32( x_fx, xn_bufFB_fx, s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ) ); // q_x + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x } ELSE IF( ( st->element_mode == EVS_MONO ) ) { @@ -374,8 +376,9 @@ void decoder_tcx_imdct_fx( } ELSE { - Copy32( x_fx, x_tmp_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x } IF( ( st->igf != 0 ) ) @@ -416,24 +419,29 @@ void decoder_tcx_imdct_fx( FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) { - xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], sub( q_x, q_win ) ) ); // q_x + xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x move16(); } + + Word16 ratio_e; + Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9) + ratio = shr( ratio, sub( 6, ratio_e ) ); + IF( st->element_mode != EVS_MONO ) { IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir_fx, q_win ); + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); } ELSE { IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir_fx, q_win ); + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); } FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) { - xn_bufFB_fx[ind] = L_shl( xn_bufFB_fx_16[ind], sub( q_x, q_win ) ); // Q_x + xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x } IF( ( bfi == 0 ) ) @@ -453,19 +461,22 @@ void decoder_tcx_imdct_fx( IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { - res_m = BASOP_Util_Divide1616_Scale( L_frame_glob, L_FRAME, &res_e ); - st->old_fpitch = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + // Using sat as a single instruction shifts and extracts + st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8 + move32(); } IF( GT_16( st->element_mode, EVS_MONO ) ) { res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); } ELSE { res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); } } @@ -475,7 +486,7 @@ void decoder_tcx_imdct_fx( Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) FOR( Word16 ind = 0; ind < overlapFB; ind++ ) { - hTcxDec->syn_OverlFB[ind] = (Word16) L_shr( xn_bufFB_fx[( ind + L_frameTCX )], sub( q_x, q_win ) ); // q_x + hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x } } @@ -483,7 +494,7 @@ void decoder_tcx_imdct_fx( Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) { - synthFB_fx[ind] = (Word16) L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], sub( q_x, q_win ) ); // q_x + synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x } diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 36246f739..f23c0b710 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -70,6 +70,7 @@ static void ivas_binRenderer_filterModule_fx( Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx; Word16 *Q_filterStates; const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx; + Word16 shift_q; FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -87,11 +88,6 @@ static void ivas_binRenderer_filterModule_fx( FOR( k = 0; k < numTimeSlots; k++ ) { Word64 outRealLeft_fx = 0, outRealRight_fx = 0, outImagLeft_fx = 0, outImagRight_fx = 0; - Word64 W_sub1 = 0, W_add1 = 0, W_sub2 = 0, W_add2 = 0; - move64(); - move64(); - move64(); - move64(); move64(); move64(); move64(); @@ -104,31 +100,32 @@ static void ivas_binRenderer_filterModule_fx( filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1]; move32(); - W_sub1 = W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] - W_add1 = W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] - W_sub2 = W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] - W_add2 = W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] + shift_q = sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ); + outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); + outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); + outRealRight_fx = W_shr( outRealRight_fx, shift_q ); + outImagRight_fx = W_shr( outImagRight_fx, shift_q ); - outRealLeft_fx = W_shr( outRealLeft_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); - outImagLeft_fx = W_shr( outImagLeft_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); - outRealRight_fx = W_shr( outRealRight_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); - outImagRight_fx = W_shr( outImagRight_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates[tapIdx - 1] - Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; - move16(); + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); + + outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); + outRealRight_fx = W_mac_32_32( outRealRight_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsRightImagPtr_fx[tapIdx] ); - /* Left Real and Imag */ - outRealLeft_fx = W_add( outRealLeft_fx, W_sub1 ); // Q29 + Q_filterStates[1] - outImagLeft_fx = W_add( outImagLeft_fx, W_add1 ); // Q29 + Q_filterStates[1] + outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); + outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); - /* Right Real and Imag*/ - outRealRight_fx = W_add( outRealRight_fx, W_sub2 ); // Q29 + Q_filterStates[1] - outImagRight_fx = W_add( outImagRight_fx, W_add2 ); // Q29 + Q_filterStates[1] + Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; + move16(); } + shift_q = add( sub( Q_filterStates[1], Q_curr ), 1 ); + outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); + outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); + outRealRight_fx = W_shr( outRealRight_fx, shift_q ); + outImagRight_fx = W_shr( outImagRight_fx, shift_q ); filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx]; move32(); @@ -141,27 +138,29 @@ static void ivas_binRenderer_filterModule_fx( /* Left Real and Imag */ // Q29 + Q_curr - out_Conv_CLDFB_real[0][k][bandIdx] = W_add( out_Conv_CLDFB_real[0][k][bandIdx], - W_add( W_shr( outRealLeft_fx, sub( Q_filterStates[1], Q_curr ) ), - W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsLeftRealPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsLeftImagPtr_fx[0] ) ) ) ); // Q29 + Word32 temp1 = L_shr( filterStatesLeftRealPtr_fx[0], 1 ); + Word32 temp2 = L_shr( filterStatesLeftImagPtr_fx[0], 1 ); + + + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, temp1, filterTapsLeftRealPtr_fx[0] ); + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( temp2 ), filterTapsLeftImagPtr_fx[0] ); + out_Conv_CLDFB_real[0][k][bandIdx] = W_add( out_Conv_CLDFB_real[0][k][bandIdx], outRealLeft_fx ); // Q29 move64(); - out_Conv_CLDFB_imag[0][k][bandIdx] = W_add( out_Conv_CLDFB_imag[0][k][bandIdx], - W_add( W_shr( outImagLeft_fx, sub( Q_filterStates[1], Q_curr ) ), - W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsLeftImagPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsLeftRealPtr_fx[0] ) ) ) ); // Q29 + + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp1, filterTapsLeftImagPtr_fx[0] ); + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp2, filterTapsLeftRealPtr_fx[0] ); + out_Conv_CLDFB_imag[0][k][bandIdx] = W_add( out_Conv_CLDFB_imag[0][k][bandIdx], outImagLeft_fx ); // Q29 move64(); /* Right Real and Imag */ - out_Conv_CLDFB_real[1][k][bandIdx] = W_add( out_Conv_CLDFB_real[1][k][bandIdx], - W_add( W_shr( outRealRight_fx, sub( Q_filterStates[1], Q_curr ) ), - W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsRightRealPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsRightImagPtr_fx[0] ) ) ) ); // Q29 + outRealRight_fx = W_mac_32_32( outRealRight_fx, temp1, filterTapsRightRealPtr_fx[0] ); + outRealRight_fx = W_mac_32_32( outRealRight_fx, L_negate( temp2 ), filterTapsRightImagPtr_fx[0] ); + out_Conv_CLDFB_real[1][k][bandIdx] = W_add( out_Conv_CLDFB_real[1][k][bandIdx], outRealRight_fx ); // Q29 move64(); - out_Conv_CLDFB_imag[1][k][bandIdx] = W_add( out_Conv_CLDFB_imag[1][k][bandIdx], - W_add( W_shr( outImagRight_fx, sub( Q_filterStates[1], Q_curr ) ), - W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsRightImagPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsRightRealPtr_fx[0] ) ) ) ); // Q29 + + outImagRight_fx = W_mac_32_32( outImagRight_fx, temp1, filterTapsRightImagPtr_fx[0] ); + outImagRight_fx = W_mac_32_32( outImagRight_fx, temp2, filterTapsRightRealPtr_fx[0] ); + out_Conv_CLDFB_imag[1][k][bandIdx] = W_add( out_Conv_CLDFB_imag[1][k][bandIdx], outImagRight_fx ); // Q29 move64(); } } diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index 5aa649ecd..fd039fe96 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -410,8 +410,6 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( const Word16 nchan_in /* i : number of input channels */ ) { - Word16 cx_init_e; - Word16 cx_init_imag_e; Word16 band_idx, ch_idx; Word16 brange[2]; Word32 real_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * MAX_TRANSPORT_CHANNELS]; @@ -421,10 +419,9 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( Word32 real_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word32 imag_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word16 output_e; - Word16 i, j, tmp1, tmp2, tmp1_e, tmp2_e, shift_imag, shift_real; - Word32 L_tmp; + Word16 tmp1_e, tmp2_e, shift_imag, shift_real; Word16 band, num_bands; - + Word16 cx_fx_norm, cx_imag_fx_norm; /* estimate input covariance */ /* Already stack here instead of in the process_subframe */ @@ -451,8 +448,11 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( move16(); imag_in_e = ImagBuffer_e; move16(); - shift_real = sub( L_norm_arr( real_in_buffer_fx, imult1616( num_bands, nchan_in ) ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); - shift_imag = sub( L_norm_arr( imag_in_buffer_fx, imult1616( num_bands, nchan_in ) ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); + + Word16 buf_len = imult1616( num_bands, nchan_in ); + + shift_real = sub( L_norm_arr( real_in_buffer_fx, buf_len ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); + shift_imag = sub( L_norm_arr( imag_in_buffer_fx, buf_len ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); real_in_e = sub( real_in_e, shift_real ); imag_in_e = sub( imag_in_e, shift_imag ); @@ -460,50 +460,23 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( output_e = s_max( real_in_e, imag_in_e ); - FOR( i = 0; i < num_bands * nchan_in; ++i ) - { - real_in_buffer_fx[i] = L_shr( real_in_buffer_fx[i], sub( output_e, RealBuffer_e ) ); // Q(31-output_e) - move32(); - imag_in_buffer_fx[i] = L_shr( imag_in_buffer_fx[i], sub( output_e, ImagBuffer_e ) ); // Q(31-output_e) - move32(); - } + scale_sig32( real_in_buffer_fx, buf_len, sub( RealBuffer_e, output_e ) ); + scale_sig32( imag_in_buffer_fx, buf_len, sub( ImagBuffer_e, output_e ) ); cmplx_matrix_square_fx( real_in_buffer_fx, imag_in_buffer_fx, num_bands, nchan_in, real_buffer_fx, imag_buffer_fx, output_e, &output_e ); v_add_fixed_me( cx_fx, *cx_e, real_buffer_fx, output_e, cx_fx, &tmp1_e, imult1616( nchan_in, nchan_in ), 1 ); v_add_fixed_me( cx_imag_fx, *cx_imag_e, imag_buffer_fx, output_e, cx_imag_fx, &tmp2_e, imult1616( nchan_in, nchan_in ), 1 ); - cx_init_e = tmp1_e; - move16(); - cx_init_imag_e = tmp2_e; - move16(); - // normalizing both the matrices to a common exponent for a better precision - tmp1 = 0; - move16(); - tmp2 = 0; - move16(); - - FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) - { - L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e, 0, 0, &tmp1_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e, 0, 0, &tmp2_e ); - tmp1 = s_max( tmp1, tmp1_e ); - tmp2 = s_max( tmp2, tmp2_e ); - } + cx_fx_norm = L_norm_arr( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + cx_imag_fx_norm = L_norm_arr( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) - { - L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e, 0, 0, &tmp1_e ); - cx_fx[j] = L_shr( L_tmp, sub( tmp1, tmp1_e ) ); // Q(31-tmp1) - move32(); - L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e, 0, 0, &tmp2_e ); - cx_imag_fx[j] = L_shr( L_tmp, sub( tmp2, tmp2_e ) ); // Q(31-tmp2) - move32(); - } + scale_sig32( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS, cx_fx_norm ); + scale_sig32( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS, cx_imag_fx_norm ); - *cx_e = tmp1; + *cx_e = sub( tmp1_e, cx_fx_norm ); move16(); - *cx_imag_e = tmp2; + *cx_imag_e = sub( tmp2_e, cx_imag_fx_norm ); move16(); return; diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 942a2b5b0..c8778f99c 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -912,13 +912,55 @@ static void ApplyRotation_fx( ) { Word16 ch; - Word16 temp_exp; *d = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), add( c_e, x11_e ), Mpy_32_32( s, x12 ), add( s_e, x12_e ), d_e ); /* exp(d_e) */ move32(); *g = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), add( c_e, x12_e ), Mpy_32_32( L_negate( s ), x11 ), add( s_e, x11_e ), g_e ); /* exp(g_e) */ move32(); +#ifdef SVD_WMOPS_OPT + Word16 c_q = sub( 31, c_e ); + Word16 s_q = sub( 31, s_e ); + Word32 op1, op2; + Word16 op_e; + + // Bring c and s to same Q + IF( GT_16( c_q, s_q ) ) + { + op1 = L_shr( c, sub( c_q, s_q ) ); + op2 = s; + move32(); + op_e = s_q; + move16(); + } + ELSE + { + op1 = c; + move32(); + op2 = L_shr( s, sub( s_q, c_q ) ); + op_e = c_q; + move16(); + } + op_e = add( op_e, 1 ); // 64 bit mac -> +1 + + FOR( ch = 0; ch < nChannels; ch++ ) + { + x11 = singularVector[ch][currentIndex2]; + move32(); + x12 = singularVector[ch][currentIndex1]; + move32(); + + Word64 temp = W_mac_32_32( W_mult_32_32( op1, x11 ), op2, x12 ); // Q(singularVector) + op_e + temp = W_shr( temp, op_e ); // Q(singularVector) + singularVector[ch][currentIndex2] = W_sat_l( temp ); // Q(singularVector) + move32(); + + temp = W_mac_32_32( W_mult_32_32( op1, x12 ), L_negate( op2 ), x11 ); // Q(singularVector) + op_e + temp = W_shr( temp, op_e ); // Q(singularVector) + singularVector[ch][currentIndex1] = W_sat_l( temp ); // Q(singularVector) + move32(); + } +#else #ifndef FIX_MINOR_SVD_WMOPS_MR1010X FOR( ch = 0; ch < nChannels; ch++ ) { @@ -952,6 +994,7 @@ static void ApplyRotation_fx( move32(); } +#endif #endif return; @@ -1605,26 +1648,43 @@ static void singularVectorsAccumulationLeft_fx( t_ii = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxWithSign_fx( t_ii ), &temp_exp ); /* exp(1 + (temp_exp + tii_e)) */ t_ii_e = add( 1, sub( temp_exp, t_ii_e ) ); #endif + Word16 tempe; + Word32 temp = BASOP_Util_Divide3232_Scale_cadence( t_ii, maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &tempe ); + tempe = add( tempe, sub( t_ii_e, singularVectors_Left_e[nCh][nCh] ) ); // fprintf( fp, "%e\n", me2f( t_ii, t_ii_e ) ); FOR( iCh = nCh + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { - norm_y = 0; - move32(); - norm_y_e = 0; + Word64 acc = 0; + move64(); + Word64 prod[16]; + Word16 prod_e[16]; + Word16 max_e = -31; move16(); FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ { #ifndef FIX_1010_OPT_SINGLE_RESCALE norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ), add( sing_exp2[k][nCh], sing_exp2[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ #else - norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ), add( singularVectors_Left_e[k][nCh], singularVectors_Left_e[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ + prod[k] = W_mult0_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ); + prod_e[k] = add( singularVectors_Left_e[k][nCh], singularVectors_Left_e[k][iCh] ); + max_e = s_max( max_e, prod_e[k] ); #endif } - t_jj = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_32( t_ii, norm_y ), maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &temp_exp ); // t_ii_e+norm_y_e-*singularVectors_e, + + FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ + { + acc = W_add( acc, W_shr( prod[k], sub( max_e, prod_e[k] ) ) ); + } + Word16 acc_e = W_norm( acc ); + acc = W_shl( acc, acc_e ); + + norm_y = W_extract_h( acc ); + norm_y_e = add( sub( max_e, acc_e ), 1 ); + t_jj = Mpy_32_32( temp, norm_y ); #ifndef FIX_1010_OPT_SINGLE_RESCALE t_jj_e = add( temp_exp, sub( add( t_ii_e, norm_y_e ), sing_exp2[nCh][nCh] ) ); #else - t_jj_e = add( temp_exp, sub( add( t_ii_e, norm_y_e ), singularVectors_Left_e[nCh][nCh] ) ); + t_jj_e = add( tempe, norm_y_e ); #endif FOR( k = nCh; k < nChannelsL; k++ ) /* nChannelsL */ { diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index c50d690c5..1788536e4 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -409,7 +409,7 @@ void ivas_dirac_dec_decorr_process_fx( HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state ) { - Word16 ch_idx, k, l, idx_in_out, max_band_decorr; + Word16 ch_idx, k, l, max_band_decorr; Word16 split_bands_idx, band_idx, decorr_buffer_len, time_idx; Word16 offset, idx_filter, incr_aux; Word16 k_1, k_2, num_bands, filter_length, pre_delay, decorr_buffer_step; @@ -506,22 +506,24 @@ void ivas_dirac_dec_decorr_process_fx( set32_fx( onset_filter_fx, ONE_IN_Q31, imult1616( num_protos_diff, num_freq_bands ) ); Word16 q_temp = s_min( q_onset_dec, q_aux_buffer ); + Word16 shift_q = sub( q_onset_dec, q_temp ); - IF( NE_16( q_temp, q_onset_dec ) ) + IF( shift_q != 0 ) { - FOR( Word16 i = 0; i < imult1616( num_protos_diff, max_band_decorr_temp ); i++ ) + FOR( Word16 i = 0; i < num_protos_diff * max_band_decorr_temp; i++ ) { - h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i], sub( q_onset_dec, q_temp ) ); // q_temp - h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i], sub( q_onset_dec, q_temp ) ); // q_temp + h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i], shift_q ); // q_temp + h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i], shift_q ); // q_temp move32(); move32(); } } - IF( NE_16( q_temp, q_aux_buffer ) ) + shift_q = sub( q_aux_buffer, q_temp ); + IF( shift_q != 0 ) { - FOR( Word16 i = 0; i < shl( imult1616( num_protos_diff, max_band_decorr_temp ), 1 ); i++ ) + FOR( Word16 i = 0; i < 2 * num_protos_diff * max_band_decorr_temp; i++ ) { - aux_buffer_fx[i] = L_shr( aux_buffer_fx[i], sub( q_aux_buffer, q_temp ) ); // q_temp + aux_buffer_fx[i] = L_shr( aux_buffer_fx[i], shift_q ); // q_temp move32(); } } @@ -566,9 +568,9 @@ void ivas_dirac_dec_decorr_process_fx( /* final phase rotation */ FOR( k = 0; k < max_band_decorr; k++ ) { - *p_frame_dec_fx = L_sub( Mpy_32_16_1( ( *decorr_buffer_fx ), ( *phase_coeff_real_fx ) ), Mpy_32_16_1( ( *( decorr_buffer_fx + 1 ) ), ( *phase_coeff_imag_fx ) ) ); // sub( q_decorr_buf, 1 ) + *p_frame_dec_fx = Msub_32_16( Mpy_32_16_1( *decorr_buffer_fx, ( *phase_coeff_real_fx ) ), *( decorr_buffer_fx + 1 ), ( *phase_coeff_imag_fx ) ); // sub( q_decorr_buf, 1 ) p_frame_dec_fx++; - *p_frame_dec_fx = L_add( Mpy_32_16_1( ( *decorr_buffer_fx ), ( *phase_coeff_imag_fx ) ), Mpy_32_16_1( ( *( decorr_buffer_fx + 1 ) ), ( *phase_coeff_real_fx ) ) ); // sub( q_decorr_buf, 1 ) + *p_frame_dec_fx = Madd_32_16( Mpy_32_16_1( *decorr_buffer_fx, ( *phase_coeff_imag_fx ) ), ( *( decorr_buffer_fx + 1 ) ), ( *phase_coeff_real_fx ) ); // sub( q_decorr_buf, 1 ) p_frame_dec_fx++; phase_coeff_imag_fx++; phase_coeff_real_fx++; @@ -620,8 +622,8 @@ void ivas_dirac_dec_decorr_process_fx( #endif q_shift = getScaleFactor32( aux_buffer_fx, imult1616( imult1616( 2, num_protos_dir ), max_band_decorr_temp ) ); - - FOR( Word16 j = 0; j < shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ); j++ ) + Word16 buf_len = shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ); + FOR( Word16 j = 0; j < buf_len; j++ ) { aux_buffer_fx[j] = L_shl( aux_buffer_fx[j], q_shift ); // add( q_aux_buffer, q_shift ) move32(); @@ -674,8 +676,9 @@ void ivas_dirac_dec_decorr_process_fx( filter_coeff_num_real_fx = &h_freq_domain_decorr_ap_params->filter_coeff_num_real_fx[idx_filter]; // Q12 filter_coeff_den_real_fx = &h_freq_domain_decorr_ap_params->filter_coeff_den_real_fx[idx_filter]; // Q12 decorr_buffer_start_ptr_fx = &h_freq_domain_decorr_ap_state->decorr_buffer_fx[2 * ( ch_idx * max_band_decorr + band_idx )]; - input_real_fx = aux_buffer_fx[shl( add( imult1616( proto_index_dir[ch_idx], max_band_decorr ), band_idx ), 1 )]; // q_aux - input_imag_fx = aux_buffer_fx[add( shl( add( imult1616( proto_index_dir[ch_idx], max_band_decorr ), band_idx ), 1 ), 1 )]; // q_aux + Word16 idx = shl( add( imult1616( proto_index_dir[ch_idx], max_band_decorr ), band_idx ), 1 ); + input_real_fx = aux_buffer_fx[idx]; // q_aux + input_imag_fx = aux_buffer_fx[idx + 1]; // q_aux /* MA part of filter impulse response */ FOR( l = 0; l < filter_length; l++ ) @@ -766,14 +769,15 @@ void ivas_dirac_dec_decorr_process_fx( #ifdef MSAN_FIX q_shift = Q31; move16(); + offset = shl( max_band_decorr, 1 ); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { q_shift = s_min( q_shift, - L_norm_arr( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ) ) ); + L_norm_arr( &frame_dec_fx[2 * ch_idx * num_freq_bands], offset ) ); } FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - Scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); + scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], offset, q_shift ); } #else q_shift = L_norm_arr( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels ); @@ -784,13 +788,14 @@ void ivas_dirac_dec_decorr_process_fx( IF( h_freq_domain_decorr_ap_params->use_ducker ) { + Word16 len1 = shl( imult1616( max_band_decorr, num_protos_dir ), 1 ); /* compute direct power w/o onsets for the energy ratio, signal is still in the aux buffer */ - v_mult_fixed( aux_buffer_fx, aux_buffer_fx, aux_buffer_fx, shl( imult1616( max_band_decorr, num_protos_dir ), 1 ) ); // 2 *q_aux -31 + v_mult_fixed( aux_buffer_fx, aux_buffer_fx, aux_buffer_fx, len1 ); // 2 *q_aux -31 - q_aux_buffer = sub( imult1616( 2, q_aux_buffer ), 31 ); + q_aux_buffer = sub( shl( q_aux_buffer, 1 ), 31 ); // if this scaling is eliminated overflow is happening fot v_add_inc_fix - q_shift = sub( L_norm_arr( aux_buffer_fx, shl( imult1616( num_protos_dir, max_band_decorr ), 1 ) ), find_guarded_bits_fx( 2 ) ); + q_shift = sub( L_norm_arr( aux_buffer_fx, len1 ), 1 /*find_guarded_bits_fx( 2 )*/ ); Scale_sig32( aux_buffer_fx, shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ), q_shift ); q_aux_buffer = add( q_aux_buffer, q_shift ); @@ -847,18 +852,18 @@ void ivas_dirac_dec_decorr_process_fx( } norm = W_norm( min64 ); #endif - - FOR( Word16 i = 0; i < shl( imult1616( num_channels, max_band_decorr ), 1 ); i++ ) + norm = sub( norm, 1 /*find_guarded_bits_fx( 2 )*/ ); + FOR( Word16 i = 0; i < 2 * num_channels * max_band_decorr; i++ ) { - aux_buffer_fx[i] = W_extract_h( W_shl( aux_64[i], sub( norm, find_guarded_bits_fx( 2 ) ) ) ); + aux_buffer_fx[i] = W_extract_h( W_shl( aux_64[i], norm ) ); move32(); } - q_aux_buffer = add( imult1616( 2, q_frame_f ), sub( sub( norm, 1 ), 32 ) ); + q_aux_buffer = add( shl( q_frame_f, 1 ), sub( norm, 32 ) ); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - v_add_inc_fx( &aux_buffer_fx[shl( imult1616( ch_idx, max_band_decorr ), 1 )], 2, &aux_buffer_fx[add( shl( imult1616( ch_idx, max_band_decorr ), 1 ), 1 )], 2, &aux_buffer_fx[imult1616( ch_idx, max_band_decorr )], 1, max_band_decorr ); + v_add_inc_fx( &aux_buffer_fx[2 * ch_idx * max_band_decorr], 2, &aux_buffer_fx[2 * ch_idx * max_band_decorr + 1], 2, &aux_buffer_fx[ch_idx * max_band_decorr], 1, max_band_decorr ); } /* smooth energies */ @@ -959,7 +964,7 @@ void ivas_dirac_dec_decorr_process_fx( FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { q_shift = s_min( q_shift, - sub( L_norm_arr( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ) ), + sub( L_norm_arr( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ) ), Q2 ) ); } FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -974,7 +979,7 @@ void ivas_dirac_dec_decorr_process_fx( FOR( ch_idx = 0; ch_idx < num_channels; ch_idx++ ) { - Word32 *frame_dec_fx_ptr = &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )]; + Word32 *frame_dec_fx_ptr = &frame_dec_fx[2 * ch_idx * num_freq_bands]; Word16 cur_proto_index = imult1616( proto_index_dir[ch_idx], max_band_decorr ); Word16 cur_reverb_index = imult1616( ch_idx, max_band_decorr ); Word32 *reverb_energy_smooth_ptr = &h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx[cur_reverb_index]; // q_aux @@ -1020,22 +1025,18 @@ void ivas_dirac_dec_decorr_process_fx( e_duck_gain = add( e_duck_gain, sub( e_direct_energy_smooth, add( e_reverb_energy_smooth, 1 ) ) ); duck_gain = Sqrt16( duck_gain, &e_duck_gain ); - Word16 comp_flag = BASOP_Util_Cmp_Mant32Exp( duck_gain, e_duck_gain, 16384, 2 ); - IF( EQ_16( comp_flag, 1 ) ) - { - duck_gain = 16384; // 2inQ13 - move16(); - } - ELSE + /* if ( duck_gain > 2.0f ) { - duck_gain = shl( duck_gain, sub( e_duck_gain, 2 ) ); // Q13 - } + duck_gain = 2.0f; + } */ + duck_gain = shl_sat( duck_gain, sub( e_duck_gain, 1 ) ); // Q14 + #ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 2 ); // q_frame_dec frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )], duck_gain ), 2 ); // q_frame_dec #else - frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 2 ); // q_frame_dec - frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 2 ); // q_frame_dec + frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_dec + frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 1 ); // q_frame_dec #endif move32(); move32(); @@ -1055,7 +1056,7 @@ void ivas_dirac_dec_decorr_process_fx( Word16 sf = MAX_16; FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - sf = s_min( sf, getScaleFactor32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ) ) ); + sf = s_min( sf, getScaleFactor32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ) ) ); } sf = s_min( sub( sf, 1 ), q_shift ); q_if_local = sub( q_shift, sf ); @@ -1065,7 +1066,7 @@ void ivas_dirac_dec_decorr_process_fx( #ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); + scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } #else Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q @@ -1078,7 +1079,7 @@ void ivas_dirac_dec_decorr_process_fx( #ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); + scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } #else Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q @@ -1098,24 +1099,22 @@ void ivas_dirac_dec_decorr_process_fx( FOR( k = 0; k < max_band_decorr; ++k ) { - aux_buffer_fx[2 * k] = Mpy_32_32( L_shr_r( input_frame_fx[add( shl( offset, 1 ), shl( k, 1 ) )], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[add( offset, k )] ) ); - aux_buffer_fx[add( shl( k, 1 ), 1 )] = Mpy_32_32( L_shr_r( input_frame_fx[add( add( shl( offset, 1 ), shl( k, 1 ) ), 1 )], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[add( offset, k )] ) ); // q_frame_f + aux_buffer_fx[2 * k] = Mpy_32_32( L_shr_r( input_frame_fx[2 * ( offset + k )], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[offset + k] ) ); + aux_buffer_fx[add( shl( k, 1 ), 1 )] = Mpy_32_32( L_shr_r( input_frame_fx[2 * ( offset + k ) + 1], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[offset + k] ) ); // q_frame_f move32(); move32(); } - v_add_fx( &frame_dec_fx[imult1616( ch_idx, shl( num_freq_bands, 1 ) )], aux_buffer_fx, &frame_dec_fx[imult1616( ch_idx, shl( num_freq_bands, 1 ) )], shl( max_band_decorr, 1 ) ); + v_add_fx( &frame_dec_fx[2 * ch_idx * num_freq_bands], aux_buffer_fx, &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ) ); } } /* avoid decorrelation above maximum frequency -> set to zero the remaining frequencies*/ + Word16 val = shl( sub( num_freq_bands, h_freq_domain_decorr_ap_params->max_band_decorr ), 1 ); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - /* calc output indices */ - idx_in_out = shl( ( add( imult1616( ch_idx, num_freq_bands ), h_freq_domain_decorr_ap_params->max_band_decorr ) ), 1 ); - /* copy to output signal */ - set32_fx( &frame_dec_fx[idx_in_out], 0, shl( sub( num_freq_bands, h_freq_domain_decorr_ap_params->max_band_decorr ), 1 ) ); + set32_fx( &frame_dec_fx[2 * ( ch_idx * num_freq_bands + h_freq_domain_decorr_ap_params->max_band_decorr )], 0, val ); } *q_frame_dec = q_frame_f; move16(); -- GitLab From 560e0abc7a9c7336f3384606170f878b6993d621 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Feb 2025 14:40:39 +0530 Subject: [PATCH 0069/1221] Fix for 3GPP issue 1263: Fixed point renderer crashed when rendering ISM stream to FOA at 16kHz Link #1263 --- lib_rend/lib_rend.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f230cca25..9cab74182 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4564,40 +4564,58 @@ static void renderBufferChannelLerp_fx( { i = 0; Word32 tmp = Q31_BY_SUB_FRAME_240; + Word32 tmp1 = 239; + move32(); move32(); move32(); SWITCH( outAudio.config.numSamplesPerChannel ) { case NUM_SAMPLES_960: tmp = Q31_BY_NUM_SAMPLES_960; + tmp1 = 959; + move32(); move32(); BREAK; case NUM_SAMPLES_720: tmp = Q31_BY_NUM_SAMPLES_720; + tmp1 = 719; + move32(); move32(); BREAK; case NUM_SAMPLES_320: tmp = Q31_BY_NUM_SAMPLES_320; + tmp1 = 319; + move32(); move32(); BREAK; case NUM_SAMPLES_160: tmp = Q31_BY_NUM_SAMPLES_160; + tmp1 = 159; + move32(); move32(); BREAK; case L_SUBFRAME_48k: tmp = Q31_BY_SUB_FRAME_240; + tmp1 = 239; + move32(); move32(); BREAK; case L_SUBFRAME_32k: tmp = Q31_BY_SUB_FRAME_180; + tmp1 = 179; + move32(); move32(); BREAK; case L_SUBFRAME_16k: tmp = Q31_BY_SUB_FRAME_80; + tmp1 = 79; + move32(); move32(); BREAK; case L_SUBFRAME_8k: tmp = Q31_BY_SUB_FRAME_40; + tmp1 = 39; + move32(); move32(); BREAK; default: @@ -4606,7 +4624,15 @@ static void renderBufferChannelLerp_fx( /* Otherwise use weighted average between previous and current gain */ DO { - fadeIn = UL_Mpy_32_32( i, tmp ); + IF( EQ_32( i, tmp1 ) ) + { + fadeIn = ONE_IN_Q31; + move32(); + } + ELSE + { + fadeIn = UL_Mpy_32_32( i, tmp ); + } fadeOut = L_sub( ONE_IN_Q31, fadeIn ); *outSmpl = L_add( Mpy_32_32( L_add( Mpy_32_32( fadeIn, currentGain ), Mpy_32_32( fadeOut, previousGain ) ), ( *inSmpl ) ), *outSmpl ); -- GitLab From bbbeb024798e9fa79153a977b1d601fd066ef92f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 7 Feb 2025 10:52:28 +0100 Subject: [PATCH 0070/1221] changes for split-by-level complexity graphs --- .gitlab-ci.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0f1c85764..9f9f96e4c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1253,8 +1253,25 @@ voip-be-on-merge-request: - unzip artifacts.zip || true # this may fail on first run, when there are no artifacts there and the zip file is actually just "404"-html - ls - public_dir="$CI_JOB_NAME-public" + # if is needed to catch case when no artifact is there (first run), similarly as above - - if [[ -d $public_dir ]]; then mv $public_dir/* wmops/; fi + - if [[ -d $public_dir ]]; then + - mv $public_dir/* wmops/ + # check here if we have the split-by-levels files present - if not, fake them up with the existing global one + # this is needed for the first run with split graphs on a branch where the global version did run previously + # NOTE: checking only for level_1 file here as this should already be sufficient + # NOTE2: also not chechking for RAM for same reason + - wmops_all_global="wmops/log_wmops_all.txt" + - ram_all_global="wmops/log_ram_all.txt" + - if [ -f "${wmops_all_global}" ] && [ ! -f "wmops/log_wmops_all_level_1.txt" ]; then + - declare -a suffixes=("level_1" "level_2" "level_3" "rate_sw") + - for suffix in "${suffixes[@]}"; do + - cp ${wmops_all_global} wmops/log_wmops_all_${suffix}.txt + - cp ${ram_all_global} wmops/log_ram_all_${suffix}.txt + - done + - fi + - fi + - ls wmops - rm artifacts.zip - rm -rf $public_dir @@ -1271,7 +1288,7 @@ voip-be-on-merge-request: &complexity-measurements-prepare-artifacts # prepare artifacts -> move to public directory - public_dir="$CI_JOB_NAME-public" - mkdir $public_dir - - mv -f wmops/log_*_all.txt ./*.js ${public_dir}/ + - mv -f wmops/log_*_all*.txt ./*.js ${public_dir}/ # move logfiles for links - mkdir $public_dir/logs # first move logs -- GitLab From fa370ae40eeef01e63cb90b216777eaf6c42d843 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 7 Feb 2025 10:53:43 +0100 Subject: [PATCH 0071/1221] fix BASOP issue 1265, FLP issue 1273: fix counter overflow in ISM metadata encoder; under NONBE_1273_ISM_METADATA_COUNTER --- lib_com/options.h | 1 + lib_enc/ivas_ism_metadata_enc.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index fa1fd8f4e..e17fb511c 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -140,6 +140,7 @@ #define FIX_ISSUE_1230 /* Ittiam: Fix for issue 1230: Basop Enc audible differences and distortion @16kbps */ #define NONBE_1211_DTX_BR_SWITCHING /* VA: port float issue 1211: fix crash in MASA DTX bitrate switching */ #define FIX_1189_GSC_IVAS_OMASA /* VA: Fix for issue 1189: Bitstream desynchornization due to reading/writing of the GSC_IVAS_mode parameter */ +#define NONBE_1273_ISM_METADATA_COUNTER /* VA: BASOP issue 1265, FLP issue 1273: fix counter overflow in ISM metadata encoder */ #define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF /* FhG: fix for issue 1101: complexity of spar dec upmixer */ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ #define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS /* FhG: Defines 1.0f-weight variables, uses Madd operation instead of L_add_sat */ diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 9bcc34dd8..32138faba 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -317,7 +317,10 @@ ivas_error ivas_ism_metadata_enc_fx( } ELSE IF( EQ_16( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ) ) { - +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; + move16(); +#endif lowrate_metadata_flag[ch] = 1; move16(); hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; @@ -639,6 +642,10 @@ ivas_error ivas_ism_metadata_enc_fx( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); + move16(); +#endif } ELSE { @@ -806,6 +813,10 @@ ivas_error ivas_ism_metadata_enc_fx( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); + move16(); +#endif } ELSE { -- GitLab From 60930d82c600d56d2703b1576f1dd809ba834986 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Feb 2025 16:06:53 +0530 Subject: [PATCH 0072/1221] Bug fixes for MC and SBA formats [x] Remove wrong q-updation for bin_e in stereo_tcx_core_enc [x] Few corrections for SBA format files --- lib_enc/core_enc_init.c | 4 ++-- lib_enc/ivas_core_pre_proc.c | 2 ++ lib_enc/ivas_core_pre_proc_front.c | 7 ++++++- lib_enc/ivas_tcx_core_enc.c | 6 +----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index d82d1b7ff..43e93f27c 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -528,8 +528,8 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - - /*Resamp buffers needed only for ACELP*/ + st->exp_buf_wspeech_enc = st->exp_old_wsp; + move16(); /*Resamp buffers needed only for ACELP*/ IF( EQ_16( st->L_frame, L_FRAME16k ) ) { lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 848e26ce3..3444ca091 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -571,6 +571,8 @@ ivas_error pre_proc_ivas_fx( st->q_inp = -1; move16(); Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ + st->mem_wsp_enc = shl( st->mem_wsp_enc,sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k + move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); Word16 Q_old_inp_128k = *Q_new; diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 9e09f93f6..57a6222c1 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1643,6 +1643,8 @@ ivas_error pre_proc_front_ivas_fx( st->exp_mem_preemph_enc = sub( Q15, Q_old_inp_16k ); move16(); Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ + st->mem_wsp_enc = shl( st->mem_wsp_enc,sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); //Q_old_inp_16k + move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); /* Q15 - Q_old_inp_16k */ @@ -1666,7 +1668,7 @@ ivas_error pre_proc_front_ivas_fx( *epsP_fx_q = add( Q_r[0], 1 ); move16(); - st->mem_wsp_enc = shr_r( st->mem_wsp_enc, *Q_new ); // Q_new - 1 -> Q-1 + st->mem_wsp_enc = shl( st->mem_wsp_enc,sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); //Q0 move16(); *Q_new = add( *Q_new, Q_to_be_looked_into ); // actual Q_new @@ -1676,6 +1678,9 @@ ivas_error pre_proc_front_ivas_fx( Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( 0, sub( Q15, st->exp_buf_speech_enc ) ) ); /* Q0 */ st->exp_buf_speech_enc = Q15; move16(); + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q0 */ + st->exp_buf_wspeech_enc = Q15; + move16(); smc_dec = ivas_acelp_tcx20_switching_fx( st, st->speech_enc, 0, st->wspeech_enc, non_staX_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, flag_16k_smc ); /* Q0 */ } ELSE diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index f993c8e28..0680fc795 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -727,10 +727,6 @@ void stereo_tcx_core_enc( move16(); } } - st->q_Bin_E = Q_new + Q_SCALE - 2; - move16(); - st->q_Bin_E_old = Q_new + Q_SCALE - 2; - move16(); Scale_sig( st->synth, st->L_frame, -Q_new ); IF( st->tcxonly == 0 ) { @@ -875,7 +871,7 @@ Word16 ivas_acelp_tcx20_switching_fx( #ifdef MSAN_FIX FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length / 2; i++ ) { - window_fx[st->hTcxCfg->tcx_mdct_window_length / 2 - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 + window_fx[st->hTcxCfg->tcx_mdct_window_length - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 move16(); window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 move16(); -- GitLab From 64a68a5359ee8cd84ea264f54a4452ad2fcef734 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Feb 2025 16:21:42 +0530 Subject: [PATCH 0073/1221] Clang formatting changes --- lib_enc/ivas_core_pre_proc.c | 2 +- lib_enc/ivas_core_pre_proc_front.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 3444ca091..541cc620c 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -571,7 +571,7 @@ ivas_error pre_proc_ivas_fx( st->q_inp = -1; move16(); Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ - st->mem_wsp_enc = shl( st->mem_wsp_enc,sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k + st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 57a6222c1..fd9b79617 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1643,7 +1643,7 @@ ivas_error pre_proc_front_ivas_fx( st->exp_mem_preemph_enc = sub( Q15, Q_old_inp_16k ); move16(); Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ - st->mem_wsp_enc = shl( st->mem_wsp_enc,sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); //Q_old_inp_16k + st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); @@ -1668,7 +1668,7 @@ ivas_error pre_proc_front_ivas_fx( *epsP_fx_q = add( Q_r[0], 1 ); move16(); - st->mem_wsp_enc = shl( st->mem_wsp_enc,sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); //Q0 + st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q0 move16(); *Q_new = add( *Q_new, Q_to_be_looked_into ); // actual Q_new -- GitLab From d9be453d24945793846bf52d35d2efe197a8ca17 Mon Sep 17 00:00:00 2001 From: malenov Date: Fri, 7 Feb 2025 13:31:44 +0100 Subject: [PATCH 0074/1221] dumping core.loc2, coder_type and ism_imp --- lib_enc/ivas_core_pre_proc_front.c | 14 +++++++++++++ lib_enc/ivas_decision_matrix_enc.c | 33 ++++++++++++++++++++---------- lib_enc/ivas_ism_enc.c | 19 +++++++++++++++++ lib_enc/ivas_ism_metadata_enc.c | 11 ++++++++++ 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 74af17216..c06c437ff 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1456,6 +1456,20 @@ ivas_error pre_proc_front_ivas_fx( Copy_Scale_sig_16_32( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->coder_type, sizeof( int16_t ), 1, fname( st->force_dir, "force_coder_type.enf", -1, -1, -1 ) ); + dbgread( &st->coder_type_raw, sizeof( int16_t ), 1, fname( st->force_dir, "force_coder_type_raw.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, 1, "res/force_coder_type.enf" ); + dbgwrite( &st->coder_type_raw, sizeof( int16_t ), 1, 1, "res/force_coder_type_raw.enf" ); + } +#endif + + /*-----------------------------------------------------------------* * channel aware mode configuration * *-----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index 08ce3cd21..e668641dc 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -207,6 +207,17 @@ void ivas_decision_matrix_enc_fx( test(); test(); +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core_loc1.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core_loc1.enf" ); + } +#endif + /* do not allow TD stereo ACELP core -> DFT stereo TCX core switching as it is on the WC complexity path */ if ( ( ( st->last_core == ACELP_CORE && EQ_16( last_element_mode, IVAS_CPE_TD ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) ) || ( EQ_16( st->tdm_LRTD_flag, 1 ) && LE_32( st->total_brate, IVAS_16k4 ) ) ) && EQ_16( st->core, TCX_20_CORE ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) /* Override TCX in case of LRTD && primary channel has low bitrate*/ { @@ -255,17 +266,6 @@ void ivas_decision_matrix_enc_fx( } #endif -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core.enf" ); - } -#endif - /* TCX not available at low bitrates -> replace it by GSC */ test(); IF( EQ_16( st->core, TCX_20_CORE ) && LT_32( st->total_brate, STEREO_TCX_MIN_RATE ) ) @@ -305,6 +305,17 @@ void ivas_decision_matrix_enc_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core_loc2.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core_loc2.enf" ); + } +#endif + /*---------------------------------------------------------------------* * Select ACELP and GSC extension layer *---------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 2fef5a1cb..70b049ba8 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -228,6 +228,11 @@ ivas_error ivas_ism_enc_fx( st->bits_frame_nominal = sub( extract_l( Mpy_32_32( hSCE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ), ISM_NB_BITS_METADATA_NOMINAL ); move16(); + +#ifdef DEBUG_MODE_INFO + dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, st->id_element, ENC ) ); +#endif + /*----------------------------------------------------------------* * Front Pre-processing *----------------------------------------------------------------*/ @@ -506,6 +511,20 @@ ivas_error ivas_ism_enc_fx( } } +#ifdef DEBUG_MODE_INFO + for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ ) + { + float tmpF; + int16_t id; + + st = st_ivas->hSCE[sce_id]->hCoreCoder[0]; + id = st->id_element; + + tmpF = st->element_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "element_brate", 0, id, ENC ) ); + } +#endif + pop_wmops(); return error; diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 9bcc34dd8..ef410b59c 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -338,6 +338,17 @@ ivas_error ivas_ism_metadata_enc_fx( } } +#ifdef DEBUG_FORCE_DIR + if ( hSCE[0]->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( ism_imp, sizeof( int16_t ), nchan_ism, fname( hSCE[0]->hCoreCoder[0]->force_dir, "force_ism_imp.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( ism_imp, sizeof( int16_t ), nchan_ism, 1, "res/force_ism_imp.enf" ); + } +#endif + /*----------------------------------------------------------------* * Write ISM common signaling *----------------------------------------------------------------*/ -- GitLab From 997665709a585ed6ca6380b16e147539c0ac7a0f Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Fri, 7 Feb 2025 08:29:08 -0500 Subject: [PATCH 0075/1221] fix saturation missing in EVS counter --- lib_enc/acelp_core_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 6449367c8..b9310dead 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -156,7 +156,7 @@ ivas_error acelp_core_enc_fx( st_fx->Nb_ACELP_frames = 0; move16(); } - st_fx->Nb_ACELP_frames = add( st_fx->Nb_ACELP_frames, 1 ); // Q0 + st_fx->Nb_ACELP_frames = add_sat( st_fx->Nb_ACELP_frames, 1 ); // Q0 move16(); int_fs_fx = INT_FS_16k_FX; @@ -967,7 +967,7 @@ ivas_error acelp_core_enc_ivas_fx( st->Nb_ACELP_frames = 0; move16(); } - st->Nb_ACELP_frames = add( st->Nb_ACELP_frames, 1 ); + st->Nb_ACELP_frames = add_sat( st->Nb_ACELP_frames, 1 ); move16(); IF( EQ_16( st->L_frame, L_FRAME ) ) -- GitLab From b0fc3fcdff86c8466d66d60f2cbad2121a0ed7bd Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Fri, 7 Feb 2025 10:55:55 -0500 Subject: [PATCH 0076/1221] fix saturation missing in EVS counter --- lib_enc/energy_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/energy_fx.c b/lib_enc/energy_fx.c index 6d81eb82a..7dc96a4e3 100644 --- a/lib_enc/energy_fx.c +++ b/lib_enc/energy_fx.c @@ -184,7 +184,7 @@ static void update_sb_bg_energy( Word32 sb_bg_energy_ti, tmp; Word16 tmpQ, i; - *tbg_energy_count = add( *tbg_energy_count, 1 ); /* Q0 */ + *tbg_energy_count = add_sat( *tbg_energy_count, 1 ); /* Q0 */ move16(); tmpQ = add( tmp_Q_add, frame_sb_energy_scale ); -- GitLab From 43633d492c8a1b5d9cb793788e09567f393f896b Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 9 Feb 2025 20:46:21 +0100 Subject: [PATCH 0077/1221] fix instrumentation --- lib_com/ivas_dirac_com.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index e07d36b1e..2704c1f08 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -975,13 +975,13 @@ void computeDiffuseness_fixed( if ( shift_q < 0 ) { shiftEquiv = L_lshl( 0x80000000, shift_q ); - shift_qtotal = sub( min_q_shift1, 0 ); } if ( shift_q >= 0 ) { shiftEquiv = L_add( 0x7FFFFFFF, 0 ); - shift_qtotal = sub( min_q_shift1, shift_q ); } + shift_qtotal = sub( min_q_shift1, s_max( shift_q, 0 ) ); + FOR( k = 0; k < num_freq_bands; k++ ) { tmp = L_shl( p_tmp_c[k], shift_qtotal ); @@ -1018,16 +1018,16 @@ void computeDiffuseness_fixed( shift_q = sub( q_tmp, q_intensity ); #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS - if ( shift_q >= 0 ) - { - shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); - shift_qtotal = sub( min_q_shift2, shift_q ); - } if ( shift_q < 0 ) { shiftEquiv = L_lshl( 0x80000000, shift_q ); - shift_qtotal = sub( min_q_shift2, 0 ); } + if ( shift_q >= 0 ) + { + shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); + } + shift_qtotal = sub( min_q_shift2, s_max( shift_q, 0 ) ); + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) { p_tmp = buffer_intensity[j][i]; -- GitLab From c4a32b8a40cf6b1f0e27ad8b880f45d9f2a22de7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 10 Feb 2025 13:50:23 +0530 Subject: [PATCH 0078/1221] Precision improvements, comments update for MR !1096 and fft-func updates --- lib_com/cnst.h | 1 + lib_com/fft_rel.c | 162 +++++++++++++++++++++++++++++++++++++++ lib_com/lsf_tools_fx.c | 74 ++++++++++++++++++ lib_com/prot_fx.h | 20 +++++ lib_com/tools_fx.c | 103 +++++++++++++++++++++++++ lib_enc/analy_sp_fx.c | 26 +++++-- lib_enc/swb_tbe_enc_fx.c | 2 +- lib_rend/lib_rend.c | 18 ++--- 8 files changed, 389 insertions(+), 17 deletions(-) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 66b6dc9a1..a5030ac9c 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1233,6 +1233,7 @@ enum #define SPC 0.0234952f #define SPC_plus SPC * 1.001f #define ALPHA_SQ ( ( 0.5f / PI2 ) * ( 0.5f / PI2 ) ) +#define ALPHA_SQ_Q30 (6799549) /* ( ( 0.5f / PI2 ) * ( 0.5f / PI2 ) ) in Q30 */ #define NC M / 2 #define LSF_GAP 50.0f diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c index 85d0ae76a..aa3b578bd 100644 --- a/lib_com/fft_rel.c +++ b/lib_com/fft_rel.c @@ -301,6 +301,168 @@ void fft_rel( return; } +void fft_rel_16_32fx( + Word16 x[], /* i/o: input/output vector Qx */ + Word16 *q_x, /* extra scaling added on speech buffer*/ + Word16 i_subfr, + const Word16 n, /* i : vector length */ + const Word16 m /* i : log2 of vector length */ +) +{ + Word16 i, j, k, n1, n2, n4; + Word16 step; + Word32 xt, t1, t2; + Word32 *x0, *x1, *x2; + const Word16 *s, *c; + Word32 *xi2, *xi3, *xi4, *xi1; + + Word32 fft_bff32[L_FFT]; + Copy_Scale_sig_16_32_no_sat( x, fft_bff32, L_FFT, 0 ); // copying x to fft_bff32 without scaling + + /*-----------------------------------------------------------------* + * Digit reverse counter + *-----------------------------------------------------------------*/ + + j = 0; + move16(); + x0 = &fft_bff32[0]; // Qx + FOR( i = 0; i < n - 1; i++ ) + { + IF( LT_16( i, j ) ) + { + xt = fft_bff32[j]; // Qx + move32(); + fft_bff32[j] = *x0; // Qx + move32(); + *x0 = xt; // Qx + move32(); + } + x0++; + k = shr( n, 1 ); + WHILE( ( k <= j ) ) + { + j = sub( j, k ); + k = shr( k, 1 ); + } + j = add( j, k ); + } + + /*-----------------------------------------------------------------* + * Length two butterflies + *-----------------------------------------------------------------*/ + + x0 = &fft_bff32[0]; + x1 = &fft_bff32[1]; + FOR( i = 0; i < ( n >> 1 ); i++ ) + { + xt = *x0; + move32(); + *x0 = L_add( xt, *x1 ); + move32(); + *x1 = L_sub( xt, *x1 ); + move32(); + x0++; + x0++; + x1++; + x1++; + } + + /*-----------------------------------------------------------------* + * Other butterflies + * + * The implementation described in [1] has been changed by using + * table lookup for evaluating sine and cosine functions. The + * variable ind and its increment step are needed to access table + * entries. Note that this implementation assumes n4 to be so + * small that ind will never exceed the table. Thus the input + * argument n and the constant N_MAX_SAS must be set properly. + *-----------------------------------------------------------------*/ + + n2 = 1; + move16(); + /* step = N_MAX_SAS/4; */ + FOR( k = 2; k <= m; k++ ) + { + n4 = n2; + move16(); + n2 = shl( n4, 1 ); + n1 = shl( n2, 1 ); + + step = idiv1616( N_MAX_SAS, n1 ); + + x0 = fft_bff32; + x1 = fft_bff32 + n2; + x2 = fft_bff32 + add( n2, n4 ); + FOR( i = 0; i < n; i += n1 ) + { + xt = *x0; + move32(); /* xt = x[i]; */ + *x0 = L_add( xt, *x1 ); + move32(); /* x[i] = xt + x[i+n2]; */ + *x1 = L_sub( xt, *x1 ); + move32(); /* x[i+n2] = xt - x[i+n2]; */ + *x2 = L_negate( *x2 ); + move32(); /* x[i+n2+n4] = -x[i+n2+n4]; */ + + + s = sincos_t_fx + step; // Q15 + c = s + 64; // Q15 + xi1 = fft_bff32 + add( i, 1 ); + xi3 = xi1 + n2; + xi2 = xi3 - 2; + xi4 = xi1 + sub( n1, 2 ); + + FOR( j = 1; j < n4; j++ ) + { + t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */ + t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */ + *xi4 = L_sub( *xi2, t2 ); + move32(); + *xi3 = L_negate( L_add( *xi2, t2 ) ); + move32(); + *xi2 = L_sub( *xi1, t1 ); + move32(); + *xi1 = L_add( *xi1, t1 ); + move32(); + + xi4--; + xi2--; + xi3++; + xi1++; + c += step; + s += step; /* autoincrement by ar0 */ + } + + x0 += n1; + x1 += n1; + x2 += n1; + } + /* step = shr(step, 1); */ + } + Word16 norm = L_norm_arr( fft_bff32, L_FFT ); + IF( i_subfr == 0 ) + { + Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm ); + *q_x = sub( norm, 16 ); + move16(); + } + ELSE + { + IF( LT_16( sub( norm, 16 ), *q_x ) ) + { + scale_sig( x - L_FFT, L_FFT, sub( sub( norm, 16 ), *q_x ) ); + Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm ); + *q_x = sub( norm, 16 ); + move16(); + } + ELSE + { + Copy_Scale_sig32_16( fft_bff32, x, L_FFT, add( 16, *q_x ) ); + } + } + + return; +} void fft_rel_fx( Word16 x[], /* i/o: input/output vector Qx */ diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index b99fc4753..0a8a86aee 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -1505,6 +1505,80 @@ void lsp_weights_fx( move16(); } +void lsp_weights_ivas_fx( + Word16 lsp_nq_fx[], + Word16 w[], + Word16 Order, + Word16 *Qout ) +{ + Word16 i; + Word16 q_weight[20]; + Word32 weight[20]; + Word16 delta1, delta2; + Word32 L_tmp; + Word16 q_min; + + delta1 = lsp_nq_fx[0]; // Q15 + move16(); + delta2 = sub( lsp_nq_fx[1], lsp_nq_fx[0] ); // Q15 + + L_tmp = L_mult0( delta1, delta2 ); // Q30 // Q30 + L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[0] ); // q_weight[0] + + weight[0] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[0]-8 + q_weight[0] = sub( q_weight[0], 8 ); + move32(); + move16(); + + q_min = q_weight[0]; + move16(); + + FOR( i = 1; i < Order - 1; i++ ) + { + delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15 + delta2 = sub( lsp_nq_fx[i + 1], lsp_nq_fx[i] ); // Q15 + + L_tmp = L_mult0( delta1, delta2 ); // Q30 + L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i] + + weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i] + q_weight[i] = sub( q_weight[i], 8 ); + move32(); + move16(); + + q_min = s_min( q_min, q_weight[i] ); + } + delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15 + delta2 = sub( 16384 /* 0.5 in Q15*/, lsp_nq_fx[i] ); // Q15 + + L_tmp = L_mult0( delta1, delta2 ); // Q30 + L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i] + + weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i] + q_weight[i] = sub( q_weight[i], 8 ); + move32(); + move16(); + + q_min = s_min( q_min, q_weight[i] ); + + FOR( i = 0; i < Order; i++ ) + { + w[i] = round_fx( L_shl( weight[i], sub( q_min, q_weight[i] ) ) ); /* q_min-16 */ + move16(); + } + + IF( Order != LPC_SHB_ORDER_WB ) + { + w[3] = round_fx( L_shl( L_mult( w[3], 18022 ), 1 ) ); /* q_min-16 */ + w[4] = round_fx( L_shl( L_mult( w[4], 18022 ), 1 ) ); /* q_min-16 */ + move16(); + move16(); + } + + *Qout = sub( q_min, 16 ); + move16(); +} + /* * E_LPC_isf_isp_conversion * diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index daf2c80d5..fbd3b27f3 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1084,6 +1084,12 @@ void lsp_weights_fx( Word16 Order, Word16 *Qout ); +void lsp_weights_ivas_fx( + Word16 lsp_nq_fx[], + Word16 w[], + Word16 Order, + Word16 *Qout ); + void space_lsfs_fx( Word16 *lsfs, /* i/o: Line spectral frequencies */ const Word16 order /* i : order of LP analysis */ @@ -1472,6 +1478,13 @@ void fft_rel_fx( const Word16 n, /* i : vector length */ const Word16 m /* i : log2 of vector length */ ); +void fft_rel_16_32fx( + Word16 x[], /* i/o: input/output vector Qx */ + Word16 *q_x, /* extra scaling added on speech buffer*/ + Word16 i_subfr, + const Word16 n, /* i : vector length */ + const Word16 m /* i : log2 of vector length */ +); void fft_rel_fx32( Word32 x[], /* i/o: i /output vector */ const Word16 n, /* i : vector length */ @@ -10297,6 +10310,13 @@ Word32 root_a_over_b_fx( Word16 Q_b, Word16 *exp_out ); +Word32 root_a_over_b_ivas_fx( + Word32 a, /* Q(Q_a) */ + Word16 Q_a, + Word32 b, /* Q(Q_b) */ + Word16 Q_b, + Word16 *exp_out ); + void fir_fx( const Word16 x[], /* i : input vector Qx*/ const Word16 h[], /* i : impulse response of the FIR filter Q12*/ Word16 y[], /* o : output vector (result of filtering) Qx*/ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 704b44b84..063f49fc4 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -2505,6 +2505,109 @@ Word32 root_a_over_b_fx( return L_tmp; } +Word32 root_a_over_b_ivas_fx( + Word32 a, /* Q(Q_a) */ + Word16 Q_a, + Word32 b, /* Q(Q_b) */ + Word16 Q_b, + Word16 *q_out ) +{ + Word16 shift_a, shift_b, shift; + Word32 mod_a, mod_b, one_in_Q_a, one_in_Q_b, half_in_Q_a, half_in_Q_b; + Word32 a_sqr, b_sqr, p0, p1, p2, approx; + Word16 exp; + + test(); + IF( ( a <= 0 ) || ( b <= 0 ) ) + { + *q_out = 0; + move16(); + return 0; + } + + one_in_Q_a = L_shl( 1, Q_a ); // 1.0f in Q_a + one_in_Q_b = L_shl( 1, Q_b ); // 1.0f in Q_b + half_in_Q_a = L_shr( one_in_Q_a, 1 ); // 0.5f in Q_a + half_in_Q_b = L_shr( one_in_Q_b, 1 ); // 0.5f in Q_b + + a = L_add( a, one_in_Q_a ); + b = L_add( b, one_in_Q_b ); + + /* This next piece of code implements a "norm" function */ + /* and returns the shift needed to scale "a" to have a */ + /* 1 in the (MSB-1) position. This is equivalent to */ + /* giving a value between 0.5 & 1.0. */ + + mod_a = a; + move32(); + + shift_a = 0; + move16(); + WHILE( GT_32( mod_a, one_in_Q_a ) ) + { + mod_a = L_shr( mod_a, 1 ); + shift_a = sub( shift_a, 1 ); + } + + WHILE( LT_32( mod_a, half_in_Q_a ) ) + { + mod_a = L_shl( mod_a, 1 ); + shift_a = add( shift_a, 1 ); + } + + shift_a = s_and( shift_a, -2 ); + mod_a = L_shl( a, shift_a ); // Q_a + + /* This next piece of code implements a "norm" function */ + /* and returns the shift needed to scale "b" to have a */ + /* 1 in the (MSB-1) position. This is equivalent to */ + /* giving a value between 0.5 & 1.0. */ + mod_b = b; + move32(); + + shift_b = 0; + move16(); + WHILE( GT_32( mod_b, one_in_Q_b ) ) + { + mod_b = L_shr( mod_b, 1 ); + shift_b = sub( shift_b, 1 ); + } + + WHILE( LT_32( mod_b, half_in_Q_b ) ) + { + mod_b = L_shl( mod_b, 1 ); + shift_b = add( shift_b, 1 ); + } + + shift_b = s_and( shift_b, -2 ); + mod_b = L_shl( b, shift_b ); // Q_b + + shift = shr( sub( shift_b, shift_a ), 1 ); + + a_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_a, mod_a ), sub( 32, Q_a ) ) ); // Q_a + b_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_b, mod_b ), sub( 32, Q_b ) ) ); // Q_b + + p2 = L_shl( -408505077 /* -0.7609f in Q29 */, sub( Q_b, 31 ) ); // Qb-2 + p1 = L_shl( 1444612250 /* 2.6908f in Q29 */, sub( Q_b, 31 ) ); // Qb-2 + p0 = L_shl( 385258566 /* 0.7176f in Q29 */, sub( Q_b, 31 ) ); // Qb-2 + + p2 = Madd_32_32( Madd_32_32( p2, 501759554 /* 0.9346f in Q29*/, mod_b ), -252060893 /* -0.4695f in Q29 */, b_sqr ); // Q_b-2 + p1 = Madd_32_32( Madd_32_32( p1, -1774680487 /* -3.3056f in Q29 */, mod_b ), 891635211 /* 1.6608f in Q29 */, b_sqr ); // Q_b-2 + p0 = Madd_32_32( Madd_32_32( p0, -473251709 /* -0.8815f in Q29 */, mod_b ), 237780127 /* 0.4429f in Q29 */, b_sqr ); // Q_b-2 + + /* approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; */ + approx = Madd_32_32( Mpy_32_32( p1, mod_a ), p2, a_sqr ); // Q_a+Q_b-33 + approx = L_add( approx, L_shl( p0, sub( Q_a, 31 ) ) ); // Q_a+Q_b-33 + + exp = sub( norm_l( approx ), 1 ); + approx = L_shl( approx, exp ); // // Q_a+Q_b-33+exp + + *q_out = sub( add( sub( add( Q_a, Q_b ), 33 ), exp ), shift ); + move16(); + + return approx; +} + /*===================================================================*/ /* FUNCTION : fir_fx () */ /*-------------------------------------------------------------------*/ diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index f0d940563..c0d1a8bca 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -510,9 +510,7 @@ void ivas_analy_sp_fx( } ELSE { - Word16 scale = norm_arr( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT + 4 * ( L_SUBFR / 2 ) ); - scale = sub( scale, LOG2_L_FFT ); // guard_bits - *q_fft_buff = add( Q_new, scale ); + Word16 scale = 0; move16(); FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) @@ -543,11 +541,25 @@ void ivas_analy_sp_fx( move16(); } - scale_sig( pt_fft, L_FFT, scale ); - /* compute the spectrum */ - fft_rel_fx( pt_fft, L_FFT, LOG2_L_FFT ); - + fft_rel_16_32fx( pt_fft, &scale, i_subfr, L_FFT, LOG2_L_FFT ); + *q_fft_buff = add( Q_new, scale ); // resultant q for fft_buff + move16(); + IF( EQ_16( i_subfr, 1 ) ) + { + Word16 new_q_lf_E = add( shl( *q_fft_buff, 1 ), 14 ); + Word16 new_q_bands = new_q_lf_E; + IF( GT_16( new_q_bands, 39 ) ) + { + new_q_bands = 39; + move16(); + } + scale_sig32( fr_bands, NB_BANDS, sub( new_q_bands, *q_fr_bands ) ); + scale_sig32( lf_E, VOIC_BINS, sub( new_q_lf_E, *q_lf_E ) ); + LEtot = W_shl( LEtot, sub( new_q_bands, *q_fr_bands ) ); + scale_sig32( Bin_E, L_FFT / 2, sub( new_q_lf_E, *q_lf_E ) ); + scale_sig32( band_energies, NB_BANDS, sub( new_q_bands, *q_fr_bands ) ); + } /* find energy per critical band */ ivas_find_enr( pt_fft, *q_fft_buff, pt_bands, q_fr_bands, lf_E + i_subfr * VOIC_BINS, q_lf_E, &LEtot, min_band, max_band, &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 1366ab4c5..23bd387d4 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -3148,7 +3148,7 @@ void swb_tbe_enc_ivas_fx( test(); IF( st_fx->rf_mode || EQ_32( st_fx->extl_brate, SWB_TBE_0k95 ) || EQ_32( st_fx->extl_brate, SWB_TBE_1k10 ) ) { - lsp_weights_fx( lsf_shb_fx, weights_lsp, LPC_SHB_ORDER, &Q_out ); + lsp_weights_ivas_fx( lsf_shb_fx, weights_lsp, LPC_SHB_ORDER, &Q_out ); /* to compensate for the 1.1* weighting done inside the function lsp_weights */ /*weights_lsp[3]*=0.909091f; weights_lsp[4]*=0.909091f; */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 9cab74182..86eea321b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4564,7 +4564,7 @@ static void renderBufferChannelLerp_fx( { i = 0; Word32 tmp = Q31_BY_SUB_FRAME_240; - Word32 tmp1 = 239; + Word32 tmp1 = 239; /* L_SUBFRAME_48k - 1 */ move32(); move32(); move32(); @@ -4572,49 +4572,49 @@ static void renderBufferChannelLerp_fx( { case NUM_SAMPLES_960: tmp = Q31_BY_NUM_SAMPLES_960; - tmp1 = 959; + tmp1 = 959; /* NUM_SAMPLES_960 - 1 */ move32(); move32(); BREAK; case NUM_SAMPLES_720: tmp = Q31_BY_NUM_SAMPLES_720; - tmp1 = 719; + tmp1 = 719; /* NUM_SAMPLES_720 - 1 */ move32(); move32(); BREAK; case NUM_SAMPLES_320: tmp = Q31_BY_NUM_SAMPLES_320; - tmp1 = 319; + tmp1 = 319; /* NUM_SAMPLES_320 - 1 */ move32(); move32(); BREAK; case NUM_SAMPLES_160: tmp = Q31_BY_NUM_SAMPLES_160; - tmp1 = 159; + tmp1 = 159; /* NUM_SAMPLES_160 - 1 */ move32(); move32(); BREAK; case L_SUBFRAME_48k: tmp = Q31_BY_SUB_FRAME_240; - tmp1 = 239; + tmp1 = 239; /* L_SUBFRAME_48k - 1 */ move32(); move32(); BREAK; case L_SUBFRAME_32k: tmp = Q31_BY_SUB_FRAME_180; - tmp1 = 179; + tmp1 = 179; /* L_SUBFRAME_32k - 1 */ move32(); move32(); BREAK; case L_SUBFRAME_16k: tmp = Q31_BY_SUB_FRAME_80; - tmp1 = 79; + tmp1 = 79; /* L_SUBFRAME_16k - 1 */ move32(); move32(); BREAK; case L_SUBFRAME_8k: tmp = Q31_BY_SUB_FRAME_40; - tmp1 = 39; + tmp1 = 39; /* L_SUBFRAME_8k - 1 */ move32(); move32(); BREAK; -- GitLab From 5c1535eb867eed69d26a6b30a7e93bf06eb8b380 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 10 Feb 2025 15:11:03 +0530 Subject: [PATCH 0079/1221] Fix for 3GPP issue 1251: Basop Encoder: Spectral holes between 2-4 kHz and spectral differences for Unified Stereo @24kbps - 2 Link #1251 --- lib_enc/ivas_stereo_ica_enc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 5ee97f27c..9d06a5523 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1337,17 +1337,10 @@ static void estDownmixGain_fx( } ELSE IF( GT_16( hStereoTCA->LRTD_G_ATT_cnt, 1 ) ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */ { - currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, ¤tGain_e ); // Q = 15 + 0 - (15 - exp) - /* Division result Q has to be got back to the Q of initial currentGain hence the shift operation below */ - IF( currentGain_e != 0 ) - { - currentGain = shr( currentGain, sub( Q15, currentGain_e ) ); /* Q15 */ - currentGain_e = 0; - move16(); - } + currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, &exp ); + currentGain_e = add( exp, sub( currentGain_e, 15 ) ); } - IF( GE_16( norm_s( currentGain ), sub( currentGain_e, 1 ) ) ) { /* convert currentGain into Q14 */ -- GitLab From a8e2c96b93cb5e7da3959a8dd0e45b0abe564571 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 10 Feb 2025 15:15:52 +0530 Subject: [PATCH 0080/1221] TNS bug fixes, updates in swb_tbe_enc and lp_filt_exc_enc_ivas_fx --- lib_enc/cod_tcx.c | 4 ++-- lib_enc/lp_exc_e_fx.c | 2 +- lib_enc/swb_tbe_enc_fx.c | 6 +++--- lib_enc/tns_base_enc_fx.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index aaa7e4e2e..8ddfb573b 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -290,7 +290,7 @@ void TNSAnalysisStereo_fx( Word16 maxEnergyChange_fx; maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ); - IF( GE_16( maxEnergyChange_fx, pTnsParameters[0]->minEnergyChange ) ) + IF( GE_16( maxEnergyChange_fx, L_shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) ) { sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); move16(); @@ -552,7 +552,7 @@ void TNSAnalysisStereo_fx( { Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); - IF( GE_16( maxEnergyChange_fx, pTnsParameters->minEnergyChange ) ) + IF( GE_16( maxEnergyChange_fx, L_shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) ) { sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); move16(); diff --git a/lib_enc/lp_exc_e_fx.c b/lib_enc/lp_exc_e_fx.c index 5afca5136..0887698f7 100644 --- a/lib_enc/lp_exc_e_fx.c +++ b/lib_enc/lp_exc_e_fx.c @@ -260,7 +260,7 @@ Word16 lp_filt_exc_enc_ivas_fx( } IF( use_prev_sf_pit_gain == 1 ) { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, gain_pit, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); } ELSE { diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 23bd387d4..f67d81c71 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -4049,7 +4049,9 @@ void swb_tbe_enc_ivas_fx( { /* Re-normalize gain shape before quantization */ // sum_gain = sum2_f(GainShape, NUM_SHB_SUBGAINS); - sum_gain_fx = sum16_32_fx( GainShape_fx, NUM_SHB_SUBGAINS ); + tmp = 0; + move16(); + sum_gain_fx = sum2_16_exp_fx( GainShape_fx, NUM_SHB_SUBGAINS, &tmp, 2 ); IF( sum_gain_fx == 0 ) { normFact_fx = 0; @@ -4058,8 +4060,6 @@ void swb_tbe_enc_ivas_fx( ELSE { // normFact = (float) sqrt( 1.0f / sum_gain ); - tmp = Q16; - move16(); normFact_fx = ISqrt32( sum_gain_fx, &tmp ); } diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index 79bb7b914..90028b732 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -675,7 +675,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur ELSE { maxEnergyChange = GetTCXMaxenergyChange_ivas_fx( hTranDet, isTCX10, NSUBBLOCKS, 3 ); - IF( sub( maxEnergyChange, pTnsParameters->minEnergyChange ) >= 0 ) + IF( sub( maxEnergyChange, L_shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) >= 0 ) { pTnsData->nFilters = add( pTnsData->nFilters, 1 ); -- GitLab From 862ad71da876fc21a5a1667caef42caa7dbaeebc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 10 Feb 2025 15:55:30 +0530 Subject: [PATCH 0081/1221] Bug fix: Exponent mismatch bug fixed in ivas_mdct_core_whitening_enc_fx Link #1239 --- lib_enc/ivas_mdct_core_enc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 710eb864f..18bee6777 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -2108,8 +2108,13 @@ void ivas_mdct_core_whitening_enc_fx( st->hTcxEnc->spectrum_e[n] = sub( st->hTcxEnc->spectrum_e[n], q_com ); move16(); + Word16 exp_tmp = st->hTcxEnc->spectrum_e[n]; + move16(); + /* Shape spectrum */ ShapeSpectrum_ivas_fx( st->hTcxCfg, A_q_fx[ch][n], NULL, NULL, L_subframe, tcx_subframe_coded_lines, st->hTcxEnc->spectrum_fx[n], &st->hTcxEnc->spectrum_e[n], st->hTcxEnc->fUseTns[n], st, scf_q_fx[ch][n] ); + + Scale_sig32( st->hTcxEnc->spectrum_fx[n] + L_subframe, sub( L_subframeTCX, L_subframe ), sub( exp_tmp, st->hTcxEnc->spectrum_e[n] ) ); } } /*--------------------------------------------------------------* @@ -2243,8 +2248,13 @@ void ivas_mdct_core_whitening_enc_fx( mdst_spectrum_e[ch][n] = sub( mdst_spectrum_e[ch][n], q_com ); move16(); + Word16 exp_tmp = mdst_spectrum_e[ch][n]; + move16(); + /* Shape spectrum */ ShapeSpectrum_ivas_fx( st->hTcxCfg, A_q_fx[ch][n], NULL, NULL, L_subframe, tcx_subframe_coded_lines, mdst_spectrum_fx[ch][n], &mdst_spectrum_e[ch][n], st->hTcxEnc->fUseTns[n], st, scf_q_fx[ch][n] ); + + Scale_sig32( mdst_spectrum_fx[ch][n] + L_subframe, sub( L_subframeTCX, L_subframe ), sub( exp_tmp, mdst_spectrum_e[ch][n] ) ); } } } -- GitLab From 0ec81a7a6a77a5ad999add316be7e1f578ca7da2 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 10 Feb 2025 12:09:08 +0100 Subject: [PATCH 0082/1221] fix res ouput id > 9 --- lib_debug/debug.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib_debug/debug.c b/lib_debug/debug.c index f1cfa928a..23de1bd36 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -39,6 +39,7 @@ #include "options.h" #ifdef DEBUGGING #include "debug.h" +#include #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK #include @@ -771,8 +772,10 @@ char *fname( const int16_t id, const int16_t enc_dec ) { - char idd[5] = ".idX"; - idd[3] = (char) ( id + '0' ); + char idd[6]; + + assert( id < 100 ); + sprintf( idd, ".id%d", id ); strcpy( tmp_fname, dir ); strcat( tmp_fname, file ); -- GitLab From 55146b977a608485aab3f10e8d52f055c231f347 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 10 Feb 2025 15:02:12 +0100 Subject: [PATCH 0083/1221] REMOVE_EVS_DUPLICATES in acelp_core_dec_fx() --- lib_com/gs_inact_switching_fx.c | 65 +++++++++++++++++++++++++------- lib_com/gs_noisefill_fx.c | 55 ++++++++++++++++++--------- lib_com/options.h | 2 + lib_com/prot_fx.h | 3 ++ lib_dec/FEC_scale_syn_fx.c | 10 +++++ lib_dec/acelp_core_dec_fx.c | 57 +++++++++++++++++++++++++++- lib_dec/acelp_core_dec_ivas_fx.c | 15 +++++++- lib_dec/dec_gen_voic_fx.c | 14 ++++++- lib_dec/gs_dec_fx.c | 12 +++++- 9 files changed, 196 insertions(+), 37 deletions(-) diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 5dfe6b1d6..52635d502 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -253,31 +253,68 @@ void Inac_switch_ematch_ivas_fx( exp = sub( exp, 14 ); IF( LT_16( i, 2 ) ) { - FOR( j = 0; j < 8; j++ ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( element_mode, EVS_MONO ) ) { - L_tmp = L_mult0( *pt_exc, ftmp ); - L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/ - *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/ - move16(); - pt_exc++; + FOR( j = 0; j < 8; j++ ) + { + L_tmp = L_mult( *pt_exc, ftmp ); + L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/ + *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/ + move16(); + pt_exc++; + } + } + ELSE +#endif + { + FOR( j = 0; j < 8; j++ ) + { + L_tmp = L_mult0( *pt_exc, ftmp ); + L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/ + *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/ + move16(); + pt_exc++; + } } } ELSE { - FOR( j = 0; j < 16; j++ ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( element_mode, EVS_MONO ) ) { - L_tmp = L_mult0( *pt_exc, ftmp ); - L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/ - *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/ - move16(); - pt_exc++; + FOR( j = 0; j < 16; j++ ) + { + L_tmp = L_mult( *pt_exc, ftmp ); + L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/ + *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/ + move16(); + pt_exc++; + } + } + ELSE +#endif + { + FOR( j = 0; j < 16; j++ ) + { + L_tmp = L_mult0( *pt_exc, ftmp ); + L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/ + *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/ + move16(); + pt_exc++; + } } } } /* Going back to time */ - Scale_sig( dct_exc_tmp, 240, 1 ); // Q_exc - Scale_sig( exc2, 240, 1 ); // Q_exc +#ifdef REMOVE_EVS_DUPLICATES + IF( GT_16( element_mode, EVS_MONO ) ) +#endif + { + Scale_sig( dct_exc_tmp, 240, 1 ); // Q_exc + Scale_sig( exc2, 240, 1 ); // Q_exc + } edct_16fx( dct_exc_tmp, exc2, L_frame, 5, element_mode ); } diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index d2a576dbe..5cf285bf2 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -1412,32 +1412,51 @@ void highband_exc_dct_in_ivas_fx( } } #endif - Word16 Q_tmp = *Q_exc; - move16(); - Word16 Q_old = *Q_exc; - move16(); - Comp_and_apply_gain_ivas_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc ); - IF( exc_wo_nf != NULL ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( element_mode, EVS_MONO ) ) { - Comp_and_apply_gain_ivas_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, &Q_tmp ); - IF( GT_16( Q_tmp, *Q_exc ) ) - { - Scale_sig( exc_wo_nf, L_frame, sub( *Q_exc, Q_tmp ) ); - } - ELSE IF( LT_16( Q_tmp, *Q_exc ) ) + Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, *Q_exc ); + + IF( exc_wo_nf != NULL ) { - Scale_sig( exc_diffQ, L_frame, sub( Q_tmp, *Q_exc ) ); - *Q_exc = Q_tmp; - move16(); + Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, *Q_exc ); + Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); } - Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) ); - Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); } ELSE { - Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) ); +#endif + Word16 Q_tmp = *Q_exc; + move16(); + Word16 Q_old = *Q_exc; + move16(); + Comp_and_apply_gain_ivas_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc ); + + IF( exc_wo_nf != NULL ) + { + Comp_and_apply_gain_ivas_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, &Q_tmp ); + IF( GT_16( Q_tmp, *Q_exc ) ) + { + Scale_sig( exc_wo_nf, L_frame, sub( *Q_exc, Q_tmp ) ); + } + ELSE IF( LT_16( Q_tmp, *Q_exc ) ) + { + Scale_sig( exc_diffQ, L_frame, sub( Q_tmp, *Q_exc ) ); + *Q_exc = Q_tmp; + move16(); + } + Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) ); + Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); + } + ELSE + { + Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) ); + } +#ifdef REMOVE_EVS_DUPLICATES } +#endif + /*--------------------------------------------------------------------------------------* * add the correction layer to the LF bins, * and add the quantized pulses or the noise for the higher part of the spectrum diff --git a/lib_com/options.h b/lib_com/options.h index 1b2c15f87..c34882a0e 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,4 +154,6 @@ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ + +#define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions */ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index fbd3b27f3..bef07e952 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -8242,6 +8242,9 @@ void FEC_scale_syn_ivas_fx( Word16 *mem_syn, /* o: initial synthesis filter states */ Word16 Q_exc, Word16 Q_syn, +#ifdef REMOVE_EVS_DUPLICATES + const Word16 element_mode, /* i : element mode */ +#endif const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ const Word16 force_scaling /* i: force scaling */ ); diff --git a/lib_dec/FEC_scale_syn_fx.c b/lib_dec/FEC_scale_syn_fx.c index d664aa9fb..f6439b166 100644 --- a/lib_dec/FEC_scale_syn_fx.c +++ b/lib_dec/FEC_scale_syn_fx.c @@ -641,6 +641,9 @@ void FEC_scale_syn_ivas_fx( Word16 *mem_syn, /* o: initial synthesis filter states Q_syn*/ Word16 Q_exc, Word16 Q_syn, +#ifdef REMOVE_EVS_DUPLICATES + const Word16 element_mode, /* i : element mode */ +#endif const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ const Word16 force_scaling /* i: force scaling */ ) @@ -735,8 +738,15 @@ void FEC_scale_syn_ivas_fx( /*-----------------------------------------------------------------* * Find the energy/gain at the end of the frame *-----------------------------------------------------------------*/ + tmp = sub( 3, getScaleFactor16( synth, L_frame ) ); + +#ifdef REMOVE_EVS_DUPLICATES + test(); + IF( tmp > 0 && GT_16( element_mode, EVS_MONO ) ) +#else IF( tmp > 0 ) +#endif { Word16 synth_tmp[L_FRAME16k]; Copy_Scale_sig( synth, synth_tmp, L_frame, -tmp ); // Q_synth - tmp diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index a41a0c813..e3770b997 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -777,14 +777,21 @@ ivas_error acelp_core_dec_fx( move16(); } +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); - +#endif test(); test(); IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) { +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif } } @@ -827,8 +834,12 @@ ivas_error acelp_core_dec_fx( if ( !tdm_lp_reuse_flag ) #endif { +#ifdef REMOVE_EVS_DUPLICATES + lsf_dec_ivas_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, tdm_lsfQ_PCh ); +#else lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, tdm_lsfQ_PCh ); +#endif } #ifdef ADD_LRTD else @@ -953,7 +964,11 @@ ivas_error acelp_core_dec_fx( IF( st_fx->stab_fac_fx == 0 && st_fx->old_bfi_cnt > 0 && NE_16( st_fx->clas_dec, VOICED_CLAS ) && NE_16( st_fx->clas_dec, ONSET ) && st_fx->relax_prev_lsf_interp == 0 && !( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) ) { +#ifdef REMOVE_EVS_DUPLICATES + int_lsp4_ivas_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid_fx, lsp_new_fx, Aq_fx, M, 2 ); +#else int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid_fx, lsp_new_fx, Aq_fx, M, 2 ); +#endif } /*---------------------------------------------------------------* @@ -1005,7 +1020,11 @@ ivas_error acelp_core_dec_fx( ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) ) { /* UNVOICED frames */ +#ifdef REMOVE_EVS_DUPLICATES + decod_unvoiced_ivas_fx( st_fx, Aq_fx, Es_pred_fx, uc_two_stage_flag, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); +#else decod_unvoiced_fx( st_fx, Aq_fx, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); +#endif } ELSE IF( EQ_16( st_fx->ppp_mode_dec, 1 ) ) { @@ -1026,17 +1045,26 @@ ivas_error acelp_core_dec_fx( } ELSE IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) ) ) { +#ifdef REMOVE_EVS_DUPLICATES + decod_audio_ivas_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf, + 0, 0, 0, NULL ); +#else decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf #ifdef ADD_LRTD , tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf #endif ); +#endif tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ } ELSE { +#ifdef REMOVE_EVS_DUPLICATES + IF( NE_32( ( error = decod_gen_voic_ivas_fx( st_fx, st_fx->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf, 0, NULL ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = decod_gen_voic_fx( st_fx, st_fx->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf /*, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf*/ ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -1049,6 +1077,7 @@ ivas_error acelp_core_dec_fx( /* synthesis for ACELP core switching and SWB BWE */ syn_12k8_fx( st_fx->L_frame, Aq_fx, exc_fx, temp_buf_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); + /* save and delay synthesis to be used by SWB BWE */ IF( hBWE_FD != NULL ) { @@ -1059,7 +1088,11 @@ ivas_error acelp_core_dec_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES + Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode, 0, EVS_MONO ); +#else Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); +#endif /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames *------------------------------------------------------------*/ @@ -1187,9 +1220,16 @@ ivas_error acelp_core_dec_fx( k = add( k, 1 ); } +#ifdef REMOVE_EVS_DUPLICATES + FEC_scale_syn_ivas_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); + +#else FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); +#endif test(); test(); @@ -1268,8 +1308,13 @@ ivas_error acelp_core_dec_fx( { save_old_syn_fx( st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); } + /* Apply energy matching when switching to inactive frames */ +#ifdef REMOVE_EVS_DUPLICATES + Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode, 0, EVS_MONO ); +#else Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); +#endif /* udate past excitation signals for LD music post-filter */ IF( hMusicPF != NULL ) @@ -1343,9 +1388,15 @@ ivas_error acelp_core_dec_fx( * (smoothing is performed in the excitation domain and signal is resynthesized after) *------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES + FEC_scale_syn_ivas_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); +#else FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); +#endif } /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ @@ -1440,7 +1491,11 @@ ivas_error acelp_core_dec_fx( Copy( syn_fx, temp_buf + L_SYN_MEM, L_FRAME16k ); st_fx->hPFstat->on = 1; move16(); +#ifdef REMOVE_EVS_DUPLICATES + formant_post_filt_ivas_fx( st_fx->hPFstat, temp_buf + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME16k, st_fx->lp_noise, st_fx->total_brate, 0 ); +#else formant_post_filt_fx( st_fx->hPFstat, temp_buf + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME16k, st_fx->lp_noise, st_fx->total_brate, 0 ); +#endif } ELSE IF( GE_16( st_fx->last_bwidth, WB ) ) { diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 24427c5d2..8d6b63833 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -47,12 +47,15 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" +static void rescale_fdCngDec( HANDLE_FD_CNG_DEC hFdCngDec, Word16 old_NoiseExp ); + + /*-------------------------------------------------------------------* * acelp_core_dec_ivas_fx() * * ACELP core decoder *-------------------------------------------------------------------*/ -static void rescale_fdCngDec( HANDLE_FD_CNG_DEC hFdCngDec, Word16 old_NoiseExp ); + ivas_error acelp_core_dec_ivas_fx( Decoder_State *st, /* i/o: decoder state structure */ Word16 output_fx[], /* o : synthesis @internal Fs Q_syn*/ @@ -350,6 +353,7 @@ ivas_error acelp_core_dec_ivas_fx( int_fs = INT_FS_16k; move16(); } + test(); /* reset post-filter in case of switching */ if ( st->hPFstat != NULL && ( st->hPFstat->on == 0 ) ) @@ -368,6 +372,7 @@ ivas_error acelp_core_dec_ivas_fx( move16(); } test(); + /* TD stereo parameters */ IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) { @@ -1225,7 +1230,11 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k, -Q6 ); // Q0 FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, +#ifdef REMOVE_EVS_DUPLICATES + exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, st->element_mode, avoid_lpc_burst_on_recovery, 0 ); +#else exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, 0 ); +#endif test(); test(); test(); @@ -1380,7 +1389,11 @@ ivas_error acelp_core_dec_ivas_fx( FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, +#ifdef REMOVE_EVS_DUPLICATES + exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, st->element_mode, avoid_lpc_burst_on_recovery, 0 ); +#else exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, 0 ); +#endif } /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 1abd3d58b..190431fb8 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -809,8 +809,18 @@ ivas_error decod_gen_voic_ivas_fx( } ELSE { - enhancer_ivas_fx2( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, - norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); + } + ELSE +#endif + { + enhancer_ivas_fx2( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); + } } p_Aq_fx += ( M + 1 ); diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index c237bc987..93c346a7d 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -1514,7 +1514,17 @@ void gsc_dec_ivas_fx( { i--; } - mean_gain = gsc_gaindec_ivas_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ + +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ + } + ELSE +#endif + { + mean_gain = gsc_gaindec_ivas_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ + } #else mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); -- GitLab From ef2485345725198d55c50d1db33506c25ea13845 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 10 Feb 2025 16:13:32 +0100 Subject: [PATCH 0084/1221] fix --- lib_dec/dec_gen_voic_fx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 190431fb8..8ee335e3f 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -699,7 +699,16 @@ ivas_error decod_gen_voic_ivas_fx( } /* update LP filtered gains for the case of frame erasures */ - lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); + } + ELSE +#endif + { + lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); + } /*----------------------------------------------------------------------* * Find the total excitation -- GitLab From 68e8c9810d6eea2113b278f0d618cd629340e9c2 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 10 Feb 2025 17:04:05 +0100 Subject: [PATCH 0085/1221] fix --- lib_com/gs_noisefill_fx.c | 5 +++++ lib_dec/acelp_core_dec_fx.c | 3 +-- lib_dec/gs_dec_fx.c | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index 5cf285bf2..1ccc697fb 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -1496,7 +1496,12 @@ void highband_exc_dct_in_ivas_fx( Q_hb_exc = 0; move16(); envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, *Q_exc, &Q_hb_exc ); +#ifdef REMOVE_EVS_DUPLICATES + test(); + IF( GT_16( *Q_exc, Q_hb_exc ) && GT_16( element_mode, EVS_MONO ) ) +#else IF( GT_16( *Q_exc, Q_hb_exc ) ) +#endif { Scale_sig( exc_wo_nf, L_frame, sub( Q_hb_exc, *Q_exc ) ); *Q_exc = Q_hb_exc; diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index e3770b997..779df2fa4 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1046,8 +1046,7 @@ ivas_error acelp_core_dec_fx( ELSE IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) ) ) { #ifdef REMOVE_EVS_DUPLICATES - decod_audio_ivas_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf, - 0, 0, 0, NULL ); + decod_audio_ivas_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf, 0, 0, 0, NULL ); #else decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf #ifdef ADD_LRTD diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 93c346a7d..72e07e57f 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -993,9 +993,11 @@ void decod_audio_ivas_fx( } } #endif + Word16 Q_exc_old = st_fx->Q_exc; move16(); gsc_dec_ivas_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, &st_fx->Q_exc ); + IF( NE_16( Q_exc_old, st_fx->Q_exc ) ) { Q_exc_old = sub( Q_exc_old, st_fx->Q_exc ); -- GitLab From fb7b4020601f61bc9e4fd51df65763967bf977a6 Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 10 Feb 2025 17:47:12 +0100 Subject: [PATCH 0086/1221] fix --- lib_dec/dec_uv_fx.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index ffb49be38..6a15732a0 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -247,10 +247,18 @@ void decod_unvoiced_ivas_fx( * Excitation enhancements (update of total excitation signal) *----------------------------------------------------------------*/ - /*enhancer_fx(st_fx->core_brate, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, - norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &(st_fx->dm_fx), st_fx->Q_exc);*/ - enhancer_ivas_fx( MODE1, st_fx->core_brate, uc_two_stage_flag, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, - norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx /*Q9/Q12?*/, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + enhancer_fx( st_fx->core_brate, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); + } + ELSE +#endif + { + enhancer_ivas_fx( MODE1, st_fx->core_brate, uc_two_stage_flag, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx /*Q9/Q12?*/, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); + } Word16 tmp_idx; tmp_idx = 0; @@ -258,9 +266,16 @@ void decod_unvoiced_ivas_fx( if ( i_subfr_fx != 0 ) { idiv1616( i_subfr_fx, L_SUBFR ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); + } +#endif } voice_factors_fx[tmp_idx] = 0; move16(); + interp_code_5over2_fx( &exc_fx[i_subfr_fx], &bwe_exc_fx[( ( i_subfr_fx * 2 * HIBND_ACB_L_FAC ) >> 1 )], L_SUBFR ); p_Aq_fx += ( M + 1 ); -- GitLab From f309031e8accc05c1bf3de35cf5c5cec1197bee7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Feb 2025 12:29:18 +0530 Subject: [PATCH 0087/1221] [3GPP-Issue #1102] Address sanity bug causes crash on linux runners with ivas-float-update and newly added .prm file for encoder tests --- lib_com/options.h | 1 + lib_dec/ivas_mct_dec.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 1b2c15f87..283553640 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,4 +154,5 @@ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #endif diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 33a71fbcf..a8cda4e58 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -86,6 +86,10 @@ ivas_error ivas_mct_dec_fx( set16_fx( x_len[0], 0, NB_DIV ); set16_fx( x_len[1], 0, NB_DIV ); Decoder_State **sts; +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + Word32 *p_output_orig_fx[2]; + Word32 synth_32_fx[CPE_CHANNELS][L_FRAME_PLUS]; +#endif Word16 synth_fx[CPE_CHANNELS][L_FRAME_PLUS]; //(Q_synth) Word32 ivas_total_brate; ivas_error error; @@ -162,6 +166,18 @@ ivas_error ivas_mct_dec_fx( /* MCT side bits decoder */ ivas_mct_side_bits_fx( hMCT, st_ivas->hCPE, nCPE, st_ivas->hCPE[0]->hCoreCoder[0], st_ivas->bfi, st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream, ivas_total_brate, nb_bits_metadata ); +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + /* in case of switching from an SID frame (with ACELP core) to MCT, buffer of L_FRAME_PLUS samples is needed -> use synth[] as a temporary buffer */ + IF( st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + p_output_orig_fx[n] = output_fx[n]; + output_fx[n] = synth_32_fx[n]; + } + } +#endif + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { st_ivas->hCPE[cpe_id]->hCoreCoder[0]->BER_detect = s_or( st_ivas->hCPE[cpe_id]->hCoreCoder[0]->BER_detect, st_ivas->BER_detect ); @@ -371,6 +387,18 @@ ivas_error ivas_mct_dec_fx( } } +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + /* set pointers back */ + test(); + IF( cpe_id == 0 && st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + output_fx[n] = p_output_orig_fx[n]; + } + } + +#endif /*----------------------------------------------------------------* * CoreCoder Post-processing and updates -- GitLab From 19726c715a0689d98b57bc4a9d18e72bd8c44b1e Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 11 Feb 2025 10:27:38 +0100 Subject: [PATCH 0088/1221] fix(point)ed RCcontextMapping_encode2_estimate_bandWise_start_fx() and RCcontextMapping_encode2_estimate_bandWise_fx() already. --- lib_enc/ACcontextMapping_enc_fx.c | 122 +++++++++++++++--------------- lib_enc/stat_enc.h | 3 +- 2 files changed, 64 insertions(+), 61 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 08baa4f3d..53af78878 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -16,6 +16,9 @@ #include "prot_fx_enc.h" #include "ivas_prot.h" /* Range coder header file */ +#define MAKE_NUMBER_QX(number,QX) ((number)<<(QX)) +#define MAKE_VARIABLE_QX(variable,QX) W_shl(W_deposit32_l(L_deposit_l(( variable) ) ), (QX)) + /*-------------------------------------------------------------------* * ACcontextMapping_encode2_no_mem_s17_LC_fx() * @@ -1106,8 +1109,8 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( } /* Finish range encoder */ - rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder Q0*/ - bp = add( rc_tot_bits, nbbits_ntuples ); /* Update bitstream pointer Q0*/ + rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder Q0*/ + bp = add( rc_tot_bits, nbbits_ntuples ); /* Update bitstream pointer Q0*/ /* Cross-check that there is no overflow */ @@ -1215,15 +1218,15 @@ static Word16 find_last_nz_pair_fx( *-------------------------------------------------------------------*/ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( - Word16 *x, /* Spectral coefficients Q0*/ - const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) Q0*/ - Word16 *lastnz_out, /* Q0 */ - Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring Q0*/ - const Word16 target, /* Target bits Q0*/ - Word16 *stop, /* Q0 */ - Word16 mode, /* Q0 */ - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ -) + Word16 *x, /* Spectral coefficients Q0*/ + const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) Q0*/ + Word16 *lastnz_out, /* Q0 */ + Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring Q0*/ + const Word16 target, /* Target bits Q0*/ + Word16 *stop, /* Q0 */ + Word16 mode, /* Q0 */ + CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ + ) { /* Common variables */ Word16 a1, b1; @@ -1363,7 +1366,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[lev1]; /* ESC symbol */ bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); /* exp(bit_estimate_e) */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane exp(bit_estimate_e) */ + bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane exp(bit_estimate_e) */ a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1451,7 +1454,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( *nEncoded = lastnz2; /* Q0 */ move16(); - *stop = stop2; /* If zero, it means no overflow occured during bit-estimation Q0*/ + *stop = stop2; /* If zero, it means no overflow occured during bit-estimation Q0*/ move16(); *lastnz_out = lastnz; /* Q0 */ move16(); @@ -1512,7 +1515,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( lastnz = add( lastnz, 2 ); /* Q0 */ IF( LT_16( lastnz, 2 ) ) { - lastnz = 2; /* At least one tuple is coded Q0*/ + lastnz = 2; /* At least one tuple is coded Q0*/ move16(); } @@ -1611,37 +1614,37 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); } ELSE /* Overflow */ + { + IF( *stop ){ + *stop = tot_bits2; /* Q0 */ + move16(); + } + ELSE { - IF( *stop ){ - *stop = tot_bits2; /* Q0 */ + *stop = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); /* Q0 */ + move16(); + } + } + + *lastnz_out = lastnz; /* Q0 */ move16(); - } - ELSE - { - *stop = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); /* Q0 */ + *nEncoded = lastnz2; /* Q0 */ move16(); - } -} + /* Safety mechanism to avoid overflow */ + test(); + IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) + { + FOR( k = 0; k < lastnz2; k++ ) + { + x[k] = 0; + move16(); + } + } -*lastnz_out = lastnz; /* Q0 */ -move16(); -*nEncoded = lastnz2; /* Q0 */ -move16(); -/* Safety mechanism to avoid overflow */ -test(); -IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) -{ - FOR( k = 0; k < lastnz2; k++ ) - { - x[k] = 0; - move16(); + return tot_bits2; } } -return tot_bits2; -} -} - /*-------------------------------------------------------------------* * RCcontextMapping_encode2_estimate_bandWise_start_fx() @@ -1669,10 +1672,9 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( move16(); } - hContextMem->bit_estimate_fx = 2; /* Q0 */ - move32(); - hContextMem->bit_estimate_e = Q31; - move16(); + hContextMem->bit_estimate_accu = MAKE_NUMBER_QX(2, Q23 ); + move64(); + /* Init */ @@ -1682,18 +1684,21 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( /* bits to encode lastnz */ k = 1; move16(); + i = 2; + move16(); WHILE( LT_16( k, hContextMem->nt_half ) ) { - hContextMem->bit_estimate_fx = L_add( hContextMem->bit_estimate_fx, 1 ); /* exp(bit_estimate_e) */ - move32(); + hContextMem->bit_estimate_accu = W_add( hContextMem->bit_estimate_accu, MAKE_NUMBER_QX(1, Q23 ) ); + move64(); k = shl( k, 1 ); + i = add( i, 1 ); /* check while condition */ } /* bits to encode lastnz */ - hContextMem->nbits_old = extract_l( hContextMem->bit_estimate_fx ); /* Q0 */ + hContextMem->nbits_old = i; move16(); hContextMem->ctx = 0; @@ -1713,14 +1718,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( BREAK; } } - Word16 tmp2 = extract_l( hContextMem->bit_estimate_fx ); - Word16 tmp = norm_l( hContextMem->bit_estimate_fx ); - hContextMem->bit_estimate_e = sub( Q31, tmp ); - move16(); - hContextMem->bit_estimate_fx = L_shl( hContextMem->bit_estimate_fx, tmp ); /* exp(bit_estimate_e) */ - move32(); - return tmp2; + return hContextMem->nbits_old; } /*-------------------------------------------------------------------* @@ -1777,8 +1776,9 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); /* Q0 */ /* Signs Bits */ - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, imult3216( ONE_IN_Q30, s_min( a1, 1 ) ), Q1, &hContextMem->bit_estimate_e ); /* exp(hContextMem->bit_estimate_e) */ - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, imult3216( ONE_IN_Q30, s_min( b1, 1 ) ), Q1, &hContextMem->bit_estimate_e ); /* exp(hContextMem->bit_estimate_e) */ + hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + move32(); move32(); @@ -1792,11 +1792,13 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( pki = lookup[lev1]; /* Q0 */ move16(); - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], Q8, &hContextMem->bit_estimate_e ); /* exp(hContextMem->bit_estimate_e) */ - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, 2 * ONE_IN_Q29, Q2, &hContextMem->bit_estimate_e ); /* Add the 2 LSB bits that were shifted out exp(hContextMem->bit_estimate_e) */ + hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, MAKE_VARIABLE_QX(2, Q23 ) ); move32(); move32(); + + // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; // hContextMem->bit_estimate += 2; /* Add the 2 LSB bits that were shifted out */ @@ -1809,8 +1811,9 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( pki = lookup[lev1]; /* Q0 */ move16(); - symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol Q0*/ - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], Q8, &hContextMem->bit_estimate_e ); /* exp(bit_estimate_e) */ + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol Q0*/ + hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + move32(); // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; @@ -1830,9 +1833,10 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( move16(); } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( L_shr( hContextMem->bit_estimate_fx, sub( Q15, hContextMem->bit_estimate_e ) ) ); /* Q0 */ + total_output_bits = round_fx( W_shr( hContextMem->bit_estimate_accu, Q7 ) ); /* Q0 */ // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); + bandBits = sub( total_output_bits, hContextMem->nbits_old ); /* Q0 */ hContextMem->nbits_old = total_output_bits; /* Q0 */ move16(); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 0f1c2e906..a3a743509 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -2348,8 +2348,7 @@ typedef struct context_rc_mem_struct { int16_t nbits_old; int16_t ctx; - Word32 bit_estimate_fx; - Word16 bit_estimate_e; + Word64 bit_estimate_accu; int16_t rateFlag; int16_t lastnz; int16_t nt_half; -- GitLab From ba6f7e27c1e7cf4abb7f2cdd755c9afa0fe11ba8 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 10:35:49 +0100 Subject: [PATCH 0089/1221] REMOVE_EVS_DUPLICATES2 --- lib_com/options.h | 1 + lib_dec/acelp_core_dec_fx.c | 15 ++++++++++++++- lib_dec/fd_cng_dec_fx.c | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index c34882a0e..f45ee973d 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,4 +156,5 @@ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ #define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions */ +#define REMOVE_EVS_DUPLICATES2 #endif diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 779df2fa4..46826654e 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -432,7 +432,11 @@ ivas_error acelp_core_dec_fx( } /* update synthesis filter memories */ +#ifdef REMOVE_EVS_DUPLICATES2 + ivas_synth_mem_updt2_fx( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); +#else synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); +#endif #else synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC ); #endif @@ -630,8 +634,11 @@ ivas_error acelp_core_dec_fx( /* decode CNG parameters */ IF( st_fx->cng_type == LP_CNG ) { - +#ifdef REMOVE_EVS_DUPLICATES2 + CNG_dec_ivas_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); +#else CNG_dec_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); +#endif #ifdef IVAS_CODE local_element_mode = st_fx->element_mode; move16(); @@ -684,6 +691,7 @@ ivas_error acelp_core_dec_fx( } } #endif + //generate_comfort_noise_dec_ivas_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 1, nchan_out ); generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); FdCng_exc( st_fx->hFdCngDec->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); @@ -1556,12 +1564,17 @@ ivas_error acelp_core_dec_fx( move32(); } /*Noise estimate*/ +#ifdef REMOVE_EVS_DUPLICATES2 + IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) && !st_fx->cng_ism_flag ) +#else IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) /* && !st->cng_ism_flag IVAS_CODE */ ) +#endif { #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT PMT( "Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done" ) ApplyFdCng_fx( syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else + //ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, realBuffer, imagBuffer, NULL, st_fx, 0, ( st_fx->coder_type == AUDIO && !st_fx->GSC_noisy_speech ) ); ApplyFdCng_fx( syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) ); #endif } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index c683b25b6..0b2682f3a 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -955,7 +955,12 @@ Word16 ApplyFdCng_fx( test(); IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { +#ifdef REMOVE_EVS_DUPLICATES2 + scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); + +#else scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); +#endif } hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; move16(); @@ -1037,8 +1042,13 @@ Word16 ApplyFdCng_fx( IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ +#ifdef REMOVE_EVS_DUPLICATES2 + scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, + hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); +#else scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); +#endif *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); } @@ -1054,8 +1064,13 @@ Word16 ApplyFdCng_fx( /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { +#ifdef REMOVE_EVS_DUPLICATES2 + scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, + hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); +#else scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); +#endif *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); -- GitLab From 6624c8d0d2df51995c6308c396fd23d31a7e587c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Feb 2025 15:28:30 +0530 Subject: [PATCH 0090/1221] Fixed point changes for MR !907 [float fix] port fix for float issue 920 --- lib_com/options.h | 1 + lib_com/prot_fx.h | 5 ++++- lib_enc/core_enc_init.c | 9 ++++++++- lib_enc/core_enc_switch.c | 4 ++++ lib_enc/init_enc.c | 4 ++++ 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 283553640..14e2a45c3 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -152,6 +152,7 @@ #define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ #define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ +#define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index fbd3b27f3..8b76805a2 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -11067,7 +11067,10 @@ void calculate_hangover_attenuation_gain_ivas_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +#ifdef FIX_920_IGF_INIT_ERROR + const Word32 igf_brate, /* i : IGF configuration bitrate */ +#endif + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); void core_coder_reconfig_ivas_fx( diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index 43e93f27c..e98956efe 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -63,7 +63,10 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +#ifdef FIX_920_IGF_INIT_ERROR + const Word32 igf_brate, /* i : IGF configuration bitrate */ +#endif + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ) { TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; @@ -195,7 +198,11 @@ void init_coder_ace_plus_ivas_fx( test(); IF( st->igf && st->hIGFEnc != NULL ) { +#ifdef FIX_920_IGF_INIT_ERROR + IGFEncSetMode_ivas_fx( st->hIGFEnc, igf_brate, st->bwidth, st->element_mode, st->rf_mode ); +#else IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); +#endif } ELSE IF( st->hIGFEnc != NULL ) { diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index e5c3903a1..b6f723c2b 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -229,7 +229,11 @@ void core_coder_mode_switch_ivas_fx( Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); +#ifdef FIX_920_IGF_INIT_ERROR + init_coder_ace_plus_ivas_fx( st, last_total_brate, st->total_brate, MCT_flag ); +#else init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); +#endif if ( st->hLPDmem != NULL ) { st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index edd887afd..7ce9f8ff5 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -1096,7 +1096,11 @@ ivas_error init_encoder_ivas_fx( move16(); /* Initialize ACELP */ #endif +#ifdef FIX_920_IGF_INIT_ERROR + init_coder_ace_plus_ivas_fx( st, st->last_total_brate, igf_brate, 0 ); +#else init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); +#endif IF( st->hLPDmem != NULL ) { -- GitLab From b1d7c629ea30252e06480b979aed8c864b075eb3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Feb 2025 16:15:21 +0530 Subject: [PATCH 0091/1221] Fix for warnings in MSVS --- lib_dec/ivas_svd_dec.c | 4 ++-- lib_enc/cod_tcx.c | 4 ++-- lib_enc/tns_base_enc_fx.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index c8778f99c..77cf192c2 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -1971,11 +1971,11 @@ static Word32 maxWithSign_fx( } #else Word32 result; - if ( a >= 0 ) + IF( a >= 0 ) { result = L_max( a, SVD_MINIMUM_VALUE_FX ); } - if ( a < 0 ) + ELSE { result = L_min( a, -SVD_MINIMUM_VALUE_FX ); } diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 8ddfb573b..963cc1650 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -290,7 +290,7 @@ void TNSAnalysisStereo_fx( Word16 maxEnergyChange_fx; maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ); - IF( GE_16( maxEnergyChange_fx, L_shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) ) + IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) ) { sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); move16(); @@ -552,7 +552,7 @@ void TNSAnalysisStereo_fx( { Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); - IF( GE_16( maxEnergyChange_fx, L_shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) ) + IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) ) { sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); move16(); diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index 90028b732..d1763e039 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -675,7 +675,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur ELSE { maxEnergyChange = GetTCXMaxenergyChange_ivas_fx( hTranDet, isTCX10, NSUBBLOCKS, 3 ); - IF( sub( maxEnergyChange, L_shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) >= 0 ) + IF( sub( maxEnergyChange, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) >= 0 ) { pTnsData->nFilters = add( pTnsData->nFilters, 1 ); -- GitLab From 0a0a50baf43f721019b3d5f55672e05cbd3a547e Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 11 Feb 2025 12:51:54 +0100 Subject: [PATCH 0092/1221] removed bit_estimate_fx and bit_estimate_e from the ACcontextMapping_enc_fx.c completely. --- lib_enc/ACcontextMapping_enc_fx.c | 87 ++++++++++++++----------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 53af78878..2c58b4557 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1230,43 +1230,40 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { /* Common variables */ Word16 a1, b1; - Word16 k, pki, lev1; + Word16 i, k, pki, lev1; UWord16 t; Word16 lastnz, lastnz2; Word16 rateFlag; - Word32 bit_estimate_fx; - Word16 bit_estimate_e; + Word64 bit_estimate_accu; + Word16 symbol; const UWord8 *lookup; - Word32 nbits2_fx; // Q23 - Word16 nbits2_e; + Word64 nbits2_accu; /* Initialization */ - bit_estimate_fx = 2 * ONE_IN_Q29; - bit_estimate_e = 2; - move32(); - move16(); + bit_estimate_accu = MAKE_NUMBER_QX(2, Q23 ); + move64(); - nbits2_fx = 0; - nbits2_e = 0; - move32(); - move16(); + nbits2_accu = 0; + move64(); /* bits to encode lastnz */ k = 1; move16(); + i = 2; + move64(); WHILE( LT_16( k, nt / 2 ) ) { - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ONE_IN_Q30, 1, &bit_estimate_e ); - k = k << 1; + bit_estimate_accu = W_add( bit_estimate_accu, MAKE_NUMBER_QX(1, Q23 ) ); + k = shl( k, 1 ); + i = add( i, 2 ); /* check while condition */ + } - nbits2_fx = bit_estimate_fx; /* exp(bit_estimate_e) */ - nbits2_e = bit_estimate_e; - move32(); - move16(); + nbits2_accu = bit_estimate_accu; + move64(); IF( hm_cfg ) { @@ -1353,9 +1350,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( b1 = (Word16) abs( x[b1_i] ); lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); /* exp(bit_estimate_e) */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); /* exp(bit_estimate_e) */ - + bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); @@ -1365,9 +1361,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { pki = lookup[lev1]; /* ESC symbol */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); /* exp(bit_estimate_e) */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane exp(bit_estimate_e) */ - + bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX(2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1379,10 +1374,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[lev1]; symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], 8, &bit_estimate_e ); /* exp(bit_estimate_e) */ + bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ - IF( GT_32( L_shr( bit_estimate_fx, sub( Q16, bit_estimate_e ) ), L_shl( target, Q15 ) ) ) + IF( GT_32( W_shr( bit_estimate_accu, Q8 ), L_shl( target, Q15 ) ) ) { stop2 = 1; move16(); @@ -1395,10 +1390,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( ELSE { lastnz2 = add( b1_i, 1 ); - nbits2_fx = bit_estimate_fx; - move32(); - nbits2_e = bit_estimate_e; - move16(); + nbits2_accu = bit_estimate_accu; + move64(); } /* Update context for next 2-tuple */ @@ -1439,11 +1432,11 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); /* Q0 */ + total_output_bits = round_fx( W_shr(bit_estimate_accu, Q7 ) ); IF( *stop ) { - total_output_bits = round_fx( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ) ); /* Q0 */ + total_output_bits = round_fx( W_shr( nbits2_accu, Q7 ) ); } IF( stop2 ) @@ -1468,7 +1461,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( hm_cfg->numPeakIndices = numPeakIndicesOrig; /* Q0 */ move16(); - return round_fx( L_add( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ), ONE_IN_Q14 ) ); /* Q0 */ + + return round_fx( L_add( W_shr( nbits2_accu, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ } ELSE /* if (!hm_cfg) */ { @@ -1534,8 +1528,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); rateQ = add( rateFlag, extract_l( GT_16( k, shr( nt, 1 ) ) ) ); /* Q0 */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); /* exp(bit_estimate_e) */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); /* exp(bit_estimate_e) */ + bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ lookup = &ari_lookup_s17_LC[t + shl( rateQ, NBITS_CONTEXT )]; /* Q0 */ @@ -1547,8 +1541,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ move16(); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); /* exp(bit_estimate_e) */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane exp(bit_estimate_e) */ + bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX(2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1563,10 +1557,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], 8, &bit_estimate_e ); /* exp(bit_estimate_e) */ + bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ - IF( GT_32( L_shr( bit_estimate_fx, sub( Q16, bit_estimate_e ) ), L_shl( target, Q15 ) ) ) /* Overflow occured */ + IF( GT_32( W_shr( bit_estimate_accu, Q8 ), L_shl( target, Q15 ) ) ) { overflow_flag = 1; move16(); @@ -1575,10 +1569,9 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { IF( abs_s( x[k] ) || abs_s( x[k + 1] ) ) /* No overflow & non-zero tuple */ { - nbits2_fx = bit_estimate_fx; /* exp(bit_estimate_e) */ - nbits2_e = bit_estimate_e; - move32(); - move16(); + nbits2_accu = bit_estimate_accu; /* exp(bit_estimate_e) */ + move64(); + lastnz2 = add( k, 2 ); } } @@ -1598,7 +1591,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - tot_bits2 = round_fx( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ) ); + tot_bits2 = round_fx( W_shr( nbits2_accu, Q7 ) ); IF( LT_16( lastnz2, lastnz ) ) /* Overflow occured because unable to code all tuples */ { overflow_flag = 1; @@ -1606,7 +1599,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } IF( EQ_16( mode, -1 ) ) { - tot_bits2 = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); /* Q0 */ + tot_bits2 = round_fx( W_shr( bit_estimate_accu, Q7 ) ); } IF( overflow_flag == 0 ) /* No overflow */ { @@ -1621,7 +1614,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } ELSE { - *stop = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); /* Q0 */ + *stop = round_fx( W_shr( bit_estimate_accu, Q7 ) ); move16(); } } -- GitLab From 3241b0c1448ff4da5a680ef8e0c7c026c905b809 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 13:10:14 +0100 Subject: [PATCH 0093/1221] REMOVE_EVS_DUPLICATES2 --- lib_dec/acelp_core_dec_fx.c | 129 ++++++++++++++++++++++++++++++++++-- lib_dec/fd_cng_dec_fx.c | 45 +++++++++++-- 2 files changed, 164 insertions(+), 10 deletions(-) diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 46826654e..db6ba759d 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -661,7 +661,7 @@ ivas_error acelp_core_dec_fx( test(); IF( EQ_32( st_fx->core_brate, SID_2k40 ) && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { - FdCng_decodeSID_fx( st_fx->hFdCngDec->hFdCngCom, st_fx ); + FdCng_decodeSID_fx( st_fx->hFdCngDec->hFdCngCom, st_fx ); // VE: 2 variants needed *sid_bw = 0; move16(); } @@ -691,8 +691,7 @@ ivas_error acelp_core_dec_fx( } } #endif - //generate_comfort_noise_dec_ivas_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 1, nchan_out ); - generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); + generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); // VE: 2 variants needed FdCng_exc( st_fx->hFdCngDec->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); @@ -709,10 +708,29 @@ ivas_error acelp_core_dec_fx( } i = st_fx->Q_exc; move16(); +#ifdef REMOVE_EVS_DUPLICATES2 + test(); + IF( st_fx->hMusicPF && st_fx->hGSCDec ) + { + Rescale_exc( st_fx->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, + imult1616( st_fx->L_frame, HIBND_ACB_L_FAC ), 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); + } + IF( st_fx->hPFstat != NULL ) + { + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, + &st_fx->mem_deemph_fx, st_fx->hBPF->pst_old_syn_fx, &st_fx->hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); + } + ELSE + { + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, + &st_fx->mem_deemph_fx, NULL, NULL, &st_fx->agc_mem_fx[1], NULL, 0, 0, NULL ); + } +#else Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); +#endif Copy_Scale_sig( exc2_fx, exc2_fx, st_fx->L_frame, sub( st_fx->Q_exc, i ) ); // Q_exc /* update past excitation signals for LD music post-filter */ @@ -725,7 +743,7 @@ ivas_error acelp_core_dec_fx( FOR( i = 0; i < DCT_L_POST; i++ ) { /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); + hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); // VE: 2 variants needed move16(); } } @@ -1574,8 +1592,11 @@ ivas_error acelp_core_dec_fx( PMT( "Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done" ) ApplyFdCng_fx( syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else - //ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, realBuffer, imagBuffer, NULL, st_fx, 0, ( st_fx->coder_type == AUDIO && !st_fx->GSC_noisy_speech ) ); +#ifdef REMOVE_EVS_DUPLICATES2 + ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, realBuffer, imagBuffer, NULL, st_fx, 0, ( st_fx->coder_type == AUDIO && !st_fx->GSC_noisy_speech ) ); +#else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) ); +#endif #endif } /* CNA: Generate additional comfort noise to mask potential coding artefacts */ @@ -1759,6 +1780,82 @@ ivas_error acelp_core_dec_fx( bass_psfilter_fx( st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, st_fx->L_frame, pitch_buf_fx, st_fx->bpf_off, st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, st_fx->coder_type, st_fx->Q_syn, bpf_error_signal ); } + +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + /* analysis of the synthesis at internal sampling rate */ + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); + + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + /* analysis and add the BPF error signal */ + i = 0; + move16(); + if ( st_fx->bpf_off == 0 ) + { + i = CLDFB_NO_COL_MAX; + move16(); + } + + addBassPostFilter_fx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate( st_fx->Q_syn ), + i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor ); + + /* set output mask for upsampling */ + IF( EQ_16( st_fx->bwidth, NB ) ) + { + /* set NB mask for upsampling */ + st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, 10 ); + move16(); + } + ELSE IF( NE_16( st_fx->cldfbSyn->bandsToZero, sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ) ) ) + { + /* in case of BW switching, re-init to default */ + st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ); + move16(); + } + + /*WB/SWB-FD_CNG*/ + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + test(); + IF( !st_fx->cng_sba_flag || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + test(); + test(); + test(); + IF( ( ( st_fx->core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) && ( EQ_16( st_fx->cng_type, FD_CNG ) ) && ( LT_16( st_fx->hFdCngDec->hFdCngCom->numCoreBands, st_fx->cldfbSyn->no_channels ) ) ) + { + generate_comfort_noise_dec_hf_fx( realBuffer, imagBuffer, &scaleFactor.hb_scale, st_fx ); + + st_fx->cldfbSyn->bandsToZero = 0; + move16(); + IF( LT_16( st_fx->hFdCngDec->hFdCngCom->regularStopBand, st_fx->cldfbSyn->no_channels ) ) + { + st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->hFdCngDec->hFdCngCom->regularStopBand ); + move16(); + } + st_fx->cldfbSyn->lsb = st_fx->cldfbAna->no_channels; + move16(); + } + } + + /* synthesis of the combined signal */ + st_fx->Q_syn2 = st_fx->Q_syn; + move16(); + cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); + + /* Bring CLDFB output to Q0 */ + Scale_sig( synth_out, output_frame, negate( st_fx->Q_syn2 ) ); + st_fx->Q_syn2 = 0; + move16(); + + /* save synthesis - needed in case of core switching */ + Copy( synth_out, st_fx->previoussynth_fx, output_frame ); + } +#else test(); IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) { @@ -1881,6 +1978,7 @@ ivas_error acelp_core_dec_fx( /* save synthesis - needed in case of core switching */ Copy( synth_out, st_fx->previoussynth_fx, output_frame ); } +#endif #ifdef IVAS_CODE ELSE { @@ -1924,13 +2022,34 @@ ivas_error acelp_core_dec_fx( IF( ( EQ_16( st_fx->L_frame, L_FRAME ) && NE_16( st_fx->bwidth, NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st_fx->extl, -1 ) || EQ_16( st_fx->extl, SWB_CNG ) || ( EQ_16( st_fx->extl, WB_BWE ) && st_fx->extl_brate == 0 && NE_16( st_fx->coder_type, AUDIO ) ) ) ) ) { +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, + st_fx->Q_syn2, st_fx->hBWE_zero->delay_syn_hf_fx, &st_fx->hBWE_zero->memExp1, st_fx->hBWE_zero->mem_hp_interp_fx, st_fx->extl, st_fx->CNG_mode ); + } + ELSE + { + hf_synth_reset_fx( st_fx->hBWE_zero ); + } +#else hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, st_fx->Q_syn2, st_fx->hBWE_zero->delay_syn_hf_fx, &st_fx->hBWE_zero->memExp1, st_fx->hBWE_zero->mem_hp_interp_fx, st_fx->extl, st_fx->CNG_mode ); + +#endif } +#ifdef REMOVE_EVS_DUPLICATES2 ELSE { hf_synth_reset_fx( st_fx->hBWE_zero ); +#ifdef MSAN_FIX + IF( NE_16( st_fx->element_mode, EVS_MONO ) ) // TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact + { + set16_fx( st_fx->hBWE_zero->mem_hp400_fx, 0, 6 ); + } +#endif } +#endif } /*-----------------------------------------------------------------* diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 0b2682f3a..7b4eef9f2 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -957,7 +957,6 @@ Word16 ApplyFdCng_fx( { #ifdef REMOVE_EVS_DUPLICATES2 scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); - #else scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); #endif @@ -1279,7 +1278,16 @@ Word16 ApplyFdCng_ivas_fx( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ - perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); + } + ELSE +#endif + { + perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); + } /* Update the shaping parameters */ test(); @@ -1522,7 +1530,16 @@ Word16 ApplyFdCng_ivas_fx( IF( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ - perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); + } + ELSE +#endif + { + perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); + } } } @@ -1580,7 +1597,16 @@ Word16 ApplyFdCng_ivas_fx( IF( st != NULL && EQ_16( st->cng_type, LP_CNG ) ) { /* Perform noise estimation on inactive phase at the decoder */ - perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); + } + ELSE +#endif + { + perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); + } /* Update the shaping parameters */ @@ -1833,7 +1859,16 @@ Word16 ApplyFdCng_ivas_fx( IF( EQ_16( st->codec_mode, MODE2 ) ) { /* Generate comfort noise during SID or zero frames */ - generate_comfort_noise_dec_ivas_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + generate_comfort_noise_dec_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); + } + ELSE +#endif + { + generate_comfort_noise_dec_ivas_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); + } } BREAK; -- GitLab From ee29e3294f378e60e425a50e62ffa1b2875de886 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 13:54:52 +0100 Subject: [PATCH 0094/1221] fix --- lib_dec/fd_cng_dec_fx.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 7b4eef9f2..bf10d9c17 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -955,11 +955,7 @@ Word16 ApplyFdCng_fx( test(); IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { -#ifdef REMOVE_EVS_DUPLICATES2 - scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); -#else scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); -#endif } hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; move16(); @@ -1041,13 +1037,8 @@ Word16 ApplyFdCng_fx( IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ -#ifdef REMOVE_EVS_DUPLICATES2 - scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, - hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); -#else scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); -#endif *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); } @@ -1063,14 +1054,8 @@ Word16 ApplyFdCng_fx( /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { -#ifdef REMOVE_EVS_DUPLICATES2 - scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, - hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); -#else scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); -#endif - *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); } -- GitLab From 5e2edf84fe18ea27bb9d8c91ff2d6f0e7ffcd9cb Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 14:34:33 +0100 Subject: [PATCH 0095/1221] fix --- lib_dec/amr_wb_dec_fx.c | 8 ++++++++ lib_dec/evs_dec_fx.c | 4 ++++ lib_dec/fd_cng_dec_fx.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index d45655903..b3fbc0233 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -374,7 +374,11 @@ ivas_error amr_wb_dec_fx( IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_1k75 ) ) { /* decode CNG parameters */ +#ifdef REMOVE_EVS_DUPLICATES2 + CNG_dec_ivas_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); +#else CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); +#endif /* comfort noise generation */ CNG_exc_fx( st_fx->core_brate, L_FRAME, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, @@ -795,8 +799,12 @@ ivas_error amr_wb_dec_fx( #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT PMT( "Fixed point not done here " ) ApplyFdCng_fx( syn, NULL, NULL, NULL, st, 0, 0 ); +#else +#ifdef REMOVE_EVS_DUPLICATES2 + ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 ); #else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, NULL, NULL, st_fx, 0, 0 ); +#endif #endif st_fx->hFdCngDec->hFdCngCom->frame_type_previous = st_fx->m_frame_type; move16(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index de6448433..fee893c4b 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -999,8 +999,12 @@ ivas_error evs_dec_fx( move32(); #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT ApplyFdCng_fx( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); +#else +#ifdef REMOVE_EVS_DUPLICATES2 + ApplyFdCng_ivas_fx( output_sp, 0, NULL, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); #else ApplyFdCng_fx( output_sp, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); +#endif #endif /* Generate additional comfort noise to mask potential coding artefacts */ test(); diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index bf10d9c17..0fba4e644 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1276,7 +1276,14 @@ Word16 ApplyFdCng_ivas_fx( /* Update the shaping parameters */ test(); - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); + } + ELSE +#endif + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } @@ -1596,7 +1603,14 @@ Word16 ApplyFdCng_ivas_fx( /* Update the shaping parameters */ test(); - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); + } + ELSE +#endif + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } @@ -1675,8 +1689,16 @@ Word16 ApplyFdCng_ivas_fx( IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ - scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, - hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); + } + ELSE +#endif + { + scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); + } *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); } -- GitLab From fd003f8c14898f23130026e71cdcd51fa57cf44c Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 11 Feb 2025 14:53:41 +0100 Subject: [PATCH 0096/1221] improve high complexity of param_mc_prm_est: MC/7-1-4/128kBit reduced by 166 WMOPS --- lib_com/options.h | 1 + lib_enc/ivas_mc_param_enc.c | 83 +++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 1b2c15f87..11a10b5b0 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,4 +154,5 @@ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ #endif diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 0577df340..e3eb59445 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -723,9 +723,16 @@ static void ivas_param_mc_param_est_enc_fx( } } +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + Word16 gb = find_guarded_bits_fx( l_ts ); + Word16 add20gb = add( 20, gb ); +#endif + FOR( ts = start_ts; ts < num_time_slots; ts++ ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST Word16 gb = find_guarded_bits_fx( l_ts ); +#endif ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb ); ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans ); @@ -810,10 +817,25 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); +#else + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e); + a_e = sub(add20gb, a_e); + b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); + b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); + b_e = sub( add20gb, b_e ); + c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); + c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); + c_e = sub( add20gb, c_e ); + d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); + d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); + d_e = sub( add20gb, d_e ); +#endif /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); @@ -844,6 +866,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST dmx_real_fx[ch_idx1] = 0; move32(); dmx_real_e[ch_idx1] = 0; @@ -863,13 +886,49 @@ static void ivas_param_mc_param_est_enc_fx( move32(); p_dmx_fac_fx++; } +#else + Word32 real_fx = L_add(0, 0); + Word16 real_e = 0; + move16(); + Word32 imag_fx = L_add( 0, 0 ); + Word16 imag_e = 0; + move16(); + + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e ); + L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add( 20, gb ), &imag_e ); + p_dmx_fac_fx++; + } + dmx_real_fx[ch_idx1] = real_fx; + move32(); + dmx_real_e[ch_idx1] = real_e; + move16(); + dmx_imag_fx[ch_idx1] = imag_fx; + move32(); + dmx_imag_e[ch_idx1] = imag_e; + move16(); +#endif } /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + a_fx = dmx_real_fx[ch_idx1]; + move32(); + a_e = dmx_real_e[ch_idx1]; + move16(); + b_fx = dmx_imag_fx[ch_idx1]; + move32(); + b_e = dmx_imag_e[ch_idx1]; + move16(); +#endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -891,6 +950,12 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); +#else + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, dmx_real_fx[ch_idx2] ), add( a_e, dmx_real_e[ch_idx2] ), Mpy_32_32( b_fx, dmx_imag_fx[ch_idx2] ), add( b_e, dmx_imag_e[ch_idx2] ), &tmp_e ); + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, + &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); +#endif move32(); } } @@ -898,12 +963,30 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); + a_e = sub( add20gb, a_e ); + b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); + b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); + b_e = sub( add20gb, b_e ); +#endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); +#else + + c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); + c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); + c_e = sub( add20gb, c_e ); + d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); + d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); + d_e = sub( add20gb, d_e ); +#endif /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); -- GitLab From 5826482915088a6b53715c625a974c00d21004a1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 15:19:24 +0100 Subject: [PATCH 0097/1221] fix --- lib_dec/fd_cng_dec_fx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 0fba4e644..af670f0d0 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1711,8 +1711,16 @@ Word16 ApplyFdCng_ivas_fx( /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { - scalebands_fx( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, - hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); + } + ELSE +#endif + { + scalebands_fx( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); + } *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); -- GitLab From 31ef1423be708164aeae8527d161e4098115f331 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 11 Feb 2025 15:26:46 +0100 Subject: [PATCH 0098/1221] fix clang-fomat-issues --- lib_enc/ivas_mc_param_enc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index e3eb59445..438451ceb 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -823,9 +823,9 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); #else - a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]); - a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e); - a_e = sub(add20gb, a_e); + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); + a_e = sub( add20gb, a_e ); b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); b_e = sub( add20gb, b_e ); @@ -887,7 +887,7 @@ static void ivas_param_mc_param_est_enc_fx( p_dmx_fac_fx++; } #else - Word32 real_fx = L_add(0, 0); + Word32 real_fx = L_add( 0, 0 ); Word16 real_e = 0; move16(); Word32 imag_fx = L_add( 0, 0 ); -- GitLab From e8fa2b8809206c5783edfbecea256352e97d28f3 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 15:52:56 +0100 Subject: [PATCH 0099/1221] fix --- lib_dec/acelp_core_dec_fx.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index db6ba759d..3a96a6225 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -712,8 +712,19 @@ ivas_error acelp_core_dec_fx( test(); IF( st_fx->hMusicPF && st_fx->hGSCDec ) { - Rescale_exc( st_fx->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, - imult1616( st_fx->L_frame, HIBND_ACB_L_FAC ), 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + // VE: TBV: 'st_fx->L_frame * HIBND_ACB_L_FAC' should be corrected + Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, + st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); + } + ELSE +#endif + { + Rescale_exc( st_fx->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, + imult1616( st_fx->L_frame, HIBND_ACB_L_FAC ), 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); + } } IF( st_fx->hPFstat != NULL ) { @@ -2043,7 +2054,7 @@ ivas_error acelp_core_dec_fx( { hf_synth_reset_fx( st_fx->hBWE_zero ); #ifdef MSAN_FIX - IF( NE_16( st_fx->element_mode, EVS_MONO ) ) // TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact + IF( NE_16( st_fx->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact { set16_fx( st_fx->hBWE_zero->mem_hp400_fx, 0, 6 ); } -- GitLab From 6a7ac819038756057abfb40442ed4fb0db30067a Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 4 Feb 2025 16:14:11 +0100 Subject: [PATCH 0100/1221] port issue 1264: Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA; under NONBE_FIX_GSC_BSTR --- lib_com/bits_alloc_fx.c | 106 +++++++++++++++++++++++------ lib_com/gs_inact_switching_fx.c | 24 ++++--- lib_com/options.h | 1 + lib_com/prot.h | 29 -------- lib_com/prot_fx.h | 88 +++++++++++++----------- lib_dec/FEC_fx.c | 8 +++ lib_dec/acelp_core_dec_fx.c | 9 ++- lib_dec/acelp_core_dec_ivas_fx.c | 17 +++++ lib_dec/acelp_core_switch_dec_fx.c | 6 ++ lib_dec/dec_gen_voic_fx.c | 4 ++ lib_dec/gs_dec_fx.c | 16 +++++ lib_enc/acelp_core_enc_fx.c | 25 +++++++ lib_enc/acelp_core_switch_enc_fx.c | 10 +++ lib_enc/enc_gen_voic_fx.c | 4 ++ lib_enc/ivas_core_pre_proc.c | 4 ++ lib_enc/transition_enc_fx.c | 16 +++++ 16 files changed, 265 insertions(+), 102 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 83a98a85f..7713865a4 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -762,17 +762,20 @@ static ivas_error acelp_FCB_allocator_ivas( *--------------------------------------------------------------------*/ ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -1075,7 +1078,11 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && !inactive_coder_type_flag ) ) +#else IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, -1, -1 )]; move16(); @@ -1196,7 +1203,11 @@ ivas_error config_acelp1( { test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ +#else IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -1414,7 +1425,11 @@ ivas_error config_acelp1( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) +#else ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) +#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -1478,7 +1493,11 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) +#else IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1587,7 +1606,11 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) +#else IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1627,7 +1650,11 @@ ivas_error config_acelp1( } } } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && inactive_coder_type_flag ) ) +#else ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -1768,7 +1795,11 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ +#else IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ubits = 0; move16(); @@ -1877,17 +1908,20 @@ ivas_error config_acelp1( *--------------------------------------------------------------------*/ ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -2169,7 +2203,11 @@ ivas_error config_acelp1_IVAS( test(); test(); /* gain Q bit-budget - part 1 */ +#ifdef NONBE_FIX_GSC_BSTR + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && !inactive_coder_type_flag ) ) +#else IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && ( coder_type != INACTIVE ) && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( ( coder_type == INACTIVE ) && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, -1 )]; move16(); @@ -2294,7 +2332,11 @@ ivas_error config_acelp1_IVAS( { test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ +#else IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -2510,7 +2552,11 @@ ivas_error config_acelp1_IVAS( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) +#else ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) +#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -2574,7 +2620,11 @@ ivas_error config_acelp1_IVAS( test(); test(); /* algebraic codebook bit-budget */ +#ifdef NONBE_FIX_GSC_BSTR + IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) +#else IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2675,7 +2725,11 @@ ivas_error config_acelp1_IVAS( test(); test(); /* AVQ codebook */ +#ifdef NONBE_FIX_GSC_BSTR + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) +#else IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2713,7 +2767,11 @@ ivas_error config_acelp1_IVAS( } } } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && inactive_coder_type_flag ) ) +#else ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -2854,7 +2912,11 @@ ivas_error config_acelp1_IVAS( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ +#else IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ubits = 0; move16(); diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 5dfe6b1d6..c0feb91f5 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -162,15 +162,17 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 total_brate, /* i : total bit rate */ - const Word16 Q_exc /* i : input and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode /* i : Last codec mode */ - , +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif + const Word16 L_frame, /* i : Frame lenght */ +#ifndef NONBE_FIX_GSC_BSTR + const Word32 total_brate, /* i : total bit rate */ +#endif + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ const Word16 element_mode /* i : element mode */ ) @@ -222,7 +224,11 @@ void Inac_switch_ematch_ivas_fx( move16(); } } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( coder_type == INACTIVE ) && inactive_coder_type_flag ) +#else ELSE IF( ( coder_type == INACTIVE ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) +#endif { /* Find spectrum and energy per band for inactive frames */ edct_16fx( exc2, dct_exc_tmp, L_frame, 5, element_mode ); diff --git a/lib_com/options.h b/lib_com/options.h index 33cfc8d16..50f691903 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,6 +141,7 @@ #define NONBE_1211_DTX_BR_SWITCHING /* VA: port float issue 1211: fix crash in MASA DTX bitrate switching */ #define FIX_1189_GSC_IVAS_OMASA /* VA: Fix for issue 1189: Bitstream desynchornization due to reading/writing of the GSC_IVAS_mode parameter */ #define NONBE_1273_ISM_METADATA_COUNTER /* VA: BASOP issue 1265, FLP issue 1273: fix counter overflow in ISM metadata encoder */ +#define NONBE_FIX_GSC_BSTR /* VA: issue 1264 FLP (1189 BASOP): Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA */ #define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF /* FhG: fix for issue 1101: complexity of spar dec upmixer */ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ #define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS /* FhG: Defines 1.0f-weight variables, uses Madd operation instead of L_add_sat */ diff --git a/lib_com/prot.h b/lib_com/prot.h index a2a2cdac3..647a18bf1 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -7461,35 +7461,6 @@ int16_t BITS_ALLOC_config_acelp_IVAS( const int16_t nb_subfr /* i : number of subframes */ ); -ivas_error config_acelp1_IVAS( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t core_brate_inp, /* i : core bitrate */ - const int16_t core, /* i : core */ - const int16_t extl, /* i : extension layer */ - const int32_t extl_brate, /* i : extension layer bitrate */ - const int16_t L_frame, /* i : frame length at internal Fs */ - const int16_t GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const int16_t signaling_bits, /* i : number of signaling bits */ - const int16_t coder_type, /* i : coder type */ - const int16_t tc_subfr, /* i : TC subfr ID */ - const int16_t tc_call, /* i : TC call number (0,1,2) */ - int16_t *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - int16_t *unbits, /* o : number of unused bits */ - const int16_t element_mode, /* i : element mode */ - int16_t *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel*/ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const int16_t idchan, /* i : channel id */ - const int16_t active_cnt, /* i : Active frame counter */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int16_t GSC_IVAS_mode /* i : GSC IVAS mode */ -); - -/*! r: ACELP16k flag */ - void FEC_clas_estim( const float *syn, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 8b76805a2..9fae6a1c1 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4777,17 +4777,20 @@ Word16 BITS_ALLOC_config_acelp( const Word16 nb_subfr ); ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -5764,16 +5767,14 @@ void tcx_ltp_post32( // gs_inact_switching_fx.c void Inac_swtch_ematch_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 core_brate, /* i : Core bit rate */ - const Word16 Q_exc /* i : i and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word32 core_brate, /* i : Core bit rate */ + const Word16 Q_exc, /* i : i and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ const short last_core, /* i : Last core used */ const short last_codec_mode /* i : Last codec mode */ ); @@ -5783,15 +5784,17 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 core_brate, /* i : Core bit rate */ - const Word16 Q_exc /* i : input and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode /* i : Last codec mode */ - , +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif + const Word16 L_frame, /* i : Frame lenght */ +#ifndef NONBE_FIX_GSC_BSTR + const Word32 core_brate, /* i : Core bit rate */ +#endif + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ const Word16 element_mode /* i : element mode */ ); @@ -10990,17 +10993,20 @@ void lsf_syn_mem_backup_ivas_fx( Word16 *pstreaklen ); ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index 0686996f3..35bb254af 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -504,7 +504,11 @@ void FEC_exc_estim_fx( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) +#else IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) ) +#endif { st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag; move16(); @@ -666,7 +670,11 @@ void FEC_exc_estim_fx( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) +#else IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) +#endif { /* For GSC - the excitation is already computed */ Copy( exc, exc2, st_fx->L_frame ); diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index a41a0c813..1b2207491 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -777,14 +777,21 @@ ivas_error acelp_core_dec_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); - +#endif test(); test(); IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) { +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, TRANSITION, -1, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif } } diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 24427c5d2..0914e7ece 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -830,12 +830,21 @@ ivas_error acelp_core_dec_ivas_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, st->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif + test(); test(); IF( EQ_16( st->coder_type, TRANSITION ) && LT_16( tc_subfr, L_SUBFR ) && EQ_16( st->L_frame, L_FRAME ) ) { +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, TRANSITION, -1, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif } } @@ -1106,7 +1115,11 @@ ivas_error acelp_core_dec_ivas_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ +#ifdef NONBE_FIX_GSC_BSTR + Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#else Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#endif /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames @@ -1313,7 +1326,11 @@ ivas_error acelp_core_dec_ivas_fx( } /* Apply energy matching when switching to inactive frames */ +#ifdef NONBE_FIX_GSC_BSTR + Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#else Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#endif /* update past excitation signals for LD music post-filter */ IF( st->hMusicPF != NULL ) diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index f347cdb7e..387533957 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -128,7 +128,13 @@ ivas_error acelp_core_switch_dec_fx( /*----------------------------------------------------------------* * Excitation decoding *----------------------------------------------------------------*/ + +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); +#else config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); +#endif + decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); /*----------------------------------------------------------------* diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 1abd3d58b..bdfac224f 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -693,7 +693,11 @@ ivas_error decod_gen_voic_ivas_fx( * Transform domain contribution decoding *-----------------------------------------------------------------*/ test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( !st_fx->inactive_coder_type_flag && st_fx->coder_type == INACTIVE ) +#else IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( st_fx->coder_type == INACTIVE ) ) +#endif { transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); } diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index c237bc987..3a39f9e33 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -96,12 +96,22 @@ void decod_audio_fx( st_fx->GSC_noisy_speech = 0; /* Q0 */ move16(); } + /* set bit-allocation */ #ifdef ADD_LRTD +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif +#else +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif +#endif + /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ @@ -600,12 +610,18 @@ void decod_audio_ivas_fx( st_fx->GSC_noisy_speech = 0; move16(); } + /* set bit-allocation */ #if 1 // def ADD_LRTD +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif + /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index b9310dead..260934aca 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -402,7 +402,11 @@ ivas_error acelp_core_enc_fx( IF( !nelp_mode && !ppp_mode ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, +#else st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, +#endif tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -538,7 +542,11 @@ ivas_error acelp_core_enc_fx( tc_classif_enc_fx( Q_new, st_fx->L_frame, &tc_subfr_fx, &position, attack_flag, st_fx->pitch[0], res_fx ); config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, +#ifdef NONBE_FIX_GSC_BSTR + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, +#else -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, +#endif tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -605,7 +613,11 @@ ivas_error acelp_core_enc_fx( /* Configure ACELP bit allocation */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, +#ifdef NONBE_FIX_GSC_BSTR + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, +#else -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, +#endif st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /* redo LSF quantization */ @@ -1267,7 +1279,11 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( !nelp_mode && !ppp_mode ) { +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif } /*-----------------------------------------------------------------* @@ -1404,7 +1420,11 @@ ivas_error acelp_core_enc_ivas_fx( { tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif } /*---------------------------------------------------------------* @@ -1461,8 +1481,13 @@ ivas_error acelp_core_enc_ivas_fx( { /* restore memories of LSF quantizer and synthesis filter */ lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); + /* Configure ACELP bit allocation */ +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif /* redo LSF quantization */ lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL, Q_new ); diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index d521d85a2..47c735a85 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -148,8 +148,13 @@ void acelp_core_switch_enc_fx( /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ + config_acelp1( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, +#ifdef NONBE_FIX_GSC_BSTR + GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#else GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#endif encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); @@ -271,8 +276,13 @@ void acelp_core_switch_enc_ivas_fx( /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ + config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, +#ifdef NONBE_FIX_GSC_BSTR + GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#else GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#endif encod_gen_voic_core_switch_ivas_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 6f71b8ba1..96e7e274c 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -661,7 +661,11 @@ void encod_gen_voic_ivas_fx( *-----------------------------------------------------------------*/ test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( !st_fx->inactive_coder_type_flag && EQ_16( st_fx->coder_type, INACTIVE ) ) +#else IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && EQ_16( st_fx->coder_type, INACTIVE ) ) +#endif { transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr_fx, cn_fx, exc_fx, p_Aq_fx, p_Aw_fx, h1_fx, xn_fx, xn2_fx, y1_fx, y2_fx, Es_pred_fx, &gain_pit_fx, gain_code_fx, g_corr_fx, clip_gain_fx, &gain_preQ_fx, code_preQ_fx, unbits_fx, Q_new, shift ); diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 541cc620c..31b14ed10 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -284,7 +284,11 @@ ivas_error pre_proc_ivas_fx( } ELSE IF( GT_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( ( st->vad_flag == 0 && GE_16( st->bwidth, SWB ) && GE_16( st->max_bwidth, SWB ) ) || ( st->localVAD == 0 && ( LE_16( st->bwidth, WB ) || LE_16( st->max_bwidth, WB ) ) ) ) ) { +#ifdef NONBE_FIX_GSC_BSTR + /* inactive frames will be coded by AVQ technology (exceptionally it can be later rewritten to GSC technology in ivas_combined_format_brate_sanity()) */ +#else /* inactive frames will be coded by AVQ technology */ +#endif st->coder_type = INACTIVE; move16(); } diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 02372138d..0089fc745 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -214,7 +214,11 @@ void transition_enc_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, +#else L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, +#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -326,7 +330,11 @@ void transition_enc_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, +#else st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, +#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* @@ -1035,7 +1043,11 @@ void transition_enc_ivas_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, +#else L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, +#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -1147,7 +1159,11 @@ void transition_enc_ivas_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, +#else st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, +#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* -- GitLab From 12785e1f46ea03c6679a230eb6dd6a26214d2c27 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Feb 2025 10:13:11 +0100 Subject: [PATCH 0101/1221] restore EVS BE - add missing logic into the decision matrix --- lib_dec/decision_matrix_dec_fx.c | 15 +++++++++++++++ lib_enc/decision_matrix_enc_fx.c | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index 9c0020223..a83de038a 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -713,5 +713,20 @@ void decision_matrix_dec_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + /*-----------------------------------------------------------------* + * set inactive coder_type flag in ACELP core + *-----------------------------------------------------------------*/ + + st->inactive_coder_type_flag = 0; /* AVQ by default */ + move16(); + + if ( LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + { + st->inactive_coder_type_flag = 1; /* GSC */ + move16(); + } + +#endif return; } diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index 2ebb7289a..3624cf374 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -386,6 +386,21 @@ void decision_matrix_enc_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + /*-----------------------------------------------------------------* + * set inactive coder_type flag in ACELP core + *-----------------------------------------------------------------*/ + + st_fx->inactive_coder_type_flag = 0; /* AVQ by default */ + move16(); + + if ( LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + { + st_fx->inactive_coder_type_flag = 1; /* GSC */ + move16(); + } + +#endif return; } -- GitLab From b490057bad71b85e0de24b77dec4b2bfc36c6acf Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Feb 2025 16:39:14 +0100 Subject: [PATCH 0102/1221] add comments --- lib_com/bits_alloc_fx.c | 48 +++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 7713865a4..f2a074ba5 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -1071,7 +1071,7 @@ ivas_error config_acelp1( { bits = sub( bits, TDM_IC_LSF_PRED_BITS ); } - /* gain Q bit-budget - part 1 */ + /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ test(); test(); test(); @@ -1079,7 +1079,9 @@ ivas_error config_acelp1( test(); test(); #ifdef NONBE_FIX_GSC_BSTR - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && !inactive_coder_type_flag ) ) + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || + ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ + ) #else IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) #endif @@ -1426,7 +1428,10 @@ ivas_error config_acelp1( move16(); } #ifdef NONBE_FIX_GSC_BSTR - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || /* @12.8kHz core except of GSC */ + ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || + EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ + ) #else ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) #endif @@ -1494,7 +1499,9 @@ ivas_error config_acelp1( test(); test(); #ifdef NONBE_FIX_GSC_BSTR - IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) + IF( flag_hardcoded /* EVS */ || + ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) #else IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) #endif @@ -1607,7 +1614,8 @@ ivas_error config_acelp1( test(); test(); #ifdef NONBE_FIX_GSC_BSTR - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) #else IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) #endif @@ -1651,7 +1659,9 @@ ivas_error config_acelp1( } } #ifdef NONBE_FIX_GSC_BSTR - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && inactive_coder_type_flag ) ) + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || + ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || + ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) #else ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) #endif @@ -1796,7 +1806,8 @@ ivas_error config_acelp1( test(); test(); #ifdef NONBE_FIX_GSC_BSTR - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || + ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ #else IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ #endif @@ -2202,9 +2213,10 @@ ivas_error config_acelp1_IVAS( test(); test(); test(); - /* gain Q bit-budget - part 1 */ + /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ #ifdef NONBE_FIX_GSC_BSTR - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && !inactive_coder_type_flag ) ) + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || + ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) #else IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && ( coder_type != INACTIVE ) && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( ( coder_type == INACTIVE ) && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) #endif @@ -2553,7 +2565,9 @@ ivas_error config_acelp1_IVAS( move16(); } #ifdef NONBE_FIX_GSC_BSTR - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) /* @12.8kHz core except of GSC */ || + ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || + EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ ) #else ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) #endif @@ -2621,7 +2635,9 @@ ivas_error config_acelp1_IVAS( test(); /* algebraic codebook bit-budget */ #ifdef NONBE_FIX_GSC_BSTR - IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) + IF( flag_hardcoded /* EVS */ || + ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) #else IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) #endif @@ -2726,7 +2742,8 @@ ivas_error config_acelp1_IVAS( test(); /* AVQ codebook */ #ifdef NONBE_FIX_GSC_BSTR - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( !inactive_coder_type_flag && coder_type == INACTIVE ) ) + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) #else IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) #endif @@ -2768,7 +2785,9 @@ ivas_error config_acelp1_IVAS( } } #ifdef NONBE_FIX_GSC_BSTR - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && inactive_coder_type_flag ) ) + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || + ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || + ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) #else ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) #endif @@ -2913,7 +2932,8 @@ ivas_error config_acelp1_IVAS( test(); test(); #ifdef NONBE_FIX_GSC_BSTR - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || + ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ #else IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ #endif -- GitLab From 10a43bc1c02ec1b64d8b62c2db381c03ca077fcb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Feb 2025 21:39:09 +0530 Subject: [PATCH 0103/1221] Fix for 3GPP issue 1278: Bug in ACELP unvoiced (UC) frames decoding Link #1278 --- lib_dec/dec_uv_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index ffb49be38..1c03a1cdd 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -255,9 +255,9 @@ void decod_unvoiced_ivas_fx( Word16 tmp_idx; tmp_idx = 0; move16(); - if ( i_subfr_fx != 0 ) + IF ( i_subfr_fx != 0 ) { - idiv1616( i_subfr_fx, L_SUBFR ); + tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); } voice_factors_fx[tmp_idx] = 0; move16(); -- GitLab From 6df96a3003aa59443dfcc63435bdf979fb059150 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Feb 2025 21:42:24 +0530 Subject: [PATCH 0104/1221] Clang formatting changes --- lib_dec/dec_uv_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index 1c03a1cdd..aa898956a 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -255,7 +255,7 @@ void decod_unvoiced_ivas_fx( Word16 tmp_idx; tmp_idx = 0; move16(); - IF ( i_subfr_fx != 0 ) + IF( i_subfr_fx != 0 ) { tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); } -- GitLab From 4276239737d482ee265d2eec90166ed4ee51c48a Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 11 Feb 2025 20:34:33 +0100 Subject: [PATCH 0105/1221] remove acelp_core_dec_fx() --- lib_dec/acelp_core_dec_fx.c | 18 +- lib_dec/acelp_core_dec_ivas_fx.c | 905 +++++++++++++++++++------------ lib_dec/amr_wb_dec_fx.c | 4 +- lib_dec/decision_matrix_dec_fx.c | 15 + lib_dec/evs_dec_fx.c | 7 +- lib_dec/fd_cng_dec_fx.c | 16 +- 6 files changed, 606 insertions(+), 359 deletions(-) diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 3a96a6225..fc35cb754 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -432,7 +432,7 @@ ivas_error acelp_core_dec_fx( } /* update synthesis filter memories */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES ivas_synth_mem_updt2_fx( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); #else synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); @@ -634,7 +634,7 @@ ivas_error acelp_core_dec_fx( /* decode CNG parameters */ IF( st_fx->cng_type == LP_CNG ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES CNG_dec_ivas_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); #else CNG_dec_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); @@ -708,11 +708,11 @@ ivas_error acelp_core_dec_fx( } i = st_fx->Q_exc; move16(); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES test(); IF( st_fx->hMusicPF && st_fx->hGSCDec ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { // VE: TBV: 'st_fx->L_frame * HIBND_ACB_L_FAC' should be corrected @@ -1593,7 +1593,7 @@ ivas_error acelp_core_dec_fx( move32(); } /*Noise estimate*/ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) && !st_fx->cng_ism_flag ) #else IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) /* && !st->cng_ism_flag IVAS_CODE */ ) @@ -1603,7 +1603,7 @@ ivas_error acelp_core_dec_fx( PMT( "Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done" ) ApplyFdCng_fx( syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, realBuffer, imagBuffer, NULL, st_fx, 0, ( st_fx->coder_type == AUDIO && !st_fx->GSC_noisy_speech ) ); #else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) ); @@ -1792,7 +1792,7 @@ ivas_error acelp_core_dec_fx( st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, st_fx->coder_type, st_fx->Q_syn, bpf_error_signal ); } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { /* analysis of the synthesis at internal sampling rate */ @@ -2033,7 +2033,7 @@ ivas_error acelp_core_dec_fx( IF( ( EQ_16( st_fx->L_frame, L_FRAME ) && NE_16( st_fx->bwidth, NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st_fx->extl, -1 ) || EQ_16( st_fx->extl, SWB_CNG ) || ( EQ_16( st_fx->extl, WB_BWE ) && st_fx->extl_brate == 0 && NE_16( st_fx->coder_type, AUDIO ) ) ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, @@ -2049,7 +2049,7 @@ ivas_error acelp_core_dec_fx( #endif } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES ELSE { hf_synth_reset_fx( st_fx->hBWE_zero ); diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 8d6b63833..f02e6d337 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -151,7 +151,6 @@ ivas_error acelp_core_dec_ivas_fx( error = IVAS_ERR_OK; move32(); - test(); test(); test(); @@ -664,11 +663,21 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Word16 old_NoiseEstExp = st->hFdCngDec->hFdCngCom->sidNoiseEstExp; - move16(); - FdCng_decodeSID_ivas_fx( st ); - rescale_fdCngDec( st->hFdCngDec, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); - Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, M + 1, sub( norm_s( st->hFdCngDec->hFdCngCom->A_cng[0] ), Q2 ) ); // Qx +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + FdCng_decodeSID_fx( st->hFdCngDec->hFdCngCom, st ); + } + ELSE +#endif + { + Word16 old_NoiseEstExp = st->hFdCngDec->hFdCngCom->sidNoiseEstExp; + move16(); + FdCng_decodeSID_ivas_fx( st ); + rescale_fdCngDec( st->hFdCngDec, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); + Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, M + 1, sub( norm_s( st->hFdCngDec->hFdCngCom->A_cng[0] ), Q2 ) ); // Qx + } + *sid_bw = 0; move16(); } @@ -720,7 +729,16 @@ ivas_error acelp_core_dec_ivas_fx( } } - generate_comfort_noise_dec_ivas_fx( NULL, NULL, NULL, st, &( st->Q_exc ), 1, nchan_out ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + generate_comfort_noise_dec_fx( NULL, NULL, NULL, st, &( st->Q_exc ), 2, -1 ); + } + ELSE +#endif + { + generate_comfort_noise_dec_ivas_fx( NULL, NULL, NULL, st, &( st->Q_exc ), 1, nchan_out ); + } FdCng_exc( st->hFdCngDec->hFdCngCom, &st->CNG_mode, st->L_frame, st->lsp_old_fx, st->first_CNG, st->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); @@ -740,8 +758,19 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( st->hMusicPF && st->hGSCDec ) { - Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, - imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + // VE: TBV: 'st_fx->L_frame * HIBND_ACB_L_FAC' should be corrected + Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, + st->L_frame * HIBND_ACB_L_FAC, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); + } + ELSE +#endif + { + Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, + imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); + } } IF( st->hPFstat != NULL ) { @@ -763,14 +792,26 @@ ivas_error acelp_core_dec_ivas_fx( /* Update music post processing values */ /* Filter energies update */ - FOR( i = 0; i < DCT_L_POST; i++ ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) { - st->hMusicPF->filt_lfE_fx[i] = add( 9830, mult_r( 22937, st->hMusicPF->filt_lfE_fx[i] ) ); // Q15, 9830 =.3f in Q15, 22937=.7f in Q15 - move16(); + FOR( i = 0; i < DCT_L_POST; i++ ) + { + st->hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, st->hMusicPF->filt_lfE_fx[i] ) ); + move16(); + } + } + ELSE +#endif + { + FOR( i = 0; i < DCT_L_POST; i++ ) + { + st->hMusicPF->filt_lfE_fx[i] = add( 9830, mult_r( 22937, st->hMusicPF->filt_lfE_fx[i] ) ); // Q15, 9830 =.3f in Q15, 22937=.7f in Q15 + move16(); + } } } - /* synthesis at 12.8kHz sampling rate */ #ifndef FIX_1100_REMOVE_LPC_RESCALING Aq_fx[0] = ONE_IN_Q12; @@ -778,15 +819,28 @@ ivas_error acelp_core_dec_ivas_fx( move16(); syn_12k8_fx( st->L_frame, Aq_fx, exc2_fx, psyn_fx, st->mem_syn2_fx, 1, st->Q_exc, st->Q_syn ); syn_12k8_fx( st->L_frame, Aq_fx, exc3_fx, syn1_fx, st->mem_syn3_fx, 1, st->Q_exc, st->Q_syn ); - st->Q_syn_cng = st->Q_syn; - move16(); - st->Q_exc_cng = st->Q_exc; - move16(); + /* reset the decoder */ CNG_reset_dec_fx( st, pitch_buf_fx, voice_factors_fx ); - /* update st->mem_syn1 for ACELP core switching */ - Copy_Scale_sig( st->mem_syn3_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); // Q(-1) + +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + /* update st_fx->mem_syn1 for ACELP core switching */ + Copy( st->mem_syn3_fx, st->mem_syn1_fx, M ); + } + ELSE +#endif + { + st->Q_syn_cng = st->Q_syn; + move16(); + st->Q_exc_cng = st->Q_exc; + move16(); + + /* update st->mem_syn1 for ACELP core switching */ + Copy_Scale_sig( st->mem_syn3_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); // Q(-1) + } /* update old synthesis for classification */ Copy( syn1_fx + st->L_frame - L_SYN_MEM_CLAS_ESTIM, st->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); @@ -1157,13 +1211,30 @@ ivas_error acelp_core_dec_ivas_fx( Word16 qdct = 0; move16(); /* Extrapolation of the last future part, windowing and high resolution DCT transform */ - Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, st->hMusicPF->filt_lfE_fx, st->last_core, st->element_mode, pitch_buf_fx, st->hMusicPF->LDm_enh_lp_gbin_fx, st->Q_exc, &qdct ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + // VE: TBV: this is a bug in EVS - 'st->last_coder_type' should be replaced by 'st->core_brate' + Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, st->hMusicPF->filt_lfE_fx, st->last_coder_type, st->element_mode, pitch_buf_fx, + st->hMusicPF->LDm_enh_lp_gbin_fx, st->Q_exc, &qdct ); + } + ELSE +#endif + { + Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, st->hMusicPF->filt_lfE_fx, st->last_core, st->element_mode, pitch_buf_fx, st->hMusicPF->LDm_enh_lp_gbin_fx, st->Q_exc, &qdct ); + } /* LD music post-filter */ LD_music_post_filter_fx( st->hMusicPF, dct_buffer_fx, dct_buffer_fx, st->core_brate, &st->hMusicPF->Old_ener_Q, AUDIO, last_coder_type, qdct ); /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */ - Copy( st->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/ +#ifdef REMOVE_EVS_DUPLICATES + IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBC whether needed in IVAS +#endif + { + Copy( st->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/ + } + Post_music_postP_fx( dct_buffer_fx, exc2_fx, st->mem_syn2_fx, st->mem_syn2_fx, Aq_fx, psyn_fx, &st->Q_exc, &st->prev_Q_syn, &st->Q_syn, st->mem_syn_clas_estim_fx, 0, &st->mem_deemph_fx, st->hBPF->pst_old_syn_fx, &st->hBPF->pst_mem_deemp_err_fx, &st->agc_mem_fx[1], st->hPFstat, temp_buf_fx, mem_tmp_fx ); @@ -1209,6 +1280,7 @@ ivas_error acelp_core_dec_ivas_fx( /*------------------------------------------------------------* * FEC - Estimate the classification information *------------------------------------------------------------*/ + FEC_clas_estim_fx( st, st->Opt_AMR_WB, st->L_frame, &st->clas_dec, st->coder_type, pitch_buf_fx, psyn_fx, &st->lp_ener_FER_fx, &st->decision_hyst, NULL, NULL, NULL, NULL, 0, NULL, st->Q_syn, temp_buf_fx, @@ -1586,19 +1658,28 @@ ivas_error acelp_core_dec_ivas_fx( } ELSE IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) { - IF( st->idchan == 0 ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) { - IF( NE_16( st->element_mode, last_element_mode ) ) + generate_masking_noise_fx( psyn_fx, st->Q_syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0 ); + } + ELSE +#endif + { + IF( st->idchan == 0 ) { - set16_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st->hFdCngDec->hFdCngCom->fftlen ); + IF( NE_16( st->element_mode, last_element_mode ) ) + { + set16_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st->hFdCngDec->hFdCngCom->fftlen ); + } + Word32 psyn_32_fx[L_FRAME16k]; + Word16 exp; + Copy_Scale_sig_16_32_no_sat( psyn_fx, psyn_32_fx, st->hFdCngDec->hFdCngCom->frameSize, sub( Q6, st->Q_syn ) ); // Q6 + Copy_Scale_sig_16_32_no_sat( st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->hFdCngDec->hFdCngCom->frameSize, 1 ), Q15 ); // Q15 + generate_masking_noise_ivas_fx( psyn_32_fx, &exp, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); + Copy_Scale_sig_32_16( psyn_32_fx, psyn_fx, st->hFdCngDec->hFdCngCom->frameSize, sub( st->Q_syn, exp ) ); // Q = st->Q_syn + Copy_Scale_sig_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2, shl( st->hFdCngDec->hFdCngCom->frameSize, 1 ), -Q15 ); // Q0 } - Word32 psyn_32_fx[L_FRAME16k]; - Word16 exp; - Copy_Scale_sig_16_32_no_sat( psyn_fx, psyn_32_fx, st->hFdCngDec->hFdCngCom->frameSize, sub( Q6, st->Q_syn ) ); // Q6 - Copy_Scale_sig_16_32_no_sat( st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->hFdCngDec->hFdCngCom->frameSize, 1 ), Q15 ); // Q15 - generate_masking_noise_ivas_fx( psyn_32_fx, &exp, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); - Copy_Scale_sig_32_16( psyn_32_fx, psyn_fx, st->hFdCngDec->hFdCngCom->frameSize, sub( st->Q_syn, exp ) ); // Q = st->Q_syn - Copy_Scale_sig_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2, shl( st->hFdCngDec->hFdCngCom->frameSize, 1 ), -Q15 ); // Q0 } } } @@ -1685,36 +1766,27 @@ ivas_error acelp_core_dec_ivas_fx( * Bass post-filter *----------------------------------------------------------------*/ - /* check if the CLDFB works on the right sample rate */ - IF( NE_16( imult1616( st->cldfbAna->no_channels, st->cldfbAna->no_col ), st->L_frame ) ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) { - resampleCldfb_ivas_fx( st->cldfbAna, L_mult0( st->L_frame, FRAMES_PER_SEC ) ); - resampleCldfb_ivas_fx( st->cldfbBPF, L_mult0( st->L_frame, FRAMES_PER_SEC ) ); + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128 * 3]; - IF( st->ini_frame > 0 ) + /* check if the CLDFB works on the right sample rate */ + IF( ( st->cldfbAna->usb * st->cldfbAna->no_col ) != st->L_frame ) { - st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); - move16(); - } - } - - /* analyze pitch coherence for bass post-filter */ + /* resample to ACELP internal sampling rate */ + Word16 newCldfbBands = CLDFB_getNumChannels( L_mult0( st->L_frame, FRAMES_PER_SEC ) ); + resampleCldfb( st->cldfbAna, newCldfbBands, st->L_frame, 0 ); + resampleCldfb( st->cldfbBPF, newCldfbBands, st->L_frame, 0 ); - Word32 pitch_buf_fx_q20[12]; - - Scale_sig32( st->old_pitch_buf_fx, 2 * NB_SUBFR16k + 2, Q4 ); // Q(x+4) - Word16 lim = shr( st->L_frame, 6 ); - FOR( Word16 lp = 0; lp < lim; lp++ ) - { - pitch_buf_fx_q20[lp] = L_shl( pitch_buf_fx[lp], Q14 ); - move32(); - } - bpf_pitch_coherence_ivas_fx( st, pitch_buf_fx_q20 ); - Scale_sig32( st->old_pitch_buf_fx, 2 * NB_SUBFR16k + 2, -Q4 ); // Qx + IF( st->ini_frame > 0 ) + { + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); + move16(); + } + } - test(); - IF( !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->bpf_off ) ) - { test(); IF( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) ) { @@ -1730,89 +1802,26 @@ ivas_error acelp_core_dec_ivas_fx( bass_psfilter_fx( st->hBPF, st->Opt_AMR_WB, psyn_fx, st->L_frame, pitch_buf_fx, st->bpf_off, st->stab_fac_fx, &st->stab_fac_smooth_fx, st->coder_type, st->Q_syn, bpf_error_signal_16fx ); - } - Word32 syn_tmp_32_fx[L_FRAME16k + L_SUBFR], *syn_32_fx; - set32_fx( syn_tmp_32_fx, 0, L_FRAME16k + L_SUBFR ); - syn_32_fx = syn_tmp_32_fx + L_SUBFR; - test(); - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) - { - /* analysis of the synthesis at internal sampling rate */ - Word32 realBufferSave_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - Word32 imagBufferSave_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - Word32 *pRealSave_fx[CLDFB_NO_COL_MAX], *pImagSave_fx[CLDFB_NO_COL_MAX]; - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - pRealSave_fx[i] = realBufferSave_fx[i]; - pImagSave_fx[i] = imagBufferSave_fx[i]; - } -#ifndef MSAN_FIX - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 -#endif - IF( st->p_bpf_noise_buf_32 ) - { -#ifdef MSAN_FIX - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 -#endif - Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); - Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 - } -#ifdef MSAN_FIX - FOR( i = 0; i < st->L_frame; i++ ) -#else - for ( i = 0; i < L_FRAME16k; i++ ) -#endif - { - syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); // Q12 - move32(); - } + /* analysis of the synthesis at internal sampling rate */ + cldfbAnalysisFiltering( st->cldfbAna, realBuffer_fx, imagBuffer_fx, &scaleFactor, psyn_fx, negate( st->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); - Word16 offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); - Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, 1 ); // Q12 - st->cldfbAna->Q_cldfb_state = Q12; + scaleFactor.hb_scale = scaleFactor.lb_scale; move16(); - cldfbAnalysis_ivas_fx( syn_32_fx, realBuffer_fx, imagBuffer_fx, -1, st->cldfbAna ); - Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, -1 ); // Q11 - st->cldfbAna->Q_cldfb_state = Q11; - move16(); - /* analysis and add the BPF error signal */ - Word32 tmp_bpf_error_signal_fx[L_FRAME16k]; - Word16 q_bpf_error_signal; - Word16 cldfb_state_offset = sub( st->cldfbBPF->p_filter_length, st->cldfbBPF->no_channels ); - q_bpf_error_signal = Q6; - move16(); -#ifdef MSAN_FIX -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#endif -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn ); // Q6 -#endif - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 - Scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 - } - Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, sub( q_bpf_error_signal, Q10 ) ); // q_bpf_error_signal (Q6) - st->cldfbBPF->Q_cldfb_state = q_bpf_error_signal; - move16(); - tmp = -1; + /* analysis and add the BPF error signal */ + i = 0; move16(); - if ( st->bpf_off ) + if ( st->bpf_off == 0 ) { - tmp = 0; + i = CLDFB_NO_COL_MAX; move16(); } - addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx, tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); - Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, negate( ( sub( q_bpf_error_signal, Q10 ) ) ) ); // Q10 - st->cldfbBPF->Q_cldfb_state = Q10; - move16(); + addBassPostFilter_fx( bpf_error_signal_16fx, realBuffer_fx, imagBuffer_fx, st->cldfbBPF, workBuffer, negate( st->Q_syn ), + i, st->cldfbAna->no_col, st->cldfbAna->no_channels, &scaleFactor ); + /* set output mask for upsampling */ IF( EQ_16( st->bwidth, NB ) ) { @@ -1826,118 +1835,405 @@ ivas_error acelp_core_dec_ivas_fx( st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); move16(); } + + /*WB/SWB-FD_CNG*/ + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + test(); - IF( !st->cng_sba_flag || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + test(); + test(); + IF( ( ( st->core_brate == FRAME_NO_DATA ) || EQ_32( st->core_brate, SID_2k40 ) ) && ( EQ_16( st->cng_type, FD_CNG ) ) && ( LT_16( st->hFdCngDec->hFdCngCom->numCoreBands, st->cldfbSyn->no_channels ) ) ) { - test(); - test(); - test(); - /*WB/SWB-FD_CNG*/ - IF( ( st->core_brate == FRAME_NO_DATA || EQ_32( st->core_brate, SID_2k40 ) ) && ( EQ_16( st->cng_type, FD_CNG ) ) && ( LT_16( st->hFdCngDec->hFdCngCom->numCoreBands, st->cldfbSyn->no_channels ) ) ) + generate_comfort_noise_dec_hf_fx( realBuffer_fx, imagBuffer_fx, &scaleFactor.hb_scale, st ); + + st->cldfbSyn->bandsToZero = 0; + move16(); + IF( LT_16( st->hFdCngDec->hFdCngCom->regularStopBand, st->cldfbSyn->no_channels ) ) { - Word16 tmpBufferScale = 0; + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->hFdCngDec->hFdCngCom->regularStopBand ); move16(); - generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); + } + st->cldfbSyn->lsb = st->cldfbAna->no_channels; + move16(); + } - FOR( i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++ ) - { - Scale_sig32( realBuffer_fx[i] + st->hFdCngDec->hFdCngCom->numCoreBands, sub( st->hFdCngDec->hFdCngCom->regularStopBand, st->hFdCngDec->hFdCngCom->numCoreBands ), sub( add( tmpBufferScale, 15 ), Q31 ) ); // Q0 - Scale_sig32( imagBuffer_fx[i] + st->hFdCngDec->hFdCngCom->numCoreBands, sub( st->hFdCngDec->hFdCngCom->regularStopBand, st->hFdCngDec->hFdCngCom->numCoreBands ), sub( add( tmpBufferScale, 15 ), Q31 ) ); // Q0 - } + /* synthesis of the combined signal */ + st->Q_syn2 = st->Q_syn; + move16(); + cldfbSynthesisFiltering( st->cldfbSyn, realBuffer_fx, imagBuffer_fx, &scaleFactor, synth_fx16, negate( st->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); + + /* Bring CLDFB output to Q0 */ + Scale_sig( synth_fx16, output_frame, negate( st->Q_syn2 ) ); + st->Q_syn2 = 0; + move16(); + + /* save synthesis - needed in case of core switching */ + Copy( synth_fx16, st->previoussynth_fx, output_frame ); + } + ELSE +#endif + { + /* check if the CLDFB works on the right sample rate */ + IF( NE_16( imult1616( st->cldfbAna->no_channels, st->cldfbAna->no_col ), st->L_frame ) ) + { + resampleCldfb_ivas_fx( st->cldfbAna, L_mult0( st->L_frame, FRAMES_PER_SEC ) ); + resampleCldfb_ivas_fx( st->cldfbBPF, L_mult0( st->L_frame, FRAMES_PER_SEC ) ); + + IF( st->ini_frame > 0 ) + { + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); + move16(); + } + } + + /* analyze pitch coherence for bass post-filter */ + + Word32 pitch_buf_fx_q20[12]; - IF( LT_16( st->hFdCngDec->hFdCngCom->regularStopBand, st->cldfbSyn->no_channels ) ) + Scale_sig32( st->old_pitch_buf_fx, 2 * NB_SUBFR16k + 2, Q4 ); // Q(x+4) + Word16 lim = shr( st->L_frame, 6 ); + FOR( Word16 lp = 0; lp < lim; lp++ ) + { + pitch_buf_fx_q20[lp] = L_shl( pitch_buf_fx[lp], Q14 ); + move32(); + } + bpf_pitch_coherence_ivas_fx( st, pitch_buf_fx_q20 ); + Scale_sig32( st->old_pitch_buf_fx, 2 * NB_SUBFR16k + 2, -Q4 ); // Qx + + test(); + IF( !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->bpf_off ) ) + { + test(); + IF( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) ) + { + IF( EQ_16( st->L_frame, L_FRAME ) ) { - st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->hFdCngDec->hFdCngCom->regularStopBand ); - move16(); + retro_interp5_4_fx( st->hBPF->pst_old_syn_fx ); } - ELSE + ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) ) { - st->cldfbSyn->bandsToZero = 0; - move16(); + retro_interp4_5_fx( psyn_fx, st->hBPF->pst_old_syn_fx ); } } + + bass_psfilter_fx( st->hBPF, st->Opt_AMR_WB, psyn_fx, st->L_frame, pitch_buf_fx, st->bpf_off, + st->stab_fac_fx, &st->stab_fac_smooth_fx, st->coder_type, st->Q_syn, bpf_error_signal_16fx ); } - IF( save_hb_synth_fx16 != NULL ) + Word32 syn_tmp_32_fx[L_FRAME16k + L_SUBFR], *syn_32_fx; + set32_fx( syn_tmp_32_fx, 0, L_FRAME16k + L_SUBFR ); + syn_32_fx = syn_tmp_32_fx + L_SUBFR; + test(); + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) { - /* save and then zero-out lowband */ - Word16 Q_real = 0, Q_imag = 0; - Word32 max_real = 0, max_imag = 0; + /* analysis of the synthesis at internal sampling rate */ + Word32 realBufferSave_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 imagBufferSave_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 *pRealSave_fx[CLDFB_NO_COL_MAX], *pImagSave_fx[CLDFB_NO_COL_MAX]; + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + pRealSave_fx[i] = realBufferSave_fx[i]; + pImagSave_fx[i] = imagBufferSave_fx[i]; + } +#ifndef MSAN_FIX + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 +#endif + IF( st->p_bpf_noise_buf_32 ) + { +#ifdef MSAN_FIX + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 +#endif + Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); + Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 + } + +#ifdef MSAN_FIX + FOR( i = 0; i < st->L_frame; i++ ) +#else + for ( i = 0; i < L_FRAME16k; i++ ) +#endif + { + syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); // Q12 + move32(); + } + + Word16 offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, 1 ); // Q12 + st->cldfbAna->Q_cldfb_state = Q12; move16(); + cldfbAnalysis_ivas_fx( syn_32_fx, realBuffer_fx, imagBuffer_fx, -1, st->cldfbAna ); + Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, -1 ); // Q11 + st->cldfbAna->Q_cldfb_state = Q11; move16(); - move32(); - move32(); + /* analysis and add the BPF error signal */ + Word32 tmp_bpf_error_signal_fx[L_FRAME16k]; + Word16 q_bpf_error_signal; + Word16 cldfb_state_offset = sub( st->cldfbBPF->p_filter_length, st->cldfbBPF->no_channels ); + + q_bpf_error_signal = Q6; + move16(); +#ifdef MSAN_FIX +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#else + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#endif +#else + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn ); // Q6 +#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { - FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - max_real = L_max( max_real, L_abs( realBuffer_fx[i][j] ) ); - max_imag = L_max( max_imag, L_abs( imagBuffer_fx[i][j] ) ); - } + Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 + Scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 } - Word32 max_val = L_max( max_real, max_imag ); - Q_imag = sub( norm_l( max_val ), 3 ) /* Guard bits */; - Q_real = Q_imag; + Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, sub( q_bpf_error_signal, Q10 ) ); // q_bpf_error_signal (Q6) + st->cldfbBPF->Q_cldfb_state = q_bpf_error_signal; move16(); - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + tmp = -1; + move16(); + if ( st->bpf_off ) { - scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real - scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_imag ); // Q_imag + tmp = 0; + move16(); } - scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) - st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); + + addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx, tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, negate( ( sub( q_bpf_error_signal, Q10 ) ) ) ); // Q10 + st->cldfbBPF->Q_cldfb_state = Q10; move16(); -#ifndef MSAN_FIX - Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); // Q_real-1 -#endif + /* set output mask for upsampling */ + IF( EQ_16( st->bwidth, NB ) ) + { + /* set NB mask for upsampling */ + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, 10 ); + move16(); + } + ELSE IF( NE_16( st->cldfbSyn->bandsToZero, sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ) ) ) + { + /* in case of BW switching, re-init to default */ + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); + move16(); + } + test(); + IF( !st->cng_sba_flag || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + test(); + test(); + test(); + /*WB/SWB-FD_CNG*/ + IF( ( st->core_brate == FRAME_NO_DATA || EQ_32( st->core_brate, SID_2k40 ) ) && ( EQ_16( st->cng_type, FD_CNG ) ) && ( LT_16( st->hFdCngDec->hFdCngCom->numCoreBands, st->cldfbSyn->no_channels ) ) ) + { + Word16 tmpBufferScale = 0; + move16(); + generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); + + FOR( i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++ ) + { + Scale_sig32( realBuffer_fx[i] + st->hFdCngDec->hFdCngCom->numCoreBands, sub( st->hFdCngDec->hFdCngCom->regularStopBand, st->hFdCngDec->hFdCngCom->numCoreBands ), sub( add( tmpBufferScale, 15 ), Q31 ) ); // Q0 + Scale_sig32( imagBuffer_fx[i] + st->hFdCngDec->hFdCngCom->numCoreBands, sub( st->hFdCngDec->hFdCngCom->regularStopBand, st->hFdCngDec->hFdCngCom->numCoreBands ), sub( add( tmpBufferScale, 15 ), Q31 ) ); // Q0 + } - FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + IF( LT_16( st->hFdCngDec->hFdCngCom->regularStopBand, st->cldfbSyn->no_channels ) ) + { + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->hFdCngDec->hFdCngCom->regularStopBand ); + move16(); + } + ELSE + { + st->cldfbSyn->bandsToZero = 0; + move16(); + } + } + } + + IF( save_hb_synth_fx16 != NULL ) { + /* save and then zero-out lowband */ + Word16 Q_real = 0, Q_imag = 0; + Word32 max_real = 0, max_imag = 0; + move16(); + move16(); + move32(); + move32(); FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { - realBufferSave_fx[i][j] = realBuffer_fx[i][j]; - imagBufferSave_fx[i][j] = imagBuffer_fx[i][j]; - move32(); - move32(); - IF( LT_16( j, st->hFdCngDec->hFdCngCom->numCoreBands ) && LT_16( i, st->hFdCngDec->hFdCngCom->numSlots ) ) + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + max_real = L_max( max_real, L_abs( realBuffer_fx[i][j] ) ); + max_imag = L_max( max_imag, L_abs( imagBuffer_fx[i][j] ) ); + } + } + Word32 max_val = L_max( max_real, max_imag ); + Q_imag = sub( norm_l( max_val ), 3 ) /* Guard bits */; + Q_real = Q_imag; + move16(); + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real + scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_imag ); // Q_imag + } + scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) + st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); + move16(); +#ifndef MSAN_FIX + Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); // Q_real-1 +#endif + + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { - realBuffer_fx[i][j] = 0; - imagBuffer_fx[i][j] = 0; + realBufferSave_fx[i][j] = realBuffer_fx[i][j]; + imagBufferSave_fx[i][j] = imagBuffer_fx[i][j]; move32(); move32(); + IF( LT_16( j, st->hFdCngDec->hFdCngCom->numCoreBands ) && LT_16( i, st->hFdCngDec->hFdCngCom->numSlots ) ) + { + realBuffer_fx[i][j] = 0; + imagBuffer_fx[i][j] = 0; + move32(); + move32(); + } } } - } - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, st->cldfbSynHB ); + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, st->cldfbSynHB ); - Scale_sig32( save_hb_synth_fx, L_FRAME48k, negate( ( sub( Q_real, 1 ) ) ) ); // Q0 - Scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 - st->cldfbSynHB->Q_cldfb_state = Q10; - move16(); - /* restore lowband */ - FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + Scale_sig32( save_hb_synth_fx, L_FRAME48k, negate( ( sub( Q_real, 1 ) ) ) ); // Q0 + Scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 + st->cldfbSynHB->Q_cldfb_state = Q10; + move16(); + /* restore lowband */ + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + realBuffer_fx[i][j] = realBufferSave_fx[i][j]; + imagBuffer_fx[i][j] = imagBufferSave_fx[i][j]; + move32(); + move32(); + } + } + Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // Q_real-1 + st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); + move16(); + cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, st->cldfbSyn ); + Scale_sig32( synth_fx, L_FRAME48k, negate( sub( Q_real, 1 ) ) ); // Q0 + Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 + st->cldfbSynHB->Q_cldfb_state = Q10; + move16(); + } + ELSE { + /* synthesis of the combined signal */ + Word16 Q_real, Q_imag; + Word32 max_real, max_imag; + Q_real = 0; + Q_imag = 0; + max_real = 0; + max_imag = 0; + move16(); + move16(); + move32(); + move32(); FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { - realBuffer_fx[i][j] = realBufferSave_fx[i][j]; - imagBuffer_fx[i][j] = imagBufferSave_fx[i][j]; - move32(); - move32(); + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + max_real = L_max( max_real, L_abs( realBuffer_fx[i][j] ) ); + max_imag = L_max( max_imag, L_abs( imagBuffer_fx[i][j] ) ); + } } + Word32 max_val = L_max( max_real, max_imag ); + Q_imag = sub( norm_l( max_val ), 3 ) /* Guard bits */; + Q_real = Q_imag; + move16(); + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real + scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real + } + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); + move16(); +#ifndef MSAN_FIX + Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); +#endif + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, st->cldfbSyn ); +#ifdef MSAN_FIX + scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 +#else + Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); +#endif + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 + st->cldfbSyn->Q_cldfb_state = Q10; + move16(); } - Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // Q_real-1 - st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); - move16(); - cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, st->cldfbSyn ); - Scale_sig32( synth_fx, L_FRAME48k, negate( sub( Q_real, 1 ) ) ); // Q0 - Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 - st->cldfbSynHB->Q_cldfb_state = Q10; - move16(); + + /* save synthesis - needed in case of core switching */ + Copy32( synth_fx, st->previoussynth_fx_32, output_frame ); // Q0 } ELSE { - /* synthesis of the combined signal */ + Word16 nSamples = NS2SA_FX2( i_mult( st->L_frame, FRAMES_PER_SEC ), FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ + + /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ +#ifndef MSAN_FIX + for ( i = 0; i < L_FRAME16k; i++ ) +#else + FOR( i = 0; i < st->L_frame; i++ ) +#endif + { + syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); + move32(); + } + + Word16 offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, 1 ); // Q12 + st->cldfbAna->Q_cldfb_state = Q12; + move16(); + cldfbAnalysis_ivas_fx( syn_32_fx + sub( st->L_frame, nSamples ), realBuffer_fx, imagBuffer_fx, nSamples, st->cldfbAna ); + + Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, -1 ); // Q11 + st->cldfbAna->Q_cldfb_state = Q11; + move16(); /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ + Word32 tmp_bpf_error_signal_fx[L_FRAME16k]; + Word16 q_bpf_error_signal; + Word16 cldfb_state_offset; + cldfb_state_offset = sub( st->cldfbBPF->p_filter_length, st->cldfbBPF->no_channels ); + + // Get Q-factor + q_bpf_error_signal = Q6; + move16(); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#else + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#endif + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 + Scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 + } + Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, sub( q_bpf_error_signal, Q10 ) ); // q_bpf_error_signal (Q6) + st->cldfbBPF->Q_cldfb_state = q_bpf_error_signal; + move16(); + tmp = 0; + move16(); + if ( !st->bpf_off ) + { + tmp = nSamples; + move16(); + } + addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx + sub( st->L_frame, nSamples ), tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + + + Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, negate( sub( q_bpf_error_signal, Q10 ) ) ); // Q10 + st->cldfbBPF->Q_cldfb_state = Q10; + move16(); + /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ Word16 Q_real, Q_imag; Word32 max_real, max_imag; Q_real = 0; @@ -1966,151 +2262,46 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real } scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) - st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); - move16(); #ifndef MSAN_FIX Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, st->cldfbSyn ); + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); + #ifdef MSAN_FIX - scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 + Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 #else Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); #endif - scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 + Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); - } - - /* save synthesis - needed in case of core switching */ - Copy32( synth_fx, st->previoussynth_fx_32, output_frame ); // Q0 - } - ELSE - { - Word16 nSamples = NS2SA_FX2( i_mult( st->L_frame, FRAMES_PER_SEC ), FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ + IF( st->p_bpf_noise_buf_32 ) + { + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 + Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); - /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ -#ifndef MSAN_FIX - for ( i = 0; i < L_FRAME16k; i++ ) -#else - FOR( i = 0; i < st->L_frame; i++ ) -#endif - { - syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); - move32(); - } + Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 + } - Word16 offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); - Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, 1 ); // Q12 - st->cldfbAna->Q_cldfb_state = Q12; - move16(); - cldfbAnalysis_ivas_fx( syn_32_fx + sub( st->L_frame, nSamples ), realBuffer_fx, imagBuffer_fx, nSamples, st->cldfbAna ); - - Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, -1 ); // Q11 - st->cldfbAna->Q_cldfb_state = Q11; - move16(); /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ - Word32 tmp_bpf_error_signal_fx[L_FRAME16k]; - Word16 q_bpf_error_signal; - Word16 cldfb_state_offset; - cldfb_state_offset = sub( st->cldfbBPF->p_filter_length, st->cldfbBPF->no_channels ); - - // Get Q-factor - q_bpf_error_signal = Q6; - move16(); -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#endif - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 - Scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 - } - Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, sub( q_bpf_error_signal, Q10 ) ); // q_bpf_error_signal (Q6) - st->cldfbBPF->Q_cldfb_state = q_bpf_error_signal; - move16(); - tmp = 0; - move16(); - if ( !st->bpf_off ) - { - tmp = nSamples; - move16(); + set32_fx( synth_fx, 0, output_frame ); } - addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx + sub( st->L_frame, nSamples ), tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); - - Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, negate( sub( q_bpf_error_signal, Q10 ) ) ); // Q10 - st->cldfbBPF->Q_cldfb_state = Q10; - move16(); - /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ - Word16 Q_real, Q_imag; - Word32 max_real, max_imag; - Q_real = 0; - Q_imag = 0; - max_real = 0; - max_imag = 0; - move16(); - move16(); - move32(); - move32(); - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - max_real = L_max( max_real, L_abs( realBuffer_fx[i][j] ) ); - max_imag = L_max( max_imag, L_abs( imagBuffer_fx[i][j] ) ); - } - } - Word32 max_val = L_max( max_real, max_imag ); - Q_imag = sub( norm_l( max_val ), 3 ) /* Guard bits */; - Q_real = Q_imag; - move16(); - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real - scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real - } - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + /* Copy output signal */ #ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); -#endif - - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); - -#ifdef MSAN_FIX - Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 + Scale_sig( syn_tmp_fx, L_FRAME16k + L_SUBFR, -st->Q_syn ); #else - Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); + Scale_sig( syn_tmp_fx, add( st->L_frame, L_SUBFR ), negate( st->Q_syn ) ); // Q0 #endif - Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 - st->cldfbSyn->Q_cldfb_state = Q10; - move16(); - IF( st->p_bpf_noise_buf_32 ) + IF( st->element_mode > EVS_MONO ) { - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 - Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); - - Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 + Copy( psyn_fx, output_fx, st->L_frame ); /*Q_syn*/ } - set32_fx( synth_fx, 0, output_frame ); - } - - /* Copy output signal */ -#ifndef MSAN_FIX - Scale_sig( syn_tmp_fx, L_FRAME16k + L_SUBFR, -st->Q_syn ); -#else - Scale_sig( syn_tmp_fx, add( st->L_frame, L_SUBFR ), negate( st->Q_syn ) ); // Q0 -#endif - IF( st->element_mode > EVS_MONO ) - { - Copy( psyn_fx, output_fx, st->L_frame ); /*Q_syn*/ + st->Q_syn2 = 0; + move16(); } - st->Q_syn2 = 0; - move16(); /*-----------------------------------------------------------------* * Bandwidth extension 6kHz-7kHz *-----------------------------------------------------------------*/ @@ -2126,26 +2317,41 @@ ivas_error acelp_core_dec_ivas_fx( IF( ( EQ_16( st->L_frame, L_FRAME ) && ( st->bwidth != NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st->extl, -1 ) || EQ_16( st->extl, SWB_CNG ) || ( EQ_16( st->extl, WB_BWE ) && st->extl_brate == 0 && NE_16( st->coder_type, AUDIO ) ) ) ) ) { +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, psyn_fx, synth_fx16, st->Q_exc, + st->Q_syn2, st->hBWE_zero->delay_syn_hf_fx, &st->hBWE_zero->memExp1, st->hBWE_zero->mem_hp_interp_fx, st->extl, st->CNG_mode ); + } + ELSE +#endif + { #ifdef MSAN_FIX - Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q0 + Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q0 #else - Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); + Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); #endif - hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, - psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2, st->hBWE_zero->delay_syn_hf_fx, &st->hBWE_zero->memExp1, - st->hBWE_zero->mem_hp_interp_fx, st->extl, st->CNG_mode ); + hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, + psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2, st->hBWE_zero->delay_syn_hf_fx, &st->hBWE_zero->memExp1, + st->hBWE_zero->mem_hp_interp_fx, st->extl, st->CNG_mode ); #ifdef MSAN_FIX - Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, output_frame, 0 ); + Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, output_frame, 0 ); #else - Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, L_FRAME48k, 0 ); + Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, L_FRAME48k, 0 ); #endif + } } ELSE { hf_synth_reset_fx( st->hBWE_zero ); +#ifdef REMOVE_EVS_DUPLICATES2 + IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact +#endif + { #ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); #endif + } } } @@ -2180,13 +2386,23 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( !st->ppp_mode_dec && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + non_linearity_fx( bwe_exc_fx, bwe_exc_extended_fx, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, + st->coder_type, voice_factors_fx, st->L_frame ); + } + ELSE +#endif + { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc #else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc #endif - non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); - Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc + non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); + Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc + } } test(); if ( st->core_brate == FRAME_NO_DATA || EQ_32( st->core_brate, SID_2k40 ) ) @@ -2195,6 +2411,7 @@ ivas_error acelp_core_dec_ivas_fx( move32(); } } + /*----------------------------------------------------------------------* * Updates *----------------------------------------------------------------------*/ @@ -2205,10 +2422,19 @@ ivas_error acelp_core_dec_ivas_fx( IF( GT_32( st->core_brate, SID_2k40 ) && st->hTdCngDec != NULL && st->hFdCngDec != NULL ) { /* update CNG parameters in active frames */ - cng_params_upd_ivas_fx( lsp_new_fx, exc_fx, st->L_frame, &st->hTdCngDec->ho_circ_ptr, st->hTdCngDec->ho_ener_circ_fx, &st->hTdCngDec->ho_circ_size, - st->hTdCngDec->ho_lsp_circ_fx, st->Q_exc, DEC, st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate, st->element_mode, - st->hFdCngDec->hFdCngCom->CngBandwidth ); - +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + cng_params_upd_fx( lsp_new_fx, exc_fx, st->L_frame, &st->hTdCngDec->ho_circ_ptr, st->hTdCngDec->ho_ener_circ_fx, &st->hTdCngDec->ho_circ_size, st->hTdCngDec->ho_lsp_circ_fx, + st->Q_exc, DEC, st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate ); + } + ELSE +#endif + { + cng_params_upd_ivas_fx( lsp_new_fx, exc_fx, st->L_frame, &st->hTdCngDec->ho_circ_ptr, st->hTdCngDec->ho_ener_circ_fx, &st->hTdCngDec->ho_circ_size, + st->hTdCngDec->ho_lsp_circ_fx, st->Q_exc, DEC, st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate, st->element_mode, + st->hFdCngDec->hFdCngCom->CngBandwidth ); + } /* Set 16k LSP flag for CNG buffer */ st->hTdCngDec->ho_16k_lsp[st->hTdCngDec->ho_circ_ptr] = 0; @@ -2220,6 +2446,9 @@ ivas_error acelp_core_dec_ivas_fx( } } +#ifdef REMOVE_EVS_DUPLICATES + IF( NE_16( st->element_mode, EVS_MONO ) ) +#endif { IF( save_hb_synth_fx16 ) { diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index b3fbc0233..8a2ef7b40 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -374,7 +374,7 @@ ivas_error amr_wb_dec_fx( IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_1k75 ) ) { /* decode CNG parameters */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES CNG_dec_ivas_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); #else CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); @@ -800,7 +800,7 @@ ivas_error amr_wb_dec_fx( PMT( "Fixed point not done here " ) ApplyFdCng_fx( syn, NULL, NULL, NULL, st, 0, 0 ); #else -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 ); #else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, NULL, NULL, st_fx, 0, 0 ); diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index 9c0020223..ff03f8bc5 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -713,5 +713,20 @@ void decision_matrix_dec_fx( move16(); } +#ifdef REMOVE_EVS_DUPLICATES2 + /*-----------------------------------------------------------------* + * set inactive coder_type flag in ACELP core + *-----------------------------------------------------------------*/ + + st->inactive_coder_type_flag = 0; /* AVQ by default */ + move16(); + + if ( LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + { + st->inactive_coder_type_flag = 1; /* GSC */ + move16(); + } + +#endif return; } diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index fee893c4b..2f0873ba5 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -346,8 +346,11 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ - +#ifdef REMOVE_EVS_DUPLICATES2 + IF( ( error = acelp_core_dec_ivas_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) +#else IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1000,7 +1003,7 @@ ivas_error evs_dec_fx( #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT ApplyFdCng_fx( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); #else -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES ApplyFdCng_ivas_fx( output_sp, 0, NULL, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); #else ApplyFdCng_fx( output_sp, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index af670f0d0..a3c9b5826 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1263,7 +1263,7 @@ Word16 ApplyFdCng_ivas_fx( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); @@ -1276,7 +1276,7 @@ Word16 ApplyFdCng_ivas_fx( /* Update the shaping parameters */ test(); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); @@ -1522,7 +1522,7 @@ Word16 ApplyFdCng_ivas_fx( IF( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); @@ -1589,7 +1589,7 @@ Word16 ApplyFdCng_ivas_fx( IF( st != NULL && EQ_16( st->cng_type, LP_CNG ) ) { /* Perform noise estimation on inactive phase at the decoder */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); @@ -1603,7 +1603,7 @@ Word16 ApplyFdCng_ivas_fx( /* Update the shaping parameters */ test(); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); @@ -1689,7 +1689,7 @@ Word16 ApplyFdCng_ivas_fx( IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); @@ -1711,7 +1711,7 @@ Word16 ApplyFdCng_ivas_fx( /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); @@ -1874,7 +1874,7 @@ Word16 ApplyFdCng_ivas_fx( IF( EQ_16( st->codec_mode, MODE2 ) ) { /* Generate comfort noise during SID or zero frames */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { generate_comfort_noise_dec_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); -- GitLab From dc7ba37ef19e17d318568bba7a8a11ce925ee037 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 10:55:48 +0530 Subject: [PATCH 0106/1221] Fix for 3GPP issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps Link #1218 --- lib_com/options.h | 1 + lib_dec/acelp_core_dec_ivas_fx.c | 12 ++++++++++++ lib_dec/fd_cng_dec_fx.c | 5 +++++ lib_dec/ivas_stereo_cng_dec.c | 5 +++++ 4 files changed, 23 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 50f691903..7fe865756 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -127,6 +127,7 @@ #define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */ #define FIX_ISSUE_1185 /* Ittiam: Fix for issue 1185: Assertion in ivas_dirac_dec_binaural_internal_fx() for crash in decoder in fft30_with_cmplx_data()*/ #define FIX_ISSUE_1209 /* Ittiam: Fix for issue 1209: Assertion exit in BASOP encoder (stereo_dmx_evs)*/ +#define FIX_ISSUE_1218 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ #define IVAS_ISSUE_1188_EVS_CRASH /* Ittiam: Fix for issue 1188: Issue due to ASAN */ #define FIX_ISSUE_1155 /* Ittiam: Fix for issue 1155: Encoder crash for Stereo at 32kbps in PostShortTerm_ivas_enc_fx()*/ #define FIX_1010_OPT_DIV /* FhG: SVD complexity optimizations (non-be) */ diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 0914e7ece..e52c52c7c 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -180,7 +180,19 @@ ivas_error acelp_core_dec_ivas_fx( IF( EQ_32( st->core_brate, SID_2k40 ) ) { FdCng_decodeSID_ivas_fx( st ); +#ifdef FIX_ISSUE_1218 + Word16 n1, n2; + n1 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART ); + n2 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); + + Word16 common_e = s_max( sub( old_NoiseEstExp, n2 ), sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, n1 ) ); + scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, common_e ) ); + scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( old_NoiseEstExp, common_e ) ); + st->hFdCngDec->hFdCngCom->sidNoiseEstExp = common_e; + move16(); +#else rescale_fdCngDec( st->hFdCngDec, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); +#endif } FOR( i = 0; i < NPART; i++ ) { diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index c683b25b6..fa7e602a5 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1807,7 +1807,12 @@ Word16 ApplyFdCng_ivas_fx( { FOR( ; j <= hFdCngCom->part[k]; j++ ) { +#ifdef FIX_ISSUE_1218 + /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ + cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ +#else cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ +#endif move32(); } } diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index df5f15696..2ad6085ca 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -683,7 +683,12 @@ static void stereo_dft_generate_comfort_noise_fx( factor = L_min( L_add( L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ), W_extract_l( W_mult0_32_32( Mpy_32_16_1( L_sub( factor, L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ) ), ONE_BY_MAX_K ), hStereoCng->xfade_frame_counter ) ) ), factor ); /* q_div */ FOR( ; j <= hFdCngCom->part[k]; j++ ) { +#ifdef FIX_ISSUE_1218 + /* NOTE: saturation is added here as part of issue 1218 fix. After rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ + hFdCngCom->cngNoiseLevel[j] = L_shl_sat( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ +#else hFdCngCom->cngNoiseLevel[j] = L_shl( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ +#endif move32(); } } -- GitLab From 0d47aa8edd2143480c4c989b7202724d3afa7bdf Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 12:30:48 +0530 Subject: [PATCH 0107/1221] Fix for 3GPP issue 1192: areas of reduced energy observed Link #1192 --- lib_enc/tcx_utils_enc_fx.c | 193 ++++++++++++------------------------- 1 file changed, 62 insertions(+), 131 deletions(-) diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index bafd932a3..4d8f26031 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2399,6 +2399,7 @@ void tcx_noise_factor_fx( *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); } + void tcx_noise_factor_ivas_fx( Word32 *x_orig, /* i: unquantized mdct coefficients */ Word16 x_orig_e, /* i: exponent */ @@ -2415,8 +2416,9 @@ void tcx_noise_factor_ivas_fx( Word16 element_mode /* i: element mode */ ) { - Word16 i, k = 0, maxK, segmentOffset; + Word16 i, k, win, segmentOffset; Word32 sqErrorNrg, n; + Word64 sqErrorNrg64; Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1; Word32 accu1, accu2, tmp32; Word16 tmp1, tmp2, s; @@ -2427,7 +2429,6 @@ void tcx_noise_factor_ivas_fx( Flag Overflow = 0; move32(); #endif - move16(); assert( nTransWidth <= 16 ); @@ -2436,8 +2437,10 @@ void tcx_noise_factor_ivas_fx( nTransWidth_1 = sub( nTransWidth, 1 ); /*Adjust noise filling level*/ - sqErrorNrg = L_deposit_l( 0 ); - n = L_deposit_l( 0 ); + sqErrorNrg64 = 0; + move64(); + n = 0; + move32(); /* get inverse frame length */ tmp1 = getInvFrameLen( L_frame ); @@ -2463,15 +2466,13 @@ void tcx_noise_factor_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */ { segmentOffset = i; - maxK = 1; - move16(); move16(); } ELSE { /* find last nonzero line below iFirstLine, use it as start offset */ tmp1 = shr( iFirstLine, 1 ); - FOR( i = iFirstLine; i > tmp1; i-- ) + FOR( ; i > tmp1; i-- ) { IF( sqQ[i] != 0 ) { @@ -2484,16 +2485,6 @@ void tcx_noise_factor_ivas_fx( inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); } - /* initialize left (k) and right (maxK) non-zero neighbor pointers */ - k = 0; - move16(); - FOR( maxK = 1; maxK < nTransWidth; maxK++ ) - { - IF( sqQ[i + maxK] != 0 ) - { - BREAK; - } - } i = add( i, 1 ); segmentOffset = i; move16(); @@ -2501,17 +2492,20 @@ void tcx_noise_factor_ivas_fx( IF( LE_16( nTransWidth, 3 ) ) { - accu1 = L_deposit_l( 0 ); - accu2 = L_deposit_l( 0 ); - xMax = L_deposit_l( 0 ); + accu1 = 0; + move32(); + accu2 = 0; + move32(); + xMax = 0; + move32(); - FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k++ ) + FOR( k = i & 0xFFFE; k < lowpassLine; k++ ) { xMax = L_max( xMax, L_abs( x_orig[k] ) ); } s = sub( norm_l( xMax ), 4 ); - FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k += 2 ) + FOR( k = i & 0xFFFE; k < lowpassLine; k += 2 ) { /* even-index bins, left sub-win */ tmp1 = round_fx( L_shl( x_orig[k], s ) ); @@ -2524,13 +2518,15 @@ void tcx_noise_factor_ivas_fx( k = 0; move16(); - IF( accu1 == 0 ) + if ( accu1 == 0 ) { - accu1 = L_deposit_l( 1 ); + accu1 = 1; + move32(); } - IF( accu2 == 0 ) + if ( accu2 == 0 ) { - accu2 = L_deposit_l( 1 ); + accu2 = 1; + move32(); } att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s ); @@ -2545,19 +2541,19 @@ void tcx_noise_factor_ivas_fx( move16(); } - accu1 = L_deposit_l( 0 ); + win = 0; + move16(); - tmp1 = sub( lowpassLine, nTransWidth ); - FOR( ; i <= tmp1; i++ ) + FOR( ; i < lowpassLine; i++ ) { inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); - IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ + IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */ { - k = sub( i, segmentOffset ); - - IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ + IF( win > 0 ) { + k = sub( i, segmentOffset ); + IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); @@ -2590,115 +2586,35 @@ void tcx_noise_factor_ivas_fx( n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } } - sqErrorNrg = L_add( sqErrorNrg, accu1 ); - accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */ - k = 0; - move16(); - } - - FOR( ; maxK < nTransWidth; maxK++ ) - { - IF( sqQ[i + maxK] != 0 ) + FOR( k = segmentOffset; k < i - win; k++ ) { - BREAK; - } - } - segmentOffset = add( i, 1 ); /* new segment might start at next line */ - } - ELSE /* current line is zero, so update pointers & segment sum */ - { - IF( LT_16( k, nTransWidth ) ) - { - k = add( k, 1 ); - } - - tmp2 = sub( maxK, nTransWidth ); - test(); - IF( tmp2 < 0 && NE_16( element_mode, IVAS_CPE_MDCT ) ) - { - maxK = sub( maxK, 1 ); - } - - test(); - IF( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) ) - { - maxK = sub( nTransWidth, 1 ); - } - - /* update segment sum: magnitudes scaled by smoothing function */ - /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ - tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); - accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); - } - } - - FOR( ; i < lowpassLine; i++ ) - { - inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); - - IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ - { - k = sub( i, segmentOffset ); - - IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ - { - IF( LE_16( nTransWidth, 3 ) ) - { - tmp2 = sub( k, c1 ); - IF( tmp2 > 0 ) - { - n = L_msu( n, k, (Word16) 0x8000 ); - } - IF( tmp2 > 0 ) - { - n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - } - IF( tmp2 <= 0 ) - { - n = L_mac( n, int_sqr[k], c2 ); - } + sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); + sqQ[k] = 0; + move32(); } - ELSE + FOR( ; win > 0; win-- ) { - tmp2 = sub( k, 12 ); - IF( tmp2 > 0 ) - { - n = L_msu( n, k, (Word16) 0x8000 ); - } - IF( tmp2 > 0 ) - { - n = L_sub( n, 0x70000 ); - } - IF( tmp2 <= 0 ) - { - n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); - } + sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); + sqQ[k++] = 0; + move32(); } - sqErrorNrg = L_add( sqErrorNrg, accu1 ); } - segmentOffset = add( i, 1 ); /* no new segments since maxK remains 1 */ + segmentOffset = add( i, 1 ); /* new segment might start at next line */ } - ELSE /* current line is zero, so update pointers & energy sum */ + ELSE /* current line is zero, so update pointers & segment sum */ { - IF( LT_16( k, nTransWidth ) ) + IF( LT_16( win, nTransWidth ) ) { - k = add( k, 1 ); - } - IF( LT_16( maxK, nTransWidth ) ) - { - maxK = sub( maxK, 1 ); + win = add( win, 1 ); } - /* update segment sum: magnitudes scaled by smoothing function */ - /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ - tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); - accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); + sqQ[i] = L_shl( Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ), inv_gain2_e ); + move32(); } } - - k = sub( i, segmentOffset ); - IF( k > 0 ) /* add last segment sum to sum of segment magnitudes */ + IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */ { + k = sub( i, segmentOffset ); IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); @@ -2731,14 +2647,27 @@ void tcx_noise_factor_ivas_fx( n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } } - sqErrorNrg = L_add( sqErrorNrg, accu1 ); + FOR( k = segmentOffset; k < i - win; k++ ) + { + sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); + sqQ[k] = 0; + move32(); + } + FOR( ; win > 0; win-- ) + { + sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); + sqQ[k++] = 0; + move32(); + } } /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { + tmp2 = W_norm( sqErrorNrg64 ); + sqErrorNrg = W_extract_l( W_shr( sqErrorNrg64, sub( 32, tmp2 ) ) ); // 31 - (x_orig_e - 1) - 32 + tmp2 tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); - s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 ); + s = add( add( add( x_orig_e, sub( 31, tmp2 ) ), -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; tmp1 = shl_o( tmp1, s, &Overflow ); BASOP_SATURATE_WARNING_ON_EVS; @@ -2762,8 +2691,10 @@ void tcx_noise_factor_ivas_fx( move16(); *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); + move16(); } + void tcx_encoder_memory_update_fx( Word16 *wsig, /* i : target weighted signal */ Word16 *xn_buf, /* i/o: mdct output buffer/time domain weigthed synthesis */ -- GitLab From 119e85bf66c4f8d93c381c18f43bb25b0960d8fb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 12:37:44 +0530 Subject: [PATCH 0108/1221] Fix for 3GPP issue 1284: Assert in ic_bwe_enc_specMapping_ivas_fx of BASOP encoder with OMASA LTV input coded at 24.4 kbps Link #1284 --- lib_enc/ivas_stereo_icbwe_enc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index 407f66cfe..5da4c239a 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -219,8 +219,11 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( u_fx = extract_l( *specMapping_fx ); - tmp = mult( b_fx, b_fx ); // b_e + b_e; - tmp1 = mult( a_fx, c_fx ); // a_e + c_e + 2 + + /*only possible saturation is -32768 and -32768 to avoid crash in that case mult_sat is used instead of mult*/ + + tmp = mult_sat( b_fx, b_fx ); // b_e + b_e; + tmp1 = mult_sat( a_fx, c_fx ); // a_e + c_e + 2 exp = BASOP_Util_Add_MantExp( tmp, add( b_e, b_e ), tmp1, add( a_e, add( c_e, 2 ) ), &temp_fx ); /* Q15-exp */ test(); -- GitLab From 3fcb6e833731821485d4855821e600021da26cec Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 08:56:01 +0100 Subject: [PATCH 0109/1221] fix NB PF - tmp hack --- lib_dec/acelp_core_dec_ivas_fx.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index f02e6d337..90360d635 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1498,7 +1498,18 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( st->last_bwidth == NB && st->hPFstat != NULL ) { - Copy( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); + } + ELSE +#endif + { + // VE: TBV: tmp hack - this is a bug in IVAS + Copy( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr ); + } + IF( st->bwidth == NB ) { st->hPFstat->on = 1; -- GitLab From 0a01289c10e58a9ab2ecfa93a0061768fd7d11fc Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 09:55:43 +0100 Subject: [PATCH 0110/1221] try revert acelp_core_dec_fx() --- lib_dec/evs_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 2f0873ba5..ada1a68de 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -346,7 +346,7 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES2aa IF( ( error = acelp_core_dec_ivas_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) #else IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) -- GitLab From b2e1ffd8a00ee1b64d0a8f963182946b67874649 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 10:27:06 +0100 Subject: [PATCH 0111/1221] fix CNA --- lib_dec/acelp_core_dec_ivas_fx.c | 22 +++++++++++++++++++--- lib_dec/evs_dec_fx.c | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 90360d635..09d370760 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1748,10 +1748,26 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( ( st->flag_cna == 0 ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->last_flag_cna, 1 ) && ( ( st->last_core == ACELP_CORE && !( EQ_16( st->last_coder_type, AUDIO ) && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || EQ_16( st->last_core, AMR_WB_CORE ) ) ) { - FOR( i = 0; i < ( st->hFdCngDec->hFdCngCom->frameSize ) / 2; i++ ) +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) { - psyn_fx[i] = add( psyn_fx[i], shr_r( mult_r( st->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * ( st->hFdCngDec->hFdCngCom->frameSize / 4 )], st->hFdCngDec->hFdCngCom->fftlenFac ), -st->Q_syn ) ); - move16(); + // VE:TBC - in FLP, it is: + // v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2 ); + // v_add( temp_buf, syn, syn, st->L_frame / 2 ); + FOR( i = 0; i < st->L_frame / 2; i++ ) + { + psyn_fx[i] = add( psyn_fx[i], shr_r( st->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st->L_frame / 4], negate( st->Q_syn ) ) ); + move16(); + } + } + ELSE +#endif + { + FOR( i = 0; i < ( st->hFdCngDec->hFdCngCom->frameSize ) / 2; i++ ) + { + psyn_fx[i] = add( psyn_fx[i], shr_r( mult_r( st->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * ( st->hFdCngDec->hFdCngCom->frameSize / 4 )], st->hFdCngDec->hFdCngCom->fftlenFac ), -st->Q_syn ) ); + move16(); + } } } diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index ada1a68de..2f0873ba5 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -346,7 +346,7 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ -#ifdef REMOVE_EVS_DUPLICATES2aa +#ifdef REMOVE_EVS_DUPLICATES2 IF( ( error = acelp_core_dec_ivas_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) #else IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) -- GitLab From 7ece91aa0a09b57044bd7dc06052f4403f6fdc0e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 15:04:01 +0530 Subject: [PATCH 0112/1221] Comment update --- lib_enc/ivas_stereo_icbwe_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index 5da4c239a..16c12be50 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -220,7 +220,7 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( u_fx = extract_l( *specMapping_fx ); - /*only possible saturation is -32768 and -32768 to avoid crash in that case mult_sat is used instead of mult*/ + /* while performing (-32768)*(-32768), overflow occurs because the result comes out as 32768 after mult. This is the only case for mult where overflow happens. In order to avoid this scenario mult_sat is used */ tmp = mult_sat( b_fx, b_fx ); // b_e + b_e; tmp1 = mult_sat( a_fx, c_fx ); // a_e + c_e + 2 -- GitLab From 95a6efce548173b6b0c53bf197c5c1447615abfa Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Feb 2025 11:13:52 +0100 Subject: [PATCH 0113/1221] applied the patches from the review. --- lib_enc/ACcontextMapping_enc_fx.c | 85 +++++++++++++++---------------- lib_enc/stat_enc.h | 2 +- 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 2c58b4557..f0298a647 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -16,8 +16,8 @@ #include "prot_fx_enc.h" #include "ivas_prot.h" /* Range coder header file */ -#define MAKE_NUMBER_QX(number,QX) ((number)<<(QX)) -#define MAKE_VARIABLE_QX(variable,QX) W_shl(W_deposit32_l(L_deposit_l(( variable) ) ), (QX)) +#define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) +#define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /*-------------------------------------------------------------------* * ACcontextMapping_encode2_no_mem_s17_LC_fx() @@ -1218,15 +1218,15 @@ static Word16 find_last_nz_pair_fx( *-------------------------------------------------------------------*/ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( - Word16 *x, /* Spectral coefficients Q0*/ - const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) Q0*/ - Word16 *lastnz_out, /* Q0 */ - Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring Q0*/ - const Word16 target, /* Target bits Q0*/ - Word16 *stop, /* Q0 */ - Word16 mode, /* Q0 */ - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ - ) + Word16 *x, /* Spectral coefficients Q0*/ + const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) Q0*/ + Word16 *lastnz_out, /* Q0 */ + Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring Q0*/ + const Word16 target, /* Target bits Q0*/ + Word16 *stop, /* Q0 */ + Word16 mode, /* Q0 */ + CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ +) { /* Common variables */ Word16 a1, b1; @@ -1234,14 +1234,14 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( UWord16 t; Word16 lastnz, lastnz2; Word16 rateFlag; - Word64 bit_estimate_accu; + Word64 bit_estimate_fx; Word16 symbol; const UWord8 *lookup; Word64 nbits2_accu; /* Initialization */ - bit_estimate_accu = MAKE_NUMBER_QX(2, Q23 ); + bit_estimate_fx = MAKE_NUMBER_QX(2, Q23 ); move64(); nbits2_accu = 0; @@ -1255,14 +1255,14 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( WHILE( LT_16( k, nt / 2 ) ) { - bit_estimate_accu = W_add( bit_estimate_accu, MAKE_NUMBER_QX(1, Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX(1, Q23 ) ); k = shl( k, 1 ); i = add( i, 2 ); /* check while condition */ } - nbits2_accu = bit_estimate_accu; + nbits2_accu = bit_estimate_fx; move64(); IF( hm_cfg ) @@ -1350,8 +1350,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( b1 = (Word16) abs( x[b1_i] ); lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); - bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); @@ -1361,8 +1361,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { pki = lookup[lev1]; /* ESC symbol */ - bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX(2, Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX(2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1374,10 +1374,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[lev1]; symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ - bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ - IF( GT_32( W_shr( bit_estimate_accu, Q8 ), L_shl( target, Q15 ) ) ) + IF( GT_32( W_shr( bit_estimate_fx, Q8 ), L_shl( target, Q15 ) ) ) { stop2 = 1; move16(); @@ -1390,7 +1390,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( ELSE { lastnz2 = add( b1_i, 1 ); - nbits2_accu = bit_estimate_accu; + nbits2_accu = bit_estimate_fx; move64(); } @@ -1432,7 +1432,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( W_shr(bit_estimate_accu, Q7 ) ); + total_output_bits = round_fx( W_shr(bit_estimate_fx, Q7 ) ); IF( *stop ) { @@ -1528,8 +1528,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); rateQ = add( rateFlag, extract_l( GT_16( k, shr( nt, 1 ) ) ) ); /* Q0 */ - bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); - bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ lookup = &ari_lookup_s17_LC[t + shl( rateQ, NBITS_CONTEXT )]; /* Q0 */ @@ -1541,8 +1541,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ move16(); - bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - bit_estimate_accu = W_add_nosat( bit_estimate_accu, MAKE_VARIABLE_QX(2, Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX(2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1557,10 +1557,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ - bit_estimate_accu = W_add_nosat( bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ - IF( GT_32( W_shr( bit_estimate_accu, Q8 ), L_shl( target, Q15 ) ) ) + IF( GT_32( W_shr( bit_estimate_fx, Q8 ), L_shl( target, Q15 ) ) ) { overflow_flag = 1; move16(); @@ -1569,7 +1569,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { IF( abs_s( x[k] ) || abs_s( x[k + 1] ) ) /* No overflow & non-zero tuple */ { - nbits2_accu = bit_estimate_accu; /* exp(bit_estimate_e) */ + nbits2_accu = bit_estimate_fx; /* exp(bit_estimate_e) */ move64(); lastnz2 = add( k, 2 ); @@ -1599,7 +1599,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } IF( EQ_16( mode, -1 ) ) { - tot_bits2 = round_fx( W_shr( bit_estimate_accu, Q7 ) ); + tot_bits2 = round_fx( W_shr( bit_estimate_fx, Q7 ) ); } IF( overflow_flag == 0 ) /* No overflow */ { @@ -1614,7 +1614,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } ELSE { - *stop = round_fx( W_shr( bit_estimate_accu, Q7 ) ); + *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); move16(); } } @@ -1665,7 +1665,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( move16(); } - hContextMem->bit_estimate_accu = MAKE_NUMBER_QX(2, Q23 ); + hContextMem->bit_estimate_fx = MAKE_NUMBER_QX(2, Q23 ); move64(); @@ -1682,7 +1682,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( WHILE( LT_16( k, hContextMem->nt_half ) ) { - hContextMem->bit_estimate_accu = W_add( hContextMem->bit_estimate_accu, MAKE_NUMBER_QX(1, Q23 ) ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_NUMBER_QX( 1, Q23 ) ); move64(); k = shl( k, 1 ); @@ -1769,8 +1769,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); /* Q0 */ /* Signs Bits */ - hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); - hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); move32(); move32(); @@ -1785,13 +1785,12 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( pki = lookup[lev1]; /* Q0 */ move16(); - hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, MAKE_VARIABLE_QX(2, Q23 ) ); + hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); move32(); move32(); - // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; // hContextMem->bit_estimate += 2; /* Add the 2 LSB bits that were shifted out */ @@ -1804,8 +1803,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( pki = lookup[lev1]; /* Q0 */ move16(); - symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol Q0*/ - hContextMem->bit_estimate_accu = W_add_nosat( hContextMem->bit_estimate_accu, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol Q0*/ + hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); move32(); // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; @@ -1825,8 +1824,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( hContextMem->ctx = add( i_mult( s_and( hContextMem->ctx, 0xf ), 16 ), t ); /* Q0 */ move16(); - } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( W_shr( hContextMem->bit_estimate_accu, Q7 ) ); /* Q0 */ + } /*end of the 2-tuples loop*/ + total_output_bits = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */ // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index a3a743509..ee7f7f9b4 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -2348,7 +2348,7 @@ typedef struct context_rc_mem_struct { int16_t nbits_old; int16_t ctx; - Word64 bit_estimate_accu; + Word64 bit_estimate_fx; int16_t rateFlag; int16_t lastnz; int16_t nt_half; -- GitLab From 4454ffcb6b9557f8f989a470878993c52fce6f6e Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Feb 2025 11:30:22 +0100 Subject: [PATCH 0114/1221] added a comment for the datatype (Q23). --- lib_enc/ACcontextMapping_enc_fx.c | 2 +- lib_enc/stat_enc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index f0298a647..d20db6b86 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1234,7 +1234,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( UWord16 t; Word16 lastnz, lastnz2; Word16 rateFlag; - Word64 bit_estimate_fx; + Word64 bit_estimate_fx; /* Q23 */ Word16 symbol; const UWord8 *lookup; diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index ee7f7f9b4..0fa9aeb88 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -2348,7 +2348,7 @@ typedef struct context_rc_mem_struct { int16_t nbits_old; int16_t ctx; - Word64 bit_estimate_fx; + Word64 bit_estimate_fx; /* Q23 */ int16_t rateFlag; int16_t lastnz; int16_t nt_half; -- GitLab From 94c98bdb687a8609009c9fe94b80c33329734b41 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 11:30:34 +0100 Subject: [PATCH 0115/1221] REMOVE_EVS_DUPLICATES3 --- lib_com/bits_alloc_fx.c | 3 ++- lib_com/gs_inact_switching_fx.c | 5 +++-- lib_com/prot_fx.h | 32 ++++++++++++++++++++---------- lib_dec/FEC_fx.c | 4 ++++ lib_dec/FEC_scale_syn_fx.c | 3 ++- lib_dec/acelp_core_switch_dec_fx.c | 6 ++++++ lib_dec/amr_wb_dec_fx.c | 17 ++++++++++++++++ lib_dec/cng_dec_fx.c | 3 ++- lib_dec/dec_ace_fx.c | 6 ++++++ lib_dec/dec_gen_voic_fx.c | 3 ++- lib_dec/dec_pit_exc_fx.c | 3 +++ lib_dec/dec_uv_fx.c | 3 ++- lib_dec/evs_dec_fx.c | 2 +- lib_dec/fd_cng_dec_fx.c | 4 +++- lib_dec/gs_dec_fx.c | 18 +++++++++++++++-- lib_dec/lsf_dec_fx.c | 3 ++- lib_enc/acelp_core_enc_fx.c | 28 ++++++++++++++++++++++++-- lib_enc/acelp_core_switch_enc_fx.c | 6 ++++++ lib_enc/transition_enc_fx.c | 27 +++++++++++++++++++++++++ 19 files changed, 152 insertions(+), 24 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 83a98a85f..53c5ca474 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -761,6 +761,7 @@ static ivas_error acelp_FCB_allocator_ivas( * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz *--------------------------------------------------------------------*/ +#ifndef REMOVE_EVS_DUPLICATES ivas_error config_acelp1( const Word16 enc_dec, /* i : encoder/decoder flag */ const Word32 total_brate, /* i : total bitrate */ @@ -1875,7 +1876,7 @@ ivas_error config_acelp1( * - should be in range of <6700; 24350> for ACELP@12.8kHz * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz *--------------------------------------------------------------------*/ - +#endif ivas_error config_acelp1_IVAS( const Word16 enc_dec, /* i : encoder/decoder flag */ const Word32 total_brate, /* i : total bitrate */ diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 52635d502..5e74feb0c 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -38,6 +38,8 @@ /* RETURN ARGUMENTS : */ /* _ None */ /*========================================================================*/ + +#ifndef REMOVE_EVS_DUPLICATES void Inac_swtch_ematch_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ @@ -155,8 +157,7 @@ void Inac_swtch_ematch_fx( return; } - - +#endif void Inac_switch_ematch_ivas_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index bef07e952..f80814a0e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4776,6 +4776,7 @@ Word16 BITS_ALLOC_config_acelp( const Word16 narrowband, const Word16 nb_subfr ); +#ifndef REMOVE_EVS_DUPLICATES3 ivas_error config_acelp1( const Word16 enc_dec, /* i : encoder/decoder flag */ const Word32 total_brate, /* i : total bitrate */ @@ -4802,7 +4803,7 @@ ivas_error config_acelp1( const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ); - +#endif Word16 set_ACELP_flag( const Word16 element_mode, /* i : element mode */ const Word32 element_brate, /* i : element bitrate */ @@ -5762,6 +5763,7 @@ void tcx_ltp_post32( Word32 *tcx_buf, /* sig_q */ Word16 sig_q ); +#ifndef REMOVE_EVS_DUPLICATES3 // gs_inact_switching_fx.c void Inac_swtch_ematch_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ @@ -5777,6 +5779,7 @@ void Inac_swtch_ematch_fx( const short last_core, /* i : Last core used */ const short last_codec_mode /* i : Last codec mode */ ); +#endif void Inac_switch_ematch_ivas_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ @@ -6035,6 +6038,7 @@ void td_bwe_dec_init_fx( const Word32 output_Fs /* i : output sampling rate */ ); +#ifndef REMOVE_EVS_DUPLICATES3 // lsf_dec_fx.c void lsf_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ @@ -6048,7 +6052,7 @@ void lsf_dec_fx( , const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ ); - +#endif void lsf_dec_ivas_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 tc_subfr, /* i : TC subframe index Q0*/ @@ -6204,6 +6208,7 @@ void lsf_mid_dec_fx( Word16 lsp_mid[] /* o : quantized LSPs Q15*/ ); +#ifndef REMOVE_EVS_DUPLICATES3 // cng_dec_fx.c void CNG_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ @@ -6214,7 +6219,7 @@ void CNG_dec_fx( Word16 *allow_cn_step, /* o : allow CN step Q0 */ Word16 *sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0 */ Word32 *q_env ); - +#endif void CNG_dec_ivas_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 last_element_mode, /* i : last element mode Q0 */ @@ -6819,6 +6824,7 @@ void PulseResynchronization_fx( Word32 /*float*/ const pitchEnd /*i Q16*/ ); +#ifndef REMOVE_EVS_DUPLICATES3 // gs_dec_fx.c void decod_audio_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -6833,7 +6839,7 @@ void decod_audio_fx( , Word16 *gain_buf /*Q14*/ ); - +#endif void decod_audio_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ @@ -6852,6 +6858,7 @@ void decod_audio_ivas_fx( const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6*/ ); +#ifndef REMOVE_EVS_DUPLICATES3 void gsc_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ @@ -6864,7 +6871,7 @@ void gsc_dec_fx( const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ Word16 Q_exc ); - +#endif void gsc_dec_ivas_fx( Decoder_State *st_fx, /* i/o: State structure */ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ @@ -7080,6 +7087,7 @@ void re8_PPV_fx( Word16 y[] /* o : point in RE8 (8-dimensional integer vector) Q0 */ ); +#ifndef REMOVE_EVS_DUPLICATES3 // dec_pit_exc_fx.c void dec_pit_exc_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -7099,7 +7107,7 @@ void dec_pit_exc_fx( const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ #endif ); - +#endif void dec_pit_exc_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* i : LP filter coefficient */ @@ -7539,6 +7547,7 @@ void configureFdCngDec_fx( const Word16 Last_L_frame, const Word16 element_mode ); +#ifndef REMOVE_EVS_DUPLICATES3 /* Apply the CLDFB-based CNG */ Word16 ApplyFdCng_fx( Word16 *timeDomainInput, /* i : pointer to time domain i */ @@ -7552,7 +7561,7 @@ Word16 ApplyFdCng_fx( Decoder_State *st, const Word16 concealWholeFrame, /* i : binary flag indicating frame loss */ Word16 is_music ); - +#endif Word16 ApplyFdCng_ivas_fx( Word16 *timeDomainInput, /* i : pointer to time domain input */ Word16 Q, @@ -8185,6 +8194,7 @@ void FEC_pitch_estim_fx( Word16 element_mode /* i : element mode */ ); +#ifndef REMOVE_EVS_DUPLICATES3 // FEC_scale_sync_fx.c void FEC_scale_syn_fx( const Word16 L_frame, /* i : length of the frame */ @@ -8215,7 +8225,7 @@ void FEC_scale_syn_fx( const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ const Word16 force_scaling /* i: force scaling */ ); - +#endif void FEC_scale_syn_ivas_fx( const Word16 L_frame, /* i : length of the frame */ Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ @@ -8532,6 +8542,7 @@ Word16 FEC_synchro_exc_fx( /* o : do_WI flag const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ ); +#ifndef REMOVE_EVS_DUPLICATES3 // dec_uv_fx.c void decod_unvoiced_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -8544,7 +8555,7 @@ void decod_unvoiced_fx( Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ Word16 *gain_buf ); - +#endif void decod_unvoiced_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ @@ -8588,6 +8599,7 @@ void gaus_L2_dec( Word16 *seed_acelp /*i/o : random seed Q0 */ ); +#ifndef REMOVE_EVS_DUPLICATES3 // dec_gen_voic_fx.c ivas_error decod_gen_voic_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -8604,7 +8616,7 @@ ivas_error decod_gen_voic_fx( Word16 *unbits, /* number of unused bits */ Word16 *gain_buf /*Q14*/ ); - +#endif ivas_error decod_gen_voic_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 L_frame, /* i : length of the frame */ diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index 0686996f3..ae222b3ca 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -511,6 +511,9 @@ void FEC_exc_estim_fx( /* st_fx->L_frame / L_SUBFR */ tmp = shr( st_fx->L_frame, 6 ); /* Replication of the last spectrum, with a slight downscaling of its dynamic */ +#ifdef REMOVE_EVS_DUPLICATES + gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc ); +#else IF( st_fx->element_mode == EVS_MONO ) { gsc_dec_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, st_fx->Q_exc ); @@ -519,6 +522,7 @@ void FEC_exc_estim_fx( { gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc ); } +#endif *tmp_noise = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ move16(); /* Transform back to time domain */ diff --git a/lib_dec/FEC_scale_syn_fx.c b/lib_dec/FEC_scale_syn_fx.c index f6439b166..714a60166 100644 --- a/lib_dec/FEC_scale_syn_fx.c +++ b/lib_dec/FEC_scale_syn_fx.c @@ -50,6 +50,7 @@ /* _ None */ /*========================================================================*/ +#ifndef REMOVE_EVS_DUPLICATES void FEC_scale_syn_fx( const Word16 L_frame, /* i : length of the frame */ Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ @@ -614,7 +615,7 @@ void FEC_scale_syn_fx( return; } - +#endif void FEC_scale_syn_ivas_fx( const Word16 L_frame, /* i : length of the frame */ Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index f347cdb7e..6bdf57083 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -128,7 +128,13 @@ ivas_error acelp_core_switch_dec_fx( /*----------------------------------------------------------------* * Excitation decoding *----------------------------------------------------------------*/ + +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); +#else config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); +#endif + decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); /*----------------------------------------------------------------* diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 8a2ef7b40..8881b26ba 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -631,9 +631,15 @@ ivas_error amr_wb_dec_fx( move16(); } +#ifdef REMOVE_EVS_DUPLICATES + FEC_scale_syn_ivas_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); +#else FEC_scale_syn_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); +#endif frame_ener_fx( L_FRAME, st_fx->clas_dec, syn_fx, pitch_buf_tmp[3], &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 ); } @@ -712,10 +718,17 @@ ivas_error amr_wb_dec_fx( * (smoothing is performed in the excitation domain and signal is resynthesized after) *------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES + FEC_scale_syn_ivas_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, + MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, + st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, + st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, 0, 0 ); +#else FEC_scale_syn_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, 0, 0 ); +#endif /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ frame_ener_fx( L_FRAME, st_fx->last_good, syn_fx, shr( FEC_pitch_fx, 6 ), &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 ); @@ -772,7 +785,11 @@ ivas_error amr_wb_dec_fx( st_fx->hPFstat->on = 1; move16(); test(); +#ifdef REMOVE_EVS_DUPLICATES + formant_post_filt_ivas_fx( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl( st_fx->psf_lp_noise_fx, 15 ), st_fx->total_brate, sub( amr_io_class, AUDIO_CLAS ) == 0 ); +#else formant_post_filt_fx( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl( st_fx->psf_lp_noise_fx, 15 ), st_fx->total_brate, sub( amr_io_class, AUDIO_CLAS ) == 0 ); +#endif } /*----------------------------------------------------------------* diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index 3590dae71..3f6a97b98 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -26,6 +26,7 @@ static void shb_CNG_decod_ivas_fx( Decoder_State *st_fx, const Word16 *synth_fx, * Decode residual signal energy *-----------------------------------------------------------------*/ +#ifndef REMOVE_EVS_DUPLICATES void CNG_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 last_element_mode, /* i : last element mode Q0 */ @@ -696,7 +697,7 @@ void CNG_dec_fx( return; } - +#endif void CNG_dec_ivas_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 last_element_mode, /* i : last element mode Q0 */ diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index e327d4cfb..cb7556b24 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -681,9 +681,15 @@ void decoder_acelp_fx( move16(); } +#ifdef REMOVE_EVS_DUPLICATES + FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, syn, pBuf_scaleSyn, st->enr_old_fx, 0, + st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, + exc, exc2, A, &( st->old_enr_LP ), mem_back, mem_syn, st->Q_exc, st->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, force_scale_syn ); +#else FEC_scale_syn_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, syn, pBuf_scaleSyn, st->enr_old_fx, 0, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, exc, exc2, A, &( st->old_enr_LP ), mem_back, mem_syn, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, force_scale_syn ); +#endif } /* update ACELP synthesis memory */ Copy( mem_syn, st->mem_syn2_fx, M ); diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 8ee335e3f..c369c4865 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -36,6 +36,7 @@ /* _ None */ /*======================================================================*/ +#ifndef REMOVE_EVS_DUPLICATES ivas_error decod_gen_voic_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 L_frame, /* i : length of the frame */ @@ -503,7 +504,7 @@ ivas_error decod_gen_voic_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*======================================================================*/ - +#endif ivas_error decod_gen_voic_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 L_frame, /* i : length of the frame */ diff --git a/lib_dec/dec_pit_exc_fx.c b/lib_dec/dec_pit_exc_fx.c index 4e18eebce..bc12fd306 100644 --- a/lib_dec/dec_pit_exc_fx.c +++ b/lib_dec/dec_pit_exc_fx.c @@ -29,6 +29,8 @@ /* RETURN ARGUMENTS : */ /* _ None */ /*==========================================================================*/ + +#ifndef REMOVE_EVS_DUPLICATES void dec_pit_exc_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* i : LP filter coefficient */ @@ -456,6 +458,7 @@ void dec_pit_exc_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*==========================================================================*/ +#endif void dec_pit_exc_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* i : LP filter coefficient */ diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index 6a15732a0..e98858996 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -25,6 +25,7 @@ static void gain_dec_gacelp_uv_fx( * Decode unvoiced (UC) frames *-------------------------------------------------------------------*/ +#ifndef REMOVE_EVS_DUPLICATES void decod_unvoiced_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ @@ -112,7 +113,7 @@ void decod_unvoiced_fx( * * Decode unvoiced (UC) frames *-------------------------------------------------------------------*/ - +#endif void decod_unvoiced_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 2f0873ba5..ada1a68de 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -346,7 +346,7 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES2aa IF( ( error = acelp_core_dec_ivas_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) #else IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index a3c9b5826..b17113495 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -572,6 +572,8 @@ void deleteFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec ) Returns: error */ + +#ifndef REMOVE_EVS_DUPLICATES Word16 ApplyFdCng_fx( Word16 *timeDomainInput, /* i : pointer to time domain input Q*/ Word16 Q, @@ -1160,7 +1162,7 @@ Word16 ApplyFdCng_fx( return 0; } - +#endif Word16 ApplyFdCng_ivas_fx( Word16 *timeDomainInput, /* i : pointer to time domain input Q*/ Word16 Q, diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 72e07e57f..622fe6a26 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -31,6 +31,8 @@ /* RETURN ARGUMENTS : */ /* _ None */ /*==========================================================================*/ + +#ifndef REMOVE_EVS_DUPLICATES void decod_audio_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ @@ -96,12 +98,18 @@ void decod_audio_fx( st_fx->GSC_noisy_speech = 0; /* Q0 */ move16(); } + /* set bit-allocation */ #ifdef ADD_LRTD config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif +#endif + /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ @@ -529,6 +537,7 @@ void decod_audio_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*==========================================================================*/ +#endif void decod_audio_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ @@ -600,12 +609,14 @@ void decod_audio_ivas_fx( st_fx->GSC_noisy_speech = 0; move16(); } + /* set bit-allocation */ -#if 1 // def ADD_LRTD +#if 1 // def ADD_LRTD or def REMOVE_EVS_DUPLICATES config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif + /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ @@ -825,7 +836,7 @@ void decod_audio_ivas_fx( Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); } -#if 1 // def ADD_LRTD +#if 1 // def ADD_LRTD or def REMOVE_EVS_DUPLICATES dec_pit_exc_ivas_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); #else dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf ); @@ -1077,6 +1088,8 @@ void decod_audio_ivas_fx( /* RETURN ARGUMENTS : */ /* _None */ /*==========================================================================*/ + +#ifndef REMOVE_EVS_DUPLICATES void gsc_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ @@ -1404,6 +1417,7 @@ void gsc_dec_fx( /* RETURN ARGUMENTS : */ /* _None */ /*==========================================================================*/ +#endif void gsc_dec_ivas_fx( Decoder_State *st_fx, /* i/o: State structure */ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index 50b5ec341..40628a5bb 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -100,6 +100,7 @@ static void dqlsf_CNG_fx( /* _ None */ /*===========================================================================*/ +#ifndef REMOVE_EVS_DUPLICATES void lsf_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 tc_subfr, /* i : TC subframe index Q0*/ @@ -353,7 +354,7 @@ void lsf_dec_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*===========================================================================*/ - +#endif void lsf_dec_ivas_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 tc_subfr, /* i : TC subframe index Q0*/ diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 6449367c8..97254972d 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -401,10 +401,17 @@ ivas_error acelp_core_enc_fx( test(); IF( !nelp_mode && !ppp_mode ) { +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, + st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, + st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); + +#else config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif } /*-----------------------------------------------------------------* @@ -537,9 +544,15 @@ ivas_error acelp_core_enc_fx( { tc_classif_enc_fx( Q_new, st_fx->L_frame, &tc_subfr_fx, &position, attack_flag, st_fx->pitch[0], res_fx ); +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, + tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif } /*---------------------------------------------------------------* @@ -604,9 +617,15 @@ ivas_error acelp_core_enc_fx( lsp_mid_bck_fx, mCb1_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen_fx ); /* Configure ACELP bit allocation */ +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, + st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif /* redo LSF quantization */ #ifdef LSF_RE_USE_SECONDARY_CHANNEL @@ -1267,7 +1286,9 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( !nelp_mode && !ppp_mode ) { - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, + st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, + st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } /*-----------------------------------------------------------------* @@ -1404,7 +1425,9 @@ ivas_error acelp_core_enc_ivas_fx( { tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, + -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, + st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } /*---------------------------------------------------------------* @@ -1461,6 +1484,7 @@ ivas_error acelp_core_enc_ivas_fx( { /* restore memories of LSF quantizer and synthesis filter */ lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); + /* Configure ACELP bit allocation */ config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index d521d85a2..70a84c198 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -148,8 +148,14 @@ void acelp_core_switch_enc_fx( /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ + +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, + GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#else config_acelp1( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#endif encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 02372138d..adb529ca6 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -213,10 +213,16 @@ void transition_enc_fx( IF( EQ_16( *tc_subfr, TC_0_0 ) ) { /* this is called only to compute unused bits */ +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, + st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#else config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#endif } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, sub( shift_wsp, 1 ) ); move16(); @@ -325,10 +331,17 @@ void transition_enc_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, + unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#else config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#endif } + /*-----------------------------------------------------------------* * get number of bits for pitch encoding *-----------------------------------------------------------------*/ @@ -1033,11 +1046,18 @@ void transition_enc_ivas_fx( IF( EQ_16( *tc_subfr, TC_0_0 ) ) { +#ifdef REMOVE_EVS_DUPLICATES + /* this is called only to compute unused bits */ + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, + st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#else /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#endif } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, sub( shift_wsp, 1 ) ); move16(); @@ -1146,10 +1166,17 @@ void transition_enc_ivas_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { +#ifdef REMOVE_EVS_DUPLICATES + config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, + unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#else config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); +#endif } + /*-----------------------------------------------------------------* * get number of bits for pitch encoding *-----------------------------------------------------------------*/ -- GitLab From b45ca67f12f69b4f452fa9facf50911748af6f74 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 12:00:06 +0100 Subject: [PATCH 0116/1221] fix build --- lib_com/bits_alloc_fx.c | 3 ++- lib_com/prot_fx.h | 3 ++- lib_dec/acelp_core_switch_dec_fx.c | 6 +++++- lib_dec/dec_amr_wb_fx.c | 5 +++++ lib_dec/dec_gen_voic_fx.c | 3 ++- lib_dec/dec_uv_fx.c | 11 ++++++++++- lib_dec/pit_dec_fx.c | 4 ++-- 7 files changed, 28 insertions(+), 7 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 53c5ca474..1d8a90048 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -439,6 +439,7 @@ static Word16 fcb_table( * Routine to allocate fixed innovation codebook bit-budget *--------------------------------------------------------------------*/ +#ifndef REMOVE_EVS_DUPLICATES static ivas_error acelp_FCB_allocator( Word16 *nBits, /* i/o: available bit-budget */ Word16 fixed_cdk_index[], /* o : codebook index Q0 */ @@ -599,7 +600,7 @@ static ivas_error acelp_FCB_allocator( return error; } - +#endif static ivas_error acelp_FCB_allocator_ivas( Word16 *nBits, /* i/o: available bit-budget */ Word16 fixed_cdk_index[], /* o : codebook index Q0 */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index f80814a0e..34b72e544 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -7166,6 +7166,7 @@ void Mode2_delta_pit_dec( Word16 **pt_indice /* i/o: pointer to Vector of Q indexes */ ); +#ifndef REMOVE_EVS_DUPLICATES3 Word16 pit_decode_fx( /* o : floating pitch value */ Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ @@ -7185,7 +7186,7 @@ Word16 pit_decode_fx( /* o : floating pitch value const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ #endif ); - +#endif Word16 pit_decode_ivas_fx( /* o : floating pitch value */ Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 6bdf57083..36bac44ec 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -825,7 +825,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) #else - Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) + Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) #endif IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st_fx->cldfbAna ) ), IVAS_ERR_OK ) ) { @@ -919,7 +919,11 @@ static void decod_gen_voic_core_switch_fx( * Decode pitch lag *----------------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES3 + pitch = pit_decode_ivas_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ +#else pitch = pit_decode_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ +#endif /*--------------------------------------------------------------* * Find the adaptive codebook vector. diff --git a/lib_dec/dec_amr_wb_fx.c b/lib_dec/dec_amr_wb_fx.c index baea98a2c..8a980f68d 100644 --- a/lib_dec/dec_amr_wb_fx.c +++ b/lib_dec/dec_amr_wb_fx.c @@ -71,12 +71,17 @@ void decod_amr_wb_fx( * Decode pitch lag *----------------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES + *pt_pitch_fx = pit_decode_ivas_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); +#else *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR #ifdef ADD_LRTD , 0, NULL #endif ); +#endif + /*--------------------------------------------------------------* * Find the adaptive codebook vector *--------------------------------------------------------------*/ diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index c369c4865..bcbef190f 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -677,6 +677,7 @@ ivas_error decod_gen_voic_ivas_fx( IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { + // VE: function to be merged? gain_dec_lbr_ivas_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); } ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) @@ -801,7 +802,7 @@ ivas_error decod_gen_voic_ivas_fx( { idx = idiv1616( i_subfr_fx, L_SUBFR ); } - + // VE: function to be merged prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index e98858996..6a9fbcf3f 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -208,7 +208,16 @@ void decod_unvoiced_ivas_fx( move16(); /* update LP filtered gains for the case of frame erasures */ - lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_FRAME ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_FRAME ); + } + ELSE +#endif + { + lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_FRAME ); + } /*-------------------------------------------------------* * - Find the total excitation. * diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c index b72c2bae1..6c37bb906 100644 --- a/lib_dec/pit_dec_fx.c +++ b/lib_dec/pit_dec_fx.c @@ -319,7 +319,7 @@ void Mode2_delta_pit_dec( /* _ (Word16 ) pitch : close loop integer pitch Q6 */ /*=======================================================================*/ - +#ifndef REMOVE_EVS_DUPLICATES3 Word16 pit_decode_fx( /* o : floating pitch value */ Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ @@ -599,7 +599,7 @@ Word16 pit_decode_fx( /* o : floating pitch value /* _ (Word16 ) pitch : close loop integer pitch Q6 */ /*=======================================================================*/ - +#endif Word16 pit_decode_ivas_fx( /* o : floating pitch value */ Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ -- GitLab From ea99231dc0aac04b07fbe0ef59ee1b80919e3f31 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Feb 2025 12:28:52 +0100 Subject: [PATCH 0117/1221] applied the formatting patch. --- lib_enc/ACcontextMapping_enc_fx.c | 72 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index d20db6b86..0e816e77c 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1238,10 +1238,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( Word16 symbol; const UWord8 *lookup; - Word64 nbits2_accu; + Word64 nbits2_accu; /* Initialization */ - bit_estimate_fx = MAKE_NUMBER_QX(2, Q23 ); + bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); move64(); nbits2_accu = 0; @@ -1255,11 +1255,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( WHILE( LT_16( k, nt / 2 ) ) { - bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX(1, Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX( 1, Q23 ) ); k = shl( k, 1 ); i = add( i, 2 ); /* check while condition */ - } nbits2_accu = bit_estimate_fx; @@ -1362,7 +1361,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[lev1]; /* ESC symbol */ bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX(2, Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1373,7 +1372,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[lev1]; - symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ @@ -1390,7 +1389,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( ELSE { lastnz2 = add( b1_i, 1 ); - nbits2_accu = bit_estimate_fx; + nbits2_accu = bit_estimate_fx; move64(); } @@ -1432,7 +1431,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( W_shr(bit_estimate_fx, Q7 ) ); + total_output_bits = round_fx( W_shr( bit_estimate_fx, Q7 ) ); IF( *stop ) { @@ -1542,7 +1541,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX(2, Q23 ) ); + bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1556,7 +1555,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ move16(); - symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ @@ -1607,37 +1606,37 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); } ELSE /* Overflow */ - { - IF( *stop ){ - *stop = tot_bits2; /* Q0 */ - move16(); - } - ELSE { - *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); - move16(); - } - } - - *lastnz_out = lastnz; /* Q0 */ + IF( *stop ){ + *stop = tot_bits2; /* Q0 */ move16(); - *nEncoded = lastnz2; /* Q0 */ + } + ELSE + { + *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); move16(); - /* Safety mechanism to avoid overflow */ - test(); - IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) - { - FOR( k = 0; k < lastnz2; k++ ) - { - x[k] = 0; - move16(); - } - } + } +} - return tot_bits2; +*lastnz_out = lastnz; /* Q0 */ +move16(); +*nEncoded = lastnz2; /* Q0 */ +move16(); +/* Safety mechanism to avoid overflow */ +test(); +IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) +{ + FOR( k = 0; k < lastnz2; k++ ) + { + x[k] = 0; + move16(); } } +return tot_bits2; +} +} + /*-------------------------------------------------------------------* * RCcontextMapping_encode2_estimate_bandWise_start_fx() @@ -1665,9 +1664,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( move16(); } - hContextMem->bit_estimate_fx = MAKE_NUMBER_QX(2, Q23 ); + hContextMem->bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); move64(); - /* Init */ @@ -1824,7 +1822,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( hContextMem->ctx = add( i_mult( s_and( hContextMem->ctx, 0xf ), 16 ), t ); /* Q0 */ move16(); - } /*end of the 2-tuples loop*/ + } /*end of the 2-tuples loop*/ total_output_bits = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */ // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); -- GitLab From 4bc1b7981ad272a770c662102f661f5f7adf6837 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 12:51:07 +0100 Subject: [PATCH 0118/1221] REMOVE_EVS_DUPLICATES3 --- lib_com/options.h | 2 +- lib_com/prot_fx.h | 3 ++- lib_dec/acelp_core_dec_ivas_fx.c | 2 +- lib_dec/acelp_core_switch_dec_fx.c | 2 +- lib_dec/dec_post_fx.c | 10 +++++++--- lib_dec/decision_matrix_dec_fx.c | 2 +- lib_dec/evs_dec_fx.c | 2 +- lib_dec/post_dec_fx.c | 16 ++++++++++++++++ 8 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index f45ee973d..b30960266 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,5 +156,5 @@ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ #define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions */ -#define REMOVE_EVS_DUPLICATES2 +#define REMOVE_EVS_DUPLICATES3 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 34b72e544..8c823e1f1 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6639,6 +6639,7 @@ void nb_post_filt_fx( const Word16 disable_hpf /* i : flag to diabled HPF */ ); +#ifndef REMOVE_EVS_DUPLICATES void formant_post_filt_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *synth_in, /* i : 12k8 synthesis */ @@ -6649,7 +6650,7 @@ void formant_post_filt_fx( Word32 rate, /* (i) : bit-rate */ const Word16 off_flag /* i : off flag */ ); - +#endif void formant_post_filt_ivas_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *synth_in, /* i : 12k8 synthesis */ diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 09d370760..7c9e50b85 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -2371,7 +2371,7 @@ ivas_error acelp_core_dec_ivas_fx( ELSE { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact #endif { diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 36bac44ec..7a6348905 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -920,7 +920,7 @@ static void decod_gen_voic_core_switch_fx( *----------------------------------------------------------------------*/ #ifdef REMOVE_EVS_DUPLICATES3 - pitch = pit_decode_ivas_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ + pitch = pit_decode_ivas_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*Q6*/ #else pitch = pit_decode_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ #endif diff --git a/lib_dec/dec_post_fx.c b/lib_dec/dec_post_fx.c index a6e06db54..df3fb1f8f 100644 --- a/lib_dec/dec_post_fx.c +++ b/lib_dec/dec_post_fx.c @@ -33,8 +33,9 @@ static void calc_st_filt_local_fx( Word16 *apond2, Word16 *apond1, Word16 *parco static void modify_pst_param_fx( const Word16 lp_noise, Word16 *g1, Word16 *g2, const Word16 coder_type, Word16 *gain_factor ); +#ifndef REMOVE_EVS_DUPLICATES static void Dec_formant_postfilt_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); - +#endif static void Dec_formant_postfilt_ivas_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); static void calc_st_filt_ivas_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero, const Word16 extl ); @@ -255,6 +256,8 @@ static void Dec_postfilt_fx( * * Main routine to perform formant post filtering *--------------------------------------------------------------------------*/ + +#ifndef REMOVE_EVS_DUPLICATES void formant_post_filt_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *synth_in, /* i : 12k8 synthesis */ @@ -379,7 +382,7 @@ void formant_post_filt_fx( p_Aq += ( M + 1 ); } } - +#endif void formant_post_filt_ivas_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *synth_in, /* i : 12k8 synthesis */ @@ -519,6 +522,7 @@ void formant_post_filt_ivas_fx( * k1 = 1st parcor calculated on {hi} * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 *----------------------------------------------------------------------------*/ +#ifndef REMOVE_EVS_DUPLICATES static void Dec_formant_postfilt_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q14*/ @@ -597,7 +601,7 @@ static void Dec_formant_postfilt_fx( return; } - +#endif static void Dec_formant_postfilt_ivas_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q14*/ diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index ff03f8bc5..8433960b2 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -713,7 +713,7 @@ void decision_matrix_dec_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES /*-----------------------------------------------------------------* * set inactive coder_type flag in ACELP core *-----------------------------------------------------------------*/ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index ada1a68de..1a7338315 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -346,7 +346,7 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ -#ifdef REMOVE_EVS_DUPLICATES2aa +#ifdef REMOVE_EVS_DUPLICATES IF( ( error = acelp_core_dec_ivas_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) #else IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/post_dec_fx.c b/lib_dec/post_dec_fx.c index d581f810a..b5d56d8fb 100644 --- a/lib_dec/post_dec_fx.c +++ b/lib_dec/post_dec_fx.c @@ -139,13 +139,21 @@ void post_decoder( { st->hPFstat->on = 1; move16(); +#ifdef REMOVE_EVS_DUPLICATES + formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); +#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); +#endif } ELSE { st->hPFstat->on = 0; move16(); +#ifdef REMOVE_EVS_DUPLICATES + formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); +#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); +#endif } } @@ -302,13 +310,21 @@ void post_decoder_ivas_fx( { st->hPFstat->on = 1; move16(); +#ifdef REMOVE_EVS_DUPLICATES + formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); +#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); +#endif } ELSE { st->hPFstat->on = 0; move16(); +#ifdef REMOVE_EVS_DUPLICATES + formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); +#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); +#endif } } -- GitLab From e4e68a27ef3d8305598a922e2fd8e7916282b9dc Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 15:29:00 +0100 Subject: [PATCH 0119/1221] fix old_syn_12k8_16k_fx[] --- lib_dec/acelp_core_dec_ivas_fx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 7c9e50b85..e7b1032a2 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -849,7 +849,16 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn IF( st->hBWE_FD != NULL ) { - save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - this is likely a bug in IVAS + { + save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); + } + ELSE +#endif + { + save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); + } } } -- GitLab From 613673b0883bf0e0c18f0ba671f8905e0f73419a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 21:20:48 +0530 Subject: [PATCH 0120/1221] Bug fixes in orig-specturm q, in functions ITF_Detect_fx and Q_lsf_tcxlpc_fx --- lib_com/prot_fx.h | 10 +++ lib_com/tns_base.c | 139 ++++++++++++++++++++++++++++++ lib_enc/igf_enc.c | 4 +- lib_enc/ivas_core_enc.c | 8 +- lib_enc/ivas_tcx_core_enc.c | 2 +- lib_enc/lsf_msvq_ma_enc_fx.c | 159 +++++++++++++++++++++++++++++++++++ lib_enc/prot_fx_enc.h | 13 +++ lib_enc/tcx_utils_enc_fx.c | 2 +- 8 files changed, 329 insertions(+), 8 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9fae6a1c1..0e093b77f 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3642,6 +3642,16 @@ Word16 ITF_Detect_fx( Word32 const pSpectrum[], Word16 *curr_order, Word16 Q ); +Word16 ITF_Detect_ivas_fx( Word32 const pSpectrum[], + const Word16 startLine, + const Word16 stopLine, + const Word16 maxOrder, + Word16 *A, + Word16 *Q_A, + Word16 *predictionGain, + Word16 *curr_order, + Word16 Q ); + void ITF_Apply_fx( Word32 spectrum[], Word16 startLine, Word16 stopLine, diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index d4de526d6..af4a87d34 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -602,6 +602,145 @@ Word16 ITF_Detect_fx( return 1; } + +Word16 ITF_Detect_ivas_fx( + const Word32 pSpectrum[], /*Q*/ + const Word16 startLine, /*Q0*/ + const Word16 stopLine, /*Q0*/ + const Word16 maxOrder, /*Q0*/ + Word16 *A, /*Q_A*/ + Word16 *Q_A, + Word16 *predictionGain, /*Q7*/ + Word16 *curr_order, /*Q0*/ + Word16 Q ) +{ + Word32 norms[MAX_SUBDIVISIONS]; + Word16 num_subdivisions, i, length; + Word16 iStartLine, iEndLine, spectrumLength; + Word32 rxx[ITF_MAX_FILTER_ORDER + 1]; + Word16 q_rxx[ITF_MAX_FILTER_ORDER + 1]; + Word32 temp_spectrum[640]; + const Word16 *pWindow; + const Word32 *ptr_spectrum1, *ptr_spectrum2; + Word16 iSubdivisions, lag; + Word16 headroom, guard_bits, shift, q_min; + Word64 sum; + Word16 fac, q_fac, exp, q_temp; + Word32 temp; + + IF( maxOrder <= 0 ) + { + return 0; + } + pWindow = tnsAcfWindow_fx; + set_zero_fx( norms, MAX_SUBDIVISIONS ); + set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */ + set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */ + + spectrumLength = sub( stopLine, startLine ); + num_subdivisions = 0; + move16(); + + /* Calculate norms for each spectrum part */ + FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ ) + { + /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */ + iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/ + /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */ + iEndLine = add( startLine, mult( imult1616( spectrumLength, add( iSubdivisions, 1 ) ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/ + + + /* Variable initialization */ + /* norms[iSubdivisions] = sum2_f(pSpectrum + iStartLine - IGF_START_MN, iEndLine - iStartLine); */ + + ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN ); + length = sub( iEndLine, iStartLine ); + headroom = L_norm_arr( ptr_spectrum1, length ); + guard_bits = find_guarded_bits_fx( length ); + shift = sub( headroom, guard_bits ); + + Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift + + sum = 0; + move64(); + FOR( i = 0; i < length; i++ ) + { + sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1 + } + + IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) ) + { + BREAK; + } + + /* fac = 1.0f / norms[iSubdivisions]; */ + exp = W_norm( sum ); + sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp + fac = div_s( ONE_IN_Q14, extract_h( W_extract_h( sum ) ) ); // 15+14-(2(Q+shift)+1+exp-48) = 76-(2(Q+shift)+exp) + q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) ); + pWindow = tnsAcfWindow_fx; + + /* For additional loop condition */ + /* Variable initialization */ + /*for ( lag = 1; lag <= maxOrder; lag++ ) + { + rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ); + pWindow++; + }*/ + + ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN; + FOR( lag = 1; lag <= maxOrder; lag++ ) + { + /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */ + ptr_spectrum2 = temp_spectrum + lag; // pSpectrum + iStartLine - IGF_START_MN + lag; + + sum = 0; + move64(); + FOR( i = 0; i < iEndLine - iStartLine - lag; i++ ) + { + sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1 + } + exp = W_norm( sum ); + sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp + temp = Mpy_32_32( L_mult0( fac, *pWindow ), W_extract_h( sum ) ); // (q_fac+15)+(2(Q+shift)+1+exp-32)-31 = q_fac+2(Q+shift)+exp-47 + q_temp = sub( add( q_fac, add( shl( add( Q, shift ), 1 ), exp ) ), 47 ); + + /* rxx[lag] += fac * (*pWindow) * dotp(pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag); */ + q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 ); + rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) ); + q_rxx[lag] = q_min; + move32(); + move16(); + + pWindow++; + } + + num_subdivisions = add( num_subdivisions, 1 ); + } + + minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min ); + q_min = s_min( Q29, q_min ); + + FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ ) + { + rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) ); + move32(); + } + + IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */ + { + rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min ); + move32(); + + /* Limit the maximum order to spectrum length/4 */ + ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain ); + + *curr_order = maxOrder; /*Q0*/ + move16(); + } + + return 1; +} /* Helper functions for Hufmann table coding */ diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 6cccea43b..a85843be2 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -575,8 +575,8 @@ static void IGF_CalculateEnvelope_ivas_fx( strt_cpy = add( strt_cpy, 1 ); } - sfbEnergyTileR = L_deposit_l( BASOP_Util_Divide3232_Scale( sfbEnergyTileR, width, &tmp_e ) ); - sfbEnergyTileR_e = add( sub( sfbEnergyTileR_e, Q15 ), tmp_e ); + sfbEnergyTileR = L_deposit_h( BASOP_Util_Divide3232_Scale( sfbEnergyTileR, width, &tmp_e ) ); + sfbEnergyTileR_e = add( sub( sfbEnergyTileR_e, Q31 ), tmp_e ); IF( sfbEnergyTileR == 0 ) { diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 3bc869675..0c7fe9094 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -498,14 +498,14 @@ ivas_error ivas_core_enc_fx( IF( EQ_16( nSubframes, NB_DIV ) ) { Word16 max_e = s_max( orig_spectrum_e[i][0], orig_spectrum_e[i][1] ); - Scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i], N_TCX10_MAX, sub( orig_spectrum_e[i][0], max_e ) ); // exp(max_e) - Scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i] + N_TCX10_MAX, N_TCX10_MAX, sub( orig_spectrum_e[i][1], max_e ) ); // exp(max_e) - hMCT->q_orig_spectrum_long_fx[cpe_id][i] = max_e; + scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i], N_TCX10_MAX, sub( orig_spectrum_e[i][0], max_e ) ); // exp(max_e) + scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i] + N_TCX10_MAX, N_TCX10_MAX, sub( orig_spectrum_e[i][1], max_e ) ); // exp(max_e) + hMCT->q_orig_spectrum_long_fx[cpe_id][i] = sub( Q31, max_e ); move16(); } ELSE { - hMCT->q_orig_spectrum_long_fx[cpe_id][i] = orig_spectrum_e[i][0]; + hMCT->q_orig_spectrum_long_fx[cpe_id][i] = sub( Q31, orig_spectrum_e[i][0] ); move16(); } diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 0680fc795..f072e5436 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -466,7 +466,7 @@ void stereo_tcx_core_enc( E_LPC_lsp_lsf_conversion( lsp_fx, lsf_fx, M ); /* Quantize */ - Q_lsf_tcxlpc_fx( lsf_fx, lsf_tcx_q_fx, lspq_ind, param_lpc, M, st->narrowBand, tcx_lpc_cdk, st->mem_MA_fx, st->hTcxCfg->coder_type, st->Bin_E_fx, Q_ener ); + Q_lsf_tcxlpc_ivas_fx( lsf_fx, lsf_tcx_q_fx, lspq_ind, param_lpc, M, st->narrowBand, tcx_lpc_cdk, st->mem_MA_fx, st->hTcxCfg->coder_type, st->Bin_E_fx, st->q_Bin_E ); /* Account for consumed bits */ nbits_lpc[0] = TCXLPC_NUMBITS; diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index d30f2c249..b81cc18e8 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -652,6 +652,165 @@ Word16 Q_lsf_tcxlpc_fx( return NumIndices; } + +Word16 Q_lsf_tcxlpc_ivas_fx( + /* const */ Word16 lsf[], /* i : original lsf */ + Word16 lsf_q[], /* o : quantized lsf */ + Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ + Word16 indices[], /* o : VQ indices */ + const Word16 lpcorder, /* i : LPC order */ + const Word16 narrowband, /* i : narrowband flag */ + const Word16 cdk, /* i : codebook selector */ + const Word16 mem_MA[], /* i : MA memory */ + const Word16 coder_type, + const Word32 *Bin_Ener, + const Word16 Q_ener ) +{ + Word16 weights[M + 1]; + Word16 pred[M16k]; + Word16 i; + Word16 NumIndices; + Word16 lsf_q_ind[M16k]; + const Word16 *means; + Word16 lsf_rem[M]; + Word16 lsf_rem_q_ind[M]; + + Unified_weighting_fx( &Bin_Ener[L_FFT / 2], Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M ); + + move16(); + NumIndices = 0; + + /* Put disabled flag */ + indices[NumIndices] = 0; + move16(); + NumIndices = add( NumIndices, 1 ); + + /* Inter-frame prediction */ + + means = lsf_means[narrowband]; /* 14Q1 * 1.28 */ + + FOR( i = 0; i < lpcorder; ++i ) + { + pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28 + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/ + move16(); + } + + /* Subtract prediction */ + + FOR( i = 0; i < lpcorder; ++i ) + { + lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */ + move16(); + } + + + msvq_enc_fx( + lsf_codebook[narrowband][cdk], + lsf_dims, + lsf_offs, + lsf, + lsf_numlevels, + kMaxC, + TCXLPC_NUMSTAGES, + weights, + lpcorder, + lpcorder, + indices + NumIndices ); + msvq_dec( + lsf_codebook[narrowband][cdk], + lsf_dims, + lsf_offs, + TCXLPC_NUMSTAGES, + lpcorder, + lpcorder, + indices + NumIndices, +#ifdef IVAS_MSVQ + 0, NULL, +#endif + lsf_q ); + NumIndices = add( NumIndices, TCXLPC_NUMSTAGES ); + + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q_ind[i] = lsf_q[i]; + move16(); + } + + /* Update flag */ + indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk ); + move16(); + + /* Get residual vector */ + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) ); + move16(); + } + + /* Quantize using extra stage(s) */ + msvq_enc_fx( + lsf_ind_codebook[narrowband][cdk], + lsf_ind_dims, + lsf_ind_offs, + lsf_rem, + lsf_ind_numlevels, + kMaxC, + TCXLPC_IND_NUMSTAGES, + weights, + lpcorder, + lpcorder, + indices + NumIndices ); + /* Only add contribution if flag is enabled */ + IF( indices[0] ) + { + /* Decode */ + msvq_dec( + lsf_ind_codebook[narrowband][cdk], + lsf_ind_dims, + lsf_ind_offs, + TCXLPC_IND_NUMSTAGES, + lpcorder, + lpcorder, + indices + NumIndices, +#ifdef IVAS_MSVQ + 0, NULL, +#endif + lsf_rem_q_ind ); + NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES ); + + /* Add to MA-removed vector */ + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] ); + move16(); + } + } + + /* Add inter-frame prediction */ + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q[i] = add( lsf_q[i], pred[i] ); + lsf[i] = add( lsf[i], pred[i] ); + move16(); + move16(); + } + + reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX ); + + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] ); + move16(); + } + reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX ); + + IF( lsp_q_ind ) + { + E_LPC_lsf_lsp_conversion /*lsf2lsp*/ ( lsf_q_ind, lsp_q_ind, lpcorder ); + } + + return NumIndices; +} /*--------------------------------------------------------------------------* * enc_lsf_tcxlpc_fx() * diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index bc08aae24..280a76c94 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2652,6 +2652,19 @@ Word16 Q_lsf_tcxlpc_fx( const Word32 *Bin_Ener, const Word16 Q_ener ); +Word16 Q_lsf_tcxlpc_ivas_fx( + /* const */ Word16 lsf[], /* i : original lsf */ + Word16 lsf_q[], /* o : quantized lsf */ + Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ + Word16 indices[], /* o : VQ indices */ + const Word16 lpcorder, /* i : LPC order */ + const Word16 narrowband, /* i : narrowband flag */ + const Word16 cdk, /* i : codebook selector */ + const Word16 mem_MA[], /* i : MA memory */ + const Word16 coder_type, + const Word32 *Bin_Ener, + const Word16 Q_ener ); + Word16 signalling_mode1_tcx20_enc_fx( Encoder_State *st, /* i : encoder state structure */ Word16 push /*Q0*/ ); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 4d8f26031..35a72b07f 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3825,7 +3825,7 @@ void ProcessIGF_ivas_fx( q_A = 0; move16(); - ITF_Detect_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); + ITF_Detect_ivas_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); test(); IF( LT_32( L_deposit_l( hIGFEnc->tns_predictionGain ), 9646899 /* 1.15 in Q23 */ ) && LT_32( L_deposit_l( predictionGain ), 9646899 /* 1.15 in Q23 */ ) ) -- GitLab From 1ed2851535b85c983858296f3a4b977f57bcb257 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 21:32:05 +0530 Subject: [PATCH 0121/1221] Fix for 3GPP issue 1202: BASOP encoder ParamISM: strong timbre differences in the noise track Link #1202 --- lib_enc/ivas_ism_param_enc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 1430607d6..5e91a30fb 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -307,7 +307,7 @@ void ivas_param_ism_stereo_dmx_fx( /* Smoothing */ cardioid_left[i] = add( mult( 24576 /* 0.75f in Q15 */, cardioid_left[i] ), mult( 8192 /* 0.25f in Q15 */, last_cardioid_left ) ); // Q14 move16(); - grad = mult( sub( cardioid_left[i], last_cardioid_left ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ); /* Q14 */ /* for the right cardioid, multiply with -1 */ + Word32 grad_32 = L_mult( sub( cardioid_left[i], last_cardioid_left ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ); /* Q14+Q16 = Q30 */ /* for the right cardioid, multiply with -1 */ /* Cardioids sum up to 1 */ cardioid_right[i] = sub( ONE_IN_Q14 /* 1.0f in Q14 */, cardioid_left[i] ); /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */ move16(); @@ -316,13 +316,13 @@ void ivas_param_ism_stereo_dmx_fx( { tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, add( last_cardioid_left, mult0( j, grad ) ) ), 15 ) ); /* Qx DMX Left */ - stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + tmp = W_extract_l( W_shr( W_mult_32_32( tmp, L_add( last_cardioid_left, L_shr( Mpy_32_32( L_shl( j, 22 ), grad_32 ), 7 ) ) ), 15 ) ); /* Qx DMX Left */ + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ move32(); tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, add( last_cardioid_right, negate( mult0( j, grad ) ) ) ), 15 ) ); /* Qx DMX Right */ - stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + tmp = W_extract_l( W_shr( W_mult_32_32( tmp, L_add( last_cardioid_right, L_shr( L_negate( Mpy_32_32( L_shl( j, 22 ), grad_32 ) ), 7 ) ) ), 15 ) ); /* Qx DMX Right */ + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ move32(); ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ } -- GitLab From 9ad83d1c7250046e9403523c67c33ac488bcafc5 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 12 Feb 2025 17:09:53 +0100 Subject: [PATCH 0122/1221] REMOVE_EVS_DUPLICATES2 --- lib_com/options.h | 4 +- lib_com/prot_fx.h | 32 +++++++++------ lib_com/swb_tbe_com_fx.c | 3 +- lib_dec/acelp_core_dec_fx.c | 12 +++--- lib_dec/acelp_core_dec_ivas_fx.c | 11 +++-- lib_dec/acelp_core_switch_dec_fx.c | 2 +- lib_dec/dec_LPD_fx.c | 5 +++ lib_dec/dec_ace_fx.c | 5 +++ lib_dec/dec_gen_voic_fx.c | 3 +- lib_dec/dec_tran_fx.c | 8 ++++ lib_dec/gain_dec_fx.c | 4 +- lib_dec/init_dec_fx.c | 1 - lib_dec/pit_dec_fx.c | 2 +- lib_enc/analy_lp_fx.c | 65 +++++++++++++++++++----------- lib_enc/cod_ace_fx.c | 6 +++ lib_enc/enc_gen_voic_fx.c | 7 ++++ lib_enc/enc_tran_fx.c | 5 +++ lib_enc/init_enc_fx.c | 1 - lib_enc/ivas_core_pre_proc.c | 9 +++++ lib_enc/ivas_core_pre_proc_front.c | 4 ++ lib_enc/ivas_front_vad.c | 5 +++ lib_enc/pre_proc_fx.c | 10 ++++- lib_enc/prot_fx_enc.h | 31 ++++++++------ 23 files changed, 163 insertions(+), 72 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index b30960266..dd2eef974 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -155,6 +155,6 @@ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ -#define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions */ -#define REMOVE_EVS_DUPLICATES3 +#define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions, ACELP low-band decoder */ +#define REMOVE_EVS_DUPLICATES2 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 8c823e1f1..c90b7551a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3220,6 +3220,7 @@ void synthesise_fb_high_band_fx( Word16 bpf_memory_Q[], Word16 Qout ); +#ifndef REMOVE_EVS_DUPLICATES2 void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ #ifdef ADD_IVAS_TBE_CODE @@ -3247,6 +3248,7 @@ void prep_tbe_exc_fx( const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ #endif ); +#endif void prep_tbe_exc_ivas_fx( const Word16 L_frame_fx, /* i : length of the frame */ @@ -4776,7 +4778,7 @@ Word16 BITS_ALLOC_config_acelp( const Word16 narrowband, const Word16 nb_subfr ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES ivas_error config_acelp1( const Word16 enc_dec, /* i : encoder/decoder flag */ const Word32 total_brate, /* i : total bitrate */ @@ -5763,7 +5765,7 @@ void tcx_ltp_post32( Word32 *tcx_buf, /* sig_q */ Word16 sig_q ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // gs_inact_switching_fx.c void Inac_swtch_ematch_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ @@ -6038,7 +6040,7 @@ void td_bwe_dec_init_fx( const Word32 output_Fs /* i : output sampling rate */ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // lsf_dec_fx.c void lsf_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ @@ -6208,7 +6210,7 @@ void lsf_mid_dec_fx( Word16 lsp_mid[] /* o : quantized LSPs Q15*/ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // cng_dec_fx.c void CNG_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ @@ -6825,7 +6827,7 @@ void PulseResynchronization_fx( Word32 /*float*/ const pitchEnd /*i Q16*/ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // gs_dec_fx.c void decod_audio_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -6859,7 +6861,7 @@ void decod_audio_ivas_fx( const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6*/ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES void gsc_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ @@ -6940,6 +6942,7 @@ void gain_dec_mless_fx( Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excitation Q16*/ ); +#ifndef REMOVE_EVS_DUPLICATES void gain_dec_lbr_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ const Word16 coder_type, /* i : coding type */ @@ -6954,6 +6957,7 @@ void gain_dec_lbr_fx( , const Word16 L_subfr /* i : subfr lenght */ ); +#endif void gain_dec_lbr_ivas_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ @@ -7088,7 +7092,7 @@ void re8_PPV_fx( Word16 y[] /* o : point in RE8 (8-dimensional integer vector) Q0 */ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // dec_pit_exc_fx.c void dec_pit_exc_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -7167,7 +7171,7 @@ void Mode2_delta_pit_dec( Word16 **pt_indice /* i/o: pointer to Vector of Q indexes */ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES Word16 pit_decode_fx( /* o : floating pitch value */ Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ @@ -7549,7 +7553,7 @@ void configureFdCngDec_fx( const Word16 Last_L_frame, const Word16 element_mode ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES /* Apply the CLDFB-based CNG */ Word16 ApplyFdCng_fx( Word16 *timeDomainInput, /* i : pointer to time domain i */ @@ -8196,7 +8200,7 @@ void FEC_pitch_estim_fx( Word16 element_mode /* i : element mode */ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // FEC_scale_sync_fx.c void FEC_scale_syn_fx( const Word16 L_frame, /* i : length of the frame */ @@ -8544,7 +8548,7 @@ Word16 FEC_synchro_exc_fx( /* o : do_WI flag const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // dec_uv_fx.c void decod_unvoiced_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -8601,7 +8605,7 @@ void gaus_L2_dec( Word16 *seed_acelp /*i/o : random seed Q0 */ ); -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES // dec_gen_voic_fx.c ivas_error decod_gen_voic_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ @@ -9565,6 +9569,8 @@ void d_gain_pred_fx( Word16 *Es_pred, /* o : predicited scaled innovation energy */ Word16 **pt_indice /* i/o: pointer to the buffer of indices */ ); + +#ifndef REMOVE_EVS_DUPLICATES // acelp_core_dec_fx.c ivas_error acelp_core_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ @@ -9590,7 +9596,7 @@ ivas_error acelp_core_dec_fx( STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ const Word16 read_sid_info /* i : read SID info flag */ ); - +#endif // evs_dec_fx.c ivas_error evs_dec_fx( Decoder_State *st_fx, /* i/o : Decoder state structure */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 92271c1f1..c7a8fd1f0 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7131,6 +7131,7 @@ void tbe_celp_exc( /* _ None */ /*======================================================================================*/ +#ifndef REMOVE_EVS_DUPLICATES2 void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ #ifdef ADD_IVAS_TBE_CODE @@ -7299,7 +7300,7 @@ void prep_tbe_exc_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*======================================================================================*/ - +#endif void prep_tbe_exc_ivas_fx( const Word16 L_frame_fx, /* i : length of the frame */ #if 1 // def ADD_IVAS_TBE_CODE diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index fc35cb754..e81ae0428 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -10,6 +10,8 @@ #include "ivas_prot_fx.h" #include "ivas_cnst.h" /* Common constants */ #include "cnst.h" /* Common constants */ + +#ifndef REMOVE_EVS_DUPLICATES /*==========================================================================*/ /* FUNCTION : void acelp_core_dec_fx () */ /*--------------------------------------------------------------------------*/ @@ -661,7 +663,7 @@ ivas_error acelp_core_dec_fx( test(); IF( EQ_32( st_fx->core_brate, SID_2k40 ) && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { - FdCng_decodeSID_fx( st_fx->hFdCngDec->hFdCngCom, st_fx ); // VE: 2 variants needed + FdCng_decodeSID_fx( st_fx->hFdCngDec->hFdCngCom, st_fx ); *sid_bw = 0; move16(); } @@ -691,7 +693,7 @@ ivas_error acelp_core_dec_fx( } } #endif - generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); // VE: 2 variants needed + generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); FdCng_exc( st_fx->hFdCngDec->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); @@ -715,7 +717,6 @@ ivas_error acelp_core_dec_fx( #ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { - // VE: TBV: 'st_fx->L_frame * HIBND_ACB_L_FAC' should be corrected Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); } @@ -754,7 +755,7 @@ ivas_error acelp_core_dec_fx( FOR( i = 0; i < DCT_L_POST; i++ ) { /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); // VE: 2 variants needed + hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); move16(); } } @@ -2054,7 +2055,7 @@ ivas_error acelp_core_dec_fx( { hf_synth_reset_fx( st_fx->hBWE_zero ); #ifdef MSAN_FIX - IF( NE_16( st_fx->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact + IF( NE_16( st_fx->element_mode, EVS_MONO ) ) { set16_fx( st_fx->hBWE_zero->mem_hp400_fx, 0, 6 ); } @@ -2132,3 +2133,4 @@ ivas_error acelp_core_dec_fx( return IVAS_ERR_OK; } +#endif diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index e7b1032a2..fcfbe1e66 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -761,7 +761,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { - // VE: TBV: 'st_fx->L_frame * HIBND_ACB_L_FAC' should be corrected + // VE: TBV: should 'st_fx->L_frame * HIBND_ACB_L_FAC' be corrected in EVS? Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, st->L_frame * HIBND_ACB_L_FAC, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); } @@ -1223,7 +1223,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { - // VE: TBV: this is a bug in EVS - 'st->last_coder_type' should be replaced by 'st->core_brate' + // VE: TBV: this is likely a bug in EVS - 'st->last_coder_type' should be replaced by 'st->core_brate' Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, st->hMusicPF->filt_lfE_fx, st->last_coder_type, st->element_mode, pitch_buf_fx, st->hMusicPF->LDm_enh_lp_gbin_fx, st->Q_exc, &qdct ); } @@ -1760,7 +1760,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { - // VE:TBC - in FLP, it is: + // VE: TBV - is it correct in EVS? in FLP, it is: // v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2 ); // v_add( temp_buf, syn, syn, st->L_frame / 2 ); FOR( i = 0; i < st->L_frame / 2; i++ ) @@ -2381,7 +2381,7 @@ ivas_error acelp_core_dec_ivas_fx( { hf_synth_reset_fx( st->hBWE_zero ); #ifdef REMOVE_EVS_DUPLICATES - IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but conditon is here to keep EVS bit-exact + IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but condition is here to keep EVS bit-exact for the moment #endif { #ifdef MSAN_FIX @@ -2425,8 +2425,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { - non_linearity_fx( bwe_exc_fx, bwe_exc_extended_fx, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, - st->coder_type, voice_factors_fx, st->L_frame ); + non_linearity_fx( bwe_exc_fx, bwe_exc_extended_fx, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); } ELSE #endif diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 7a6348905..81beffb34 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -919,7 +919,7 @@ static void decod_gen_voic_core_switch_fx( * Decode pitch lag *----------------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES3 +#ifdef REMOVE_EVS_DUPLICATES pitch = pit_decode_ivas_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*Q6*/ #else pitch = pit_decode_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index f3443349a..c722418f7 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -555,7 +555,12 @@ void decoder_LPD_fx( st->relax_prev_lsf_interp = 2; move16(); } + +#ifdef REMOVE_EVS_DUPLICATES2 + int_lsp4_ivas_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp ); +#else int_lsp4_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp ); +#endif } ELSE { diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index cb7556b24..5d644c289 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -532,6 +532,10 @@ void decoder_acelp_fx( move16(); IF( st->igf != 0 ) { +#ifdef REMOVE_EVS_DUPLICATES2 + prep_tbe_exc_ivas_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, + gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); +#else prep_tbe_exc_fx( st->L_frame, #ifdef ADD_IVAS_TBE_CODE L_SUBFR, @@ -543,6 +547,7 @@ void decoder_acelp_fx( st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 #endif ); +#endif } /*---------------------------------------------------------* diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index bcbef190f..c369c4865 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -677,7 +677,6 @@ ivas_error decod_gen_voic_ivas_fx( IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { - // VE: function to be merged? gain_dec_lbr_ivas_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); } ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) @@ -802,7 +801,7 @@ ivas_error decod_gen_voic_ivas_fx( { idx = idiv1616( i_subfr_fx, L_SUBFR ); } - // VE: function to be merged + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, diff --git a/lib_dec/dec_tran_fx.c b/lib_dec/dec_tran_fx.c index e886fd337..96eace777 100644 --- a/lib_dec/dec_tran_fx.c +++ b/lib_dec/dec_tran_fx.c @@ -253,9 +253,17 @@ void decod_tran_fx( { tmp_idx_2 = idiv1616( i_subfr, L_SUBFR ); } + +#ifdef REMOVE_EVS_DUPLICATES2 + prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, + st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame_fx, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate ); +#endif /*----------------------------------------------------------------* * Excitation enhancements (update of total excitation signal) diff --git a/lib_dec/gain_dec_fx.c b/lib_dec/gain_dec_fx.c index 5e1712231..00eca187d 100644 --- a/lib_dec/gain_dec_fx.c +++ b/lib_dec/gain_dec_fx.c @@ -601,6 +601,8 @@ void gain_dec_mless_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*==================================================================================*/ + +#ifndef REMOVE_EVS_DUPLICATES void gain_dec_lbr_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ const Word16 coder_type, /* i : coding type */ @@ -969,7 +971,7 @@ void gain_dec_lbr_fx( return; } - +#endif void gain_dec_lbr_ivas_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ const Word16 coder_type, /* i : coding type */ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index d709ff5fc..8aa4f45e1 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -483,7 +483,6 @@ ivas_error init_decoder_fx( } /* TCX core */ - // VE: reduction possible for MCT_CHAN_MODE_LFE channel - see I1-172 IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { IF( ( st_fx->hTcxDec = (TCX_DEC_HANDLE) malloc( sizeof( TCX_DEC_DATA ) ) ) == NULL ) diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c index 6c37bb906..b7f0abec3 100644 --- a/lib_dec/pit_dec_fx.c +++ b/lib_dec/pit_dec_fx.c @@ -319,7 +319,7 @@ void Mode2_delta_pit_dec( /* _ (Word16 ) pitch : close loop integer pitch Q6 */ /*=======================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES3 +#ifndef REMOVE_EVS_DUPLICATES Word16 pit_decode_fx( /* o : floating pitch value */ Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ diff --git a/lib_enc/analy_lp_fx.c b/lib_enc/analy_lp_fx.c index c2f9d0585..b5764ec43 100644 --- a/lib_enc/analy_lp_fx.c +++ b/lib_enc/analy_lp_fx.c @@ -24,19 +24,22 @@ * - update LSPs for the next frame *-------------------------------------------------------------------*/ void analy_lp_ivas_fx( - const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ - const Word16 L_frame, /* i :(q0) length of the frame */ - const Word16 L_look, /* i :(q0) look-ahead */ - Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ - Word16 A[], /* o :(q14) A(z) filter coefficients */ - Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 lsp_new[], /* o :(q15) current frame LSPs */ - Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ - Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ - const Word16 Top[2], /* i :(q0) open loop pitch lag */ - const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ - const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ + const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ + const Word16 L_frame, /* i :(q0) length of the frame */ + const Word16 L_look, /* i :(q0) look-ahead */ + Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ + Word16 A[], /* o :(q14) A(z) filter coefficients */ + Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 lsp_new[], /* o :(q15) current frame LSPs */ + Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ + Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ + const Word16 Top[2], /* i :(q0) open loop pitch lag */ + const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ + const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ +#ifdef REMOVE_EVS_DUPLICATES2 + const Word16 element_mode, /* i : element mode */ +#endif const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ Word16 Q_new, /*i: stores Q for speech*/ Word16 *Q_r /*stores q for ener*/ ) @@ -74,19 +77,24 @@ void analy_lp_ivas_fx( /* Autocorrelations */ autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 ); - /*if ( r[0] < 100.0f && no_thr == 0 )*/ - /*r[0] = 100.0f*/ - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_Comp( r_h[0], r_l[0] ) /* Q_r[1 - i_subfr]*/, sub( 31, add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ) ), 100 /*q0*/, 31 ), -1 ) ) +#ifdef REMOVE_EVS_DUPLICATES2 + IF( NE_16( element_mode, EVS_MONO ) ) +#endif { - /*Q_min stores min of 24 and the actual Q for r*/ - Word16 Q_min = s_min( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), 24 ); /* comparing q with 24 because exponent of 100 is 7 so max q should be 24*/ - L_Extract( L_shl( 100, Q_min ), &r_h[0], &r_l[0] ); /*extracting high and low components of r[0]*/ - FOR( i = 1; i < 17; i++ ) + /*if ( r[0] < 100.0f && no_thr == 0 )*/ + /*r[0] = 100.0f*/ + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_Comp( r_h[0], r_l[0] ) /* Q_r[1 - i_subfr]*/, sub( 31, add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ) ), 100 /*q0*/, 31 ), -1 ) ) { - L_Extract( L_shr( L_Comp( r_h[i], r_l[i] ), sub( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), Q_min ) ), &r_h[i], &r_l[i] ); /*scaling all the values to q24*/ + /*Q_min stores min of 24 and the actual Q for r*/ + Word16 Q_min = s_min( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), 24 ); /* comparing q with 24 because exponent of 100 is 7 so max q should be 24*/ + L_Extract( L_shl( 100, Q_min ), &r_h[0], &r_l[0] ); /*extracting high and low components of r[0]*/ + FOR( i = 1; i < 17; i++ ) + { + L_Extract( L_shr( L_Comp( r_h[i], r_l[i] ), sub( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), Q_min ) ), &r_h[i], &r_l[i] ); /*scaling all the values to q24*/ + } + Q_r[1 - i_subfr] = sub( Q_min, shl( Q_new, 1 ) ); /*updating the q (subtracting shl( Q_new, 1 ) as in later part it is being added-> to maintain q24 )*/ + move16(); } - Q_r[1 - i_subfr] = sub( Q_min, shl( Q_new, 1 ) ); /*updating the q (subtracting shl( Q_new, 1 ) as in later part it is being added-> to maintain q24 )*/ - move16(); } /* Lag windowing */ @@ -124,6 +132,7 @@ void analy_lp_ivas_fx( return; } +#ifndef REMOVE_EVS_DUPLICATES2 void analy_lp_fx( const Word16 speech[], /* i : pointer to the speech frame Q_new*/ const Word16 L_frame, /* i : length of the frame Q0*/ @@ -195,12 +204,20 @@ void analy_lp_fx( IF( EQ_16( sec_chan_low_rate, 1 ) ) { /* LSP interpolation */ +#ifdef REMOVE_EVS_DUPLICATES2 + int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 ); +#else int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 ); +#endif } ELSE { /* LSP interpolation */ +#ifdef REMOVE_EVS_DUPLICATES2 + int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); +#else int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); +#endif } Copy( lsp_new, lsp_old, M ); /* Q15 */ *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */ @@ -208,7 +225,7 @@ void analy_lp_fx( return; } - +#endif /*-------------------------------------------------------------------* * analy_lp_AMR_WB() diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index e701b8e46..aa823cbda 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -409,8 +409,14 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * IF( st->igf != 0 ) { +#ifdef REMOVE_EVS_DUPLICATES2 + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate, + st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate ); +#endif } /*---------------------------------------------------------* diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 6f71b8ba1..39cdba524 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -368,9 +368,16 @@ void encod_gen_voic_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES2 + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, + T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index b4495d4ff..66167c138 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -309,8 +309,13 @@ Word16 encod_tran_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef REMOVE_EVS_DUPLICATES2 + prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame_fx, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 89bbdc898..be2355f08 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -760,7 +760,6 @@ ivas_error init_encoder_fx( * TCX core *-----------------------------------------------------------------*/ - // VE: reduction possible for MCT_CHAN_MODE_LFE channel - see I1-172 test(); IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 541cc620c..bce78a8ee 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -1134,11 +1134,20 @@ ivas_error ivas_compute_core_buffers_fx( IF( Q_new ) { +#ifdef REMOVE_EVS_DUPLICATES2 + analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, sub( *Q_new, 1 ), Q_r ); +#else analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, sub( *Q_new, 1 ), Q_r ); +#endif } ELSE { +#ifdef REMOVE_EVS_DUPLICATES2 + analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, -1, Q_r ); + +#else analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, -1, Q_r ); +#endif } /*--------------------------------------------------------------* diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index fd9b79617..24112da14 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1196,8 +1196,12 @@ ivas_error pre_proc_front_ivas_fx( move16(); } +#ifdef REMOVE_EVS_DUPLICATES2 + analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, element_mode, i, Q_new_loc, Q_r ); +#else analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, i, Q_new_loc, Q_r ); +#endif FOR( Word16 idx = 0; idx < M + 1; idx++ ) { diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index f52bdadb4..751744102 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -673,7 +673,12 @@ ivas_error front_vad_spar_fx( hFrontVad->q_buffer_12k8 = Q_inp_12k8; move16(); +#ifdef REMOVE_EVS_DUPLICATES2 + analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, st->element_mode, 0, Q_inp_12k8, Q_r ); +#else analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, 0 /* <-- sec_chan_low_rate */, Q_inp_12k8, Q_r ); +#endif + FOR( Word16 i = 0; i <= M; i++ ) { epsP_fx[i] = L_Comp( epsP_h[i], epsP_l[i] ); // Q_r[0] diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index bd3d4cb34..c119b59dc 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -214,7 +214,7 @@ void pre_proc_fx( * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* @@ -419,7 +419,11 @@ void pre_proc_fx( alw_voicing[1] = st->voicing_fx[2]; move16(); +#ifdef REMOVE_EVS_DUPLICATES2 + analy_lp_ivas_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, EVS_MONO, 0, *Q_new, Q_r ); +#else analy_lp_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, -1 /*IVAS_CODE !! LowRateFlag*/, *Q_new, Q_r ); +#endif lsp2lsf_fx( lsp_new, lsf_new, M, INT_FS_12k8 ); stab_fac = lsf_stab_fx( lsf_new, st->lsf_old1_fx, 0, L_FRAME ); @@ -1152,7 +1156,11 @@ void pre_proc_fx( Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); } +#ifdef REMOVE_EVS_DUPLICATES2 + analy_lp_ivas_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, EVS_MONO, 0, *Q_new, Q_r ); +#else analy_lp_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, -1 /*IVAS_CODE !! LowRateFlag*/, *Q_new, Q_r ); +#endif /*--------------------------------------------------------------* * Compute Weighted Input diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index bc08aae24..666192389 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -70,23 +70,27 @@ ivas_error acelp_core_enc_fx( #endif ); void analy_lp_ivas_fx( - const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ - const Word16 L_frame, /* i :(q0) length of the frame */ - const Word16 L_look, /* i :(q0) look-ahead */ - Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ - Word16 A[], /* o :(q14) A(z) filter coefficients */ - Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 lsp_new[], /* o :(q15) current frame LSPs */ - Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ - Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ - const Word16 Top[2], /* i :(q0) open loop pitch lag */ - const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ - const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ + const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ + const Word16 L_frame, /* i :(q0) length of the frame */ + const Word16 L_look, /* i :(q0) look-ahead */ + Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ + Word16 A[], /* o :(q14) A(z) filter coefficients */ + Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 lsp_new[], /* o :(q15) current frame LSPs */ + Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ + Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ + const Word16 Top[2], /* i :(q0) open loop pitch lag */ + const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ + const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ +#ifdef REMOVE_EVS_DUPLICATES2 + const Word16 element_mode, /* i : element mode */ +#endif const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ Word16 Q_new, /*i: stores Q for speech*/ Word16 *Q_r /*stores q for ener*/ ); +#ifndef REMOVE_EVS_DUPLICATES2 void analy_lp_fx( const Word16 speech[], /* i : pointer to the speech frame Q_new*/ const Word16 L_frame, /* i : length of the frame Q0*/ @@ -104,6 +108,7 @@ void analy_lp_fx( const Word16 sec_chan_low_rate, /* i : flag to signal second channel Q0*/ Word16 Q_new, Word16 *Q_r ); +#endif void AVQ_cod_fx( /* o: comfort noise gain factor */ const Word16 xri[], /* i: vector to quantize */ -- GitLab From 0f9b0399ed065076529081735c3484fcacedc5b1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Feb 2025 21:47:01 +0530 Subject: [PATCH 0123/1221] Fix for 3GPP issue 1288: Missing scaling in NB post-filter Link #1288 --- lib_com/prot_fx.h | 2 +- lib_dec/acelp_core_dec_ivas_fx.c | 6 +++--- lib_dec/dec_post_fx.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9fae6a1c1..21cb3ba36 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6631,7 +6631,7 @@ void nb_post_filt_fx( const Word16 tmp_noise, /* i : noise energy Q0 */ Word16 *Synth, /* i : 12k8 synthesis Qsyn */ const Word16 *Aq, /* i : LP filter coefficient Q12 */ - const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q6 */ + const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q0 */ const Word16 coder_type, /* i : coder_type */ const Word16 BER_detect, /* i : BER detect flag */ const Word16 disable_hpf /* i : flag to diabled HPF */ diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 0914e7ece..92ea2e032 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1235,7 +1235,7 @@ ivas_error acelp_core_dec_ivas_fx( *------------------------------------------------------------*/ - Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k, -Q6 ); // Q0 + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, 0 ); @@ -1393,7 +1393,7 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( EQ_32( st->total_brate, ACELP_7k20 ) || EQ_32( st->total_brate, ACELP_8k00 ) ) { - Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k, -Q6 ); // Q0 + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, @@ -1430,7 +1430,7 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( st->last_bwidth == NB && st->hPFstat != NULL ) { - Copy( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k ); + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 IF( st->bwidth == NB ) { st->hPFstat->on = 1; diff --git a/lib_dec/dec_post_fx.c b/lib_dec/dec_post_fx.c index a6e06db54..a4f618a3f 100644 --- a/lib_dec/dec_post_fx.c +++ b/lib_dec/dec_post_fx.c @@ -86,7 +86,7 @@ void nb_post_filt_fx( const Word16 tmp_noise, /* i : noise energy Q0 */ Word16 *Synth, /* i : 12k8 synthesis Qsyn */ const Word16 *Aq, /* i : LP filter coefficient Q12 */ - const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q6 */ + const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q0 */ const Word16 coder_type, /* i : coder_type */ const Word16 BER_detect, /* i : BER detect flag */ const Word16 disable_hpf /* i : flag to diabled HPF */ @@ -142,7 +142,7 @@ void nb_post_filt_fx( move16(); FOR( i = 0; i < L_frame; i += L_SUBFR ) { - T0_first = Pitch_buf[j]; // Q6 + T0_first = Pitch_buf[j]; // Q0 move16(); Dec_postfilt_fx( hPFstat, T0_first, &Pf_in[i], p_Aq, &Synth[i], Post_G1, Post_G2, Gain_factor, disable_hpf ); @@ -179,7 +179,7 @@ void nb_post_filt_fx( *----------------------------------------------------------------------------*/ static void Dec_postfilt_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ - const Word16 t0, /* i : pitch delay given by coder Q6 */ + const Word16 t0, /* i : pitch delay given by coder Q0 */ const Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q0 */ const Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */ Word16 *sig_out, /* o : postfiltered output Q15*/ @@ -749,7 +749,7 @@ static void modify_pst_param_fx( * Perform harmonic postfilter *----------------------------------------------------------------------------*/ static void pst_ltp_fx( - Word16 t0, /* i : pitch delay given by coder Q6 */ + Word16 t0, /* i : pitch delay given by coder Q0 */ Word16 *ptr_sig_in, /* i : postfilter i filter (residu2) Qx */ Word16 *ptr_sig_pst0, /* o : harmonic postfilter o Qx */ Word16 gain_factor /* i : Gain Factor (Q15) */ -- GitLab From 3840a36f096c73139aef67304f34d836b55fea37 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 10:43:04 +0530 Subject: [PATCH 0124/1221] Updates for 3GPP issue 1078 Link #1078 --- lib_enc/ext_sig_ana_fx.c | 2 ++ lib_enc/ivas_cpe_enc.c | 48 +++++++++++++++----------------- lib_enc/transient_detection_fx.c | 4 +-- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index f55d87020..fc4a1889a 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -918,6 +918,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( assert( frameno == 0 ); windowed_samples[0] = L_deposit_l( overlap_mode[frameno] ); // Q0 windowed_samples[1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0 + *q_win = 0; + move16(); } IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 6ea59adb3..e681840d0 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -775,36 +775,32 @@ ivas_error ivas_cpe_enc_fx( test(); IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) { - - shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ - sts[1]->q_inp = add( sts[1]->q_inp, shift ); - move16(); - Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp ) */ - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( s_min( sts[1]->q_old_inp, sts[1]->q_inp ), sts[1]->q_old_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp ) */ - sts[1]->q_inp = s_min( sts[1]->q_inp, sts[1]->q_old_inp ); - move16(); - sts[1]->q_old_inp = sts[1]->q_inp; - move16(); - - shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[0]->q_old_inp + shift*/ - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); + Word16 q_min; + q_min = sts[1]->q_old_inp; move16(); - shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[0]->q_inp + shift */ - sts[0]->q_inp = add( sts[0]->q_inp, shift ); + q_min = s_min( q_min, sts[1]->q_inp ); + q_min = s_min( q_min, sts[0]->q_old_inp ); + q_min = s_min( q_min, sts[0]->q_inp ); + + shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); + shift = s_min( shift, norm_arr( sts[1]->input_fx, input_frame ) ); + shift = s_min( shift, norm_arr( sts[0]->old_input_signal_fx, input_frame ) ); + shift = s_min( shift, norm_arr( sts[0]->input_fx, input_frame ) ); + + q_min = add( q_min, shift ); + + scale_sig( sts[1]->input_fx, input_frame, sub( q_min, sts[1]->q_inp ) ); /* q_min */ + scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_min, sts[1]->q_old_inp ) ); /* q_min */ + scale_sig( sts[0]->input_fx, input_frame, sub( q_min, sts[0]->q_inp ) ); /* q_min */ + scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_min, sts[0]->q_old_inp ) ); /* q_min */ + + sts[1]->q_old_inp = q_min; + sts[0]->q_old_inp = q_min; + sts[1]->q_inp = q_min; + sts[0]->q_inp = q_min; move16(); move16(); - Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); /* min( sts[0]->q_inp, sts[0]->q_old_inp ) */ - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( s_min( sts[0]->q_old_inp, sts[0]->q_inp ), sts[0]->q_old_inp ) ); /* min( sts[0]->q_inp, sts[0]->q_old_inp ) */ - sts[0]->q_inp = s_min( sts[0]->q_inp, sts[0]->q_old_inp ); move16(); - sts[0]->q_old_inp = sts[0]->q_inp; move16(); } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 3e4b29acc..d9859a1a1 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -199,9 +199,9 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 } ELSE /* no attack, but set index anyway in case of strong energy increase */ { - W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i - 1], attackRatioThreshold_1_5 ), 1 ); + W_tmp2 = W_shr( W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold_1_5 ), 1 ); W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ( ATTACKTHRESHOLD_E + 1 ) ) ); - W_tmp3 = W_shr( W_mult_32_16( pAccSubblockNrg[i - 2], attackRatioThreshold_1_5 ), 1 ); + W_tmp3 = W_shr( W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold_1_5 ), 1 ); IF( s_and( ( (Word16) GT_64( W_tmp1, W_tmp2 ) ), ( W_sub( W_tmp1, W_tmp3 ) > 0 ) ) ) -- GitLab From 1b3a5ca678b84539b6c71f5531f639658a2ffc67 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Mon, 10 Feb 2025 18:00:00 -0500 Subject: [PATCH 0125/1221] possible fix for 1279 --- lib_com/options.h | 3 ++- lib_dec/ivas_core_dec.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 7fe865756..d6bbaf88a 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,5 +158,6 @@ #define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ -#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index c7893c88d..8d88074a8 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -574,7 +574,9 @@ ivas_error ivas_core_dec_fx( st->cldfbSyn->Q_cldfb_state = Q11; move16(); } +#ifndef FIX_ISSUE_1279 /* the update of prev_Q_syn is already done inside rescale_mem( ) */ st->prev_Q_syn = st->Q_syn; +#endif move16(); IF( save_hb_synth_32_fx ) -- GitLab From 1871be8bd0c2eb214bbce42c11f1a9550f5331dc Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 10:27:06 +0100 Subject: [PATCH 0126/1221] check for complexity artifact folder not being empty this handles failures in previous job runs which still lead to archiving the empty directory --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc48090cd..cba93f48b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1328,7 +1328,9 @@ voip-be-on-merge-request: - public_dir="$CI_JOB_NAME-public" # if is needed to catch case when no artifact is there (first run), similarly as above - - if [[ -d $public_dir ]]; then + # 1. check for public_dir being there as this might not be the case when artifact download failed + # 2. check for public dir not being empty - handle job failures in prev job that happen after the dir is created. In that case, the empty dir is in the artifacts + - if [ -d $public_dir ] && [ ! -z "$( ls -A $public_dir )" ]; then - mv $public_dir/* wmops/ # check here if we have the split-by-levels files present - if not, fake them up with the existing global one # this is needed for the first run with split graphs on a branch where the global version did run previously -- GitLab From ee599155cc18a6691a8ebc9e7c0878343df4482d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 15:33:04 +0530 Subject: [PATCH 0127/1221] Bug fix in dtx_hangover_addition_fx, integration and Q correction of ITF_Detect_IVAS --- lib_enc/acelp_core_enc_fx.c | 1 + lib_enc/ivas_core_pre_proc_front.c | 2 +- lib_enc/tcx_utils_enc_fx.c | 2 +- lib_enc/vad_fx.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 260934aca..a294d12da 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1377,6 +1377,7 @@ ivas_error acelp_core_enc_ivas_fx( move16(); PREEMPH_FX( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF_fx ); Copy( hLPDmem->old_exc + sub( st->L_frame, M ), hLPDmem->mem_syn, M ); /* Q_new */ + Scale_sig( st->hLPDmem->mem_syn, M, sub( st->hLPDmem->q_mem_syn, Q_new ) ); Residu3_fx( Aq, hLPDmem->old_exc, old_exc_fx, st->L_frame, 0 ); } diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index fd9b79617..6ab82420f 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -853,7 +853,7 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( ( hCPE != NULL && !( lr_vad_enabled && st->idchan == 0 ) ) || hSCE != NULL ) { - *vad_flag_dtx = dtx_hangover_addition_fx( st, st->vad_flag, sub( st->lp_speech_fx, st->lp_noise_fx ), 0, vad_hover_flag, NULL, NULL ); /* Q0 */ + *vad_flag_dtx = ivas_dtx_hangover_addition_fx( st, st->vad_flag, sub( st->lp_speech_fx, st->lp_noise_fx ), 0, vad_hover_flag, NULL, NULL, NULL ); /* Q0 */ move16(); } ELSE diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 35a72b07f..685ed26c1 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3932,7 +3932,7 @@ void ProcessStereoIGF_fx( predictionGain = 0; move16(); - ITF_Detect_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); + ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); test(); hIGFEnc[ch]->flatteningTrigger = LT_32( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q23 ) && LT_32( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index 9ecca6975..38e43b032 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -566,7 +566,7 @@ Word16 ivas_dtx_hangover_addition_fx( test(); test(); test(); - if ( ( GT_16( hVAD->prim_act_he_fx, 31129 ) ) && ( GT_16( hNoiseEst->Etot_lp_fx, 40 * 256 ) ) && ( GT_16( hVAD->vad_prim_cnt_16, 14 ) ) && ( GT_16( hVAD->vad_flag_cnt_50, 48 ) ) ) /* 45 requires roughly > 95% flag activity */ + if ( ( GT_16( hVAD->prim_act_he_fx, 32113 ) ) && ( GT_16( hNoiseEst->Etot_lp_fx, 40 * 256 ) ) && ( GT_16( hVAD->vad_prim_cnt_16, 14 ) ) && ( GT_16( hVAD->vad_flag_cnt_50, 48 ) ) ) /* 45 requires roughly > 95% flag activity */ { hVAD->hangover_cnt_music = 0; move16(); -- GitLab From 6fc185fad21e8d252cb1993bd0d526c77eaf0c67 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 15:38:32 +0530 Subject: [PATCH 0128/1221] Fix for 3GPP issue 1289: Encoder crash for Stereo at 24.4 kbps Link #1289 --- lib_enc/ivas_stereo_icbwe_enc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index 16c12be50..9cf899bcb 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -1030,6 +1030,13 @@ void stereo_icBWE_enc_ivas_fx( IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) { /* IC BWE spectral mapping */ + Word32 max_abs_val; + maximum_abs_32_fx( shb_synth_nonref_fx, L_FRAME16k, &max_abs_val ); + IF( max_abs_val > 0 ) + { + scale_sig32( shb_synth_nonref_fx, L_FRAME16k, -1 ); + shb_synth_nonref_e = sub( shb_synth_nonref_e, -1 ); + } spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); /* Q0 */ } ELSE -- GitLab From 4417eda1ab7dcdcf98ad5510ea76b5c2016a2c9e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 15:41:02 +0530 Subject: [PATCH 0129/1221] Fix for 3GPP issue 1268: High MLD for ParamMC at 80 kbps - signal distributed to incorrect channels Link #1268 --- lib_enc/ivas_mc_param_enc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 0577df340..43162f6de 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -1011,8 +1011,6 @@ static void ivas_param_mc_param_est_enc_fx( move16(); ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_sum_fx[cur_param_band][ref_channel_idx][ref_channel_idx], // ref_ener_e Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e ); - ref_ener_e = Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx]; - move16(); } L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); #ifdef FIX_ISSUE_1154 -- GitLab From 88b261ec8835ba2c79d01348ea082734ef514ef3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 15:59:36 +0530 Subject: [PATCH 0130/1221] Fix for 3GPP issue 1247: Basop Encoder: Noise introduced for Stereo DTX @32kbps Link #1247 --- lib_com/options.h | 1 + lib_enc/ivas_cpe_enc.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index d6bbaf88a..c380ea8e7 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -160,4 +160,5 @@ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ +#define FIX_ISSUE_1247 #endif diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 6ea59adb3..f0c9a04c1 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -394,6 +394,25 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ +#ifdef FIX_ISSUE_1247 + shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); + Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ + sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); + move16(); + shift = norm_arr( sts[1]->input_fx, input_frame ); + Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ + sts[1]->q_inp = add( sts[1]->q_inp, shift ); + move16(); + + shift = norm_arr( sts[0]->old_input_signal_fx, input_frame ); + Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ + sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); + move16(); + shift = norm_arr( sts[0]->input_fx, input_frame ); + Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ + sts[0]->q_inp = add( sts[0]->q_inp, shift ); + move16(); +#else shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); @@ -411,6 +430,7 @@ ivas_error ivas_cpe_enc_fx( Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); +#endif Word16 q_inp = s_min( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), s_min( sts[1]->q_inp, sts[1]->q_old_inp ) ); -- GitLab From 4446c32f9332e95c60c440f9f4b0f839aedb8790 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 16:04:29 +0530 Subject: [PATCH 0131/1221] Fix for 3GPP issue 1277: Stereo CNG during high level mixed music Link #1277 --- lib_enc/nois_est_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 1e2131b29..27a48652a 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -2804,7 +2804,7 @@ void noise_est_ivas_fx( lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ - IF( LT_16( st_fx->ini_frame, 150 ) ) + IF( LT_16( ini_frame, 150 ) ) { /* Allow use of quicker filter during init - if needed */ /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ @@ -2848,7 +2848,7 @@ void noise_est_ivas_fx( test(); test(); if ( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 /* 15 in Q8 */ ) ) || - ( GT_16( st_fx->ini_frame, 10 ) && + ( GT_16( ini_frame, 10 ) && GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 /* 7 in Q8 */ ) ) ) ) { *st_harm_cor_cnt = 1; @@ -3113,7 +3113,7 @@ void noise_est_ivas_fx( test(); test(); IF( ( ( LT_16( *st_harm_cor_cnt, ( 3 * HC_CNT_SLOW_FX ) ) ) && ( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || ( noise_char > 0 ) ) ) || - ( ( GT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( sub( Etot, Etot_l_lp ), 2560 ) ) ) || + ( ( GT_16( ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( sub( Etot, Etot_l_lp ), 2560 ) ) ) || ( GT_16( cor_tmp, cor_max ) ) || /* Q15 */ ( GT_32( LepsP, th_eps ) ) || /* Q11 */ ( GT_16( *loc_harm, 0 ) ) || @@ -3419,7 +3419,7 @@ void noise_est_ivas_fx( test(); test(); test(); - if ( LT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) && GT_16( hNoiseEst->harm_cor_cnt, 5 ) && LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 /* 7 in Q8 */ ) && + if ( LT_16( ini_frame, HE_LT_CNT_INIT_FX ) && GT_16( hNoiseEst->harm_cor_cnt, 5 ) && LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 /* 7 in Q8 */ ) && ( ( LT_16( hNoiseEst->act_pred_fx, 19333 /* 0.59 in Q15 */ ) && LT_16( hNoiseEst->lt_haco_ev_fx, 7537 /* 0.23 in Q15 */ ) ) || LT_16( hNoiseEst->act_pred_fx, 12452 /* 0.38 in Q15 */ ) || ( ( ( st_fx->element_mode == EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 /* 0.15 in Q15 */ ) ) || ( ( st_fx->element_mode > EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 /* 0.08 in Q15 */ ) ) ) || LT_16( non_staB, 50 * 256 /* 50 in Q8 */ ) || ( aE_bgd != 0 ) || ( LT_16( Etot, 10752 /* 42.0 in Q8 */ ) && GT_16( hNoiseEst->harm_cor_cnt, 10 ) && LT_16( hNoiseEst->lt_haco_ev_fx, 11469 /* 0.35 in Q8 */ ) && LT_16( hNoiseEst->act_pred_fx, 26214 /* 0.8 in Q8 */ ) ) ) ) -- GitLab From 018322d6e02720037f50f6f003a858057f4a81cf Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 16:33:45 +0530 Subject: [PATCH 0132/1221] Fix for 3GPP issue 1291: Wrong use of imult1616() in ACELP rescaling Link #1291 --- lib_com/cnst.h | 1 + lib_com/options.h | 1 + lib_dec/acelp_core_dec_ivas_fx.c | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index a5030ac9c..197fbd3c4 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1536,6 +1536,7 @@ enum #define SHB_OVERLAP_LEN ( L_FRAME16k - L_SHB_LAHEAD ) / ( NUM_SHB_SUBFR - 1 ) #define QUANT_DIST_INIT ( 10000000000.0f ) /* Quantiser search distance initialisation */ #define HIBND_ACB_L_FAC 5 / 2 /* SHB Interpolation Factor */ +#define HIBND_ACB_L_FAC_Q1 ( 5 ) /* SHB Interpolation Factor Q1 */ #define NUM_HILBERTS 2 #define HILBERT_ORDER1 5 #define HILBERT_ORDER2 4 diff --git a/lib_com/options.h b/lib_com/options.h index d6bbaf88a..5f585d891 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -155,6 +155,7 @@ #define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ #define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ +#define FIX_ISSUE_1291 /* Ittiam: Wrong use of imult1616() in ACELP rescaling */ #define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index e52c52c7c..165594e77 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -748,7 +748,11 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->hMusicPF && st->hGSCDec ) { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, +#ifdef FIX_ISSUE_1291 + shr( imult1616( st->L_frame, HIBND_ACB_L_FAC_Q1 ), 1 ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); +#else imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); +#endif } IF( st->hPFstat != NULL ) { -- GitLab From 2660ef93ce3c87949688e900716e5fdafa3f8f1e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 16:46:47 +0530 Subject: [PATCH 0133/1221] Clang formatting changes --- lib_enc/ivas_cpe_enc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index f0c9a04c1..cc91df0e1 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -365,8 +365,8 @@ ivas_error ivas_cpe_enc_fx( Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ #else - Copy_Scale_sig_16_32_DEPREC( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_DEPREC( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_DEPREC( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ #endif Word16 shift = getScaleFactor32( sts[1]->input32_fx, input_frame ); scale_sig32( sts[1]->input32_fx, input_frame, shift ); /* Q11 + shift */ -- GitLab From cc5a39ea1bd7228f429109fc79b0621fe7c2bdda Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 12:29:28 +0100 Subject: [PATCH 0134/1221] increase testcase and job timeouts for sanitizer tests --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc48090cd..b95573265 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,7 +23,7 @@ variables: PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 - TESTCASE_TIMEOUT_LTV_SANITIZERS: 7200 + TESTCASE_TIMEOUT_LTV_SANITIZERS: 10800 CI_REGRESSION_THRESH_MLD: "0.1" CI_REGRESSION_THRESH_MAX_ABS_DIFF: "50" CI_REGRESSION_THRESH_SSNR: "-1" @@ -539,7 +539,7 @@ stages: .ivas-pytest-sanitizers-anchor: &ivas-pytest-sanitizers-anchor stage: test needs: ["build-codec-linux-make"] - timeout: "420 minutes" + timeout: "600 minutes" rules: - if: $CI_PIPELINE_SOURCE == 'push' when: never -- GitLab From a8dda194ca7f2fab3e0cfdf03b51bec049a20558 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 17:01:55 +0530 Subject: [PATCH 0135/1221] Fix for 3GPP issue 1290: Wrong ACELP synthesis for SWB BWE in DTX Link #1290 --- lib_com/options.h | 1 + lib_dec/acelp_core_dec_ivas_fx.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index d6bbaf88a..ef0f23f9d 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -128,6 +128,7 @@ #define FIX_ISSUE_1185 /* Ittiam: Fix for issue 1185: Assertion in ivas_dirac_dec_binaural_internal_fx() for crash in decoder in fft30_with_cmplx_data()*/ #define FIX_ISSUE_1209 /* Ittiam: Fix for issue 1209: Assertion exit in BASOP encoder (stereo_dmx_evs)*/ #define FIX_ISSUE_1218 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ +#define FIX_ISSUE_1290 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ #define IVAS_ISSUE_1188_EVS_CRASH /* Ittiam: Fix for issue 1188: Issue due to ASAN */ #define FIX_ISSUE_1155 /* Ittiam: Fix for issue 1155: Encoder crash for Stereo at 32kbps in PostShortTerm_ivas_enc_fx()*/ #define FIX_1010_OPT_DIV /* FhG: SVD complexity optimizations (non-be) */ diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index e52c52c7c..26252ab0a 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -802,7 +802,11 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn IF( st->hBWE_FD != NULL ) { +#ifdef FIX_ISSUE_1290 + save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); +#else save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); +#endif } } -- GitLab From 6399e209cbb656532aae6a271fe3b2ab8fd8ad5e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Feb 2025 17:07:11 +0530 Subject: [PATCH 0136/1221] Updates for tcx_noise_factor_ivas_fx function --- lib_enc/tcx_utils_enc_fx.c | 64 +++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 685ed26c1..1e35c78c4 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2416,15 +2416,17 @@ void tcx_noise_factor_ivas_fx( Word16 element_mode /* i: element mode */ ) { - Word16 i, k, win, segmentOffset; - Word32 sqErrorNrg, n; - Word64 sqErrorNrg64; - Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1; + Word16 i, k, win, segmentOffset, j; + Word32 sqErrorNrg = 0, n; + move32(); + Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1, exp_sqErrorNrg = 0; + move16(); Word32 accu1, accu2, tmp32; Word16 tmp1, tmp2, s; Word16 c1, c2; Word16 att; /* noise level attenuation factor for transient windows */ Word32 xMax; + Word16 exp_spQ[N_MAX]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -2432,13 +2434,12 @@ void tcx_noise_factor_ivas_fx( assert( nTransWidth <= 16 ); + set16_fx( exp_spQ, x_orig_e, N_MAX ); c1 = sub( shl( nTransWidth, 1 ), 4 ); c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] ); nTransWidth_1 = sub( nTransWidth, 1 ); /*Adjust noise filling level*/ - sqErrorNrg64 = 0; - move64(); n = 0; move32(); @@ -2452,10 +2453,8 @@ void tcx_noise_factor_ivas_fx( /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */ tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */ - tmp1 = norm_l( tmp32 ); - inv_gain2 = round_fx( L_shl( tmp32, tmp1 ) ); - inv_gain2_e = add( sub( 15, tmp1 ), gain_tcx_e ); - inv_gain2 = Inv16( inv_gain2, &inv_gain2_e ); + inv_gain2 = BASOP_Util_Divide3232_Scale( MAX_32, tmp32, &inv_gain2_e ); + inv_gain2_e = add( inv_gain2_e, sub( 0, add( 15, gain_tcx_e ) ) ); inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */ inv_gain2_e = add( inv_gain2_e, 2 ); @@ -2588,13 +2587,19 @@ void tcx_noise_factor_ivas_fx( } FOR( k = segmentOffset; k < i - win; k++ ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); sqQ[k] = 0; move32(); + exp_spQ[k] = 0; + move16(); } FOR( ; win > 0; win-- ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); sqQ[k++] = 0; move32(); } @@ -2608,8 +2613,10 @@ void tcx_noise_factor_ivas_fx( win = add( win, 1 ); } /* update segment sum: magnitudes scaled by smoothing function */ - sqQ[i] = L_shl( Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ), inv_gain2_e ); + sqQ[i] = Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ); move32(); + exp_spQ[i] = add( x_orig_e, inv_gain2_e ); + move16(); } } IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */ @@ -2649,38 +2656,45 @@ void tcx_noise_factor_ivas_fx( } FOR( k = segmentOffset; k < i - win; k++ ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); sqQ[k] = 0; move32(); } FOR( ; win > 0; win-- ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); sqQ[k++] = 0; move32(); } } - + Word32 tmp4; /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { - tmp2 = W_norm( sqErrorNrg64 ); - sqErrorNrg = W_extract_l( W_shr( sqErrorNrg64, sub( 32, tmp2 ) ) ); // 31 - (x_orig_e - 1) - 32 + tmp2 - tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); - s = add( add( add( x_orig_e, sub( 31, tmp2 ) ), -15 ), s ); + tmp4 = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); + s = add( add( exp_sqErrorNrg, -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; - tmp1 = shl_o( tmp1, s, &Overflow ); + tmp4 = L_shl_o( tmp4, s, &Overflow ); BASOP_SATURATE_WARNING_ON_EVS; } ELSE { - tmp1 = 0; + tmp4 = 0; move16(); } - + FOR( j = 0; j < N_MAX; j++ ) + { + sqQ[j] = L_shl( sqQ[j], sub( x_orig_e, exp_spQ[j] ) ); + move32(); + } /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */ - tmp2 = round_fx( L_shr( L_mult( tmp1, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) ); - + tmp2 = round_fx( L_shr( Mpy_32_16_1( tmp4, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) ); if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) ) { tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1; -- GitLab From 3ea6e92d666de55982e2fc5dded4a33000838471 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 13:26:19 +0100 Subject: [PATCH 0137/1221] add new stage for checking BE with target branch --- .gitlab-ci.yml | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc48090cd..a19358b6a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -110,6 +110,7 @@ stages: - .pre - prevalidate - build + - check-be - test - deploy @@ -410,6 +411,62 @@ stages: junit: - report-junit.xml +.check-be-to-target-anchor: &check-be-to-target-anchor + stage: check-be + needs: ["build-codec-linux-make"] + timeout: "300 minutes" + variables: + XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" + HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" + FAILED_TESTCASES_LIST: "failed-testcases.txt" + script: + - set -euxo pipefail + - *print-common-info + - *update-scripts-repo + + - if [ $USE_LTV -eq 1 ]; then + - *update-ltv-repo + - *copy-ltv-files-to-testv-dir + - testcase_timeout=$TESTCASE_TIMEOUT_LTV + - else + - testcase_timeout=$TESTCASE_TIMEOUT_STV + - fi + + - python3 ci/remove_unsupported_testcases.py $PRM_FILES + - if [ $LEVEL_SCALING != "1.0" ];then + - *apply-testv-scaling + - fi + + - *build-and-create-reference-outputs + + - exit_code=0 + - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + - zero_errors_branch=$(cat $XML_REPORT_BRANCH | grep -c 'errors="0"') || true + + - touch $FAILED_TESTCASES_LIST + - if [ $exit_code -ne 0 ]; then + - exit_code=$EXIT_CODE_NON_BE + - grep "FAILED" pytest_log.txt | sed 's/^FAILED //' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST + - fi + + - exit $exit_code + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA--results" + expire_in: 1 week + when: always + paths: + - $XML_REPORT + - $HTML_REPORT + expose_as: "pytest compare results" + reports: + junit: + - $XML_REPORT_BRANCH + - $XML_REPORT_MAIN + .ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor stage: test needs: ["build-codec-linux-make"] @@ -789,6 +846,19 @@ build-codec-windows-msbuild: # Short test jobs that run in merge request pipelines # --------------------------------------------------------------- +### jobs that check for bitexactness of fx encoder and decoder +check-be-to-target-short-enc-0db: + extends: + - .rules-pytest-to-main-short + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=1.0 + - SKIP_REGRESSION_CHECK="true" + <<: *check-be-to-target-anchor + ### jobs that test fx encoder -> flt decoder ivas-pytest-compare_to_main-short-enc: extends: -- GitLab From 4823811f127ba86dd516b6f840ca6570ff070cdf Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 13:27:05 +0100 Subject: [PATCH 0138/1221] disable jobs to save time --- .gitlab-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a19358b6a..41e70e8eb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -860,7 +860,7 @@ check-be-to-target-short-enc-0db: <<: *check-be-to-target-anchor ### jobs that test fx encoder -> flt decoder -ivas-pytest-compare_to_main-short-enc: +.ivas-pytest-compare_to_main-short-enc: extends: - .rules-pytest-to-main-short - .test-job-linux @@ -872,7 +872,7 @@ ivas-pytest-compare_to_main-short-enc: - SKIP_REGRESSION_CHECK="true" <<: *ivas-pytest-on-merge-request-anchor -ivas-pytest-compare_to_main-short-enc-lev-10: +.ivas-pytest-compare_to_main-short-enc-lev-10: extends: - .rules-pytest-to-main-short - .test-job-linux @@ -884,7 +884,7 @@ ivas-pytest-compare_to_main-short-enc-lev-10: - SKIP_REGRESSION_CHECK="true" <<: *ivas-pytest-on-merge-request-anchor -ivas-pytest-compare_to_main-short-enc-lev+10: +.ivas-pytest-compare_to_main-short-enc-lev+10: extends: - .rules-pytest-to-main-short - .test-job-linux @@ -897,7 +897,7 @@ ivas-pytest-compare_to_main-short-enc-lev+10: <<: *ivas-pytest-on-merge-request-anchor ### jobs that test flt encoder -> fx decoder -ivas-pytest-compare_to_main-short-dec: +.ivas-pytest-compare_to_main-short-dec: extends: - .rules-pytest-to-main-short - .test-job-linux @@ -909,7 +909,7 @@ ivas-pytest-compare_to_main-short-dec: - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -ivas-pytest-compare_to_main-short-dec-lev-10: +.ivas-pytest-compare_to_main-short-dec-lev-10: extends: - .rules-pytest-to-main-short - .test-job-linux @@ -921,7 +921,7 @@ ivas-pytest-compare_to_main-short-dec-lev-10: - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -ivas-pytest-compare_to_main-short-dec-lev+10: +.ivas-pytest-compare_to_main-short-dec-lev+10: extends: - .rules-pytest-to-main-short - .test-job-linux -- GitLab From 74319da31f87d17fdc7ccf301485ffa83e4dfa90 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 13:52:02 +0100 Subject: [PATCH 0139/1221] set REFERENCE_BRANCH correctly --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 41e70e8eb..d34fbf169 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -416,6 +416,7 @@ stages: needs: ["build-codec-linux-make"] timeout: "300 minutes" variables: + REFERENCE_BRANCH: "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" FAILED_TESTCASES_LIST: "failed-testcases.txt" @@ -441,7 +442,7 @@ stages: - exit_code=0 - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - - zero_errors_branch=$(cat $XML_REPORT_BRANCH | grep -c 'errors="0"') || true + - zero_errors_branch=$(cat $XML_REPORT | grep -c 'errors="0"') || true - touch $FAILED_TESTCASES_LIST - if [ $exit_code -ne 0 ]; then -- GitLab From 0c8ec9b91662d084a339802d4b68fb2a19d2bcb6 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 14:28:42 +0100 Subject: [PATCH 0140/1221] first shorter test version with needs relation --- .gitlab-ci.yml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d34fbf169..9a8e4cf44 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -185,7 +185,7 @@ stages: - enc_dmx_arg="--compare_enc_dmx" - fi - - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest -k "stereo and at" $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR @@ -441,7 +441,7 @@ stages: - *build-and-create-reference-outputs - exit_code=0 - - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + - python3 -m pytest -k "stereo and at" --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - zero_errors_branch=$(cat $XML_REPORT | grep -c 'errors="0"') || true - touch $FAILED_TESTCASES_LIST @@ -467,6 +467,7 @@ stages: junit: - $XML_REPORT_BRANCH - $XML_REPORT_MAIN + - $FAILED_TESTCASES_LIST .ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor stage: test @@ -485,6 +486,9 @@ stages: - set -euxo pipefail - *print-common-info - *update-scripts-repo + + - ls + - if [ $USE_LTV -eq 1 ]; then - *update-ltv-repo - *copy-ltv-files-to-testv-dir @@ -860,6 +864,22 @@ check-be-to-target-short-enc-0db: - SKIP_REGRESSION_CHECK="true" <<: *check-be-to-target-anchor +check-regressions-short-enc-0db: + stage: test + needs: + - job: "check-be-to-target-short-enc-0db" + artifacts: true + extends: + - .rules-pytest-to-main-short + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=1.0 + - SKIP_REGRESSION_CHECK="true" + <<: *ivas-pytest-on-merge-request-anchor + ### jobs that test fx encoder -> flt decoder .ivas-pytest-compare_to_main-short-enc: extends: -- GitLab From cde22561d513cb94e03a99e2d1a478265a4002a2 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 14:35:06 +0100 Subject: [PATCH 0141/1221] remove needs: in anchor to not overwrite value from job --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9a8e4cf44..05f531b7f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -471,7 +471,6 @@ stages: .ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor stage: test - needs: ["build-codec-linux-make"] timeout: "300 minutes" variables: XML_REPORT_BRANCH: "report-junit-branch-$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" -- GitLab From 2a5b563122d4e82278c17d17f22e5b645faf0bf7 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 14:41:07 +0100 Subject: [PATCH 0142/1221] fix artifacts --- .gitlab-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 05f531b7f..4fa731231 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -450,6 +450,8 @@ stages: - grep "FAILED" pytest_log.txt | sed 's/^FAILED //' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST - fi + - cat $FAILED_TESTCASES_LIST + - exit $exit_code allow_failure: @@ -462,12 +464,12 @@ stages: paths: - $XML_REPORT - $HTML_REPORT + - $FAILED_TESTCASES_LIST expose_as: "pytest compare results" reports: junit: - - $XML_REPORT_BRANCH - - $XML_REPORT_MAIN - - $FAILED_TESTCASES_LIST + - $XML_REPORT + - $XML_REPORT .ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor stage: test -- GitLab From 403c61ad3b7ff7f0ff81075c0325592894b6ae32 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 14:50:52 +0100 Subject: [PATCH 0143/1221] improve failed testcase parsing and add dbg artifact --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4fa731231..747f03d13 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -441,13 +441,13 @@ stages: - *build-and-create-reference-outputs - exit_code=0 - - python3 -m pytest -k "stereo and at" --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + - python3 -m pytest -k "stereo and at" --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - zero_errors_branch=$(cat $XML_REPORT | grep -c 'errors="0"') || true - touch $FAILED_TESTCASES_LIST - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE - - grep "FAILED" pytest_log.txt | sed 's/^FAILED //' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST - fi - cat $FAILED_TESTCASES_LIST @@ -465,6 +465,7 @@ stages: - $XML_REPORT - $HTML_REPORT - $FAILED_TESTCASES_LIST + - pytest_log.txt expose_as: "pytest compare results" reports: junit: -- GitLab From 3cae2338706c558cdb1a3b92258076b3c435d959 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 15:02:25 +0100 Subject: [PATCH 0144/1221] amend pipeline for getting the failed testcases --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 747f03d13..77bba1c95 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -447,7 +447,7 @@ stages: - touch $FAILED_TESTCASES_LIST - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST - fi - cat $FAILED_TESTCASES_LIST -- GitLab From 4535432e323fffaf8b8462f4bed0d685b5d187cc Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 15:10:42 +0100 Subject: [PATCH 0145/1221] check artifacts for BE in comparison job --- .gitlab-ci.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 77bba1c95..b15c5939f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,6 +34,7 @@ variables: ENCODER_TEST: "" COMPARE_DMX: "" SKIP_REGRESSION_CHECK: "" + FAILED_TESTCASES_LIST: "failed-testcases.txt" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -419,7 +420,6 @@ stages: REFERENCE_BRANCH: "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" - FAILED_TESTCASES_LIST: "failed-testcases.txt" script: - set -euxo pipefail - *print-common-info @@ -487,9 +487,16 @@ stages: script: - set -euxo pipefail - *print-common-info - - *update-scripts-repo - - ls + - cat $FAILED_TESTCASES_LIST + - if [ -f "$FAILED_TESTCASES_LIST" ]; then + - $TEST_SUITE=$(cat $FAILED_TESTCASES_LIST) + - else + - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." + - exit 0 + - fi + + - *update-scripts-repo - if [ $USE_LTV -eq 1 ]; then - *update-ltv-repo -- GitLab From dde36765f44603386812b899a932524d5a30dc09 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 15:22:43 +0100 Subject: [PATCH 0146/1221] check for file being empty --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6fc3c1fa0..7db27dd63 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -489,7 +489,7 @@ stages: - *print-common-info - cat $FAILED_TESTCASES_LIST - - if [ -f "$FAILED_TESTCASES_LIST" ]; then + - if [ -f "$FAILED_TESTCASES_LIST" ] && [ ! -z "$( ls -A $FAILED_TESTCASES_LIST )" ]; then - $TEST_SUITE=$(cat $FAILED_TESTCASES_LIST) - else - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." -- GitLab From 27456c3c28a80e478a94dfc22a4a1d16b1485719 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 15:37:45 +0100 Subject: [PATCH 0147/1221] fix check for empty file --- .gitlab-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7db27dd63..77fb89dbe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -488,8 +488,7 @@ stages: - set -euxo pipefail - *print-common-info - - cat $FAILED_TESTCASES_LIST - - if [ -f "$FAILED_TESTCASES_LIST" ] && [ ! -z "$( ls -A $FAILED_TESTCASES_LIST )" ]; then + - if [ -s $FAILED_TESTCASES_LIST ]; then - $TEST_SUITE=$(cat $FAILED_TESTCASES_LIST) - else - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." -- GitLab From fe6d391188618437e769f57f858eebed7b8f5d42 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Thu, 13 Feb 2025 15:54:40 +0100 Subject: [PATCH 0148/1221] remove unncessary code increasing i --- lib_enc/ACcontextMapping_enc_fx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 0e816e77c..6b0129123 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1230,7 +1230,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { /* Common variables */ Word16 a1, b1; - Word16 i, k, pki, lev1; + Word16 k, pki, lev1; UWord16 t; Word16 lastnz, lastnz2; Word16 rateFlag; @@ -1250,14 +1250,11 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( /* bits to encode lastnz */ k = 1; move16(); - i = 2; - move64(); WHILE( LT_16( k, nt / 2 ) ) { bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX( 1, Q23 ) ); k = shl( k, 1 ); - i = add( i, 2 ); /* check while condition */ } -- GitLab From b79cca58f691da72f9ca7cb32548af5ebbded60c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 15:55:10 +0100 Subject: [PATCH 0149/1221] [revert-me] force TCX20 to provoke diff for testing --- lib_enc/transient_detection_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index d9859a1a1..b0d131258 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -804,6 +804,8 @@ void SetTCXModeInfo_ivas_fx( hTcxEnc->tcxMode = TCX_20; move16(); } + + hTcxEnc->tcxMode = TCX_20; } ELSE { -- GitLab From 42a1d25e5b743dfaa4cbd1873b5070caea330930 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 16:05:51 +0100 Subject: [PATCH 0150/1221] fix variable assignment --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 77fb89dbe..a3c12f6c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -489,7 +489,7 @@ stages: - *print-common-info - if [ -s $FAILED_TESTCASES_LIST ]; then - - $TEST_SUITE=$(cat $FAILED_TESTCASES_LIST) + - TEST_SUITE=$(cat $FAILED_TESTCASES_LIST) - else - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." - exit 0 -- GitLab From a494d1d67767cf35567cef8c7b4203db68df04df Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 16:16:35 +0100 Subject: [PATCH 0151/1221] remove newlines from artifact file --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a3c12f6c9..dbdd25f75 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -447,7 +447,7 @@ stages: - touch $FAILED_TESTCASES_LIST - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' > $FAILED_TESTCASES_LIST + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' | tr "\n" " " > $FAILED_TESTCASES_LIST - fi - cat $FAILED_TESTCASES_LIST -- GitLab From 3d459969828c4ea73d0220258a190002a2cc7fbe Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 16:24:54 +0100 Subject: [PATCH 0152/1221] try without additional "" --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dbdd25f75..fcad772f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -447,7 +447,7 @@ stages: - touch $FAILED_TESTCASES_LIST - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | awk -F'::' '{print "\"" $1 "::" $2 "\"" }' | tr "\n" " " > $FAILED_TESTCASES_LIST + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | tr "\n" " " > $FAILED_TESTCASES_LIST - fi - cat $FAILED_TESTCASES_LIST -- GitLab From 37049c2c4fd6ab53c600c6785090560e10e40e10 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Thu, 13 Feb 2025 16:37:08 +0100 Subject: [PATCH 0153/1221] clean up RCcontextMapping_encode2_estimate_bandWise_start_fx() --- lib_enc/ACcontextMapping_enc_fx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 6b0129123..dd9e57626 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1672,8 +1672,6 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( /* bits to encode lastnz */ k = 1; move16(); - i = 2; - move16(); WHILE( LT_16( k, hContextMem->nt_half ) ) { @@ -1681,12 +1679,11 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( move64(); k = shl( k, 1 ); - i = add( i, 1 ); /* check while condition */ } /* bits to encode lastnz */ - hContextMem->nbits_old = i; + hContextMem->nbits_old = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */; move16(); hContextMem->ctx = 0; -- GitLab From e0c6fd18548e729d9f00fce04bf099b6e64449ab Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 16:59:25 +0100 Subject: [PATCH 0154/1221] try with moving the pytest cache instead of file parsing --- .gitlab-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fcad772f7..2c570229b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,6 +35,7 @@ variables: COMPARE_DMX: "" SKIP_REGRESSION_CHECK: "" FAILED_TESTCASES_LIST: "failed-testcases.txt" + PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -441,6 +442,7 @@ stages: - *build-and-create-reference-outputs - exit_code=0 + - rm -rf .pytest_cache || true - python3 -m pytest -k "stereo and at" --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - zero_errors_branch=$(cat $XML_REPORT | grep -c 'errors="0"') || true @@ -452,6 +454,7 @@ stages: - cat $FAILED_TESTCASES_LIST + - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache - exit $exit_code allow_failure: @@ -466,6 +469,7 @@ stages: - $HTML_REPORT - $FAILED_TESTCASES_LIST - pytest_log.txt + - $PYTEST_CACHE_ARTIFACT expose_as: "pytest compare results" reports: junit: @@ -489,7 +493,9 @@ stages: - *print-common-info - if [ -s $FAILED_TESTCASES_LIST ]; then - - TEST_SUITE=$(cat $FAILED_TESTCASES_LIST) + - rm -rf .pytest_cache || true + - unzip $PYTEST_CACHE_ARTIFACT + - PYTEST_ADDOPTS="--last-failed" - else - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." - exit 0 -- GitLab From 29a875d5c013fbb6c259024358e6e1f76a55606b Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Thu, 13 Feb 2025 17:04:04 +0100 Subject: [PATCH 0155/1221] identation problem in one of the functions, due to { in the wrong place. --- lib_enc/ACcontextMapping_enc_fx.c | 49 ++++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index dd9e57626..9715f6bb8 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1603,37 +1603,38 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); } ELSE /* Overflow */ + { + IF( *stop ) + { + *stop = tot_bits2; /* Q0 */ + move16(); + } + ELSE { - IF( *stop ){ - *stop = tot_bits2; /* Q0 */ + *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); + move16(); + } + } + + *lastnz_out = lastnz; /* Q0 */ move16(); - } - ELSE - { - *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); + *nEncoded = lastnz2; /* Q0 */ move16(); - } -} + /* Safety mechanism to avoid overflow */ + test(); + IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) + { + FOR( k = 0; k < lastnz2; k++ ) + { + x[k] = 0; + move16(); + } + } -*lastnz_out = lastnz; /* Q0 */ -move16(); -*nEncoded = lastnz2; /* Q0 */ -move16(); -/* Safety mechanism to avoid overflow */ -test(); -IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) -{ - FOR( k = 0; k < lastnz2; k++ ) - { - x[k] = 0; - move16(); + return tot_bits2; } } -return tot_bits2; -} -} - /*-------------------------------------------------------------------* * RCcontextMapping_encode2_estimate_bandWise_start_fx() -- GitLab From cae305518a72bc5ff14db3c6f3c0c1e1dae209ba Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Thu, 13 Feb 2025 17:09:46 +0100 Subject: [PATCH 0156/1221] indentation problem due to missing return. --- lib_enc/ACcontextMapping_enc_fx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 9715f6bb8..a0e819313 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1633,6 +1633,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( return tot_bits2; } + return 0; } -- GitLab From 4e815c1a00fb533432ff7ac7525261f731c7f4e0 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Thu, 13 Feb 2025 17:14:58 +0100 Subject: [PATCH 0157/1221] indentation problem due to return inside if statement. --- lib_enc/ACcontextMapping_enc_fx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index a0e819313..149ad36b0 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1228,6 +1228,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ ) { + Word16 retval; /* Common variables */ Word16 a1, b1; Word16 k, pki, lev1; @@ -1239,6 +1240,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( Word16 symbol; const UWord8 *lookup; Word64 nbits2_accu; + retval = 0; + move16(); /* Initialization */ bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); @@ -1458,7 +1461,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); - return round_fx( L_add( W_shr( nbits2_accu, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ + retval = round_fx( L_add( W_shr( nbits2_accu, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ } ELSE /* if (!hm_cfg) */ { @@ -1631,9 +1634,9 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } } - return tot_bits2; + retval = tot_bits2; } - return 0; + return retval; } -- GitLab From 6be56cb42c5094400bdba05e8704d138f0531e5a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 17:22:40 +0100 Subject: [PATCH 0158/1221] set PYTEST_ADDOPTS as env var --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c570229b..7ae61dc30 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -495,7 +495,7 @@ stages: - if [ -s $FAILED_TESTCASES_LIST ]; then - rm -rf .pytest_cache || true - unzip $PYTEST_CACHE_ARTIFACT - - PYTEST_ADDOPTS="--last-failed" + - export PYTEST_ADDOPTS=--last-failed - else - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." - exit 0 -- GitLab From 8597d69739c136ca71a0c5b552f2d336c2aae7d6 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Thu, 13 Feb 2025 17:29:53 +0100 Subject: [PATCH 0159/1221] indentation problem persists --- lib_enc/ACcontextMapping_enc_fx.c | 57 ++++++++++++++----------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 149ad36b0..cad29d320 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1228,7 +1228,6 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ ) { - Word16 retval; /* Common variables */ Word16 a1, b1; Word16 k, pki, lev1; @@ -1240,8 +1239,6 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( Word16 symbol; const UWord8 *lookup; Word64 nbits2_accu; - retval = 0; - move16(); /* Initialization */ bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); @@ -1461,7 +1458,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); - retval = round_fx( L_add( W_shr( nbits2_accu, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ + return round_fx( L_add( W_shr( nbits2_accu, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ } ELSE /* if (!hm_cfg) */ { @@ -1606,37 +1603,35 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); } ELSE /* Overflow */ - { - IF( *stop ) - { - *stop = tot_bits2; /* Q0 */ - move16(); - } - ELSE { - *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); - move16(); - } - } - - *lastnz_out = lastnz; /* Q0 */ + IF( *stop ){ + *stop = tot_bits2; /* Q0 */ move16(); - *nEncoded = lastnz2; /* Q0 */ + } + ELSE + { + *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); move16(); - /* Safety mechanism to avoid overflow */ - test(); - IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) - { - FOR( k = 0; k < lastnz2; k++ ) - { - x[k] = 0; - move16(); - } - } + } +} - retval = tot_bits2; +*lastnz_out = lastnz; /* Q0 */ +move16(); +*nEncoded = lastnz2; /* Q0 */ +move16(); +/* Safety mechanism to avoid overflow */ +test(); +IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) +{ + FOR( k = 0; k < lastnz2; k++ ) + { + x[k] = 0; + move16(); } - return retval; +} + +return tot_bits2; +} } @@ -1688,7 +1683,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( } /* bits to encode lastnz */ - hContextMem->nbits_old = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */; + hContextMem->nbits_old = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */ move16(); hContextMem->ctx = 0; -- GitLab From b48d823bdd916292c018e338c0fe9df8d28340af Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 17:31:42 +0100 Subject: [PATCH 0160/1221] overwrite cache b4 every pytest call --- .gitlab-ci.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ae61dc30..5017a4112 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -476,6 +476,12 @@ stages: - $XML_REPORT - $XML_REPORT +.overwrite-pytest-cache-with-artifact: &overwrite-pytest-cache-with-artifact + - if [ -f $PYTEST_CACHE_ARTIFACT ] then + - rm -rf .pytest_cache || true + - unzip $PYTEST_CACHE_ARTIFACT + - fi + .ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor stage: test timeout: "300 minutes" @@ -493,8 +499,7 @@ stages: - *print-common-info - if [ -s $FAILED_TESTCASES_LIST ]; then - - rm -rf .pytest_cache || true - - unzip $PYTEST_CACHE_ARTIFACT + - *overwrite-pytest-cache-with-artifact - export PYTEST_ADDOPTS=--last-failed - else - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." @@ -524,6 +529,8 @@ stages: # this per default builds the branch and the reference and creates the reference outputs - *build-and-create-reference-outputs - exit_code=0 + # need to restore cache again + - *overwrite-pytest-cache-with-artifact - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || exit_code=$? - zero_errors_branch=$(cat $XML_REPORT_BRANCH | grep -c 'errors="0"') || true - python3 scripts/parse_xml_report.py $XML_REPORT_BRANCH $CSV_BRANCH @@ -541,6 +548,8 @@ stages: - git pull - make clean - make -j + # need to restore cache again + - *overwrite-pytest-cache-with-artifact - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true - python3 scripts/parse_xml_report.py $XML_REPORT_MAIN $CSV_MAIN -- GitLab From b76abea1c07f129a2b4bd72e8907cc432aae5105 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 17:45:48 +0100 Subject: [PATCH 0161/1221] fix syntax error --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5017a4112..3e034bebd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -477,7 +477,7 @@ stages: - $XML_REPORT .overwrite-pytest-cache-with-artifact: &overwrite-pytest-cache-with-artifact - - if [ -f $PYTEST_CACHE_ARTIFACT ] then + - if [ -f $PYTEST_CACHE_ARTIFACT ]; then - rm -rf .pytest_cache || true - unzip $PYTEST_CACHE_ARTIFACT - fi -- GitLab From 94fe3242b661346909ff5ebb142191d8a6d4fc41 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 17:47:16 +0100 Subject: [PATCH 0162/1221] [revert-me] deactivate more jobs for faster testing --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3e034bebd..4e5748231 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -817,7 +817,7 @@ build-codec-linux-make: - make -j # ensure that codec builds on linux with instrumentation active -build-codec-linux-instrumented-make: +.build-codec-linux-instrumented-make: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -834,7 +834,7 @@ build-codec-linux-instrumented-make: - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP - make -j -C $INSTR_DIR -build-codec-linux-debugging-make: +.build-codec-linux-debugging-make: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -852,7 +852,7 @@ build-codec-linux-debugging-make: - *activate-debug-mode-info-if-set - make -j -build-codec-windows-msbuild: +.build-codec-windows-msbuild: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -1352,7 +1352,7 @@ coverage-test-on-main-scheduled: # --------------------------------------------------------------- # check bitexactness to EVS -be-2-evs-26444: +.be-2-evs-26444: extends: - .test-job-linux rules: -- GitLab From bd5f9b08172ba992243c71f005cc6e58fcdbac45 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 18:00:29 +0100 Subject: [PATCH 0163/1221] add missing jobs --- .gitlab-ci.yml | 111 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4e5748231..881b41b8b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -885,13 +885,10 @@ check-be-to-target-short-enc-0db: - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 - SKIP_REGRESSION_CHECK="true" + - rm -rf tests/dut tests/ref <<: *check-be-to-target-anchor -check-regressions-short-enc-0db: - stage: test - needs: - - job: "check-be-to-target-short-enc-0db" - artifacts: true +check-be-to-target-short-enc-+10db: extends: - .rules-pytest-to-main-short - .test-job-linux @@ -899,12 +896,66 @@ check-regressions-short-enc-0db: - USE_LTV=0 - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=1.0 + - LEVEL_SCALING=3.162 - SKIP_REGRESSION_CHECK="true" - <<: *ivas-pytest-on-merge-request-anchor + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor -### jobs that test fx encoder -> flt decoder -.ivas-pytest-compare_to_main-short-enc: +check-be-to-target-short-enc--10db: + extends: + - .rules-pytest-to-main-short + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=0.3162 + - SKIP_REGRESSION_CHECK="true" + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +check-be-to-target-short-dec-0db: + extends: + - .rules-pytest-to-main-short + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_ENCODER_PATH=./IVAS_cod_ref + - TEST_SUITE="$SHORT_TEST_SUITE" + - LEVEL_SCALING=1.0 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +check-be-to-target-short-dec-+10db: + extends: + - .rules-pytest-to-main-short + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_ENCODER_PATH=./IVAS_cod_ref + - TEST_SUITE="$SHORT_TEST_SUITE" + - LEVEL_SCALING=3.162 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +check-be-to-target-short-dec--10db: + extends: + - .rules-pytest-to-main-short + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_ENCODER_PATH=./IVAS_cod_ref + - TEST_SUITE="$SHORT_TEST_SUITE" + - LEVEL_SCALING=0.3162 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +### jobs that check for regressions on non-BE testcases +check-regressions-short-enc-0db: + stage: test + needs: + - job: "check-be-to-target-short-enc-0db" + artifacts: true extends: - .rules-pytest-to-main-short - .test-job-linux @@ -914,9 +965,14 @@ check-regressions-short-enc-0db: - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 - SKIP_REGRESSION_CHECK="true" + - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -.ivas-pytest-compare_to_main-short-enc-lev-10: +check-regressions-short-enc-+10db: + stage: test + needs: + - job: "check-be-to-target-short-enc-+10db" + artifacts: true extends: - .rules-pytest-to-main-short - .test-job-linux @@ -924,11 +980,16 @@ check-regressions-short-enc-0db: - USE_LTV=0 - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=0.3162 + - LEVEL_SCALING=3.162 - SKIP_REGRESSION_CHECK="true" + - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -.ivas-pytest-compare_to_main-short-enc-lev+10: +check-regressions-short-enc--10db: + stage: test + needs: + - job: "check-be-to-target-short-enc--10db" + artifacts: true extends: - .rules-pytest-to-main-short - .test-job-linux @@ -936,12 +997,16 @@ check-regressions-short-enc-0db: - USE_LTV=0 - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=3.162 + - LEVEL_SCALING=0.3162 - SKIP_REGRESSION_CHECK="true" + - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -### jobs that test flt encoder -> fx decoder -.ivas-pytest-compare_to_main-short-dec: +check-regressions-short-dec-0db: + stage: test + needs: + - job: "check-be-to-target-short-dec-0db" + artifacts: true extends: - .rules-pytest-to-main-short - .test-job-linux @@ -953,7 +1018,11 @@ check-regressions-short-enc-0db: - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -.ivas-pytest-compare_to_main-short-dec-lev-10: +check-regressions-short-enc-+10db: + stage: test + needs: + - job: "check-be-to-target-short-enc-+10db" + artifacts: true extends: - .rules-pytest-to-main-short - .test-job-linux @@ -961,11 +1030,15 @@ check-regressions-short-enc-0db: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=0.3162 + - LEVEL_SCALING=3.162 - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -.ivas-pytest-compare_to_main-short-dec-lev+10: +check-regressions-short-enc--10db: + stage: test + needs: + - job: "check-be-to-target-short-enc--10db" + artifacts: true extends: - .rules-pytest-to-main-short - .test-job-linux @@ -973,7 +1046,7 @@ check-regressions-short-enc-0db: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=3.162 + - LEVEL_SCALING=0.3162 - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -- GitLab From 4fcc08c18f5b08ff9ce4fa602a21d41b58aff97a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 18:01:49 +0100 Subject: [PATCH 0164/1221] fix job names --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 881b41b8b..32003043d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1018,10 +1018,10 @@ check-regressions-short-dec-0db: - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -check-regressions-short-enc-+10db: +check-regressions-short-dec-+10db: stage: test needs: - - job: "check-be-to-target-short-enc-+10db" + - job: "check-be-to-target-short-dec-+10db" artifacts: true extends: - .rules-pytest-to-main-short @@ -1034,10 +1034,10 @@ check-regressions-short-enc-+10db: - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -check-regressions-short-enc--10db: +check-regressions-short-dec--10db: stage: test needs: - - job: "check-be-to-target-short-enc--10db" + - job: "check-be-to-target-short-dec--10db" artifacts: true extends: - .rules-pytest-to-main-short -- GitLab From 91f046f47e652e6addc52b1fca20391f0087325f Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 13 Feb 2025 22:07:15 +0100 Subject: [PATCH 0165/1221] completed tuning of MC param: no more BE now --- lib_com/options.h | 2 +- lib_enc/ivas_mc_param_enc.c | 59 ++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 11 deletions(-) mode change 100644 => 100755 lib_enc/ivas_mc_param_enc.c diff --git a/lib_com/options.h b/lib_com/options.h index b7a3eaddb..7d6004fcc 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,5 +158,5 @@ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #endif diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c old mode 100644 new mode 100755 index 438451ceb..b99a8ef74 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -815,6 +815,24 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); + a_e = sub( add20gb, a_e ); + if ( a_fx == 0 ) + { + a_e = 0; + move16(); + } + b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); + b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); + b_e = sub( add20gb, b_e ); + if ( b_fx == 0 ) + { + b_e = 0; + move16(); + } +#endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { #ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST @@ -823,20 +841,23 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); #else - a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); - a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); - a_e = sub( add20gb, a_e ); - b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); - b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); - b_e = sub( add20gb, b_e ); c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); c_e = sub( add20gb, c_e ); + if ( c_fx == 0 ) + { + c_e = 0; + move16(); + } d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); d_e = sub( add20gb, d_e ); + if ( d_fx == 0 ) + { + d_e = 0; + move16(); + } #endif - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], @@ -899,7 +920,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e ); L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); - imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add( 20, gb ), &imag_e ); + imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add20gb, &imag_e ); p_dmx_fac_fx++; } dmx_real_fx[ch_idx1] = real_fx; @@ -967,9 +988,19 @@ static void ivas_param_mc_param_est_enc_fx( a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); a_e = sub( add20gb, a_e ); + if ( a_fx == 0 ) + { + a_e = 0; + move16(); + } b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); b_e = sub( add20gb, b_e ); + if ( b_fx == 0 ) + { + b_e = 0; + move16(); + } #endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { @@ -979,15 +1010,23 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); #else - c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); c_e = sub( add20gb, c_e ); + if ( c_fx == 0 ) + { + c_e = 0; + move16(); + } d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); d_e = sub( add20gb, d_e ); + if ( d_fx == 0 ) + { + d_e = 0; + move16(); + } #endif - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, -- GitLab From 9c6af891a99b1d612528b8fd18e870fcf3c42d97 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 14 Feb 2025 08:53:21 +0100 Subject: [PATCH 0166/1221] one variable still had a name from the development nomenklature. --- lib_enc/ACcontextMapping_enc_fx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index cad29d320..aad058c27 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1238,13 +1238,13 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( Word16 symbol; const UWord8 *lookup; - Word64 nbits2_accu; + Word64 nbits2_fx; /* Initialization */ bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); move64(); - nbits2_accu = 0; + nbits2_fx = 0; move64(); /* bits to encode lastnz */ @@ -1258,7 +1258,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( /* check while condition */ } - nbits2_accu = bit_estimate_fx; + nbits2_fx = bit_estimate_fx; move64(); IF( hm_cfg ) @@ -1386,7 +1386,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( ELSE { lastnz2 = add( b1_i, 1 ); - nbits2_accu = bit_estimate_fx; + nbits2_fx = bit_estimate_fx; move64(); } @@ -1432,7 +1432,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( IF( *stop ) { - total_output_bits = round_fx( W_shr( nbits2_accu, Q7 ) ); + total_output_bits = round_fx( W_shr( nbits2_fx, Q7 ) ); } IF( stop2 ) @@ -1458,7 +1458,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); - return round_fx( L_add( W_shr( nbits2_accu, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ + return round_fx( L_add( W_shr( nbits2_fx, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ } ELSE /* if (!hm_cfg) */ { @@ -1565,7 +1565,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { IF( abs_s( x[k] ) || abs_s( x[k + 1] ) ) /* No overflow & non-zero tuple */ { - nbits2_accu = bit_estimate_fx; /* exp(bit_estimate_e) */ + nbits2_fx = bit_estimate_fx; /* exp(bit_estimate_e) */ move64(); lastnz2 = add( k, 2 ); @@ -1587,7 +1587,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - tot_bits2 = round_fx( W_shr( nbits2_accu, Q7 ) ); + tot_bits2 = round_fx( W_shr( nbits2_fx, Q7 ) ); IF( LT_16( lastnz2, lastnz ) ) /* Overflow occured because unable to code all tuples */ { overflow_flag = 1; -- GitLab From 9ced24f50a9f43c5eb4a476dd55639158d96be69 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 14 Feb 2025 09:47:39 +0100 Subject: [PATCH 0167/1221] removed some compiler warnings and commented the representations a bit better. --- lib_enc/ACcontextMapping_enc_fx.c | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index aad058c27..4c12b6907 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -16,8 +16,8 @@ #include "prot_fx_enc.h" #include "ivas_prot.h" /* Range coder header file */ -#define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) -#define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) +#define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) /* evaulated at compile time */ +#define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /* evaluated at run time */ /*-------------------------------------------------------------------* * ACcontextMapping_encode2_no_mem_s17_LC_fx() @@ -1346,8 +1346,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( b1 = (Word16) abs( x[b1_i] ); lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); @@ -1357,8 +1357,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( { pki = lookup[lev1]; /* ESC symbol */ - bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1370,10 +1370,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[lev1]; symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ - bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ - IF( GT_32( W_shr( bit_estimate_fx, Q8 ), L_shl( target, Q15 ) ) ) + IF( GT_32( W_extract_l( W_shr( bit_estimate_fx, Q8 ) ), L_shl( target, Q15 ) ) ) { stop2 = 1; move16(); @@ -1428,11 +1428,11 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( W_shr( bit_estimate_fx, Q7 ) ); + total_output_bits = round_fx( W_extract_l( W_shr( bit_estimate_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ IF( *stop ) { - total_output_bits = round_fx( W_shr( nbits2_fx, Q7 ) ); + total_output_bits = round_fx( W_extract_l( W_shr( nbits2_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ } IF( stop2 ) @@ -1458,7 +1458,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); - return round_fx( L_add( W_shr( nbits2_fx, Q7 ), ONE_IN_Q14 ) ); /* Q0 */ + return round_fx( L_add( W_extract_l( W_shr( nbits2_fx, Q7 ) ), ONE_IN_Q14 ) ); /* Q0 */ } ELSE /* if (!hm_cfg) */ { @@ -1524,8 +1524,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); rateQ = add( rateFlag, extract_l( GT_16( k, shr( nt, 1 ) ) ) ); /* Q0 */ - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ lookup = &ari_lookup_s17_LC[t + shl( rateQ, NBITS_CONTEXT )]; /* Q0 */ @@ -1537,8 +1537,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ move16(); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - bit_estimate_fx = W_add_nosat( bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX( 2, Q23 ) ); a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); @@ -1553,10 +1553,10 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( move16(); symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ - bit_estimate_fx = W_add_nosat( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); /* Should we truncate? */ - IF( GT_32( W_shr( bit_estimate_fx, Q8 ), L_shl( target, Q15 ) ) ) + IF( GT_32( W_extract_l( W_shr( bit_estimate_fx, Q8 ) ), L_shl( target, Q15 ) ) ) { overflow_flag = 1; move16(); @@ -1587,7 +1587,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ - tot_bits2 = round_fx( W_shr( nbits2_fx, Q7 ) ); + tot_bits2 = round_fx( W_extract_l( W_shr( nbits2_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ IF( LT_16( lastnz2, lastnz ) ) /* Overflow occured because unable to code all tuples */ { overflow_flag = 1; @@ -1595,7 +1595,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } IF( EQ_16( mode, -1 ) ) { - tot_bits2 = round_fx( W_shr( bit_estimate_fx, Q7 ) ); + tot_bits2 = round_fx( W_extract_l( W_shr( bit_estimate_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ } IF( overflow_flag == 0 ) /* No overflow */ { @@ -1610,7 +1610,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } ELSE { - *stop = round_fx( W_shr( bit_estimate_fx, Q7 ) ); + *stop = round_fx( W_extract_l( W_shr( bit_estimate_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ move16(); } } @@ -1683,7 +1683,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( } /* bits to encode lastnz */ - hContextMem->nbits_old = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */ + hContextMem->nbits_old = round_fx( W_extract_l( W_shr( hContextMem->bit_estimate_fx, Q7 ) ) ); /* Q0 */ move16(); hContextMem->ctx = 0; @@ -1761,8 +1761,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); /* Q0 */ /* Signs Bits */ - hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); - hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); move32(); move32(); @@ -1777,8 +1777,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( pki = lookup[lev1]; /* Q0 */ move16(); - hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); - hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_NUMBER_QX( 2, Q23 ) ); move32(); move32(); @@ -1796,7 +1796,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( pki = lookup[lev1]; /* Q0 */ move16(); symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol Q0*/ - hContextMem->bit_estimate_fx = W_add_nosat( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); move32(); // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; @@ -1817,7 +1817,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( move16(); } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( W_shr( hContextMem->bit_estimate_fx, Q7 ) ); /* Q0 */ + total_output_bits = round_fx( W_extract_l( W_shr( hContextMem->bit_estimate_fx, Q7 ) ) ); /* Q0 */ // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); -- GitLab From dbb55697955ed456f41e51f63e5498fb9438a941 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 09:52:13 +0100 Subject: [PATCH 0168/1221] improve reporting in be check job --- .gitlab-ci.yml | 69 +++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 32003043d..5007018a3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,6 +35,7 @@ variables: COMPARE_DMX: "" SKIP_REGRESSION_CHECK: "" FAILED_TESTCASES_LIST: "failed-testcases.txt" + ERRORS_TESTCASES_LIST: "errors-testcases.txt" PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." @@ -305,6 +306,14 @@ stages: tags: - ivas-windows +.print-results-banner: &print-results-banner + - set +x + - echo "" + - echo "==================================================================================================================" + - echo "================================================== TEST RESULTS ==================================================" + - echo "==================================================================================================================" + - echo "" + # template for test jobs on linux that need the TESTV_DIR .test-job-linux-needs-testv-dir: extends: .test-job-linux @@ -444,17 +453,37 @@ stages: - exit_code=0 - rm -rf .pytest_cache || true - python3 -m pytest -k "stereo and at" --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - - zero_errors_branch=$(cat $XML_REPORT | grep -c 'errors="0"') || true - touch $FAILED_TESTCASES_LIST + - touch $ERRORS_TESTCASES_LIST + - touch $PYTEST_CACHE_ARTIFACT - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE + - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | tr "\n" " " > $FAILED_TESTCASES_LIST - - fi + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' > failed_testcases_for_printing.txt + - num_failures=$(wc -l < failed_testcases_for_printing.txt) - - cat $FAILED_TESTCASES_LIST + - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' | tr "\n" " " > $ERRORS_TESTCASES_LIST + - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' > errors_testcases_for_printing.txt + - num_errors=$(wc -l < errors_testcases_for_printing.txt) - - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache + - *print-results-banner + - echo "Found these $num_failures non-bitexact testcases:" + - cat failed_testcases_for_printing.txt + + - if [ $num_errors -ne 0 ]; then + - exit_code=1 + - echo "There were errors present in the following testcases:" + - cat errors_testcases_for_printing.txt + - fi + + - exit $exit_code + - else + - *print-results-banner + - echo "All testcases are bitexact." + - fi - exit $exit_code allow_failure: @@ -502,7 +531,10 @@ stages: - *overwrite-pytest-cache-with-artifact - export PYTEST_ADDOPTS=--last-failed - else - - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME. No need to check for regressions." + # turn off echoing back of commands for result printout + - *print-results-banner + - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME." + - echo "No need to check for regressions. All is fine." - exit 0 - fi @@ -528,10 +560,9 @@ stages: ### run branch first # this per default builds the branch and the reference and creates the reference outputs - *build-and-create-reference-outputs - - exit_code=0 # need to restore cache again - *overwrite-pytest-cache-with-artifact - - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || exit_code=$? + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true - zero_errors_branch=$(cat $XML_REPORT_BRANCH | grep -c 'errors="0"') || true - python3 scripts/parse_xml_report.py $XML_REPORT_BRANCH $CSV_BRANCH @@ -550,34 +581,14 @@ stages: - make -j # need to restore cache again - *overwrite-pytest-cache-with-artifact - - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true - python3 scripts/parse_xml_report.py $XML_REPORT_MAIN $CSV_MAIN - # If outputs of main and branch are equal, have equal reports and no run errors were encountered, the job will pass. - - diff_sba=0 - - diff_param=0 - - diff_report=0 - # SHORT_TEST_SUITE_ENCODER does not contain test_sba.py. This leads to non-existing output folders being compared and to diff_sba=1. Therefore, this is skipped for the encoder tests - - if [ "$TEST_SUITE" != "$SHORT_TEST_SUITE_ENCODER" ]; then - - python3 scripts/batch_comp_audio.py --tool pyaudio3dtools -sd tests/dut/sba_bs/raw tests/dut_branch/sba_bs/raw || diff_sba=$? - - fi - - python3 scripts/batch_comp_audio.py --tool pyaudio3dtools -sd tests/dut/param_file/dec tests/dut_branch/param_file/dec || diff_param=$? - - diff $CSV_BRANCH $CSV_MAIN || diff_report=$? - - if [ $diff_param -eq 0 ] && [ $diff_sba -eq 0 ] && [ $diff_report -eq 0 ] && [ $zero_errors_branch -eq 1 ]; then - - echo "Output BE to main, identical report and no run errors encountered." - # Add dummy files to avoid warning on missing artifacts - - touch changes_crashes.csv - - touch changes_MLD.csv - - touch changes_MAXIMUM_ABS_DIFF.csv - - touch changes_MIN_SSNR.csv - - touch changes_MIN_ODG.csv - - exit 0; - - fi - ### compare the two csv files for regressions - regressions_found=0 - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH || regressions_found=$? + - exit_code=0 - if [ $exit_code -eq 1 ]; then echo "Differences encountered"; exit_code=$EXIT_CODE_NON_BE; fi - if [ $zero_errors_branch != 1 ]; then echo "Run errors encountered!"; exit_code=$EXIT_CODE_NON_BE; fi - if [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then -- GitLab From e7adcd904f205e4aa4577394a8eb58af7f831ded Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 14 Feb 2025 09:59:49 +0100 Subject: [PATCH 0169/1221] applied the clang patch. --- lib_enc/ACcontextMapping_enc_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 4c12b6907..203f39707 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -16,8 +16,8 @@ #include "prot_fx_enc.h" #include "ivas_prot.h" /* Range coder header file */ -#define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) /* evaulated at compile time */ -#define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /* evaluated at run time */ +#define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) /* evaulated at compile time */ +#define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /* evaluated at run time */ /*-------------------------------------------------------------------* * ACcontextMapping_encode2_no_mem_s17_LC_fx() @@ -1588,7 +1588,7 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /*end of the 2-tuples loop*/ tot_bits2 = round_fx( W_extract_l( W_shr( nbits2_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ - IF( LT_16( lastnz2, lastnz ) ) /* Overflow occured because unable to code all tuples */ + IF( LT_16( lastnz2, lastnz ) ) /* Overflow occured because unable to code all tuples */ { overflow_flag = 1; move16(); @@ -1816,7 +1816,7 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( hContextMem->ctx = add( i_mult( s_and( hContextMem->ctx, 0xf ), 16 ), t ); /* Q0 */ move16(); - } /*end of the 2-tuples loop*/ + } /*end of the 2-tuples loop*/ total_output_bits = round_fx( W_extract_l( W_shr( hContextMem->bit_estimate_fx, Q7 ) ) ); /* Q0 */ // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); -- GitLab From 6e747abbf37c5e0cbe41d683cb416c10b83d3d6c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 10:32:00 +0100 Subject: [PATCH 0170/1221] condense printout --- .gitlab-ci.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5007018a3..b8b21b72b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -309,10 +309,10 @@ stages: .print-results-banner: &print-results-banner - set +x - echo "" - - echo "==================================================================================================================" - - echo "================================================== TEST RESULTS ==================================================" - - echo "==================================================================================================================" - - echo "" + - > + echo -e "==================================================================================================================\n +================================================== TEST RESULTS ==================================================\n +==================================================================================================================\n" # template for test jobs on linux that need the TESTV_DIR .test-job-linux-needs-testv-dir: @@ -533,8 +533,7 @@ stages: - else # turn off echoing back of commands for result printout - *print-results-banner - - echo "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME." - - echo "No need to check for regressions. All is fine." + - echo -e "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME.\nNo need to check for regressions. All is fine." - exit 0 - fi -- GitLab From 0cae04a9ef1b5ceac92c43f42f2c51e70be10c0d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 10:33:44 +0100 Subject: [PATCH 0171/1221] fix artifact-related zip error --- .gitlab-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b8b21b72b..d8eecaabe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -454,9 +454,6 @@ stages: - rm -rf .pytest_cache || true - python3 -m pytest -k "stereo and at" --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - - touch $FAILED_TESTCASES_LIST - - touch $ERRORS_TESTCASES_LIST - - touch $PYTEST_CACHE_ARTIFACT - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache @@ -481,6 +478,10 @@ stages: - exit $exit_code - else + # create empty files to not have errors at artifact stage + - touch $FAILED_TESTCASES_LIST + - touch $ERRORS_TESTCASES_LIST + - touch $PYTEST_CACHE_ARTIFACT - *print-results-banner - echo "All testcases are bitexact." - fi @@ -497,6 +498,7 @@ stages: - $XML_REPORT - $HTML_REPORT - $FAILED_TESTCASES_LIST + - $ERRORS_TESTCASES_LIST - pytest_log.txt - $PYTEST_CACHE_ARTIFACT expose_as: "pytest compare results" -- GitLab From b39991b5fdadac3d4ed624d569d955b5ba187906 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 10:35:17 +0100 Subject: [PATCH 0172/1221] collapse into one line --- .gitlab-ci.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d8eecaabe..5ee556e60 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -309,10 +309,7 @@ stages: .print-results-banner: &print-results-banner - set +x - echo "" - - > - echo -e "==================================================================================================================\n -================================================== TEST RESULTS ==================================================\n -==================================================================================================================\n" + - echo -e "==================================================================================================================\n================================================== TEST RESULTS ==================================================\n==================================================================================================================\n" # template for test jobs on linux that need the TESTV_DIR .test-job-linux-needs-testv-dir: -- GitLab From db14b5ea2514f5349ed819e2b27b6052a19dfcb3 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 10:42:12 +0100 Subject: [PATCH 0173/1221] ignore return codes for grep pipes --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5ee556e60..d672a4b98 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -455,12 +455,12 @@ stages: - exit_code=$EXIT_CODE_NON_BE - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | tr "\n" " " > $FAILED_TESTCASES_LIST - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' > failed_testcases_for_printing.txt + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | tr "\n" " " > $FAILED_TESTCASES_LIST || true + - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' > failed_testcases_for_printing.txt || true - num_failures=$(wc -l < failed_testcases_for_printing.txt) - - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' | tr "\n" " " > $ERRORS_TESTCASES_LIST - - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' > errors_testcases_for_printing.txt + - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' | tr "\n" " " > $ERRORS_TESTCASES_LIST || true + - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' > errors_testcases_for_printing.txt || true - num_errors=$(wc -l < errors_testcases_for_printing.txt) - *print-results-banner -- GitLab From 499c80b726336eb6294211a28ce07ed3cc389b51 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 10:57:43 +0100 Subject: [PATCH 0174/1221] rework if and result reporting in regression branch --- .gitlab-ci.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d672a4b98..c0e04314d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -587,14 +587,16 @@ stages: - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH || regressions_found=$? - exit_code=0 - - if [ $exit_code -eq 1 ]; then echo "Differences encountered"; exit_code=$EXIT_CODE_NON_BE; fi - - if [ $zero_errors_branch != 1 ]; then echo "Run errors encountered!"; exit_code=$EXIT_CODE_NON_BE; fi - - if [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then + - *print-results-banner + - if [ $zero_errors_branch != 1 ]; then + - echo "Run errors encountered!" + - exit_code=$EXIT_CODE_FAIL + - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then - if [ $allow_regressions_flag == 0 ]; then - - echo "Detected regression wrt to main, [allow regression] not set!" + - echo "Detected regression wrt to $CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [allow regression] not set!" - exit_code=$EXIT_CODE_FAIL; - else - - echo "Detected regression wrt to main, [allow regression] set." + - echo "Detected regression wrt to $CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [allow regression] set." - exit_code=$EXIT_CODE_NON_BE; - fi - fi -- GitLab From 5eb39f0dd6600569a66c417297df647e0b17aa08 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 11:23:00 +0100 Subject: [PATCH 0175/1221] remove SKIP_REGrESSION_CHECK --- .gitlab-ci.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c0e04314d..36bb0d5d5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -895,7 +895,6 @@ check-be-to-target-short-enc-0db: - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 - - SKIP_REGRESSION_CHECK="true" - rm -rf tests/dut tests/ref <<: *check-be-to-target-anchor @@ -908,7 +907,6 @@ check-be-to-target-short-enc-+10db: - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 - - SKIP_REGRESSION_CHECK="true" - rm -rf tests/dut tests/ref <<: *check-be-to-target-anchor @@ -921,7 +919,6 @@ check-be-to-target-short-enc--10db: - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=0.3162 - - SKIP_REGRESSION_CHECK="true" - rm -rf tests/dut tests/ref <<: *check-be-to-target-anchor @@ -975,7 +972,6 @@ check-regressions-short-enc-0db: - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 - - SKIP_REGRESSION_CHECK="true" - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor @@ -992,7 +988,6 @@ check-regressions-short-enc-+10db: - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 - - SKIP_REGRESSION_CHECK="true" - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor @@ -1009,7 +1004,6 @@ check-regressions-short-enc--10db: - DUT_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=0.3162 - - SKIP_REGRESSION_CHECK="true" - rm -rf tests/dut tests/ref <<: *ivas-pytest-on-merge-request-anchor -- GitLab From 8a5c23e97fd44728ac6ede26212596c0a3c9bd14 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 11:34:47 +0100 Subject: [PATCH 0176/1221] move printout of regression testcases into results section --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 36bb0d5d5..ec7634a6f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -584,7 +584,7 @@ stages: ### compare the two csv files for regressions - regressions_found=0 - - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH || regressions_found=$? + - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH > regression_log.txt || regressions_found=$? - exit_code=0 - *print-results-banner @@ -592,6 +592,7 @@ stages: - echo "Run errors encountered!" - exit_code=$EXIT_CODE_FAIL - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then + - cat regression_log.txt - if [ $allow_regressions_flag == 0 ]; then - echo "Detected regression wrt to $CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [allow regression] not set!" - exit_code=$EXIT_CODE_FAIL; -- GitLab From 9db1630e8057b7f6d16f35371c6dd2675b41672c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 12:14:58 +0100 Subject: [PATCH 0177/1221] add infos for local reproduction to check-be tests --- .gitlab-ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ec7634a6f..e80445293 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,6 +37,8 @@ variables: FAILED_TESTCASES_LIST: "failed-testcases.txt" ERRORS_TESTCASES_LIST: "errors-testcases.txt" PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" + REF_COMMIT_FILE: "ref-branch-git-sha" + CUT_COMMIT_FILE: "CuT-branch-git-sha" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -145,6 +147,7 @@ stages: - fi .build-reference-binaries: &build-reference-binaries + - git rev-parse HEAD > $CUT_COMMIT_FILE - current_commit_sha=$(git rev-parse HEAD) ### build reference binaries - git checkout $REFERENCE_BRANCH @@ -158,6 +161,7 @@ stages: - mv ./IVAS_rend ./IVAS_rend_ref ### Return to current branch - git restore . + - git rev-parse HEAD > $REF_COMMIT_FILE - git checkout $current_commit_sha @@ -467,6 +471,10 @@ stages: - echo "Found these $num_failures non-bitexact testcases:" - cat failed_testcases_for_printing.txt + - echo "Reproduce locally with:" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" + - if [ $num_errors -ne 0 ]; then - exit_code=1 - echo "There were errors present in the following testcases:" @@ -498,6 +506,8 @@ stages: - $ERRORS_TESTCASES_LIST - pytest_log.txt - $PYTEST_CACHE_ARTIFACT + - $REF_COMMIT_FILE + - $CUT_COMMIT_FILE expose_as: "pytest compare results" reports: junit: -- GitLab From 5f54c650b822bc251d02df4806786079818e694d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 12:17:25 +0100 Subject: [PATCH 0178/1221] add infos also to regression check jobs --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e80445293..fd0596d4d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -601,6 +601,9 @@ stages: - if [ $zero_errors_branch != 1 ]; then - echo "Run errors encountered!" - exit_code=$EXIT_CODE_FAIL + - echo "Reproduce locally with:" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then - cat regression_log.txt - if [ $allow_regressions_flag == 0 ]; then @@ -610,6 +613,9 @@ stages: - echo "Detected regression wrt to $CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [allow regression] set." - exit_code=$EXIT_CODE_NON_BE; - fi + - echo "Reproduce locally with:" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - fi - exit $exit_code -- GitLab From b8f5e73dc5e8c9383ee681d0ed8fce68aa47e20a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 12:27:28 +0100 Subject: [PATCH 0179/1221] change formatting in FAILED_TESTCASE_LIST and ERRORS_TESTCASES_LIST to this should make command pasteable --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fd0596d4d..f351c5c27 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -459,12 +459,12 @@ stages: - exit_code=$EXIT_CODE_NON_BE - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' | tr "\n" " " > $FAILED_TESTCASES_LIST || true - - grep "^FAILED" pytest_log.txt | sed 's/^FAILED //' | sed 's/] - .*/]/' > failed_testcases_for_printing.txt || true + - grep "^FAILED" pytest_log.txt | sed "s/^FAILED /'/" | sed "s/] - .*/]'/" | tr "\n" " " > $FAILED_TESTCASES_LIST || true + - grep "^FAILED" pytest_log.txt | sed "s/^FAILED //" | sed "s/] - .*/]/" > failed_testcases_for_printing.txt || true - num_failures=$(wc -l < failed_testcases_for_printing.txt) - - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' | tr "\n" " " > $ERRORS_TESTCASES_LIST || true - - grep "^ERROR" pytest_log.txt | sed 's/^ERROR //' | sed 's/] - .*/]/' > errors_testcases_for_printing.txt || true + - grep "^ERROR" pytest_log.txt | sed "s/^ERROR /'/" | sed "s/] - .*/]'/" | tr "\n" " " > $ERRORS_TESTCASES_LIST || true + - grep "^ERROR" pytest_log.txt | sed "s/^ERROR //" | sed "s/] - .*/]/" > errors_testcases_for_printing.txt || true - num_errors=$(wc -l < errors_testcases_for_printing.txt) - *print-results-banner -- GitLab From 556377cbfec6ae4006d2609e4a6c6f0681223f01 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 12:37:05 +0100 Subject: [PATCH 0180/1221] add notion about where to find the command lines --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f351c5c27..875a4a478 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -474,7 +474,7 @@ stages: - echo "Reproduce locally with:" - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - + - echo "The individual command lines can be found in the html report in the job artifacts." - if [ $num_errors -ne 0 ]; then - exit_code=1 - echo "There were errors present in the following testcases:" @@ -604,6 +604,7 @@ stages: - echo "Reproduce locally with:" - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" + - echo "The individual command lines can be found in the changes*.csv files in the job artifacts." - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then - cat regression_log.txt - if [ $allow_regressions_flag == 0 ]; then @@ -616,6 +617,7 @@ stages: - echo "Reproduce locally with:" - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" + - echo "The individual command lines can be found in the changes*.csv files in the job artifacts." - fi - exit $exit_code -- GitLab From afb1629b107fb5bcf6fcdb4c34dab67891edf4f9 Mon Sep 17 00:00:00 2001 From: Arun Ganesh Nayak <100918@ittiam.com> Date: Mon, 17 Feb 2025 14:17:44 +0530 Subject: [PATCH 0181/1221] Fix for 3GPP issue 1285: Assert in ivas_fill_spectrum_fx of BASOP decoder when fed with OMASA bitstream from BASOP encoder --- lib_com/fill_spectrum.c | 2 +- lib_com/hq_tools_fx.c | 30 +++ lib_com/options.h | 2 + lib_com/prot_fx.h | 23 ++ lib_com/swb_bwe_com_fx.c | 556 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 612 insertions(+), 1 deletion(-) diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index 111ac6d2f..5a4f7c4bc 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -263,7 +263,7 @@ void ivas_fill_spectrum_fx( } ELSE IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) ) { - hq_bwe_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R ); + hq_bwe_ivas_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R ); } /*----------------------------------------------------------------* diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index 998f3f048..7b7da27e6 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -2102,6 +2102,36 @@ void hq_bwe_fx( return; } +void hq_bwe_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode Q0*/ + Word32 *coeff_out1, /* i/o: BWE input & temporary buffer Q12*/ + const Word16 *hq_generic_fenv, /* i : SWB frequency envelopes Q1*/ + Word32 *coeff_out, /* o : SWB signal in MDCT domain Q12*/ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic Q0*/ + Word16 *prev_L_swb_norm, /* i/o: last normalize length Q0*/ + const Word16 hq_generic_exc_clas, /* i : hq generic hf excitation class Q0*/ + const Word16 *sfm_end, /* i : End of bands Q0*/ + const Word16 num_sfm, /* i : Number of bands Q0*/ + const Word16 num_env_bands, /* i : Number of coded envelope bands Q0*/ + const Word16 *R /* i : Bit allocation Q0*/ +) +{ + Word16 n_swb_overlap_offset, n_swb_overlap; + Word32 hq_swb_overlap_buf_fx[L_FRAME32k]; + + n_swb_overlap_offset = add( swb_bwe_subband[0], hq_generic_offset ); + n_swb_overlap = sub( sfm_end[( num_env_bands - 1 )], n_swb_overlap_offset ); /*Q0*/ + + + Copy32( &coeff_out[n_swb_overlap_offset], hq_swb_overlap_buf_fx, sub( add( n_swb_overlap, sfm_end[( num_sfm - 1 )] ), sfm_end[( num_env_bands - 1 )] ) ); /*Q12*/ + + hq_generic_decoding_ivas_fx( HQ_mode, coeff_out1, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, R ); + + overlap_hq_bwe_fx( hq_swb_overlap_buf_fx, coeff_out, n_swb_overlap_offset, n_swb_overlap, R, num_env_bands, num_sfm, sfm_end ); + + return; +} + /*--------------------------------------------------------------------------* * hq_wb_nf_bwe() * diff --git a/lib_com/options.h b/lib_com/options.h index 56a6eeabf..0c8105d8c 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,4 +162,6 @@ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #define FIX_ISSUE_1247 +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define FIX_1285_DECODER_CRASH #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index dc84a2f36..cf7072cf5 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -434,6 +434,16 @@ void hq_generic_decoding_fx( const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ const Word16 *R ); +void hq_generic_decoding_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode */ + Word32 *coeff_out1_fx, /* i/o: BWE i & temporary buffer */ + const Word16 *hq_generic_fenv_fx, /* i : SWB frequency envelopes */ + Word32 *coeff_out_fx, /* o : SWB signal in MDCT domain */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic*/ + Word16 *prev_L_swb_norm, /* i/o: last normalize length */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ + const Word16 *R ); + void save_old_syn_fx( const Word16 L_frame, /* i : frame length */ const Word16 syn[], /* i : ACELP synthesis */ @@ -706,6 +716,19 @@ void hq_bwe_fx( const Word16 num_env_bands, const Word16 *R ); +void hq_bwe_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode */ + Word32 *coeff_out1, /* i/o: BWE i & temporary buffer */ + const Word16 *hq_generic_fenv, /* i : SWB frequency envelopes */ + Word32 *coeff_out, /* o : SWB signal in MDCT domain */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic bwe*/ + Word16 *prev_L_swb_norm, /*i/o : last normalize length */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ + const Word16 *sfm_end, /* i : End of bands */ + const Word16 num_sfm, + const Word16 num_env_bands, + const Word16 *R ); + void hq_wb_nf_bwe_fx( const Word16 *coeff_fx, /* i : coded/noisefilled normalized spectrum */ const Word16 is_transient, diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index 303d453f1..5cbdd105e 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -3021,6 +3021,562 @@ void hq_generic_decoding_fx( return; } +void hq_generic_decoding_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode : Q0 */ + Word32 *coeff_out1_fx, /* i/o: BWE input & temporary buffer : Q12 */ + const Word16 *hq_generic_fenv_fx, /* i : SWB frequency envelopes : Q1 */ + Word32 *coeff_out_fx, /* o : SWB signal in MDCT domain : Q12 */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generci : Q0 */ + Word16 *prev_L_swb_norm, /* i/o: last normalize length : Q0 */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class " Q0 */ + const Word16 *R ) +{ + Word16 i, n_freq, n_band, L_swb_norm; + Word16 k; + Word16 nenv; + Word16 tenv; + + Word16 exp, exp1, exp2, frac, tmp, tmp2, cs; + Word32 L_tmp, L_tmp1, L_tmp2, max_coeff_fx; + Word16 fenvL_fx, wfenv_fx, factor_fx; + Word32 *pit1_fx; + Word16 tmp1_fx, tmp2_fx, tmp3_fx, tmp4_fx; + Word32 energy_fx; + + Word32 envelope_fx[L_FRAME16k]; + Word32 mean_vector_fx[20]; + Word16 rn_weight0_fx; + Word16 s; + Word16 blen, nband_lf, sfidx, efidx; + Word16 bwe_seed; + Word16 signum[L_FRAME16k]; + + nenv = sub( SWB_FENV, 2 ); + if ( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + nenv = SWB_FENV; + move16(); + } + + tenv = nenv; + move16(); + if ( EQ_16( HQ_mode, HQ_GEN_FB ) ) + { + tenv = add( nenv, DIM_FB ); + } + + max_coeff_fx = 0; + move16(); + tmp = add( swb_bwe_subband[0], hq_generic_offset ); + FOR( n_freq = add( HQ_GENERIC_ST_FREQ, hq_generic_offset ); n_freq < tmp; n_freq++ ) + { + max_coeff_fx = L_max( max_coeff_fx, L_abs( coeff_out1_fx[n_freq] ) ); + } + cs = norm_l( max_coeff_fx ); + + L_tmp = 0; + move16(); + tmp2 = add( swb_bwe_subband[0], hq_generic_offset ); + FOR( n_freq = add( HQ_GENERIC_ST_FREQ, hq_generic_offset ); n_freq < tmp2; n_freq++ ) + { + tmp = extract_h( L_shl( coeff_out1_fx[n_freq], cs ) ); /*12 + cs - 16 */ + L_tmp1 = L_mult0( tmp, tmp ); /*2*(cs-2) */ + L_tmp = L_add( L_tmp, L_shr( L_tmp1, 5 ) ); /*2*(cs-2) - 5 */ + } + cs = sub( shl( cs, 1 ), 9 ); + fenvL_fx = 0; + move16(); + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); +#ifdef EVS_FUNC_MODIFIED + frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ +#else + frac = round_fx( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ +#endif + tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ + exp = sub( add( cs, exp ), 30 ); + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ + fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ + } + + calc_normal_length_fx_32( HQ_CORE, coeff_out1_fx, HQ_GEN_SWB, -1, &L_swb_norm, prev_L_swb_norm ); + + calc_norm_envelop_lf_fx( coeff_out1_fx, envelope_fx, &L_swb_norm, HQ_mode, hq_generic_offset, &sfidx, &efidx ); + + blen = 16; + move16(); + + IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_EXC0 ) ) + { + rn_weight0_fx = 819; + move16(); /* 0.8 Q10 */ + } + ELSE IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_EXC1 ) ) + { + rn_weight0_fx = 51; + move16(); /* 0.05 Q10*/ + } + ELSE + { + rn_weight0_fx = 205; + move16(); /* 0.02 Q10 */ + } + + tmp = sub( efidx, sfidx ); + IF( tmp == 0 ) + { + nband_lf = 0; + move16(); + } + ELSE + { + exp = norm_s( tmp ); + nband_lf = shl( tmp, sub( exp, 1 ) ); + exp1 = norm_s( blen ); + tmp = shl( blen, exp1 ); + nband_lf = shr( div_s( nband_lf, tmp ), add( sub( 14, exp1 ), exp ) ); /* 15 + exp-1 - exp1, Q0*/ + } + + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + IF( coeff_out1_fx[n_freq] < 0 ) + { + signum[n_freq] = -1; + move16(); + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + ELSE + { + signum[n_freq] = 1; + move16(); + } + } + + /* applying whitening */ + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + exp = norm_l( coeff_out1_fx[n_freq] ) - 1; + exp1 = norm_l( envelope_fx[n_freq] ); + + L_tmp = L_shl( coeff_out1_fx[n_freq], exp ); + L_tmp1 = L_shl( envelope_fx[n_freq], exp1 ); + + logic16(); + coeff_out1_fx[n_freq] = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + move32(); /*31 + exp1 - exp2*/ + + exp = add( 31, sub( exp, exp1 ) ); + coeff_out1_fx[n_freq] = L_shl( coeff_out1_fx[n_freq], sub( 20, exp ) ); + move32(); /*Q12->Q20*/ + } + + /* mean vector generation for controlling dynamic range */ + FOR( k = 0; k < nband_lf; ++k ) + { + energy_fx = 1; + move16(); + + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( i_mult2( k, blen ), sfidx ); i < tmp; ++i ) + { + energy_fx = L_add( energy_fx, coeff_out1_fx[i] ); + } + exp = sub( norm_l( energy_fx ), 1 ); + L_tmp = L_shl( energy_fx, exp ); + exp1 = norm_l( L_and( blen, 0x00007fff ) ); + L_tmp1 = L_shl( blen, exp1 ); + logic16(); + mean_vector_fx[k] = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + move32(); /*31 + 20 + exp1 - exp2*/ + exp = add( 51, sub( exp, exp1 ) ); + mean_vector_fx[k] = L_shl( mean_vector_fx[k], sub( 20, exp ) ); + move32(); /*Q12->Q20*/ + } + + /* dynamics control */ + FOR( k = 0; k < nband_lf; ++k ) + { + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( i_mult2( k, blen ), sfidx ); i < tmp; ++i ) + { + L_tmp = L_sub( coeff_out1_fx[i], mean_vector_fx[k] ); + exp = norm_l( L_tmp ); + L_tmp = L_shl( L_tmp, exp ); /* exp+12*/ + exp1 = norm_l( rn_weight0_fx ); + L_tmp1 = L_shl( rn_weight0_fx, exp1 ); /* exp1+10*/ + L_tmp = L_mult( extract_h( L_tmp ), extract_h( L_tmp1 ) ); + L_tmp = L_shr( L_tmp, add( exp, sub( exp1, 21 ) ) ); /* Q20*/ + coeff_out1_fx[i] = L_sub( coeff_out1_fx[i], L_tmp ); + move32(); + } + } + + IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_EXC0 ) ) + { + bwe_seed = add( add( shl( R[0], 3 ), shl( R[1], 2 ) ), add( shl( R[2], 1 ), R[3] ) ); + + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + IF( signum[n_freq] < 0 ) + { + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + + IF( Random( &bwe_seed ) < 0 ) + { + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + } + } + ELSE + { + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + IF( signum[n_freq] < 0 ) + { + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + } + } + + /* normalizing modified low frequency spectrum */ + FOR( k = 0; k < nband_lf; ++k ) + { + energy_fx = 1; + move16(); + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( ( i_mult2( k, blen ) ), sfidx ); i < tmp; ++i ) + { + exp = norm_l( coeff_out1_fx[i] ); + L_tmp1 = L_shl( coeff_out1_fx[i], exp ); /* exp + 12*/ + + L_tmp = Mult_32_32( L_tmp1, L_tmp1 ); + L_tmp = L_shr( L_tmp, sub( i_mult2( 2, exp ), 11 ) ); /*Q20 */ + energy_fx = L_add( energy_fx, L_tmp ); + } + + exp = norm_l( energy_fx ); + L_tmp = L_shl( energy_fx, sub( exp, 1 ) ); + exp1 = norm_s( blen ); + L_tmp1 = L_shl( (Word32) blen, add( exp1, 16 ) ); + + L_tmp = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + exp = sub( add( 34, exp ), exp1 ); + L_tmp = L_shr( L_tmp, sub( exp, 31 ) ); + exp = 31; + move16(); + + exp = sub( 31, exp ); + IF( exp & 0x1 ) + { + L_tmp = L_shr( L_tmp, 1 ); + exp = add( exp, 1 ); + } + L_tmp = Sqrt_l( L_tmp, &exp1 ); + exp = add( 31, sub( shr( exp1, 1 ), shr( exp, 1 ) ) ); + energy_fx = L_shl( L_tmp, sub( 31, exp ) ); /*Q31*/ + + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( ( i_mult2( k, blen ) ), sfidx ); i < tmp; ++i ) + { + IF( NE_32( L_abs( coeff_out1_fx[i] ), coeff_out1_fx[i] ) ) + { + s = -1; + move16(); + coeff_out1_fx[i] = L_abs( coeff_out1_fx[i] ); + move32(); + } + ELSE + { + s = 0; + move16(); + } + exp = norm_l( coeff_out1_fx[i] ); + L_tmp = L_shl( coeff_out1_fx[i], sub( exp, 1 ) ); + exp1 = norm_l( energy_fx ); + L_tmp1 = L_shl( (Word32) energy_fx, exp1 ); + logic16(); + L_tmp = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + exp = add( sub( 19, exp1 ), exp ); + coeff_out1_fx[i] = L_shl( L_tmp, add( sub( 12, exp ), 15 ) ); + move32(); /* Q12 -> Q27 */ + IF( s ) + { + coeff_out1_fx[i] = L_negate( coeff_out1_fx[i] ); + move32(); + } + } + } + + Copy32( &coeff_out1_fx[HQ_GENERIC_OFFSET], &coeff_out_fx[HQ_GENERIC_HIGH0 + hq_generic_offset], HQ_GENERIC_LEN0 ); + Copy32( &coeff_out1_fx[HQ_GENERIC_OFFSET], &coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset], HQ_GENERIC_LEN0 ); + + IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + Copy32( &coeff_out1_fx[HQ_GENERIC_LOW0], &coeff_out_fx[HQ_GENERIC_HIGH2 + hq_generic_offset], HQ_GENERIC_END_FREQ - HQ_GENERIC_HIGH2 ); + } + + IF( EQ_16( HQ_mode, HQ_GEN_FB ) ) + { + IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + Copy32( &coeff_out1_fx[HQ_GENERIC_LOW0 + HQ_GENERIC_END_FREQ - HQ_GENERIC_HIGH2], &coeff_out_fx[fb_bwe_subband[0]], 160 ); + } + ELSE + { + Copy32( &coeff_out1_fx[HQ_GENERIC_OFFSET + HQ_GENERIC_LEN0], &coeff_out_fx[fb_bwe_subband[0]], 160 ); + } + } + + + L_tmp1 = L_deposit_l( 0 ); + L_tmp2 = L_deposit_l( 0 ); + FOR( i = 0; i < 5; ++i ) + { + L_tmp1 = L_add( L_tmp1, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset + i] ), 3 ) ); // adding guard bits + L_tmp2 = L_add( L_tmp2, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 - 2 + hq_generic_offset - i] ), 3 ) ); //adding guard bits + } + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset]; + L_tmp1 = L_max( L_tmp1, 1 ); + L_tmp2 = L_max( L_tmp2, 1 ); + exp1 = norm_l( L_tmp1 ); + exp2 = sub( norm_l( L_tmp2 ), 1 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp2_fx, tmp1_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr( tmp3_fx, add( 5, sub( exp2, exp1 ) ) ); /*10 */ + + if ( LT_16( tmp3_fx, 307 /*0.3 in Q10 */ ) ) + { + tmp3_fx = 307 /*0.3 in Q10 */; + move16(); + } + FOR( ; tmp3_fx < 1024; tmp3_fx += 102 ) + { + *pit1_fx = Mult_32_16( *pit1_fx, shl( tmp3_fx, 5 ) ); + move32(); /*15 + 5 + 10 -15 */ + pit1_fx++; + } + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH1 - 1 + hq_generic_offset]; + + exp1 = sub( norm_l( L_tmp1 ), 1 ); + exp2 = norm_l( L_tmp2 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp1_fx, tmp2_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr( tmp3_fx, add( 5, sub( exp1, exp2 ) ) ); /*10 */ + + IF( GT_16( tmp3_fx, 5120 ) ) + { + FOR( tmp3_fx = 5120; tmp3_fx > 1024; tmp3_fx -= 512 ) + { + /* Adding saturation suggested as fix for issue #957 */ + L_tmp1 = L_shl_sat( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ + *pit1_fx-- = L_tmp1; + move32(); + } + } + + IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + L_tmp1 = L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 + hq_generic_offset] ), L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 + 1 + hq_generic_offset] ) ); + L_tmp2 = L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 4 + hq_generic_offset] ), L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 3 + hq_generic_offset] ), + L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 2 + hq_generic_offset] ), L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 1 + hq_generic_offset] ) ) ) ); + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH2 + hq_generic_offset]; + + L_tmp1 = L_max( L_tmp1, 1 ); + L_tmp2 = L_max( L_tmp2, 1 ); + exp1 = norm_l( L_tmp1 ); + exp2 = sub( norm_l( L_tmp2 ), 1 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp2_fx, tmp1_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr_sat( tmp3_fx, add( 5, sub( exp2, exp1 ) ) ); /*10 */ + if ( LT_16( tmp3_fx, 307 /* 0.3 in Q10*/ ) ) + { + tmp3_fx = 307; /* 0.3 in Q10*/ + move16(); + } + FOR( ; tmp3_fx < 1024; tmp3_fx += 102 ) + { + L_tmp = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ + *pit1_fx++ = L_tmp; + move32(); + } + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH2 - 1 + hq_generic_offset]; + + exp1 = sub( norm_l( L_tmp1 ), 1 ); + exp2 = norm_l( L_tmp2 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp1_fx, tmp2_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr( tmp3_fx, add( 5, sub( exp1, exp2 ) ) ); /*10 */ + tmp3_fx = shr( tmp3_fx, 1 ); + tmp4_fx = mult_r( tmp3_fx, 1638 /* 0.05 in Q15 */ ); + WHILE( tmp3_fx > 1024 /* 1 in Q10*/ ) + { +#ifdef EVS_FUNC_MODIFIED + L_tmp1 = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ +#else + L_tmp1 = Mult_32_16( L_shl( *pit1_fx, 5 ), tmp3_fx ); /*15 + 5 + 10 -15 */ +#endif + *pit1_fx-- = L_tmp1; + move32(); + tmp3_fx = sub( tmp3_fx, tmp4_fx ); + } + } + + + wfenv_fx = hq_generic_fenv_fx[0]; + move16(); /*1 */ + i = 0; + move16(); + tmp2 = add( add( swb_bwe_subband[0], hq_generic_offset ), 8 ); + FOR( n_freq = add( swb_bwe_subband[0], hq_generic_offset ); n_freq < tmp2; n_freq++ ) + { + factor_fx = shl( i, 12 ); /*15 */ + L_tmp1 = L_mult( sub( 32767, factor_fx ), fenvL_fx ); /*17 */ + L_tmp2 = L_mult( factor_fx, wfenv_fx ); /*17 */ + L_tmp1 = L_add( L_tmp1, L_tmp2 ); /*17 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*17 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 17 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, add( 1, cs ) ); + move32(); /*12 */ + i++; + move16(); + } + + k = sub( nenv, 2 ); + FOR( n_band = 0; n_band < k; n_band++ ) + { + wfenv_fx = hq_generic_fenv_fx[n_band + 1]; + move16(); /*1 */ + + tmp2 = swb_bwe_sm_subband[n_band + 1] + hq_generic_offset; + FOR( i = 0; n_freq < tmp2; i++ ) + { + L_tmp1 = L_mult( sub( wfenv_fx, hq_generic_fenv_fx[n_band] ), smooth_factor_fx[n_band] ); /*17 */ + L_tmp1 = Mult_32_16( L_tmp1, shl( i, 10 ) ); /*17 + 10 - 15 */ + L_tmp1 = L_add( L_tmp1, L_shl( hq_generic_fenv_fx[n_band], 11 ) ); /*12 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*12 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 12 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shl( L_tmp, sub( 4, cs ) ); + move32(); /*12 */ + n_freq++; + } + } + + wfenv_fx = hq_generic_fenv_fx[nenv - 1]; + move16(); /*1 */ + tmp2 = add( swb_bwe_sm_subband[nenv - 1], hq_generic_offset ); + FOR( i = 0; n_freq < tmp2; i++ ) + { + L_tmp1 = L_mult( sub( wfenv_fx, hq_generic_fenv_fx[nenv - 2] ), smooth_factor_fx[nenv - 2] ); /*17 */ + L_tmp1 = Mult_32_16( L_tmp1, shl( i, 10 ) ); /*17 + 10 - 15 */ + L_tmp1 = L_add( L_tmp1, L_shl( hq_generic_fenv_fx[nenv - 2], 11 ) ); /*12 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*12 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 12 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shl( L_tmp, sub( 4, cs ) ); + move32(); /*12 */ + n_freq++; + } + + IF( EQ_16( HQ_mode, HQ_GEN_SWB ) ) + { + FOR( n_band = sub( nenv, 1 ); n_band < nenv; ++n_band ) + { + wfenv_fx = hq_generic_fenv_fx[n_band]; + move16(); /*1 */ + tmp2 = add( swb_bwe_subband[n_band + 1], hq_generic_offset ); + FOR( ; n_freq < tmp2; n_freq++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + } + } + } + ELSE + { + test(); + IF( GT_16( sub( hq_generic_fenv_fx[nenv - 1], hq_generic_fenv_fx[nenv] ), 30 ) || LT_16( hq_generic_fenv_fx[nenv], 10 ) ) + { + wfenv_fx = hq_generic_fenv_fx[nenv - 1]; + move16(); /*1 */ + FOR( i = 0; n_freq < fb_bwe_subband[0]; i++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + n_freq++; + } + + FOR( n_band = 0; n_band < DIM_FB; n_band++ ) + { + wfenv_fx = hq_generic_fenv_fx[n_band + nenv]; + move16(); /*1 */ + tmp2 = fb_bwe_subband[n_band + 1]; + FOR( i = 0; n_freq < tmp2; i++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + n_freq++; + } + } + } + ELSE + { + FOR( n_band = 0; n_band < DIM_FB; n_band++ ) + { + wfenv_fx = hq_generic_fenv_fx[n_band + nenv - 1]; + move16(); /*1 */ + + FOR( i = 0; n_freq < fb_bwe_sm_subband[n_band]; i++ ) + { + L_tmp1 = L_mult( sub( wfenv_fx, hq_generic_fenv_fx[n_band + nenv] ), fb_smooth_factor_fx[n_band] ); /*17 */ + L_tmp1 = Mult_32_16( L_tmp1, shl( i, 9 ) ); /*17 + 9 - 15 */ + L_tmp1 = L_add( L_tmp1, L_shl( hq_generic_fenv_fx[n_band + nenv], 10 ) ); /*11 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*11 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 11 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shl( L_tmp, sub( 5, cs ) ); + move32(); /*12 */ + n_freq = add( n_freq, 1 ); + } + } + + wfenv_fx = hq_generic_fenv_fx[tenv - 1]; + move16(); /*1 */ + + FOR( ; n_freq < fb_bwe_subband[DIM_FB]; n_freq++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + } + } + } + + return; +} + /*-------------------------------------------------------------------* * save_old_syn() -- GitLab From dc01d1167c817794bcd534b1b7ee4d8c0488abe1 Mon Sep 17 00:00:00 2001 From: Arun Ganesh Nayak <100918@ittiam.com> Date: Mon, 17 Feb 2025 14:24:39 +0530 Subject: [PATCH 0182/1221] Fix for 3GPP issue 1285: Assert in ivas_fill_spectrum_fx of BASOP decoder when fed with OMASA bitstream from BASOP encoder --- lib_com/swb_bwe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index 5cbdd105e..09f72b230 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -3338,8 +3338,8 @@ void hq_generic_decoding_ivas_fx( L_tmp2 = L_deposit_l( 0 ); FOR( i = 0; i < 5; ++i ) { - L_tmp1 = L_add( L_tmp1, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset + i] ), 3 ) ); // adding guard bits - L_tmp2 = L_add( L_tmp2, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 - 2 + hq_generic_offset - i] ), 3 ) ); //adding guard bits + L_tmp1 = L_add( L_tmp1, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset + i] ), 3 ) ); // adding guard bits + L_tmp2 = L_add( L_tmp2, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 - 2 + hq_generic_offset - i] ), 3 ) ); // adding guard bits } pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset]; -- GitLab From d9eb2c888d202ebc3e1f51595d9903fbaf8e5813 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 10:44:28 +0100 Subject: [PATCH 0183/1221] deactivate switches for testing --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 2fc2f64b4..c87cd23da 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -159,8 +159,8 @@ #define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ -#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +// #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +// #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #define FIX_ISSUE_1247 -- GitLab From 4b7574d6caaa4ee87b5cc11918dbce5415d15d3d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:37:00 +0100 Subject: [PATCH 0184/1221] add pre and post check for being up-to-date with target --- .gitlab-ci.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 875a4a478..97de3b670 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -117,6 +117,7 @@ stages: - build - check-be - test + - postvalidate - deploy # --------------------------------------------------------------- @@ -229,6 +230,13 @@ stages: - (Get-Content -Path "CMakeLists.txt") -replace '# \(add_compile_options\("\/WX"\)\)', '$1' | Set-Content -Path "CMakeLists.txt" - Get-ChildItem -Path "Workspace_msvc" -Filter "*.vcxproj" | ForEach-Object { (Get-Content -Path $_.FullName) -replace 'false', 'true' | Set-Content -Path $_.FullName } +.rules-merge-request: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + .rules-pytest-to-ref-short: rules: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare" @@ -774,6 +782,35 @@ uninterruptible: # verification jobs # --------------------------------------------------------------- +branch-is-up-to-date-with-target-pre: + extends: + - .rules-merge-request + stage: prevalidate + needs: [] + tags: + - ivas-basop-linux + script: + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + echo -e "Your branch is $commits_behind_count commits behind the target branch, run\n\tgit pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + +branch-is-up-to-date-with-target-post: + extends: + - .rules-merge-request + stage: postvalidate + tags: + - ivas-basop-linux + script: + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run, run\n\tgit pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + clang-format-check: extends: - .test-job-linux -- GitLab From 543229ce49a777b1cfab2ac3c0f198f6c745b6a9 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:40:07 +0100 Subject: [PATCH 0185/1221] add up-to-date check to BE test as well --- .gitlab-ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 97de3b670..597e15e40 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -441,6 +441,14 @@ stages: HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" script: - set -euxo pipefail + + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run. Checking bitexactness now can result in meaningless results. Run\n\t git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + - *print-common-info - *update-scripts-repo -- GitLab From 5ab4502a9c76ada0195f5ad59756b0e8cbc5c12b Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:42:11 +0100 Subject: [PATCH 0186/1221] add missing anchor --- .gitlab-ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 597e15e40..bcfed96df 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -217,6 +217,11 @@ stages: - cd $LTV_DIR - git pull - cd - + +.get-commits-behind-count: &get-commits-behind-count + - echo $CI_COMMIT_SHA + - echo $CI_MERGE_REQUEST_TARGET_BRANCH_NAME + - commits_behind_count=$(git rev-list --count $CI_COMMIT_SHA..origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME) .copy-ltv-files-to-testv-dir: ©-ltv-files-to-testv-dir - cp "$LTV_DIR"/*.wav scripts/testv/ -- GitLab From e28286c8c2df0cb223ce0620b28942626f23ad48 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:44:54 +0100 Subject: [PATCH 0187/1221] fix rule template --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bcfed96df..b6be74fd5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -236,11 +236,11 @@ stages: - Get-ChildItem -Path "Workspace_msvc" -Filter "*.vcxproj" | ForEach-Object { (Get-Content -Path $_.FullName) -replace 'false', 'true' | Set-Content -Path $_.FullName } .rules-merge-request: - extends: .rules-basis rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - if: $CI_PIPELINE_SOURCE == 'push' when: never + - when: never .rules-pytest-to-ref-short: rules: -- GitLab From 53228a4ae9aa28723f0059092363dd8f5319a738 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:51:33 +0100 Subject: [PATCH 0188/1221] check for up-to-date with main in regression jobs, too also rename anchor as it is only used for the regressions checks now --- .gitlab-ci.yml | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b6be74fd5..0d757075f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -436,6 +436,14 @@ stages: junit: - report-junit.xml +.check-up-to-date-in-comparison-jobs: &check-up-to-date-in-comparison-jobs + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run. Checking bitexactness or testing for regressions now can result in meaningless results. Run\n\t git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + .check-be-to-target-anchor: &check-be-to-target-anchor stage: check-be needs: ["build-codec-linux-make"] @@ -445,16 +453,11 @@ stages: XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" script: - - set -euxo pipefail + - *check-up-to-date-in-comparison-jobs + - *print-common-info - - *get-commits-behind-count - - | - if [ $commits_behind_count -ne 0 ]; then - echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run. Checking bitexactness now can result in meaningless results. Run\n\t git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." - exit 1 - fi + - set -euxo pipefail - - *print-common-info - *update-scripts-repo - if [ $USE_LTV -eq 1 ]; then @@ -541,7 +544,7 @@ stages: - unzip $PYTEST_CACHE_ARTIFACT - fi -.ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor +.check-regressions-pytest-anchor: &check-regressions-pytest-anchor stage: test timeout: "300 minutes" variables: @@ -554,9 +557,11 @@ stages: IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" script: - - set -euxo pipefail + - *check-up-to-date-in-comparison-jobs - *print-common-info + - set -euxo pipefail + - if [ -s $FAILED_TESTCASES_LIST ]; then - *overwrite-pytest-cache-with-artifact - export PYTEST_ADDOPTS=--last-failed @@ -1042,7 +1047,7 @@ check-regressions-short-enc-0db: - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor check-regressions-short-enc-+10db: stage: test @@ -1058,7 +1063,7 @@ check-regressions-short-enc-+10db: - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor check-regressions-short-enc--10db: stage: test @@ -1074,7 +1079,7 @@ check-regressions-short-enc--10db: - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=0.3162 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor check-regressions-short-dec-0db: stage: test @@ -1090,7 +1095,7 @@ check-regressions-short-dec-0db: - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=1.0 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor check-regressions-short-dec-+10db: stage: test @@ -1106,7 +1111,7 @@ check-regressions-short-dec-+10db: - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=3.162 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor check-regressions-short-dec--10db: stage: test @@ -1122,7 +1127,7 @@ check-regressions-short-dec--10db: - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=0.3162 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor # --------------------------------------------------------------- # Short test jobs for running from web interface or schedule -- GitLab From 978268149b7ce3d432ac43b6f34721f6ea731a5c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:53:09 +0100 Subject: [PATCH 0189/1221] add commit files to regression check artifacts --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0d757075f..5bd1627ae 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -665,6 +665,8 @@ stages: - $CSV_MAIN - $SUMMARY_HTML_ARTIFACT_NAME - $IMAGES_ARTIFACT_NAME + - $REF_COMMIT_FILE + - $CUT_COMMIT_FILE - changes_crashes.csv - changes_MLD.csv - changes_MAXIMUM_ABS_DIFF.csv -- GitLab From 752cb148959cac020d7a6bdca4580e54f18f8842 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 12:57:33 +0100 Subject: [PATCH 0190/1221] remove empty needs in build stage --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5bd1627ae..aeb3c601b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -312,13 +312,11 @@ stages: .build-job-linux: stage: build timeout: "2 minutes" - needs: [] tags: - ivas-basop-linux .build-job-windows: stage: build - needs: [] timeout: "4 minutes" tags: - ivas-windows -- GitLab From 61fb4a0eaa696effa2b3cb2ce8b59d4b5c0b9cd8 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 14:06:47 +0100 Subject: [PATCH 0191/1221] Revert "[revert-me] deactivate more jobs for faster testing" This reverts commit 94fe3242b661346909ff5ebb142191d8a6d4fc41. --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aeb3c601b..6961113f4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -902,7 +902,7 @@ build-codec-linux-make: - make -j # ensure that codec builds on linux with instrumentation active -.build-codec-linux-instrumented-make: +build-codec-linux-instrumented-make: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -919,7 +919,7 @@ build-codec-linux-make: - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP - make -j -C $INSTR_DIR -.build-codec-linux-debugging-make: +build-codec-linux-debugging-make: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -937,7 +937,7 @@ build-codec-linux-make: - *activate-debug-mode-info-if-set - make -j -.build-codec-windows-msbuild: +build-codec-windows-msbuild: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -1504,7 +1504,7 @@ coverage-test-on-main-scheduled: # --------------------------------------------------------------- # check bitexactness to EVS -.be-2-evs-26444: +be-2-evs-26444: extends: - .test-job-linux rules: -- GitLab From 09823bfe6741dfcec344878c7120320f4e3c594a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 14:07:31 +0100 Subject: [PATCH 0192/1221] Revert "[revert-me] force TCX20 to provoke diff for testing" This reverts commit b79cca58f691da72f9ca7cb32548af5ebbded60c. --- lib_enc/transient_detection_fx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index b0d131258..d9859a1a1 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -804,8 +804,6 @@ void SetTCXModeInfo_ivas_fx( hTcxEnc->tcxMode = TCX_20; move16(); } - - hTcxEnc->tcxMode = TCX_20; } ELSE { -- GitLab From 3af8351a7f5d0794817df190871841d59233e272 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 14:12:11 +0100 Subject: [PATCH 0193/1221] remove pytest filter which was used for testing only --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6961113f4..d0b4e4d6a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -193,7 +193,7 @@ stages: - enc_dmx_arg="--compare_enc_dmx" - fi - - python3 -m pytest -k "stereo and at" $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR @@ -475,7 +475,7 @@ stages: - exit_code=0 - rm -rf .pytest_cache || true - - python3 -m pytest -k "stereo and at" --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE -- GitLab From 960fffa18703d87baedeb23b2a12f9c21fd04860 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 15:05:12 +0100 Subject: [PATCH 0194/1221] check for up to date branch after build of reference --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d0b4e4d6a..8e1d38a6f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -438,6 +438,7 @@ stages: - *get-commits-behind-count - | if [ $commits_behind_count -ne 0 ]; then + set +x echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run. Checking bitexactness or testing for regressions now can result in meaningless results. Run\n\t git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." exit 1 fi @@ -451,7 +452,6 @@ stages: XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" script: - - *check-up-to-date-in-comparison-jobs - *print-common-info - set -euxo pipefail @@ -472,6 +472,7 @@ stages: - fi - *build-and-create-reference-outputs + - *check-up-to-date-in-comparison-jobs - exit_code=0 - rm -rf .pytest_cache || true @@ -555,7 +556,6 @@ stages: IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" script: - - *check-up-to-date-in-comparison-jobs - *print-common-info - set -euxo pipefail @@ -592,6 +592,7 @@ stages: ### run branch first # this per default builds the branch and the reference and creates the reference outputs - *build-and-create-reference-outputs + - *check-up-to-date-in-comparison-jobs # need to restore cache again - *overwrite-pytest-cache-with-artifact - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true -- GitLab From 2de341b9b6f0b35595bcfe85b8746366f7202e6e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 17 Feb 2025 15:12:35 +0100 Subject: [PATCH 0195/1221] add --show_improvements arg to basop_check_for_changes.py --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8e1d38a6f..f0dfa5668 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -619,7 +619,7 @@ stages: ### compare the two csv files for regressions - regressions_found=0 - - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH > regression_log.txt || regressions_found=$? + - python3 scripts/basop_check_for_changes_in_testcases.py --show_improvements --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH > regression_log.txt || regressions_found=$? - exit_code=0 - *print-results-banner -- GitLab From dec31eaf27e965a0dae0085ed9523a84c3c19e54 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Mon, 17 Feb 2025 22:25:03 +0530 Subject: [PATCH 0196/1221] Partial fix for 3GPP issue 1129, ivas function for tcx_arith_encode_envelope_fx and revamped the function IGF_ErodeSpectrum_ivas_fx --- lib_enc/arith_coder_enc_fx.c | 131 ++++++++++++++++++++++++++++++++ lib_enc/cod_tcx_fx.c | 11 ++- lib_enc/igf_enc.c | 6 +- lib_enc/igf_enc_fx.c | 142 +++++++++++++++-------------------- lib_enc/prot_fx_enc.h | 21 +++++- 5 files changed, 223 insertions(+), 88 deletions(-) diff --git a/lib_enc/arith_coder_enc_fx.c b/lib_enc/arith_coder_enc_fx.c index b97fd7931..98a5173f5 100644 --- a/lib_enc/arith_coder_enc_fx.c +++ b/lib_enc/arith_coder_enc_fx.c @@ -792,3 +792,134 @@ void tcx_arith_encode_envelope_fx( *nf_seed = extract_l( L_tmp2 ); move16(); } + +void tcx_arith_encode_envelope_ivas_fx( + Word32 spectrum[], /* i/o: MDCT coefficients Q31-e */ + Word16 *spectrum_e, /* i/o: MDCT exponent Q0 */ + Word16 signs[], /* o: signs (spectrum[.]<0) Q0 */ + const Word16 L_frame, /* i: frame or MDCT length Q0 */ + const Word16 L_spec, /* i: frame or MDCT length Q0 */ + Encoder_State *st, /* i/o: coder state */ + const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */ + Word16 target_bits, /* i: number of available bits Q0 */ + Word16 prm[], /* o: bitstream parameters Q0 */ + const Word8 use_hm, /* i: use HM in current frame? */ + Word16 prm_hm[], /* o: HM parameter area Q0 */ + const Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/ + Word16 *arith_bits, /* o: bits used for ari. coding Q0 */ + Word16 *signaling_bits, /* o: bits used for signaling Q0 */ + const Word16 low_complexity /* i: low-complexity flag Q0 */ +) +{ + Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ + Word16 *envelope; /* scaled envelope (Q15-e) */ + Word16 envelope_e; + Word16 exponents[N_MAX_ARI]; /* Q15 */ + Word16 L_spec_core; + Word16 *q_spectrum; + TCX_CONFIG_HANDLE hTcxCfg; + Word16 scale, scale_e; + Word16 k, kMax; + Word16 deadzone; + const Word8 *deadzone_flags; + Word16 gamma_w, gamma_uw; + Word16 hm_bits; + Word32 L_tmp; + Word16 tmp; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + assert( L_spec <= N_MAX_ARI ); + + hTcxCfg = st->hTcxCfg; + deadzone = hTcxCfg->sq_rounding; + move16(); + deadzone_flags = hTcxEnc->memQuantZeros; + *signaling_bits = 0; + move16(); + + assert( st->enableTcxLpc ); + gamma_w = 32767 /*1.0f Q15*/; + move16(); + gamma_uw = st->inv_gamma; + move16(); + + tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); + + FOR( k = 0; k < L_spec; k++ ) + { + signs[k] = extract_l( L_lshr( spectrum[k], 31 ) ); + move16(); + if ( spectrum[k] < 0 ) + { + spectrum[k] = L_abs( spectrum[k] ); + move32(); + } + } + + IF( use_hm != 0 ) + { + tcx_hm_analyse_fx( spectrum, spectrum_e, L_spec, env, target_bits, hTcxCfg->coder_type, prm_hm, tcxltp_pitch, hTcxEnc->tcxltp_gain, &hm_bits ); + + target_bits = sub( target_bits, hm_bits ); + *signaling_bits = add( *signaling_bits, hm_bits ); + move16(); + } + ELSE + { + prm_hm[0] = 0; /* just to be sure */ + move16(); + hm_bits = 0; + move16(); + } + + L_spec_core = L_spec; + move16(); + if ( st->igf ) + { + L_spec_core = s_min( L_spec_core, st->hIGFEnc->infoStartLine ); + } + envelope = (Word16 *) env; + + tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + + tmp = sub( envelope_e, 1 + 15 ); + FOR( k = 0; k < L_spec; k++ ) + { + exponents[k] = round_fx( expfp( envelope[k], tmp ) ); + move16(); + } + + scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e ); + + /* Final quantization */ + kMax = tcx_arith_find_kMax( spectrum, *spectrum_e, L_spec, scale, scale_e, deadzone, deadzone_flags ); + + q_spectrum = (Word16 *) env; /* Reuse buffer */ + + L_tmp = L_mult( deadzone, 1 ); /* Q16 */ + tmp = add( sub( *spectrum_e, 15 ), scale_e ); + FOR( k = 0; k <= kMax; k++ ) + { + /* quantise using dead-zone */ + q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) ); + move16(); + } + + /* Final encoding */ + *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm ); + move16(); + + /* Multiply back the signs */ + FOR( k = 0; k <= kMax; k++ ) + { + if ( signs[k] != 0 ) + L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) ); + if ( signs[k] == 0 ) + L_tmp = L_mult( q_spectrum[k], 1 << ( 30 - SPEC_EXP_DEC ) ); + spectrum[k] = L_tmp; + move32(); + } + *spectrum_e = SPEC_EXP_DEC; + move16(); + set32_fx( spectrum + k, 0, sub( s_max( L_frame, L_spec ), k ) ); +} diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index ebec48fa7..94b030f5a 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -4192,13 +4192,22 @@ void QuantizeTCXSpectrum_fx( low_complexiety = 1; move16(); } - tcx_arith_encode_envelope_fx( spectrum_fx, spectrum_e, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, tmp8, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, nf_seed, low_complexiety ); + tcx_arith_encode_envelope_ivas_fx( spectrum_fx, spectrum_e, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, tmp8, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, low_complexiety ); sqTargetBits = sub( sqTargetBits, signaling_bits ); *prm_target = sqTargetBits; move16(); /* Noise filling seed */ + Word64 seed = 0; + move64(); + FOR( i = 0; i < noiseFillingBorder; ++i ) + { + /* *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 ); */ + seed = W_mac_32_32( seed, L_abs( spectrum_fx[i] ), i ); // exp: spectrum_e + } + *nf_seed = extract_l( W_extract_l( W_shr( seed, sub( 31, *spectrum_e ) ) ) ); // Q0 + move16(); } *hm_active = prm_hm[0]; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index a85843be2..d20169e73 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2593,7 +2593,6 @@ void IGFEncApplyMono_ivas_fx( Word16 *pPowerSpectrumParameter_exp; Word16 att_fx = MAX16B; Word16 last_core_acelp; - Word16 highPassEner_exp; move16(); Word32 common_pPowerSpectrum_fx[N_MAX + L_MDCT_OVLP_MAX]; @@ -2670,7 +2669,7 @@ void IGFEncApplyMono_ivas_fx( move16(); } } - IGF_ErodeSpectrum_ivas_fx( &highPassEner_exp, st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, common_pPowerSpectrum_exp, igfGridIdx, 0 ); + IGF_ErodeSpectrum_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, common_pPowerSpectrum_exp, igfGridIdx, 0 ); } @@ -2694,7 +2693,6 @@ void IGFEncApplyStereo_fx( const Word32 element_brate, /* i : element bitrate */ const Word16 mct_on ) { - Word16 highPassEner_exp; Word32 *pPowerSpectrumParameter_fx[NB_DIV]; /* If it is NULL it informs a function that specific handling is needed */ Word32 *pPowerSpectrumParameterMsInv_fx[NB_DIV]; Word16 coreMsMask[N_MAX]; @@ -2768,7 +2766,7 @@ void IGFEncApplyStereo_fx( IGF_Whitening_ivas_fx( hIGFEnc[ch], pPowerSpectrumParameter_fx[ch], &exp_pPowerSpectrum[0], igfGridIdx, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, ( sts[0]->hTcxEnc->fUseTns[frameno] || sts[1]->hTcxEnc->fUseTns[frameno] ), sp_aud_decision0, element_brate, sts[ch]->element_mode ); - IGF_ErodeSpectrum_ivas_fx( &highPassEner_exp, hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx, mct_on ); + IGF_ErodeSpectrum_ivas_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx, mct_on ); } return; } diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 268166ba9..ca1759c89 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -525,8 +525,7 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou } } -void IGF_ErodeSpectrum_ivas_fx( Word16 *highPassEner_exp, /**< out: | exponent of highPassEner */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ +void IGF_ErodeSpectrum_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ Word32 *pSpectrum, /**< in/out: | MDCT spectrum Qx*/ Word32 *pPowerSpectrum, /**< in/out: | power spectrum */ Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */ @@ -541,26 +540,17 @@ void IGF_ErodeSpectrum_ivas_fx( Word16 *highPassEner_exp, /**< ou Word32 highPassEner; /* Q31 */ Word32 lastLine; Word32 nextLine; - Word32 L_c; - Word32 highPassEner_Ovfl; - Word16 s; - Word16 tmploop; Word16 *swb_offset; Word16 sfb; Word16 startSfb; Word16 stopSfb; Word16 line; - Word16 flag; Word16 *igfScaleF; Word16 tmp; - Word32 L_tmp; - -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - Flag Carry = 0; - move32(); - move32(); -#endif + Word16 factor; + Word16 exp1, exp2; + Word16 num, den; + Word32 temp; hPrivateData = &hInstance->igfData; hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; @@ -576,10 +566,6 @@ void IGF_ErodeSpectrum_ivas_fx( Word16 *highPassEner_exp, /**< ou move16(); igfScaleF = hPrivateData->igfScfQuantized; move16(); - *highPassEner_exp = 0; - move16(); - highPassEner = 0; - move32(); IF( NULL == pPowerSpectrum ) { @@ -593,90 +579,82 @@ void IGF_ErodeSpectrum_ivas_fx( Word16 *highPassEner_exp, /**< ou IF( igfBgn > 0 ) { - L_c = 0; - move32(); + Word64 sum = 0; + move64(); FOR( i = 0; i < igfBgn; i++ ) { - Carry = 0; - highPassEner = L_add_co( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/, &Carry, &Overflow ); - Overflow = 0; - L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); + sum = W_mac_32_16( sum, pPowerSpectrum[i], i ); // Q: 31-pPowerSpectrum_exp+1 } + exp1 = W_norm( sum ); + sum = W_shl( sum, sub( exp1, 1 ) ); // Q: 31-pPowerSpectrum_exp+1+exp1-1 + num = extract_h( W_extract_h( sum ) ); // Q: 31-pPowerSpectrum_exp+exp1-48 = -pPowerSpectrum_exp+exp1-17 + exp1 = add( 32, sub( pPowerSpectrum_exp, exp1 ) ); // exp: 32+pPowerSpectrum_exp-exp1 - highPassEner = norm_llQ31( L_c, highPassEner, highPassEner_exp ); /*Q20, highPassEner_exp*/ - *highPassEner_exp = add( *highPassEner_exp, pPowerSpectrum_exp ); - test(); - test(); - test(); - test(); - test(); IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_16400_CPE ) ) { - igfBgn = shl( igfBgn, 0 ); + factor = ONE_IN_Q14; // Q14 + move16(); } ELSE IF( mct_on && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) ) ) { - igfBgn = imult1616( igfBgn, 45 /*0.7.Q6*/ ); - igfBgn = shr( igfBgn, 7 ); + factor = 11469; // 0.7f in Q14 + move16(); } ELSE { - igfBgn = shl( igfBgn, 1 ); + factor = 32767; // 2.f in Q14 + move16(); } - highPassEner = L_deposit_l( BASOP_Util_Divide3216_Scale( highPassEner /*Q20, highPassEner_exp*/, igfBgn /*Q0*/, &s ) ); /*Q15, highPassEner_exp+11-16+s*/ - *highPassEner_exp = add( add( *highPassEner_exp, s ), 12 - 16 + ( 31 - 15 ) ); /*Q15->Q31,highPassEner_exp*/ - lastLine = pSpectrum[i - 1]; + + temp = L_mult( igfBgn, factor ); // exp: 16 + exp2 = norm_l( temp ); + den = extract_h( L_shl( temp, exp2 ) ); // exp: 16-exp2 + exp2 = sub( 16, exp2 ); + + highPassEner = L_deposit_h( div_s( num, den ) ); // exp: exp1-exp2 + + /* highPassEner is used only for comparison, saturation doesn't effect the outcome */ + highPassEner = L_shl_sat( highPassEner, sub( sub( exp1, exp2 ), pPowerSpectrum_exp ) ); // exp: pPowerSpectrum_exp + + lastLine = pSpectrum[i - 1]; // Qx move32(); - nextLine = 0; + nextLine = pSpectrum[i]; // Qx move32(); - /* May overflow - just for threshold comparison */ - /* negate because the negated may be 1 larger in abs, */ - /* so whenever compared to the negation of a maximum possible pPowerspectrum, it is still larger */ - highPassEner_Ovfl = L_shl_o( L_negate( highPassEner ), sub( *highPassEner_exp, pPowerSpectrum_exp ), &Overflow ); - L_tmp = L_add_o( pPowerSpectrum[i - 1], highPassEner_Ovfl, &Overflow ); - - if ( L_tmp >= 0 ) + if ( LT_32( pPowerSpectrum[i - 1], highPassEner ) ) { - nextLine = pSpectrum[i]; + nextLine = 0; move32(); } - tmploop = sub( igfEnd, 1 ); - FOR( /*i*/; i < tmploop; i++ ) + + FOR( /*i*/; i < igfEnd - 1; i++ ) { /* May overflow - just for threshold comparison */ - BASOP_SATURATE_WARNING_OFF_EVS - L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl ); - BASOP_SATURATE_WARNING_ON_EVS; - - IF( L_tmp < 0 ) + IF( LT_32( pPowerSpectrum[i], highPassEner ) ) { - lastLine = pSpectrum[i]; + lastLine = pSpectrum[i]; // Qx move32(); - pSpectrum[i] = nextLine; + pSpectrum[i] = nextLine; // Qx move32(); nextLine = 0; move32(); } ELSE { - pSpectrum[i - 1] = lastLine; + pSpectrum[i - 1] = lastLine; // Qx move32(); - lastLine = pSpectrum[i]; + lastLine = pSpectrum[i]; // Qx move32(); - nextLine = pSpectrum[i + 1]; + nextLine = pSpectrum[i + 1]; // Qx move32(); } } /* May overflow - just for threshold comparison */ - BASOP_SATURATE_WARNING_OFF_EVS - L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl ); - BASOP_SATURATE_WARNING_ON_EVS - if ( L_tmp < 0 ) + if ( LT_32( pPowerSpectrum[i], highPassEner ) ) { pSpectrum[i] = 0; move32(); @@ -692,27 +670,29 @@ void IGF_ErodeSpectrum_ivas_fx( Word16 *highPassEner_exp, /**< ou move32(); } - FOR( sfb = startSfb; sfb < stopSfb; sfb++ ) + // Below check is present at the beginning of the function and is not required here + /* IF( NULL != pPowerSpectrum ) */ { - flag = 0; - move16(); - FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ ) + FOR( sfb = startSfb; sfb < stopSfb; sfb++ ) { - if ( pSpectrum[line] != 0 ) + tmp = 0; + move16(); + FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ ) { - flag = 1; - move16(); + if ( pSpectrum[line] != 0 ) + { + tmp = add( tmp, 1 ); + } } - } - tmp = igfScaleF[sfb]; - move16(); - IF( flag ) - { - tmp = sub( igfScaleF[sfb], 1 ); - } - if ( igfScaleF[sfb] ) - { - igfScaleF[sfb] = tmp; + + Word16 igfScaleF_cnt = igfScaleF[sfb]; + move16(); + test(); + if ( tmp && igfScaleF[sfb] ) + { + igfScaleF_cnt = sub( igfScaleF[sfb], 1 ); + } + igfScaleF[sfb] = igfScaleF_cnt; move16(); } } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 280a76c94..711d7069a 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2432,6 +2432,24 @@ void tcx_arith_encode_envelope_fx( const Word16 low_complexity /* i: low-complexity flag Q0 */ ); +void tcx_arith_encode_envelope_ivas_fx( + Word32 spectrum[], /* i/o: MDCT coefficients Q31-e */ + Word16 *spectrum_e, /* i/o: MDCT exponent Q0 */ + Word16 signs[], /* o: signs (spectrum[.]<0) Q0 */ + const Word16 L_frame, /* i: frame or MDCT length Q0 */ + const Word16 L_spec, /* i: frame or MDCT length Q0 */ + Encoder_State *st, /* i/o: coder state */ + const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */ + Word16 target_bits, /* i: number of available bits Q0 */ + Word16 prm[], /* o: bitstream parameters Q0 */ + const Word8 use_hm, /* i: use HM in current frame? */ + Word16 prm_hm[], /* o: HM parameter area Q0 */ + const Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/ + Word16 *arith_bits, /* o: bits used for ari. coding Q0 */ + Word16 *signaling_bits, /* o: bits used for signaling Q0 */ + const Word16 low_complexity /* i: low-complexity flag Q0 */ +); + /** Quantize gain. * Quantize gain in range [0..127], * @param n Length of the spectrum. @@ -3050,8 +3068,7 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< out: | const Word16 igfGridIdx /**< in: Q0 | IGF grid index */ ); -void IGF_ErodeSpectrum_ivas_fx( Word16 *highPassEner_exp, /**< out: | exponent of highPassEner */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ +void IGF_ErodeSpectrum_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ Word32 *pSpectrum, /**< in/out: | MDCT spectrum */ Word32 *pPowerSpectrum, /**< in/out: | power spectrum */ Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */ -- GitLab From 38678a41ba18f765d3c49e114772ee16609621ad Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Mon, 17 Feb 2025 22:34:25 +0530 Subject: [PATCH 0197/1221] Fix for 3GPP issue 1262: Saturated signal in discrete multichannel output with fx encoder in v2 release --- lib_enc/ivas_mct_enc.c | 2 ++ lib_enc/ivas_mdct_core_enc.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 8c194bed1..5510f1eb1 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -401,6 +401,8 @@ ivas_error ivas_mct_enc_fx( move16(); st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[1] = sub( 31, q_spec ); move16(); + st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e = sub( 31, q_spec ); + move16(); IF( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) { diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 18bee6777..4997a6715 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -2672,6 +2672,11 @@ void ivas_mdct_quant_coder_fx( st->hTcxEnc->spectrum_e[n] = min_shift; move16(); } + if ( GT_16( nSubframes, 1 ) ) + { + st->hTcxEnc->spectrum_long_e = min_shift; + move16(); + } } EstimateStereoTCXNoiseLevel_fx( sts, quantized_spectrum_fx, gain_tcx_fx, gain_tcx_e, L_frame, noiseFillingBorder, hm_active, ignore_chan, fac_ns_fx, param_core, MCT_flag ); -- GitLab From fb7b54f9ea764dd7584503928143c1effef6db81 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Mon, 17 Feb 2025 22:50:36 +0530 Subject: [PATCH 0198/1221] Partila fix for 3GPP issue 1239: BASOP encoder OSBA: artifacts in discrete object channel --- lib_enc/ivas_mct_enc_mct.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 18218aa25..4b84ea9cb 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -601,6 +601,11 @@ static void getGlobalILD_fx( { sts[ch]->hTcxEnc->spectrum_e[k] = add( sts[ch]->hTcxEnc->spectrum_e[k], 4 ); // Updating exponent of spectrum as q_ratio is in Q11 } + IF( GT_16( nSubframes, 1 ) ) + { + sts[ch]->hTcxEnc->spectrum_long_e = add( sts[ch]->hTcxEnc->spectrum_long_e, 4 ); + move16(); + } FOR( k = 0; k < nSubframes; k++ ) { @@ -877,10 +882,12 @@ void apply_MCT_enc_fx( } sts[ch]->hTcxEnc->spectrum_e[1] = add( sts[ch]->hTcxEnc->spectrum_e[0], exp ); sts[ch]->hTcxEnc->spectrum_e[0] = add( sts[ch]->hTcxEnc->spectrum_e[0], exp ); + sts[ch]->hTcxEnc->spectrum_long_e = add( sts[ch]->hTcxEnc->spectrum_long_e, exp ); hMCT->mc_global_ild[ch] = 0; move16(); move16(); move16(); + move16(); } } } -- GitLab From dfdaaaa72496aa328d0c80a09d24861fa7e6a3f8 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Mon, 17 Feb 2025 22:59:10 +0530 Subject: [PATCH 0199/1221] Fix for 3GPP issue 1287: Major spectral difference between signal decoded from fixed- and floating-point encoded bitstreams at 13.2kbps for OSBA inputs --- lib_enc/igf_enc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index a85843be2..e23417e70 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2666,9 +2666,10 @@ void IGFEncApplyMono_ivas_fx( FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) { - common_pPowerSpectrum_fx[i] = L_shl( common_pPowerSpectrum_fx[i], sub( pPowerSpectrumParameter_exp[i], common_pPowerSpectrum_exp ) ); + common_pPowerSpectrum_fx[i] = L_shl( pPowerSpectrumParameter_fx[i], sub( pPowerSpectrumParameter_exp[i], common_pPowerSpectrum_exp ) ); move16(); } + pPowerSpectrumParameter_fx = common_pPowerSpectrum_fx; } IGF_ErodeSpectrum_ivas_fx( &highPassEner_exp, st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, common_pPowerSpectrum_exp, igfGridIdx, 0 ); } -- GitLab From 74f66bf8e65f7b3e63d8df19e27d02b07af0feeb Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 09:47:30 +0100 Subject: [PATCH 0200/1221] further cleanup --- lib_com/options.h | 1 - lib_rend/ivas_dirac_output_synthesis_dec.c | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 92144ade1..2747226b4 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,4 +157,3 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ #define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ -//#define FIX_1072_SPEEDUP_output_synthesis_procSlot /* "-" */ \ No newline at end of file diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 404f98b1b..6a7a73c18 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -942,18 +942,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } -#ifdef FIX_1072_SPEEDUP_output_synthesis_procSlot - q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - q_diff_c = sub( q_diffuseness, 4 ); - - mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 - mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 - mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - - /*Todo: simplify so that mpy+add can be merged to madd*/ - sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ - -#else mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 @@ -981,7 +969,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/ } } -#endif sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ -- GitLab From fc11d020838a7da70152594f05efce479afaddcb Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 11:34:22 +0100 Subject: [PATCH 0201/1221] tiny fix --- lib_com/ivas_dirac_com.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 9fe68f250..38abc76f3 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -968,7 +968,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; -- GitLab From 74d1e1951db936a260f30cd2fefe11c1a41e9cf9 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 11:39:19 +0100 Subject: [PATCH 0202/1221] apply clang format patch --- lib_com/ivas_dirac_com.c | 5 ++--- lib_dec/ivas_dirac_dec.c | 2 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 8 ++------ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 38abc76f3..2704c1f08 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -972,11 +972,11 @@ void computeDiffuseness_fixed( Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; - if( shift_q < 0 ) + if ( shift_q < 0 ) { shiftEquiv = L_lshl( 0x80000000, shift_q ); } - if( shift_q >= 0 ) + if ( shift_q >= 0 ) { shiftEquiv = L_add( 0x7FFFFFFF, 0 ); } @@ -1011,7 +1011,6 @@ void computeDiffuseness_fixed( #endif - q_ene = s_min( q_ene, q_tmp ); /* Intensity slow */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index ed1f292b2..95cca12a0 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2555,7 +2555,7 @@ void ivas_dirac_dec_render_sf_fx( p_Rmat_fx = 0; move32(); } - + IF( ( hDirAC->hConfig->dec_param_estim == FALSE ) ) { Word16 *masa_band_mapping; diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index ba8048267..866badda0 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1099,7 +1099,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); #endif - } #ifdef FIX_1072_SPEEDUP_gainpanning Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); @@ -1109,13 +1108,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { Word16 i; Word32 aux; - IF(temp_q1 < 0) + IF( temp_q1 < 0 ) { Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] , aux, temp_q1_equiv ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv ); move32(); } } @@ -1129,7 +1128,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } - } ELSE { @@ -1140,8 +1138,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } - - } #else -- GitLab From 8fcadb93851018d4702a386c6dcf388e72810373 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 12:23:28 +0100 Subject: [PATCH 0203/1221] added some push/pop wmops , introduced FIX_1072_SPEEDUP_output_synthesis_procSlot --- lib_com/ivas_dirac_com.c | 51 ++++++++ lib_com/options.h | 5 + lib_dec/ivas_dirac_dec.c | 23 +++- lib_rend/ivas_dirac_output_synthesis_dec.c | 143 ++++++++++++++++++++- 4 files changed, 214 insertions(+), 8 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index ebd958e1b..796fc8960 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -960,6 +960,7 @@ void computeDiffuseness_fixed( q_intensity = add( q_factor_intensity[0], min_q_shift2 ); move16(); + push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" ); FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) { /* Energy slow */ @@ -967,6 +968,28 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); + +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB + Word16 shift_q = sub( q_tmp, q_ene ); + Word32 shiftEquiv; + Word16 shift_qtotal; + if( shift_q < 0 ) + { + shiftEquiv = L_lshl( 0x80000000, shift_q ); + shift_qtotal = sub( min_q_shift1, 0 ); + } + if( shift_q >= 0 ) + { + shiftEquiv = L_add( 0x7FFFFFFF, 0 ); + shift_qtotal = sub( min_q_shift1, shift_q ); + } + FOR( k = 0; k < num_freq_bands; k++ ) + { + tmp = L_shl( p_tmp_c[k], shift_qtotal ); + energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); + move32(); + } +#else Word16 shift_q = sub( q_tmp, q_ene ); IF( shift_q < 0 ) { @@ -986,6 +1009,9 @@ void computeDiffuseness_fixed( move32(); } } +#endif + + q_ene = s_min( q_ene, q_tmp ); @@ -993,6 +1019,28 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB + if( shift_q >= 0 ) + { + shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); + shift_qtotal = sub( min_q_shift2, shift_q ); + } + if ( shift_q < 0 ) + { + shiftEquiv = L_lshl( 0x80000000, shift_q ); + shift_qtotal = sub( min_q_shift2, 0 ); + } + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = buffer_intensity[j][i]; + FOR( k = 0; k < num_freq_bands; k++ ) + { + tmp = L_shl( p_tmp[k], shift_qtotal ); + intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv ); + move32(); + } + } +#else IF( shift_q > 0 ) { FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) @@ -1019,8 +1067,11 @@ void computeDiffuseness_fixed( } } } +#endif + q_intensity = s_min( q_intensity, q_tmp ); } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" );/*/ min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) ); min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) ); diff --git a/lib_com/options.h b/lib_com/options.h index fa1fd8f4e..47a8f8b2c 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -153,3 +153,8 @@ #define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ #endif #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ + + +#define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ +#define FIX_1072_SPEEDUP_output_synthesis_procSlot /* "-" */ \ No newline at end of file diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 95cca12a0..318a3ec55 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2231,7 +2231,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); Word16 tmp1; - push_wmops( "ivas_dirac_dec_render" ); + push_wmops( "ivas_dirac_dec_render (IDR)" ); /* Initialize aux buffers */ hDirAC = st_ivas->hDirAC; @@ -2341,6 +2341,7 @@ void ivas_dirac_dec_render_sf_fx( } ELSE IF( !( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) { + push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" ); Word16 outchannels; idx_lfe = 0; move16(); @@ -2409,6 +2410,7 @@ void ivas_dirac_dec_render_sf_fx( } } } + pop_wmops(); /*push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" );*/ } size = imult1616( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); @@ -2555,7 +2557,7 @@ void ivas_dirac_dec_render_sf_fx( p_Rmat_fx = 0; move32(); } - + IF( ( hDirAC->hConfig->dec_param_estim == FALSE ) ) { Word16 *masa_band_mapping; @@ -2706,6 +2708,7 @@ void ivas_dirac_dec_render_sf_fx( } } + push_wmops( "(IDR) LOOP1" ); FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { index_slot = add( slot_idx_start, slot_idx ); @@ -2923,6 +2926,8 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: + pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; @@ -2932,6 +2937,7 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * Compute DirAC parameters at decoder side *-----------------------------------------------------------------*/ + push_wmops( "(IDR) LOOP1 DirACparams |" ); IF( EQ_16( hDirAC->hConfig->dec_param_estim, TRUE ) ) { Copy( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], sub( hSpatParamRendCom->num_freq_bands, hDirAC->hConfig->enc_param_start_band ) ); @@ -2980,8 +2986,11 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; move16(); + push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" ); computeDiffuseness_fixed( hDirACRend->buffer_intensity_real_fx, hDirACRend->buffer_energy_fx, num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], hDirACRend->q_buffer_intensity_real, hDirACRend->q_buffer_energy, &hSpatParamRendCom->q_diffuseness_vector ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" );/*/ } + pop_wmops(); /* push_wmops( "(IDR) LOOP1 DirACparams |" );*/ /*-----------------------------------------------------------------* * frequency domain decorrelation @@ -3083,6 +3092,7 @@ void ivas_dirac_dec_render_sf_fx( } /*Compute PSDs*/ + push_wmops( "(IDR) LOOP1 PSDs |" ); h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params ); h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state ); num_channels_dir = hDirACRend->num_outputs_dir; @@ -3165,6 +3175,7 @@ void ivas_dirac_dec_render_sf_fx( } ELSE { + push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" ); ivas_dirac_dec_output_synthesis_process_slot_fx( reference_power_fx, DirAC_mem.reference_power_q, p_onset_filter_fx, @@ -3182,6 +3193,7 @@ void ivas_dirac_dec_render_sf_fx( md_idx, hodirac_flag, hDirAC->hConfig->dec_param_estim ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" );/*/ } IF( hDirAC->hConfig->dec_param_estim ) @@ -3252,7 +3264,9 @@ void ivas_dirac_dec_render_sf_fx( v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); q_reference_power_smooth = sub( q_reference_power_smooth, 1 ); } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs |" );*/ } + pop_wmops(); /*push_wmops( "(IDR) LOOP1" );*/ minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) @@ -3581,7 +3595,6 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * CLDFB synthesis (and binaural rendering) *-----------------------------------------------------------------*/ - index_slot = slot_idx_start_cldfb_synth; move16(); @@ -3963,6 +3976,7 @@ void ivas_dirac_dec_render_sf_fx( } } + hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); move16(); hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); @@ -4077,8 +4091,7 @@ void ivas_dirac_dec_render_sf_fx( } } } - - pop_wmops(); + pop_wmops(); /*push_wmops( "ivas_dirac_dec_render (IDR)" );*/ return; } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 4686ca1e6..320492c66 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -710,11 +710,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } + push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" ); test(); IF( dec_param_estim == FALSE && hodirac_flag ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" ); v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */ v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/ Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx], @@ -737,19 +739,24 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); h_dirac_output_synthesis_state->direct_power_factor_q = 30; move16(); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" );/*/ } ELSE { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" ); ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], h_dirac_output_synthesis_state->direct_power_factor_fx, h_dirac_output_synthesis_state->diffuse_power_factor_fx, &h_dirac_output_synthesis_state->direct_power_factor_q, &h_dirac_output_synthesis_state->diffuse_power_factor_q ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" );*/ } } ELSE IF( EQ_16( dec_param_estim, TRUE ) ) { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" ); + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" ); /* compute direct responses */ ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom, hDirACRend, @@ -764,7 +771,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sh_rot_max_order, p_Rmat, hodirac_flag ); - + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" );*/ { IF( h_dirac_output_synthesis_state->direct_responses_square_fx ) { @@ -811,12 +818,14 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[kk] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; move16(); } - + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" ); FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ ) { Word16 k; IF( ch_idx != 0 ) { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" ); + ; Word32 a, c; Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c; Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab; @@ -906,6 +915,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ + + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -931,11 +942,63 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } +#ifdef FIX_1072_SPEEDUP_output_synthesis_procSlot + q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + q_diff_c = sub( q_diffuseness, 4 ); mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 + /*Todo: simplify so that mpy+add can be merged to madd*/ + + //sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ + + { + Word16 mpy_diff_c_exp = sub( 31, q_diff_c ); + Word16 q_diff_aab_exp = sub( 31, q_diff_aab ); + + Word32 L_tmp; + Word16 shift; + + if ( !mpy_diff_c ) + mpy_diff_c_exp = add( q_diff_aab_exp, 0 ); + + if ( !mpy_diff_aab ) + q_diff_aab_exp = add( mpy_diff_c_exp, 0 ); + + shift = sub( mpy_diff_c_exp, q_diff_aab_exp ); + shift = s_max( -31, shift ); + shift = s_min( 31, shift ); + if ( shift < 0 ) + { + /* exponent of b is greater than exponent of a, shr mpy_diff_c */ + mpy_diff_c = L_shl( mpy_diff_c, shift ); + } + if ( shift > 0 ) + { + /* exponent of a is greater than exponent of b */ + mpy_diff_aab = L_shr( mpy_diff_aab, shift ); + } + mpy_diff_c_exp = add( s_max( mpy_diff_c_exp, q_diff_aab_exp ), 1 ); + L_tmp = L_add( L_shr( mpy_diff_c, 1 ), L_shr( mpy_diff_aab, 1 ) ); + shift = norm_l( L_tmp ); + if ( shift ) + L_tmp = L_shl( L_tmp, shift ); + if ( L_tmp == 0 ) + mpy_diff_c_exp = add( 0, 0 ); + if ( L_tmp != 0 ) + mpy_diff_c_exp = sub( mpy_diff_c_exp, shift ); + sqr_exp = mpy_diff_c_exp; + + sqr_inp = L_tmp; + } + +#else + mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 + mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 + mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 + q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); q_diff_c = sub( q_diffuseness, 4 ); @@ -959,6 +1022,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/ } } +#endif + sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) @@ -987,9 +1052,12 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" );*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" );*/ } ELSE { + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" ); Word32 sqr_inp, mpy_diff, sqr; Word16 sqr_exp; /*Diffuseness modellling nrg compensation*/ @@ -1027,6 +1095,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1 @@ -1060,8 +1129,12 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" );*/ + pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ } } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ + Word16 temp = MAX_16; /*q0*/ move16(); tmp16 = imult1616( num_freq_bands, num_channels_dir ); @@ -1078,9 +1151,21 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } free( Q_temp_cy_cross_dir_smooth_fx ); /*Directional gain (panning)*/ + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" ); + Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { +#ifdef FIX_1072_SPEEDUP_gainpanning /*is there any difference in any bitstream?*/ + Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); + FOR( Word16 kk = 0; kk < tmp16; kk++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], temp_q1 ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ + move32(); + } + h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; + move16(); +#else FOR( Word16 kk = 0; kk < tmp16; kk++ ) { h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ @@ -1088,7 +1173,53 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); +#endif + + } +#ifdef FIX_1072_SPEEDUP_gainpanning + Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); + FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) + { + IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + { + Word16 i; + Word32 aux; + IF(temp_q1 < 0) + { + Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); + FOR( i = 0; i < num_freq_bands; i++ ) + { + aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] , aux, temp_q1_equiv ); + move32(); + } + } + ELSE + { + FOR( i = 0; i < num_freq_bands; i++ ) + { + aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + aux = L_shl( aux, temp_q1 ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux ); + move32(); + } + } + + } + ELSE + { + Word16 i; + FOR( i = 0; i < num_freq_bands; i++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + move32(); + } + } + + } + +#else FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { v_mult_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx, @@ -1107,6 +1238,9 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ } +#endif + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" );*/ + /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) { @@ -1124,7 +1258,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/ } - + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3 <<-|" );/*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ return; } ELSE @@ -1143,7 +1278,9 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ diff_start_band = 0; move16(); -- GitLab From e195b40a9d3cc49024483b47e5b60932b3a298a2 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 15:21:55 +0100 Subject: [PATCH 0204/1221] delete FIX_1072_SPEEDUP_output_synthesis_procSlot --- lib_com/options.h | 3 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 33 +++++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 9e9295f22..b3a1e4238 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -170,6 +170,5 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ #define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ -#define FIX_1072_SPEEDUP_output_synthesis_procSlot /* "-" */ #endif \ No newline at end of file diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 320492c66..39d52be9f 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -942,28 +942,27 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } +#define FIX_1072_SPEEDUP_output_synthesis_procSlot #ifdef FIX_1072_SPEEDUP_output_synthesis_procSlot q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); q_diff_c = sub( q_diffuseness, 4 ); - mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 - mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 - mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - - /*Todo: simplify so that mpy+add can be merged to madd*/ - - //sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ - { Word16 mpy_diff_c_exp = sub( 31, q_diff_c ); Word16 q_diff_aab_exp = sub( 31, q_diff_aab ); - Word32 L_tmp; + Word32 L_tmp, L_tmp1, L_tmp2; Word16 shift; - if ( !mpy_diff_c ) - mpy_diff_c_exp = add( q_diff_aab_exp, 0 ); + mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 + mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 + + L_tmp = L_add( diffuseness[k], 0 ); + if ( !diffuseness[k] ) + mpy_diff_c_exp = add( q_diff_aab_exp, 0 ); + if ( !c ) + mpy_diff_c_exp = add( q_diff_aab_exp, 0 ); if ( !mpy_diff_aab ) q_diff_aab_exp = add( mpy_diff_c_exp, 0 ); @@ -973,7 +972,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( if ( shift < 0 ) { /* exponent of b is greater than exponent of a, shr mpy_diff_c */ - mpy_diff_c = L_shl( mpy_diff_c, shift ); + L_tmp = L_shl( L_tmp, shift ); } if ( shift > 0 ) { @@ -981,7 +980,15 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_diff_aab = L_shr( mpy_diff_aab, shift ); } mpy_diff_c_exp = add( s_max( mpy_diff_c_exp, q_diff_aab_exp ), 1 ); - L_tmp = L_add( L_shr( mpy_diff_c, 1 ), L_shr( mpy_diff_aab, 1 ) ); + L_tmp = L_shr( L_tmp, 1 ); + L_tmp1 = L_shr( mpy_diff_aab, 1 ); + + L_tmp = Madd_32_32( L_tmp1, L_tmp, c ); // Q = q_diffuseness - 4 + + /*Todo: simplify so that mpy+add can be merged to madd*/ + + // sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ + shift = norm_l( L_tmp ); if ( shift ) L_tmp = L_shl( L_tmp, shift ); -- GitLab From 7ffce0ac054813b100e1d6fa03aaf7cc8139c5a8 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 15:22:21 +0100 Subject: [PATCH 0205/1221] delete FIX_1072_SPEEDUP_output_synthesis_procSlot 2 --- lib_rend/ivas_dirac_output_synthesis_dec.c | 61 ---------------------- 1 file changed, 61 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 39d52be9f..6a7a73c18 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -942,66 +942,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } -#define FIX_1072_SPEEDUP_output_synthesis_procSlot -#ifdef FIX_1072_SPEEDUP_output_synthesis_procSlot - q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - q_diff_c = sub( q_diffuseness, 4 ); - - { - Word16 mpy_diff_c_exp = sub( 31, q_diff_c ); - Word16 q_diff_aab_exp = sub( 31, q_diff_aab ); - - Word32 L_tmp, L_tmp1, L_tmp2; - Word16 shift; - - mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 - mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 - - L_tmp = L_add( diffuseness[k], 0 ); - - if ( !diffuseness[k] ) - mpy_diff_c_exp = add( q_diff_aab_exp, 0 ); - if ( !c ) - mpy_diff_c_exp = add( q_diff_aab_exp, 0 ); - if ( !mpy_diff_aab ) - q_diff_aab_exp = add( mpy_diff_c_exp, 0 ); - - shift = sub( mpy_diff_c_exp, q_diff_aab_exp ); - shift = s_max( -31, shift ); - shift = s_min( 31, shift ); - if ( shift < 0 ) - { - /* exponent of b is greater than exponent of a, shr mpy_diff_c */ - L_tmp = L_shl( L_tmp, shift ); - } - if ( shift > 0 ) - { - /* exponent of a is greater than exponent of b */ - mpy_diff_aab = L_shr( mpy_diff_aab, shift ); - } - mpy_diff_c_exp = add( s_max( mpy_diff_c_exp, q_diff_aab_exp ), 1 ); - L_tmp = L_shr( L_tmp, 1 ); - L_tmp1 = L_shr( mpy_diff_aab, 1 ); - - L_tmp = Madd_32_32( L_tmp1, L_tmp, c ); // Q = q_diffuseness - 4 - - /*Todo: simplify so that mpy+add can be merged to madd*/ - - // sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ - - shift = norm_l( L_tmp ); - if ( shift ) - L_tmp = L_shl( L_tmp, shift ); - if ( L_tmp == 0 ) - mpy_diff_c_exp = add( 0, 0 ); - if ( L_tmp != 0 ) - mpy_diff_c_exp = sub( mpy_diff_c_exp, shift ); - sqr_exp = mpy_diff_c_exp; - - sqr_inp = L_tmp; - } - -#else mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 @@ -1029,7 +969,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/ } } -#endif sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ -- GitLab From c481ec66eedc41edf39bdcaaa594f45baab975ba Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 18 Feb 2025 20:23:14 +0530 Subject: [PATCH 0206/1221] Updates for multi_harm_ivas_fx to improve precision --- lib_enc/multi_harm_fx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib_enc/multi_harm_fx.c b/lib_enc/multi_harm_fx.c index 641c35979..86fe541bb 100644 --- a/lib_enc/multi_harm_fx.c +++ b/lib_enc/multi_harm_fx.c @@ -379,6 +379,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni { Word16 i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm; Word16 S[L_FFT / 2], flor, step, tmp16, tmp2, Expx2, Expy2; + Word32 tmp2_32; Word16 corx2, cory2, corxy, cor, cor_map[L_FFT / 2], *pt1, *pt2, cor_strong; Word32 L_acc; Word32 Lcorx2, Lcory2, Lcorxy, Lcor_map_LT_sum; @@ -621,7 +622,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni *------------------------------------------------------------------*/ Lcor_map_LT_sum = L_deposit_l( 0 ); - tmp2 = 0; + tmp2_32 = 0; move16(); cor_strong = 0; @@ -633,7 +634,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni FOR( i = 0; i < L; i++ ) { /* tmp2 += S[i]; */ - tmp2 = add( tmp2, shl( S[i], 1 ) ); /* tmp2 in Q8; max value is 128) */ + tmp2_32 = L_add( tmp2_32, cor_map[i] ); /* tmp2_32 in Q15; max value is 128) */ /* *pt1 = M_ALPHA_FX * *pt1 + (1-M_ALPHA_FX) * *pt2++ */ *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 ); @@ -651,6 +652,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni pt1++; pt2++; } + tmp2 = L_shr_sat( tmp2_32, 7 ); // q15-> q8 IF( EQ_16( bwidth, NB ) ) { -- GitLab From c1a600e4a450d562fdccf8b817434e11401370f5 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 18 Feb 2025 20:31:08 +0530 Subject: [PATCH 0207/1221] Bug fix in wb_vad_ivas_fx to update vad flag --- lib_enc/vad_fx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index 38e43b032..12ec31933 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -2638,11 +2638,15 @@ Word16 wb_vad_ivas_fx( /* DTX HANGOVER is in pre_proc_fx() */ flag_he1 = 0; move16(); - + st_fx->localVAD = 0; + move16(); IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_mssnr, L_mssnr_e, L_vad_thr, 18 ), 1 ) ) { flag_he1 = 1; - move16(); /* he1 primary decision */ + move16(); + st_fx->localVAD = 1; + move16(); + /* he1 primary decision */ hVAD->nb_active_frames_he1 = add( hVAD->nb_active_frames_he1, 1 ); /* Counter of consecutive active speech frames */ move16(); -- GitLab From 9ab12acf35c129fae7d4bfc27bde0200a2331f59 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 18 Feb 2025 16:01:44 +0100 Subject: [PATCH 0208/1221] Some more push/pop wmops --- lib_com/ivas_dirac_com.c | 4 ++-- lib_com/options.h | 2 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 796fc8960..97c8a88bd 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -969,7 +969,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; @@ -1019,7 +1019,7 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS if( shift_q >= 0 ) { shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); diff --git a/lib_com/options.h b/lib_com/options.h index b3a1e4238..44e1e3623 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -169,6 +169,6 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESSB /* "-" */ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* "-" */ #endif \ No newline at end of file diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 6a7a73c18..540934a63 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -623,7 +623,6 @@ void ivas_dirac_dec_output_synthesis_close_fx( * * *------------------------------------------------------------------------*/ - void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ const Word16 q_reference_power, /* i : Estimated power Q */ @@ -756,7 +755,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( ELSE IF( EQ_16( dec_param_estim, TRUE ) ) { push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" ); - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" ); /* compute direct responses */ ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom, hDirACRend, @@ -771,7 +769,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sh_rot_max_order, p_Rmat, hodirac_flag ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.1<<<<-|" );*/ { IF( h_dirac_output_synthesis_state->direct_responses_square_fx ) { @@ -945,7 +942,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); q_diff_c = sub( q_diffuseness, 4 ); @@ -2974,6 +2970,8 @@ void ivas_dirac_dec_compute_directional_responses_fx( Word16 dipole_freq_range[2]; MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type; + push_wmops( "(IDR PATH3 B3.1)" ); + Q_direct_response_ls = Q31; move16(); exp_direct_response_ls = 0; @@ -3035,6 +3033,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( LT_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) && NE_16( k, hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) ) { + push_wmops( "(IDR PATH3 B3.1) mvr2r_inc_fixed " ); /* Panning gains have to be computed only for the first bin of the coding band in MASA, for other bins the previous values can be used */ IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { @@ -3046,12 +3045,15 @@ void ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/ + pop_wmops();/*push_wmops( "(IDR PATH3 B3.1) mvr2r_inc_fixed " );*/ } ELSE { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING " ); /* HOA3 PANNING */ IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_HOA3 ) ) { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF" ); set32_fx( direct_response_hoa_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/ set32_fx( direct_response_dir2_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/ @@ -3350,9 +3352,11 @@ void ivas_dirac_dec_compute_directional_responses_fx( { assert( 0 && "Not supported synthesis method!" ); } + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF" );*/ } ELSE IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_VBAP ) ) /*VBAP*/ { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING ELSE" ); /* Synthesize the first direction */ spreadCoherencePanningVbap_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k], direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir, hVBAPdata ); @@ -3604,11 +3608,13 @@ void ivas_dirac_dec_compute_directional_responses_fx( mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/ mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/ + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING ELSE" );*/ } ELSE { assert( 0 && "Not supported panning method!" ); } + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING " );*/ } } @@ -3617,6 +3623,8 @@ void ivas_dirac_dec_compute_directional_responses_fx( hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = direct_response_square_q; move16(); + + pop_wmops(); return; } -- GitLab From b5e558f9e226b03eec447def9a8df876ec82ebaf Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 18 Feb 2025 20:28:17 +0530 Subject: [PATCH 0209/1221] MSAN fix for encoder and decoder --- lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 7 +++++++ lib_enc/cod_tcx_fx.c | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 216888fbe..5867a44b3 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -1241,6 +1241,13 @@ void ivas_sba_dirac_stereo_dec_fx( CPE_DEC_HANDLE hCPE; STEREO_DFT_DEC_DATA_HANDLE hStereoDft; +#ifdef MSAN_FIX + FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) + { + set32_fx( DFT[i], 0, STEREO_DFT_BUF_MAX ); + } +#endif + hSCE = st_ivas->hSCE[0]; hCPE = st_ivas->hCPE[0]; hStereoDft = hCPE->hStereoDft; diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 94b030f5a..b2fe04ce1 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -1717,6 +1717,10 @@ void EstimateStereoTCXNoiseLevel_fx( Word16 *fac_ns_q; Word32 total_brate; +#ifdef MSAN_FIX + set32_fx( combined_q_spectrum, 0, N_MAX ); +#endif + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { Encoder_State *st = sts[ch]; -- GitLab From 48ece3d0c459c1563c8f25f674d063c7b6a86a2d Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Wed, 19 Feb 2025 14:00:48 +0530 Subject: [PATCH 0210/1221] Fix for 3GPP issue 1258: Decoder: Click artifact for Stereo to Mono Decoding --- lib_dec/ivas_core_dec.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 8d88074a8..9aaddb2fb 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -782,6 +782,7 @@ ivas_error ivas_core_dec_fx( /* for inactive frames with mono output, copy and (if necessary) downmix buffers */ ELSE IF( EQ_16( hCPE->nchan_out, 1 ) ) { + Word16 shift1, shift2; sts[0] = hCPE->hCoreCoder[0]; sts[1] = hCPE->hCoreCoder[1]; @@ -800,6 +801,15 @@ ivas_error ivas_core_dec_fx( move16(); sts[1]->hHQ_core->Q_old_wtda = sub( 15, sts[1]->hHQ_core->exp_old_out ); move16(); + + shift1 = norm_arr( sts[0]->hHQ_core->old_out_fx, L_FRAME48k ); + shift2 = norm_arr( sts[1]->hHQ_core->old_out_fx, L_FRAME48k ); + scale_sig( sts[0]->hHQ_core->old_out_fx, L_FRAME48k, shift1 ); + scale_sig( sts[1]->hHQ_core->old_out_fx, L_FRAME48k, shift2 ); + sts[0]->hHQ_core->Q_old_wtda = add( sts[0]->hHQ_core->Q_old_wtda, shift1 ); + sts[1]->hHQ_core->Q_old_wtda = add( sts[1]->hHQ_core->Q_old_wtda, shift2 ); + move16(); + move16(); } } -- GitLab From b949948e2b31ca8013cc26ca8e6a3b8cf8cca02d Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 10:23:33 +0100 Subject: [PATCH 0211/1221] version now with 2 macros for NONBE and BE code parts --- lib_com/options.h | 4 +++- lib_enc/ivas_mc_param_enc.c | 44 ++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index c87cd23da..9ee0d46fc 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -160,7 +160,9 @@ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ // #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ -// #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +/* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #define FIX_ISSUE_1247 diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index e205a015e..b5bc92016 100755 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -723,14 +723,14 @@ static void ivas_param_mc_param_est_enc_fx( } } -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#if defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE ) || defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE ) Word16 gb = find_guarded_bits_fx( l_ts ); Word16 add20gb = add( 20, gb ); #endif FOR( ts = start_ts; ts < num_time_slots; ts++ ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#if !defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE ) && !defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE ) Word16 gb = find_guarded_bits_fx( l_ts ); #endif ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb ); @@ -741,6 +741,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( i = 0; i < nchan_input; i++ ) { pcm_in_fx[i] += l_ts; + move32(); } /* Computing the downmix */ FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ ) @@ -758,6 +759,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE dmx_real_fx[ch_idx1] = 0; move32(); dmx_real_e[ch_idx1] = 0; @@ -776,6 +778,28 @@ static void ivas_param_mc_param_est_enc_fx( move32(); p_dmx_fac_fx++; } +#else + Word32 real_fx = L_add(0,0); + Word16 real_e = add(0, 0); + Word32 imag_fx = L_add( 0, 0 ); + Word16 imag_e = add( 0, 0 ); + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e ); + L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add20gb, &imag_e ); + p_dmx_fac_fx++; + } + dmx_real_fx[ch_idx1] = real_fx; + dmx_real_e[ch_idx1] = real_e; + dmx_imag_fx[ch_idx1] = imag_fx; + dmx_imag_e[ch_idx1] = imag_e; + move32(); + move16(); + move32(); + move16(); +#endif } /* Cx for transport channels */ @@ -815,7 +839,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); a_e = sub( add20gb, a_e ); @@ -835,7 +859,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); @@ -887,7 +911,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE dmx_real_fx[ch_idx1] = 0; move32(); dmx_real_e[ch_idx1] = 0; @@ -937,7 +961,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -949,7 +973,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -984,7 +1008,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); a_e = sub( add20gb, a_e ); @@ -1004,7 +1028,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); @@ -1031,7 +1055,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); - move32(); +pri move32(); } } } -- GitLab From d07b495424684c5238177f60d920ca6a2584cb30 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 10:25:46 +0100 Subject: [PATCH 0212/1221] fix stupid typo --- lib_enc/ivas_mc_param_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index b5bc92016..248f80d81 100755 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -1055,7 +1055,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); -pri move32(); + move32(); } } } -- GitLab From cfa5fa996e7797541a2b2bd9fe04305f77ea7379 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 10:28:27 +0100 Subject: [PATCH 0213/1221] fix clang-format-issues --- lib_enc/ivas_mc_param_enc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100755 => 100644 lib_enc/ivas_mc_param_enc.c diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c old mode 100755 new mode 100644 index 248f80d81..c50f58ff3 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -779,8 +779,8 @@ static void ivas_param_mc_param_est_enc_fx( p_dmx_fac_fx++; } #else - Word32 real_fx = L_add(0,0); - Word16 real_e = add(0, 0); + Word32 real_fx = L_add( 0, 0 ); + Word16 real_e = add( 0, 0 ); Word32 imag_fx = L_add( 0, 0 ); Word16 imag_e = add( 0, 0 ); FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) -- GitLab From 1bb7dd5c70dda96a488f52e4c56dc475ecf35c86 Mon Sep 17 00:00:00 2001 From: Bauer Date: Thu, 20 Feb 2025 10:46:34 +0100 Subject: [PATCH 0214/1221] added/changed FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot & FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx --- lib_com/ivas_prot_fx.h | 8 ++ lib_com/ivas_spar_com.c | 135 +++++++++++++++++++++ lib_com/options.h | 7 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 117 +++++++++++++----- 4 files changed, 237 insertions(+), 30 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 5ce037b9a..ed72fd178 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4994,6 +4994,14 @@ void ivas_dirac_dec_get_response_fx( const Word16 ambisonics_order, Word16 Q_out ); +#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx +void ivas_dirac_dec_get_response_fx_29( + const Word16 azimuth, + const Word16 elevation, + Word32 *response_fx, /*Q_out*/ + const Word16 ambisonics_order); + #endif + void calculate_hodirac_sector_parameters_fx( DIRAC_ENC_HANDLE hDirAC, /* i : DirAC handle */ Word32 RealBuffer_fx[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : signal vector (L+1)^2 x N_bins, real part */ diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 14de6cc15..cd5bab07c 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -7173,6 +7173,141 @@ void ivas_dirac_dec_get_response_fx( return; } +#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx +void ivas_dirac_dec_get_response_fx_29( + const Word16 azimuth, + const Word16 elevation, + Word32 *response_fx, /*Q_out*/ + const Word16 ambisonics_order) +{ + Word16 index_azimuth, index_elevation; + Word16 el, az; + Word32 cos_1_fx, cos_2_fx, sin_1_fx, cos_az_fx[3]; + Word32 sin_az_fx[3]; + Word32 f_fx; + Word32 c_fx_better; + Word16 l, m; + Word16 b, b1, b_2, b1_2; + //Word16 Q_out = 29; + + push_wmops( "ivas_dirac_dec_get_response_fx_29" ); + index_azimuth = add( azimuth, 180 ) % 360; + move16(); + index_elevation = add( elevation, 90 ); + + Word32 e_fac = L_add(0x7FFFFFFF, 0); + + if ( GT_16( index_elevation, 90 ) ) + { + e_fac = L_add(0x80000000, 0); + } + + + el = index_elevation; + move16(); + + if ( GT_16( index_elevation, 90 ) ) + { + el = sub( 180, index_elevation ); + } + + az = index_azimuth; + move16(); + + if ( GT_16( index_azimuth, 180 ) ) + { + az = sub( 360, index_azimuth ); + } + + f_fx = 1; + move16(); + + if ( GT_16( index_azimuth, 180 ) ) + { + f_fx = -1; + } + + cos_1_fx = L_shr( dirac_gains_trg_term_fx[az][0], 1 ); // q30 + cos_2_fx = L_shl( Mpy_32_32( cos_1_fx, cos_1_fx ), 1 ); // q30 + sin_1_fx = L_shr( dirac_gains_trg_term_fx[az][1], 1 ); // q30 + + if ( EQ_32( f_fx, -1 ) ) + { + sin_1_fx = L_negate( sin_1_fx ); // q30 + } + cos_az_fx[0] = cos_1_fx; // q30 + move32(); + cos_az_fx[1] = L_shl( L_sub( cos_2_fx, ONE_IN_Q29 /*0.5 q30*/ ), 1 ); /*q30*/ + move32(); + cos_az_fx[2] = L_sub( L_shl( Mpy_32_32( cos_1_fx, cos_az_fx[1] ), 2 ), cos_az_fx[0] /* cos_az_fx[0] q30*/ ); /*q30*/ + move32(); + sin_az_fx[0] = sin_1_fx; /*q30*/ + move32(); + sin_az_fx[1] = L_shl( Mpy_32_32( sin_1_fx, cos_1_fx ), 2 ); /*q30*/ + move32(); + sin_az_fx[2] = L_shl( Mpy_32_32( sin_1_fx, L_sub( cos_2_fx, ONE_IN_Q28 /*1/4 q30*/ ) ), 3 ); /*q30*/ + move32(); + + //response_fx[0] = L_shl_sat( 1, Q_out ); // Q_out + response_fx[0] = 0x20000000; + move32(); + + //q_diff = sub( Q_out, 29 ); + + push_wmops( "ivas_dirac_dec_get_response_fx_29_LOOPS" ); + +FOR( l = 1; l <= ambisonics_order; l++ ) + { + Word16 a; + b_2 = imult1616( l, l ); + b1_2 = add( b_2, shl( l, 1 ) ); + FOR( m = 0; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + + c_fx_better = local_result_table[el][a]; // q30 + move32(); + response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); // Q_out + move32(); + + b1 = b1_2 - m; + response_fx[b1] = Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ); // Q_out + move32(); + } + + FOR( m = 1; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c_fx_better = local_result_table[el][a]; // q30 + move32(); + c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30 + response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); // Q_out + move32(); + + b1 = b1_2 - m; + response_fx[b1] = Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ); // Q_out + move32(); + } + + b = add( b_2, l ); + a = dirac_gains_P_idx[b]; + c_fx_better = local_result_table_2[el][a]; // q30 + move32(); + if ( s_and( l, 0x01 ) ) + { + c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30 + } + response_fx[b] = L_shl( c_fx_better, -1 ); // Q_out + move32(); + } + + pop_wmops(); /*push_wmops( "ivas_dirac_dec_get_response_fx_29_LOOPS" );*/ + pop_wmops(); /*push_wmops( "ivas_dirac_dec_get_response_fx_29" );*/ + return; +} +#endif /*FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx*/ /*-----------------------------------------------------------------------------------------* * Function ivas_get_bits_to_encode * diff --git a/lib_com/options.h b/lib_com/options.h index 44e1e3623..8fe969bb6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -164,11 +164,12 @@ #define FIX_ISSUE_1247 #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_1285_DECODER_CRASH - #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ +#define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, in development*/ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* "-" */ -#define FIX_1072_SPEEDUP_gainpanning /* FhG: WMOPS tuning, in development*/ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* "-" */ +#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ +#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ #endif \ No newline at end of file diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 540934a63..f7d18b65d 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -821,7 +821,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word16 k; IF( ch_idx != 0 ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" ); + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop A <<<<<-|" ); ; Word32 a, c; Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c; @@ -912,8 +912,50 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop A <<<<<-|" );*/ + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" ); +#ifdef FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot + FOR( ; k < num_freq_bands; k++ ) + { + a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses + move32(); + IF( reference_power[k + num_freq_bands] == 0 ) + { + sqr_inp = Mpy_32_32( diffuseness[k], c ); + sqr_exp = sub( 31 - 4, q_diffuseness ); + } + ELSE + { + IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 ) + { + mpy_a_a_b = Mpy_32_32( a, a ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 + mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 + mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 + //q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q, add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + q_diff_aab = sub( add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ), 62 ); + q_diff_c = sub( q_diffuseness, 4 ); + + sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ + } + ELSE + { + b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ + + mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 + mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 + mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 + //q_diff_aab = add( add(h_dirac_output_synthesis_state->direct_responses_q , sub( sub( 15, b_exp ), 15 )), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + q_diff_aab = add( sub( h_dirac_output_synthesis_state->direct_responses_q, b_exp ), ( sub( add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ), 62 ) ) ); + q_diff_c = sub( q_diffuseness, 4 ); - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" ); + sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ + + } + } + sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ + sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ + } +#else FOR( ; k < num_freq_bands; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -942,7 +984,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + q_diff_aab = add( add( h_dirac_output_synthesis_state->direct_responses_q, sub( sub( 15, b_exp ), 15 ) ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); q_diff_c = sub( q_diffuseness, 4 ); test(); @@ -968,38 +1010,40 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ - IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) + } +#endif + + IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) + { + IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { - IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ - move32(); - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); - move16(); - } - ELSE - { - sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; - move16(); - } - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + move16(); } ELSE { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ - move32(); - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; move16(); } + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ + move32(); + } + ELSE + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + move16(); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF nfreqbds <<<<<<-|" );*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop IF <<<<<-|" );*/ + + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" );*/ } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" ); + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop C <<<<<-|" ); Word32 sqr_inp, mpy_diff, sqr; Word16 sqr_exp; /*Diffuseness modellling nrg compensation*/ @@ -1037,7 +1081,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" ); + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop C <<<<<<-|" );*/ + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop D <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1 @@ -1071,8 +1116,8 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE nfreqbds <<<<<<-|" );*/ - pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop ELSE <<<<<-|" );/*/ + + pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop D <<<<<-|" );/*/ } } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ @@ -3066,24 +3111,38 @@ void ivas_dirac_dec_compute_directional_responses_fx( exp_direct_response_dir2 = 0; move16(); + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse" ); IF( p_Rmat != 0 ) { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse_SPLIT_FX" ); ivas_dirac_dec_get_response_split_order_fx( azimuth[k], elevation[k], direct_response_hoa_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_hoa ); IF( hodirac_flag ) { ivas_dirac_dec_get_response_split_order_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_dir2 ); } + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse_SPLIT_FX" );*/ } ELSE { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse__FX" ); +#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx + ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order); +#else ivas_dirac_dec_get_response_fx( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_hoa ); +#endif IF( hodirac_flag ) { +#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx + ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order); +#else ivas_dirac_dec_get_response_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_dir2 ); +#endif } + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse__FX" );*/ } + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse" );*/ test(); test(); @@ -3091,16 +3150,19 @@ void ivas_dirac_dec_compute_directional_responses_fx( test(); IF( masa_band_mapping == NULL && EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH1" ); mvr2r_inc_fixed( direct_response_hoa_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_hoa*/ IF( hodirac_flag ) { mvr2r_inc_fixed( direct_response_dir2_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_dir2*/ } + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH1" );*/ } ELSE IF( ( ( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) && ( masa_band_mapping != NULL ) ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) { + push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH2" ); /* Synthesize the first direction */ IF( GT_16( Q_direct_response_hoa, Q29 ) ) { @@ -3347,6 +3409,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( } mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*q29*/ + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH2" );*/ } ELSE { -- GitLab From 3adbd6fbee1af752c0dae017f684a30aef7f2029 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Feb 2025 11:01:39 +0100 Subject: [PATCH 0215/1221] use ignorelist in USAN job --- .gitlab-ci.yml | 10 ++++++++-- Makefile | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1bc5a6f07..855f5d571 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -553,9 +553,15 @@ stages: - *copy-ltv-files-to-testv-dir - python3 ci/remove_unsupported_testcases.py $PRM_FILES - *build-reference-and-dut-binaries + + - make_args="CLANG=$CLANG_NUM" + - if [[ $CLANG_NUM == 3 ]]; then + - export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1" + - python3 scripts/basop_create_ignorelist_for_ubsan.py + - make_args="$make_args IGNORELIST=1" + - fi - make clean - - make -j CLANG=$CLANG_NUM - - if [[ $CLANG_NUM == 3 ]]; then export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1"; fi + - make -j $make_args - testcase_timeout=$TESTCASE_TIMEOUT_LTV_SANITIZERS - python3 -m pytest $TEST_SUITE -v --tb=no --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout $testcase_timeout --ref_encoder_path $DUT_ENCODER_PATH --ref_decoder_path $DUT_DECODER_PATH artifacts: diff --git a/Makefile b/Makefile index 4e92bc951..e444cc54b 100644 --- a/Makefile +++ b/Makefile @@ -82,10 +82,14 @@ ifeq "$(CLANG)" "3" CC = $(CCCLANG) # NOTE: keep in sync with list in CMakeLists.txt usan_checks = undefined,float-divide-by-zero,implicit-conversion,local-bounds -CFLAGS += -fsanitize=$(usan_checks) +CFLAGS += -fsanitize=$(usan_checks) CFLAGS += -fsanitize-recover=$(usan_checks) LDFLAGS += -fsanitize=$(usan_checks) LDFLAGS += -fsanitize-recover=$(usan_checks) + +ifeq "$(IGNORELIST)" "1" +CFLAGS += -fsanitize-ignorelist=ubsan_ignorelist.txt +LDFLAGS += -fsanitize-ignorelist=ubsan_ignorelist.txt endif ifeq "$(RELEASE)" "1" -- GitLab From 62d1d624acb3f90d7b7b3405ef026972dd794a33 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 11:32:40 +0100 Subject: [PATCH 0216/1221] deactivated temporarily the NONBE part of this MR to check the pipeline results --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 9ee0d46fc..bee60af30 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,7 +162,7 @@ // #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ /* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #define FIX_ISSUE_1247 -- GitLab From fc5fb077d82513ee77924703f210e305063a3052 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Wed, 19 Feb 2025 14:37:14 +0530 Subject: [PATCH 0217/1221] Updates in MCT core encoder path for precision improvement --- lib_com/ivas_prot_fx.h | 19 ++++++++++--------- lib_enc/igf_enc.c | 4 ++-- lib_enc/ivas_lfe_enc.c | 7 ++++--- lib_enc/ivas_mct_core_enc.c | 38 ++++++++++++++++++------------------- lib_enc/ivas_mct_enc_mct.c | 25 ++++++++++++++---------- lib_enc/tcx_utils_enc_fx.c | 4 ++-- 6 files changed, 52 insertions(+), 45 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 5ce037b9a..1682c255b 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3341,15 +3341,16 @@ void ivas_omasa_enc_fx( ); void mctStereoIGF_enc_fx( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - Word16 q_origSpec, /* i : Q for MDCT spectrum */ - Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx and powSpecMsInv_fx*/ - Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ + Word16 q_origSpec, /* i : Q for MDCT spectrum */ + Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ + Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */ + Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/ + Word16 q_powerSpecMsInv[MCT_MAX_CHANNELS], /* i : Q for powSpecMsInv_fx */ + Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ + const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ); void ivas_mct_core_enc_fx( diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index d20169e73..0ce087508 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -943,9 +943,9 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); sfbEnergyR = add_sat( EPSILON_FX, BASOP_Util_Divide3216_Scale( sum2_32_fx( pMDCTSpectrum_fx + swb_offset[sfb], width, &tmp_e ) /*exp: tmp_e*/, width, &sfbEnergyR_e ) ); // sfbEnergyR_e sfbEnergyR_e = add( sfbEnergyR_e, add( tmp_e, -15 ) ); - gain = sfbEnergyR; // gain_e + gain = L_shl( sfbEnergyR, 16 ); // gain_e move32(); - gain_e = add( sfbEnergyR_e, 16 ); + gain_e = sfbEnergyR_e; IF( element_mode > EVS_MONO ) { diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc.c index e72270e6c..e219e8b37 100644 --- a/lib_enc/ivas_lfe_enc.c +++ b/lib_enc/ivas_lfe_enc.c @@ -199,12 +199,13 @@ static void ivas_lfe_enc_quant_fx( q_lfe_abs_sum = sub( q_lfe_abs_sum, q_tmp ); } - tmp = BASOP_Util_Divide3232_Scale( max_value, W_extract_l( lfe_abs_sum ), &q_tmp ); - tmp = L_shl( tmp, sub( q_lfe_abs_sum, sub( 15, q_tmp ) ) ); /* Q0 (max_value / lfe_abs_sum) */ + tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( max_value, W_extract_l( lfe_abs_sum ), &q_tmp ) ); + // tmp = L_shl( tmp, sub( q_lfe_abs_sum, sub( 15, q_tmp ) ) ); /* Q0 (max_value / lfe_abs_sum) */ + q_tmp = sub( Q16, sub( q_lfe_abs_sum, sub( 15, q_tmp ) ) ); /* log2_f(max_value / lfe_abs_sum) -> Q25 */ tmp = BASOP_Util_Log2( tmp ); - tmp = L_add( tmp, 1040187392 ) /* (31<<25) -> 1040187392 */; /* Q25 */ + tmp = L_add( tmp, L_shl( sub( Q31, q_tmp ), Q25 ) ) /* (31<<25) -> 1040187392 */; /* Q25 */ /* IVAS_LFE_SHIFTS_PER_DOUBLE * log2_f(max_value / lfe_abs_sum) */ tmp = Mpy_32_16_1( tmp, IVAS_LFE_SHIFTS_PER_DOUBLE ); /* 25-15 -> Q10 */ diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index f5f179778..52fd554d8 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -247,7 +247,7 @@ void ivas_mct_core_enc_fx( Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ Word16 total_side_bits; Word16 chBitRatios[MCT_MAX_CHANNELS]; - Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; + Word16 q_powSpec[MCT_MAX_CHANNELS], q_powerSpecMsInv[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; Word16 tmp_q_powSpec[L_FRAME48k], tmp_q_powSpecInv[L_FRAME48k], *tmp_q_psi[2]; Word64 W_tmp; Encoder_State *sts[MCT_MAX_CHANNELS]; @@ -437,7 +437,7 @@ void ivas_mct_core_enc_fx( FOR( i = 0; i < L_subframeTCX; i++ ) { W_tmp = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -445,7 +445,7 @@ void ivas_mct_core_enc_fx( move16(); W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -459,7 +459,7 @@ void ivas_mct_core_enc_fx( { /* power spectrum: MDCT^2 + MDST^2 */ W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp ); tmp_q_psi[n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -471,7 +471,7 @@ void ivas_mct_core_enc_fx( mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); /* An MDST estimate */ W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -480,7 +480,7 @@ void ivas_mct_core_enc_fx( } W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp ); tmp_q_psi[n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -490,7 +490,7 @@ void ivas_mct_core_enc_fx( /* power spectrum: MDCT^2 + MDST^2 */ W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][0], sts[ch]->hTcxEnc->spectrum_fx[n][0] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpec_fx[ch][n * L_subframeTCX] = W_extract_h( W_tmp ); tmp_q_powSpec[n * L_subframeTCX] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -513,7 +513,7 @@ void ivas_mct_core_enc_fx( } W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpec_fx[ch][( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); tmp_q_powSpec[( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -524,31 +524,31 @@ void ivas_mct_core_enc_fx( /* Aligning the Q-factors */ { + q_powSpec[ch] = Q31; + move16(); + q_powerSpecMsInv[ch] = Q31; + move16(); /* NOTE: This logic has been added because using a constant headroom while computing `powSpec` and `powSpecMsInv` leads to significant precision loss, which results in poor quality. */ FOR( i = 0; i < L_FRAME48k; i++ ) { - if ( powerSpec_fx[ch][i] == 0 ) + IF( powerSpec_fx[ch][i] != 0 ) { - tmp_q_powSpec[i] = 63; + q_powSpec[ch] = s_min( q_powSpec[ch], add( tmp_q_powSpec[i], norm_l( powerSpec_fx[ch][i] ) ) ); move16(); } - if ( powerSpecMsInv_fx[ch][0][i] == 0 ) + IF( powerSpecMsInv_fx[ch][0][i] != 0 ) { - tmp_q_powSpecInv[i] = 63; + q_powerSpecMsInv[ch] = s_min( q_powerSpecMsInv[ch], add( tmp_q_powSpecInv[i], norm_l( powerSpecMsInv_fx[ch][0][i] ) ) ); move16(); } } - minimum_s( tmp_q_powSpec, L_FRAME48k, &q_powSpec[ch] ); - minimum_s( tmp_q_powSpecInv, L_FRAME48k, &tmp_s ); - q_powSpec[ch] = s_min( q_powSpec[ch], tmp_s ); - move16(); FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpec[ch] ) ); - powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i], q_powSpec[ch] ) ); + powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powerSpecMsInv[ch] ) ); + powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i + ( n * L_subframeTCX )], q_powSpec[ch] ) ); move32(); move32(); } @@ -606,7 +606,7 @@ void ivas_mct_core_enc_fx( { IF( hMCT->currBlockDataCnt > 0 ) { - mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, powerSpecMsInv_fx, q_powSpec, inv_spectrum_fx, sp_aud_decision0 ); + mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, q_powSpec, powerSpecMsInv_fx, q_powerSpecMsInv, inv_spectrum_fx, sp_aud_decision0 ); } ELSE { diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 4b84ea9cb..654c00db4 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -981,15 +981,16 @@ void write_mct_bitstream_fx( * IGF analysis of channels after MCT processing *--------------------------------------------------------------------*/ void mctStereoIGF_enc_fx( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - Word16 q_origSpec, /* i : Q for MDCT spectrum */ - Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx and powSpecMsInv_fx*/ - Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ + Word16 q_origSpec, /* i : Q for MDCT spectrum */ + Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ + Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */ + Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/ + Word16 q_powerSpecMsInv[MCT_MAX_CHANNELS], /* i : Q for powSpecMsInv_fx */ + Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ + const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ) { Word32 *p_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; @@ -999,6 +1000,7 @@ void mctStereoIGF_enc_fx( Word16 b, nSubframes, L_subframeTCX; Word16 p_ch[2], n, ch, ch1, ch2, s = 31; + Word16 q_pSI_ch[2]; Word16 q_pS_ch[2]; Encoder_State *p_st[NB_DIV]; Encoder_State *st; @@ -1062,7 +1064,9 @@ void mctStereoIGF_enc_fx( p_inv_spectrum_fx[0][n] = inv_spectrum_fx[ch1][n]; p_inv_spectrum_fx[1][n] = inv_spectrum_fx[ch2][n]; q_pS_ch[0] = q_powerSpec[ch1]; + q_pSI_ch[0] = q_powerSpecMsInv[ch1]; q_pS_ch[1] = q_powerSpec[ch2]; + q_pSI_ch[1] = q_powerSpecMsInv[ch2]; move16(); move16(); @@ -1075,6 +1079,7 @@ void mctStereoIGF_enc_fx( { s = s_min( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[n] ) ); s = s_min( s, q_pS_ch[ch] ); + s = s_min( s, q_pSI_ch[ch] ); } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -1085,7 +1090,7 @@ void mctStereoIGF_enc_fx( move16(); move16(); - scale_sig32( p_powerSpecMsInv_fx[ch][0], L_FRAME48k, sub( s, q_pS_ch[ch] ) ); + scale_sig32( p_powerSpecMsInv_fx[ch][0], L_FRAME48k, sub( s, q_pSI_ch[ch] ) ); scale_sig32( &p_powerSpec_fx[ch][0], sts[ch]->hTcxEnc->L_frameTCX, sub( s, q_pS_ch[ch] ) ); q_powerSpec[ch1] = s; q_powerSpec[ch2] = s; diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 1e35c78c4..27c8e6f5f 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3842,7 +3842,7 @@ void ProcessIGF_ivas_fx( ITF_Detect_ivas_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); test(); - IF( LT_32( L_deposit_l( hIGFEnc->tns_predictionGain ), 9646899 /* 1.15 in Q23 */ ) && LT_32( L_deposit_l( predictionGain ), 9646899 /* 1.15 in Q23 */ ) ) + IF( LT_16( hIGFEnc->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 ) ) { hIGFEnc->flatteningTrigger = 1; move16(); @@ -3949,7 +3949,7 @@ void ProcessStereoIGF_fx( ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); test(); - hIGFEnc[ch]->flatteningTrigger = LT_32( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q23 ) && LT_32( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); + hIGFEnc[ch]->flatteningTrigger = LT_16( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); move16(); hIGFEnc[ch]->infoTotalBitsPerFrameWritten = 0; -- GitLab From f016e6dd8aa1358d8f459755d87fa721f8a40fa1 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Feb 2025 12:27:45 +0100 Subject: [PATCH 0218/1221] fix missing endif --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index e444cc54b..9d18cbde3 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,7 @@ ifeq "$(IGNORELIST)" "1" CFLAGS += -fsanitize-ignorelist=ubsan_ignorelist.txt LDFLAGS += -fsanitize-ignorelist=ubsan_ignorelist.txt endif +endif ifeq "$(RELEASE)" "1" CFLAGS += -DRELEASE -- GitLab From 550a38ef5fb2ae8ee48555504ae3b1b13b7d3a9c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Feb 2025 13:28:25 +0100 Subject: [PATCH 0219/1221] remove redundant builds and set bash strict mode --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 855f5d571..c1e56d48d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -552,8 +552,9 @@ stages: - *update-scripts-repo - *copy-ltv-files-to-testv-dir - python3 ci/remove_unsupported_testcases.py $PRM_FILES - - *build-reference-and-dut-binaries + - *build-reference-binaries + - set -euxo pipefail - make_args="CLANG=$CLANG_NUM" - if [[ $CLANG_NUM == 3 ]]; then - export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1" -- GitLab From abc297aae68e774f96cdb5ac108997b539f289a4 Mon Sep 17 00:00:00 2001 From: Bauer Date: Thu, 20 Feb 2025 13:57:31 +0100 Subject: [PATCH 0220/1221] some more mods to FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot --- lib_rend/ivas_dirac_output_synthesis_dec.c | 56 ++++++++++++++++------ 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index f7d18b65d..d96165ba4 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -821,8 +821,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word16 k; IF( ch_idx != 0 ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop A <<<<<-|" ); - ; Word32 a, c; Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c; Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab; @@ -912,7 +910,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop A <<<<<-|" );*/ + push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" ); #ifdef FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot FOR( ; k < num_freq_bands; k++ ) @@ -926,16 +924,20 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } ELSE { + Word16 diff_c_exp; + Word16 diff_aab_exp; IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 ) { mpy_a_a_b = Mpy_32_32( a, a ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 //q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q, add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - q_diff_aab = sub( add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ), 62 ); - q_diff_c = sub( q_diffuseness, 4 ); + //q_diff_aab = sub( add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ), 62 ); + diff_aab_exp = sub( 31 + 62, add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ) ); + //q_diff_c = sub( q_diffuseness, 4 ); + diff_c_exp = sub( 31 + 4, q_diffuseness ); - sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ + sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/ } ELSE { @@ -945,16 +947,44 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 //q_diff_aab = add( add(h_dirac_output_synthesis_state->direct_responses_q , sub( sub( 15, b_exp ), 15 )), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - q_diff_aab = add( sub( h_dirac_output_synthesis_state->direct_responses_q, b_exp ), ( sub( add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ), 62 ) ) ); - q_diff_c = sub( q_diffuseness, 4 ); + //q_diff_aab = add( sub( h_dirac_output_synthesis_state->direct_responses_q, b_exp ), ( sub( add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ), 62 ) ) ); + diff_aab_exp = sub( sub( add( sub( 31 + 62, h_dirac_output_synthesis_state->direct_responses_q ), b_exp ), h_dirac_output_synthesis_state->direct_responses_q ), q_diffuseness ); + //q_diff_c = sub( q_diffuseness, 4 ); + diff_c_exp = sub( 31 + 4, q_diffuseness ); - sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/ + sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/ } } sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ } + + IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) + { + IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + move16(); + } + ELSE + { + sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; + move16(); + } + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ + move32(); + } + ELSE + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + move16(); + } #else FOR( ; k < num_freq_bands; k++ ) { @@ -1011,7 +1041,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ } -#endif IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) { @@ -1038,12 +1067,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); move16(); } +#endif + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" );*/ } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop C <<<<<-|" ); Word32 sqr_inp, mpy_diff, sqr; Word16 sqr_exp; /*Diffuseness modellling nrg compensation*/ @@ -1081,8 +1111,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop C <<<<<<-|" );*/ - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop D <<<<<<-|" ); FOR( ; k < num_freq_bands; k++ ) { mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1 @@ -1116,8 +1144,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } - - pop_wmops();/*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop D <<<<<-|" );/*/ } } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ -- GitLab From 552ffd749e2a208554bcf06ed5afb13cd9acbc85 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 14:57:16 +0100 Subject: [PATCH 0221/1221] reactivated NONBE modifications to see pipeline effects --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 006a3811d..1a2e77c95 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,7 +162,7 @@ // #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ /* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ -//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #define FIX_ISSUE_1247 -- GitLab From 81b0eae0d1ed28a9e59a25f0397ef9b8887693ba Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Feb 2025 14:58:30 +0100 Subject: [PATCH 0222/1221] fix order of arguments in basop_check_for_changes.py script --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1bc5a6f07..1aa93e06c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -491,7 +491,7 @@ stages: ### compare the two csv files for regressions - regressions_found=0 - - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH || regressions_found=$? + - python3 scripts/basop_check_for_changes_in_testcases.py --xml_report $XML_REPORT_BRANCH $CSV_BRANCH $CSV_MAIN || regressions_found=$? - if [ $exit_code -eq 1 ]; then echo "Differences encountered"; exit_code=$EXIT_CODE_NON_BE; fi - if [ $zero_errors_branch != 1 ]; then echo "Run errors encountered!"; exit_code=$EXIT_CODE_NON_BE; fi -- GitLab From 592784dde6f72cd513196a8066255e1b0a1d4be6 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Feb 2025 14:52:16 +0000 Subject: [PATCH 0223/1221] Revert some unwanted changes --- lib_com/ivas_prot_fx.h | 2 +- lib_com/options.h | 1 - lib_dec/ivas_dirac_dec.c | 3 ++- lib_rend/ivas_dirac_output_synthesis_dec.c | 5 ++++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 21583afe5..96a628408 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -5001,7 +5001,7 @@ void ivas_dirac_dec_get_response_fx_29( const Word16 elevation, Word32 *response_fx, /*Q_out*/ const Word16 ambisonics_order); - #endif +#endif void calculate_hodirac_sector_parameters_fx( DIRAC_ENC_HANDLE hDirAC, /* i : DirAC handle */ diff --git a/lib_com/options.h b/lib_com/options.h index 8fe969bb6..88bb82c2e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -164,7 +164,6 @@ #define FIX_ISSUE_1247 #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_1285_DECODER_CRASH -#define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, in development*/ #define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* "-" */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 318a3ec55..13ba3479b 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -3595,6 +3595,7 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * CLDFB synthesis (and binaural rendering) *-----------------------------------------------------------------*/ + index_slot = slot_idx_start_cldfb_synth; move16(); @@ -3976,7 +3977,6 @@ void ivas_dirac_dec_render_sf_fx( } } - hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); move16(); hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); @@ -4091,6 +4091,7 @@ void ivas_dirac_dec_render_sf_fx( } } } + pop_wmops(); /*push_wmops( "ivas_dirac_dec_render (IDR)" );*/ return; diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index d96165ba4..a620095a0 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -623,6 +623,7 @@ void ivas_dirac_dec_output_synthesis_close_fx( * * *------------------------------------------------------------------------*/ + void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ const Word16 q_reference_power, /* i : Estimated power Q */ @@ -769,6 +770,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sh_rot_max_order, p_Rmat, hodirac_flag ); + { IF( h_dirac_output_synthesis_state->direct_responses_square_fx ) { @@ -1011,9 +1013,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } + mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 + q_diff_aab = add( add( h_dirac_output_synthesis_state->direct_responses_q, sub( sub( 15, b_exp ), 15 ) ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); q_diff_c = sub( q_diffuseness, 4 ); @@ -1037,7 +1041,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/ } } - sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ } -- GitLab From 9c1092282d7f2d8635aec151f01ee76ff1640463 Mon Sep 17 00:00:00 2001 From: Bauer Date: Thu, 20 Feb 2025 15:57:09 +0100 Subject: [PATCH 0224/1221] applied clang patch --- lib_com/ivas_dirac_com.c | 7 ++-- lib_com/ivas_prot_fx.h | 2 +- lib_com/ivas_spar_com.c | 18 +++++------ lib_com/options.h | 4 +-- lib_dec/ivas_dirac_dec.c | 6 ++-- lib_rend/ivas_dirac_output_synthesis_dec.c | 37 ++++++++++------------ 6 files changed, 34 insertions(+), 40 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 97c8a88bd..d03191084 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -973,12 +973,12 @@ void computeDiffuseness_fixed( Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv; Word16 shift_qtotal; - if( shift_q < 0 ) + if ( shift_q < 0 ) { shiftEquiv = L_lshl( 0x80000000, shift_q ); shift_qtotal = sub( min_q_shift1, 0 ); } - if( shift_q >= 0 ) + if ( shift_q >= 0 ) { shiftEquiv = L_add( 0x7FFFFFFF, 0 ); shift_qtotal = sub( min_q_shift1, shift_q ); @@ -1012,7 +1012,6 @@ void computeDiffuseness_fixed( #endif - q_ene = s_min( q_ene, q_tmp ); /* Intensity slow */ @@ -1020,7 +1019,7 @@ void computeDiffuseness_fixed( shift_q = sub( q_tmp, q_intensity ); #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS - if( shift_q >= 0 ) + if ( shift_q >= 0 ) { shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); shift_qtotal = sub( min_q_shift2, shift_q ); diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 96a628408..95dde1650 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -5000,7 +5000,7 @@ void ivas_dirac_dec_get_response_fx_29( const Word16 azimuth, const Word16 elevation, Word32 *response_fx, /*Q_out*/ - const Word16 ambisonics_order); + const Word16 ambisonics_order ); #endif void calculate_hodirac_sector_parameters_fx( diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index cd5bab07c..c6194b8de 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -7178,7 +7178,7 @@ void ivas_dirac_dec_get_response_fx_29( const Word16 azimuth, const Word16 elevation, Word32 *response_fx, /*Q_out*/ - const Word16 ambisonics_order) + const Word16 ambisonics_order ) { Word16 index_azimuth, index_elevation; Word16 el, az; @@ -7188,18 +7188,18 @@ void ivas_dirac_dec_get_response_fx_29( Word32 c_fx_better; Word16 l, m; Word16 b, b1, b_2, b1_2; - //Word16 Q_out = 29; + // Word16 Q_out = 29; push_wmops( "ivas_dirac_dec_get_response_fx_29" ); index_azimuth = add( azimuth, 180 ) % 360; move16(); index_elevation = add( elevation, 90 ); - Word32 e_fac = L_add(0x7FFFFFFF, 0); + Word32 e_fac = L_add( 0x7FFFFFFF, 0 ); if ( GT_16( index_elevation, 90 ) ) { - e_fac = L_add(0x80000000, 0); + e_fac = L_add( 0x80000000, 0 ); } @@ -7248,15 +7248,15 @@ void ivas_dirac_dec_get_response_fx_29( sin_az_fx[2] = L_shl( Mpy_32_32( sin_1_fx, L_sub( cos_2_fx, ONE_IN_Q28 /*1/4 q30*/ ) ), 3 ); /*q30*/ move32(); - //response_fx[0] = L_shl_sat( 1, Q_out ); // Q_out + // response_fx[0] = L_shl_sat( 1, Q_out ); // Q_out response_fx[0] = 0x20000000; move32(); - //q_diff = sub( Q_out, 29 ); + // q_diff = sub( Q_out, 29 ); push_wmops( "ivas_dirac_dec_get_response_fx_29_LOOPS" ); -FOR( l = 1; l <= ambisonics_order; l++ ) + FOR( l = 1; l <= ambisonics_order; l++ ) { Word16 a; b_2 = imult1616( l, l ); @@ -7282,7 +7282,7 @@ FOR( l = 1; l <= ambisonics_order; l++ ) a = dirac_gains_P_idx[b]; c_fx_better = local_result_table[el][a]; // q30 move32(); - c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30 + c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30 response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); // Q_out move32(); @@ -7297,7 +7297,7 @@ FOR( l = 1; l <= ambisonics_order; l++ ) move32(); if ( s_and( l, 0x01 ) ) { - c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30 + c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30 } response_fx[b] = L_shl( c_fx_better, -1 ); // Q_out move32(); diff --git a/lib_com/options.h b/lib_com/options.h index 88bb82c2e..4ef49845c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -#define WMOPS /* Activate complexity and memory counters */ +//#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -171,4 +171,4 @@ #define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ #define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ -#endif \ No newline at end of file +#endif diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 13ba3479b..77287dc76 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2557,7 +2557,7 @@ void ivas_dirac_dec_render_sf_fx( p_Rmat_fx = 0; move32(); } - + IF( ( hDirAC->hConfig->dec_param_estim == FALSE ) ) { Word16 *masa_band_mapping; @@ -2926,7 +2926,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: - pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } @@ -4091,7 +4091,7 @@ void ivas_dirac_dec_render_sf_fx( } } } - + pop_wmops(); /*push_wmops( "ivas_dirac_dec_render (IDR)" );*/ return; diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index a620095a0..bc4970bcc 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -770,7 +770,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( sh_rot_max_order, p_Rmat, hodirac_flag ); - + { IF( h_dirac_output_synthesis_state->direct_responses_square_fx ) { @@ -933,10 +933,10 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_a_a_b = Mpy_32_32( a, a ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - //q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q, add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - //q_diff_aab = sub( add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ), 62 ); + // q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q, add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + // q_diff_aab = sub( add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ), 62 ); diff_aab_exp = sub( 31 + 62, add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ) ); - //q_diff_c = sub( q_diffuseness, 4 ); + // q_diff_c = sub( q_diffuseness, 4 ); diff_c_exp = sub( 31 + 4, q_diffuseness ); sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/ @@ -948,14 +948,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - //q_diff_aab = add( add(h_dirac_output_synthesis_state->direct_responses_q , sub( sub( 15, b_exp ), 15 )), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - //q_diff_aab = add( sub( h_dirac_output_synthesis_state->direct_responses_q, b_exp ), ( sub( add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ), 62 ) ) ); + // q_diff_aab = add( add(h_dirac_output_synthesis_state->direct_responses_q , sub( sub( 15, b_exp ), 15 )), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); + // q_diff_aab = add( sub( h_dirac_output_synthesis_state->direct_responses_q, b_exp ), ( sub( add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ), 62 ) ) ); diff_aab_exp = sub( sub( add( sub( 31 + 62, h_dirac_output_synthesis_state->direct_responses_q ), b_exp ), h_dirac_output_synthesis_state->direct_responses_q ), q_diffuseness ); - //q_diff_c = sub( q_diffuseness, 4 ); + // q_diff_c = sub( q_diffuseness, 4 ); diff_c_exp = sub( 31 + 4, q_diffuseness ); sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/ - } } sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ @@ -1190,7 +1189,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); #endif - } #ifdef FIX_1072_SPEEDUP_gainpanning Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); @@ -1200,13 +1198,13 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { Word16 i; Word32 aux; - IF(temp_q1 < 0) + IF( temp_q1 < 0 ) { Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] , aux, temp_q1_equiv ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv ); move32(); } } @@ -1220,7 +1218,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } - } ELSE { @@ -1231,8 +1228,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move32(); } } - - } #else @@ -1294,7 +1289,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ + pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ @@ -3119,7 +3114,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/ - pop_wmops();/*push_wmops( "(IDR PATH3 B3.1) mvr2r_inc_fixed " );*/ + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) mvr2r_inc_fixed " );*/ } ELSE { @@ -3156,7 +3151,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( { push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse__FX" ); #ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx - ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order); + ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order ); #else ivas_dirac_dec_get_response_fx( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_hoa ); #endif @@ -3164,7 +3159,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( IF( hodirac_flag ) { #ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx - ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order); + ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order ); #else ivas_dirac_dec_get_response_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_dir2 ); #endif @@ -3438,7 +3433,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( } mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*q29*/ - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH2" );*/ + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH2" );*/ } ELSE { @@ -3700,13 +3695,13 @@ void ivas_dirac_dec_compute_directional_responses_fx( mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/ mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/ - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING ELSE" );*/ + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING ELSE" );*/ } ELSE { assert( 0 && "Not supported panning method!" ); } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING " );*/ + pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING " );*/ } } -- GitLab From 10c03e0a51a27a6e37d269f7ecb930926a407a6e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Feb 2025 14:58:30 +0100 Subject: [PATCH 0225/1221] fix order of arguments in basop_check_for_changes.py script --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f3f527373..51d5bc42e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -619,7 +619,7 @@ stages: ### compare the two csv files for regressions - regressions_found=0 - - python3 scripts/basop_check_for_changes_in_testcases.py --show_improvements --xml_report $XML_REPORT_BRANCH $CSV_MAIN $CSV_BRANCH > regression_log.txt || regressions_found=$? + - python3 scripts/basop_check_for_changes_in_testcases.py --show_improvements --xml_report $XML_REPORT_BRANCH $CSV_BRANCH $CSV_MAIN > regression_log.txt || regressions_found=$? - exit_code=0 - *print-results-banner -- GitLab From a2d7f097464c57e8949bd25d333312e43a6c241a Mon Sep 17 00:00:00 2001 From: malenov Date: Fri, 21 Feb 2025 14:07:49 +0100 Subject: [PATCH 0226/1221] proper way of porting SUPPORT_FORCE_TCX10_TCX20 --- apps/encoder.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/encoder.c b/apps/encoder.c index 165d03543..0cdb2cff9 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -2000,10 +2000,24 @@ static IVAS_ENC_FORCED_MODE parseForcedMode( { return IVAS_ENC_FORCE_GSC; } - else if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) ) + if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) +#ifdef SUPPORT_FORCE_TCX10_TCX20 + || ( strcmp( forcedModeChar, "TCX20" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX20'" ) == 0 ) +#endif + ) { +#ifdef SUPPORT_FORCE_TCX10_TCX20 + return IVAS_ENC_FORCE_TCX20; +#else return IVAS_ENC_FORCE_TCX; +#endif } +#ifdef SUPPORT_FORCE_TCX10_TCX20 + if ( ( strcmp( forcedModeChar, "TCX10" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX10'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_TCX10; + } +#endif else if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) ) { return IVAS_ENC_FORCE_HQ; -- GitLab From ff8a621a25b32357e22ed3f256ef62cfea74f66b Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Feb 2025 14:27:21 +0100 Subject: [PATCH 0227/1221] fix check-be tests comparison was always done with full chain BASOP codec, not using the flt ref en/decoder where applicable --- .gitlab-ci.yml | 81 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 51d5bc42e..65ae34075 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: TESTV_DIR: "/usr/local/testv" LTV_DIR: "/usr/local/ltv" EVS_BE_TEST_DIR_BASOP: "/usr/local/be_2_evs_basop" - REFERENCE_BRANCH: "ivas-float-update" + FLOAT_REF_BRANCH: "ivas-float-update" BUILD_OUTPUT: "build_output.txt" SCRIPTS_DIR: "/usr/local/scripts" EXIT_CODE_NON_BE: 123 @@ -17,6 +17,8 @@ variables: DUT_DECODER_PATH: "./IVAS_dec" REF_ENCODER_PATH: "./IVAS_cod_ref" REF_DECODER_PATH: "./IVAS_dec_ref" + MERGE_TARGET_ENCODER_PATH: "./IVAS_cod_merge_target" + MERGE_TARGET_DECODER_PATH: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" @@ -37,8 +39,9 @@ variables: FAILED_TESTCASES_LIST: "failed-testcases.txt" ERRORS_TESTCASES_LIST: "errors-testcases.txt" PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" - REF_COMMIT_FILE: "ref-branch-git-sha" - CUT_COMMIT_FILE: "CuT-branch-git-sha" + FLOAT_REF_COMMIT_FILE: "float-ref-git-sha" + CUT_COMMIT_FILE: "CuT-git-sha" + MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -147,14 +150,13 @@ stages: - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUG_MODE_INFO\ *\)\*\//\1/g" lib_com/options.h - fi -.build-reference-binaries: &build-reference-binaries +.build-float-ref-binaries: &build-float-ref-binaries - git rev-parse HEAD > $CUT_COMMIT_FILE - current_commit_sha=$(git rev-parse HEAD) ### build reference binaries - - git checkout $REFERENCE_BRANCH + - git checkout $FLOAT_REF_BRANCH - git pull - *activate-debug-mode-info-if-set - - cat lib_com/options.h - make clean - make -j - mv ./IVAS_cod ./$REF_ENCODER_PATH @@ -162,20 +164,35 @@ stages: - mv ./IVAS_rend ./IVAS_rend_ref ### Return to current branch - git restore . - - git rev-parse HEAD > $REF_COMMIT_FILE + - git rev-parse HEAD > $FLOAT_REF_COMMIT_FILE - git checkout $current_commit_sha +.build-merge-target-binaries: &build-merge-target-binaries + - current_commit_sha=$(git rev-parse HEAD) + ### build merge target binaries + - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME + - git pull + - *activate-debug-mode-info-if-set + - make clean + - make -j + - mv ./IVAS_cod ./$MERGE_TARGET_ENCODER_PATH + - mv ./IVAS_dec ./$MERGE_TARGET_DECODER_PATH + - mv ./IVAS_rend ./IVAS_rend_merge_target + ### Return to current branch + - git restore . + - git rev-parse HEAD > $MERGE_TARGET_COMMIT_FILE + - git checkout $current_commit_sha -.build-reference-and-dut-binaries: &build-reference-and-dut-binaries +.build-float-ref-and-dut-binaries: &build-float-ref-and-dut-binaries ### build reference binaries - - *build-reference-binaries + - *build-float-ref-binaries ### build dut binaries - *activate-debug-mode-info-if-set - make clean - make -j -.build-and-create-reference-outputs: &build-and-create-reference-outputs - - *build-reference-and-dut-binaries +.build-and-create-float-ref-outputs: &build-and-create-float-ref-outputs + - *build-float-ref-and-dut-binaries ### prepare pytest # create short test vectors @@ -365,7 +382,7 @@ stages: - if [ "$COMPARE_DMX" = "true" ] || [ "$ENCODER_TEST" = "true" ]; then - BUILD_WITH_DEBUG_MODE_INFO="true" - fi - - *build-and-create-reference-outputs + - *build-and-create-float-ref-outputs - comp_args="--mld --ssnr --odg" - if [ "$ENCODER_TEST" = "true" ]; then @@ -448,15 +465,16 @@ stages: needs: ["build-codec-linux-make"] timeout: "300 minutes" variables: - REFERENCE_BRANCH: "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" + PYTEST_LOG_TARGET_BRANCH: "pytest-log-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME.txt" script: - *print-common-info - set -euxo pipefail - *update-scripts-repo + - python3 tests/create_short_testvectors.py - if [ $USE_LTV -eq 1 ]; then - *update-ltv-repo @@ -471,12 +489,16 @@ stages: - *apply-testv-scaling - fi - - *build-and-create-reference-outputs + - *build-float-ref-binaries + - *build-merge-target-binaries - *check-up-to-date-in-comparison-jobs + - exit_code_target=0 + - python3 -m pytest $TEST_SUITE -v --update_ref 1 --create_ref -n auto --ref_encoder_path $MERGE_TARGET_ENCODER_PATH --ref_decoder_path $MERGE_TARGET_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH > $PYTEST_LOG_TARGET_BRANCH || exit_code_target=$? + - exit_code=0 - rm -rf .pytest_cache || true - - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $MERGE_TARGET_ENCODER_PATH --ref_decoder_path $MERGE_TARGET_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE @@ -495,7 +517,7 @@ stages: - cat failed_testcases_for_printing.txt - echo "Reproduce locally with:" - - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - echo "The individual command lines can be found in the html report in the job artifacts." - if [ $num_errors -ne 0 ]; then @@ -529,8 +551,10 @@ stages: - $ERRORS_TESTCASES_LIST - pytest_log.txt - $PYTEST_CACHE_ARTIFACT - - $REF_COMMIT_FILE + - $FLOAT_REF_COMMIT_FILE - $CUT_COMMIT_FILE + - $MERGE_TARGET_COMMIT_FILE + - $PYTEST_LOG_TARGET_BRANCH expose_as: "pytest compare results" reports: junit: @@ -591,7 +615,7 @@ stages: ### run branch first # this per default builds the branch and the reference and creates the reference outputs - - *build-and-create-reference-outputs + - *build-and-create-float-ref-outputs - *check-up-to-date-in-comparison-jobs # need to restore cache again - *overwrite-pytest-cache-with-artifact @@ -627,7 +651,7 @@ stages: - echo "Run errors encountered!" - exit_code=$EXIT_CODE_FAIL - echo "Reproduce locally with:" - - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - echo "The individual command lines can be found in the changes*.csv files in the job artifacts." - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then @@ -640,7 +664,7 @@ stages: - exit_code=$EXIT_CODE_NON_BE; - fi - echo "Reproduce locally with:" - - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - echo "The individual command lines can be found in the changes*.csv files in the job artifacts." - fi @@ -664,8 +688,9 @@ stages: - $CSV_MAIN - $SUMMARY_HTML_ARTIFACT_NAME - $IMAGES_ARTIFACT_NAME - - $REF_COMMIT_FILE + - $FLOAT_REF_COMMIT_FILE - $CUT_COMMIT_FILE + - $MERGE_TARGET_COMMIT_FILE - changes_crashes.csv - changes_MLD.csv - changes_MAXIMUM_ABS_DIFF.csv @@ -695,7 +720,7 @@ stages: - *copy-ltv-files-to-testv-dir - python3 ci/remove_unsupported_testcases.py $PRM_FILES - - *build-reference-binaries + - *build-float-ref-binaries - set -euxo pipefail - make_args="CLANG=$CLANG_NUM" - if [[ $CLANG_NUM == 3 ]]; then @@ -740,7 +765,7 @@ stages: - if [ $LEVEL_SCALING != "1.0" ];then - *apply-testv-scaling - fi - - *build-reference-and-dut-binaries + - *build-float-ref-and-dut-binaries ### run pytest - exit_code=0 @@ -975,6 +1000,7 @@ check-be-to-target-short-enc-0db: before_script: - USE_LTV=0 - DUT_DECODER_PATH=./IVAS_dec_ref + - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 - rm -rf tests/dut tests/ref @@ -987,6 +1013,7 @@ check-be-to-target-short-enc-+10db: before_script: - USE_LTV=0 - DUT_DECODER_PATH=./IVAS_dec_ref + - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 - rm -rf tests/dut tests/ref @@ -999,6 +1026,7 @@ check-be-to-target-short-enc--10db: before_script: - USE_LTV=0 - DUT_DECODER_PATH=./IVAS_dec_ref + - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - LEVEL_SCALING=0.3162 - rm -rf tests/dut tests/ref @@ -1011,6 +1039,7 @@ check-be-to-target-short-dec-0db: before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref + - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=1.0 - rm -rf tests/dut tests/ref @@ -1023,6 +1052,7 @@ check-be-to-target-short-dec-+10db: before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref + - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=3.162 - rm -rf tests/dut tests/ref @@ -1035,6 +1065,7 @@ check-be-to-target-short-dec--10db: before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref + - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=0.3162 - rm -rf tests/dut tests/ref @@ -1466,7 +1497,7 @@ coverage-test-on-main-scheduled: - *update-scripts-repo - *update-ltv-repo - *copy-ltv-files-to-testv-dir - - *build-reference-binaries + - *build-float-ref-binaries # Build DuT binaries with GCOV - make clean - make GCOV=1 -j @@ -1665,7 +1696,7 @@ voip-be-on-merge-request: - *print-common-info - *update-scripts-repo - *update-ltv-repo - - *build-reference-and-dut-binaries + - *build-float-ref-and-dut-binaries - *complexity-measurements-setup - which coan artifacts: -- GitLab From 548bdacb70227acf2f10c292563f021c385ce1c7 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Feb 2025 14:38:17 +0100 Subject: [PATCH 0228/1221] add missing build for branch --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 65ae34075..292d8ae41 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -491,6 +491,8 @@ stages: - *build-float-ref-binaries - *build-merge-target-binaries + - make clean + - make -j - *check-up-to-date-in-comparison-jobs - exit_code_target=0 -- GitLab From 94133433546736a505d76d3e6dd51c5bc7df0c6b Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 21 Feb 2025 15:17:45 +0100 Subject: [PATCH 0229/1221] Use input_scaling for testing --- .gitlab-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c1e56d48d..cbab6a130 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ variables: REF_DECODER_PATH: "./IVAS_dec_ref" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" + BASOP_CI_BRANCH_PC_REPO: "ci/basop-ci-branch-input-scaling" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 @@ -343,7 +343,7 @@ stages: - fi - *build-and-create-reference-outputs - - comp_args="--mld --ssnr --odg" + - comp_args="--mld --ssnr --odg --input_scaling $LEVEL_SCALING" - if [ "$ENCODER_TEST" = "true" ]; then - comp_args="${comp_args} --enc_stats" - fi @@ -444,11 +444,13 @@ stages: - echo $CI_MERGE_REQUEST_TITLE > tmp.txt - allow_regressions_flag=$(grep -c --ignore-case "\[allow[ -]*regression\]" tmp.txt) || true + - comp_args="--mld --ssnr --odg --input_scaling $LEVEL_SCALING" + ### run branch first # this per default builds the branch and the reference and creates the reference outputs - *build-and-create-reference-outputs - exit_code=0 - - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || exit_code=$? + - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH $comp_args --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || exit_code=$? - zero_errors_branch=$(cat $XML_REPORT_BRANCH | grep -c 'errors="0"') || true - python3 scripts/parse_xml_report.py $XML_REPORT_BRANCH $CSV_BRANCH -- GitLab From e463cc92c149c82a8142eb0045a072ed5cca73f3 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Feb 2025 15:41:28 +0100 Subject: [PATCH 0230/1221] run prepare_combined_files script --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 292d8ae41..1ea012c2a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -485,6 +485,8 @@ stages: - fi - python3 ci/remove_unsupported_testcases.py $PRM_FILES + - python3 scripts/prepare_combined_format_inputs.py + - if [ $LEVEL_SCALING != "1.0" ];then - *apply-testv-scaling - fi -- GitLab From c1781082bdb607eb3b887167229c5b1f1cbd678b Mon Sep 17 00:00:00 2001 From: Tapani Pihlajakuja Date: Mon, 24 Feb 2025 08:35:30 +0000 Subject: [PATCH 0231/1221] Update 2 files - /.gitlab/issue_templates/float-update-porting.md - /.gitlab/merge_request_templates/float-update-porting.md --- .gitlab/issue_templates/float-update-porting.md | 2 -- .gitlab/merge_request_templates/float-update-porting.md | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab/issue_templates/float-update-porting.md b/.gitlab/issue_templates/float-update-porting.md index 84d15a8c8..19bbf7ba8 100644 --- a/.gitlab/issue_templates/float-update-porting.md +++ b/.gitlab/issue_templates/float-update-porting.md @@ -2,7 +2,5 @@ - Original merge request in float repo: -- Branch for float ref update: -- Branch for BASOP update: /label ~Type:FloatUpdatePorting ~Status::ToDo diff --git a/.gitlab/merge_request_templates/float-update-porting.md b/.gitlab/merge_request_templates/float-update-porting.md index 7ffdee333..5b6d90dad 100644 --- a/.gitlab/merge_request_templates/float-update-porting.md +++ b/.gitlab/merge_request_templates/float-update-porting.md @@ -1,6 +1,6 @@ - Link to issue in BASOP repo: -- Link to original issue in float repo: +- Link to original MR in float repo: - Requested reviewers: /label Type:FloatUpdatePorting -- GitLab From e21996d8675465373eb719b2aed585878a2aa0c3 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Feb 2025 11:23:37 +0100 Subject: [PATCH 0232/1221] fix bug in renaming of the codec binaries for use by pytest --- .gitlab-ci.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1ea012c2a..a7f044dad 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,12 +13,20 @@ variables: SHORT_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_basop_encoder.prm" LONG_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_ltv_basop_encoder.prm" TEST_SUITE: "" + # These path variables are used by the pytest calls. + # They can be overwritten in the job templates to e.g. only test encoder or decoder in the chain DUT_ENCODER_PATH: "./IVAS_cod" DUT_DECODER_PATH: "./IVAS_dec" REF_ENCODER_PATH: "./IVAS_cod_ref" REF_DECODER_PATH: "./IVAS_dec_ref" MERGE_TARGET_ENCODER_PATH: "./IVAS_cod_merge_target" MERGE_TARGET_DECODER_PATH: "./IVAS_dec_merge_target" + # These path variables are used for building the binaries + # They should never be overwritten! + REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_ref" + REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_ref" + MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_merge_target" + MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" @@ -159,8 +167,8 @@ stages: - *activate-debug-mode-info-if-set - make clean - make -j - - mv ./IVAS_cod ./$REF_ENCODER_PATH - - mv ./IVAS_dec ./$REF_DECODER_PATH + - mv ./IVAS_cod ./$REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY + - mv ./IVAS_dec ./$REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_rend ./IVAS_rend_ref ### Return to current branch - git restore . @@ -175,8 +183,8 @@ stages: - *activate-debug-mode-info-if-set - make clean - make -j - - mv ./IVAS_cod ./$MERGE_TARGET_ENCODER_PATH - - mv ./IVAS_dec ./$MERGE_TARGET_DECODER_PATH + - mv ./IVAS_cod ./$MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY + - mv ./IVAS_dec ./$MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_rend ./IVAS_rend_merge_target ### Return to current branch - git restore . -- GitLab From 42023f79808d5a4eb3103741cd872ccdc983a9ab Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Mon, 24 Feb 2025 09:14:12 -0500 Subject: [PATCH 0233/1221] possible fix to 1320 --- lib_enc/ivas_td_low_rate_enc.c | 53 ++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index 95762fa29..a39a17d99 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -222,6 +222,10 @@ void encod_gen_2sbfr( LPD_state_HANDLE hLPDmem = st->hLPDmem; +#ifdef FIX_1320_LOWRATE_ACELP + Word16 gcode16; + Word32 Lgcode, Ltmp; +#endif #ifdef MSAN_FIX set16_fx( cn, 0, 2 * L_SUBFR ); /* Target vector in residual domain */ #endif @@ -269,8 +273,12 @@ void encod_gen_2sbfr( // Scale_sig( &hLPDmem->mem_w0, M + 1, sub( add( *Q_new, hLPDmem->e_mem_syn ), Q16 ) ); // M + 1 to sync mem_syn exponent with mem_w0 exponent // hLPDmem->e_mem_syn = sub( Q16, *Q_new ); - find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); +#ifndef FIX_1320_LOWRATE_ACELP + find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); +#else + find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); +#endif /*Scale_sig(h1, L_SUBFR, shift); */ /*Q14-shift */ Copy_Scale_sig( h1, h2, 2 * L_SUBFR, -2 ); Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ @@ -300,8 +308,11 @@ void encod_gen_2sbfr( * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); - +#else + lp_filt_exc_enc_ivas_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); +#endif /* update long-term pitch gain for speech/music classifier */ st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277, gain_pit ) ); // Q14 move16(); @@ -334,14 +345,30 @@ void encod_gen_2sbfr( gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); +#ifndef FIX_1320_LOWRATE_ACELP hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); +#else + Lgcode = L_shl_sat( gain_code, sub( Q_new, 0 ) ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx_sat( Lgcode ); /*Q0*/ + hLPDmem->tilt_code = est_tilt_ivas_fx(exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0); +#endif move16(); /*-----------------------------------------------------------------* * Update memory of the weighting filter *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); +#else + Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add(5, shift ) ); /*Q15+shift*/ + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ +#endif move16(); /*-----------------------------------------------------------------* @@ -349,6 +376,7 @@ void encod_gen_2sbfr( * Save the non-enhanced excitation for FEC_exc *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP FOR( i = 0; i < 2 * L_SUBFR; i++ ) { exc2[i + i_subfr] = mult( gain_pit, exc[i + i_subfr] ); @@ -356,7 +384,20 @@ void encod_gen_2sbfr( exc[i + i_subfr] = add( exc2[i + i_subfr], mult( extract_h( gain_code ), code[i] ) ); move16(); } - +#else + FOR(i = 0; i < 2 * L_SUBFR; i++) + { + /* code in Q9, gain_pit in Q14 */ + exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); + Ltmp = L_mult( gcode16, code[i] ); /* Q10 */ + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */ + Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/ + exc[i + i_subfr] = round_fx_sat( Ltmp ); + move16(); + move16(); + } +#endif /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ @@ -370,9 +411,11 @@ void encod_gen_2sbfr( * Synthesize speech to update mem_syn_flt[]. * Update A(z) filters *-----------------------------------------------------------------*/ - +#ifndef FIX_1320_LOWRATE_ACELP E_UTIL_synthesis( 0, p_Aq, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1, M ); - +#else + Syn_filt_s(1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); +#endif p_Aw += 2 * ( M + 1 ); p_Aq += 2 * ( M + 1 ); -- GitLab From 7de3bc969f7709963211055a4be0df334663f3b5 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Mon, 24 Feb 2025 09:38:14 -0500 Subject: [PATCH 0234/1221] small correction to the fix --- lib_com/options.h | 2 ++ lib_enc/ivas_td_low_rate_enc.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 0c8105d8c..8204162b7 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -164,4 +164,6 @@ #define FIX_ISSUE_1247 #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_1285_DECODER_CRASH + +#define FIX_1320_LOWRATE_ACELP #endif diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index a39a17d99..e29810db0 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -302,8 +302,11 @@ void encod_gen_2sbfr( * Gain clipping test to avoid unstable synthesis on frame erasure *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, Q_new ); // Q0 - +#else + clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, sub( Q_new, 1 ) ); // Q0 +#endif /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ @@ -348,7 +351,7 @@ void encod_gen_2sbfr( #ifndef FIX_1320_LOWRATE_ACELP hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); #else - Lgcode = L_shl_sat( gain_code, sub( Q_new, 0 ) ); /* scaled gain_code with Qnew -> Q16*/ + Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_sat( Lgcode ); /*Q0*/ hLPDmem->tilt_code = est_tilt_ivas_fx(exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0); #endif -- GitLab From dc11ee23067a74b0572c2dd331a99640d7c6ca5f Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Mon, 24 Feb 2025 09:55:30 -0500 Subject: [PATCH 0235/1221] fix clang --- lib_enc/ivas_td_low_rate_enc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index e29810db0..d09134951 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -352,8 +352,8 @@ void encod_gen_2sbfr( hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); #else Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx_sat( Lgcode ); /*Q0*/ - hLPDmem->tilt_code = est_tilt_ivas_fx(exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0); + gcode16 = round_fx_sat( Lgcode ); /*Q0*/ + hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); #endif move16(); @@ -365,12 +365,12 @@ void encod_gen_2sbfr( hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); #else Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ - Ltmp = L_shl( Ltmp, add(5, shift ) ); /*Q15+shift*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ #endif move16(); @@ -388,14 +388,14 @@ void encod_gen_2sbfr( move16(); } #else - FOR(i = 0; i < 2 * L_SUBFR; i++) + FOR( i = 0; i < 2 * L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); - Ltmp = L_mult( gcode16, code[i] ); /* Q10 */ - Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */ + Ltmp = L_mult( gcode16, code[i] ); /* Q10 */ + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */ Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */ - Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/ exc[i + i_subfr] = round_fx_sat( Ltmp ); move16(); move16(); @@ -417,7 +417,7 @@ void encod_gen_2sbfr( #ifndef FIX_1320_LOWRATE_ACELP E_UTIL_synthesis( 0, p_Aq, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1, M ); #else - Syn_filt_s(1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); + Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); #endif p_Aw += 2 * ( M + 1 ); p_Aq += 2 * ( M + 1 ); -- GitLab From bbc6fea61ff3becd414c2abc783a4818d662f7b2 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 13 Feb 2025 14:02:03 -0500 Subject: [PATCH 0236/1221] fixes to overflow in preprocessing --- lib_com/options.h | 1 + lib_enc/ivas_stereo_classifier.c | 4 ++++ lib_enc/speech_music_classif_fx.c | 11 +++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 974237f4c..2d359665c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -168,4 +168,5 @@ #define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ #define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* FhG: Minor WMOPS tuning, nonbe */ #define FIX_1320_LOWRATE_ACELP +#define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ #endif diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index c84fd73f1..4913f2545 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -1647,7 +1647,11 @@ static void edge_detect_fx( } } +#ifndef FIX_1297_OVERFLOW *edge_str = extract_l( L_shr( edge_min, 10 ) ); // Q15 +#else + *edge_str = extract_h( L_shl_sat( edge_min, 16 - 10 ) ); // Q15 +#endif move16(); *edge_type = et; // Q0 move16(); diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 32b521ef4..295cff8a1 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2303,14 +2303,21 @@ Word16 ivas_smc_gmm_fx( *high_lpn_flag = 1; move32(); } - +#ifndef FIX_1297_OVERFLOW hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 11 ) ); // Q7 move16(); hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 11 ) ); // Q7 move16(); hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q7 move16(); - +#else + hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 + move16(); + hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 + move16(); + hSpMusClas->lpn_fx = extract_h( L_shl_sat( lpn_fx, 16 - 11 ) ); // Q7 + move16(); +#endif /* determine HQ Generic speech class */ IF( st->hHQ_core != NULL ) { -- GitLab From 89812809bebc8e1dbd5c87502203ff08e13b797d Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 13 Feb 2025 15:27:40 -0500 Subject: [PATCH 0237/1221] fix for possible assert in guas_enc (1298) --- lib_com/options.h | 1 + lib_enc/gaus_enc_fx.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 2d359665c..e7c3f2ce5 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -169,4 +169,5 @@ #define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* FhG: Minor WMOPS tuning, nonbe */ #define FIX_1320_LOWRATE_ACELP #define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ +#define FIX_1298 /* VA: fix possible assert in gaus_enc */ #endif diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index a9add7ea8..a7d60642b 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -980,9 +980,13 @@ void gauss2v_ivas_fx( /* eneri = round_fx(ener[i]) + round_fx(ener[j]) + 2*round_fx(dotprod) */ /* Use ScalingShift to stay aligned with ener[] */ eneri = L_shl( dotprod, 1 ); /* One left shift added for factor of 2 */ +#ifndef FIX_1298 eneri = L_add( ener[i], eneri ); eneri = L_add( ener[j], eneri ); /* Q31 */ - +#else + eneri = L_add_sat( ener[i], eneri ); + eneri = L_add_sat( ener[j], eneri ); /* Q31 */ +#endif lo1 = L_Extract_lc( cor32, &hi1 ); cor2 = Sad_32( 0, hi1, lo1 ); /* Square + Add */ -- GitLab From 20387d7dd12d252d2611f807d9534887654ffc4a Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Fri, 14 Feb 2025 13:49:39 -0500 Subject: [PATCH 0238/1221] possible modification to improve #1300 --- lib_com/options.h | 1 + lib_enc/ivas_stereo_ica_enc.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index e7c3f2ce5..2788649c8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,4 +170,5 @@ #define FIX_1320_LOWRATE_ACELP #define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ +#define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ #endif diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 9d06a5523..4c77f86af 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1965,6 +1965,8 @@ void stereo_tca_enc_fx( Word16 temp_exp, tempF_16fx; Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */ + +#ifndef FIX_1300_ICA_SHIFT_QUANT_IMPROV IF( temp_exp < 0 ) { scalar_value = shl( scalar_value, sub( temp_exp, Q3 ) ); // Q12 @@ -1976,6 +1978,11 @@ void stereo_tca_enc_fx( hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, shl( 1, sub( 14, temp_exp ) ), ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ move16(); } +#else + scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ +#endif + tempF_fx = tempF_16fx; move32(); } -- GitLab From 5dc906cb2e73c390ae3ad6c41605b0acf9612ef1 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Fri, 14 Feb 2025 14:55:44 -0500 Subject: [PATCH 0239/1221] fix clang --- lib_enc/ivas_stereo_ica_enc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 4c77f86af..5b79f416a 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1979,8 +1979,8 @@ void stereo_tca_enc_fx( move16(); } #else - scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ + scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ #endif tempF_fx = tempF_16fx; -- GitLab From 3064dbd12837fdec68c7b8617f01c8a59ef10b9b Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Fri, 14 Feb 2025 15:09:06 -0500 Subject: [PATCH 0240/1221] correction of constants --- lib_com/options.h | 1 + lib_enc/ivas_stereo_td_analysis.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 2788649c8..288145122 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -171,4 +171,5 @@ #define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ +#define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ #endif diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index 49ac895ef..a938083e6 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -74,9 +74,13 @@ #define RATIO_MAX 1.5f /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ +#ifdef FIX_1301_CORRECT_TD_CNST +#define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ +#else #define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ - +#endif #define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ #define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ #define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ -- GitLab From 6237fb9cb1fee12e6d7a1d9bbe9ee8d9d740aa62 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Fri, 14 Feb 2025 15:12:22 -0500 Subject: [PATCH 0241/1221] fix clang format --- lib_enc/ivas_stereo_td_analysis.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index a938083e6..4e8b51c11 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -78,8 +78,8 @@ #define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ #else -#define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ #endif #define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ #define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ -- GitLab From cae6da2568bee735bbc6347ca81c5c1a4d677d2e Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Mon, 17 Feb 2025 15:40:20 -0500 Subject: [PATCH 0242/1221] more correction on constant error, plus one potential saturation was missing --- lib_enc/ivas_stereo_td_analysis.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index 4e8b51c11..f80c74c69 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -262,7 +262,11 @@ Word16 stereo_tdm_ener_analysis_fx( rms_thd_fx = L_shr( rms_thd_fx, 2 ); /*Q16*/ /*rms_thd_fx *= 0.25f*/ test(); test(); +#ifdef FIX_1301_CORRECT_TD_CNST + IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 4915200 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) +#else IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 75 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) +#endif { rms_thd_fx = L_shr( rms_thd_fx, 5 ); /* Q16*/ /*rms_thd_fx *= 0.03125f*/ } @@ -336,6 +340,10 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } +#ifdef FIX_1301_CORRECT_TD_CNST + rms_L_fx = L_shl( rms_L_fx, sub( Q16, q_rms_L ) ); /* All the following energy comparison are done in Q16 */ + rms_R_fx = L_shl( rms_R_fx, sub( Q16, q_rms_R ) ); +#endif test(); IF( EQ_16( hStereoTD->prev_fr_LRTD_TD_dec, 1 ) && side_can_change == 0 ) { @@ -434,7 +442,11 @@ Word16 stereo_tdm_ener_analysis_fx( ELSE { /*ratio_L = ( 1.0f - cosf( EVS_PI * ratio_L / 2.0f ) ) / 2.0f;*/ +#ifdef FIX_1301_CORRECT_TD_CNST + ratio_L_fx = L_deposit_h( sub_sat( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) +#else ratio_L_fx = L_deposit_h( sub( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) +#endif } test(); @@ -482,7 +494,7 @@ Word16 stereo_tdm_ener_analysis_fx( { test(); test(); - IF( GE_32( hCPE->element_brate, IVAS_48k ) && sts[0]->hVAD->hangover_cnt != 0 && LT_32( L_max( hStereoTD->tdm_lt_rms_L_fx, hStereoTD->tdm_lt_rms_R_fx ), 33554432 /* 512.0f */ ) ) + IF( GE_32( hCPE->element_brate, IVAS_48k ) && sts[0]->hVAD->hangover_cnt != 0 && LT_32( L_max( hStereoTD->tdm_lt_rms_L_fx, hStereoTD->tdm_lt_rms_R_fx ), 33554432 /* 512.0f in Q16*/ ) ) { ratio_L_fx = check_bounds_l( ratio_L_fx, 644245094 /*0.3f in Q31*/, 1503238554 /*0.7f in Q31*/ ); /* Q31 */ } @@ -491,7 +503,7 @@ Word16 stereo_tdm_ener_analysis_fx( test(); test(); test(); - IF( ( GT_32( hCPE->hStereoTCA->instTargetGain_fx, 644245094 /*1.2f in Q29*/ ) || GT_32( hCPE->hStereoTCA->targetGain_fx, ONE_IN_Q29 ) ) && LT_32( ratio_L_fx, 858993459 /*0.4f*/ ) ) + IF( ( GT_32( hCPE->hStereoTCA->instTargetGain_fx, 644245094 /*1.2f in Q29*/ ) || GT_32( hCPE->hStereoTCA->targetGain_fx, ONE_IN_Q29 ) ) && LT_32( ratio_L_fx, 858993459 /*0.4f in Q31*/ ) ) { ratio_L_fx = 858993459; /*0.4f in Q31*/ move32(); @@ -569,7 +581,7 @@ Word16 stereo_tdm_ener_analysis_fx( } } - IF( LT_16( sub( sts[1]->lp_speech_fx, sts[1]->lp_noise_fx ), 12800 /*50.0f*/ ) ) /* likely presence of noisy content */ + IF( LT_16( sub( sts[1]->lp_speech_fx, sts[1]->lp_noise_fx ), 12800 /*50.0f in Q8*/ ) ) /* likely presence of noisy content */ { /* pointing in the right direction, inverse it else do nothing */ test(); @@ -1063,7 +1075,11 @@ static void NOOP_decision_fx( } ELSE { - if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) +#ifdef FIX_1301_CORRECT_TD_CNST + if ( LT_32( sts[0]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) ) +#else + if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) +#endif { tdm_NOOP_switch_flag = 1; move16(); -- GitLab From 7b46b2feacdf05d77fe95c1dae2a336ab3b0c294 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Mon, 17 Feb 2025 15:42:59 -0500 Subject: [PATCH 0243/1221] fix clang --- lib_enc/ivas_stereo_td_analysis.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index f80c74c69..5bc62bc8b 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -341,7 +341,7 @@ Word16 stereo_tdm_ener_analysis_fx( } #ifdef FIX_1301_CORRECT_TD_CNST - rms_L_fx = L_shl( rms_L_fx, sub( Q16, q_rms_L ) ); /* All the following energy comparison are done in Q16 */ + rms_L_fx = L_shl( rms_L_fx, sub( Q16, q_rms_L ) ); /* All the following energy comparison are done in Q16 */ rms_R_fx = L_shl( rms_R_fx, sub( Q16, q_rms_R ) ); #endif test(); @@ -655,7 +655,7 @@ Word16 stereo_tdm_ener_analysis_fx( #ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 #else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 + ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 #endif move32(); @@ -666,7 +666,7 @@ Word16 stereo_tdm_ener_analysis_fx( #ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 #else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 + ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 #endif move32(); } @@ -1076,9 +1076,9 @@ static void NOOP_decision_fx( ELSE { #ifdef FIX_1301_CORRECT_TD_CNST - if ( LT_32( sts[0]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) ) + if ( LT_32( sts[0]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) ) #else - if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) + if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) #endif { tdm_NOOP_switch_flag = 1; -- GitLab From d4452776da4bc08bbf1c56271369f398d11fb963 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Feb 2025 10:41:19 +0000 Subject: [PATCH 0244/1221] undo some unintended changes - deactivate inDev-defines --- lib_com/options.h | 4 ++-- lib_rend/ivas_dirac_output_synthesis_dec.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index be20cf739..788eb80b9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,7 +172,7 @@ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ -#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ -#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ +//#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ +//#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ #endif diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index b55a50afb..3556575fa 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -959,7 +959,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ - } + IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) { @@ -986,6 +986,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); move16(); } + } #else FOR( ; k < num_freq_bands; k++ ) { @@ -1042,8 +1043,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ - } - IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) { IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) @@ -1069,6 +1068,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); move16(); } + } #endif -- GitLab From bad5dd7ac52dbe6723eae97978a6f12d9e75757f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Feb 2025 11:44:59 +0100 Subject: [PATCH 0245/1221] applied clang format patch --- lib_rend/ivas_dirac_output_synthesis_dec.c | 74 +++++++++++----------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 3556575fa..5ac5b676b 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -959,33 +959,33 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ - - IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) - { - IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + + IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ + IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + move16(); + } + ELSE + { + sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; + move16(); + } + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ move32(); - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); - move16(); } ELSE { - sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); move16(); } - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ - move32(); - } - ELSE - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ - move32(); - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); - move16(); - } } #else FOR( ; k < num_freq_bands; k++ ) @@ -1043,31 +1043,31 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/ sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/ - IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) - { - IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 ) { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ + IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); + move16(); + } + ELSE + { + sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; + move16(); + } + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ move32(); - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); - move16(); } ELSE { - sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/ - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ + move32(); + Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); move16(); } - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/ - move32(); - } - ELSE - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/ - move32(); - Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp ); - move16(); - } } #endif -- GitLab From 5fd61388a3eef1e1de4b9e97f0f2b3fe1e02a017 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 25 Feb 2025 12:01:48 +0100 Subject: [PATCH 0246/1221] fixed builderror --- lib_rend/ivas_dirac_output_synthesis_dec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 5ac5b676b..1bbecc555 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1248,8 +1248,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ } -#endif - #endif pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" );*/ -- GitLab From f854c6a7ad1d22159d570a7a0761bae6461a2c41 Mon Sep 17 00:00:00 2001 From: ber Date: Tue, 25 Feb 2025 13:06:40 +0100 Subject: [PATCH 0247/1221] activate inDev macros --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 788eb80b9..be20cf739 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,7 +172,7 @@ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ -//#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ -//#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ +#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ +#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ #endif -- GitLab From 162f6c3568c2ed9c7990b0445864f2cdc7b7ca81 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 25 Feb 2025 13:57:21 +0100 Subject: [PATCH 0248/1221] update copyright header to 2025 --- LICENSE.md | 2 +- apps/decoder.c | 2 +- apps/encoder.c | 2 +- apps/renderer.c | 2 +- lib_com/basop32.c | 2 +- lib_com/basop32.h | 2 +- lib_com/basop_com_lpc.c | 2 +- lib_com/basop_lsf_tools.c | 2 +- lib_com/basop_proto_func.h | 2 +- lib_com/basop_settings.h | 2 +- lib_com/basop_tcx_utils.c | 2 +- lib_com/basop_util.c | 2 +- lib_com/basop_util.h | 2 +- lib_com/bitstream.c | 2 +- lib_com/bitstream_fx.c | 2 +- lib_com/cldfb.c | 2 +- lib_com/cng_exc.c | 2 +- lib_com/cnst.h | 2 +- lib_com/common_api_types.h | 2 +- lib_com/core_com_config.c | 2 +- lib_com/deemph.c | 2 +- lib_com/delay_comp.c | 2 +- lib_com/disclaimer.c | 2 +- lib_com/enh40.c | 2 +- lib_com/enh40.h | 2 +- lib_com/enr_1_az.c | 2 +- lib_com/env_adj.c | 2 +- lib_com/env_stab.c | 2 +- lib_com/env_stab_trans.c | 2 +- lib_com/fft.c | 2 +- lib_com/fft_cldfb_fx.c | 2 +- lib_com/fft_fx.c | 2 +- lib_com/fft_rel.c | 2 +- lib_com/fill_spectrum.c | 2 +- lib_com/findpulse.c | 2 +- lib_com/frame_ener.c | 2 +- lib_com/frame_ener_fx.c | 2 +- lib_com/get_gain.c | 2 +- lib_com/get_gain_fx.c | 2 +- lib_com/gs_gains.c | 2 +- lib_com/gs_gains_fx.c | 2 +- lib_com/gs_preech.c | 2 +- lib_com/gs_preech_fx.c | 2 +- lib_com/hp50.c | 2 +- lib_com/hp50_fx.c | 2 +- lib_com/hq2_bit_alloc_fx.c | 2 +- lib_com/hq2_core_com.c | 2 +- lib_com/hq2_core_com_fx.c | 2 +- lib_com/hq2_noise_inject_fx.c | 2 +- lib_com/hq_conf.c | 2 +- lib_com/hq_tools_fx.c | 2 +- lib_com/ifft_rel.c | 2 +- lib_com/int_lsp.c | 2 +- lib_com/interleave_spectrum.c | 2 +- lib_com/interpol.c | 2 +- lib_com/isf_dec_amr_wb_fx.c | 2 +- lib_com/ivas_agc_com_fx.c | 2 +- lib_com/ivas_arith.c | 2 +- lib_com/ivas_avq_pos_reorder_com.c | 2 +- lib_com/ivas_cnst.h | 2 +- lib_com/ivas_cov_smooth.c | 2 +- lib_com/ivas_dirac_com.c | 2 +- lib_com/ivas_entropy_coder_common.c | 2 +- lib_com/ivas_error.h | 2 +- lib_com/ivas_error_utils.h | 2 +- lib_com/ivas_fb_mixer.c | 2 +- lib_com/ivas_filters.c | 2 +- lib_com/ivas_ism_com.c | 2 +- lib_com/ivas_lfe_com.c | 2 +- lib_com/ivas_masa_com.c | 2 +- lib_com/ivas_mc_com.c | 2 +- lib_com/ivas_mc_param_com.c | 2 +- lib_com/ivas_mcmasa_com.c | 2 +- lib_com/ivas_mct_com.c | 2 +- lib_com/ivas_mdct_core_com.c | 2 +- lib_com/ivas_mdct_imdct_fx.c | 2 +- lib_com/ivas_mdft_imdft.c | 2 +- lib_com/ivas_omasa_com.c | 2 +- lib_com/ivas_pca_tools.c | 2 +- lib_com/ivas_prot.h | 2 +- lib_com/ivas_prot_fx.h | 2 +- lib_com/ivas_qmetadata_com.c | 2 +- lib_com/ivas_qspherical_com.c | 2 +- lib_com/ivas_rom_com.c | 2 +- lib_com/ivas_rom_com.h | 2 +- lib_com/ivas_rom_com_fx.c | 2 +- lib_com/ivas_rom_com_fx.h | 2 +- lib_com/ivas_sba_config.c | 2 +- lib_com/ivas_sns_com_fx.c | 2 +- lib_com/ivas_spar_com.c | 2 +- lib_com/ivas_spar_com_quant_util.c | 2 +- lib_com/ivas_stat_com.h | 2 +- lib_com/ivas_stereo_dft_com.c | 2 +- lib_com/ivas_stereo_eclvq_com_fx.c | 2 +- lib_com/ivas_stereo_ica_com_fx.c | 2 +- lib_com/ivas_stereo_mdct_bands_com.c | 2 +- lib_com/ivas_stereo_mdct_stereo_com.c | 2 +- lib_com/ivas_stereo_psychlpc_com.c | 2 +- lib_com/ivas_stereo_td_bit_alloc.c | 2 +- lib_com/ivas_tools.c | 2 +- lib_com/ivas_transient_det.c | 2 +- lib_com/lag_wind.c | 2 +- lib_com/lerp.c | 2 +- lib_com/limit_t0.c | 2 +- lib_com/logqnorm_fx.c | 2 +- lib_com/longarith.c | 2 +- lib_com/lpc_tools_fx.c | 2 +- lib_com/lsf_tools_fx.c | 2 +- lib_com/mime.h | 2 +- lib_com/modif_fs.c | 2 +- lib_com/move.h | 2 +- lib_com/mslvq_com.c | 2 +- lib_com/mslvq_com_fx.c | 2 +- lib_com/nelp_fx.c | 2 +- lib_com/options.h | 2 +- lib_com/ppp_fx.c | 2 +- lib_com/preemph.c | 2 +- lib_com/prot.h | 2 +- lib_com/prot_fx.h | 2 +- lib_com/reordvct_fx.c | 2 +- lib_com/rom_basop_util.c | 2 +- lib_com/rom_basop_util.h | 2 +- lib_com/rom_com.c | 2 +- lib_com/rom_com.h | 2 +- lib_com/rom_com_fx.c | 2 +- lib_com/rom_com_fx.h | 2 +- lib_com/scale_mem_fx.c | 2 +- lib_com/stat_com.h | 2 +- lib_com/stl.h | 2 +- lib_com/swb_bwe_com_fx.c | 2 +- lib_com/swb_bwe_com_lr_fx.c | 2 +- lib_com/swb_tbe_com.c | 2 +- lib_com/tcx_mdct_window.c | 2 +- lib_com/tools.c | 2 +- lib_com/tools_fx.c | 2 +- lib_com/typedef.h | 2 +- lib_com/wtda.c | 2 +- lib_debug/debug.c | 2 +- lib_debug/debug.h | 2 +- lib_debug/sba_debug.c | 2 +- lib_debug/sba_debug.h | 2 +- lib_debug/snr.c | 2 +- lib_dec/ACcontextMapping_dec.c | 2 +- lib_dec/FEC.c | 2 +- lib_dec/FEC_HQ_core.c | 2 +- lib_dec/FEC_HQ_phase_ecu.c | 2 +- lib_dec/FEC_adapt_codebook.c | 2 +- lib_dec/FEC_clas_estim.c | 2 +- lib_dec/FEC_lsf_estim.c | 2 +- lib_dec/FEC_pitch_estim.c | 2 +- lib_dec/FEC_scale_syn.c | 2 +- lib_dec/LD_music_post_filter.c | 2 +- lib_dec/TonalComponentDetection.c | 2 +- lib_dec/acelp_core_dec.c | 2 +- lib_dec/acelp_core_dec_ivas_fx.c | 2 +- lib_dec/acelp_core_switch_dec.c | 2 +- lib_dec/amr_wb_dec.c | 2 +- lib_dec/ari_dec.c | 2 +- lib_dec/ari_hm_dec.c | 2 +- lib_dec/arith_coder_dec.c | 2 +- lib_dec/avq_dec.c | 2 +- lib_dec/bass_psfilter.c | 2 +- lib_dec/cng_dec.c | 2 +- lib_dec/core_dec_init.c | 2 +- lib_dec/core_dec_reconf.c | 2 +- lib_dec/core_dec_switch.c | 2 +- lib_dec/core_switching_dec.c | 2 +- lib_dec/d_gain2p.c | 2 +- lib_dec/dec2t32.c | 2 +- lib_dec/dec4t64.c | 2 +- lib_dec/dec_LPD.c | 2 +- lib_dec/dec_ace.c | 2 +- lib_dec/dec_acelp.c | 2 +- lib_dec/dec_acelp_tcx_main.c | 2 +- lib_dec/dec_amr_wb.c | 2 +- lib_dec/dec_gen_voic.c | 2 +- lib_dec/dec_higher_acelp.c | 2 +- lib_dec/dec_nelp.c | 2 +- lib_dec/dec_pit_exc.c | 2 +- lib_dec/dec_post.c | 2 +- lib_dec/dec_ppp.c | 2 +- lib_dec/dec_prm.c | 2 +- lib_dec/dec_tcx.c | 2 +- lib_dec/dec_tran.c | 2 +- lib_dec/dec_uv.c | 2 +- lib_dec/decision_matrix_dec.c | 2 +- lib_dec/dlpc_avq.c | 2 +- lib_dec/dlpc_stoch.c | 2 +- lib_dec/er_dec_acelp.c | 2 +- lib_dec/er_dec_tcx.c | 2 +- lib_dec/er_scale_syn.c | 2 +- lib_dec/er_sync_exc.c | 2 +- lib_dec/er_util.c | 2 +- lib_dec/evs_dec.c | 2 +- lib_dec/fd_cng_dec.c | 2 +- lib_dec/gain_dec.c | 2 +- lib_dec/gaus_dec.c | 2 +- lib_dec/gs_dec.c | 2 +- lib_dec/gs_dec_amr_wb.c | 2 +- lib_dec/hdecnrm.c | 2 +- lib_dec/hf_synth.c | 2 +- lib_dec/hq_classifier_dec.c | 2 +- lib_dec/hq_conf_fec.c | 2 +- lib_dec/hq_core_dec.c | 2 +- lib_dec/hq_env_dec.c | 2 +- lib_dec/hq_hr_dec.c | 2 +- lib_dec/hq_lr_dec.c | 2 +- lib_dec/igf_dec.c | 2 +- lib_dec/igf_scf_dec.c | 2 +- lib_dec/init_dec.c | 2 +- lib_dec/inov_dec.c | 2 +- lib_dec/ivas_agc_dec.c | 2 +- lib_dec/ivas_agc_dec_fx.c | 2 +- lib_dec/ivas_binRenderer_internal.c | 2 +- lib_dec/ivas_core_dec.c | 2 +- lib_dec/ivas_corecoder_dec_reconfig.c | 2 +- lib_dec/ivas_cpe_dec.c | 2 +- lib_dec/ivas_cpe_dec_fx.c | 2 +- lib_dec/ivas_dec.c | 2 +- lib_dec/ivas_decision_matrix_dec.c | 2 +- lib_dec/ivas_dirac_dec.c | 2 +- lib_dec/ivas_dirac_output_synthesis_cov.c | 2 +- lib_dec/ivas_entropy_decoder.c | 2 +- lib_dec/ivas_init_dec.c | 2 +- lib_dec/ivas_ism_dec.c | 2 +- lib_dec/ivas_ism_dtx_dec.c | 2 +- lib_dec/ivas_ism_metadata_dec.c | 2 +- lib_dec/ivas_ism_param_dec.c | 2 +- lib_dec/ivas_ism_renderer.c | 2 +- lib_dec/ivas_jbm_dec.c | 2 +- lib_dec/ivas_lfe_dec.c | 2 +- lib_dec/ivas_lfe_dec_fx.c | 2 +- lib_dec/ivas_lfe_plc.c | 2 +- lib_dec/ivas_lfe_plc_fx.c | 2 +- lib_dec/ivas_ls_custom_dec.c | 2 +- lib_dec/ivas_masa_dec.c | 2 +- lib_dec/ivas_mc_param_dec.c | 2 +- lib_dec/ivas_mc_paramupmix_dec.c | 2 +- lib_dec/ivas_mcmasa_dec.c | 2 +- lib_dec/ivas_mct_core_dec.c | 2 +- lib_dec/ivas_mct_dec.c | 2 +- lib_dec/ivas_mct_dec_mct.c | 2 +- lib_dec/ivas_mct_dec_mct_fx.c | 2 +- lib_dec/ivas_mdct_core_dec.c | 2 +- lib_dec/ivas_mono_dmx_renderer.c | 2 +- lib_dec/ivas_objectRenderer_internal.c | 2 +- lib_dec/ivas_omasa_dec.c | 2 +- lib_dec/ivas_osba_dec.c | 2 +- lib_dec/ivas_out_setup_conversion.c | 2 +- lib_dec/ivas_output_config.c | 2 +- lib_dec/ivas_pca_dec.c | 2 +- lib_dec/ivas_pca_dec_fx.c | 2 +- lib_dec/ivas_post_proc.c | 2 +- lib_dec/ivas_qmetadata_dec.c | 2 +- lib_dec/ivas_qspherical_dec.c | 2 +- lib_dec/ivas_range_uni_dec.c | 2 +- lib_dec/ivas_rom_dec.c | 2 +- lib_dec/ivas_rom_dec.h | 2 +- lib_dec/ivas_sba_dec.c | 2 +- lib_dec/ivas_sba_dirac_stereo_dec.c | 2 +- lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 2 +- lib_dec/ivas_sba_rendering_internal.c | 2 +- lib_dec/ivas_sce_dec.c | 2 +- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_sns_dec.c | 2 +- lib_dec/ivas_sns_dec_fx.c | 2 +- lib_dec/ivas_spar_decoder.c | 2 +- lib_dec/ivas_spar_md_dec.c | 2 +- lib_dec/ivas_stat_dec.h | 2 +- lib_dec/ivas_stereo_adapt_GR_dec.c | 2 +- lib_dec/ivas_stereo_cng_dec.c | 2 +- lib_dec/ivas_stereo_dft_dec.c | 2 +- lib_dec/ivas_stereo_dft_dec_dmx.c | 2 +- lib_dec/ivas_stereo_dft_dec_fx.c | 2 +- lib_dec/ivas_stereo_dft_plc.c | 2 +- lib_dec/ivas_stereo_dft_plc_fx.c | 2 +- lib_dec/ivas_stereo_eclvq_dec.c | 2 +- lib_dec/ivas_stereo_esf_dec.c | 2 +- lib_dec/ivas_stereo_ica_dec.c | 2 +- lib_dec/ivas_stereo_icbwe_dec.c | 2 +- lib_dec/ivas_stereo_mdct_core_dec.c | 2 +- lib_dec/ivas_stereo_mdct_core_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec.c | 2 +- lib_dec/ivas_stereo_switching_dec.c | 2 +- lib_dec/ivas_stereo_td_dec.c | 2 +- lib_dec/ivas_svd_dec.c | 2 +- lib_dec/ivas_tcx_core_dec.c | 2 +- lib_dec/ivas_td_low_rate_dec.c | 2 +- lib_dec/jbm_jb4_circularbuffer.c | 2 +- lib_dec/jbm_jb4_circularbuffer.h | 2 +- lib_dec/jbm_jb4_inputbuffer.c | 2 +- lib_dec/jbm_jb4_inputbuffer.h | 2 +- lib_dec/jbm_jb4_jmf.c | 2 +- lib_dec/jbm_jb4_jmf.h | 2 +- lib_dec/jbm_jb4sb.c | 2 +- lib_dec/jbm_jb4sb.h | 2 +- lib_dec/jbm_pcmdsp_apa.c | 2 +- lib_dec/jbm_pcmdsp_apa.h | 2 +- lib_dec/jbm_pcmdsp_fifo.c | 2 +- lib_dec/jbm_pcmdsp_fifo.h | 2 +- lib_dec/jbm_pcmdsp_similarityestimation.c | 2 +- lib_dec/jbm_pcmdsp_similarityestimation.h | 2 +- lib_dec/jbm_pcmdsp_window.c | 2 +- lib_dec/jbm_pcmdsp_window.h | 2 +- lib_dec/lead_deindexing.c | 2 +- lib_dec/lib_dec.c | 2 +- lib_dec/lib_dec.h | 2 +- lib_dec/lib_dec_fx.c | 2 +- lib_dec/lp_exc_d.c | 2 +- lib_dec/lsf_dec.c | 2 +- lib_dec/lsf_msvq_ma_dec.c | 2 +- lib_dec/nelp_dec.c | 2 +- lib_dec/peak_vq_dec.c | 2 +- lib_dec/pit_dec.c | 2 +- lib_dec/pitch_extr.c | 2 +- lib_dec/post_dec.c | 2 +- lib_dec/ppp_dec.c | 2 +- lib_dec/pvq_core_dec.c | 2 +- lib_dec/pvq_decode.c | 2 +- lib_dec/range_dec.c | 2 +- lib_dec/re8_dec.c | 2 +- lib_dec/rom_dec.c | 2 +- lib_dec/rom_dec.h | 2 +- lib_dec/rst_dec.c | 2 +- lib_dec/stat_dec.h | 2 +- lib_dec/stat_noise_uv_dec.c | 2 +- lib_dec/swb_bwe_dec.c | 2 +- lib_dec/swb_bwe_dec_hr.c | 2 +- lib_dec/swb_bwe_dec_lr.c | 2 +- lib_dec/swb_tbe_dec.c | 2 +- lib_dec/syn_outp.c | 2 +- lib_dec/tcq_core_dec.c | 2 +- lib_dec/tcx_utils_dec.c | 2 +- lib_dec/tns_base_dec.c | 2 +- lib_dec/tonalMDCTconcealment.c | 2 +- lib_dec/transition_dec.c | 2 +- lib_dec/updt_dec.c | 2 +- lib_dec/vlpc_1st_dec.c | 2 +- lib_dec/vlpc_2st_dec.c | 2 +- lib_dec/voiced_dec.c | 2 +- lib_dec/waveadjust_fec_dec.c | 2 +- lib_enc/ari_enc.c | 2 +- lib_enc/ari_hm_enc.c | 2 +- lib_enc/arith_coder_enc.c | 2 +- lib_enc/avq_cod.c | 2 +- lib_enc/bass_psfilter_enc.c | 2 +- lib_enc/bw_detect.c | 2 +- lib_enc/cng_enc.c | 2 +- lib_enc/cod2t32.c | 2 +- lib_enc/cod4t64.c | 2 +- lib_enc/cod4t64_fast.c | 2 +- lib_enc/cod_ace.c | 2 +- lib_enc/cod_tcx.c | 2 +- lib_enc/cod_uv.c | 2 +- lib_enc/comvad_decision.c | 2 +- lib_enc/cor_shif.c | 2 +- lib_enc/core_enc_2div.c | 2 +- lib_enc/core_enc_init.c | 2 +- lib_enc/core_enc_ol.c | 2 +- lib_enc/core_enc_reconf.c | 2 +- lib_enc/core_enc_switch.c | 2 +- lib_enc/core_enc_updt.c | 2 +- lib_enc/core_switching_enc.c | 2 +- lib_enc/corr_xh.c | 2 +- lib_enc/decision_matrix_enc.c | 2 +- lib_enc/detect_transient.c | 2 +- lib_enc/detect_transient_fx.c | 2 +- lib_enc/diffcod.c | 2 +- lib_enc/dtx.c | 2 +- lib_enc/enc_acelp.c | 2 +- lib_enc/enc_acelp_tcx_main.c | 2 +- lib_enc/enc_acelpx.c | 2 +- lib_enc/enc_amr_wb.c | 2 +- lib_enc/enc_gain.c | 2 +- lib_enc/enc_gen_voic.c | 2 +- lib_enc/enc_prm.c | 2 +- lib_enc/fd_cng_enc.c | 2 +- lib_enc/find_tilt.c | 2 +- lib_enc/find_uv.c | 2 +- lib_enc/find_wsp.c | 2 +- lib_enc/frame_spec_dif_cor_rate.c | 2 +- lib_enc/gain_enc.c | 2 +- lib_enc/gp_clip_fx.c | 2 +- lib_enc/gs_enc.c | 2 +- lib_enc/guided_plc_enc.c | 2 +- lib_enc/hf_cod_amrwb.c | 2 +- lib_enc/hq_classifier_enc.c | 2 +- lib_enc/hq_core_enc.c | 2 +- lib_enc/hq_env_enc.c | 2 +- lib_enc/hq_hr_enc.c | 2 +- lib_enc/hq_lr_enc.c | 2 +- lib_enc/hvq_enc.c | 2 +- lib_enc/igf_enc.c | 2 +- lib_enc/igf_scf_enc.c | 2 +- lib_enc/init_enc.c | 2 +- lib_enc/inov_enc.c | 2 +- lib_enc/isf_enc_amr_wb.c | 2 +- lib_enc/isf_enc_amr_wb_fx.c | 2 +- lib_enc/ivas_agc_enc.c | 2 +- lib_enc/ivas_core_enc.c | 2 +- lib_enc/ivas_core_pre_proc.c | 2 +- lib_enc/ivas_core_pre_proc_front.c | 2 +- lib_enc/ivas_corecoder_enc_reconfig.c | 2 +- lib_enc/ivas_cpe_enc.c | 2 +- lib_enc/ivas_decision_matrix_enc.c | 2 +- lib_enc/ivas_dirac_enc.c | 2 +- lib_enc/ivas_enc.c | 2 +- lib_enc/ivas_enc_cov_handler.c | 2 +- lib_enc/ivas_entropy_coder.c | 2 +- lib_enc/ivas_front_vad.c | 2 +- lib_enc/ivas_init_enc.c | 2 +- lib_enc/ivas_ism_dtx_enc.c | 2 +- lib_enc/ivas_ism_enc.c | 2 +- lib_enc/ivas_ism_metadata_enc.c | 2 +- lib_enc/ivas_ism_param_enc.c | 2 +- lib_enc/ivas_lfe_enc.c | 2 +- lib_enc/ivas_masa_enc.c | 2 +- lib_enc/ivas_mc_param_enc.c | 2 +- lib_enc/ivas_mc_paramupmix_enc.c | 2 +- lib_enc/ivas_mcmasa_enc.c | 2 +- lib_enc/ivas_mct_core_enc.c | 2 +- lib_enc/ivas_mct_enc.c | 2 +- lib_enc/ivas_mct_enc_mct.c | 2 +- lib_enc/ivas_mdct_core_enc.c | 2 +- lib_enc/ivas_omasa_enc.c | 2 +- lib_enc/ivas_osba_enc.c | 2 +- lib_enc/ivas_pca_enc.c | 2 +- lib_enc/ivas_qmetadata_enc.c | 2 +- lib_enc/ivas_qspherical_enc.c | 2 +- lib_enc/ivas_range_uni_enc.c | 2 +- lib_enc/ivas_rom_enc.h | 2 +- lib_enc/ivas_rom_enc_fx.c | 2 +- lib_enc/ivas_sba_enc.c | 2 +- lib_enc/ivas_sce_enc.c | 2 +- lib_enc/ivas_sns_enc.c | 2 +- lib_enc/ivas_spar_encoder.c | 2 +- lib_enc/ivas_spar_md_enc.c | 2 +- lib_enc/ivas_stat_enc.h | 2 +- lib_enc/ivas_stereo_adapt_GR_enc.c | 2 +- lib_enc/ivas_stereo_classifier.c | 2 +- lib_enc/ivas_stereo_cng_enc.c | 2 +- lib_enc/ivas_stereo_dft_enc.c | 2 +- lib_enc/ivas_stereo_dft_enc_itd.c | 2 +- lib_enc/ivas_stereo_dft_td_itd.c | 2 +- lib_enc/ivas_stereo_dmx_evs.c | 2 +- lib_enc/ivas_stereo_eclvq_enc.c | 2 +- lib_enc/ivas_stereo_ica_enc.c | 2 +- lib_enc/ivas_stereo_icbwe_enc.c | 2 +- lib_enc/ivas_stereo_mdct_core_enc.c | 2 +- lib_enc/ivas_stereo_mdct_igf_enc.c | 2 +- lib_enc/ivas_stereo_mdct_stereo_enc.c | 2 +- lib_enc/ivas_stereo_switching_enc.c | 2 +- lib_enc/ivas_stereo_td_analysis.c | 2 +- lib_enc/ivas_stereo_td_enc.c | 2 +- lib_enc/ivas_tcx_core_enc.c | 2 +- lib_enc/ivas_td_low_rate_enc.c | 2 +- lib_enc/lead_indexing.c | 2 +- lib_enc/lib_enc.c | 2 +- lib_enc/lib_enc.h | 2 +- lib_enc/long_enr.c | 2 +- lib_enc/lp_exc_e.c | 2 +- lib_enc/lsf_enc.c | 2 +- lib_enc/lsf_msvq_ma_enc.c | 2 +- lib_enc/ltd_stable.c | 2 +- lib_enc/mdct_classifier.c | 2 +- lib_enc/mdct_selector.c | 2 +- lib_enc/mslvq_enc.c | 2 +- lib_enc/multi_harm.c | 2 +- lib_enc/nelp_enc.c | 2 +- lib_enc/nelp_enc_fx.c | 2 +- lib_enc/pit_enc.c | 2 +- lib_enc/pitch_ol.c | 2 +- lib_enc/pitch_ol2.c | 2 +- lib_enc/plc_enc_ext.c | 2 +- lib_enc/prot_fx_enc.h | 2 +- lib_enc/rom_enc.c | 2 +- lib_enc/rom_enc.h | 2 +- lib_enc/setmodeindex.c | 2 +- lib_enc/stat_enc.h | 2 +- lib_enc/swb_bwe_enc_lr_fx.c | 2 +- lib_enc/swb_tbe_enc.c | 2 +- lib_rend/ivas_allrad_dec.c | 2 +- lib_rend/ivas_crend.c | 2 +- lib_rend/ivas_dirac_ana.c | 2 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 2 +- lib_rend/ivas_dirac_decorr_dec.c | 2 +- lib_rend/ivas_dirac_onsets_dec.c | 2 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 2 +- lib_rend/ivas_dirac_rend.c | 2 +- lib_rend/ivas_efap.c | 2 +- lib_rend/ivas_hrtf.c | 2 +- lib_rend/ivas_limiter.c | 2 +- lib_rend/ivas_masa_merge.c | 2 +- lib_rend/ivas_mcmasa_ana.c | 2 +- lib_rend/ivas_objectRenderer.c | 2 +- lib_rend/ivas_objectRenderer_hrFilt.c | 2 +- lib_rend/ivas_objectRenderer_mix.c | 2 +- lib_rend/ivas_objectRenderer_sfx.c | 2 +- lib_rend/ivas_objectRenderer_sources.c | 2 +- lib_rend/ivas_objectRenderer_vec.c | 2 +- lib_rend/ivas_omasa_ana.c | 2 +- lib_rend/ivas_orient_trk.c | 2 +- lib_rend/ivas_output_init.c | 2 +- lib_rend/ivas_prot_rend.h | 2 +- lib_rend/ivas_reflections.c | 2 +- lib_rend/ivas_render_config.c | 2 +- lib_rend/ivas_reverb.c | 2 +- lib_rend/ivas_reverb_delay_line.c | 2 +- lib_rend/ivas_reverb_fft_filter.c | 2 +- lib_rend/ivas_reverb_filter_design.c | 2 +- lib_rend/ivas_reverb_iir_filter.c | 2 +- lib_rend/ivas_reverb_utils.c | 2 +- lib_rend/ivas_rom_TdBinauralRenderer.c | 2 +- lib_rend/ivas_rom_TdBinauralRenderer.h | 2 +- lib_rend/ivas_rom_binauralRenderer.c | 2 +- lib_rend/ivas_rom_binauralRenderer.h | 2 +- lib_rend/ivas_rom_binaural_crend_head.c | 2 +- lib_rend/ivas_rom_binaural_crend_head.h | 2 +- lib_rend/ivas_rom_rend.c | 2 +- lib_rend/ivas_rom_rend.h | 2 +- lib_rend/ivas_rotation.c | 2 +- lib_rend/ivas_sba_rendering.c | 2 +- lib_rend/ivas_shoebox.c | 2 +- lib_rend/ivas_stat_rend.h | 2 +- lib_rend/ivas_td_decorr.c | 2 +- lib_rend/ivas_vbap.c | 2 +- lib_rend/lib_rend.c | 2 +- lib_rend/lib_rend.h | 2 +- lib_util/audio_file_reader.c | 2 +- lib_util/audio_file_reader.h | 2 +- lib_util/audio_file_writer.c | 2 +- lib_util/audio_file_writer.h | 2 +- lib_util/bitstream_reader.c | 2 +- lib_util/bitstream_reader.h | 2 +- lib_util/bitstream_writer.c | 2 +- lib_util/bitstream_writer.h | 2 +- lib_util/cmdl_tools.c | 2 +- lib_util/cmdl_tools.h | 2 +- lib_util/cmdln_parser.c | 2 +- lib_util/cmdln_parser.h | 2 +- lib_util/evs_rtp_payload.c | 2 +- lib_util/evs_rtp_payload.h | 2 +- lib_util/g192.c | 2 +- lib_util/g192.h | 2 +- lib_util/hrtf_file_reader.c | 2 +- lib_util/hrtf_file_reader.h | 2 +- lib_util/ism_file_reader.c | 2 +- lib_util/ism_file_reader.h | 2 +- lib_util/ism_file_writer.c | 2 +- lib_util/ism_file_writer.h | 2 +- lib_util/jbm_file_reader.c | 2 +- lib_util/jbm_file_reader.h | 2 +- lib_util/jbm_file_writer.c | 2 +- lib_util/jbm_file_writer.h | 2 +- lib_util/ls_custom_file_reader.c | 2 +- lib_util/ls_custom_file_reader.h | 2 +- lib_util/masa_file_reader.c | 2 +- lib_util/masa_file_reader.h | 2 +- lib_util/masa_file_writer.c | 2 +- lib_util/masa_file_writer.h | 2 +- lib_util/mime_io.c | 2 +- lib_util/mime_io.h | 2 +- lib_util/render_config_reader.c | 2 +- lib_util/render_config_reader.h | 2 +- lib_util/rotation_file_reader.c | 2 +- lib_util/rotation_file_reader.h | 2 +- lib_util/rtpdump.c | 2 +- lib_util/rtpdump.h | 2 +- lib_util/test_fft.c | 2 +- lib_util/test_fft.h | 2 +- lib_util/test_mdct.c | 2 +- lib_util/tinywavein_c.h | 2 +- lib_util/tinywaveout_c.h | 2 +- lib_util/vector3_pair_file_reader.c | 2 +- lib_util/vector3_pair_file_reader.h | 2 +- readme.txt | 2 +- 576 files changed, 576 insertions(+), 576 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 1c60a85b1..ca74eaf48 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/apps/decoder.c b/apps/decoder.c index 058722569..1c59a02e7 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/apps/encoder.c b/apps/encoder.c index b06b5de0d..b6526ae2b 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/apps/renderer.c b/apps/renderer.c index f5c0a8847..81750925e 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 200757026..7fab24660 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 96fd8d166..9bbf24f1c 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_com_lpc.c b/lib_com/basop_com_lpc.c index 5de4fa5d3..5cfb3bed0 100644 --- a/lib_com/basop_com_lpc.c +++ b/lib_com/basop_com_lpc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_lsf_tools.c b/lib_com/basop_lsf_tools.c index 3e49411d6..2c49ad4cf 100644 --- a/lib_com/basop_lsf_tools.c +++ b/lib_com/basop_lsf_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_proto_func.h b/lib_com/basop_proto_func.h index be8b46782..29db9c9c1 100644 --- a/lib_com/basop_proto_func.h +++ b/lib_com/basop_proto_func.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_settings.h b/lib_com/basop_settings.h index a2ef70417..9a344afc4 100644 --- a/lib_com/basop_settings.h +++ b/lib_com/basop_settings.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_tcx_utils.c b/lib_com/basop_tcx_utils.c index 17f0e23ba..378faae0f 100644 --- a/lib_com/basop_tcx_utils.c +++ b/lib_com/basop_tcx_utils.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 19b654e5e..b7ee35ab3 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 92994542e..a6db7dc8d 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 9e61c2571..e5754fa35 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 1acf69c2a..6163fc4ff 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index b6eafd993..1907ef327 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/cng_exc.c b/lib_com/cng_exc.c index 794b6de29..494305e6f 100644 --- a/lib_com/cng_exc.c +++ b/lib_com/cng_exc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 197fbd3c4..26903f525 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index b98f2e7d1..553a34f56 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index e002617ab..8d360c6a3 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/deemph.c b/lib_com/deemph.c index 8cddd7580..b2b43cf72 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 38a077f9e..9e6c450cd 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index 44fc3627a..ba0973f97 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/enh40.c b/lib_com/enh40.c index 89960030f..570f4b211 100644 --- a/lib_com/enh40.c +++ b/lib_com/enh40.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/enh40.h b/lib_com/enh40.h index ff1a86b92..9c3742f3e 100644 --- a/lib_com/enh40.h +++ b/lib_com/enh40.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/enr_1_az.c b/lib_com/enr_1_az.c index e11a500db..81fb78262 100644 --- a/lib_com/enr_1_az.c +++ b/lib_com/enr_1_az.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/env_adj.c b/lib_com/env_adj.c index 554cf1dbe..18520e188 100644 --- a/lib_com/env_adj.c +++ b/lib_com/env_adj.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/env_stab.c b/lib_com/env_stab.c index be19b55e0..b80fd0a8b 100644 --- a/lib_com/env_stab.c +++ b/lib_com/env_stab.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/env_stab_trans.c b/lib_com/env_stab_trans.c index e3f98d881..8c6ec265f 100644 --- a/lib_com/env_stab_trans.c +++ b/lib_com/env_stab_trans.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/fft.c b/lib_com/fft.c index be42d29cb..352a24be9 100644 --- a/lib_com/fft.c +++ b/lib_com/fft.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/fft_cldfb_fx.c b/lib_com/fft_cldfb_fx.c index 80e643362..b26b1bc9f 100644 --- a/lib_com/fft_cldfb_fx.c +++ b/lib_com/fft_cldfb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index ba895d83c..1b095e346 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c index aa3b578bd..839b2faaf 100644 --- a/lib_com/fft_rel.c +++ b/lib_com/fft_rel.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index 5a4f7c4bc..12ed75f0a 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/findpulse.c b/lib_com/findpulse.c index cc7d2bf3b..f2347d5b3 100644 --- a/lib_com/findpulse.c +++ b/lib_com/findpulse.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/frame_ener.c b/lib_com/frame_ener.c index 40e1167e5..e89c4dfad 100644 --- a/lib_com/frame_ener.c +++ b/lib_com/frame_ener.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/frame_ener_fx.c b/lib_com/frame_ener_fx.c index f89c1264b..4428c0796 100644 --- a/lib_com/frame_ener_fx.c +++ b/lib_com/frame_ener_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/get_gain.c b/lib_com/get_gain.c index bf4c1adfb..89b5fa3de 100644 --- a/lib_com/get_gain.c +++ b/lib_com/get_gain.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/get_gain_fx.c b/lib_com/get_gain_fx.c index 66abe96ae..d4c2413c3 100644 --- a/lib_com/get_gain_fx.c +++ b/lib_com/get_gain_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c index 13fdbd67c..9adb448a4 100644 --- a/lib_com/gs_gains.c +++ b/lib_com/gs_gains.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index d6aee58c5..35236b603 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/gs_preech.c b/lib_com/gs_preech.c index a2b2405db..58b49172d 100644 --- a/lib_com/gs_preech.c +++ b/lib_com/gs_preech.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index a75604a14..9d905bcf2 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hp50.c b/lib_com/hp50.c index cd9ed3e98..6920063d4 100644 --- a/lib_com/hp50.c +++ b/lib_com/hp50.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index a1700047e..84bbf8b3c 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hq2_bit_alloc_fx.c b/lib_com/hq2_bit_alloc_fx.c index 4742c81c2..61d00ce98 100644 --- a/lib_com/hq2_bit_alloc_fx.c +++ b/lib_com/hq2_bit_alloc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hq2_core_com.c b/lib_com/hq2_core_com.c index a30655394..bc4edb869 100644 --- a/lib_com/hq2_core_com.c +++ b/lib_com/hq2_core_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hq2_core_com_fx.c b/lib_com/hq2_core_com_fx.c index 86c02fa88..bf0af5e87 100644 --- a/lib_com/hq2_core_com_fx.c +++ b/lib_com/hq2_core_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hq2_noise_inject_fx.c b/lib_com/hq2_noise_inject_fx.c index b85aaa027..bc96fe0f8 100644 --- a/lib_com/hq2_noise_inject_fx.c +++ b/lib_com/hq2_noise_inject_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hq_conf.c b/lib_com/hq_conf.c index 84b843fb4..c139a493c 100644 --- a/lib_com/hq_conf.c +++ b/lib_com/hq_conf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index 7b7da27e6..4426f85d9 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ifft_rel.c b/lib_com/ifft_rel.c index e3b62bdb5..423eea46d 100644 --- a/lib_com/ifft_rel.c +++ b/lib_com/ifft_rel.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/int_lsp.c b/lib_com/int_lsp.c index 37ca1ca4b..0f673b8fd 100644 --- a/lib_com/int_lsp.c +++ b/lib_com/int_lsp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum.c index f65b7a5c5..745ee6ac3 100644 --- a/lib_com/interleave_spectrum.c +++ b/lib_com/interleave_spectrum.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/interpol.c b/lib_com/interpol.c index ceafad116..45021f1c2 100644 --- a/lib_com/interpol.c +++ b/lib_com/interpol.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/isf_dec_amr_wb_fx.c b/lib_com/isf_dec_amr_wb_fx.c index 3b98b1346..5ab82ee6d 100644 --- a/lib_com/isf_dec_amr_wb_fx.c +++ b/lib_com/isf_dec_amr_wb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_agc_com_fx.c b/lib_com/ivas_agc_com_fx.c index 9159fa259..b2c09fa07 100644 --- a/lib_com/ivas_agc_com_fx.c +++ b/lib_com/ivas_agc_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_arith.c b/lib_com/ivas_arith.c index 56f4c599c..2f729bbd4 100644 --- a/lib_com/ivas_arith.c +++ b/lib_com/ivas_arith.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_avq_pos_reorder_com.c b/lib_com/ivas_avq_pos_reorder_com.c index cd50e9ab2..ac539b787 100644 --- a/lib_com/ivas_avq_pos_reorder_com.c +++ b/lib_com/ivas_avq_pos_reorder_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 1fe54d164..6612fac1f 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth.c index 8b13f3fd1..445ea8c78 100644 --- a/lib_com/ivas_cov_smooth.c +++ b/lib_com/ivas_cov_smooth.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 2704c1f08..cf942cc4a 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_entropy_coder_common.c b/lib_com/ivas_entropy_coder_common.c index 8793723cd..d28828d6f 100644 --- a/lib_com/ivas_entropy_coder_common.c +++ b/lib_com/ivas_entropy_coder_common.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 1198008f6..bbf951ab3 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_error_utils.h b/lib_com/ivas_error_utils.h index b686cf283..0c3d5ce04 100644 --- a/lib_com/ivas_error_utils.h +++ b/lib_com/ivas_error_utils.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index df8f7d0f5..498de0188 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters.c index 32ebe479f..7705deb6a 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index 1dd7f0f87..74e9641aa 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_lfe_com.c b/lib_com/ivas_lfe_com.c index 56f14a18b..4d993d64f 100644 --- a/lib_com/ivas_lfe_com.c +++ b/lib_com/ivas_lfe_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com.c index 1ff433344..35db926d0 100644 --- a/lib_com/ivas_masa_com.c +++ b/lib_com/ivas_masa_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mc_com.c b/lib_com/ivas_mc_com.c index 39ba64d0e..88d6c1b5e 100644 --- a/lib_com/ivas_mc_com.c +++ b/lib_com/ivas_mc_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mc_param_com.c b/lib_com/ivas_mc_param_com.c index be3f35606..d69da849a 100644 --- a/lib_com/ivas_mc_param_com.c +++ b/lib_com/ivas_mc_param_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mcmasa_com.c b/lib_com/ivas_mcmasa_com.c index fe29c8486..da0b8f1c4 100644 --- a/lib_com/ivas_mcmasa_com.c +++ b/lib_com/ivas_mcmasa_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mct_com.c b/lib_com/ivas_mct_com.c index 3d2d4c99b..b220d69a7 100644 --- a/lib_com/ivas_mct_com.c +++ b/lib_com/ivas_mct_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mdct_core_com.c b/lib_com/ivas_mdct_core_com.c index f3ad466cc..a5cfb8673 100644 --- a/lib_com/ivas_mdct_core_com.c +++ b/lib_com/ivas_mdct_core_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mdct_imdct_fx.c b/lib_com/ivas_mdct_imdct_fx.c index 37c525109..542f5ca74 100644 --- a/lib_com/ivas_mdct_imdct_fx.c +++ b/lib_com/ivas_mdct_imdct_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_mdft_imdft.c b/lib_com/ivas_mdft_imdft.c index 4ed267ba5..0f24fba81 100644 --- a/lib_com/ivas_mdft_imdft.c +++ b/lib_com/ivas_mdft_imdft.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_omasa_com.c b/lib_com/ivas_omasa_com.c index a86f90acb..eb230b224 100644 --- a/lib_com/ivas_omasa_com.c +++ b/lib_com/ivas_omasa_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools.c index 6ccc07523..5689e81c0 100644 --- a/lib_com/ivas_pca_tools.c +++ b/lib_com/ivas_pca_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 5ea7b0765..2493add28 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 1682c255b..80bdda3c2 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_qmetadata_com.c b/lib_com/ivas_qmetadata_com.c index 85d4332e0..cbc67de00 100644 --- a/lib_com/ivas_qmetadata_com.c +++ b/lib_com/ivas_qmetadata_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com.c index c3608d248..8ef48be2e 100644 --- a/lib_com/ivas_qspherical_com.c +++ b/lib_com/ivas_qspherical_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 5a864835c..560d1ee8e 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index b58e183eb..6004760e3 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index cc138d070..8ea2b91e4 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index e1f4d0a6e..3344a35d2 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index 370e8caa4..94ceb8e3c 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index 5931c4ea1..788fb3c56 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 14de6cc15..0ebae0de6 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util.c index 81044fb40..0f0e003dd 100644 --- a/lib_com/ivas_spar_com_quant_util.c +++ b/lib_com/ivas_spar_com_quant_util.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 090db04db..249d1e963 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com.c index 8b377bdbc..1157fffcf 100644 --- a/lib_com/ivas_stereo_dft_com.c +++ b/lib_com/ivas_stereo_dft_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c index 30d95afe9..b4fb66429 100644 --- a/lib_com/ivas_stereo_eclvq_com_fx.c +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index be9f35868..78a3c90ca 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_mdct_bands_com.c b/lib_com/ivas_stereo_mdct_bands_com.c index 8c21798b6..b1750fd16 100644 --- a/lib_com/ivas_stereo_mdct_bands_com.c +++ b/lib_com/ivas_stereo_mdct_bands_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_mdct_stereo_com.c b/lib_com/ivas_stereo_mdct_stereo_com.c index 45e734fea..dd94358af 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com.c +++ b/lib_com/ivas_stereo_mdct_stereo_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com.c index e34e8fd18..996b262db 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c index 0f5eb402e..14ab8131e 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index d6210dfc7..ec3c30723 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ivas_transient_det.c b/lib_com/ivas_transient_det.c index dccf4db02..b5ea507eb 100644 --- a/lib_com/ivas_transient_det.c +++ b/lib_com/ivas_transient_det.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind.c index 505cc0753..e0871fa70 100644 --- a/lib_com/lag_wind.c +++ b/lib_com/lag_wind.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/lerp.c b/lib_com/lerp.c index 2fd9321be..bb33d9922 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/limit_t0.c b/lib_com/limit_t0.c index dfbfbb796..d49cad283 100644 --- a/lib_com/limit_t0.c +++ b/lib_com/limit_t0.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/logqnorm_fx.c b/lib_com/logqnorm_fx.c index c7852bbe4..833ff03fb 100644 --- a/lib_com/logqnorm_fx.c +++ b/lib_com/logqnorm_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 68ba282d5..66c5dd15e 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index 1c0fb7500..ef6c0b0ff 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 0a8a86aee..08e74b9b7 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/mime.h b/lib_com/mime.h index 80d984617..6e9e5fc87 100644 --- a/lib_com/mime.h +++ b/lib_com/mime.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index 06119b69e..4af93522d 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/move.h b/lib_com/move.h index 5c325fb1d..7762ec79a 100644 --- a/lib_com/move.h +++ b/lib_com/move.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index bab16f165..34e2083b9 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index 7c6658e8f..14c9b6d97 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/nelp_fx.c b/lib_com/nelp_fx.c index b37d57093..39d57299e 100644 --- a/lib_com/nelp_fx.c +++ b/lib_com/nelp_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/options.h b/lib_com/options.h index 288145122..03b40ce1c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/ppp_fx.c b/lib_com/ppp_fx.c index 791813dc7..cc6b59bdb 100644 --- a/lib_com/ppp_fx.c +++ b/lib_com/ppp_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/preemph.c b/lib_com/preemph.c index 66a12c621..490a18aef 100644 --- a/lib_com/preemph.c +++ b/lib_com/preemph.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/prot.h b/lib_com/prot.h index 647a18bf1..16f4659a0 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index cf7072cf5..284986bb4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/reordvct_fx.c b/lib_com/reordvct_fx.c index 3b741203a..62eb2f352 100644 --- a/lib_com/reordvct_fx.c +++ b/lib_com/reordvct_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/rom_basop_util.c b/lib_com/rom_basop_util.c index 4a0eed6b6..c3bfc6eef 100644 --- a/lib_com/rom_basop_util.c +++ b/lib_com/rom_basop_util.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/rom_basop_util.h b/lib_com/rom_basop_util.h index f2e81f0a1..e7811db89 100644 --- a/lib_com/rom_basop_util.h +++ b/lib_com/rom_basop_util.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 5e61db76e..bad47f065 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 19447609c..274a33a18 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/rom_com_fx.c b/lib_com/rom_com_fx.c index e669a8995..611658884 100644 --- a/lib_com/rom_com_fx.c +++ b/lib_com/rom_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/rom_com_fx.h b/lib_com/rom_com_fx.h index 5c30ad5da..29e763757 100644 --- a/lib_com/rom_com_fx.h +++ b/lib_com/rom_com_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/scale_mem_fx.c b/lib_com/scale_mem_fx.c index 9dd997680..002821050 100644 --- a/lib_com/scale_mem_fx.c +++ b/lib_com/scale_mem_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 45a16dc1a..c468ef114 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/stl.h b/lib_com/stl.h index 6643f5948..0de974226 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index 09f72b230..eda099cd9 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/swb_bwe_com_lr_fx.c b/lib_com/swb_bwe_com_lr_fx.c index 7c2c35551..d0b8d0100 100644 --- a/lib_com/swb_bwe_com_lr_fx.c +++ b/lib_com/swb_bwe_com_lr_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 105c4db15..2aa781a43 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index 110a1160d..cececd8f5 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/tools.c b/lib_com/tools.c index 733e5634a..4d9f5e956 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 063f49fc4..efa9d7e5a 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/typedef.h b/lib_com/typedef.h index 3d86229dd..d3aba3e98 100644 --- a/lib_com/typedef.h +++ b/lib_com/typedef.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_com/wtda.c b/lib_com/wtda.c index 6bce31db9..a7ea5314c 100644 --- a/lib_com/wtda.c +++ b/lib_com/wtda.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_debug/debug.c b/lib_debug/debug.c index 23de1bd36..0cfa00e81 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_debug/debug.h b/lib_debug/debug.h index e88def922..64b1de154 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c index a85bc7be0..c05ae96ef 100644 --- a/lib_debug/sba_debug.c +++ b/lib_debug/sba_debug.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_debug/sba_debug.h b/lib_debug/sba_debug.h index 60f74401d..2be427d52 100644 --- a/lib_debug/sba_debug.h +++ b/lib_debug/sba_debug.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_debug/snr.c b/lib_debug/snr.c index bd8af44e8..cf15a2907 100644 --- a/lib_debug/snr.c +++ b/lib_debug/snr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ACcontextMapping_dec.c b/lib_dec/ACcontextMapping_dec.c index cf5b4a9b7..186a22bc7 100644 --- a/lib_dec/ACcontextMapping_dec.c +++ b/lib_dec/ACcontextMapping_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c index fc669bf26..3dd25fd27 100644 --- a/lib_dec/FEC.c +++ b/lib_dec/FEC.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_HQ_core.c b/lib_dec/FEC_HQ_core.c index 794f6dab3..6a119b365 100644 --- a/lib_dec/FEC_HQ_core.c +++ b/lib_dec/FEC_HQ_core.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c index 2df90bf11..85b25b336 100644 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ b/lib_dec/FEC_HQ_phase_ecu.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_adapt_codebook.c b/lib_dec/FEC_adapt_codebook.c index b2dcc5560..f07b5952a 100644 --- a/lib_dec/FEC_adapt_codebook.c +++ b/lib_dec/FEC_adapt_codebook.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_clas_estim.c b/lib_dec/FEC_clas_estim.c index 4d461a0dc..77501d3fa 100644 --- a/lib_dec/FEC_clas_estim.c +++ b/lib_dec/FEC_clas_estim.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_lsf_estim.c b/lib_dec/FEC_lsf_estim.c index 1fa0758f7..49a4adafc 100644 --- a/lib_dec/FEC_lsf_estim.c +++ b/lib_dec/FEC_lsf_estim.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_pitch_estim.c b/lib_dec/FEC_pitch_estim.c index 1b9ed9484..bae1a8539 100644 --- a/lib_dec/FEC_pitch_estim.c +++ b/lib_dec/FEC_pitch_estim.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/FEC_scale_syn.c b/lib_dec/FEC_scale_syn.c index 7d23dd6f7..5c3581f4f 100644 --- a/lib_dec/FEC_scale_syn.c +++ b/lib_dec/FEC_scale_syn.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/LD_music_post_filter.c b/lib_dec/LD_music_post_filter.c index b2b69cc45..494df80ce 100644 --- a/lib_dec/LD_music_post_filter.c +++ b/lib_dec/LD_music_post_filter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/TonalComponentDetection.c b/lib_dec/TonalComponentDetection.c index 040d4569d..a8ad442c0 100644 --- a/lib_dec/TonalComponentDetection.c +++ b/lib_dec/TonalComponentDetection.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 5350d6dbc..2374f1b7c 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index e9e4625ce..066a3eab5 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c index fd4f3cb7c..b25a46f03 100644 --- a/lib_dec/acelp_core_switch_dec.c +++ b/lib_dec/acelp_core_switch_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index d441f6ead..47e1f0be1 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ari_dec.c b/lib_dec/ari_dec.c index 8dedcea1e..b45cb5d9c 100644 --- a/lib_dec/ari_dec.c +++ b/lib_dec/ari_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ari_hm_dec.c b/lib_dec/ari_hm_dec.c index f290ca9fb..da7722325 100644 --- a/lib_dec/ari_hm_dec.c +++ b/lib_dec/ari_hm_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/arith_coder_dec.c b/lib_dec/arith_coder_dec.c index a9579d5d2..93bd8877c 100644 --- a/lib_dec/arith_coder_dec.c +++ b/lib_dec/arith_coder_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/avq_dec.c b/lib_dec/avq_dec.c index 27bb2c324..1e54dc9d9 100644 --- a/lib_dec/avq_dec.c +++ b/lib_dec/avq_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c index a33149fff..478a81474 100644 --- a/lib_dec/bass_psfilter.c +++ b/lib_dec/bass_psfilter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/cng_dec.c b/lib_dec/cng_dec.c index 515dd295a..5f2ee4f7e 100644 --- a/lib_dec/cng_dec.c +++ b/lib_dec/cng_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index 48464fb35..37c397bbf 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/core_dec_reconf.c b/lib_dec/core_dec_reconf.c index f8f6d6a6f..6bcd541ef 100644 --- a/lib_dec/core_dec_reconf.c +++ b/lib_dec/core_dec_reconf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c index 9fb0cf788..09bd8e846 100644 --- a/lib_dec/core_dec_switch.c +++ b/lib_dec/core_dec_switch.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index a8041cd53..4c48a6fa8 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/d_gain2p.c b/lib_dec/d_gain2p.c index bcdeaa041..cc19164ca 100644 --- a/lib_dec/d_gain2p.c +++ b/lib_dec/d_gain2p.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec2t32.c b/lib_dec/dec2t32.c index 6b94be229..13c9ebade 100644 --- a/lib_dec/dec2t32.c +++ b/lib_dec/dec2t32.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec4t64.c b/lib_dec/dec4t64.c index e931b0a68..d448123b1 100644 --- a/lib_dec/dec4t64.c +++ b/lib_dec/dec4t64.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index 9af4fa20e..4c0b6a79a 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_ace.c b/lib_dec/dec_ace.c index da306d76e..76754d2e6 100644 --- a/lib_dec/dec_ace.c +++ b/lib_dec/dec_ace.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_acelp.c b/lib_dec/dec_acelp.c index 7cae62391..075822eb6 100644 --- a/lib_dec/dec_acelp.c +++ b/lib_dec/dec_acelp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index 4e5d4e3ae..d8b8509d9 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_amr_wb.c b/lib_dec/dec_amr_wb.c index 0874e988a..4cf26936b 100644 --- a/lib_dec/dec_amr_wb.c +++ b/lib_dec/dec_amr_wb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_gen_voic.c b/lib_dec/dec_gen_voic.c index fd4f3cb7c..b25a46f03 100644 --- a/lib_dec/dec_gen_voic.c +++ b/lib_dec/dec_gen_voic.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_higher_acelp.c b/lib_dec/dec_higher_acelp.c index 2a9bb28cb..77bd8dd6d 100644 --- a/lib_dec/dec_higher_acelp.c +++ b/lib_dec/dec_higher_acelp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_nelp.c b/lib_dec/dec_nelp.c index e7a8ca967..167c70dbf 100644 --- a/lib_dec/dec_nelp.c +++ b/lib_dec/dec_nelp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_pit_exc.c b/lib_dec/dec_pit_exc.c index e5ee5c0c0..5a894a39c 100644 --- a/lib_dec/dec_pit_exc.c +++ b/lib_dec/dec_pit_exc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_post.c b/lib_dec/dec_post.c index 10836b779..5cb811408 100644 --- a/lib_dec/dec_post.c +++ b/lib_dec/dec_post.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_ppp.c b/lib_dec/dec_ppp.c index e7a8ca967..167c70dbf 100644 --- a/lib_dec/dec_ppp.c +++ b/lib_dec/dec_ppp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c index 33c62a67a..7b4567f7a 100644 --- a/lib_dec/dec_prm.c +++ b/lib_dec/dec_prm.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index 708527df5..aca84d9d9 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -1,7 +1,7 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_tran.c b/lib_dec/dec_tran.c index 88f93c733..3522990d9 100644 --- a/lib_dec/dec_tran.c +++ b/lib_dec/dec_tran.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dec_uv.c b/lib_dec/dec_uv.c index e748899a9..9e7ce9558 100644 --- a/lib_dec/dec_uv.c +++ b/lib_dec/dec_uv.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/decision_matrix_dec.c b/lib_dec/decision_matrix_dec.c index a96d130cb..9ee7741c0 100644 --- a/lib_dec/decision_matrix_dec.c +++ b/lib_dec/decision_matrix_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dlpc_avq.c b/lib_dec/dlpc_avq.c index 3514dda88..748544423 100644 --- a/lib_dec/dlpc_avq.c +++ b/lib_dec/dlpc_avq.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/dlpc_stoch.c b/lib_dec/dlpc_stoch.c index c1956b8d9..5645c9462 100644 --- a/lib_dec/dlpc_stoch.c +++ b/lib_dec/dlpc_stoch.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/er_dec_acelp.c b/lib_dec/er_dec_acelp.c index 68731d8f1..047de37fb 100644 --- a/lib_dec/er_dec_acelp.c +++ b/lib_dec/er_dec_acelp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c index 2d8fdd56a..f2bd70247 100644 --- a/lib_dec/er_dec_tcx.c +++ b/lib_dec/er_dec_tcx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/er_scale_syn.c b/lib_dec/er_scale_syn.c index a45d9a0bd..eea698fa6 100644 --- a/lib_dec/er_scale_syn.c +++ b/lib_dec/er_scale_syn.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/er_sync_exc.c b/lib_dec/er_sync_exc.c index 8b2b54876..05720aca8 100644 --- a/lib_dec/er_sync_exc.c +++ b/lib_dec/er_sync_exc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/er_util.c b/lib_dec/er_util.c index 88c1af13f..9cd1332e6 100644 --- a/lib_dec/er_util.c +++ b/lib_dec/er_util.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index d441f6ead..47e1f0be1 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 51ae2d59f..dd3adb247 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/gain_dec.c b/lib_dec/gain_dec.c index d441f6ead..47e1f0be1 100644 --- a/lib_dec/gain_dec.c +++ b/lib_dec/gain_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/gaus_dec.c b/lib_dec/gaus_dec.c index d441f6ead..47e1f0be1 100644 --- a/lib_dec/gaus_dec.c +++ b/lib_dec/gaus_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/gs_dec.c b/lib_dec/gs_dec.c index 79457ca5d..4d34802bb 100644 --- a/lib_dec/gs_dec.c +++ b/lib_dec/gs_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/gs_dec_amr_wb.c b/lib_dec/gs_dec_amr_wb.c index d441f6ead..47e1f0be1 100644 --- a/lib_dec/gs_dec_amr_wb.c +++ b/lib_dec/gs_dec_amr_wb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hdecnrm.c b/lib_dec/hdecnrm.c index 56e7b45fe..19627a4f3 100644 --- a/lib_dec/hdecnrm.c +++ b/lib_dec/hdecnrm.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hf_synth.c b/lib_dec/hf_synth.c index 8070239de..fc8c8da5f 100644 --- a/lib_dec/hf_synth.c +++ b/lib_dec/hf_synth.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hq_classifier_dec.c b/lib_dec/hq_classifier_dec.c index 0fe8682da..c899b52ff 100644 --- a/lib_dec/hq_classifier_dec.c +++ b/lib_dec/hq_classifier_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hq_conf_fec.c b/lib_dec/hq_conf_fec.c index fd4f3cb7c..b25a46f03 100644 --- a/lib_dec/hq_conf_fec.c +++ b/lib_dec/hq_conf_fec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hq_core_dec.c b/lib_dec/hq_core_dec.c index 5a1f34a11..cd29271f1 100644 --- a/lib_dec/hq_core_dec.c +++ b/lib_dec/hq_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hq_env_dec.c b/lib_dec/hq_env_dec.c index fc894ba6c..d029c2fa8 100644 --- a/lib_dec/hq_env_dec.c +++ b/lib_dec/hq_env_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hq_hr_dec.c b/lib_dec/hq_hr_dec.c index fd4f3cb7c..b25a46f03 100644 --- a/lib_dec/hq_hr_dec.c +++ b/lib_dec/hq_hr_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/hq_lr_dec.c b/lib_dec/hq_lr_dec.c index dd5876ea9..8547d9712 100644 --- a/lib_dec/hq_lr_dec.c +++ b/lib_dec/hq_lr_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index 785dc6a86..64a8d798b 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/igf_scf_dec.c b/lib_dec/igf_scf_dec.c index 1c0985cf4..68174a8c2 100644 --- a/lib_dec/igf_scf_dec.c +++ b/lib_dec/igf_scf_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 3c20d7b27..2b8091305 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/inov_dec.c b/lib_dec/inov_dec.c index 84f371717..be630cee0 100644 --- a/lib_dec/inov_dec.c +++ b/lib_dec/inov_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_agc_dec.c b/lib_dec/ivas_agc_dec.c index 3bfbcee10..46246da44 100644 --- a/lib_dec/ivas_agc_dec.c +++ b/lib_dec/ivas_agc_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index 8996f087d..f5418abc6 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index f23c0b710..748bdec38 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 9aaddb2fb..92b43092b 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index 56a45ddb0..89ca9a5ba 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index bc61a3baa..4a6f34081 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index f36a227b3..c22c617c0 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 70d0a21a7..351331bb2 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec.c index 6196d31fb..a8c151edb 100644 --- a/lib_dec/ivas_decision_matrix_dec.c +++ b/lib_dec/ivas_decision_matrix_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 95cca12a0..7d2f7be4f 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index fd039fe96..13d8fc940 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_entropy_decoder.c b/lib_dec/ivas_entropy_decoder.c index 5f64c1123..0c489fb04 100644 --- a/lib_dec/ivas_entropy_decoder.c +++ b/lib_dec/ivas_entropy_decoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 35844b5e5..73e2b5d01 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index a5f7f7b06..14e83fe83 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 106653e48..0365005be 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index ae33f2794..833ed5e16 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index c7fce8dd5..1f7af935d 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 2f2a0fda5..738e5a598 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 427959388..5317e803e 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c index a9ed90a8a..e9f3a7b28 100644 --- a/lib_dec/ivas_lfe_dec.c +++ b/lib_dec/ivas_lfe_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index ec58c45c0..616b15c6e 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_lfe_plc.c b/lib_dec/ivas_lfe_plc.c index 8ae40e2be..89b232254 100644 --- a/lib_dec/ivas_lfe_plc.c +++ b/lib_dec/ivas_lfe_plc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 2c2b5d5eb..f5e7816ad 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_ls_custom_dec.c b/lib_dec/ivas_ls_custom_dec.c index 25badc608..eabee357b 100644 --- a/lib_dec/ivas_ls_custom_dec.c +++ b/lib_dec/ivas_ls_custom_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 983eb3309..aa42f4f91 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 4175d15de..50d03b577 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index c1bf455a5..b12236746 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec.c index 3f5f1d098..687efb3ce 100644 --- a/lib_dec/ivas_mcmasa_dec.c +++ b/lib_dec/ivas_mcmasa_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mct_core_dec.c b/lib_dec/ivas_mct_core_dec.c index 7c4c3743c..824370bb8 100644 --- a/lib_dec/ivas_mct_core_dec.c +++ b/lib_dec/ivas_mct_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index a8cda4e58..a92f21f6d 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c index 7ba41f344..52431d36a 100644 --- a/lib_dec/ivas_mct_dec_mct.c +++ b/lib_dec/ivas_mct_dec_mct.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mct_dec_mct_fx.c b/lib_dec/ivas_mct_dec_mct_fx.c index 3ed0998d1..331bdc253 100644 --- a/lib_dec/ivas_mct_dec_mct_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 9c189e6a1..2158dec1c 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer.c index 6ef615601..231aee8aa 100644 --- a/lib_dec/ivas_mono_dmx_renderer.c +++ b/lib_dec/ivas_mono_dmx_renderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 256ce8f96..3a6480386 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 509217616..0fb4163be 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index f9d14c995..a5285b5cb 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 59a560f33..02f37672d 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 64995d8a0..cb96d3b0d 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_pca_dec.c b/lib_dec/ivas_pca_dec.c index 9e3fbe939..f2f5274be 100644 --- a/lib_dec/ivas_pca_dec.c +++ b/lib_dec/ivas_pca_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 1700c2527..4a0c62e8d 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c index b961b6dbb..dc4a1b01b 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 434fc958d..c225f126a 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_qspherical_dec.c b/lib_dec/ivas_qspherical_dec.c index 446c64b6c..43ac60305 100644 --- a/lib_dec/ivas_qspherical_dec.c +++ b/lib_dec/ivas_qspherical_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_range_uni_dec.c b/lib_dec/ivas_range_uni_dec.c index 3da244dd8..6d6631f73 100644 --- a/lib_dec/ivas_range_uni_dec.c +++ b/lib_dec/ivas_range_uni_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index e73246176..812d9957f 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index e79c50856..11752380d 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index e27bc0638..65faabdc0 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index 15a652bc1..1cfc7aa2e 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 5867a44b3..12a34e170 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index 7cc1ebbb6..434fdf5fa 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index 0bee68afb..5f384870f 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index 6c22b3a98..ce4992046 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sns_dec.c b/lib_dec/ivas_sns_dec.c index 7823d2f7c..86fd2fb3e 100644 --- a/lib_dec/ivas_sns_dec.c +++ b/lib_dec/ivas_sns_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 0451aad08..37489e58f 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 0bdc62756..cddbf8cdf 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index c33c5da63..3ad16b981 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index cf01ce54f..b1522be36 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_adapt_GR_dec.c b/lib_dec/ivas_stereo_adapt_GR_dec.c index fbaa98534..c67a52b6c 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 2ad6085ca..c8985d7cd 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 94234a1e1..5449521d6 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx.c index e97ba23de..99cea064b 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 961120073..b76bddbbc 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_dft_plc.c b/lib_dec/ivas_stereo_dft_plc.c index 3988b275a..5a9122b00 100644 --- a/lib_dec/ivas_stereo_dft_plc.c +++ b/lib_dec/ivas_stereo_dft_plc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index ded3b48f4..9e6878faf 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_eclvq_dec.c b/lib_dec/ivas_stereo_eclvq_dec.c index c74649d90..ed26543d3 100644 --- a/lib_dec/ivas_stereo_eclvq_dec.c +++ b/lib_dec/ivas_stereo_eclvq_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_esf_dec.c b/lib_dec/ivas_stereo_esf_dec.c index e52528044..80603f6c0 100644 --- a/lib_dec/ivas_stereo_esf_dec.c +++ b/lib_dec/ivas_stereo_esf_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec.c index a28afdad9..b72e66c5f 100644 --- a/lib_dec/ivas_stereo_ica_dec.c +++ b/lib_dec/ivas_stereo_ica_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 8b8887c9c..6bba90feb 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 233dcc225..e11120d38 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 3014dba06..bf343da7f 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 829173da0..4a788be83 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index ad6d58ebf..a8b74c447 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec.c index c53135f0a..d296e3f33 100644 --- a/lib_dec/ivas_stereo_td_dec.c +++ b/lib_dec/ivas_stereo_td_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 77cf192c2..a22502188 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index d3a3d7bc6..37ffc5128 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c index 7df267b1d..dbbc22b4d 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer.c index bc12026c9..cdabe4700 100644 --- a/lib_dec/jbm_jb4_circularbuffer.c +++ b/lib_dec/jbm_jb4_circularbuffer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4_circularbuffer.h b/lib_dec/jbm_jb4_circularbuffer.h index ec6a5c7be..de614eeea 100644 --- a/lib_dec/jbm_jb4_circularbuffer.h +++ b/lib_dec/jbm_jb4_circularbuffer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer.c index 27a1d6ff1..55113ee13 100644 --- a/lib_dec/jbm_jb4_inputbuffer.c +++ b/lib_dec/jbm_jb4_inputbuffer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4_inputbuffer.h b/lib_dec/jbm_jb4_inputbuffer.h index b9c9c5ef6..769cccba6 100644 --- a/lib_dec/jbm_jb4_inputbuffer.h +++ b/lib_dec/jbm_jb4_inputbuffer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4_jmf.c b/lib_dec/jbm_jb4_jmf.c index 8e5215dae..940df5ecb 100644 --- a/lib_dec/jbm_jb4_jmf.c +++ b/lib_dec/jbm_jb4_jmf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4_jmf.h b/lib_dec/jbm_jb4_jmf.h index b08f5502c..6b5a00434 100644 --- a/lib_dec/jbm_jb4_jmf.h +++ b/lib_dec/jbm_jb4_jmf.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index a19f8bfd7..4878b7d64 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 55565be4a..939fad2cb 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index 92aee035e..10b91a60c 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 7acdf599c..1fe7481df 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c index 35a08b2de..00e5ce7f0 100644 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ b/lib_dec/jbm_pcmdsp_fifo.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_fifo.h b/lib_dec/jbm_pcmdsp_fifo.h index 12b7f5b14..1375c5713 100644 --- a/lib_dec/jbm_pcmdsp_fifo.h +++ b/lib_dec/jbm_pcmdsp_fifo.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.c b/lib_dec/jbm_pcmdsp_similarityestimation.c index b6eeaf0e1..cc13c0148 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.c +++ b/lib_dec/jbm_pcmdsp_similarityestimation.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.h b/lib_dec/jbm_pcmdsp_similarityestimation.h index 123d0c3c1..086f88181 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.h +++ b/lib_dec/jbm_pcmdsp_similarityestimation.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_window.c b/lib_dec/jbm_pcmdsp_window.c index ea15ab7a1..eba40ec98 100644 --- a/lib_dec/jbm_pcmdsp_window.c +++ b/lib_dec/jbm_pcmdsp_window.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/jbm_pcmdsp_window.h b/lib_dec/jbm_pcmdsp_window.h index 9102e027f..3551380de 100644 --- a/lib_dec/jbm_pcmdsp_window.h +++ b/lib_dec/jbm_pcmdsp_window.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lead_deindexing.c b/lib_dec/lead_deindexing.c index dbe4a43e8..35a1adf15 100644 --- a/lib_dec/lead_deindexing.c +++ b/lib_dec/lead_deindexing.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 8e228facb..81d78932a 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 28fbe71b9..0c4d54db8 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 7e2e69ec4..2cc4c6387 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lp_exc_d.c b/lib_dec/lp_exc_d.c index e7a8ca967..167c70dbf 100644 --- a/lib_dec/lp_exc_d.c +++ b/lib_dec/lp_exc_d.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lsf_dec.c b/lib_dec/lsf_dec.c index f963d7317..abc1aab9d 100644 --- a/lib_dec/lsf_dec.c +++ b/lib_dec/lsf_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/lsf_msvq_ma_dec.c b/lib_dec/lsf_msvq_ma_dec.c index 313c2798e..042eec9ab 100644 --- a/lib_dec/lsf_msvq_ma_dec.c +++ b/lib_dec/lsf_msvq_ma_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/nelp_dec.c b/lib_dec/nelp_dec.c index 895fdaae2..1dc550e6d 100644 --- a/lib_dec/nelp_dec.c +++ b/lib_dec/nelp_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/peak_vq_dec.c b/lib_dec/peak_vq_dec.c index 7b039f26f..67ab06e08 100644 --- a/lib_dec/peak_vq_dec.c +++ b/lib_dec/peak_vq_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/pit_dec.c b/lib_dec/pit_dec.c index 7d906b12e..c74e05591 100644 --- a/lib_dec/pit_dec.c +++ b/lib_dec/pit_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/pitch_extr.c b/lib_dec/pitch_extr.c index 53a6b154a..3d10f2158 100644 --- a/lib_dec/pitch_extr.c +++ b/lib_dec/pitch_extr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/post_dec.c b/lib_dec/post_dec.c index 3643a2810..380b256b0 100644 --- a/lib_dec/post_dec.c +++ b/lib_dec/post_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/ppp_dec.c b/lib_dec/ppp_dec.c index d1de09bc7..7ea6e47a5 100644 --- a/lib_dec/ppp_dec.c +++ b/lib_dec/ppp_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/pvq_core_dec.c b/lib_dec/pvq_core_dec.c index 936720d06..2bdb05e5f 100644 --- a/lib_dec/pvq_core_dec.c +++ b/lib_dec/pvq_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/pvq_decode.c b/lib_dec/pvq_decode.c index 8e752f0ac..9228e2f5d 100644 --- a/lib_dec/pvq_decode.c +++ b/lib_dec/pvq_decode.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/range_dec.c b/lib_dec/range_dec.c index fd4f3cb7c..b25a46f03 100644 --- a/lib_dec/range_dec.c +++ b/lib_dec/range_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/re8_dec.c b/lib_dec/re8_dec.c index e748899a9..9e7ce9558 100644 --- a/lib_dec/re8_dec.c +++ b/lib_dec/re8_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/rom_dec.c b/lib_dec/rom_dec.c index 787966f72..3f5243286 100644 --- a/lib_dec/rom_dec.c +++ b/lib_dec/rom_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/rom_dec.h b/lib_dec/rom_dec.h index f057b804a..8c1021682 100644 --- a/lib_dec/rom_dec.h +++ b/lib_dec/rom_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/rst_dec.c b/lib_dec/rst_dec.c index 3b7436831..3feb2af8e 100644 --- a/lib_dec/rst_dec.c +++ b/lib_dec/rst_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 5c7f894b9..c892ae732 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/stat_noise_uv_dec.c b/lib_dec/stat_noise_uv_dec.c index e748899a9..9e7ce9558 100644 --- a/lib_dec/stat_noise_uv_dec.c +++ b/lib_dec/stat_noise_uv_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c index 0f9863bdf..68272a79f 100644 --- a/lib_dec/swb_bwe_dec.c +++ b/lib_dec/swb_bwe_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/swb_bwe_dec_hr.c b/lib_dec/swb_bwe_dec_hr.c index e2be97ae4..06d666ffd 100644 --- a/lib_dec/swb_bwe_dec_hr.c +++ b/lib_dec/swb_bwe_dec_hr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/swb_bwe_dec_lr.c b/lib_dec/swb_bwe_dec_lr.c index ff2af374e..7bd79fa23 100644 --- a/lib_dec/swb_bwe_dec_lr.c +++ b/lib_dec/swb_bwe_dec_lr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c index 6035e402d..80dfad505 100644 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/syn_outp.c b/lib_dec/syn_outp.c index 96ac16dba..543b69d8d 100644 --- a/lib_dec/syn_outp.c +++ b/lib_dec/syn_outp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/tcq_core_dec.c b/lib_dec/tcq_core_dec.c index 403c5db5b..f7f81a0fa 100644 --- a/lib_dec/tcq_core_dec.c +++ b/lib_dec/tcq_core_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/tcx_utils_dec.c b/lib_dec/tcx_utils_dec.c index efee08d61..1fc02caee 100644 --- a/lib_dec/tcx_utils_dec.c +++ b/lib_dec/tcx_utils_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/tns_base_dec.c b/lib_dec/tns_base_dec.c index 68e2e313c..c74a5f4e1 100644 --- a/lib_dec/tns_base_dec.c +++ b/lib_dec/tns_base_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 0ac877450..6a74d3b87 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/transition_dec.c b/lib_dec/transition_dec.c index d441f6ead..47e1f0be1 100644 --- a/lib_dec/transition_dec.c +++ b/lib_dec/transition_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/updt_dec.c b/lib_dec/updt_dec.c index 2b370b05d..6ffe42f8c 100644 --- a/lib_dec/updt_dec.c +++ b/lib_dec/updt_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/vlpc_1st_dec.c b/lib_dec/vlpc_1st_dec.c index 97a511fb6..78821eb05 100644 --- a/lib_dec/vlpc_1st_dec.c +++ b/lib_dec/vlpc_1st_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/vlpc_2st_dec.c b/lib_dec/vlpc_2st_dec.c index e748899a9..9e7ce9558 100644 --- a/lib_dec/vlpc_2st_dec.c +++ b/lib_dec/vlpc_2st_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/voiced_dec.c b/lib_dec/voiced_dec.c index 87f19fd33..4fbd33bdf 100644 --- a/lib_dec/voiced_dec.c +++ b/lib_dec/voiced_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_dec/waveadjust_fec_dec.c b/lib_dec/waveadjust_fec_dec.c index b573d3d7f..65de1e11f 100644 --- a/lib_dec/waveadjust_fec_dec.c +++ b/lib_dec/waveadjust_fec_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ari_enc.c b/lib_enc/ari_enc.c index cda9d3c82..da4d1486b 100644 --- a/lib_enc/ari_enc.c +++ b/lib_enc/ari_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ari_hm_enc.c b/lib_enc/ari_hm_enc.c index a227784dc..c6e11a3f0 100644 --- a/lib_enc/ari_hm_enc.c +++ b/lib_enc/ari_hm_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/arith_coder_enc.c b/lib_enc/arith_coder_enc.c index 5680feed4..5625b6cf4 100644 --- a/lib_enc/arith_coder_enc.c +++ b/lib_enc/arith_coder_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/avq_cod.c b/lib_enc/avq_cod.c index 8e752f0ac..9228e2f5d 100644 --- a/lib_enc/avq_cod.c +++ b/lib_enc/avq_cod.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/bass_psfilter_enc.c b/lib_enc/bass_psfilter_enc.c index 8e752f0ac..9228e2f5d 100644 --- a/lib_enc/bass_psfilter_enc.c +++ b/lib_enc/bass_psfilter_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/bw_detect.c b/lib_enc/bw_detect.c index 2cba6f328..d86351ae8 100644 --- a/lib_enc/bw_detect.c +++ b/lib_enc/bw_detect.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cng_enc.c b/lib_enc/cng_enc.c index 15dc89516..192a71f92 100644 --- a/lib_enc/cng_enc.c +++ b/lib_enc/cng_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cod2t32.c b/lib_enc/cod2t32.c index e7a8ca967..167c70dbf 100644 --- a/lib_enc/cod2t32.c +++ b/lib_enc/cod2t32.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cod4t64.c b/lib_enc/cod4t64.c index b4081d00f..9be976783 100644 --- a/lib_enc/cod4t64.c +++ b/lib_enc/cod4t64.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index e4c8124e6..16651b8f2 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cod_ace.c b/lib_enc/cod_ace.c index 3ee7cc7b2..46d7a42d1 100644 --- a/lib_enc/cod_ace.c +++ b/lib_enc/cod_ace.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 963cc1650..25f615e6a 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cod_uv.c b/lib_enc/cod_uv.c index e748899a9..9e7ce9558 100644 --- a/lib_enc/cod_uv.c +++ b/lib_enc/cod_uv.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/comvad_decision.c b/lib_enc/comvad_decision.c index f6ca036b2..efb9c1d78 100644 --- a/lib_enc/comvad_decision.c +++ b/lib_enc/comvad_decision.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/cor_shif.c b/lib_enc/cor_shif.c index 825401325..0e2004abf 100644 --- a/lib_enc/cor_shif.c +++ b/lib_enc/cor_shif.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_enc_2div.c b/lib_enc/core_enc_2div.c index 0fe8682da..c899b52ff 100644 --- a/lib_enc/core_enc_2div.c +++ b/lib_enc/core_enc_2div.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index e98956efe..41f3d0ac5 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_enc_ol.c b/lib_enc/core_enc_ol.c index d86e50ff1..c282f7649 100644 --- a/lib_enc/core_enc_ol.c +++ b/lib_enc/core_enc_ol.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_enc_reconf.c b/lib_enc/core_enc_reconf.c index 24729c124..29c215059 100644 --- a/lib_enc/core_enc_reconf.c +++ b/lib_enc/core_enc_reconf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index b6f723c2b..3c0f41446 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_enc_updt.c b/lib_enc/core_enc_updt.c index 95f1c67b6..4533af002 100644 --- a/lib_enc/core_enc_updt.c +++ b/lib_enc/core_enc_updt.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c index 67c7a552f..08789dbde 100644 --- a/lib_enc/core_switching_enc.c +++ b/lib_enc/core_switching_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/corr_xh.c b/lib_enc/corr_xh.c index 68195a7ec..9fd3cb8a2 100644 --- a/lib_enc/corr_xh.c +++ b/lib_enc/corr_xh.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/decision_matrix_enc.c b/lib_enc/decision_matrix_enc.c index 34d9fd39d..5e0c266ca 100644 --- a/lib_enc/decision_matrix_enc.c +++ b/lib_enc/decision_matrix_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/detect_transient.c b/lib_enc/detect_transient.c index 4922b9e4c..c2bbde080 100644 --- a/lib_enc/detect_transient.c +++ b/lib_enc/detect_transient.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/detect_transient_fx.c b/lib_enc/detect_transient_fx.c index a3dba9d27..51f1cb476 100644 --- a/lib_enc/detect_transient_fx.c +++ b/lib_enc/detect_transient_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/diffcod.c b/lib_enc/diffcod.c index 3c07227e2..9f6bb4283 100644 --- a/lib_enc/diffcod.c +++ b/lib_enc/diffcod.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c index fd519a119..726508b0c 100644 --- a/lib_enc/dtx.c +++ b/lib_enc/dtx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_acelp.c b/lib_enc/enc_acelp.c index e1517cb69..bf5688ef1 100644 --- a/lib_enc/enc_acelp.c +++ b/lib_enc/enc_acelp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_acelp_tcx_main.c b/lib_enc/enc_acelp_tcx_main.c index fc894ba6c..d029c2fa8 100644 --- a/lib_enc/enc_acelp_tcx_main.c +++ b/lib_enc/enc_acelp_tcx_main.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_acelpx.c b/lib_enc/enc_acelpx.c index 661cc4b7b..f6e2b0379 100644 --- a/lib_enc/enc_acelpx.c +++ b/lib_enc/enc_acelpx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_amr_wb.c b/lib_enc/enc_amr_wb.c index 0fe8682da..c899b52ff 100644 --- a/lib_enc/enc_amr_wb.c +++ b/lib_enc/enc_amr_wb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_gain.c b/lib_enc/enc_gain.c index a82d2075a..491d5d2f3 100644 --- a/lib_enc/enc_gain.c +++ b/lib_enc/enc_gain.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_gen_voic.c b/lib_enc/enc_gen_voic.c index 0fe8682da..c899b52ff 100644 --- a/lib_enc/enc_gen_voic.c +++ b/lib_enc/enc_gen_voic.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 6c6ade036..554521732 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 5fdc5e6f0..3b1b81730 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/find_tilt.c b/lib_enc/find_tilt.c index 952805169..efd1b44d2 100644 --- a/lib_enc/find_tilt.c +++ b/lib_enc/find_tilt.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/find_uv.c b/lib_enc/find_uv.c index 2e14972c7..c6ae02a76 100644 --- a/lib_enc/find_uv.c +++ b/lib_enc/find_uv.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/find_wsp.c b/lib_enc/find_wsp.c index 00729bde0..89b77d351 100644 --- a/lib_enc/find_wsp.c +++ b/lib_enc/find_wsp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/frame_spec_dif_cor_rate.c b/lib_enc/frame_spec_dif_cor_rate.c index 09ecb0cc8..9185f37bd 100644 --- a/lib_enc/frame_spec_dif_cor_rate.c +++ b/lib_enc/frame_spec_dif_cor_rate.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/gain_enc.c b/lib_enc/gain_enc.c index bd3da322a..276e20738 100644 --- a/lib_enc/gain_enc.c +++ b/lib_enc/gain_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/gp_clip_fx.c b/lib_enc/gp_clip_fx.c index b4845a1a4..d7614473b 100644 --- a/lib_enc/gp_clip_fx.c +++ b/lib_enc/gp_clip_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/gs_enc.c b/lib_enc/gs_enc.c index 4468194be..900c381bf 100644 --- a/lib_enc/gs_enc.c +++ b/lib_enc/gs_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/guided_plc_enc.c b/lib_enc/guided_plc_enc.c index c10866a49..6c0e9022d 100644 --- a/lib_enc/guided_plc_enc.c +++ b/lib_enc/guided_plc_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hf_cod_amrwb.c b/lib_enc/hf_cod_amrwb.c index d1de09bc7..7ea6e47a5 100644 --- a/lib_enc/hf_cod_amrwb.c +++ b/lib_enc/hf_cod_amrwb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hq_classifier_enc.c b/lib_enc/hq_classifier_enc.c index 273cba75c..634f42971 100644 --- a/lib_enc/hq_classifier_enc.c +++ b/lib_enc/hq_classifier_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c index dc29b801b..a3a75cc95 100644 --- a/lib_enc/hq_core_enc.c +++ b/lib_enc/hq_core_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hq_env_enc.c b/lib_enc/hq_env_enc.c index 4e446e1c5..e8859676c 100644 --- a/lib_enc/hq_env_enc.c +++ b/lib_enc/hq_env_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hq_hr_enc.c b/lib_enc/hq_hr_enc.c index f73925978..42f661f6e 100644 --- a/lib_enc/hq_hr_enc.c +++ b/lib_enc/hq_hr_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hq_lr_enc.c b/lib_enc/hq_lr_enc.c index b184c5ac6..d0941db74 100644 --- a/lib_enc/hq_lr_enc.c +++ b/lib_enc/hq_lr_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/hvq_enc.c b/lib_enc/hvq_enc.c index b693d838b..adf7751a1 100644 --- a/lib_enc/hvq_enc.c +++ b/lib_enc/hvq_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 0ce087508..89dc1bf30 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index e9ef96e1a..192d7e597 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 7ce9f8ff5..8448843dc 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/inov_enc.c b/lib_enc/inov_enc.c index 754e202e5..08f1e768f 100644 --- a/lib_enc/inov_enc.c +++ b/lib_enc/inov_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/isf_enc_amr_wb.c b/lib_enc/isf_enc_amr_wb.c index 08af81cf8..7bb7c56fe 100644 --- a/lib_enc/isf_enc_amr_wb.c +++ b/lib_enc/isf_enc_amr_wb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/isf_enc_amr_wb_fx.c b/lib_enc/isf_enc_amr_wb_fx.c index 047a7409c..4851ed155 100644 --- a/lib_enc/isf_enc_amr_wb_fx.c +++ b/lib_enc/isf_enc_amr_wb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index dcc55f5ad..649c5bae5 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 0c7fe9094..6dc3d10ec 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 31b14ed10..96a3e110f 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 6ab82420f..c18134e0a 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index 847cdd0f6..b1d819f5c 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index ea42591ca..42305ec19 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index 27da71324..280443fc5 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 017aa2904..ec55850fd 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index a7fb71461..2bab65c42 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index 5c19d8e02..95a114b67 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c index da4826776..0dd0f5aa1 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index f52bdadb4..5460ccb12 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 7a499ce67..7ad7d40e4 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc.c index f098dc0e4..95b37435c 100644 --- a/lib_enc/ivas_ism_dtx_enc.c +++ b/lib_enc/ivas_ism_dtx_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 3dc12da91..7f41b27a8 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 32138faba..68391eabd 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 5e91a30fb..bef6912bd 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc.c index e219e8b37..8ccb59c9c 100644 --- a/lib_enc/ivas_lfe_enc.c +++ b/lib_enc/ivas_lfe_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 583a37006..f4fe68c59 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 43162f6de..859ce3a9b 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 61f817b2f..c94946b2d 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index ad52915d1..3687df381 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 52fd554d8..0ed03eb1c 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 5510f1eb1..dbced19fd 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 654c00db4..ae561c0d0 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 4997a6715..6f1d4117d 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index a9ebf8ec3..f09d4513d 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index 9d7c92dd0..ab8252854 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_pca_enc.c b/lib_enc/ivas_pca_enc.c index 4e133567c..8b61cb6c8 100644 --- a/lib_enc/ivas_pca_enc.c +++ b/lib_enc/ivas_pca_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 00b62f2f6..387f82463 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_qspherical_enc.c b/lib_enc/ivas_qspherical_enc.c index 4bf3650e6..eb60d4849 100644 --- a/lib_enc/ivas_qspherical_enc.c +++ b/lib_enc/ivas_qspherical_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_range_uni_enc.c b/lib_enc/ivas_range_uni_enc.c index a93f470f5..35ecad69c 100644 --- a/lib_enc/ivas_range_uni_enc.c +++ b/lib_enc/ivas_range_uni_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 501965bfa..0d0941cc4 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_rom_enc_fx.c b/lib_enc/ivas_rom_enc_fx.c index e4361b933..b26972b8a 100644 --- a/lib_enc/ivas_rom_enc_fx.c +++ b/lib_enc/ivas_rom_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index ef76d67c9..b247900a0 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index dd9cb61a0..1760e757f 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index 5566c1547..8f93c4d76 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index e1b3905c2..a0c5be842 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 1d367dd52..8b23eca5f 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index db72219cd..c7343fe4e 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_adapt_GR_enc.c b/lib_enc/ivas_stereo_adapt_GR_enc.c index a47029be4..62fed34f7 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index 4913f2545..e83bccd09 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_cng_enc.c b/lib_enc/ivas_stereo_cng_enc.c index 92add6cdd..4727cd188 100644 --- a/lib_enc/ivas_stereo_cng_enc.c +++ b/lib_enc/ivas_stereo_cng_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index d532a9af1..cf246368f 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c index f65b5114c..70a467232 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd.c index e64e5a1ec..dd7f575b7 100644 --- a/lib_enc/ivas_stereo_dft_td_itd.c +++ b/lib_enc/ivas_stereo_dft_td_itd.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index be470e2cf..7b0e7df62 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_eclvq_enc.c b/lib_enc/ivas_stereo_eclvq_enc.c index 118baaa69..cd0e6fe2d 100644 --- a/lib_enc/ivas_stereo_eclvq_enc.c +++ b/lib_enc/ivas_stereo_eclvq_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 5b79f416a..0235630d2 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index 9cf899bcb..8c2d136b7 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index ffc671d41..e85c01db2 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_mdct_igf_enc.c b/lib_enc/ivas_stereo_mdct_igf_enc.c index 190255fd9..38be1a6a4 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc.c index 4c73ba2e7..9c729709d 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index a1e5592e5..786c45cb3 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index 5bc62bc8b..79e05bf09 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc.c index 02bdd1561..304754fc3 100644 --- a/lib_enc/ivas_stereo_td_enc.c +++ b/lib_enc/ivas_stereo_td_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index f072e5436..bc6df4f56 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index d09134951..e5514b7eb 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/lead_indexing.c b/lib_enc/lead_indexing.c index d20e6a703..3a6a477b9 100644 --- a/lib_enc/lead_indexing.c +++ b/lib_enc/lead_indexing.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 319ebdf87..9a82fc05e 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index c23f56df9..176e35236 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/long_enr.c b/lib_enc/long_enr.c index aba21a1fe..31ab8f019 100644 --- a/lib_enc/long_enr.c +++ b/lib_enc/long_enr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/lp_exc_e.c b/lib_enc/lp_exc_e.c index 7d23dd6f7..5c3581f4f 100644 --- a/lib_enc/lp_exc_e.c +++ b/lib_enc/lp_exc_e.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/lsf_enc.c b/lib_enc/lsf_enc.c index 06e686f81..3ac84b28e 100644 --- a/lib_enc/lsf_enc.c +++ b/lib_enc/lsf_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 6ee7bb9c3..830f1ecd6 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/ltd_stable.c b/lib_enc/ltd_stable.c index 825401325..0e2004abf 100644 --- a/lib_enc/ltd_stable.c +++ b/lib_enc/ltd_stable.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/mdct_classifier.c b/lib_enc/mdct_classifier.c index b157e0ff9..047f02355 100644 --- a/lib_enc/mdct_classifier.c +++ b/lib_enc/mdct_classifier.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/mdct_selector.c b/lib_enc/mdct_selector.c index 9d6f499db..952043e3a 100644 --- a/lib_enc/mdct_selector.c +++ b/lib_enc/mdct_selector.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/mslvq_enc.c b/lib_enc/mslvq_enc.c index 9f95d696c..a49d435c3 100644 --- a/lib_enc/mslvq_enc.c +++ b/lib_enc/mslvq_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/multi_harm.c b/lib_enc/multi_harm.c index 7d23dd6f7..5c3581f4f 100644 --- a/lib_enc/multi_harm.c +++ b/lib_enc/multi_harm.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/nelp_enc.c b/lib_enc/nelp_enc.c index d1de09bc7..7ea6e47a5 100644 --- a/lib_enc/nelp_enc.c +++ b/lib_enc/nelp_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index a0ed2f523..3bd8e340d 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/pit_enc.c b/lib_enc/pit_enc.c index 224203cb0..5bde0f450 100644 --- a/lib_enc/pit_enc.c +++ b/lib_enc/pit_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/pitch_ol.c b/lib_enc/pitch_ol.c index 65b32d74c..0853fd9fd 100644 --- a/lib_enc/pitch_ol.c +++ b/lib_enc/pitch_ol.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/pitch_ol2.c b/lib_enc/pitch_ol2.c index 1ce646476..dc77e0dfa 100644 --- a/lib_enc/pitch_ol2.c +++ b/lib_enc/pitch_ol2.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/plc_enc_ext.c b/lib_enc/plc_enc_ext.c index 404ee401e..17c76dee6 100644 --- a/lib_enc/plc_enc_ext.c +++ b/lib_enc/plc_enc_ext.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 711d7069a..99483ebb9 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/rom_enc.c b/lib_enc/rom_enc.c index e1f2442bc..abdb1249d 100644 --- a/lib_enc/rom_enc.c +++ b/lib_enc/rom_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/rom_enc.h b/lib_enc/rom_enc.h index bad6e9f86..35fd3027d 100644 --- a/lib_enc/rom_enc.h +++ b/lib_enc/rom_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/setmodeindex.c b/lib_enc/setmodeindex.c index 1cc6168c3..b7ff1d2b6 100644 --- a/lib_enc/setmodeindex.c +++ b/lib_enc/setmodeindex.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 0fa9aeb88..d012c5a96 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index c324b9ac9..acd984509 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index 018ac1f0e..db4e51127 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec.c index 193648a4e..4a4c1ff89 100644 --- a/lib_rend/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec.c @@ -1,7 +1,7 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 12bc769fa..67d47e89d 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana.c index f2bc10e6a..06744dc6e 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 71ecb5106..e2ab6cd3e 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index 1788536e4..01fd1e610 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_rend/ivas_dirac_onsets_dec.c index f53f41404..c6119cc34 100644 --- a/lib_rend/ivas_dirac_onsets_dec.c +++ b/lib_rend/ivas_dirac_onsets_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 866badda0..0fe7cdef1 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index cafd70966..b563d4399 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 0bf3b85a4..8947809d1 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf.c index ab69784c7..506d76efd 100644 --- a/lib_rend/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 17211d1c6..595573016 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge.c index 9e6807b00..e8d06d0bb 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index 106ca56f4..0b0c8ffeb 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index f323b615d..8b689b94b 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 4d5ad355a..ab09a82b5 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 5616da037..a328a51bf 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 8c6fd8663..caa393355 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index f01f66797..af60f7746 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 5e4d9d6ac..c8efd80ad 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index 26f0cefcf..7d6129d20 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index a3e833455..bb6f26346 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 359bea7e6..980e5ca17 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 4afd38886..b642e05d7 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index c5d118858..e5e8cdb56 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index d35a6c005..792b485a7 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index c70e325e3..9e621ce83 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line.c index c8db27955..3eeb4ede4 100644 --- a/lib_rend/ivas_reverb_delay_line.c +++ b/lib_rend/ivas_reverb_delay_line.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reverb_fft_filter.c b/lib_rend/ivas_reverb_fft_filter.c index 79cb544b2..3befcde91 100644 --- a/lib_rend/ivas_reverb_fft_filter.c +++ b/lib_rend/ivas_reverb_fft_filter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design.c index b1499839c..428cf3353 100644 --- a/lib_rend/ivas_reverb_filter_design.c +++ b/lib_rend/ivas_reverb_filter_design.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter.c index 7049fa580..217e16dd8 100644 --- a/lib_rend/ivas_reverb_iir_filter.c +++ b/lib_rend/ivas_reverb_iir_filter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils.c index ddb95aaf0..46ef576a8 100644 --- a/lib_rend/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c index f6921bc92..cee2a9753 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.h b/lib_rend/ivas_rom_TdBinauralRenderer.h index 7cdd84d6d..89d86f112 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.h +++ b/lib_rend/ivas_rom_TdBinauralRenderer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer.c index fa4cbd7aa..e7dbbae70 100644 --- a/lib_rend/ivas_rom_binauralRenderer.c +++ b/lib_rend/ivas_rom_binauralRenderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_binauralRenderer.h b/lib_rend/ivas_rom_binauralRenderer.h index 8e7bd4a55..4b1428ac8 100644 --- a/lib_rend/ivas_rom_binauralRenderer.h +++ b/lib_rend/ivas_rom_binauralRenderer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_binaural_crend_head.c b/lib_rend/ivas_rom_binaural_crend_head.c index 60925a31f..068ce0927 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.c +++ b/lib_rend/ivas_rom_binaural_crend_head.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_binaural_crend_head.h b/lib_rend/ivas_rom_binaural_crend_head.h index 0004a05d7..bc0d3cd17 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.h +++ b/lib_rend/ivas_rom_binaural_crend_head.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index d99a4ad76..54940355c 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index c80fab8ce..e7d6c6293 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 758d787b1..39720469b 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 0309cf61f..7c7a20223 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index 6e27da202..9ed0d8d33 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 38b2fe524..44207c79a 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_td_decorr.c b/lib_rend/ivas_td_decorr.c index c4507aae1..af51a7820 100644 --- a/lib_rend/ivas_td_decorr.c +++ b/lib_rend/ivas_td_decorr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/ivas_vbap.c b/lib_rend/ivas_vbap.c index 24465c3e7..e1a6868d8 100644 --- a/lib_rend/ivas_vbap.c +++ b/lib_rend/ivas_vbap.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 86eea321b..a1c551405 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 74e6070b5..22ed7ed65 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index ff9a9b33b..ca5e6e496 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/audio_file_reader.h b/lib_util/audio_file_reader.h index 185d8c077..571c1e765 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/audio_file_writer.c b/lib_util/audio_file_writer.c index 0f2f5335d..fb7a64c42 100644 --- a/lib_util/audio_file_writer.c +++ b/lib_util/audio_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/audio_file_writer.h b/lib_util/audio_file_writer.h index 0b1c3315f..2622992ce 100644 --- a/lib_util/audio_file_writer.h +++ b/lib_util/audio_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/bitstream_reader.c b/lib_util/bitstream_reader.c index 841d6e1de..2bd6f46aa 100644 --- a/lib_util/bitstream_reader.c +++ b/lib_util/bitstream_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/bitstream_reader.h b/lib_util/bitstream_reader.h index e33de4897..fb6f9f9b9 100644 --- a/lib_util/bitstream_reader.h +++ b/lib_util/bitstream_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/bitstream_writer.c b/lib_util/bitstream_writer.c index d19a05898..8c4b64cd4 100644 --- a/lib_util/bitstream_writer.c +++ b/lib_util/bitstream_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/bitstream_writer.h b/lib_util/bitstream_writer.h index b0fab9e44..f3efd4ddf 100644 --- a/lib_util/bitstream_writer.h +++ b/lib_util/bitstream_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/cmdl_tools.c b/lib_util/cmdl_tools.c index 337583ab9..bec772ce4 100644 --- a/lib_util/cmdl_tools.c +++ b/lib_util/cmdl_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/cmdl_tools.h b/lib_util/cmdl_tools.h index 7c3c05ba1..327acb93d 100644 --- a/lib_util/cmdl_tools.h +++ b/lib_util/cmdl_tools.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/cmdln_parser.c b/lib_util/cmdln_parser.c index fe2c1b1db..b2c8f85bc 100644 --- a/lib_util/cmdln_parser.c +++ b/lib_util/cmdln_parser.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/cmdln_parser.h b/lib_util/cmdln_parser.h index 4721d968f..2627d5566 100644 --- a/lib_util/cmdln_parser.h +++ b/lib_util/cmdln_parser.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/evs_rtp_payload.c b/lib_util/evs_rtp_payload.c index c122716f3..a0c514bad 100644 --- a/lib_util/evs_rtp_payload.c +++ b/lib_util/evs_rtp_payload.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/evs_rtp_payload.h b/lib_util/evs_rtp_payload.h index 004ecf79b..357d98557 100644 --- a/lib_util/evs_rtp_payload.h +++ b/lib_util/evs_rtp_payload.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/g192.c b/lib_util/g192.c index bec637464..d6c6ec475 100644 --- a/lib_util/g192.c +++ b/lib_util/g192.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/g192.h b/lib_util/g192.h index 6d6104d45..8014f5236 100644 --- a/lib_util/g192.h +++ b/lib_util/g192.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 3410ada71..8920e6780 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/hrtf_file_reader.h b/lib_util/hrtf_file_reader.h index e222fd4d1..104cc5c7a 100644 --- a/lib_util/hrtf_file_reader.h +++ b/lib_util/hrtf_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/ism_file_reader.c b/lib_util/ism_file_reader.c index f6f020639..f3d782aeb 100644 --- a/lib_util/ism_file_reader.c +++ b/lib_util/ism_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/ism_file_reader.h b/lib_util/ism_file_reader.h index 886ebb34b..c785cc294 100644 --- a/lib_util/ism_file_reader.h +++ b/lib_util/ism_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/ism_file_writer.c b/lib_util/ism_file_writer.c index 093414293..94bab6dd2 100644 --- a/lib_util/ism_file_writer.c +++ b/lib_util/ism_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/ism_file_writer.h b/lib_util/ism_file_writer.h index 34cc4e711..6bf1a3e31 100644 --- a/lib_util/ism_file_writer.h +++ b/lib_util/ism_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/jbm_file_reader.c b/lib_util/jbm_file_reader.c index 01ca956f7..b657ab789 100644 --- a/lib_util/jbm_file_reader.c +++ b/lib_util/jbm_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/jbm_file_reader.h b/lib_util/jbm_file_reader.h index 379506ee6..e824e1eee 100644 --- a/lib_util/jbm_file_reader.h +++ b/lib_util/jbm_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/jbm_file_writer.c b/lib_util/jbm_file_writer.c index 6e26fe703..76a5a67d2 100644 --- a/lib_util/jbm_file_writer.c +++ b/lib_util/jbm_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/jbm_file_writer.h b/lib_util/jbm_file_writer.h index fad5ec81e..aca768a1a 100644 --- a/lib_util/jbm_file_writer.h +++ b/lib_util/jbm_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 90b734d07..01d1f0307 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/ls_custom_file_reader.h b/lib_util/ls_custom_file_reader.h index b5def3376..46b20a4ff 100644 --- a/lib_util/ls_custom_file_reader.h +++ b/lib_util/ls_custom_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 5b8d759c2..9351d9bc9 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/masa_file_reader.h b/lib_util/masa_file_reader.h index de55035c7..7510598c3 100644 --- a/lib_util/masa_file_reader.h +++ b/lib_util/masa_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/masa_file_writer.c b/lib_util/masa_file_writer.c index 8bf55ba86..0939d0829 100644 --- a/lib_util/masa_file_writer.c +++ b/lib_util/masa_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/masa_file_writer.h b/lib_util/masa_file_writer.h index d7f53d4b6..2d476e28f 100644 --- a/lib_util/masa_file_writer.h +++ b/lib_util/masa_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/mime_io.c b/lib_util/mime_io.c index 8a6262953..782f818d0 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/mime_io.h b/lib_util/mime_io.h index 6ce5070c4..dbd21c9c7 100644 --- a/lib_util/mime_io.h +++ b/lib_util/mime_io.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 692f8c58d..b6122ec0f 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 445ced79a..5edf73ded 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 987d40c85..468f80765 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/rotation_file_reader.h b/lib_util/rotation_file_reader.h index 3f98ea5b0..8d6206bd6 100644 --- a/lib_util/rotation_file_reader.h +++ b/lib_util/rotation_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/rtpdump.c b/lib_util/rtpdump.c index 9f8784947..e3eb4c1f4 100644 --- a/lib_util/rtpdump.c +++ b/lib_util/rtpdump.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/rtpdump.h b/lib_util/rtpdump.h index b97ec97d8..5b8b31e8d 100644 --- a/lib_util/rtpdump.h +++ b/lib_util/rtpdump.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/test_fft.c b/lib_util/test_fft.c index 5c0e2b33f..1b52fe351 100644 --- a/lib_util/test_fft.c +++ b/lib_util/test_fft.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/test_fft.h b/lib_util/test_fft.h index 7a3567f89..6c9629090 100644 --- a/lib_util/test_fft.h +++ b/lib_util/test_fft.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/test_mdct.c b/lib_util/test_mdct.c index 91095df38..69d83588d 100644 --- a/lib_util/test_mdct.c +++ b/lib_util/test_mdct.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/tinywavein_c.h b/lib_util/tinywavein_c.h index 0fd1b7a65..b86d97c96 100644 --- a/lib_util/tinywavein_c.h +++ b/lib_util/tinywavein_c.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/tinywaveout_c.h b/lib_util/tinywaveout_c.h index 9b11e325a..693beccf9 100644 --- a/lib_util/tinywaveout_c.h +++ b/lib_util/tinywaveout_c.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/vector3_pair_file_reader.c b/lib_util/vector3_pair_file_reader.c index 380e69e27..ec14ebc71 100644 --- a/lib_util/vector3_pair_file_reader.c +++ b/lib_util/vector3_pair_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/lib_util/vector3_pair_file_reader.h b/lib_util/vector3_pair_file_reader.h index 3255fb315..6515d32d5 100644 --- a/lib_util/vector3_pair_file_reader.h +++ b/lib_util/vector3_pair_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 diff --git a/readme.txt b/readme.txt index 25275a795..9b1ab852d 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 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 -- GitLab From 0cfe1705750f642dcf30a2e96e7d737396a55504 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Feb 2025 19:09:18 +0530 Subject: [PATCH 0249/1221] Fix for 3GPP issue 1291: Wrong use of imult1616() in ACELP rescaling - 2 Correction for L_frame=320 --- lib_dec/acelp_core_dec_ivas_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index e9e4625ce..712a3339f 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -749,7 +749,7 @@ ivas_error acelp_core_dec_ivas_fx( { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, #ifdef FIX_ISSUE_1291 - shr( imult1616( st->L_frame, HIBND_ACB_L_FAC_Q1 ), 1 ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); + L_FRAME32k, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); #else imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); #endif @@ -803,7 +803,7 @@ ivas_error acelp_core_dec_ivas_fx( Copy( syn1_fx + st->L_frame - L_SYN_MEM_CLAS_ESTIM, st->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); /* save and delay synthesis to be used by SWB BWE */ - Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn + Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn -> Q(-1) IF( st->hBWE_FD != NULL ) { #ifdef FIX_ISSUE_1290 -- GitLab From 2b317eb444c38f6676598ef15e37554784883a2f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Feb 2025 15:20:53 +0100 Subject: [PATCH 0250/1221] activated inDev macros --- lib_com/options.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index be20cf739..8d464ccef 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -//#define WMOPS /* Activate complexity and memory counters */ +#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -172,7 +172,8 @@ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ -#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ -#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ +#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ // -1.5 WMOPS +#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ // -1 WMOPS + #endif -- GitLab From df4ab5e6d98ccf2250ef0b6daa10b9b7c1f0ec91 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 25 Feb 2025 15:39:37 +0100 Subject: [PATCH 0251/1221] replaced the costly basop_util_mant2exp() function with a 64 bit addtion. there is a potential overflow which needs to be adressed first. --- lib_com/ivas_prot_fx.h | 6 +++++ lib_com/ivas_tools.c | 39 +++++++++++++++++++++++++++++++ lib_enc/speech_music_classif_fx.c | 23 ++++++------------ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 1682c255b..1b6e7be85 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4714,6 +4714,12 @@ Word32 dot_product_cholesky_fixed( const Word16 exp_A, Word16 *exp_sum ); +Word64 dot_product_cholesky_fixed64( + const Word32 *x, /* i : vector x */ + const Word32 *A, /* i : Cholesky matrix A */ + const Word16 N /* i : vector & matrix size */ +); + void v_mult_mat_fx( Word32 *y_fx, /* o : the product x*A */ Word16 *y_q_fx, diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index d6210dfc7..9f1a42f29 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -642,6 +642,45 @@ Word32 dot_product_cholesky_fixed( return suma; } +/*---------------------------------------------------------------------* + * dot_product_cholesky() + * + * Calculates dot product of type x'*A*A'*x, where x is column vector of size m, + * and A is a Cholesky decomposition of some Hermitian matrix S whose size is m*m. + * Therefore, S=A*A' where A is upper triangular matrix of size (m*m+m)/2 (zeros ommitted, column-wise) + *---------------------------------------------------------------------*/ + +/*! r: the dot product x'*A*A'*x */ +Word64 dot_product_cholesky_fixed64( + const Word32 *x, /* i : vector x Q31 - exp_x*/ + const Word32 *A, /* i : Cholesky matrix A Q31 - exp_A*/ + const Word16 N /* i : vector & matrix size Q0*/ +) +{ + Word16 i, j; + Word64 suma, tmp_sum; + Word32 mul; + const Word32 *pt_x, *pt_A; + pt_A = A; + suma = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + tmp_sum = 0; + move32(); + pt_x = x; + + FOR( j = 0; j <= i; j++ ) + { + mul = Mpy_32_32( *pt_x++, *pt_A++ ); + tmp_sum = W_add( tmp_sum, W_deposit32_l( mul ) ); + } + + suma = W_mac_32_32( suma, tmp_sum, tmp_sum ); // TODO: make sure that this does not overflow. + } + + return suma; +} void v_mult_mat_fixed( Word32 *y, /* o : the product x*A Qx - guardbits*/ const Word32 *x, /* i : vector x Qx*/ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 295cff8a1..34744131f 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1683,10 +1683,8 @@ Word16 ivas_smc_gmm_fx( Word16 flag_odv; Word32 lps_fx, lpm_fx, lpn_fx; Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; - Word32 lprob_fx; - Word16 lprob_exp = 0; + Word64 wprob_fx; Word32 fvm_fx[N_PCA_COEF]; - Word16 fvm_exp = 0; Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; @@ -2273,23 +2271,16 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - fvm_exp = sub( 31, Qfact_FV ); - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_shr( wprob_fx, Q18 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_shr( wprob_fx, Q18 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_shr( wprob_fx, Q18 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); } -- GitLab From 832751e64a46f710d9c53d326d0b75994b6ce0e1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Feb 2025 12:41:22 +0530 Subject: [PATCH 0252/1221] Modifications in acelp encode sub-function call stack, bug fixes and saturation removal in GenShapedSHBExcitation_enc --- lib_com/prot_fx.h | 45 +++--- lib_com/swb_tbe_com_fx.c | 213 ++++++++++++----------------- lib_enc/acelp_core_switch_enc_fx.c | 10 +- lib_enc/analy_sp_fx.c | 46 +++---- lib_enc/core_enc_init.c | 22 ++- lib_enc/core_enc_reconf.c | 7 +- lib_enc/core_enc_switch.c | 2 +- lib_enc/enc_gen_voic_fx.c | 16 +-- lib_enc/enc_pit_exc_fx.c | 14 +- lib_enc/enc_tran_fx.c | 5 +- lib_enc/enc_uv_fx.c | 10 +- lib_enc/find_tar_fx.c | 82 +++++------ lib_enc/ivas_td_low_rate_enc.c | 17 ++- lib_enc/multi_harm_fx.c | 2 +- lib_enc/pit_enc_fx.c | 176 ++++++++++++------------ lib_enc/prot_fx_enc.h | 135 +++++++++--------- lib_enc/swb_tbe_enc_fx.c | 14 +- 17 files changed, 385 insertions(+), 431 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index cf7072cf5..485ddb33d 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3035,7 +3035,7 @@ void GenShapedSHBExcitation_fx( void GenShapedSHBExcitation_ivas_enc_fx( Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc_fb */ Word32 *mem_csfilt, /* i/o: memory */ Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ Word16 *state_lpc_syn, /* i/o: memory */ @@ -3051,33 +3051,30 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ Word16 *shb_res, Word16 *vf_ind, - const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ - Word16 fb_state_lpc_syn[], /* i/o: memory */ - Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ Word16 *Q_bwe_exc, Word16 *Q_bwe_exc_fb, const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, - const Word16 prev_bfi -#if 1 // def ADD_IVAS_TBE_CODE - , /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + const Word16 prev_bfi, + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ Word16 Q_EnvSHBres_4k, - Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -#endif + Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ ); void GenShapedSHBExcitation_ivas_dec_fx( @@ -11113,7 +11110,7 @@ void init_coder_ace_plus_ivas_fx( ); void core_coder_reconfig_ivas_fx( - Encoder_State *st ); + Encoder_State *st, const int32_t last_total_brate ); void core_coder_mode_switch_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 92271c1f1..6cdf1185a 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -2879,7 +2879,7 @@ void GenShapedSHBExcitation_fx( void GenShapedSHBExcitation_ivas_enc_fx( Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc_fb */ Word32 *mem_csfilt, /* i/o: memory */ Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ Word16 *state_lpc_syn, /* i/o: memory */ @@ -2901,24 +2901,24 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 *Q_bwe_exc, Word16 *Q_bwe_exc_fb, const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ - const Word32 bitrate, /* i : bitrate */ - const Word16 prev_bfi, /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, + const Word16 prev_bfi, + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ Word16 Q_EnvSHBres_4k, - Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling Q0 */ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling Q0 */ + Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ ) { Word16 i, j, k; @@ -2963,13 +2963,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word32 White_exc16k_32[L_FRAME16k]; Word16 White_exc16k_tmp[L_FRAME16k]; Word16 prev_Q_bwe_exc_fb; - Word16 chk1, chk2; - chk1 = 0; - chk2 = 0; - move16(); - move16(); -#if 1 // def ADD_IVAS_TBE_CODE Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; Word16 cbsize; Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; @@ -2984,7 +2978,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( mix_factor = 0; /* Q15 */ move16(); -#endif + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); FOR( i = 0; i < L_FRAME32k; i = i + 2 ) @@ -3016,11 +3010,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* i: exc16k in Q_bwe_exc */ /* o: exc16kWhtnd in Q_bwe_exc */ -#if 1 // def ADD_IVAS_TBE_CODE IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { temp2 = 0; move16(); @@ -3041,25 +3031,21 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* Estimate pow1 associated with Low band nonlinear extended excitation */ /* pow1=0.00001f */ tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); - pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ + W_tmp = W_shl( 21475 /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ FOR( k = 0; k < L_FRAME16k; k++ ) { /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ excTmp2[k] = abs_s( exc16kWhtnd[k] ); move16(); - chk1 = s_or( chk1, exc16kWhtnd[k] ); /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ - pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ + W_tmp = W_mac_16_16( W_tmp, exc16kWhtnd[k], exc16kWhtnd[k] ); // 2*Q_bwe_exc+1 } - Q_pow1 = shl( *Q_bwe_exc, 1 ); + exp = W_norm( W_tmp ); + pow1 = W_extract_h( W_shl( W_tmp, exp ) ); // 2*Q_bwe_exc+1+exp-32 = // tmp+exp + Q_pow1 = add( tmp, exp ); - test(); -#if 1 // ADD_IVAS_TBE_CODE IF( flag_ACELP16k == 0 ) -#else - IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) -#endif { /* varEnvShape = mean_fx(voice_factors, 4); */ /* unroll the loop */ @@ -3105,12 +3091,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( test(); test(); test(); -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#else - IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#endif { /* pre-init smoothing filter to avoid energy drop outs */ L_tmp = L_mult( excTmp2[0], 1638 ); @@ -3137,7 +3119,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); move32(); } -#if 1 // def ADD_IVAS_TBE_CODE + IF( MSFlag > 0 ) { // varEnvShape = 0.995f; @@ -3196,7 +3178,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } ELSE -#endif { /* Track the low band envelope */ L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); @@ -3222,7 +3203,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); move32(); } -#if 1 // def ADD_IVAS_TBE_CODE + test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { @@ -3261,7 +3242,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } ELSE -#endif { /* create a random excitation - Reuse exc16k memory */ create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 @@ -3282,36 +3262,32 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* calculate pow22 */ /* pow22=0.00001f */ tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - Word64 sum = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + W_tmp = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { /* White_exc16k[k] *= excNoisyEnv[k]; */ White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 move16(); - chk2 = s_or( chk2, White_exc16k[k] ); /* i: excNoisyEnv in (Q_excTmp2) */ /* i: White_exc16k in Q6 */ /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ + W_tmp = W_mac0_16_16( W_tmp, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ } - Q_pow22 = W_norm( sum ); - pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = W_norm( W_tmp ); + pow22 = W_extract_h( W_shl( W_tmp, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); } -#if 1 // def ADD_IVAS_TBE_CODE flag_plosive = 0; move16(); test(); test(); test(); IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ { @@ -3545,7 +3521,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( ELSE /* decoder side */ { test(); -#if 1 // def ADD_IVAS_TBE_CODE IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { IF( *vf_ind == 0 ) @@ -3563,7 +3538,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } ELSE -#endif { /* *vf_ind is an integer scale by 0.125f*/ tmp = shl( *vf_ind, ( 15 - 3 ) ); @@ -3576,10 +3550,9 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } } -#if 1 // def ADD_IVAS_TBE_CODE + test(); IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) -#endif { voice_factors[0] = mult_r( voice_factors[0], tmp2 ); move16(); @@ -3593,103 +3566,94 @@ void GenShapedSHBExcitation_ivas_enc_fx( move16(); } } -#if 1 // def ADD_IVAS_TBE_CODE - Scale_sig( White_exc16k, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); // Q_bwe_exc + test(); IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) { /* save buffers for IC-BWE */ // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); - Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); + Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); // Q_bwe_exc *nlExc16k_e = sub( 15, *Q_bwe_exc ); move16(); + // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); - /*Word16 temp_fac = divide3232(L_shr(pow1, Q_pow1), pow22); - Word16 temp_fac_exp = 0; - temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - Word16 temp_fac = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 - // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); + Word16 temp_fac = round_fx_sat( L_tmp ); // Q15-exp + FOR( k = 0; k < L_FRAME16k; k++ ) { - mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); // Q_bwe_exc + mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); // Q_White_exc16k+15-exp-15 = Q_White_exc16k-exp move16(); } - *mixExc16k_e = sub( 15, *Q_bwe_exc ); + *mixExc16k_e = sub( 15, sub( Q_White_exc16k, exp ) ); move16(); } -#endif - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_FB[k] = White_exc16k[k]; /* Q_bwe_exc */ - move16(); - } + Copy( White_exc16k, White_exc16k_FB, L_FRAME16k ); // Q_White_exc16k prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; + *Q_bwe_exc_fb = Q_White_exc16k; move16(); - *Q_bwe_exc_fb = *Q_bwe_exc; move16(); - deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc) */ - /* i: tbe_demph (Q_bwe_exc) */ + Word16 tbe_demph_fx = shl_sat( *tbe_demph, sub( Q_White_exc16k, *Q_bwe_exc ) ); // Q_White_exc16k + + deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, &tbe_demph_fx ); + /* i/o: White_exc16k (Q_White_exc16k) */ + /* i: tbe_demph_fx (Q_White_exc16k) */ + *tbe_demph = shr_sat( tbe_demph_fx, sub( Q_White_exc16k, *Q_bwe_exc ) ); + move16(); -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { IF( !flag_plosive ) /* use only LB excitation in case of plosives */ { /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ - // old_scale = (float)sqrt(*prev_pow_exc16kWhtnd / pow1); - // old_scale = divide3232(*prev_pow_exc16kWhtnd, pow1); // exp = Q15 - (Q_pow1) - // Word16 old_scale_exp = Q15 - (Q_pow1); - // old_scale = Sqrt16(old_scale, &old_scale_exp); - // old_scale = shl(old_scale, old_scale_exp); //Q15 - L_tmp = root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ); - IF( exp < 0 ) - { - L_tmp = L_shl( L_tmp, exp ); - exp = 0; - move16(); - } - old_scale = round_fx_sat( L_tmp ); // exp + /* old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); */ + old_scale = round_fx_sat( root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ) ); // exp + old_scale = shl( old_scale, s_min( 0, exp ) ); // limit Q factor to 15 + exp = s_max( 0, exp ); + // new_scale = 1.0f; new_scale = shr( 32767, exp ); // exp + // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); step_scale = mult_r( sub( new_scale, old_scale ), 205 ); // exp scale = old_scale; // exp move16(); + /* interpolate between the old and the new value of the mixing factor */ old_fact = *prev_mix_factor; // Q15 + new_fact = mix_factor; // Q15 move16(); - new_fact = mix_factor; // Q15 move16(); + // step = (new_fact - old_fact) / (L_FRAME16k / 2); step = mult_r( sub( new_fact, old_fact ), 205 ); // Q15 fact = old_fact; // Q15 move16(); + + shift = add( exp, sub( *Q_bwe_exc, Q_White_exc16k ) ); + /* mixing of LB and gaussian excitation in the first half of the frame */ FOR( k = 0; k < L_FRAME16k / 2; k++ ) { - // exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(fact, mult(shl(White_exc16k[k], *Q_bwe_exc), scale)), mult_r(sub(32767, fact), exc16kWhtnd[k])); - L_tmp = L_add_sat( L_shl_sat( L_mult( fact, mult_r( White_exc16k[k], scale ) ), exp ), // Q15 + Q_bwe_exc + (Q15-exp) - Q15 + exp + Q1 - L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc + Q16 - exc16kWhtnd[k] = round_fx_sat( L_tmp ); // Q_bwe_exc + /* exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; */ + L_tmp = L_shl_sat( L_mult( fact, mult_r( White_exc16k[k], scale ) ), shift ); // Q_bwe_exc+16 + exc16kWhtnd[k] = mac_r_sat( L_tmp, sub( 32767, fact ), exc16kWhtnd[k] ); // Q_bwe_exc move16(); + fact = add_sat( fact, step ); // Q15 scale = add_sat( scale, step_scale ); // exp } + shift = sub( *Q_bwe_exc, Q_White_exc16k ); /* mixing of LB and gaussian excitation in the second half of the frame */ FOR( ; k < L_FRAME16k; k++ ) { // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(new_fact, shl(White_exc16k[k], *Q_bwe_exc)), mult_r(sub(32767, new_fact), exc16kWhtnd[k])); - L_tmp = L_add( L_mult( new_fact, White_exc16k[k] ), - mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc + Q15 + Q1 => Q_bwe_exc + Q16 - exc16kWhtnd[k] = round_fx( L_tmp ); // Q_bwe_exc + L_tmp = L_shl_sat( L_mult( new_fact, White_exc16k[k] ), shift ); // Q_bwe_exc+16 + exc16kWhtnd[k] = mac_r( L_tmp, sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_bwe_exc move16(); } } @@ -3697,32 +3661,28 @@ void GenShapedSHBExcitation_ivas_enc_fx( PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc } ELSE -#endif { -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) -#else - IF( EQ_16( coder_type, UNVOICED ) ) -#endif { - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = 0; + move16(); + test(); - if ( chk1 == 0 && chk2 == 0 ) + IF( pow1 != 0 && pow22 != 0 ) { - L_tmp = 0; - move32(); + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ } - scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ + FOR( k = 0; k < L_FRAME16k; k++ ) { - /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); // Q_bwe_exc + Q15 + Q1 => Q_bwe_exc + Q16 - /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx_sat( L_tmp ); // Q_bwe_exc + exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); // Q_White_exc16k move16(); - /* exc16kWhtnd: Q_bwe_exc */ } + + Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); // Q_bwe_exc + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc /* i/o: exc16kWhtnd (Q_bwe_exc) */ /* i/o: tbe_premph (Q_bwe_exc) */ @@ -3785,13 +3745,13 @@ void GenShapedSHBExcitation_ivas_enc_fx( temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ } + shift = sub( *Q_bwe_exc, Q_White_exc16k ); FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc)*/ + L_tmp = L_shl_sat( L_mult( temp2, White_exc16k[k + j] ), shift ); // 16+(Q_bwe_exc) exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); // Q_bwe_exc move16(); - /* Q_bwe_exc */ } k = add( k, lSubFr ); @@ -3813,11 +3773,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } -#if 1 // def ADD_IVAS_TBE_CODE IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( LT_32( bitrate, ACELP_24k40 ) ) -#endif { syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); /* i: exc16kWhtnd in Q_bwe_exc */ @@ -3928,8 +3884,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); Scale_sig( fb_tbe_demph, 1, tmp ); syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); - /* i: White_exc16k_FB in (14-n2) */ - /* o: White_exc16k_FB_temp in (14-n2) */ + /* i: White_exc16k_FB in (Q_bwe_exc_fb) */ + /* o: White_exc16k_FB_temp in (Q_bwe_exc_fb) */ FOR( i = 0; i < 10; i++ ) { @@ -3951,10 +3907,11 @@ void GenShapedSHBExcitation_ivas_enc_fx( set16_fx( White_exc16k_FB, 0, L_FRAME16k ); } -#if 1 // def ADD_IVAS_TBE_CODE *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 *prev_mix_factor = mix_factor; -#endif + move32(); + move16(); + return; } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 47c735a85..8268d48b1 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -570,6 +570,7 @@ static void encod_gen_voic_core_switch_ivas_fx( Word16 h2[L_SUBFR + ( M + 1 )]; Word16 dummyF[NB_SUBFR16k]; Word16 lp_select, lp_flag; + Word16 q_h1; LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ BSTR_ENC_HANDLE hBstr; @@ -634,9 +635,8 @@ static void encod_gen_voic_core_switch_ivas_fx( find_targets_ivas_fx( inp, hLPDmem->mem_syn, 0, &( hLPDmem->mem_w0 ), Aq, res, L_SUBFR, Ap, TILT_FAC_FX, xn, cn, h1 ); } - /*Scale_sig(h1, L_SUBFR, shift); */ /*Q14-shift */ - Copy_Scale_sig( h1, h2, L_SUBFR, -2 ); - Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn, L_SUBFR, shift ); /* Q_new */ @@ -646,8 +646,9 @@ static void encod_gen_voic_core_switch_ivas_fx( * Adaptive exc. construction *----------------------------------------------------------------*/ set16_fx( dummyF, -1, NB_SUBFR16k ); /* hack to signal ACELP->HQ switching frame */ + pitch = pit_encode_ivas_fx( hBstr, - st_fx->acelp_cfg.pitch_bits, core_bitrate, 0, L_frame, GENERIC, &pitch_limit_flag, 0, exc, L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, dummyF /*hStereoTD->tdm_Pri_pitch_buf*/ ); /* Q6 */ + st_fx->acelp_cfg.pitch_bits, core_bitrate, 0, L_frame, GENERIC, &pitch_limit_flag, 0, exc, L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, dummyF /*hStereoTD->tdm_Pri_pitch_buf*/, Q_new ); /* Q6 */ /*-----------------------------------------------------------------* * Find adaptive exitation @@ -666,6 +667,7 @@ static void encod_gen_voic_core_switch_ivas_fx( * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ lp_flag = st_fx->acelp_cfg.ltf_mode; /* Q0 */ + Scale_sig( h1, L_SUBFR, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14+shift*/ lp_select = lp_filt_exc_enc_ivas_fx( MODE1, GENERIC, 0, exc, h1, xn, y1, xn2, L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index c0d1a8bca..d5333ae13 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -445,29 +445,29 @@ static void find_enr_dft_ivas_fx( * Spectral analysis of 12.8kHz input *-------------------------------------------------------------------*/ void ivas_analy_sp_fx( - const Word16 element_mode, /* i : element mode Q0*/ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate Q0*/ - Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ - const Word16 Q_new, /* i : current scaling exp Q0 */ - Word32 *fr_bands, /* o : energy in critical frequency bands q_fr_bands */ - Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ - Word32 *lf_E, /* o : per bin E for first... q_lf_E */ - Word16 *q_lf_E, /* o : per bin E for first... Q0 */ - Word16 *Etot, /* o : total input energy Q8 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - Word32 *Bin_E, /* o : per-bin energy spectrum Q7 */ - Word16 *q_Bin_E, /* o : per-bin energy spectrum Q7 */ - Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q7 */ - Word16 *q_Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q7 */ - Word32 *PS, /* o : per-bin energy spectrum Q_new + QSCALE - 2 */ - Word16 *q_PS, /* o : per-bin energy spectrum Q_new + QSCALE - 2 */ - Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ - Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies)*/ - Word16 *q_band_energies, /* o : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ - Word16 *fft_buff, /* o : FFT coefficients (q_fft_buff) */ - Word16 *q_fft_buff /* o : Q of FFT coefficients Q0 */ + const Word16 element_mode, /* i : element mode Q0 */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 input_Fs, /* i : input sampling rate Q0 */ + Word16 *speech, /* i : speech buffer Q_new */ + const Word16 Q_new, /* i : current scaling exp Q0 */ + Word32 *fr_bands, /* o : energy in critical frequency bands q_fr_bands */ + Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ + Word32 *lf_E, /* o : per bin E for first... q_lf_E */ + Word16 *q_lf_E, /* o : per bin E for first... Q0 */ + Word16 *Etot, /* o : total input energy Q8 */ + const Word16 min_band, /* i : minimum critical band Q0 */ + const Word16 max_band, /* i : maximum critical band Q0 */ + Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ + Word16 *q_Bin_E, /* o : per-bin energy spectrum Q0 */ + Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame q_Bin_E_old */ + Word16 *q_Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q0 */ + Word32 *PS, /* o : per-bin energy spectrum q_PS */ + Word16 *q_PS, /* o : per-bin energy spectrum Q0 */ + Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ + Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies) */ + Word16 *q_band_energies, /* o : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ + Word16 *fft_buff, /* o : FFT coefficients (q_fft_buff) */ + Word16 *q_fft_buff /* o : Q of FFT coefficients Q0 */ ) { Word16 *pt; diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index e98956efe..74f73bf52 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -53,8 +53,8 @@ static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); static void init_core_sig_ana_ivas_fx( Encoder_State *st ); static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ); -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift ); +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate); +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate); /*-----------------------------------------------------------------------* * init_coder_ace_plus() * @@ -223,11 +223,11 @@ void init_coder_ace_plus_ivas_fx( } /* Initialize Signal Buffers */ - init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr ); + init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr, last_total_brate); /* Initialize ACELP */ - init_acelp_ivas_fx( st, L_frame_old, 0 ); + init_acelp_ivas_fx( st, L_frame_old, 0, last_total_brate); if ( st->ini_frame == 0 ) { @@ -442,7 +442,7 @@ static void init_tcx_ivas_fx( * Initialization of signal buffers *-----------------------------------------------------------------------*/ /*copy of evs function since it was static */ -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ) +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate) { LPD_state_HANDLE hLPDmem = st->hLPDmem; @@ -478,7 +478,7 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol test(); test(); test(); - IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, st->last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) { lerp( st->buf_speech_enc, st->buf_speech_enc, st->L_frame, L_frame_old ); test(); @@ -530,7 +530,7 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol move16(); } /*coming from TCXonly modes*/ - ELSE IF( !st->tcxonly && GE_32( st->last_total_brate, ACELP_32k ) ) + ELSE IF( !st->tcxonly && GE_32(last_total_brate, ACELP_32k ) ) { Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); @@ -647,7 +647,7 @@ static void init_core_sig_ana_ivas_fx( Encoder_State *st ) * * *-----------------------------------------------------------------------*/ -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift ) +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate) { Word16 mem_syn_r_size_old; Word16 mem_syn_r_size_new; @@ -753,7 +753,7 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh test(); test(); test(); - IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, st->last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) { Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ IF( EQ_16( st->L_frame, L_FRAME16k ) ) @@ -959,8 +959,6 @@ static void init_modes_ivas_fx( Word8 n; Word32 tmp32; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - (void) last_total_brate; - /* Restrict ACE/TCX20/TCX10 mode */ move16(); @@ -1050,7 +1048,7 @@ static void init_modes_ivas_fx( } /* Reconfigure core */ - core_coder_reconfig_ivas_fx( st ); + core_coder_reconfig_ivas_fx( st, last_total_brate); return; diff --git a/lib_enc/core_enc_reconf.c b/lib_enc/core_enc_reconf.c index 24729c124..890194966 100644 --- a/lib_enc/core_enc_reconf.c +++ b/lib_enc/core_enc_reconf.c @@ -49,7 +49,8 @@ *-----------------------------------------------------------------*/ void core_coder_reconfig_ivas_fx( - Encoder_State *st ) + Encoder_State *st, + const int32_t last_total_brate ) { Word16 i, bwidth, index; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; @@ -324,7 +325,7 @@ void core_coder_reconfig_ivas_fx( test(); test(); test(); - IF( ( LT_32( st->total_brate, ACELP_24k40 ) ) && ( ( GT_32( st->total_brate, st->last_total_brate ) ) || ( EQ_16( st->last_codec_mode, MODE1 ) ) ) ) + IF( ( LT_32( st->total_brate, ACELP_24k40 ) ) && ( ( GT_32( st->total_brate, last_total_brate ) ) || ( EQ_16( st->last_codec_mode, MODE1 ) ) ) ) { /* low-freq memQuantZeros_fx must be reset partially if bitrate increased */ FOR( i = 0; i < hTcxEnc->nmStartLine; i++ ) @@ -333,7 +334,7 @@ void core_coder_reconfig_ivas_fx( move16(); } } - ELSE IF( ( GE_32( st->total_brate, ACELP_24k40 ) ) && ( LE_32( st->total_brate, ACELP_32k ) ) && ( GE_32( st->last_total_brate, ACELP_13k20 ) ) && ( LT_32( st->last_total_brate, ACELP_24k40 ) ) ) + ELSE IF( ( GE_32( st->total_brate, ACELP_24k40 ) ) && ( LE_32( st->total_brate, ACELP_32k ) ) && ( GE_32( last_total_brate, ACELP_13k20 ) ) && ( LT_32( last_total_brate, ACELP_24k40 ) ) ) { FOR( i = 0; i < st->L_frame; i++ ) /* memQuantZeros_fx won't be updated */ { diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index b6f723c2b..81b299057 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -206,7 +206,7 @@ void core_coder_mode_switch_ivas_fx( st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); move16(); - core_coder_reconfig_ivas_fx( st ); + core_coder_reconfig_ivas_fx( st, last_total_brate); } ELSE { diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 96e7e274c..1053f8b00 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -465,13 +465,13 @@ void encod_gen_voic_ivas_fx( Word16 shift_wsp; Word16 harm_flag_acelp; Word16 lp_select, lp_flag, L_frame; + Word16 q_h1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); #endif SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; - SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; /*------------------------------------------------------------------* @@ -554,16 +554,16 @@ void encod_gen_voic_ivas_fx( find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); - Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); /*Q11*/ - Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution Q14+shift*/ + q_h1 = sub( 14, norm_s( h1_fx[0] ) ); + Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn_fx, L_SUBFR, shift ); *pt_pitch_fx = pit_encode_ivas_fx( hBstr, st_fx->acelp_cfg.pitch_bits, st_fx->core_brate, 0, L_frame, st_fx->coder_type, &pitch_limit_flag, i_subfr_fx, exc_fx, - L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /* Q6 */ + L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new ); /* Q6 */ + move16(); - // tbe_celp_exc(L_frame, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx); tbe_celp_exc_ivas( st_fx->element_mode, st_fx->idchan, L_frame, L_SUBFR, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx, st_fx->tdm_LRTD_flag ); /*-----------------------------------------------------------------* @@ -588,7 +588,7 @@ void encod_gen_voic_ivas_fx( /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ - + Scale_sig( h1_fx, L_SUBFR, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14*/ lp_select = lp_filt_exc_enc_ivas_fx( MODE1, st_fx->coder_type, i_subfr_fx, exc_fx, h1_fx, xn_fx, y1_fx, xn2_fx, L_SUBFR, L_frame, g_corr_fx, clip_gain_fx, &gain_pit_fx, &lp_flag ); @@ -597,10 +597,6 @@ void encod_gen_voic_ivas_fx( push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } - /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit_fx;*/ - hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx, &Overflow ), &Overflow ); /* Q14 */ - move16(); - /*-----------------------------------------------------------------* * Transform domain contribution encoding - active frames *-----------------------------------------------------------------*/ diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index e0d4f5016..e03db0c47 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -580,7 +580,7 @@ void enc_pit_exc_ivas_fx( Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ Word16 h1_q15[PIT_EXC_L_SUBFR + ( M + 1 )]; - SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; + Word16 q_h1; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; @@ -740,8 +740,8 @@ void enc_pit_exc_ivas_fx( find_targets_ivas_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); - Copy_Scale_sig( h1, h2, L_subfr, -2 ); /* Q13 */ - Scale_sig( h1, L_subfr, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2, L_subfr, sub( 11, q_h1 ) ); /*Q11*/ /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn, L_subfr, shift ); /* Q_new - 1 + shift */ @@ -750,9 +750,12 @@ void enc_pit_exc_ivas_fx( * Close-loop pitch search and quantization * Adaptive exc. construction *----------------------------------------------------------------*/ + *pt_pitch = pit_encode_ivas_fx( hBstr, st_fx->acelp_cfg.pitch_bits, Pitch_BR, 0, st_fx->L_frame, Pitch_CT, &pitch_limit_flag, i_subfr, exc, - L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /* Q6 */ + L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new ); /* Q6 */ move16(); + Scale_sig( h1, L_subfr, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14*/ + /*-----------------------------------------------------------------* * Find adaptive exitation *-----------------------------------------------------------------*/ @@ -779,9 +782,6 @@ void enc_pit_exc_ivas_fx( push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } - /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit;*/ - hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ - gpit_tmp = gain_pit; move16(); /*Q14*/ test(); diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index b4495d4ff..bf04daff5 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -467,6 +467,7 @@ Word16 encod_tran_ivas_fx( Word16 L_frame_fx; Word16 shift_wsp; Word32 L_tmp; + Word16 q_h1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -540,7 +541,9 @@ Word16 encod_tran_ivas_fx( find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); - Copy_Scale_sig( h1, h2_fx, L_SUBFR, -2 ); + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ + Scale_sig( h1, L_SUBFR, sub( 13, q_h1 ) ); /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn, L_SUBFR, shift ); diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 32c397613..0be344d72 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -93,8 +93,8 @@ void encod_unvoiced_fx( i_subfr_idx = shr( i_subfr, 6 ); Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ - find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, - res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); + find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, + res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); /*Copy_Scale_sig(h1_fx, h2_fx, L_SUBFR, -2);*/ Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ @@ -279,6 +279,7 @@ void encod_unvoiced_ivas_fx( Word16 i_subfr, Q_xn, Q_new_p5, tmp2, j, i; Word16 index, i_subfr_idx; Word16 unbits_PI; + Word16 q_h1; acelp_cfg = &( st_fx->acelp_cfg ); SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; @@ -319,8 +320,9 @@ void encod_unvoiced_ivas_fx( find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); - Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); - Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1_fx[0] ) ); + Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); + Scale_sig( h1_fx, L_SUBFR, sub( 14, q_h1 ) ); /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn_fx, L_SUBFR, shift ); // Q_new - 1 + shift diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index c758db8f3..4e15bc828 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -171,16 +171,19 @@ void find_targets_ivas_fx( Word16 tilt_fac, /* i : tilt factor Q15*/ Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter Q14*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ) { Word16 i; Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */ Word16 scale, scaleq, j, d, s, s2, tmp; Word16 Aqs[M + 1]; - Word32 Ltmp; + Word32 h1_32[6 * L_SUBFR]; + Word16 sf; + Word64 Ltmp64; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif /*------------------------------------------------------------------------* * Find the target vector for excitation search: @@ -200,12 +203,14 @@ void find_targets_ivas_fx( temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */ move16(); } - Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); - Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new -1*/ + syn_filt_fx( 0, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); - deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new -1 */ + Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new */ + + deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new */ + *mem_w0 = shr( *mem_w0, 1 ); // Q_new - 1 /*-----------------------------------------------------------------* * Find target in residual domain (cn[]) for innovation search @@ -216,13 +221,13 @@ void find_targets_ivas_fx( temp[0] = 0; move16(); preemph_copy_fx( xn, cn, tilt_fac, shr( L_subfr, 1 ), temp ); - syn_filt_s_lc_fx( 1, Ap, cn, temp, shr( L_subfr, 1 ) ); /* Q-1 -> Q-2 */ - Residu3_lc_fx( p_Aq, M, temp, cn, shr( L_subfr, 1 ), 1 ); /* Q-2 -> Q-1 */ - Scale_sig( cn, shr( L_subfr, 1 ), 1 ); /* Q_new */ + syn_filt_s_lc_fx( 1, Ap, cn, temp, shr( L_subfr, 1 ) ); /* Q_new -> Q_new - 1 */ + Residu3_lc_fx( p_Aq, M, temp, cn, shr( L_subfr, 1 ), 1 ); /* Q_new - 1 -> Q_new */ /* second half: res[] --> cn[] (approximated and faster) */ Copy( &res[i_subfr + shr( L_subfr, 1 )], cn + shr( L_subfr, 1 ), shr( L_subfr, 1 ) ); /* Q_new */ } + scale_sig( xn, L_subfr, -1 ); // Q_new - 1 /*---------------------------------------------------------------* * Compute impulse response, h1[], of weighted synthesis filter * @@ -242,67 +247,48 @@ void find_targets_ivas_fx( Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */ s = add( scale, 1 ); s2 = 16384; + move16(); } - set16_fx( h1, 0, L_subfr ); + + set32_fx( h1_32, 0, L_subfr ); Overflow = 0; move16(); FOR( i = 0; i < M; i++ ) { - Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ + Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= i; j++ ) { - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */ + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ } - h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */ + h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); } - Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ + + Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= M; j++ ) { - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */ + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ } - h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */ + h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); - // PMT("should we used extended basop here for when the L_subfr > L_SUBFR, to prevent saturation/overflow and the subsequent loop\n") FOR( i = M + 1; i < L_subfr; i++ ) { - Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */ + Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_o( h1_32[i - 1], s, &Overflow ) ) ); /* Q27 */ FOR( j = 2; j <= M; j++ ) { - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */ - } - h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */ - } - IF( Overflow ) - { - s2 = shr( s2, 1 ); - FOR( i = 0; i < M; i++ ) - { - Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ - FOR( j = 1; j <= i; j++ ) - { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */ - } - h1[i] = round_fx( L_shl_o( Ltmp, s, &Overflow ) ); /* Q11 + s */ - } - Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ - FOR( j = 1; j <= M; j++ ) - { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */ - } - h1[M] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */ - FOR( i = M + 1; i < L_subfr; i++ ) - { - Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */ - FOR( j = 2; j <= M; j++ ) - { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */ - } - h1[i] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */ + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ } + h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); } + sf = sub( L_norm_arr( h1_32, L_subfr ), 1 ); + Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf + tmp = 0; - Deemph2( h1, tilt_fac, L_subfr, &tmp ); + move16(); + Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1 return; } diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index d09134951..5fffadc77 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -219,6 +219,7 @@ void encod_gen_2sbfr( Word32 norm_gain_code; Word16 pitch_limit_flag; Word16 error; + Word16 q_h1; LPD_state_HANDLE hLPDmem = st->hLPDmem; @@ -269,26 +270,23 @@ void encod_gen_2sbfr( Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new - // Scaling mem_syn buffer to Q_new - 1 from e_mem_syn - // Scale_sig( &hLPDmem->mem_w0, M + 1, sub( add( *Q_new, hLPDmem->e_mem_syn ), Q16 ) ); // M + 1 to sync mem_syn exponent with mem_w0 exponent - // hLPDmem->e_mem_syn = sub( Q16, *Q_new ); - - #ifndef FIX_1320_LOWRATE_ACELP find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); #else find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); #endif - /*Scale_sig(h1, L_SUBFR, shift); */ /*Q14-shift */ - Copy_Scale_sig( h1, h2, 2 * L_SUBFR, -2 ); - Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2, 2 * L_SUBFR, sub( 11, q_h1 ) ); /*------------------------------------------------------------------------* * Close-loop pitch search on the 1st and 3rd subfr only and quantization * Adaptive exc. construction *------------------------------------------------------------------------*/ + *pt_pitch = pit_encode_ivas_fx( st->hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 0, L_frame, coder_type, &pitch_limit_flag, i_subfr, exc, 2 * L_SUBFR, st->pitch, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new ); + move16(); - *pt_pitch = pit_encode_ivas_fx( st->hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 0, L_frame, coder_type, &pitch_limit_flag, i_subfr, exc, 2 * L_SUBFR, st->pitch, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + Scale_sig( h1, 2 * L_SUBFR, sub( 13, q_h1 ) ); // Q13 tbe_celp_exc_ivas( st->element_mode, st->idchan, L_frame, 2 * L_SUBFR, i_subfr, T0, T0_frac, &error, bwe_exc, st->tdm_LRTD_flag ); @@ -310,6 +308,7 @@ void encod_gen_2sbfr( /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ + Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ #ifndef FIX_1320_LOWRATE_ACELP lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); diff --git a/lib_enc/multi_harm_fx.c b/lib_enc/multi_harm_fx.c index 86fe541bb..78ef81c60 100644 --- a/lib_enc/multi_harm_fx.c +++ b/lib_enc/multi_harm_fx.c @@ -652,7 +652,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni pt1++; pt2++; } - tmp2 = L_shr_sat( tmp2_32, 7 ); // q15-> q8 + tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8 IF( EQ_16( bwidth, NB ) ) { diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index 3793ee00d..80e144743 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -487,26 +487,27 @@ Word16 pit_encode_fx( /* o : Fractional pitc return pitch_cl; } -Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 pitch_bits[], /* i : pitch bits */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - const Word16 i_subfr, /* i : subframe index */ - Word16 *exc, /* i/o: pointer to excitation signal frame */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 *pitch, /* i : open loop pitch estimates in current frame */ - Word16 *T0_min, /* i/o: lower limit for close-loop search */ - Word16 *T0_max, /* i/o: higher limit for close-loop search */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 pitch_bits[], /* i : pitch bits */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *exc, /* i/o: pointer to excitation signal frame Q_new */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 *pitch, /* i : open loop pitch estimates in current frame */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ + const Word16 *h1, /* i : weighted filter input response Q(14 - norm_s(h1[0]) */ + const Word16 *xn, /* i : target vector Q_new */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new /* i */ ) { Word16 pitch_cl; @@ -617,6 +618,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional { nBits = pitch_bits[i_subfr >> L_sufr_sft]; } + test(); IF( EQ_16( coder_type, AUDIO ) ) { /*-------------------------------------------------------* @@ -628,7 +630,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional move16(); test(); test(); - if ( EQ_16( L_subfr, L_frame / 2 ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) + if ( EQ_16( L_subfr, shr( L_frame, 1 ) ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) { pit_flag = L_SUBFR; move16(); @@ -656,7 +658,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr, Q_new ); move16(); pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } @@ -684,19 +686,17 @@ Word16 pit_encode_ivas_fx( /* o : Fractional test(); IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 5 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_DOUBLEEXTEND_9b, PIT_FR1_DOUBLEEXTEND_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_DOUBLEEXTEND_9b, PIT_FR1_DOUBLEEXTEND_9b, L_FRAME, L_SUBFR, Q_new ); move16(); } ELSE IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR, Q_new ); move16(); } pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } -#if 1 - //#ifdef ADD_LRTD ELSE IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) || EQ_16( nBits, 4 ) ) { /*-------------------------------------------------------* @@ -731,7 +731,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional IF( nBits > 0 ) { /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); move16(); IF( EQ_16( delta, 8 ) ) { @@ -748,7 +748,6 @@ Word16 pit_encode_ivas_fx( /* o : Fractional move16(); } } -#endif ELSE { /*-------------------------------------------------------* @@ -778,12 +777,12 @@ Word16 pit_encode_ivas_fx( /* o : Fractional { IF( *limit_flag == 0 ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); move16(); } ELSE { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN_EXTEND, PIT_FR1_EXTEND_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN_EXTEND, PIT_FR1_EXTEND_8b, L_FRAME, L_SUBFR, Q_new ); move16(); } } @@ -791,18 +790,18 @@ Word16 pit_encode_ivas_fx( /* o : Fractional { IF( *limit_flag == 0 ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR, Q_new ); move16(); } ELSE { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_EXTEND_9b, PIT_FR1_EXTEND_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_EXTEND_9b, PIT_FR1_EXTEND_9b, L_FRAME, L_SUBFR, Q_new ); move16(); } } ELSE IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR, Q_new ); } pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -812,12 +811,12 @@ Word16 pit_encode_ivas_fx( /* o : Fractional test(); IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, L_FRAME16k, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, L_FRAME16k, L_SUBFR, Q_new ); move16(); } ELSE IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR, Q_new ); move16(); } @@ -858,7 +857,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); move16(); } ELSE IF( EQ_32( core_brate, ACELP_8k85 ) ) @@ -881,7 +880,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); move16(); } ELSE @@ -908,7 +907,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR, Q_new ); move16(); } @@ -1156,19 +1155,20 @@ Word16 delta_pit_enc_fx( /* o : pitch index * * Find the closed loop pitch period with 1/4 subsample resolution. *-------------------------------------------------------------------*/ -Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch lag */ - const Word16 exc[], /* i : excitation buffer Q_new*/ - const Word16 xn[], /* i : target signal Q_new-1+shift*/ - const Word16 h[], /* i : weighted synthesis filter impulse response Q(14+shift)*/ - const Word16 t0_min, /* i : minimum value in the searched range. Q0*/ - const Word16 t0_max, /* i : maximum value in the searched range. Q0*/ - Word16 *pit_frac, /* o : chosen fraction (0, 1, 2 or 3) */ - const Word16 i_subfr, /* i : flag to first subframe */ - const Word16 limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ - const Word16 t0_fr2, /* i : minimum value for resolution 1/2 */ - const Word16 t0_fr1, /* i : minimum value for resolution 1 */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 L_subfr /* i : size of subframe */ +Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch lag */ + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s[h[0]) */ + const Word16 t0_min, /* i : minimum value in the searched range. Q0 */ + const Word16 t0_max, /* i : maximum value in the searched range. Q0 */ + Word16 *pit_frac, /* o : chosen fraction (0, 1, 2 or 3) */ + const Word16 i_subfr, /* i : flag to first subframe */ + const Word16 limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ + const Word16 t0_fr2, /* i : minimum value for resolution 1/2 */ + const Word16 t0_fr1, /* i : minimum value for resolution 1 */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 L_subfr, /* i : size of subframe */ + Word16 Q_new /* i */ ) { Word16 i; @@ -1225,7 +1225,7 @@ Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch move16(); move16(); /* corr[t_min..t_max] */ - norm_corr_ivas_fx( exc, xn, h, t_min, t_max, corr, L_subfr ); + norm_corr_ivas_fx( exc, xn, h, t_min, t_max, corr, L_subfr, Q_new ); /*-----------------------------------------------------------------* * Find integer pitch @@ -1238,7 +1238,7 @@ Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch FOR( i = add( t0_min, 1 ); i <= t0_max; i++ ) { - if ( corr[i] >= max_val ) + if ( GE_16( corr[i], max_val ) ) { t0 = i; move16(); @@ -1346,6 +1346,7 @@ Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch return ( t0 ); } + Word16 pitch_fr4_fx( /* o : chosen integer pitch lag */ const Word16 exc[], /* i : excitation buffer Q_new*/ const Word16 xn[], /* i : target signal Q_new-1+shift*/ @@ -1545,43 +1546,35 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag * excitation) *---------------------------------------------------------------------*/ void norm_corr_ivas_fx( - const Word16 exc[], /* i : excitation buffer Q_new*/ - const Word16 xn[], /* i : target signal Q_new-1+shift*/ - const Word16 h[], /* i : weighted synthesis filter impulse response Q(14+shift)*/ - const Word16 t_min, /* i : minimum value of searched range */ - const Word16 t_max, /* i : maximum value of searched range */ - Word16 ncorr[], /* o : normalized correlation Q15 */ - const Word16 L_subfr /* i : subframe size */ + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s(h[0])) */ + const Word16 t_min, /* i : minimum value of searched range */ + const Word16 t_max, /* i : maximum value of searched range */ + Word16 ncorr[], /* o : normalized correlation */ + const Word16 L_subfr, /* i : subframe size */ + Word16 Q_new /* i */ ) { Word16 i, k, t; - Word16 corr, exp_corr, norm, exp_norm, exp, scale; + Word16 corr, exp_corr, norm, exp_norm, exp; Word16 excf[L_FRAME16k]; + Word16 ncorr_e[15 + 2 * L_INTERPOL1 + 1]; + Word16 h_e, e_max; Word32 L_tmp; Word64 W_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif k = negate( t_min ); - + h_e = add( 1, norm_s( h[0] ) ); // exponent of h /*-----------------------------------------------------------------* * compute the filtered excitation for the first delay t_min *-----------------------------------------------------------------*/ - conv_fx( &exc[k], h, excf, L_subfr ); - - /* Compute rounded down 1/sqrt(energy of xn[]) */ - L_tmp = L_mac_o( 1, xn[0], xn[0], &Overflow ); - FOR( i = 1; i < L_subfr; i++ ) - { - L_tmp = L_mac_o( L_tmp, xn[i], xn[i], &Overflow ); - } - exp = norm_l( L_tmp ); - exp = sub( 30, exp ); - - exp = add( exp, 2 ); /* energy of xn[] x 2 + rounded up */ - scale = negate( shr( exp, 1 ) ); /* (1< 0; i-- ) { /* saturation can occur in add() */ - /*excf[i] = add(mult(exc[k], h[i]), excf[i - 1]); move16(); */ excf[i] = round_fx_sat( L_mac_sat( L_mult( excf[i - 1], 32767 ), exc[k], h[i] ) ); + move16(); } excf[0] = mult_r( exc[k], h[0] ); move16(); } } + // Aligning the values of ncorr to a common exponent + maximum_fx( ncorr_e, t_max + 1 - t_min, &e_max ); + FOR( t = t_min; t <= t_max; t++ ) + { + ncorr[t] = shr( ncorr[t], sub( e_max, ncorr_e[t - t_min] ) ); + move16(); + } return; } + void norm_corr_fx( const Word16 exc[], /* i : excitation buffer Q_new*/ const Word16 xn[], /* i : target signal Q_new-1+shift*/ diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 711d7069a..a3a7bd910 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -954,15 +954,18 @@ void norm_corr_fx( Word16 ncorr[], /* o : normalized correlation Q15 */ const Word16 L_subfr /* i : subframe size */ ); + void norm_corr_ivas_fx( - const Word16 exc[], /* i : excitation buffer Q_new*/ - const Word16 xn[], /* i : target signal Q_new-1+shift*/ - const Word16 h[], /* i : weighted synthesis filter impulse response Q(14+shift)*/ - const Word16 t_min, /* i : minimum value of searched range */ - const Word16 t_max, /* i : maximum value of searched range */ - Word16 ncorr[], /* o : normalized correlation Q15 */ - const Word16 L_subfr /* i : subframe size */ + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s(h[0])) */ + const Word16 t_min, /* i : minimum value of searched range */ + const Word16 t_max, /* i : maximum value of searched range */ + Word16 ncorr[], /* o : normalized correlation */ + const Word16 L_subfr, /* i : subframe size */ + Word16 Q_new /* i */ ); + Word16 peak_avrg_ratio_fx( const Word32 total_brate, /* Q0 */ const Word32 *input_hi_fx, /* i : i signal Q_coeff*/ @@ -1024,20 +1027,23 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag const Word16 L_frame, /* i : length of the frame */ const Word16 L_subfr /* i : size of subframe */ ); -Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch lag */ - const Word16 exc[], /* i : excitation buffer Q_new*/ - const Word16 xn[], /* i : target signal Q_new-1+shift*/ - const Word16 h[], /* i : weighted synthesis filter impulse response Q(14+shift)*/ - const Word16 t0_min, /* i : minimum value in the searched range. Q0*/ - const Word16 t0_max, /* i : maximum value in the searched range. Q0*/ - Word16 *pit_frac, /* o : chosen fraction (0, 1, 2 or 3) */ - const Word16 i_subfr, /* i : flag to first subframe */ - const Word16 limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ - const Word16 t0_fr2, /* i : minimum value for resolution 1/2 */ - const Word16 t0_fr1, /* i : minimum value for resolution 1 */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 L_subfr /* i : size of subframe */ + +Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch lag */ + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s[h[0]) */ + const Word16 t0_min, /* i : minimum value in the searched range. Q0 */ + const Word16 t0_max, /* i : maximum value in the searched range. Q0 */ + Word16 *pit_frac, /* o : chosen fraction (0, 1, 2 or 3) */ + const Word16 i_subfr, /* i : flag to first subframe */ + const Word16 limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ + const Word16 t0_fr2, /* i : minimum value for resolution 1/2 */ + const Word16 t0_fr1, /* i : minimum value for resolution 1 */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 L_subfr, /* i : size of subframe */ + Word16 Q_new /* i */ ); + void pit_Q_enc_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ @@ -2222,29 +2228,29 @@ void analy_sp_fx( ); void ivas_analy_sp_fx( - const Word16 element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ - const Word16 Q_new, /* i : current scaling exp Q0 */ - Word32 *fr_bands, /* o : energy in critical frequency bands q_fr_bands */ - Word16 *q_fr_bands, /* o : Q of energy in critical frequency bands Q0 */ - Word32 *lf_E, /* o : per bin E for first... Q0 */ - Word16 *q_lf_E, /* o : Q of per bin E for first... q_lf_E */ - Word16 *Etot, /* o : total input energy Q8 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ - Word16 *q_Bin_E, /* o : Q of per-bin energy spectrum Q0 */ - Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame q_Bin_E_old */ - Word16 *q_Bin_E_old, /* o : Q of per-bin energy spectrum of the previous frame Q0 */ - Word32 *PS, /* o : per-bin energy spectrum q_PS */ - Word16 *q_PS, /* o : Q of per-bin energy spectrum Q0 */ - Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ - Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies)*/ - Word16 *q_band_energies, /* o : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ - Word16 *fft_buff, /* o : FFT coefficients (q_fft_buff) */ - Word16 *q_fft_buff /* o : Q of FFT coefficients Q0 */ + const Word16 element_mode, /* i : element mode Q0 */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 input_Fs, /* i : input sampling rate Q0 */ + Word16 *speech, /* i : speech buffer Q_new */ + const Word16 Q_new, /* i : current scaling exp Q0 */ + Word32 *fr_bands, /* o : energy in critical frequency bands q_fr_bands */ + Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ + Word32 *lf_E, /* o : per bin E for first... q_lf_E */ + Word16 *q_lf_E, /* o : per bin E for first... Q0 */ + Word16 *Etot, /* o : total input energy Q8 */ + const Word16 min_band, /* i : minimum critical band Q0 */ + const Word16 max_band, /* i : maximum critical band Q0 */ + Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ + Word16 *q_Bin_E, /* o : per-bin energy spectrum Q0 */ + Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame q_Bin_E_old */ + Word16 *q_Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q0 */ + Word32 *PS, /* o : per-bin energy spectrum q_PS */ + Word16 *q_PS, /* o : per-bin energy spectrum Q0 */ + Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ + Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies) */ + Word16 *q_band_energies, /* o : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ + Word16 *fft_buff, /* o : FFT coefficients (q_fft_buff) */ + Word16 *q_fft_buff /* o : Q of FFT coefficients Q0 */ ); void find_wsp_fx( const Word16 Az[], @@ -2337,7 +2343,7 @@ void find_targets_ivas_fx( Word16 tilt_fac, /* i : tilt factor Q15*/ Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter Q14*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ); void E_ACELP_adaptive_codebook( @@ -3424,26 +3430,27 @@ Word16 pit_encode_fx( /* o : Fractional pitc const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ); -Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 pitch_bits[], /* i : pitch bits */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - const Word16 i_subfr, /* i : subframe index */ - Word16 *exc, /* i/o: pointer to excitation signal frame */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 *pitch, /* i : open loop pitch estimates in current frame */ - Word16 *T0_min, /* i/o: lower limit for close-loop search */ - Word16 *T0_max, /* i/o: higher limit for close-loop search */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 pitch_bits[], /* i : pitch bits */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *exc, /* i/o: pointer to excitation signal frame Q_new */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 *pitch, /* i : open loop pitch estimates in current frame */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ + const Word16 *h1, /* i : weighted filter input response Q(14 - norm_s(h1[0]) */ + const Word16 *xn, /* i : target vector Q_new */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new /* i */ ); Word16 lp_filt_exc_enc_fx( diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index f67d81c71..7422a5a15 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -3706,13 +3706,13 @@ void swb_tbe_enc_ivas_fx( Q_bwe_exc_fb = hBWE_TD->prev_Q_bwe_exc_fb; move16(); - GenShapedSHBExcitation_ivas_enc_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, - hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, - st_fx->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st_fx->extl, - &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_Q31, - shb_res_gshape_fx, shb_res_fx, &vf_ind_fx, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0, st_fx->element_mode, st_fx->flag_ACELP16k, nlExc16k_fx, nlExc16k_e, mixExc16k_fx, mixExc16k_e, st_fx->extl_brate, MSFlag, - EnvSHBres_4k_norm_fx, Q_EnvSHBres_4k_norm, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), &Env_error_fx, Env_error_part_fx ); + GenShapedSHBExcitation_ivas_enc_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, hBWE_TD->mem_csfilt_fx, + hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, st_fx->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, + vf_modified_fx, st_fx->extl, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_Q31, + shb_res_gshape_fx, shb_res_fx, &vf_ind_fx, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, + &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0, st_fx->element_mode, st_fx->flag_ACELP16k, nlExc16k_fx, + nlExc16k_e, mixExc16k_fx, mixExc16k_e, st_fx->extl_brate, MSFlag, EnvSHBres_4k_norm_fx, Q_EnvSHBres_4k_norm, + &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), &Env_error_fx, Env_error_part_fx ); *Q_white_exc = Q_bwe_exc_fb; move16(); -- GitLab From 01b3c4b5c17bc6b6d165e52e7c638b15ccfd8c28 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Feb 2025 12:46:11 +0530 Subject: [PATCH 0253/1221] Clang formatting changes --- lib_com/prot_fx.h | 39 ++++++++++++++++++++------------------- lib_enc/core_enc_init.c | 20 ++++++++++---------- lib_enc/core_enc_switch.c | 2 +- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 485ddb33d..412b5aa35 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3051,30 +3051,30 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ Word16 *shb_res, Word16 *vf_ind, - const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ - Word16 fb_state_lpc_syn[], /* i/o: memory */ - Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ Word16 *Q_bwe_exc, Word16 *Q_bwe_exc_fb, const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, const Word16 prev_bfi, - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ Word16 Q_EnvSHBres_4k, - Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ + Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ ); void GenShapedSHBExcitation_ivas_dec_fx( @@ -11110,7 +11110,8 @@ void init_coder_ace_plus_ivas_fx( ); void core_coder_reconfig_ivas_fx( - Encoder_State *st, const int32_t last_total_brate ); + Encoder_State *st, + const int32_t last_total_brate ); void core_coder_mode_switch_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index 74f73bf52..657ef8d96 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -53,8 +53,8 @@ static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); static void init_core_sig_ana_ivas_fx( Encoder_State *st ); static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate); -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate); +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ); +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ); /*-----------------------------------------------------------------------* * init_coder_ace_plus() * @@ -223,11 +223,11 @@ void init_coder_ace_plus_ivas_fx( } /* Initialize Signal Buffers */ - init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr, last_total_brate); + init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr, last_total_brate ); /* Initialize ACELP */ - init_acelp_ivas_fx( st, L_frame_old, 0, last_total_brate); + init_acelp_ivas_fx( st, L_frame_old, 0, last_total_brate ); if ( st->ini_frame == 0 ) { @@ -442,7 +442,7 @@ static void init_tcx_ivas_fx( * Initialization of signal buffers *-----------------------------------------------------------------------*/ /*copy of evs function since it was static */ -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate) +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ) { LPD_state_HANDLE hLPDmem = st->hLPDmem; @@ -478,7 +478,7 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol test(); test(); test(); - IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) { lerp( st->buf_speech_enc, st->buf_speech_enc, st->L_frame, L_frame_old ); test(); @@ -530,7 +530,7 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol move16(); } /*coming from TCXonly modes*/ - ELSE IF( !st->tcxonly && GE_32(last_total_brate, ACELP_32k ) ) + ELSE IF( !st->tcxonly && GE_32( last_total_brate, ACELP_32k ) ) { Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); @@ -647,7 +647,7 @@ static void init_core_sig_ana_ivas_fx( Encoder_State *st ) * * *-----------------------------------------------------------------------*/ -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate) +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ) { Word16 mem_syn_r_size_old; Word16 mem_syn_r_size_new; @@ -753,7 +753,7 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh test(); test(); test(); - IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) { Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ IF( EQ_16( st->L_frame, L_FRAME16k ) ) @@ -1048,7 +1048,7 @@ static void init_modes_ivas_fx( } /* Reconfigure core */ - core_coder_reconfig_ivas_fx( st, last_total_brate); + core_coder_reconfig_ivas_fx( st, last_total_brate ); return; diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index 81b299057..98e926a2b 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -206,7 +206,7 @@ void core_coder_mode_switch_ivas_fx( st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); move16(); - core_coder_reconfig_ivas_fx( st, last_total_brate); + core_coder_reconfig_ivas_fx( st, last_total_brate ); } ELSE { -- GitLab From e86a8b5fe7ce3094bf769099ef03cc506dcc800f Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 26 Feb 2025 11:03:31 +0100 Subject: [PATCH 0254/1221] the cholesky_fixed64 function returns Q10 instead of Q18 now. --- lib_com/ivas_tools.c | 9 +++++---- lib_enc/speech_music_classif_fx.c | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 9f1a42f29..6cb13740a 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -660,10 +660,11 @@ Word64 dot_product_cholesky_fixed64( Word16 i, j; Word64 suma, tmp_sum; Word32 mul; + Word32 tmp; const Word32 *pt_x, *pt_A; pt_A = A; suma = 0; - move32(); + move64(); FOR( i = 0; i < N; i++ ) { tmp_sum = 0; @@ -675,10 +676,10 @@ Word64 dot_product_cholesky_fixed64( mul = Mpy_32_32( *pt_x++, *pt_A++ ); tmp_sum = W_add( tmp_sum, W_deposit32_l( mul ) ); } - - suma = W_mac_32_32( suma, tmp_sum, tmp_sum ); // TODO: make sure that this does not overflow. + tmp_sum = W_shr( tmp_sum, 4 ); // to make sure that the tmp_sum will not overflow + tmp = W_extract_l( tmp_sum ); + suma = W_mac_32_32( suma, tmp, tmp ); } - return suma; } void v_mult_mat_fixed( diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 34744131f..da93127bf 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2271,16 +2271,16 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); - ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_shr( wprob_fx, Q18 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_shr( wprob_fx, Q18 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_shr( wprob_fx, Q18 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); } -- GitLab From 83f55d062391b690dec53bf8d43f83929c1f9e1f Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 26 Feb 2025 11:41:53 +0100 Subject: [PATCH 0255/1221] fix MSVC build --- Workspace_msvc/lib_com.vcxproj.filters | 252 +++-- Workspace_msvc/lib_dec.vcxproj.filters | 1197 ++++++++++++++++++------ Workspace_msvc/lib_enc.vcxproj.filters | 1072 +++++++++++---------- Workspace_msvc/renderer.vcxproj | 2 +- apps/renderer.c | 56 +- lib_com/options.h | 4 - lib_com/stat_com.h | 7 + lib_dec/stat_dec.h | 6 - lib_enc/stat_enc.h | 2 +- 9 files changed, 1680 insertions(+), 918 deletions(-) diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 195d4deb1..c58edbff6 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -82,7 +82,6 @@ common_all_c - common_all_c @@ -161,7 +160,6 @@ common_all_c - common_evs_c @@ -216,7 +214,6 @@ common_all_c - common_all_c @@ -361,65 +358,192 @@ common_all_c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + @@ -493,7 +617,6 @@ common_h - common_h @@ -504,6 +627,9 @@ common_h + + common_all_c + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index b9dbd7fd5..348c5fbda 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -1,305 +1,912 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + - - - - - - - - - - - - + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + + + {6d564218-e0e5-4a7b-80b3-6b10661ad36c} + + + {33d78f8d-2d43-40f5-a9b1-711097bd6746} + + + {044baa49-b157-45ed-8bec-29b6d7172e82} + + + {adc81a29-2517-49f0-819f-e8cea3d49ae3} + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index ac23c810f..0c3220178 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -1,851 +1,839 @@ - + - - enc_ivas_c + + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - enc_evs_c + encoder_evs_c + + + encoder_evs_c - enc_evs_c + encoder_evs_c + + + encoder_evs_c - enc_evs_c + encoder_evs_c + + + encoder_evs_c - enc_evs_c + encoder_evs_c - - enc_evs_c + + encoder_evs_c - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c + encoder_evs_c - - enc_evs_c + + encoder_evs_c - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_evs_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - enc_all_c + + encoder_ivas_c - - enc_evs_c + + encoder_ivas_c - enc_ivas_c - - - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c - - - enc_all_c + encoder_ivas_c - - enc_evs_c - - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_ivas_c + + + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c + + + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - enc_ivas_c + encoder_ivas_c - - - enc_ivas_c - - - enc_ivas_c + + encoder_ivas_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - enc_all_c + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c + + + encoder_all_c - enc_evs_c + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_ivas_c + + encoder_all_c + + + encoder_all_c + + + encoder_all_c + + + encoder_all_c + - enc_h + encoder_h + + + encoder_h - enc_h + encoder_h - enc_h + encoder_h - enc_h + encoder_h - - enc_h - - - enc_h + encoder_all_c - - {b7ee0526-8b79-4554-a3ec-04e51d38475f} + + {34137975-e4fd-40f0-938f-02fd46da5e22} - - {dabed049-70a2-48f2-9da6-3b81a3664033} + + {c24a3dcd-cde3-411b-aecf-747c29d87668} - - {5717f1cb-c593-400b-b23a-45c422fd95c8} + + {e78e5d72-8d6d-4b00-a6e0-64a62c9cf8f2} - - {6cccabbe-510f-43d3-90e1-8ed5ea3837d7} + + {597ebb71-22ba-41e8-b4bf-e8691bda2e5b} \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 1f95040e1..70a130e31 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -65,7 +65,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks diff --git a/apps/renderer.c b/apps/renderer.c index f5c0a8847..cf8112313 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -48,7 +48,6 @@ #include "vector3_pair_file_reader.h" #include "wmc_auto.h" -#include "prot_fx.h" #define WMC_TOOL_SKIP @@ -56,11 +55,15 @@ * Local constants *------------------------------------------------------------------------------------------*/ +#define Q15 15 +#define Q22 22 +#define Q31 31 +#define ONE_IN_Q31 0x7fffffff + #define RENDERER_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 - #define IVAS_MAX16B_FLT 32767.0f #define IVAS_MIN16B_FLT ( -32768.0f ) #define IVAS_MAX16B_FX 32767 @@ -428,6 +431,47 @@ static Word16 find_guard_bits( Word32 n ) : n <= 1024 ? 10 : 11; } + +static Word32 floatToFixed( float f, Word16 Q ) +{ + Word64 result_32; + + if ( f == 1.0f && Q == Q15 ) + return IVAS_MAX16B_FX; + if ( f == 1.0f && Q == Q31 ) + return MAXVAL_WORD32; + if ( Q < 0 ) + result_32 = (Word64) ( (float) ( f ) / (double) ( (unsigned Word64) 1 << ( -Q ) ) + ( f >= 0 ? 0.5 : -0.5 ) ); + else + result_32 = (Word64) ( f * (double) ( (unsigned Word64) 1 << Q ) + ( f >= 0 ? 0.5 : -0.5 ) ); + if ( result_32 > MAX_32 ) + return MAX_32; + if ( result_32 < MIN_32 ) + return MIN_32; + + return (Word32) result_32; +} + +/* note: This function is defined inside the library too with different name but same functionality */ +static void floatToFixed_arrL_app( float *f, Word32 *i, Word16 Q, Word16 l ) +{ + for ( int j = 0; j < l; j++ ) + { + Word64 i64_val = floatToFixed( f[j], Q ); + IF( i64_val > MAX_32 ) + { + i64_val = MAX_32; + } + ELSE IF( i64_val < MIN_32 ) + { + i64_val = MIN_32; + } + i[j] = (Word32) i64_val; + } + + return; +} + static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, const Word16 chBeginIdx, @@ -930,8 +974,8 @@ int main( /* Set up output custom layout configuration */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { - floatToFixed_arrL( args.outConfig.outSetupCustom.azimuth, args.outConfig.outSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); - floatToFixed_arrL( args.outConfig.outSetupCustom.elevation, args.outConfig.outSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.outConfig.outSetupCustom.azimuth, args.outConfig.outSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.outConfig.outSetupCustom.elevation, args.outConfig.outSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); if ( ( error = IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( hIvasRend, args.outConfig.outSetupCustom ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in IVAS_REND_ConfigureCustomOutputLoudspeakerLayout(): %s\n", ivas_error_to_string( error ) ); @@ -1018,8 +1062,8 @@ int main( if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { - floatToFixed_arrL( args.inConfig.inSetupCustom.azimuth, args.inConfig.inSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); - floatToFixed_arrL( args.inConfig.inSetupCustom.elevation, args.inConfig.inSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.inConfig.inSetupCustom.azimuth, args.inConfig.inSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.inConfig.inSetupCustom.elevation, args.inConfig.inSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); if ( ( error = IVAS_REND_ConfigureCustomInputLoudspeakerLayout( hIvasRend, mcIds[i], args.inConfig.inSetupCustom ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in IVAS_REND_ConfigureCustomInputLoudspeakerLayout(): %s\n", ivas_error_to_string( error ) ); diff --git a/lib_com/options.h b/lib_com/options.h index 288145122..9d5ca2e4c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -41,10 +41,6 @@ /* ################### Start DEBUGGING switches ######################## */ -#ifdef _MSC_VER -#pragma warning(disable:4310) /* cast truncates constant value this affects mainly constants tables*/ -#endif - /*#define DEBUGGING*/ /* Allows debugging message to be printed out during runtime */ #ifdef DEBUGGING #define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 45a16dc1a..26b219217 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -102,6 +102,13 @@ typedef struct } ARCODEC, *PARCODEC; +struct dispMem_fx +{ + Word16 prev_state; /*Q0 */ + Word32 prev_gain_code; /*Q16 */ + Word16 prev_gain_pit[6]; /*Q14 */ +}; + /*---------------------------------------------------------------* * ACELP Encoder/Decoder Static RAM * *---------------------------------------------------------------*/ diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 5c7f894b9..3e82d8c06 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1258,12 +1258,6 @@ typedef struct amrwb_io_dec_structure } AMRWB_IO_DEC_DATA, *AMRWB_IO_DEC_HANDLE; -struct dispMem_fx -{ - Word16 prev_state; /*Q0 */ - Word32 prev_gain_code; /*Q16 */ - Word16 prev_gain_pit[6]; /*Q14 */ -}; /*----------------------------------------------------------------------------------* * diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 0fa9aeb88..78fef6e22 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -43,7 +43,7 @@ #include "stat_com.h" #include "cnst.h" #include "ivas_cnst.h" -#include "stat_dec.h" /* Compilation switches */ + /*------------------------------------------------------------------------------------------* * Indice -- GitLab From 9508caea7d67fcbe993ab3ed4226caec014d29f1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Feb 2025 12:59:02 +0100 Subject: [PATCH 0256/1221] fix MSVC warning C4701 mentioned in MR1091 --- lib_com/ivas_dirac_com.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 2704c1f08..407b62da6 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -970,7 +970,7 @@ void computeDiffuseness_fixed( #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); - Word32 shiftEquiv; + Word32 shiftEquiv = L_add( 0, 0 ); Word16 shift_qtotal; if ( shift_q < 0 ) { -- GitLab From 887852872817fce5dcfc9053ffbb4c3e0b4675cd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Feb 2025 12:59:02 +0100 Subject: [PATCH 0257/1221] fix MSVC warning C4701 mentioned in MR1091 --- lib_com/ivas_dirac_com.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 2704c1f08..407b62da6 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -970,7 +970,7 @@ void computeDiffuseness_fixed( #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); - Word32 shiftEquiv; + Word32 shiftEquiv = L_add( 0, 0 ); Word16 shift_qtotal; if ( shift_q < 0 ) { -- GitLab From da62e16d5fe1e91d6895d3e1d99b694e3a63c4bb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Feb 2025 13:25:08 +0100 Subject: [PATCH 0258/1221] some cleaning --- lib_com/ivas_prot_fx.h | 5 +++-- lib_com/ivas_spar_com.c | 5 +++-- lib_com/options.h | 7 +++---- lib_rend/ivas_dirac_output_synthesis_dec.c | 12 +++--------- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 95dde1650..debac9a73 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4995,11 +4995,12 @@ void ivas_dirac_dec_get_response_fx( const Word16 ambisonics_order, Word16 Q_out ); -#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx +#ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx +/*This is a derivate to ivas_dirac_dec_get_response_fx with fixed Q_out=29*/ void ivas_dirac_dec_get_response_fx_29( const Word16 azimuth, const Word16 elevation, - Word32 *response_fx, /*Q_out*/ + Word32 *response_fx, /*Q_out=29*/ const Word16 ambisonics_order ); #endif diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index c6194b8de..9ef094977 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -7173,7 +7173,8 @@ void ivas_dirac_dec_get_response_fx( return; } -#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx +#ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx +/*This is a derivate to ivas_dirac_dec_get_response_fx with fixed Q_out=29*/ void ivas_dirac_dec_get_response_fx_29( const Word16 azimuth, const Word16 elevation, @@ -7307,7 +7308,7 @@ void ivas_dirac_dec_get_response_fx_29( pop_wmops(); /*push_wmops( "ivas_dirac_dec_get_response_fx_29" );*/ return; } -#endif /*FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx*/ +#endif /*FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx*/ /*-----------------------------------------------------------------------------------------* * Function ivas_get_bits_to_encode * diff --git a/lib_com/options.h b/lib_com/options.h index 8d464ccef..68914fa45 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -#define WMOPS /* Activate complexity and memory counters */ +//#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -171,9 +171,8 @@ #define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ - -#define FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, in development*/ // -1.5 WMOPS -#define FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, in development*/ // -1 WMOPS +#define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ +#define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ #endif diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 1bbecc555..68ca49ad9 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -914,7 +914,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" ); -#ifdef FIX1072_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot +#ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot FOR( ; k < num_freq_bands; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -933,10 +933,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_a_a_b = Mpy_32_32( a, a ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - // q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q, add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - // q_diff_aab = sub( add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ), 62 ); diff_aab_exp = sub( 31 + 62, add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ) ); - // q_diff_c = sub( q_diffuseness, 4 ); diff_c_exp = sub( 31 + 4, q_diffuseness ); sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/ @@ -948,10 +945,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 - // q_diff_aab = add( add(h_dirac_output_synthesis_state->direct_responses_q , sub( sub( 15, b_exp ), 15 )), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - // q_diff_aab = add( sub( h_dirac_output_synthesis_state->direct_responses_q, b_exp ), ( sub( add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ), 62 ) ) ); diff_aab_exp = sub( sub( add( sub( 31 + 62, h_dirac_output_synthesis_state->direct_responses_q ), b_exp ), h_dirac_output_synthesis_state->direct_responses_q ), q_diffuseness ); - // q_diff_c = sub( q_diffuseness, 4 ); diff_c_exp = sub( 31 + 4, q_diffuseness ); sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/ @@ -3149,7 +3143,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( ELSE { push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse__FX" ); -#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx +#ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order ); #else ivas_dirac_dec_get_response_fx( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_hoa ); @@ -3157,7 +3151,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( IF( hodirac_flag ) { -#ifdef FIX_1072_SPEEDUP_ivas_dirac_dec_get_response_fx +#ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order ); #else ivas_dirac_dec_get_response_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_dir2 ); -- GitLab From 67e59adf10ae3f19b1a1e4426bef5462236d91ee Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Feb 2025 12:29:47 +0000 Subject: [PATCH 0259/1221] Del push/pop wmops --- lib_com/ivas_dirac_com.c | 2 - lib_com/ivas_spar_com.c | 9 ----- lib_com/options.h | 4 +- lib_dec/ivas_dirac_dec.c | 18 +-------- lib_rend/ivas_dirac_output_synthesis_dec.c | 45 +--------------------- 5 files changed, 5 insertions(+), 73 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 43cffea7c..2704c1f08 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -960,7 +960,6 @@ void computeDiffuseness_fixed( q_intensity = add( q_factor_intensity[0], min_q_shift2 ); move16(); - push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" ); FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) { /* Energy slow */ @@ -1070,7 +1069,6 @@ void computeDiffuseness_fixed( q_intensity = s_min( q_intensity, q_tmp ); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness B <<-|" );/*/ min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) ); min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) ); diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 9ef094977..dc23ad8a0 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -7191,7 +7191,6 @@ void ivas_dirac_dec_get_response_fx_29( Word16 b, b1, b_2, b1_2; // Word16 Q_out = 29; - push_wmops( "ivas_dirac_dec_get_response_fx_29" ); index_azimuth = add( azimuth, 180 ) % 360; move16(); index_elevation = add( elevation, 90 ); @@ -7249,14 +7248,9 @@ void ivas_dirac_dec_get_response_fx_29( sin_az_fx[2] = L_shl( Mpy_32_32( sin_1_fx, L_sub( cos_2_fx, ONE_IN_Q28 /*1/4 q30*/ ) ), 3 ); /*q30*/ move32(); - // response_fx[0] = L_shl_sat( 1, Q_out ); // Q_out response_fx[0] = 0x20000000; move32(); - // q_diff = sub( Q_out, 29 ); - - push_wmops( "ivas_dirac_dec_get_response_fx_29_LOOPS" ); - FOR( l = 1; l <= ambisonics_order; l++ ) { Word16 a; @@ -7303,9 +7297,6 @@ void ivas_dirac_dec_get_response_fx_29( response_fx[b] = L_shl( c_fx_better, -1 ); // Q_out move32(); } - - pop_wmops(); /*push_wmops( "ivas_dirac_dec_get_response_fx_29_LOOPS" );*/ - pop_wmops(); /*push_wmops( "ivas_dirac_dec_get_response_fx_29" );*/ return; } #endif /*FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx*/ diff --git a/lib_com/options.h b/lib_com/options.h index 68914fa45..19b588da3 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -56,7 +56,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -//#define WMOPS /* Activate complexity and memory counters */ +/*#define WMOPS*/ /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -173,6 +173,4 @@ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ #define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ - - #endif diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 77287dc76..95cca12a0 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2231,7 +2231,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); Word16 tmp1; - push_wmops( "ivas_dirac_dec_render (IDR)" ); + push_wmops( "ivas_dirac_dec_render" ); /* Initialize aux buffers */ hDirAC = st_ivas->hDirAC; @@ -2341,7 +2341,6 @@ void ivas_dirac_dec_render_sf_fx( } ELSE IF( !( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) { - push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" ); Word16 outchannels; idx_lfe = 0; move16(); @@ -2410,7 +2409,6 @@ void ivas_dirac_dec_render_sf_fx( } } } - pop_wmops(); /*push_wmops( "(IDR) SBA_FORMAT | SBA_ISM_FORMAT" );*/ } size = imult1616( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); @@ -2708,7 +2706,6 @@ void ivas_dirac_dec_render_sf_fx( } } - push_wmops( "(IDR) LOOP1" ); FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { index_slot = add( slot_idx_start, slot_idx ); @@ -2926,8 +2923,6 @@ void ivas_dirac_dec_render_sf_fx( move16(); BREAK; default: - pop_wmops(); /* push_wmops( "ivas_dirac_dec_render (IDR)" );*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1");/*/ return; } q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; @@ -2937,7 +2932,6 @@ void ivas_dirac_dec_render_sf_fx( /*-----------------------------------------------------------------* * Compute DirAC parameters at decoder side *-----------------------------------------------------------------*/ - push_wmops( "(IDR) LOOP1 DirACparams |" ); IF( EQ_16( hDirAC->hConfig->dec_param_estim, TRUE ) ) { Copy( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], sub( hSpatParamRendCom->num_freq_bands, hDirAC->hConfig->enc_param_start_band ) ); @@ -2986,11 +2980,8 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; move16(); - push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" ); computeDiffuseness_fixed( hDirACRend->buffer_intensity_real_fx, hDirACRend->buffer_energy_fx, num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], hDirACRend->q_buffer_intensity_real, hDirACRend->q_buffer_energy, &hSpatParamRendCom->q_diffuseness_vector ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 DirACparams computeDiffuseness <-|" );/*/ } - pop_wmops(); /* push_wmops( "(IDR) LOOP1 DirACparams |" );*/ /*-----------------------------------------------------------------* * frequency domain decorrelation @@ -3092,7 +3083,6 @@ void ivas_dirac_dec_render_sf_fx( } /*Compute PSDs*/ - push_wmops( "(IDR) LOOP1 PSDs |" ); h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params ); h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state ); num_channels_dir = hDirACRend->num_outputs_dir; @@ -3175,7 +3165,6 @@ void ivas_dirac_dec_render_sf_fx( } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" ); ivas_dirac_dec_output_synthesis_process_slot_fx( reference_power_fx, DirAC_mem.reference_power_q, p_onset_filter_fx, @@ -3193,7 +3182,6 @@ void ivas_dirac_dec_render_sf_fx( md_idx, hodirac_flag, hDirAC->hConfig->dec_param_estim ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 <-|" );/*/ } IF( hDirAC->hConfig->dec_param_estim ) @@ -3264,9 +3252,7 @@ void ivas_dirac_dec_render_sf_fx( v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); q_reference_power_smooth = sub( q_reference_power_smooth, 1 ); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs |" );*/ } - pop_wmops(); /*push_wmops( "(IDR) LOOP1" );*/ minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) @@ -4092,7 +4078,7 @@ void ivas_dirac_dec_render_sf_fx( } } - pop_wmops(); /*push_wmops( "ivas_dirac_dec_render (IDR)" );*/ + pop_wmops(); return; } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 68ca49ad9..c0327f3af 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -710,13 +710,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } - push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" ); test(); IF( dec_param_estim == FALSE && hodirac_flag ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" ); v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */ v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/ Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx], @@ -739,23 +737,19 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); h_dirac_output_synthesis_state->direct_power_factor_q = 30; move16(); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B1<<<-|" );/*/ } ELSE { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" ); ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], h_dirac_output_synthesis_state->direct_power_factor_fx, h_dirac_output_synthesis_state->diffuse_power_factor_fx, &h_dirac_output_synthesis_state->direct_power_factor_q, &h_dirac_output_synthesis_state->diffuse_power_factor_q ); - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B2<<<-|" );*/ } } ELSE IF( EQ_16( dec_param_estim, TRUE ) ) { - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" ); /* compute direct responses */ ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom, hDirACRend, @@ -817,7 +811,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Q_temp_cy_cross_dir_smooth_fx[kk] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth; move16(); } - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" ); + FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ ) { Word16 k; @@ -912,8 +906,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ - - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" ); #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot FOR( ; k < num_freq_bands; k++ ) { @@ -1064,9 +1056,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } #endif - - - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop B <<<<<-|" );*/ } ELSE { @@ -1142,8 +1131,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 bigloop <<<<-|" );/*/ - Word16 temp = MAX_16; /*q0*/ move16(); tmp16 = imult1616( num_freq_bands, num_channels_dir ); @@ -1160,8 +1147,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } free( Q_temp_cy_cross_dir_smooth_fx ); /*Directional gain (panning)*/ - push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" ); - Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { @@ -1243,7 +1228,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ } #endif - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3.3 gainpanning <<<<-|" );*/ /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) @@ -1262,8 +1246,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/ } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3 <<-|" );/*/ - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ + return; } ELSE @@ -1282,9 +1265,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( h_dirac_output_synthesis_state->direct_power_factor_q = 31; move16(); } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B3<<<-|" );/*/ } - pop_wmops(); /*push_wmops( "(IDR) LOOP1 PSDs PATH3 B <<-|" );/*/ diff_start_band = 0; move16(); @@ -3032,8 +3013,6 @@ void ivas_dirac_dec_compute_directional_responses_fx( Word16 dipole_freq_range[2]; MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type; - push_wmops( "(IDR PATH3 B3.1)" ); - Q_direct_response_ls = Q31; move16(); exp_direct_response_ls = 0; @@ -3095,7 +3074,6 @@ void ivas_dirac_dec_compute_directional_responses_fx( LT_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) && NE_16( k, hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) ) { - push_wmops( "(IDR PATH3 B3.1) mvr2r_inc_fixed " ); /* Panning gains have to be computed only for the first bin of the coding band in MASA, for other bins the previous values can be used */ IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { @@ -3107,15 +3085,12 @@ void ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/ - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) mvr2r_inc_fixed " );*/ } ELSE { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING " ); /* HOA3 PANNING */ IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_HOA3 ) ) { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF" ); set32_fx( direct_response_hoa_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/ set32_fx( direct_response_dir2_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/ @@ -3128,21 +3103,17 @@ void ivas_dirac_dec_compute_directional_responses_fx( exp_direct_response_dir2 = 0; move16(); - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse" ); IF( p_Rmat != 0 ) { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse_SPLIT_FX" ); ivas_dirac_dec_get_response_split_order_fx( azimuth[k], elevation[k], direct_response_hoa_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_hoa ); IF( hodirac_flag ) { ivas_dirac_dec_get_response_split_order_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_dir2 ); } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse_SPLIT_FX" );*/ } ELSE { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse__FX" ); #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order ); #else @@ -3157,9 +3128,7 @@ void ivas_dirac_dec_compute_directional_responses_fx( ivas_dirac_dec_get_response_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_dir2 ); #endif } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse__FX" );*/ } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- getResponse" );*/ test(); test(); @@ -3167,19 +3136,16 @@ void ivas_dirac_dec_compute_directional_responses_fx( test(); IF( masa_band_mapping == NULL && EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH1" ); mvr2r_inc_fixed( direct_response_hoa_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_hoa*/ IF( hodirac_flag ) { mvr2r_inc_fixed( direct_response_dir2_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_dir2*/ } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH1" );*/ } ELSE IF( ( ( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) && ( masa_band_mapping != NULL ) ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH2" ); /* Synthesize the first direction */ IF( GT_16( Q_direct_response_hoa, Q29 ) ) { @@ -3426,17 +3392,14 @@ void ivas_dirac_dec_compute_directional_responses_fx( } mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*q29*/ - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF -- PATH2" );*/ } ELSE { assert( 0 && "Not supported synthesis method!" ); } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING IF" );*/ } ELSE IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_VBAP ) ) /*VBAP*/ { - push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING ELSE" ); /* Synthesize the first direction */ spreadCoherencePanningVbap_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k], direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir, hVBAPdata ); @@ -3688,13 +3651,11 @@ void ivas_dirac_dec_compute_directional_responses_fx( mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/ mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/ - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING ELSE" );*/ } ELSE { assert( 0 && "Not supported panning method!" ); } - pop_wmops(); /*push_wmops( "(IDR PATH3 B3.1) HOA3 PANNING " );*/ } } @@ -3703,8 +3664,6 @@ void ivas_dirac_dec_compute_directional_responses_fx( hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = direct_response_square_q; move16(); - - pop_wmops(); return; } -- GitLab From d3d63a8b48f4661a64f9dfc3307c043fd090ed9b Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 26 Feb 2025 14:37:27 +0100 Subject: [PATCH 0260/1221] applied the clang patch. --- lib_com/ivas_tools.c | 4 ++-- lib_enc/speech_music_classif_fx.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 6cb13740a..2b62a0e5a 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -654,7 +654,7 @@ Word32 dot_product_cholesky_fixed( Word64 dot_product_cholesky_fixed64( const Word32 *x, /* i : vector x Q31 - exp_x*/ const Word32 *A, /* i : Cholesky matrix A Q31 - exp_A*/ - const Word16 N /* i : vector & matrix size Q0*/ + const Word16 N /* i : vector & matrix size Q0*/ ) { Word16 i, j; @@ -676,7 +676,7 @@ Word64 dot_product_cholesky_fixed64( mul = Mpy_32_32( *pt_x++, *pt_A++ ); tmp_sum = W_add( tmp_sum, W_deposit32_l( mul ) ); } - tmp_sum = W_shr( tmp_sum, 4 ); // to make sure that the tmp_sum will not overflow + tmp_sum = W_shr( tmp_sum, 4 ); // to make sure that the tmp_sum will not overflow tmp = W_extract_l( tmp_sum ); suma = W_mac_32_32( suma, tmp, tmp ); } diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index da93127bf..fe6647a6c 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2271,15 +2271,15 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); } -- GitLab From 82c5e4ca92329673e3fcaca14d11e967c2f37350 Mon Sep 17 00:00:00 2001 From: malenov Date: Wed, 26 Feb 2025 15:35:42 +0100 Subject: [PATCH 0261/1221] make DEBUG_FORCE_DIR inactive by default --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 46ea18c9d..92c0dd78c 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -50,7 +50,7 @@ #define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ #define DEBUG_MODE_INFO_TWEAK /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */ #define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ -#define DEBUG_FORCE_DIR /* Force modes/parameters by reading from external binary files */ +/*#define DEBUG_FORCE_DIR*/ /* Force modes/parameters by reading from external binary files */ /*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ #define SUPPORT_FORCE_TCX10_TCX20 /* VA: Enable -force tcx10|tcx20 command-line option */ #endif -- GitLab From bfad31be34fc246c8a128dea91c6ca90e56088cb Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 26 Feb 2025 15:52:16 +0100 Subject: [PATCH 0262/1221] clang format --- lib_enc/ivas_core_pre_proc_front.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 9fc530fa4..184c07505 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1786,7 +1786,7 @@ ivas_error pre_proc_front_ivas_fx( dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc2.enf" ); dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision0.enf" ); dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision1.enf" ); - dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); + dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); } #endif -- GitLab From c7d647c34c6a5a8345e1f28fab9bb63aee47d779 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Feb 2025 09:26:19 +0530 Subject: [PATCH 0263/1221] Adding fix for non-uniform q in first_VQstages --- lib_enc/gs_enc_fx.c | 4 ++++ lib_enc/ivas_core_pre_proc_front.c | 2 +- lib_enc/lsf_enc_fx.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 357e88410..7ae8fb42e 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -679,7 +679,11 @@ void encod_audio_ivas_fx( *--------------------------------------------------------------------------------------*/ edct_16fx( dct_epit, exc, st_fx->L_frame, 7, st_fx->element_mode ); + scale_sig( exc, st_fx->L_frame, sub( Q_new, Q_exc ) ); edct_16fx( exc_wo_nf, exc_wo_nf, st_fx->L_frame, 7, st_fx->element_mode ); + scale_sig( exc_wo_nf, st_fx->L_frame, sub( Q_new, Q_exc ) ); + Q_exc = Q_new; + move16(); /*--------------------------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected *--------------------------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 6ab82420f..a77c4e36a 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -627,7 +627,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); set32_fx( sig_out, 0, 960 ); - headroom = 1; + headroom = 2; move16(); test(); diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 3f3f91392..52f15471f 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -2133,7 +2133,7 @@ static void first_VQstages( L_tmp1 = Mult_32_16( L_tmp1, u[j] ); /*x2.56 + Q15 + x2.56 -Q15 */ L_tmp = L_add( L_tmp, L_tmp1 ); /*Q0 + x2.56 +x2.56 */ } - set32_fx( dist[1], L_tmp, maxC ); + set32_fx( dist[1], L_shr( L_tmp, 1 ), maxC ); /*Q-1 + x2.56 +x2.56 */ /* Set up initial error (residual) vectors */ pTmp = resid[1]; @@ -2192,15 +2192,15 @@ static void first_VQstages( /* compute weighted codebook element and its energy */ FOR( c2 = 0; c2 < N; c2++ ) { - Tmp[c2] = shl( mult( w[c2], cbp[c2] ), 2 ); /* Q8 + x2.56 -Q15 +Q2 */ + Tmp[c2] = extract_h( L_shl( L_mult0( w[c2], cbp[c2] ), 6 ) ); /* Q8 + x2.56 + q6 -q16 */ move16(); } - en = L_mult( cbp[0], Tmp[0] ); + en = L_mult( cbp[0], Tmp[0] ); /*x2.56 + x2.56 + Q-2 +Q1 */ FOR( c2 = 1; c2 < N; c2++ ) { - en = L_mac( en, cbp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-5 +Q1 */ + en = L_mac( en, cbp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-2 +Q1 */ } cbp += N; move16(); @@ -2208,15 +2208,15 @@ static void first_VQstages( /* iterate over all parent nodes */ FOR( c = 0; c < m; c++ ) { - pTmp = &resid[0][c * N]; + pTmp = &resid[0][c * N]; /*x2.56*/ move16(); - L_tmp = L_mult( pTmp[0], Tmp[0] ); + L_tmp = L_mult( pTmp[0], Tmp[0] ); /*x2.56 + x2.56 + Q-2 +Q1 */ FOR( c2 = 1; c2 < N; c2++ ) { - L_tmp = L_mac( L_tmp, pTmp[c2], Tmp[c2] ); /* */ + L_tmp = L_mac( L_tmp, pTmp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-2 +Q1 */ } - L_tmp = L_add( dist[0][c], L_sub( en, L_shl( L_tmp, 1 ) ) ); + L_tmp = L_add( dist[0][c], L_sub( en, L_shl( L_tmp, 1 ) ) ); /*x2.56 + x2.56 -1*/ IF( LE_32( L_tmp, dist[1][p_max] ) ) { -- GitLab From cedd8d6fecad8081d81dd4f0a246a5b084795a14 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Feb 2025 16:10:52 +0530 Subject: [PATCH 0264/1221] Fix for EVS BE issue --- lib_enc/lsf_enc_fx.c | 193 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 2 deletions(-) diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 52f15471f..45a4e014a 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -2125,6 +2125,196 @@ static void first_VQstages( set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); + /* Set up inital distance vector */ + L_tmp = L_deposit_l( 0 ); + FOR( j = 0; j < N; j++ ) + { + L_tmp1 = L_shl_o( L_mult0( u[j], w[j] ), 7, &Overflow ); /*x2.56 + Q8 + Q7 */ + L_tmp1 = Mult_32_16( L_tmp1, u[j] ); /*x2.56 + Q15 + x2.56 -Q15 */ + L_tmp = L_add( L_tmp, L_tmp1 ); /*Q0 + x2.56 +x2.56 */ + } + set32_fx( dist[1], L_tmp, maxC ); + + /* Set up initial error (residual) vectors */ + pTmp = resid[1]; + move16(); + FOR( c = 0; c < maxC; c++ ) + { + Copy( u, pTmp, N ); + pTmp += N; + } + + /*----------------------------------------------------------------* + * LSF quantization + *----------------------------------------------------------------*/ + + /* Loop over all stages */ + m = 1; + move16(); + FOR( s = 0; s < stagesVQ; s++ ) + { + /* set codebook pointer to point to first stage */ + cbp = cb[s]; + move16(); + + /* save pointer to the beginning of the current stage */ + cb_stage = cbp; + move16(); + + /* swap pointers to parent and current nodes */ + pTmp_short = indices[0]; + indices[0] = indices[1]; + move16(); + indices[1] = pTmp_short; + move16(); + + pTmp = resid[0]; + resid[0] = resid[1]; + move16(); + resid[1] = pTmp; + move16(); + + pTmp32 = dist[0]; + dist[0] = dist[1]; + move32(); + dist[1] = pTmp32; + move32(); + + /* p_max points to maximum distortion node (worst of best) */ + p_max = 0; + move16(); + + /* set distortions to a large value */ + set32_fx( dist[1], MAXINT32, maxC ); + + FOR( j = 0; j < levels[s]; j++ ) + { + /* compute weighted codebook element and its energy */ + FOR( c2 = 0; c2 < N; c2++ ) + { + Tmp[c2] = shl( mult( w[c2], cbp[c2] ), 2 ); /* Q8 + x2.56 -Q15 +Q2 */ + move16(); + } + + en = L_mult( cbp[0], Tmp[0] ); + + FOR( c2 = 1; c2 < N; c2++ ) + { + en = L_mac( en, cbp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-5 +Q1 */ + } + cbp += N; + move16(); + + /* iterate over all parent nodes */ + FOR( c = 0; c < m; c++ ) + { + pTmp = &resid[0][c * N]; + move16(); + L_tmp = L_mult( pTmp[0], Tmp[0] ); + FOR( c2 = 1; c2 < N; c2++ ) + { + L_tmp = L_mac( L_tmp, pTmp[c2], Tmp[c2] ); /* */ + } + + L_tmp = L_add( dist[0][c], L_sub( en, L_shl( L_tmp, 1 ) ) ); + + IF( LE_32( L_tmp, dist[1][p_max] ) ) + { + /* replace worst */ + dist[1][p_max] = L_tmp; + move32(); + indices[1][p_max * stagesVQ + s] = j; + move16(); + parents[p_max] = c; + move16(); + + /* limit number of times inner loop is entered */ + IF( LT_16( counter, max_inner ) ) + { + counter = add( counter, 1 ); + IF( LT_16( counter, max_inner ) ) + { + /* find new worst */ + p_max = maximum_32_fx( dist[1], maxC, &f_tmp ); + } + ELSE + { + /* find minimum distortion */ + p_max = minimum_32_fx( dist[1], maxC, &f_tmp ); + } + } + } + } + } + + /*------------------------------------------------------------* + * Compute error vectors for each node + *------------------------------------------------------------*/ + cs = 0; + move16(); + FOR( c = 0; c < maxC; c++ ) + { + /* subtract codebook entry from the residual vector of the parent node */ + pTmp = resid[1] + c * N; + move16(); + Copy( resid[0] + parents[c] * N, pTmp, N ); + Vr_subt( pTmp, cb_stage + ( indices[1][cs + s] ) * N, pTmp, N ); + + /* get indices that were used for parent node */ + Copy( indices[0] + parents[c] * stagesVQ, indices[1] + cs, s ); + cs = add( cs, stagesVQ ); + } + + m = maxC; + move16(); + } + + Copy( indices[1], indices_VQstage, maxC * stagesVQ ); + + return; +} + +static void first_VQstages_ivas_fx( + const Word16 *const *cb, + Word16 u[], /* i : vector to be encoded (prediction and mean removed) */ + Word16 *levels, /* i : number of levels in each stage */ + Word16 stagesVQ, /* i : number of stages */ + Word16 w[], /* i : weights */ + Word16 N, /* i : vector dimension */ + Word16 max_inner, /* i : maximum number of swaps in inner loop */ + Word16 indices_VQstage[] ) +{ + Word16 resid_buf[2 * LSFMBEST * M], *resid[2]; + Word32 dist_buf[2 * LSFMBEST], *dist[2], en; + Word32 f_tmp, L_tmp, L_tmp1, *pTmp32; + Word16 Tmp[M], *pTmp, cs; + Word16 *pTmp_short, idx_buf[2 * LSFMBEST * MAX_VQ_STAGES], parents[LSFMBEST], counter = 0, j, + m, s, c, c2, p_max, *indices[2]; + Word16 maxC = LSFMBEST; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*float dd[16];*/ + const Word16 *cb_stage, *cbp; + + /* Set pointers to previous (parent) and current node (parent node is indexed [0], current node is indexed [1]) */ + indices[0] = idx_buf; + move16(); + indices[1] = idx_buf + maxC * stagesVQ; + move16(); + resid[0] = resid_buf; + move16(); + resid[1] = resid_buf + maxC * N; + move16(); + dist[0] = dist_buf; + move16(); + dist[1] = dist_buf + maxC; + move16(); + + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( parents, 0, maxC ); + /* Set up inital distance vector */ L_tmp = L_deposit_l( 0 ); FOR( j = 0; j < N; j++ ) @@ -2273,7 +2463,6 @@ static void first_VQstages( return; } - /*--------------------------------------------------------------------------- * vq_enc_lsf_lvq() * @@ -2457,7 +2646,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( stagesVQ > 0 ) { /* first VQ stages */ - first_VQstages( cb, u, levels, stagesVQ, w, M, MSVQ_MAXCNT, indices_firstVQ ); + first_VQstages_ivas_fx( cb, u, levels, stagesVQ, w, M, MSVQ_MAXCNT, indices_firstVQ ); } -- GitLab From d034a0b0bcd88313c3cfd77992a70270b546ffa1 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 27 Feb 2025 12:54:31 +0100 Subject: [PATCH 0265/1221] disable per-testcase timeouts on msan jobs --- .gitlab-ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c51f8c54d..d3eb06636 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -750,8 +750,12 @@ stages: - fi - make clean - make -j $make_args - - testcase_timeout=$TESTCASE_TIMEOUT_LTV_SANITIZERS - - python3 -m pytest $TEST_SUITE -v --tb=no --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout $testcase_timeout --ref_encoder_path $DUT_ENCODER_PATH --ref_decoder_path $DUT_DECODER_PATH + - testcase_timeout_arg="--testcase_timeout $TESTCASE_TIMEOUT_LTV_SANITIZERS" + # disable per-testcase timeout for msan to evaluate what is going on that it takes so long + - if [[ $CLANG_NUM = 1 ]]; then + - testcase_timeout_arg="" + - fi + - python3 -m pytest $TEST_SUITE -v --tb=no --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml $testcase_timeout_arg --ref_encoder_path $DUT_ENCODER_PATH --ref_decoder_path $DUT_DECODER_PATH artifacts: name: "$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA--results" when: always -- GitLab From 50852fa60db649b94a3e7da799c17a82af7579fe Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Feb 2025 18:30:52 +0530 Subject: [PATCH 0266/1221] Fix for 3GPP issue 1308: Large differences between BASOP and float for critical item in MDCT-stereo @96kbps Link #1308 --- lib_com/lpc_tools_fx.c | 85 +++++++++++++++++++++++++++++++++++++++ lib_com/prot_fx.h | 1 + lib_com/stat_com.h | 1 + lib_com/tns_base.c | 2 + lib_enc/cod_tcx.c | 41 ++++++++++--------- lib_enc/prot_fx_enc.h | 3 +- lib_enc/tns_base_enc_fx.c | 74 +++++++++++++++++++++++++++++----- 7 files changed, 175 insertions(+), 32 deletions(-) diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index ef6c0b0ff..bde05b4f4 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -1210,6 +1210,91 @@ Word16 E_LPC_lsp_unweight( return 0; } +/* + * E_LPC_schur_ivas + * + * Parameters: + * R I: Rh[M+1] Vector of autocorrelations (msb) + * reflCoeff O: rc[M] Reflection coefficients. Q15 + * epsP O: error vector + * + * Function: + * Schur algorithm to compute + * the LPC parameters from the autocorrelations of speech. + * + * Returns: + * void + */ +Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m ) +{ + Word16 i, j, temp16, mMi, s; + Word32 g0[M], *g1, tmp32; + const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */ + Word32 tmp_epsP; + + s = getScaleFactor32( r, add( m, 1 ) ); + IF( s != 0 ) + { + scale_sig32( r, add( m, 1 ), s ); /* scale in-place */ + } + + g1 = r; + Copy32( r + 1, g0, m ); + + /* compute g0[0]/g1[0], where g0[0] < g1[0] */ + temp16 = negate( divide3232( g0[0], g1[0] ) ); + reflCoeff[0] = temp16; + move16(); + // epsP[0] = r[0]; + move32(); + + + FOR( i = 0; i < m; i++ ) + { + /* g1[0] = g0[0]*temp16 + g1[0]; */ + tmp32 = Mpy_32_16_1( g0[0], temp16 ); + g1[0] = L_add( g1[0], tmp32 ); + move32(); + + mMi = sub( m, i ); + FOR( j = 1; j < mMi; j++ ) + { + /* g0[j-1] = g0[j] + g1[j]*temp16; + g1[j] = g0[j]*temp16 + g1[j]; */ + g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) ); + move32(); + g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) ); + move32(); + } + temp16 = negate( divide3232( g0[0], g1[0] ) ); + reflCoeff[i + 1] = temp16; + move16(); + + /* Prediction errors */ + tmp_epsP = L_shr( g1[0], s ); + if ( tmp_epsP <= 0 ) + { + tmp_epsP = min_epsP; + move32(); + } + // epsP[i + 1] = tmp_epsP; + move32(); + } + + /* epsP[i+1] = g0[0]*temp16 + g1[0]; */ + tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) ); + tmp_epsP = L_shr( tmp_epsP, s ); + if ( tmp_epsP <= 0 ) + { + tmp_epsP = min_epsP; + move32(); + } + + /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */ + + + return g1[0]; +} /* * E_LPC_schur diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c67e2da28..5a6e24046 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1198,6 +1198,7 @@ Word16 E_LPC_lsp_unweight( ); Word32 E_LPC_schur( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, Word32 epsP[] /*Qr*/, const Word16 m ); +Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m ); void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/, const Word16 *old_lsf /*15Q16*/, Word16 lpcOrder, Word8 lpcRep /*Q0*/ ); diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 2340c7a75..b1b1d1f61 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -197,6 +197,7 @@ typedef struct TNS_filter_structure Word16 order; /* Filter order. */ Word16 coefIndex[TNS_MAX_FILTER_ORDER]; /* Quantized filter coefficients. */ Word16 predictionGain; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q7 */ + Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ Word16 avgSqrCoef; /* Average squared filter coefficient. E(0), Q15 */ } STnsFilter; diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index af4a87d34..b5fd1f41f 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -1202,6 +1202,8 @@ void ResetTnsData( STnsData *pTnsData ) move16(); pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/ move16(); + pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/ + move32(); pTnsFilter->avgSqrCoef = 0; move16(); pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/ diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 25f615e6a..d0d36b502 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -55,8 +55,9 @@ * *-------------------------------------------------------------------*/ -#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) +#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 ) void TNSAnalysisStereo_fx( Encoder_State **sts, /* i : encoder state handle */ Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/ @@ -72,7 +73,7 @@ void TNSAnalysisStereo_fx( Encoder_State *st = NULL; TCX_ENC_HANDLE hTcxEnc = NULL; Word16 individual_decision[NB_DIV]; - Word16 maxPredictionGain_fx = 0, meanPredictionGain_fx; + Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; move16(); individual_decision[0] = 0; @@ -144,7 +145,7 @@ void TNSAnalysisStereo_fx( BREAK; } - CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k], NULL ); + CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] ); } } } @@ -209,7 +210,7 @@ void TNSAnalysisStereo_fx( test(); IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word16 maxPredGain_fx = -ONE_IN_Q7; + Word32 maxPredGain_fx = -ONE_IN_Q23; move16(); sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; @@ -227,30 +228,30 @@ void TNSAnalysisStereo_fx( * both filters for the decision */ - meanPredictionGain_fx = mac_r( L_mult( pFilter[0]->predictionGain, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain, 16384 /*0.5f Q15*/ ); // Q7 - maxPredictionGain_fx = s_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q7 + meanPredictionGain_fx = L_add( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ) ); // Q23 + maxPredictionGain_fx = L_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q23 test(); test(); test(); - IF( GT_16( pFilter[0]->predictionGain, pTnsParameters[0]->minPredictionGain ) && LT_32( sts[0]->element_brate, IVAS_80k ) && - GT_16( pFilter[1]->predictionGain, pTnsParameters[1]->minPredictionGain ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + IF( GT_32( pFilter[0]->predictionGain32, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && + GT_32( pFilter[1]->predictionGain32, L_shl( pTnsParameters[1]->minPredictionGain, 16 ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) { - pFilter[0]->predictionGain = pFilter[1]->predictionGain = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ + pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ move16(); move16(); } test(); - IF( LT_16( abs_s( sub( pFilter[0]->predictionGain, pFilter[1]->predictionGain ) ), mult( SIMILAR_TNS_THRESHOLD_FX_IN_Q15, meanPredictionGain_fx ) ) && + IF( LT_32( L_abs( L_sub( pFilter[0]->predictionGain32, pFilter[1]->predictionGain32 ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) { Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - maxPredGain_fx = s_max( maxPredGain_fx, meanPredictionGain_fx ); + maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); test(); test(); - IF( GT_16( meanPredictionGain_fx, pTnsParameters[0]->minPredictionGain ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + IF( GT_32( meanPredictionGain_fx, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) { test(); test(); @@ -456,7 +457,7 @@ void TNSAnalysisStereo_fx( test(); test(); test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_16( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; move16(); @@ -476,7 +477,7 @@ void TNSAnalysisStereo_fx( ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); } } - maxPredictionGain_fx = s_max( maxPredictionGain_fx, maxPredGain_fx ); + maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); } } } @@ -514,7 +515,7 @@ void TNSAnalysisStereo_fx( IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word16 maxPredGain_fx = -ONE_IN_Q7; // Q7 + Word32 maxPredGain_fx = -ONE_IN_Q23; // Q23 move16(); sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; @@ -525,9 +526,9 @@ void TNSAnalysisStereo_fx( pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - maxPredGain_fx = s_max( maxPredGain_fx, pFilter->predictionGain ); + maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); test(); - IF( GT_16( pFilter->predictionGain, pTnsParameters->minPredictionGain ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + IF( GT_32( pFilter->predictionGain32, L_shl( pTnsParameters->minPredictionGain, 16 ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) { test(); test(); @@ -601,7 +602,7 @@ void TNSAnalysisStereo_fx( move16(); test(); test(); - IF( !bWhitenedDomain && LT_16( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[ch]->hTcxEnc->fUseTns[k] = 0; move16(); @@ -616,7 +617,7 @@ void TNSAnalysisStereo_fx( move16(); } } - maxPredictionGain_fx = s_max( maxPredictionGain_fx, maxPredGain_fx ); + maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); } } } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 38552ba0d..a8e7f1047 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1629,8 +1629,7 @@ void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ const Word16 pSpectrum_e, - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain Q7*/ + STnsData *pTnsData /* o : TNS data struct */ ); /** Detect TNS parameters. diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index d1763e039..cc9596ba0 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -26,6 +26,8 @@ */ static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ); +static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ); + /** Quantization for reflection coefficients. * * @param parCoeff input reflection coefficients. @@ -313,8 +315,7 @@ void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum */ const Word16 pSpectrum_e, - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain */ + STnsData *pTnsData /* o : TNS data struct */ ) { Word32 norms[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; @@ -410,17 +411,10 @@ void CalculateTnsFilt_fx( pFilter->spectrumLength = spectrumLength; move16(); /* Limit the maximum order to spectrum length/4 */ - GetFilterParameters( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); + GetFilterParameters_ivas( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); } } - IF( predictionGain ) - { - assert( pTnsConfig->nMaxFilters == 1 ); - *predictionGain = pTnsData->filter->predictionGain; - move16(); - } - return; } @@ -845,7 +839,67 @@ Word16 WriteTnsData_ivas_fx( STnsConfig const *pTnsConfig, Word16 const *stream, /********************************/ /* Private functions */ /********************************/ +static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ) +{ + Word16 i; + Word16 parCoeff[TNS_MAX_FILTER_ORDER + 1]; + Word32 rxx_0; + Word32 L_tmp; +#if TNS_COEF_RES == 5 + Word16 const *values = tnsCoeff5; +#elif TNS_COEF_RES == 4 + Word16 const *values = tnsCoeff4; +#elif TNS_COEF_RES == 3 + Word16 const *values = tnsCoeff3; +#endif + Word16 *indexes = pTnsFilter->coefIndex; + + rxx_0 = rxx[0]; + move32(); + /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ + L_tmp = E_LPC_schur_ivas( rxx, parCoeff, maxOrder ); + BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, this value is compared against a threshold. */ + Word16 temp_e = 0; + move16(); + Word16 temp = BASOP_Util_Divide3232_Scale( rxx_0, L_tmp, &temp_e ); + pTnsFilter->predictionGain32 = L_shl( temp, ( sub( add( 16, temp_e ), PRED_GAIN_E ) ) ); // Q23 + move32(); + pTnsFilter->predictionGain = extract_h( pTnsFilter->predictionGain32 ); // Q7 + move16(); + BASOP_SATURATE_WARNING_ON_EVS + /* non-linear quantization of TNS lattice coefficients with given resolution */ + Parcor2Index( parCoeff, indexes, maxOrder ); + /* reduce filter order by truncating trailing zeros */ + i = sub( maxOrder, 1 ); + + test(); + WHILE( ( i >= 0 ) && ( indexes[i] == 0 ) ) + { + i = sub( i, 1 ); + } + + + pTnsFilter->order = add( i, 1 ); + move16(); + + /* compute avg(coef*coef) */ + L_tmp = L_deposit_l( 0 ); + + FOR( i = pTnsFilter->order - 1; i >= 0; i-- ) + { + Word16 value; + + value = shr( values[indexes[i] + INDEX_SHIFT], 1 ); + + L_tmp = L_mac0( L_tmp, value, value ); + } + + pTnsFilter->avgSqrCoef = round_fx( L_tmp ); + move16(); + /* assert(maxOrder == 8); + pTnsFilter->avgSqrCoef = shr(pTnsFilter->avgSqrCoef, 3); */ +} static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ) { Word16 i; -- GitLab From 643d82a6a705e2fa53484c8941c439b18e8023d1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Feb 2025 18:34:48 +0530 Subject: [PATCH 0267/1221] Clang formatting changes --- lib_com/stat_com.h | 2 +- lib_enc/prot_fx_enc.h | 2 +- lib_enc/tns_base_enc_fx.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index b1b1d1f61..af097da84 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -197,7 +197,7 @@ typedef struct TNS_filter_structure Word16 order; /* Filter order. */ Word16 coefIndex[TNS_MAX_FILTER_ORDER]; /* Quantized filter coefficients. */ Word16 predictionGain; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q7 */ - Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ + Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ Word16 avgSqrCoef; /* Average squared filter coefficient. E(0), Q15 */ } STnsFilter; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index a8e7f1047..58da977a7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1629,7 +1629,7 @@ void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ const Word16 pSpectrum_e, - STnsData *pTnsData /* o : TNS data struct */ + STnsData *pTnsData /* o : TNS data struct */ ); /** Detect TNS parameters. diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index cc9596ba0..452842e30 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -879,7 +879,7 @@ static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter i = sub( i, 1 ); } - + pTnsFilter->order = add( i, 1 ); move16(); @@ -894,7 +894,7 @@ static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter L_tmp = L_mac0( L_tmp, value, value ); } - + pTnsFilter->avgSqrCoef = round_fx( L_tmp ); move16(); /* assert(maxOrder == 8); -- GitLab From dd7e49514ef58cc4a304e4bc29f125a5a9f1af16 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 27 Feb 2025 16:30:18 +0100 Subject: [PATCH 0268/1221] Issue #867 : use 2 scale regions for reference_power vectors to improve precision. Work in progress. --- lib_com/cnst.h | 3 + lib_com/options.h | 3 + lib_dec/ivas_dirac_dec.c | 336 +++++++++++- lib_rend/ivas_dirac_output_synthesis_dec.c | 214 +++++++- lib_rend/ivas_dirac_rend.c | 581 ++++++++++++++++++++- lib_rend/ivas_prot_rend.h | 4 + lib_rend/ivas_stat_rend.h | 17 + lib_rend/lib_rend.c | 48 ++ 8 files changed, 1190 insertions(+), 16 deletions(-) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 26903f525..e6edc0cab 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -785,6 +785,9 @@ enum #define L_HP20_MEM 4 /* HP20 filter memory length */ #define CLDFB_NO_CHANNELS_MAX 60 /* CLDFB resampling - max number of CLDFB channels, == IVAS_CLDFB_NO_CHANNELS_MAX */ +#ifdef FIX_867_CLDFB_NRG_SCALE +#define CLDFB_NO_CHANNELS_HALF 30 /* CLDFB resampling - max number of CLDFB channels, == IVAS_CLDFB_NO_CHANNELS_MAX */ +#endif #define CLDFB_NO_CHANNELS_MAX_FX 30720 /*Q9*/ #define CLDFB_NO_COL_MAX 16 /* CLDFB resampling - max number of CLDFB col., == IVAS_CLDFB_NO_COL_MAX */ #define CLDFB_NO_COL_MAX_SWITCH 6 /* CLDFB resampling - max number of CLDFB col. for switching */ diff --git a/lib_com/options.h b/lib_com/options.h index a37ccf387..b02e87542 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -169,4 +169,7 @@ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ +#define FIX_867_CLDFB_NRG_SCALE /* Issue 867: split cldfb energy scale into 2 regions for better precision */ +//#define FIX_867_CLDFB_NRG_SCALE_CLDFB /* Issue 867: use dynamic scale for CLDFB analysis. Almost zero improvement. */ +//#define FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK /* Issue 867: erase higher cldfb values to remove noise from MDCT */ #endif diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 7d2f7be4f..de248f3bb 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2224,7 +2224,12 @@ void ivas_dirac_dec_render_sf_fx( DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params; DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state; Word16 num_channels_dir, exp; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_diffuseness_vector = Q31, q_reference_power_smooth[2] = { Q31, Q31 }; + move16(); +#else Word16 q_diffuseness_vector = Q31, q_reference_power_smooth = Q31; +#endif move16(); move16(); Word16 proto_power_smooth_len = 0; @@ -2464,10 +2469,33 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_prev_fx, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->hOutSetup.nchan_out_woLFE ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev+ tmp1) hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev = add( hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev, tmp1 ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + tmp1 = 31; + move16(); + FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { + tmp1 = s_min(tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF ) ); + } + FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF, tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], tmp1 ); + move16(); + tmp1 = 31; + move16(); + FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { + tmp1 = s_min(tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ) ); + } + FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], tmp1 ); + move16(); +#else tmp1 = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, tmp1 ); move16(); +#endif IF( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx != 0 ) { tmp1 = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, imult1616( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ) ); @@ -2743,8 +2771,59 @@ void ivas_dirac_dec_render_sf_fx( { /* CLDFB Analysis*/ offset = i_mult( hSpatParamRendCom->num_freq_bands, index_slot ); +#ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB + Word16 q_input; + Word32 sigTemp[MAX_TRANSPORT_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + q_input = 4; + move16(); + FOR( ch = 0; ch < nchan_transport; ch++ ) + { + q_input = s_min(q_input, L_norm_arr(&st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], + hSpatParamRendCom->num_freq_bands)); + } + FOR( ch = 0; ch < nchan_transport; ch++ ) + { + Copy_Scale_sig32(&st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], + sigTemp[ch], + hSpatParamRendCom->num_freq_bands, + q_input ); + } + q_input = add(Q11, q_input); +#endif +#ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK + Word16 cldfb_last_band=0; + move16(); + { + Word32 sr; + Word16 el; + FOR ( el=0; elnSCE; el++ ) { + test(); test(); + IF ( st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) { + cldfb_last_band = s_max( cldfb_last_band, st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->infoIGFStopFreq ); + sr = st_ivas->hSCE[el]->hCoreCoder[0]->output_Fs; + } + } + FOR ( el=0; elnCPE; el++ ) { + test(); test(); + IF ( st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) { + cldfb_last_band = s_max( cldfb_last_band, st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->infoIGFStopFreq ); + sr = st_ivas->hCPE[el]->hCoreCoder[0]->output_Fs; + } + test(); test(); + IF ( st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->isIGFActive ) { + cldfb_last_band = s_max( cldfb_last_band, st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->infoIGFStopFreq ); + } + } + IF ( EQ_16( cldfb_last_band, 0 ) ) { + cldfb_last_band = hSpatParamRendCom->num_freq_bands; + } ELSE { + cldfb_last_band = mult_r( div_s( shr( cldfb_last_band, 2 ), extract_l(L_shr ( sr, 3 ) ) ), hSpatParamRendCom->num_freq_bands ); + } + } +#endif FOR( ch = 0; ch < nchan_transport; ch++ ) { +#ifndef FIX_867_CLDFB_NRG_SCALE_CLDFB q_temp_cldfb = Q11; move16(); cldfbAnalysis_ts_fx_fixed_q( &st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], @@ -2752,6 +2831,22 @@ void ivas_dirac_dec_render_sf_fx( Cldfb_ImagBuffer_fx[ch][0], hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch], &q_temp_cldfb ); +#else + q_temp_cldfb = q_input; + move16(); + cldfbAnalysis_ts_fx_var_q( sigTemp[ch], + Cldfb_RealBuffer_fx[ch][0], + Cldfb_ImagBuffer_fx[ch][0], + hSpatParamRendCom->num_freq_bands, + st_ivas->cldfbAnaDec[ch], &q_temp_cldfb ); +#endif +#ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK + FOR (i=cldfb_last_band; inum_freq_bands; i++) { + Cldfb_RealBuffer_fx[ch][0][i] = 0; + Cldfb_ImagBuffer_fx[ch][0][i] = 0; + move32(); move32(); + } +#endif } q_cldfb = q_temp_cldfb; move16(); @@ -2812,7 +2907,11 @@ void ivas_dirac_dec_render_sf_fx( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fx, DirAC_mem.reference_power_q, +#else reference_power_fx, &DirAC_mem.reference_power_q, +#endif slot_idx, nchan_transport, hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, @@ -2825,7 +2924,11 @@ void ivas_dirac_dec_render_sf_fx( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fx, DirAC_mem.reference_power_q, +#else reference_power_fx, &DirAC_mem.reference_power_q, +#endif slot_idx, nchan_transport, hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, @@ -2844,9 +2947,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif 0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect, q_cldfb ); @@ -2870,9 +2981,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif slot_idx, hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, hDirACRend->hoa_decoder, @@ -2887,9 +3006,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif hDirACRend->hOutSetup.is_loudspeaker_setup, slot_idx, hSpatParamRendCom->num_freq_bands, @@ -2912,9 +3039,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif slot_idx, hDirACRend->num_protos_diff, hSpatParamRendCom->num_freq_bands, q_cldfb ); @@ -2977,7 +3112,12 @@ void ivas_dirac_dec_render_sf_fx( num_freq_bands, azimuth, elevation ); Copy32( reference_power_fx, &( hDirACRend->buffer_energy_fx[i_mult( sub( index, 1 ), num_freq_bands )] ), num_freq_bands ); +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32(&( hDirACRend->buffer_energy_fx[add(i_mult( sub( index, 1 ), num_freq_bands ), CLDFB_NO_CHANNELS_HALF)]), sub(num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_q[1])); + hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q[0]; +#else hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; +#endif move16(); computeDiffuseness_fixed( hDirACRend->buffer_intensity_real_fx, hDirACRend->buffer_energy_fx, num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], hDirACRend->q_buffer_intensity_real, hDirACRend->q_buffer_energy, &hSpatParamRendCom->q_diffuseness_vector ); @@ -3209,6 +3349,73 @@ void ivas_dirac_dec_render_sf_fx( IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { +#ifdef FIX_867_CLDFB_NRG_SCALE +#if 0 + IF( LT_16( q_reference_power_smooth[0], DirAC_mem.reference_power_q[0] ) ) + { + Word32 temp; + FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + { + temp = L_shl( reference_power_fx[i], sub( q_reference_power_smooth[0], DirAC_mem.reference_power_q[0] ) ); + reference_power_fx[i] = L_max(temp, L_min(reference_power_fx[i], 1)); + move32(); + } + DirAC_mem.reference_power_q[0] = q_reference_power_smooth[0]; + move16(); + } + ELSE + { + Word32 temp; + FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + { + temp = L_shl( reference_power_smooth_fx[i], sub( DirAC_mem.reference_power_q[0], q_reference_power_smooth[0] ) ); + reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); + move32(); + } + q_reference_power_smooth[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + + IF( LT_16( q_reference_power_smooth[1], DirAC_mem.reference_power_q[1] ) ) + { + Word32 temp; + FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + temp = L_shl( reference_power_fx[i], sub( q_reference_power_smooth[1], DirAC_mem.reference_power_q[1] ) ); + reference_power_fx[i] = L_max(temp, L_min(reference_power_fx[i], 1)); + move32(); + } + DirAC_mem.reference_power_q[1] = q_reference_power_smooth[1]; + move16(); + } + ELSE + { + Word32 temp; + FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + temp = L_shl( reference_power_smooth_fx[i], sub( DirAC_mem.reference_power_q[1], q_reference_power_smooth[1] ) ); + reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); + move32(); + } + q_reference_power_smooth[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); + q_reference_power_smooth[0] = sub( q_reference_power_smooth[0], 1 ); + q_reference_power_smooth[1] = sub( q_reference_power_smooth[1], 1 ); +#else + v_add_fixed_me(reference_power_fx, sub(31, DirAC_mem.reference_power_q[0]), + reference_power_smooth_fx, sub(31, q_reference_power_smooth[0]), + reference_power_smooth_fx, &temp_q, + CLDFB_NO_CHANNELS_HALF, 1 ); + q_reference_power_smooth[0] = sub(31, temp_q); + v_add_fixed_me(reference_power_fx + CLDFB_NO_CHANNELS_HALF, sub(31, DirAC_mem.reference_power_q[1]), + reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub(31, q_reference_power_smooth[1]), + reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, &temp_q, + sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), 1 ); + q_reference_power_smooth[1] = sub(31, temp_q); +#endif +#else IF( LT_16( q_reference_power_smooth, DirAC_mem.reference_power_q ) ) { Word32 temp; @@ -3251,6 +3458,7 @@ void ivas_dirac_dec_render_sf_fx( } v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); q_reference_power_smooth = sub( q_reference_power_smooth, 1 ); +#endif } } @@ -3442,6 +3650,51 @@ void ivas_dirac_dec_render_sf_fx( Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx, i_mult( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ), sub( Q31, hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q ) ); // Q31 } +#ifdef FIX_867_CLDFB_NRG_SCALE + exp = L_norm_arr( reference_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); + scale_sig32( reference_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, exp ); // q_reference_power_smooth[0] + exp + q_reference_power_smooth[0] = add( q_reference_power_smooth[0], exp ); + IF( LT_16( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // q_reference_power_smooth[0] + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = q_reference_power_smooth[0]; + move16(); + } + ELSE + { + Word32 temp; + FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + { + temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], q_reference_power_smooth[0] ) ); + reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); + move32(); + } + q_reference_power_smooth[0] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0]; + move16(); + } + + exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ); + scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), exp ); // q_reference_power_smooth + exp + q_reference_power_smooth[1] = add( q_reference_power_smooth[1], exp ); + IF( LT_16( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // q_reference_power_smooth + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = q_reference_power_smooth[1]; + move16(); + } + ELSE + { + Word32 temp; + FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], q_reference_power_smooth[1] ) ); + reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); + move32(); + } + q_reference_power_smooth[1] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1]; + move16(); + } +#else exp = L_norm_arr( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands ); scale_sig32( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, exp ); // q_reference_power_smooth + exp q_reference_power_smooth = add( q_reference_power_smooth, exp ); @@ -3472,6 +3725,7 @@ void ivas_dirac_dec_render_sf_fx( q_reference_power_smooth = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q; move16(); } +#endif IF( hDirACRend->masa_stereo_type_detect != NULL ) { @@ -3491,6 +3745,60 @@ void ivas_dirac_dec_render_sf_fx( } } +#ifdef FIX_867_CLDFB_NRG_SCALE + exp = 31; + move16(); + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + exp = s_min(exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF ) ); + } + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); + move16(); + IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) + { + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF, sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // proto_power_smooth_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0]; + move16(); + } + ELSE + { + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF, sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // proto_power_smooth_prev_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; + move16(); + } + exp = 31; + move16(); + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + exp = s_min(exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ) ); + } + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); + move16(); + IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ) + { + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // proto_power_smooth_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1]; + move16(); + } + ELSE + { + FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // proto_power_smooth_prev_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; + move16(); + } +#else exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, exp ); @@ -3507,7 +3815,7 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q; move16(); } - +#endif exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, i_mult( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, i_mult( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q + exp) hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, exp ); @@ -3550,11 +3858,35 @@ void ivas_dirac_dec_render_sf_fx( hSpatParamRendCom->subframe_nbslots[subframe_idx], diffuseness_vector_fx, reference_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + q_reference_power_smooth, +#else &q_reference_power_smooth, +#endif qualityBasedSmFactor_fx, hDirAC->hConfig->enc_param_start_band, &q_Cldfb ); +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 allZero = 1; + move16(); + FOR( i = 0; i < proto_power_smooth_len; i++ ) + { + if ( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx[i] != 0 ) + { + allZero = 0; + move16(); + } + } + if (allZero) { + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = 31; + move16(); + } + if (allZero) { + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = 31; + move16(); + } +#else Word16 sh = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q; move16(); hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = 31; @@ -3567,7 +3899,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); } } - +#endif FOR( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) { FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 0fe7cdef1..a0273292f 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -307,9 +307,14 @@ ivas_error ivas_dirac_dec_output_synthesis_open_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); } set32_fx( dirac_output_synthesis_state->reference_power_smooth_prev_fx, 0, hSpatParamRendCom->num_freq_bands ); +#ifdef FIX_867_CLDFB_NRG_SCALE + dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31; + dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31; + move16(); move16(); +#else dirac_output_synthesis_state->reference_power_smooth_prev_q = Q31; move16(); - +#endif IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); @@ -489,8 +494,14 @@ void ivas_dirac_dec_output_synthesis_init_fx( IF( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx != NULL ) { set32_fx( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ) ); +#ifdef FIX_867_CLDFB_NRG_SCALE + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31; + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31; + move16(); move16(); +#else h_dirac_output_synthesis_state->proto_power_smooth_prev_q = Q31; move16(); +#endif } set32_fx( h_dirac_output_synthesis_state->gains_dir_prev_fx, 0, size ); h_dirac_output_synthesis_state->gains_dir_prev_q = 0; @@ -626,7 +637,11 @@ void ivas_dirac_dec_output_synthesis_close_fx( void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + const Word16 *q_reference_power, /* i : Estimated power Q */ +#else const Word16 q_reference_power, /* i : Estimated power Q */ +#endif const Word32 *onset, /* i : onset filter Q31*/ const Word16 *azimuth, const Word16 *elevation, @@ -1207,7 +1222,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( hDirACRend->proto_index_diff, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, +#ifdef FIX_867_CLDFB_NRG_SCALE + q_reference_power, +#else &q_reference_power, +#endif h_dirac_output_synthesis_state->diffuse_responses_square_fx, onset, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, @@ -1220,9 +1239,15 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( /* process other PSDs only slot wise for 4 transport channels */ IF( EQ_16( dec_param_estim, TRUE ) ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); + + computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); +#else computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); +#endif } return; @@ -1990,6 +2015,26 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( // Scale cy_auto_diff_smooth_fx if required IF( diff_start_band != 0 ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + /* Is this necessary at all ? */ + q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); + scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, + i_mult( num_freq_bands, nchan_target_psds ), + sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/ + q_reference_power_smooth[0] = q_com; + q_reference_power_smooth[1] = q_com; + move16(); move16(); + h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = q_com; + h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = q_com; + move16(); move16(); + + h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com; + move16(); +#else q_com = s_min( *q_reference_power_smooth, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); scale_sig32( reference_power_smooth, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/ @@ -2003,6 +2048,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com; move16(); +#endif } computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band, @@ -2012,6 +2058,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); + } /*-----------------------------------------------------------------* @@ -2138,6 +2185,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ), h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth +#ifdef FIX_867_CLDFB_NRG_SCALE + assert(q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0]); + assert(q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1]); +#else + assert(*q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q); +#endif weightedDirectionSmoothness = L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth @@ -2145,8 +2198,13 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( exp = 0; move16(); +#if 0 tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 +#else + L_tmp = BASOP_Util_Divide3232_Scale_cadence( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ + smoothedDirectionSmoothness = L_shl_sat( L_tmp , exp ); // Q31 +#endif h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31 move32(); @@ -2210,6 +2268,55 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( } // Move proto_power_smooth_fx to common Q-factor + +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 min_exp2 = MIN_16; + min_exp = MIN_16; + move16(); move16(); + Word16 q_tmp2 = Q31; + q_tmp = Q31; + move16(); move16(); + + FOR( k = 0; k < num_protos_dir; k++ ) + { + FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + { + min_exp = s_max(min_exp, exp_arr[k * num_freq_bands + l]); + } + FOR( l=CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + min_exp2 = s_max(min_exp2, exp_arr[k * num_freq_bands + l]); + } + } + + p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; + + FOR( k = 0; k < num_protos_dir; k++ ) + { + FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + { + *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/ + move32(); + p_power_smooth++; + } + FOR( l=CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp2, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/ + move32(); + p_power_smooth++; + } + } + q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); + q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); + + // Update the Q-factor + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = h_dirac_output_synthesis_state->proto_power_smooth_q[0]; + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = h_dirac_output_synthesis_state->proto_power_smooth_q[1]; + move16(); move16(); + h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp; + h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2; + move16(); move16(); +#else min_exp = MIN_16; move16(); q_tmp = Q31; @@ -2229,7 +2336,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx; p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; - FOR( k = 0; k < num_protos_dir; k++ ) { FOR( l = 0; l < num_freq_bands; l++ ) @@ -2246,6 +2352,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move16(); h_dirac_output_synthesis_state->proto_power_smooth_q = q_tmp; move16(); +#endif /*Direct gains and diffuse gains on number of output channels*/ p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx; @@ -2293,6 +2400,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( FOR( k = 0; k < nchan_out_woLFE; k++ ) { Word32 power_smooth_temp; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx; +#endif p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx + i_mult( proto_direct_index[k], num_freq_bands ); // q_proto_power_smooth FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ ) { @@ -2300,18 +2410,28 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( g1 = alpha[l]; // Q31 move32(); g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + assert(q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k]); *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ), Mpy_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); // (Q31, q_cy_auto_dir_smooth_prev_local) -> q_cy_auto_dir_smooth_prev_local move32(); + assert(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev); *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ), Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev move32(); power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_dir_smooth_prev++ ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31 +#ifdef FIX_867_CLDFB_NRG_SCALE + qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), + q_cy_auto_dir_smooth_prev_local[k] ), + Q31 ) ); + +#else exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ), q_cy_auto_dir_smooth_prev_local[k] ), Q31 ) ); +#endif p_power_smooth++; *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp) @@ -2395,10 +2515,16 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( ( p_cy_cross_dir_smooth++ ); power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); L_tmp = Mpy_32_32( power_smooth_temp, L_tmp ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31 +#ifdef FIX_867_CLDFB_NRG_SCALE + qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), + add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ), + Q31 ) ); +#else exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ), add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ), Q31 ) ); - +#endif *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp) move32(); *( p_gains_dir ) = L_shl_sat( *( p_gains_dir ), sub( h_dirac_output_synthesis_state->gains_dir_prev_q, sub( Q31, exp ) ) ); // gains_dir_prev_q @@ -2446,9 +2572,15 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move32(); } ( p_cy_auto_diff_smooth_prev++ ); +#ifdef FIX_867_CLDFB_NRG_SCALE + exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), + h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ), + Q31 ) ); +#else exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ), Q31 ) ); +#endif p_power_smooth++; *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); /*31-exp*/ @@ -3913,8 +4045,13 @@ static void computeTargetPSDs_direct_fx( /* estimate direct and diffuse power */ v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[0] ) ); + Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); +#else Word16 common1_q = s_min( *q_cy_auto_dir_smooth, *q_reference_power ); Word16 common2_q = s_min( *q_cy_cross_dir_smooth, *q_reference_power ); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -3922,12 +4059,22 @@ static void computeTargetPSDs_direct_fx( cur_idx = imult1616( ch_idx, num_freq_bands ); v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ +#else scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ +#endif scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */ v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */ v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ +#else scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ +#endif scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */ v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */ } @@ -3991,17 +4138,34 @@ static void computeTargetPSDs_direct_subframe_fx( } } q_tmp = W_norm( W_max ); +#ifdef FIX_867_CLDFB_NRG_SCALE + FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + { + cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power[0]+q_tmp*/ + move32(); + } + Word16 q_tmp2 = sub(q_tmp, sub(q_reference_power[1], q_reference_power[0])); + FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ ) + { + cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ + move32(); + } +#else FOR( i = 0; i < num_freq_bands; i++ ) { cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power+q_tmp*/ move32(); } - q_cy_auto_dir_smooth[ch_idx] = add( *q_reference_power, q_tmp ); +#endif + q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); move16(); v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32(&cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max(sub(num_freq_bands, CLDFB_NO_CHANNELS_HALF), 0), sub(q_reference_power[0], q_reference_power[1])); +#endif } - *q_cy_cross_dir_smooth = *q_reference_power; + *q_cy_cross_dir_smooth = q_reference_power[0]; move16(); return; @@ -4028,7 +4192,11 @@ static void computeTargetPSDs_diffuse_fx( /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 common_q = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); +#else Word16 common_q = s_min( *q_cy_auto_diff_smooth, *q_reference_power ); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -4036,7 +4204,12 @@ static void computeTargetPSDs_diffuse_fx( cur_idx = imult1616( ch_idx, num_freq_bands ); v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub ( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */ +#else scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ +#endif scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */ v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */ } @@ -4066,6 +4239,9 @@ static void computeTargetPSDs_diffuse_subframe_fx( /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32(diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max(0, sub(num_freq_bands, CLDFB_NO_CHANNELS_HALF)), sub(q_reference_power[0], q_reference_power[1])); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { @@ -4099,14 +4275,23 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( /* segment auxiliary buffer */ Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_common, q_reference_power_min_one[2]; + q_reference_power_min_one[0] = sub( q_reference_power[0], Q1 ); + q_reference_power_min_one[1] = sub( q_reference_power[1], Q1 ); +#else Word16 q_common, q_reference_power_min_one; q_reference_power_min_one = sub( *q_reference_power, Q1 ); +#endif /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power +#ifdef FIX_867_CLDFB_NRG_SCALE + q_common = s_min(*q_cy_auto_diff_smooth, s_min(q_reference_power_min_one[0], q_reference_power_min_one[1] ) ); +#else IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power_min_one ) ) { q_common = q_reference_power_min_one; @@ -4117,7 +4302,7 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( q_common = *q_cy_auto_diff_smooth; move16(); } - +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { @@ -4133,6 +4318,22 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( v_add_fixed( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands, Q1 ); // Q30 v_mult_fixed( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands ); // (Q30, q_reference_power) -> q_reference_power - Q1 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( NE_16( q_common, q_reference_power_min_one[0] ) ) + { + scale_sig32( aux_buffer_res, s_min( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( q_common, q_reference_power_min_one[0] ) ); // q_common + } + IF( NE_16( q_common, q_reference_power_min_one[1] ) ) + { + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max(0, sub( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_common, q_reference_power_min_one[1] ) ); // q_common + } + IF( NE_16( q_common, *q_cy_auto_diff_smooth ) ) + { + scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common + } + v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 ); // (q_common - Q1) + scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1) +#else IF( NE_16( q_common, q_reference_power_min_one ) ) { scale_sig32( aux_buffer_res, num_decorr_freq_bands, sub( q_common, q_reference_power_min_one ) ); // q_common @@ -4143,6 +4344,7 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( } v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 ); // (q_common - Q1) scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1) +#endif } /* Q adjustment */ diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index b563d4399..19a67dd3d 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -787,10 +787,19 @@ ivas_error ivas_dirac_alloc_mem_fx( } } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx = hDirAC_mem->proto_power_smooth_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = Q31; + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = Q31; + move16(); move16(); + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = Q31; + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = Q31; + move16(); move16(); +#else hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = Q31; move16(); hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = Q31; move16(); +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx = hDirAC_mem->proto_power_diff_smooth_fx; hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = hDirAC_mem->proto_power_diff_smooth_q; move16(); @@ -948,10 +957,19 @@ ivas_error ivas_dirac_alloc_mem_fx( hDirAC_mem->reference_power_len = imult1616( 2, num_freq_bands ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirAC_mem->reference_power_q[0] = Q31; + hDirAC_mem->reference_power_q[1] = Q31; + move16(); move16(); + hDirAC_mem->reference_power_smooth_q[0] = Q31; + hDirAC_mem->reference_power_smooth_q[1] = Q31; + move16(); move16(); +#else hDirAC_mem->reference_power_q = Q31; move16(); hDirAC_mem->reference_power_smooth_q = Q31; move16(); +#endif IF( hDirACRend->proto_signal_decorr_on ) { IF( ( hDirAC_mem->onset_filter_fx = (Word32 *) malloc( sizeof( Word32 ) * num_outputs_diff * num_freq_bands ) ) == NULL ) @@ -1478,8 +1496,14 @@ void protoSignalComputation_shd_fx( *proto_direct_buffer_f_q = add( q_cldfb, min_q_shift ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + reference_power_q[qidx] = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 ); + move16(); +#else *reference_power_q = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 ); move16(); +#endif Word16 shift = sub( *proto_direct_buffer_f_q, q_cldfb ); FOR( k = 1; k < 4; k++ ) @@ -1514,8 +1538,14 @@ void protoSignalComputation_shd_fx( } *proto_direct_buffer_f_q = q_cldfb; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_q[0] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + reference_power_q[1] = reference_power_q[0]; + move16(); move16(); +#else *reference_power_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); +#endif } /* Additional transport channels = planar SBA components of degree higher than 1*/ @@ -1577,7 +1607,11 @@ void protoSignalComputation1_fx( { Word16 l, k, idx; Word32 *p_proto_buffer_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 proto_power_smooth_fx_q[2], min_q_shift, q_shift; +#else Word16 proto_power_smooth_fx_q, min_q_shift, q_shift; +#endif Word32 re, im; min_q_shift = Q31; @@ -1600,17 +1634,48 @@ void protoSignalComputation1_fx( q_shift = sub( q_shift, find_guarded_bits_fx( 2 ) ); Scale_sig32( proto_power_smooth_fx, num_freq_bands, q_shift ); /*proto_power_smooth_q+q_shift*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_q[0] = add( proto_power_smooth_q[0], q_shift ); + proto_power_smooth_q[1] = add( proto_power_smooth_q[1], q_shift ); + proto_power_smooth_fx_q[0] = proto_power_smooth_q[0]; + proto_power_smooth_fx_q[1] = proto_power_smooth_q[1]; + move16(); move16(); +#else *proto_power_smooth_q = add( *proto_power_smooth_q, q_shift ); proto_power_smooth_fx_q = *proto_power_smooth_q; move16(); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); +#endif re = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift reference_power_fx[l] = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 move32(); + +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_q[qidx] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + move16(); + + IF( LT_16( reference_power_q[qidx], proto_power_smooth_q[qidx] ) ) + { + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( proto_power_smooth_q[qidx], reference_power_q[qidx] ) ), reference_power_fx[l] ); // reference_power_q + move32(); + proto_power_smooth_fx_q[qidx] = reference_power_q[qidx]; + move16(); + } + ELSE + { + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( reference_power_fx[l], sub( reference_power_q[qidx], proto_power_smooth_q[qidx] ) ) ); // proto_power_smooth_q + move32(); + proto_power_smooth_fx_q[qidx] = proto_power_smooth_q[qidx]; + move16(); + } +#else *reference_power_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); @@ -1628,7 +1693,7 @@ void protoSignalComputation1_fx( proto_power_smooth_fx_q = *proto_power_smooth_q; move16(); } - +#endif idx = 2 * l; p_proto_buffer_fx[idx] = RealBuffer_fx[0][0][l]; // q_cldfb move32(); @@ -1649,8 +1714,14 @@ void protoSignalComputation1_fx( move16(); *proto_direct_buffer_f_q = q_cldfb; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_q[0] = proto_power_smooth_fx_q[0]; + proto_power_smooth_q[1] = proto_power_smooth_fx_q[1]; + move16(); move16(); +#else *proto_power_smooth_q = proto_power_smooth_fx_q; move16(); +#endif return; } @@ -1701,6 +1772,7 @@ void protoSignalComputation2_fx( Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; + /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ min_q_shift = Q31; move16(); @@ -1733,6 +1805,44 @@ void protoSignalComputation2_fx( temp_q_shift = sub( temp_q_shift, 2 ); // guard bits /* Upscaling of the buffer proto_power_smooth_fx */ +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( isloudspeaker ) + { + q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + ELSE + { + q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + q_proto_power_smooth[0] = add( q_proto_power_smooth[0], sub( q_shift, 1 ) ); + move16(); + IF( isloudspeaker ) + { + q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + ELSE + { + q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + q_proto_power_smooth[1] = add( q_proto_power_smooth[1], sub( q_shift, 1 ) ); + move16(); +#else IF( isloudspeaker ) { q_shift = getScaleFactor32( proto_power_smooth_fx, i_mult( 3, num_freq_bands ) ); @@ -1745,7 +1855,7 @@ void protoSignalComputation2_fx( } *q_proto_power_smooth = add( *q_proto_power_smooth, sub( q_shift, 1 ) ); move16(); - +#endif IF( isloudspeaker ) { p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f @@ -1775,14 +1885,27 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -1793,14 +1916,26 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -1810,14 +1945,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -1995,6 +2142,9 @@ void protoSignalComputation2_fx( } /* Compute protos (and their power) for direct sound rendering */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); +#endif /* W prototype */ IF( stereo_type_detect->interpolator > 0 ) @@ -2005,14 +2155,26 @@ void protoSignalComputation2_fx( Imag_aux_fx = Madd_32_16( Mpy_32_16_1( Imag_aux_fx, shr( interpolatorSpaced_fx, 1 ) ), Imag_aux_fx, interpolatorDmx_fx ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift) -31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2027,14 +2189,26 @@ void protoSignalComputation2_fx( tempDmx_fx = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 temp = Madd_32_16( Mpy_32_16_1( tempSpaced_fx, interpolatorSpaced_fx ), tempDmx_fx, interpolatorDmx_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2051,14 +2225,26 @@ void protoSignalComputation2_fx( Real_aux_fx = L_shr( Real_aux_fx, 1 ); // q_cldfb+min_q_shift Imag_aux_fx = L_shr( Imag_aux_fx, 1 ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2070,14 +2256,26 @@ void protoSignalComputation2_fx( ELSE { temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2090,14 +2288,26 @@ void protoSignalComputation2_fx( ELSE { temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2133,14 +2343,26 @@ void protoSignalComputation2_fx( } temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } } @@ -2163,14 +2385,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } } @@ -2192,14 +2426,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } } @@ -2382,14 +2628,27 @@ void protoSignalComputation2_fx( reference_power_64fx[l] = W_add( W_mult0_32_32( Real_aux_fx, Real_aux_fx ), W_mult0_32_32( Imag_aux_fx, Imag_aux_fx ) ); // q_temp move64(); +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2404,14 +2663,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // q_temp +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2431,6 +2702,40 @@ void protoSignalComputation2_fx( } } q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 norm_shift = 63; + move16(); + FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + { + IF( reference_power_64fx[l] ) + { + norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) ); + } + } + FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + { + reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32 + move32(); + } + q_reference_power[0] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); + move16(); + norm_shift = 63; + move16(); + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + IF( reference_power_64fx[l] ) + { + norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) ); + } + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32 + move32(); + } + q_reference_power[1] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); + move16(); +#else Word16 norm_shift = 63; move16(); FOR( l = 0; l < num_freq_bands; l++ ) @@ -2447,13 +2752,19 @@ void protoSignalComputation2_fx( } *q_reference_power = sub( add( q_reference_power_64fx, norm_shift ), 32 ); move16(); - +#endif *q_proto_frame_f = add( q_cldfb, min_q_shift ); move16(); *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp ); + q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp ); + move16(); move16(); +#else *q_proto_power_smooth = s_min( *q_proto_power_smooth, q_temp ); move16(); +#endif return; } @@ -3681,7 +3992,11 @@ static void ivas_masa_ext_dirac_render_sf_fx( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, slot_idx, nchan_transport, +#else reference_power_fix, &DirAC_mem.reference_power_q, slot_idx, nchan_transport, +#endif hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, 0, q_cldfb ); @@ -3694,12 +4009,53 @@ static void ivas_masa_ext_dirac_render_sf_fx( protoSignalComputation2_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hDirACRend->proto_frame_f_fx, &hDirACRend->proto_frame_f_q, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else reference_power_fix, &DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif 0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect, q_cldfb ); proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } +#else IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, sub( DirAC_mem.reference_power_len, hSpatParamRendCom->num_freq_bands ), sub( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ); // DirAC_mem.reference_power_q @@ -3712,6 +4068,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q ); @@ -3727,9 +4084,15 @@ static void ivas_masa_ext_dirac_render_sf_fx( &hDirACRend->proto_frame_f_q, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else reference_power_fix, &DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif hDirACRend->hOutSetup.is_loudspeaker_setup, slot_idx, hSpatParamRendCom->num_freq_bands, @@ -3737,6 +4100,43 @@ static void ivas_masa_ext_dirac_render_sf_fx( proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } + +#else IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, sub( DirAC_mem.reference_power_len, hSpatParamRendCom->num_freq_bands ), sub( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ); // DirAC_mem.reference_power_q @@ -3749,6 +4149,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q ); @@ -3761,16 +4162,57 @@ static void ivas_masa_ext_dirac_render_sf_fx( &hDirACRend->proto_frame_f_q, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else reference_power_fix, &DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif slot_idx, hDirACRend->num_protos_diff, hSpatParamRendCom->num_freq_bands, q_cldfb ); proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); - +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } +#else IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, sub( DirAC_mem.reference_power_len, hSpatParamRendCom->num_freq_bands ), sub( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ); // DirAC_mem.reference_power_q @@ -3783,7 +4225,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } - +#endif temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q ); @@ -3902,10 +4344,19 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { Scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, -1 ); // DirAC_mem.reference_power_q-1 +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q[0] = sub( DirAC_mem.reference_power_q[0], 1 ); + DirAC_mem.reference_power_q[1] = sub( DirAC_mem.reference_power_q[1], 1 ); + move16(); move16(); + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); move16(); +#else DirAC_mem.reference_power_q = sub( DirAC_mem.reference_power_q, 1 ); move16(); DirAC_mem.reference_power_smooth_q = DirAC_mem.reference_power_q; move16(); +#endif v_add_fixed( reference_power_fix, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 0 ); // DirAC_mem.reference_power_smooth_q } } @@ -4016,10 +4467,19 @@ static void ivas_masa_ext_dirac_render_sf_fx( Word16 reference_power_temp_q = getScaleFactor32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len ); scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, reference_power_temp_q ); /*DirAC_mem.reference_power_q + reference_power_temp_q*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q[0] = add( DirAC_mem.reference_power_q[0], reference_power_temp_q ); + DirAC_mem.reference_power_q[1] = add( DirAC_mem.reference_power_q[1], reference_power_temp_q ); + move16(); + DirAC_mem.reference_power_smooth_q[0] = add( DirAC_mem.reference_power_q[0], reference_power_temp_q ); + DirAC_mem.reference_power_smooth_q[1] = add( DirAC_mem.reference_power_q[1], reference_power_temp_q ); + move16(); +#else DirAC_mem.reference_power_q = add( DirAC_mem.reference_power_q, reference_power_temp_q ); move16(); DirAC_mem.reference_power_smooth_q = add( DirAC_mem.reference_power_q, reference_power_temp_q ); move16(); +#endif Word16 q_cy_auto_diff_smooth = getScaleFactor32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_len ); Scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_len, q_cy_auto_diff_smooth ); // h_dirac_output_synthesis_state->q_cy_auto_diff_smooth+ q_cy_auto_diff_smooth @@ -4049,14 +4509,52 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->masa_stereo_type_detect->q_subtract_power_y = s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y ); move16(); } +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands*2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands*3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands*4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + move16(); + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*5, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands*2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands*3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands*4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + move16(); + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*4, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); +#else Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); - +#endif Word16 proto_power_diff_smooth_prev_temp_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len ); Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len, proto_power_diff_smooth_prev_temp_q ); // hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q + proto_power_diff_smooth_prev_temp_q hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q, proto_power_diff_smooth_prev_temp_q ); @@ -4077,7 +4575,30 @@ static void ivas_masa_ext_dirac_render_sf_fx( Scale_sig32( diffuseness_vector_fx, hSpatParamRendCom->num_freq_bands, 1 ); /*Buffer rescaling*/ - +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + IF ( GT_16( DirAC_mem.reference_power_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 2), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 3), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 4), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + } + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); + move16(); + DirAC_mem.reference_power_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + DirAC_mem.reference_power_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); + move16(); + DirAC_mem.reference_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + DirAC_mem.reference_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); + move16(); +#else Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, hSpatParamRendCom->num_freq_bands, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) Scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ), DirAC_mem.reference_power_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) @@ -4087,7 +4608,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); DirAC_mem.reference_power_smooth_q = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ); move16(); - +#endif ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hSpatParamRendCom, @@ -4095,12 +4616,55 @@ static void ivas_masa_ext_dirac_render_sf_fx( hSpatParamRendCom->subframe_nbslots[subframe_idx], diffuseness_vector_fx, reference_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_smooth_q, +#else &DirAC_mem.reference_power_smooth_q, +#endif ONE_IN_Q31, 0, &q_cldfb ); hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = DirAC_mem.reference_power_smooth_q[0]; + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } +#else hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q = DirAC_mem.reference_power_smooth_q; move16(); IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) @@ -4115,6 +4679,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif } /*-----------------------------------------------------------------* diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index b642e05d7..d329b8c85 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -632,7 +632,11 @@ void ivas_dirac_dec_output_synthesis_close( ); void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power */ +#ifdef FIX_867_CLDFB_NRG_SCALE + const Word16 *q_reference_power, /* i : Estimated power */ +#else const Word16 q_reference_power, /* i : Estimated power */ +#endif const Word32 *onset, /* i : onset filter */ const Word16 *azimuth, const Word16 *elevation, diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 44207c79a..b2f5ae3eb 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -228,8 +228,13 @@ typedef struct dirac_dec_stack_mem Word32 *cy_auto_diff_smooth_fx; Word32 *reference_power_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 reference_power_q[2]; + Word16 reference_power_smooth_q[2]; +#else Word16 reference_power_q; Word16 reference_power_smooth_q; +#endif Word16 reference_power_len; Word32 *onset_filter_fx; /* Q31 */ @@ -277,7 +282,11 @@ typedef struct dirac_output_synthesis_state_structure /* Temporal smoothing memories */ Word32 *reference_power_smooth_prev_fx; /* Q(reference_power_smooth_prev_q) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 reference_power_smooth_prev_q[2]; +#else Word16 reference_power_smooth_prev_q; +#endif Word32 *direction_smoothness_prev_fx; /* Q31 */ /* only pointer to local buffers */ @@ -295,10 +304,18 @@ typedef struct dirac_output_synthesis_state_structure Word16 diff_dir_power_factor_len; Word32 *proto_power_smooth_fx; /* Smoothed power of the prototype signals. Size: num_freq_bands*num_channels. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 proto_power_smooth_q[2]; +#else Word16 proto_power_smooth_q; +#endif Word16 proto_power_smooth_len; Word32 *proto_power_smooth_prev_fx; /* Smoothed power of the prototype signals of the previous synthesis block. Size: num_freq_bands*num_channels. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 proto_power_smooth_prev_q[2]; +#else Word16 proto_power_smooth_prev_q; +#endif Word16 proto_power_smooth_prev_len; Word32 *proto_power_diff_smooth_fx; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a1c551405..a24330988 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8309,8 +8309,14 @@ static void intermidiate_ext_dirac_render( IF( to_fix ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0] = Q31; + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1] = Q31; + move16(); move16(); +#else DirAC_mem.reference_power_smooth_q = DirAC_mem.reference_power_q = Q31; move16(); +#endif move16(); FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { @@ -8439,14 +8445,56 @@ static void intermidiate_ext_dirac_render( IF( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx ) { +#ifdef FIX_867_CLDFB_NRG_SCALE +#if 0 + /* Possible improvement: normalize both scale regions individually. */ + tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); + move16(); move16(); +#else + /* Possible improvement: normalize both scale regions individually. */ + tmp = 0; + move16(); + FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { + tmp = s_min(tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF ) ); + } + FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); + move16(); + tmp = 0; + move16(); + FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { + tmp = s_min(tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + } + FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); + move16(); +#endif +#else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, tmp ); move16(); +#endif +#ifdef FIX_867_CLDFB_NRG_SCALE + /* Possible improvement: normalize both scale regions individually. */ + tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); +#else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); +#endif } tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len ); -- GitLab From 34be0cabef44c7dc10caf656d8dbf8f48377cef4 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 27 Feb 2025 16:32:49 +0100 Subject: [PATCH 0269/1221] Issue #867 : use 2 scale regions for reference_power vectors to improve precision. Work in progress. Format. --- lib_dec/ivas_dirac_dec.c | 143 +++++++++++-------- lib_rend/ivas_dirac_output_synthesis_dec.c | 89 ++++++------ lib_rend/ivas_dirac_rend.c | 151 ++++++++++++--------- lib_rend/lib_rend.c | 19 ++- 4 files changed, 232 insertions(+), 170 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index de248f3bb..c490c546a 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2472,21 +2472,25 @@ void ivas_dirac_dec_render_sf_fx( #ifdef FIX_867_CLDFB_NRG_SCALE tmp1 = 31; move16(); - FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - tmp1 = s_min(tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF ) ); + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF ) ); } - FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF, tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], tmp1 ); move16(); tmp1 = 31; move16(); - FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - tmp1 = s_min(tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ) ); + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); } - FOR (i=0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], tmp1 ); move16(); @@ -2778,46 +2782,57 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( ch = 0; ch < nchan_transport; ch++ ) { - q_input = s_min(q_input, L_norm_arr(&st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], - hSpatParamRendCom->num_freq_bands)); + q_input = s_min( q_input, L_norm_arr( &st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], + hSpatParamRendCom->num_freq_bands ) ); } FOR( ch = 0; ch < nchan_transport; ch++ ) { - Copy_Scale_sig32(&st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], - sigTemp[ch], - hSpatParamRendCom->num_freq_bands, - q_input ); + Copy_Scale_sig32( &st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], + sigTemp[ch], + hSpatParamRendCom->num_freq_bands, + q_input ); } - q_input = add(Q11, q_input); + q_input = add( Q11, q_input ); #endif #ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK - Word16 cldfb_last_band=0; + Word16 cldfb_last_band = 0; move16(); { Word32 sr; Word16 el; - FOR ( el=0; elnSCE; el++ ) { - test(); test(); - IF ( st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) { + FOR( el = 0; el < st_ivas->nSCE; el++ ) + { + test(); + test(); + IF( st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) + { cldfb_last_band = s_max( cldfb_last_band, st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->infoIGFStopFreq ); sr = st_ivas->hSCE[el]->hCoreCoder[0]->output_Fs; } } - FOR ( el=0; elnCPE; el++ ) { - test(); test(); - IF ( st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) { + FOR( el = 0; el < st_ivas->nCPE; el++ ) + { + test(); + test(); + IF( st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) + { cldfb_last_band = s_max( cldfb_last_band, st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->infoIGFStopFreq ); sr = st_ivas->hCPE[el]->hCoreCoder[0]->output_Fs; } - test(); test(); - IF ( st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->isIGFActive ) { + test(); + test(); + IF( st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->isIGFActive ) + { cldfb_last_band = s_max( cldfb_last_band, st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->infoIGFStopFreq ); } } - IF ( EQ_16( cldfb_last_band, 0 ) ) { + IF( EQ_16( cldfb_last_band, 0 ) ) + { cldfb_last_band = hSpatParamRendCom->num_freq_bands; - } ELSE { - cldfb_last_band = mult_r( div_s( shr( cldfb_last_band, 2 ), extract_l(L_shr ( sr, 3 ) ) ), hSpatParamRendCom->num_freq_bands ); + } + ELSE + { + cldfb_last_band = mult_r( div_s( shr( cldfb_last_band, 2 ), extract_l( L_shr( sr, 3 ) ) ), hSpatParamRendCom->num_freq_bands ); } } #endif @@ -2841,10 +2856,12 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbAnaDec[ch], &q_temp_cldfb ); #endif #ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK - FOR (i=cldfb_last_band; inum_freq_bands; i++) { + FOR( i = cldfb_last_band; i < hSpatParamRendCom->num_freq_bands; i++ ) + { Cldfb_RealBuffer_fx[ch][0][i] = 0; Cldfb_ImagBuffer_fx[ch][0][i] = 0; - move32(); move32(); + move32(); + move32(); } #endif } @@ -3113,7 +3130,7 @@ void ivas_dirac_dec_render_sf_fx( Copy32( reference_power_fx, &( hDirACRend->buffer_energy_fx[i_mult( sub( index, 1 ), num_freq_bands )] ), num_freq_bands ); #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32(&( hDirACRend->buffer_energy_fx[add(i_mult( sub( index, 1 ), num_freq_bands ), CLDFB_NO_CHANNELS_HALF)]), sub(num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_q[1])); + Scale_sig32( &( hDirACRend->buffer_energy_fx[add( i_mult( sub( index, 1 ), num_freq_bands ), CLDFB_NO_CHANNELS_HALF )] ), sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_q[1] ) ); hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q[0]; #else hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; @@ -3404,16 +3421,16 @@ void ivas_dirac_dec_render_sf_fx( q_reference_power_smooth[0] = sub( q_reference_power_smooth[0], 1 ); q_reference_power_smooth[1] = sub( q_reference_power_smooth[1], 1 ); #else - v_add_fixed_me(reference_power_fx, sub(31, DirAC_mem.reference_power_q[0]), - reference_power_smooth_fx, sub(31, q_reference_power_smooth[0]), - reference_power_smooth_fx, &temp_q, - CLDFB_NO_CHANNELS_HALF, 1 ); - q_reference_power_smooth[0] = sub(31, temp_q); - v_add_fixed_me(reference_power_fx + CLDFB_NO_CHANNELS_HALF, sub(31, DirAC_mem.reference_power_q[1]), - reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub(31, q_reference_power_smooth[1]), - reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, &temp_q, - sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), 1 ); - q_reference_power_smooth[1] = sub(31, temp_q); + v_add_fixed_me( reference_power_fx, sub( 31, DirAC_mem.reference_power_q[0] ), + reference_power_smooth_fx, sub( 31, q_reference_power_smooth[0] ), + reference_power_smooth_fx, &temp_q, + CLDFB_NO_CHANNELS_HALF, 1 ); + q_reference_power_smooth[0] = sub( 31, temp_q ); + v_add_fixed_me( reference_power_fx + CLDFB_NO_CHANNELS_HALF, sub( 31, DirAC_mem.reference_power_q[1] ), + reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( 31, q_reference_power_smooth[1] ), + reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, &temp_q, + sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 1 ); + q_reference_power_smooth[1] = sub( 31, temp_q ); #endif #else IF( LT_16( q_reference_power_smooth, DirAC_mem.reference_power_q ) ) @@ -3666,15 +3683,15 @@ void ivas_dirac_dec_render_sf_fx( FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) { temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], q_reference_power_smooth[0] ) ); - reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); + reference_power_smooth_fx[i] = L_max( temp, L_min( reference_power_smooth_fx[i], 1 ) ); move32(); } q_reference_power_smooth[0] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0]; move16(); } - exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ); - scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), exp ); // q_reference_power_smooth + exp + exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // q_reference_power_smooth + exp q_reference_power_smooth[1] = add( q_reference_power_smooth[1], exp ); IF( LT_16( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ) { @@ -3688,7 +3705,7 @@ void ivas_dirac_dec_render_sf_fx( FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) { temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], q_reference_power_smooth[1] ) ); - reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); + reference_power_smooth_fx[i] = L_max( temp, L_min( reference_power_smooth_fx[i], 1 ) ); move32(); } q_reference_power_smooth[1] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1]; @@ -3748,17 +3765,20 @@ void ivas_dirac_dec_render_sf_fx( #ifdef FIX_867_CLDFB_NRG_SCALE exp = 31; move16(); - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { - exp = s_min(exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF ) ); + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF ) ); } - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); move16(); IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) { - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF, sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // proto_power_smooth_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0]; @@ -3766,7 +3786,8 @@ void ivas_dirac_dec_render_sf_fx( } ELSE { - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF, sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // proto_power_smooth_prev_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; @@ -3774,26 +3795,30 @@ void ivas_dirac_dec_render_sf_fx( } exp = 31; move16(); - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { - exp = s_min(exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ) ); + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); } - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); move16(); IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ) { - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // proto_power_smooth_q + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // proto_power_smooth_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1]; move16(); } ELSE { - FOR ( i=0; proto_power_smooth_len > i; i = add(i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // proto_power_smooth_prev_q + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // proto_power_smooth_prev_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; move16(); @@ -3878,11 +3903,13 @@ void ivas_dirac_dec_render_sf_fx( move16(); } } - if (allZero) { + if ( allZero ) + { hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = 31; move16(); } - if (allZero) { + if ( allZero ) + { hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = 31; move16(); } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index a0273292f..8a2dd7bec 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -310,7 +310,8 @@ ivas_error ivas_dirac_dec_output_synthesis_open_fx( #ifdef FIX_867_CLDFB_NRG_SCALE dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31; dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31; - move16(); move16(); + move16(); + move16(); #else dirac_output_synthesis_state->reference_power_smooth_prev_q = Q31; move16(); @@ -497,7 +498,8 @@ void ivas_dirac_dec_output_synthesis_init_fx( #ifdef FIX_867_CLDFB_NRG_SCALE h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31; h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31; - move16(); move16(); + move16(); + move16(); #else h_dirac_output_synthesis_state->proto_power_smooth_prev_q = Q31; move16(); @@ -636,13 +638,13 @@ void ivas_dirac_dec_output_synthesis_close_fx( *------------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_process_slot_fx( - const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ + const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ #ifdef FIX_867_CLDFB_NRG_SCALE const Word16 *q_reference_power, /* i : Estimated power Q */ #else const Word16 q_reference_power, /* i : Estimated power Q */ #endif - const Word32 *onset, /* i : onset filter Q31*/ + const Word32 *onset, /* i : onset filter Q31*/ const Word16 *azimuth, const Word16 *elevation, const Word32 *diffuseness, /* Q(q_diffuseness)*/ @@ -2018,19 +2020,21 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( #ifdef FIX_867_CLDFB_NRG_SCALE /* Is this necessary at all ? */ q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); - scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, i_mult( num_freq_bands, nchan_target_psds ), sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/ q_reference_power_smooth[0] = q_com; q_reference_power_smooth[1] = q_com; - move16(); move16(); + move16(); + move16(); h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = q_com; h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = q_com; - move16(); move16(); + move16(); + move16(); h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com; move16(); @@ -2058,7 +2062,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); - } /*-----------------------------------------------------------------* @@ -2186,10 +2189,10 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth #ifdef FIX_867_CLDFB_NRG_SCALE - assert(q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0]); - assert(q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1]); + assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] ); + assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] ); #else - assert(*q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q); + assert( *q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q ); #endif weightedDirectionSmoothness = L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), @@ -2203,7 +2206,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 #else L_tmp = BASOP_Util_Divide3232_Scale_cadence( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ - smoothedDirectionSmoothness = L_shl_sat( L_tmp , exp ); // Q31 + smoothedDirectionSmoothness = L_shl_sat( L_tmp, exp ); // Q31 #endif h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31 @@ -2272,20 +2275,22 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( #ifdef FIX_867_CLDFB_NRG_SCALE Word16 min_exp2 = MIN_16; min_exp = MIN_16; - move16(); move16(); + move16(); + move16(); Word16 q_tmp2 = Q31; q_tmp = Q31; - move16(); move16(); + move16(); + move16(); FOR( k = 0; k < num_protos_dir; k++ ) { FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) { - min_exp = s_max(min_exp, exp_arr[k * num_freq_bands + l]); + min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] ); } - FOR( l=CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) { - min_exp2 = s_max(min_exp2, exp_arr[k * num_freq_bands + l]); + min_exp2 = s_max( min_exp2, exp_arr[k * num_freq_bands + l] ); } } @@ -2299,7 +2304,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move32(); p_power_smooth++; } - FOR( l=CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) { *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp2, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/ move32(); @@ -2312,10 +2317,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( // Update the Q-factor h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = h_dirac_output_synthesis_state->proto_power_smooth_q[0]; h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = h_dirac_output_synthesis_state->proto_power_smooth_q[1]; - move16(); move16(); + move16(); + move16(); h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp; h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2; - move16(); move16(); + move16(); + move16(); #else min_exp = MIN_16; move16(); @@ -2410,11 +2417,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( g1 = alpha[l]; // Q31 move32(); g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 - assert(q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k]); + assert( q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k] ); *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ), Mpy_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); // (Q31, q_cy_auto_dir_smooth_prev_local) -> q_cy_auto_dir_smooth_prev_local move32(); - assert(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev); + assert( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev ); *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ), Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev move32(); @@ -2422,7 +2429,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_dir_smooth_prev++ ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31 #ifdef FIX_867_CLDFB_NRG_SCALE - qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), q_cy_auto_dir_smooth_prev_local[k] ), Q31 ) ); @@ -2516,7 +2523,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); L_tmp = Mpy_32_32( power_smooth_temp, L_tmp ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31 #ifdef FIX_867_CLDFB_NRG_SCALE - qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ), Q31 ) ); @@ -4058,22 +4065,22 @@ static void computeTargetPSDs_direct_fx( { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else - scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ #endif scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */ v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */ - v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else - scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ #endif scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */ v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */ @@ -4144,7 +4151,7 @@ static void computeTargetPSDs_direct_subframe_fx( cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power[0]+q_tmp*/ move32(); } - Word16 q_tmp2 = sub(q_tmp, sub(q_reference_power[1], q_reference_power[0])); + Word16 q_tmp2 = sub( q_tmp, sub( q_reference_power[1], q_reference_power[0] ) ); FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ ) { cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ @@ -4161,7 +4168,7 @@ static void computeTargetPSDs_direct_subframe_fx( move16(); v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32(&cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max(sub(num_freq_bands, CLDFB_NO_CHANNELS_HALF), 0), sub(q_reference_power[0], q_reference_power[1])); + Scale_sig32( &cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) ); #endif } @@ -4203,12 +4210,12 @@ static void computeTargetPSDs_diffuse_fx( { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */ - scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub ( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */ #else - scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ #endif scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */ v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */ @@ -4240,7 +4247,7 @@ static void computeTargetPSDs_diffuse_subframe_fx( v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32(diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max(0, sub(num_freq_bands, CLDFB_NO_CHANNELS_HALF)), sub(q_reference_power[0], q_reference_power[1])); + Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power[0], q_reference_power[1] ) ); #endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -4290,7 +4297,7 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE - q_common = s_min(*q_cy_auto_diff_smooth, s_min(q_reference_power_min_one[0], q_reference_power_min_one[1] ) ); + q_common = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power_min_one[0], q_reference_power_min_one[1] ) ); #else IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power_min_one ) ) { @@ -4321,11 +4328,11 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( #ifdef FIX_867_CLDFB_NRG_SCALE IF( NE_16( q_common, q_reference_power_min_one[0] ) ) { - scale_sig32( aux_buffer_res, s_min( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( q_common, q_reference_power_min_one[0] ) ); // q_common + scale_sig32( aux_buffer_res, s_min( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_common, q_reference_power_min_one[0] ) ); // q_common } IF( NE_16( q_common, q_reference_power_min_one[1] ) ) { - scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max(0, sub( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_common, q_reference_power_min_one[1] ) ); // q_common + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_common, q_reference_power_min_one[1] ) ); // q_common } IF( NE_16( q_common, *q_cy_auto_diff_smooth ) ) { diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 19a67dd3d..c4c1a2330 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -790,10 +790,12 @@ ivas_error ivas_dirac_alloc_mem_fx( #ifdef FIX_867_CLDFB_NRG_SCALE hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = Q31; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = Q31; - move16(); move16(); + move16(); + move16(); hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = Q31; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = Q31; - move16(); move16(); + move16(); + move16(); #else hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = Q31; move16(); @@ -960,10 +962,12 @@ ivas_error ivas_dirac_alloc_mem_fx( #ifdef FIX_867_CLDFB_NRG_SCALE hDirAC_mem->reference_power_q[0] = Q31; hDirAC_mem->reference_power_q[1] = Q31; - move16(); move16(); + move16(); + move16(); hDirAC_mem->reference_power_smooth_q[0] = Q31; hDirAC_mem->reference_power_smooth_q[1] = Q31; - move16(); move16(); + move16(); + move16(); #else hDirAC_mem->reference_power_q = Q31; move16(); @@ -1497,7 +1501,7 @@ void protoSignalComputation_shd_fx( *proto_direct_buffer_f_q = add( q_cldfb, min_q_shift ); move16(); #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); reference_power_q[qidx] = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 ); move16(); #else @@ -1541,7 +1545,8 @@ void protoSignalComputation_shd_fx( #ifdef FIX_867_CLDFB_NRG_SCALE reference_power_q[0] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); reference_power_q[1] = reference_power_q[0]; - move16(); move16(); + move16(); + move16(); #else *reference_power_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); @@ -1639,7 +1644,8 @@ void protoSignalComputation1_fx( proto_power_smooth_q[1] = add( proto_power_smooth_q[1], q_shift ); proto_power_smooth_fx_q[0] = proto_power_smooth_q[0]; proto_power_smooth_fx_q[1] = proto_power_smooth_q[1]; - move16(); move16(); + move16(); + move16(); #else *proto_power_smooth_q = add( *proto_power_smooth_q, q_shift ); proto_power_smooth_fx_q = *proto_power_smooth_q; @@ -1649,7 +1655,7 @@ void protoSignalComputation1_fx( FOR( l = 0; l < num_freq_bands; l++ ) { #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); #endif re = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -1717,7 +1723,8 @@ void protoSignalComputation1_fx( #ifdef FIX_867_CLDFB_NRG_SCALE proto_power_smooth_q[0] = proto_power_smooth_fx_q[0]; proto_power_smooth_q[1] = proto_power_smooth_fx_q[1]; - move16(); move16(); + move16(); + move16(); #else *proto_power_smooth_q = proto_power_smooth_fx_q; move16(); @@ -1811,15 +1818,15 @@ void protoSignalComputation2_fx( q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } ELSE { q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } q_proto_power_smooth[0] = add( q_proto_power_smooth[0], sub( q_shift, 1 ) ); @@ -1829,16 +1836,16 @@ void protoSignalComputation2_fx( q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } ELSE { q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } q_proto_power_smooth[1] = add( q_proto_power_smooth[1], sub( q_shift, 1 ) ); move16(); @@ -1886,7 +1893,7 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) @@ -2143,7 +2150,7 @@ void protoSignalComputation2_fx( /* Compute protos (and their power) for direct sound rendering */ #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); #endif /* W prototype */ @@ -2629,7 +2636,7 @@ void protoSignalComputation2_fx( move64(); #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min(1, s_max(0, sub(l, CLDFB_NO_CHANNELS_HALF-1))); + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) @@ -2760,7 +2767,8 @@ void protoSignalComputation2_fx( #ifdef FIX_867_CLDFB_NRG_SCALE q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp ); q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp ); - move16(); move16(); + move16(); + move16(); #else *q_proto_power_smooth = s_min( *q_proto_power_smooth, q_temp ); move16(); @@ -4024,7 +4032,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q @@ -4041,7 +4050,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q @@ -4051,7 +4061,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( } ELSE { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; move16(); } @@ -4104,7 +4114,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q @@ -4121,7 +4132,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q @@ -4131,7 +4143,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( } ELSE { - Scale_sig32( reference_power_fix, sub(hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; move16(); } @@ -4181,7 +4193,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q @@ -4198,7 +4211,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q @@ -4347,10 +4361,12 @@ static void ivas_masa_ext_dirac_render_sf_fx( #ifdef FIX_867_CLDFB_NRG_SCALE DirAC_mem.reference_power_q[0] = sub( DirAC_mem.reference_power_q[0], 1 ); DirAC_mem.reference_power_q[1] = sub( DirAC_mem.reference_power_q[1], 1 ); - move16(); move16(); + move16(); + move16(); DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; - move16(); move16(); + move16(); + move16(); #else DirAC_mem.reference_power_q = sub( DirAC_mem.reference_power_q, 1 ); move16(); @@ -4510,40 +4526,44 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); } #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands*2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands*3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands*4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands * 2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands * 3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands * 4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); move16(); - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*5, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 5, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); move16(); - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands*2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands*3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands*4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands * 2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands * 3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands * 4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); move16(); - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - IF ( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands*4, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 4, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); move16(); @@ -4576,18 +4596,19 @@ static void ivas_masa_ext_dirac_render_sf_fx( /*Buffer rescaling*/ #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - IF ( GT_16( DirAC_mem.reference_power_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) { - Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 2), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 3), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 4), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + IF( GT_16( DirAC_mem.reference_power_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { + Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) } hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); @@ -4633,7 +4654,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q @@ -4650,7 +4672,8 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF ( GT_16( DirAC_mem.reference_power_len, shr(hSpatParamRendCom->num_freq_bands, 1 ) ) ) { + IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + { Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a24330988..16739283b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8312,7 +8312,8 @@ static void intermidiate_ext_dirac_render( #ifdef FIX_867_CLDFB_NRG_SCALE DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0] = Q31; DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1] = Q31; - move16(); move16(); + move16(); + move16(); #else DirAC_mem.reference_power_smooth_q = DirAC_mem.reference_power_q = Q31; move16(); @@ -8457,20 +8458,24 @@ static void intermidiate_ext_dirac_render( /* Possible improvement: normalize both scale regions individually. */ tmp = 0; move16(); - FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { - tmp = s_min(tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF ) ); + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF ) ); } - FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); move16(); tmp = 0; move16(); - FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { - tmp = s_min(tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); } - FOR ( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands) ) { + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); -- GitLab From 959cf7ada88ceaaef4cfaf1c949c69449d007435 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 27 Feb 2025 16:35:37 +0100 Subject: [PATCH 0270/1221] Issue #867 : use 2 scale regions for reference_power vectors to improve precision. Work in progress. Format. Fix warning. --- lib_rend/ivas_dirac_output_synthesis_dec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 8a2dd7bec..a6d11fac4 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1952,7 +1952,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word16 alphaMaxBinFast; Word32 L_tmp; Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS]; +#if 0 Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp; +#else + Word16 exp = 0, exp1, q_com, q_tmp, min_exp; +#endif Word32 tmp32; move16(); -- GitLab From 9778e0b4fb9e4c9a420b1ce19416ed22a35618b1 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 28 Feb 2025 09:30:06 +0100 Subject: [PATCH 0271/1221] whitespace --- lib_com/ivas_tools.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index e0a971951..dc45e3f0e 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -642,6 +642,7 @@ Word32 dot_product_cholesky_fixed( return suma; } + /*---------------------------------------------------------------------* * dot_product_cholesky() * @@ -665,6 +666,7 @@ Word64 dot_product_cholesky_fixed64( pt_A = A; suma = 0; move64(); + FOR( i = 0; i < N; i++ ) { tmp_sum = 0; @@ -676,12 +678,15 @@ Word64 dot_product_cholesky_fixed64( mul = Mpy_32_32( *pt_x++, *pt_A++ ); tmp_sum = W_add( tmp_sum, W_deposit32_l( mul ) ); } + tmp_sum = W_shr( tmp_sum, 4 ); // to make sure that the tmp_sum will not overflow tmp = W_extract_l( tmp_sum ); suma = W_mac_32_32( suma, tmp, tmp ); } + return suma; } + void v_mult_mat_fixed( Word32 *y, /* o : the product x*A Qx - guardbits*/ const Word32 *x, /* i : vector x Qx*/ -- GitLab From 50219449150be1331a9e943a99dff4ca2a62ad6e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Feb 2025 14:12:07 +0530 Subject: [PATCH 0272/1221] USAN fixes for encoder and decoder --- lib_com/ivas_dirac_com.c | 8 ++++++++ lib_com/options.h | 1 + lib_dec/ivas_td_low_rate_dec.c | 13 +++++++++++++ lib_enc/ivas_mct_core_enc.c | 13 +++++++++++++ lib_enc/ivas_qmetadata_enc.c | 17 +++++++++++++++++ lib_enc/ivas_stereo_ica_enc.c | 14 +++++++++----- lib_enc/ivas_tcx_core_enc.c | 9 +++++++++ lib_rend/ivas_dirac_output_synthesis_dec.c | 4 ++++ 8 files changed, 74 insertions(+), 5 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 0e8050451..557db9696 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -974,7 +974,11 @@ void computeDiffuseness_fixed( Word16 shift_qtotal; if ( shift_q < 0 ) { +#ifdef FIX_USAN_ISSUES + shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); +#else shiftEquiv = L_lshl( 0x80000000, shift_q ); +#endif } if ( shift_q >= 0 ) { @@ -1020,7 +1024,11 @@ void computeDiffuseness_fixed( #ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS if ( shift_q < 0 ) { +#ifdef FIX_USAN_ISSUES + shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); +#else shiftEquiv = L_lshl( 0x80000000, shift_q ); +#endif } if ( shift_q >= 0 ) { diff --git a/lib_com/options.h b/lib_com/options.h index a37ccf387..50c5066fa 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,6 +156,7 @@ #define FIX_ISSUE_1291 /* Ittiam: Wrong use of imult1616() in ACELP rescaling */ #define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ +#define FIX_USAN_ISSUES /* Ittiam: Fix issues reported by USAN */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c index dbbc22b4d..a4380bd4e 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec.c @@ -139,8 +139,21 @@ void tdm_low_rate_dec_fx( edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, find_guarded_bits_fx( L_FRAME ), IVAS_CPE_TD ); +#ifdef FIX_USAN_ISSUES + IF( bwe_exc != NULL ) + { + Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, + L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); + } + ELSE + { + Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], NULL, st->hGSCDec->last_exc_dct_in_fx, + L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); + } +#else Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); +#endif /*----------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected *----------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 0ed03eb1c..7a5a83155 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -337,8 +337,21 @@ void ivas_mct_core_enc_fx( IF( switch_bw ) { +#ifdef FIX_USAN_ISSUES + IF( sts[ch_core]->hIGFEnc == NULL ) + { + initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, + sts[ch_core]->igf, NULL, 0 ); + } + ELSE + { + initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, + sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); + } +#else initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); +#endif } IF( sts[ch_core]->igf ) diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 387f82463..3f0218e97 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -2503,7 +2503,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( } ELSE { +#ifdef FIX_USAN_ISSUES + avg_elevation_index = (UWord16) L_add( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ); +#else avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ) ); +#endif } // avg_elevation_index = (uint16_t) ( ( avg_elevation_index + avg_elevation_alphabet ) % avg_elevation_alphabet ); avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index, avg_elevation_alphabet ) % avg_elevation_alphabet ); @@ -2638,8 +2642,13 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( FOR( avg_azimuth_offset = 0; avg_azimuth_offset < q_direction->cfg.search_effort; avg_azimuth_offset++ ) { set_zero_fx( avg_direction_vector, 3 ); +#ifdef FIX_USAN_ISSUES + avg_azimuth_index = (UWord16) L_add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); + avg_azimuth_index = (UWord16) ( L_add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); +#else avg_azimuth_index = (UWord16) add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); avg_azimuth_index = (UWord16) ( add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); +#endif all_zero_dist_azimuth_indexes = 1; move16(); azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); @@ -5445,7 +5454,11 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { +#ifdef FIX_USAN_ISSUES + no_idx16 = add( shr( nbits_fr, 4 ), 1 ); +#else no_idx16 = shr_r( nbits_fr, 4 ); +#endif } /* write combined index */ @@ -5467,7 +5480,11 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { +#ifdef FIX_USAN_ISSUES + no_idx16 = add( shr( nbits_fr1, 4 ), 1 ); +#else no_idx16 = shr_r( nbits_fr1, 4 ); +#endif } assert( no_idx16 <= 4 ); diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 0235630d2..72876ae35 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -1096,9 +1096,13 @@ static void corrStatsEst_fx( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */ move32(); +#ifdef FIX_USAN_ISSUES + Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ +#else Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -hStereoTCA->delay_0_mem_fx[0], hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ - inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ - IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 +#endif + inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ + IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 { set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 ); hStereoTCA->delay_0_mem_exp = temp; @@ -1979,8 +1983,8 @@ void stereo_tca_enc_fx( move16(); } #else - scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ + scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ #endif tempF_fx = tempF_16fx; @@ -2272,7 +2276,7 @@ static void unclr_calc_corr_features_fx( prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) ); sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */ #else - sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); /* Q31-sum_prod_exp */ + sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); /* Q31-sum_prod_exp */ #endif } diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index bc6df4f56..c7fc58099 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -1061,7 +1061,12 @@ Word16 ivas_acelp_tcx20_switching_fx( IF( LE_32( offset, 0xAA153 ) ) /* 0xAA153 -> 32.f * log2(10)/10 */ { +#ifdef FIX_USAN_ISSUES + offset = (Word32) 0xFFD57AB5; /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ + move32(); +#else offset = L_add( 0xFFD57AB5, 0 ); /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ +#endif } offset_tcx = offset; move32(); @@ -1164,7 +1169,11 @@ Word16 ivas_acelp_tcx20_switching_fx( { *pt_ener_sfr = -668739840; /* 0xFFEC1185 -> log2(1e-6) in 6Q25 */ move32(); +#ifdef FIX_USAN_ISSUES + tmp32 = (Word32) 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ +#else tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ +#endif move32(); } ELSE diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 0fe7cdef1..d6c999aa0 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1110,7 +1110,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word32 aux; IF( temp_q1 < 0 ) { +#ifdef FIX_USAN_ISSUES + Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 ); +#else Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); +#endif FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); -- GitLab From d29e5c5e6eba221b818ea52c966833297ded4bbb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Feb 2025 15:14:54 +0530 Subject: [PATCH 0273/1221] Clang formatting changes --- lib_enc/ivas_tcx_core_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index c7fc58099..cecc1bf80 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -1172,7 +1172,7 @@ Word16 ivas_acelp_tcx20_switching_fx( #ifdef FIX_USAN_ISSUES tmp32 = (Word32) 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ #else - tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ + tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ #endif move32(); } -- GitLab From 77fbd2f57f72a36859b492777453df1f9d1c614e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 28 Feb 2025 10:51:30 +0100 Subject: [PATCH 0274/1221] adjust artifacts and instructions to match new files produced --- .gitlab-ci.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d3eb06636..3c20ff80e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -673,7 +673,7 @@ stages: - echo "Reproduce locally with:" - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - - echo "The individual command lines can be found in the changes*.csv files in the job artifacts." + - echo "The individual command lines can be found in the regressions_crashes.csv files in the job artifacts." - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then - cat regression_log.txt - if [ $allow_regressions_flag == 0 ]; then @@ -686,7 +686,7 @@ stages: - echo "Reproduce locally with:" - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" - - echo "The individual command lines can be found in the changes*.csv files in the job artifacts." + - echo "The individual command lines can be found in the regressions_*.csv files in the job artifacts." - fi - exit $exit_code @@ -711,11 +711,8 @@ stages: - $FLOAT_REF_COMMIT_FILE - $CUT_COMMIT_FILE - $MERGE_TARGET_COMMIT_FILE - - changes_crashes.csv - - changes_MLD.csv - - changes_MAXIMUM_ABS_DIFF.csv - - changes_MIN_SSNR.csv - - changes_MIN_ODG.csv + - regressions_*.csv + - improvements_*.csv expose_as: "pytest compare results" reports: junit: -- GitLab From 5f8ae98a1d0e89005331b074938c801f0fe63b06 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 28 Feb 2025 12:16:33 +0100 Subject: [PATCH 0275/1221] can't use wildcards with "expose as" -> use explicit paths --- .gitlab-ci.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c20ff80e..fc4c023dc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -711,8 +711,16 @@ stages: - $FLOAT_REF_COMMIT_FILE - $CUT_COMMIT_FILE - $MERGE_TARGET_COMMIT_FILE - - regressions_*.csv - - improvements_*.csv + - regressions_crashes.csv + - regressions_MLD.csv + - regressions_MAXIMUM_ABS_DIFF.csv + - regressions_MIN_SSNR.csv + - regressions_MIN_ODG.csv + - improvements_crashes.csv + - improvements_MLD.csv + - improvements_MAXIMUM_ABS_DIFF.csv + - improvements_MIN_SSNR.csv + - improvements_MIN_ODG.csv expose_as: "pytest compare results" reports: junit: -- GitLab From db8929b2b43f157801b52d0b29da6e4cf6d183e9 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Feb 2025 16:50:49 +0530 Subject: [PATCH 0276/1221] Removal of redundant files from lib_dec --- Workspace_msvc/lib_dec.vcxproj | 99 --------- Workspace_msvc/lib_dec.vcxproj.filters | 295 ------------------------- lib_dec/ACcontextMapping_dec.c | 45 ---- lib_dec/FEC.c | 54 ----- lib_dec/FEC_HQ_phase_ecu.c | 44 ---- lib_dec/FEC_adapt_codebook.c | 51 ----- lib_dec/FEC_clas_estim.c | 44 ---- lib_dec/FEC_lsf_estim.c | 49 ---- lib_dec/FEC_pitch_estim.c | 42 ---- lib_dec/FEC_scale_syn.c | 42 ---- lib_dec/LD_music_post_filter.c | 44 ---- lib_dec/TonalComponentDetection.c | 47 ---- lib_dec/acelp_core_dec.c | 49 ---- lib_dec/acelp_core_switch_dec.c | 42 ---- lib_dec/amr_wb_dec.c | 43 ---- lib_dec/avq_dec.c | 42 ---- lib_dec/cng_dec.c | 47 ---- lib_dec/core_dec_reconf.c | 43 ---- lib_dec/core_dec_switch.c | 48 ---- lib_dec/d_gain2p.c | 43 ---- lib_dec/dec2t32.c | 55 ----- lib_dec/dec4t64.c | 43 ---- lib_dec/dec_LPD.c | 54 ----- lib_dec/dec_ace.c | 42 ---- lib_dec/dec_acelp.c | 46 ---- lib_dec/dec_acelp_tcx_main.c | 43 ---- lib_dec/dec_amr_wb.c | 48 ---- lib_dec/dec_gen_voic.c | 42 ---- lib_dec/dec_higher_acelp.c | 50 ----- lib_dec/dec_nelp.c | 41 ---- lib_dec/dec_pit_exc.c | 48 ---- lib_dec/dec_post.c | 159 ------------- lib_dec/dec_ppp.c | 41 ---- lib_dec/dec_tran.c | 47 ---- lib_dec/dec_uv.c | 40 ---- lib_dec/decision_matrix_dec.c | 50 ----- lib_dec/dlpc_avq.c | 47 ---- lib_dec/dlpc_stoch.c | 49 ---- lib_dec/er_dec_acelp.c | 42 ---- lib_dec/er_dec_tcx.c | 45 ---- lib_dec/er_scale_syn.c | 49 ---- lib_dec/er_sync_exc.c | 43 ---- lib_dec/er_util.c | 43 ---- lib_dec/evs_dec.c | 43 ---- lib_dec/gain_dec.c | 43 ---- lib_dec/gaus_dec.c | 43 ---- lib_dec/gs_dec.c | 50 ----- lib_dec/gs_dec_amr_wb.c | 43 ---- lib_dec/hdecnrm.c | 85 ------- lib_dec/hf_synth.c | 112 ---------- lib_dec/hq_classifier_dec.c | 42 ---- lib_dec/hq_conf_fec.c | 42 ---- lib_dec/hq_core_dec.c | 56 ----- lib_dec/hq_env_dec.c | 41 ---- lib_dec/hq_hr_dec.c | 42 ---- lib_dec/hq_lr_dec.c | 105 --------- lib_dec/igf_dec.c | 141 ------------ lib_dec/igf_scf_dec.c | 41 ---- lib_dec/inov_dec.c | 50 ----- lib_dec/ivas_agc_dec.c | 37 ---- lib_dec/ivas_cpe_dec.c | 69 ------ lib_dec/ivas_dec.c | 49 ---- lib_dec/ivas_lfe_dec.c | 36 --- lib_dec/ivas_lfe_plc.c | 46 ---- lib_dec/ivas_mct_dec_mct.c | 41 ---- lib_dec/ivas_pca_dec.c | 44 ---- lib_dec/ivas_sba_dirac_stereo_dec.c | 43 ---- lib_dec/ivas_sce_dec.c | 43 ---- lib_dec/ivas_sns_dec.c | 41 ---- lib_dec/ivas_stereo_dft_plc.c | 40 ---- lib_dec/ivas_stereo_mdct_core_dec.c | 42 ---- lib_dec/jbm_pcmdsp_fifo.c | 40 ---- lib_dec/lead_deindexing.c | 47 ---- lib_dec/lib_dec.c | 37 ---- lib_dec/lp_exc_d.c | 41 ---- lib_dec/lsf_dec.c | 58 ----- lib_dec/lsf_msvq_ma_dec.c | 43 ---- lib_dec/nelp_dec.c | 49 ---- lib_dec/peak_vq_dec.c | 77 ------- lib_dec/pit_dec.c | 43 ---- lib_dec/pitch_extr.c | 45 ---- lib_dec/post_dec.c | 59 ----- lib_dec/ppp_dec.c | 43 ---- lib_dec/pvq_core_dec.c | 44 ---- lib_dec/pvq_decode.c | 42 ---- lib_dec/range_dec.c | 42 ---- lib_dec/re8_dec.c | 40 ---- lib_dec/rst_dec.c | 49 ---- lib_dec/stat_noise_uv_dec.c | 40 ---- lib_dec/swb_bwe_dec_hr.c | 49 ---- lib_dec/swb_bwe_dec_lr.c | 51 ----- lib_dec/syn_outp.c | 49 ---- lib_dec/tcq_core_dec.c | 44 ---- lib_dec/tcx_utils_dec.c | 49 ---- lib_dec/tns_base_dec.c | 43 ---- lib_dec/transition_dec.c | 43 ---- lib_dec/updt_dec.c | 44 ---- lib_dec/vlpc_1st_dec.c | 42 ---- lib_dec/vlpc_2st_dec.c | 40 ---- lib_dec/voiced_dec.c | 55 ----- lib_dec/waveadjust_fec_dec.c | 77 ------- 101 files changed, 5315 deletions(-) delete mode 100644 lib_dec/ACcontextMapping_dec.c delete mode 100644 lib_dec/FEC.c delete mode 100644 lib_dec/FEC_HQ_phase_ecu.c delete mode 100644 lib_dec/FEC_adapt_codebook.c delete mode 100644 lib_dec/FEC_clas_estim.c delete mode 100644 lib_dec/FEC_lsf_estim.c delete mode 100644 lib_dec/FEC_pitch_estim.c delete mode 100644 lib_dec/FEC_scale_syn.c delete mode 100644 lib_dec/LD_music_post_filter.c delete mode 100644 lib_dec/TonalComponentDetection.c delete mode 100644 lib_dec/acelp_core_dec.c delete mode 100644 lib_dec/acelp_core_switch_dec.c delete mode 100644 lib_dec/amr_wb_dec.c delete mode 100644 lib_dec/avq_dec.c delete mode 100644 lib_dec/cng_dec.c delete mode 100644 lib_dec/core_dec_reconf.c delete mode 100644 lib_dec/core_dec_switch.c delete mode 100644 lib_dec/d_gain2p.c delete mode 100644 lib_dec/dec2t32.c delete mode 100644 lib_dec/dec4t64.c delete mode 100644 lib_dec/dec_LPD.c delete mode 100644 lib_dec/dec_ace.c delete mode 100644 lib_dec/dec_acelp.c delete mode 100644 lib_dec/dec_acelp_tcx_main.c delete mode 100644 lib_dec/dec_amr_wb.c delete mode 100644 lib_dec/dec_gen_voic.c delete mode 100644 lib_dec/dec_higher_acelp.c delete mode 100644 lib_dec/dec_nelp.c delete mode 100644 lib_dec/dec_pit_exc.c delete mode 100644 lib_dec/dec_post.c delete mode 100644 lib_dec/dec_ppp.c delete mode 100644 lib_dec/dec_tran.c delete mode 100644 lib_dec/dec_uv.c delete mode 100644 lib_dec/decision_matrix_dec.c delete mode 100644 lib_dec/dlpc_avq.c delete mode 100644 lib_dec/dlpc_stoch.c delete mode 100644 lib_dec/er_dec_acelp.c delete mode 100644 lib_dec/er_dec_tcx.c delete mode 100644 lib_dec/er_scale_syn.c delete mode 100644 lib_dec/er_sync_exc.c delete mode 100644 lib_dec/er_util.c delete mode 100644 lib_dec/evs_dec.c delete mode 100644 lib_dec/gain_dec.c delete mode 100644 lib_dec/gaus_dec.c delete mode 100644 lib_dec/gs_dec.c delete mode 100644 lib_dec/gs_dec_amr_wb.c delete mode 100644 lib_dec/hdecnrm.c delete mode 100644 lib_dec/hf_synth.c delete mode 100644 lib_dec/hq_classifier_dec.c delete mode 100644 lib_dec/hq_conf_fec.c delete mode 100644 lib_dec/hq_core_dec.c delete mode 100644 lib_dec/hq_env_dec.c delete mode 100644 lib_dec/hq_hr_dec.c delete mode 100644 lib_dec/hq_lr_dec.c delete mode 100644 lib_dec/igf_dec.c delete mode 100644 lib_dec/igf_scf_dec.c delete mode 100644 lib_dec/inov_dec.c delete mode 100644 lib_dec/ivas_agc_dec.c delete mode 100644 lib_dec/ivas_cpe_dec.c delete mode 100644 lib_dec/ivas_dec.c delete mode 100644 lib_dec/ivas_lfe_dec.c delete mode 100644 lib_dec/ivas_lfe_plc.c delete mode 100644 lib_dec/ivas_mct_dec_mct.c delete mode 100644 lib_dec/ivas_pca_dec.c delete mode 100644 lib_dec/ivas_sba_dirac_stereo_dec.c delete mode 100644 lib_dec/ivas_sce_dec.c delete mode 100644 lib_dec/ivas_sns_dec.c delete mode 100644 lib_dec/ivas_stereo_dft_plc.c delete mode 100644 lib_dec/ivas_stereo_mdct_core_dec.c delete mode 100644 lib_dec/jbm_pcmdsp_fifo.c delete mode 100644 lib_dec/lead_deindexing.c delete mode 100644 lib_dec/lib_dec.c delete mode 100644 lib_dec/lp_exc_d.c delete mode 100644 lib_dec/lsf_dec.c delete mode 100644 lib_dec/lsf_msvq_ma_dec.c delete mode 100644 lib_dec/nelp_dec.c delete mode 100644 lib_dec/peak_vq_dec.c delete mode 100644 lib_dec/pit_dec.c delete mode 100644 lib_dec/pitch_extr.c delete mode 100644 lib_dec/post_dec.c delete mode 100644 lib_dec/ppp_dec.c delete mode 100644 lib_dec/pvq_core_dec.c delete mode 100644 lib_dec/pvq_decode.c delete mode 100644 lib_dec/range_dec.c delete mode 100644 lib_dec/re8_dec.c delete mode 100644 lib_dec/rst_dec.c delete mode 100644 lib_dec/stat_noise_uv_dec.c delete mode 100644 lib_dec/swb_bwe_dec_hr.c delete mode 100644 lib_dec/swb_bwe_dec_lr.c delete mode 100644 lib_dec/syn_outp.c delete mode 100644 lib_dec/tcq_core_dec.c delete mode 100644 lib_dec/tcx_utils_dec.c delete mode 100644 lib_dec/tns_base_dec.c delete mode 100644 lib_dec/transition_dec.c delete mode 100644 lib_dec/updt_dec.c delete mode 100644 lib_dec/vlpc_1st_dec.c delete mode 100644 lib_dec/vlpc_2st_dec.c delete mode 100644 lib_dec/voiced_dec.c delete mode 100644 lib_dec/waveadjust_fec_dec.c diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index d6e4a7c67..3d447fe21 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -136,152 +136,94 @@ - false - false - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -294,16 +236,13 @@ - - - @@ -315,7 +254,6 @@ - @@ -323,10 +261,8 @@ - - @@ -336,13 +272,11 @@ - - @@ -355,78 +289,45 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 348c5fbda..cc7594415 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -1,17 +1,10 @@  - - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c @@ -21,120 +14,63 @@ decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - - - decoder_evs_c - decoder_evs_c decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c - - decoder_evs_c - decoder_evs_c decoder_evs_c - - decoder_evs_c - - - decoder_evs_c - decoder_evs_c decoder_evs_c - - decoder_evs_c - - - decoder_evs_c - decoder_evs_c decoder_evs_c - - decoder_evs_c - - - decoder_evs_c - decoder_evs_c decoder_evs_c - - decoder_evs_c - decoder_ivas_c @@ -147,15 +83,9 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -192,15 +122,9 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -228,9 +152,6 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -255,9 +176,6 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -279,24 +197,15 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -321,9 +230,6 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -339,9 +245,6 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -363,15 +266,9 @@ decoder_ivas_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -393,9 +290,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -405,9 +299,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -417,27 +308,15 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -453,69 +332,36 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -525,18 +371,9 @@ decoder_all_c - - decoder_all_c - - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -549,105 +386,54 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -657,15 +443,9 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -681,102 +461,57 @@ decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -792,33 +527,18 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -828,33 +548,18 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - diff --git a/lib_dec/ACcontextMapping_dec.c b/lib_dec/ACcontextMapping_dec.c deleted file mode 100644 index 186a22bc7..000000000 --- a/lib_dec/ACcontextMapping_dec.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "ivas_rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot.h" /* Range coder header file */ -#include diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c deleted file mode 100644 index 3dd25fd27..000000000 --- a/lib_dec/FEC.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "prot.h" -#include "wmc_auto.h" - - -#define WMC_TOOL_SKIP -/*-------------------------------------------------------------------* - * pulseRes_preCalc() - * - * calculates some conditions for Pulse resynchronization to take place - *-------------------------------------------------------------------*/ - -#undef WMC_TOOL_SKIP diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c deleted file mode 100644 index 85b25b336..000000000 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "rom_dec.h" -#include "rom_com.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_adapt_codebook.c b/lib_dec/FEC_adapt_codebook.c deleted file mode 100644 index f07b5952a..000000000 --- a/lib_dec/FEC_adapt_codebook.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_dec.h" -#include "prot.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------------- - * FEC_synchro_exc() - * - * Perform resynchronisation of the last glottal pulse in voiced frame lost - *------------------------------------------------------------------------*/ - -/*! r: do_WI flag */ diff --git a/lib_dec/FEC_clas_estim.c b/lib_dec/FEC_clas_estim.c deleted file mode 100644 index 77501d3fa..000000000 --- a/lib_dec/FEC_clas_estim.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include "cnst.h" -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_lsf_estim.c b/lib_dec/FEC_lsf_estim.c deleted file mode 100644 index 49a4adafc..000000000 --- a/lib_dec/FEC_lsf_estim.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * FEC_lsf2lsp_interp_flt() - * - * - LSP calculation - * - A(z) calculation - *-------------------------------------------------------------------*/ diff --git a/lib_dec/FEC_pitch_estim.c b/lib_dec/FEC_pitch_estim.c deleted file mode 100644 index bae1a8539..000000000 --- a/lib_dec/FEC_pitch_estim.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_scale_syn.c b/lib_dec/FEC_scale_syn.c deleted file mode 100644 index 5c3581f4f..000000000 --- a/lib_dec/FEC_scale_syn.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/LD_music_post_filter.c b/lib_dec/LD_music_post_filter.c deleted file mode 100644 index 494df80ce..000000000 --- a/lib_dec/LD_music_post_filter.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "wmc_auto.h" diff --git a/lib_dec/TonalComponentDetection.c b/lib_dec/TonalComponentDetection.c deleted file mode 100644 index a8ad442c0..000000000 --- a/lib_dec/TonalComponentDetection.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#define _USE_MATH_DEFINES - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c deleted file mode 100644 index 2374f1b7c..000000000 --- a/lib_dec/acelp_core_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - - -#include -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c deleted file mode 100644 index b25a46f03..000000000 --- a/lib_dec/acelp_core_switch_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c deleted file mode 100644 index 47e1f0be1..000000000 --- a/lib_dec/amr_wb_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/avq_dec.c b/lib_dec/avq_dec.c deleted file mode 100644 index 1e54dc9d9..000000000 --- a/lib_dec/avq_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" -#include diff --git a/lib_dec/cng_dec.c b/lib_dec/cng_dec.c deleted file mode 100644 index 5f2ee4f7e..000000000 --- a/lib_dec/cng_dec.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "ivas_cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_dec/core_dec_reconf.c b/lib_dec/core_dec_reconf.c deleted file mode 100644 index 6bcd541ef..000000000 --- a/lib_dec/core_dec_reconf.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" -#include "prot_fx.h" diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c deleted file mode 100644 index 09bd8e846..000000000 --- a/lib_dec/core_dec_switch.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------* - * mode_switch_decoder_LPD() - * - * - *-------------------------------------------------------------*/ diff --git a/lib_dec/d_gain2p.c b/lib_dec/d_gain2p.c deleted file mode 100644 index cc19164ca..000000000 --- a/lib_dec/d_gain2p.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec2t32.c b/lib_dec/dec2t32.c deleted file mode 100644 index 13c9ebade..000000000 --- a/lib_dec/dec2t32.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*----------------------------------------------------------------------------------* - * dec_acelp_2t32() - * - * 12 bits algebraic codebook decoder. - * 2 track x 32 positions per track = 64 samples. - * - * 12 bits --> 2 pulses in a frame of 64 samples. - * - * All pulses can have two (2) possible amplitudes: +1 or -1. - * Each pulse can have 32 possible positions. - * - * See cod2t32.c for more details of the algebraic code. - *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/dec4t64.c b/lib_dec/dec4t64.c deleted file mode 100644 index d448123b1..000000000 --- a/lib_dec/dec4t64.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c deleted file mode 100644 index 4c0b6a79a..000000000 --- a/lib_dec/dec_LPD.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "cnst.h" -#include "basop_proto_func.h" -#include "stat_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -/*-------------------------------------------------------------------* - * decoder_LPD() - * - * Core decoder MODE2 - *--------------------------------------------------------------------*/ diff --git a/lib_dec/dec_ace.c b/lib_dec/dec_ace.c deleted file mode 100644 index 76754d2e6..000000000 --- a/lib_dec/dec_ace.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_acelp.c b/lib_dec/dec_acelp.c deleted file mode 100644 index 075822eb6..000000000 --- a/lib_dec/dec_acelp.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c deleted file mode 100644 index d8b8509d9..000000000 --- a/lib_dec/dec_acelp_tcx_main.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include "rom_com.h" -#include -#include "options.h" -#include "stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_amr_wb.c b/lib_dec/dec_amr_wb.c deleted file mode 100644 index 4cf26936b..000000000 --- a/lib_dec/dec_amr_wb.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * decod_amr_wb() - * - * Decode excitation signal in AMR-WB IO mode - *---------------------------------------------------------------------*/ diff --git a/lib_dec/dec_gen_voic.c b/lib_dec/dec_gen_voic.c deleted file mode 100644 index b25a46f03..000000000 --- a/lib_dec/dec_gen_voic.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_higher_acelp.c b/lib_dec/dec_higher_acelp.c deleted file mode 100644 index 77bd8dd6d..000000000 --- a/lib_dec/dec_higher_acelp.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-----------------------------------------------------------------* - * transf_cdbk_dec() - * - * Transform domain contribution decoding - *-----------------------------------------------------------------*/ diff --git a/lib_dec/dec_nelp.c b/lib_dec/dec_nelp.c deleted file mode 100644 index 167c70dbf..000000000 --- a/lib_dec/dec_nelp.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_pit_exc.c b/lib_dec/dec_pit_exc.c deleted file mode 100644 index 5a894a39c..000000000 --- a/lib_dec/dec_pit_exc.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * dec_pit_exc() - * - * Decode pitch-only contribution (used by the GSC technology) - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_post.c b/lib_dec/dec_post.c deleted file mode 100644 index 5cb811408..000000000 --- a/lib_dec/dec_post.c +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - -#define FORMAT_POST_FILT_G1 0.75f /*0.75f*/ /*denominator 0.9,0.75,0.15,0.9*/ - - -/*-------------------------------------------------------------------------- - * Local function prototypes - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * Function Init_post_filter_ivas() - * - * Post-filter initialization - *--------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------- - * nb_post_filt_ivas() - * - * Main routine to perform post filtering of NB signals - *--------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------- - * formant_post_filt_ivas: - * - * WB and SWB formant post-filtering - *--------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Dec_postfilt() - * - * Adaptive postfilter main function - * Short-term postfilter : - * Hst(z) = Hst0(z) Hst1(z) - * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z) - * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated) - * g0 = SUM(|hi|) if > 1 - * g0 = 1. else - * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1) - * with mu = k1 * gamma3 - * k1 = 1st parcor calculated on {hi} - * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 - * Long-term postfilter : - * harmonic postfilter : H0(z) = gl * (1 + b * z-p) - * b = gamma_g * gain_ltp - * gl = 1 / 1 + b - * computation of delay p on A(gamma2)(z) s(z) - * sub optimal search - * 1. search around 1st subframe delay (3 integer values) - * 2. search around best integer with fract. delays (1/8) - *----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Dec_formant_postfilt - * - * Post - adaptive postfilter main function - * Short term postfilter : - * Hst(z) = Hst0(z) Hst1(z) - * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z) - * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated) - * g0 = SUM(|hi|) if > 1 - * g0 = 1. else - * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1) - * with mu = k1 * gamma3 - * k1 = 1st parcor calculated on {hi} - * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 - *----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * pst_ltp() - * - * Perform harmonic postfilter - *----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * search_del() - * - * Computes best (shortest) integer LTP delay + fine search - *---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * filt_plt() - * - * Perform long term postfilter - *----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * compute_ltp_l() - * - * compute delayed signal, num & den of gain for fractional delay - * with long interpolation filter - *----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * select_ltp() - * - * selects best of (gain1, gain2) - * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1 - * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2 - *----------------------------------------------------------------------------*/ - -/*! r: 1 = 1st gain, 2 = 2nd gain */ - - -/*------------------------------------------------------------------------------------ - * modify_pst_param() - * - * Modify gamma1 and gamma2 values in function of the long-term noise level - *-----------------------------------------------------------------------------------*/ diff --git a/lib_dec/dec_ppp.c b/lib_dec/dec_ppp.c deleted file mode 100644 index 167c70dbf..000000000 --- a/lib_dec/dec_ppp.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_tran.c b/lib_dec/dec_tran.c deleted file mode 100644 index 3522990d9..000000000 --- a/lib_dec/dec_tran.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * decod_tran() - * - * Decode transition (TC) frames - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_uv.c b/lib_dec/dec_uv.c deleted file mode 100644 index 9e7ce9558..000000000 --- a/lib_dec/dec_uv.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/decision_matrix_dec.c b/lib_dec/decision_matrix_dec.c deleted file mode 100644 index 9ee7741c0..000000000 --- a/lib_dec/decision_matrix_dec.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "stat_dec.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-----------------------------------------------------------------* - * decision_matrix_dec() - * - * ACELP/HQ core selection - * Read ACELP signaling bits from the bitstream - * Set extension layers - *-----------------------------------------------------------------*/ diff --git a/lib_dec/dlpc_avq.c b/lib_dec/dlpc_avq.c deleted file mode 100644 index 748544423..000000000 --- a/lib_dec/dlpc_avq.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------* - * dlpc_avq() - * - * Variable bitrate multiple LPC un-quantizer - *------------------------------------------------------------------*/ diff --git a/lib_dec/dlpc_stoch.c b/lib_dec/dlpc_stoch.c deleted file mode 100644 index 5645c9462..000000000 --- a/lib_dec/dlpc_stoch.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------* - * lpc_unquantize() - * - * - *------------------------------------------------------------------*/ diff --git a/lib_dec/er_dec_acelp.c b/lib_dec/er_dec_acelp.c deleted file mode 100644 index 047de37fb..000000000 --- a/lib_dec/er_dec_acelp.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c deleted file mode 100644 index f2bd70247..000000000 --- a/lib_dec/er_dec_tcx.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include "cnst.h" -#include "ivas_cnst.h" -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_scale_syn.c b/lib_dec/er_scale_syn.c deleted file mode 100644 index eea698fa6..000000000 --- a/lib_dec/er_scale_syn.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" - - -/*----------------------------------------------------------------------------------* - * Damping_fact_flt() - * - * Estimate damping factor - *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/er_sync_exc.c b/lib_dec/er_sync_exc.c deleted file mode 100644 index 05720aca8..000000000 --- a/lib_dec/er_sync_exc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_util.c b/lib_dec/er_util.c deleted file mode 100644 index 9cd1332e6..000000000 --- a/lib_dec/er_util.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c deleted file mode 100644 index 47e1f0be1..000000000 --- a/lib_dec/evs_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/gain_dec.c b/lib_dec/gain_dec.c deleted file mode 100644 index 47e1f0be1..000000000 --- a/lib_dec/gain_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/gaus_dec.c b/lib_dec/gaus_dec.c deleted file mode 100644 index 47e1f0be1..000000000 --- a/lib_dec/gaus_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/gs_dec.c b/lib_dec/gs_dec.c deleted file mode 100644 index 4d34802bb..000000000 --- a/lib_dec/gs_dec.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * decod_audio() - * - * Decode audio (AC) frames - *-------------------------------------------------------------------*/ diff --git a/lib_dec/gs_dec_amr_wb.c b/lib_dec/gs_dec_amr_wb.c deleted file mode 100644 index 47e1f0be1..000000000 --- a/lib_dec/gs_dec_amr_wb.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/hdecnrm.c b/lib_dec/hdecnrm.c deleted file mode 100644 index 19627a4f3..000000000 --- a/lib_dec/hdecnrm.c +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------------------*/ -/* Function decode_huff_context() */ -/* */ -/* Context based Huffman decoding for indices of quantized norms */ -/*--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------*/ -/* Function hdecnrm() */ -/* */ -/* Huffman decoding for indices of quantized norms */ -/*--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * huff_dec() - * - * Huffman decoding - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hdecnrm_context() - * - * Huffman decoding for indices of quantized norms - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hdecnrm_resize() - * - * - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hdecnrm_trans() - * - * Huffman decoding for indices of quantized norms - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/hf_synth.c b/lib_dec/hf_synth.c deleted file mode 100644 index fc8c8da5f..000000000 --- a/lib_dec/hf_synth.c +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "basop32.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------------------* - * hf_synthesis_amr_wb() - * - * HF noise synthesis - * - Generate HF noise between 6 and 8 kHz, mix it with signal obtained by linear resampling. - * - Set energy of high band - *-----------------------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------------------* - * EnhanceClass() - * - * - *-----------------------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------------------* - * envelope() - * - * - *-----------------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * AdaptiveStartBand() - * - * adaptively select the start band of bandwidth extension - *---------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------* - * hp400_12k8() - * - * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz. - * Optimized for fixed-point to get the following frequency response: - * - * frequency : 0Hz 100Hz 200Hz 300Hz 400Hz 630Hz 1.5kHz 3kHz - * dB loss : -infdB -30dB -20dB -10dB -3dB +6dB +1dB 0dB - * - * Algorithm : - * - * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] - * + a[1]*y[i-1] + a[2]*y[i-2]; - * - * short b[3] = {3660, -7320, 3660}; in Q12 - * short a[3] = {4096, 7320, -3540}; in Q12 - * - * float b[3] = {0.893554687, -1.787109375, 0.893554687}; - * float a[3] = {1.000000000, 1.787109375, -0.864257812}; - *-----------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * filt_6k_7k() - * - * 15th order band pass 6kHz to 7kHz FIR filter - * - * frequency :4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz - * dB loss : -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB - * (gain = 4.0) - *-------------------------------------------------------------------*/ diff --git a/lib_dec/hq_classifier_dec.c b/lib_dec/hq_classifier_dec.c deleted file mode 100644 index c899b52ff..000000000 --- a/lib_dec/hq_classifier_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_conf_fec.c b/lib_dec/hq_conf_fec.c deleted file mode 100644 index b25a46f03..000000000 --- a/lib_dec/hq_conf_fec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_core_dec.c b/lib_dec/hq_core_dec.c deleted file mode 100644 index cd29271f1..000000000 --- a/lib_dec/hq_core_dec.c +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" - -/*-------------------------------------------------------------------------- - * hq_core_dec() - * - * HQ core decoder - *--------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * hq_core_dec_init() - * - * Initialize HQ core state structure - *-------------------------------------------------------------------*/ diff --git a/lib_dec/hq_env_dec.c b/lib_dec/hq_env_dec.c deleted file mode 100644 index d029c2fa8..000000000 --- a/lib_dec/hq_env_dec.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_hr_dec.c b/lib_dec/hq_hr_dec.c deleted file mode 100644 index b25a46f03..000000000 --- a/lib_dec/hq_hr_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_lr_dec.c b/lib_dec/hq_lr_dec.c deleted file mode 100644 index 8547d9712..000000000 --- a/lib_dec/hq_lr_dec.c +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "prot.h" -#include "stl.h" -#include "basop_util.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------------------* - * Local function prototypes - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * hq_lr_dec() - * - * HQ low rate decoding routine - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------------ - * small_symbol_dec_tran() - * - * Huffman decoding of differential energies - *--------------------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * small_symbol_dec() - * - * Huffman decoding of differential energies (MSB and LSB) - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * large_symbol_dec() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * band_energy_dequant() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * p2a_threshold_dequant() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * mdct_spectrum_fine_gain_dec() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * spt_shorten_domain_set_dec() - * - * update the shorten band information based on p2a analysis - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c deleted file mode 100644 index 64a8d798b..000000000 --- a/lib_dec/igf_dec.c +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_dec.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -/*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_1_flr() - * - * measures TCX noise - *-------------------------------------------------------------------*/ - -/*! r: number of noise bands */ - - -/*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_2_flt() - * - * replaces TCX noise - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_2_new_flt() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_decode_whitening_level_flt() - * - * reads whitening levels - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_getMDCTSquare_flt() - * - * square the MDCT spectrum - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_calcSfbEnergy_flt() - * - * calculate energy per SFB - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_setLinesToZero_flt() - * - * set power spectrum values to zero, needed for energy calculation - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_RefineGrid_flt() - * - * refines the IGF grid - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGFDecReadData_flt() - * - * reads whitening information from the bitstream - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGFDecUpdateInfo_flt() - * - * updates the start/stop frequency of IGF according to igfGridIdx - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGFDecStoreTCX10SubFrameData_flt() - * - * store the IGF bitstream information for TCX10 subframes - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * IGFDecRestoreTCX10SubFrameData_flt() - * - * restore the IGF bitstream information for TCX10 subframes - *-------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * init_igf_dec_flt() - * - * Initialize IGF decoder parameters - *-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * get_igf_startline_flt() - * - * - *-----------------------------------------------------------------------*/ diff --git a/lib_dec/igf_scf_dec.c b/lib_dec/igf_scf_dec.c deleted file mode 100644 index 68174a8c2..000000000 --- a/lib_dec/igf_scf_dec.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/inov_dec.c b/lib_dec/inov_dec.c deleted file mode 100644 index be630cee0..000000000 --- a/lib_dec/inov_dec.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*----------------------------------------------------------------------* - * inov_decode() - * - * Decode the algebraic innovation and do pitch sharpening - *----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_agc_dec.c b/lib_dec/ivas_agc_dec.c deleted file mode 100644 index 46246da44..000000000 --- a/lib_dec/ivas_agc_dec.c +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include -#include "options.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c deleted file mode 100644 index 4a6f34081..000000000 --- a/lib_dec/ivas_cpe_dec.c +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" -#include - - -/*--------------------------------------------------------------------------* - * Local function prototypes - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * ivas_cpe_dec() - * - * Channel Pair Element (CPE) decoding routine - *--------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------- - * read_stereo_mode_and_bwidth() - * - * Read stereo technology info & audio bandwidth - *-------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------- - * stereo_mode_combined_format_dec() - * - * Set stereo format in a combined format - *-------------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c deleted file mode 100644 index 351331bb2..000000000 --- a/lib_dec/ivas_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------------------* - * ivas_dec() - * - * Principal IVAS decoder routine - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c deleted file mode 100644 index e9f3a7b28..000000000 --- a/lib_dec/ivas_lfe_dec.c +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_lfe_plc.c b/lib_dec/ivas_lfe_plc.c deleted file mode 100644 index 89b232254..000000000 --- a/lib_dec/ivas_lfe_plc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" - -/*------------------------------------------------------------------------------------------* - * Local constants - *------------------------------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c deleted file mode 100644 index 52431d36a..000000000 --- a/lib_dec/ivas_mct_dec_mct.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" -#include "wmc_auto.h" -#include -#include "stat_enc.h" -#include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_pca_dec.c b/lib_dec/ivas_pca_dec.c deleted file mode 100644 index f2f5274be..000000000 --- a/lib_dec/ivas_pca_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include -#include "ivas_cnst.h" -#include "wmc_auto.h" - - -/*-----------------------------------------------------------------------* - * Local function definitions - *-----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c deleted file mode 100644 index 1cfc7aa2e..000000000 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "ivas_rom_com.h" -#include "ivas_rom_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c deleted file mode 100644 index 5f384870f..000000000 --- a/lib_dec/ivas_sce_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_sns_dec.c b/lib_dec/ivas_sns_dec.c deleted file mode 100644 index 86fd2fb3e..000000000 --- a/lib_dec/ivas_sns_dec.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "ivas_rom_com.h" -#include "ivas_cnst.h" -#include -#include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_dft_plc.c b/lib_dec/ivas_stereo_dft_plc.c deleted file mode 100644 index 5a9122b00..000000000 --- a/lib_dec/ivas_stereo_dft_plc.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "math.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c deleted file mode 100644 index e11120d38..000000000 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_com.h" -#include "ivas_prot.h" -#include "ivas_stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c deleted file mode 100644 index 00e5ce7f0..000000000 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -/*! @file jbm_pcmdsp_fifo.c Ringbuffer (FIFO) with fixed capacity for audio samples */ - -#include -#include "options.h" diff --git a/lib_dec/lead_deindexing.c b/lib_dec/lead_deindexing.c deleted file mode 100644 index 35a1adf15..000000000 --- a/lib_dec/lead_deindexing.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c deleted file mode 100644 index 81d78932a..000000000 --- a/lib_dec/lib_dec.c +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#include -#include -#include -#include "lib_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/lp_exc_d.c b/lib_dec/lp_exc_d.c deleted file mode 100644 index 167c70dbf..000000000 --- a/lib_dec/lp_exc_d.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/lsf_dec.c b/lib_dec/lsf_dec.c deleted file mode 100644 index abc1aab9d..000000000 --- a/lib_dec/lsf_dec.c +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "basop_proto_func.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" - - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * lsf_dec() - * - * LSF decoder - *---------------------------------------------------------------------*/ diff --git a/lib_dec/lsf_msvq_ma_dec.c b/lib_dec/lsf_msvq_ma_dec.c deleted file mode 100644 index 042eec9ab..000000000 --- a/lib_dec/lsf_msvq_ma_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" diff --git a/lib_dec/nelp_dec.c b/lib_dec/nelp_dec.c deleted file mode 100644 index 1dc550e6d..000000000 --- a/lib_dec/nelp_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * nelp_decoder() - * - * NELP decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/peak_vq_dec.c b/lib_dec/peak_vq_dec.c deleted file mode 100644 index 67ab06e08..000000000 --- a/lib_dec/peak_vq_dec.c +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------* - * Local function prototypes - *------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hvq_dec() - * - * HVQ decoder - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * peak_vq_dec() - * - * Vector de-quantization of MDCT peaks - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * dequant_peaks() - * - * Reads codebook vector and scales peak - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hvq_dec_pos() - * - * HVQ decode peak positions - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/pit_dec.c b/lib_dec/pit_dec.c deleted file mode 100644 index c74e05591..000000000 --- a/lib_dec/pit_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/pitch_extr.c b/lib_dec/pitch_extr.c deleted file mode 100644 index 3d10f2158..000000000 --- a/lib_dec/pitch_extr.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "basop_util.h" -#include "wmc_auto.h" diff --git a/lib_dec/post_dec.c b/lib_dec/post_dec.c deleted file mode 100644 index 380b256b0..000000000 --- a/lib_dec/post_dec.c +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Function prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * post_decoder_flt() - * - * Perform post-processing - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bass_pf_1sf_delay() - * - * Perform low-frequency postfiltering - *---------------------------------------------------------------------*/ diff --git a/lib_dec/ppp_dec.c b/lib_dec/ppp_dec.c deleted file mode 100644 index 7ea6e47a5..000000000 --- a/lib_dec/ppp_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/pvq_core_dec.c b/lib_dec/pvq_core_dec.c deleted file mode 100644 index 2bdb05e5f..000000000 --- a/lib_dec/pvq_core_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "stl.h" -#include "wmc_auto.h" diff --git a/lib_dec/pvq_decode.c b/lib_dec/pvq_decode.c deleted file mode 100644 index 9228e2f5d..000000000 --- a/lib_dec/pvq_decode.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/range_dec.c b/lib_dec/range_dec.c deleted file mode 100644 index b25a46f03..000000000 --- a/lib_dec/range_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/re8_dec.c b/lib_dec/re8_dec.c deleted file mode 100644 index 9e7ce9558..000000000 --- a/lib_dec/re8_dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/rst_dec.c b/lib_dec/rst_dec.c deleted file mode 100644 index 3feb2af8e..000000000 --- a/lib_dec/rst_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*----------------------------------------------------------------------------------* - * CNG_reset_dec() - * - * Reset decoder static variables in case of CNG frame - *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/stat_noise_uv_dec.c b/lib_dec/stat_noise_uv_dec.c deleted file mode 100644 index 9e7ce9558..000000000 --- a/lib_dec/stat_noise_uv_dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/swb_bwe_dec_hr.c b/lib_dec/swb_bwe_dec_hr.c deleted file mode 100644 index 06d666ffd..000000000 --- a/lib_dec/swb_bwe_dec_hr.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * swb_bwe_dec_hr() - * - * HR SWB BWE decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/swb_bwe_dec_lr.c b/lib_dec/swb_bwe_dec_lr.c deleted file mode 100644 index 7bd79fa23..000000000 --- a/lib_dec/swb_bwe_dec_lr.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "stat_com.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * DecodeSWBGenericParameters() - * - * Decoding of generic subband coding parameters - *-------------------------------------------------------------------*/ diff --git a/lib_dec/syn_outp.c b/lib_dec/syn_outp.c deleted file mode 100644 index 543b69d8d..000000000 --- a/lib_dec/syn_outp.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * syn_output() - * - * Output synthesis signal with compensation for saturation - * returns number of clipped samples - *-------------------------------------------------------------------*/ diff --git a/lib_dec/tcq_core_dec.c b/lib_dec/tcq_core_dec.c deleted file mode 100644 index f7f81a0fa..000000000 --- a/lib_dec/tcq_core_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" diff --git a/lib_dec/tcx_utils_dec.c b/lib_dec/tcx_utils_dec.c deleted file mode 100644 index 1fc02caee..000000000 --- a/lib_dec/tcx_utils_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------- - * tcx_decoder_memory_update_flt() - * - * - *--------------------------------------------------------------*/ diff --git a/lib_dec/tns_base_dec.c b/lib_dec/tns_base_dec.c deleted file mode 100644 index c74a5f4e1..000000000 --- a/lib_dec/tns_base_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "stat_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/transition_dec.c b/lib_dec/transition_dec.c deleted file mode 100644 index 47e1f0be1..000000000 --- a/lib_dec/transition_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/updt_dec.c b/lib_dec/updt_dec.c deleted file mode 100644 index 6ffe42f8c..000000000 --- a/lib_dec/updt_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "cnst.h" -#include -#include "wmc_auto.h" diff --git a/lib_dec/vlpc_1st_dec.c b/lib_dec/vlpc_1st_dec.c deleted file mode 100644 index 78821eb05..000000000 --- a/lib_dec/vlpc_1st_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/vlpc_2st_dec.c b/lib_dec/vlpc_2st_dec.c deleted file mode 100644 index 9e7ce9558..000000000 --- a/lib_dec/vlpc_2st_dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/voiced_dec.c b/lib_dec/voiced_dec.c deleted file mode 100644 index 4fbd33bdf..000000000 --- a/lib_dec/voiced_dec.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * ppp_voiced_decoder() - * - * Voiced decoder for SC-VBR - *-------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * sc_vbr_dec_init_flt() - * - * Initialize SC-VBR decoder - *---------------------------------------------------------------------*/ diff --git a/lib_dec/waveadjust_fec_dec.c b/lib_dec/waveadjust_fec_dec.c deleted file mode 100644 index 65de1e11f..000000000 --- a/lib_dec/waveadjust_fec_dec.c +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * Local functions - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * waveform_adj2() - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_decode() - * - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_update() - * - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_update2() - * - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_signal_tuning() - * - * - *-------------------------------------------------------------------*/ -- GitLab From 4efb8dc052a8a2bcc64d83643560c732a2894349 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 19 Feb 2025 17:13:29 +0100 Subject: [PATCH 0277/1221] port FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP; under NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD --- lib_com/cnst.h | 4 ++++ lib_com/options.h | 1 + lib_enc/dtx_fx.c | 9 +++++---- lib_enc/ivas_ism_dtx_enc.c | 4 ++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 26903f525..87aafb11a 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -932,6 +932,10 @@ typedef enum #define GAIN_PRED_ORDER 4 /* Gain quantization - prediction order for gain quantizer (only for AMR-WB IO mode) */ #define MEAN_ENER 30 /* Gain quantization - average innovation energy */ +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD +#define DTX_THR 5 /* DTX - lp_noise threshold for DTX at higher bitrates */ +#endif + #define DTX_HIST_SIZE 8 /* CNG & DTX - number of last signal frames used for CNG averaging */ #define CNG_ISF_FACT 0.9f /* CNG & DTX - CNG spectral envelope smoothing factor */ #define STEP_AMR_WB_SID 2.625f /* CNG & DTX - CNG energy quantization step */ diff --git a/lib_com/options.h b/lib_com/options.h index 50c5066fa..9fed7783e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,4 +170,5 @@ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ +#define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ #endif diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 17965e99e..c003185a2 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -30,8 +30,7 @@ #define CNG_TYPE_HO 20 /* hangover for switching between CNG types */ -/* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ -#define LP_NOISE_LV 5 /* LP_NOISE level */ +#define LP_NOISE_LV DTX_THR /* LP_NOISE level */ #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ @@ -104,7 +103,6 @@ void dtx_ivas_fx( } ELSE { - /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ test(); test(); test(); @@ -232,7 +230,11 @@ void dtx_ivas_fx( test(); br_dtx_flag = ( ( st_fx->element_mode == EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ); +#else LT_16( st_fx->lp_noise_fx, 3840 /*15 in Q8*/ ); +#endif } test(); test(); @@ -674,7 +676,6 @@ void dtx_fx( } ELSE { - /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc.c index 95b37435c..3439baff1 100644 --- a/lib_enc/ivas_ism_dtx_enc.c +++ b/lib_enc/ivas_ism_dtx_enc.c @@ -177,7 +177,11 @@ Word16 ivas_ism_dtx_enc_fx( ( EQ_16( nchan_ism, 2 ) && LE_32( ivas_total_brate, IVAS_48k ) ) || ( EQ_16( nchan_ism, 3 ) && LE_32( ivas_total_brate, IVAS_80k ) ) || ( EQ_16( nchan_ism, 4 ) && LE_32( ivas_total_brate, IVAS_96k ) ) || +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + LT_16( lp_noise_max_fx, ( DTX_THR << 8 ) ) ) ) +#else LT_16( lp_noise_max_fx, ( 15 << 8 ) ) ) ) +#endif { dtx_flag = 0; move16(); -- GitLab From 2158608ceaa6fa982d915f5757ac3dad174f233f Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 20 Feb 2025 17:00:36 +0100 Subject: [PATCH 0278/1221] replace LP_NOISE_LV by DTX_THR --- lib_enc/dtx_fx.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index c003185a2..a1478d3f8 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -30,8 +30,9 @@ #define CNG_TYPE_HO 20 /* hangover for switching between CNG types */ -#define LP_NOISE_LV DTX_THR /* LP_NOISE level */ - +#ifndef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD +#define DTX_THR 5 /* LP_NOISE level */ +#endif #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ #define MAX_BRATE_DTX_IVAS IVAS_64k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ @@ -106,7 +107,7 @@ void dtx_ivas_fx( test(); test(); test(); - last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); + last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); test(); test(); @@ -115,9 +116,9 @@ void dtx_ivas_fx( #ifdef NONBE_1211_DTX_BR_SWITCHING last_br_flag = ( st_fx->element_mode == EVS_MONO && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) ) || ( st_fx->element_mode != EVS_MONO && LE_32( last_ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || - LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ); + LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); #else - last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); + last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); br_dtx_flag = 0; move16(); #endif @@ -231,7 +232,7 @@ void dtx_ivas_fx( br_dtx_flag = ( ( st_fx->element_mode == EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || #ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD - LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ); + LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); #else LT_16( st_fx->lp_noise_fx, 3840 /*15 in Q8*/ ); #endif @@ -676,9 +677,9 @@ void dtx_fx( } ELSE { - last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); + last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); - last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); + last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); br_dtx_flag = 0; move16(); } @@ -773,8 +774,8 @@ void dtx_fx( if ( st_fx->dtx_sce_sba == 0 ) #endif { - br_dtx_flag = LE_32( st_fx->total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || - EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st_fx->element_brate, IVAS_64k ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) ) ); + br_dtx_flag = LE_32( st_fx->total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || + EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st_fx->element_brate, IVAS_64k ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) ) ); } test(); test(); -- GitLab From b28ea2b217927e16c52f8aaca103daa952ec2cd3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Mar 2025 14:44:44 +0530 Subject: [PATCH 0279/1221] Fix for 3GPP issue 708: OSBA decoder crash [main] Link #708 --- lib_com/options.h | 1 + lib_dec/ivas_sba_dec.c | 5 +++++ lib_enc/lib_enc.c | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 9fed7783e..b24ac8267 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -171,4 +171,5 @@ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ #define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ +#define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ #endif diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 65faabdc0..94f1affde 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -351,7 +351,12 @@ ivas_error ivas_sba_dec_reconfigure_fx( test(); test(); test(); +#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH + test(); + IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) +#else IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) +#endif { IF( ( hSpar->hPCA = (PCA_DEC_STATE *) malloc( sizeof( PCA_DEC_STATE ) ) ) == NULL ) { diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 0475d65c4..6035687ed 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1095,7 +1095,11 @@ static ivas_error configureEncoder( } +#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH + if ( hEncoderConfig->Opt_PCA_ON && !( ( hEncoderConfig->ivas_format == SBA_FORMAT || hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) +#else if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) +#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } -- GitLab From 0ca0d09fc34508ec2abf1b6deb0992d2926480c2 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 3 Mar 2025 11:05:46 +0100 Subject: [PATCH 0280/1221] Use INV_LEVEL_SCALING instead --- .gitlab-ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cbab6a130..842611691 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -343,7 +343,8 @@ stages: - fi - *build-and-create-reference-outputs - - comp_args="--mld --ssnr --odg --input_scaling $LEVEL_SCALING" + - INV_LEVEL_SCALING=$(awk "BEGIN {print 1.0 / $LEVEL_SCALING}") + - comp_args="--mld --ssnr --odg --scalefac $INV_LEVEL_SCALING" - if [ "$ENCODER_TEST" = "true" ]; then - comp_args="${comp_args} --enc_stats" - fi @@ -444,7 +445,8 @@ stages: - echo $CI_MERGE_REQUEST_TITLE > tmp.txt - allow_regressions_flag=$(grep -c --ignore-case "\[allow[ -]*regression\]" tmp.txt) || true - - comp_args="--mld --ssnr --odg --input_scaling $LEVEL_SCALING" + - INV_LEVEL_SCALING=$(awk "BEGIN {print 1.0 / $LEVEL_SCALING}") + - comp_args="--mld --ssnr --odg --scalefac $INV_LEVEL_SCALING" ### run branch first # this per default builds the branch and the reference and creates the reference outputs -- GitLab From 281cfe4739a359ac07571cfebb9c9a830db58999 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 14:29:35 +0100 Subject: [PATCH 0281/1221] Fix cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF --- lib_dec/ivas_dirac_dec.c | 22 ++++++------- lib_rend/ivas_dirac_output_synthesis_dec.c | 16 ++++----- lib_rend/ivas_dirac_rend.c | 38 +++++++++++----------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index c490c546a..559edcca6 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -3130,7 +3130,7 @@ void ivas_dirac_dec_render_sf_fx( Copy32( reference_power_fx, &( hDirACRend->buffer_energy_fx[i_mult( sub( index, 1 ), num_freq_bands )] ), num_freq_bands ); #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32( &( hDirACRend->buffer_energy_fx[add( i_mult( sub( index, 1 ), num_freq_bands ), CLDFB_NO_CHANNELS_HALF )] ), sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_q[1] ) ); + Scale_sig32( &( hDirACRend->buffer_energy_fx[add( i_mult( sub( index, 1 ), num_freq_bands ), CLDFB_NO_CHANNELS_HALF )] ), s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_q[1] ) ); hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q[0]; #else hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; @@ -3371,7 +3371,7 @@ void ivas_dirac_dec_render_sf_fx( IF( LT_16( q_reference_power_smooth[0], DirAC_mem.reference_power_q[0] ) ) { Word32 temp; - FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + FOR( i = 0; i < s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) { temp = L_shl( reference_power_fx[i], sub( q_reference_power_smooth[0], DirAC_mem.reference_power_q[0] ) ); reference_power_fx[i] = L_max(temp, L_min(reference_power_fx[i], 1)); @@ -3383,7 +3383,7 @@ void ivas_dirac_dec_render_sf_fx( ELSE { Word32 temp; - FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + FOR( i = 0; i < s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) { temp = L_shl( reference_power_smooth_fx[i], sub( DirAC_mem.reference_power_q[0], q_reference_power_smooth[0] ) ); reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); @@ -3680,7 +3680,7 @@ void ivas_dirac_dec_render_sf_fx( ELSE { Word32 temp; - FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + FOR( i = 0; i < s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) { temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], q_reference_power_smooth[0] ) ); reference_power_smooth_fx[i] = L_max( temp, L_min( reference_power_smooth_fx[i], 1 ) ); @@ -3767,11 +3767,11 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF ) ); + exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ) ) ); } FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); move16(); @@ -3779,7 +3779,7 @@ void ivas_dirac_dec_render_sf_fx( { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF, sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // proto_power_smooth_q + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // proto_power_smooth_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0]; move16(); @@ -3788,7 +3788,7 @@ void ivas_dirac_dec_render_sf_fx( { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, CLDFB_NO_CHANNELS_HALF, sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // proto_power_smooth_prev_q + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // proto_power_smooth_prev_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; move16(); @@ -3797,7 +3797,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); } FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { @@ -3809,7 +3809,7 @@ void ivas_dirac_dec_render_sf_fx( { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // proto_power_smooth_q + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // proto_power_smooth_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1]; move16(); @@ -3818,7 +3818,7 @@ void ivas_dirac_dec_render_sf_fx( { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // proto_power_smooth_prev_q + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // proto_power_smooth_prev_q } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; move16(); diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index b1a24fdc3..74ec5f655 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -2029,9 +2029,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( /* Is this necessary at all ? */ q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, i_mult( num_freq_bands, nchan_target_psds ), sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/ @@ -2281,7 +2281,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( // Move proto_power_smooth_fx to common Q-factor #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 min_exp2 = MIN_16; + Word16 min_exp2 = -64; min_exp = MIN_16; move16(); move16(); @@ -2292,7 +2292,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( FOR( k = 0; k < num_protos_dir; k++ ) { - FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) { min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] ); } @@ -2306,7 +2306,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( FOR( k = 0; k < num_protos_dir; k++ ) { - FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) { *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/ move32(); @@ -4076,7 +4076,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ - scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ #endif @@ -4086,7 +4086,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ - scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ #endif @@ -4154,7 +4154,7 @@ static void computeTargetPSDs_direct_subframe_fx( } q_tmp = W_norm( W_max ); #ifdef FIX_867_CLDFB_NRG_SCALE - FOR( i = 0; i < CLDFB_NO_CHANNELS_HALF; i++ ) + FOR( i = 0; i < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) { cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power[0]+q_tmp*/ move32(); diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index c4c1a2330..9ebcb3132 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -1818,34 +1818,34 @@ void protoSignalComputation2_fx( q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } ELSE { - q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - scale_sig32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + q_shift = getScaleFactor32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } q_proto_power_smooth[0] = add( q_proto_power_smooth[0], sub( q_shift, 1 ) ); move16(); IF( isloudspeaker ) { - q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } ELSE { - q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 - scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } q_proto_power_smooth[1] = add( q_proto_power_smooth[1], sub( q_shift, 1 ) ); move16(); @@ -2712,14 +2712,14 @@ void protoSignalComputation2_fx( #ifdef FIX_867_CLDFB_NRG_SCALE Word16 norm_shift = 63; move16(); - FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) { IF( reference_power_64fx[l] ) { norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) ); } } - FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) { reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32 move32(); -- GitLab From e1b06ae2edc7bd01fba7d6dd852c40d62e34f502 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 14:32:22 +0100 Subject: [PATCH 0282/1221] Fix cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF. format. --- lib_rend/ivas_dirac_output_synthesis_dec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 74ec5f655..0a89b81ea 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -2028,9 +2028,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( #ifdef FIX_867_CLDFB_NRG_SCALE /* Is this necessary at all ? */ q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); - scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, i_mult( num_freq_bands, nchan_target_psds ), @@ -4075,7 +4075,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ @@ -4085,7 +4085,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ -- GitLab From 0e1ff48ee48f5d60918aa6f0d99489f8fa90fe8a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Mar 2025 19:09:04 +0530 Subject: [PATCH 0283/1221] Crash fixes for LTV encoder, ASAN/MSAN fixes --- lib_com/stat_com.h | 3 +- lib_com/tns_base.c | 2 + lib_enc/cod_tcx.c | 127 ++++++++++++++++++++++++---- lib_enc/ext_sig_ana_fx.c | 4 + lib_enc/igf_enc.c | 13 ++- lib_enc/ivas_core_pre_proc_front.c | 8 +- lib_enc/ivas_mct_core_enc.c | 4 + lib_enc/ivas_mct_enc_mct.c | 8 ++ lib_enc/ivas_stereo_mdct_core_enc.c | 9 +- lib_enc/prot_fx_enc.h | 10 ++- lib_enc/tcx_utils_enc_fx.c | 9 +- lib_enc/tns_base_enc_fx.c | 6 +- 12 files changed, 171 insertions(+), 32 deletions(-) diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index af097da84..9edc28c03 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -197,7 +197,8 @@ typedef struct TNS_filter_structure Word16 order; /* Filter order. */ Word16 coefIndex[TNS_MAX_FILTER_ORDER]; /* Quantized filter coefficients. */ Word16 predictionGain; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q7 */ - Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ + Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. predictionGain_e */ + Word16 predictionGain_e; /*Exponent for predictionGain32 */ Word16 avgSqrCoef; /* Average squared filter coefficient. E(0), Q15 */ } STnsFilter; diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index b5fd1f41f..515746bd5 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -1204,6 +1204,8 @@ void ResetTnsData( STnsData *pTnsData ) move16(); pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/ move32(); + pTnsFilter->predictionGain_e = PRED_GAIN_E; + move16(); pTnsFilter->avgSqrCoef = 0; move16(); pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/ diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index d0d36b502..78fe246e3 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -74,8 +74,11 @@ void TNSAnalysisStereo_fx( TCX_ENC_HANDLE hTcxEnc = NULL; Word16 individual_decision[NB_DIV]; Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; + move32(); + Word16 maxPredictionGain_e = Q31, meanPredictionGain_e; + move16(); + Word16 sum_e = 0; move16(); - individual_decision[0] = 0; move16(); individual_decision[1] = 0; @@ -210,7 +213,9 @@ void TNSAnalysisStereo_fx( test(); IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word32 maxPredGain_fx = -ONE_IN_Q23; + Word32 maxPredGain_fx = -ONE_IN_Q31; + move32(); + Word16 maxPredGain_e = 0; move16(); sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; @@ -228,30 +233,74 @@ void TNSAnalysisStereo_fx( * both filters for the decision */ - meanPredictionGain_fx = L_add( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ) ); // Q23 - maxPredictionGain_fx = L_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q23 - + meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e + Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, meanPredictionGain_fx, meanPredictionGain_e ); + IF( flag < 0 ) + { + maxPredictionGain_fx = meanPredictionGain_fx; + maxPredictionGain_e = meanPredictionGain_e; + move32(); + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } + Word16 flag_1 = BASOP_Util_Cmp_Mant32Exp( pFilter[1]->predictionGain32, pFilter[1]->predictionGain_e, L_deposit_h( pTnsParameters[1]->minPredictionGain ), PRED_GAIN_E ); + if ( flag_1 < 0 ) + { + flag_1 = 0; + move16(); + } test(); test(); test(); - IF( GT_32( pFilter[0]->predictionGain32, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && - GT_32( pFilter[1]->predictionGain32, L_shl( pTnsParameters[1]->minPredictionGain, 16 ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + IF( flag && LT_32( sts[0]->element_brate, IVAS_80k ) && + flag_1 && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) { pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ + move32(); + move32(); + pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */ + move16(); + move16(); + pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */ move16(); move16(); } + flag = BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ), meanPredictionGain_e, L_abs( BASOP_Util_Add_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_negate( pFilter[1]->predictionGain32 ), pFilter[1]->predictionGain_e, &sum_e ) ), sum_e ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); - IF( LT_32( L_abs( L_sub( pFilter[0]->predictionGain32, pFilter[1]->predictionGain32 ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && + IF( flag && ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) { Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); + // maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); + flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, meanPredictionGain_fx, meanPredictionGain_e ); + IF( flag < 0 ) + { + maxPredGain_fx = meanPredictionGain_fx; + maxPredGain_e = meanPredictionGain_e; + move32(); + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( meanPredictionGain_fx, meanPredictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); test(); - IF( GT_32( meanPredictionGain_fx, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + IF( flag || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) { test(); test(); @@ -454,10 +503,16 @@ void TNSAnalysisStereo_fx( move16(); } } + Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); test(); test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && individual_decision[k] == 0 && flag && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; move16(); @@ -477,7 +532,15 @@ void TNSAnalysisStereo_fx( ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); } } - maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); + IF( flag < 0 ) + { + maxPredictionGain_fx = maxPredGain_fx; + maxPredictionGain_e = maxPredGain_e; + move32(); + move16(); + } } } } @@ -515,7 +578,9 @@ void TNSAnalysisStereo_fx( IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word32 maxPredGain_fx = -ONE_IN_Q23; // Q23 + Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31 + move32(); + Word16 maxPredGain_e = 0; move16(); sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; @@ -526,9 +591,23 @@ void TNSAnalysisStereo_fx( pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); + // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, pFilter->predictionGain32, pFilter->predictionGain_e ); + IF ( flag < 0 ) + { + maxPredGain_fx = pFilter->predictionGain32; + move32(); + maxPredGain_e = pFilter->predictionGain_e; + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( pFilter->predictionGain32, pFilter->predictionGain_e, L_deposit_h( pTnsParameters->minPredictionGain ), PRED_GAIN_E ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); - IF( GT_32( pFilter->predictionGain32, L_shl( pTnsParameters->minPredictionGain, 16 ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + IF( flag || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) { test(); test(); @@ -600,9 +679,15 @@ void TNSAnalysisStereo_fx( sts[ch]->hTcxEnc->fUseTns[k] = 0; } move16(); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); test(); - IF( !bWhitenedDomain && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && flag && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[ch]->hTcxEnc->fUseTns[k] = 0; move16(); @@ -617,7 +702,15 @@ void TNSAnalysisStereo_fx( move16(); } } - maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); + IF( flag < 0 ) + { + maxPredictionGain_fx = maxPredGain_fx; + maxPredictionGain_e = maxPredGain_e; + move32(); + move16(); + } } } } diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index fc4a1889a..c437be5be 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1372,7 +1372,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( st->igf ) { Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] ); +#ifndef MSAN_FIX ProcessIGF_ivas_fx( st, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); +#else + ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); +#endif } } } diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 2c9f5a371..6ac6e6811 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2577,7 +2577,10 @@ Word16 IGFEncWriteConcatenatedBitstream( *-------------------------------------------------------------------*/ void IGFEncApplyMono_ivas_fx( - Encoder_State *st, /* i : Encoder state */ + Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ +#endif const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ @@ -2658,12 +2661,20 @@ void IGFEncApplyMono_ivas_fx( IF( pPowerSpectrumParameter_fx ) { +#ifndef MSAN_FIX FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) +#else + FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) +#endif { common_pPowerSpectrum_exp = s_max( common_pPowerSpectrum_exp, pPowerSpectrumParameter_exp[i] ); } +#ifndef MSAN_FIX FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) +#else + FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) +#endif { common_pPowerSpectrum_fx[i] = L_shl( pPowerSpectrumParameter_fx[i], sub( pPowerSpectrumParameter_exp[i], common_pPowerSpectrum_exp ) ); move16(); diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index e866dd146..b7a10a4f3 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -630,12 +630,6 @@ ivas_error pre_proc_front_ivas_fx( headroom = 2; move16(); - test(); - test(); - if ( ( st->bwidth == NB || st->max_bwidth == NB ) && GT_32( st->input_Fs, 8000 ) ) - { - headroom = add( headroom, 1 ); - } test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) @@ -731,7 +725,7 @@ ivas_error pre_proc_front_ivas_fx( shift = sub( norm_s( inp_max ), headroom ); Word16 Q_min; - shift = s_max( shift, 0 ); + shift = s_max( shift, -1 ); shift = s_min( shift, Q_MAX ); minimum_fx( st->Q_max, L_Q_MEM, &Q_min ); *Q_new = s_min( shift, Q_min ); diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 7a5a83155..d11447c03 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -656,7 +656,11 @@ void ivas_mct_core_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); +#ifndef MSAN_FIX ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#else + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#endif st->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index ae561c0d0..7e8547841 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -1118,7 +1118,11 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[p_ch[ch]], sub( Q31, q_powerSpec[p_ch[ch]] ), N_MAX + L_MDCT_OVLP_MAX ); +#ifndef MSAN_FIX ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#else + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); @@ -1159,7 +1163,11 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powerSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); +#ifndef MSAN_FIX ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#else + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index e85c01db2..b43c8dfdb 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -676,8 +676,11 @@ void stereo_mdct_core_enc_fx( q_spectrum = sub( Q31, st->hTcxEnc->spectrum_e[n] ); Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ - +#ifndef MSAN_FIX ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#else + ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#endif } } } @@ -718,7 +721,11 @@ void stereo_mdct_core_enc_fx( Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ +#ifndef MSAN_FIX ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#else + ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#endif } } } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 58da977a7..4d8b74380 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1250,7 +1250,10 @@ void AVQ_cod_lpc_fx( ); void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ + Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ +#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -3092,7 +3095,10 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | Word16 last_core_acelp /**< in: Q0 | indictaor if last frame was acelp coded */ ); -void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ +void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ +#endif const int16_t igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 27c8e6f5f..5e7ca7be8 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3783,7 +3783,10 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) * *---------------------------------------------------------------------*/ void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ + Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ +#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -3830,7 +3833,11 @@ void ProcessIGF_ivas_fx( IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, *q_spectrum ) ); +#ifndef MSAN_FIX IGFEncApplyMono_ivas_fx( st, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); +#else + IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); +#endif curr_order = 0; move16(); diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index 452842e30..f1881a427 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -862,9 +862,11 @@ static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter Word16 temp_e = 0; move16(); Word16 temp = BASOP_Util_Divide3232_Scale( rxx_0, L_tmp, &temp_e ); - pTnsFilter->predictionGain32 = L_shl( temp, ( sub( add( 16, temp_e ), PRED_GAIN_E ) ) ); // Q23 + pTnsFilter->predictionGain32 = L_deposit_h( temp ); move32(); - pTnsFilter->predictionGain = extract_h( pTnsFilter->predictionGain32 ); // Q7 + pTnsFilter->predictionGain_e = temp_e; + move16(); + pTnsFilter->predictionGain = shl_sat( temp, sub( temp_e, PRED_GAIN_E ) ); // Q7 move16(); BASOP_SATURATE_WARNING_ON_EVS /* non-linear quantization of TNS lattice coefficients with given resolution */ -- GitLab From 584e1f745784ba714a23de577eee39e0a7edf542 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Mar 2025 19:16:30 +0530 Subject: [PATCH 0284/1221] Clang formatting changes --- lib_enc/cod_tcx.c | 2 +- lib_enc/prot_fx_enc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 78fe246e3..88e028c86 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -593,7 +593,7 @@ void TNSAnalysisStereo_fx( // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, pFilter->predictionGain32, pFilter->predictionGain_e ); - IF ( flag < 0 ) + IF( flag < 0 ) { maxPredGain_fx = pFilter->predictionGain32; move32(); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 4d8b74380..2e151df8f 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1252,7 +1252,7 @@ void AVQ_cod_lpc_fx( void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ #ifdef MSAN_FIX - Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ #endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ -- GitLab From c8d9f7b458d6916666d980eb32fe224f2e5daa31 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 3 Mar 2025 14:55:44 +0100 Subject: [PATCH 0285/1221] Restore basop-ci-branch --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 997429468..15c944725 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "ci/basop-ci-branch-input-scaling" + BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From de66837188c12936e978e84b4df7344ec71cdd36 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 15:14:58 +0100 Subject: [PATCH 0286/1221] Fix more cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF. --- lib_dec/ivas_dirac_dec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 559edcca6..ed721f142 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2474,11 +2474,11 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF ) ); + tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); } FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, CLDFB_NO_CHANNELS_HALF, tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], tmp1 ); move16(); @@ -2486,11 +2486,11 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); } FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], tmp1 ); move16(); -- GitLab From 18254c7c1ba3ef0fc2c1b228079243f24bd00bdb Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 15:47:36 +0100 Subject: [PATCH 0287/1221] Fix more cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF. --- lib_dec/ivas_dirac_dec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index ed721f142..e41832040 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -3424,12 +3424,12 @@ void ivas_dirac_dec_render_sf_fx( v_add_fixed_me( reference_power_fx, sub( 31, DirAC_mem.reference_power_q[0] ), reference_power_smooth_fx, sub( 31, q_reference_power_smooth[0] ), reference_power_smooth_fx, &temp_q, - CLDFB_NO_CHANNELS_HALF, 1 ); + s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 1 ); q_reference_power_smooth[0] = sub( 31, temp_q ); v_add_fixed_me( reference_power_fx + CLDFB_NO_CHANNELS_HALF, sub( 31, DirAC_mem.reference_power_q[1] ), reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( 31, q_reference_power_smooth[1] ), reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, &temp_q, - sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 1 ); + s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ); q_reference_power_smooth[1] = sub( 31, temp_q ); #endif #else @@ -3668,12 +3668,12 @@ void ivas_dirac_dec_render_sf_fx( } #ifdef FIX_867_CLDFB_NRG_SCALE - exp = L_norm_arr( reference_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); - scale_sig32( reference_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, exp ); // q_reference_power_smooth[0] + exp + exp = L_norm_arr( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + scale_sig32( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // q_reference_power_smooth[0] + exp q_reference_power_smooth[0] = add( q_reference_power_smooth[0], exp ); IF( LT_16( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // q_reference_power_smooth[0] + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // q_reference_power_smooth[0] hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = q_reference_power_smooth[0]; move16(); } @@ -3690,12 +3690,12 @@ void ivas_dirac_dec_render_sf_fx( move16(); } - exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // q_reference_power_smooth + exp + exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), exp ); // q_reference_power_smooth + exp q_reference_power_smooth[1] = add( q_reference_power_smooth[1], exp ); IF( LT_16( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // q_reference_power_smooth + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // q_reference_power_smooth hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = q_reference_power_smooth[1]; move16(); } -- GitLab From 9d8f6920ba39faa6d9d7b61a017892b37bea02bc Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 16:21:18 +0100 Subject: [PATCH 0288/1221] Fix more cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF. --- lib_rend/ivas_dirac_output_synthesis_dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 0a89b81ea..064fae66b 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -2028,9 +2028,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( #ifdef FIX_867_CLDFB_NRG_SCALE /* Is this necessary at all ? */ q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); - scale_sig32( reference_power_smooth, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, i_mult( num_freq_bands, nchan_target_psds ), -- GitLab From bc99a0ed94b295c5dcd4134d055e9b4d76e94b21 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 16:23:00 +0100 Subject: [PATCH 0289/1221] Fix more cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF. --- lib_rend/ivas_dirac_output_synthesis_dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 064fae66b..90fd493bc 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -2028,9 +2028,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( #ifdef FIX_867_CLDFB_NRG_SCALE /* Is this necessary at all ? */ q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); - scale_sig32( reference_power_smooth, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ + scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, i_mult( num_freq_bands, nchan_target_psds ), -- GitLab From 6937f3d181ce236f5828667bd57c45ceb25b3ec3 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 16:27:12 +0100 Subject: [PATCH 0290/1221] Fix more cases where number of bands is lower than CLDFB_NO_CHANNELS_HALF. --- lib_rend/ivas_dirac_output_synthesis_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 90fd493bc..b93bb05c1 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -4075,7 +4075,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ @@ -4085,7 +4085,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, CLDFB_NO_CHANNELS_HALF, sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ -- GitLab From 1d5ecbb6edc98eb9ffa3e7cb8132fd97356676a3 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 3 Mar 2025 16:42:15 +0100 Subject: [PATCH 0291/1221] format --- lib_rend/ivas_dirac_output_synthesis_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index b93bb05c1..c733f12c0 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -4075,7 +4075,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ @@ -4085,7 +4085,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ -- GitLab From 3a1f5fa87f739f3cb38d61146d2817d6118471f6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Feb 2025 19:20:51 +0530 Subject: [PATCH 0292/1221] Fix for 3GPP issue 1311: BASOP encoder for 80kbps Stereo does not trigger dtx when it should Link #1311 --- lib_enc/dtx_fx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index a1478d3f8..be4368f69 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -35,7 +35,7 @@ #endif #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ -#define MAX_BRATE_DTX_IVAS IVAS_64k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ +#define MAX_BRATE_DTX_IVAS IVAS_80k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ /*-------------------------------------------------------------------* * Local function prototypes @@ -107,7 +107,7 @@ void dtx_ivas_fx( test(); test(); test(); - last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); + last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, MAX_BRATE_DTX_EVS ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, MAX_BRATE_DTX_IVAS ) ); test(); test(); @@ -118,7 +118,7 @@ void dtx_ivas_fx( ( st_fx->element_mode != EVS_MONO && LE_32( last_ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); #else - last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); + last_br_flag = LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_IVAS ) ); br_dtx_flag = 0; move16(); #endif @@ -135,7 +135,7 @@ void dtx_ivas_fx( test(); test(); test(); - if ( ( EQ_16( st_fx->codec_mode, MODE1 ) || st_fx->Opt_AMR_WB ) && EQ_16( st_fx->element_mode, IVAS_SCE ) && EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + if ( ( EQ_16( st_fx->codec_mode, MODE1 ) || st_fx->Opt_AMR_WB ) && NE_16( st_fx->element_mode, IVAS_SCE ) && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { st_fx->cng_type = LP_CNG; move16(); @@ -254,8 +254,6 @@ void dtx_ivas_fx( { st_fx->last_total_brate_cng = -1; move16(); - st_fx->last_rf_mode_cng = st_fx->rf_mode; - move16(); } ELSE { @@ -265,6 +263,8 @@ void dtx_ivas_fx( move16(); st_fx->last_codec_mode_cng = st_fx->codec_mode; move16(); + st_fx->last_rf_mode_cng = st_fx->rf_mode; + move16(); } IF( hDtxEnc->cnt_SID == 0 ) @@ -321,7 +321,7 @@ void dtx_ivas_fx( test(); test(); test(); - IF( ( EQ_16( st_fx->cng_type, FD_CNG ) && ( LE_32( st_fx->total_brate, ACELP_24k40 ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( st_fx->total_brate, ACELP_32k ) ) ) ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) ) /* at highest bitrates, use exclusively LP_CNG */ + IF( ( EQ_16( st_fx->cng_type, FD_CNG ) && ( LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) ) ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) ) /* at highest bitrates, use exclusively LP_CNG */ { test(); test(); -- GitLab From 7edb193c68a1c0c4ce8f9da3c5846c2d171e66fc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Mar 2025 22:40:28 +0530 Subject: [PATCH 0293/1221] Fix for 3GPP issue 1256: Usage of NS2SA()-macro on variables Link #1256 --- lib_com/core_com_config.c | 4 +-- lib_com/ivas_fb_mixer.c | 6 ++-- lib_com/tcx_ltp_fx.c | 2 +- lib_com/window_ola_fx.c | 6 ++-- lib_dec/FEC_HQ_phase_ecu_fx.c | 30 +++++++++--------- lib_dec/acelp_core_dec_ivas_fx.c | 2 +- lib_dec/acelp_core_switch_dec_fx.c | 2 +- lib_dec/core_switching_dec.c | 8 ++--- lib_dec/core_switching_dec_fx.c | 4 +-- lib_dec/evs_dec_fx.c | 16 +++++----- lib_dec/fd_cng_dec_fx.c | 8 ++--- lib_dec/init_dec_fx.c | 4 +-- lib_dec/ivas_core_dec.c | 8 ++--- lib_dec/ivas_dirac_dec.c | 2 +- lib_dec/ivas_init_dec.c | 4 +-- lib_dec/ivas_ism_param_dec.c | 1 - lib_dec/ivas_jbm_dec.c | 26 +++++++-------- lib_dec/ivas_masa_dec.c | 2 +- lib_dec/ivas_mc_param_dec.c | 8 ++--- lib_dec/ivas_mc_paramupmix_dec.c | 2 +- lib_dec/ivas_mct_dec.c | 10 +++--- lib_dec/ivas_mdct_core_dec.c | 4 +-- lib_dec/ivas_post_proc.c | 24 +++++++------- lib_dec/ivas_sba_dec.c | 2 +- lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 2 +- lib_dec/ivas_stereo_dft_dec.c | 2 +- lib_dec/ivas_stereo_dft_dec_dmx.c | 4 +-- lib_dec/ivas_stereo_dft_dec_fx.c | 4 +-- lib_dec/ivas_stereo_ica_dec.c | 12 +++---- lib_dec/ivas_stereo_icbwe_dec.c | 28 ++++++++-------- lib_dec/ivas_stereo_mdct_stereo_dec.c | 4 +-- lib_dec/ivas_stereo_switching_dec.c | 12 +++---- lib_dec/ivas_stereo_td_dec.c | 8 ++--- lib_dec/swb_bwe_dec.c | 2 +- lib_dec/swb_bwe_dec_fx.c | 2 +- lib_enc/amr_wb_enc_fx.c | 2 +- lib_enc/core_enc_init_fx.c | 2 +- lib_enc/core_switching_enc_fx.c | 4 +-- lib_enc/fd_cng_enc_fx.c | 4 +-- lib_enc/hq_core_enc.c | 2 +- lib_enc/init_enc.c | 2 +- lib_enc/init_enc_fx.c | 2 +- lib_enc/ivas_core_pre_proc.c | 24 +++++++------- lib_enc/ivas_core_pre_proc_front.c | 8 ++--- lib_enc/ivas_corecoder_enc_reconfig.c | 2 +- lib_enc/ivas_cpe_enc.c | 6 ++-- lib_enc/ivas_front_vad.c | 2 +- lib_enc/ivas_lfe_enc.c | 4 +-- lib_enc/ivas_mc_paramupmix_enc.c | 4 +-- lib_enc/ivas_mcmasa_enc.c | 16 +++++----- lib_enc/ivas_osba_enc.c | 4 +-- lib_enc/ivas_stereo_ica_enc.c | 10 +++--- lib_enc/ivas_stereo_switching_enc.c | 6 ++-- lib_enc/lib_enc.c | 2 +- lib_enc/swb_bwe_enc_fx.c | 28 ++++++++-------- lib_enc/swb_pre_proc_fx.c | 44 +++++++++++++------------- lib_enc/swb_tbe_enc_fx.c | 8 ++--- 57 files changed, 225 insertions(+), 226 deletions(-) diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index 8d360c6a3..fdf935461 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -1235,8 +1235,8 @@ void init_tcx_window_cfg_fx( } /*Mid-OLA*/ /*compute minimum length for "half" window: lookahead - 5ms. It must be also multiple of 2*/ - hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA_FX2( 12800, 5000000L ), sr2fscale( sr_core ) ), LD_FSCALE_DENOM ) ); /*Q0*/ - hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA_FX2( 12800, 5000000L ), sr2fscale( input_Fs ) ), LD_FSCALE_DENOM ) ); /*Q0*/ + hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), sr2fscale( sr_core ) ), LD_FSCALE_DENOM ) ); /*Q0*/ + hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), sr2fscale( input_Fs ) ), LD_FSCALE_DENOM ) ); /*Q0*/ move16(); move16(); assert( GT_16( hTcxCfg->tcx_mdct_window_half_length, 16 ) && "Half window can not be large enough!" ); diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index 498de0188..43f468fb0 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -1289,7 +1289,7 @@ static ivas_error ivas_filterbank_setup_fx( ivas_get_active_bins_fx( &pAll_bins_per_band, &pAll_bins_per_band_abs, &pAll_bins_start_offset, &pAll_bins_start_offset_abs, sampling_rate ); - IF( EQ_16( pCfg->fb_latency, NS2SA( sampling_rate, DELAY_FB_1_NS ) ) ) + IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) ) { pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30 move32(); @@ -1478,7 +1478,7 @@ static ivas_error ivas_fb_mixer_get_window_fx( error = IVAS_ERR_OK; move32(); - IF( EQ_16( fade_len, NS2SA( sampling_rate, DELAY_FB_4_NS ) ) ) + IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) ) { SWITCH( sampling_rate ) { @@ -1495,7 +1495,7 @@ static ivas_error ivas_fb_mixer_get_window_fx( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" ); } } - ELSE IF( EQ_16( fade_len, NS2SA( sampling_rate, DELAY_FB_1_NS ) ) ) + ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) ) { SWITCH( sampling_rate ) { diff --git a/lib_com/tcx_ltp_fx.c b/lib_com/tcx_ltp_fx.c index 55228e0b3..9d7cb9254 100644 --- a/lib_com/tcx_ltp_fx.c +++ b/lib_com/tcx_ltp_fx.c @@ -1282,7 +1282,7 @@ void tcx_ltp_post( filtIdx = 0; /* just to avoid comilation warnings */ move16(); - tcx_buf_len = NS2SA( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */ + tcx_buf_len = NS2SA_FX2( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */ SideInfoOnly = 0; move16(); if ( GE_32( total_brate, HQ_96k ) ) diff --git a/lib_com/window_ola_fx.c b/lib_com/window_ola_fx.c index 19725735a..2948e725e 100644 --- a/lib_com/window_ola_fx.c +++ b/lib_com/window_ola_fx.c @@ -833,13 +833,13 @@ void core_switching_OLA_fx( IF( ( output_frame - L_FRAME16k ) == 0 ) /* no resampling */ { - Copy( mem_over_hp + 2, tmp_buf_switch + i_mult2( SWITCH_GAP_LENGTH_8k, delta ), NS2SA( output_Fs, DELAY_CLDFB_NS ) ); + Copy( mem_over_hp + 2, tmp_buf_switch + i_mult2( SWITCH_GAP_LENGTH_8k, delta ), NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ) ); } ELSE { IF( ( output_frame - L_FRAME8k ) == 0 ) /* not done yet */ { - Copy( synth_subfr_out + SWITCH_GAP_LENGTH_8k, tmp_buf_switch + SWITCH_GAP_LENGTH_8k, NS2SA( output_Fs, DELAY_CLDFB_NS ) ); /* copy subframe to tmp buffer */ + Copy( synth_subfr_out + SWITCH_GAP_LENGTH_8k, tmp_buf_switch + SWITCH_GAP_LENGTH_8k, NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ) ); /* copy subframe to tmp buffer */ } ELSE { @@ -950,7 +950,7 @@ void core_switching_OLA_fx( pt = synth; pt2 = tmp_buf_switch; - tmp = NS2SA( output_Fs, DELAY_CLDFB_NS ); + tmp = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); move16(); pt3 = synth_subfr_bwe; diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 708fc39e6..dd63b6508 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -2156,7 +2156,7 @@ static void ivas_subst_spec_fx( ELSE { // tmp = NS2SA(output_frame*50,PH_ECU_ALDO_OLP2_NS-PH_ECU_LOOKAHEAD_NS); - tmp = NS2SA_FX2( output_frame * 50, PH_ECU_ALDO_OLP2_NS ); + tmp = NS2SA_FX2( L_mult0( output_frame, 50 ), PH_ECU_ALDO_OLP2_NS ); move16(); tmp = sub( tmp, ph_ecu_lookahead ); tmp = add( tmp, sub( Lecu, shr( sub( Lecu, Lprot ), 1 ) ) ); @@ -2559,7 +2559,7 @@ static void subst_spec_fx( } ELSE { - tmp = NS2SA( output_frame * 50, PH_ECU_ALDO_OLP2_NS - PH_ECU_LOOKAHEAD_NS ); + tmp = NS2SA_FX2( L_mult0( output_frame, 50 ), PH_ECU_ALDO_OLP2_NS - PH_ECU_LOOKAHEAD_NS ); move16(); tmp = add( tmp, sub( Lecu, shr( sub( Lecu, Lprot ), 1 ) ) ); tmp = sub( tmp, shr( output_frame, 1 ) ); @@ -2920,9 +2920,9 @@ static void ivas_rec_wtda_fx( Word16 copy_len; Word16 ola_len; - copy_len = NS2SA( output_frame * FRAMES_PER_SEC, ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* prototype fill on each side of xsubst to fill MDCT Frame */ + copy_len = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* prototype fill on each side of xsubst to fill MDCT Frame */ move16(); - ola_len = NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */ + ola_len = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */ move16(); xf_len = 26; @@ -2980,7 +2980,7 @@ static void ivas_rec_wtda_fx( } /* extract reconstructed frame with aldo window */ - timesh = sub( NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ), shr( sub( shl( output_frame, 1 ), Lprot ), 1 ) ); + timesh = sub( NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ), shr( sub( shl( output_frame, 1 ), Lprot ), 1 ) ); set16_fx( xsubst_, 0, add( sub( shl( output_frame, 1 ), Lprot ), timesh ) ); Copy( X, xsubst_ + add( sub( shl( output_frame, 1 ), Lprot ), timesh ), sub( Lprot, timesh ) ); @@ -2988,9 +2988,9 @@ static void ivas_rec_wtda_fx( /* Copy and OLA look ahead zero part of MDCT window from decoded signal */ IF( element_mode != EVS_MONO ) { - Copy( old_dec, xsubst_ + NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ), copy_len ); /* also need to scale to Q0 ?? */ + Copy( old_dec, xsubst_ + NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ), copy_len ); /* also need to scale to Q0 ?? */ pOld = old_dec + copy_len; - pNew = xsubst_ + add( copy_len, NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ) ); + pNew = xsubst_ + add( copy_len, NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ) ); tmp = div_s( 1, shl( ola_len, 1 ) ); // Q15 tmp = round_fx( L_shl( L_mult( tmp, EVS_PI_FX ), 2 ) ); // Q15 sinq_fx( tmp, 0, ola_len, xfwin ); @@ -4583,7 +4583,7 @@ static void ivas_fec_noise_filling_fx( } ELSE { - kk = NS2SA( L * FRAMES_PER_SEC, N_ZERO_MDCT_NS ); + kk = NS2SA_FX2( L_mult0( L, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ); p_mdct_ola = old_out + kk; } @@ -4939,7 +4939,7 @@ static void ivas_hq_phase_ecu_fx( IF( element_mode == EVS_MONO ) { - ph_ecu_lookahead = NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); + ph_ecu_lookahead = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), PH_ECU_LOOKAHEAD_NS ); move16(); } ELSE @@ -5018,7 +5018,7 @@ static void ivas_hq_phase_ecu_fx( alpha, beta, *beta_mute, Xavg, element_mode, ph_ecu_lookahead, noise_fac ); /* reconstructed frame in tda domain */ - old_dec = prevsynth + sub( shl( output_frame, 1 ), NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ) ); + old_dec = prevsynth + sub( shl( output_frame, 1 ), NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ) ); ivas_rec_frame_fx( X, ecu_rec, output_frame, *Q_spec, old_dec, element_mode, num_p, plocs ); *last_fec = 0; @@ -5223,11 +5223,11 @@ void ivas_hq_ecu_fx( move16(); IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { - fec_alg_input = prevsynth + NS2SA( output_frame * FRAMES_PER_SEC, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ); + fec_alg_input = prevsynth + NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ); } ELSE { - fec_alg_input = prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); + fec_alg_input = prevsynth - NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), PH_ECU_LOOKAHEAD_NS ); } /* init (values ar changed after) */ @@ -5286,7 +5286,7 @@ void ivas_hq_ecu_fx( } ELSE { - ivas_hq_phase_ecu_fx( prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ), ecu_rec, time_offs, X_sav, Q_spec, num_p, plocs, plocsi, + ivas_hq_phase_ecu_fx( prevsynth - NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), PH_ECU_LOOKAHEAD_NS ), ecu_rec, time_offs, X_sav, Q_spec, num_p, plocs, plocsi, env_stab, last_fec, ph_ecu_active, prev_bfi, old_is_transient, mag_chg_1st, Xavg, beta_mute, st_fx->bwidth, output_frame, corr, st_fx->element_mode ); @@ -5354,7 +5354,7 @@ void hq_ecu_fx( #ifdef IVAS_FEC_ECU_TO_COMPLETE fec_ecu_pitch_fx( fec_alg_input, prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); #else - fec_ecu_pitch_fx( prevsynth + NS2SA( output_frame * 50, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); + fec_ecu_pitch_fx( prevsynth + NS2SA_FX2( L_mult0( output_frame, 50 ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); #endif } ELSE @@ -5409,7 +5409,7 @@ void hq_ecu_fx( ( LT_32( st_fx->total_brate, 48000 ) && ( ( ph_ecu_HqVoicing || GT_16( corr, 27853 ) ) && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) ) ) ) { - fec_alg_fx( prevsynth + NS2SA( output_frame * 50, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, &st_fx->hHQ_core->ni_seed_forfec, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth ); + fec_alg_fx( prevsynth + NS2SA_FX2( L_mult0( output_frame, 50 ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, &st_fx->hHQ_core->ni_seed_forfec, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth ); *last_fec = 1; move16(); *ph_ecu_active = 0; diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 42e4e36ef..6e56bc154 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -2101,7 +2101,7 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); #ifdef MSAN_FIX Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 387533957..f1772b9a7 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -242,7 +242,7 @@ ivas_error acelp_core_switch_dec_fx( *Q_syn = 0; move16(); - Copy_Scale_sig( synth_intFreq + sub( NS2SA( i_mult( L_frame_for_cs, 50 ), ( SWITCH_GAP_LENGTH_NS - DELAY_CLDFB_NS ) ), 2 ), mem_synth, add( NS2SA( i_mult( L_frame_for_cs, 50 ), DELAY_CLDFB_NS ), 2 ), negate( st_fx->Q_syn ) ); /* Copy mem with Q0 */ + Copy_Scale_sig( synth_intFreq + sub( NS2SA_FX2( i_mult( L_frame_for_cs, 50 ), ( SWITCH_GAP_LENGTH_NS - DELAY_CLDFB_NS ) ), 2 ), mem_synth, add( NS2SA_FX2( i_mult( L_frame_for_cs, 50 ), DELAY_CLDFB_NS ), 2 ), negate( st_fx->Q_syn ) ); /* Copy mem with Q0 */ /*----------------------------------------------------------------* * BWE decoding diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index 4c48a6fa8..aa04a70cb 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -110,11 +110,11 @@ ivas_error core_switching_pre_dec_ivas_fx( /* reset old HB synthesis buffer */ IF( EQ_16( st->last_L_frame, L_FRAME ) ) { - st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + st->old_bwe_delay = NS2SA_FX2( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); } ELSE { - st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + st->old_bwe_delay = NS2SA_FX2( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); } move16(); set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); @@ -189,7 +189,7 @@ ivas_error core_switching_pre_dec_ivas_fx( st->last_core = HQ_CORE; move16(); - Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 } @@ -221,7 +221,7 @@ ivas_error core_switching_pre_dec_ivas_fx( move16(); } - delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); + delay_comp = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); /*TODO To be tested:control not entering the block*/ test(); test(); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 17df8b5ca..d654b3af4 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1765,7 +1765,7 @@ ivas_error core_switching_post_dec_ivas_fx( Copy_Scale_sig( st_fx->previoussynth_fx, synth, delay_comp, *Qsynth ); /* Qsynth */ /* Overlap between TCX-LB and TCX-FB*/ - Word16 tmpDelta = NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); + Word16 tmpDelta = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); Word32 L_tmp2; FOR( i = 0; i < tmpDelta; i++ ) { @@ -1924,7 +1924,7 @@ ivas_error core_switching_post_dec_ivas_fx( } IF( output_mem_fx != NULL ) { - Scale_sig( output_mem_fx, NS2SA( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); /* Qtmp */ + Scale_sig( output_mem_fx, NS2SA_FX2( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); /* Qtmp */ } *Qsynth = Qtmp; move16(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index de6448433..945e149f2 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -919,7 +919,7 @@ ivas_error evs_dec_fx( IF( ( EQ_16( st_fx->bwidth, SWB ) || EQ_16( st_fx->bwidth, FB ) ) && ( ( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) ) && EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) { - GenTransition_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, 2 * NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), hb_synth_fx, + GenTransition_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, shl( NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), 1 ), hb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->mem_resamp_HB_32k_fx, &( hBWE_TD->syn_dm_phase ), st_fx->output_Fs, hBWE_TD->int_3_over_2_tbemem_dec_fx, st_fx->rf_flag, st_fx->total_brate ); @@ -929,7 +929,7 @@ ivas_error evs_dec_fx( } ELSE IF( EQ_16( st_fx->bwidth, WB ) && EQ_16( st_fx->last_extl, WB_TBE ) ) { - GenTransition_WB_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, st_fx->prev_Qx, 2 * NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), hb_synth_fx, + GenTransition_WB_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, st_fx->prev_Qx, shl( NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), 1 ), hb_synth_fx, hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, st_fx->output_Fs, hBWE_TD->mem_resamp_HB_fx ); hb_synth_fx_exp = st_fx->prev_Qx; @@ -1327,12 +1327,12 @@ ivas_error evs_dec_fx( { IF( EQ_32( st_fx->output_Fs, 8000 ) ) { - Copy( hTcxDec->FBTCXdelayBuf, st_fx->delay_buf_out_fx, NS2SA( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*st_fx->q_prev_synth_buffer_fx*/ + Copy( hTcxDec->FBTCXdelayBuf, st_fx->delay_buf_out_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*st_fx->q_prev_synth_buffer_fx*/ } ELSE { - Copy( hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); /*st_fx->Qprev_synth_buffer_fx*/ - Copy( hTcxDec->FBTCXdelayBuf + NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), st_fx->delay_buf_out_fx, NS2SA( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*Q0*/ + Copy( hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); /*st_fx->Qprev_synth_buffer_fx*/ + Copy( hTcxDec->FBTCXdelayBuf + NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), st_fx->delay_buf_out_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*Q0*/ } } } @@ -1362,7 +1362,7 @@ ivas_error evs_dec_fx( Scale_sig( output_sp, output_frame, timeIn_e ); /*timeIn_e*/ - tcx_ltp_post( st_fx, hTcxLtpDec, st_fx->core, output_frame /*hTcxDec->L_frameTCX*/, NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS ) + tmps, + tcx_ltp_post( st_fx, hTcxLtpDec, st_fx->core, output_frame /*hTcxDec->L_frameTCX*/, add( NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS ), tmps ), output_sp, hTcxDec->FBTCXdelayBuf ); Copy( output_sp, synth_fx, output_frame ); /*timeIn_e*/ @@ -1397,8 +1397,8 @@ ivas_error evs_dec_fx( ELSE { - Copy_Scale_sig( synth_fx + output_frame, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ - Copy_Scale_sig( hHQ_core->old_out_fx + NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS ), hTcxDec->old_synthFB_fx + shl( output_frame, 1 ) - NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( hHQ_core->Q_old_wtda ) ); /*Q0*/ + Copy_Scale_sig( synth_fx + output_frame, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ + Copy_Scale_sig( hHQ_core->old_out_fx + NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS ), hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( hHQ_core->Q_old_wtda ) ); /*Q0*/ } } } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index fa7e602a5..8a902448f 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -3621,9 +3621,9 @@ void generate_comfort_noise_dec_fx( IF( st->hTcxCfg->last_aldo != 0 ) { - FOR( i = 0; i < sub( hFdCngCom->frameSize, NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); i++ ) + FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ move16(); } } @@ -4160,9 +4160,9 @@ void generate_comfort_noise_dec_ivas_fx( IF( st->hTcxCfg->last_aldo != 0 ) { - FOR( i = 0; i < sub( hFdCngCom->frameSize, NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); i++ ) + FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ move16(); } } diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index d709ff5fc..a96774113 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -493,8 +493,8 @@ ivas_error init_decoder_fx( set16_fx( st_fx->hTcxDec->FBTCXdelayBuf, 0, 111 ); - st_fx->hTcxDec->old_synthFB_fx = st_fx->hTcxDec->synth_history_fx + NS2SA( st_fx->output_Fs, PH_ECU_MEM_NS ); - st_fx->hTcxDec->prev_good_synth_fx = st_fx->hTcxDec->old_synthFB_fx + NS2SA( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ); + st_fx->hTcxDec->old_synthFB_fx = st_fx->hTcxDec->synth_history_fx + NS2SA_FX2( st_fx->output_Fs, PH_ECU_MEM_NS ); + st_fx->hTcxDec->prev_good_synth_fx = st_fx->hTcxDec->old_synthFB_fx + NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ); } ELSE { diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 92b43092b..261a3c74e 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1639,15 +1639,15 @@ ivas_error ivas_core_dec_fx( move16(); move16(); - Copy_Scale_sig32_16( st->prev_synth_buffer32_fx, st->prev_synth_buffer_fx, NS2SA_FX2( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -( Q11 ) ); // Q0 + Copy_Scale_sig32_16( st->prev_synth_buffer32_fx, st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -( Q11 ) ); // Q0 st->q_prev_synth_buffer_fx = 0; move16(); exp_ouput = Find_Max_Norm32( output_32_fx[n], output_frame ); exp_ouput = add( exp_ouput, Q11 ); - exp_prev_synth_buffer = Find_Max_Norm16( st->prev_synth_buffer_fx, NS2SA_FX2( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + exp_prev_synth_buffer = Find_Max_Norm16( st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); exp_prev_synth_buffer = add( exp_prev_synth_buffer, st->q_prev_synth_buffer_fx ); - exp_old_out = Find_Max_Norm16( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), sub( add( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ), NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ) ); + exp_old_out = Find_Max_Norm16( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), sub( add( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ), NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ) ) ); exp_delay_buf_out = Find_Max_Norm16( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); exp_synth_history = Find_Max_Norm16( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ) ); exp_max = s_min( exp_synth_history, exp_ouput ); @@ -1660,7 +1660,7 @@ ivas_error ivas_core_dec_fx( Scale_sig32( output_fx_loc, output_frame, sub( exp_max, Q11 ) ); // Q(31-exp_max) Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), exp_max ); // exp_max Scale_sig( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), sub( NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ) ), exp_max ); // Q(31-exp_max) - Scale_sig( st->prev_synth_buffer_fx, NS2SA_FX2( 48000, L_sub( DELAY_BWE_TOTAL_NS, DELAY_CLDFB_NS ) ), sub( exp_max, st->q_prev_synth_buffer_fx ) ); // Q(exp_max - prev_synth_buffer_fx) + Scale_sig( st->prev_synth_buffer_fx, NS2SA_FX2( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), sub( exp_max, st->q_prev_synth_buffer_fx ) ); // Q(exp_max - prev_synth_buffer_fx) Scale_sig( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ), sub( exp_max, 0 ) ); // Q(31-exp_max) st->q_prev_synth_buffer_fx = sub( exp_max, st->q_prev_synth_buffer_fx ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 7d2f7be4f..9849647ea 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2093,7 +2093,7 @@ void ivas_dirac_dec_render_fx( output_f_local_fx[ch] = output_f_local_buff_fx[ch]; set_zero_fx( output_f_local_fx[ch], nSamplesAsked ); } - slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); // cL + slot_size = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); // cL /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 73e2b5d01..037ef4eb9 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2034,7 +2034,7 @@ ivas_error ivas_init_decoder_fx( } } - granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); @@ -2333,7 +2333,7 @@ ivas_error ivas_init_decoder_fx( /* no module has yet open the TC buffer, open a default one */ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); - IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 1f7af935d..424e6fb86 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -797,7 +797,6 @@ ivas_error ivas_param_ism_dec_open_fx( IF( st_ivas->hTcBuffer == NULL ) { - move16(); // NS2SA IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, nchan_full, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 5317e803e..3b66d3107 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -431,8 +431,8 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } IF( hCPE->hCoreCoder[0] != NULL ) { @@ -522,7 +522,7 @@ ivas_error ivas_jbm_dec_tc_fx( #ifdef MSAN_FIX FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) { - Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), hCPE->q_prev_synth_fx - 11 ); // q_prev_synth_fx + Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx } #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); @@ -537,7 +537,7 @@ ivas_error ivas_jbm_dec_tc_fx( #ifdef MSAN_FIX FOR( int ii = 0; ii < CPE_CHANNELS; ii++ ) { - Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 + Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 } #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); @@ -968,8 +968,8 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } IF( hCPE->hCoreCoder[0] != NULL ) { @@ -1008,7 +1008,7 @@ ivas_error ivas_jbm_dec_tc_fx( } #ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, 11 ) ); // q_prev_synth_fx + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); #endif @@ -1028,8 +1028,8 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 } IF( hCPE->hCoreCoder[0] != NULL ) @@ -1427,8 +1427,8 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } IF( hCPE->hCoreCoder[0] != NULL ) @@ -1473,7 +1473,7 @@ ivas_error ivas_jbm_dec_tc_fx( } #ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, 11 ) ); // q_prev_synth_fx + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); #endif @@ -1484,7 +1484,7 @@ ivas_error ivas_jbm_dec_tc_fx( } #ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); #endif // MSAN_FIX diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index aa42f4f91..4ca5c05b0 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -836,7 +836,7 @@ ivas_error ivas_masa_dec_open_fx( nchan_to_allocate = add( nchan_to_allocate, 1 ); } - IF( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_transport, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_transport, nchan_to_allocate, nchan_to_allocate, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 50d03b577..459dcc4d4 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -534,7 +534,7 @@ ivas_error ivas_param_mc_dec_open_fx( IF( st_ivas->hTcBuffer == NULL ) { - IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { return error; } @@ -1941,10 +1941,10 @@ void ivas_param_mc_dec_render_fx( /*slots_to_render = min(sub(hParamMC->num_slots, hParamMC->slots_rendered), nSamplesAsked / NS2SA(output_Fs, CLDFB_SLOT_NS)); *nSamplesRendered = slots_to_render * NS2SA(output_Fs, CLDFB_SLOT_NS);*/ Word16 temp_e; - Word16 temp = BASOP_Util_Divide1616_Scale( nSamplesAsked, NS2SA( output_Fs, CLDFB_SLOT_NS ), &temp_e ); + Word16 temp = BASOP_Util_Divide1616_Scale( nSamplesAsked, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ), &temp_e ); temp = shr( temp, sub( 15, temp_e ) ); slots_to_render = s_min( sub( hParamMC->num_slots, hParamMC->slots_rendered ), temp ); - *nSamplesRendered = imult1616( slots_to_render, NS2SA( output_Fs, CLDFB_SLOT_NS ) ); + *nSamplesRendered = imult1616( slots_to_render, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); move16(); Word16 j, k; first_sf = hParamMC->subframes_rendered; @@ -2272,7 +2272,7 @@ void ivas_param_mc_dec_render_fx( hParamMC->subframes_rendered = last_sf; move16(); - *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA( output_Fs, CLDFB_SLOT_NS ) ); + *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); move16(); FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index b12236746..be53d79c8 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -418,7 +418,7 @@ ivas_error ivas_mc_paramupmix_dec_open( move16(); } - IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index a92f21f6d..c95a5285a 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -430,11 +430,11 @@ ivas_error ivas_mct_dec_fx( Word16 output_mem_fx[L_FRAME48k]; IF( hCPE->output_mem_fx[1] != NULL ) { - Copy_Scale_sig_32_16( hCPE->output_mem_fx[1], output_mem_fx, NS2SA( sts[n]->output_Fs, 3125000 ), -Q11 ); + Copy_Scale_sig_32_16( hCPE->output_mem_fx[1], output_mem_fx, NS2SA_FX2( sts[n]->output_Fs, 3125000 ), -Q11 ); } ELSE { - set16_fx( output_mem_fx, 0, NS2SA( sts[n]->output_Fs, 3125000 ) ); + set16_fx( output_mem_fx, 0, NS2SA_FX2( sts[n]->output_Fs, 3125000 ) ); } Word16 Q_synth = sub( 15, e_sig[n] ); @@ -461,9 +461,9 @@ ivas_error ivas_mct_dec_fx( #endif /* Save synthesis for HQ FEC */ Word32 output_fx_[L_FRAME48k]; - Copy32( output_fx[( cpe_id * CPE_CHANNELS ) + n], output_fx_, L_FRAME48k ); // Q11 - Scale_sig32( output_fx_, L_FRAME48k, Q16 - Q11 ); // Q11 -> Q16 - Copy_Scale_sig32_16( sts[n]->prev_synth_buffer32_fx, sts[n]->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); // Q11 -> Q0 + Copy32( output_fx[( cpe_id * CPE_CHANNELS ) + n], output_fx_, L_FRAME48k ); // Q11 + Scale_sig32( output_fx_, L_FRAME48k, Q16 - Q11 ); // Q11 -> Q16 + Copy_Scale_sig32_16( sts[n]->prev_synth_buffer32_fx, sts[n]->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -Q11 ); // Q11 -> Q0 sts[n]->q_prev_synth_buffer_fx = 0; move16(); diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 2158dec1c..190cc6b14 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -1361,7 +1361,7 @@ void ivas_mdct_core_reconstruct_fx( /* Update */ Copy( synth_buf_fx + st->L_frame, st->hTcxDec->old_synth, st->hTcxDec->old_synth_len ); - Copy( st->hTcxDec->old_synthFB_fx + st->hTcxDec->L_frameTCX - NS2SA( st->output_Fs, PH_ECU_MEM_NS ), st->hTcxDec->synth_history_fx, NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ); + Copy( st->hTcxDec->old_synthFB_fx + st->hTcxDec->L_frameTCX - NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ), st->hTcxDec->synth_history_fx, NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ); Copy( synth_bufFB_fx + st->hTcxDec->L_frameTCX, st->hTcxDec->old_synthFB_fx, st->hTcxDec->old_synth_lenFB ); st->hTcxDec->q_old_synth = q_syn; st->hTcxDec->q_synth_history_fx = st->hTcxDec->q_old_synth; @@ -1371,7 +1371,7 @@ void ivas_mdct_core_reconstruct_fx( IF( st->hHQ_core != NULL ) { - Copy( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + st->hTcxDec->old_synth_lenFB, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + st->hTcxDec->old_synth_lenFB, NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); } Copy( st->lsp_q_cng, st->old_lsp_q_cng, M ); diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c index dc4a1b01b..853aa365f 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc.c @@ -159,7 +159,7 @@ void ivas_post_proc_fx( ELSE { /*Use channel 0 side info.*/ - tcx_ltp_post32( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem_fx[k], output_q ); + tcx_ltp_post32( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem_fx[k], output_q ); } } } @@ -268,7 +268,7 @@ void stereo_dft_dec_core_switching_fx( IF( ( ( ( st->last_core != ACELP_CORE ) || ( EQ_16( st->prev_bfi, 1 ) && EQ_16( st->last_core, ACELP_CORE ) && EQ_16( st->last_con_tcx, 1 ) ) ) && NE_16( st->last_core, AMR_WB_CORE ) ) || ( sba_dirac_stereo_dtx_flag && EQ_16( st->cng_type, FD_CNG ) ) ) /* TCX / HQ-CORE -> TCX / HQ-CORE */ { /* In case of a TCX to ACELP switch next frame */ - Copy32( &output_fx[st->L_frame - NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ + Copy32( &output_fx[st->L_frame - NS2SA( ( st->L_frame * FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ /* BPF */ test(); @@ -315,8 +315,8 @@ void stereo_dft_dec_core_switching_fx( /* Update FB input buff with hb synth FOR last delay_tdbwe sampled */ FOR( i = 0; i < delay_tdbwe; i++ ) { - hCPE->input_mem_fx[0][( ( NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = - L_add( hCPE->input_mem_fx[0][NS2SA_FX2( L_add( L_sub( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ), delay_tdbwe ), i )], hb_synth_fx[i] ); /*Q11*/ + hCPE->input_mem_fx[0][( ( NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = + L_add( hCPE->input_mem_fx[0][NS2SA( ( ( L_frameTCX * FRAMES_PER_SEC ) - STEREO_DFT32MS_OVL_NS ) + delay_tdbwe, i )], hb_synth_fx[i] ); /*Q11*/ move32(); } } @@ -325,7 +325,7 @@ void stereo_dft_dec_core_switching_fx( /* Update FB input buff with hb synth FOR last delay_tdbwe sampled */ FOR( i = 0; i < delay_tdbwe; i++ ) { - hCPE->input_mem_fx[0][( ( NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = hb_synth_fx[i]; /*Q11*/ + hCPE->input_mem_fx[0][( ( NS2SA_FX2( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = hb_synth_fx[i]; /*Q11*/ move32(); } } @@ -368,7 +368,7 @@ void stereo_dft_dec_core_switching_fx( /* In case of TCX frames, output LB TCX is zeroed out until the end but in case of an TCX->ACELP switch, this memory is needed, hence it is backed up */ /* Unlike the case when DFT32MS is disabled, there is only 1 DFT analysis window, hence in the TCX frame we don't want to do a DFT analysis FOR LB TCX but in a potential ACELP frame, we want the memories of the LB TCX FOR the last OLA samples so that HB analysis can be skipped */ - Copy32( &output_fx[st->L_frame - NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ + Copy32( &output_fx[st->L_frame - NS2SA_FX2( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ /*zero the rest FOR avoiding adding contribution except the last samples which are not considered in DFT analysis (potentially used in next ACELP frame)*/ IF( GT_32( st->last_core_brate, SID_2k40 ) ) @@ -418,8 +418,8 @@ void stereo_dft_dec_core_switching_fx( delay_comp = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); /*Q0*/ move16(); - Copy32( &st->hHQ_core->oldOut_fx[( nZeros - ( delay_comp + NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ - Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ + Copy32( &st->hHQ_core->oldOut_fx[nZeros - ( delay_comp + NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ + Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ Word16 mem_len; mem_len = NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /*Q0*/ @@ -462,11 +462,11 @@ void stereo_dft_dec_core_switching_fx( Word32 delay_dft_dec_lb_inv = (Word32) ( calc_inv / delay_dft_dec_lb ); FOR( i = 0; i < delay_dft_dec_lb; i++ ) { - hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = - Mpy_32_32( hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )], L_shl( i, qdelay_dft_dec_lb ) ); /*Q11 + qdelay_dft_dec_lb -31*/ + hCPE->input_mem_LB_fx[0][( ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = + Mpy_32_32( hCPE->input_mem_LB_fx[0][( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i], L_shl( i, qdelay_dft_dec_lb ) ); /*Q11 + qdelay_dft_dec_lb -31*/ move32(); - hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = - L_shl( Mpy_32_32( hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )], delay_dft_dec_lb_inv ), sub( Q31, qdelay_dft_dec_lb ) ); /*Q11*/ + hCPE->input_mem_LB_fx[0][( ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = + L_shl( Mpy_32_32( hCPE->input_mem_LB_fx[0][( ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )], delay_dft_dec_lb_inv ), sub( Q31, qdelay_dft_dec_lb ) ); /*Q11*/ move32(); } stereo_dft_dec_analyze_fx( hCPE, output_fx, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_LB, 0, 0, q, q_DFT ); diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 94f1affde..417079541 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -223,7 +223,7 @@ ivas_error ivas_sba_dec_reconfigure_fx( } /* determine new granularity */ - granularity_new = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); /*Q0*/ + granularity_new = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); /*Q0*/ move16(); /* this will change anyway only with binaural */ diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 12a34e170..573a9c17f 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -1293,7 +1293,7 @@ void ivas_sba_dirac_stereo_dec_fx( sba_mono_flag = (Word16) EQ_16( st_ivas->hDecoderConfig->nchan_out, 1 ); move16(); - memOffset = NS2SA( L_mult0( output_frame, FRAMES_PER_SEC ), IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); + memOffset = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); move16(); ivas_sba_dirac_stereo_config( hStereoDft->hConfig ); diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 5449521d6..b0100063a 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -289,7 +289,7 @@ void stereo_dft_dec_analyze_fx( move16(); /* Offset FOR the time buffers */ - assert( ( delay >= -NS2SA_FX2( ( input_frame * FRAMES_PER_SEC ), STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA_FX2( ( input_frame * FRAMES_PER_SEC ), STEREO_DFT_OVL_NS ) ) ); + assert( ( delay >= -NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_OVL_NS ) ) ); mem_size = add( delay_dec, delay ); /* Update buffers */ diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx.c index 99cea064b..0db9ab09f 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx.c @@ -61,8 +61,8 @@ void stereo_dft_dmx_out_reset_fx( hStereoDftDmx->prevTargetGain_fx = ONE_IN_Q29; /* Q29 */ move32(); - set32_fx( hStereoDftDmx->memOutHB_fx, 0, NS2SA_FX2( 48000, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoDftDmx->memTransitionHB_fx, 0, NS2SA_FX2( 48000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoDftDmx->memOutHB_fx, 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoDftDmx->memTransitionHB_fx, 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); return; } diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index b76bddbbc..ca4cfdb69 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -99,7 +99,7 @@ void stereo_dft_dec_reset_fx( Word16 i; Word16 j, b; #ifdef MSAN_FIX - set_zero_fx( hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( 16000, STEREO_DFT32MS_OVL_NS ) ); + set_zero_fx( hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ) ); #endif /*Configuration*/ @@ -1360,7 +1360,7 @@ void stereo_dft_dec_res_fx( set32_fx( hCPE->hStereoDft->res_cod_mem_fx, 0, STEREO_DFT_OVL_8k ); hCPE->hStereoDft->q_res_cod_mem_fx = Q16; move16(); - set32_fx( hCPE->input_mem_fx[1], 0, NS2SA_FX2( 8000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hCPE->input_mem_fx[1], 0, NS2SA( 8000, STEREO_DFT32MS_OVL_NS ) ); set16_fx( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec.c index b72e66c5f..08ac60ffc 100644 --- a/lib_dec/ivas_stereo_ica_dec.c +++ b/lib_dec/ivas_stereo_ica_dec.c @@ -126,7 +126,7 @@ void stereo_tca_dec_fx( dsFactor = BASOP_Util_Divide3232_Scale( output_Fs, 8000, &exp_ds ); dsFactor = shr( dsFactor, sub( 15, exp_ds ) ); /* Q0 */ - tempMax = NS2SA( output_Fs, L_NCSHIFT_NS ); /* Q0 */ + tempMax = NS2SA_FX2( output_Fs, L_NCSHIFT_NS ); /* Q0 */ hStereoTCA->corrLagStats = s_min( hStereoTCA->indx_ica_NCShift * dsFactor, tempMax ); /* Q0 */ bothChannelShift = 0; @@ -343,14 +343,14 @@ void stereo_tca_scale_R_channel_fx( return; } /* Scale the Right channel with the gain */ - l_ica_ovl = NS2SA( output_Fs, STEREO_L_TCA_OVLP_NS ); /* Q0 */ + l_ica_ovl = NS2SA_FX2( output_Fs, STEREO_L_TCA_OVLP_NS ); /* Q0 */ move16(); test(); IF( EQ_16( hCPE->nchan_out, 1 ) ) { /* in mono DMX, the scaling is done before synchro_synthesis() */ - flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); /* Q0 */ move16(); test(); @@ -365,18 +365,18 @@ void stereo_tca_scale_R_channel_fx( hCPE->hStereoDftDmx->targetGain_fx = ONE_IN_Q29; /* Q29 */ move32(); - flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ move16(); } } ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ move16(); } ELSE { - flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS ); /* Q0 */ move16(); } diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 6bba90feb..b634d4557 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -339,7 +339,7 @@ void stereo_icBWE_dec_fx( move32(); alpha_fx = add_sat( alpha_fx, winSlope_fx ); /* Q15 */ } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) { synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); // Qsyth - 1 move32(); @@ -766,7 +766,7 @@ void stereo_icBWE_dec_fx( alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) { synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); /* Qsyn - 1 */ move32(); @@ -933,7 +933,7 @@ void stereo_icBWE_dec_fx( } } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) { synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); /* Qsyn - 1 */ move32(); @@ -1015,7 +1015,7 @@ void stereo_icBWE_decproc_fx( output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */ move32(); - memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); /* Q0 */ + memOffset = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); /* Q0 */ /* LRTD stereo mode - 2xBWEs used */ test(); @@ -1070,8 +1070,8 @@ void stereo_icBWE_decproc_fx( set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); } test(); @@ -1123,13 +1123,13 @@ void stereo_icBWE_decproc_fx( Copy32( outputHB[refChanIndx_bwe], temp0_fx + memOffset, sub( output_frame, memOffset ) ); /* Q11 */ Copy32( outputHB[!refChanIndx_bwe], temp1_fx + memOffset, sub( output_frame, memOffset ) ); /* Q11 */ - decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ + decoderDelay = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ test(); IF( last_core != ACELP_CORE && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ - icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); /* Q0 */ + icbweOLASize = NS2SA_FX2( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); /* Q0 */ FOR( i = 0; i < decoderDelay; i++ ) { @@ -1286,15 +1286,15 @@ void stereo_icBWE_decproc_fx( ELSE { /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ - v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); } set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); } } } @@ -1304,13 +1304,13 @@ void stereo_icBWE_decproc_fx( } ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( last_core, ACELP_CORE ) ) { - Word16 delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + Word16 delay_tdbwe = NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ); FOR( n = 0; n < hCPE->nchan_out; n++ ) { FOR( i = 0; i < delay_tdbwe; i++ ) { - output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); + output[n][NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); move32(); } } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 4a788be83..20fa578f8 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -947,7 +947,7 @@ void applyDmxMdctStereo_fx( test(); IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) { - crossfade_len = NS2SA( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); + crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); move16(); SWITCH( hCPE->hCoreCoder[0]->output_Fs ) { @@ -994,7 +994,7 @@ void applyDmxMdctStereo_fx( } ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) ) { - crossfade_len = NS2SA( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */ + crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */ move16(); SWITCH( hCPE->hCoreCoder[0]->output_Fs ) { diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index a8b74c447..c6466183b 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -415,7 +415,7 @@ ivas_error stereo_memory_dec_fx( IF( hCPE->hCoreCoder[0]->last_core != ACELP_CORE ) { - Copy32( hCPE->hStereoDft->buff_LBTCX_mem_fx, hCPE->input_mem_LB_fx[0], NS2SA( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ + Copy32( hCPE->hStereoDft->buff_LBTCX_mem_fx, hCPE->input_mem_LB_fx[0], NS2SA_FX2( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ } } @@ -470,7 +470,7 @@ ivas_error stereo_memory_dec_fx( } /* memory update - needed in TD stereo, TCX/HQ frame -> DFT stereo, ACELP frame switching */ - Copy32( hCPE->input_mem_LB_fx[0], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( s_min( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), 16000 ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ + Copy32( hCPE->input_mem_LB_fx[0], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( s_min( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), 16000 ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ /* allocate ICBWE structure */ IF( hCPE->hStereoICBWE == NULL ) @@ -1034,11 +1034,11 @@ ivas_error stereo_memory_dec_fx( IF( hCPE->prev_synth_chs_fx[1] == NULL ) { st = hCPE->hCoreCoder[1]; - IF( ( hCPE->prev_synth_chs_fx[1] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA( st->output_Fs, FRAME_SIZE_NS ) ) ) == NULL ) + IF( ( hCPE->prev_synth_chs_fx[1] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } - set32_fx( hCPE->prev_synth_chs_fx[1], 0, NS2SA( st->output_Fs, FRAME_SIZE_NS ) ); + set32_fx( hCPE->prev_synth_chs_fx[1], 0, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ) ); } IF( hCPE->hStereoICBWE == NULL && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) @@ -2143,7 +2143,7 @@ void stereo_td2dft_update_fx( /* TCX synthesis (it was already delayed in TD stereo in core_switching_post_dec()) */ IF( sts[n]->hTcxDec != NULL ) { - ovl_TCX = NS2SA_FX2( sts[n]->hTcxDec->L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ); /* Q0 */ + ovl_TCX = NS2SA_FX2( L_mult0( sts[n]->hTcxDec->L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /* Q0 */ move16(); Copy32( synth_fx + sts[n]->hTcxDec->L_frameTCX + hq_delay_comp - ovl_TCX, hCPE->input_mem_fx[n], sub( ovl_TCX, hq_delay_comp ) ); /* Q11 */ Copy32( sts[n]->delay_buf_out32_fx, hCPE->input_mem_fx[n] + ovl_TCX - hq_delay_comp, hq_delay_comp ); /* Q11 */ @@ -2161,7 +2161,7 @@ void stereo_td2dft_update_fx( /* TCX synthesis (it was already delayed in TD stereo in core_switching_post_dec()) */ IF( sts[n]->hTcxDec != NULL ) { - ovl_TCX = NS2SA_FX2( sts[n]->hTcxDec->L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ); /* Q0 */ + ovl_TCX = NS2SA_FX2( L_mult0( sts[n]->hTcxDec->L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /* Q0 */ move16(); Copy32( synth_fx + add( sts[n]->hTcxDec->L_frameTCX, sub( hq_delay_comp, ovl_TCX ) ), hCPE->input_mem_fx[n], sub( ovl_TCX, hq_delay_comp ) ); /* Q11 */ Copy32( sts[n]->delay_buf_out32_fx, hCPE->input_mem_fx[n] + sub( ovl_TCX, hq_delay_comp ), hq_delay_comp ); /* Q11 */ diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec.c index d296e3f33..c975da8d6 100644 --- a/lib_dec/ivas_stereo_td_dec.c +++ b/lib_dec/ivas_stereo_td_dec.c @@ -680,17 +680,17 @@ void stereo_tdm_combine_fx( output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */ move32(); - tdm_n_OVA = NS2SA( output_Fs, TDM_L_NOVA_NS ); /* Q0 */ + tdm_n_OVA = NS2SA_FX2( output_Fs, TDM_L_NOVA_NS ); /* Q0 */ move16(); IF( flag_HB ) { - upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ); /* Q0 */ + upmixing_delay = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ); /* Q0 */ move16(); } ELSE { - upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS ); /* Q0 */ + upmixing_delay = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS ); /* Q0 */ move16(); } @@ -845,7 +845,7 @@ void stereo_tdm_combine_fx( } incr_fx = Mpy_32_32( L_sub( ONE_IN_Q29, fac_fx ), step ); /* Q29 */ - FOR( i = 0; i < NS2SA( output_Fs, ACELP_LOOK_NS ); i++ ) + FOR( i = 0; i < NS2SA_FX2( output_Fs, ACELP_LOOK_NS ); i++ ) { PCh_2_L_fx[i] = L_shl_sat( Mpy_32_32( PCh_2_L_fx[i], fac_fx ), 2 ); /* Qx */ move32(); diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c index 68272a79f..6b80108a8 100644 --- a/lib_dec/swb_bwe_dec.c +++ b/lib_dec/swb_bwe_dec.c @@ -654,7 +654,7 @@ void fd_bwe_dec_init_fx( ) { set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); hBWE_FD->prev_mode = NORMAL; move16(); hBWE_FD->prev_Energy_fx = 0; diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 7a6abb790..9552bbf2f 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -1223,7 +1223,7 @@ void fd_bwe_dec_init( { hBWE_FD->old_wtda_wb_fx_exp = 0; move16(); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); hBWE_FD->old_wtda_swb_fx_exp = 0; move16(); diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index d5bbfab29..d7dd47256 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -455,7 +455,7 @@ void amr_wb_enc_fx( IF( EQ_32( st->input_Fs, 16000 ) ) { /* no resampling needed, only delay adjustement to account for the FIR resampling delay */ - tmps = NS2SA_FX2( 16000, DELAY_FIR_RESAMPL_NS ); + tmps = NS2SA( 16000, DELAY_FIR_RESAMPL_NS ); Copy_Scale_sig( &st->mem_decim16k_fx[tmps], new_inp_16k, tmps, -1 ); /* Input in Q0 -> Output in Q-1 to mimic the resampling filter */ Copy_Scale_sig( st->input_fx, new_inp_16k + tmps, sub( input_frame, tmps ), -1 ); /* Input in Q0 -> Output in Q-1 to mimic the resampling filter */ Copy( st->input_fx + input_frame - shl( tmps, 1 ), st->mem_decim16k_fx, shl( tmps, 1 ) ); /* memory still in Q0 */ diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index f6b5b5984..1f5b0df1e 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -526,7 +526,7 @@ void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Wor st->new_speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc + st->encoderLookahead_enc; st->new_speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc + st->encoderLookahead_enc; hTcxEnc->new_speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc + st->encoderLookahead_enc; - hTcxEnc->new_speech_TCX = st->input_buff_fx + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) - NS2SA( st->input_Fs, DELAY_FIR_RESAMPL_NS ); + hTcxEnc->new_speech_TCX = st->input_buff_fx + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) - NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); st->speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc; st->speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc; diff --git a/lib_enc/core_switching_enc_fx.c b/lib_enc/core_switching_enc_fx.c index 07468363f..da1139d15 100644 --- a/lib_enc/core_switching_enc_fx.c +++ b/lib_enc/core_switching_enc_fx.c @@ -430,8 +430,8 @@ void core_switching_post_enc_fx( test(); IF( ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) && EQ_16( st_fx->element_mode, EVS_MONO ) ) /* core switching ==> CELP subframe encoding */ { - acelp_core_switch_enc_fx( st_fx, old_inp_12k8 + L_INP_MEM - NS2SA_FX2( INT_FS_FX, ACELP_LOOK_NS ), - old_inp_16k + L_INP_MEM - NS2SA_FX2( INT_FS_16k, ACELP_LOOK_NS ), A, Qshift, Q_new ); + acelp_core_switch_enc_fx( st_fx, old_inp_12k8 + L_INP_MEM - NS2SA( INT_FS_FX, ACELP_LOOK_NS ), + old_inp_16k + L_INP_MEM - NS2SA( INT_FS_16k, ACELP_LOOK_NS ), A, Qshift, Q_new ); } hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index d5be64f77..93a954ae8 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1531,7 +1531,7 @@ void generate_comfort_noise_enc_fx( Encoder_State *stcod, { FOR( i = 0; i < st->frameSize; i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); move16(); } } @@ -1917,7 +1917,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, { FOR( i = 0; i < st->frameSize; i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); move16(); } } diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c index a3a75cc95..24579e74e 100644 --- a/lib_enc/hq_core_enc.c +++ b/lib_enc/hq_core_enc.c @@ -323,7 +323,7 @@ void hq_core_enc_ivas_fx( overlap = st->hTcxCfg->tcx_mdct_window_length; /* Q0 */ move16(); - nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS ); + nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS ); move16(); L_frame = sub( st->L_frame + st->hTcxCfg->tcx_offset, st->hTcxCfg->lfacNext ); tcx_offset = st->hTcxCfg->lfacNext; diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 8448843dc..1d4964ab8 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -429,7 +429,7 @@ ivas_error init_encoder_ivas_fx( IF( st->element_mode == EVS_MONO ) { st->input32_fx = st->input_buff32_fx + st->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); - st->input_fx = st->input_buff_fx + add( frame_length, (Word16) NS2SA( st->input_Fs, DELAY_FIR_RESAMPL_NS ) ); + st->input_fx = st->input_buff_fx + add( frame_length, (Word16) NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ) ); } ELSE { diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 89bbdc898..58706279e 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -71,7 +71,7 @@ ivas_error init_encoder_fx( st_fx->old_input_signal_fx = st_fx->input_buff_fx; IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { - st_fx->input_fx = st_fx->input_buff_fx + st_fx->input_Fs / FRAMES_PER_SEC + NS2SA( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); + st_fx->input_fx = st_fx->input_buff_fx + st_fx->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); } ELSE { diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 96a3e110f..718a09026 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -533,7 +533,7 @@ ivas_error pre_proc_ivas_fx( sr_core_tmp = L_max( INT_FS_16k, st->sr_core ); } - L_look = NS2SA( sr_core_tmp, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) Q0*/ + L_look = NS2SA_FX2( sr_core_tmp, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) Q0*/ move16(); inp_16k_fx = old_inp_16k_fx + L_INP_MEM - L_look; @@ -747,7 +747,7 @@ ivas_error ivas_compute_core_buffers_fx( { lMemRecalc_16k = NS2SA( INT_FS_16k, L_MEM_RECALC_NS ); move16(); - lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS ); + lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ); move16(); } @@ -765,7 +765,7 @@ ivas_error ivas_compute_core_buffers_fx( L_frame_tmp = s_max( L_FRAME16k, st->L_frame ); } - L_look = NS2SA( sr_core, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) */ + L_look = NS2SA_FX2( sr_core, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) */ move16(); new_inp_16k_fx = old_inp_16k_fx + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ @@ -775,7 +775,7 @@ ivas_error ivas_compute_core_buffers_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_SCE ) ) { - new_inp_16k_fx -= NS2SA( sr_core, DELAY_FIR_RESAMPL_NS ); + new_inp_16k_fx -= NS2SA_FX2( sr_core, DELAY_FIR_RESAMPL_NS ); } IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) @@ -814,8 +814,8 @@ ivas_error ivas_compute_core_buffers_fx( Copy( st->mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ - Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) @@ -840,7 +840,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 length_16k = NS2SA_FX2( INT_FS_16k, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); move16(); - Copy( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ + Copy( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_16k_fx - lMemRecalc_16k - length_16k, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ Scale_sig( new_inp_16k_fx - lMemRecalc_16k - length_16k, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } @@ -851,19 +851,19 @@ ivas_error ivas_compute_core_buffers_fx( IF( lMemRecalc > 0 ) { - size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc + input_frame, lMemRecalc, input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ - Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc + input_frame, lMemRecalc, input_Fs, new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ - Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } } ELSE IF( st->idchan == 0 ) { /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ + Copy( signal_in_fx + input_frame - NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ } /*------------------------------------------------* diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index b7a10a4f3..7bb67cbbd 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -432,7 +432,7 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { lMemRecalc = NS2SA_FX2( st->input_Fs, L_MEM_RECALC_NS ); - lMemRecalc_12k8 = NS2SA_FX2( INT_FS_12k8, L_MEM_RECALC_NS ); + lMemRecalc_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_NS ); } input_Fs = st->input_Fs; /* Q0 */ @@ -575,7 +575,7 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( st->idchan, 1 ) ) { Word16 length_inp = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS ); - Word16 length_12k8 = NS2SA_FX2( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); + Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ @@ -597,7 +597,7 @@ ivas_error pre_proc_front_ivas_fx( ELSE /* DFT stereo */ { /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* hSCE->hCoreCoder[n]->q_inp */ + Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* hSCE->hCoreCoder[n]->q_inp */ } Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( -1, sub( 15, st->exp_buf_speech_enc ) ) ); /* Q(-1) */ @@ -678,7 +678,7 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( st->idchan, 1 ) ) { - Word16 length_12k8 = NS2SA_FX2( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); + Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); move16(); // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, sig_out, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx ); diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index b1d819f5c..1b4d5da4a 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -86,7 +86,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( move16(); IF( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) ) { - len_inp_memory = add( len_inp_memory, NS2SA( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ) ); /* Q0 */ + len_inp_memory = add( len_inp_memory, NS2SA_FX2( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ) ); /* Q0 */ } nchan_transport_old_real = nchan_transport_old; /* Q0 */ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 3635ab04a..8f9a0edf6 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -873,7 +873,7 @@ ivas_error ivas_cpe_enc_fx( Word16 input_norm, q_inp32, common_q, fir_delay_len; input_norm = L_norm_arr( sts[0]->input32_fx + out_start_ind, sub( out_end_ind, out_start_ind ) ); q_inp32 = add( Q15, input_norm ); - fir_delay_len = NS2SA( sts[0]->input_Fs, DELAY_FIR_RESAMPL_NS ); + fir_delay_len = NS2SA_FX2( sts[0]->input_Fs, DELAY_FIR_RESAMPL_NS ); move16(); // Find common Q-factor between { q_inp, q_old_inp and q_inp32-16 } @@ -1408,12 +1408,12 @@ ivas_error create_cpe_enc_fx( test(); IF( EQ_16( ivas_format, STEREO_FORMAT ) || EQ_16( ivas_format, MASA_FORMAT ) || ( EQ_16( ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { - IF( ( hCPE->input_mem_fx[n] = (Word16 *) malloc( sizeof( Word16 ) * NS2SA( input_Fs, STEREO_DFT_OVL_NS ) ) ) == NULL ) + IF( ( hCPE->input_mem_fx[n] = (Word16 *) malloc( sizeof( Word16 ) * NS2SA_FX2( input_Fs, STEREO_DFT_OVL_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } - set16_zero_fx( hCPE->input_mem_fx[n], NS2SA( input_Fs, STEREO_DFT_OVL_NS ) ); + set16_zero_fx( hCPE->input_mem_fx[n], NS2SA_FX2( input_Fs, STEREO_DFT_OVL_NS ) ); } ELSE { diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 5460ccb12..3844598c6 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -417,7 +417,7 @@ ivas_error front_vad_create_fx( move16(); /* allocate delay buffer to compensate for filterbank delay */ - hFrontVad->delay_samples = NS2SA( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); + hFrontVad->delay_samples = NS2SA_FX2( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); move16(); hFrontVad->delay_buf_fx = NULL; IF( GT_16( hFrontVad->delay_samples, 0 ) ) diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc.c index 8ccb59c9c..fee34abd8 100644 --- a/lib_enc/ivas_lfe_enc.c +++ b/lib_enc/ivas_lfe_enc.c @@ -538,12 +538,12 @@ ivas_error ivas_create_lfe_enc_fx( * Input memory buffer: allocate and initialize *-----------------------------------------------------------------*/ - IF( ( hLFE->old_wtda_audio_fx = (Word32 *) malloc( sizeof( hLFE->old_wtda_audio_fx[0] ) * NS2SA( input_Fs, IVAS_LFE_FADE_NS ) ) ) == NULL ) + IF( ( hLFE->old_wtda_audio_fx = (Word32 *) malloc( sizeof( hLFE->old_wtda_audio_fx[0] ) * NS2SA_FX2( input_Fs, IVAS_LFE_FADE_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE memory\n" ) ); } - set32_fx( hLFE->old_wtda_audio_fx, 0, NS2SA( input_Fs, IVAS_LFE_FADE_NS ) ); + set32_fx( hLFE->old_wtda_audio_fx, 0, NS2SA_FX2( input_Fs, IVAS_LFE_FADE_NS ) ); hLFE->q_old_wtda_audio = 31; move16(); diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index c94946b2d..392f1d9ab 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -201,8 +201,8 @@ ivas_error ivas_mc_paramupmix_enc_open_fx( /* assuming parameters are calculated at end of frame, compensate for MCT delay and half of decoder fb */ /* still 1.5ms off, since MCT delay is not large enough */ /* param at end of frame */ - fb_cfg->prior_input_length = (int16_t) ( NS2SA( input_Fs, 12000000L ) + NS2SA( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA( input_Fs, DELAY_FB_1_NS / 2 ) ); - fb_cfg->prior_input_length = (int16_t) max( fb_cfg->prior_input_length, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + fb_cfg->prior_input_length = (Word16) ( NS2SA_FX2( input_Fs, 12000000L ) + NS2SA_FX2( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA_FX2( input_Fs, DELAY_FB_1_NS / 2 ) ); + fb_cfg->prior_input_length = (Word16) max( fb_cfg->prior_input_length, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Allocate and initialize FB mixer handle */ IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMCParamUpmix->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 3687df381..b3f99e27c 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -200,22 +200,22 @@ ivas_error ivas_mcmasa_enc_open_fx( } /* initialize delay compensation */ - hMcMasa->num_samples_delay_comp = NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); + hMcMasa->num_samples_delay_comp = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); move16(); #ifdef DISABLE_DIRAC_DELAY_COMP hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */ #endif - tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ) ); + tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ); hMcMasa->num_slots_delay_comp = tmp_f; move16(); - IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) ) + IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) ) { hMcMasa->num_slots_delay_comp = add( hMcMasa->num_slots_delay_comp, 1 ); move16(); hMcMasa->offset_comp = negate( hMcMasa->num_samples_delay_comp ); move16(); - hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ); + hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ); move16(); hMcMasa->offset_comp = add( hMcMasa->offset_comp, hMcMasa->num_samples_delay_comp ); move16(); @@ -241,17 +241,17 @@ ivas_error ivas_mcmasa_enc_open_fx( IF( hMcMasa->separateChannelEnabled ) { /* TD Energy calculation with LP */ - IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) + IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); - IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) + IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); hMcMasa->hFbMixerLfe = NULL; } ELSE diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index ab8252854..5eee0975a 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -114,7 +114,7 @@ ivas_error ivas_osba_enc_open_fx( { set_val_Word32( hOSba->prev_object_dm_gains_fx[i], INV_SQRT_2_Q30, MAX_INPUT_CHANNELS ); } - len = NS2SA( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); + len = NS2SA_FX2( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); move16(); FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) { @@ -421,7 +421,7 @@ void ivas_osba_enc_fx( Word16 Q_out = *q_data; move16(); Word16 n, delay_s; - delay_s = NS2SA( input_Fs, IVAS_FB_ENC_DELAY_NS ); + delay_s = NS2SA_FX2( input_Fs, IVAS_FB_ENC_DELAY_NS ); IF( ism_mode == ISM_MODE_NONE ) { /*keep the delay buffer up to date*/ diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 72876ae35..e0a8a8ed4 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -112,7 +112,7 @@ static void tcaTargetCh_LA_fx( target = ptrChanL; } - tempS = NS2SA( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS ); + tempS = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS ); tempF1 = 0; move32(); tempF1_exp = 0; @@ -1512,7 +1512,7 @@ static void icaMemUpdate_fx( IF( hCPE->hStereoICBWE != NULL ) { assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS ); - i = NS2SA( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS ); + i = NS2SA_FX2( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS ); Copy_Scale_sig_32_16( bufChanL + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], i, -Q16 ); /* q_com-16 */ Copy_Scale_sig_32_16( bufChanR + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], i, -Q16 ); /* q_com-16 */ hCPE->hStereoICBWE->q_dataChan_fx = sub( q_com, Q16 ); @@ -1580,9 +1580,9 @@ void stereo_tca_enc_fx( q_com = sts[0]->q_inp32; move16(); - lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS ); + lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ); move16(); - lMemRecalc_SCh = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS ); + lMemRecalc_SCh = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS ); move16(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) @@ -2081,7 +2081,7 @@ void stereo_tca_enc_fx( { /* Scale the Right channel with the gain */ Word16 j; - Word16 l_ica_ovl = NS2SA( input_Fs, STEREO_L_TCA_OVLP_NS ); + Word16 l_ica_ovl = NS2SA_FX2( input_Fs, STEREO_L_TCA_OVLP_NS ); Word16 winSlope = div_s( 1, l_ica_ovl ); // Q15 diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index 786c45cb3..190adbf1c 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -822,7 +822,7 @@ void stereo_switching_enc_fx( offset = sub( sts[0]->cldfbAnaEnc->p_filter_length, sts[0]->cldfbAnaEnc->no_channels ); /* Q0 */ FOR( i = 0; i < offset; i++ ) { - sts[0]->cldfbAnaEnc->cldfb_state_fx[i] = L_deposit_h( old_input_signal_pri[input_frame - offset - NS2SA( input_frame * FRAMES_PER_SEC, L_MEM_RECALC_TBE_NS ) + i] ); /* Q16+q_inp */ + sts[0]->cldfbAnaEnc->cldfb_state_fx[i] = L_deposit_h( old_input_signal_pri[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ); /* Q16+q_inp */ move32(); } sts[0]->cldfbAnaEnc->Q_cldfb_state = add( Q16, q_inp ); @@ -844,7 +844,7 @@ void stereo_switching_enc_fx( test(); IF( hCPE->hStereoTD != NULL && EQ_16( hCPE->hStereoTD->tdm_last_ratio_idx, LRTD_STEREO_LEFT_IS_PRIM ) ) { - v_multc_fixed_32_16( hCPE->hCoreCoder[1]->old_input_signal_fx + sub( input_frame, add( offset, NS2SA( input_frame * FRAMES_PER_SEC, L_MEM_RECALC_TBE_NS ) ) ), -MAX_32, sts[1]->cldfbAnaEnc->cldfb_state_fx, offset ); /* Q16+q_inp */ + v_multc_fixed_32_16( hCPE->hCoreCoder[1]->old_input_signal_fx + sub( input_frame, add( offset, NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) ) ), -MAX_32, sts[1]->cldfbAnaEnc->cldfb_state_fx, offset ); /* Q16+q_inp */ sts[1]->cldfbAnaEnc->Q_cldfb_state = add( Q16, q_inp ); move16(); } @@ -852,7 +852,7 @@ void stereo_switching_enc_fx( { FOR( i = 0; i < offset; i++ ) { - sts[1]->cldfbAnaEnc->cldfb_state_fx[i] = L_shr( L_deposit_h( hCPE->hCoreCoder[1]->old_input_signal_fx[input_frame - offset - NS2SA( input_frame * FRAMES_PER_SEC, L_MEM_RECALC_TBE_NS ) + i] ), 5 ); /* Q11+q_inp */ + sts[1]->cldfbAnaEnc->cldfb_state_fx[i] = L_shr( L_deposit_h( hCPE->hCoreCoder[1]->old_input_signal_fx[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ), 5 ); /* Q11+q_inp */ move32(); } sts[1]->cldfbAnaEnc->Q_cldfb_state = add( Q16 - 5, q_inp ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 6035687ed..b4ca63bac 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1451,7 +1451,7 @@ ivas_error IVAS_ENC_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *delay = NS2SA( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); + *delay = NS2SA_FX2( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); move16(); *delay = imult1616( *delay, hEncoderConfig->nchan_inp ); diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index c7d99cc69..01ac8383f 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -225,8 +225,8 @@ void wb_bwe_enc_ivas_fx( /*---------------------------------------------------------------------* * Delay the original input signal to be synchronized with ACELP core synthesis *---------------------------------------------------------------------*/ - set16_fx( old_input_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + set16_fx( old_input_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); move16(); new_input_fx = old_input_fx + Sample_Delay_WB_BWE; @@ -351,21 +351,21 @@ void swb_bwe_enc_ivas_fx( move32(); } - set16_fx( old_input_fx, 0, add( NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); + set16_fx( old_input_fx, 0, add( NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); - Sample_Delay_HP = NS2SA_FX2( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - Sample_Delay_HP = NS2SA_FX2( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); } - Sample_Delay_LP = NS2SA_FX2( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); IF( st_fx->element_mode > EVS_MONO ) { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) @@ -381,15 +381,15 @@ void swb_bwe_enc_ivas_fx( ELSE { Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); - Sample_Delay_HP = NS2SA_FX2( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - Sample_Delay_HP = NS2SA_FX2( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); } - Sample_Delay_LP = NS2SA_FX2( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); + Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); IF( st_fx->element_mode > EVS_MONO ) { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) @@ -677,11 +677,11 @@ void swb_bwe_enc_fx( move32(); } - set16_fx( old_input_fx, 0, add( NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); + set16_fx( old_input_fx, 0, add( NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { - Sample_Delay_SWB_BWE = NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); @@ -689,7 +689,7 @@ void swb_bwe_enc_fx( } ELSE { - Sample_Delay_SWB_BWE = NS2SA( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 3e9c07c23..3bad5fa7f 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -81,7 +81,7 @@ void wb_pre_proc_fx( move16(); } - set16_fx( old_input, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); + set16_fx( old_input, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); max_wb = 1; move16(); @@ -161,7 +161,7 @@ void wb_pre_proc_fx( test(); IF( ( NE_16( st_fx->extl, WB_BWE ) || ( EQ_16( st_fx->extl, WB_BWE ) && LE_32( st_fx->total_brate, ACELP_8k00 ) ) ) && !hSC_VBR->ppp_mode ) { - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); Copy( new_inp_resamp16k, &old_input[Sample_Delay_WB_BWE], L_FRAME16k ); Copy( hBWE_FD->old_input_wb_fx, old_input, Sample_Delay_WB_BWE ); @@ -257,7 +257,7 @@ void wb_pre_proc_ivas_fx( move16(); } - set16_fx( old_input, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + STEREO_DFT_OVL_16k + L_FRAME16k ); + set16_fx( old_input, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + STEREO_DFT_OVL_16k + L_FRAME16k ); max_wb = 1; move16(); @@ -311,7 +311,7 @@ void wb_pre_proc_ivas_fx( hb_speech and the two decimator memories are in Q_wb_sp */ IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); IF( EQ_16( last_element_mode, IVAS_CPE_TD ) ) { @@ -347,7 +347,7 @@ void wb_pre_proc_ivas_fx( move16(); Word16 l_recalc_4k = ( L_MEM_RECALC_16K + L_FILT16k + 1 ) / 4; move16(); - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); IF( EQ_16( last_element_mode, IVAS_CPE_DFT ) ) { @@ -391,7 +391,7 @@ void wb_pre_proc_ivas_fx( Word16 l_recalc_16k = L_FILT16k + 1; /* Note: "+1" is used because L_FILT16k is not divisible by 4 */ Word16 l_recalc_4k = ( L_FILT16k + 1 ) / 4; - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); /*Get past signal*/ Copy_Scale_sig( hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - l_recalc_16k, old_input, l_recalc_16k, Q_wb_sp ); @@ -454,7 +454,7 @@ void wb_pre_proc_ivas_fx( test(); IF( ( NE_16( st_fx->extl, WB_BWE ) || ( EQ_16( st_fx->extl, WB_BWE ) && EQ_32( st_fx->total_brate, 0 ) ) ) && !ppp_mode ) { - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); Copy( new_inp_resamp16k, &old_input[Sample_Delay_WB_BWE], L_FRAME16k ); Copy( hBWE_FD->old_input_wb_fx, old_input, Sample_Delay_WB_BWE ); @@ -540,7 +540,7 @@ void swb_pre_proc_fx( imagBufferFlipped[j] = imagBufferTmp[j]; } - set16_fx( old_input_fx, 0, NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); + set16_fx( old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); IF( EQ_32( st_fx->input_Fs, 32000 ) ) { @@ -549,7 +549,7 @@ void swb_pre_proc_fx( test(); IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) ) { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); Copy( hBWE_FD->old_fdbwe_speech_fx, &old_input_fx[Sample_Delay_SWB_BWE], L_FRAME32k ); set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); Copy( hBWE_FD->old_fdbwe_speech_fx + L_FRAME32k - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); @@ -756,9 +756,9 @@ void swb_pre_proc_fx( /* Reset CLDFB synthesis buffer */ set16_fx( st_fx->cldfbSynTd->FilterStates, 0, st_fx->cldfbSynTd->p_filter_length + st_fx->cldfbSynTd->no_channels * st_fx->cldfbSynTd->no_col ); } - IF( st_fx->last_extl == -1 ) + IF( EQ_16( st_fx->last_extl, -1 ) ) { - delay = NS2SA( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); + delay = NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); FOR( i = 0; i < delay; i++ ) { shb_speech_fx[i] = mult_r( mult_r( i, 983 /*0.03f Q15*/ ), shb_speech_fx[2 * delay - 1 - i] ); @@ -813,7 +813,7 @@ void swb_pre_proc_ivas_fx( Word16 Sample_Delay_SWB_BWE32k, lMemRecalc32k, dft_ovl32k; Word32 one_by_50_Q31 = 42949673; - lMemRecalc32k = NS2SA_FX2( 32000, L_MEM_RECALC_NS ); + lMemRecalc32k = NS2SA( 32000, L_MEM_RECALC_NS ); move16(); // exp_lbEner move16(); // lMemRecalc32k move32(); // one_by_50_Q31 @@ -831,16 +831,16 @@ void swb_pre_proc_ivas_fx( imagBufferFlipped[j] = imagBufferTmp[j]; } - set16_fx( old_input_fx, 0, NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); + set16_fx( old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); IF( EQ_32( st->input_Fs, 32000 ) ) { IF( st->element_mode > EVS_MONO ) { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS ); IF( EQ_16( st->L_frame, L_FRAME16k ) ) { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_16k_NS ); + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_16k_NS ); } Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); @@ -864,15 +864,15 @@ void swb_pre_proc_ivas_fx( test(); IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) && NE_16( st->extl, SWB_BWE_HIGHRATE ) ) { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); test(); IF( st->element_mode > EVS_MONO && EQ_16( st->L_frame, L_FRAME16k ) ) { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); } IF( st->element_mode > EVS_MONO ) { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( 32000, DELAY_FIR_RESAMPL_NS ) ); + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA( 32000, DELAY_FIR_RESAMPL_NS ) ); } Copy( hBWE_FD->old_fdbwe_speech_fx, &old_input_fx[Sample_Delay_SWB_BWE], L_FRAME32k ); @@ -894,15 +894,15 @@ void swb_pre_proc_ivas_fx( ELSE /* 48 kHz */ { - Sample_Delay_SWB_BWE32k = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_SWB_BWE32k = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS ); move16(); - Sample_Delay_SWB_BWE = NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_SWB_BWE = NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS ); move16(); IF( EQ_16( st->L_frame, L_FRAME16k ) ) { - Sample_Delay_SWB_BWE32k = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_16k_NS ); + Sample_Delay_SWB_BWE32k = NS2SA( 32000, DELAY_FD_BWE_ENC_16k_NS ); move16(); - Sample_Delay_SWB_BWE = NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_16k_NS ); + Sample_Delay_SWB_BWE = NS2SA( 48000, DELAY_FD_BWE_ENC_16k_NS ); move16(); } diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 7422a5a15..a5e4e902b 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); - Sample_Delay_HP = NS2SA_FX2( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; + Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) { @@ -7468,16 +7468,16 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->L_frame, L_FRAME ) ) { - Sample_Delay_HP = NS2SA_FX2( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ) - L_FRAME48k / 2; + Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ) - L_FRAME48k / 2; } ELSE { - Sample_Delay_HP = NS2SA_FX2( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ) - L_FRAME48k / 2; + Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ) - L_FRAME48k / 2; } } ELSE { - Sample_Delay_HP = NS2SA_FX2( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; + Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; } IF( NE_16( st->last_extl, FB_TBE ) ) -- GitLab From f8098d80f2d9eb69dfb23381d4aec58ab747d4d7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 10:40:10 +0530 Subject: [PATCH 0294/1221] Files cleanup in lib_enc --- Workspace_msvc/lib_enc.vcxproj | 66 -- Workspace_msvc/lib_enc.vcxproj.filters | 198 ---- lib_enc/ari_enc.c | 316 ------ lib_enc/ari_enc_fx.c | 223 +++++ lib_enc/ari_hm_enc.c | 53 -- lib_enc/arith_coder_enc.c | 51 - lib_enc/avq_cod.c | 42 - lib_enc/bass_psfilter_enc.c | 42 - lib_enc/bw_detect.c | 64 -- lib_enc/cng_enc.c | 429 --------- lib_enc/cng_enc_fx.c | 374 ++++++++ lib_enc/cod2t32.c | 41 - lib_enc/cod4t64.c | 48 - lib_enc/cod_ace.c | 42 - lib_enc/cod_tcx.c | 869 ----------------- lib_enc/cod_tcx_fx.c | 721 ++++++++++++++ lib_enc/cod_uv.c | 40 - lib_enc/comvad_decision.c | 41 - lib_enc/cor_shif.c | 41 - lib_enc/core_enc_2div.c | 42 - lib_enc/core_enc_init.c | 1055 -------------------- lib_enc/core_enc_init_fx.c | 1004 ++++++++++++++++++++ lib_enc/core_enc_ol.c | 46 - lib_enc/core_enc_reconf.c | 346 ------- lib_enc/core_enc_reconf_fx.c | 304 ++++++ lib_enc/core_enc_switch.c | 302 ------ lib_enc/core_enc_switch_fx.c | 259 +++++ lib_enc/core_enc_updt.c | 117 --- lib_enc/core_enc_updt_fx.c | 74 ++ lib_enc/core_switching_enc.c | 603 ------------ lib_enc/core_switching_enc_fx.c | 561 ++++++++++- lib_enc/corr_xh.c | 41 - lib_enc/decision_matrix_enc.c | 45 - lib_enc/detect_transient.c | 42 - lib_enc/diffcod.c | 149 --- lib_enc/dtx.c | 45 - lib_enc/enc_acelp.c | 91 -- lib_enc/enc_acelp_tcx_main.c | 41 - lib_enc/enc_acelpx.c | 42 - lib_enc/enc_amr_wb.c | 42 - lib_enc/enc_gain.c | 43 - lib_enc/enc_gen_voic.c | 42 - lib_enc/enc_prm.c | 231 ----- lib_enc/enc_prm_fx.c | 189 +++- lib_enc/fd_cng_enc.c | 1172 ----------------------- lib_enc/fd_cng_enc_fx.c | 1100 +++++++++++++++++++++ lib_enc/find_tilt.c | 303 ------ lib_enc/find_tilt_fx.c | 252 +++++ lib_enc/find_uv.c | 660 ------------- lib_enc/find_uv_fx.c | 539 +++++++++++ lib_enc/find_wsp.c | 98 -- lib_enc/find_wsp_fx.c | 59 +- lib_enc/frame_spec_dif_cor_rate.c | 47 - lib_enc/gain_enc.c | 55 -- lib_enc/gs_enc.c | 56 -- lib_enc/guided_plc_enc.c | 42 - lib_enc/hf_cod_amrwb.c | 43 - lib_enc/hq_classifier_enc.c | 52 - lib_enc/hq_core_enc.c | 410 -------- lib_enc/hq_core_enc_fx.c | 359 +++++++ lib_enc/hq_env_enc.c | 42 - lib_enc/hq_hr_enc.c | 280 ------ lib_enc/hq_hr_enc_fx.c | 236 ++++- lib_enc/hq_lr_enc.c | 46 - lib_enc/hvq_enc.c | 44 - lib_enc/init_enc.c | 1215 ------------------------ lib_enc/init_enc_fx.c | 1170 +++++++++++++++++++++++ lib_enc/inov_enc.c | 49 - lib_enc/isf_enc_amr_wb.c | 43 - lib_enc/ivas_entropy_coder.c | 3 +- lib_enc/lead_indexing.c | 208 ---- lib_enc/long_enr.c | 47 - lib_enc/lp_exc_e.c | 42 - lib_enc/lsf_enc.c | 49 - lib_enc/ltd_stable.c | 41 - lib_enc/mdct_classifier.c | 43 - lib_enc/mdct_selector.c | 44 - lib_enc/mslvq_enc.c | 308 ------ lib_enc/mslvq_enc_fx.c | 177 ++++ lib_enc/multi_harm.c | 42 - lib_enc/nelp_enc.c | 43 - lib_enc/pit_enc.c | 45 - lib_enc/pitch_ol.c | 48 - lib_enc/pitch_ol2.c | 274 ------ lib_enc/pitch_ol2_fx.c | 224 +++++ lib_enc/plc_enc_ext.c | 43 - lib_enc/setmodeindex.c | 97 -- lib_enc/setmodeindex_fx.c | 45 + 88 files changed, 7865 insertions(+), 11787 deletions(-) delete mode 100644 lib_enc/ari_enc.c delete mode 100644 lib_enc/ari_hm_enc.c delete mode 100644 lib_enc/arith_coder_enc.c delete mode 100644 lib_enc/avq_cod.c delete mode 100644 lib_enc/bass_psfilter_enc.c delete mode 100644 lib_enc/bw_detect.c delete mode 100644 lib_enc/cng_enc.c delete mode 100644 lib_enc/cod2t32.c delete mode 100644 lib_enc/cod4t64.c delete mode 100644 lib_enc/cod_ace.c delete mode 100644 lib_enc/cod_tcx.c delete mode 100644 lib_enc/cod_uv.c delete mode 100644 lib_enc/comvad_decision.c delete mode 100644 lib_enc/cor_shif.c delete mode 100644 lib_enc/core_enc_2div.c delete mode 100644 lib_enc/core_enc_init.c delete mode 100644 lib_enc/core_enc_ol.c delete mode 100644 lib_enc/core_enc_reconf.c delete mode 100644 lib_enc/core_enc_switch.c delete mode 100644 lib_enc/core_enc_updt.c delete mode 100644 lib_enc/core_switching_enc.c delete mode 100644 lib_enc/corr_xh.c delete mode 100644 lib_enc/decision_matrix_enc.c delete mode 100644 lib_enc/detect_transient.c delete mode 100644 lib_enc/diffcod.c delete mode 100644 lib_enc/dtx.c delete mode 100644 lib_enc/enc_acelp.c delete mode 100644 lib_enc/enc_acelp_tcx_main.c delete mode 100644 lib_enc/enc_acelpx.c delete mode 100644 lib_enc/enc_amr_wb.c delete mode 100644 lib_enc/enc_gain.c delete mode 100644 lib_enc/enc_gen_voic.c delete mode 100644 lib_enc/enc_prm.c delete mode 100644 lib_enc/fd_cng_enc.c delete mode 100644 lib_enc/find_tilt.c delete mode 100644 lib_enc/find_uv.c delete mode 100644 lib_enc/find_wsp.c delete mode 100644 lib_enc/frame_spec_dif_cor_rate.c delete mode 100644 lib_enc/gain_enc.c delete mode 100644 lib_enc/gs_enc.c delete mode 100644 lib_enc/guided_plc_enc.c delete mode 100644 lib_enc/hf_cod_amrwb.c delete mode 100644 lib_enc/hq_classifier_enc.c delete mode 100644 lib_enc/hq_core_enc.c delete mode 100644 lib_enc/hq_env_enc.c delete mode 100644 lib_enc/hq_hr_enc.c delete mode 100644 lib_enc/hq_lr_enc.c delete mode 100644 lib_enc/hvq_enc.c delete mode 100644 lib_enc/init_enc.c delete mode 100644 lib_enc/inov_enc.c delete mode 100644 lib_enc/isf_enc_amr_wb.c delete mode 100644 lib_enc/lead_indexing.c delete mode 100644 lib_enc/long_enr.c delete mode 100644 lib_enc/lp_exc_e.c delete mode 100644 lib_enc/lsf_enc.c delete mode 100644 lib_enc/ltd_stable.c delete mode 100644 lib_enc/mdct_classifier.c delete mode 100644 lib_enc/mdct_selector.c delete mode 100644 lib_enc/mslvq_enc.c delete mode 100644 lib_enc/multi_harm.c delete mode 100644 lib_enc/nelp_enc.c delete mode 100644 lib_enc/pit_enc.c delete mode 100644 lib_enc/pitch_ol.c delete mode 100644 lib_enc/pitch_ol2.c delete mode 100644 lib_enc/plc_enc_ext.c delete mode 100644 lib_enc/setmodeindex.c diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 75831970e..86e56d42a 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -239,60 +239,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -324,18 +273,13 @@ - - - - - @@ -373,18 +317,8 @@ - - - - - - - - - - diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 0c3220178..406c01b86 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -8,75 +8,39 @@ encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c @@ -92,54 +56,33 @@ encoder_evs_c - - encoder_evs_c - encoder_evs_c encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c - - encoder_evs_c - encoder_evs_c encoder_evs_c - - encoder_evs_c - encoder_evs_c encoder_evs_c - - encoder_evs_c - encoder_evs_c @@ -347,135 +290,72 @@ encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c encoder_all_c - - encoder_all_c - encoder_all_c @@ -494,9 +374,6 @@ encoder_all_c - - encoder_all_c - encoder_all_c @@ -506,27 +383,15 @@ encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c @@ -536,45 +401,24 @@ encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c @@ -590,39 +434,21 @@ encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c @@ -632,27 +458,15 @@ encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c @@ -668,21 +482,12 @@ encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c - - encoder_all_c - encoder_all_c @@ -719,9 +524,6 @@ encoder_all_c - - encoder_all_c - encoder_all_c diff --git a/lib_enc/ari_enc.c b/lib_enc/ari_enc.c deleted file mode 100644 index da4d1486b..000000000 --- a/lib_enc/ari_enc.c +++ /dev/null @@ -1,316 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "stat_com.h" -#include "basop_util.h" -#include "wmc_auto.h" -#include "prot_fx_enc.h" - - -/*--------------------------------------------------------------- - * ari_copy_states() - * - * Copy state - *-------------------------------------------------------------*/ - -void ari_copy_states( - Tastat *source, - Tastat *dest ) -{ - dest->low = source->low; - dest->high = source->high; - dest->bits_to_follow = source->bits_to_follow; - - return; -} - -/*--------------------------------------------------------------- - Ari encoder 14 bits routines - -------------------------------------------------------------*/ - -/*--------------------------------------------------------------- - * ari_start_encoding_14bits() - * - * Start ArCo encoding - *-------------------------------------------------------------*/ - -void ari_start_encoding_14bits( - Tastat *s ) -{ - /* : addressing is made with walking pointer s */ - s->low = 0; - s->high = ari_q4new; - s->bits_to_follow = 0; - move32(); - move32(); - move32(); - - return; -} -void ari_start_encoding_14bits_ivas_fx( - Tastat *s ) -{ - /* : addressing is made with walking pointer s */ - s->low = 0; - s->high = ari_q4new; - s->bits_to_follow = 0; - move32(); - move32(); - move32(); - - return; -} - -/*--------------------------------------------------------------- - * ari_done_encoding_14bits_ivas_fx() - * - * Finish ArCo encoding - *-------------------------------------------------------------*/ - -Word16 ari_done_encoding_14bits_ivas_fx( - Word16 *ptr, /* Q0 */ - Word16 bp, /* Q0 */ - Tastat *s ) -{ - Word16 bit; - - bit = 0; - move16(); - IF( GE_32( s->low, ari_q1new ) ) - { - bit = s_xor( bit, 1 ); - } - return ari_put_bit_plus_follow( ptr, bp, add( extract_l( s->bits_to_follow ), 1 ), bit ); -} - - -/*--------------------------------------------------------------- - * ari_encode_14bits_ext_ivas_fx() - * - * encode function for extended proba tables: less branches needed for coding - * - *-------------------------------------------------------------*/ -Word16 ari_encode_14bits_ext_ivas_fx( - Word16 *ptr, /* Q0 */ - Word16 bp, /* Q0 */ - Tastat *s, - Word32 symbol, /* Q0 */ - UWord16 const *cum_freq /* Q0 */ -) -{ - Word32 low; - Word32 high; - Word32 range; - Word16 bits_to_follow; - Word16 i; - UWord16 temp; - Word32 L_temp1, L_temp2; - - high = L_add( s->high, 0 ); - low = L_add( s->low, 0 ); - range = L_add( L_sub( high, low ), 1 ); /* Q0 */ - - L_temp1 = L_shl( range, 15 - stat_bitsnew /*both are constants*/ ); - Mpy_32_16_ss( L_temp1, cum_freq[symbol + 1], &L_temp2, &temp ); - IF( symbol != 0 ) /* when symbol is 0, range remains unchanged */ - { - Mpy_32_16_ss( L_temp1, cum_freq[symbol], &range, &temp ); - } - high = L_sub( L_add( low, range ), 1 ); /* Q0 */ - low = L_add( low, L_temp2 ); /* Q0 */ - - assert( s->bits_to_follow <= MAX_16 ); - bits_to_follow = extract_l( s->bits_to_follow ); /* Q0 */ - - FOR( i = 0; i < 0x7FFF; i++ ) - { - IF( LT_32( high, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ - bits_to_follow = 0; - move16(); - } - ELSE IF( GE_32( low, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ - bits_to_follow = 0; - move16(); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LT_32( high, ari_q3new ) ) - { - /* Output an opposite bit */ - /* later if in middle half. */ - bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ - low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; /* Otherwise exit loop. */ - } - } - low = L_add( low, low ); /* Q0 */ - high = L_add( L_add( high, high ), 1 ); /* Scale up code range. Q0*/ - } - - s->low = low; /* Q0 */ - move32(); - s->high = high; /* Q0 */ - move32(); - s->bits_to_follow = bits_to_follow; /* Q0 */ - move32(); - - return bp; -} - - -/*------------------------------------------------------------------------ - * Function: ari_encode_14bits_high_low_fx() - * - *-------------------------------------------------------------------------*/ - -static Word16 ari_encode_14bits_high_low_fx( - Word16 *ptr, /* Q0 */ - Word16 bp, /* Q0 */ - Word16 bits, /* Q0 */ - Tastat *s, - Word32 high, /* Q0 */ - Word32 low /* Q0 */ -) -{ - Word16 bits_to_follow, tmp; - - bits_to_follow = extract_l( s->bits_to_follow ); /* Q0 */ - move16(); - - /* while there are more than 16 bits left */ - tmp = sub( 16, bits ); /* Q0 */ - WHILE( add( add( bp, bits_to_follow ), tmp ) < 0 ) - { - IF( LE_32( high, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ - bits_to_follow = 0; - move16(); - } - ELSE IF( GE_32( low, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ - bits_to_follow = 0; - move16(); - low = L_sub( low, ari_q2new ); /* Q0 */ - high = L_sub( high, ari_q2new ); /* Subtract offset to top. Q0*/ - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - /* Output an opposite bit */ - /* later if in middle half. */ - bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ - low = L_sub( low, ari_q1new ); /* Subtract offset to middle Q0*/ - high = L_sub( high, ari_q1new ); /* Q0 */ - } - ELSE - { - BREAK; /* Otherwise exit loop. */ - } - } - - low = L_add( low, low ); - high = L_add( high, high ); /* Scale up code range. */ - } - - s->low = low; /* Q0 */ - move32(); - s->high = L_sub( high, 1 ); /* Q0 */ - move32(); - s->bits_to_follow = bits_to_follow; /* Q0 */ - move16(); - - return bp; -} - -/*------------------------------------------------------------------------ - * Function: ari_encode_14bits_sign_ivas_fx() - * - * Encode a sign with equal probabilities. - *-------------------------------------------------------------------------*/ -Word16 ari_encode_14bits_sign_ivas_fx( - Word16 *ptr, /* Q0 */ - Word16 bp, /* Q0 */ - Word32 bits, /* Q0 */ - Tastat *s, - Word16 sign /* Q0 */ -) -{ - Word32 low, high, range; - Word32 L_tmp; - - high = L_add( s->high, 1 ); - low = L_add( s->low, 0 ); - range = L_sub( high, low ); /* Q0 */ - - L_tmp = L_shr( range, 1 ); - if ( sign != 0 ) - { - high = L_add( low, L_tmp ); /* Q0 */ - } - if ( sign == 0 ) - { - low = L_add( low, L_tmp ); /* Q0 */ - } - - return ari_encode_14bits_high_low_fx( ptr, bp, extract_l( bits ), s, high, low ); -} - -/*------------------------------------------------------------------------ - * Function: ari_done_cbr_encoding_14bits() - * - * Finish up encoding in CBR mode. - *-------------------------------------------------------------------------*/ diff --git a/lib_enc/ari_enc_fx.c b/lib_enc/ari_enc_fx.c index 0ef053edd..29ddd838c 100644 --- a/lib_enc/ari_enc_fx.c +++ b/lib_enc/ari_enc_fx.c @@ -364,3 +364,226 @@ Word16 ari_done_cbr_encoding_14bits_fx( return bp; } + +void ari_start_encoding_14bits_ivas_fx( + Tastat *s ) +{ + /* : addressing is made with walking pointer s */ + s->low = 0; + s->high = ari_q4new; + s->bits_to_follow = 0; + move32(); + move32(); + move32(); + + return; +} + +/*--------------------------------------------------------------- + * ari_done_encoding_14bits_ivas_fx() + * + * Finish ArCo encoding + *-------------------------------------------------------------*/ + +Word16 ari_done_encoding_14bits_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Tastat *s ) +{ + Word16 bit; + + bit = 0; + move16(); + IF( GE_32( s->low, ari_q1new ) ) + { + bit = s_xor( bit, 1 ); + } + return ari_put_bit_plus_follow( ptr, bp, add( extract_l( s->bits_to_follow ), 1 ), bit ); +} + + +/*--------------------------------------------------------------- + * ari_encode_14bits_ext_ivas_fx() + * + * encode function for extended proba tables: less branches needed for coding + * + *-------------------------------------------------------------*/ +Word16 ari_encode_14bits_ext_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Tastat *s, + Word32 symbol, /* Q0 */ + UWord16 const *cum_freq /* Q0 */ +) +{ + Word32 low; + Word32 high; + Word32 range; + Word16 bits_to_follow; + Word16 i; + UWord16 temp; + Word32 L_temp1, L_temp2; + + high = L_add( s->high, 0 ); + low = L_add( s->low, 0 ); + range = L_add( L_sub( high, low ), 1 ); /* Q0 */ + + L_temp1 = L_shl( range, 15 - stat_bitsnew /*both are constants*/ ); + Mpy_32_16_ss( L_temp1, cum_freq[symbol + 1], &L_temp2, &temp ); + IF( symbol != 0 ) /* when symbol is 0, range remains unchanged */ + { + Mpy_32_16_ss( L_temp1, cum_freq[symbol], &range, &temp ); + } + high = L_sub( L_add( low, range ), 1 ); /* Q0 */ + low = L_add( low, L_temp2 ); /* Q0 */ + + assert( s->bits_to_follow <= MAX_16 ); + bits_to_follow = extract_l( s->bits_to_follow ); /* Q0 */ + + FOR( i = 0; i < 0x7FFF; i++ ) + { + IF( LT_32( high, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ + bits_to_follow = 0; + move16(); + } + ELSE IF( GE_32( low, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ + bits_to_follow = 0; + move16(); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LT_32( high, ari_q3new ) ) + { + /* Output an opposite bit */ + /* later if in middle half. */ + bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ + low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; /* Otherwise exit loop. */ + } + } + low = L_add( low, low ); /* Q0 */ + high = L_add( L_add( high, high ), 1 ); /* Scale up code range. Q0*/ + } + + s->low = low; /* Q0 */ + move32(); + s->high = high; /* Q0 */ + move32(); + s->bits_to_follow = bits_to_follow; /* Q0 */ + move32(); + + return bp; +} + + +/*------------------------------------------------------------------------ + * Function: ari_encode_14bits_high_low_fx() + * + *-------------------------------------------------------------------------*/ + +static Word16 ari_encode_14bits_high_low_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + Tastat *s, + Word32 high, /* Q0 */ + Word32 low /* Q0 */ +) +{ + Word16 bits_to_follow, tmp; + + bits_to_follow = extract_l( s->bits_to_follow ); /* Q0 */ + move16(); + + /* while there are more than 16 bits left */ + tmp = sub( 16, bits ); /* Q0 */ + WHILE( add( add( bp, bits_to_follow ), tmp ) < 0 ) + { + IF( LE_32( high, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ + bits_to_follow = 0; + move16(); + } + ELSE IF( GE_32( low, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ + bits_to_follow = 0; + move16(); + low = L_sub( low, ari_q2new ); /* Q0 */ + high = L_sub( high, ari_q2new ); /* Subtract offset to top. Q0*/ + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + /* Output an opposite bit */ + /* later if in middle half. */ + bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ + low = L_sub( low, ari_q1new ); /* Subtract offset to middle Q0*/ + high = L_sub( high, ari_q1new ); /* Q0 */ + } + ELSE + { + BREAK; /* Otherwise exit loop. */ + } + } + + low = L_add( low, low ); + high = L_add( high, high ); /* Scale up code range. */ + } + + s->low = low; /* Q0 */ + move32(); + s->high = L_sub( high, 1 ); /* Q0 */ + move32(); + s->bits_to_follow = bits_to_follow; /* Q0 */ + move16(); + + return bp; +} + +/*------------------------------------------------------------------------ + * Function: ari_encode_14bits_sign_ivas_fx() + * + * Encode a sign with equal probabilities. + *-------------------------------------------------------------------------*/ +Word16 ari_encode_14bits_sign_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word32 bits, /* Q0 */ + Tastat *s, + Word16 sign /* Q0 */ +) +{ + Word32 low, high, range; + Word32 L_tmp; + + high = L_add( s->high, 1 ); + low = L_add( s->low, 0 ); + range = L_sub( high, low ); /* Q0 */ + + L_tmp = L_shr( range, 1 ); + if ( sign != 0 ) + { + high = L_add( low, L_tmp ); /* Q0 */ + } + if ( sign == 0 ) + { + low = L_add( low, L_tmp ); /* Q0 */ + } + + return ari_encode_14bits_high_low_ivas_fx( ptr, bp, extract_l( bits ), s, high, low ); +} diff --git a/lib_enc/ari_hm_enc.c b/lib_enc/ari_hm_enc.c deleted file mode 100644 index c6e11a3f0..000000000 --- a/lib_enc/ari_hm_enc.c +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "stl.h" -#include "basop_util.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * EncodeIndex() - * - * - *-------------------------------------------------------------------*/ diff --git a/lib_enc/arith_coder_enc.c b/lib_enc/arith_coder_enc.c deleted file mode 100644 index 5625b6cf4..000000000 --- a/lib_enc/arith_coder_enc.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ diff --git a/lib_enc/avq_cod.c b/lib_enc/avq_cod.c deleted file mode 100644 index 9228e2f5d..000000000 --- a/lib_enc/avq_cod.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/bass_psfilter_enc.c b/lib_enc/bass_psfilter_enc.c deleted file mode 100644 index 9228e2f5d..000000000 --- a/lib_enc/bass_psfilter_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/bw_detect.c b/lib_enc/bw_detect.c deleted file mode 100644 index d86351ae8..000000000 --- a/lib_enc/bw_detect.c +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define BWD_MIN_BRATE_WIDER_BW_MDCT IVAS_48k -#define BWD_MIN_BRATE_WIDER_BW_ISM IVAS_32k -#define BWD_MAX_BRATE_WIDER_BW_MDCT IVAS_80k -#define BWD_MAX_BRATE_WIDER_BW_ISM IVAS_64k - -#define ALPHA_BWD 0.75f -#define BWD_LT_THRESH 0.6f - -#define BWD_COUNT_MAX 100 -#define BWD_COUNT_WIDER_BW 10 -#define BWD_COUNT_WIDER_BW_MDCT 0 - -#define CLDFB_ENER_OFFSET 1.6f diff --git a/lib_enc/cng_enc.c b/lib_enc/cng_enc.c deleted file mode 100644 index 192a71f92..000000000 --- a/lib_enc/cng_enc.c +++ /dev/null @@ -1,429 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx_enc.h" -#include "prot_fx.h" -#include "ivas_rom_com_fx.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - -static Word16 shb_DTX_ivas_fx( Encoder_State *st, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k_fx ); - -static void shb_CNG_encod_ivas_fx( Encoder_State *st, const Word16 update ); - - -void swb_CNG_enc_ivas_fx( - Encoder_State *st, /* i/o: State structure */ - const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ - const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ -) -{ - Word16 shb_SID_updt; - - test(); - IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) - { - IF( st->cng_type == LP_CNG ) - { - test(); - IF( GE_32( st->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) ) - { - /* decide if SHB SID encoding or not */ - shb_SID_updt = shb_DTX_ivas_fx( st, shb_speech_fx, syn_12k8_16k_fx ); - - /* SHB CNG encoding */ - shb_CNG_encod_ivas_fx( st, shb_SID_updt ); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_32( st->core_brate, SID_2k40 ) ) - { - /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */ - delete_indice( st->hBstr, IND_CNG_ENV1 ); - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); - push_indice( st->hBstr, IND_UNUSED, 0, 4 ); - push_indice( st->hBstr, IND_SID_BW, 1, 1 ); - } - } - st->hTdCngEnc->last_vad = 0; - move16(); - } - ELSE - { - st->hTdCngEnc->last_vad = 1; - move16(); - } - - return; -} - - -/*---------------------------------------------------------------------* - * shb_CNG_encod() - * - * SID parameters encoding for SHB signal - *---------------------------------------------------------------------*/ - -static void shb_CNG_encod_ivas_fx( - Encoder_State *st, /* i/o: State structure */ - const Word16 update /* i : SID update flag */ -) -{ - Word16 idx_ener = 0; - move16(); - BSTR_ENC_HANDLE hBstr = st->hBstr; - - Word16 ener_mid_dec_thr_fx; - - IF( EQ_16( update, 1 ) ) - { - IF( st->element_mode == EVS_MONO ) - { - /* 6.0 in Q8 -> 1510 */ - /* 0.9 in Q15 29491 */ - /* ( 1 / log10(2.0) ) * 0.1 in Q15 ->10886 */ - idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 29491 ), 8 ); /* Q0 */ - } - ELSE - { - /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/ - // PMT("shb_CNG_encod_fx quantization in missing") - /* 6.0 in Q8 -> 1510 */ - /* 0.7 in Q15 22938 */ - /* ( 1 / log10(2.0) ) * 0.1 in Q15 -> 10886 */ - idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 22938 ), 8 ); /* Q0 */ - } - - - if ( LT_16( st->bwidth, SWB ) ) - { - idx_ener = 0; - move16(); - } - - IF( GT_16( idx_ener, 15 ) ) - { - idx_ener = 15; - move16(); - } - ELSE IF( idx_ener < 0 ) - { - idx_ener = 0; - move16(); - } - - /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */ - IF( st->element_mode != EVS_MONO ) - { - IF( EQ_16( abs_s( sub( idx_ener, st->hTdCngEnc->last_idx_ener ) ), 1 ) ) - { - - Word16 tmp, tmp1, tmp2, scale, exp1, exp2, ener_mid_dec_thr_e; - tmp = BASOP_Util_Divide1616_Scale( st->hTdCngEnc->last_idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 - scale = add( scale, ( 15 - 0 ) ); - tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); - tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp1 ); - exp1 = add( exp1, ( scale - 0 ) ); - - ener_mid_dec_thr_fx = shr( mult( tmp1, 9864 ), 1 ); // exp = exp - - tmp = BASOP_Util_Divide1616_Scale( idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 - scale = add( scale, ( 15 - 0 ) ); - tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); - tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp2 ); - exp2 = add( exp2, ( scale - 0 ) ); - - tmp2 = shr( mult( tmp1, 9864 ), 1 ); // exp = exp - - ener_mid_dec_thr_e = BASOP_Util_Add_MantExp( tmp2, exp2, ener_mid_dec_thr_fx, exp1, &ener_mid_dec_thr_fx ); - - - scale = BASOP_Util_Add_MantExp( st->hTdCngEnc->mov_shb_cng_ener_fx, 7, negate( ener_mid_dec_thr_fx ), ener_mid_dec_thr_e, &tmp ); - tmp1 = BASOP_Util_Divide1616_Scale( tmp, ener_mid_dec_thr_fx, &exp1 ); - exp1 = add( exp1, sub( scale, ener_mid_dec_thr_e ) ); - IF( LT_16( abs_s( tmp1 ), shr( 328, sub( 15, exp1 ) ) ) ) - { - idx_ener = st->hTdCngEnc->last_idx_ener; - move16(); - } - } - } - - st->hTdCngEnc->last_idx_ener = idx_ener; - move16(); - - push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 ); - push_indice( hBstr, IND_SID_BW, 1, 1 ); - delete_indice( hBstr, IND_CNG_ENV1 ); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); - } - ELSE - { - push_indice( hBstr, IND_UNUSED, 0, 2 ); - } - st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - st->hTdCngEnc->ho_sid_bw = L_or( st->hTdCngEnc->ho_sid_bw, 0x1L ); - move32(); - move32(); - } - ELSE IF( EQ_32( st->core_brate, SID_2k40 ) ) - { - st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - move32(); - push_indice( hBstr, IND_SID_BW, 0, 1 ); - } - - return; -} - -/*---------------------------------------------------------------------* - * shb_DTX() - * - * Decide if encoding SHB SID or not - *---------------------------------------------------------------------*/ - -static Word16 shb_DTX_ivas_fx( - Encoder_State *st, /* i/o: State structure */ - const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ - const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ -) -{ - Word16 i; - Word16 update; - - Word16 allow_cn_step = 0; - move16(); - Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4]; - Word16 *shb_new_speech_fx; - Word32 wb_ener_fx; - Word32 shb_ener_fx; - Word16 log_wb_ener_fx; - Word16 log_shb_ener_fx; - Word16 tmp; - Word16 exp; - Word16 fra; - Word16 att_fx; /*Q8*/ - - TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc; - TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; - - -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move16(); -#endif - - shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4; - Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // old_speech_shb_fx -> Q0 - Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k ); // Q0 - Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // Q0 - - shb_ener_fx = L_deposit_l( 0 ); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac - } - - shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* ( 1 / L_FRAME16K ) -> 102 in Q15, shb_ener_fx in Q1 */ - - wb_ener_fx = L_deposit_l( 0 ); - FOR( i = 0; i < st->L_frame; i++ ) - { - wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k_fx[i], syn_12k8_16k_fx[i], &Overflow ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac - } - - wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */ - - exp = norm_l( wb_ener_fx ); - fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) ); - exp = sub( 30 - 1, exp ); - wb_ener_fx = Mpy_32_16( exp, fra, LG10 ); - - log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */ - exp = norm_l( shb_ener_fx ); - fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) ); - exp = sub( 30 - 1, exp ); - shb_ener_fx = Mpy_32_16( exp, fra, LG10 ); - - - test(); - IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - Word32 att_fx32 = 0; - move32(); - Word16 index; - - apply_scale_ivas_fx( &att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index ); // Q23; - - att_fx = extract_l( L_shr( att_fx32, 15 ) ); // Q8 - } - ELSE - { - att_fx = -1664; // Q8 - move16(); - } - - - log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att_fx, &Overflow ); /* log_shb_ener_fx in Q8 */ - - IF( st->hDtxEnc->first_CNG == 0 ) - { - - - hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; // Q8 - hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; // Q8 - hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx; // Q8 - hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx; // Q8 - move16(); - move16(); - move16(); - move16(); - } - IF( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12 in Q8*/ ) ) - { - allow_cn_step = 1; - move16(); - } - - /* Also allow step if shb energy has dropped 12 dB */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GT_16( sub( hTdCngEnc->mov_shb_cng_ener_fx, log_shb_ener_fx ), 3072 /*12 in Q8*/ ) ) - { - allow_cn_step = 1; - move16(); - } - - IF( EQ_16( allow_cn_step, 1 ) ) - { - hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; - hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; - move16(); - move16(); - } - ELSE - { - tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */ - tmp = mult( tmp, 29491 /* .9f in Q15*/ ); /* Q8 */ - hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */ - move16(); - - tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ); - tmp = mult( tmp, 8192 /* .25f in Q15*/ ); /* Q8 */ - hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */ - move16(); - } - - hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 ); - update = 0; - - move16(); - move16(); - - IF( EQ_32( st->core_brate, SID_2k40 ) ) - { - test(); - test(); - test(); - IF( st->hDtxEnc->first_CNG == 0 ) - { - update = 1; - move16(); - } - ELSE IF( hTdCngEnc->shb_cng_ini_cnt > 0 ) - { - hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 ); - update = 1; - move16(); - move16(); - } - ELSE IF( EQ_16( hTdCngEnc->last_vad, 1 ) ) - { - update = 1; - move16(); - } - ELSE IF( GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) ) - { - update = 1; - move16(); - } - ELSE IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 ) ) - { - update = 1; - move16(); - } - ELSE IF( ( GE_16( st->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) ) || ( LT_16( st->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) ) ) - { - update = 1; - move16(); - } - - hTdCngEnc->last_SID_bwidth = st->bwidth; - move16(); - } - - /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */ - test(); - test(); - if ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_32( st->core_brate, SID_2k40 ) ) - { - update = 1; - move16(); - } - - IF( EQ_16( update, 1 ) ) - { - hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx; - hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx; - hTdCngEnc->shb_NO_DATA_cnt = 0; - move16(); - move16(); - move16(); - } - - return ( update ); -} diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 4cfc193ec..7188bcbad 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -27,6 +27,8 @@ *---------------------------------------------------------------------*/ static void shb_CNG_encod_fx( Encoder_State *st_fx, const Word16 update_fx ); static Word16 shb_DTX_fx( Encoder_State *st_fx, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k ); +static Word16 shb_DTX_ivas_fx( Encoder_State *st, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k_fx ); +static void shb_CNG_encod_ivas_fx( Encoder_State *st, const Word16 update ); /*---------------------------------------------------------------------* * CNG_enc() * @@ -2839,3 +2841,375 @@ void calculate_hangover_attenuation_gain_ivas_fx( return; } + +void swb_CNG_enc_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ + const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ +) +{ + Word16 shb_SID_updt; + + test(); + IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) + { + IF( st->cng_type == LP_CNG ) + { + test(); + IF( GE_32( st->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) ) + { + /* decide if SHB SID encoding or not */ + shb_SID_updt = shb_DTX_ivas_fx( st, shb_speech_fx, syn_12k8_16k_fx ); + + /* SHB CNG encoding */ + shb_CNG_encod_ivas_fx( st, shb_SID_updt ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_32( st->core_brate, SID_2k40 ) ) + { + /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */ + delete_indice( st->hBstr, IND_CNG_ENV1 ); + push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); + push_indice( st->hBstr, IND_UNUSED, 0, 4 ); + push_indice( st->hBstr, IND_SID_BW, 1, 1 ); + } + } + st->hTdCngEnc->last_vad = 0; + move16(); + } + ELSE + { + st->hTdCngEnc->last_vad = 1; + move16(); + } + + return; +} + + +/*---------------------------------------------------------------------* + * shb_CNG_encod() + * + * SID parameters encoding for SHB signal + *---------------------------------------------------------------------*/ + +static void shb_CNG_encod_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + const Word16 update /* i : SID update flag */ +) +{ + Word16 idx_ener = 0; + move16(); + BSTR_ENC_HANDLE hBstr = st->hBstr; + + Word16 ener_mid_dec_thr_fx; + + IF( EQ_16( update, 1 ) ) + { + IF( st->element_mode == EVS_MONO ) + { + /* 6.0 in Q8 -> 1510 */ + /* 0.9 in Q15 29491 */ + /* ( 1 / log10(2.0) ) * 0.1 in Q15 ->10886 */ + idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 29491 ), 8 ); /* Q0 */ + } + ELSE + { + /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/ + // PMT("shb_CNG_encod_fx quantization in missing") + /* 6.0 in Q8 -> 1510 */ + /* 0.7 in Q15 22938 */ + /* ( 1 / log10(2.0) ) * 0.1 in Q15 -> 10886 */ + idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 22938 ), 8 ); /* Q0 */ + } + + + if ( LT_16( st->bwidth, SWB ) ) + { + idx_ener = 0; + move16(); + } + + IF( GT_16( idx_ener, 15 ) ) + { + idx_ener = 15; + move16(); + } + ELSE IF( idx_ener < 0 ) + { + idx_ener = 0; + move16(); + } + + /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */ + IF( st->element_mode != EVS_MONO ) + { + IF( EQ_16( abs_s( sub( idx_ener, st->hTdCngEnc->last_idx_ener ) ), 1 ) ) + { + + Word16 tmp, tmp1, tmp2, scale, exp1, exp2, ener_mid_dec_thr_e; + tmp = BASOP_Util_Divide1616_Scale( st->hTdCngEnc->last_idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 + scale = add( scale, ( 15 - 0 ) ); + tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); + tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp1 ); + exp1 = add( exp1, ( scale - 0 ) ); + + ener_mid_dec_thr_fx = shr( mult( tmp1, 9864 ), 1 ); // exp = exp + + tmp = BASOP_Util_Divide1616_Scale( idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 + scale = add( scale, ( 15 - 0 ) ); + tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); + tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp2 ); + exp2 = add( exp2, ( scale - 0 ) ); + + tmp2 = shr( mult( tmp1, 9864 ), 1 ); // exp = exp + + ener_mid_dec_thr_e = BASOP_Util_Add_MantExp( tmp2, exp2, ener_mid_dec_thr_fx, exp1, &ener_mid_dec_thr_fx ); + + + scale = BASOP_Util_Add_MantExp( st->hTdCngEnc->mov_shb_cng_ener_fx, 7, negate( ener_mid_dec_thr_fx ), ener_mid_dec_thr_e, &tmp ); + tmp1 = BASOP_Util_Divide1616_Scale( tmp, ener_mid_dec_thr_fx, &exp1 ); + exp1 = add( exp1, sub( scale, ener_mid_dec_thr_e ) ); + IF( LT_16( abs_s( tmp1 ), shr( 328, sub( 15, exp1 ) ) ) ) + { + idx_ener = st->hTdCngEnc->last_idx_ener; + move16(); + } + } + } + + st->hTdCngEnc->last_idx_ener = idx_ener; + move16(); + + push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 ); + push_indice( hBstr, IND_SID_BW, 1, 1 ); + delete_indice( hBstr, IND_CNG_ENV1 ); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); + } + ELSE + { + push_indice( hBstr, IND_UNUSED, 0, 2 ); + } + st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); + st->hTdCngEnc->ho_sid_bw = L_or( st->hTdCngEnc->ho_sid_bw, 0x1L ); + move32(); + move32(); + } + ELSE IF( EQ_32( st->core_brate, SID_2k40 ) ) + { + st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); + move32(); + push_indice( hBstr, IND_SID_BW, 0, 1 ); + } + + return; +} + +/*---------------------------------------------------------------------* + * shb_DTX() + * + * Decide if encoding SHB SID or not + *---------------------------------------------------------------------*/ + +static Word16 shb_DTX_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ + const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ +) +{ + Word16 i; + Word16 update; + + Word16 allow_cn_step = 0; + move16(); + Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4]; + Word16 *shb_new_speech_fx; + Word32 wb_ener_fx; + Word32 shb_ener_fx; + Word16 log_wb_ener_fx; + Word16 log_shb_ener_fx; + Word16 tmp; + Word16 exp; + Word16 fra; + Word16 att_fx; /*Q8*/ + + TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc; + TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; + + +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + + shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4; + Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // old_speech_shb_fx -> Q0 + Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k ); // Q0 + Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // Q0 + + shb_ener_fx = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac + } + + shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* ( 1 / L_FRAME16K ) -> 102 in Q15, shb_ener_fx in Q1 */ + + wb_ener_fx = L_deposit_l( 0 ); + FOR( i = 0; i < st->L_frame; i++ ) + { + wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k_fx[i], syn_12k8_16k_fx[i], &Overflow ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac + } + + wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */ + + exp = norm_l( wb_ener_fx ); + fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) ); + exp = sub( 30 - 1, exp ); + wb_ener_fx = Mpy_32_16( exp, fra, LG10 ); + + log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */ + exp = norm_l( shb_ener_fx ); + fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) ); + exp = sub( 30 - 1, exp ); + shb_ener_fx = Mpy_32_16( exp, fra, LG10 ); + + + test(); + IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + Word32 att_fx32 = 0; + move32(); + Word16 index; + + apply_scale_ivas_fx( &att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index ); // Q23; + + att_fx = extract_l( L_shr( att_fx32, 15 ) ); // Q8 + } + ELSE + { + att_fx = -1664; // Q8 + move16(); + } + + + log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att_fx, &Overflow ); /* log_shb_ener_fx in Q8 */ + + IF( st->hDtxEnc->first_CNG == 0 ) + { + + + hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; // Q8 + hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; // Q8 + hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx; // Q8 + hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx; // Q8 + move16(); + move16(); + move16(); + move16(); + } + IF( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12 in Q8*/ ) ) + { + allow_cn_step = 1; + move16(); + } + + /* Also allow step if shb energy has dropped 12 dB */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GT_16( sub( hTdCngEnc->mov_shb_cng_ener_fx, log_shb_ener_fx ), 3072 /*12 in Q8*/ ) ) + { + allow_cn_step = 1; + move16(); + } + + IF( EQ_16( allow_cn_step, 1 ) ) + { + hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; + hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; + move16(); + move16(); + } + ELSE + { + tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */ + tmp = mult( tmp, 29491 /* .9f in Q15*/ ); /* Q8 */ + hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */ + move16(); + + tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ); + tmp = mult( tmp, 8192 /* .25f in Q15*/ ); /* Q8 */ + hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */ + move16(); + } + + hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 ); + update = 0; + + move16(); + move16(); + + IF( EQ_32( st->core_brate, SID_2k40 ) ) + { + test(); + test(); + test(); + IF( st->hDtxEnc->first_CNG == 0 ) + { + update = 1; + move16(); + } + ELSE IF( hTdCngEnc->shb_cng_ini_cnt > 0 ) + { + hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 ); + update = 1; + move16(); + move16(); + } + ELSE IF( EQ_16( hTdCngEnc->last_vad, 1 ) ) + { + update = 1; + move16(); + } + ELSE IF( GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) ) + { + update = 1; + move16(); + } + ELSE IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 ) ) + { + update = 1; + move16(); + } + ELSE IF( ( GE_16( st->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) ) || ( LT_16( st->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) ) ) + { + update = 1; + move16(); + } + + hTdCngEnc->last_SID_bwidth = st->bwidth; + move16(); + } + + /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */ + test(); + test(); + if ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_32( st->core_brate, SID_2k40 ) ) + { + update = 1; + move16(); + } + + IF( EQ_16( update, 1 ) ) + { + hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx; + hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx; + hTdCngEnc->shb_NO_DATA_cnt = 0; + move16(); + move16(); + move16(); + } + + return ( update ); +} diff --git a/lib_enc/cod2t32.c b/lib_enc/cod2t32.c deleted file mode 100644 index 167c70dbf..000000000 --- a/lib_enc/cod2t32.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/cod4t64.c b/lib_enc/cod4t64.c deleted file mode 100644 index 9be976783..000000000 --- a/lib_enc/cod4t64.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_enc/cod_ace.c b/lib_enc/cod_ace.c deleted file mode 100644 index 46d7a42d1..000000000 --- a/lib_enc/cod_ace.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include -#include "options.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c deleted file mode 100644 index 88e028c86..000000000 --- a/lib_enc/cod_tcx.c +++ /dev/null @@ -1,869 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "ivas_rom_com_fx.h" -#include "prot_fx_enc.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" - - -/*-------------------------------------------------------------------* - * TNSAnalysisStereo() - * - * - *-------------------------------------------------------------------*/ - -#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 ) -void TNSAnalysisStereo_fx( - Encoder_State **sts, /* i : encoder state handle */ - Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/ - const Word16 bWhitenedDomain, /* i : whitened domain flag Q0*/ - Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm Q0*/ - Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame Q0*/ - Word16 param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters Q0*/ - const Word16 mct_on /* i : flag mct block (1) or stereo (0) Q0*/ -) -{ - Word16 ch, k, L_spec, L_frame, nSubframes, iFilter; - Word32 *spectrum_fx; - Encoder_State *st = NULL; - TCX_ENC_HANDLE hTcxEnc = NULL; - Word16 individual_decision[NB_DIV]; - Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; - move32(); - Word16 maxPredictionGain_e = Q31, meanPredictionGain_e; - move16(); - Word16 sum_e = 0; - move16(); - individual_decision[0] = 0; - move16(); - individual_decision[1] = 0; - move16(); - L_spec = -1; - move16(); - L_frame = -1; - move16(); - - /* TNS filter analysis, loop over channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - continue; - } - - hTcxEnc = st->hTcxEnc; - - IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - - FOR( k = 0; k < nSubframes; k++ ) - { - /* reset tns on whitened domain flag */ - IF( !bWhitenedDomain ) - { - hTcxEnc->bTnsOnWhithenedSpectra[k] = 0; - move16(); - hTcxEnc->fUseTns[k] = 0; - move16(); - } - test(); - test(); - IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - spectrum_fx = hTcxEnc->spectrum_fx[k]; - - L_frame = hTcxEnc->L_frameTCX; - move16(); - st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; - L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; - move16(); - /*-----------------------------------------------------------* - * Temporal Noise Shaping analysis * - *-----------------------------------------------------------*/ - - IF( EQ_16( hTcxEnc->transform_type[k], TCX_5 ) ) - { - /* rearrange LF sub-window lines prior to TNS analysis & filtering */ - tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx ); - } - - /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */ - - ResetTnsData( &hTcxEnc->tnsData[k] ); - IF( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 ) - { - BREAK; - } - - CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] ); - } - } - } - - IF( !mct_on ) - { - /* TNS decision */ - /* if framing differs between channels, keep the filter decision per channel */ - test(); - test(); - IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && - NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || - NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) ) - { - individual_decision[0] = individual_decision[1] = 1; - move16(); - move16(); - } - ELSE IF( bWhitenedDomain ) - { - IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - FOR( k = 0; k < nSubframes; k++ ) - { - IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - individual_decision[k] = 1; - move16(); - } - } - } - - /* framing equal, check for similar filters, if very similar (also indicator for and M signal), - * use at least the same decision, maybe use the same filter - */ - { - Word8 isTCX10; - - IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - isTCX10 = 0; - } - ELSE - { - nSubframes = NB_DIV; - isTCX10 = 1; - } - move16(); - move16(); - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - test(); - IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - Word32 maxPredGain_fx = -ONE_IN_Q31; - move32(); - Word16 maxPredGain_e = 0; - move16(); - sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; - sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; - - FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter[2]; - struct TnsParameters const *pTnsParameters[2]; - pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - - /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of - * both filters for the decision - */ - - meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e - Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, meanPredictionGain_fx, meanPredictionGain_e ); - IF( flag < 0 ) - { - maxPredictionGain_fx = meanPredictionGain_fx; - maxPredictionGain_e = meanPredictionGain_e; - move32(); - move16(); - } - flag = BASOP_Util_Cmp_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - Word16 flag_1 = BASOP_Util_Cmp_Mant32Exp( pFilter[1]->predictionGain32, pFilter[1]->predictionGain_e, L_deposit_h( pTnsParameters[1]->minPredictionGain ), PRED_GAIN_E ); - if ( flag_1 < 0 ) - { - flag_1 = 0; - move16(); - } - test(); - test(); - test(); - IF( flag && LT_32( sts[0]->element_brate, IVAS_80k ) && - flag_1 && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ - move32(); - move32(); - pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */ - move16(); - move16(); - pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */ - move16(); - move16(); - } - flag = BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ), meanPredictionGain_e, L_abs( BASOP_Util_Add_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_negate( pFilter[1]->predictionGain32 ), pFilter[1]->predictionGain_e, &sum_e ) ), sum_e ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - test(); - IF( flag && - ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) - { - - Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 - Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - // maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); - flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, meanPredictionGain_fx, meanPredictionGain_e ); - IF( flag < 0 ) - { - maxPredGain_fx = meanPredictionGain_fx; - maxPredGain_e = meanPredictionGain_e; - move32(); - move16(); - } - flag = BASOP_Util_Cmp_Mant32Exp( meanPredictionGain_fx, meanPredictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - test(); - test(); - IF( flag || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) - { - test(); - test(); - test(); - IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( meanLtpGain_fx, 19660 /* 0.6 in Q15*/ ) ) - { - - sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter[0]->order != 0 ) - { - pFilter[0]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - IF( pFilter[1]->order != 0 ) - { - pFilter[1]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - Word16 maxEnergyChange_fx; - maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ); - - IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) ) - { - sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter[0]->order != 0 ) - { - pFilter[0]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - IF( pFilter[1]->order != 0 ) - { - pFilter[1]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_OFF; - move16(); - pFilter[1]->filterType = TNS_FILTER_OFF; - move16(); - } - } - } - ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - move16(); - move16(); - sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - } - ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */ - { - assert( 0 ); - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_OFF; - move16(); - pFilter[1]->filterType = TNS_FILTER_OFF; - move16(); - } - - test(); - test(); - IF( EQ_16( pFilter[0]->filterType, TNS_FILTER_ON ) && EQ_16( pFilter[1]->filterType, TNS_FILTER_ON ) && LT_32( sts[0]->element_brate, IVAS_80k ) ) - { - Word16 tmpIntValue = 0; - move16(); - Word16 tmpCoeff[TNS_MAX_FILTER_ORDER]; - Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order ); - - set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER ); - FOR( i = 0; i < maxOrder; i++ ) - { - tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) ); - } - - IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */ - { - FOR( i = maxOrder - 1; i >= 0; i-- ) - { - IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) ) - { - tmpCoeff[i] = pFilter[0]->coefIndex[i]; - } - ELSE - { - tmpCoeff[i] = pFilter[1]->coefIndex[i]; - } - move16(); - IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) ) - { - maxOrder = sub( maxOrder, 1 ); - } - ELSE - { - tmpIntValue = 0; - move16(); - } - } - /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */ - IF( maxOrder > 0 ) - { - FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- ) - { - pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i]; - move16(); - move16(); - } - - pFilter[0]->order = pFilter[1]->order = maxOrder; - move16(); - move16(); - } - } - } - } - ELSE - { - individual_decision[k] = 1; - move16(); - } - } - - IF( individual_decision[k] == 0 ) - { - IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[0]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[0]->hTcxEnc->fUseTns[k] = 0; - } - move16(); - - IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[1]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[1]->hTcxEnc->fUseTns[k] = 0; - } - move16(); - } - ELSE - { - sts[0]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[1]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[0]->hTcxEnc->fUseTns[k] = 0; - move16(); - sts[1]->hTcxEnc->fUseTns[k] = 0; - move16(); - FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - move16(); - sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - move16(); - } - } - Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - test(); - test(); - test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && flag && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) - { - sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - move16(); - sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - move16(); - sts[0]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[1]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[0]->hTcxEnc->fUseTns[k] = 0; - move16(); - sts[1]->hTcxEnc->fUseTns[k] = 0; - move16(); - FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter ); - ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); - } - } - // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); - flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); - IF( flag < 0 ) - { - maxPredictionGain_fx = maxPredGain_fx; - maxPredictionGain_e = maxPredGain_e; - move32(); - move16(); - } - } - } - } - } - - /* individual decision for each channel */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - CONTINUE; - } - - Word8 isTCX10; - - IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - isTCX10 = 0; - } - ELSE - { - nSubframes = NB_DIV; - isTCX10 = 1; - } - move16(); - move16(); - - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - test(); - test(); - IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && - ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31 - move32(); - Word16 maxPredGain_e = 0; - move16(); - sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; - - FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter; - struct TnsParameters const *pTnsParameters; - pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - - // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); - Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, pFilter->predictionGain32, pFilter->predictionGain_e ); - IF( flag < 0 ) - { - maxPredGain_fx = pFilter->predictionGain32; - move32(); - maxPredGain_e = pFilter->predictionGain_e; - move16(); - } - flag = BASOP_Util_Cmp_Mant32Exp( pFilter->predictionGain32, pFilter->predictionGain_e, L_deposit_h( pTnsParameters->minPredictionGain ), PRED_GAIN_E ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - test(); - IF( flag || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) - { - test(); - test(); - IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 /*.6f in Q15*/ ) ) - { - sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter->order != 0 ) - { - pFilter->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); - - IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) ) - { - sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter->order != 0 ) - { - pFilter->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - pFilter->filterType = TNS_FILTER_OFF; - move16(); - } - } - } - ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - move16(); - sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); - move16(); - } - ELSE - { - pFilter->filterType = TNS_FILTER_OFF; - move16(); - } - } - - IF( ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[ch]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[ch]->hTcxEnc->fUseTns[k] = 0; - } - move16(); - Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - test(); - test(); - IF( !bWhitenedDomain && flag && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) - { - sts[ch]->hTcxEnc->fUseTns[k] = 0; - move16(); - sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - move16(); - sts[ch]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); - sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - move16(); - } - } - // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); - flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); - IF( flag < 0 ) - { - maxPredictionGain_fx = maxPredGain_fx; - maxPredictionGain_e = maxPredGain_e; - move32(); - move16(); - } - } - } - } - - - /* we have the decision, set filter data accordingly */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IF( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - CONTINUE; - } - - IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; - - FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter; - pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; - SWITCH( pFilter->filterType ) - { - case TNS_FILTER_OFF: - ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); - BREAK; - case TNS_FILTER_ON_ZERO: - /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */ - ClearTnsFilterCoefficients( pFilter ); - pFilter->order = 1; - move16(); - BREAK; - } - } - } - } - } - - /* Apply filters, loop over channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - CONTINUE; - } - - IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - test(); - test(); - test(); - IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */ - sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] && - sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] ) - { - Word16 equalFilterData = 0; - move16(); - test(); - test(); - if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) && - EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) && - EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - equalFilterData = 1; - move16(); - } - - IF( equalFilterData ) - { - FOR( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter]; - const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter]; - Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */ - - move16(); - test(); - WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) ) - { - test(); - i = sub( i, 1 ); - } - IF( i >= 0 ) - { - equalFilterData = 0; - move16(); - BREAK; - } - } - IF( equalFilterData ) - { - st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */ - move16(); - } - } - } - test(); - test(); - IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; - move16(); - spectrum_fx = st->hTcxEnc->spectrum_fx[k]; - /* If TNS should be used then get the residual after applying it inplace in the spectrum */ - IF( st->hTcxEnc->fUseTns[k] ) - { - st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; - - ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 ); - } - - IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) - { - tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC ); - } - - st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k]; - move16(); - EncodeTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k ); - } - - IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) - { - tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] ); - tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] ); - } - } - } - return; -} diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index b2fe04ce1..bf20608b0 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -26,6 +26,9 @@ #include "debug.h" #endif +#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 ) /* Up to the Autocorrelation it is the same code as in GetMDCT, with the difference in the parameters in the call to tcx_windowing_analysis */ void HBAutocorrelation_fx( @@ -5363,3 +5366,721 @@ void InternalTCXDecoder_fx( return; } + + +void TNSAnalysisStereo_fx( + Encoder_State **sts, /* i : encoder state handle */ + Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/ + const Word16 bWhitenedDomain, /* i : whitened domain flag Q0*/ + Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm Q0*/ + Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame Q0*/ + Word16 param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters Q0*/ + const Word16 mct_on /* i : flag mct block (1) or stereo (0) Q0*/ +) +{ + Word16 ch, k, L_spec, L_frame, nSubframes, iFilter; + Word32 *spectrum_fx; + Encoder_State *st = NULL; + TCX_ENC_HANDLE hTcxEnc = NULL; + Word16 individual_decision[NB_DIV]; + Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; + move16(); + + individual_decision[0] = 0; + move16(); + individual_decision[1] = 0; + move16(); + L_spec = -1; + move16(); + L_frame = -1; + move16(); + + /* TNS filter analysis, loop over channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st = sts[ch]; + IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + continue; + } + + hTcxEnc = st->hTcxEnc; + + IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + + FOR( k = 0; k < nSubframes; k++ ) + { + /* reset tns on whitened domain flag */ + IF( !bWhitenedDomain ) + { + hTcxEnc->bTnsOnWhithenedSpectra[k] = 0; + move16(); + hTcxEnc->fUseTns[k] = 0; + move16(); + } + test(); + test(); + IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + spectrum_fx = hTcxEnc->spectrum_fx[k]; + + L_frame = hTcxEnc->L_frameTCX; + move16(); + st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; + L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; + move16(); + /*-----------------------------------------------------------* + * Temporal Noise Shaping analysis * + *-----------------------------------------------------------*/ + + IF( EQ_16( hTcxEnc->transform_type[k], TCX_5 ) ) + { + /* rearrange LF sub-window lines prior to TNS analysis & filtering */ + tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx ); + } + + /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */ + + ResetTnsData( &hTcxEnc->tnsData[k] ); + IF( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 ) + { + BREAK; + } + + CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] ); + } + } + } + + IF( !mct_on ) + { + /* TNS decision */ + /* if framing differs between channels, keep the filter decision per channel */ + test(); + test(); + IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && + NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || + NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) ) + { + individual_decision[0] = individual_decision[1] = 1; + move16(); + move16(); + } + ELSE IF( bWhitenedDomain ) + { + IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + individual_decision[k] = 1; + move16(); + } + } + } + + /* framing equal, check for similar filters, if very similar (also indicator for and M signal), + * use at least the same decision, maybe use the same filter + */ + { + Word8 isTCX10; + + IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + isTCX10 = 0; + } + ELSE + { + nSubframes = NB_DIV; + isTCX10 = 1; + } + move16(); + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + Word32 maxPredGain_fx = -ONE_IN_Q23; + move16(); + sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; + sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; + + FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + STnsFilter *pFilter[2]; + struct TnsParameters const *pTnsParameters[2]; + pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter; + pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; + pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter; + pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; + + /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of + * both filters for the decision + */ + + meanPredictionGain_fx = L_add( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ) ); // Q23 + maxPredictionGain_fx = L_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q23 + + test(); + test(); + test(); + IF( GT_32( pFilter[0]->predictionGain32, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && + GT_32( pFilter[1]->predictionGain32, L_shl( pTnsParameters[1]->minPredictionGain, 16 ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + { + pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ + move16(); + move16(); + } + test(); + IF( LT_32( L_abs( L_sub( pFilter[0]->predictionGain32, pFilter[1]->predictionGain32 ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && + ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) + { + + Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 + Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); + maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); + test(); + test(); + IF( GT_32( meanPredictionGain_fx, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + { + test(); + test(); + test(); + IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( meanLtpGain_fx, 19660 /* 0.6 in Q15*/ ) ) + { + + sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter[0]->order != 0 ) + { + pFilter[0]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + IF( pFilter[1]->order != 0 ) + { + pFilter[1]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[1]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + Word16 maxEnergyChange_fx; + maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ); + + IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) ) + { + sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter[0]->order != 0 ) + { + pFilter[0]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + IF( pFilter[1]->order != 0 ) + { + pFilter[1]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[1]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_OFF; + move16(); + pFilter[1]->filterType = TNS_FILTER_OFF; + move16(); + } + } + } + ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ + { + pFilter[0]->filterType = TNS_FILTER_ON_ZERO; + pFilter[1]->filterType = TNS_FILTER_ON_ZERO; + move16(); + move16(); + sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + } + ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */ + { + assert( 0 ); + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_OFF; + move16(); + pFilter[1]->filterType = TNS_FILTER_OFF; + move16(); + } + + test(); + test(); + IF( EQ_16( pFilter[0]->filterType, TNS_FILTER_ON ) && EQ_16( pFilter[1]->filterType, TNS_FILTER_ON ) && LT_32( sts[0]->element_brate, IVAS_80k ) ) + { + Word16 tmpIntValue = 0; + move16(); + Word16 tmpCoeff[TNS_MAX_FILTER_ORDER]; + Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order ); + + set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER ); + FOR( i = 0; i < maxOrder; i++ ) + { + tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) ); + } + + IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */ + { + FOR( i = maxOrder - 1; i >= 0; i-- ) + { + IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) ) + { + tmpCoeff[i] = pFilter[0]->coefIndex[i]; + } + ELSE + { + tmpCoeff[i] = pFilter[1]->coefIndex[i]; + } + move16(); + IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) ) + { + maxOrder = sub( maxOrder, 1 ); + } + ELSE + { + tmpIntValue = 0; + move16(); + } + } + /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */ + IF( maxOrder > 0 ) + { + FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- ) + { + pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i]; + move16(); + move16(); + } + + pFilter[0]->order = pFilter[1]->order = maxOrder; + move16(); + move16(); + } + } + } + } + ELSE + { + individual_decision[k] = 1; + move16(); + } + } + + IF( individual_decision[k] == 0 ) + { + IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ) + { + sts[0]->hTcxEnc->fUseTns[k] = 1; + } + ELSE + { + sts[0]->hTcxEnc->fUseTns[k] = 0; + } + move16(); + + IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ) + { + sts[1]->hTcxEnc->fUseTns[k] = 1; + } + ELSE + { + sts[1]->hTcxEnc->fUseTns[k] = 0; + } + move16(); + } + ELSE + { + sts[0]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[1]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[0]->hTcxEnc->fUseTns[k] = 0; + move16(); + sts[1]->hTcxEnc->fUseTns[k] = 0; + move16(); + FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; + move16(); + sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; + move16(); + } + } + test(); + test(); + test(); + IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + { + sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; + move16(); + sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; + move16(); + sts[0]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[1]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[0]->hTcxEnc->fUseTns[k] = 0; + move16(); + sts[1]->hTcxEnc->fUseTns[k] = 0; + move16(); + FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter ); + ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); + } + } + maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + } + } + } + } + + /* individual decision for each channel */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + Word8 isTCX10; + + IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + isTCX10 = 0; + } + ELSE + { + nSubframes = NB_DIV; + isTCX10 = 1; + } + move16(); + move16(); + + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + test(); + IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && + ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + Word32 maxPredGain_fx = -ONE_IN_Q23; // Q23 + move16(); + sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; + + FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + STnsFilter *pFilter; + struct TnsParameters const *pTnsParameters; + pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; + pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; + + maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); + test(); + IF( GT_32( pFilter->predictionGain32, L_shl( pTnsParameters->minPredictionGain, 16 ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + { + test(); + test(); + IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 /*.6f in Q15*/ ) ) + { + sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter->order != 0 ) + { + pFilter->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); + + IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) ) + { + sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter->order != 0 ) + { + pFilter->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + pFilter->filterType = TNS_FILTER_OFF; + move16(); + } + } + } + ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ + { + pFilter->filterType = TNS_FILTER_ON_ZERO; + move16(); + sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + } + ELSE + { + pFilter->filterType = TNS_FILTER_OFF; + move16(); + } + } + + IF( ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ) + { + sts[ch]->hTcxEnc->fUseTns[k] = 1; + } + ELSE + { + sts[ch]->hTcxEnc->fUseTns[k] = 0; + } + move16(); + test(); + test(); + IF( !bWhitenedDomain && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + { + sts[ch]->hTcxEnc->fUseTns[k] = 0; + move16(); + sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; + move16(); + sts[ch]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); + sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; + move16(); + } + } + maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + } + } + } + + + /* we have the decision, set filter data accordingly */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; + + FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + STnsFilter *pFilter; + pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; + SWITCH( pFilter->filterType ) + { + case TNS_FILTER_OFF: + ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); + BREAK; + case TNS_FILTER_ON_ZERO: + /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */ + ClearTnsFilterCoefficients( pFilter ); + pFilter->order = 1; + move16(); + BREAK; + } + } + } + } + } + + /* Apply filters, loop over channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st = sts[ch]; + IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + test(); + test(); + IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */ + sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] && + sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] ) + { + Word16 equalFilterData = 0; + move16(); + test(); + test(); + if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) && + EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) && + EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + { + equalFilterData = 1; + move16(); + } + + IF( equalFilterData ) + { + FOR( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter]; + const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter]; + Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */ + + move16(); + test(); + WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) ) + { + test(); + i = sub( i, 1 ); + } + IF( i >= 0 ) + { + equalFilterData = 0; + move16(); + BREAK; + } + } + IF( equalFilterData ) + { + st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */ + move16(); + } + } + } + test(); + test(); + IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; + move16(); + spectrum_fx = st->hTcxEnc->spectrum_fx[k]; + /* If TNS should be used then get the residual after applying it inplace in the spectrum */ + IF( st->hTcxEnc->fUseTns[k] ) + { + st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; + + ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 ); + } + + IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) + { + tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC ); + } + + st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k]; + move16(); + EncodeTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k ); + } + + IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) + { + tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] ); + tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] ); + } + } + } + return; +} diff --git a/lib_enc/cod_uv.c b/lib_enc/cod_uv.c deleted file mode 100644 index 9e7ce9558..000000000 --- a/lib_enc/cod_uv.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/comvad_decision.c b/lib_enc/comvad_decision.c deleted file mode 100644 index efb9c1d78..000000000 --- a/lib_enc/comvad_decision.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/cor_shif.c b/lib_enc/cor_shif.c deleted file mode 100644 index 0e2004abf..000000000 --- a/lib_enc/cor_shif.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/core_enc_2div.c b/lib_enc/core_enc_2div.c deleted file mode 100644 index c899b52ff..000000000 --- a/lib_enc/core_enc_2div.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c deleted file mode 100644 index b0a1c880e..000000000 --- a/lib_enc/core_enc_init.c +++ /dev/null @@ -1,1055 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "options_warnings.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" - -#include "prot_fx.h" - -/*-----------------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------------*/ -static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); -static void init_core_sig_ana_ivas_fx( Encoder_State *st ); -static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ); -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ); -/*-----------------------------------------------------------------------* - * init_coder_ace_plus() - * - * Initialization of state variables - *-----------------------------------------------------------------------*/ -void init_coder_ace_plus_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - const Word32 last_total_brate, /* i : last total bitrate */ -#ifdef FIX_920_IGF_INIT_ERROR - const Word32 igf_brate, /* i : IGF configuration bitrate */ -#endif - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - Word16 L_frame_old; /*keep old frame size for switching */ - Word16 L_subfr; - - /* Bitrate */ - st->tcxonly = getTcxonly_ivas_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - move16(); - - /* Core Sampling Rate */ - st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); - st->fscale = sr2fscale_fx( st->sr_core ); - move32(); - move16(); - - /* Narrowband? */ - IF( EQ_16( st->bwidth, NB ) ) - { - st->narrowBand = 1; - move16(); - } - ELSE - { - st->narrowBand = 0; - move16(); - } - - /* Core Framing */ - L_frame_old = st->last_L_frame; - move16(); - st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - st->L_frame_past = -1; - move16(); - - IF( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - - IF( st->ini_frame == 0 ) - { - set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - hTcxEnc->acelp_zir = hTcxEnc->Txnq + L_FRAME / 2; - hTcxEnc->q_Txnq = Q15; - move16(); - hTcxEnc->tcx_target_bits_fac = ONE_IN_Q14; - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( ( st->element_mode == EVS_MONO && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, ACELP_32k ) ) || ( st->element_mode > EVS_MONO && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) ) - { - st->nb_subfr = NB_SUBFR16k; - move16(); - } - ELSE - { - st->nb_subfr = NB_SUBFR; - move16(); - } - L_subfr = idiv1616( st->L_frame, st->nb_subfr ); - - /* Core Lookahead */ - st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); - st->encoderLookahead_FB = NS2SA_FX2( st->input_Fs, ACELP_LOOK_NS ); - move16(); - move16(); - - IF( st->ini_frame == 0 ) - { - st->acelpFramesCount = 0; - move16(); - st->prevTempFlatness_fx = 128 /*1.0f Q7*/; - move16(); - } - - /* Initialize TBE */ - IF( st->hBWE_TD != NULL ) - { - st->hBWE_TD->prev_coder_type = GENERIC; - move16(); - set16_fx( st->hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); - st->hBWE_TD->prev_tilt_para_fx = 0; - move16(); - set16_fx( st->hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); - } - - st->currEnergyHF_fx = 0; - move32(); - st->currEnergyHF_e_fx = 0; - move16(); - test(); - /* Initialize LPC analysis/quantization */ - IF( LE_32( st->sr_core, INT_FS_16k ) && st->tcxonly == 0 ) - { - st->lpcQuantization = 1; - move16(); - } - ELSE - { - st->lpcQuantization = 0; - move16(); - } - - st->next_force_safety_net = 0; - move16(); - test(); - test(); - IF( ( NE_16( st->last_L_frame, st->L_frame ) ) || ( EQ_16( st->last_core, AMR_WB_CORE ) ) || ( EQ_16( st->last_core, HQ_CORE ) ) ) - { - set16_fx( st->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - } - - /* Initialize IGF */ - if ( st->hIGFEnc != NULL ) - { - st->hIGFEnc->infoStopFrequency = -1; - move16(); - } - - test(); - IF( st->igf && st->hIGFEnc != NULL ) - { -#ifdef FIX_920_IGF_INIT_ERROR - IGFEncSetMode_ivas_fx( st->hIGFEnc, igf_brate, st->bwidth, st->element_mode, st->rf_mode ); -#else - IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); -#endif - } - ELSE IF( st->hIGFEnc != NULL ) - { - st->hIGFEnc->infoTotalBitsWritten = 0; - move16(); - st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; - move16(); - } - - /* Initialize Core Signal Analysis Module */ - init_core_sig_ana_ivas_fx( st ); - - - /* Initialize TCX */ - IF( hTcxEnc != NULL ) - { - init_tcx_ivas_fx( st, L_frame_old, st->total_brate, last_total_brate, MCT_flag ); - } - - /* Initialize Signal Buffers */ - init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr, last_total_brate ); - - /* Initialize ACELP */ - - init_acelp_ivas_fx( st, L_frame_old, 0, last_total_brate ); - - if ( st->ini_frame == 0 ) - { - st->tec_tfa = 0; - move16(); - } - - IF( st->hTECEnc != NULL ) - { - resetTecEnc_Fx( st->hTECEnc, st->tec_tfa ); - } - - test(); - test(); - test(); - IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) - { - st->tec_tfa = 1; - move16(); - } - ELSE - { - st->tec_tfa = 0; - move16(); - } - - st->tec_flag = 0; - move16(); - st->tfa_flag = 0; - move16(); - - test(); - test(); - test(); - IF( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) - { - st->glr = 1; - move16(); - } - ELSE - { - st->glr = 0; - move16(); - } - - st->glr_reset = 0; - move16(); - - /* Initialize ACELP/TCX Modes */ - init_modes_ivas_fx( st, last_total_brate ); - - /* Adaptive BPF */ - set32_fx( st->mem_bpf_fx1, 0, 2 * L_FILT16k ); - set32_fx( st->mem_error_bpf_fx, 0, 2 * L_FILT16k ); - - IF( st->ini_frame == 0 ) - { - st->Q_max_enc[0] = 15; - move16(); - st->Q_max_enc[1] = 15; - move16(); - } - - IF( GE_32( st->total_brate, HQ_48k ) ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - ELSE - { - st->enablePlcWaveadjust = 0; - move16(); - } - - IF( st->hPlcExt ) - { - init_PLC_enc_fx( st->hPlcExt, st->sr_core ); - } - - st->glr_idx[0] = 0; - move16(); - st->glr_idx[1] = 0; - move16(); - st->mean_gc[0] = 0; - move16(); - st->mean_gc[1] = 0; - move16(); - st->prev_lsf4_mean = 0; - move16(); - st->last_stab_fac = 0; - move16(); - - return; -} - -/*-----------------------------------------------------------------------* - * init_tcx() - * - * Initialization of TCX - *-----------------------------------------------------------------------*/ - - -static void init_tcx_ivas_fx( - Encoder_State *st, - const Word16 L_frame_old, - const Word32 total_brate, - const Word32 last_total_brate, - const Word16 MCT_flag ) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ - hTcxEnc->spectrum_fx[0] = hTcxEnc->spectrum_long_fx; - hTcxEnc->spectrum_fx[1] = hTcxEnc->spectrum_long_fx + N_TCX10_MAX; - st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; - move16(); - move16(); - - init_tcx_cfg_ivas_fx( st->hTcxCfg, total_brate, st->sr_core, st->input_Fs, st->L_frame, st->bwidth, hTcxEnc->L_frameTCX, - st->fscale, st->preemph_fac, st->tcxonly, st->rf_mode, st->igf, - st->hIGFEnc != NULL ? st->hIGFEnc->infoStopFrequency : 0, st->element_mode, st->ini_frame, MCT_flag ); - - /* Init TCX target bits correction factor */ - hTcxEnc->tcx_target_bits_fac = 0x4000; /*1.0f in 1Q14*/ - move16(); - hTcxEnc->measuredBwRatio = 0x4000; /*1.0f in 1Q14*/ - move16(); - hTcxEnc->noiseTiltFactor = 9216; /*0.5625f in 1Q14*/ - move16(); - hTcxEnc->noiseLevelMemory_cnt = 0; - move16(); - - set16_fx( hTcxEnc->ltpGainMemory_fx, 0, N_LTP_GAIN_MEMS ); - set8_fx( hTcxEnc->memQuantZeros, 0, L_FRAME_PLUS ); - - /* TCX-LTP */ - hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); - move16(); - - test(); - test(); - test(); - test(); - IF( st->ini_frame == 0 ) - { - hTcxEnc->tcxltp_pitch_int_past = st->L_frame; - hTcxEnc->tcxltp_pitch_fr_past = 0; - hTcxEnc->tcxltp_gain_past = 0; - hTcxEnc->tcxltp_norm_corr_past = 0; - hTcxEnc->tcxltp_norm_corr_mem = 0; - hTcxEnc->kernel_switch_corr_past = 0; - hTcxEnc->kernel_symmetry_past = 0; /* MDCT_IV & 1 */ - hTcxEnc->enc_ste_pre_corr_past = 0; - hTcxEnc->tfm_mem_fx = 1610612736; /* 0.75 in Q31 */ - hTcxEnc->tcxltp_on_mem = 0; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } - ELSE IF( NE_16( st->L_frame, L_frame_old ) && !( ( GE_32( total_brate, ACELP_16k40 ) && LE_32( total_brate, ACELP_24k40 ) ) && - ( EQ_32( total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) - { - Word16 pitres, pitres_old; - Word16 pit, pit_old; - - pitres_old = 4; - move16(); - if ( EQ_16( 160, shr( L_frame_old, sub( 7, norm_s( L_frame_old ) ) ) ) ) /*if ( L_frame_old%160==0 )*/ - { - pitres_old = 6; - move16(); - } - - /*pit_old = (float)st->tcxltp_pitch_int_past + (float)st->tcxltp_pitch_fr_past/(float)pitres_old;*/ - pit_old = add( hTcxEnc->tcxltp_pitch_int_past, mult_r( hTcxEnc->tcxltp_pitch_fr_past, div_s( 1, pitres_old ) ) ); - - pitres = 4; - move16(); - if ( EQ_16( 160, shr( st->L_frame, sub( 7, norm_s( st->L_frame ) ) ) ) ) /*if ( st->L_frame%160==0 )*/ - { - pitres = 6; - move16(); - } - - /*pit = pit_old * (float)st->L_frame/(float)L_frame_old;*/ - pit = shl_sat( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); - /* Note : the saturation here that can happens when FS == 32kHz*/ - /* assert(pit <= st->L_frame);*/ - - hTcxEnc->tcxltp_pitch_int_past = pit; - move16(); - hTcxEnc->tcxltp_pitch_fr_past = i_mult2( sub( pit, hTcxEnc->tcxltp_pitch_int_past ), pitres ); - move16(); - } - - hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); - move16(); - - return; -} - -/*-----------------------------------------------------------------------* - * init_sig_buffers() - * - * Initialization of signal buffers - *-----------------------------------------------------------------------*/ -/*copy of evs function since it was static */ -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ) -{ - - LPD_state_HANDLE hLPDmem = st->hLPDmem; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Encoder Past Samples at encoder-sampling-rate */ - st->encoderPastSamples_enc = shr( imult1616( st->L_frame, 9 ), 4 ); - move16(); - - /* Initialize Signal Buffers and Pointers at encoder-sampling-rate */ - IF( st->ini_frame == 0 ) - { - set16_fx( st->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - st->exp_buf_speech_enc = 0; - move16(); - set16_fx( st->buf_speech_enc_pe, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - st->exp_buf_speech_enc_pe = 0; - move16(); - if ( hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->buf_speech_ltp, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - hTcxEnc->exp_buf_speech_ltp = 0; - move16(); - } - set16_fx( st->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); /* increased by 320 to avoid memory overlap in ivas_find_wsp_fx() and also to accomodate for the wspeech_enc */ - st->exp_buf_wspeech_enc = 0; - move16(); - } - ELSE - { - test(); - test(); - test(); - test(); - test(); - IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) - { - lerp( st->buf_speech_enc, st->buf_speech_enc, st->L_frame, L_frame_old ); - test(); - IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) /* condition should be checked again */ - { - Copy( st->buf_speech_enc, hTcxEnc->buf_speech_ltp, st->L_frame ); - Scale_sig( hTcxEnc->buf_speech_ltp, st->L_frame, sub( st->exp_buf_speech_enc, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(15-max(st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp)) - Scale_sig( hTcxEnc->buf_speech_ltp + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( hTcxEnc->exp_buf_speech_ltp, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(15-max(st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp)) - hTcxEnc->exp_buf_speech_ltp = s_max( hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); - move16(); - } - - // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); - st->exp_buf_wspeech_enc = st->exp_old_wsp; - move16(); - - /*Resamp buffers needed only for ACELP*/ - test(); - test(); - IF( EQ_16( st->L_frame, L_FRAME ) && !st->tcxonly ) - { - // Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - Copy( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); - /* SCaling to common exponent*/ - Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_12k8, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) - Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) - Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) - st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ); - move16(); - } - ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) && !st->tcxonly ) - { - lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); - Copy( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); - /* SCaling to common exponent*/ - Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_16k, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ); - move16(); - } - - st->mem_preemph_enc = st->buf_speech_enc[st->encoderPastSamples_enc + st->encoderLookahead_enc - 1]; - move16(); - st->exp_mem_preemph_enc = st->exp_buf_speech_enc; - move16(); - st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 - move16(); - } - /*coming from TCXonly modes*/ - ELSE IF( !st->tcxonly && GE_32( last_total_brate, ACELP_32k ) ) - { - - Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); - // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - st->exp_buf_wspeech_enc = st->exp_old_wsp; - move16(); /*Resamp buffers needed only for ACELP*/ - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); - } - hLPDmem->mem_w0 = 0; - move16(); - st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 - move16(); - } - } - - st->new_speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc + st->encoderLookahead_enc; - st->new_speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc + st->encoderLookahead_enc; - if ( hTcxEnc != NULL ) - { - hTcxEnc->new_speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc + st->encoderLookahead_enc; - } - - IF( st->hTcxEnc != NULL ) - { - st->hTcxEnc->new_speech_TCX = st->input_buff_fx + Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ); - st->hTcxEnc->speech_TCX = st->hTcxEnc->new_speech_TCX - st->encoderLookahead_FB; - } - st->speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc; - st->speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc; - - if ( hTcxEnc != NULL ) - { - hTcxEnc->speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc; - } - - IF( st->element_mode > EVS_MONO ) - { - st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_SUBFR; - } - ELSE - { - st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_subfr; - } - - test(); - test(); - IF( st->ini_frame == 0 || NE_16( st->L_frame, L_frame_old ) || EQ_16( st->last_codec_mode, MODE1 ) ) - { - set16_fx( st->buf_synth, 0, OLD_SYNTH_SIZE_ENC + L_FRAME32k ); - } - - st->synth = st->buf_synth + st->L_frame + L_subfr; - - - return; -} - -/*-----------------------------------------------------------------------* - * init_core_sig_ana() - * - * - *-----------------------------------------------------------------------*/ -static void init_core_sig_ana_ivas_fx( Encoder_State *st ) -{ - - /* Pre-emphasis factor and memory */ - - st->preemph_fac = PREEMPH_FAC_SWB; /*SWB*/ - move16(); - IF( LT_16( st->fscale, ( 16000 * FSCALE_DENOM ) / 12800 ) ) - { - st->preemph_fac = PREEMPH_FAC; /*WB*/ - move16(); - } - ELSE IF( LT_16( st->fscale, ( 24000 * FSCALE_DENOM ) / 12800 ) ) - { - st->preemph_fac = PREEMPH_FAC_16k; /*WB*/ - move16(); - } - - st->gamma = GAMMA1; - move16(); - st->inv_gamma = GAMMA1_INV; - move16(); - IF( EQ_32( st->sr_core, 16000 ) ) - { - st->gamma = GAMMA16k; - move16(); - st->inv_gamma = GAMMA16k_INV; - move16(); - } - - - st->min_band = 1; - move16(); - st->max_band = 16; - move16(); - - IF( st->narrowBand == 0 ) - { - st->min_band = 0; - move16(); - st->max_band = 19; - move16(); - } - - - return; -} -/*-----------------------------------------------------------------------* - * init_acelp() - * - * - *-----------------------------------------------------------------------*/ -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ) -{ - Word16 mem_syn_r_size_old; - Word16 mem_syn_r_size_new; - LPD_state_HANDLE hLPDmem = st->hLPDmem; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Init pitch lag */ - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - /* TCX LTP ana always runs @12.8kHz */ - st->pit_res_max = initPitchLagParameters( 12800, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); - move16(); - } - ELSE - { - st->pit_res_max = initPitchLagParameters( st->sr_core, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); - move16(); - } - - /* Init LPDmem */ - IF( st->ini_frame == 0 ) - { - IF( hLPDmem != NULL ) - { - set16_fx( hLPDmem->syn, 0, 1 + M ); - set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); - } - - IF( st->hTcxEnc != NULL ) - { - set16_fx( st->hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - st->hTcxEnc->q_Txnq = Q15; - move16(); - st->hTcxEnc->acelp_zir = st->hTcxEnc->Txnq + shr( st->L_frame, 1 ); - } - } - ELSE /*Rate switching*/ - { - IF( st->last_core == ACELP_CORE ) - { - lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, shr( st->L_frame, 1 ), shr( L_frame_old, 1 ) ); - } - ELSE - { - lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_length_old ); - } - hTcxEnc->acelp_zir = hTcxEnc->Txnq + shr( st->L_frame, 1 ); - - /* Rate switching */ - IF( EQ_16( st->last_codec_mode, MODE1 ) && st->element_mode == EVS_MONO ) - { - IF( hLPDmem != NULL ) - { - Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); - set16_fx( hLPDmem->syn, 0, M ); - hLPDmem->q_lpd_syn = Q15; - move16(); - } - IF( st->hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - st->hTcxEnc->q_Txnq = Q15; - move16(); - } - } - - /*AMR-WBIO->MODE2*/ - IF( EQ_16( st->last_core, AMR_WB_CORE ) ) - { - st->next_force_safety_net = 1; - move16(); - st->last_core = ACELP_CORE; - move16(); - } - /*HQ-CORE->MODE2*/ - test(); - IF( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->last_core, HQ_CORE ) ) - { - /*Reset of ACELP memories*/ - st->next_force_safety_net = 1; - move16(); - st->rate_switching_reset = 1; - move16(); - IF( hLPDmem != NULL ) - { - hLPDmem->tilt_code = TILT_CODE; - move16(); - set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); - set16_fx( hLPDmem->syn, 0, 1 + M ); - hLPDmem->q_lpd_syn = Q15; - move16(); - hLPDmem->q_lpd_old_exc = Q15; - move16(); - hLPDmem->mem_w0 = 0; - move16(); - set16_fx( hLPDmem->mem_syn, 0, M ); - set16_fx( hLPDmem->mem_syn2, 0, M ); - hLPDmem->q_mem_syn = Q15; - move16(); - } - - /* unquantized LPC*/ - test(); - test(); - test(); - IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) - { - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); - } - } - Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ - IF( st->tcxonly == 0 ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - ELSE - { - E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); - } - st->last_core = TCX_20_CORE; - move16(); - - st->hTcxCfg->last_aldo = 1; /*It was previously ALDO*/ - st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - move16(); - /*ALDO overlap windowed past: also used in MODE1 but for other MDCT-FB*/ - set16_fx( hTcxEnc->old_out_fx, 0, st->L_frame ); - } - ELSE - { - test(); - test(); - test(); - test(); - IF( ( NE_16( st->L_frame, L_frame_old ) ) && ( LE_16( st->L_frame, L_FRAME16k ) ) && ( LE_16( L_frame_old, L_FRAME16k ) ) ) - { - /* convert quantized LSP vector */ - st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); - move16(); - IF( st->tcxonly == 0 ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - ELSE - { - E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); - } - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); - } - ELSE - { - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); - } - - - /*Mem of deemphasis stay unchanged : hLPDmem->syn*/ - IF( hLPDmem != NULL ) - { - synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); - Word16 tmp, A[M + 1], Ap[M + 1], tmp_buf[M + 1]; - /* Update wsyn */ - /* lsp2a_stab( st->lsp_old, A, M ); */ - E_LPC_f_lsp_a_conversion( st->lsp_old_fx, A, M ); - weight_a_fx( A, Ap, GAMMA1, M ); - tmp = 0; - move16(); - tmp_buf[0] = 0; - move16(); - Copy( hLPDmem->mem_syn2, tmp_buf + 1, M ); - deemph_fx( tmp_buf + 1, st->preemph_fac, M, &tmp ); - Residu3_fx( Ap, tmp_buf + M, &tmp, 1, 1 ); - hLPDmem->mem_w0 = sub_sat( shr_sat( st->wspeech_enc[-1], shift ), tmp ); - move16(); - } - } - ELSE IF( ( NE_16( st->L_frame, L_frame_old ) ) ) - { - /*Partial reset of ACELP memories*/ - st->next_force_safety_net = 1; - move16(); - st->rate_switching_reset = 1; - move16(); - - /*reset partly some memories*/ - IF( hLPDmem != NULL ) - { - hLPDmem->tilt_code = TILT_CODE; - move16(); - set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); - move16(); - hLPDmem->q_lpd_old_exc = Q15; - move16(); - /*Resamp others memories*/ - /*Size of LPC syn memory*/ - /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ - mem_syn_r_size_old = shr( L_frame_old, 4 ); - mem_syn_r_size_new = shr( st->L_frame, 4 ); - - lerp( hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); - Copy( hLPDmem->mem_syn_r + L_SYN_MEM - M, hLPDmem->mem_syn, M ); - Copy( hLPDmem->mem_syn, hLPDmem->mem_syn2, M ); - - /*Untouched memories : hLPDmem->syn & hLPDmem->mem_w0*/ - hLPDmem->mem_w0 = 0; - move16(); - } - /* unquantized LPC*/ - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); - } - Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ - IF( st->tcxonly == 0 ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - ELSE - { - E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); - } - } - ELSE IF( !st->tcxonly && EQ_16( st->L_frame, L_FRAME16k ) && GT_32( st->last_total_brate, ACELP_32k ) ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - } - } - - test(); - test(); - if ( EQ_16( st->last_bwidth, NB ) && NE_16( st->bwidth, NB ) && st->ini_frame != 0 ) - { - st->rate_switching_reset = 1; - move16(); - } - - /* Post-processing */ - /*EVS specific*/ - /* hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); - set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); - hLPDmem->dm_fx.prev_state = 0;*/ - /*------------*/ - - if ( hLPDmem != NULL ) - { - hLPDmem->dm_fx.prev_state = 0; - move16(); /* This corresponds to st_fx->dispMem in FLP */ - hLPDmem->dm_fx.prev_gain_code = 0; - move32(); - - FOR( Word16 i = 2; i < 8; i++ ) - { - hLPDmem->dm_fx.prev_gain_pit[i - 2] = 0; - move16(); - } - hLPDmem->gc_threshold = 0; - move16(); - } - - /* Pulse Search configuration */ - st->acelp_autocorr = 1; - move16(); - - /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ - test(); - test(); - if ( ( LE_32( st->total_brate, ACELP_9k60 ) || EQ_16( st->rf_mode, 1 ) ) && ( EQ_32( st->sr_core, 12800 ) ) ) - { - st->acelp_autocorr = 0; - move16(); - } - - - /*BPF parameters for adjusting gain in function of background noise*/ - IF( EQ_16( st->codec_mode, MODE2 ) ) - { - st->mem_bpf_fx.lp_error_ener = L_deposit_l( 0 ); - move32(); - st->pst_lp_ener_fx = 0; - move16(); - IF( EQ_16( st->last_codec_mode, MODE1 ) ) - { - st->mem_bpf_fx.lp_error = 0; - move32(); - st->pst_mem_deemp_err_fx = 0; - move16(); - } - } - - return; -} -/*-----------------------------------------------------------------------* - * init_modes() - * - * - *-----------------------------------------------------------------------*/ - -static void init_modes_ivas_fx( - Encoder_State *st, - const Word32 last_total_brate ) -{ - Word8 n; - Word32 tmp32; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Restrict ACE/TCX20/TCX10 mode */ - move16(); - st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, st->Opt_AMR_WB ); - move16(); - st->acelpEnabled = 0; - move16(); - st->tcx20Enabled = 0; - move16(); - st->tcx10Enabled = 0; - - if ( EQ_16( s_and( st->restrictedMode, 1 ), 1 ) ) - { - st->acelpEnabled = 1; - move16(); - } - if ( EQ_16( s_and( st->restrictedMode, 2 ), 2 ) ) - { - st->tcx20Enabled = 1; - move16(); - } - if ( EQ_16( s_and( st->restrictedMode, 4 ), 4 ) ) - { - st->tcx10Enabled = 1; - move16(); - } - - /* TCX mode (TCX20 TCX10_10 or NO_TCX) */ - if ( st->hTcxEnc != NULL ) - { - hTcxEnc->tcxMode = NO_TCX; - move16(); - } - - /* Bits Budget */ - /*st->bits_frame_nominal = (int)( (float)st->L_frame * (float)FSCALE_DENOM * (float)st->bitrate / ( (float)st->fscale * 12800.0f ) );*/ - /*st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f );*/ - /*328 = 0.010009765625 in 0Q15*/ - /* st->bits_frame_nominal = extract_h(L_add(L_mult(div_l(L_mult(shl(st->L_frame,2),st->bitrate),st->fscale),328),16056)); */ - - /* st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f ); */ - tmp32 = L_shl( st->total_brate, 1 ); /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate */ - st->bits_frame_nominal = extract_l( L_shr( Mpy_32_16_1( tmp32, 20972 ), 6 ) ); /* 20972 = 0.01 * 64 * 32768 */ - move16(); - - IF( st->Opt_AMR_WB ) - { - st->bits_frame = st->bits_frame_nominal; - move16(); - st->bits_frame_core = st->bits_frame_nominal; - move16(); - st->frame_size_index = 0; - move16(); - } - ELSE - { - FOR( n = 0; n < FRAME_SIZE_NB; n++ ) - { - IF( LT_32( n, FRAME_SIZE_NB - 1 ) ) - { - test(); - IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) && GT_32( FrameSizeConfig[n + 1].frame_bits, st->bits_frame_nominal ) ) - { - st->frame_size_index = n; - move16(); - st->bits_frame = st->bits_frame_nominal; - move16(); - st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); - move16(); - BREAK; - } - } - ELSE - { - IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) ) - { - st->frame_size_index = n; - move16(); - st->bits_frame = st->bits_frame_nominal; - move16(); - st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); - move16(); - BREAK; - } - } - } - } - - /* Reconfigure core */ - core_coder_reconfig_ivas_fx( st, last_total_brate ); - - - return; -} diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 1f5b0df1e..4151725af 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -28,6 +28,11 @@ static void init_core_sig_ana_fx( Encoder_State *st ); static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 shift ); static void init_modes_fx( Encoder_State *st, const Word32 Last_total_brate ); static void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ); +static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); +static void init_core_sig_ana_ivas_fx( Encoder_State *st ); +static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ); +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ); /*-----------------------------------------------------------------------* * init_coder_ace_plus_fx() @@ -930,5 +935,1004 @@ static void init_modes_fx( core_coder_reconfig_fx( st, last_total_brate ); + return; +} + +/*-----------------------------------------------------------------------* + * init_coder_ace_plus() + * + * Initialization of state variables + *-----------------------------------------------------------------------*/ +void init_coder_ace_plus_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate */ +#ifdef FIX_920_IGF_INIT_ERROR + const Word32 igf_brate, /* i : IGF configuration bitrate */ +#endif + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 L_frame_old; /*keep old frame size for switching */ + Word16 L_subfr; + + /* Bitrate */ + st->tcxonly = getTcxonly_ivas_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + move16(); + + /* Core Sampling Rate */ + st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + st->fscale = sr2fscale_fx( st->sr_core ); + move32(); + move16(); + + /* Narrowband? */ + IF( EQ_16( st->bwidth, NB ) ) + { + st->narrowBand = 1; + move16(); + } + ELSE + { + st->narrowBand = 0; + move16(); + } + + /* Core Framing */ + L_frame_old = st->last_L_frame; + move16(); + st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + st->L_frame_past = -1; + move16(); + + IF( hTcxEnc != NULL ) + { + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + + IF( st->ini_frame == 0 ) + { + set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); + hTcxEnc->acelp_zir = hTcxEnc->Txnq + L_FRAME / 2; + hTcxEnc->q_Txnq = Q15; + move16(); + hTcxEnc->tcx_target_bits_fac = ONE_IN_Q14; + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + IF( ( st->element_mode == EVS_MONO && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, ACELP_32k ) ) || ( st->element_mode > EVS_MONO && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) ) + { + st->nb_subfr = NB_SUBFR16k; + move16(); + } + ELSE + { + st->nb_subfr = NB_SUBFR; + move16(); + } + L_subfr = idiv1616( st->L_frame, st->nb_subfr ); + + /* Core Lookahead */ + st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); + st->encoderLookahead_FB = NS2SA_FX2( st->input_Fs, ACELP_LOOK_NS ); + move16(); + move16(); + + IF( st->ini_frame == 0 ) + { + st->acelpFramesCount = 0; + move16(); + st->prevTempFlatness_fx = 128 /*1.0f Q7*/; + move16(); + } + + /* Initialize TBE */ + IF( st->hBWE_TD != NULL ) + { + st->hBWE_TD->prev_coder_type = GENERIC; + move16(); + set16_fx( st->hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); + st->hBWE_TD->prev_tilt_para_fx = 0; + move16(); + set16_fx( st->hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); + } + + st->currEnergyHF_fx = 0; + move32(); + st->currEnergyHF_e_fx = 0; + move16(); + test(); + /* Initialize LPC analysis/quantization */ + IF( LE_32( st->sr_core, INT_FS_16k ) && st->tcxonly == 0 ) + { + st->lpcQuantization = 1; + move16(); + } + ELSE + { + st->lpcQuantization = 0; + move16(); + } + + st->next_force_safety_net = 0; + move16(); + test(); + test(); + IF( ( NE_16( st->last_L_frame, st->L_frame ) ) || ( EQ_16( st->last_core, AMR_WB_CORE ) ) || ( EQ_16( st->last_core, HQ_CORE ) ) ) + { + set16_fx( st->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + } + + /* Initialize IGF */ + if ( st->hIGFEnc != NULL ) + { + st->hIGFEnc->infoStopFrequency = -1; + move16(); + } + + test(); + IF( st->igf && st->hIGFEnc != NULL ) + { +#ifdef FIX_920_IGF_INIT_ERROR + IGFEncSetMode_ivas_fx( st->hIGFEnc, igf_brate, st->bwidth, st->element_mode, st->rf_mode ); +#else + IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); +#endif + } + ELSE IF( st->hIGFEnc != NULL ) + { + st->hIGFEnc->infoTotalBitsWritten = 0; + move16(); + st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; + move16(); + } + + /* Initialize Core Signal Analysis Module */ + init_core_sig_ana_ivas_fx( st ); + + + /* Initialize TCX */ + IF( hTcxEnc != NULL ) + { + init_tcx_ivas_fx( st, L_frame_old, st->total_brate, last_total_brate, MCT_flag ); + } + + /* Initialize Signal Buffers */ + init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr, last_total_brate ); + + /* Initialize ACELP */ + + init_acelp_ivas_fx( st, L_frame_old, 0, last_total_brate ); + + if ( st->ini_frame == 0 ) + { + st->tec_tfa = 0; + move16(); + } + + IF( st->hTECEnc != NULL ) + { + resetTecEnc_Fx( st->hTECEnc, st->tec_tfa ); + } + + test(); + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) + { + st->tec_tfa = 1; + move16(); + } + ELSE + { + st->tec_tfa = 0; + move16(); + } + + st->tec_flag = 0; + move16(); + st->tfa_flag = 0; + move16(); + + test(); + test(); + test(); + IF( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) + { + st->glr = 1; + move16(); + } + ELSE + { + st->glr = 0; + move16(); + } + + st->glr_reset = 0; + move16(); + + /* Initialize ACELP/TCX Modes */ + init_modes_ivas_fx( st, last_total_brate ); + + /* Adaptive BPF */ + set32_fx( st->mem_bpf_fx1, 0, 2 * L_FILT16k ); + set32_fx( st->mem_error_bpf_fx, 0, 2 * L_FILT16k ); + + IF( st->ini_frame == 0 ) + { + st->Q_max_enc[0] = 15; + move16(); + st->Q_max_enc[1] = 15; + move16(); + } + + IF( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + ELSE + { + st->enablePlcWaveadjust = 0; + move16(); + } + + IF( st->hPlcExt ) + { + init_PLC_enc_fx( st->hPlcExt, st->sr_core ); + } + + st->glr_idx[0] = 0; + move16(); + st->glr_idx[1] = 0; + move16(); + st->mean_gc[0] = 0; + move16(); + st->mean_gc[1] = 0; + move16(); + st->prev_lsf4_mean = 0; + move16(); + st->last_stab_fac = 0; + move16(); + + return; +} + +/*-----------------------------------------------------------------------* + * init_tcx() + * + * Initialization of TCX + *-----------------------------------------------------------------------*/ + + +static void init_tcx_ivas_fx( + Encoder_State *st, + const Word16 L_frame_old, + const Word32 total_brate, + const Word32 last_total_brate, + const Word16 MCT_flag ) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ + hTcxEnc->spectrum_fx[0] = hTcxEnc->spectrum_long_fx; + hTcxEnc->spectrum_fx[1] = hTcxEnc->spectrum_long_fx + N_TCX10_MAX; + st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; + move16(); + move16(); + + init_tcx_cfg_ivas_fx( st->hTcxCfg, total_brate, st->sr_core, st->input_Fs, st->L_frame, st->bwidth, hTcxEnc->L_frameTCX, + st->fscale, st->preemph_fac, st->tcxonly, st->rf_mode, st->igf, + st->hIGFEnc != NULL ? st->hIGFEnc->infoStopFrequency : 0, st->element_mode, st->ini_frame, MCT_flag ); + + /* Init TCX target bits correction factor */ + hTcxEnc->tcx_target_bits_fac = 0x4000; /*1.0f in 1Q14*/ + move16(); + hTcxEnc->measuredBwRatio = 0x4000; /*1.0f in 1Q14*/ + move16(); + hTcxEnc->noiseTiltFactor = 9216; /*0.5625f in 1Q14*/ + move16(); + hTcxEnc->noiseLevelMemory_cnt = 0; + move16(); + + set16_fx( hTcxEnc->ltpGainMemory_fx, 0, N_LTP_GAIN_MEMS ); + set8_fx( hTcxEnc->memQuantZeros, 0, L_FRAME_PLUS ); + + /* TCX-LTP */ + hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); + move16(); + + test(); + test(); + test(); + test(); + IF( st->ini_frame == 0 ) + { + hTcxEnc->tcxltp_pitch_int_past = st->L_frame; + hTcxEnc->tcxltp_pitch_fr_past = 0; + hTcxEnc->tcxltp_gain_past = 0; + hTcxEnc->tcxltp_norm_corr_past = 0; + hTcxEnc->tcxltp_norm_corr_mem = 0; + hTcxEnc->kernel_switch_corr_past = 0; + hTcxEnc->kernel_symmetry_past = 0; /* MDCT_IV & 1 */ + hTcxEnc->enc_ste_pre_corr_past = 0; + hTcxEnc->tfm_mem_fx = 1610612736; /* 0.75 in Q31 */ + hTcxEnc->tcxltp_on_mem = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + ELSE IF( NE_16( st->L_frame, L_frame_old ) && !( ( GE_32( total_brate, ACELP_16k40 ) && LE_32( total_brate, ACELP_24k40 ) ) && + ( EQ_32( total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + { + Word16 pitres, pitres_old; + Word16 pit, pit_old; + + pitres_old = 4; + move16(); + if ( EQ_16( 160, shr( L_frame_old, sub( 7, norm_s( L_frame_old ) ) ) ) ) /*if ( L_frame_old%160==0 )*/ + { + pitres_old = 6; + move16(); + } + + /*pit_old = (float)st->tcxltp_pitch_int_past + (float)st->tcxltp_pitch_fr_past/(float)pitres_old;*/ + pit_old = add( hTcxEnc->tcxltp_pitch_int_past, mult_r( hTcxEnc->tcxltp_pitch_fr_past, div_s( 1, pitres_old ) ) ); + + pitres = 4; + move16(); + if ( EQ_16( 160, shr( st->L_frame, sub( 7, norm_s( st->L_frame ) ) ) ) ) /*if ( st->L_frame%160==0 )*/ + { + pitres = 6; + move16(); + } + + /*pit = pit_old * (float)st->L_frame/(float)L_frame_old;*/ + pit = shl_sat( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); + /* Note : the saturation here that can happens when FS == 32kHz*/ + /* assert(pit <= st->L_frame);*/ + + hTcxEnc->tcxltp_pitch_int_past = pit; + move16(); + hTcxEnc->tcxltp_pitch_fr_past = i_mult2( sub( pit, hTcxEnc->tcxltp_pitch_int_past ), pitres ); + move16(); + } + + hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); + move16(); + + return; +} + +/*-----------------------------------------------------------------------* + * init_sig_buffers() + * + * Initialization of signal buffers + *-----------------------------------------------------------------------*/ +/*copy of evs function since it was static */ +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ) +{ + + LPD_state_HANDLE hLPDmem = st->hLPDmem; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Encoder Past Samples at encoder-sampling-rate */ + st->encoderPastSamples_enc = shr( imult1616( st->L_frame, 9 ), 4 ); + move16(); + + /* Initialize Signal Buffers and Pointers at encoder-sampling-rate */ + IF( st->ini_frame == 0 ) + { + set16_fx( st->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + st->exp_buf_speech_enc = 0; + move16(); + set16_fx( st->buf_speech_enc_pe, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + st->exp_buf_speech_enc_pe = 0; + move16(); + if ( hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->buf_speech_ltp, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + hTcxEnc->exp_buf_speech_ltp = 0; + move16(); + } + set16_fx( st->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); /* increased by 320 to avoid memory overlap in ivas_find_wsp_fx() and also to accomodate for the wspeech_enc */ + st->exp_buf_wspeech_enc = 0; + move16(); + } + ELSE + { + test(); + test(); + test(); + test(); + test(); + IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + { + lerp( st->buf_speech_enc, st->buf_speech_enc, st->L_frame, L_frame_old ); + test(); + IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) /* condition should be checked again */ + { + Copy( st->buf_speech_enc, hTcxEnc->buf_speech_ltp, st->L_frame ); + Scale_sig( hTcxEnc->buf_speech_ltp, st->L_frame, sub( st->exp_buf_speech_enc, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(15-max(st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp)) + Scale_sig( hTcxEnc->buf_speech_ltp + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( hTcxEnc->exp_buf_speech_ltp, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(15-max(st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp)) + hTcxEnc->exp_buf_speech_ltp = s_max( hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); + move16(); + } + + // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); + st->exp_buf_wspeech_enc = st->exp_old_wsp; + move16(); + + /*Resamp buffers needed only for ACELP*/ + test(); + test(); + IF( EQ_16( st->L_frame, L_FRAME ) && !st->tcxonly ) + { + // Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Copy( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); + /* SCaling to common exponent*/ + Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_12k8, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) + Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) + Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) + st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ); + move16(); + } + ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) && !st->tcxonly ) + { + lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); + Copy( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); + /* SCaling to common exponent*/ + Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_16k, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); + Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); + Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); + st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ); + move16(); + } + + st->mem_preemph_enc = st->buf_speech_enc[st->encoderPastSamples_enc + st->encoderLookahead_enc - 1]; + move16(); + st->exp_mem_preemph_enc = st->exp_buf_speech_enc; + move16(); + st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 + move16(); + } + /*coming from TCXonly modes*/ + ELSE IF( !st->tcxonly && GE_32( last_total_brate, ACELP_32k ) ) + { + + Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); + // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + st->exp_buf_wspeech_enc = st->exp_old_wsp; + move16(); /*Resamp buffers needed only for ACELP*/ + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); + } + hLPDmem->mem_w0 = 0; + move16(); + st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 + move16(); + } + } + + st->new_speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc + st->encoderLookahead_enc; + st->new_speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc + st->encoderLookahead_enc; + if ( hTcxEnc != NULL ) + { + hTcxEnc->new_speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc + st->encoderLookahead_enc; + } + + IF( st->hTcxEnc != NULL ) + { + st->hTcxEnc->new_speech_TCX = st->input_buff_fx + Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ); + st->hTcxEnc->speech_TCX = st->hTcxEnc->new_speech_TCX - st->encoderLookahead_FB; + } + st->speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc; + st->speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc; + + if ( hTcxEnc != NULL ) + { + hTcxEnc->speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc; + } + + IF( st->element_mode > EVS_MONO ) + { + st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_SUBFR; + } + ELSE + { + st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_subfr; + } + + test(); + test(); + IF( st->ini_frame == 0 || NE_16( st->L_frame, L_frame_old ) || EQ_16( st->last_codec_mode, MODE1 ) ) + { + set16_fx( st->buf_synth, 0, OLD_SYNTH_SIZE_ENC + L_FRAME32k ); + } + + st->synth = st->buf_synth + st->L_frame + L_subfr; + + + return; +} + +/*-----------------------------------------------------------------------* + * init_core_sig_ana() + * + * + *-----------------------------------------------------------------------*/ +static void init_core_sig_ana_ivas_fx( Encoder_State *st ) +{ + + /* Pre-emphasis factor and memory */ + + st->preemph_fac = PREEMPH_FAC_SWB; /*SWB*/ + move16(); + IF( LT_16( st->fscale, ( 16000 * FSCALE_DENOM ) / 12800 ) ) + { + st->preemph_fac = PREEMPH_FAC; /*WB*/ + move16(); + } + ELSE IF( LT_16( st->fscale, ( 24000 * FSCALE_DENOM ) / 12800 ) ) + { + st->preemph_fac = PREEMPH_FAC_16k; /*WB*/ + move16(); + } + + st->gamma = GAMMA1; + move16(); + st->inv_gamma = GAMMA1_INV; + move16(); + IF( EQ_32( st->sr_core, 16000 ) ) + { + st->gamma = GAMMA16k; + move16(); + st->inv_gamma = GAMMA16k_INV; + move16(); + } + + + st->min_band = 1; + move16(); + st->max_band = 16; + move16(); + + IF( st->narrowBand == 0 ) + { + st->min_band = 0; + move16(); + st->max_band = 19; + move16(); + } + + + return; +} +/*-----------------------------------------------------------------------* + * init_acelp() + * + * + *-----------------------------------------------------------------------*/ +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ) +{ + Word16 mem_syn_r_size_old; + Word16 mem_syn_r_size_new; + LPD_state_HANDLE hLPDmem = st->hLPDmem; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Init pitch lag */ + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + /* TCX LTP ana always runs @12.8kHz */ + st->pit_res_max = initPitchLagParameters( 12800, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); + move16(); + } + ELSE + { + st->pit_res_max = initPitchLagParameters( st->sr_core, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); + move16(); + } + + /* Init LPDmem */ + IF( st->ini_frame == 0 ) + { + IF( hLPDmem != NULL ) + { + set16_fx( hLPDmem->syn, 0, 1 + M ); + set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); + } + + IF( st->hTcxEnc != NULL ) + { + set16_fx( st->hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); + st->hTcxEnc->q_Txnq = Q15; + move16(); + st->hTcxEnc->acelp_zir = st->hTcxEnc->Txnq + shr( st->L_frame, 1 ); + } + } + ELSE /*Rate switching*/ + { + IF( st->last_core == ACELP_CORE ) + { + lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, shr( st->L_frame, 1 ), shr( L_frame_old, 1 ) ); + } + ELSE + { + lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_length_old ); + } + hTcxEnc->acelp_zir = hTcxEnc->Txnq + shr( st->L_frame, 1 ); + + /* Rate switching */ + IF( EQ_16( st->last_codec_mode, MODE1 ) && st->element_mode == EVS_MONO ) + { + IF( hLPDmem != NULL ) + { + Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); + set16_fx( hLPDmem->syn, 0, M ); + hLPDmem->q_lpd_syn = Q15; + move16(); + } + IF( st->hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); + st->hTcxEnc->q_Txnq = Q15; + move16(); + } + } + + /*AMR-WBIO->MODE2*/ + IF( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + st->next_force_safety_net = 1; + move16(); + st->last_core = ACELP_CORE; + move16(); + } + /*HQ-CORE->MODE2*/ + test(); + IF( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->last_core, HQ_CORE ) ) + { + /*Reset of ACELP memories*/ + st->next_force_safety_net = 1; + move16(); + st->rate_switching_reset = 1; + move16(); + IF( hLPDmem != NULL ) + { + hLPDmem->tilt_code = TILT_CODE; + move16(); + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + set16_fx( hLPDmem->syn, 0, 1 + M ); + hLPDmem->q_lpd_syn = Q15; + move16(); + hLPDmem->q_lpd_old_exc = Q15; + move16(); + hLPDmem->mem_w0 = 0; + move16(); + set16_fx( hLPDmem->mem_syn, 0, M ); + set16_fx( hLPDmem->mem_syn2, 0, M ); + hLPDmem->q_mem_syn = Q15; + move16(); + } + + /* unquantized LPC*/ + test(); + test(); + test(); + IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + { + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); + } + } + Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + st->last_core = TCX_20_CORE; + move16(); + + st->hTcxCfg->last_aldo = 1; /*It was previously ALDO*/ + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + move16(); + /*ALDO overlap windowed past: also used in MODE1 but for other MDCT-FB*/ + set16_fx( hTcxEnc->old_out_fx, 0, st->L_frame ); + } + ELSE + { + test(); + test(); + test(); + test(); + IF( ( NE_16( st->L_frame, L_frame_old ) ) && ( LE_16( st->L_frame, L_FRAME16k ) ) && ( LE_16( L_frame_old, L_FRAME16k ) ) ) + { + /* convert quantized LSP vector */ + st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); + move16(); + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); + } + ELSE + { + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); + } + + + /*Mem of deemphasis stay unchanged : hLPDmem->syn*/ + IF( hLPDmem != NULL ) + { + synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); + Word16 tmp, A[M + 1], Ap[M + 1], tmp_buf[M + 1]; + /* Update wsyn */ + /* lsp2a_stab( st->lsp_old, A, M ); */ + E_LPC_f_lsp_a_conversion( st->lsp_old_fx, A, M ); + weight_a_fx( A, Ap, GAMMA1, M ); + tmp = 0; + move16(); + tmp_buf[0] = 0; + move16(); + Copy( hLPDmem->mem_syn2, tmp_buf + 1, M ); + deemph_fx( tmp_buf + 1, st->preemph_fac, M, &tmp ); + Residu3_fx( Ap, tmp_buf + M, &tmp, 1, 1 ); + hLPDmem->mem_w0 = sub_sat( shr_sat( st->wspeech_enc[-1], shift ), tmp ); + move16(); + } + } + ELSE IF( ( NE_16( st->L_frame, L_frame_old ) ) ) + { + /*Partial reset of ACELP memories*/ + st->next_force_safety_net = 1; + move16(); + st->rate_switching_reset = 1; + move16(); + + /*reset partly some memories*/ + IF( hLPDmem != NULL ) + { + hLPDmem->tilt_code = TILT_CODE; + move16(); + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + move16(); + hLPDmem->q_lpd_old_exc = Q15; + move16(); + /*Resamp others memories*/ + /*Size of LPC syn memory*/ + /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ + mem_syn_r_size_old = shr( L_frame_old, 4 ); + mem_syn_r_size_new = shr( st->L_frame, 4 ); + + lerp( hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + Copy( hLPDmem->mem_syn_r + L_SYN_MEM - M, hLPDmem->mem_syn, M ); + Copy( hLPDmem->mem_syn, hLPDmem->mem_syn2, M ); + + /*Untouched memories : hLPDmem->syn & hLPDmem->mem_w0*/ + hLPDmem->mem_w0 = 0; + move16(); + } + /* unquantized LPC*/ + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); + } + Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + } + ELSE IF( !st->tcxonly && EQ_16( st->L_frame, L_FRAME16k ) && GT_32( st->last_total_brate, ACELP_32k ) ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + } + } + + test(); + test(); + if ( EQ_16( st->last_bwidth, NB ) && NE_16( st->bwidth, NB ) && st->ini_frame != 0 ) + { + st->rate_switching_reset = 1; + move16(); + } + + /* Post-processing */ + /*EVS specific*/ + /* hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0;*/ + /*------------*/ + + if ( hLPDmem != NULL ) + { + hLPDmem->dm_fx.prev_state = 0; + move16(); /* This corresponds to st_fx->dispMem in FLP */ + hLPDmem->dm_fx.prev_gain_code = 0; + move32(); + + FOR( Word16 i = 2; i < 8; i++ ) + { + hLPDmem->dm_fx.prev_gain_pit[i - 2] = 0; + move16(); + } + hLPDmem->gc_threshold = 0; + move16(); + } + + /* Pulse Search configuration */ + st->acelp_autocorr = 1; + move16(); + + /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ + test(); + test(); + if ( ( LE_32( st->total_brate, ACELP_9k60 ) || EQ_16( st->rf_mode, 1 ) ) && ( EQ_32( st->sr_core, 12800 ) ) ) + { + st->acelp_autocorr = 0; + move16(); + } + + + /*BPF parameters for adjusting gain in function of background noise*/ + IF( EQ_16( st->codec_mode, MODE2 ) ) + { + st->mem_bpf_fx.lp_error_ener = L_deposit_l( 0 ); + move32(); + st->pst_lp_ener_fx = 0; + move16(); + IF( EQ_16( st->last_codec_mode, MODE1 ) ) + { + st->mem_bpf_fx.lp_error = 0; + move32(); + st->pst_mem_deemp_err_fx = 0; + move16(); + } + } + + return; +} +/*-----------------------------------------------------------------------* + * init_modes() + * + * + *-----------------------------------------------------------------------*/ + +static void init_modes_ivas_fx( + Encoder_State *st, + const Word32 last_total_brate ) +{ + Word8 n; + Word32 tmp32; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Restrict ACE/TCX20/TCX10 mode */ + move16(); + st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, st->Opt_AMR_WB ); + move16(); + st->acelpEnabled = 0; + move16(); + st->tcx20Enabled = 0; + move16(); + st->tcx10Enabled = 0; + + if ( EQ_16( s_and( st->restrictedMode, 1 ), 1 ) ) + { + st->acelpEnabled = 1; + move16(); + } + if ( EQ_16( s_and( st->restrictedMode, 2 ), 2 ) ) + { + st->tcx20Enabled = 1; + move16(); + } + if ( EQ_16( s_and( st->restrictedMode, 4 ), 4 ) ) + { + st->tcx10Enabled = 1; + move16(); + } + + /* TCX mode (TCX20 TCX10_10 or NO_TCX) */ + if ( st->hTcxEnc != NULL ) + { + hTcxEnc->tcxMode = NO_TCX; + move16(); + } + + /* Bits Budget */ + /*st->bits_frame_nominal = (int)( (float)st->L_frame * (float)FSCALE_DENOM * (float)st->bitrate / ( (float)st->fscale * 12800.0f ) );*/ + /*st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f );*/ + /*328 = 0.010009765625 in 0Q15*/ + /* st->bits_frame_nominal = extract_h(L_add(L_mult(div_l(L_mult(shl(st->L_frame,2),st->bitrate),st->fscale),328),16056)); */ + + /* st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f ); */ + tmp32 = L_shl( st->total_brate, 1 ); /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate */ + st->bits_frame_nominal = extract_l( L_shr( Mpy_32_16_1( tmp32, 20972 ), 6 ) ); /* 20972 = 0.01 * 64 * 32768 */ + move16(); + + IF( st->Opt_AMR_WB ) + { + st->bits_frame = st->bits_frame_nominal; + move16(); + st->bits_frame_core = st->bits_frame_nominal; + move16(); + st->frame_size_index = 0; + move16(); + } + ELSE + { + FOR( n = 0; n < FRAME_SIZE_NB; n++ ) + { + IF( LT_32( n, FRAME_SIZE_NB - 1 ) ) + { + test(); + IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) && GT_32( FrameSizeConfig[n + 1].frame_bits, st->bits_frame_nominal ) ) + { + st->frame_size_index = n; + move16(); + st->bits_frame = st->bits_frame_nominal; + move16(); + st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); + move16(); + BREAK; + } + } + ELSE + { + IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) ) + { + st->frame_size_index = n; + move16(); + st->bits_frame = st->bits_frame_nominal; + move16(); + st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); + move16(); + BREAK; + } + } + } + } + + /* Reconfigure core */ + core_coder_reconfig_ivas_fx( st, last_total_brate ); + + return; } diff --git a/lib_enc/core_enc_ol.c b/lib_enc/core_enc_ol.c deleted file mode 100644 index c282f7649..000000000 --- a/lib_enc/core_enc_ol.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" diff --git a/lib_enc/core_enc_reconf.c b/lib_enc/core_enc_reconf.c deleted file mode 100644 index 2bffd1728..000000000 --- a/lib_enc/core_enc_reconf.c +++ /dev/null @@ -1,346 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-----------------------------------------------------------------* - * Funtion core_coder_reconfig * - * ~~~~~~~~~~~~~~~~~~~ * - * - reconfig core coder when switching to another frame type * - *-----------------------------------------------------------------*/ - -void core_coder_reconfig_ivas_fx( - Encoder_State *st, - const int32_t last_total_brate ) -{ - Word16 i, bwidth, index; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - /*Configuration of ACELP*/ - BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); - - /*Configuration of partial copy*/ - IF( st->Opt_RF_ON ) - { - st->hRF->acelp_cfg_rf.mode_index = 1; - st->hRF->acelp_cfg_rf.midLpc = 0; - st->hRF->acelp_cfg_rf.midLpc_enable = 0; - st->hRF->acelp_cfg_rf.pre_emphasis = 0; - st->hRF->acelp_cfg_rf.formant_enh = 1; - st->hRF->acelp_cfg_rf.formant_tilt = 1; - st->hRF->acelp_cfg_rf.voice_tilt = 1; - st->hRF->acelp_cfg_rf.formant_enh_num = FORMANT_SHARPENING_G1; - st->hRF->acelp_cfg_rf.formant_enh_den = FORMANT_SHARPENING_G2; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->nb_bits_header_tcx = 2; /* signal class */ - move16(); - } - ELSE IF( st->tcxonly ) - { - st->nb_bits_header_tcx = 1 + 1; /*TCX20/TCX10 + last_core*/ - st->nb_bits_header_tcx = add( st->nb_bits_header_tcx, 2 ); /* Siganl class*/ - move16(); - move16(); - } - ELSE - { - st->nb_bits_header_ace = 1 + 2 + 1; /*TCX/ACELP+coder_type + last_core*/ - st->nb_bits_header_tcx = st->nb_bits_header_ace; - move16(); - move16(); - - IF( st->hTcxCfg != NULL ) - { - IF( st->hTcxCfg->lfacNext <= 0 ) - { - st->nb_bits_header_ace = sub( st->nb_bits_header_ace, 1 ); /*No last_core*/ - move16(); - } - } - } - - - /*Switch off TCX or ACELP?*/ - IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) - { - st->acelpEnabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 1 ) ), 1 ) ); - st->tcx20Enabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 2 ) ), 2 ) ); - move16(); - move16(); - } - st->prevEnergyHF_fx = st->currEnergyHF_fx = 1073725440l /*65535.0f Q14*/; /* prevent block switch */ - st->currEnergyHF_e_fx = 17; - move32(); - move16(); - - /*Sanity check : don't need to be instrumented*/ - IF( st->tcxonly == 0 ) - { - assert( st->acelpEnabled || st->tcx20Enabled || st->frame_size_index == 0 ); - } - ELSE - { - assert( st->tcx10Enabled || st->tcx20Enabled || st->frame_size_index == 0 ); - } - - /* TCX-LTP */ - IF( st->hTcxEnc != NULL ) - { - hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); - move16(); - } - - /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ - - st->acelp_autocorr = 1; - move16(); - - test(); - if ( ( LE_32( st->total_brate, ACELP_9k60 ) ) && ( EQ_32( st->sr_core, INT_FS_12k8 ) ) ) - { - st->acelp_autocorr = 0; - move16(); - } - - /*Get bandwidth mode*/ - IF( st->narrowBand ) - { - move16(); - bwidth = NB; - } - ELSE IF( LE_32( st->sr_core, INT_FS_16k ) ) - { - move16(); - bwidth = WB; - } - ELSE - { - move16(); - bwidth = SWB; - } - - /*Scale TCX for non-active frames to adjust loudness with ACELP*/ - IF( st->hTcxCfg != NULL ) - { - st->hTcxCfg->na_scale = 32767 /*1.0f Q15*/; - move16(); - - test(); - IF( LT_16( bwidth, 2 ) && ( st->tcxonly == 0 ) ) - { - /*const Word16 scaleTableSize = sizeof(scaleTcxTable) / sizeof(scaleTcxTable[0]);*/ - - FOR( i = 0; i < SIZE_SCALE_TABLE_TCX; i++ ) - { - - test(); - test(); - IF( EQ_16( bwidth, scaleTcxTable[i].bwmode ) && - GE_32( st->total_brate, scaleTcxTable[i].bitrateFrom ) && - LT_32( st->total_brate, scaleTcxTable[i].bitrateTo ) ) - { - if ( st->rf_mode ) - { - i = sub( i, 1 ); - } - move16(); - st->hTcxCfg->na_scale = scaleTcxTable[i].scale; - BREAK; - } - } - } - } - st->enableTcxLpc = 0; - move16(); - IF( GT_16( st->element_mode, IVAS_SCE ) ) - { - test(); - test(); - st->enableTcxLpc = ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR_CPE ) || st->rf_mode ) ); - move16(); - } - ELSE - { - test(); - test(); - if ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR ) || st->rf_mode != 0 ) ) - { - st->enableTcxLpc = 1; - move16(); - } - } - test(); - IF( st->ini_frame == 0 || EQ_16( st->last_codec_mode, MODE1 ) ) - { - st->envWeighted = 0; - move16(); - } - - test(); - test(); - test(); - IF( EQ_16( st->bwidth, SWB ) && - ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) - { - IF( st->tec_tfa == 0 ) - { - FOR( i = 0; i < MAX_TEC_SMOOTHING_DEG; i++ ) - { - st->hTECEnc->loBuffer[i] = 0; - move16(); - } - } - st->tec_tfa = 1; - move16(); - } - ELSE - { - st->tec_tfa = 0; - move16(); - } - - st->enablePlcWaveadjust = 0; - move16(); - if ( GE_32( st->total_brate, HQ_48k ) ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - - - move16(); - st->glr = 0; - test(); - test(); - test(); - if ( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( st->element_mode == EVS_MONO ) ) - { - move16(); - st->glr = 1; - } - - IF( st->glr ) - { - move16(); - st->nb_bits_header_ace = add( st->nb_bits_header_ace, G_LPC_RECOVERY_BITS ); - } - IF( hTcxEnc != NULL ) - { - test(); - IF( EQ_16( st->bwidth, NB ) || EQ_16( st->bwidth, WB ) ) - { - IF( st->rf_mode == 0 ) - { - index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index ) ); - } - ELSE - { - index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index - 1 ) ); - } - hTcxEnc->nmStartLine = startLineWB[index]; - move16(); - } - ELSE /* (st->bwidth == SWB || st->bwidth == FB) */ - { - IF( st->rf_mode == 0 ) - { - index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index ), 3 ) ); - } - ELSE - { - index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index - 1 ), 3 ) ); - } - test(); - test(); - if ( GE_32( st->total_brate, IVAS_96k ) && LE_32( st->total_brate, IVAS_192k ) && GT_16( st->element_mode, IVAS_SCE ) ) - { - index = sub( index, 1 ); - } - hTcxEnc->nmStartLine = startLineSWB[index]; - move16(); - test(); - test(); - IF( EQ_32( st->total_brate, IVAS_48k ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LT_16( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), shl( st->L_frame, 2 ) ) ) - { - hTcxEnc->nmStartLine = shr( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), 2 ); /* low-rate stereo is more efficient than dual-mono due to stereo processing */ - move16(); - } - } - } - - IF( hTcxEnc != NULL ) - { - test(); - test(); - test(); - test(); - test(); - IF( ( LT_32( st->total_brate, ACELP_24k40 ) ) && ( ( GT_32( st->total_brate, last_total_brate ) ) || ( EQ_16( st->last_codec_mode, MODE1 ) ) ) ) - { - /* low-freq memQuantZeros_fx must be reset partially if bitrate increased */ - FOR( i = 0; i < hTcxEnc->nmStartLine; i++ ) - { - hTcxEnc->memQuantZeros[i] = 0; - move16(); - } - } - ELSE IF( ( GE_32( st->total_brate, ACELP_24k40 ) ) && ( LE_32( st->total_brate, ACELP_32k ) ) && ( GE_32( last_total_brate, ACELP_13k20 ) ) && ( LT_32( last_total_brate, ACELP_24k40 ) ) ) - { - FOR( i = 0; i < st->L_frame; i++ ) /* memQuantZeros_fx won't be updated */ - { - hTcxEnc->memQuantZeros[i] = 0; - move16(); - } - } - } -} diff --git a/lib_enc/core_enc_reconf_fx.c b/lib_enc/core_enc_reconf_fx.c index 3140422be..3637dd53f 100644 --- a/lib_enc/core_enc_reconf_fx.c +++ b/lib_enc/core_enc_reconf_fx.c @@ -334,3 +334,307 @@ void core_coder_reconfig_fx( } } } + + +/*-----------------------------------------------------------------* + * Funtion core_coder_reconfig * + * ~~~~~~~~~~~~~~~~~~~ * + * - reconfig core coder when switching to another frame type * + *-----------------------------------------------------------------*/ + +void core_coder_reconfig_ivas_fx( + Encoder_State *st, + const int32_t last_total_brate ) +{ + Word16 i, bwidth, index; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + /*Configuration of ACELP*/ + BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); + + /*Configuration of partial copy*/ + IF( st->Opt_RF_ON ) + { + st->hRF->acelp_cfg_rf.mode_index = 1; + st->hRF->acelp_cfg_rf.midLpc = 0; + st->hRF->acelp_cfg_rf.midLpc_enable = 0; + st->hRF->acelp_cfg_rf.pre_emphasis = 0; + st->hRF->acelp_cfg_rf.formant_enh = 1; + st->hRF->acelp_cfg_rf.formant_tilt = 1; + st->hRF->acelp_cfg_rf.voice_tilt = 1; + st->hRF->acelp_cfg_rf.formant_enh_num = FORMANT_SHARPENING_G1; + st->hRF->acelp_cfg_rf.formant_enh_den = FORMANT_SHARPENING_G2; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->nb_bits_header_tcx = 2; /* signal class */ + move16(); + } + ELSE IF( st->tcxonly ) + { + st->nb_bits_header_tcx = 1 + 1; /*TCX20/TCX10 + last_core*/ + st->nb_bits_header_tcx = add( st->nb_bits_header_tcx, 2 ); /* Siganl class*/ + move16(); + move16(); + } + ELSE + { + st->nb_bits_header_ace = 1 + 2 + 1; /*TCX/ACELP+coder_type + last_core*/ + st->nb_bits_header_tcx = st->nb_bits_header_ace; + move16(); + move16(); + + IF( st->hTcxCfg != NULL ) + { + IF( st->hTcxCfg->lfacNext <= 0 ) + { + st->nb_bits_header_ace = sub( st->nb_bits_header_ace, 1 ); /*No last_core*/ + move16(); + } + } + } + + + /*Switch off TCX or ACELP?*/ + IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) + { + st->acelpEnabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 1 ) ), 1 ) ); + st->tcx20Enabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 2 ) ), 2 ) ); + move16(); + move16(); + } + st->prevEnergyHF_fx = st->currEnergyHF_fx = 1073725440l /*65535.0f Q14*/; /* prevent block switch */ + st->currEnergyHF_e_fx = 17; + move32(); + move16(); + + /*Sanity check : don't need to be instrumented*/ + IF( st->tcxonly == 0 ) + { + assert( st->acelpEnabled || st->tcx20Enabled || st->frame_size_index == 0 ); + } + ELSE + { + assert( st->tcx10Enabled || st->tcx20Enabled || st->frame_size_index == 0 ); + } + + /* TCX-LTP */ + IF( st->hTcxEnc != NULL ) + { + hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); + move16(); + } + + /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ + + st->acelp_autocorr = 1; + move16(); + + test(); + if ( ( LE_32( st->total_brate, ACELP_9k60 ) ) && ( EQ_32( st->sr_core, INT_FS_12k8 ) ) ) + { + st->acelp_autocorr = 0; + move16(); + } + + /*Get bandwidth mode*/ + IF( st->narrowBand ) + { + move16(); + bwidth = NB; + } + ELSE IF( LE_32( st->sr_core, INT_FS_16k ) ) + { + move16(); + bwidth = WB; + } + ELSE + { + move16(); + bwidth = SWB; + } + + /*Scale TCX for non-active frames to adjust loudness with ACELP*/ + IF( st->hTcxCfg != NULL ) + { + st->hTcxCfg->na_scale = 32767 /*1.0f Q15*/; + move16(); + + test(); + IF( LT_16( bwidth, 2 ) && ( st->tcxonly == 0 ) ) + { + /*const Word16 scaleTableSize = sizeof(scaleTcxTable) / sizeof(scaleTcxTable[0]);*/ + + FOR( i = 0; i < SIZE_SCALE_TABLE_TCX; i++ ) + { + + test(); + test(); + IF( EQ_16( bwidth, scaleTcxTable[i].bwmode ) && + GE_32( st->total_brate, scaleTcxTable[i].bitrateFrom ) && + LT_32( st->total_brate, scaleTcxTable[i].bitrateTo ) ) + { + if ( st->rf_mode ) + { + i = sub( i, 1 ); + } + move16(); + st->hTcxCfg->na_scale = scaleTcxTable[i].scale; + BREAK; + } + } + } + } + st->enableTcxLpc = 0; + move16(); + IF( GT_16( st->element_mode, IVAS_SCE ) ) + { + test(); + test(); + st->enableTcxLpc = ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR_CPE ) || st->rf_mode ) ); + move16(); + } + ELSE + { + test(); + test(); + if ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR ) || st->rf_mode != 0 ) ) + { + st->enableTcxLpc = 1; + move16(); + } + } + test(); + IF( st->ini_frame == 0 || EQ_16( st->last_codec_mode, MODE1 ) ) + { + st->envWeighted = 0; + move16(); + } + + test(); + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && + ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) + { + IF( st->tec_tfa == 0 ) + { + FOR( i = 0; i < MAX_TEC_SMOOTHING_DEG; i++ ) + { + st->hTECEnc->loBuffer[i] = 0; + move16(); + } + } + st->tec_tfa = 1; + move16(); + } + ELSE + { + st->tec_tfa = 0; + move16(); + } + + st->enablePlcWaveadjust = 0; + move16(); + if ( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + + + move16(); + st->glr = 0; + test(); + test(); + test(); + if ( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( st->element_mode == EVS_MONO ) ) + { + move16(); + st->glr = 1; + } + + IF( st->glr ) + { + move16(); + st->nb_bits_header_ace = add( st->nb_bits_header_ace, G_LPC_RECOVERY_BITS ); + } + IF( hTcxEnc != NULL ) + { + test(); + IF( EQ_16( st->bwidth, NB ) || EQ_16( st->bwidth, WB ) ) + { + IF( st->rf_mode == 0 ) + { + index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index ) ); + } + ELSE + { + index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index - 1 ) ); + } + hTcxEnc->nmStartLine = startLineWB[index]; + move16(); + } + ELSE /* (st->bwidth == SWB || st->bwidth == FB) */ + { + IF( st->rf_mode == 0 ) + { + index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index ), 3 ) ); + } + ELSE + { + index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index - 1 ), 3 ) ); + } + test(); + test(); + if ( GE_32( st->total_brate, IVAS_96k ) && LE_32( st->total_brate, IVAS_192k ) && GT_16( st->element_mode, IVAS_SCE ) ) + { + index = sub( index, 1 ); + } + hTcxEnc->nmStartLine = startLineSWB[index]; + move16(); + test(); + test(); + IF( EQ_32( st->total_brate, IVAS_48k ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LT_16( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), shl( st->L_frame, 2 ) ) ) + { + hTcxEnc->nmStartLine = shr( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), 2 ); /* low-rate stereo is more efficient than dual-mono due to stereo processing */ + move16(); + } + } + } + + IF( hTcxEnc != NULL ) + { + test(); + test(); + test(); + test(); + test(); + IF( ( LT_32( st->total_brate, ACELP_24k40 ) ) && ( ( GT_32( st->total_brate, last_total_brate ) ) || ( EQ_16( st->last_codec_mode, MODE1 ) ) ) ) + { + /* low-freq memQuantZeros_fx must be reset partially if bitrate increased */ + FOR( i = 0; i < hTcxEnc->nmStartLine; i++ ) + { + hTcxEnc->memQuantZeros[i] = 0; + move16(); + } + } + ELSE IF( ( GE_32( st->total_brate, ACELP_24k40 ) ) && ( LE_32( st->total_brate, ACELP_32k ) ) && ( GE_32( last_total_brate, ACELP_13k20 ) ) && ( LT_32( last_total_brate, ACELP_24k40 ) ) ) + { + FOR( i = 0; i < st->L_frame; i++ ) /* memQuantZeros_fx won't be updated */ + { + hTcxEnc->memQuantZeros[i] = 0; + move16(); + } + } + } +} diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c deleted file mode 100644 index f2375fb50..000000000 --- a/lib_enc/core_enc_switch.c +++ /dev/null @@ -1,302 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" - - -/*-------------------------------------------------------------------* - * core_coder_mode_switch() - * - * - *-------------------------------------------------------------------*/ -void core_coder_mode_switch_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word32 last_total_brate, /* i : last bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - Word16 i, fscale, switchWB; - Word32 sr_core; - Word16 bSwitchFromAmrwbIO; - Word16 tcxonly_tmp, exp_res; - - switchWB = 0; - move16(); - bSwitchFromAmrwbIO = 0; - move16(); - exp_res = 0; - move16(); - - - if ( EQ_16( st->last_core, AMR_WB_CORE ) ) - { - bSwitchFromAmrwbIO = 1; - move16(); - } - - /* force active frame for the first frame when switching from high bitrates when DTX is enabled*/ - sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); - - fscale = sr2fscale_fx( sr_core ); - if ( EQ_16( st->last_codec_mode, MODE1 ) ) - { - switchWB = 1; /*force init when coming from MODE1*/ - move16(); - } - - tcxonly_tmp = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - - if ( NE_32( tcxonly_tmp, st->tcxonly ) ) - { - switchWB = 1; /*force init when coming from MODE1*/ - move16(); - } - - test(); - test(); - IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) - { - st->sr_core = sr_core; - move16(); - Word16 tmp = BASOP_Util_Divide3232_Scale( sr_core, FRAMES_PER_SEC, &exp_res ); - st->L_frame = shr( tmp, sub( 15, exp_res ) ); // Q0 - move16(); - - st->tcxonly = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - move16(); - - Word16 exp_tmp1 = 0; - move16(); - Word16 tmp1 = BASOP_Util_Divide1616_Scale( ONE_IN_Q9, 128, &exp_tmp1 ); - - Word16 exp_tmp2 = 0; - move16(); - Word16 tmp2 = BASOP_Util_Divide3232_Scale( st->total_brate, 100, &exp_tmp2 ); - - Word16 exp_tmp3 = 0; - move16(); - Word16 tmp3 = BASOP_Util_Divide3232_Scale( st->L_frame, st->fscale, &exp_tmp3 ); - - Word32 tmp4 = L_mult0( tmp1, tmp2 ); // exp_tmp1 + exp_tmp2 - Word32 tmp5 = L_shl( Mpy_32_16_1( tmp4, tmp3 ), 1 ); // exp_tmp1 + exp_tmp2 + exp_tmp3 - st->bits_frame_nominal = extract_l( L_shr( tmp5, sub( 31, ( add( add( exp_tmp1, exp_tmp2 ), exp_tmp3 ) ) ) ) ); - move16(); - st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); - move16(); - /* switch IGF configuration */ - IF( st->igf ) - { - IGFEncSetMode_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); - } - st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( st->bwidth ); - move16(); - - st->hTcxCfg->bandwidth = getTcxBandwidth( st->bwidth ); - move16(); - if ( st->tcxonly ) - { - st->hTcxCfg->tcxRateLoopOpt = 2; - move16(); - } - else - { - st->hTcxCfg->tcxRateLoopOpt = 0; - move16(); - } - if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->hTcxCfg->tcxRateLoopOpt = 3; - move16(); - } - st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); - st->hTcxCfg->resq = getResq( st->total_brate ); - hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); - test(); - if ( st->hTcxCfg->resq && !st->tcxonly ) - { - st->hTcxCfg->tcxRateLoopOpt = 1; - move16(); - } - st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( st->total_brate, st->igf, st->element_mode ); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - - IF( st->hTcxCfg->fIsTNSAllowed ) - { - InitTnsConfigs_ivas_fx( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); - - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); - } - - IF( EQ_16( st->bwidth, NB ) ) - { - st->narrowBand = 1; - st->min_band = 1; - st->max_band = 16; - } - ELSE - { - st->narrowBand = 0; - st->min_band = 0; - st->max_band = 19; - } - - move16(); - move16(); - move16(); - - FOR( i = 0; i < FRAME_SIZE_NB; i++ ) - { - IF( EQ_32( FrameSizeConfig[i].frame_bits, st->bits_frame_nominal ) ) - { - st->frame_size_index = i; - st->bits_frame = FrameSizeConfig[i].frame_bits; - st->bits_frame_core = FrameSizeConfig[i].frame_net_bits; - move16(); - move16(); - move16(); - BREAK; - } - } - - st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); - move16(); - core_coder_reconfig_ivas_fx( st, last_total_brate ); - } - ELSE - { - st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); - move16(); - IF( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - } - st->currEnergyHF_fx = 0; - move32(); - st->currEnergyHF_e_fx = 0; - move16(); - Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); - st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); - move16(); - shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); - Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); - st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); - move16(); -#ifdef FIX_920_IGF_INIT_ERROR - init_coder_ace_plus_ivas_fx( st, last_total_brate, st->total_brate, MCT_flag ); -#else - init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); -#endif - if ( st->hLPDmem != NULL ) - { - st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; - move16(); - } - } - - test(); - IF( st->igf && st->hBWE_TD != NULL ) - { - /* reset TBE */ - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->bwidth, WB ) && NE_16( st->last_extl, WB_TBE ) ) || - ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || - ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) - { - TBEreset_enc_fx( st, st->bwidth ); - } - ELSE - { - set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); - set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - } - } - test(); - IF( st->envWeighted && !st->enableTcxLpc ) - { - /* Unweight the envelope */ - st->inv_gamma = BASOP_Util_Divide1616_Scale( MAX16B, st->gamma, &exp_res ); - move16(); - st->inv_gamma = shr( st->inv_gamma, sub( Q1, exp_res ) ); /* Q14 */ - move16(); - E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); - st->envWeighted = 0; - move16(); - } - - IF( GE_32( st->total_brate, HQ_48k ) ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - ELSE - { - st->enablePlcWaveadjust = 0; - move16(); - } - - test(); - test(); - if ( ( GT_32( last_total_brate, HQ_32k ) || EQ_16( st->last_codec_mode, MODE1 ) ) && ( st->element_mode == EVS_MONO ) ) - { - st->glr_reset = 1; - move16(); - } - - return; -} diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index 1096cfb49..82bb5fca9 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -223,3 +223,262 @@ void core_coder_mode_switch_fx( st->glr_reset = 1; } } + + +/*-------------------------------------------------------------------* + * core_coder_mode_switch() + * + * + *-------------------------------------------------------------------*/ +void core_coder_mode_switch_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word32 last_total_brate, /* i : last bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 i, fscale, switchWB; + Word32 sr_core; + Word16 bSwitchFromAmrwbIO; + Word16 tcxonly_tmp, exp_res; + + switchWB = 0; + move16(); + bSwitchFromAmrwbIO = 0; + move16(); + exp_res = 0; + move16(); + + + if ( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + bSwitchFromAmrwbIO = 1; + move16(); + } + + /* force active frame for the first frame when switching from high bitrates when DTX is enabled*/ + sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + + fscale = sr2fscale_fx( sr_core ); + if ( EQ_16( st->last_codec_mode, MODE1 ) ) + { + switchWB = 1; /*force init when coming from MODE1*/ + move16(); + } + + tcxonly_tmp = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + + if ( NE_32( tcxonly_tmp, st->tcxonly ) ) + { + switchWB = 1; /*force init when coming from MODE1*/ + move16(); + } + + test(); + test(); + IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) + { + st->sr_core = sr_core; + move16(); + Word16 tmp = BASOP_Util_Divide3232_Scale( sr_core, FRAMES_PER_SEC, &exp_res ); + st->L_frame = shr( tmp, sub( 15, exp_res ) ); // Q0 + move16(); + + st->tcxonly = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + move16(); + + Word16 exp_tmp1 = 0; + move16(); + Word16 tmp1 = BASOP_Util_Divide1616_Scale( ONE_IN_Q9, 128, &exp_tmp1 ); + + Word16 exp_tmp2 = 0; + move16(); + Word16 tmp2 = BASOP_Util_Divide3232_Scale( st->total_brate, 100, &exp_tmp2 ); + + Word16 exp_tmp3 = 0; + move16(); + Word16 tmp3 = BASOP_Util_Divide3232_Scale( st->L_frame, st->fscale, &exp_tmp3 ); + + Word32 tmp4 = L_mult0( tmp1, tmp2 ); // exp_tmp1 + exp_tmp2 + Word32 tmp5 = L_shl( Mpy_32_16_1( tmp4, tmp3 ), 1 ); // exp_tmp1 + exp_tmp2 + exp_tmp3 + st->bits_frame_nominal = extract_l( L_shr( tmp5, sub( 31, ( add( add( exp_tmp1, exp_tmp2 ), exp_tmp3 ) ) ) ) ); + move16(); + st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + /* switch IGF configuration */ + IF( st->igf ) + { + IGFEncSetMode_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); + } + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( st->bwidth ); + move16(); + + st->hTcxCfg->bandwidth = getTcxBandwidth( st->bwidth ); + move16(); + if ( st->tcxonly ) + { + st->hTcxCfg->tcxRateLoopOpt = 2; + move16(); + } + else + { + st->hTcxCfg->tcxRateLoopOpt = 0; + move16(); + } + if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->hTcxCfg->tcxRateLoopOpt = 3; + move16(); + } + st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); + st->hTcxCfg->resq = getResq( st->total_brate ); + hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); + test(); + if ( st->hTcxCfg->resq && !st->tcxonly ) + { + st->hTcxCfg->tcxRateLoopOpt = 1; + move16(); + } + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( st->total_brate, st->igf, st->element_mode ); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + IF( st->hTcxCfg->fIsTNSAllowed ) + { + InitTnsConfigs_ivas_fx( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); + + SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); + } + + IF( EQ_16( st->bwidth, NB ) ) + { + st->narrowBand = 1; + st->min_band = 1; + st->max_band = 16; + } + ELSE + { + st->narrowBand = 0; + st->min_band = 0; + st->max_band = 19; + } + + move16(); + move16(); + move16(); + + FOR( i = 0; i < FRAME_SIZE_NB; i++ ) + { + IF( EQ_32( FrameSizeConfig[i].frame_bits, st->bits_frame_nominal ) ) + { + st->frame_size_index = i; + st->bits_frame = FrameSizeConfig[i].frame_bits; + st->bits_frame_core = FrameSizeConfig[i].frame_net_bits; + move16(); + move16(); + move16(); + BREAK; + } + } + + st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); + move16(); + core_coder_reconfig_ivas_fx( st, last_total_brate ); + } + ELSE + { + st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + IF( hTcxEnc != NULL ) + { + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + } + st->currEnergyHF_fx = 0; + move32(); + st->currEnergyHF_e_fx = 0; + move16(); + Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); + st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); + move16(); + shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); + Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); + st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); + move16(); +#ifdef FIX_920_IGF_INIT_ERROR + init_coder_ace_plus_ivas_fx( st, last_total_brate, st->total_brate, MCT_flag ); +#else + init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); +#endif + if ( st->hLPDmem != NULL ) + { + st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; + move16(); + } + } + + test(); + IF( st->igf && st->hBWE_TD != NULL ) + { + /* reset TBE */ + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->bwidth, WB ) && NE_16( st->last_extl, WB_TBE ) ) || + ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || + ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) + { + TBEreset_enc_fx( st, st->bwidth ); + } + ELSE + { + set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + } + } + test(); + IF( st->envWeighted && !st->enableTcxLpc ) + { + /* Unweight the envelope */ + st->inv_gamma = BASOP_Util_Divide1616_Scale( MAX16B, st->gamma, &exp_res ); + move16(); + st->inv_gamma = shr( st->inv_gamma, sub( Q1, exp_res ) ); /* Q14 */ + move16(); + E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); + st->envWeighted = 0; + move16(); + } + + IF( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + ELSE + { + st->enablePlcWaveadjust = 0; + move16(); + } + + test(); + test(); + if ( ( GT_32( last_total_brate, HQ_32k ) || EQ_16( st->last_codec_mode, MODE1 ) ) && ( st->element_mode == EVS_MONO ) ) + { + st->glr_reset = 1; + move16(); + } + + return; +} diff --git a/lib_enc/core_enc_updt.c b/lib_enc/core_enc_updt.c deleted file mode 100644 index 4533af002..000000000 --- a/lib_enc/core_enc_updt.c +++ /dev/null @@ -1,117 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * core_encode_update() - * - * Common updates of buffers - *-------------------------------------------------------------------*/ - -void core_encode_update_ivas_fx( - Encoder_State *st /* i/o: Encoder state structure */ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - Word16 n; - - /* Update Input Signal Buffers */ - n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); - - Copy( st->buf_speech_enc_pe + st->L_frame, st->buf_speech_enc_pe, n ); - Copy( st->buf_speech_enc + st->L_frame, st->buf_speech_enc, n ); - - IF( !st->tcxonly ) - { - n = add( st->L_frame, shr( st->L_frame, 2 ) ); - Copy( st->buf_wspeech_enc + st->L_frame, st->buf_wspeech_enc, n ); - } - - IF( hTcxEnc != NULL ) - { - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) || EQ_32( st->core_brate, SID_2k40 ) || ( st->core_brate == FRAME_NO_DATA ) ) - { - Word16 max_e = s_max( st->hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); - Scale_sig( hTcxEnc->buf_speech_ltp, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, negate( sub( max_e, st->hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(31-max_e) - Copy_Scale_sig( st->buf_speech_enc + st->L_frame, hTcxEnc->buf_speech_ltp + st->L_frame, st->L_frame, negate( sub( max_e, st->exp_buf_speech_enc ) ) ); // Q(31-max_e) - st->hTcxEnc->exp_buf_speech_ltp = max_e; - move16(); - } - } - - n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); - Copy( st->buf_synth + st->L_frame, st->buf_synth, add( st->L_frame, L_SUBFR ) ); - IF( hTcxEnc != NULL ) - { - Copy( hTcxEnc->buf_speech_ltp + st->L_frame, hTcxEnc->buf_speech_ltp, n ); - - IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->hTcxEnc->kernel_switch_corr_past = 0; - st->hTcxEnc->kernel_type[0] = MDCT_IV; - st->hTcxEnc->kernel_symmetry_past = 0; - st->hTcxEnc->enc_ste_pre_corr_past = 0; - - move16(); - move16(); - move16(); - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( ( st->Opt_DTX_ON && LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) || ( st->tcxonly && ( EQ_16( st->codec_mode, MODE2 ) || ( st->element_mode > EVS_MONO ) ) ) ) - { - /* reset LP memories */ - set16_fx( st->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); // 2.56 scaling - } - return; -} diff --git a/lib_enc/core_enc_updt_fx.c b/lib_enc/core_enc_updt_fx.c index 125f0cd52..305c2a92f 100644 --- a/lib_enc/core_enc_updt_fx.c +++ b/lib_enc/core_enc_updt_fx.c @@ -211,3 +211,77 @@ void core_encode_update_cng_fx( return; } + +/*-------------------------------------------------------------------* + * core_encode_update() + * + * Common updates of buffers + *-------------------------------------------------------------------*/ + +void core_encode_update_ivas_fx( + Encoder_State *st /* i/o: Encoder state structure */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 n; + + /* Update Input Signal Buffers */ + n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); + + Copy( st->buf_speech_enc_pe + st->L_frame, st->buf_speech_enc_pe, n ); + Copy( st->buf_speech_enc + st->L_frame, st->buf_speech_enc, n ); + + IF( !st->tcxonly ) + { + n = add( st->L_frame, shr( st->L_frame, 2 ) ); + Copy( st->buf_wspeech_enc + st->L_frame, st->buf_wspeech_enc, n ); + } + + IF( hTcxEnc != NULL ) + { + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) || EQ_32( st->core_brate, SID_2k40 ) || ( st->core_brate == FRAME_NO_DATA ) ) + { + Word16 max_e = s_max( st->hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); + Scale_sig( hTcxEnc->buf_speech_ltp, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, negate( sub( max_e, st->hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(31-max_e) + Copy_Scale_sig( st->buf_speech_enc + st->L_frame, hTcxEnc->buf_speech_ltp + st->L_frame, st->L_frame, negate( sub( max_e, st->exp_buf_speech_enc ) ) ); // Q(31-max_e) + st->hTcxEnc->exp_buf_speech_ltp = max_e; + move16(); + } + } + + n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); + Copy( st->buf_synth + st->L_frame, st->buf_synth, add( st->L_frame, L_SUBFR ) ); + IF( hTcxEnc != NULL ) + { + Copy( hTcxEnc->buf_speech_ltp + st->L_frame, hTcxEnc->buf_speech_ltp, n ); + + IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->hTcxEnc->kernel_switch_corr_past = 0; + st->hTcxEnc->kernel_type[0] = MDCT_IV; + st->hTcxEnc->kernel_symmetry_past = 0; + st->hTcxEnc->enc_ste_pre_corr_past = 0; + + move16(); + move16(); + move16(); + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + IF( ( st->Opt_DTX_ON && LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) || ( st->tcxonly && ( EQ_16( st->codec_mode, MODE2 ) || ( st->element_mode > EVS_MONO ) ) ) ) + { + /* reset LP memories */ + set16_fx( st->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); // 2.56 scaling + } + return; +} diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c deleted file mode 100644 index 08789dbde..000000000 --- a/lib_enc/core_switching_enc.c +++ /dev/null @@ -1,603 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "ivas_prot_fx.h" - -void core_switching_pre_enc_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *old_inp_12k8, /* i : old input signal @12.8kHz q_old_inp_12k8 */ - const Word16 q_old_inp_12k8, /* i : Q old input signal @12.8kHz */ - const Word16 *old_inp_16k, /* i : old input signal @16kHz q_old_inp_16k */ - const Word16 q_old_inp_16k, /* i : Q old input signal @16kHz */ - const Word16 active_cnt, /* i : active frame counter */ - const Word16 last_element_mode /* i : last_element_mode */ -) -{ - Word16 Sample_Delay_HP, Sample_Delay_LP; - Word16 tmp16; - Word16 tmp; - SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; - LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; - HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; - TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; - TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc; - FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; - - /* Mode switching */ - test(); - test(); - test(); - IF( EQ_16( st_fx->last_codec_mode, MODE2 ) || ( ( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) && ( st_fx->element_mode > EVS_MONO ) ) ) ) - { - IF( hLPDmem != NULL ) - { - st_fx->mem_deemph_fx = hLPDmem->syn[M]; - move16(); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); - } - - if ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - st_fx->igf = 0; - move16(); - } - - IF( hBWE_TD != NULL ) - { - IF( st_fx->last_core != ACELP_CORE ) - { - /* reset BWE memories */ - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); - move32(); - } - - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - test(); - IF( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) - { - if ( st_fx->element_mode == EVS_MONO ) - { - st_fx->last_core = HQ_CORE; - move16(); - } - IF( hHQ_core != NULL ) - { - set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); - hHQ_core->last_max_pos_pulse = 0; - move16(); - - hHQ_core->mode_count = 0; - move16(); - hHQ_core->mode_count1 = 0; - move16(); - - set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - hHQ_core->prev_frm_hfe2 = 0; - move16(); - hHQ_core->prev_stab_hfe2 = 0; - move16(); - } - test(); - /*ALDO overlap windowed past: also used in MODE2 but for other MDCT-LB*/ - IF( ( st_fx->element_mode == EVS_MONO ) && hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); - } - } - - test(); - IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( EQ_16( st_fx->last_L_frame, L_FRAME ) ) ) - { - Copy( st_fx->lsp_old_fx, st_fx->lsp_old16k_fx, M ); - - st_fx->rate_switching_reset_16kHz = lsp_convert_poly_fx( st_fx->lsp_old16k_fx, st_fx->L_frame, 0 ); - move16(); - } - - st_fx->use_acelp_preq = 0; - move16(); - } - - test(); - test(); - test(); - if ( EQ_16( st_fx->last_core, -1 ) && ( EQ_16( st_fx->core, HQ_CORE ) || EQ_16( st_fx->core, TCX_20_CORE ) || EQ_16( st_fx->core, TCX_10_CORE ) ) ) - { - /* very first frame is HQ_CORE */ - st_fx->last_core = HQ_CORE; - move16(); - } - - test(); - test(); - IF( EQ_16( st_fx->core, HQ_CORE ) && ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) /* HQ init */ - { - set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); - hHQ_core->last_max_pos_pulse = 0; - move16(); - - hHQ_core->mode_count = 0; - move16(); - hHQ_core->mode_count1 = 0; - move16(); - - set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - hHQ_core->prev_frm_hfe2 = 0; - move16(); - hHQ_core->prev_stab_hfe2 = 0; - move16(); - - IF( hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); - } - } - - /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores - within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ - test(); - test(); - IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) - { - IF( hSC_VBR != NULL ) - { - hSC_VBR->last_last_ppp_mode = 0; - move16(); - hSC_VBR->last_ppp_mode = 0; - move16(); - hSC_VBR->last_nelp_mode = 0; - move16(); - } - } - - test(); - test(); - test(); - IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) || LE_32( st_fx->last_total_brate, PPP_NELP_2k80 ) ) ) - { - st_fx->act_count = 3; - move16(); - st_fx->uv_count = 0; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) || - ( ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( active_cnt, 1 ) ) ) - { - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ - lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); - } - ELSE - { - Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ - lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); - } - - st_fx->mem_deemph_fx = 0; - move16(); - /* Reset ACELP parameters */ - IF( hLPDmem != NULL ) - { - move16(); - hLPDmem->syn[M] = 0; - move16(); - set16_fx( hLPDmem->mem_syn2, 0, M ); - set16_fx( hLPDmem->mem_syn, 0, M ); - set16_fx( hLPDmem->mem_syn1_fx, 0, M ); - hLPDmem->q_mem_syn = Q15; - move16(); - hLPDmem->mem_w0 = 0; - move16(); - hLPDmem->tilt_code = 0; - move16(); - hLPDmem->gc_threshold = 0; - move32(); - /* set16_fx( st_fx->dispMem, 0, 8 ); */ - set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); - hLPDmem->dm_fx.prev_state = 0; - move16(); - hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); - } - st_fx->Nb_ACELP_frames = 0; - move16(); - - set16_fx( st_fx->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); - init_gp_clip_fx( st_fx->clip_var_fx ); - st_fx->last_coder_type = GENERIC; - move16(); - - tmp16 = add( NB_SUBFR, 1 ); - - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - tmp16 = NB_SUBFR; - move16(); - } - - Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); - set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); - - /* Reset old ACELP buffers */ - test(); - IF( ( st_fx->element_mode == EVS_MONO ) && hLPDmem != NULL ) - { - set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); - } - IF( hBWE_TD != NULL ) - { - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - - /* reset BWE memories */ - hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - IF( hBWE_FD != NULL ) - { - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - } - test(); - test(); - test(); - IF( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) ) - { - /* Reset the ACELP core in case of TCX->ACELP core switching */ - st_fx->Nb_ACELP_frames = 0; - move16(); - - IF( hLPDmem != NULL ) - { - hLPDmem->mem_w0 = 0; - move16(); - hLPDmem->tilt_code = 0; - move16(); - hLPDmem->gc_threshold = 0; - move32(); - init_gp_clip_fx( st_fx->clip_var_fx ); - set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); - hLPDmem->dm_fx.prev_state = 0; - move16(); - hLPDmem->dm_fx.prev_gain_code = 0; - move32(); - } - - st_fx->last_coder_type = GENERIC; - move16(); - - tmp16 = shr( st_fx->L_frame, 6 ); - Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); - set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); - - /* Reset old TD BWE buffers */ - IF( hBWE_TD != NULL ) - { - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* reset BWE memories */ - IF( hBWE_FD != NULL ) - { - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); /* TODO : this might not be needed */ - } - } - test(); - test(); - test(); - IF( GE_32( st_fx->input_Fs, 16000 ) && NE_16( st_fx->last_extl, WB_BWE ) && EQ_16( st_fx->extl, WB_BWE ) && hBWE_FD != NULL ) - { - test(); - IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) ) - { - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->modeCount = 0; - move16(); - } - - hBWE_FD->prev_L_swb_norm1 = 8; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - IF( ( GE_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->last_extl, SWB_BWE ) && EQ_16( st_fx->extl, SWB_BWE ) ) || - ( GE_32( st_fx->input_Fs, 48000 ) && NE_16( st_fx->last_extl, FB_BWE ) && EQ_16( st_fx->extl, FB_BWE ) ) ) - { - /* we are switching to SWB BWE - reset SWB BWE buffers */ - - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); - Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); - IF( ( st_fx->element_mode > EVS_MONO ) ) - { - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); - } - Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); - } - IF( GT_16( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ) - { - Copy_Scale_sig( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_12k8 ) ); // prev_Q_input_lp - } - ELSE - { - Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_12k8 - hBWE_FD->prev_Q_input_lp = q_old_inp_12k8; - move16(); - Copy( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); - } - } - ELSE - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); - Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) - { - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); - } - Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); - } - IF( GT_16( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ) - { - Copy_Scale_sig( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_16k ) ); // prev_Q_input_lp - } - ELSE - { - Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_16k - hBWE_FD->prev_Q_input_lp = q_old_inp_16k; - move16(); - Copy( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); - } - } - - tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); - Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); -#ifdef FIX_ISSUE_1230 - hBWE_FD->Q_new_input_hp = 0; - move16(); -#endif - - IF( NE_16( st_fx->last_extl, WB_BWE ) ) - { - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->modeCount = 0; - move16(); - } - hBWE_FD->EnergyLF_fx = 0; - hBWE_FD->EnergyLF_exp = 0; - move32(); - move16(); - hBWE_FD->prev_L_swb_norm1 = 8; - move16(); /*8.0 in Q0 */ - st_fx->EnergyLT_fx_exp = 30; - move16(); /* Set to a High Exponent so it is 1^-30 */ - } - /*---------------------------------------------------------------------* - * band-width switching from WB -> SWB/FB - *---------------------------------------------------------------------*/ - IF( st_fx->element_mode > EVS_MONO ) - { - IF( st_fx->bwidth_sw_cnt == 0 ) - { - test(); - IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) - { - st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); - move16(); - } - } - ELSE - { - st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); - move16(); - IF( EQ_16( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ) ) - { - st_fx->bwidth_sw_cnt = 0; - move16(); - } - } - } - - return; -} - -/*---------------------------------------------------------------------* - * core_switching_post_enc() - * - * Postprocessing for ACELP/HQ core switching - *---------------------------------------------------------------------*/ - -void core_switching_post_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word16 *old_inp_12k8_fx, /* i : old input signal @12.8kHz Q_new-1 */ - Word16 *old_inp_16k_fx, /* i : old input signal @16kHz Q_new-1 */ - Word16 A_fx[], /* i : unquant. LP filter coefs. Q12 */ - Word16 Q_new ) -{ - IF( EQ_16( st->core, HQ_CORE ) ) - { - st->use_acelp_preq = 0; - move16(); - test(); - test(); - IF( ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) && st->element_mode == EVS_MONO ) /* core switching ==> ACELP subframe encoding */ - { - /* Memory scaling to keep everything in common q */ - Scale_sig( st->hLPDmem->mem_syn, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn2, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn3, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - st->hLPDmem->mem_w0 = shl( st->hLPDmem->mem_w0, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - move16(); - st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); - move16(); - - acelp_core_switch_enc_ivas_fx( st, old_inp_12k8_fx + L_INP_MEM - NS2SA( INT_FS_12k8, ACELP_LOOK_NS ), old_inp_16k_fx + L_INP_MEM - NS2SA( INT_FS_16k, ACELP_LOOK_NS ), A_fx, 0, sub( Q_new, 1 ) ); - } - - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - st->hBWE_FD->mem_deemph_old_syn_fx = 0; - move16(); - st->hBWE_FD->q_mem_deemph_old_syn = 0; - move16(); - } - ELSE - { - IF( st->hBWE_TD == NULL ) - { - return; - } - - test(); - /* reset SWB TBE buffers */ - IF( EQ_16( st->extl, WB_TBE ) && NE_16( st->last_extl, WB_TBE ) ) - { - wb_tbe_extras_reset_fx( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); - - IF( NE_16( st->last_extl, WB_BWE ) ) - { - set16_fx( st->hBWE_TD->decim_state1_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - set16_fx( st->hBWE_TD->decim_state2_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - } - - set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); - set16_fx( st->hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); - set32_fx( st->hBWE_TD->mem_csfilt_fx, 0, 2 ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - - IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && - ( EQ_16( st->last_core, HQ_CORE ) || NE_16( st->L_frame, st->last_L_frame ) || ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) ) ) - { - set16_fx( st->hBWE_TD->state_ana_filt_shb_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - - InitSWBencBufferStates_fx( st->hBWE_TD, NULL ); - swb_tbe_reset_fx( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->state_syn_shbexc_fx, &( st->hBWE_TD->tbe_demph_fx ), &( st->hBWE_TD->tbe_premph_fx ), st->hBWE_TD->mem_stp_swb_fx, &( st->hBWE_TD->gain_prec_swb_fx ) ); - - set16_fx( st->hBWE_TD->dec_2_over_3_mem_fx, 0, L_FILT_2OVER3 ); - set16_fx( st->hBWE_TD->dec_2_over_3_mem_lp_fx, 0, L_FILT_2OVER3_LP ); - } - ELSE IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && ( ( EQ_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || ( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_32( st->last_total_brate, st->total_brate ) ) || ( NE_16( st->last_bwidth, st->bwidth ) ) || ( NE_16( st->last_codec_mode, MODE1 ) ) || ( NE_16( st->rf_mode_last, st->rf_mode ) ) ) ) - { - set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); - set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - } - ELSE IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) - { - TBEreset_enc_fx( st, st->bwidth ); - } - - test(); - test(); - test(); - test(); - /* Interp_3_2 CNG buffers reset */ - IF( EQ_16( st->extl, FB_TBE ) && ( ( NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) || NE_16( st->L_frame, st->last_L_frame ) ) ) - { - set16_fx( st->hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - st->hBWE_TD->fb_tbe_demph_fx = 0; - move16(); - fb_tbe_reset_enc_fx( st->hBWE_TD->elliptic_bpf_2_48k_mem_fx, &st->hBWE_TD->prev_fb_energy_fx, st->hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &st->hBWE_TD->prev_fb_energy_fx_Q ); - } - /* Fade towards init value for non HQ_CORE */ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) ) ) ); /*crest_lp_q*/ - move32(); - st->hHQ_core->crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_mod_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ) ) ); /*crest_mod_lp_q*/ - move32(); - } - } - - return; -} diff --git a/lib_enc/core_switching_enc_fx.c b/lib_enc/core_switching_enc_fx.c index da1139d15..6fa341a7b 100644 --- a/lib_enc/core_switching_enc_fx.c +++ b/lib_enc/core_switching_enc_fx.c @@ -8,8 +8,9 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ /*---------------------------------------------------------------------* @@ -672,3 +673,559 @@ void core_switching_hq_prepare_enc_fx( } return; } + +void core_switching_pre_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *old_inp_12k8, /* i : old input signal @12.8kHz q_old_inp_12k8 */ + const Word16 q_old_inp_12k8, /* i : Q old input signal @12.8kHz */ + const Word16 *old_inp_16k, /* i : old input signal @16kHz q_old_inp_16k */ + const Word16 q_old_inp_16k, /* i : Q old input signal @16kHz */ + const Word16 active_cnt, /* i : active frame counter */ + const Word16 last_element_mode /* i : last_element_mode */ +) +{ + Word16 Sample_Delay_HP, Sample_Delay_LP; + Word16 tmp16; + Word16 tmp; + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; + TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; + TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc; + FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; + + /* Mode switching */ + test(); + test(); + test(); + IF( EQ_16( st_fx->last_codec_mode, MODE2 ) || ( ( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) && ( st_fx->element_mode > EVS_MONO ) ) ) ) + { + IF( hLPDmem != NULL ) + { + st_fx->mem_deemph_fx = hLPDmem->syn[M]; + move16(); + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); + } + + if ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + st_fx->igf = 0; + move16(); + } + + IF( hBWE_TD != NULL ) + { + IF( st_fx->last_core != ACELP_CORE ) + { + /* reset BWE memories */ + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); + move32(); + } + + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + test(); + IF( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) + { + if ( st_fx->element_mode == EVS_MONO ) + { + st_fx->last_core = HQ_CORE; + move16(); + } + IF( hHQ_core != NULL ) + { + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse = 0; + move16(); + + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + + set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2 = 0; + move16(); + hHQ_core->prev_stab_hfe2 = 0; + move16(); + } + test(); + /*ALDO overlap windowed past: also used in MODE2 but for other MDCT-LB*/ + IF( ( st_fx->element_mode == EVS_MONO ) && hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); + } + } + + test(); + IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( EQ_16( st_fx->last_L_frame, L_FRAME ) ) ) + { + Copy( st_fx->lsp_old_fx, st_fx->lsp_old16k_fx, M ); + + st_fx->rate_switching_reset_16kHz = lsp_convert_poly_fx( st_fx->lsp_old16k_fx, st_fx->L_frame, 0 ); + move16(); + } + + st_fx->use_acelp_preq = 0; + move16(); + } + + test(); + test(); + test(); + if ( EQ_16( st_fx->last_core, -1 ) && ( EQ_16( st_fx->core, HQ_CORE ) || EQ_16( st_fx->core, TCX_20_CORE ) || EQ_16( st_fx->core, TCX_10_CORE ) ) ) + { + /* very first frame is HQ_CORE */ + st_fx->last_core = HQ_CORE; + move16(); + } + + test(); + test(); + IF( EQ_16( st_fx->core, HQ_CORE ) && ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) /* HQ init */ + { + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse = 0; + move16(); + + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + + set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2 = 0; + move16(); + hHQ_core->prev_stab_hfe2 = 0; + move16(); + + IF( hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) + { + IF( hSC_VBR != NULL ) + { + hSC_VBR->last_last_ppp_mode = 0; + move16(); + hSC_VBR->last_ppp_mode = 0; + move16(); + hSC_VBR->last_nelp_mode = 0; + move16(); + } + } + + test(); + test(); + test(); + IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) || LE_32( st_fx->last_total_brate, PPP_NELP_2k80 ) ) ) + { + st_fx->act_count = 3; + move16(); + st_fx->uv_count = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) || + ( ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( active_cnt, 1 ) ) ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); + } + + st_fx->mem_deemph_fx = 0; + move16(); + /* Reset ACELP parameters */ + IF( hLPDmem != NULL ) + { + move16(); + hLPDmem->syn[M] = 0; + move16(); + set16_fx( hLPDmem->mem_syn2, 0, M ); + set16_fx( hLPDmem->mem_syn, 0, M ); + set16_fx( hLPDmem->mem_syn1_fx, 0, M ); + hLPDmem->q_mem_syn = Q15; + move16(); + hLPDmem->mem_w0 = 0; + move16(); + hLPDmem->tilt_code = 0; + move16(); + hLPDmem->gc_threshold = 0; + move32(); + /* set16_fx( st_fx->dispMem, 0, 8 ); */ + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0; + move16(); + hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + } + st_fx->Nb_ACELP_frames = 0; + move16(); + + set16_fx( st_fx->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + init_gp_clip_fx( st_fx->clip_var_fx ); + st_fx->last_coder_type = GENERIC; + move16(); + + tmp16 = add( NB_SUBFR, 1 ); + + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + tmp16 = NB_SUBFR; + move16(); + } + + Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); + set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); + + /* Reset old ACELP buffers */ + test(); + IF( ( st_fx->element_mode == EVS_MONO ) && hLPDmem != NULL ) + { + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + } + IF( hBWE_TD != NULL ) + { + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + + /* reset BWE memories */ + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + IF( hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + } + test(); + test(); + test(); + IF( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) ) + { + /* Reset the ACELP core in case of TCX->ACELP core switching */ + st_fx->Nb_ACELP_frames = 0; + move16(); + + IF( hLPDmem != NULL ) + { + hLPDmem->mem_w0 = 0; + move16(); + hLPDmem->tilt_code = 0; + move16(); + hLPDmem->gc_threshold = 0; + move32(); + init_gp_clip_fx( st_fx->clip_var_fx ); + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0; + move16(); + hLPDmem->dm_fx.prev_gain_code = 0; + move32(); + } + + st_fx->last_coder_type = GENERIC; + move16(); + + tmp16 = shr( st_fx->L_frame, 6 ); + Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); + set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); + + /* Reset old TD BWE buffers */ + IF( hBWE_TD != NULL ) + { + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* reset BWE memories */ + IF( hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); /* TODO : this might not be needed */ + } + } + test(); + test(); + test(); + IF( GE_32( st_fx->input_Fs, 16000 ) && NE_16( st_fx->last_extl, WB_BWE ) && EQ_16( st_fx->extl, WB_BWE ) && hBWE_FD != NULL ) + { + test(); + IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->modeCount = 0; + move16(); + } + + hBWE_FD->prev_L_swb_norm1 = 8; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + IF( ( GE_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->last_extl, SWB_BWE ) && EQ_16( st_fx->extl, SWB_BWE ) ) || + ( GE_32( st_fx->input_Fs, 48000 ) && NE_16( st_fx->last_extl, FB_BWE ) && EQ_16( st_fx->extl, FB_BWE ) ) ) + { + /* we are switching to SWB BWE - reset SWB BWE buffers */ + + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); + IF( ( st_fx->element_mode > EVS_MONO ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + } + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); + } + IF( GT_16( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ) + { + Copy_Scale_sig( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_12k8 ) ); // prev_Q_input_lp + } + ELSE + { + Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_12k8 + hBWE_FD->prev_Q_input_lp = q_old_inp_12k8; + move16(); + Copy( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + } + } + ELSE + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + } + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); + } + IF( GT_16( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ) + { + Copy_Scale_sig( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_16k ) ); // prev_Q_input_lp + } + ELSE + { + Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_16k + hBWE_FD->prev_Q_input_lp = q_old_inp_16k; + move16(); + Copy( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + } + } + + tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); + Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); +#ifdef FIX_ISSUE_1230 + hBWE_FD->Q_new_input_hp = 0; + move16(); +#endif + + IF( NE_16( st_fx->last_extl, WB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->modeCount = 0; + move16(); + } + hBWE_FD->EnergyLF_fx = 0; + hBWE_FD->EnergyLF_exp = 0; + move32(); + move16(); + hBWE_FD->prev_L_swb_norm1 = 8; + move16(); /*8.0 in Q0 */ + st_fx->EnergyLT_fx_exp = 30; + move16(); /* Set to a High Exponent so it is 1^-30 */ + } + /*---------------------------------------------------------------------* + * band-width switching from WB -> SWB/FB + *---------------------------------------------------------------------*/ + IF( st_fx->element_mode > EVS_MONO ) + { + IF( st_fx->bwidth_sw_cnt == 0 ) + { + test(); + IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) + { + st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); + move16(); + } + } + ELSE + { + st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); + move16(); + IF( EQ_16( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ) ) + { + st_fx->bwidth_sw_cnt = 0; + move16(); + } + } + } + + return; +} + +/*---------------------------------------------------------------------* + * core_switching_post_enc() + * + * Postprocessing for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + +void core_switching_post_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word16 *old_inp_12k8_fx, /* i : old input signal @12.8kHz Q_new-1 */ + Word16 *old_inp_16k_fx, /* i : old input signal @16kHz Q_new-1 */ + Word16 A_fx[], /* i : unquant. LP filter coefs. Q12 */ + Word16 Q_new ) +{ + IF( EQ_16( st->core, HQ_CORE ) ) + { + st->use_acelp_preq = 0; + move16(); + test(); + test(); + IF( ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) && st->element_mode == EVS_MONO ) /* core switching ==> ACELP subframe encoding */ + { + /* Memory scaling to keep everything in common q */ + Scale_sig( st->hLPDmem->mem_syn, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn2, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn3, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + st->hLPDmem->mem_w0 = shl( st->hLPDmem->mem_w0, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + move16(); + st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); + move16(); + + acelp_core_switch_enc_ivas_fx( st, old_inp_12k8_fx + L_INP_MEM - NS2SA( INT_FS_12k8, ACELP_LOOK_NS ), old_inp_16k_fx + L_INP_MEM - NS2SA( INT_FS_16k, ACELP_LOOK_NS ), A_fx, 0, sub( Q_new, 1 ) ); + } + + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + st->hBWE_FD->mem_deemph_old_syn_fx = 0; + move16(); + st->hBWE_FD->q_mem_deemph_old_syn = 0; + move16(); + } + ELSE + { + IF( st->hBWE_TD == NULL ) + { + return; + } + + test(); + /* reset SWB TBE buffers */ + IF( EQ_16( st->extl, WB_TBE ) && NE_16( st->last_extl, WB_TBE ) ) + { + wb_tbe_extras_reset_fx( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); + + IF( NE_16( st->last_extl, WB_BWE ) ) + { + set16_fx( st->hBWE_TD->decim_state1_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set16_fx( st->hBWE_TD->decim_state2_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + } + + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); + set16_fx( st->hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); + set32_fx( st->hBWE_TD->mem_csfilt_fx, 0, 2 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + + IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && + ( EQ_16( st->last_core, HQ_CORE ) || NE_16( st->L_frame, st->last_L_frame ) || ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) ) ) + { + set16_fx( st->hBWE_TD->state_ana_filt_shb_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + + InitSWBencBufferStates_fx( st->hBWE_TD, NULL ); + swb_tbe_reset_fx( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->state_syn_shbexc_fx, &( st->hBWE_TD->tbe_demph_fx ), &( st->hBWE_TD->tbe_premph_fx ), st->hBWE_TD->mem_stp_swb_fx, &( st->hBWE_TD->gain_prec_swb_fx ) ); + + set16_fx( st->hBWE_TD->dec_2_over_3_mem_fx, 0, L_FILT_2OVER3 ); + set16_fx( st->hBWE_TD->dec_2_over_3_mem_lp_fx, 0, L_FILT_2OVER3_LP ); + } + ELSE IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && ( ( EQ_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || ( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_32( st->last_total_brate, st->total_brate ) ) || ( NE_16( st->last_bwidth, st->bwidth ) ) || ( NE_16( st->last_codec_mode, MODE1 ) ) || ( NE_16( st->rf_mode_last, st->rf_mode ) ) ) ) + { + set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + } + ELSE IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) + { + TBEreset_enc_fx( st, st->bwidth ); + } + + test(); + test(); + test(); + test(); + /* Interp_3_2 CNG buffers reset */ + IF( EQ_16( st->extl, FB_TBE ) && ( ( NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) || NE_16( st->L_frame, st->last_L_frame ) ) ) + { + set16_fx( st->hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->fb_tbe_demph_fx = 0; + move16(); + fb_tbe_reset_enc_fx( st->hBWE_TD->elliptic_bpf_2_48k_mem_fx, &st->hBWE_TD->prev_fb_energy_fx, st->hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &st->hBWE_TD->prev_fb_energy_fx_Q ); + } + /* Fade towards init value for non HQ_CORE */ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) ) ) ); /*crest_lp_q*/ + move32(); + st->hHQ_core->crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_mod_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ) ) ); /*crest_mod_lp_q*/ + move32(); + } + } + + return; +} diff --git a/lib_enc/corr_xh.c b/lib_enc/corr_xh.c deleted file mode 100644 index 9fd3cb8a2..000000000 --- a/lib_enc/corr_xh.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" diff --git a/lib_enc/decision_matrix_enc.c b/lib_enc/decision_matrix_enc.c deleted file mode 100644 index 5e0c266ca..000000000 --- a/lib_enc/decision_matrix_enc.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "prot_fx_enc.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/detect_transient.c b/lib_enc/detect_transient.c deleted file mode 100644 index c2bbde080..000000000 --- a/lib_enc/detect_transient.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/diffcod.c b/lib_enc/diffcod.c deleted file mode 100644 index 9f6bb4283..000000000 --- a/lib_enc/diffcod.c +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------------------*/ -/* Function diffcod() */ -/* */ -/* Differential coding for indices of quantized norms */ -/*--------------------------------------------------------------------------*/ - -void diffcod( - const int16_t N, /* i : number of sub-vectors */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx /* o : differential code */ -) -{ - int16_t i, k, r; - - for ( i = N - 1; i > 0; i-- ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k < ( -15 ) ) - { - y[r] = y[i] + 15; - } - } - - for ( i = 1; i < N; i++ ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k > 16 ) - { - k = 16; - y[i] = y[r] + 16; - } - difidx[r] = k + 15; - } - - return; -} - - -/*-------------------------------------------------------------------------- - * diffcod_lrmdct() - * - * Differential coding for indices of quantized norms - *--------------------------------------------------------------------------*/ - -void diffcod_lrmdct( - const int16_t N, /* i : number of sub-vectors */ - const int16_t be_ref, /* i : band energy reference */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx, /* o : differential code */ - const int16_t is_transient /* i : transient flag */ -) -{ - int16_t i, m, r; - int16_t k; - int16_t thr_l, thr_h; - - if ( is_transient ) - { - thr_l = -15; - thr_h = 16; - } - else - { - thr_l = -32; - thr_h = 31; - } - - difidx[0] = y[0] - be_ref; - if ( difidx[0] > thr_h ) - { - difidx[0] = thr_h; - y[0] = be_ref + thr_h; - } - - if ( difidx[0] < thr_l ) - { - difidx[0] = thr_l; - y[0] = be_ref + thr_l; - } - - m = N - 1; - for ( i = m; i > 0; i-- ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k < thr_l ) - { - y[r] = y[i] - thr_l; - } - } - - for ( i = 1; i < N; i++ ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k > thr_h ) - { - k = thr_h; - y[i] = y[r] + thr_h; - } - difidx[i] = k; - } - - return; -} diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c deleted file mode 100644 index 726508b0c..000000000 --- a/lib_enc/dtx.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_acelp.c b/lib_enc/enc_acelp.c deleted file mode 100644 index bf5688ef1..000000000 --- a/lib_enc/enc_acelp.c +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" - - -/* - * acelp_2pulse_search - * - * Parameters: - * nb_pos_ix I: nb of pos for pulse 1 (1..8) - * track_x I: track of pulse 1 - * track_y I: track of pulse 2 - * ps I/O: correlation of all fixed pulses - * alp I/O: energy of all fixed pulses - * ix O: position of pulse 1 - * iy O: position of pulse 2 - * dn I: corr. between target and h[] - * dn2 I: vector of selected positions - * cor_x I: corr. of pulse 1 with fixed pulses - * cor_y I: corr. of pulse 2 with fixed pulses - * rrixiy I: corr. of pulse 1 with pulse 2 - * - * Function: - * Find the best positions of 2 pulses in a subframe - * - * Returns: - * void - */ - - -/* - * E_ACELP_1pulse_search - * - * Parameters: - * track_x I: track of pulse 1 - * track_y I: track of pulse 2 - * ps I/O: correlation of all fixed pulses - * alp I/O: energy of all fixed pulses - * ix O: position of pulse 1 - * dn I: corr. between target and h[] - * cor_x I: corr. of pulse 1 with fixed pulses - * cor_y I: corr. of pulse 2 with fixed pulses - * - * Function: - * Find the best positions of 1 pulse in a subframe - * - * Returns: - * void - */ diff --git a/lib_enc/enc_acelp_tcx_main.c b/lib_enc/enc_acelp_tcx_main.c deleted file mode 100644 index d029c2fa8..000000000 --- a/lib_enc/enc_acelp_tcx_main.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_acelpx.c b/lib_enc/enc_acelpx.c deleted file mode 100644 index f6e2b0379..000000000 --- a/lib_enc/enc_acelpx.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_amr_wb.c b/lib_enc/enc_amr_wb.c deleted file mode 100644 index c899b52ff..000000000 --- a/lib_enc/enc_amr_wb.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_gain.c b/lib_enc/enc_gain.c deleted file mode 100644 index 491d5d2f3..000000000 --- a/lib_enc/enc_gain.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_gen_voic.c b/lib_enc/enc_gen_voic.c deleted file mode 100644 index c899b52ff..000000000 --- a/lib_enc/enc_gen_voic.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c deleted file mode 100644 index 554521732..000000000 --- a/lib_enc/enc_prm.c +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * writeTCXMode_fx() - * - * write TCX mode - *--------------------------------------------------------------------*/ - -void writeTCXMode_fx( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ - Word16 *nbits_start /* o : nbits start Q0*/ -) -{ - UWord16 index; - Word16 idx, start_idx; - Word16 nBits; - - IF( st->tcxonly ) - { - push_next_indice( hBstr, (UWord16) EQ_16( st->core, TCX_10_CORE ), 1 ); - - test(); - IF( EQ_16( st->clas, UNVOICED_CLAS ) ) - { - index = 0; - move16(); - } - ELSE IF( EQ_16( st->clas, VOICED_TRANSITION ) || EQ_16( st->clas, UNVOICED_TRANSITION ) ) - { - index = 1; - move16(); - } - ELSE IF( EQ_16( st->clas, VOICED_CLAS ) ) - { - index = 2; - move16(); - } - ELSE - { - index = 3; - move16(); - } - - push_next_indice( hBstr, index, 2 ); - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) - { - push_next_indice( hBstr, st->vad_flag, 1 ); - } - } - ELSE - { - IF( EQ_16( st->core, ACELP_CORE ) ) - { - /* write the RF signaling information */ - IF( EQ_16( st->rf_mode, 1 ) ) - { - /* find the section in the ACELP signaling table corresponding to bitrate */ - idx = 0; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) /* total bitrate is kept at 13.2kbps */ - { - idx = add( idx, 1 ); - } - - /* retrieve the number of bits for signaling */ - idx = add( idx, 1 ); /* Q0 */ - nBits = extract_l( acelp_sig_tbl[idx] ); /* Q0 */ - - /* retrieve the signaling index */ - idx = add( idx, 1 ); - start_idx = idx; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) - { - idx = add( idx, 1 ); - } - push_next_indice( hBstr, sub( idx, start_idx ), nBits ); - push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ - *nbits_start = 3; - move16(); - } - ELSE - { - push_next_indice( hBstr, st->coder_type, 3 ); - } - } - ELSE - { - IF( EQ_16( st->mdct_sw, MODE1 ) ) - { - /* 2 bits instead of 3 as TCX is already signaled */ - push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); - } - ELSE - { - IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) - { - push_next_indice( hBstr, 1, 1 ); /* TCX */ - push_next_indice( hBstr, 0, 1 ); /* not HQ_CORE */ - push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); - } - ELSE - { - /*write the RF signaling information*/ - IF( EQ_16( st->rf_mode, 1 ) ) - { - /* find the section in the ACELP signaling table corresponding to bitrate */ - idx = 0; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) - { - idx = add( idx, 1 ); - } - - /* retrieve the number of bits for signaling */ - idx = add( idx, 1 ); - nBits = extract_l( acelp_sig_tbl[idx] ); - - test(); - test(); - IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) || EQ_16( st->hTcxCfg->coder_type, GENERIC ) || EQ_16( st->hTcxCfg->coder_type, TRANSITION ) ) - { - st->sharpFlag = 1; - move16(); - } - ELSE - { - st->sharpFlag = 0; - move16(); - } - - /* retrieve the signaling index */ - idx = add( idx, 1 ); - start_idx = idx; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->hTcxCfg->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) - { - idx = add( idx, 1 ); - } - push_next_indice( hBstr, sub( idx, start_idx ), nBits ); - push_next_indice( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ - *nbits_start = 3; - move16(); - } - ELSE - { - push_next_indice( hBstr, add( ACELP_MODE_MAX, st->hTcxCfg->coder_type ), 3 ); - } - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * writeTCXWindowing_fx() - * - * write TCX transform type - *-------------------------------------------------------------------*/ - -void writeTCXWindowing_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 overlap_mode /* i : overlap mode Q0*/ -) -{ - - IF( EQ_16( overlap_mode, MIN_OVERLAP ) ) - { - push_next_indice( hBstr, 2, 2 ); - } - ELSE IF( EQ_16( overlap_mode, HALF_OVERLAP ) ) - { - push_next_indice( hBstr, 3, 2 ); - } - ELSE - { - push_next_indice( hBstr, 0, 1 ); - } - - return; -} diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index d394fa2d3..da2ea5863 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -11,7 +11,7 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -//#include "prot_fx.h" +#include "prot.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -1512,3 +1512,190 @@ void writeTCXparam_fx( return; } + +/*-------------------------------------------------------------------* + * writeTCXMode_fx() + * + * write TCX mode + *--------------------------------------------------------------------*/ + +void writeTCXMode_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + Word16 *nbits_start /* o : nbits start Q0*/ +) +{ + UWord16 index; + Word16 idx, start_idx; + Word16 nBits; + + IF( st->tcxonly ) + { + push_next_indice( hBstr, (UWord16) EQ_16( st->core, TCX_10_CORE ), 1 ); + + test(); + IF( EQ_16( st->clas, UNVOICED_CLAS ) ) + { + index = 0; + move16(); + } + ELSE IF( EQ_16( st->clas, VOICED_TRANSITION ) || EQ_16( st->clas, UNVOICED_TRANSITION ) ) + { + index = 1; + move16(); + } + ELSE IF( EQ_16( st->clas, VOICED_CLAS ) ) + { + index = 2; + move16(); + } + ELSE + { + index = 3; + move16(); + } + + push_next_indice( hBstr, index, 2 ); + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) + { + push_next_indice( hBstr, st->vad_flag, 1 ); + } + } + ELSE + { + IF( EQ_16( st->core, ACELP_CORE ) ) + { + /* write the RF signaling information */ + IF( EQ_16( st->rf_mode, 1 ) ) + { + /* find the section in the ACELP signaling table corresponding to bitrate */ + idx = 0; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) /* total bitrate is kept at 13.2kbps */ + { + idx = add( idx, 1 ); + } + + /* retrieve the number of bits for signaling */ + idx = add( idx, 1 ); /* Q0 */ + nBits = extract_l( acelp_sig_tbl[idx] ); /* Q0 */ + + /* retrieve the signaling index */ + idx = add( idx, 1 ); + start_idx = idx; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) + { + idx = add( idx, 1 ); + } + push_next_indice( hBstr, sub( idx, start_idx ), nBits ); + push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ + *nbits_start = 3; + move16(); + } + ELSE + { + push_next_indice( hBstr, st->coder_type, 3 ); + } + } + ELSE + { + IF( EQ_16( st->mdct_sw, MODE1 ) ) + { + /* 2 bits instead of 3 as TCX is already signaled */ + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); + } + ELSE + { + IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) + { + push_next_indice( hBstr, 1, 1 ); /* TCX */ + push_next_indice( hBstr, 0, 1 ); /* not HQ_CORE */ + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); + } + ELSE + { + /*write the RF signaling information*/ + IF( EQ_16( st->rf_mode, 1 ) ) + { + /* find the section in the ACELP signaling table corresponding to bitrate */ + idx = 0; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) + { + idx = add( idx, 1 ); + } + + /* retrieve the number of bits for signaling */ + idx = add( idx, 1 ); + nBits = extract_l( acelp_sig_tbl[idx] ); + + test(); + test(); + IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) || EQ_16( st->hTcxCfg->coder_type, GENERIC ) || EQ_16( st->hTcxCfg->coder_type, TRANSITION ) ) + { + st->sharpFlag = 1; + move16(); + } + ELSE + { + st->sharpFlag = 0; + move16(); + } + + /* retrieve the signaling index */ + idx = add( idx, 1 ); + start_idx = idx; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->hTcxCfg->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) + { + idx = add( idx, 1 ); + } + push_next_indice( hBstr, sub( idx, start_idx ), nBits ); + push_next_indice( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ + *nbits_start = 3; + move16(); + } + ELSE + { + push_next_indice( hBstr, add( ACELP_MODE_MAX, st->hTcxCfg->coder_type ), 3 ); + } + } + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * writeTCXWindowing_fx() + * + * write TCX transform type + *-------------------------------------------------------------------*/ + +void writeTCXWindowing_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 overlap_mode /* i : overlap mode Q0*/ +) +{ + + IF( EQ_16( overlap_mode, MIN_OVERLAP ) ) + { + push_next_indice( hBstr, 2, 2 ); + } + ELSE IF( EQ_16( overlap_mode, HALF_OVERLAP ) ) + { + push_next_indice( hBstr, 3, 2 ); + } + ELSE + { + push_next_indice( hBstr, 0, 1 ); + } + + return; +} diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c deleted file mode 100644 index 3b1b81730..000000000 --- a/lib_enc/fd_cng_enc.c +++ /dev/null @@ -1,1172 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "stat_enc.h" -#include "wmc_auto.h" - -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * initFdCngEnc() - * - * Initialize FD_CNG - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * deleteFdCngEnc() - * - * Delete the instance of type FD_CNG - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * resetFdCngEnc() - * - * Reset the instance of type FD_CNG - *-------------------------------------------------------------------*/ -/*-------------------------------------------------------------------* - * perform_noise_estimation_enc() - * - * Perform noise estimation - *-------------------------------------------------------------------*/ -void perform_noise_estimation_enc_ivas_fx( - Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/ - Word16 band_energies_exp, - Word32 *enerBuffer, /* enerBuffer_exp */ - Word16 enerBuffer_exp, - HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ - const Word32 input_Fs, /* i : input sampling rate Q0*/ - CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */ -) -{ - Word16 i, j, s, s1, s2; - Word16 numBands; - Word16 numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands; /* Q0 */ - move16(); - Word16 regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; /* Q0 */ - move16(); - Word16 numSlots = hFdCngEnc->hFdCngCom->numSlots; /* Q0 */ - move16(); - assert( numSlots == 16 ); - - Word32 numSlots_inv_fx = 1073741824; // Q34 of .0625 - move32(); - Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; /* exp(peridog_exp) */ - Word32 *ptr_per_fx = periodog; - Word64 periodog_64; - Word16 periodog_exp[PERIODOGLEN]; - Word16 npart = hFdCngEnc->hFdCngCom->npart; /* Q0 */ - move16(); - Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; /* Q0 */ - move16(); - Word16 nCLDFBpart = hFdCngEnc->hFdCngCom->nCLDFBpart; /* Q0 */ - move16(); - - Word16 *psize = hFdCngEnc->hFdCngCom->psize; // 6Q9 - Word32 *msPeriodog_fx = hFdCngEnc->msPeriodog_fx; - Word32 *msNoiseEst_fx = hFdCngEnc->msNoiseEst_fx; /* exp(msNoiseEst_fx_exp) */ - - Word16 *msLogPeriodog_fx = hFdCngEnc->msLogPeriodog_fx; - Word16 *msLogNoiseEst_fx = hFdCngEnc->msLogNoiseEst_fx; - - Word32 scaleEB_fx = 0; - move32(); - Word32 tmp; - - test(); - IF( hCPE != NULL && hCPE->hStereoDft != NULL ) - { - // band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT; - // chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX; - // chan_width_bins = chan_width_f / band_res_dft; - - ///* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */ - // scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); - - ///* Scale with number of bins in one band */ - // scaleEB = scaleEB / chan_width_bins; - - SWITCH( input_Fs ) - { - case 8000: - scaleEB_fx = 251648; // Q35 - move32(); - BREAK; - case 16000: - scaleEB_fx = 62912; // Q35 - move32(); - BREAK; - case 32000: - scaleEB_fx = 15728; // Q35 - move32(); - BREAK; - case 48000: - scaleEB_fx = 6991; // Q35 - move32(); - BREAK; - default: - assert( 0 && "invalid sample rate" ); - } - } - ELSE - { - scaleEB_fx = Mpy_32_32( numSlots_inv_fx, L_deposit_l( hFdCngEnc->hFdCngCom->scalingFactor ) ); // Q34 + Q30 - Q31 = Q33 - scaleEB_fx = L_shl( scaleEB_fx, 2 ); // Q35 - } - - /* preemphasis compensation and grouping of per bin energies into msPeriodog */ - FOR( i = 0; i < nFFTpart; i++ ) - { - tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); - msPeriodog_fx[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); - move32(); - } - - /* exponent for fft part of msPeriodog */ - hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP ); - move16(); - - Word16 max_exp = -31; - move16(); - i = 0; - move16(); - /* Adjust to the desired time resolution by averaging the periodograms over the time slots */ - FOR( j = numCoreBands; j < regularStopBand; j++ ) - { - periodog_64 = W_mult_32_32( enerBuffer[j], scaleEB_fx ); - Word16 scale = W_norm( periodog_64 ); - *ptr_per_fx = W_extract_h( W_shl( periodog_64, scale ) ); - move32(); - periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) ); - move16(); - max_exp = s_max( max_exp, periodog_exp[i] ); - - ptr_per_fx++; - i++; - } - /* exponent for cldfb part of msPeriodog */ - // hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP ); - // move16(); - - numBands = sub( regularStopBand, numCoreBands ); /* Q0 */ - FOR( i = 0; i < numBands; i++ ) - { - - periodog[i] = L_shr( periodog[i], sub( max_exp, periodog_exp[i] ) ); - - move16(); - } - hFdCngEnc->hFdCngCom->exp_cldfb_periodog = max_exp; - move16(); - IF( numBands > 0 ) - { - ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */ - bandcombinepow( - periodog, - hFdCngEnc->hFdCngCom->exp_cldfb_periodog, - numBands, - hFdCngEnc->hFdCngCom->CLDFBpart, - nCLDFBpart, - hFdCngEnc->hFdCngCom->CLDFBpsize_inv, - &msPeriodog_fx[nFFTpart], - &hFdCngEnc->msPeriodog_fx_exp_cldfb ); - - ///* find common exponent for fft part and cldfb part of msperiodog */ - s1 = getScaleFactor32( msPeriodog_fx, nFFTpart ); - s2 = getScaleFactor32( &msPeriodog_fx[nFFTpart], nCLDFBpart ); - - s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) ); - s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft ); - s2 = sub( s, hFdCngEnc->msPeriodog_fx_exp_cldfb ); - - hFdCngEnc->msPeriodog_fx_exp_fft = s; - move16(); - hFdCngEnc->msPeriodog_fx_exp_cldfb = s; - move16(); - - FOR( i = 0; i < nFFTpart; i++ ) - { - msPeriodog_fx[i] = L_shr( msPeriodog_fx[i], s1 ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ - move32(); - } - - FOR( i = 0; i < nCLDFBpart; i++ ) - { - msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s_min( 31, s2 ) ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ - move32(); - } - } - /* exponent for entire msPeriodog vector */ - hFdCngEnc->msPeriodog_fx_exp = hFdCngEnc->msPeriodog_fx_exp_fft; - move16(); - - /* Compress MS inputs */ - // compress_range_flt( msPeriodog, msLogPeriodog, npart ); - compress_range( msPeriodog_fx, hFdCngEnc->msPeriodog_fx_exp, msLogPeriodog_fx, npart ); - - - /* Call the minimum statistics routine for noise estimation */ - - minimum_statistics_fx( npart, nFFTpart, psize, msLogPeriodog_fx, hFdCngEnc->msNoiseFloor_fx, msLogNoiseEst_fx, hFdCngEnc->msAlpha_fx, hFdCngEnc->msPsd_fx, hFdCngEnc->msPsdFirstMoment_fx, - hFdCngEnc->msPsdSecondMoment_fx, hFdCngEnc->msMinBuf_fx, hFdCngEnc->msBminWin_fx, hFdCngEnc->msBminSubWin_fx, hFdCngEnc->msCurrentMin_fx, hFdCngEnc->msCurrentMinOut_fx, hFdCngEnc->msCurrentMinSubWindow_fx, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf_fx, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom, - ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode ); - - /* Expand MS outputs */ - expand_range( msLogNoiseEst_fx, msNoiseEst_fx, &hFdCngEnc->msNoiseEst_fx_exp, hFdCngEnc->hFdCngCom->npart ); - - return; -} - - -/*-------------------------------------------------------------------* - * FdCng_encodeSID() - * - * Generate a bitstream out of the partition levels - *-------------------------------------------------------------------*/ -void FdCng_encodeSID_ivas_fx( - Encoder_State *st /* i/o: encoder state structure */ -) -{ - Word16 N; - HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc; - HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - BSTR_ENC_HANDLE hBstr = st->hBstr; - - Word32 *invTrfMatrix_fx, *E_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word32 v_fx[32], gain_fx, e_fx, temp; - Word16 w_fx[32], indices[32], exp[32]; - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; - Word16 v_e, gain_q_offset, preemph_fac; - Word16 i, index; - - gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0; - move16(); - - if ( st->element_mode == EVS_MONO ) - { - gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0; - move16(); - } - - preemph_fac = st->preemph_fac; // Q15 - move16(); - - /* Init */ - N = hFdCngEnc->npartDec; - move16(); - - E_fx = hFdCngEnc->msNoiseEst_fx; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - - set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); - - /* Convert to LOG */ - e_fx = 0; - move32(); - FOR( i = 0; i < N; i++ ) - { - IF( E_fx[i] == 0 ) - { - /* 10 * log(1e-4) = 10 * (-4) = -40 */ - v_fx[i] = -41943040; // -40.0 in Q20 - move32(); - } - ELSE - { - v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], hFdCngEnc->msNoiseEst_fx_exp ) ); // Q20 = 26+25-31 - move32(); - } - e_fx = L_add( e_fx, v_fx[i] ); // Q20 - } - - /* Normalize MSVQ input */ - gain_fx = 0; - move32(); - FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) - { - gain_fx = L_add( gain_fx, v_fx[i] ); // Q20 - } - - /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ - gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20 - - FOR( i = 0; i < N; i++ ) - { - v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20 - move32(); - } - - v_e = 11; // Q20 - move16(); - - /* MSVQ encoder */ - set_val_Word16( w_fx, ONE_IN_Q8, N ); - - IF( st->element_mode != EVS_MONO ) - { - /* DCT domain compressed/truncated indices used for first stage */ - /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched - in FDCNG band domain - */ - IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) - { - /* truncated DCT21 analysis */ - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 - - dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20 - - /* truncated IDCT21 extension to 24 bands */ - extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20 - - Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20 - } - - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 - - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); - - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); - - v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); - } - ELSE - { /* EVS_MONO tables */ - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices ); - - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 ); - - v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); - } - - /* Compute gain */ - gain_fx = 0; - move32(); - FOR( i = 0; i < N; i++ ) - { - gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e - } - - e_fx = L_shl( e_fx, sub( 11, v_e ) ); // Q = 31 - v_e - gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e - gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 - - /* Apply bitrate-dependant scale */ - IF( st->element_mode > EVS_MONO ) - { - apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - } - ELSE - { - apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); - } - - /* Quantize gain */ - temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 - index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 - - if ( index < 0 ) - { - index = 0; - move16(); - } - - if ( GT_16( index, 127 ) ) - { - index = 127; - move16(); - } - - gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e - - /* Apply gain and undo log */ - FOR( i = 0; i < N; i++ ) - { - temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e - hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); - move32(); - } - - maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); - - FOR( i = 0; i < N; i++ ) - { - hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp - move32(); - } - - /* NB last band energy compensation */ - IF( hFdCngCom->CngBandwidth == NB ) - { - hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) - move32(); - } - - test(); - IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) - move32(); - } - - /* Write bitstream */ - IF( EQ_16( st->codec_mode, MODE2 ) ) - { - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - push_next_indice( hBstr, indices[i], bits_37bits[i] ); - } - - push_next_indice( hBstr, index, 7 ); - } - ELSE - { - Word16 is_frame_len_16k = 0; - move16(); - if ( EQ_16( st->L_frame, L_FRAME16k ) ) - { - is_frame_len_16k = 1; - move16(); - } - push_indice( hBstr, IND_SID_TYPE, 1, 1 ); - push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 ); - push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); - - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); - } - - push_indice( hBstr, IND_ENERGY, index, 7 ); - } - - /* Interpolate the bin/band-wise levels from the partition levels */ - scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); - - return; -} - - -/*-------------------------------------------------------------------* - * stereoFdCngCoherence() - * - * compute coherence of channels for use in FD-CNG - *-------------------------------------------------------------------*/ -void stereoFdCngCoherence_fx( - Encoder_State **sts, /* i/o: core encoder structures */ - const Word16 last_element_mode, /* i : last element mode Q0*/ - Word16 fft_buf_fx[CPE_CHANNELS][2 * L_FFT], /* i : fft buffers for L and R channels fft_exp*/ - Word16 fft_exp ) -{ - const Word16 *pt_fftL, *pt_fftR; - Word16 i_subfr, i; - Word32 cr, ci, eL, eR; - Word16 cr_exp, ci_exp, eL_exp, eR_exp; - Word32 *mem; - Word16 *mem_exp; - - IF( NE_16( last_element_mode, IVAS_CPE_MDCT ) ) - { - set32_fx( sts[0]->hFdCngEnc->mem_coherence_fx, EPSILON_FX, 4 ); - set16_fx( sts[0]->hFdCngEnc->mem_coherence_exp, 0, 4 ); - } - test(); - test(); - IF( EQ_32( sts[0]->core_brate, -1 ) || EQ_32( sts[1]->core_brate, -1 ) ) - { - /* case: at least one channel has triggered VAD -> ACTIVE FRAME */ - IF( EQ_32( sts[0]->core_brate, -1 ) ) - { - sts[1]->total_brate = sts[0]->total_brate; /* Q0 */ - move32(); - sts[1]->active_cnt = sts[0]->active_cnt; /* Q0 */ - move16(); - if ( GE_32( sts[1]->active_cnt, CNG_TYPE_HO ) ) - { - sts[1]->last_total_brate_cng = -1; - move16(); - } - } - IF( EQ_32( sts[1]->core_brate, -1 ) ) - { - sts[0]->total_brate = sts[1]->total_brate; /* Q0 */ - move32(); - sts[0]->active_cnt = sts[1]->active_cnt; /* Q0 */ - move16(); - if ( GE_16( sts[0]->active_cnt, CNG_TYPE_HO ) ) - { - sts[0]->last_total_brate_cng = -1; - move16(); - } - } - sts[0]->core_brate = -1; - move32(); - sts[1]->core_brate = -1; - move32(); - sts[0]->hDtxEnc->cnt_SID = 0; - move16(); - sts[1]->hDtxEnc->cnt_SID = 0; - move16(); - } - ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) ) - { - /* case: no VAD for both channels -> INACTIVE FRAME */ - reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); - - reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); - - /* synchronize SID sending for variable SID rate */ - IF( EQ_32( sts[0]->core_brate, sts[1]->core_brate ) ) - { - sts[0]->core_brate = SID_2k40; - move32(); - sts[1]->core_brate = SID_2k40; - move32(); - } - - /* synchronize SID counters */ - sts[0]->hDtxEnc->cnt_SID = s_min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); /* Q0 */ - sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; /* Q0 */ - move16(); - move16(); - } - - pt_fftL = fft_buf_fx[0]; - pt_fftR = fft_buf_fx[1]; - mem = sts[0]->hFdCngEnc->mem_coherence_fx; /* exp(sts[0]->hFdCngEnc->mem_coherence_exp) */ - mem_exp = sts[0]->hFdCngEnc->mem_coherence_exp; - FOR( i_subfr = 0; i_subfr < 2; i_subfr++ ) - { - cr = ci = eL = eR = EPSILON_FX; - move32(); - move32(); - move32(); - move32(); - cr_exp = ci_exp = eL_exp = eR_exp = 0; - move16(); - move16(); - move16(); - move16(); - - cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[0], pt_fftR[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */ - eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[0], pt_fftL[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftL[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */ - eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[0], pt_fftR[0] ), L_mult( pt_fftR[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */ - - FOR( i = 1; i < L_FFT / 2; i++ ) - { - cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[i], pt_fftR[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */ - ci = BASOP_Util_Add_Mant32Exp( ci, ci_exp, L_add( L_mult( -pt_fftL[i], pt_fftR[L_FFT - i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[i] ) ), shl( fft_exp, 1 ), &ci_exp ); /* exp(ci_exp) */ - eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[i], pt_fftL[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftL[L_FFT - i] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */ - eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[i], pt_fftR[i] ), L_mult( pt_fftR[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */ - } - test(); - test(); - IF( LE_32( sts[0]->ini_frame, 50 ) || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) - { - mem[0] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[0], 31129 /*0.95f*/ ), mem_exp[0], Mpy_32_16_1( cr, 1638 /*0.05f*/ ), cr_exp, &mem_exp[0] ); /* exp(mem_exp[0]) */ - move32(); - mem[1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[1], 31129 /*0.95f*/ ), mem_exp[1], Mpy_32_16_1( ci, 1638 /*0.05f*/ ), ci_exp, &mem_exp[1] ); /* exp(mem_exp[1]) */ - move32(); - mem[2] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[2], 31129 /*0.95f*/ ), mem_exp[2], Mpy_32_16_1( eL, 1638 /*0.05f*/ ), eL_exp, &mem_exp[2] ); /* exp(mem_exp[2]) */ - move32(); - mem[3] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[3], 31129 /*0.95f*/ ), mem_exp[3], Mpy_32_16_1( eR, 1638 /*0.05f*/ ), eR_exp, &mem_exp[3] ); /* exp(mem_exp[3]) */ - move32(); - } - - pt_fftL += L_FFT; - pt_fftR += L_FFT; - } - - Word16 sqr_inp, temp, sqr_out, sqr_inp_exp; - Word32 sqr_inp32 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( mem[0], mem[0] ), shl( mem_exp[0], 1 ), Mpy_32_32( mem[1], mem[1] ), shl( mem_exp[1], 1 ), &sqr_inp_exp ); /* exp(sqr_inp_exp) */ - sqr_inp = BASOP_Util_Divide3232_Scale( sqr_inp32, Mpy_32_32( mem[2], mem[3] ), &temp ); - sqr_inp_exp = add( temp, sub( sqr_inp_exp, add( mem_exp[2], mem_exp[3] ) ) ); - sqr_out = Sqrt16( sqr_inp, &sqr_inp_exp ); - sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = shl_sat( sqr_out, sqr_inp_exp ); // Q15 expected. - move16(); - return; -} - -/*-------------------------------------------------------------------* - * FdCngEncodeMDCTStereoSID() - * - * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX - *-------------------------------------------------------------------*/ - -void FdCngEncodeMDCTStereoSID_fx( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -) -{ - ENC_CORE_HANDLE sts[CPE_CHANNELS]; - Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; - Word16 gain_idx[CPE_CHANNELS]; - Word16 N, stages, ch, p, coh_idx; - Word32 *lr_in_ptr_fx[CPE_CHANNELS]; - Word16 lr_in_ptr_e[CPE_CHANNELS]; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word16 ms_ptr_e; - Word32 *lr_out_ptr_fx[CPE_CHANNELS]; - Word16 lr_out_ptr_e[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 E_fx[CPE_CHANNELS]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 weights_fx[NPART]; - Word32 side_energy_fx; - Word16 Qside_energy; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/ - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN], dct_target_fx[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/ - Word16 tmp, tmp_e; - Word16 no_side_flag; - Word16 is_inp_ms; - Word16 size_value, temp_e, gb, shift; - Word32 tmp32, t1, t2; - - is_inp_ms = 0; - move16(); - IF( EQ_16( hCPE->hCoreCoder[0]->cng_sba_flag, 1 ) ) - { - is_inp_ms = 1; - move16(); - } - - /* set pointers and initialize */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; /* exp(sts[ch]->hFdCngEnc->msNoiseEst_fx_exp) */ - lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; - lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; /* exp(sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp) */ - lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; - } - N = sts[0]->hFdCngEnc->npartDec; /* Q0 */ - move16(); - set16_fx( weights_fx, ONE_IN_Q8, NPART ); - - /* apply log and save energy of original left and right channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - // E[ch] = 0.0f; - E_fx[ch] = 0; - move32(); - FOR( p = 0; p < N; p++ ) - { - IF( lr_in_ptr_fx[ch][p] ) - { - t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25 - t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 - } - ELSE - { - t2 = 0; - move32(); - } - ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 - move32(); - E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19 - move32(); - } - } - ms_ptr_e = Q31 - Q23; - move16(); - - /* M/S transform on log envelopes */ - IF( is_inp_ms == 0 ) - { - convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); // ms_ptr_e = Q23; - } - - gb = find_guarded_bits_fx( N ); - side_energy_fx = sum2_f_32_fx( ms_ptr_fx[1], N, gb ); - Qside_energy = sub( sub( shl( sub( 31, ms_ptr_e ), 1 ), 31 ), gb ); - - /* do not transmit side shape if initial noise shapes are very similar */ - IF( LE_32( side_energy_fx, L_shl( 214748365, sub( Qside_energy, Q31 ) ) ) ) - { - no_side_flag = 1; - move16(); - } - ELSE - { - no_side_flag = 0; - move16(); - } - - /* Quantize noise shapes */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - /* Normalize MSVQ input */ - gain_fx[ch] = 0; - move32(); - FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) - { - tmp32 = Mpy_32_32( ms_ptr_fx[ch][p], 165191050 /* 0.07 in Q31*/ ); // Q23 - gain_fx[ch] = L_add( gain_fx[ch], tmp32 ); // Q23 - move32(); - } - - FOR( p = 0; p < N; p++ ) - { - ms_ptr_fx[ch][p] = L_sub( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q23 - move32(); - } - } - - /* always split channel targetloop */ - - /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */ - /* High quality cosine smooth basis extension used to not introduce noise in stage#1 DCT24 analysis and subsequent VQ-steps */ - IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) - { - size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ - size_value = shr( size_value, sub( 15, temp_e ) ); - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, size_value ); // Q31 /*WB: create truncated IDCT21 matrix */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/ - /* truncated DCT 21 analysis */ - dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[ch], dct_target_fx[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); - /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors, - estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated length 24 input target envelope signal */ - /* this DCT21 extension does not introduce DCT24 coefficient noise for the subsequent dct24 target analysis, and later in IDCT24 synthesis */ - - /* truncated IDCT 21 extension synthesis */ - extend_dctN_input_fx( ms_ptr_fx[ch], dct_target_fx[ch], N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ - - Copy32( tot_sig_ext_fx, ms_ptr_fx[ch], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ */ - } - } - - size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ - size_value = shr( size_value, sub( 15, temp_e ) ); - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, size_value ); /*always create/set up IDCT24 matrix in RAM */ - - /* end split */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - /* MSVQ */ - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - move16(); - } - ELSE - { - stages = FD_CNG_stages_37bits; - move16(); - } - - /* DCT24 domain compressed/truncated indices used for first stage */ - /* mid channel quantization using stages 1 through 6 */ - /* & side channel quantization using stages 1 through 4 */ - - { - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[ch], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, stages, weights_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[ch] ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); - } - } - shift = find_guarded_bits_fx( N ); - ms_ptr_e = sub( 31, sub( 20, shift ) ); - - IF( no_side_flag ) - { - set32_fx( ms_ptr_fx[1], 0, N ); - } - - /* undo M/S */ - IF( is_inp_ms == 0 ) - { - convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - } - - /* Compute gain against original left and right channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - gain_fx[ch] = 0; - move32(); - - tmp_e = 15; - move16(); - tmp = Inv16( N, &tmp_e ); - FOR( p = 0; p < N; p++ ) - { - gain_fx[ch] = L_add( gain_fx[ch], Mpy_32_16_1( ms_ptr_fx[ch][p], shl( tmp, tmp_e ) ) ); // Q23 - move32(); - } - gain_fx[ch] = L_sub( L_shl( Mpy_32_16_1( E_fx[ch], shl( tmp, tmp_e ) ), Q23 - Q19 ), L_shl( gain_fx[ch], sub( ms_ptr_e, 8 ) ) ); // Q23 - move32(); - - apply_scale( &gain_fx[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - - /* quantize gain */ - gain_idx[ch] = (Word16) Mpy_32_32_r( L_add( gain_fx[ch], 251658240 ), 384 ); // Q23 - move16(); - gain_idx[ch] = s_max( 0, s_min( 127, gain_idx[ch] ) ); - move16(); - - gain_fx[ch] = Mpy_32_16_1( L_shl( sub( gain_idx[ch], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23 - move32(); - } - - /* restore channel noise envelopes */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; - HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - - tmp_e = 0; - move16(); - Word32 pow; - - Word16 e_lr_out[NPART]; - - FOR( p = 0; p < N; p++ ) - { - pow = L_shl( gain_fx[ch], 8 - ms_ptr_e ); - pow = L_add( ms_ptr_fx[ch][p], pow ); - pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/ - lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); - move32(); - tmp_e = s_max( tmp_e, e_lr_out[p] ); - } - - FOR( p = 0; p < N; p++ ) - { - lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], e_lr_out[p] - tmp_e ); - move32(); - } - lr_out_ptr_e[ch] = tmp_e; - move32(); - - sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; - move16(); - - /* scale bands and get scalefactors */ - scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); - - sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; - } - - /* quantize channel coherence */ - coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 ); - coh_idx = max( 0, min( coh_idx, 15 ) ); - - /* ---- Write SID bitstream ---- */ - - - /* noise shapes and channel gains */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; - - /* side info */ - push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 ); - push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 ); - } - ELSE - { - stages = FD_CNG_stages_37bits; - /* side info */ - push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 ); - push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); - push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 ); - } - - FOR( Word16 i = 0; i < stages; i++ ) - { - push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] ); - } - push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 ); - } - - /* pad with zeros to reach common SID frame size */ - push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); - - return; -} - -/*-------------------------------------------------------------------* - * FdCngEncodeDiracMDCTStereoSID() - * - * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX - * together with Dirac - *-------------------------------------------------------------------*/ - -void FdCngEncodeDiracMDCTStereoSID_fx( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -) -{ - ENC_CORE_HANDLE sts[CPE_CHANNELS]; - Word32 *lr_in_ptr_fx[CPE_CHANNELS]; - Word16 lr_in_ptr_e[CPE_CHANNELS]; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word16 ms_ptr_e; - Word32 *lr_out_ptr_fx[CPE_CHANNELS]; - Word16 lr_out_ptr_e[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 E_fx[CPE_CHANNELS]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 weights_fx[NPART]; - Word16 N[CPE_CHANNELS]; - Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; - Word16 gain_idx[CPE_CHANNELS]; - Word16 ch, p; - Word16 tmp, tmp_e, shift; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - Word32 t1, t2, tmp32; - /* set pointers and initialize */ - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - N[ch] = sts[ch]->hFdCngEnc->npartDec; - lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; - lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; - lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; - lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; - move16(); - } - set16_fx( weights_fx, ONE_IN_Q8, NPART ); - - /* apply log and save energy of original left and right channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - // E[ch] = 0.0f; - E_fx[ch] = 0; - move32(); - FOR( p = 0; p < N[ch]; p++ ) - { - t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] + EPSILLON_FX ); // Q25 - t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 - ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 - move32(); - E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 5 ) ); // Q18 - move32(); - } - } - ms_ptr_e = Q31 - Q23; - move16(); - - /* M/S transform on log envelopes */ - convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); - E_fx[0] = 0; - move32(); - FOR( p = 0; p < N[0]; p++ ) - { - E_fx[0] = L_add( E_fx[0], L_shr( ms_ptr_fx[0][p], 5 ) ); // Q18 - move32(); - } - - /* Quantize M noise shape */ - /* Normalize MSVQ input */ - gain_fx[0] = 0; - move16(); - FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) - { - tmp32 = Mpy_32_32( ms_ptr_fx[0][p], 165191050 /* 0.07 in Q31 */ ); // Q23 - gain_fx[0] = L_add( gain_fx[0], tmp32 ); // Q23 - move32(); - } - - FOR( p = 0; p < N[0]; p++ ) - { - ms_ptr_fx[0][p] = L_sub( ms_ptr_fx[0][p], gain_fx[0] ); // Q23 - move32(); - } - - - /* MSVQ */ - /* DCT domain compressed/truncated indices used for first stage */ - /* mid quantization using stages #1 through 6 */ - scale_sig32( ms_ptr_fx[0], N[0], -6 ); - ms_ptr_e = add( ms_ptr_e, 6 ); - move16(); - IF( EQ_16( N[0], FDCNG_VQ_MAX_LEN_WB ) ) - { - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); - /* truncated DCT 21 analysis */ - dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[0], dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); - /* truncated IDCT21 extension to 24 synthesis */ - - extend_dctN_input_fx( ms_ptr_fx[0], dct_target_fx, N[0], tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ - - Copy32( tot_sig_ext_fx, ms_ptr_fx[0], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 Q23*/ - } - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); - - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[0], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights_fx, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[0] ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); - shift = find_guarded_bits_fx( N[0] ); - ms_ptr_e = sub( 31, sub( 20, shift ) ); - scale_sig32( ms_ptr_fx[1], N[1], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */ - - /* set S to zero */ - set32_fx( ms_ptr_fx[1], 0, NPART ); - - /* compute M gain */ - gain_fx[0] = 0; - move32(); - tmp_e = 15; - move16(); - tmp = Inv16( N[0], &tmp_e ); - FOR( p = 0; p < N[0]; p++ ) - { - gain_fx[0] = L_add( gain_fx[0], Mpy_32_16_1( ms_ptr_fx[0][p], shl( tmp, tmp_e ) ) ); // Q23 - move32(); - } - gain_fx[0] = L_sub( L_shl( Mpy_32_16_1( E_fx[0], shl( tmp, tmp_e ) ), Q23 - Q18 ), L_shl( gain_fx[0], ms_ptr_e - 8 ) ); // Q23 - move32(); - - apply_scale( &gain_fx[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - - /* quantize gain */ - gain_idx[0] = extract_l( Mpy_32_32_r( L_add( gain_fx[0], 251658240 ), 384 ) ); - move16(); - gain_idx[0] = s_max( 0, s_min( 127, gain_idx[0] ) ); - move16(); - - gain_fx[0] = Mpy_32_16_1( L_shl( sub( gain_idx[0], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 /* 0.66 in Q15 */ ); // Q23 - move32(); - gain_fx[1] = gain_fx[0]; // Q23 - move32(); - - /* undo M/S */ - convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - - /* restore channel noise envelopes */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; - HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - - Word32 pow; - Word16 e_lr_out[NPART]; - tmp_e = -MAX_16; - FOR( p = 0; p < N[ch]; p++ ) - { - pow = L_shl( gain_fx[ch], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */ - pow = L_add( ms_ptr_fx[ch][p], pow ); /* Q31 - ms_ptr_e */ - pow = Mpy_32_32( pow, 214748365 /* 0.1 in Q31 */ ); /*pow = 0.1 Q31 - ms_ptr_e*/ - lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); - tmp_e = s_max( tmp_e, e_lr_out[p] ); - } - - FOR( p = 0; p < N[ch]; p++ ) - { - lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], sub( e_lr_out[p], tmp_e ) ); // Q(31 - tmp_e) - } - - sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; - move16(); - lr_out_ptr_e[ch] = tmp_e; - move16(); - - /* NB last band energy compensation */ - IF( hFdCngCom->CngBandwidth == NB ) - { - lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], NB_LAST_BAND_SCALE ); // Q(31 - tmp_e) - move32(); - } - ELSE IF( hFdCngCom->CngBandwidth == SWB && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], SWB_13k2_LAST_BAND_SCALE ); // Q(31 - tmp_e) - move32(); - } - /* scale bands and get scalefactors */ - scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; - move16(); - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); - sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; - } - sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = 0; - move16(); - sts[1]->hFdCngEnc->hFdCngCom->coherence_fx = 0; - move16(); - - /* ---- Write SID bitstream ---- */ - - /* side info */ - push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 ); - push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); - IF( EQ_16( sts[0]->L_frame, L_FRAME16k ) ) - { - push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 1, 1 ); - } - ELSE - { - push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 0, 1 ); - } - - /* noise shapes and channel gains */ - FOR( Word16 i = 0; i < FD_CNG_stages_37bits; i++ ) - { - push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] ); - } - push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 ); - - return; -} diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 93a954ae8..50f479d8d 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -14,6 +14,7 @@ #include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" +#include "ivas_prot_fx.h" #include "basop_util.h" #include "rom_basop_util.h" @@ -2267,3 +2268,1102 @@ Word16 cng_energy_ivas_fx( } return enr; } + +void perform_noise_estimation_enc_ivas_fx( + Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/ + Word16 band_energies_exp, + Word32 *enerBuffer, /* enerBuffer_exp */ + Word16 enerBuffer_exp, + HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ + CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */ +) +{ + Word16 i, j, s, s1, s2; + Word16 numBands; + Word16 numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands; /* Q0 */ + move16(); + Word16 regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; /* Q0 */ + move16(); + Word16 numSlots = hFdCngEnc->hFdCngCom->numSlots; /* Q0 */ + move16(); + assert( numSlots == 16 ); + + Word32 numSlots_inv_fx = 1073741824; // Q34 of .0625 + move32(); + Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; /* exp(peridog_exp) */ + Word32 *ptr_per_fx = periodog; + Word64 periodog_64; + Word16 periodog_exp[PERIODOGLEN]; + Word16 npart = hFdCngEnc->hFdCngCom->npart; /* Q0 */ + move16(); + Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; /* Q0 */ + move16(); + Word16 nCLDFBpart = hFdCngEnc->hFdCngCom->nCLDFBpart; /* Q0 */ + move16(); + + Word16 *psize = hFdCngEnc->hFdCngCom->psize; // 6Q9 + Word32 *msPeriodog_fx = hFdCngEnc->msPeriodog_fx; + Word32 *msNoiseEst_fx = hFdCngEnc->msNoiseEst_fx; /* exp(msNoiseEst_fx_exp) */ + + Word16 *msLogPeriodog_fx = hFdCngEnc->msLogPeriodog_fx; + Word16 *msLogNoiseEst_fx = hFdCngEnc->msLogNoiseEst_fx; + + Word32 scaleEB_fx = 0; + move32(); + Word32 tmp; + + test(); + IF( hCPE != NULL && hCPE->hStereoDft != NULL ) + { + // band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT; + // chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX; + // chan_width_bins = chan_width_f / band_res_dft; + + ///* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */ + // scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); + + ///* Scale with number of bins in one band */ + // scaleEB = scaleEB / chan_width_bins; + + SWITCH( input_Fs ) + { + case 8000: + scaleEB_fx = 251648; // Q35 + move32(); + BREAK; + case 16000: + scaleEB_fx = 62912; // Q35 + move32(); + BREAK; + case 32000: + scaleEB_fx = 15728; // Q35 + move32(); + BREAK; + case 48000: + scaleEB_fx = 6991; // Q35 + move32(); + BREAK; + default: + assert( 0 && "invalid sample rate" ); + } + } + ELSE + { + scaleEB_fx = Mpy_32_32( numSlots_inv_fx, L_deposit_l( hFdCngEnc->hFdCngCom->scalingFactor ) ); // Q34 + Q30 - Q31 = Q33 + scaleEB_fx = L_shl( scaleEB_fx, 2 ); // Q35 + } + + /* preemphasis compensation and grouping of per bin energies into msPeriodog */ + FOR( i = 0; i < nFFTpart; i++ ) + { + tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); + msPeriodog_fx[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); + move32(); + } + + /* exponent for fft part of msPeriodog */ + hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP ); + move16(); + + Word16 max_exp = -31; + move16(); + i = 0; + move16(); + /* Adjust to the desired time resolution by averaging the periodograms over the time slots */ + FOR( j = numCoreBands; j < regularStopBand; j++ ) + { + periodog_64 = W_mult_32_32( enerBuffer[j], scaleEB_fx ); + Word16 scale = W_norm( periodog_64 ); + *ptr_per_fx = W_extract_h( W_shl( periodog_64, scale ) ); + move32(); + periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) ); + move16(); + max_exp = s_max( max_exp, periodog_exp[i] ); + + ptr_per_fx++; + i++; + } + /* exponent for cldfb part of msPeriodog */ + // hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP ); + // move16(); + + numBands = sub( regularStopBand, numCoreBands ); /* Q0 */ + FOR( i = 0; i < numBands; i++ ) + { + + periodog[i] = L_shr( periodog[i], sub( max_exp, periodog_exp[i] ) ); + + move16(); + } + hFdCngEnc->hFdCngCom->exp_cldfb_periodog = max_exp; + move16(); + IF( numBands > 0 ) + { + ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */ + bandcombinepow( + periodog, + hFdCngEnc->hFdCngCom->exp_cldfb_periodog, + numBands, + hFdCngEnc->hFdCngCom->CLDFBpart, + nCLDFBpart, + hFdCngEnc->hFdCngCom->CLDFBpsize_inv, + &msPeriodog_fx[nFFTpart], + &hFdCngEnc->msPeriodog_fx_exp_cldfb ); + + ///* find common exponent for fft part and cldfb part of msperiodog */ + s1 = getScaleFactor32( msPeriodog_fx, nFFTpart ); + s2 = getScaleFactor32( &msPeriodog_fx[nFFTpart], nCLDFBpart ); + + s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) ); + s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft ); + s2 = sub( s, hFdCngEnc->msPeriodog_fx_exp_cldfb ); + + hFdCngEnc->msPeriodog_fx_exp_fft = s; + move16(); + hFdCngEnc->msPeriodog_fx_exp_cldfb = s; + move16(); + + FOR( i = 0; i < nFFTpart; i++ ) + { + msPeriodog_fx[i] = L_shr( msPeriodog_fx[i], s1 ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ + move32(); + } + + FOR( i = 0; i < nCLDFBpart; i++ ) + { + msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s_min( 31, s2 ) ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ + move32(); + } + } + /* exponent for entire msPeriodog vector */ + hFdCngEnc->msPeriodog_fx_exp = hFdCngEnc->msPeriodog_fx_exp_fft; + move16(); + + /* Compress MS inputs */ + // compress_range_flt( msPeriodog, msLogPeriodog, npart ); + compress_range( msPeriodog_fx, hFdCngEnc->msPeriodog_fx_exp, msLogPeriodog_fx, npart ); + + + /* Call the minimum statistics routine for noise estimation */ + + minimum_statistics_fx( npart, nFFTpart, psize, msLogPeriodog_fx, hFdCngEnc->msNoiseFloor_fx, msLogNoiseEst_fx, hFdCngEnc->msAlpha_fx, hFdCngEnc->msPsd_fx, hFdCngEnc->msPsdFirstMoment_fx, + hFdCngEnc->msPsdSecondMoment_fx, hFdCngEnc->msMinBuf_fx, hFdCngEnc->msBminWin_fx, hFdCngEnc->msBminSubWin_fx, hFdCngEnc->msCurrentMin_fx, hFdCngEnc->msCurrentMinOut_fx, hFdCngEnc->msCurrentMinSubWindow_fx, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf_fx, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom, + ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode ); + + /* Expand MS outputs */ + expand_range( msLogNoiseEst_fx, msNoiseEst_fx, &hFdCngEnc->msNoiseEst_fx_exp, hFdCngEnc->hFdCngCom->npart ); + + return; +} + + +/*-------------------------------------------------------------------* + * FdCng_encodeSID() + * + * Generate a bitstream out of the partition levels + *-------------------------------------------------------------------*/ +void FdCng_encodeSID_ivas_fx( + Encoder_State *st /* i/o: encoder state structure */ +) +{ + Word16 N; + HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + BSTR_ENC_HANDLE hBstr = st->hBstr; + + Word32 *invTrfMatrix_fx, *E_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 v_fx[32], gain_fx, e_fx, temp; + Word16 w_fx[32], indices[32], exp[32]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; + Word16 v_e, gain_q_offset, preemph_fac; + Word16 i, index; + + gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + + if ( st->element_mode == EVS_MONO ) + { + gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0; + move16(); + } + + preemph_fac = st->preemph_fac; // Q15 + move16(); + + /* Init */ + N = hFdCngEnc->npartDec; + move16(); + + E_fx = hFdCngEnc->msNoiseEst_fx; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + + set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); + + /* Convert to LOG */ + e_fx = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + IF( E_fx[i] == 0 ) + { + /* 10 * log(1e-4) = 10 * (-4) = -40 */ + v_fx[i] = -41943040; // -40.0 in Q20 + move32(); + } + ELSE + { + v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], hFdCngEnc->msNoiseEst_fx_exp ) ); // Q20 = 26+25-31 + move32(); + } + e_fx = L_add( e_fx, v_fx[i] ); // Q20 + } + + /* Normalize MSVQ input */ + gain_fx = 0; + move32(); + FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) + { + gain_fx = L_add( gain_fx, v_fx[i] ); // Q20 + } + + /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ + gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20 + + FOR( i = 0; i < N; i++ ) + { + v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20 + move32(); + } + + v_e = 11; // Q20 + move16(); + + /* MSVQ encoder */ + set_val_Word16( w_fx, ONE_IN_Q8, N ); + + IF( st->element_mode != EVS_MONO ) + { + /* DCT domain compressed/truncated indices used for first stage */ + /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched + in FDCNG band domain + */ + IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) + { + /* truncated DCT21 analysis */ + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 + + dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20 + + /* truncated IDCT21 extension to 24 bands */ + extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20 + + Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20 + } + + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 + + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); + + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); + + v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); + } + ELSE + { /* EVS_MONO tables */ + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices ); + + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 ); + + v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); + } + + /* Compute gain */ + gain_fx = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e + } + + e_fx = L_shl( e_fx, sub( 11, v_e ) ); // Q = 31 - v_e + gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e + gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 + + /* Apply bitrate-dependant scale */ + IF( st->element_mode > EVS_MONO ) + { + apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + } + ELSE + { + apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); + } + + /* Quantize gain */ + temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 + index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 + + if ( index < 0 ) + { + index = 0; + move16(); + } + + if ( GT_16( index, 127 ) ) + { + index = 127; + move16(); + } + + gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e + + /* Apply gain and undo log */ + FOR( i = 0; i < N; i++ ) + { + temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e + hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); + move32(); + } + + maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); + + FOR( i = 0; i < N; i++ ) + { + hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp + move32(); + } + + /* NB last band energy compensation */ + IF( hFdCngCom->CngBandwidth == NB ) + { + hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) + move32(); + } + + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) + move32(); + } + + /* Write bitstream */ + IF( EQ_16( st->codec_mode, MODE2 ) ) + { + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_next_indice( hBstr, indices[i], bits_37bits[i] ); + } + + push_next_indice( hBstr, index, 7 ); + } + ELSE + { + Word16 is_frame_len_16k = 0; + move16(); + if ( EQ_16( st->L_frame, L_FRAME16k ) ) + { + is_frame_len_16k = 1; + move16(); + } + push_indice( hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 ); + push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); + + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); + } + + push_indice( hBstr, IND_ENERGY, index, 7 ); + } + + /* Interpolate the bin/band-wise levels from the partition levels */ + scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); + + return; +} + + +/*-------------------------------------------------------------------* + * stereoFdCngCoherence() + * + * compute coherence of channels for use in FD-CNG + *-------------------------------------------------------------------*/ +void stereoFdCngCoherence_fx( + Encoder_State **sts, /* i/o: core encoder structures */ + const Word16 last_element_mode, /* i : last element mode Q0*/ + Word16 fft_buf_fx[CPE_CHANNELS][2 * L_FFT], /* i : fft buffers for L and R channels fft_exp*/ + Word16 fft_exp ) +{ + const Word16 *pt_fftL, *pt_fftR; + Word16 i_subfr, i; + Word32 cr, ci, eL, eR; + Word16 cr_exp, ci_exp, eL_exp, eR_exp; + Word32 *mem; + Word16 *mem_exp; + + IF( NE_16( last_element_mode, IVAS_CPE_MDCT ) ) + { + set32_fx( sts[0]->hFdCngEnc->mem_coherence_fx, EPSILON_FX, 4 ); + set16_fx( sts[0]->hFdCngEnc->mem_coherence_exp, 0, 4 ); + } + test(); + test(); + IF( EQ_32( sts[0]->core_brate, -1 ) || EQ_32( sts[1]->core_brate, -1 ) ) + { + /* case: at least one channel has triggered VAD -> ACTIVE FRAME */ + IF( EQ_32( sts[0]->core_brate, -1 ) ) + { + sts[1]->total_brate = sts[0]->total_brate; /* Q0 */ + move32(); + sts[1]->active_cnt = sts[0]->active_cnt; /* Q0 */ + move16(); + if ( GE_32( sts[1]->active_cnt, CNG_TYPE_HO ) ) + { + sts[1]->last_total_brate_cng = -1; + move16(); + } + } + IF( EQ_32( sts[1]->core_brate, -1 ) ) + { + sts[0]->total_brate = sts[1]->total_brate; /* Q0 */ + move32(); + sts[0]->active_cnt = sts[1]->active_cnt; /* Q0 */ + move16(); + if ( GE_16( sts[0]->active_cnt, CNG_TYPE_HO ) ) + { + sts[0]->last_total_brate_cng = -1; + move16(); + } + } + sts[0]->core_brate = -1; + move32(); + sts[1]->core_brate = -1; + move32(); + sts[0]->hDtxEnc->cnt_SID = 0; + move16(); + sts[1]->hDtxEnc->cnt_SID = 0; + move16(); + } + ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) ) + { + /* case: no VAD for both channels -> INACTIVE FRAME */ + reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); + + reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); + + /* synchronize SID sending for variable SID rate */ + IF( EQ_32( sts[0]->core_brate, sts[1]->core_brate ) ) + { + sts[0]->core_brate = SID_2k40; + move32(); + sts[1]->core_brate = SID_2k40; + move32(); + } + + /* synchronize SID counters */ + sts[0]->hDtxEnc->cnt_SID = s_min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); /* Q0 */ + sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; /* Q0 */ + move16(); + move16(); + } + + pt_fftL = fft_buf_fx[0]; + pt_fftR = fft_buf_fx[1]; + mem = sts[0]->hFdCngEnc->mem_coherence_fx; /* exp(sts[0]->hFdCngEnc->mem_coherence_exp) */ + mem_exp = sts[0]->hFdCngEnc->mem_coherence_exp; + FOR( i_subfr = 0; i_subfr < 2; i_subfr++ ) + { + cr = ci = eL = eR = EPSILON_FX; + move32(); + move32(); + move32(); + move32(); + cr_exp = ci_exp = eL_exp = eR_exp = 0; + move16(); + move16(); + move16(); + move16(); + + cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[0], pt_fftR[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */ + eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[0], pt_fftL[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftL[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */ + eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[0], pt_fftR[0] ), L_mult( pt_fftR[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */ + + FOR( i = 1; i < L_FFT / 2; i++ ) + { + cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[i], pt_fftR[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */ + ci = BASOP_Util_Add_Mant32Exp( ci, ci_exp, L_add( L_mult( -pt_fftL[i], pt_fftR[L_FFT - i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[i] ) ), shl( fft_exp, 1 ), &ci_exp ); /* exp(ci_exp) */ + eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[i], pt_fftL[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftL[L_FFT - i] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */ + eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[i], pt_fftR[i] ), L_mult( pt_fftR[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */ + } + test(); + test(); + IF( LE_32( sts[0]->ini_frame, 50 ) || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) + { + mem[0] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[0], 31129 /*0.95f*/ ), mem_exp[0], Mpy_32_16_1( cr, 1638 /*0.05f*/ ), cr_exp, &mem_exp[0] ); /* exp(mem_exp[0]) */ + move32(); + mem[1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[1], 31129 /*0.95f*/ ), mem_exp[1], Mpy_32_16_1( ci, 1638 /*0.05f*/ ), ci_exp, &mem_exp[1] ); /* exp(mem_exp[1]) */ + move32(); + mem[2] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[2], 31129 /*0.95f*/ ), mem_exp[2], Mpy_32_16_1( eL, 1638 /*0.05f*/ ), eL_exp, &mem_exp[2] ); /* exp(mem_exp[2]) */ + move32(); + mem[3] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[3], 31129 /*0.95f*/ ), mem_exp[3], Mpy_32_16_1( eR, 1638 /*0.05f*/ ), eR_exp, &mem_exp[3] ); /* exp(mem_exp[3]) */ + move32(); + } + + pt_fftL += L_FFT; + pt_fftR += L_FFT; + } + + Word16 sqr_inp, temp, sqr_out, sqr_inp_exp; + Word32 sqr_inp32 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( mem[0], mem[0] ), shl( mem_exp[0], 1 ), Mpy_32_32( mem[1], mem[1] ), shl( mem_exp[1], 1 ), &sqr_inp_exp ); /* exp(sqr_inp_exp) */ + sqr_inp = BASOP_Util_Divide3232_Scale( sqr_inp32, Mpy_32_32( mem[2], mem[3] ), &temp ); + sqr_inp_exp = add( temp, sub( sqr_inp_exp, add( mem_exp[2], mem_exp[3] ) ) ); + sqr_out = Sqrt16( sqr_inp, &sqr_inp_exp ); + sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = shl_sat( sqr_out, sqr_inp_exp ); // Q15 expected. + move16(); + return; +} + +/*-------------------------------------------------------------------* + * FdCngEncodeMDCTStereoSID() + * + * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX + *-------------------------------------------------------------------*/ + +void FdCngEncodeMDCTStereoSID_fx( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ +) +{ + ENC_CORE_HANDLE sts[CPE_CHANNELS]; + Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; + Word16 gain_idx[CPE_CHANNELS]; + Word16 N, stages, ch, p, coh_idx; + Word32 *lr_in_ptr_fx[CPE_CHANNELS]; + Word16 lr_in_ptr_e[CPE_CHANNELS]; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word16 ms_ptr_e; + Word32 *lr_out_ptr_fx[CPE_CHANNELS]; + Word16 lr_out_ptr_e[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 E_fx[CPE_CHANNELS]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 weights_fx[NPART]; + Word32 side_energy_fx; + Word16 Qside_energy; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/ + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN], dct_target_fx[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/ + Word16 tmp, tmp_e; + Word16 no_side_flag; + Word16 is_inp_ms; + Word16 size_value, temp_e, gb, shift; + Word32 tmp32, t1, t2; + + is_inp_ms = 0; + move16(); + IF( EQ_16( hCPE->hCoreCoder[0]->cng_sba_flag, 1 ) ) + { + is_inp_ms = 1; + move16(); + } + + /* set pointers and initialize */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; /* exp(sts[ch]->hFdCngEnc->msNoiseEst_fx_exp) */ + lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; + lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; /* exp(sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp) */ + lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; + } + N = sts[0]->hFdCngEnc->npartDec; /* Q0 */ + move16(); + set16_fx( weights_fx, ONE_IN_Q8, NPART ); + + /* apply log and save energy of original left and right channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + // E[ch] = 0.0f; + E_fx[ch] = 0; + move32(); + FOR( p = 0; p < N; p++ ) + { + IF( lr_in_ptr_fx[ch][p] ) + { + t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25 + t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 + } + ELSE + { + t2 = 0; + move32(); + } + ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 + move32(); + E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19 + move32(); + } + } + ms_ptr_e = Q31 - Q23; + move16(); + + /* M/S transform on log envelopes */ + IF( is_inp_ms == 0 ) + { + convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); // ms_ptr_e = Q23; + } + + gb = find_guarded_bits_fx( N ); + side_energy_fx = sum2_f_32_fx( ms_ptr_fx[1], N, gb ); + Qside_energy = sub( sub( shl( sub( 31, ms_ptr_e ), 1 ), 31 ), gb ); + + /* do not transmit side shape if initial noise shapes are very similar */ + IF( LE_32( side_energy_fx, L_shl( 214748365, sub( Qside_energy, Q31 ) ) ) ) + { + no_side_flag = 1; + move16(); + } + ELSE + { + no_side_flag = 0; + move16(); + } + + /* Quantize noise shapes */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + /* Normalize MSVQ input */ + gain_fx[ch] = 0; + move32(); + FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) + { + tmp32 = Mpy_32_32( ms_ptr_fx[ch][p], 165191050 /* 0.07 in Q31*/ ); // Q23 + gain_fx[ch] = L_add( gain_fx[ch], tmp32 ); // Q23 + move32(); + } + + FOR( p = 0; p < N; p++ ) + { + ms_ptr_fx[ch][p] = L_sub( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q23 + move32(); + } + } + + /* always split channel targetloop */ + + /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */ + /* High quality cosine smooth basis extension used to not introduce noise in stage#1 DCT24 analysis and subsequent VQ-steps */ + IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) + { + size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ + size_value = shr( size_value, sub( 15, temp_e ) ); + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, size_value ); // Q31 /*WB: create truncated IDCT21 matrix */ + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/ + /* truncated DCT 21 analysis */ + dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[ch], dct_target_fx[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); + /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors, + estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated length 24 input target envelope signal */ + /* this DCT21 extension does not introduce DCT24 coefficient noise for the subsequent dct24 target analysis, and later in IDCT24 synthesis */ + + /* truncated IDCT 21 extension synthesis */ + extend_dctN_input_fx( ms_ptr_fx[ch], dct_target_fx[ch], N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ + + Copy32( tot_sig_ext_fx, ms_ptr_fx[ch], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ */ + } + } + + size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ + size_value = shr( size_value, sub( 15, temp_e ) ); + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, size_value ); /*always create/set up IDCT24 matrix in RAM */ + + /* end split */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + /* MSVQ */ + IF( ch ) + { + stages = FD_CNG_JOINT_stages_25bits; + move16(); + } + ELSE + { + stages = FD_CNG_stages_37bits; + move16(); + } + + /* DCT24 domain compressed/truncated indices used for first stage */ + /* mid channel quantization using stages 1 through 6 */ + /* & side channel quantization using stages 1 through 4 */ + + { + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[ch], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, stages, weights_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[ch] ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); + } + } + shift = find_guarded_bits_fx( N ); + ms_ptr_e = sub( 31, sub( 20, shift ) ); + + IF( no_side_flag ) + { + set32_fx( ms_ptr_fx[1], 0, N ); + } + + /* undo M/S */ + IF( is_inp_ms == 0 ) + { + convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + } + + /* Compute gain against original left and right channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + gain_fx[ch] = 0; + move32(); + + tmp_e = 15; + move16(); + tmp = Inv16( N, &tmp_e ); + FOR( p = 0; p < N; p++ ) + { + gain_fx[ch] = L_add( gain_fx[ch], Mpy_32_16_1( ms_ptr_fx[ch][p], shl( tmp, tmp_e ) ) ); // Q23 + move32(); + } + gain_fx[ch] = L_sub( L_shl( Mpy_32_16_1( E_fx[ch], shl( tmp, tmp_e ) ), Q23 - Q19 ), L_shl( gain_fx[ch], sub( ms_ptr_e, 8 ) ) ); // Q23 + move32(); + + apply_scale( &gain_fx[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + + /* quantize gain */ + gain_idx[ch] = (Word16) Mpy_32_32_r( L_add( gain_fx[ch], 251658240 ), 384 ); // Q23 + move16(); + gain_idx[ch] = s_max( 0, s_min( 127, gain_idx[ch] ) ); + move16(); + + gain_fx[ch] = Mpy_32_16_1( L_shl( sub( gain_idx[ch], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23 + move32(); + } + + /* restore channel noise envelopes */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + + tmp_e = 0; + move16(); + Word32 pow; + + Word16 e_lr_out[NPART]; + + FOR( p = 0; p < N; p++ ) + { + pow = L_shl( gain_fx[ch], 8 - ms_ptr_e ); + pow = L_add( ms_ptr_fx[ch][p], pow ); + pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/ + lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); + move32(); + tmp_e = s_max( tmp_e, e_lr_out[p] ); + } + + FOR( p = 0; p < N; p++ ) + { + lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], e_lr_out[p] - tmp_e ); + move32(); + } + lr_out_ptr_e[ch] = tmp_e; + move32(); + + sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; + move16(); + + /* scale bands and get scalefactors */ + scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); + + sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; + } + + /* quantize channel coherence */ + coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 ); + coh_idx = max( 0, min( coh_idx, 15 ) ); + + /* ---- Write SID bitstream ---- */ + + + /* noise shapes and channel gains */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( ch ) + { + stages = FD_CNG_JOINT_stages_25bits; + sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; + + /* side info */ + push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 ); + push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 ); + } + ELSE + { + stages = FD_CNG_stages_37bits; + /* side info */ + push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); + push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 ); + } + + FOR( Word16 i = 0; i < stages; i++ ) + { + push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] ); + } + push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 ); + } + + /* pad with zeros to reach common SID frame size */ + push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); + + return; +} + +/*-------------------------------------------------------------------* + * FdCngEncodeDiracMDCTStereoSID() + * + * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX + * together with Dirac + *-------------------------------------------------------------------*/ + +void FdCngEncodeDiracMDCTStereoSID_fx( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ +) +{ + ENC_CORE_HANDLE sts[CPE_CHANNELS]; + Word32 *lr_in_ptr_fx[CPE_CHANNELS]; + Word16 lr_in_ptr_e[CPE_CHANNELS]; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word16 ms_ptr_e; + Word32 *lr_out_ptr_fx[CPE_CHANNELS]; + Word16 lr_out_ptr_e[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 E_fx[CPE_CHANNELS]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 weights_fx[NPART]; + Word16 N[CPE_CHANNELS]; + Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; + Word16 gain_idx[CPE_CHANNELS]; + Word16 ch, p; + Word16 tmp, tmp_e, shift; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + Word32 t1, t2, tmp32; + /* set pointers and initialize */ + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + N[ch] = sts[ch]->hFdCngEnc->npartDec; + lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; + lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; + lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; + lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; + move16(); + } + set16_fx( weights_fx, ONE_IN_Q8, NPART ); + + /* apply log and save energy of original left and right channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + // E[ch] = 0.0f; + E_fx[ch] = 0; + move32(); + FOR( p = 0; p < N[ch]; p++ ) + { + t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] + EPSILLON_FX ); // Q25 + t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 + ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 + move32(); + E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 5 ) ); // Q18 + move32(); + } + } + ms_ptr_e = Q31 - Q23; + move16(); + + /* M/S transform on log envelopes */ + convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); + E_fx[0] = 0; + move32(); + FOR( p = 0; p < N[0]; p++ ) + { + E_fx[0] = L_add( E_fx[0], L_shr( ms_ptr_fx[0][p], 5 ) ); // Q18 + move32(); + } + + /* Quantize M noise shape */ + /* Normalize MSVQ input */ + gain_fx[0] = 0; + move16(); + FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) + { + tmp32 = Mpy_32_32( ms_ptr_fx[0][p], 165191050 /* 0.07 in Q31 */ ); // Q23 + gain_fx[0] = L_add( gain_fx[0], tmp32 ); // Q23 + move32(); + } + + FOR( p = 0; p < N[0]; p++ ) + { + ms_ptr_fx[0][p] = L_sub( ms_ptr_fx[0][p], gain_fx[0] ); // Q23 + move32(); + } + + + /* MSVQ */ + /* DCT domain compressed/truncated indices used for first stage */ + /* mid quantization using stages #1 through 6 */ + scale_sig32( ms_ptr_fx[0], N[0], -6 ); + ms_ptr_e = add( ms_ptr_e, 6 ); + move16(); + IF( EQ_16( N[0], FDCNG_VQ_MAX_LEN_WB ) ) + { + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); + /* truncated DCT 21 analysis */ + dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[0], dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); + /* truncated IDCT21 extension to 24 synthesis */ + + extend_dctN_input_fx( ms_ptr_fx[0], dct_target_fx, N[0], tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ + + Copy32( tot_sig_ext_fx, ms_ptr_fx[0], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 Q23*/ + } + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); + + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[0], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights_fx, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[0] ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); + shift = find_guarded_bits_fx( N[0] ); + ms_ptr_e = sub( 31, sub( 20, shift ) ); + scale_sig32( ms_ptr_fx[1], N[1], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */ + + /* set S to zero */ + set32_fx( ms_ptr_fx[1], 0, NPART ); + + /* compute M gain */ + gain_fx[0] = 0; + move32(); + tmp_e = 15; + move16(); + tmp = Inv16( N[0], &tmp_e ); + FOR( p = 0; p < N[0]; p++ ) + { + gain_fx[0] = L_add( gain_fx[0], Mpy_32_16_1( ms_ptr_fx[0][p], shl( tmp, tmp_e ) ) ); // Q23 + move32(); + } + gain_fx[0] = L_sub( L_shl( Mpy_32_16_1( E_fx[0], shl( tmp, tmp_e ) ), Q23 - Q18 ), L_shl( gain_fx[0], ms_ptr_e - 8 ) ); // Q23 + move32(); + + apply_scale( &gain_fx[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + + /* quantize gain */ + gain_idx[0] = extract_l( Mpy_32_32_r( L_add( gain_fx[0], 251658240 ), 384 ) ); + move16(); + gain_idx[0] = s_max( 0, s_min( 127, gain_idx[0] ) ); + move16(); + + gain_fx[0] = Mpy_32_16_1( L_shl( sub( gain_idx[0], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 /* 0.66 in Q15 */ ); // Q23 + move32(); + gain_fx[1] = gain_fx[0]; // Q23 + move32(); + + /* undo M/S */ + convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + + /* restore channel noise envelopes */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + + Word32 pow; + Word16 e_lr_out[NPART]; + tmp_e = -MAX_16; + FOR( p = 0; p < N[ch]; p++ ) + { + pow = L_shl( gain_fx[ch], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */ + pow = L_add( ms_ptr_fx[ch][p], pow ); /* Q31 - ms_ptr_e */ + pow = Mpy_32_32( pow, 214748365 /* 0.1 in Q31 */ ); /*pow = 0.1 Q31 - ms_ptr_e*/ + lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); + tmp_e = s_max( tmp_e, e_lr_out[p] ); + } + + FOR( p = 0; p < N[ch]; p++ ) + { + lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], sub( e_lr_out[p], tmp_e ) ); // Q(31 - tmp_e) + } + + sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; + move16(); + lr_out_ptr_e[ch] = tmp_e; + move16(); + + /* NB last band energy compensation */ + IF( hFdCngCom->CngBandwidth == NB ) + { + lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], NB_LAST_BAND_SCALE ); // Q(31 - tmp_e) + move32(); + } + ELSE IF( hFdCngCom->CngBandwidth == SWB && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], SWB_13k2_LAST_BAND_SCALE ); // Q(31 - tmp_e) + move32(); + } + /* scale bands and get scalefactors */ + scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; + move16(); + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); + sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; + } + sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = 0; + move16(); + sts[1]->hFdCngEnc->hFdCngCom->coherence_fx = 0; + move16(); + + /* ---- Write SID bitstream ---- */ + + /* side info */ + push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); + IF( EQ_16( sts[0]->L_frame, L_FRAME16k ) ) + { + push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 1, 1 ); + } + ELSE + { + push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 0, 1 ); + } + + /* noise shapes and channel gains */ + FOR( Word16 i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] ); + } + push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 ); + + return; +} diff --git a/lib_enc/find_tilt.c b/lib_enc/find_tilt.c deleted file mode 100644 index efd1b44d2..000000000 --- a/lib_enc/find_tilt.c +++ /dev/null @@ -1,303 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ - - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * find_tilt() - * - * Find LF/HF energy ratio - *-------------------------------------------------------------------*/ -void find_tilt_ivas_fx( - const Word32 fr_bands[], /* i : energy in frequency bands q_fr_bands*/ - const Word16 q_fr_bands, /* i : Q of fr_bands Q0*/ - const Word32 bckr[], /* i : per band background noise energy estimate q_bckr*/ - const Word16 q_bckr, /* i : Q of bckr Q0*/ - Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ - const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ - const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ - const Word32 *lf_E, /* i : per bin energy for low frequencies q_lf_E*/ - const Word16 q_lf_E, /* i : Q of lf_E */ - const Word16 corr_shift, /* i : normalized correlation correction Q15*/ - const Word16 bwidth, /* i : input signal bandwidth */ - const Word16 max_band, /* i : maximum critical band */ - Word32 hp_E[], /* o : energy in HF Q_new*/ - const Word16 codec_mode, /* i : MODE1 or MODE2 */ - Word32 *bckr_tilt_lt, /* i/o: lf/hf E ratio of background noise Q16 */ - Word16 Opt_vbr_mode ) -{ - Word32 lp_bckr = 0, hp_bckr = 0, lp_E, Ltmp; - const Word32 *pt_E, *pt_bands, *pt_bckr, *hf_bands, *tmp_E; - Word16 tmp, freq, f0, f1, f2, mean_voi, bin; - Word16 i, nb_bands; - Word16 e_tmp, m_tmp; - Word16 m_Fs, e_Fs; - Word16 m_cnt, e_cnt; - Word16 m_hpE, e_hpE; - Word64 sum; - Word16 inv_bands, q_lp_E; - Word32 Le_min_scaled, Ltmp2; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - move32(); - move32(); - /*-----------------------------------------------------------------* - * Initializations - *-----------------------------------------------------------------*/ - - IF( ( bwidth != NB ) ) - { - /* WB processing */ - bin = BIN4_FX; - move16(); /* First useful frequency bin ~ 50 Hz */ - pt_bands = fr_bands; /* Q_new */ - tmp_E = lf_E; /* Q_new - 2 */ - pt_bckr = bckr; /* Q_new */ - nb_bands = 10; - inv_bands = 3277 /* 1/10 in Q15 */; - move16(); - move16(); - } - ELSE - { - /* NB processing */ - bin = 3 * BIN4_FX; /* First useful frequency bin ~ 150 Hz */ - pt_bands = fr_bands + 1; /* Exlcude 1st critical band */ - tmp_E = lf_E + 2; /* Start at the 3rd bin (150 Hz) */ - pt_bckr = bckr + 1; /* Exlcude 1st critical band */ - nb_bands = 9; - inv_bands = 3641; /* 1/9 in Q15 */ - move16(); - move16(); /* Nb. of "low" frequency bands taken into account in NB processing */ - } - - /*-----------------------------------------------------------------* - * Find spectrum tilt - *-----------------------------------------------------------------*/ - - pt_E = tmp_E; /* Point at the 1st useful element of the per-bin energy vector */ - hf_bands = fr_bands; - - /* bckr + voicing */ - /*lp_bckr = mean( pt_bckr, nb_bands );*/ /* estimated noise E in first critical bands, up to 1270 Hz */ - sum = 0; - move64(); - FOR( i = 0; i < nb_bands; i++ ) - { - sum = W_mac_32_16( sum, pt_bckr[i], inv_bands ); // q_bckr+16 - } - lp_bckr = W_shl_sat_l( sum, -16 ); // q_bckr - /*hp_bckr = 0.5f * (bckr[max_band-1] + bckr[max_band]);*/ /* estimated noise E in last 2 critical bands */ - hp_bckr = W_extract_h( W_mac_32_32( W_mult_32_32( bckr[max_band - 1], ONE_IN_Q30 ), bckr[max_band], ONE_IN_Q30 ) ); // q_bckr - if ( hp_bckr == 0 ) /* Avoid division by zero. */ - { - hp_bckr = L_deposit_l( 1 ); - } - Ltmp = BASOP_Util_Divide3232_Scale_cadence( lp_bckr, hp_bckr, &e_tmp ); - Ltmp = Mpy_32_16_r( Ltmp, 3277 /* 0.1f in Q15 */ ); - Ltmp = L_shr_sat( Ltmp, sub( 15, e_tmp ) ); - *bckr_tilt_lt = L_add_sat( Mpy_32_16_r( *bckr_tilt_lt, 29491 /* 0.9f in Q15 */ ), Ltmp ); // Q16 - move32(); - - test(); - IF( EQ_16( codec_mode, MODE2 ) || EQ_16( Opt_vbr_mode, 1 ) ) - { - /*lp_bckr *= FACT;*/ - /*hp_bckr *= FACT;*/ - lp_bckr = L_add_sat( L_shl_sat( lp_bckr, 1 ), lp_bckr ); /* Q_new */ - hp_bckr = L_add_sat( L_shl_sat( hp_bckr, 1 ), hp_bckr ); /* Q_new */ - } - /*mean_voi = 0.5f * (voicing[1] + voicing[2]) + corr_shift;*/ - Ltmp = L_mult( voicing[1], 16384 /* 0.5 in Q15 */ ); // Q31 - Ltmp = L_mac( Ltmp, voicing[2], 16384 /* 0.5 in Q15 */ ); // Q31 - Ltmp = L_mac_o( Ltmp, corr_shift, 32767 /* 1.0f in Q15 */, &Overflow ); // Q31 - mean_voi = round_fx_o( Ltmp, &Overflow ); // Q15 - - /*f0 = INT_FS_FX / pitch[2];*/ - e_tmp = norm_s( pitch[2] ); - m_tmp = shl( pitch[2], e_tmp ); - - m_Fs = div_s( INT_FS_FX, m_tmp ); /* exp(e_tmp) */ - e_Fs = sub( 15, e_tmp ); - f0 = shr( m_Fs, sub( e_Fs, 4 ) ); /* Q4 */ - - Le_min_scaled = L_shl( E_MIN_FXQ31, sub( q_fr_bands, Q31 ) ); // q_fr_bands=q_bckr - - FOR( i = 0; i < 2; i++ ) - { - /*hp_E[i] = 0.5f * (hf_bands[max_band-1] + hf_bands[max_band]) - hp_bckr; */ /* averaged E in last 2 critical bands */ - Ltmp = W_extract_h( W_mac_32_32( W_mult_32_32( hf_bands[max_band - 1], ONE_IN_Q30 ), hf_bands[max_band], ONE_IN_Q30 ) ); // q_fr_bands - Ltmp = L_sub( Ltmp, hp_bckr ); // q_fr_bands - - Ltmp2 = L_max( Ltmp, L_shl_sat( 1, q_fr_bands ) ); // q_fr_bands, saturation is added because q_fr_bands is limited to 31 - if ( Opt_vbr_mode == 0 ) - { - Ltmp2 = L_max( Ltmp, Le_min_scaled ); // q_fr_bands - } - hp_E[i] = L_max( Ltmp2, 1 ); // to prevent division by zero - move32(); - - test(); - IF( GT_16( mean_voi, TH_COR_FX ) && LT_16( pitch[2], TH_PIT_FX ) ) /* High-pitched voiced frames */ - { - freq = bin; // Q4 - move16(); /* 1st useful frequency bin */ - m_cnt = 0; - move16(); - sum = 0; - move64(); - - f1 = add( shr( f0, 1 ), f0 ); /* Middle between 2 harmonics */ - f2 = f0; - move16(); - WHILE( LE_16( freq, 20320 /* 1270.0f in Q4 */ ) ) /* End frequency of 10th critical band */ - { - FOR( ; freq <= f1; freq += BIN4_FX ) - { - /* include only bins sufficiently close to harmonics */ - tmp = sub( freq, f2 ); - IF( L_mac0( -TH_D_FX * TH_D_FX, tmp, tmp ) < 0 ) - { - sum = W_mac_32_16( sum, *pt_E, 1 ); // q_lf_E+1 - m_cnt = add( m_cnt, 1 ); - } - pt_E++; - } - f1 = add_o( f1, f0, &Overflow ); - f2 = add_o( f2, f0, &Overflow ); - } - /*lp_E = lp_E / (float)cnt - lp_bckr;*/ - e_tmp = sub( W_norm( sum ), 1 ); - m_tmp = extract_h( W_extract_h( W_shl( sum, e_tmp ) ) ); // q_lf_E+1+e_tmp-32-16 - e_tmp = sub( add( q_lf_E, e_tmp ), 47 ); - - e_cnt = norm_s( m_cnt ); - m_cnt = shl( m_cnt, e_cnt ); // e_cnt - - m_tmp = div_s( m_tmp, m_cnt ); // Q15+e_tmp-e_cnt - e_tmp = add( Q15, sub( e_tmp, e_cnt ) ); - sum = W_shl( m_tmp, sub( add( q_bckr, 1 ), e_tmp ) ); // q_bckr+1 - sum = W_msu_32_16( sum, lp_bckr, 1 ); // q_bckr+1 - q_lp_E = W_norm( sum ); - lp_E = W_extract_h( W_shl( sum, q_lp_E ) ); // q_bckr+1+q_lp_E-32 - q_lp_E = sub( add( q_lp_E, q_bckr ), Q31 ); - - pt_E = tmp_E + VOIC_BINS; /* Update for next half-frame Q_new - 1 */ - } - ELSE /* Other than high-pitched voiced frames */ - { - /*lp_E = mean( pt_bands, nb_bands ) - lp_bckr;*/ /* averaged E in first critical bands, up to 1270 Hz */ - sum = 0; - move64(); - FOR( Word16 j = 0; j < nb_bands; j++ ) - { - sum = W_mac_32_16( sum, pt_bands[j], inv_bands ); // q_fr_bands+16 - } - sum = W_mac_32_16( sum, lp_bckr, -ONE_IN_Q15 ); // q_fr_bands+16 - lp_E = W_round48_L( sum ); // q_fr_bands=q_bckr - q_lp_E = q_bckr; // q_fr_bands=q_bckr - move16(); - } - test(); - IF( Opt_vbr_mode == 0 && GT_32( L_shl_sat( Le_min_scaled, sub( q_lp_E, q_bckr ) ), lp_E ) ) - { - lp_E = E_MIN_FXQ31; - q_lp_E = Q31; - move32(); - move16(); - } - if ( Opt_vbr_mode != 0 ) - { - lp_E = L_max( lp_E, 0 ); // q_lp_E - } - /*ee[i] = lp_E / hp_E[i];*/ /* LF/HF ratio */ - - if ( lp_E == 0 ) - { - ee[i] = 0; - move32(); - } - test(); - IF( lp_E != 0 ) - { - e_tmp = sub( norm_l( lp_E ), 1 ); - m_tmp = extract_h( L_shl( lp_E, e_tmp ) ); // e_tmp+q_lp_E-16 - e_hpE = norm_l( hp_E[i] ); - m_hpE = extract_h( L_shl( hp_E[i], e_hpE ) ); // e_hpE+q_bckr-16 - m_tmp = div_s( m_tmp, m_hpE ); // Q15+(e_tmp+q_lp_E)-(e_hpE+q_bckr) - e_tmp = sub( add( e_tmp, q_lp_E ), add( e_hpE, q_bckr ) ); - ee[i] = L_shr_o( m_tmp, add( e_tmp, 15 - 6 ), &Overflow ); /* ee in Q6 */ - move32(); - } - - IF( bwidth == NB ) /* For NB input, compensate for the missing bands */ - { - Ltmp = L_shl_o( ee[i], 3, &Overflow ); /* Q6 */ - IF( EQ_32( Ltmp, MAX_32 ) ) /* if Overflow: Compute with less precision */ - { - Ltmp = Mult_32_16( ee[i], 24576 /* 0.75 in Q15 */ ); /* 6/8 Q6*/ - ee[i] = L_shl_sat( Ltmp, 3 ); /* Q6 */ - move32(); /* x8 */ - } - ELSE - { - ee[i] = Mult_32_16( Ltmp, 24576 /* 0.75 in Q15 */ ); - move32(); /* 6/8 */ - } - } - - pt_bands += NB_BANDS; /* Update for next half-frame */ - hf_bands += NB_BANDS; - } - - return; -} diff --git a/lib_enc/find_tilt_fx.c b/lib_enc/find_tilt_fx.c index 44ad404e3..ea71b09bc 100644 --- a/lib_enc/find_tilt_fx.c +++ b/lib_enc/find_tilt_fx.c @@ -240,3 +240,255 @@ void find_tilt_fx( return; } + +/*-------------------------------------------------------------------* + * find_tilt() + * + * Find LF/HF energy ratio + *-------------------------------------------------------------------*/ +void find_tilt_ivas_fx( + const Word32 fr_bands[], /* i : energy in frequency bands q_fr_bands*/ + const Word16 q_fr_bands, /* i : Q of fr_bands Q0*/ + const Word32 bckr[], /* i : per band background noise energy estimate q_bckr*/ + const Word16 q_bckr, /* i : Q of bckr Q0*/ + Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ + const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ + const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ + const Word32 *lf_E, /* i : per bin energy for low frequencies q_lf_E*/ + const Word16 q_lf_E, /* i : Q of lf_E */ + const Word16 corr_shift, /* i : normalized correlation correction Q15*/ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 max_band, /* i : maximum critical band */ + Word32 hp_E[], /* o : energy in HF Q_new*/ + const Word16 codec_mode, /* i : MODE1 or MODE2 */ + Word32 *bckr_tilt_lt, /* i/o: lf/hf E ratio of background noise Q16 */ + Word16 Opt_vbr_mode ) +{ + Word32 lp_bckr = 0, hp_bckr = 0, lp_E, Ltmp; + const Word32 *pt_E, *pt_bands, *pt_bckr, *hf_bands, *tmp_E; + Word16 tmp, freq, f0, f1, f2, mean_voi, bin; + Word16 i, nb_bands; + Word16 e_tmp, m_tmp; + Word16 m_Fs, e_Fs; + Word16 m_cnt, e_cnt; + Word16 m_hpE, e_hpE; + Word64 sum; + Word16 inv_bands, q_lp_E; + Word32 Le_min_scaled, Ltmp2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + move32(); + move32(); + /*-----------------------------------------------------------------* + * Initializations + *-----------------------------------------------------------------*/ + + IF( ( bwidth != NB ) ) + { + /* WB processing */ + bin = BIN4_FX; + move16(); /* First useful frequency bin ~ 50 Hz */ + pt_bands = fr_bands; /* Q_new */ + tmp_E = lf_E; /* Q_new - 2 */ + pt_bckr = bckr; /* Q_new */ + nb_bands = 10; + inv_bands = 3277 /* 1/10 in Q15 */; + move16(); + move16(); + } + ELSE + { + /* NB processing */ + bin = 3 * BIN4_FX; /* First useful frequency bin ~ 150 Hz */ + pt_bands = fr_bands + 1; /* Exlcude 1st critical band */ + tmp_E = lf_E + 2; /* Start at the 3rd bin (150 Hz) */ + pt_bckr = bckr + 1; /* Exlcude 1st critical band */ + nb_bands = 9; + inv_bands = 3641; /* 1/9 in Q15 */ + move16(); + move16(); /* Nb. of "low" frequency bands taken into account in NB processing */ + } + + /*-----------------------------------------------------------------* + * Find spectrum tilt + *-----------------------------------------------------------------*/ + + pt_E = tmp_E; /* Point at the 1st useful element of the per-bin energy vector */ + hf_bands = fr_bands; + + /* bckr + voicing */ + /*lp_bckr = mean( pt_bckr, nb_bands );*/ /* estimated noise E in first critical bands, up to 1270 Hz */ + sum = 0; + move64(); + FOR( i = 0; i < nb_bands; i++ ) + { + sum = W_mac_32_16( sum, pt_bckr[i], inv_bands ); // q_bckr+16 + } + lp_bckr = W_shl_sat_l( sum, -16 ); // q_bckr + /*hp_bckr = 0.5f * (bckr[max_band-1] + bckr[max_band]);*/ /* estimated noise E in last 2 critical bands */ + hp_bckr = W_extract_h( W_mac_32_32( W_mult_32_32( bckr[max_band - 1], ONE_IN_Q30 ), bckr[max_band], ONE_IN_Q30 ) ); // q_bckr + if ( hp_bckr == 0 ) /* Avoid division by zero. */ + { + hp_bckr = L_deposit_l( 1 ); + } + Ltmp = BASOP_Util_Divide3232_Scale_cadence( lp_bckr, hp_bckr, &e_tmp ); + Ltmp = Mpy_32_16_r( Ltmp, 3277 /* 0.1f in Q15 */ ); + Ltmp = L_shr_sat( Ltmp, sub( 15, e_tmp ) ); + *bckr_tilt_lt = L_add_sat( Mpy_32_16_r( *bckr_tilt_lt, 29491 /* 0.9f in Q15 */ ), Ltmp ); // Q16 + move32(); + + test(); + IF( EQ_16( codec_mode, MODE2 ) || EQ_16( Opt_vbr_mode, 1 ) ) + { + /*lp_bckr *= FACT;*/ + /*hp_bckr *= FACT;*/ + lp_bckr = L_add_sat( L_shl_sat( lp_bckr, 1 ), lp_bckr ); /* Q_new */ + hp_bckr = L_add_sat( L_shl_sat( hp_bckr, 1 ), hp_bckr ); /* Q_new */ + } + /*mean_voi = 0.5f * (voicing[1] + voicing[2]) + corr_shift;*/ + Ltmp = L_mult( voicing[1], 16384 /* 0.5 in Q15 */ ); // Q31 + Ltmp = L_mac( Ltmp, voicing[2], 16384 /* 0.5 in Q15 */ ); // Q31 + Ltmp = L_mac_o( Ltmp, corr_shift, 32767 /* 1.0f in Q15 */, &Overflow ); // Q31 + mean_voi = round_fx_o( Ltmp, &Overflow ); // Q15 + + /*f0 = INT_FS_FX / pitch[2];*/ + e_tmp = norm_s( pitch[2] ); + m_tmp = shl( pitch[2], e_tmp ); + + m_Fs = div_s( INT_FS_FX, m_tmp ); /* exp(e_tmp) */ + e_Fs = sub( 15, e_tmp ); + f0 = shr( m_Fs, sub( e_Fs, 4 ) ); /* Q4 */ + + Le_min_scaled = L_shl( E_MIN_FXQ31, sub( q_fr_bands, Q31 ) ); // q_fr_bands=q_bckr + + FOR( i = 0; i < 2; i++ ) + { + /*hp_E[i] = 0.5f * (hf_bands[max_band-1] + hf_bands[max_band]) - hp_bckr; */ /* averaged E in last 2 critical bands */ + Ltmp = W_extract_h( W_mac_32_32( W_mult_32_32( hf_bands[max_band - 1], ONE_IN_Q30 ), hf_bands[max_band], ONE_IN_Q30 ) ); // q_fr_bands + Ltmp = L_sub( Ltmp, hp_bckr ); // q_fr_bands + + Ltmp2 = L_max( Ltmp, L_shl_sat( 1, q_fr_bands ) ); // q_fr_bands, saturation is added because q_fr_bands is limited to 31 + if ( Opt_vbr_mode == 0 ) + { + Ltmp2 = L_max( Ltmp, Le_min_scaled ); // q_fr_bands + } + hp_E[i] = L_max( Ltmp2, 1 ); // to prevent division by zero + move32(); + + test(); + IF( GT_16( mean_voi, TH_COR_FX ) && LT_16( pitch[2], TH_PIT_FX ) ) /* High-pitched voiced frames */ + { + freq = bin; // Q4 + move16(); /* 1st useful frequency bin */ + m_cnt = 0; + move16(); + sum = 0; + move64(); + + f1 = add( shr( f0, 1 ), f0 ); /* Middle between 2 harmonics */ + f2 = f0; + move16(); + WHILE( LE_16( freq, 20320 /* 1270.0f in Q4 */ ) ) /* End frequency of 10th critical band */ + { + FOR( ; freq <= f1; freq += BIN4_FX ) + { + /* include only bins sufficiently close to harmonics */ + tmp = sub( freq, f2 ); + IF( L_mac0( -TH_D_FX * TH_D_FX, tmp, tmp ) < 0 ) + { + sum = W_mac_32_16( sum, *pt_E, 1 ); // q_lf_E+1 + m_cnt = add( m_cnt, 1 ); + } + pt_E++; + } + f1 = add_o( f1, f0, &Overflow ); + f2 = add_o( f2, f0, &Overflow ); + } + /*lp_E = lp_E / (float)cnt - lp_bckr;*/ + e_tmp = sub( W_norm( sum ), 1 ); + m_tmp = extract_h( W_extract_h( W_shl( sum, e_tmp ) ) ); // q_lf_E+1+e_tmp-32-16 + e_tmp = sub( add( q_lf_E, e_tmp ), 47 ); + + e_cnt = norm_s( m_cnt ); + m_cnt = shl( m_cnt, e_cnt ); // e_cnt + + m_tmp = div_s( m_tmp, m_cnt ); // Q15+e_tmp-e_cnt + e_tmp = add( Q15, sub( e_tmp, e_cnt ) ); + sum = W_shl( m_tmp, sub( add( q_bckr, 1 ), e_tmp ) ); // q_bckr+1 + sum = W_msu_32_16( sum, lp_bckr, 1 ); // q_bckr+1 + q_lp_E = W_norm( sum ); + lp_E = W_extract_h( W_shl( sum, q_lp_E ) ); // q_bckr+1+q_lp_E-32 + q_lp_E = sub( add( q_lp_E, q_bckr ), Q31 ); + + pt_E = tmp_E + VOIC_BINS; /* Update for next half-frame Q_new - 1 */ + } + ELSE /* Other than high-pitched voiced frames */ + { + /*lp_E = mean( pt_bands, nb_bands ) - lp_bckr;*/ /* averaged E in first critical bands, up to 1270 Hz */ + sum = 0; + move64(); + FOR( Word16 j = 0; j < nb_bands; j++ ) + { + sum = W_mac_32_16( sum, pt_bands[j], inv_bands ); // q_fr_bands+16 + } + sum = W_mac_32_16( sum, lp_bckr, -ONE_IN_Q15 ); // q_fr_bands+16 + lp_E = W_round48_L( sum ); // q_fr_bands=q_bckr + q_lp_E = q_bckr; // q_fr_bands=q_bckr + move16(); + } + test(); + IF( Opt_vbr_mode == 0 && GT_32( L_shl_sat( Le_min_scaled, sub( q_lp_E, q_bckr ) ), lp_E ) ) + { + lp_E = E_MIN_FXQ31; + q_lp_E = Q31; + move32(); + move16(); + } + if ( Opt_vbr_mode != 0 ) + { + lp_E = L_max( lp_E, 0 ); // q_lp_E + } + /*ee[i] = lp_E / hp_E[i];*/ /* LF/HF ratio */ + + if ( lp_E == 0 ) + { + ee[i] = 0; + move32(); + } + test(); + IF( lp_E != 0 ) + { + e_tmp = sub( norm_l( lp_E ), 1 ); + m_tmp = extract_h( L_shl( lp_E, e_tmp ) ); // e_tmp+q_lp_E-16 + e_hpE = norm_l( hp_E[i] ); + m_hpE = extract_h( L_shl( hp_E[i], e_hpE ) ); // e_hpE+q_bckr-16 + m_tmp = div_s( m_tmp, m_hpE ); // Q15+(e_tmp+q_lp_E)-(e_hpE+q_bckr) + e_tmp = sub( add( e_tmp, q_lp_E ), add( e_hpE, q_bckr ) ); + ee[i] = L_shr_o( m_tmp, add( e_tmp, 15 - 6 ), &Overflow ); /* ee in Q6 */ + move32(); + } + + IF( bwidth == NB ) /* For NB input, compensate for the missing bands */ + { + Ltmp = L_shl_o( ee[i], 3, &Overflow ); /* Q6 */ + IF( EQ_32( Ltmp, MAX_32 ) ) /* if Overflow: Compute with less precision */ + { + Ltmp = Mult_32_16( ee[i], 24576 /* 0.75 in Q15 */ ); /* 6/8 Q6*/ + ee[i] = L_shl_sat( Ltmp, 3 ); /* Q6 */ + move32(); /* x8 */ + } + ELSE + { + ee[i] = Mult_32_16( Ltmp, 24576 /* 0.75 in Q15 */ ); + move32(); /* 6/8 */ + } + } + + pt_bands += NB_BANDS; /* Update for next half-frame */ + hf_bands += NB_BANDS; + } + + return; +} diff --git a/lib_enc/find_uv.c b/lib_enc/find_uv.c deleted file mode 100644 index c6ae02a76..000000000 --- a/lib_enc/find_uv.c +++ /dev/null @@ -1,660 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define L_ENR ( NB_SSF + 2 ) - -/*-------------------------------------------------------------------* - * find_ener_decrease() - * - * Find maximum energy ratio between short sub-subframes in case - * energy is trailing off after a spike - *-------------------------------------------------------------------*/ - -/*! r: maximum energy ratio */ -static Word16 find_ener_decrease_fx( /* o : maximum energy ratio Q10*/ - const Word16 ind_deltaMax, /* i : index of the beginning of maximum energy search Q0*/ - const Word32 *pt_enr_ssf /* i : Pointer to the energy buffer Qx*/ -) -{ - Word16 i, j, end, flag; - Word16 wtmp0, wtmp1; - Word32 maxEnr, minEnr; - Word16 dE2, exp0, exp1; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - dE2 = 0; - move16(); - - j = add( ind_deltaMax, 2 ); /* Q0 */ - move16(); - end = add( j, L_ENR ); - move16(); - maxEnr = L_add( pt_enr_ssf[j], 0 ); - j = add( j, 1 ); - flag = 0; - move16(); - FOR( i = j; i < end; i++ ) - { - test(); - IF( ( GT_32( pt_enr_ssf[i], maxEnr ) ) && ( flag == 0 ) ) - { - maxEnr = pt_enr_ssf[i]; /* Qx */ - j = add( j, 1 ); - } - ELSE - { - flag = 1; - move16(); - } - } - - minEnr = L_add( maxEnr, 0 ); - FOR( i = j; i < end; i++ ) - { - minEnr = L_min( minEnr, pt_enr_ssf[i] ); /* Qx */ - } - - - minEnr = L_add_sat( minEnr, 100000 ); - exp0 = norm_l( minEnr ); - wtmp0 = extract_h( L_shl( minEnr, exp0 ) ); - exp1 = sub( norm_l( maxEnr ), 1 ); - wtmp1 = extract_h( L_shl( maxEnr, exp1 ) ); - wtmp1 = div_s( wtmp1, wtmp0 ); - dE2 = shr_ro( wtmp1, add( sub( exp1, exp0 ), 15 - 10 ), &Overflow ); /*Q10*/ - - return dE2; -} - -/*-------------------------------------------------------------------* - * find_uv() - * - * Decision about coder type - *-------------------------------------------------------------------*/ -Word16 find_uv_ivas_fx( /* o : coding type */ - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ - const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ - const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ - Word32 *dE1X, /* o : sudden energy increase for S/M classifier Q13*/ - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ - const Word16 relE, /* i : relative frame energy Q8*/ - const Word16 Etot, /* i : total energy Q8*/ - const Word32 hp_E[], /* i : energy in HF q_hp_E*/ - Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ - const Word16 last_core_orig, /* i : original last core Q0*/ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const Word16 Q_new, - const Word16 q_hp_E ) -{ - Word16 coder_type, i; - Word32 mean_ee, dE1, fac_32; - const Word16 *pt_speech; - Word32 L_tmp, enr_ssf[2 * NB_SSF + 2 * NB_SSF + 2], E_min_th; - Word16 dE2; - Word16 ind_deltaMax, tmp_offset_flag; - Word32 Ltmp0, *pt_enr_ssf, *pt_enr_ssf1, dE2_th; - Word16 exp0, exp1; - Word16 wtmp0, wtmp1; - Word16 fac, mean_voi3, dE3; - Word16 relE_thres; - Word16 mean_voi3_offset; - Word16 voicing_m, dpit1, dpit2, dpit3; - Word16 ee0_th, ee1_th, voi_th, nb_cond, flag_low_relE; - NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst; - SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - Word16 Last_Resort; - Word16 vadnoise; - - IF( hSC_VBR != NULL ) - { - Last_Resort = hSC_VBR->Last_Resort; /* Q0 */ - move16(); - vadnoise = hSC_VBR->vadnoise_fx; /* Q8 */ - move16(); - } - ELSE - { - Last_Resort = 0; - move16(); - vadnoise = 0; - move16(); - } - - /*-----------------------------------------------------------------* - * Detect sudden energy increases to catch voice and music - * temporal events (dE1) - * - * - Find maximum energy per short subblocks. - * Two subblock sets are used shifted by half the subblock length - * - Find maximum energy ratio between adjacent subblocks - *-----------------------------------------------------------------*/ - - /* Find maximum energy per short subblocks */ - pt_speech = speech - SSF; - pt_enr_ssf = enr_ssf + 2 * NB_SSF; - FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ ) - { - emaximum_fx( Q_new, pt_speech, SSF, pt_enr_ssf ); - pt_speech += ( SSF / 2 ); - pt_enr_ssf++; - } - - dE1 = 0; - move16(); - ind_deltaMax = 0; - move16(); - pt_enr_ssf = enr_ssf + 2 * NB_SSF; - pt_enr_ssf1 = pt_enr_ssf + 2; - - /* Test on energy increase between adjacent sub-subframes */ - exp1 = 0; - move16(); - FOR( i = 0; i < 2 * NB_SSF; i++ ) - { - /*fac = *pt_enr_ssf1 / (*pt_enr_ssf + 1);*/ - Ltmp0 = L_max( *pt_enr_ssf, 1 ); - exp0 = norm_l( Ltmp0 ); - wtmp0 = extract_h( L_shl( Ltmp0, exp0 ) ); - exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 ); - wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) ); - fac = div_s( wtmp1, wtmp0 ); - fac_32 = L_shr_o( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ), &Overflow ); /* fac32 in Q13*/ - - if ( GT_32( fac_32, dE1 ) ) - { - ind_deltaMax = i; - move16(); - } - - dE1 = L_max( dE1, fac_32 ); /* Q13 */ - - pt_enr_ssf++; - pt_enr_ssf1++; - } - - IF( hStereoClassif != NULL ) - { - IF( st_fx->idchan == 0 ) - { - hStereoClassif->dE1_ch1_fx = dE1; /* Q13 */ - move32(); - hStereoClassif->dE1_ch1_e = 31 - Q13; - move16(); - } - ELSE - { - hStereoClassif->dE1_ch2_fx = dE1; /* Q13 */ - move32(); - hStereoClassif->dE1_ch2_e = 31 - Q13; - move16(); - } - } - - if ( dE1X != NULL ) - { - *dE1X = dE1; /* Q13 */ - move32(); - } - - /*-----------------------------------------------------------------* - * Average spectral tilt - * Average voicing (normalized correlation) - *-----------------------------------------------------------------*/ - - /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */ - mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); /* Q6 */ - mean_ee = Mult_32_16( mean_ee, 10923 ); /*Q6*/ - - /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/ - Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 /* 1/3 in Q15 */ ); /* Q31 */ - Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 /* 1/3 in Q15 */ ); /* Q31 */ - mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 /* 1/3 in Q15 */ ); /*Q15*/ - /*-----------------------------------------------------------------* - * Total frame energy difference (dE3) - *-----------------------------------------------------------------*/ - - dE3 = sub( Etot, hNoiseEst->Etot_last_fx ); /*Q8*/ - - /*-----------------------------------------------------------------* - * Energy decrease after spike (dE2) - *-----------------------------------------------------------------*/ - - /* set different thresholds and conditions for NB and WB input */ - dE2_th = 30 << 10; - move32(); - nb_cond = 1; - move16(); /* no additional condition for WB input */ - IF( st_fx->input_bwidth == NB ) - { - dE2_th = 21 << 10; - move32(); - if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ - { - nb_cond = 0; - move16(); - } - } - - /* calcualte maximum energy decrease */ - dE2 = 0; - move16(); /* Test on energy decrease after an energy spike */ - pt_enr_ssf = enr_ssf + 2 * NB_SSF; - - test(); - IF( GT_32( dE1, 30 << 13 ) && nb_cond ) /*>30 Q13*/ - { - IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) ) - { - st_fx->old_ind_deltaMax = ind_deltaMax; /* Q0 */ - move16(); - Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); /* Qx */ - } - ELSE - { - st_fx->old_ind_deltaMax = -1; - move16(); - dE2 = find_ener_decrease_fx( ind_deltaMax, pt_enr_ssf ); /*Q10*/ - - if ( GT_32( dE2, dE2_th ) ) - { - st_fx->spike_hyst = 0; - move16(); - } - } - } - ELSE - { - IF( st_fx->old_ind_deltaMax >= 0 ) - { - Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); /* Qx */ - dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); /* Q10 */ - - if ( GT_32( dE2, dE2_th ) ) - { - st_fx->spike_hyst = 1; - move16(); - } - } - - st_fx->old_ind_deltaMax = -1; - move16(); - } - - /*-----------------------------------------------------------------* - * Detection of voiced offsets (tmp_offset_flag) - *-----------------------------------------------------------------*/ - - tmp_offset_flag = 1; - move16(); - - IF( st_fx->input_bwidth != NB ) - { - ee0_th = 154; /*2.4 in Q6 */ - move16(); - voi_th = 24248; /*0.74f Q15 */ - move16(); - } - ELSE - { - ee0_th = 627; /*9.8f Q6 */ - move16(); - voi_th = 24904; /*0.76f Q15*/ - move16(); - } - - E_min_th = L_shl( E_MIN_IVAS_FX_Q31, sub( q_hp_E, Q31 ) ); - - test(); - test(); - test(); - IF( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ - ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ - ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */ - { - tmp_offset_flag = 0; - move16(); - } - - /*-----------------------------------------------------------------* - * Decision about UC - *-----------------------------------------------------------------*/ - - /* SC-VBR - set additional parameters and thresholds for SC-VBR */ - mean_voi3_offset = 0; - move16(); - flag_low_relE = 0; - move16(); - ee1_th = 608; /*9.5 Q6*/ - move16(); - test(); - test(); - IF( st_fx->Opt_SC_VBR || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) ) /* Allow the low energy flag for the secondary channel */ - { - ee1_th = 544; /*8.5f Q6*/ - move16(); - - /* SC-VBR - determine the threshold on relative energy as a function of lp_noise */ - IF( st_fx->input_bwidth != NB ) - { - /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */ - L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 22938 /* 0.7 in Q15 */, st_fx->lp_noise_fx ); // Q24 - IF( Last_Resort == 0 ) - { - /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/ - L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 21299 /* 0.650f in Q15 */, st_fx->lp_noise_fx ); // Q24 - } - relE_thres = round_fx( L_tmp ); - } - ELSE - { - - /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/ - L_tmp = L_mac( -473117491 /* 28.2f in Q24 */, 19661 /* 0.6f in Q15 */, st_fx->lp_noise_fx ); // Q24 - relE_thres = round_fx( L_tmp ); - } - relE_thres = s_max( relE_thres, -6400 /* -25.0f in Q8 */ ); /* Q8 */ - - /* SC-VBR = set flag on low relative energy */ - if ( LT_16( relE, relE_thres ) ) - { - flag_low_relE = 1; - move16(); - } - - /* SC-VBR - correction of voicing threshold for NB inputs (important only in noisy conditions) */ - test(); - if ( st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) /* vadnoise in Q8, constant Q0<<8 */ - { - mean_voi3_offset = 1638; /*0.05f Q15*/ - move16(); - } - } - - /* make decision whether frame is unvoiced */ - coder_type = GENERIC; - move16(); - IF( st_fx->input_bwidth == NB ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ - { - coder_type = UNVOICED; - move16(); - } - } - ELSE - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ - /*( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && */ /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], 397 /* 6.2f in Q16 */ ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 245760 /* 30.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) ) ) /* low relative frame energy (only for SC-VBR) */ - { - coder_type = UNVOICED; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Decision about VC - *-----------------------------------------------------------------*/ - if ( st_fx->Opt_SC_VBR ) - { - hSC_VBR->set_ppp_generic = 0; - } - move16(); - - test(); - test(); - IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) ) - { - dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); /* Q6 */ - dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); /* Q6 */ - dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); /* Q6 */ - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( GT_16( voicing_fr[0], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 1st sf. */ - ( GT_16( voicing_fr[1], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ - ( GT_16( voicing_fr[2], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ - ( GT_16( voicing_fr[3], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ - ( GT_32( mean_ee, 256 /* 4.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ - ( LT_16( dpit1, 3 << 6 ) ) && - ( LT_16( dpit2, 3 << 6 ) ) && - ( LT_16( dpit3, 3 << 6 ) ) ) - { - coder_type = VOICED; - move16(); - } - ELSE IF( st_fx->Opt_SC_VBR && st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_16( voicing_fr[0], 8192 /* 0.25 in Q15 */ ) && /* normalized correlation high in 1st sf. */ - ( GT_16( voicing_fr[1], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ - ( GT_16( voicing_fr[2], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ - ( GT_16( voicing_fr[3], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ - ( GT_32( mean_ee, 64 /* 1.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ - ( LT_16( dpit1, 5 << 6 ) ) && - ( LT_16( dpit2, 5 << 6 ) ) && - ( LT_16( dpit3, 5 << 6 ) ) ) - { - hSC_VBR->set_ppp_generic = 1; - move16(); - coder_type = VOICED; - move16(); - } - } - - /* set VOICED mode for frames with very stable pitch and high correlation - and avoid to switch to AUDIO/MUSIC later */ - voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 /* 0.25 in Q15 */ ), voicing_fr[2], 8192 /* 0.25 in Q15 */ ), voicing_fr[1], 8192 /* 0.25 in Q15 */ ), voicing_fr[0], 8192 /* 0.25 in Q15 */ ); /* Q15 */ - test(); - test(); - test(); - test(); - test(); - IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) && - GT_16( voicing_m, 31130 /* 0.95f in Q15 */ ) && GT_16( st_fx->voicing_sm_fx, 31785 /* 0.97f in Q15 */ ) ) ) - { - coder_type = VOICED; - move16(); - *flag_spitch = 1; - move16(); /*to avoid switch to AUDIO/MUSIC later*/ - } - } - - /*-----------------------------------------------------------------* - * Channel-aware mode - set RF mode and total bitrate - *-----------------------------------------------------------------*/ - - st_fx->rf_mode = st_fx->Opt_RF_ON; /* Q0 */ - move16(); - - IF( EQ_16( coder_type, GENERIC ) ) - { - test(); - test(); - test(); - test(); - IF( ( LT_16( voicing_fr[0], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ - ( LT_16( voicing_fr[1], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ - ( LT_16( voicing_fr[2], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 3rd sf. */ - ( LT_16( voicing_fr[3], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 4th sf. */ - ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */ - - { - st_fx->rf_mode = 0; - move16(); - /* Current frame cannot be compressed to pack the partial redundancy;*/ - - IF( NE_16( st_fx->rf_mode, st_fx->Opt_RF_ON ) ) - { - core_coder_mode_switch_ivas_fx( st_fx, st_fx->last_total_brate, 0 ); - } - } - } - - /*-----------------------------------------------------------------* - * UNCLR classifier - *-----------------------------------------------------------------*/ - - IF( hStereoClassif != NULL ) - { - test(); - test(); - test(); - test(); - test(); - IF( st_fx->element_mode > EVS_MONO && ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, UNVOICED ) || coder_type == INACTIVE || st_fx->localVAD == 0 ) && LT_16( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], MAX_UV_CNT ) ) - { - hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = add( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], 1 ); - move16(); - } - ELSE - { - hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = 0; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Updates - *-----------------------------------------------------------------*/ - - /* update spike hysteresis parameters */ - test(); - if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) ) - { - st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); /* Q0 */ - move16(); - } - - /* reset spike hysteresis */ - test(); - test(); - test(); - if ( ( GT_16( st_fx->spike_hyst, 1 ) ) && - ( GT_16( dE3, 5 << 8 ) || /* energy increases */ - ( GT_16( relE, -3328 /* 13 in Q8 */ ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 /* 0.695 in Q15 */ ) ) ) ) ) /* normalized correlation is high */ - { - st_fx->spike_hyst = -1; - move16(); - } - - /* update tilt parameters */ - st_fx->ee_old_fx = ee[1]; - move32(); /*Q6*/ - st_fx->old_dE1_fx = dE1; - move32(); /*Q13*/ - - /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */ - st_fx->coder_type_raw = coder_type; /* Q0 */ - move16(); - - return coder_type; -} -/*-------------------------------------------------------------------* - * find_uv() - * - * Decision about coder type - *-------------------------------------------------------------------*/ diff --git a/lib_enc/find_uv_fx.c b/lib_enc/find_uv_fx.c index 3f4c8abc7..200e538e4 100644 --- a/lib_enc/find_uv_fx.c +++ b/lib_enc/find_uv_fx.c @@ -618,3 +618,542 @@ Word16 find_uv_fx( /* o : coding type */ return coder_type; } + +/*-------------------------------------------------------------------* + * find_uv() + * + * Decision about coder type + *-------------------------------------------------------------------*/ +Word16 find_uv_ivas_fx( /* o : coding type */ + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ + const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ + const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ + const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ + Word32 *dE1X, /* o : sudden energy increase for S/M classifier Q13*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF q_hp_E*/ + Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ + const Word16 last_core_orig, /* i : original last core Q0*/ + STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ + const Word16 Q_new, + const Word16 q_hp_E ) +{ + Word16 coder_type, i; + Word32 mean_ee, dE1, fac_32; + const Word16 *pt_speech; + Word32 L_tmp, enr_ssf[2 * NB_SSF + 2 * NB_SSF + 2], E_min_th; + Word16 dE2; + Word16 ind_deltaMax, tmp_offset_flag; + Word32 Ltmp0, *pt_enr_ssf, *pt_enr_ssf1, dE2_th; + Word16 exp0, exp1; + Word16 wtmp0, wtmp1; + Word16 fac, mean_voi3, dE3; + Word16 relE_thres; + Word16 mean_voi3_offset; + Word16 voicing_m, dpit1, dpit2, dpit3; + Word16 ee0_th, ee1_th, voi_th, nb_cond, flag_low_relE; + NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst; + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + Word16 Last_Resort; + Word16 vadnoise; + + IF( hSC_VBR != NULL ) + { + Last_Resort = hSC_VBR->Last_Resort; /* Q0 */ + move16(); + vadnoise = hSC_VBR->vadnoise_fx; /* Q8 */ + move16(); + } + ELSE + { + Last_Resort = 0; + move16(); + vadnoise = 0; + move16(); + } + + /*-----------------------------------------------------------------* + * Detect sudden energy increases to catch voice and music + * temporal events (dE1) + * + * - Find maximum energy per short subblocks. + * Two subblock sets are used shifted by half the subblock length + * - Find maximum energy ratio between adjacent subblocks + *-----------------------------------------------------------------*/ + + /* Find maximum energy per short subblocks */ + pt_speech = speech - SSF; + pt_enr_ssf = enr_ssf + 2 * NB_SSF; + FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ ) + { + emaximum_fx( Q_new, pt_speech, SSF, pt_enr_ssf ); + pt_speech += ( SSF / 2 ); + pt_enr_ssf++; + } + + dE1 = 0; + move16(); + ind_deltaMax = 0; + move16(); + pt_enr_ssf = enr_ssf + 2 * NB_SSF; + pt_enr_ssf1 = pt_enr_ssf + 2; + + /* Test on energy increase between adjacent sub-subframes */ + exp1 = 0; + move16(); + FOR( i = 0; i < 2 * NB_SSF; i++ ) + { + /*fac = *pt_enr_ssf1 / (*pt_enr_ssf + 1);*/ + Ltmp0 = L_max( *pt_enr_ssf, 1 ); + exp0 = norm_l( Ltmp0 ); + wtmp0 = extract_h( L_shl( Ltmp0, exp0 ) ); + exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 ); + wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) ); + fac = div_s( wtmp1, wtmp0 ); + fac_32 = L_shr_o( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ), &Overflow ); /* fac32 in Q13*/ + + if ( GT_32( fac_32, dE1 ) ) + { + ind_deltaMax = i; + move16(); + } + + dE1 = L_max( dE1, fac_32 ); /* Q13 */ + + pt_enr_ssf++; + pt_enr_ssf1++; + } + + IF( hStereoClassif != NULL ) + { + IF( st_fx->idchan == 0 ) + { + hStereoClassif->dE1_ch1_fx = dE1; /* Q13 */ + move32(); + hStereoClassif->dE1_ch1_e = 31 - Q13; + move16(); + } + ELSE + { + hStereoClassif->dE1_ch2_fx = dE1; /* Q13 */ + move32(); + hStereoClassif->dE1_ch2_e = 31 - Q13; + move16(); + } + } + + if ( dE1X != NULL ) + { + *dE1X = dE1; /* Q13 */ + move32(); + } + + /*-----------------------------------------------------------------* + * Average spectral tilt + * Average voicing (normalized correlation) + *-----------------------------------------------------------------*/ + + /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */ + mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); /* Q6 */ + mean_ee = Mult_32_16( mean_ee, 10923 ); /*Q6*/ + + /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/ + Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 /* 1/3 in Q15 */ ); /* Q31 */ + Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 /* 1/3 in Q15 */ ); /* Q31 */ + mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 /* 1/3 in Q15 */ ); /*Q15*/ + /*-----------------------------------------------------------------* + * Total frame energy difference (dE3) + *-----------------------------------------------------------------*/ + + dE3 = sub( Etot, hNoiseEst->Etot_last_fx ); /*Q8*/ + + /*-----------------------------------------------------------------* + * Energy decrease after spike (dE2) + *-----------------------------------------------------------------*/ + + /* set different thresholds and conditions for NB and WB input */ + dE2_th = 30 << 10; + move32(); + nb_cond = 1; + move16(); /* no additional condition for WB input */ + IF( st_fx->input_bwidth == NB ) + { + dE2_th = 21 << 10; + move32(); + if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ + { + nb_cond = 0; + move16(); + } + } + + /* calcualte maximum energy decrease */ + dE2 = 0; + move16(); /* Test on energy decrease after an energy spike */ + pt_enr_ssf = enr_ssf + 2 * NB_SSF; + + test(); + IF( GT_32( dE1, 30 << 13 ) && nb_cond ) /*>30 Q13*/ + { + IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) ) + { + st_fx->old_ind_deltaMax = ind_deltaMax; /* Q0 */ + move16(); + Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); /* Qx */ + } + ELSE + { + st_fx->old_ind_deltaMax = -1; + move16(); + dE2 = find_ener_decrease_fx( ind_deltaMax, pt_enr_ssf ); /*Q10*/ + + if ( GT_32( dE2, dE2_th ) ) + { + st_fx->spike_hyst = 0; + move16(); + } + } + } + ELSE + { + IF( st_fx->old_ind_deltaMax >= 0 ) + { + Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); /* Qx */ + dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); /* Q10 */ + + if ( GT_32( dE2, dE2_th ) ) + { + st_fx->spike_hyst = 1; + move16(); + } + } + + st_fx->old_ind_deltaMax = -1; + move16(); + } + + /*-----------------------------------------------------------------* + * Detection of voiced offsets (tmp_offset_flag) + *-----------------------------------------------------------------*/ + + tmp_offset_flag = 1; + move16(); + + IF( st_fx->input_bwidth != NB ) + { + ee0_th = 154; /*2.4 in Q6 */ + move16(); + voi_th = 24248; /*0.74f Q15 */ + move16(); + } + ELSE + { + ee0_th = 627; /*9.8f Q6 */ + move16(); + voi_th = 24904; /*0.76f Q15*/ + move16(); + } + + E_min_th = L_shl( E_MIN_IVAS_FX_Q31, sub( q_hp_E, Q31 ) ); + + test(); + test(); + test(); + IF( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ + ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ + ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */ + { + tmp_offset_flag = 0; + move16(); + } + + /*-----------------------------------------------------------------* + * Decision about UC + *-----------------------------------------------------------------*/ + + /* SC-VBR - set additional parameters and thresholds for SC-VBR */ + mean_voi3_offset = 0; + move16(); + flag_low_relE = 0; + move16(); + ee1_th = 608; /*9.5 Q6*/ + move16(); + test(); + test(); + IF( st_fx->Opt_SC_VBR || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) ) /* Allow the low energy flag for the secondary channel */ + { + ee1_th = 544; /*8.5f Q6*/ + move16(); + + /* SC-VBR - determine the threshold on relative energy as a function of lp_noise */ + IF( st_fx->input_bwidth != NB ) + { + /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */ + L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 22938 /* 0.7 in Q15 */, st_fx->lp_noise_fx ); // Q24 + IF( Last_Resort == 0 ) + { + /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/ + L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 21299 /* 0.650f in Q15 */, st_fx->lp_noise_fx ); // Q24 + } + relE_thres = round_fx( L_tmp ); + } + ELSE + { + + /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/ + L_tmp = L_mac( -473117491 /* 28.2f in Q24 */, 19661 /* 0.6f in Q15 */, st_fx->lp_noise_fx ); // Q24 + relE_thres = round_fx( L_tmp ); + } + relE_thres = s_max( relE_thres, -6400 /* -25.0f in Q8 */ ); /* Q8 */ + + /* SC-VBR = set flag on low relative energy */ + if ( LT_16( relE, relE_thres ) ) + { + flag_low_relE = 1; + move16(); + } + + /* SC-VBR - correction of voicing threshold for NB inputs (important only in noisy conditions) */ + test(); + if ( st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) /* vadnoise in Q8, constant Q0<<8 */ + { + mean_voi3_offset = 1638; /*0.05f Q15*/ + move16(); + } + } + + /* make decision whether frame is unvoiced */ + coder_type = GENERIC; + move16(); + IF( st_fx->input_bwidth == NB ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ + ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */ + ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ + ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ + ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ + /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ + ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ + ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */ + ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ + flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ + { + coder_type = UNVOICED; + move16(); + } + } + ELSE + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ + /*( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && */ /* normalized correlation low on look-ahead - onset detection */ + ( LT_32( ee[0], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ + ( LT_32( ee[1], 397 /* 6.2f in Q16 */ ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ + ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ + /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ + ( LE_32( dE1, 245760 /* 30.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ + ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) && /* + one frame hysteresis */ + ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ + || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) ) ) /* low relative frame energy (only for SC-VBR) */ + { + coder_type = UNVOICED; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Decision about VC + *-----------------------------------------------------------------*/ + if ( st_fx->Opt_SC_VBR ) + { + hSC_VBR->set_ppp_generic = 0; + } + move16(); + + test(); + test(); + IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) ) + { + dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); /* Q6 */ + dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); /* Q6 */ + dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); /* Q6 */ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( GT_16( voicing_fr[0], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 1st sf. */ + ( GT_16( voicing_fr[1], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( GT_16( voicing_fr[2], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ + ( GT_16( voicing_fr[3], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ + ( GT_32( mean_ee, 256 /* 4.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ + ( LT_16( dpit1, 3 << 6 ) ) && + ( LT_16( dpit2, 3 << 6 ) ) && + ( LT_16( dpit3, 3 << 6 ) ) ) + { + coder_type = VOICED; + move16(); + } + ELSE IF( st_fx->Opt_SC_VBR && st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_16( voicing_fr[0], 8192 /* 0.25 in Q15 */ ) && /* normalized correlation high in 1st sf. */ + ( GT_16( voicing_fr[1], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( GT_16( voicing_fr[2], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ + ( GT_16( voicing_fr[3], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ + ( GT_32( mean_ee, 64 /* 1.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ + ( LT_16( dpit1, 5 << 6 ) ) && + ( LT_16( dpit2, 5 << 6 ) ) && + ( LT_16( dpit3, 5 << 6 ) ) ) + { + hSC_VBR->set_ppp_generic = 1; + move16(); + coder_type = VOICED; + move16(); + } + } + + /* set VOICED mode for frames with very stable pitch and high correlation + and avoid to switch to AUDIO/MUSIC later */ + voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 /* 0.25 in Q15 */ ), voicing_fr[2], 8192 /* 0.25 in Q15 */ ), voicing_fr[1], 8192 /* 0.25 in Q15 */ ), voicing_fr[0], 8192 /* 0.25 in Q15 */ ); /* Q15 */ + test(); + test(); + test(); + test(); + test(); + IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) && + GT_16( voicing_m, 31130 /* 0.95f in Q15 */ ) && GT_16( st_fx->voicing_sm_fx, 31785 /* 0.97f in Q15 */ ) ) ) + { + coder_type = VOICED; + move16(); + *flag_spitch = 1; + move16(); /*to avoid switch to AUDIO/MUSIC later*/ + } + } + + /*-----------------------------------------------------------------* + * Channel-aware mode - set RF mode and total bitrate + *-----------------------------------------------------------------*/ + + st_fx->rf_mode = st_fx->Opt_RF_ON; /* Q0 */ + move16(); + + IF( EQ_16( coder_type, GENERIC ) ) + { + test(); + test(); + test(); + test(); + IF( ( LT_16( voicing_fr[0], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( LT_16( voicing_fr[1], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( LT_16( voicing_fr[2], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 3rd sf. */ + ( LT_16( voicing_fr[3], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 4th sf. */ + ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */ + + { + st_fx->rf_mode = 0; + move16(); + /* Current frame cannot be compressed to pack the partial redundancy;*/ + + IF( NE_16( st_fx->rf_mode, st_fx->Opt_RF_ON ) ) + { + core_coder_mode_switch_ivas_fx( st_fx, st_fx->last_total_brate, 0 ); + } + } + } + + /*-----------------------------------------------------------------* + * UNCLR classifier + *-----------------------------------------------------------------*/ + + IF( hStereoClassif != NULL ) + { + test(); + test(); + test(); + test(); + test(); + IF( st_fx->element_mode > EVS_MONO && ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, UNVOICED ) || coder_type == INACTIVE || st_fx->localVAD == 0 ) && LT_16( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], MAX_UV_CNT ) ) + { + hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = add( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], 1 ); + move16(); + } + ELSE + { + hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = 0; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Updates + *-----------------------------------------------------------------*/ + + /* update spike hysteresis parameters */ + test(); + if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) ) + { + st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); /* Q0 */ + move16(); + } + + /* reset spike hysteresis */ + test(); + test(); + test(); + if ( ( GT_16( st_fx->spike_hyst, 1 ) ) && + ( GT_16( dE3, 5 << 8 ) || /* energy increases */ + ( GT_16( relE, -3328 /* 13 in Q8 */ ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 /* 0.695 in Q15 */ ) ) ) ) ) /* normalized correlation is high */ + { + st_fx->spike_hyst = -1; + move16(); + } + + /* update tilt parameters */ + st_fx->ee_old_fx = ee[1]; + move32(); /*Q6*/ + st_fx->old_dE1_fx = dE1; + move32(); /*Q13*/ + + /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */ + st_fx->coder_type_raw = coder_type; /* Q0 */ + move16(); + + return coder_type; +} diff --git a/lib_enc/find_wsp.c b/lib_enc/find_wsp.c deleted file mode 100644 index 89b77d351..000000000 --- a/lib_enc/find_wsp.c +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" -/*-------------------------------------------------------------------* - * ivas_find_wsp_fx() - * - * Compute weighted speech used in open-loop pitch search - *-------------------------------------------------------------------*/ -void ivas_find_wsp_fx( - const Word16 L_frame, /* i : length of the frame Q0*/ - const Word16 L_subfr, /* i : length of subframe Q0*/ - const Word16 nb_subfr, /* i : number of subframes Q0*/ - const Word16 *A_fx, - /* i : A(z) filter coefficients */ // Q12 - Word16 *Aw_fx, - /* o : weighted A(z) filter coefficients */ // Q12 - const Word16 *speech_fx, - /* i : pointer to the denoised speech frame */ // Q_new - const Word16 tilt_fact, - /* i : tilt factor */ // Q15 - Word16 *wsp_fx, - /* o : poitnter to the weighted speech frame */ // Q_new - Word16 *mem_wsp_fx, - /* i/o: W(Z) denominator memory */ // Q_new - const Word16 gamma, - /* i : weighting factor */ // Q15 - const Word16 L_look /* i : look-ahead Q0*/ -) -{ - Word16 *p_Aw_fx, tmp_fx; - Word16 i_subfr; - - - /*-----------------------------------------------------------------* - * Compute weighted A(z) unquantized for subframes - *-----------------------------------------------------------------*/ - weight_a_subfr_fx( nb_subfr, A_fx, Aw_fx, gamma, M ); - - /*-----------------------------------------------------------------* - * Compute weighted speech for all subframes - *-----------------------------------------------------------------*/ - p_Aw_fx = Aw_fx; - FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr ) - { - Residu3_fx( p_Aw_fx, &speech_fx[i_subfr], &wsp_fx[i_subfr], L_subfr, 0 ); - p_Aw_fx += ( M + 1 ); - } - p_Aw_fx -= ( M + 1 ); - - /*-----------------------------------------------------------------* - * Weighted speech computation is extended on look-ahead - *-----------------------------------------------------------------*/ - - deemph_fx( wsp_fx, tilt_fact, L_frame, mem_wsp_fx ); - Residu3_fx( p_Aw_fx, &speech_fx[L_frame], &wsp_fx[L_frame], L_look, 0 ); - tmp_fx = *mem_wsp_fx; - deemph_fx( &wsp_fx[L_frame], tilt_fact, L_look, &tmp_fx ); - return; -} diff --git a/lib_enc/find_wsp_fx.c b/lib_enc/find_wsp_fx.c index 7468c3dc7..d08922a2a 100644 --- a/lib_enc/find_wsp_fx.c +++ b/lib_enc/find_wsp_fx.c @@ -6,7 +6,7 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" +#include "prot.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -78,3 +78,60 @@ void find_wsp_fx( deemph_fx( &wsp[L_frame], preemph_fac, lookahead, &wtmp ); } } + +/*-------------------------------------------------------------------* + * ivas_find_wsp_fx() + * + * Compute weighted speech used in open-loop pitch search + *-------------------------------------------------------------------*/ +void ivas_find_wsp_fx( + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_subfr, /* i : length of subframe Q0*/ + const Word16 nb_subfr, /* i : number of subframes Q0*/ + const Word16 *A_fx, + /* i : A(z) filter coefficients */ // Q12 + Word16 *Aw_fx, + /* o : weighted A(z) filter coefficients */ // Q12 + const Word16 *speech_fx, + /* i : pointer to the denoised speech frame */ // Q_new + const Word16 tilt_fact, + /* i : tilt factor */ // Q15 + Word16 *wsp_fx, + /* o : poitnter to the weighted speech frame */ // Q_new + Word16 *mem_wsp_fx, + /* i/o: W(Z) denominator memory */ // Q_new + const Word16 gamma, + /* i : weighting factor */ // Q15 + const Word16 L_look /* i : look-ahead Q0*/ +) +{ + Word16 *p_Aw_fx, tmp_fx; + Word16 i_subfr; + + + /*-----------------------------------------------------------------* + * Compute weighted A(z) unquantized for subframes + *-----------------------------------------------------------------*/ + weight_a_subfr_fx( nb_subfr, A_fx, Aw_fx, gamma, M ); + + /*-----------------------------------------------------------------* + * Compute weighted speech for all subframes + *-----------------------------------------------------------------*/ + p_Aw_fx = Aw_fx; + FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr ) + { + Residu3_fx( p_Aw_fx, &speech_fx[i_subfr], &wsp_fx[i_subfr], L_subfr, 0 ); + p_Aw_fx += ( M + 1 ); + } + p_Aw_fx -= ( M + 1 ); + + /*-----------------------------------------------------------------* + * Weighted speech computation is extended on look-ahead + *-----------------------------------------------------------------*/ + + deemph_fx( wsp_fx, tilt_fact, L_frame, mem_wsp_fx ); + Residu3_fx( p_Aw_fx, &speech_fx[L_frame], &wsp_fx[L_frame], L_look, 0 ); + tmp_fx = *mem_wsp_fx; + deemph_fx( &wsp_fx[L_frame], tilt_fact, L_look, &tmp_fx ); + return; +} diff --git a/lib_enc/frame_spec_dif_cor_rate.c b/lib_enc/frame_spec_dif_cor_rate.c deleted file mode 100644 index 9185f37bd..000000000 --- a/lib_enc/frame_spec_dif_cor_rate.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * frame_spec_dif_cor_rate() - * - * - *-------------------------------------------------------------------*/ diff --git a/lib_enc/gain_enc.c b/lib_enc/gain_enc.c deleted file mode 100644 index 276e20738..000000000 --- a/lib_enc/gain_enc.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define RANGE 64 - -/*---------------------------------------------------------------------* - * Es_pred_enc() - * - * Calculation and quantization of average predicted innovation energy to be - *---------------------------------------------------------------------*/ diff --git a/lib_enc/gs_enc.c b/lib_enc/gs_enc.c deleted file mode 100644 index 900c381bf..000000000 --- a/lib_enc/gs_enc.c +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * GSC_enc_init() - * - * Initialize GSC encoder state structure - *-------------------------------------------------------------------*/ diff --git a/lib_enc/guided_plc_enc.c b/lib_enc/guided_plc_enc.c deleted file mode 100644 index 6c0e9022d..000000000 --- a/lib_enc/guided_plc_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "stat_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/hf_cod_amrwb.c b/lib_enc/hf_cod_amrwb.c deleted file mode 100644 index 7ea6e47a5..000000000 --- a/lib_enc/hf_cod_amrwb.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/hq_classifier_enc.c b/lib_enc/hq_classifier_enc.c deleted file mode 100644 index 634f42971..000000000 --- a/lib_enc/hq_classifier_enc.c +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -/*-----------------------------------------------------------------* - * Local constants - *-----------------------------------------------------------------*/ - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c deleted file mode 100644 index 24579e74e..000000000 --- a/lib_enc/hq_core_enc.c +++ /dev/null @@ -1,410 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -#include "prot_fx.h" -#include "prot_fx_enc.h" - -/*-------------------------------------------------------------------------- - * hq_core_enc() - * - * HQ core encoder - *--------------------------------------------------------------------------*/ - -void hq_core_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *audio_fx, /* i : input audio signal Q0 */ - const Word16 input_frame_orig, /* i : frame length Q0*/ - const Word16 hq_core_type, /* i : HQ core type Q0*/ - const Word16 Voicing_flag, /* i : Voicing flag for FER method selection Q0*/ - const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ -) -{ - Word16 i, is_transient, num_bits, extra_unused; - - Word32 t_audio_fx[L_FRAME48k_EXT]; - Word16 wtda_audio_fx16[2 * L_FRAME48k]; - Word32 wtda_audio_fx32[2 * L_FRAME48k]; - Word16 two_frames_buffer[2 * L_FRAME48k]; - Word16 tmp; - Word16 Aq_old_fx[M + 1]; - Word16 output_fx[L_FRAME48k]; - Word16 Q_audio; - Word16 out_q = 0, old_q = 0; - move16(); - move16(); - Word16 inner_frame, input_frame, L_frame; - Word16 L_spec, overlap, nz, tcx_offset; - Word16 left_overlap, right_overlap; - BSTR_ENC_HANDLE hBstr = st->hBstr; - Word16 q = 0; - Word16 exp; - move16(); - - push_wmops( "hq_core_enc" ); - - set16_fx( wtda_audio_fx16, 0, 2 * L_FRAME48k ); - set32_fx( wtda_audio_fx32, 0, 2 * L_FRAME48k ); - st->Nb_ACELP_frames = 0; - move16(); - set_zero_fx( t_audio_fx, L_FRAME48k_EXT ); - /* set input_frame length */ - input_frame = input_frame_orig; /* Q0 */ - - /* Sanity check, it should never happen at the encoder side (no BFI) */ - IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) - { - st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; - move16(); - } - ELSE - { - st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - - /*-------------------------------------------------------------------------- - * Preprocessing in the first HQ frame after ACELP frame - * Find the number of bits for PVQ coding - * Write signaling information - *--------------------------------------------------------------------------*/ - - num_bits = BASOP_Util_Divide3232_Scale( st->total_brate, FRAMES_PER_SEC, &exp ); /* Q15-exp */ - num_bits = shr( num_bits, sub( 15, exp ) ); /* Q0 */ - extra_unused = 0; - move16(); - - /*-------------------------------------------------------------------------- - * Detect signal transition - *--------------------------------------------------------------------------*/ - - is_transient = detect_transient_fx( audio_fx, input_frame, 0, st ); /* Q0 */ - move16(); - - test(); - test(); - IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) - { - /*-------------------------------------------------------------------------- - * IVAS switching frame - *--------------------------------------------------------------------------*/ - - L_spec = input_frame; - left_overlap = -1; - right_overlap = -1; - move16(); - move16(); - move16(); - - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_spec, wtda_audio_fx16, 1, 1 ); - - q = 0; - move16(); - Q_audio = sub( Q16, q ); - TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); - Q_audio = sub( Q31, Q_audio ); -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ -#else - Copy_Scale_sig_16_32_DEPREC( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ -#endif - inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ - L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ - is_transient = 0; - move16(); - move16(); - move16(); - } - ELSE - { - /*-------------------------------------------------------------------------- - * Windowing and time-domain aliasing - * DCT transform - *--------------------------------------------------------------------------*/ - Q_audio = 0; - move16(); - Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); /* Q0 */ - Scale_sig( st->input_fx, add( input_frame, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( st->q_inp ) ); /* Q0 */ - st->q_old_inp = 0; - move16(); - st->q_inp = 0; - move16(); - Copy( st->old_input_signal_fx, two_frames_buffer, input_frame ); /* Q0 */ - Copy( audio_fx, two_frames_buffer + input_frame, input_frame ); /* Q0 */ - - wtda_fx( two_frames_buffer + input_frame, &Q_audio, wtda_audio_fx32, NULL, 0, - st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, input_frame ); - - test(); - IF( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) - { - /* Preprocessing in the first HQ frame after ACELP frame */ - core_switching_hq_prepare_enc_fx( st, &num_bits, input_frame, wtda_audio_fx32, two_frames_buffer + input_frame ); - - /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */ - IF( GT_16( num_bits, ACELP_48k_BITS ) ) - { - extra_unused = sub( num_bits, ACELP_48k_BITS ); - num_bits = ACELP_48k_BITS; - move16(); - } - } - - Word16 tmp_q = Q_audio; - move16(); - direct_transform_fx( wtda_audio_fx32, t_audio_fx, is_transient, input_frame, &Q_audio, st->element_mode ); - scale_sig32( wtda_audio_fx32, L_FRAME48k_EXT, sub( Q_audio, tmp_q ) ); /* Q_audio */ - - /* scale coefficients to their nominal level (8kHz) */ - IF( NE_16( input_frame, NORM_MDCT_FACTOR ) ) - { - UWord16 lsb; - tmp = mult_r( input_frame, 410 / 2 ); /* 1/8000 in Q15 */ - Word16 ener_match_fx = hq_nominal_scaling[tmp]; - move16(); - FOR( i = 0; i < input_frame; i++ ) - { - /*t_audio_q[i] *= ener_match; */ - Mpy_32_16_ss( t_audio_fx[i], ener_match_fx, &t_audio_fx[i], &lsb ); /* Q12 */ - move16(); - } - } - - /* limit encoded band-width according to the command-line OR BWD limitation */ - inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ - L_spec = l_spec_tbl[st->bwidth]; /* Q0 */ - - move16(); - move16(); - - - IF( GT_16( input_frame, inner_frame ) ) - { - IF( EQ_16( is_transient, 1 ) ) - { - FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) - { - tmp = shr( inner_frame, 2 ); - Copy32( t_audio_fx + i_mult2( i, shr( input_frame, 2 ) ), t_audio_fx + i_mult2( i, tmp ), tmp ); /* Q_audio */ - } - } - - set32_fx( t_audio_fx + inner_frame, 0, sub( input_frame, inner_frame ) ); - } - } - - - /* subtract signaling bits */ - num_bits = sub( num_bits, hBstr->nb_bits_tot ); /* Q0 */ - - /*-------------------------------------------------------------------------- - * High-band gain control in case of BWS - *--------------------------------------------------------------------------*/ - - IF( st->bwidth_sw_cnt > 0 ) - { - Word32 L_tmp; - tmp = BASOP_Util_Divide1616_Scale( 3, BWS_TRAN_PERIOD, &exp ); /* Q15-exp */ - shr( tmp, exp ); - L_tmp = L_deposit_h( tmp ); /* Q31-exp */ - IF( is_transient ) - { - FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) - { - v_multc_fixed( t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), L_tmp, t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), sub( shr( inner_frame, 2 ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ) ); // Q_audio + Q31 - Q31 -> Q_audio - } - } - ELSE - { - v_multc_fixed( t_audio_fx + L_FRAME16k, L_tmp, t_audio_fx + L_FRAME16k, L_spec - L_FRAME16k ); // Q_audio + Q31 - Q31 -> Q_audio - } - } - - /*-------------------------------------------------------------------------- - * Classify whether to put extra bits for FER mitigation - *--------------------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, HQ_CORE ) ) && GT_32( st->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) ) - { - IF( Voicing_flag > 0 ) - { - push_indice( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); - num_bits = sub( num_bits, 1 ); - } - ELSE - { - push_indice( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); - num_bits = sub( num_bits, 1 ); - } - } - - /*-------------------------------------------------------------------------- - * Transform-domain encoding - *--------------------------------------------------------------------------*/ - - scale_sig32( t_audio_fx, L_FRAME48k_EXT, sub( Q12, Q_audio ) ); - scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q12, Q_audio ) ); - Q_audio = 12; - move16(); - IF( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) - { - - hq_lr_enc_ivas_fx( st, t_audio_fx, inner_frame, &num_bits, is_transient ); - } - ELSE - { - /* HQ high rate encoder */ - hq_hr_enc_ivas_fx( st, t_audio_fx, L_spec, &num_bits, is_transient, vad_hover_flag ); - } - - /* write all unused bits to the bitstream */ - num_bits = add( num_bits, extra_unused ); - - WHILE( GT_16( num_bits, 16 ) ) - { - push_indice( hBstr, IND_UNUSED, 0, 16 ); - num_bits = sub( num_bits, 16 ); - } - - IF( num_bits != 0 ) - { - push_indice( hBstr, IND_UNUSED, 0, num_bits ); - } - - test(); - test(); - IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) - { - overlap = st->hTcxCfg->tcx_mdct_window_length; /* Q0 */ - move16(); - - nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS ); - move16(); - L_frame = sub( st->L_frame + st->hTcxCfg->tcx_offset, st->hTcxCfg->lfacNext ); - tcx_offset = st->hTcxCfg->lfacNext; - move16(); - - set16_fx( Aq_old_fx, 0, M + 1 ); /* Dummy filter */ - Aq_old_fx[0] = 1; - move16(); - - /* Code taken from InternalTCXDecoder() */ - Copy_Scale_sig_32_16( wtda_audio_fx32, wtda_audio_fx16, 2 * L_FRAME48k, negate( Q_audio ) ); // Q0 - TCX_MDCT_Inverse( t_audio_fx, sub( sub( 31, Q_audio ), 15 ), wtda_audio_fx16, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); - - - /* Window current frame */ - Word16 tcx_offset_tmp; - - IF( tcx_offset < 0 ) - { - tcx_offset_tmp = negate( tcx_offset ); - } - ELSE - { - tcx_offset_tmp = 0; - move16(); - } - tcx_windowing_synthesis_current_frame( wtda_audio_fx16, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old_fx, st->hTcxCfg->tcx_mdct_window_trans, shr( st->L_frame, 1 ), tcx_offset_tmp, st->last_core, 0, 0 ); - - - /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ - Copy( wtda_audio_fx16 + sub( L_frame, nz ), st->hTcxEnc->old_out_fx, nz + overlap ); /* Q0 */ - set16_fx( st->hTcxEnc->old_out_fx + add( nz, overlap ), 0, nz ); - - tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out_fx + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); - - FOR( i = 0; i < nz / 2; i++ ) - { - // This implementation is diffrent in float code need to revisit to check its correctness. - st->hTcxEnc->old_out_fx[nz + overlap + i] = mult( wtda_audio_fx16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1_trunc[i].v.re ); // Q0 + Q15 - Q15 -> Q0; - st->hTcxEnc->old_out_fx[nz / 2 + ( nz + overlap + i )] = mult( wtda_audio_fx16[nz / 2 + ( L_frame - 1 - i )], st->hTcxCfg->tcx_aldo_window_1_trunc[nz / 2 - 1 - i].v.im ); // Q0 + Q15 - Q15 -> Q0; - move16(); - move16(); - } - - Copy( wtda_audio_fx16 + sub( shr( overlap, 1 ), tcx_offset ), output_fx, st->L_frame ); /* Q0 */ - } - ELSE - { - Word16 tmp_q = Q_audio; - move16(); - Word32 ener_match_fx = SQRT2_FIXED; - move32(); - FOR( i = 0; i < input_frame; i++ ) - { - t_audio_fx[i] = Mpy_32_32( t_audio_fx[i], ener_match_fx ); /* Q12 - 1 -> Q11 */ - move32(); - } - - Q_audio = sub( Q_audio, 1 ); - scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, tmp_q ) ); /* Q_audio */ - Inverse_Transform( t_audio_fx, &Q_audio, wtda_audio_fx32, is_transient, L_FRAME16k, inner_frame, st->element_mode ); - - - out_q = Q_audio; - move16(); - window_ola_fx( wtda_audio_fx32, output_fx, &out_q, st->hTcxEnc->old_out_fx, &old_q, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); - - Scale_sig( output_fx, L_FRAME16k, negate( out_q ) ); /* Q0 */ - Scale_sig( st->hTcxEnc->old_out_fx, L_FRAME32k, negate( old_q ) ); /* Q0 */ - st->hTcxEnc->Q_old_out = 0; - move16(); - } - - IF( st->element_mode > EVS_MONO ) - { - /* Store LB synthesis in case of switch to ACELP */ - Copy( output_fx, st->hLPDmem->old_exc, L_FRAME16k ); - st->hLPDmem->q_lpd_old_exc = 0; - move16(); - } - pop_wmops(); - - return; -} diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index 6dc7bb5b9..11583ea11 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -7,6 +7,7 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -388,3 +389,361 @@ void HQ_core_enc_init_fx( return; } + +void hq_core_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 *audio_fx, /* i : input audio signal Q0 */ + const Word16 input_frame_orig, /* i : frame length Q0*/ + const Word16 hq_core_type, /* i : HQ core type Q0*/ + const Word16 Voicing_flag, /* i : Voicing flag for FER method selection Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ +) +{ + Word16 i, is_transient, num_bits, extra_unused; + + Word32 t_audio_fx[L_FRAME48k_EXT]; + Word16 wtda_audio_fx16[2 * L_FRAME48k]; + Word32 wtda_audio_fx32[2 * L_FRAME48k]; + Word16 two_frames_buffer[2 * L_FRAME48k]; + Word16 tmp; + Word16 Aq_old_fx[M + 1]; + Word16 output_fx[L_FRAME48k]; + Word16 Q_audio; + Word16 out_q = 0, old_q = 0; + move16(); + move16(); + Word16 inner_frame, input_frame, L_frame; + Word16 L_spec, overlap, nz, tcx_offset; + Word16 left_overlap, right_overlap; + BSTR_ENC_HANDLE hBstr = st->hBstr; + Word16 q = 0; + Word16 exp; + move16(); + + push_wmops( "hq_core_enc" ); + + set16_fx( wtda_audio_fx16, 0, 2 * L_FRAME48k ); + set32_fx( wtda_audio_fx32, 0, 2 * L_FRAME48k ); + st->Nb_ACELP_frames = 0; + move16(); + set_zero_fx( t_audio_fx, L_FRAME48k_EXT ); + /* set input_frame length */ + input_frame = input_frame_orig; /* Q0 */ + + /* Sanity check, it should never happen at the encoder side (no BFI) */ + IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) + { + st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + ELSE + { + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + + /*-------------------------------------------------------------------------- + * Preprocessing in the first HQ frame after ACELP frame + * Find the number of bits for PVQ coding + * Write signaling information + *--------------------------------------------------------------------------*/ + + num_bits = BASOP_Util_Divide3232_Scale( st->total_brate, FRAMES_PER_SEC, &exp ); /* Q15-exp */ + num_bits = shr( num_bits, sub( 15, exp ) ); /* Q0 */ + extra_unused = 0; + move16(); + + /*-------------------------------------------------------------------------- + * Detect signal transition + *--------------------------------------------------------------------------*/ + + is_transient = detect_transient_fx( audio_fx, input_frame, 0, st ); /* Q0 */ + move16(); + + test(); + test(); + IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) + { + /*-------------------------------------------------------------------------- + * IVAS switching frame + *--------------------------------------------------------------------------*/ + + L_spec = input_frame; + left_overlap = -1; + right_overlap = -1; + move16(); + move16(); + move16(); + + WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_spec, wtda_audio_fx16, 1, 1 ); + + q = 0; + move16(); + Q_audio = sub( Q16, q ); + TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); + Q_audio = sub( Q31, Q_audio ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ +#else + Copy_Scale_sig_16_32_DEPREC( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ +#endif + inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ + L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ + is_transient = 0; + move16(); + move16(); + move16(); + } + ELSE + { + /*-------------------------------------------------------------------------- + * Windowing and time-domain aliasing + * DCT transform + *--------------------------------------------------------------------------*/ + Q_audio = 0; + move16(); + Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); /* Q0 */ + Scale_sig( st->input_fx, add( input_frame, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( st->q_inp ) ); /* Q0 */ + st->q_old_inp = 0; + move16(); + st->q_inp = 0; + move16(); + Copy( st->old_input_signal_fx, two_frames_buffer, input_frame ); /* Q0 */ + Copy( audio_fx, two_frames_buffer + input_frame, input_frame ); /* Q0 */ + + wtda_fx( two_frames_buffer + input_frame, &Q_audio, wtda_audio_fx32, NULL, 0, + st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, input_frame ); + + test(); + IF( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) + { + /* Preprocessing in the first HQ frame after ACELP frame */ + core_switching_hq_prepare_enc_fx( st, &num_bits, input_frame, wtda_audio_fx32, two_frames_buffer + input_frame ); + + /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */ + IF( GT_16( num_bits, ACELP_48k_BITS ) ) + { + extra_unused = sub( num_bits, ACELP_48k_BITS ); + num_bits = ACELP_48k_BITS; + move16(); + } + } + + Word16 tmp_q = Q_audio; + move16(); + direct_transform_fx( wtda_audio_fx32, t_audio_fx, is_transient, input_frame, &Q_audio, st->element_mode ); + scale_sig32( wtda_audio_fx32, L_FRAME48k_EXT, sub( Q_audio, tmp_q ) ); /* Q_audio */ + + /* scale coefficients to their nominal level (8kHz) */ + IF( NE_16( input_frame, NORM_MDCT_FACTOR ) ) + { + UWord16 lsb; + tmp = mult_r( input_frame, 410 / 2 ); /* 1/8000 in Q15 */ + Word16 ener_match_fx = hq_nominal_scaling[tmp]; + move16(); + FOR( i = 0; i < input_frame; i++ ) + { + /*t_audio_q[i] *= ener_match; */ + Mpy_32_16_ss( t_audio_fx[i], ener_match_fx, &t_audio_fx[i], &lsb ); /* Q12 */ + move16(); + } + } + + /* limit encoded band-width according to the command-line OR BWD limitation */ + inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ + L_spec = l_spec_tbl[st->bwidth]; /* Q0 */ + + move16(); + move16(); + + + IF( GT_16( input_frame, inner_frame ) ) + { + IF( EQ_16( is_transient, 1 ) ) + { + FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) + { + tmp = shr( inner_frame, 2 ); + Copy32( t_audio_fx + i_mult2( i, shr( input_frame, 2 ) ), t_audio_fx + i_mult2( i, tmp ), tmp ); /* Q_audio */ + } + } + + set32_fx( t_audio_fx + inner_frame, 0, sub( input_frame, inner_frame ) ); + } + } + + + /* subtract signaling bits */ + num_bits = sub( num_bits, hBstr->nb_bits_tot ); /* Q0 */ + + /*-------------------------------------------------------------------------- + * High-band gain control in case of BWS + *--------------------------------------------------------------------------*/ + + IF( st->bwidth_sw_cnt > 0 ) + { + Word32 L_tmp; + tmp = BASOP_Util_Divide1616_Scale( 3, BWS_TRAN_PERIOD, &exp ); /* Q15-exp */ + shr( tmp, exp ); + L_tmp = L_deposit_h( tmp ); /* Q31-exp */ + IF( is_transient ) + { + FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) + { + v_multc_fixed( t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), L_tmp, t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), sub( shr( inner_frame, 2 ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ) ); // Q_audio + Q31 - Q31 -> Q_audio + } + } + ELSE + { + v_multc_fixed( t_audio_fx + L_FRAME16k, L_tmp, t_audio_fx + L_FRAME16k, L_spec - L_FRAME16k ); // Q_audio + Q31 - Q31 -> Q_audio + } + } + + /*-------------------------------------------------------------------------- + * Classify whether to put extra bits for FER mitigation + *--------------------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, HQ_CORE ) ) && GT_32( st->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) ) + { + IF( Voicing_flag > 0 ) + { + push_indice( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); + num_bits = sub( num_bits, 1 ); + } + ELSE + { + push_indice( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); + num_bits = sub( num_bits, 1 ); + } + } + + /*-------------------------------------------------------------------------- + * Transform-domain encoding + *--------------------------------------------------------------------------*/ + + scale_sig32( t_audio_fx, L_FRAME48k_EXT, sub( Q12, Q_audio ) ); + scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q12, Q_audio ) ); + Q_audio = 12; + move16(); + IF( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) + { + + hq_lr_enc_ivas_fx( st, t_audio_fx, inner_frame, &num_bits, is_transient ); + } + ELSE + { + /* HQ high rate encoder */ + hq_hr_enc_ivas_fx( st, t_audio_fx, L_spec, &num_bits, is_transient, vad_hover_flag ); + } + + /* write all unused bits to the bitstream */ + num_bits = add( num_bits, extra_unused ); + + WHILE( GT_16( num_bits, 16 ) ) + { + push_indice( hBstr, IND_UNUSED, 0, 16 ); + num_bits = sub( num_bits, 16 ); + } + + IF( num_bits != 0 ) + { + push_indice( hBstr, IND_UNUSED, 0, num_bits ); + } + + test(); + test(); + IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) + { + overlap = st->hTcxCfg->tcx_mdct_window_length; /* Q0 */ + move16(); + + nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS ); + move16(); + L_frame = sub( st->L_frame + st->hTcxCfg->tcx_offset, st->hTcxCfg->lfacNext ); + tcx_offset = st->hTcxCfg->lfacNext; + move16(); + + set16_fx( Aq_old_fx, 0, M + 1 ); /* Dummy filter */ + Aq_old_fx[0] = 1; + move16(); + + /* Code taken from InternalTCXDecoder() */ + Copy_Scale_sig_32_16( wtda_audio_fx32, wtda_audio_fx16, 2 * L_FRAME48k, negate( Q_audio ) ); // Q0 + TCX_MDCT_Inverse( t_audio_fx, sub( sub( 31, Q_audio ), 15 ), wtda_audio_fx16, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); + + + /* Window current frame */ + Word16 tcx_offset_tmp; + + IF( tcx_offset < 0 ) + { + tcx_offset_tmp = negate( tcx_offset ); + } + ELSE + { + tcx_offset_tmp = 0; + move16(); + } + tcx_windowing_synthesis_current_frame( wtda_audio_fx16, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old_fx, st->hTcxCfg->tcx_mdct_window_trans, shr( st->L_frame, 1 ), tcx_offset_tmp, st->last_core, 0, 0 ); + + + /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ + Copy( wtda_audio_fx16 + sub( L_frame, nz ), st->hTcxEnc->old_out_fx, nz + overlap ); /* Q0 */ + set16_fx( st->hTcxEnc->old_out_fx + add( nz, overlap ), 0, nz ); + + tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out_fx + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); + + FOR( i = 0; i < nz / 2; i++ ) + { + // This implementation is diffrent in float code need to revisit to check its correctness. + st->hTcxEnc->old_out_fx[nz + overlap + i] = mult( wtda_audio_fx16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1_trunc[i].v.re ); // Q0 + Q15 - Q15 -> Q0; + st->hTcxEnc->old_out_fx[nz / 2 + ( nz + overlap + i )] = mult( wtda_audio_fx16[nz / 2 + ( L_frame - 1 - i )], st->hTcxCfg->tcx_aldo_window_1_trunc[nz / 2 - 1 - i].v.im ); // Q0 + Q15 - Q15 -> Q0; + move16(); + move16(); + } + + Copy( wtda_audio_fx16 + sub( shr( overlap, 1 ), tcx_offset ), output_fx, st->L_frame ); /* Q0 */ + } + ELSE + { + Word16 tmp_q = Q_audio; + move16(); + Word32 ener_match_fx = SQRT2_FIXED; + move32(); + FOR( i = 0; i < input_frame; i++ ) + { + t_audio_fx[i] = Mpy_32_32( t_audio_fx[i], ener_match_fx ); /* Q12 - 1 -> Q11 */ + move32(); + } + + Q_audio = sub( Q_audio, 1 ); + scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, tmp_q ) ); /* Q_audio */ + Inverse_Transform( t_audio_fx, &Q_audio, wtda_audio_fx32, is_transient, L_FRAME16k, inner_frame, st->element_mode ); + + + out_q = Q_audio; + move16(); + window_ola_fx( wtda_audio_fx32, output_fx, &out_q, st->hTcxEnc->old_out_fx, &old_q, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); + + Scale_sig( output_fx, L_FRAME16k, negate( out_q ) ); /* Q0 */ + Scale_sig( st->hTcxEnc->old_out_fx, L_FRAME32k, negate( old_q ) ); /* Q0 */ + st->hTcxEnc->Q_old_out = 0; + move16(); + } + + IF( st->element_mode > EVS_MONO ) + { + /* Store LB synthesis in case of switch to ACELP */ + Copy( output_fx, st->hLPDmem->old_exc, L_FRAME16k ); + st->hLPDmem->q_lpd_old_exc = 0; + move16(); + } + pop_wmops(); + + return; +} diff --git a/lib_enc/hq_env_enc.c b/lib_enc/hq_env_enc.c deleted file mode 100644 index e8859676c..000000000 --- a/lib_enc/hq_env_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/hq_hr_enc.c b/lib_enc/hq_hr_enc.c deleted file mode 100644 index 42f661f6e..000000000 --- a/lib_enc/hq_hr_enc.c +++ /dev/null @@ -1,280 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" -#include "prot_fx_enc.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------------------* - * hq_hr_enc() - * - * HQ high rate encoding routine - *--------------------------------------------------------------------------*/ - -void hq_hr_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word32 *t_audio_fx, /* i/o: transform-domain coefficients Q12*/ - const Word16 length, /* i : length of spectrum Q0*/ - Word16 *num_bits, /* i/o: number of available bits Q0*/ - const Word16 is_transient, /* i : transient flag Q0*/ - const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ -) -{ - Word16 nb_sfm; - Word16 sum, hcode_l; - Word16 difidx[NB_SFM]; - Word16 normqlg2[NB_SFM], ynrm[NB_SFM]; - Word16 nf_idx; - Word16 bits; - Word16 LCmode; - Word16 shape_bits, num_sfm, numnrmibits; - Word16 hqswb_clas; - Word16 num_env_bands; - Word16 Npeaks, start_norm; - Word16 difidx_org[NB_SFM]; - Word16 R[NB_SFM]; - Word16 peaks[HVQ_MAX_PEAKS]; - Word16 sfmsize[NB_SFM], sfm_start[NB_SFM], sfm_end[NB_SFM]; - Word16 npulses[NB_SFM], maxpulse[NB_SFM]; - Word16 Rsubband[NB_SFM]; /* Q3 */ - Word32 t_audio_q_fx[L_SPEC48k_EXT]; - Word16 noise_level_fx[HVQ_BWE_NOISE_BANDS]; - Word16 hq_generic_offset; - Word16 hq_generic_exc_clas = 0; - move16(); - Word16 core_sfm; - Word16 har_freq_est1 = 0, har_freq_est2 = 0; - move16(); - move16(); - Word16 flag_dis = 1; - move16(); - const Word16 *subband_search_offset; - Word16 wBands[2]; - Word16 b_delta_env; - HQ_ENC_HANDLE hHQ_core = st->hHQ_core; - BSTR_ENC_HANDLE hBstr = st->hBstr; - Word16 att_fx; - Word16 t_audio_norm[L_FRAME48k_EXT]; - Word16 t_audio_q_norm[L_FRAME48k_EXT]; - Word32 nf_gains_fx[HVQ_NF_GROUPS], pe_gains_fx[HVQ_NF_GROUPS]; - Word16 hq_generic_fenv_fx[HQ_FB_FENV]; - /*------------------------------------------------------------------* - * Initializations - *------------------------------------------------------------------*/ - - Npeaks = 0; - move16(); - set16_fx( npulses, 0, NB_SFM ); - set16_fx( maxpulse, 0, NB_SFM ); - set16_fx( difidx_org, 0, NB_SFM ); - set32_fx( t_audio_q_fx, 0, L_FRAME48k ); - set32_fx( nf_gains_fx, 0, HVQ_NF_GROUPS ); - set32_fx( pe_gains_fx, 0, HVQ_NF_GROUPS ); - /*------------------------------------------------------------------* - * Classification - *------------------------------------------------------------------*/ - bits = hq_classifier_enc_ivas_fx( st, length, t_audio_fx, is_transient, &Npeaks, peaks, pe_gains_fx, nf_gains_fx, &hqswb_clas ); /* Q0 */ - *num_bits = sub( *num_bits, bits ); - move16(); - - /*------------------------------------------------------------------* - * Set quantization parameters - *------------------------------------------------------------------*/ - - hq_configure_fx( length, hqswb_clas, st->core_brate, &num_sfm, &nb_sfm, &start_norm, &num_env_bands, &numnrmibits, &hq_generic_offset, sfmsize, sfm_start, sfm_end ); - - /*------------------------------------------------------------------* - * Transient frame handling - *------------------------------------------------------------------*/ - /* Interleave MLT coefficients of 4 sub-vectors in case of transient frame */ - IF( is_transient ) - { - interleave_spectrum_ivas_fx( t_audio_fx, length ); - } - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); - v_multc_att32( t_audio_fx, att_fx, t_audio_fx, sfm_end[( num_sfm - 1 )] ); /* Q12 */ - } - - /*------------------------------------------------------------------* - * Scalar quantization of norms - * Encode norm indices - *------------------------------------------------------------------*/ - - /* calculate and quantize norms */ - calc_norm_ivas_fx( t_audio_fx, ynrm, normqlg2, start_norm, num_env_bands, sfmsize, sfm_start ); - /* create differential code of quantized norm indices */ - diff_envelope_coding_fx( is_transient, num_env_bands, start_norm, ynrm, normqlg2, difidx ); - - /* Find norm coding mode and calculate number of bits */ - hcode_l = encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 0, NORMAL_HQ_CORE, is_transient ); /* Q0 */ - - *num_bits = sub( *num_bits, add( hcode_l, NORM0_BITS + FLAGS_BITS ) ); - move16(); - /* Encode norm indices */ - encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 1, NORMAL_HQ_CORE, is_transient ); - - /*------------------------------------------------------------------* - * HQ GENERIC BWE encoding - *------------------------------------------------------------------*/ - - test(); - IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) - { - hq_generic_hf_encoding_fx( t_audio_fx, hq_generic_fenv_fx, hq_generic_offset, st, &hq_generic_exc_clas, length ); - - IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_SP_EXC ) ) - { - *num_bits = add( *num_bits, 1 ); /* conditional 1 bit saving for representing FD3 BWE excitation class */ - move16(); - } - map_hq_generic_fenv_norm_fx( hqswb_clas, hq_generic_fenv_fx, ynrm, normqlg2, num_env_bands, nb_sfm, hq_generic_offset ); - } - - /*------------------------------------------------------------------* - * Bit allocation - *------------------------------------------------------------------*/ - - ivas_hq_bit_allocation_fx( st->core_brate, length, hqswb_clas, num_bits, normqlg2, nb_sfm, sfmsize, noise_level_fx, R, Rsubband, &sum, &core_sfm, num_env_bands ); - - /*------------------------------------------------------------------* - * Normalize coefficients with quantized norms - *------------------------------------------------------------------*/ - IF( NE_16( hqswb_clas, HQ_HVQ ) ) - { - test(); - IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) - { - b_delta_env = calc_nor_delta_hf_ivas_fx( hBstr, t_audio_fx, ynrm, Rsubband, num_env_bands, nb_sfm, sfmsize, sfm_start, core_sfm ); /* Q0 */ - sum = sub( sum, b_delta_env ); - } - normalizecoefs_fx( t_audio_fx, ynrm, nb_sfm, sfm_start, sfm_end, t_audio_norm ); - } - Word16 Q_audio = 12, Q_shift; - move16(); - /*------------------------------------------------------------------* - * Quantize/code spectral fine structure using PVQ or HVQ - *------------------------------------------------------------------*/ - IF( EQ_16( hqswb_clas, HQ_HVQ ) ) - { - sum = hvq_enc_ivas_fx( st, st->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains_fx, noise_level_fx, pe_gains_fx, t_audio_fx, t_audio_q_fx ); - *num_bits = sub( *num_bits, sum ); - move16(); - } - ELSE - { - shape_bits = pvq_core_enc_ivas_fx( hBstr, t_audio_norm, t_audio_q_norm, &Q_audio, sum, nb_sfm, sfm_start, sfm_end, sfmsize, Rsubband, R, npulses, maxpulse, HQ_CORE ); /* Q0 */ - *num_bits = add( *num_bits, sub( sum, shape_bits ) ); - move16(); - } - - test(); - IF( EQ_16( hqswb_clas, HQ_HVQ ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) - { - subband_search_offset = subband_search_offsets_13p2kbps_Har; /* Q0 */ - wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; /* Q0 */ - wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; /* Q0 */ - move16(); - move16(); - IF( EQ_16( hqswb_clas, HQ_HARMONIC ) ) - { - Q_shift = sub( SWB_BWE_LR_Qs, Q_audio ); - FOR( Word16 i = 0; i < 300; i++ ) - { - t_audio_q_fx[i] = L_shl( L_deposit_l( t_audio_q_norm[i] ), Q_shift ); /* Q12 */ - move32(); - } - } - har_est_fx( t_audio_q_fx, 300, &har_freq_est1, &har_freq_est2, &flag_dis, &hHQ_core->prev_frm_hfe2, subband_search_offset, wBands, &hHQ_core->prev_stab_hfe2 ); - - hHQ_core->prev_frm_hfe2 = har_freq_est2; - move16(); - } - - /* reset LR-HQ memories */ - hHQ_core->prev_frm_hfe2 = 0; /*reset*/ - hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - nf_idx = 0; - move16(); - test(); - test(); - test(); - IF( NE_16( is_transient, 1 ) && NE_16( hqswb_clas, HQ_HVQ ) && !( EQ_16( length, L_FRAME16k ) && LE_32( st->core_brate, HQ_32k ) ) ) - { - test(); - IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) - { - nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); /* Q0 */ - push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); - } - ELSE - { - nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); /* Q0 */ - push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); - } - } - - - /* updates */ - hHQ_core->prev_hqswb_clas = hqswb_clas; /* Q0 */ - move16(); - /* Prepare synthesis for LB generation in case of switch to ACELP */ - IF( NE_16( hqswb_clas, HQ_HVQ ) ) - { - apply_envelope_enc_ivas_fx( t_audio_q_norm, ynrm, num_sfm, sfm_start, sfm_end, t_audio_q_fx ); - scale_sig32( t_audio_q_fx, length, sub( Q12, Q_audio ) ); // Q12 - } - - IF( is_transient ) - { - ivas_de_interleave_spectrum_fx( t_audio_q_fx, length ); - } - - MVR2R_WORD32( t_audio_q_fx, t_audio_fx, length ); - - return; -} diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index f73a926dc..4d4742cc1 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -5,9 +5,11 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ //#include "prot_fx.h" /* Function prototypes */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ /*--------------------------------------------------------------------------* * hq_hr_enc_fx() @@ -264,3 +266,231 @@ void hq_hr_enc_fx( return; } + +void hq_hr_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word32 *t_audio_fx, /* i/o: transform-domain coefficients Q12*/ + const Word16 length, /* i : length of spectrum Q0*/ + Word16 *num_bits, /* i/o: number of available bits Q0*/ + const Word16 is_transient, /* i : transient flag Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ +) +{ + Word16 nb_sfm; + Word16 sum, hcode_l; + Word16 difidx[NB_SFM]; + Word16 normqlg2[NB_SFM], ynrm[NB_SFM]; + Word16 nf_idx; + Word16 bits; + Word16 LCmode; + Word16 shape_bits, num_sfm, numnrmibits; + Word16 hqswb_clas; + Word16 num_env_bands; + Word16 Npeaks, start_norm; + Word16 difidx_org[NB_SFM]; + Word16 R[NB_SFM]; + Word16 peaks[HVQ_MAX_PEAKS]; + Word16 sfmsize[NB_SFM], sfm_start[NB_SFM], sfm_end[NB_SFM]; + Word16 npulses[NB_SFM], maxpulse[NB_SFM]; + Word16 Rsubband[NB_SFM]; /* Q3 */ + Word32 t_audio_q_fx[L_SPEC48k_EXT]; + Word16 noise_level_fx[HVQ_BWE_NOISE_BANDS]; + Word16 hq_generic_offset; + Word16 hq_generic_exc_clas = 0; + move16(); + Word16 core_sfm; + Word16 har_freq_est1 = 0, har_freq_est2 = 0; + move16(); + move16(); + Word16 flag_dis = 1; + move16(); + const Word16 *subband_search_offset; + Word16 wBands[2]; + Word16 b_delta_env; + HQ_ENC_HANDLE hHQ_core = st->hHQ_core; + BSTR_ENC_HANDLE hBstr = st->hBstr; + Word16 att_fx; + Word16 t_audio_norm[L_FRAME48k_EXT]; + Word16 t_audio_q_norm[L_FRAME48k_EXT]; + Word32 nf_gains_fx[HVQ_NF_GROUPS], pe_gains_fx[HVQ_NF_GROUPS]; + Word16 hq_generic_fenv_fx[HQ_FB_FENV]; + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + Npeaks = 0; + move16(); + set16_fx( npulses, 0, NB_SFM ); + set16_fx( maxpulse, 0, NB_SFM ); + set16_fx( difidx_org, 0, NB_SFM ); + set32_fx( t_audio_q_fx, 0, L_FRAME48k ); + set32_fx( nf_gains_fx, 0, HVQ_NF_GROUPS ); + set32_fx( pe_gains_fx, 0, HVQ_NF_GROUPS ); + /*------------------------------------------------------------------* + * Classification + *------------------------------------------------------------------*/ + bits = hq_classifier_enc_ivas_fx( st, length, t_audio_fx, is_transient, &Npeaks, peaks, pe_gains_fx, nf_gains_fx, &hqswb_clas ); /* Q0 */ + *num_bits = sub( *num_bits, bits ); + move16(); + + /*------------------------------------------------------------------* + * Set quantization parameters + *------------------------------------------------------------------*/ + + hq_configure_fx( length, hqswb_clas, st->core_brate, &num_sfm, &nb_sfm, &start_norm, &num_env_bands, &numnrmibits, &hq_generic_offset, sfmsize, sfm_start, sfm_end ); + + /*------------------------------------------------------------------* + * Transient frame handling + *------------------------------------------------------------------*/ + /* Interleave MLT coefficients of 4 sub-vectors in case of transient frame */ + IF( is_transient ) + { + interleave_spectrum_ivas_fx( t_audio_fx, length ); + } + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); + v_multc_att32( t_audio_fx, att_fx, t_audio_fx, sfm_end[( num_sfm - 1 )] ); /* Q12 */ + } + + /*------------------------------------------------------------------* + * Scalar quantization of norms + * Encode norm indices + *------------------------------------------------------------------*/ + + /* calculate and quantize norms */ + calc_norm_ivas_fx( t_audio_fx, ynrm, normqlg2, start_norm, num_env_bands, sfmsize, sfm_start ); + /* create differential code of quantized norm indices */ + diff_envelope_coding_fx( is_transient, num_env_bands, start_norm, ynrm, normqlg2, difidx ); + + /* Find norm coding mode and calculate number of bits */ + hcode_l = encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 0, NORMAL_HQ_CORE, is_transient ); /* Q0 */ + + *num_bits = sub( *num_bits, add( hcode_l, NORM0_BITS + FLAGS_BITS ) ); + move16(); + /* Encode norm indices */ + encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 1, NORMAL_HQ_CORE, is_transient ); + + /*------------------------------------------------------------------* + * HQ GENERIC BWE encoding + *------------------------------------------------------------------*/ + + test(); + IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) + { + hq_generic_hf_encoding_fx( t_audio_fx, hq_generic_fenv_fx, hq_generic_offset, st, &hq_generic_exc_clas, length ); + + IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_SP_EXC ) ) + { + *num_bits = add( *num_bits, 1 ); /* conditional 1 bit saving for representing FD3 BWE excitation class */ + move16(); + } + map_hq_generic_fenv_norm_fx( hqswb_clas, hq_generic_fenv_fx, ynrm, normqlg2, num_env_bands, nb_sfm, hq_generic_offset ); + } + + /*------------------------------------------------------------------* + * Bit allocation + *------------------------------------------------------------------*/ + + ivas_hq_bit_allocation_fx( st->core_brate, length, hqswb_clas, num_bits, normqlg2, nb_sfm, sfmsize, noise_level_fx, R, Rsubband, &sum, &core_sfm, num_env_bands ); + + /*------------------------------------------------------------------* + * Normalize coefficients with quantized norms + *------------------------------------------------------------------*/ + IF( NE_16( hqswb_clas, HQ_HVQ ) ) + { + test(); + IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) + { + b_delta_env = calc_nor_delta_hf_ivas_fx( hBstr, t_audio_fx, ynrm, Rsubband, num_env_bands, nb_sfm, sfmsize, sfm_start, core_sfm ); /* Q0 */ + sum = sub( sum, b_delta_env ); + } + normalizecoefs_fx( t_audio_fx, ynrm, nb_sfm, sfm_start, sfm_end, t_audio_norm ); + } + Word16 Q_audio = 12, Q_shift; + move16(); + /*------------------------------------------------------------------* + * Quantize/code spectral fine structure using PVQ or HVQ + *------------------------------------------------------------------*/ + IF( EQ_16( hqswb_clas, HQ_HVQ ) ) + { + sum = hvq_enc_ivas_fx( st, st->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains_fx, noise_level_fx, pe_gains_fx, t_audio_fx, t_audio_q_fx ); + *num_bits = sub( *num_bits, sum ); + move16(); + } + ELSE + { + shape_bits = pvq_core_enc_ivas_fx( hBstr, t_audio_norm, t_audio_q_norm, &Q_audio, sum, nb_sfm, sfm_start, sfm_end, sfmsize, Rsubband, R, npulses, maxpulse, HQ_CORE ); /* Q0 */ + *num_bits = add( *num_bits, sub( sum, shape_bits ) ); + move16(); + } + + test(); + IF( EQ_16( hqswb_clas, HQ_HVQ ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) + { + subband_search_offset = subband_search_offsets_13p2kbps_Har; /* Q0 */ + wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; /* Q0 */ + wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; /* Q0 */ + move16(); + move16(); + IF( EQ_16( hqswb_clas, HQ_HARMONIC ) ) + { + Q_shift = sub( SWB_BWE_LR_Qs, Q_audio ); + FOR( Word16 i = 0; i < 300; i++ ) + { + t_audio_q_fx[i] = L_shl( L_deposit_l( t_audio_q_norm[i] ), Q_shift ); /* Q12 */ + move32(); + } + } + har_est_fx( t_audio_q_fx, 300, &har_freq_est1, &har_freq_est2, &flag_dis, &hHQ_core->prev_frm_hfe2, subband_search_offset, wBands, &hHQ_core->prev_stab_hfe2 ); + + hHQ_core->prev_frm_hfe2 = har_freq_est2; + move16(); + } + + /* reset LR-HQ memories */ + hHQ_core->prev_frm_hfe2 = 0; /*reset*/ + hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + nf_idx = 0; + move16(); + test(); + test(); + test(); + IF( NE_16( is_transient, 1 ) && NE_16( hqswb_clas, HQ_HVQ ) && !( EQ_16( length, L_FRAME16k ) && LE_32( st->core_brate, HQ_32k ) ) ) + { + test(); + IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) + { + nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); /* Q0 */ + push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); + } + ELSE + { + nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); /* Q0 */ + push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); + } + } + + + /* updates */ + hHQ_core->prev_hqswb_clas = hqswb_clas; /* Q0 */ + move16(); + /* Prepare synthesis for LB generation in case of switch to ACELP */ + IF( NE_16( hqswb_clas, HQ_HVQ ) ) + { + apply_envelope_enc_ivas_fx( t_audio_q_norm, ynrm, num_sfm, sfm_start, sfm_end, t_audio_q_fx ); + scale_sig32( t_audio_q_fx, length, sub( Q12, Q_audio ) ); // Q12 + } + + IF( is_transient ) + { + ivas_de_interleave_spectrum_fx( t_audio_q_fx, length ); + } + + MVR2R_WORD32( t_audio_q_fx, t_audio_fx, length ); + + return; +} diff --git a/lib_enc/hq_lr_enc.c b/lib_enc/hq_lr_enc.c deleted file mode 100644 index d0941db74..000000000 --- a/lib_enc/hq_lr_enc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "stl.h" -#include "basop_util.h" -#include "wmc_auto.h" diff --git a/lib_enc/hvq_enc.c b/lib_enc/hvq_enc.c deleted file mode 100644 index adf7751a1..000000000 --- a/lib_enc/hvq_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c deleted file mode 100644 index 1d4964ab8..000000000 --- a/lib_enc/init_enc.c +++ /dev/null @@ -1,1215 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" -#include "ivas_prot_fx.h" -#include "prot_fx_enc.h" -ivas_error init_encoder_ivas_fx( - Encoder_State *st, /* i/o: state structure */ - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - const Word16 idchan, /* i : channel ID */ - const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ - const Word16 interval_SID, /* i : interval for SID update */ - const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const Word32 element_brate /* i : element bitrate */ -) -{ - Word16 i; - ivas_error error; - Word32 igf_brate; - - error = IVAS_ERR_OK; - move32(); - - /*-----------------------------------------------------------------* - * General parameters - *-----------------------------------------------------------------*/ - - IF( st->Opt_AMR_WB ) - { - st->last_core = AMR_WB_CORE; - } - ELSE - { - st->last_core = -1; - } - move16(); - - st->L_frame = L_FRAME; - move16(); - st->last_coder_type = GENERIC; - move16(); - st->coder_type = GENERIC; - move16(); - st->last_total_brate = st->total_brate; - move32(); - st->last_bits_frame_nominal = -1; - move16(); - st->last_total_brate_cng = -1; - move16(); - st->last_core_brate = st->total_brate; - move32(); - st->dtx_sce_sba = 0; - move16(); - st->extl = -1; - move16(); - st->last_extl = -1; - move16(); - st->last_L_frame = L_FRAME; - move16(); - st->rate_switching_reset = 0; - move16(); - st->rate_switching_reset_16kHz = 0; - move16(); - st->clas = UNVOICED_CLAS; - move16(); - st->low_rate_mode = 0; - move16(); - st->ini_frame = 0; - move16(); - st->inactive_coder_type_flag = 0; - move16(); - st->sba_br_sw_while_no_data = 0; - move16(); - - st->coder_type_raw = VOICED; - move16(); - st->last_coder_type_raw = st->coder_type_raw; - move16(); - - st->flag_ACELP16k = set_ACELP_flag_IVAS( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); - move16(); - - st->is_ism_format = 0; - move16(); - - IF( NE_16( ism_mode, ISM_MODE_NONE ) ) - { - st->is_ism_format = 1; - move16(); - } - - /*-----------------------------------------------------------------* - * Bitstream - *-----------------------------------------------------------------*/ - - IF( !vad_only_flag ) - { - IF( ( st->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); - } - - /* set pointer to the buffer of indices */ - st->hBstr->ind_list = st_ivas->ind_list; - st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; - st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; - st->hBstr->nb_ind_tot = 0; - move16(); - st->hBstr->nb_bits_tot = 0; - move16(); - st->hBstr->st_ivas = st_ivas; - } - ELSE - { - st->hBstr = NULL; - } - - /*-----------------------------------------------------------------* - * Pre-processing and ACELP core parameters - *-----------------------------------------------------------------*/ - - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - Copy( GEWB_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( GEWB_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( GEWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); - - st->next_force_safety_net = 0; - move16(); - - st->pstreaklen = 0; - move16(); - st->streaklimit_fx = MAX_WORD16; - move16(); - set16_fx( st->mem_MA_fx, 0, M ); - - init_gp_clip_fx( st->clip_var_fx ); - pitch_ol_init_fx( &st->old_thres_fx, &st->old_pitch, &st->delta_pit, &st->old_corr_fx ); - set16_fx( st->old_wsp_fx, 0, L_WSP_MEM ); - st->exp_old_wsp = 0; - move16(); - set16_fx( st->old_wsp2_fx, 0, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); // Needs to change depending on usage. - st->Q_old_wsp2 = 0; - move16(); - - st->mem_preemph_fx = 0; - move16(); - st->mem_preemph16k_fx = 0; - move16(); - st->mem_preemph_enc = 0; - move16(); - st->exp_mem_preemph_enc = 0; - move16(); - -#if 1 // TODO: Float Initializations. To be removed later - st->active_cnt = 0; - move16(); -#endif - - st->pst_mem_deemp_err_fx = 0; - move16(); - st->pst_lp_ener_fx = 0; - move16(); - - /* AVQ pre-quantizer memory */ - st->mem_preemp_preQ_fx = 0; - move16(); - st->mem_deemp_preQ_fx = 0; - move16(); - st->last_nq_preQ = 0; - move16(); - st->last_code_preq = 0; - move16(); - st->use_acelp_preq = 0; - move16(); - st->last_harm_flag_acelp = 0; - move16(); - - /* (Decimated) Weighted Speech Memory */ - st->mem_wsp_enc = 0; - move16(); - st->mem_wsp_fx = 0; - move16(); - st->mem_wsp_q = 0; - move16(); - set16_fx( st->mem_decim2_fx, 0, 3 ); - set32_fx( st->Bin_E_fx, 0, L_FFT ); - st->q_Bin_E = Q31; - move16(); - st->ee_old_fx = 640; /* 10.0f in Q6 */ - move16(); - st->Nb_ACELP_frames = 0; - move16(); - st->audio_frame_cnt = AUDIO_COUNTER_INI; /* Initialization of the audio frame counter mildly into the audio mode */ - move16(); - - /* adaptive lag window memory */ - st->old_pitch_la = 0; - move16(); - - st->prev_Q_new = 0; - move16(); - - IF( EQ_32( st->input_Fs, 8000 ) ) - { - st->min_band = 1; - move16(); - st->max_band = 16; - move16(); - } - ELSE - { - st->min_band = 0; - move16(); - st->max_band = 19; - move16(); - } - - IF( st->Opt_AMR_WB ) - { - Copy( mean_isf_amr_wb_fx, st->lsf_old_fx, M ); - E_LPC_isf_isp_conversion( st->lsf_old_fx, st->lsp_old1_fx, M ); - } - ELSE - { - Copy( GEWB_Ave_fx, st->lsf_old_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old1_fx, M, INT_FS_12k8 ); - } - - Copy( st->lsf_old_fx, st->lsf_old1_fx, M ); - Copy( st->lsp_old1_fx, st->lsp_old_fx, M ); - Copy( st->lsp_old_fx, st->lsp_old16k_fx, M ); - Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); - - st->stab_fac_fx = 0; - move16(); - - /* Bass post-filter memories - encoder side of MODE2 */ - st->bpf_off = 0; - move16(); - st->pst_mem_deemp_err_fx = 0; - move16(); - st->pst_lp_ener_fx = 0; - move16(); - - /* TC coder type */ - st->tc_cnt = 0; - move16(); - - /* find_uv() parameters */ - st->old_dE1_fx = 0; - move16(); - st->old_ind_deltaMax = 0; - move16(); - set32_fx( st->old_enr_ssf_fx, 0, shl( NB_SSF, 1 ) ); - st->spike_hyst = -1; - move16(); - - /* stereo switching memories */ - st->mem_preemph_DFT_fx = 0; - move16(); - set16_fx( st->inp_12k8_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_12k8, L_MEM_RECALC_12K8 ), L_FILT ) ); - st->mem_preemph16k_DFT_fx = 0; - move16(); - set16_fx( st->inp_16k_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_16k, L_MEM_RECALC_16K ), L_FILT16k ) ); - - st->sharpFlag = 0; - move16(); - - /* Stationary noise UV modification */ - st->ge_sm_fx = L_deposit_l( 640 ); /*Q(GE_SHIFT)*/ - move16(); - st->uv_count = 0; - move16(); - st->act_count = 3; - move16(); - Copy( st->lsp_old_fx, st->lspold_s_fx, M ); - st->noimix_seed = RANDOM_INITSEED; - move16(); - st->min_alpha_fx = 32767; - move16(); - st->exc_pe_fx = 0; - move16(); - st->Q_stat_noise = 15; - move16(); - /* FEC */ - st->last_clas = UNVOICED_CLAS; - move16(); - st->prev_fmerit = 0; - move16(); - st->fmerit_dt = 0; - move16(); - st->Last_pulse_pos = 0; - move16(); - - FOR( i = 0; i < shl( NB_SUBFR16k, 1 ); i++ ) - { - st->old_pitch_buf_fx[i] = L_SUBFR_Q6; - move16(); - } - - /* mode1 core switching */ - st->old_Es_pred_fx = 0; - move16(); - set16_fx( st->old_Aq_12_8_fx + 1, 0, M ); - st->old_Aq_12_8_fx[0] = ONE_IN_Q12; - move16(); - - /* stable short pitch detection */ - st->voicing0_sm_fx = 0; - move16(); - st->voicing_sm_fx = 0; - move16(); - st->LF_EnergyRatio_sm_fx = 1; - move16(); - st->predecision_flag = 0; - move16(); - st->diff_sm_fx = 0; - move32(); - st->energy_sm_fx = 0; - move32(); - - set16_fx( st->pitch, L_SUBFR, 3 ); - set16_fx( st->voicing_fx, 0, 3 ); - - /*-----------------------------------------------------------------* - * General signal buffers - *-----------------------------------------------------------------*/ - - IF( !vad_only_flag ) - { - IF( ( st->hSignalBuf = (SIGNAL_BUFFERS_ENC_HANDLE) malloc( sizeof( SIGNAL_BUFFERS_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Signal buffers\n" ) ); - } - - st->Bin_E_old_fx = st->hSignalBuf->Bin_E_old_fx; - st->mem_decim_fx = st->hSignalBuf->mem_decim_fx; - st->mem_decim16k_fx = st->hSignalBuf->mem_decim16k_fx; - st->old_inp_12k8_fx = st->hSignalBuf->old_inp_12k8_fx; - st->old_inp_16k_fx = st->hSignalBuf->old_inp_16k_fx; - st->buf_speech_enc_pe = st->hSignalBuf->buf_speech_enc_pe; - st->buf_synth = st->hSignalBuf->buf_synth; - st->buf_speech_enc = st->hSignalBuf->buf_speech_enc; - st->buf_wspeech_enc = st->hSignalBuf->buf_wspeech_enc; - - set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); - st->q_Bin_E_old = Q31; - move16(); - set16_fx( st->hSignalBuf->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - st->exp_buf_speech_enc = 0; - move16(); - set16_fx( st->hSignalBuf->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); - st->exp_buf_wspeech_enc = 0; - move16(); - /* initializations */ -#ifndef MSAN_FIX - set32_fx( st->Bin_E_old_fx, 0, shr( L_FFT, 2 ) ); -#else - set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); -#endif - st->q_Bin_E_old = Q31; - move16(); - set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); - set16_fx( st->mem_decim16k_fx, 0, shl( L_FILT_MAX, 1 ) ); - set16_fx( st->old_inp_12k8_fx, 0, L_INP_MEM ); - set16_fx( st->old_inp_16k_fx, 0, L_INP_MEM ); - st->exp_old_inp_16k = 0; - st->exp_old_inp_12k8 = 0; - move16(); - move16(); - - st->input_buff_fx = st->hSignalBuf->input_buff; - st->input_buff32_fx = st->hSignalBuf->input_buff32; - set16_fx( st->input_buff_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); - st->q_inp = Q15; - move16(); - st->q_old_inp = Q15; - move16(); - set32_fx( st->input_buff32_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); - st->q_inp32 = Q31; - move16(); - st->old_input_signal_fx = st->input_buff_fx; - /* st->input_Fs / FRAMES_PER_SEC */ - Word16 frame_length = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); - - IF( st->element_mode == EVS_MONO ) - { - st->input32_fx = st->input_buff32_fx + st->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); - st->input_fx = st->input_buff_fx + add( frame_length, (Word16) NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ) ); - } - ELSE - { - st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC - st->input_fx = st->input_buff_fx + frame_length; - } -#if 1 // TODO: To be removed later -#endif - } - ELSE - { - st->hSignalBuf = NULL; - st->Bin_E_old_fx = NULL; - st->mem_decim_fx = NULL; - st->mem_decim16k_fx = NULL; - st->old_inp_12k8_fx = NULL; - st->old_inp_16k_fx = NULL; - st->buf_speech_enc_pe = NULL; - st->buf_synth = NULL; - st->buf_speech_enc = NULL; - st->buf_wspeech_enc = NULL; - st->input_buff_fx = NULL; -#if 1 -#endif - } - - /*-----------------------------------------------------------------* - * Noise estimator - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) - { - IF( ( st->hNoiseEst = (NOISE_EST_HANDLE) malloc( sizeof( NOISE_EST_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ); - } - - noise_est_init_ivas_fx( st->hNoiseEst ); - } - ELSE - { - st->hNoiseEst = NULL; - } - - /*-----------------------------------------------------------------* - * VAD - *-----------------------------------------------------------------*/ - - st->vad_flag = 1; - move16(); - st->localVAD = 0; - move16(); - - IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) && ( !vad_only_flag ) ) - { - IF( ( st->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); - } - - wb_vad_init_ivas_fx( st->hVAD ); - } - ELSE - { - st->hVAD = NULL; - } - st->Pos_relE_cnt = 20; - move16(); - - /* CLDFB-based VAD */ - IF( st->element_mode == EVS_MONO ) - { - /* This is done to as in EVS T_CldfbVadState structure is present in Encoder State */ - /* - if ( ( st->hVAD_CLDFB = (VAD_CLDFB_HANDLE) malloc( sizeof( T_CldfbVadState ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB VAD\n" ) ); - } - */ - st->hVAD_CLDFB = &st->vad_st; - - vad_init_fx( st->hVAD_CLDFB ); - } - ELSE - { - st->hVAD_CLDFB = NULL; - } - - /*-----------------------------------------------------------------* - * Speech/music classifier - *-----------------------------------------------------------------*/ - - IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) - { - IF( ( st->hSpMusClas = (SP_MUS_CLAS_HANDLE) malloc( sizeof( SP_MUS_CLAS_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Speech/music classifier\n" ) ); - } - - speech_music_clas_init_ivas_fx( st->hSpMusClas ); - st->sp_aud_decision0 = 0; - move16(); - st->sp_aud_decision1 = 0; - move16(); - st->sp_aud_decision2 = 0; - move16(); - } - ELSE - { - st->hSpMusClas = NULL; - } - - - /*-----------------------------------------------------------------* - * WB, SWB and FB bandwidth detector - *-----------------------------------------------------------------*/ - - st->lt_mean_NB_fx = 0; - move16(); - st->lt_mean_WB_fx = 0; - move16(); - st->lt_mean_SWB_fx = 0; - move16(); - st->count_WB = BWD_COUNT_MAX; - move16(); - st->count_SWB = BWD_COUNT_MAX; - move16(); - st->count_FB = BWD_COUNT_MAX; - move16(); - st->bwidth = st->max_bwidth; - move16(); - st->last_input_bwidth = st->bwidth; - move16(); - st->last_bwidth = st->bwidth; - move16(); - st->last_bwidth_cng = st->bwidth; - move16(); - st->bwidth_sw_cnt = 0; - move16(); - - - /*-----------------------------------------------------------------* - * DTX - *-----------------------------------------------------------------*/ - - st->lp_speech_fx = 11520; /*Q8 (45.0) */ /* Initialize the long-term active speech level in dB */ - move16(); - st->lp_noise_fx = 0; - move16(); - st->flag_noisy_speech_snr = 0; - move16(); - st->fd_cng_reset_flag = 0; - move16(); - st->cng_type = -1; - move16(); - st->bckr_tilt_lt = 0; - move16(); - st->active_cnt = 0; - move16(); - - test(); - test(); - test(); - test(); - IF( ( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) - { - IF( ( st->hDtxEnc = (DTX_ENC_HANDLE) malloc( sizeof( DTX_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX variables\n" ) ); - } - dtx_enc_init_fx( st, var_SID_rate_flag, interval_SID ); - } - ELSE - { - st->hDtxEnc = NULL; - } - - /*-----------------------------------------------------------------* - * No other handles needed to be allocated for front-VAD structure - *-----------------------------------------------------------------*/ - - IF( vad_only_flag ) - { - st->hTdCngEnc = NULL; - st->cldfbAnaEnc = NULL; - st->hFdCngEnc = NULL; - st->hSC_VBR = NULL; - st->hAmrwb_IO = NULL; - st->hLPDmem = NULL; - st->hGSCEnc = NULL; - st->hBWE_TD = NULL; - st->cldfbSynTd = NULL; - st->hBWE_FD = NULL; - st->hHQ_core = NULL; - st->hRF = NULL; - st->hTECEnc = NULL; - st->hTcxEnc = NULL; - st->hTcxCfg = NULL; - st->hIGFEnc = NULL; - st->hPlcExt = NULL; - st->hTranDet = NULL; - - st->element_mode = IVAS_SCE; - move16(); - st->idchan = 100; /* indicates hCoreCoderVAD */ - move16(); - st->core = -1; - move16(); - st->rf_mode = 0; - move16(); - - return error; - } - - /*-----------------------------------------------------------------* - * LP-CNG - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - test(); - IF( ( ( idchan == 0 && st->Opt_DTX_ON && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || st->element_mode == EVS_MONO ) && !( EQ_16( ism_mode, ISM_MODE_PARAM ) || EQ_16( ism_mode, ISM_MODE_DISC ) ) ) - { - IF( ( st->hTdCngEnc = (TD_CNG_ENC_HANDLE) malloc( sizeof( TD_CNG_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); - } - - td_cng_enc_init_ivas_fx( st->hTdCngEnc, st->Opt_DTX_ON, st->max_bwidth ); - } - ELSE - { - st->hTdCngEnc = NULL; - } - - /*-----------------------------------------------------------------* - * CLDFB & resampling tools parameters - *-----------------------------------------------------------------*/ - test(); - test(); - test(); - IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) - { - IF( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - ELSE - { - st->cldfbAnaEnc = NULL; - } - - st->energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ - move32(); - st->sf_energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ - move16(); - - /*-----------------------------------------------------------------* - * SC-VBR parameters - *-----------------------------------------------------------------*/ - - test(); - IF( st->Opt_SC_VBR || st->element_mode == EVS_MONO ) - { - IF( ( st->hSC_VBR = (SC_VBR_ENC_HANDLE) malloc( sizeof( SC_VBR_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SC-VBR\n" ) ); - } - - sc_vbr_enc_init_fx( st->hSC_VBR ); - } - ELSE - { - st->hSC_VBR = NULL; - } - - st->last_Opt_SC_VBR = 0; - move16(); - - - /*-----------------------------------------------------------------* - * AMR-WB IO initialization - *-----------------------------------------------------------------*/ - - test(); - IF( st->Opt_AMR_WB || st->element_mode == EVS_MONO ) - { - IF( ( st->hAmrwb_IO = (AMRWB_IO_ENC_HANDLE) malloc( sizeof( AMRWB_IO_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AMR-WB IO\n" ) ); - } - - amr_wb_enc_init_fx( st->hAmrwb_IO ); - } - ELSE - { - st->hAmrwb_IO = NULL; - } - - /*-----------------------------------------------------------------* - * ACELP LPDmem - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - IF( ( st->hLPDmem = (LPD_state_HANDLE) malloc( sizeof( LPD_state ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LPDmem\n" ) ); - } - - LPDmem_enc_init_ivas_fx( st->hLPDmem ); - } - ELSE - { - st->hLPDmem = NULL; - } - - /*-----------------------------------------------------------------* - * parameters for AC coder type (GSC) - *-----------------------------------------------------------------*/ - - st->GSC_noisy_speech = 0; - move16(); - st->GSC_IVAS_mode = 0; - move16(); - - test(); - test(); - IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - IF( ( st->hGSCEnc = (GSC_ENC_HANDLE) malloc( sizeof( GSC_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n" ) ); - } - - GSC_enc_init_fx( st->hGSCEnc ); - } - ELSE - { - st->hGSCEnc = NULL; - } - - /*-----------------------------------------------------------------* - * TBE parameters - *-----------------------------------------------------------------*/ - - test(); - IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - IF( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); - } - - IF( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) - { - return error; - } - - InitSWBencBuffer_ivas_fx( st ); - ResetSHBbuffer_Enc_fx( st ); - } - ELSE - { - st->hBWE_TD = NULL; - st->cldfbSynTd = NULL; - } - - /*-----------------------------------------------------------------* - * SWB BWE parameters - *-----------------------------------------------------------------*/ - - test(); - IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - IF( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); - } - - fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX - st->Q_old_wtda = 0; - move16(); -#endif - } - ELSE - { - st->hBWE_FD = NULL; - } - - /*-----------------------------------------------------------------* - * HQ core parameters - *-----------------------------------------------------------------*/ - - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) - { - IF( ( st->hHQ_core = (HQ_ENC_HANDLE) malloc( sizeof( HQ_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ core\n" ) ); - } - - HQ_core_enc_init_fx( st->hHQ_core ); - } - ELSE - { - st->hHQ_core = NULL; - } - - /* init memory for detect_transient(), used by HQ core and swb_bwe_enc */ - st->old_hpfilt_in_fx = 0; - move16(); - st->old_hpfilt_out_fx = 0; - move16(); - st->EnergyLT_fx = 0; - move32(); - st->Energy_Old_fx = 0; - move32(); - st->TransientHangOver = 0; - move16(); - st->EnergyLT_fx_exp = 30; - move16(); - st->last_enerBuffer_exp = 0; - move16(); - - /*-----------------------------------------------------------------* - * Channel-aware mode - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( !st->Opt_RF_ON || ( NE_16( st->bwidth, WB ) && NE_16( st->bwidth, SWB ) ) || NE_32( st->total_brate, ACELP_13k20 ) ) - { - st->rf_mode = 0; - move16(); - } - ELSE - { - st->rf_mode = st->Opt_RF_ON; - move16(); - } - - st->rf_mode_last = st->rf_mode; - move16(); - - test(); - IF( st->Opt_RF_ON || st->element_mode == EVS_MONO ) - { - IF( ( st->hRF = (RF_ENC_HANDLE) malloc( sizeof( RF_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for RF\n" ) ); - } - - /* initialize RF indice buffers */ - reset_rf_indices_fx( st ); - } - ELSE - { - st->hRF = NULL; - } - - /*-----------------------------------------------------------------* - * Temporal Envelope Coding - *-----------------------------------------------------------------*/ - - IF( st->element_mode == EVS_MONO ) - { - IF( ( st->hTECEnc = (TEC_ENC_HANDLE) malloc( sizeof( TEC_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TEC\n" ) ); - } - } - ELSE - { - st->hTECEnc = NULL; - } - /* note: initialization done later in init_coder_ace_plus() */ - - /*-----------------------------------------------------------------* - * TCX core - *-----------------------------------------------------------------*/ - - // ToDo: reduction possible for MCT_CHAN_MODE_LFE channel - test(); - IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - IF( ( st->hTcxEnc = (TCX_ENC_HANDLE) malloc( sizeof( TCX_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxEnc\n" ) ); - } - set32_fx( st->hTcxEnc->spectrum_long_fx, 0, N_MAX ); - st->hTcxEnc->spectrum_long_e = 0; - move16(); - /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ - st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; - st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; - move32(); - move32(); - st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; - move16(); - move16(); -#if 1 - // set_f( st->hTcxEnc->spectrum_long, 0, N_MAX ); - // st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; - // st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; - // set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); -#endif - - set16_fx( st->hTcxEnc->old_out_fx, 0, L_FRAME32k ); - st->hTcxEnc->Q_old_out = 0; - move16(); - - /* MDCT selector */ - MDCT_selector_reset_fx( st->hTcxEnc ); - - /* MDCT classifier */ - MDCT_classifier_reset_fx( st->hTcxEnc ); - - IF( ( st->hTcxCfg = (TCX_CONFIG_HANDLE) malloc( sizeof( TCX_config ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); - } - } - ELSE - { - st->hTcxEnc = NULL; - st->hTcxCfg = NULL; - } - - /*-----------------------------------------------------------------* - * IGF - *-----------------------------------------------------------------*/ - - igf_brate = st->total_brate; - move32(); - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, ISM_FORMAT ) || EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) ) - { - igf_brate = L_sub( st->total_brate, i_mult( ISM_NB_BITS_METADATA_NOMINAL, FRAMES_PER_SEC ) ); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_FORMAT ) || - EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) || - EQ_16( st_ivas->hEncoderConfig->ivas_format, MC_FORMAT ) || - EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_FORMAT ) ) ) ) - { - /* use nominal bitrates for DFT Stereo and (O)SBA, same as in stereo_dft_config()/ivas_spar_config() */ - IF( EQ_32( element_brate, IVAS_13k2 ) ) - { - igf_brate = ACELP_9k60; - } - ELSE IF( EQ_32( element_brate, IVAS_16k4 ) ) - { - igf_brate = ACELP_13k20; - } - ELSE IF( EQ_32( element_brate, IVAS_24k4 ) ) - { - igf_brate = ACELP_16k40; - } - ELSE IF( EQ_32( element_brate, IVAS_32k ) ) - { - igf_brate = ACELP_24k40; - } - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - igf_brate = element_brate; - } - move32(); - test(); - IF( EQ_16( st->codec_mode, MODE2 ) || GT_16( st->element_mode, EVS_MONO ) ) - { - st->igf = getIgfPresent_fx( st->element_mode, igf_brate, st->max_bwidth, st->rf_mode ); - } - ELSE - { - st->igf = 0; - } - move16(); - - test(); - test(); - test(); - IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) && ( st->igf || st->element_mode == EVS_MONO ) ) - { - IF( ( st->hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) ); - } - } - ELSE - { - st->hIGFEnc = NULL; - } - - /*-----------------------------------------------------------------* - * Mode 2 initialization - *-----------------------------------------------------------------*/ - - st->last_sr_core = L_mult0( st->last_L_frame, FRAMES_PER_SEC ); - move32(); - - - /* PLC encoder */ - IF( st->element_mode == EVS_MONO ) - { - IF( ( st->hPlcExt = (PLC_ENC_EVS_HANDLE) malloc( sizeof( PLC_ENC_EVS ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hPlcExt\n" ) ); - } - } - ELSE - { - st->hPlcExt = NULL; - } - - /* Init Mode 2 core coder */ - st->last_totalNoise_fx = 0; - move16(); - set16_fx( st->totalNoise_increase_hist_fx, 0, TOTALNOISE_HIST_SIZE ); - st->totalNoise_increase_len = 0; - move16(); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - IF( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - } - st->currEnergyHF_fx = 0; - move32(); - st->currEnergyHF_e_fx = 0; - move16(); -#ifdef MSAN_FIX - st->prevEnergyHF_fx = 0; - move32(); -#endif - - /* Initialize TCX */ - - /* Initialize Signal Buffers */ - Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); - st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); - move16(); - shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); - Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); - st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); - move16(); - /* Initialize ACELP */ -#endif -#ifdef FIX_920_IGF_INIT_ERROR - init_coder_ace_plus_ivas_fx( st, st->last_total_brate, igf_brate, 0 ); -#else - init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); -#endif - - IF( st->hLPDmem != NULL ) - { - st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; - move16(); - } - /*-----------------------------------------------------------------* - * FD-CNG encoder - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - IF( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) - { - createFdCngEnc_fx( &st->hFdCngEnc ); - initFdCngEnc_fx( st->hFdCngEnc, st->input_Fs, st->cldfbAnaEnc->scale ); - /* initialization for IVAS modes happens in first frame pre-processing */ - IF( st->element_mode == EVS_MONO ) - { - Word32 total_brate; - - test(); - IF( st->rf_mode && EQ_32( st->total_brate, ACELP_13k20 ) ) - { - total_brate = ACELP_9k60; - move32(); - } - ELSE - { - total_brate = st->total_brate; - move32(); - } - - configureFdCngEnc_ivas_fx( st->hFdCngEnc, st->bwidth, total_brate ); - } - } - ELSE - { - st->hFdCngEnc = NULL; - } - - /*-----------------------------------------------------------------* - * Transient detector - *-----------------------------------------------------------------*/ - - IF( ( st->hTranDet = (TRAN_DET_HANDLE) malloc( sizeof( TRAN_DET_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); - } - Word16 temp; - Word16 frame_length = BASOP_Util_Divide3232_Scale( st->input_Fs, FRAMES_PER_SEC, &temp ); - frame_length = shr( frame_length, sub( 15, temp ) ); - - IF( GT_16( st->element_mode, EVS_MONO ) ) - { - InitTransientDetection_ivas_fx( frame_length, 0, st->hTranDet, 1 ); - } - ELSE - { - InitTransientDetection_ivas_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); - } - - /*-----------------------------------------------------------------* - * IVAS parameters - *-----------------------------------------------------------------*/ - - st->tdm_LRTD_flag = 0; - move16(); - st->cng_sba_flag = 0; - move16(); - st->bits_frame_channel = 0; - move16(); - st->side_bits_frame_channel = 0; - move16(); - st->Q_syn2 = 0; - move16(); - st->Q_syn = 0; - move16(); - set16_fx( st->Q_max, Q_MAX, L_Q_MEM ); - set16_fx( st->Q_max_16k, Q_MAX, L_Q_MEM ); - st->Q_old = 15; - move16(); - st->old_wsp_max = 0; - move16(); - st->old_wsp_shift = 0; - move16(); - st->sharpFlag = 0; - move16(); - - return error; -} - - -/*-----------------------------------------------------------------------* - * destroy_cldfb_encoder() - * - * Free memory which was allocated in init_encoder() - *-----------------------------------------------------------------------*/ - -void destroy_cldfb_encoder_fx( - Encoder_State *st /* i/o: Encoder static variables structure */ -) -{ - deleteCldfb_ivas_fx( &st->cldfbSynTd ); - deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); - - deleteFdCngEnc_fx( &st->hFdCngEnc ); - - return; -} diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 58706279e..ca8b70ca2 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -10,8 +10,10 @@ #include "stl.h" #include "ivas_cnst.h" #include "ivas_error.h" +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* @@ -1062,3 +1064,1171 @@ void destroy_encoder_fx( return; } + +ivas_error init_encoder_ivas_fx( + Encoder_State *st, /* i/o: state structure */ + Encoder_Struct *st_ivas, /* i/o: encoder state structure */ + const Word16 idchan, /* i : channel ID */ + const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ + const Word16 interval_SID, /* i : interval for SID update */ + const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const Word32 element_brate /* i : element bitrate */ +) +{ + Word16 i; + ivas_error error; + Word32 igf_brate; + + error = IVAS_ERR_OK; + move32(); + + /*-----------------------------------------------------------------* + * General parameters + *-----------------------------------------------------------------*/ + + IF( st->Opt_AMR_WB ) + { + st->last_core = AMR_WB_CORE; + } + ELSE + { + st->last_core = -1; + } + move16(); + + st->L_frame = L_FRAME; + move16(); + st->last_coder_type = GENERIC; + move16(); + st->coder_type = GENERIC; + move16(); + st->last_total_brate = st->total_brate; + move32(); + st->last_bits_frame_nominal = -1; + move16(); + st->last_total_brate_cng = -1; + move16(); + st->last_core_brate = st->total_brate; + move32(); + st->dtx_sce_sba = 0; + move16(); + st->extl = -1; + move16(); + st->last_extl = -1; + move16(); + st->last_L_frame = L_FRAME; + move16(); + st->rate_switching_reset = 0; + move16(); + st->rate_switching_reset_16kHz = 0; + move16(); + st->clas = UNVOICED_CLAS; + move16(); + st->low_rate_mode = 0; + move16(); + st->ini_frame = 0; + move16(); + st->inactive_coder_type_flag = 0; + move16(); + st->sba_br_sw_while_no_data = 0; + move16(); + + st->coder_type_raw = VOICED; + move16(); + st->last_coder_type_raw = st->coder_type_raw; + move16(); + + st->flag_ACELP16k = set_ACELP_flag_IVAS( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); + move16(); + + st->is_ism_format = 0; + move16(); + + IF( NE_16( ism_mode, ISM_MODE_NONE ) ) + { + st->is_ism_format = 1; + move16(); + } + + /*-----------------------------------------------------------------* + * Bitstream + *-----------------------------------------------------------------*/ + + IF( !vad_only_flag ) + { + IF( ( st->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); + } + + /* set pointer to the buffer of indices */ + st->hBstr->ind_list = st_ivas->ind_list; + st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; + st->hBstr->nb_ind_tot = 0; + move16(); + st->hBstr->nb_bits_tot = 0; + move16(); + st->hBstr->st_ivas = st_ivas; + } + ELSE + { + st->hBstr = NULL; + } + + /*-----------------------------------------------------------------* + * Pre-processing and ACELP core parameters + *-----------------------------------------------------------------*/ + + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + Copy( GEWB_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( GEWB_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( GEWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); + + st->next_force_safety_net = 0; + move16(); + + st->pstreaklen = 0; + move16(); + st->streaklimit_fx = MAX_WORD16; + move16(); + set16_fx( st->mem_MA_fx, 0, M ); + + init_gp_clip_fx( st->clip_var_fx ); + pitch_ol_init_fx( &st->old_thres_fx, &st->old_pitch, &st->delta_pit, &st->old_corr_fx ); + set16_fx( st->old_wsp_fx, 0, L_WSP_MEM ); + st->exp_old_wsp = 0; + move16(); + set16_fx( st->old_wsp2_fx, 0, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); // Needs to change depending on usage. + st->Q_old_wsp2 = 0; + move16(); + + st->mem_preemph_fx = 0; + move16(); + st->mem_preemph16k_fx = 0; + move16(); + st->mem_preemph_enc = 0; + move16(); + st->exp_mem_preemph_enc = 0; + move16(); + +#if 1 // TODO: Float Initializations. To be removed later + st->active_cnt = 0; + move16(); +#endif + + st->pst_mem_deemp_err_fx = 0; + move16(); + st->pst_lp_ener_fx = 0; + move16(); + + /* AVQ pre-quantizer memory */ + st->mem_preemp_preQ_fx = 0; + move16(); + st->mem_deemp_preQ_fx = 0; + move16(); + st->last_nq_preQ = 0; + move16(); + st->last_code_preq = 0; + move16(); + st->use_acelp_preq = 0; + move16(); + st->last_harm_flag_acelp = 0; + move16(); + + /* (Decimated) Weighted Speech Memory */ + st->mem_wsp_enc = 0; + move16(); + st->mem_wsp_fx = 0; + move16(); + st->mem_wsp_q = 0; + move16(); + set16_fx( st->mem_decim2_fx, 0, 3 ); + set32_fx( st->Bin_E_fx, 0, L_FFT ); + st->q_Bin_E = Q31; + move16(); + st->ee_old_fx = 640; /* 10.0f in Q6 */ + move16(); + st->Nb_ACELP_frames = 0; + move16(); + st->audio_frame_cnt = AUDIO_COUNTER_INI; /* Initialization of the audio frame counter mildly into the audio mode */ + move16(); + + /* adaptive lag window memory */ + st->old_pitch_la = 0; + move16(); + + st->prev_Q_new = 0; + move16(); + + IF( EQ_32( st->input_Fs, 8000 ) ) + { + st->min_band = 1; + move16(); + st->max_band = 16; + move16(); + } + ELSE + { + st->min_band = 0; + move16(); + st->max_band = 19; + move16(); + } + + IF( st->Opt_AMR_WB ) + { + Copy( mean_isf_amr_wb_fx, st->lsf_old_fx, M ); + E_LPC_isf_isp_conversion( st->lsf_old_fx, st->lsp_old1_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st->lsf_old_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old1_fx, M, INT_FS_12k8 ); + } + + Copy( st->lsf_old_fx, st->lsf_old1_fx, M ); + Copy( st->lsp_old1_fx, st->lsp_old_fx, M ); + Copy( st->lsp_old_fx, st->lsp_old16k_fx, M ); + Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); + + st->stab_fac_fx = 0; + move16(); + + /* Bass post-filter memories - encoder side of MODE2 */ + st->bpf_off = 0; + move16(); + st->pst_mem_deemp_err_fx = 0; + move16(); + st->pst_lp_ener_fx = 0; + move16(); + + /* TC coder type */ + st->tc_cnt = 0; + move16(); + + /* find_uv() parameters */ + st->old_dE1_fx = 0; + move16(); + st->old_ind_deltaMax = 0; + move16(); + set32_fx( st->old_enr_ssf_fx, 0, shl( NB_SSF, 1 ) ); + st->spike_hyst = -1; + move16(); + + /* stereo switching memories */ + st->mem_preemph_DFT_fx = 0; + move16(); + set16_fx( st->inp_12k8_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_12k8, L_MEM_RECALC_12K8 ), L_FILT ) ); + st->mem_preemph16k_DFT_fx = 0; + move16(); + set16_fx( st->inp_16k_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_16k, L_MEM_RECALC_16K ), L_FILT16k ) ); + + st->sharpFlag = 0; + move16(); + + /* Stationary noise UV modification */ + st->ge_sm_fx = L_deposit_l( 640 ); /*Q(GE_SHIFT)*/ + move16(); + st->uv_count = 0; + move16(); + st->act_count = 3; + move16(); + Copy( st->lsp_old_fx, st->lspold_s_fx, M ); + st->noimix_seed = RANDOM_INITSEED; + move16(); + st->min_alpha_fx = 32767; + move16(); + st->exc_pe_fx = 0; + move16(); + st->Q_stat_noise = 15; + move16(); + /* FEC */ + st->last_clas = UNVOICED_CLAS; + move16(); + st->prev_fmerit = 0; + move16(); + st->fmerit_dt = 0; + move16(); + st->Last_pulse_pos = 0; + move16(); + + FOR( i = 0; i < shl( NB_SUBFR16k, 1 ); i++ ) + { + st->old_pitch_buf_fx[i] = L_SUBFR_Q6; + move16(); + } + + /* mode1 core switching */ + st->old_Es_pred_fx = 0; + move16(); + set16_fx( st->old_Aq_12_8_fx + 1, 0, M ); + st->old_Aq_12_8_fx[0] = ONE_IN_Q12; + move16(); + + /* stable short pitch detection */ + st->voicing0_sm_fx = 0; + move16(); + st->voicing_sm_fx = 0; + move16(); + st->LF_EnergyRatio_sm_fx = 1; + move16(); + st->predecision_flag = 0; + move16(); + st->diff_sm_fx = 0; + move32(); + st->energy_sm_fx = 0; + move32(); + + set16_fx( st->pitch, L_SUBFR, 3 ); + set16_fx( st->voicing_fx, 0, 3 ); + + /*-----------------------------------------------------------------* + * General signal buffers + *-----------------------------------------------------------------*/ + + IF( !vad_only_flag ) + { + IF( ( st->hSignalBuf = (SIGNAL_BUFFERS_ENC_HANDLE) malloc( sizeof( SIGNAL_BUFFERS_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Signal buffers\n" ) ); + } + + st->Bin_E_old_fx = st->hSignalBuf->Bin_E_old_fx; + st->mem_decim_fx = st->hSignalBuf->mem_decim_fx; + st->mem_decim16k_fx = st->hSignalBuf->mem_decim16k_fx; + st->old_inp_12k8_fx = st->hSignalBuf->old_inp_12k8_fx; + st->old_inp_16k_fx = st->hSignalBuf->old_inp_16k_fx; + st->buf_speech_enc_pe = st->hSignalBuf->buf_speech_enc_pe; + st->buf_synth = st->hSignalBuf->buf_synth; + st->buf_speech_enc = st->hSignalBuf->buf_speech_enc; + st->buf_wspeech_enc = st->hSignalBuf->buf_wspeech_enc; + + set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); + st->q_Bin_E_old = Q31; + move16(); + set16_fx( st->hSignalBuf->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + st->exp_buf_speech_enc = 0; + move16(); + set16_fx( st->hSignalBuf->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); + st->exp_buf_wspeech_enc = 0; + move16(); + /* initializations */ +#ifndef MSAN_FIX + set32_fx( st->Bin_E_old_fx, 0, shr( L_FFT, 2 ) ); +#else + set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); +#endif + st->q_Bin_E_old = Q31; + move16(); + set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); + set16_fx( st->mem_decim16k_fx, 0, shl( L_FILT_MAX, 1 ) ); + set16_fx( st->old_inp_12k8_fx, 0, L_INP_MEM ); + set16_fx( st->old_inp_16k_fx, 0, L_INP_MEM ); + st->exp_old_inp_16k = 0; + st->exp_old_inp_12k8 = 0; + move16(); + move16(); + + st->input_buff_fx = st->hSignalBuf->input_buff; + st->input_buff32_fx = st->hSignalBuf->input_buff32; + set16_fx( st->input_buff_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); + st->q_inp = Q15; + move16(); + st->q_old_inp = Q15; + move16(); + set32_fx( st->input_buff32_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); + st->q_inp32 = Q31; + move16(); + st->old_input_signal_fx = st->input_buff_fx; + /* st->input_Fs / FRAMES_PER_SEC */ + Word16 frame_length = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + + IF( st->element_mode == EVS_MONO ) + { + st->input32_fx = st->input_buff32_fx + st->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); + st->input_fx = st->input_buff_fx + add( frame_length, (Word16) NS2SA( st->input_Fs, DELAY_FIR_RESAMPL_NS ) ); + } + ELSE + { + st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC + st->input_fx = st->input_buff_fx + frame_length; + } +#if 1 // TODO: To be removed later +#endif + } + ELSE + { + st->hSignalBuf = NULL; + st->Bin_E_old_fx = NULL; + st->mem_decim_fx = NULL; + st->mem_decim16k_fx = NULL; + st->old_inp_12k8_fx = NULL; + st->old_inp_16k_fx = NULL; + st->buf_speech_enc_pe = NULL; + st->buf_synth = NULL; + st->buf_speech_enc = NULL; + st->buf_wspeech_enc = NULL; + st->input_buff_fx = NULL; +#if 1 +#endif + } + + /*-----------------------------------------------------------------* + * Noise estimator + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) + { + IF( ( st->hNoiseEst = (NOISE_EST_HANDLE) malloc( sizeof( NOISE_EST_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ); + } + + noise_est_init_ivas_fx( st->hNoiseEst ); + } + ELSE + { + st->hNoiseEst = NULL; + } + + /*-----------------------------------------------------------------* + * VAD + *-----------------------------------------------------------------*/ + + st->vad_flag = 1; + move16(); + st->localVAD = 0; + move16(); + + IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) && ( !vad_only_flag ) ) + { + IF( ( st->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); + } + + wb_vad_init_ivas_fx( st->hVAD ); + } + ELSE + { + st->hVAD = NULL; + } + st->Pos_relE_cnt = 20; + move16(); + + /* CLDFB-based VAD */ + IF( st->element_mode == EVS_MONO ) + { + /* This is done to as in EVS T_CldfbVadState structure is present in Encoder State */ + /* + if ( ( st->hVAD_CLDFB = (VAD_CLDFB_HANDLE) malloc( sizeof( T_CldfbVadState ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB VAD\n" ) ); + } + */ + st->hVAD_CLDFB = &st->vad_st; + + vad_init_fx( st->hVAD_CLDFB ); + } + ELSE + { + st->hVAD_CLDFB = NULL; + } + + /*-----------------------------------------------------------------* + * Speech/music classifier + *-----------------------------------------------------------------*/ + + IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) + { + IF( ( st->hSpMusClas = (SP_MUS_CLAS_HANDLE) malloc( sizeof( SP_MUS_CLAS_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Speech/music classifier\n" ) ); + } + + speech_music_clas_init_ivas_fx( st->hSpMusClas ); + st->sp_aud_decision0 = 0; + move16(); + st->sp_aud_decision1 = 0; + move16(); + st->sp_aud_decision2 = 0; + move16(); + } + ELSE + { + st->hSpMusClas = NULL; + } + + + /*-----------------------------------------------------------------* + * WB, SWB and FB bandwidth detector + *-----------------------------------------------------------------*/ + + st->lt_mean_NB_fx = 0; + move16(); + st->lt_mean_WB_fx = 0; + move16(); + st->lt_mean_SWB_fx = 0; + move16(); + st->count_WB = BWD_COUNT_MAX; + move16(); + st->count_SWB = BWD_COUNT_MAX; + move16(); + st->count_FB = BWD_COUNT_MAX; + move16(); + st->bwidth = st->max_bwidth; + move16(); + st->last_input_bwidth = st->bwidth; + move16(); + st->last_bwidth = st->bwidth; + move16(); + st->last_bwidth_cng = st->bwidth; + move16(); + st->bwidth_sw_cnt = 0; + move16(); + + + /*-----------------------------------------------------------------* + * DTX + *-----------------------------------------------------------------*/ + + st->lp_speech_fx = 11520; /*Q8 (45.0) */ /* Initialize the long-term active speech level in dB */ + move16(); + st->lp_noise_fx = 0; + move16(); + st->flag_noisy_speech_snr = 0; + move16(); + st->fd_cng_reset_flag = 0; + move16(); + st->cng_type = -1; + move16(); + st->bckr_tilt_lt = 0; + move16(); + st->active_cnt = 0; + move16(); + + test(); + test(); + test(); + test(); + IF( ( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) + { + IF( ( st->hDtxEnc = (DTX_ENC_HANDLE) malloc( sizeof( DTX_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX variables\n" ) ); + } + dtx_enc_init_fx( st, var_SID_rate_flag, interval_SID ); + } + ELSE + { + st->hDtxEnc = NULL; + } + + /*-----------------------------------------------------------------* + * No other handles needed to be allocated for front-VAD structure + *-----------------------------------------------------------------*/ + + IF( vad_only_flag ) + { + st->hTdCngEnc = NULL; + st->cldfbAnaEnc = NULL; + st->hFdCngEnc = NULL; + st->hSC_VBR = NULL; + st->hAmrwb_IO = NULL; + st->hLPDmem = NULL; + st->hGSCEnc = NULL; + st->hBWE_TD = NULL; + st->cldfbSynTd = NULL; + st->hBWE_FD = NULL; + st->hHQ_core = NULL; + st->hRF = NULL; + st->hTECEnc = NULL; + st->hTcxEnc = NULL; + st->hTcxCfg = NULL; + st->hIGFEnc = NULL; + st->hPlcExt = NULL; + st->hTranDet = NULL; + + st->element_mode = IVAS_SCE; + move16(); + st->idchan = 100; /* indicates hCoreCoderVAD */ + move16(); + st->core = -1; + move16(); + st->rf_mode = 0; + move16(); + + return error; + } + + /*-----------------------------------------------------------------* + * LP-CNG + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + IF( ( ( idchan == 0 && st->Opt_DTX_ON && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || st->element_mode == EVS_MONO ) && !( EQ_16( ism_mode, ISM_MODE_PARAM ) || EQ_16( ism_mode, ISM_MODE_DISC ) ) ) + { + IF( ( st->hTdCngEnc = (TD_CNG_ENC_HANDLE) malloc( sizeof( TD_CNG_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); + } + + td_cng_enc_init_ivas_fx( st->hTdCngEnc, st->Opt_DTX_ON, st->max_bwidth ); + } + ELSE + { + st->hTdCngEnc = NULL; + } + + /*-----------------------------------------------------------------* + * CLDFB & resampling tools parameters + *-----------------------------------------------------------------*/ + test(); + test(); + test(); + IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) + { + IF( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + st->cldfbAnaEnc = NULL; + } + + st->energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ + move32(); + st->sf_energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ + move16(); + + /*-----------------------------------------------------------------* + * SC-VBR parameters + *-----------------------------------------------------------------*/ + + test(); + IF( st->Opt_SC_VBR || st->element_mode == EVS_MONO ) + { + IF( ( st->hSC_VBR = (SC_VBR_ENC_HANDLE) malloc( sizeof( SC_VBR_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SC-VBR\n" ) ); + } + + sc_vbr_enc_init_fx( st->hSC_VBR ); + } + ELSE + { + st->hSC_VBR = NULL; + } + + st->last_Opt_SC_VBR = 0; + move16(); + + + /*-----------------------------------------------------------------* + * AMR-WB IO initialization + *-----------------------------------------------------------------*/ + + test(); + IF( st->Opt_AMR_WB || st->element_mode == EVS_MONO ) + { + IF( ( st->hAmrwb_IO = (AMRWB_IO_ENC_HANDLE) malloc( sizeof( AMRWB_IO_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AMR-WB IO\n" ) ); + } + + amr_wb_enc_init_fx( st->hAmrwb_IO ); + } + ELSE + { + st->hAmrwb_IO = NULL; + } + + /*-----------------------------------------------------------------* + * ACELP LPDmem + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + IF( ( st->hLPDmem = (LPD_state_HANDLE) malloc( sizeof( LPD_state ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LPDmem\n" ) ); + } + + LPDmem_enc_init_ivas_fx( st->hLPDmem ); + } + ELSE + { + st->hLPDmem = NULL; + } + + /*-----------------------------------------------------------------* + * parameters for AC coder type (GSC) + *-----------------------------------------------------------------*/ + + st->GSC_noisy_speech = 0; + move16(); + st->GSC_IVAS_mode = 0; + move16(); + + test(); + test(); + IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + IF( ( st->hGSCEnc = (GSC_ENC_HANDLE) malloc( sizeof( GSC_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n" ) ); + } + + GSC_enc_init_fx( st->hGSCEnc ); + } + ELSE + { + st->hGSCEnc = NULL; + } + + /*-----------------------------------------------------------------* + * TBE parameters + *-----------------------------------------------------------------*/ + + test(); + IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + IF( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); + } + + IF( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + { + return error; + } + + InitSWBencBuffer_ivas_fx( st ); + ResetSHBbuffer_Enc_fx( st ); + } + ELSE + { + st->hBWE_TD = NULL; + st->cldfbSynTd = NULL; + } + + /*-----------------------------------------------------------------* + * SWB BWE parameters + *-----------------------------------------------------------------*/ + + test(); + IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + IF( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); + } + + fd_bwe_enc_init_fx( st->hBWE_FD ); +#ifdef MSAN_FIX + st->Q_old_wtda = 0; + move16(); +#endif + } + ELSE + { + st->hBWE_FD = NULL; + } + + /*-----------------------------------------------------------------* + * HQ core parameters + *-----------------------------------------------------------------*/ + + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) + { + IF( ( st->hHQ_core = (HQ_ENC_HANDLE) malloc( sizeof( HQ_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ core\n" ) ); + } + + HQ_core_enc_init_fx( st->hHQ_core ); + } + ELSE + { + st->hHQ_core = NULL; + } + + /* init memory for detect_transient(), used by HQ core and swb_bwe_enc */ + st->old_hpfilt_in_fx = 0; + move16(); + st->old_hpfilt_out_fx = 0; + move16(); + st->EnergyLT_fx = 0; + move32(); + st->Energy_Old_fx = 0; + move32(); + st->TransientHangOver = 0; + move16(); + st->EnergyLT_fx_exp = 30; + move16(); + st->last_enerBuffer_exp = 0; + move16(); + + /*-----------------------------------------------------------------* + * Channel-aware mode + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( !st->Opt_RF_ON || ( NE_16( st->bwidth, WB ) && NE_16( st->bwidth, SWB ) ) || NE_32( st->total_brate, ACELP_13k20 ) ) + { + st->rf_mode = 0; + move16(); + } + ELSE + { + st->rf_mode = st->Opt_RF_ON; + move16(); + } + + st->rf_mode_last = st->rf_mode; + move16(); + + test(); + IF( st->Opt_RF_ON || st->element_mode == EVS_MONO ) + { + IF( ( st->hRF = (RF_ENC_HANDLE) malloc( sizeof( RF_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for RF\n" ) ); + } + + /* initialize RF indice buffers */ + reset_rf_indices_fx( st ); + } + ELSE + { + st->hRF = NULL; + } + + /*-----------------------------------------------------------------* + * Temporal Envelope Coding + *-----------------------------------------------------------------*/ + + IF( st->element_mode == EVS_MONO ) + { + IF( ( st->hTECEnc = (TEC_ENC_HANDLE) malloc( sizeof( TEC_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TEC\n" ) ); + } + } + ELSE + { + st->hTECEnc = NULL; + } + /* note: initialization done later in init_coder_ace_plus() */ + + /*-----------------------------------------------------------------* + * TCX core + *-----------------------------------------------------------------*/ + + // ToDo: reduction possible for MCT_CHAN_MODE_LFE channel + test(); + IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + IF( ( st->hTcxEnc = (TCX_ENC_HANDLE) malloc( sizeof( TCX_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxEnc\n" ) ); + } + set32_fx( st->hTcxEnc->spectrum_long_fx, 0, N_MAX ); + st->hTcxEnc->spectrum_long_e = 0; + move16(); + /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ + st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; + st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; + move32(); + move32(); + st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; + move16(); + move16(); +#if 1 + // set_f( st->hTcxEnc->spectrum_long, 0, N_MAX ); + // st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; + // st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; + // set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); +#endif + + set16_fx( st->hTcxEnc->old_out_fx, 0, L_FRAME32k ); + st->hTcxEnc->Q_old_out = 0; + move16(); + + /* MDCT selector */ + MDCT_selector_reset_fx( st->hTcxEnc ); + + /* MDCT classifier */ + MDCT_classifier_reset_fx( st->hTcxEnc ); + + IF( ( st->hTcxCfg = (TCX_CONFIG_HANDLE) malloc( sizeof( TCX_config ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); + } + } + ELSE + { + st->hTcxEnc = NULL; + st->hTcxCfg = NULL; + } + + /*-----------------------------------------------------------------* + * IGF + *-----------------------------------------------------------------*/ + + igf_brate = st->total_brate; + move32(); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, ISM_FORMAT ) || EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) ) + { + igf_brate = L_sub( st->total_brate, i_mult( ISM_NB_BITS_METADATA_NOMINAL, FRAMES_PER_SEC ) ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_FORMAT ) || + EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) || + EQ_16( st_ivas->hEncoderConfig->ivas_format, MC_FORMAT ) || + EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_FORMAT ) ) ) ) + { + /* use nominal bitrates for DFT Stereo and (O)SBA, same as in stereo_dft_config()/ivas_spar_config() */ + IF( EQ_32( element_brate, IVAS_13k2 ) ) + { + igf_brate = ACELP_9k60; + } + ELSE IF( EQ_32( element_brate, IVAS_16k4 ) ) + { + igf_brate = ACELP_13k20; + } + ELSE IF( EQ_32( element_brate, IVAS_24k4 ) ) + { + igf_brate = ACELP_16k40; + } + ELSE IF( EQ_32( element_brate, IVAS_32k ) ) + { + igf_brate = ACELP_24k40; + } + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + igf_brate = element_brate; + } + move32(); + test(); + IF( EQ_16( st->codec_mode, MODE2 ) || GT_16( st->element_mode, EVS_MONO ) ) + { + st->igf = getIgfPresent_fx( st->element_mode, igf_brate, st->max_bwidth, st->rf_mode ); + } + ELSE + { + st->igf = 0; + } + move16(); + + test(); + test(); + test(); + IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) && ( st->igf || st->element_mode == EVS_MONO ) ) + { + IF( ( st->hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) ); + } + } + ELSE + { + st->hIGFEnc = NULL; + } + + /*-----------------------------------------------------------------* + * Mode 2 initialization + *-----------------------------------------------------------------*/ + + st->last_sr_core = L_mult0( st->last_L_frame, FRAMES_PER_SEC ); + move32(); + + + /* PLC encoder */ + IF( st->element_mode == EVS_MONO ) + { + IF( ( st->hPlcExt = (PLC_ENC_EVS_HANDLE) malloc( sizeof( PLC_ENC_EVS ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hPlcExt\n" ) ); + } + } + ELSE + { + st->hPlcExt = NULL; + } + + /* Init Mode 2 core coder */ + st->last_totalNoise_fx = 0; + move16(); + set16_fx( st->totalNoise_increase_hist_fx, 0, TOTALNOISE_HIST_SIZE ); + st->totalNoise_increase_len = 0; + move16(); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + IF( hTcxEnc != NULL ) + { + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + } + st->currEnergyHF_fx = 0; + move32(); + st->currEnergyHF_e_fx = 0; + move16(); +#ifdef MSAN_FIX + st->prevEnergyHF_fx = 0; + move32(); +#endif + + /* Initialize TCX */ + + /* Initialize Signal Buffers */ + Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); + st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); + move16(); + shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); + Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); + st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); + move16(); + /* Initialize ACELP */ +#endif +#ifdef FIX_920_IGF_INIT_ERROR + init_coder_ace_plus_ivas_fx( st, st->last_total_brate, igf_brate, 0 ); +#else + init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); +#endif + + IF( st->hLPDmem != NULL ) + { + st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; + move16(); + } + /*-----------------------------------------------------------------* + * FD-CNG encoder + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + IF( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) + { + createFdCngEnc_fx( &st->hFdCngEnc ); + initFdCngEnc_fx( st->hFdCngEnc, st->input_Fs, st->cldfbAnaEnc->scale ); + /* initialization for IVAS modes happens in first frame pre-processing */ + IF( st->element_mode == EVS_MONO ) + { + Word32 total_brate; + + test(); + IF( st->rf_mode && EQ_32( st->total_brate, ACELP_13k20 ) ) + { + total_brate = ACELP_9k60; + move32(); + } + ELSE + { + total_brate = st->total_brate; + move32(); + } + + configureFdCngEnc_ivas_fx( st->hFdCngEnc, st->bwidth, total_brate ); + } + } + ELSE + { + st->hFdCngEnc = NULL; + } + + /*-----------------------------------------------------------------* + * Transient detector + *-----------------------------------------------------------------*/ + + IF( ( st->hTranDet = (TRAN_DET_HANDLE) malloc( sizeof( TRAN_DET_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); + } + Word16 temp; + Word16 frame_length = BASOP_Util_Divide3232_Scale( st->input_Fs, FRAMES_PER_SEC, &temp ); + frame_length = shr( frame_length, sub( 15, temp ) ); + + IF( GT_16( st->element_mode, EVS_MONO ) ) + { + InitTransientDetection_ivas_fx( frame_length, 0, st->hTranDet, 1 ); + } + ELSE + { + InitTransientDetection_ivas_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); + } + + /*-----------------------------------------------------------------* + * IVAS parameters + *-----------------------------------------------------------------*/ + + st->tdm_LRTD_flag = 0; + move16(); + st->cng_sba_flag = 0; + move16(); + st->bits_frame_channel = 0; + move16(); + st->side_bits_frame_channel = 0; + move16(); + st->Q_syn2 = 0; + move16(); + st->Q_syn = 0; + move16(); + set16_fx( st->Q_max, Q_MAX, L_Q_MEM ); + set16_fx( st->Q_max_16k, Q_MAX, L_Q_MEM ); + st->Q_old = 15; + move16(); + st->old_wsp_max = 0; + move16(); + st->old_wsp_shift = 0; + move16(); + st->sharpFlag = 0; + move16(); + + return error; +} + + +/*-----------------------------------------------------------------------* + * destroy_cldfb_encoder() + * + * Free memory which was allocated in init_encoder() + *-----------------------------------------------------------------------*/ + +void destroy_cldfb_encoder_fx( + Encoder_State *st /* i/o: Encoder static variables structure */ +) +{ + deleteCldfb_ivas_fx( &st->cldfbSynTd ); + deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); + + deleteFdCngEnc_fx( &st->hFdCngEnc ); + + return; +} diff --git a/lib_enc/inov_enc.c b/lib_enc/inov_enc.c deleted file mode 100644 index 08f1e768f..000000000 --- a/lib_enc/inov_enc.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * inov_encode() - * - * Encode the algebraic innovation - *---------------------------------------------------------------------*/ diff --git a/lib_enc/isf_enc_amr_wb.c b/lib_enc/isf_enc_amr_wb.c deleted file mode 100644 index 7bb7c56fe..000000000 --- a/lib_enc/isf_enc_amr_wb.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c index 0dd0f5aa1..eb82aa78a 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder.c @@ -35,6 +35,7 @@ #include "options.h" #include "ivas_cnst.h" #include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" @@ -174,7 +175,7 @@ static Word16 ivas_arith_encode_array_fx( pCum_freq = pArith->cum_freq[0]; /* Q0 */ } - ari_start_encoding_14bits( &as ); + ari_start_encoding_14bits_ivas_fx( &as ); FOR( i = 0; i < in_len; i++ ) { diff --git a/lib_enc/lead_indexing.c b/lib_enc/lead_indexing.c deleted file mode 100644 index 3a6a477b9..000000000 --- a/lib_enc/lead_indexing.c +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ - -static int16_t fcb_encode_pos( const int16_t pos_vector[], const int16_t pulse_num, const int16_t pos_num ); - - -/*-------------------------------------------------------------------* - * re8_compute_base_index: - * - * Compute base index for RE8 - *-------------------------------------------------------------------*/ - -void re8_compute_base_index( - const int16_t *x, /* i : Elemen of Q2, Q3 or Q4 */ - const int16_t ka, /* i : Identifier of the absolute leader related to x */ - uint16_t *I /* o : index */ -) -{ - int16_t i, j, k1, m; - int16_t setor_8p[8], setor_8p_temp[8]; - int16_t sign_8p; - int16_t code_index, code_level, code_area; - uint16_t offset; - const int16_t *a1, *a2; - - a1 = vals_a[ka]; - a2 = vals_q[ka]; - - /* the sign process */ - - sign_8p = 0; - m = 0; - code_index = 0; - k1 = a2[0]; - - if ( ( a2[1] == 2 ) && ( a1[0] ^ 1 ) && ( ka != 5 ) ) - { - for ( i = 0; i < 8; i++ ) - { - if ( x[i] != 0 ) - { - sign_8p = sign_8p * 2; - setor_8p_temp[m] = i; - m++; - } - if ( x[i] < 0 ) - { - sign_8p += 1; - } - } - - code_index = fcb_encode_pos( setor_8p_temp, 8, m ); - code_index = ( code_index << k1 ) + sign_8p; - - offset = Is[ka]; - - - *I = offset + code_index; - } - else - { - for ( i = 0; i < 8; i++ ) - { - setor_8p[i] = (int16_t) abs( x[i] ); - - if ( x[i] < 0 ) - { - sign_8p = sign_8p * 2 + 1; - m++; - } - if ( x[i] > 0 ) - { - sign_8p = sign_8p * 2; - m++; - } - } - - if ( k1 != m ) - { - sign_8p = sign_8p >> 1; - } - - /* code level by level */ - - code_level = a2[1]; - code_area = 8; - - if ( a2[2] != 1 ) - { - for ( j = 0; j < code_level - 1; j++ ) - { - m = 0; - - for ( i = 0; i < code_area; i++ ) - { - if ( setor_8p[i] != a1[j] ) - { - setor_8p_temp[m] = i; - setor_8p[m] = setor_8p[i]; - m++; - } - } - code_index *= select_table22[m][code_area]; - - code_index += fcb_encode_pos( setor_8p_temp, code_area, m ); - - code_area = m; - } - } - else - { - for ( i = 0; i < code_area; i++ ) - { - if ( setor_8p[i] == a1[1] ) - { - code_index += i; - } - } - } - - code_index = ( code_index << k1 ) + sign_8p; - - offset = Is[ka]; - - *I = offset + code_index; - } - - return; -} - -/*-------------------------------------------------------------------* - * fcb_encode_pos: - * - * Base function to compute base index for RE8 - *-------------------------------------------------------------------*/ - -/*! r: Code index */ -static int16_t fcb_encode_pos( - const int16_t pos_vector[], /* i : Position vectort */ - const int16_t pulse_num, /* i : Pulse number */ - const int16_t pos_num /* i : Position number */ -) -{ - int16_t i, j; - int16_t code_index; - int16_t temp, temp1; - const int16_t *select_table23; - - temp = pulse_num - 1; - - select_table23 = select_table22[pos_num]; - - code_index = select_table23[pulse_num] - select_table23[pulse_num - pos_vector[0]]; - - for ( i = 0, j = 1; i < pos_num - 1; i++, j++ ) - { - temp1 = pos_num - j; - - select_table23 = select_table22[temp1]; - - code_index += select_table23[temp - pos_vector[i]] - select_table23[pulse_num - pos_vector[j]]; - } - - return code_index; -} diff --git a/lib_enc/long_enr.c b/lib_enc/long_enr.c deleted file mode 100644 index 31ab8f019..000000000 --- a/lib_enc/long_enr.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * long_enr() - * - * Compute relative energy, long-term average total noise energy and total active speech energy - *-------------------------------------------------------------------*/ diff --git a/lib_enc/lp_exc_e.c b/lib_enc/lp_exc_e.c deleted file mode 100644 index 5c3581f4f..000000000 --- a/lib_enc/lp_exc_e.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/lsf_enc.c b/lib_enc/lsf_enc.c deleted file mode 100644 index 3ac84b28e..000000000 --- a/lib_enc/lsf_enc.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "basop_proto_func.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/ltd_stable.c b/lib_enc/ltd_stable.c deleted file mode 100644 index 0e2004abf..000000000 --- a/lib_enc/ltd_stable.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/mdct_classifier.c b/lib_enc/mdct_classifier.c deleted file mode 100644 index 047f02355..000000000 --- a/lib_enc/mdct_classifier.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include -#include "ivas_prot_fx.h" diff --git a/lib_enc/mdct_selector.c b/lib_enc/mdct_selector.c deleted file mode 100644 index 952043e3a..000000000 --- a/lib_enc/mdct_selector.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/mslvq_enc.c b/lib_enc/mslvq_enc.c deleted file mode 100644 index a49d435c3..000000000 --- a/lib_enc/mslvq_enc.c +++ /dev/null @@ -1,308 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "ivas_prot.h" - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - -Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead ); - -/*-----------------------------------------------------------------* - * mslvq() - * - * Encodes the LSF residual - *-----------------------------------------------------------------*/ - -Word32 mslvq_ivas_16( - Word16 *pTmp, /* i : M-dimensional input vector */ - Word16 *quant, /* o : quantized vector */ - Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ - Word16 *idx_scale, /* o : scale index for each subvector */ - const Word16 *w, /* i : weights for LSF quantization */ - const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ - const Word16 mode_glb, /* i : LVQ coding mode */ - const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ - /*Retunr dist in q 22*/ -) -{ - Word32 dist, L_tmp; - const Word16 *p_scales, *p_sigma, *p_inv_sigma; - Word16 i, tmp, tmp1; - Word16 p_no_lead[MAX_NO_SCALES * 2]; - dist = L_deposit_l( 0 ); - IF( pred_flag == 0 ) - { - p_sigma = sigma_MSLVQ_fx[mode]; - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; - p_scales = scales_ivas_fx[mode_glb]; - - tmp = no_lead_idx[mode_glb][0]; - move16(); - tmp1 = no_lead_idx[mode_glb][1]; - move16(); - test(); - if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) - { - tmp = add( tmp, DELTA_LEADER ); - } - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) leaders_short[tmp][i]; - move16(); - p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; - move16(); - } - } - ELSE - { - IF( GE_16( pred_flag, 5 ) ) - { - /* assert( pred_flag >= 12 && pred_flag <= 15 ); */ - /* pred_flag is here the number of bits for MSLVQ */ - - p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; - - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; - IF( mode_glb == 0 ) - { - p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; - - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; - move16(); - } - } - ELSE - { - p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; - move16(); - } - } - } - ELSE - { - p_sigma = sigma_p_fx[mode]; - - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_p_fx[mode]; - - p_scales = scales_p_ivas_fx[mode_glb]; - - tmp = no_lead_p_idx[mode_glb][0]; - move16(); - tmp1 = no_lead_p_idx[mode_glb][1]; - move16(); - - test(); - IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) - { - tmp = add( tmp, DELTA_LEADER ); - } - - test(); - IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) ) - { - tmp = add( tmp, DELTA_LEADER ); - tmp1 = add( tmp1, DELTA_LEADER ); - } - - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) leaders_short[tmp][i]; - move16(); - p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; - move16(); - } - } - } - - /* first subvector */ - dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, - p_sigma, p_inv_sigma, p_scales, p_no_lead ); - - IF( LT_16( pred_flag, 5 ) ) - { - /* second subvector */ - L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES ); - - dist = L_add( dist, L_tmp ); - } - - return dist; -} - -/*-----------------------------------------------------------------* - * mslvq_cng() - * - * Encodes the LSF residual in SID frames - *-----------------------------------------------------------------*/ - -/*-----------------------------------------------------------------* - * prepare_data() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * calculate_min_dist() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * quantize_data() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * index_lvq() - * - * sorts in descending order and computes indices in the sorted vector - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * encode_comb() - * - * creates an index for the lattice codevector - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * index_leaders() - * - * gives the index in a class of leaders without considering the sign yet - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * find_pos() - * - * Finds the positions in vector c for which the vector components are equal to 'arg'. - * It returns the number of such positions and their values in the array 'p'. - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * encode_sign_pc1() - * - * Creates an index for signs of the significant codevector components - * Gives the index of the signs - binary representation where negative sign stands for 1 - * and positive sign stands for 1. - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * take_out_val() - * - * removes the value val from the vector v - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * c2idx() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * index_lvq_SHB() - * - *-----------------------------------------------------------------*/ - - -UWord32 index_lvq_SHB_fx( - const Word16 idx_lead, - const Word16 idx_scale, - const Word16 nbits, - Word16 *lat_cv, - const Word16 mode ) -{ - UWord16 i; - const Word8 *p_no_lead; - UWord32 index; - - IF( mode == 0 ) - { - p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3]; - } - ELSE - { - p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3]; - } - - index = 0; - move32(); - IF( GT_16( idx_lead, -1 ) ) - { - index = 1; - move32(); - FOR( i = 0; i < idx_scale; i++ ) - { - index = index + table_no_cv[p_no_lead[i]]; - move32(); - } - - IF( idx_lead > 0 ) - { - index = index + table_no_cv[idx_lead]; - move32(); - } - - index = index + encode_comb_fx( lat_cv, idx_lead ); - move32(); - } - - return index; -} diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index b6445443b..d8a78c525 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -1140,3 +1140,180 @@ Word16 c2idx_fx( /* o: index */ return tmp; } } + +/*-----------------------------------------------------------------* + * mslvq() + * + * Encodes the LSF residual + *-----------------------------------------------------------------*/ + +Word32 mslvq_ivas_16( + Word16 *pTmp, /* i : M-dimensional input vector */ + Word16 *quant, /* o : quantized vector */ + Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ + Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ + Word16 *idx_scale, /* o : scale index for each subvector */ + const Word16 *w, /* i : weights for LSF quantization */ + const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ + const Word16 mode_glb, /* i : LVQ coding mode */ + const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ + /*Retunr dist in q 22*/ +) +{ + Word32 dist, L_tmp; + const Word16 *p_scales, *p_sigma, *p_inv_sigma; + Word16 i, tmp, tmp1; + Word16 p_no_lead[MAX_NO_SCALES * 2]; + dist = L_deposit_l( 0 ); + IF( pred_flag == 0 ) + { + p_sigma = sigma_MSLVQ_fx[mode]; + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_scales = scales_ivas_fx[mode_glb]; + + tmp = no_lead_idx[mode_glb][0]; + move16(); + tmp1 = no_lead_idx[mode_glb][1]; + move16(); + test(); + if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) + { + tmp = add( tmp, DELTA_LEADER ); + } + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) leaders_short[tmp][i]; + move16(); + p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; + move16(); + } + } + ELSE + { + IF( GE_16( pred_flag, 5 ) ) + { + /* assert( pred_flag >= 12 && pred_flag <= 15 ); */ + /* pred_flag is here the number of bits for MSLVQ */ + + p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; + + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; + IF( mode_glb == 0 ) + { + p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; + + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; + move16(); + } + } + ELSE + { + p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; + move16(); + } + } + } + ELSE + { + p_sigma = sigma_p_fx[mode]; + + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = inv_sigma_p_fx[mode]; + + p_scales = scales_p_ivas_fx[mode_glb]; + + tmp = no_lead_p_idx[mode_glb][0]; + move16(); + tmp1 = no_lead_p_idx[mode_glb][1]; + move16(); + + test(); + IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) + { + tmp = add( tmp, DELTA_LEADER ); + } + + test(); + IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) ) + { + tmp = add( tmp, DELTA_LEADER ); + tmp1 = add( tmp1, DELTA_LEADER ); + } + + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) leaders_short[tmp][i]; + move16(); + p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; + move16(); + } + } + } + + /* first subvector */ + dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, + p_sigma, p_inv_sigma, p_scales, p_no_lead ); + + IF( LT_16( pred_flag, 5 ) ) + { + /* second subvector */ + L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES ); + + dist = L_add( dist, L_tmp ); + } + + return dist; +} + + +UWord32 index_lvq_SHB_fx( + const Word16 idx_lead, + const Word16 idx_scale, + const Word16 nbits, + Word16 *lat_cv, + const Word16 mode ) +{ + UWord16 i; + const Word8 *p_no_lead; + UWord32 index; + + IF( mode == 0 ) + { + p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3]; + } + ELSE + { + p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3]; + } + + index = 0; + move32(); + IF( GT_16( idx_lead, -1 ) ) + { + index = 1; + move32(); + FOR( i = 0; i < idx_scale; i++ ) + { + index = index + table_no_cv[p_no_lead[i]]; + move32(); + } + + IF( idx_lead > 0 ) + { + index = index + table_no_cv[idx_lead]; + move32(); + } + + index = index + encode_comb_fx( lat_cv, idx_lead ); + move32(); + } + + return index; +} diff --git a/lib_enc/multi_harm.c b/lib_enc/multi_harm.c deleted file mode 100644 index 5c3581f4f..000000000 --- a/lib_enc/multi_harm.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/nelp_enc.c b/lib_enc/nelp_enc.c deleted file mode 100644 index 7ea6e47a5..000000000 --- a/lib_enc/nelp_enc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/pit_enc.c b/lib_enc/pit_enc.c deleted file mode 100644 index 5bde0f450..000000000 --- a/lib_enc/pit_enc.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/pitch_ol.c b/lib_enc/pitch_ol.c deleted file mode 100644 index 0853fd9fd..000000000 --- a/lib_enc/pitch_ol.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ diff --git a/lib_enc/pitch_ol2.c b/lib_enc/pitch_ol2.c deleted file mode 100644 index dc77e0dfa..000000000 --- a/lib_enc/pitch_ol2.c +++ /dev/null @@ -1,274 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define MAX_DELTA 16 /* half-length of the delta search */ -#define COR_BUF_LEN ( L_INTERPOL1 * 2 + MAX_DELTA * 2 + 1 ) -/*-------------------------------------------------------------------* - * pitch_ol2() - * - * Open-loop pitch precision improvement with 1/4 resolution - * The pitch is searched in the interval 0 ) - { - ratio = 0; - move16(); - } - ELSE - { - ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */ - } - /*ratio *= max(voicing,0);*/ - tmp = s_max( voicing_m, 0 ); - ratio = mult_r( ratio, tmp ); /*Q7*/ - /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/ - L_tmp = L_mult( ratio, 2048 ); - L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 ); - *LF_EnergyRatio_sm = round_fx( L_tmp ); - move16(); - test(); - if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) ) - { - *predecision_flag = 1; - move16(); - } - - if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) ) - { - *predecision_flag = 0; - move16(); - } - - /* short pitch candidate detection */ - Tp = pitch[1]; - move16(); - cor_max = 0; - move16(); - pt_wsp = wsp + 3 * L_SUBFR; - pit_min = PIT_MIN_DOUBLEEXTEND; - move16(); - pit_min_up = PIT_MIN; - move16(); - FOR( T = pit_min; T <= pit_min_up; T++ ) - { - energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR ); - test(); - IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) ) - { - cor_max = L_add( energy1, 0 ); - Tp = T; - move16(); - } - } - energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 ); - exp1 = sub( exp1, shl( Q_new, 1 ) ); - energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 ); - exp2 = sub( exp2, shl( Q_new, 1 ) ); - /* cor_max *= inv_sqrt( energy0*energy1 );*/ - L_tmp = Mult_32_32( energy0, energy1 ); - exp = norm_l( L_tmp ); - L_tmp1 = L_shl( L_tmp, exp ); - - exp = sub( sub( 31, exp ), ( sub( sub( 31, exp1 ), exp2 ) ) ); - move16(); - L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/ - cor_max = Mult_32_32( cor_max, L_tmp1 ); - exp = add( sub( sub( 31, add( shl( Q_new, 1 ), 1 ) ), sub( 31, exp ) ), 31 ); - cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/ - /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/ - *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) ); - move16(); - - /* final short pitch detection */ - test(); - test(); - test(); - *flag_spitch = 0; - move16(); - IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) && - ( GT_16( *voicing0_sm, 21299 /*.65f in Q15*/ ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 22938 /*.7f in Q15*/ ) ) ) ) - { - *flag_spitch = 1; - move16(); - pitch[0] = Tp; - move16(); - pitch[1] = Tp; - move16(); - pitch[2] = Tp; - move16(); - } - - return; -} diff --git a/lib_enc/pitch_ol2_fx.c b/lib_enc/pitch_ol2_fx.c index 5d68216c9..7ca13171e 100644 --- a/lib_enc/pitch_ol2_fx.c +++ b/lib_enc/pitch_ol2_fx.c @@ -404,3 +404,227 @@ void StableHighPitchDetect_fx( return; } + + +/*-------------------------------------------------------------------* + * pitch_ol2() + * + * Open-loop pitch precision improvement with 1/4 resolution + * The pitch is searched in the interval 0 ) + { + ratio = 0; + move16(); + } + ELSE + { + ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */ + } + /*ratio *= max(voicing,0);*/ + tmp = s_max( voicing_m, 0 ); + ratio = mult_r( ratio, tmp ); /*Q7*/ + /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/ + L_tmp = L_mult( ratio, 2048 ); + L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 ); + *LF_EnergyRatio_sm = round_fx( L_tmp ); + move16(); + test(); + if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) ) + { + *predecision_flag = 1; + move16(); + } + + if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) ) + { + *predecision_flag = 0; + move16(); + } + + /* short pitch candidate detection */ + Tp = pitch[1]; + move16(); + cor_max = 0; + move16(); + pt_wsp = wsp + 3 * L_SUBFR; + pit_min = PIT_MIN_DOUBLEEXTEND; + move16(); + pit_min_up = PIT_MIN; + move16(); + FOR( T = pit_min; T <= pit_min_up; T++ ) + { + energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR ); + test(); + IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) ) + { + cor_max = L_add( energy1, 0 ); + Tp = T; + move16(); + } + } + energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 ); + exp1 = sub( exp1, shl( Q_new, 1 ) ); + energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 ); + exp2 = sub( exp2, shl( Q_new, 1 ) ); + /* cor_max *= inv_sqrt( energy0*energy1 );*/ + L_tmp = Mult_32_32( energy0, energy1 ); + exp = norm_l( L_tmp ); + L_tmp1 = L_shl( L_tmp, exp ); + + exp = sub( sub( 31, exp ), ( sub( sub( 31, exp1 ), exp2 ) ) ); + move16(); + L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/ + cor_max = Mult_32_32( cor_max, L_tmp1 ); + exp = add( sub( sub( 31, add( shl( Q_new, 1 ), 1 ) ), sub( 31, exp ) ), 31 ); + cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/ + /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/ + *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) ); + move16(); + + /* final short pitch detection */ + test(); + test(); + test(); + *flag_spitch = 0; + move16(); + IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) && + ( GT_16( *voicing0_sm, 21299 /*.65f in Q15*/ ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 22938 /*.7f in Q15*/ ) ) ) ) + { + *flag_spitch = 1; + move16(); + pitch[0] = Tp; + move16(); + pitch[1] = Tp; + move16(); + pitch[2] = Tp; + move16(); + } + + return; +} diff --git a/lib_enc/plc_enc_ext.c b/lib_enc/plc_enc_ext.c deleted file mode 100644 index 17c76dee6..000000000 --- a/lib_enc/plc_enc_ext.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "stat_enc.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/setmodeindex.c b/lib_enc/setmodeindex.c deleted file mode 100644 index b7ff1d2b6..000000000 --- a/lib_enc/setmodeindex.c +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*--------------------------------------------------------------------------- - - function name: SetModeIndex - description: function for configuring the codec between frames - currently bitrate and bandwidth only - must not be called while a frame is encoded - hence mutexes must be used in MT environments - - format: BANDWIDTH*16 + BITRATE (mode index) - - ---------------------------------------------------------------------------*/ - -void SetModeIndex_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - const Word32 last_total_brate, /* i : last total bitrate Q0*/ - const Word16 last_element_mode, /* i : last IVAS element mode Q0*/ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) Q0*/ -) -{ - Word16 ini_frame_loc = st->ini_frame; // Q0 - move16(); - - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( last_element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) ) - { - st->ini_frame = 0; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - /* Reconfigure the core coder */ - IF( ( NE_32( last_total_brate, st->total_brate ) ) || - ( NE_16( st->last_bwidth, st->bwidth ) ) || - ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || - ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || - ( NE_16( st->rf_mode_last, st->rf_mode ) ) || - ( st->element_mode > EVS_MONO && st->ini_frame == 0 ) ) - { - core_coder_mode_switch_ivas_fx( st, last_total_brate, MCT_flag ); - } - - st->ini_frame = ini_frame_loc; // Q0 - move16(); - - return; -} diff --git a/lib_enc/setmodeindex_fx.c b/lib_enc/setmodeindex_fx.c index fc3025f51..012c5757f 100644 --- a/lib_enc/setmodeindex_fx.c +++ b/lib_enc/setmodeindex_fx.c @@ -55,3 +55,48 @@ void SetModeIndex_fx( return; } + + +void SetModeIndex_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate Q0*/ + const Word16 last_element_mode, /* i : last IVAS element mode Q0*/ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) Q0*/ +) +{ + Word16 ini_frame_loc = st->ini_frame; // Q0 + move16(); + + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( last_element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) ) + { + st->ini_frame = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + /* Reconfigure the core coder */ + IF( ( NE_32( last_total_brate, st->total_brate ) ) || + ( NE_16( st->last_bwidth, st->bwidth ) ) || + ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || + ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || + ( NE_16( st->rf_mode_last, st->rf_mode ) ) || + ( st->element_mode > EVS_MONO && st->ini_frame == 0 ) ) + { + core_coder_mode_switch_ivas_fx( st, last_total_brate, MCT_flag ); + } + + st->ini_frame = ini_frame_loc; // Q0 + move16(); + + return; +} -- GitLab From ffd9acccfccfb915b783e0c8fcc4ac9649181786 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 11:54:54 +0530 Subject: [PATCH 0295/1221] Restore cod_tcx_fx.c fix and LTV crash fix for +10dB files --- lib_enc/cod_tcx_fx.c | 127 +++++++++++++++++++++++++++++++++++++------ lib_enc/gs_enc_fx.c | 4 +- 2 files changed, 112 insertions(+), 19 deletions(-) diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index bf20608b0..0ed7535f1 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -5384,8 +5384,11 @@ void TNSAnalysisStereo_fx( TCX_ENC_HANDLE hTcxEnc = NULL; Word16 individual_decision[NB_DIV]; Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; + move32(); + Word16 maxPredictionGain_e = Q31, meanPredictionGain_e; + move16(); + Word16 sum_e = 0; move16(); - individual_decision[0] = 0; move16(); individual_decision[1] = 0; @@ -5520,7 +5523,9 @@ void TNSAnalysisStereo_fx( test(); IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word32 maxPredGain_fx = -ONE_IN_Q23; + Word32 maxPredGain_fx = -ONE_IN_Q31; + move32(); + Word16 maxPredGain_e = 0; move16(); sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; @@ -5538,30 +5543,74 @@ void TNSAnalysisStereo_fx( * both filters for the decision */ - meanPredictionGain_fx = L_add( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ) ); // Q23 - maxPredictionGain_fx = L_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q23 - + meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e + Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, meanPredictionGain_fx, meanPredictionGain_e ); + IF( flag < 0 ) + { + maxPredictionGain_fx = meanPredictionGain_fx; + maxPredictionGain_e = meanPredictionGain_e; + move32(); + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } + Word16 flag_1 = BASOP_Util_Cmp_Mant32Exp( pFilter[1]->predictionGain32, pFilter[1]->predictionGain_e, L_deposit_h( pTnsParameters[1]->minPredictionGain ), PRED_GAIN_E ); + if ( flag_1 < 0 ) + { + flag_1 = 0; + move16(); + } test(); test(); test(); - IF( GT_32( pFilter[0]->predictionGain32, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && - GT_32( pFilter[1]->predictionGain32, L_shl( pTnsParameters[1]->minPredictionGain, 16 ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + IF( flag && LT_32( sts[0]->element_brate, IVAS_80k ) && + flag_1 && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) { pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ + move32(); + move32(); + pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */ + move16(); move16(); + pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */ + move16(); + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ), meanPredictionGain_e, L_abs( BASOP_Util_Add_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_negate( pFilter[1]->predictionGain32 ), pFilter[1]->predictionGain_e, &sum_e ) ), sum_e ); + if ( flag < 0 ) + { + flag = 0; move16(); } test(); - IF( LT_32( L_abs( L_sub( pFilter[0]->predictionGain32, pFilter[1]->predictionGain32 ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && + IF( flag && ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) { Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); + // maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); + flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, meanPredictionGain_fx, meanPredictionGain_e ); + IF( flag < 0 ) + { + maxPredGain_fx = meanPredictionGain_fx; + maxPredGain_e = meanPredictionGain_e; + move32(); + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( meanPredictionGain_fx, meanPredictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); test(); - IF( GT_32( meanPredictionGain_fx, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + IF( flag || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) { test(); test(); @@ -5764,10 +5813,16 @@ void TNSAnalysisStereo_fx( move16(); } } + Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); test(); test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && individual_decision[k] == 0 && flag && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; move16(); @@ -5787,7 +5842,15 @@ void TNSAnalysisStereo_fx( ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); } } - maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); + IF( flag < 0 ) + { + maxPredictionGain_fx = maxPredGain_fx; + maxPredictionGain_e = maxPredGain_e; + move32(); + move16(); + } } } } @@ -5825,7 +5888,9 @@ void TNSAnalysisStereo_fx( IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word32 maxPredGain_fx = -ONE_IN_Q23; // Q23 + Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31 + move32(); + Word16 maxPredGain_e = 0; move16(); sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; @@ -5836,9 +5901,23 @@ void TNSAnalysisStereo_fx( pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); + // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, pFilter->predictionGain32, pFilter->predictionGain_e ); + IF ( flag < 0 ) + { + maxPredGain_fx = pFilter->predictionGain32; + move32(); + maxPredGain_e = pFilter->predictionGain_e; + move16(); + } + flag = BASOP_Util_Cmp_Mant32Exp( pFilter->predictionGain32, pFilter->predictionGain_e, L_deposit_h( pTnsParameters->minPredictionGain ), PRED_GAIN_E ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); - IF( GT_32( pFilter->predictionGain32, L_shl( pTnsParameters->minPredictionGain, 16 ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + IF( flag || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) { test(); test(); @@ -5910,9 +5989,15 @@ void TNSAnalysisStereo_fx( sts[ch]->hTcxEnc->fUseTns[k] = 0; } move16(); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); + if ( flag < 0 ) + { + flag = 0; + move16(); + } test(); test(); - IF( !bWhitenedDomain && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && flag && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[ch]->hTcxEnc->fUseTns[k] = 0; move16(); @@ -5927,7 +6012,15 @@ void TNSAnalysisStereo_fx( move16(); } } - maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); + IF( flag < 0 ) + { + maxPredictionGain_fx = maxPredGain_fx; + maxPredictionGain_e = maxPredGain_e; + move32(); + move16(); + } } } } diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 7ae8fb42e..a804c1311 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -679,9 +679,9 @@ void encod_audio_ivas_fx( *--------------------------------------------------------------------------------------*/ edct_16fx( dct_epit, exc, st_fx->L_frame, 7, st_fx->element_mode ); - scale_sig( exc, st_fx->L_frame, sub( Q_new, Q_exc ) ); + Scale_sig( exc, st_fx->L_frame, sub( Q_new, Q_exc ) ); edct_16fx( exc_wo_nf, exc_wo_nf, st_fx->L_frame, 7, st_fx->element_mode ); - scale_sig( exc_wo_nf, st_fx->L_frame, sub( Q_new, Q_exc ) ); + Scale_sig( exc_wo_nf, st_fx->L_frame, sub( Q_new, Q_exc ) ); Q_exc = Q_new; move16(); /*--------------------------------------------------------------------------------------* -- GitLab From 7a7515d693a14f7af64802c8cbe1b8496b1cd808 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 11:57:37 +0530 Subject: [PATCH 0296/1221] Clang formatting changes --- lib_enc/cod_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 0ed7535f1..93c1dc58d 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -5903,7 +5903,7 @@ void TNSAnalysisStereo_fx( // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, pFilter->predictionGain32, pFilter->predictionGain_e ); - IF ( flag < 0 ) + IF( flag < 0 ) { maxPredGain_fx = pFilter->predictionGain32; move32(); -- GitLab From defa4937cc74af9928015fd67aa64d8aabcedbdd Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 13:42:55 +0530 Subject: [PATCH 0297/1221] Optimization of stereo decode path 32kHz @32kbps --- lib_com/fft_fx.c | 334 ++++++++++++++++++++++++++++ lib_com/hp50_fx.c | 66 ++++++ lib_com/modif_fs.c | 94 ++++++++ lib_com/mslvq_com_fx.c | 50 +++++ lib_com/options.h | 1 + lib_com/scale_mem_fx.c | 13 ++ lib_com/trans_inv_fx.c | 31 ++- lib_dec/acelp_core_dec_ivas_fx.c | 18 +- lib_dec/ivas_stereo_cng_dec.c | 19 +- lib_dec/ivas_stereo_dft_dec_fx.c | 167 ++++++++++++-- lib_dec/ivas_stereo_switching_dec.c | 38 +++- lib_dec/ivas_stereo_td_dec.c | 24 +- 12 files changed, 833 insertions(+), 22 deletions(-) diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 1b095e346..acadbb06b 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -4727,6 +4727,16 @@ static void fft_len16( cmplx t[4]; cmplx y[16]; +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[0]; // Qx + move64(); + s[1] = x[4]; // Qx + move64(); + s[2] = x[8]; // Qx + move64(); + s[3] = x[12]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[0], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[4], SCALEFACTOR16 ); // Qx @@ -4735,6 +4745,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[12], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4754,6 +4765,16 @@ static void fft_len16( y[3] = CL_add( t[1], t[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[1]; // Qx + move64(); + s[1] = x[5]; // Qx + move64(); + s[2] = x[9]; // Qx + move64(); + s[3] = x[13]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[1], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[5], SCALEFACTOR16 ); // Qx @@ -4762,6 +4783,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[13], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4781,6 +4803,16 @@ static void fft_len16( y[7] = CL_add( t[1], t[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[2]; // Qx + move64(); + s[1] = x[6]; // Qx + move64(); + s[2] = x[10]; // Qx + move64(); + s[3] = x[14]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[2], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[6], SCALEFACTOR16 ); // Qx @@ -4789,6 +4821,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[14], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4810,6 +4843,16 @@ static void fft_len16( y[11] = CL_add( t[1], t[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[3]; // Qx + move64(); + s[1] = x[7]; // Qx + move64(); + s[2] = x[11]; // Qx + move64(); + s[3] = x[15]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[3], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[7], SCALEFACTOR16 ); // Qx @@ -4818,6 +4861,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[15], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4978,6 +5022,18 @@ static void fft_len20_fx( cmplx tt[4]; cmplx y[20]; +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[0]; // Qx + move64(); + xx[1] = x[16]; // Qx + move64(); + xx[2] = x[12]; // Qx + move64(); + xx[3] = x[8]; // Qx + move64(); + xx[4] = x[4]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[0], SCALEFACTOR20 ); // Qx move64(); xx[1] = CL_shr( x[16], SCALEFACTOR20 ); // Qx @@ -4988,6 +5044,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[4], SCALEFACTOR20 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -5023,6 +5080,18 @@ static void fft_len20_fx( y[12] = CL_msu_j( s[2], s[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[5]; + move64(); + xx[1] = x[1]; + move64(); + xx[2] = x[17]; + move64(); + xx[3] = x[13]; + move64(); + xx[4] = x[9]; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[5], SCALEFACTOR20 ); move64(); xx[1] = CL_shr( x[1], SCALEFACTOR20 ); @@ -5033,6 +5102,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[9], SCALEFACTOR20 ); move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -5068,6 +5138,18 @@ static void fft_len20_fx( y[13] = CL_msu_j( s[2], s[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[10]; + move64(); + xx[1] = x[6]; + move64(); + xx[2] = x[2]; + move64(); + xx[3] = x[18]; + move64(); + xx[4] = x[14]; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[10], SCALEFACTOR20 ); move64(); xx[1] = CL_shr( x[6], SCALEFACTOR20 ); @@ -5078,6 +5160,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[14], SCALEFACTOR20 ); move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -5113,6 +5196,18 @@ static void fft_len20_fx( y[14] = CL_msu_j( s[2], s[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[15]; + move64(); + xx[1] = x[11]; + move64(); + xx[2] = x[7]; + move64(); + xx[3] = x[3]; + move64(); + xx[4] = x[19]; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[15], SCALEFACTOR20 ); move64(); xx[1] = CL_shr( x[11], SCALEFACTOR20 ); @@ -5123,6 +5218,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[19], SCALEFACTOR20 ); move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -6501,6 +6597,239 @@ static void fft_lenN( cmplx s[8]; cmplx y[8]; +#ifdef OPT_STEREO_32KBPS_V1 + y[1] = xx[1 * dim1]; + move64(); + y[2] = xx[2 * dim1]; + move64(); + y[3] = xx[3 * dim1]; + move64(); + y[4] = xx[4 * dim1]; + move64(); + y[5] = xx[5 * dim1]; + move64(); + y[6] = xx[6 * dim1]; + move64(); + y[7] = xx[7 * dim1]; + move64(); + + test(); + test(); + IF( EQ_16( dim1, 8 ) || EQ_16( dim1, 16 ) || EQ_16( dim1, 32 ) ) + { + FOR( i = 0; i < dim1; i++ ) + { + { + y[0] = xx[i]; + move64(); + }; + IF( i > 0 ) + { + { + y[1] = CL_mac_j( CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 1 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 1 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[2] = CL_mac_j( CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 2 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 2 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[3] = CL_mac_j( CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 3 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 3 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[4] = CL_mac_j( CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 4 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 4 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[5] = CL_mac_j( CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 5 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 5 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[6] = CL_mac_j( CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 6 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 6 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[7] = CL_mac_j( CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 7 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 7 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + } + + t[0] = CL_add( y[0], y[4] ); + move64(); + t[1] = CL_sub( y[0], y[4] ); + move64(); + t[2] = CL_add( y[1], y[5] ); + move64(); + t[3] = CL_sub( y[1], y[5] ); + move64(); + t[4] = CL_add( y[2], y[6] ); + move64(); + t[5] = CL_sub( y[2], y[6] ); + move64(); + t[6] = CL_add( y[3], y[7] ); + move64(); + t[7] = CL_sub( y[3], y[7] ); + move64(); + + s[0] = CL_add( t[0], t[4] ); + move64(); + s[2] = CL_sub( t[0], t[4] ); + move64(); + s[4] = CL_mac_j( t[1], t[5] ); + move64(); + s[5] = CL_msu_j( t[1], t[5] ); + move64(); + s[1] = CL_add( t[2], t[6] ); + move64(); + s[3] = CL_swap_real_imag( CL_sub( CL_conjugate( t[2] ), CL_conjugate( t[6] ) ) ); + move64(); + + t[0] = CL_swap_real_imag( CL_add( t[3], t[7] ) ); + move64(); + t[1] = CL_sub( t[3], t[7] ); + move64(); + + s[6] = CL_scale( CL_add( CL_conjugate( t[0] ), t[1] ), FFT_C81 ); // Qx + move64(); + s[7] = CL_scale( CL_sub( t[0], CL_conjugate( t[1] ) ), FFT_C81 ); // Qx + move64(); + s[7] = CL_conjugate( s[7] ); + move64(); + + x[i] = CL_add( s[0], s[1] ); + move64(); + x[( i + ( 1 * dim1 ) )] = CL_add( s[5], s[6] ); + move64(); + x[( i + ( 2 * dim1 ) )] = CL_sub( s[2], s[3] ); + move64(); + x[( i + ( 3 * dim1 ) )] = CL_add( s[4], s[7] ); + move64(); + x[( i + ( 4 * dim1 ) )] = CL_sub( s[0], s[1] ); + move64(); + x[( i + ( 5 * dim1 ) )] = CL_sub( s[5], s[6] ); + move64(); + x[( i + ( 6 * dim1 ) )] = CL_add( s[2], s[3] ); + move64(); + x[( i + ( 7 * dim1 ) )] = CL_sub( s[4], s[7] ); + move64(); + } + } + ELSE + { + FOR( i = 0; i < dim1; i++ ) + { + { + y[0] = xx[i]; + move64(); + }; + IF( i > 0 ) + { + { + y[1] = CL_mac_j( CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 1 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 1 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[2] = CL_mac_j( CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 2 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 2 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[3] = CL_mac_j( CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 3 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 3 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[4] = CL_mac_j( CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 4 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 4 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[5] = CL_mac_j( CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 5 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 5 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[6] = CL_mac_j( CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 6 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 6 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[7] = CL_mac_j( CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 7 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 7 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + } + + t[0] = CL_add( y[0], y[4] ); + move64(); + t[1] = CL_sub( y[0], y[4] ); + move64(); + t[2] = CL_add( y[1], y[5] ); + move64(); + t[3] = CL_sub( y[1], y[5] ); + move64(); + t[4] = CL_add( y[2], y[6] ); + move64(); + t[5] = CL_sub( y[2], y[6] ); + move64(); + t[6] = CL_add( y[3], y[7] ); + move64(); + t[7] = CL_sub( y[3], y[7] ); + move64(); + + s[0] = CL_add( t[0], t[4] ); + move64(); + s[2] = CL_sub( t[0], t[4] ); + move64(); + s[4] = CL_mac_j( t[1], t[5] ); + move64(); + s[5] = CL_msu_j( t[1], t[5] ); + move64(); + s[1] = CL_add( t[2], t[6] ); + move64(); + s[3] = CL_swap_real_imag( CL_sub( CL_conjugate( t[2] ), CL_conjugate( t[6] ) ) ); + move64(); + + t[0] = CL_swap_real_imag( CL_add( t[3], t[7] ) ); + move64(); + t[1] = CL_sub( t[3], t[7] ); + move64(); + + s[6] = CL_scale( CL_add( CL_conjugate( t[0] ), t[1] ), FFT_C81 ); // Qx + move64(); + s[7] = CL_scale( CL_sub( t[0], CL_conjugate( t[1] ) ), FFT_C81 ); // Qx + move64(); + s[7] = CL_conjugate( s[7] ); + move64(); + + x[i] = CL_add( s[0], s[1] ); + move64(); + x[( i + ( 1 * dim1 ) )] = CL_add( s[5], s[6] ); + move64(); + x[( i + ( 2 * dim1 ) )] = CL_sub( s[2], s[3] ); + move64(); + x[( i + ( 3 * dim1 ) )] = CL_add( s[4], s[7] ); + move64(); + x[( i + ( 4 * dim1 ) )] = CL_sub( s[0], s[1] ); + move64(); + x[( i + ( 5 * dim1 ) )] = CL_sub( s[5], s[6] ); + move64(); + x[( i + ( 6 * dim1 ) )] = CL_add( s[2], s[3] ); + move64(); + x[( i + ( 7 * dim1 ) )] = CL_sub( s[4], s[7] ); + move64(); + } + } +#else /* OPT_STEREO_32KBPS_V1 */ test(); test(); test(); @@ -6781,6 +7110,7 @@ static void fft_lenN( move64(); } } +#endif /* OPT_STEREO_32KBPS_V1 */ BREAK; } @@ -7173,7 +7503,11 @@ void rfft_fx( move32(); x[( length - ( i << 1 ) )] = Mpy_32_16_1( L_add( t1, t3 ), 16384 /*0.5.Q15*/ ); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + x[( ( length - ( i << 1 ) ) + 1 )] = Mpy_32_16_1( L_add( t2, t4 ), -16384 /*0.5.Q15*/ ); +#else /* OPT_STEREO_32KBPS_V1 */ x[( ( length - ( i << 1 ) ) + 1 )] = Mpy_32_16_1( L_negate( L_add( t2, t4 ) ), 16384 /*0.5.Q15*/ ); +#endif /* OPT_STEREO_32KBPS_V1 */ move32(); } diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index 84bbf8b3c..d13835f4c 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -469,8 +469,14 @@ void hp20_fx_32( { Word16 i; Word32 a1_fx, a2_fx, b1_fx, b2_fx; +#ifdef OPT_STEREO_32KBPS_V1 + Word16 Qy1, Qy2, Qmin; + Word64 y0_fx64, y1_fx64, y2_fx64; + Word32 x0, x1, x2; +#else /* OPT_STEREO_32KBPS_V1 */ Word16 Qx0, Qx1, Qx2, Qy1, Qprev_y1, Qy2, Qprev_y2, Qmin; Word64 x0_fx64, x1_fx64, x2_fx64, y0_fx64, y1_fx64, y2_fx64, R1, R2, R3, R4, R5; +#endif /* OPT_STEREO_32KBPS_V1 */ IF( EQ_32( Fs, 8000 ) ) { @@ -521,15 +527,64 @@ void hp20_fx_32( move32(); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + y1_fx64 = W_add( W_deposit32_l( mem_fx[0] ), W_deposit32_h( mem_fx[1] ) ); + y2_fx64 = W_add( W_deposit32_l( mem_fx[2] ), W_deposit32_h( mem_fx[3] ) ); + + x0 = mem_fx[4]; + move32(); + x1 = mem_fx[5]; + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Qprev_y1 = extract_l( mem_fx[4] ); Qprev_y2 = extract_l( mem_fx[5] ); y1_fx64 = W_deposit32_l( mem_fx[0] ); y2_fx64 = W_deposit32_l( mem_fx[1] ); x0_fx64 = W_deposit32_l( mem_fx[2] ); x1_fx64 = W_deposit32_l( mem_fx[3] ); +#endif /* OPT_STEREO_32KBPS_V1 */ FOR( i = 0; i < lg; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + x2 = x1; + move32(); + x1 = x0; + move32(); + x0 = signal_fx[i]; + move32(); + + Qy1 = W_norm( y1_fx64 ); + if ( y1_fx64 == 0 ) + { + Qy1 = 62; + move16(); + } + + Qy2 = W_norm( y2_fx64 ); + if ( y2_fx64 == 0 ) + { + Qy2 = 62; + move16(); + } + + Qmin = s_min( Qy1, Qy2 ); + + Qmin = sub( Qmin, 34 ); + + y0_fx64 = W_mac_32_32( W_mult_32_32( W_shl_sat_l( y1_fx64, Qmin ), a1_fx ), W_shl_sat_l( y2_fx64, Qmin ), a2_fx ); // Qmin + Q29 + Q30 + 1 + + Word64 temp = W_mac_32_32( W_mac_32_32( W_mult_32_32( x2, b2_fx ), x1, b1_fx ), x0, b2_fx ); // Q30 + Word64 y0_fx = W_shr( y0_fx64, add( Qmin, Q30 ) ); // Q30 + y0_fx64 = W_add( temp, y0_fx ); // Q30 + signal_fx[i] = W_shl_sat_l( y0_fx64, -Q30 ); + move32(); + + y2_fx64 = y1_fx64; + move64(); + y1_fx64 = y0_fx64; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ x2_fx64 = x1_fx64; move64(); x1_fx64 = x0_fx64; @@ -611,8 +666,17 @@ void hp20_fx_32( move64(); move16(); move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifdef OPT_STEREO_32KBPS_V1 + mem_fx[0] = W_extract_l( y1_fx64 ); + mem_fx[1] = W_extract_h( y1_fx64 ); + mem_fx[2] = W_extract_l( y2_fx64 ); + mem_fx[3] = W_extract_h( y2_fx64 ); + mem_fx[4] = x0; + mem_fx[5] = x1; +#else /* OPT_STEREO_32KBPS_V1 */ Qy1 = W_norm( y1_fx64 ); test(); IF( y1_fx64 != 0 && LT_16( Qy1, 32 ) ) @@ -635,6 +699,8 @@ void hp20_fx_32( mem_fx[3] = W_extract_l( x1_fx64 ); mem_fx[4] = Qprev_y1; mem_fx[5] = Qprev_y2; +#endif /* OPT_STEREO_32KBPS_V1 */ + move32(); move32(); move32(); diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index 4af93522d..1b2836252 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -115,6 +115,22 @@ void Decimate_allpass_steep_fx32( /* upper allpass filter chain */ FOR( k = 0; k < N / 2; k++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[0] = Madd_32_16( mem[0], in[2 * k], AP1_STEEP_FX[0] ); // Qx + move32(); + mem[0] = Msub_32_16( in[2 * k], temp[0], AP1_STEEP_FX[0] ); // Qx + move32(); + + temp[1] = Madd_32_16( mem[1], temp[0], AP1_STEEP_FX[1] ); // Qx + move32(); + mem[1] = Msub_32_16( temp[0], temp[1], AP1_STEEP_FX[1] ); // Qx + move32(); + + out[k] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) ); // Qx move32(); mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) ); // Qx @@ -129,17 +145,31 @@ void Decimate_allpass_steep_fx32( move32(); mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } /* lower allpass filter chain */ +#ifdef OPT_STEREO_32KBPS_V1 + temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( mem[2 * ALLPASSSECTIONS_STEEP], temp[0], AP2_STEEP_FX[0] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) ); // Qx move32(); mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ /* for better performance, unroll this loop */ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP + 1] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx move32(); /*if ( fabs( temp[n] ) < 1e-12 ) @@ -148,26 +178,48 @@ void Decimate_allpass_steep_fx32( }*/ mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifdef OPT_STEREO_32KBPS_V1 + temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); + + mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ out[0] = W_round48_L( W_mac_32_16( W_mult_32_16( out[0], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx move32(); FOR( k = 1; k < N / 2; k++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], in[2 * k - 1], AP2_STEEP_FX[0] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( in[2 * k - 1], temp[0], AP2_STEEP_FX[0] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[sub( shl( k, 1 ), 1 )], AP2_STEEP_FX[0] ) ); // Qx move32(); mem[ALLPASSSECTIONS_STEEP] = L_sub( in[sub( shl( k, 1 ), 1 )], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ /* for better performance, unroll this loop */ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx move32(); /*if ( fabs( temp[n] ) < 1e-12 ) @@ -176,12 +228,20 @@ void Decimate_allpass_steep_fx32( }*/ mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifdef OPT_STEREO_32KBPS_V1 + temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); + mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ out[k] = W_round48_L( W_mac_32_16( W_mult_32_16( out[k], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx move32(); } @@ -211,12 +271,21 @@ void interpolate_3_over_2_allpass_32( FOR( i = 0; i < len; i++ ) { /* Upper branch */ +#ifdef OPT_STEREO_32KBPS_V1 + Vu[0] = Madd_32_16( mem[0], L_sub( input[i], mem[1] ), filt_coeff[0] ); // Qx + Q15 - Q15 -> Qx + move32(); + Vu[1] = Madd_32_16( mem[1], L_sub( Vu[0], mem[2] ), filt_coeff[1] ); // Qx + Q15 - Q15 -> Qx + move32(); + mem[3] = Madd_32_16( mem[2], L_sub( Vu[1], mem[3] ), filt_coeff[2] ); // Qx + Q15 - Q15 -> Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Vu[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx + Q15 - Q15 -> Qx move32(); Vu[1] = L_add( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx + Q15 - Q15 -> Qx move32(); mem[3] = L_add( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx + Q15 - Q15 -> Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ mem[1] = Vu[0]; // Qx move32(); @@ -226,12 +295,21 @@ void interpolate_3_over_2_allpass_32( move32(); /* Middle branch */ +#ifdef OPT_STEREO_32KBPS_V1 + Vm[0] = Madd_32_16( mem[0], L_sub( input[i], mem[4] ), filt_coeff[3] ); // Qx + Q15 - Q15 -> Qx + move32(); + Vm[1] = Madd_32_16( mem[4], L_sub( Vm[0], mem[5] ), filt_coeff[4] ); // Qx + Q15 - Q15 -> Qx + move32(); + mem[6] = Madd_32_16( mem[5], L_sub( Vm[1], mem[6] ), filt_coeff[5] ); // Qx + Q15 - Q15 -> Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Vm[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx + Q15 - Q15 -> Qx move32(); Vm[1] = L_add( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx + Q15 - Q15 -> Qx move32(); mem[6] = L_add( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx + Q15 - Q15 -> Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ mem[4] = Vm[0]; // Qx move32(); @@ -241,12 +319,21 @@ void interpolate_3_over_2_allpass_32( move32(); /* Lower branch */ +#ifdef OPT_STEREO_32KBPS_V1 + Vl[0] = Madd_32_16( mem[0], L_sub( input[i], mem[7] ), filt_coeff[6] ); // Qx + Q15 - Q15 -> Qx + move32(); + Vl[1] = Madd_32_16( mem[7], L_sub( Vl[0], mem[8] ), filt_coeff[7] ); // Qx + Q15 - Q15 -> Qx + move32(); + mem[9] = Madd_32_16( mem[8], L_sub( Vl[1], mem[9] ), filt_coeff[8] ); // Qx + Q15 - Q15 -> Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Vl[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx + Q15 - Q15 -> Qx move32(); Vl[1] = L_add( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx + Q15 - Q15 -> Qx move32(); mem[9] = L_add( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx + Q15 - Q15 -> Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ mem[0] = input[i]; // Qx move32(); @@ -265,10 +352,17 @@ void interpolate_3_over_2_allpass_32( { mem_temp = out1_buff[2 * i]; move32(); +#ifdef OPT_STEREO_32KBPS_V1 + out[i] = Madd_32_16( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), L_add( mem[11], mem[14] ), -4965 ); // Qx + Q15 - Q15 -> Qx + // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965 + out[i] = Madd_32_16( out[i], L_add( mem[12], mem[13] ), 20125 ); + // 0.614152f in Q15 -> 20125 +#else /* OPT_STEREO_32KBPS_V1 */ out[i] = L_add( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), Mpy_32_16_1( L_add( mem[11], mem[14] ), -4965 ) ); // Qx + Q15 - Q15 -> Qx // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965 out[i] = L_add( out[i], Mpy_32_16_1( L_add( mem[12], mem[13] ), 20125 ) ); // 0.614152f in Q15 -> 20125 +#endif /* OPT_STEREO_32KBPS_V1 */ mem[10] = mem[11]; // Qx move32(); mem[11] = mem[12]; // Qx diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index 14c9b6d97..d97830a5f 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -122,9 +122,33 @@ void init_lvq_fx( ) { Word16 i, j; +#ifdef OPT_STEREO_32KBPS_V1 + Word16 k; +#endif /* OPT_STEREO_32KBPS_V1 */ /* safety-net mode */ FOR( i = 0; i < MAX_NO_MODES; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; ( j++, k++ ) ) + { + if ( ( no_lead_fx[i][j] <= 0 ) ) + { + j = MAX_NO_SCALES; + } + } + no_scales[i][0] = k; + move16(); + + FOR( k = 0; j < MAX_NO_SCALES << 1; ( j++, k++ ) ) + { + if ( no_lead_fx[i][j] <= 0 ) + { + j = MAX_NO_SCALES << 1; + } + } + no_scales[i][1] = k; + move16(); +#else /* OPT_STEREO_32KBPS_V1 */ j = 0; move16(); test(); @@ -143,10 +167,35 @@ void init_lvq_fx( } no_scales[i][1] = sub( j, MAX_NO_SCALES ); move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ } /* predictive mode */ FOR( i = 0; i < MAX_NO_MODES_p; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; ( j++, k++ ) ) + { + + if ( ( no_lead_p_fx[i][j] <= 0 ) ) + { + j = MAX_NO_SCALES; + } + } + no_scales_p[i][0] = k; + move16(); + + FOR( k = 0; j < MAX_NO_SCALES << 1; ( j++, k++ ) ) + { + + if ( ( no_lead_p_fx[i][j] <= 0 ) ) + { + j = MAX_NO_SCALES << 1; + } + } + + no_scales_p[i][1] = k; + move16(); +#else /* OPT_STEREO_32KBPS_V1 */ j = 0; move16(); WHILE( ( LT_16( j, MAX_NO_SCALES ) ) && ( no_lead_p_fx[i][j] > 0 ) ) @@ -165,6 +214,7 @@ void init_lvq_fx( } no_scales_p[i][1] = sub( j, MAX_NO_SCALES ); move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ } /* index offsets for each truncation */ init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p ); diff --git a/lib_com/options.h b/lib_com/options.h index b24ac8267..d3570004d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,4 +172,5 @@ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ #define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ #define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ +//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #endif diff --git a/lib_com/scale_mem_fx.c b/lib_com/scale_mem_fx.c index 002821050..2ce2ffd12 100644 --- a/lib_com/scale_mem_fx.c +++ b/lib_com/scale_mem_fx.c @@ -307,8 +307,15 @@ void scale_sig32( /* saturation can occur here */ x[i] = L_shl( x[i], exp0 ); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + if ( 0 == exp0 ) + { + i = lg; + } +#endif /* OPT_STEREO_32KBPS_V1 */ } } + void scale_sig32_r( Word32 x[], /* i/o: signal to scale Qx */ const Word16 lg, /* i : size of x[] Q0 */ @@ -322,6 +329,12 @@ void scale_sig32_r( /* saturation can occur here */ x[i] = L_shl_r( x[i], exp0 ); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + if ( 0 == exp0 ) + { + i = lg; + } +#endif /* OPT_STEREO_32KBPS_V1 */ } } diff --git a/lib_com/trans_inv_fx.c b/lib_com/trans_inv_fx.c index fbe0f0d6d..0033e2c9e 100644 --- a/lib_com/trans_inv_fx.c +++ b/lib_com/trans_inv_fx.c @@ -84,7 +84,9 @@ void preecho_sb_fx( UWord16 tmp_u16; Word32 mean_prev_hb_fx_loc, mean_prev_nc_fx_loc, mean_prev_fx_loc; /* */ Word16 q16p1, qmemp1, qtmp; - +#ifdef OPT_STEREO_32KBPS_V1 + Word16 shift_q = sub( 15, q_sig32 ); +#endif /* OPT_STEREO_32KBPS_V1 */ q16p1 = add( q_sig16, 1 ); qmemp1 = q16p1; @@ -137,6 +139,18 @@ void preecho_sb_fx( /* len3xLp20 = framelength/2-(short)((float)framelength*N_ZERO_MDCT/FRAME_SIZE_MS); in float*/ fxptr1 = imdct_mem_fx; +#ifdef OPT_STEREO_32KBPS_V1 + FOR( i = 0; i < len3xLp20; i++ ) + { + *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[len3xLp20 - 1 - i], shift_q ) ) ); /*Q-1*/ + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + } + FOR( i = 0; i < framelength >> 1; i++ ) + { + *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], shift_q ) ) ); /*Q-1*/ + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + } +#else /* OPT_STEREO_32KBPS_V1 */ fx32ptr1 = wtda_audio_fx + len3xLp20 - 1; /*q_sig32*/ FOR( i = 0; i < len3xLp20; i++ ) { @@ -148,7 +162,10 @@ void preecho_sb_fx( *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], sub( 15, q_sig32 ) ) ) ); /*Q-1*/ move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ } +#endif /* OPT_STEREO_32KBPS_V1 */ + qmemp1 = 0; /*already in q-1*/ + move16(); subframelength = shr( framelength, LOG2_NUMSF ); /*Q0*/ subsubframelength = shr( subframelength, log2_num_subsubframes ); /*Q0*/ @@ -391,6 +408,17 @@ void preecho_sb_fx( move16(); FOR( i = 1; i <= NUMSF; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + max_es_hb_fx = L_max( max_es_hb_fx, es_mdct_hb_fx[i] ); /* max energy low band, 8 present and 1 future subframes */ + + max_es_fx = L_max( max_es_fx, es_mdct_fx[i] ); /* max energy low band, 8 present and 1 future subframes */ + + if ( GE_32( es_mdct_fx[i], max_es_fx ) ) /* '=' to handle the first window*/ + { + maxind = i; + move16(); + } +#else /* OPT_STEREO_32KBPS_V1 */ IF( GE_32( es_mdct_hb_fx[i], max_es_hb_fx ) ) /* '=' to handle the first window*/ { max_es_hb_fx = L_add( es_mdct_hb_fx[i], 0 ); /* max energy low band, 8 present and 1 future subframes */ @@ -402,6 +430,7 @@ void preecho_sb_fx( maxind = i; move16(); } +#endif /* OPT_STEREO_32KBPS_V1 */ } cnt2 = cnt5 = 0; diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 6e56bc154..5c16bc3e9 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1908,7 +1908,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_imag ); // Q_imag } - scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#ifdef OPT_STEREO_32KBPS_V1 + scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) +#else /* OPT_STEREO_32KBPS_V1 */ + scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); #ifndef MSAN_FIX @@ -1989,7 +1993,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real } - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#ifdef OPT_STEREO_32KBPS_V1 + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) +#else /* OPT_STEREO_32KBPS_V1 */ + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); #ifndef MSAN_FIX @@ -2096,7 +2104,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real } - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#ifdef OPT_STEREO_32KBPS_V1 + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) +#else /* OPT_STEREO_32KBPS_V1 */ + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#endif /* OPT_STEREO_32KBPS_V1 */ #ifndef MSAN_FIX Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index c8985d7cd..b3bddae59 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -1450,7 +1450,11 @@ void stereo_cna_update_params_fx( { IF( EQ_16( hCPE->nchan_out, 1 ) ) { +#ifdef OPT_STEREO_32KBPS_V1 + c_LR_fx = MAX_32; +#else /* OPT_STEREO_32KBPS_V1 */ c_LR_fx = MAX_WORD16; +#endif /* OPT_STEREO_32KBPS_V1 */ move32(); c_ILD_fx = 0; move32(); @@ -1512,8 +1516,12 @@ void stereo_cna_update_params_fx( dotLR_fx = Mpy_32_32( W_extract_l( dotLR_fx ), energy_xy_fx ); /* dotLR_fx_q + ((31 - temp_res_q) - 31)) */ dotLR_fx_q = add( dotLR_fx_q, sub( sub( 31, temp_res_q ), 31 ) ); dotLR_fx = W_deposit32_l( L_shl_sat( W_extract_l( dotLR_fx ), sub( 31, dotLR_fx_q ) ) ); /* Q31 */ - /* estimate L/R correlation factor and ILD in time domain */ + /* estimate L/R correlation factor and ILD in time domain */ +#ifdef OPT_STEREO_32KBPS_V1 + c_LR_fx = W_extract_l( dotLR_fx ); /* Q31 */ +#else /* OPT_STEREO_32KBPS_V1 */ c_LR_fx = extract_h( W_extract_l( dotLR_fx ) ); /* Q15 */ +#endif /* OPT_STEREO_32KBPS_V1 */ temp_res_q = 0; move16(); @@ -1552,15 +1560,24 @@ void stereo_cna_update_params_fx( /* update of long-term ILD and LR correlation factors for stereo CNA */ IF( !hFdCngDec->first_cna_noise_updated ) { +#ifdef OPT_STEREO_32KBPS_V1 + hFdCngDec->cna_LR_LT_fx = extract_h( c_LR_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ hFdCngDec->cna_LR_LT_fx = extract_l( c_LR_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ move16(); hFdCngDec->cna_ILD_LT_fx = extract_l( c_ILD_fx ); move16(); } ELSE { +#ifdef OPT_STEREO_32KBPS_V1 + hFdCngDec->cna_LR_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_LR_CORR_LT_FILT_FX, hFdCngDec->cna_LR_LT_fx ), + Mpy_32_32( ONE_IN_Q31 - STEREO_CNA_LR_CORR_LT_FILT_FX, c_LR_fx ) ) ); /* Q31 */ +#else /* OPT_STEREO_32KBPS_V1 */ hFdCngDec->cna_LR_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_LR_CORR_LT_FILT_FX, hFdCngDec->cna_LR_LT_fx ), Mpy_32_16_1( L_sub( ONE_IN_Q31, STEREO_CNA_LR_CORR_LT_FILT_FX ), extract_l( c_LR_fx ) ) ) ); /* Q31 */ +#endif /* OPT_STEREO_32KBPS_V1 */ move16(); hFdCngDec->cna_ILD_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_ILD_LT_FILT_FX, hFdCngDec->cna_ILD_LT_fx ), diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index ca4cfdb69..7c1c892aa 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1519,8 +1519,10 @@ void stereo_dft_dec_fx( HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom; Word16 *cna_seed = &( hFdCngCom->seed ); Word32 DFT_W, DFT_Y; +#ifndef OPT_STEREO_32KBPS_V1 Word16 q_samp_ratio = Q15; move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ output_frame = (Word16) Mpy_32_32( L_add( st0->output_Fs, FRAMES_PER_SEC_BY_2 ), ONE_BY_FRAMES_PER_SEC_Q31 ); /* Q0 */ @@ -1528,8 +1530,12 @@ void stereo_dft_dec_fx( * Initialization *-----------------------------------------------------------------*/ +#ifdef OPT_STEREO_32KBPS_V1 + samp_ratio = divide3232( st0->sr_core, st0->output_Fs ); // Q15 +#else /* OPT_STEREO_32KBPS_V1 */ samp_ratio = (Word16) BASOP_Util_Divide3232_Scale( st0->sr_core, st0->output_Fs, &q_samp_ratio ); samp_ratio = shr( samp_ratio, sub( Q15 - Q12, q_samp_ratio ) ); +#endif /* OPT_STEREO_32KBPS_V1 */ stop = shr( STEREO_DFT32MS_N_32k, 1 ); @@ -2102,10 +2108,17 @@ void stereo_dft_dec_fx( /*Nyquist Freq.*/ IF( EQ_16( hStereoDft->band_limits[b], shr( hStereoDft->NFFT, 1 ) ) ) { +#ifdef OPT_STEREO_32KBPS_V1 + DFT_L[1] = Madd_32_16( pDFT_DMX[1], pDFT_DMX[1], g ); /* qDFT */ + move32(); + DFT_R[1] = Msub_32_16( pDFT_DMX[1], pDFT_DMX[1], g ); /* qDFT */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ DFT_L[1] = L_add( pDFT_DMX[1], Mpy_32_16_1( pDFT_DMX[1], g ) ); /* qDFT */ move32(); DFT_R[1] = L_sub( pDFT_DMX[1], Mpy_32_16_1( pDFT_DMX[1], g ) ); /* qDFT */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ DFT_L[1] = Mpy_32_16_1( DFT_L[1], INV_SQRT2_FX_Q15 ); /* qDFT */ move32(); DFT_R[1] = Mpy_32_16_1( DFT_R[1], INV_SQRT2_FX_Q15 ); /* qDFT */ @@ -2238,27 +2251,52 @@ void stereo_dft_dec_fx( q_cna_level = sub( Q31, add( q_cna_level, Q16 ) ); /* generate comfort noise from gaussian noise and add to the decoded DFT spectrum */ +#ifdef OPT_STEREO_32KBPS_V1 + Word16 shift = sub( q_cna_level, hStereoDft->q_dft ); +#endif /* OPT_STEREO_32KBPS_V1 */ N1 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ N2 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ - l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ - l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ - DFT_L[2 * i] = L_add( DFT_L[2 * i], l_tmp ); /* q_dft */ +#ifdef OPT_STEREO_32KBPS_V1 + l_tmp = Madd_32_16( Madd_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ +#else /* OPT_STEREO_32KBPS_V1 */ + l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ +#endif /* OPT_STEREO_32KBPS_V1 */ + DFT_L[2 * i] = L_add( DFT_L[2 * i], l_tmp ); /* q_dft */ move32(); +#ifdef OPT_STEREO_32KBPS_V1 + l_tmp = Msub_32_16( Msub_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ + DFT_R[2 * i] = L_add( DFT_R[2 * i], l_tmp ); /* q_dft */ +#else /* OPT_STEREO_32KBPS_V1 */ l_tmp = L_sub( Msub_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ DFT_R[2 * i] = L_add( DFT_R[2 * i], l_tmp ); /* q_dft */ +#endif /* OPT_STEREO_32KBPS_V1 */ move32(); N1 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ N2 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ - l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ - l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ - DFT_L[2 * i + 1] = L_add( DFT_L[2 * i + 1], l_tmp ); /* q_dft */ +#ifdef OPT_STEREO_32KBPS_V1 + l_tmp = Madd_32_16( Madd_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ + DFT_L[2 * i + 1] = L_add( DFT_L[2 * i + 1], l_tmp ); /* q_dft */ + move32(); + l_tmp = Msub_32_16( Msub_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ + DFT_R[2 * i + 1] = L_add( DFT_R[2 * i + 1], l_tmp ); /* q_dft */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ + l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ + DFT_L[2 * i + 1] = L_add( DFT_L[2 * i + 1], l_tmp ); /* q_dft */ move32(); l_tmp = L_sub( Msub_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ DFT_R[2 * i + 1] = L_add( DFT_R[2 * i + 1], l_tmp ); /* q_dft */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } } @@ -2346,8 +2384,12 @@ static void stereo_dft_compute_td_stefi_params_fx( return; } +#ifdef OPT_STEREO_32KBPS_V1 + bin0 = round_fx( L_mult0( hStereoDft->NFFT, samp_ratio ) ); +#else /* OPT_STEREO_32KBPS_V1 */ bin0 = extract_l( L_shr_r( Mpy_32_16_1( (Word32) hStereoDft->NFFT, samp_ratio ), 1 ) ); /* Q0 */ bin0 = shl( bin0, Q3 ); +#endif /* OPT_STEREO_32KBPS_V1 */ bin0 = s_min( bin0, hStereoDft->band_limits[hStereoDft->nbands] ); /* Q0 */ b = hStereoDft->nbands; /* Q0 */ move16(); @@ -2512,14 +2554,18 @@ static void stereo_dft_dequantize_ipd_fx( *-------------------------------------------------------------------------*/ void stereo_dft_generate_res_pred_fx( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const Word16 samp_ratio, /* i : sampling ratio Q13*/ - Word32 *pDFT_DMX, /* i : downmix signal qDFT*/ - Word32 *DFT_PRED_RES, /* o : residual prediction signal qDFT*/ - Word32 *pPredGain, /* i : residual prediction gains Q31*/ - const Word16 k, /* i : subframe index Q0*/ - Word32 *ap_filt_DMX, /* i : enhanced stereo filling signal qDFT*/ - Word16 *stop, /* o : last FD stereo filling bin Q0*/ - const Word16 bfi /* i : BFI flag Q0*/ +#ifdef OPT_STEREO_32KBPS_V1 + const Word16 samp_ratio, /* i : sampling ratio Q15*/ +#else /* OPT_STEREO_32KBPS_V1 */ + const Word16 samp_ratio, /* i : sampling ratio Q13*/ +#endif /* OPT_STEREO_32KBPS_V1 */ + Word32 *pDFT_DMX, /* i : downmix signal qDFT*/ + Word32 *DFT_PRED_RES, /* o : residual prediction signal qDFT*/ + Word32 *pPredGain, /* i : residual prediction gains Q31*/ + const Word16 k, /* i : subframe index Q0*/ + Word32 *ap_filt_DMX, /* i : enhanced stereo filling signal qDFT*/ + Word16 *stop, /* o : last FD stereo filling bin Q0*/ + const Word16 bfi /* i : BFI flag Q0*/ ) { /* general variables */ @@ -2529,7 +2575,10 @@ void stereo_dft_generate_res_pred_fx( Word16 lb_stefi_start_band; /* variables for enhanced stereo filling */ - Word16 norm_fac, q_norm_fac, lim_norm_fac; + Word16 norm_fac, q_norm_fac; +#ifndef OPT_STEREO_32KBPS_V1 + Word16 lim_norm_fac; +#endif /* OPT_STEREO_32KBPS_V1 */ Word16 q_sqrt; Word16 alpha; // gain_limit; @@ -2543,8 +2592,12 @@ void stereo_dft_generate_res_pred_fx( Word32 pred_gain_avg; Word32 g2; Word16 nbands_respred; +#ifdef OPT_STEREO_32KBPS_V1 + Word16 q_new, diff; +#else /* OPT_STEREO_32KBPS_V1 */ q_norm_fac = 0; move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ push_wmops( "gen_respred" ); /* smoothing and limiting parameters */ @@ -2566,8 +2619,12 @@ void stereo_dft_generate_res_pred_fx( /* In ACELP mode the downmix signal is not available in bandwidth extension area. * * Therefore, the downmix energy in the corresponding subbands is estimated. */ +#ifdef OPT_STEREO_32KBPS_V1 + bin0 = round_fx( L_mult0( hStereoDft->NFFT, samp_ratio ) ); +#else /* OPT_STEREO_32KBPS_V1 */ bin0 = (Word16) ( L_shr( L_add( L_mult0( hStereoDft->NFFT, samp_ratio ), ONE_IN_Q12 ), Q12 + 1 ) ); /* Q0 */ move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ bin0 = s_min( bin0, hStereoDft->band_limits[hStereoDft->nbands] ); /* Q0 */ b = hStereoDft->nbands; move16(); @@ -2611,37 +2668,78 @@ void stereo_dft_generate_res_pred_fx( /* calculate band energies (low band only in case of ACELP) */ FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + dmx_nrg_64bit = W_mac_32_32( W_mac_32_32( dmx_nrg_64bit, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), + pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ); /* 2 * q_dft + 1 */ + rev_nrg_64bit = W_mac_32_32( W_mac_32_32( rev_nrg_64bit, ap_filt_DMX[2 * i], ap_filt_DMX[2 * i] ), + ap_filt_DMX[2 * i + 1], ap_filt_DMX[2 * i + 1] ); /* 2 * q_dft + 1 */ +#else /* OPT_STEREO_32KBPS_V1 */ dmx_nrg_64bit = W_add( dmx_nrg_64bit, W_add( W_mult0_32_32( pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), W_mult0_32_32( pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ) ) ); /* 2 * q_dft */ rev_nrg_64bit = W_add( rev_nrg_64bit, W_add( W_mult0_32_32( ap_filt_DMX[2 * i], ap_filt_DMX[2 * i] ), W_mult0_32_32( ap_filt_DMX[2 * i + 1], ap_filt_DMX[2 * i + 1] ) ) ); /* 2 * q_dft */ +#endif /* OPT_STEREO_32KBPS_V1 */ } + +#ifdef OPT_STEREO_32KBPS_V1 + q_new = add( shl( hStereoDft->q_dft, 1 ), 1 ); + q_shift = W_norm( dmx_nrg_64bit ); + dmx_nrg = W_shl_sat_l( dmx_nrg_64bit, sub( q_shift, 32 ) ); // 2 * hStereoDft->q_dft + 1 - (q_shift - 32) + dmx_nrg_q = add( q_new, sub( q_shift, 32 ) ); + q_shift = W_norm( rev_nrg_64bit ); + rev_nrg = W_shl_sat_l( rev_nrg_64bit, sub( q_shift, 32 ) ); // 2 * hStereoDft->q_dft + 1 - (q_shift - 32) + rev_nrg_q = add( q_new, sub( q_shift, 32 ) ); + move16(); +#else /* OPT_STEREO_32KBPS_V1 */ q_shift = W_norm( dmx_nrg_64bit ); dmx_nrg = W_extract_l( W_shl( dmx_nrg_64bit, sub( q_shift, 32 ) ) ); // 2 * hStereoDft->q_dft + (q_shift - 32) dmx_nrg_q = add( imult1616( 2, hStereoDft->q_dft ), sub( q_shift, 32 ) ); q_shift = W_norm( rev_nrg_64bit ); rev_nrg = W_extract_l( W_shl( rev_nrg_64bit, sub( q_shift, 32 ) ) ); // 2 * hStereoDft->q_dft + (q_shift - 32) rev_nrg_q = add( imult1616( 2, hStereoDft->q_dft ), sub( q_shift, 32 ) ); +#endif /* OPT_STEREO_32KBPS_V1 */ /* Reach a common Q for dmx_nrg and rev_nrg */ q_com = s_min( dmx_nrg_q, rev_nrg_q ); dmx_nrg = L_shl( dmx_nrg, sub( q_com, dmx_nrg_q ) ); /* q_com */ rev_nrg = L_shl( rev_nrg, sub( q_com, rev_nrg_q ) ); /* q_com */ + +#ifdef OPT_STEREO_32KBPS_V1 + diff = sub( hStereoDft->q_smoothed_nrg, q_com ); + IF( diff < 0 ) +#else /* OPT_STEREO_32KBPS_V1 */ IF( LT_16( hStereoDft->q_smoothed_nrg, q_com ) ) +#endif /* OPT_STEREO_32KBPS_V1 */ { +#ifdef OPT_STEREO_32KBPS_V1 + rev_nrg = L_shl( rev_nrg, shl( diff, 1 ) ); + dmx_nrg = L_shl( dmx_nrg, shl( diff, 1 ) ); +#else /* OPT_STEREO_32KBPS_V1 */ rev_nrg = L_shr( rev_nrg, shl( sub( q_com, hStereoDft->q_smoothed_nrg ), 1 ) ); dmx_nrg = L_shr( dmx_nrg, shl( sub( q_com, hStereoDft->q_smoothed_nrg ), 1 ) ); +#endif /* OPT_STEREO_32KBPS_V1 */ q_com = hStereoDft->q_smoothed_nrg; move16(); } +#ifdef OPT_STEREO_32KBPS_V1 + ELSE +#else /* OPT_STEREO_32KBPS_V1 */ ELSE IF( GT_16( hStereoDft->q_smoothed_nrg, q_com ) ) +#endif /* OPT_STEREO_32KBPS_V1 */ { +#ifdef OPT_STEREO_32KBPS_V1 + hStereoDft->smooth_res_nrg_fx[b] = L_shr( hStereoDft->smooth_res_nrg_fx[b], shl( diff, 1 ) ); /* hStereoDft->q_smoothed_nrg */ + move32(); + hStereoDft->smooth_dmx_nrg_fx[b] = L_shr( hStereoDft->smooth_dmx_nrg_fx[b], shl( diff, 1 ) ); /* hStereoDft->q_smoothed_nrg */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ hStereoDft->smooth_res_nrg_fx[b] = L_shr( hStereoDft->smooth_res_nrg_fx[b], shl( sub( hStereoDft->q_smoothed_nrg, q_com ), 1 ) ); /* hStereoDft->q_smoothed_nrg */ move32(); hStereoDft->smooth_dmx_nrg_fx[b] = L_shr( hStereoDft->smooth_dmx_nrg_fx[b], shl( sub( hStereoDft->q_smoothed_nrg, q_com ), 1 ) ); /* hStereoDft->q_smoothed_nrg */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ q_smoothed_nrg_local[b] = q_com; move16(); } @@ -2651,9 +2749,38 @@ void stereo_dft_generate_res_pred_fx( hStereoDft->smooth_dmx_nrg_fx[b] = Madd_32_16( Mpy_32_16_1( hStereoDft->smooth_dmx_nrg_fx[b], alpha ), dmx_nrg, sub( (Word16) ( 0x7FFF ), alpha ) ); /* hStereoDft->q_smoothed_nrg */ move32(); +#ifdef OPT_STEREO_32KBPS_V1 + // Compute norm_fac in Q14 + norm_fac = MAX_16; + move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ /* normalization factor */ IF( hStereoDft->smooth_res_nrg_fx[b] != 0 ) { +#ifdef OPT_STEREO_32KBPS_V1 + norm_fac = 0; + move16(); + IF( hStereoDft->smooth_dmx_nrg_fx[b] != 0 ) + { + Word16 quo, quo_e; + Word32 prod; + + norm_fac = BASOP_Util_Divide3232_Scale( hStereoDft->smooth_dmx_nrg_fx[b], hStereoDft->smooth_res_nrg_fx[b], &q_norm_fac ); /* q_norm_fac */ + norm_fac = Sqrt16( norm_fac, &q_norm_fac ); + + quo = BASOP_Util_Divide1616_Scale( 32767, norm_fac, &quo_e ); /* q_norm_fac */ + quo_e = sub( quo_e, q_norm_fac ); + quo = shl_sat( quo, sub( quo_e, 1 ) ); // Q14 + quo = s_max( 13107 /*0.8 in Q14 */, quo ); + quo = s_min( quo, 20480 /* 1.25 in Q14*/ ); + + prod = L_mult( norm_fac, quo ); // exp:q_norm_fac+1 + // Bring to Q30 + prod = L_shl_sat( prod, q_norm_fac ); + + norm_fac = extract_h( prod ); + } +#else /* OPT_STEREO_32KBPS_V1 */ norm_fac = BASOP_Util_Divide3232_Scale( hStereoDft->smooth_dmx_nrg_fx[b], hStereoDft->smooth_res_nrg_fx[b], &q_norm_fac ); /* q_norm_fac */ norm_fac = Sqrt16( norm_fac, &q_norm_fac ); IF( norm_fac != 0 ) @@ -2709,7 +2836,9 @@ void stereo_dft_generate_res_pred_fx( } } } +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifndef OPT_STEREO_32KBPS_V1 ELSE { norm_fac = MAX_16; @@ -2717,13 +2846,21 @@ void stereo_dft_generate_res_pred_fx( q_norm_fac = Q1; move16(); } +#endif /* OPT_STEREO_32KBPS_V1 */ FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i] ), 1 ); /* q_dft */ + move32(); + DFT_PRED_RES[2 * i + 1] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i + 1] ), 1 ); /* q_dft */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i] ), q_norm_fac ); /* q_dft */ move32(); DFT_PRED_RES[2 * i + 1] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i + 1] ), q_norm_fac ); /* q_dft */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } } diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index c6466183b..c8a59cd6a 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -2343,15 +2343,20 @@ static Word32 ncross_corr_self_fx( { Word64 c_c_fx; Word32 c_c_fx_return; + Word64 energy_x_fx, energy_y_fx; +#ifndef OPT_STEREO_32KBPS_V1 Word16 c_c_fx_q; - Word64 energy_xy_fx, energy_x_fx, energy_y_fx; + Word64 energy_xy_fx; +#endif /* OPT_STEREO_32KBPS_V1 */ UWord16 j; Word32 *signal_a_fx, *signal_b_fx; Word32 temp_x, temp_y; Word16 headroom_left_x, headroom_left_y; +#ifndef OPT_STEREO_32KBPS_V1 Word16 x_inv_q, y_inv_q; Word16 x_q, y_q; Word16 res_q; +#endif /* OPT_STEREO_32KBPS_V1 */ c_c_fx = 0; move64(); energy_x_fx = 0; @@ -2362,13 +2367,43 @@ static Word32 ncross_corr_self_fx( signal_b_fx = &signal_fx[y]; /* Q11 */ FOR( j = 0; j < corr_len; j += subsampling ) { +#ifdef OPT_STEREO_32KBPS_V1 + c_c_fx = W_mac_32_32( c_c_fx, signal_a_fx[j], signal_b_fx[j] ); /* 2 * Q11 + 1*/ + energy_x_fx = W_mac_32_32( energy_x_fx, signal_a_fx[j], signal_a_fx[j] ); /* 2 * Q11+ 1 */ + energy_y_fx = W_mac_32_32( energy_y_fx, signal_b_fx[j], signal_b_fx[j] ); /* 2 * Q11+ 1 */ +#else /* OPT_STEREO_32KBPS_V1 */ c_c_fx = W_add( c_c_fx, W_mult0_32_32( ( signal_a_fx[j] ), ( signal_b_fx[j] ) ) ); /* 2 * Q11 */ energy_x_fx = W_add( energy_x_fx, W_mult0_32_32( ( signal_a_fx[j] ), ( signal_a_fx[j] ) ) ); /* 2 * Q11 */ energy_y_fx = W_add( energy_y_fx, W_mult0_32_32( ( signal_b_fx[j] ), ( signal_b_fx[j] ) ) ); /* 2 * Q11 */ +#endif /* OPT_STEREO_32KBPS_V1 */ } headroom_left_x = W_norm( energy_x_fx ); headroom_left_y = W_norm( energy_y_fx ); +#ifdef OPT_STEREO_32KBPS_V1 + temp_x = W_extract_h( W_shl( energy_x_fx, headroom_left_x ) ); // Q23 + headroom_left_x -32 + temp_y = W_extract_h( W_shl( energy_y_fx, headroom_left_y ) ); // Q23 + headroom_left_y -32 + Word64 prod = W_mult0_32_32( temp_x, temp_y ); // Q(headroom_left_x + headroom_left_y - 18) + Word16 q_prod = W_norm( prod ); + Word32 energy = W_extract_h( W_shl( prod, q_prod ) ); // Q(headroom_left_x + headroom_left_y + q_prod - 18) - 32 + q_prod = sub( 81, add( add( headroom_left_x, headroom_left_y ), q_prod ) ); + energy = Sqrt32( energy, &q_prod ); + + IF( LT_32( energy, L_shl_sat( 1, sub( 31, q_prod ) ) ) ) + { + c_c_fx_return = W_shl_sat_l( c_c_fx, 31 - ( 2 * OUTPUT_Q + 1 ) ); // Q31 + } + ELSE + { + // Maximize c_c_fx + Word16 q_cc = W_norm( c_c_fx ); + Word32 num = W_extract_h( W_shl( c_c_fx, q_cc ) ); // Q(23 + q_cc - 32) -> e(40 - q_cc) + Word16 quo_e; + num = BASOP_Util_Divide3232_Scale_cadence( num, energy, &quo_e ); + quo_e = add( sub( sub( 40, q_cc ), q_prod ), quo_e ); + c_c_fx_return = L_shl_sat( num, quo_e ); // Q31 + } +#else /* OPT_STEREO_32KBPS_V1 */ IF( LT_16( headroom_left_x, 32 ) ) { energy_x_fx = W_shr( energy_x_fx, sub( 32, headroom_left_x ) ); /* 2 * Q11 - (32 -headroom_left_x) */ @@ -2440,6 +2475,7 @@ static Word32 ncross_corr_self_fx( c_c_fx_return = W_extract_l( c_c_fx ); /* Q31 */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ return c_c_fx_return; } diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec.c index c975da8d6..e31c9f6bc 100644 --- a/lib_dec/ivas_stereo_td_dec.c +++ b/lib_dec/ivas_stereo_td_dec.c @@ -384,7 +384,7 @@ void tdm_upmix_plain_fx( const Word32 PCh_2_L_fx[], /* i : primary channel Qx*/ const Word32 SCh_2_R_fx[], /* i : secondary channel Qx*/ const Word32 LR_ratio_fx, /* i : mixing ratio Q31*/ - const Word32 inv_den_LR_ratio_fx, /* i : inverse mixing ration Q31*/ + const Word32 inv_den_LR_ratio_fx, /* i : inverse mixing ration Q30*/ const Word16 start_index, /* i : start index Q0*/ const Word16 end_index, /* i : end index Q0*/ const Word16 plus_minus_flag /* i : plus/minus flag Q0*/ @@ -396,16 +396,37 @@ void tdm_upmix_plain_fx( { FOR( i = start_index; i < end_index; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + Word32 temp_left = Madd_32_32( SCh_2_R_fx[i], L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Left_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_left, inv_den_LR_ratio_fx ), -30 ); /* Qx */ + move32(); + Word32 temp_right = Msub_32_32( PCh_2_L_fx[i], L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Right_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_right, inv_den_LR_ratio_fx ), -30 ); /* Qx */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Word32 temp_left = L_add( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ); /* Qx */ Left_fx[i] = L_shl_sat( Mpy_32_32( temp_left, inv_den_LR_ratio_fx ), 1 ); /* Qx + 1 */ move32(); Word32 temp_right = L_add( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), L_negate( LR_ratio_fx ) ), PCh_2_L_fx[i] ); /* Qx */ Right_fx[i] = L_shl_sat( Mpy_32_32( temp_right, inv_den_LR_ratio_fx ), 1 ); /* Qx + 1 */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } } ELSE { +#ifdef OPT_STEREO_32KBPS_V1 + Word32 inv_den_LR_ratio_fx_neg = L_negate( inv_den_LR_ratio_fx ); + FOR( i = start_index; i < end_index; i++ ) + { + Word32 temp_left = Msub_32_32( SCh_2_R_fx[i], L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Left_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_left, inv_den_LR_ratio_fx_neg ), -30 ); /* Qx */ + move32(); + Word32 temp_right = Msub_32_32( PCh_2_L_fx[i], L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Right_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_right, inv_den_LR_ratio_fx_neg ), -30 ); /* Qx */ + move32(); + } +#else /* OPT_STEREO_32KBPS_V1 */ FOR( i = start_index; i < end_index; i++ ) { Word32 temp_left = L_sub( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ); /* Qx */ @@ -415,6 +436,7 @@ void tdm_upmix_plain_fx( Right_fx[i] = L_shl_sat( Mpy_32_32( temp_right, inv_den_LR_ratio_fx ), 1 ); /* Qx + 1 */ move32(); } +#endif /* OPT_STEREO_32KBPS_V1 */ } return; -- GitLab From af3a0391da504aecba2648bf91eb6104199e5a9e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 14:54:26 +0100 Subject: [PATCH 0298/1221] fixed arithmetic symbol --- lib_rend/ivas_dirac_output_synthesis_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 1e79224f6..ddd568698 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -914,7 +914,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( IF( reference_power[k + num_freq_bands] == 0 ) { sqr_inp = Mpy_32_32( diffuseness[k], c ); - sqr_exp = sub( 31 - 4, q_diffuseness ); + sqr_exp = sub( 31 + 4, q_diffuseness ); } ELSE { -- GitLab From 1aa2c023baeaa1ee514e8d84709c04ed4dcf9315 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 14:34:08 +0000 Subject: [PATCH 0299/1221] Last cleanup --- lib_rend/ivas_dirac_output_synthesis_dec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index ddd568698..eabdf9389 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1055,7 +1055,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } -#endif } ELSE { -- GitLab From 12d2affe11c67abbdc3fbbc96f2f71be593c80bc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 15:41:07 +0100 Subject: [PATCH 0300/1221] revert last commit --- lib_rend/ivas_dirac_output_synthesis_dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index eabdf9389..ddd568698 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1055,6 +1055,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } +#endif } ELSE { -- GitLab From bb55862d3bbd4d106b2f10e9ff6deb35595b32f1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 20:41:36 +0530 Subject: [PATCH 0301/1221] Duplicate lib_dec files cleanup --- Workspace_msvc/lib_dec.vcxproj | 14 - Workspace_msvc/lib_dec.vcxproj.filters | 42 - lib_dec/FEC_HQ_core.c | 136 -- lib_dec/FEC_HQ_core_fx.c | 92 + lib_dec/ari_dec.c | 338 ---- lib_dec/ari_dec_fx.c | 289 +++ lib_dec/arith_coder_dec.c | 250 --- lib_dec/arith_coder_dec_fx.c | 208 ++ lib_dec/bass_psfilter.c | 317 --- lib_dec/bass_psfilter_fx.c | 244 +++ lib_dec/core_dec_init.c | 84 - lib_dec/core_dec_init_fx.c | 26 + lib_dec/core_switching_dec.c | 1076 ---------- lib_dec/core_switching_dec_fx.c | 1009 ++++++++++ lib_dec/dec_prm.c | 328 ---- lib_dec/dec_prm_fx.c | 270 +++ lib_dec/dec_tcx.c | 508 ----- lib_dec/dec_tcx_fx.c | 447 +++++ lib_dec/fd_cng_dec.c | 1393 ------------- lib_dec/fd_cng_dec_fx.c | 1280 ++++++++++++ lib_dec/init_dec.c | 76 - lib_dec/init_dec_fx.c | 15 + lib_dec/ivas_mc_param_dec.c | 33 + lib_dec/ivas_mc_param_dec_fx.c | 34 - lib_dec/swb_bwe_dec.c | 681 ------- lib_dec/swb_bwe_dec_fx.c | 369 ++++ lib_dec/swb_tbe_dec.c | 2478 ------------------------ lib_dec/swb_tbe_dec_fx.c | 2034 ++++++++++++++++++- lib_dec/tonalMDCTconcealment.c | 436 ----- lib_dec/tonalMDCTconcealment_fx.c | 391 ++++ 30 files changed, 6701 insertions(+), 8197 deletions(-) delete mode 100644 lib_dec/FEC_HQ_core.c delete mode 100644 lib_dec/ari_dec.c delete mode 100644 lib_dec/arith_coder_dec.c delete mode 100644 lib_dec/bass_psfilter.c delete mode 100644 lib_dec/core_dec_init.c delete mode 100644 lib_dec/core_switching_dec.c delete mode 100644 lib_dec/dec_prm.c delete mode 100644 lib_dec/dec_tcx.c delete mode 100644 lib_dec/fd_cng_dec.c delete mode 100644 lib_dec/init_dec.c delete mode 100644 lib_dec/ivas_mc_param_dec_fx.c delete mode 100644 lib_dec/swb_bwe_dec.c delete mode 100644 lib_dec/swb_tbe_dec.c delete mode 100644 lib_dec/tonalMDCTconcealment.c diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 3d447fe21..b3a847791 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -145,22 +145,17 @@ - - - false - - @@ -176,9 +171,7 @@ - - @@ -191,12 +184,10 @@ - - @@ -216,7 +207,6 @@ - @@ -246,7 +236,6 @@ - @@ -310,18 +299,15 @@ - - - diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index cc7594415..c4e148b89 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -8,9 +8,6 @@ decoder_evs_c - - decoder_evs_c - decoder_evs_c @@ -137,9 +134,6 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -275,36 +269,24 @@ decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c @@ -320,15 +302,9 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -365,9 +341,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -380,9 +353,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -437,9 +407,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -515,15 +482,9 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -542,9 +503,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c diff --git a/lib_dec/FEC_HQ_core.c b/lib_dec/FEC_HQ_core.c deleted file mode 100644 index 6a119b365..000000000 --- a/lib_dec/FEC_HQ_core.c +++ /dev/null @@ -1,136 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_dec.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -void save_synthesis_hq_fec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 output_fx[], /* i : decoded synthesis */ - const Word16 output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -) -{ - Word16 post_hq_delay; - - SWITCH( st->element_mode ) - { - case EVS_MONO: - post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS ); - BREAK; - case IVAS_SCE: - post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - BREAK; - case IVAS_CPE_DFT: - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) - { - post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - } - ELSE - { - post_hq_delay = 0; - move16(); - } - BREAK; - default: - post_hq_delay = 0; - move16(); - BREAK; - } - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) - { - Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); - FOR( Word16 i = 0; i < output_frame; i++ ) - { - st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 - move16(); - } - - IF( st->element_mode == EVS_MONO ) - { - /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill - this buffer are not available for all cases, the impact on the output is limited */ - - set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - } - ELSE - { - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - - IF( st->core != ACELP_CORE ) - { - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - ELSE - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - ELSE - { - IF( st->core != ACELP_CORE ) - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - return; -} diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index f88927ee5..09bc652be 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -1961,6 +1961,98 @@ static void Next_good_after_burst_erasures_fx( return; } + +void save_synthesis_hq_fec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 output_fx[], /* i : decoded synthesis */ + const Word16 output_frame, /* i : decoded synthesis */ + CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ +) +{ + Word16 post_hq_delay; + + SWITCH( st->element_mode ) + { + case EVS_MONO: + post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS ); + BREAK; + case IVAS_SCE: + post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); + BREAK; + case IVAS_CPE_DFT: + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + { + post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); + } + ELSE + { + post_hq_delay = 0; + move16(); + } + BREAK; + default: + post_hq_delay = 0; + move16(); + BREAK; + } + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) + { + Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); + FOR( Word16 i = 0; i < output_frame; i++ ) + { + st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 + move16(); + } + + IF( st->element_mode == EVS_MONO ) + { + /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill + this buffer are not available for all cases, the impact on the output is limited */ + + set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); + IF( GE_16( output_frame, L_FRAME16k ) ) + { + Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + } + ELSE + { + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + + IF( st->core != ACELP_CORE ) + { + IF( GE_16( output_frame, L_FRAME16k ) ) + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + ELSE + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + } + } + ELSE + { + IF( st->core != ACELP_CORE ) + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + } + } + return; +} + + #ifdef ADD_IVAS_HQ_CODE_FEC /*-------------------------------------------------------------------------- * save_synthesis_hq_fec() diff --git a/lib_dec/ari_dec.c b/lib_dec/ari_dec.c deleted file mode 100644 index b45cb5d9c..000000000 --- a/lib_dec/ari_dec.c +++ /dev/null @@ -1,338 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "stat_com.h" -#include "basop_util.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------- - * Ari decode 14 bits routines - -------------------------------------------------------------*/ - -/*--------------------------------------------------------------- - * ari_start_decoding_14bits_ivas() - * - * Start ArCo decoding - *-------------------------------------------------------------*/ - - -Word16 ari_start_decoding_14bits_prm_ivas_fx( - const Word16 *ptr, - Word16 bp, - Tastat *s ) -{ - Word32 val; - Word16 i; - const Word16 *p; - - val = 0; - move32(); - p = ptr + bp; - - FOR( i = 0; i < cbitsnew; i++ ) - { - val = L_or( L_shl( val, 1 ), *( p + i ) ); - } - s->low = 0; - move32(); - s->high = ari_q4new; - move32(); - s->value = val; - move32(); - - return add( bp, i ); -} - - -Word16 ari_decode_14bits_pow_ivas( - Word16 *ptr, - Word16 bp, - Word16 bits, - Word16 *res, - Tastat *s, - UWord16 base ) -{ - UWord16 symbol; - Word32 low, high; - UWord32 range, value, cum; - Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ - Word16 lowlim, highlim, testval; - Word16 k; - - highlim = 0; - low = s->low; - high = L_add( s->high, 1 ); - value = s->value; - lowlim = 0; - symbol = 0; - move16(); - move32(); - move32(); - move16(); - move16(); - - range = (UWord32) W_sub( high, low ); - move32(); - - /* the value read from bitstream */ - assert( value >= (UWord32) low ); - cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); - move32(); - - /* search for the interval where "cum" fits */ - IF( GT_64( W_mult0_32_32( L_shr( base, 1 ), range ), cum ) ) /* below pow-1 */ - { - pows[0] = testval = base; - move16(); - move16(); - /* increase exponent until it is smaller than "cum" */ - FOR( k = 1; k < 12; k++ ) - { - highlim = testval; - move16(); - pows[k] = mult_r( pows[k - 1], pows[k - 1] ); - move16(); - testval = mult_r( pows[k], base ); - IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) /* found! big range is [lowlim,testval], (now narrow it down) */ - { - lowlim = testval; - move16(); - k = sub( k, 1 ); - symbol = (UWord16) L_shl( 1, k ); - BREAK; - } - } - assert( k < 12 ); /* maximum 2^10-1*/ - /* narrow the range down */ - FOR( k--; k > 0; k-- ) - { - testval = mult_r( highlim, pows[k] ); - IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) - { - lowlim = testval; - move16(); - symbol = (UWord16) L_sub( symbol, L_shl( 1, sub( k, 1 ) ) ); - } - ELSE - { - highlim = testval; - move16(); - } - } - highlim = shr( highlim, 1 ); - lowlim = shr( lowlim, 1 ); - } - ELSE /* trivial case, above pow-1, that is, first symbol */ - { - symbol = 0; - lowlim = extract_l( L_shr( base, 1 ) ); - highlim = 16384; - move16(); - move16(); - } - - - high = L_add( low, mul_sbc_14bits( range, highlim ) ); - - low = L_add( low, mul_sbc_14bits( range, lowlim ) ); - - /*ptr init for ptr*/ - FOR( ; bp < bits; ) - { - IF( GT_32( high, ari_q2new ) ) - { - IF( GE_32( low, ari_q2new ) ) - { - value = (UWord32) W_sub( value, ari_q2new ); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - value = (UWord32) W_sub( value, ari_q1new ); - low = L_sub( low, ari_q1new ); - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; - } - } - } - low = L_add( low, low ); - high = L_add( high, high ); - - assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); - - value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); - } - - test(); - test(); - test(); - IF( !( NE_16( bp, bits ) || !( EQ_32( s->low, low ) && ( EQ_32( s->high, high ) ) && ( EQ_64( s->value, value ) ) ) ) ) - { - /* This should not happen except of bit errors. */ - s->high = s->low = 0; - move32(); - move32(); - *res = 0; - move16(); - return -1; - } - - s->low = low; - s->high = L_sub( high, 1 ); - s->value = value; - move32(); - move32(); - move32(); - - *res = symbol; - move16(); - return bp; -} - -Word16 ari_decode_14bits_sign_ivas( - Word16 *ptr, - Word16 bp, - Word16 bits, - Word16 *res, - Tastat *s ) -{ - Word16 symbol; - Word32 low, high; - UWord32 range, value, cum; - - low = s->low; - high = L_add( s->high, 1 ); - value = s->value; - move32(); - move32(); - - range = (UWord32) W_sub( high, low ); - - IF( LT_16( bp, bits ) ) - { - assert( value >= (UWord32) low ); - cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); - IF( GT_64( W_shl( range, 13 ), cum ) ) - { - symbol = 2; - move16(); - high = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); - } - ELSE - { - symbol = 1; - move16(); - low = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); - } - - /*ptr init for ptr*/ - FOR( ; bp < bits; ) - { - IF( GT_32( high, ari_q2new ) ) - { - IF( GE_32( low, ari_q2new ) ) - { - value = (UWord32) W_sub( value, ari_q2new ); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - value = (UWord32) W_sub( value, ari_q1new ); - low = L_sub( low, ari_q1new ); - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; - } - } - } - low = L_add( low, low ); - high = L_add( high, high ); - - assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); - - value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); - } - } - ELSE - { - cum = (UWord32) W_sub( value, low ); - range = (UWord32) W_shr( range, 1 ); - IF( GT_64( range, cum ) ) - { - symbol = 2; - move16(); - high = L_add( low, range ); - } - ELSE - { - symbol = 1; - move16(); - low = L_add( low, range ); - } - } - - s->low = low; - s->high = L_sub( high, 1 ); - s->value = value; - move32(); - move32(); - move32(); - - *res = symbol; - move16(); - - return bp; -} diff --git a/lib_dec/ari_dec_fx.c b/lib_dec/ari_dec_fx.c index 3681568f2..524f9d121 100644 --- a/lib_dec/ari_dec_fx.c +++ b/lib_dec/ari_dec_fx.c @@ -551,3 +551,292 @@ Word16 ari_decode_14bits_sign_fx( Word16 *ptr, Word16 bp, Word16 bits, Word16 *r { return ari_decode_14bits_notbl_fx( ptr, bp, bits, res, s, 0, ari_lookup_sign_fx ); } + +/*--------------------------------------------------------------- + * ari_start_decoding_14bits_ivas() + * + * Start ArCo decoding + *-------------------------------------------------------------*/ + + +Word16 ari_start_decoding_14bits_prm_ivas_fx( + const Word16 *ptr, + Word16 bp, + Tastat *s ) +{ + Word32 val; + Word16 i; + const Word16 *p; + + val = 0; + move32(); + p = ptr + bp; + + FOR( i = 0; i < cbitsnew; i++ ) + { + val = L_or( L_shl( val, 1 ), *( p + i ) ); + } + s->low = 0; + move32(); + s->high = ari_q4new; + move32(); + s->value = val; + move32(); + + return add( bp, i ); +} + + +Word16 ari_decode_14bits_pow_ivas( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s, + UWord16 base ) +{ + UWord16 symbol; + Word32 low, high; + UWord32 range, value, cum; + Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ + Word16 lowlim, highlim, testval; + Word16 k; + + highlim = 0; + low = s->low; + high = L_add( s->high, 1 ); + value = s->value; + lowlim = 0; + symbol = 0; + move16(); + move32(); + move32(); + move16(); + move16(); + + range = (UWord32) W_sub( high, low ); + move32(); + + /* the value read from bitstream */ + assert( value >= (UWord32) low ); + cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); + move32(); + + /* search for the interval where "cum" fits */ + IF( GT_64( W_mult0_32_32( L_shr( base, 1 ), range ), cum ) ) /* below pow-1 */ + { + pows[0] = testval = base; + move16(); + move16(); + /* increase exponent until it is smaller than "cum" */ + FOR( k = 1; k < 12; k++ ) + { + highlim = testval; + move16(); + pows[k] = mult_r( pows[k - 1], pows[k - 1] ); + move16(); + testval = mult_r( pows[k], base ); + IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) /* found! big range is [lowlim,testval], (now narrow it down) */ + { + lowlim = testval; + move16(); + k = sub( k, 1 ); + symbol = (UWord16) L_shl( 1, k ); + BREAK; + } + } + assert( k < 12 ); /* maximum 2^10-1*/ + /* narrow the range down */ + FOR( k--; k > 0; k-- ) + { + testval = mult_r( highlim, pows[k] ); + IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) + { + lowlim = testval; + move16(); + symbol = (UWord16) L_sub( symbol, L_shl( 1, sub( k, 1 ) ) ); + } + ELSE + { + highlim = testval; + move16(); + } + } + highlim = shr( highlim, 1 ); + lowlim = shr( lowlim, 1 ); + } + ELSE /* trivial case, above pow-1, that is, first symbol */ + { + symbol = 0; + lowlim = extract_l( L_shr( base, 1 ) ); + highlim = 16384; + move16(); + move16(); + } + + + high = L_add( low, mul_sbc_14bits( range, highlim ) ); + + low = L_add( low, mul_sbc_14bits( range, lowlim ) ); + + /*ptr init for ptr*/ + FOR( ; bp < bits; ) + { + IF( GT_32( high, ari_q2new ) ) + { + IF( GE_32( low, ari_q2new ) ) + { + value = (UWord32) W_sub( value, ari_q2new ); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + value = (UWord32) W_sub( value, ari_q1new ); + low = L_sub( low, ari_q1new ); + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; + } + } + } + low = L_add( low, low ); + high = L_add( high, high ); + + assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); + + value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); + } + + test(); + test(); + test(); + IF( !( NE_16( bp, bits ) || !( EQ_32( s->low, low ) && ( EQ_32( s->high, high ) ) && ( EQ_64( s->value, value ) ) ) ) ) + { + /* This should not happen except of bit errors. */ + s->high = s->low = 0; + move32(); + move32(); + *res = 0; + move16(); + return -1; + } + + s->low = low; + s->high = L_sub( high, 1 ); + s->value = value; + move32(); + move32(); + move32(); + + *res = symbol; + move16(); + return bp; +} + +Word16 ari_decode_14bits_sign_ivas( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s ) +{ + Word16 symbol; + Word32 low, high; + UWord32 range, value, cum; + + low = s->low; + high = L_add( s->high, 1 ); + value = s->value; + move32(); + move32(); + + range = (UWord32) W_sub( high, low ); + + IF( LT_16( bp, bits ) ) + { + assert( value >= (UWord32) low ); + cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); + IF( GT_64( W_shl( range, 13 ), cum ) ) + { + symbol = 2; + move16(); + high = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); + } + ELSE + { + symbol = 1; + move16(); + low = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); + } + + /*ptr init for ptr*/ + FOR( ; bp < bits; ) + { + IF( GT_32( high, ari_q2new ) ) + { + IF( GE_32( low, ari_q2new ) ) + { + value = (UWord32) W_sub( value, ari_q2new ); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + value = (UWord32) W_sub( value, ari_q1new ); + low = L_sub( low, ari_q1new ); + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; + } + } + } + low = L_add( low, low ); + high = L_add( high, high ); + + assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); + + value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); + } + } + ELSE + { + cum = (UWord32) W_sub( value, low ); + range = (UWord32) W_shr( range, 1 ); + IF( GT_64( range, cum ) ) + { + symbol = 2; + move16(); + high = L_add( low, range ); + } + ELSE + { + symbol = 1; + move16(); + low = L_add( low, range ); + } + } + + s->low = low; + s->high = L_sub( high, 1 ); + s->value = value; + move32(); + move32(); + move32(); + + *res = symbol; + move16(); + + return bp; +} + diff --git a/lib_dec/arith_coder_dec.c b/lib_dec/arith_coder_dec.c deleted file mode 100644 index 93bd8877c..000000000 --- a/lib_dec/arith_coder_dec.c +++ /dev/null @@ -1,250 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------* - * tcx_arith_decode() - * - * - *-------------------------------------------------------*/ - -/*! r: number of bits consumed */ - -static Word16 tcx_arith_decode_ivas_fx( - const Word16 L_frame, /* i : number of spectral lines */ - const Word16 envelope[], /* i : scaled envelope (Q15-envelope_e) */ - Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ - const Word16 target_bits, /* i : target bit budget */ - Word16 prm[], /* i : bitstream parameters */ - Word32 q_spectrum[], /* o : scalar quantized spectrum (Q31-q_spectrum_e) */ - Word16 *q_spectrum_e /* o : spectrum exponent */ -) -{ - Word16 bp, k, q; - Word16 s; - Tastat as; - UWord16 exp_k; - Word16 tmp; - - bp = ari_start_decoding_14bits_prm_ivas_fx( prm, 0, &as ); - - tmp = sub( envelope_e, 1 ); - - FOR( k = 0; k < L_frame; k++ ) - { - IF( EQ_16( envelope[k], 0 ) ) /* safety check in case of bit errors */ - { - set32_fx( q_spectrum, 0, L_frame ); - return -1; - } - ELSE - { - exp_k = expfp_evs_fx( negate( envelope[k] ), tmp ); - } - - /* decode line magnitude */ - bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); - - IF( q ) - { - /* line is non-zero, decode sign */ - bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); - q_spectrum[k] = L_mult( q, sub( 3, shl( s, 1 ) ) ); - move32(); - q_spectrum[k] = L_shl( q_spectrum[k], 30 - SPEC_EXP_DEC ); // Q(31-20) - move32(); - } - ELSE - { - /* line is zero, no sign needed */ - q_spectrum[k] = 0; - move32(); - } - - IF( LE_32( as.high, as.low ) ) - { - if ( LT_16( bp, target_bits ) ) /* safety check in case of bit errors */ - { - bp = -1; - move16(); - } - BREAK; /* no bits left, so exit loop */ - } - } - *q_spectrum_e = SPEC_EXP_DEC; - move16(); - - set32_fx( q_spectrum + k, 0, sub( L_frame, k ) ); - - return bp; -} - -/*-------------------------------------------------------* - * tcx_arith_decode_envelope() - * - * - *-------------------------------------------------------*/ - -void tcx_arith_decode_envelope_ivas_fx( - Decoder_State *st, /* i/o: coder state */ - Word32 q_spectrum[], /* o : quantised MDCT coefficients Q(31-q_spectrum_e) */ - Word16 *q_spectrum_e, /* o : MDCT exponent */ - const Word16 L_frame, /* i : frame or MDCT length */ - Word16 L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const Word16 target_bits, /* i : number of available bits */ - Word16 prm[], /* i : bitstream parameters */ - const Word16 use_hm, /* i : use HM in current frame? */ - const Word16 prm_hm[], /* i : HM parameter area */ - Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - Word16 *arith_bits, /* o : bits used for ari. coding */ - Word16 *signaling_bits, /* o : bits used for signaling */ - const Word16 low_complexity /* i : low-complexity flag */ -) -{ - Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ - Word16 *envelope; /* scaled envelope (Q15-e) */ - Word16 envelope_e; - Word16 L_spec_core; - TCX_CONFIG_HANDLE hTcxCfg; - TCX_DEC_HANDLE hTcxDec; - Word16 gamma_w, gamma_uw; - Word16 hm_bits; - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_16( L_spec, N_MAX_ARI ) || ( ( st->element_mode == EVS_MONO ) && GT_16( target_bits, ( ACELP_13k20 / FRAMES_PER_SEC ) ) ) || - ( EQ_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC ) ) ) ) || - ( GT_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC ) ) ) ) || - ( target_bits <= 0 ) ) - { - /* this could happen in case of bit errors */ - st->BER_detect = 1; - move16(); - L_spec = N_MAX_ARI; - move16(); - *signaling_bits = 0; - move16(); - *arith_bits = 0; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - - return; - } - - hTcxCfg = st->hTcxCfg; - hTcxDec = st->hTcxDec; - *signaling_bits = 0; - move16(); - - assert( hTcxDec->enableTcxLpc ); - gamma_w = MAX16B; - move16(); - gamma_uw = st->inv_gamma; - move16(); - -#define WMC_TOOL_SKIP - tcx_arith_render_envelope_ivas_fx( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); -#undef WMC_TOOL_SKIP - - IF( use_hm != 0 ) - { - IF( prm_hm[0] != 0 ) - { - tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); - - IF( hm_bits < 0 ) - { - st->BER_detect = 1; - move16(); - *signaling_bits = 0; - move16(); - *arith_bits = 0; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - - return; - } - } - ELSE - { - hm_bits = 1; - move16(); - } - *signaling_bits = add( *signaling_bits, hm_bits ); - move16(); - } - - L_spec_core = L_spec; - move16(); - IF( st->igf ) - { - L_spec_core = s_min( L_spec_core, st->hIGFDec->infoIGFStartLine ); - } - - envelope = (Word16 *) env; - tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); - - *arith_bits = tcx_arith_decode_ivas_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); - move16(); - - /* safety check in case of bit errors */ - IF( *arith_bits < 0 ) - { - st->BER_detect = 1; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - } - - set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); - - return; -} diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index 4a18f64f9..6df1eb268 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -8,6 +8,9 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "basop_util.h" +#include "basop_proto_func.h" +#include "prot.h" /* Returns: number of bits consumed */ static Word16 tcx_arith_decode_fx( @@ -213,3 +216,208 @@ void tcx_arith_decode_envelope_fx( set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); } + +/*-------------------------------------------------------* + * tcx_arith_decode() + * + * + *-------------------------------------------------------*/ + +/*! r: number of bits consumed */ + +static Word16 tcx_arith_decode_ivas_fx( + const Word16 L_frame, /* i : number of spectral lines */ + const Word16 envelope[], /* i : scaled envelope (Q15-envelope_e) */ + Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ + const Word16 target_bits, /* i : target bit budget */ + Word16 prm[], /* i : bitstream parameters */ + Word32 q_spectrum[], /* o : scalar quantized spectrum (Q31-q_spectrum_e) */ + Word16 *q_spectrum_e /* o : spectrum exponent */ +) +{ + Word16 bp, k, q; + Word16 s; + Tastat as; + UWord16 exp_k; + Word16 tmp; + + bp = ari_start_decoding_14bits_prm_ivas_fx( prm, 0, &as ); + + tmp = sub( envelope_e, 1 ); + + FOR( k = 0; k < L_frame; k++ ) + { + IF( EQ_16( envelope[k], 0 ) ) /* safety check in case of bit errors */ + { + set32_fx( q_spectrum, 0, L_frame ); + return -1; + } + ELSE + { + exp_k = expfp_evs_fx( negate( envelope[k] ), tmp ); + } + + /* decode line magnitude */ + bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); + + IF( q ) + { + /* line is non-zero, decode sign */ + bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); + q_spectrum[k] = L_mult( q, sub( 3, shl( s, 1 ) ) ); + move32(); + q_spectrum[k] = L_shl( q_spectrum[k], 30 - SPEC_EXP_DEC ); // Q(31-20) + move32(); + } + ELSE + { + /* line is zero, no sign needed */ + q_spectrum[k] = 0; + move32(); + } + + IF( LE_32( as.high, as.low ) ) + { + if ( LT_16( bp, target_bits ) ) /* safety check in case of bit errors */ + { + bp = -1; + move16(); + } + BREAK; /* no bits left, so exit loop */ + } + } + *q_spectrum_e = SPEC_EXP_DEC; + move16(); + + set32_fx( q_spectrum + k, 0, sub( L_frame, k ) ); + + return bp; +} + +/*-------------------------------------------------------* + * tcx_arith_decode_envelope() + * + * + *-------------------------------------------------------*/ + +void tcx_arith_decode_envelope_ivas_fx( + Decoder_State *st, /* i/o: coder state */ + Word32 q_spectrum[], /* o : quantised MDCT coefficients Q(31-q_spectrum_e) */ + Word16 *q_spectrum_e, /* o : MDCT exponent */ + const Word16 L_frame, /* i : frame or MDCT length */ + Word16 L_spec, /* i : length w/o BW limitation */ + const Word16 A_ind[], /* i : quantised LPC coefficients */ + const Word16 target_bits, /* i : number of available bits */ + Word16 prm[], /* i : bitstream parameters */ + const Word16 use_hm, /* i : use HM in current frame? */ + const Word16 prm_hm[], /* i : HM parameter area */ + Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ + Word16 *arith_bits, /* o : bits used for ari. coding */ + Word16 *signaling_bits, /* o : bits used for signaling */ + const Word16 low_complexity /* i : low-complexity flag */ +) +{ + Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ + Word16 *envelope; /* scaled envelope (Q15-e) */ + Word16 envelope_e; + Word16 L_spec_core; + TCX_CONFIG_HANDLE hTcxCfg; + TCX_DEC_HANDLE hTcxDec; + Word16 gamma_w, gamma_uw; + Word16 hm_bits; + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_16( L_spec, N_MAX_ARI ) || ( ( st->element_mode == EVS_MONO ) && GT_16( target_bits, ( ACELP_13k20 / FRAMES_PER_SEC ) ) ) || + ( EQ_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC ) ) ) ) || + ( GT_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC ) ) ) ) || + ( target_bits <= 0 ) ) + { + /* this could happen in case of bit errors */ + st->BER_detect = 1; + move16(); + L_spec = N_MAX_ARI; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + + hTcxCfg = st->hTcxCfg; + hTcxDec = st->hTcxDec; + *signaling_bits = 0; + move16(); + + assert( hTcxDec->enableTcxLpc ); + gamma_w = MAX16B; + move16(); + gamma_uw = st->inv_gamma; + move16(); + +#define WMC_TOOL_SKIP + tcx_arith_render_envelope_ivas_fx( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); +#undef WMC_TOOL_SKIP + + IF( use_hm != 0 ) + { + IF( prm_hm[0] != 0 ) + { + tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); + + IF( hm_bits < 0 ) + { + st->BER_detect = 1; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + } + ELSE + { + hm_bits = 1; + move16(); + } + *signaling_bits = add( *signaling_bits, hm_bits ); + move16(); + } + + L_spec_core = L_spec; + move16(); + IF( st->igf ) + { + L_spec_core = s_min( L_spec_core, st->hIGFDec->infoIGFStartLine ); + } + + envelope = (Word16 *) env; + tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + + *arith_bits = tcx_arith_decode_ivas_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); + move16(); + + /* safety check in case of bit errors */ + IF( *arith_bits < 0 ) + { + st->BER_detect = 1; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + } + + set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); + + return; +} + diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c deleted file mode 100644 index 478a81474..000000000 --- a/lib_dec/bass_psfilter.c +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "cnst.h" -#include "stat_dec.h" -#include "rom_com.h" -#include -#include "wmc_auto.h" -#include "ivas_prot_fx.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - - -#define NBPSF_L_EXTRA 120 -#define BPF_STOP_STOPBAND_16 16 -#define K_PC_DEC_FX -1170 /* -0.0357f in Q15 */ -#define K_PC_DEC_FX32 -76665166 /* -0.0357f in Q31 */ -#define C_PC_DEC_FX 6583 /*in Q8*/ - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bass_psfilter() - * - * Perform low-frequency postfiltering - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * Pit_track() - * - * Perform pitch tracking and test pitch/2 to avoid continuous pitch doubling - *---------------------------------------------------------------------*/ - -/*! r: Pitch */ - - -/*---------------------------------------------------------------------* - * addBassPostFilter() - * - * Add BPF component in cldfb domain - *---------------------------------------------------------------------*/ - - -void addBassPostFilter_ivas_fx( - const Word32 *harm_timeIn_fx, // Qx - const Word16 samplesToProcess, - Word32 **rAnalysis_fx, // Qx - 5 - Word32 **iAnalysis_fx, // Qx - 5 - HANDLE_CLDFB_FILTER_BANK cldfb ) -{ - Word32 *tmp_R_fx[CLDFB_NO_COL_MAX]; - Word32 *tmp_I_fx[CLDFB_NO_COL_MAX]; - Word32 cldfbBufferReal_fx[CLDFB_NO_COL_MAX][20]; - Word32 cldfbBufferImag_fx[CLDFB_NO_COL_MAX][20]; - Word16 i, b; - Word16 maxBand; - const Word32 *weights_fx; - Word16 nCol = cldfb->no_col; - move16(); - Word16 nColToProcess = nCol; - move16(); - Word16 nChan = cldfb->no_channels; - move16(); - IF( GT_16( samplesToProcess, -1 ) ) - { - nColToProcess = idiv1616( sub( add( samplesToProcess, cldfb->no_channels ), 1 ), cldfb->no_channels ); - move16(); - } - - assert( nCol == 16 ); - - weights_fx = bpf_weights_16_ivas_fx_32; - - IF( GT_16( nChan, BPF_STOP_STOPBAND_16 ) ) - { - maxBand = BPF_STOP_STOPBAND_16; - move16(); - } - ELSE - { - maxBand = nChan; - move16(); - } - - FOR( i = 0; i < nColToProcess; i++ ) - { - tmp_R_fx[i] = cldfbBufferReal_fx[i]; - tmp_I_fx[i] = cldfbBufferImag_fx[i]; - } - - cldfbAnalysis_ivas_fx( harm_timeIn_fx, tmp_R_fx, tmp_I_fx, samplesToProcess, cldfb ); - - /* now do the subtraction */ - FOR( i = 0; i < nColToProcess; i++ ) - { - /* loop over low frequency bands */ - FOR( b = 0; b < maxBand; b++ ) - { - rAnalysis_fx[i][b] = Msub_32_32( rAnalysis_fx[i][b], tmp_R_fx[i][b], weights_fx[b] ); // Qx - 6 - move32(); - iAnalysis_fx[i][b] = Msub_32_32( iAnalysis_fx[i][b], tmp_I_fx[i][b], weights_fx[b] ); // Qx - 6 - move32(); - } - } - - return; -} - - -/*---------------------------------------------------------------------* - * res_bpf_adapt_ivas_fx() - * - * Analyze BPF output and decide if it should be applied on DFT stereo - * residual signal - *---------------------------------------------------------------------*/ - -/*! r: Decision to enable or disable BPF on DFT stereo residual */ -Word16 res_bpf_adapt_ivas_fx( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ - const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ - Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer Q12 */ - Word16 q_res ) -{ - Word32 error_nrg; - Word32 tmp; - Word32 res_hb_nrg; - Word16 bpf_error_ratio; - Word16 res_bpf_flag; - Word16 i; - Word16 i_start; - Word16 i_end; - Word16 bw_inv; - Word64 W_tmp; - - IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) - { - i_start = 39; - move16(); - i_end = 64; - move16(); - bw_inv = 1311; - move16(); /* 1/(64 - 39) in Q15 */ - } - ELSE - { - i_start = 28; - move16(); - i_end = 40; - move16(); - bw_inv = 2720; - move16(); /* 1/(40 - 28) in Q15*/ - } - - /* Measure energy of high frequency band in MDCT domain */ - res_hb_nrg = L_deposit_l( 0 ); - W_tmp = W_deposit32_l( 0 ); - FOR( i = i_start; i < i_end; i++ ) - { - W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); - } - - res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 - res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 - res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); - hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; - move32(); - - /* Measure energy of discontinuities at subframe boundaries */ - error_nrg = 0; - move32(); - FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) - { - tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); - error_nrg = Madd_32_32( error_nrg, tmp, tmp ); - hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[( i + ( STEREO_DFT_L_SUBFR_8k - 1 ) )]; - move32(); - } - error_nrg = L_shl( error_nrg, 1 ); // Q0 - error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ - /* Form decision variable and apply limit */ - IF( LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ) - { - Word16 temp; - bpf_error_ratio = BASOP_Util_Divide3232_Scale( error_nrg, res_hb_nrg, &temp ); - bpf_error_ratio = shl( bpf_error_ratio, sub( 13, sub( 15, temp ) ) ); - } - ELSE - { - bpf_error_ratio = ONE_IN_Q14; // Q13 - move16(); - } - bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( ( MAX_16 - STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); - hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; - move16(); - - res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q13 ); - move16(); - - return res_bpf_flag; -} - -void bpf_pitch_coherence_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 pitch_buf[] /* i : pitch for every subfr [0,1,2,3] Q20 */ -) -{ - Word16 nb_subfr; - Word32 pc, pcn1, pcn2, pcn3; - Word32 scaled_inv_L_frame; // Q8 + Q23 - - SWITCH( st->L_frame ) - { - case 80: - scaled_inv_L_frame = 26843545; // 1/80 in Q31 - move32(); - BREAK; - case 160: - scaled_inv_L_frame = 13421773; // 1/160 in Q31 - move32(); - BREAK; - case 256: - scaled_inv_L_frame = 8388608; // 1/256 in Q31 - move32(); - BREAK; - case 320: - scaled_inv_L_frame = 6710886; // 1/320 in Q31 - move32(); - BREAK; - case 512: - scaled_inv_L_frame = 4194304; // 1/512 in Q31 - move32(); - BREAK; - case 640: - scaled_inv_L_frame = 3355443; // 1/640 in Q31 - move32(); - BREAK; - case 960: - scaled_inv_L_frame = 2236962; // 1/80 in Q31 - move32(); - BREAK; - default: - scaled_inv_L_frame = 0; - move32(); - } - - nb_subfr = shr( st->L_frame, 6 ); - test(); - IF( GT_16( st->clas_dec, UNVOICED_CLAS ) && ( st->element_mode != EVS_MONO ) ) - { - pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( st->old_pitch_buf_fx[nb_subfr], st->old_pitch_buf_fx[nb_subfr + 1] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn1 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn1 = L_max( L_min( pcn1, 4096 ), 0 ); // 4096 = 1 in Q12 - - pc = L_abs( L_sub( L_add( pitch_buf[nb_subfr - 1], pitch_buf[nb_subfr - 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn2 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn2 = L_max( L_min( pcn2, 4096 ), 0 ); // 4096 = 1 in Q12 - - pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn3 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn3 = L_max( L_min( pcn3, 4096 ), 0 ); // 4096 = 1 in Q12 - - IF( LT_32( L_add( pcn1, L_add( pcn2, pcn3 ) ), 10240 /*2.5f in Q12*/ ) ) - { - st->hBPF->psf_att_fx = 13107; //.4 in Q15 - move16(); /*Q15*/ - set16_fx( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); - } - } - - return; -} diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index c11e30c93..7d2be2c52 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -6,6 +6,7 @@ #include #include "options.h" /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "rom_dec.h" /* Static table prototypes */ @@ -17,6 +18,9 @@ #define NBPSF_L_EXTRA 120 #define BPF_STOP_STOPBAND_16 16 +#define K_PC_DEC_FX -1170 /* -0.0357f in Q15 */ +#define K_PC_DEC_FX32 -76665166 /* -0.0357f in Q31 */ +#define C_PC_DEC_FX 6583 /*in Q8*/ /*---------------------------------------------------------------------* * Local function prototypes @@ -889,6 +893,246 @@ void addBassPostFilter_fx( return; } +/*---------------------------------------------------------------------* + * addBassPostFilter() + * + * Add BPF component in cldfb domain + *---------------------------------------------------------------------*/ + + +void addBassPostFilter_ivas_fx( + const Word32 *harm_timeIn_fx, // Qx + const Word16 samplesToProcess, + Word32 **rAnalysis_fx, // Qx - 5 + Word32 **iAnalysis_fx, // Qx - 5 + HANDLE_CLDFB_FILTER_BANK cldfb ) +{ + Word32 *tmp_R_fx[CLDFB_NO_COL_MAX]; + Word32 *tmp_I_fx[CLDFB_NO_COL_MAX]; + Word32 cldfbBufferReal_fx[CLDFB_NO_COL_MAX][20]; + Word32 cldfbBufferImag_fx[CLDFB_NO_COL_MAX][20]; + Word16 i, b; + Word16 maxBand; + const Word32 *weights_fx; + Word16 nCol = cldfb->no_col; + move16(); + Word16 nColToProcess = nCol; + move16(); + Word16 nChan = cldfb->no_channels; + move16(); + IF( GT_16( samplesToProcess, -1 ) ) + { + nColToProcess = idiv1616( sub( add( samplesToProcess, cldfb->no_channels ), 1 ), cldfb->no_channels ); + move16(); + } + + assert( nCol == 16 ); + + weights_fx = bpf_weights_16_ivas_fx_32; + + IF( GT_16( nChan, BPF_STOP_STOPBAND_16 ) ) + { + maxBand = BPF_STOP_STOPBAND_16; + move16(); + } + ELSE + { + maxBand = nChan; + move16(); + } + + FOR( i = 0; i < nColToProcess; i++ ) + { + tmp_R_fx[i] = cldfbBufferReal_fx[i]; + tmp_I_fx[i] = cldfbBufferImag_fx[i]; + } + + cldfbAnalysis_ivas_fx( harm_timeIn_fx, tmp_R_fx, tmp_I_fx, samplesToProcess, cldfb ); + + /* now do the subtraction */ + FOR( i = 0; i < nColToProcess; i++ ) + { + /* loop over low frequency bands */ + FOR( b = 0; b < maxBand; b++ ) + { + rAnalysis_fx[i][b] = Msub_32_32( rAnalysis_fx[i][b], tmp_R_fx[i][b], weights_fx[b] ); // Qx - 6 + move32(); + iAnalysis_fx[i][b] = Msub_32_32( iAnalysis_fx[i][b], tmp_I_fx[i][b], weights_fx[b] ); // Qx - 6 + move32(); + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * res_bpf_adapt_ivas_fx() + * + * Analyze BPF output and decide if it should be applied on DFT stereo + * residual signal + *---------------------------------------------------------------------*/ + +/*! r: Decision to enable or disable BPF on DFT stereo residual */ +Word16 res_bpf_adapt_ivas_fx( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ + const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ + Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer Q12 */ + Word16 q_res ) +{ + Word32 error_nrg; + Word32 tmp; + Word32 res_hb_nrg; + Word16 bpf_error_ratio; + Word16 res_bpf_flag; + Word16 i; + Word16 i_start; + Word16 i_end; + Word16 bw_inv; + Word64 W_tmp; + + IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) + { + i_start = 39; + move16(); + i_end = 64; + move16(); + bw_inv = 1311; + move16(); /* 1/(64 - 39) in Q15 */ + } + ELSE + { + i_start = 28; + move16(); + i_end = 40; + move16(); + bw_inv = 2720; + move16(); /* 1/(40 - 28) in Q15*/ + } + + /* Measure energy of high frequency band in MDCT domain */ + res_hb_nrg = L_deposit_l( 0 ); + W_tmp = W_deposit32_l( 0 ); + FOR( i = i_start; i < i_end; i++ ) + { + W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); + } + + res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 + res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 + res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); + hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; + move32(); + + /* Measure energy of discontinuities at subframe boundaries */ + error_nrg = 0; + move32(); + FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) + { + tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); + error_nrg = Madd_32_32( error_nrg, tmp, tmp ); + hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[( i + ( STEREO_DFT_L_SUBFR_8k - 1 ) )]; + move32(); + } + error_nrg = L_shl( error_nrg, 1 ); // Q0 + error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ + /* Form decision variable and apply limit */ + IF( LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ) + { + Word16 temp; + bpf_error_ratio = BASOP_Util_Divide3232_Scale( error_nrg, res_hb_nrg, &temp ); + bpf_error_ratio = shl( bpf_error_ratio, sub( 13, sub( 15, temp ) ) ); + } + ELSE + { + bpf_error_ratio = ONE_IN_Q14; // Q13 + move16(); + } + bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( ( MAX_16 - STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); + hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; + move16(); + + res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q13 ); + move16(); + + return res_bpf_flag; +} + +void bpf_pitch_coherence_ivas_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 pitch_buf[] /* i : pitch for every subfr [0,1,2,3] Q20 */ +) +{ + Word16 nb_subfr; + Word32 pc, pcn1, pcn2, pcn3; + Word32 scaled_inv_L_frame; // Q8 + Q23 + + SWITCH( st->L_frame ) + { + case 80: + scaled_inv_L_frame = 26843545; // 1/80 in Q31 + move32(); + BREAK; + case 160: + scaled_inv_L_frame = 13421773; // 1/160 in Q31 + move32(); + BREAK; + case 256: + scaled_inv_L_frame = 8388608; // 1/256 in Q31 + move32(); + BREAK; + case 320: + scaled_inv_L_frame = 6710886; // 1/320 in Q31 + move32(); + BREAK; + case 512: + scaled_inv_L_frame = 4194304; // 1/512 in Q31 + move32(); + BREAK; + case 640: + scaled_inv_L_frame = 3355443; // 1/640 in Q31 + move32(); + BREAK; + case 960: + scaled_inv_L_frame = 2236962; // 1/80 in Q31 + move32(); + BREAK; + default: + scaled_inv_L_frame = 0; + move32(); + } + + nb_subfr = shr( st->L_frame, 6 ); + test(); + IF( GT_16( st->clas_dec, UNVOICED_CLAS ) && ( st->element_mode != EVS_MONO ) ) + { + pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( st->old_pitch_buf_fx[nb_subfr], st->old_pitch_buf_fx[nb_subfr + 1] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn1 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn1 = L_max( L_min( pcn1, 4096 ), 0 ); // 4096 = 1 in Q12 + + pc = L_abs( L_sub( L_add( pitch_buf[nb_subfr - 1], pitch_buf[nb_subfr - 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn2 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn2 = L_max( L_min( pcn2, 4096 ), 0 ); // 4096 = 1 in Q12 + + pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn3 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn3 = L_max( L_min( pcn3, 4096 ), 0 ); // 4096 = 1 in Q12 + + IF( LT_32( L_add( pcn1, L_add( pcn2, pcn3 ) ), 10240 /*2.5f in Q12*/ ) ) + { + st->hBPF->psf_att_fx = 13107; //.4 in Q15 + move16(); /*Q15*/ + set16_fx( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); + } + } + + return; +} + + #ifdef ADD_BPF_ADAPT /*---------------------------------------------------------------------* * res_bpf_adapt() diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c deleted file mode 100644 index 37c397bbf..000000000 --- a/lib_dec/core_dec_init.c +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "stat_com.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -/*-----------------------------------------------------------------------* - * open_decoder_LPD() - * - * Initialization of state variables - *-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * tcxltp_dec_init() - * - * Initialization TCX-LTP handle - *-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * reset_tcx_overl_buf() - * - * Reset TCX core overlap buffers - *-----------------------------------------------------------------------*/ - -void reset_tcx_overl_buf_fx( - TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ -) -{ - set16_fx( hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_old_syn_Overl = 0; - move16(); - set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl_TDAC = 0; - move16(); - set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl = 0; - move16(); - set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl_TDACFB = 0; - move16(); - return; -} - -/*-----------------------------------------------------------------------* - * acelp_plc_mdct_transition() - * - * Prepare MDCT OLA memories in TCX/HQ after ACELP PLC - *-----------------------------------------------------------------------*/ diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 671dbfd2c..f649772b2 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -2191,3 +2191,29 @@ void open_decoder_LPD_ivas_fx( return; } + +/*-----------------------------------------------------------------------* + * reset_tcx_overl_buf() + * + * Reset TCX core overlap buffers + *-----------------------------------------------------------------------*/ + +void reset_tcx_overl_buf_fx( + TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ +) +{ + set16_fx( hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_old_syn_Overl = 0; + move16(); + set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl_TDAC = 0; + move16(); + set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl = 0; + move16(); + set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl_TDACFB = 0; + move16(); + return; +} + diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c deleted file mode 100644 index aa04a70cb..000000000 --- a/lib_dec/core_switching_dec.c +++ /dev/null @@ -1,1076 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" - -#include "ivas_prot_fx.h" -#include "debug.h" -/*---------------------------------------------------------------------* - * Local prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * core_switching_pre_dec() - * - * Preprocessing/preparation for ACELP/HQ core switching - *---------------------------------------------------------------------*/ -ivas_error core_switching_pre_dec_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word16 output_frame, /* i : frame length */ - const Word32 last_core_brate_st0, /* i : channel 0 last core bitrate */ - const Word16 nchan_out, /* i : number of output channels */ - const Word16 last_element_mode, /* i : last_element_mode */ - const Word32 last_element_brate, /* i : last element bitrate */ - Word16 Q_old_synthFB, - Word16 *Q_olapBufferSynth, - Word16 *Q_olapBufferSynth2 ) -{ - Word32 tmp_fx; /*Q-12*/ - Word16 i, oldLenClasBuff, newLenClasBuff; - ivas_error error; - Word16 exp = 25; - move16(); - error = IVAS_ERR_OK; - move32(); - - /* Codec mode switching */ - test(); - test(); - test(); - IF( EQ_16( st->last_codec_mode, MODE2 ) || ( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) - { - st->mem_deemph_fx = st->syn[M]; - move16(); - set16_fx( st->agc_mem_fx, 0, 2 ); - Scale_sig( &( st->mem_deemph_fx ), 1, st->Q_syn ); /* Brings mem_deemph to Qsyn */ - - Copy_Scale_sig( st->mem_syn2_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); /*Q-1*/ - - st->bpf_off = 1; - move16(); - IF( st->hPFstat != NULL ) - { - Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ - Scale_sig( st->hPFstat->mem_res2, DECMEM_RES2, st->Q_syn ); /* NB post_filter mem , Q_syn*/ - Scale_sig( st->hPFstat->mem_stp, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ - set16_fx( st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ - } - IF( st->hBPF != NULL ) - { - st->hBPF->pst_lp_ener_fx = round_fx( L_shl( Mpy_32_16_1( st->lp_error_ener, 0x6054 ), 2 + 8 ) ); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ - st->hBPF->pst_mem_deemp_err_fx = 0; - move16(); - move16(); - } - st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); // Q(23+1-16)->Q8 - move16(); - - /* reset old HB synthesis buffer */ - IF( EQ_16( st->last_L_frame, L_FRAME ) ) - { - st->old_bwe_delay = NS2SA_FX2( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); - } - ELSE - { - st->old_bwe_delay = NS2SA_FX2( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); - } - move16(); - set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); - - test(); - IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) - { -#ifdef MSAN_FIX - st->hBWE_TD->prev_hb_synth_fx_exp = 31; - move16(); -#endif // MSAN_FIX - /* reset BWE memories */ - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* reset upd_cnt */ - st->upd_cnt = MAX_UPD_CNT; - move16(); - - st->igf = 0; - move16(); - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - IF( st->hHQ_core != NULL ) - { - set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); - set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); - - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - IF( GT_32( st->output_Fs, 16000 ) ) - { - set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); - } - - /* pre-echo */ - st->hHQ_core->pastpre = 0; - move16(); - } - - /* reset the GSC pre echo energy threshold in case of switching */ - if ( st->hGSCDec != NULL ) - { - st->hGSCDec->Last_frame_ener_fx = MAX_32; - move32(); - } - - test(); - IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) - { - IF( st->element_mode == EVS_MONO ) - { - st->last_core = HQ_CORE; - move16(); - - Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 - } - - IF( st->hHQ_core != NULL ) - { - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - } - } - - IF( st->prev_bfi != 0 ) - { - Word16 delay_comp; - - /*switch off Hq Voicing as it was not updated in MODE2*/ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->oldHqVoicing = 0; - st->hHQ_core->HqVoicing = 0; - move16(); - move16(); - } - - delay_comp = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - /*TODO To be tested:control not entering the block*/ - test(); - test(); - IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) - { - /*TODO None of the test dtreams are entering this block,hence enabled assert(0)*/ - assert( 0 ); - Word32 *realBuffer_fx[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer_fx[CLDFB_NO_COL_MAX_SWITCH]; - Word32 realBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; - Word32 syn_Overl_fx[320]; - Word32 fer_samples_fx[960]; - Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->syn_Overl, syn_Overl_fx, 320, 15 ); - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->fer_samples_fx, fer_samples_fx, 960, 15 ); - - - FOR( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) - { - set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer_fx[i] = realBufferTmp_fx[i]; - imagBuffer_fx[i] = imagBufferTmp_fx[i]; - } - - /* CLDFB analysis of the synthesis at internal sampling rate */ - IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbAna ) ), IVAS_ERR_OK ) ) - { - return error; - } - - cldfbAnalysis_ivas_fx( syn_Overl_fx, realBuffer_fx, imagBuffer_fx, delay_comp, st->cldfbAna ); - cldfb_restore_memory_ivas_fx( st->cldfbAna ); /*Assuming Q10*/ - - /* CLDFB synthesis of the combined signal */ - IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbSyn ) ), IVAS_ERR_OK ) ) - { - return error; - } - - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); - cldfb_restore_memory_ivas_fx( st->cldfbSyn ); - Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); - Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); - } - - test(); - test(); - IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) - { - lerp( st->hTcxDec->syn_Overl, st->hHQ_core->fer_samples_fx + delay_comp, shr( output_frame, 1 ), shr( st->last_L_frame, 1 ) ); - /*Set to zero the remaining part*/ - set16_fx( st->hHQ_core->fer_samples_fx + delay_comp + output_frame / 2, 0, sub( shr( output_frame, 1 ), delay_comp ) ); - } - } - - st->use_acelp_preq = 0; - st->reset_mem_AR = 0; - move16(); - move16(); - } - - /*FEC*/ - IF( LE_16( st->L_frame, L_FRAME16k ) ) - { - test(); - IF( LE_16( st->last_L_frame, L_FRAME16k ) && NE_16( st->core, HQ_CORE ) ) - { - IF( NE_16( st->L_frame, st->last_L_frame ) ) - { - IF( GT_16( st->L_frame, st->last_L_frame ) ) - { - oldLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->last_L_frame, st->L_frame ) ); - newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - move16(); - } - ELSE - { - oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - move16(); - newLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->L_frame, st->last_L_frame ) ); - } - lerp( &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); - } - } - ELSE - { - set16_fx( st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); - } - } - - /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores - within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) ) ) - { - st->last_ppp_mode_dec = 0; - st->last_nelp_mode_dec = 0; - move16(); - move16(); - } - - /* Handle state reset of stat_noise_uv_mod memory */ - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || LE_32( st->last_total_brate, PPP_NELP_2k80 ) ) ) - { - st->act_count = 3; - st->uv_count = 0; - move16(); - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && EQ_16( st->last_core, HQ_CORE ) ) || ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( nchan_out, 2 ) && - NE_32( st->core_brate, SID_2k40 ) && ( st->core_brate != FRAME_NO_DATA ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) ) ) - { - test(); - if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - st->hPFstat->reset = 1; - move16(); - } - - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Copy( TRWB2_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB2_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( TRWB2_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( TRWB2_Ave_fx, st->lsf_adaptive_mean_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_16k ); - } - ELSE - { - Copy( TRWB_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( TRWB_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( TRWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_12k8 ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( nchan_out, 2 ) && GT_32( st->core_brate, SID_2k40 ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) && st->hTcxDec != NULL ) - { - /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ - set16_fx( st->hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); - set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); - set16_fx( st->agc_mem_fx, 0, 2 ); - } - st->mem_deemph_fx = 0; - move16(); - IF( !st->last_con_tcx ) - { - set16_fx( st->mem_syn2_fx, 0, M ); - } - set16_fx( st->mem_syn1_fx, 0, M ); - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* Reset ACELP parameters */ - set16_fx( st->mem_MA_fx, 0, M ); - - IF( EQ_32( st->sr_core, INT_FS_16k ) ) - { - Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); - } - ELSE - { - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - } - - st->tilt_code_fx = 0; - st->gc_threshold_fx = 0; - st->dm_fx.prev_gain_code = 0; - st->dm_fx.prev_state = 0; - move16(); - move32(); - move32(); - move16(); - set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); - - st->last_coder_type = GENERIC; - move16(); - - fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ - st->lp_gainp_fx = 0; - move16(); - st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ - move16(); - st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ - move16(); - - st->last_voice_factor_fx = 0; - st->Last_GSC_noisy_speech_flag = 0; - move16(); - move16(); - - /* reset CLDFB memories */ - cldfb_reset_memory_fx( st->cldfbAna ); - cldfb_reset_memory_fx( st->cldfbBPF ); - cldfb_reset_memory_fx( st->cldfbSyn ); - - /* reset TBE memories */ - test(); - test(); - IF( !st->last_con_tcx && !( ( EQ_16( st->last_core, HQ_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) - { - set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); - } - ELSE IF( LT_16( st->L_frame, L_FRAME16k ) ) - { - /* resample from 16kHz to 12.8kHZ */ - synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); - } - - IF( st->hBWE_TD != NULL ) - { - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - } - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - } - - test(); - test(); - test(); - IF( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) ) - { - IF( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - } - - st->tilt_code_fx = 0; - st->gc_threshold_fx = 0; - st->dm_fx.prev_gain_code = 0; - st->dm_fx.prev_state = 0; - move16(); - move32(); - move32(); - move16(); - set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); - st->last_coder_type = GENERIC; - move16(); - fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ - - st->lp_gainp_fx = 0; - move16(); - st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ - move16(); - st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ - move16(); - - st->last_voice_factor_fx = 0; - st->Last_GSC_noisy_speech_flag = 0; - move16(); - move16(); - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - test(); - test(); - test(); - IF( EQ_16( nchan_out, 1 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && LE_32( st->element_brate, IVAS_24k4 ) && GT_32( last_element_brate, IVAS_24k4 ) ) - { - /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ - Word16 offset; - offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); - Word32 *old_synthFB_fx; - IF( ( old_synthFB_fx = (Word32 *) malloc( st->hTcxDec->old_synth_lenFB * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); - } -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#else - Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#endif - Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); - st->cldfbAna->Q_cldfb_state = Q10; - move16(); - IF( old_synthFB_fx ) - free( old_synthFB_fx ); - } - } - - test(); - test(); - test(); - test(); - IF( EQ_16( st->core, HQ_CORE ) && ( ( st->last_core == ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) || ( ( ( st->element_mode != EVS_MONO ) ) && ( NE_16( st->last_core, HQ_CORE ) ) ) ) ) - { - set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); - set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); - - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - IF( GT_32( st->output_Fs, 16000 ) ) - { - set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); - } - - IF( st->element_mode != EVS_MONO ) - { - /* Estimate mem_env_delta to reinit env_stab */ - tmp_fx = L_max( 0, L_add( ENV_STAB_EST1_FX, L_add( Mult_32_16( st->stab_fac_smooth_lt_fx, ENV_STAB_EST2_FX ), Mult_32_16( st->log_energy_diff_lt_fx, ENV_STAB_EST3_FX ) ) ) ); /*Q12*/ - - st->hHQ_core->mem_env_delta = extract_l( L_min( MAX16B, tmp_fx ) ); /* Convert to Q12 and handle saturation */ - move16(); - test(); - IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) - { - set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); - set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); - } - - st->hHQ_core->no_att_hangover = 0; - move16(); - st->hHQ_core->energy_lt_fx = 2457600; /*300.0f Q13*/ - move32(); - set16_fx( st->hHQ_core->old_is_transient, 0, 3 ); - set16_fx( st->hHQ_core->prev_noise_level_fx, 0, 2 ); - st->hHQ_core->prev_R = 0; - move16(); - set16_fx( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); - st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; - st->hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ - move16(); - move16(); - set16_fx( st->hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); - } - ELSE - { - set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); - } - } - - /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->pastpre = sub( st->hHQ_core->pastpre, 1 ); - move16(); - IF( st->hHQ_core->pastpre < 0 ) - { - reset_preecho_dec_fx( st->hHQ_core ); - } - } - test(); - IF( st->core_brate == FRAME_NO_DATA ) - { - st->VAD = 0; - st->m_frame_type = ZERO_FRAME; - } - ELSE IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, SID_1k75 ) ) - { - st->VAD = 0; - st->m_frame_type = SID_FRAME; - } - ELSE - { - st->VAD = 1; - st->m_frame_type = ACTIVE_FRAME; - } - - move16(); - move16(); - /*switch on CNA on active frames*/ - IF( ( st->element_mode == EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ - { - test(); - test(); - test(); - test(); - test(); - test(); - IF( st->VAD && ( ( NE_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, CNA_MAX_BRATE ) ) || ( EQ_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, ACELP_8k85 ) ) ) ) - { - st->flag_cna = 1; - move16(); - } - ELSE IF( st->VAD || ( EQ_16( st->cng_type, FD_CNG ) && EQ_16( st->L_frame, L_FRAME16k ) ) ) - { - st->flag_cna = 0; - move16(); - } - } - - if ( EQ_16( st->core, AMR_WB_CORE ) ) - { - st->cng_type = LP_CNG; - move16(); - } - - /* Reconfigure CNG */ - test(); - test(); - test(); - test(); - IF( st->hFdCngDec && ( NE_16( st->last_L_frame, st->L_frame ) || NE_16( st->hFdCngDec->hFdCngCom->frameSize, st->L_frame ) || ( st->ini_frame == 0 ) || NE_16( st->bwidth, st->last_bwidth ) ) ) - { - /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ - IF( NE_16( st->core, AMR_WB_CORE ) ) - { - test(); - IF( EQ_16( st->rf_flag, 1 ) && EQ_32( st->total_brate, ACELP_13k20 ) ) - { - configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, ACELP_9k60, st->L_frame, st->last_L_frame, st->element_mode ); - } - ELSE - { - configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); - } - } - ELSE - { - configureFdCngDec_ivas_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); - - if ( st->VAD ) - { - st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; - move32(); - } - } - test(); - test(); - IF( NE_16( st->last_L_frame, st->L_frame ) && LE_16( st->L_frame, L_FRAME16k ) && LE_16( st->last_L_frame, L_FRAME16k ) ) - { - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); - } - - L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth2 ); - - test(); - IF( LE_32( st->total_brate, SID_2k40 ) && LE_32( st->last_total_brate, SID_2k40 ) ) - { - L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth ); - - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], (Word16) 20480 /* 0.6250f in Q15 */ ); - move32(); - } - } - ELSE - { - FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( L_shl( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], 1 ), (Word16) 26214 /* 1.6f in Q14 */ ); - move32(); - } - } - } - } - } - - return error; -} -/*---------------------------------------------------------------------* - * core_switching_hq_prepare_dec() - * - * Preprocessing in the first HQ frame after ACELP frame - * Modify bit allocation for HQ core by removing ACELP subframe budget - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bandwidth_switching_detect() - * - * Classification for band-width switching - *---------------------------------------------------------------------*/ - -void bandwidth_switching_detect_ivas_fx( - Decoder_State *st_fx /* i/o: encoder state structure */ -) -{ - test(); - test(); - IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ - st_fx->prev_bws_cnt = 0; - st_fx->bws_cnt = 0; - st_fx->bws_cnt1 = 0; - move16(); - move16(); - move16(); - - return; - } - /* update band-width switching counter */ - test(); - test(); - test(); - test(); - IF( GE_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) ) - { - st_fx->bws_cnt1 = 0; - move16(); - } - ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) && ( st_fx->last_low_rate_mode == 0 ) ) - { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); - move16(); - } - ELSE IF( st_fx->bws_cnt1 > 0 ) - { - IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt = 0; - move16(); - } - - IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt1 = 0; - move16(); - } - ELSE - { - IF( EQ_16( st_fx->bwidth, SWB ) ) - { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt1 = 0; - move16(); - } - } - } - - /* update band-width switching counter */ - test(); - test(); - test(); - IF( GE_16( st_fx->bws_cnt, N_WS2N_FRAMES ) ) - { - st_fx->bws_cnt = 0; - move16(); - } - ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) - { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); - move16(); - } - ELSE IF( st_fx->bws_cnt > 0 ) - { - IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt1 = 0; - move16(); - } - - IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt = 0; - move16(); - } - ELSE - { - IF( EQ_16( st_fx->bwidth, WB ) ) - { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt = 0; - move16(); - } - } - } - - return; -} - - -/*---------------------------------------------------------------------* - * bw_switching_pre_proc() - * - * Band-width switching pre-processing - *---------------------------------------------------------------------*/ -void ivas_bw_switching_pre_proc_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 nchan_out /* i : number of output channels */, - Word32 *old_syn_12k8_16k_fx, - Word16 Q, - Word16 Q_audio ) -{ - Word16 i; - Word32 syn_dct_fx[L_FRAME]; - - - Flag Overflow = 0; - move32(); - - IF( st->element_mode > EVS_MONO ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) && st->hBWE_FD != NULL && !( LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) ) - { - /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ - Word16 old_syn_12k8_16k_tmp_16fx[L_FRAME16k]; - Copy_Scale_sig_32_16( old_syn_12k8_16k_fx, old_syn_12k8_16k_tmp_16fx, st->L_frame, sub( -1, Q ) ); - st->tilt_wb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_syn_12k8_16k_tmp_16fx, -1, st->L_frame ), sub( Q, 8 ) ) ); // Q24+(Q-8) - 16 - move16(); - } - - return; - } - - - test(); - test(); - IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) - { - /*----------------------------------------------------------------------* - * Calculate tilt of the ACELP core synthesis - *----------------------------------------------------------------------*/ - - st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); - move16(); - /*-------------------------------------------------------------------------------* - * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis - *-------------------------------------------------------------------------------*/ - edct_fx( old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q ); - Word64 W_tmp = 0; - move64(); - Word32 tmp; - Word16 shift; - FOR( i = 0; i < L_FRAME / 2; i++ ) - { - W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); - tmp = W_extract_h( W_tmp ); - tmp = L_shr( tmp, 8 ); - - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); - move16(); - W_tmp = 0; - move64(); - FOR( ; i < L_FRAME; i++ ) - { - W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); - tmp = W_extract_h( W_tmp ); // Q = Q + shift - 32 - tmp = L_shr( tmp, 7 ); // divide by 128 - tmp = getSqrtWord32( tmp ); - st->enerLH_fx = tmp; - move32(); - st->enerLH_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); - move16(); - } - ELSE - { - IF( st->hHQ_core->old_is_transient[0] ) - { - Word32 tmp, L_tmp = 0; - move32(); - FOR( i = 0; i < 32; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - - L_tmp = 0; - move32(); - FOR( ; i < 64; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLH_fx = tmp; - move32(); - st->enerLH_fx_Q = Q_audio; - move16(); - } - ELSE - { - Word32 tmp, L_tmp = 0; - move32(); - FOR( i = 0; i < L_FRAME / 2; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - - L_tmp = 0; - move32(); - FOR( ; i < L_FRAME; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) - { - - st->prev_ener_shb_fx = 0; - move16(); - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); - } - } - ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) - { - st->attenu_fx = 3277; // 0.1f in Q15 - move16(); - } - - test(); - test(); - test(); - test(); - test(); - if ( EQ_16( st->last_core, HQ_CORE ) || ( ( st->last_core == ACELP_CORE ) && !( EQ_16( st->last_extl, WB_TBE ) || EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) && GT_32( st->core_brate, ACELP_8k00 ) ) ) - { - st->prev_fractive = 0; - move16(); - } - - return; -} -/*---------------------------------------------------------------------* - * core_switch_lb_upsamp() - * - * Resample HQ/TCX-LB to the output sampling rate (8/16/32/48 kHz) - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * smoothTransitionDtxToTcx() - * - * apply smoothing to the transition part for inactive to active transitions in DTX - *---------------------------------------------------------------------*/ - -#define TRANSITION_SMOOTHING_LEN_16k 15 -#define TRANSITION_SMOOTHING_LEN_32k 31 -#define TRANSITION_SMOOTHING_LEN_48k 47 diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index d654b3af4..caef9485b 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -2435,3 +2435,1012 @@ static void smoothTransitionDtxToTcx_fx( return; } + + +/*---------------------------------------------------------------------* + * core_switching_pre_dec() + * + * Preprocessing/preparation for ACELP/HQ core switching + *---------------------------------------------------------------------*/ +ivas_error core_switching_pre_dec_ivas_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 output_frame, /* i : frame length */ + const Word32 last_core_brate_st0, /* i : channel 0 last core bitrate */ + const Word16 nchan_out, /* i : number of output channels */ + const Word16 last_element_mode, /* i : last_element_mode */ + const Word32 last_element_brate, /* i : last element bitrate */ + Word16 Q_old_synthFB, + Word16 *Q_olapBufferSynth, + Word16 *Q_olapBufferSynth2 ) +{ + Word32 tmp_fx; /*Q-12*/ + Word16 i, oldLenClasBuff, newLenClasBuff; + ivas_error error; + Word16 exp = 25; + move16(); + error = IVAS_ERR_OK; + move32(); + + /* Codec mode switching */ + test(); + test(); + test(); + IF( EQ_16( st->last_codec_mode, MODE2 ) || ( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) + { + st->mem_deemph_fx = st->syn[M]; + move16(); + set16_fx( st->agc_mem_fx, 0, 2 ); + Scale_sig( &( st->mem_deemph_fx ), 1, st->Q_syn ); /* Brings mem_deemph to Qsyn */ + + Copy_Scale_sig( st->mem_syn2_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); /*Q-1*/ + + st->bpf_off = 1; + move16(); + IF( st->hPFstat != NULL ) + { + Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ + Scale_sig( st->hPFstat->mem_res2, DECMEM_RES2, st->Q_syn ); /* NB post_filter mem , Q_syn*/ + Scale_sig( st->hPFstat->mem_stp, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ + set16_fx( st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ + } + IF( st->hBPF != NULL ) + { + st->hBPF->pst_lp_ener_fx = round_fx( L_shl( Mpy_32_16_1( st->lp_error_ener, 0x6054 ), 2 + 8 ) ); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ + st->hBPF->pst_mem_deemp_err_fx = 0; + move16(); + move16(); + } + st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); // Q(23+1-16)->Q8 + move16(); + + /* reset old HB synthesis buffer */ + IF( EQ_16( st->last_L_frame, L_FRAME ) ) + { + st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + ELSE + { + st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + move16(); + set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); + + test(); + IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) + { +#ifdef MSAN_FIX + st->hBWE_TD->prev_hb_synth_fx_exp = 31; + move16(); +#endif // MSAN_FIX + /* reset BWE memories */ + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* reset upd_cnt */ + st->upd_cnt = MAX_UPD_CNT; + move16(); + + st->igf = 0; + move16(); + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + IF( st->hHQ_core != NULL ) + { + set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + IF( GT_32( st->output_Fs, 16000 ) ) + { + set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } + + /* pre-echo */ + st->hHQ_core->pastpre = 0; + move16(); + } + + /* reset the GSC pre echo energy threshold in case of switching */ + if ( st->hGSCDec != NULL ) + { + st->hGSCDec->Last_frame_ener_fx = MAX_32; + move32(); + } + + test(); + IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) + { + IF( st->element_mode == EVS_MONO ) + { + st->last_core = HQ_CORE; + move16(); + + Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 + } + + IF( st->hHQ_core != NULL ) + { + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + } + } + + IF( st->prev_bfi != 0 ) + { + Word16 delay_comp; + + /*switch off Hq Voicing as it was not updated in MODE2*/ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->oldHqVoicing = 0; + st->hHQ_core->HqVoicing = 0; + move16(); + move16(); + } + + delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); + /*TODO To be tested:control not entering the block*/ + test(); + test(); + IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) + { + /*TODO None of the test dtreams are entering this block,hence enabled assert(0)*/ + assert( 0 ); + Word32 *realBuffer_fx[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer_fx[CLDFB_NO_COL_MAX_SWITCH]; + Word32 realBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; + Word32 syn_Overl_fx[320]; + Word32 fer_samples_fx[960]; + Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->syn_Overl, syn_Overl_fx, 320, 15 ); + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->fer_samples_fx, fer_samples_fx, 960, 15 ); + + + FOR( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) + { + set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + realBuffer_fx[i] = realBufferTmp_fx[i]; + imagBuffer_fx[i] = imagBufferTmp_fx[i]; + } + + /* CLDFB analysis of the synthesis at internal sampling rate */ + IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbAna ) ), IVAS_ERR_OK ) ) + { + return error; + } + + cldfbAnalysis_ivas_fx( syn_Overl_fx, realBuffer_fx, imagBuffer_fx, delay_comp, st->cldfbAna ); + cldfb_restore_memory_ivas_fx( st->cldfbAna ); /*Assuming Q10*/ + + /* CLDFB synthesis of the combined signal */ + IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbSyn ) ), IVAS_ERR_OK ) ) + { + return error; + } + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); + cldfb_restore_memory_ivas_fx( st->cldfbSyn ); + Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); + Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); + } + + test(); + test(); + IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) + { + lerp( st->hTcxDec->syn_Overl, st->hHQ_core->fer_samples_fx + delay_comp, shr( output_frame, 1 ), shr( st->last_L_frame, 1 ) ); + /*Set to zero the remaining part*/ + set16_fx( st->hHQ_core->fer_samples_fx + delay_comp + output_frame / 2, 0, sub( shr( output_frame, 1 ), delay_comp ) ); + } + } + + st->use_acelp_preq = 0; + st->reset_mem_AR = 0; + move16(); + move16(); + } + + /*FEC*/ + IF( LE_16( st->L_frame, L_FRAME16k ) ) + { + test(); + IF( LE_16( st->last_L_frame, L_FRAME16k ) && NE_16( st->core, HQ_CORE ) ) + { + IF( NE_16( st->L_frame, st->last_L_frame ) ) + { + IF( GT_16( st->L_frame, st->last_L_frame ) ) + { + oldLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->last_L_frame, st->L_frame ) ); + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + } + ELSE + { + oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + newLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->L_frame, st->last_L_frame ) ); + } + lerp( &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); + } + } + ELSE + { + set16_fx( st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) ) ) + { + st->last_ppp_mode_dec = 0; + st->last_nelp_mode_dec = 0; + move16(); + move16(); + } + + /* Handle state reset of stat_noise_uv_mod memory */ + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || LE_32( st->last_total_brate, PPP_NELP_2k80 ) ) ) + { + st->act_count = 3; + st->uv_count = 0; + move16(); + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && EQ_16( st->last_core, HQ_CORE ) ) || ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( nchan_out, 2 ) && + NE_32( st->core_brate, SID_2k40 ) && ( st->core_brate != FRAME_NO_DATA ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) ) ) + { + test(); + if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + st->hPFstat->reset = 1; + move16(); + } + + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( TRWB2_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB2_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( TRWB2_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( TRWB2_Ave_fx, st->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( TRWB_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( TRWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_12k8 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( nchan_out, 2 ) && GT_32( st->core_brate, SID_2k40 ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) && st->hTcxDec != NULL ) + { + /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ + set16_fx( st->hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); + set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); + set16_fx( st->agc_mem_fx, 0, 2 ); + } + st->mem_deemph_fx = 0; + move16(); + IF( !st->last_con_tcx ) + { + set16_fx( st->mem_syn2_fx, 0, M ); + } + set16_fx( st->mem_syn1_fx, 0, M ); + if ( st->hBWE_TD != NULL ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* Reset ACELP parameters */ + set16_fx( st->mem_MA_fx, 0, M ); + + IF( EQ_32( st->sr_core, INT_FS_16k ) ) + { + Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + } + + st->tilt_code_fx = 0; + st->gc_threshold_fx = 0; + st->dm_fx.prev_gain_code = 0; + st->dm_fx.prev_state = 0; + move16(); + move32(); + move32(); + move16(); + set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); + + st->last_coder_type = GENERIC; + move16(); + + fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ + st->lp_gainp_fx = 0; + move16(); + st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ + move16(); + st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ + move16(); + + st->last_voice_factor_fx = 0; + st->Last_GSC_noisy_speech_flag = 0; + move16(); + move16(); + + /* reset CLDFB memories */ + cldfb_reset_memory_fx( st->cldfbAna ); + cldfb_reset_memory_fx( st->cldfbBPF ); + cldfb_reset_memory_fx( st->cldfbSyn ); + + /* reset TBE memories */ + test(); + test(); + IF( !st->last_con_tcx && !( ( EQ_16( st->last_core, HQ_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) + { + set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); + } + ELSE IF( LT_16( st->L_frame, L_FRAME16k ) ) + { + /* resample from 16kHz to 12.8kHZ */ + synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); + } + + IF( st->hBWE_TD != NULL ) + { + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + } + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + } + + test(); + test(); + test(); + IF( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) ) + { + IF( st->hBWE_TD != NULL ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + } + + st->tilt_code_fx = 0; + st->gc_threshold_fx = 0; + st->dm_fx.prev_gain_code = 0; + st->dm_fx.prev_state = 0; + move16(); + move32(); + move32(); + move16(); + set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); + st->last_coder_type = GENERIC; + move16(); + fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ + + st->lp_gainp_fx = 0; + move16(); + st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ + move16(); + st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ + move16(); + + st->last_voice_factor_fx = 0; + st->Last_GSC_noisy_speech_flag = 0; + move16(); + move16(); + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + test(); + test(); + test(); + IF( EQ_16( nchan_out, 1 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && LE_32( st->element_brate, IVAS_24k4 ) && GT_32( last_element_brate, IVAS_24k4 ) ) + { + /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ + Word16 offset; + offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + Word32 *old_synthFB_fx; + IF( ( old_synthFB_fx = (Word32 *) malloc( st->hTcxDec->old_synth_lenFB * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); + } +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 +#else + Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 +#endif + Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); + st->cldfbAna->Q_cldfb_state = Q10; + move16(); + IF( old_synthFB_fx ) + free( old_synthFB_fx ); + } + } + + test(); + test(); + test(); + test(); + IF( EQ_16( st->core, HQ_CORE ) && ( ( st->last_core == ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) || ( ( ( st->element_mode != EVS_MONO ) ) && ( NE_16( st->last_core, HQ_CORE ) ) ) ) ) + { + set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + IF( GT_32( st->output_Fs, 16000 ) ) + { + set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } + + IF( st->element_mode != EVS_MONO ) + { + /* Estimate mem_env_delta to reinit env_stab */ + tmp_fx = L_max( 0, L_add( ENV_STAB_EST1_FX, L_add( Mult_32_16( st->stab_fac_smooth_lt_fx, ENV_STAB_EST2_FX ), Mult_32_16( st->log_energy_diff_lt_fx, ENV_STAB_EST3_FX ) ) ) ); /*Q12*/ + + st->hHQ_core->mem_env_delta = extract_l( L_min( MAX16B, tmp_fx ) ); /* Convert to Q12 and handle saturation */ + move16(); + test(); + IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) + { + set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); + set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); + } + + st->hHQ_core->no_att_hangover = 0; + move16(); + st->hHQ_core->energy_lt_fx = 2457600; /*300.0f Q13*/ + move32(); + set16_fx( st->hHQ_core->old_is_transient, 0, 3 ); + set16_fx( st->hHQ_core->prev_noise_level_fx, 0, 2 ); + st->hHQ_core->prev_R = 0; + move16(); + set16_fx( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); + st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; + st->hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ + move16(); + move16(); + set16_fx( st->hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); + } + ELSE + { + set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); + set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + } + } + + /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->pastpre = sub( st->hHQ_core->pastpre, 1 ); + move16(); + IF( st->hHQ_core->pastpre < 0 ) + { + reset_preecho_dec_fx( st->hHQ_core ); + } + } + test(); + IF( st->core_brate == FRAME_NO_DATA ) + { + st->VAD = 0; + st->m_frame_type = ZERO_FRAME; + } + ELSE IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, SID_1k75 ) ) + { + st->VAD = 0; + st->m_frame_type = SID_FRAME; + } + ELSE + { + st->VAD = 1; + st->m_frame_type = ACTIVE_FRAME; + } + + move16(); + move16(); + /*switch on CNA on active frames*/ + IF( ( st->element_mode == EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ + { + test(); + test(); + test(); + test(); + test(); + test(); + IF( st->VAD && ( ( NE_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, CNA_MAX_BRATE ) ) || ( EQ_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, ACELP_8k85 ) ) ) ) + { + st->flag_cna = 1; + move16(); + } + ELSE IF( st->VAD || ( EQ_16( st->cng_type, FD_CNG ) && EQ_16( st->L_frame, L_FRAME16k ) ) ) + { + st->flag_cna = 0; + move16(); + } + } + + if ( EQ_16( st->core, AMR_WB_CORE ) ) + { + st->cng_type = LP_CNG; + move16(); + } + + /* Reconfigure CNG */ + test(); + test(); + test(); + test(); + IF( st->hFdCngDec && ( NE_16( st->last_L_frame, st->L_frame ) || NE_16( st->hFdCngDec->hFdCngCom->frameSize, st->L_frame ) || ( st->ini_frame == 0 ) || NE_16( st->bwidth, st->last_bwidth ) ) ) + { + /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ + IF( NE_16( st->core, AMR_WB_CORE ) ) + { + test(); + IF( EQ_16( st->rf_flag, 1 ) && EQ_32( st->total_brate, ACELP_13k20 ) ) + { + configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, ACELP_9k60, st->L_frame, st->last_L_frame, st->element_mode ); + } + ELSE + { + configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + } + } + ELSE + { + configureFdCngDec_ivas_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); + + if ( st->VAD ) + { + st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; + move32(); + } + } + test(); + test(); + IF( NE_16( st->last_L_frame, st->L_frame ) && LE_16( st->L_frame, L_FRAME16k ) && LE_16( st->last_L_frame, L_FRAME16k ) ) + { + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); + } + + L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth2 ); + + test(); + IF( LE_32( st->total_brate, SID_2k40 ) && LE_32( st->last_total_brate, SID_2k40 ) ) + { + L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth ); + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], (Word16) 20480 /* 0.6250f in Q15 */ ); + move32(); + } + } + ELSE + { + FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( L_shl( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], 1 ), (Word16) 26214 /* 1.6f in Q14 */ ); + move32(); + } + } + } + } + } + + return error; +} +/*---------------------------------------------------------------------* + * core_switching_hq_prepare_dec() + * + * Preprocessing in the first HQ frame after ACELP frame + * Modify bit allocation for HQ core by removing ACELP subframe budget + *---------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------* + * bandwidth_switching_detect() + * + * Classification for band-width switching + *---------------------------------------------------------------------*/ + +void bandwidth_switching_detect_ivas_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ +) +{ + test(); + test(); + IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ + st_fx->prev_bws_cnt = 0; + st_fx->bws_cnt = 0; + st_fx->bws_cnt1 = 0; + move16(); + move16(); + move16(); + + return; + } + /* update band-width switching counter */ + test(); + test(); + test(); + test(); + IF( GE_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) ) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) && ( st_fx->last_low_rate_mode == 0 ) ) + { + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + move16(); + } + ELSE IF( st_fx->bws_cnt1 > 0 ) + { + IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + + IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE + { + IF( EQ_16( st_fx->bwidth, SWB ) ) + { + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + } + } + + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16( st_fx->bws_cnt, N_WS2N_FRAMES ) ) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) + { + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + move16(); + } + ELSE IF( st_fx->bws_cnt > 0 ) + { + IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + + IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE + { + IF( EQ_16( st_fx->bwidth, WB ) ) + { + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * bw_switching_pre_proc() + * + * Band-width switching pre-processing + *---------------------------------------------------------------------*/ +void ivas_bw_switching_pre_proc_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 last_element_brate, /* i : last element bitrate */ + const Word16 nchan_out /* i : number of output channels */, + Word32 *old_syn_12k8_16k_fx, + Word16 Q, + Word16 Q_audio ) +{ + Word16 i; + Word32 syn_dct_fx[L_FRAME]; + + + Flag Overflow = 0; + move32(); + + IF( st->element_mode > EVS_MONO ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) && st->hBWE_FD != NULL && !( LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) ) + { + /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ + Word16 old_syn_12k8_16k_tmp_16fx[L_FRAME16k]; + Copy_Scale_sig_32_16( old_syn_12k8_16k_fx, old_syn_12k8_16k_tmp_16fx, st->L_frame, sub( -1, Q ) ); + st->tilt_wb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_syn_12k8_16k_tmp_16fx, -1, st->L_frame ), sub( Q, 8 ) ) ); // Q24+(Q-8) - 16 + move16(); + } + + return; + } + + + test(); + test(); + IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) + { + /*----------------------------------------------------------------------* + * Calculate tilt of the ACELP core synthesis + *----------------------------------------------------------------------*/ + + st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); + move16(); + /*-------------------------------------------------------------------------------* + * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis + *-------------------------------------------------------------------------------*/ + edct_fx( old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q ); + Word64 W_tmp = 0; + move64(); + Word32 tmp; + Word16 shift; + FOR( i = 0; i < L_FRAME / 2; i++ ) + { + W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + tmp = W_extract_h( W_tmp ); + tmp = L_shr( tmp, 8 ); + + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); + move16(); + W_tmp = 0; + move64(); + FOR( ; i < L_FRAME; i++ ) + { + W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + tmp = W_extract_h( W_tmp ); // Q = Q + shift - 32 + tmp = L_shr( tmp, 7 ); // divide by 128 + tmp = getSqrtWord32( tmp ); + st->enerLH_fx = tmp; + move32(); + st->enerLH_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); + move16(); + } + ELSE + { + IF( st->hHQ_core->old_is_transient[0] ) + { + Word32 tmp, L_tmp = 0; + move32(); + FOR( i = 0; i < 32; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + + L_tmp = 0; + move32(); + FOR( ; i < 64; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLH_fx = tmp; + move32(); + st->enerLH_fx_Q = Q_audio; + move16(); + } + ELSE + { + Word32 tmp, L_tmp = 0; + move32(); + FOR( i = 0; i < L_FRAME / 2; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + + L_tmp = 0; + move32(); + FOR( ; i < L_FRAME; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) + { + + st->prev_ener_shb_fx = 0; + move16(); + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); + } + } + ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) + { + st->attenu_fx = 3277; // 0.1f in Q15 + move16(); + } + + test(); + test(); + test(); + test(); + test(); + if ( EQ_16( st->last_core, HQ_CORE ) || ( ( st->last_core == ACELP_CORE ) && !( EQ_16( st->last_extl, WB_TBE ) || EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) && GT_32( st->core_brate, ACELP_8k00 ) ) ) + { + st->prev_fractive = 0; + move16(); + } + + return; +} \ No newline at end of file diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c deleted file mode 100644 index 7b4567f7a..000000000 --- a/lib_dec/dec_prm.c +++ /dev/null @@ -1,328 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * getTCXMode_ivas() - * - * get TCX mode - *--------------------------------------------------------------------*/ -void getTCXMode_ivas_fx( - Decoder_State *st, /* i/o: decoder memory state */ - Decoder_State *st0, /* i : bitstream */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - UWord16 ind; - - IF( st->tcxonly ) - { - /* get core */ - ind = get_next_indice_fx( st0, 1 ); /* Store decoder memory of last_core */ - st->core = add( ind, TCX_20_CORE ); - move16(); - /* get class */ - ind = get_next_indice_fx( st0, 2 ); - - st->clas_dec = ONSET; - move16(); - IF( ind == 0 ) - { - st->clas_dec = UNVOICED_CLAS; - move16(); - } - ELSE IF( EQ_16( ind, 1 ) ) - { - IF( GE_16( st->last_good, VOICED_TRANSITION ) ) - { - st->clas_dec = VOICED_TRANSITION; - move16(); - } - ELSE - { - st->clas_dec = UNVOICED_TRANSITION; - move16(); - } - } - ELSE IF( EQ_16( ind, 2 ) ) - { - st->clas_dec = VOICED_CLAS; - move16(); - } - - st->coder_type = INACTIVE; - move16(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) - { - st->VAD = get_next_indice_fx( st0, 1 ); - move16(); - } - ELSE - { - st->VAD = 0; - move16(); - } - } - ELSE - { - IF( EQ_16( st->mdct_sw, MODE1 ) ) - { - /* 2 bits instead of 3 as TCX is already signaled */ - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = get_next_indice_fx( st0, 2 ); - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - ELSE - { - IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) - { - IF( get_next_indice_1_fx( st0 ) ) - { - ind = get_next_indice_fx( st0, 3 ); - assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = ind; - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - ELSE /* ACELP */ - { - st->core = ACELP_CORE; - move16(); - st->coder_type = get_next_indice_fx( st0, 2 ); - move16(); - } - } - ELSE - { - IF( EQ_16( st->rf_flag, 1 ) ) - { - IF( !st->use_partial_copy ) - { - ind = get_next_indice_fx( st0, 1 ); - IF( ind == 0 ) - { - st->core = ACELP_CORE; - move16(); - } - ELSE - { - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = st->coder_type; - move16(); - } - } - } - ELSE - { - ind = get_next_indice_fx( st, 3 ); - IF( LT_16( ind, ACELP_MODE_MAX ) ) - { - st->core = ACELP_CORE; - move16(); - st->coder_type = ind; - move16(); - } - ELSE - { - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = sub( ind, ACELP_MODE_MAX ); - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - } - } - } - - IF( EQ_16( st->element_mode, EVS_MONO ) ) - { - test(); - IF( st->igf && EQ_16( st->core, ACELP_CORE ) ) - { - st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_flag ) ); - move16(); - } - - IF( st->rf_flag ) - { - st->bits_frame_core = sub( st->bits_frame_core, add( st->rf_target_bits, 1 ) ); /* +1 as flag-bit not considered in rf_target_bits */ - move16(); - } - } - - /* Inactive frame detection on non-DTX mode */ - IF( EQ_16( st->coder_type, INACTIVE ) ) - { - st->VAD = 0; - move16(); - } - ELSE - { - st->VAD = 1; - move16(); - } - } - - /*Core extended mode mapping for correct PLC classification*/ - st->core_ext_mode = st->coder_type; - move16(); - if ( EQ_16( st->coder_type, INACTIVE ) ) - { - st->core_ext_mode = UNVOICED; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * getTCXWindowing_ivas() - * - * get TCX transform type for each subframe - *--------------------------------------------------------------------*/ -void getTCXWindowing_ivas_fx( - const Word16 core, /* i : current core */ - const Word16 last_core, /* i : last frame core */ - const Word16 element_mode, /* i : element mode */ - TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ - Decoder_State *st0 /* i : bitstream */ -) -{ - Word16 overlap_code; - - /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ - test(); - test(); - test(); - IF( EQ_16( last_core, ACELP_CORE ) || EQ_16( last_core, AMR_WB_CORE ) ) - { - hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; - move16(); - } - ELSE IF( EQ_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) - { - hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; - move16(); - } - ELSE IF( NE_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) - { - hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; - move16(); - } - ELSE - { - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - /* Set the current overlap mode based on the current frame type and coded overlap mode */ - hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - - IF( NE_16( core, ACELP_CORE ) ) - { - overlap_code = 0; - move16(); - IF( get_next_indice_fx( st0, 1 ) ) - { - overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); - } - - assert( MIN_OVERLAP == 2 && HALF_OVERLAP == 3 ); - hTcxCfg->tcx_curr_overlap_mode = overlap_code; - move16(); - /*TCX10 : always symmetric windows*/ - test(); - test(); - test(); - IF( EQ_16( core, TCX_20_CORE ) && ( overlap_code == 0 ) && NE_16( last_core, ACELP_CORE ) && NE_16( last_core, AMR_WB_CORE ) ) - { - hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - } - } - - test(); - IF( NE_16( element_mode, EVS_MONO ) && EQ_16( core, TCX_10_CORE ) ) - { - /* also read last overlap */ - overlap_code = 0; - move16(); - - IF( get_next_indice_fx( st0, 1 ) ) - { - overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); - } - - hTcxCfg->tcx_last_overlap_mode = overlap_code; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * getLPCparam_ivas() - * - * get LPC parameters - *--------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * Function dec_prm_ivas() * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * - * SQ is used for TCX modes - * - * decode parameters according to selected mode * - *-----------------------------------------------------------------*/ diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c index 73edd3b3b..77fd7d421 100644 --- a/lib_dec/dec_prm_fx.c +++ b/lib_dec/dec_prm_fx.c @@ -1742,3 +1742,273 @@ void dec_prm_fx( return; } + + +/*-------------------------------------------------------------------* + * getTCXMode_ivas() + * + * get TCX mode + *--------------------------------------------------------------------*/ +void getTCXMode_ivas_fx( + Decoder_State *st, /* i/o: decoder memory state */ + Decoder_State *st0, /* i : bitstream */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +) +{ + UWord16 ind; + + IF( st->tcxonly ) + { + /* get core */ + ind = get_next_indice_fx( st0, 1 ); /* Store decoder memory of last_core */ + st->core = add( ind, TCX_20_CORE ); + move16(); + /* get class */ + ind = get_next_indice_fx( st0, 2 ); + + st->clas_dec = ONSET; + move16(); + IF( ind == 0 ) + { + st->clas_dec = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16( ind, 1 ) ) + { + IF( GE_16( st->last_good, VOICED_TRANSITION ) ) + { + st->clas_dec = VOICED_TRANSITION; + move16(); + } + ELSE + { + st->clas_dec = UNVOICED_TRANSITION; + move16(); + } + } + ELSE IF( EQ_16( ind, 2 ) ) + { + st->clas_dec = VOICED_CLAS; + move16(); + } + + st->coder_type = INACTIVE; + move16(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) + { + st->VAD = get_next_indice_fx( st0, 1 ); + move16(); + } + ELSE + { + st->VAD = 0; + move16(); + } + } + ELSE + { + IF( EQ_16( st->mdct_sw, MODE1 ) ) + { + /* 2 bits instead of 3 as TCX is already signaled */ + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = get_next_indice_fx( st0, 2 ); + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE + { + IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) + { + IF( get_next_indice_1_fx( st0 ) ) + { + ind = get_next_indice_fx( st0, 3 ); + assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = ind; + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE /* ACELP */ + { + st->core = ACELP_CORE; + move16(); + st->coder_type = get_next_indice_fx( st0, 2 ); + move16(); + } + } + ELSE + { + IF( EQ_16( st->rf_flag, 1 ) ) + { + IF( !st->use_partial_copy ) + { + ind = get_next_indice_fx( st0, 1 ); + IF( ind == 0 ) + { + st->core = ACELP_CORE; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = st->coder_type; + move16(); + } + } + } + ELSE + { + ind = get_next_indice_fx( st, 3 ); + IF( LT_16( ind, ACELP_MODE_MAX ) ) + { + st->core = ACELP_CORE; + move16(); + st->coder_type = ind; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = sub( ind, ACELP_MODE_MAX ); + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + } + } + } + + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + test(); + IF( st->igf && EQ_16( st->core, ACELP_CORE ) ) + { + st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_flag ) ); + move16(); + } + + IF( st->rf_flag ) + { + st->bits_frame_core = sub( st->bits_frame_core, add( st->rf_target_bits, 1 ) ); /* +1 as flag-bit not considered in rf_target_bits */ + move16(); + } + } + + /* Inactive frame detection on non-DTX mode */ + IF( EQ_16( st->coder_type, INACTIVE ) ) + { + st->VAD = 0; + move16(); + } + ELSE + { + st->VAD = 1; + move16(); + } + } + + /*Core extended mode mapping for correct PLC classification*/ + st->core_ext_mode = st->coder_type; + move16(); + if ( EQ_16( st->coder_type, INACTIVE ) ) + { + st->core_ext_mode = UNVOICED; + move16(); + } + + return; +} + +/*-------------------------------------------------------------------* + * getTCXWindowing_ivas() + * + * get TCX transform type for each subframe + *--------------------------------------------------------------------*/ +void getTCXWindowing_ivas_fx( + const Word16 core, /* i : current core */ + const Word16 last_core, /* i : last frame core */ + const Word16 element_mode, /* i : element mode */ + TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ + Decoder_State *st0 /* i : bitstream */ +) +{ + Word16 overlap_code; + + /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ + test(); + test(); + test(); + IF( EQ_16( last_core, ACELP_CORE ) || EQ_16( last_core, AMR_WB_CORE ) ) + { + hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; + move16(); + } + ELSE IF( EQ_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) + { + hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; + move16(); + } + ELSE IF( NE_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) + { + hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + ELSE + { + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + /* Set the current overlap mode based on the current frame type and coded overlap mode */ + hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + + IF( NE_16( core, ACELP_CORE ) ) + { + overlap_code = 0; + move16(); + IF( get_next_indice_fx( st0, 1 ) ) + { + overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); + } + + assert( MIN_OVERLAP == 2 && HALF_OVERLAP == 3 ); + hTcxCfg->tcx_curr_overlap_mode = overlap_code; + move16(); + /*TCX10 : always symmetric windows*/ + test(); + test(); + test(); + IF( EQ_16( core, TCX_20_CORE ) && ( overlap_code == 0 ) && NE_16( last_core, ACELP_CORE ) && NE_16( last_core, AMR_WB_CORE ) ) + { + hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + } + } + + test(); + IF( NE_16( element_mode, EVS_MONO ) && EQ_16( core, TCX_10_CORE ) ) + { + /* also read last overlap */ + overlap_code = 0; + move16(); + + IF( get_next_indice_fx( st0, 1 ) ) + { + overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); + } + + hTcxCfg->tcx_last_overlap_mode = overlap_code; + move16(); + } + + return; +} + diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c deleted file mode 100644 index aca84d9d9..000000000 --- a/lib_dec/dec_tcx.c +++ /dev/null @@ -1,508 +0,0 @@ - -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include -#include "options.h" -#include -#include "stat_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "ivas_rom_com.h" -#include "ivas_prot_fx.h" -#include "debug.h" - -/*-------------------------------------------------------------------* - * decoder_tcx_post() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * decoder_tcx_tns() - * - * TCX: TNS application - *-------------------------------------------------------------------*/ - -void decoder_tcx_tns_fx( - Decoder_State *st, /* i/o: coder memory state */ - const Word16 L_frame_glob, /* i : frame length */ - const Word16 L_spec, - const Word16 L_frame, - const Word16 L_frameTCX, - Word32 x_fx[N_MAX], // Qx - const Word16 fUseTns, /* i : flag that is set if TNS data is present */ - STnsData *tnsData, - const Word16 bfi, /* i : Bad frame indicator */ - const Word16 frame_cnt, /* i : frame counter in the super frame */ - const Word16 whitenedDomain, - Word16 *length ) -{ - Word16 index, isTCX5, L, tmp; - TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - move16(); - - isTCX5 = 0; - move16(); - L = L_frameTCX; - move16(); - tmp = L; - move16(); - - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) - { - test(); - test(); - IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - test(); - test(); - test(); - IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) - { - L = L_spec; - move16(); - tmp = L; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) || - ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) || - ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && - NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - move16(); - - tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); - } - } - - /*-----------------------------------------------------------* - * Temporal Noise Shaping Synthesis * - *-----------------------------------------------------------*/ - - - test(); - test(); - test(); - IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) - { - /* Apply TNS to get the reconstructed signal */ - SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); - - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) - { - tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); - } - - ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 ); - - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) - { - test(); - IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ - { - tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); - tmp = L_frameTCX; - move16(); - } - ELSE - { - tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); - } - } - } - test(); - IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) ) - { - tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); - } - - /* restore index */ - test(); - test(); - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) - { - /* restore sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = index; - move16(); - } - - if ( length != NULL ) - { - *length = tmp; - move16(); - } - - return; -} - - -void decoder_tcx_imdct_fx( - Decoder_State *st, /* i/o: coder memory state */ - const Word16 L_frame_glob, /* i : frame length */ - const Word16 L_frameTCX_glob, - const Word16 L_spec, - const Word16 tcx_offset, - const Word16 tcx_offsetFB, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 left_rect, - Word32 x_fx[N_MAX], // Q(11) - Word16 q_x, - Word16 xn_buf_fx[], // Q(-2) - Word16 q_win, - const UWord16 kernelType, /* i : TCX transform kernel type */ - const Word16 fUseTns, /* i : flag that is set if TNS data is present */ - Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */ - Word16 synthFB_fx[], // Q(-2) - const Word16 bfi, /* i : Bad frame indicator */ - const Word16 frame_cnt, /* i : frame counter in the super frame */ - const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -) -{ - Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; - Word16 overlapFB; - Word32 x_tmp_fx[L_FRAME_PLUS]; - Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; - Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; - Word16 acelp_zir_fx[L_FRAME_MAX / 2]; - Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; - Word16 index, proc = 0; - TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; - TCX_DEC_HANDLE hTcxDec = st->hTcxDec; - TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - Word16 predictionGain_fx; - Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf - Word16 q_a_itf = 15; - Word16 x_e = sub( 31, q_x ); - move16(); - Word16 shift_q = sub( q_x, q_win ); - - /*-----------------------------------------------------------------* - * Initializations - *-----------------------------------------------------------------*/ - - /* Init lengths */ - overlap = hTcxCfg->tcx_mdct_window_length; - move16(); - overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; - move16(); - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - move16(); - test(); - test(); - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - IF( st->igf != 0 ) - { - proc = st->hIGFDec->flatteningTrigger; - move16(); - - test(); - IF( proc && fUseTns != 0 ) - { - proc = 0; - move16(); - } - - IF( proc ) - { - - startLine = st->hIGFDec->infoIGFStartLine; - move16(); - endLine = st->hIGFDec->infoIGFStopLine; - move16(); - curr_order = 0; - move16(); - predictionGain_fx = 0; - move16(); - L = L_frameTCX; - move16(); - isTCX5 = 0; - move16(); - - /* interleave again for ITF */ - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly ) - { - test(); - test(); - test(); - IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) - { - L = L_spec; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || - ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || - ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && - ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - move16(); - - tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); - } - } - - FOR( j = startLine; j < endLine; j++ ) - { - IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) - { - x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x - move32(); - x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; - move32(); - } - } - - ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); - - ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); - - FOR( j = startLine; j < endLine; j++ ) - { - IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) - { - x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x - move32(); - } - } - - /* deinterleave */ - IF( NE_16( isTCX5, 0 ) ) - { - tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); - } - } - } - - /*-----------------------------------------------------------* - * Prepare OLA buffer after waveadjustment. * - * Compute inverse MDCT of x[]. * - *-----------------------------------------------------------*/ - - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); - set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); - Copy32( x_fx, x_tmp_fx, copy_len ); // q_x - Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x - } - ELSE IF( ( st->element_mode == EVS_MONO ) ) - { - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - } - ELSE - { - Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) ); - Copy32( x_fx, x_tmp_fx, copy_len ); // q_x - Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x - } - - IF( ( st->igf != 0 ) ) - { - set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); - } - - test(); - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag ) - { - - IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, - hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); - } - - /* Generate additional comfort noise to mask potential coding artefacts */ - test(); - test(); - test(); - IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) ) - { - generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom ); - FOR( Word16 ind = 0; ind < L_frame; ind++ ) - { - x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x - } - } - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) ) - { - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - - IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); - } - - FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) - { - xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x - move16(); - } - - Word16 ratio_e; - Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9) - ratio = shr( ratio, sub( 6, ratio_e ) ); - - IF( st->element_mode != EVS_MONO ) - { - IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, - hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); - } - ELSE - { - - IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); - } - FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) - { - xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x - } - - IF( ( bfi == 0 ) ) - { - Word16 res_m, res_e = 0; - move16(); - st->second_last_tns_active = st->last_tns_active; - move16(); - st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; - move16(); - hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; - move32(); - hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; - move32(); - res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e ); - st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) ); - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - // Using sat as a single instruction shifts and extracts - st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8 - move32(); - } - - IF( GT_16( st->element_mode, EVS_MONO ) ) - { - res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); - st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - move32(); - } - ELSE - { - res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); - st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - move32(); - } - } - - /* Update old_syn_overl */ - IF( hTcxCfg->last_aldo == 0 ) - { - Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) - FOR( Word16 ind = 0; ind < overlapFB; ind++ ) - { - hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x - } - } - - /* Output */ - Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) - FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) - { - synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x - } - - - return; -} - -/*-------------------------------------------------------------------* - * init_tcx_info() - * - * Initialize lengths for TCX processing, update IGF subframe info - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index a0556437d..4d97367ef 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -4856,3 +4856,450 @@ void decoder_tcx_noiseshaping_igf_fx( return; } + + +/*-------------------------------------------------------------------* + * decoder_tcx_tns() + * + * TCX: TNS application + *-------------------------------------------------------------------*/ + +void decoder_tcx_tns_fx( + Decoder_State *st, /* i/o: coder memory state */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_spec, + const Word16 L_frame, + const Word16 L_frameTCX, + Word32 x_fx[N_MAX], // Qx + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + STnsData *tnsData, + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 whitenedDomain, + Word16 *length ) +{ + Word16 index, isTCX5, L, tmp; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + + isTCX5 = 0; + move16(); + L = L_frameTCX; + move16(); + tmp = L; + move16(); + + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) + { + test(); + test(); + IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + { + /* fix sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + test(); + test(); + test(); + IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) + { + L = L_spec; + move16(); + tmp = L; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) || + ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) || + ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && + NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) ) + { + isTCX5 = 1; + move16(); + + tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); + } + } + + /*-----------------------------------------------------------* + * Temporal Noise Shaping Synthesis * + *-----------------------------------------------------------*/ + + + test(); + test(); + test(); + IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) + { + /* Apply TNS to get the reconstructed signal */ + SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); + + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + { + tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); + } + + ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 ); + + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + { + test(); + IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ + { + tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); + tmp = L_frameTCX; + move16(); + } + ELSE + { + tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); + } + } + } + test(); + IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) ) + { + tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); + } + + /* restore index */ + test(); + test(); + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + { + /* restore sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = index; + move16(); + } + + if ( length != NULL ) + { + *length = tmp; + move16(); + } + + return; +} + + +void decoder_tcx_imdct_fx( + Decoder_State *st, /* i/o: coder memory state */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_frameTCX_glob, + const Word16 L_spec, + const Word16 tcx_offset, + const Word16 tcx_offsetFB, + const Word16 L_frame, + const Word16 L_frameTCX, + const Word16 left_rect, + Word32 x_fx[N_MAX], // Q(11) + Word16 q_x, + Word16 xn_buf_fx[], // Q(-2) + Word16 q_win, + const UWord16 kernelType, /* i : TCX transform kernel type */ + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */ + Word16 synthFB_fx[], // Q(-2) + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ +) +{ + Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; + Word16 overlapFB; + Word32 x_tmp_fx[L_FRAME_PLUS]; + Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; + Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 acelp_zir_fx[L_FRAME_MAX / 2]; + Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; + Word16 index, proc = 0; + TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec = st->hTcxDec; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + Word16 predictionGain_fx; + Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf + Word16 q_a_itf = 15; + Word16 x_e = sub( 31, q_x ); + move16(); + Word16 shift_q = sub( q_x, q_win ); + + /*-----------------------------------------------------------------* + * Initializations + *-----------------------------------------------------------------*/ + + /* Init lengths */ + overlap = hTcxCfg->tcx_mdct_window_length; + move16(); + overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + test(); + test(); + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) ) + { + /* fix sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + IF( st->igf != 0 ) + { + proc = st->hIGFDec->flatteningTrigger; + move16(); + + test(); + IF( proc && fUseTns != 0 ) + { + proc = 0; + move16(); + } + + IF( proc ) + { + + startLine = st->hIGFDec->infoIGFStartLine; + move16(); + endLine = st->hIGFDec->infoIGFStopLine; + move16(); + curr_order = 0; + move16(); + predictionGain_fx = 0; + move16(); + L = L_frameTCX; + move16(); + isTCX5 = 0; + move16(); + + /* interleave again for ITF */ + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly ) + { + test(); + test(); + test(); + IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) + { + L = L_spec; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || + ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || + ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && + ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) ) + { + isTCX5 = 1; + move16(); + + tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); + } + } + + FOR( j = startLine; j < endLine; j++ ) + { + IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) + { + x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x + move32(); + x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; + move32(); + } + } + + ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); + + ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); + + FOR( j = startLine; j < endLine; j++ ) + { + IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) + { + x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x + move32(); + } + } + + /* deinterleave */ + IF( NE_16( isTCX5, 0 ) ) + { + tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); + } + } + } + + /*-----------------------------------------------------------* + * Prepare OLA buffer after waveadjustment. * + * Compute inverse MDCT of x[]. * + *-----------------------------------------------------------*/ + + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); + set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x + } + ELSE IF( ( st->element_mode == EVS_MONO ) ) + { + Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + } + ELSE + { + Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x + } + + IF( ( st->igf != 0 ) ) + { + set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); + } + + test(); + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag ) + { + + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, + hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); + } + + /* Generate additional comfort noise to mask potential coding artefacts */ + test(); + test(); + test(); + IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) ) + { + generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom ); + FOR( Word16 ind = 0; ind < L_frame; ind++ ) + { + x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x + } + } + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) ) + { + Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); + } + + FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) + { + xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x + move16(); + } + + Word16 ratio_e; + Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9) + ratio = shr( ratio, sub( 6, ratio_e ) ); + + IF( st->element_mode != EVS_MONO ) + { + IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, + hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + } + ELSE + { + + IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + } + FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) + { + xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x + } + + IF( ( bfi == 0 ) ) + { + Word16 res_m, res_e = 0; + move16(); + st->second_last_tns_active = st->last_tns_active; + move16(); + st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; + move16(); + hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; + move32(); + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + move32(); + res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e ); + st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) ); + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + // Using sat as a single instruction shifts and extracts + st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8 + move32(); + } + + IF( GT_16( st->element_mode, EVS_MONO ) ) + { + res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); + st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); + } + ELSE + { + res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); + st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); + } + } + + /* Update old_syn_overl */ + IF( hTcxCfg->last_aldo == 0 ) + { + Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) + FOR( Word16 ind = 0; ind < overlapFB; ind++ ) + { + hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x + } + } + + /* Output */ + Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) + FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) + { + synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x + } + + + return; +} + diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c deleted file mode 100644 index dd3adb247..000000000 --- a/lib_dec/fd_cng_dec.c +++ /dev/null @@ -1,1393 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_rom_dec.h" -#include "ivas_rom_com_fx.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" -#include "basop_util.h" -#include "rom_basop_util.h" - -/*------------------------------------------------------------------- - * Local constants - *-------------------------------------------------------------------*/ - -#define DELTA_MASKING_NOISE_Q15 0 -#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ -#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ -#define LOG_10_BASE_2 1783446566 /* Q29 */ -#define GAIN_Q_OFFSET_IVAS_FX 45 -#define LOG_10_BASE_2_BY_10_Q31 713378606 -#define TWO_BY_THREE_Q31 1431655765 -#define ONE_BY_FRAMES_PER_SEC_Q15 656 -#define NB_LAST_BAND_SCALE_Q31 1717986918 -#define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918 - -/*------------------------------------------------------------------- - * Local fucntions declarations - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * createFdCngDec() - * - * Create an instance of type FD_CNG - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * initFdCngDec() - * - * Initialize an instance of type FD_CNG - *-------------------------------------------------------------------*/ -void configureFdCngDec_ivas_fx( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ - const Word16 bwidth, /*Q0*/ - const Word32 total_brate, /*Q0*/ - const Word16 L_frame, /*Q0*/ - const Word16 last_L_frame, /*Q0*/ - const Word16 element_mode /*Q0*/ ) -{ - Word16 j, stopBandFR; - HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; - - hsCom->CngBandwidth = bwidth; /*Q0*/ - move16(); - if ( EQ_16( hsCom->CngBandwidth, FB ) ) - { - hsCom->CngBandwidth = SWB; - move16(); - } - test(); - IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) ) - { - hsCom->CngBitrate = total_brate; /*Q0*/ - move32(); - } - ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) ) - { - /* set minimum active CBR bitrate IF CngBitrate is uninitialized */ - IF( element_mode > EVS_MONO ) - { - hsCom->CngBitrate = IVAS_13k2; - move32(); - } - ELSE - { - hsCom->CngBitrate = ACELP_7k20; - move32(); - } - } - - /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ - /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ - if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) - { - hsCom->CngBitrate = IVAS_48k; - move32(); - } - hsCom->numSlots = 16; - move32(); - - /* NB configuration */ - IF( EQ_16( bwidth, NB ) ) - { - hsCom->FdCngSetup = FdCngSetup_nb; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 16; - move16(); - } - - /* WB configuration */ - ELSE IF( EQ_16( bwidth, WB ) ) - { - /* FFT 6.4kHz, no CLDFB */ - test(); - test(); - IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb1; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 16; - move16(); - } - /* FFT 6.4kHz, CLDFB 8.0kHz */ - ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb2; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 20; - move16(); - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb2; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 20; - move16(); - hsCom->FdCngSetup.fftlen = 640; - move16(); - hsCom->FdCngSetup.stopFFTbin = 256; - move16(); - } - } - /* FFT 8.0kHz, no CLDFB */ - ELSE - { - hsCom->FdCngSetup = FdCngSetup_wb3; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 20; - move16(); - } - } - - /* SWB/FB configuration */ - ELSE - { - /* FFT 6.4kHz, CLDFB 14kHz */ - IF( EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_swb1; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 35; - move16(); - } - /* FFT 8.0kHz, CLDFB 16kHz */ - ELSE - { - hsCom->FdCngSetup = FdCngSetup_swb2; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 40; - move16(); - test(); - if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) - { - hsCom->regularStopBand = 35; - move16(); - } - } - } - - - hsCom->fftlen = hsCom->FdCngSetup.fftlen; - move16(); - hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; - move16(); - - /* Configure the SID quantizer and the Comfort Noise Generator */ - - hsCom->startBand = 2; - move16(); - hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/ - initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); - - IF( EQ_16( hsCom->stopFFTbin, 160 ) ) - { - hsCom->nFFTpart = 17; - move16(); - } - ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) ) - { - hsCom->nFFTpart = 20; - move16(); - } - ELSE - { - hsCom->nFFTpart = 21; - move16(); - } - hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/ - move16(); - FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) - { - hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/ - move16(); - hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; - move16(); - } - - stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/); - move16(); - if ( GT_16( stopBandFR, hsCom->stopFFTbin ) ) - { - stopBandFR = hsCom->stopFFTbin; /*Q0*/ - move16(); - } - - initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR ); - - hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/ - move16(); - - BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); - BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); - - SWITCH( hsCom->fftlen ) - { - case 512: - hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/ - hsCom->fftSineTab_fx = NULL; - hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/ - hsCom->fftlenShift = 8; - move16(); - hsCom->fftlenFac = 32767 /*1.0 Q15*/; - move16(); - BREAK; - case 640: - hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/ - hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/ - hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/ - hsCom->fftlenShift = 9; - move16(); - hsCom->fftlenFac = 20480 /*0.625 Q15*/; - move16(); - BREAK; - default: - assert( !"Unsupported FFT length for FD-based CNG" ); - BREAK; - } - BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); - BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); - hsCom->frameSize = shr( hsCom->fftlen, 1 ); - - return; -} - -/*------------------------------------------------------------------- - * deleteFdCngDec() - * - * Delete the instance of type FD_CNG - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * ApplyFdCng() - * - * Apply the CLDFB-based CNG at the decoder - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * FdCng_decodeSID() - * - * Decode the FD-CNG bitstream - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * FdCng_decodeSID_ivas_fx() - * - * Decode the FD-CNG bitstream - *-------------------------------------------------------------------*/ - -void FdCng_decodeSID_ivas_fx( - Decoder_State *st /* i/o: decoder state structure */ -) -{ - Word16 N; - Word32 *sidNoiseEst; - Word32 gain; - Word16 i, index; - Word32 v[32]; - Word16 indices[32]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 tmp16; - - IF( st->element_mode == EVS_MONO ) - { - tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0; - move16(); - } - ELSE - { - tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0; - move16(); - } - - const Word16 gain_q_offset = tmp16; /* Q0 */ - move16(); - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/ - - hFdCngCom = ( st->hFdCngDec )->hFdCngCom; - - sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/ - - N = hFdCngCom->npart; /*Q0*/ - move16(); - gain = 0; - move32(); - hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); - move16(); - - /* Read bitstream */ - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ - move16(); - } - - index = get_next_indice_fx( st, 7 ); - - /* MSVQ decoder */ - - IF( st->element_mode != EVS_MONO ) - { - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); - } - ELSE - { /* Legacy EVS_MONO MSVQ tables */ - msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 ); - } - - - /* Decode gain */ - // gain = ((float)index - gain_q_offset) / 1.5f; - gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15 - - /* Apply gain and undo log */ - Word16 res_exp[NPART]; - Word16 max_res_exp = 0; - move16(); - FOR( i = 0; i < N; i++ ) - { - sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ - move32(); - if ( LT_16( max_res_exp, res_exp[i] ) ) - { - max_res_exp = res_exp[i]; - move16(); - } - } - - FOR( i = 0; i < N; i++ ) - { - sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = max_res_exp; - move16(); - - /* NB last band energy compensation */ - - IF( hFdCngCom->CngBandwidth == NB ) - { - sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ - move32(); - } - - test(); - IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ - move32(); - } - - scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); - - return; -} - -/*------------------------------------------------------------------- - * noisy_speech_detection() - * - * - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_comfort_noise_dec() - * - * Generate the comfort noise based on the target noise level - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_masking_noise() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_masking_noise_ivas_fx() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_masking_noise_ivas_fx( - Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/ - Word16 *exp_out, /* o : time-domain signal exp */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const Word16 length, /* i : frame size Q0*/ - const Word16 core, /* i : core Q0*/ - const Word16 return_noise, /* i : noise is returned instead of added Q0*/ - const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/ - const Word16 element_mode, /* i : element mode Q0*/ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const Word16 nchan_out /* i : number of output channels Q0*/ -) -{ - Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel; - Word32 *ptr_level_fx = cngNoiseLevel_fx; - Word32 *fftBuffer_fx = hFdCngCom->fftBuffer; - Word16 i; - Word32 maskingNoise_fx[L_FRAME16k]; - Word32 *ptr_r_fx; - Word32 *ptr_i_fx; - Word16 startBand; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale_fx; - Word16 shift; - scale_fx = 0x40000000; // 1.0 in Q30 - move32(); - startBand = hFdCngCom->startBand; /*Q0*/ - move16(); - shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); - if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) - { - shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/ - } - scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/ - hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift ); - move16(); - - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - *exp_out = Q15; - move16(); - IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) - { - IF( NE_16( core, AMR_WB_CORE ) ) - { - /* Compute additional CN level */ - FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) - { - test(); - test(); - if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) && - GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) && - LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) - { - BREAK; - } - } - - scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */ - } - ELSE - { - /* Compute additional CN level */ - FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) - { - if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) ) - { - BREAK; - } - } - - IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) ) - { - scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */ - } - ELSE - { - scale_fx = 0; - move32(); - } - } - - /* Exclude clean speech */ - scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30 - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ - IF( startBand == 0 ) - { - rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15 - ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/ - Word16 exp1; - exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 ); - Word32 mpy1; - mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/ - mpy1 = L_shl( mpy1, exp1 ); // Q31 - fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15 - ptr_level_fx++; - } - ELSE - { - fftBuffer_fx[0] = 0; - move32(); - set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) ); - ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - } - ptr_i_fx = ptr_r_fx + 1; - FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ ) - { - /* Real part in FFT bins */ - rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15 - Word16 exp2; - exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 ); - Word32 mpy2; - mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/ - ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15 - move32(); - ptr_r_fx += 2; - - /* Imaginary part in FFT bins */ - rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15 - ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15 - ptr_i_fx += 2; - } - - /* Remaining FFT bins are set to zero */ - set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); - /* Nyquist frequency is discarded */ - fftBuffer_fx[1] = 0; - move32(); - } - ELSE - { - /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen ); - } - - /* Perform STFT synthesis */ - IF( secondary ) - { - SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); - } - ELSE - { - SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); - } - *exp_out = sub( *exp_out, Q9 ); - move16(); - - /* Add some comfort noise on top of decoded signal */ - IF( return_noise ) - { - Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ - } - ELSE - { - v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ - } - - return; -} - -/*------------------------------------------------------------------- - * generate_masking_noise_update_seed() - * - * Update seed for scenarios where generate_masking_noise() is - * not called based on signal statistics - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * generate_stereo_masking_noise_fx() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_stereo_masking_noise_fx( - Word16 *syn, /* i/o: time-domain signal Q_syn*/ - Word16 Q_syn, - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/ - const Word16 fadeOut, /* i : only fade out of previous state Q0*/ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const Word16 nchan_out /* i : number of output channels Q0*/ -) -{ - HANDLE_FD_CNG_COM hFdCngCom; - Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/; - Word32 Np_fx[L_FRAME16k]; - Word32 Ns_fx[L_FRAME16k]; - Word32 N1_fx[L_FRAME16k]; - Word32 N2_fx[L_FRAME16k]; - Word16 N1_fx_exp, N2_fx_exp; - Word16 i; - - IF( st->idchan == 0 ) - { - hFdCngCom = st->hFdCngDec->hFdCngCom; -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#endif - Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ - - set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); - set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); - - IF( !fadeOut ) - { -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#endif - generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 - /* Generate masking noise for secondary channel */ - IF( flag_sec_CNA ) - { - generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6 - gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/ - scale_fx = ONE_IN_Q30; - move32(); - IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) ) - { - Word16 exp_gamma; - exp_gamma = 0; - move16(); - Word16 divisor1; - divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma - gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30 - Word16 exp_gamma1, exp_gamma2, exp_gamma3; - exp_gamma1 = Q1; - exp_gamma2 = Q1; - exp_gamma3 = Q1; - move16(); - move16(); - move16(); - gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/ - Word32 temp; - temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1 - gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1 - gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30 - Word32 divisor2; - divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3 - scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30 - } - ELSE - { - gamma_fx = 0; - move16(); - } - - FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) - { - Np_fx[i] = L_add( Np_fx[i], - Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6 - move32(); - Word32 add2; - add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - if ( hStereoCng->c_PS_LT_fx < 0 ) - { - add2 = L_negate( add2 ); /*Q6*/ - } - Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/ - move32(); - } - FOR( ; i < hFdCngCom->frameSize; i++ ) - { - Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - move32(); - Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - move32(); - IF( hStereoCng->c_PS_LT_fx < 0 ) - { - Ns_fx[i] = L_negate( Ns_fx[i] ); - move32(); - } - } - /* Below code to be converted */ - Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21 - FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) - { - hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, - L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), - Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), - Q14 ); // Q_olap - move16(); - hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, - L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), - Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), - Q14 ); // Q_olap - move16(); - } - } - ELSE - { - FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) - { - Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6 - move32(); - } - Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/ - scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21 - FOR( i = 0; i < hFdCngCom->frameSize; i++ ) - { - hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap - move16(); - } - } - - Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/ - } - ELSE - { - set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) ); - set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) ); - } - IF( flag_sec_CNA ) - { - Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6 - hStereoCng->enableSecCNA = 1; - move16(); - } - ELSE - { - set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize ); - } - - /* add masking noise */ - FOR( i = 0; i < hFdCngCom->frameSize; i++ ) - { - syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn - move16(); - } - } - ELSE IF( hStereoCng->enableSecCNA ) - { - Word16 SP_ratio_fx; - SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/ - Word16 prevSP_ratio_fx; - prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/ - move16(); - /* scale and add masking noise */ - FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ ) - { - Word16 s; - Word16 scale_fx_tmp; - scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15 - scale_fx_tmp = shl( scale_fx_tmp, s ); - syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - FOR( ; i < *hStereoCng->frameSize / 2; i++ ) - { - syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - FOR( ; i < *hStereoCng->frameSize; i++ ) - { - syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/ - move16(); - } - - return; -} -void generate_masking_noise_lb_dirac_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/ - const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/ - const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/ -) -{ - Word16 i; - Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ - Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/ - Word32 *ptr_r; - Word32 *ptr_i; - Word32 *ptr_level; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale; - Word16 n_samples_out, n_samples_start, n_samples_out_loop; - - push_wmops( "fd_cng_dirac" ); - - /* Init */ - scale = 0; - move32(); - n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs ); - n_samples_start = 0; - move16(); - Word16 exp_out = Q11; - move16(); - /*LB CLDFB - CNA from STFT*/ - IF( cna_flag ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) - { - /* Compute additional CN level */ - FOR( i = 0; i < 15; i++ ) - { - test(); - test(); - if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && - GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) && - LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) - { - BREAK; - } - } - - scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */ - scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */ - } - } - - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - test(); - IF( cna_flag && tdBuffer != NULL ) - { - WHILE( n_samples_out > 0 ) - { - n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out ); - IF( scale != 0 ) - { - /*Generate LF comfort noise only at first slot, for the whole frame*/ - ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ - IF( EQ_16( hFdCngCom->startBand, 0 ) ) - { - rand_gauss_fx( &fftBuffer[0], seed, exp_out ); - ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/ - - Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp ); - Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/ - sqr = L_shl( sqr, exp2 ); /*Q31*/ - fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_level++; - } - ELSE - { - fftBuffer[0] = 0; - move32(); - set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) ); - ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/ - } - ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/ - - FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ ) - { - rand_gauss_fx( ptr_r, seed, exp_out ); - Word16 exp2 = hFdCngCom->cngNoiseLevelExp; - Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/ - ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_r += 2; - - /* Imaginary part in FFT bins */ - rand_gauss_fx( ptr_i, seed, exp_out ); - ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_i += 2; - } - /* Remaining FFT bins are set to zero */ - set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); - /* Nyquist frequency is discarded */ - fftBuffer[1] = 0; - move32(); - - /* Perform STFT synthesis */ - SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); - scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11 - } - - ELSE - { - /* very low level case - update random seeds */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set32_fx( fftBuffer, 0, hFdCngCom->fftlen ); - /* Perform STFT synthesis */ - SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); - } - hFdCngCom->fftBuffer_exp = 31 - 11; - move16(); - n_samples_out = sub( n_samples_out, hFdCngCom->frameSize ); - n_samples_start = add( n_samples_start, hFdCngCom->frameSize ); - } - } - - pop_wmops(); - - return; -} -void generate_masking_noise_dirac_ivas_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/ - Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/ - Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/ - const Word16 slot_index, /* i : CLDFB slot index Q0*/ - const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/ - const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/ - Word16 q_input, - Word16 *q_cldfb ) -{ - Word16 i; - Word32 *ptr_level_fx; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale_fx; - Word16 q_scale, q_shift, q_ptr_level; - - push_wmops( "fd_cng_dirac" ); - - /* Init */ - scale_fx = 0; - move32(); - - /* Resample CLDFB memories if necessary*/ - IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) ) - { - resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); - } - - set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); - - /*LB CLDFB - CNA from STFT*/ - IF( cna_flag != 0 ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - IF( hFdCngCom->likelihood_noisy_speech > 0 ) - { - /* Compute additional CN level */ - FOR( i = 0; i < 15; i++ ) - { - test(); - test(); - if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && - ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) && - ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) ) - { - BREAK; - } - } - - scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */ - scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); - } - } - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - IF( cna_flag && tdBuffer_fx != NULL ) - { - *q_cldfb = q_input; - move16(); - IF( scale_fx != 0 ) - { - /* LF CLDFB*/ - cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); - } - ELSE - { - /* LB ana CLDFB*/ - cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); - } - } - - /*HF CLDFB - CNA and/or FD-CNG*/ - if ( fd_cng_flag ) - { - scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27 - } - IF( scale_fx != 0 ) - { - q_scale = 27; - move16(); - q_shift = norm_l( scale_fx ); - scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ - q_scale = add( q_scale, q_shift ); - scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 - q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); - ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ - q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); - - FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) - { - Word32 num; - Word16 exp, q_num; - q_shift = norm_l( scale_fx ); - scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ - q_scale = add( q_scale, q_shift ); - num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ - q_num = sub( add( q_scale, q_ptr_level ), 31 ); - exp = sub( 31, q_num ); - num = Sqrt32( num, &exp ); /*Q31 - exp*/ - /* Real part in CLDFB band */ - rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb ); - Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp ); - move32(); - /* Imaginary part in CLDFB band */ - rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb ); - Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp ); - move32(); - - ptr_level_fx++; - } - } - - pop_wmops(); - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeMDCTStereoSID() - * - * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream - * - *-------------------------------------------------------------------*/ - -void FdCngDecodeMDCTStereoSID_fx( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word32 *lr_ptr_fx[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 indices[FD_CNG_stages_37bits]; - Word16 N, i, ch, p, stages; - Word16 is_out_ms; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 shift, exp_diff, max_exp_idx; - Word16 exp_arr[NPART]; - Word32 tmp32, tmp32_arr[NPART]; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 - - is_out_ms = 0; - move16(); - if ( hCPE->hCoreCoder[0]->cng_sba_flag ) - { - is_out_ms = 1; - move16(); - } - - N = 0; /* to avoid compilation warning */ - move16(); - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ - lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/ - } - - /* decode noise shapes and gains */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; - move16(); - hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/ - move16(); - - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - move16(); - } - ELSE - { - stages = FD_CNG_stages_37bits; - move16(); - } - - /* read bitstream */ - FOR( i = 0; i < stages; i++ ) - { - indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/ - move16(); - } - { - gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 - move32(); - } - - /* MSVQ decoder */ - shift = find_guarded_bits_fx( N ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift - - Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20 - } - - dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) ); - - IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) - { - set32_fx( ms_ptr_fx[1], 0, NPART ); - } - - IF( EQ_16( is_out_ms, 0 ) ) - { - inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - } - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - max_exp_idx = 0; - move16(); - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - FOR( p = 0; p < N; p++ ) - { - tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 - tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ - move32(); - if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) - { - max_exp_idx = p; /*Q0*/ - move16(); - } - } - - // Bringing in same exponent - FOR( p = 0; p < N; p++ ) - { - lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; - move16(); - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); - move16(); - FOR( p = 0; p < N; p++ ) - { - IF( GT_16( exp_diff, 0 ) ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ - move32(); - } - ELSE - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ - move32(); - } - } - IF( LT_16( exp_diff, 0 ) ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); - move16(); - } - } - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeDiracMDCTStereoSID_fx() - * - * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream - *-------------------------------------------------------------------*/ - -void FdCngDecodeDiracMDCTStereoSID_fx( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word32 *lr_ptr_fx[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 indices[FD_CNG_stages_37bits]; - Word16 N, i, ch, p; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 shift, exp_diff, max_exp_idx; - Word16 exp_arr[NPART]; - Word32 tmp32, tmp32_arr[NPART]; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ - lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/ - ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/ - } - - /* decode noise shapes and gains */ - hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; /*Q0*/ - move16(); - - /* read bitstream */ - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/ - move16(); - } - gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 - move32(); - - gain_fx[1] = gain_fx[0]; /*Q20*/ - move32(); - - /* MSVQ decoder */ - shift = find_guarded_bits_fx( N ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift - - Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20 - - Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/ - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - max_exp_idx = 0; - move16(); - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - - FOR( p = 0; p < N; p++ ) - { - tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 - tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ - move32(); - if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) - { - max_exp_idx = p; /*Q0*/ - move16(); - } - } - - // Bringing in same exponent - FOR( p = 0; p < N; p++ ) - { - lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/ - move16(); - - /* NB last band energy compensation */ - test(); - IF( hFdCngCom->CngBandwidth == NB ) - { - lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/ - move32(); - } - ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/ - move32(); - } - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0; - move16(); - sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0; - move16(); - - IF( EQ_16( hCPE->nchan_out, 1 ) ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); - FOR( p = 0; p < N; p++ ) - { - IF( exp_diff > 0 ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ - move32(); - } - ELSE - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ - move32(); - } - } - IF( exp_diff < 0 ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); - move16(); - } - } - - return; -} diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 8a902448f..f788144fa 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -24,6 +24,14 @@ #define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ #define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ #define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ +#define DELTA_MASKING_NOISE_Q15 0 +#define LOG_10_BASE_2 1783446566 /* Q29 */ +#define GAIN_Q_OFFSET_IVAS_FX 45 +#define LOG_10_BASE_2_BY_10_Q31 713378606 +#define TWO_BY_THREE_Q31 1431655765 +#define ONE_BY_FRAMES_PER_SEC_Q15 656 +#define NB_LAST_BAND_SCALE_Q31 1717986918 +#define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918 /******************************** * External tables * @@ -5025,6 +5033,1278 @@ void generate_masking_noise_mdct_ivas_fx( return; } + +/*------------------------------------------------------------------- + * initFdCngDec() + * + * Initialize an instance of type FD_CNG + *-------------------------------------------------------------------*/ +void configureFdCngDec_ivas_fx( + HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ + const Word16 bwidth, /*Q0*/ + const Word32 total_brate, /*Q0*/ + const Word16 L_frame, /*Q0*/ + const Word16 last_L_frame, /*Q0*/ + const Word16 element_mode /*Q0*/ ) +{ + Word16 j, stopBandFR; + HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; + + hsCom->CngBandwidth = bwidth; /*Q0*/ + move16(); + if ( EQ_16( hsCom->CngBandwidth, FB ) ) + { + hsCom->CngBandwidth = SWB; + move16(); + } + test(); + IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) ) + { + hsCom->CngBitrate = total_brate; /*Q0*/ + move32(); + } + ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) ) + { + /* set minimum active CBR bitrate IF CngBitrate is uninitialized */ + IF( element_mode > EVS_MONO ) + { + hsCom->CngBitrate = IVAS_13k2; + move32(); + } + ELSE + { + hsCom->CngBitrate = ACELP_7k20; + move32(); + } + } + + /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ + /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ + if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) + { + hsCom->CngBitrate = IVAS_48k; + move32(); + } + hsCom->numSlots = 16; + move32(); + + /* NB configuration */ + IF( EQ_16( bwidth, NB ) ) + { + hsCom->FdCngSetup = FdCngSetup_nb; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + + /* WB configuration */ + ELSE IF( EQ_16( bwidth, WB ) ) + { + /* FFT 6.4kHz, no CLDFB */ + test(); + test(); + IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + /* FFT 6.4kHz, CLDFB 8.0kHz */ + ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 20; + move16(); + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + hsCom->FdCngSetup.fftlen = 640; + move16(); + hsCom->FdCngSetup.stopFFTbin = 256; + move16(); + } + } + /* FFT 8.0kHz, no CLDFB */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_wb3; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + } + } + + /* SWB/FB configuration */ + ELSE + { + /* FFT 6.4kHz, CLDFB 14kHz */ + IF( EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_swb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 35; + move16(); + } + /* FFT 8.0kHz, CLDFB 16kHz */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_swb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 40; + move16(); + test(); + if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + hsCom->regularStopBand = 35; + move16(); + } + } + } + + + hsCom->fftlen = hsCom->FdCngSetup.fftlen; + move16(); + hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; + move16(); + + /* Configure the SID quantizer and the Comfort Noise Generator */ + + hsCom->startBand = 2; + move16(); + hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/ + initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); + + IF( EQ_16( hsCom->stopFFTbin, 160 ) ) + { + hsCom->nFFTpart = 17; + move16(); + } + ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) ) + { + hsCom->nFFTpart = 20; + move16(); + } + ELSE + { + hsCom->nFFTpart = 21; + move16(); + } + hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/ + move16(); + FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) + { + hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/ + move16(); + hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; + move16(); + } + + stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/); + move16(); + if ( GT_16( stopBandFR, hsCom->stopFFTbin ) ) + { + stopBandFR = hsCom->stopFFTbin; /*Q0*/ + move16(); + } + + initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR ); + + hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/ + move16(); + + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); + + SWITCH( hsCom->fftlen ) + { + case 512: + hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/ + hsCom->fftSineTab_fx = NULL; + hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/ + hsCom->fftlenShift = 8; + move16(); + hsCom->fftlenFac = 32767 /*1.0 Q15*/; + move16(); + BREAK; + case 640: + hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/ + hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/ + hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/ + hsCom->fftlenShift = 9; + move16(); + hsCom->fftlenFac = 20480 /*0.625 Q15*/; + move16(); + BREAK; + default: + assert( !"Unsupported FFT length for FD-based CNG" ); + BREAK; + } + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); + hsCom->frameSize = shr( hsCom->fftlen, 1 ); + + return; +} + +/*------------------------------------------------------------------- + * FdCng_decodeSID_ivas_fx() + * + * Decode the FD-CNG bitstream + *-------------------------------------------------------------------*/ + +void FdCng_decodeSID_ivas_fx( + Decoder_State *st /* i/o: decoder state structure */ +) +{ + Word16 N; + Word32 *sidNoiseEst; + Word32 gain; + Word16 i, index; + Word32 v[32]; + Word16 indices[32]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 tmp16; + + IF( st->element_mode == EVS_MONO ) + { + tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0; + move16(); + } + ELSE + { + tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + } + + const Word16 gain_q_offset = tmp16; /* Q0 */ + move16(); + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/ + + hFdCngCom = ( st->hFdCngDec )->hFdCngCom; + + sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/ + + N = hFdCngCom->npart; /*Q0*/ + move16(); + gain = 0; + move32(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); + move16(); + + /* Read bitstream */ + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ + move16(); + } + + index = get_next_indice_fx( st, 7 ); + + /* MSVQ decoder */ + + IF( st->element_mode != EVS_MONO ) + { + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); + } + ELSE + { /* Legacy EVS_MONO MSVQ tables */ + msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 ); + } + + + /* Decode gain */ + // gain = ((float)index - gain_q_offset) / 1.5f; + gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15 + + /* Apply gain and undo log */ + Word16 res_exp[NPART]; + Word16 max_res_exp = 0; + move16(); + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ + move32(); + if ( LT_16( max_res_exp, res_exp[i] ) ) + { + max_res_exp = res_exp[i]; + move16(); + } + } + + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = max_res_exp; + move16(); + + /* NB last band energy compensation */ + + IF( hFdCngCom->CngBandwidth == NB ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ + move32(); + } + + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ + move32(); + } + + scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); + + return; +} + +/*------------------------------------------------------------------- + * generate_masking_noise_ivas_fx() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_masking_noise_ivas_fx( + Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/ + Word16 *exp_out, /* o : time-domain signal exp */ + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + const Word16 length, /* i : frame size Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 return_noise, /* i : noise is returned instead of added Q0*/ + const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ + const Word16 nchan_out /* i : number of output channels Q0*/ +) +{ + Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel; + Word32 *ptr_level_fx = cngNoiseLevel_fx; + Word32 *fftBuffer_fx = hFdCngCom->fftBuffer; + Word16 i; + Word32 maskingNoise_fx[L_FRAME16k]; + Word32 *ptr_r_fx; + Word32 *ptr_i_fx; + Word16 startBand; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale_fx; + Word16 shift; + scale_fx = 0x40000000; // 1.0 in Q30 + move32(); + startBand = hFdCngCom->startBand; /*Q0*/ + move16(); + shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/ + } + scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/ + hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift ); + move16(); + + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + *exp_out = Q15; + move16(); + IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) + { + IF( NE_16( core, AMR_WB_CORE ) ) + { + /* Compute additional CN level */ + FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) + { + test(); + test(); + if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) && + GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) && + LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) + { + BREAK; + } + } + + scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */ + } + ELSE + { + /* Compute additional CN level */ + FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) + { + if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) ) + { + BREAK; + } + } + + IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) ) + { + scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */ + } + ELSE + { + scale_fx = 0; + move32(); + } + } + + /* Exclude clean speech */ + scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30 + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ + IF( startBand == 0 ) + { + rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15 + ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/ + Word16 exp1; + exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 ); + Word32 mpy1; + mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/ + mpy1 = L_shl( mpy1, exp1 ); // Q31 + fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15 + ptr_level_fx++; + } + ELSE + { + fftBuffer_fx[0] = 0; + move32(); + set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) ); + ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + } + ptr_i_fx = ptr_r_fx + 1; + FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ ) + { + /* Real part in FFT bins */ + rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15 + Word16 exp2; + exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 ); + Word32 mpy2; + mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/ + ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15 + move32(); + ptr_r_fx += 2; + + /* Imaginary part in FFT bins */ + rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15 + ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15 + ptr_i_fx += 2; + } + + /* Remaining FFT bins are set to zero */ + set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); + /* Nyquist frequency is discarded */ + fftBuffer_fx[1] = 0; + move32(); + } + ELSE + { + /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ + generate_masking_noise_update_seed_fx( hFdCngCom ); + + set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen ); + } + + /* Perform STFT synthesis */ + IF( secondary ) + { + SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); + } + ELSE + { + SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); + } + *exp_out = sub( *exp_out, Q9 ); + move16(); + + /* Add some comfort noise on top of decoded signal */ + IF( return_noise ) + { + Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ + } + ELSE + { + v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ + } + + return; +} + +/*------------------------------------------------------------------- + * generate_stereo_masking_noise_fx() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_stereo_masking_noise_fx( + Word16 *syn, /* i/o: time-domain signal Q_syn*/ + Word16 Q_syn, + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ + const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/ + const Word16 fadeOut, /* i : only fade out of previous state Q0*/ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ + const Word16 nchan_out /* i : number of output channels Q0*/ +) +{ + HANDLE_FD_CNG_COM hFdCngCom; + Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/; + Word32 Np_fx[L_FRAME16k]; + Word32 Ns_fx[L_FRAME16k]; + Word32 N1_fx[L_FRAME16k]; + Word32 N2_fx[L_FRAME16k]; + Word16 N1_fx_exp, N2_fx_exp; + Word16 i; + + IF( st->idchan == 0 ) + { + hFdCngCom = st->hFdCngDec->hFdCngCom; +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ +#else + Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ +#endif + Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ + + set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); + set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); + + IF( !fadeOut ) + { +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ +#else + Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ +#endif + generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 + /* Generate masking noise for secondary channel */ + IF( flag_sec_CNA ) + { + generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6 + gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/ + scale_fx = ONE_IN_Q30; + move32(); + IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) ) + { + Word16 exp_gamma; + exp_gamma = 0; + move16(); + Word16 divisor1; + divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma + gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30 + Word16 exp_gamma1, exp_gamma2, exp_gamma3; + exp_gamma1 = Q1; + exp_gamma2 = Q1; + exp_gamma3 = Q1; + move16(); + move16(); + move16(); + gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/ + Word32 temp; + temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1 + gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1 + gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30 + Word32 divisor2; + divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3 + scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30 + } + ELSE + { + gamma_fx = 0; + move16(); + } + + FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) + { + Np_fx[i] = L_add( Np_fx[i], + Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6 + move32(); + Word32 add2; + add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + if ( hStereoCng->c_PS_LT_fx < 0 ) + { + add2 = L_negate( add2 ); /*Q6*/ + } + Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/ + move32(); + } + FOR( ; i < hFdCngCom->frameSize; i++ ) + { + Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + move32(); + Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + move32(); + IF( hStereoCng->c_PS_LT_fx < 0 ) + { + Ns_fx[i] = L_negate( Ns_fx[i] ); + move32(); + } + } + /* Below code to be converted */ + Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21 + FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) + { + hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, + L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), + Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), + Q14 ); // Q_olap + move16(); + hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, + L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), + Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), + Q14 ); // Q_olap + move16(); + } + } + ELSE + { + FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) + { + Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6 + move32(); + } + Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/ + scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21 + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) + { + hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap + move16(); + } + } + + Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/ + } + ELSE + { + set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) ); + set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) ); + } + IF( flag_sec_CNA ) + { + Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6 + hStereoCng->enableSecCNA = 1; + move16(); + } + ELSE + { + set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize ); + } + + /* add masking noise */ + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) + { + syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn + move16(); + } + } + ELSE IF( hStereoCng->enableSecCNA ) + { + Word16 SP_ratio_fx; + SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/ + Word16 prevSP_ratio_fx; + prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/ + move16(); + /* scale and add masking noise */ + FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ ) + { + Word16 s; + Word16 scale_fx_tmp; + scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15 + scale_fx_tmp = shl( scale_fx_tmp, s ); + syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); + } + FOR( ; i < *hStereoCng->frameSize / 2; i++ ) + { + syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); + } + FOR( ; i < *hStereoCng->frameSize; i++ ) + { + syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); + } + hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/ + move16(); + } + + return; +} +void generate_masking_noise_lb_dirac_fx( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/ + const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/ + const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/ +) +{ + Word16 i; + Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ + Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/ + Word32 *ptr_r; + Word32 *ptr_i; + Word32 *ptr_level; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale; + Word16 n_samples_out, n_samples_start, n_samples_out_loop; + + push_wmops( "fd_cng_dirac" ); + + /* Init */ + scale = 0; + move32(); + n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs ); + n_samples_start = 0; + move16(); + Word16 exp_out = Q11; + move16(); + /*LB CLDFB - CNA from STFT*/ + IF( cna_flag ) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) + { + /* Compute additional CN level */ + FOR( i = 0; i < 15; i++ ) + { + test(); + test(); + if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && + GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) && + LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) + { + BREAK; + } + } + + scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */ + scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */ + } + } + + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + test(); + IF( cna_flag && tdBuffer != NULL ) + { + WHILE( n_samples_out > 0 ) + { + n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out ); + IF( scale != 0 ) + { + /*Generate LF comfort noise only at first slot, for the whole frame*/ + ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ + IF( EQ_16( hFdCngCom->startBand, 0 ) ) + { + rand_gauss_fx( &fftBuffer[0], seed, exp_out ); + ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/ + + Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp ); + Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/ + sqr = L_shl( sqr, exp2 ); /*Q31*/ + fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); + ptr_level++; + } + ELSE + { + fftBuffer[0] = 0; + move32(); + set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) ); + ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/ + } + ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/ + + FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ ) + { + rand_gauss_fx( ptr_r, seed, exp_out ); + Word16 exp2 = hFdCngCom->cngNoiseLevelExp; + Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/ + ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); + ptr_r += 2; + + /* Imaginary part in FFT bins */ + rand_gauss_fx( ptr_i, seed, exp_out ); + ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); + ptr_i += 2; + } + /* Remaining FFT bins are set to zero */ + set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); + /* Nyquist frequency is discarded */ + fftBuffer[1] = 0; + move32(); + + /* Perform STFT synthesis */ + SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); + scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11 + } + + ELSE + { + /* very low level case - update random seeds */ + generate_masking_noise_update_seed_fx( hFdCngCom ); + + set32_fx( fftBuffer, 0, hFdCngCom->fftlen ); + /* Perform STFT synthesis */ + SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); + } + hFdCngCom->fftBuffer_exp = 31 - 11; + move16(); + n_samples_out = sub( n_samples_out, hFdCngCom->frameSize ); + n_samples_start = add( n_samples_start, hFdCngCom->frameSize ); + } + } + + pop_wmops(); + + return; +} +void generate_masking_noise_dirac_ivas_fx( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/ + Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/ + Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/ + const Word16 slot_index, /* i : CLDFB slot index Q0*/ + const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/ + const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/ + Word16 q_input, + Word16 *q_cldfb ) +{ + Word16 i; + Word32 *ptr_level_fx; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale_fx; + Word16 q_scale, q_shift, q_ptr_level; + + push_wmops( "fd_cng_dirac" ); + + /* Init */ + scale_fx = 0; + move32(); + + /* Resample CLDFB memories if necessary*/ + IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) ) + { + resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); + } + + set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); + + /*LB CLDFB - CNA from STFT*/ + IF( cna_flag != 0 ) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + IF( hFdCngCom->likelihood_noisy_speech > 0 ) + { + /* Compute additional CN level */ + FOR( i = 0; i < 15; i++ ) + { + test(); + test(); + if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && + ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) && + ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) ) + { + BREAK; + } + } + + scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */ + scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); + } + } + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + IF( cna_flag && tdBuffer_fx != NULL ) + { + *q_cldfb = q_input; + move16(); + IF( scale_fx != 0 ) + { + /* LF CLDFB*/ + cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); + } + ELSE + { + /* LB ana CLDFB*/ + cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); + } + } + + /*HF CLDFB - CNA and/or FD-CNG*/ + if ( fd_cng_flag ) + { + scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27 + } + IF( scale_fx != 0 ) + { + q_scale = 27; + move16(); + q_shift = norm_l( scale_fx ); + scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ + q_scale = add( q_scale, q_shift ); + scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 + q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); + ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ + q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); + + FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) + { + Word32 num; + Word16 exp, q_num; + q_shift = norm_l( scale_fx ); + scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ + q_scale = add( q_scale, q_shift ); + num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ + q_num = sub( add( q_scale, q_ptr_level ), 31 ); + exp = sub( 31, q_num ); + num = Sqrt32( num, &exp ); /*Q31 - exp*/ + /* Real part in CLDFB band */ + rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb ); + Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp ); + move32(); + /* Imaginary part in CLDFB band */ + rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb ); + Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp ); + move32(); + + ptr_level_fx++; + } + } + + pop_wmops(); + + return; +} + + +/*------------------------------------------------------------------- + * FdCngDecodeMDCTStereoSID() + * + * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream + * + *-------------------------------------------------------------------*/ + +void FdCngDecodeMDCTStereoSID_fx( + CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ +) +{ + DEC_CORE_HANDLE sts[CPE_CHANNELS]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 indices[FD_CNG_stages_37bits]; + Word16 N, i, ch, p, stages; + Word16 is_out_ms; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 shift, exp_diff, max_exp_idx; + Word16 exp_arr[NPART]; + Word32 tmp32, tmp32_arr[NPART]; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 + + is_out_ms = 0; + move16(); + if ( hCPE->hCoreCoder[0]->cng_sba_flag ) + { + is_out_ms = 1; + move16(); + } + + N = 0; /* to avoid compilation warning */ + move16(); + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ + lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/ + } + + /* decode noise shapes and gains */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; + N = hFdCngCom->npart; + move16(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/ + move16(); + + IF( ch ) + { + stages = FD_CNG_JOINT_stages_25bits; + move16(); + } + ELSE + { + stages = FD_CNG_stages_37bits; + move16(); + } + + /* read bitstream */ + FOR( i = 0; i < stages; i++ ) + { + indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/ + move16(); + } + { + gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 + move32(); + } + + /* MSVQ decoder */ + shift = find_guarded_bits_fx( N ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift + + Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20 + } + + dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) ); + + IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) + { + set32_fx( ms_ptr_fx[1], 0, NPART ); + } + + IF( EQ_16( is_out_ms, 0 ) ) + { + inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + } + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + max_exp_idx = 0; + move16(); + hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; + FOR( p = 0; p < N; p++ ) + { + tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 + tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ + move32(); + if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) + { + max_exp_idx = p; /*Q0*/ + move16(); + } + } + + // Bringing in same exponent + FOR( p = 0; p < N; p++ ) + { + lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; + move16(); + + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); + } + + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) + { + /* create proper M noise shape in channel zero after gains have been applied */ + exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); + move16(); + FOR( p = 0; p < N; p++ ) + { + IF( GT_16( exp_diff, 0 ) ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ + move32(); + } + ELSE + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ + move32(); + } + } + IF( LT_16( exp_diff, 0 ) ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); + move16(); + } + } + + return; +} + + +/*------------------------------------------------------------------- + * FdCngDecodeDiracMDCTStereoSID_fx() + * + * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream + *-------------------------------------------------------------------*/ + +void FdCngDecodeDiracMDCTStereoSID_fx( + CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ +) +{ + DEC_CORE_HANDLE sts[CPE_CHANNELS]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 indices[FD_CNG_stages_37bits]; + Word16 N, i, ch, p; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 shift, exp_diff, max_exp_idx; + Word16 exp_arr[NPART]; + Word32 tmp32, tmp32_arr[NPART]; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ + lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/ + ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/ + } + + /* decode noise shapes and gains */ + hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; + N = hFdCngCom->npart; /*Q0*/ + move16(); + + /* read bitstream */ + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/ + move16(); + } + gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 + move32(); + + gain_fx[1] = gain_fx[0]; /*Q20*/ + move32(); + + /* MSVQ decoder */ + shift = find_guarded_bits_fx( N ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift + + Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20 + + Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/ + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + max_exp_idx = 0; + move16(); + hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; + + FOR( p = 0; p < N; p++ ) + { + tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 + tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ + move32(); + if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) + { + max_exp_idx = p; /*Q0*/ + move16(); + } + } + + // Bringing in same exponent + FOR( p = 0; p < N; p++ ) + { + lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/ + move16(); + + /* NB last band energy compensation */ + test(); + IF( hFdCngCom->CngBandwidth == NB ) + { + lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/ + move32(); + } + ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/ + move32(); + } + + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); + } + sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0; + move16(); + sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0; + move16(); + + IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + /* create proper M noise shape in channel zero after gains have been applied */ + exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); + FOR( p = 0; p < N; p++ ) + { + IF( exp_diff > 0 ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ + move32(); + } + ELSE + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ + move32(); + } + } + IF( exp_diff < 0 ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); + move16(); + } + } + + return; +} + + #ifdef IVAS_CODE_CNG /*------------------------------------------------------------------- diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c deleted file mode 100644 index 2b8091305..000000000 --- a/lib_dec/init_dec.c +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*----------------------------------------------------------------------* - * init_decoder() - * - * Initialization of static variables for the decoder - *----------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------* - * reset_preecho_dec() - * - * Initialization of static variables for pre-echo - *----------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------* - * destroy_cldfb_decoder_flt() - * - * Free memory which was allocated in init_decoder() - *----------------------------------------------------------------------*/ -void destroy_cldfb_decoder_ivas_fx( - Decoder_State *st /* o : Decoder static variables structure */ -) -{ - /* CLDFB BPF & resampling tools */ - deleteCldfb_ivas_fx( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ - deleteCldfb_ivas_fx( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ - deleteCldfb_ivas_fx( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ - deleteCldfb_ivas_fx( &st->cldfbSynHB ); - - deleteFdCngDec_fx( &st->hFdCngDec ); - - return; -} diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index a96774113..caa164df9 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1822,3 +1822,18 @@ void destroy_cldfb_decoder_fx( return; } + +void destroy_cldfb_decoder_ivas_fx( + Decoder_State *st /* o : Decoder static variables structure */ +) +{ + /* CLDFB BPF & resampling tools */ + deleteCldfb_ivas_fx( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ + deleteCldfb_ivas_fx( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ + deleteCldfb_ivas_fx( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ + deleteCldfb_ivas_fx( &st->cldfbSynHB ); + + deleteFdCngDec_fx( &st->hFdCngDec ); + + return; +} diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 459dcc4d4..5a948bdfa 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -3787,3 +3787,36 @@ static void ivas_param_mc_bs_decode_parameter_values_fx( return; } + +Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( + Decoder_Struct *st_ivas /* i : Parametric MC handle */ +) +{ + Word16 num_cldfb_syntheses; + + num_cldfb_syntheses = 0; + move16(); + + /* sanity check*/ + IF( st_ivas->hParamMC == NULL ) + { + assert( 0 && "ParamMC handle does not exist!\n" ); + } + + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + num_cldfb_syntheses = 2; + move16(); + } + ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) + { + num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + + return num_cldfb_syntheses; +} diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c deleted file mode 100644 index 0d9ee2710..000000000 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "ivas_prot_fx.h" - -Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( - Decoder_Struct *st_ivas /* i : Parametric MC handle */ -) -{ - Word16 num_cldfb_syntheses; - - num_cldfb_syntheses = 0; - move16(); - - /* sanity check*/ - IF( st_ivas->hParamMC == NULL ) - { - assert( 0 && "ParamMC handle does not exist!\n" ); - } - - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - num_cldfb_syntheses = 2; - move16(); - } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) - { - num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - - return num_cldfb_syntheses; -} diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c deleted file mode 100644 index 6b80108a8..000000000 --- a/lib_dec/swb_bwe_dec.c +++ /dev/null @@ -1,681 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" - - -static Word16 para_pred_bws_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *signal_wb_fx, /* i : wideband frequency signal Q_syn */ - Word16 *SWB_fenv_fx, /* o : frequency-domain BWE envelope Q1 */ - Word16 Q_syn ) -{ - Word16 i, j, k; - Word16 mode; - Word16 tmp, tmp_den, tmp_num; - Word32 L_tmp, L_tmp_max; - Word16 exp; - Word16 *input_hi_fx; - Word32 *mea; - Word16 peak_fx, mag_fx; - Word32 mean_fx[7], peak_32_fx; - Word32 avrg1_fx, avrg2_fx, min_fx; - Word16 att_fx; - Word16 coder_type = st_fx->coder_type; - move16(); - - mode = NORMAL; - move16(); - - k = 0; - move16(); - input_hi_fx = &signal_wb_fx[SHARP_WIDTH]; /*Q_syn*/ - FOR( i = 0; i < 7; i++ ) - { - peak_fx = 0; - move16(); - mean_fx[i] = 0; - move16(); - FOR( j = 0; j < SHARP_WIDTH; j++ ) - { - mag_fx = abs_s( *input_hi_fx ); /*Q_syn*/ - peak_fx = s_max( peak_fx, mag_fx ); /*Q_syn*/ - mean_fx[i] = L_add( mean_fx[i], L_deposit_l( mag_fx ) ); /*Q_syn*/ - move32(); - input_hi_fx++; - } - - IF( LT_16( Q_syn, 11 ) ) - { - tmp = 1; - move16(); - } - ELSE - { - tmp = 0; - move16(); - if ( GT_16( shr( peak_fx, 3 ), shl( 1, Q_syn ) ) ) - { - tmp = 1; - move16(); - } - } - IF( tmp > 0 ) - { - L_tmp = L_msu0( Mult_32_16( L_shl( mean_fx[i], 10 ) /*Q_syn + 10*/, 18432 /*4.5f Q12*/ ), peak_fx /*Q_syn*/, 4544 /*35.5 (SHARP_WIDTH + 3.5f)Q7*/ ); - if ( L_tmp < 0 ) - { - k = add( k, 1 ); - } - } - } - - avrg1_fx = L_deposit_l( 0 ); - avrg2_fx = L_deposit_l( 0 ); - FOR( i = 1; i < 4; i++ ) - { - avrg1_fx = L_add( avrg1_fx, mean_fx[i] ); /*Q_syn*/ - avrg2_fx = L_add( avrg2_fx, mean_fx[i + 3] ); /*Q_syn*/ - } - avrg1_fx = Mult_32_16( avrg1_fx, 10923 /* 1/3 -> Q15 -> 10923 */ ); /*Q_syn + Q15 - 15*/ - avrg2_fx = Mult_32_16( avrg2_fx, 10923 /* 1/3 -> Q15 -> 10923 */ ); /*Q_syn + Q15 - 15*/ - - min_fx = L_add( 2147483647, 0 ); /*2^31 */ - peak_32_fx = L_deposit_l( 0 ); - FOR( i = 4; i < 7; i++ ) - { - IF( GT_32( mean_fx[i], L_shl( avrg2_fx, 1 ) ) ) - { - exp = norm_l( mean_fx[i] ); - IF( LT_16( exp, 16 ) ) - { - tmp_den = extract_l( L_shr( mean_fx[i], sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp_num = extract_l( L_shr( avrg2_fx, sub( 15, exp ) ) ); /*Qsyn - 16 + exp */ - } - ELSE - { - tmp_den = extract_l( mean_fx[i] ); - tmp_num = extract_l( L_shl( avrg2_fx, 1 ) ); - } - - tmp_den = div_s( 1, tmp_den ); - - tmp = i_mult( tmp_num, tmp_den ); /*Q15 */ - - mean_fx[i] = Mult_32_16( mean_fx[i], tmp ); /*Q_syn + Q15 - 15*/ - move32(); - } - min_fx = L_min( min_fx, mean_fx[i] ); - peak_32_fx = L_max( peak_32_fx, mean_fx[i] ); - } - - IF( GT_16( st_fx->tilt_wb_fx, 16384 /*8 in Q11*/ ) ) - { - IF( GT_16( st_fx->tilt_wb_fx, 30720 /*15.0f in Q11*/ ) ) - { - min_fx = peak_32_fx; - move32(); - } - ELSE - { - tmp = extract_l( L_shr( L_mult0( st_fx->tilt_wb_fx, 17476 ), 14 ) ); /*Q15 */ - min_fx = Mult_32_16( peak_32_fx, tmp ); - } - } - - test(); - IF( peak_32_fx == 0 || min_fx == 0 ) - { - set16_fx( SWB_fenv_fx, 0, SWB_FENV ); - } - ELSE - { - exp = norm_l( peak_32_fx ); - IF( LT_16( exp, 16 ) ) - { - tmp_den = extract_l( L_shr( peak_32_fx, sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp = div_s( 16384, tmp_den ); /*Q15+14 - (Qsyn - 16 + exp) */ - tmp_num = extract_l( L_shr( min_fx, sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp = extract_l( L_shr( L_mult0( tmp_num, tmp ), 14 ) ); /*Q15 */ - } - ELSE - { - tmp_den = extract_l( peak_32_fx ); /*Qsyn */ - exp = norm_s( tmp_den ); - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp_den ); /*Q 29-exp - Qsyn */ - tmp_num = extract_l( min_fx ); /*Qsyn */ - tmp = extract_l( L_shr( L_mult0( tmp_num, tmp ), sub( 14, exp ) ) ); /*Q15 */ - } - - j = 0; - move16(); - mea = &mean_fx[4]; - L_tmp_max = L_shl( 32767, add( Q_syn, 5 ) ); - FOR( i = 0; i < SWB_FENV; i++ ) - { - if ( EQ_16( j, 5 ) ) - { - mea++; - j = 0; - move16(); - } - j = add( j, 1 ); - L_tmp = L_min( Mult_32_16( *mea, tmp ), L_tmp_max ); - SWB_fenv_fx[i] = extract_l( L_shr( L_tmp, add( Q_syn, 5 ) ) ); - move16(); - } - } - - j = 0; - move16(); - FOR( i = SWB_FENV / 2; i < SWB_FENV; i++ ) - { - tmp = sub( 32767, i_mult( j, 2341 ) ); - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], tmp ); - move16(); - j = add( j, 1 ); - } - - IF( GT_32( avrg1_fx, L_shl( avrg2_fx, 3 ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = shr( SWB_fenv_fx[i], 1 ); - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( NE_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->last_codec_mode, MODE1 ) && - ( GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLH_fx, 1 ), st_fx->prev_enerLH_fx ) ) && - ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLL_fx, 1 ), st_fx->prev_enerLL_fx ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - test(); - IF( NE_16( st_fx->prev_coder_type, coder_type ) && GT_16( mult_r( SWB_fenv_fx[i], 16384 /*1/2.0f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i] ) ) - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 3277 /*0.1f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i], 29491 /*0.9f in Q15*/ ) ); - move16(); - } - ELSE - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], st_fx->attenu_fx ), st_fx->prev_SWB_fenv_fx[i], sub( 32767 /*1.0f in Q15*/, st_fx->attenu_fx ) ) ); - move16(); - } - } - - IF( LT_16( st_fx->attenu_fx, 29491 /*0.9f in Q15*/ ) ) - { - st_fx->attenu_fx = add( st_fx->attenu_fx, 1638 /*0.05f in Q15*/ ); - move16(); - } - } - ELSE - { - test(); - test(); - test(); - test(); - IF( NE_32( st_fx->core_brate, st_fx->last_core_brate ) || ( GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLH_fx, 1 ), st_fx->prev_enerLH_fx ) ) || - ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLL_fx, 1 ), st_fx->prev_enerLL_fx ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - if ( GT_16( mult_r( SWB_fenv_fx[i], 16384 /*0.5f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i] ) ) - { - SWB_fenv_fx[i] = st_fx->prev_SWB_fenv_fx[i]; - move16(); - } - } - } - - FOR( i = 0; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 29491 /*0.9f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i], 3277 /*0.1f in Q15*/ ) ); - move16(); - } - st_fx->attenu_fx = 3277; /*Q15*/ - move16(); - } - - if ( GT_16( k, 3 ) ) - { - mode = HARMONIC; - move16(); - } - - - att_fx = i_mult( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 819 ); /*15 */ - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - FOR( i = 0; i < 4; i++ ) - { - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], att_fx ); - move16(); /*Q1 */ - } - } - - FOR( i = 4; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], att_fx ); - move16(); /*Q1 */ - } - - return mode; -} - - -/*-------------------------------------------------------------------* - * WB_BWE_gain_deq() - * - * Decoding of WB parameters - *-------------------------------------------------------------------*/ - - -Word16 swb_bwe_dec_fx32( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word32 output_fx[], /* i : synthesis @internal Fs : Q11 */ - Word32 *synth_fx, /* i : ACELP core synthesis/final synthesis : Q11 */ - Word32 *hb_synth_fx, /* o : SHB synthesis/final synthesis : Q_syn_hb */ - Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - Word16 output_frame /* i : frame length */ -) -{ - Word16 L; - Word16 mode; - Word16 idxGain; - Word16 i, j, l_subfr; - Word16 fb_band_begin; - Word16 frica_flag = 0; - move16(); - Word16 ener_adjust_quan_fx; - Word16 fb_ener_adjust_fx = 0; - move16(); - Word16 scl, new_input_fx_exp, ysynth_frame_size; - Word16 Q_syn, Q_syn_hb, tmp, tmp2, q_tmp, Qsynth_fx16; - - Word16 ysynth_fx[L_FRAME48k]; - Word16 SWB_fenv_fx[SWB_FENV]; - Word16 SWB_tenv_fx[SWB_TENV]; - Word16 synth_fx16[L_FRAME48k]; - Word16 hb_synth_fx16[L_FRAME48k]; - - Word32 L_tmp; - Word32 yerror_fx[L_FRAME48k]; - Word32 ysynth_fx32[L_FRAME48k]; - Word32 SWB_tenv_tmp_fx[SWB_TENV]; - Word32 wtda_synth_fx[2 * L_FRAME48k]; - - FD_BWE_DEC_HANDLE hBWE_FD; - hBWE_FD = st_fx->hBWE_FD; - - /*---------------------------------------------------------------------* - * SWB BWE decoding - *---------------------------------------------------------------------*/ - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* todo - delay output[] by 1.25ms ? */ - L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); - - /* windowing of the ACELP core synthesis */ - wtda_fx32( ysynth_fx32, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, /*st_fx->L_frame*/ L_FRAME16k ); - - /* DCT of the ACELP core synthesis */ - new_input_fx_exp = 11; - move16(); - direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, /*st_fx->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); - ysynth_frame_size = L_FRAME16k; - move16(); - } - ELSE - { - /* windowing of the ACELP core synthesis */ - wtda_fx32( synth_fx, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, output_frame ); - - /* DCT of the ACELP core synthesis */ - new_input_fx_exp = 11; - move16(); - direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); - ysynth_frame_size = output_frame; - move16(); - } - - /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ - scl = sub( 16 + 11, new_input_fx_exp ); - /* Possible to Upscale? */ - IF( scl > 0 ) - { - /* Yes */ - /* Calc Room to Upscale */ - Q_syn = sub( Find_Max_Norm32( ysynth_fx32, ysynth_frame_size ), 3 ); - /* Stay within MAX_Q_NEW_INPUT */ - scl = s_min( Q_syn, scl ); - } - /*Don't upscale if already in 15 bits*/ - IF( GT_16( scl, 15 ) ) - { - FOR( i = 0; i < ysynth_frame_size; i++ ) - { - ysynth_fx[i] = extract_l( ysynth_fx32[i] ); - move16(); - } - Q_syn = new_input_fx_exp; - move16(); - } - ELSE - { - Copy_Scale_sig32_16( ysynth_fx32, ysynth_fx, ysynth_frame_size, scl ); - Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); - } - - IF( !st_fx->bfi ) - { - IF( st_fx->bws_cnt > 0 ) - { - /* estimate parameters */ - mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn ); - } - ELSE - { - /* de-quantization */ - mode = swb_bwe_gain_deq_fx( st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); - } - - L = SWB_FENV; - move16(); - if ( EQ_16( mode, TRANSIENT ) ) - { - L = SWB_FENV_TRANS; - move16(); - } - - L_tmp = 0; - move32(); - FOR( i = 0; i < L; i++ ) - { - L_tmp = L_add( L_tmp, L_deposit_l( SWB_fenv_fx[i] ) ); - } - q_tmp = norm_s( L ); - tmp = div_s( shl( 1, sub( 14, q_tmp ) ), L ); /*Q(29-q_tmp) */ - L_tmp = Mpy_32_16_1( L_tmp, tmp ); /*Q(1+29-q_tmp+1-16)->Q(15-q_tmp) */ - st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, add( q_tmp, 2 ) ) ); /*Q1 */ - move16(); - } - ELSE - { - /* SHB FEC */ - - IF( NE_16( hBWE_FD->prev_mode, TRANSIENT ) ) - { - mode = hBWE_FD->prev_mode; - move16(); - } - ELSE - { - mode = NORMAL; - move16(); - } - - Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); - } - - /* reconstruction of MDCT spectrum of the error signal */ - set32_fx( yerror_fx, 0, output_frame ); - - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); - } - ELSE - { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); - } - - test(); - IF( EQ_16( hBWE_FD->prev_frica_flag, 1 ) && frica_flag == 0 ) - { - FOR( i = 0; i < L_SUBFR; i++ ) - { - tmp = sub( 32767, extract_l( L_mult0( i, 512 ) ) ); /*Q15 */ - hBWE_FD->mem_imdct_fx[i] = mult_r( hBWE_FD->mem_imdct_fx[i], tmp ); - move16(); - } - - FOR( ; i < output_frame; i++ ) - { - hBWE_FD->mem_imdct_fx[i] = 0; - move16(); - } - } - - /* decode information */ - IF( EQ_16( st_fx->extl, FB_BWE ) ) - { - IF( !st_fx->bfi ) - { - idxGain = (Word16) get_next_indice_fx( st_fx, NUM_BITS_FB_FRAMEGAIN ); - fb_ener_adjust_fx = usdequant_fx( idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX ); /*Q15 */ - } - ELSE IF( st_fx->bfi ) - { - fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; - move16(); - } - - st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; - move16(); - IF( EQ_16( mode, TRANSIENT ) ) - { - ener_adjust_quan_fx = shr( fb_ener_adjust_fx, 2 ); - } - ELSE - { - IF( SWB_fenv_fx[7] != 0 ) - { - tmp = div_s( 1, SWB_fenv_fx[7] ); - ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); - } - ELSE - { - ener_adjust_quan_fx = 0; - move16(); - } - } - - fb_band_begin = FB_BAND_BEGIN; - move16(); - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - fb_band_begin = FB_BAND_BEGIN_12k8; - move16(); - } - - j = 0; - move16(); - FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) - { - tmp = sub( 32767, i_mult( j, 1024 ) ); - tmp = mult_r( tmp, ener_adjust_quan_fx ); /*Q13*/ - - tmp2 = i_mult( j, 256 ); /*Q13*/ - tmp2 = mult_r( tmp2, fb_ener_adjust_fx ); /*Q13*/ - - tmp = add( tmp, tmp2 ); /*Q13*/ - yerror_fx[i] = L_shl( Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], tmp ), 2 ); /*15+Q_syn */ - move32(); - j = add( j, 1 ); - } - FOR( ; i < FB_BAND_END; i++ ) - { - yerror_fx[i] = Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], fb_ener_adjust_fx ); /*15+Q_syn */ - move32(); - } - } - - /* iDCT of the error signal */ - Q_syn_hb = add( Q_syn, 15 ); - Inverse_Transform( yerror_fx, &Q_syn_hb, wtda_synth_fx, 0, output_frame, -1, st_fx->element_mode ); - - /* inverse windowing of the error signal */ - window_ola_fx( wtda_synth_fx, hb_synth_fx16, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); - l_subfr = mult( output_frame, 8192 ); - - test(); - IF( EQ_16( mode, TRANSIENT ) ) - { - FOR( i = 0; i < SWB_TENV; i++ ) - { - SWB_tenv_tmp_fx[i] = L_mult0( SWB_tenv_fx[i] /*Q0*/, 26214 /*0.8f Q15*/ ); // Q15 - move32(); - } - - /* time envelope shaping when the current frame is TRANSIENT frame */ - time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); - - Q_syn_hb = sub( Q_syn_hb, 3 ); - - hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; - move16(); - } - ELSE IF( EQ_16( frica_flag, 1 ) && hBWE_FD->prev_frica_flag == 0 ) - { - Qsynth_fx16 = Find_Max_Norm32( synth_fx, output_frame ); - Qsynth_fx16 = sub( Qsynth_fx16, shr( add( sub( 15, norm_s( l_subfr ) ), 1 ), 1 ) ); - Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); - Qsynth_fx16 = add( 11 - 16, Qsynth_fx16 ); - - /* IVAS_fmToDo: synth[] is @internal_Fs!!! */ - time_reduce_pre_echo_fx( synth_fx16, hb_synth_fx16, hBWE_FD->prev_td_energy_fx, l_subfr, Qsynth_fx16, Q_syn_hb ); - } - ELSE - { - tmp = i_mult2( 3, l_subfr ); - L_tmp = L_deposit_l( 0 ); - - FOR( i = 0; i < l_subfr; i++ ) - { - L_tmp = L_mac0_sat( L_tmp, hb_synth_fx16[add( tmp, i )], hb_synth_fx16[add( tmp, i )] ); /*(2*Q_syn_hb) */ - } - - L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ - hBWE_FD->prev_td_energy_fx = 0; - move16(); - - IF( L_tmp != 0 ) - { - q_tmp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, q_tmp ) ); - q_tmp = sub( q_tmp, sub( 30, shl( Q_syn_hb, 1 ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &q_tmp ); /*Q(31-exp) */ - hBWE_FD->prev_td_energy_fx = round_fx( L_shl( L_tmp, sub( q_tmp, 15 ) ) ); /*Q0 */ - move16(); - } - } - - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - Qsynth_fx16 = add( 16 - 11, Q_syn_hb ); - Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); - - /* add HB synth from hf_synth() */ - v_add_16( hb_synth_fx16, synth_fx16, hb_synth_fx16, output_frame ); - } - - hBWE_FD->prev_mode = mode; - move16(); - hBWE_FD->prev_frica_flag = frica_flag; - move16(); - - FOR( i = 0; i < output_frame; i++ ) - { - hb_synth_fx[i] = L_deposit_l( hb_synth_fx16[i] ); // Q_syn_hb - move32(); - } - - return Q_syn_hb; -} - - -void fd_bwe_dec_init_fx( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -) -{ - set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->prev_Energy_fx = 0; - move16(); - hBWE_FD->prev_L_swb_norm = 8; - move16(); - hBWE_FD->Seed = 21211; - move16(); - hBWE_FD->prev_frica_flag = 0; - move16(); - set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); - hBWE_FD->prev_td_energy_fx = 0; - move16(); - hBWE_FD->prev_weight_fx = 0; - move16(); - hBWE_FD->prev_flag = 0; - move16(); - hBWE_FD->prev_Energy_wb_fx = 0; - move32(); - hBWE_FD->mem_deemph_old_syn_fx = 0; - move16(); - - return; -} diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 9552bbf2f..23c4c3e8a 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -1266,3 +1266,372 @@ void fd_bwe_dec_init( return; } + +/*-------------------------------------------------------------------* + * WB_BWE_gain_deq() + * + * Decoding of WB parameters + *-------------------------------------------------------------------*/ + + +Word16 swb_bwe_dec_fx32( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 output_fx[], /* i : synthesis @internal Fs : Q11 */ + Word32 *synth_fx, /* i : ACELP core synthesis/final synthesis : Q11 */ + Word32 *hb_synth_fx, /* o : SHB synthesis/final synthesis : Q_syn_hb */ + Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + Word16 output_frame /* i : frame length */ +) +{ + Word16 L; + Word16 mode; + Word16 idxGain; + Word16 i, j, l_subfr; + Word16 fb_band_begin; + Word16 frica_flag = 0; + move16(); + Word16 ener_adjust_quan_fx; + Word16 fb_ener_adjust_fx = 0; + move16(); + Word16 scl, new_input_fx_exp, ysynth_frame_size; + Word16 Q_syn, Q_syn_hb, tmp, tmp2, q_tmp, Qsynth_fx16; + + Word16 ysynth_fx[L_FRAME48k]; + Word16 SWB_fenv_fx[SWB_FENV]; + Word16 SWB_tenv_fx[SWB_TENV]; + Word16 synth_fx16[L_FRAME48k]; + Word16 hb_synth_fx16[L_FRAME48k]; + + Word32 L_tmp; + Word32 yerror_fx[L_FRAME48k]; + Word32 ysynth_fx32[L_FRAME48k]; + Word32 SWB_tenv_tmp_fx[SWB_TENV]; + Word32 wtda_synth_fx[2 * L_FRAME48k]; + + FD_BWE_DEC_HANDLE hBWE_FD; + hBWE_FD = st_fx->hBWE_FD; + + /*---------------------------------------------------------------------* + * SWB BWE decoding + *---------------------------------------------------------------------*/ + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ + /* todo - delay output[] by 1.25ms ? */ + L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); + + /* windowing of the ACELP core synthesis */ + wtda_fx32( ysynth_fx32, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, /*st_fx->L_frame*/ L_FRAME16k ); + + /* DCT of the ACELP core synthesis */ + new_input_fx_exp = 11; + move16(); + direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, /*st_fx->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); + ysynth_frame_size = L_FRAME16k; + move16(); + } + ELSE + { + /* windowing of the ACELP core synthesis */ + wtda_fx32( synth_fx, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, output_frame ); + + /* DCT of the ACELP core synthesis */ + new_input_fx_exp = 11; + move16(); + direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); + ysynth_frame_size = output_frame; + move16(); + } + + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ + scl = sub( 16 + 11, new_input_fx_exp ); + /* Possible to Upscale? */ + IF( scl > 0 ) + { + /* Yes */ + /* Calc Room to Upscale */ + Q_syn = sub( Find_Max_Norm32( ysynth_fx32, ysynth_frame_size ), 3 ); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min( Q_syn, scl ); + } + /*Don't upscale if already in 15 bits*/ + IF( GT_16( scl, 15 ) ) + { + FOR( i = 0; i < ysynth_frame_size; i++ ) + { + ysynth_fx[i] = extract_l( ysynth_fx32[i] ); + move16(); + } + Q_syn = new_input_fx_exp; + move16(); + } + ELSE + { + Copy_Scale_sig32_16( ysynth_fx32, ysynth_fx, ysynth_frame_size, scl ); + Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); + } + + IF( !st_fx->bfi ) + { + IF( st_fx->bws_cnt > 0 ) + { + /* estimate parameters */ + mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn ); + } + ELSE + { + /* de-quantization */ + mode = swb_bwe_gain_deq_fx( st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); + } + + L = SWB_FENV; + move16(); + if ( EQ_16( mode, TRANSIENT ) ) + { + L = SWB_FENV_TRANS; + move16(); + } + + L_tmp = 0; + move32(); + FOR( i = 0; i < L; i++ ) + { + L_tmp = L_add( L_tmp, L_deposit_l( SWB_fenv_fx[i] ) ); + } + q_tmp = norm_s( L ); + tmp = div_s( shl( 1, sub( 14, q_tmp ) ), L ); /*Q(29-q_tmp) */ + L_tmp = Mpy_32_16_1( L_tmp, tmp ); /*Q(1+29-q_tmp+1-16)->Q(15-q_tmp) */ + st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, add( q_tmp, 2 ) ) ); /*Q1 */ + move16(); + } + ELSE + { + /* SHB FEC */ + + IF( NE_16( hBWE_FD->prev_mode, TRANSIENT ) ) + { + mode = hBWE_FD->prev_mode; + move16(); + } + ELSE + { + mode = NORMAL; + move16(); + } + + Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); + } + + /* reconstruction of MDCT spectrum of the error signal */ + set32_fx( yerror_fx, 0, output_frame ); + + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + } + ELSE + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + } + + test(); + IF( EQ_16( hBWE_FD->prev_frica_flag, 1 ) && frica_flag == 0 ) + { + FOR( i = 0; i < L_SUBFR; i++ ) + { + tmp = sub( 32767, extract_l( L_mult0( i, 512 ) ) ); /*Q15 */ + hBWE_FD->mem_imdct_fx[i] = mult_r( hBWE_FD->mem_imdct_fx[i], tmp ); + move16(); + } + + FOR( ; i < output_frame; i++ ) + { + hBWE_FD->mem_imdct_fx[i] = 0; + move16(); + } + } + + /* decode information */ + IF( EQ_16( st_fx->extl, FB_BWE ) ) + { + IF( !st_fx->bfi ) + { + idxGain = (Word16) get_next_indice_fx( st_fx, NUM_BITS_FB_FRAMEGAIN ); + fb_ener_adjust_fx = usdequant_fx( idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX ); /*Q15 */ + } + ELSE IF( st_fx->bfi ) + { + fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; + move16(); + } + + st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; + move16(); + IF( EQ_16( mode, TRANSIENT ) ) + { + ener_adjust_quan_fx = shr( fb_ener_adjust_fx, 2 ); + } + ELSE + { + IF( SWB_fenv_fx[7] != 0 ) + { + tmp = div_s( 1, SWB_fenv_fx[7] ); + ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); + } + ELSE + { + ener_adjust_quan_fx = 0; + move16(); + } + } + + fb_band_begin = FB_BAND_BEGIN; + move16(); + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + fb_band_begin = FB_BAND_BEGIN_12k8; + move16(); + } + + j = 0; + move16(); + FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) + { + tmp = sub( 32767, i_mult( j, 1024 ) ); + tmp = mult_r( tmp, ener_adjust_quan_fx ); /*Q13*/ + + tmp2 = i_mult( j, 256 ); /*Q13*/ + tmp2 = mult_r( tmp2, fb_ener_adjust_fx ); /*Q13*/ + + tmp = add( tmp, tmp2 ); /*Q13*/ + yerror_fx[i] = L_shl( Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], tmp ), 2 ); /*15+Q_syn */ + move32(); + j = add( j, 1 ); + } + FOR( ; i < FB_BAND_END; i++ ) + { + yerror_fx[i] = Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], fb_ener_adjust_fx ); /*15+Q_syn */ + move32(); + } + } + + /* iDCT of the error signal */ + Q_syn_hb = add( Q_syn, 15 ); + Inverse_Transform( yerror_fx, &Q_syn_hb, wtda_synth_fx, 0, output_frame, -1, st_fx->element_mode ); + + /* inverse windowing of the error signal */ + window_ola_fx( wtda_synth_fx, hb_synth_fx16, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); + l_subfr = mult( output_frame, 8192 ); + + test(); + IF( EQ_16( mode, TRANSIENT ) ) + { + FOR( i = 0; i < SWB_TENV; i++ ) + { + SWB_tenv_tmp_fx[i] = L_mult0( SWB_tenv_fx[i] /*Q0*/, 26214 /*0.8f Q15*/ ); // Q15 + move32(); + } + + /* time envelope shaping when the current frame is TRANSIENT frame */ + time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); + + Q_syn_hb = sub( Q_syn_hb, 3 ); + + hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; + move16(); + } + ELSE IF( EQ_16( frica_flag, 1 ) && hBWE_FD->prev_frica_flag == 0 ) + { + Qsynth_fx16 = Find_Max_Norm32( synth_fx, output_frame ); + Qsynth_fx16 = sub( Qsynth_fx16, shr( add( sub( 15, norm_s( l_subfr ) ), 1 ), 1 ) ); + Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); + Qsynth_fx16 = add( 11 - 16, Qsynth_fx16 ); + + /* IVAS_fmToDo: synth[] is @internal_Fs!!! */ + time_reduce_pre_echo_fx( synth_fx16, hb_synth_fx16, hBWE_FD->prev_td_energy_fx, l_subfr, Qsynth_fx16, Q_syn_hb ); + } + ELSE + { + tmp = i_mult2( 3, l_subfr ); + L_tmp = L_deposit_l( 0 ); + + FOR( i = 0; i < l_subfr; i++ ) + { + L_tmp = L_mac0_sat( L_tmp, hb_synth_fx16[add( tmp, i )], hb_synth_fx16[add( tmp, i )] ); /*(2*Q_syn_hb) */ + } + + L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ + hBWE_FD->prev_td_energy_fx = 0; + move16(); + + IF( L_tmp != 0 ) + { + q_tmp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, q_tmp ) ); + q_tmp = sub( q_tmp, sub( 30, shl( Q_syn_hb, 1 ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &q_tmp ); /*Q(31-exp) */ + hBWE_FD->prev_td_energy_fx = round_fx( L_shl( L_tmp, sub( q_tmp, 15 ) ) ); /*Q0 */ + move16(); + } + } + + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + Qsynth_fx16 = add( 16 - 11, Q_syn_hb ); + Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); + + /* add HB synth from hf_synth() */ + v_add_16( hb_synth_fx16, synth_fx16, hb_synth_fx16, output_frame ); + } + + hBWE_FD->prev_mode = mode; + move16(); + hBWE_FD->prev_frica_flag = frica_flag; + move16(); + + FOR( i = 0; i < output_frame; i++ ) + { + hb_synth_fx[i] = L_deposit_l( hb_synth_fx16[i] ); // Q_syn_hb + move32(); + } + + return Q_syn_hb; +} + + +void fd_bwe_dec_init_fx( + FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ +) +{ + set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm = 8; + move16(); + hBWE_FD->Seed = 21211; + move16(); + hBWE_FD->prev_frica_flag = 0; + move16(); + set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + hBWE_FD->prev_weight_fx = 0; + move16(); + hBWE_FD->prev_flag = 0; + move16(); + hBWE_FD->prev_Energy_wb_fx = 0; + move32(); + hBWE_FD->mem_deemph_old_syn_fx = 0; + move16(); + + return; +} + diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c deleted file mode 100644 index 80dfad505..000000000 --- a/lib_dec/swb_tbe_dec.c +++ /dev/null @@ -1,2478 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ); - -/*-------------------------------------------------------------------* - * ResetSHBbuffer_Dec() - * - * - *-------------------------------------------------------------------*/ - -static void calc_tilt_bwe_fx_loc( - const Word32 *sp_fx, /* i : input signal : Q11 */ - Word32 *tilt_fx, /* o : signal tilt : tilt_fx_q */ - Word16 *tilt_fx_q, /* o : signal tilt */ - const Word16 N /* i : signal length : Q0 */ -) -{ - Word16 i; - Word64 r0_fx, r1_fx; - - r0_fx = EPSILON_FX_SMALL; - move64(); - FOR( i = 0; i < N; i++ ) - { - r0_fx = W_add( r0_fx, W_shr( W_mult_32_32( sp_fx[i], sp_fx[i] ), 1 ) ); /*Q11*2 - 1*/ - } - r1_fx = W_deposit32_l( abs( L_sub( sp_fx[1], sp_fx[0] ) ) ); /*Q11*/ - FOR( i = 2; i < N; i++ ) - { - IF( W_mult_32_32( L_sub( sp_fx[i], sp_fx[i - 1] ) /*Q11*/, L_sub( sp_fx[i - 1], sp_fx[i - 2] ) /*Q11*/ ) /*Q11 * 2 - 1*/ < 0 ) - { - r1_fx = W_add( r1_fx, W_deposit32_l( abs( L_sub( sp_fx[i], sp_fx[i - 1] ) ) ) ); /*Q11*/ - } - } - Word16 headroom_left_r0 = W_norm( r0_fx ); - Word16 headroom_left_r1 = W_norm( r1_fx ); - Word16 r0_q = 0, r1_q = 0; - move16(); - move16(); - IF( LT_16( headroom_left_r0, 32 ) ) - { - r0_fx = W_shr( r0_fx, sub( 32, headroom_left_r0 ) ); - r0_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_r0 ) ) ); - } - ELSE - { - r0_q = 31 - ( 2 * OUTPUT_Q ); - move16(); - } - - IF( LT_16( headroom_left_r1, 32 ) ) - { - r1_fx = W_shr( r1_fx, sub( 32, headroom_left_r1 ) ); - r1_q = sub( OUTPUT_Q, sub( 32, headroom_left_r1 ) ); - } - ELSE - { - r1_q = OUTPUT_Q; - move16(); - } - Word32 temp_r0_inv = ISqrt32( W_extract_l( r0_fx ), &r0_q ); - Word32 res = Mpy_32_32( W_extract_l( r1_fx ), temp_r0_inv ); - // Word16 res_q = r1_q + ( r0_q < 0 ? ( 31 + ( -1 * r0_q ) ) : r0_q ) - 31; - Word16 res_q; - IF( r0_q < 0 ) - { - res_q = add( r1_q, sub( add( 31, -r0_q ), 31 ) ); - } - ELSE - { - res_q = add( r1_q, sub( r0_q, 31 ) ); - } - Word16 norm_res = norm_l( res ); - IF( norm_res > 0 ) - { - *tilt_fx = L_shl_sat( res, norm_res ); - move32(); - *tilt_fx_q = add( res_q, norm_res ); - move16(); - } - ELSE - { - *tilt_fx = res; - move32(); - *tilt_fx_q = res_q; - move16(); - } - return; -} - -/*-------------------------------------------------------------------* - * swb_tbe_dec() - * - * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module - *-------------------------------------------------------------------*/ -static void rescale_genSHB_mem_dec( - Decoder_State *st_fx, - Word16 sf /*Q0*/ -) -{ - Word16 i; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) - { - hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); - move16(); - } - - FOR( i = 0; i < 7; i++ ) - { - hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); - move16(); - } - - /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ - IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); - move16(); - } - - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); - move16(); - } - } - - hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); - move32(); - - hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); - move16(); - hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); - move16(); -} - -static void gradientGainShape( - Decoder_State *st_fx, - Word16 *GainShape_fx, /*Q15*/ - Word32 *GainFrame_fx /* Q18 */ ) -{ - Word16 i, j, tmp; - Word16 GainShapeTemp[NUM_SHB_SUBFR / 4]; - Word16 GainGrad0[3]; - Word16 GainGrad1[3]; - Word16 GainGradFEC[4]; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - - /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ - FOR( j = 0; j < 3; j++ ) - { - GainGrad0[j] = sub( shr( st_fx->GainShape_Delay[j + 1], 1 ), shr( st_fx->GainShape_Delay[j], 1 ) ); - move16(); /* Q14 */ - GainGrad1[j] = sub( shr( st_fx->GainShape_Delay[j + 5], 1 ), shr( st_fx->GainShape_Delay[j + 4], 1 ) ); - move16(); /* Q14 */ - GainGradFEC[j + 1] = add( mult_r( GainGrad0[j], 13107 /*0.4f in Q15*/ ), mult_r( GainGrad1[j], 19660 /*0.6f in Q15*/ ) ); - move16(); /* Q14 */ - } - - /* gradient for the first gainshape */ - test(); - test(); - test(); - IF( ( ( GT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( GT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) || - ( ( LT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( LT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) ) - { - GainGradFEC[0] = add( mult_r( GainGrad1[1], 3277 /*0.1f in Q15*/ ), mult_r( GainGrad1[2], 29490 /*0.9f in Q15*/ ) ); - move16(); /* Q14 */ - } - ELSE - { - GainGradFEC[0] = add( mult_r( GainGrad1[0], 6553 /*0.2f in Q15*/ ), mult_r( GainGrad1[1], 9830 /*0.3f in Q15*/ ) ); - move16(); - GainGradFEC[0] = add( GainGradFEC[0], mult_r( GainGrad1[2], 16384 /*0.5f in Q15*/ ) ); - move16(); /* Q14 */ - } - - /* get the first gainshape template */ - test(); - test(); - IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && ( GainGradFEC[0] > 0 ) ) - { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), GainGradFEC[0] ); - move16(); - } - ELSE IF( GainGradFEC[0] > 0 ) - { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), mult_r( GainGradFEC[0], 16384 /*0.5f in Q15*/ ) ); - move16(); /* Q14 */ - } - ELSE - { - GainShapeTemp[0] = shr( st_fx->GainShape_Delay[7], 1 ); - move16(); /* Q14 */ - } - - /*Get the second the third and the fourth gainshape template*/ - - tmp = shr( GainGrad1[2], 3 ); /* GainGrad1[2]/8 */ - tmp = mult_r( tmp, 26214 ); /* 0.8 in Q15 tmp*(8/10) */ - - test(); - IF( ( GT_16( tmp, GainGrad1[1] ) ) && ( GainGrad1[1] > 0 ) ) - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 26214 /*0.8f in Q15*/ ) ); - move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); - } - } - ELSE - { - test(); - IF( ( GT_16( tmp, GainGrad1[1] ) ) && ( GainGrad1[1] < 0 ) ) - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 6553 /*0.2f in Q15*/ ) ); - move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); /* Q14 */ - } - } - ELSE - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], GainGradFEC[i] ); - move16(); - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); - } - } - } - - /* Get the gainshape and gain frame for the current frame*/ - test(); - test(); - test(); - IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && EQ_16( st_fx->nbLostCmpt, 1 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - tmp = mult_r( GainShapeTemp[i], 19660 /*0.6f Q15*/ ); /* GainShapeTemp[i]*0.6 */ - - IF( GT_16( 8192, tmp ) ) - { - GainShape_fx[i * 4 + j] = shl( tmp, 2 ); /*Q15*/ - move16(); /* (GainShapeTemp[i]*0.6)>>1 */ - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; /*Q15*/ - move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 31129 ); - move16(); - } - ELSE IF( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - IF( LT_16( GainShapeTemp[i], 16384 ) ) - { - GainShape_fx[i * 4 + j] = shl( GainShapeTemp[i], 1 ); /*Q15*/ - move16(); - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; // 1.0f in Q15 - move16(); - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 31129 /*0.95f in Q15*/ ); /*Q15*/ - move16(); - } - ELSE IF( GT_16( st_fx->nbLostCmpt, 1 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - GainShape_fx[i * 4 + j] = GainShapeTemp[i]; /*Q15*/ - move16(); - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 16384 /*0.5f in Q15*/ ); /*Q15*/ - move16(); - } - ELSE - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - IF( LT_16( GainShapeTemp[i], 16384 ) ) - { - GainShape_fx[i * 4 + j] = shl( GainShapeTemp[i], 1 ); /*Q15*/ - move16(); - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; /*Q15*/ - move16(); - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 27852 /*0.85f in Q15*/ ); /*Q15*/ - move16(); - } - - *GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx ); /* Q18 */ - move32(); -} - -static void find_max_mem_dec( - Decoder_State *st_fx, - Word16 *n_mem, - Word16 *n_mem2, - Word16 *n_mem3 ) -{ - Word16 i; - Word16 n_mem_32; - Word16 max = 0; - move16(); - Word32 Lmax = 0; - move32(); - Word16 tempQ15, max2 = 0; - move16(); - Word16 max3; - Word32 tempQ32, Lmax3; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - /* old BWE exc max */ - FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) - { - tempQ15 = abs_s( hBWE_TD->old_bwe_exc_extended_fx[i] ); - max = s_max( max, tempQ15 ); - } - - /* decimate all-pass steep memory */ - FOR( i = 0; i < 7; i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ); - max = s_max( max, tempQ15 ); - } - - /* -- keep norm of state_lpc_syn_fx, state_syn_shbexc_fx, - and mem_stp_swb_fx separately for 24.4 and 32kbps ----*/ - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->state_lpc_syn_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->state_syn_shbexc_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_stp_swb_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* for total_brate > 16.4kbps, use n_mem2; else account for the max2 for n_mem calculation */ - *n_mem2 = norm_s( max2 ); - move16(); - if ( max2 == 0 ) - { - *n_mem2 = 15; - move16(); - } - - if ( LT_32( st_fx->total_brate, ACELP_24k40 ) ) - { - max = s_max( max, max2 ); - } - - /* de-emph and pre-emph memory */ - tempQ15 = abs_s( hBWE_TD->tbe_demph_fx ); - max = s_max( max, tempQ15 ); - - tempQ15 = abs_s( hBWE_TD->tbe_premph_fx ); - max = s_max( max, tempQ15 ); - - IF( EQ_16( st_fx->extl, FB_TBE ) ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->fb_state_lpc_syn_fx[i] ); - max = s_max( max, tempQ15 ); - } - /* FB de-emph memory */ - tempQ15 = abs_s( hBWE_TD->fb_tbe_demph_fx ); - max = s_max( max, tempQ15 ); - } - /* estimate the norm for 16-bit memories */ - *n_mem = norm_s( max ); - move16(); - if ( max == 0 ) - { - *n_mem = 15; - move16(); - } - - /* estimate the norm for 32-bit memories */ - Lmax = L_abs( hBWE_TD->mem_csfilt_fx[0] ); /* only element [0] is used in env. shaping */ - - n_mem_32 = norm_l( Lmax ); - if ( Lmax == 0 ) - { - n_mem_32 = 31; - move16(); - } - - tempQ15 = sub( s_min( *n_mem, n_mem_32 ), 1 ); - *n_mem = s_max( tempQ15, 0 ); - move16(); - - /* --------------------------------------------------------------*/ - /* Find headroom for synthesis stage associated with these memories: - 1. st_fx->syn_overlap_fx - 2. st_fx->genSHBsynth_state_lsyn_filt_shb_local - 3. st_fx->genSHBsynth_Hilbert_Mem_fx (32-bit) */ - max3 = 0; - move16(); - /* find max in prev overlapSyn */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - tempQ15 = abs_s( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev int_3_over_2_tbemem_dec_fx */ - IF( EQ_32( st_fx->output_Fs, 48000 ) ) - { - FOR( i = 0; i < INTERP_3_2_MEM_LEN; i++ ) - { - tempQ15 = abs_s( hBWE_TD->int_3_over_2_tbemem_dec_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - } - IF( EQ_32( st_fx->output_Fs, 16000 ) ) - { - FOR( i = 0; i < ( 2 * ALLPASSSECTIONS_STEEP + 1 ); i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_resamp_HB_32k_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - } - /* estimate the norm for 16-bit memories */ - *n_mem3 = norm_s( max3 ); - move16(); - if ( max3 == 0 ) - { - *n_mem3 = 15; - move16(); - } - - Lmax3 = 0; - move32(); - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - /* find max in prev genSHBsynth_Hilbert_Mem_fx */ - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - tempQ32 = L_abs( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] ); - Lmax3 = L_max( Lmax3, tempQ32 ); - } - } - - /* estimate the norm for 32-bit memories */ - n_mem_32 = norm_l( Lmax3 ); - if ( Lmax3 == 0 ) - { - n_mem_32 = 31; - move16(); - } - - tempQ15 = sub( s_min( *n_mem3, n_mem_32 ), 2 ); /* very important leave at least 2 bit head room - because of the Hilber transform and Q14 coeffs */ - *n_mem3 = s_max( tempQ15, 0 ); - move16(); - /* --------------------------------------------------------------*/ -} - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ) -{ - Word16 i; - // Word16 n_mem_32; - Word16 tempQ15; - Word16 max3; - // Word32 tempQ32, Lmax3; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st->hBWE_TD; - - /* --------------------------------------------------------------*/ - /* Find headroom for synthesis stage associated with these memories: - 1. st->syn_overlap_fx*/ - max3 = 0; - move16(); - /* find max in prev overlapSyn */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ - - /* estimate the norm for 16-bit memories */ - *n_mem3 = norm_s( max3 ); - move16(); - if ( max3 == 0 ) - { - *n_mem3 = 15; - move16(); - } -} - -/*-------------------------------------------------------------------* - * ivas_swb_tbe_dec_fx() - * - * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module - *-------------------------------------------------------------------*/ -void ivas_swb_tbe_dec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation : Q_exc */ - Word16 Q_exc, - const Word16 voice_factors_fx[], /* i : voicing factors : Q15 */ - const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis : old_syn_fx */ - Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE : Q_white_exc*/ - Word32 *synth_fx, /* o : SHB synthesis/final synthesis : Qx */ - Word16 *pitch_buf_fx, /* i : Q6 */ - Word16 *Q_white_exc ) -{ - Word16 i, j, cnt, n; - Word16 stemp; - TD_BWE_DEC_HANDLE hBWE_TD; - Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; - Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; - Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; - Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; // Q12,Q12,Q15 - Word32 GainFrame_fx; // Q18 - Word32 error_fx[L_FRAME32k]; - Word16 ener_fx; - Word32 L_ener; - Word16 is_fractive; - Word32 prev_pow_fx, curr_pow_fx, Lscale; - Word16 scale_fx; - Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; - Word32 curr_frame_pow_fx; - Word16 curr_frame_pow_exp; - Word32 L_prev_ener_shb; - Word16 vf_modified_fx[NB_SUBFR16k]; - Word16 f_fx, inc_fx; - Word32 GainFrame_prevfrm_fx; - Word32 tilt_swb_fec_32_fx; - Word16 tilt_swb_fec_fx_q; - Word16 tilt_swb_fec_fx; - Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ - Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; - Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; - const Word16 *ptr_lsp_interp_coef_fx; - Word32 shb_ener_sf_32; - Word16 shb_res_gshape_fx[NB_SUBFR16k]; - Word16 mixFactors_fx; - Word16 vind; - Word16 shb_res_dummy_fx[L_FRAME16k]; - Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; - Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; - Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; - Word16 pitch_fx; - Word16 l_subframe; - Word16 formant_fac_fx; - Word16 synth_scale_fx; - Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; - Word16 refl_fx[M]; - Word16 tilt_para_fx; - Word16 *nlExc16k_fx, *mixExc16k_fx; - Word16 MSFlag; - Word16 feedback_fx; - Word16 GainShape_tilt_fx; - - // scaling - Word16 exp, tmp; - Word16 tmp1, tmp2; - Word16 mean_vf; - Word32 Lmax, L_tmp; - Word16 frac; - Word32 L_tmp1, L_tmp2; - Word16 Q_bwe_exc; - Word16 Q_bwe_exc_fb; - Word16 Q_shb; - Word16 n_mem, n_mem2, n_mem3, Qx, sc; - Word16 expa, expb; - Word16 fraca, fracb; - Word16 exp_ener, inv_ener; - - hBWE_TD = st->hBWE_TD; - - /* initializations */ - GainFrame_fx = 0; - move32(); - mixFactors_fx = 0; - move16(); - shb_ener_sf_32 = 0; - move32(); - set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); - if ( st->hTdCngDec != NULL ) - { - st->hTdCngDec->shb_dtx_count = 0; - move16(); - } - is_fractive = 0; - move16(); - - IF( hStereoICBWE != NULL ) - { - nlExc16k_fx = hStereoICBWE->nlExc16k_fx; - mixExc16k_fx = hStereoICBWE->mixExc16k_fx; - MSFlag = hStereoICBWE->MSFlag; - move16(); - } - ELSE - { - nlExc16k_fx = NULL; - mixExc16k_fx = NULL; - MSFlag = 0; - move16(); - } - - /* find tilt */ - calc_tilt_bwe_fx_loc( old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME ); - tilt_swb_fec_fx = round_fx_sat( L_shl_sat( tilt_swb_fec_32_fx, sub( 11 + 16, tilt_swb_fec_fx_q ) ) ); - test(); - if ( st->bfi && st->clas_dec != UNVOICED_CLAS ) - { - tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; - move16(); - } - - /* WB/SWB bandwidth switching */ - test(); - test(); - IF( ( GT_16( st->tilt_wb_fx, 10240 /*5 in Q11*/ ) && ( EQ_16( st->clas_dec, UNVOICED_CLAS ) ) ) || GT_16( st->tilt_wb_fx, 20480 /*10 in Q11*/ ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( st->prev_fractive == 0 ) && - ( LT_32( st->prev_enerLH_fx, L_shl( st->enerLH_fx, 1 ) ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) && LT_32( st->prev_enerLL_fx, L_shl( st->enerLL_fx, 1 ) ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) ) || - ( EQ_16( st->prev_fractive, 1 ) && - GT_32( L_shr( st->prev_enerLH_fx, 2 ), Mult_32_16( st->enerLH_fx, 24576 ) ) ) /* 24576 in Q13*/ - || ( GT_32( L_shr( st->enerLL_fx, 1 ), Mult_32_16( st->enerLH_fx, 24576 ) ) && /*24576 = 1.5 in Q14*/ - LT_16( st->tilt_wb_fx, 20480 ) ) /* 20480 = 10 in Q11*/ - ) - { - is_fractive = 0; - } - ELSE - { - is_fractive = 1; - } - move16(); - } - - /* WB/SWB bandwidth switching */ - IF( st->bws_cnt > 0 ) - { - f_fx = 1489; /*1.0f / 22.0f in Q15*/ - move16(); - inc_fx = 1489; /*1.0f / 22.0f in Q15*/ - move16(); - - IF( EQ_16( is_fractive, 1 ) ) - { - Copy( lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); - } - ELSE - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); /*Q15*/ - } - } - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && !( ( L_sub( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) < 0 ) && L_sub( st->prev_enerLH_fx, ( L_shr( st->enerLH_fx, 1 ) > 0 ) ) ) ) || st->last_core != ACELP_CORE || ( ( st->last_core == ACELP_CORE ) && GT_32( abs( L_sub( st->last_core_brate, st->core_brate ) ), 3600 ) ) || EQ_16( s_xor( is_fractive, st->prev_fractive ), 1 ) ) - { - set16_fx( GainShape_fx, 11587, NUM_SHB_SUBFR ); /*0.3536f in Q15*/ - } - ELSE - { - if ( GT_16( hBWE_TD->prev_GainShape_fx, 11587 ) ) /*0.3536f in Q15*/ - { - hBWE_TD->prev_GainShape_fx = 11587; /*0.3536f in Q15*/ - move16(); - } - set16_fx( GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); - } - - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ - } - ELSE - { - test(); - IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) - { - f_fx = 1489; /*Q15*/ - move16(); - inc_fx = 1489; /*Q15*/ - move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); - } - } - - IF( !st->bfi ) - { - IF( st->use_partial_copy ) - { - IF( NE_16( st->last_extl, SWB_TBE ) ) - { - hBWE_TD->GainFrame_prevfrm_fx = 0; - move32(); - f_fx = 1489 /*0.045454f Q15*/; - move16(); - inc_fx = 1489 /*0.045454f Q15*/; - move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); /*Q15*/ - } - } - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - set16_fx( GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); - - IF( EQ_16( st->rf_frame_type, RF_NELP ) ) - { - /* Frame gain */ - - GainFrame_fx = L_mac( SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); - L_tmp = Mult_32_16( GainFrame_fx, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ - - frac = L_Extract_lc( L_tmp, &exp ); - L_tmp = Pow2( 30, frac ); - GainFrame_fx = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && !st->prev_use_partial_copy && EQ_16( st->prev_coder_type, UNVOICED ) && NE_32( GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx ) && NE_16( st->next_coder_type, GENERIC ) && EQ_16( st->last_extl, SWB_TBE ) ) - { - GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6553 /*0.2f in Q15*/ ) ); - } - } - ELSE - { - temp_fx = 0; - move16(); - /* Frame gain */ - SWITCH( st->rf_indx_tbeGainFr ) - { - case 0: - GainFrame_fx = 131072; /* 0.5f in Q18 */ - move32(); - if ( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 1: - GainFrame_fx = 524288; /* 2.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 2: - GainFrame_fx = 1048576; /* 4.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 3: - GainFrame_fx = 2097152; /* 8.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - default: - fprintf( stderr, "RF SWB-TBE gain bits not supported." ); - } - - IF( EQ_16( st->last_extl, SWB_TBE ) ) - { - GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp_fx ), Mult_32_16( GainFrame_fx, sub( 32767, temp_fx ) ) ); - /*Q18*/ - } - - IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) ) - { - if ( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, VOICED ) && EQ_16( st->rf_frame_type, RF_GENPRED ) && GT_32( GainFrame_fx, 2097152 /*8.0f in Q18*/ ) && LT_32( GainFrame_fx, 3059606 /*11.67f in Q18*/ ) ) - { - GainFrame_fx = Mult_32_16( GainFrame_fx, 9830 /*0.3f in Q15*/ ); // Q18 - } - } - } - } - ELSE - { - /* de-quantization */ - ivas_dequantizeSHBparams_fx_9_1( st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, - &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag ); - if ( hStereoICBWE != NULL ) - { - hStereoICBWE->MSFlag = MSFlag; - move16(); - } - } - } - ELSE - { - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) - { - gradientGainShape( st, GainShape_fx, &GainFrame_fx ); - } - ELSE - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); - move16(); - } - } - IF( GT_16( tilt_swb_fec_fx, ( 8 << 11 ) ) ) /* tilt_swb_fec_fx in Q11 */ - { - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); - } - ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); - } - ELSE - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); - } - GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); - } - ELSE - { - GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; - move32(); /* gain locking */ - } - } - - IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) - { - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) - { - L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ - tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ - tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ - i = sub( norm_s( tmp1 ), 1 ); - tmp1 = shl( tmp1, i ); /* Qi */ - IF( tmp == 0 ) - { - tmp = 32767 /*1.0f Q15*/; - move16(); /*Q15*/ - } - ELSE - { - scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ - scale_fx = s_max( scale_fx, 0 ); - tmp = shl_sat( scale_fx, sub( sub( 15, exp ), i ) ); /*Q15*/ - } - scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ - test(); - IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || - GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) - { - shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, scale_fx ); - - if ( GT_16( st->nbLostCmpt, 1 ) ) - { - shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); - } - } - ELSE - { - L_tmp = L_mult( scale_fx, scale_fx ); /* Q29 */ - shb_ener_sf_32 = L_shl( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); - } - } - ELSE - { - test(); - IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || - GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) - { - shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); - } - ELSE - { - shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); - } - } - } - - shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); - mixFactors_fx = hBWE_TD->prev_mixFactors_fx; - move16(); - - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ - } - ELSE - { - set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ - } - } - } - - /* get the gainshape delay */ - Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ - move16(); - } - - L_tmp = L_mult( voice_factors_fx[0], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors_fx[1], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors_fx[2], 8192 ); - mean_vf = mac_r( L_tmp, voice_factors_fx[3], 8192 ); - - Copy( voice_factors_fx, vf_modified_fx, NB_SUBFR16k ); - - test(); - IF( EQ_16( st->coder_type, VOICED ) || GT_16( mean_vf, 13107 /*0.4f Q15*/ ) ) - { - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mult( voice_factors_fx[i], 26214 /*0.8f Q15*/ ); - vf_modified_fx[i] = mac_r( L_tmp, voice_factors_fx[i - 1], 6554 /*0.2f Q15*/ ); - move16(); - } - - IF( st->L_frame != L_FRAME ) - { - L_tmp = L_mult( voice_factors_fx[4], 26214 /*0.8f Q15*/ ); - vf_modified_fx[4] = mac_r( L_tmp, voice_factors_fx[3], 6554 /*0.2f Q15*/ ); - move16(); - } - } - - test(); - IF( st->use_partial_copy && st->nelp_mode_dec ) - { - set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); - } - - /* SHB LSF from current frame; and convert to LSP for interpolation */ - E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); - - test(); - IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) - { - /* SHB LSP values from prev. frame for interpolation */ - Copy( hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); - } - ELSE - { - /* Use current frame's LSPs; in effect no interpolation */ - Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); - } - - test(); - test(); - test(); - IF( ( st->bws_cnt == 0 ) && ( st->bws_cnt1 == 0 ) && ( st->prev_use_partial_copy == 0 ) && ( st->use_partial_copy == 0 ) ) - { - lsf_diff_fx[0] = 16384; - move16(); /*Q15*/ - lsf_diff_fx[LPC_SHB_ORDER - 1] = 16384; - move16(); /*Q15*/ - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - lsf_diff_fx[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); - move16(); - } - - a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M ); - tmp = add( 16384, shr( refl_fx[0], 1 ) ); /*Q14*/ - tmp1 = mult( 27425, tmp ); - tmp1 = mult( tmp1, tmp ); /*Q10*/ - tmp2 = shr( mult( 31715, tmp ), 2 ); /*Q10*/ - tilt_para_fx = add( sub( tmp1, tmp2 ), 1335 ); /*Q10*/ - - test(); - IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) - { - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - hBWE_TD->prev_lsf_diff_fx[i - 1] = shr( lsf_diff_fx[i], 1 ); - move16(); - } - } - - IF( LE_32( st->extl_brate, FB_TBE_1k8 ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( !( GT_16( hBWE_TD->prev_tilt_para_fx, 5120 ) && ( EQ_16( st->coder_type, TRANSITION ) || LT_16( tilt_para_fx, 1024 ) ) ) && - !( ( ( LT_16( hBWE_TD->prev_tilt_para_fx, 3072 ) && GE_16( st->prev_coder_type, VOICED ) ) ) && GT_16( tilt_para_fx, 5120 ) ) ) - { - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - IF( LT_16( lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1] ) ) - { - tmp = mult( 26214, lsf_diff_fx[i] ); - - test(); - IF( ( hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ - { - st->BER_detect = 1; - move16(); - tmp = 0; - move16(); - } - ELSE - { - tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); - } - - tmp = s_max( tmp, 16384 ); - w_fx[i] = s_min( tmp, 32767 ); - move16(); - } - ELSE - { - tmp = mult( 26214, hBWE_TD->prev_lsf_diff_fx[i - 1] ); - - test(); - IF( ( lsf_diff_fx[i] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ - { - st->BER_detect = 1; - move16(); - tmp = 0; - move16(); - } - ELSE - { - tmp = div_s( tmp, lsf_diff_fx[i] ); - } - - tmp = s_max( tmp, 16384 ); - w_fx[i] = s_min( tmp, 32767 ); - move16(); - } - } - w_fx[0] = w_fx[1]; - move16(); - w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; - move16(); - - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w_fx[i] ) ); - tmp2 = mult( lsp_shb_2_fx[i], w_fx[i] ); - lsp_temp_fx[i] = add( tmp1, tmp2 ); - move16(); - } - } - ELSE - { - Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); - } - - /* convert from lsp to lsf */ - lsp2lsf_fx( lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1 ); - } - - Copy( lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); - hBWE_TD->prev_tilt_para_fx = tilt_para_fx; - move16(); - } - ELSE - { - Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); - } - - IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) - { - /* SHB LSP interpolation */ - ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ - FOR( j = 0; j < 4; j++ ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - L_tmp = L_mult( lsp_shb_1_fx[i], ( *ptr_lsp_interp_coef_fx ) ); - lsp_temp_fx[i] = mac_r( L_tmp, lsp_shb_2_fx[i], ( *( ptr_lsp_interp_coef_fx + 1 ) ) ); - move16(); - } - ptr_lsp_interp_coef_fx += 2; - - tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); - /* convert LSPs to LP coefficients */ - E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - /* Bring the LPCs to Q12 */ - Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); - lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this - move16(); -#endif - } - } - - /* Save the SWB LSP values from current frame for interpolation */ - Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); - - /* save the shb_ener and mixFactor values */ - hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; - move32(); - hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; - move32(); - hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; - move32(); - hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; - move16(); - hBWE_TD->prev_mixFactors_fx = mixFactors_fx; - move16(); - - /* SWB CNG/DTX - update memories */ - IF( st->hTdCngDec != NULL ) - { - Copy( st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); - Copy( lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); - } - - /* convert LSPs back into LP coeffs */ - E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER ); - Copy_Scale_sig( lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_fx[0] ), 2 ) ); /* Q12 */ - lpc_shb_fx[0] = ONE_IN_Q12; - move16(); - - test(); - IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - Word32 vind_temp = Mpy_32_32( L_shl( L_add( L_deposit_l( mixFactors_fx ), 1 ), 15 ), ( ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) << 16 ) ); // check addition of 1 - vind = extract_l( L_shr( vind_temp, 15 ) ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*7*/ - /* i: mixFactors_fx in Q15 */ - /* o: vind in Q0 */ - } - ELSE - { - vind = shl( mixFactors_fx, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*8*/ - /* i: mixFactors_fx in Q15 */ - /* o: vind in Q0 */ - } - - /* Determine formant PF strength */ - formant_fac_fx = swb_formant_fac_fx( lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx ); - /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ - IF( GT_32( st->total_brate, ACELP_32k ) ) - { - FOR( j = 0; j < 4; j++ ) - { - Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); - } - } - - /* From low band excitation, generate highband excitation */ - - /* -------- start of memory rescaling -------- */ - /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ - Lmax = 0; - move32(); - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) - { - Lmax = L_max( Lmax, L_abs( bwe_exc_extended_fx[cnt] ) ); - } - Q_bwe_exc = norm_l( Lmax ); - if ( Lmax == 0 ) - { - Q_bwe_exc = 31; - move16(); - } - Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); - find_max_mem_dec( st, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ - - tmp = add( st->prev_Q_bwe_exc, n_mem ); - if ( GT_16( Q_bwe_exc, tmp ) ) - { - Q_bwe_exc = tmp; - move16(); - } - - /* rescale the memories if Q_bwe_exc is different from previous frame */ - sc = sub( Q_bwe_exc, st->prev_Q_bwe_exc ); - IF( sc != 0 ) - { - rescale_genSHB_mem_dec( st, sc ); - } - - /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ - sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); - - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) - { - bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended_fx[cnt], sc ) ); - move16(); - } - - /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ - - /* save the previous Q factor (32-bit) of the buffer */ - st->prev_Q_bwe_exc = Q_bwe_exc; - move16(); - - Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ - - /* -------- end of rescaling memories -------- */ - - Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; - move16(); - - Q_shb = 0; - move16(); - - Copy( hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD ); - GenShapedSHBExcitation_ivas_dec_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, - hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, - st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, - &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, - shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, - st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, - NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); - - *Q_white_exc = Q_bwe_exc_fb; - move16(); - IF( EQ_16( st->extl, FB_TBE ) ) - { - st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; - move16(); - } - ELSE - { - /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. - 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ - st->prev_Q_bwe_exc_fb = 51; - move16(); - } - - /* rescale the TBE post proc memory */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); - move16(); - } - /* fill-in missing SHB excitation */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) - { - Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD ); - } - - IF( hStereoICBWE != NULL ) - { - Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); - } - - test(); - IF( NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) - { - /* TD BWE post-processing */ - PostShortTerm_ivas_dec_fx( &shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, - hBWE_TD->ptr_mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ), hBWE_TD->mem_zero_swb_fx, formant_fac_fx ); - } - - Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ - - tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); - prev_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - curr_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) - { - prev_pow_fx = L_mac0_sat( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ - curr_pow_fx = L_mac0_sat( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ - } - - if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) - { - curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ - } - - Lscale = root_a_over_b_fx( curr_pow_fx, - shl( Q_bwe_exc, 1 ), - prev_pow_fx, - shl( Q_bwe_exc, 1 ), - &exp ); - - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ - shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ - move16(); - } - IF( exp < 0 ) - { - Lscale = L_shl( Lscale, exp ); - exp = 0; - move16(); - } - FOR( ; i < L_SHB_LAHEAD + 10; i++ ) - { - temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ - temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); - Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ - shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ - move16(); - } - } - ELSE - { - /* reset the PF memories if the PF is not running */ - set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - } - - /* Update SHB excitation */ - Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ - l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; - move16(); - L_ener = EPSILON_FX_SMALL; - move32(); - - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - L_tmp = 0; - move32(); - ener_tmp_fx[i] = EPSILON_FX_SMALL; - move32(); - - Word64 tmp64 = 0; - move64(); - FOR( j = 0; j < l_subframe; j++ ) - { - tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )], shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )] ); /* 2*Q_bwe_exc */ - } - L_tmp = W_sat_l( tmp64 ); - - L_tmp = Mult_32_16( L_tmp, 410 /*0.0125 Q15*/ ); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ - IF( L_tmp != 0 ) - { - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( exp, sub( 30, i_mult( 2, Q_bwe_exc ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); - ener_tmp_fx[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ - move32(); - L_ener = L_add_sat( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ - } - } - ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ - /* WB/SWB bandwidth switching */ - IF( st->bws_cnt > 0 ) - { - IF( is_fractive == 0 ) - { - IF( GT_16( st->tilt_wb_fx, 2048 ) ) /*assuming st->tilt_wb_fx in Q11*/ - { - st->tilt_wb_fx = 2048; - move16(); - } - ELSE IF( LT_16( st->tilt_wb_fx, 1024 ) ) - { - st->tilt_wb_fx = 1024; - move16(); - } - test(); - if ( EQ_16( st->prev_fractive, 1 ) && GT_16( st->tilt_wb_fx, 1024 ) ) - { - st->tilt_wb_fx = 1024; - move16(); - } - } - ELSE - { - IF( GT_16( st->tilt_wb_fx, 8192 ) ) - { - IF( st->prev_fractive == 0 ) - { - st->tilt_wb_fx = 8192; - move16(); - } - ELSE - { - st->tilt_wb_fx = 16384; - move16(); - } - } - ELSE - { - st->tilt_wb_fx = shl( st->tilt_wb_fx, 2 ); - move16(); - } - } - - IF( ener_fx != 0 ) - { - L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 13 ) ); /* 2+11 +st->Q_syn2 -13 = st->Q_syn2*/ - exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = shr( div_s( 16384, tmp ), 1 ); /*Q(15+14-2-exp-1) = 26 - exp*/ - - test(); - IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ - { - st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ - move16(); - /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ - } - ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) - { - st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ - move16(); - /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ - } - L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ - GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ - } - ELSE - { - GainFrame_prevfrm_fx = 0; - move32(); - } - - IF( EQ_16( is_fractive, 1 ) ) - { - GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 10 ); - } - ELSE - { - GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 8 ); - } - - test(); - IF( EQ_16( ( is_fractive & st->prev_fractive ), 1 ) && GT_32( GainFrame_fx, GainFrame_prevfrm_fx ) ) - { - GainFrame_fx = L_add( Mult_32_16( GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); /* 18 +15 -15 = 18*/ - } - ELSE - { - test(); - test(); - test(); - test(); - IF( ( LT_32( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) ) && ( LT_32( L_shr( st->prev_enerLL_fx, 1 ), st->enerLL_fx ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) && ( s_xor( is_fractive, st->prev_fractive ) == 0 ) ) - { - GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( GainFrame_prevfrm_fx, 1 ) ); - } - ELSE - { - test(); - IF( ( is_fractive == 0 ) && EQ_16( st->prev_fractive, 1 ) ) - { - L_tmp1 = L_shl( Mult_32_16( GainFrame_fx, 3277 ), 13 ); /* 31 */ - L_tmp = L_sub( 2147483647, L_tmp1 ); /* 31 */ - GainFrame_fx = L_add( Mult_32_32( GainFrame_fx, L_tmp ), Mult_32_32( GainFrame_prevfrm_fx, L_tmp1 ) ); /* 18 */ - } - ELSE - { - GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( L_min( GainFrame_prevfrm_fx, GainFrame_fx ), 1 ) ); /* 18 */ - } - } - } - - GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( sub( N_WS2N_FRAMES, st->bws_cnt ), 819 ) ); /*Q18*/ - } - ELSE - { - IF( st->bws_cnt1 > 0 ) - { - GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( st->bws_cnt1, 819 ) ); /*Q18*/ - } - IF( GE_16( st->nbLostCmpt, 1 ) ) - { - ener_fx = s_max( 1, ener_fx ); - exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ - prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ - } - - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->clas_dec != UNVOICED_CLAS ) && NE_16( st->clas_dec, UNVOICED_TRANSITION ) && LT_16( hBWE_TD->tilt_swb_fec_fx, 16384 ) && - ( ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st->enerLL_fx, 1 ), st->prev_enerLL_fx ) ) || ( GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st->enerLH_fx, 1 ), st->prev_enerLH_fx ) ) ) ) - { - IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) ) /*18*/ - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 13107 ), Mult_32_16( GainFrame_fx, 19661 ) ); /*18*/ - } - ELSE IF( GT_32( L_shr( prev_ener_ratio_fx, 1 ), GainFrame_fx ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); - } - ELSE - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); - } - - test(); - IF( GT_16( tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx ) && ( hBWE_TD->tilt_swb_fec_fx > 0 ) ) - { - exp = norm_s( hBWE_TD->tilt_swb_fec_fx ); - tmp = shl( hBWE_TD->tilt_swb_fec_fx, exp ); /*Q(11+exp)*/ - tmp = div_s( 16384, tmp ); /*Q(15+14-11-exp)*/ - tmp = extract_h( L_shl( L_mult0( tmp, st->tilt_wb_fx ), sub( exp, 1 ) ) ); /*18 -exp +11 + exp -1 -16 =12; */ - GainFrame_fx = L_shl( Mult_32_16( GainFrame_fx, s_min( tmp, 20480 ) ), 3 ); /*Q18 = 18 +12 -15 +3 */ - } - } - ELSE IF( ( ( st->clas_dec != UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 4096 ) ) && GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); - } - } - ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) - { - test(); - IF( GT_16( tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) ) - { - GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6554 /*0.2f in Q15*/ ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 /*4.0f in Q12*/ ), 3 ) ); /*Q18*/ - } - ELSE - { - GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 16384 ), Mult_32_16( GainFrame_fx, 16384 ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 ), 3 ) ); /*Q18*/ - } - } - ELSE IF( GT_32( prev_ener_ratio_fx, GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) - { - test(); - IF( GT_16( tilt_swb_fec_fx, 20480 ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 16384 /*0.5f in Q15*/ ), Mult_32_16( GainFrame_fx, 16384 /*0.5f in Q15*/ ) ); /* Q18 */ - } - ELSE - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 /*0.2f in Q15*/ ), Mult_32_16( GainFrame_fx, 26214 /*0.8f in Q15*/ ) ); /* Q18 */ - } - } - } - } - - st->prev_fractive = is_fractive; - move16(); - - /* Adjust the subframe and frame gain of the synthesized shb signal */ - /* Scale the shaped excitation */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - L_tmp = L_mult( pitch_buf_fx[0], 8192 ); - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 8192 ); /* pitch_buf in Q6 x 0.25 in Q15 */ - } - pitch_fx = round_fx( L_tmp ); /* Q6 */ - } - ELSE - { - L_tmp = L_mult( pitch_buf_fx[0], 6554 ); - FOR( i = 1; i < NB_SUBFR16k; i++ ) - { - L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 6554 ); /* pitch_buf in Q6 x 0.2 in Q15 */ - } - pitch_fx = round_fx( L_tmp ); /* Q6 */ - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( GE_32( st->extl_brate, SWB_TBE_2k8 ) && EQ_16( st->prev_coder_type, st->coder_type ) && NE_16( st->coder_type, UNVOICED ) ) || ( LT_32( st->extl_brate, SWB_TBE_2k8 ) && ( EQ_16( st->prev_coder_type, st->coder_type ) || ( EQ_16( st->prev_coder_type, VOICED ) && EQ_16( st->coder_type, GENERIC ) ) || ( EQ_16( st->prev_coder_type, GENERIC ) && EQ_16( st->coder_type, VOICED ) ) ) ) ) && GT_16( pitch_fx, 4480 /*70 in Q6*/ ) && LT_16( st->extl, FB_TBE ) && NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_tmp_fx[i] = GainShape_fx[i * 4]; /* Q15 */ - move16(); - } - - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ - L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ - tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); - L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ - IF( GT_32( L_tmp1, L_tmp2 ) ) - { - L_tmp = L_tmp2; - move32(); - if ( L_tmp2 < 0 ) - { - L_tmp = L_negate( L_tmp2 ); - } - - expb = norm_l( L_tmp ); - fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); - expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ - - expa = norm_l( ener_tmp_fx[i] ); - fraca = extract_h( L_shl( ener_tmp_fx[i], expa ) ); - expa = sub( 30, expa ); - - scale_fx = shr( sub( fraca, fracb ), 15 ); - fracb = shl( fracb, scale_fx ); - expb = sub( expb, scale_fx ); - - tmp = div_s( fracb, fraca ); - exp = sub( sub( expb, expa ), 1 ); - tmp = shl( tmp, exp ); - GainShape_tmp_fx[i] = add( tmp, shr( GainShape_tmp_fx[i], 1 ) ); /* Q15 */ - move16(); - } - - hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; - move32(); - hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; - move16(); - st->prev_ener_fx_Q = Q_bwe_exc; - move16(); - } - - FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); - } - GainShape_fx[i] = GainShape_tmp_fx[idx]; - move16(); - } - } - ELSE - { - st->prev_ener_fx_Q = Q_bwe_exc; - move16(); - } - st->prev_Q_bwe_syn = Q_bwe_exc; - move16(); - - - /* Gain shape smoothing after quantization */ - test(); - IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; - move16(); - } - - lls_interp_n_fx( GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1 ); - - test(); - IF( GE_16( vind, 6 ) && LT_16( abs_s( GainShape_tilt_fx ), 3932 ) ) - { - feedback_fx = 9830; - move16(); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_fx[i] = add_sat( mult( sub( 32767, feedback_fx ), GainShape_fx[i * NUM_SHB_SUBGAINS] ), mult( feedback_fx, GainShape_tmp_fx[i] ) ); - move16(); - } - - FOR( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); - } - GainShape_fx[i] = GainShape_fx[idx]; - move16(); - } - } - } - - /* fil-in missing memory */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) - { - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - Word16 intermediate = mult( shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i] ); - Word32 intermediate_32 = Mpy_32_16_1( Mpy_32_16_1( GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i] ), intermediate ); - hBWE_TD->syn_overlap_fx[i] = round_fx( L_shl_sat( intermediate_32, sub( 16, ( add( Q_bwe_exc, 18 - 15 ) ) ) ) ); - move16(); - } - } - - Word16 n_mem3_new = 0; - move16(); - find_max_mem_dec_m3( st, &n_mem3_new ); - - ScaleShapedSHB_fx( SHB_OVERLAP_LEN, - shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ - hBWE_TD->syn_overlap_fx, - GainShape_fx, /* Q15 */ - GainFrame_fx, /* Q18 */ - window_shb_fx, - subwin_shb_fx, - &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); - - IF( hStereoICBWE != NULL ) - { - Copy_Scale_sig_16_32_DEPREC( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); - Copy( GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR ); - hStereoICBWE->gFrameRef_fx = GainFrame_fx; - move32(); - - Copy( shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); - } - - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - max_val = s_max( max_val, abs_s( shaped_shb_excitation_fx[i] ) ); /* Q0 */ - } - IF( max_val == 0 ) - { - curr_frame_pow_fx = 0; - move32(); - n = 0; - move16(); - } - ELSE - { - n = norm_s( max_val ); - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ - move16(); - } - - curr_frame_pow_fx = 0; - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ - curr_frame_pow_fx = L_add( curr_frame_pow_fx, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ - } - } - curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); - tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); - IF( tmp > 0 ) /* shifting prev */ - { - IF( GT_16( tmp, 32 ) ) - { - st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); - move16(); - tmp = 32; - move16(); - } - hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); - move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; - move16(); - } - ELSE /* shifting curr */ - { - IF( LT_16( tmp, -32 ) ) - { - curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); - tmp = -32; - move16(); - } - curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); - curr_frame_pow_exp = st->prev_frame_pow_exp; - move16(); - } - test(); - test(); - IF( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) - { - test(); - test(); - IF( ( GT_32( L_shr( curr_frame_pow_fx, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) && - ( GT_32( hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16( st->prev_coder_type, UNVOICED ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ - - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ - } - ELSE - { - scale_fx = temp_fx = 32767; - move16(); /*Q15*/ - move16(); /*Q15*/ - } - - FOR( j = 0; j < 8; j++ ) - { - GainShape_fx[2 * j] = mult_r( GainShape_fx[2 * j], scale_fx ); - move16(); - GainShape_fx[2 * j + 1] = mult_r( GainShape_fx[2 * j + 1], scale_fx ); - move16(); - FOR( i = 0; i < L_FRAME16k / 8; i++ ) - { - shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )] = mult_r( shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )], scale_fx ); - move16(); - } - - IF( temp_fx > 0 ) - { - /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) - and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ - IF( LT_16( scale_fx, temp_fx ) ) - { - scale_fx = div_s( scale_fx, temp_fx ); - } - ELSE - { - scale_fx = 32767; - move16(); - } - } - ELSE - { - scale_fx = 0; - move16(); - } - } - } - - /* adjust the FEC frame energy */ - IF( st->bfi ) - { - scale_fx = temp_fx = 4096; - move16(); /*Q12*/ - move16(); - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) && - NE_16( st->prev_coder_type, UNVOICED ) && - ( st->last_good != UNVOICED_CLAS ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); /*31 - exp*/ - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && EQ_16( st->nbLostCmpt, 1 ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && - ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - } - ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && - ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - } - - FOR( j = 0; j < 8; j++ ) - { - GainShape_fx[2 * j] = shl_sat( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); - move16(); /* 15 +12 +3-15 =15*/ - GainShape_fx[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape_fx[add( 2 * j, 1 )], scale_fx ), 3 ); - move16(); - FOR( i = 0; i < 40; i++ ) - { - shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = shl( mult_r( shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx ), 3 ); - move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ - } - - IF( temp_fx > 0 ) - { - IF( LT_16( scale_fx, temp_fx ) ) - { - scale_fx = shr( div_s( scale_fx, temp_fx ), 3 ); - } - ELSE - { - tmp1 = sub( norm_s( scale_fx ), 1 ); - tmp2 = norm_s( temp_fx ); - scale_fx = div_s( shl( scale_fx, tmp1 ), shl( temp_fx, tmp2 ) ); - scale_fx = shr( scale_fx, add( sub( tmp1, tmp2 ), 3 ) ); - } - } - ELSE - { - scale_fx = 0; - move16(); - } - } - } - - hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; - move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; - move16(); - - Word64 prev_ener_shb64 = 0; - move64(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* Q0 */ - } - L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); - - L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ - st->prev_ener_shb_fx = 0; - move16(); - IF( L_prev_ener_shb != 0 ) - { - exp = norm_l( L_prev_ener_shb ); - tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); - exp = sub( exp, sub( 30, ( add( i_mult( 2, Q_bwe_exc ), 8 ) ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); - st->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ - move16(); - } - - IF( st->hBWE_FD != NULL ) - { - L_tmp = Mult_32_16( curr_frame_pow_fx, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ - tmp = 0; - move16(); - IF( L_tmp != 0 ) - { - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( exp, sub( 30, add( curr_frame_pow_exp, 8 ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); - tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ - } - set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ - } - - FOR( i = 0; i < L_FRAME16k; i++ ) - { - shaped_shb_excitation_fx_32[i] = L_shl( shaped_shb_excitation_fx[i], sub( Q11, Q_bwe_exc ) ); - move32(); - } - - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ - GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); - Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); - - /* resample SHB synthesis (if needed) and scale down */ - synth_scale_fx = 32767; - move16(); /* 1.0 in Q15 */ - if ( EQ_16( st->codec_mode, MODE1 ) ) - { - synth_scale_fx = 29491; - move16(); /* 0.9 in Q15 */ - } - - IF( EQ_32( st->output_Fs, 48000 ) ) - { - IF( EQ_16( st->extl, FB_TBE ) ) - { - tmp = norm_l( GainFrame_fx ); - if ( GainFrame_fx == 0 ) - { - tmp = 31; - move16(); - } - L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ - - tmp1 = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); - } - L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ - White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ - move16(); - tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); - } - - *Q_white_exc = sub( add( *Q_white_exc, tmp ), 13 ); /* *Q_white_exc + 18 + tmp -15 -16 */ - move16(); - tmp = norm_s( tmp1 ); - if ( tmp1 == 0 ) - { - tmp = 15; - move16(); - } - - FOR( i = 0; i < L_FRAME16k; i++ ) - { - White_exc16k_fx[i] = shl( White_exc16k_fx[i], sub( tmp, 1 ) ); - move16(); - } - *Q_white_exc = sub( add( *Q_white_exc, tmp ), 1 ); - move16(); - } - - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); - } - } - interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( st->output_Fs, 32000 ) ) - { - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - synth_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); /*Qx*/ - } - } - ELSE - { - Copy32( error_fx, synth_fx, L_FRAME32k ); - } - } - ELSE IF( EQ_32( st->output_Fs, 16000 ) ) - { - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); - } - } - - Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); - } - - - /* Update previous frame parameters for FEC */ - Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; - move32(); /*Q18*/ - hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; - move16(); - - if ( !st->bfi ) - { - hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ - move16(); - } - } - ELSE - { - IF( !st->bfi ) - { - hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; - move32(); /*Q18*/ - hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; - move16(); - hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ - move16(); - } - } - - hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; - move32(); - hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; - move16(); - st->prev_Q_bwe_syn2 = Q_bwe_exc; - move16(); - st->prev_Qx = Q_bwe_exc; - move16(); - - return; -} -/*-------------------------------------------------------------------* - * Dequant_lower_LSF() - * - * Dequantized the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * Map_higher_LSF() - * - * Map the higher LSFs from the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * Map_higher_LSF() - * - * Map the higher LSFs from the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * dequantizeSHBparams() - * - * Dequantize super highband spectral envolope, temporal gains and frame gain - *-------------------------------------------------------------------*/ - - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ) -{ - Word16 i, length; - - Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); - - /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ - test(); - test(); - test(); - test(); - IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) - { - flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); - } - ELSE - { - FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); - } - ELSE - { - syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; - } - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); - move32(); - } - - IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( output_Fs, 16000 ) ) - { - Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); - } - - return; -} -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -) -{ - Word16 i, length; - Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; - Word32 upsampled_synth_fx[L_FRAME48k]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); - Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); - - /* perform spectral flip and downmix with overlap snippet to match HB synth */ - FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); - move32(); - } - ELSE - { - speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* upsampling if necessary */ - IF( EQ_32( output_Fs, 32000 ) ) - { - Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); - } - ELSE IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); - } - - return; -} - -/*-------------------------------------------------------------------* - * td_bwe_dec_init() - * - * Initialize TD BWE state structure at the decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 28ac01671..a37ebf9d9 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7,6 +7,7 @@ #include "options.h" #include "rom_com.h" #include "prot_fx.h" +#include "prot.h" #include "rom_dec.h" #include "stl.h" @@ -31,6 +32,11 @@ Word16 dotp_loc( const Word16 n /* i : vector length */ ); +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 ); + + /* gain shape concealment code */ static void gradientGainShape( Decoder_State *st_fx, Word16 *GainShape, Word32 *GainFrame ); @@ -3695,12 +3701,12 @@ static void gradientGainShape( IF( GT_16( 8192, tmp ) ) { - GainShape[add( i * 4, j )] = shl( tmp, 2 ); + GainShape[i * 4 + j] = shl( tmp, 2 ); move16(); /* (GainShapeTemp[i]*0.6)>>1 */ } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ } } @@ -3716,12 +3722,12 @@ static void gradientGainShape( { IF( LT_16( GainShapeTemp[i], 16384 ) ) { - GainShape[add( i * 4, j )] = shl( GainShapeTemp[i], 1 ); + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); move16(); } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); } } @@ -3750,12 +3756,12 @@ static void gradientGainShape( { IF( LT_16( GainShapeTemp[i], 16384 ) ) { - GainShape[add( i * 4, j )] = shl( GainShapeTemp[i], 1 ); + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); move16(); } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); } } @@ -5300,3 +5306,2019 @@ void td_bwe_dec_init_fx( return; } + +/*-------------------------------------------------------------------* + * ResetSHBbuffer_Dec() + * + * + *-------------------------------------------------------------------*/ + +static void calc_tilt_bwe_fx_loc( + const Word32 *sp_fx, /* i : input signal : Q11 */ + Word32 *tilt_fx, /* o : signal tilt : tilt_fx_q */ + Word16 *tilt_fx_q, /* o : signal tilt */ + const Word16 N /* i : signal length : Q0 */ +) +{ + Word16 i; + Word64 r0_fx, r1_fx; + + r0_fx = EPSILON_FX_SMALL; + move64(); + FOR( i = 0; i < N; i++ ) + { + r0_fx = W_add( r0_fx, W_shr( W_mult_32_32( sp_fx[i], sp_fx[i] ), 1 ) ); /*Q11*2 - 1*/ + } + r1_fx = W_deposit32_l( abs( L_sub( sp_fx[1], sp_fx[0] ) ) ); /*Q11*/ + FOR( i = 2; i < N; i++ ) + { + IF( W_mult_32_32( L_sub( sp_fx[i], sp_fx[i - 1] ) /*Q11*/, L_sub( sp_fx[i - 1], sp_fx[i - 2] ) /*Q11*/ ) /*Q11 * 2 - 1*/ < 0 ) + { + r1_fx = W_add( r1_fx, W_deposit32_l( abs( L_sub( sp_fx[i], sp_fx[i - 1] ) ) ) ); /*Q11*/ + } + } + Word16 headroom_left_r0 = W_norm( r0_fx ); + Word16 headroom_left_r1 = W_norm( r1_fx ); + Word16 r0_q = 0, r1_q = 0; + move16(); + move16(); + IF( LT_16( headroom_left_r0, 32 ) ) + { + r0_fx = W_shr( r0_fx, sub( 32, headroom_left_r0 ) ); + r0_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_r0 ) ) ); + } + ELSE + { + r0_q = 31 - ( 2 * OUTPUT_Q ); + move16(); + } + + IF( LT_16( headroom_left_r1, 32 ) ) + { + r1_fx = W_shr( r1_fx, sub( 32, headroom_left_r1 ) ); + r1_q = sub( OUTPUT_Q, sub( 32, headroom_left_r1 ) ); + } + ELSE + { + r1_q = OUTPUT_Q; + move16(); + } + Word32 temp_r0_inv = ISqrt32( W_extract_l( r0_fx ), &r0_q ); + Word32 res = Mpy_32_32( W_extract_l( r1_fx ), temp_r0_inv ); + // Word16 res_q = r1_q + ( r0_q < 0 ? ( 31 + ( -1 * r0_q ) ) : r0_q ) - 31; + Word16 res_q; + IF( r0_q < 0 ) + { + res_q = add( r1_q, sub( add( 31, -r0_q ), 31 ) ); + } + ELSE + { + res_q = add( r1_q, sub( r0_q, 31 ) ); + } + Word16 norm_res = norm_l( res ); + IF( norm_res > 0 ) + { + *tilt_fx = L_shl_sat( res, norm_res ); + move32(); + *tilt_fx_q = add( res_q, norm_res ); + move16(); + } + ELSE + { + *tilt_fx = res; + move32(); + *tilt_fx_q = res_q; + move16(); + } + return; +} + +/*-------------------------------------------------------------------* + * swb_tbe_dec() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +static void rescale_genSHB_mem_dec_ivas( + Decoder_State *st_fx, + Word16 sf /*Q0*/ +) +{ + Word16 i; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); + move16(); + } + + /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ + IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); + move16(); + } + } + + hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); + move32(); + + hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); + move16(); + hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); + move16(); +} + +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 ) +{ + Word16 i; + // Word16 n_mem_32; + Word16 tempQ15; + Word16 max3; + // Word32 tempQ32, Lmax3; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + /* --------------------------------------------------------------*/ + /* Find headroom for synthesis stage associated with these memories: + 1. st->syn_overlap_fx*/ + max3 = 0; + move16(); + /* find max in prev overlapSyn */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); + max3 = s_max( max3, tempQ15 ); + } + /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ + + /* estimate the norm for 16-bit memories */ + *n_mem3 = norm_s( max3 ); + move16(); + if ( max3 == 0 ) + { + *n_mem3 = 15; + move16(); + } +} + +/*-------------------------------------------------------------------* + * ivas_swb_tbe_dec_fx() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +void ivas_swb_tbe_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ + const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation : Q_exc */ + Word16 Q_exc, + const Word16 voice_factors_fx[], /* i : voicing factors : Q15 */ + const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis : old_syn_fx */ + Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE : Q_white_exc*/ + Word32 *synth_fx, /* o : SHB synthesis/final synthesis : Qx */ + Word16 *pitch_buf_fx, /* i : Q6 */ + Word16 *Q_white_exc ) +{ + Word16 i, j, cnt, n; + Word16 stemp; + TD_BWE_DEC_HANDLE hBWE_TD; + Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; + Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; + Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; + Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; // Q12,Q12,Q15 + Word32 GainFrame_fx; // Q18 + Word32 error_fx[L_FRAME32k]; + Word16 ener_fx; + Word32 L_ener; + Word16 is_fractive; + Word32 prev_pow_fx, curr_pow_fx, Lscale; + Word16 scale_fx; + Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; + Word32 curr_frame_pow_fx; + Word16 curr_frame_pow_exp; + Word32 L_prev_ener_shb; + Word16 vf_modified_fx[NB_SUBFR16k]; + Word16 f_fx, inc_fx; + Word32 GainFrame_prevfrm_fx; + Word32 tilt_swb_fec_32_fx; + Word16 tilt_swb_fec_fx_q; + Word16 tilt_swb_fec_fx; + Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ + Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; + Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; + const Word16 *ptr_lsp_interp_coef_fx; + Word32 shb_ener_sf_32; + Word16 shb_res_gshape_fx[NB_SUBFR16k]; + Word16 mixFactors_fx; + Word16 vind; + Word16 shb_res_dummy_fx[L_FRAME16k]; + Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; + Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; + Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; + Word16 pitch_fx; + Word16 l_subframe; + Word16 formant_fac_fx; + Word16 synth_scale_fx; + Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; + Word16 refl_fx[M]; + Word16 tilt_para_fx; + Word16 *nlExc16k_fx, *mixExc16k_fx; + Word16 MSFlag; + Word16 feedback_fx; + Word16 GainShape_tilt_fx; + + // scaling + Word16 exp, tmp; + Word16 tmp1, tmp2; + Word16 mean_vf; + Word32 Lmax, L_tmp; + Word16 frac; + Word32 L_tmp1, L_tmp2; + Word16 Q_bwe_exc; + Word16 Q_bwe_exc_fb; + Word16 Q_shb; + Word16 n_mem, n_mem2, n_mem3, Qx, sc; + Word16 expa, expb; + Word16 fraca, fracb; + Word16 exp_ener, inv_ener; + + hBWE_TD = st->hBWE_TD; + + /* initializations */ + GainFrame_fx = 0; + move32(); + mixFactors_fx = 0; + move16(); + shb_ener_sf_32 = 0; + move32(); + set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); + if ( st->hTdCngDec != NULL ) + { + st->hTdCngDec->shb_dtx_count = 0; + move16(); + } + is_fractive = 0; + move16(); + + IF( hStereoICBWE != NULL ) + { + nlExc16k_fx = hStereoICBWE->nlExc16k_fx; + mixExc16k_fx = hStereoICBWE->mixExc16k_fx; + MSFlag = hStereoICBWE->MSFlag; + move16(); + } + ELSE + { + nlExc16k_fx = NULL; + mixExc16k_fx = NULL; + MSFlag = 0; + move16(); + } + + /* find tilt */ + calc_tilt_bwe_fx_loc( old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME ); + tilt_swb_fec_fx = round_fx_sat( L_shl_sat( tilt_swb_fec_32_fx, sub( 11 + 16, tilt_swb_fec_fx_q ) ) ); + test(); + if ( st->bfi && st->clas_dec != UNVOICED_CLAS ) + { + tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; + move16(); + } + + /* WB/SWB bandwidth switching */ + test(); + test(); + IF( ( GT_16( st->tilt_wb_fx, 10240 /*5 in Q11*/ ) && ( EQ_16( st->clas_dec, UNVOICED_CLAS ) ) ) || GT_16( st->tilt_wb_fx, 20480 /*10 in Q11*/ ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( st->prev_fractive == 0 ) && + ( LT_32( st->prev_enerLH_fx, L_shl( st->enerLH_fx, 1 ) ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) && LT_32( st->prev_enerLL_fx, L_shl( st->enerLL_fx, 1 ) ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) ) || + ( EQ_16( st->prev_fractive, 1 ) && + GT_32( L_shr( st->prev_enerLH_fx, 2 ), Mult_32_16( st->enerLH_fx, 24576 ) ) ) /* 24576 in Q13*/ + || ( GT_32( L_shr( st->enerLL_fx, 1 ), Mult_32_16( st->enerLH_fx, 24576 ) ) && /*24576 = 1.5 in Q14*/ + LT_16( st->tilt_wb_fx, 20480 ) ) /* 20480 = 10 in Q11*/ + ) + { + is_fractive = 0; + } + ELSE + { + is_fractive = 1; + } + move16(); + } + + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + f_fx = 1489; /*1.0f / 22.0f in Q15*/ + move16(); + inc_fx = 1489; /*1.0f / 22.0f in Q15*/ + move16(); + + IF( EQ_16( is_fractive, 1 ) ) + { + Copy( lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + } + ELSE + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); /*Q15*/ + } + } + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && !( ( L_sub( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) < 0 ) && L_sub( st->prev_enerLH_fx, ( L_shr( st->enerLH_fx, 1 ) > 0 ) ) ) ) || st->last_core != ACELP_CORE || ( ( st->last_core == ACELP_CORE ) && GT_32( abs( L_sub( st->last_core_brate, st->core_brate ) ), 3600 ) ) || EQ_16( s_xor( is_fractive, st->prev_fractive ), 1 ) ) + { + set16_fx( GainShape_fx, 11587, NUM_SHB_SUBFR ); /*0.3536f in Q15*/ + } + ELSE + { + if ( GT_16( hBWE_TD->prev_GainShape_fx, 11587 ) ) /*0.3536f in Q15*/ + { + hBWE_TD->prev_GainShape_fx = 11587; /*0.3536f in Q15*/ + move16(); + } + set16_fx( GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); + } + + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ + } + ELSE + { + test(); + IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) + { + f_fx = 1489; /*Q15*/ + move16(); + inc_fx = 1489; /*Q15*/ + move16(); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); + } + } + + IF( !st->bfi ) + { + IF( st->use_partial_copy ) + { + IF( NE_16( st->last_extl, SWB_TBE ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = 0; + move32(); + f_fx = 1489 /*0.045454f Q15*/; + move16(); + inc_fx = 1489 /*0.045454f Q15*/; + move16(); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); /*Q15*/ + } + } + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + set16_fx( GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); + + IF( EQ_16( st->rf_frame_type, RF_NELP ) ) + { + /* Frame gain */ + + GainFrame_fx = L_mac( SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); + L_tmp = Mult_32_16( GainFrame_fx, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ + + frac = L_Extract_lc( L_tmp, &exp ); + L_tmp = Pow2( 30, frac ); + GainFrame_fx = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && !st->prev_use_partial_copy && EQ_16( st->prev_coder_type, UNVOICED ) && NE_32( GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx ) && NE_16( st->next_coder_type, GENERIC ) && EQ_16( st->last_extl, SWB_TBE ) ) + { + GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6553 /*0.2f in Q15*/ ) ); + } + } + ELSE + { + temp_fx = 0; + move16(); + /* Frame gain */ + SWITCH( st->rf_indx_tbeGainFr ) + { + case 0: + GainFrame_fx = 131072; /* 0.5f in Q18 */ + move32(); + if ( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 1: + GainFrame_fx = 524288; /* 2.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 2: + GainFrame_fx = 1048576; /* 4.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 3: + GainFrame_fx = 2097152; /* 8.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + default: + fprintf( stderr, "RF SWB-TBE gain bits not supported." ); + } + + IF( EQ_16( st->last_extl, SWB_TBE ) ) + { + GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp_fx ), Mult_32_16( GainFrame_fx, sub( 32767, temp_fx ) ) ); + /*Q18*/ + } + + IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) ) + { + if ( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, VOICED ) && EQ_16( st->rf_frame_type, RF_GENPRED ) && GT_32( GainFrame_fx, 2097152 /*8.0f in Q18*/ ) && LT_32( GainFrame_fx, 3059606 /*11.67f in Q18*/ ) ) + { + GainFrame_fx = Mult_32_16( GainFrame_fx, 9830 /*0.3f in Q15*/ ); // Q18 + } + } + } + } + ELSE + { + /* de-quantization */ + ivas_dequantizeSHBparams_fx_9_1( st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, + &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag ); + if ( hStereoICBWE != NULL ) + { + hStereoICBWE->MSFlag = MSFlag; + move16(); + } + } + } + ELSE + { + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) + { + gradientGainShape( st, GainShape_fx, &GainFrame_fx ); + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); + move16(); + } + } + IF( GT_16( tilt_swb_fec_fx, ( 8 << 11 ) ) ) /* tilt_swb_fec_fx in Q11 */ + { + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); + } + ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); + } + ELSE + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); + } + GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); + } + ELSE + { + GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; + move32(); /* gain locking */ + } + } + + IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) + { + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) + { + L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ + tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ + tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ + i = sub( norm_s( tmp1 ), 1 ); + tmp1 = shl( tmp1, i ); /* Qi */ + IF( tmp == 0 ) + { + tmp = 32767 /*1.0f Q15*/; + move16(); /*Q15*/ + } + ELSE + { + scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ + scale_fx = s_max( scale_fx, 0 ); + tmp = shl_sat( scale_fx, sub( sub( 15, exp ), i ) ); /*Q15*/ + } + scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ + test(); + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, scale_fx ); + + if ( GT_16( st->nbLostCmpt, 1 ) ) + { + shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); + } + } + ELSE + { + L_tmp = L_mult( scale_fx, scale_fx ); /* Q29 */ + shb_ener_sf_32 = L_shl( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); + } + } + ELSE + { + test(); + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); + } + ELSE + { + shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); + } + } + } + + shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); + mixFactors_fx = hBWE_TD->prev_mixFactors_fx; + move16(); + + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ + } + ELSE + { + set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ + } + } + } + + /* get the gainshape delay */ + Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ + move16(); + } + + L_tmp = L_mult( voice_factors_fx[0], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors_fx[1], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors_fx[2], 8192 ); + mean_vf = mac_r( L_tmp, voice_factors_fx[3], 8192 ); + + Copy( voice_factors_fx, vf_modified_fx, NB_SUBFR16k ); + + test(); + IF( EQ_16( st->coder_type, VOICED ) || GT_16( mean_vf, 13107 /*0.4f Q15*/ ) ) + { + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mult( voice_factors_fx[i], 26214 /*0.8f Q15*/ ); + vf_modified_fx[i] = mac_r( L_tmp, voice_factors_fx[i - 1], 6554 /*0.2f Q15*/ ); + move16(); + } + + IF( st->L_frame != L_FRAME ) + { + L_tmp = L_mult( voice_factors_fx[4], 26214 /*0.8f Q15*/ ); + vf_modified_fx[4] = mac_r( L_tmp, voice_factors_fx[3], 6554 /*0.2f Q15*/ ); + move16(); + } + } + + test(); + IF( st->use_partial_copy && st->nelp_mode_dec ) + { + set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); + } + + /* SHB LSF from current frame; and convert to LSP for interpolation */ + E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); + + test(); + IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) + { + /* SHB LSP values from prev. frame for interpolation */ + Copy( hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); + } + ELSE + { + /* Use current frame's LSPs; in effect no interpolation */ + Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); + } + + test(); + test(); + test(); + IF( ( st->bws_cnt == 0 ) && ( st->bws_cnt1 == 0 ) && ( st->prev_use_partial_copy == 0 ) && ( st->use_partial_copy == 0 ) ) + { + lsf_diff_fx[0] = 16384; + move16(); /*Q15*/ + lsf_diff_fx[LPC_SHB_ORDER - 1] = 16384; + move16(); /*Q15*/ + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + lsf_diff_fx[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); + move16(); + } + + a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M ); + tmp = add( 16384, shr( refl_fx[0], 1 ) ); /*Q14*/ + tmp1 = mult( 27425, tmp ); + tmp1 = mult( tmp1, tmp ); /*Q10*/ + tmp2 = shr( mult( 31715, tmp ), 2 ); /*Q10*/ + tilt_para_fx = add( sub( tmp1, tmp2 ), 1335 ); /*Q10*/ + + test(); + IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) + { + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + hBWE_TD->prev_lsf_diff_fx[i - 1] = shr( lsf_diff_fx[i], 1 ); + move16(); + } + } + + IF( LE_32( st->extl_brate, FB_TBE_1k8 ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( !( GT_16( hBWE_TD->prev_tilt_para_fx, 5120 ) && ( EQ_16( st->coder_type, TRANSITION ) || LT_16( tilt_para_fx, 1024 ) ) ) && + !( ( ( LT_16( hBWE_TD->prev_tilt_para_fx, 3072 ) && GE_16( st->prev_coder_type, VOICED ) ) ) && GT_16( tilt_para_fx, 5120 ) ) ) + { + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + IF( LT_16( lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1] ) ) + { + tmp = mult( 26214, lsf_diff_fx[i] ); + + test(); + IF( ( hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + move16(); + } + ELSE + { + tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); + } + + tmp = s_max( tmp, 16384 ); + w_fx[i] = s_min( tmp, 32767 ); + move16(); + } + ELSE + { + tmp = mult( 26214, hBWE_TD->prev_lsf_diff_fx[i - 1] ); + + test(); + IF( ( lsf_diff_fx[i] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + move16(); + } + ELSE + { + tmp = div_s( tmp, lsf_diff_fx[i] ); + } + + tmp = s_max( tmp, 16384 ); + w_fx[i] = s_min( tmp, 32767 ); + move16(); + } + } + w_fx[0] = w_fx[1]; + move16(); + w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; + move16(); + + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w_fx[i] ) ); + tmp2 = mult( lsp_shb_2_fx[i], w_fx[i] ); + lsp_temp_fx[i] = add( tmp1, tmp2 ); + move16(); + } + } + ELSE + { + Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); + } + + /* convert from lsp to lsf */ + lsp2lsf_fx( lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1 ); + } + + Copy( lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); + hBWE_TD->prev_tilt_para_fx = tilt_para_fx; + move16(); + } + ELSE + { + Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); + } + + IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) + { + /* SHB LSP interpolation */ + ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ + FOR( j = 0; j < 4; j++ ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + L_tmp = L_mult( lsp_shb_1_fx[i], ( *ptr_lsp_interp_coef_fx ) ); + lsp_temp_fx[i] = mac_r( L_tmp, lsp_shb_2_fx[i], ( *( ptr_lsp_interp_coef_fx + 1 ) ) ); + move16(); + } + ptr_lsp_interp_coef_fx += 2; + + tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); + /* convert LSPs to LP coefficients */ + E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); +#ifndef FIX_1100_REMOVE_LPC_RESCALING + /* Bring the LPCs to Q12 */ + Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); + lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this + move16(); +#endif + } + } + + /* Save the SWB LSP values from current frame for interpolation */ + Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); + + /* save the shb_ener and mixFactor values */ + hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; + move32(); + hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; + move32(); + hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; + move32(); + hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; + move16(); + hBWE_TD->prev_mixFactors_fx = mixFactors_fx; + move16(); + + /* SWB CNG/DTX - update memories */ + IF( st->hTdCngDec != NULL ) + { + Copy( st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); + Copy( lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); + } + + /* convert LSPs back into LP coeffs */ + E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER ); + Copy_Scale_sig( lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_fx[0] ), 2 ) ); /* Q12 */ + lpc_shb_fx[0] = ONE_IN_Q12; + move16(); + + test(); + IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + Word32 vind_temp = Mpy_32_32( L_shl( L_add( L_deposit_l( mixFactors_fx ), 1 ), 15 ), ( ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) << 16 ) ); // check addition of 1 + vind = extract_l( L_shr( vind_temp, 15 ) ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*7*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + ELSE + { + vind = shl( mixFactors_fx, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*8*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + + /* Determine formant PF strength */ + formant_fac_fx = swb_formant_fac_fx( lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx ); + /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ + IF( GT_32( st->total_brate, ACELP_32k ) ) + { + FOR( j = 0; j < 4; j++ ) + { + Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); + } + } + + /* From low band excitation, generate highband excitation */ + + /* -------- start of memory rescaling -------- */ + /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ + Lmax = 0; + move32(); + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + Lmax = L_max( Lmax, L_abs( bwe_exc_extended_fx[cnt] ) ); + } + Q_bwe_exc = norm_l( Lmax ); + if ( Lmax == 0 ) + { + Q_bwe_exc = 31; + move16(); + } + Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); + find_max_mem_dec( st, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ + + tmp = add( st->prev_Q_bwe_exc, n_mem ); + if ( GT_16( Q_bwe_exc, tmp ) ) + { + Q_bwe_exc = tmp; + move16(); + } + + /* rescale the memories if Q_bwe_exc is different from previous frame */ + sc = sub( Q_bwe_exc, st->prev_Q_bwe_exc ); + IF( sc != 0 ) + { + rescale_genSHB_mem_dec_ivas( st, sc ); + } + + /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ + sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended_fx[cnt], sc ) ); + move16(); + } + + /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ + + /* save the previous Q factor (32-bit) of the buffer */ + st->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + + Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ + + /* -------- end of rescaling memories -------- */ + + Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; + move16(); + + Q_shb = 0; + move16(); + + Copy( hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD ); + GenShapedSHBExcitation_ivas_dec_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, + hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, + &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, + shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, + &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, + st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, + NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); + + *Q_white_exc = Q_bwe_exc_fb; + move16(); + IF( EQ_16( st->extl, FB_TBE ) ) + { + st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + move16(); + } + ELSE + { + /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. + 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ + st->prev_Q_bwe_exc_fb = 51; + move16(); + } + + /* rescale the TBE post proc memory */ + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); + move16(); + } + /* fill-in missing SHB excitation */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) + { + Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD ); + } + + IF( hStereoICBWE != NULL ) + { + Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); + } + + test(); + IF( NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) + { + /* TD BWE post-processing */ + PostShortTerm_ivas_dec_fx( &shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, + hBWE_TD->ptr_mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ), hBWE_TD->mem_zero_swb_fx, formant_fac_fx ); + } + + Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ + + tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); + prev_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ + curr_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + prev_pow_fx = L_mac0_sat( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ + curr_pow_fx = L_mac0_sat( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ + } + + if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) + { + curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ + } + + Lscale = root_a_over_b_fx( curr_pow_fx, + shl( Q_bwe_exc, 1 ), + prev_pow_fx, + shl( Q_bwe_exc, 1 ), + &exp ); + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + IF( exp < 0 ) + { + Lscale = L_shl( Lscale, exp ); + exp = 0; + move16(); + } + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ + temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); + Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } + ELSE + { + /* reset the PF memories if the PF is not running */ + set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + } + + /* Update SHB excitation */ + Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ + l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; + move16(); + L_ener = EPSILON_FX_SMALL; + move32(); + + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + L_tmp = 0; + move32(); + ener_tmp_fx[i] = EPSILON_FX_SMALL; + move32(); + + Word64 tmp64 = 0; + move64(); + FOR( j = 0; j < l_subframe; j++ ) + { + tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )], shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )] ); /* 2*Q_bwe_exc */ + } + L_tmp = W_sat_l( tmp64 ); + + L_tmp = Mult_32_16( L_tmp, 410 /*0.0125 Q15*/ ); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, sub( 30, i_mult( 2, Q_bwe_exc ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + ener_tmp_fx[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ + move32(); + L_ener = L_add_sat( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ + } + } + ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + IF( is_fractive == 0 ) + { + IF( GT_16( st->tilt_wb_fx, 2048 ) ) /*assuming st->tilt_wb_fx in Q11*/ + { + st->tilt_wb_fx = 2048; + move16(); + } + ELSE IF( LT_16( st->tilt_wb_fx, 1024 ) ) + { + st->tilt_wb_fx = 1024; + move16(); + } + test(); + if ( EQ_16( st->prev_fractive, 1 ) && GT_16( st->tilt_wb_fx, 1024 ) ) + { + st->tilt_wb_fx = 1024; + move16(); + } + } + ELSE + { + IF( GT_16( st->tilt_wb_fx, 8192 ) ) + { + IF( st->prev_fractive == 0 ) + { + st->tilt_wb_fx = 8192; + move16(); + } + ELSE + { + st->tilt_wb_fx = 16384; + move16(); + } + } + ELSE + { + st->tilt_wb_fx = shl( st->tilt_wb_fx, 2 ); + move16(); + } + } + + IF( ener_fx != 0 ) + { + L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 13 ) ); /* 2+11 +st->Q_syn2 -13 = st->Q_syn2*/ + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = shr( div_s( 16384, tmp ), 1 ); /*Q(15+14-2-exp-1) = 26 - exp*/ + + test(); + IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ + { + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ + move16(); + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ + } + ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) + { + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ + move16(); + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ + } + L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ + GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ + } + ELSE + { + GainFrame_prevfrm_fx = 0; + move32(); + } + + IF( EQ_16( is_fractive, 1 ) ) + { + GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 10 ); + } + ELSE + { + GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 8 ); + } + + test(); + IF( EQ_16( ( is_fractive & st->prev_fractive ), 1 ) && GT_32( GainFrame_fx, GainFrame_prevfrm_fx ) ) + { + GainFrame_fx = L_add( Mult_32_16( GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); /* 18 +15 -15 = 18*/ + } + ELSE + { + test(); + test(); + test(); + test(); + IF( ( LT_32( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) ) && ( LT_32( L_shr( st->prev_enerLL_fx, 1 ), st->enerLL_fx ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) && ( s_xor( is_fractive, st->prev_fractive ) == 0 ) ) + { + GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( GainFrame_prevfrm_fx, 1 ) ); + } + ELSE + { + test(); + IF( ( is_fractive == 0 ) && EQ_16( st->prev_fractive, 1 ) ) + { + L_tmp1 = L_shl( Mult_32_16( GainFrame_fx, 3277 ), 13 ); /* 31 */ + L_tmp = L_sub( 2147483647, L_tmp1 ); /* 31 */ + GainFrame_fx = L_add( Mult_32_32( GainFrame_fx, L_tmp ), Mult_32_32( GainFrame_prevfrm_fx, L_tmp1 ) ); /* 18 */ + } + ELSE + { + GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( L_min( GainFrame_prevfrm_fx, GainFrame_fx ), 1 ) ); /* 18 */ + } + } + } + + GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( sub( N_WS2N_FRAMES, st->bws_cnt ), 819 ) ); /*Q18*/ + } + ELSE + { + IF( st->bws_cnt1 > 0 ) + { + GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( st->bws_cnt1, 819 ) ); /*Q18*/ + } + IF( GE_16( st->nbLostCmpt, 1 ) ) + { + ener_fx = s_max( 1, ener_fx ); + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ + prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ + } + + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->clas_dec != UNVOICED_CLAS ) && NE_16( st->clas_dec, UNVOICED_TRANSITION ) && LT_16( hBWE_TD->tilt_swb_fec_fx, 16384 ) && + ( ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st->enerLL_fx, 1 ), st->prev_enerLL_fx ) ) || ( GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st->enerLH_fx, 1 ), st->prev_enerLH_fx ) ) ) ) + { + IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) ) /*18*/ + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 13107 ), Mult_32_16( GainFrame_fx, 19661 ) ); /*18*/ + } + ELSE IF( GT_32( L_shr( prev_ener_ratio_fx, 1 ), GainFrame_fx ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); + } + ELSE + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); + } + + test(); + IF( GT_16( tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx ) && ( hBWE_TD->tilt_swb_fec_fx > 0 ) ) + { + exp = norm_s( hBWE_TD->tilt_swb_fec_fx ); + tmp = shl( hBWE_TD->tilt_swb_fec_fx, exp ); /*Q(11+exp)*/ + tmp = div_s( 16384, tmp ); /*Q(15+14-11-exp)*/ + tmp = extract_h( L_shl( L_mult0( tmp, st->tilt_wb_fx ), sub( exp, 1 ) ) ); /*18 -exp +11 + exp -1 -16 =12; */ + GainFrame_fx = L_shl( Mult_32_16( GainFrame_fx, s_min( tmp, 20480 ) ), 3 ); /*Q18 = 18 +12 -15 +3 */ + } + } + ELSE IF( ( ( st->clas_dec != UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 4096 ) ) && GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); + } + } + ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) + { + test(); + IF( GT_16( tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) ) + { + GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6554 /*0.2f in Q15*/ ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 /*4.0f in Q12*/ ), 3 ) ); /*Q18*/ + } + ELSE + { + GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 16384 ), Mult_32_16( GainFrame_fx, 16384 ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 ), 3 ) ); /*Q18*/ + } + } + ELSE IF( GT_32( prev_ener_ratio_fx, GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) + { + test(); + IF( GT_16( tilt_swb_fec_fx, 20480 ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 16384 /*0.5f in Q15*/ ), Mult_32_16( GainFrame_fx, 16384 /*0.5f in Q15*/ ) ); /* Q18 */ + } + ELSE + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 /*0.2f in Q15*/ ), Mult_32_16( GainFrame_fx, 26214 /*0.8f in Q15*/ ) ); /* Q18 */ + } + } + } + } + + st->prev_fractive = is_fractive; + move16(); + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + /* Scale the shaped excitation */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + L_tmp = L_mult( pitch_buf_fx[0], 8192 ); + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 8192 ); /* pitch_buf in Q6 x 0.25 in Q15 */ + } + pitch_fx = round_fx( L_tmp ); /* Q6 */ + } + ELSE + { + L_tmp = L_mult( pitch_buf_fx[0], 6554 ); + FOR( i = 1; i < NB_SUBFR16k; i++ ) + { + L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 6554 ); /* pitch_buf in Q6 x 0.2 in Q15 */ + } + pitch_fx = round_fx( L_tmp ); /* Q6 */ + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( GE_32( st->extl_brate, SWB_TBE_2k8 ) && EQ_16( st->prev_coder_type, st->coder_type ) && NE_16( st->coder_type, UNVOICED ) ) || ( LT_32( st->extl_brate, SWB_TBE_2k8 ) && ( EQ_16( st->prev_coder_type, st->coder_type ) || ( EQ_16( st->prev_coder_type, VOICED ) && EQ_16( st->coder_type, GENERIC ) ) || ( EQ_16( st->prev_coder_type, GENERIC ) && EQ_16( st->coder_type, VOICED ) ) ) ) ) && GT_16( pitch_fx, 4480 /*70 in Q6*/ ) && LT_16( st->extl, FB_TBE ) && NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp_fx[i] = GainShape_fx[i * 4]; /* Q15 */ + move16(); + } + + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ + L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ + tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); + L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ + IF( GT_32( L_tmp1, L_tmp2 ) ) + { + L_tmp = L_tmp2; + move32(); + if ( L_tmp2 < 0 ) + { + L_tmp = L_negate( L_tmp2 ); + } + + expb = norm_l( L_tmp ); + fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); + expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ + + expa = norm_l( ener_tmp_fx[i] ); + fraca = extract_h( L_shl( ener_tmp_fx[i], expa ) ); + expa = sub( 30, expa ); + + scale_fx = shr( sub( fraca, fracb ), 15 ); + fracb = shl( fracb, scale_fx ); + expb = sub( expb, scale_fx ); + + tmp = div_s( fracb, fraca ); + exp = sub( sub( expb, expa ), 1 ); + tmp = shl( tmp, exp ); + GainShape_tmp_fx[i] = add( tmp, shr( GainShape_tmp_fx[i], 1 ) ); /* Q15 */ + move16(); + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; + move32(); + hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; + move16(); + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + + FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); + } + GainShape_fx[i] = GainShape_tmp_fx[idx]; + move16(); + } + } + ELSE + { + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + st->prev_Q_bwe_syn = Q_bwe_exc; + move16(); + + + /* Gain shape smoothing after quantization */ + test(); + IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; + move16(); + } + + lls_interp_n_fx( GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1 ); + + test(); + IF( GE_16( vind, 6 ) && LT_16( abs_s( GainShape_tilt_fx ), 3932 ) ) + { + feedback_fx = 9830; + move16(); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_fx[i] = add_sat( mult( sub( 32767, feedback_fx ), GainShape_fx[i * NUM_SHB_SUBGAINS] ), mult( feedback_fx, GainShape_tmp_fx[i] ) ); + move16(); + } + + FOR( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); + } + GainShape_fx[i] = GainShape_fx[idx]; + move16(); + } + } + } + + /* fil-in missing memory */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) + { + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + Word16 intermediate = mult( shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i] ); + Word32 intermediate_32 = Mpy_32_16_1( Mpy_32_16_1( GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i] ), intermediate ); + hBWE_TD->syn_overlap_fx[i] = round_fx( L_shl_sat( intermediate_32, sub( 16, ( add( Q_bwe_exc, 18 - 15 ) ) ) ) ); + move16(); + } + } + + Word16 n_mem3_new = 0; + move16(); + find_max_mem_dec_m3( st, &n_mem3_new ); + + ScaleShapedSHB_fx( SHB_OVERLAP_LEN, + shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ + hBWE_TD->syn_overlap_fx, + GainShape_fx, /* Q15 */ + GainFrame_fx, /* Q18 */ + window_shb_fx, + subwin_shb_fx, + &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); + + IF( hStereoICBWE != NULL ) + { + Copy_Scale_sig_16_32_DEPREC( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); + Copy( GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR ); + hStereoICBWE->gFrameRef_fx = GainFrame_fx; + move32(); + + Copy( shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); + } + + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + max_val = s_max( max_val, abs_s( shaped_shb_excitation_fx[i] ) ); /* Q0 */ + } + IF( max_val == 0 ) + { + curr_frame_pow_fx = 0; + move32(); + n = 0; + move16(); + } + ELSE + { + n = norm_s( max_val ); + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ + move16(); + } + + curr_frame_pow_fx = 0; + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ + curr_frame_pow_fx = L_add( curr_frame_pow_fx, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ + } + } + curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); + tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); + IF( tmp > 0 ) /* shifting prev */ + { + IF( GT_16( tmp, 32 ) ) + { + st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); + move16(); + tmp = 32; + move16(); + } + hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + } + ELSE /* shifting curr */ + { + IF( LT_16( tmp, -32 ) ) + { + curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); + tmp = -32; + move16(); + } + curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); + curr_frame_pow_exp = st->prev_frame_pow_exp; + move16(); + } + test(); + test(); + IF( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) + { + test(); + test(); + IF( ( GT_32( L_shr( curr_frame_pow_fx, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) && + ( GT_32( hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16( st->prev_coder_type, UNVOICED ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + } + ELSE + { + scale_fx = temp_fx = 32767; + move16(); /*Q15*/ + move16(); /*Q15*/ + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape_fx[2 * j] = mult_r( GainShape_fx[2 * j], scale_fx ); + move16(); + GainShape_fx[2 * j + 1] = mult_r( GainShape_fx[2 * j + 1], scale_fx ); + move16(); + FOR( i = 0; i < L_FRAME16k / 8; i++ ) + { + shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )] = mult_r( shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )], scale_fx ); + move16(); + } + + IF( temp_fx > 0 ) + { + /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) + and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ + IF( LT_16( scale_fx, temp_fx ) ) + { + scale_fx = div_s( scale_fx, temp_fx ); + } + ELSE + { + scale_fx = 32767; + move16(); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + /* adjust the FEC frame energy */ + IF( st->bfi ) + { + scale_fx = temp_fx = 4096; + move16(); /*Q12*/ + move16(); + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) && + NE_16( st->prev_coder_type, UNVOICED ) && + ( st->last_good != UNVOICED_CLAS ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); /*31 - exp*/ + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && EQ_16( st->nbLostCmpt, 1 ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && + ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + } + ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && + ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape_fx[2 * j] = shl_sat( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); + move16(); /* 15 +12 +3-15 =15*/ + GainShape_fx[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape_fx[add( 2 * j, 1 )], scale_fx ), 3 ); + move16(); + FOR( i = 0; i < 40; i++ ) + { + shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = shl( mult_r( shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx ), 3 ); + move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ + } + + IF( temp_fx > 0 ) + { + IF( LT_16( scale_fx, temp_fx ) ) + { + scale_fx = shr( div_s( scale_fx, temp_fx ), 3 ); + } + ELSE + { + tmp1 = sub( norm_s( scale_fx ), 1 ); + tmp2 = norm_s( temp_fx ); + scale_fx = div_s( shl( scale_fx, tmp1 ), shl( temp_fx, tmp2 ) ); + scale_fx = shr( scale_fx, add( sub( tmp1, tmp2 ), 3 ) ); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + Word64 prev_ener_shb64 = 0; + move64(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* Q0 */ + } + L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); + + L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ + st->prev_ener_shb_fx = 0; + move16(); + IF( L_prev_ener_shb != 0 ) + { + exp = norm_l( L_prev_ener_shb ); + tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); + exp = sub( exp, sub( 30, ( add( i_mult( 2, Q_bwe_exc ), 8 ) ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + st->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + move16(); + } + + IF( st->hBWE_FD != NULL ) + { + L_tmp = Mult_32_16( curr_frame_pow_fx, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ + tmp = 0; + move16(); + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, sub( 30, add( curr_frame_pow_exp, 8 ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + } + set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ + } + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shaped_shb_excitation_fx_32[i] = L_shl( shaped_shb_excitation_fx[i], sub( Q11, Q_bwe_exc ) ); + move32(); + } + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); + Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); + + /* resample SHB synthesis (if needed) and scale down */ + synth_scale_fx = 32767; + move16(); /* 1.0 in Q15 */ + if ( EQ_16( st->codec_mode, MODE1 ) ) + { + synth_scale_fx = 29491; + move16(); /* 0.9 in Q15 */ + } + + IF( EQ_32( st->output_Fs, 48000 ) ) + { + IF( EQ_16( st->extl, FB_TBE ) ) + { + tmp = norm_l( GainFrame_fx ); + if ( GainFrame_fx == 0 ) + { + tmp = 31; + move16(); + } + L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ + + tmp1 = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); + } + L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ + White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ + move16(); + tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); + } + + *Q_white_exc = sub( add( *Q_white_exc, tmp ), 13 ); /* *Q_white_exc + 18 + tmp -15 -16 */ + move16(); + tmp = norm_s( tmp1 ); + if ( tmp1 == 0 ) + { + tmp = 15; + move16(); + } + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + White_exc16k_fx[i] = shl( White_exc16k_fx[i], sub( tmp, 1 ) ); + move16(); + } + *Q_white_exc = sub( add( *Q_white_exc, tmp ), 1 ); + move16(); + } + + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); + } + } + interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( st->output_Fs, 32000 ) ) + { + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + synth_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); /*Qx*/ + } + } + ELSE + { + Copy32( error_fx, synth_fx, L_FRAME32k ); + } + } + ELSE IF( EQ_32( st->output_Fs, 16000 ) ) + { + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); + } + } + + Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); + } + + + /* Update previous frame parameters for FEC */ + Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move32(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + + if ( !st->bfi ) + { + hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ + move16(); + } + } + ELSE + { + IF( !st->bfi ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move32(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ + move16(); + } + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; + move32(); + hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; + move16(); + st->prev_Q_bwe_syn2 = Q_bwe_exc; + move16(); + st->prev_Qx = Q_bwe_exc; + move16(); + + return; +} + +void GenTransition_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 element_mode, /* i : element mode : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 rf_flag, /* i : RF flag : Q0 */ + const Word32 total_brate, /* i : total bitrate : Q0 */ + const Word16 prev_Qx ) +{ + Word16 i, length; + + Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); + + /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ + test(); + test(); + test(); + test(); + IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) + { + flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); + } + ELSE + { + FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); + } + ELSE + { + syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; + } + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) + { + outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); + move32(); + } + + IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( output_Fs, 16000 ) ) + { + Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); + } + + return; +} +void GenTransition_WB_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ +) +{ + Word16 i, length; + Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; + Word32 upsampled_synth_fx[L_FRAME48k]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); + Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); + move32(); + } + ELSE + { + speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) + { + outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } + + /* upsampling if necessary */ + IF( EQ_32( output_Fs, 32000 ) ) + { + Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); + } + ELSE IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); + } + + return; +} diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c deleted file mode 100644 index 6a74d3b87..000000000 --- a/lib_dec/tonalMDCTconcealment.c +++ /dev/null @@ -1,436 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#define _USE_MATH_DEFINES - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" - - -/*******************************************************/ -/*-------------- public functions -------------------- */ -/*******************************************************/ - -void TonalMdctConceal_create_concealment_noise_ivas_fx( - Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp - Word16 *concealment_noise_exp, - CPE_DEC_HANDLE hCPE, - const Word16 L_frameTCX, // Q0 - const Word16 L_frame, // Q0 - const Word16 idchan, // Q0 - const Word16 subframe_idx, // Q0 - const Word16 core, // Q0 - const Word16 crossfade_gain, // Q15 - const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) -{ - STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; - TonalMDCTConcealPtr hTonalMDCTConc; - Decoder_State *st; - HANDLE_FD_CNG_COM hFdCngCom; - Word16 *rnd_c, *rnd; - Word16 crossOverFreq, i, save_rnd_c, max_noise_line; - Word16 c, c_inv, inc; - Word32 noise_shape_buffer[L_FRAME48k]; - Word16 noise_shape_buffer_e[L_FRAME48k]; - Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e; - move16(); - Word32 *cngNoiseLevelPtr; - Word32 last_scf; - - Word16 c_e, c_inv_e; - - push_wmops( "create_conc_noise" ); - - hStereoMdct = hCPE->hStereoMdct; - st = hCPE->hCoreCoder[idchan]; - hTonalMDCTConc = st->hTonalMDCTConc; - hFdCngCom = st->hFdCngDec->hFdCngCom; - rnd = &hStereoMdct->noise_seeds_channels[idchan]; - rnd_c = &hStereoMdct->noise_seed_common; - - /* determine start bin for IGF */ - IF( st->igf == 0 ) - { - IF( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - crossOverFreq = s_min( L_frameTCX, L_frame ); - } - ELSE - { - crossOverFreq = L_frameTCX; - move16(); - } - } - ELSE - { - crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); - } - - /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ - max_noise_line = crossOverFreq; - move16(); - IF( st->tonal_mdct_plc_active ) - { - max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) ); - } - - /* first lost frame is handled separately */ - IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) - { - *rnd = add( 1977, idchan ); // Q0 - move16(); - /* will be set twice when looping over two channels, but does not matter */ - *rnd_c = 1979; // Q0 - move16(); - } - - IF( GT_16( crossfade_gain, 32734 ) ) - /* Due to precision loss */ /* 0.999 in Q15*/ - { - /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); - move16(); - concealment_noise[i] = *rnd; // Q31-concealment_noise_exp - move32(); - } - *concealment_noise_exp = 31; - move16(); - pop_wmops(); - - return; - } - - save_rnd_c = *rnd_c; // Q0 - move16(); - - c_e = 1; - move16(); - c_inv_e = 1; - move16(); - - c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e - c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e - - IF( NE_16( c_e, c_inv_e ) ) - { - IF( LT_16( c_e, c_inv_e ) ) - { - c = shr( c, sub( c_inv_e, c_e ) ); // Q0 - c_e = c_inv_e; - move16(); - } - ELSE - { - c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0 - } - } - - /* pre-compute the noise shape for later weighting of the noise spectra */ - cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; - last_scf_e = hFdCngCom->cngNoiseLevelExp; - move16(); - - IF( GT_16( st->core, TCX_20_CORE ) ) - { - inc = 2; - } - ELSE - { - inc = 1; - } - move16(); - start_idx = idiv1616( hFdCngCom->startBand, inc ); - stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc ); - - FOR( i = 0; i < start_idx; i++ ) - { - noise_shape_buffer[i] = 0; - move32(); - noise_shape_buffer_e[i] = 0; - move16(); - } - FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) ) - { - noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp; - move16(); - noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i] - move32(); - noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp ); - } - - FOR( i = 0; i < stop_idx; i++ ) - { - IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ) - { - - noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i]) - move32(); - } - } - - last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e - - IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) ) - { - Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e) - - noise_shape_buffer_common_exp = last_scf_e; - move16(); - } - ELSE - { - last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp) - } - - FOR( ; i < max_noise_line; i++ ) - { - noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp - move32(); - } - - /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31 - move32(); - hTonalMDCTConc->curr_noise_nrg_exp = 0; - move16(); - *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) ); - move16(); - temp_e = hTonalMDCTConc->curr_noise_nrg_exp; - move16(); - - test(); - test(); - test(); - test(); - IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) ) - { - /* current channel is TCX20 -> generate noise for "full-length" spectrum */ - - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); // Q0 - *rnd_c = own_random( rnd_c ); - - move16(); - move16(); - - concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp - move32(); - IF( concealment_noise[i] != 0 ) - { - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e - } - hTonalMDCTConc->curr_noise_nrg_exp = temp_e; - move16(); - } - } - ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ - { - /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); // Q0 - *rnd_c = own_random( rnd_c ); // Q0 - move16(); - move16(); - - concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); - move32(); - IF( concealment_noise[i] != 0 ) - { - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e - } - hTonalMDCTConc->curr_noise_nrg_exp = temp_e; - move16(); - - *rnd_c = own_random( rnd_c ); - move16(); - } - } - - IF( st->tonal_mdct_plc_active ) - { - FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) - { - concealment_noise[i] = 0; - move32(); - } - } - - /* restore common seed - - after finishing the first channel - - after a first subframe if the current channel is TCX10 */ - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) ) - { - *rnd_c = save_rnd_c; - move16(); - } - - st->seed_tcx_plc = *rnd; - move16(); - - pop_wmops(); - - return; -} - - -void TonalMdctConceal_whiten_noise_shape_ivas_fx( - Decoder_State *st, - const Word16 L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) -{ - Word16 inc, start_idx, stop_idx, i; - Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; - Word16 noiseLevelPtr_exp; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 whitenend_noise_shape[L_FRAME16k]; - Word16 q_wns; - Word32 scfs_int[FDNS_NPTS]; - const PsychoacousticParameters *psychParams; - - push_wmops( "apply_sns_on_noise_shape" ); - - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; - psychParams = st->hTonalMDCTConc->psychParams; - hFdCngCom = st->hFdCngDec->hFdCngCom; - -#ifdef MSAN_FIX - set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); -#endif - - IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) - { - IF( GT_16( st->core, TCX_20_CORE ) ) - { - inc = 2; - move16(); - } - ELSE - { - inc = 1; - move16(); - } - } - ELSE - { - IF( GT_16( st->last_core, TCX_20_CORE ) ) - { - inc = 2; - move16(); - } - ELSE - { - inc = 1; - move16(); - } - } - start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); - stop_idx = shr( L_frame, sub( inc, 1 ) ); - noiseLevelPtr = hFdCngCom->cngNoiseLevel; - noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; - move16(); - - FOR( Word16 j = start_idx; j < stop_idx; j++ ) - { - whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 ); - move32(); - noiseLevelPtr += inc; - } - - IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) - { - Word32 scf[SNS_NPTS]; - - sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) ); - - sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); - sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); - - scfs_for_shaping = &scfs_int[0]; // Q16 - } - ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ - { - scfs_for_shaping = &scfs_bg[0]; // Q16 - } - - IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 ) - { - q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 ); - sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL ); - - IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) ) - { - FOR( i = 0; i < sub( stop_idx, start_idx ); i++ ) - { - hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1) - move32(); - } - } - ELSE - { - Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) ); - - scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); - - hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1) - move16(); - } - } - ELSE - { - set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); - } - - pop_wmops(); -} diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index a4aa23e7f..3cf5f51f3 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -3200,6 +3200,397 @@ static void CalcPowerSpec( powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 ); move32(); } + + +/*******************************************************/ +/*-------------- public functions -------------------- */ +/*******************************************************/ + +void TonalMdctConceal_create_concealment_noise_ivas_fx( + Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp + Word16 *concealment_noise_exp, + CPE_DEC_HANDLE hCPE, + const Word16 L_frameTCX, // Q0 + const Word16 L_frame, // Q0 + const Word16 idchan, // Q0 + const Word16 subframe_idx, // Q0 + const Word16 core, // Q0 + const Word16 crossfade_gain, // Q15 + const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) +{ + STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; + TonalMDCTConcealPtr hTonalMDCTConc; + Decoder_State *st; + HANDLE_FD_CNG_COM hFdCngCom; + Word16 *rnd_c, *rnd; + Word16 crossOverFreq, i, save_rnd_c, max_noise_line; + Word16 c, c_inv, inc; + Word32 noise_shape_buffer[L_FRAME48k]; + Word16 noise_shape_buffer_e[L_FRAME48k]; + Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e; + move16(); + Word32 *cngNoiseLevelPtr; + Word32 last_scf; + + Word16 c_e, c_inv_e; + + push_wmops( "create_conc_noise" ); + + hStereoMdct = hCPE->hStereoMdct; + st = hCPE->hCoreCoder[idchan]; + hTonalMDCTConc = st->hTonalMDCTConc; + hFdCngCom = st->hFdCngDec->hFdCngCom; + rnd = &hStereoMdct->noise_seeds_channels[idchan]; + rnd_c = &hStereoMdct->noise_seed_common; + + /* determine start bin for IGF */ + IF( st->igf == 0 ) + { + IF( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + crossOverFreq = s_min( L_frameTCX, L_frame ); + } + ELSE + { + crossOverFreq = L_frameTCX; + move16(); + } + } + ELSE + { + crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); + } + + /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ + max_noise_line = crossOverFreq; + move16(); + IF( st->tonal_mdct_plc_active ) + { + max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) ); + } + + /* first lost frame is handled separately */ + IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) + { + *rnd = add( 1977, idchan ); // Q0 + move16(); + /* will be set twice when looping over two channels, but does not matter */ + *rnd_c = 1979; // Q0 + move16(); + } + + IF( GT_16( crossfade_gain, 32734 ) ) + /* Due to precision loss */ /* 0.999 in Q15*/ + { + /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); + move16(); + concealment_noise[i] = *rnd; // Q31-concealment_noise_exp + move32(); + } + *concealment_noise_exp = 31; + move16(); + pop_wmops(); + + return; + } + + save_rnd_c = *rnd_c; // Q0 + move16(); + + c_e = 1; + move16(); + c_inv_e = 1; + move16(); + + c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e + c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e + + IF( NE_16( c_e, c_inv_e ) ) + { + IF( LT_16( c_e, c_inv_e ) ) + { + c = shr( c, sub( c_inv_e, c_e ) ); // Q0 + c_e = c_inv_e; + move16(); + } + ELSE + { + c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0 + } + } + + /* pre-compute the noise shape for later weighting of the noise spectra */ + cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; + last_scf_e = hFdCngCom->cngNoiseLevelExp; + move16(); + + IF( GT_16( st->core, TCX_20_CORE ) ) + { + inc = 2; + } + ELSE + { + inc = 1; + } + move16(); + start_idx = idiv1616( hFdCngCom->startBand, inc ); + stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc ); + + FOR( i = 0; i < start_idx; i++ ) + { + noise_shape_buffer[i] = 0; + move32(); + noise_shape_buffer_e[i] = 0; + move16(); + } + FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) ) + { + noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp; + move16(); + noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i] + move32(); + noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp ); + } + + FOR( i = 0; i < stop_idx; i++ ) + { + IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ) + { + + noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i]) + move32(); + } + } + + last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e + + IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) ) + { + Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e) + + noise_shape_buffer_common_exp = last_scf_e; + move16(); + } + ELSE + { + last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp) + } + + FOR( ; i < max_noise_line; i++ ) + { + noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp + move32(); + } + + /* fill the noise vector */ + hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31 + move32(); + hTonalMDCTConc->curr_noise_nrg_exp = 0; + move16(); + *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) ); + move16(); + temp_e = hTonalMDCTConc->curr_noise_nrg_exp; + move16(); + + test(); + test(); + test(); + test(); + IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) ) + { + /* current channel is TCX20 -> generate noise for "full-length" spectrum */ + + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); // Q0 + *rnd_c = own_random( rnd_c ); + + move16(); + move16(); + + concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp + move32(); + IF( concealment_noise[i] != 0 ) + { + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e + } + hTonalMDCTConc->curr_noise_nrg_exp = temp_e; + move16(); + } + } + ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ + { + /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); // Q0 + *rnd_c = own_random( rnd_c ); // Q0 + move16(); + move16(); + + concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); + move32(); + IF( concealment_noise[i] != 0 ) + { + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e + } + hTonalMDCTConc->curr_noise_nrg_exp = temp_e; + move16(); + + *rnd_c = own_random( rnd_c ); + move16(); + } + } + + IF( st->tonal_mdct_plc_active ) + { + FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) + { + concealment_noise[i] = 0; + move32(); + } + } + + /* restore common seed + - after finishing the first channel + - after a first subframe if the current channel is TCX10 */ + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) ) + { + *rnd_c = save_rnd_c; + move16(); + } + + st->seed_tcx_plc = *rnd; + move16(); + + pop_wmops(); + + return; +} + + +void TonalMdctConceal_whiten_noise_shape_ivas_fx( + Decoder_State *st, + const Word16 L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) +{ + Word16 inc, start_idx, stop_idx, i; + Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; + Word16 noiseLevelPtr_exp; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 whitenend_noise_shape[L_FRAME16k]; + Word16 q_wns; + Word32 scfs_int[FDNS_NPTS]; + const PsychoacousticParameters *psychParams; + + push_wmops( "apply_sns_on_noise_shape" ); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + +#ifdef MSAN_FIX + set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); +#endif + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + IF( GT_16( st->core, TCX_20_CORE ) ) + { + inc = 2; + move16(); + } + ELSE + { + inc = 1; + move16(); + } + } + ELSE + { + IF( GT_16( st->last_core, TCX_20_CORE ) ) + { + inc = 2; + move16(); + } + ELSE + { + inc = 1; + move16(); + } + } + start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); + stop_idx = shr( L_frame, sub( inc, 1 ) ); + noiseLevelPtr = hFdCngCom->cngNoiseLevel; + noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; + move16(); + + FOR( Word16 j = start_idx; j < stop_idx; j++ ) + { + whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 ); + move32(); + noiseLevelPtr += inc; + } + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + Word32 scf[SNS_NPTS]; + + sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) ); + + sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); + sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); + + scfs_for_shaping = &scfs_int[0]; // Q16 + } + ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ + { + scfs_for_shaping = &scfs_bg[0]; // Q16 + } + + IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 ) + { + q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 ); + sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL ); + + IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) ) + { + FOR( i = 0; i < sub( stop_idx, start_idx ); i++ ) + { + hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1) + move32(); + } + } + ELSE + { + Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) ); + + scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); + + hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1) + move16(); + } + } + ELSE + { + set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); + } + + pop_wmops(); +} + + #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], -- GitLab From 5424115f277ce702a36ade2f97f07029b2c543a6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 20:44:33 +0530 Subject: [PATCH 0302/1221] Clang formatting --- lib_dec/ari_dec_fx.c | 1 - lib_dec/arith_coder_dec_fx.c | 1 - lib_dec/bass_psfilter_fx.c | 10 +++++----- lib_dec/core_dec_init_fx.c | 1 - lib_dec/core_switching_dec_fx.c | 2 +- lib_dec/dec_prm_fx.c | 1 - lib_dec/dec_tcx_fx.c | 1 - lib_dec/fd_cng_dec_fx.c | 8 ++++---- lib_dec/swb_bwe_dec_fx.c | 1 - 9 files changed, 10 insertions(+), 16 deletions(-) diff --git a/lib_dec/ari_dec_fx.c b/lib_dec/ari_dec_fx.c index 524f9d121..3aabbdaa5 100644 --- a/lib_dec/ari_dec_fx.c +++ b/lib_dec/ari_dec_fx.c @@ -839,4 +839,3 @@ Word16 ari_decode_14bits_sign_ivas( return bp; } - diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index 6df1eb268..e5a1220e0 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -420,4 +420,3 @@ void tcx_arith_decode_envelope_ivas_fx( return; } - diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index 7d2be2c52..75cabf160 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -4,12 +4,12 @@ #include #include -#include "options.h" /* Compilation switches */ -#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "rom_dec.h" /* Static table prototypes */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_dec.h" /* Static table prototypes */ #include "basop_util.h" /*---------------------------------------------------------------------* diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index f649772b2..8fefa3bb2 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -2216,4 +2216,3 @@ void reset_tcx_overl_buf_fx( move16(); return; } - diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index caef9485b..52c3e3073 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -3443,4 +3443,4 @@ void ivas_bw_switching_pre_proc_fx( } return; -} \ No newline at end of file +} diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c index 77fd7d421..3d277807d 100644 --- a/lib_dec/dec_prm_fx.c +++ b/lib_dec/dec_prm_fx.c @@ -2011,4 +2011,3 @@ void getTCXWindowing_ivas_fx( return; } - diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 4d97367ef..e71157a1e 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -5302,4 +5302,3 @@ void decoder_tcx_imdct_fx( return; } - diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index f788144fa..70c4760ae 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -20,10 +20,10 @@ #endif -#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ -#define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ -#define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ -#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ +#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ +#define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ +#define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ +#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ #define DELTA_MASKING_NOISE_Q15 0 #define LOG_10_BASE_2 1783446566 /* Q29 */ #define GAIN_Q_OFFSET_IVAS_FX 45 diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 23c4c3e8a..d15a97821 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -1634,4 +1634,3 @@ void fd_bwe_dec_init_fx( return; } - -- GitLab From a8e2883c2491bc9327bf11f806321d6f14e29b59 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 3 Mar 2025 22:29:22 +0530 Subject: [PATCH 0303/1221] Fix for 3GPP issue 1325: saturation occuring in tcx_encoder_memory_update_ivas_fx() Link #1325 --- lib_enc/ivas_tcx_core_enc.c | 18 ++---------------- lib_enc/tcx_utils_enc_fx.c | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index cecc1bf80..84bffa87c 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -570,23 +570,9 @@ void stereo_tcx_core_enc( move16(); move16(); - /* Scaling old_exc buffer to Q_new */ - IF( NE_16( Q_new, Q_exc ) ) - { - Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( Q_new, Q_exc ) ); - } - coder_tcx_post_ivas_fx( st, st->hLPDmem, st->hTcxCfg, st->synth, A_q_fx, Aw_fx, st->wspeech_enc, Q_new ); - /* Upscaling old_exc buffer */ - s = norm_arr( st->hLPDmem->old_exc, L_EXC_MEM ) - 1; - Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, s ); - IF( st->hTdCngEnc != NULL ) - { - Scale_sig( st->hTdCngEnc->cng_exc2_buf, HO_HIST_SIZE * L_FFT, sub( add( shl( Q_new, 1 ), s ), Q_exc ) ); - } - Q_exc = add( shl( Q_new, 1 ), s ); // 2 * Q_new + s - st->hLPDmem->q_lpd_old_exc = Q_exc; + Q_exc = Q_new; // Q_new move16(); IF( st->enableTcxLpc ) @@ -659,7 +645,7 @@ void stereo_tcx_core_enc( ELSE { cng_params_upd_ivas_fx( lsp_new_fx, st->hLPDmem->old_exc + L_EXC_MEM - st->L_frame, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, - st->hTdCngEnc->ho_lsp_circ_fx, Q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hTdCngEnc->ho_lsp_circ_fx, st->hLPDmem->q_lpd_old_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); } diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 5e7ca7be8..2a6f040ac 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2814,12 +2814,12 @@ void tcx_encoder_memory_update_ivas_fx( /* Emphasis of synth -> synth_pe */ tmp = synth[-( M + 1 )]; move16(); - E_UTIL_f_preemph2( Q_new - 1, synth - M, preemph, add( M, L_frame_glob ), &tmp ); + E_UTIL_f_preemph2( 0, synth - M, preemph, add( M, L_frame_glob ), &tmp ); // Q_new Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M ); Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M ); Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM ); - LPDmem->q_mem_syn = sub( shl( Q_new, 1 ), 1 ); // resultant q of synth after E_UTIL_f_preemph2 + LPDmem->q_mem_syn = Q_new; // resultant q of synth after E_UTIL_f_preemph2 move16(); test(); @@ -2828,13 +2828,27 @@ void tcx_encoder_memory_update_ivas_fx( /* Update excitation */ IF( LT_16( L_frame_glob, L_EXC_MEM ) ) { - Copy( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ) ); - Scale_sig( LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), Q_new ); // Q_new->2*Q_new - Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 1 ); // 2*Q_new + Word16 shift = norm_arr( LPDmem->old_exc + L_frame_glob, sub( L_EXC_MEM, L_frame_glob ) ); + IF( LT_16( shift, sub( Q_new, LPDmem->q_lpd_old_exc ) ) ) + { + Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), shift ); + LPDmem->q_lpd_old_exc = add( LPDmem->q_lpd_old_exc, shift ); + move16(); + Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, sub( LPDmem->q_lpd_old_exc, Q_new ) ); // LPDmem->q_lpd_old_exc + } + ELSE + { + Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), sub( Q_new, LPDmem->q_lpd_old_exc ) ); + Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 0 ); // Q_new + LPDmem->q_lpd_old_exc = Q_new; + move16(); + } } ELSE { - Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 1 ); // 2*Q_new + Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 0 ); // Q_new + LPDmem->q_lpd_old_exc = Q_new; + move16(); } } } -- GitLab From 1e58f1597c8d14b4bcecd1658fd3a6e0f4a99ac7 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Tue, 4 Mar 2025 20:50:46 +0100 Subject: [PATCH 0304/1221] encapsulate changes --- lib_com/ivas_prot_fx.h | 7 ++++-- lib_com/ivas_tools.c | 14 ++++-------- lib_com/options.h | 1 + lib_enc/speech_music_classif_fx.c | 36 ++++++++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6b09b1b47..1bdc33439 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4706,6 +4706,8 @@ Word32 dot_product_cholesky_fx( const Word32 *A, /* i : Cholesky matrix A */ const Word16 N /* i : vector & matrix size */ ); + +#ifndef DOT_PROD_CHOLESKY_64BIT Word32 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ @@ -4713,12 +4715,13 @@ Word32 dot_product_cholesky_fixed( const Word16 exp_x, const Word16 exp_A, Word16 *exp_sum ); - -Word64 dot_product_cholesky_fixed64( +#else +Word64 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ const Word16 N /* i : vector & matrix size */ ); +#endif void v_mult_mat_fx( Word32 *y_fx, /* o : the product x*A */ diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index dc45e3f0e..d55766928 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -606,6 +606,7 @@ void v_sub32_fx( * Therefore, S=A*A' where A is upper triangular matrix of size (m*m+m)/2 (zeros ommitted, column-wise) *---------------------------------------------------------------------*/ +#ifndef DOT_PROD_CHOLESKY_64BIT /*! r: the dot product x'*A*A'*x */ Word32 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x Q31 - exp_x*/ @@ -642,17 +643,9 @@ Word32 dot_product_cholesky_fixed( return suma; } - -/*---------------------------------------------------------------------* - * dot_product_cholesky() - * - * Calculates dot product of type x'*A*A'*x, where x is column vector of size m, - * and A is a Cholesky decomposition of some Hermitian matrix S whose size is m*m. - * Therefore, S=A*A' where A is upper triangular matrix of size (m*m+m)/2 (zeros ommitted, column-wise) - *---------------------------------------------------------------------*/ - +#else /*! r: the dot product x'*A*A'*x */ -Word64 dot_product_cholesky_fixed64( +Word64 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x Q31 - exp_x*/ const Word32 *A, /* i : Cholesky matrix A Q31 - exp_A*/ const Word16 N /* i : vector & matrix size Q0*/ @@ -686,6 +679,7 @@ Word64 dot_product_cholesky_fixed64( return suma; } +#endif void v_mult_mat_fixed( Word32 *y, /* o : the product x*A Qx - guardbits*/ diff --git a/lib_com/options.h b/lib_com/options.h index a37ccf387..5fc9a375f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -169,4 +169,5 @@ #define FIX_1298 /* VA: fix possible assert in gaus_enc */ #define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ +#define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #endif diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index fe6647a6c..f0fc3f304 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1683,8 +1683,16 @@ Word16 ivas_smc_gmm_fx( Word16 flag_odv; Word32 lps_fx, lpm_fx, lpn_fx; Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; +#ifndef DOT_PROD_CHOLESKY_64BIT + Word32 lprob_fx; + Word16 lprob_exp = 0; +#else Word64 wprob_fx; +#endif Word32 fvm_fx[N_PCA_COEF]; +#ifndef DOT_PROD_CHOLESKY_64BIT + Word16 fvm_exp = 0; +#endif Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; @@ -2271,16 +2279,38 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 +#ifndef DOT_PROD_CHOLESKY_64BIT + fvm_exp = sub( 31, Qfact_FV ); + lprob_exp = 0; + move16(); + lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#else + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#endif move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 +#ifndef DOT_PROD_CHOLESKY_64BIT + lprob_exp = 0; + move16(); + lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#else + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#endif move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed64( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 +#ifndef DOT_PROD_CHOLESKY_64BIT + lprob_exp = 0; + move16(); + lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#else + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#endif move32(); } -- GitLab From 0a6e192810ff8bd1bfa653f383dc55039487756c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 10:56:41 +0530 Subject: [PATCH 0305/1221] Renaming all files with "_fx" suffix --- Workspace_msvc/lib_com.vcxproj | 60 ++-- Workspace_msvc/lib_com.vcxproj.filters | 180 +++++----- Workspace_msvc/lib_dec.vcxproj | 96 ++--- Workspace_msvc/lib_dec.vcxproj.filters | 288 +++++++-------- Workspace_msvc/lib_enc.vcxproj | 110 +++--- Workspace_msvc/lib_enc.vcxproj.filters | 330 +++++++++--------- Workspace_msvc/lib_rend.vcxproj | 76 ++-- Workspace_msvc/lib_rend.vcxproj.filters | 83 +++-- lib_com/{ivas_arith.c => ivas_arith_fx.c} | 0 ...er_com.c => ivas_avq_pos_reorder_com_fx.c} | 0 ...ivas_cov_smooth.c => ivas_cov_smooth_fx.c} | 0 .../{ivas_dirac_com.c => ivas_dirac_com_fx.c} | 0 ...ommon.c => ivas_entropy_coder_common_fx.c} | 0 .../{ivas_fb_mixer.c => ivas_fb_mixer_fx.c} | 0 lib_com/{ivas_filters.c => ivas_filters_fx.c} | 0 lib_com/{ivas_ism_com.c => ivas_ism_com_fx.c} | 0 lib_com/{ivas_lfe_com.c => ivas_lfe_com_fx.c} | 0 .../{ivas_masa_com.c => ivas_masa_com_fx.c} | 0 lib_com/{ivas_mc_com.c => ivas_mc_com_fx.c} | 0 ..._mc_param_com.c => ivas_mc_param_com_fx.c} | 0 ...ivas_mcmasa_com.c => ivas_mcmasa_com-fx.c} | 0 lib_com/{ivas_mct_com.c => ivas_mct_com_fx.c} | 0 ...dct_core_com.c => ivas_mdct_core_com_fx.c} | 0 ...ivas_mdft_imdft.c => ivas_mdft_imdft_fx.c} | 0 .../{ivas_omasa_com.c => ivas_omasa_com_fx.c} | 0 .../{ivas_pca_tools.c => ivas_pca_tools_fx.c} | 0 ...metadata_com.c => ivas_qmetadata_com_fx.c} | 0 ...herical_com.c => ivas_qspherical_com_fx.c} | 0 ...ivas_sba_config.c => ivas_sba_config_fx.c} | 0 .../{ivas_spar_com.c => ivas_spar_com_fx.c} | 0 ...t_util.c => ivas_spar_com_quant_util_fx.c} | 0 ...reo_dft_com.c => ivas_stereo_dft_com_fx.c} | 0 ..._com.c => ivas_stereo_mdct_bands_com_fx.c} | 0 ...com.c => ivas_stereo_mdct_stereo_com_fx.c} | 0 ...pc_com.c => ivas_stereo_psychlpc_com_fx.c} | 0 ..._alloc.c => ivas_stereo_td_bit_alloc_fx.c} | 0 lib_com/{ivas_tools.c => ivas_tools_fx.c} | 0 ...ransient_det.c => ivas_transient_det_fx.c} | 0 ...ernal.c => ivas_binRenderer_internal_fx.c} | 0 .../{ivas_core_dec.c => ivas_core_dec_fx.c} | 0 ...fig.c => ivas_corecoder_dec_reconfig_fx.c} | 0 ...ix_dec.c => ivas_decision_matrix_dec_fx.c} | 0 .../{ivas_dirac_dec.c => ivas_dirac_dec_fx.c} | 0 ...c => ivas_dirac_output_synthesis_cov_fx.c} | 0 ...py_decoder.c => ivas_entropy_decoder_fx.c} | 0 lib_dec/{ivas_ism_dec.c => ivas_ism_dec_fx.c} | 0 ...as_ism_dtx_dec.c => ivas_ism_dtx_dec_fx.c} | 0 ...adata_dec.c => ivas_ism_metadata_dec_fx.c} | 0 ...sm_param_dec.c => ivas_ism_param_dec_fx.c} | 0 ..._ism_renderer.c => ivas_ism_renderer_fx.c} | 0 lib_dec/{ivas_jbm_dec.c => ivas_jbm_dec_fx.c} | 0 ...s_custom_dec.c => ivas_ls_custom_dec_fx.c} | 0 .../{ivas_masa_dec.c => ivas_masa_dec_fx.c} | 0 ..._mc_param_dec.c => ivas_mc_param_dec_fx.c} | 0 ...pmix_dec.c => ivas_mc_paramupmix_dec_fx.c} | 0 ...ivas_mcmasa_dec.c => ivas_mcmasa_dec_fx.c} | 0 ..._mct_core_dec.c => ivas_mct_core_dec_fx.c} | 0 lib_dec/{ivas_mct_dec.c => ivas_mct_dec_fx.c} | 0 ..._dec_mct_fx.c => ivas_mct_dec_mct_fx_fx.c} | 0 ...dct_core_dec.c => ivas_mdct_core_dec_fx.c} | 0 ...renderer.c => ivas_mono_dmx_renderer_fx.c} | 0 ...al.c => ivas_objectRenderer_internal_fx.c} | 0 .../{ivas_omasa_dec.c => ivas_omasa_dec_fx.c} | 0 .../{ivas_osba_dec.c => ivas_osba_dec_fx.c} | 0 ...rsion.c => ivas_out_setup_conversion_fx.c} | 0 ...utput_config.c => ivas_output_config_fx.c} | 0 .../{ivas_post_proc.c => ivas_post_proc_fx.c} | 0 ...metadata_dec.c => ivas_qmetadata_dec_fx.c} | 0 ...herical_dec.c => ivas_qspherical_dec_fx.c} | 0 ...ange_uni_dec.c => ivas_range_uni_dec_fx.c} | 0 lib_dec/{ivas_sba_dec.c => ivas_sba_dec_fx.c} | 0 ...nal.c => ivas_sba_rendering_internal_fx.c} | 0 ..._spar_decoder.c => ivas_spar_decoder_fx.c} | 0 ...as_spar_md_dec.c => ivas_spar_md_dec_fx.c} | 0 ...GR_dec.c => ivas_stereo_adapt_GR_dec_fx.c} | 0 ...dec_dmx.c => ivas_stereo_dft_dec_dmx_fx.c} | 0 ...eclvq_dec.c => ivas_stereo_eclvq_dec_fx.c} | 0 ...reo_esf_dec.c => ivas_stereo_esf_dec_fx.c} | 0 ...reo_ica_dec.c => ivas_stereo_ica_dec_fx.c} | 0 ...icbwe_dec.c => ivas_stereo_icbwe_dec_fx.c} | 0 ...dec.c => ivas_stereo_mdct_stereo_dec_fx.c} | 0 ...g_dec.c => ivas_stereo_switching_dec_fx.c} | 0 ...tereo_td_dec.c => ivas_stereo_td_dec_fx.c} | 0 lib_dec/{ivas_svd_dec.c => ivas_svd_dec_fx.c} | 0 ..._tcx_core_dec.c => ivas_tcx_core_dec_fx.c} | 0 ...w_rate_dec.c => ivas_td_low_rate_dec_fx.c} | 0 lib_enc/{ivas_agc_enc.c => ivas_agc_enc_fx.c} | 0 .../{ivas_core_enc.c => ivas_core_enc_fx.c} | 0 ..._front.c => ivas_core_pre_proc_front_fx.c} | 0 ...ore_pre_proc.c => ivas_core_pre_proc_fx.c} | 0 ...fig.c => ivas_corecoder_enc_reconfig_fx.c} | 0 lib_enc/{ivas_cpe_enc.c => ivas_cpe_enc_fx.c} | 0 ...ix_enc.c => ivas_decision_matrix_enc_fx.c} | 0 .../{ivas_dirac_enc.c => ivas_dirac_enc_fx.c} | 0 ...ov_handler.c => ivas_enc_cov_handler_fx.c} | 0 lib_enc/{ivas_enc.c => ivas_enc_fx.c} | 0 ...ntropy_coder.c => ivas_entropy_coder_fx.c} | 0 .../{ivas_front_vad.c => ivas_front_vad_fx.c} | 0 .../{ivas_init_enc.c => ivas_init_enc_fx.c} | 0 ...as_ism_dtx_enc.c => ivas_ism_dtx_enc_fx.c} | 0 lib_enc/{ivas_ism_enc.c => ivas_ism_enc_fx.c} | 0 ...adata_enc.c => ivas_ism_metadata_enc_fx.c} | 0 ...sm_param_enc.c => ivas_ism_param_enc_fx.c} | 0 lib_enc/{ivas_lfe_enc.c => ivas_lfe_enc_fx.c} | 0 .../{ivas_masa_enc.c => ivas_masa_enc_fx.c} | 0 ..._mc_param_enc.c => ivas_mc_param_enc_fx.c} | 0 ...pmix_enc.c => ivas_mc_paramupmix_enc_fx.c} | 0 ...ivas_mcmasa_enc.c => ivas_mcmasa_enc_fx.c} | 0 ..._mct_core_enc.c => ivas_mct_core_enc_fx.c} | 0 lib_enc/{ivas_mct_enc.c => ivas_mct_enc_fx.c} | 0 ...as_mct_enc_mct.c => ivas_mct_enc_mct_fx.c} | 0 ...dct_core_enc.c => ivas_mdct_core_enc_fx.c} | 0 .../{ivas_omasa_enc.c => ivas_omasa_enc_fx.c} | 0 .../{ivas_osba_enc.c => ivas_osba_enc_fx.c} | 0 lib_enc/{ivas_pca_enc.c => ivas_pca_enc_fx.c} | 0 ...metadata_enc.c => ivas_qmetadata_enc_fx.c} | 0 ...herical_enc.c => ivas_qspherical_enc_fx.c} | 0 ...ange_uni_enc.c => ivas_range_uni_enc_fx.c} | 0 lib_enc/{ivas_sba_enc.c => ivas_sba_enc_fx.c} | 0 lib_enc/{ivas_sce_enc.c => ivas_sce_enc_fx.c} | 0 lib_enc/{ivas_sns_enc.c => ivas_sns_enc_fx.c} | 0 ..._spar_encoder.c => ivas_spar_encoder_fx.c} | 0 ...as_spar_md_enc.c => ivas_spar_md_enc_fx.c} | 0 ...GR_enc.c => ivas_stereo_adapt_GR_enc_fx.c} | 0 ...assifier.c => ivas_stereo_classifier_fx.c} | 0 ...reo_cng_enc.c => ivas_stereo_cng_enc_fx.c} | 0 ...reo_dft_enc.c => ivas_stereo_dft_enc_fx.c} | 0 ...enc_itd.c => ivas_stereo_dft_enc_itd_fx.c} | 0 ...t_td_itd.c => ivas_stereo_dft_td_itd_fx.c} | 0 ...reo_dmx_evs.c => ivas_stereo_dmx_evs_fx.c} | 0 ...eclvq_enc.c => ivas_stereo_eclvq_enc_fx.c} | 0 ...reo_ica_enc.c => ivas_stereo_ica_enc_fx.c} | 0 ...icbwe_enc.c => ivas_stereo_icbwe_enc_fx.c} | 0 ...e_enc.c => ivas_stereo_mdct_core_enc_fx.c} | 0 ...gf_enc.c => ivas_stereo_mdct_igf_enc_fx.c} | 0 ...enc.c => ivas_stereo_mdct_stereo_enc_fx.c} | 0 ...g_enc.c => ivas_stereo_switching_enc_fx.c} | 0 ...nalysis.c => ivas_stereo_td_analysis_fx.c} | 0 ...tereo_td_enc.c => ivas_stereo_td_enc_fx.c} | 0 ..._tcx_core_enc.c => ivas_tcx_core_enc_fx.c} | 0 ...w_rate_enc.c => ivas_td_low_rate_enc_fx.c} | 0 ...ivas_allrad_dec.c => ivas_allrad_dec_fx.c} | 0 lib_rend/{ivas_crend.c => ivas_crend_fx.c} | 0 .../{ivas_dirac_ana.c => ivas_dirac_ana_fx.c} | 0 ...=> ivas_dirac_dec_binaural_functions_fx.c} | 0 ...ecorr_dec.c => ivas_dirac_decorr_dec_fx.c} | 0 ...nsets_dec.c => ivas_dirac_onsets_dec_fx.c} | 0 ...c => ivas_dirac_output_synthesis_dec_fx.c} | 0 ...ivas_dirac_rend.c => ivas_dirac_rend_fx.c} | 0 lib_rend/{ivas_efap.c => ivas_efap_fx.c} | 0 lib_rend/{ivas_hrtf.c => ivas_hrtf_fx.c} | 0 .../{ivas_limiter.c => ivas_limiter_fx.c} | 0 ...ivas_masa_merge.c => ivas_masa_merge_fx.c} | 0 ...ivas_mcmasa_ana.c => ivas_mcmasa_ana_fx.c} | 0 ...ectRenderer.c => ivas_objectRenderer_fx.c} | 0 ...Filt.c => ivas_objectRenderer_hrFilt_fx.c} | 0 ...rer_mix.c => ivas_objectRenderer_mix_fx.c} | 0 ...rer_sfx.c => ivas_objectRenderer_sfx_fx.c} | 0 ...ces.c => ivas_objectRenderer_sources_fx.c} | 0 ...rer_vec.c => ivas_objectRenderer_vec_fx.c} | 0 .../{ivas_omasa_ana.c => ivas_omasa_ana_fx.c} | 0 ...ivas_orient_trk.c => ivas_orient_trk_fx.c} | 0 ...as_reflections.c => ivas_reflections_fx.c} | 0 ...ender_config.c => ivas_render_config_fx.c} | 0 ...lay_line.c => ivas_reverb_delay_line_fx.c} | 0 ...t_filter.c => ivas_reverb_fft_filter_fx.c} | 0 ...esign.c => ivas_reverb_filter_design_fx.c} | 0 lib_rend/{ivas_reverb.c => ivas_reverb_fx.c} | 0 ...r_filter.c => ivas_reverb_iir_filter_fx.c} | 0 ..._reverb_utils.c => ivas_reverb_utils_fx.c} | 0 ...rer.c => ivas_rom_TdBinauralRenderer_fx.c} | 0 ...derer.c => ivas_rom_binauralRenderer_fx.c} | 0 ...ad.c => ivas_rom_binaural_crend_head_fx.c} | 0 .../{ivas_rom_rend.c => ivas_rom_rend_fx.c} | 0 .../{ivas_rotation.c => ivas_rotation_fx.c} | 0 ...ba_rendering.c => ivas_sba_rendering_fx.c} | 0 .../{ivas_shoebox.c => ivas_shoebox_fx.c} | 0 .../{ivas_td_decorr.c => ivas_td_decorr_fx.c} | 0 lib_rend/{ivas_vbap.c => ivas_vbap_fx.c} | 0 179 files changed, 610 insertions(+), 613 deletions(-) rename lib_com/{ivas_arith.c => ivas_arith_fx.c} (100%) rename lib_com/{ivas_avq_pos_reorder_com.c => ivas_avq_pos_reorder_com_fx.c} (100%) rename lib_com/{ivas_cov_smooth.c => ivas_cov_smooth_fx.c} (100%) rename lib_com/{ivas_dirac_com.c => ivas_dirac_com_fx.c} (100%) rename lib_com/{ivas_entropy_coder_common.c => ivas_entropy_coder_common_fx.c} (100%) rename lib_com/{ivas_fb_mixer.c => ivas_fb_mixer_fx.c} (100%) rename lib_com/{ivas_filters.c => ivas_filters_fx.c} (100%) rename lib_com/{ivas_ism_com.c => ivas_ism_com_fx.c} (100%) rename lib_com/{ivas_lfe_com.c => ivas_lfe_com_fx.c} (100%) rename lib_com/{ivas_masa_com.c => ivas_masa_com_fx.c} (100%) rename lib_com/{ivas_mc_com.c => ivas_mc_com_fx.c} (100%) rename lib_com/{ivas_mc_param_com.c => ivas_mc_param_com_fx.c} (100%) rename lib_com/{ivas_mcmasa_com.c => ivas_mcmasa_com-fx.c} (100%) rename lib_com/{ivas_mct_com.c => ivas_mct_com_fx.c} (100%) rename lib_com/{ivas_mdct_core_com.c => ivas_mdct_core_com_fx.c} (100%) rename lib_com/{ivas_mdft_imdft.c => ivas_mdft_imdft_fx.c} (100%) rename lib_com/{ivas_omasa_com.c => ivas_omasa_com_fx.c} (100%) rename lib_com/{ivas_pca_tools.c => ivas_pca_tools_fx.c} (100%) rename lib_com/{ivas_qmetadata_com.c => ivas_qmetadata_com_fx.c} (100%) rename lib_com/{ivas_qspherical_com.c => ivas_qspherical_com_fx.c} (100%) rename lib_com/{ivas_sba_config.c => ivas_sba_config_fx.c} (100%) rename lib_com/{ivas_spar_com.c => ivas_spar_com_fx.c} (100%) rename lib_com/{ivas_spar_com_quant_util.c => ivas_spar_com_quant_util_fx.c} (100%) rename lib_com/{ivas_stereo_dft_com.c => ivas_stereo_dft_com_fx.c} (100%) rename lib_com/{ivas_stereo_mdct_bands_com.c => ivas_stereo_mdct_bands_com_fx.c} (100%) rename lib_com/{ivas_stereo_mdct_stereo_com.c => ivas_stereo_mdct_stereo_com_fx.c} (100%) rename lib_com/{ivas_stereo_psychlpc_com.c => ivas_stereo_psychlpc_com_fx.c} (100%) rename lib_com/{ivas_stereo_td_bit_alloc.c => ivas_stereo_td_bit_alloc_fx.c} (100%) rename lib_com/{ivas_tools.c => ivas_tools_fx.c} (100%) rename lib_com/{ivas_transient_det.c => ivas_transient_det_fx.c} (100%) rename lib_dec/{ivas_binRenderer_internal.c => ivas_binRenderer_internal_fx.c} (100%) rename lib_dec/{ivas_core_dec.c => ivas_core_dec_fx.c} (100%) rename lib_dec/{ivas_corecoder_dec_reconfig.c => ivas_corecoder_dec_reconfig_fx.c} (100%) rename lib_dec/{ivas_decision_matrix_dec.c => ivas_decision_matrix_dec_fx.c} (100%) rename lib_dec/{ivas_dirac_dec.c => ivas_dirac_dec_fx.c} (100%) rename lib_dec/{ivas_dirac_output_synthesis_cov.c => ivas_dirac_output_synthesis_cov_fx.c} (100%) rename lib_dec/{ivas_entropy_decoder.c => ivas_entropy_decoder_fx.c} (100%) rename lib_dec/{ivas_ism_dec.c => ivas_ism_dec_fx.c} (100%) rename lib_dec/{ivas_ism_dtx_dec.c => ivas_ism_dtx_dec_fx.c} (100%) rename lib_dec/{ivas_ism_metadata_dec.c => ivas_ism_metadata_dec_fx.c} (100%) rename lib_dec/{ivas_ism_param_dec.c => ivas_ism_param_dec_fx.c} (100%) rename lib_dec/{ivas_ism_renderer.c => ivas_ism_renderer_fx.c} (100%) rename lib_dec/{ivas_jbm_dec.c => ivas_jbm_dec_fx.c} (100%) rename lib_dec/{ivas_ls_custom_dec.c => ivas_ls_custom_dec_fx.c} (100%) rename lib_dec/{ivas_masa_dec.c => ivas_masa_dec_fx.c} (100%) rename lib_dec/{ivas_mc_param_dec.c => ivas_mc_param_dec_fx.c} (100%) rename lib_dec/{ivas_mc_paramupmix_dec.c => ivas_mc_paramupmix_dec_fx.c} (100%) rename lib_dec/{ivas_mcmasa_dec.c => ivas_mcmasa_dec_fx.c} (100%) rename lib_dec/{ivas_mct_core_dec.c => ivas_mct_core_dec_fx.c} (100%) rename lib_dec/{ivas_mct_dec.c => ivas_mct_dec_fx.c} (100%) rename lib_dec/{ivas_mct_dec_mct_fx.c => ivas_mct_dec_mct_fx_fx.c} (100%) rename lib_dec/{ivas_mdct_core_dec.c => ivas_mdct_core_dec_fx.c} (100%) rename lib_dec/{ivas_mono_dmx_renderer.c => ivas_mono_dmx_renderer_fx.c} (100%) rename lib_dec/{ivas_objectRenderer_internal.c => ivas_objectRenderer_internal_fx.c} (100%) rename lib_dec/{ivas_omasa_dec.c => ivas_omasa_dec_fx.c} (100%) rename lib_dec/{ivas_osba_dec.c => ivas_osba_dec_fx.c} (100%) rename lib_dec/{ivas_out_setup_conversion.c => ivas_out_setup_conversion_fx.c} (100%) rename lib_dec/{ivas_output_config.c => ivas_output_config_fx.c} (100%) rename lib_dec/{ivas_post_proc.c => ivas_post_proc_fx.c} (100%) rename lib_dec/{ivas_qmetadata_dec.c => ivas_qmetadata_dec_fx.c} (100%) rename lib_dec/{ivas_qspherical_dec.c => ivas_qspherical_dec_fx.c} (100%) rename lib_dec/{ivas_range_uni_dec.c => ivas_range_uni_dec_fx.c} (100%) rename lib_dec/{ivas_sba_dec.c => ivas_sba_dec_fx.c} (100%) rename lib_dec/{ivas_sba_rendering_internal.c => ivas_sba_rendering_internal_fx.c} (100%) rename lib_dec/{ivas_spar_decoder.c => ivas_spar_decoder_fx.c} (100%) rename lib_dec/{ivas_spar_md_dec.c => ivas_spar_md_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_adapt_GR_dec.c => ivas_stereo_adapt_GR_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_dft_dec_dmx.c => ivas_stereo_dft_dec_dmx_fx.c} (100%) rename lib_dec/{ivas_stereo_eclvq_dec.c => ivas_stereo_eclvq_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_esf_dec.c => ivas_stereo_esf_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_ica_dec.c => ivas_stereo_ica_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_icbwe_dec.c => ivas_stereo_icbwe_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_mdct_stereo_dec.c => ivas_stereo_mdct_stereo_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_switching_dec.c => ivas_stereo_switching_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_td_dec.c => ivas_stereo_td_dec_fx.c} (100%) rename lib_dec/{ivas_svd_dec.c => ivas_svd_dec_fx.c} (100%) rename lib_dec/{ivas_tcx_core_dec.c => ivas_tcx_core_dec_fx.c} (100%) rename lib_dec/{ivas_td_low_rate_dec.c => ivas_td_low_rate_dec_fx.c} (100%) rename lib_enc/{ivas_agc_enc.c => ivas_agc_enc_fx.c} (100%) rename lib_enc/{ivas_core_enc.c => ivas_core_enc_fx.c} (100%) rename lib_enc/{ivas_core_pre_proc_front.c => ivas_core_pre_proc_front_fx.c} (100%) rename lib_enc/{ivas_core_pre_proc.c => ivas_core_pre_proc_fx.c} (100%) rename lib_enc/{ivas_corecoder_enc_reconfig.c => ivas_corecoder_enc_reconfig_fx.c} (100%) rename lib_enc/{ivas_cpe_enc.c => ivas_cpe_enc_fx.c} (100%) rename lib_enc/{ivas_decision_matrix_enc.c => ivas_decision_matrix_enc_fx.c} (100%) rename lib_enc/{ivas_dirac_enc.c => ivas_dirac_enc_fx.c} (100%) rename lib_enc/{ivas_enc_cov_handler.c => ivas_enc_cov_handler_fx.c} (100%) rename lib_enc/{ivas_enc.c => ivas_enc_fx.c} (100%) rename lib_enc/{ivas_entropy_coder.c => ivas_entropy_coder_fx.c} (100%) rename lib_enc/{ivas_front_vad.c => ivas_front_vad_fx.c} (100%) rename lib_enc/{ivas_init_enc.c => ivas_init_enc_fx.c} (100%) rename lib_enc/{ivas_ism_dtx_enc.c => ivas_ism_dtx_enc_fx.c} (100%) rename lib_enc/{ivas_ism_enc.c => ivas_ism_enc_fx.c} (100%) rename lib_enc/{ivas_ism_metadata_enc.c => ivas_ism_metadata_enc_fx.c} (100%) rename lib_enc/{ivas_ism_param_enc.c => ivas_ism_param_enc_fx.c} (100%) rename lib_enc/{ivas_lfe_enc.c => ivas_lfe_enc_fx.c} (100%) rename lib_enc/{ivas_masa_enc.c => ivas_masa_enc_fx.c} (100%) rename lib_enc/{ivas_mc_param_enc.c => ivas_mc_param_enc_fx.c} (100%) rename lib_enc/{ivas_mc_paramupmix_enc.c => ivas_mc_paramupmix_enc_fx.c} (100%) rename lib_enc/{ivas_mcmasa_enc.c => ivas_mcmasa_enc_fx.c} (100%) rename lib_enc/{ivas_mct_core_enc.c => ivas_mct_core_enc_fx.c} (100%) rename lib_enc/{ivas_mct_enc.c => ivas_mct_enc_fx.c} (100%) rename lib_enc/{ivas_mct_enc_mct.c => ivas_mct_enc_mct_fx.c} (100%) rename lib_enc/{ivas_mdct_core_enc.c => ivas_mdct_core_enc_fx.c} (100%) rename lib_enc/{ivas_omasa_enc.c => ivas_omasa_enc_fx.c} (100%) rename lib_enc/{ivas_osba_enc.c => ivas_osba_enc_fx.c} (100%) rename lib_enc/{ivas_pca_enc.c => ivas_pca_enc_fx.c} (100%) rename lib_enc/{ivas_qmetadata_enc.c => ivas_qmetadata_enc_fx.c} (100%) rename lib_enc/{ivas_qspherical_enc.c => ivas_qspherical_enc_fx.c} (100%) rename lib_enc/{ivas_range_uni_enc.c => ivas_range_uni_enc_fx.c} (100%) rename lib_enc/{ivas_sba_enc.c => ivas_sba_enc_fx.c} (100%) rename lib_enc/{ivas_sce_enc.c => ivas_sce_enc_fx.c} (100%) rename lib_enc/{ivas_sns_enc.c => ivas_sns_enc_fx.c} (100%) rename lib_enc/{ivas_spar_encoder.c => ivas_spar_encoder_fx.c} (100%) rename lib_enc/{ivas_spar_md_enc.c => ivas_spar_md_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_adapt_GR_enc.c => ivas_stereo_adapt_GR_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_classifier.c => ivas_stereo_classifier_fx.c} (100%) rename lib_enc/{ivas_stereo_cng_enc.c => ivas_stereo_cng_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_dft_enc.c => ivas_stereo_dft_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_dft_enc_itd.c => ivas_stereo_dft_enc_itd_fx.c} (100%) rename lib_enc/{ivas_stereo_dft_td_itd.c => ivas_stereo_dft_td_itd_fx.c} (100%) rename lib_enc/{ivas_stereo_dmx_evs.c => ivas_stereo_dmx_evs_fx.c} (100%) rename lib_enc/{ivas_stereo_eclvq_enc.c => ivas_stereo_eclvq_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_ica_enc.c => ivas_stereo_ica_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_icbwe_enc.c => ivas_stereo_icbwe_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_mdct_core_enc.c => ivas_stereo_mdct_core_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_mdct_igf_enc.c => ivas_stereo_mdct_igf_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_mdct_stereo_enc.c => ivas_stereo_mdct_stereo_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_switching_enc.c => ivas_stereo_switching_enc_fx.c} (100%) rename lib_enc/{ivas_stereo_td_analysis.c => ivas_stereo_td_analysis_fx.c} (100%) rename lib_enc/{ivas_stereo_td_enc.c => ivas_stereo_td_enc_fx.c} (100%) rename lib_enc/{ivas_tcx_core_enc.c => ivas_tcx_core_enc_fx.c} (100%) rename lib_enc/{ivas_td_low_rate_enc.c => ivas_td_low_rate_enc_fx.c} (100%) rename lib_rend/{ivas_allrad_dec.c => ivas_allrad_dec_fx.c} (100%) rename lib_rend/{ivas_crend.c => ivas_crend_fx.c} (100%) rename lib_rend/{ivas_dirac_ana.c => ivas_dirac_ana_fx.c} (100%) rename lib_rend/{ivas_dirac_dec_binaural_functions.c => ivas_dirac_dec_binaural_functions_fx.c} (100%) rename lib_rend/{ivas_dirac_decorr_dec.c => ivas_dirac_decorr_dec_fx.c} (100%) rename lib_rend/{ivas_dirac_onsets_dec.c => ivas_dirac_onsets_dec_fx.c} (100%) rename lib_rend/{ivas_dirac_output_synthesis_dec.c => ivas_dirac_output_synthesis_dec_fx.c} (100%) rename lib_rend/{ivas_dirac_rend.c => ivas_dirac_rend_fx.c} (100%) rename lib_rend/{ivas_efap.c => ivas_efap_fx.c} (100%) rename lib_rend/{ivas_hrtf.c => ivas_hrtf_fx.c} (100%) rename lib_rend/{ivas_limiter.c => ivas_limiter_fx.c} (100%) rename lib_rend/{ivas_masa_merge.c => ivas_masa_merge_fx.c} (100%) rename lib_rend/{ivas_mcmasa_ana.c => ivas_mcmasa_ana_fx.c} (100%) rename lib_rend/{ivas_objectRenderer.c => ivas_objectRenderer_fx.c} (100%) rename lib_rend/{ivas_objectRenderer_hrFilt.c => ivas_objectRenderer_hrFilt_fx.c} (100%) rename lib_rend/{ivas_objectRenderer_mix.c => ivas_objectRenderer_mix_fx.c} (100%) rename lib_rend/{ivas_objectRenderer_sfx.c => ivas_objectRenderer_sfx_fx.c} (100%) rename lib_rend/{ivas_objectRenderer_sources.c => ivas_objectRenderer_sources_fx.c} (100%) rename lib_rend/{ivas_objectRenderer_vec.c => ivas_objectRenderer_vec_fx.c} (100%) rename lib_rend/{ivas_omasa_ana.c => ivas_omasa_ana_fx.c} (100%) rename lib_rend/{ivas_orient_trk.c => ivas_orient_trk_fx.c} (100%) rename lib_rend/{ivas_reflections.c => ivas_reflections_fx.c} (100%) rename lib_rend/{ivas_render_config.c => ivas_render_config_fx.c} (100%) rename lib_rend/{ivas_reverb_delay_line.c => ivas_reverb_delay_line_fx.c} (100%) rename lib_rend/{ivas_reverb_fft_filter.c => ivas_reverb_fft_filter_fx.c} (100%) rename lib_rend/{ivas_reverb_filter_design.c => ivas_reverb_filter_design_fx.c} (100%) rename lib_rend/{ivas_reverb.c => ivas_reverb_fx.c} (100%) rename lib_rend/{ivas_reverb_iir_filter.c => ivas_reverb_iir_filter_fx.c} (100%) rename lib_rend/{ivas_reverb_utils.c => ivas_reverb_utils_fx.c} (100%) rename lib_rend/{ivas_rom_TdBinauralRenderer.c => ivas_rom_TdBinauralRenderer_fx.c} (100%) rename lib_rend/{ivas_rom_binauralRenderer.c => ivas_rom_binauralRenderer_fx.c} (100%) rename lib_rend/{ivas_rom_binaural_crend_head.c => ivas_rom_binaural_crend_head_fx.c} (100%) rename lib_rend/{ivas_rom_rend.c => ivas_rom_rend_fx.c} (100%) rename lib_rend/{ivas_rotation.c => ivas_rotation_fx.c} (100%) rename lib_rend/{ivas_sba_rendering.c => ivas_sba_rendering_fx.c} (100%) rename lib_rend/{ivas_shoebox.c => ivas_shoebox_fx.c} (100%) rename lib_rend/{ivas_td_decorr.c => ivas_td_decorr_fx.c} (100%) rename lib_rend/{ivas_vbap.c => ivas_vbap_fx.c} (100%) diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index c88725ef0..8c42f19ca 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -200,42 +200,42 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + - + - - - + + + - - - - - - + + + + + + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index c58edbff6..8f2be8853 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -1,81 +1,6 @@ - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - common_all_c @@ -469,18 +394,6 @@ common_ivas_c - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - common_ivas_c @@ -493,9 +406,6 @@ common_ivas_c - - common_ivas_c - common_all_c @@ -544,6 +454,96 @@ common_all_c + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index b3a847791..2d06d29aa 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -210,69 +210,69 @@ - - - + + + - - - - + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + + + - + - + - - - + + + - + - - - - + + + + - - - - - - + + + + + + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index c4e148b89..8a4fc4605 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -71,195 +71,51 @@ decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_ivas_c - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - decoder_all_c @@ -518,6 +374,150 @@ decoder_all_c + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 86e56d42a..86dcef905 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -215,64 +215,64 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -319,7 +319,7 @@ - + diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 406c01b86..899097163 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -107,174 +107,9 @@ encoder_evs_c - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - encoder_ivas_c - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - - - encoder_ivas_c - encoder_all_c @@ -602,6 +437,171 @@ encoder_all_c + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + + + encoder_ivas_c + diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index fa11b23be..1ffab139a 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -136,46 +136,46 @@ - - - - - - + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index 01f3dfb74..47b4fee01 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -2,124 +2,124 @@ - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c @@ -143,9 +143,6 @@ rend_h - - rend_h - diff --git a/lib_com/ivas_arith.c b/lib_com/ivas_arith_fx.c similarity index 100% rename from lib_com/ivas_arith.c rename to lib_com/ivas_arith_fx.c diff --git a/lib_com/ivas_avq_pos_reorder_com.c b/lib_com/ivas_avq_pos_reorder_com_fx.c similarity index 100% rename from lib_com/ivas_avq_pos_reorder_com.c rename to lib_com/ivas_avq_pos_reorder_com_fx.c diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth_fx.c similarity index 100% rename from lib_com/ivas_cov_smooth.c rename to lib_com/ivas_cov_smooth_fx.c diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com_fx.c similarity index 100% rename from lib_com/ivas_dirac_com.c rename to lib_com/ivas_dirac_com_fx.c diff --git a/lib_com/ivas_entropy_coder_common.c b/lib_com/ivas_entropy_coder_common_fx.c similarity index 100% rename from lib_com/ivas_entropy_coder_common.c rename to lib_com/ivas_entropy_coder_common_fx.c diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer_fx.c similarity index 100% rename from lib_com/ivas_fb_mixer.c rename to lib_com/ivas_fb_mixer_fx.c diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters_fx.c similarity index 100% rename from lib_com/ivas_filters.c rename to lib_com/ivas_filters_fx.c diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com_fx.c similarity index 100% rename from lib_com/ivas_ism_com.c rename to lib_com/ivas_ism_com_fx.c diff --git a/lib_com/ivas_lfe_com.c b/lib_com/ivas_lfe_com_fx.c similarity index 100% rename from lib_com/ivas_lfe_com.c rename to lib_com/ivas_lfe_com_fx.c diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com_fx.c similarity index 100% rename from lib_com/ivas_masa_com.c rename to lib_com/ivas_masa_com_fx.c diff --git a/lib_com/ivas_mc_com.c b/lib_com/ivas_mc_com_fx.c similarity index 100% rename from lib_com/ivas_mc_com.c rename to lib_com/ivas_mc_com_fx.c diff --git a/lib_com/ivas_mc_param_com.c b/lib_com/ivas_mc_param_com_fx.c similarity index 100% rename from lib_com/ivas_mc_param_com.c rename to lib_com/ivas_mc_param_com_fx.c diff --git a/lib_com/ivas_mcmasa_com.c b/lib_com/ivas_mcmasa_com-fx.c similarity index 100% rename from lib_com/ivas_mcmasa_com.c rename to lib_com/ivas_mcmasa_com-fx.c diff --git a/lib_com/ivas_mct_com.c b/lib_com/ivas_mct_com_fx.c similarity index 100% rename from lib_com/ivas_mct_com.c rename to lib_com/ivas_mct_com_fx.c diff --git a/lib_com/ivas_mdct_core_com.c b/lib_com/ivas_mdct_core_com_fx.c similarity index 100% rename from lib_com/ivas_mdct_core_com.c rename to lib_com/ivas_mdct_core_com_fx.c diff --git a/lib_com/ivas_mdft_imdft.c b/lib_com/ivas_mdft_imdft_fx.c similarity index 100% rename from lib_com/ivas_mdft_imdft.c rename to lib_com/ivas_mdft_imdft_fx.c diff --git a/lib_com/ivas_omasa_com.c b/lib_com/ivas_omasa_com_fx.c similarity index 100% rename from lib_com/ivas_omasa_com.c rename to lib_com/ivas_omasa_com_fx.c diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools_fx.c similarity index 100% rename from lib_com/ivas_pca_tools.c rename to lib_com/ivas_pca_tools_fx.c diff --git a/lib_com/ivas_qmetadata_com.c b/lib_com/ivas_qmetadata_com_fx.c similarity index 100% rename from lib_com/ivas_qmetadata_com.c rename to lib_com/ivas_qmetadata_com_fx.c diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com_fx.c similarity index 100% rename from lib_com/ivas_qspherical_com.c rename to lib_com/ivas_qspherical_com_fx.c diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config_fx.c similarity index 100% rename from lib_com/ivas_sba_config.c rename to lib_com/ivas_sba_config_fx.c diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com_fx.c similarity index 100% rename from lib_com/ivas_spar_com.c rename to lib_com/ivas_spar_com_fx.c diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util_fx.c similarity index 100% rename from lib_com/ivas_spar_com_quant_util.c rename to lib_com/ivas_spar_com_quant_util_fx.c diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com_fx.c similarity index 100% rename from lib_com/ivas_stereo_dft_com.c rename to lib_com/ivas_stereo_dft_com_fx.c diff --git a/lib_com/ivas_stereo_mdct_bands_com.c b/lib_com/ivas_stereo_mdct_bands_com_fx.c similarity index 100% rename from lib_com/ivas_stereo_mdct_bands_com.c rename to lib_com/ivas_stereo_mdct_bands_com_fx.c diff --git a/lib_com/ivas_stereo_mdct_stereo_com.c b/lib_com/ivas_stereo_mdct_stereo_com_fx.c similarity index 100% rename from lib_com/ivas_stereo_mdct_stereo_com.c rename to lib_com/ivas_stereo_mdct_stereo_com_fx.c diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com_fx.c similarity index 100% rename from lib_com/ivas_stereo_psychlpc_com.c rename to lib_com/ivas_stereo_psychlpc_com_fx.c diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc_fx.c similarity index 100% rename from lib_com/ivas_stereo_td_bit_alloc.c rename to lib_com/ivas_stereo_td_bit_alloc_fx.c diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools_fx.c similarity index 100% rename from lib_com/ivas_tools.c rename to lib_com/ivas_tools_fx.c diff --git a/lib_com/ivas_transient_det.c b/lib_com/ivas_transient_det_fx.c similarity index 100% rename from lib_com/ivas_transient_det.c rename to lib_com/ivas_transient_det_fx.c diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal_fx.c similarity index 100% rename from lib_dec/ivas_binRenderer_internal.c rename to lib_dec/ivas_binRenderer_internal_fx.c diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec_fx.c similarity index 100% rename from lib_dec/ivas_core_dec.c rename to lib_dec/ivas_core_dec_fx.c diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c similarity index 100% rename from lib_dec/ivas_corecoder_dec_reconfig.c rename to lib_dec/ivas_corecoder_dec_reconfig_fx.c diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec_fx.c similarity index 100% rename from lib_dec/ivas_decision_matrix_dec.c rename to lib_dec/ivas_decision_matrix_dec_fx.c diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec_fx.c similarity index 100% rename from lib_dec/ivas_dirac_dec.c rename to lib_dec/ivas_dirac_dec_fx.c diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c similarity index 100% rename from lib_dec/ivas_dirac_output_synthesis_cov.c rename to lib_dec/ivas_dirac_output_synthesis_cov_fx.c diff --git a/lib_dec/ivas_entropy_decoder.c b/lib_dec/ivas_entropy_decoder_fx.c similarity index 100% rename from lib_dec/ivas_entropy_decoder.c rename to lib_dec/ivas_entropy_decoder_fx.c diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec_fx.c similarity index 100% rename from lib_dec/ivas_ism_dec.c rename to lib_dec/ivas_ism_dec_fx.c diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec_fx.c similarity index 100% rename from lib_dec/ivas_ism_dtx_dec.c rename to lib_dec/ivas_ism_dtx_dec_fx.c diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec_fx.c similarity index 100% rename from lib_dec/ivas_ism_metadata_dec.c rename to lib_dec/ivas_ism_metadata_dec_fx.c diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec_fx.c similarity index 100% rename from lib_dec/ivas_ism_param_dec.c rename to lib_dec/ivas_ism_param_dec_fx.c diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer_fx.c similarity index 100% rename from lib_dec/ivas_ism_renderer.c rename to lib_dec/ivas_ism_renderer_fx.c diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec_fx.c similarity index 100% rename from lib_dec/ivas_jbm_dec.c rename to lib_dec/ivas_jbm_dec_fx.c diff --git a/lib_dec/ivas_ls_custom_dec.c b/lib_dec/ivas_ls_custom_dec_fx.c similarity index 100% rename from lib_dec/ivas_ls_custom_dec.c rename to lib_dec/ivas_ls_custom_dec_fx.c diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec_fx.c similarity index 100% rename from lib_dec/ivas_masa_dec.c rename to lib_dec/ivas_masa_dec_fx.c diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec_fx.c similarity index 100% rename from lib_dec/ivas_mc_param_dec.c rename to lib_dec/ivas_mc_param_dec_fx.c diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c similarity index 100% rename from lib_dec/ivas_mc_paramupmix_dec.c rename to lib_dec/ivas_mc_paramupmix_dec_fx.c diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec_fx.c similarity index 100% rename from lib_dec/ivas_mcmasa_dec.c rename to lib_dec/ivas_mcmasa_dec_fx.c diff --git a/lib_dec/ivas_mct_core_dec.c b/lib_dec/ivas_mct_core_dec_fx.c similarity index 100% rename from lib_dec/ivas_mct_core_dec.c rename to lib_dec/ivas_mct_core_dec_fx.c diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec_fx.c similarity index 100% rename from lib_dec/ivas_mct_dec.c rename to lib_dec/ivas_mct_dec_fx.c diff --git a/lib_dec/ivas_mct_dec_mct_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c similarity index 100% rename from lib_dec/ivas_mct_dec_mct_fx.c rename to lib_dec/ivas_mct_dec_mct_fx_fx.c diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec_fx.c similarity index 100% rename from lib_dec/ivas_mdct_core_dec.c rename to lib_dec/ivas_mdct_core_dec_fx.c diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer_fx.c similarity index 100% rename from lib_dec/ivas_mono_dmx_renderer.c rename to lib_dec/ivas_mono_dmx_renderer_fx.c diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal_fx.c similarity index 100% rename from lib_dec/ivas_objectRenderer_internal.c rename to lib_dec/ivas_objectRenderer_internal_fx.c diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec_fx.c similarity index 100% rename from lib_dec/ivas_omasa_dec.c rename to lib_dec/ivas_omasa_dec_fx.c diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec_fx.c similarity index 100% rename from lib_dec/ivas_osba_dec.c rename to lib_dec/ivas_osba_dec_fx.c diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion_fx.c similarity index 100% rename from lib_dec/ivas_out_setup_conversion.c rename to lib_dec/ivas_out_setup_conversion_fx.c diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config_fx.c similarity index 100% rename from lib_dec/ivas_output_config.c rename to lib_dec/ivas_output_config_fx.c diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc_fx.c similarity index 100% rename from lib_dec/ivas_post_proc.c rename to lib_dec/ivas_post_proc_fx.c diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec_fx.c similarity index 100% rename from lib_dec/ivas_qmetadata_dec.c rename to lib_dec/ivas_qmetadata_dec_fx.c diff --git a/lib_dec/ivas_qspherical_dec.c b/lib_dec/ivas_qspherical_dec_fx.c similarity index 100% rename from lib_dec/ivas_qspherical_dec.c rename to lib_dec/ivas_qspherical_dec_fx.c diff --git a/lib_dec/ivas_range_uni_dec.c b/lib_dec/ivas_range_uni_dec_fx.c similarity index 100% rename from lib_dec/ivas_range_uni_dec.c rename to lib_dec/ivas_range_uni_dec_fx.c diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec_fx.c similarity index 100% rename from lib_dec/ivas_sba_dec.c rename to lib_dec/ivas_sba_dec_fx.c diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal_fx.c similarity index 100% rename from lib_dec/ivas_sba_rendering_internal.c rename to lib_dec/ivas_sba_rendering_internal_fx.c diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder_fx.c similarity index 100% rename from lib_dec/ivas_spar_decoder.c rename to lib_dec/ivas_spar_decoder_fx.c diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec_fx.c similarity index 100% rename from lib_dec/ivas_spar_md_dec.c rename to lib_dec/ivas_spar_md_dec_fx.c diff --git a/lib_dec/ivas_stereo_adapt_GR_dec.c b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_adapt_GR_dec.c rename to lib_dec/ivas_stereo_adapt_GR_dec_fx.c diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c similarity index 100% rename from lib_dec/ivas_stereo_dft_dec_dmx.c rename to lib_dec/ivas_stereo_dft_dec_dmx_fx.c diff --git a/lib_dec/ivas_stereo_eclvq_dec.c b/lib_dec/ivas_stereo_eclvq_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_eclvq_dec.c rename to lib_dec/ivas_stereo_eclvq_dec_fx.c diff --git a/lib_dec/ivas_stereo_esf_dec.c b/lib_dec/ivas_stereo_esf_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_esf_dec.c rename to lib_dec/ivas_stereo_esf_dec_fx.c diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_ica_dec.c rename to lib_dec/ivas_stereo_ica_dec_fx.c diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_icbwe_dec.c rename to lib_dec/ivas_stereo_icbwe_dec_fx.c diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_mdct_stereo_dec.c rename to lib_dec/ivas_stereo_mdct_stereo_dec_fx.c diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_switching_dec.c rename to lib_dec/ivas_stereo_switching_dec_fx.c diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec_fx.c similarity index 100% rename from lib_dec/ivas_stereo_td_dec.c rename to lib_dec/ivas_stereo_td_dec_fx.c diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec_fx.c similarity index 100% rename from lib_dec/ivas_svd_dec.c rename to lib_dec/ivas_svd_dec_fx.c diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec_fx.c similarity index 100% rename from lib_dec/ivas_tcx_core_dec.c rename to lib_dec/ivas_tcx_core_dec_fx.c diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec_fx.c similarity index 100% rename from lib_dec/ivas_td_low_rate_dec.c rename to lib_dec/ivas_td_low_rate_dec_fx.c diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc_fx.c similarity index 100% rename from lib_enc/ivas_agc_enc.c rename to lib_enc/ivas_agc_enc_fx.c diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc_fx.c similarity index 100% rename from lib_enc/ivas_core_enc.c rename to lib_enc/ivas_core_enc_fx.c diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front_fx.c similarity index 100% rename from lib_enc/ivas_core_pre_proc_front.c rename to lib_enc/ivas_core_pre_proc_front_fx.c diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc_fx.c similarity index 100% rename from lib_enc/ivas_core_pre_proc.c rename to lib_enc/ivas_core_pre_proc_fx.c diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c similarity index 100% rename from lib_enc/ivas_corecoder_enc_reconfig.c rename to lib_enc/ivas_corecoder_enc_reconfig_fx.c diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc_fx.c similarity index 100% rename from lib_enc/ivas_cpe_enc.c rename to lib_enc/ivas_cpe_enc_fx.c diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc_fx.c similarity index 100% rename from lib_enc/ivas_decision_matrix_enc.c rename to lib_enc/ivas_decision_matrix_enc_fx.c diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc_fx.c similarity index 100% rename from lib_enc/ivas_dirac_enc.c rename to lib_enc/ivas_dirac_enc_fx.c diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler_fx.c similarity index 100% rename from lib_enc/ivas_enc_cov_handler.c rename to lib_enc/ivas_enc_cov_handler_fx.c diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc_fx.c similarity index 100% rename from lib_enc/ivas_enc.c rename to lib_enc/ivas_enc_fx.c diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder_fx.c similarity index 100% rename from lib_enc/ivas_entropy_coder.c rename to lib_enc/ivas_entropy_coder_fx.c diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad_fx.c similarity index 100% rename from lib_enc/ivas_front_vad.c rename to lib_enc/ivas_front_vad_fx.c diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc_fx.c similarity index 100% rename from lib_enc/ivas_init_enc.c rename to lib_enc/ivas_init_enc_fx.c diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc_fx.c similarity index 100% rename from lib_enc/ivas_ism_dtx_enc.c rename to lib_enc/ivas_ism_dtx_enc_fx.c diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc_fx.c similarity index 100% rename from lib_enc/ivas_ism_enc.c rename to lib_enc/ivas_ism_enc_fx.c diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc_fx.c similarity index 100% rename from lib_enc/ivas_ism_metadata_enc.c rename to lib_enc/ivas_ism_metadata_enc_fx.c diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc_fx.c similarity index 100% rename from lib_enc/ivas_ism_param_enc.c rename to lib_enc/ivas_ism_param_enc_fx.c diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc_fx.c similarity index 100% rename from lib_enc/ivas_lfe_enc.c rename to lib_enc/ivas_lfe_enc_fx.c diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc_fx.c similarity index 100% rename from lib_enc/ivas_masa_enc.c rename to lib_enc/ivas_masa_enc_fx.c diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc_fx.c similarity index 100% rename from lib_enc/ivas_mc_param_enc.c rename to lib_enc/ivas_mc_param_enc_fx.c diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c similarity index 100% rename from lib_enc/ivas_mc_paramupmix_enc.c rename to lib_enc/ivas_mc_paramupmix_enc_fx.c diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc_fx.c similarity index 100% rename from lib_enc/ivas_mcmasa_enc.c rename to lib_enc/ivas_mcmasa_enc_fx.c diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc_fx.c similarity index 100% rename from lib_enc/ivas_mct_core_enc.c rename to lib_enc/ivas_mct_core_enc_fx.c diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc_fx.c similarity index 100% rename from lib_enc/ivas_mct_enc.c rename to lib_enc/ivas_mct_enc_fx.c diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct_fx.c similarity index 100% rename from lib_enc/ivas_mct_enc_mct.c rename to lib_enc/ivas_mct_enc_mct_fx.c diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc_fx.c similarity index 100% rename from lib_enc/ivas_mdct_core_enc.c rename to lib_enc/ivas_mdct_core_enc_fx.c diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc_fx.c similarity index 100% rename from lib_enc/ivas_omasa_enc.c rename to lib_enc/ivas_omasa_enc_fx.c diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc_fx.c similarity index 100% rename from lib_enc/ivas_osba_enc.c rename to lib_enc/ivas_osba_enc_fx.c diff --git a/lib_enc/ivas_pca_enc.c b/lib_enc/ivas_pca_enc_fx.c similarity index 100% rename from lib_enc/ivas_pca_enc.c rename to lib_enc/ivas_pca_enc_fx.c diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc_fx.c similarity index 100% rename from lib_enc/ivas_qmetadata_enc.c rename to lib_enc/ivas_qmetadata_enc_fx.c diff --git a/lib_enc/ivas_qspherical_enc.c b/lib_enc/ivas_qspherical_enc_fx.c similarity index 100% rename from lib_enc/ivas_qspherical_enc.c rename to lib_enc/ivas_qspherical_enc_fx.c diff --git a/lib_enc/ivas_range_uni_enc.c b/lib_enc/ivas_range_uni_enc_fx.c similarity index 100% rename from lib_enc/ivas_range_uni_enc.c rename to lib_enc/ivas_range_uni_enc_fx.c diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc_fx.c similarity index 100% rename from lib_enc/ivas_sba_enc.c rename to lib_enc/ivas_sba_enc_fx.c diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc_fx.c similarity index 100% rename from lib_enc/ivas_sce_enc.c rename to lib_enc/ivas_sce_enc_fx.c diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc_fx.c similarity index 100% rename from lib_enc/ivas_sns_enc.c rename to lib_enc/ivas_sns_enc_fx.c diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder_fx.c similarity index 100% rename from lib_enc/ivas_spar_encoder.c rename to lib_enc/ivas_spar_encoder_fx.c diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc_fx.c similarity index 100% rename from lib_enc/ivas_spar_md_enc.c rename to lib_enc/ivas_spar_md_enc_fx.c diff --git a/lib_enc/ivas_stereo_adapt_GR_enc.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_adapt_GR_enc.c rename to lib_enc/ivas_stereo_adapt_GR_enc_fx.c diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier_fx.c similarity index 100% rename from lib_enc/ivas_stereo_classifier.c rename to lib_enc/ivas_stereo_classifier_fx.c diff --git a/lib_enc/ivas_stereo_cng_enc.c b/lib_enc/ivas_stereo_cng_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_cng_enc.c rename to lib_enc/ivas_stereo_cng_enc_fx.c diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_dft_enc.c rename to lib_enc/ivas_stereo_dft_enc_fx.c diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c similarity index 100% rename from lib_enc/ivas_stereo_dft_enc_itd.c rename to lib_enc/ivas_stereo_dft_enc_itd_fx.c diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c similarity index 100% rename from lib_enc/ivas_stereo_dft_td_itd.c rename to lib_enc/ivas_stereo_dft_td_itd_fx.c diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs_fx.c similarity index 100% rename from lib_enc/ivas_stereo_dmx_evs.c rename to lib_enc/ivas_stereo_dmx_evs_fx.c diff --git a/lib_enc/ivas_stereo_eclvq_enc.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_eclvq_enc.c rename to lib_enc/ivas_stereo_eclvq_enc_fx.c diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_ica_enc.c rename to lib_enc/ivas_stereo_ica_enc_fx.c diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_icbwe_enc.c rename to lib_enc/ivas_stereo_icbwe_enc_fx.c diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_mdct_core_enc.c rename to lib_enc/ivas_stereo_mdct_core_enc_fx.c diff --git a/lib_enc/ivas_stereo_mdct_igf_enc.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_mdct_igf_enc.c rename to lib_enc/ivas_stereo_mdct_igf_enc_fx.c diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_mdct_stereo_enc.c rename to lib_enc/ivas_stereo_mdct_stereo_enc_fx.c diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_switching_enc.c rename to lib_enc/ivas_stereo_switching_enc_fx.c diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis_fx.c similarity index 100% rename from lib_enc/ivas_stereo_td_analysis.c rename to lib_enc/ivas_stereo_td_analysis_fx.c diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc_fx.c similarity index 100% rename from lib_enc/ivas_stereo_td_enc.c rename to lib_enc/ivas_stereo_td_enc_fx.c diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc_fx.c similarity index 100% rename from lib_enc/ivas_tcx_core_enc.c rename to lib_enc/ivas_tcx_core_enc_fx.c diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc_fx.c similarity index 100% rename from lib_enc/ivas_td_low_rate_enc.c rename to lib_enc/ivas_td_low_rate_enc_fx.c diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec_fx.c similarity index 100% rename from lib_rend/ivas_allrad_dec.c rename to lib_rend/ivas_allrad_dec_fx.c diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend_fx.c similarity index 100% rename from lib_rend/ivas_crend.c rename to lib_rend/ivas_crend_fx.c diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana_fx.c similarity index 100% rename from lib_rend/ivas_dirac_ana.c rename to lib_rend/ivas_dirac_ana_fx.c diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c similarity index 100% rename from lib_rend/ivas_dirac_dec_binaural_functions.c rename to lib_rend/ivas_dirac_dec_binaural_functions_fx.c diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec_fx.c similarity index 100% rename from lib_rend/ivas_dirac_decorr_dec.c rename to lib_rend/ivas_dirac_decorr_dec_fx.c diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_rend/ivas_dirac_onsets_dec_fx.c similarity index 100% rename from lib_rend/ivas_dirac_onsets_dec.c rename to lib_rend/ivas_dirac_onsets_dec_fx.c diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c similarity index 100% rename from lib_rend/ivas_dirac_output_synthesis_dec.c rename to lib_rend/ivas_dirac_output_synthesis_dec_fx.c diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend_fx.c similarity index 100% rename from lib_rend/ivas_dirac_rend.c rename to lib_rend/ivas_dirac_rend_fx.c diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap_fx.c similarity index 100% rename from lib_rend/ivas_efap.c rename to lib_rend/ivas_efap_fx.c diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf_fx.c similarity index 100% rename from lib_rend/ivas_hrtf.c rename to lib_rend/ivas_hrtf_fx.c diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter_fx.c similarity index 100% rename from lib_rend/ivas_limiter.c rename to lib_rend/ivas_limiter_fx.c diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge_fx.c similarity index 100% rename from lib_rend/ivas_masa_merge.c rename to lib_rend/ivas_masa_merge_fx.c diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana_fx.c similarity index 100% rename from lib_rend/ivas_mcmasa_ana.c rename to lib_rend/ivas_mcmasa_ana_fx.c diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer_fx.c similarity index 100% rename from lib_rend/ivas_objectRenderer.c rename to lib_rend/ivas_objectRenderer_fx.c diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c similarity index 100% rename from lib_rend/ivas_objectRenderer_hrFilt.c rename to lib_rend/ivas_objectRenderer_hrFilt_fx.c diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix_fx.c similarity index 100% rename from lib_rend/ivas_objectRenderer_mix.c rename to lib_rend/ivas_objectRenderer_mix_fx.c diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c similarity index 100% rename from lib_rend/ivas_objectRenderer_sfx.c rename to lib_rend/ivas_objectRenderer_sfx_fx.c diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources_fx.c similarity index 100% rename from lib_rend/ivas_objectRenderer_sources.c rename to lib_rend/ivas_objectRenderer_sources_fx.c diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec_fx.c similarity index 100% rename from lib_rend/ivas_objectRenderer_vec.c rename to lib_rend/ivas_objectRenderer_vec_fx.c diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana_fx.c similarity index 100% rename from lib_rend/ivas_omasa_ana.c rename to lib_rend/ivas_omasa_ana_fx.c diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk_fx.c similarity index 100% rename from lib_rend/ivas_orient_trk.c rename to lib_rend/ivas_orient_trk_fx.c diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections_fx.c similarity index 100% rename from lib_rend/ivas_reflections.c rename to lib_rend/ivas_reflections_fx.c diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config_fx.c similarity index 100% rename from lib_rend/ivas_render_config.c rename to lib_rend/ivas_render_config_fx.c diff --git a/lib_rend/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line_fx.c similarity index 100% rename from lib_rend/ivas_reverb_delay_line.c rename to lib_rend/ivas_reverb_delay_line_fx.c diff --git a/lib_rend/ivas_reverb_fft_filter.c b/lib_rend/ivas_reverb_fft_filter_fx.c similarity index 100% rename from lib_rend/ivas_reverb_fft_filter.c rename to lib_rend/ivas_reverb_fft_filter_fx.c diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design_fx.c similarity index 100% rename from lib_rend/ivas_reverb_filter_design.c rename to lib_rend/ivas_reverb_filter_design_fx.c diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb_fx.c similarity index 100% rename from lib_rend/ivas_reverb.c rename to lib_rend/ivas_reverb_fx.c diff --git a/lib_rend/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter_fx.c similarity index 100% rename from lib_rend/ivas_reverb_iir_filter.c rename to lib_rend/ivas_reverb_iir_filter_fx.c diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils_fx.c similarity index 100% rename from lib_rend/ivas_reverb_utils.c rename to lib_rend/ivas_reverb_utils_fx.c diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer_fx.c similarity index 100% rename from lib_rend/ivas_rom_TdBinauralRenderer.c rename to lib_rend/ivas_rom_TdBinauralRenderer_fx.c diff --git a/lib_rend/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer_fx.c similarity index 100% rename from lib_rend/ivas_rom_binauralRenderer.c rename to lib_rend/ivas_rom_binauralRenderer_fx.c diff --git a/lib_rend/ivas_rom_binaural_crend_head.c b/lib_rend/ivas_rom_binaural_crend_head_fx.c similarity index 100% rename from lib_rend/ivas_rom_binaural_crend_head.c rename to lib_rend/ivas_rom_binaural_crend_head_fx.c diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend_fx.c similarity index 100% rename from lib_rend/ivas_rom_rend.c rename to lib_rend/ivas_rom_rend_fx.c diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation_fx.c similarity index 100% rename from lib_rend/ivas_rotation.c rename to lib_rend/ivas_rotation_fx.c diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering_fx.c similarity index 100% rename from lib_rend/ivas_sba_rendering.c rename to lib_rend/ivas_sba_rendering_fx.c diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox_fx.c similarity index 100% rename from lib_rend/ivas_shoebox.c rename to lib_rend/ivas_shoebox_fx.c diff --git a/lib_rend/ivas_td_decorr.c b/lib_rend/ivas_td_decorr_fx.c similarity index 100% rename from lib_rend/ivas_td_decorr.c rename to lib_rend/ivas_td_decorr_fx.c diff --git a/lib_rend/ivas_vbap.c b/lib_rend/ivas_vbap_fx.c similarity index 100% rename from lib_rend/ivas_vbap.c rename to lib_rend/ivas_vbap_fx.c -- GitLab From f3a52497e1298d393cf5d34fb298caf9534183a2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 11:51:18 +0530 Subject: [PATCH 0306/1221] Fix for 3GPP issue 1313: Multi-frame attenuation for MDCT-stereo 48kbps with input +10dB Link #1313 --- lib_enc/ivas_mc_param_enc_fx.c | 10 +++--- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 8 ++--- lib_enc/stat_enc.h | 4 +-- lib_enc/transient_detection_fx.c | 48 ++++++++++---------------- 4 files changed, 30 insertions(+), 40 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 859ce3a9b..36324ae0f 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1639,8 +1639,8 @@ static void ivas_param_mc_transient_detection_fx( push_wmops( "param_mc_trn_det" ); attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold; - pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay]; // Q0 - pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q0 + pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay]; // Q(-1) + pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q(-1) bIsAttackPresent = FALSE; move16(); @@ -1651,8 +1651,8 @@ static void ivas_param_mc_transient_detection_fx( * if we had an attack very late in the last frame, * make the current frame also a transient one... */ test(); - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 31, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) || - EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 31, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) ) + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) || + EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ) { bIsAttackPresent = TRUE; move16(); @@ -1661,7 +1661,7 @@ static void ivas_param_mc_transient_detection_fx( } FOR( i = 0; i < NSUBBLOCKS; i++ ){ - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 31, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) ){ + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 32, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ){ bIsAttackPresent = TRUE; move16(); attackIndex = i; diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index b43c8dfdb..2a87ea4f9 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -53,13 +53,13 @@ static void sync_tcx_mode_fx( Encoder_State **st /* i/o: Encoder state */ ) { - const Word32 prevAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[st[0]->hTranDet->subblockEnergies.nDelay]; /* Q0 */ + const Word32 prevAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[st[0]->hTranDet->subblockEnergies.nDelay]; /* Q(-1) */ move32(); - const Word32 prevAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[st[1]->hTranDet->subblockEnergies.nDelay]; /* Q0 */ + const Word32 prevAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[st[1]->hTranDet->subblockEnergies.nDelay]; /* Q(-1) */ move32(); - const Word32 lastAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[( st[0]->hTranDet->subblockEnergies.nDelay + st[0]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q0 */ + const Word32 lastAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[( st[0]->hTranDet->subblockEnergies.nDelay + st[0]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q(-1) */ move32(); - const Word32 lastAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[( st[1]->hTranDet->subblockEnergies.nDelay + st[1]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q0 */ + const Word32 lastAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[( st[1]->hTranDet->subblockEnergies.nDelay + st[1]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q(-1) */ move32(); test(); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 5067cb410..6292c4b33 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -138,8 +138,8 @@ typedef struct typedef struct { DelayBuffer *pDelayBuffer; /* Delay buffer. */ - Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q0 - Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q0 + Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) + Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ /* IVAS: Q3 */ int16_t nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ int16_t nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index d9859a1a1..82d24ceba 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -726,7 +726,7 @@ void RunTransientDetection_ivas_fx( e0_fx = dotp_fx( filteredInput_fx + /* length / 2 */ shr( length, 1 ), filteredInput_fx + /* length / 2 */ shr( length, 1 ), shr( pSubblockEnergies->pDelayBuffer->nSubblockSize, 1 ) /* pSubblockEnergies->pDelayBuffer->nSubblockSize / 2 */, &exp ); exp = sub( exp, 2 * 0 - 1 ); // Q = 2*0 + (30-exp), E = 31 - (2*0 + 30 - exp) = 1 + exp - 2*0 = exp - (2*0-1) e0_fx = BASOP_Util_Add_Mant32Exp( MIN_BLOCK_ENERGY_IVAS_FX_Q7 / 2, 31 - Q7, e0_fx, exp, &exp ); - e1_fx = BASOP_Util_Add_Mant32Exp( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], 31 - 0, L_negate( e0_fx ), exp, &exp1 ); + e1_fx = BASOP_Util_Add_Mant32Exp( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], 32, L_negate( e0_fx ), exp, &exp1 ); IF( BASOP_Util_Cmp_Mant32Exp( e1_fx, exp1, e0_fx, exp ) > 0 ) { pSubblockEnergies->ramp_up_flag = (UWord16) L_or( pSubblockEnergies->ramp_up_flag, 0x0001 ); @@ -1122,8 +1122,8 @@ static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, De assert( ( pDelayBuffer != NULL ) && ( pSubblockEnergies != NULL ) && ( pDelayBuffer->nSubblockSize * NSUBBLOCKS == nFrameLength ) && ( pDelayBuffer->nSubblockSize > 0 ) ); - set32_fx( pSubblockEnergies->subblockNrg, 107 /* 107.37 in Q0 */, nMaxBuffSize ); - set32_fx( pSubblockEnergies->accSubblockNrg, 107 /* 107.37 in Q0 */, nMaxBuffSize + 1 ); + set32_fx( pSubblockEnergies->subblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize ); + set32_fx( pSubblockEnergies->accSubblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize + 1 ); set16_fx( pSubblockEnergies->subblockNrgChange, ONE_IN_Q3, nMaxBuffSize ); IF( nDelay != 0 ) { @@ -1495,9 +1495,9 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp Word16 *pSubblockNrgChange; Word32 *pAccSubblockTmp; Word16 nWindows; - Word16 w, k, k2, tmp; + Word16 w, k, k2; Word32 w0, w1; - Word32 accu; + Word64 accu; move16(); pDelayBuffer = pSubblockEnergies->pDelayBuffer; @@ -1522,45 +1522,35 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp IF( nWindows > 0 ) { /* Process left over samples from the previous frame. */ - accu = 107; // 107.37f in Q0 - move32(); - assert( ( SUBBLOCK_NRG_E & 1 ) == 0 ); + accu = 215; // 107.37f in Q1 + move64(); FOR( k = 0; k < nPartialDelay; k++ ) { - tmp = delayBuffer[k]; // Q0 - move16(); - accu = L_mac0( accu, tmp, tmp ); // Q0 + accu = W_mac_16_16( accu, delayBuffer[k], delayBuffer[k] ); // Q1 } /* Process new samples in the 0. subblock. */ - w = sub( nSubblockSize, nPartialDelay ); - assert( ( SUBBLOCK_NRG_E & 1 ) == 0 ); - FOR( k = 0; k < w; k++ ) + FOR( k = 0; k < ( nSubblockSize - nPartialDelay ); k++ ) { - tmp = input[k]; // Q0 - move16(); - accu = L_mac0_sat( accu, tmp, tmp ); // Q0 + accu = W_mac_16_16( accu, input[k], input[k] ); // Q1 } - pSubblockNrg[0] = accu; // Q0 + pSubblockNrg[0] = W_shl_sat_l( accu, -2 ); // Q(-1) move32(); /* Set accumulated subblock energy at this point. */ UpdatedAndStoreAccWindowNrg( pSubblockNrg[0], pAccSubblockTmp, facAccSubblockNrg, &pAccSubblockNrg[0] ); FOR( w = 1; w < nWindows; w++ ) { - accu = 107; // 107.37f in Q0 - move32(); + accu = 215; // 107.37f in Q1 + move64(); /* Process new samples in the w. subblock. */ k2 = add( k, nSubblockSize ); - assert( ( SUBBLOCK_NRG_E & 1 ) == 0 ); FOR( ; k < k2; k++ ) { - tmp = input[k]; // Q0 - move16(); - accu = L_mac0_sat( accu, tmp, tmp ); // Q0 + accu = W_mac_16_16( accu, input[k], input[k] ); // Q1 } - pSubblockNrg[w] = accu; // Q0 + pSubblockNrg[w] = W_shl_sat_l( accu, -2 ); // Q(-1) move32(); /* Set accumulated subblock energy at this point. */ UpdatedAndStoreAccWindowNrg( pSubblockNrg[w], pAccSubblockTmp, facAccSubblockNrg, &pAccSubblockNrg[w] ); @@ -1743,7 +1733,7 @@ Word16 transient_analysis_ivas_fx( /* Forward attack analysis */ FOR( i = -2; i < 7; i++ ) { - IF( BASOP_Util_Cmp_Mant32Exp( hTranDet->subblockEnergies.subblockNrg[nRelativeDelay + i], 31, Mpy_32_16_1( hTranDet->subblockEnergies.accSubblockNrg[nRelativeDelay + i], thr_fwd_fx ), ( 31 + 4 ) ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( hTranDet->subblockEnergies.subblockNrg[nRelativeDelay + i], 32, Mpy_32_16_1( hTranDet->subblockEnergies.accSubblockNrg[nRelativeDelay + i], thr_fwd_fx ), ( 32 + 4 ) ) > 0 ) { prel_force_td = s_or( prel_force_td, 0x0001 ); } @@ -1780,7 +1770,7 @@ Word16 transient_analysis_ivas_fx( /* -3 check */ test(); - IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[1 + offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[1], thr_rev_fx ), ( 31 + 4 ) ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[1 + offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[1], thr_rev_fx ), ( 32 + 4 ) ) > 0 ) { prel_force_td = s_or( prel_force_td, 0x0002 ); move16(); @@ -1788,10 +1778,10 @@ Word16 transient_analysis_ivas_fx( /* -4 check */ test(); - IF( prel_force_td == 0 && BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[0], thr_rev_fx ), ( 31 + 4 ) ) > 0 ) + IF( prel_force_td == 0 && BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[0], thr_rev_fx ), ( 32 + 4 ) ) > 0 ) { - IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[0], add( thr_rev_fx, THR_LOW_STEP_FX ) ), ( 31 + 4 ) ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[0], add( thr_rev_fx, THR_LOW_STEP_FX ) ), ( 32 + 4 ) ) > 0 ) { prel_force_td = s_or( prel_force_td, 0x0004 ); } -- GitLab From 47fe3fc529be651d476e21441652186b54d0299e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 12:31:16 +0530 Subject: [PATCH 0307/1221] Speech buffer scaling fix and scaling fix in ivas_core_enc --- lib_com/ivas_prot_fx.h | 3 +- lib_com/prot.h | 1 + lib_enc/core_enc_init_fx.c | 47 +++++++++++++++++---------- lib_enc/ext_sig_ana_fx.c | 11 ++++--- lib_enc/ivas_core_enc_fx.c | 14 ++++---- lib_enc/ivas_core_pre_proc_front_fx.c | 4 +-- lib_enc/ivas_core_pre_proc_fx.c | 40 ++++++++++++----------- lib_enc/stat_enc.h | 20 ++++++------ 8 files changed, 78 insertions(+), 62 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 80bdda3c2..b581dfa7e 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -5857,8 +5857,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame */ Word16 Q_old_inp_16k, Word16 Q_r[2], - Word16 *Q_new, - Word16 downscale_buf_speech_enc_pe ); + Word16 *Q_new); ivas_error ivas_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 16f4659a0..f5d69075e 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -761,6 +761,7 @@ void preemph_ivas_fx( const Word16 L, /* i : vector size Q0*/ Word32 *mem /* i/o: memory (x[-1]) Qx*/ ); + void cb_shape( const int16_t preemphFlag, /* i : flag for pre-emphasis */ const int16_t pitchFlag, /* i : flag for pitch sharpening */ diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 4151725af..c2b1c22e1 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -3,8 +3,8 @@ ====================================================================================*/ #include -//#include "prot_fx.h" -//#include "basop_mpy.h" +// #include "prot_fx.h" +// #include "basop_mpy.h" #include "options.h" #include "cnst.h" #include "stl.h" @@ -1375,6 +1375,7 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol } // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( 0, sub( st->exp_old_wsp, st->exp_buf_wspeech_enc ) ) ); Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); st->exp_buf_wspeech_enc = st->exp_old_wsp; move16(); @@ -1384,25 +1385,36 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol test(); IF( EQ_16( st->L_frame, L_FRAME ) && !st->tcxonly ) { - // Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - Copy( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); - /* SCaling to common exponent*/ - Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_12k8, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) - Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) - Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); // Q(15-max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe )) - st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ); - move16(); + if ( st->exp_buf_speech_enc_pe >= st->exp_old_inp_12k8 ) + { + Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ); // Scaling to common Q + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + } + else + { + Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( st->exp_buf_speech_enc_pe, st->exp_old_inp_12k8 ) ); // Scaling to common Q + Copy( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); + st->exp_buf_speech_enc_pe = st->exp_old_inp_12k8; + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + move16(); + } } ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) && !st->tcxonly ) { lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); - Copy( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); - /* SCaling to common exponent*/ - Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_16k, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ); - move16(); + if ( st->exp_buf_speech_enc_pe >= st->exp_old_inp_16k ) + { + Copy_Scale_sig( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ); // Scaling to common Q + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + } + else + { + Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( st->exp_buf_speech_enc_pe, st->exp_old_inp_16k ) ); // Scaling to common Q + Copy( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); + st->exp_buf_speech_enc_pe = st->exp_old_inp_16k; + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + move16(); + } } st->mem_preemph_enc = st->buf_speech_enc[st->encoderPastSamples_enc + st->encoderLookahead_enc - 1]; @@ -1416,6 +1428,7 @@ static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_ol ELSE IF( !st->tcxonly && GE_32( last_total_brate, ACELP_32k ) ) { + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( 0, sub( st->exp_old_wsp, st->exp_buf_wspeech_enc ) ) ); Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); st->exp_buf_wspeech_enc = st->exp_old_wsp; diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index c437be5be..732c1ba11 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -710,8 +710,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( test(); IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy( new_samples, st->new_speech_enc, L_frame ); /* Q0 */ - Scale_sig( st->new_speech_enc, L_frame, 1 ); // Q1 + Copy_Scale_sig(new_samples, st->new_speech_enc, L_frame, sub( 15, st->exp_buf_speech_enc)); + /* st->new_speech_enc copied from new_samples in Q st->exp_buf_speech_enc + This is considering new_samples is in q 0 in current code*/ } /*--------------------------------------------------------------* @@ -747,10 +748,10 @@ void core_signal_analysis_high_bitrate_ivas_fx( test(); IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); + Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); //Assuming both exp_buf_speech_enc_pe and exp_buf_speech_enc are same + + PREEMPH_FX(st->new_speech_enc_pe, st->preemph_fac, L_frame, &(st->mem_preemph_enc)); //using this to keep values alligned in Q-1 - Preemph_scaled( st->new_speech_enc_pe, Q_new, &( st->mem_preemph_enc ), - st->Q_max_enc, st->preemph_fac, 1, 0, 2, L_frame, st->coder_type_raw, 1 ); } /* Rescale Memory */ diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 6dc3d10ec..303adecfd 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -734,8 +734,8 @@ ivas_error ivas_core_enc_fx( Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, shift ); // st->Q_old_wtda } - Word16 q_new_swb_speech_buffer = getScaleFactor16( new_swb_speech_buffer_fx_16, input_frame ); - Scale_sig( new_swb_speech_buffer_fx_16, input_frame, q_new_swb_speech_buffer ); // Q0->q_new_swb_speech_buffer + Word16 q_new_swb_speech_buffer = getScaleFactor16( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX ); + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // Q0->q_new_swb_speech_buffer /* SWB TBE encoder */ test(); @@ -759,11 +759,11 @@ ivas_error ivas_core_enc_fx( } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) ) { - Copy_Scale_sig_32_16( shb_speech_fx32, shb_speech_fx, L_FRAME16k, -Q16 ); // Q_shb_spch - 16 - Scale_sig( new_swb_speech_fx_16, input_frame, negate( q_new_swb_speech_buffer ) ); // Q0 + Copy_Scale_sig_32_16( shb_speech_fx32, shb_speech_fx, L_FRAME16k, -Q16 ); // Q_shb_spch - 16 + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, negate( q_new_swb_speech_buffer ) ); // q_new_swb_speech_buffer -> Q0 /* SWB(FB) BWE encoder */ swb_bwe_enc_ivas_fx( st, last_element_mode, old_inp_12k8_fx[n], old_inp_16k_fx[n], old_syn_12k8_16k_fx[n], new_swb_speech_fx_16, shb_speech_fx, sub( Q_shb_spch, Q16 ), sub( Q_new[n], 1 ) ); - Scale_sig( new_swb_speech_fx_16, input_frame, q_new_swb_speech_buffer ); // q_new_swb_speech_buffer + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // Q0 -> q_new_swb_speech_buffer } Scale_sig( old_syn_12k8_16k_fx[n], L_FRAME16k, sub( Q1, Q_new[n] ) ); // Q0 @@ -793,8 +793,8 @@ ivas_error ivas_core_enc_fx( stereo_icBWE_preproc_fx( hCPE, input_frame, new_swb_speech_buffer_fx_16 /*tmp buffer*/, q_new_swb_speech_buffer ); q_new_swb_speech_buffer = add( q_new_swb_speech_buffer, 16 ); - Copy_Scale_sig_16_32_no_sat( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, input_frame, Q16 ); // q_new_swb_speech_buffer - Copy_Scale_sig_16_32_no_sat( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 + Copy_Scale_sig_16_32_no_sat( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, L_FRAME48k + STEREO_DFT_OVL_MAX, Q16 ); // q_new_swb_speech_buffer - 16 - > q_new_swb_speech_buffer + Copy_Scale_sig_16_32_no_sat( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 stereo_icBWE_enc_ivas_fx( hCPE, shb_speech_fx32, sub( Q31, Q_shb_spch ), new_swb_speech_buffer_fx, sub( Q31, q_new_swb_speech_buffer ), voice_factors_fx32[0] ); diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 7bb67cbbd..04e518e99 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -725,7 +725,7 @@ ivas_error pre_proc_front_ivas_fx( shift = sub( norm_s( inp_max ), headroom ); Word16 Q_min; - shift = s_max( shift, -1 ); + shift = s_max( shift, 0 ); shift = s_min( shift, Q_MAX ); minimum_fx( st->Q_max, L_Q_MEM, &Q_min ); *Q_new = s_min( shift, Q_min ); @@ -1702,7 +1702,7 @@ ivas_error pre_proc_front_ivas_fx( error = ivas_compute_core_buffers_fx( st, NULL, old_inp_16k_fx, NULL, input_frame, IVAS_SCE /*last_element_mode*/, INT_FS_16k /*sr_core_tmp*/, ener_fx, A_fx, Aw_fx, epsP_fx, - lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new, 1 ); + lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new); IF( NE_32( error, IVAS_ERR_OK ) ) { return error; diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 718a09026..f4712a771 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -579,14 +579,28 @@ ivas_error pre_proc_ivas_fx( move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); - Word16 Q_old_inp_128k = *Q_new; + Word16 Q_inp_12k8 = *Q_new; + move16(); + Word16 Q_inp_16k = *Q_new; move16(); IF( !flag_16k_smc ) { error = ivas_compute_core_buffers_fx( st, &inp_16k_fx, old_inp_16k_fx, new_inp_resamp16k_fx, input_frame, last_element_mode, sr_core_tmp, ener_fx, A_fx, Aw_fx, epsP_fx, - lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new, 0 ); + lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, &Q_inp_16k); + IF (GT_16(Q_inp_16k, Q_inp_12k8)) + { + Scale_sig(old_inp_16k_fx, L_INP, sub(Q_inp_12k8, Q_inp_16k)); + *Q_new = Q_inp_12k8; + } + ELSE + { + Scale_sig(old_inp_12k8_fx, L_INP_12k8, sub(Q_inp_16k, Q_inp_12k8)); + *Q_new = Q_inp_16k; + } + move16(); + IF( error != IVAS_ERR_OK ) { return error; @@ -628,7 +642,7 @@ ivas_error pre_proc_ivas_fx( IF( flag_16k_smc ) { - Copy( st->buf_speech_enc + L_FRAME16k, new_inp_resamp16k_fx, L_FRAME16k ); /* Q_new - 1 */ + Copy( st->buf_speech_enc + L_FRAME16k, new_inp_resamp16k_fx, L_FRAME16k ); /* Q_old_inp_16k */ } /*-----------------------------------------------------------------* @@ -643,14 +657,11 @@ ivas_error pre_proc_ivas_fx( /* set the pointer of the current frame for the ACELP core */ IF( EQ_16( st->L_frame, L_FRAME ) ) { - *inp_fx = inp_12k8_fx; /* Q_old_inp_128k */ - *Q_new = Q_old_inp_128k; - move16(); + *inp_fx = inp_12k8_fx; /* Q_old_inp_12k8 */ } ELSE { *inp_fx = inp_16k_fx; - Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( *Q_new, Q_old_inp_128k ) ); } /* Update VAD hangover frame counter in active frames */ @@ -703,9 +714,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ Word16 Q_old_inp_16k, Word16 Q_r[2], - Word16 *Q_new, - Word16 downscale_buf_speech_enc_pe /* Q0 */ -) + Word16 *Q_new) { Word16 *inp_16k_fx, *new_inp_16k_fx; Word16 delay, element_mode; @@ -1103,14 +1112,7 @@ ivas_error ivas_compute_core_buffers_fx( { /* update signal buffers */ Word16 shift; - IF( downscale_buf_speech_enc_pe ) - { - shift = negate( *Q_new ); - } - ELSE - { - shift = 0; - } + shift = negate(*Q_new); move16(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { @@ -1148,7 +1150,7 @@ ivas_error ivas_compute_core_buffers_fx( /*--------------------------------------------------------------* * Compute Weighted Input *---------------------------------------------------------------*/ - + ivas_find_wsp_fx( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A_fx, Aw_fx, st->speech_enc_pe, PREEMPH_FAC_16k, st->wspeech_enc, &st->mem_wsp_enc, st->gamma, L_LOOK_16k ); } diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 6292c4b33..12cf078cf 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -113,9 +113,9 @@ typedef struct signal_buffers_enc_data_structure Word16 old_inp_12k8_fx[L_INP_MEM]; /* memory of input signal at 12.8kHz */ Word16 old_inp_16k_fx[L_INP_MEM]; /* ACELP@16kHz - memory of input signal @16 kHz */ - Word16 buf_speech_enc_pe[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; + Word16 buf_speech_enc_pe[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; // exp_buf_speech_enc_pe Word16 buf_synth[OLD_SYNTH_SIZE_ENC + L_FRAME32k]; - Word16 buf_speech_enc[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; + Word16 buf_speech_enc[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; //exp_buf_speech_enc Word16 buf_wspeech_enc[L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320]; /*normally there is a lookahead for 12k8 and 16k but L_FRAME_MAX=L_FRAME_16K+L_NEXT_16k*/ /* increased by 320 to avoid memory overlap in ivas_find_wsp() and also to accomodate for the wspeech_enc */ } SIGNAL_BUFFERS_ENC_DATA, *SIGNAL_BUFFERS_ENC_HANDLE; @@ -1463,10 +1463,10 @@ typedef struct enc_core_structure Word16 *old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ Word16 *old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ - Word16 *buf_speech_enc_pe; + Word16 *buf_speech_enc_pe; // exp_buf_speech_enc_pe Word16 *buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ - Word16 *buf_speech_enc; - Word16 *buf_wspeech_enc; + Word16 *buf_speech_enc; //exp_buf_speech_enc + Word16 *buf_wspeech_enc; //exp_buf_wspeech_enc Word16 exp_buf_speech_enc_pe; Word16 exp_buf_speech_enc; @@ -1640,11 +1640,11 @@ typedef struct enc_core_structure Word16 exp_mem_preemph_enc; /* speech preemph filter memory (at encoder-sampling-rate) */ /* Signal Buffers and Pointers at encoder-sampling-rate */ - Word16 *speech_enc; - Word16 *speech_enc_pe; - Word16 *new_speech_enc; - Word16 *new_speech_enc_pe; - Word16 *wspeech_enc; + Word16 *speech_enc; //exp_buf_speech_enc + Word16 *speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *new_speech_enc; //exp_buf_speech_enc + Word16 *new_speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *wspeech_enc; //exp_buf_wspeech_enc Word16 *synth; int16_t enableTcxLpc; /* global toggle for the TCX LPC quantizer */ -- GitLab From 42806254d09551b20f527354a61fff694d80d9a9 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 12:33:58 +0530 Subject: [PATCH 0308/1221] Clang formatting changes --- lib_com/ivas_prot_fx.h | 2 +- lib_enc/ext_sig_ana_fx.c | 11 +++++------ lib_enc/ivas_core_pre_proc_front_fx.c | 2 +- lib_enc/ivas_core_pre_proc_fx.c | 20 ++++++++++---------- lib_enc/stat_enc.h | 22 +++++++++++----------- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index b581dfa7e..a61d6228d 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -5857,7 +5857,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame */ Word16 Q_old_inp_16k, Word16 Q_r[2], - Word16 *Q_new); + Word16 *Q_new ); ivas_error ivas_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 732c1ba11..9e6318591 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -710,9 +710,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( test(); IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy_Scale_sig(new_samples, st->new_speech_enc, L_frame, sub( 15, st->exp_buf_speech_enc)); - /* st->new_speech_enc copied from new_samples in Q st->exp_buf_speech_enc - This is considering new_samples is in q 0 in current code*/ + Copy_Scale_sig( new_samples, st->new_speech_enc, L_frame, sub( 15, st->exp_buf_speech_enc ) ); + /* st->new_speech_enc copied from new_samples in Q st->exp_buf_speech_enc + This is considering new_samples is in q 0 in current code*/ } /*--------------------------------------------------------------* @@ -748,10 +748,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( test(); IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); //Assuming both exp_buf_speech_enc_pe and exp_buf_speech_enc are same - - PREEMPH_FX(st->new_speech_enc_pe, st->preemph_fac, L_frame, &(st->mem_preemph_enc)); //using this to keep values alligned in Q-1 + Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); // Assuming both exp_buf_speech_enc_pe and exp_buf_speech_enc are same + PREEMPH_FX( st->new_speech_enc_pe, st->preemph_fac, L_frame, &( st->mem_preemph_enc ) ); // using this to keep values alligned in Q-1 } /* Rescale Memory */ diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 04e518e99..f963b55a4 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1702,7 +1702,7 @@ ivas_error pre_proc_front_ivas_fx( error = ivas_compute_core_buffers_fx( st, NULL, old_inp_16k_fx, NULL, input_frame, IVAS_SCE /*last_element_mode*/, INT_FS_16k /*sr_core_tmp*/, ener_fx, A_fx, Aw_fx, epsP_fx, - lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new); + lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new ); IF( NE_32( error, IVAS_ERR_OK ) ) { return error; diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index f4712a771..1234a6876 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -588,19 +588,19 @@ ivas_error pre_proc_ivas_fx( error = ivas_compute_core_buffers_fx( st, &inp_16k_fx, old_inp_16k_fx, new_inp_resamp16k_fx, input_frame, last_element_mode, sr_core_tmp, ener_fx, A_fx, Aw_fx, epsP_fx, - lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, &Q_inp_16k); - IF (GT_16(Q_inp_16k, Q_inp_12k8)) + lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, &Q_inp_16k ); + IF( GT_16( Q_inp_16k, Q_inp_12k8 ) ) { - Scale_sig(old_inp_16k_fx, L_INP, sub(Q_inp_12k8, Q_inp_16k)); - *Q_new = Q_inp_12k8; + Scale_sig( old_inp_16k_fx, L_INP, sub( Q_inp_12k8, Q_inp_16k ) ); + *Q_new = Q_inp_12k8; } ELSE { - Scale_sig(old_inp_12k8_fx, L_INP_12k8, sub(Q_inp_16k, Q_inp_12k8)); - *Q_new = Q_inp_16k; + Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( Q_inp_16k, Q_inp_12k8 ) ); + *Q_new = Q_inp_16k; } move16(); - + IF( error != IVAS_ERR_OK ) { return error; @@ -714,7 +714,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ Word16 Q_old_inp_16k, Word16 Q_r[2], - Word16 *Q_new) + Word16 *Q_new ) { Word16 *inp_16k_fx, *new_inp_16k_fx; Word16 delay, element_mode; @@ -1112,7 +1112,7 @@ ivas_error ivas_compute_core_buffers_fx( { /* update signal buffers */ Word16 shift; - shift = negate(*Q_new); + shift = negate( *Q_new ); move16(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { @@ -1150,7 +1150,7 @@ ivas_error ivas_compute_core_buffers_fx( /*--------------------------------------------------------------* * Compute Weighted Input *---------------------------------------------------------------*/ - + ivas_find_wsp_fx( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A_fx, Aw_fx, st->speech_enc_pe, PREEMPH_FAC_16k, st->wspeech_enc, &st->mem_wsp_enc, st->gamma, L_LOOK_16k ); } diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 12cf078cf..d9f71128d 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -113,9 +113,9 @@ typedef struct signal_buffers_enc_data_structure Word16 old_inp_12k8_fx[L_INP_MEM]; /* memory of input signal at 12.8kHz */ Word16 old_inp_16k_fx[L_INP_MEM]; /* ACELP@16kHz - memory of input signal @16 kHz */ - Word16 buf_speech_enc_pe[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; // exp_buf_speech_enc_pe + Word16 buf_speech_enc_pe[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; // exp_buf_speech_enc_pe Word16 buf_synth[OLD_SYNTH_SIZE_ENC + L_FRAME32k]; - Word16 buf_speech_enc[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; //exp_buf_speech_enc + Word16 buf_speech_enc[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; // exp_buf_speech_enc Word16 buf_wspeech_enc[L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320]; /*normally there is a lookahead for 12k8 and 16k but L_FRAME_MAX=L_FRAME_16K+L_NEXT_16k*/ /* increased by 320 to avoid memory overlap in ivas_find_wsp() and also to accomodate for the wspeech_enc */ } SIGNAL_BUFFERS_ENC_DATA, *SIGNAL_BUFFERS_ENC_HANDLE; @@ -1463,10 +1463,10 @@ typedef struct enc_core_structure Word16 *old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ Word16 *old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ - Word16 *buf_speech_enc_pe; // exp_buf_speech_enc_pe - Word16 *buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ - Word16 *buf_speech_enc; //exp_buf_speech_enc - Word16 *buf_wspeech_enc; //exp_buf_wspeech_enc + Word16 *buf_speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ + Word16 *buf_speech_enc; // exp_buf_speech_enc + Word16 *buf_wspeech_enc; // exp_buf_wspeech_enc Word16 exp_buf_speech_enc_pe; Word16 exp_buf_speech_enc; @@ -1640,11 +1640,11 @@ typedef struct enc_core_structure Word16 exp_mem_preemph_enc; /* speech preemph filter memory (at encoder-sampling-rate) */ /* Signal Buffers and Pointers at encoder-sampling-rate */ - Word16 *speech_enc; //exp_buf_speech_enc - Word16 *speech_enc_pe; // exp_buf_speech_enc_pe - Word16 *new_speech_enc; //exp_buf_speech_enc - Word16 *new_speech_enc_pe; // exp_buf_speech_enc_pe - Word16 *wspeech_enc; //exp_buf_wspeech_enc + Word16 *speech_enc; // exp_buf_speech_enc + Word16 *speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *new_speech_enc; // exp_buf_speech_enc + Word16 *new_speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *wspeech_enc; // exp_buf_wspeech_enc Word16 *synth; int16_t enableTcxLpc; /* global toggle for the TCX LPC quantizer */ -- GitLab From 9002a018c57848060404d8e92908c9dacfce05a8 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 09:17:58 +0100 Subject: [PATCH 0309/1221] remove unused switches --- lib_com/ivas_ism_com_fx.c | 1 - lib_com/ivas_prot.h | 1 - lib_com/options.h | 1 - lib_enc/ivas_ism_dtx_enc_fx.c | 1 - lib_enc/ivas_ism_metadata_enc_fx.c | 3 +-- lib_rend/lib_rend.c | 10 +++------- 6 files changed, 4 insertions(+), 13 deletions(-) diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index 74e9641aa..d3f18a795 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -43,7 +43,6 @@ #include "ivas_prot_fx.h" #include "prot_fx.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /*-----------------------------------------------------------------------* * Local constants diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 2493add28..34f11c01f 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -45,7 +45,6 @@ #include "ivas_stat_com.h" #include "ivas_error_utils.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /* clang-format off */ diff --git a/lib_com/options.h b/lib_com/options.h index d3570004d..7d65c5eac 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -70,7 +70,6 @@ #define IVAS_FLOAT_FIXED #define IVAS_FLOAT_FIXED_CONVERSIONS /* Temporary macro to keep track of intermediate flt to fixed and fixed to flt conversions */ #define MSAN_FIX -#define ISM_DISABLE #define FIX_TMP_714 #define BASOP_NOGLOB_TMP_715 #define EVS_FUNC_MODIFIED diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 3439baff1..615660761 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -40,7 +40,6 @@ #include "prot_fx.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /*-----------------------------------------------------------------------* diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index d78281ff4..a5a1286a2 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -44,8 +44,7 @@ #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED -#include "ivas_rom_com_fx.h" + /*-----------------------------------------------------------------------* * Local constants diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a1c551405..698c652e5 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -33,24 +33,20 @@ #include "options.h" #include "lib_rend.h" #include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_rom_com_fx.h" #include "ivas_rom_rend.h" #include #include #include #include "wmc_auto.h" -#include "ivas_rom_com_fx.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "debug.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED + /*-------------------------------------------------------------------* * Local constants *-------------------------------------------------------------------*/ -- GitLab From 65bee438bed413351f4b84df7a3fcdb6f76bbce0 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 10:12:57 +0100 Subject: [PATCH 0310/1221] review and remove ADD_LRTD --- lib_com/est_tilt_fx.c | 35 +- lib_com/gs_bitallocation_fx.c | 925 ++++++++--------------------- lib_com/gs_bitallocation_ivas_fx.c | 144 ++--- lib_com/gs_noisefill_fx.c | 108 +--- lib_com/gs_preech_fx.c | 7 +- lib_com/options.h | 3 - lib_com/prot_fx.h | 91 ++- lib_com/syn_filt_fx.c | 18 - lib_dec/acelp_core_dec_fx.c | 123 +--- lib_dec/acelp_core_dec_ivas_fx.c | 8 +- lib_dec/core_switching_dec_fx.c | 4 - lib_dec/dec_amr_wb_fx.c | 8 +- lib_dec/dec_pit_exc_fx.c | 76 +-- lib_dec/evs_dec_fx.c | 9 +- lib_dec/gs_dec_fx.c | 335 ++--------- lib_dec/inov_dec_fx.c | 4 +- lib_dec/lsf_dec_fx.c | 5 - lib_dec/pit_dec_fx.c | 56 -- lib_dec/stat_dec.h | 37 +- lib_enc/acelp_core_enc_fx.c | 113 +--- lib_enc/cng_enc_fx.c | 4 - lib_enc/enc_pit_exc_fx.c | 5 +- lib_enc/enc_uv_fx.c | 3 +- lib_enc/evs_enc_fx.c | 7 +- lib_enc/gain_enc_fx.c | 14 - lib_enc/gs_enc_fx.c | 37 +- lib_enc/init_enc_fx.c | 5 +- lib_enc/lib_enc.c | 3 - lib_enc/lsf_enc_fx.c | 289 +++------ lib_enc/pit_enc_fx.c | 42 -- lib_enc/prot_fx_enc.h | 21 +- 31 files changed, 567 insertions(+), 1972 deletions(-) diff --git a/lib_com/est_tilt_fx.c b/lib_com/est_tilt_fx.c index 138b8c1bc..4ff9c6c11 100644 --- a/lib_com/est_tilt_fx.c +++ b/lib_com/est_tilt_fx.c @@ -40,18 +40,12 @@ Word16 est_tilt_fx( /* o : tilt of the code const Word32 gain_code, /* i : algebraic code gain Q16 */ Word16 *voice_fac, /* o : voicing factor Q15 */ const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#ifdef ADD_LRTD - , - const Word16 L_subfr /* i : Sub frame length */ -#endif ) { Word16 i, tmp, exp, ener1, exp1, ener2, exp2; Word32 L_tmp; Word16 tilt_code; -#ifdef ADD_LRTD - PMT( "FIX POINT NEED to be adapted for 16 kHz frame length " ) -#endif + ener1 = extract_h( Dot_product12( exc, exc, L_SUBFR, &exp1 ) ); exp1 = sub( exp1, add( Q_exc, Q_exc ) ); L_tmp = L_mult( gain_pit, gain_pit ); /* energy of pitch excitation */ @@ -117,26 +111,23 @@ Word16 est_tilt_fx( /* o : tilt of the code /* RETURN ARGUMENTS : */ /* _ (Word16) tolt_code : tilt of the code Q15 */ /*=======================================================================*/ -Word16 est_tilt_ivas_fx( /* o : tilt of the code Q15 */ - const Word16 *exc, /* i : adaptive excitation vector Qx */ - const Word16 gain_pit, /* i : adaptive gain Q14 */ - const Word16 *code, /* i : algebraic excitation vector Q9 */ - const Word32 gain_code, /* i : algebraic code gain Q16 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#if 1 // def ADD_LRTD - , - const Word16 L_subfr, /* i : Sub frame length */ - const Word16 flag_tilt /* i : flag for special tilt */ -#endif + +/* o : tilt of the code Q15 */ +Word16 est_tilt_ivas_fx( + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic excitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc, /* i : Scaling factor of excitation Q0 */ + const Word16 L_subfr, /* i : Sub frame length */ + const Word16 flag_tilt /* i : flag for special tilt */ ) { Word16 i, tmp, exp, ener1, exp1, ener2, exp2; Word32 L_tmp; Word16 tilt_code; -#ifdef ADD_LRTD - PMT( "FIX POINT NEED to be adapted for 16 kHz frame length " ) -#endif + ener1 = extract_h( Dot_product12( exc, exc, L_subfr, &exp1 ) ); exp1 = sub( exp1, add( Q_exc, Q_exc ) ); L_tmp = L_mult( gain_pit, gain_pit ); /* energy of pitch excitation */ diff --git a/lib_com/gs_bitallocation_fx.c b/lib_com/gs_bitallocation_fx.c index 47d3679a8..e8f32c804 100644 --- a/lib_com/gs_bitallocation_fx.c +++ b/lib_com/gs_bitallocation_fx.c @@ -120,40 +120,7 @@ void bands_and_bit_alloc_fx( move16(); bit_new_bands = 5; move16(); -#ifdef ADD_LRTD - if ( GT_32( core_brate, ACELP_16k40 ) && EQ_16( L_frame, L_FRAME16k ) ) - { - bit_new_bands = 7; - move16(); - } - - i = 0; - move16(); - WHILE( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) - { - IF( LE_32( core_brate, brate_intermed_tbl[i] ) ) - { - BREAK; - } - - IF( EQ_32( brate_intermed_tbl[i], ACELP_24k40 ) ) - { - BREAK; - } - - i = add( i, 1 ); - } - - if ( GT_16( element_mode, EVS_MONO ) && EQ_16( coder_type, AUDIO ) && - LE_32( core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ - { - i = sub( i, 1 ); - } - - bit_index = i_mult2( BRATE2IDX_fx( brate_intermed_tbl[i] ), 17 ); -#else bit_index = i_mult2( BRATE2IDX_fx( core_brate ), 17 ); -#endif bit_index_mem = bit_index; move16(); @@ -189,668 +156,330 @@ void bands_and_bit_alloc_fx( move16(); } -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k ) - { - *bit -= 8; - } - - if ( coder_type == INACTIVE && core_brate <= GSC_LRES_GAINQ_LIMIT ) /* can happen only for 2nd channel inactive */ - { - *bit += GSC_LRES_NB_NITS; - } - - if ( *bit > 0 ) + IF( EQ_16( GSC_noisy_speech, 1 ) ) { - if ( GSC_IVAS_mode > 0 ) - { - SWB_bit_budget = *bit; - st_band = 5; - - set_f( bits_per_bands, 0, MBANDS_GN_BITALLOC16k ); - - /* 2- Decide the pourcentage of bits allocated to LF (between 50-75%) depending of the temporal contribution in GSC */ - bit_fracf = ( -0.125f * Diff_len + 76.0f ) / 100; - bit_fracf = check_bounds( bit_fracf, 0.50f, 0.75f ); - - /* Adjusment of the bitrate between LF and HF base on the content type */ - /* 1 = new GSC bit alloc - 2 = GSC bit alloc for tc frame - 3 = more music like (should not happen often given music is coded with dft) */ - - if ( GSC_IVAS_mode <= 3 ) - { - nb_bands_max -= 6; - } - - if ( GSC_IVAS_mode == 2 ) - { - bit_fracf += 0.1f; - nb_bands_max--; - } - - if ( GSC_IVAS_mode == 3 ) - { - bit_fracf -= 0.1f; - nb_bands_max += 3; - } - - /* First find how much we want to share between LF and HF, at low bitrate, a miminum of bits is needed in LF by limitating the number of bands*/ - /* Adjust the number of band based on the content type and bitrate */ - nb_bands_adj = 1.0f; - if ( GSC_IVAS_mode == 1 && core_brate < GSC_L_RATE_STG ) - { - nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f; - } - else if ( GSC_IVAS_mode != 2 && core_brate > GSC_H_RATE_STG ) - { - nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f; - } - nb_bands_max = (int16_t) ( nb_bands_max * nb_bands_adj + 0.5f ); - nb_bands_max = check_bounds_s( nb_bands_max, 5, nb_tot_bands ); - - bit_fracf *= SWB_bit_budget; - - /* Estimation of the number of bit used in HF */ - /* with only the first weigthing The number of bits in max_ener_band[st_band-1] = 17% of bit_fracf */ - mb = .17f * bit_fracf; - mp = ( 2.0f * DSR_NB_PULSE ); - if ( core_brate < GSC_L_RATE_STG && GSC_IVAS_mode == 3 ) - { - mp = 1.5f * DSR_NB_PULSE; - } - else if ( core_brate < GSC_L_RATE_STG ) - { - mp = DSR_NB_PULSE; - } - - /* We want max_ener_band[st_band] <= max_ener_band[st_band-1] and max_ener_band[nb_bands_max-1] <= max_ener_band[st_band]*/ - /* We will estimate the number of bits to allocate of HF and put the remaining bits, if any, back on LF */ - /* compute the total possible number of band to be coded */ - nb_tot_bands = (int16_t) ( ( SWB_bit_budget - bit_fracf ) / ( mp + ( mb - mp ) / 2.0f ) ); - mp = min( mp, mb ); - if ( nb_tot_bands + st_band > nb_bands_max ) - { - bit_adj = ( ( mb + mp ) / 2 ) * ( nb_tot_bands + st_band - nb_bands_max ); - bit_adj = max( 0, bit_adj ); - nb_tot_bands = nb_bands_max - st_band; - bit_fracf += bit_adj; - } - nb_tot_bands += st_band; - - /* Allocate bits to LF */ - etmp = 0.23f; - for ( j = 0; j < st_band; j++ ) - { - i = j; - max_ener_band[j] = i; - ener_vec[i] = MIN16B; - bits_per_bands[j] = etmp * bit_fracf; - etmp -= 0.015f; - } - - SWB_bit_budget -= bit_fracf; - - /* Find low energy band in HF */ - set_s( nb_pulse_per_band, 2, MBANDS_GN_BITALLOC16k ); - for ( i = st_band + 2; i < nb_tot_bands - 1; i++ ) - { - if ( ener_vec[i] < ener_vec[i - 1] && ener_vec[i] < ener_vec[i + 1] ) - { - nb_pulse_per_band[i] = 1; - } - } - for ( j = st_band; j < nb_tot_bands; j++ ) - { - if ( j > 6 ) - { - i = maximum( ener_vec, nb_tot_bands, &etmp ); - } - else - { - i = j; - } - - max_ener_band[j] = i; - ener_vec[i] = MIN16B; - } - - /* Recompute the final bit distribution for HF */ - if ( nb_tot_bands > st_band ) - { - bit_fracf = DSR_NB_PULSE; - mb = ( SWB_bit_budget * 2 / ( nb_tot_bands - st_band ) ) - mp; - bit_fracf = ( mb - mp ) / ( nb_tot_bands - st_band ); - mb -= bit_fracf; - /* Do the distribution */ - for ( j = st_band; j < nb_tot_bands; j++ ) - { - if ( nb_pulse_per_band[max_ener_band[j]] > 1 ) - { - bits_per_bands[max_ener_band[j]] = mb; - } - else - { - bits_per_bands[max_ener_band[j]] = 4.5f; - } - mb -= bit_fracf; - SWB_bit_budget -= bits_per_bands[max_ener_band[j]]; - } - } - - /* Series of verification in case bit allocated != the budget */ - if ( SWB_bit_budget > 0 ) - { - i = st_band - 1; - while ( SWB_bit_budget > 0 ) - { - bits_per_bands[i]++; - SWB_bit_budget--; - i--; - if ( i == -1 ) - { - i = st_band - 1; - } - } - } + SWB_bit_budget = *bit; + move16(); + nb_bands = 5; + move16(); - nb_bands = nb_tot_bands; + st_band = nb_bands; + move16(); - sum_bit = 0; - j = 0; - for ( i = 0; i < nb_bands; i++ ) - { - if ( bits_per_bands[i] > 112 ) - { - sum_bit += bits_per_bands[i] - 112; - bits_per_bands[i] = 112; - j = i + 1; - } + set32_fx( bits_per_bands, 0, MBANDS_GN ); + /*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */ + bit_fracf = L_mult( div_s( 1, nb_bands ), shl( SWB_bit_budget, 2 ) ); /* Q18 */ - /* safety check for overage bit reallocation */ - else if ( bits_per_bands[i] + sum_bit / 3 > 112 ) - { - j = i + 1; - } - } + nb_tot_bands = sub( nb_bands_max, 6 ); + nb_tot_bands = s_min( nb_tot_bands, 16 ); - if ( sum_bit != 0 ) - { - sum_bit /= ( nb_bands - j ); - for ( i = j; i < nb_bands; i++ ) - { - bits_per_bands[i] += sum_bit; - } - } + FOR( j = 0; j < 2; j++ ) + { + i = j; + move16(); + max_ener_band[j] = i; + move16(); + ener_vec[i] = 0; + move16(); } - else -#endif - IF( EQ_16( GSC_noisy_speech, 1 ) ) - { - SWB_bit_budget = *bit; - move16(); - nb_bands = 5; - move16(); -#ifdef ADD_LRTD - - fzero_val = 0.0f; - if ( element_mode > EVS_MONO ) - { - fzero_val = MIN16B_FLT; - } - - if ( coder_type == UNVOICED && element_mode > EVS_MONO ) - { - nb_bands = 3; - if ( SWB_bit_budget > 20 ) - { - nb_bands = 5; - } - } - else if ( bwidth < SWB ) - { - nb_bands = 7; - } - -#endif - - st_band = nb_bands; - move16(); + FOR( ; j < nb_bands; j++ ) + { + i = maximum_fx( ener_vec, nb_tot_bands, &etmp ); + max_ener_band[j] = i; + move16(); + ener_vec[i] = 0; + move16(); + } - set32_fx( bits_per_bands, 0, MBANDS_GN ); - /*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */ - bit_fracf = L_mult( div_s( 1, nb_bands ), shl( SWB_bit_budget, 2 ) ); /* Q18 */ + set32_fx( bits_per_bands, bit_fracf, nb_bands ); + } + ELSE + { + bit_index++; + bit_tmp = sub( *bit, GSC_freq_bits[bit_index] ); + bit_index++; + nb_bands_max = add( nb_bands_max, GSC_freq_bits[bit_index] ); + bit_index++; - nb_tot_bands = sub( nb_bands_max, 6 ); - nb_tot_bands = s_min( nb_tot_bands, 16 ); + *pvq_len = 112; + move16(); + st_band = 7; + move16(); - FOR( j = 0; j < 2; j++ ) - { - i = j; - move16(); - max_ener_band[j] = i; - move16(); - ener_vec[i] = 0; - move16(); - } -#ifdef ADD_LRTD - if ( bwidth < SWB ) - { - if ( coder_type == UNVOICED && element_mode > EVS_MONO ) - { - nb_tot_bands = 5; - } -#endif - FOR( ; j < nb_bands; j++ ) - { - i = maximum_fx( ener_vec, nb_tot_bands, &etmp ); - max_ener_band[j] = i; - move16(); - ener_vec[i] = 0; - move16(); - } -#ifdef ADD_LRTD - } - else - { - for ( ; j < nb_bands; j++ ) - { - i = maximum( ener_vec, nb_tot_bands, &etmp ); - max_ener_band[j] = i; - ener_vec[i] = fzero_val; - } - } -#endif - set32_fx( bits_per_bands, bit_fracf, nb_bands ); - } - ELSE + IF( LE_32( core_brate, ACELP_9k60 ) ) { - bit_index++; - bit_tmp = sub( *bit, GSC_freq_bits[bit_index] ); - bit_index++; - nb_bands_max = add( nb_bands_max, GSC_freq_bits[bit_index] ); - bit_index++; - - *pvq_len = 112; + *pvq_len = 80; move16(); - st_band = 7; + st_band = 5; move16(); -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_16k40 ) - { - *pvq_len = 160; - st_band = 10; - nb_bands = *pvq_len / 16; - bit_tmp -= 35; - bit_new_bands = 5; - } -#endif - IF( LE_32( core_brate, ACELP_9k60 ) ) - { - *pvq_len = 80; - move16(); - st_band = 5; - move16(); - - IF( Diff_len == 0 ) - { - nb_bands_max = add( nb_bands_max, 2 ); - bit_tmp = sub( bit_tmp, 13 ); - } - } - ELSE IF( Diff_len == 0 ) + IF( Diff_len == 0 ) { nb_bands_max = add( nb_bands_max, 2 ); - bit_tmp = sub( bit_tmp, 17 ); + bit_tmp = sub( bit_tmp, 13 ); } + } - nb_bands = shr( *pvq_len, 4 ); -#ifdef ADD_LRTD - nb_bands_max = min( nb_bands_max, MBANDS_GN_BITALLOC16k ); -#endif - /*------------------------------------------------------------------------ + ELSE IF( Diff_len == 0 ) + { + nb_bands_max = add( nb_bands_max, 2 ); + bit_tmp = sub( bit_tmp, 17 ); + } + + nb_bands = shr( *pvq_len, 4 ); + + /*------------------------------------------------------------------------ * Ajustement of the maximum number of bands in function of the * dynamics of the spectrum (more or less speech like) *-----------------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - IF( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) - { - /* Probably classification error -> concentrate bits on LF */ -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate >= ACELP_24k40 ) - { - nb_bands_max = nb_tot_bands - 2; - } - else if ( core_brate >= ACELP_16k40 ) - { - nb_bands_max = nb_bands + 2; - } - else -#endif - if ( GE_32( core_brate, ACELP_8k00 ) ) - { - nb_bands_max = add( nb_bands, 1 ); - } - else - { - nb_bands_max = nb_bands; - move16(); - } - } - ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP2 ) || - ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) /* Very low dynamic, tend to speech, do not try to code HF at all */ - { - nb_bands_max = sub( nb_bands_max, 2 ); - } - ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP1 ) ) /* Very low dynamic, tend to speech, code less HF */ + test(); + test(); + test(); + test(); + IF( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) + { + /* Probably classification error -> concentrate bits on LF */ + if ( GE_32( core_brate, ACELP_8k00 ) ) { - nb_bands_max = sub( nb_bands_max, 1 ); + nb_bands_max = add( nb_bands, 1 ); } -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k ) - { - if ( core_brate < ACELP_24k40 ) - { - nb_bands_max -= 4; - } - else if ( core_brate < ACELP_32k ) - { - if ( Diff_len > 0 || noise_lev >= NOISE_LEVEL_SP2 ) - { - nb_bands_max -= 2; - bit_new_bands *= 2; - } - } - else if ( core_brate >= ACELP_32k ) - { - bit_new_bands *= 2; - } - } - -#endif - test(); - if ( ( EQ_16( bwidth, NB ) ) && GT_16( nb_bands_max, 10 ) ) + else { - nb_bands_max = 10; + nb_bands_max = nb_bands; move16(); } + } + ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP2 ) || + ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) /* Very low dynamic, tend to speech, do not try to code HF at all */ + { + nb_bands_max = sub( nb_bands_max, 2 ); + } + ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP1 ) ) /* Very low dynamic, tend to speech, code less HF */ + { + nb_bands_max = sub( nb_bands_max, 1 ); + } + + test(); + if ( ( EQ_16( bwidth, NB ) ) && GT_16( nb_bands_max, 10 ) ) + { + nb_bands_max = 10; + move16(); + } - /*------------------------------------------------------------------------ + /*------------------------------------------------------------------------ * Find extra number of band to code according to bit rate availables *-----------------------------------------------------------------------*/ + test(); + WHILE( GE_16( bit_tmp, bit_new_bands ) && LE_16( nb_bands, sub( nb_bands_max, 1 ) ) ) + { test(); - WHILE( GE_16( bit_tmp, bit_new_bands ) && LE_16( nb_bands, sub( nb_bands_max, 1 ) ) ) - { - test(); - bit_tmp = sub( bit_tmp, bit_new_bands ); - nb_bands = add( nb_bands, 1 ); - } + bit_tmp = sub( bit_tmp, bit_new_bands ); + nb_bands = add( nb_bands, 1 ); + } - /*------------------------------------------------------------------------ + /*------------------------------------------------------------------------ * Fractional bits to distribute on the first x bands *-----------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_32k ) - { - bit_fracf = 0; - } - else -#endif - { - bit_fracf = L_mult( div_s( 1, st_band ), shl( bit_tmp, 2 ) ); /* Q18 */ - } - /*------------------------------------------------------------------------ + + { + bit_fracf = L_mult( div_s( 1, st_band ), shl( bit_tmp, 2 ) ); /* Q18 */ + } + /*------------------------------------------------------------------------ * Complete the bit allocation per frequency band *-----------------------------------------------------------------------*/ - imax = 5; + imax = 5; + move16(); + + if ( GT_32( core_brate, ACELP_9k60 ) ) + { + imax = 7; move16(); + } + FOR( i = 0; i < imax; i++ ) + { + bits_per_bands[i] = L_add( GSC_freq_bits_fx[bit_index], bit_fracf ); + move32(); /* Q18 */ + bit_index = add( bit_index, 1 ); + } - if ( GT_32( core_brate, ACELP_9k60 ) ) - { - imax = 7; - move16(); - } - FOR( i = 0; i < imax; i++ ) + IF( Diff_len == 0 ) + { + bit_index = add( bit_index_mem, 10 ); + FOR( i = 0; i < 7; i++ ) { - bits_per_bands[i] = L_add( GSC_freq_bits_fx[bit_index], bit_fracf ); - move32(); /* Q18 */ + bits_per_bands[i] = L_add( bits_per_bands[i], GSC_freq_bits_fx[bit_index] ); + move32(); /*chk Q18 */ bit_index = add( bit_index, 1 ); } -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_16k40 ) - { - bit_index = 0; - i = imax - 1; - bits_per_bands[i] += Compl_GSC_freq_bits[bit_index]; - i++; - bit_index++; - - for ( ; i < 10; i++ ) - { - bits_per_bands[i] += Compl_GSC_freq_bits[bit_index] + bit_fracf; - bit_index++; - } - } -#endif - IF( Diff_len == 0 ) - { - bit_index = add( bit_index_mem, 10 ); - FOR( i = 0; i < 7; i++ ) - { - bits_per_bands[i] = L_add( bits_per_bands[i], GSC_freq_bits_fx[bit_index] ); - move32(); /*chk Q18 */ - bit_index = add( bit_index, 1 ); - } - } -#ifdef ADD_LRTD - if ( bit_fracf < 0 ) - { - for ( j = 0; j < nb_tot_bands; j++ ) - { - bits_per_bands[j] = max( bits_per_bands[j], 0 ); - } - } + } -#endif - /*-------------------------------------------------------------------------- + /*-------------------------------------------------------------------------- * Complete the bit allocation per frequency band for 16kHz high brate mode *--------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_32k ) - { - for ( j = st_band; j < nb_bands; j++ ) - { - bits_per_bands[j] = bit_new_bands; - } - - bit_fracf = ( 1.0f / nb_bands ) * ( bit_tmp ); - etmp = 2.0f * bit_fracf / ( nb_bands + 1 ); - bit_fracf = etmp; - for ( j = nb_bands - 1; j >= 0; j-- ) - { - bits_per_bands[j] += etmp; - etmp += bit_fracf; - } - } - else -#endif + { + FOR( j = st_band; j < nb_bands; j++ ) { - FOR( j = st_band; j < nb_bands; j++ ) - { - bits_per_bands[j] = L_shl( bit_new_bands, 18 ); - move32(); /*chk Q18 */ - } + bits_per_bands[j] = L_shl( bit_new_bands, 18 ); + move32(); /*chk Q18 */ } + } - /*-------------------------------------------------------------------------- + /*-------------------------------------------------------------------------- * Compute a maximum band (band offset) for the search on maximal energy * This is function of the spectral dynamic and the bitrate *--------------------------------------------------------------------------*/ - bandoffset = sub( nb_tot_bands, add( nb_bands, 2 ) ); + bandoffset = sub( nb_tot_bands, add( nb_bands, 2 ) ); - test(); - test(); - test(); - test(); - test(); - IF( LE_16( noise_lev, NOISE_LEVEL_SP1a ) ) - { - bandoffset = sub( bandoffset, 1 ); - } - ELSE IF( ( LE_32( core_brate, ACELP_13k20 ) && ( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) ) || - ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) - { - bandoffset = add( bandoffset, 1 ); - } + test(); + test(); + test(); + test(); + test(); + IF( LE_16( noise_lev, NOISE_LEVEL_SP1a ) ) + { + bandoffset = sub( bandoffset, 1 ); + } + ELSE IF( ( LE_32( core_brate, ACELP_13k20 ) && ( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) ) || + ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) + { + bandoffset = add( bandoffset, 1 ); + } - bandoffset = s_max( bandoffset, 0 ); + bandoffset = s_max( bandoffset, 0 ); - /*-------------------------------------------------------------------------- + /*-------------------------------------------------------------------------- * Initiazed sorted vector * For the first x bands to be included in th final sorted vector * Sort the remaining bands in decrease energy order *--------------------------------------------------------------------------*/ - FOR( j = 0; j < nb_tot_bands; j++ ) - { - max_ener_band[j] = -10; - move16(); - } - FOR( j = 0; j < st_band; j++ ) - { - max_ener_band[j] = j; - move16(); - ener_vec[j] = -10; - move16(); - } - pos = st_band; + FOR( j = 0; j < nb_tot_bands; j++ ) + { + max_ener_band[j] = -10; move16(); - FOR( ; j < nb_bands; j++ ) + } + FOR( j = 0; j < st_band; j++ ) + { + max_ener_band[j] = j; + move16(); + ener_vec[j] = -10; + move16(); + } + pos = st_band; + move16(); + FOR( ; j < nb_bands; j++ ) + { + i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); + pos = s_max( pos, i ); + max_ener_band[j] = i; + move16(); + ener_vec[i] = -10; + move16(); + } + + /* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */ + test(); + test(); + test(); + IF( GT_16( sub( nb_tot_bands, bandoffset ), nb_bands ) && ( GT_16( pos, 7 ) && EQ_32( core_brate, ACELP_8k00 ) ) && EQ_16( bwidth, WB ) ) + { + band = sub( nb_tot_bands, add( bandoffset, nb_bands ) ); + FOR( j = 0; j < band; j++ ) { i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); - pos = s_max( pos, i ); - max_ener_band[j] = i; + max_ener_band[add( nb_bands, j )] = i; move16(); ener_vec[i] = -10; move16(); + bits_per_bands[add( nb_bands, j )] = 1310720; + move32(); /*Q18 */ } + nb_bands = add( nb_bands, band ); - /* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */ - test(); - test(); - test(); - IF( GT_16( sub( nb_tot_bands, bandoffset ), nb_bands ) && ( GT_16( pos, 7 ) && EQ_32( core_brate, ACELP_8k00 ) ) && EQ_16( bwidth, WB ) ) + bit_tmp = i_mult2( band, 5 ); + + IF( LE_16( band, 2 ) ) { - band = sub( nb_tot_bands, add( bandoffset, nb_bands ) ); - FOR( j = 0; j < band; j++ ) + FOR( j = sub( st_band, 1 ); j < nb_bands; j++ ) { - i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); - max_ener_band[add( nb_bands, j )] = i; - move16(); - ener_vec[i] = -10; - move16(); - bits_per_bands[add( nb_bands, j )] = 1310720; - move32(); /*Q18 */ + bits_per_bands[j] = L_add( bits_per_bands[j], 262144 ); /*Q18 */ + move32(); } - nb_bands = add( nb_bands, band ); - - bit_tmp = i_mult2( band, 5 ); + bit_tmp = add( bit_tmp, add( sub( nb_bands, st_band ), 1 ) ); + } - IF( LE_16( band, 2 ) ) + i = 0; + move16(); + j = 0; + move16(); + FOR( ; bit_tmp > 0; bit_tmp-- ) + { + bits_per_bands[j] = L_sub( bits_per_bands[j], 262144 ); /*Q18 */ + j = add( j, 1 ); + if ( EQ_16( j, sub( st_band, i ) ) ) { - FOR( j = sub( st_band, 1 ); j < nb_bands; j++ ) - { - bits_per_bands[j] = L_add( bits_per_bands[j], 262144 ); /*Q18 */ - move32(); - } - bit_tmp = add( bit_tmp, add( sub( nb_bands, st_band ), 1 ) ); + j = 0; + move16(); } - - i = 0; - move16(); - j = 0; - move16(); - FOR( ; bit_tmp > 0; bit_tmp-- ) + test(); + if ( j == 0 && LT_16( i, sub( st_band, 1 ) ) ) { - bits_per_bands[j] = L_sub( bits_per_bands[j], 262144 ); /*Q18 */ - j = add( j, 1 ); - if ( EQ_16( j, sub( st_band, i ) ) ) - { - j = 0; - move16(); - } - test(); - if ( j == 0 && LT_16( i, sub( st_band, 1 ) ) ) - { - i = add( i, 1 ); - } + i = add( i, 1 ); } } } - /*-------------------------------------------------------------------------- + } + /*-------------------------------------------------------------------------- * Bit sum verification for GSC inactive at very high rate * The maximum number of bits per band of length 16 is 112 * Redistribute the overage bits if needed *--------------------------------------------------------------------------*/ - sum_bit = 0; - move16(); - j = 0; - move16(); - FOR( i = 0; i < nb_bands; i++ ) - { - L_tmp = Mult_32_16( sum_bit, 10923 ); + sum_bit = 0; + move16(); + j = 0; + move16(); + FOR( i = 0; i < nb_bands; i++ ) + { + L_tmp = Mult_32_16( sum_bit, 10923 ); - IF( GT_32( bits_per_bands[i], 29360128 ) ) /* 112 in Q18 */ - { - sum_bit = L_add( sum_bit, L_sub( bits_per_bands[i], 29360128 ) ); /* Q18 */ - bits_per_bands[i] = 29360128; - move32(); - j = add( i, 1 ); - } - ELSE IF( GT_32( L_add( bits_per_bands[i], L_tmp ), 29360128 ) ) /* Q18 */ - { - j = add( i, 1 ); - } + IF( GT_32( bits_per_bands[i], 29360128 ) ) /* 112 in Q18 */ + { + sum_bit = L_add( sum_bit, L_sub( bits_per_bands[i], 29360128 ) ); /* Q18 */ + bits_per_bands[i] = 29360128; + move32(); + j = add( i, 1 ); } + ELSE IF( GT_32( L_add( bits_per_bands[i], L_tmp ), 29360128 ) ) /* Q18 */ + { + j = add( i, 1 ); + } + } - IF( sum_bit != 0 ) + IF( sum_bit != 0 ) + { + tmp = sub( nb_bands, j ); + sum_bit = Mult_32_16( sum_bit, div_s( 1, tmp ) ); /* Q18 */ + FOR( i = j; i < nb_bands; i++ ) { - tmp = sub( nb_bands, j ); - sum_bit = Mult_32_16( sum_bit, div_s( 1, tmp ) ); /* Q18 */ - FOR( i = j; i < nb_bands; i++ ) - { - bits_per_bands[i] = L_add( bits_per_bands[i], sum_bit ); - move32(); /* Q18 */ - } + bits_per_bands[i] = L_add( bits_per_bands[i], sum_bit ); + move32(); /* Q18 */ } - /*-------------------------------------------------------------------------- + } + /*-------------------------------------------------------------------------- * second step of bit sum verification, normally sum_bit == *bit *--------------------------------------------------------------------------*/ - w_sum_bit = 0; + w_sum_bit = 0; + move16(); + FOR( i = 0; i < nb_bands; i++ ) + { + out_bits_per_bands[i] = shl( extract_l( L_shr( bits_per_bands[i], 18 ) ), 3 ); move16(); - FOR( i = 0; i < nb_bands; i++ ) - { - out_bits_per_bands[i] = shl( extract_l( L_shr( bits_per_bands[i], 18 ) ), 3 ); - move16(); - w_sum_bit = add( w_sum_bit, out_bits_per_bands[i] ); /* Q3 */ - } - tmp = shl( *bit, 3 ); -#ifdef ADD_LRTD - if ( GSC_IVAS_mode != 0 && sum_bit < *bit ) /* If we need to add bits, we are doing it on the LF */ - { - reajust_bits( bits_per_bands, 0, nb_bands, (int16_t) sum_bit, *bit ); - } - else - { - reajust_bits( bits_per_bands, nb_bands - 1, 0, (int16_t) sum_bit, *bit ); - } -#else + w_sum_bit = add( w_sum_bit, out_bits_per_bands[i] ); /* Q3 */ + } + tmp = shl( *bit, 3 ); + IF( GT_16( tmp, w_sum_bit ) ) { i = sub( nb_bands, 1 ); @@ -866,88 +495,24 @@ void bands_and_bit_alloc_fx( } } } -#endif - /*-------------------------------------------------------------------------- + + /*-------------------------------------------------------------------------- * Recompute the real number/length of frequency bands to encode *--------------------------------------------------------------------------*/ - *nb_subbands = nb_bands; - move16(); - *pvq_len = shl( *nb_subbands, 4 ); + *nb_subbands = nb_bands; + move16(); + *pvq_len = shl( *nb_subbands, 4 ); - /*-------------------------------------------------------------------------- + /*-------------------------------------------------------------------------- * Concatenate bands (encoder only) *--------------------------------------------------------------------------*/ - IF( exc_diff != NULL ) - { - FOR( j = 0; j < nb_bands; j++ ) - { - Copy( exc_diff + shl( max_ener_band[j], 4 ), concat_in + shl( j, 4 ), 16 ); - } - } -#ifdef ADD_LRTD - } - else /* *bit == 0 */ - { - set_s( bits_per_bands_s, 0, nb_tot_bands ); - *nb_subbands = 0; - *pvq_len = 0; - } -#endif - return; -} -#ifdef ADD_LRTD -/*-------------------------------------------------------------------* - * reajust_bits() - * - * - *-------------------------------------------------------------------*/ - -static void reajust_bits( - float *bits_per_bands, - const int16_t st_band, - const int16_t end_band, - const int16_t sum_bit_in, - const int16_t bit_bdgt_in ) -{ - int16_t i, amount_to_add, incr; - int16_t bit_bdgt, sum_bit; - - incr = 1; - if ( end_band < st_band ) - { - incr = -1; - } - - if ( bit_bdgt_in < sum_bit_in ) - { - amount_to_add = -1; - bit_bdgt = sum_bit_in; - sum_bit = bit_bdgt_in; - } - else - { - bit_bdgt = bit_bdgt_in; - sum_bit = sum_bit_in; - amount_to_add = 1; - } - - i = st_band; - while ( bit_bdgt > sum_bit ) + IF( exc_diff != NULL ) { - if ( amount_to_add > 0 || ( amount_to_add < 0 && bits_per_bands[i] > 1 ) ) + FOR( j = 0; j < nb_bands; j++ ) { - bits_per_bands[i] += amount_to_add; - sum_bit += (int16_t) abs( amount_to_add ); - } - - i += incr; - if ( i == end_band ) - { - i = st_band; + Copy( exc_diff + shl( max_ener_band[j], 4 ), concat_in + shl( j, 4 ), 16 ); } } return; } - -#endif diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 0ab167015..eef3d50c6 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -103,8 +103,8 @@ void bands_and_bit_alloc_ivas_fx( Word16 etmp; Word16 tmp; Word16 pos, band; - Word32 SWB_bit_budget; // Q0 -> Q18 - Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; // Q18 + Word32 SWB_bit_budget; /* Q0 -> Q18 */ + Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; /* Q18 */ Word16 w_sum_bit; Word16 fzero_val; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -148,7 +148,7 @@ void bands_and_bit_alloc_ivas_fx( move16(); bit_new_bands = 5; move16(); -#if 1 // def ADD_LRTD + test(); if ( GT_32( core_brate, ACELP_16k40 ) && EQ_16( L_frame, L_FRAME16k ) ) { @@ -183,9 +183,6 @@ void bands_and_bit_alloc_ivas_fx( } bit_index = i_mult2( BRATE2IDX_fx( brate_intermed_tbl[i] ), 17 ); -#else - bit_index = i_mult2( BRATE2IDX_fx( core_brate ), 17 ); -#endif bit_index_mem = bit_index; move16(); @@ -221,7 +218,6 @@ void bands_and_bit_alloc_ivas_fx( move16(); } -#if 1 // def ADD_LRTD IF( EQ_16( L_frame, L_FRAME16k ) ) { *bit = sub( *bit, 8 ); @@ -242,18 +238,12 @@ void bands_and_bit_alloc_ivas_fx( nb_tot_bands = Find_bit_alloc_IVAS_fx( core_brate, GSC_IVAS_mode, Diff_len, nb_tot_bands, bit, max_ener_band, ener_vec, bits_per_bands ); nb_bands = nb_tot_bands; } - ELSE -#endif - IF( EQ_16( GSC_noisy_speech, 1 ) ) + ELSE IF( EQ_16( GSC_noisy_speech, 1 ) ) { SWB_bit_budget = *bit; /*Q0*/ move32(); nb_bands = 5; move16(); - -#if 1 // def ADD_LRTD - - // fzero_val = 0.0f; fzero_val = 0; move16(); @@ -281,8 +271,6 @@ void bands_and_bit_alloc_ivas_fx( move16(); } -#endif - st_band = nb_bands; move16(); @@ -298,11 +286,10 @@ void bands_and_bit_alloc_ivas_fx( move16(); max_ener_band[j] = i; move16(); - // ener_vec[i] = 0; ener_vec[i] = fzero_val; move16(); } -#if 1 // def ADD_LRTD + IF( LT_16( bwidth, SWB ) ) { test(); @@ -311,17 +298,15 @@ void bands_and_bit_alloc_ivas_fx( nb_tot_bands = 5; move16(); } -#endif + FOR( ; j < nb_bands; j++ ) { i = maximum_fx( ener_vec, nb_tot_bands, &etmp ); max_ener_band[j] = i; move16(); - // ener_vec[i] = 0; ener_vec[i] = fzero_val; move16(); } -#if 1 // def ADD_LRTD } ELSE { @@ -334,7 +319,7 @@ void bands_and_bit_alloc_ivas_fx( move16(); } } -#endif + set32_fx( bits_per_bands, bit_fracf, nb_bands ); } ELSE @@ -349,7 +334,7 @@ void bands_and_bit_alloc_ivas_fx( move16(); st_band = 7; move16(); -#if 1 // def ADD_LRTD + test(); IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_16k40 ) ) { @@ -362,7 +347,7 @@ void bands_and_bit_alloc_ivas_fx( bit_new_bands = 5; move16(); } -#endif + IF( LE_32( core_brate, ACELP_9k60 ) ) { *pvq_len = 80; @@ -384,9 +369,8 @@ void bands_and_bit_alloc_ivas_fx( } nb_bands = shr( *pvq_len, 4 ); -#if 1 // def ADD_LRTD nb_bands_max = s_min( nb_bands_max, MBANDS_GN_BITALLOC16k ); -#endif + /*------------------------------------------------------------------------ * Ajustement of the maximum number of bands in function of the * dynamics of the spectrum (more or less speech like) @@ -398,7 +382,6 @@ void bands_and_bit_alloc_ivas_fx( IF( coder_type == INACTIVE || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) { /* Probably classification error -> concentrate bits on LF */ -#if 1 // def ADD_LRTD IF( EQ_16( L_frame, L_FRAME16k ) && GE_32( core_brate, ACELP_24k40 ) ) { nb_bands_max = sub( nb_tot_bands, 2 ); @@ -407,9 +390,7 @@ void bands_and_bit_alloc_ivas_fx( { nb_bands_max = add( nb_bands, 2 ); } - ELSE -#endif - IF( GE_32( core_brate, ACELP_8k00 ) ) + ELSE IF( GE_32( core_brate, ACELP_8k00 ) ) { nb_bands_max = add( nb_bands, 1 ); } @@ -428,7 +409,7 @@ void bands_and_bit_alloc_ivas_fx( { nb_bands_max = sub( nb_bands_max, 1 ); } -#if 1 // def ADD_LRTD + IF( EQ_16( L_frame, L_FRAME16k ) ) { IF( LT_32( core_brate, ACELP_24k40 ) ) @@ -450,7 +431,6 @@ void bands_and_bit_alloc_ivas_fx( } } -#endif test(); if ( ( bwidth == NB ) && GT_16( nb_bands_max, 10 ) ) { @@ -472,7 +452,7 @@ void bands_and_bit_alloc_ivas_fx( /*------------------------------------------------------------------------ * Fractional bits to distribute on the first x bands *-----------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_32k ) ) { @@ -480,10 +460,10 @@ void bands_and_bit_alloc_ivas_fx( move32(); } ELSE -#endif { bit_fracf = Find_bit_frac_fx( st_band, bit_tmp ); /*Q18*/ } + /*------------------------------------------------------------------------ * Complete the bit allocation per frequency band *-----------------------------------------------------------------------*/ @@ -501,13 +481,12 @@ void bands_and_bit_alloc_ivas_fx( move32(); /* Q18 */ bit_index = add( bit_index, 1 ); } -#if 1 // def ADD_LRTD + IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_16k40 ) ) { bit_index = 0; move16(); i = sub( imax, 1 ); - // bits_per_bands[i] += Compl_GSC_freq_bits[bit_index]; bits_per_bands[i] = L_add( bits_per_bands[i], L_shl( Compl_GSC_freq_bits[bit_index], Q18 ) ); /*Q18*/ move32(); i = add( i, 1 ); @@ -515,13 +494,12 @@ void bands_and_bit_alloc_ivas_fx( FOR( ; i < 10; i++ ) { - // bits_per_bands[i] += Compl_GSC_freq_bits[bit_index] + bit_fracf; bits_per_bands[i] = L_add( bits_per_bands[i], L_add( L_shl( Compl_GSC_freq_bits[bit_index], Q18 ), bit_fracf ) ); /*Q18*/ move32(); bit_index = add( bit_index, 1 ); } } -#endif + IF( Diff_len == 0 ) { bit_index = add( bit_index_mem, 10 ); @@ -532,7 +510,7 @@ void bands_and_bit_alloc_ivas_fx( bit_index = add( bit_index, 1 ); } } -#if 1 // def ADD_LRTD + IF( bit_fracf < 0 ) { FOR( j = 0; j < nb_tot_bands; j++ ) @@ -542,39 +520,33 @@ void bands_and_bit_alloc_ivas_fx( } } -#endif /*-------------------------------------------------------------------------- * Complete the bit allocation per frequency band for 16kHz high brate mode *--------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_32k ) ) { FOR( j = st_band; j < nb_bands; j++ ) { - // bits_per_bands[j] = bit_new_bands; bits_per_bands[j] = L_shl( bit_new_bands, Q18 ); move32(); } - // bit_fracf = (1.0f / nb_bands) * (bit_tmp); bit_fracf = L_shl( L_mult0( idiv1616( 16384, nb_bands ), bit_tmp ), 4 ); /*Q18*/ - // etmp = 2.0f * bit_fracf / (nb_bands + 1); - etmp = divide3216( L_shr( bit_fracf, Q2 ), add( nb_bands, 1 ) ); // Q15 - // bit_fracf = etmp; - bit_fracf = L_shl( etmp, Q3 ); // Q18 + etmp = divide3216( L_shr( bit_fracf, Q2 ), add( nb_bands, 1 ) ); /* Q15 */ + + bit_fracf = L_shl( etmp, Q3 ); /* Q18 */ + FOR( j = nb_bands - 1; j >= 0; j-- ) { - // bits_per_bands[j] = etmp; - // etmp += bit_fracf; - bits_per_bands[j] = L_add( bits_per_bands[j], L_shl( etmp, Q3 ) ); // Q18 + bits_per_bands[j] = L_add( bits_per_bands[j], L_shl( etmp, Q3 ) ); /* Q18 */ move32(); etmp = extract_l( L_add( etmp, L_shr( bit_fracf, Q3 ) ) ); } } ELSE -#endif { FOR( j = st_band; j < nb_bands; j++ ) { @@ -688,6 +660,7 @@ void bands_and_bit_alloc_ivas_fx( } } } + /*-------------------------------------------------------------------------- * Bit sum verification for GSC inactive at very high rate * The maximum number of bits per band of length 16 is 112 @@ -724,19 +697,20 @@ void bands_and_bit_alloc_ivas_fx( move32(); /* Q18 */ } } + /*-------------------------------------------------------------------------- * second step of bit sum verification, normally sum_bit == *bit *--------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + sum_bit = 0; move32(); FOR( i = 0; i < nb_bands; i++ ) { - // bits_per_bands[i] = (float)floor(bits_per_bands[i]); bits_per_bands[i] = L_shl( L_shr( bits_per_bands[i], Q18 ), Q18 ); move32(); sum_bit = L_add( sum_bit, L_shr( bits_per_bands[i], Q18 ) ); /*Q0*/ } + test(); IF( GSC_IVAS_mode != 0 && LT_32( sum_bit, *bit ) ) /* If we need to add bits, we are doing it on the LF */ { @@ -755,23 +729,7 @@ void bands_and_bit_alloc_ivas_fx( w_sum_bit = add( w_sum_bit, out_bits_per_bands[i] ); /* Q3 */ } tmp = shl( *bit, 3 ); -#else - IF( GT_16( tmp, w_sum_bit ) ) - { - i = sub( nb_bands, 1 ); - move16(); - FOR( ; tmp > w_sum_bit; w_sum_bit += ( 1 << 3 ) ) - { - out_bits_per_bands[i] = add( out_bits_per_bands[i], 1 << 3 ); - move16(); - i = sub( i, 1 ); - IF( i == 0 ) - { - i = sub( nb_bands, 1 ); - } - } - } -#endif + /*-------------------------------------------------------------------------- * Recompute the real number/length of frequency bands to encode *--------------------------------------------------------------------------*/ @@ -790,7 +748,6 @@ void bands_and_bit_alloc_ivas_fx( Copy( exc_diff + shl( max_ener_band[j], 4 ), concat_in + shl( j, 4 ), 16 ); } } -#if 1 // def ADD_LRTD } ELSE /* *bit == 0 */ { @@ -800,10 +757,11 @@ void bands_and_bit_alloc_ivas_fx( *pvq_len = 0; move16(); } -#endif + return; } -#if 1 // def ADD_LRTD + + /*-------------------------------------------------------------------* * reajust_bits() * @@ -924,26 +882,28 @@ static Word32 Find_bit_frac_fx( return ( L_out ); } -static Word16 Find_bit_alloc_IVAS_fx( /*o: Number of band to encode */ - const Word32 core_brate, /* i : core bit rate */ - const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ - const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ - const Word16 nb_tot_bands_in, /* i : total number of band */ - Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ - Word16 *max_ener_band, /* i/o: Energy based sorted order */ - Word16 *ener_vec, /* i/o: Energy per band order */ - Word32 *bits_per_bands /* o : Number of bit allowed per allowed subband Q18 */ + +/* o : Number of band to encode */ +static Word16 Find_bit_alloc_IVAS_fx( + const Word32 core_brate, /* i : core bit rate */ + const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ + const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ + const Word16 nb_tot_bands_in, /* i : total number of band */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + Word16 *max_ener_band, /* i/o: Energy based sorted order */ + Word16 *ener_vec, /* i/o: Energy per band order */ + Word32 *bits_per_bands /* o : Number of bit allowed per allowed subband Q18 */ ) { Word32 mp, mb, nb_bands_adj, bit_adj; Word16 nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; - Word32 SWB_bit_budget; // Q0 -> Q18 + Word32 SWB_bit_budget; /* Q0 -> Q18 */ Word16 i, j, nb_bands_max, st_band, nb_tot_bands_loc, etmp; Word32 sum_bit /*Q18*/, bit_fracf /*Q18*/; Word16 d_tmp, e_div, tmp16; Word32 Ltmp, etmp_32fx; - SWB_bit_budget = *bit; // Q0 + SWB_bit_budget = *bit; /* Q0 */ st_band = 5; nb_bands_max = nb_tot_bands_in; @@ -993,12 +953,12 @@ static Word16 Find_bit_alloc_IVAS_fx( /*o: Number IF( EQ_16( GSC_IVAS_mode, 1 ) && LT_32( core_brate, GSC_L_RATE_STG ) ) { /* nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f;*/ - nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, Q18 ) ), Q18_0_75 ); // Q18 + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, Q18 ) ), Q18_0_75 ); /* Q18 */ } ELSE IF( NE_16( GSC_IVAS_mode, 2 ) && GT_32( core_brate, GSC_H_RATE_STG ) ) { /*nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f;*/ - nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, Q18 ) ), Q18_1_2 ); // Q18 + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, Q18 ) ), Q18_1_2 ); /* Q18 */ } /*nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f);*/ @@ -1131,7 +1091,7 @@ static Word16 Find_bit_alloc_IVAS_fx( /*o: Number move32(); } mb = L_sub( mb, bit_fracf ); - SWB_bit_budget = L_sub( SWB_bit_budget, bits_per_bands[max_ener_band[j]] ); // Q18 + SWB_bit_budget = L_sub( SWB_bit_budget, bits_per_bands[max_ener_band[j]] ); /* Q18 */ } } @@ -1192,17 +1152,23 @@ static Word16 Find_bit_alloc_IVAS_fx( /*o: Number move32(); } } + return nb_tot_bands_loc; } -static Word16 Find_norm_inv_fx( const Word32 ToDivide, Word16 *e_div ) /* Find normalized 1 / ToDivide */ + +/* Find normalized 1 / ToDivide */ +static Word16 Find_norm_inv_fx( + const Word32 ToDivide, + Word16 *e_div ) { Word16 d_tmp, e_tmp; + e_tmp = norm_l( ToDivide ); d_tmp = round_fx( L_shl( ToDivide, e_tmp ) ); d_tmp = div_s( 16384, d_tmp ); /* 1.0 in Q14, dividend is normalize so >= 16384 as required for the division */ *e_div = sub( 14, e_tmp ); move16(); + return d_tmp; } -#endif diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index d2a576dbe..2e00e4641 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -793,7 +793,6 @@ void highband_exc_dct_in_fx( { IF( exc_diffQ[i] == 0 ) { - // PMT("code below to be validated for IVAS use") /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/ tmp = mult( shl( noisepb[0], 1 ), Random( seed_tcx ) ); /*Q15 */ tmp = shr( tmp, sub( 15, Qexc_diffQ ) ); /*qNoise_fac */ @@ -876,66 +875,7 @@ void highband_exc_dct_in_fx( /*--------------------------------------------------------------------------------------* * Apply decoded gain onto the difference signal *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( GSC_IVAS_mode >= 1 ) - { - float scale_factLF = 0.9f; - float scale_factHF = 0.9f; - - if ( GSC_IVAS_mode == 1 && GSC_noisy_speech == 0 ) - { - scale_factHF = 0.8f; - } - else if ( GSC_IVAS_mode == 2 || GSC_noisy_speech == 1 ) - { - scale_factHF = 0.71f; - } - else if ( GSC_IVAS_mode == 3 ) - { - scale_factHF = 0.9f; - } - for ( i = 0; i < pit_band_idx * 16; i++ ) - { - exc_diffQ[i] *= scale_factLF; - } - for ( ; i < L_frame; i++ ) - { - exc_diffQ[i] *= scale_factHF; - } - } - else if ( GSC_noisy_speech ) - { - float scale_fact = 0.9f; - - if ( element_mode == IVAS_CPE_TD ) - { - if ( coder_type == INACTIVE ) - { - scale_fact = 1.0f; - } - else - { - scale_fact = 0.95f; - } - } - else if ( element_mode > IVAS_SCE ) - { - scale_fact = 0.71f; - } - for ( i = 0; i < L_frame; i++ ) - { - exc_diffQ[i] *= scale_fact; - } - } - if ( GSC_noisy_speech && element_mode > IVAS_SCE && core_brate < ACELP_7k20 ) - { - for ( i = 80; i < L_frame; i++ ) - { - exc_diffQ[i] *= ( +0.0024f * (float) i + 1.192f ); - } - } -#else IF( GSC_noisy_speech ) { FOR( i = 0; i < L_frame; i++ ) @@ -944,7 +884,7 @@ void highband_exc_dct_in_fx( move16(); } } -#endif + Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc ); IF( exc_wo_nf != NULL ) @@ -1232,7 +1172,6 @@ void highband_exc_dct_in_ivas_fx( { IF( exc_diffQ[i] == 0 ) { - // PMT("code below to be validated for IVAS use") /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/ tmp = mult( shl( noisepb[0], 1 ), Random( seed_tcx ) ); /*Q15 */ tmp = shr( tmp, sub( 15, Qexc_diffQ ) ); /*qNoise_fac */ @@ -1313,105 +1252,86 @@ void highband_exc_dct_in_ivas_fx( } } } + /*--------------------------------------------------------------------------------------* * Apply decoded gain onto the difference signal *--------------------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + IF( GSC_IVAS_mode >= 1 ) { - // float scale_factLF = 0.9f; - Word16 scale_factLF = 29491; + Word16 scale_factLF = 29491; /* 0.9f */ move16(); - // float scale_factHF = 0.9f; - Word16 scale_factHF = 29491; + Word16 scale_factHF = 29491; /* 0.9f */ move16(); test(); test(); IF( EQ_16( GSC_IVAS_mode, 1 ) && GSC_noisy_speech == 0 ) { - // scale_factHF = 0.8f; scale_factHF = 26214; move16(); } ELSE IF( EQ_16( GSC_IVAS_mode, 2 ) || EQ_16( GSC_noisy_speech, 1 ) ) { - // scale_factHF = 0.71f; - scale_factHF = 23265; + scale_factHF = 23265; /* 0.71f */ move16(); } ELSE IF( EQ_16( GSC_IVAS_mode, 3 ) ) { - // scale_factHF = 0.9f; - scale_factHF = 29491; + scale_factHF = 29491; /* 0.9f */ move16(); } FOR( i = 0; i < pit_band_idx * 16; i++ ) { - // exc_diffQ[i] *= scale_factLF; exc_diffQ[i] = mult_r( exc_diffQ[i], scale_factLF ); } FOR( ; i < L_frame; i++ ) { - // exc_diffQ[i] *= scale_factHF; exc_diffQ[i] = mult_r( exc_diffQ[i], scale_factHF ); move16(); } } ELSE IF( GSC_noisy_speech ) { - // float scale_fact = 0.9f; - Word16 scale_fact = 29491; + Word16 scale_fact = 29491; /* 0.9f */ move16(); IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { IF( coder_type == INACTIVE ) { - // scale_fact = 1.0f; - scale_fact = 32767; + scale_fact = 32767; /* 1.0f */ move16(); } ELSE { - // scale_fact = 0.95f; - scale_fact = 31129; + scale_fact = 31129; /* 0.95f */ move16(); } } ELSE IF( GT_16( element_mode, IVAS_SCE ) ) { - // scale_fact = 0.71f; - scale_fact = 23265; + scale_fact = 23265; /* 0.71f */ move16(); } FOR( i = 0; i < L_frame; i++ ) { - // exc_diffQ[i] *= scale_fact; exc_diffQ[i] = mult_r( exc_diffQ[i], scale_fact ); move16(); } } + IF( GSC_noisy_speech && GT_16( element_mode, IVAS_SCE ) && LT_32( core_brate, ACELP_7k20 ) ) { FOR( i = 80; i < L_frame; i++ ) { - // exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); + /* exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); */ exc_diffQ[i] = mult_r( shl( exc_diffQ[i], 1 ) /*Q16*/, (Word16) L_shr( L_add( 629 * i, 312475 ) /*Q18*/, Q4 ) /*Q14*/ ); move16(); } } -#else - IF( GSC_noisy_speech ) - { - FOR( i = 0; i < L_frame; i++ ) - { - exc_diffQ[i] = mult_r( exc_diffQ[i], 29491 ); - move16(); - } - } -#endif + Word16 Q_tmp = *Q_exc; move16(); Word16 Q_old = *Q_exc; diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index 9d905bcf2..2e9e5eb96 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -154,13 +154,8 @@ void pre_echo_att_fx( * In normal cases, just compute the energy of the frame *-------------------------------------------------------*/ - etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ -#ifdef ADD_LRTD - PMTE() + etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#else - etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#endif *Last_frame_ener_fx = etmp_fx; move32(); /*2*Q_new+1*/ } diff --git a/lib_com/options.h b/lib_com/options.h index 7d65c5eac..f2014f019 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -67,14 +67,11 @@ #define BASOP_NOGLOB_DECLARE_LOCAL #endif -#define IVAS_FLOAT_FIXED #define IVAS_FLOAT_FIXED_CONVERSIONS /* Temporary macro to keep track of intermediate flt to fixed and fixed to flt conversions */ #define MSAN_FIX #define FIX_TMP_714 #define BASOP_NOGLOB_TMP_715 #define EVS_FUNC_MODIFIED -//#define EVS_FLOAT_ENC -#define IVAS_CNST #define REMOVE_IVAS_UNUSED_PARAMETERS_WARNING /*temporary operation on unused EVS parameters to remove warnings, these parameters will be used in IVAS */ #define MOD_BIT_ALLOC_ROM_TABLE /* Just to highlight modification in bit allocation table and to ensure these modifications doesn't affect EVS modes*/ #define SIMPLIFY_CODE_BE // Simplify synthesis loop diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 5a6e24046..6f5519f68 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4866,24 +4866,18 @@ Word16 est_tilt_fx( /* o : tilt of the code const Word32 gain_code, /* i : algebraic code gain Q16 */ Word16 *voice_fac, /* o : voicing factor Q15 */ const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#ifdef ADD_LRTD - , - const Word16 L_subfr /* i : Sub frame lenght */ -#endif ); -Word16 est_tilt_ivas_fx( /* o : tilt of the code Q15 */ - const Word16 *exc, /* i : adaptive excitation vector Qx */ - const Word16 gain_pit, /* i : adaptive gain Q14 */ - const Word16 *code, /* i : algebraic excitation vector Q9 */ - const Word32 gain_code, /* i : algebraic code gain Q16 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#if 1 // def ADD_LRTD - , - const Word16 L_subfr, /* i : Sub frame length */ - const Word16 flag_tilt /* i : flag for special tilt */ -#endif +/* o : tilt of the code Q15 */ +Word16 est_tilt_ivas_fx( + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic excitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc, /* i : Scaling factor of excitation Q0 */ + const Word16 L_subfr, /* i : Sub frame length */ + const Word16 flag_tilt /* i : flag for special tilt */ ); Word16 Est_tilt2( /* o : tilt of the code */ @@ -7127,30 +7121,21 @@ void dec_pit_exc_fx( const Word16 nb_subfr_fx /* i : Number of subframe considered */ , Word16 *gain_buf /*Q14*/ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ); void dec_pit_exc_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 coder_type, /* i : coding type */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *code_fx, /* o : innovation */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 nb_subfr_fx /* i : Number of subframe considered */ - , - Word16 *gain_buf /*Q14*/ -#if 1 // def ADD_LRTD - , + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 coder_type, /* i : coding type */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *code_fx, /* o : innovation */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 nb_subfr_fx, /* i : Number of subframe considered */ + Word16 *gain_buf, /*Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ); // pit_dec_fx.c @@ -7205,28 +7190,24 @@ Word16 pit_decode_fx( /* o : floating pitch value Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ const Word16 L_subfr /* i : subframe length */ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ); -Word16 pit_decode_ivas_fx( /* o : floating pitch value */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - Word16 *T0, /* o : close loop integer pitch */ - Word16 *T0_frac, /* o : close loop fractional part of the pitch */ - Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ - Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ +/* o : floating pitch value */ +Word16 pit_decode_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ ); void pit_Q_dec_fx( diff --git a/lib_com/syn_filt_fx.c b/lib_com/syn_filt_fx.c index 6e0f7e716..968cc8359 100644 --- a/lib_com/syn_filt_fx.c +++ b/lib_com/syn_filt_fx.c @@ -639,25 +639,7 @@ void synth_mem_updt2( { lerp( old_exc + L_EXC_MEM - last_L_frame, old_exc + L_EXC_MEM - L_frame, L_frame, last_L_frame ); } -#ifdef ADD_LRTD - IF( EQ_16( dec, DEC_IVAS ) ) - { - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - /* find scaling factor */ - PME() - en1 = 1.25f * sum2_f( mem_syn2, M ); - en2 = sum2_f( mem_syn_r + L_SYN_MEM - M, M ); - loc_rat = sqrtf( en2 ) / ( sqrtf( en1 ) + 0.01f ); - /* scale synthesis filter memory */ - FOR( i = 0; i < M; i++ ) - { - mem_syn_r[L_SYN_MEM - M + i] *= loc_rat; - } - } - } -#endif /*Resamp memory*/ /*Size of LPC syn memory*/ /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 1b2207491..903a37163 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -107,9 +107,6 @@ ivas_error acelp_core_dec_fx( Word16 uc_two_stage_flag, dec; Word16 nb_bits, indice; Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; -#ifdef ADD_LRTD - Word16 *p_tdm_Pri_pitch_buf; -#endif MUSIC_POSTFILT_HANDLE hMusicPF; BPF_DEC_HANDLE hBPF; TD_BWE_DEC_HANDLE hBWE_TD; @@ -359,9 +356,6 @@ ivas_error acelp_core_dec_fx( tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; -#ifdef ADD_LRTD - p_tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; -#endif move16(); move16(); move16(); @@ -380,9 +374,6 @@ ivas_error acelp_core_dec_fx( move16(); } tdm_Pitch_reuse_flag = 0; -#ifdef ADD_LRTD - p_tdm_Pri_pitch_buf = NULL; -#endif move16(); } /*----------------------------------------------------------------* @@ -830,86 +821,10 @@ ivas_error acelp_core_dec_fx( /*-----------------------------------------------------------------* * LSF de-quantization and interpolation *-----------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( !tdm_lp_reuse_flag ) -#endif - { - lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, - tdm_lsfQ_PCh ); - } -#ifdef ADD_LRTD - else - { - const float *pt_interp_2; -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->active_cnt != 1 ) - { - int16_t beta_index; - beta_index = get_next_indice( st, TDM_IC_LSF_PRED_BITS ); - tdm_SCh_lsf_reuse( DEC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, NULL, &beta_index ); - } - else - { - mvr2r( tdm_lspQ_PCh, lsp_new, M ); - mvr2r( tdm_lsfQ_PCh, lsf_new, M ); - } -#else - mvr2r( tdm_lspQ_PCh, lsp_new, M ); - mvr2r( tdm_lsfQ_PCh, lsf_new, M ); -#endif - if ( st->rate_switching_reset ) - { - /* extrapolation in case of unstable LSF convert */ - mvr2r( lsp_new, st->lsp_old, M ); - mvr2r( lsf_new, st->lsf_old, M ); - } - - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) - { - pt_interp_2 = interpol_frac2; - } + lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, + tdm_lsfQ_PCh ); - if ( st->active_cnt == 1 ) - { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - } - - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } - - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - old_exc_s = st->old_exc + L_EXC_MEM_DEC - st->L_frame; - tmpF = *old_exc_s; - st->mem_deemph = old_exc_s[st->L_frame - 1]; - preemph( old_exc_s, st->preemph_fac, L_FRAME16k, &tmpF ); - mvr2r( old_exc_s + st->L_frame - M, st->mem_syn2, M ); - residu( Aq, M, old_exc_s, old_exc + L_EXC_MEM_DEC - st->L_frame, st->L_frame ); - } - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ -#ifdef CR_FIX_639_HQ_ACELP_TRANSITION - if ( st->L_frame == L_FRAME ) - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - else - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } -#else - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); -#endif - } -#endif /*-----------------------------------------------------------------* * FEC - first good frame after lost frame(s) (possibility to correct the ACB) *-----------------------------------------------------------------*/ @@ -979,27 +894,7 @@ ivas_error acelp_core_dec_fx( test(); test(); -#ifdef ADD_LRTD - IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - IF( LE_16( st_fx->coder_type, UNVOICED ) ) - { - tdm_low_rate_dec( st_fx, dct_exc_tmp, &tmp_noise, pitch_buf, voice_factors, exc, exc2, bwe_exc, lsf_new ); - } - ELSE /* GENERIC */ - { - decod_gen_2sbfr( st_fx, sharpFlag, Aq, pitch_buf, voice_factors, exc, exc2, bwe_exc, gain_buf, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf ); - - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - tmp_noise = st_fx->lp_gainc_fx; - move16(); - } - } - } - else -#endif - IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) + IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) { /* SC-VBR - NELP frames */ Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, negate( st_fx->Q_exc ) ); // Q0 @@ -1033,12 +928,7 @@ ivas_error acelp_core_dec_fx( } ELSE IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) ) ) { - decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf -#ifdef ADD_LRTD - , - tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf -#endif - ); + decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf ); tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ } ELSE @@ -1676,10 +1566,7 @@ ivas_error acelp_core_dec_fx( move16(); } } -#ifdef ADD_LRTD - /* analyze pitch coherence for bass post-filter */ - bpf_pitch_coherence( st, pitch_buf ); -#endif + test(); IF( !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->bpf_off ) ) { diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 5c16bc3e9..9597a97ae 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1100,12 +1100,8 @@ ivas_error acelp_core_dec_ivas_fx( ELSE IF( EQ_16( st->coder_type, AUDIO ) || ( ( st->coder_type == INACTIVE ) && st->inactive_coder_type_flag ) ) { /* AUDIO and INACTIVE frames (coded by GSC technology) */ - decod_audio_ivas_fx( st, dct_exc_tmp_fx, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf_fx -#if 1 // def ADD_LRTD - , - tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx -#endif - ); + decod_audio_ivas_fx( st, dct_exc_tmp_fx, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf_fx, + tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ); tmp_noise_fx = shr_r( st->lp_gainc_fx, 3 ); /*Q0*/ } ELSE diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 52c3e3073..f984f2ce9 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1164,8 +1164,6 @@ ivas_error core_switching_post_dec_fx( error = IVAS_ERR_OK; move32(); - // PMT("core_switching_post_dec_fx : Only handles has been converted, code needs to be entirely reviewed ") - /* Rescale synthesis in Q0 to avoid multiple rescaling after */ tmp = Find_Max_Norm16( synth, output_frame ); Scale_sig( synth, output_frame, tmp ); @@ -1560,8 +1558,6 @@ ivas_error core_switching_post_dec_ivas_fx( error = IVAS_ERR_OK; move32(); - // PMT("core_switching_post_dec_fx : Only handles has been converted, code needs to be entirely reviewed ") - /* Rescale synthesis in Q0 to avoid multiple rescaling after */ tmp = Find_Max_Norm16( synth, output_frame ); Scale_sig( synth, output_frame, tmp ); /* Qsynth + tmp */ diff --git a/lib_dec/dec_amr_wb_fx.c b/lib_dec/dec_amr_wb_fx.c index baea98a2c..415b4584e 100644 --- a/lib_dec/dec_amr_wb_fx.c +++ b/lib_dec/dec_amr_wb_fx.c @@ -71,12 +71,8 @@ void decod_amr_wb_fx( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR -#ifdef ADD_LRTD - , - 0, NULL -#endif - ); + *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); + /*--------------------------------------------------------------* * Find the adaptive codebook vector *--------------------------------------------------------------*/ diff --git a/lib_dec/dec_pit_exc_fx.c b/lib_dec/dec_pit_exc_fx.c index 4e18eebce..746b66819 100644 --- a/lib_dec/dec_pit_exc_fx.c +++ b/lib_dec/dec_pit_exc_fx.c @@ -41,11 +41,6 @@ void dec_pit_exc_fx( const Word16 nb_subfr_fx /* i : Number of subframe considered */ , Word16 *gain_buf /*Q14*/ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ) { Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ @@ -179,12 +174,7 @@ void dec_pit_exc_fx( /*----------------------------------------------------------------------* * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx -#ifdef ADD_LRTD - , - tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf -#endif - ); + *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx ); move16(); /*--------------------------------------------------------------* @@ -207,12 +197,7 @@ void dec_pit_exc_fx( gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#ifdef ADD_LRTD - , - L_subfr_fx -#endif - ); + st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 ); move16(); } ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */ @@ -225,12 +210,7 @@ void dec_pit_exc_fx( gain_dec_lbr_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#ifdef ADD_LRTD - , - L_subfr_fx -#endif - ); + st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 ); move16(); } ELSE @@ -457,22 +437,18 @@ void dec_pit_exc_fx( /* _ None */ /*==========================================================================*/ void dec_pit_exc_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 coder_type, /* i : coding type */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */ - Word16 *code_fx, /* o : innovation */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 nb_subfr_fx /* i : Number of subframe considered */ - , - Word16 *gain_buf /*Q14*/ -#if 1 // def ADD_LRTD - , + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 coder_type, /* i : coding type */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */ + Word16 *code_fx, /* o : innovation */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 nb_subfr_fx, /* i : Number of subframe considered */ + Word16 *gain_buf, /*Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ) { Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ @@ -591,9 +567,11 @@ void dec_pit_exc_ivas_fx( set16_fx( st_fx->acelp_cfg.pitch_bits, 9, 4 ); set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, 5 ); } + /*------------------------------------------------------------------* * ACELP subframe loop *------------------------------------------------------------------*/ + p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ pt_gain = gain_buf; /* pointer to the gain buffer */ @@ -602,12 +580,8 @@ void dec_pit_exc_ivas_fx( /*----------------------------------------------------------------------* * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_ivas_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx -#if 1 // def ADD_LRTD - , - tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf -#endif - ); + + *pt_pitch_fx = pit_decode_ivas_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); move16(); /*--------------------------------------------------------------* @@ -623,6 +597,7 @@ void dec_pit_exc_ivas_fx( IF( EQ_16( use_fcb, 1 ) ) { inov_decode_fx( st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx ); + /*--------------------------------------------------------------* * Gain decoding * Estimate spectrum tilt and voicing @@ -630,18 +605,14 @@ void dec_pit_exc_ivas_fx( gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#if 1 // def ADD_LRTD - , - L_subfr_fx, 0 -#endif - ); + st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 ); move16(); } ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */ { /*inov_decode_fx(st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx);*/ inov_decode_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, 0, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx ); + /*--------------------------------------------------------------* * Gain decoding * Estimate spectrum tilt and voicing @@ -649,12 +620,7 @@ void dec_pit_exc_ivas_fx( gain_dec_lbr_ivas_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); - st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#if 1 // def ADD_LRTD - , - L_subfr_fx, 0 -#endif - ); + st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 ); move16(); } ELSE diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 945e149f2..5a12d1a2c 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -333,7 +333,7 @@ ivas_error evs_dec_fx( /*---------------------------------------------------------------------* * Preprocessing (preparing) for ACELP/HQ core switching *---------------------------------------------------------------------*/ - // PMT("core_switching_pre_dec_fx missign args") + IF( ( error = core_switching_pre_dec_fx( st_fx, output_frame ) ) != IVAS_ERR_OK ) { return error; @@ -346,7 +346,6 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ - IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) { return error; @@ -356,12 +355,11 @@ ivas_error evs_dec_fx( } ELSE { - // PMT("HQ core missing args") - hq_core_dec_fx( st_fx, synth_fx, &Q_synth, output_frame, hq_core_type, core_switching_flag ); Qpostd = Q_synth; move16(); } + /*---------------------------------------------------------------------* * Postprocessing for ACELP/HQ core switching *---------------------------------------------------------------------*/ @@ -382,7 +380,6 @@ ivas_error evs_dec_fx( * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - /// PMT("bw_switching_pre_proc_fx missing args") bw_switching_pre_proc_fx( old_syn_12k8_16k_fx, st_fx ); /*---------------------------------------------------------------------* @@ -1372,7 +1369,7 @@ ivas_error evs_dec_fx( /*----------------------------------------------------------------* * Save synthesis for HQ FEC *----------------------------------------------------------------*/ - // PMT("The code below could be move to save_synthesis_hq_fec") + post_hq_delay = NS2SA_FX2( st_fx->output_Fs, POST_HQ_DELAY_NS ); IF( EQ_16( st_fx->codec_mode, MODE1 ) ) { diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 3a39f9e33..a80cfe796 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -75,12 +75,7 @@ void decod_audio_fx( /* decode GSC SWB speech flag */ test(); -#if !defined ADD_LRTD IF( st_fx->coder_type != INACTIVE && GE_32( st_fx->total_brate, ACELP_13k20 ) ) -#else - if ( st_fx->GSC_IVAS_mode >= 1 || ( st_fx->coder_type != INACTIVE && ( ( st_fx->element_mode == EVS_MONO && st_fx->total_brate >= ACELP_13k20 ) || - ( st_fx->element_mode > EVS_MONO && st_fx->total_brate > MIN_BRATE_GSC_NOISY_FLAG && st_fx->bwidth >= SWB && !st_fx->flag_ACELP16k ) ) ) ) -#endif { st_fx->GSC_noisy_speech = (Word16) get_next_indice_fx( st_fx, 1 ); /* Q0 */ move16(); @@ -98,30 +93,17 @@ void decod_audio_fx( } /* set bit-allocation */ -#ifdef ADD_LRTD -#ifdef NONBE_FIX_GSC_BSTR - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif -#else #ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif #endif /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ -#if defined ADD_LRTD - test(); - test(); - IF( st_fx->GSC_IVAS_mode >= 1 || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && st_fx->GSC_IVAS_mode == 0 ) ) -#else + IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) ) -#endif { nb_subfr = NB_SUBFR; /* Q0 */ move16(); @@ -129,25 +111,6 @@ void decod_audio_fx( move16(); hGSCDec->noise_lev = NOISE_LEVEL_SP3; /* Q0 */ move16(); -#ifdef ADD_LRTD - if ( st_fx->GSC_IVAS_mode >= 1 ) - { - if ( st_fx->core_brate < GSC_L_RATE_STG && st_fx->GSC_IVAS_mode < 3 ) - { - nb_subfr = 2; - } - hGSCDec->noise_lev = NOISE_LEVEL_SP2; - - if ( st_fx->GSC_IVAS_mode == 3 ) /* Music like */ - { - hGSCDec->noise_lev = NOISE_LEVEL_SP0; - } - else if ( st_fx->GSC_noisy_speech == 0 ) /* speech like but not noisy */ - { - hGSCDec->noise_lev = NOISE_LEVEL_SP3; - } - } -#endif } ELSE { @@ -165,54 +128,30 @@ void decod_audio_fx( /*---------------------------------------------------------------* * Decode number of subframes *---------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( st_fx->L_frame == L_FRAME16k && ( st_fx->core_brate <= ACELP_13k20 || st_fx->coder_type == INACTIVE ) ) - { - hGSCDec->cor_strong_limit = 0; - nb_subfr = 1; - } - else -#endif + + + hGSCDec->cor_strong_limit = 1; /* Q0 */ + move16(); + nb_subfr = SWNB_SUBFR; + move16(); + + IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) { - hGSCDec->cor_strong_limit = 1; /* Q0 */ + nbits = 1; move16(); - nb_subfr = SWNB_SUBFR; + nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ move16(); - IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) + IF( s_and( nb_frame_flg, 0x1 ) == 0 ) { - nbits = 1; + nb_subfr = 2 * SWNB_SUBFR; /* Q0 */ move16(); -#ifdef ADD_LRTD - if ( st_fx->L_frame == L_FRAME16k && st_fx->core_brate >= MIN_RATE_4SBFR ) - { - nbits = 2; - } -#endif - nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ + hGSCDec->cor_strong_limit = 0; move16(); - - IF( s_and( nb_frame_flg, 0x1 ) == 0 ) - { - nb_subfr = 2 * SWNB_SUBFR; /* Q0 */ - move16(); - hGSCDec->cor_strong_limit = 0; - move16(); - } -#ifdef ADD_LRTD - else if ( st_fx->L_frame == L_FRAME16k && st_fx->core_brate >= MIN_RATE_4SBFR ) - { - nb_subfr = 2 * SWNB_SUBFR; /* cor_strong already set to 1 */ - } - - if ( ( nb_frame_flg >> 1 ) == 1 ) - { - nb_subfr *= 2; - } -#endif } } } + /*---------------------------------------------------------------* * Decode the last band where the adaptive (pitch) contribution is significant *---------------------------------------------------------------*/ @@ -282,13 +221,7 @@ void decod_audio_fx( * Decode adaptive (pitch) excitation contribution *---------------------------------------------------------------*/ test(); -#ifdef ADD_LRTD - if ( !( st_fx->GSC_IVAS_mode > 0 && st_fx->L_frame / nb_subfr == 2 * L_SUBFR && st_fx->GSC_IVAS_mode < 3 ) && - ( ( st_fx->core_brate >= MIN_RATE_FCB || st_fx->GSC_noisy_speech ) && - ( ( nb_subfr == NB_SUBFR && st_fx->L_frame == L_FRAME ) || ( nb_subfr == NB_SUBFR16k && st_fx->L_frame == L_FRAME16k ) ) ) ) -#else IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) && EQ_16( nb_subfr, NB_SUBFR ) ) -#endif { Word16 indice; nbits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( st_fx->core_brate, GENERIC, -1, -1 )]; /* Q0 */ @@ -303,11 +236,9 @@ void decod_audio_fx( Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); } -#ifdef ADD_LRTD - dec_pit_exc_fx( st_fx, Aq, coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); -#else + dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf ); -#endif + IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) { minimum_fx( pitch_buf, shr( st_fx->L_frame, 6 ), &low_pit ); @@ -449,29 +380,12 @@ void decod_audio_fx( tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ } - - test(); -#if defined ADD_LRTD - test(); - if ( EQ_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->idchan == 0 ) -#else test(); if ( st_fx->coder_type == INACTIVE && LE_32( st_fx->core_brate, ACELP_9k60 ) ) -#endif { tmp_nb_bits_tot = add( tmp_nb_bits_tot, 5 ); /* Q0 */ } -#ifdef ADD_LRTD - IF( EQ_16( st_fx->idchan, 1 ) ) - { - tmp_nb_bits_tot = add( tmp_nb_bits_tot, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ); - IF( EQ_16( st_fx->tdm_LRTD_flag, 1 ) ) - { - tmp_nb_bits_tot = sub( tmp_nb_bits_tot, STEREO_BITS_TCA ); - } - } -#endif gsc_dec_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, st_fx->Q_exc ); /*--------------------------------------------------------------------------------------* * iDCT transform @@ -612,26 +526,19 @@ void decod_audio_ivas_fx( } /* set bit-allocation */ -#if 1 // def ADD_LRTD #ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ -#if 1 // defined ADD_LRTD + test(); test(); IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && st_fx->GSC_IVAS_mode == 0 ) ) -#else - IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) ) -#endif { nb_subfr = NB_SUBFR; /* Q0 */ move16(); @@ -639,7 +546,7 @@ void decod_audio_ivas_fx( move16(); hGSCDec->noise_lev = NOISE_LEVEL_SP3; /* Q0 */ move16(); -#if 1 // def ADD_LRTD + IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) ) { test(); @@ -662,7 +569,6 @@ void decod_audio_ivas_fx( move16(); } } -#endif } ELSE { @@ -680,7 +586,7 @@ void decod_audio_ivas_fx( /*---------------------------------------------------------------* * Decode number of subframes *---------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); test(); IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && ( LE_32( st_fx->core_brate, ACELP_13k20 ) || st_fx->coder_type == INACTIVE ) ) @@ -691,7 +597,6 @@ void decod_audio_ivas_fx( move16(); } ELSE -#endif { hGSCDec->cor_strong_limit = 1; /* Q0 */ move16(); @@ -702,14 +607,14 @@ void decod_audio_ivas_fx( { nbits = 1; /* Q0 */ move16(); -#if 1 // def ADD_LRTD + test(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { nbits = 2; /* Q0 */ move16(); } -#endif + nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ move16(); @@ -721,7 +626,6 @@ void decod_audio_ivas_fx( hGSCDec->cor_strong_limit = 0; move16(); } -#if 1 // def ADD_LRTD ELSE IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { nb_subfr = 2 * SWNB_SUBFR; /* cor_strong already set to 1 */ @@ -732,18 +636,17 @@ void decod_audio_ivas_fx( { nb_subfr = shl( nb_subfr, 1 ); /* Q0 */ } -#endif } } } -#if 1 + test(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) && EQ_16( nb_subfr, NB_SUBFR ) ) { nb_subfr = NB_SUBFR16k; /* Q0 */ move16(); } -#endif + /*---------------------------------------------------------------* * Decode the last band where the adaptive (pitch) contribution is significant *---------------------------------------------------------------*/ @@ -802,7 +705,6 @@ void decod_audio_ivas_fx( hGSCDec->Last_GSC_pit_band_idx = pit_band_idx; /* Q0 */ move16(); - /*--------------------------------------------------------------------------------------* * Decode adaptive (pitch) excitation contribution * Reset unvaluable part of the adaptive (pitch) excitation contribution @@ -813,7 +715,6 @@ void decod_audio_ivas_fx( * Decode adaptive (pitch) excitation contribution *---------------------------------------------------------------*/ test(); -#if 1 // def ADD_LRTD test(); test(); test(); @@ -824,9 +725,6 @@ void decod_audio_ivas_fx( IF( !( ( st_fx->GSC_IVAS_mode > 0 ) && EQ_16( idiv1616( st_fx->L_frame, nb_subfr ), 2 * L_SUBFR ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) && ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || st_fx->GSC_noisy_speech ) && ( ( EQ_16( nb_subfr, NB_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && EQ_16( st_fx->L_frame, L_FRAME16k ) ) ) ) ) -#else - IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) && EQ_16( nb_subfr, NB_SUBFR ) ) -#endif { Word16 indice; nbits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( st_fx->core_brate, GENERIC, -1, -1 )]; /* Q0 */ @@ -841,11 +739,9 @@ void decod_audio_ivas_fx( Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); } -#if 1 // def ADD_LRTD + dec_pit_exc_ivas_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); -#else - dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf ); -#endif + IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) { minimum_fx( pitch_buf, shr( st_fx->L_frame, 6 ), &low_pit ); @@ -989,17 +885,12 @@ void decod_audio_ivas_fx( test(); -#if 1 // defined ADD_LRTD test(); if ( st_fx->coder_type == INACTIVE && LE_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->idchan == 0 ) -#else - if ( EQ_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, ACELP_9k60 ) ) -#endif { tmp_nb_bits_tot = add( tmp_nb_bits_tot, 5 ); /* Q0 */ } -#if 1 // ydef ADD_LRTD IF( EQ_16( st_fx->idchan, 1 ) ) { tmp_nb_bits_tot = add( tmp_nb_bits_tot, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ); /* Q0 */ @@ -1008,7 +899,7 @@ void decod_audio_ivas_fx( tmp_nb_bits_tot = sub( tmp_nb_bits_tot, STEREO_BITS_TCA ); /* Q0 */ } } -#endif + Word16 Q_exc_old = st_fx->Q_exc; move16(); gsc_dec_ivas_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, &st_fx->Q_exc ); @@ -1105,7 +996,6 @@ void gsc_dec_fx( Word16 Q_exc ) { Word16 i, j, bit, nb_subbands, pvq_len; -#if 1 // def ADD_LRTD Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; Word16 bitallocation_exc[2]; Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k]; @@ -1113,15 +1003,6 @@ void gsc_dec_fx( Word16 exc_diffQ[L_FRAME16k]; Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; Word16 concat_out[L_FRAME16k]; -#else - Word16 bitallocation_band[MBANDS_GN]; - Word16 bitallocation_exc[2]; - Word16 Ener_per_bd_iQ[MBANDS_GN]; - Word16 max_ener_band[MBANDS_GN]; - Word16 exc_diffQ[L_FRAME]; - Word16 bits_per_bands[MBANDS_GN]; - Word16 concat_out[L_FRAME]; -#endif Word16 inpulses_fx[NB_SFM]; Word16 imaxpulse_fx[NB_SFM]; Word16 mean_gain; @@ -1145,22 +1026,7 @@ void gsc_dec_fx( *--------------------------------------------------------------------------------------*/ bit = bits_used; move16(); -#ifdef ADD_LRTD - test(); - test(); - test(); - test(); - IF( EQ_16( coder_type, INACTIVE ) && ( EQ_16( st_fx->tdm_LRTD_flag, 1 ) || EQ_16( st_fx->element_mode, IVAS_SCE ) ) && LE_32( st_fx->core_brate, GSC_LRES_GAINQ_LIMIT ) ) - { - bit = add( bit, GSC_LRES_NB_NITS ); - } - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Mbands_gn = MBANDS_GN16k; - move16(); - } -#endif set16_fx( exc_diffQ, 0, st_fx->L_frame ); /*--------------------------------------------------------------------------------------* @@ -1184,33 +1050,8 @@ void gsc_dec_fx( } ELSE { - -#ifdef ADD_LRTD - i = 0; - move16(); - While( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) - { - IF( LQ_32( st_fx->core_brate, brate_intermed_tbl[i] ) ) - { - break; - } - i = add( i, 1 ); - } - - test(); - test(); - test(); - test(); - IF( GT_16( st_fx->element_mode, EVS_MONO ) > &&EQ_16( coder_type, AUDIO ) && - LE_32( st_fx->core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation is mapped to 8 kb/s instead of 9.6 kb/s in this case */ - { - i--; - } - mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); - -#else mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q12 */ -#endif + st_fx->lp_gainc_fx = mult_r( 640, mean_gain ); /*10 in Q6 x Q12 -> lp_gainc in Q3 */ move16(); } @@ -1236,10 +1077,7 @@ void gsc_dec_fx( * reduce spectral dynamic * save spectrum *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - max_eq = 32767; - move16(); -#endif + test(); IF( EQ_16( st_fx->last_good, INACTIVE_CLAS ) || EQ_16( st_fx->Last_GSC_noisy_speech_flag, 1 ) ) { @@ -1270,12 +1108,6 @@ void gsc_dec_fx( max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech, st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); -#ifdef ADD_LRTD - if ( bit == 0 ) - { - set16_fx( concact_out, 0, L_FRAME16k ); - } -#endif { pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ @@ -1283,17 +1115,6 @@ void gsc_dec_fx( seed_init = 0; move16(); -#ifdef ADD_LRTD - max_eq = 0.0f; - max_eq_val = 1.0f; - - if ( ( ( st_fx->core_brate < ACELP_7k20 && st_fx->GSC_noisy_speech == 1 ) || st_fx->core_brate < 6000 ) && coder_type <= UNVOICED ) - { - j = emaximum( concat_out, nb_subbands * 16, &max_eq ); - max_eq = (float) ( max_eq_val / ( fabs( concat_out[j] ) + 0.01f ) ); - max_eq = min( max_eq_val, max_eq ); - } -#endif /* Reorder Q bands */ FOR( j = 0; j < nb_subbands; j++ ) { @@ -1350,34 +1171,8 @@ void gsc_dec_fx( * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal * Gain is based on the inter-correlation gain between the pulses found and residual signal *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - test(); - test(); - test(); - test(); - test(); - test(); - IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) - { - FOR( i = 64; i < st_fx->L_frame; i++ ) - { - PMT( "GSC FIX point to be done here" ) - exc_diffQ[i] *= max_eq; - } - } - ELSE IF( ( ( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) || LT_32( st_fx->core_brate, 6000 ) ) && LE_16( st_fx->coder_type, UNVOICED ) ) - { - FOR( i = 0; i < L_FRAME; i++ ) - { - PMT( "GSC FIX point to be done here" ) - exc_diffQ[i] *= max_eq; - } - } - else -#endif - { - freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); - } + + freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); } /*--------------------------------------------------------------------------------------* @@ -1432,7 +1227,6 @@ void gsc_dec_ivas_fx( Word16 *Q_exc ) { Word16 i, j, bit, nb_subbands, pvq_len; -#if 1 // def ADD_LRTD Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; Word16 bitallocation_exc[2]; Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k]; @@ -1441,19 +1235,10 @@ void gsc_dec_ivas_fx( Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; Word16 concat_out[L_FRAME16k]; Word16 max_eq, max_eq_val; -#else - Word16 bitallocation_band[MBANDS_GN]; - Word16 bitallocation_exc[2]; - Word16 Ener_per_bd_iQ[MBANDS_GN]; - Word16 max_ener_band[MBANDS_GN]; - Word16 exc_diffQ[L_FRAME]; - Word16 bits_per_bands[MBANDS_GN]; - Word16 concat_out[L_FRAME]; -#endif Word16 inpulses_fx[NB_SFM]; Word16 imaxpulse_fx[NB_SFM]; Word16 mean_gain; - Word16 Mbands_gn = 16; + Word16 Mbands_gn = MBANDS_GN; Word16 Qexc_diffQ = Q_PVQ_OUT; Word32 L_tmp; Word16 Q_tmp; @@ -1461,8 +1246,8 @@ void gsc_dec_ivas_fx( GSC_DEC_HANDLE hGSCDec; hGSCDec = st_fx->hGSCDec; - move16(); // for Mbands_gn - move16(); // for Qexc_diffQ + move16(); /* for Mbands_gn */ + move16(); /* for Qexc_diffQ */ set16_fx( inpulses_fx, 0, NB_SFM ); set16_fx( imaxpulse_fx, 0, NB_SFM ); @@ -1471,7 +1256,7 @@ void gsc_dec_ivas_fx( *--------------------------------------------------------------------------------------*/ bit = bits_used; move16(); -#if 1 // def ADD_LRTD + test(); test(); test(); @@ -1485,7 +1270,7 @@ void gsc_dec_ivas_fx( Mbands_gn = MBANDS_GN16k; /* Q0 */ move16(); } -#endif + set16_fx( exc_diffQ, 0, st_fx->L_frame ); /*--------------------------------------------------------------------------------------* @@ -1509,8 +1294,6 @@ void gsc_dec_ivas_fx( } ELSE { - -#if 1 // def ADD_LRTD i = 0; move16(); WHILE( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) @@ -1532,9 +1315,6 @@ void gsc_dec_ivas_fx( } mean_gain = gsc_gaindec_ivas_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ -#else - mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); -#endif st_fx->lp_gainc_fx = mult_r( 640, mean_gain ); /*10 in Q6 x Q12 -> lp_gainc in Q3 */ move16(); } @@ -1560,17 +1340,17 @@ void gsc_dec_ivas_fx( * reduce spectral dynamic * save spectrum *--------------------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + max_eq = 32767; move16(); -#endif + test(); IF( EQ_16( st_fx->last_good, INACTIVE_CLAS ) || EQ_16( st_fx->Last_GSC_noisy_speech_flag, 1 ) ) { FOR( i = 0; i < st_fx->L_frame; i++ ) { L_tmp = L_shr( L_mult( Random( &hGSCDec->seed_tcx ), 26214 ), 5 ); /*Q10*/ - L_tmp = L_mac( L_tmp, hGSCDec->Last_GSC_spectrum_fx[i], 6554 ); /* Q10 */ + L_tmp = L_mac( L_tmp, hGSCDec->Last_GSC_spectrum_fx[i], 6554 ); /*Q10*/ hGSCDec->Last_GSC_spectrum_fx[i] = round_fx( L_tmp ); /*Q10*/ move16(); } @@ -1594,27 +1374,24 @@ void gsc_dec_ivas_fx( max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech, st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); -#if 1 // def ADD_LRTD IF( bit == 0 ) { set16_fx( concat_out, 0, L_FRAME16k ); } -#endif - { - pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); + + pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); #ifdef MSAN_FIX - IF( nb_subbands > 0 ) - { - Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ - } -#else + IF( nb_subbands > 0 ) + { Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ -#endif } +#else + Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ +#endif + seed_init = 0; move16(); -#if 1 // def ADD_LRTD max_eq = 0; move16(); max_eq_val = 32767; /* 1.0f in Q15 */ @@ -1626,7 +1403,6 @@ void gsc_dec_ivas_fx( IF( ( ( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) || LT_32( st_fx->core_brate, 6000 ) ) && LE_16( coder_type, UNVOICED ) ) { j = maximum_fx( concat_out, imult1616( nb_subbands, 16 ), &max_eq ); - // max_eq = max_eq_val / (abs_s(concat_out[j]) + 328 /*0.01f*/ ); Word16 temp_max_eq = add( abs_s( concat_out[j] ), 10 ) /*0.01f in Q10*/; if ( LE_16( temp_max_eq, ONE_IN_Q10 ) ) { @@ -1641,7 +1417,7 @@ void gsc_dec_ivas_fx( max_eq = shl( max_eq, exp ); /* Q15 */ } } -#endif + /* Reorder Q bands */ FOR( j = 0; j < nb_subbands; j++ ) { @@ -1701,7 +1477,7 @@ void gsc_dec_ivas_fx( * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal * Gain is based on the inter-correlation gain between the pulses found and residual signal *--------------------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); test(); test(); @@ -1710,8 +1486,6 @@ void gsc_dec_ivas_fx( { FOR( i = 64; i < st_fx->L_frame; i++ ) { - // PMT("GSC FIX point to be done here") - // exc_diffQ[i] *= max_eq; exc_diffQ[i] = mult_r( exc_diffQ[i], max_eq ); /* Q_PVQ_OUT */ move16(); } @@ -1720,14 +1494,11 @@ void gsc_dec_ivas_fx( { FOR( i = 0; i < L_FRAME; i++ ) { - // PMT("GSC FIX point to be done here") - // exc_diffQ[i] *= max_eq; exc_diffQ[i] = mult_r( exc_diffQ[i], max_eq ); /* Q_PVQ_OUT */ move16(); } } ELSE -#endif { freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); } @@ -1768,17 +1539,11 @@ void GSC_dec_init( move16(); move16(); -#ifdef ADD_LRTD - set16_fx( hGSCDec->Last_GSC_spectrum_fx, 0, L_FRAME16k ); - set16_fx( hGSCDec->last_exc_dct_in_fx, 0, L_FRAME16k ); - set16_fx( hGSCDec->lt_ener_per_band_fx, 4096, MBANDS_GN_BITALLOC16k ); - set16_fx( hGSCDec->old_y_gain_fx, 0, MBANDS_GN_BITALLOC16k ); -#else set16_fx( hGSCDec->Last_GSC_spectrum_fx, 0, L_FRAME ); set16_fx( hGSCDec->last_exc_dct_in_fx, 0, L_FRAME ); set16_fx( hGSCDec->old_y_gain_fx, 0, MBANDS_GN ); set16_fx( hGSCDec->lt_ener_per_band_fx, 4096, MBANDS_GN ); /*Q12*/ -#endif + hGSCDec->last_ener_fx = 0; move16(); set16_fx( hGSCDec->last_bitallocation_band, 0, 6 ); diff --git a/lib_dec/inov_dec_fx.c b/lib_dec/inov_dec_fx.c index ef65c4fcd..1ab1efe8f 100644 --- a/lib_dec/inov_dec_fx.c +++ b/lib_dec/inov_dec_fx.c @@ -113,7 +113,7 @@ void inov_decode_fx( move16(); bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ), 15 ); // Q0 move16(); - // PMT("CONDITION above is missing -> idchan") + FOR( i = 0; i < wordcnt; i++ ) { indexing_indices[i] = extract_l( get_next_indice_fx( st_fx, 16 ) ); // Q0 @@ -298,7 +298,7 @@ void inov_decode_ivas_fx( move16(); bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ), 15 ); // Q0 move16(); - // PMT("CONDITION above is missing -> idchan") + FOR( i = 0; i < wordcnt; i++ ) { indexing_indices[i] = get_next_indice_fx( st_fx, 16 ); // Q0 diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index 50b5ec341..becf60759 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -664,12 +664,7 @@ void lsf_end_dec_fx( test(); test(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - test(); - IF( ( EQ_16( coder_type_org, GENERIC ) ) && ( EQ_32( st->sr_core, INT_FS_16k ) ) && ( mode2_flag == 0 ) && ( st->idchan == 0 ) ) -#else IF( ( EQ_16( coder_type_org, GENERIC ) ) && ( EQ_32( st->sr_core, INT_FS_16k ) ) && ( mode2_flag == 0 ) ) -#endif { /* this bit is used only for primary channel or mono */ coder_type = (Word16) get_next_indice_fx( st, 1 ); /* Q0 */ diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c index b72c2bae1..1d3e96497 100644 --- a/lib_dec/pit_dec_fx.c +++ b/lib_dec/pit_dec_fx.c @@ -333,11 +333,6 @@ Word16 pit_decode_fx( /* o : floating pitch value Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ const Word16 L_subfr /* i : subframe length */ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ) { Word16 pitch; /*Q2*/ @@ -458,57 +453,6 @@ Word16 pit_decode_fx( /* o : floating pitch value pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); } -#ifdef ADD_LRTD - ELSE IF( EQ_16( st_fx->idchan, 1 ) && ( EQ_16( tdm_Pitch_reuse_flag, 1 ) || EQ_16( nBits, 4 ) ) ) - { - test(); - test(); - /*-------------------------------------------------------* - * Pitch decoding with reusing of primary channel information - *-------------------------------------------------------*/ - Word16 loc_T0, loc_frac, delta, pit_tmp1, pit_tmp2, isubfridx; - - delta = 4; - pit_flag = L_SUBFR; - move16(); - move16(); - isubfridx = shr( i_subfr, 6 ); - IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) - { - move16(); - move16(); - pit_tmp1 = tdm_Pri_pitch_buf[isubfridx]; /*tdm_Pri_pitch_buf in Q6 ->pit_tmp1 and 2 in Q6 too */ - pit_tmp2 = tdm_Pri_pitch_buf[shr( add( i_subfr, 1 ), 6 )]; - /*loc_T0 = (int16_t)(0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]);*/ - loc_T0 = mac_r( L_mult( 16384, pit_tmp1, 16384, pit_tmp2 ) ); - /*loc_frac = (int16_t)(((0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]) - loc_T0) * 4.0f);*/ - } - ELSE - { - /*loc_T0 = (int16_t)tdm_Pri_pitch_buf[i_subfr / L_SUBFR];*/ - loc_T0 = tdm_Pri_pitch_buf[isubfridx]; /*Q6*/ - /*loc_frac = (int16_t)((tdm_Pri_pitch_buf[i_subfr / L_SUBFR] - loc_T0) * 4.0f);*/ - } - loc_frac = shr(sub(loc_T0, shl(shr(loc_T0, 6), 6)), 4)); /* Final result in Q 2*/ - loc_T0 = shr( loc_T0, 6 ); /*Q6 -> Q0*/ - - - limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max ); - - IF( nBits > 0 ) - { - pit_Q_dec_fx( 0, pitch_index, nBits, delta, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - ELSE - { - *T0 = loc_T0; - *T0_frac = loc_frac; - move16(); - move16(); - } - printf( "function not tested yet\n" ); - } -#endif ELSE { /*-------------------------------------------------------* diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 3c1065c24..530cd41d0 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -529,32 +529,17 @@ typedef struct tcx_dec_structure typedef struct gsc_dec_structure { - Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ - - Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - // Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - - Word16 old_y_gain_fx[MBANDS_GN16k]; /* AC mode (GSC) - AR mem for low rate gain quantization */ - - Word16 noise_lev; /* AC mode (GSC) - noise level */ - // Word16 noise_lev; /* AC mode (GSC) - noise level Q0*/ - + Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ + Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ + Word16 old_y_gain_fx[MBANDS_GN16k]; /* AC mode (GSC) - AR mem for low rate gain quantization */ + Word16 noise_lev; /* AC mode (GSC) - noise level */ Word16 lt_ener_per_band_fx[MBANDS_GN16k]; /* Q12 */ - - Word32 Last_frame_ener_fx; /* AC mode (GSC) - last frame energy */ - - Word16 Last_GSC_spectrum_fx[L_FRAME16k]; /* AC mode (GSC) - Last good GSC spectrum */ - - Word16 Last_GSC_pit_band_idx; /* AC mode (GSC) - Last pitch band index */ - // Word16 Last_GSC_pit_band_idx; /* AC mode (GSC) - Last pitch band index Q0*/ - - Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous excitation */ - - Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ - - Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - // Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - + Word32 Last_frame_ener_fx; /* AC mode (GSC) - last frame energy */ + Word16 Last_GSC_spectrum_fx[L_FRAME16k]; /* AC mode (GSC) - Last good GSC spectrum */ + Word16 Last_GSC_pit_band_idx; /* AC mode (GSC) - Last pitch band index */ + Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous excitation */ + Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ + Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ } GSC_DEC_DATA, *GSC_DEC_HANDLE; @@ -566,10 +551,8 @@ typedef struct gsc_dec_structure typedef struct WI_dec_structure { Word16 old_exc2_fx[L_EXC_MEM]; /* FEC - old excitation2 used in fast recovery */ - Word16 old_syn2_fx[L_EXC_MEM]; /* FEC - old syn speech used in fast recovery */ - } WI_DEC_DATA, *WI_DEC_HANDLE; diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index a294d12da..dcee88325 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -39,14 +39,10 @@ ivas_error acelp_core_enc_fx( Word16 old_syn_12k8_16k_fx[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn*/ Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ Word16 *unbits_fx, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new, - const Word16 shift -#ifdef ADD_LRTD - , - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif -) + const Word16 shift ) { Word16 nBits; /* reserved bits */ Word16 i; @@ -113,6 +109,8 @@ ivas_error acelp_core_enc_fx( * Initialization *------------------------------------------------------------------*/ + (void) tdm_lsfQ_PCh; + Es_pred_fx = 0; move16(); @@ -206,16 +204,14 @@ ivas_error acelp_core_enc_fx( /* TD stereo */ test(); -#ifdef ADD_LRTD IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) { tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; - tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; + tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf_fx; } ELSE -#endif { tdm_lp_reuse_flag = 0; tdm_low_rate_mode = 0; @@ -453,78 +449,8 @@ ivas_error acelp_core_enc_fx( if ( !tdm_lp_reuse_flag ) { -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, tdm_lsfQ_PCh, Q_new ); -#else lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, Q_new ); -#endif } -#ifdef ADD_LRTD - else - { - const float *pt_interp_2; -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->active_cnt != 1 ) - { - int16_t beta_index; - float lsf_wgts[M]; - - /* intra_frame prediction for the LSFs */ - lsp2lsf( lsp_new, lsf_new, M, 12800 ); - - Unified_weighting( &st->Bin_E[L_FFT / 2], lsf_new, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M ); - - tdm_SCh_lsf_reuse( ENC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, lsf_wgts, &beta_index ); - - push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); - } -#endif - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) - { - pt_interp_2 = interpol_frac2; - } -#ifndef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->active_cnt == 1 ) - { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - lsp2lsf( lsp_new, lsf_new, M, st->sr_core ); - } -#endif - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); - - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - tmpF = hLPDmem->old_exc[0]; - preemph( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF ); - mvr2r( hLPDmem->old_exc + st->L_frame - M, hLPDmem->mem_syn, M ); - residu( Aq, M, hLPDmem->old_exc, old_exc, st->L_frame ); - } - - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ -#ifdef CR_FIX_639_HQ_ACELP_TRANSITION - if ( st->L_frame == L_FRAME ) - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - else - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } -#else - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); -#endif - } -#endif - /*---------------------------------------------------------------* * Calculation of LP residual (filtering through A[z] filter) @@ -566,26 +492,12 @@ ivas_error acelp_core_enc_fx( *------------------------------------------------------------*/ test(); test(); -#ifdef ADD_LRTD - if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ + IF( hSC_VBR->nelp_mode ) { - if ( st->coder_type <= UNVOICED ) - { - tdm_low_rate_enc( st, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, 0 /*attack_flag*/, lsf_new, &tmp_noise ); - } - else /* GENERIC */ - { - encod_gen_2sbfr( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } + /* SC-VBR - NELP frames */ + encod_nelp_fx( st_fx, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf_fx, + voice_factors_fx, bwe_exc_fx, Q_new, shift ); } - else -#endif - IF( hSC_VBR->nelp_mode ) - { - /* SC-VBR - NELP frames */ - encod_nelp_fx( st_fx, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf_fx, - voice_factors_fx, bwe_exc_fx, Q_new, shift ); - } ELSE IF( EQ_16( coder_type, UNVOICED ) ) { /* UNVOICED frames (Gauss. excitation) */ @@ -621,11 +533,8 @@ ivas_error acelp_core_enc_fx( st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /* redo LSF quantization */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, tdm_lsfQ_PCh, Q_new ); -#else lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, Q_new ); -#endif + /* recalculation of LP residual (filtering through A[z] filter) */ calc_residu_fx( st_fx, inp_fx, res_fx, Aq_fx ); diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 7188bcbad..15cc1a9e7 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -338,11 +338,7 @@ void CNG_enc_fx( } ELSE { -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_enc_fx( st_fx, lsf_new, lsp_new, NULL, NULL, 100, 0, 0, NULL, Q_new ); -#else lsf_enc_fx( st_fx, lsf_new, lsp_new, NULL, NULL, 100, 0, 0, Q_new ); -#endif } /* Reset CNG history if CNG frame length is changed */ test(); diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index e03db0c47..18948a93f 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -329,7 +329,7 @@ void enc_pit_exc_fx( inov_encode_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, st_fx->last_L_frame, GENERIC, st_fx->bwidth, 0, i_subfr, -1, p_Aq, gain_pit, cn, exc, h2, st_fx->hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, 2 * L_SUBFR, shift ); - // PMT("code to be validated") + /*-----------------------------------------------------------------* * Gain encoding *-----------------------------------------------------------------*/ @@ -811,10 +811,9 @@ void enc_pit_exc_ivas_fx( * Innovation encoding *-----------------------------------------------------------------*/ - inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, st_fx->last_L_frame, GENERIC, st_fx->bwidth, 0, i_subfr, -1, p_Aq, gain_pit, cn, exc, h2, st_fx->hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, 2 * L_SUBFR, shift, Q_new ); - // PMT("code to be validated") + /*-----------------------------------------------------------------* * Gain encoding *-----------------------------------------------------------------*/ diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 0be344d72..2a621f1d5 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -115,10 +115,11 @@ void encod_unvoiced_fx( /*----------------------------------------------------------------* * Unvoiced subframe processing in two stages *----------------------------------------------------------------*/ - // PMT("The code below needs validation, never been tested") + /* No adaptive codebook (UC) */ set16_fx( y1, 0, L_SUBFR ); set16_fx( exc_fx + i_subfr, 0, L_SUBFR ); + /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure * or in case of floating point encoder & fixed p. decoder diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index 3005edd6e..6970597c8 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -282,12 +282,7 @@ ivas_error evs_enc_fx( IF( EQ_16( st->core, ACELP_CORE ) ) { acelp_core_enc_fx( st, inp, ener, A, Aw, epsP_h, epsP_l, lsp_new, lsp_mid, vad_hover_flag, - attack_flag, bwe_exc_extended, voice_factors, old_syn_12k8_16k, pitch_buf, &unbits, Q_new, shift -#ifdef ADD_LRTD - , - NULL, NULL -#endif - ); + attack_flag, bwe_exc_extended, voice_factors, old_syn_12k8_16k, pitch_buf, &unbits, NULL, NULL, Q_new, shift ); } /*---------------------------------------------------------------------* * HQ core encoding diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 162fc41fa..f927940ae 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -2059,12 +2059,6 @@ void gain_enc_lbr_fx( move16(); /* Compute scalar product */ -#ifdef DEBUG - if ( L_subfr != L_SUBFR ) - { - PMT( "Entire function needs review to accommode for L_subfr > L_SUBFR" ); - } -#endif coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) ); move16(); exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */ @@ -2272,15 +2266,11 @@ void gain_enc_lbr_fx( move16(); IF( EQ_16( nBits, 7 ) ) { -#ifdef IVAS_CODE cdbk = gp_gamma_3sfr_7b_fx; if ( clip_gain == 1 ) { size -= 28; } -#else - // PMT("gp_gamma_3sfr_7b_fx is missing") -#endif } ELSE { @@ -2375,15 +2365,11 @@ void gain_enc_lbr_fx( move16(); IF( EQ_16( nBits, 7 ) ) { -#ifdef IVAS_CODE cdbk = gp_gamma_4sfr_7b_fx; if ( clip_gain == 1 ) { size -= 25; } -#else - // PMT("gp_gamma_4sfr_7b_fx is missing") -#endif } ELSE { diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index a804c1311..8ed7e9d6c 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -785,10 +785,6 @@ void gsc_enc_fx( Word16 imaxpulse_fx[NB_SFM]; Word16 Q_tmp; Word16 seed_init; -#ifdef ADD_LRTD - Word16 max_eq_val; - Word32 max_eq; -#endif GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -896,18 +892,6 @@ void gsc_enc_fx( move16(); set16_fx( bitallocation_band, 0, MBANDS_GN_BITALLOC16k ); -#ifdef ADD_LRTD - max_eq = 0; - max_eq_val = 1.0f; - - IF( ( ( ( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) || LT_32( st_fx->core_brate, 6000 ) ) && LE_16( st_fx->coder_type, UNVOICED ) ) || GE_16( st_fx->GSC_IVAS_mode, 1 ) ) - { - j = emaximum( concat_out, nb_subbands * 16, &max_eq ); - max_eq = max_eq_val / ( fabsf( concat_out[j] ) + 0.01f ); - max_eq = min( max_eq_val, max_eq ); - } -#endif - FOR( j = 0; j < nb_subbands; j++ ) { Copy( concat_out + j * 16, exc_diffQ + max_ener_band[j] * 16, 16 ); /*Q12*/ @@ -963,26 +947,7 @@ void gsc_enc_fx( * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal * Gain is based on the inter-correlation gain between the pulses found and residual signal *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - test(); - test(); - test(); - IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) - { - FOR( i = 64; i < st->L_frame; i++ ) - { - exc_diffQ[i] *= max_eq; - } - } - ELSE IF( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) && LE_16( st_fx->coder_type, UNVOICED ) ) - { - FOR( i = 0; i < L_FRAME; i++ ) - { - exc_diffQ[i] *= max_eq; - } - } - else -#endif + { freq_dnw_scaling_fx( hGSCEnc->cor_strong_limit, st_fx->coder_type, hGSCEnc->noise_lev, st_fx->core_brate, exc_diffQ, Q_PVQ_OUT, st_fx->L_frame ); } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index ca8b70ca2..5de4e8e92 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -35,9 +35,8 @@ ivas_error init_encoder_fx( move16(); ISM_MODE ism_mode = ISM_MODE_NONE; ivas_error error; - // PMT("ism_mode, idchan, vad_only_flag to be move to function header") - error = IVAS_ERR_OK; + error = IVAS_ERR_OK; /*-----------------------------------------------------------------* * General signal buffers @@ -409,7 +408,7 @@ ivas_error init_encoder_fx( /*-----------------------------------------------------------------* * Noise estimator *-----------------------------------------------------------------*/ - // PMT("deal with idchan ") + test(); test(); IF( /*idchan == 0 ||*/ EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index b4ca63bac..1f2fee684 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1410,9 +1410,6 @@ static ivas_error configureEncoder_fx( IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { hIvasEnc->hCoreCoder = st_ivas->hSCE[0]->hCoreCoder[0]; /* Note: this is needed for switching in EVS mono */ - //#ifndef EVS_FLOAT_ENC - // hIvasEnc->hCoreCoder_fx = st_ivas->hSCE[0]->hCoreCoder_fx[0]; - //#endif } ELSE { diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 45a4e014a..de5e474a0 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -72,18 +72,12 @@ void lsf_enc_fx( const Word16 Nb_ACELP_frames, const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ -#endif const Word16 Q_new ) { Word16 nBits = 0; Word16 int_fs; Word16 force_sf = 0; Word16 fec_lsf[M], stab, i; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - (void) tdm_low_rate_mode; -#endif #ifdef IVAS_CODE Word16 param_lpc[NPRM_LPC_NEW]; #endif @@ -191,13 +185,10 @@ void lsf_enc_fx( /*-------------------------------------------------------------------------------------* * Frame end LSF quantization *-------------------------------------------------------------------------------------*/ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_end_enc_fx( st_fx, lsf_new, lsf_new, nBits, coder_type, Q_new + QSCALE - 2, - force_sf, NULL, NULL, NULL, st_fx->coder_type_raw_fxtdm_lsfQ_PCh ); -#else + lsf_end_enc_fx( st_fx, lsf_new, lsf_new, nBits, coder_type, Q_new + QSCALE - 2, force_sf, NULL, NULL, NULL, st_fx->coder_type_raw ); -#endif + /* convert quantized LSFs back to LSPs */ lsf2lsp_fx( lsf_new, lsp_new, M, int_fs ); @@ -296,11 +287,10 @@ void lsf_enc_fx( } /* LSP interpolation and conversion of LSPs to A(z) */ -#ifdef ADD_LRTD test(); IF( EQ_16( tdm_low_rate_mode, 1 ) && GT_16( coder_type, UNVOICED ) ) { - IF( EQ_16( st_fx->active_cnt_fx, 1 ) ) + IF( EQ_16( st_fx->active_cnt, 1 ) ) { Copy( lsp_mid, st_fx->lsp_old_fx, M ); lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, int_fs ); @@ -311,7 +301,6 @@ void lsf_enc_fx( int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, -2 ); } ELSE -#endif { int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, 0 ); } @@ -885,10 +874,6 @@ void lsf_end_enc_fx( Word16 *no_indices, Word16 *bits_param_lpc, Word16 coder_type_raw /* i : Coder type (LSF coder_type have some special cases)*/ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif ) { Word16 i; @@ -922,10 +907,6 @@ void lsf_end_enc_fx( Word16 tmp; Word16 flag_1bit_gran; BSTR_ENC_HANDLE hBstr = st->hBstr; -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - Word16 pred3[M]; - Word16 dummy, dummy_v[5]; -#endif flag_1bit_gran = (Word16) GT_16( st->element_mode, EVS_MONO ); @@ -935,11 +916,7 @@ void lsf_end_enc_fx( test(); test(); test(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( st->codec_mode, MODE1 ) && ( st->idchan == 0 ) ) /* this bit is used only for primary channel or mono */ -#else IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( st->codec_mode, MODE1 ) ) -#endif { IF( EQ_16( coder_type_raw, VOICED ) ) { @@ -1014,16 +991,7 @@ void lsf_end_enc_fx( pred1[i] = add( ModeMeans_fx[mode_lvq][i], mult_r( MU_MA_FX, st->mem_MA_fx[i] ) ); move16(); } -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - /* TD stereo SCh: perform intra-frame prediction with pulling-to-mean */ - if ( st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL ) - { - /* if secondary channel predmode is set to be > 2 */ - predmode += 3; - tdm_SCh_LSF_intra_pred( st->element_brate, tdm_lsfQ_PCh, pred3 ); - } -#endif IF( predmode == 0 ) { /* Subtract only mean */ @@ -1048,183 +1016,112 @@ void lsf_end_enc_fx( move16(); } ELSE -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - PMT( "LSF_RE_USE_SECONDARY_CHANNEL CODE IS MISSING " ) { - if ( predmode == 2 ) -#endif - { - /* Adaptive scaling factor (multiplier) is updated in order to reduce the amount of consecutive predictive frames in + /* Adaptive scaling factor (multiplier) is updated in order to reduce the amount of consecutive predictive frames in case of possible frame erasure. AR-predictive usage for VOICED mode is allowed to be higher than other modes. */ - test(); - test(); - test(); - IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) + test(); + test(); + test(); + IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) + { + /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ + st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); + move16(); + } + + IF( st->pstreaklen == 0 ) + { + /* reset the consecutive AR-predictor multiplier */ + st->streaklimit_fx = 32767; /*1.0 in Q15 */ + move16(); + } + + /* VOICED_WB@16kHz */ + test(); + IF( EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( coder_type, VOICED ) && flag_1bit_gran == 0 ) + { + /* Subtract mean and AR prediction */ + Copy( ModeMeans_fx[mode_lvq], pred0, M ); + /* subtract only mean */ + Vr_subt( lsf, pred0, Tmp, M ); + + FOR( i = 0; i < M; i++ ) { - /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ - st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); - move16(); + /* subtract mean and AR prediction */ + pred2[i] = mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ); + Tmp2[i] = sub( Tmp[i], pred2[i] ); + pred2[i] = add( pred2[i], pred0[i] ); } - IF( st->pstreaklen == 0 ) + /* select safety_net or predictive */ + safety_net = qlsf_Mode_Select_fx( wghts, Tmp2, st->streaklimit_fx, OP_LOOP_THR_HVO ); + IF( EQ_16( force_sf, 1 ) ) { - /* reset the consecutive AR-predictor multiplier */ - st->streaklimit_fx = 32767; /*1.0 in Q15 */ + safety_net = 1; move16(); } - /* VOICED_WB@16kHz */ - test(); - IF( EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( coder_type, VOICED ) && flag_1bit_gran == 0 ) + IF( safety_net ) { - /* Subtract mean and AR prediction */ - Copy( ModeMeans_fx[mode_lvq], pred0, M ); - /* subtract only mean */ - Vr_subt( lsf, pred0, Tmp, M ); - - FOR( i = 0; i < M; i++ ) - { - /* subtract mean and AR prediction */ - pred2[i] = mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ); - Tmp2[i] = sub( Tmp[i], pred2[i] ); - pred2[i] = add( pred2[i], pred0[i] ); - } - - /* select safety_net or predictive */ - safety_net = qlsf_Mode_Select_fx( wghts, Tmp2, st->streaklimit_fx, OP_LOOP_THR_HVO ); - IF( EQ_16( force_sf, 1 ) ) - { - safety_net = 1; - move16(); - } - - IF( safety_net ) - { - /* Safety-net - BC-TCQ quantization : SN */ - Err[0] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); - st->pstreaklen = 0; - move16(); - } - ELSE - { - /* predictive - BC-TCQ quantization : AR */ - Err[1] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp2, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); - st->pstreaklen = add( st->pstreaklen, 1 ); - } + /* Safety-net - BC-TCQ quantization : SN */ + Err[0] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); + st->pstreaklen = 0; + move16(); } - /* all other frames (not VOICED@16kHz) */ ELSE { - /* Subtract mean and AR prediction */ - Copy( ModeMeans_fx[mode_lvq], pred0, M ); - /* subtract only mean */ - Vr_subt( lsf, pred0, Tmp, M ); - - FOR( i = 0; i < M; i++ ) - { - /* subtract mean and AR prediction */ - pred2[i] = add( pred0[i], mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ) ); - Tmp2[i] = sub( lsf[i], pred2[i] ); - } - - /* safety-net */ - Err[0] = vq_lvq_lsf_enc( 0, mode_lvq, Tmp, levels0, stages0, wghts, Idx0, lsf, pred0, st->offset_scale1_fx, st->offset_scale2_fx, st->no_scales_fx, resq, lsfq ); - /* Predictive quantizer is calculated only if it can be selected */ - test(); - IF( !force_sf || GT_32( Err[0], abs_threshold ) ) - { - Err[1] = vq_lvq_lsf_enc( 2, mode_lvq_p, Tmp2, levels1, stages1, wghts, Idx1, lsf, pred2, - st->offset_scale1_p_fx, st->offset_scale2_p_fx, st->no_scales_p_fx, &resq[M], &lsfq[M] ); - } - test(); - test(); - /* Select whether to use safety-net (non-predictive) or predictive LSF quantizer. The decision is based on following: - if the non-predictive (safety-net) quantization error (Err[0]) is low enough (spectral distortion is low) it is selected - or if the predictively quantized error (Err[1]) is by at least adaptive margin smaller than non-predictive quantizer. - or if the in case of frame erasure the resulting concealed predictive LSF would be unstable safety-net is selected */ - IF( force_sf || LT_32( Mult_32_16( Err[0], ( st->streaklimit_fx ) ), L_add( Err[1], Mult_32_16( Err[1], PREFERSFNET_FX ) ) ) || LT_32( Err[0], abs_threshold ) ) - { - safety_net = 1; - move16(); - st->pstreaklen = 0; - move16(); /* Reset the consecutive predictive frame counter */ - } - ELSE - { - safety_net = 0; - move16(); /* Increase the consecutive predictive frame counter by one */ - st->pstreaklen = add( st->pstreaklen, 1 ); - } + /* predictive - BC-TCQ quantization : AR */ + Err[1] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp2, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); + st->pstreaklen = add( st->pstreaklen, 1 ); } } -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - PMT( "LSF_RE_USE_SECONDARY_CHANNEL CODE IS MISSING " ) - else /* of "if (predmode==2)" */ + /* all other frames (not VOICED@16kHz) */ + ELSE { - mvr2r( ModeMeans[mode_lvq], pred0, M ); - - if ( predmode == 4 ) - { - mode_lvq_p = 9; /* force to Generic WB with AR*/ - } + /* Subtract mean and AR prediction */ + Copy( ModeMeans_fx[mode_lvq], pred0, M ); + /* subtract only mean */ + Vr_subt( lsf, pred0, Tmp, M ); - for ( i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { /* subtract mean and AR prediction */ - pred2[i] = pred0[i] + Predictors[mode_lvq_p][i] * ( st->mem_AR[i] - pred0[i] ); - Tmp[i] = lsf[i] - pred2[i]; - Tmp2[i] = lsf[i] - pred3[i]; + pred2[i] = add( pred0[i], mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ) ); + Tmp2[i] = sub( lsf[i], pred2[i] ); } - /* Adaptive scaling factor (multiplier) is updated in order to reduce the amount of consecutive predictive frames in - case of possible frame erasure. AR-predictive usage for VOICED mode is allowed to be higher than other modes. */ - if ( st->pstreaklen > ( STREAKLEN ) ) + /* safety-net */ + Err[0] = vq_lvq_lsf_enc( 0, mode_lvq, Tmp, levels0, stages0, wghts, Idx0, lsf, pred0, st->offset_scale1_fx, st->offset_scale2_fx, st->no_scales_fx, resq, lsfq ); + /* Predictive quantizer is calculated only if it can be selected */ + test(); + IF( !force_sf || GT_32( Err[0], abs_threshold ) ) { - /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ - st->streaklimit *= STREAKMULT; + Err[1] = vq_lvq_lsf_enc( 2, mode_lvq_p, Tmp2, levels1, stages1, wghts, Idx1, lsf, pred2, + st->offset_scale1_p_fx, st->offset_scale2_p_fx, st->no_scales_p_fx, &resq[M], &lsfq[M] ); } - - if ( st->pstreaklen == 0 ) + test(); + test(); + /* Select whether to use safety-net (non-predictive) or predictive LSF quantizer. The decision is based on following: + if the non-predictive (safety-net) quantization error (Err[0]) is low enough (spectral distortion is low) it is selected + or if the predictively quantized error (Err[1]) is by at least adaptive margin smaller than non-predictive quantizer. + or if the in case of frame erasure the resulting concealed predictive LSF would be unstable safety-net is selected */ + IF( force_sf || LT_32( Mult_32_16( Err[0], ( st->streaklimit_fx ) ), L_add( Err[1], Mult_32_16( Err[1], PREFERSFNET_FX ) ) ) || LT_32( Err[0], abs_threshold ) ) { - /* reset the adaptive scaling factor */ - st->streaklimit = 1.0f; + safety_net = 1; + move16(); + st->pstreaklen = 0; + move16(); /* Reset the consecutive predictive frame counter */ } - - /* intra pred */ - /* use G AR pred for the intra mode (as a safety mode, this is why the indexes 0/1 are interchanged)*/ - - lsf_allocate( nBits - 1, mode_lvq, 9, &stages1, &stages0, levels1, levels0, bits1, bits0 ); - - Err[0] = vq_lvq_lsf_enc( 2, 9, Tmp2, levels0, stages0, wghts, Idx0, lsf, pred3, &resq[M], &lsfq[M] ); - - if ( force_sf ) + ELSE { - safety_net = 1; /* intra-frame prediction */ - st->pstreaklen = 0; /* Reset the consecutive predictive frame counter */ - } - else - { /* try also the inter frame prediction */ - - /* AR inter-frame prediction */ - lsf_allocate( nBits - 1, mode_lvq, mode_lvq_p, &dummy, &stages1, dummy_v, levels1, dummy_v, bits1 ); - - - Err[1] = vq_lvq_lsf_enc( 2, mode_lvq_p, Tmp, levels1, stages1, wghts, Idx1, lsf, pred2, resq, lsfq ); - - if ( Err[0] * ( st->streaklimit ) < PREFERSFNET * Err[1] ) - { - safety_net = 1; - st->pstreaklen = 0; /* Reset the consecutive predictive frame counter */ - } - else - { - safety_net = 0; - ( st->pstreaklen )++; /* Increase the consecutive predictive frame counter by one */ - } + safety_net = 0; + move16(); /* Increase the consecutive predictive frame counter by one */ + st->pstreaklen = add( st->pstreaklen, 1 ); } } } -#endif /*--------------------------------------------------------------------------* \ + + /*--------------------------------------------------------------------------* \ * Write indices to array \ *--------------------------------------------------------------------------*/ @@ -1232,22 +1129,14 @@ void lsf_end_enc_fx( { /* write coder_type bit for VOICED@16kHz or GENERIC@16kHz */ test(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && ( st->idchan == 0 ) ) -#else IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) ) -#endif { /* VOICED =2 and GENERIC=3, so "coder_type-2" means VOICED =0 and GENERIC=1*/ push_indice_fx( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); } /* write predictor selection bit */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( GE( predmode, 2 ) ) -#else IF( EQ_16( predmode, 2 ) ) -#endif { push_indice_fx( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); } @@ -1267,11 +1156,7 @@ void lsf_end_enc_fx( { cumleft = nBits; move16(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( GE( predmode, 2 ) ) -#else IF( EQ_16( predmode, 2 ) ) -#endif { /* subtract predictor selection bit */ cumleft = sub( nBits, 1 ); @@ -1434,16 +1319,6 @@ void lsf_end_enc_fx( } ELSE { -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL ) - { - /* intra mode*/ - vq_dec_lvq( 0, qlsf, &indice[0], stages0, M, 9, /*mode_lvq_p,*/ levels0[stages0 - 1] ); - v_add( qlsf, pred3, qlsf, M ); - v_sub( qlsf, pred1, st->mem_MA, M ); - } - else -#endif { vq_dec_lvq_fx( 1, qlsf, &indice[0], stages0, M, mode_lvq, levels0[stages0 - 1], &st->offset_scale1_fx[0][0], &st->offset_scale2_fx[0][0], &st->offset_scale1_p_fx[0][0], &st->offset_scale2_p_fx[0][0], @@ -2122,7 +1997,7 @@ static void first_VQstages( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ @@ -2312,7 +2187,7 @@ static void first_VQstages_ivas_fx( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index 80e144743..d53e2eb6e 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -268,48 +268,6 @@ Word16 pit_encode_fx( /* o : Fractional pitc pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } -#ifdef ADD_LRTD - else if ( tdm_Pitch_reuse_flag == 1 || nBits == 4 ) - { - /*-------------------------------------------------------* - * Pitch encoding with reusing primary channel information - *-------------------------------------------------------*/ - int16_t loc_T0, loc_frac; - - delta = 4; - - pit_flag = L_SUBFR; - - if ( L_subfr == 2 * L_SUBFR ) - { - loc_T0 = (int16_t) ( 0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[( i_subfr + L_SUBFR ) / L_SUBFR] ); - loc_frac = (int16_t) ( ( ( 0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[( i_subfr + L_SUBFR ) / L_SUBFR] ) - loc_T0 ) * 4.0f ); - } - else - { - loc_T0 = (int16_t) tdm_Pri_pitch_buf[i_subfr / L_SUBFR]; - loc_frac = (int16_t) ( ( tdm_Pri_pitch_buf[i_subfr / L_SUBFR] - loc_T0 ) * 4.0f ); - } - - /* pitch lag search limitation */ - limit_T0( L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max ); - if ( nBits > 0 ) - { - /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); - if ( delta == 8 ) - { - *T0_frac = 0; - } - pit_Q_enc( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); - } - else - { - *T0 = loc_T0; - *T0_frac = loc_frac; - } - } -#endif ELSE { /*-------------------------------------------------------* diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 2e151df8f..c3e9d1b4c 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -61,14 +61,13 @@ ivas_error acelp_core_enc_fx( Word16 old_syn_12k8_16k_fx[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn*/ Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ Word16 *unbits_fx, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new, const Word16 shift -#ifdef ADD_LRTD - , - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif + ); + void analy_lp_ivas_fx( const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ const Word16 L_frame, /* i :(q0) length of the frame */ @@ -906,10 +905,6 @@ void lsf_end_enc_fx( Word16 *no_indices, Word16 *bits_param_lpc, Word16 coder_type_raw /* i : Coder type (LSF coder_type have some special cases)*/ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif ); void lsf_end_enc_ivas_fx( @@ -923,10 +918,10 @@ void lsf_end_enc_ivas_fx( Word16 *lpc_param, Word16 *no_indices, Word16 *bits_param_lpc, - Word16 coder_type_raw /* i : Coder type (LSF coder_type have some special cases)*/ - , + Word16 coder_type_raw, /* i : Coder type (LSF coder_type have some special cases)*/ const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ ); + void Mode2_abs_pit_enc_fx( Word16 T0, /* i : integer pitch lag */ Word16 T0_frac, /* i : pitch fraction */ @@ -1853,9 +1848,6 @@ void lsf_enc_fx( const Word16 Nb_ACELP_frames, const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ -#endif const Word16 Q_new ); void lsf_enc_ivas_fx( @@ -1868,6 +1860,7 @@ void lsf_enc_ivas_fx( const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new ); + void Es_pred_enc_fx( Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/ Word16 *indice, /* o : indice of quantization Q0*/ -- GitLab From 7bf5394675814ab272299e098bd3bbcb7ee1920f Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 10:28:15 +0100 Subject: [PATCH 0311/1221] remove redundant code under IVAS_CODE_CNG --- lib_com/fd_cng_com_fx.c | 5 - lib_com/prot_fx.h | 13 - lib_dec/cng_dec_fx.c | 52 +- lib_dec/dec_acelp_tcx_main_fx.c | 22 +- lib_dec/fd_cng_dec_fx.c | 814 +------------------------------- lib_enc/fd_cng_enc_fx.c | 58 +-- 6 files changed, 9 insertions(+), 955 deletions(-) diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index f4468bd0b..e04a13fdf 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -566,11 +566,6 @@ void minimum_statistics( Word16 *msPeriodogBuf, /* i/o: Buffer of periodograms (energies) */ Word16 *msPeriodogBufPtr, /* i/o: Counter */ HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -#ifdef IVAS_CODE_CNG - , - const Word16 enc_dec, /* i : encoder/decoder indicator */ - const Word16 element_mode /* i : IVAS element mode type */ -#endif ) { Word16 i, j, k, s, s1, s2, s3; diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 6f5519f68..cb7416eb3 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -7588,15 +7588,6 @@ void perform_noise_estimation_dec_fx( float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ -#ifdef IVAS_CODE_CNG - , - const Word16 element_mode, /* i : element mode */ - const Word16 bwidth, /* i : audio bandwidth */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 last_L_frame, /* i : frame length of the last frame at internal Fs */ - const Word32 last_core_brate, /* i : previous frame core bitrate */ - const Word16 VAD /* i : VAD flag in the decoder */ -#endif ); void perform_noise_estimation_dec_ivas_fx( @@ -8725,10 +8716,6 @@ Word16 dec_acelp_tcx_frame_fx( Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ Word16 *voice_factors, /* o : voicing factors */ Word16 pitch_buf[] /* o : floating pitch for each subframe */ -#ifdef IVAS_CODE_CNG - , - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -#endif ); // dec_LPD_fx.c diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index 3590dae71..e3401739e 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -1513,12 +1513,6 @@ static void shb_CNG_decod_fx( } ELSE { -#ifdef IVAS_CODE_CNG - /* de-quantization of SHB CNG parameters */ To be verified - L_tmp = L_mult( idx_ener_fx, 17615 ); /*Q13*/ - st_fx->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 147962 ), 5 ) ); /*Q8 */ - move16(); -#endif } } } @@ -1549,9 +1543,6 @@ static void shb_CNG_decod_fx( Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */ -#ifdef IVAS_CODE_CNG - // mvr2r(shb_lpcCNG, st->hTdCngDec->shb_lpcCNG, LPC_SHB_ORDER + 1); -#endif /* SHB energy estimation */ wb_ener_fx = L_deposit_l( 1 ); /*Q1 */ FOR( i = 0; i < L_FRAME32k; i++ ) @@ -1695,9 +1686,7 @@ static void shb_CNG_decod_fx( L_tmp = L_deposit_h( tmp ); /*Q31 */ tmp = sub( add( 5, exp ), add( q, exp1 ) ); L_gain_fx = Isqrt_lc( L_tmp, &tmp ); /*Q31-Qtmp */ -#ifdef IVAS_CODE_CNG - st->hTdCngDec->shb_cng_gain = ener_fx; -#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { shb_syn16k_fx[i] = extract_l( L_shr( Mpy_32_16_1( L_gain_fx, excSHB_fx[i] ), sub( 5, tmp ) ) ); /*Q3 = 31-Qtmp-8-15-5+Qtmp */ @@ -1726,11 +1715,8 @@ static void shb_CNG_decod_fx( { interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, st_fx->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); } -#ifdef IVAS_CODE_CNG - ResetSHBbuffer_Dec( st->hBWE_TD, st->extl ); -#else + ResetSHBbuffer_Dec_fx( st_fx ); -#endif return; } @@ -2037,20 +2023,6 @@ void td_cng_dec_init_fx( move16(); hTdCngDec->last_allow_cn_step = 0; move16(); -#ifdef IVAS_CODE_CNG - // mvr2r(st->lsp_old, st->lspCNG, M); - // hTdCngDec->shb_cng_ener = -6.02f; - IF( st->element_mode != EVS_MONO ) - { - // set_f(hTdCngDec->shb_lpcCNG, 0.0f, LPC_SHB_ORDER + 1); - // hTdCngDec->shb_lpcCNG[0] = 1.0f; - // hTdCngDec->shb_cng_gain = -82.0; /* a dB value approximately corresponding to shb index 0(used as index -15) */ - } - // hTdCngDec->wb_cng_ener = -6.02f; - // hTdCngDec->last_wb_cng_ener = -6.02f; - // hTdCngDec->last_shb_cng_ener = -6.02f; - // hTdCngDec->swb_cng_seed = RANDOM_INITSEED; -#endif hTdCngDec->ho_hist_ptr = -1; move16(); hTdCngDec->ho_sid_bw = L_deposit_l( 0 ); @@ -2081,26 +2053,6 @@ void td_cng_dec_init_fx( set16_fx( hTdCngDec->exc_mem_fx, 0, 24 ); set16_fx( hTdCngDec->exc_mem1_fx, 0, 30 ); set32_fx( hTdCngDec->old_env_fx, 0, NUM_ENV_CNG ); -#ifdef IVAS_CODE_CNG - // st->CNG_mode = -1; - // for (i = 0; i < LPC_SHB_ORDER; i++) - //{ - // IF (st->element_mode != EVS_MONO) - // { - // hTdCngDec->lsp_shb_prev[i] = 0.5f * ((float)(i + 1)) / ((float)(LPC_SHB_ORDER + 1)); - // } - // else - // { - // hTdCngDec->lsp_shb_prev[i] = 0.5f * ((float)i) / ((float)LPC_SHB_ORDER); - // } - // hTdCngDec->lsp_shb_prev_prev[i] = hTdCngDec->lsp_shb_prev[i]; - // } - - // hTdCngDec->shb_dtx_count = 0; - // hTdCngDec->trans_cnt = 0; - // hTdCngDec->last_shb_ener = 0.001f; - // set_f(hTdCngDec->interpol_3_2_cng_dec, 0.0f, INTERP_3_2_MEM_LEN); -#endif hTdCngDec->burst_cnt = 0; move16(); diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c index 7edd23549..04a41ed46 100644 --- a/lib_dec/dec_acelp_tcx_main_fx.c +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -10,12 +10,7 @@ #include "stat_com.h" #include "prot_fx.h" #include "basop_util.h" -static void decode_frame_type_fx( Decoder_State *st -#ifdef IVAS_CODE_CNG - , - STEREO_CNG_DEC_HANDLE hStereoCng -#endif -) +static void decode_frame_type_fx( Decoder_State *st ) { Word32 L_tmp; Word16 num_bits; @@ -259,9 +254,7 @@ static void decode_frame_type_fx( Decoder_State *st IF( EQ_16( st->m_frame_type, SID_FRAME ) && NE_16( st->hFdCngDec->hFdCngCom->frame_type_previous, ACTIVE_FRAME ) ) { lerp( st->hFdCngDec->hFdCngCom->olapBufferSynth, st->hFdCngDec->hFdCngCom->olapBufferSynth, st->L_frame * 2, st->last_L_frame * 2 ); -#ifdef IVAS_CODE_CNG - lerp( hStereoCng->olapBufferSynth22, hStereoCng->olapBufferSynth22, st->L_frame * 2, st->last_L_frame * 2 ); -#endif + IF( EQ_16( st->L_frame, L_FRAME ) ) { FOR( n = 0; n < shl( st->L_frame, 1 ); n++ ) @@ -311,10 +304,6 @@ Word16 dec_acelp_tcx_frame_fx( Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation Q0 */ Word16 *voice_factors, /* o : voicing factors Q15 */ Word16 pitch_buf[] /* o : floating pitch for each subframe Q6 */ -#ifdef IVAS_CODE_CNG - , - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -#endif ) { Word16 num_bits; @@ -366,12 +355,7 @@ Word16 dec_acelp_tcx_frame_fx( Word32 total_brate = st->last_total_brate; move32(); - decode_frame_type_fx( st -#ifdef IVAS_CODE_CNG - , - hStereoCng -#endif - ); + decode_frame_type_fx( st ); st->force_lpd_reset = 0; move16(); diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 70c4760ae..c509d5d10 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -279,30 +279,6 @@ void initFdCngDec_fx( hFdCngDec->smoothed_psd_exp = 0; move16(); -#ifdef IVAS_CODE_CNG - set_f( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0.0f, NPART ); - - set_f( hFdCngDec->smoothed_psd, 0.0f, L_FRAME16k ); - set_f( hFdCngDec->msPeriodog_ST, 0.0f, NPART_SHAPING ); - - hFdCngDec->ms_last_inactive_bwidth = NB; - hFdCngDec->ms_cnt_bw_up = 0; - - hFdCngDec->cna_LR_LT = 0.5f; - hFdCngDec->cna_ILD_LT = 0.0f; - hFdCngDec->first_cna_noise_updated = 0; - hFdCngDec->first_cna_noise_update_cnt = 0; - hFdCngDec->cna_nbands = 6; - mvs2s( cna_init_bands, hFdCngDec->cna_band_limits, MAX_CNA_NBANDS + 1 ); - hFdCngDec->cna_act_fact = 1.0f; - hFdCngDec->cna_rescale_fact = 0.0f; - hFdCngDec->cna_seed = 5687; - set_zero( hFdCngDec->cna_cm, STEREO_DFT_BAND_MAX ); - set_zero( hFdCngDec->cna_g_state, STEREO_DFT_BAND_MAX ); - - st->CNG_mode = -1; - mvr2r( st->lsp_old, st->lspCNG, M ); -#endif return; } /* @@ -1032,12 +1008,6 @@ Word16 ApplyFdCng_fx( hFdCngCom->psize_inv, hFdCngDec->partNoiseShape, &hFdCngDec->partNoiseShape_exp ); -#ifdef IVAS_CODE_CNG - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - Copy( hFdCngDec->hFdCngCom->sidNoiseEst, hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); - } -#endif } IF( EQ_16( st->m_frame_type, SID_FRAME ) ) @@ -1054,11 +1024,8 @@ Word16 ApplyFdCng_fx( { if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { -#ifdef IVAS_CODE_CNG - sidNoiseEst = hFdCngCom->sidNoiseEstLp; - move16(); -#endif } + /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { @@ -1136,24 +1103,7 @@ Word16 ApplyFdCng_fx( move16(); } } -#ifdef IVAS_CODE_CNG - else if ( st->element_mode == IVAS_CPE_DFT ) - { - if ( !( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) ) - { - sidNoiseEst = hFdCngCom->sidNoiseEstLp; - j = 0; - for ( k = 0; k < hFdCngCom->nFFTpart; k++ ) - { - factor = ( sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape[k] + DELTA ); - for ( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = hFdCngDec->bandNoiseShape[j] * factor; - } - } - } - } -#endif + IF( EQ_16( st->codec_mode, MODE2 ) ) { /* Generate comfort noise during SID or zero frames */ @@ -1866,15 +1816,6 @@ void perform_noise_estimation_dec_fx( float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ -#ifdef IVAS_CODE_CNG - , - const int16_t element_mode, /* i : element mode */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t L_frame, /* i : frame length at internal Fs */ - const int16_t last_L_frame, /* i : frame length of the last frame at internal Fs */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - const int16_t VAD /* i : VAD flag in the decoder */ -#endif ) { Word16 i, tmp_r, tmp_i, fac, fftBuffer_exp; @@ -1883,10 +1824,6 @@ void perform_noise_estimation_dec_fx( Word16 *part, *psize_inv, *psize_norm; Word32 tmp, *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i; -#ifdef IVAS_CODE_CNG - PMT( "lots of code related to IVAS needs to be done " ) -#endif - /* pointer initialization */ periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/ @@ -1919,238 +1856,7 @@ void perform_noise_estimation_dec_fx( AnalysisSTFT( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom ); #endif fftBuffer_exp = add( fftBuffer_exp, WORD16_BITS - 1 ); -#ifdef IVAS_CODE_CNG - if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) - { - /* Calculate periodogram (squared magnitude in each FFT bin) */ - if ( startBand == 0 ) - { - ( *ptr_per ) = fftBuffer[0] * fftBuffer[0]; - ptr_per++; - ptr_r = fftBuffer + 2; - } - else - { - ptr_r = fftBuffer + 2 * startBand; - } - - ptr_i = ptr_r + 1; - - for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ ) - { - ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i ); - ptr_r += 2; - ptr_i += 2; - } - - /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ - v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand ); - - /* Combine bins of power spectrum into partitions */ - i = 0; - for ( p = 0; p < npart; p++ ) - { - - /* calculate mean over all bins in power partition */ - temp = 0; - for ( ; i <= part[p]; i++ ) - { - temp += periodog[i]; - } - msPeriodog[p] = temp * psize_inv[p]; - } - - /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */ - if ( hFdCngDec->first_cna_noise_updated ) - { - i = 0; - for ( p = 0; p < npart; p++ ) - { - /* calculate variance over all bins in power partition */ - temp = 0; - for ( ; i <= part[p]; i++ ) - { - delta = periodog[i] - msPeriodog[p]; - temp += delta * delta; - } - temp *= psize_inv[p]; - - /* compensate for the loss of variance */ - msPeriodog[p] = (float) ( msPeriodog[p] + sqrt( temp ) * rand_gauss( &ftemp, &hFdCngDec->cna_seed ) ); - - if ( msPeriodog[p] < 1e-5f ) - { - msPeriodog[p] = 1e-5f; - } - } - } - - /* calculate total energy (short-term and long-term) */ - enr_tot = sum_f( msPeriodog, npart ) + EPSILON; - enr_tot0 = sum_f( msNoiseEst, npart ) + EPSILON; - - /* update short-term periodogram on larger partitions */ - for ( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ ) - { - if ( L_frame != last_L_frame || last_core_brate <= SID_2k40 ) - { - /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */ - hFdCngDec->msPeriodog_ST[p] = msPeriodog[p]; - } - else - { - hFdCngDec->msPeriodog_ST[p] = (float) ( ST_PERIODOG_FACT * hFdCngDec->msPeriodog_ST[p] + ( 1 - ST_PERIODOG_FACT ) * msPeriodog[p] ); - } - } - - /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */ - /* part L_FRAME16k L_FRAME */ - /* ... */ - /* [55] 146 146 */ - /* [56] 174 160 */ - /* [57] 210 174 */ - /* [58] 254 190 */ - /* [59] 306 210 */ - /* [60] 317 230 */ - /* [61] 253 */ - - if ( last_L_frame == L_FRAME16k && L_frame == L_FRAME ) - { - msNoiseEst[61] = msNoiseEst[58]; - msNoiseEst[60] = min( msNoiseEst[58], msNoiseEst[57] ); - msNoiseEst[59] = msNoiseEst[57]; - msNoiseEst[58] = msNoiseEst[56]; - msNoiseEst[57] = msNoiseEst[56]; - msNoiseEst[56] = min( msNoiseEst[56], msNoiseEst[55] ); - } - else if ( last_L_frame == L_FRAME && L_frame == L_FRAME16k ) - { - msNoiseEst[56] = min( msNoiseEst[56], msNoiseEst[57] ); - msNoiseEst[57] = min( msNoiseEst[58], msNoiseEst[59] ); - msNoiseEst[58] = min( msNoiseEst[60], msNoiseEst[61] ); - msNoiseEst[59] = 0.0f; - msNoiseEst[60] = 0.0f; - msNoiseEst[61] = 0.0f; - - hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES; - } - - /* Smooth with IIR filter */ - if ( !hFdCngDec->first_cna_noise_updated ) - { - if ( !VAD ) - { - /* background noise update with moving average */ - alpha = 1.0f / ( hFdCngDec->first_cna_noise_update_cnt + 1 ); - for ( p = 0; p < npart; p++ ) - { - msNoiseEst[p] = ( 1 - alpha ) * msNoiseEst[p] + alpha * msPeriodog[p]; - } - - /* check, if we reached the required number of first CNA noise update frames */ - if ( hFdCngDec->first_cna_noise_update_cnt < FIRST_CNA_NOISE_UPD_FRAMES - 1 ) - { - hFdCngDec->first_cna_noise_update_cnt++; - } - else - { - hFdCngDec->first_cna_noise_updated = 1; - if ( hFdCngDec->hFdCngCom->msFrCnt_init_counter == 0 ) - { - hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1; - } - } - } - else - { - hFdCngDec->first_cna_noise_update_cnt = 0; - } - } - else - { - hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1; - if ( VAD ) - { - /* no updates during active frames except for significant energy drops */ - enr_ratio = enr_tot / enr_tot0; - if ( enr_ratio < 0.5f ) - { - /* total energy significantly decreases during active frames -> downward update */ - wght = lin_interp( enr_ratio, 0.0f, 0.8f, 0.5f, 0.95f, 1 ); - for ( p = 0; p < npart; p++ ) - { - if ( msPeriodog[p] < msNoiseEst[p] ) - { - msNoiseEst[p] = wght * msNoiseEst[p] + ( 1 - wght ) * msPeriodog[p]; - } - } - } - else - { - /* energy significantly decreases in one of the larger partitions during active frames -> downward update */ - for ( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ ) - { - if ( hFdCngDec->msPeriodog_ST[p] < msNoiseEst[p] ) - { - msNoiseEst[p] = (float) ( CNA_ACT_DN_FACT * msNoiseEst[p] + ( 1 - CNA_ACT_DN_FACT ) * hFdCngDec->msPeriodog_ST[p] ); - } - } - } - } - else - { - - if ( bwidth >= WB && hFdCngDec->ms_last_inactive_bwidth == NB ) - { - /* bandwidth increased -> set counter for fast initilization */ - hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES; - } - hFdCngDec->ms_last_inactive_bwidth = bwidth; - /* update background noise during inactive frames */ - ptr_per = msNoiseEst; - for ( p = 0; p < npart; p++ ) - { - enr = msPeriodog[p]; - alpha = 0.95f; - /* bandwidth increased -> do fast re-initilization */ - if ( hFdCngDec->ms_cnt_bw_up > 0 && p > 55 ) - { - alpha = 1.0f / ( hFdCngDec->ms_cnt_bw_up + 1 ); - } - else if ( enr < *ptr_per && part[p] == 1 ) - { - /* faster downward update for single-bin partitions */ - alpha = 0.8f; - } - else if ( enr > 2.0f * ( *ptr_per ) ) - { - /* prevent abrupt upward updates */ - enr = 2.0f * ( *ptr_per ); - } - - /* IIR smoothing */ - *ptr_per *= alpha; - *ptr_per += ( 1 - alpha ) * enr; - ptr_per++; - } - - if ( hFdCngDec->ms_cnt_bw_up > 0 ) - { - hFdCngDec->ms_cnt_bw_up--; - } - } - } - - mvr2r( msNoiseEst, hFdCngDec->msPsd, npart ); - - /* Expand partitions into bins of power spectrum */ - scalebands( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, stopFFTbin - startBand, hFdCngDec->bandNoiseShape, 1 ); - mvr2r( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd[startBand], stopFFTbin - startBand ); - set_zero( &hFdCngDec->smoothed_psd[stopFFTbin], L_FRAME16k - stopFFTbin ); - } - else -#endif { #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) @@ -2302,12 +2008,7 @@ void perform_noise_estimation_dec_fx( hFdCngDec->msNewMinFlag, hFdCngDec->msPeriodogBuf, &( hFdCngDec->msPeriodogBufPtr ), - hFdCngDec->hFdCngCom -#ifdef IVAS_CODE_CNG - , - DEC, element_mode -#endif - ); + hFdCngDec->hFdCngCom ); /* Expand MS outputs */ expand_range( hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart ); @@ -2347,10 +2048,6 @@ void perform_noise_estimation_dec_ivas_fx( Word16 q_shift; Word32 max_l; Word16 norm_shift; -#ifdef IVAS_CODE_CNG - PMT( "lots of code related to IVAS needs to be done " ) -#endif - /* pointer initialization */ periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/ @@ -6303,508 +6000,3 @@ void FdCngDecodeDiracMDCTStereoSID_fx( return; } - - -#ifdef IVAS_CODE_CNG - -/*------------------------------------------------------------------- - * generate_stereo_masking_noise() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_stereo_masking_noise( - float *syn, /* i/o: time-domain signal */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t fadeOut, /* i : only fade out of previous state */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -) -{ - HANDLE_FD_CNG_COM hFdCngCom; - float gamma, scale, SP_ratio; - float Np[L_FRAME16k]; - float Ns[L_FRAME16k]; - float N1[L_FRAME16k]; - float N2[L_FRAME16k]; - int16_t i; - - if ( st->idchan == 0 ) - { - hFdCngCom = st->hFdCngDec->hFdCngCom; - mvr2r( hFdCngCom->olapBufferSynth2, Np, hFdCngCom->frameSize / 2 ); - mvr2r( hStereoCng->olapBufferSynth22, Ns, hFdCngCom->frameSize / 2 ); - set_f( &Np[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 ); - set_f( &Ns[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 ); - - if ( !fadeOut ) - { - generate_masking_noise_fx( N1, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); - /* Generate masking noise for secondary channel */ - if ( flag_sec_CNA ) - { - generate_masking_noise_fx( N2, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); - gamma = hStereoCng->c_PS_LT * hStereoCng->c_PS_LT; - scale = 1.0f; - if ( gamma < 0.9f ) - { - gamma = gamma / ( 1 - gamma ); - gamma = (float) sqrt( gamma + 1 ) - (float) sqrt( gamma ); - scale = 1.0f / (float) sqrt( 1 + gamma * gamma ); - } - else - { - gamma = 0.0f; - } - - for ( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) - { - Np[i] += scale * ( N1[i] + gamma * N2[i] ); - Ns[i] += scale * sign( hStereoCng->c_PS_LT ) * ( N1[i] - gamma * N2[i] ); - } - for ( ; i < hFdCngCom->frameSize; i++ ) - { - Np[i] = scale * ( N1[i] + gamma * N2[i] ); - Ns[i] = scale * sign( hStereoCng->c_PS_LT ) * ( N1[i] - gamma * N2[i] ); - } - scale *= (float) ( hFdCngCom->fftlen / 2 ); - for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) - { - hFdCngCom->olapBufferSynth2[i] = scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] + gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); - hStereoCng->olapBufferSynth22[i] = sign( hStereoCng->c_PS_LT ) * scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] - gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); - } - } - else - { - for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) - { - Np[i] += N1[i]; - } - mvr2r( &N1[hFdCngCom->frameSize / 2], &Np[hFdCngCom->frameSize / 2], hFdCngCom->frameSize / 2 ); - scale = (float) ( hFdCngCom->fftlen / 2 ); - for ( i = 0; i < hFdCngCom->frameSize; i++ ) - { - hFdCngCom->olapBufferSynth2[i] = scale * hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4]; - } - } - } - else - { - set_f( hFdCngCom->olapBufferSynth2, 0.0f, hFdCngCom->frameSize / 2 ); - set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize / 2 ); - } - if ( flag_sec_CNA ) - { - mvr2r( Ns, hStereoCng->maskingNoiseS, hFdCngCom->frameSize ); - hStereoCng->enableSecCNA = 1; - } - else - { - set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize ); - } - - /* add masking noise */ - v_add( Np, syn, syn, hFdCngCom->frameSize ); - } - else if ( hStereoCng->enableSecCNA ) - { - SP_ratio = hStereoTD->SP_ratio_LT; /* Use long-term SP ratio based on L/R synthesis */ - /* scale and add masking noise */ - for ( i = 0; i < *hStereoCng->frameSize / 4; i++ ) - { - scale = ( ( hStereoTD->prevSP_ratio * ( *hStereoCng->frameSize / 4 - (float) i ) + SP_ratio * (float) i ) / ( *hStereoCng->frameSize / 4 ) ); - syn[i] += scale * hStereoCng->maskingNoiseS[i]; - } - for ( ; i < *hStereoCng->frameSize / 2; i++ ) - { - syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i]; - } - for ( ; i < *hStereoCng->frameSize; i++ ) - { - syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i]; - } - hStereoTD->prevSP_ratio = SP_ratio; - } - - return; -} - -/*------------------------------------------------------------------- - * generate_masking_noise_hf_cldfb() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_masking_noise_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - float *Cldfb_RealBuffer, /* o : CLDFD real buffer */ - float *Cldfb_ImagBuffer, /* o : CLDFD imaginary buffer */ - const int16_t slot_index, /* i : CLDFB slot index */ - const int16_t cna_flag, /* i : CNA flag for LB and HB */ - const int16_t fd_cng_flag /* i : FD-CNG flag for HB */ -) -{ - int16_t i; - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *fftBuffer = hFdCngCom->fftBuffer; - float *ptr_r; - float *ptr_i; - float *ptr_level; - int16_t *seed = &( hFdCngCom->seed ); - float scale; - - wmops_sub_start( "fd_cng_dirac" ); - - /* Init */ - scale = 0.f; - - /* Resample CLDFB memories if necessary*/ - if ( ( h_cldfb->no_channels * h_cldfb->no_col ) != hFdCngCom->frameSize ) - { - resampleCldfb( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); - } - - set_zero( Cldfb_RealBuffer, CLDFB_NO_CHANNELS_MAX ); - set_zero( Cldfb_ImagBuffer, CLDFB_NO_CHANNELS_MAX ); - - /*LB CLDFB - CNA from STFT*/ -#ifdef DEBUG_MODE_DIRAC - { - int16_t tmp_s; - tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f ); - dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" ); - } -#endif - if ( cna_flag ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) - { - /* Compute additional CN level */ - for ( i = 0; i < 15; i++ ) - { - if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_dirac[i].bwmode ) && - ( hFdCngCom->CngBitrate >= scaleTable_cn_dirac[i].bitrateFrom ) && - ( hFdCngCom->CngBitrate < scaleTable_cn_dirac[i].bitrateTo ) ) - { - break; - } - } - - scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale / 10.f ) - 1.f; - scale *= hFdCngCom->likelihood_noisy_speech; - } - } - - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - if ( cna_flag && tdBuffer != NULL ) - { - if ( scale != 0 ) - { - /*Generate LF comfort noise only at first slot, for the whole frame*/ - if ( slot_index == 0 ) - { - ptr_level = cngNoiseLevel; - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ - if ( hFdCngCom->startBand == 0 ) - { - rand_gauss( &fftBuffer[0], seed ); - ptr_r = fftBuffer + 2; - fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ - ptr_level++; - } - else - { - fftBuffer[0] = 0.f; - set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngCom->startBand - 1 ) ); - ptr_r = fftBuffer + 2 * hFdCngCom->startBand; - } - ptr_i = ptr_r + 1; - - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) - { - /* Real part in FFT bins */ - rand_gauss( ptr_r, seed ); - ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); - ptr_r += 2; - /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, seed ); - ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); - ptr_i += 2; - } - - /* Remaining FFT bins are set to zero */ - set_f( fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin ); - /* Nyquist frequency is discarded */ - fftBuffer[1] = 0.f; - - /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, tdBuffer, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, X, Y, -1, -1 ); - -#ifdef DEBUG_MODE_DIRAC - { - int16_t tmp[1000]; - - for ( i = 0; i < hFdCngCom->frameSize; i++ ) - { - tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); - } - dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); - } -#endif - } - - /* LF CLDFB*/ - cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); - } - else - { - if ( slot_index == 0 ) - { - /* very low level case - update random seeds */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set_f( fftBuffer, 0.f, hFdCngCom->fftlen ); - - /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, tdBuffer, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, X, Y, -1, -1 ); - -#ifdef DEBUG_MODE_DIRAC - { - int16_t tmp[1000]; - - for ( i = 0; i < hFdCngCom->frameSize; i++ ) - { - tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); - } - dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); - } -#endif - } - - /* LB ana CLDFB*/ - cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); - } - } - - /*HF CLDFB - CNA and/or FD-CNG*/ - if ( fd_cng_flag ) - { - scale += 1.f; - } - if ( scale != 0 ) - { - scale *= CLDFB_SCALING_FLT * ( h_cldfb->scale * h_cldfb->scale * 8.f ); - ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; - - for ( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) - { - /* Real part in CLDFB band */ - rand_gauss( &Cldfb_RealBuffer[i], seed ); - Cldfb_RealBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); - /* Imaginary part in CLDFB band */ - rand_gauss( &Cldfb_ImagBuffer[i], seed ); - Cldfb_ImagBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); - - ptr_level++; - } - } - - wmops_sub_end(); - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeMDCTStereoSID() - * - * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream - * - *-------------------------------------------------------------------*/ - -void FdCngDecodeMDCTStereoSID( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - float *ms_ptr[CPE_CHANNELS]; - float *lr_ptr[CPE_CHANNELS]; - float logNoiseEst[CPE_CHANNELS][NPART]; - float gain[CPE_CHANNELS]; - int16_t indices[FD_CNG_stages_37bits]; - int16_t N, i, ch, p, stages; - int16_t is_out_ms; - - is_out_ms = 0; - if ( hCPE->hCoreCoder[0]->cng_sba_flag ) - { - is_out_ms = 1; - } - - N = 0; /* to avoid compilation warning */ - - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; - } - - /* decode noise shapes and gains */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; - hFdCngCom->sid_frame_counter++; - - if ( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - } - else - { - stages = FD_CNG_stages_37bits; - } - - /* read bitstream */ - for ( i = 0; i < stages; i++ ) - { - indices[i] = get_next_indice( sts[ch], bits_37bits[i] ); - } - { - gain[ch] = ( (float) get_next_indice( sts[ch], 7 ) - GAIN_Q_OFFSET_IVAS ) / 1.5f; - } - - /* MSVQ decoder */ - msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, ms_ptr[ch], NULL ); - } - - if ( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) - { - set_zero( ms_ptr[1], NPART ); - } - - if ( is_out_ms == 0 ) - { - inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f ); - } - - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - for ( p = 0; p < N; p++ ) - { - lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f ); - } - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - - if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_4k4 ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - for ( p = 0; p < N; p++ ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); - } - } - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeDiracMDCTStereoSID() - * - * Decode FD-Cng parameters for CNG in 2TC DirAC mode from the bitstream - *-------------------------------------------------------------------*/ - -void FdCngDecodeDiracMDCTStereoSID( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - float *ms_ptr[CPE_CHANNELS]; - float *lr_ptr[CPE_CHANNELS]; - float logNoiseEst[CPE_CHANNELS][NPART]; - float gain[CPE_CHANNELS]; - int16_t indices[FD_CNG_stages_37bits]; - int16_t N, i, ch, p; - - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; - ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; - } - - /* decode noise shapes and gains */ - hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; - - /* read bitstream */ - for ( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice( sts[0], bits_37bits[i] ); - } - gain[0] = ( (float) get_next_indice( sts[0], 7 ) - GAIN_Q_OFFSET_IVAS ) / 1.5f; - gain[1] = gain[0]; - - /* MSVQ decoder */ - msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, ms_ptr[0], NULL ); - mvr2r( ms_ptr[0], ms_ptr[1], N ); - - /*inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f );*/ - - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - for ( p = 0; p < N; p++ ) - { - lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f ); - } - - /* NB last band energy compensation */ - if ( hFdCngCom->CngBandwidth == NB ) - { - lr_ptr[ch][N - 1] *= NB_LAST_BAND_SCALE; - } - else if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 ) - { - lr_ptr[ch][N - 1] *= SWB_13k2_LAST_BAND_SCALE; - } - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; - sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; - - if ( hCPE->nchan_out == 1 ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - for ( p = 0; p < N; p++ ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); - } - sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; - sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; - } - - return; -} -#endif diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 50f479d8d..97db8d2a0 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1058,19 +1058,6 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru BSTR_ENC_HANDLE hBstr = corest->hBstr; HANDLE_FD_CNG_COM st; Word16 maxC_37bits = FD_CNG_maxC_37bits, stages_37bits = FD_CNG_stages_37bits, maxN_37bits = FD_CNG_maxN_37bits; -#ifdef IVAS_CODE_CNG - float *invTrfMatrix; - float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; - float tot_sig_ext[FDCNG_VQ_MAX_LEN]; - const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS; - /* Init */ - N = hFdCngEnc->npartDec; - - invTrfMatrix = (float *) tmpRAM; /* dynamically filled */ - set_zero( v, FDCNG_VQ_MAX_LEN ); -#endif - /* Init */ st = stenc->hFdCngCom; @@ -1120,29 +1107,6 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru v16[i] = extract_h( L_sub( v[i], gain ) ); } -#ifdef IVAS_CODE_CNG - IF( st->element_mode != EVS_MONO ) - { - /* DCT domain compressed/truncated indices used for first stage */ - /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched - in FDCNG band domain - */ - if ( N == FDCNG_VQ_MAX_LEN_WB ) - { - create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); - /* truncated DCT21 analysis */ - dctT2_N_apply_matrix( (const float *) v, dct_target, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); - /* truncated IDCT21 extension to 24 bands */ - extend_dctN_input( v, dct_target, N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); - - mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ - } - create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); - msvq_enc_fx( cdk_37bits_ivas, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices ); - msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL ); - } - ELSE -#endif { /* MSVQ encoder */ msvq_encoder( cdk_37bits, v16, levels_37bits, maxC_37bits, stages_37bits, N, maxN_37bits, indices ); @@ -1166,28 +1130,14 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru /* Apply bitrate-dependant scale */ -#ifdef IVAS_CODE_CNG - if ( st->element_mode > EVS_MONO ) - { - apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - } - else -#endif { apply_scale( &gain, st->CngBandwidth, st->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); } -#ifdef IVAS_CODE_CNG - /* Quantize gain, Q14.23 format */ - gain = L_add( gain, L_shr( gain, 1 ) ); - gain = L_add( gain, gain_q_offset /*gain_q_offset+.5 Q23*/ ); - index = extract_l( L_shr( gain, WORD32_BITS - 1 - 8 ) ); -#else /* Quantize gain, Q14.23 format */ gain = L_add( gain, L_shr( gain, 1 ) ); gain = L_add( gain, 507510784l /*60.5 Q23*/ ); index = extract_l( L_shr( gain, WORD32_BITS - 1 - 8 ) ); -#endif if ( index < 0 ) { @@ -1200,17 +1150,11 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru index = 127; move16(); } -#ifndef IVAS_CODE_CNG + /* gain Q14.23 format */ gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); gain = L_sub( gain, 503316480l /*60.0 Q23*/ ); gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); -#else - /* gain Q14.23 format */ - gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); - gain = L_sub( gain, gain_q_offset /*60.0 Q23*/ ); - gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); -#endif /* Apply gain and undo log */ -- GitLab From b2d415f2fd3b80ac464075000c7c571f9b886706 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 15:49:55 +0530 Subject: [PATCH 0312/1221] Partial fix for 3GPP issue 1303: Obvious spectral discrepencies between signals decoded from fixed- and floating-point encoded bitstreams at 13.2kbps with -16LKFS FOA input sampled at 48kHz and optimizations Link #1303 --- lib_enc/cod_tcx_fx.c | 106 +++++++++++++-------------------------- lib_enc/swb_bwe_enc_fx.c | 4 +- 2 files changed, 37 insertions(+), 73 deletions(-) diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 93c1dc58d..de9763df0 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -5379,13 +5379,13 @@ void TNSAnalysisStereo_fx( ) { Word16 ch, k, L_spec, L_frame, nSubframes, iFilter; - Word32 *spectrum_fx; + Word32 *spectrum_fx, sum; Encoder_State *st = NULL; TCX_ENC_HANDLE hTcxEnc = NULL; Word16 individual_decision[NB_DIV]; Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; move32(); - Word16 maxPredictionGain_e = Q31, meanPredictionGain_e; + Word16 maxPredictionGain_e = 0, meanPredictionGain_e; move16(); Word16 sum_e = 0; move16(); @@ -5544,31 +5544,21 @@ void TNSAnalysisStereo_fx( */ meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e - Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, meanPredictionGain_fx, meanPredictionGain_e ); - IF( flag < 0 ) + + /* maxPredictionGain = max( maxPredictionGain, meanPredictionGain );*/ + IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, meanPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */ { maxPredictionGain_fx = meanPredictionGain_fx; maxPredictionGain_e = meanPredictionGain_e; move32(); move16(); } - flag = BASOP_Util_Cmp_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } - Word16 flag_1 = BASOP_Util_Cmp_Mant32Exp( pFilter[1]->predictionGain32, pFilter[1]->predictionGain_e, L_deposit_h( pTnsParameters[1]->minPredictionGain ), PRED_GAIN_E ); - if ( flag_1 < 0 ) - { - flag_1 = 0; - move16(); - } + test(); test(); test(); - IF( flag && LT_32( sts[0]->element_brate, IVAS_80k ) && - flag_1 && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + IF( GT_32( pFilter[0]->predictionGain32, L_shl_sat( L_deposit_h( pTnsParameters[0]->minPredictionGain ), sub( PRED_GAIN_E, pFilter[0]->predictionGain_e ) ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && + GT_32( pFilter[1]->predictionGain32, L_shl_sat( L_deposit_h( pTnsParameters[1]->minPredictionGain ), sub( PRED_GAIN_E, pFilter[1]->predictionGain_e ) ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) { pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ move32(); @@ -5578,39 +5568,29 @@ void TNSAnalysisStereo_fx( move16(); pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */ move16(); - move16(); - } - flag = BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ), meanPredictionGain_e, L_abs( BASOP_Util_Add_Mant32Exp( pFilter[0]->predictionGain32, pFilter[0]->predictionGain_e, L_negate( pFilter[1]->predictionGain32 ), pFilter[1]->predictionGain_e, &sum_e ) ), sum_e ); - if ( flag < 0 ) - { - flag = 0; - move16(); } - test(); - IF( flag && + sum_e = s_max( pFilter[0]->predictionGain_e, pFilter[1]->predictionGain_e ); + sum = L_abs( L_sub_sat( L_shl( pFilter[0]->predictionGain32, sub( pFilter[0]->predictionGain_e, sum_e ) ), L_shl( pFilter[1]->predictionGain32, sub( pFilter[1]->predictionGain_e, sum_e ) ) ) ); // sum_e + + IF( LT_32( L_shl_sat( sum, sub( sum_e, meanPredictionGain_e ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) { Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - // maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); - flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, meanPredictionGain_fx, meanPredictionGain_e ); - IF( flag < 0 ) + + /* maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); */ + IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, maxPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */ { maxPredGain_fx = meanPredictionGain_fx; maxPredGain_e = meanPredictionGain_e; move32(); move16(); } - flag = BASOP_Util_Cmp_Mant32Exp( meanPredictionGain_fx, meanPredictionGain_e, L_deposit_h( pTnsParameters[0]->minPredictionGain ), PRED_GAIN_E ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } + test(); test(); - IF( flag || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + IF( GT_32( meanPredictionGain_fx, L_shl_sat( L_deposit_h( pTnsParameters[0]->minPredictionGain ), sub( PRED_GAIN_E, meanPredictionGain_e ) ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) { test(); test(); @@ -5813,16 +5793,13 @@ void TNSAnalysisStereo_fx( move16(); } } - Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } + test(); test(); test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && flag && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && individual_decision[k] == 0 && + LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && + NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; move16(); @@ -5842,9 +5819,9 @@ void TNSAnalysisStereo_fx( ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); } } - // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); - flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); - IF( flag < 0 ) + + /* maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); */ + IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* exp: maxPredGain_e */ { maxPredictionGain_fx = maxPredGain_fx; maxPredictionGain_e = maxPredGain_e; @@ -5902,22 +5879,16 @@ void TNSAnalysisStereo_fx( pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); - Word16 flag = BASOP_Util_Cmp_Mant32Exp( maxPredGain_fx, maxPredGain_e, pFilter->predictionGain32, pFilter->predictionGain_e ); - IF( flag < 0 ) + IF( GT_32( pFilter->predictionGain32, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, pFilter->predictionGain_e ) ) ) ) /* pFilter->predictionGain_e */ { maxPredGain_fx = pFilter->predictionGain32; - move32(); maxPredGain_e = pFilter->predictionGain_e; + move32(); move16(); } - flag = BASOP_Util_Cmp_Mant32Exp( pFilter->predictionGain32, pFilter->predictionGain_e, L_deposit_h( pTnsParameters->minPredictionGain ), PRED_GAIN_E ); - if ( flag < 0 ) - { - flag = 0; - move16(); - } + test(); - IF( flag || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + IF( GT_32( pFilter->predictionGain32, L_shl_sat( L_deposit_h( pTnsParameters->minPredictionGain ), sub( PRED_GAIN_E, pFilter->predictionGain_e ) ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) { test(); test(); @@ -5980,24 +5951,17 @@ void TNSAnalysisStereo_fx( } } - IF( ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[ch]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[ch]->hTcxEnc->fUseTns[k] = 0; - } + sts[ch]->hTcxEnc->fUseTns[k] = 0; move16(); - Word16 flag = BASOP_Util_Cmp_Mant32Exp( TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23, PRED_GAIN_E, maxPredGain_fx, maxPredGain_e ); - if ( flag < 0 ) + if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) { - flag = 0; + sts[ch]->hTcxEnc->fUseTns[k] = 1; move16(); } + test(); test(); - IF( !bWhitenedDomain && flag && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[ch]->hTcxEnc->fUseTns[k] = 0; move16(); @@ -6012,9 +5976,9 @@ void TNSAnalysisStereo_fx( move16(); } } + // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); - flag = BASOP_Util_Cmp_Mant32Exp( maxPredictionGain_fx, maxPredictionGain_e, maxPredGain_fx, maxPredGain_e ); - IF( flag < 0 ) + IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* maxPredGain_e */ { maxPredictionGain_fx = maxPredGain_fx; maxPredictionGain_e = maxPredGain_e; diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 01ac8383f..639ec9dca 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -3205,7 +3205,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( tmp = i_mult2( n_band, L ); FOR( i = 0; i < L; i++ ) { - WB_tenv_syn_fx = L_add( WB_tenv_syn_fx, L_shr( L_mult0( synth_fx[i + tmp], synth_fx[i + tmp] ), 7 ) ); /*2*st_fx->Q_syn2 - 7 */ + WB_tenv_syn_fx = L_add( WB_tenv_syn_fx, L_shr( L_mult0( synth_fx[i + tmp], synth_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp-7 */ WB_tenv_orig_fx = L_add( WB_tenv_orig_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp - 7 */ } @@ -3239,7 +3239,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( #else den = round_fx( L_shl( WB_tenv_syn_fx, expd ) ); #endif - expd = sub( sub( 30, expd ), sub( shl( st_fx->Q_syn2, 1 ), 7 ) ); + expd = sub( sub( 30, expd ), sub( shl( Q_insig_lp, 1 ), 7 ) ); scale = shr( sub( den, num ), 15 ); num = shl( num, scale ); -- GitLab From ebf10d0b6924fb45346d9e863aed1397d3871066 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 11:20:20 +0100 Subject: [PATCH 0313/1221] review and remove redundant code under IVAS_CODE --- lib_com/bits_alloc_fx.c | 3 +- lib_dec/acelp_core_dec_fx.c | 313 +---------------- lib_dec/dec_higher_acelp_fx.c | 8 +- lib_dec/evs_dec_fx.c | 4 - lib_dec/gs_dec_fx.c | 11 +- lib_dec/init_dec_fx.c | 8 - lib_dec/lsf_dec_fx.c | 2 - lib_enc/acelp_core_enc_fx.c | 1 - lib_enc/amr_wb_enc_fx.c | 10 +- lib_enc/cng_enc_fx.c | 60 +--- lib_enc/core_switching_enc_fx.c | 49 --- lib_enc/dtx_fx.c | 55 +-- lib_enc/enc_higher_acelp_fx.c | 15 - lib_enc/fd_cng_enc_fx.c | 5 - lib_enc/find_uv_fx.c | 51 +-- lib_enc/gain_enc_fx.c | 5 - lib_enc/inov_enc_fx.c | 83 +---- lib_enc/long_enr_fx.c | 60 +--- lib_enc/lsf_enc_fx.c | 32 -- lib_enc/nois_est_fx.c | 103 +----- lib_enc/pre_proc_fx.c | 22 +- lib_enc/prot_fx_enc.h | 21 +- lib_enc/speech_music_classif_fx.c | 68 +--- lib_enc/stat_enc.h | 535 +----------------------------- lib_enc/updt_enc_fx.c | 28 +- lib_enc/vad_fx.c | 12 +- 26 files changed, 61 insertions(+), 1503 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index f2a074ba5..88b276126 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -408,7 +408,7 @@ static Word16 BITS_ALLOC_adjust_acelp_fixed_cdk( return bitsused; } -/*#ifdef IVAS_CODE Below basop operators are missing */ + /*-------------------------------------------------------------------* * fcb_table() * @@ -3271,4 +3271,3 @@ Word16 set_ACELP_flag_IVAS( return 0; } } -/*#endif IVAS_CODE*/ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 903a37163..1d59d1269 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -143,66 +143,6 @@ ivas_error acelp_core_dec_fx( return error; } - -#ifdef IVAS_CODE - output_frame = (int16_t) ( st->output_Fs / FRAMES_PER_SEC ); - - /*----------------------------------------------------------------* - * stereo SID and CNG frames processing - *----------------------------------------------------------------*/ - - if ( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) - { - if ( st->cng_type == FD_CNG ) - { - configureFdCngDec_fx( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); - - /* Only run parameter decoding in SID frames */ - if ( st->core_brate == SID_2k40 ) - { - FdCng_decodeSID_fx( st ); - } - - for ( i = 0; i < NPART; i++ ) - { - st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; - } - -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( NULL, NULL, NULL, NULL, st, 0, 0 ); -#else - ApplyFdCng_fx( NULL, NULL, NULL, NULL, st, 0, 0 ); -#endif - } - else - { - configureFdCngDec_fx( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); - - /* decode CNG parameters */ - CNG_dec( st, last_element_mode, Aq, lsp_new, lsf_new, &allow_cn_step, sid_bw, q_env ); - - /* comfort noise generation */ - CNG_exc( st->core_brate, st->L_frame, &st->hTdCngDec->Enew, &st->hTdCngDec->cng_seed, NULL, NULL, &st->lp_ener, st->last_core_brate, &st->first_CNG, &( st->hTdCngDec->cng_ener_seed ), NULL, allow_cn_step, &st->hTdCngDec->last_allow_cn_step, st->hTdCngDec->num_ho, q_env, st->hTdCngDec->lp_env, st->hTdCngDec->old_env, st->hTdCngDec->exc_mem, st->hTdCngDec->exc_mem1, sid_bw, &st->hTdCngDec->cng_ener_seed1, NULL, st->Opt_AMR_WB, st->element_mode ); - - mvr2r( Aq, st->Aq_cng, M + 1 ); - - /* update old LSP and LSF vector */ - mvr2r( lsf_new, st->lsf_old, M ); - mvr2r( lsp_new, st->lsp_old, M ); - } - - set_f( output, 0, output_frame ); /* output and synth are not used in DFT domain CNG generation and the decoder output is unaffected if they are left uninitalized */ - set_f( synth, 0, output_frame ); /* They are however read in a few places which causes errors in the valgrind tests. Simplest solution from a code perspective was to set them to zero. */ - - /* CN generation done in DFT domain */ - wmops_sub_end(); - return error; - } - - /*----------------------------------------------------------------* - * Active frames processing - *----------------------------------------------------------------*/ -#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { set32_fx( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); @@ -265,13 +205,7 @@ ivas_error acelp_core_dec_fx( move32(); } } -#ifdef IVAS_CODE - if ( st->hFdCngDec != NULL && ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( st->last_core_brate == SID_2k40 || st->last_core_brate == FRAME_NO_DATA ) ) - { - set_zero( st->hFdCngDec->hFdCngCom->olapBufferSynth2, FFTLEN ); - set_zero( hStereoCng->olapBufferSynth22, FFTLEN ); - } -#endif + st_fx->clas_dec = st_fx->last_good; move16(); enr_q_fx = 0; @@ -413,7 +347,7 @@ ivas_error acelp_core_dec_fx( Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); // Qlog2(2.56) } set16_fx( st_fx->mem_MA_fx, 0, M ); -#if 1 // def IVAS_CODE + dec = DEC; move16(); IF( NE_16( st_fx->element_mode, EVS_MONO ) ) @@ -424,9 +358,7 @@ ivas_error acelp_core_dec_fx( /* update synthesis filter memories */ synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); -#else - synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC ); -#endif + Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); // Q_exc Copy_Scale_sig( st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/ @@ -591,7 +523,7 @@ ivas_error acelp_core_dec_fx( { tc_subfr_fx = tc_classif_fx( st_fx, st_fx->L_frame ); } -#if 1 // def IVAS_CODE + /*----------------------------------------------------------------* * Decoding of GSC IVAS mode *----------------------------------------------------------------*/ @@ -611,7 +543,7 @@ ivas_error acelp_core_dec_fx( move16(); } } -#endif + /*----------------------------------------------------------------* * Decoding of inactive CNG frames *----------------------------------------------------------------*/ @@ -623,22 +555,13 @@ ivas_error acelp_core_dec_fx( { CNG_dec_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); -#ifdef IVAS_CODE - local_element_mode = st_fx->element_mode; - move16(); - IF( ( EQ_16( nchan_out, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) || EQ_16( st_fx->masa_sid_format, 1 ) ) - { - local_element_mode = IVAS_SCE; /* For DFT Stereo mono decoding, run CNG_exc as in SCE */ - move16(); - } -#endif + /* comfort noise generation */ CNG_exc_fx( st_fx->core_brate, st_fx->L_frame, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, &st_fx->first_CNG, &( st_fx->hTdCngDec->cng_ener_seed ), bwe_exc_fx, allow_cn_step_fx, &st_fx->hTdCngDec->last_allow_cn_step, st_fx->prev_Q_exc, st_fx->Q_exc, st_fx->hTdCngDec->num_ho, q_env, st_fx->hTdCngDec->lp_env_fx, st_fx->hTdCngDec->old_env_fx, st_fx->hTdCngDec->exc_mem_fx, st_fx->hTdCngDec->exc_mem1_fx, sid_bw, &st_fx->hTdCngDec->cng_ener_seed1, exc3_fx, st_fx->Opt_AMR_WB, st_fx->element_mode ); -#if 1 // def IVAS_CODE + Copy( Aq_fx, st_fx->Aq_cng, M + 1 ); // Q12 -#endif } ELSE { @@ -649,32 +572,7 @@ ivas_error acelp_core_dec_fx( *sid_bw = 0; move16(); } -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_DFT ) - { - assert( nchan_out == 1 ); - for ( i = 0; i < NPART; i++ ) - { - st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; - } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( syn, 0, NULL, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else - ApplyFdCng_fx( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#endif - } - if ( !read_sid_info ) - { - float noise_lvl_highest; - - noise_lvl_highest = st->hFdCngDec->hFdCngCom->cngNoiseLevel[st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand - 1]; - for ( int16_t b = st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand; b < st->hFdCngDec->hFdCngCom->stopBand; b++ ) - { - st->hFdCngDec->hFdCngCom->cngNoiseLevel[b] = noise_lvl_highest; - } - } -#endif generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); FdCng_exc( st_fx->hFdCngDec->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); @@ -809,10 +707,6 @@ ivas_error acelp_core_dec_fx( move16(); st_fx->last_nq_preQ = 0; move16(); -#ifdef IVAS_CODE - st_fx->last_code_preq = 0; - move16(); -#endif } st_fx->use_acelp_preq = 0; @@ -1409,103 +1303,8 @@ ivas_error acelp_core_dec_fx( #endif } /* CNA: Generate additional comfort noise to mask potential coding artefacts */ - -#ifdef IVAS_CODE - if ( !st->cna_dirac_flag ) - { - /* CNA: Generate additional comfort noise to mask potential coding artefacts */ - if ( st->flag_cna && !( st->coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->GSC_noisy_speech ) ) ) - { - if ( st->element_mode == IVAS_CPE_TD && nchan_out == 2 ) - { - if ( hStereoCng->flag_cna_fade ) - { - generate_stereo_masking_noise( syn, st, hStereoTD, flag_sec_CNA, 1, hStereoCng, nchan_out ); - hStereoCng->flag_cna_fade = 0; - } - else - { - if ( st->element_mode != last_element_mode && st->idchan == 0 ) - { - /* Clear memory for secondary channel CNA */ - set_f( hStereoCng->olapBufferSynth22, 0.0f, st->hFdCngDec->hFdCngCom->frameSize / 2 ); - } - - generate_stereo_masking_noise( syn, st, hStereoTD, flag_sec_CNA, 0, hStereoCng, nchan_out ); - } - } - else if ( st->element_mode != IVAS_CPE_DFT ) - { - if ( st->idchan == 0 ) - { - if ( st->element_mode != last_element_mode ) - { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.0f, st->hFdCngDec->hFdCngCom->fftlen ); - } - generate_masking_noise_fx( syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); - } - } - } - else if ( st->flag_cna && st->coder_type == AUDIO && ( ( st->last_core == ACELP_CORE && !( st->last_coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || st->last_core == TCX_20_CORE ) ) - { - if ( st->element_mode == IVAS_CPE_TD && nchan_out == 2 ) - { - generate_stereo_masking_noise( syn, st, hStereoTD, flag_sec_CNA, 1, hStereoCng, nchan_out ); - hStereoCng->flag_cna_fade = 1; - } - else - { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->hFdCngDec->hFdCngCom->frameSize / 4, (float) ( st->hFdCngDec->hFdCngCom->fftlen / 2 ), temp_buf, st->hFdCngDec->hFdCngCom->frameSize / 2 ); - v_add( temp_buf, syn, syn, st->hFdCngDec->hFdCngCom->frameSize / 2 ); - } - } - else - { - if ( hStereoCng != NULL ) - { - hStereoCng->flag_cna_fade = 1; - hStereoCng->enableSecCNA = 0; - } - } - - if ( st->element_mode == IVAS_CPE_TD ) - { - /*Noise estimate*/ - if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) - { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( syn, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else - ApplyFdCng_fx( syn, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#endif - } - } - } -#endif } -#ifdef IVAS_CODE - if ( !st->cna_dirac_flag ) - { - if ( st->flag_cna == 0 && st->L_frame == L_FRAME16k && st->last_flag_cna == 1 && ( ( st->last_core == ACELP_CORE && !( st->last_coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || st->last_core == AMR_WB_CORE ) ) - { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2 ); - v_add( temp_buf, syn, syn, st->L_frame / 2 ); - } - - if ( st->flag_cna == 0 || ( st->coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->GSC_noisy_speech ) ) ) - { - if ( st->idchan == 0 ) - { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); - } - if ( hStereoCng != NULL && st->idchan == 0 ) - { - set_f( hStereoCng->olapBufferSynth22, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); - } - } - } -#else test(); test(); test(); @@ -1522,29 +1321,6 @@ ivas_error acelp_core_dec_fx( move16(); } } -#endif - -#ifndef IVAS_CODE - test(); - test(); - test(); - test(); - test(); - IF( st_fx->flag_cna == 0 && EQ_16( st_fx->L_frame, L_FRAME16k ) && EQ_16( st_fx->last_flag_cna, 1 ) && ( ( st_fx->last_core == ACELP_CORE && NE_16( st_fx->last_coder_type, AUDIO ) ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) - { - FOR( i = 0; i < st_fx->L_frame / 2; i++ ) - { - syn_fx[i] = add( syn_fx[i], shr_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->L_frame / 4], negate( st_fx->Q_syn ) ) ); - move16(); - } - } - - test(); - IF( st_fx->flag_cna == 0 || EQ_16( st_fx->coder_type, AUDIO ) ) - { - set16_fx( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st_fx->hFdCngDec->hFdCngCom->fftlen ); - } -#endif } /*----------------------------------------------------------------* @@ -1589,20 +1365,6 @@ ivas_error acelp_core_dec_fx( test(); IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) { -#ifdef IVAS_CODE - float realBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float imagBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float *pRealSave[CLDFB_NO_COL_MAX], *pImagSave[CLDFB_NO_COL_MAX]; - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - pRealSave[i] = realBufferSave[i]; - pImagSave[i] = imagBufferSave[i]; - } - if ( st->p_bpf_noise_buf ) - { - mvr2r( bpf_error_signal, st->p_bpf_noise_buf, st->L_frame ); - } -#endif /* analysis of the synthesis at internal sampling rate */ cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); @@ -1663,40 +1425,6 @@ ivas_error acelp_core_dec_fx( /* synthesis of the combined signal */ st_fx->Q_syn2 = st_fx->Q_syn; move16(); -#ifdef IVAS_CODE - if ( save_hb_synth != NULL ) - { - /* save and then zero-out lowband */ - for ( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - realBufferSave[i][j] = realBuffer[i][j]; - imagBufferSave[i][j] = imagBuffer[i][j]; - if ( j < st->hFdCngDec->hFdCngCom->numCoreBands && i < st->hFdCngDec->hFdCngCom->numSlots ) - { - realBuffer[i][j] = 0.0f; - imagBuffer[i][j] = 0.0f; - } - } - } - - cldfbSynthesis( realBuffer, imagBuffer, save_hb_synth, -1, st->cldfbSynHB ); - - /* restore lowband */ - for ( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - realBuffer[i][j] = realBufferSave[i][j]; - imagBuffer[i][j] = imagBufferSave[i][j]; - } - } - - cldfbSynthesis( pRealSave, pImagSave, synth, -1, st->cldfbSyn ); - } - else -#endif { cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); } @@ -1708,34 +1436,7 @@ ivas_error acelp_core_dec_fx( /* save synthesis - needed in case of core switching */ Copy( synth_out, st_fx->previoussynth_fx, output_frame ); } -#ifdef IVAS_CODE - ELSE - { - int16_t nSamples = NS2SA( st->L_frame * FRAMES_PER_SEC, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ - - /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ - cldfbAnalysis( syn + st->L_frame - nSamples, realBuffer, imagBuffer, nSamples, st->cldfbAna ); - - /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ - addBassPostFilter( bpf_error_signal + st->L_frame - nSamples, st->bpf_off ? 0 : nSamples, realBuffer, imagBuffer, st->cldfbBPF ); - /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ - cldfbSynthesis( realBuffer, imagBuffer, synth /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); - - if ( st->p_bpf_noise_buf ) - { - mvr2r( bpf_error_signal, st->p_bpf_noise_buf, st->L_frame ); - } - - set_f( synth, 0.0f, output_frame ); - } - - /* Copy output signal */ - if ( st->element_mode > EVS_MONO ) - { - mvr2r( syn, output, st->L_frame ); - } -#endif /*-----------------------------------------------------------------* * Bandwidth extension 6kHz-7kHz *-----------------------------------------------------------------*/ diff --git a/lib_dec/dec_higher_acelp_fx.c b/lib_dec/dec_higher_acelp_fx.c index b1cb2b516..aff7e5656 100644 --- a/lib_dec/dec_higher_acelp_fx.c +++ b/lib_dec/dec_higher_acelp_fx.c @@ -8,7 +8,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ -#define IVAS_CODE #define IVAS_CODE_AVQ /*-----------------------------------------------------------------* * transf_cdbk_dec() @@ -36,7 +35,6 @@ void transf_cdbk_dec_fx( Flag Overflow = 0; move32(); #endif -#ifdef IVAS_CODE Word16 avq_bit_sFlag; Word16 trgtSvPos; Word16 Nsv; @@ -50,7 +48,7 @@ void transf_cdbk_dec_fx( move16(); avq_bit_sFlag = 1; } -#endif + /*--------------------------------------------------------------* * Set bit-allocation *--------------------------------------------------------------*/ @@ -112,7 +110,7 @@ void transf_cdbk_dec_fx( *gain_preQ = round_fx( L_tmp ); /* Q2*/ move16(); } -#ifdef IVAS_CODE + trgtSvPos = sub( Nsv, 1 ); test(); test(); @@ -126,7 +124,7 @@ void transf_cdbk_dec_fx( move16(); move16(); } -#endif + /*--------------------------------------------------------------* * Demultiplex and decode subvectors from bit-stream *--------------------------------------------------------------*/ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 5a12d1a2c..60e13dd8f 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -36,11 +36,7 @@ ivas_error evs_dec_fx( Word16 exp, fra; Word16 tmp_buffer_fx[L_FRAME48k]; Word16 tmp16, tmp16_2; -#ifdef IVAS_CODE Word16 synth_fx[L_FRAME48k]; -#else - Word16 synth_fx[L_FRAME48k + HQ_DELTA_MAX * HQ_DELAY_COMP]; -#endif Word16 fb_exc_fx[L_FRAME16k]; Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; Word16 Q_fb_exc; diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index a80cfe796..385339664 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -370,11 +370,8 @@ void decod_audio_fx( tmp_nb_bits_tot = st_fx->next_bit_pos; /* Q0 */ move16(); -#ifdef IVAS_CODE - if ( st_fx->extl_brate_fx_orig > 0 ) -#else + if ( st_fx->extl_brate > 0 ) -#endif { /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ @@ -873,17 +870,13 @@ void decod_audio_ivas_fx( tmp_nb_bits_tot = st_fx->next_bit_pos; /* Q0 */ move16(); -#if 1 // def IVAS_CODE + if ( st_fx->extl_brate_orig > 0 ) -#else - if ( st_fx->extl_brate > 0 ) -#endif { /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ } - test(); test(); if ( st_fx->coder_type == INACTIVE && LE_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->idchan == 0 ) diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index caa164df9..5d8aee302 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -20,10 +20,6 @@ ivas_error init_decoder_fx( Decoder_State *st_fx, /* o: Decoder static variables structure */ const Word16 idchan /* i : channel ID */ -#ifdef IVAS_CODE - , - const MC_MODE mc_mode /* i : MC mode */ -#endif ) { Word16 i; @@ -778,11 +774,7 @@ ivas_error init_decoder_fx( resampleCldfb( st_fx->cldfbBPF, newCldfbBands, st_fx->L_frame, 1 ); test(); -#ifdef IVAS_CODE - IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || idchan == 0 ) && NE_16( mc_mode, MC_MODE_MCT ) && NE_16( mc_mode, MC_MODE_PARAMUPMIX ) ) // TBV Fixed point missing -#else IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || idchan == 0 ) /*&& mc_mode != MC_MODE_MCT && mc_mode != MC_MODE_PARAMUPMIX*/ ) -#endif { /* Create FD_CNG instance */ diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index becf60759..d263e6dd3 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -195,7 +195,6 @@ void lsf_dec_fx( /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ st_fx->seed_acelp = extract_l( L_add( imult3216( 31821L /* Q0 */, add( shr( ( st_fx->seed_acelp ), 1 ), param_lpc[i] ) ), 13849L /* Q0 */ ) ); /* Q0 */ move16(); - // PMTE() /*IVAS_CODE to be completed */ } } IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) @@ -449,7 +448,6 @@ void lsf_dec_ivas_fx( /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ st_fx->seed_acelp = extract_l( L_add( imult3216( 31821L /* Q0 */, add( shr( ( st_fx->seed_acelp ), 1 ), param_lpc[i] ) ), 13849L /* Q0 */ ) ); /* Q0 */ move16(); - // PMTE() /*IVAS_CODE to be completed */ } } IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index dcee88325..94d7f0471 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -329,7 +329,6 @@ ivas_error acelp_core_enc_fx( { IF( hTdCngEnc != NULL ) { - /*IVAS_CODE CNG_att is missing */ enr = cng_energy_fx( st_fx->element_mode, st_fx->bwidth, hDtxEnc->CNG_mode, /*st_fx->hTdCngEnc->CNG_att*/ 0, exc_fx, st_fx->L_frame, Q_new ); // Q8 /* calculate the energy quantization index */ diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index d7dd47256..90bdc74a5 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -351,12 +351,7 @@ void amr_wb_enc_fx( high_lpn_flag = 0; move16(); /* Q0 flag */ - long_enr_fx( st, Etot, localVAD_HE_SAD, high_lpn_flag -#ifdef IVAS_CODE - , - NULL, 1, NULL, NULL -#endif - ); + long_enr_fx( st, Etot, localVAD_HE_SAD, high_lpn_flag ); relE = sub( Etot, st->lp_speech_fx ); /* Q8 */ IF( NE_16( st->bwidth, NB ) ) @@ -441,9 +436,6 @@ void amr_wb_enc_fx( noise_est_fx( st, old_pitch1, tmpN, epsP_h, epsP_l, Etot, relE, corr_shift, tmpE, fr_bands, &cor_map_sum, NULL, &sp_div, &Q_sp_div, &non_staX, &harm_flag, lf_E, &hNoiseEst->harm_cor_cnt, hNoiseEst->Etot_l_lp_fx, hNoiseEst->Etot_v_h2_fx, &hNoiseEst->bg_cnt, st->lgBin_E_fx, Q_new, Le_min_scaled, &sp_floor, NULL, -#ifdef IVAS_CODE - NULL, NULL, -#endif st->ini_frame ); /*----------------------------------------------------------------* diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 15cc1a9e7..179d0230b 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -727,11 +727,6 @@ void CNG_enc_fx( test(); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - // PMT("Code to be completed") -#ifdef IVAS_CODE - att = powf( 10.0f, hTdCngEnc->CNG_att / 20.0f ); - v_multc( res1, att, res1, st->L_frame ); -#endif } ELSE IF( NE_16( st_fx->bwidth, NB ) ) { @@ -909,9 +904,6 @@ void CNG_enc_fx( test(); IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - // PMT("CNG IVAS_SCE and IVAS_CPE_DFT code missing") - // IVAS_CODE - // enr += hTdCngEnc->CNG_att * FAC_LOG2 / 10.0f; } ELSE IF( NE_16( st_fx->bwidth, NB ) ) { @@ -2415,14 +2407,6 @@ void swb_CNG_enc_fx( } ELSE IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && EQ_32( st_fx->core_brate, SID_2k40 ) ) { - // PMT("CNG IVAS_CPE_DFT code not implemented") -#ifdef IVAS_CODE - /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */ - delete_indice( st->hBstr, IND_CNG_ENV1 ); - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); - push_indice( st->hBstr, IND_UNUSED, 0, 4 ); - push_indice( st->hBstr, IND_SID_BW, 1, 1 ); -#endif } } hTdCngEnc->last_vad = 0; @@ -2450,9 +2434,6 @@ static void shb_CNG_encod_fx( Word16 idx_ener_fx; TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; -#ifdef IVAS_CODE - Word16 ener_mid_dec_thr; -#endif idx_ener_fx = 0; move16(); @@ -2484,41 +2465,15 @@ static void shb_CNG_encod_fx( { idx_ener_fx = s_max( idx_ener_fx, 0 ); } -#ifdef IVAS_CODE - /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */ - if ( st->element_mode != EVS_MONO ) - { - if ( abs( idx_ener - st->hTdCngEnc->last_idx_ener ) == 1 ) - { - ener_mid_dec_thr = 0.5f * ( ( st->hTdCngEnc->last_idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f ); - ener_mid_dec_thr += 0.5f * ( ( idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f ); - - if ( fabs( st->hTdCngEnc->mov_shb_cng_ener - ener_mid_dec_thr ) / ener_mid_dec_thr < ENER_MID_DEAD_ZONE ) - { - idx_ener = st->hTdCngEnc->last_idx_ener; - } - } - } - st->hTdCngEnc->last_idx_ener = idx_ener; -#endif push_indice_fx( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice_fx( hBstr, IND_SID_BW, 1, 1 ); -#ifndef IVAS_CODE - hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); - hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; - move16(); - move16(); -#else delete_indice( hBstr, IND_CNG_ENV1 ); -#endif -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_DFT ) + + if ( st_fx->element_mode == IVAS_CPE_DFT ) { - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); } else -#endif { push_indice_fx( hBstr, IND_UNUSED, 0, 2 ); } @@ -2633,13 +2588,7 @@ static Word16 shb_DTX_fx( allow_cn_step_fx = 1; move16(); } -#ifdef IVAS_CODE - /* Also allow step if shb energy has dropped 12 dB */ - if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( ( hTdCngEnc->mov_shb_cng_ener - log_shb_ener ) > 12.0f ) ) - { - allow_cn_step = 1; - } -#endif + IF( EQ_16( allow_cn_step_fx, 1 ) ) { hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; @@ -2759,13 +2708,10 @@ void calculate_hangover_attenuation_gain_fx( test(); IF( hTdCngEnc->burst_ho_cnt > 0 && ( vad_hover_flag != 0 ) && ( NE_16( st->bwidth, NB ) || st->element_mode > EVS_MONO ) ) /* corresponds to line 504 in FLT acelp_core_enc.c */ { -#ifdef IVAS_CODE if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) { - *att = powf( 10.0f, ( st->hTdCngEnc->CNG_att / 160.0f ) * st->hTdCngEnc->burst_ho_cnt ); } else -#endif { offset = 5; move16(); diff --git a/lib_enc/core_switching_enc_fx.c b/lib_enc/core_switching_enc_fx.c index 6fa341a7b..dc3062298 100644 --- a/lib_enc/core_switching_enc_fx.c +++ b/lib_enc/core_switching_enc_fx.c @@ -373,31 +373,6 @@ void core_switching_pre_enc_fx( st_fx->EnergyLT_fx_exp = 30; move16(); /* Set to a High Exponent so it is 1^-30 */ } - /*---------------------------------------------------------------------* - * band-width switching from WB -> SWB/FB - *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) - { - IF( st_fx->bwidth_sw_cnt_fx == 0 ) - { - IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) - { - st_fx->bwidth_sw_cnt_fx = add( st_fx->bwidth_sw_cnt_fx, 1 ); - } - } - ELSE - { - st_fx->bwidth_sw_cnt_fx = add( st_fx->bwidth_sw_cnt_fx, 1 ); - - IF( EQ_16( st_fx->bwidth_sw_cnt_fx, BWS_TRAN_PERIOD ) ) - { - st_fx->bwidth_sw_cnt_fx = 0; - move16(); - } - } - } -#endif return; } @@ -483,22 +458,6 @@ void core_switching_post_enc_fx( set16_fx( hBWE_TD->state_ana_filt_shb_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); set16_fx( hBWE_TD->old_speech_shb_fx, 0, L_LOOK_16k + L_SUBFR16k ); -#ifdef IVAS_CODE - set16_fx( hBWE_TD->mem_shb_res_fx, 0, MAX_LEN_MA_FILTER ); - set16_fx( hBWE_TD->old_EnvSHBres_fx, 0, L_FRAME4k ); - hBWE_TD->old_mean_EnvSHBres_fx = 0; - hBWE_TD->prev_enr_EnvSHBres_fx = 32767; /*Q15 ??? */ - hBWE_TD->prev_shb_env_tilt_fx = 0; - hBWE_TD->prev_pow_exc16kWhtnd_fx = 32767; /*Q15 ??? */ - hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 ??? */ - hBWE_TD->prev_Env_error_fx = 0; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); -#endif swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); @@ -531,14 +490,6 @@ void core_switching_post_enc_fx( hBWE_TD->fb_tbe_demph_fx = 0; fb_tbe_reset_enc_fx( hBWE_TD->elliptic_bpf_2_48k_mem_fx, &hBWE_TD->prev_fb_energy_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &hBWE_TD->prev_fb_energy_fx_Q ); } - /* Fade towards init value for non HQ_CORE */ - IF( st_fx->hHQ_core != NULL ) - { -#ifdef IVAS_CODE - st_fx->hHQ_core->crest_lp = HQ_CREST_FAC_SM * ( st_fx->hHQ_core->crest_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * HQ_CREST_THRESHOLD; - st_fx->hHQ_core->crest_mod_lp = HQ_CREST_FAC_SM * ( st_fx->hHQ_core->crest_mod_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * HQ_CREST_MOD_THRESHOLD; -#endif - } } return; diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index be4368f69..a6b9e0aa4 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -662,11 +662,7 @@ void dtx_fx( move32(); #endif -#ifdef IVAS_CODE IF( st_fx->dtx_sce_sba != 0 ) -#else - if ( 0 ) -#endif { last_br_cng_flag = 1; last_br_flag = 1; @@ -770,9 +766,8 @@ void dtx_fx( /*------------------------------------------------------------------------* * Select SID or FRAME_NO_DATA frame if DTX is enabled *------------------------------------------------------------------------*/ -#ifdef IVAS_CODE + if ( st_fx->dtx_sce_sba == 0 ) -#endif { br_dtx_flag = LE_32( st_fx->total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st_fx->element_brate, IVAS_64k ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) ) ); @@ -836,20 +831,7 @@ void dtx_fx( st_fx->core_brate = SID_2k40; move32(); } - // PMT("dtx_sce_sba code is missing") -#ifdef IVAS_CODE - IF( ( NE_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->cng_type, FD_CNG ) ) && EQ_16( st_fx->dtx_sce_sba, 1 ) ) - { - st_fx->cng_type = FD_CNG; - move16(); - if ( EQ_16( st_fx->element_mode, EVS_MONO ) && ( EQ_32( st_fx->total_brate, ACELP_9k60 ) || EQ_32( st_fx->total_brate, ACELP_16k40 ) || EQ_32( st_fx->total_brate, ACELP_24k40 ) || EQ_32( st_fx->total_brate, ACELP_48k ) || EQ_32( st_fx->total_brate, HQ_96k ) || EQ_32( st_fx->total_brate, HQ_128k ) ) ) - { - st_fx->codec_mode = MODE2; - move16(); - } - } - ELSE -#endif + { test(); test(); @@ -879,7 +861,6 @@ void dtx_fx( } } -#if 1 // def IVAS_CODE /* reset the bitstream (IVAS format signalling was already written) */ IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { @@ -889,7 +870,6 @@ void dtx_fx( reset_indices_enc( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); #endif } -#endif } /*------------------------------------------------------------------------* @@ -932,32 +912,6 @@ void dtx_fx( { IF( EQ_16( st_fx->element_mode, IVAS_SCE ) ) { -#ifdef IVAS_CODE - Word16 lp_thresh, fd_thresh; - PMT( "lp_thresh scaling is to be found" ) - test(); - IF( st_fx->Opt_DTX_ON && EQ_16( st_fx->dtx_sce_sba, 1 ) ) - { - lp_thresh = 5.f; - fd_thresh = 2.f; - } - ELSE - - { - lp_thresh = 10.f; - fd_thresh = 5.f; - } - - /*More conservative selection of LP-CNG for SCE*/ - if ( st->cng_type == LP_CNG && ( st->bckr_tilt_lt > lp_thresh ) ) - { - st->cng_type = FD_CNG; - } - else if ( st->cng_type == FD_CNG && ( st->bckr_tilt_lt < fd_thresh ) && ( st->lp_noise > 2.f ) ) - { - st->cng_type = LP_CNG; - } -#endif } ELSE { @@ -1630,11 +1584,6 @@ void td_cng_enc_init_fx( move16(); move16(); -#ifdef IVAS_CODE - hTdCngEnc->CNG_att_fx = 0; - hTdCngEnc->last_idx_ener_fx = 0; -#endif - hTdCngEnc->cng_buf_cnt = 0; diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index c4c544469..a01550978 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -324,22 +324,7 @@ void transf_cdbk_enc_fx( } st_fx->last_nq_preQ = nq[7]; move16(); -#ifdef IVAS_CODE - /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ - if ( st->element_mode > EVS_MONO && st->coder_type != INACTIVE && st->core_brate >= MIN_BRATE_AVQ_EXC && st->core_brate <= MAX_BRATE_AVQ_EXC_TD && !harm_flag_acelp && code_preQ[0] != 0 ) - { - if ( (float) abs( st->last_code_preq ) > 16.0f * (float) fabs( code_preQ[0] ) ) - { - st->mem_preemp_preQ /= 16; - } - else if ( (float) abs( st->last_code_preq ) > 8.0f * (float) fabs( code_preQ[0] ) ) - { - st->mem_preemp_preQ /= 8; - } - } - st->last_code_preq = (int16_t) code_preQ[L_SUBFR - 1]; -#endif PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) ); /*--------------------------------------------------------------* diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 97db8d2a0..9cb2cd8e0 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -2083,12 +2083,7 @@ Word16 cng_energy_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) ) { - // PMT(" IVAS CNG ener computing is missing") -#ifdef IVAS_CODE - enr += CNG_att * FAC_LOG2 / 10.0f; -#else (void) CNG_att; -#endif } ELSE IF( NE_16( bwidth, NB ) ) { diff --git a/lib_enc/find_uv_fx.c b/lib_enc/find_uv_fx.c index 200e538e4..79dc78c6d 100644 --- a/lib_enc/find_uv_fx.c +++ b/lib_enc/find_uv_fx.c @@ -93,21 +93,14 @@ Word16 find_uv_fx( /* o : coding type */ const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ -#ifdef IVAS_CODE - Word32 *dE1X, /* o : sudden energy increase for S/M classifier */ -#endif - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ - const Word16 relE, /* i : relative frame energy Q8*/ - const Word16 Etot, /* i : total energy Q8*/ - const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ const Word16 Q_new, Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ const Word16 shift, const Word16 last_core_orig /* i : original last core Q0*/ -#ifdef IVAS_CODE - , - STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier structure */ -#endif ) { Word16 coder_type, i; @@ -202,25 +195,7 @@ Word16 find_uv_fx( /* o : coding type */ pt_enr_ssf++; pt_enr_ssf1++; } -#ifdef IVAS_CODE - IF( hStereoClassif != NULL ) - { - IF( st_fx->idchan == 0 ) - { - hStereoClassif->dE1_ch1 = dE1; - } - ELSE - { - hStereoClassif->dE1_ch2 = dE1; - } - } - if ( dE1X != NULL ) - { - *dE1X = dE1; - move32(); - } -#endif /*-----------------------------------------------------------------* * Average spectral tilt * Average voicing (normalized correlation) @@ -564,24 +539,6 @@ Word16 find_uv_fx( /* o : coding type */ } } } -#ifdef IVAS_CODE - /*-----------------------------------------------------------------* - * UNCLR classifier - *-----------------------------------------------------------------*/ - - if ( hStereoClassif != NULL ) - { - if ( st->element_mode > EVS_MONO && ( coder_type == GENERIC || coder_type == UNVOICED || coder_type == INACTIVE || st->localVAD == 0 ) && hStereoClassif->unclr_sw_enable_cnt[st->idchan] < MAX_UV_CNT ) - { - hStereoClassif->unclr_sw_enable_cnt[st->idchan]++; - } - else - { - hStereoClassif->unclr_sw_enable_cnt[st->idchan] = 0; - } - } -#endif - /*-----------------------------------------------------------------* * Updates diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index f927940ae..6af068bae 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -467,11 +467,6 @@ void gain_enc_mless_fx( qua_table = gain_qua_mless_6b_fx; if ( element_mode > EVS_MONO ) { -#ifdef IVAS_CODE - qua_table = gain_qua_mless_6b_stereo; -#else - // PMTE() -#endif } move16(); if ( EQ_16( clip_gain, 1 ) ) diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 7964df4a8..7bb13239f 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -274,83 +274,7 @@ Word16 inov_encode_fx( IF( !Opt_AMR_WB ) { IF( st_fx->acelp_cfg.fcb_mode ) - { // PMTE() -#ifdef IVAS_CODE - if ( st->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr] < ACELP_FIXED_CDK_NB ) - { - int16_t wordcnt, bitcnt; - int16_t prm[8]; - - if ( st->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr] >= 0 ) - { - if ( L_subfr == 2 * L_SUBFR ) - { - nBits = st->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr]; - - if ( nBits == 8 ) - { - acelp_1t64( hBstr, dn, h1, code, y2, L_subfr ); - } - else - { - acelp_fast( hBstr, nBits, dn, cn, h1, code, y2, L_subfr ); - } - } - else if ( ( st->idchan == 1 && st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 7 ) || ( st->idchan == 0 && st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 3 ) ) - { - if ( st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] == 0 ) - { - acelp_1t64( hBstr, dn, h1, code, y2, L_subfr ); - } - else - { - acelp_fast( hBstr, st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], dn, cn, h1, code, y2, L_SUBFR ); - } - } - else - { - E_ACELP_4t( dn, cn, h1, Rw, acelpautoc, code, st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], prm, L_frame, last_L_frame, st->total_brate, i_subfr, cmpl_flag ); - - wordcnt = ACELP_FIXED_CDK_BITS( st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ) >> 4; - bitcnt = ACELP_FIXED_CDK_BITS( st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ) & 15; - - for ( i = 0; i < wordcnt; i++ ) - { - push_indice( hBstr, IND_ALG_CDBK_4T64, prm[i], 16 ); - } - if ( bitcnt ) - { - push_indice( hBstr, IND_ALG_CDBK_4T64, prm[i], bitcnt ); - } - - /* Generate weighted code */ - set_f( y2, 0.0f, L_SUBFR ); - for ( i = 0; i < L_SUBFR; i++ ) - { - /* Code is sparse, so check which samples are non-zero */ - if ( code[i] != 0 ) - { - for ( k = 0; k < L_SUBFR - i; k++ ) - { - y2[i + k] += code[i] * h1[k]; - } - } - } - } - } - else - { - set_f( code, 0.0f, L_SUBFR ); - set_f( y2, 0.0f, L_SUBFR ); - } - } -#ifdef DEBUGGING - else - { - IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid mode for acelp frame!\n" ); - } -#endif -#endif + { } ELSE { @@ -656,9 +580,7 @@ Word16 inov_encode_ivas_fx( IF( !Opt_AMR_WB ) { IF( st_fx->acelp_cfg.fcb_mode ) - { // PMTE() -#if 1 - //#ifdef IVAS_CODE + { Word16 idx = 0, idx2 = 0; move16(); move16(); @@ -748,7 +670,6 @@ Word16 inov_encode_ivas_fx( { IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid mode for acelp frame!\n" ); } -#endif #endif } ELSE diff --git a/lib_enc/long_enr_fx.c b/lib_enc/long_enr_fx.c index 0916b2b09..5fe465f29 100644 --- a/lib_enc/long_enr_fx.c +++ b/lib_enc/long_enr_fx.c @@ -150,18 +150,13 @@ void ivas_long_enr_fx( *-----------------------------------------------------------------*/ return; } + + void long_enr_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ Word16 high_lpn_flag /* i : sp/mus LPN flag */ -#ifdef IVAS_CODE - , - FRONT_VAD_ENC_HANDLE hFrontVad[CPE_CHANNELS], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[CPE_CHANNELS] /* i : total channel energy LR channels */ -#endif ) { Word16 tmp; @@ -172,58 +167,7 @@ void long_enr_fx( * Compute long term estimate of total noise energy * and total active speech energy *-----------------------------------------------------------------*/ -#ifdef IVAS_CODE - Word16 n; - if ( hFrontVad != NULL ) - { - if ( hFrontVad[0]->ini_frame < 4 ) - { - for ( n = 0; n < n_chan; n++ ) - { - hFrontVad[n]->lp_noise = hFrontVad[n]->hNoiseEst->totalNoise; - tmp = hFrontVad[n]->lp_noise + 10.0f; - - if ( hFrontVad[n]->lp_speech < tmp ) - { - hFrontVad[n]->lp_speech = tmp; - } - } - } - else - { - float smooth_prev, smooth_curr; - - if ( hFrontVad[0]->ini_frame < 150 ) - { - smooth_prev = 0.95f; - smooth_curr = 0.05f; - } - else - { - smooth_prev = 0.98f; - smooth_curr = 0.02f; - } - for ( n = 0; n < n_chan; n++ ) - { - hFrontVad[n]->lp_noise = smooth_prev * hFrontVad[n]->lp_noise + smooth_curr * hFrontVad[n]->hNoiseEst->totalNoise; - - if ( localVAD_HE_SAD_LR[n] && !high_lpn_flag ) - { - if ( ( hFrontVad[n]->lp_speech - Etot_LR[n] ) < 10.0f ) - { - hFrontVad[n]->lp_speech = 0.98f * hFrontVad[n]->lp_speech + 0.02f * Etot_LR[n]; - } - else - { - hFrontVad[n]->lp_speech = hFrontVad[n]->lp_speech - 0.05f; - } - } - } - } - } - else -#endif { IF( LT_16( st_fx->ini_frame, 4 ) ) { diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index de5e474a0..96ab40547 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -78,9 +78,6 @@ void lsf_enc_fx( Word16 int_fs; Word16 force_sf = 0; Word16 fec_lsf[M], stab, i; -#ifdef IVAS_CODE - Word16 param_lpc[NPRM_LPC_NEW]; -#endif Word32 L_tmp; Word16 coder_type, ppp_mode, nelp_mode; @@ -199,19 +196,6 @@ void lsf_enc_fx( Copy( lsf_new, st_fx->lsf_old_fx, M ); } /* set seed_acelp used in UC mode */ -#ifdef IVAS_CODE - test(); - IF( EQ_16( coder_type, UNVOICED ) && GT_16( st_fx->element_mode, EVS_MONO ) ) - { - st_fx->seed_acelp = 0; - move16(); - FOR( i = no_param_lpc - 1; i >= 0; i-- ) - { - /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ - st->seed_acelp = (int16_t) ( ( ( ( st->seed_acelp ) >> 1 ) + param_lpc[i] ) * 31821L + 13849L ); - } - } -#endif IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { /* return if SID frame (conversion to A(z) done in the calling function) */ @@ -3534,14 +3518,6 @@ static void lsf_mid_enc_fx( move16(); BREAK; } -#ifdef IVAS_CODE - case 1: - { - ratio = tbl_mid_voi_wb_1b_fx; - move16(); - BREAK; - } -#endif } } ELSE IF( EQ_16( coder_type, UNVOICED ) ) @@ -3559,14 +3535,6 @@ static void lsf_mid_enc_fx( move16(); BREAK; } -#ifdef IVAS_CODE - case 4: - { - ratio = tbl_mid_gen_wb_4b_fx; - move16(); - BREAK; - } -#endif case 2: { ratio = tbl_mid_gen_wb_2b_fx; diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 27a48652a..68eed3d65 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -192,11 +192,11 @@ void noise_est_init_fx( hNoiseEst->totalNoise_fx = 0; move16(); hNoiseEst->first_noise_updt = 0; - // hNoiseEst->first_noise_updt_cnt_fx = 0; IVAS_CODE ?? move16(); hNoiseEst->aEn = 6; - // hNoiseEst->aEn_inac_cnt = 0; IVAS_CODE + move16(); + hNoiseEst->aEn_inac_cnt = 0; move16(); hNoiseEst->harm_cor_cnt = 0; @@ -269,21 +269,7 @@ void noise_est_init_ivas_fx( ) { Word16 i; -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - hNoiseEst->first_noise_updt = 0; - hNoiseEst->first_noise_updt_cnt = 0; - move16(); - move16(); - hNoiseEst->aEn = 6; - hNoiseEst->aEn_inac_cnt = 0; - hNoiseEst->harm_cor_cnt = 0; - hNoiseEst->bg_cnt = 0; - hNoiseEst->low_tn_track_cnt = 0; - move16(); - move16(); - move16(); - move16(); -#endif + FOR( i = 0; i < NB_BANDS; i++ ) { hNoiseEst->fr_bands1_fx[i] = 1; @@ -312,13 +298,14 @@ void noise_est_init_ivas_fx( hNoiseEst->totalNoise_fx = 0; move16(); hNoiseEst->first_noise_updt = 0; - // hNoiseEst->first_noise_updt_cnt_fx = 0; IVAS_CODE ?? + move16(); + hNoiseEst->first_noise_updt_cnt = 0; move16(); hNoiseEst->aEn = 6; - // hNoiseEst->aEn_inac_cnt = 0; IVAS_CODE move16(); - + hNoiseEst->aEn_inac_cnt = 0; + move16(); hNoiseEst->harm_cor_cnt = 0; move16(); hNoiseEst->bg_cnt = 0; @@ -890,11 +877,7 @@ void noise_est_fx( const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ Word16 *sp_floor, /* o : noise floor estimate Q7 */ Word16 S_map[], /* o : short-term correlation map Q7 */ -#ifdef IVAS_CODE - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ -#endif - const Word16 ini_frame /* i : Frame number (init) */ + const Word16 ini_frame /* i : Frame number (init) */ ) { Word16 alpha, alpha2, alpha2m1, alpham1; @@ -939,14 +922,8 @@ void noise_est_fx( #ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( ncharX ); #endif + /* Check if LR-VAD */ -#ifdef IVAS_CODE - IF( hFrontVad != NULL ) - { - hNoiseEst = hFrontVad->hNoiseEst; - } - ELSE -#endif { hNoiseEst = st_fx->hNoiseEst; } @@ -964,9 +941,6 @@ void noise_est_fx( move16(); /*st_fx->ener_RAT = 10.0f * (float)log10( mean(lf_E, 8));*/ -#ifdef IVAS_CODE - IF( hFrontVad == NULL ) -#endif { IF( hSpMusClas != NULL ) { @@ -1069,9 +1043,7 @@ void noise_est_fx( /*-----------------------------------------------------------------* * Multi-harmonic analysis *-----------------------------------------------------------------*/ -#ifdef IVAS_CODE - IF( hFrontVad == NULL ) -#endif + { IF( st_fx->hSpMusClas != NULL ) { @@ -1166,12 +1138,7 @@ void noise_est_fx( Ltmp2 = sum32_fx( &fr_bands[10], sub( st_fx->max_band, 9 ) ); wtmp = shl_o( 1, sub( add( Q_new, QSCALE ), 1 ), &Overflow ); -#ifdef IVAS_CODE - IF( ncharX != NULL ) - { - *ncharX = ftemp2 / ( ftemp + 1e-5f ); - } -#endif + test(); IF( L_msu( Ltmp, 100, wtmp ) < 0 || L_msu( Ltmp2, 100, wtmp ) < 0 ) { @@ -1332,9 +1299,6 @@ void noise_est_fx( move32(); /* calculation of non-stationarity measure for speech/music classification */ -#ifdef IVAS_CODE - IF( hFrontVad == NULL ) -#endif { test(); test(); @@ -1707,39 +1671,6 @@ void noise_est_fx( hNoiseEst->aEn = s_min( hNoiseEst->aEn, 6 ); hNoiseEst->aEn = s_max( hNoiseEst->aEn, 0 ); -#ifdef IVAS_CODE - /*-----------------------------------------------------------------* - * Stereo classifier - save raw aEn - *-----------------------------------------------------------------*/ - - if ( hStereoClassif != NULL ) - { - if ( ( non_sta > th_sta ) || - ( tmp_pc < TH_PC ) || - ( 0.5f * ( st->voicing[0] + st->voicing[1] ) > cor_max ) || - ( epsP[2] / epsP[16] > th_eps ) || - ( ( hNoiseEst->act_pred > 0.8f ) && ( non_sta2 > th_sta ) ) ) - { - /* active signal present - increment counter */ - hStereoClassif->aEn_raw[st->idchan] = add( hStereoClassif->aEn_raw[st->idchan], 2 ); - } - else - { - /* background noise present - decrement counter */ - hStereoClassif->aEn_raw[st->idchan] = sub( hStereoClassif->aEn_raw[st->idchan], 1 ); - } - - if ( GT_16( hStereoClassif->aEn_raw[st->idchan], 6 ) ) - { - hStereoClassif->aEn_raw[st->idchan] = 6; - } - else if ( hStereoClassif->aEn_raw[st->idchan] < 0 ) - { - hStereoClassif->aEn_raw[st->idchan] = 0; - } - } -#endif - /* Additional NNE detectors */ @@ -2192,18 +2123,6 @@ void noise_est_fx( move16(); } -#ifdef IVAS_CODE - IF( st_fx->element_mode > EVS_MONO ) - { - test(); - IF( hNoiseEst->first_noise_updt_cnt_fx > 0 && LT_16( hNoiseEst->first_noise_updt_cnt_fx, 100 ) ) - { - hNoiseEst->first_noise_updt_cnt_fx = add( hNoiseEst->first_noise_updt_cnt_fx, 1 ); - move16(); - } - } -#endif - return; } diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index bd3d4cb34..5a8f4aa7c 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -214,7 +214,7 @@ void pre_proc_fx( * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* @@ -497,9 +497,6 @@ void pre_proc_fx( noise_est_fx( st, old_pitch1, tmpN, epsP_h, epsP_l, *Etot, relE, corr_shift, tmpE, fr_bands, &cor_map_sum, NULL, &sp_div, &Q_sp_div, &non_staX, &loc_harm, lf_E, &hNoiseEst->harm_cor_cnt, hNoiseEst->Etot_l_lp_fx, hNoiseEst->Etot_v_h2_fx, &hNoiseEst->bg_cnt, st->lgBin_E_fx, *Q_new, Le_min_scaled, &sp_floor, NULL, -#ifdef IVAS_CODE - NULL, NULL, -#endif st->ini_frame ); /*------------------------------------------------------------------* @@ -516,15 +513,7 @@ void pre_proc_fx( st->max_band, hp_E, st->codec_mode, *Q_new, &( st->bckr_tilt_lt ), st->Opt_SC_VBR ); st->coder_type = find_uv_fx( st, pitch_fr, voicing_fr, inp_12k8, ee, -#ifdef IVAS_CODE - NULL, -#endif - corr_shift, relE, *Etot, hp_E, *Q_new, &flag_spitch, *shift, last_core_orig -#ifdef IVAS_CODE - , - NULL -#endif - ); + corr_shift, relE, *Etot, hp_E, *Q_new, &flag_spitch, *shift, last_core_orig ); /*----------------------------------------------------------------* * channel aware mode configuration * @@ -598,12 +587,7 @@ void pre_proc_fx( speech_music_classif_fx( st, new_inp_12k8, inp_12k8, localVAD_HE_SAD, lsp_new, cor_map_sum, epsP, PS, *Etot, old_cor, attack_flag, non_staX, relE, Q_esp, *Q_new, &high_lpn_flag, flag_spitch ); - long_enr_fx( st, *Etot, localVAD_HE_SAD, high_lpn_flag -#ifdef IVAS_CODE - , - NULL, 1, NULL, NULL -#endif - ); /* has to be after after sp_music classfier */ + long_enr_fx( st, *Etot, localVAD_HE_SAD, high_lpn_flag ); /* has to be after after sp_music classfier */ /*----------------------------------------------------------------* * Rewrite the VAD flag by VAD flag with DTX hangover for further processing) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index c3e9d1b4c..0a058740b 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -286,21 +286,14 @@ Word16 find_uv_fx( /* o : coding type const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ -#ifdef IVAS_CODE - Word32 *dE1X, /* o : sudden energy increase for S/M classifier */ -#endif - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ - const Word16 relE, /* i : relative frame energy Q8*/ - const Word16 Etot, /* i : total energy Q8*/ - const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ const Word16 Q_new, Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ const Word16 shift, const Word16 last_core_orig /* i : original last core Q0*/ -#ifdef IVAS_CODE - , - STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier structure */ -#endif ); void fine_gain_quant_fx( @@ -401,11 +394,7 @@ void noise_est_fx( const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ Word16 *sp_floor, /* o : noise floor estimate Q7 */ Word16 S_map[], /* o : short-term correlation map Q7 */ -#ifdef IVAS_CODE - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ -#endif - const Word16 ini_frame /* i : Frame number (init) */ + const Word16 ini_frame /* i : Frame number (init) */ ); void noise_est_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 295cff8a1..04f02d860 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -55,16 +55,7 @@ static void tonal_context_improv_fx( Encoder_State *st_fx, const Word32 PS[], co static void var_cor_calc_fx( const Word16 old_corr, Word16 *mold_corr, Word16 var_cor_t[], Word16 *high_stable_cor ); -static Word16 attack_det_fx( const Word16 *inp, const Word16 Qx, const Word16 last_clas, const Word16 localVAD, const Word16 coder_type, const Word32 total_brate -#ifdef IVAS_CODE - , - const Word16 element_mode, - const Word16 clas, - Word32 finc_prev[], - Word32 *lt_finc, - Word16 *last_strong_attack -#endif -); +static Word16 attack_det_fx( const Word16 *inp, const Word16 Qx, const Word16 last_clas, const Word16 localVAD, const Word16 coder_type, const Word32 total_brate ); static void order_spectrum_fx( Word16 *vec, Word16 len ); @@ -1336,12 +1327,7 @@ static void sp_mus_classif_2nd_fx( var_cor_calc_fx( st->old_corr_fx, &hSpMusClas->mold_corr_fx, hSpMusClas->var_cor_t_fx, &hSpMusClas->high_stable_cor ); /* attack detection */ - attack = attack_det_fx( inp, Qx, st->clas, st->localVAD, st->coder_type, st->total_brate -#ifdef IVAS_CODE - , - EVS_MONO, st->clas, hSpMusClas->finc_prev, &hSpMusClas->lt_finc, &hSpMusClas->last_strong_attack -#endif - ); + attack = attack_det_fx( inp, Qx, st->clas, st->localVAD, st->coder_type, st->total_brate ); test(); test(); @@ -1487,22 +1473,11 @@ static Word16 attack_det_fx( /* o : attack flag const Word16 localVAD, /* i : local VAD flag */ const Word16 coder_type, /* i : coder type */ const Word32 total_brate /* i : total bitrate */ -#ifdef IVAS_CODE - , - const Word16 element_mode, /* i : IVAS element mode */ - const Word16 clas, /* i : signal class */ - Word32 finc_prev[], /* i/o: previous finc */ - Word32 *lt_finc, /* i/o: long-term mean finc */ - Word16 *last_strong_attack /* i/o: last strong attack flag */ -#endif ) { Word16 i, j, tmp, tmp1, attack, exp1; Word32 L_tmp, etmp, etmp2, finc[ATT_NSEG]; Word16 att_3lsub_pos; -#ifdef IVAS_CODE - Word16 attack1; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -1531,10 +1506,6 @@ static Word16 attack_det_fx( /* o : attack flag } attack = maximum_32_fx( finc, ATT_NSEG, &etmp ); -#ifdef IVAS_CODE - attack1 = attack; - move16(); -#endif move16(); test(); IF( EQ_16( localVAD, 1 ) && EQ_16( coder_type, GENERIC ) ) @@ -1600,37 +1571,6 @@ static Word16 attack_det_fx( /* o : attack flag } } } -#ifdef IVAS_CODE - test(); - test(); - test(); - IF( attack == 0 && GT_16( element_mode, EVS_MONO ) && ( LT_16( clas, VOICED_TRANSITION ) || EQ_16( clas, ONSET ) ) ) - { - Copy32( finc, finc_prev, attack1 ); - - /* compute mean energy before the attack */ - etmp = L_shr( sum32_fx( finc_prev, ATT_NSEG ), 5 ); /*ATT_NSEG == 32*/ - - etmp2 = finc[attack1]; - move32(); - test(); - test(); - if ( ( LT_32( L_shl( etmp, 4 ), etmp2 ) ) || ( LT_32( L_mult0( etmp, 12 ), etmp2 ) && EQ_16( last_clas, UNVOICED_CLAS ) ) ) - { - attack = attack1; - move16(); - } - PMT( "Size of lf_finc not verified yet" ) - test(); - if ( GT_32( L_mult0( 20, *lt_finc ), etmp2 ) || *last_strong_attack ) /*lt_finc assumes same Q as etmp2, TBV!!!! */ - { - attack = 0; - move16(); - } - } - *last_strong_attack = attack; - move16(); -#endif } ELSE IF( attack > 0 ) { @@ -1647,10 +1587,6 @@ static Word16 attack_det_fx( /* o : attack flag BREAK; } } -#ifdef IVAS_CODE - *last_strong_attack = 0; - move16(); -#endif } return attack; diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 6292c4b33..7421921f0 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1780,9 +1780,10 @@ typedef struct enc_core_structure Word16 is_ism_format; /* Indication whether the codec operates in ISM format */ Word16 dtx_sce_sba; /* enable use of FD CNG with transform domain cores in SCE SBA */ - /*----------------------------------------------------------------------------------* - * Fixed point only variables - *----------------------------------------------------------------------------------*/ + + /*----------------------------------------------------------------------------------* + * Fixed point only variables + *----------------------------------------------------------------------------------*/ Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ @@ -1813,534 +1814,6 @@ typedef struct enc_core_structure } Encoder_State, *ENC_CORE_HANDLE; -// typedef struct Encoder_State_fx -//{ -// -// /*----------------------------------------------------------------------------------* -// * Common parameters - -// *----------------------------------------------------------------------------------*/ -// /*----------------------------------------------------------------------------------* -// * Stereo/IVAS parameters -// *----------------------------------------------------------------------------------*/ -// Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ -// -// Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ -// Word16 cna_dirac_flag; /* CNA in DirAC flag */ -// Word16 cng_sba_flag; /* CNG in SBA flag */ -// Word16 idchan; /* channel ID (audio channel number) */ -// Word16 element_mode; /* element mode */ -// Word16 last_element_mode; /* element mode */ -// Word16 low_rate_mode; /* low-rate mode flag */ -// MCT_CHAN_MODE mct_chan_mode; -// Word16 GSC_IVAS_mode; -// Word16 is_ism_format; /* Indication whether the codec operates in ISM format */ -// Word16 dtx_sce_sba; /* enable use of FD CNG with transform domain cores in SCE SBA */ -// -// -// //#ifdef IVAS_CODE -// -// #ifdef DEBUGGING -// Word16 id_element; /* element ID */ -// #endif -// Word32 element_brate; /* element bitrate */ -// Word16 extl_orig; /* extension layer */ -// Word32 extl_brate_orig; /* extension layer bitrate */ -// /*----------------------- End of IVAS specific--------------------------------------*/ -// -// -// Word16 codec_mode; /* MODE1 or MODE2 */ -// Word16 last_codec_mode; /* Previous Codec Mode*/ -// Word16 last_codec_mode_cng; /* Codec Mode of the last inactive frame*/ -// Word16 mdct_sw_enable; /* MDCT switching enable flag */ -// Word16 mdct_sw; /* MDCT switching indicator */ -// Word16 last_enerBuffer_exp; -// Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ -// Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME) */ -// -// BSTR_ENC_HANDLE hBstr; /* encoder bitstream handle */ -// -// -// LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ -// -// -// Word32 input_Fs_fx; /* input signal sampling frequency in Hz */ -// Word32 total_brate_fx; /* total bitrate in kbps of the codec */ -// Word32 last_total_brate_fx; /* total bitrate in kbps of the codec */ -// Word32 last_total_brate_cng_fx; /* total bitrate in kbps of the last inactive frame */ -// Word16 core_fx; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ -// Word32 core_brate_fx; /* core bitrate */ -// Word32 last_core_brate_fx; /* previous frame core bitrate */ -// Word16 input_frame_fx; /* Frame lenght (function of input_Fs) */ -// Word16 extl_fx; /* extension layer */ -// Word16 last_extl_fx; /* previous extension layer */ -// Word32 extl_brate_fx; /* extension layer bitrate */ -// Word16 input_bwidth_fx; /* input signal bandwidth */ -// Word16 last_input_bwidth_fx; /* input signal bandwidth in the previous frame */ -// Word16 bwidth_fx; /* encoded bandwidth NB, WB, SWB or FB */ -// Word16 max_bwidth_fx; /* maximum encoded bandwidth */ -// Word16 last_bwidth_fx; /* input signal bandwidth in the previous frame */ -// Word16 last_bwidth_cng_fx; /* input signal bandwidth in the previous inactive frame */ -// Word16 L_frame_fx; /* ACELP core internal frame length */ -// Word16 Opt_AMR_WB_fx; /* flag indicating AMR-WB IO mode */ -// Word16 Opt_DTX_ON_fx; /* flag indicating DTX operation */ -// Word16 cng_type_fx; /* flag indicating LP or CLDFB based SID/CNG */ -// Word16 active_fr_cnt_fx; /* counter of active frames */ -// Word16 Opt_SC_VBR_fx; /* flag indicating SC-VBR mode */ -// Word16 last_Opt_SC_VBR_fx; /* flag indicating SC-VBR mode in the last frame */ -// /*----------------------------------------------------------------------------------* -// * ACELP core parameters -// *----------------------------------------------------------------------------------*/ -// -// Word16 clas_fx; /* current frame clas */ -// Word16 last_clas_fx; /* previous frame signal classification */ -// Word32 Bin_E_fx[L_FFT]; /* Q_new + Q_SCALE -2 per bin energy of two frames */ -// -// /*----------------------------------------------------------------------------------* -// * General signal buffers -// *----------------------------------------------------------------------------------*/ -// Word16* input_buff; -// /*Word16* input; -// Word16* old_input_signal;*/ -// -// SIGNAL_BUFFERS_ENC_HANDLE hSignalBuf; -// -// Word32* Bin_E_old_fx; /* per bin energy of old 2nd frames */ -// Word16* mem_decim_fx; /* decimation filter memory */ -// Word16* mem_decim16k_fx; /* ACELP@16kHz - decimation filter memory @16kHz */ -// Word16* old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ -// Word16* old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ -// -// Word16* buf_speech_enc_pe; -// Word16* buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ -// Word16* buf_speech_enc; -// Word16* buf_wspeech_enc; -// -// -// Word16 lsp_old1_fx[M]; /* old unquantized LSP vector at the end of the frame */ -// Word16 lsf_old1_fx[M]; /* old LSF vector at the end of the frame */ -// Word16 lsp_old_fx[M]; /* old LSP vector at the end of the frame */ -// Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame */ -// Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz */ -// Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz */ -// Word16 pstreaklen_fx; /* LSF quantizer */ -// Word16 streaklimit_fx; /* LSF quantizer */ -// Word32 offset_scale1_fx[MAX_NO_MODES + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure 1st 8-dim subvector*/ -// Word32 offset_scale2_fx[MAX_NO_MODES + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure 2nd 8-dim subvector*/ -// Word32 offset_scale1_p_fx[MAX_NO_MODES_p + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure, pred. case, 1st 8-dim subvector*/ -// Word32 offset_scale2_p_fx[MAX_NO_MODES_p + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure, pred. case, 2nd 8-dim subvector*/ -// Word16 no_scales_fx[MAX_NO_MODES][2]; /* LSF LVQ structure Q0*/ -// Word16 no_scales_p_fx[MAX_NO_MODES_p][2]; /* LSF LVQ structure Q0*/ -// Word16 stab_fac_fx; /* LSF stability factor */ -// Word16 mem_deemph_fx; /* deemphasis filter memory */ -// Word16 mem_preemph_fx; /* preemphasis filter memory */ -// Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ -// Word16 old_wsp_fx[L_WSP_MEM]; /* old weighted signal vector */ -// /*Word16 old_exc_fx[L_EXC_MEM];*/ /* old excitation vector */ -// Word16 old_wsp2_fx[(L_WSP_MEM - L_INTERPOL) / OPL_DECIM]; /* old decimated weighted signal vector qwsp */ -// -// /*----------------------------------------------------------------------------------* -// * Noise estimation -// *----------------------------------------------------------------------------------*/ -// -// NOISE_EST_HANDLE hNoiseEst; -// -// Word16 mem_wsp_fx; /* weighted signal vector memory */ -// Word16 mem_decim2_fx[3]; /* weighted signal decimation filter memory qwsp */ -// Word16 clip_var_fx[6]; -// Word16 mem_AR_fx[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean) */ -// Word16 mem_MA_fx[M]; /* MA memory of LSF quantizer (past quantized residual) (used also in AMR-WB IO mode) */ -// Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ -// Word16 coder_type_raw_fx; -// Word16 last_coder_type_raw_fx; /* raw last_coder_type (coming from the sigal classification) */ -// Word16 last_coder_type; /*Q0 previous coding type */ -// Word16 ini_frame_fx; /* initialization frames counter */ -// Word16 old_thres_fx; /* normalized correlation weighting in open-loop pitch Q15 */ -// Word16 old_corr_fx; /* normalized correlation in previous frame (mean value) Q15 */ -// Word16 old_pitch; /* previous pitch for open-loop pitch search Q0 */ -// Word16 delta_pit_fx; /* open-loop pitch extrapolation correction Q0 */ -// Word32 ee_old_fx; -// Word16 min_band_fx; /* Q0 minimum critical band of useful bandwidth */ -// Word16 max_band_fx; /* Q0 maximum critical band of useful bandwidth */ -// Word16 tc_cnt_fx; /* TC frame counter */ -// Word16 audio_frame_cnt_fx; /* Counter of relative presence of audio frames */ -// Word32 old_dE1_fx; /* Maximum energy increase in previous frame */ -// Word16 old_ind_deltaMax_fx; /* Index of the sub-subframe of maximum energy in previous frame */ -// Word32 old_enr_ssf_fx[2 * NB_SSF]; /* Maxima of energies per sub-subframes of previous frame */ -// Word16 spike_hyst_fx; /* Hysteresis to prevent UC after sharp energy spike */ -// Word16 music_hysteresis_fx; /* Counter of frames after AUDIO coding mode to prevent UC */ -// Word16 last_harm_flag_acelp_fx; /* harmonicity flag for ACELP @32kbps rate */ -// Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ -// Word16 old_Es_pred_fx; /* Q8 old Es_pred for core switching */ -// -// GSC_ENC_HANDLE hGSCEnc; -// -// -// Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ -// -// SP_MUS_CLAS_HANDLE hSpMusClas; -// -// Word16 lgBin_E_fx[L_FFT / 2]; /* Q8 per bin energy of two frames */ -// -// /* speech/music classifier improvement parameters */ -// Word16 last_vad_spa_fx; -// -// -// Word16 Last_pulse_pos_fx; /* FEC - last position of the first glotal pulse in the frame */ -// Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame */ -// Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame */ -// Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC */ -// Word16 next_force_safety_net_fx; /* FEC - flag to force safety net in next frame */ -// -// -// /*----------------------------------------------------------------------------------* -// * VAD/DTX/CNG -// *----------------------------------------------------------------------------------*/ -// -// VAD_HANDLE hVAD; -// -// VAD_CLDFB_HANDLE hVAD_CLDFB; -// Word16 lp_speech_fx; -// Word16 Opt_HE_SAD_ON_fx; -// Word16 nb_active_frames_HE_SAD_fx; -// -// -// -// -// Word16 voicing_old_fx; -// -// -// Word32 bckr_tilt_lt; -// -// -// TD_CNG_ENC_HANDLE hTdCngEnc; -// -// DTX_ENC_HANDLE hDtxEnc; -// Word16 var_SID_rate_flag_fx; /* CNG and DTX - flag for variable SID rate */ -// Word16 interval_SID_fx; /* CNG and DTX - interval of SID update, default 8 */ -// -// Word16 lp_noise_fx; /* CNG and DTX - LP filtered total noise estimation */ -// -// Word16 uv_count; /*Q0*/ /* Stationary noise UV modification - unvoiced counter */ -// Word16 act_count; /*Q0*/ /* Stationary noise UV modification - activation counter */ -// Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain */ -// Word16 lspold_s_fx[M]; /*Q15*/ /* Stationary noise UV modification - old LSP vector */ -// Word16 noimix_seed; /*Q0*/ /* Stationary noise UV modification - mixture seed */ -// Word16 min_alpha_fx; /*Q15*/ /* Stationary noise UV modification - minimum alpha */ -// Word16 exc_pe_fx; /* Stationary noise UV modification - memory of the preemphasis filter */ -// -// Word16 last_L_frame_fx; /* ACELP@16kHz - last L_frame value */ -// Word16 mem_preemph16k_fx; /* ACELP@16kHz - preemphasis filter memory @16kHz */ -// Word16 mem_deemp_preQ_fx; /* ACELP@16kHz - prequantizer deemhasis memory */ -// Word16 mem_preemp_preQ_fx; /* ACELP@16kHz - prequantizer preemhasis memory */ -// Word16 last_nq_preQ; /* ACELP@16kHz - AVQ subquantizer number of the last sub-band of the last subframe */ -// Word16 use_acelp_preq; /* ACELP@16kHz - flag of prequantizer usage */ -// -// Word16 bpf_off_fx; -// Word16 old_pitch_buf_fx[2 * NB_SUBFR16k]; /*Q6 Bass post-filter - buffer of old subframe pitch values */ -// -// -// /* stable short pitch detection */ -// Word16 voicing0_sm_fx; -// Word16 voicing_sm_fx; -// Word16 LF_EnergyRatio_sm_fx; -// Word16 predecision_flag_fx; -// Word32 diff_sm_fx; -// Word32 energy_sm_fx; -// -// Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ -// -// /*----------------------------------------------------------------------------------* -// * AMR-WB IO handle -// *----------------------------------------------------------------------------------*/ -// HANDLE_CLDFB_FILTER_BANK cldfbAna_Fx; -// -// AMRWB_IO_ENC_HANDLE hAmrwb_IO; /* AMR-WB IO encoder handle */ -// -// /*----------------------------------------------------------------------------------* -// * CLDFB analysis -// *----------------------------------------------------------------------------------*/ -// HANDLE_CLDFB_FILTER_BANK cldfbAna_Fx; -// -// HANDLE_CLDFB_FILTER_BANK cldfbSyn_Fx; -// -// /*----------------------------------------------------------------------------------* -// * FD CNG handle -// *----------------------------------------------------------------------------------*/ -// HANDLE_FD_CNG_ENC_FX hFdCngEnc_fx; -// Word16 fd_cng_reset_flag; -// Word16 last_totalNoise_fx; -// Word16 totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE]; -// Word16 totalNoise_increase_len_fx; -// /*----------------------------------------------------------------------------------* -// * SC-VBR parameters -// *----------------------------------------------------------------------------------*/ -// -// /*----------------------------------------------------------------------------------* -// * SC-VBR parameters -// *----------------------------------------------------------------------------------*/ -// -// SC_VBR_ENC_HANDLE hSC_VBR; -// -// /*----------------------------------------------------------------------------------* -// * HQ core parameters -// *----------------------------------------------------------------------------------*/ -// Word16 * input; -// Word16 * old_input_signal_fx; -// Word16 Q_old_wtda; -// Word16 old_hpfilt_in_fx; -// Word16 old_hpfilt_out_fx; -// Word32 EnergyLT_fx; -// Word32 Energy_Old_fx; -// Word16 TransientHangOver_fx; -// Word16 last_core_fx; -// -// HQ_ENC_HANDLE hHQ_core; /* HQ core encoder handle */ -// -// Word16 Nb_ACELP_frames_fx; -// -// PVQ_ENC_HANDLE hPVQ; -// -// /*----------------------------------------------------------------------------------* -// * TD BWE parameters -// *----------------------------------------------------------------------------------*/ -// -// TD_BWE_ENC_HANDLE hBWE_TD; -// -// /*----------------------------------------------------------------------------------* -// * FD BWE parameters -// *----------------------------------------------------------------------------------*/ -// -// FD_BWE_ENC_HANDLE hBWE_FD; -// -// /*----------------------------------------------------------------------------------* -// * WB, SWB and FB bandwidth detector -// *----------------------------------------------------------------------------------*/ -// -// Word16 lt_mean_NB_fx; -// Word16 lt_mean_WB_fx; -// Word16 lt_mean_SWB_fx; -// Word16 count_WB_fx; -// Word16 count_SWB_fx; -// Word16 count_FB_fx; -// -// RF_ENC_HANDLE hRF; /* RF encoder handle */ -// -// Word16 rf_mode; -// Word16 rf_target_bits_write; -// Word16 rf_mode_last; -// Word16 last_rf_mode_cng; -// Word16 Opt_RF_ON; -// Word16 rf_fec_offset; -// Word16 rf_fec_indicator; -// -// /*----------------------------------------------------------------------------------* -// * Fixed point only variables -// *----------------------------------------------------------------------------------*/ -// -// Word16 prev_Q_bwe_exc; -// Word16 prev_Q_bwe_syn; -// Word16 Q_stat_noise_ge; -// Word16 Q_stat_noise; -// Word16 Q_syn2; -// Word16 Q_syn; -// Word16 Q_max[L_Q_MEM]; -// Word16 Q_max_16k[L_Q_MEM]; -// Word16 Q_old; -// Word16 prev_Q_old; -// Word16 old_wsp_max; /* Last weigthed speech maximal value */ -// Word16 old_wsp_shift; /* Last wsp scaling */ -// Word16 prev_Q_new; -// Word16 prev_Q_shb; -// -// /*----------------------------------------------------------------------------------* -// * -// *----------------------------------------------------------------------------------*/ -// -// Word16 EnergyLT_fx_exp; -// Word16 prev_lsp_wb_fx[LPC_SHB_ORDER_WB]; -// Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; -// Word16 prev_lsp_wb_temp_fx[LPC_SHB_ORDER_WB]; -// -// Word16 frame_size_index; /* 0-FRAME_SIZE_NB-1: index determining the frame size */ -// Word16 bits_frame_nominal; /* avg bits per frame on active frame */ -// Word16 bits_frame; /* total bits per frame */ -// Word16 bits_frame_core; /* bits per frame for the core */ -// Word8 narrowBand; -// -// /*ACELP config*/ -// ACELP_config acelp_cfg; /* configuration set for each frame */ -// -// ACELP_config acelp_cfg_rf; /* configuration for RF frame */ -// -// Word16 mode_index; /* Mode Index for LPD core */ -// -// /*TCX config*/ -// TCX_CONFIG_HANDLE hTcxCfg; -// /*----------------------------------------------------------------------------------* -// * TCX core encoder handle -// *----------------------------------------------------------------------------------*/ -// -// TCX_ENC_HANDLE hTcxEnc; -// -// /* cod_main.c */ -// Word16 mem_preemph_enc; /* speech preemph filter memory (at encoder-sampling-rate) */ -// -// -// Word16 *speech_enc; -// Word16 *speech_enc_pe; -// Word16 *new_speech_enc; -// Word16 *new_speech_enc_pe; -// Word16 *wspeech_enc; -// Word16 *synth; -// /* Core Signal Analysis Outputs */ -// -// Word8 enableTcxLpc; /* global toggle for the TCX LPC quantizer */ -// Word16 envWeighted; /* are is{p,f}_old_q[] weighted or not? */ -// -// Word8 acelpEnabled; /* Flag indicating if ACELP can be used */ -// Word8 tcx10Enabled; /* Flag indicating if TCX 10 can be used */ -// Word8 tcx20Enabled; /* Flag indicating if TCX 20 can be used */ -// -// -// Word16 mem_wsp_enc; /* wsp vector memory */ -// -// Word16 nb_bits_header_ace; /* number of bits for the header */ -// Word16 nb_bits_header_tcx; /* number of bits for the header */ -// -// /*Added by fcs : restrict the possible in EVS: 0 base 10 = d.c.b.a base 2*/ -// /* a = 0/1 : ACELP on/off*/ -// /* b = 0/1 : TCX20 on/off*/ -// /* c = 0/1 : TCX40 on/off*/ -// /* d = 0/1 : TCX80 on/off*/ -// Word16 restrictedMode; -// -// /* Framing */ -// Word16 nb_subfr; -// -// Word16 preemph_fac; /*Preemphasis factor*/ -// -// Word16 gamma; -// Word16 inv_gamma; -// -// TransientDetection transientDetection; -// Word16 transient_info[3]; -// -// Word16 acelpFramesCount; /* Acelp frame counter. Counts upto 50 only !!! */ -// -// Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E */ -// -// Word32 prevEnergyHF_fx; -// Word32 currEnergyHF_fx; -// Word16 currEnergyHF_e_fx; /* exponent of currEnergyHF and prevEnergyHF */ -// Word32 energyCoreLookahead_Fx; -// Word16 sf_energyCoreLookahead_Fx; -// -// /* lsf quantizer*/ -// Word16 parcorr[2]; -// Word16 parcorr_mid[2]; -// -// Word16 lpcQuantization; -// Word16 numlpc; -// Word16 encoderLookahead_enc; -// Word16 encoderPastSamples_enc; -// Word16 encoderLookahead_FB; -// -// /* pitch_ol for adaptive lag window */ -// Word16 old_pitch_la; /* past open loop pitch lag from look-ahead */ -// Word16 old_voicing_la; /* past open loop pitch gain from look-ahead */ -// -// Word32 band_energies[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor MODE2_E_MIN */ -// Word16 band_energies_exp; /* exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */ -// -// Word8 tcxonly; -// -// Word16 Q_max_enc[2]; -// -// Word16 finalVAD; -// Word8 flag_noisy_speech_snr; /*encoder detector for noisy speech*/ -// Word16 Pos_relE_cnt; /* Number of frames between positive relE */ -// -// Word16 fscale; -// Word32 sr_core; -// Word32 last_sr_core; -// Word8 acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ -// -// Word16 pit_min; -// Word16 pit_fr1; -// Word16 pit_fr1b; -// Word16 pit_fr2; -// Word16 pit_max; -// Word16 pit_res_max; /* goes from 1 upto 6 (see core_enc_init.c: init_acelp()) */ -// -// /* for FAC */ -// Word16 L_frame_past; -// -// /*Adaptive BPF*/ -// Word16 bpf_gain_param; -// Word16 bpf_T[NB_SUBFR16k]; -// Word16 bpf_gainT[NB_SUBFR16k]; -// -// struct MEM_BPF -// { -// Word16 noise_buf[2 * L_FILT16k]; -// Word16 error_buf[L_FILT16k]; -// Word32 lp_error; -// Word32 lp_error_ener; -// Word16 noise_shift_old; -// } mem_bpf; -// -// -// -// Word8 glr; -// Word16 glr_idx[2]; -// Word32 gain_code[NB_SUBFR16k]; -// Word32 mean_gc[2]; -// Word16 prev_lsf4_mean; -// Word16 last_stab_fac; -// Word8 glr_reset; -// -// /*for rate switching*/ -// Word16 rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ -// Word16 rate_switching_reset_16kHz; -// -// Word16 enablePlcWaveadjust; -// Word16 Tonal_SideInfo; -// -// IGF_ENC_INSTANCE_HANDLE hIGFEnc; /* IGF encoder handle */ -// Word16 igf; -// -// Word16 seed_acelp; -// -// PLC_ENC_EVS_HANDLE hPlcExt; -// -// Word16 tec_tfa; -// TEC_ENC_HANDLE hTECEnc; /* TEC encoder handle */ -// Word16 tec_flag; -// Word16 tfa_flag; -// Word32 tfa_enr[N_TEC_TFA_SUBFR]; -// -// Word16 nTimeSlots; /* for CLDFB */ -// -// T_CldfbVadState_fx vad_st; -// -// -// Word16 pitch_fx[3]; -// Word16 voicing_fx[3]; -// Word16 sp_aud_decision0; /* 1st stage speech/music classification */ -// Word16 sp_aud_decision1; /* 1st stage speech/music classification */ -// Word16 sp_aud_decision2; /* 2nd stage speech/music classification */ -// Word16 coder_type; /* coder type */ -// Word16 vad_flag; -// Word16 sharpFlag; /* formant sharpening flag */ -// Word16 localVAD; -// -// Word16 tdm_pc; -// Word16 prev_fmerit; -// Word16 fmerit_dt; -// -// -// } Encoder_State, * ENC_CORE_HANDLE_FX; typedef struct GainItemStr { diff --git a/lib_enc/updt_enc_fx.c b/lib_enc/updt_enc_fx.c index 77d7f538f..fb2a6215b 100644 --- a/lib_enc/updt_enc_fx.c +++ b/lib_enc/updt_enc_fx.c @@ -332,7 +332,7 @@ void updt_IO_switch_enc_fx( * * Common updates for MODE1 and MODE2 *-------------------------------------------------------------------*/ -#if 1 + void updt_enc_common_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 Etot, /* i : total energy */ @@ -343,27 +343,24 @@ void updt_enc_common_fx( * Updates - main main codec parameters *---------------------------------------------------------------------*/ - st->last_sr_core = st->sr_core; //## + st->last_sr_core = st->sr_core; move32(); st->last_codec_mode = st->codec_mode; move16(); - st->last_L_frame = st->L_frame; // + st->last_L_frame = st->L_frame; move16(); st->last_core = st->core; move16(); st->last_core_brate = st->core_brate; move32(); -#ifdef IVAS_CODE - st->last_bits_frame_nominal_fx = st->bits_frame_nominal; -#endif st->last_total_brate = st->total_brate; move32(); - st->last_extl = st->extl; // + st->last_extl = st->extl; move16(); - st->last_input_bwidth = st->input_bwidth; //## + st->last_input_bwidth = st->input_bwidth; move16(); - st->last_bwidth = st->bwidth; //## + st->last_bwidth = st->bwidth; move16(); st->hNoiseEst->Etot_last_fx = Etot; move16(); @@ -425,18 +422,12 @@ void updt_enc_common_fx( move16(); move16(); -#ifdef IVAS_CODE test(); test(); test(); IF( ( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GE_16( st->hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) { - st->hTdCngEnc->CNG_att_fx = 0; - move16(); - - apply_scale( &st->hTdCngEnc->CNG_att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } -#endif } } @@ -550,17 +541,14 @@ void updt_enc_common_fx( /*---------------------------------------------------------------------* * Other updates *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE + test(); IF( GT_16( st->element_mode, EVS_MONO ) && st->hTcxEnc != NULL ) { - st->hTcxEnc->tcxltp_norm_corr_mem = st->hTcxEnc->tcxltp_norm_corr_past; - move16(); } -#endif return; } -#endif + void updt_enc_common_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index 12ec31933..1fdcb94fa 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -1296,19 +1296,9 @@ Word16 wb_vad_fx( L_tmp = L_shl( L_mult( sub( hNoiseEst->Etot_v_h2_fx, nv_ofs ), nv ), 7 ); /* Q8+Q8+1 +7 --> Q24 */ L_tmp = L_mac( L_tmp, nc, (Word16) 32767 ); /* Q8+Q15+1 = Q24 */ thr1 = mac_r( L_tmp, lp_snr, nk ); /* Q8+Q15+1 - 16 --> Q8 */ -#ifdef IVAS_CODE - IF( st->element_mode > EVS_MONO && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) - { - /* lower threshold during warmup time */ - thr1 -= 10.0f; - vad_thr = 0.f; - } -#endif + IF( GT_16( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) /* if (lp_snr > 20.0f )*/ { -#ifdef IVAS_CODE - IF( st->element_mode == EVS_MONO || GT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) -#endif { /* thr1 = thr1 + 0.3f * (lp_snr - 20.0f); */ thr1 = add( thr1, mult( 9830, sub( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) ); /* Q15*Q8+1 -16 --> Q8 */ -- GitLab From 65df1d250d03b1181a37b3149b1f67285ae5f266 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 15:57:17 +0530 Subject: [PATCH 0314/1221] Clang formatting changes --- lib_enc/swb_bwe_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 639ec9dca..3ca3f3f3f 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -3205,7 +3205,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( tmp = i_mult2( n_band, L ); FOR( i = 0; i < L; i++ ) { - WB_tenv_syn_fx = L_add( WB_tenv_syn_fx, L_shr( L_mult0( synth_fx[i + tmp], synth_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp-7 */ + WB_tenv_syn_fx = L_add( WB_tenv_syn_fx, L_shr( L_mult0( synth_fx[i + tmp], synth_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp-7 */ WB_tenv_orig_fx = L_add( WB_tenv_orig_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp - 7 */ } -- GitLab From e46fb7a4a262cabfb315c91d213c418e14358ec7 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 11:27:53 +0100 Subject: [PATCH 0315/1221] review and remove redundant code under IVAS_CODE_SWITCHING --- lib_com/prot_fx.h | 18 +-- lib_dec/core_switching_dec_fx.c | 279 ++------------------------------ lib_dec/evs_dec_fx.c | 10 +- 3 files changed, 16 insertions(+), 291 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index cb7416eb3..0371f747a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -8011,22 +8011,12 @@ ivas_error core_switching_pre_dec_fx( ); ivas_error core_switching_post_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth Qsynth*/ -#ifdef IVAS_CODE_SWITCHING - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth Qsynth*/ const Word16 output_frame, /* i : frame length Q0*/ const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ -#ifdef IVAS_CODE_SWITCHING - const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const Word16 nchan_out, /* i : number of output channels */ -#endif - const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ - Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ); ivas_error core_switching_post_dec_ivas_fx( diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index f984f2ce9..17b3f9fbc 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -16,10 +16,6 @@ * * *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE_SWITCHING -static void core_switch_lb_upsamp( Decoder_State *st, float *output ); -static void smoothTransitionDtxToTcx( float synth[], const int16_t output_frame, const int16_t delay_comp ); -#endif static void smoothTransitionDtxToTcx_fx( Word16 synth[], const Word16 output_frame, const Word16 delay_comp ); static void core_switch_lb_upsamp_fx( Decoder_State *st, Word32 *output ); @@ -189,30 +185,11 @@ void bw_switching_pre_proc_fx( Flag Overflow = 0; move32(); #endif -#ifdef IVAS_CODE_SWITCHING + IF( st_fx->element_mode > EVS_MONO ) { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st_fx->core, ACELP_CORE ) && !( EQ_16( st_fx->bfi, 1 ) && EQ_16( st_fx->con_tcx, 1 ) ) && - st_fx->hBWE_FD != NULL && !( LE_16( st_fx->core_brate, SID_2k40 ) && EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && - !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st_fx->idchan, 1 ) && LE_16( last_element_brate, IVAS_SID_4k4 ) ) ) - { - /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ - calc_tilt_bwe( old_syn_12k8_16k, &st->tilt_wb, st->L_frame ); - } - - return; } -#endif + test(); test(); IF( EQ_16( st_fx->core, ACELP_CORE ) && !( EQ_16( st_fx->bfi, 1 ) && EQ_16( st_fx->con_tcx, 1 ) ) ) @@ -321,149 +298,7 @@ void bw_switching_pre_proc_fx( return; } -#ifdef IVAS_CODE_SWITCHING - - -/*---------------------------------------------------------------------* - * core_switch_lb_upsamp() - * - * Resample HQ/TCX-LB to the output sampling rate (8/16/32/48 kHz) - *---------------------------------------------------------------------*/ - -static void core_switch_lb_upsamp( - Decoder_State *st, /* i/o: Decoder state */ - float *output /* i/o: LB synth/upsampled LB synth */ -) -{ - int16_t i; - float *realBuffer[CLDFB_OVRLP_MIN_SLOTS], *imagBuffer[CLDFB_OVRLP_MIN_SLOTS]; - float realBufferTmp[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; - float imagBufferTmp[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; - - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ - for ( i = 0; i < CLDFB_OVRLP_MIN_SLOTS; i++ ) - { - set_f( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - set_f( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer[i] = realBufferTmp[i]; - imagBuffer[i] = imagBufferTmp[i]; - } - - /* check if the CLDFB works on the right sample rate */ - if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) - { - resampleCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - - if ( st->cldfbBPF != NULL && st->L_frame <= L_FRAME16k ) - { - resampleCldfb( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); - } - - if ( st->ini_frame > 0 ) - { - st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; - } - } - - /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysis( output, realBuffer, imagBuffer, CLDFB_OVRLP_MIN_SLOTS * st->cldfbAna->no_channels, st->cldfbAna ); - - /* analysis and add the BPF error signal */ - if ( st->p_bpf_noise_buf ) - { - addBassPostFilter( st->p_bpf_noise_buf, st->bpf_off ? 0 : CLDFB_OVRLP_MIN_SLOTS * st->cldfbBPF->no_channels, realBuffer, imagBuffer, st->cldfbBPF ); - } - - /* set output mask for upsampling */ - if ( st->bwidth == NB ) - { - /* set NB mask for upsampling */ - st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - 10; - } - else if ( st->cldfbSyn->bandsToZero != st->cldfbSyn->no_channels - st->cldfbAna->no_channels ) - { - /* in case of BW switching, re-init to default */ - st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; - } - - /* synthesis of the combined signal */ - cldfbSynthesis( realBuffer, imagBuffer, output, CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels, st->cldfbSyn ); - - /* save synthesis - needed in case of core switching */ - if ( st->hTcxDec != NULL ) - { - mvr2r( output, st->previoussynth, st->hTcxDec->L_frameTCX ); - } - - return; -} - -/*---------------------------------------------------------------------* - * smoothTransitionMdctStereoDtx() - * - * apply smoothing to the transition part for MDCT-Stereo DTX - *---------------------------------------------------------------------*/ - -#define TRANSITION_SMOOTHING_LEN_16k 15 -#define TRANSITION_SMOOTHING_LEN_32k 31 -#define TRANSITION_SMOOTHING_LEN_48k 47 - -static void smoothTransitionMdctStereoDtx( - float synth[], /* i/o: synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t delay_comp /* i : delay compensation in samples */ -) -{ - int16_t i, filter_len; - float w, mem, step, fade_in; - float smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; - float smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; - - filter_len = TRANSITION_SMOOTHING_LEN_16k; - if ( output_frame == L_FRAME32k ) - { - filter_len = TRANSITION_SMOOTHING_LEN_32k; - } - else if ( output_frame == L_FRAME48k ) - { - filter_len = TRANSITION_SMOOTHING_LEN_48k; - } - - /* prepare buffer */ - for ( i = 0; i < filter_len / 2; i++ ) - { - smoothing_input_buffer[i] = synth[0]; - } - mvr2r( synth, smoothing_input_buffer + filter_len / 2, 2 * delay_comp + filter_len / 2 ); - - /* apply Mean filter */ - w = 1.f / filter_len; - mem = sum_f( smoothing_input_buffer, filter_len ); - for ( i = 0; i < 2 * delay_comp; i++ ) - { - smoothing_out_buffer[i] = w * mem; - mem = mem - smoothing_input_buffer[i] + smoothing_input_buffer[i + filter_len]; - } - /* apply fades around transition */ - step = 1.f / delay_comp; - fade_in = 0.f; - for ( i = 0; i < delay_comp; i++ ) - { - synth[i] = smoothing_out_buffer[i] * fade_in + synth[i] * ( 1 - fade_in ); - fade_in += step; - } - - fade_in = 0.f; - for ( ; i < 2 * delay_comp; i++ ) - { - synth[i] = synth[i] * fade_in + smoothing_out_buffer[i] * ( 1 - fade_in ); - fade_in += step; - } - - return; -} -#endif /*---------------------------------------------------------------------* * core_switching_pre_dec_fx() * @@ -738,13 +573,7 @@ ivas_error core_switching_pre_dec_fx( test(); test(); - IF( ( ( EQ_16( st_fx->core, ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) - //#ifdef IVAS_CODE_SWITCHING - // || ((EQ_16(st_fx->element_mode, IVAS_CPE_DFT) || EQ_16(st_fx->element_mode, IVAS_CPE_TD) || - // (EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && last_element_mode == IVAS_CPE_DFT)) && EQ_16(nchan_out,2) && - // NE_16(st_fx->core_brate, SID_2k40) && NE_16(st_fx->core_brate, FRAME_NO_DATA) && (EQ_16(last_core_brate_st0, FRAME_NO_DATA) || EQ_16(last_core_brate_st0, SID_2k40))) - //#endif - ) + IF( ( ( EQ_16( st_fx->core, ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) ) { test(); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) @@ -770,14 +599,7 @@ ivas_error core_switching_pre_dec_fx( lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); } -#ifdef IVAS_CODE_SWITCHING - if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && nchan_out == 2 && st->core_brate > SID_2k40 && ( last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40 ) && st->hTcxDec != NULL ) - { - /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ - set_f( st->hTcxDec->old_syn_Overl, 0.0f, L_FRAME32k / 2 ); - set_f( st->hFdCngDec->hFdCngCom->olapBufferAna, 0.0f, FFTLEN ); - } -#endif + set16_fx( st_fx->agc_mem_fx, 0, 2 ); st_fx->mem_deemph_fx = 0; move16(); @@ -876,47 +698,7 @@ ivas_error core_switching_pre_dec_fx( set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); } } -#ifdef IVAS_CODE_SWITCHING - if ( ( st->core == ACELP_CORE || st->core == AMR_WB_CORE ) && ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) ) - { - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; - set_f( st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); - } - - st->tilt_code = 0.0f; - st->gc_threshold = 0.0f; - set_f( st->dispMem, 0, 8 ); - - st->last_coder_type = GENERIC; - - fer_energy( output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1 ); - st->lp_gainp = 0.0f; - st->lp_gainc = (float) sqrt( st->lp_ener ); - - st->last_voice_factor = 0; - st->Last_GSC_noisy_speech_flag = 0; - - if ( st->output_Fs >= 16000 && st->hBWE_zero != NULL ) - { - hf_synth_reset( st->hBWE_zero ); - } - if ( st->hBWE_FD != NULL ) - { - set_f( st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - if ( nchan_out == 1 && st->element_mode == IVAS_CPE_DFT && st->element_brate <= IVAS_24k4 && last_element_brate > IVAS_24k4 ) - { - /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ - int16_t offset; - offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; - mvr2r( st->hTcxDec->old_synthFB + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state, offset ); - } - } -#endif test(); test(); test(); @@ -941,40 +723,16 @@ ivas_error core_switching_pre_dec_fx( { set32_fx( hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); } -#ifdef IVAS_CODE_SWITCHING - if ( st->element_mode != EVS_MONO ) - { - /* Estimate mem_env_delta to reinit env_stab */ - tmp = max( 0, ENV_STAB_EST1 + ( ENV_STAB_EST2 * st->stab_fac_smooth_lt ) + ( ENV_STAB_EST3 * st->log_energy_diff_lt ) ); - st->hHQ_core->mem_env_delta = (int16_t) min( MAX16B, (int32_t) ( tmp * ( 1 << 12 ) ) ); /* Convert to Q12 and handle saturation */ - - if ( st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE ) - { - set_f( st->hHQ_core->old_out, 0, output_frame ); - set_f( st->hHQ_core->old_outLB, 0, L_FRAME16k ); - } - st->hHQ_core->no_att_hangover = 0; - st->hHQ_core->energy_lt = 300.0f; - - set_s( st->hHQ_core->old_is_transient, 0, 3 ); - set_f( st->hHQ_core->prev_noise_level, 0.0f, 2 ); - st->hHQ_core->prev_R = 0; - set_s( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); - st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; - st->hHQ_core->prev_ni_ratio = 0.5f; - set_f( st->hHQ_core->prev_En_sb, 0.0f, NB_SWB_SUBBANDS ); + if ( st_fx->element_mode != EVS_MONO ) + { } else -#endif { set16_fx( hHQ_core->old_out_fx, 0, output_frame ); hHQ_core->Q_old_wtda_LB = 15; hHQ_core->Q_old_wtda = 15; move16(); -#ifdef IVAS_CODE_SWITCHING - set_f( st->hHQ_core->old_outLB, 0, L_FRAME16k ); -#endif } } @@ -1081,12 +839,10 @@ ivas_error core_switching_pre_dec_fx( IF( NE_16( st_fx->last_L_frame, st_fx->L_frame ) && LE_16( st_fx->L_frame, L_FRAME16k ) && LE_16( st_fx->last_L_frame, L_FRAME16k ) ) { test(); -#ifdef IVAS_CODE_SWITCHING IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - lerp( st_fx->hFdCngDec->hFdCngCom->olapBufferAna + st_fx->last_L_frame, st_fx->hFdCngDec->hFdCngCom->olapBufferAna + st_fx->L_frame, st_fx->L_frame, st_fx->last_L_frame ); } -#endif + lerp( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, shl( st_fx->L_frame, 1 ), shl( st_fx->last_L_frame, 1 ) ); test(); IF( LE_32( st_fx->total_brate, SID_2k40 ) && LE_32( st_fx->last_total_brate, SID_2k40 ) ) @@ -1122,22 +878,12 @@ ivas_error core_switching_pre_dec_fx( *---------------------------------------------------------------------*/ ivas_error core_switching_post_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth*/ -#ifdef IVAS_CODE_SWITCHING - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth*/ const Word16 output_frame, /* i : frame length Q0*/ const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ -#ifdef IVAS_CODE_SWITCHING - const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const Word16 nchan_out, /* i : number of output channels */ -#endif - const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ - Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ) { Word16 i, delay_comp, delta; @@ -1152,9 +898,6 @@ ivas_error core_switching_post_dec_fx( HQ_DEC_HANDLE hHQ_core; ivas_error error; -#ifdef IVAS_CODE_SWITCHING - int16_t offset; -#endif #ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( last_element_mode ); #endif diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 60e13dd8f..a5a5ba6d9 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -360,15 +360,7 @@ ivas_error evs_dec_fx( * Postprocessing for ACELP/HQ core switching *---------------------------------------------------------------------*/ - if ( ( error = core_switching_post_dec_fx( st_fx, synth_fx, -#ifdef IVAS_CODE_SWITCHING - output, output_mem[], IVAS_FORMAT ivas_format, use_cldfb_for_dft, -#endif - output_frame, core_switching_flag, -#ifdef IVAS_CODE_SWITCHING - sba_dirac_stereo_flag, nchan_out, -#endif - st_fx->last_element_mode, &Qpostd ) ) != IVAS_ERR_OK ) + if ( ( error = core_switching_post_dec_fx( st_fx, synth_fx, output_frame, core_switching_flag, st_fx->last_element_mode, &Qpostd ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From d716d99ff0cda5fd84edb3c30aacb7d92c45ee25 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 11:29:26 +0100 Subject: [PATCH 0316/1221] remove redundant code under IVAS_CODE_FCB --- lib_dec/dec4t64_fx.c | 235 ------------------------------------------- 1 file changed, 235 deletions(-) diff --git a/lib_dec/dec4t64_fx.c b/lib_dec/dec4t64_fx.c index 58f9048c4..ee6ef65a6 100644 --- a/lib_dec/dec4t64_fx.c +++ b/lib_dec/dec4t64_fx.c @@ -793,242 +793,7 @@ void D_ACELP_decode_43bit_fx( UWord16 idxs[], Word16 code[], Word16 *pulsestrack return; } -#ifdef IVAS_CODE_FCB -/*-------------------------------------------------------* - * dec_1p_N1() - * - * Decode 1 pulse with N+1 bits - *-------------------------------------------------------*/ - -static void dec_1p_N1_L_subfr( - const int32_t index, /* i : quantization index */ - const int16_t nb_pos, /* i : number of positions */ - const int16_t N, /* i : nb. of bits */ - int16_t pos[] /* o : pulse position */ -) -{ - int16_t i, pos1; - int32_t mask; - - mask = ( ( 1 << N ) - 1 ); - pos1 = (int16_t) ( index & mask ); - i = (int16_t) ( index >> N ) & 1; - - if ( i == 1 ) - { - pos1 += nb_pos; - } - - pos[0] = pos1; - - return; -} - -/*-------------------------------------------------------* - * add_pulses() - * - * Add decoded pulses to the codeword - *-------------------------------------------------------*/ - -static void add_pulses_L_subfr( - const int16_t nb_pos, /* i : number of positions */ - const int16_t pos[], /* i : pulse position */ - const int16_t nb_pulse, /* i : nb. of pulses */ - const int16_t track, /* i : no. of the tracks */ - float code[] /* i/o: decoded codevector */ -) -{ - int16_t i, k; - - for ( k = 0; k < nb_pulse; k++ ) - { - i = ( ( pos[k] & ( nb_pos - 1 ) ) * NB_TRACK_FCB_4T ) + track; - if ( ( pos[k] & nb_pos ) == 0 ) - { - code[i] += 1.0f; - } - else - { - code[i] -= 1.0f; - } - } - - return; -} - -/*----------------------------------------------------------------------------------* - * dec_acelp_fast() - * - * fast algebraic codebook decoder - *----------------------------------------------------------------------------------*/ - -void dec_acelp_fast( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t cdk_index, /* i : codebook index */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -) -{ - int16_t k, pos[7], skip_track; - int32_t L_index; - PulseConfig config; - - skip_track = -1; - set_f( code, 0.0f, L_subfr ); - - if ( L_subfr == L_SUBFR ) - { - config = PulseConfTable[cdk_index]; - - if ( cdk_index == 2 ) - { - dec_acelp_2t32( st, code ); - } - else if ( config.nb_pulse == 2 ) - { - /* 10 bits, 2 pulses, 4 tracks 1010 (used only even tracks) */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k += 2 ) - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - else if ( config.nb_pulse == 3 ) - { - if ( config.codetrackpos == TRACKPOS_FIXED_FIRST ) - { - /* 15 bits, 3 pulses, 4 tracks 1110 fixed track to first ? */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k++ ) - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - else if ( config.codetrackpos == TRACKPOS_FREE_THREE ) - { - /* 17 bits, 3 pulses, 4 tracks (used all tracks) - 1110, 1101, 1011, 0111 */ - skip_track = get_next_indice( st, 2 ); - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - if ( k != skip_track ) - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - } - } - else - { - if ( config.bits == 20 ) - { - skip_track = -1; - } - else if ( config.codetrackpos == TRACKPOS_FIXED_FIRST ) - { - skip_track = 0; - } - else if ( config.codetrackpos == TRACKPOS_FREE_ONE ) - { - skip_track = get_next_indice( st, 2 ); - } - - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - if ( k == skip_track ) - { - L_index = get_next_indice( st, 9 ); - dec_2p_2N1( L_index, 4, 0, pos ); - add_pulses( pos, 2, k, code ); - } - else - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - } - } - else /* L_subfr == 2*L_SUBFR */ - { - config.bits = cdk_index; - - if ( cdk_index == 14 ) - { - /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */ - int16_t index, i0, i1; - - index = get_next_indice( st, 14 ); - - i0 = ( ( index >> 7 ) & ( NB_POS_FCB_2T_128 - 1 ) ) * NB_TRACK_FCB_2T; - i1 = ( ( index & ( NB_POS_FCB_2T_128 - 1 ) ) * NB_TRACK_FCB_2T ) + 1; - - code[i0] = -1.0f; - if ( ( index & 0x2000 ) == 0 ) - { - code[i0] = 1.0f; - } - - code[i1] = -1.0f; - if ( ( index & 0x40 ) == 0 ) - { - code[i1] = 1.0f; - } - } - else if ( cdk_index == 12 ) - { - /* 12 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k += 2 ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - else if ( cdk_index == 18 ) - { - /* 18 bits, 3 pulses, 4 tracks: 1110 (used first three tracks) */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k++ ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - else if ( cdk_index == 20 ) - { - /* 20 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */ - skip_track = get_next_indice( st, 2 ); - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - if ( k != skip_track ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - } - else if ( cdk_index == 24 ) - { - /* 24 bits, 4 pulses, 4 tracks: 1111 */ - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - } - - return; -} -#endif /*-------------------------------------------------------* * dec_1p_N1() -- GitLab From 3c022b6dac418d2aa99a2d0c7779a63d18c6ea4b Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 11:34:25 +0100 Subject: [PATCH 0317/1221] remove redundant code under IVAS_CODE_CPE, IVAS_CODE_DFT, and IVAS_CODE_BWD --- lib_enc/amr_wb_enc_fx.c | 6 +----- lib_enc/analy_sp_fx.c | 24 ++---------------------- lib_enc/bw_detect_fx.c | 11 +++-------- lib_enc/pre_proc_fx.c | 6 +----- lib_enc/prot_fx_enc.h | 4 ---- 5 files changed, 7 insertions(+), 44 deletions(-) diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index 90bdc74a5..5a3aec3f4 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -292,11 +292,7 @@ void amr_wb_enc_fx( * Detect NB spectrum in a 16kHz-sampled input *----------------------------------------------------------------*/ - analy_sp_fx( st->element_mode, -#ifdef IVAS_CODE_CPE - hCPE, -#endif - st->input_Fs, inp, Q_new, fr_bands, lf_E, &Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, + analy_sp_fx( st->element_mode, inp, Q_new, fr_bands, lf_E, &Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, PS, st->lgBin_E_fx, st->band_energies, fft_buff ); noise_est_pre_fx( Etot, st->ini_frame, hNoiseEst, 0, EVS_MONO, EVS_MONO ); diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index d5333ae13..185bac26b 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -19,9 +19,7 @@ static void find_enr( Word16 data[], Word32 band[], Word32 *ptE, Word32 *LEtot, const Word16 min_band, const Word16 max_band, const Word16 Q_new2, const Word32 e_min, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies ); static void ivas_find_enr( Word16 *data, Word16 q_data, Word32 *band, Word16 *q_band, Word32 *ptE, Word16 *q_ptE, Word64 *LEtot, const Word16 min_band, const Word16 max_band, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies ); -#ifdef IVAS_CODE_CPE -static void find_enr_dft( CPE_ENC_HANDLE hCPE, const int32_t input_Fs, float DFT_past_DMX[], float band[], float *ptE, float *Etot, const int16_t min_band, const int16_t max_band, float *Bin_E, float *band_ener ); -#endif + /*-------------------------------------------------------------------* * analy_sp_fx() @@ -31,10 +29,6 @@ static void find_enr_dft( CPE_ENC_HANDLE hCPE, const int32_t input_Fs, float DFT void analy_sp_fx( const Word16 element_mode, /* i : element mode */ -#ifdef IVAS_CODE_CPE - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ -#endif - const Word32 input_Fs, /* i : input sampling rate */ Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ const Word16 Q_new, /* i : current scaling exp Q0 */ Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ @@ -60,9 +54,7 @@ void analy_sp_fx( Word16 Min_val, Max_val; Word16 Scale_fac2; Word16 fft_temp[L_FFT]; -#ifndef IVAS_CODE_CPE - (void) input_Fs; -#endif + /*-----------------------------------------------------------------* * Compute spectrum * find energy per critical frequency band and total energy in dB @@ -134,18 +126,6 @@ void analy_sp_fx( pt_fft += L_FFT; } } -#ifdef IVAS_CODE_CPE - ELSE - { - /* find energy per critical band */ - find_enr_dft( hCPE, input_Fs, hCPE->hStereoDft->DFT[0], pt_bands, lf_E, Etot, min_band, max_band, Bin_E, band_ener ); - mvr2r( lf_E, lf_E + VOIC_BINS, VOIC_BINS ); - mvr2r( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 ); - mvr2r( band_ener, band_ener + NB_BANDS, NB_BANDS ); - mvr2r( pt_bands, pt_bands + NB_BANDS, NB_BANDS ); - *Etot *= 2.f; - } -#endif /* Average total log energy over both half-frames */ frac_etot = 0; diff --git a/lib_enc/bw_detect_fx.c b/lib_enc/bw_detect_fx.c index 931b175ff..2e9b2c5db 100644 --- a/lib_enc/bw_detect_fx.c +++ b/lib_enc/bw_detect_fx.c @@ -67,12 +67,6 @@ void bw_detect_fx( const Word32 *pt32; Word32 max_NB32, max_WB32, max_SWB32, max_FB32, mean_NB32, mean_WB32, mean_SWB32, mean_FB32; /* Q11*/ /* we need Word32 for the new cldfb energy vectors */ Word16 bwd_count_wider_bw; -#ifdef IVAS_CODE_DFT - Word16 l_frame; -#endif -#ifndef IVAS_CODE_BWD - (void) spectrum; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -1046,7 +1040,7 @@ void set_bw_fx( move16(); } } -//#ifdef IVAS_CODE_BWD + /*-------------------------------------------------------------------* * set_bw_stereo() @@ -1093,7 +1087,8 @@ void set_bw_stereo_fx( return; } -//#endif + + /*-------------------------------------------------------------------* * set_bw_mct() * diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 5a8f4aa7c..7c17e76d8 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -254,11 +254,7 @@ void pre_proc_fx( * Spectral analysis *--------------------------------------------------------------------------*/ - analy_sp_fx( -1, -#ifdef IVAS_CODE_CPE - NULL, -#endif - st->input_Fs, inp_12k8, *Q_new, fr_bands, lf_E, Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, + analy_sp_fx( -1, inp_12k8, *Q_new, fr_bands, lf_E, Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, PS, st->lgBin_E_fx, st->band_energies, fft_buff ); st->band_energies_exp = sub( sub( WORD32_BITS - 1, *Q_new ), QSCALE ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 0a058740b..02f8344d1 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2190,10 +2190,6 @@ void stat_noise_uv_enc_ivas_fx( void analy_sp_fx( const Word16 element_mode, /* i : element mode */ -#ifdef IVAS_CODE_CPE - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ -#endif - const Word32 input_Fs, /* i : i sampling rate */ Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ const Word16 Q_new, /* i : current scaling exp Q0 */ Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ -- GitLab From 510e8af8c52190ec433eafe94526aa07e37e6ab0 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 11:55:26 +0100 Subject: [PATCH 0318/1221] clang-format --- lib_com/gs_bitallocation_fx.c | 56 +++++++++++++++++------------------ lib_enc/lsf_enc_fx.c | 8 ++--- lib_enc/pre_proc_fx.c | 2 +- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib_com/gs_bitallocation_fx.c b/lib_com/gs_bitallocation_fx.c index e8f32c804..87ba794d4 100644 --- a/lib_com/gs_bitallocation_fx.c +++ b/lib_com/gs_bitallocation_fx.c @@ -230,9 +230,9 @@ void bands_and_bit_alloc_fx( nb_bands = shr( *pvq_len, 4 ); /*------------------------------------------------------------------------ - * Ajustement of the maximum number of bands in function of the - * dynamics of the spectrum (more or less speech like) - *-----------------------------------------------------------------------*/ + * Ajustement of the maximum number of bands in function of the + * dynamics of the spectrum (more or less speech like) + *-----------------------------------------------------------------------*/ test(); test(); test(); @@ -268,8 +268,8 @@ void bands_and_bit_alloc_fx( } /*------------------------------------------------------------------------ - * Find extra number of band to code according to bit rate availables - *-----------------------------------------------------------------------*/ + * Find extra number of band to code according to bit rate availables + *-----------------------------------------------------------------------*/ test(); WHILE( GE_16( bit_tmp, bit_new_bands ) && LE_16( nb_bands, sub( nb_bands_max, 1 ) ) ) { @@ -279,15 +279,15 @@ void bands_and_bit_alloc_fx( } /*------------------------------------------------------------------------ - * Fractional bits to distribute on the first x bands - *-----------------------------------------------------------------------*/ + * Fractional bits to distribute on the first x bands + *-----------------------------------------------------------------------*/ { bit_fracf = L_mult( div_s( 1, st_band ), shl( bit_tmp, 2 ) ); /* Q18 */ } /*------------------------------------------------------------------------ - * Complete the bit allocation per frequency band - *-----------------------------------------------------------------------*/ + * Complete the bit allocation per frequency band + *-----------------------------------------------------------------------*/ imax = 5; move16(); @@ -315,8 +315,8 @@ void bands_and_bit_alloc_fx( } /*-------------------------------------------------------------------------- - * Complete the bit allocation per frequency band for 16kHz high brate mode - *--------------------------------------------------------------------------*/ + * Complete the bit allocation per frequency band for 16kHz high brate mode + *--------------------------------------------------------------------------*/ { FOR( j = st_band; j < nb_bands; j++ ) @@ -327,9 +327,9 @@ void bands_and_bit_alloc_fx( } /*-------------------------------------------------------------------------- - * Compute a maximum band (band offset) for the search on maximal energy - * This is function of the spectral dynamic and the bitrate - *--------------------------------------------------------------------------*/ + * Compute a maximum band (band offset) for the search on maximal energy + * This is function of the spectral dynamic and the bitrate + *--------------------------------------------------------------------------*/ bandoffset = sub( nb_tot_bands, add( nb_bands, 2 ) ); @@ -351,10 +351,10 @@ void bands_and_bit_alloc_fx( bandoffset = s_max( bandoffset, 0 ); /*-------------------------------------------------------------------------- - * Initiazed sorted vector - * For the first x bands to be included in th final sorted vector - * Sort the remaining bands in decrease energy order - *--------------------------------------------------------------------------*/ + * Initiazed sorted vector + * For the first x bands to be included in th final sorted vector + * Sort the remaining bands in decrease energy order + *--------------------------------------------------------------------------*/ FOR( j = 0; j < nb_tot_bands; j++ ) { max_ener_band[j] = -10; @@ -432,10 +432,10 @@ void bands_and_bit_alloc_fx( } } /*-------------------------------------------------------------------------- - * Bit sum verification for GSC inactive at very high rate - * The maximum number of bits per band of length 16 is 112 - * Redistribute the overage bits if needed - *--------------------------------------------------------------------------*/ + * Bit sum verification for GSC inactive at very high rate + * The maximum number of bits per band of length 16 is 112 + * Redistribute the overage bits if needed + *--------------------------------------------------------------------------*/ sum_bit = 0; move16(); j = 0; @@ -468,8 +468,8 @@ void bands_and_bit_alloc_fx( } } /*-------------------------------------------------------------------------- - * second step of bit sum verification, normally sum_bit == *bit - *--------------------------------------------------------------------------*/ + * second step of bit sum verification, normally sum_bit == *bit + *--------------------------------------------------------------------------*/ w_sum_bit = 0; move16(); FOR( i = 0; i < nb_bands; i++ ) @@ -497,15 +497,15 @@ void bands_and_bit_alloc_fx( } /*-------------------------------------------------------------------------- - * Recompute the real number/length of frequency bands to encode - *--------------------------------------------------------------------------*/ + * Recompute the real number/length of frequency bands to encode + *--------------------------------------------------------------------------*/ *nb_subbands = nb_bands; move16(); *pvq_len = shl( *nb_subbands, 4 ); /*-------------------------------------------------------------------------- - * Concatenate bands (encoder only) - *--------------------------------------------------------------------------*/ + * Concatenate bands (encoder only) + *--------------------------------------------------------------------------*/ IF( exc_diff != NULL ) { FOR( j = 0; j < nb_bands; j++ ) diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 96ab40547..709bb47e0 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -1106,8 +1106,8 @@ void lsf_end_enc_fx( } /*--------------------------------------------------------------------------* \ - * Write indices to array \ - *--------------------------------------------------------------------------*/ + * Write indices to array \ + *--------------------------------------------------------------------------*/ IF( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->core, ACELP_CORE ) ) { @@ -1981,7 +1981,7 @@ static void first_VQstages( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ @@ -2171,7 +2171,7 @@ static void first_VQstages_ivas_fx( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 7c17e76d8..4ce9403a6 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -214,7 +214,7 @@ void pre_proc_fx( * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* -- GitLab From fd7c5da5ba8747239702eaff899b3559c43362e8 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 5 Mar 2025 14:16:04 +0100 Subject: [PATCH 0319/1221] Fix scaling errors. --- lib_rend/ivas_dirac_output_synthesis_dec.c | 2 +- lib_rend/ivas_dirac_rend.c | 65 +++++++++++++++++++++- lib_rend/lib_rend.c | 8 +-- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index c733f12c0..28026b487 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -4061,7 +4061,7 @@ static void computeTargetPSDs_direct_fx( v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[0] ) ); + Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); #else Word16 common1_q = s_min( *q_cy_auto_dir_smooth, *q_reference_power ); diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 9ebcb3132..7f4076266 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -2808,6 +2808,9 @@ void protoSignalComputation4_fx( Word32 sq_tmp_fx; Word32 *p_proto_buffer_fx; Word16 min_q_shift, q_shift; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 min_q_shift2, q_shift2; +#endif Word32 re, im; Word16 proto_power_smooth_fx_q, sq_tmp_q; @@ -2815,6 +2818,12 @@ void protoSignalComputation4_fx( move16(); q_shift = Q31; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + min_q_shift2 = Q31; + move16(); + q_shift2 = Q31; + move16(); +#endif sq_tmp_q = 0; move16(); @@ -2823,16 +2832,52 @@ void protoSignalComputation4_fx( /* calculate the shift possible for both RealBuffer_fx and ImagBuffer_fx buffers*/ FOR( k = 0; k < s_max( 4, nchan_transport ); k++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + q_shift = L_norm_arr( RealBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands) ); + min_q_shift = s_min( q_shift, min_q_shift ); + q_shift = L_norm_arr( ImagBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands) ); + min_q_shift = s_min( q_shift, min_q_shift ); + q_shift2 = L_norm_arr( RealBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + min_q_shift2 = s_min( q_shift2, min_q_shift2 ); + q_shift2 = L_norm_arr( ImagBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + min_q_shift2 = s_min( q_shift2, min_q_shift2 ); +#else q_shift = L_norm_arr( RealBuffer_fx[k][0], num_freq_bands ); min_q_shift = s_min( q_shift, min_q_shift ); q_shift = L_norm_arr( ImagBuffer_fx[k][0], num_freq_bands ); min_q_shift = s_min( q_shift, min_q_shift ); +#endif } q_shift = min_q_shift; min_q_shift = sub( min_q_shift, find_guarded_bits_fx( i_mult( 2, 4 ) ) ); - +#ifdef FIX_867_CLDFB_NRG_SCALE + q_shift2 = min_q_shift2; + min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( i_mult( 2, 4 ) ) ); +#endif FOR( k = 0; k < 4; k++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + FOR( l = 0; l < s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ); l++ ) + { + re = L_shl( RealBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift + im = L_shl( ImagBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift + + sq_tmp_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 + + reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31 + move32(); + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + re = L_shl( RealBuffer_fx[k][0][l], min_q_shift2 ); // q_cldfb+min_q_shift + im = L_shl( ImagBuffer_fx[k][0][l], min_q_shift2 ); // q_cldfb+min_q_shift + + sq_tmp_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 + + reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31 + move32(); + } +#else FOR( l = 0; l < num_freq_bands; l++ ) { re = L_shl( RealBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -2843,12 +2888,24 @@ void protoSignalComputation4_fx( reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31 move32(); } +#endif } +#ifdef FIX_867_CLDFB_NRG_SCALE + sq_tmp_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + reference_power_q[0] = sq_tmp_q; + move16(); + sq_tmp_q = sub( add( add( q_cldfb, min_q_shift2 ), add( q_cldfb, min_q_shift2 ) ), 31 ); + reference_power_q[1] = sq_tmp_q; + move16(); + + min_q_shift = sub( s_min( q_shift, q_shift2 ), find_guarded_bits_fx( 2 ) ); +#else sq_tmp_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); *reference_power_q = sub( add( sq_tmp_q, Q15 ), 15 ); move16(); min_q_shift = sub( q_shift, find_guarded_bits_fx( 2 ) ); +#endif /*For decorrelated diffuseness*/ FOR( l = 0; l < num_outputs_diff; l++ ) @@ -2931,8 +2988,14 @@ void protoSignalComputation4_fx( *proto_direct_buffer_f_q = *proto_frame_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_q[0] = proto_power_smooth_fx_q; + proto_power_smooth_q[1] = proto_power_smooth_fx_q; + move16(); move16(); +#else *proto_power_smooth_q = proto_power_smooth_fx_q; move16(); +#endif return; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 16739283b..4f430ff01 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8460,11 +8460,11 @@ static void intermidiate_ext_dirac_render( move16(); FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { - tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF ) ); + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ) ); } FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, CLDFB_NO_CHANNELS_HALF, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) , tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); move16(); @@ -8472,11 +8472,11 @@ static void intermidiate_ext_dirac_render( move16(); FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { - tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); } FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); move16(); -- GitLab From eb283286d62fcac0cad5bda9d4f4512f09d43af1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 14:20:53 +0100 Subject: [PATCH 0320/1221] fix build-codec-linux-make --- lib_com/frame_ener.c | 333 ------------------ lib_com/frame_ener_fx.c | 39 +++ lib_com/get_gain.c | 170 ---------- lib_com/gs_preech.c | 381 --------------------- lib_com/hp50.c | 728 ---------------------------------------- lib_com/hp50_fx.c | 10 - 6 files changed, 39 insertions(+), 1622 deletions(-) delete mode 100644 lib_com/frame_ener.c delete mode 100644 lib_com/get_gain.c delete mode 100644 lib_com/gs_preech.c delete mode 100644 lib_com/hp50.c diff --git a/lib_com/frame_ener.c b/lib_com/frame_ener.c deleted file mode 100644 index e89c4dfad..000000000 --- a/lib_com/frame_ener.c +++ /dev/null @@ -1,333 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" -/*----------------------------------------------------------------------------------* - * fer_energy() - * - * Estimation of pitch-synchronous (voiced sounds) or half-frame energy - *----------------------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -void fer_energy( - const int16_t L_frame, /* i : frame length */ - const int16_t clas, /* i : frame classification */ - const float *synth, /* i : synthesized speech at Fs = 12k8 Hz */ - const float pitch, /* i : pitch period */ - float *enr, /* o : pitch-synchronous or half_frame energy */ - const int16_t offset /* i : speech pointer offset (0 or L_frame) */ -) -{ - int16_t len; - const float *pt_synth; - - if ( clas == VOICED_CLAS || clas == ONSET || clas == SIN_ONSET ) /* Voiced or Onset current frame */ - { - len = (int16_t) ( pitch + 0.5f ); /* pitch value */ - - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + L_frame - len; - } - - emaximum( pt_synth, len, enr ); /* pitch synchronous E */ - } - else - { - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + L_frame / 2; - } - - *enr = dotp( pt_synth, pt_synth, L_frame / 2 ); - *enr /= (float) ( L_frame / 2 ); - } - return; -} -#endif - -void fer_energy_fx( - const Word16 L_frame, /* i : frame length */ - const Word16 clas, /* i : frame classification */ - const Word32 *synth, /* i : synthesized speech at Fs = 12k8 Hz Q(q_synth) */ - const Word16 q_synth, /* i : synthesized speech at Fs = 12k8 Hz */ - const Word16 pitch, /* i : pitch period Q0 */ - Word32 *enr, /* o : pitch-synchronous or half_frame energy Q0 */ - const Word16 offset /* i : speech pointer offset (0 or L_frame) */ -) -{ - Word16 len, shift, exp; - const Word32 *pt_synth; - Word16 enr_tmp, i; - Word64 W_tmp; - - test(); - test(); - IF( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */ - { - len = ( pitch ); /* pitch value */ - move16(); - - pt_synth = synth; - IF( offset != 0 ) - { - pt_synth = synth + sub( L_frame, len ); - } - - emaximum_32fx( q_synth, pt_synth, len, enr ); /* pitch synchronous E */ - } - ELSE - { - pt_synth = synth; - IF( offset != 0 ) - { - pt_synth = synth + shr( L_frame, 1 ); - } - - W_tmp = 0; - move64(); - FOR( i = 0; i < L_frame / 2; i++ ) - { - W_tmp = W_add( W_tmp, W_mult0_32_32( pt_synth[i], pt_synth[i] ) ); // Q = q_synth * 2 - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); // Q = q_synth * 2 + shift - *enr = W_extract_h( W_tmp ); // Q = q_synth * 2 + shift - 32 - move32(); - - enr_tmp = BASOP_Util_Divide3216_Scale( *enr, shr( L_frame, 1 ) /*Q0*/, &exp ); - *enr = L_shr( L_deposit_l( enr_tmp ), sub( sub( sub( shift, 32 ), exp ), 1 ) ); /*Q0*/ - move32(); - } - return; -} - - -/*----------------------------------------------------------------------------------* - * frame_ener() - * - * Estimation of pitch-synchronous (voiced) or mean half-frame (unvoiced) energy - *----------------------------------------------------------------------------------*/ -Word16 frame_ener_fx( - const Word16 L_frame, /* i : length of the frame */ - const Word16 clas, /* i : frame classification */ - const Word16 *synth, /* i : synthesized speech at Fs = 12k8 Hz Q_new */ - const Word16 pitch, /* i : pitch period Q0 */ - Word32 *enr_q, /* o : pitch-synchronous or half_frame energy Q0 */ - const Word16 offset, /* i : speech pointer offset (0 or L_FRAME) */ - const Word16 Q_new, /* i : Scaling factor */ - Word16 shift, /* i : Shift need to obtain 12 bits vectors */ - const Word16 enc /* i : Encoder/decoder */ -) -{ - Word16 len, exp_enrq, exp_tmp, pos; - Word16 i; - const Word16 *pt_synth; - Word32 Ltmp; - - exp_enrq = 0; - move16(); - test(); - test(); - IF( ( EQ_16( clas, VOICED_CLAS ) ) || ( EQ_16( clas, ONSET ) ) || ( EQ_16( clas, SIN_ONSET ) ) ) /* current frame is voiced */ - { - /* current frame is voiced */ - len = pitch; - move16(); /* pitch value at the end of frame */ - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + sub( L_frame, len ); - } - emaximum_fx( Q_new, pt_synth, len, enr_q ); - IF( enc != 0 ) - { - exp_enrq = norm_l( *enr_q ); - *enr_q = L_shl( *enr_q, exp_enrq ); - move32(); - exp_enrq = sub( exp_enrq, 2 ); - } - } - ELSE - { - /* current frame is unvoiced */ - Word16 L_frame2, exp2, enr_q_tmp; - - L_frame2 = shr( L_frame, 1 ); - pos = 0; - move16(); - - if ( offset != 0 ) - { - pos = sub( L_frame, L_frame2 ); - } - Ltmp = L_mult_sat( synth[pos], synth[pos] ); /*2 * Qnew + 1*/ - FOR( i = 1; i < L_frame2; i++ ) - { - Ltmp = L_mac_sat( Ltmp, synth[pos + i], synth[pos + i] ); /*2 * Qnew + 1*/ - } - test(); - IF( EQ_32( Ltmp, MAX_32 ) || enc != 0 ) - { - /* scale down when overflow occurs */ - *enr_q = Energy_scale( synth + pos, L_frame2, shift, &exp_enrq ); - move32(); - } - ELSE - { - shift = 0; - move16(); - /* Normalize acc in Q31 (energy already calculated) */ - pos = norm_l( Ltmp ); - Ltmp = L_shl( Ltmp, pos ); - exp_enrq = sub( 30, pos ); /* exponent = 0..30 */ - *enr_q = Ltmp; - move32(); - } - - /* enr2 = 1.0f/L_FRAME2 * dot_product(synth, synth, L_FRAME2) */ - exp_enrq = sub( exp_enrq, shl( shift, 1 ) ); - - IF( enc != 0 ) - { - assert( L_frame == 256 || L_frame == 320 ); - - exp_tmp = add( shl( Q_new, 1 ), -2 + 7 ); /* L_subfr == L_SUBFR */ - exp_enrq = sub( exp_enrq, exp_tmp ); - exp_enrq = sub( 31, exp_enrq ); - - IF( EQ_16( L_frame, 320 ) ) - { - *enr_q = Mult_32_16( *enr_q, 26214 ); /*x 0.8 to get /160*/ - move32(); - i = norm_l( *enr_q ); - *enr_q = L_shl( *enr_q, i ); - move32(); - exp_enrq = add( i, exp_enrq ); - } - } - ELSE - { - exp_enrq = sub( exp_enrq, add( Q_new, Q_new ) ); - enr_q_tmp /*Q30 exp2+exp_enrq*/ = BASOP_Util_Divide3216_Scale( *enr_q /*Q31*/, L_frame2 /*Q0*/, &exp2 ); - *enr_q = L_shr( L_deposit_l( enr_q_tmp ), sub( 30, add( exp2, exp_enrq ) ) ); /*Q0*/ - move32(); - *enr_q = L_add( *enr_q, 1 ); - move32(); - exp_enrq = 0; - move16(); - } - } - - return exp_enrq; -} - -/*------------------------------------------------------------------------* - * frame_energy() - * - * Compute pitch-synchronous energy at the frame end - *------------------------------------------------------------------------*/ -Word16 frame_energy_fx( /* o : Frame energy in Q8 */ - Word16 L_frame, - const Word16 *pitch, /* i : pitch values for each subframe Q6 */ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_syn*/ - const Word16 lp_speech, /* i : long term active speech energy average Q8 */ - Word16 *frame_ener, /* o : pitch-synchronous energy at frame end Q8 */ - const Word16 Q_syn /* i : Synthesis scaling */ -) -{ - Word32 Ltmp; - const Word16 *pt1; - Word16 tmp16, exp1, exp2, tmp1, tmp2; - Word16 len, enern; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - - /* len = (0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f) */ - len = mult_r( add_o( pitch[2], pitch[3], &Overflow ), 256 ); - - if ( LT_16( len, L_SUBFR ) ) - { - len = shl( len, 1 ); - } - pt1 = speech + sub( L_frame, len ); - - /* *frame_ener = 10.0f * log10(dot_product(pt1, pt1, len) / (float)len) */ - - tmp1 = norm_s( len ); - tmp2 = shl( len, tmp1 ); - tmp1 = sub( 15, tmp1 ); - - Ltmp = Dot_productSq16HQ( 0, pt1, len, &exp1 ); - exp1 = sub( exp1, shl( Q_syn, 1 ) ); - exp1 = sub( exp1, 1 ); /* compensation of leftshift caused by mac operation in dot_productSq16HQ */ - tmp16 = BASOP_Util_Divide3216_Scale( Ltmp, len, &exp2 ); - - exp1 = add( exp1, exp2 ); - exp1 = add( exp1, 1 ); /* compensate result of division Q-1 */ - - - tmp2 = norm_s( tmp16 ); - Ltmp = L_shl( L_deposit_h( tmp16 ), tmp2 ); /*Q16, (exp1-tmp2) = Q31, exp1-tmp2+15*/ - - Ltmp = BASOP_Util_Log2( Ltmp ); /*Q(31-6) = Q25*/ - exp1 = sub( 15 + exp1, tmp2 ); - - /*add ld(2^exp1)=exp1 but check format, first*/ - tmp16 = sub( sub( 15, norm_s( exp1 ) ), 5 ); /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/ - Ltmp = L_shr_o( Ltmp, tmp16, &Overflow ); /*Q25, tmp16*/ - exp2 = shr( exp1, tmp16 ); /*Q0 , tmp16*/ - Ltmp = L_add_o( Ltmp, L_shl( L_deposit_l( exp2 ), 25 ), &Overflow ); /*Q25, tmp16, normalized*/ - - /*make 10*log10 out of log2*/ - Ltmp = Mpy_32_16_1( Ltmp, LG10 ); /*Q25,tmp16 * Q13 = Q23, tmp16*/ - *frame_ener = extract_h( L_shl_o( Ltmp, add( tmp16, 1 ), &Overflow ) ); /*Q8*/ - move16(); - enern = sub_o( *frame_ener, lp_speech, &Overflow ); /*Q8*/ - - return enern; -} diff --git a/lib_com/frame_ener_fx.c b/lib_com/frame_ener_fx.c index 4428c0796..7ee58371a 100644 --- a/lib_com/frame_ener_fx.c +++ b/lib_com/frame_ener_fx.c @@ -47,6 +47,45 @@ * Estimation of pitch-synchronous (voiced sounds) or half-frame energy *----------------------------------------------------------------------------------*/ +void fer_energy( + const int16_t L_frame, /* i : frame length */ + const int16_t clas, /* i : frame classification */ + const float *synth, /* i : synthesized speech at Fs = 12k8 Hz */ + const float pitch, /* i : pitch period */ + float *enr, /* o : pitch-synchronous or half_frame energy */ + const int16_t offset /* i : speech pointer offset (0 or L_frame) */ +) +{ + int16_t len; + const float *pt_synth; + + if ( clas == VOICED_CLAS || clas == ONSET || clas == SIN_ONSET ) /* Voiced or Onset current frame */ + { + len = (int16_t) ( pitch + 0.5f ); /* pitch value */ + + pt_synth = synth; + if ( offset != 0 ) + { + pt_synth = synth + L_frame - len; + } + + emaximum( pt_synth, len, enr ); /* pitch synchronous E */ + } + else + { + pt_synth = synth; + if ( offset != 0 ) + { + pt_synth = synth + L_frame / 2; + } + + *enr = dotp( pt_synth, pt_synth, L_frame / 2 ); + *enr /= (float) ( L_frame / 2 ); + } + return; +} + + void fer_energy_fx( const Word16 L_frame, /* i : frame length */ const Word16 clas, /* i : frame classification */ diff --git a/lib_com/get_gain.c b/lib_com/get_gain.c deleted file mode 100644 index 89b5fa3de..000000000 --- a/lib_com/get_gain.c +++ /dev/null @@ -1,170 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*----------------------------------------------------------------------------------* - * get_gain() - * - * - *----------------------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -/*! r: codebook gain (adaptive or fixed) */ -float get_gain_flt( - const float x[], /* i : target signal */ - const float y[], /* i : filtered codebook excitation */ - const int16_t n, /* i : segment length */ - float *en_y /* o : energy of y (sum of y[]^2, optional) */ -) -{ - float corr = 0.0f, ener = 1e-6f; - int16_t i; - - for ( i = 0; i < n; i++ ) - { - corr += x[i] * y[i]; - ener += y[i] * y[i]; - } - - if ( en_y ) - { - *en_y = ener; - } - - return ( corr / ener ); -} -#endif - -Word32 get_gain( /* output: codebook gain (adaptive or fixed) Q16 */ - const Word16 x[], /* input : target signal Qx */ - const Word16 y[], /* input : filtered codebook excitation Qx */ - const Word16 n /* input : segment length */ -) -{ - Word32 tcorr, tener, Lgain; - Word16 exp_c, exp_e, exp, tmp; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - - tcorr = L_deposit_l( 0 ); - tener = L_deposit_l( 0 ); - - - /*----------------------------------------------------------------* - * Find gain based on inter-correlation product - *----------------------------------------------------------------*/ - - tcorr = Dot_product16HQ( 0, x, y, n, &exp_c ); - tener = Dot_productSq16HQ( 0, y, n, &exp_e ); - - BASOP_Util_Divide_MantExp( round_fx_o( tcorr, &Overflow ), exp_c, s_max( round_fx_o( tener, &Overflow ), 1 ), exp_e, &tmp, &exp ); - Lgain = L_shl_o( L_deposit_l( tmp ) /*Q15*/, add( 1, exp ), &Overflow ) /*Q16*/; - - return Lgain; -} - -Word32 get_gain2( /* output: codebook gain (adaptive or fixed) Q16 */ - const Word16 x[], /* input : target signal */ - const Word16 y[], /* input : filtered codebook excitation */ - const Word16 n /* input : segment length */ -) -{ - Word32 tcorr, tener, Lgain; - Word16 m_corr, m_ener, negative, Q_corr, Q_ener; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - negative = 0; - move16(); - - /*----------------------------------------------------------------* - * Find gain based on inter-correlation product - *----------------------------------------------------------------*/ - tcorr = Dot_product16HQ( 0, x, y, n, &Q_corr ); - tener = Dot_productSq16HQ( 0, y, n, &Q_ener ); - - tener = L_max( tener, 1 ); - - if ( tcorr <= 0 ) - { - negative = 1; - move16(); - } - BASOP_SATURATE_WARNING_OFF_EVS /*tcorr max be negative maxvall - not critical*/ - tcorr = L_abs( tcorr ); - BASOP_SATURATE_WARNING_ON_EVS - - m_corr = extract_h( tcorr ); - - m_ener = extract_h( tener ); - - IF( GT_16( m_corr, m_ener ) ) - { - m_corr = shr( m_corr, 1 ); - Q_corr = add( Q_corr, 1 ); - } - if ( m_ener == 0 ) - { - move16(); - m_corr = 0x7FFF; - } - IF( m_ener != 0 ) - { - m_corr = div_s( m_corr, m_ener ); - } - - Q_corr = sub( Q_corr, Q_ener ); - - Lgain = L_shl_o( L_deposit_l( m_corr ), add( Q_corr, 1 ), &Overflow ); /* Lgain in Q16 */ - - if ( negative != 0 ) - { - Lgain = L_negate( Lgain ); /* Lgain in Q16 */ - } - - - return Lgain; -} diff --git a/lib_com/gs_preech.c b/lib_com/gs_preech.c deleted file mode 100644 index 58b49172d..000000000 --- a/lib_com/gs_preech.c +++ /dev/null @@ -1,381 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define ATT_LENGHT16k 80 -#ifndef IVAS_FLOAT_FIXED -#define INV_L_FRAME16k ( 1.0f / L_FRAME16k ) -#endif - -#define ATT_LENGHT 64 -#define ATT_SEG_LEN ( L_FRAME / ATT_LENGHT ) - -#ifndef IVAS_FLOAT_FIXED -#define INV_ATT_SEG_LEN ( 1.0f / ATT_SEG_LEN ) -#define INV_L_FRAME ( 1.0f / L_FRAME ) -#endif - -#ifndef IVAS_FLOAT_FIXED -/*-------------------------------------------------------------------* - * pre_echo_att() - * - * Attenuation of the pre-echo when encoder specifies an attack - *-------------------------------------------------------------------*/ - -void pre_echo_att( - float *Last_frame_ener, /* i/o: Energy of the last frame */ - float *exc, /* i/o: Excitation of the current frame */ - const int16_t attack_flag, /* i : attack flag (GSC or TC) */ - const int16_t last_coder_type, /* i : Last coder type */ - const int16_t L_frame /* i : frame length */ -) -{ - float etmp; - float etmp1; - float finc[ATT_LENGHT16k], ratio_float, inv_l_frame; - int16_t att_len; - int16_t attack_pos, i; - - if ( attack_flag > 0 && last_coder_type == AUDIO ) - { - /*-------------------------------------------------------------------------* - * Find where the onset (attack) occurs by computing the energy per section - * The inverse weighting aims to favor the first maxima in case of - * gradual onset - *-------------------------------------------------------------------------*/ - - att_len = ATT_LENGHT; - if ( L_frame == L_FRAME16k ) - { - att_len = ATT_LENGHT16k; - } - for ( i = 0; i < att_len; i++ ) - { - finc[i] = sum2_f( exc + i * ATT_SEG_LEN, ATT_SEG_LEN ) * ( (float) ( att_len - i ) / ( att_len ) ); - } - etmp = -1; - attack_pos = maximum( finc, att_len, &etmp ); - - /* Scaled the maximum energy and allowed 6 dB increase*/ - etmp *= INV_ATT_SEG_LEN; - etmp1 = etmp; - *Last_frame_ener *= 4.0f; - - /* If the maximum normalized energy > last frame energy + 6dB */ - if ( etmp > *Last_frame_ener && attack_pos > 0 ) - { - /* Find the average energy before the attack */ - etmp = sum_f( finc, attack_pos ) + 0.01f; - etmp /= ( attack_pos * ATT_SEG_LEN ); - - /* Find the correction factor and apply it before the attack */ - ratio_float = (float) sqrt( *Last_frame_ener / etmp ); - - - /* Pre-echo atttenuation should never increase the energy */ - ratio_float = min( ratio_float, 1.0f ); - for ( i = 0; i < attack_pos * ATT_SEG_LEN; i++ ) - { - exc[i] *= ratio_float; - } - } - *Last_frame_ener = etmp1; - } - else - { - /*-------------------------------------------------------* - * In normal cases, just compute the energy of the frame - *-------------------------------------------------------*/ - - etmp = sum2_f( exc, L_frame ) + 0.01f; - inv_l_frame = INV_L_FRAME; - if ( L_frame == L_FRAME16k ) - { - inv_l_frame = INV_L_FRAME16k; - } - etmp *= inv_l_frame; - *Last_frame_ener = etmp; - } - - return; -} -#endif - -void pre_echo_att_fx( - Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ - Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/ - const Word16 gsc_attack_flag_fx, /* i : flag signalling attack encoded by AC mode (GSC) Q0*/ - const Word16 Q_new, - const Word16 last_coder_type, /* i : Last coding mode Q0*/ - const Word16 L_frame /* i : Frame length Q0*/ -) -{ - Word32 etmp_fx; - Word32 finc_fx[ATT_LENGHT16k] = { 0 }; - move16(); - Word16 ratio_fx; - Word16 attack_pos_fx, i; - Word32 L_tmp, L_tmp1; - Word16 tmp, n1, n2, exp, frac1, frac2; - Word32 etmp1_fx; - Word16 att_len; - - test(); - IF( gsc_attack_flag_fx > 0 && EQ_16( last_coder_type, AUDIO ) ) /*gsc_attack_flag_fx does not get set for all the test cases */ - { - /*-------------------------------------------------------------------------* - * Find where the onset (attack) occurs by computing the energy per section - * The inverse weighting aims to favor the first maxima in case of - * gradual onset - *-------------------------------------------------------------------------*/ - att_len = ATT_LENGHT; /* Q0 */ - move16(); - if ( EQ_16( L_frame, L_FRAME16k ) ) - { - att_len = ATT_LENGHT16k; /* Q0 */ - move16(); - } - FOR( i = 0; i < att_len; i++ ) - { - L_tmp = sum2_fx( &exc_fx[i * 4], ATT_SEG_LEN ); /*2*Q_new+1, //ATT_SEG_LEN=(L_FRAME/ATT_LENGHT)=4(=shl(x,2))*/ - tmp = div_s( sub( att_len, i ), att_len ); /*Q15 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /*2*Q_new+1 */ - finc_fx[i] = L_tmp; - move32(); /*2*Q_new+1 */ - } - - attack_pos_fx = maximum_32_fx( finc_fx, att_len, &etmp_fx ); - - /* Scaled the maximum energy and allowed 6 dB increase*/ - etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ - etmp1_fx = etmp_fx; - move32(); - *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); - move32(); /*2*Q_new+1 */ - - /* If the maximum normalized energy > last frame energy + 6dB */ - test(); - IF( GT_32( etmp_fx, *Last_frame_ener_fx ) && attack_pos_fx > 0 ) - { - /* Find the average energy before the attack */ - L_tmp = sum32_fx( finc_fx, attack_pos_fx ); /*Q1 */ - L_tmp1 = L_shr( L_mult( attack_pos_fx, attack_pos_fx ), 1 ); /*Q0 */ - tmp = round_fx( Isqrt( L_tmp1 ) ); /*Q15 */ - L_tmp = L_shr( L_tmp, 2 ); /*Q1 ; ATT_SEG_LEN=4 */ - etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ - - etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ - /* Find the correction factor and apply it before the attack */ - /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ - /* = isqrt(etmp/(*Last_frame_ener)) */ - etmp_fx = L_max( etmp_fx, 1 ); - *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); - move32(); - n1 = norm_l( etmp_fx ); - n2 = norm_l( *Last_frame_ener_fx ); - - n1 = sub( n1, 1 ); - exp = sub( n1, n2 ); - - frac1 = round_fx( L_shl( etmp_fx, n1 ) ); - frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); - L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ - L_tmp = L_shr( L_tmp, exp ); /* add exponent */ - - L_tmp = Isqrt( L_tmp ); - ratio_fx = round_fx( L_shl( L_tmp, 9 ) ); /* Q13 */ - - /* Pre-echo atttenuation should never increase the energy */ - ratio_fx = s_min( ratio_fx, 8192 /* 1 in Q13 */ ); /* Q13 */ - FOR( i = 0; i < attack_pos_fx * ATT_SEG_LEN; i++ ) - { - /*exc_fx[i] *= ratio_fx;*/ - exc_fx[i] = round_fx( L_shl( L_mac( -8192, exc_fx[i], ratio_fx ), 2 ) ); - move16(); - } - } - *Last_frame_ener_fx = etmp1_fx; /*2*Q_new+1*/ - move32(); - } - ELSE - { - /*-------------------------------------------------------* - * In normal cases, just compute the energy of the frame - *-------------------------------------------------------*/ - - etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ -#ifdef ADD_LRTD - PMTE() - etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#else - etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#endif - *Last_frame_ener_fx = etmp_fx; - move32(); /*2*Q_new+1*/ - } - - return; -} - - -void pre_echo_att_ivas_fx( - Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ - Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/ - const Word16 gsc_attack_flag_fx, /* i : flag signalling attack encoded by AC mode (GSC) Q0*/ - const Word16 Q_new, - const Word16 last_coder_type, /* i : Last coding mode Q0*/ - const Word16 L_frame /* i : Frame length Q0*/ -) -{ - Word32 etmp_fx; - Word32 finc_fx[ATT_LENGHT16k] = { 0 }; - move16(); - Word16 ratio_fx; - Word16 attack_pos_fx, i; - Word32 L_tmp, L_tmp1; - Word16 tmp, n1, n2, exp, frac1, frac2; - Word32 etmp1_fx; - Word16 att_len; - - test(); - IF( gsc_attack_flag_fx > 0 && EQ_16( last_coder_type, AUDIO ) ) /*gsc_attack_flag_fx does not get set for all the test cases */ - { - /*-------------------------------------------------------------------------* - * Find where the onset (attack) occurs by computing the energy per section - * The inverse weighting aims to favor the first maxima in case of - * gradual onset - *-------------------------------------------------------------------------*/ - att_len = ATT_LENGHT; /* Q0 */ - move16(); - if ( EQ_16( L_frame, L_FRAME16k ) ) - { - att_len = ATT_LENGHT16k; /* Q0 */ - move16(); - } - FOR( i = 0; i < att_len; i++ ) - { - L_tmp = sum2_fx( &exc_fx[i * 4], ATT_SEG_LEN ); /*2*Q_new+1, //ATT_SEG_LEN=(L_FRAME/ATT_LENGHT)=4(=shl(x,2))*/ - tmp = div_s( sub( att_len, i ), att_len ); /*Q15 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /*2*Q_new+1 */ - finc_fx[i] = L_tmp; - move32(); /*2*Q_new+1 */ - } - - attack_pos_fx = maximum_32_fx( finc_fx, att_len, &etmp_fx ); - - /* Scaled the maximum energy and allowed 6 dB increase*/ - etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ - etmp1_fx = etmp_fx; - move32(); - *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); - move32(); /*2*Q_new+1 */ - - /* If the maximum normalized energy > last frame energy + 6dB */ - test(); - IF( GT_32( etmp_fx, *Last_frame_ener_fx ) && attack_pos_fx > 0 ) - { - /* Find the average energy before the attack */ - L_tmp = sum32_fx( finc_fx, attack_pos_fx ); /*Q1 */ - L_tmp1 = L_shr( L_mult( attack_pos_fx, attack_pos_fx ), 1 ); /*Q0 */ - tmp = round_fx( Isqrt( L_tmp1 ) ); /*Q15 */ - L_tmp = L_shr( L_tmp, 2 ); /*Q1 ; ATT_SEG_LEN=4 */ - etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ - - etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ - /* Find the correction factor and apply it before the attack */ - /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ - /* = isqrt(etmp/(*Last_frame_ener)) */ - etmp_fx = L_max( etmp_fx, 1 ); - *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); - move32(); - n1 = norm_l( etmp_fx ); - n2 = norm_l( *Last_frame_ener_fx ); - - n1 = sub( n1, 1 ); - exp = sub( n1, n2 ); - - frac1 = round_fx( L_shl( etmp_fx, n1 ) ); - frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); - L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ - L_tmp = L_shr( L_tmp, exp ); /* add exponent */ - - L_tmp = Isqrt( L_tmp ); - ratio_fx = round_fx( L_shl( L_tmp, 9 ) ); - - /* Pre-echo atttenuation should never increase the energy */ - ratio_fx = s_min( ratio_fx, 8192 /* 1 in Q13 */ ); /* Q13 */ - FOR( i = 0; i < attack_pos_fx * ATT_SEG_LEN; i++ ) - { - /*exc_fx[i] *= ratio_fx;*/ - exc_fx[i] = round_fx( L_shl( L_mac( -8192, exc_fx[i], ratio_fx ), 2 ) ); - move16(); - } - } - *Last_frame_ener_fx = etmp1_fx; /* 2 * Q_new + 1 */ - move32(); - } - ELSE - { - /*-------------------------------------------------------* - * In normal cases, just compute the energy of the frame - *-------------------------------------------------------*/ - Word16 exp_etmp = sub( 15, Q_new ); - etmp_fx = sum2_16_exp_fx( exc_fx, L_frame, &exp_etmp, 7 ); /* Q = 31-exp_etmp */ - - etmp_fx = L_shr( etmp_fx, 8 ); /*31-exp_etmp//INV_L_FRAME = 1/256*/ - - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - etmp_fx = Mpy_32_16_1( etmp_fx, 26214 /* 0.8 in Q15 */ ); /*31 - exp_etmp*/ - } - *Last_frame_ener_fx = L_shl( etmp_fx, sub( shl( Q_new, 1 ), sub( 30 /*31-1*/, exp_etmp ) ) ); /*2*Q_new+1*/ - move32(); /*2*Q_new+1*/ - } - - return; -} diff --git a/lib_com/hp50.c b/lib_com/hp50.c deleted file mode 100644 index 6920063d4..000000000 --- a/lib_com/hp50.c +++ /dev/null @@ -1,728 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/* - * hp20 - * - * Function: - * 2nd order high pass filter with nominal cut off frequency at 20 Hz. - * - * Returns: - * void - */ - -#ifndef IVAS_FLOAT_FIXED -void hp20_flt( - Float32 signal[], - const Word16 lg, - Float32 mem[], - const Word32 Fs ) -{ - Word16 i; - Float32 x0, x1, x2, y0, y1, y2; - Float32 a1, a2, b1, b2; - - y1 = mem[0]; - y2 = mem[1]; - x0 = mem[2]; - x1 = mem[3]; - - if ( Fs == 8000 ) - { - /* hp filter 20Hz at 3dB for 8000KHz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a =[1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1 = 1.977786483776764f; - a2 = -0.978030508491796f; - b1 = -1.977908496134280f; - b2 = 0.988954248067140f; - } - else if ( Fs == 16000 ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b =[ 0.994461788958195 -1.988923577916390 0.994461788958195] - a =[1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1 = 1.988892905899653f; - a2 = -0.988954249933127f; - b1 = -1.988923577916390f; - b2 = 0.994461788958195f; - } - else if ( Fs == 32000 ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b =[0.997227049904470 -1.994454099808940 0.997227049904470] - a =[1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1 = 1.994446410541927f; - a2 = -0.994461789075954f; - b1 = -1.994454099808940f; - b2 = 0.997227049904470f; - } - else - { - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[ 0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1 = 1.996297601769122f; - a2 = -0.996304442992686f; - b1 = -1.996301022380904f; - b2 = 0.998150511190452f; - } - - for ( i = 0; i < lg; i++ ) - { - x2 = x1; - x1 = x0; - x0 = signal[i]; - y0 = ( y1 * a1 ) + ( y2 * a2 ) + ( x0 * b2 ) + ( x1 * b1 ) + ( x2 * b2 ); - signal[i] = y0; - y2 = y1; - y1 = y0; - } - - mem[0] = ( ( y1 > 1e-10 ) | ( y1 < -1e-10 ) ) ? y1 : 0; - mem[1] = ( ( y2 > 1e-10 ) | ( y2 < -1e-10 ) ) ? y2 : 0; - mem[2] = ( ( x0 > 1e-10 ) | ( x0 < -1e-10 ) ) ? x0 : 0; - mem[3] = ( ( x1 > 1e-10 ) | ( x1 < -1e-10 ) ) ? x1 : 0; - - return; -} -#endif - - -#define HP20_COEFF_SCALE ( 2 ) -/* - * hp20 - * - * Function: - * 2nd order high pass filter with nominal cut off frequency at 20 Hz. - * - * Returns: - * void - */ - -static Word32 HP50_Mode2_Mpy_32_16_fix( Word32 a, Word16 b ) -{ - Word32 result = Mpy_32_16_1( a, b ); - /* perform rounding towards lower value for negative results */ - if ( result < 0 ) - result = L_add( result, 1 ); - return result; -} - -static Word32 HP50_Mpy_32_32_fix( Word32 a, Word32 b ) -{ - Word32 result = Mpy_32_32( a, b ); - /* perform rounding towards lower value for negative results */ - if ( result < 0 ) - result = L_add( result, 1 ); - return result; -} - - -static void filter_2nd_order( - Word16 signal[], - const Word16 stride, - const Word16 prescale, - const Word16 lg, - Word32 mem[4], - Word32 a1, - Word32 a2, - Word32 b1, - Word32 b2 ) -{ - - Word16 i; - Word16 x2, x1; - Word32 L_sum, L_y1, L_y2; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - - /* - * Saturation: The states of the filter, namely L_y1 and L_y2 shall - * never saturate, because that causes error in the filter feedback. - * The final output written into signal[] might saturate because of - * unavoidable filter overshoot. - */ - - /* Execute first 2 iterations with 32-bit x anx y memory values */ - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mpy_32_32_fix( b2, mem[2] ); /* b2*x2 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( b1, mem[3] ) ); /* b1*x1 */ - x2 = shr( signal[0], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) ); /* b2*x0 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[0], a2 ) ); /* y2*a2 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a1 ) ); /* y1*a1 */ - - L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS - signal[0] = round_fx_o( L_shl_o( L_y2, prescale, &Overflow ), &Overflow ); - BASOP_SATURATE_WARNING_ON_EVS - - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mpy_32_32_fix( b2, mem[3] ); /* b2*x2 */ - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) ); /* b1*x1 */ - x1 = shr( signal[stride], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) ); /* b2*x0 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a2 ) ); /* y2*a2 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) ); /* y1*a1 */ - - L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS - signal[stride] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow ); - BASOP_SATURATE_WARNING_ON_EVS - move16(); - - /* New we use a trick and toggle x1/x2 and L_y1/L_y2 to save a few cycles unrolling the loop by 2 */ - FOR( i = 2; i < lg; i += 2 ) - { - /* y[i+0] = b2*x[i-2] + b1*x[i-1] + b2*x[i-0] + a2*y[i-2] + a1*y[i-1]; */ - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x2 ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x1 ) ); - x2 = shr( signal[i * stride], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a2 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a1 ) ); - - L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS - signal[i_mult( i, stride )] = round_fx_o( L_shl_o( L_y2, prescale, &Overflow ), &Overflow ); - BASOP_SATURATE_WARNING_ON_EVS - /* y[i+1] = b2*x[i-1] + b1*x[i-0] + b2*x[i+1] + a2*y[i-1] + a1*y[i+0]; */ - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x1 ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) ); - x1 = shr( signal[( i + 1 ) * stride], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a2 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) ); - - L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS - signal[i_mult( add( i, 1 ), stride )] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow ); - BASOP_SATURATE_WARNING_ON_EVS - move16(); - } - /* update static filter memory from variables */ - mem[0] = L_y2; - move32(); - mem[1] = L_y1; - move32(); - mem[2] = L_deposit_h( x2 ); - move32(); - mem[3] = L_deposit_h( x1 ); - move32(); - - - return; -} - - -void hp20( Word16 signal[], /* i/o: signal to filter any */ - const Word16 stride, /* i : stride to be applied accessing signal */ - const Word16 lg, /* i : length of signal (integer) Q0 */ - Word32 mem[5], /* i/o: static filter memory with this layout: */ - /* mem[0]: y[-2] (32-bit) */ - /* mem[1]; y[-1] (32-bit) */ - /* mem[2]: x[-2] << 16 */ - /* mem[3]: x[-1] << 16 */ - /* Note: mem[0..3] need to be scaled per frame */ - /* mem[4]: states scale */ - const Word32 sFreq ) /* i : input sampling rate Q0 */ -{ - Word32 a1, b1, a2, b2; - Word16 prescale, prescaleOld, diff; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - - prescale = getScaleFactor16( signal, lg ); - prescaleOld = extract_l( mem[4] ); - diff = norm_l( L_shl_sat( mem[2], prescaleOld ) ); - if ( mem[2] != 0 ) - { - prescale = s_min( prescale, diff ); - } - diff = norm_l( L_shl_o( mem[3], prescaleOld, &Overflow ) ); - if ( mem[3] != 0 ) - { - prescale = s_min( prescale, diff ); - } - /* Take into account the left shift performed into the loop + 1 bit headroom*/ - prescale = s_max( -12, sub( 1 + HP20_COEFF_SCALE, prescale ) ); - IF( prescale != prescaleOld ) - { - diff = sub( prescale, prescaleOld ); - mem[0] = L_shr_o( mem[0], diff, &Overflow ); - move32(); - mem[1] = L_shr_o( mem[1], diff, &Overflow ); - move32(); - mem[2] = L_shr_o( mem[2], diff, &Overflow ); - move32(); - mem[3] = L_shr_o( mem[3], diff, &Overflow ); - move32(); - mem[4] = L_deposit_l( prescale ); - } - - IF( EQ_32( sFreq, 8000 ) ) - { - /* hp filter 20Hz at 3dB for 8000 Hz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a = [1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1 = 1061816033l /* 1.977786483776764 Q29*/; - move32(); - a2 = -525076131l /*-0.978030508491796 Q29*/; - move32(); - b1 = -1061881538l /*-1.977908496134280 Q29*/; - move32(); - b2 = 530940769l /* 0.988954248067140 Q29*/; - move32(); - } - ELSE IF( EQ_32( sFreq, 16000 ) ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b = [0.994461788958195 -1.988923577916390 0.994461788958195] - a = [1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1 = 1067778748l /* 1.988892905899653 Q29*/; - move32(); - a2 = -530940770l /*-0.988954249933127 Q29*/; - move32(); - b1 = -1067795215l /*-1.988923577916390 Q29*/; - move32(); - b2 = 533897608l /* 0.994461788958195 Q29*/; - move32(); - } - ELSE IF( EQ_32( sFreq, 32000 ) ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b = [0.997227049904470 -1.994454099808940 0.997227049904470] - a = [1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1 = 1070760263l /* 1.994446410541927 Q29*/; - move32(); - a2 = -533897608l /*-0.994461789075954 Q29*/; - move32(); - b1 = -1070764392l /*-1.994454099808940 Q29*/; - move32(); - b2 = 535382196l /* 0.997227049904470 Q29*/; - move32(); - } - ELSE - { - assert( sFreq == 48000 ); - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1 = 1071754114l /* 1.996297601769122 Q29*/; - move32(); - a2 = -534886875l /*-0.996304442992686 Q29*/; - move32(); - b1 = -1071755951l /*-1.996301022380904 Q29*/; - move32(); - b2 = 535877975l /* 0.998150511190452 Q29*/; - move32(); - } - - - filter_2nd_order( signal, stride, prescale, lg, - mem, a1, a2, b1, b2 ); - - return; -} - - -#ifdef HP20_FIX32_RECODING -void hp20_fx_32( - Word32 signal_fx[], - const Word16 lg, - Word32 mem_fx[], - const Word32 Fs ) -{ - Word32 i; - Word32 a1_fx, a2_fx, b1_fx, b2_fx; - Word32 diff_pos, diff_neg; - Flag Overflow = 0; - Word16 prescale, prescaleOld, prescale_current_frame, diff; - - prescale = getScaleFactor32( signal_fx, lg ); - prescale_current_frame = s_min( 3, sub( 1 + HP20_COEFF_SCALE, prescale ) ); - - - prescaleOld = extract_l( mem_fx[4] ); - - diff_pos = norm_l( L_shl_o( L_max( mem_fx[2], mem_fx[3] ), prescaleOld, &Overflow ) ); - diff_neg = norm_l( L_shl_o( L_min( mem_fx[2], mem_fx[3] ), prescaleOld, &Overflow ) ); - - diff = L_max( diff_pos, diff_neg ); - - IF( NE_16( diff, 0 ) ) - { - prescale = s_min( prescale, diff ); - } - - prescale = s_min( 3, sub( 1 + HP20_COEFF_SCALE, prescale ) ); - - diff = sub( prescale, prescaleOld ); - mem_fx[0] = L_shr_o( mem_fx[0], diff, &Overflow ); - move32(); - mem_fx[1] = L_shr_o( mem_fx[1], diff, &Overflow ); - move32(); - mem_fx[2] = L_shr_o( mem_fx[2], diff, &Overflow ); - move32(); - mem_fx[3] = L_shr_o( mem_fx[3], diff, &Overflow ); - move32(); - mem_fx[4] = L_deposit_l( prescale_current_frame ); - move32(); - - IF( EQ_32( Fs, 8000 ) ) - { - /* hp filter 20Hz at 3dB for 8000KHz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a =[1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1_fx = 1061816033l /* 1.977786483776764 Q29*/; - a2_fx = -525076131l /*-0.978030508491796 Q29*/; - b1_fx = -1061881538l /*-1.977908496134280 Q29*/; - b2_fx = 530940769l /* 0.988954248067140 Q29*/; - } - ELSE IF( EQ_32( Fs, 16000 ) ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b =[ 0.994461788958195 -1.988923577916390 0.994461788958195] - a =[1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1_fx = 1067778748l /* 1.988892905899653 Q29*/; - a2_fx = -530940770l /*-0.988954249933127 Q29*/; - b1_fx = -1067795215l /*-1.988923577916390 Q29*/; - b2_fx = 533897608l /* 0.994461788958195 Q29*/; - } - ELSE IF( EQ_32( Fs, 32000 ) ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b =[0.997227049904470 -1.994454099808940 0.997227049904470] - a =[1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1_fx = 1070760263l /* 1.994446410541927 Q29*/; - a2_fx = -533897608l /*-0.994461789075954 Q29*/; - b1_fx = -1070764392l /*-1.994454099808940 Q29*/; - b2_fx = 535382196l /* 0.997227049904470 Q29*/; - } - ELSE - { - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[ 0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1_fx = 1071754114l /* 1.996297601769122 Q29*/; - a2_fx = -534886875l /*-0.996304442992686 Q29*/; - b1_fx = -1071755951l /*-1.996301022380904 Q29*/; - b2_fx = 535877975l /* 0.998150511190452 Q29*/; - } - move32(); - move32(); - move32(); - move32(); - Word64 W_sum, W_y0, W_y1, W_y2; - Word32 x0, x1, x2; - - W_sum = W_mult_32_32( b2_fx, mem_fx[2] ); /* b2*x2 */ - W_sum = W_mac_32_32( W_sum, b1_fx, mem_fx[3] ); /* b1*x1 */ - x2 = L_shr( signal_fx[0], prescale ); - W_sum = W_mac_32_32( W_sum, b2_fx, x2 ); /* b2*x0 */ - W_sum = W_mac_32_32( W_sum, mem_fx[0], a2_fx ); /* y2*a2 */ - W_sum = W_mac_32_32( W_sum, mem_fx[1], a1_fx ); /* y1*a1 */ - W_y2 = W_shl( W_sum, HP20_COEFF_SCALE ); - signal_fx[0] = W_extract_h( W_shl( W_y2, prescale ) ); - move32(); - - W_sum = W_mult_32_32( b2_fx, mem_fx[3] ); /* b2*x2 */ - W_sum = W_mac_32_32( W_sum, b1_fx, x2 ); /* b1*x1 */ - x1 = L_shr( signal_fx[1], prescale ); - W_sum = W_mac_32_32( W_sum, b2_fx, x1 ); /* b2*x0 */ - W_sum = W_mac_32_32( W_sum, mem_fx[1], a2_fx ); /* y2*a2 */ - W_sum = W_mac_32_32( W_sum, W_extract_h( W_y2 ), a1_fx ); /* y1*a1 */ - W_y1 = W_shl( W_sum, HP20_COEFF_SCALE ); - signal_fx[1] = W_extract_h( W_shl( W_y1, prescale ) ); - move32(); - - diff = sub( prescale_current_frame, prescale ); - W_y1 = W_shr( W_y1, diff ); - W_y2 = W_shr( W_y2, diff ); - x2 = L_shr( x2, diff ); - x1 = L_shr( x1, diff ); - - FOR( i = 2; i < lg; i++ ) - { - W_sum = W_mult_32_32( b2_fx, x2 ); /* b2*x2 */ - W_sum = W_mac_32_32( W_sum, b1_fx, x1 ); /* b1*x1 */ - x0 = L_shr( signal_fx[i], prescale_current_frame ); - W_sum = W_mac_32_32( W_sum, b2_fx, x0 ); /* b2*x0 */ - W_sum = W_mac_32_32( W_sum, W_extract_h( W_y2 ), a2_fx ); /* y2*a2 */ - W_sum = W_mac_32_32( W_sum, W_extract_h( W_y1 ), a1_fx ); /* y1*a1 */ - W_y0 = W_shl( W_sum, HP20_COEFF_SCALE ); - - signal_fx[i] = W_extract_h( W_shl( W_y0, prescale_current_frame ) ); - move32(); - - x2 = x1; - x1 = x0; - W_y2 = W_y1; - W_y1 = W_y0; - - move32(); - move32(); - move64(); - move64(); - } - - mem_fx[0] = W_extract_h( W_y2 ); - mem_fx[1] = W_extract_h( W_y1 ); - mem_fx[2] = x2; - mem_fx[3] = x1; - - move32(); - move32(); - move32(); - move32(); - - return; -} -#else -void hp20_fx_32( - Word32 signal_fx[], - const Word16 lg, - Word32 mem_fx[], - const Word32 Fs ) -{ - Word16 i; - Word32 a1_fx, a2_fx, b1_fx, b2_fx; - Word16 Qx0, Qx1, Qx2, Qy1, Qprev_y1, Qy2, Qprev_y2, Qmin; - Word64 x0_fx64, x1_fx64, x2_fx64, y0_fx64, y1_fx64, y2_fx64, R1, R2, R3, R4, R5; - - IF( EQ_32( Fs, 8000 ) ) - { - /* hp filter 20Hz at 3dB for 8000KHz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a =[1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1_fx = 1061816033l /* 1.977786483776764 Q29*/; - a2_fx = -525076131l /*-0.978030508491796 Q29*/; - b1_fx = -1061881538l /*-1.977908496134280 Q29*/; - b2_fx = 530940769l /* 0.988954248067140 Q29*/; - } - ELSE IF( EQ_32( Fs, 16000 ) ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b =[ 0.994461788958195 -1.988923577916390 0.994461788958195] - a =[1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1_fx = 1067778748l /* 1.988892905899653 Q29*/; - a2_fx = -530940770l /*-0.988954249933127 Q29*/; - b1_fx = -1067795215l /*-1.988923577916390 Q29*/; - b2_fx = 533897608l /* 0.994461788958195 Q29*/; - } - ELSE IF( EQ_32( Fs, 32000 ) ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b =[0.997227049904470 -1.994454099808940 0.997227049904470] - a =[1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1_fx = 1070760263l /* 1.994446410541927 Q29*/; - a2_fx = -533897608l /*-0.994461789075954 Q29*/; - b1_fx = -1070764392l /*-1.994454099808940 Q29*/; - b2_fx = 535382196l /* 0.997227049904470 Q29*/; - } - ELSE - { - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[ 0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1_fx = 1071754114l /* 1.996297601769122 Q29*/; - a2_fx = -534886875l /*-0.996304442992686 Q29*/; - b1_fx = -1071755951l /*-1.996301022380904 Q29*/; - b2_fx = 535877975l /* 0.998150511190452 Q29*/; - } - move32(); - move32(); - move32(); - move32(); - - Qprev_y1 = extract_l( mem_fx[4] ); - Qprev_y2 = extract_l( mem_fx[5] ); - y1_fx64 = W_deposit32_l( mem_fx[0] ); - y2_fx64 = W_deposit32_l( mem_fx[1] ); - x0_fx64 = W_deposit32_l( mem_fx[2] ); - x1_fx64 = W_deposit32_l( mem_fx[3] ); - - FOR( i = 0; i < lg; i++ ) - { - x2_fx64 = x1_fx64; - move64(); - x1_fx64 = x0_fx64; - move64(); - x0_fx64 = W_deposit32_l( signal_fx[i] ); - - Qy1 = W_norm( y1_fx64 ); - if ( y1_fx64 == 0 ) - { - Qy1 = 62; - move16(); - } - Qy1 = sub( Qy1, 34 ); - R1 = W_mult0_32_32( W_extract_l( W_shl( y1_fx64, Qy1 ) ), a1_fx ); - Qy1 = add( Qy1, Qprev_y1 ); - - Qy2 = W_norm( y2_fx64 ); - if ( y2_fx64 == 0 ) - { - Qy2 = 62; - move16(); - } - Qy2 = sub( Qy2, 34 ); - R2 = W_mult0_32_32( W_extract_l( W_shl( y2_fx64, Qy2 ) ), a2_fx ); - Qy2 = add( Qy2, Qprev_y2 ); - - Qx0 = W_norm( x0_fx64 ); - if ( x0_fx64 == 0 ) - { - Qx0 = 62; - move16(); - } - Qx0 = sub( Qx0, 34 ); - R3 = W_mult0_32_32( W_extract_l( W_shl( x0_fx64, Qx0 ) ), b2_fx ); - - Qx1 = W_norm( x1_fx64 ); - if ( x1_fx64 == 0 ) - { - Qx1 = 62; - move16(); - } - Qx1 = sub( Qx1, 34 ); - R4 = W_mult0_32_32( W_extract_l( W_shl( x1_fx64, Qx1 ) ), b1_fx ); - - Qx2 = W_norm( x2_fx64 ); - if ( x2_fx64 == 0 ) - { - Qx2 = 62; - move16(); - } - Qx2 = sub( Qx2, 34 ); - R5 = W_mult0_32_32( W_extract_l( W_shl( x2_fx64, Qx2 ) ), b2_fx ); - - Qmin = s_min( Qy1, Qy2 ); - - y0_fx64 = W_add( W_shr( R1, sub( Qy1, Qmin ) ), W_shr( R2, sub( Qy2, Qmin ) ) ); - - Qmin = s_min( Qmin, Qx0 ); - Qmin = s_min( Qmin, Qx1 ); - Qmin = s_min( Qmin, Qx2 ); - - y0_fx64 = W_add( W_shr( y0_fx64, sub( s_min( Qy1, Qy2 ), Qmin ) ), W_add( W_shr( R3, sub( Qx0, Qmin ) ), W_add( W_shr( R4, sub( Qx1, Qmin ) ), W_shr( R5, sub( Qx2, Qmin ) ) ) ) ); - - y0_fx64 = W_shr( y0_fx64, 29 ); - - signal_fx[i] = W_extract_l( W_shr( y0_fx64, Qmin ) ); - move32(); - IF( signal_fx[i] < 0 ) - { - signal_fx[i] = L_add( signal_fx[i], 1 ); - move32(); - } - - y2_fx64 = y1_fx64; - y1_fx64 = y0_fx64; - Qprev_y2 = Qprev_y1; - Qprev_y1 = Qmin; - move64(); - move64(); - move16(); - move16(); - } - - Qy1 = W_norm( y1_fx64 ); - test(); - IF( y1_fx64 != 0 && LT_16( Qy1, 32 ) ) - { - y1_fx64 = W_shr( y1_fx64, sub( 32, Qy1 ) ); - Qprev_y1 = sub( Qprev_y1, sub( 32, Qy1 ) ); - } - - Qy2 = W_norm( y2_fx64 ); - test(); - IF( y2_fx64 != 0 && LT_16( Qy2, 32 ) ) - { - y2_fx64 = W_shr( y2_fx64, sub( 32, Qy2 ) ); - Qprev_y2 = sub( Qprev_y2, sub( 32, Qy2 ) ); - } - - mem_fx[0] = W_extract_l( y1_fx64 ); - mem_fx[1] = W_extract_l( y2_fx64 ); - mem_fx[2] = W_extract_l( x0_fx64 ); - mem_fx[3] = W_extract_l( x1_fx64 ); - mem_fx[4] = Qprev_y1; - mem_fx[5] = Qprev_y2; - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - - return; -} -#endif diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index d13835f4c..9820eb3c8 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -41,16 +41,6 @@ #include "wmc_auto.h" #include "prot_fx.h" -/* - * hp20 - * - * Function: - * 2nd order high pass filter with nominal cut off frequency at 20 Hz. - * - * Returns: - * void - */ - #define HP20_COEFF_SCALE ( 2 ) /* -- GitLab From 3c9da4c86cffb43fc64077c1d6d646ce95422191 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 5 Mar 2025 14:25:39 +0100 Subject: [PATCH 0321/1221] clang format. --- lib_rend/ivas_dirac_rend_fx.c | 7 ++++--- lib_rend/lib_rend.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 7f4076266..f5e050db1 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2833,9 +2833,9 @@ void protoSignalComputation4_fx( FOR( k = 0; k < s_max( 4, nchan_transport ); k++ ) { #ifdef FIX_867_CLDFB_NRG_SCALE - q_shift = L_norm_arr( RealBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands) ); + q_shift = L_norm_arr( RealBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ); min_q_shift = s_min( q_shift, min_q_shift ); - q_shift = L_norm_arr( ImagBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands) ); + q_shift = L_norm_arr( ImagBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ); min_q_shift = s_min( q_shift, min_q_shift ); q_shift2 = L_norm_arr( RealBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); min_q_shift2 = s_min( q_shift2, min_q_shift2 ); @@ -2991,7 +2991,8 @@ void protoSignalComputation4_fx( #ifdef FIX_867_CLDFB_NRG_SCALE proto_power_smooth_q[0] = proto_power_smooth_fx_q; proto_power_smooth_q[1] = proto_power_smooth_fx_q; - move16(); move16(); + move16(); + move16(); #else *proto_power_smooth_q = proto_power_smooth_fx_q; move16(); diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 4f430ff01..f33bc8997 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8460,11 +8460,11 @@ static void intermidiate_ext_dirac_render( move16(); FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { - tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) ) ); + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); } FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF) , tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); move16(); -- GitLab From d46773e421e8e5ef085eefa98fcf63cbaa9e7c76 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 14:26:18 +0100 Subject: [PATCH 0322/1221] remove unused function --- lib_com/frame_ener_fx.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/lib_com/frame_ener_fx.c b/lib_com/frame_ener_fx.c index 7ee58371a..4428c0796 100644 --- a/lib_com/frame_ener_fx.c +++ b/lib_com/frame_ener_fx.c @@ -47,45 +47,6 @@ * Estimation of pitch-synchronous (voiced sounds) or half-frame energy *----------------------------------------------------------------------------------*/ -void fer_energy( - const int16_t L_frame, /* i : frame length */ - const int16_t clas, /* i : frame classification */ - const float *synth, /* i : synthesized speech at Fs = 12k8 Hz */ - const float pitch, /* i : pitch period */ - float *enr, /* o : pitch-synchronous or half_frame energy */ - const int16_t offset /* i : speech pointer offset (0 or L_frame) */ -) -{ - int16_t len; - const float *pt_synth; - - if ( clas == VOICED_CLAS || clas == ONSET || clas == SIN_ONSET ) /* Voiced or Onset current frame */ - { - len = (int16_t) ( pitch + 0.5f ); /* pitch value */ - - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + L_frame - len; - } - - emaximum( pt_synth, len, enr ); /* pitch synchronous E */ - } - else - { - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + L_frame / 2; - } - - *enr = dotp( pt_synth, pt_synth, L_frame / 2 ); - *enr /= (float) ( L_frame / 2 ); - } - return; -} - - void fer_energy_fx( const Word16 L_frame, /* i : frame length */ const Word16 clas, /* i : frame classification */ -- GitLab From 54426a49982dbc40bdac0a07ee514d7c711fbd5a Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 14:34:47 +0100 Subject: [PATCH 0323/1221] fix build-codec-linux-debugging-make --- lib_rend/lib_rend.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 698c652e5..493979e30 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -45,6 +45,9 @@ #include #include #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-------------------------------------------------------------------* -- GitLab From 1afe839586e76766c822080214a21ec9cd7c1d51 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 16:02:36 +0100 Subject: [PATCH 0324/1221] remove ADD_IVAS_BWE --- lib_com/prot_fx.h | 35 ++++--------- lib_dec/decision_matrix_dec_fx.c | 4 +- lib_dec/evs_dec_fx.c | 20 +------- lib_dec/init_dec_fx.c | 6 +-- lib_dec/swb_bwe_dec_fx.c | 84 +++++--------------------------- lib_dec/swb_tbe_dec_fx.c | 5 +- lib_enc/cng_enc_fx.c | 7 +-- 7 files changed, 32 insertions(+), 129 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 0371f747a..51fbb12d5 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6057,10 +6057,7 @@ void TBEreset_dec_fx( void td_bwe_dec_init_fx( Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ -#ifdef ADD_IVAS_BWE - const Word16 extl, /* i : BWE extension layer */ -#endif - const Word32 output_Fs /* i : output sampling rate */ + const Word32 output_Fs /* i : output sampling rate */ ); // lsf_dec_fx.c @@ -7700,19 +7697,12 @@ Word16 WB_BWE_gain_deq_fx( ); Word16 wb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ const Word16 output_frame, /* i : frame length */ Word16 *voice_factors_fx, /* i : voicing factors Q15 */ const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ - Decoder_State *st_fx /* i/o: decoder state structure */ - , + Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 *Qpost ); Word16 swb_bwe_gain_deq_fx( /* o : BWE class */ @@ -7724,18 +7714,11 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class const Word16 hqswb_clas /* i : HQ BWE class */ ); -Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif - const Word16 output_frame /* i : frame length */ - , +Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 output_frame, /* i : frame length */ Word16 *Qpost ); void fd_bwe_dec_init( diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index a83de038a..f9833e80a 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -681,12 +681,12 @@ void decision_matrix_dec_fx( st->nb_subfr = NB_SUBFR16k; move16(); } -#if 1 // def ADD_IVAS_BWE 0> NEEDED for IO with conf_acelp1 + st->extl_orig = st->extl; move16(); st->extl_brate_orig = st->extl_brate; move32(); -#endif + test(); IF( EQ_32( st->output_Fs, 8000 ) ) { diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index a5a5ba6d9..aa997d4c0 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -383,15 +383,7 @@ ivas_error evs_dec_fx( ELSE IF( EQ_16( st_fx->extl, WB_BWE ) && st_fx->bws_cnt == 0 ) { /* WB BWE decoder */ - hb_synth_fx_exp = wb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - NULL, -#endif - synth_fx, hb_synth_fx, -#ifdef ADD_IVAS_BWE - 0, -#endif - output_frame, voice_factors_fx, pitch_buf_fx, st_fx, &Qpostd ); /*Q0*/ + hb_synth_fx_exp = wb_bwe_dec_fx( synth_fx, hb_synth_fx, output_frame, voice_factors_fx, pitch_buf_fx, st_fx, &Qpostd ); /*Q0*/ } /*---------------------------------------------------------------------* @@ -434,15 +426,7 @@ ivas_error evs_dec_fx( ( GE_32( st_fx->output_Fs, 32000 ) && EQ_16( st_fx->core, ACELP_CORE ) && GT_16( st_fx->bwidth, NB ) && st_fx->bws_cnt > 0 && !st_fx->ppp_mode_dec && !( EQ_16( st_fx->nelp_mode_dec, 1 ) && EQ_16( st_fx->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ - hb_synth_fx_exp = swb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - NULL, -#endif - st_fx, synth_fx, hb_synth_fx, -#ifdef ADD_IVAS_BWE - 0, -#endif - output_frame, &Qpostd ); /*Q0*/ + hb_synth_fx_exp = swb_bwe_dec_fx( st_fx, synth_fx, hb_synth_fx, output_frame, &Qpostd ); /*Q0*/ } ELSE IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || EQ_16( st_fx->extl, FB_BWE_HIGHRATE ) ) { diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 5d8aee302..4f1db90ff 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -532,11 +532,7 @@ ivas_error init_decoder_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, -#ifdef ADD_IVAS_BWE - st_fx->extl, -#endif - st_fx->output_Fs ); + td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, st_fx->output_Fs ); #ifdef MSAN_FIX st_fx->hBWE_TD->prev_hb_synth_fx_exp = 31; diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index d15a97821..b91dcdf32 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -505,19 +505,12 @@ Word16 ivas_wb_bwe_dec_fx( /* o : } Word16 wb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ const Word16 output_frame, /* i : frame length */ Word16 *voice_factors_fx, /* i : voicing factors Q15 */ const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ - Decoder_State *st_fx /* i/o: decoder state structure */ - , + Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 *Qpost ) { Word16 mode; @@ -538,18 +531,7 @@ Word16 wb_bwe_dec_fx( new_input_fx_exp = *Qpost; move16(); -#ifdef ADD_IVAS_BWE - if ( st->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft ) - { - /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* IVAS_fmToDo: delay output[] by 1.25ms ? */ - lerp( output, ysynth, L_FRAME16k, st->L_frame ); - wtda( ysynth, wtda_synth, hBWE_FD->old_wtda_swb, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k ); - direct_transform( wtda_synth, ysynth, 0, /*st->L_frame*/ L_FRAME16k, st->element_mode ); - } - else -#endif { wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ @@ -574,11 +556,7 @@ Word16 wb_bwe_dec_fx( Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); IF( !st_fx->bfi ) { -#ifdef ADD_IVAS_BWE - IF( st_fx->extl_brate > 0 ) -#else IF( EQ_32( st_fx->total_brate, ACELP_13k20 ) ) -#endif { /* de-quantization */ mode = WB_BWE_gain_deq_fx( st_fx, WB_fenv_fx ); @@ -654,20 +632,15 @@ Word16 wb_bwe_dec_fx( window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); -#ifdef ADD_IVAS_BWE - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* add HB synth from hf_synth() */ - v_add( hb_synth, synth, hb_synth, output_frame ); - } -#endif hBWE_FD->prev_mode = mode; move16(); st_fx->prev_Q_synth = Q_syn; move16(); + return Q_syn_hb; } + + /*-------------------------------------------------------------------* * swb_bwe_gain_deq() * @@ -910,18 +883,11 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class * * SWB BWE decoder *-------------------------------------------------------------------*/ -Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif - const Word16 output_frame /* i : frame length */ - , +Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 output_frame, /* i : frame length */ Word16 *Qpost ) { Word16 i, l_subfr; @@ -957,19 +923,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ /* windowing of the ACELP core synthesis */ new_input_fx_exp = *Qpost; move16(); -#ifdef ADD_IVAS_BWE - if ( st->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft ) - { - /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* IVAS_fmToDo: delay output[] by 1.25ms ? */ - lerp( output, ysynthIfx, L_FRAME16k, st_fx->L_frame ); - wtda_fx( ysynth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, - &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k ); - direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, /*st->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); - } - else -#endif { wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, &hBWE_FD->old_wtda_swb_fx_exp, @@ -1112,12 +1066,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ } fb_band_begin = FB_BAND_BEGIN; move16(); -#ifdef ADD_IVAS_BWE - IF( st_fx->L_frame == L_FRAME ) - { - fb_band_begin = FB_BAND_BEGIN_12k8; - } -#endif + FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) { tmp = sub( 32767, i_mult( j, 1024 ) ); @@ -1193,14 +1142,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ move16(); } } -#ifdef ADD_IVAS_BWE - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* add HB synth from hf_synth() */ - v_add( hb_synth, synth, hb_synth, output_frame ); - } -#endif + hBWE_FD->prev_frica_flag = frica_flag; move16(); hBWE_FD->prev_mode = mode; diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index a37ebf9d9..bc8ef03cb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -5236,10 +5236,7 @@ void td_bwe_dec_init_ivas_fx( void td_bwe_dec_init_fx( Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ -#ifdef ADD_IVAS_BWE - const Word16 extl, /* i : BWE extension layer */ -#endif - const Word32 output_Fs /* i : output sampling rate */ + const Word32 output_Fs /* i : output sampling rate */ ) { Word16 i; diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 179d0230b..1721476b4 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2446,8 +2446,6 @@ static void shb_CNG_encod_fx( } ELSE { - /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/ - // PMT("shb_CNG_encod_fx quantization in missing") } if ( LT_16( st_fx->bwidth, SWB ) ) @@ -2468,7 +2466,10 @@ static void shb_CNG_encod_fx( push_indice_fx( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice_fx( hBstr, IND_SID_BW, 1, 1 ); - delete_indice( hBstr, IND_CNG_ENV1 ); + hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); + hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; + move16(); + move16(); if ( st_fx->element_mode == IVAS_CPE_DFT ) { -- GitLab From 95009451fea95fac053b01d04e25afef3f8dfd11 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 5 Mar 2025 16:17:42 +0100 Subject: [PATCH 0325/1221] fix --- lib_dec/acelp_core_dec_fx.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 1d59d1269..c0ad52a48 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1321,6 +1321,26 @@ ivas_error acelp_core_dec_fx( move16(); } } + + test(); + test(); + test(); + test(); + test(); + IF( st_fx->flag_cna == 0 && EQ_16( st_fx->L_frame, L_FRAME16k ) && EQ_16( st_fx->last_flag_cna, 1 ) && ( ( st_fx->last_core == ACELP_CORE && NE_16( st_fx->last_coder_type, AUDIO ) ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) + { + FOR( i = 0; i < st_fx->L_frame / 2; i++ ) + { + syn_fx[i] = add( syn_fx[i], shr_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->L_frame / 4], negate( st_fx->Q_syn ) ) ); + move16(); + } + } + + test(); + IF( st_fx->flag_cna == 0 || EQ_16( st_fx->coder_type, AUDIO ) ) + { + set16_fx( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st_fx->hFdCngDec->hFdCngCom->fftlen ); + } } /*----------------------------------------------------------------* -- GitLab From 726b69f070b295ddd2c65a28eeb3e76757de6606 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 21:03:44 +0530 Subject: [PATCH 0326/1221] Optimizations for multichannel file decoded with binaural rendering ivas_binRenderer_filterModule_fx - 3.96 WMOPS improvement matrix_product_mant_exp - 9.631 WMOPS improvement BASOP_Util_Add_Mant32Exp - 15.926 WMOPS improvement --- lib_com/ivas_prot_fx.h | 14 ++ lib_com/ivas_tools_fx.c | 238 +++++++++++++++++-- lib_com/options.h | 1 + lib_dec/ivas_binRenderer_internal_fx.c | 78 +++++- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 159 ++++++++++++- lib_dec/ivas_mc_param_dec_fx.c | 4 + lib_rend/ivas_stat_rend.h | 4 + 7 files changed, 466 insertions(+), 32 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 79ba75b81..3c01bebfd 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1314,6 +1314,20 @@ Word16 matrix_diag_product_fx( Word32 *Z, /* o : resulting matrix after the matrix multiplication */ Word16 *Z_e ); +#ifdef OPT_BASOP_ADD_v1 +Word16 matrix_diag_product_fx_2( + const Word32 *X, /* i : left hand matrix Q31 - X_e*/ + const Word16 X_e, + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y, /* i : right hand diagonal matrix as vector containing the diagonal elements Q31 - Y_e*/ + const Word16 *Y_e, + const Word16 entriesY, /* i : number of entries in the diagonal Q0*/ + Word32 *Z, /* o : resulting matrix after the matrix multiplication Q31 - Z_e*/ + Word16 *Z_e ); +#endif /* OPT_BASOP_ADD_v1 */ + Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix */ const Word16 *X_e, diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index d55766928..9cd1a063e 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -980,7 +980,9 @@ Word16 matrix_product_mant_exp_fx( Word16 out_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word16 *Zp_fx_e = out_e; Word16 row, col; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ Word64 temp; Word16 temp_e; Word16 prod_e = add( X_fx_e, Y_fx_e ); @@ -1007,9 +1009,13 @@ Word16 matrix_product_mant_exp_fx( FOR( k = 0; k < rowsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ x_idx = k + i * rowsX; y_idx = k + j * rowsY; temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1047,9 +1053,13 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ x_idx = i + k * rowsX; y_idx = j + k * rowsY; temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1087,9 +1097,13 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ x_idx = k + i * rowsX; y_idx = j + k * rowsY; temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1128,9 +1142,13 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ x_idx = i + k * rowsX; y_idx = k + j * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1188,7 +1206,9 @@ Word16 matrix_product_fx( ) { Word16 i, j, k; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; /* Processing */ @@ -1209,9 +1229,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1232,9 +1256,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ + y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1255,9 +1283,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -1280,9 +1312,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ // TODO: overflow of Z_fx to be checked move32(); } @@ -1307,7 +1343,9 @@ Word16 matrix_product_q30_fx( ) { Word16 i, j, k; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; Word64 W_tmp; @@ -1330,10 +1368,14 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < rowsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 +#else /* OPT_BASOP_ADD_v1 */ //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 +#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1357,10 +1399,14 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 +#else /* OPT_BASOP_ADD_v1 */ //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 +#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1384,9 +1430,11 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifndef OPT_BASOP_ADD_v1 //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ +#endif /* OPT_BASOP_ADD_v1 */ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 } @@ -1413,10 +1461,14 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 +#else /* OPT_BASOP_ADD_v1 */ //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 +#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1449,7 +1501,9 @@ Word16 matrix_product_mant_exp( Word16 *Zp_e = Z_e; Word32 L_tmp; Word16 tmp_e; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1471,11 +1525,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < rowsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[k + i * rowsX], Y_e[k + j * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ //( *Zp ) += X[k + i * rowsX] * Y[k + j * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1503,11 +1562,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[i + k * rowsX], Y_e[j + k * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[j + k * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); ( *Zp_e ) = tmp_e; @@ -1534,11 +1598,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[k + i * rowsX], Y_e[j + k * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ //( *Zp ) += X_fx[k + i * rowsX] * Y_fx[j + k * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1568,11 +1637,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[i + k * rowsX], Y_e[k + j * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[k + j * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1603,7 +1677,9 @@ Word16 matrix_diag_product_fx( { Word16 i, j; Word32 *Zp = Z; +#ifndef OPT_BASOP_ADD_v1 Word16 tmp; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1616,8 +1692,12 @@ Word16 matrix_diag_product_fx( { FOR( i = 0; i < colsX; ++i ) { +#ifdef OPT_BASOP_ADD_v1 + *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ tmp = add( j, imult1616( i, rowsX ) ); - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ + *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1648,6 +1728,100 @@ Word16 matrix_diag_product_fx( return EXIT_SUCCESS; } +#ifdef OPT_BASOP_ADD_v1 +Word16 matrix_diag_product_fx_2( + const Word32 *X, /* i : left hand matrix Q31 - X_e*/ + const Word16 X_e, + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y, /* i : right hand diagonal matrix as vector containing the diagonal elements Q31 - Y_e*/ + const Word16 *Y_e, + const Word16 entriesY, /* i : number of entries in the diagonal Q0*/ + Word32 *Z, /* o : resulting matrix after the matrix multiplication Q31 - Z_e*/ + Word16 *Z_e ) +{ + Word16 i, j; + Word32 *Zp = Z; + Word16 *Z_ep = Z_e; + Word16 tmp; + Word16 max_exp = -31; + move16(); + + /* Processing */ + IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ + { + IF( NE_16( rowsX, entriesY ) ) + { + return EXIT_FAILURE; + } + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < colsX; ++i ) + { + tmp = j + i * rowsX; /*Q0*/ + *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ + move32(); + Zp++; + *( Z_ep ) = add( X_e, Y_e[j] ); + move16(); + max_exp = s_max( max_exp, *Z_ep ); // Find the max exp + Z_ep++; + } + } + + Zp = Z; + Z_ep = Z_e; + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < colsX; ++i ) + { + *Zp = L_shr( *Zp, sub( max_exp, *Z_ep ) ); + *Z_ep = max_exp; + Zp++; + Z_ep++; + } + } + } + ELSE /* Regular case */ + { + IF( NE_16( colsX, entriesY ) ) + { + return EXIT_FAILURE; + } + + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < rowsX; ++i ) + { + *( Zp ) = Mpy_32_32( *( X ), Y[j] ); /*Q31 - (X_e + Y_e)*/ + move32(); + Zp++; + *( Z_ep ) = add( X_e, Y_e[j] ); + move16(); + max_exp = s_max( max_exp, *Z_ep ); // Find the max exp + Z_ep++; + X++; + } + } + Zp = Z; + Z_ep = Z_e; + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < rowsX; ++i ) + { + *Zp = L_shr( *Zp, sub( max_exp, *Z_ep ) ); + *Z_ep = max_exp; + Zp++; + Z_ep++; + } + } + } + + return EXIT_SUCCESS; +} +#endif /* OPT_BASOP_ADD_v1 */ + Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ const Word16 *X_e, @@ -1663,7 +1837,9 @@ Word16 matrix_diag_product_fx_1( Word16 i, j; Word32 *Zp = Z; Word16 *Z_ep = Z_e; +#ifndef OPT_BASOP_ADD_v1 Word16 tmp; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1676,11 +1852,19 @@ Word16 matrix_diag_product_fx_1( { FOR( i = 0; i < colsX; ++i ) { +#ifdef OPT_BASOP_ADD_v1 + *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ tmp = add( j, imult1616( i, rowsX ) ); /*Q0*/ *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; +#ifdef OPT_BASOP_ADD_v1 + *( Z_ep ) = add( X_e[j + i * rowsX], Y_e[j] ); +#else /* OPT_BASOP_ADD_v1 */ *( Z_ep ) = add( X_e[tmp], Y_e[j] ); +#endif /* OPT_BASOP_ADD_v1 */ move16(); Z_ep++; } @@ -1726,7 +1910,9 @@ Word16 diag_matrix_product_fx( { Word16 i, j; Word32 *Zp = Z; +#ifndef OPT_BASOP_ADD_v1 Word16 tmp; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1739,8 +1925,12 @@ Word16 diag_matrix_product_fx( { FOR( j = 0; j < entriesY; ++j ) { - tmp = add( i, imult1616( j, rowsX ) ); /*Q0*/ - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#ifdef OPT_BASOP_ADD_v1 + *( Zp ) = Mpy_32_32( X[i + j * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ + tmp = add( i, imult1616( j, rowsX ) ); /*Q0*/ + *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1786,7 +1976,9 @@ Word16 matrix_product_diag_fx( { Word16 j, k; Word32 *Zp = Z; +#ifndef OPT_BASOP_ADD_v1 Word16 y_idx, x_idx; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1805,9 +1997,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -1825,9 +2021,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -1847,9 +2047,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -1869,9 +2073,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; diff --git a/lib_com/options.h b/lib_com/options.h index 59698f78e..b2f44bfe9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -174,4 +174,5 @@ #define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ +#define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #endif diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 748bdec38..a6e03eee3 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -68,9 +68,17 @@ static void ivas_binRenderer_filterModule_fx( { Word16 bandIdx, k, chIdx, tapIdx; Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx; +#ifdef OPT_BASOP_ADD_v1 + Word16 Q_filterStates; +#else /* OPT_BASOP_ADD_v1 */ Word16 *Q_filterStates; +#endif /* OPT_BASOP_ADD_v1 */ const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx; Word16 shift_q; +#ifdef OPT_BASOP_ADD_v1 + Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStatesLeft; + move16(); +#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -78,7 +86,9 @@ static void ivas_binRenderer_filterModule_fx( { filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] ); filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] ); +#ifndef OPT_BASOP_ADD_v1 Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx][0] ); +#endif /* OPT_BASOP_ADD_v1 */ filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29 filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29 @@ -100,39 +110,59 @@ static void ivas_binRenderer_filterModule_fx( filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1]; move32(); +#ifndef OPT_BASOP_ADD_v1 shift_q = sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ); outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); outRealRight_fx = W_shr( outRealRight_fx, shift_q ); outImagRight_fx = W_shr( outImagRight_fx, shift_q ); +#endif /* OPT_BASOP_ADD_v1 */ - outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); - outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates[tapIdx - 1] - - outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); - outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates - outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); - outRealRight_fx = W_mac_32_32( outRealRight_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsRightImagPtr_fx[tapIdx] ); + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates - outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); - outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); + outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outRealRight_fx = W_mac_32_32( outRealRight_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates +#ifndef OPT_BASOP_ADD_v1 Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; move16(); +#endif /* OPT_BASOP_ADD_v1 */ } + +#ifdef OPT_BASOP_ADD_v1 + shift_q = add( sub( Q_filterStates, Q_curr ), 1 ); +#else /* OPT_BASOP_ADD_v1 */ shift_q = add( sub( Q_filterStates[1], Q_curr ), 1 ); - outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); - outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); - outRealRight_fx = W_shr( outRealRight_fx, shift_q ); - outImagRight_fx = W_shr( outImagRight_fx, shift_q ); +#endif /* OPT_BASOP_ADD_v1 */ + +#ifdef OPT_BASOP_ADD_v1 + IF( shift_q != 0 ) + { +#endif /* OPT_BASOP_ADD_v1 */ + outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); // Q_curr + outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); // Q_curr + outRealRight_fx = W_shr( outRealRight_fx, shift_q ); // Q_curr + outImagRight_fx = W_shr( outImagRight_fx, shift_q ); // Q_curr +#ifdef OPT_BASOP_ADD_v1 + hBinRenderer->hBinRenConvModule->Q_filterStatesLeft = Q_curr; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx]; move32(); filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx]; move32(); +#ifndef OPT_BASOP_ADD_v1 Q_filterStates[0] = Q_curr; move16(); +#endif /* OPT_BASOP_ADD_v1 */ /* Left Real and Imag */ @@ -318,10 +348,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#ifndef OPT_BASOP_ADD_v1 IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -335,10 +367,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#ifndef OPT_BASOP_ADD_v1 IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif /* OPT_BASOP_ADD_v1 */ FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { @@ -352,10 +386,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#ifndef OPT_BASOP_ADD_v1 IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif /* OPT_BASOP_ADD_v1 */ } } /* set memories */ @@ -400,7 +436,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); +#ifdef OPT_BASOP_ADD_v1 + hBinRenConvModule->Q_filterStatesLeft = 31; + move16(); +#else /* OPT_BASOP_ADD_v1 */ set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTapsArray[bandIdx] ); +#endif /* OPT_BASOP_ADD_v1 */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftBRIRReal_fx[bandIdx][tmp]; @@ -414,7 +455,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); +#ifdef OPT_BASOP_ADD_v1 + hBinRenConvModule->Q_filterStatesLeft = 31; + move16(); +#else /* OPT_BASOP_ADD_v1 */ set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTaps ); +#endif /* OPT_BASOP_ADD_v1 */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp]; @@ -1279,8 +1325,10 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 free( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] ); hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); @@ -1289,8 +1337,10 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 free( hBinRenConvModule->Q_filterStatesLeft[bandIdx] ); hBinRenConvModule->Q_filterStatesLeft[bandIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx ); @@ -1299,8 +1349,10 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx ); hBinRenConvModule->filterStatesLeftImag_fx = NULL; +#ifndef OPT_BASOP_ADD_v1 free( hBinRenConvModule->Q_filterStatesLeft ); hBinRenConvModule->Q_filterStatesLeft = NULL; +#endif /* OPT_BASOP_ADD_v1 */ free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index 13d8fc940..afbde5a60 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -725,7 +725,11 @@ Word16 computeMixingMatrices_fx( Word32 G_hat_fx[MAX_OUTPUT_CHANNELS]; Word16 G_hat_buff_e[MAX_OUTPUT_CHANNELS]; +#ifdef OPT_BASOP_ADD_v1 + Word16 mat_mult_buffer2_e, mat_mult_buffer3_e; +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer1_e, mat_mult_buffer2_e, mat_mult_buffer3_e; +#endif /* OPT_BASOP_ADD_v1 */ Word32 mat_mult_buffer3_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; @@ -775,7 +779,9 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); - +#ifdef OPT_BASOP_ADD_v1 + Word16 max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ /* Computing Ky */ FOR( i = 0; i < lengthCy; ++i ) { @@ -788,8 +794,20 @@ Word16 computeMixingMatrices_fx( move32(); Ky_fx_e[i + ( j * lengthCy )] = tmp_e; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, tmp_e ); +#endif /* OPT_BASOP_ADD_v1 */ } } +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCy * lengthCy; ++i ) + { + Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); + move32(); + Ky_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Decomposition of Cx @@ -800,7 +818,9 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); svd_fx( svd_in_buffer_fx, Cx_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCx, lengthCx ); - +#ifdef OPT_BASOP_ADD_v1 + max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { FOR( j = 0; j < lengthCx; ++j ) @@ -812,9 +832,20 @@ Word16 computeMixingMatrices_fx( move32(); Kx_fx_e[( i + ( j * lengthCx ) )] = tmp_e; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, tmp_e ); +#endif /* OPT_BASOP_ADD_v1 */ } } - +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCx * lengthCx; ++i ) + { + Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); + move32(); + Kx_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -938,14 +969,25 @@ Word16 computeMixingMatrices_fx( /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ +#ifdef OPT_BASOP_ADD_v1 + Word16 mat_mult_buffer1_fx_e; +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer1_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word16 Q_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; set16_fx( Q_e_arr, Q_e, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); matrix_product_mant_exp( Kx_fx, Kx_fx_e, lengthCx, lengthCx, 1, Q_fx, Q_e_arr, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer2_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( Kx_fx, Kx_fx_e[0], lengthCx, lengthCx, 1, Q_fx, Q_e, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); + + matrix_diag_product_fx_2( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); + + matrix_product_mant_exp_fx( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e[0], lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_diag_product_fx_1( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); matrix_product_mant_exp( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e, lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); @@ -969,6 +1011,7 @@ Word16 computeMixingMatrices_fx( mat_mult_buffer1_e = exp; move16(); +#endif /* OPT_BASOP_ADD_v1 */ IF( LT_16( lengthCx, lengthCy ) ) { @@ -977,7 +1020,11 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCx; move16(); +#ifdef OPT_BASOP_ADD_v1 + svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); +#else /* OPT_BASOP_ADD_v1 */ svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); +#endif /* OPT_BASOP_ADD_v1 */ } ELSE { @@ -986,7 +1033,11 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCy; move16(); +#ifdef OPT_BASOP_ADD_v1 + svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); +#else /* OPT_BASOP_ADD_v1 */ svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); +#endif /* OPT_BASOP_ADD_v1 */ } /* Actually Processing P */ @@ -997,25 +1048,46 @@ Word16 computeMixingMatrices_fx( svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, lengthCy, lengthCx ); svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); +#ifdef OPT_BASOP_ADD_v1 + mat_mult_buffer1_fx_e = 0; +#else /* OPT_BASOP_ADD_v1 */ mat_mult_buffer1_e = 0; +#endif /* OPT_BASOP_ADD_v1 */ move16(); mat_mult_buffer2_e = 0; move16(); +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, + mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, + mat_mult_buffer3_fx, &mat_mult_buffer3_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, lengthCy, lengthCx, 0, mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, mat_mult_buffer3_fx, &mat_mult_buffer3_e ); +#endif /* OPT_BASOP_ADD_v1 */ /************************ Formulate M **********************/ +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; +#ifdef OPT_BASOP_ADD_v1 + Word16 mat_mult_buffer1_fx_e1[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + set16_fx( mat_mult_buffer1_fx_e1, mat_mult_buffer1_fx_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Formulate Cr @@ -1026,9 +1098,15 @@ Word16 computeMixingMatrices_fx( Word16 Cx_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; set16_fx( Cx_e_arr, Cx_fx_e, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1 ); + + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ exp = mixing_matrix_fx_e[0]; move16(); @@ -1067,7 +1145,11 @@ Word16 computeMixingMatrices_fx( } /* Avoid Meaningless negative main diagonal elements */ +#ifdef OPT_BASOP_ADD_v1 + IF( Cr_fx[i + ( i * lengthCy )] < 0 ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( Cr_fx[i + ( i * lengthCy )], exp, 0, 0 ) < 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { Cr_fx[i + ( i * lengthCy )] = 0; move32(); @@ -1129,7 +1211,11 @@ Word16 computeMixingMatrices_fx( { /* Avoid correction for very small energies, main diagonal elements of Cy_tilde_p may be negative */ +#ifdef OPT_BASOP_ADD_v1 + IF( Cy_tilde_p_fx[i + ( i * lengthCy )] < 0 ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( Cy_tilde_p_fx[i + ( i * lengthCy )], mat_mult_buffer2_e, 0, 0 ) < 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1148,7 +1234,12 @@ Word16 computeMixingMatrices_fx( move16(); } +#ifdef OPT_BASOP_ADD_v1 + Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, adj_e[i] ) ); + IF( GT_32( adj_fx_p[i], temp ) ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], adj_e[i], 1073741824, 3 ) > 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1281,6 +1372,9 @@ Word16 computeMixingMatricesResidual_fx( svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); /* Computing Ky */ +#ifdef OPT_BASOP_ADD_v1 + Word16 max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCy; ++i ) { FOR( j = 0; j < lengthCy; ++j ) @@ -1292,9 +1386,22 @@ Word16 computeMixingMatricesResidual_fx( move32(); Ky_fx_e[i + j * lengthCy] = tmp_e; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, tmp_e ); +#endif /* OPT_BASOP_ADD_v1 */ } } +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCy * lengthCy; ++i ) + { + Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); + move32(); + Ky_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ + /*-----------------------------------------------------------------* * Decomposition of Cx *-----------------------------------------------------------------*/ @@ -1305,7 +1412,9 @@ Word16 computeMixingMatricesResidual_fx( * square root of the diagonal of Cx */ /* Computing Kx */ - +#ifdef OPT_BASOP_ADD_v1 + max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { exp = Cx_e; @@ -1314,7 +1423,20 @@ Word16 computeMixingMatricesResidual_fx( move32(); Kx_fx_e[i] = exp; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, exp ); +#endif /* OPT_BASOP_ADD_v1 */ + } + +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCx; ++i ) + { + Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); + move32(); + Kx_fx_e[i] = max_e; + move16(); } +#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Regularization of Sx @@ -1322,16 +1444,25 @@ Word16 computeMixingMatricesResidual_fx( limit_fx = Kx_fx[0]; move32(); +#ifndef OPT_BASOP_ADD_v1 limit_e = Kx_fx_e[0]; move16(); +#endif /* OPT_BASOP_ADD_v1 */ + FOR( i = 1; i < lengthCx; i++ ) { +#ifdef OPT_BASOP_ADD_v1 + IF( GT_32( Kx_fx[i], limit_fx ) ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( Kx_fx[i], Kx_fx_e[i], limit_fx, limit_e ) > 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { limit_fx = Kx_fx[i]; move32(); +#ifndef OPT_BASOP_ADD_v1 limit_e = Kx_fx_e[i]; move16(); +#endif /* OPT_BASOP_ADD_v1 */ } } @@ -1339,7 +1470,11 @@ Word16 computeMixingMatricesResidual_fx( L_tmp = L_add( L_tmp, EPSILLON_FX ); limit_fx = L_tmp; move16(); +#ifdef OPT_BASOP_ADD_v1 + limit_e = add( Kx_fx_e[0], reg_Sx_e ); +#else /* OPT_BASOP_ADD_v1 */ limit_e = add( limit_e, reg_Sx_e ); +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -1488,10 +1623,16 @@ Word16 computeMixingMatricesResidual_fx( * Formulate M *-----------------------------------------------------------------*/ + +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); + set16_fx( mat_mult_buffer1_buff_e, mat_mult_buffer1_buff_e[0], MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); +#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; @@ -1576,7 +1717,12 @@ Word16 computeMixingMatricesResidual_fx( move32(); adj_buff_e[i] = scale; move16(); +#ifdef OPT_BASOP_ADD_v1 + Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, scale ) ); + IF( GT_32( adj_fx_p[i], temp ) ) // 1073741824 -> 1.0f in Q30 +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], scale, 1073741824, 3 ) > 0 ) // 1073741824 -> 1.0f in Q30 +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1971,7 +2117,12 @@ Word16 computeMixingMatricesISM_fx( } } +#ifdef OPT_BASOP_ADD_v1 + Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, temp_e[i] ) ); + IF( GT_32( adj_fx[i], temp ) ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( adj_fx[i], temp_e[i], MAX_32, 2 ) > 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx[i] = MAX_32; move32(); diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 5a948bdfa..4c1d5d190 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -2931,7 +2931,11 @@ static void ivas_param_mc_get_mixing_matrices_fx( FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) { +#ifdef OPT_BASOP_ADD_v1 + if ( Cproto_diag_fx[ch_idx1] < 0 ) +#else /* OPT_BASOP_ADD_v1 */ if ( BASOP_Util_Cmp_Mant32Exp( Cproto_diag_fx[ch_idx1], Cproto_diag_e, 0, 0 ) < 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { Cproto_diag_fx[ch_idx1] = 0; move16(); diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 44207c79a..386644ab1 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -666,7 +666,11 @@ typedef struct ivas_binaural_rendering_conv_module_struct_fx Word32 ***filterStatesLeftReal_fx; Word32 ***filterStatesLeftImag_fx; +#ifdef OPT_BASOP_ADD_v1 + Word16 Q_filterStatesLeft; +#else /* OPT_BASOP_ADD_v1 */ Word16 ***Q_filterStatesLeft; +#endif /* OPT_BASOP_ADD_v1 */ Word16 numTapsArray[BINAURAL_CONVBANDS]; Word16 numTaps; -- GitLab From fe2305639e2eccc5af553ffbb293fa26fa395422 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 5 Mar 2025 16:50:30 +0100 Subject: [PATCH 0327/1221] Change computeTargetPSDs_direct_subframe_fx to handle 2 scale regions directly. Extend 2 scale regions headroom calculation to proto_power_smooth_prev --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 48 +++++++++---------- lib_rend/lib_rend.c | 25 +++++++++- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 28026b487..fc88b5a9a 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2022,31 +2022,10 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); +#ifndef FIX_867_CLDFB_NRG_SCALE // Scale cy_auto_diff_smooth_fx if required IF( diff_start_band != 0 ) { -#ifdef FIX_867_CLDFB_NRG_SCALE - /* Is this necessary at all ? */ - q_com = s_min( s_min( q_reference_power_smooth[0], q_reference_power_smooth[1] ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); - scale_sig32( reference_power_smooth, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( reference_power_smooth + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_com, q_reference_power_smooth[0] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_com, q_reference_power_smooth[1] ) ); /**q_reference_power_smooth->q_com*/ - scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, - i_mult( num_freq_bands, nchan_target_psds ), - sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/ - q_reference_power_smooth[0] = q_com; - q_reference_power_smooth[1] = q_com; - move16(); - move16(); - h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = q_com; - h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = q_com; - move16(); - move16(); - - h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com; - move16(); -#else q_com = s_min( *q_reference_power_smooth, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); scale_sig32( reference_power_smooth, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/ scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/ @@ -2060,8 +2039,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com; move16(); -#endif } +#endif computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, @@ -4250,24 +4229,45 @@ static void computeTargetPSDs_diffuse_subframe_fx( { Word16 ch_idx, cur_idx; Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_cy_auto_diff_smooth_new; +#endif /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power[0], q_reference_power[1] ) ); + q_cy_auto_diff_smooth_new = q_reference_power[0]; + move16(); + IF ( LT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) + { + Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_reference_power[0] ) ); + q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth; + move16(); + } #endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF ( GT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) + { + Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_reference_power[0], *q_cy_auto_diff_smooth ) ); + } +#endif v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ) ); // (q_reference_power, Q31) -> q_reference_power } +#ifdef FIX_867_CLDFB_NRG_SCALE + *q_cy_auto_diff_smooth = q_cy_auto_diff_smooth_new; + move16(); +#else *q_cy_auto_diff_smooth = *q_reference_power; move16(); - +#endif return; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f33bc8997..19750a59a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8455,7 +8455,6 @@ static void intermidiate_ext_dirac_render( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); move16(); move16(); #else - /* Possible improvement: normalize both scale regions individually. */ tmp = 0; move16(); FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) @@ -8488,12 +8487,36 @@ static void intermidiate_ext_dirac_render( move16(); #endif #ifdef FIX_867_CLDFB_NRG_SCALE +#if 0 /* Possible improvement: normalize both scale regions individually. */ tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); move16(); +#else + tmp = 0; + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ) ) ); + } + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + move16(); + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + } + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); +#endif #else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ -- GitLab From e6809f1864dff189057bd8a53db71bf2daa84a6b Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 5 Mar 2025 16:52:35 +0100 Subject: [PATCH 0328/1221] clang format --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index fc88b5a9a..0624d3910 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -4240,7 +4240,7 @@ static void computeTargetPSDs_diffuse_subframe_fx( Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power[0], q_reference_power[1] ) ); q_cy_auto_diff_smooth_new = q_reference_power[0]; move16(); - IF ( LT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) + IF( LT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) { Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_reference_power[0] ) ); q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth; @@ -4253,7 +4253,7 @@ static void computeTargetPSDs_diffuse_subframe_fx( cur_idx = imult1616( ch_idx, num_freq_bands ); #ifdef FIX_867_CLDFB_NRG_SCALE - IF ( GT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) + IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) { Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_reference_power[0], *q_cy_auto_diff_smooth ) ); } -- GitLab From c08fe4f43533a7ec9383b28fa30525126abb57b4 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 5 Mar 2025 17:36:30 +0100 Subject: [PATCH 0329/1221] Add check for variable PYTEST_MLD_SHORT in .rules-pytest-to-ref-short to enable scheduled trigger --- .gitlab-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fc4c023dc..ac52a99a7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -274,12 +274,11 @@ stages: .rules-pytest-to-ref-short: rules: + - if: $PYTEST_MLD_SHORT # Set by scheduled pipeline - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare" - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_PIPELINE_SOURCE == 'push' when: never - - if: $CI_PIPELINE_SOURCE == 'schedule' - when: never .rules-pytest-to-input-short: rules: -- GitLab From 9070166f865c137b9d17c3786f678521908d5fa8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 5 Mar 2025 21:49:33 +0530 Subject: [PATCH 0330/1221] Fix for 3GPP issue 1334: possible Overflow in stereo leading to a click/pop Link #1334 --- lib_com/ivas_prot_fx.h | 2 +- lib_enc/ivas_cpe_enc_fx.c | 2 +- lib_enc/ivas_stereo_dft_enc_fx.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 3c01bebfd..4a72b194a 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2922,7 +2922,7 @@ void stereo_dft_enc_write_BS_fx( void stereo_dft_enc_res_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ - const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q16 */ + const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q15 */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ Word16 *nb_bits, /* o : number of bits written */ const Word16 max_bits ); diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 8f9a0edf6..3fd9c2d7a 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -1207,7 +1207,7 @@ ivas_error ivas_cpe_enc_fx( FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { - Copy_Scale_sig_16_32_no_sat( old_inp_12k8_16fx[i], old_inp_12k8_fx[i], L_INP_12k8, Q16 + Q1 ); + Copy_Scale_sig_16_32_no_sat( old_inp_12k8_16fx[i], old_inp_12k8_fx[i], L_INP_12k8, Q16 ); // Q(-1) -> Q15 } stereo_dft_enc_res_fx( hCPE->hStereoDft, old_inp_12k8_fx[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, max_bits ); } diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index cf246368f..8578a46ae 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -2700,7 +2700,7 @@ static void stereo_dft_enc_get_res_cod_mode_flag_fx( void stereo_dft_enc_res_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ - const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q16 */ + const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q15 */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ Word16 *nb_bits, /* o : number of bits written */ const Word16 max_bits ) @@ -2745,7 +2745,7 @@ void stereo_dft_enc_res_fx( /* MDCT analysis */ // TCX_MDCT_flt( win, MDCT_RES, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); - MDCT_RES_e = 16; + MDCT_RES_e = 17; move16(); TCX_MDCT( win, MDCT_RES, &MDCT_RES_e, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); -- GitLab From e0bea5dc61bd03613b0c783ebf1acb6789fd143c Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 5 Mar 2025 21:52:29 +0100 Subject: [PATCH 0331/1221] fix compiler warnings --- lib_enc/speech_music_classif_fx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 0188ba45c..415bbaafd 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2286,8 +2286,8 @@ Word16 ivas_smc_gmm_fx( lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 #else - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 #endif move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); @@ -2297,8 +2297,8 @@ Word16 ivas_smc_gmm_fx( lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 #else - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 #endif move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); @@ -2308,8 +2308,8 @@ Word16 ivas_smc_gmm_fx( lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 #else - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_shr( wprob_fx, Q10 ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 #endif move32(); } @@ -2332,7 +2332,7 @@ Word16 ivas_smc_gmm_fx( hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q7 move16(); #else - hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 + hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 move16(); -- GitLab From 75ccfd47463bd199135478c6a52e050d66571113 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:34:18 +0530 Subject: [PATCH 0332/1221] Bug fix related to 3GPP issue 1316 --- lib_enc/ivas_mdct_core_enc_fx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 6f1d4117d..edfc607ed 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1168,6 +1168,7 @@ void ivas_mdct_core_whitening_enc_fx( Word32 scf_fx[CPE_CHANNELS][NB_DIV][M]; Word32 scf_q_fx[CPE_CHANNELS][NB_DIV][M]; Word64 chE_fx[2], chE_tot_fx; + Word16 chE_q[2]; Word8 sns_low_br_mode; Word16 nbits_start_sns; Word16 num_sns; @@ -1905,6 +1906,7 @@ void ivas_mdct_core_whitening_enc_fx( IF( mct_on ) { set64_fx( chE_fx, 0, NB_DIV ); + set16_fx( chE_q, 0, NB_DIV ); } init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); @@ -1973,6 +1975,8 @@ void ivas_mdct_core_whitening_enc_fx( chE_fx[n] = W_add( W_deposit32_l( powerSpec_fx[i] ), chE_fx[n] ); move64(); } + chE_q[n] = sub( add( q_pow_tmp, q_pow ), 32 ); + move16(); } sns_compute_scf_fx( powerSpec_fx, st->hTcxCfg->psychParamsCurrent, st->L_frame, scf_fx[ch][n], sub( add( q_pow_tmp, q_pow ), 32 ) ); } @@ -1980,14 +1984,14 @@ void ivas_mdct_core_whitening_enc_fx( /* MCT: detect whether there are silent channels and set mct_chan_mode accordingly */ IF( mct_on ) { - Word16 q = sub( add( q_pow_tmp, q_pow ), 32 ); + Word16 q = s_min( chE_q[0], chE_q[1] ); Word64 silent_thr = SILENT_CHANNEL_THRES_FX; move64(); chE_tot_fx = 0; move64(); FOR( i = 0; i < NB_DIV; i++ ) { - chE_tot_fx = W_add( chE_fx[i], chE_tot_fx ); + chE_tot_fx = W_add( W_shr( chE_fx[i], sub( chE_q[i], q ) ), chE_tot_fx ); } IF( GT_16( q, Q24 ) ) { -- GitLab From caec0b360e69aa746d27ca4166994e5e810e43ce Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:40:51 +0530 Subject: [PATCH 0333/1221] Fix for 3GPP issue 1344: Decoder segfault for Stereo at 24.4kbps in ivas_fec_noise_filling_fx() Link #1344 --- lib_dec/FEC_HQ_phase_ecu_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index dd63b6508..34d01d7fe 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -4595,11 +4595,11 @@ static void ivas_fec_noise_filling_fx( { L_tmp = L_mult( *sinq_tab, *sinq_tab ); /*Q30 */ sinq_tab++; - q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ - q1 = round_fx( L_tmp ); /*Q15 */ - L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ - L_tmp = L_mac( L_tmp, shr( *pt6++, Q_old_out ), q2 ); /*Qsynth+16 */ - ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ + q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ + q1 = round_fx( L_tmp ); /*Q15 */ + L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ + L_tmp = L_add( L_tmp, L_shr( Mpy_32_16_1( L_deposit_h( *pt6++ ), q2 ), Q_old_out ) ); /*Qsynth+16 */ + ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ move16(); } -- GitLab From 2cc9768f631e7f312c11885862964c999769dd40 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Mar 2025 14:43:59 +0100 Subject: [PATCH 0334/1221] clang-format --- lib_dec/fd_cng_dec_fx.c | 4 ++-- lib_enc/pre_proc_fx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 65a20bfae..11af48a85 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1243,7 +1243,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } @@ -1570,7 +1570,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 88eb78a60..062dc3fa4 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -214,7 +214,7 @@ void pre_proc_fx( * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* -- GitLab From 5d2f008f0a341b0ce7180a89c4532787e6dbf789 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Mar 2025 15:26:29 +0100 Subject: [PATCH 0335/1221] revision of the use of delay_signal() --- lib_com/prot_fx.h | 16 +--- lib_com/tools_fx.c | 19 +---- lib_dec/acelp_core_dec_fx.c | 3 +- lib_dec/acelp_core_dec_ivas_fx.c | 4 +- lib_dec/core_switching_dec_fx.c | 13 +--- lib_dec/evs_dec_fx.c | 16 +--- lib_dec/hf_synth_fx.c | 74 +++++++------------ lib_dec/ivas_core_dec_fx.c | 2 +- lib_dec/ivas_ism_renderer_fx.c | 2 +- lib_dec/ivas_jbm_dec_fx.c | 4 +- lib_dec/ivas_lfe_dec_fx.c | 2 +- lib_dec/ivas_mc_paramupmix_dec_fx.c | 2 +- lib_dec/ivas_omasa_dec_fx.c | 2 +- lib_dec/ivas_sce_dec_fx.c | 4 +- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +-- lib_enc/ivas_osba_enc_fx.c | 2 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 4 +- lib_rend/ivas_td_decorr_fx.c | 2 +- 18 files changed, 54 insertions(+), 127 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 51fbb12d5..bf95a7d34 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6603,12 +6603,7 @@ void hf_synth_fx( Word16 *synth, /* i : 12.8kHz synthesis signal Q_syn2*/ Word16 *synth16k, /* o : 16kHz synthesis signal Q_syn2*/ const Word16 Q_exc, /* i : excitation scaling */ - const Word16 Q_syn2, /* i : synthesis scaling */ - Word16 *delay_syn_hf, /*i/o: HF synthesis memory Q_syn2*/ - Word16 *memExp1, /* o : HF excitation exponent */ - Word16 *mem_hp_interp, /* i/o: interpol. memory Qx*/ - const Word16 extl, /* i : flag indicating BWE Q0*/ - const Word16 CNG_mode /* i : CNG_mode Q0*/ + const Word16 Q_syn2 /* i : synthesis scaling */ ); void hf_synth_amr_wb_init_fx( @@ -9580,13 +9575,6 @@ void set32_fx( const Word16 N /* i : Lenght of the vector */ ); -void delay_signal_fx( - Word32 x[], /* i/o: signal to be delayed */ - const Word16 len, /* i : length of the input signal */ - Word32 mem[], /* i/o: synchronization memory */ - const Word16 delay /* i : delay in samples */ -); - void delay_signal_q_adj_fx( Word32 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ @@ -10502,7 +10490,7 @@ void floating_point_add( const Word32 my, /* i: mantissa of the adder Q31 */ const Word16 ey /* i: exponent of the adder Q0 */ ); -/*delay_signal_fx is also present*/ + void delay_signal( Word16 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index efa9d7e5a..19b12b917 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -4028,23 +4028,6 @@ void delay_signal( return; } -void delay_signal_fx( - Word32 x[], /* i/o: signal to be delayed */ - const Word16 len, /* i : length of the input signal */ - Word32 mem[], /* i/o: synchronization memory */ - const Word16 delay /* i : delay in samples */ -) -{ - - Word32 tmp_buffer[L_FRAME48k]; - - Copy32( mem, tmp_buffer, delay ); - Copy32( x + sub( len, delay ), mem, delay ); - Copy32( x, x + delay, sub( len, delay ) ); - Copy32( tmp_buffer, x, delay ); - - return; -} void delay_signal_q_adj_fx( Word32 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ @@ -4138,7 +4121,7 @@ void v_shr_16( } /*-------------------------------------------------------------------* - * delay_signal() + * delay_signal32() * * Delay buffer by defined number of samples *-------------------------------------------------------------------*/ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index c0ad52a48..0efc7e9a5 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1472,8 +1472,7 @@ ivas_error acelp_core_dec_fx( IF( ( EQ_16( st_fx->L_frame, L_FRAME ) && NE_16( st_fx->bwidth, NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st_fx->extl, -1 ) || EQ_16( st_fx->extl, SWB_CNG ) || ( EQ_16( st_fx->extl, WB_BWE ) && st_fx->extl_brate == 0 && NE_16( st_fx->coder_type, AUDIO ) ) ) ) ) { - hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, - st_fx->Q_syn2, st_fx->hBWE_zero->delay_syn_hf_fx, &st_fx->hBWE_zero->memExp1, st_fx->hBWE_zero->mem_hp_interp_fx, st_fx->extl, st_fx->CNG_mode ); + hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, st_fx->Q_syn2 ); } ELSE { diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 9597a97ae..4bd77610a 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -2163,9 +2163,7 @@ ivas_error acelp_core_dec_ivas_fx( #else Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); #endif - hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, - psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2, st->hBWE_zero->delay_syn_hf_fx, &st->hBWE_zero->memExp1, - st->hBWE_zero->mem_hp_interp_fx, st->extl, st->CNG_mode ); + hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2 ); #ifdef MSAN_FIX Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, output_frame, 0 ); #else diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 17b3f9fbc..9c69b0432 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -978,10 +978,7 @@ ivas_error core_switching_post_dec_fx( Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); - - Copy( synth, &synth[delay_comp], output_frame ); /* Qsynth */ - Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* Q0 */ - Copy( &synth[output_frame], st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth */ + delay_signal( synth, output_frame, st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth, Q0 */ test(); test(); @@ -1410,13 +1407,7 @@ ivas_error core_switching_post_dec_ivas_fx( Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); - Word16 temp_buffer[L_FRAME48k]; - - Copy( st_fx->delay_buf_out_fx, temp_buffer, delay_comp ); /* Q0 */ - Copy( synth + sub( output_frame, delay_comp ), st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth */ - move16(); - Copy( synth, synth + delay_comp, sub( output_frame, delay_comp ) ); /* Qsynth */ - Copy( temp_buffer, synth, delay_comp ); /* Q0 */ + delay_signal( synth, output_frame, st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth, Q0 */ test(); test(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index aa997d4c0..13e533796 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -492,10 +492,7 @@ ivas_error evs_dec_fx( Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( exp, st_fx->Qprev_synth_buffer_fx ) ); /*exp*/ st_fx->Qprev_synth_buffer_fx = exp; move16(); - Copy( synth_fx, tmp_buffer_fx, output_frame ); /*exp*/ - Copy( st_fx->prev_synth_buffer_fx, synth_fx, tmps ); /*st_fx->Qprev_synth_buffer_fx*/ - Copy( tmp_buffer_fx, synth_fx + tmps, output_frame - tmps ); /*exp*/ - Copy( tmp_buffer_fx + output_frame - tmps, st_fx->prev_synth_buffer_fx, tmps ); /*exp*/ + delay_signal( synth_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); /*exp, t_fx->Qprev_synth_buffer_fx*/ } ELSE { @@ -634,16 +631,14 @@ ivas_error evs_dec_fx( Copy( tmp_buffer_fx, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hBWE_TD->prev_hb_synth_fx_exp*/ } + /* Delay hb_synth */ tmp16 = sub( hb_synth_fx_exp, hBWE_TD->prev_hb_synth_fx_exp ); IF( tmp16 != 0 ) { Scale_sig( st_fx->hb_prev_synth_buffer_fx, tmps, tmp16 ); /*Q15 - hb_synth_fx_exp*/ } - Copy( hb_synth_fx, tmp_buffer_fx, output_frame ); /*Q15 - hb_synth_fx_exp*/ - Copy( st_fx->hb_prev_synth_buffer_fx, hb_synth_fx, tmps ); /*Q15 - hb_synth_fx_exp*/ - Copy( tmp_buffer_fx, hb_synth_fx + tmps, sub( output_frame, tmps ) ); /*Q15 - hb_synth_fx_exp*/ - Copy( tmp_buffer_fx + sub( output_frame, tmps ), st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp*/ + delay_signal( hb_synth_fx, output_frame, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp, Q15 - hb_synth_fx_exp*/ st_fx->old_bwe_delay = tmps; move16(); @@ -1203,10 +1198,7 @@ ivas_error evs_dec_fx( /* Delay compensation for TD-BWE*/ IF( GE_16( output_frame, L_FRAME16k ) ) { - Copy( output_sp, tmp_buffer_fx, output_frame ); /*timeIn_e*/ - Copy_Scale_sig( st_fx->prev_synth_buffer_fx, output_sp, delay_tdbwe, negate( timeIn_e ) ); /*st_fx->q_prev_synth_buffer_fx*/ - Copy( tmp_buffer_fx, output_sp + delay_tdbwe, sub( output_frame, delay_tdbwe ) ); /*timeIn_e*/ - Copy_Scale_sig( tmp_buffer_fx + sub( output_frame, delay_tdbwe ), st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); /*timeIn_e*/ + delay_signal( output_sp, output_frame, st_fx->prev_synth_buffer_fx, delay_tdbwe ); /*timeIn_e, st_fx->q_prev_synth_buffer_fx*/ } test(); diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index c61bf95ce..5807ae1fc 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -21,7 +21,7 @@ *---------------------------------------------------------------------*/ static void filt_6k_7k_scale_fx( Word16 signal[], Word16 lg, Word16 mem[], Word16 fact, Word16 exp ); -static void hf_synthesis_fx( ZERO_BWE_DEC_HANDLE hBWE_zero, const Word32 core_brate, const Word16 output_subfr, const Word16 Aq[], const Word16 exc[], const Word16 Q_exc, Word16 synth[], Word16 synth16k[], const Word16 Q_syn, Word16 *delay_syn_hf, Word16 *memExp1, Word16 *mem_hp_interp, const Word16 extl, const Word16 CNG_mode ); +static void hf_synthesis_fx( ZERO_BWE_DEC_HANDLE hBWE_zero, const Word32 core_brate, const Word16 output_subfr, const Word16 Aq[], const Word16 exc[], const Word16 Q_exc, Word16 synth[], Word16 synth16k[], const Word16 Q_syn ); static void hf_synthesis_amr_wb_fx( const Word32 core_brate, const Word16 output_subfr, const Word16 Ap[], Word16 exc16k[], Word16 synth_out[], Word16 *mem_syn_hf, Word16 *delay_syn_hf, Word16 *mem_hp_interp, Word16 p_r, Word16 HF_corr_gain, Word16 til, Word16 voice_factors, const Word16 exc[], const Word16 Q_exc, const Word16 Q_out, Word16 qhf ); static void envelope_fx( AMRWB_IO_DEC_HANDLE hAmrwb_IO, const Word32 core_brate, const Word16 Aq[], Word16 Ap[], Word16 *r, Word16 tilt0, Word16 tilt, Word16 voice_factor ); static void AdaptiveStartBand_fx( Word16 *start_band, const Word32 rate, const Word16 *lsf, const Word16 voicing_fac, const Word16 clas, Word16 *voicing_flag, Word16 *start_band_old, Word32 *OptCrit_old ); @@ -87,12 +87,7 @@ void hf_synth_fx( Word16 *synth, /* i : 12.8kHz synthesis signal Q_syn2*/ Word16 *synth16k, /* o : 16kHz synthesis signal Q_syn2*/ const Word16 Q_exc, /* i : excitation scaling */ - const Word16 Q_syn2, /* i : synthesis scaling */ - Word16 *delay_syn_hf, /*i/o: HF synthesis memory Q_syn2*/ - Word16 *memExp1, /* o : HF excitation exponent */ - Word16 *mem_hp_interp, /* i/o: interpol. memory Qx*/ - const Word16 extl, /* i : flag indicating BWE Q0*/ - const Word16 CNG_mode /* i : CNG_mode Q0*/ + const Word16 Q_syn2 /* i : synthesis scaling */ ) { const Word16 *p_Aq; @@ -104,8 +99,7 @@ void hf_synth_fx( p_Aq = Aq; /* Q12 */ FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) { - hf_synthesis_fx( hBWE_zero, core_brate, output_subfr, p_Aq, &exc[i_subfr], Q_exc, &synth[i_subfr], &synth16k[imult3216( (Word32) i_subfr, output_subfr ) / L_SUBFR], - Q_syn2, delay_syn_hf, memExp1, mem_hp_interp, extl, CNG_mode ); + hf_synthesis_fx( hBWE_zero, core_brate, output_subfr, p_Aq, &exc[i_subfr], Q_exc, &synth[i_subfr], &synth16k[imult3216( (Word32) i_subfr, output_subfr ) / L_SUBFR], Q_syn2 ); p_Aq += ( M + 1 ); /* Q12 */ } @@ -133,27 +127,19 @@ static void hf_synthesis_fx( const Word16 Q_exc, /* i : excitation scaling */ Word16 synth[], /* i : 12.8kHz synthesis signal Q_syn*/ Word16 synth16k[], /* i/o: 16kHz synthesis signal Q_syn*/ - const Word16 Q_syn, /* i : synthesis scaling */ - Word16 *delay_syn_hf, /* i/o: HF synthesis memory Q_syn*/ - Word16 *memExp1, /* o : HF excitation scaling exponent */ - Word16 *mem_hp_interp, /* i/o: interpol. memory Qx*/ - const Word16 extl, /* i : flag indicating BWE Q0*/ - const Word16 CNG_mode /* i : CNG_mode Q0*/ + const Word16 Q_syn /* i : synthesis scaling */ ) { - Word16 i; + Word16 i, s; Word16 HF_syn[L_SUBFR16k], upsampled_HF_syn[L_FRAME48k / NB_SUBFR]; Word16 HF_exc[L_SUBFR16k]; - Word16 temp_buffer[NS2SA( 16000, DELAY_CLDFB_NS ) - L_FILT16k]; - Word16 tmp, ener, exp1, exp2, scale, delay; + Word16 tmp, ener, exp1, exp2, scale; Word32 L_tmp; Word16 Ap[M16k + 1]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); #endif - (void) extl; - (void) CNG_mode; /*-----------------------------------------------------------------* * generate white noise vector @@ -189,8 +175,8 @@ static void hf_synthesis_fx( L_tmp = Isqrt_lc( L_tmp, &exp1 ); scale = round_fx( L_tmp ); /* Q18 when Q_exc=-1, HF_exc in Q-3 */ - exp2 = sub( *memExp1, exp1 ); - *memExp1 = exp1; + exp2 = sub( hBWE_zero->memExp1, exp1 ); + hBWE_zero->memExp1 = exp1; move16(); /*-----------------------------------------------------------------* @@ -280,41 +266,31 @@ static void hf_synthesis_fx( *-----------------------------------------------------------------*/ /* delay by 5 samples @16kHz to compensate CLDFB resampling delay (20samples) and HP filtering delay (roughly 15 samples) */ - delay = NS2SA_FX2( 16000, DELAY_CLDFB_NS ) - 15; - Copy( HF_syn + sub( L_SUBFR16k, delay ), temp_buffer, delay ); /* Q_syn+exp1 */ - Copy( HF_syn, HF_syn + delay, sub( L_SUBFR16k, delay ) ); /* Q_syn+exp1 */ - Copy( delay_syn_hf, HF_syn, delay ); /* Q_syn */ - Copy( temp_buffer, delay_syn_hf, delay ); /* Q_syn */ + delay_signal( HF_syn, L_SUBFR16k, hBWE_zero->delay_syn_hf_fx, NS2SA_FX2( 16000, DELAY_CLDFB_NS ) - 15 ); /* interpolate the HF synthesis */ IF( EQ_16( output_subfr, L_SUBFR48k ) ) /* 48kHz sampled output */ { - { - Word16 s; - s = s_max( s_min( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( mem_hp_interp, INTERP_3_1_MEM_LEN - 3 ) ), 3 ), - sub( Find_Max_Norm16( mem_hp_interp + INTERP_3_1_MEM_LEN - 3, 3 ), 1 ) ), - 0 ); - Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */ - Scale_sig( mem_hp_interp, INTERP_3_1_MEM_LEN, s ); /* Qx + s */ - interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, mem_hp_interp ); - Scale_sig( upsampled_HF_syn, 3 * L_SUBFR16k, -s ); /* Q_syn + exp1 + s */ - Scale_sig( mem_hp_interp, INTERP_3_1_MEM_LEN, -s ); /* Qx */ - Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */ - } + s = s_max( s_min( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN - 3 ) ), 3 ), + sub( Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx + INTERP_3_1_MEM_LEN - 3, 3 ), 1 ) ), + 0 ); + Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */ + Scale_sig( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN, s ); /* Qx + s */ + interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, hBWE_zero->mem_hp_interp_fx ); + Scale_sig( upsampled_HF_syn, 3 * L_SUBFR16k, -s ); /* Q_syn + exp1 + s */ + Scale_sig( hBWE_zero->mem_hp_interp_fx, INTERP_3_1_MEM_LEN, -s ); /* Qx */ + Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */ Scale_sig( upsampled_HF_syn, L_SUBFR48k, -1 ); } ELSE IF( EQ_16( output_subfr, L_SUBFR32k ) ) /* 32kHz sampled output */ { - { - Word16 s; - s = s_max( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( mem_hp_interp, 2 * ALLPASSSECTIONS_STEEP ) ), 2 ), 0 ); - Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */ - Scale_sig( mem_hp_interp, 2 * ALLPASSSECTIONS_STEEP, s ); /* Qx + s */ - Interpolate_allpass_steep_fx( HF_syn, mem_hp_interp, L_SUBFR16k, upsampled_HF_syn ); - Scale_sig( upsampled_HF_syn, 2 * L_SUBFR16k, -s ); /* Q_syn + exp1 */ - Scale_sig( mem_hp_interp, 2 * ALLPASSSECTIONS_STEEP, -s ); /* Qx */ - Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */ - } + s = s_max( sub( s_min( Find_Max_Norm16( HF_syn, L_SUBFR16k ), Find_Max_Norm16( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP ) ), 2 ), 0 ); + Scale_sig( HF_syn, L_SUBFR16k, s ); /* Q_syn+exp1+s */ + Scale_sig( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP, s ); /* Qx + s */ + Interpolate_allpass_steep_fx( HF_syn, hBWE_zero->mem_hp_interp_fx, L_SUBFR16k, upsampled_HF_syn ); + Scale_sig( upsampled_HF_syn, 2 * L_SUBFR16k, -s ); /* Q_syn + exp1 */ + Scale_sig( hBWE_zero->mem_hp_interp_fx, 2 * ALLPASSSECTIONS_STEEP, -s ); /* Qx */ + Scale_sig( HF_syn, L_SUBFR16k, -s ); /* Q_syn+exp1 */ } ELSE /* 16kHz sampled output */ { diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 261a3c74e..aa715fe8b 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1450,7 +1450,7 @@ ivas_error ivas_core_dec_fx( Word32 hb_prev_synth_buffer_fx_32[111]; Copy_Scale_sig_16_32_DEPREC( st->hb_prev_synth_buffer_fx, hb_prev_synth_buffer_fx_32, 111, 11 ); // Q11 - delay_signal_fx( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); + delay_signal32( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); Copy_Scale_sig_32_16( hb_prev_synth_buffer_fx_32, st->hb_prev_synth_buffer_fx, 111, -( 11 ) ); // Q0 } ELSE diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 738e5a598..b78077604 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -566,7 +566,7 @@ void ivas_omasa_separate_object_render_jbm_fx( Word16 tcBufferSize; tcBufferSize = i_mult( hSpatParamRendCom->num_slots, hSpatParamRendCom->slot_size ); - delay_signal_fx( input_fx[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[obj], st_ivas->hMasaIsmData->delayBuffer_size ); + delay_signal32( input_fx[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[obj], st_ivas->hMasaIsmData->delayBuffer_size ); } offsetSamples = 0; move16(); diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 3b66d3107..fd6e7636c 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1363,7 +1363,7 @@ ivas_error ivas_jbm_dec_tc_fx( ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 ) { /* Delay the separated channel to sync with the DirAC rendering */ - delay_signal_fx( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); + delay_signal32( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); } } ELSE @@ -1711,7 +1711,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( { FOR( n = 0; n < st_ivas->nchan_ism; n++ ) { - delay_signal_fx( st_ivas->hTcBuffer->tc_fx[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer_fx[n], st_ivas->hSbaIsmData->delayBuffer_size ); + delay_signal32( st_ivas->hTcBuffer->tc_fx[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer_fx[n], st_ivas->hSbaIsmData->delayBuffer_size ); } } diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index 616b15c6e..a8a1793ba 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -394,7 +394,7 @@ void ivas_lfe_dec_fx( /* add delay to make overall max(block_offset, 11.5) */ IF( hLFE->lfe_addl_delay > 0 ) { - delay_signal_fx( output_lfe_ch, output_frame, hLFE->lfe_delay_buf_fx, hLFE->lfe_addl_delay ); + delay_signal32( output_lfe_ch, output_frame, hLFE->lfe_delay_buf_fx, hLFE->lfe_addl_delay ); } return; diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index be53d79c8..5a2061b80 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -499,7 +499,7 @@ static void paramupmix_td_decorr_process_jbm_fx( FOR( k = 0; k < MC_PARAMUPMIX_COMBINATIONS; k++ ) { Copy32( pcm_in[k], pp_out_pcm[k], output_frame ); - delay_signal_fx( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); + delay_signal32( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); /* In ducking gains */ IF( hTdDecorr[k]->ducking_flag ) diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index 0fb4163be..7cdd241c1 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -779,7 +779,7 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm_fx( tc_local_fx[n] = st_ivas->hTcBuffer->tc_fx[n + 2]; // Q11 v_multc_fixed_16( tc_local_fx[n], gain_fx, tc_local_fx[n], tcBufferSize ); - delay_signal_fx( tc_local_fx[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size ); + delay_signal32( tc_local_fx[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size ); } } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index ce4992046..45600f7d8 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -320,13 +320,13 @@ ivas_error ivas_sce_dec_fx( * LB synthesis synchronization between IVAS formats *----------------------------------------------------------------*/ - delay_signal_fx( output[0], output_frame, st->prev_synth_buffer32_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ) ); + delay_signal32( output[0], output_frame, st->prev_synth_buffer32_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ) ); /*----------------------------------------------------------------* * HB synthesis synchronization between IVAS formats *----------------------------------------------------------------*/ - delay_signal_fx( outputHB[0], output_frame, hSCE->prev_hb_synth_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + delay_signal32( outputHB[0], output_frame, hSCE->prev_hb_synth_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); /*----------------------------------------------------------------* * output LB and HB mix diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c8a59cd6a..af7759ec0 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -1265,7 +1265,7 @@ void synchro_synthesis_fx( { /* delay CLDFB-based mono output (<= 24.4 kbps) to be aligned with DFT-based mono output (32 kbps), needed to avoid discontinuities with TCX-LTP. */ Copy32( sts[0]->prev_synth_buffer32_fx + delay_comp_DFT, hCPE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ - delay_signal_fx( output_fx[0], output_frame, hCPE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); + delay_signal32( output_fx[0], output_frame, hCPE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); } IF( NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) @@ -1282,7 +1282,7 @@ void synchro_synthesis_fx( } ELSE { - delay_signal_fx( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); + delay_signal32( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); } } if ( sba_dirac_stereo_flag ) @@ -1603,15 +1603,15 @@ void synchro_synthesis_fx( IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { Copy32( sts[n]->prev_synth_buffer32_fx + delay_comp_DFT, hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ - delay_signal_fx( output_fx[n], output_frame, hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ + delay_signal32( output_fx[n], output_frame, hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ ivas_post_proc_fx( NULL, hCPE, n, output_fx[n], output_fx, output_frame, 0, output_fx_q ); - delay_signal_fx( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); + delay_signal32( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); Copy32( hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, sts[n]->prev_synth_buffer32_fx + delay_comp_DFT, delay_diff ); /* Q11 */ } ELSE { - delay_signal_fx( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_TD ); + delay_signal32( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_TD ); } } diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 5eee0975a..46518a443 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -448,7 +448,7 @@ void ivas_osba_enc_fx( /* delay ISM input channels to match the SBA encoder delay */ FOR( n = 0; n < nchan_ism; n++ ) { - delay_signal_fx( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s ); + delay_signal32( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s ); azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index d6c999aa0..a557ebedf 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -3727,7 +3727,7 @@ void ivas_lfe_synth_with_filters_fx( /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */ delay = hMasaLfeSynth->delayBuffer_syncDirAC_size; move16(); - delay_signal_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/ + delay_signal32( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/ /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */ lowpassCoef_fx_exp = 15; @@ -3886,7 +3886,7 @@ void ivas_lfe_synth_with_filters_fx( /* Delay the separated channel to match the delay of the lowpass filter */ delay = hMasaLfeSynth->delayBuffer_syncLp_size; move16(); - delay_signal_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/ + delay_signal32( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/ return; } diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index af51a7820..5cef99e63 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -487,7 +487,7 @@ void ivas_td_decorr_process_fx( /* Look-ahead delay */ Copy32( pcm_in[0], ppOut_pcm[0], output_frame ); - delay_signal_fx( ppOut_pcm[0], output_frame, hTdDecorr->look_ahead_buf, hTdDecorr->offset ); + delay_signal32( ppOut_pcm[0], output_frame, hTdDecorr->look_ahead_buf, hTdDecorr->offset ); /* In ducking gains */ IF( hTdDecorr->ducking_flag ) -- GitLab From 4653aa3d90f61b9d3e21eb5f45f13fe3bd06eddf Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Mar 2025 16:31:30 +0100 Subject: [PATCH 0336/1221] fix --- lib_dec/evs_dec_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 13e533796..af411c366 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -1198,7 +1198,9 @@ ivas_error evs_dec_fx( /* Delay compensation for TD-BWE*/ IF( GE_16( output_frame, L_FRAME16k ) ) { + Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, negate( timeIn_e ) ); delay_signal( output_sp, output_frame, st_fx->prev_synth_buffer_fx, delay_tdbwe ); /*timeIn_e, st_fx->q_prev_synth_buffer_fx*/ + Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); } test(); -- GitLab From 9a549b097a08fad2217ee3414acccfc0d24ded1d Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 6 Mar 2025 16:00:04 +0100 Subject: [PATCH 0337/1221] update .gitlab-ci.yaml - remove -p BASOP from instrumentation job and getWmops.sh --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac52a99a7..58547f2ab 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -977,7 +977,7 @@ build-codec-linux-instrumented-make: script: - *print-common-info - *update-scripts-repo - - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP + - bash scripts/prepare_instrumentation.sh -m MEM_ONLY - make -j -C $INSTR_DIR build-codec-linux-debugging-make: @@ -1730,7 +1730,7 @@ voip-be-on-merge-request: stage: test variables: ret_val: 0 - GET_WMOPS_ARGS: "mem_only basop" + GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: - *print-common-info -- GitLab From 693ea5ac46f50e64ab13133926f168db57548a29 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:36:41 +0530 Subject: [PATCH 0338/1221] Fix for 3GPP issue 1346: Decoder crash for Stereo at 24.4kbps JBM decoding in ivas_hq_core_dec_fx() Link #1346 --- lib_com/lerp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/lerp.c b/lib_com/lerp.c index bb33d9922..28719205a 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -430,7 +430,7 @@ static void lerp_proc32( Word32 *f /*Qx*/, Word32 *f_out /*Qx*/, Word16 bufferNe { diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/ } - *ptr++ = L_add_sat( f[idx], Mpy_32_16_1( L_sub( f[idx + 1], f[idx] ), diff ) ); /*Qx*/ + *ptr++ = L_add_sat( f[idx], L_sub( Mpy_32_16_1( f[idx + 1], diff ), Mpy_32_16_1( f[idx], diff ) ) ); /*Qx*/ move32(); pos = L_add( pos, shift ); /*Q16*/ idx = extract_h( pos ); -- GitLab From 6d95f90310de811c18a5c8feeea0ada4ac027cb2 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Mar 2025 18:06:14 +0100 Subject: [PATCH 0339/1221] harmonize function save_synthesis_hq_fec_fx() --- lib_com/prot_fx.h | 16 ++++++++----- lib_dec/FEC_HQ_core_fx.c | 37 +++++++++++++++-------------- lib_dec/evs_dec_fx.c | 48 +++++++++++--------------------------- lib_dec/ivas_core_dec_fx.c | 2 +- lib_dec/ivas_mct_dec_fx.c | 2 +- 5 files changed, 44 insertions(+), 61 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index bf95a7d34..3c9408a41 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9712,20 +9712,24 @@ void addBassPostFilter_ivas_fx( Word32 **iAnalysis_fx, HANDLE_CLDFB_FILTER_BANK cldfb ); -Word32 ism_dequant_meta_fx( /* o : Q22*/ - const Word16 idx, /* i : quantizer index */ - const Word32 borders_fx[], /* i : level borders Q22*/ - const Word32 q_step_fx, /* i : quantization step Q22 */ - const Word32 q_step_border_fx, /* i : quantization step at the border Q22*/ - const Word16 cbsize /* i : codebook size */ +/* o : Q22*/ +Word32 ism_dequant_meta_fx( + const Word16 idx, /* i : quantizer index */ + const Word32 borders_fx[], /* i : level borders Q22*/ + const Word32 q_step_fx, /* i : quantization step Q22 */ + const Word32 q_step_border_fx, /* i : quantization step at the border Q22*/ + const Word16 cbsize /* i : codebook size */ ); void save_synthesis_hq_fec_fx( Decoder_State *st, /* i/o: decoder state structure */ + const Word16 synth_fx[], /* i : decoded synthesis (EVS) */ const Word32 output_fx[], /* i : decoded synthesis */ const Word16 output_frame, /* i : decoded synthesis */ + const Word16 Qpostd, /* i : Q value of delayed signal */ CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ ); + void calculate_nbits_meta_fx( const Word16 nchan_ism, Word32 q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], // Q30 diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 09bc652be..803827440 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -1964,8 +1964,10 @@ static void Next_good_after_burst_erasures_fx( void save_synthesis_hq_fec_fx( Decoder_State *st, /* i/o: decoder state structure */ + const Word16 synth_fx[], /* i : decoded synthesis (EVS) */ const Word32 output_fx[], /* i : decoded synthesis */ const Word16 output_frame, /* i : decoded synthesis */ + const Word16 Qpostd, /* i : Q value of delayed signal */ CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ ) { @@ -2004,44 +2006,43 @@ void save_synthesis_hq_fec_fx( test(); IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) { - Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); - FOR( Word16 i = 0; i < output_frame; i++ ) - { - st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 - move16(); - } - IF( st->element_mode == EVS_MONO ) { + Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); /*hTcxDec->q_synth_history_fx*/ + Copy_Scale_sig( synth_fx, st->hTcxDec->old_synthFB_fx + sub( output_frame, post_hq_delay ), output_frame, negate( Qpostd ) ); /* output_sp not initialized yet */ /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill this buffer are not available for all cases, the impact on the output is limited */ - set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); + IF( GE_16( output_frame, L_FRAME16k ) ) { - Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - } - ELSE - { - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + Copy_Scale_sig( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st->Qprev_synth_buffer_fx ) ); /*Q0*/ } - IF( st->core != ACELP_CORE ) + IF( NE_16( st->core, ACELP_CORE ) ) { IF( GE_16( output_frame, L_FRAME16k ) ) { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + Copy_Scale_sig( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ + Copy_Scale_sig( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( st->hHQ_core->Q_old_wtda ) ); /*Q0*/ } ELSE { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + + Copy_Scale_sig( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ + Copy_Scale_sig( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( st->hHQ_core->Q_old_wtda ) ); /*Q0*/ } } } ELSE { + Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); + FOR( Word16 i = 0; i < output_frame; i++ ) + { + st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 + move16(); + } + IF( st->core != ACELP_CORE ) { Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index af411c366..372eacbc1 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -27,7 +27,6 @@ ivas_error evs_dec_fx( Word16 core_switching_flag; Word16 unbits; Word16 hq_core_type; - Word16 post_hq_delay; Word32 bwe_exc_extended_fx[L_FRAME32k + NL_BUFF_OFFSET]; Word16 voice_factors_fx[NB_SUBFR16k]; Word16 hb_synth_fx[L_FRAME48k]; @@ -492,7 +491,10 @@ ivas_error evs_dec_fx( Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( exp, st_fx->Qprev_synth_buffer_fx ) ); /*exp*/ st_fx->Qprev_synth_buffer_fx = exp; move16(); - delay_signal( synth_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); /*exp, t_fx->Qprev_synth_buffer_fx*/ + Copy( synth_fx, tmp_buffer_fx, output_frame ); /*exp*/ + Copy( st_fx->prev_synth_buffer_fx, synth_fx, tmps ); /*st_fx->Qprev_synth_buffer_fx*/ + Copy( tmp_buffer_fx, synth_fx + tmps, output_frame - tmps ); /*exp*/ + Copy( tmp_buffer_fx + output_frame - tmps, st_fx->prev_synth_buffer_fx, tmps ); /*exp*/ } ELSE { @@ -631,14 +633,16 @@ ivas_error evs_dec_fx( Copy( tmp_buffer_fx, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hBWE_TD->prev_hb_synth_fx_exp*/ } - /* Delay hb_synth */ tmp16 = sub( hb_synth_fx_exp, hBWE_TD->prev_hb_synth_fx_exp ); IF( tmp16 != 0 ) { Scale_sig( st_fx->hb_prev_synth_buffer_fx, tmps, tmp16 ); /*Q15 - hb_synth_fx_exp*/ } - delay_signal( hb_synth_fx, output_frame, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp, Q15 - hb_synth_fx_exp*/ + Copy( hb_synth_fx, tmp_buffer_fx, output_frame ); /*Q15 - hb_synth_fx_exp*/ + Copy( st_fx->hb_prev_synth_buffer_fx, hb_synth_fx, tmps ); /*Q15 - hb_synth_fx_exp*/ + Copy( tmp_buffer_fx, hb_synth_fx + tmps, sub( output_frame, tmps ) ); /*Q15 - hb_synth_fx_exp*/ + Copy( tmp_buffer_fx + sub( output_frame, tmps ), st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp*/ st_fx->old_bwe_delay = tmps; move16(); @@ -1198,9 +1202,10 @@ ivas_error evs_dec_fx( /* Delay compensation for TD-BWE*/ IF( GE_16( output_frame, L_FRAME16k ) ) { - Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, negate( timeIn_e ) ); - delay_signal( output_sp, output_frame, st_fx->prev_synth_buffer_fx, delay_tdbwe ); /*timeIn_e, st_fx->q_prev_synth_buffer_fx*/ - Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); + Copy( output_sp, tmp_buffer_fx, output_frame ); /*timeIn_e*/ + Copy_Scale_sig( st_fx->prev_synth_buffer_fx, output_sp, delay_tdbwe, negate( timeIn_e ) ); /*st_fx->q_prev_synth_buffer_fx*/ + Copy( tmp_buffer_fx, output_sp + delay_tdbwe, sub( output_frame, delay_tdbwe ) ); /*timeIn_e*/ + Copy_Scale_sig( tmp_buffer_fx + sub( output_frame, delay_tdbwe ), st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); /*timeIn_e*/ } test(); @@ -1336,35 +1341,8 @@ ivas_error evs_dec_fx( * Save synthesis for HQ FEC *----------------------------------------------------------------*/ - post_hq_delay = NS2SA_FX2( st_fx->output_Fs, POST_HQ_DELAY_NS ); - IF( EQ_16( st_fx->codec_mode, MODE1 ) ) - { + save_synthesis_hq_fec_fx( st_fx, synth_fx, NULL, output_frame, 0, NULL ); - Copy( hTcxDec->synth_history_fx + output_frame, hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_MEM_NS ) ) ); /*hTcxDec->q_synth_history_fx*/ - Copy_Scale_sig( synth_fx, hTcxDec->old_synthFB_fx + sub( output_frame, post_hq_delay ), output_frame, negate( Qpostd ) ); /* output_sp not initialized yet */ - /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill - this buffer are not available for all cases, the impact on the output is limited */ - set16_fx( hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); - - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy_Scale_sig( st_fx->prev_synth_buffer_fx, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st_fx->Qprev_synth_buffer_fx ) ); /*Q0*/ - } - IF( NE_16( st_fx->core, ACELP_CORE ) ) - { - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy_Scale_sig( synth_fx + output_frame, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ - Copy_Scale_sig( hHQ_core->old_out_fx + NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS ), hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( hHQ_core->Q_old_wtda ) ); /*Q0*/ - } - ELSE - { - - Copy_Scale_sig( synth_fx + output_frame, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ - Copy_Scale_sig( hHQ_core->old_out_fx + NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS ), hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( hHQ_core->Q_old_wtda ) ); /*Q0*/ - } - } - } /*----------------------------------------------------------------* * HP filtering *----------------------------------------------------------------*/ diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index aa715fe8b..d5bd949c1 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1667,7 +1667,7 @@ ivas_error ivas_core_dec_fx( move16(); } /* Save synthesis for HQ FEC */ - save_synthesis_hq_fec_fx( st, output_fx_loc, output_frame, hCPE ); + save_synthesis_hq_fec_fx( st, NULL, output_fx_loc, output_frame, 0, hCPE ); /* Updates */ diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index c95a5285a..247f2bfc9 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -467,7 +467,7 @@ ivas_error ivas_mct_dec_fx( sts[n]->q_prev_synth_buffer_fx = 0; move16(); - save_synthesis_hq_fec_fx( sts[n], output_fx_, output_frame, hCPE ); + save_synthesis_hq_fec_fx( sts[n], NULL, output_fx_, output_frame, 0, hCPE ); /* CoreCoder common updates */ ivas_updt_dec_common_fx( hCPE->hCoreCoder[n], NORMAL_HQ_CORE, -1, output_fx[( cpe_id * CPE_CHANNELS ) + n], 11 ); -- GitLab From 947e3bfe38965936fbab9ff4e1ff494397223adc Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Mar 2025 18:45:10 +0100 Subject: [PATCH 0340/1221] update --- lib_dec/evs_dec_fx.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 372eacbc1..ef93ec3fe 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -491,10 +491,7 @@ ivas_error evs_dec_fx( Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( exp, st_fx->Qprev_synth_buffer_fx ) ); /*exp*/ st_fx->Qprev_synth_buffer_fx = exp; move16(); - Copy( synth_fx, tmp_buffer_fx, output_frame ); /*exp*/ - Copy( st_fx->prev_synth_buffer_fx, synth_fx, tmps ); /*st_fx->Qprev_synth_buffer_fx*/ - Copy( tmp_buffer_fx, synth_fx + tmps, output_frame - tmps ); /*exp*/ - Copy( tmp_buffer_fx + output_frame - tmps, st_fx->prev_synth_buffer_fx, tmps ); /*exp*/ + delay_signal( synth_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); /*exp, t_fx->Qprev_synth_buffer_fx*/ } ELSE { @@ -639,10 +636,7 @@ ivas_error evs_dec_fx( { Scale_sig( st_fx->hb_prev_synth_buffer_fx, tmps, tmp16 ); /*Q15 - hb_synth_fx_exp*/ } - Copy( hb_synth_fx, tmp_buffer_fx, output_frame ); /*Q15 - hb_synth_fx_exp*/ - Copy( st_fx->hb_prev_synth_buffer_fx, hb_synth_fx, tmps ); /*Q15 - hb_synth_fx_exp*/ - Copy( tmp_buffer_fx, hb_synth_fx + tmps, sub( output_frame, tmps ) ); /*Q15 - hb_synth_fx_exp*/ - Copy( tmp_buffer_fx + sub( output_frame, tmps ), st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp*/ + delay_signal( hb_synth_fx, output_frame, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp, Q15 - hb_synth_fx_exp*/ st_fx->old_bwe_delay = tmps; move16(); @@ -1202,10 +1196,9 @@ ivas_error evs_dec_fx( /* Delay compensation for TD-BWE*/ IF( GE_16( output_frame, L_FRAME16k ) ) { - Copy( output_sp, tmp_buffer_fx, output_frame ); /*timeIn_e*/ - Copy_Scale_sig( st_fx->prev_synth_buffer_fx, output_sp, delay_tdbwe, negate( timeIn_e ) ); /*st_fx->q_prev_synth_buffer_fx*/ - Copy( tmp_buffer_fx, output_sp + delay_tdbwe, sub( output_frame, delay_tdbwe ) ); /*timeIn_e*/ - Copy_Scale_sig( tmp_buffer_fx + sub( output_frame, delay_tdbwe ), st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); /*timeIn_e*/ + Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, negate( timeIn_e ) ); + delay_signal( output_sp, output_frame, st_fx->prev_synth_buffer_fx, delay_tdbwe ); /*timeIn_e, st_fx->q_prev_synth_buffer_fx*/ + Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); } test(); -- GitLab From b542ea355e182ce718912ddd107c696990524724 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Mar 2025 19:48:47 +0100 Subject: [PATCH 0341/1221] update --- lib_dec/evs_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index ef93ec3fe..436972d4e 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -1334,7 +1334,7 @@ ivas_error evs_dec_fx( * Save synthesis for HQ FEC *----------------------------------------------------------------*/ - save_synthesis_hq_fec_fx( st_fx, synth_fx, NULL, output_frame, 0, NULL ); + save_synthesis_hq_fec_fx( st_fx, synth_fx, NULL, output_frame, Qpostd, NULL ); /*----------------------------------------------------------------* * HP filtering -- GitLab From 842e5d97b7e8917b33ceddcf5de3006d0cdf55c5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:44:47 +0530 Subject: [PATCH 0342/1221] Fix for 3GPP issue 1307: Missing signal in BASOP enc-dec path compared to float enc-dec path using selection test MASA at 24.4 kbps with DTX enabled Link #1307 --- lib_enc/nois_est_fx.c | 37 ++++++++++++++++++++----------------- lib_enc/stat_enc.h | 3 +++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 68eed3d65..0851e4c17 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -326,6 +326,10 @@ void noise_est_init_ivas_fx( hNoiseEst->Etot_sq_st_est_fx = 1600; /* 400 in Q2 */ move16(); move16(); + hNoiseEst->L_Etot_st_est_fx = 167772160; /* 20.0f in Q23 */ + hNoiseEst->L_Etot_sq_st_est_fx = 26214400; /* 400 in Q16 */ + move32(); + move32(); hNoiseEst->epsP_0_2_lp_fx = 4096; /*1.0 Q12*/ move16(); hNoiseEst->epsP_0_2_ad_lp_fx = 0; @@ -2195,9 +2199,9 @@ void noise_est_ivas_fx( Word16 vad_bwidth_fx; /* vad ns control variabel for input bwidth from teh BWD */ /* for DTX operation */ - Word16 lim_Etot_fx; /* Q8 */ - Word16 lim_Etot_sq_fx; /* Q2 */ - Word16 st_E_var_est_fx; /* Q2 */ + Word16 lim_Etot_fx; /* Q8 */ + Word32 lim_Etot_sq_fx; /* Q16 */ + Word32 st_E_var_est_fx; NOISE_EST_HANDLE hNoiseEst; SP_MUS_CLAS_HANDLE hSpMusClas; Word32 Le_min_scaled; @@ -2720,32 +2724,31 @@ void noise_est_ivas_fx( Lnon_sta2 = L_deposit_l( 1024 ); /* 1.0 in Q10 */ } - lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ - lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ + lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ + lim_Etot_sq_fx = L_mult0( lim_Etot_fx, lim_Etot_fx ); /* Q16 */ IF( LT_16( ini_frame, 150 ) ) { /* Allow use of quicker filter during init - if needed */ /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ - hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); // Q8 - move16(); + hNoiseEst->L_Etot_st_est_fx = Madd_32_16_r( L_mult0( 8192, lim_Etot_fx ), hNoiseEst->L_Etot_st_est_fx, 24576 ); // Q23 + move32(); /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ - hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); // Q2 - move16(); + hNoiseEst->L_Etot_sq_st_est_fx = Madd_32_16_r( Mult_32_16( lim_Etot_sq_fx, 8192 ), hNoiseEst->L_Etot_sq_st_est_fx, 24576 ); // Q16 + move32(); } ELSE { /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ - hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); // Q8 - move16(); + hNoiseEst->L_Etot_st_est_fx = Madd_32_16_r( L_mult0( 8192, lim_Etot_fx ), hNoiseEst->L_Etot_st_est_fx, 24576 ); // Q23 + move32(); /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ - hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); // Q2 - move16(); + hNoiseEst->L_Etot_sq_st_est_fx = Madd_32_16_r( Mult_32_16( lim_Etot_sq_fx, 8192 ), hNoiseEst->L_Etot_sq_st_est_fx, 24576 ); // Q16 + move32(); } - st_E_var_est_fx = sub( hNoiseEst->Etot_sq_st_est_fx, extract_h( L_shl_r( L_mult( hNoiseEst->Etot_st_est_fx, hNoiseEst->Etot_st_est_fx ), 1 ) ) ); // Q2 - - + Word16 exp_tmp; + st_E_var_est_fx = BASOP_Util_Add_Mant32Exp( hNoiseEst->L_Etot_sq_st_est_fx, Q15, L_negate( Mpy_32_32( hNoiseEst->L_Etot_st_est_fx, hNoiseEst->L_Etot_st_est_fx ) ), Q16, &exp_tmp ); // exp(exp_tmp) /*-----------------------------------------------------------------* * Count frames since last correlation or harmonic event *-----------------------------------------------------------------*/ @@ -2775,7 +2778,7 @@ void noise_est_ivas_fx( } test(); test(); - IF( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 /* 30.0f in Q8 */ ) && GT_16( st_E_var_est_fx, 32 /* 8.0f in Q2 */ ) ) + IF( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 /* 30.0f in Q8 */ ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( st_E_var_est_fx, exp_tmp, 524288 /* 8.0f in Q16 */, Q15 ), 1 ) ) { /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ *st_harm_cor_cnt = s_max( 1, shr( add( *st_harm_cor_cnt, 2 ), 2 ) ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 6fd9ce6f3..ad572d2ba 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -566,6 +566,9 @@ typedef struct noise_estimation_structure Word16 Etot_st_est_fx; /* Q8 Noise estimation - short term estimate of E{ Etot } */ Word16 Etot_sq_st_est_fx; /* Q2 Noise estimation - short term estimate of E{ Etot^2 } */ + Word32 L_Etot_st_est_fx; /* Q23 Noise estimation - short term estimate of E{ Etot } */ + Word32 L_Etot_sq_st_est_fx; /* Q16 Noise estimation - short term estimate of E{ Etot^2 } */ + Word16 aEn_inac_cnt; } NOISE_EST_DATA, *NOISE_EST_HANDLE; -- GitLab From 3116ef12792222dc5086b9edb5a9b52469994161 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 07:28:01 +0530 Subject: [PATCH 0343/1221] Clean up of prot.h file --- Workspace_msvc/lib_com.vcxproj | 3 - Workspace_msvc/lib_com.vcxproj.filters | 9 - lib_com/ari_hm_fx.c | 1 - lib_com/arith_coder_fx.c | 1 - lib_com/basop_tcx_utils.c | 2 +- lib_com/bitalloc_fx.c | 1 - lib_com/bitstream.c | 3 +- lib_com/cldfb.c | 1 - lib_com/cng_exc.c | 57 - lib_com/codec_tcx_common.c | 1 - lib_com/core_com_config.c | 60 +- lib_com/deemph.c | 3 +- lib_com/delay_comp.c | 3 +- lib_com/disclaimer.c | 2 +- lib_com/enr_1_az.c | 3 +- lib_com/env_adj.c | 3 +- lib_com/env_stab.c | 3 +- lib_com/env_stab_trans.c | 3 +- lib_com/fd_cng_com_fx.c | 1 - lib_com/fft.c | 2 +- lib_com/fft_fx.c | 2 +- lib_com/fft_rel.c | 3 +- lib_com/fill_spectrum.c | 3 +- lib_com/findpulse.c | 3 +- lib_com/float_to_fix_ops.c | 1 - lib_com/frame_ener_fx.c | 3 +- lib_com/get_gain_fx.c | 3 +- lib_com/gs_bitallocation_ivas_fx.c | 1 - lib_com/gs_gains.c | 1 - lib_com/gs_preech_fx.c | 3 +- lib_com/hp50_fx.c | 3 +- lib_com/hq2_core_com.c | 2 +- lib_com/hq_conf.c | 3 +- lib_com/hq_tools_fx.c | 1 - lib_com/ifft_rel.c | 3 +- lib_com/int_lsp.c | 3 +- lib_com/interleave_spectrum.c | 3 +- lib_com/interpol.c | 3 +- lib_com/ivas_agc_com_fx.c | 2 +- lib_com/ivas_arith_fx.c | 3 +- lib_com/ivas_avq_pos_reorder_com_fx.c | 2 +- lib_com/ivas_cov_smooth_fx.c | 1 - lib_com/ivas_dirac_com_fx.c | 3 +- lib_com/ivas_entropy_coder_common_fx.c | 2 +- lib_com/ivas_fb_mixer_fx.c | 3 +- lib_com/ivas_ism_com_fx.c | 3 +- lib_com/ivas_lfe_com_fx.c | 2 +- lib_com/ivas_masa_com_fx.c | 3 +- lib_com/ivas_mc_com_fx.c | 2 +- lib_com/ivas_mc_param_com_fx.c | 1 - lib_com/ivas_mct_com_fx.c | 2 +- lib_com/ivas_mdct_core_com_fx.c | 3 +- lib_com/ivas_mdft_imdft_fx.c | 3 +- lib_com/ivas_omasa_com_fx.c | 3 +- lib_com/ivas_pca_tools_fx.c | 1 - lib_com/ivas_qmetadata_com_fx.c | 3 +- lib_com/ivas_qspherical_com_fx.c | 4 +- lib_com/ivas_sba_config_fx.c | 2 +- lib_com/ivas_sns_com_fx.c | 1 - lib_com/ivas_spar_com_fx.c | 1 - lib_com/ivas_spar_com_quant_util_fx.c | 1 - lib_com/ivas_stereo_dft_com_fx.c | 2 +- lib_com/ivas_stereo_eclvq_com_fx.c | 2 +- lib_com/ivas_stereo_ica_com_fx.c | 1 - lib_com/ivas_stereo_mdct_bands_com_fx.c | 3 +- lib_com/ivas_stereo_psychlpc_com_fx.c | 2 +- lib_com/ivas_stereo_td_bit_alloc_fx.c | 3 +- lib_com/ivas_tools_fx.c | 3 +- lib_com/ivas_transient_det_fx.c | 3 +- lib_com/lag_wind.c | 1 - lib_com/lerp.c | 129 - lib_com/limit_t0.c | 231 - lib_com/longarith.c | 3 +- lib_com/lsp_conv_poly_fx.c | 3 +- lib_com/modif_fs.c | 3 +- lib_com/mslvq_com.c | 3 +- lib_com/mslvq_com_fx.c | 1 - lib_com/preemph.c | 2 +- lib_com/prot.h | 8340 ----------------- lib_com/prot_fx.h | 793 +- lib_com/pvq_com_fx.c | 1 - lib_com/residu_fx.c | 1 - lib_com/rom_com.c | 3 +- lib_com/rom_com_fx.c | 2 +- lib_com/swb_tbe_com.c | 1 - lib_com/swb_tbe_com_fx.c | 1 - lib_com/tcx_mdct_window.c | 1 - lib_com/tcx_utils_fx.c | 1 - lib_com/tns_base.c | 1 - lib_com/tools.c | 1199 +-- lib_com/tools_fx.c | 1 - lib_com/wtda.c | 3 +- lib_dec/acelp_core_dec_ivas_fx.c | 1 - lib_dec/acelp_core_switch_dec_fx.c | 1 - lib_dec/ari_hm_dec.c | 3 +- lib_dec/arith_coder_dec_fx.c | 1 - lib_dec/avq_dec_fx.c | 1 - lib_dec/cng_dec_fx.c | 1 - lib_dec/core_dec_init_fx.c | 1 - lib_dec/core_dec_switch_fx.c | 1 - lib_dec/dec_tcx_fx.c | 1 - lib_dec/gs_dec_fx.c | 1 - lib_dec/hf_synth_fx.c | 1 - lib_dec/hq_core_dec_fx.c | 1 - lib_dec/igf_dec_fx.c | 3 +- lib_dec/init_dec_fx.c | 1 - lib_dec/ivas_agc_dec_fx.c | 1 - lib_dec/ivas_binRenderer_internal_fx.c | 3 +- lib_dec/ivas_core_dec_fx.c | 3 +- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 1 - lib_dec/ivas_cpe_dec_fx.c | 3 +- lib_dec/ivas_decision_matrix_dec_fx.c | 3 +- lib_dec/ivas_dirac_dec_fx.c | 3 +- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 3 +- lib_dec/ivas_entropy_decoder_fx.c | 3 +- lib_dec/ivas_init_dec.c | 3 +- lib_dec/ivas_ism_dec_fx.c | 3 +- lib_dec/ivas_ism_dtx_dec_fx.c | 3 +- lib_dec/ivas_ism_metadata_dec_fx.c | 1 - lib_dec/ivas_ism_param_dec_fx.c | 3 +- lib_dec/ivas_ism_renderer_fx.c | 1 - lib_dec/ivas_jbm_dec_fx.c | 3 +- lib_dec/ivas_lfe_dec_fx.c | 1 - lib_dec/ivas_lfe_plc_fx.c | 1 - lib_dec/ivas_ls_custom_dec_fx.c | 3 +- lib_dec/ivas_masa_dec_fx.c | 1 - lib_dec/ivas_mc_param_dec_fx.c | 3 +- lib_dec/ivas_mc_paramupmix_dec_fx.c | 1 - lib_dec/ivas_mcmasa_dec_fx.c | 2 +- lib_dec/ivas_mct_core_dec_fx.c | 3 +- lib_dec/ivas_mct_dec_fx.c | 1 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 3 +- lib_dec/ivas_mdct_core_dec_fx.c | 3 +- lib_dec/ivas_mono_dmx_renderer_fx.c | 1 - lib_dec/ivas_objectRenderer_internal_fx.c | 3 +- lib_dec/ivas_omasa_dec_fx.c | 3 +- lib_dec/ivas_osba_dec_fx.c | 3 +- lib_dec/ivas_out_setup_conversion_fx.c | 3 +- lib_dec/ivas_pca_dec_fx.c | 3 +- lib_dec/ivas_post_proc_fx.c | 1 - lib_dec/ivas_qmetadata_dec_fx.c | 3 +- lib_dec/ivas_qspherical_dec_fx.c | 2 +- lib_dec/ivas_range_uni_dec_fx.c | 3 +- lib_dec/ivas_sba_dec_fx.c | 3 +- lib_dec/ivas_sba_rendering_internal_fx.c | 3 +- lib_dec/ivas_sce_dec_fx.c | 1 - lib_dec/ivas_sns_dec_fx.c | 3 +- lib_dec/ivas_spar_decoder_fx.c | 3 +- lib_dec/ivas_spar_md_dec_fx.c | 3 +- lib_dec/ivas_stereo_adapt_GR_dec_fx.c | 3 +- lib_dec/ivas_stereo_cng_dec.c | 3 +- lib_dec/ivas_stereo_dft_dec.c | 1 - lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 3 +- lib_dec/ivas_stereo_dft_dec_fx.c | 1 - lib_dec/ivas_stereo_dft_plc_fx.c | 1 - lib_dec/ivas_stereo_eclvq_dec_fx.c | 2 +- lib_dec/ivas_stereo_ica_dec_fx.c | 3 +- lib_dec/ivas_stereo_icbwe_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_core_dec_fx.c | 3 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 3 +- lib_dec/ivas_stereo_switching_dec_fx.c | 3 +- lib_dec/ivas_stereo_td_dec_fx.c | 1 - lib_dec/ivas_svd_dec_fx.c | 3 +- lib_dec/ivas_tcx_core_dec_fx.c | 3 +- lib_dec/ivas_td_low_rate_dec_fx.c | 1 - lib_dec/jbm_jb4_circularbuffer.c | 2 +- lib_dec/jbm_jb4_circularbuffer.h | 2 +- lib_dec/jbm_jb4_inputbuffer.c | 2 +- lib_dec/jbm_jb4_jmf.c | 2 +- lib_dec/jbm_jb4sb.c | 1 - lib_dec/jbm_pcmdsp_apa.c | 3 +- lib_dec/lib_dec_fx.c | 5 +- lib_dec/swb_tbe_dec_fx.c | 1 - lib_dec/tonalMDCTconcealment_fx.c | 1 - lib_enc/ACcontextMapping_enc_fx.c | 1 - lib_enc/FEC_enc_fx.c | 1 - lib_enc/SNR_calc_fx.c | 1 - lib_enc/acelp_core_enc_fx.c | 1 - lib_enc/acelp_core_switch_enc_fx.c | 1 - lib_enc/ari_hm_enc_fx.c | 4 +- lib_enc/avq_cod_fx.c | 4 +- lib_enc/cng_enc_fx.c | 10 +- lib_enc/cod2t32_fx.c | 1 - lib_enc/cod4t64_fast.c | 1 - lib_enc/cod4t64_fx.c | 3 +- lib_enc/cod_tcx_fx.c | 2 - lib_enc/core_enc_init_fx.c | 1 - lib_enc/core_enc_switch_fx.c | 5 +- lib_enc/dtx_fx.c | 1 - lib_enc/enc_gen_voic_fx.c | 3 +- lib_enc/enc_higher_acelp_fx.c | 3 +- lib_enc/enc_pit_exc_fx.c | 1 - lib_enc/enc_prm_fx.c | 3 +- lib_enc/enc_tran_fx.c | 1 - lib_enc/enc_uv_fx.c | 3 +- lib_enc/eval_pit_contr_fx.c | 1 - lib_enc/evs_enc_fx.c | 3 +- lib_enc/fd_cng_enc_fx.c | 1 - lib_enc/find_wsp_fx.c | 3 +- lib_enc/gain_enc_fx.c | 1 - lib_enc/gaus_enc_fx.c | 1 - lib_enc/gs_enc_fx.c | 2 - lib_enc/hq_classifier_enc_fx.c | 1 - lib_enc/hq_core_enc_fx.c | 10 +- lib_enc/hq_env_enc_fx.c | 1 - lib_enc/hq_hr_enc_fx.c | 1 - lib_enc/hq_lr_enc_fx.c | 1 - lib_enc/hvq_enc_fx.c | 1 - lib_enc/igf_enc.c | 38 +- lib_enc/igf_enc_fx.c | 3 +- lib_enc/igf_scf_enc.c | 3 +- lib_enc/init_enc_fx.c | 1 - lib_enc/inov_enc_fx.c | 1 - lib_enc/ivas_agc_enc_fx.c | 3 +- lib_enc/ivas_core_enc_fx.c | 3 +- lib_enc/ivas_core_pre_proc_front_fx.c | 2 - lib_enc/ivas_core_pre_proc_fx.c | 3 +- lib_enc/ivas_corecoder_enc_reconfig_fx.c | 1 - lib_enc/ivas_cpe_enc_fx.c | 3 +- lib_enc/ivas_decision_matrix_enc_fx.c | 3 +- lib_enc/ivas_dirac_enc_fx.c | 1 - lib_enc/ivas_enc_cov_handler_fx.c | 3 +- lib_enc/ivas_enc_fx.c | 3 +- lib_enc/ivas_entropy_coder_fx.c | 1 - lib_enc/ivas_front_vad_fx.c | 3 +- lib_enc/ivas_init_enc_fx.c | 3 +- lib_enc/ivas_ism_dtx_enc_fx.c | 3 +- lib_enc/ivas_ism_enc_fx.c | 3 +- lib_enc/ivas_ism_metadata_enc_fx.c | 3 +- lib_enc/ivas_ism_param_enc_fx.c | 1 - lib_enc/ivas_lfe_enc_fx.c | 3 +- lib_enc/ivas_masa_enc_fx.c | 1 - lib_enc/ivas_mc_param_enc_fx.c | 2 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 3 +- lib_enc/ivas_mcmasa_enc_fx.c | 1 - lib_enc/ivas_mct_core_enc_fx.c | 4 +- lib_enc/ivas_mct_enc_fx.c | 3 +- lib_enc/ivas_mct_enc_mct_fx.c | 1 - lib_enc/ivas_mdct_core_enc_fx.c | 3 +- lib_enc/ivas_omasa_enc_fx.c | 1 - lib_enc/ivas_osba_enc_fx.c | 3 +- lib_enc/ivas_pca_enc_fx.c | 3 +- lib_enc/ivas_qmetadata_enc_fx.c | 4 +- lib_enc/ivas_qspherical_enc_fx.c | 1 - lib_enc/ivas_range_uni_enc_fx.c | 2 +- lib_enc/ivas_sba_enc_fx.c | 3 +- lib_enc/ivas_sce_enc_fx.c | 1 - lib_enc/ivas_sns_enc_fx.c | 3 +- lib_enc/ivas_spar_encoder_fx.c | 1 - lib_enc/ivas_spar_md_enc_fx.c | 2 - lib_enc/ivas_stereo_adapt_GR_enc_fx.c | 2 +- lib_enc/ivas_stereo_classifier_fx.c | 3 +- lib_enc/ivas_stereo_cng_enc_fx.c | 3 +- lib_enc/ivas_stereo_dft_enc_fx.c | 3 +- lib_enc/ivas_stereo_dft_enc_itd_fx.c | 1 - lib_enc/ivas_stereo_dft_td_itd_fx.c | 3 +- lib_enc/ivas_stereo_dmx_evs_fx.c | 2 - lib_enc/ivas_stereo_eclvq_enc_fx.c | 1 - lib_enc/ivas_stereo_ica_enc_fx.c | 3 +- lib_enc/ivas_stereo_icbwe_enc_fx.c | 3 +- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_igf_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 1 - lib_enc/ivas_stereo_switching_enc_fx.c | 3 +- lib_enc/ivas_stereo_td_analysis_fx.c | 3 +- lib_enc/ivas_stereo_td_enc_fx.c | 3 +- lib_enc/ivas_tcx_core_enc_fx.c | 3 +- lib_enc/ivas_td_low_rate_enc_fx.c | 1 - lib_enc/lib_enc.c | 1 - lib_enc/lsf_enc_fx.c | 1 - lib_enc/lsf_msvq_ma_enc.c | 1 - lib_enc/mdct_classifier_fx.c | 1 - lib_enc/mslvq_enc_fx.c | 3 +- lib_enc/nelp_enc_fx.c | 1 - lib_enc/peak_vq_enc_fx.c | 1 - lib_enc/pit_enc_fx.c | 1 - lib_enc/range_enc_fx.c | 1 - lib_enc/speech_music_classif_fx.c | 1 - lib_enc/stat_noise_uv_enc_fx.c | 1 - lib_enc/swb_bwe_enc_fx.c | 3 +- lib_enc/swb_bwe_enc_lr_fx.c | 1 - lib_enc/swb_tbe_enc.c | 46 - lib_enc/swb_tbe_enc_fx.c | 1 - lib_enc/tcq_core_enc_fx.c | 1 - lib_enc/tns_base_enc_fx.c | 1 - lib_enc/transition_enc_fx.c | 1 - lib_rend/ivas_allrad_dec_fx.c | 2 +- lib_rend/ivas_crend_fx.c | 3 +- lib_rend/ivas_dirac_ana_fx.c | 3 +- .../ivas_dirac_dec_binaural_functions_fx.c | 1 - lib_rend/ivas_dirac_decorr_dec_fx.c | 3 +- lib_rend/ivas_dirac_onsets_dec_fx.c | 3 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 3 +- lib_rend/ivas_dirac_rend_fx.c | 3 +- lib_rend/ivas_efap_fx.c | 1 - lib_rend/ivas_hrtf_fx.c | 2 +- lib_rend/ivas_limiter_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 3 +- lib_rend/ivas_mcmasa_ana_fx.c | 3 +- lib_rend/ivas_objectRenderer_fx.c | 3 +- lib_rend/ivas_objectRenderer_hrFilt_fx.c | 3 +- lib_rend/ivas_objectRenderer_mix_fx.c | 3 +- lib_rend/ivas_objectRenderer_sfx_fx.c | 3 +- lib_rend/ivas_objectRenderer_sources_fx.c | 3 +- lib_rend/ivas_objectRenderer_vec_fx.c | 3 +- lib_rend/ivas_omasa_ana_fx.c | 3 +- lib_rend/ivas_output_init.c | 2 +- lib_rend/ivas_reflections_fx.c | 3 +- lib_rend/ivas_render_config_fx.c | 3 +- lib_rend/ivas_reverb_delay_line_fx.c | 3 +- lib_rend/ivas_reverb_fft_filter_fx.c | 3 +- lib_rend/ivas_reverb_filter_design_fx.c | 1 - lib_rend/ivas_reverb_fx.c | 3 +- lib_rend/ivas_reverb_iir_filter_fx.c | 3 +- lib_rend/ivas_reverb_utils_fx.c | 3 +- lib_rend/ivas_rotation_fx.c | 3 +- lib_rend/ivas_sba_rendering_fx.c | 1 - lib_rend/ivas_shoebox_fx.c | 1 - lib_rend/ivas_td_decorr_fx.c | 1 - lib_rend/ivas_vbap_fx.c | 3 +- lib_rend/lib_rend.c | 1 - lib_util/hrtf_file_reader.c | 3 +- lib_util/ls_custom_file_reader.c | 2 +- lib_util/mime_io.c | 2 +- lib_util/render_config_reader.c | 2 +- lib_util/rotation_file_reader.c | 1 - lib_util/vector3_pair_file_reader.c | 1 - 327 files changed, 990 insertions(+), 10601 deletions(-) delete mode 100644 lib_com/cng_exc.c delete mode 100644 lib_com/limit_t0.c delete mode 100644 lib_com/prot.h delete mode 100644 lib_enc/swb_tbe_enc.c diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 8c42f19ca..5b26a2911 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -138,7 +138,6 @@ - @@ -238,7 +237,6 @@ - @@ -324,7 +322,6 @@ - diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 8f2be8853..b9769e3ec 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -304,9 +304,6 @@ common_all_c - - common_all_c - common_all_c @@ -412,9 +409,6 @@ common_all_c - - common_all_c - common_all_c @@ -588,9 +582,6 @@ common_h - - common_h - common_h diff --git a/lib_com/ari_hm_fx.c b/lib_com/ari_hm_fx.c index 076bc8d92..46f8ecea1 100644 --- a/lib_com/ari_hm_fx.c +++ b/lib_com/ari_hm_fx.c @@ -10,7 +10,6 @@ #include "basop_util.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) void UnmapIndex( diff --git a/lib_com/arith_coder_fx.c b/lib_com/arith_coder_fx.c index de22a7cf3..846b4dcea 100644 --- a/lib_com/arith_coder_fx.c +++ b/lib_com/arith_coder_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "prot.h" #include "basop_util.h" #include "basop_proto_func.h" #include "cnst.h" diff --git a/lib_com/basop_tcx_utils.c b/lib_com/basop_tcx_utils.c index 378faae0f..8038c4f91 100644 --- a/lib_com/basop_tcx_utils.c +++ b/lib_com/basop_tcx_utils.c @@ -40,7 +40,7 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stl.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #define WMC_TOOL_SKIP diff --git a/lib_com/bitalloc_fx.c b/lib_com/bitalloc_fx.c index 92a8e3928..30ae2d47b 100644 --- a/lib_com/bitalloc_fx.c +++ b/lib_com/bitalloc_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ void bitalloc_fx( Word16 *y, /* i : reordered norm of sub-vectors Q0 */ diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index e5754fa35..9c0a53f8f 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -38,7 +38,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "stat_dec.h" @@ -1884,7 +1883,7 @@ static void decision_matrix_core_dec( * Set up MDCT core switching if indicated in the bitstream *-------------------------------------------------------------------*/ -void mdct_switching_dec( +void mdct_switching_dec_ivas_fx( Decoder_State *st /* i/o: decoder state structure */ ) { diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 1907ef327..38195b65d 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "stat_dec.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_com_fx.h" diff --git a/lib_com/cng_exc.c b/lib_com/cng_exc.c deleted file mode 100644 index 494305e6f..000000000 --- a/lib_com/cng_exc.c +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - -#define A2 0.2f -#define GAIN_VAR 0.000011f - - -/*-------------------------------------------------------* - * cng_params_upd() - * - * update CNG parameters - *-------------------------------------------------------*/ diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common.c index f6da34b55..1ebc2829c 100644 --- a/lib_com/codec_tcx_common.c +++ b/lib_com/codec_tcx_common.c @@ -6,7 +6,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "rom_basop_util.h" diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index fdf935461..ed72605de 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -38,10 +38,9 @@ #include #include "options.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 @@ -551,63 +550,6 @@ int16_t sr2fscale( return (int16_t) ( ( FSCALE_DENOM * sr_core ) / 12800 ); } -/*-------------------------------------------------------------------* - * getCoreSamplerateMode2_flt() - * - * - *-------------------------------------------------------------------*/ - -int32_t getCoreSamplerateMode2_flt( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ -) -{ - int32_t sr_core = 0; - - if ( bwidth == NB ) - { - sr_core = INT_FS_12k8; - } - else if ( element_mode == EVS_MONO && ( ( bwidth == WB && total_brate < ACELP_13k20 ) || ( bwidth == SWB && total_brate <= ACELP_13k20 ) || ( rf_mode == 1 ) ) ) - { - sr_core = INT_FS_12k8; - } - else if ( element_mode > EVS_MONO && flag_ACELP16k == 0 ) - { - sr_core = INT_FS_12k8; - } - else if ( bwidth == WB || ( bwidth == SWB && total_brate <= ACELP_32k ) || ( bwidth == FB && total_brate <= ACELP_32k ) ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE && element_mode == IVAS_SCE && !is_ism_format ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE_ISM && element_mode == IVAS_SCE && is_ism_format ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE && element_mode == IVAS_SCE && is_ism_format ) - { - sr_core = 25600; - } - else if ( ( ( bwidth == SWB || bwidth == FB ) && element_mode == EVS_MONO && total_brate <= HQ_64k ) || ( element_mode > IVAS_SCE && ( ( bwidth == SWB && total_brate <= IVAS_96k ) || ( bwidth == FB && total_brate <= IVAS_96k ) ) ) ) - { - sr_core = 25600; - } - else if ( bwidth == SWB || bwidth == FB ) - { - sr_core = 32000; - } - - return sr_core; -} - Word32 getCoreSamplerateMode2( const Word16 element_mode, /* i : IVAS element mode Q0*/ const Word32 total_brate, /* i : total bitrate Q0*/ diff --git a/lib_com/deemph.c b/lib_com/deemph.c index b2b43cf72..c03a050bc 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -36,9 +36,8 @@ #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" void deemph_fx_32( diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 9e6c450cd..edccca074 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------------- * get_delay() diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index ba0973f97..1a01c2c32 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -36,7 +36,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_com/enr_1_az.c b/lib_com/enr_1_az.c index 81fb78262..5c99cdfa5 100644 --- a/lib_com/enr_1_az.c +++ b/lib_com/enr_1_az.c @@ -37,9 +37,8 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" Word16 Enr_1_Az_fx_o( /* o : impulse response energy Q3 */ diff --git a/lib_com/env_adj.c b/lib_com/env_adj.c index 18520e188..5a83dbe5f 100644 --- a/lib_com/env_adj.c +++ b/lib_com/env_adj.c @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*--------------------------------------------------------------------------* * env_adj() diff --git a/lib_com/env_stab.c b/lib_com/env_stab.c index b80fd0a8b..a3140b4e4 100644 --- a/lib_com/env_stab.c +++ b/lib_com/env_stab.c @@ -39,11 +39,10 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" #include "stl.h" -#include "prot_fx.h" /*--------------------------------------------------------------------------* * Local constants *--------------------------------------------------------------------------*/ diff --git a/lib_com/env_stab_trans.c b/lib_com/env_stab_trans.c index 8c6ec265f..829bef5f4 100644 --- a/lib_com/env_stab_trans.c +++ b/lib_com/env_stab_trans.c @@ -38,10 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*--------------------------------------------------------------------------* * env_stab_transient_detect() * diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index e04a13fdf..78809ed2c 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot.h" #define FFT_SCALING_512 1073741824 // Q22 #define FFT_SCALING_640 1342177280 // Q22 diff --git a/lib_com/fft.c b/lib_com/fft.c index 352a24be9..e262f3909 100644 --- a/lib_com/fft.c +++ b/lib_com/fft.c @@ -39,7 +39,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index acadbb06b..73ff582df 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -44,7 +44,7 @@ #include "options.h" #include #include "cnst.h" -// #include "prot.h" +// #include "prot_fx.h" #include "prot_fx.h" //#include "cnst_fx.h" #include "rom_com.h" diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c index 839b2faaf..1d020cabd 100644 --- a/lib_com/fft_rel.c +++ b/lib_com/fft_rel.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* * Local constants diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index 12ed75f0a..bd9080a7b 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/findpulse.c b/lib_com/findpulse.c index f2347d5b3..68853e061 100644 --- a/lib_com/findpulse.c +++ b/lib_com/findpulse.c @@ -37,10 +37,9 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*----------------------------------------------------------------------------------* * findpulse() diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 41d90359f..1f7c28fd8 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -3,7 +3,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_com/frame_ener_fx.c b/lib_com/frame_ener_fx.c index 4428c0796..68fdf33c3 100644 --- a/lib_com/frame_ener_fx.c +++ b/lib_com/frame_ener_fx.c @@ -38,9 +38,8 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*----------------------------------------------------------------------------------* * fer_energy() * diff --git a/lib_com/get_gain_fx.c b/lib_com/get_gain_fx.c index d4c2413c3..8ec4f5a40 100644 --- a/lib_com/get_gain_fx.c +++ b/lib_com/get_gain_fx.c @@ -36,9 +36,8 @@ #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*----------------------------------------------------------------------------------* * get_gain() diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index eef3d50c6..0921dc88c 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -5,7 +5,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot.h" /* Function prototypes */ #include "assert.h" /* Debug prototypes */ diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c index 9adb448a4..8fa769475 100644 --- a/lib_com/gs_gains.c +++ b/lib_com/gs_gains.c @@ -39,7 +39,6 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index 2e9e5eb96..3b3eaa777 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -39,9 +39,8 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index 9820eb3c8..f5e7105cf 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -37,9 +37,8 @@ #include #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #define HP20_COEFF_SCALE ( 2 ) diff --git a/lib_com/hq2_core_com.c b/lib_com/hq2_core_com.c index bc4edb869..121dae06a 100644 --- a/lib_com/hq2_core_com.c +++ b/lib_com/hq2_core_com.c @@ -39,7 +39,7 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "basop_proto_func.h" #include "wmc_auto.h" diff --git a/lib_com/hq_conf.c b/lib_com/hq_conf.c index c139a493c..90a256cea 100644 --- a/lib_com/hq_conf.c +++ b/lib_com/hq_conf.c @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" void hq_configure_fx( diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index 4426f85d9..cf3ce202e 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -39,7 +39,6 @@ #include "rom_com.h" /* Static table prototypes FIP version */ #include "stl.h" /* required for wmc_tool */ #include "prot_fx.h" -#include "prot.h" #include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* diff --git a/lib_com/ifft_rel.c b/lib_com/ifft_rel.c index 423eea46d..9e64a4e25 100644 --- a/lib_com/ifft_rel.c +++ b/lib_com/ifft_rel.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-----------------------------------------------------------------* * Local constants *-----------------------------------------------------------------*/ diff --git a/lib_com/int_lsp.c b/lib_com/int_lsp.c index 0f673b8fd..570e9ebd9 100644 --- a/lib_com/int_lsp.c +++ b/lib_com/int_lsp.c @@ -37,10 +37,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" void int_lsp_fx( diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum.c index 745ee6ac3..5c4c98e29 100644 --- a/lib_com/interleave_spectrum.c +++ b/lib_com/interleave_spectrum.c @@ -37,10 +37,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/interpol.c b/lib_com/interpol.c index 45021f1c2..a490a7552 100644 --- a/lib_com/interpol.c +++ b/lib_com/interpol.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" -#include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_com/ivas_agc_com_fx.c b/lib_com/ivas_agc_com_fx.c index b2c09fa07..94e6b222f 100644 --- a/lib_com/ivas_agc_com_fx.c +++ b/lib_com/ivas_agc_com_fx.c @@ -38,7 +38,7 @@ #include "ivas_prot_fx.h" #include #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" /*------------------------------------------------------------------------------------------* * Local constants diff --git a/lib_com/ivas_arith_fx.c b/lib_com/ivas_arith_fx.c index 2f729bbd4..006a31177 100644 --- a/lib_com/ivas_arith_fx.c +++ b/lib_com/ivas_arith_fx.c @@ -33,9 +33,8 @@ #include #include "options.h" #include "wmc_auto.h" -#include "prot.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_avq_pos_reorder_com_fx.c b/lib_com/ivas_avq_pos_reorder_com_fx.c index ac539b787..25f8be3ad 100644 --- a/lib_com/ivas_avq_pos_reorder_com_fx.c +++ b/lib_com/ivas_avq_pos_reorder_com_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-----------------------------------------------------------------* diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index 445ea8c78..acc0df821 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "ivas_prot.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 557db9696..9b60b2c5c 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -37,10 +37,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_entropy_coder_common_fx.c b/lib_com/ivas_entropy_coder_common_fx.c index d28828d6f..99381d19a 100644 --- a/lib_com/ivas_entropy_coder_common_fx.c +++ b/lib_com/ivas_entropy_coder_common_fx.c @@ -35,7 +35,7 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_fb_mixer_fx.c b/lib_com/ivas_fb_mixer_fx.c index 43f468fb0..883861024 100644 --- a/lib_com/ivas_fb_mixer_fx.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -34,13 +34,12 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index d3f18a795..f1201b06c 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -35,13 +35,12 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_com/ivas_lfe_com_fx.c b/lib_com/ivas_lfe_com_fx.c index 4d993d64f..7464c41c2 100644 --- a/lib_com/ivas_lfe_com_fx.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -34,7 +34,7 @@ #include "math.h" #include "options.h" #include "ivas_stat_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_masa_com_fx.c b/lib_com/ivas_masa_com_fx.c index 35db926d0..fbe752aad 100644 --- a/lib_com/ivas_masa_com_fx.c +++ b/lib_com/ivas_masa_com_fx.c @@ -34,14 +34,13 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_rom_com_fx.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_com_fx.c b/lib_com/ivas_mc_com_fx.c index 88d6c1b5e..62d623b83 100644 --- a/lib_com/ivas_mc_com_fx.c +++ b/lib_com/ivas_mc_com_fx.c @@ -34,7 +34,7 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_param_com_fx.c b/lib_com/ivas_mc_param_com_fx.c index d69da849a..a54abe7ab 100644 --- a/lib_com/ivas_mc_param_com_fx.c +++ b/lib_com/ivas_mc_param_com_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_com.h" diff --git a/lib_com/ivas_mct_com_fx.c b/lib_com/ivas_mct_com_fx.c index b220d69a7..1f3c58153 100644 --- a/lib_com/ivas_mct_com_fx.c +++ b/lib_com/ivas_mct_com_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com_fx.c b/lib_com/ivas_mdct_core_com_fx.c index a5cfb8673..000f3992f 100644 --- a/lib_com/ivas_mdct_core_com_fx.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -34,9 +34,8 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* diff --git a/lib_com/ivas_mdft_imdft_fx.c b/lib_com/ivas_mdft_imdft_fx.c index 0f24fba81..b10444307 100644 --- a/lib_com/ivas_mdft_imdft_fx.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -33,14 +33,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" #include #include -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_omasa_com_fx.c b/lib_com/ivas_omasa_com_fx.c index eb230b224..ef6350285 100644 --- a/lib_com/ivas_omasa_com_fx.c +++ b/lib_com/ivas_omasa_com_fx.c @@ -35,11 +35,10 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "rom_com.h" #include -#include "prot_fx.h" /*--------------------------------------------------------------- * Local constants diff --git a/lib_com/ivas_pca_tools_fx.c b/lib_com/ivas_pca_tools_fx.c index 5689e81c0..1e36c5e8e 100644 --- a/lib_com/ivas_pca_tools_fx.c +++ b/lib_com/ivas_pca_tools_fx.c @@ -38,7 +38,6 @@ #include #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index cbc67de00..79a585e8b 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -37,10 +37,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 8ef48be2e..5caa850cb 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -37,12 +37,10 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_sba_config_fx.c b/lib_com/ivas_sba_config_fx.c index 94ceb8e3c..38785956c 100644 --- a/lib_com/ivas_sba_config_fx.c +++ b/lib_com/ivas_sba_config_fx.c @@ -37,7 +37,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index 788fb3c56..f35de8eb0 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 0ebae0de6..fc6e60310 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "basop_util.h" #include "ivas_stat_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" diff --git a/lib_com/ivas_spar_com_quant_util_fx.c b/lib_com/ivas_spar_com_quant_util_fx.c index 0f0e003dd..8292de5c1 100644 --- a/lib_com/ivas_spar_com_quant_util_fx.c +++ b/lib_com/ivas_spar_com_quant_util_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "math.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_stereo_dft_com_fx.c b/lib_com/ivas_stereo_dft_com_fx.c index 1157fffcf..80e64c0cc 100644 --- a/lib_com/ivas_stereo_dft_com_fx.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -36,7 +36,7 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c index b4fb66429..d0ffff39c 100644 --- a/lib_com/ivas_stereo_eclvq_com_fx.c +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -37,7 +37,7 @@ #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*--------------------------------------------------------------- diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index 78a3c90ca..9aa880842 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_mdct_bands_com_fx.c b/lib_com/ivas_stereo_mdct_bands_com_fx.c index b1750fd16..c21abcf8c 100644 --- a/lib_com/ivas_stereo_mdct_bands_com_fx.c +++ b/lib_com/ivas_stereo_mdct_bands_com_fx.c @@ -37,9 +37,8 @@ #include "ivas_rom_com.h" #include "ivas_prot.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_com/ivas_stereo_psychlpc_com_fx.c b/lib_com/ivas_stereo_psychlpc_com_fx.c index 996b262db..cb3c39df2 100644 --- a/lib_com/ivas_stereo_psychlpc_com_fx.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_stereo_td_bit_alloc_fx.c b/lib_com/ivas_stereo_td_bit_alloc_fx.c index 14ab8131e..9074473d7 100644 --- a/lib_com/ivas_stereo_td_bit_alloc_fx.c +++ b/lib_com/ivas_stereo_td_bit_alloc_fx.c @@ -38,9 +38,8 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index 9cd1a063e..e460637f7 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -34,11 +34,10 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define ANGLE_90_DEG_Q22 377487360 diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index b5ea507eb..97025b46f 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -34,11 +34,10 @@ #include "options.h" #include "math.h" #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_stat_com.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind.c index e0871fa70..9fb287271 100644 --- a/lib_com/lag_wind.c +++ b/lib_com/lag_wind.c @@ -37,7 +37,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/lerp.c b/lib_com/lerp.c index 28719205a..4e306b936 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -36,154 +36,25 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" - /*-------------------------------------------------------------* * Local function prototypes *-------------------------------------------------------------*/ -static void lerp_proc_flt( const float *f, float *f_out, const int16_t bufferNewSize, const int16_t bufferOldSize ); - - /*-------------------------------------------------------------* * procedure lerp_flt() * * * * * *-------------------------------------------------------------*/ -void lerp_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize_inp ) -{ - float maxFac; - int16_t bufferOldSize, tmpNewSize; - - maxFac = 507.0 / 128.0; - bufferOldSize = bufferOldSize_inp; - - if ( (float) bufferNewSize / bufferOldSize > maxFac ) - { - tmpNewSize = bufferOldSize * 2; - while ( bufferNewSize > bufferOldSize ) - { - if ( (float) bufferNewSize / bufferOldSize <= maxFac ) - { - tmpNewSize = bufferNewSize; - } - - lerp_proc_flt( f, f_out, tmpNewSize, bufferOldSize ); - - f = f_out; - bufferOldSize = tmpNewSize; - tmpNewSize *= 2; - } - } - else if ( (float) bufferOldSize / bufferNewSize > maxFac ) - { - tmpNewSize = bufferOldSize / 2; - while ( bufferNewSize < bufferOldSize ) - { - if ( (float) bufferOldSize / bufferNewSize <= maxFac ) - { - tmpNewSize = bufferNewSize; - } - - lerp_proc_flt( f, f_out, tmpNewSize, bufferOldSize ); - - f = f_out; - bufferOldSize = tmpNewSize; - tmpNewSize /= 2; - } - } - else - { - lerp_proc_flt( f, f_out, bufferNewSize, bufferOldSize ); - } - - return; -} - /*-------------------------------------------------------------* * procedure lerp_proc_flt() * * * * * *-------------------------------------------------------------*/ -static void lerp_proc_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize ) -{ - int16_t i, idx; - float pos, shift, diff; - float buf[2 * L_FRAME_MAX]; - Word16 tmp; - - if ( bufferNewSize == bufferOldSize ) - { - mvr2r( f, buf, bufferNewSize ); - mvr2r( buf, f_out, bufferNewSize ); - return; - } - - /* Using the basop code to avoid reading beyond end of input for bufferOldSize=320, bufferNewSize=640 */ - tmp = div_s( bufferOldSize, shl( bufferNewSize, 4 ) ); - shift = (float) ( L_shl( L_deposit_l( tmp ), 4 - 15 + 16 ) ) / 65536.0f; - pos = 0.5f * shift - 0.5f; - - if ( shift < 0.3f ) - { - pos = pos - 0.13f; - } - - /* first point of interpolation */ - if ( pos < 0 ) - { - buf[0] = f[0] + pos * ( f[1] - f[0] ); - } - else - { - idx = (int16_t) pos; - diff = pos - idx; - buf[0] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - } - - pos += shift; - - for ( i = 1; i < bufferNewSize - 1; i++ ) - { - idx = (int16_t) pos; - diff = pos - idx; - - buf[i] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - pos += shift; - } - - - /* last point */ - idx = (int16_t) pos; - - if ( pos > bufferOldSize - 1 ) - { - idx = bufferOldSize - 2; - } - - diff = pos - idx; - - buf[bufferNewSize - 1] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - - mvr2r( buf, f_out, bufferNewSize ); - - return; -} - - /*-------------------------------------------------------------* * Local constants *-------------------------------------------------------------*/ diff --git a/lib_com/limit_t0.c b/lib_com/limit_t0.c deleted file mode 100644 index d49cad283..000000000 --- a/lib_com/limit_t0.c +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------* - * Local constants - *-------------------------------------------------*/ - -#define LIMIT_PIT_REL_LOWER 2 /* delta interval to extend pitch coding in relative Q */ -#define LIMIT_PIT_REL_UPPER 0 - -/*-------------------------------------------------* - * limit_T0() - * - * Close-loop pitch lag search limitation - *-------------------------------------------------*/ - -void limit_T0( - const int16_t L_frame, /* i : length of the frame */ - const int16_t delta, /* i : Half the close-loop searched interval */ - const int16_t pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ - const int16_t limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) */ - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_max /* o : higher pitch limit */ -) -{ - int16_t delta2, T1; - int16_t pit_min, pit_max; - - if ( limit_flag == 0 ) /* restrained Q limits */ - { - /* set limits */ - if ( L_frame == L_FRAME ) - { - pit_max = PIT_MAX; - pit_min = PIT_MIN; - } - else /* L_frame == L_FRAME16k */ - { - pit_max = PIT16k_MAX; - pit_min = PIT16k_MIN; - } - - delta2 = 2 * delta - 1; - - T1 = T0; - if ( T0_frac >= 2 ) - { - T1++; - } - *T0_min = T1 - delta; - - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_min = *T0_max - delta2; - } - } - else /* extended Q limits */ - { - - /* set limits */ - if ( L_frame == L_FRAME ) - { - pit_max = PIT_MAX; - pit_min = PIT_MIN_EXTEND; - - if ( limit_flag == 2 ) - { - pit_min = PIT_MIN_DOUBLEEXTEND; - } - } - else /* L_frame == L_FRAME16k */ - { - pit_max = PIT16k_MAX; - pit_min = PIT16k_MIN_EXTEND; - } - - delta2 = 2 * delta - 1; - - T1 = T0; - if ( T0_frac >= 2 ) - { - T1++; - } - *T0_min = T1 - delta; - - if ( pit_flag == 0 ) - { - /* subframes with absolute search: keep Q range */ - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_min = *T0_max - delta2; - } - } - else - { - /* subframes with relative search: extend Q range */ - if ( *T0_min < pit_min - LIMIT_PIT_REL_LOWER ) - { - *T0_min = pit_min - LIMIT_PIT_REL_LOWER; - } - - if ( *T0_min < L_INTERPOL ) - { - *T0_min = L_INTERPOL; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max + LIMIT_PIT_REL_UPPER ) - { - *T0_max = pit_max + LIMIT_PIT_REL_UPPER; - *T0_min = *T0_max - delta2; - } - } - } - - return; -} - - -/*-------------------------------------------------* - * Routine limit_T0_voiced_ivas() - * - * Close-loop pitch lag search limitation - *-------------------------------------------------*/ - -void limit_T0_voiced_ivas( - const int16_t nbits, - const int16_t res, - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - const int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_min_frac, /* o : lower pitch limit */ - int16_t *T0_max, /* o : higher pitch limit */ - int16_t *T0_max_frac, /* o : higher pitch limit */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max /* i : Maximum pitch lag */ -) -{ - int16_t T1, temp1, temp2; - - /* Mid-point */ - T1 = T0; - if ( ( T0_res > 1 ) && ( T0_frac >= ( T0_res >> 1 ) ) ) - { - T1++; - } - - /* Lower-bound */ - temp1 = ( T1 * res ) - ( 1 << ( nbits - 1 ) ); - temp2 = temp1 / res; - *T0_min = temp2; - *T0_min_frac = temp1 - temp2 * res; - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - *T0_min_frac = 0; - } - - /* Higher-bound */ - temp1 = ( *T0_min * res ) + *T0_min_frac + ( 1 << nbits ) - 1; - temp2 = temp1 / res; - *T0_max = temp2; - *T0_max_frac = temp1 - temp2 * res; - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_max_frac = res - 1; - temp1 = ( *T0_max * res ) + *T0_max_frac - ( 1 << nbits ) + 1; - temp2 = temp1 / res; - *T0_min = temp2; - *T0_min_frac = temp1 - temp2 * res; - } - - return; -} diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 66c5dd15e..8946e41aa 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -37,10 +37,9 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_com/lsp_conv_poly_fx.c b/lib_com/lsp_conv_poly_fx.c index 61ead2bf2..4f493cacd 100644 --- a/lib_com/lsp_conv_poly_fx.c +++ b/lib_com/lsp_conv_poly_fx.c @@ -6,10 +6,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index 1b2836252..7ed3cb59b 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -38,10 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" void Interpolate_allpass_steep_32( diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 34e2083b9..a15b11611 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -38,10 +38,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index d97830a5f..10e560433 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "stl.h" diff --git a/lib_com/preemph.c b/lib_com/preemph.c index 490a18aef..9ebc0f72a 100644 --- a/lib_com/preemph.c +++ b/lib_com/preemph.c @@ -36,7 +36,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-------------------------------------------------------------* diff --git a/lib_com/prot.h b/lib_com/prot.h deleted file mode 100644 index f5d69075e..000000000 --- a/lib_com/prot.h +++ /dev/null @@ -1,8340 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#ifndef PROT_H -#define PROT_H - -#include -#include -#include -#include "options.h" -#include "typedef.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "stat_com.h" -#include "ivas_stat_com.h" -#include "ivas_stat_enc.h" -#include "ivas_stat_dec.h" -#include "cnst.h" -#include "stl.h" -#include "ivas_error_utils.h" - - -/*----------------------------------------------------------------------------------* - * Prototypes of global macros - *----------------------------------------------------------------------------------*/ - -#ifndef min -#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef max -#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef TRUNC -#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) -#endif - -#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) -#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) - -#ifndef ABSVAL -#define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) -#endif - -#ifndef SQR -#define SQR( a ) ( ( a ) * ( a ) ) -#endif - -#ifndef SWAP -#define SWAP( a, b ) \ - { \ - tempr = ( a ); \ - ( a ) = ( b ); \ - ( b ) = tempr; \ - } -#endif - -#ifndef swap -#define swap( x, y, type ) \ - { \ - type u__p; \ - u__p = x; \ - x = y; \ - y = u__p; \ - } -#endif - -#define set_max( a, b ) \ - { \ - if ( ( b ) > *a ) \ - { \ - *a = ( b ); \ - } \ - } /* If the first argument is already the highes or lowest, nothing is done. */ -#define set_min( a, b ) \ - { \ - if ( ( b ) < *a ) \ - { \ - *a = ( b ); \ - } \ - } /* Otherwise, the 2nd arg is stored at the address of the first arg. */ - - -/*----------------------------------------------------------------------------------* - * MODE1 prototypes - *----------------------------------------------------------------------------------*/ - -/*! r: inverse square root of input value */ -float inv_sqrt( - const float x /* i : input value */ -); - -/*! r: output random value */ -int16_t own_random( - int16_t *seed /* i/o: random seed */ -); - -/*! r: sign of x (+1/-1) */ -float sign( - const float x /* i : input value of x */ -); - -/*! r: logarithm2 of x */ -float log2_f( - const float x /* i : input value of x */ -); - -int16_t norm_ul_float( - uint32_t UL_var1 ); - -/*! r: sum of all vector elements */ -int16_t sum_s( - const int16_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all vector elements */ -float sum_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all squared vector elements */ -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -void set_c( - int8_t y[], /* i/o: Vector to set */ - const int8_t a, /* i : Value to set the vector to */ - const int32_t N /* i : Length of the vector */ -); - -void set_s( - int16_t y[], /* i/o: Vector to set */ - const int16_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ -); - -void set_l( - int32_t y[], /* i/o: Vector to set */ - const int32_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Length of the vector */ -); - -void set_f( - float y[], /* i/o: Vector to set */ - const float a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ -); - -void set_zero_fx( - Word32 *vec, /* o : input vector */ - const Word16 lvec /* i : length of the vector */ -); -void set_zero2_fx( - Word32 *vec, /* o : input vector */ - const Word32 lvec /* i : length of the vector */ -); -void set16_zero_fx( - Word16 *vec, /* o : input vector */ - const Word16 lvec /* i : length of the vector */ -); - -void set_zero( - float *vec, /* o : input vector */ - const int16_t lvec /* i : length of the vector */ -); - -void mvr2r( - const float x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2s( - const int16_t x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvl2l( - const int32_t x[], /* i : input vector */ - int32_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); - -Word16 maximumAbs_l( - const Word32 *vec, /* i : input vector */ - const Word16 lvec, /* i : length of input vector */ - Word32 *max_val /* o : maximum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum_s( - const int16_t *vec, /* i : Input vector */ - const int16_t lvec, /* i : Vector length */ - int16_t *min_val /* o : minimum value in the input vector */ -); - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -); - -/*! r: vector mean */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: dot product of x[] and y[] */ -float dotp( - const float x[], /* i : vector x[] */ - const float y[], /* i : vector y[] */ - const int16_t n /* i : vector length */ -); - -void conv( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response (or second input vector) */ - float y[], /* o : output vetor (result of convolution) */ - const int16_t L /* i : vector size */ -); - -void fir( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response of the FIR filter */ - float y[], /* o : output vector (result of filtering) */ - float mem[], /* i/o: memory of the input signal (M samples) */ - const int16_t L, /* i : input vector size */ - const int16_t K, /* i : order of the FIR filter (M+1 coefs.) */ - const int16_t upd /* i : 1 = update the memory, 0 = not */ -); - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_sub( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 - vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_mult( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 .* vector 2*/ - const int16_t N /* i : Vector length */ -); - -void v_multc( - const float x[], /* i : Input vector */ - const float c, /* i : Constant */ - float y[], /* o : Output vector that contains c*x */ - const int16_t N /* i : Vector length */ -); - -/*! r: index of the winning codeword */ -int16_t squant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float cb[], /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -); - -int16_t squant_int( - uint8_t x, /* i : scalar value to quantize */ - uint8_t *xq, /* o : quantized value */ - const uint8_t *cb, /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: index of the winning codevector */ -int16_t vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: index of the winning codevector */ -int16_t w_vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - const int16_t weights[], /* i : error weights */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize, /* i : codebook size */ - const int16_t reverse /* i : reverse codebook vectors */ -); - -/*! r: index of the winning codeword */ -int16_t usquant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta, /* i : quantization step */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: dequanzited gain */ -float usdequant( - const int16_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ -); - -void v_sort_float( - float *r, /* i/o: Vector to be sorted in place */ - const int16_t lo, /* i : Low limit of sorting range */ - const int16_t up /* i : High limit of sorting range */ -); - -void sort( - uint16_t *x, /* i/o: Vector to be sorted */ - uint16_t len /* i/o: vector length */ -); - -void sort_l( - Word32 *x, /* i/o: Vector to be sorted */ - Word16 len /* i/o: vector length */ -); - -/*! r: variance of vector */ -float var( - const float *x, /* i : input vector */ - const int16_t len /* i : length of inputvector */ -); - -/*! r: standard deviation */ -float std_dev( - const float *x, /* i : input vector */ - const int16_t len /* i : length of the input vector */ -); - -/*! r: the dot product x'*A*x */ -float dot_product_mat( - const float *x, /* i : vector x */ - const float *A, /* i : matrix A */ - const int16_t m /* i : vector length */ -); - -float root_a( - float a ); - -float root_a_over_b( - float a, - float b ); - -void polezero_filter( - const float *in, /* i : input vector */ - float *out, /* o : output vector */ - const int16_t N, /* i : input vector size */ - const float *b, /* i : numerator coefficients */ - const float *a, /* i : denominator coefficients */ - const int16_t order, /* i : filter order */ - float *mem /* i/o: filter memory */ -); - -double rint_new( - double x /* i/o: Round to the nearest integer with mid point exception */ -); - -double anint( - double x /* i/o: Round to the nearest integer */ -); - -/*! r: Output either 1 if Numeric, 0 if NaN or Inf */ -int16_t is_numeric_float( - float x /* i : Input value which is checked if numeric or not */ -); - -void delay_signal_float( - float x[], /* i/o: signal to be delayed */ - const int16_t len, /* i : length of the input signal */ - float mem[], /* i/o: synchronization memory */ - const int16_t delay /* i : delay in samples */ -); - -ivas_error push_indice( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t id, /* i : ID of the indice */ - uint16_t value, /* i : value of the quantized indice */ - int16_t nb_bits /* i : number of bits used to quantize the indice */ -); - -ivas_error push_next_indice( - BSTR_ENC_HANDLE hBstr, - UWord16 value, /* i : value of the quantized indice */ - Word16 nb_bits /* i : number of bits used to quantize the indice */ -); - -ivas_error push_next_bits( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ - const Word16 nb_bits /* i : number of bits to pack */ -); - -/*! r: maximum number of indices */ -Word16 get_ivas_max_num_indices_fx( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -/*! r: maximum number of indices */ -int16_t get_BWE_max_num_indices( - const int32_t extl_brate /* i : extensiona layer bitrate */ -); - -/*! r: maximum number of indices */ -Word16 get_ivas_max_num_indices_metadata_fx( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); -ivas_error ind_list_realloc( - INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ - const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ - Encoder_Struct *st_ivas /* i : IVAS encoder structure */ -); - -ivas_error check_ind_list_limits( - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -); - -void move_indices( - INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ - INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ - const int16_t nb_indices /* i : number of moved indices */ -); - -/*! r: index of the indice in the list, -1 if not found */ -int16_t find_indice( - BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ - const int16_t id, /* i : ID of the indice */ - uint16_t *value, /* o : value of the quantized indice */ - int16_t *nb_bits /* o : number of bits used to quantize the indice */ -); - -/*! r: number of deleted indices */ -uint16_t delete_indice( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t id /* i : ID of the indice */ -); - -/*! r: value of the indice */ -uint16_t get_next_indice( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_next_indice_1( - Decoder_State *st /* i/o: decoder state structure */ -); - -void get_next_indice_tmp( - Decoder_State *st, /* o : decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_indice( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos, /* i : absolute position in the bitstream */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_indice_1( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos /* i : absolute position in the bitstream */ -); - -void reset_indices_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t max_num_indices /* i : max number of indices */ -); - -void reset_indices_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -ivas_error write_indices_ivas( - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - uint16_t *bit_stream, /* i/o: output bitstream */ - uint16_t *num_bits /* i/o: number of bits written to output */ -); - -Word16 rate2EVSmode_float( - const Word32 brate, /* i : bitrate */ - int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ -); - - -/*! r: 1 = OK, 0 = something wrong */ -ivas_error read_indices( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t bit_stream[], /* i : bitstream buffer */ - UWord16 num_bits, /* i : number of bits in bitstream */ - int16_t *prev_ft_speech, - int16_t *CNG, - int16_t bfi /* i : bad frame indicator */ -); - - -void ivas_set_bitstream_pointers( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -Decoder_State **reset_elements( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -void convertSerialToBytestream( - const uint16_t *const serial, /* i : input serial bitstream with values 0 and 1 */ - const uint16_t num_bits, /* i : number of bits in the input bitstream */ - uint8_t *const bytestream /* o : output compact bitstream (bytestream) */ -); - -void convertBytestreamToSerial( - const uint8_t *const bytestream, /* i : input compact bitstream (bytestream) */ - const uint16_t num_bits, /* i : number of bits in the input bitstream */ - uint16_t *const serial /* o : output serial bitstream with values 0 and 1 */ -); - -void mdct_switching_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -void evs_dec_previewFrame_float( - uint8_t *bitstream, /* i : bitstream pointer */ - int16_t bitstreamSize, /* i : bitstream size */ - int16_t *partialCopyFrameType, /* o : frame type of the partial copy */ - int16_t *partialCopyOffset /* o : offset of the partial copy relative to the primary copy */ -); - - -void getPartialCopyInfo_float( - Decoder_State *st, /* i : decoder state structure */ - int16_t *sharpFlag ); - -void get_NextCoderType( - uint8_t *bitstream, /* i : bitstream */ - int16_t *next_coder_type /* o : next coder type */ -); - -int16_t print_disclaimer( - FILE *fPtr ); - - -/*! r: delay value in ns */ -int32_t get_delay( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t io_fs, /* i : input/output sampling frequency */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ -); - -void decision_matrix_enc( - Encoder_State *st, /* i/o: encoder state structure */ - int16_t *hq_core_type /* o : HQ core type */ -); - -void signaling_enc( - Encoder_State *st /* i : encoder state structure */ -); - -int16_t signaling_mode1_tcx20_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t push /* i : flag to push indice */ -); - -void decision_matrix_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *sharpFlag, /* o : formant sharpening flag */ - int16_t *hq_core_type, /* o : HQ core type */ - int16_t *core_switching_flag /* o : ACELP->HQ switching frame flag */ -); - - -void amr_wb_dec_init( - AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ -); - -void hf_synth_amr_wb_init( - AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ -); - -void hf_synth_amr_wb_reset( - AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth_amr_wb( - AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ - ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t output_frame, /* i : output frame length */ - const float *Aq, /* i : quantized Az */ - const float *exc, /* i : excitation at 12.8 kHz */ - float *synth, /* i/o: synthesis signal at 12.8 kHz */ - int16_t *amr_io_class, /* i : signal class (determined by FEC algorithm) */ - float *synth_out, /* i/o: synthesis signal at output Fs */ - float fmerit, /* i : classify parameter from FEC */ - const int16_t *hf_gain, /* i : decoded HF gain */ - const float *voice_factors, /* i : voicing factors */ - const float pitch_buf[], /* i : pitch buffer */ - const float ng_ener_ST, /* i : Noise gate - short-term energy */ - const float *lsf_new /* i : ISF vector */ -); - -void hf_cod_init( - float *mem_hp400_enc, /* o : memory of hp 400 Hz filter */ - float *mem_hf1_enc, /* o : HF band-pass filter memory */ - float *mem_syn_hf_enc, /* o : HF synthesis memory */ - float *mem_hf2_enc, /* o : HF band-pass filter memory */ - float *gain_alpha /* o : smoothing gain for transitions between active and inactive frames */ -); - -void hf_cod( - const int32_t core_brate, /* i : core bitrate */ - const float *speech16k, /* i : original speech at 16 kHz */ - const float Aq[], /* i : quantized Aq */ - const float exc[], /* i : excitation at 12.8 kHz */ - float synth[], /* i : 12.8kHz synthesis signal */ - int16_t *seed2_enc, /* i/o: random seed for HF noise gen */ - float *mem_hp400_enc, /* i/o: memory of hp 400 Hz filter */ - float *mem_syn_hf_enc, /* i/o: HF synthesis memory */ - float *mem_hf1_enc, /* i/o: HF band-pass filter memory */ - float *mem_hf2_enc, /* i/o: HF band-pass filter memory */ - const int16_t *dtxHangoverCount, - float *gain_alpha, /* i/o: smoothing gain for transitions between active and inactive frames */ - int16_t *hf_gain /* o : HF gain to be transmitted to decoder */ -); - -void hf_synth_init( - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth_reset( - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth( - ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t output_frame, /* i : output frame length */ - const float *Aq, /* i : quantized Az */ - const float *exc, /* i : excitation at 12.8 kHz */ - float *synth, /* i/o: 12.8kHz synthesis signal */ - float *synth16k /* i/o: 16kHz synthesis signal */ -); - -void fft_rel( - float x[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ -); - -void ifft_rel( - float io[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ -); - -void preemph( - float *signal, /* i/o: signal */ - const float mu, /* i : preemphasis factor */ - const int16_t L, /* i : vector size */ - float *mem /* i/o: memory (x[-1]) */ -); -void preemph_ivas_fx( - Word32 *signal, /* i/o: signal Qx*/ - const Word16 mu, /* i : preemphasis factor Q15*/ - const Word16 L, /* i : vector size Q0*/ - Word32 *mem /* i/o: memory (x[-1]) Qx*/ -); - -void cb_shape( - const int16_t preemphFlag, /* i : flag for pre-emphasis */ - const int16_t pitchFlag, /* i : flag for pitch sharpening */ - const int16_t scramblingFlag, /* i : flag for phase scrambling */ - const int16_t formantFlag, /* i : flag for formant sharpening */ - const int16_t formantTiltFlag, /* i : flag for formant tilt */ - const float g1, /* i : formant sharpening numerator weighting */ - const float g2, /* i : formant sharpening denominator weighting */ - const float *p_Aq, /* i : LP filter coefficients */ - float *code, /* i/o: signal to shape */ - const float tilt_code, /* i : tilt of code */ - const float pt_pitch, /* i : pointer to current subframe fractional pitch*/ - const int16_t L_subfr /* i : subfframe length */ -); - -void CNG_exc( - const int32_t core_brate, /* i : core bitrate */ - const int16_t L_frame, /* i : length of the frame */ - float *Enew, /* i/o: decoded SID energy */ - int16_t *seed, /* i/o: random generator seed */ - float exc[], /* o : current non-enhanced excitation */ - float exc2[], /* o : current enhanced excitation */ - float *lp_ener, /* i/o: LP filtered E */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - int16_t *first_CNG, /* i/o: first CNG frame flag for energy init. */ - int16_t *cng_ener_seed, /* i/o: random generator seed for CNG energy */ - float bwe_exc[], /* o : excitation for SWB TBE */ - const int16_t allow_cn_step, /* i : allow CN step */ - int16_t *last_allow_cn_step, /* i/o: last CN_step */ - const int16_t num_ho, /* i : number of selected hangover frames */ - float q_env[], - float *lp_env, - float *old_env, - float *exc_mem, - float *exc_mem1, - int16_t *sid_bw, - int16_t *cng_ener_seed1, - float exc3[], - const int16_t Opt_AMR_WB, /* i : AMR-WB interop flag */ - const int16_t element_mode /* i : IVAS Element mode */ -); - - -void cng_params_postupd( - const int16_t ho_circ_ptr, /* i : pointer for CNG averaging buffers */ - int16_t *cng_buf_cnt, /* i/o: counter for CNG store buffers */ - const float *cng_exc2_buf, /* i : Excitation buffer */ - const int32_t *cng_brate_buf, /* i : bitrate buffer */ - float ho_env_circ[], /* i/o: Envelope buffer */ - const int16_t element_mode, /* i : Element mode */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void calculate_hangover_attenuation_gain( - Encoder_State *st, /* i : encoder state structure */ - float *att, /* o : attenuation factor */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -int16_t get_cng_mode_ivas( - const int32_t last_active_brate /* i : last active bitrate */ -); - -void disf_ns_28b( - int16_t *indice, /* i : quantized indices, use indice[0] = -1 in the decoder*/ - float *isf_q /* o : ISF in the frequency domain (0..6400) */ -); - -void limit_T0( - const int16_t L_frame, /* i : length of the frame */ - const int16_t delta, /* i : Half the close-loop searched interval */ - const int16_t pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ - const int16_t limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_max /* o : higher pitch limit */ -); - -/*! r: interpolated value */ -float interpolation( - const float *x, /* i : input vector */ - const float *win, /* i : interpolation window */ - const int16_t frac, /* i : fraction */ - const int16_t up_samp, /* i : upsampling factor */ - const int16_t nb_coef /* i : nb of filter coef */ -); - -void deemph( - float *signal, /* i/o: signal */ - const float mu, /* i : deemphasis factor */ - const int16_t L, /* i : vector size */ - float *mem /* i/o: memory (y[-1]) */ -); - -void weight_a( - const float *a, /* i : LP filter coefficients */ - float *ap, /* o : weighted LP filter coefficients */ - const float gamma, /* i : weighting factor */ - const int16_t m /* i : order of LP filter */ -); - -void weight_a_subfr( - const int16_t nb_subfr, /* i : number of subframes */ - const float *a, /* i : LP filter coefficients */ - float *ap, /* o : weighted LP filter coefficients */ - const float gamma, /* i : weighting factor */ - const int16_t m /* i : order of LP filter */ -); - -void syn_12k8( - const int16_t L_frame, /* i : length of the frame */ - const float *Aq, /* i : LP filter coefficients */ - const float *exc, /* i : input signal */ - float *synth, /* o : output signal */ - float *mem, /* i/o: initial filter states */ - const int16_t update_m /* i : update memory flag: 0 --> no memory update */ -); /* 1 --> update of memory */ - -void syn_filt( - const float a[], /* i : LP filter coefficients */ - const int16_t m, /* i : order of LP filter */ - const float x[], /* i : input signal */ - float y[], /* o : output signal */ - const int16_t l, /* i : size of filtering */ - float mem[], /* i/o: initial filter states */ - const int16_t update_m /* i : update memory flag: 0 --> no memory update */ -); /* 1 --> update of memory */ - -void synth_mem_updt2_flt( - const int16_t L_frame, /* i : frame length */ - const int16_t last_L_frame, /* i : frame length */ - float old_exc[], /* i/o: excitation buffer */ - float mem_syn_r[], /* i/o: synthesis filter memory */ - float mem_syn2[], /* o : synthesis filter memory for find_target */ - float mem_syn[], /* o : synthesis filter memory for find_target */ - const int16_t dec /* i : flag for decoder indication */ -); - -void int_lsp( - const int16_t L_frame, /* i : length of the frame */ - const float lsp_old[], /* i : LSPs from past frame */ - const float lsp_new[], /* i : LSPs from present frame */ - float *Aq, /* o : LP coefficients in both subframes */ - const int16_t m, /* i : order of LP filter */ - const float *int_coeffs, /* i : interpolation coefficients */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - -void int_lsp4( - const int16_t L_frame, /* i : length of the frame */ - const float lsp_old[], /* i : previous end-frame LSPs */ - const float lsp_mid[], /* i : current mid-frame LSPs */ - const float lsp_new[], /* i : current end-frame LSPs */ - float *Aq, /* o : LP coefficients in both subframes */ - const int16_t m, /* i : order of LP filter */ - int16_t relax_prev_lsf_interp /* i : relax prev frame lsf interp after erasure */ -); - -/*! r: length of output */ -int16_t modify_Fs( - const float sigIn[], /* i : signal to decimate */ - const int16_t lg, /* i : length of input */ - const int32_t fin, /* i : frequency of input */ - float sigOut[], /* o : decimated signal */ - const int32_t fout, /* i : frequency of output */ - float mem[], /* i/o: filter memory */ - const int16_t nblp /* i : flag indicating if NB low-pass is applied */ -); - -void pred_lt4_flt( - const float excI[], /* i : input excitation buffer */ - float excO[], /* o : output excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const int16_t L_subfr, /* i : subframe size */ - const float *win, /* i : interpolation window */ - const int16_t nb_coef, /* i : nb of filter coef */ - const int16_t up_sample /* i : up_sample */ -); - -void pred_lt4_tc_flt( - float exc[], /* i : excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const float *win, /* i : interpolation window */ - const int16_t imp_pos, /* i : glottal impulse position */ - const int16_t i_subfr /* i : subframe index */ -); - -void residu( - const float *a, /* i : LP filter coefficients */ - const int16_t m, /* i : order of LP filter */ - const float *x, /* i : input signal (usually speech) */ - float *y, /* o : output signal (usually residual) */ - const int16_t l /* i : size of filtering */ -); - -void calc_residu( - const float *speech, /* i : weighted speech signal */ - float *res, /* o : residual signal */ - const float *p_Aq, /* i : quantized LP filter coefficients */ - const int16_t L_frame /* i : size of frame */ -); - -/*! r: impulse response energy */ -float enr_1_Az( - const float Aq[], /* i : LP filter coefs */ - const int16_t len /* i : impulse response length */ -); - -void Es_pred_enc( - float *Es_pred, /* o : predicited scaled innovation energy */ - int16_t *Es_pred_indice, /* o : indice corresponding to above parameter */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : length of the subframe */ - const float *res, /* i : residual signal */ - const float *voicing, /* i : normal. correlattion in three 1/2frames */ - const int16_t nb_bits, /* i : allocated number of bits */ - const int16_t no_ltp /* i : no_ltp flag */ -); - -void create_offset( - UWord32 *offset_scale1, - UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ); - -float mslvq( - float *pTmp, /* i : M-dimensional input vector */ - float *quant, /* o : quantized vector */ - float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - int16_t *idx_lead, /* o : leader index for each 8-dim subvector */ - int16_t *idx_scale, /* o : scale index for each subvector */ - const float *w, /* i : weights for LSF quantization */ - const int16_t mode, /* i : number indicating the coding mode */ - const int16_t mode_glb, /* i : LVQ coding mode */ - const int16_t pred_flag /* i : prediction flag (0: safety net, 1 - predictive )*/ -); - -void permute( - float *pTmp1, /* i/o: vector whose components are to be permuted */ - const int16_t *perm /* i : permutation info (indexes that should be interchanged), max two perms */ -); - -void sort_desc_ind( - float *s, - const int16_t len, - int16_t *ind ); - -float mslvq_cng( - int16_t idx_cv, /* i : index of cv from previous stage */ - float *pTmp, /* i : 16 dimensional input vector */ - float *quant, /* o : quantized vector */ - float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - int16_t *idx_lead, /* o : leader index for each 8-dim subvector */ - int16_t *idx_scale, /* o : scale index for each subvector */ - const float *w /* i : weights for LSF quantization */ -); - -int16_t deindex_lvq_cng( - int16_t *index, /* i : index to be decoded, as an array of 3 short */ - float *x_lvq, /* o : decoded codevector */ - const int16_t idx_cv, /* i : relative mode_lvq, wrt START_CNG */ - const int16_t no_bits /* i : number of bits for lattice */ -); - -void multiply32_32_64( - UWord32 x, /* i : operand 1 */ - UWord32 y, /* i : operand 2 */ - UWord32 *res /* o : result as array of two uint32 */ -); - -int16_t deindex_lvq( - int16_t *index, /* i : index to be decoded, as an array of 3 short */ - float *x_lvq, /* o : decoded codevector */ - const int16_t mode, /* i : LVQ coding mode (select scales & no_lead ), or idx_cv */ - const int16_t sf_flag, /* i : safety net flag */ - const int16_t no_bits /* i : number of bits for lattice */ -); - -void index_lvq( - float *quant, /* i : codevector to be indexed (2 8-dim subvectors) */ - int16_t *idx_lead, /* i : leader class index for each subvector */ - int16_t *idx_scale, /* i : scale index for each subvector */ - const int16_t mode, /* i : integer signaling the quantizer structure for the current bitrate */ - int16_t *index, /* o : encoded index (represented on 3 short each with 15 bits ) */ - const int16_t prediction_flag /* i : predictive mode or not */ -); - -int16_t qlsf_ARSN_tcvq_Dec_16k( - float *y, /* o : Quantized LSF vector */ - int16_t *indice, /* i : Indices */ - const int16_t nBits /* i : number of bits */ -); - - -int16_t lsf_bctcvq_decprm_ivas( - Decoder_State *st, - int16_t *param_lpc ); - - -void disf_2s_36b( - int16_t *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */ - float *isf_q, /* o : quantized ISFs in the cosine domain */ - float *mem_AR, /* i/o: quantizer memory for AR model */ - float *mem_MA /* i/o: quantizer memory for MA model */ -); - -void disf_2s_46b( - int16_t *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */ - float *isf_q, /* o : quantized ISFs in the cosine domain */ - float *mem_AR, /* o : quantizer memory for AR model */ - float *mem_MA /* i/o: quantizer memory for MA model */ -); - -void re8_k2y( - const int16_t *k, /* i : Voronoi index k[0..7] */ - const int16_t m, /* i : Voronoi modulo (m = 2^r = 1<=2) */ - int16_t *y /* o : 8-dimensional point y[0..7] in RE8 */ -); - -void re8_PPV( - const float x[], /* i : point in R^8 */ - int16_t y[] /* o : point in RE8 (8-dimensional integer vector) */ -); - -void enhancer( - const int16_t codec_mode, /* i : flag indicating Codec Mode */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t cbk_index, /* i : */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t coder_type, /* i : coding type */ - const int16_t L_frame, /* i : frame size */ - const float voice_fac, /* i : subframe voicing estimation */ - const float stab_fac, /* i : LP filter stablility measure */ - const float norm_gain_code, /* i : normalized innovative cb. gain */ - const float gain_inov, /* i : gain of the unscaled innovation */ - float *gc_threshold, /* i/o: code threshold */ - float *code, /* i/o: innovation */ - float *exc2, /* i/o: adapt. excitation/total exc. */ - const float gain_pit, /* i : Quantized pitch gain */ - float *dispMem /* i/o: Phase dispersion algorithm memory */ -); - -void phase_dispersion_flt( - const float gain_code, /* i : gain of code */ - const float gain_pit, /* i : gain of pitch */ - float code[], /* i/o: code vector */ - const int16_t mode, /* i : level, 0=hi, 1=lo, 2=off */ - float disp_mem[] /* i/o: static memory (size = 8) */ -); - -void re8_vor( - int16_t y[], /* i : point in RE8 (8-dimensional integer vector) */ - int16_t *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */ - int16_t k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4 */ - int16_t c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */ - int16_t *ka /* o : identifier of absolute leader (needed to index c)*/ -); - -void DoRTFT480( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT320( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT160( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT128( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT120( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT80( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT20( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT40( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFTn( - float *x, /* i/o: real part of input and output data */ - float *y, /* i/o: imaginary part of input and output data */ - const int16_t n /* i : size of the FFT n=(2^k) up to 1024 */ -); - -void BASOP_cfft_ivas( - Word32 *re, /* i/o: real part */ - Word32 *im, /* i/o: imag part */ - Word16 s, /* i : stride real and imag part */ - Word16 *scale /* i : scalefactor */ -); - -void fft( - float *re, /* i/o: real part */ - float *im, /* i/o: imag part */ - const int16_t length, /* i : length of fft */ - const int16_t s /* i : sign */ -); - -void rfft( - float *x, /* i/o: values */ - const float *w, /* i : window */ - const int16_t length, /* i : length of fft */ - const int16_t isign /* i : sign */ -); - -void sinq( - const float tmp, /* i : sinus factor cos(tmp*i+phi) */ - const float phi, /* i : sinus phase cos(tmp*i+phi) */ - const int16_t N, /* i : size of output */ - float x[] /* o : output vector */ -); - -void edct2( - const int16_t n, - const int16_t isgn, - float *in, - float *a, - const int16_t *ip, - const float *w ); - -void stat_noise_uv_mod( - const int16_t coder_type, /* i : coder type */ - float noisiness, /* i : noisiness parameter */ - const float *const lsp_old, /* i : old LSP vector at 4th sfr */ - const float *const lsp_new, /* i : LSP vector at 4th sfr */ - const float *const lsp_mid, /* i : LSP vector at 2nd sfr */ - float *Aq, /* o : A(z) quantized for the 4 subframes */ - float *exc2, /* o : excitation buffer */ - const int16_t bfi, /* i : bad frame indicator */ - float *ge_sm, /* i/o: smoothed excitation gain */ - int16_t *uv_count, /* i/o: unvoiced counter */ - int16_t *act_count, /* i/o: activation counter */ - float lspold_s[], /* i/o: old LSP */ - int16_t *noimix_seed, /* i/o: mixture seed */ - float *st_min_alpha, /* i/o: minimum alpha */ - float *exc_pe, /* i/o: memory of the preemphasis filter */ - const int32_t bitrate, /* i : core bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void limit_band_noise_level_calc( - const int16_t *wnorm, /* i : reordered norm of sub-vectors */ - int16_t *limit, /* o : highest band of bit allocation */ - const int32_t core_brate, /* i : core bitrate */ - float *noise_level /* o : noise level */ -); - -/*! r: hqswb_clas */ -int16_t peak_avrg_ratio( - const int32_t total_brate, /* i : total bitrate */ - const float *input_hi, /* i : input signal */ - const int16_t N, /* i : number of coefficients */ - int16_t *mode_count, /* i/o: HQ_HARMONIC mode count */ - int16_t *mode_count1 /* i/o: HQ_NORMAL mode count */ -); - -/*! r: Number of coefficients in nf codebook */ -int16_t build_nf_codebook( - const int16_t flag_32K_env_ho, /* i : Envelope attenuation hangover flag */ - const float *coeff, /* i : Coded spectral coefficients */ - const int16_t *sfm_start, /* i : Subband start indices */ - const int16_t *sfmsize, /* i : Subband widths */ - const int16_t *sfm_end, /* i : Subband end indices */ - const int16_t nb_sfm, /* i : Last coded band */ - const int16_t *R, /* i : Per-band bit allocation */ - float *CodeBook, /* o : Noise-fill codebook */ - float *CodeBook_mod /* o : Densified noise-fill codebook */ -); - -void apply_noisefill_HQ( - const int16_t *R, /* i : bit allocation */ - const int16_t length, /* i : input frame length */ - const int16_t flag_32K_env_ho, /* i : envelope stability hangover flag */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t last_sfm, /* i : last coded subband */ - const float *CodeBook, /* i : Noise-fill codebook */ - const float *CodeBook_mod, /* i : Densified noise-fill codebook */ - const int16_t cb_size, /* i : Codebook length */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : Subband band width */ - float *coeff /* i/o: coded/noisefilled spectrum */ -); - -void harm_bwe_fine( - const int16_t *R, /* i : bit allocation */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t high_sfm, /* i : higher transition band to BWE */ - const int16_t num_sfm, /* i : total number of bands */ - const int16_t *norm, /* i : quantization indices for norms */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - float *coeff, /* i/o: coded/noisefilled normalized spectrum */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - float *coeff_fine /* o : BWE fine structure */ -); - -void hvq_bwe_fine( - const int16_t last_sfm, /* i : last coded subband */ - const int16_t num_sfm, /* i : total number of bands */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *peak_idx, /* i : Peak index */ - const int16_t Npeaks, /* i : Number of peaks */ - int16_t *peak_pos, /* i/o: Peak positions */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - float *coeff, /* i/o: coded/noisefilled normalized spectrum */ - int16_t *bwe_peaks, /* o : Positions of peaks in BWE */ - float *coeff_fine /* o : HVQ BWE fine structure */ -); - -void hq_fold_bwe( - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t num_sfm, /* i : Number of subbands */ - float *coeff /* i/o: coded/noisefilled normalized spectrum */ -); - -void apply_nf_gain( - const int16_t nf_idx, /* i : noise fill gain index */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *R, /* i : bit allocation */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - float *coeff /* i/o: coded/noisefilled normalized spectrum */ - -); - -void hq_generic_fine( - float *coeff, /* i : coded/noisefilled normalized spectrum */ - const int16_t last_sfm, /* i : Last coded band */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out1 /* o : HQ GENERIC input */ -); - -void harm_bwe( - const float *coeff_fine, /* i : fine structure for BWE */ - const float *coeff, /* i : coded/noisefilled normalized spectrum */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t high_sfm, /* i : higher transition band to BWE */ - const int16_t *R, /* i : bit allocation */ - const int16_t prev_hq_mode, /* i : previous hq mode */ - int16_t *norm, /* i/o: quantization indices for norms */ - float *noise_level, /* i/o: noise levels for harmonic modes */ - float *prev_noise_level, /* i/o: noise factor in previous frame */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - const int16_t element_mode /* i : element mode */ -); - -void hvq_bwe( - const float *coeff, /* i : coded/noisefilled spectrum */ - const float *coeff_fine, /* i : BWE fine structure */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfm_len, /* i : Subband length */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t prev_hq_mode, /* i : previous hq mode */ - const int16_t *bwe_peaks, /* i : HVQ bwe peaks */ - const int16_t bin_th, /* i : HVQ transition bin */ - const int16_t num_sfm, /* i : Number of bands */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t *R, /* i : Bit allocation */ - int16_t *norm, /* i/o: quantization indices for norms */ - float *noise_level, /* i/o: noise levels for harmonic modes */ - float *prev_noise_level, /* i/o: noise factor in previous frame */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out /* o : coded/noisefilled spectrum */ -); - -void hvq_concat_bands( - const int16_t pvq_bands, /* i : Number of bands in concatenated PVQ target */ - const int16_t *sel_bnds, /* i : Array of selected high bands */ - const int16_t n_sel_bnds, /* i : Number of selected high bands */ - int16_t *hvq_band_start, /* o : Band start indices */ - int16_t *hvq_band_width, /* o : Band widths */ - int16_t *hvq_band_end /* o : Band end indices */ -); - -void hq_generic_bwe( - const int16_t HQ_mode, /* i : HQ mode */ - float *coeff_out1, /* i/o: BWE input & temporary buffer */ - const float *hq_generic_fenv, /* i : SWB frequency envelopes */ - float *coeff_out, /* o : SWB signal in MDCT domain */ - const int16_t hq_generic_offset, /* i : frequency offset for representing hq generic*/ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - const int16_t hq_generic_exc_clas, /* i : hq generic hf excitation class */ - const int16_t *sfm_end, /* i : End of bands */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t num_env_bands, /* i : Number of coded envelope bands */ - const int16_t *R /* i : Bit allocation */ -); - -void map_hq_generic_fenv_norm( - const int16_t hqswb_clas, /* i : signal classification flag */ - const float *hq_generic_fenv, /* i : HQ GENERIC envelope */ - int16_t *ynrm, /* o : high band norm indices */ - int16_t *normqlg2, /* o : high band norm values */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t hq_generic_offset /* i : Freq offset for HQ GENERIC */ -); - -/*! r: Number of bits consumed for the delta coding */ -int16_t calc_nor_delta_hf( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *t_audio, /* i : transform-domain coefficients */ - int16_t *ynrm, /* i/o: norm indices */ - int16_t *Rsubband, /* i/o: sub-band bit allocation */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t *sfmsize, /* i : band length */ - const int16_t *sfm_start, /* i : Start index of bands */ - const int16_t core_sfm /* i : index of the end band for core */ -); - -/*! r: Number of bits consumed for the delta coding */ -int16_t get_nor_delta_hf( - Decoder_State *st, /* i/o: Decoder state */ - int16_t *ynrm, /* i/o: norm indices */ - int16_t *Rsubband, /* i/o: sub-band bit allocation */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t core_sfm ); /* i : index of the end band for core */ - -void hq_wb_nf_bwe( - const float *coeff, /* i : coded/noisefilled normal. spectrum */ - const int16_t is_transient, /* i : is transient flag */ - const int16_t prev_bfi, /* i : previous bad frame indicator */ - const float *normq_v, /* i : norms */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : Subband band width */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *R, /* i : bit allocation */ - const int16_t prev_is_transient, /* i : previous transient flag */ - float *prev_normq, /* i/o: previous norms */ - float *prev_env, /* i/o: previous noise envelopes */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */ - int16_t *prev_R, /* i/o: previous frame bit allocation info. */ - float *coeff_out /* o : coded/noisefilled spectrum */ -); - -/*! r: Number of bits */ -int16_t encode_envelope_indices( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t numnrmibits, /* i : Bitrate of fall-back coding mode */ - int16_t *difidx, /* i/o: Diff indices/encoded diff indices */ - int16_t *LCmode, /* o : Coding mode */ - const int16_t flag_pack, /* i : indicator of packing or estimating bits */ - const int16_t flag_HQ2, /* i : indicator of HQ2 core */ - const int16_t is_transient /* i : transient flag */ -); - -void diff_envelope_coding( - const int16_t is_transient, /* i : transient indicator */ - const int16_t num_env_bands, /* i : number of envelope bands to code */ - const int16_t start_norm, /* i : start of envelope coding */ - int16_t *ynrm, /* i/o: quantization indices for norms */ - int16_t *normqlg2, /* i/o: quantized norms */ - int16_t *difidx /* o : differential code */ -); - -/*! r: Number of bits */ -int16_t decode_envelope_indices( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t start_norm, /* i : First SDE encoded norm */ - const int16_t num_sfm, /* i : Number of norms */ - const int16_t numnrmibits, /* i : Bitrate of fall-back coding mode */ - int16_t *ynrm, /* o : Decoded norm indices */ - const int16_t flag_HQ2, /* i : indicator of HQ2 core */ - const int16_t is_transient /* i : transient flag */ -); - -/*! r: Number of bits */ -void dequantize_norms( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t start_norm, /* i : First SDE encoded norm */ - const int16_t num_sfm, /* i : Number of norms */ - const int16_t is_transient, /* i : Transient flag */ - int16_t *ynrm, /* o : Decoded norm indices */ - int16_t *normqlg2 /* o : Log2 of decoded norms */ -); - -void hq_configure( - const int16_t length, /* i : Frame length */ - const int16_t hqswb_clas, /* i : HQ SWB class */ - const int32_t core_brate, /* i : core bitrate */ - int16_t *num_sfm, /* o : Total number of subbands */ - int16_t *nb_sfm, /* o : Total number of coded bands */ - int16_t *start_norm, /* o : First norm to be SDE encoded */ - int16_t *num_sde_norm, /* o : Number of norms for SDE encoding */ - int16_t *numnrmibits, /* o : Number of bits in fall-back norm encoding */ - int16_t *hq_generic_offset, /* o : Freq offset for HQ GENERIC */ - int16_t *sfmsize, /* o : Subband bandwidths */ - int16_t *sfm_start, /* o : Subband start coefficients */ - int16_t *sfm_end /* o : Subband end coefficients */ -); - -/*! r: Consumed bits */ -int16_t hvq_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t hvq_bits, /* i : HVQ bit budget */ - const int16_t Npeaks, /* i : Number of peaks */ - const int16_t *ynrm, /* i : Envelope coefficients */ - int16_t *R, /* i/o: Bit allocation/updated bit allocation */ - int16_t *peaks, /* i/o: Peak pos. / Encoded peak pos. */ - float *nf_gains, /* i/o: Noise fill gains / Quant. nf gains */ - float *noise_level, /* o : Quantized noise level */ - const float *pe_gains, /* i : Peak gains */ - const float *coefs, /* i : spectrum coefficients */ - float *coefs_out /* o : encoded spectrum coefficients */ -); -/*! r: Consumed bits */ -int16_t hq_classifier_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t length, /* i : Frame length */ - int16_t *is_transient, /* o : Transient flag */ - int16_t *hqswb_clas /* o : HQ class */ -); - -void hq_bit_allocation( - const int32_t core_brate, /* i : Core bitrate */ - const int16_t length, /* i : Frame length */ - const int16_t hqswb_clas, /* i : HQ class */ - int16_t *num_bits, /* i/o: Remaining bit budget */ - const int16_t *normqlg2, /* i : Quantized norms */ - const int16_t nb_sfm, /* i : Number sub bands to be encoded */ - const int16_t *sfmsize, /* i : Sub band bandwidths */ - float *noise_level, /* o : HVQ noise level */ - int16_t *R, /* o : Bit allocation per sub band */ - int16_t *Rsubband, /* o : Fractional bit allocation (Q3) */ - int16_t *sum, /* o : Sum of allocated shape bits */ - int16_t *core_sfm, /* o : Last coded band in core */ - const int16_t num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ -); - -void enforce_zero_for_min_envelope( - const int16_t hqswb_clas, /* i : HQ coding class */ - const int16_t *ynrm, /* i : Envelope indices */ - float *coefsq, /* i/o: Quantized spectrum/zeroed spectrum */ - int16_t nb_sfm, /* i : Number of coded sub bands */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end /* i : Sub band end indices */ -); - -void apply_envelope( - const float *coeff, /* i/o: Coded/noisefilled normalized spectrum */ - const int16_t *norm, /* i : Envelope */ - const float *norm_adj, /* i : Envelope adjustment */ - const int16_t num_sfm, /* i : Total number of bands */ - const int16_t last_sfm, /* i : Last coded band */ - const int16_t HQ_mode, /* i : HQ mode */ - const int16_t length, /* i : Frame length */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end, /* i : Sub band end indices */ - float *normq_v, /* o : Envelope with adjustment */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - float *coeff_out1 /* o : noisefilled spectrum for HQ SWB BWE */ -); - -void apply_envelope_enc( - float *coeff, /* i/o: Normalized/scaled normalized spectrum */ - const int16_t *norm, /* i : Envelope */ - const int16_t num_sfm, /* i : Total number of bands */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end /* i : Sub band end indices */ -); - -/*! r: Leading_sign_index, index, size, k_val */ -PvqEntry mpvq_encode_vec( - const int16_t *vec_in, /* i : Signed pulse train */ - const int16_t dim_in, /* i : Dimension */ - int16_t k_val_local /* i/o: Num unit pulses */ -); - -/*! r: Size, dim, k_val */ -PvqEntry get_size_mpvq_calc_offset( - const int16_t dim_in, /* i : Dimension */ - const int16_t k_val_in, /* i : Num unit pulses */ - uint32_t *h_mem /* o : Offsets */ -); - -void mpvq_decode_vec( - const PvqEntry *entry, /* i : Sign_ind, index, dim, k_val */ - uint32_t *h_mem, /* i : A/U offsets */ - int16_t *vec_out /* o : Pulse train */ -); - -/*! r: Multiplication result */ -uint32_t UMult_32_32( - const uint32_t UL_var1, /* i : factor 1 */ - const uint32_t UL_var2 /* i : factor 2 */ -); - -/*! r: inverse */ -uint32_t UL_inverse_float( - const uint32_t UL_val, /* i : input value Q_exp */ - int16_t *exp /* i/o: input exp / result exp */ -); - -/*! r: ratio */ -Word16 ratio_float( - const Word32 numer, /* i : numerator */ - const Word32 denom, /* i : denominator */ - Word16 *expo /* i/o: input exp / result exp */ -); - -/*! r: Angle between 0 and EVS_PI/2 radian (Q14) */ -Word16 atan2_fx_flt( - const Word32 y, /* i : near side (Argument must be positive) (Q15) */ - const Word32 x /* i : opposite side (Q15) */ -); - -void pvq_encode_frame( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *coefs_norm, /* i : normalized coefficients to encode */ - float *coefs_quant, /* o : quantized coefficients */ - float *gopt, /* o : optimal shape gains */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *pulse_vector, /* o : non-normalized pulse shapes */ - const int16_t *sfm_start, /* i : indices of first coefficients in the bands */ - const int16_t *sfm_end, /* i : indices of last coefficients in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - const int16_t nb_sfm, /* i : total number of bands */ - const int16_t *R, /* i : bitallocation per band (Q3) */ - const int16_t pvq_bits, /* i : number of bits avaiable */ - const int16_t core /* i : core */ -); - -void pvq_decode_frame( - Decoder_State *st, /* i/o: Decoder state */ - float *coefs_quant, /* o : quantized coefficients */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *pulse_vector, /* o : non-normalized pulse shapes */ - const int16_t *sfm_start, /* i : indices of first coeffs in the bands */ - const int16_t *sfm_end, /* i : indices of last coeffs in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - const int16_t nb_sfm, /* i : total number of bands */ - const int16_t *R, /* i : bitallocation per band (Q3) */ - const int16_t pvq_bits, /* i : number of bits avaiable */ - const int16_t core /* i : core */ -); - -void srt_vec_ind( - const int16_t *linear, /* linear input */ - int16_t *srt, /* sorted output */ - int16_t *I, /* index for sorted output */ - const int16_t length ); - -void srt_vec_ind_f( - const float *linear, /* linear input */ - float *srt, /* sorted output */ - int16_t *I, /* index for sorted output */ - const int16_t length /* length of vector */ -); - -/*! r: floor(sqrt(input)) */ -uint32_t floor_sqrt_exact( - const uint32_t input /* i : unsigned input [0.. UINT_MAX/4] */ -); - -void fine_gain_quant( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t *ord, /* i : Indices for energy order */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t *gain_bits, /* i : Gain adjustment bits per sub band */ - float *fg_pred, /* i/o: Predicted gains / Corrected gains */ - const float *gopt /* i : Optimal gains */ -); - -void apply_gain( - const int16_t *ord, /* i : Indices for energy order */ - const int16_t *band_start, /* i : Sub band start indices */ - const int16_t *band_end, /* i : Sub band end indices */ - const int16_t num_sfm, /* i : Number of bands */ - const float *gains, /* i : Band gain vector */ - float *xq /* i/o: float synthesis / gain adjusted synth */ -); - -void fine_gain_pred( - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end, /* i : Sub band end indices */ - const int16_t *sfm_size, /* i : Sub band bandwidths */ - const int16_t *i_sort, /* i : Energy sorting indices */ - const int16_t *K, /* i : Number of pulses per band */ - const int16_t *maxpulse, /* i : Maximum pulse per band */ - const int16_t *R, /* i : Bits per sub band (Q3) */ - const int16_t num_sfm, /* i : Number of sub bands */ - float *xq, /* i/o: Quantized vector /quantized vector with finegain adj */ - int16_t *y, /* i/o: Quantized vector */ - float *fg_pred, /* o : Predicted fine gains */ - const int16_t core /* i : Core */ -); - -void fine_gain_dec( - Decoder_State *st, /* i/o: Decoder state struct */ - const int16_t *ord, /* i : Indices for energy order */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t *gain_bits, /* i : Gain adjustment bits per sub band */ - float *fg_pred /* i/o: Predicted gains / Corrected gains */ -); - -void get_max_pulses( - const int16_t *band_start, /* i : Sub band start indices */ - const int16_t *band_end, /* i : Sub band end indices */ - const int16_t *k_sort, /* i : Indices for sorting by energy */ - const int16_t *npulses, /* i : Pulses per sub band */ - const int16_t BANDS, /* i : Number of bands */ - int16_t *inp_vector, /* i/o: Encoded shape vectors */ - int16_t *maxpulse /* o : Maximum pulse height per band */ -); - -Word32 ar_div_ivas( - Word32 num, - Word32 denum ); - -void ar_encoder_start( - PARCODEC arInst, - TCQ_PBITSTREAM bsInst, - int16_t max_bits ); - -void ar_decoder_start( - PARCODEC arInst, - TCQ_PBITSTREAM bsInst ); - -void ar_encoder_done( - PARCODEC arInst ); - -void ar_decoder_done( - PARCODEC arInst ); - - -Word32 Mult_32_16( - Word32 a, - Word16 b ); - -Word32 Mult_32_32( - Word32 a, - Word32 b ); - - -void decode_mangitude_tcq_fx_ivas( - ARCODEC *pardec, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *positions, - Word32 *out, - Word32 *surplus_fx ); - -void decode_signs_fx_ivas( - ARCODEC *pardec, - Word16 size, - Word32 *out ); - -void srt_vec_ind_fx_ivas( - const Word32 *linear, - Word32 *srt, - Word16 *I, - Word16 length ); - - -void bit_allocation_second_fx2( - Word32 *Rk, - Word32 *Rk_sort, - Word16 BANDS, - const Word16 *band_width, - Word16 *k_sort, - Word16 *k_num, - const Word16 *p2a_flags, - const Word16 p2a_bands, - const Word16 *last_bitalloc, - const Word16 input_frame ); - - -Word32 encode_magnitude_tcq_fx_ivas( - ARCODEC *parenc, - float *magn_fx, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *savedstates, - Word32 *est_frame_bits_fx ); - -Word32 encode_signs_fx_ivas( - ARCODEC *parenc, - float *magn, - Word16 size, - Word16 npos, - Word32 *est_frame_bits_fx ); - -Word32 encode_magnitude_usq_fx_ivas( - ARCODEC *parenc, - float *magn_fx, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *est_frame_bits_fx ); - -ivas_error tcq_core_LR_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int32_t inp_vector[], - const float coefs_norm[], - float coefs_quant[], - const int16_t bit_budget, /* number of bits */ - const int16_t nb_sfm, - const int16_t *sfm_start, - const int16_t *sfm_end, - const int16_t *sfmsize, - Word32 *Rk_fx, - int16_t *npulses, - int16_t *k_sort, - const int16_t *p2a_flags, - const int16_t p2a_bands, - const int16_t *last_bitalloc, - const int16_t input_frame, - const int16_t adjustFlag, - const int16_t is_transient ); - -void tcq_core_LR_dec( - Decoder_State *st, - int32_t *inp_vector, - const int16_t bit_budget, - const int16_t bands, - const int16_t *band_start, - const int16_t *band_width, - Word32 *Rk_fx, - int16_t npulses[], - int16_t *k_sort, - const int16_t *p2a_flags, - const int16_t p2a_bands, - const int16_t *last_bitalloc, - const int16_t input_frame, - const int16_t adjustFlag, - const int16_t *is_transient ); - - -void TCQLSB( - int16_t bcount, - float *abuffer, - float *mbuffer, - float *sbuffer, - int16_t *dpath ); - -void RestoreTCQ( - float *magn, - int16_t size, - int16_t *bcount, - float *mbuffer ); - -void SaveTCQdata( - PARCODEC arInst, - int16_t *dpath, - int16_t bcount ); - -void LoadTCQdata( - PARCODEC arInst, - int16_t *dpath, - int16_t bcount ); - -void RestoreTCQdec( - int32_t *magn, - int16_t size, - int16_t *bcount, - float *mbuffer ); - -void TCQLSBdec( - int16_t *dpath, - float *mbuffer, - int16_t bcount ); - -void bit_allocation_second_fx2( - Word32 *Rk, - Word32 *Rk_sort, - Word16 BANDS, - const Word16 *band_width, - Word16 *k_sort, - Word16 *k_num, - const Word16 *p2a_flags, - const Word16 p2a_bands, - const Word16 *last_bitalloc, - const Word16 input_frame ); - -void io_ini_enc( - const int32_t argc, /* i : command line arguments number */ - char *argv[], /* i : command line arguments */ - FILE **f_input, /* o : input signal file */ - FILE **f_stream, /* o : output bitstream file */ - FILE **f_rate, /* o : bitrate switching profile (0 if N/A) */ - FILE **f_bwidth, /* o : bandwidth switching profile (0 if N/A) */ - FILE **f_metadata, /* o : metadata files (NULL if N/A) */ -#ifdef DEBUGGING - FILE **f_force, /* o : force switching profile (0 if N/A) */ -#endif - FILE **f_rf, /* o : channel aware configuration file */ - int16_t *quietMode, /* o : limit printouts */ - int16_t *noDelayCmp, /* o : turn off delay compensation */ - Encoder_Struct *st /* o : IVAS encoder structure */ -); - -void read_next_rfparam( - int16_t *rf_fec_offset, /* o : RF offset */ - int16_t *rf_fec_indicator, /* o : RF FEC indicator */ - FILE *f_rf /* i : file pointer to read parameters */ -); - -void read_next_brate( - int32_t *total_brate, /* i/o: total bitrate */ - const int32_t last_total_brate, /* i : last total bitrate */ - FILE *f_rate, /* i : bitrate switching profile (0 if N/A) */ - const int16_t element_mode, /* i : IVAS element mode */ - int32_t input_Fs, /* i : input sampling frequency */ - int16_t *Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - int16_t *Opt_SC_VBR, /* i/o: SC-VBR flag */ - int16_t *codec_mode /* i/o: Mode 1 or 2 */ -); - -void read_next_bwidth( - int16_t *max_bwidth, /* i/o: maximum encoded bandwidth */ - FILE *f_bwidth, /* i : bandwidth switching profile (0 if N/A) */ - int32_t *bwidth_profile_cnt, /* i/o: counter of frames for bandwidth switching profile file */ - int32_t input_Fs /* i : input sampling rate */ -); - -#ifdef DEBUGGING -void read_next_force( - int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ - FILE *f_force, /* i : force switching profile (0 if N/A) */ - int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ -); -#endif - -ivas_error init_encoder_ivas_fx( - Encoder_State *st, /* i/o: state structure */ - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - const Word16 idchan, /* i : channel ID */ - const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ - const Word16 interval_SID, /* i : interval for SID update */ - const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const Word32 element_brate /* i : element bitrate */ -); - -void LPDmem_enc_init( - LPD_state_HANDLE hLPDmem /* i/o: LP memories */ -); - -ivas_error evs_enc( - Encoder_State *st, /* i/o: state structure */ - const int16_t *data, /* i : input signal */ - float *mem_hp20_in, /* i/o: hp20 filter memory */ - const int16_t n_samples /* i : number of input samples */ -); -void amr_wb_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t *data, /* i : input signal */ - float *mem_hp20_in, /* i/o: hp20 filter memory */ - const int16_t n_samples /* i : number of input samples */ -); - -void sc_vbr_enc_init( - SC_VBR_ENC_HANDLE hSC_VBR /* i/o: SC-VBR encoder handle */ -); - -void amr_wb_enc_init( - AMRWB_IO_ENC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO encoder handle */ -); - -void pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t input_frame, /* i : frame length */ - float old_inp_12k8[], /* i/o: buffer of old input signal */ - float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ - float **inp, /* o : ptr. to inp. signal in the current frame*/ - float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ - float *ener, /* o : residual energy from Levinson-Durbin */ - int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ - float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - float epsP[M + 1], /* i/o: LP prediction errors */ - float lsp_new[M], /* i/o: LSPs at the end of the frame */ - float lsp_mid[M], /* i/o: LSPs in the middle of the frame */ - int16_t *vad_hover_flag, /* i : VAD hangover flag */ - int16_t *attack_flag, /* o : attack flag */ - float *new_inp_resamp16k, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - int16_t *Voicing_flag, /* o : voicing flag for HQ FEC */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - int16_t *hq_core_type /* o : HQ core type */ -); - - -/*! r: HQ_CORE/TCX_20_CORE decision */ -int16_t mdct_classifier( - Encoder_State *st, /* i/o: Encoder state variable */ - const float *fft_buff, /* i : FFT spectrum from fft_rel */ - const float enerBuffer[], /* i : energy buffer */ - const int32_t brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ -); - -void MDCT_selector( - Encoder_State *st, /* i/o: Encoder State */ - const float sp_floor, /* i : Noise floor estimate */ - const float Etot, /* i : Total energy */ - const float cor_map_sum, /* i : sum of correlation map */ - const float enerBuffer[] /* i : energy buffer */ -); - -ivas_error acelp_core_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 inp[], /* i : input signal of the current frame Q_new*/ - Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ - Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ - const Word32 epsP[M + 1], /* i : LP prediction errors Qx*/ - Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ - Word16 lsp_mid[M], /* i : LSPs in the middle of the frame Q15*/ - const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ - const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ - Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ - Word16 *voice_factors_fx, /* o : voicing factors Q15*/ - Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn_12k8_16*/ - Word16 *q_old_syn_12k8_16, - Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ - Word16 *unbits, /* o : number of unused bits Q0*/ - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ - Word16 Q_new ); - -ivas_error acelp_core_switch_dec_bfi( - Decoder_State *st /* i/o: decoder state structure */ -); - -void acelp_core_switch_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float inp12k8[], /* i : input signal @12.8 kHz */ - const float inp16k[], /* i : input signal @16 kHz */ - const float A[NB_SUBFR16k * ( M + 1 )] /* i : A(z) unquantized for the 4 subframes */ -); - -/*! r: length of output */ -int16_t modify_Fs_intcub3m_sup( - const float sigIn[], /* i : signal to decimate with memory of 2 samples (indexes -2 & -1) */ - const int16_t lg, /* i : length of input */ - const int32_t fin, /* i : frequency of input */ - float sigOut[], /* o : decimated signal */ - const int32_t fout, /* i : frequency of output */ - int16_t *delayout /* o : delay of output */ -); - -void core_switching_OLA( - const float *mem_over_hp, /* i : upsampling filter memory */ - const int16_t last_L_frame, /* i : last L_frame lengthture */ - const int32_t output_Fs, /* i : output sampling rate */ - float *synth, /* i/o: synthesized signal from HQ core */ - const float *synth_subfr_out, /* i : synthesized signal from ACELP core */ - float *synth_subfr_bwe, /* i : synthesized BWE from ACELP core */ - const int16_t output_frame, /* i : output frame length */ - const int16_t bwidth /* i : output bandwidth */ -); - -void retro_interp4_5( - const float *syn, - float *pst_old_syn ); - -void retro_interp5_4( - float *pst_old_syn ); -void core_switching_hq_prepare_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *num_bits, /* i/o: bit budget update */ - const int16_t input_frame /* i : input frame length */ -); - -ivas_error acelp_core_switch_dec( - Decoder_State *st, /* i/o: decoder structure */ - float *synth_subfr_out, /* o : synthesized ACELP subframe */ - float *tmp_synth_bwe, /* o : synthesized ACELP subframe BWE */ - const int16_t output_frame, /* i : input frame length */ - const int16_t core_switching_flag, /* i : core switching flag */ - float *mem_synth, /* o : synthesis to overlap */ - const int16_t nchan_out /* i : number of output channels */ -); - -void ResetSHBbuffer_Enc( - TD_BWE_ENC_HANDLE hBWE_TD /* i/o: TD BWE data handle */ -); - -void ResetSHBbuffer_Dec( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t extl /* i : BWE extension layer */ -); - -void calc_st_filt( - const float *apond2, /* i : coefficients of numerator */ - const float *apond1, /* i : coefficients of denominator */ - float *parcor0, /* o : 1st parcor calcul. on composed filter */ - float *sig_ltp_ptr, /* i/o: input of 1/A(gamma1) : scaled by 1/g0 */ - float *mem_zero, /* i/o: All zero memory */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - - -void scale_st_ivas( - const float *sig_in, /* i : postfilter input signal */ - float *sig_out, /* i/o: postfilter output signal */ - float *gain_prec, /* i/o: last value of gain for subframe */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - -void filt_mu( - const float *sig_in, /* i : signal (beginning at sample -1) */ - float *sig_out, /* o : output signal */ - const float parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - -void PostShortTerm( - float *sig_in, /* i : input signal (ptr. to current subframe */ - float *lpccoeff, /* i : LPC coefficients for current subframe */ - float *sig_out, /* o : postfiltered output */ - float *mem_stp, /* i/o: postfilter memory */ - float *ptr_mem_stp, /* i/o: pointer to postfilter memory */ - float *ptr_gain_prec, /* i/o: for gain adjustment */ - float *mem_zero, /* i/o: null memory to compute h_st */ - const float formant_fac /* i : Strength of post-filter [0,1] */ -); - -/*! r: Formant filter strength [0,1] */ -float swb_formant_fac( - const float lpc_shb2, /* i : 2nd HB LPC coefficient */ - float *tilt_mem /* i/o: Tilt smoothing memory */ -); - -void GenShapedSHBExcitation( - float *excSHB, /* o : synthesized shaped shb exctiation */ - const float *lpc_shb, /* i : lpc coefficients */ - float *exc16kWhtnd, /* o : whitened synthesized shb excitation */ - float *mem_csfilt, /* i/o: memory */ - float *mem_genSHBexc_filt_down_shb, /* i/o: memory */ - float *state_lpc_syn, /* i/o: memory */ - const int16_t coder_type, /* i : coding type */ - const float *bwe_exc_extended, /* i : bandwidth extended excitation */ - int16_t bwe_seed[], /* i/o: random number generator seed */ - float voice_factors[], /* i : voicing factor */ - const int16_t extl, /* i : extension layer */ - float *tbe_demph, /* i/o: de-emphasis memory */ - float *tbe_premph, /* i/o: pre-emphasis memory */ - float *lpc_shb_sf, /* i : LP coefficients */ - float *shb_ener_sf, /* i : SHB subframe energies */ - float *shb_res_gshape, /* i : SHB LP residual gain shape */ - float *shb_res, /* i : SHB residual used in encoder only */ - int16_t *vf_ind, /* i/o: Mixing factor index */ - const float formant_fac, /* i : Formant sharpening factor [0..1] */ - float fb_state_lpc_syn[], /* i/o: memory */ - float *fb_tbe_demph, /* i/o: fb de-emphasis memory */ - const int32_t total_brate, /* i : overall bitrate */ - const int16_t prev_bfi, /* i : previous frame was lost flag */ - const int16_t element_mode, /* i : element mode */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - float *nlExc16k, /* i/o: NL exc for IC-BWE */ - float *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const int32_t extl_brate, /* i : TD BWE bitrate */ - const int16_t MSFlag, /* i : Multi-source flag */ - float EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - float *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - float *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - float *Env_error, /* o : error in SHB residual envelope modelling*/ - float Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -); - -void GenSHBSynth( - const float *shb_target_speech, /* i : input synthesized speech */ - float *shb_syn_speech_32k, /* o : output highband component */ - float Hilbert_Mem[], /* i/o: memory */ - float state_lsyn_filt_shb_local[], /* i/o: memory */ - const int16_t L_frame, /* i : ACELP Frame length */ - int16_t *syn_dm_phase ); - -void ScaleShapedSHB( - const int16_t length, /* i : SHB overlap length */ - float *synSHB, /* i/o: synthesized shb signal */ - float *overlap, /* i/o: buffer for overlap-add */ - const float *subgain, /* i : subframe gain */ - const float frame_gain, /* i : frame gain */ - const float *win, /* i : window */ - const float *subwin /* i : subframes window */ -); - -void Interpolate_allpass_steep( - const float *in, /* i : input array of size N */ - float *mem, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - float *out /* o : output array of size 2*N */ -); - -void Decimate_allpass_steep( - const float *in, /* i : input array of size N */ - float *mem, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - float *out /* o : output array of size N/2 */ -); - -void interpolate_3_over_2_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem /* i/o: memory */ -); - -void decimate_2_over_3_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem, /* i/o: memory */ - float *lp_mem ); - -void interpolate_3_over_1_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem /* i/o: memory */ -); - -void InitSWBencBuffer( - TD_BWE_ENC_HANDLE hBWE_TD /* i/o: TD BWE data handle */ -); - -void InitSWBencBufferStates( - TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *shb_speech /* o : SHB target signal (6-14kHz) at 16kHz */ -); - -void swb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - STEREO_ICBWE_ENC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const float *new_speech, /* i : original input signal */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - float *White_exc16k, /* o : shaped white excitation for the FB TBE */ - const float pitch_buf[] /* i : pitch for each subframe */ -); - -void swb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - const float old_syn_12k8_16k[], /* i : low band synthesis at 12.8kHz or 16kHz */ - float *White_exc16k, /* o : shaped white excitation for the FB TBE */ - float *synth, /* i/o: ACELP core synthesis/final synthesis */ - float *pitch_buf ); - -void flip_and_downmix_generic( - float input[], /* i : input spectrum */ - float output[], /* o : output spectrum */ - const int16_t length, /* i : length of spectra */ - float mem1_ext[HILBERT_ORDER1], /* i/o: Hilbert filter memory */ - float mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory */ - float mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory */ - int16_t *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -); -void flip_and_downmix_generic_fx_32( - Word32 input[], /* i : input spectrum Qx*/ - Word32 output[], /* o : output spectrum Qx*/ - const Word16 length, /* i : length of spectra */ - Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ - Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -); -void non_linearity( - const float input[], /* i : input signal */ - float output[], /* i : output signal */ - float old_bwe_exc_extended[], /* i/o: memory bugffer */ - const int16_t length, /* i : input length */ - float *prev_scale, /* i/o: memory */ - const int16_t coder_type, /* i : Coder Type */ - const float *voice_factors, /* i : Voice Factors */ - const int16_t L_frame /* i : ACELP frame length */ -); - -void interp_code_5over2( - const float inp_code[], /* i : input vector */ - float interp_code[], /* o : output vector */ - const int16_t inp_length /* i : length of the input vector */ -); - -void interp_code_4over2( - const float inp_code[], /* i : input vector */ - float interp_code[], /* o : output vector */ - const int16_t inp_length /* i : length of the input vector */ -); - -void flip_spectrum_and_decimby4( - const float input[], /* i : input spectrum */ - float output[], /* o : output spectrum */ - const int16_t length, /* i : vector length */ - float mem1[], /* i/o: memory */ - float mem2[], /* i/o: memory */ - const int16_t ramp_flag /* i : flag to trigger slow ramp-up of output */ -); - -void GenShapedWBExcitation( - float *excSHB, /* o : synthesized shaped shb exctiation */ - const float *lpc_shb, /* i : lpc coefficients */ - float *exc4kWhtnd, /* o : whitened synthesized shb excitation */ - float *mem_csfilt, /* i/o: memory */ - float *mem_genSHBexc_filt_down1, /* i/o: memory */ - float *mem_genSHBexc_filt_down2, /* i/o: memory */ - float *mem_genSHBexc_filt_down3, /* i/o: memory */ - float *state_lpc_syn, /* i/o: memory */ - const int16_t coder_type, /* i : coding type */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - int16_t bwe_seed[], /* i/o: random number generator seed */ - const float voice_factors[], /* i : voicing factor */ - const int16_t uv_flag, /* i : unvoiced flag */ - const int16_t igf_flag ); - -void GenWBSynth( - const float *input_synspeech, /* i : input synthesized speech */ - float *shb_syn_speech_16k, /* o : output highband compnent */ - float *state_lsyn_filt_shb1, /* i/o: memory */ - float *state_lsyn_filt_shb2 /* i/o: memory */ -); - -void wb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *hb_speech, /* i : HB target signal (6-8kHz) at 16kHz */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float pitch_buf[], /* i : pitch for each subframe */ - const float voicing[] /* o : OL maximum normalized correlation */ -); - -void wb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - float *synth /* i/o: ACELP core synthesis/final synthesis */ -); - -void tbe_write_bitstream( - Encoder_State *st /* i/o: encoder state structure */ -); - -void tbe_read_bitstream( - Decoder_State *st /* i/o: decoder state structure */ -); - -void GenTransition( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *outputHB, /* o : synthesized HB transitions signal */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t element_mode, /* i : element mode */ - const int16_t L_frame, /* i : ACELP frame length */ - const int16_t rf_flag, /* i : RF flag */ - const int32_t total_brate /* i : total bitrate */ -); - - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ); - -void GenTransition_WB( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *outputHB, /* o : synthesized HB transitions signal */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -); - -void td_bwe_dec_init( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t extl, /* i : BWE extension layer */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void TBEreset_enc( - TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t last_core, /* i : last core */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void TBEreset_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -/*! r: TBE bit consumption per frame */ -int16_t get_tbe_bits( - const int32_t total_brate, /* i : overall bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t rf_mode /* i : channel aware mode */ -); - -void fb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float new_input[], /* i : input speech at 48 kHz sample rate */ - const float fb_exc[] /* i : FB excitation from the SWB part */ -); - -void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* i/o: high-band synthesis */ - float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ - const int16_t output_frame /* i : output frame length */ -); - -void calc_tilt_bwe( - const float *sp, /* i : input signal */ - float *tilt, /* o : signal tilt */ - const int16_t N /* i : signal length */ -); - -void fd_bwe_enc_init( - FD_BWE_ENC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -); - -void swb_pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - float *new_swb_speech, /* o : original input signal at 32kHz */ - float *shb_speech, /* o : SHB target signal (6-14kHz) at 16kHz */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : imag buffer */ - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ -); - -void wb_pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const float *new_inp_resamp16k, /* i : original input signal */ - float *hb_speech /* o : HB target signal (6-8kHz) at 16kHz */ -); - -void wb_bwe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_wb_speech /* i : original input signal at 16kHz */ -); - -void wb_bwe_dec_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const float output[], /* i : synthesis @internal Fs */ - float *synth, /* i/o: ACELP core synthesis/final synthesis */ - float *hb_synth, /* o : SHB synthesis/final synthesis */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const float voice_factors[], /* i : voicing factors */ - const float pitch_buf[] /* i : pitch buffer */ -); - -void swb_bwe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const float *old_input_12k8, /* i : input signal @12.8kHz for SWB BWE */ - const float *old_input_16k, /* i : input signal @16kHz for SWB BWE */ - const float *old_syn_12k8_16k, /* i : ACELP core synthesis at 12.8kHz or 16kHz*/ - const float *new_swb_speech, /* i : original input signal at 32kHz */ - const float *shb_speech /* i : SHB target signal (6-14kHz) at 16kHz */ -); - -void swb_bwe_enc_hr( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_input, /* i : input signal */ - const int16_t input_frame, /* i : frame length */ - const int16_t unbits /* i : number of core unused bits */ -); - -void fd_bwe_dec_init_flt( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -); - -void swb_bwe_dec_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const float output[], /* i : synthesis @internal Fs */ - const float *synth, /* i : ACELP core synthesis/final synthesis */ - float *hb_synth, /* o : SHB synthesis/final synthesis */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame /* i : frame length */ -); - -void hr_bwe_dec_init_flt( - HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ -); - -void swb_bwe_dec_hr( - Decoder_State *st, /* i/o: decoder state structure */ - const float *syn_12k8_16k, /* i : ACELP core synthesis @16kHz */ - float *hb_synth, /* o : SHB synthesis */ - const int16_t output_frame, /* i : frame length */ - const int16_t unbits, /* i : number of core unused bits */ - const float pitch_buf[] /* i : pitch buffer */ -); - - -void calc_normal_length( - const int16_t core, /* i : core */ - const float *sp, /* i : input signal */ - const int16_t mode, /* i : input mode */ - const int16_t extl, /* i : extension layer */ - int16_t *L_swb_norm, /* o : normalize length */ - int16_t *prev_L_swb_norm /* i/o: last normalize length */ -); - -void calc_norm_envelop( - const float SWB_signal[], /* i : SWB spectrum */ - float *envelope, /* o : normalized envelope */ - const int16_t L_swb_norm, /* i : length of envelope */ - const int16_t SWB_flength, /* i : Length of input/output */ - const int16_t st_offset /* i : offset */ -); - -void time_envelop_shaping( - float werr[], /* i/o: SHB synthesis */ - float SWB_tenv[], /* i/o: frequency envelope */ - const int16_t L /* i : frame length */ -); - -void time_reduce_pre_echo( - const float *synth, /* i : ACELP core synthesis */ - float *error, /* o : SHB BWE synthesis */ - float prev_td_energy, /* o : last td energy */ - const int16_t L /* i : subframe length */ -); - -int16_t WB_BWE_gain_pred( - float *WB_fenv, /* o : WB frequency envelopes */ - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - const int16_t coder_type, /* i : coding type */ - const int16_t prev_code_type, /* i : coding type of last frame */ - const float prev_WB_fenv, /* i : envelope for last frame */ - const float voice_factors[], /* i : voicing factors */ - const float pitch_buf[], /* i : pitch buffer */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - const float last_wb_bwe_ener, /* i : previous frame wb bwe signal energy */ - const int16_t last_extl, /* i : extl. layer for last frame */ - const float tilt ); - -void WB_BWE_decoding( - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - float *WB_fenv, /* i : WB frequency envelopes */ - float *WB_signal, /* o : WB signal in MDCT domain */ - const int16_t WB_flength, /* i : Length of input/output */ - const int16_t mode, /* i : classification for WB signal */ - const int16_t last_extl, /* i : extl. layer for last frame */ - float *prev_Energy, /* i/o: energy for last frame */ - float *prev_WB_fenv, /* i/o: envelope for last frame */ - int16_t *prev_L_wb_norm, /* i/o: length for last frame wb norm */ - const int16_t extl, /* i : extension layer */ - const int16_t coder_type, /* i : coding type */ - const int32_t total_brate, /* i : core layer bitrate */ - int16_t *Seed, /* i/o: random generator seed */ - int16_t *prev_flag, /* i/o: attenu flag of last frame */ - int16_t prev_coder_type /* i : coding type of last frame */ -); - -void SWB_BWE_decoding( - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - float *SWB_fenv, /* i/o: SWB frequency envelopes */ - float *SWB_signal, /* o : SWB signal in MDCT domain */ - const int16_t SWB_flength, /* i : Length of input/output */ - const int16_t mode, /* i : classification for SWB signal */ - int16_t *frica_flag, /* o : fricative signal flag */ - float *prev_Energy, /* i/o: energy for last frame */ - float *prev_SWB_fenv, /* i/o: envelope for last frame */ - int16_t *prev_L_swb_norm, /* i/o: length for last frame wb norm */ - const float tilt_nb, /* i : tilt of synthesis wb signal */ - int16_t *Seed, /* i/o: random generator seed */ - const int16_t st_offset, /* i : offset value due to different core */ - float *prev_weight, /* i/o: excitation weight value of last frame */ - const int16_t extl, /* i : extension layer */ - const int16_t last_extl /* i : extension layer of last frame */ -); - -void CNG_reset_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors, /* o : voicing factors */ - int16_t VBR_cng_reset_flag ); - -/*! r: stability flag */ -uint16_t a2rc( - const float *a, /* i : LPC coefficients */ - float *refl, /* o : Reflection co-efficients */ - const int16_t lpcorder /* i : LPC order */ -); - - -void analy_sp( - const int16_t element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int32_t input_Fs, /* i : input sampling rate */ - float *speech, /* i : speech buffer */ - float *Bin_E, /* o : per bin log energy spectrum */ - float *Bin_E_old, /* o : per bin log energy spectrum for mid-frame */ - float *fr_bands, /* o : per band energy spectrum (2 analyses) */ - float lf_E[], /* o : per bin E for first VOIC_BINS bins (without DC) */ - float *Etot, /* o : total input energy */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *band_ener, /* o : energy in critical frequency bands without minimum noise floor E_MIN */ - float *PS, /* o : Per bin energy spectrum */ - float *fft_buff /* o : FFT coefficients */ -); - -void CNG_enc( - Encoder_State *st, /* i/o: State structure */ - float Aq[], /* o : LP coefficients */ - const float *speech, /* i : pointer to current frame input speech buffer */ - float enr, /* i : frame energy output from Levinson recursion */ - const float *lsp_mid, /* i : mid frame LSPs */ - float *lsp_new, /* i/o: current frame LSPs */ - float *lsf_new, /* i/o: current frame LSFs */ - int16_t *allow_cn_step, /* o : allow CN step */ - float *q_env, - int16_t *sid_bw ); - -void swb_CNG_enc( - Encoder_State *st, /* i/o: State structure */ - const float *shb_speech, /* i : SHB target signal (6-14kHz) at 16kHz */ - const float *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz */ -); - -void lsf_enc( - Encoder_State *st, /* i/o: state structure */ - float *lsf_new, /* o : quantized LSF vector */ - float *lsp_new, /* i/o: LSP vector to quantize/quantized */ - float *lsp_mid, /* i : mid-frame LSP vector */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const int16_t GSC_IVAS_mode, /* i : GSC IVAS mode */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void isf_enc_amr_wb( - Encoder_State *st, /* i/o: state structure */ - float *isf_new, /* o : quantized ISF vector */ - float *isp_new, /* i/o: ISP vector to quantize/quantized */ - float *Aq /* o : quantized A(z) for 4 subframes */ -); - -void find_targets( - const float *speech, /* i : pointer to the speech frame */ - const float *mem_syn, /* i : memory of the synthesis filter */ - const int16_t i_subfr, /* i : subframe index */ - float *mem_w0, /* i/o: weighting filter denominator memory */ - const float *p_Aq, /* i : interpolated quantized A(z) filter */ - const float *res, /* i : residual signal */ - const int16_t L_subfr, /* i : length of vectors for gain quantization */ - const float *Ap, /* i : unquantized A(z) filter with bandwidth expansion */ - const float tilt_fac, /* i : tilt factor */ - float *xn, /* o : Close-loop Pitch search target vector */ - float *cn, /* o : target vector in residual domain */ - float *h1 /* o : impulse response of weighted synthesis filter */ -); - -Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ - const Word16 pos1, /* i: position of the pulse 1 */ - const Word16 pos2, /* i: position of the pulse 2 */ - const Word16 N /* i: number of bits FOR position */ -); -void find_tilt( - const float fr_bands[], /* i : energy in frequency bands */ - const float bckr[], /* i : per band background noise energy estimate */ - float ee[2], /* o : lf/hf E ration for present frame */ - const int16_t pitch[3], /* i : open loop pitch values for 3 half-frames */ - const float voicing[3], /* i : normalized correlation for 3 half-frames */ - const float *lf_E, /* i : per bin energy for low frequencies */ - const float corr_shift, /* i : normalized correlation correction */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t max_band, /* i : maximum critical band */ - float hp_E[], /* o : energy in HF */ - const int16_t codec_mode, /* i : Mode 1 or 2 */ - float *bckr_tilt_lt, /* i/o: lf/hf E ratio of background noise */ - int16_t Opt_vbr_mode ); - -void init_gp_clip( - float mem[] /* o : memory of gain of pitch clipping algorithm */ -); - -int16_t gp_clip( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float *voicing, /* i : normalized correlations (from OL pitch) */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t coder_type, /* i : coding type */ - const float xn[], /* i : target vector */ - float mem[] /* i/o: memory of gain of pitch clipping algorithm */ -); - -void gp_clip_test_lsf( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float lsf[], /* i : LSF vector */ - float mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - -void gp_clip_test_gain_pit( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float gain_pit, /* i : gain of quantized pitch */ - float mem[] /* i/o: memory of gain of pitch clipping algorithm */ -); - -void analy_lp( - const float speech[], /* i : pointer to the denoised speech frame */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_look, /* i : look-ahead length */ - float *ener, /* o : residual signal energy */ - float A[], /* o : A(z) filter coefficients */ - float epsP[], /* o : LP analysis residual energies for each iteration */ - float lsp_new[], /* o : current frame ISPs */ - float lsp_mid[], /* o : current mid-frame ISPs */ - float lsp_old[], /* i/o: previous frame unquantized ISPs */ - const int16_t Top[2], /* i : open loop pitch lag */ - const float Tnc[2], /* i : open loop pitch gain */ - const int32_t sr_core, /* i : internal sampling rate */ - const int16_t sec_chan_low_rate /* i : TD secondary channel flag */ -); - -void analy_lp_AMR_WB( - const float speech[], /* i : pointer to the speech frame */ - float *ener, /* o : residual energy from Levinson-Durbin */ - float A[], /* o : A(z) filter coefficients */ - float epsP[], /* o : LP analysis residual energies for each iteration */ - float isp_new[], /* o : current frame ISPs */ - float isp_old[], /* i/o: previous frame unquantized ISPs */ - float isf_new[], /* o : current frame ISFs */ - const int16_t Top, /* i : open loop pitch lag */ - const float Tnc /* i : open loop pitch gain */ -); - -void noise_est_init( - NOISE_EST_HANDLE hNoiseEst /* i/o: Noise estimation handle */ -); - -void speech_music_clas_init( - SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */ -); - -void long_enr( - Encoder_State *st, /* i/o: encoder state structure */ - const float Etot, /* i : total channel energy */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ - FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[] /* i : total channel energy LR channels */ -); - -void noise_est_pre( - const float Etot, /* i : Energy of current frame */ - const int16_t ini_frame, /* i : Frame number (init) */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation data handle */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t last_element_mode /* i : last element mode */ -); - -void noise_est_down( - const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ - float bckr[], /* i/o: per band background noise energy estimate */ - float tmpN[], /* o : temporary noise update */ - float enr[], /* o : averaged energy over both subframes */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *totalNoise, /* o : noise estimate over all critical bands */ - const float Etot, /* i : Energy of current frame */ - float *Etot_last, /* i/o: Energy of last frame */ - float *Etot_v_h2 /* i/o: Energy variaions of noise frames */ -); - -void noise_est( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t old_pitch1, /* i : previous frame OL pitch[1] */ - const float tmpN[], /* i : temporary noise update */ - const float *epsP, /* i : LP prediction error energies */ - const float Etot, /* i : total channel E */ - const float relE, /* i : relative frame energy */ - const float corr_shift, /* i : normalized correlation correction */ - const float enr[], /* i : averaged energy over both subframes */ - float fr_bands[], /* i : spectrum per critical bands of the current frame */ - float *cor_map_sum, /* o : sum of correlation map from mult-harm analysis */ - float *ncharX, /* o : noise character for sp/mus classifier */ - float *sp_div, /* o : soectral diversity feature */ - float *non_staX, /* o : non-stationarity for sp/mus classifier */ - int16_t *loc_harm, /* o : multi-harmonicity flag for UV classifier */ - const float *lf_E, /* i : per bin energy for low frequencies */ - int16_t *st_harm_cor_cnt, /* i : 1st harm correlation timer */ - const float Etot_l_lp, /* i : Smoothed low energy */ - float *sp_floor, /* o : noise floor estimate */ - float S_map[], /* o : short-term correlation map */ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ - const int16_t ini_frame /* i : Frame number (init) */ -); - -void vad_param_updt( - Encoder_State *st, /* i/o: encoder state structure */ - const float corr_shift, /* i : correlation shift */ - const float corr_shiftR, /* i : correlation shift right channel */ - const float A[], /* i : A(z) unquantized for the 4 subframes */ - const int16_t old_pitch1, /* i : previous frame OL pitch[1] */ - FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const int16_t n_channels /* i : number of channels */ -); - - -void lp_gain_updt( - const int16_t i_subfr, /* i : subframe number */ - const float gain_pit, /* i : Decoded gain pitch */ - const float norm_gain_code, /* i : Normalised gain code */ - float *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) */ - float *lp_gainc, /* i/o: LP-filtered code gain (FEC) */ - const int16_t L_frame /* i : length of the frame */ -); - -void GSC_enc_init( - GSC_ENC_HANDLE hGSCEnc /* i/o: GSC data handle */ -); - - -/*! r: index of the last band where pitch contribution is significant */ -int16_t Pit_exc_contribution_len( - Encoder_State *st, /* i/o: state structure */ - const float *dct_res, /* i : DCT of residual */ - float *dct_pitex, /* i/o: DCT of pitch contribution */ - float *pitch_buf, /* i/o: Pitch per subframe */ - int16_t *hangover /* i : Hangover for the time contribution switching */ -); - -int16_t stab_est( - float etot, /* i : Total energy of the current frame */ - float *lt_diff_etot, /* i/o: Long term total energy variation */ - float *mem_etot, /* i/o: Total energy memory */ - int16_t *nb_thr_3, /* i/o: Number of consecutives frames of level 3 */ - int16_t *nb_thr_1, /* i/o: Number of consecutives frames of level 1 */ - float *thresh, /* i/o: Detection thresold */ - int16_t *last_music_flag, /* i/o: Previous music detection ouptut */ - const int16_t vad_flag /* i : VAD flag */ -); - -float gsc_gainQ( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const float y_gain4[], /* i : gain per band */ - float y_gainQ[], /* o : quantized gain per band */ - const int32_t core_brate, /* i : Core rate */ - const int16_t coder_type, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t L_frame, /* i : frame length */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int32_t core_brate_inp /* i : true core brate */ -); - -void Comp_and_apply_gain( - float exc_diffQ[], /* i/o: gain per band */ - float Ener_per_bd_iQ[], /* o : Quant Ener per band */ - float Ener_per_bd_yQ[], /* o : Ener per band for quantize y */ - int16_t Mbands_gn, /* i : number of bands */ - const int16_t ReUseGain /* i : Reuse the gain in Ener_per_bd_yQ */ -); - -void bands_and_bit_alloc_ivas_fx( - const Word16 cor_strong_limit, /* i : HF correlation */ - const Word16 noise_lev, /* i : dwn scaling factor */ - const Word32 core_brate, /* i : core bit rate */ - const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ - const Word16 bits_used, /* i : Number of bit used before frequency Q */ - Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ - const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ - Word16 *max_ener_band, /* o : Sorted order */ - Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ - Word16 *nb_subbands, /* o : Number of subband allowed */ - const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ - Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ - Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ - const Word16 coder_type, /* i : coding type */ - const Word16 bwidth, /* i : input signal bandwidth */ - const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ - const Word16 L_frame, /* i : frame length */ - const Word16 element_mode, /* i : element mode */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ -); - -void GSC_dec_init_ivas( - GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ -); - -void decod_audio( - Decoder_State *st, /* i/o: decoder static memory */ - float dct_epit[], /* o : GSC excitation in DCT domain */ - const float *Aq, /* i : LP filter coefficient */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc_dct_in, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *lsf_new, /* i : current frame ISF vector */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reuse flag */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void gsc_dec( - Decoder_State *st, /* i/o: State structure */ - float exc_dct_in[], /* i/o: dct of pitch-only/total excitation */ - const int16_t pit_band_idx, /* i : pitch band index */ - const int16_t Diff_len, /* i : */ - const int16_t bits_used, /* i : total number of bits used */ - const int16_t nb_subfr, /* i : Number of subframe considered */ - const int16_t coder_type, /* i : coding type */ - int16_t *last_bin, /* i : last bin of bit allocation */ - const float *lsf_new, /* i : ISFs at the end of the frame */ - float *exc_wo_nf, /* o : excitation (in f domain) without noisefill*/ - float *tmp_noise /* o : long-term noise energy */ -); - -void dec_pit_exc( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *code, /* o : innovation */ - float *exc, /* i/o: adapt. excitation exc */ - const int16_t nb_subfr, /* i : Number of subframe considered */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void music_postfilt_init_flt( - MUSIC_POSTFILT_HANDLE hMusicPF /* i/o: LD music postfilter handle */ -); - -void LD_music_post_filter( - MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ - const float dtc_in[], /* i : input synthesis */ - float dtc_out[], /* o : output synthesis */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t coder_type, /* i : Coder type : -1 in case of IO */ - const int16_t Last_coder_type /* i : last Coder type */ -); - -void Post_music_postP( - float dct_buffer_in[], /* i/o: excitation buffer */ - float exc_buffer_out[], /* o : DCT output buffer */ - float *exc2, /* i/o: Current excitation to be overwriten */ - const float *mem_tmp, /* i : previous frame synthesis memory */ - float *st_mem_syn2, /* i/o: current frame synthesis memory */ - const float *Aq, /* i : LPC filter coefficients */ - float *syn /* i/o: 12k8 synthesis */ -); - -void Prep_music_postP( - float exc_buffer_in[], /* i/o: excitation buffer */ - float dct_buffer_out[], /* o : DCT output buffer */ - float filt_lfE[], /* i/o: long term spectrum energy */ - const int16_t last_core, /* i : last core */ - const float *pitch_buf, /* i : current frame pitch information */ - float *LDm_enh_lp_gbin /* o : smoothed suppression gain, per bin FFT */ -); - -void speech_music_classif( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_inp, /* i : new input signal */ - const float *inp, /* i : input signal to locate attach position */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const float lsp_new[M], /* i : LSPs in current frame */ - const float cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.) */ - const float epsP[M + 1], /* i : LP prediciton error */ - const float PS[], /* i : energy spectrum */ - const float Etot, /* i : total frame energy */ - const float old_cor, /* i : max correlation from previous frame */ - int16_t *attack_flag, /* o : attack flag (GSC or TC) */ - const float non_staX, /* i : unbound non-stationarity for sp/mus classifier */ - const float relE, /* i : relative frame energy */ - int16_t *high_lpn_flag, /* o : sp/mus LPN flag */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); -void ivas_find_wsp_fx( - const Word16 L_frame, /* i : length of the frame Q0*/ - const Word16 L_subfr, /* i : length of subframe Q0*/ - const Word16 nb_subfr, /* i : number of subframes Q0*/ - const Word16 *A_fx, - /* i : A(z) filter coefficients */ // Q12 - Word16 *Aw_fx, - /* o : weighted A(z) filter coefficients */ // Q12 - const Word16 *speech_fx, - /* i : pointer to the denoised speech frame */ // Q_new - const Word16 tilt_fact, - /* i : tilt factor */ // Q15 - Word16 *wsp_fx, - /* o : poitnter to the weighted speech frame */ // Q_new - Word16 *mem_wsp_fx, - /* i/o: W(Z) denominator memory */ // Q_new - const Word16 gamma, - /* i : weighting factor */ // Q15 - const Word16 L_look /* i : look-ahead Q0*/ -); - -void gain_enc_amr_wb( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const int32_t core_brate, /* i : core bitrate */ - float *gain_pit, /* i/o: Pitch gain / Quantized pitch gain */ - float *gain_code, /* o : Quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - float *past_qua_en /* i/o: gain quantization memory (4 words) */ -); - -void gain_enc_lbr( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe index */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const int16_t L_subfr /* i : subfr Lenght */ -); - -void gain_enc_mless( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t element_mode, /* i : element mode */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain /* i : gain pitch clipping flag (1 = clipping) */ -); - -void gain_enc_SQ( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t i_subfr, /* i : subframe index */ - const float *xn, /* i : target vector */ - const float *yy1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain /* i : gain pitch clipping flag (1 = clipping) */ -); - -/*! r: Return index of quantization */ -int16_t gain_enc_gaus( - float *gain, /* i/o: Code gain to quantize */ - const int16_t bits, /* i : number of bits to quantize */ - const float lowBound, /* i : lower bound of quantizer (dB) */ - const float topBound /* i : upper bound of quantizer (dB) */ -); - -void E_corr_xy2( - const float xn[], /* i : target vector */ - const float y1[], /* i : filtered excitation components 1 */ - const float y2[], /* i : filtered excitation components 2 */ - float g_corr[], /* o : correlations between x, y1, y2, y3, y4 */ - const int16_t L_subfr /* i : subframe size */ -); - - -/*! r: coding type */ -int16_t find_uv( - Encoder_State *st, /* i/o: encoder state structure */ - const float *pitch_fr, /* i : pointer to adjusted fractional pitch (4 val.) */ - const float *voicing_fr, /* i : refined correlation for each subframes */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float *ee, /* i : lf/hf Energy ratio for present frame */ - float *dE1X, /* o : sudden energy increase for S/M classifier */ - const float corr_shift, /* i : normalized correlation correction in noise */ - const float relE, /* i : relative frame energy */ - const float Etot, /* i : total energy */ - const float hp_E[], /* i : energy in HF */ - int16_t *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ - const int16_t last_core_orig, /* i : original last core */ - STEREO_CLASSIF_HANDLE hStereoClf /* i/o: stereo classifier structure */ -); - -/*! r: classification for current frames */ -int16_t signal_clas( - Encoder_State *st, /* i/o: encoder state structure */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float *ee, /* i : lf/hf E ration for 2 half-frames */ - const float relE, /* i : frame relative E to the long term average */ - const int16_t L_look, /* i : look-ahead */ - int16_t *clas_mod /* o : class flag for NOOP detection */ -); - -void select_TC( - const int16_t codec_mode, /* i : codec mode */ - const int16_t tc_cnt, /* i : TC frame counter */ - int16_t *coder_type, /* i/o: coder type */ - const int16_t localVAD /* i : VAD without hangover */ -); - - -void wb_vad_init( - VAD_HANDLE hVAD /* i/o: VAD data handle */ -); - -int16_t dtx_hangover_addition( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t vad_flag, /* i : VAD flag */ - const float snr, /* i : input single SNR estimate */ - const int16_t cldfb_subtraction, /* i : */ - int16_t *vad_hover_flag, /* o : VAD hangover flag */ - VAD_HANDLE hVAD, /* i/o: VAD handle for L or R channel */ - NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ - int16_t *rem_dtx_ho /* o : Expected remaining hangover frames */ -); - -int16_t wb_vad( - Encoder_State *st, /* i/o: encoder state structure */ - const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ - int16_t *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */ - int16_t *clean_speech_HO, /* o : SC-VBR clean speech HO flag */ - int16_t *NB_speech_HO, /* o : SC-VBR NB speech HO flag */ - float *snr_sum_he, /* i : voicing metric from SAD */ - int16_t *localVAD_HE_SAD, /* o : HE_SAD decision without hangovers */ - int16_t *flag_noisy_speech_snr, /* o : */ - VAD_HANDLE hVAD, /* i/o: VAD handle */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ - float lp_speech, /* i : long term active speech energy average */ - float lp_noise /* i : long term noise energy */ -); - -void bw_detect( - Encoder_State *st, /* i/o: Encoder State */ - const float signal_in[], /* i : input signal */ - float *spectrum, /* i : MDCT spectrum */ - const float *enerBuffer, /* i : energy buffer */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ -); - -void set_bw( - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - Encoder_State *st, /* i/o: Encoder State */ - const int16_t codec_mode /* i : codec mode */ -); - -float gaus_encode( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - const float *h1, /* i : weighted filter input response */ - const float *xn, /* i : target vector */ - float *exc, /* o : pointer to excitation signal frame */ - float *mem_w0, /* o : weighting filter denominator memory */ - float *gp_clip_mem, /* o : memory of gain of pitch clipping algorithm */ - float *tilt_code, /* o : synthesis excitation spectrum tilt */ - float *code, /* o : algebraic excitation */ - float *gain_code, /* o : Code gain. */ - float *y2, /* o : zero-memory filtered adaptive excitation */ - float *gain_inov, /* o : innovation gain */ - float *voice_fac, /* o : voicing factor */ - float *gain_pit, /* o : adaptive excitation gain */ - float *norm_gain_code /* o : normalized innovative cb. gain */ -); - -void td_cng_enc_init( - TD_CNG_ENC_HANDLE hTdCngEnc, /* i/o: DTX/TD CNG data handle */ - const int16_t Opt_DTX_ON, /* i : flag indicating DTX operation */ - const int16_t max_bwidth /* i : maximum encoded bandwidth */ -); - -void dtx( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t vad, /* i : VAD flag for DTX */ - const float speech[] /* i : Pointer to the speech frame */ -); - -void dtx_hangover_control( - Encoder_State *st, /* i/o: encoder state structure */ - const float lsp_new[M] /* i : current frame LSPs */ -); - - -void updt_enc_common( - Encoder_State *st /* i/o: encoder state structure */ -); - -void updt_IO_switch_enc( - Encoder_State *st, /* i/o: state structure */ - const int16_t input_frame /* i : input frame length */ -); - -void transition_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - int16_t *tc_subfr, /* i/o: TC subframe index */ - int16_t *Jopt_flag, /* i : joint optimization flag */ - int16_t *position, /* i/o: maximum of residual signal index */ - int16_t *T0, /* i/o: close loop integer pitch */ - int16_t *T0_frac, /* i/o: close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: lower limit for close-loop search */ - int16_t *T0_max, /* i/o: higher limit for close-loop search */ - float *exc, /* i/o: pointer to excitation signal frame */ - float *y1, /* o : zero-memory filtered adaptive excitation */ - const float *h1, /* i : weighted filter input response */ - const float *xn, /* i : target vector */ - float *xn2, /* o : target vector for innovation search */ - float *gp_cl, /* i/o: memory of gain of pitch clipping algorithm */ - float *gain_pit, /* o : adaptive excitation gain */ - float *g_corr, /* o : ACELP correlation values */ - int16_t *clip_gain, /* i/o: adaptive gain clipping flag */ - float **pt_pitch, /* o : floating pitch values */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits /* i/o: unused bits */ -); - -void tc_classif_enc( - const int16_t L_frame, /* i : length of the frame */ - int16_t *tc_subfr, /* i/o: TC subframe index */ - int16_t *position, /* i/o: maximum of residual signal index */ - const int16_t attack_flag, /* i : attack flag */ - const int16_t pitch, /* i : open loop pitch estimates for first halfframe */ - const float *res /* i : pointer to the LP residual signal frame */ -); - - -void gain_enc_tc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t i_subfr, /* i : subframe index */ - const float xn[], /* i : target vector */ - const float y2[], /* i : zero-memory filtered algebraic codebook excitation */ - const float code[], /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : pitch gain / Quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - - -/*! r: comfort noise gain factor */ -float AVQ_cod( - const float xri[], /* i : vector to quantize */ - int16_t xriq[], /* o : quantized normalized vector (assuming the bit budget is enough) */ - const int16_t nb_bits, /* i : number of allocated bits */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void AVQ_encmux( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t extl, /* i : extension layer */ - int16_t xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ - int16_t *nb_bits, /* i/o: number of allocated bits */ - const int16_t Nsv, /* i : number of subvectors */ - int16_t nq[], /* o : AVQ nq index */ - int16_t avq_bit_sFlag, /* i : flag indicating AVQ bit savings */ - int16_t trgtSvPos /* i : target SV for AVQ bit savings */ -); - -void ordr_esti( - const int16_t k, /* i : sub-vector index */ - int16_t *Mpos, /* i/o: dominant sub-vector position from ACV */ - int16_t svOrder[], /* i/o: AVQ sub-vector order */ - const int16_t Nsv /* i : total sub-vectors in a sub-frames */ -); - -void re8_cod( - int16_t x[], /* i : point in RE8 (8-dimensional integer vector) */ - int16_t *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ - uint16_t *I, /* o : index of c (pointer to unsigned 16-bit word) */ - int16_t k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index */ -); - -void pre_exc( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : frame length */ - const float *speech, /* i : input speech */ - const float *p_Aq, /* i : 12k8 Lp coefficient */ - const float *p_A, /* i : unquantized A(q) filter with bandwidth expansion */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : current sub frame indicator */ - float *Ap, /* o : weighted LP filter coefficients */ - const float *res, /* i : residual signal */ - float *h1, /* o : impulse response of weighted synthesis filter */ - float *xn, /* o : close-loop Pitch search target vector */ - float *cn, /* o : target vector in residual domain */ - float *mem_syn, /* i/o: memory of the synthesis filter */ - float *mem_w0, /* i/o: weighting filter denominator memory */ - const int16_t L_subfr /* i : subframe length */ -); - - -void encod_amr_wb( - Encoder_State *st, /* i/o: state structure */ - const float speech[], /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float Aq[], /* i : 12k8 Lp coefficient */ - const float *res, /* i : residual signal */ - float *syn, /* i/o: core synthesis */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - int16_t hf_gain[NB_SUBFR], /* o : decoded HF gain */ - const float *speech16k /* i : input speech @16kHz */ -); - -void stat_noise_uv_enc( - Encoder_State *st, /* i/o: state structure */ - const float *epsP, /* i : LP prediction errors */ - const float *isp_new, /* i : immittance spectral pairs at 4th sfr */ - const float *isp_mid, /* i : immittance spectral pairs at 2nd sfr */ - float *Aq, /* i/o: A(z) quantized for the 4 subframes */ - float *exc2, /* i/o: excitation buffer */ - const int16_t uc_two_stage_flag /* o : flag undicating two-stage UC */ -); - -void re8_compute_base_index( - const int16_t *x, /* i : Elemen of Q2, Q3 or Q4 */ - const int16_t ka, /* i : Identifier of the absolute leader related to x */ - uint16_t *I /* o : index */ -); - -void transf_cdbk_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const int16_t i_subfr, /* i : subframe index */ - float cn[], /* i/o: target vector in residual domain */ - float exc[], /* i/o: pointer to excitation signal frame */ - const float *p_Aq, /* i : 12k8 Lp coefficient */ - const float Ap[], /* i : weighted LP filter coefficients */ - const float h1[], /* i : weighted filter input response */ - float xn[], /* i/o: target vector */ - float xn2[], /* i/o: target vector for innovation search */ - float y1[], /* i/o: zero-memory filtered adaptive excitation */ - const float y2[], /* i : zero-memory filtered innovative excitation */ - const float Es_pred, /* i : predicited scaled innovation energy */ - float *gain_pit, /* i/o: adaptive excitation gain */ - const float gain_code, /* i : innovative excitation gain */ - float g_corr[], /* o : ACELP correlation values */ - const int16_t clip_gain, /* i : adaptive gain clipping flag */ - float *gain_preQ, /* o : prequantizer excitation gain */ - float code_preQ[], /* o : prequantizer excitation */ - int16_t *unbits /* i/o: number of AVQ unused bits */ -); -void deemph_lpc( - float *p_Aq_cuerr, /* i : LP coefficients current frame */ - float *p_Aq_old, /* i : LP coefficients previous frame */ - float *LPC_de_curr, /* o : De-emphasized LP coefficients current frame */ - float *LPC_de_old, /* o : De-emphasized LP coefficients previous frame*/ - const int16_t deemph_old ); - -void Interpol_delay( - float *out, /* o : pitch interpolation output */ - float *last, /* i : last frame pitch lag */ - float *current, /* i : current frame pitch lag */ - int16_t SubNum, /* i : subframe number */ - const float *frac /* i : interpolation constant */ -); - -void dequantize_uvg( - int16_t iG1, /* i : gain 1 index */ - int16_t *iG2, /* i : gain 2 index */ - float *G, /* o : quantized gain */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void generate_nelp_excitation( - int16_t *seed, /* i/o: random number seed */ - float *Gains, /* i : excitation gains */ - float *output, /* o : excitation output */ - float gain_fac /* i : gain factor */ -); - -void nelp_encoder( - Encoder_State *st, /* i/o: encoder state */ - float *in, /* i : residual signal */ - float *exc, /* o : NELP quantized excitation signal */ - const int16_t reduce_gains ); - -void encod_nelp( - Encoder_State *st, /* i/o: state structure */ - const float *speech, /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float *Aq, /* i : 12k8 Lp coefficient */ - float *res, /* o : residual signal */ - float *synth, /* o : core synthesis */ - float *tmp_noise, /* o : long-term noise energy */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void realft( - float *data, /* i/o: data array */ - int16_t n, /* i : length of data array */ - int16_t isign /* i : sign +1 or -1 */ -); - -ivas_error DTFS_new( - DTFS_STRUCTURE **dtfs_out ); - -void DTFS_copy( - DTFS_STRUCTURE *Xout, /* o : DTFS */ - DTFS_STRUCTURE Xinp /* i : DTFS */ -); - -void DTFS_sub( - DTFS_STRUCTURE *tmp, /* o : output DFTS */ - DTFS_STRUCTURE X1, /* i : DTFS input 1 */ - DTFS_STRUCTURE X2 /* i : DTFS input 2 */ -); - -void DTFS_to_fs( - const float *x, /* i : Time domain signal */ - const int16_t N, /* i : Length of input vector */ - DTFS_STRUCTURE *X, /* o : DTFS structure with a, b, lag */ - const int32_t sampling_rate, - const int16_t FR_flag /* i : FR flag */ -); - -void DTFS_fs_inv( - DTFS_STRUCTURE *X, /* i : DTFS */ - float *x, /* o : time domain sig */ - const int16_t N, /* i : Output length */ - float ph0 /* i : Input phase */ -); - -void DTFS_car2pol( - DTFS_STRUCTURE *X /* i/o: DTFS structure a, b, lag */ - /* input in Cartesion, output in Polar */ -); - -void DTFS_pol2car( - DTFS_STRUCTURE *X /* i/o: DTFS structure a, b, lag */ - /* input in Polar, output in Cartesian */ -); - -/*! r: Return Input RMS between f1/f2 b4 scaling */ -float DTFS_setEngyHarm( - float f1, /* i : lower band freq of input to control energy */ - float f2, /* i : upper band freq of input to control energy */ - float g1, /* i : lower band freq of output to control energy */ - float g2, /* i : upper band freq of output to control energy */ - float en2, /* i : Target Energy to set the DTFS to */ - DTFS_STRUCTURE *X /* i/o: DTFS to adjust the energy of */ -); - -void DTFS_to_erb( - DTFS_STRUCTURE X, /* i : DTFS input */ - float *out /* o : ERB output */ -); - -void DTFS_zeroPadd( - const int16_t N, /* i : Target lag */ - DTFS_STRUCTURE *X /* i/o: DTFS */ -); - -/*! r: Energy */ -float DTFS_getEngy( - DTFS_STRUCTURE X /* i : DTFS to compute energy of */ -); - -void DTFS_adjustLag( - DTFS_STRUCTURE *X_DTFS, /* i/o: DTFS to adjust lag for */ - const int16_t N /* i : Target lag */ -); - -void DTFS_poleFilter( - DTFS_STRUCTURE *X, /* i/o: DTFS to poleFilter inplace */ - const float *LPC, /* i : LPCs */ - const int16_t N /* i : LPCORDER */ -); - -void DTFS_zeroFilter( - DTFS_STRUCTURE *X, /* i/o: DTFS to zeroFilter inplace */ - const float *LPC, /* i : LPCs */ - const int16_t N /* i : LPCORDER */ -); - -float DTFS_alignment_full( - DTFS_STRUCTURE X1_DTFS, /* i : reference DTFS */ - DTFS_STRUCTURE X2_DTFS, /* i : DTFS to shift */ - const int16_t num_steps /* i : resolution */ -); - -void DTFS_phaseShift( - DTFS_STRUCTURE *X, /* i : DTFS to shift */ - float ph /* i : phase to shift */ -); - -void erb_add( - float *curr_erb, /* i/o: current ERB */ - const int16_t l, /* i : current lag */ - const float *prev_erb, /* i : previous ERB */ - const int16_t pl, /* i : previous lag */ - const int16_t *index, /* i : ERB index */ - const int16_t num_erb /* i : number of ERBs */ -); - -void erb_slot( - int16_t lag, /* i : input lag */ - int16_t *out, /* o : ERB slots */ - float *mfreq, /* i : ERB frequencies */ - int16_t num_erb /* i : number of ERBs */ -); - -void erb_diff( - const float *prev_erb, /* i : previous ERB */ - const int16_t pl, /* i : previous lag */ - const float *curr_erb, /* i : current ERB */ - const int16_t l, /* i : current lag */ - const float *curr_lsp, /* i : current LSP coefficients */ - float *out, /* o : ERB difference */ - int16_t *index, /* i : ERB index */ - const int16_t num_erb /* i : Number of ERBs */ -); - -void DTFS_erb_inv( - float *in, /* i : ERB inpt */ - int16_t *slot, /* i : ERB slots filled based on lag */ - float *mfreq, /* i : erb frequence edges */ - DTFS_STRUCTURE *X, /* o : DTFS after erb-inv */ - const int16_t num_erb /* i : Number of ERB bands */ -); - -ivas_error ppp_quarter_encoder( - int16_t *returnFlag, /* o : return value */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - DTFS_STRUCTURE *CURRCW_Q, /* o : Quantized (amp/phase) DTFS */ - DTFS_STRUCTURE *TARGETCW, /* o : DTFS with quant phase but unquant Amp */ - const int16_t prevCW_lag, /* i : previous lag */ - DTFS_STRUCTURE vCURRCW_NQ, /* i : Unquantized DTFS */ - const float *curr_lpc, /* i : LPCS */ - float *lastLgainE, /* i/o: last low band gain */ - float *lastHgainE, /* i/o: last high band gain */ - float *lasterbE, /* i/o: last ERB vector */ - DTFS_STRUCTURE PREV_CW_E /* i : past DTFS */ -); - -ivas_error WIsyn( - DTFS_STRUCTURE PREVCW, /* i : Prev frame DTFS */ - DTFS_STRUCTURE *CURR_CW_DTFS, /* i/o: Curr frame DTFS */ - const float *curr_lpc, /* i : LPC */ - float *ph_offset, /* i/o: Phase offset to line up at end of frame */ - float *out, /* o : Waveform Interpolated time domain signal */ - const int16_t N, /* i : Number of samples of output to generate */ - const int16_t FR_flag /* i : called for post-smoothing in FR */ -); - -void set_ppp_mode( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t noisy_speech_HO, /* i : SC-VBR noisy speech HO flag */ - const int16_t clean_speech_HO, /* i : SC-VBR clean speech HO flag */ - const int16_t NB_speech_HO, /* i : SC-VBR NB speech HO flag */ - const int16_t localVAD_he /* i : HE-SAD flag without hangover */ -); - -ivas_error ppp_voiced_encoder( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - SC_VBR_ENC_HANDLE hSC_VBR, /* i/o: SC-VBR state structure */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t last_coder_type_raw, /* i : raw last_coder_type */ - const float old_pitch_buf[], /* i : buffer of old subframe pitch values */ - float *in, /* i : residual signal */ - float *out, /* o : Quantized residual signal */ - const int16_t delay, /* i : open loop pitch */ - float *lpc1, /* i : prev frame de-emphasized LPC */ - float *lpc2, /* i : current frame de-emphasized LPC */ - float *exc, /* i : previous frame quantized excitation */ - float *pitch /* o : floating pitch values for each subframe */ -); - -ivas_error encod_ppp( - Encoder_State *st, /* i/o: state structure */ - const float speech[], /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float Aq[], /* i : 12k8 Lp coefficient */ - float *res, /* i/o: residual signal */ - float *synth, /* i/o: core synthesis */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void reset_rf_indices( - RF_ENC_HANDLE hRF, /* i/o: RF state structure */ - const int16_t L_frame, /* i : frame length */ - int16_t *rf_target_bits_write ); - -void signaling_enc_rf( - Encoder_State *st /* i/o: encoder state structure */ -); - -ivas_error acelp_core_dec( - Decoder_State *st, /* i/o: Decoder state structure */ - float output[], /* o : synthesis @internal Fs */ - float synth[], /* o : synthesis */ - float save_hb_synth[], /* o : HB synthesis */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - float pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe */ - int16_t *unbits, /* o : number of unused bits */ - int16_t *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const float tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t last_element_mode, /* i : last element mode */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t nchan_out, /* i : number of output channels */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t read_sid_info /* i : read SID info flag */ -); - -void bass_psfilter_init( - BPF_DEC_HANDLE hBPF /* o : BPF data handle */ -); - -void bass_psfilter( - BPF_DEC_HANDLE hBPF, /* o : BPF data handle */ - const int16_t Opt_AMR_WB, /* i : AMR-WB IO flag */ - const float synth_in[], /* i : synthesis (at 16kHz) */ - const int16_t L_frame, /* i : length of the last frame */ - const float pitch_buf[], /* i : pitch for every subfr [0,1,2,3] */ - const int16_t bpf_off, /* i : do not use BPF when set to 1 */ - float v_stab, /* i : stability factor */ - float *v_stab_smooth, /* i : smoothed stability factor */ - const int16_t coder_type, /* i : coder_type */ - float bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ -); - -void CNG_reset_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors /* o : voicing factors */ -); - -void updt_dec( - Decoder_State *st, /* i/o: state structure */ - const float *old_exc, /* i : buffer of excitation */ - const float *pitch_buf, /* i : floating pitch values for each subframe */ - const float Es_pred, /* i : predicited scaled innovation energy */ - const float *Aq, /* i : A(z) quantized for all subframes */ - const float *lsf_new, /* i : current frame LSF vector */ - const float *lsp_new, /* i : current frame LSP vector */ - const float voice_factors[], /* i : voicing factors */ - const float *old_bwe_exc, /* i : buffer of excitation */ - const float *gain_buf /* o : floating pitch gain for each subframe */ -); - -void updt_IO_switch_dec( - const int16_t output_frame, /* i : output frame length */ - Decoder_State *st /* i/o: state structure */ -); - -void updt_dec_common( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t concealWholeFrameTmp, /* i : concealWholeFrameTmp flag */ - const float *synth /* i : decoded synthesis */ -); - -void td_cng_dec_init( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - -void CNG_dec( - Decoder_State *st, /* i/o: State structure */ - const int16_t last_element_mode, /* i : last element mode */ - float Aq[], /* o : LP coefficients */ - float *lsp_new, /* i/o: current frame LSPs */ - float *lsf_new, /* i/o: current frame LSFs */ - int16_t *allow_cn_step, /* o : allow cn step */ - int16_t *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - float *q_env ); - -void swb_CNG_dec( - Decoder_State *st, /* i/o: State structure */ - const float *synth, /* i : ACELP core synthesis at 32kHz */ - float *shb_synth, /* o : high-band CNG synthesis */ - const int16_t sid_bw /* i : 0-NB/WB, 1-SWB SID */ -); - -void lsf_dec( - Decoder_State *st, /* i/o: State structure */ - const int16_t tc_subfr, /* i : TC subframe index */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - int16_t *LSF_Q_prediction, /* o : LSF prediction mode */ - float *lsf_new, /* o : de-quantized LSF vector */ - float *lsp_new, /* o : de-quantized LSP vector */ - float *lsp_mid, /* o : de-quantized mid-frame LSP vector */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void isf_dec_amr_wb( - Decoder_State *st, /* i/o: State structure */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - float *isf_new, /* o : de-quantized ISF vector */ - float *isp_new /* o : de-quantized ISP vector */ -); - -void Es_pred_dec( - float *Es_pred, /* o : predicted scaled innovation energy */ - const int16_t enr_idx, /* i : indice */ - const int16_t nb_bits, /* i : number of bits */ - const int16_t no_ltp /* i : no LTP flag */ -); - -void gaus_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - float *code, /* o : gaussian excitation */ - float *norm_gain_code, /* o : gain of the normalized gaussian excitation */ - float *lp_gainp, /* i/o: lp filtered pitch gain(FER) */ - float *lp_gainc, /* i/o: lp filtered code gain (FER) */ - float *gain_inov, /* o : unscaled innovation gain */ - float *tilt_code, /* o : synthesis excitation spectrum tilt */ - float *voice_fac, /* o : estimated voicing factor */ - float *gain_pit, /* o : reset pitch gain */ - float *pt_pitch, /* o : reset floating pitch buffer */ - float *exc, /* o : excitation signal frame */ - float *gain_code, /* o : gain of the gaussian excitation */ - float *exc2 /* o : scaled excitation signal frame */ -); - -void gain_dec_amr_wb( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *past_qua_en, /* i/o: gain quantization memory (4 words) */ - float *gain_inov, /* o : unscaled innovation gain */ - const float *code, /* i : algebraic code excitation */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -void gain_dec_lbr( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe index */ - const float *code, /* i : algebraic excitation */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ - const int16_t L_subfr /* i : subframe length */ -); - -void gain_dec_mless( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe number */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *code, /* i : algebraic code excitation */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -void gain_dec_SQ( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe number */ - const float *code, /* i : algebraic code excitation */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -/*! r: quantized codebook gain */ -float gain_dec_gaus( - const int16_t index, /* i : quantization index */ - const int16_t bits, /* i : number of bits to quantize */ - const float lowBound, /* i : lower bound of quantizer (dB) */ - const float topBound, /* i : upper bound of quantizer (dB) */ - const float gain_inov, /* i : unscaled innovation gain */ - float *norm_gain_code /* o : gain of normalized gaus. excit. */ -); - -/*! r: floating pitch value */ -float pit_decode_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : length of the frame */ - int16_t i_subfr, /* i : subframe index */ - const int16_t coder_type, /* i : coding type */ - int16_t *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: delta search min for sf 2 & 4 */ - int16_t *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void abs_pit_dec_flt( - const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ - int16_t pitch_index, /* i : pitch index */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac /* o : pitch fraction */ -); - -void delta_pit_dec_flt( - const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ - const int16_t pitch_index, /* i : pitch index */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - const int16_t T0_min /* i : delta search min */ -); - -void pit_Q_dec_flt( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t pitch_index, /* i : pitch index */ - const int16_t nBits, /* i : # of Q bits */ - const int16_t delta, /* i : Half the CL searched interval */ - const int16_t pit_flag, /* i : absolute(0) or delta(1) pitch Q */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_min, /* i/o: delta search min */ - int16_t *T0_max, /* i/o: delta search max */ - int16_t *BER_detect /* o : BER detect flag */ -); - -void pit16k_Q_dec_flt( - const int16_t pitch_index, /* i : pitch index */ - const int16_t nBits, /* i : # of Q bits */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_min, /* i/o: delta search min */ - int16_t *T0_max, /* i/o: delta search max */ - int16_t *BER_detect /* o : BER detect flag */ -); - - -void inov_decode( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const int16_t i_subfr, /* i : subframe index */ - const float *p_Aq, /* i : LP filter coefficients */ - const float tilt_code, /* i : tilt of of the excitation of previous subframe */ - const float pt_pitch, /* i : pointer to current subframe fractional pitch */ - float *code, /* o : algebraic excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void dec_acelp_1t64( - Decoder_State *st, /* i/o: decoder state structure */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void dec_acelp_2t32( - Decoder_State *st, /* i/o: decoder state structure */ - float code[] /* o : algebraic (fixed) codebook excitation */ -); - -void dec_acelp_4t64( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t nbbits, /* i : number of bits per codebook */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - - -void FEC_exc_estim( - Decoder_State *st, /* i/o: Decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - float *old_exc, /* i/o: excitation buffer */ - float *exc2, /* o : excitation buffer (for synthesis) */ - float *exc_dct_in, /* o : GSC excitation in DCT domain */ - float *pitch_buf, /* o : Floating pitch for each subframe */ - float *tmp_tc, /* o : FEC pitch */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - float *lsf_new, /* i : ISFs at the end of the frame */ - float *tmp_noise /* o : long-term noise energy */ -); - -void FEC_lsf2lsp_interp_flt( - Decoder_State *st, /* i/o: Decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - float *Aq, /* o : calculated A(z) for 4 subframes */ - float *lsf, /* o : estimated LSF vector */ - float *lsp /* o : estimated LSP vector */ -); - -void FEC_lsf_estim_enc( - Encoder_State *st, /* i : Encoder static memory */ - float *lsf /* o : estimated LSF vector */ -); - -float frame_energy( - const int16_t L_frame, /* i : length of the frame */ - const float *pitch, /* i : pitch values for each subframe */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float lp_speech, /* i : long term active speech energy average */ - float *frame_ener /* o : pitch-synchronous energy at frame end */ -); - -void FEC_SinOnset( - float *exc, /* i/o: exc vector to modify */ - int16_t puls_pos, /* i : Last pulse position desired */ - int16_t T0, /* i : decoded first frame pitch */ - float enr_q, /* i : energy provided by the encoder */ - float *Aq, /* i : Lsp coefficient */ - const int16_t L_frame /* i : Frame length */ -); - -int16_t FEC_enhACB( - const int16_t L_frame, /* i : Frame length */ - const int16_t last_L_frame, /* i : frame length of last frame */ - float *exc_io, /* i/o: Adaptive codebook memory */ - const int16_t new_pit, /* i : decoded first frame pitch */ - const int16_t puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ - const float bfi_pitch /* i : Pitch used for concealment */ -); - -void FEC_scale_syn( - const int16_t L_frame, /* i : length of the frame */ - int16_t clas, /* i/o: frame classification */ - const int16_t last_good, /* i : last good frame classification */ - float *synth, /* i/o: synthesized speech at Fs = 12k8 Hz */ - const float *pitch, /* i : pitch values for each subframe */ - float enr_old, /* i : energy at the end of prvious frame */ - float enr_q, /* i : transmitted energy for current frame */ - const int16_t coder_type, /* i : coding type */ - const int16_t LSF_Q_prediction, /* i : LSF prediction mode */ - int16_t *scaling_flag, /* i/o: flag to indicate energy control of syn */ - float *lp_ener_FEC_av, /* i/o: averaged voiced signal energy */ - float *lp_ener_FEC_max, /* i/o: averaged voiced signal energy */ - const int16_t bfi, /* i : current frame BFI */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t prev_bfi, /* i : previous frame BFI */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - float *exc, /* i/o: excitation signal without enhancement */ - float *exc2, /* i/o: excitation signal with enhancement */ - const float Aq[], /* i : LP filter coefs */ - float *old_enr_LP, /* i/o: LP filter E of last good voiced frame */ - const float *mem_tmp, /* i : temp. initial synthesis filter states */ - float *mem_syn, /* o : initial synthesis filter states */ - const int16_t avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ - const int16_t force_scaling /* i : force scaling */ -); - -void FEC_pitch_estim( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t last_core, /* i : last core */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t clas, /* i : current frame classification */ - const int16_t last_good, /* i : last good clas information */ - const float pitch_buf[], /* i : Floating pitch for each subframe */ - const float old_pitch_buf[], /* i : buffer of old subframe pitch values */ - float *bfi_pitch, /* i/o: update of the estimated pitch for FEC */ - int16_t *bfi_pitch_frame, /* o : frame length when pitch was updated */ - int16_t *upd_cnt, /* i/o: update counter */ - const int16_t coder_type ); - -void FEC_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i : configuration of the ACELP */ - const float *synth, /* i : pointer to synthesized speech for E computation */ - const int16_t coder_type, /* i : type of coder */ - int16_t clas, /* i : signal clas for current frame */ - const float *fpit, /* i : close loop fractional pitch buffer */ - const float *res, /* i : LP residual signal frame */ - int16_t *last_pulse_pos, /* i/o: Position of the last pulse */ - const int16_t L_frame, /* i : Frame length */ - const int32_t total_brate /* i : total codec bitrate */ -); - -int16_t FEC_pos_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *last_pulse_pos, /* o : Last glottal pulse position in the lost ACB */ - float *enr_q, /* o : Decoded energy */ - const int16_t nBits_es_Pred /* i : number of bits for Es_pred Q */ -); - -void improv_amr_wb_gs( - const int16_t clas, /* i : bitrate allocated to the core */ - const int16_t coder_type, /* i : coder_type */ - const int32_t core_brate, /* i : bitrate allocated to the core */ - int16_t *seed_tcx, /* i/o: Seed used for noise generation */ - float *old_Aq, /* i/o: old LPC filter coefficient */ - float *mem_syn2, /* i/o: synthesis memory */ - const float lt_voice_fac, /* i/o: long term voice factor */ - const int16_t locattack, /* i : Flag for a detected attack */ - float *Aq, /* i/o: Decoded LP filter coefficient */ - float *exc2, /* i/o: Decoded complete excitation */ - float *mem_tmp, /* i/o: synthesis temporary memory */ - float *syn, /* i/o: Decoded synthesis to be updated */ - const float *pitch_buf, /* i : Decoded pitch buffer */ - const float Last_ener, /* i : Last energy */ - const int16_t rate_switching_reset, /* i : rate switching reset flag */ - const int16_t last_coder_type, /* i : Last coder_type */ - const int16_t VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ -); - -int16_t tc_classif( - Decoder_State *st /* i/o: decoder state structure */ -); - -void transition_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t tc_subfr, /* i : TC subframe index */ - int16_t *Jopt_flag, /* i : joint optimization flag */ - float *exc, /* i/o: current frame excitation signal */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: delta search min for sf 2 & 4 */ - int16_t *T0_max, /* i/o: delta search max for sf 2 & 4 */ - float **pt_pitch, /* o : floating pitch values */ - int16_t *position, /* i/o: first glottal impulse position in frame */ - float *bwe_exc /* i/o: excitation for SWB TBE */ -); - -void gain_dec_tc( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe number */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const float *code, /* i : algebraic code excitation */ - float *gain_pit, /* o : pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excit. */ -); - -void stat_noise_uv_dec( - Decoder_State *st, /* i/o: decoder static memory */ - const float *lsp_new, /* i : end-frame LSP vector */ - const float *lsp_mid, /* i : mid-frame LSP vector */ - float *Aq, /* o : A(z) quantized for the 4 subframes */ - float *exc2, /* i/o: excitation buffer */ - const int16_t uc_two_stage_flag /* 1 : flag undicating two-stage UC */ -); - -void sc_vbr_dec_init_flt( - SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */ -); - -void decod_nelp( - Decoder_State *st, /* i/o: decoder static memory */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *exc, /* o : adapt. excitation exc */ - float *exc2, /* o : adapt. excitation/total exc */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* o : excitation for SWB TBE */ - const int16_t bfi, /* i : bad frame indicator */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -void nelp_decoder( - Decoder_State *st, /* i/o: decoder static memory */ - float *exc_nelp, /* o : adapt. excitation/total exc */ - float *exc, /* o : adapt. excitation exc */ - int16_t bfi, /* i : frame error rate */ - const int16_t coder_type, /* i : coding type */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error decod_ppp( - Decoder_State *st, /* i/o: state structure */ - const float Aq[], /* i : 12k8 Lp coefficient */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t bfi /* i : BFI flag */ -); - -ivas_error ppp_quarter_decoder( - Decoder_State *st, /* i/o: decoder state structure */ - DTFS_STRUCTURE *CURRCW_Q_DTFS, /* i/o: Current CW DTFS */ - int16_t prevCW_lag, /* i : Previous lag */ - float *lastLgainD, /* i/o: Last gain lowband */ - float *lastHgainD, /* i/o: Last gain highwband */ - float *lasterbD, /* i/o: Last ERB vector */ - int16_t bfi, /* i : FER flag */ - DTFS_STRUCTURE PREV_CW_D /* i : Previous DTFS */ -); - -ivas_error ppp_voiced_decoder( - Decoder_State *st, /* i/o: state structure */ - float *out, /* o : residual signal */ - const float *lpc2, /* i : current frame LPC */ - float *exc, /* i : previous frame excitation */ - float *pitch, /* o : floating pitch values for each subframe */ - const int16_t bfi /* i : BFI flag */ -); - -void AVQ_demuxdec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t xriq[], /* o : decoded subvectors [0..8*Nsv-1] */ - int16_t *nb_bits, /* i/o: number of allocated bits */ - const int16_t Nsv, /* i : number of subvectors */ - int16_t nq[], /* i/o: AVQ nq index */ - int16_t avq_bit_sFlag, /* i : flag for AVQ bit saving solution*/ - int16_t trgtSvPos /* i : target SV for AVQ bit savings */ -); - - -void Init_post_filter_ivas( - PFSTAT_HANDLE hPFstat /* i : post-filter state memories */ -); - -void nb_post_filt_ivas( - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : sub-frame length */ - PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ - float *lp_noise, /* i/o: long term noise energy */ - const float tmp_noise, /* i : noise energy */ - float *synth, /* i/o: synthesis */ - const float *Aq, /* i : LP filter coefficient */ - const float *pitch_buf, /* i : Floating pitch for each subframe */ - const int16_t coder_type, /* i : coder_type -> deactivated in AUDIO */ - const int16_t BER_detect, /* i : BER detect flag */ - const int16_t disable_hpf /* i : flag to diabled HPF */ -); - -void decod_unvoiced( - Decoder_State *st, /* i/o: decoder static memory */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* o : adapt. excitation exc */ - float *exc2, /* o : adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - float *gain_buf /* o : floating pitch gain for each subfram */ -); - -void decod_tran( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits, /* i/o: number of unused bits */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error decod_gen_voic( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const int16_t do_WI, /* i : FEC fast recovery flag */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits, /* i/o: number of unused bits */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void decod_amr_wb( - Decoder_State *st, /* i/o: decoder static memory */ - const float *Aq, /* i : LP filter coefficients */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - int16_t hf_gain[NB_SUBFR], /* o : decoded HF gain */ - float *voice_factors, /* o : voicing factors */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error init_decoder( - Decoder_State *st, /* o : Decoder static variables structure */ - const int16_t idchan, /* i : channel ID */ - const MC_MODE mc_mode /* i : MC mode */ -); - -void destroy_cldfb_decoder_flt( - Decoder_State *st /* o : Decoder static variables structure */ -); - -void HQ_core_dec_init_flt( - HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ -); - -void HQ_nbfec_init_flt( - HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ -); - -ivas_error evs_dec( - Decoder_State *st, /* i/o: Decoder state structure */ - float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ - float *output, /* o : output synthesis signal */ - FRAME_MODE frameMode /* i : Decoder frame mode */ -); - -void get_next_frame_parameters( - Decoder_State *st /* i/o: Decoder state structure */ -); - -ivas_error amr_wb_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ - float *output /* o : synthesis output */ -); - -void transf_cdbk_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const int16_t i_subfr, /* i : subframe index */ - const float Es_pred, /* i : predicited scaled innovation energy */ - const float gain_code, /* i : innovative excitation gain */ - float *gain_preQ, /* o : prequantizer excitation gain */ - float *norm_gain_preQ, /* o : normalized prequantizer excitation gain */ - float code_preQ[], /* o : prequantizer excitation */ - int16_t *unbits /* o : number of AVQ unused bits */ -); - -/*! r: decoded gain */ -float gain_dequant( - int16_t index, /* i : quantization index */ - const float min_val, /* i : value of lower limit */ - const float max_val, /* i : value of upper limit */ - const int16_t bits /* i : number of bits to dequantize */ -); - -void hq_core_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *audio, /* i : input audio signal */ - const int16_t input_frame, /* i : frame length */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t Voicing_flag, /* i : Voicing flag for FER method selection */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -int16_t detect_transient( - Encoder_State *st, /* i/o: encoder state structure */ - const float *in, /* i : input signal */ - const int16_t L /* i : length */ -); - -void wtda( - const float *new_audio, /* i : input audio */ - float *wtda_audio, /* o : windowed audio */ - float *old_wtda, /* i/o: windowed audio from previous frame */ - const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ - const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t L /* i : length */ -); - -void wtda_ext( - const float *new_audio, /* i : input audio */ - float *wtda_audio, /* o : windowed audio */ - const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ - const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t L, /* i : length */ - const uint16_t kernel_type /* i : transform kernel type (0 - 3) */ -); - -void tcx_get_windows_mode1_flt( - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - float *left_win, /* o : left overlap window */ - float *right_win, /* o : right overlap window */ - float *left_win_int, /* o : left overlap window */ - float *right_win_int, /* o : right overlap window */ - const int16_t L /* i : length */ -); - -void direct_transform( - const float *in32, /* i : input signal */ - float *out32, /* o : output transformation */ - const int16_t is_transient, /* i : transient flag */ - const int16_t L, /* i : length */ - const int16_t element_mode /* i : IVAS element mode */ -); - - -void interleave_spectrum( - float *coefs, /* i/o: input and output coefficients */ - const int16_t length /* i : length of spectrum */ -); - -void hq_hr_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float *coefs, /* i/o: transform-domain coefficients */ - const int16_t length, /* i : length of spectrum */ - int16_t *num_bits, /* i/o: number of available bits */ - const int16_t is_transient, /* i : transient flag */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void huff_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : Number of codewords to decode */ - const int16_t buffer_len, /* i : Number of bits to read */ - const int16_t num_lengths, /* i : Number of different huffman codeword lengths */ - const int16_t *thres, /* i : Threshold of first codeword of each length */ - const int16_t *offset, /* i : Offset for first codeword */ - const int16_t *huff_tab, /* i : Huffman table order by codeword lengths */ - int16_t *index /* o : Decoded index */ -); - -void reordernorm( - const int16_t *ynrm, /* i : quantization indices for norms */ - const int16_t *normqlg2, /* i : quantized norms */ - int16_t *idxbuf, /* o : reordered quantization indices */ - int16_t *normbuf, /* o : reordered quantized norms */ - const int16_t nb_sfm /* i : number of bands */ -); - -void diffcod( - const int16_t N, /* i : number of sub-vectors */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx /* o : differential code */ -); - -void diffcod_lrmdct( - const int16_t N, /* i : number of sub-vectors */ - const int16_t be_ref, /* i : band energy reference */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx, /* o : differential code */ - const int16_t is_transient /* i : transient flag */ -); - -void bitallocsum( - int16_t *R, /* i : bit-allocation vector */ - const int16_t nb_sfm, /* i : number of sub-vectors */ - int16_t *sum, /* o : total number of bits allocated */ - int16_t *Rsubband, /* o : rate per subband (Q3) */ - const int16_t num_bits, /* i : number of bits */ - const int16_t length, /* i : length of spectrum */ - const int16_t *sfmsize /* i : Length of bands */ -); -/*! r: BWE class */ -int16_t swb_bwe_gain_deq_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t core, /* i : core */ - float *SWB_tenv, /* o : time-domain BWE envelope */ - float *SWB_fenv, /* o : frequency-domain BWE envelope */ - const int16_t hr_flag, /* i : high rate flag */ - const int16_t hqswb_clas /* i : HQ BWE class */ -); - -void save_old_syn( - const int16_t L_frame, /* i : frame length */ - const float syn[], /* i : ACELP synthesis */ - float old_syn[], /* o : old synthesis buffer */ - float old_syn_12k8_16k[], /* i/o: old synthesis buffer */ - const float preemph_fac, /* i : preemphasis factor */ - float *mem_deemph /* i/o: deemphasis filter memory */ -); - -void hq_generic_hf_decoding( - const int16_t HQ_mode, /* i : HQ mode */ - float *coeff_out1, /* i/o: BWE input & temporary buffer */ - const float *hq_generic_fenv, /* i : SWB frequency envelopes */ - float *coeff_out, /* o : SWB signal in MDCT domain */ - const int16_t hq_generic_offset, /* i : frequency offset for representing hq swb bwe*/ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - const int16_t hq_swb_bwe_exc_clas, /* i : bwe excitation class */ - const int16_t *R ); - -void hq_core_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float out[], /* o : output synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching frame flag */ - float *output /* o : LB synthesis in case of ACELP-HQ switch */ -); - -void IMDCT( - float *x, - float *old_syn_overl, - float *syn_Overl_TDAC, - float *xn_buf, - const float *tcx_aldo_window_1_trunc, - const float *tcx_aldo_window_2, - const float *tcx_mdct_window_half, - const float *tcx_mdct_window_minimum, - const float *tcx_mdct_window_trans, - const int16_t tcx_mdct_window_half_length, - const int16_t tcx_mdct_window_min_length, - int16_t index, - const uint16_t kernel_type, /* i : TCX transform kernel type */ - const int16_t left_rect, - const int16_t tcx_offset, - const int16_t overlap, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t L_spec_TCX5, - const int16_t L_frame_glob, - const int16_t frame_cnt, - const int16_t bfi, - float *old_out, - const int16_t FB_flag, - Decoder_State *st, - const int16_t fullband, - float *acelp_zir ); - -void hq_hr_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *t_audio_q, /* o : transform-domain coefficients */ - const int16_t length, /* i : frame length */ - const int16_t num_bits, /* i : number of available bits */ - int16_t *ynrm, /* o : norm quantization index vector */ - int16_t *is_transient, /* o : transient flag */ - int16_t *hqswb_clas, /* o : HQ SWB class */ - float *SWB_fenv, /* o : SWB frequency envelopes */ - const int16_t core_switching_flag /* i : Core switching flag */ - -); - -void hdecnrm_context( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index, /* o : indices of quantized norms */ - int16_t *n_length /* o : decoded stream length */ -); - -void hdecnrm_tran( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index /* o : indices of quantized norms */ -); - -void hdecnrm_resize( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of SFMs */ - int16_t *index /* o : norm quantization index vector */ -); - -void hdecnrm( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index /* o : indices of quantized norms */ -); - -/*! r: index of last band */ -int16_t find_last_band( - const int16_t *bitalloc, /* i : bit allocation */ - const int16_t nb_sfm /* i : number of possibly coded bands */ -); - -void fill_spectrum( - float *coeff, /* i/o: normalized MLT spectrum / nf spectrum */ - int16_t *R, /* i : number of pulses per band */ - const int16_t is_transient, /* i : transient flag */ - int16_t norm[], /* i : quantization indices for norms */ - const float *hq_generic_fenv, /* i : HQ GENERIC envelope */ - const int16_t hq_generic_offset, /* i : HQ GENERIC offset */ - const int16_t nf_idx, /* i : noise fill index */ - const int16_t length, /* i : Length of spectrum (32 or 48 kHz) */ - const float env_stab, /* i : Envelope stability measure [0..1] */ - int16_t *no_att_hangover, /* i/o: Frame counter for attenuation hangover */ - float *energy_lt, /* i/o: Long-term energy measure for transient detection */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - const int16_t hq_generic_exc_clas, /* i : HF excitation class */ - const int16_t core_sfm, /* i : index of the end band for core */ - int16_t HQ_mode, /* i : HQ mode */ - float noise_level[], /* i : noise level for harmonic modes */ - int32_t core_brate, /* i : target bitrate */ - float prev_noise_level[], /* i/o: noise factor in previous frame */ - int16_t *prev_R, /* i/o: bit allocation info. in previous frame */ - float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */ - const int16_t *peak_idx, /* i : peak positions */ - const int16_t Npeaks, /* i : number of peaks */ - const int16_t *npulses, /* i : Number of assigned pulses per band */ - int16_t prev_is_transient, /* i : previous transient flag */ - float *prev_normq, /* i : previous norms */ - float *prev_env, /* i : previous noise envelopes */ - int16_t prev_bfi, /* i : previous bad frame indicator */ - const int16_t *sfmsize, /* i : Length of bands */ - const int16_t *sfm_start, /* i : Start of bands */ - const int16_t *sfm_end, /* i : End of bands */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length for harmonic mode */ - int16_t prev_hq_mode, /* i : previous HQ mode */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t num_env_bands, /* i : Number of envelope bands */ - const int16_t element_mode /* i : element mode */ -); - -void de_interleave_spectrum( - float *coefs, /* i/o: input and output coefficients */ - int16_t length /* i : length of spectrum */ -); - -void inverse_transform( - const float *InMDCT, /* i : input MDCT vector */ - float *Out, /* o : output vector */ - const int16_t IsTransient, /* i : transient flag */ - const int16_t L, /* i : output frame length */ - const int16_t L_inner, /* i : length of the transform */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void window_ola( - const float *ImdctOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t L, /* i : length */ - const int16_t right_mode, - const int16_t left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t use_bfi_win, /* i : use BFI windowing */ - const int16_t oldHqVoicing, /* i : previous HqVoicing */ - float *oldgapsynth /* i : previous gapsynth */ -); - -void window_ola_ext( - const float *ImdstOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t L, /* i : length */ - const int16_t right_mode, - const int16_t left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const uint16_t kernel_type /* i : transform kernel type */ -); - -void map_quant_weight( - const int16_t normqlg2[], /* i : quantized norms */ - int16_t wnorm[], /* o : weighted norm */ - const int16_t is_transient /* i : transient flag */ -); - -void recovernorm( - const int16_t *const idxbuf, /* i : reordered quantization indices */ - int16_t *ynrm, /* o : recovered quantization indices */ - int16_t *normqlg2, /* o : recovered quantized norms */ - const int16_t nb_sfm /* i : number of subbands */ -); - -void reordvct( - int16_t *y, /* i/o: vector to rearrange */ - const int16_t N, /* i : dimensions */ - int16_t *idx /* o : reordered vector index */ -); - -void bitalloc( - int16_t *y, /* i : reordered norm of sub-vectors */ - int16_t *idx, /* i : reordered sub-vector indices */ - int16_t sum, /* i : number of available bits */ - int16_t N, /* i : number of norms */ - int16_t K, /* i : maximum number of bits per dimension */ - int16_t *r, /* o : bit-allacation vector */ - const int16_t *sfmsize, /* i : Length of bands */ - const int16_t hqswb_clas /* i : signal classification flag */ -); - -/*! r: Integer (truncated) number of allocated bits */ -int16_t BitAllocF( - int16_t *y, /* i : norm of sub-vectors */ - int32_t bit_rate, /* i : bitrate */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - int16_t *R, /* o : bit-allocation indicator */ - int16_t *Rsubband, /* o : sub-band bit-allocation vector (Q3) */ - const int16_t hqswb_clas, /* i : hq swb class */ - const int16_t num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ -); - -/*! r: Integer (truncated) number of allocated bits */ -int16_t BitAllocWB( - int16_t *y, /* i : norm of sub-vectors */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - int16_t *R, /* o : bit-allocation indicator */ - int16_t *Rsubband ); /* o : sub-band bit-allocation vector (Q3) */ - -/*! r: Number of low frequency bands */ -int16_t hvq_pvq_bitalloc( - int16_t num_bits, /* i/o: Number of available bits (including gain bits) */ - const int32_t core_brate, /* i : bitrate */ - const int16_t bwidth, /* i : Encoded bandwidth */ - const int16_t *ynrm, /* i : Envelope coefficients */ - const int32_t manE_peak, /* i : Peak energy mantissa */ - const int16_t expE_peak, /* i : Peak energy exponent */ - int16_t *Rk, /* o : bit allocation for concatenated vector */ - int16_t *R, /* i/o: Global bit allocation */ - int16_t *sel_bands, /* o : Selected bands for encoding */ - int16_t *n_sel_bands /* o : No. of selected bands for encoding */ -); - -void floating_point_add_float( - int32_t *mx, /* i/o: mantissa of the addend Q31 */ - int16_t *ex, /* i/o: exponent of the addend Q0 */ - const int32_t my, /* i : mantissa of the adder Q31 */ - const int16_t ey /* i : exponent of the adder Q0 */ -); - -/*! r: Number of bits needed */ -int16_t rc_get_bits2( - const int16_t N, /* i : Number of bits currently used */ - const uint32_t range /* i : Range of range coder */ -); - -void rc_enc_init( - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - int16_t tot_bits /* i : Total bit budget */ -); - -void rc_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const uint32_t cum_freq, /* i : Cumulative frequency up to symbol */ - const uint32_t sym_freq, /* i : Symbol probability */ - const uint32_t tot /* i : Total cumulative frequency */ -); - -void rc_enc_finish( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ /* i/o: PVQ encoder handle */ -); - -void rc_enc_bits( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const uint32_t value, /* i : Value to encode */ - const int16_t bits /* i : Number of bits used */ -); - -void rc_enc_uniform( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - uint32_t value, /* i : Value to encode */ - uint32_t tot /* i : Maximum value */ -); - -void rc_dec_init( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - int16_t tot_bits /* i : Total bit budget */ -); - -/*! r: Decoded value */ -uint32_t rc_decode( - int16_t *BER_detect, /* o : Bit error detection flag */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - uint32_t tot /* i : Total cumulative frequency */ -); - -void rc_dec_update( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const uint32_t cum_freq, /* i : Cumulative frequency */ - const uint32_t sym_freq /* i : Symbol frequency */ -); - -/*! r: Decoded value */ -uint32_t rc_dec_bits( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const int16_t bits /* i : Number of bits */ -); - -/*! r: Decoded value */ -uint32_t rc_dec_uniform( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const uint32_t tot /* i : Maximum value */ -); - -void rc_dec_finish( - Decoder_State *st, /* i/o: decoder state structure */ - PVQ_DEC_HANDLE hPVQ /* i/o: PVQ decoder handle */ -); - -/*! r: number of bits encoded */ -int16_t pvq_core_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - float coefs_norm[], /* i/o: normalized coefficients to encode */ - float coefs_quant[], /* o : quantized coefficients */ - const int16_t bits_tot, /* i : total number of bits */ - const int16_t nb_sfm, /* i : number of bands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : subband width */ - int16_t *R, /* i/o: Bit allocation/Adjusted bit alloc. (Q3) */ - int16_t *Rs, /* i/o: Integer bit allocation */ - int16_t *npulses, /* o : number of pulses */ - int16_t *maxpulse, /* i : maximum pulse per band */ - const int16_t core /* i : number of bands */ -); - -/*! r: number of bits decoded */ -int16_t pvq_core_dec( - Decoder_State *st, /* i/o: Decoder state */ - const int16_t *sfm_start, /* i : indices of first coeffs in the bands */ - const int16_t *sfm_end, /* i : indices of last coeffs in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - float coefs_quant[], /* o : output MDCT */ - const int16_t bits_tot, /* i : bit budget */ - const int16_t nb_sfm, /* i : number of bands */ - int16_t *R, /* i/o: Bit allocation/Adjusted bit alloc.(Q3) */ - int16_t *Rs, /* i/o: Integer bit allocation */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *maxpulse, /* o : maximum pulse per band */ - const int16_t core /* i : core */ -); - -void pvq_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const float *x, /* i : vector to quantize */ - int16_t *y, /* o : quantized vector (non-scaled integer)*/ - float *xq, /* o : quantized vector (scaled float) */ - const int16_t pulses, /* i : number of allocated pulses */ - const int16_t N, /* i : Length of vector */ - const float gain /* i : Gain */ -); - -void pvq_decode( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - float *xq, /* o : decoded vector (scaled float) */ - int16_t *y, /* o : decoded vector (non-scaled short)*/ - const int16_t K, /* i : number of allocated pulses */ - const int16_t N, /* i : Length of vector */ - const float gain /* i : Gain */ -); - -void rangeCoderFinalizationFBits( - const int16_t Brc, /* i : Current number of decoded bits */ - const uint32_t INTrc, /* i : Range coder state */ - int16_t *FBits /* i : Fractional finalization bits */ -); - -void bandBitsAdjustment( - const int16_t Brc, /* i : Current number of read quanta in range coder */ - const uint32_t INTrc, /* i : Range coder state */ - const int16_t Bavail, /* i : Available number of quanta */ - const int16_t Nbands, /* i : Number of bands */ - const int16_t D, /* i : Remaining number of bands to encode */ - const int16_t L, /* i : Size of current band */ - const int16_t Bband, /* i : Quanta allocation for current band */ - const int16_t Breserv, /* i : Quanta reservoir */ - int16_t *Bband_adj, /* o : Actual used number of quanta */ - int16_t *Brem, /* o : Quanta remaining */ - int16_t *Breservplus /* o : Quanta pool size */ -); - -void conservativeL1Norm( - const int16_t L, /* i : Length of vector segment */ - const int16_t Qvec, /* i : Assigned number of quanta */ - const int16_t Fcons, /* i : Conservative rounding flag */ - const int16_t Qavail, /* i : Input quanta remaining */ - const int16_t Qreserv, /* i : Input quanta in reservoir */ - const int16_t Dspec, /* i : assigned diracs from bitalloc */ - int16_t *Dvec, /* o : actual number of diracs */ - int16_t *Qspare, /* o : Output quanta remaining */ - int16_t *Qreservplus, /* o : Output quanta in reservoir */ - int16_t *Dspecplus /* o : Output number of diracs */ -); - -void NearOppSplitAdjustment( - const int16_t qband, /* i : quanta for current band */ - const int16_t qzero, /* i : range coder finalization quanta */ - const int16_t Qac, /* i : range coder current quanta */ - const uint32_t INTac, /* i : range coder state */ - const int16_t qglobal, /* i : quanta input */ - const int16_t FlagCons, /* i : conservative rounding flag */ - const int16_t Np, /* i : number of parts */ - const int16_t Nhead, /* i : first part */ - const int16_t Ntail, /* i : remaining parts */ - const int16_t Nnear, /* i : length of near component */ - const int16_t Nopp, /* i : length of opposite component */ - int16_t oppRQ3, /* i : ratio */ - int16_t *qnear, /* o : quantized near */ - int16_t *qopp, /* o : quantized opposite */ - int16_t *qglobalupd /* o : quanta remaining */ -); - -/*! r: Approximate integer division for positive input */ -int32_t intLimCDivPos( - const int32_t NUM, /* i : numerator */ - const int16_t DEN /* i : denominator */ -); - -/*! r: Approximate integer division */ -int16_t shrtCDivSignedApprox_flt( - const int16_t num, /* i : numerator */ - const int16_t den /* i : denominator */ -); - -void QuantaPerDsDirac( - const int16_t td, /* i : Length of vector segment */ - const int16_t dsDiracIndex, /* i : Quanta table index */ - const uint8_t *const *dimFrQuanta, /* i : Quanta lookup table */ - int16_t *Quanta /* i : Quanta */ -); - -void obtainEnergyQuantizerDensity( - const int16_t L_in, /* i : left vector energy */ - const int16_t R_in, /* i : right vector energy */ - int16_t *Density /* o : quantizer density */ -); - -void densityAngle2RmsProjDec( - const int16_t D, /* i : density */ - const int16_t indexphi, /* i : decoded index from AR dec */ - int16_t *oppQ15, /* o : opposite */ - int16_t *nearQ15, /* o : near */ - int16_t *oppRatioQ3 /* o : ratio */ -); - -void densityAngle2RmsProjEnc( - const int16_t D, /* i : density */ - const int16_t phiQ14uq, /* i : angle */ - int16_t *indexphi, /* o : index */ - int16_t *oppQ15, /* o : opposite */ - int16_t *nearQ15, /* o : near */ - int16_t *oppRatioQ3 /* o : ratio */ -); - -void env_adj( - const int16_t *pulses, /* i : number of pulses per band */ - const int16_t length, /* i : length of spectrum */ - const int16_t last_sfm, /* i : Index of last band */ - float *adj, /* o : Adjustment factors for the envelope */ - const float env_stab, /* i : Envelope stability parameter */ - const int16_t *sfmsize /* i : Length of bands */ -); - -float env_stability( - const int16_t *ynrm, /* i : Norm vector for current frame */ - const int16_t nb_sfm, /* i : Number of sub-bands */ - int16_t *mem_norm, /* i/o: Norm vector memory from past frame */ - int16_t *mem_env_delta, /* i/o: Envelope stability memory for smoothing*/ - const int16_t core_switching_flag /* i : Core switching flag */ -); - -/*! r: New speech/music state */ -float env_stab_smo( - float env_stab, /* i : env_stab value */ - float *env_stab_state_p, /* i/o: env_stab state probabilities */ - int16_t *ho_cnt /* i/o: hangover counter for speech state */ -); -void core_switching_post_enc( - Encoder_State *st, /* i/o: encoder state structure */ - // const float *old_inp_12k8, /* i : old input signal @12.8kHz */ - float *old_inp_12k8, /* i : old input signal @12.8kHz */ - // const float *old_inp_16k, /* i : old input signal @16kHz */ - float *old_inp_16k, /* i : old input signal @16kHz */ - // const float A[] /* i : unquant. LP filter coefs. */ - Word16 A_fx[], /* i : unquant. LP filter coefs. */ - Word16 Q_new ); -ivas_error core_switching_post_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *synth, /* i/o: output synthesis */ - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching frame flag */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode /* i : element mode of previous frame */ -); - -ivas_error core_switching_pre_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t output_frame, /* i : frame length */ - const int32_t last_core_brate_st0, /* i : channel 0 last core bitrate */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode, /* i : last_element_mode */ - const int32_t last_element_brate /* i : last element bitrate */ -); - -void bandwidth_switching_detect( - Decoder_State *st /* i/o: decoder state structure */ -); - -void bw_switching_pre_proc( - Decoder_State *st, /* i/o: decoder state structure */ - const float *old_syn_12k8_16k, /* i : ACELP core synthesis @ 12.8kHz or 16kHz */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t nchan_out /* i : number of output channels */ -); - -void updt_bw_switching( - Decoder_State *st, /* i/o: decoder state structure */ - const float *synth /* i : float synthesis signal */ -); - -void swb_tbe_reset( - float mem_csfilt[], - float mem_genSHBexc_filt_down_shb[], - float state_lpc_syn[], - float syn_overlap[], - float state_syn_shbexc[], - float *tbe_demph, - float *tbe_premph, - float mem_stp_swb[], - float *gain_prec_swb ); - -void swb_tbe_reset_synth( - float genSHBsynth_Hilbert_Mem[], - float genSHBsynth_state_lsyn_filt_shb_local[] ); - -void find_td_envelope( - const float inp[], - const int16_t len, - const int16_t len_h, - float mem_h[], - float out[] ); - -void fb_tbe_reset_enc( - float elliptic_bpf_2_48k_mem[][4], - float *prev_fb_energy ); - -void fb_tbe_reset_synth( - float fbbwe_hpf_mem[][4], - float *prev_fbbwe_ratio ); - -void wb_tbe_extras_reset( - float mem_genSHBexc_filt_down_wb2[], - float mem_genSHBexc_filt_down_wb3[] ); - -void wb_tbe_extras_reset_synth( - float state_lsyn_filt_shb[], - float state_lsyn_filt_dwn_shb[], - float mem_resamp_HB[] ); - -void tbe_celp_exc_flt( - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - float *bwe_exc, /* i/o: BWE excitation */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - float *error, /* i/o: error */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -); - -void prep_tbe_exc( - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const float gain_pit, /* i : Pitch gain */ - const float gain_code, /* i : algebraic codebook gain */ - const float code[], /* i : algebraic excitation */ - const float voice_fac, /* i : voicing factor */ - float *voice_factors, /* o : TBE voicing factor */ - float bwe_exc[], /* i/o: excitation for TBE */ - const float gain_preQ, /* i : prequantizer excitation gain */ - const float code_preQ[], /* i : prequantizer excitation */ - const int16_t T0, /* i : integer pitch variables */ - const int16_t coder_type, /* i : coding type */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -); - -void synthesise_fb_high_band( - const float excitation_in[], /* i : full band excitation */ - float output[], /* o : high band speech - 14.0 to 20 kHz */ - const float fb_exc_energy, /* i : full band excitation energy */ - const float ratio_float, /* i : energy ratio */ - const int16_t L_frame, /* i : ACELP frame length */ - const int16_t bfi, /* i : BFI flag */ - float *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ - float bpf_memory[][4] /* i/o: memory for elliptic bpf 48k */ -); - -void elliptic_bpf_48k_generic( - const float input[], /* i : input signal */ - float output[], /* o : output signal */ - float memory[][4], /* i/o: 4 arrays for memory */ - const float full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 */ -); - -void HQ_FEC_processing( - Decoder_State *st, /* i/o: decoder state structure */ - float *t_audio_q, /* o : MDCT coeffs. (for synthesis) */ - int16_t is_transient, /* i : Old flag for transient */ - float ynrm_values[][MAX_PGF], /* i : Old average Norm values for each group of bands */ - float r_p_values[][MAX_ROW], /* i : Computed y-intercept and slope by Regression */ - int16_t num_Sb, /* i : Number of sub-band group */ - int16_t nb_sfm, /* i : Number of sub-band */ - int16_t *Num_bands_p, /* i : Number of coeffs. for each sub-band */ - int16_t output_frame, /* i : Frame size */ - const int16_t *sfm_start, /* i : Start of bands */ - const int16_t *sfm_end /* i : End of bands */ -); - -void HQ_FEC_Mem_update( - Decoder_State *st, /* i/o: decoder state structure */ - const float *t_audio_q, - float *normq, - int16_t *ynrm, - const int16_t *Num_bands_p, - const int16_t is_transient, - const int16_t hqswb_clas, - const int16_t c_switching_flag, - const int16_t nb_sfm, - const int16_t num_Sb, - float *mean_en_high, - const int16_t hq_core_type, /* i : normal or low-rate MDCT(HQ) core */ - const int16_t output_frame /* i : Frame size */ -); - -void time_domain_FEC_HQ( - Decoder_State *st, /* i : Decoder State */ - float *wtda_audio, /* i : input */ - float *out, /* o : output audio */ - const float mean_en_high, /* i : transient flag */ - const int16_t output_frame /* i : Frame size */ -); - -void save_synthesis_hq_fec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *output, /* i : decoded synthesis */ - const int16_t output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -); - -void Next_good_after_burst_erasures( - const float *ImdctOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t ol_size /* i : overlap size */ -); - - -void reset_preecho_dec( - HQ_DEC_HANDLE hHQ_core /* i/o: HQ decoder handle */ -); - -void preecho_sb( - const int32_t core_brate, /* i : core bitrate */ - const float wtda_audio[], /* i : imdct signal */ - float *rec_sig, /* i : reconstructed signal, output of the imdct transform */ - const int16_t framelength, /* i : frame length */ - float *memfilt_lb, /* i/o: memory */ - float *mean_prev_hb, /* i/o: memory */ - float *smoothmem, /* i/o: memory */ - float *mean_prev, /* i/o: memory */ - float *mean_prev_nc, /* i/o: memory */ - float *wmold_hb, /* i/o: memory */ - int16_t *prevflag, /* i/o: flag */ - int16_t *pastpre, /* i/o: flag */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void hq2_core_configure( - const int16_t frame_length, /* i : frame length */ - const int16_t num_bits, /* i : number of bits */ - const int16_t is_transient, /* i : transient flag */ - int16_t *bands, - int16_t *length, - int16_t band_width[], - int16_t band_start[], - int16_t band_end[], - Word32 *L_qint, /* o : Q29 */ - Word16 *eref_fx, /* o : Q10 */ - Word16 *bit_alloc_weight_fx, /* o : Q13 */ - int16_t *gqlevs, - int16_t *Ngq, - int16_t *p2a_bands, - float *p2a_th, - float *pd_thresh, - float *ld_slope, - float *ni_coef, - float *ni_pd_th, - int32_t bwe_br ); - -void hq_lr_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float t_audio[], /* i/o: transform-domain coefs. */ - const int16_t inner_frame, /* i : inner frame length */ - int16_t *num_bits, /* i/o: number of available bits */ - const int16_t is_transient /* i : transient flag */ -); - -void hq_lr_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float yout[], /* o : transform-domain output coefs. */ - const int16_t inner_frame, /* i : inner frame length */ - int16_t num_bits, /* i : number of available bits */ - int16_t *is_transient /* o : transient flag */ -); - -void hq2_bit_alloc( - const float band_energy[], /* i : band energy of each subband */ - const int16_t bands, /* i : total number of subbands in a frame */ - Word32 L_Rk[], /* i/o: Bit allocation/Adjusted bit alloc. */ - int16_t *bit_budget, /* i/o: bit bugdet */ - int16_t *p2a_flags, /* i : HF tonal indicator */ - const Word16 weight_fx, /* i : weight (Q13) */ - const int16_t band_width[], /* i : Sub band bandwidth */ - const int16_t num_bits, /* i : available bits */ - const int16_t hqswb_clas, /* i : HQ2 class information */ - const int16_t bwidth, /* i : input bandwidth */ - const int16_t is_transient /* i : indicator HQ_TRANSIENT or not */ -); - -void hq2_noise_inject( - float y2hat[], - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - float Ep[], - float Rk[], - const int16_t npulses[], - int16_t ni_seed, - const int16_t bands, - const int16_t ni_start_band, - const int16_t bw_low, - const int16_t bw_high, - const float enerL, - const float enerH, - float last_ni_gain[], - float last_env[], - int16_t *last_max_pos_pulse, - int16_t *p2a_flags, - int16_t p2a_bands, - const int16_t hqswb_clas, - const int16_t bwidth, - const int32_t bwe_br ); - -void mdct_spectrum_denorm( - const int32_t inp_vector[], - float y2[], - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - const float band_energy[], - const int16_t npulses[], - const int16_t bands, - const float ld_slope, - const float pd_thresh ); - -void reverse_transient_frame_energies( - float band_energy[], /* o : band energies */ - const int16_t bands /* i : number of bands */ -); - - -void hvq_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t num_bits, /* i : Number of available bits */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t *ynrm, /* i : Envelope coefficients */ - int16_t *R, /* i/o: Bit allocation/updated bit allocation */ - float *noise_level, /* o : Noise level */ - int16_t *peak_idx, /* o : Peak position vector */ - int16_t *Npeaks, /* o : Total number of peaks */ - float *coefsq_norm, /* o : Output vector */ - const int16_t core /* i : Core */ -); - -void hq_configure_bfi( - int16_t *nb_sfm, /* o : Number of sub bands */ - int16_t *num_Sb, /* o : Number of FEC sub bands ? */ - int16_t *num_bands_p, /* o : FEC sub bands */ - const int16_t **sfmsize, /* o : Subband bandwidths */ - const int16_t **sfm_start, /* o : Subband start coefficients */ - const int16_t **sfm_end /* o : Subband end coefficients */ -); - -void swb_bwe_enc_lr( - Encoder_State *st, /* i/o: encoder state structure */ - const float m_core[], /* i : core synthesis (MDCT) */ - const float m_orig[], /* i/o: scaled orig signal (MDCT) */ - float m[], /* o : output, SWB part (MDCT) */ - const int32_t total_brate, /* i : total bitrate for selecting subband pattern */ - int16_t BANDS, - int16_t *band_start, - int16_t *band_end, - float *band_energy, - int16_t *p2a_flags, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - int16_t *prev_frm_index, - const int16_t har_bands, - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - int16_t band_width[], - const float y2_ni[], - int16_t *ni_seed ); - -void swb_bwe_dec_lr( - Decoder_State *st, /* i/o: decoder state structure */ - const float m_core[], /* i : lowband synthesis */ - float m[], /* o : highband synthesis with lowband zeroed */ - const int32_t total_brate, /* i : total bitrate for selecting subband pattern */ - int16_t BANDS, - int16_t *band_start, - int16_t *band_end, - float *band_energy, - int16_t *p2a_flags, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - const int16_t har_bands, - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - int16_t band_width[], - const float y2_ni[], - int16_t *ni_seed ); - -int16_t get_usebit_npswb( - const int16_t hqswb_clas ); - -void GetPredictedSignal( - const float *predBuf, /* i : prediction buffer */ - float *outBuf, /* o : output buffer */ - const int16_t lag, /* i : prediction buffer offset */ - const int16_t fLen, /* i : length of loop (output) */ - const float gain /* i : gain to be applied */ -); - -void convert_lagIndices_pls2smp( - int16_t lagIndices_in[], - int16_t nBands_search, - int16_t lagIndices_out[], - const float sspectra[], - const int16_t sbWidth[], - const int16_t fLenLow ); - -void FindNBiggest2_simple( - const float *inBuf, /* i : input buffer (searched) */ - GainItem *g, /* o : N biggest components found */ - const int16_t nIdx, /* i : search length */ - int16_t *n, /* i : number of components searched (N biggest) */ - const int16_t N_NBIGGESTSEARCH ); - -void updat_prev_frm( - float y2[], - float t_audio[], - const int32_t bwe_br, - const int16_t length, - const int16_t inner_frame, - const int16_t bands, - const int16_t bwidth, - const int16_t is_transient, - const int16_t hqswb_clas, - int16_t *prev_hqswb_clas, - int16_t *prev_SWB_peak_pos, - int16_t prev_SWB_peak_pos_tmp[], - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - const int16_t bws_cnt ); - -void hf_parinitiz( - const int32_t total_brate, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - int16_t wBands[], - const int16_t **subband_search_offset, - const int16_t **subband_offsets, - int16_t *nBands, - int16_t *nBands_search, - int16_t *swb_lowband, - int16_t *swb_highband ); - -float spectrumsmooth_noiseton( - float spectra[], - const float spectra_ni[], - float sspectra[], - float sspectra_diff[], - float sspectra_ni[], - const int16_t fLenLow, - int16_t *ni_seed ); - -void noiseinj_hf( - float xSynth_har[], - const float th_g[], - const float band_energy[], - float *prev_En_sb, - const int16_t p2a_flags[], - const int16_t BANDS, - const int16_t band_start[], - const int16_t band_end[], - const int16_t fLenLow ); - -void noise_extr_corcod( - float spectra[], - const float spectra_ni[], - float sspectra[], - float sspectra_diff[], - float sspectra_ni[], - const int16_t fLenLow, - int16_t prev_hqswb_clas, - float *prev_ni_ratio ); - -void genhf_noise( - float noise_flr[], - float xSynth_har[], - float *predBuf, - int16_t bands, /* i : total number of subbands in a frame */ - int16_t harmonic_band, /* i : Number of LF harmonic frames */ - int16_t har_freq_est2, - int16_t pos_max_hfe2, - int16_t *pul_res, - GainItem pk_sf[], - const int16_t fLenLow, - const int16_t fLenHigh, - const int16_t sbWidth[], - const int16_t lagIndices[], - const int16_t subband_offsets[], - const int16_t subband_search_offset[] ); - -void ton_ene_est( - float xSynth_har[], - float be_tonal[], - float band_energy[], - int16_t band_start[], - int16_t band_end[], - int16_t band_width[], - const int16_t fLenLow, - const int16_t fLenHigh, - int16_t bands, - int16_t har_bands, - float ni_lvl, - GainItem pk_sf[], - int16_t *pul_res ); - -void Gettonl_scalfact( - float *outBuf, /* o : synthesized spectrum */ - const float *codbuf, /* i : core coder */ - const int16_t fLenLow, /* i : lowband length */ - const int16_t fLenHigh, /* i : highband length */ - int16_t harmonic_band, /* i : Number of LF harmonic frames */ - int16_t bands, /* i : total number of subbands in a frame */ - float *band_energy, /* i : band energy of each subband */ - int16_t *band_start, /* i : subband start indices */ - int16_t *band_end, /* i : subband end indices */ - const int16_t p2aflags[], - float be_tonal[], - GainItem *pk_sf, - int16_t *pul_res ); - -void SpectrumSmoothing( - float *inBuf, - float *outBuf, - const int16_t fLen, - const float th_cut ); - -void hq2_bit_alloc_har( - float *y, /* i : band energy of sub-vectors */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - Word32 *L_Rsubband, - int16_t p2a_bands, - int32_t core_brate, /* i : core bitrate */ - int16_t p2a_flags[], - int16_t band_width[] ); - -void GetSynthesizedSpecThinOut( - const float *predBuf, - float *outBuf, - const int16_t nBands, - const int16_t *sbWidth, - const int16_t *lagIndices, - const float *lagGains, - const int16_t predBufLen ); - -void return_bits_normal2( - int16_t *bit_budget, - const int16_t p2a_flags[], - const int16_t bands, - const int16_t bits_lagIndices[] ); - -void GetlagGains( - const float *predBuf, - const float *band_energy, - const int16_t nBands, - const int16_t *sbWidth, - const int16_t *lagIndices, - const int16_t predBufLen, - float *lagGains ); - -void preset_hq2_swb( - const int16_t hqswb_clas, - const int16_t band_end[], - int16_t *har_bands, - int16_t p2a_bands, - const int16_t length, - const int16_t bands, - int16_t *lowlength, - int16_t *highlength, - float m[] ); - -void post_hq2_swb( - const float m[], - const int16_t lowlength, - const int16_t highlength, - const int16_t hqswb_clas, - const int16_t har_bands, - const int16_t bands, - const int16_t p2a_flags[], - const int16_t band_start[], - const int16_t band_end[], - float y2[], - int16_t npulses[] ); - -void har_denorm_pulcnt( - float spectra[], /* i/o: MDCT domain spectrum */ - const int16_t band_start[], /* i : Number subbands/Frame */ - const int16_t band_end[], /* i : Band Start of each SB */ - const float band_energy[], /* i : Band end of each SB */ - const int16_t band_width[], - const int16_t npulses[], - const int16_t har_bands /* i : No. of harmonic bands */ -); - -int16_t har_est( - float spectra[], - const int16_t N, - int16_t *har_freq_est1, - int16_t *har_freq_est2, - int16_t *flag_dis, - int16_t *prev_frm_hfe2, - const int16_t subband_search_offset[], - const int16_t sbWidth[], - int16_t *prev_stab_hfe2 ); - -void spt_shorten_domain_pre( - const int16_t band_start[], - const int16_t band_end[], - const int16_t prev_SWB_peak_pos[], - const int16_t BANDS, - const int32_t bwe_br, - int16_t new_band_start[], - int16_t new_band_end[], - int16_t new_band_width[] ); - -void spt_shorten_domain_band_save( - const int16_t bands, - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - int16_t org_band_start[], - int16_t org_band_end[], - int16_t org_band_width[] ); - -void spt_shorten_domain_band_restore( - const int16_t bands, - int16_t band_start[], - int16_t band_end[], - int16_t band_width[], - const int16_t org_band_start[], - const int16_t org_band_end[], - const int16_t org_band_width[] ); - -void spt_swb_peakpos_tmp_save( - const float y2[], - const int16_t bands, - const int16_t band_start[], - const int16_t band_end[], - int16_t prev_SWB_peak_pos_tmp[] ); - -void hq_ecu( - const float *prevsynth, /* i : buffer of previously synthesized signal */ - float *ecu_rec, /* o : reconstructed frame in tda domain */ - int16_t *time_offs, /* i/o: Sample offset for consecutive frame losses*/ - float *X_sav, /* i/o: Stored spectrum of prototype frame */ - int16_t *num_p, /* i/o: Number of identified peaks */ - int16_t *plocs, /* i/o: Peak locations */ - float *plocsi, /* i/o: Interpolated peak locations */ - const float env_stab, /* i : Envelope stability parameter */ - int16_t *last_fec, /* i/o: Flag for usage of pitch dependent ECU */ - const int16_t ph_ecu_HqVoicing, /* i : HQ Voicing flag */ - int16_t *ph_ecu_active, /* i : Phase ECU active flag */ - float *gapsynth, /* o : Gap synthesis */ - const int16_t prev_bfi, /* i : indicating burst frame error */ - const int16_t old_is_transient[2], /* i : flags indicating previous transient frames*/ - float *mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ - float Xavg[LGW_MAX], /* i/o: Frequency group average gain to fade to */ - float *beta_mute, /* o : Factor for long-term mute */ - const int16_t output_frame, /* i : frame length */ - Decoder_State *st /* i/o: decoder state structure */ -); - -void peakfinder( - const float *x0, /* i : vector from which the maxima will be found */ - const int16_t len0, /* i : length of input vector */ - int16_t *plocs, /* o : the indicies of the identified peaks in x0 */ - int16_t *cInd, /* o : number of identified peaks */ - const float sel, /* i : The amount above surrounding data for a peak to be identified */ - const int16_t endpoints /* i : Flag to include endpoints in peak search */ -); - -/*! r: interpolated maximum position */ -float imax_pos( - const float *y /* i : Input vector for peak interpolation */ -); - - -void fft3( - const float X[], /* i : input frame */ - float Y[], /* o : DFT of input frame */ - const int16_t n /* i : block length (must be radix 3) */ -); - -void ifft3( - const float X[], /* i : input frame */ - float Y[], /* o : iDFT of input frame */ - const int16_t n /* i : block length (must be radix 3) */ -); - -/*! r: updated estimate of background noise */ -void minimumStatistics( - float *noiseLevelMemory, /* i/o: internal state */ - int16_t *noiseLevelIndex, /* i/o: internal state */ - int16_t *currLevelIndex, /* i/o: internal state (circular buffer) */ - float *noiseEstimate, /* i/o: previous estimate of background noise */ - float *lastFrameLevel, /* i/o: level of the last frame */ - float currentFrameLevel, /* i : level of the current frame */ - const float minLev, /* i : minimum level */ - const int16_t buffSize /* i : buffer size */ -); - -void E_ACELP_toeplitz_mul( - const float R[], - const float c[], - float d[] ); - -void E_ACELP_innovative_codebook( - const float *exc, /* i : pointer to the excitation frame */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - const int16_t T0_res, /* i : pitch resolution */ - const float pitch_gain, /* i : adaptive codebook gain */ - const float tilt_code, /* i : tilt factor */ - ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */ - const int16_t i_subfr, /* i : subframe index */ - const float *Aq, /* i : quantized LPC coefficients */ - const float *h1, /* i : impulse response of weighted synthesis filter */ - const float *xn, /* i : Close-loop Pitch search target vector */ - const float *cn, /* i : Innovative codebook search target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - float *y2, /* o : zero-memory filtered algebraic excitation */ - const int16_t acelpautoc, /* i : autocorrelation mode enabled */ - int16_t **pt_indice, /* i/o: quantization indices pointer */ - float *code, /* o : innovative codebook */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t last_L_frame, /* i : length of the last frame */ - const int32_t total_brate /* i : total bitrate */ -); - -int16_t E_ACELP_code43bit( - const float code[], - uint32_t *ps, - int16_t *p, - uint16_t idxs[] ); -void D_ACELP_indexing_ivas( - float code[], - PulseConfig config, - const int16_t num_tracks, - int16_t prm[], - int16_t *BER_detect ); - -void D_ACELP_decode_43bit( - uint16_t idxs[], - float code[], - int16_t *pulsestrack ); - -void fcb_pulse_track_joint_decode_ivas( - uint16_t *idxs, - const int16_t wordcnt, - uint32_t *index_n, - const int16_t *pulse_num, - const int16_t track_num ); - -void lag_wind_flt( - float r[], /* i/o: autocorrelations */ - const int16_t m, /* i : order of LP filter */ - const int32_t sr_core, /* i : sampling rate */ - const int16_t strength /* i : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */ -); - -void adapt_lag_wind_fx( - float r[], /* i/o: autocorrelations */ - const int16_t m, /* i : order of LP filter */ - const int16_t Top, /* i : open loop pitch lags from curr. frame (or NULL if n/a) */ - const float Tnc, /* i : open loop pitch gains from curr. frame (NULL if n/a) */ - const int32_t sr_core /* i : core sampling rate */ -); - -void core_coder_reconfig( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_total_brate /* i : last total bitrate */ -); - -void core_coder_mode_switch( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_total_brate, /* i : last bitrate */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void enc_acelp_tcx_main( - Encoder_State *st, /* i/o: encoder state structure */ - const float new_samples[], /* i : new samples */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const float lsp_new[M], /* i : LSPs at the end of the frame */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float pitch_buf[], /* o : floating pitch for each subframe */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void getTCXMode_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - Decoder_State *st0, /* i : bitstream */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void getTCXWindowing_ivas( - const Word16 core, /* i : current frame mode */ - const Word16 last_core, /* i : last frame mode */ - const Word16 element_mode, /* i : element mode */ - TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ - Decoder_State *st0 /* i : bitstream */ -); - -void getLPCparam_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t param_lpc[], /* o : LTP parameters */ - Decoder_State *st0, /* i : bitstream */ - const int16_t ch, /* i : channel */ - const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ -); - -void getTCXparam_ivas( - Decoder_State *st, /* i/o: Decoder State handle */ - Decoder_State *st0, /* i : bitstream */ - CONTEXT_HM_CONFIG hm_cfg, /* i/o: HM config */ - int16_t param[], /* o : decoded parameters */ - const int16_t bits_common, /* i : number of common bits */ - const int16_t start_bit_pos, /* i : position of the start bit */ - const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ - int16_t p_param[2], /* o : pointer to parameters for next round of bs reading*/ - int16_t nTnsBitsTCX10[2], - const int16_t pre_past_flag ); - -void pitch_pred_linear_fit_flt( - const int16_t nbLostCmpt, /* i : bfi counter */ - const int16_t last_good, /* i : last classification type */ - float *old_pitch_buf, /* i : pitch lag buffer */ - float *old_fpitch, /* i/o: pitch used for initial ACB generation */ - float *T0_out, /* o : estimated close loop pitch */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max, /* i : Maximum pitch lag */ - float *mem_pitch_gain, /* i : lag pitch gain [0] is the most recent subfr lag */ - const int16_t limitation, - const int16_t plc_use_future_lag, /* i : number of subframes to predict */ - int16_t *extrapolationFailed, /* o : flag if extrap decides not to change the pitch */ - const int16_t nb_subfr /* i : number of ACELP subframes */ -); - -void get_subframe_pitch_flt( - const int16_t nSubframes, /* i : number of subframes */ - float pitchStart, /* i : starting pitch lag (in subframe -1) */ - float pitchEnd, /* i : ending pitch lag (in subframe nSubframes-1) */ - float *pitchBuf /* o : interpolated pitch lag per subframe */ -); - -void core_encode_openloop( - Encoder_State *st, /* i/o: encoder state structure */ - const float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const float lsp_new[M], /* i : LSPs at the end of the frame */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - float *pitch_buf, /* i/o: floating pitch values for each subfr*/ - float *voice_factors, /* o : voicing factors */ - float *ptr_bwe_exc, /* o : excitation for SWB TBE */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void core_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - float *pitch_fr, /* i/o: fraction pitch values */ - float *voicing_fr, /* i/o: fractional voicing values */ - const float currTempFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac /* i : LP filter stability */ -); - -void core_encode_twodiv( - Encoder_State *st, /* i/o: coder memory state */ - const float new_samples[], /* i : new samples */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void core_encode_update( - Encoder_State *st /* i/o: encoder state structure */ -); - -void core_encode_update_cng( - Encoder_State *st, /* i/o: encoder state structure */ - float *timeDomainBuffer, - float *A, - const float Aw[] /* i : weighted A(z) unquant. for subframes*/ -); - -void core_signal_analysis_high_bitrate( - const float *new_samples, - const int16_t T_op[3], /* i : open-loop pitch values for quantiz. */ - float lsp_new[], - float lsp_mid[], - Encoder_State *st, - float *mdst_spectrum[2], - int16_t pTnsSize[], - int16_t pTnsBits[], - int16_t param_core[], - int16_t *ltpBits, - float *windowed_samples, /* i/o: backup of windowed time signal */ - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t last_element_mode, - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void encode_acelp_gains( - const float *code, - const int16_t gains_mode, - const float mean_ener_code, - const int16_t clip_gain, - ACELP_CbkCorr *g_corr, - float *gain_pit, - float *gain_code, - int16_t **pt_indice, - float *past_gcode, - float *gain_inov, - const int16_t L_subfr, - float *code2, - float *gain_code2, - const int16_t noisy_speech_flag ); - -int16_t gain_enc_gacelp_uv( - const float *code, /* i : algebraic excitation */ - const float *code2, /* i : gaussian excitation */ - const int16_t lcode, /* i : Subframe size */ - const float mean_ener, /* i : quantized mean energy of the frame */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_code2, /* o : quantized codebook gain */ - ACELP_CbkCorr *coeff, /* i/o: correlations , -2,, -2 and 2 */ - float *past_gcode, /* i/o: past gain of code */ - float *gain_inov, /* o : unscaled innovation gain */ - const int16_t noisy_speech_flag /* i : noisy speech flag */ -); - -int16_t Mode2_gain_enc_mless( - const float *code, /* i : algebraic excitation */ - const int16_t lcode, /* i : Subframe size */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - ACELP_CbkCorr *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const float mean_ener, /* i : mean_ener defined in open-loop (3 bits) */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - float *past_gcode, /* i/o: past gain of code */ - float *gain_inov, /* o : unscaled innovation gain */ - const int16_t coder_type /* i : type of coder */ -); - -void decode_acelp_gains( - const float *code, - const int16_t gains_mode, - const float mean_ener_code, - float *gain_pit, - float *gain_code, - int16_t **pt_indice, - float *past_gpit, - float *past_gcode, - float *gain_inov, - const int16_t L_subfr, - float *code2, - float *gain_code2 ); - -void gain_dec_gacelp_uv( - int16_t index, /* i/o: Quantization index vector */ - const float *code, /* i : algebraic code excitation */ - const float *code2, /* i : algebraic code excitation */ - const float mean_ener, /* i : mean energy */ - const int16_t lcode, /* i : Subframe size */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codebook gain */ - float *gain_code2, /* o : Quantized codebook gain */ - float *past_gpit, /* i/o: past gain of pitch */ - float *past_gcode, /* i/o: past energy of code */ - float *gain_inov /* o : unscaled innovation gain */ -); - -void limit_T0_voiced_ivas( - const int16_t nbits, - const int16_t res, - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - const int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_min_frac, /* o : lower pitch limit */ - int16_t *T0_max, /* o : higher pitch limit */ - int16_t *T0_max_frac, /* o : higher pitch limit */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max /* i : Maximum pitch lag */ -); - - -/*! r: floating pitch value */ -float Mode2_pit_decode_flt( - const int16_t coder_type, /* i : coding model */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t L_subfr, /* i : sub-frame length */ - int16_t **pt_indice, /* i/o: quantization indices pointer */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_res, /* i/o: pitch resolution */ - int16_t *T0_min, /* i/o: lower limit for close-loop search */ - int16_t *T0_min_frac, /* i/o: lower limit for close-loop search */ - int16_t *T0_max, /* i/o: higher limit for close-loop search */ - int16_t *T0_max_frac, /* i/o: higher limit for close-loop search */ - const int16_t pit_min, - const int16_t pit_fr1, - const int16_t pit_fr1b, - const int16_t pit_fr2, - const int16_t pit_max, - const int16_t pit_res_max ); - -void Mode2_abs_pit_dec_flt( - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_res, /* o : pitch resolution */ - int16_t **pt_indice, /* i/o: pointer to Vector of Q indexes */ - const int16_t pit_min, - const int16_t pit_fr1, - const int16_t pit_fr2, - const int16_t pit_res_max ); - -void Mode2_delta_pit_dec_flt( - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* i : delta search min */ - int16_t *T0_min_frac, /* i : delta search min */ - int16_t **pt_indice /* i/o: pointer to Vector of Q indexes */ -); - -void formant_post_filt_ivas( - PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ - float *synth_in, /* i : 12k8 synthesis */ - const float *Aq, /* i : LP filter coefficient */ - float *synth_out, /* i/o: input signal */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : sub-frame length */ - const float lp_noise, /* i : background noise energy */ - const int32_t brate, /* i : bitrate */ - const int16_t off_flag /* i : Off flag */ -); - - -int16_t dlpc_avq( - int16_t *index, /* i : Quantization indices */ - float *LSF_Q, /* o : Quantized LSF vectors */ - const int16_t numlpc, /* i : Number of sets of lpc */ - const int32_t sr_core /* i : internal sampling rate */ -); - -int16_t decode_lpc_avq( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t numlpc, /* i : Number of sets of lpc */ - int16_t *param_lpc, /* o : lpc parameters */ - const int16_t ch, /* i : channel */ - const int16_t element_mode, /* i : element mode */ - const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ -); - - -void vlpc_2st_dec_flt( - float *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ - int16_t *indx, /* i : index[] (4 bits per words) */ - const int16_t mode, /* i : 0=abs, >0=rel */ - const int32_t sr_core /* i : internal sampling rate */ -); - -void lsf_weight_2st_flt( - const float *lsfq, - float *w, - const int16_t mode, - const int32_t sr_core ); - -void mdct_window_sine_flt( - float *window, - const int32_t Fs, - const int16_t n, - const int16_t window_type, - const int16_t element_mode ); - -void mdct_window_aldo_flt( - float *window1, - float *window2, - const int16_t n ); - -void AVQ_cod_lpc( - const float nvec[], /* i : vector to quantize */ - int16_t nvecq[], /* o : quantized normalized vector (assuming the bit budget is enough) */ - int16_t *indx, /* o : index[] (4 bits per words) */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void AVQ_dec_lpc_ivas( - const int16_t indx[], /* i : index[] (4 bits per words) */ - int16_t nvecq[], /* o : vector quantized */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void vlpc_1st_dec_flt( - const int16_t index, /* i : codebook index */ - float *lsfq, /* i/o: i:prediction o:quantized lsf */ - const int32_t sr_core ); - -void WindowSignal_flt( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - int16_t offset, /* i : left folding point offset relative to the input signal pointer */ - const int16_t left_overlap_mode, /* i : overlap mode of left window half */ - const int16_t right_overlap_mode, /* i : overlap mode of right window half */ - int16_t *left_overlap_length, /* o : TCX window left overlap length */ - int16_t *right_overlap_length, /* o : TCX window right overlap length */ - const float in[], /* i : input signal */ - int16_t *L_frame, /* i/o: frame length */ - float out[], /* o : output windowed signal */ - const int16_t truncate_aldo, /* i : nonzero to truncate long ALDO slope */ - const int16_t fullband /* i : fullband flag */ -); - -void HBAutocorrelation( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - float speech[], /* i : speech */ - int16_t L_frame_glob, /* i/o: frame length */ - float *r /* o : autocorrelations vector */ -); - -void TNSAnalysis( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const int16_t L_frame, /* i : frame length */ - int16_t L_spec, /* i : length of the spectrum */ - const int16_t transform_type, /* i : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */ - const int16_t isAfterACELP, /* i : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */ - float spectrum[], /* i : MDCT spectrum of the subframe */ - TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ - const float ltp_gain, /* i : ltp gain */ - STnsData *pTnsData, /* o : TNS data */ - int8_t *pfUseTns, /* o : Flag indicating if TNS is used */ - float *predictionGain /* o : TNS prediction gain */ -); - -void CalculateTnsFilt( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - const float pSpectrum[], /* i : MDCT spectrum */ - STnsData *pTnsData, /* o : TNS data struct */ - float *predictionGain /* o : TNS prediction gain */ -); - -void ShapeSpectrum( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - float gainlpc[], /* o : MDCT gains for the previous frame */ - const int16_t L_frame_glob, /* i : frame length */ - int16_t L_spec, /* i : length of the spectrum */ - float spectrum[], /* i/o: MDCT spectrum */ - const int8_t fUseTns, /* i : Flag indicating if TNS is used */ - Encoder_State *st, /* i/o: encoder state structure */ - float *scf /* i : scale factors */ -); - -void QuantizeSpectrum( - Encoder_State *st, /* i/o: encoder state structure */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coeffs (M+1) */ - float gainlpc[], /* i : MDCT gains of the previous frame */ - float synth[], /* o : synthesis buffer */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - int16_t prm[], /* o : tcx parameters */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -/*! r: index of next coefficient */ -int16_t get_next_coeff_mapped_ivas( - int16_t ii[2], /* i/o: coefficient indexes */ - int32_t *pp, /* o : peak(1)/hole(0) indicator */ - int16_t *idx, /* o : index in unmapped domain */ - CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ -); - - -void ACcontextMapping_encode2_no_mem_s17_LC( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - int16_t nt, - int16_t lastnz, - int16_t nbbits, - int16_t resQMaxBits, - CONTEXT_HM_CONFIG *hm_cfg ); - -int16_t ACcontextMapping_decode2_no_mem_s17_LC_ivas( - Decoder_State *st, /* i/o: decoder state */ - int16_t *x, /* o : decoded spectrum */ - int16_t nt, /* i : size of spectrum */ - int16_t nbbits, /* i : bit budget */ - int16_t resQMaxBits, /* i : residual coding maximum bits */ - CONTEXT_HM_CONFIG *hm_cfg /* i : context-based harmonic model configuration */ -); - -int16_t ACcontextMapping_encode2_estimate_no_mem_s17_LC( - const int16_t *x, - const int16_t nt, - int16_t *lastnz, - int16_t *nEncoded, - const int16_t target, - int16_t *stop, - CONTEXT_HM_CONFIG *hm_cfg ); - -void RCcontextMapping_encode2_no_mem_s17_LCS( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - const int16_t nt, - int16_t lastnz, - const int16_t nbbits, - const int16_t resQMaxBits, - CONTEXT_HM_CONFIG *hm_cfg ); - -int16_t RCcontextMapping_decode2_no_mem_s17_LCS( - Decoder_State *st, /* i/o: decoder state */ - int16_t *x, /* o : decoded spectrum */ - const int16_t nt, /* i : size of spectrum */ - const int16_t nbbits, /* i : bit budget */ - const int16_t resQMaxBits, /* i : residual coding maximum bits */ - CONTEXT_HM_CONFIG *hm_cfg /* i : context-based harmonic model configuration */ -); - -int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( - int16_t *x, /* Spectral coefficients */ - const int16_t nt, /* L - size of spectrum (no. of spectral coefficients) */ - int16_t *lastnz_out, - int16_t *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ - const int16_t target, /* Target bits */ - int16_t *stop, - int16_t mode, - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ -); - -Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( - Word16 *x, /* Q0 */ - const Word16 nt, /* Q0 */ - const Word16 target, /* Q0 */ - HANDLE_RC_CONTEXT_MEM hContextMem ); - -Word16 RCcontextMapping_encode2_estimate_bandWise_fx( - Word16 *x, /* Q0 */ - const Word16 start_line, /* Q0 */ - const Word16 end_line, /* Q0 */ - HANDLE_RC_CONTEXT_MEM hContextMem /* Q0 */ -); - -void tcx_get_windows_flt( - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - int16_t *left_overlap, /* o : left overlap length */ - const float **left_win, /* o : left overlap window */ - int16_t *right_overlap, /* o : right overlap length */ - const float **right_win, /* o : right overlap window */ - const int16_t fullband /* i : fullband flag */ -); - -void tcx_windowing_analysis_flt( - const float *signal, /* i : signal vector */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_overlap, /* i : left overlap length */ - const float *left_win, /* i : left overlap window */ - const int16_t right_overlap, /* i : right overlap length */ - const float *right_win, /* i : right overlap window */ - float *output /* o : windowed signal vector */ -); - -void tcx_windowing_synthesis_current_frame_flt( - float *signal, /* i/o: signal vector */ - const float *window, /* i : TCX window vector */ - const float *window_half, /* i : TCX window vector for half-overlap window */ - const float *window_min, /* i : TCX minimum overlap window */ - const int16_t window_length, /* i : TCX window length */ - const int16_t window_half_length, /* i : TCX half window length */ - const int16_t window_min_length, /* i : TCX minimum overlap length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t left_mode, /* i : overlap mode of left window half */ - float *acelp_zir, /* i/o: acelp ZIR */ - const float *old_syn, /* i : old synthesis */ - const float *syn_overl, /* i : overlap synthesis */ - const float *A_zir, - const float *window_trans, /* i : window for transition from ACELP */ - int16_t acelp_zir_len, - const int16_t acelp_mem_len, - const int16_t last_core_bfi, /* i : last mode */ - const int16_t last_is_cng, - const int16_t fullbandScale ); - -void tcx_windowing_synthesis_past_frame_flt( - float *signal, /* i/o: signal vector */ - const float *window, /* i : TCX window vector */ - const float *window_half, /* i : TCX window vector for half-overlap window */ - const float *window_min, /* i : TCX minimum overlap window */ - const int16_t window_length, /* i : TCX window length */ - const int16_t window_half_length, /* i : TCX half window length */ - const int16_t window_min_length, /* i : TCX minimum overlap length */ - const int16_t right_mode /* i : overlap mode (left_mode of current frame) */ -); - -void ProcessIGF( - Encoder_State *st, /* i : Encoder state */ - float *pMDCTSpectrum, /* i : MDCT spectrum */ - const float *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int16_t frameno, /* i : flag indicating index of current subframe */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void ProcessStereoIGF( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - float *pITFMDCTSpectrum[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subframe*/ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void AnalyzePowerSpectrum( - Encoder_State *st, /* i/o: encoder states */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_frameTCX, /* i : full band frame length */ - const int16_t left_overlap, /* i : left overlap length */ - const int16_t right_overlap, /* i : right overlap length */ - const float mdctSpectrum[], /* i : MDCT spectrum */ - const float signal[], /* i : windowed signal corresponding to mdctSpectrum */ - float powerSpec[] /* o : Power spectrum */ -); - -void lpc2mdct_flt( - float *lpcCoeffs, - const int16_t lpcOrder, - float mdct_gains[], - const int16_t length, - const int16_t noInverse ); - -void mdct_preShaping( - float x[], - const int16_t lg, - const float gains[] ); - -void mdct_noiseShaping_flt( - float x[], - const int16_t lg, - const float gains[], - const int16_t nBands ); - - -void PsychAdaptLowFreqDeemph_flt( - float x[], - const float lpcGains[], - float lf_deemph_factors[] ); - -void AdaptLowFreqDeemph_flt( - float x[], - int16_t tcx_lpc_shaped_ari, - const float lpcGains[], - const int16_t lg, - float lf_deemph_factors[] ); - - -void tcx_noise_filling_flt( - float *Q, - const int16_t noiseFillSeed, - const int16_t iFirstLine, - const int16_t lowpassLine, - const int16_t nTransWidth, - const int16_t L_frame, - const float tiltCompFactor, - float fac_ns, - Word16 *infoTCXNoise, - const int16_t element_mode /* i : IVAS element mode */ -); - - -void tcx_decoder_memory_update_flt( - Decoder_State *st, /* i/o: decoder memory state */ - const float *xn_buf, /* i : mdct output buffer */ - float *synth, /* i/o: synth */ - const float *A /* i : Quantized LPC coefficients */ -); - - -/*! r: number of bits used (including "bits") */ -int16_t tcx_ari_res_invQ_spec_flt( - float x_Q[], /* i/o: quantized spectrum */ - const int16_t L_frame, /* i : number of lines */ - const int16_t prm[], /* i : bitstream */ - int16_t target_bits, /* i : number of bits available */ - int16_t bits, /* i : number of bits used so far */ - const float deadzone, /* i : quantizer deadzone */ - const float x_fac[] /* i : spectrum post-quantization factors */ -); - - -void ari_copy_states( - Tastat *source, - Tastat *dest ); - - -void ari_start_encoding_14bits( - Tastat *s ); - - -void ari_start_decoding_14bits_ivas( - Decoder_State *st, - Tastat *s ); - -int16_t ari_start_decoding_14bits_prm_ivas( - const int16_t *ptr, - int16_t bp, - Tastat *s ); - -void ari_decode_14bits_s17_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s, - const uint16_t *cum_freq ); - -void ari_decode_14bits_s27_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s, - const uint16_t *cum_freq ); - -void ari_decode_14bits_bit_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s ); - -/*! r: Q15 */ -Word16 expfp_evs_fx( - const Word16 x, /* i : mantissa Q15-e */ - const Word16 x_e /* i : exponent Q0 */ -); - - -void tcx_arith_render_envelope_ivas_fx( - const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/ - const Word16 L_frame, /* i : number of spectral lines Q0*/ - const Word16 L_spec, /* i : length of the coded spectrum Q0*/ - const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/ - const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/ - const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/ - Word32 env[] /* o : shaped signal envelope Q16*/ -); - -int16_t ari_encode_14bits_range( - int16_t *ptr, - int16_t bp, - int32_t bits, - Tastat *s, - uint16_t cum_freq_low, - uint16_t cum_freq_high ); - - -int16_t ari_done_cbr_encoding_14bits( - int16_t *ptr, - int16_t bp, - int32_t bits, - Tastat *s ); - - -void tcx_arith_encode_envelope( - float spectrum[], /* i/o: MDCT coefficients */ - int16_t signs[], /* o : signs (spectrum[.]<0) */ - const int16_t L_frame, /* i : frame or MDCT length */ - const int16_t L_spec, /* i : length w/o BW limitation */ - Encoder_State *st, /* i/o: coder state */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - int16_t target_bits, /* i : number of available bits */ - int16_t prm[], /* o : bitstream parameters */ - const int16_t use_hm, /* i : use HM in current frame? */ - int16_t prm_hm[], /* o : HM parameter area */ - const int16_t tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - int16_t *arith_bits, /* o : bits used for ari. coding */ - int16_t *signaling_bits, /* o : bits used for signaling */ - const int16_t low_complexity /* i : low-complexity flag */ -); - -void tcx_arith_decode_envelope( - Decoder_State *st, /* i/o: coder state */ - float q_spectrum[], /* o : quantised MDCT coefficients */ - const int16_t L_frame, /* i : frame or MDCT length */ - int16_t L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const int16_t target_bits, /* i : number of available bits */ - const int16_t prm[], /* i : bitstream parameters */ - const int16_t use_hm, /* i : use HM in current frame? */ - const int16_t prm_hm[], /* i : HM parameter area */ - int16_t tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - int16_t *arith_bits, /* o : bits used for ari. coding */ - int16_t *signaling_bits, /* o : bits used for signaling */ - const int16_t low_complexity /* i : low-complexity flag */ -); - -void tcx_arith_decode_envelope_ivas_fx( - Decoder_State *st, /* i/o: coder state */ - Word32 q_spectrum[], /* o : quantised MDCT coefficients */ - Word16 *q_spectrum_e, /* o : MDCT exponent */ - const Word16 L_frame, /* i : frame or MDCT length */ - Word16 L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const Word16 target_bits, /* i : number of available bits */ - Word16 prm[], /* i : bitstream parameters */ - const Word16 use_hm, /* i : use HM in current frame? */ - const Word16 prm_hm[], /* i : HM parameter area */ - Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - Word16 *arith_bits, /* o : bits used for ari. coding */ - Word16 *signaling_bits, /* o : bits used for signaling */ - const Word16 low_complexity /* i : low-complexity flag */ -); - - -void UnmapIndex_fx( - const Word16 PeriodicityIndex, /* Q0 */ - const Word16 Bandwidth, /* Q0 */ - const Word16 LtpPitchLag, /* Q0 */ - const Word8 SmallerLags, /* Q0 */ - Word16 *FractionalResolution, /* Q0 */ - Word32 *Lag /* Q0 */ -); - -/*! r: PeriodicityIndex */ -int16_t SearchPeriodicityIndex( - const float Mdct[], /* i : Coefficients, Mdct[0..NumCoeffs-1] */ - const float UnfilteredMdct[], /* i : Unfiltered coefficients, UnfilteredMdct[0..NumCoeffs-1] */ - const int16_t NumCoeffs, /* i : Number of coefficients */ - const int16_t shortTargetBits, /* i : Target bit budget (excl. Done flag) */ - const int16_t LtpPitchLag, /* i : TCX-LTP pitch */ - const float LtpGain, /* i : LTP gain */ - float *RelativeScore /* o : Energy concentration factor */ -); - - -int16_t EncodeIndex( - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t PeriodicityIndex, - BSTR_ENC_HANDLE hBstr ); - - -Word16 CountIndexBits_fx( - Word16 Bandwidth, /* 0: NB, 1: (S)WB Q0*/ - Word16 PeriodicityIndex /* Q0 */ -); - -int16_t DecodeIndex( - Decoder_State *st, - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t *PeriodicityIndex ); - -#define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) -#define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) - - -Word32 tcx_hm_render_fx( - const Word32 lag, /* i: pitch lag Q0 */ - const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ - Word16 p[] /* o: harmonic model Q13 */ -); - - -void tcx_hm_modify_envelope_fx( - const Word16 gain, /* i: HM gain Q11 */ - const Word32 lag, /* i: pitch lag Q0 */ - const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ - const Word16 p[], /* i: harmonic model Q13 */ - Word32 env[], /* i/o: envelope Q16 */ - const Word16 L_frame /* i: number of spectral lines Q0 */ -); - -void tcx_hm_analyse( - const float abs_spectrum[], /* i : absolute spectrum */ - const int16_t L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const int16_t targetBits, /* i : target bit budget */ - const int16_t coder_type, /* i : GC/VC coder type */ - int16_t prm_hm[], /* o : HM parameters */ - int16_t LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - const float LtpGain, /* i : LTP gain */ - int16_t *hm_bits /* o : bit consumption */ -); - -void tcx_hm_decode_ivas( - const int16_t L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const int16_t targetBits, /* i : target bit budget */ - const int16_t coder_type, /* i : GC/VC coder type */ - const int16_t prm_hm[], /* i : HM parameters */ - const int16_t LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - int16_t *hm_bits /* o : bit consumption */ -); - -void tcx_hm_decode( - const Word16 L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const Word16 targetBits, /* i : target bit budget */ - const Word16 coder_type, /* i : GC/VC coder type */ - const Word16 prm_hm[], /* i : HM parameters */ - const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - Word16 *hm_bits /* o : bit consumption */ -); - -void coder_tcx( - Encoder_State *st, /* i/o: encoder state structure */ - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ - float synth[], /* o : decoded synthesis */ - const int16_t L_frame_glob, /* i : frame length */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - int16_t nb_bits, /* i : bit budget */ - float spectrum[], /* i/o: MDCT spectrum */ - int16_t prm[], /* o : tcx parameters */ - CONTEXT_HM_CONFIG *hm_cfg, - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void coder_tcx_post( - Encoder_State *st, /* i/o: encoder memory state */ - float *A, /* o : Quantized LPC coefficients */ - const float *Ai /* i : Unquantized (interpolated) LPC coefficients */ -); - -void decoder_tcx( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - float A[], /* i : coefficients NxAz[M+1] */ - Word16 Aind[], /* i : frame-independent coefficients Az[M+1]*/ - float synth[], /* i/o: synth[-M..lg] */ - float synthFB[], /* i/o: encoder memory state */ - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void decoder_tcx_post( - Decoder_State *st, /* i/o: decoder memory state */ - float *synth, - float *synthFB, - float *A, /* i : A(z) filter coefficients */ - const int16_t bfi, - const int16_t isMCT ); - -void coder_acelp( - Encoder_State *st, /* i/o: coder memory state */ - const float A[], /* i : coefficients 4xAz[M+1] */ - const float Aq[], /* i : coefficients 4xAz_q[M+1] */ - const float speech[], /* i : speech[-M..lg] */ - LPD_state *LPDmem, /* i/o: ACELP memories */ - int16_t *prm, /* o : acelp parameters */ - const float stab_fac, - const int16_t target_bits, - float *gain_pitch_buf, /* o : gain pitch values */ - float *gain_code_buf, /* o : gain code values */ - float *pitch_buf, /* o : pitch values for each subfr.*/ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void coder_acelp_rf( - const int16_t target_bits, /* i : target bits */ - const float speech[], /* i : speech[-M..lg] */ - const int16_t coder_type, /* i : coding type */ - const int16_t rf_frame_type, /* i : rf_frame_type */ - const float A[], /* i : coefficients 4xAz[M+1] */ - const float Aq[], /* i : coefficients 4xAz_q[M+1] */ - const float voicing[], /* i : open-loop LTP gain */ - const int16_t T_op[], /* i : open-loop LTP lag */ - const float stab_fac, /* i : LP stability factor */ - Encoder_State *st, /* i/o: coder memory state */ - ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */ - float *exc_rf, /* i/o: pointer to RF excitation */ - float *syn_rf /* i/o: pointer to RF synthesis */ -); - -void decoder_acelp( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - const float A[], /* i : coefficients NxAz[M+1] */ - ACELP_config acelp_cfg, /* i : ACELP config */ - float synth[], /* i/o: synthesis */ - int16_t *pT, /* o : pitch for all subframe */ - float *pgainT, /* o : pitch gain for all subfr */ - const float stab_fac, /* i : stability of isf */ - float *pitch_buffer, /* o : pitch values for each subfr.*/ - float *voice_factors, /* o : voicing factors */ - const int16_t LSF_Q_prediction, /* i : LSF prediction mode */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void writeTCXMode_fx( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ - Word16 *nbits_start /* o : nbits start Q0*/ -); - -void writeTCXWindowing_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 overlap_mode /* i : overlap mode Q0*/ -); - -void writeLPCparam( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const int16_t param_lpc[], /* i : LPC parameters to write */ - const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ - const int16_t no_param_lpc, /* i : number of LPC parameters */ - int16_t *nbits_lpc /* o : LPC bits written */ -); - -void enc_prm( - Encoder_State *st, /* i/o: encoder state structure */ - int16_t param[], /* i : parameters */ - int16_t param_lpc[], /* i : LPC parameters */ - CONTEXT_HM_CONFIG hm_cfg[], - const int16_t bits_param_lpc[], - const int16_t no_param_lpc ); - -void writeTCXparam( - Encoder_State *st, /* i/o: Encoder State handle */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ - int16_t param[], /* i : parameters */ - const int16_t nbits_header, - const int16_t nbits_start, - const int16_t nbits_lpc, - const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ - int16_t p_param[2], /* i/o: pointer to parameters from previous bs writing */ - const int16_t target_bitsTCX10[2], - const int16_t pre_past_flag ); - -void enc_prm_rf( - Encoder_State *st, /* i/o: encoder memory state */ - const int16_t rf_frame_type, - const int16_t fec_offset ); - -void dec_prm_hm_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t *prm_hm, - const int16_t hm_size ); - -void dec_prm_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t param[], /* o : decoded parameters */ - int16_t param_lpc[], /* i : LPC parameters */ - int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ - int16_t *bitsRead ); -void gaus_L2_dec_flt( - float *code, /* o : decoded gaussian codevector */ - float tilt_code, - const float *A, - float formant_enh_num, - int16_t *seed_acelp /* i/o: random seed */ -); - -/*! r: interpolated value */ -float interpolation( - const float *x, /* i : input vector */ - const float *win, /* i : interpolation window */ - const int16_t frac, /* i : fraction */ - const int16_t up_samp, /* i : upsampling factor */ - const int16_t nb_coef /* i : nb of filter coef */ -); - -void predict_signal_flt( - const float excI[], /* i : input excitation buffer */ - float excO[], /* o : output excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const int16_t frac_max, /* i : max fraction */ - const int16_t L_subfr /* i : subframe size */ -); - -void tcx_ltp_encode( - Encoder_State *st, - const int16_t tcxMode, - const int16_t L_frame, - const float *speech, - float *speech_ltp, - const float *wsp, - const int16_t Top[], - int16_t *ltp_param, - int16_t *ltp_bits, - float *A, - const int16_t disable_ltp, - const int16_t element_mode ); - -void tcx_ltp_post_flt( - Decoder_State *st, - TCX_LTP_DEC_HANDLE hTcxLtpDec, - const int16_t core, - const int16_t output_frame, - const int16_t L_frame, - float sig[], - const float tcx_buf[] ); - -int16_t tcx_ltp_decode_params_flt( - int16_t *ltp_param, - int16_t *pitch_int, - int16_t *pitch_fr, - float *gain, - const int16_t pitmin, - const int16_t pitfr1, - const int16_t pitfr2, - const int16_t pitmax, - const int16_t pitres ); - -void create_IDCT_N_Matrix( - float *inv_matrixFloatQ, /* i/o: RAM buffer */ - const int16_t N, /* i : DCT length, number of time samples */ - const int16_t n_cols, /* i : number of dct coeffs (as DCT may be truncated) */ - const int16_t alloc_size /* i : RAM buffer size in elements */ -); - -void dctT2_N_apply_matrix( - const float *input, /* i : input in fdcng or DCT(fdcng) domain */ - float *output, /* o : output in DCT(fdcng) or fdcng ordomain */ - const int16_t dct_dim, /* i : dct processing dim possibly truncated */ - const int16_t fdcngvq_dim, /* i : fdcng domain length */ - const float *matrix, /* i : IDCT matrix */ - const int16_t matrix_row_dim, /* i : */ - const DCTTYPE dcttype /* i : matrix operation type */ -); - -void extend_dctN_input( - const float *input, /* i : input in fdcng domain */ - const float *dct_input, /* i : input in dctN(fdcng) domain */ - const int16_t in_dim, /* i : in_dim == N */ - float *ext_sig, /* o : extended output in fdcng domain */ - const int16_t out_dim, /* i : output total dim */ - float *matrix, /* i : idct synthesis matrix N rows, n_cols columns */ - const int16_t n_cols, /* i : number of columns == DCT truncation length */ - const DCTTYPE dcttype /* i : matrix operation type */ -); - - -void PulseResynchronization( - const float *src_exc, /* i : Input excitation buffer */ - float *dst_exc, /* o : output excitation buffer */ - const int16_t nFrameLength, /* i : frame length */ - const int16_t nSubframes, /* i : Number of subframes */ - const float pitchStart, /* i : Pitch at the end of the last frame */ - const float pitchEnd /* i : Pitch at the end of the current frame */ -); - -void con_acelp( - float A[], /* i : coefficients NxAz[M+1] */ - const int16_t coder_type, /* i : ACELP coder type */ - float synth[], /* i/o: synthesis */ - int16_t *pT, /* o : pitch for all subframe */ - float *pgainT, /* o : pitch gain for all subfr */ - float stab_fac, /* i : stability of isf */ - Decoder_State *st, /* i/o: coder memory state */ - float pitch_buffer[], /* i/o: floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void con_tcx( - Decoder_State *st, /* i/o: coder memory state */ - float synth[], /* i/o: synth[] */ - const float coh, /* i : coherence of stereo signal */ - int16_t *noise_seed, /* i/o: noise seed for stereo */ - const int16_t only_left, /* i : TD-PLC only in left channel */ - const float A_cng[] /* i : CNG LP filter coefficients */ -); - -int16_t lsf_msvq_ma_decprm_ivas( - Decoder_State *st, - int16_t *param_lpc ); - -int16_t dec_lsf_tcxlpc_ivas( - Decoder_State *st, /* i : Decoder state */ - int16_t **indices, /* o : Ptr to VQ indices */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk /* i : codebook selector */ -); - -int16_t D_lsf_tcxlpc_ivas( - const int16_t indices[], /* i : VQ indices */ - float lsf_q[], /* o : quantized lsf */ - Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk, /* i : codebook selector */ - const float mem_MA[] /* i : MA memory */ -); - -int16_t Q_lsf_tcxlpc( - /* const */ float lsf[], /* i : original lsf */ - float lsf_q[], /* o : quantized lsf */ - Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ - int16_t indices[], /* o : VQ indices */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk, /* i : codebook selector */ - const float mem_MA[], /* i : MA memory */ - const int16_t coder_type, /* i : acelp extended mode */ - const float *Bin_Ener /* i : Spectrum energy */ -); - -void midlsf_enc( - const float qlsf0[], - const float qlsf1[], - const float lsf[], - int16_t *idx, - const int16_t N, - const float *Bin_Ener, - const int16_t narrowBand, - const int32_t sr_core, - const int16_t coder_type ); - -void lsf_end_enc( - Encoder_State *st, - const float *lsf, - float *qlsf, - const int16_t nBits, - const int16_t coder_type_org, - const int16_t force_sf, - int16_t *lpc_param, - int16_t *no_stages, - int16_t *bits_param_lpc, - const int16_t coder_type_raw, - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void lsf_end_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t coder_type_org, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t nBits, /* i : number of bits used for ISF quantization*/ - float *qlsf, /* o : quantized LSFs in the cosine domain */ - int16_t *lpc_param, /* i : LPC parameters */ - int16_t *LSF_Q_prediction, /* o : LSF prediction mode */ - int16_t *nb_indices, /* o : number of indices */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void lpc_quantization( - Encoder_State *st, - const float lsp[], - const float lspmid[], - float lsp_q[], - float lsf_q[], - float lspmid_q[], - const int16_t coder_type, - const int16_t acelp_midLpc, - int16_t param_lpc[], - int16_t nbits_lpc[], - int16_t *bits_param_lpc, - int16_t *no_param_lpc ); - -void lpc_unquantize( - Decoder_State *st, - float *lsf, - float *lsp, - int16_t *param_lpc, - float *lspmid, - float *lsfmid, - const int16_t coder_type, - int16_t *LSF_Q_prediction /* o : LSF prediction mode */ -); - -void dlpc_bfi_flt( - const int16_t L_frame, - float *lsf_q, /* o : quantized lsfs */ - const float *lsfold, /* i : past quantized lsf */ - const int16_t last_good, /* i : last good received frame */ - const int16_t nbLostCmpt, /* i : counter of consecutive bad frames */ - float mem_MA[], /* i/o: quantizer memory for MA model */ - float mem_AR[], /* i/o: quantizer memory for MA model */ - float *stab_fac, /* i : lsf stability factor */ - float *lsf_adaptive_mean, /* i : lsf adaptive mean, updated when BFI==0 */ - const int16_t numlpc, /* i : Number of division per superframe */ - float lsf_cng[], - const int16_t plcBackgroundNoiseUpdated, - float *lsf_q_cng, /* o : quantized lsfs of background noise */ - float *old_lsf_q_cng, /* o : old quantized lsfs for background noise */ - const float lsfBase[] /* i : base for differential lsf coding */ -); - -void Unified_weighting( - const float Bin_Ener_128[], /* i : FFT Bin energy 128 bins in two sets */ - const float lsf[], /* i : LSF vector */ - float w[], /* o : LP weighting filter (numerator) */ - const int16_t narrowBand, /* i : flag for Narrowband */ - const int16_t unvoiced, /* i : flag for Unvoiced frame */ - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t order /* i : LP order */ -); - -int16_t vad_init( - VAD_CLDFB_HANDLE hVAD_CLDFB /* i/o: CLDFB VAD state */ -); - -int16_t vad_proc( - float realValues[16][60], /* i : CLDFB real values */ - float imagValues[16][60], /* i : CLDFB imag values */ - float *sb_power, /* i/o: Energy of CLDFB data */ - const int16_t numBands, /* i : number of input bands */ - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - int16_t *cldfb_addition, - const int16_t vada_flag /* i : VAD flag */ -); - - -int16_t update_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const float snr, /* i : frequency domain SNR */ - const float tsnr, /* i : time domain SNR */ - const float frame_energy, /* i : current frame energy */ - const float high_eng, /* i : current frame high frequency energy */ - const int16_t vad_flag, /* i : VAD flag */ - const int16_t music_backgound_f /* i : background music flag */ -); - -void frame_spec_dif_cor_rate( - float spec_amp[], /* i : spectral amplitude */ - float pre_spec_low_dif[], /* i/o: low spectrum different */ - float f_tonality_rate[] /* o : tonality rate */ -); - - -void SNR_calc( - const float frame_sb_energy[], /* i : energy of sub-band divided non-uniformly*/ - const float sb_bg_energy[], /* i : sub-band background energy */ - const float t_bg_energy, /* i : time background energy of several frames*/ - float *snr, /* o : frequency domain SNR */ - float *tsnr, /* o : time domain SNR */ - const float frame_energy, /* i : current frame energy */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void background_update( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - float frame_energy, /* i : current frame energy 2 */ - const int16_t update_flag, /* i : current frame update flag */ - const int16_t music_backgound_f, /* i : background music flag */ - const float snr ); - -void bg_music_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - int16_t *music_backgound_f, /* i : background music flag */ - const float frame_energy /* i : current frame energy 1 */ -); - -void est_energy( - float sb_power[], /* o : energy of sub-band divided uniformly */ - float frame_sb_energy[], /* o : energy of sub-band divided non-uniformly*/ - float *p_frame_energy, /* o : frame energy 1 */ - float *p_frame_energy2, /* o : frame energy 2 */ - float *p_high_energy, /* o : high frequency energy */ - const int16_t bw /* i : bandwidth */ -); - - -int16_t comvad_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const float snr, /* i : frequency domain SNR */ - const float tsnr, /* i : time domain SNR */ - const float snr_flux, /* i : average tsnr of several frames */ - const float lt_snr, /* i : long time SNR calculated by fg_energy and bg_energy*/ - const float lt_snr_org, /* i : original long time SNR */ - const float lf_snr, /* i : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const float frame_energy, /* i : current frame energy */ - const int16_t music_backgound_f, /* i : background music flag */ - int16_t *cldfb_addition, - const int16_t vada_flag /* i : VAD flag */ -); - -void calc_snr_flux( - float tsnr, /* i : time-domain SNR */ - float pre_snr[], /* i/o: time-domain SNR storage */ - float *snr_flux /* o : average tsnr */ -); - -void calc_lt_snr( - float *lt_snr_org, /* o : original long time SNR */ - float *lt_snr, /* o : long time SNR calculated by fg_energy and bg_energy*/ - const float fg_energy, /* i : foreground energy sum */ - const int16_t fg_energy_count, /* i : number of the foreground energy frame */ - const float bg_energy, /* i : background energy sum */ - const int16_t bg_energy_count, /* i : number of the background energy frame */ - const int16_t bw_index, /* i : band width index */ - const float lt_noise_sp_center0 /* i : long time noise spectral center by 0 */ -); - -void calc_lf_snr( - float *lf_snr_smooth, /* o : smoothed lf_snr */ - float *lf_snr, /* o : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const float l_speech_snr, /* i : sum of active frames snr */ - const int16_t l_speech_snr_count, /* i : number of the active frame */ - const float l_silence_snr, /* i : sum of the nonactive frames snr */ - const int16_t l_silence_snr_count, /* i : number of the nonactive frame */ - const int16_t fg_energy_count, /* i : number of the foreground energy frame */ - const int16_t bg_energy_count, /* i : number of the background energy frame */ - const int16_t bw_index /* i : band width index */ -); - -float construct_snr_thresh( - const float sp_center[], /* i : spectral center */ - const float snr_flux, /* i : snr flux */ - const float lt_snr, /* i : long time time domain snr */ - const float lf_snr, /* i : long time frequency domain snr */ - const int16_t continuous_speech_num, /* i : continuous speech number */ - const int16_t continuous_noise_num, /* i : continuous noise number */ - const int16_t fg_energy_est_start, /* i : whether if estimated energy */ - const int16_t bw_index /* i : band width index */ -); - -void minimum_statistics_flt( - const int16_t len, /* i : Vector length */ - const int16_t lenFFT, /* i : Length of the FFT part of the vectors */ - float *psize_flt, - float *msPeriodog, /* i : Periodograms */ - float *msNoiseFloor, - float *msNoiseEst, /* o : Noise estimates */ - float *msAlpha, - float *msPsd, - float *msPsdFirstMoment, - float *msPsdSecondMoment, - float *msMinBuf, - float *msBminWin, - float *msBminSubWin, - float *msCurrentMin, - float *msCurrentMinOut, - float *msCurrentMinSubWindow, - int16_t *msLocalMinFlag, - int16_t *msNewMinFlag, - float *msPeriodogBuf, - int16_t *msPeriodogBufPtr, - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t enc_dec, /* i : encoder/decoder indicator */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void generate_comfort_noise_enc( - Encoder_State *st /* i/o: encoder state structure */ -); - -void generate_comfort_noise_dec( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nchan_out /* i : number of output channels */ -); - -void generate_comfort_noise_dec_hf( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t cng_flag /* i : CNG Flag */ -); - -void generate_masking_noise( - float *timeDomainBuffer, /* i/o: time-domain signal */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t length, /* i : frame size */ - const int16_t core, /* i : core */ - const int16_t return_noise, /* i : noise is returned instead of added */ - const int16_t secondary, /* i : indicator for secondary channel */ - const int16_t element_mode, /* i : element mode */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -); - -void generate_masking_noise_update_seed( - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void generate_masking_noise_mdct( - float *mdctBuffer, /* i/o: time-domain signal */ - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void SynthesisSTFT_dirac_flt( - float *fftBuffer, /* i : FFT bins */ - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t samples_out, - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void generate_masking_noise_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - float *Cldfb_RealBuffer, /* o : CLDFD real buffer */ - float *Cldfb_ImagBuffer, /* o : CLDFD imaginary buffer */ - const int16_t slot_index, /* i : CLDFB slot index */ - const int16_t cna_flag, /* i : CNA flag for LB and HB */ - const int16_t fd_cng_flag /* i : FD-CNG flag for HB */ -); - -void generate_stereo_masking_noise( - float *syn, /* i/o: time-domain signal */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t fadeOut, /* i : only fade out of previous state */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -); - -void apply_scale_flt( - float *scale, /* i : scale factor */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t brate, /* i : Bit rate */ - const SCALE_SETUP *scaleTable, /* i : Scale table */ - const int16_t scaleTableSize /* i : Size of scale table */ -); - -void compress_range_flt( - float *in, - float *out, - const int16_t len ); - -void expand_range_flt( - float *in, - float *out, - const int16_t len ); - -void bandcombinepow_flt( - const float *bandpow, /* i : Power for each band */ - const int16_t nband, /* i : Number of bands */ - int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ - const int16_t npart, /* i : Number of partitions */ - const float *psize_inv_flt, /* i : Inverse partition sizes */ - float *partpow /* o : Power for each partition */ -); - -void scalebands_flt( - const float *partpow, /* i : Power for each partition */ - int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ - const int16_t npart, /* i : Number of partitions */ - int16_t *midband, /* i : Central band of each partition */ - const int16_t nFFTpart, /* i : Number of FFT partitions */ - const int16_t nband, /* i : Number of bands */ - float *bandpow, /* o : Power for each band */ - const int16_t flag_fft_en ); - -void AnalysisSTFT_flt( - const float *timeDomainInput, - float *fftBuffer, /* o : FFT bins */ - HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void SynthesisSTFT_flt( - float *fftBuffer, - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t tcx_transition, - HANDLE_FD_CNG_COM hFdCngCom, - const int16_t element_mode, /* i : element mode */ - const int16_t nchan_out /* i : number of output channels */ -); - -void lpc_from_spectrum_flt( - HANDLE_FD_CNG_COM hFdCngCom, - const int16_t start, - const int16_t stop, - const float preemph_fac ); - -ivas_error createFdCngDec( - HANDLE_FD_CNG_DEC *hFdCngDec ); - -void deleteFdCngDec( - HANDLE_FD_CNG_DEC *hFdCngDec ); - -void initFdCngDec( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - -void configureFdCngDec( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ - const int16_t bwidth, - const int32_t total_brate, - const int16_t L_frame, - const int16_t last_L_frame, - const int16_t element_mode ); - -void ApplyFdCng( - float *timeDomainInput, - float *powerSpectrum, - float **realBuffer, /* i/o: Real part of the buffer */ - float **imagBuffer, /* i/o: Imaginary part of the buffer */ - Decoder_State *st, - const int16_t concealWholeFrame, /* i : binary flag indicating frame loss */ - const int16_t is_music ); - -void generate_comfort_noise_dec( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nchan_out /* i : number of output channels */ -); - -/*! r: CNG energy */ -float cng_energy( - const int16_t element_mode, /* i : element mode */ - const int16_t bwidth, /* i : audio bandwidh */ - const int16_t CNG_mode, /* i : mode for DTX configuration */ - const float CNG_att, /* i : attenuation factor for CNG */ - const float *inputBuffer, /* i : input signal */ - const int16_t len /* i : vector length */ -); - -void FdCng_decodeSID( - Decoder_State *st /* i/o: decoder state structure */ -); - -void FdCng_exc_flt( - HANDLE_FD_CNG_COM hFdCngCom, - int16_t *CNG_mode, - const int16_t L_frame, - const float *lsp_old, - const int16_t first_CNG, - float *lsp_CNG, - float *Aq, /* o : LPC coeffs */ - float *lsp_new, /* o : lsp */ - float *lsf_new, /* o : lsf */ - float *exc, /* o : LP excitation */ - float *exc2, /* o : LP excitation */ - float *bwe_exc /* o : LP excitation for BWE */ -); - -void noisy_speech_detection( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ - const int16_t vad, /* i : VAD flag */ - const float syn[] /* i : input time-domain frame */ -); - -void deleteFdCngEnc( - HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure */ -); - - -void resetFdCngEnc( - Encoder_State *st /* i/o: encoder state structure */ -); - -void perform_noise_estimation_enc( - float *band_energies, /* i : energy in critical bands without minimum noise floor E_MIN */ - float *enerBuffer, /* i : energy buffer */ - HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ - const int32_t input_Fs, /* i : input sampling rate */ - CPE_ENC_HANDLE hCPE ); - -void AdjustFirstSID( - Encoder_State *st /* i/o: encoder state structure */ -); - -void FdCng_encodeSID( - Encoder_State *st /* i/o: encoder state structure */ -); - -void GetParameters( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ); - -void SetParameters( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - void *pParameter, - const int16_t **pStream, - int16_t *pnSize ); - -void WriteToBitstream( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - const int16_t **pStream, - int16_t *pnSize, - BSTR_ENC_HANDLE hBstr, - int16_t *pnBits ); - -void ReadFromBitstream( - ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, - Decoder_State *st, - int16_t **pStream, - int16_t *pnSize ); - -void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); -void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); -void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); -void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); - -int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); - -int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); -int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -void ResetTnsData_flt( - STnsData *pTnsData ); - -void ClearTnsFilterCoefficients_flt( - STnsFilter *pTnsFilter ); - - -int16_t DetectTnsFilt( - const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ - const float pSpectrum[], /* i : MDCT spectrum */ - TRAN_DET_HANDLE hTranDet, /* i : transient detection handle */ - const int16_t isTCX10, /* i : TCX10 or TCX20? */ - const float ltp_gain, /* i : LTP gain */ - STnsData *pTnsData, /* o : TNS data struct */ - float *predictionGain /* o : TNS prediction gain */ -); - -void EncodeTnsData( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ - int16_t *stream, /* o : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - int16_t *pnBits /* o : number of written bits */ -); - -int16_t DecodeTnsData_ivas( - STnsConfig const *pTnsConfig, - const int16_t *stream, - int16_t *pnSize, - STnsData *pTnsData ); - -void WriteTnsData( - const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ - const int16_t *stream, /* i : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - BSTR_ENC_HANDLE hBstr, /* o : bitstream */ - int16_t *pnBits /* o : number of written bits */ -); - -void ReadTnsData_ivas( - STnsConfig const *pTnsConfig, - Decoder_State *st, - int16_t *pnBits, - int16_t *stream, - int16_t *pnSize ); - -void cldfbAnalysis_ivas( - const float *timeIn, /* i : time buffer */ - float **realBuffer, /* o : real value buffer */ - float **imagBuffer, /* o : imag value buffer */ - const int16_t samplesToProcess, /* i : number of input samples */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ -); - -void cldfbAnalysis_ts_ivas( - const float *timeIn, /* i : time buffer */ - float realBuffer[CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ - float imagBuffer[CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ - const int16_t samplesToProcess, /* i : samples to process */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ -); - -void cldfbSynthesis_ivas( - float **realBuffer, /* i : real values */ - float **imagBuffer, /* i : imag values */ - float *timeOut, /* o : synthesized output */ - const int16_t samplesToProcess, /* i : number of samples */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ -); - -void configureCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ - const int32_t sampling_rate /* i : sampling rate */ -); - - -void analysisCldfbEncoder_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const float *timeIn, - const int16_t samplesToProcess, - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float *ppBuf_Ener ); - -void analysisCldfbEncoder_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word32 *timeIn, /*q11*/ - Word16 timeInq, /*q0*/ - Word16 samplesToProcess, /*q0*/ - Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word32 *ppBuf_Ener, - Word16 *enerBuffSum_exp, - CLDFB_SCALE_FACTOR *scale ); - -ivas_error openCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const int32_t sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - -void resampleCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ - const int32_t newSamplerate /* i : new samplerate to operate */ -); - -ivas_error cldfb_save_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void cldfb_restore_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void cldfb_reset_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - -void fft_cldfb( - float *data, /* i/o: input/output vector */ - const int16_t size /* i : size of fft operation */ -); - -void BITS_ALLOC_init_config_acelp_IVAS( - const int32_t bit_rate, - const int16_t narrowBand, - const int16_t nb_subfr, - ACELP_config *acelp_cfg /* o : configuration structure of ACELP */ -); - -int16_t BITS_ALLOC_config_acelp_IVAS( - const int16_t bits_frame, /* i : remaining bit budget for the frame */ - const int16_t coder_type, /* i : acelp coder type */ - ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t nb_subfr /* i : number of subframes */ -); - - -void FEC_clas_estim( - const float *syn, - const float *pitch, /* i : pitch values for each subframe */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t coder_type, /* i : coder type */ - const int16_t codec_mode, /* i : codec mode */ - float *mem_syn_clas_estim, /* i/o: memory of the synthesis signal for frame class estimation */ - int16_t *clas, /* i/o: frame classification */ - float *lp_speech, /* i/o: long term active speech energy average */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - int16_t *decision_hyst, /* i/o: hysteresis of the music/speech decision */ - int16_t *locattack, /* i/o: detection of attack (mainly to localized speech burst) */ - int16_t *UV_cnt, /* i/o: number of consecutives frames classified as UV */ - float *LT_UV_cnt, /* i/o: long term consecutives frames classified as UV */ - float *Last_ener, /* i/o: last_energy frame */ - int16_t *amr_io_class, /* i/o: classification for AMR-WB IO mode */ - float *lt_diff_etot, /* i/o: long-term total energy variation */ - float *class_para, /* o : classification para. fmerit1 */ - const float LTP_Gain, /* i : */ - const int16_t narrowBand, /* i : */ - const SIGNAL_CLASSIFIER_MODE mode, /* i : */ - const int16_t bfi, /* i : */ - const float preemph_fac, /* i : */ - const int16_t tcxonly, /* i : */ - const int32_t last_core_brate, /* i : last core bitrate */ - const int16_t FEC_mode /* i : ACELP FEC mode */ -); - - -void SetTCXModeInfo( - Encoder_State *st, /* i/o: encoder state structure */ - TRAN_DET_HANDLE hTranDet, /* i/o: transient detection handle */ - int16_t *tcxModeOverlap /* o : window overlap of current frame */ -); - -void TCX_MDCT_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDST_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDCT_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDST_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDXT_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const uint16_t kernel_type ); - -void post_decoder_flt( - Decoder_State *st, - float synth_buf[], - const float pit_gain[], - const int16_t pitch[], - float signal_out[], - float bpf_noise_buf[] ); -void cldfb_synth_set_bandsToZero_flt( - Decoder_State *st, /* i/o: decoder state structure */ - float **rAnalysis, - float **iAnalysis, - const int16_t nTimeSlots ); - -void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ -); - -void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ -); - -void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ -); - -void open_decoder_LPD( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t last_element_mode, /* i : last element mode */ - const int16_t is_init /* i : indicate call during initialization */ -); - -void acelp_plc_mdct_transition( - Decoder_State *st /* i/o: Decoder state */ -); - -void tcxltp_dec_init( - TCX_LTP_DEC_HANDLE hTcxLtpDec, - const int16_t ini_frame, - const int16_t last_codec_mode, - const int16_t element_mode, - const int16_t pit_max, - const int32_t sr_core ); - -void reset_tcx_overl_buf( - TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ -); - -void update_decoder_LPD_cng_flt( - Decoder_State *st, /* i/o: decoder state structure */ - float *timeDomainBuffer, - float *A, - float *bpf_noise_buf ); - -void reconfig_decoder_LPD_ivas( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t bits_frame, /* i : bit budget */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t L_frame_old /* i : frame length */ -); - -void mode_switch_decoder_LPD( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t last_total_brate, /* i : last frame total bitrate */ - const int16_t frame_size_index, /* i : index determining the frame size */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t last_element_mode /* i : last element mode */ -); - -void dec_acelp_tcx_frame( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *concealWholeFrame, /* i/o: concealment flag */ - float *output, /* o : synthesis */ - float *bpf_noise_buf, /* i/o: BPF noise buffer */ - float *pcmbufFB, /* o : synthesis @output_FS */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float pitch_buf[], /* o : floating pitch for each subframe */ - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -); - -void decoder_LPD( - Decoder_State *st, /* i/o: decoder memory state pointer */ - float signal_out[], /* o : signal with LPD delay (7 subfrs) */ - float signal_outFB[], /* o : synthesis @output_FS */ - int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ - float *bpf_noise_buf, /* i/o: BPF noise buffer */ - int16_t bfi, /* i : BFI flag */ - int16_t *bitsRead, /* o : number of read bits */ - int16_t param[], /* o : buffer of parameters */ - float *pitch_buf, /* i/o: floating pitch values for each subfr*/ - float *voice_factors, /* o : voicing factors */ - float *ptr_bwe_exc /* o : excitation for SWB TBE */ -); - -int16_t tcxGetNoiseFillingTilt_flt( - const float A[], - const int16_t L_frame, - const int16_t mode, - float *noiseTiltFactor ); - -void tcxFormantEnhancement_flt( - float xn_buf[], - const float *gainlpc, - float spectrum[], - const int16_t L_frame ); - -void tcxInvertWindowGrouping_flt( - TCX_CONFIG_HANDLE hTcxCfg, - float xn_buf[], - float spectrum[], - const int16_t L_frame, - const int8_t fUseTns, - const int16_t last_core, - const int16_t index, - const int16_t frame_cnt, - const int16_t bfi ); - -void tcx5SpectrumInterleaving( - const int16_t tcx5Size, - float *spectrum ); - -void tcx5SpectrumDeinterleaving( - const int16_t tcx5Size, - float *spectrum ); - -void tcx5TnsGrouping( - const int16_t L_frame, - const int16_t L_spec, - float *spectrum ); - -void tcx5TnsUngrouping( - const int16_t L_frame, - const int16_t L_spec, - float *spectrum, - const int16_t enc_dec ); - -void lerp_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize ); - -void encoderSideLossSimulation( - Encoder_State *st, - PLC_ENC_EVS_HANDLE hPlc_Ext, - float *isf_q, - const float stab_fac, - const int16_t calcOnlyISF, - const int16_t L_frame ); - -void enc_prm_side_Info( - PLC_ENC_EVS_HANDLE hPlc_Ext, - Encoder_State *st ); - -void GplcTcxEncSetup( - const int16_t tcxltp_pitch_int, - PLC_ENC_EVS_HANDLE hPlc_Ext ); - -int16_t encSideSpecPowDiffuseDetector( - float *isf_ref, - float *isf_con, - const int32_t sr_core, - float *prev_isf4_mean, - const int16_t sw, - const int16_t coder_type ); - -void updateSpecPowDiffuseIdx( - const float gain_pitch_buf[], /* i : gain pitch values */ - const float gain_code_buf[], /* i : gain pitch values */ - int16_t glr_idx[2], /* o : */ - float mean_gc[2] /* o : */ -); - -void getLookAheadResSig_flt( - float *speechLookAhead, - const float *A, - float *res, - const int16_t L_frame, - const int16_t L_subfr, - const int16_t m, - const int16_t numSubFrame ); - -void updatelsfForConcealment_flt( - PLC_ENC_EVS_HANDLE decState, - float *lsf ); - -void getConcealedLP_flt( - PLC_ENC_EVS_HANDLE memDecState, - float *AqCon, - const float xsfBase[], - const int32_t sr_core, - const int16_t last_good, - const int16_t L_frame ); - -void RecLpcSpecPowDiffuseLc_flt( - float *ispq, - float *isp_old, - float *isfq, - Decoder_State *st, - const int16_t reset_q ); - -void modify_lsf_flt( - float *lsf, - const int16_t n, - const int32_t sr_core, - const int16_t reset_q ); - -void init_PLC_enc( - PLC_ENC_EVS_HANDLE hPlcExt, - const int32_t sr_core ); - -void gPLC_encInfo( - PLC_ENC_EVS_HANDLE hPlcExt, - const int32_t total_brate, - const int16_t bwidth, - const int16_t last_clas, - const int16_t coder_type ); - -void resetTecDec( - TEC_DEC_HANDLE hTecDec ); - -void calcGainTemp_TBE( - float **pCldfbRealSrc, - float **pCldfbImagSrc, - float *loBuffer, - const int16_t startPos, /*!< Start position of the current envelope. */ - const int16_t stopPos, /*!< Stop position of the current envelope. */ - const int16_t lowSubband, /* lowSubband */ - float *pGainTemp, - const int16_t code ); - -void procTecTfa_TBE( - float *hb_synth, - float *gain, - const int16_t flat_flag, - const int16_t last_core, - const int16_t L_subfr, - const int16_t code ); - -void resetTecEnc( - TEC_ENC_HANDLE hTecEnc, - const int16_t flag ); - -void calcHiEnvLoBuff( - const int16_t noCols, - const int16_t *pFreqBandTable, /* i : freqbandTable */ - const int16_t nSfb, /* i : Number of scalefactors */ - float **pYBuf, - float *loBuf, - float *hiTempEnv ); - -void calcLoEnvCheckCorrHiLo( - const int16_t noCols, - const int16_t *pFreqBandTable, /* i : freqbandTable */ - float *loBuf, - float *loTempEnv, - float *loTempEnv_ns, - float *hiTempEnv, - int16_t *corr_flag /* o : 0 for original, 1 for TEC */ -); - - -void tecEnc_TBE( - int16_t *corrFlag, - const float *voicing, - const int16_t coder_type ); - -void set_TEC_TFA_code( - const int16_t corrFlag, - int16_t *tec_flag, - int16_t *tfa_flag ); - -float Damping_fact_flt( - const int16_t coder_type, /* i : ACELP core coder type */ - const int16_t nbLostCmpt, /* i : compt for number of consecutive lost frame */ - int16_t last_good, /* i : class of last good received frame */ - float stab_fac, /* i : LSF stability factor */ - float *lp_gainp, /* i/o: low passed pitch gain used for concealment */ - const int16_t core /* i : current core: ACELP = 0, TCX20 = 1, TCX10 = 2 */ -); - -float getLevelSynDeemph( - const float h1Init[], /* i : input value or vector to be processed */ - const float A[], /* i : LPC coefficients */ - const int16_t lenLpcExc, /* i : length of the LPC excitation buffer */ - const float preemph_fac, /* i : preemphasis factor */ - const int16_t numLoops /* i : number of loops */ -); - -void genPlcFiltBWAdap( - const int32_t sr_core, /* i : core sampling rate */ - float *lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */ - const int16_t type, /* i : type of filter, either 0 : lowpass or 1 : highpass */ - const float alpha /* i : fade out factor [0 1) used decrease filter tilt */ -); - -void highPassFiltering( - const int16_t last_good, /* i : last classification type */ - const int16_t L_buffer, /* i : buffer length */ - float exc2[], /* i/o: unvoiced excitation before the high pass filtering */ - const float hp_filt[], /* i : high pass filter coefficients */ - const int16_t l_fir_fer /* i : high pass filter length */ -); - -int16_t GetPLCModeDecision( - Decoder_State *st /* i/o: decoder memory state pointer */ -); - -void addBassPostFilter( - const float *harm_timeIn, - const int16_t samplesToProcess, - float **rAnalysis, - float **iAnalysis, - HANDLE_CLDFB_FILTER_BANK cldfb ); - -ivas_error TonalMDCTConceal_Init_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const uint16_t samplesPerBlock, - const uint16_t nSamplesCore, - const uint16_t nScaleFactors, - TCX_CONFIG_HANDLE hTcxCfg ); - -void TonalMDCTConceal_SaveFreqSignal_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const float *mdctSpectrum, - const uint16_t numSamples, - const uint16_t nNewSamplesCore, - const float *scaleFactors, - const int16_t infoIGFStartLine ); - -void TonalMDCTConceal_UpdateState_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const int16_t numSamples, - const float pitchLag, - const int16_t badBlock, - const int16_t tonalConcealmentActive ); - -void TonalMDCTConceal_SaveTimeSignal_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - float *timeSignal, - const int16_t numSamples ); - -void TonalMDCTConceal_Detect_ivas( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - const float pitchLag, /*IN */ - int16_t *umIndices, /*OUT*/ - const PsychoacousticParameters *psychParamsCurrent /*IN*/ -); - -void TonalMDCTConceal_Apply_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - float *mdctSpectrum, /*OUT*/ - const PsychoacousticParameters *psychParamsCurrent /*IN*/ -); - -void TonalMDCTConceal_InsertNoise_ivas( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - float *mdctSpectrum, /*OUT*/ - const int16_t tonalConcealmentActive, - int16_t *pSeed, /*IN/OUT*/ - const float tiltCompFactor, - const float crossfadeGain, - const float concealment_noise[L_FRAME48k], - const float cngLevelBackgroundTrace_bfi, - const int16_t crossOverFreq ); - -void DetectTonalComponents_flt( - uint16_t indexOfTonalPeak[], - uint16_t lowerIndex[], - uint16_t upperIndex[], - uint16_t *pNumIndexes, - const float lastPitchLag, - const float currentPitchLag, - const float lastMDCTSpectrum[], - const float scaleFactors[], - const float secondLastPowerSpectrum[], - const uint16_t nSamples, - const uint16_t nSamplesCore, - float floorPowerSpectrum, - const PsychoacousticParameters *psychParamsCurrent ); - -void RefineTonalComponents_flt( - uint16_t indexOfTonalPeak[], - uint16_t lowerIndex[], - uint16_t upperIndex[], - float phaseDiff[], - float phases[], - uint16_t *pNumIndexes, - const float lastPitchLag, - const float currentPitchLag, - const float lastMDCTSpectrum[], - const float scaleFactors[], - const float secondLastPowerSpectrum[], - const uint16_t nSamples, - const uint16_t nSamplesCore, - float floorPowerSpectrum, - const PsychoacousticParameters *psychParamsCurrent ); - -ivas_error PsychoacousticParameters_Init( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t nBins, /* i : Number of bins (spectral lines) */ - const int8_t nBands, /* i : Number of spectrum subbands */ - const int16_t isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ - const int16_t isWarped, /* i : Flag indicating if the scale is linear or warped */ - PsychoacousticParameters *pPsychParams ); - -void concealment_init( - const int16_t L_frameTCX, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_decode( - const int16_t core, - float *invkoef, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_update( - const int16_t bfi, - const int16_t core, - const int16_t harmonic, - float *invkoef, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_update2( - const float *outx_new, - T_PLCInfo_HANDLE hPlcInfo, - const int16_t L_frameTCX ); - -void concealment_signal_tuning( - Decoder_State *st, - const int16_t bfi, - float *outx_new, - const int16_t past_core_mode ); - -void waveform_adj2( - T_PLCInfo_HANDLE hPlcInfo, - float *overlapbuf, - float *outx_new, - const int16_t delay, - const int16_t bfi_cnt, - const int16_t bfi ); - -float SFM_Cal( - const float fcoef[], - const int16_t n ); - -void set_state_ivas( - int16_t *state, - const int16_t num, - const int16_t N ); - -int16_t RFFTN( - float *afftData, - const float *trigPtr, - const int16_t len, - const int16_t isign ); - -void DoFFT( - float *re2, - float *im2, - const int16_t length ); - -/*! r: flag indicating a valid bitrate */ -int16_t is_EVS_bitrate( - const int32_t ivas_total_brate, /* i : EVS total bitrate */ - int16_t *Opt_AMR_WB /* i : AMR-WB IO flag */ -); - -int16_t getTcxonly_ivas( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t is_ism_format /* i : flag indicating ISM format */ -); - -int16_t getTnsAllowed( - const int32_t total_brate, /* i : total bitrate */ - const int16_t igf, /* i : flag indicating IGF activity*/ - const int16_t element_mode /* i : IVAS element mode */ -); - -int16_t getCtxHm( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t rf_flag /* i : flag to signal the RF mode */ -); - -int16_t getResq( - const int32_t total_brate /* i : total bitrate */ -); - -int16_t getMdctWindowLength( - const int16_t fscale ); - -int16_t sr2fscale( - const int32_t sr_core /* i : internal sampling rate */ -); - -int32_t getCoreSamplerateMode2_flt( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ -); - -float getTcxBandwidth_flt( - const int16_t bwidth /* i : audio bandwidth */ -); - - -int16_t getCnaPresent( - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -int16_t getTcxLtp( - const int32_t sr_core /* i : internal sampling rate */ -); - -int16_t initPitchLagParameters( - const int32_t sr_core, /* i : internal sampling rate */ - int16_t *pit_min, - int16_t *pit_fr1, - int16_t *pit_fr1b, - int16_t *pit_fr2, - int16_t *pit_max ); - -void attenuateNbSpectrum( - const int16_t L_frame, - float *spectrum ); - -void SetModeIndex( - Encoder_State *st, /* i : Encoder state */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t last_element_mode, /* i : last IVAS element mode */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -int16_t getNumTcxCodedLines( - const int16_t bwidth /* i : audio bandwidth */ -); - -int16_t getTcxLpcShapedAri( - const int32_t total_brate, /* i : total bitrate */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void IGFEncApplyMono( - Encoder_State *st, /* i : Encoder state */ - const int16_t igfGridIdx, /* i : IGF grid index */ - float *pMDCTSpectrum, /* i/o: MDCT spectrum */ - float *pPowerSpectrum, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int16_t isTNSActive, /* i : flag indicating if the TNS is active */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void IGFEncApplyStereo( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ - const int16_t igfGridIdx, /* i : IGF grid index */ - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subframe */ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - - -void IGFEncResetTCX10BitCounter_ivas_fx( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ -); - -ivas_error IGF_Reconfig( - IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */ - const int16_t igf, /* i : IGF on/off */ - const int16_t reset, /* i : reset flag */ - const int32_t brate, /* i : bitrate for configuration */ - const int16_t bwidth, /* i : signal bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -void IGFEncSetMode( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - const int32_t total_brate, /* i : encoder total bitrate */ - const int16_t bwidth, /* i : encoder audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -/*! r: number of bits written per frame */ -int16_t IGFEncWriteBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t *pBitOffset, /* i : ptr to bitOffset counter */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ -); - -/*! r: total number of bits written */ -int16_t IGFEncWriteConcatenatedBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -); - -void IGFDecApplyMono_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i : instance handle of IGF Decoder */ - float *spectrum, /* i/o: MDCT spectrum */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void IGFDecCopyLPCFlatSpectrum_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const float *pSpectrumFlat, /* i : LPC flattend spectrum from TCX dec */ - const int16_t igfGridIdx /* i : IGF grid index */ -); - -void IGFDecReadData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ - Decoder_State *st, /* i : decoder state */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ -); - -/*! r: return igfAllZero flag indicating if no envelope is transmitted */ -int16_t IGFDecReadLevel_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ - Decoder_State *st, /* i : decoder state */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ -); - -void IGFDecRestoreTCX10SubFrameData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ - const int16_t subFrameIdx /* i : index of subframe */ -); - -void init_igf_dec_flt( - IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ -); - -void IGFDecSetMode_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ - const int32_t total_brate, /* i : bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t defaultStartLine, /* i : default start subband index */ - const int16_t defaultStopLine, /* i : default stop subband index */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -void IGFDecStoreTCX10SubFrameData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const int16_t subFrameIdx /* i : index of subframe */ -); - -void IGFDecUpdateInfo_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const int16_t subFrameIdx, /* i : subframe index */ - const int16_t igfGridIdx /* i : IGF grid index */ -); - -/*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFConfiguration_flt( - const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - H_IGF_INFO hIGFInfo, /* o : IGF info handle */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -/*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFGetCFTables_flt( - const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : element mode */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const uint16_t **cf_se00, /* i : CF table for t == 0 and f == 0 */ - const uint16_t **cf_se01, /* i : CF table for t == 0 and f == 1 */ - int16_t *cf_off_se01, /* o : offset for CF table above */ - const uint16_t **cf_se02, /* i : CF tables for t == 0 and f >= 2 */ - const int16_t **cf_off_se02, /* o : offsets for CF tables above */ - const uint16_t **cf_se10, /* i : CF table for t == 1 and f == 0 */ - int16_t *cf_off_se10, /* o : offset for CF table above */ - const uint16_t **cf_se11, /* i : CF tables for t == 1 and f >= 1 */ - const int16_t **cf_off_se11 /* o : offsets for CF tables above */ -); - -/*! r: multiplication factor */ -int16_t IGF_ApplyTransFac_flt( - const int16_t val, /* i : input value for multiplication, Q15 */ - const float transFac /* i : multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */ -); - -/*! r: return bitrate index */ -int16_t IGF_MapBitRateToIndex_flt( - const int32_t brate, /* i : bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - - -void IGFSCFDecoderOpen_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data */ - H_IGF_INFO hIgfInfo, /* i : IGF info handle */ - const int32_t total_brate, - const int16_t bwidth, - const int16_t element_mode, - const int16_t rf_mode ); - -void IGFSCFDecoderReset_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i : handle to public data or NULL in case there was no instance created */ -); - -void IGFSCFDecoderDecode_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data or NULL in case there was no instance created */ - Decoder_State *st, /* i/o: pointer to decoder state */ - int16_t *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t indepFlag /* i : if 1 on input the decoder will be forced to reset, - if 0 on input the decoder will be forced to encode without a reset */ -); - -/*! r: offset value */ -int16_t tbe_celp_exc_offset_flt( - const int16_t T0, /* i : Integer pitch */ - const int16_t T0_frac /* i : Fractional part of the pitch */ -); - -void blend_subfr2_flt( - float *sigIn1, /* i : input signal for fade-out */ - float *sigIn2, /* i : input signal for fade-in */ - float *sigOut /* o : output signal */ -); - -void init_tcx_window_cfg( - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX Config handle */ - const int32_t sr_core, /* i : SR core */ - const int32_t input_Fs, /* i : input/output SR */ - const int16_t L_frame, /* i : L_frame at sr_core */ - const int16_t L_frameTCX, /* i : L_frame at i/o SR */ - const int16_t encoderLookahead_enc, /* i : encoder LA at sr_core */ - const int16_t encoderLookahead_FB, /* i : encoder LA at i/o SR */ - const int16_t mdctWindowLength, /* i : window length at sr_core */ - const int16_t mdctWindowLengthFB, /* i : window length at i/o SR */ - const int16_t element_mode /* i : mode of CPE/SCE */ -); - -void init_tcx_cfg( - TCX_CONFIG_HANDLE hTcxCfg, - const int32_t total_brate, - const int32_t sr_core, - const int32_t input_Fs, - const int16_t L_frame, - const int16_t bwidth, - const int16_t L_frameTCX, - const int16_t fscale, - const int16_t encoderLookahead_enc, - const int16_t encoderLookahead_FB, - const float preemph_fac, - const int16_t tcxonly, - const int16_t rf_mode, - const int16_t igf, - const int16_t infoIGFStopFreq, - const int16_t element_mode, - const int16_t ini_frame, - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -#endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 51fbb12d5..9b596ca42 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -49,14 +49,63 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "stat_dec.h" +#include "stat_com.h" #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" +#include "ivas_stat_com.h" #include "ivas_error.h" #include "ivas_error_utils.h" #include "complex_basop.h" #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 + +/*----------------------------------------------------------------------------------* + * Prototypes of global macros + *----------------------------------------------------------------------------------*/ + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef TRUNC +#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) +#endif + +#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) +#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) + +#ifndef ABSVAL +#define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) +#endif + +#ifndef SQR +#define SQR( a ) ( ( a ) * ( a ) ) +#endif + +#ifndef SWAP +#define SWAP( a, b ) \ + { \ + tempr = ( a ); \ + ( a ) = ( b ); \ + ( b ) = tempr; \ + } +#endif + +#ifndef swap +#define swap( x, y, type ) \ + { \ + type u__p; \ + u__p = x; \ + x = y; \ + y = u__p; \ + } +#endif + /*================================================================================*/ /* conversion functions: */ /*================================================================================*/ @@ -10920,7 +10969,6 @@ void IGFEncConcatenateBitstream( BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ ); -#endif void hq_generic_hf_encoding_fx( const Word32 *coefs_fx, /* i : MDCT coefficients of weighted original */ @@ -11205,3 +11253,746 @@ void WriteToBitstream_ivas_fx( Word16 *pnSize, BSTR_ENC_HANDLE hBstr, Word16 *pnBits ); + + +/*===========================================================================================*/ +/*----------------------------------------------------------------------------------* + * MODE1 prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: inverse square root of input value */ +float inv_sqrt( + const float x /* i : input value */ +); + +/*! r: output random value */ +int16_t own_random( + int16_t *seed /* i/o: random seed */ +); + +/*! r: sign of x (+1/-1) */ +float sign( + const float x /* i : input value of x */ +); + +/*! r: logarithm2 of x */ +float log2_f( + const float x /* i : input value of x */ +); + +int16_t norm_ul_float( + uint32_t UL_var1 ); + +/*! r: sum of all vector elements */ +int16_t sum_s( + const int16_t *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: sum of all vector elements */ +int32_t sum_l( + const int32_t *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: sum of all squared vector elements */ +float sum2_f( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +void set_c( + int8_t y[], /* i/o: Vector to set */ + const int8_t a, /* i : Value to set the vector to */ + const int32_t N /* i : Length of the vector */ +); + +void set_s( + int16_t y[], /* i/o: Vector to set */ + const int16_t a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +); + +void set_l( + int32_t y[], /* i/o: Vector to set */ + const int32_t a, /* i : Value to set the vector to */ + const int16_t N /* i : Length of the vector */ +); + +void set_f( + float y[], /* i/o: Vector to set */ + const float a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +); + +void set_zero_fx( + Word32 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); +void set_zero2_fx( + Word32 *vec, /* o : input vector */ + const Word32 lvec /* i : length of the vector */ +); +void set16_zero_fx( + Word16 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); + +void set_zero( + float *vec, /* o : input vector */ + const int16_t lvec /* i : length of the vector */ +); + +void mvr2r( + const float x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvs2s( + const int16_t x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +uint32_t mvr2s( + const float x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvs2r( + const int16_t x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvl2l( + const int32_t x[], /* i : input vector */ + int32_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + + +/*! r: index of the maximum value in the input vector */ +int16_t maximum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *max_val /* o : maximum value in the input vector */ +); +/*! r: index of the maximum value in the input vector */ +int16_t maximumAbs( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *max_val /* o : maximum value in the input vector */ +); + +Word16 maximumAbs_l( + const Word32 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word32 *max_val /* o : maximum value in the input vector */ +); + +/*! r: index of the minimum value in the input vector */ +int16_t minimum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *min_val /* o : minimum value in the input vector */ +); + +/*! r: index of the minimum value in the input vector */ +int16_t minimum_s( + const int16_t *vec, /* i : Input vector */ + const int16_t lvec, /* i : Vector length */ + int16_t *min_val /* o : minimum value in the input vector */ +); + +/*! r: return index with max energy value in vector */ +int16_t emaximum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *ener_max /* o : maximum energy value */ +); + +/*! r: vector mean */ +float mean( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: dot product of x[] and y[] */ +float dotp( + const float x[], /* i : vector x[] */ + const float y[], /* i : vector y[] */ + const int16_t n /* i : vector length */ +); + +void v_add( + const float x1[], /* i : Input vector 1 */ + const float x2[], /* i : Input vector 2 */ + float y[], /* o : Output vector that contains vector 1 + vector 2 */ + const int16_t N /* i : Vector length */ +); + +void v_sub( + const float x1[], /* i : Input vector 1 */ + const float x2[], /* i : Input vector 2 */ + float y[], /* o : Output vector that contains vector 1 - vector 2 */ + const int16_t N /* i : Vector length */ +); + +/*! r: dequanzited gain */ +float usdequant( + const int16_t idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ +); + +void sort( + uint16_t *x, /* i/o: Vector to be sorted */ + uint16_t len /* i/o: vector length */ +); + +void sort_l( + Word32 *x, /* i/o: Vector to be sorted */ + Word16 len /* i/o: vector length */ +); + + +ivas_error push_indice( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + int16_t id, /* i : ID of the indice */ + uint16_t value, /* i : value of the quantized indice */ + int16_t nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_indice( + BSTR_ENC_HANDLE hBstr, + UWord16 value, /* i : value of the quantized indice */ + Word16 nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_bits( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ + const Word16 nb_bits /* i : number of bits to pack */ +); + +/*! r: maximum number of indices */ +Word16 get_ivas_max_num_indices_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +/*! r: maximum number of indices */ +int16_t get_BWE_max_num_indices( + const int32_t extl_brate /* i : extensiona layer bitrate */ +); + +/*! r: maximum number of indices */ +Word16 get_ivas_max_num_indices_metadata_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); +ivas_error ind_list_realloc( + INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ + const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ + Encoder_Struct *st_ivas /* i : IVAS encoder structure */ +); + +ivas_error check_ind_list_limits( + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +); + +void move_indices( + INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ + INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ + const int16_t nb_indices /* i : number of moved indices */ +); + +/*! r: index of the indice in the list, -1 if not found */ +int16_t find_indice( + BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ + const int16_t id, /* i : ID of the indice */ + uint16_t *value, /* o : value of the quantized indice */ + int16_t *nb_bits /* o : number of bits used to quantize the indice */ +); + +/*! r: number of deleted indices */ +uint16_t delete_indice( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t id /* i : ID of the indice */ +); + +/*! r: value of the indice */ +uint16_t get_next_indice( + Decoder_State *st, /* i/o: decoder state structure */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +/*! r: value of the indice */ +uint16_t get_next_indice_1( + Decoder_State *st /* i/o: decoder state structure */ +); + +void get_next_indice_tmp( + Decoder_State *st, /* o : decoder state structure */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +/*! r: value of the indice */ +uint16_t get_indice( + Decoder_State *st, /* i/o: decoder state structure */ + int16_t pos, /* i : absolute position in the bitstream */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +void reset_indices_enc( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t max_num_indices /* i : max number of indices */ +); + +void reset_indices_dec( + Decoder_State *st /* i/o: decoder state structure */ +); + +Word16 rate2EVSmode_float( + const Word32 brate, /* i : bitrate */ + int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ +); + + +/*! r: 1 = OK, 0 = something wrong */ +ivas_error read_indices( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 num_bits, /* i : number of bits in bitstream */ + int16_t *prev_ft_speech, + int16_t *CNG, + int16_t bfi /* i : bad frame indicator */ +); + + +void ivas_set_bitstream_pointers( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +Decoder_State **reset_elements( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void mdct_switching_dec_ivas_fx( + Decoder_State *st /* i/o: decoder state structure */ +); + +int16_t print_disclaimer( + FILE *fPtr ); + +void fft_rel( + float x[], /* i/o: input/output vector */ + const int16_t n, /* i : vector length */ + const int16_t m /* i : log2 of vector length */ +); + +void preemph_ivas_fx( + Word32 *signal, /* i/o: signal Qx*/ + const Word16 mu, /* i : preemphasis factor Q15*/ + const Word16 L, /* i : vector size Q0*/ + Word32 *mem /* i/o: memory (x[-1]) Qx*/ +); + +void create_offset( + UWord32 *offset_scale1, + UWord32 *offset_scale2, + const int16_t mode, + const int16_t prediction_flag ); + +void BASOP_cfft_ivas( + Word32 *re, /* i/o: real part */ + Word32 *im, /* i/o: imag part */ + Word16 s, /* i : stride real and imag part */ + Word16 *scale /* i : scalefactor */ +); + +Word32 ar_div_ivas( + Word32 num, + Word32 denum ); + +Word32 Mult_32_16( + Word32 a, + Word16 b ); + +Word32 Mult_32_32( + Word32 a, + Word32 b ); + + +void bit_allocation_second_fx2( + Word32 *Rk, + Word32 *Rk_sort, + Word16 BANDS, + const Word16 *band_width, + Word16 *k_sort, + Word16 *k_num, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame ); + +void bit_allocation_second_fx2( + Word32 *Rk, + Word32 *Rk_sort, + Word16 BANDS, + const Word16 *band_width, + Word16 *k_sort, + Word16 *k_num, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame ); + +#ifdef DEBUGGING +void read_next_force( + int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ + FILE *f_force, /* i : force switching profile (0 if N/A) */ + int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ +); +#endif + +ivas_error init_encoder_ivas_fx( + Encoder_State *st, /* i/o: state structure */ + Encoder_Struct *st_ivas, /* i/o: encoder state structure */ + const Word16 idchan, /* i : channel ID */ + const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ + const Word16 interval_SID, /* i : interval for SID update */ + const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const Word32 element_brate /* i : element bitrate */ +); + +ivas_error acelp_core_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 inp[], /* i : input signal of the current frame Q_new*/ + Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word32 epsP[M + 1], /* i : LP prediction errors Qx*/ + Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid[M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ + Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn_12k8_16*/ + Word16 *q_old_syn_12k8_16, + Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word16 *unbits, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ + Word16 Q_new ); + +void flip_and_downmix_generic_fx_32( + Word32 input[], /* i : input spectrum Qx*/ + Word32 output[], /* o : output spectrum Qx*/ + const Word16 length, /* i : length of spectra */ + Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ + Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ +); + +void GenTransition_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 element_mode, /* i : element mode : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 rf_flag, /* i : RF flag : Q0 */ + const Word32 total_brate, /* i : total bitrate : Q0 */ + const Word16 prev_Qx ); + +void GenTransition_WB_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ +); + +Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ + const Word16 pos1, /* i: position of the pulse 1 */ + const Word16 pos2, /* i: position of the pulse 2 */ + const Word16 N /* i: number of bits FOR position */ +); + +void bands_and_bit_alloc_ivas_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 noise_lev, /* i : dwn scaling factor */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ + Word16 *max_ener_band, /* o : Sorted order */ + Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ + Word16 *nb_subbands, /* o : Number of subband allowed */ + const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ + Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ + Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ + const Word16 L_frame, /* i : frame length */ + const Word16 element_mode, /* i : element mode */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +void ivas_find_wsp_fx( + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_subfr, /* i : length of subframe Q0*/ + const Word16 nb_subfr, /* i : number of subframes Q0*/ + const Word16 *A_fx, + /* i : A(z) filter coefficients */ // Q12 + Word16 *Aw_fx, + /* o : weighted A(z) filter coefficients */ // Q12 + const Word16 *speech_fx, + /* i : pointer to the denoised speech frame */ // Q_new + const Word16 tilt_fact, + /* i : tilt factor */ // Q15 + Word16 *wsp_fx, + /* o : poitnter to the weighted speech frame */ // Q_new + Word16 *mem_wsp_fx, + /* i/o: W(Z) denominator memory */ // Q_new + const Word16 gamma, + /* i : weighting factor */ // Q15 + const Word16 L_look /* i : look-ahead Q0*/ +); + +Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( + Word16 *x, /* Q0 */ + const Word16 nt, /* Q0 */ + const Word16 target, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem ); + +Word16 RCcontextMapping_encode2_estimate_bandWise_fx( + Word16 *x, /* Q0 */ + const Word16 start_line, /* Q0 */ + const Word16 end_line, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem /* Q0 */ +); + + +/*! r: Q15 */ +Word16 expfp_evs_fx( + const Word16 x, /* i : mantissa Q15-e */ + const Word16 x_e /* i : exponent Q0 */ +); + + +void tcx_arith_render_envelope_ivas_fx( + const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/ + const Word16 L_frame, /* i : number of spectral lines Q0*/ + const Word16 L_spec, /* i : length of the coded spectrum Q0*/ + const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/ + const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/ + const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/ + Word32 env[] /* o : shaped signal envelope Q16*/ +); + +void tcx_arith_decode_envelope_ivas_fx( + Decoder_State *st, /* i/o: coder state */ + Word32 q_spectrum[], /* o : quantised MDCT coefficients */ + Word16 *q_spectrum_e, /* o : MDCT exponent */ + const Word16 L_frame, /* i : frame or MDCT length */ + Word16 L_spec, /* i : length w/o BW limitation */ + const Word16 A_ind[], /* i : quantised LPC coefficients */ + const Word16 target_bits, /* i : number of available bits */ + Word16 prm[], /* i : bitstream parameters */ + const Word16 use_hm, /* i : use HM in current frame? */ + const Word16 prm_hm[], /* i : HM parameter area */ + Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ + Word16 *arith_bits, /* o : bits used for ari. coding */ + Word16 *signaling_bits, /* o : bits used for signaling */ + const Word16 low_complexity /* i : low-complexity flag */ +); + + +void UnmapIndex_fx( + const Word16 PeriodicityIndex, /* Q0 */ + const Word16 Bandwidth, /* Q0 */ + const Word16 LtpPitchLag, /* Q0 */ + const Word8 SmallerLags, /* Q0 */ + Word16 *FractionalResolution, /* Q0 */ + Word32 *Lag /* Q0 */ +); + +#define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) +#define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) + + +Word32 tcx_hm_render_fx( + const Word32 lag, /* i: pitch lag Q0 */ + const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[] /* o: harmonic model Q13 */ +); + + +void tcx_hm_modify_envelope_fx( + const Word16 gain, /* i: HM gain Q11 */ + const Word32 lag, /* i: pitch lag Q0 */ + const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + const Word16 p[], /* i: harmonic model Q13 */ + Word32 env[], /* i/o: envelope Q16 */ + const Word16 L_frame /* i: number of spectral lines Q0 */ +); + +void tcx_hm_decode( + const Word16 L_frame, /* i : number of spectral lines */ + Word32 env[], /* i/o: envelope shape (Q16) */ + const Word16 targetBits, /* i : target bit budget */ + const Word16 coder_type, /* i : GC/VC coder type */ + const Word16 prm_hm[], /* i : HM parameters */ + const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ + Word16 *hm_bits /* o : bit consumption */ +); + +void writeTCXMode_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + Word16 *nbits_start /* o : nbits start Q0*/ +); + +void writeTCXWindowing_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 overlap_mode /* i : overlap mode Q0*/ +); + +void writeLPCparam( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const int16_t param_lpc[], /* i : LPC parameters to write */ + const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ + const int16_t no_param_lpc, /* i : number of LPC parameters */ + int16_t *nbits_lpc /* o : LPC bits written */ +); + +void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); +void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); +void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); +void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); + +int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); + +int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); +int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +void ResetTnsData_flt( + STnsData *pTnsData ); + +void ClearTnsFilterCoefficients_flt( + STnsFilter *pTnsFilter ); + +void EncodeTnsData( + STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ + STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ + Word16 *stream, /* o : internal data stream */ + Word16 *pnSize, /* o : number of written parameters */ + Word16 *pnBits /* o : number of written bits */ +); + +Word16 DecodeTnsData_ivas( + STnsConfig const *pTnsConfig, + const Word16 *stream, + Word16 *pnSize, + STnsData *pTnsData ); + +void WriteTnsData( + const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ + const Word16 *stream, /* i : internal data stream */ + Word16 *pnSize, /* o : number of written parameters */ + BSTR_ENC_HANDLE hBstr, /* o : bitstream */ + Word16 *pnBits /* o : number of written bits */ +); + +void ReadTnsData_ivas( + STnsConfig const *pTnsConfig, + Decoder_State *st, + Word16 *pnBits, + Word16 *stream, + Word16 *pnSize ); + +void analysisCldfbEncoder_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word32 *timeIn, /*q11*/ + Word16 timeInq, /*q0*/ + Word16 samplesToProcess, /*q0*/ + Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 *ppBuf_Ener, + Word16 *enerBuffSum_exp, + CLDFB_SCALE_FACTOR *scale ); + +ivas_error openCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const int32_t sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + +ivas_error openCldfb_ivas_enc( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const Word32 sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + +void resampleCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ + const Word32 newSamplerate /* i : new samplerate to operate */ +); + +ivas_error cldfb_save_memory_ivas( + HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ +); + +void deleteCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ +); + +/*! r: flag indicating a valid bitrate */ +Word16 is_EVS_bitrate( + const Word32 ivas_total_brate, /* i : EVS total bitrate */ + Word16 *Opt_AMR_WB /* i : AMR-WB IO flag */ +); + +void IGFEncResetTCX10BitCounter_ivas_fx( + const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ +); + +ivas_error IGF_Reconfig( + IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */ + const Word16 igf, /* i : IGF on/off */ + const Word16 reset, /* i : reset flag */ + const Word32 brate, /* i : bitrate for configuration */ + const Word16 bwidth, /* i : signal bandwidth */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); + +void ordr_esti( + const Word16 k, /* i : sub-vector index */ + Word16 *Mpos, /* i/o: dominant sub-vector position from ACV */ + Word16 svOrder[], /* i/o: AVQ sub-vector order */ + const Word16 Nsv /* i : total sub-vectors in a sub-frames */ +); + +/*===========================================================================================*/ +#endif diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index ed914f2a1..479bc04d9 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -4,7 +4,6 @@ #include #include "options.h" /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ diff --git a/lib_com/residu_fx.c b/lib_com/residu_fx.c index 665dbfae6..32d18d1fe 100644 --- a/lib_com/residu_fx.c +++ b/lib_com/residu_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" -#include "prot.h" /*--------------------------------------------------------------------* * residu_ivas_fx() diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index bad47f065..172dadf82 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -38,10 +38,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "wmc_auto.h" -#include "prot_fx.h" /* clang-format off */ diff --git a/lib_com/rom_com_fx.c b/lib_com/rom_com_fx.c index 611658884..49f50e162 100644 --- a/lib_com/rom_com_fx.c +++ b/lib_com/rom_com_fx.c @@ -38,7 +38,7 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "wmc_auto.h" #include "rom_com_fx.h" diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 2aa781a43..1f112c911 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -38,7 +38,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6cdf1185a..7e9471c45 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "ivas_prot_fx.h" diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index cececd8f5..44ce806f7 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/tcx_utils_fx.c b/lib_com/tcx_utils_fx.c index 4e40e4ab2..c5ff95e04 100644 --- a/lib_com/tcx_utils_fx.c +++ b/lib_com/tcx_utils_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" #include "rom_basop_util.h" #include "basop_util.h" -#include "prot.h" #define inv_int InvIntTable diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 515746bd5..101bc1df8 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -12,7 +12,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "basop_util.h" -#include "prot.h" /*---------------------------------------------------------------------------- * Local constants diff --git a/lib_com/tools.c b/lib_com/tools.c index 4d9f5e956..e4ccd9955 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -37,7 +37,6 @@ #include #include "options.h" #include -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" @@ -136,23 +135,6 @@ int16_t sum_s( return tmp; } -/*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - int32_t tmpL; - - tmpL = 0; - for ( i = 0; i < lvec; i++ ) - { - tmpL += vec[i]; - } - - return tmpL; -} /*! r: sum of all vector elements */ Word32 sum_l_fx( const Word32 *vec, /* i : input vector */ @@ -171,23 +153,6 @@ Word32 sum_l_fx( return tmpL; } -/*! r: sum of all vector elements */ -float sum_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - float tmp; - - tmp = 0.0f; - for ( i = 0; i < lvec; i++ ) - { - tmp += vec[i]; - } - - return tmp; -} /*---------------------------------------------------------------------- * sum2_f() @@ -228,22 +193,6 @@ Word32 sum2_f_16_gb_fx( return tmp; } -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - float tmp; - - tmp = 0.0f; - for ( i = 0; i < lvec; i++ ) - { - tmp += vec[i] * vec[i]; - } - - return tmp; -} Word32 sum2_16_exp_fx( const Word16 *vec, /* i : input vector Q(15 - exp) */ @@ -532,101 +481,6 @@ void mvs2s( return; } -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -) -{ - int16_t i; - float temp; - uint32_t noClipping = 0; - - if ( n <= 0 ) - { - /* cannot transfer vectors with size 0 */ - return 0; - } - - if ( (void *) y <= (const void *) x ) - { - for ( i = 0; i < n; i++ ) - { - temp = x[i]; - temp = (float) floor( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - noClipping++; - } - else if ( temp < MIN16B_FLT ) - { - temp = MIN16B_FLT; - noClipping++; - } - - y[i] = (int16_t) temp; - } - } - else - { - for ( i = n - 1; i >= 0; i-- ) - { - temp = x[i]; - temp = (float) floor( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - noClipping++; - } - else if ( temp < MIN16B_FLT ) - { - temp = MIN16B_FLT; - noClipping++; - } - - y[i] = (int16_t) temp; - } - } - - return noClipping; -} - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -) -{ - int16_t i; - - if ( n <= 0 ) - { - /* cannot transfer vectors with size 0 */ - return; - } - - if ( (void *) y < (const void *) x ) - { - for ( i = 0; i < n; i++ ) - { - y[i] = (float) x[i]; - } - } - else - { - for ( i = n - 1; i >= 0; i-- ) - { - y[i] = (float) x[i]; - } - } - - return; -} - - void mvl2l( const int32_t x[], /* i : input vector */ int32_t y[], /* o : output vector */ @@ -659,44 +513,6 @@ void mvl2l( return; } - -/*---------------------------------------------------------------------* - * maximum() - * - * Find index and value of the maximum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = vec[0]; - - for ( j = 1; j < lvec; j++ ) - { - if ( vec[j] > tmp ) - { - ind = j; - tmp = vec[j]; - } - } - - if ( max_val != NULL ) - { - *max_val = tmp; - } - - return ind; -} - - /*! r: index of the maximum value in the input vector */ Word16 maximum_s( const Word16 *vec, /* i : input vector */ @@ -766,42 +582,6 @@ Word16 maximum_l( return ind; } -/*---------------------------------------------------------------------* - * maximumAbs() - * - * Find index and value of the maximum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = (float) fabs( vec[0] ); - - for ( j = 1; j < lvec; j++ ) - { - if ( (float) fabs( vec[j] ) > tmp ) - { - ind = j; - tmp = (float) fabs( vec[j] ); - } - } - - if ( max_val != NULL ) - { - *max_val = tmp; - } - - return ind; -} - /*! r: index of the maximum value in the input vector */ Word16 maximumAbs_l( const Word32 *vec, /* i : input vector */ @@ -835,42 +615,6 @@ Word16 maximumAbs_l( return ind; } -/*---------------------------------------------------------------------* - * minimum() - * - * Find index of a minimum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = vec[0]; - - for ( j = 1; j < lvec; j++ ) - { - if ( vec[j] < tmp ) - { - ind = j; - tmp = vec[j]; - } - } - - if ( min_val != NULL ) - { - *min_val = tmp; - } - - return ind; -} - /*-------------------------------------------------------------------* * minimum_s() * @@ -988,59 +732,6 @@ Word16 minimum_l( return ind; } -/*---------------------------------------------------------------------* - * emaximum() - * - * Find index of a maximum energy in a vector - *---------------------------------------------------------------------*/ - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -) -{ - int16_t j, ind; - float temp; - - *ener_max = 0.0f; - ind = 0; - - for ( j = 0; j < lvec; j++ ) - { - temp = vec[j] * vec[j]; - - if ( temp > *ener_max ) - { - ind = j; - *ener_max = temp; - } - } - - return ind; -} - - -/*---------------------------------------------------------------------* - * mean() - * - * Find the mean of the vector - *---------------------------------------------------------------------*/ - -/*! r: mean of vector */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - float tmp; - - tmp = sum_f( vec, lvec ) / (float) lvec; - - return tmp; -} - /*---------------------------------------------------------------------* * dotp() * @@ -1168,114 +859,6 @@ float inv_sqrt( return (float) ( 1.0 / sqrt( x ) ); } - -/*-------------------------------------------------------------------* - * conv() - * - * Convolution between vectors x[] and h[] written to y[] - * All vectors are of length L. Only the first L samples of the - * convolution are considered. - *-------------------------------------------------------------------*/ - -void conv( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response (or second input vector) */ - float y[], /* o : output vetor (result of convolution) */ - const int16_t L /* i : vector size */ -) -{ - float temp; - int16_t i, n; - for ( n = 0; n < L; n++ ) - { - temp = x[0] * h[n]; - for ( i = 1; i <= n; i++ ) - { - temp += x[i] * h[n - i]; - } - y[n] = temp; - } - - return; -} - -/*-------------------------------------------------------------------* - * fir() - * - * FIR filtering of vector x[] with filter having impulse response h[] - * written to y[] - * The input vector has length L and the FIR filter has an order of K, i.e. - * K+1 coefficients. The memory of the input signal is provided in the vector mem[] - * which has K values - * The maximum length of the input signal is L_FRAME32k and the maximum order - * of the FIR filter is L_FILT_MAX - *-------------------------------------------------------------------*/ - -void fir( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response of the FIR filter */ - float y[], /* o : output vector (result of filtering) */ - float mem[], /* i/o: memory of the input signal (L samples) */ - const int16_t L, /* i : input vector size */ - const int16_t K, /* i : order of the FIR filter (K+1 coefs.) */ - const int16_t upd /* i : 1 = update the memory, 0 = not */ -) -{ - float buf_in[L_FRAME48k + 60], buf_out[L_FRAME48k], s; - int16_t i, j; - - /* prepare the input buffer (copy and update memory) */ - mvr2r( mem, buf_in, K ); - mvr2r( x, buf_in + K, L ); - - if ( upd ) - { - mvr2r( buf_in + L, mem, K ); - } - - /* do the filtering */ - for ( i = 0; i < L; i++ ) - { - s = buf_in[K + i] * h[0]; - - for ( j = 1; j <= K; j++ ) - { - s += h[j] * buf_in[K + i - j]; - } - - buf_out[i] = s; - } - - /* copy to the output buffer */ - mvr2r( buf_out, y, L ); - - return; -} - -/*-------------------------------------------------------------------* - * v_add() - * - * Addition of two vectors sample by sample - *-------------------------------------------------------------------*/ - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] + x2[i]; - } - - return; -} - - /*-------------------------------------------------------------------* * v_add_w64() * @@ -1351,55 +934,9 @@ void v_sub_fixed( } /*-------------------------------------------------------------------* - * v_mult() + * v_multc_fixed() * - * Multiplication of two vectors - *-------------------------------------------------------------------*/ - -void v_mult( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 .* vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] * x2[i]; - } - - return; -} - -/*-------------------------------------------------------------------* - * v_multc() - * - * Multiplication of vector by constant - *-------------------------------------------------------------------*/ - -void v_multc( - const float x[], /* i : Input vector */ - const float c, /* i : Constant */ - float y[], /* o : Output vector that contains c*x */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = c * x[i]; - } - - return; -} - -/*-------------------------------------------------------------------* - * v_multc_fixed() - * - * Multiplication of vector by constant + * Multiplication of vector by constant *-------------------------------------------------------------------*/ void v_multc_fixed( @@ -1456,102 +993,6 @@ void v_multc_fixed_16_16( return; } -/*-------------------------------------------------------------------* - * squant() - * - * Scalar quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Index of the winning codeword and the winning codeword itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codeword */ -int16_t squant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float cb[], /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -) -{ - float dist, mindist, tmp; - int16_t c, idx; - - idx = 0; - mindist = 1e16f; - - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - tmp = x - cb[c]; - dist += tmp * tmp; - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - *xq = cb[idx]; - - return idx; -} - -/*! r: index of the winning codeword */ -int16_t squant_int( - uint8_t x, /* i : scalar value to quantize */ - uint8_t *xq, /* o : quantized value */ - const uint8_t *cb, /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -) -{ - int16_t i, idx; - float mindist, d; - - idx = 0; - mindist = 10000000.0f; - for ( i = 0; i < cbsize; i++ ) - { - d = (float) ( x - cb[i] ) * ( x - cb[i] ); - if ( d < mindist ) - { - mindist = d; - idx = i; - } - } - *xq = cb[idx]; - - return idx; -} - - -/*-------------------------------------------------------------------* - * usquant() - * - * Uniform scalar quantizer according to MMSE criterion - * (nearest neighbour in Euclidean space) - * - * Applies quantization based on scale and round operations. - * Index of the winning codeword and the winning codeword itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codeword */ -int16_t usquant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta, /* i : quantization step */ - const int16_t cbsize /* i : codebook size */ -) -{ - int16_t idx; - - idx = (int16_t) max( 0.f, min( cbsize - 1, ( ( x - qlow ) / delta + 0.5f ) ) ); - *xq = idx * delta + qlow; - - return idx; -} - - /*-------------------------------------------------------------------* * usdequant() * @@ -1573,219 +1014,6 @@ float usdequant( return ( g ); } - -/*-------------------------------------------------------------------* - * vquant() - * - * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Index of the winning codevector and the winning vector itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codevector */ -int16_t vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize /* i : codebook size */ -) -{ - float dist, mindist, tmp; - int16_t c, d, idx, j; - - idx = 0; - mindist = 1e16f; - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - x[d] -= x_mean[d]; - } - } - - j = 0; - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - for ( d = 0; d < dim; d++ ) - { - tmp = x[d] - cb[j++]; - dist += tmp * tmp; - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = 0; d < dim; d++ ) - { - xq[d] = cb[j++]; - } - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - xq[d] += x_mean[d]; - } - } - - return idx; -} - -/*-------------------------------------------------------------------* - * w_vquant() - * - * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Weights are put on the error for each vector element. - * Index of the winning codevector and the winning vector itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codevector */ -int16_t w_vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - const int16_t weights[], /* i : error weights */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize, /* i : codebook size */ - const int16_t rev_vect /* i : reverse codebook vectors */ -) -{ - float dist, mindist, tmp; - int16_t c, d, idx, j, k; - - idx = 0; - mindist = 1e16f; - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - x[d] -= x_mean[d]; - } - } - - j = 0; - if ( rev_vect ) - { - k = dim - 1; - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - - for ( d = k; d >= 0; d-- ) - { - tmp = x[d] - cb[j++]; - dist += weights[d] * ( tmp * tmp ); - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = k; d >= 0; d-- ) - { - xq[d] = cb[j++]; - } - } - else - { - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - - for ( d = 0; d < dim; d++ ) - { - tmp = x[d] - cb[j++]; - dist += weights[d] * ( tmp * tmp ); - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = 0; d < dim; d++ ) - { - xq[d] = cb[j++]; - } - } - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - xq[d] += x_mean[d]; - } - } - - return idx; -} - - -/*----------------------------------------------------------------------------------* - * v_sort() - * - * Sorting of vectors. This is very fast with almost ordered vectors. - *----------------------------------------------------------------------------------*/ - -void v_sort_float( - float *r, /* i/o: Vector to be sorted in place */ - const int16_t lo, /* i : Low limit of sorting range */ - const int16_t up /* I : High limit of sorting range */ -) -{ - int16_t i, j; - float tempr; - - for ( i = up - 1; i >= lo; i-- ) - { - tempr = r[i]; - for ( j = i + 1; j <= up && ( tempr > r[j] ); j++ ) - { - r[j - 1] = r[j]; - } - - r[j - 1] = tempr; - } - - return; -} - void sort( UWord16 *x, /* i/o: Vector to be sorted */ UWord16 len /* i/o: vector length */ @@ -1810,426 +1038,3 @@ void sort( return; } - -/*---------------------------------------------------------------------* - * var() - * - * Calculate the variance of a vector - *---------------------------------------------------------------------*/ - -/*! r: variance of vector */ -float var( - const float *x, /* i : input vector */ - const int16_t len /* i : length of inputvector */ -) -{ - float m; - float v; - int16_t i; - - m = mean( x, len ); - - v = 0.0f; - for ( i = 0; i < len; i++ ) - { - v += ( x[i] - m ) * ( x[i] - m ); - } - v /= len; - - return v; -} - - -/*---------------------------------------------------------------------* - * std_dev() - * - * Calculate the standard deviation of a vector - *---------------------------------------------------------------------*/ - -/*! r: standard deviation */ -float std_dev( - const float *x, /* i : input vector */ - const int16_t len /* i : length of the input vector */ -) -{ - int16_t i; - float std; - - std = 1e-16f; - for ( i = 0; i < len; i++ ) - { - std += x[i] * x[i]; - } - - std = (float) sqrt( std / len ); - - return std; -} - - -/*---------------------------------------------------------------------* - * dot_product_mat() - * - * Calculates dot product of type x'*A*x, where x is column vector of size m, - * and A is square matrix of size m*m - *---------------------------------------------------------------------*/ - -/*! r: the dot product x'*A*x */ -float dot_product_mat( - const float *x, /* i : vector x */ - const float *A, /* i : matrix A */ - const int16_t m /* i : vector & matrix size */ -) -{ - int16_t i, j; - float suma, tmp_sum; - const float *pt_x, *pt_A; - - pt_A = A; - suma = 0; - - for ( i = 0; i < m; i++ ) - { - tmp_sum = 0; - pt_x = x; - for ( j = 0; j < m; j++ ) - { - tmp_sum += *pt_x++ * *pt_A++; - } - - suma += x[i] * tmp_sum; - } - - return suma; -} - - -/*--------------------------------------------------------------------------------* - * polezero_filter() - * - * Y(Z)=X(Z)(b[0]+b[1]z^(-1)+..+b[L]z^(-L))/(a[0]+a[1]z^(-1)+..+a[M]z^(-M)) - * mem[n]=x[n]+cp[0]mem[n-1]+..+cp[M-1]mem[n-M], where cp[i]=-a[i+1]/a[0] - * y[n]=cz[0]mem[n]+cz[1]mem[n-1]+..+cz[L]mem[n-L], where cz[i]=b[i]/a[0] - * mem={mem[n-K] mem[n-K+1] . . . . mem[n-2] mem[n-1]}, where K=max(L,M) - * - * a[0] must be equal to 1.0f! - *---------------------------------------------------------------------------------*/ - -void polezero_filter( - const float *in, /* i : input vector */ - float *out, /* o : output vector */ - const int16_t N, /* i : input vector size */ - const float *b, /* i : numerator coefficients */ - const float *a, /* i : denominator coefficients */ - const int16_t order, /* i : filter order */ - float *mem /* i/o: filter memory */ -) -{ - int16_t i, j, k; - - - for ( i = 0; i < order; i++ ) - { - out[i] = in[i] * b[0]; - for ( j = 0; j < i; j++ ) - { - out[i] += in[i - 1 - j] * b[j + 1] - out[i - 1 - j] * a[j + 1]; - } - - for ( k = order - 1; j < order; j++, k-- ) - { - out[i] += mem[k] * b[j + 1] - mem[k + order] * a[j + 1]; - } - } - - for ( ; i < N; i++ ) - { - out[i] = in[i] * b[0]; - for ( j = 0; j < order; j++ ) - { - out[i] += in[i - 1 - j] * b[j + 1] - out[i - 1 - j] * a[j + 1]; - } - } - - for ( i = 0; i < order; i++ ) - { - mem[i] = in[N - order + i]; - mem[i + order] = out[N - order + i]; - } - - return; -} - -#define WMC_TOOL_SKIP -static float fleft_shift( float input, const int16_t shift ) -{ - return ( input * (float) pow( 2.0, (double) shift ) ); -} - -static float fright_shift( float input, const int16_t shift ) -{ - return ( input * (float) pow( 0.5, (double) shift ) ); -} -#undef WMC_TOOL_SKIP - - -/*--------------------------------------------------------------------------------* - * root_a() - * - * Implements a quadratic approximation to sqrt(a) - * Firstly, a is normalized to lie between 0.25 & 1.0 - * by shifting the input left or right by an even number of - * shifts. Even shifts represent powers of 4 which, after - * the sqrt, can easily be converted to powers of 2 and are - * easily dealt with. - * At the heart of the algorithm is a quadratic - * approximation of the curve sqrt(a) for 0.25 <= a <= 1.0. - * Sqrt(a) approx = 0.27 + 1.0127 * a - 0.2864 * a^2 - * - *---------------------------------------------------------------------------------*/ - -float root_a( - float a ) -{ - int16_t shift_a; - float mod_a; - float approx; - - if ( a <= 0.0f ) - { - return 0.0; - } - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "a" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_a = a; - - shift_a = 0; - while ( mod_a > 1.0 ) - { - mod_a /= 2.0; - shift_a--; - } - - while ( mod_a < 0.5 ) - { - mod_a *= 2.0; - shift_a++; - } -#undef WMC_TOOL_SKIP - - shift_a &= 0xfffe; - mod_a = fleft_shift( a, shift_a ); - - approx = 0.27f + 1.0127f * mod_a - 0.2864f * mod_a * mod_a; - - approx = fright_shift( approx, ( shift_a >> 1 ) ); - - return ( approx ); -} - -/*--------------------------------------------------------------------------------* - * root_a_over_b() - * - * Implements an approximation to sqrt(a/b) - * Firstly a & b are normalized to lie between 0.25 & 1.0 - * by shifting the inputs left or right by an even number - * of shifts. - * Even shifts represent powers of 4 which, after the sqrt, - * become powers of 2 and are easily dealt with. - * At the heart of the algorithm is an approximation of the - * curve sqrt(a/b) for 0.25 <= a <= 1.0 & 0.25 <= b <= 1.0. - * Given the value of b, the 2nd order coefficients p0, p1 - * & p2 can be determined so that... - * Sqrt(a/b) approx = p0 + p1 * a + p2 * a^2 - * where p0 approx = 0.7176 - 0.8815 * b + 0.4429 * b^2 - * p1 approx = 2.6908 - 3.3056 * b + 1.6608 * b^2 - * p2 approx = -0.7609 + 0.9346 * b - 0.4695 * b^2 - * - *---------------------------------------------------------------------------------*/ - -float root_a_over_b( - float a, - float b ) -{ - int16_t shift_a, shift_b, shift; - float mod_a, mod_b; - float p2 = -0.7609f; - float p1 = 2.6908f; - float p0 = 0.7176f; - float b_sqr; - float approx; - - if ( ( a <= 0.0f ) || ( b <= 0.0f ) ) - { - return 0.0; - } -#define WMC_TOOL_SKIP - if ( isinf( a ) ) -#undef WMC_TOOL_SKIP - { - return FLT_MAX; - } -#define WMC_TOOL_SKIP - if ( isinf( b ) ) -#undef WMC_TOOL_SKIP - { - return 0.f; - } - - a += 0x00000001; - b += 0x00000001; - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "a" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_a = a; - - shift_a = 0; - while ( mod_a > 1.0 ) - { - mod_a /= 2.0; - shift_a--; - } - - while ( mod_a < 0.5 ) - { - mod_a *= 2.0; - shift_a++; - } -#undef WMC_TOOL_SKIP - - shift_a &= 0xfffe; - mod_a = fleft_shift( a, shift_a ); - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "b" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_b = b; - - shift_b = 0; - while ( mod_b > 1.0 ) - { - mod_b /= 2.0; - shift_b--; - } - - while ( mod_b < 0.5 ) - { - mod_b *= 2.0; - shift_b++; - } -#undef WMC_TOOL_SKIP - - shift_b &= 0xfffe; - mod_b = fleft_shift( b, shift_b ); - - shift = ( shift_b - shift_a ) >> 1; - - b_sqr = mod_b * mod_b; - - p2 += 0.9346f * mod_b + -0.4695f * b_sqr; - p1 += -3.3056f * mod_b + 1.6608f * b_sqr; - p0 += -0.8815f * mod_b + 0.4429f * b_sqr; - - approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; - - approx = fleft_shift( approx, shift ); - - return ( approx ); -} - -/*--------------------------------------------------------------------------------* - * rint_new() - * - * Round to the nearest integer with mid-point exception - *---------------------------------------------------------------------------------*/ - -double rint_new( - double x ) -{ - int16_t a; - - /* middle value point test */ - if ( ceil( x + 0.5 ) == floor( x + 0.5 ) ) - { - a = (int16_t) ceil( x ); - - if ( a % 2 == 0 ) - { - return ceil( x ); - } - else - { - return floor( x ); - } - } - else - { - return floor( x + 0.5 ); - } -} - - -/*-------------------------------------------------------------------* - * anint() - * - * Round to the nearest integer. - *-------------------------------------------------------------------*/ - -double anint( - double x ) -{ - return ( x ) >= 0 ? (int32_t) ( ( x ) + 0.5 ) : (int32_t) ( (x) -0.5 ); -} - -/*-------------------------------------------------------------------* - * is_numeric_float() - * - * Returns 0 for all NaN and Inf values defined according to IEEE 754 - * floating point number's definition. Returns 1 for numeric values. - *-------------------------------------------------------------------*/ - -int16_t is_numeric_float( - float x ) -{ - union float_int - { - float float_val; - int32_t int_val; - } float_int; - - float_int.float_val = x; - - return ( ( float_int.int_val & 0x7f800000 ) != 0x7f800000 ); -} - -/*-------------------------------------------------------------------* - * delay_signal_float() - * - * Delay buffer by defined number of samples - *-------------------------------------------------------------------*/ - -void delay_signal_float( - float x[], /* i/o: signal to be delayed */ - const int16_t len, /* i : length of the input signal */ - float mem[], /* i/o: synchronization memory */ - const int16_t delay /* i : delay in samples */ -) -{ - float tmp_buffer[L_FRAME48k]; - - mvr2r( mem, tmp_buffer, delay ); - mvr2r( x + len - delay, mem, delay ); - mvr2r( x, x + delay, len - delay ); - mvr2r( tmp_buffer, x, delay ); - - return; -} diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index efa9d7e5a..1aa0bb84a 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -50,7 +50,6 @@ #include "basop32.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot.h" #include "ivas_prot_fx.h" #define INV_BANDS10 3277 /* 1/10 in Q15 */ diff --git a/lib_com/wtda.c b/lib_com/wtda.c index a7ea5314c..3fb408138 100644 --- a/lib_com/wtda.c +++ b/lib_com/wtda.c @@ -37,11 +37,10 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include #include "wmc_auto.h" -#include "prot_fx.h" void wtda_fx32( diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 9597a97ae..11379a62d 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -39,7 +39,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index f1772b9a7..fc8aba043 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ diff --git a/lib_dec/ari_hm_dec.c b/lib_dec/ari_hm_dec.c index da7722325..ef4fb62d5 100644 --- a/lib_dec/ari_hm_dec.c +++ b/lib_dec/ari_hm_dec.c @@ -40,10 +40,9 @@ #include "cnst.h" #include "stl.h" #include "basop_util.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" Word16 DecodeIndex_fx( diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index e5a1220e0..60a59c4da 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -10,7 +10,6 @@ #include "prot_fx.h" #include "basop_util.h" #include "basop_proto_func.h" -#include "prot.h" /* Returns: number of bits consumed */ static Word16 tcx_arith_decode_fx( diff --git a/lib_dec/avq_dec_fx.c b/lib_dec/avq_dec_fx.c index 3bf7e3eb6..a8ba2bfc3 100644 --- a/lib_dec/avq_dec_fx.c +++ b/lib_dec/avq_dec_fx.c @@ -7,7 +7,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ /*-------------------------------------------------------------------* diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index e3401739e..ab349773e 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -6,7 +6,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 8fefa3bb2..dd268fe08 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -7,7 +7,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "rom_com.h" diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index c7d2c5265..2fd3f1d2e 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -8,7 +8,6 @@ #include "basop_util.h" #include "prot_fx.h" #include "rom_com.h" -#include "prot.h" void mode_switch_decoder_LPD_fx( Decoder_State *st, /* i/o: decoder state structure */ diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index e71157a1e..20f7a0adf 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -9,7 +9,6 @@ #include "basop_util.h" #include "stl.h" #include "options.h" -#include "prot.h" #include "math.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 385339664..6c63377fd 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -6,7 +6,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" /*=========================================================================*/ diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index c61bf95ce..ee7a7eca6 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -7,7 +7,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "basop32.h" -#include "prot.h" /*---------------------------------------------------------------------* * Local constants diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 626f25ef4..86cf9784a 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------------- * hq_core_dec() diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 4f74c31ca..907a4a350 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -8,10 +8,9 @@ #include #include "options.h" #include "stl.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "cnst.h" #include "stat_dec.h" #include "basop_util.h" diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4f1db90ff..3865cd61c 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -8,7 +8,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "stl.h" /* required for wmc_tool */ #include "basop_util.h" -#include "prot.h" #include "ivas_prot_fx.h" /*----------------------------------------------------------------------* diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index f5418abc6..e73d89158 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -34,7 +34,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index a6e03eee3..3fe40c1f3 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "cnst.h" @@ -43,7 +43,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 261a3c74e..5bb4736e9 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -36,12 +36,11 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 89ca9a5ba..697f9d715 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -35,7 +35,6 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "prot.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index c22c617c0..9bf53f1de 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -36,10 +36,9 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include diff --git a/lib_dec/ivas_decision_matrix_dec_fx.c b/lib_dec/ivas_decision_matrix_dec_fx.c index a8c151edb..f7fd5e8e2 100644 --- a/lib_dec/ivas_decision_matrix_dec_fx.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -35,11 +35,10 @@ #include "stat_dec.h" #include "rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------* * ivas_decision_matrix_dec() diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 9849647ea..7dd7371fd 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" @@ -43,7 +43,6 @@ #include "ivas_rom_dec.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index afbde5a60..e03913f8a 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -40,7 +40,7 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" @@ -48,7 +48,6 @@ #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_entropy_decoder_fx.c b/lib_dec/ivas_entropy_decoder_fx.c index 0c489fb04..e637a6a93 100644 --- a/lib_dec/ivas_entropy_decoder_fx.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -32,13 +32,12 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 037ef4eb9..8db782c4e 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -40,9 +40,8 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 14e83fe83..664e3eeac 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -32,13 +32,12 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------------* diff --git a/lib_dec/ivas_ism_dtx_dec_fx.c b/lib_dec/ivas_ism_dtx_dec_fx.c index 0365005be..cbf088597 100644 --- a/lib_dec/ivas_ism_dtx_dec_fx.c +++ b/lib_dec/ivas_ism_dtx_dec_fx.c @@ -35,10 +35,9 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * ivas_ism_dtx_dec_fx() diff --git a/lib_dec/ivas_ism_metadata_dec_fx.c b/lib_dec/ivas_ism_metadata_dec_fx.c index 833ed5e16..a6f5e47b6 100644 --- a/lib_dec/ivas_ism_metadata_dec_fx.c +++ b/lib_dec/ivas_ism_metadata_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_stat_enc.h" #include diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 424e6fb86..9040a8a71 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -36,13 +36,12 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 738e5a598..a19ba70ec 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 3b66d3107..f632d86c8 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -35,7 +35,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" @@ -46,7 +46,6 @@ #ifdef DEBUGGING #include "debug.h" #endif -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index 616b15c6e..e68c0142d 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index f5e7816ad..a8b54d3fb 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ls_custom_dec_fx.c b/lib_dec/ivas_ls_custom_dec_fx.c index eabee357b..45f59d82f 100644 --- a/lib_dec/ivas_ls_custom_dec_fx.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -32,10 +32,9 @@ #include #include "options.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index 4ca5c05b0..806785c15 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 4c1d5d190..897fd4433 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -36,7 +36,7 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" @@ -45,7 +45,6 @@ #include "math.h" #include "wmc_auto.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define INV_EPSILON_MANT 214748365 diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index be53d79c8..e03b385b7 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_prot.h" diff --git a/lib_dec/ivas_mcmasa_dec_fx.c b/lib_dec/ivas_mcmasa_dec_fx.c index 687efb3ce..c2228b610 100644 --- a/lib_dec/ivas_mcmasa_dec_fx.c +++ b/lib_dec/ivas_mcmasa_dec_fx.c @@ -35,7 +35,7 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_core_dec_fx.c b/lib_dec/ivas_mct_core_dec_fx.c index 824370bb8..be457da47 100644 --- a/lib_dec/ivas_mct_core_dec_fx.c +++ b/lib_dec/ivas_mct_core_dec_fx.c @@ -33,7 +33,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" #include "cnst.h" @@ -42,7 +42,6 @@ #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index c95a5285a..081eca88d 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index 331bdc253..69f601724 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -34,11 +34,10 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include #include "stat_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*----------------------------------------------------------* diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 190cc6b14..7f079277a 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -33,7 +33,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -44,7 +44,6 @@ #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mono_dmx_renderer_fx.c b/lib_dec/ivas_mono_dmx_renderer_fx.c index 231aee8aa..bb5dead22 100644 --- a/lib_dec/ivas_mono_dmx_renderer_fx.c +++ b/lib_dec/ivas_mono_dmx_renderer_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 3a6480386..391a27522 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index 0fb4163be..bf7fba094 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -35,12 +35,11 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index a5285b5cb..07ea14ea2 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -34,12 +34,11 @@ #include #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 02f37672d..4811911fd 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -34,13 +34,12 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 4a0c62e8d..08ac17799 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "math.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 853aa365f..397f26bbc 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index c225f126a..4bebcda5c 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -39,9 +39,8 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot.h" - #include "prot_fx.h" + #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_qspherical_dec_fx.c b/lib_dec/ivas_qspherical_dec_fx.c index 43ac60305..d34b5402a 100644 --- a/lib_dec/ivas_qspherical_dec_fx.c +++ b/lib_dec/ivas_qspherical_dec_fx.c @@ -37,7 +37,7 @@ #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_range_uni_dec_fx.c b/lib_dec/ivas_range_uni_dec_fx.c index 6d6631f73..e629111ce 100644 --- a/lib_dec/ivas_range_uni_dec_fx.c +++ b/lib_dec/ivas_range_uni_dec_fx.c @@ -38,10 +38,9 @@ #include "rom_com.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /* diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index 417079541..efd766f76 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" @@ -44,7 +44,6 @@ #include #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * ivas_sba_set_cna_cng_flag() * diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index 434fdf5fa..a42c67389 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" @@ -40,7 +40,6 @@ #include #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #ifdef DEBUGGING #include "debug.h" #endif diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index ce4992046..89581565c 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 37489e58f..170256181 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index cddbf8cdf..812027468 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -35,7 +35,7 @@ #include #include "options.h" #include "ivas_stat_dec.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" @@ -45,7 +45,6 @@ #include "ivas_stat_com.h" #include "stat_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index 3ad16b981..2b6b145f9 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -33,13 +33,12 @@ #include #include "options.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" #include "ivas_stat_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c index c67a52b6c..8446af47d 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index b3bddae59..15885a661 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -34,13 +34,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*------------------------------------------------------------------- diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index b0100063a..166ac72e5 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "rom_dec.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index 0db9ab09f..0781d49a6 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -43,7 +43,6 @@ #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 7c1c892aa..c806f358a 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "rom_dec.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index 9e6878faf..d3415a8eb 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" diff --git a/lib_dec/ivas_stereo_eclvq_dec_fx.c b/lib_dec/ivas_stereo_eclvq_dec_fx.c index ed26543d3..693df8c77 100644 --- a/lib_dec/ivas_stereo_eclvq_dec_fx.c +++ b/lib_dec/ivas_stereo_eclvq_dec_fx.c @@ -37,7 +37,7 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index 08ac60ffc..b49ab5399 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -36,12 +36,11 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "basop32.h" #include "ivas_stat_dec.h" diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index b634d4557..22a8c4a90 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index bf343da7f..04781a9cb 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -34,13 +34,12 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "stat_com.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 20fa578f8..69083a078 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -36,10 +36,9 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c8a59cd6a..2dd2a30c3 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" @@ -42,7 +42,6 @@ #include "wmc_auto.h" #include #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_td_dec_fx.c b/lib_dec/ivas_stereo_td_dec_fx.c index e31c9f6bc..8ab7da035 100644 --- a/lib_dec/ivas_stereo_td_dec_fx.c +++ b/lib_dec/ivas_stereo_td_dec_fx.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index a22502188..bb73fe7f0 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -32,13 +32,12 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index 37ffc5128..c908e4dc3 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -34,14 +34,13 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "stat_dec.h" #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" #include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index a4380bd4e..63819b056 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -37,7 +37,6 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer.c index cdabe4700..f9d6d1ca1 100644 --- a/lib_dec/jbm_jb4_circularbuffer.c +++ b/lib_dec/jbm_jb4_circularbuffer.c @@ -38,7 +38,7 @@ #include #include "options.h" #include "string.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local includes */ #include "jbm_jb4_circularbuffer.h" diff --git a/lib_dec/jbm_jb4_circularbuffer.h b/lib_dec/jbm_jb4_circularbuffer.h index de614eeea..9e3102feb 100644 --- a/lib_dec/jbm_jb4_circularbuffer.h +++ b/lib_dec/jbm_jb4_circularbuffer.h @@ -37,7 +37,7 @@ #ifndef JBM_JB4_CIRCULARBUFFER_H #define JBM_JB4_CIRCULARBUFFER_H JBM_JB4_CIRCULARBUFFER_H -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" /** handle for circular buffer (FIFO) with fixed capacity */ diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer.c index 55113ee13..5497a4371 100644 --- a/lib_dec/jbm_jb4_inputbuffer.c +++ b/lib_dec/jbm_jb4_inputbuffer.c @@ -39,7 +39,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include "jbm_jb4_inputbuffer.h" #include "wmc_auto.h" diff --git a/lib_dec/jbm_jb4_jmf.c b/lib_dec/jbm_jb4_jmf.c index 940df5ecb..5ab8242c7 100644 --- a/lib_dec/jbm_jb4_jmf.c +++ b/lib_dec/jbm_jb4_jmf.c @@ -42,7 +42,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local includes */ diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index 4878b7d64..002b4bc10 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -48,7 +48,6 @@ #include "jbm_jb4_inputbuffer.h" #include "jbm_jb4_jmf.h" #include "jbm_jb4sb.h" -#include "prot.h" #include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index 10b91a60c..ac6a28b86 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -44,7 +44,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local headers */ #include "jbm_pcmdsp_apa.h" @@ -54,7 +54,6 @@ #include "rom_dec.h" -#include "prot_fx.h" #define INV_100_Q15 328 #define INV_400_Q15 82 #define INV_80_Q15 410 diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 2cc4c6387..66109b555 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -37,9 +37,8 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" @@ -3398,7 +3397,7 @@ static ivas_error evs_dec_main_fx( move32(); hCoreCoder[0]->output_frame_fx = extract_l( Mult_32_16( hCoreCoder[0]->output_Fs, 0x0290 /*Q0*/ ) ); // Q0 move16(); - mdct_switching_dec( hCoreCoder[0] ); + mdct_switching_dec_ivas_fx( hCoreCoder[0] ); FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index bc8ef03cb..cc9b681fb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #include "rom_dec.h" #include "stl.h" diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 3cf5f51f3..36cadf6ff 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -14,7 +14,6 @@ #include "cnst.h" #include "prot_fx.h" #include "stat_com.h" -#include "prot.h" #include "ivas_prot_fx.h" #define CROSSFADE_THRESHOLD ( 32762 ) // close to 1.0f in Q15 such that (x == 1.0f) is true diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 203f39707..1e8bef488 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "basop_util.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "rom_com.h" diff --git a/lib_enc/FEC_enc_fx.c b/lib_enc/FEC_enc_fx.c index 9106e23e7..87243e8d2 100644 --- a/lib_enc/FEC_enc_fx.c +++ b/lib_enc/FEC_enc_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/SNR_calc_fx.c b/lib_enc/SNR_calc_fx.c index f44530c84..09acfd5dc 100644 --- a/lib_enc/SNR_calc_fx.c +++ b/lib_enc/SNR_calc_fx.c @@ -10,7 +10,6 @@ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 94d7f0471..0f58bcdad 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "rom_com.h" diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 8268d48b1..90768aca1 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -11,7 +11,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ -#include "prot.h" /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ diff --git a/lib_enc/ari_hm_enc_fx.c b/lib_enc/ari_hm_enc_fx.c index a94f45528..76d48ccf4 100644 --- a/lib_enc/ari_hm_enc_fx.c +++ b/lib_enc/ari_hm_enc_fx.c @@ -10,9 +10,7 @@ #include "basop_util.h" #include "rom_com.h" #include "rom_enc.h" -#include "prot.h" -//#include "prot_fx.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 202d60e51..93a0146f3 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -5,9 +5,7 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -#include /* Compilation switches */ -#include "prot.h" /* Function prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 1721476b4..e1b5ca562 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2,12 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_enc.h" /* Encoder static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_enc.h" /* Encoder static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" diff --git a/lib_enc/cod2t32_fx.c b/lib_enc/cod2t32_fx.c index c9bbe5f30..a948a4656 100644 --- a/lib_enc/cod2t32_fx.c +++ b/lib_enc/cod2t32_fx.c @@ -5,7 +5,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index 16651b8f2..a901690e3 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/cod4t64_fx.c b/lib_enc/cod4t64_fx.c index 44cde6f27..99b794b42 100644 --- a/lib_enc/cod4t64_fx.c +++ b/lib_enc/cod4t64_fx.c @@ -5,10 +5,9 @@ #include "options.h" /* VMR-WB compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_enc.h" /* Encoder static table prototypes */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index de9763df0..c54e8ccf4 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,11 +16,9 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include -#include "prot.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#include "prot.h" #endif #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index c2b1c22e1..a2995245d 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -13,7 +13,6 @@ #include "ivas_cnst.h" #include #include "rom_com.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index 82bb5fca9..f3b4aea6b 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -4,14 +4,11 @@ #include #include #include "options.h" -#include "prot.h" -//#include "prot_fx.h" -//#include "basop_mpy.h" +#include "prot_fx.h" #include "cnst.h" /* Common constants */ #include "ivas_cnst.h" #include "rom_com_fx.h" #include "rom_com.h" /* Common constants */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index a6b9e0aa4..6e4d2a043 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -10,7 +10,6 @@ #include #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 1053f8b00..06c49a8d3 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*======================================================================*/ diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index a01550978..64a11be5b 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" #include "prot_fx_enc.h" /*---------------------------------------------------------------------* diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 18948a93f..3ed50017c 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index da2ea5863..ecd4e2f01 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -11,8 +11,7 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index bf04daff5..5b9f67503 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -7,7 +7,6 @@ // #include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 2a621f1d5..cd23c1a6f 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -5,9 +5,8 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index e49463a5c..75e82409e 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index 6970597c8..c86b7e061 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -5,10 +5,9 @@ #include #include #include "options.h" /* Compilation switches */ -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Common constants */ -#include "prot_fx.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ #include "prot_fx_enc.h" #ifdef DEBUGGING diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 9cb2cd8e0..307d42078 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -11,7 +11,6 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "rom_enc.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/find_wsp_fx.c b/lib_enc/find_wsp_fx.c index d08922a2a..155e49904 100644 --- a/lib_enc/find_wsp_fx.c +++ b/lib_enc/find_wsp_fx.c @@ -6,8 +6,7 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 6af068bae..0321cd763 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -7,7 +7,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index a7d60642b..f943b104d 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -7,7 +7,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "rom_enc.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 8ed7e9d6c..375d4c2cf 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -6,8 +6,6 @@ #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" -//#include "prot_fx.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 53ad3dbb2..944cb2649 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -8,7 +8,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-----------------------------------------------------------------* diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index 11583ea11..f22218d13 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -2,12 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/hq_env_enc_fx.c b/lib_enc/hq_env_enc_fx.c index b0875968e..5d47710ed 100644 --- a/lib_enc/hq_env_enc_fx.c +++ b/lib_enc/hq_env_enc_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ /*--------------------------------------------------------------------------------------* * encode_envelope_indices_fx() diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index 4d4742cc1..1cd516b43 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -7,7 +7,6 @@ //#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/hq_lr_enc_fx.c b/lib_enc/hq_lr_enc_fx.c index 424689804..9aca0f646 100644 --- a/lib_enc/hq_lr_enc_fx.c +++ b/lib_enc/hq_lr_enc_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ -#include "prot.h" /*--------------------------------------------------------------------------* * Local function prototypes diff --git a/lib_enc/hvq_enc_fx.c b/lib_enc/hvq_enc_fx.c index 54bc4fb58..b06a1734d 100644 --- a/lib_enc/hvq_enc_fx.c +++ b/lib_enc/hvq_enc_fx.c @@ -8,7 +8,6 @@ //#include "prot_fx.h" #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #define HVQ_ENC_NOISE_DELTA ( (Word16) 3277 ) /* 0.1 in Q15 */ diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 6ac6e6811..f6adb0f31 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -38,13 +38,12 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #define INV_Log2_10_Q15 9864 /*1/log2(10) in Q15*/ @@ -2535,41 +2534,6 @@ void IGFEncResetTCX10BitCounter_ivas_fx( } -/*-------------------------------------------------------------------* - * IGFEncWriteConcatenatedBitstream() - * - * - *-------------------------------------------------------------------*/ - -/*! r: total number of bits written */ -Word16 IGFEncWriteConcatenatedBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -) -{ - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - Word16 i; - Word16 bitsLeft; - UWord8 *pBitstream; - - hPrivateData = &hIGFEnc->igfData; - pBitstream = hPrivateData->igfBitstream; - - for ( i = 0; i < ( hPrivateData->igfBitstreamBits >> 3 ); i++ ) - { - push_next_indice( hBstr, pBitstream[i], 8 ); - } - - bitsLeft = hPrivateData->igfBitstreamBits & 0x7; - if ( bitsLeft > 0 ) - { - push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); - } - - return hIGFEnc->infoTotalBitsWritten; -} - - /*-------------------------------------------------------------------* * IGFEncApplyMono() * diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index ca1759c89..cc4840876 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -8,8 +8,7 @@ #include "options.h" #include "cnst.h" #include "stl.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ #include "stat_enc.h" #include "basop_util.h" diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index 192d7e597..2921b5886 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -36,12 +36,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "stat_enc.h" #include "stat_com.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 5de4e8e92..615ca1b33 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "ivas_cnst.h" #include "ivas_error.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 7bb13239f..46bec5f4d 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 649c5bae5..37d25c508 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -36,10 +36,9 @@ #include #include "options.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "basop_util.h" diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 303adecfd..5f318e959 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -34,12 +34,11 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "wmc_auto.h" #include -#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index f963b55a4..f41eb7f9c 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" @@ -50,7 +49,6 @@ #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*---------------------------------------------------------------* * Local constants diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 1234a6876..a9da7f342 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -37,9 +37,8 @@ #include "ivas_prot.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "basop_util.h" diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index 1b4d5da4a..32e3e7107 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 3fd9c2d7a..811e53d12 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -36,7 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" @@ -45,7 +45,6 @@ #endif #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_enc.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_decision_matrix_enc_fx.c b/lib_enc/ivas_decision_matrix_enc_fx.c index a3194a9d0..1158f72fa 100644 --- a/lib_enc/ivas_decision_matrix_enc_fx.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -35,11 +35,10 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index ec55850fd..7bfa9f268 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index 95a114b67..576bbb2c6 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -32,11 +32,10 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index 2bab65c42..0a2d976e1 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -36,14 +36,13 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_entropy_coder_fx.c b/lib_enc/ivas_entropy_coder_fx.c index eb82aa78a..a95f2884c 100644 --- a/lib_enc/ivas_entropy_coder_fx.c +++ b/lib_enc/ivas_entropy_coder_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index 3844598c6..f1aeb5398 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -36,14 +36,13 @@ #include "ivas_cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" #include #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------------------------* diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 9d31297bd..3eeb45d14 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -34,7 +34,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_enc.h" @@ -42,7 +42,6 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 615660761..64b8991d6 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -34,10 +34,9 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 51af4e5a9..22bf88df8 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -33,12 +33,11 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index a5a1286a2..a36ee78e2 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -38,10 +38,9 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_ism_param_enc_fx.c b/lib_enc/ivas_ism_param_enc_fx.c index bef6912bd..e6b23fcfc 100644 --- a/lib_enc/ivas_ism_param_enc_fx.c +++ b/lib_enc/ivas_ism_param_enc_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index fee34abd8..86237fb31 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -33,12 +33,11 @@ #include #include "options.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index f4fe68c59..21c23c34a 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 36324ae0f..2797fa5e4 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "ivas_rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" @@ -46,7 +45,6 @@ #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- * Local function prototypes diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index 392f1d9ab..9060c786b 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -36,10 +36,9 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index b3f99e27c..bb6ef0d01 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index d11447c03..439c227ae 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -34,14 +34,12 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index dbced19fd..55da30e73 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -36,10 +36,9 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "rom_com.h" diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 7e8547841..88d773b53 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index edfc607ed..403d379fa 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -36,13 +36,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index f09d4513d..7c8b78ffb 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 5eee0975a..648dcdb73 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -36,12 +36,11 @@ #include #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_enc/ivas_pca_enc_fx.c b/lib_enc/ivas_pca_enc_fx.c index 8b61cb6c8..410d5dd52 100644 --- a/lib_enc/ivas_pca_enc_fx.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 3f0218e97..7a2a28767 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -35,15 +35,13 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" -#include "prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_qspherical_enc_fx.c b/lib_enc/ivas_qspherical_enc_fx.c index eb60d4849..a6f40c8f0 100644 --- a/lib_enc/ivas_qspherical_enc_fx.c +++ b/lib_enc/ivas_qspherical_enc_fx.c @@ -39,7 +39,6 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_range_uni_enc_fx.c b/lib_enc/ivas_range_uni_enc_fx.c index 35ecad69c..cf32c644d 100644 --- a/lib_enc/ivas_range_uni_enc_fx.c +++ b/lib_enc/ivas_range_uni_enc_fx.c @@ -39,7 +39,7 @@ #include "rom_com.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_sba_enc_fx.c b/lib_enc/ivas_sba_enc_fx.c index b247900a0..86427eb2d 100644 --- a/lib_enc/ivas_sba_enc_fx.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -37,13 +37,12 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 9f63c4fc7..8c2c945d6 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 8f93c4d76..e6038186e 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -35,10 +35,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_spar_encoder_fx.c b/lib_enc/ivas_spar_encoder_fx.c index a0c5be842..674a80549 100644 --- a/lib_enc/ivas_spar_encoder_fx.c +++ b/lib_enc/ivas_spar_encoder_fx.c @@ -38,7 +38,6 @@ #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_com.h" -#include "prot.h" #include "math.h" #include "wmc_auto.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 8b23eca5f..925f4e702 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" @@ -42,7 +41,6 @@ #include "ivas_rom_com_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------------------------* * PreProcessor diff --git a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c index 62fed34f7..70c2165f8 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 0c90d5fdc..bfe683d6b 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -38,13 +38,12 @@ #endif #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index 4727cd188..255b6e938 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -36,12 +36,11 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 8578a46ae..3f7237ce5 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -37,10 +37,9 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 70a467232..7900033f4 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index dd7f575b7..58e66a01a 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_prot.h" #include "ivas_rom_com.h" @@ -43,7 +43,6 @@ #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 7b0e7df62..a3388db61 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" @@ -45,7 +44,6 @@ #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_eclvq_enc_fx.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c index cd0e6fe2d..f4962c802 100644 --- a/lib_enc/ivas_stereo_eclvq_enc_fx.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -39,7 +39,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" /* used only for norm_s in the code_length_from_count function */ diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index e0a8a8ed4..351b87cd0 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -36,12 +36,11 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 8c2d136b7..78891c5f7 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -35,12 +35,11 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 2a87ea4f9..28b0e41b9 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" diff --git a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c index 38be1a6a4..57bb18e80 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "stat_enc.h" diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index 9c729709d..b1213a750 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 190adbf1c..f3ceb2757 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -34,14 +34,13 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 79e05bf09..efae1e80d 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -35,14 +35,13 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 304754fc3..f8d600276 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -44,7 +44,6 @@ #endif #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 84bffa87c..28044b45d 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -35,13 +35,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "basop_proto_func.h" #include "wmc_auto.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #include "rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 4d6a908b3..34215025f 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 1f2fee684..211c53f8c 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -41,7 +41,6 @@ #include "lib_enc.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 709bb47e0..a61b2ebff 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -8,7 +8,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 830f1ecd6..7f58a9501 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -38,7 +38,6 @@ #include "options.h" #include "cnst.h" #include "ivas_prot.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index 265fce7f2..eec85c254 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index d8a78c525..771ef480b 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -6,9 +6,8 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot.h" /* Function prototypes */ -#include "basop32.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ +#include "basop32.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index 3bd8e340d..a7588283a 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" diff --git a/lib_enc/peak_vq_enc_fx.c b/lib_enc/peak_vq_enc_fx.c index 9ea1af949..aa4763aa6 100644 --- a/lib_enc/peak_vq_enc_fx.c +++ b/lib_enc/peak_vq_enc_fx.c @@ -11,7 +11,6 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------------- diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index d53e2eb6e..bcf7d33bb 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "rom_basop_util.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/range_enc_fx.c b/lib_enc/range_enc_fx.c index 05916e801..689b313d8 100644 --- a/lib_enc/range_enc_fx.c +++ b/lib_enc/range_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index a735c498d..353de8ec9 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -19,7 +19,6 @@ #include #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" /*---------------------------------------------------------------------* diff --git a/lib_enc/stat_noise_uv_enc_fx.c b/lib_enc/stat_noise_uv_enc_fx.c index 91dca8d63..0a20db8ed 100644 --- a/lib_enc/stat_noise_uv_enc_fx.c +++ b/lib_enc/stat_noise_uv_enc_fx.c @@ -11,7 +11,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /*======================================================================*/ /* FUNCTION : stat_noise_uv_enc_fx */ diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 3ca3f3f3f..2ca0b6d74 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -4,12 +4,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*---------------------------------------------------------------------* diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index acd984509..1a397c514 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -36,7 +36,6 @@ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" #include "stl.h" -#include "prot.h" /*--------------------------------------------------------------------------* * GetSubbandCorrIndex2_har() diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c deleted file mode 100644 index db4e51127..000000000 --- a/lib_enc/swb_tbe_enc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "ivas_prot.h" diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index a5e4e902b..61ca9b101 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -8,7 +8,6 @@ #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot.h" /* Function prototypes */ diff --git a/lib_enc/tcq_core_enc_fx.c b/lib_enc/tcq_core_enc_fx.c index fbd9775c4..82088be50 100644 --- a/lib_enc/tcq_core_enc_fx.c +++ b/lib_enc/tcq_core_enc_fx.c @@ -10,7 +10,6 @@ #include "ivas_error.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" #define IVAS_FLOAT ivas_error tcq_core_LR_enc_fx( diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index f1881a427..cf6e5dd64 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -12,7 +12,6 @@ #include #include "rom_com_fx.h" #include "rom_com.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 0089fc745..9911d766a 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 4a4c1ff89..008e27d6c 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index 67d47e89d..81437c49d 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -33,7 +33,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" @@ -41,7 +41,6 @@ #include "ivas_rom_binaural_crend_head.h" #include "ivas_stat_rend.h" #include "lib_rend.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 06744dc6e..9cc764afb 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -35,11 +35,10 @@ #include "ivas_cnst.h" #include "ivas_prot_rend.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e2ab6cd3e..7e41581f4 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 01fd1e610..4ea5c5e96 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -35,13 +35,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index c6119cc34..4eae9c286 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -34,14 +34,13 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- * ivas_dirac_dec_onset_detection_open() diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index d6c999aa0..29eac3635 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" @@ -43,7 +43,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index b563d4399..882c6e5b8 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -35,13 +35,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_rend/ivas_efap_fx.c b/lib_rend/ivas_efap_fx.c index 8947809d1..52ca3e6f9 100644 --- a/lib_rend/ivas_efap_fx.c +++ b/lib_rend/ivas_efap_fx.c @@ -35,7 +35,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" diff --git a/lib_rend/ivas_hrtf_fx.c b/lib_rend/ivas_hrtf_fx.c index 506d76efd..5d53d2ae3 100644 --- a/lib_rend/ivas_hrtf_fx.c +++ b/lib_rend/ivas_hrtf_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_error.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_limiter_fx.c b/lib_rend/ivas_limiter_fx.c index 595573016..b66127e09 100644 --- a/lib_rend/ivas_limiter_fx.c +++ b/lib_rend/ivas_limiter_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index e8d06d0bb..8b7e6575d 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -36,9 +36,8 @@ #include "ivas_prot_rend.h" #include "ivas_prot.h" #include "ivas_cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 0b0c8ffeb..25fddaa80 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -37,12 +37,11 @@ #include "options.h" #include "ivas_prot_rend.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 8b689b94b..93fe67436 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -33,14 +33,13 @@ #include "ivas_stat_rend.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" #define float_to_fixed( n, factor ) ( round( n * ( 1 << factor ) ) ) diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index ab09a82b5..a7f46b2a4 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -33,13 +33,12 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* * Local function prototypes diff --git a/lib_rend/ivas_objectRenderer_mix_fx.c b/lib_rend/ivas_objectRenderer_mix_fx.c index a328a51bf..7ee6c828b 100644 --- a/lib_rend/ivas_objectRenderer_mix_fx.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_rom_rend.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_rend/ivas_objectRenderer_sfx_fx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c index caa393355..971e2c2d1 100644 --- a/lib_rend/ivas_objectRenderer_sfx_fx.c +++ b/lib_rend/ivas_objectRenderer_sfx_fx.c @@ -35,9 +35,8 @@ #include #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index af60f7746..307d38351 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -33,11 +33,10 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_vec_fx.c b/lib_rend/ivas_objectRenderer_vec_fx.c index c8efd80ad..4d259a68e 100644 --- a/lib_rend/ivas_objectRenderer_vec_fx.c +++ b/lib_rend/ivas_objectRenderer_vec_fx.c @@ -33,10 +33,9 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 7d6129d20..d7387ecd4 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -37,11 +37,10 @@ #include "ivas_prot_rend.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 980e5ca17..054e5e981 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_rend/ivas_reflections_fx.c b/lib_rend/ivas_reflections_fx.c index e5e8cdb56..a02a29d0d 100644 --- a/lib_rend/ivas_reflections_fx.c +++ b/lib_rend/ivas_reflections_fx.c @@ -33,7 +33,7 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "rom_dec.h" #include "lib_rend.h" #include "ivas_prot_rend.h" @@ -42,7 +42,6 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index 792b485a7..b730b1510 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* * Local constants diff --git a/lib_rend/ivas_reverb_delay_line_fx.c b/lib_rend/ivas_reverb_delay_line_fx.c index 3eeb4ede4..44550803a 100644 --- a/lib_rend/ivas_reverb_delay_line_fx.c +++ b/lib_rend/ivas_reverb_delay_line_fx.c @@ -34,9 +34,8 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "debug.h" /*-----------------------------------------------------------------------------------------* * Function ivas_rev_delay_line_init() diff --git a/lib_rend/ivas_reverb_fft_filter_fx.c b/lib_rend/ivas_reverb_fft_filter_fx.c index 3befcde91..2d0722ceb 100644 --- a/lib_rend/ivas_reverb_fft_filter_fx.c +++ b/lib_rend/ivas_reverb_fft_filter_fx.c @@ -32,11 +32,10 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 428cf3353..652fc898f 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_rend.h" #include diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 9e621ce83..6b41815c4 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "math.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define float_to_fixQ31( n ) ( round( n * 0x7fffffff ) ) diff --git a/lib_rend/ivas_reverb_iir_filter_fx.c b/lib_rend/ivas_reverb_iir_filter_fx.c index 217e16dd8..98b66e0c7 100644 --- a/lib_rend/ivas_reverb_iir_filter_fx.c +++ b/lib_rend/ivas_reverb_iir_filter_fx.c @@ -32,10 +32,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 46ef576a8..ee2bada9d 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "options_warnings.h" /*-----------------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index 39720469b..7ad4c4ccb 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -37,11 +37,10 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" #include -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "debug.h" #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_rend/ivas_sba_rendering_fx.c b/lib_rend/ivas_sba_rendering_fx.c index 7c7a20223..4323fc96f 100644 --- a/lib_rend/ivas_sba_rendering_fx.c +++ b/lib_rend/ivas_sba_rendering_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" diff --git a/lib_rend/ivas_shoebox_fx.c b/lib_rend/ivas_shoebox_fx.c index 9ed0d8d33..7c930104a 100644 --- a/lib_rend/ivas_shoebox_fx.c +++ b/lib_rend/ivas_shoebox_fx.c @@ -36,7 +36,6 @@ #include "ivas_prot_rend.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index af51a7820..6d5b23f12 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_prot.h" diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index e1a6868d8..06cbd83a6 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -34,12 +34,11 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 493979e30..0cda39d62 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -32,7 +32,6 @@ #include "basop_util.h" #include "options.h" #include "lib_rend.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 8920e6780..930bb79dc 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -32,9 +32,8 @@ #include "hrtf_file_reader.h" #include -#include "prot.h" -#include "ivas_prot_rend.h" #include "prot_fx.h" +#include "ivas_prot_rend.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 01d1f0307..90d47b7c9 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -34,7 +34,7 @@ #include #include #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" struct LsCustomFileReader diff --git a/lib_util/mime_io.c b/lib_util/mime_io.c index 782f818d0..2976e1895 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -32,7 +32,7 @@ #include "mime_io.h" #include "mime.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include #include diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index b6122ec0f..e099842be 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -37,7 +37,7 @@ #include #include #include "cmdl_tools.h" -#include "prot.h" +#include "prot_fx.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 468f80765..2299f3265 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -34,7 +34,6 @@ #include #include #include -#include "prot.h" #include "prot_fx.h" diff --git a/lib_util/vector3_pair_file_reader.c b/lib_util/vector3_pair_file_reader.c index ec14ebc71..5745e9595 100644 --- a/lib_util/vector3_pair_file_reader.c +++ b/lib_util/vector3_pair_file_reader.c @@ -35,7 +35,6 @@ #include #include #include -#include "prot.h" #include "options.h" /* only included to get access to the feature-defines */ #include "prot_fx.h" #include "ivas_prot_fx.h" -- GitLab From 1411ee404ff299ce7211e7cd1325aa27e2d9ad6b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 10:13:00 +0530 Subject: [PATCH 0344/1221] Fix for 3GPP issue 1140: Missing conversion of some flt. pt. functions in the BASOP code Link #1140 --- lib_com/float_to_fix_ops.c | 8 ++--- lib_com/ivas_spar_com_fx.c | 39 ++++++++++++++++--------- lib_dec/dec_tcx_fx.c | 19 ++++++------ lib_dec/ivas_lfe_plc_fx.c | 12 ++++---- lib_dec/ivas_mc_paramupmix_dec_fx.c | 6 ++-- lib_dec/ivas_qmetadata_dec_fx.c | 3 +- lib_dec/ivas_spar_md_dec_fx.c | 7 +++-- lib_dec/ivas_stereo_cng_dec.c | 6 ++-- lib_dec/ivas_stereo_dft_dec_fx.c | 38 +++++++++++++++--------- lib_enc/ACcontextMapping_enc_fx.c | 7 +++-- lib_enc/fd_cng_enc_fx.c | 2 +- lib_enc/ivas_agc_enc_fx.c | 2 +- lib_enc/ivas_core_pre_proc_fx.c | 2 +- lib_enc/ivas_cpe_enc_fx.c | 2 +- lib_enc/ivas_init_enc_fx.c | 2 +- lib_enc/ivas_lfe_enc_fx.c | 20 ++++++------- lib_enc/ivas_mc_paramupmix_enc_fx.c | 10 +++---- lib_enc/ivas_osba_enc_fx.c | 2 +- lib_enc/ivas_qmetadata_enc_fx.c | 3 +- lib_enc/ivas_sba_enc_fx.c | 2 +- lib_enc/ivas_stereo_dft_enc_itd_fx.c | 9 ++++-- lib_enc/ivas_stereo_dmx_evs_fx.c | 6 ++-- lib_enc/ivas_stereo_ica_enc_fx.c | 4 +-- lib_enc/ivas_stereo_switching_enc_fx.c | 2 +- lib_rend/ivas_dirac_decorr_dec_fx.c | 4 +-- lib_rend/ivas_dirac_rend_fx.c | 2 +- lib_rend/ivas_reverb_filter_design_fx.c | 6 ++-- lib_rend/ivas_rotation_fx.c | 2 +- lib_rend/lib_rend.c | 12 ++++---- 29 files changed, 137 insertions(+), 102 deletions(-) diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 1f7c28fd8..8b69e05e8 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -183,14 +183,14 @@ Word16 Q_factor( float x ) { Word16 Q = 15; if ( x >= 1 || x <= -1 ) - Q = norm_s( (Word16) abs( (Word32) x ) ); + Q = norm_s( (Word16) L_abs( (Word32) x ) ); return Q; } Word16 Q_factor_L( float x ) { Word16 Q = 31; if ( x >= 1 || x <= -1 ) - Q = norm_l( abs( (Word32) x ) ); + Q = norm_l( L_abs( (Word32) x ) ); return Q; } Word16 Q_factor_L_32( Word32 x ) @@ -206,7 +206,7 @@ Word16 Q_factor_arr( float *x, Word16 l ) for ( int i = 0; i < l; i++ ) { if ( x[i] >= 1 || x[i] <= -1 ) - Q = s_min( Q, norm_s( (Word16) abs( (Word32) x[i] ) ) ); + Q = s_min( Q, norm_s( (Word16) L_abs( (Word32) x[i] ) ) ); } return Q; } @@ -216,7 +216,7 @@ Word16 Q_factor_arrL( float *x, Word16 l ) for ( int i = 0; i < l; i++ ) { if ( x[i] >= 1 || x[i] <= -1 ) - Q = s_min( Q, norm_l( (Word32) abs( (Word32) x[i] ) ) ); + Q = s_min( Q, norm_l( (Word32) L_abs( (Word32) x[i] ) ) ); } return Q; } diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index fc6e60310..6c80c1898 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -4004,7 +4004,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); P_norm_fx[0] = 0; move32(); - FOR( i = 0; i < max( 0, sub( foa_ch, ndm ) ); i++ ) + Word16 len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) { P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4014,7 +4015,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( P_norm_fx[1] = 0; move32(); - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4031,8 +4033,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( } P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31 move32(); - - FOR( i = 0; i < max( 0, ( foa_ch - ndm ) ); i++ ) + len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4045,7 +4047,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4057,6 +4060,7 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } + FOR( ; i < ( num_ch - ndm ); i++ ) { idx = sub( remix_order[i + ndm], ndm ); @@ -4222,7 +4226,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( /*normalize 2nd order*/ norm_fx = 0; move32(); - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + Word16 min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } @@ -4243,7 +4248,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) { @@ -4557,7 +4563,8 @@ void ivas_get_spar_md_from_dirac_fx( move16(); P_norm_fx[0] = 0; move32(); - FOR( i = 0; i < max( 0, sub( foa_ch, ndm ) ); i++ ) + Word16 len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, sub( foa_ch, ndm ) ) { P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4567,7 +4574,8 @@ void ivas_get_spar_md_from_dirac_fx( P_norm_fx[1] = 0; move32(); - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4584,8 +4592,8 @@ void ivas_get_spar_md_from_dirac_fx( } P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31 move32(); - - FOR( i = 0; i < max( 0, ( foa_ch - ndm ) ); i++ ) + len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4598,7 +4606,8 @@ void ivas_get_spar_md_from_dirac_fx( move32(); } } - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4775,7 +4784,8 @@ void ivas_get_spar_md_from_dirac_fx( /*normalize 2nd order*/ norm_fx = 0; move32(); - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + Word16 min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } @@ -4796,7 +4806,8 @@ void ivas_get_spar_md_from_dirac_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) { diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 20f7a0adf..00f372154 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3807,7 +3807,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, (Word16) abs( tmp32 ) * i * 2, &Overflow ); + *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } @@ -3875,7 +3875,8 @@ void decoder_tcx_invQ_fx( test(); IF( !st->tcxonly || ( hTcxCfg->resq && hTcxDec->tcx_lpc_shaped_ari ) ) { - FOR( i = 0; i < max( L_spec, L_frameTCX ); i++ ) + Word16 len = s_max( L_spec, L_frameTCX ); + FOR( i = 0; i < len; i++ ) { xn_buf[i] = ONE_IN_Q14; move16(); @@ -4891,11 +4892,11 @@ void decoder_tcx_tns_fx( move16(); test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 ) { test(); test(); - IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + IF( frame_cnt != 0 && bfi == 0 && st->last_core != ACELP_CORE ) { /* fix sub-window overlap */ hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; @@ -4940,14 +4941,14 @@ void decoder_tcx_tns_fx( test(); test(); test(); - IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) + IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && fUseTns != 0 && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) { /* Apply TNS to get the reconstructed signal */ SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); test(); test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 ) { tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); } @@ -4956,10 +4957,10 @@ void decoder_tcx_tns_fx( test(); test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 ) { test(); - IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ + IF( st->element_mode == EVS_MONO || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ { tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); tmp = L_frameTCX; @@ -5232,7 +5233,7 @@ void decoder_tcx_imdct_fx( { IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); } ELSE { diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index a8b54d3fb..018f99fe7 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -396,7 +396,7 @@ static Word16 lfeplc_lev_dur_fx( IF( LT_16( rc_q_fx[i - 1], 31 ) ) { - IF( GT_32( abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31 + IF( GT_32( L_abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31 { return 1; } @@ -413,7 +413,7 @@ static Word16 lfeplc_lev_dur_fx( } ELSE { - IF( GT_32( abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31 + IF( GT_32( L_abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31 { return 1; } @@ -465,7 +465,7 @@ static Word16 d_a2rc_fx( move32(); km_q_fx = ff_q_fx[m]; move16(); - IF( GE_64( W_shr( abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) ) + IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) ) { FOR( j = 0; j < lpcorder; j++ ) { @@ -826,7 +826,7 @@ static Word32 find_max_delta_fx( IF( !stable ) { - temp = abs( eps_fx ); + temp = L_abs( eps_fx ); IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) ) { exp1 = norm_l( -temp ); @@ -836,12 +836,12 @@ static Word32 find_max_delta_fx( } ELSE { - eps_fx = L_negate( abs( eps_fx ) ); + eps_fx = L_negate( L_abs( eps_fx ) ); } } ELSE { - temp = abs( eps_fx ); + temp = L_abs( eps_fx ); if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) ) { BREAK; diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index e03b385b7..9ea666237 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -132,7 +132,8 @@ void ivas_mc_paramupmix_dec_read_BS( nb_bits_read_orig = 0; move16(); last_bit_pos = sub( last_bit_pos, nb_bits_read_orig ); /* reverse the bitstream for easier reading of indices */ - FOR( i = 0; i < min( MAX_BITS_METADATA, last_bit_pos ); i++ ) + Word16 len = s_min( MAX_BITS_METADATA, last_bit_pos ); + FOR( i = 0; i < len; i++ ) { bstr_meta[i] = st_ivas->bit_stream[last_bit_pos - i]; move16(); @@ -269,7 +270,8 @@ void ivas_mc_paramupmix_dec_render( ivas_mc_paramupmix_dec_sf( st_ivas, output_local_fx ); - FOR( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) + Word16 num_ch = s_min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); + FOR( ch = 0; ch < num_ch; ch++ ) { output_local_fx[ch] += n_samples_sf; } diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index 4bebcda5c..81768af44 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -3257,7 +3257,8 @@ static Word16 read_truncGR_azimuth_fx( move16(); IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) { - FOR( i = 0; i < min( allowed_bits, no_subframes ); i++ ) + Word16 len = s_min( allowed_bits, no_subframes ); + FOR( i = 0; i < len; i++ ) { IF( bitstream[( *pbit_pos )--] == 0 ) { diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index 2b6b145f9..d1efbbd2c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -936,9 +936,10 @@ Word16 ivas_spar_chk_zero_coefs_fx( ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; /*Q0*/ move16(); - FOR( b = 0; b < min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) + Word16 min_bands = s_min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + FOR( b = 0; b < min_bands; b++ ) { - FOR( j = 0; j < sub( add( ndm, ndec ), 1 ); j++ ) + FOR( j = 0; j < ( ( ndm + ndec ) - 1 ); j++ ) { if ( hMdDec->spar_md.band_coeffs[b].pred_re_fx[j] != 0 ) { @@ -948,7 +949,7 @@ Word16 ivas_spar_chk_zero_coefs_fx( } FOR( j = 0; j < ndec; j++ ) { - FOR( k = 0; k < sub( ndm, 1 ); k++ ) + FOR( k = 0; k < ( ndm - 1 ); k++ ) { if ( hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k] != 0 ) { diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 15885a661..4d50ba350 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -585,7 +585,8 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */ ptr_i = ptr_r + 1; - FOR( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) + Word16 len = shr( ( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ) ), 1 ); + FOR( i = 0; i < len; i++ ) { /* Real part in FFT bins */ rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft ); @@ -622,7 +623,8 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */ ptr_i = ptr_r + 1; - FOR( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) + tmp = shr( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ), 1 ); + FOR( i = 0; i < tmp; i++ ) { ( *ptr_r ) = L_shl( Mpy_32_32( ( *ptr_r ), tmp32_1 ), q_shift ); /* q_dft + q_shift */ move32(); diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index c806f358a..8dcc7ada9 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1522,6 +1522,7 @@ void stereo_dft_dec_fx( Word16 q_samp_ratio = Q15; move16(); #endif /* OPT_STEREO_32KBPS_V1 */ + Word16 len; output_frame = (Word16) Mpy_32_32( L_add( st0->output_Fs, FRAMES_PER_SEC_BY_2 ), ONE_BY_FRAMES_PER_SEC_Q31 ); /* Q0 */ @@ -1890,7 +1891,8 @@ void stereo_dft_dec_fx( DFT_R[2 * i + 1] = L_sub( DFT_W, DFT_Y ); /* qDFT */ move32(); } - FOR( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( stop, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { DFT_W = Madd_32_32( Mpy_32_32( hStereoDft->mixer_mat_smooth_fx[0][0][b + k * IVAS_MAX_NUM_BANDS], pDFT_DMX[2 * i] ), L_add( hStereoDft->mixer_mat_smooth_fx[0][1][b + k * IVAS_MAX_NUM_BANDS], @@ -1997,7 +1999,8 @@ void stereo_dft_dec_fx( } ELSE { - FOR( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( stop, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { tmp = L_add( Madd_32_16( pDFT_RES[2 * i], pDFT_DMX[2 * i], g ), DFT_PRED_RES[2 * i] ); /* qDFT */ @@ -2218,8 +2221,8 @@ void stereo_dft_dec_fx( gamma = 0; move16(); } - - FOR( i = max( hFdCngDec->cna_band_limits[b], ( hFdCngCom->startBand / 2 ) ); i < min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); i++ ) + len = s_min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); + FOR( i = s_max( hFdCngDec->cna_band_limits[b], ( hFdCngCom->startBand >> 1 ) ); i < len; i++ ) // i < min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); { Word32 l_tmp; lev1 = *ptr_per++; @@ -2597,6 +2600,7 @@ void stereo_dft_generate_res_pred_fx( q_norm_fac = 0; move16(); #endif /* OPT_STEREO_32KBPS_V1 */ + Word16 len; push_wmops( "gen_respred" ); /* smoothing and limiting parameters */ @@ -2665,7 +2669,8 @@ void stereo_dft_generate_res_pred_fx( move64(); /* calculate band energies (low band only in case of ACELP) */ - FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], bin0 ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { #ifdef OPT_STEREO_32KBPS_V1 dmx_nrg_64bit = W_mac_32_32( W_mac_32_32( dmx_nrg_64bit, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), @@ -2847,7 +2852,8 @@ void stereo_dft_generate_res_pred_fx( } #endif /* OPT_STEREO_32KBPS_V1 */ - FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], bin0 ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { #ifdef OPT_STEREO_32KBPS_V1 DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i] ), 1 ); /* q_dft */ @@ -2969,7 +2975,8 @@ void stereo_dft_generate_res_pred_fx( move32(); dmx_nrg = EPSILON_FIX; move32(); - FOR( i = hStereoDft->band_limits[b]; i < min( bin0, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( bin0, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { dmx_nrg = Madd_32_32( Madd_32_32( dmx_nrg, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ); /* 2 * q_dft - 31 */ @@ -3010,8 +3017,8 @@ void stereo_dft_generate_res_pred_fx( q_sqrt = 0; move16(); } - - FOR( i = hStereoDft->band_limits[b]; i < min( bin0, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( bin0, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( g2, DFT_PRED_RES[2 * i] ), q_sqrt ); /* q_dft */ move32(); @@ -3068,7 +3075,8 @@ void stereo_dft_generate_res_pred_fx( // past_dmx_nrg = EPSILON_FIX; past_dmx_nrg = 0; move32(); - FOR( i = bin0; i < min( ( hStereoDft->NFFT / 2 ), ( STEREO_DFT32MS_N_32k / 2 ) ); i++ ) + len = s_min( shr( hStereoDft->NFFT, 1 ), ( STEREO_DFT32MS_N_32k >> 1 ) ); + FOR( i = bin0; i < len; i++ ) // i < min( ( hStereoDft->NFFT / 2 ), ( hStereoDft->NFFT / 2 ) ) { past_dmx_nrg = L_add( past_dmx_nrg, Madd_32_32( Mpy_32_32( hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i], hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i] ), hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i + 1], hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i + 1] ) ); /* 2 * hStereoDft->q_DFT_past_DMX_fx[d_short_ind] - 31 */ } @@ -3129,7 +3137,8 @@ void stereo_dft_generate_res_pred_fx( } q_shift = sub( hStereoDft->q_dft, hStereoDft->q_DFT_past_DMX_fx[d_short_ind] ); move16(); - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( g2, hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i] ), q_shift ); /* q_dft */ move32(); @@ -3243,7 +3252,8 @@ void stereo_dft_generate_res_pred_fx( move32(); dmx_nrg = EPSILON_FIX; move32(); - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { dmx_nrg = L_add( dmx_nrg, L_shr( Madd_32_32( Mpy_32_32( pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ), 1 ) ); /* 2 * q_dft - 31 - 1 */ @@ -3269,8 +3279,8 @@ void stereo_dft_generate_res_pred_fx( g2 = L_min( Mpy_32_16_1( pred_gain_avg, STEREO_DFT_STEFFI_GAIN_AMP_FX ), Madd_32_16( Mpy_32_16_1( pred_gain_avg, sub( (Word16) ( 0x7FFF ), STEREO_DFT_STEFFI_GAIN_REST_AMT_FX ) ), g2, STEREO_DFT_STEFFI_GAIN_REST_AMT_FX ) ); /* Q31 */ - - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { DFT_PRED_RES[2 * i] = Mpy_32_32( g2, DFT_PRED_RES[2 * i] ); /* Q31 */ move32(); diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 1e8bef488..44439540f 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1341,8 +1341,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /* Init current 2-tuple encoding */ - a1 = (Word16) abs( x[a1_i] ); - b1 = (Word16) abs( x[b1_i] ); + a1 = abs_s( x[a1_i] ); + b1 = abs_s( x[b1_i] ); lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); @@ -1731,7 +1731,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( /* Main Loop through the 2-tuples */ /*hContextMem->nt_half = end_line >> 1;*/ - FOR( k = start_line; k < min( hContextMem->lastnz, end_line ); k += 2 ) + Word16 len = s_min( hContextMem->lastnz, end_line ); + FOR( k = start_line; k < len; k += 2 ) { a1_i = k; /* Q0 */ move16(); diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 307d42078..2db8b956b 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -3039,7 +3039,7 @@ void FdCngEncodeMDCTStereoSID_fx( /* quantize channel coherence */ coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 ); - coh_idx = max( 0, min( coh_idx, 15 ) ); + coh_idx = s_max( 0, s_min( coh_idx, 15 ) ); /* ---- Write SID bitstream ---- */ diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 37d25c508..104eeb998 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -623,7 +623,7 @@ void ivas_agc_enc_process_fx( temp_16 = BASOP_Util_Divide3232_Scale( temp1, temp2, &div_e ); /* exp(div_e) */ IF( div_e < 0 ) { - temp_16 = shr( temp_16, (Word16) abs( div_e ) ); + temp_16 = shr( temp_16, abs_s( div_e ) ); div_e = 0; move16(); } diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index a9da7f342..73403a848 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -184,7 +184,7 @@ ivas_error pre_proc_ivas_fx( } IF( st->hFdCngEnc != NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) && ( ( NE_16( st->hFdCngEnc->hFdCngCom->frameSize, st->L_frame ) ) || ( NE_16( st->hFdCngEnc->hFdCngCom->CngBandwidth, st->input_bwidth ) ) ) ) { - configureFdCngEnc_ivas_fx( st->hFdCngEnc, max( st->input_bwidth, WB ), flag_1 ); + configureFdCngEnc_ivas_fx( st->hFdCngEnc, s_max( st->input_bwidth, WB ), flag_1 ); } if ( st->ini_frame == 0 ) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 811e53d12..a9d62a2b0 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -856,7 +856,7 @@ ivas_error ivas_cpe_enc_fx( } ELSE { - internal_Fs = max( INT_FS_16k, sts[0]->sr_core ); + internal_Fs = L_max( INT_FS_16k, sts[0]->sr_core ); } /* iDFT at input sampling rate */ diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 3eeb45d14..c65c85356 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -493,7 +493,7 @@ ivas_error ivas_init_encoder( if ( NE_32( ivas_format, MONO_FORMAT ) ) { /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ + hEncoderConfig->max_bwidth = s_max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ move16(); } st_ivas->ism_mode = ISM_MODE_NONE; diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 86237fb31..11056b535 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -170,17 +170,17 @@ static void ivas_lfe_enc_quant_fx( { temp_lfe_dct[4 * i] = pLfe_dct[2 * i]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i] ) ); temp_lfe_dct[4 * i + 1] = pLfe_dct[2 * i + 1]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 1] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 1] ) ); temp_lfe_dct[4 * i + 2] = pLfe_dct[2 * i + num_dct_pass_bins]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 2] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 2] ) ); temp_lfe_dct[4 * i + 3] = pLfe_dct[2 * i + num_dct_pass_bins + 1]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 3] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 3] ) ); } IF( LE_64( lfe_abs_sum, W_shr( IVAS_LFE_ABS_SUM_FLT_THR_Q42, sub( 42, q_pLfe_dct ) ) ) ) @@ -250,9 +250,9 @@ static void ivas_lfe_enc_quant_fx( move16(); } - IF( LT_32( max_of_vals, abs( values[i] ) ) ) + IF( LT_32( max_of_vals, abs_s( values[i] ) ) ) { - max_of_vals = (Word16) abs( values[i] ); + max_of_vals = abs_s( values[i] ); move16(); } } @@ -475,8 +475,8 @@ void ivas_lfe_enc_fx( IF( GT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, min( q_tmp2, sub( q_out1, q_out2 ) ) ); - q_out2 = add( q_out2, min( q_tmp2, sub( q_out1, q_out2 ) ) ); + Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, s_min( q_tmp2, sub( q_out1, q_out2 ) ) ); + q_out2 = add( q_out2, s_min( q_tmp2, sub( q_out1, q_out2 ) ) ); IF( GT_16( q_out1, q_out2 ) ) { Scale_sig32( lfe_dct_fx, num_dct_pass_bins, sub( q_out2, q_out1 ) ); // q_out2 @@ -486,8 +486,8 @@ void ivas_lfe_enc_fx( } ELSE IF( LT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx, num_dct_pass_bins, min( q_tmp1, sub( q_out2, q_out1 ) ) ); - q_out1 = add( q_out1, min( q_tmp1, sub( q_out2, q_out1 ) ) ); + Scale_sig32( lfe_dct_fx, num_dct_pass_bins, s_min( q_tmp1, sub( q_out2, q_out1 ) ) ); + q_out1 = add( q_out1, s_min( q_tmp1, sub( q_out2, q_out1 ) ) ); IF( LT_16( q_out1, q_out2 ) ) { Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, sub( q_out1, q_out2 ) ); // q_out1 diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index 9060c786b..abd09cbbd 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -201,7 +201,7 @@ ivas_error ivas_mc_paramupmix_enc_open_fx( /* still 1.5ms off, since MCT delay is not large enough */ /* param at end of frame */ fb_cfg->prior_input_length = (Word16) ( NS2SA_FX2( input_Fs, 12000000L ) + NS2SA_FX2( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA_FX2( input_Fs, DELAY_FB_1_NS / 2 ) ); - fb_cfg->prior_input_length = (Word16) max( fb_cfg->prior_input_length, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + fb_cfg->prior_input_length = s_max( fb_cfg->prior_input_length, (Word16) input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Allocate and initialize FB mixer handle */ IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMCParamUpmix->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) @@ -496,12 +496,12 @@ static void quantize_pars_fx( Word16 exp_var1 = 0; move16(); Word32 var1 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq0] ), 31 - Q28, &exp_var1 ); - var1 = abs( var1 ); + var1 = L_abs( var1 ); Word16 exp_var2 = 0; move16(); Word32 var2 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq1] ), 31 - Q28, &exp_var2 ); - var2 = abs( var2 ); + var2 = L_abs( var2 ); Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); @@ -591,12 +591,12 @@ static void quantize_beta_fx( Word16 exp_var1 = 0; move16(); Word32 var1 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq0] ), 31 - Q28, &exp_var1 ); - var1 = abs( var1 ); + var1 = L_abs( var1 ); Word16 exp_var2 = 0; move16(); Word32 var2 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq1] ), 31 - Q28, &exp_var2 ); - var2 = abs( var2 ); + var2 = L_abs( var2 ); Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 648dcdb73..1229624de 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -300,7 +300,7 @@ ivas_error ivas_osba_enc_reconfig( } } - ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); + ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); hSpar = st_ivas->hSpar; diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 7a2a28767..3416ab279 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -4089,7 +4089,8 @@ static ivas_error requantize_direction_EC_3_fx( IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) { - FOR( k = 0; k < min( no_subframes, allowed_bits ); k++ ) + Word16 len = s_min( no_subframes, allowed_bits ); + FOR( k = 0; k < len; k++ ) { push_next_indice( hMetaData, q_direction->band_data[j].azimuth_index[k], 1 ); } diff --git a/lib_enc/ivas_sba_enc_fx.c b/lib_enc/ivas_sba_enc_fx.c index 86427eb2d..8fdca5815 100644 --- a/lib_enc/ivas_sba_enc_fx.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -199,7 +199,7 @@ ivas_error ivas_sba_enc_reconfigure_fx( } } - ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); + ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); hSpar = st_ivas->hSpar; diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 7900033f4..862102d3b 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -547,7 +547,8 @@ static Word32 calc_mean_E_ratio_fx( sum_nrg_R_e = 0; move16(); - FOR( i = band_limits[b]; i < min( band_limits[b + 1], STEREO_DFT_N_32k_ENC / 2 ); i++ ) + Word16 len = s_min( band_limits[b + 1], STEREO_DFT_N_32k_ENC >> 1 ); + FOR( i = band_limits[b]; i < len; i++ ) { // sum_xcorr[0] += hItd->xcorr_smooth[2 * i]; sum_xcorr[0] = BASOP_Util_Add_Mant32Exp( sum_xcorr[0], sum_xcorr_e[0], hItd->xcorr_smooth_fx[2 * i], hItd->xcorr_smooth_fx_e[2 * i], &sum_xcorr_e[0] ); @@ -2568,7 +2569,11 @@ void stereo_dft_enc_compute_itd_fx( prev_itd_max = hItd->hybrid_itd_max; move16(); /* enable hybrid ITD handling for very large ITDs*/ - hItd->hybrid_itd_max = ( abs( itd ) > STEREO_DFT_ITD_MAX && abs( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); + // hItd->hybrid_itd_max = ( abs_s( itd ) > STEREO_DFT_ITD_MAX && abs_s( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); + test(); + test(); + test(); + hItd->hybrid_itd_max = ( GT_16( abs_s( itd ), STEREO_DFT_ITD_MAX ) && LT_16( abs_s( itd ), STEREO_DFT_ITD_MAX_ANA ) && !hCPE->hCoreCoder[0]->sp_aud_decision0 && LT_32( hCPE->element_brate, IVAS_32k ) ); move16(); /* Update memory */ hItd->prev_itd = itd; diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index a3388db61..c3cb68719 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -1203,7 +1203,7 @@ static Word32 find_poc_peak_fx( /*compute peak_range*/ tmp1 = idiv1616( hPOC->shift_limit, STEREO_DMX_EVS_FIND_POC_PEAK_TAU ); - peak_range = idiv1616( add( extract_l( abs( itd_cand[n] ) ), tmp1 ), STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 ); // Q0 + peak_range = idiv1616( add( extract_l( abs_s( itd_cand[n] ) ), tmp1 ), STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 ); // Q0 FOR( i = 1; i <= peak_range; i++ ) { @@ -1250,7 +1250,7 @@ static Word32 find_poc_peak_fx( IF( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/ { tmp13_e = 0, tmp15_e = 0; - tmp13 = BASOP_Util_Divide1616_Scale( (Word16) abs( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); + tmp13 = BASOP_Util_Divide1616_Scale( abs_s( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); tmp14 = L_mult( 6554 /*0.2f Q15*/, tmp13 ); // tmp13_e tmp15 = BASOP_Util_Add_Mant32Exp( 644245120 /*0.75f in Q31*/, 0, L_negate( tmp14 ), tmp13_e, &tmp15_e ); tmp15 = Mpy_32_32( tmp15, peakQ_fx[n] ); // tmp15_e + peakQ_e[n] @@ -1299,7 +1299,7 @@ static Word32 find_poc_peak_fx( tmp13_e = 0, tmp15_e = 0; move16(); move16(); - tmp13 = BASOP_Util_Divide1616_Scale( (Word16) abs( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); + tmp13 = BASOP_Util_Divide1616_Scale( abs_s( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); tmp14 = L_mult( 6554 /*0.2f Q15*/, tmp13 ); // tmp13_e tmp15 = BASOP_Util_Add_Mant32Exp( 1610612736 /*0.75f in Q31*/, 0, L_negate( tmp14 ), tmp13_e, &tmp15_e ); diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 351b87cd0..78c324cce 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1737,7 +1737,7 @@ void stereo_tca_enc_fx( prev_ICA_flag = 0; move16(); test(); - if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 ) + if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs_s( hStereoTCA->prevCorrLagStats[2] ) != 0 ) { prev_ICA_flag = 1; move16(); @@ -1924,7 +1924,7 @@ void stereo_tca_enc_fx( /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */ tempS = shr( currentNCShift, 1 ); /* Q0 */ - IF( LE_32( abs( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) ) + IF( LE_32( abs_s( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) ) { adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 ); } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index f3ceb2757..6513a3fa7 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -241,7 +241,7 @@ ivas_error stereo_memory_enc_fx( IF( hCPE->hStereoTCA != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { #ifdef FIX_1132_STACK_CORRUPTION - Word16 tmp = extract_h( abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); + Word16 tmp = extract_h( L_abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); if ( hCPE->hStereoDft->hItd->itd_fx[1] < 0 ) { tmp = negate( tmp ); diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 4ea5c5e96..32803f6c3 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -949,8 +949,8 @@ void ivas_dirac_dec_decorr_process_fx( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = add( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth, q_shift ); move16(); } - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); + h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); + h_freq_domain_decorr_ap_state->q_direct_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); #endif e_reverb_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 882c6e5b8..cc8e4d8bd 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -3811,7 +3811,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, hDirACRend->num_protos_diff, hDirACRend->proto_index_diff, - hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * min( 4, nchan_transport ), + hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * s_min( 4, nchan_transport ), &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, onset_filter_fx, hDirACRend->h_freq_domain_decorr_ap_params, diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 652fc898f..45e492fc8 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -740,7 +740,7 @@ void ivas_reverb_calc_color_levels_fx( Word16 temp = 0, result_e = 0; move16(); move16(); - cos_w = getCosWord16R2( (Word16) abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 + cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28 H_filter = BASOP_Util_Divide3232_Scale_cadence( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); H_filter = Sqrt32( H_filter, &temp ); @@ -1155,9 +1155,9 @@ void ivas_reverb_get_hrtf_set_properties_fx( IA_coherence[freq_idx] = L_shl( IA_coherence[freq_idx], sub( 27, sub( 15, temp ) ) ); // q = 27 move32(); /* Limiting to (0...1) range in case of small numerical errors or negative values */ - IA_coherence[freq_idx] = min( IA_coherence[freq_idx], ONE_IN_Q27 ); // Q27 + IA_coherence[freq_idx] = L_min( IA_coherence[freq_idx], ONE_IN_Q27 ); // Q27 move32(); - IA_coherence[freq_idx] = max( IA_coherence[freq_idx], 0 ); // Q27 + IA_coherence[freq_idx] = L_max( IA_coherence[freq_idx], 0 ); // Q27 move32(); } diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index 7ad4c4ccb..8b352218b 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -399,7 +399,7 @@ void rotateAziEle_fx( angle = extract_l( L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), 24 ) ); // Q0 } - *azi = s_max( -180, min( 180, angle ) ); + *azi = s_max( -180, s_min( 180, angle ) ); move16(); IF( isPlanar == 0 ) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 0cda39d62..ae3166520 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1177,8 +1177,8 @@ static Word8 checkObjectPositionChanged_fx( IVAS_ISM_METADATA *previousPos ) { test(); - return !( LT_32( abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && - LT_32( abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); + return !( LT_32( L_abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && + LT_32( L_abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); } static rendering_context getRendCtx( @@ -2018,7 +2018,7 @@ static ivas_error updateMcPanGainsForAmbiOut( Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); - IF( GE_32( abs( temp ), ONE_IN_Q29 ) ) + IF( GE_32( L_abs( temp ), ONE_IN_Q29 ) ) { IF( temp > 0 ) { @@ -2066,7 +2066,7 @@ static ivas_error updateMcPanGainsForAmbiOut( { Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); - IF( GE_32( abs( temp ), ONE_IN_Q29 ) ) + IF( GE_32( L_abs( temp ), ONE_IN_Q29 ) ) { IF( temp > 0 ) { @@ -4537,7 +4537,7 @@ static void renderBufferChannelLerp_fx( /* Process current output channel only if applying non-zero gains */ test(); test(); - IF( GT_32( abs( currentGain ), EPSILON_FX ) || ( gainsPrev != NULL && GT_32( abs( previousGain ), EPSILON_FX ) ) ) + IF( GT_32( L_abs( currentGain ), EPSILON_FX ) || ( gainsPrev != NULL && GT_32( L_abs( previousGain ), EPSILON_FX ) ) ) { /* Reset input pointer to the beginning of input channel */ inSmpl = getSmplPtr_fx( inAudio, inChannelIdx, 0 ); @@ -4546,7 +4546,7 @@ static void renderBufferChannelLerp_fx( outSmpl = getSmplPtr_fx( outAudio, outChnlIdx, 0 ); test(); - IF( gainsPrev == NULL || LE_32( abs( L_sub( L_shr( previousGain, 1 ), L_shr( currentGain, 1 ) ) ), EPSILON_FX ) ) + IF( gainsPrev == NULL || LE_32( L_abs( L_sub( L_shr( previousGain, 1 ), L_shr( currentGain, 1 ) ) ), EPSILON_FX ) ) { /* If no interpolation from previous frame, apply current gain */ DO -- GitLab From 7a5cb1ab39d2b4053aa3ad960201a0e82542acb7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 10:45:15 +0530 Subject: [PATCH 0345/1221] Fix for 3GPP issue 1347: Saturation of energies memory for dtx path Link #1347 --- lib_enc/ivas_core_pre_proc_front_fx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index f41eb7f9c..46de4e232 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1016,14 +1016,14 @@ ivas_error pre_proc_front_ivas_fx( Word16 msNoiseEst_Q = Q31; move16(); move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); IF( zero_flag ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_fx, NPART ); + msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + move16(); } - Scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ - st->hFdCngEnc->msNoiseEst_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); - move16(); perform_noise_estimation_enc_ivas_fx( band_energies_LR_fx, sub( Q31, band_energies_LR_fx_q ), enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); } ELSE @@ -1049,14 +1049,14 @@ ivas_error pre_proc_front_ivas_fx( move16(); Word16 msNoiseEst_Q = Q31; move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_fx, NPART ); /* Q0 */ + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); /* Q0 */ IF( zero_flag ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_fx, NPART ); + msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + move16(); } - Scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ - st->hFdCngEnc->msNoiseEst_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); - move16(); zero_flag = get_zero_flag( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); /* Q0 */ Word16 normmsperiodog = 31; move16(); -- GitLab From 9a19ecf2e21bcafd8553cce25ad5e0154b88399c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 11:49:53 +0530 Subject: [PATCH 0346/1221] ASAN issue fix for decoder --- lib_dec/evs_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index aa997d4c0..f20ff77f3 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -36,7 +36,7 @@ ivas_error evs_dec_fx( Word16 exp, fra; Word16 tmp_buffer_fx[L_FRAME48k]; Word16 tmp16, tmp16_2; - Word16 synth_fx[L_FRAME48k]; + Word16 synth_fx[L_FRAME48k + HQ_DELTA_MAX * HQ_DELAY_COMP]; Word16 fb_exc_fx[L_FRAME16k]; Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; Word16 Q_fb_exc; -- GitLab From b3922a9c9aab7037a50045e55f128ce965937ef3 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 7 Mar 2025 08:48:17 +0100 Subject: [PATCH 0347/1221] rename delay_signal() -> delay_signal_fx() --- Workspace_msvc/lib_com.vcxproj.filters | 2 +- lib_com/prot_fx.h | 4 +- lib_com/tools_fx.c | 46 ++++++++----------- lib_dec/amr_wb_dec_fx.c | 2 +- lib_dec/core_switching_dec_fx.c | 4 +- lib_dec/evs_dec_fx.c | 8 ++-- lib_dec/hf_synth_fx.c | 5 +- lib_dec/ivas_core_dec_fx.c | 2 +- lib_dec/ivas_ism_renderer_fx.c | 2 +- lib_dec/ivas_jbm_dec_fx.c | 4 +- lib_dec/ivas_lfe_dec_fx.c | 2 +- lib_dec/ivas_mc_paramupmix_dec_fx.c | 2 +- lib_dec/ivas_omasa_dec_fx.c | 2 +- lib_dec/ivas_sce_dec_fx.c | 4 +- lib_dec/ivas_stereo_switching_dec_fx.c | 10 ++-- lib_enc/ivas_front_vad_fx.c | 2 +- lib_enc/ivas_osba_enc_fx.c | 2 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 4 +- lib_rend/ivas_td_decorr_fx.c | 2 +- 19 files changed, 52 insertions(+), 57 deletions(-) diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index b9769e3ec..5dabcfd91 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -619,7 +619,7 @@ common_h - common_all_c + common_h diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 32bd5cc4a..65fc2bf80 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -10544,14 +10544,14 @@ void floating_point_add( const Word16 ey /* i: exponent of the adder Q0 */ ); -void delay_signal( +void delay_signal_fx( Word16 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ Word16 mem[], /* i/o: synchronization memory */ const Word16 delay /* i : delay in samples */ ); -void delay_signal32( +void delay_signal32_fx( Word32 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ Word32 mem[], /* i/o: synchronization memory */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index fad9ad664..fad2d64a8 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -4004,13 +4004,14 @@ void floating_point_add( move16(); return; } + /*-------------------------------------------------------------------* - * delay_signal() + * delay_signal_fx() * * Delay buffer by defined number of samples *-------------------------------------------------------------------*/ -void delay_signal( +void delay_signal_fx( Word16 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ Word16 mem[], /* i/o: synchronization memory */ @@ -4027,6 +4028,23 @@ void delay_signal( return; } +void delay_signal32_fx( + Word32 x[], /* i/o: signal to be delayed */ + const Word16 len, /* i : length of the input signal */ + Word32 mem[], /* i/o: synchronization memory */ + const Word16 delay /* i : delay in samples */ +) +{ + Word32 tmp_buffer[L_FRAME48k]; + + Copy32( mem, tmp_buffer, delay ); + Copy32( x + sub( len, delay ), mem, delay ); + Copy32( x, x + delay, sub( len, delay ) ); + Copy32( tmp_buffer, x, delay ); + + return; +} + void delay_signal_q_adj_fx( Word32 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ @@ -4119,30 +4137,6 @@ void v_shr_16( return; } -/*-------------------------------------------------------------------* - * delay_signal32() - * - * Delay buffer by defined number of samples - *-------------------------------------------------------------------*/ - -void delay_signal32( - Word32 x[], /* i/o: signal to be delayed */ - const Word16 len, /* i : length of the input signal */ - Word32 mem[], /* i/o: synchronization memory */ - const Word16 delay /* i : delay in samples */ -) -{ - Word32 tmp_buffer[L_FRAME48k]; - - Copy32( mem, tmp_buffer, delay ); - Copy32( x + sub( len, delay ), mem, delay ); - Copy32( x, x + delay, sub( len, delay ) ); - Copy32( tmp_buffer, x, delay ); - - return; -} - - /*---------------------------------------------------------------------* * lin_interp_fx() * diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index d45655903..c3e5b6891 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -1062,7 +1062,7 @@ ivas_error amr_wb_dec_fx( { tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ); Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) ); - delay_signal( synth_out_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); + delay_signal_fx( synth_out_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); } IF( waveadj_rec ) diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 9c69b0432..cd667586f 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -978,7 +978,7 @@ ivas_error core_switching_post_dec_fx( Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); - delay_signal( synth, output_frame, st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth, Q0 */ + delay_signal_fx( synth, output_frame, st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth, Q0 */ test(); test(); @@ -1407,7 +1407,7 @@ ivas_error core_switching_post_dec_ivas_fx( Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); /* Qtmp */ hHQ_core->Q_old_postdec = Qtmp; move16(); - delay_signal( synth, output_frame, st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth, Q0 */ + delay_signal_fx( synth, output_frame, st_fx->delay_buf_out_fx, delay_comp ); /* Qsynth, Q0 */ test(); test(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 98cf533f9..f46e29340 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -35,7 +35,7 @@ ivas_error evs_dec_fx( Word16 exp, fra; Word16 tmp_buffer_fx[L_FRAME48k]; Word16 tmp16, tmp16_2; - Word16 synth_fx[L_FRAME48k + HQ_DELTA_MAX * HQ_DELAY_COMP]; + Word16 synth_fx[L_FRAME48k]; Word16 fb_exc_fx[L_FRAME16k]; Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; Word16 Q_fb_exc; @@ -491,7 +491,7 @@ ivas_error evs_dec_fx( Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( exp, st_fx->Qprev_synth_buffer_fx ) ); /*exp*/ st_fx->Qprev_synth_buffer_fx = exp; move16(); - delay_signal( synth_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); /*exp, t_fx->Qprev_synth_buffer_fx*/ + delay_signal_fx( synth_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps ); /*exp, t_fx->Qprev_synth_buffer_fx*/ } ELSE { @@ -636,7 +636,7 @@ ivas_error evs_dec_fx( { Scale_sig( st_fx->hb_prev_synth_buffer_fx, tmps, tmp16 ); /*Q15 - hb_synth_fx_exp*/ } - delay_signal( hb_synth_fx, output_frame, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp, Q15 - hb_synth_fx_exp*/ + delay_signal_fx( hb_synth_fx, output_frame, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hb_synth_fx_exp, Q15 - hb_synth_fx_exp*/ st_fx->old_bwe_delay = tmps; move16(); @@ -1197,7 +1197,7 @@ ivas_error evs_dec_fx( IF( GE_16( output_frame, L_FRAME16k ) ) { Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, negate( timeIn_e ) ); - delay_signal( output_sp, output_frame, st_fx->prev_synth_buffer_fx, delay_tdbwe ); /*timeIn_e, st_fx->q_prev_synth_buffer_fx*/ + delay_signal_fx( output_sp, output_frame, st_fx->prev_synth_buffer_fx, delay_tdbwe ); /*timeIn_e, st_fx->q_prev_synth_buffer_fx*/ Scale_sig( st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e ); } diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index 82cca36fb..94c7d4c62 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -265,7 +265,7 @@ static void hf_synthesis_fx( *-----------------------------------------------------------------*/ /* delay by 5 samples @16kHz to compensate CLDFB resampling delay (20samples) and HP filtering delay (roughly 15 samples) */ - delay_signal( HF_syn, L_SUBFR16k, hBWE_zero->delay_syn_hf_fx, NS2SA_FX2( 16000, DELAY_CLDFB_NS ) - 15 ); + delay_signal_fx( HF_syn, L_SUBFR16k, hBWE_zero->delay_syn_hf_fx, NS2SA_FX2( 16000, DELAY_CLDFB_NS ) - 15 ); /* interpolate the HF synthesis */ IF( EQ_16( output_subfr, L_SUBFR48k ) ) /* 48kHz sampled output */ @@ -1126,7 +1126,8 @@ static void hf_synthesis_amr_wb_fx( * Synchronize LB and HB components (delay componsation) * Add synthesised high band to speech synthesis *-----------------------------------------------------------------*/ - delay_signal( HF_syn, L_SUBFR16k, delay_syn_hf, NS2SA( 16000, DELAY_CLDFB_NS ) ); + + delay_signal_fx( HF_syn, L_SUBFR16k, delay_syn_hf, NS2SA( 16000, DELAY_CLDFB_NS ) ); IF( EQ_16( output_subfr, L_SUBFR48k ) ) /* 48kHz sampled output */ { diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 044350a5d..bdc5bbf8d 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1449,7 +1449,7 @@ ivas_error ivas_core_dec_fx( Word32 hb_prev_synth_buffer_fx_32[111]; Copy_Scale_sig_16_32_DEPREC( st->hb_prev_synth_buffer_fx, hb_prev_synth_buffer_fx_32, 111, 11 ); // Q11 - delay_signal32( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); + delay_signal32_fx( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); Copy_Scale_sig_32_16( hb_prev_synth_buffer_fx_32, st->hb_prev_synth_buffer_fx, 111, -( 11 ) ); // Q0 } ELSE diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index b2ee321bc..67d12430f 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -565,7 +565,7 @@ void ivas_omasa_separate_object_render_jbm_fx( Word16 tcBufferSize; tcBufferSize = i_mult( hSpatParamRendCom->num_slots, hSpatParamRendCom->slot_size ); - delay_signal32( input_fx[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[obj], st_ivas->hMasaIsmData->delayBuffer_size ); + delay_signal32_fx( input_fx[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[obj], st_ivas->hMasaIsmData->delayBuffer_size ); } offsetSamples = 0; move16(); diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index dc111b6b4..db6d0d34e 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1362,7 +1362,7 @@ ivas_error ivas_jbm_dec_tc_fx( ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 ) { /* Delay the separated channel to sync with the DirAC rendering */ - delay_signal32( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); + delay_signal32_fx( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); } } ELSE @@ -1710,7 +1710,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( { FOR( n = 0; n < st_ivas->nchan_ism; n++ ) { - delay_signal32( st_ivas->hTcBuffer->tc_fx[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer_fx[n], st_ivas->hSbaIsmData->delayBuffer_size ); + delay_signal32_fx( st_ivas->hTcBuffer->tc_fx[n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hSbaIsmData->delayBuffer_fx[n], st_ivas->hSbaIsmData->delayBuffer_size ); } } diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index fab4963f5..f70b799cd 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -393,7 +393,7 @@ void ivas_lfe_dec_fx( /* add delay to make overall max(block_offset, 11.5) */ IF( hLFE->lfe_addl_delay > 0 ) { - delay_signal32( output_lfe_ch, output_frame, hLFE->lfe_delay_buf_fx, hLFE->lfe_addl_delay ); + delay_signal32_fx( output_lfe_ch, output_frame, hLFE->lfe_delay_buf_fx, hLFE->lfe_addl_delay ); } return; diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index 265872de7..afd685401 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -500,7 +500,7 @@ static void paramupmix_td_decorr_process_jbm_fx( FOR( k = 0; k < MC_PARAMUPMIX_COMBINATIONS; k++ ) { Copy32( pcm_in[k], pp_out_pcm[k], output_frame ); - delay_signal32( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); + delay_signal32_fx( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); /* In ducking gains */ IF( hTdDecorr[k]->ducking_flag ) diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index 824c836f6..c7cee35df 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -778,7 +778,7 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm_fx( tc_local_fx[n] = st_ivas->hTcBuffer->tc_fx[n + 2]; // Q11 v_multc_fixed_16( tc_local_fx[n], gain_fx, tc_local_fx[n], tcBufferSize ); - delay_signal32( tc_local_fx[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size ); + delay_signal32_fx( tc_local_fx[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size ); } } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index a30732b95..e40f0c6f2 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -319,13 +319,13 @@ ivas_error ivas_sce_dec_fx( * LB synthesis synchronization between IVAS formats *----------------------------------------------------------------*/ - delay_signal32( output[0], output_frame, st->prev_synth_buffer32_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ) ); + delay_signal32_fx( output[0], output_frame, st->prev_synth_buffer32_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ) ); /*----------------------------------------------------------------* * HB synthesis synchronization between IVAS formats *----------------------------------------------------------------*/ - delay_signal32( outputHB[0], output_frame, hSCE->prev_hb_synth_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + delay_signal32_fx( outputHB[0], output_frame, hSCE->prev_hb_synth_fx, NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); /*----------------------------------------------------------------* * output LB and HB mix diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 00ad8d7a6..8697c6c3d 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -1264,7 +1264,7 @@ void synchro_synthesis_fx( { /* delay CLDFB-based mono output (<= 24.4 kbps) to be aligned with DFT-based mono output (32 kbps), needed to avoid discontinuities with TCX-LTP. */ Copy32( sts[0]->prev_synth_buffer32_fx + delay_comp_DFT, hCPE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ - delay_signal32( output_fx[0], output_frame, hCPE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); + delay_signal32_fx( output_fx[0], output_frame, hCPE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); } IF( NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) @@ -1281,7 +1281,7 @@ void synchro_synthesis_fx( } ELSE { - delay_signal32( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); + delay_signal32_fx( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); } } if ( sba_dirac_stereo_flag ) @@ -1602,15 +1602,15 @@ void synchro_synthesis_fx( IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { Copy32( sts[n]->prev_synth_buffer32_fx + delay_comp_DFT, hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ - delay_signal32( output_fx[n], output_frame, hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ + delay_signal32_fx( output_fx[n], output_frame, hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, delay_diff ); /* Q11 */ ivas_post_proc_fx( NULL, hCPE, n, output_fx[n], output_fx, output_frame, 0, output_fx_q ); - delay_signal32( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); + delay_signal32_fx( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_DFT ); Copy32( hCPE->hCoreCoder[n]->hTcxDec->FBTCXdelayBuf_32, sts[n]->prev_synth_buffer32_fx + delay_comp_DFT, delay_diff ); /* Q11 */ } ELSE { - delay_signal32( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_TD ); + delay_signal32_fx( output_fx[n], output_frame, sts[n]->prev_synth_buffer32_fx, delay_comp_TD ); } } diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index f1aeb5398..2ba548ae2 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -582,7 +582,7 @@ ivas_error front_vad_spar_fx( st->input_fx = input_fx; Copy_Scale_sig32_16( omni_in, st->input_fx, input_frame, Q16 - Q11 ); /* Q16 */ - delay_signal( st->input_fx, input_frame, hFrontVad->delay_buf_fx, hFrontVad->delay_samples ); + delay_signal_fx( st->input_fx, input_frame, hFrontVad->delay_buf_fx, hFrontVad->delay_samples ); /* Scaling only if the omni_in buffer contains non-zero values */ maximum_abs_16_fx( st->input_fx, input_frame, &tmp ); diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 3a7c589fd..bfccc3d16 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -447,7 +447,7 @@ void ivas_osba_enc_fx( /* delay ISM input channels to match the SBA encoder delay */ FOR( n = 0; n < nchan_ism; n++ ) { - delay_signal32( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s ); + delay_signal32_fx( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s ); azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 8447cee26..ad806c11a 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -3726,7 +3726,7 @@ void ivas_lfe_synth_with_filters_fx( /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */ delay = hMasaLfeSynth->delayBuffer_syncDirAC_size; move16(); - delay_signal32( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/ + delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/ /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */ lowpassCoef_fx_exp = 15; @@ -3885,7 +3885,7 @@ void ivas_lfe_synth_with_filters_fx( /* Delay the separated channel to match the delay of the lowpass filter */ delay = hMasaLfeSynth->delayBuffer_syncLp_size; move16(); - delay_signal32( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/ + delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/ return; } diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index 3720847ef..019811e98 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -486,7 +486,7 @@ void ivas_td_decorr_process_fx( /* Look-ahead delay */ Copy32( pcm_in[0], ppOut_pcm[0], output_frame ); - delay_signal32( ppOut_pcm[0], output_frame, hTdDecorr->look_ahead_buf, hTdDecorr->offset ); + delay_signal32_fx( ppOut_pcm[0], output_frame, hTdDecorr->look_ahead_buf, hTdDecorr->offset ); /* In ducking gains */ IF( hTdDecorr->ducking_flag ) -- GitLab From baaf429d4007a0585084752b0fdd0dbd4a334af1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 7 Mar 2025 09:03:10 +0100 Subject: [PATCH 0348/1221] remove BASOP comparison --- lib_dec/FEC_HQ_core_fx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 803827440..471f15dfa 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -1961,6 +1961,11 @@ static void Next_good_after_burst_erasures_fx( return; } +/*-------------------------------------------------------------------------- + * save_synthesis_hq_fec_fx() + * + * Save synthesis for HQ FEC + *-------------------------------------------------------------------------*/ void save_synthesis_hq_fec_fx( Decoder_State *st, /* i/o: decoder state structure */ @@ -2019,7 +2024,7 @@ void save_synthesis_hq_fec_fx( Copy_Scale_sig( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st->Qprev_synth_buffer_fx ) ); /*Q0*/ } - IF( NE_16( st->core, ACELP_CORE ) ) + IF( st->core == ACELP_CORE ) { IF( GE_16( output_frame, L_FRAME16k ) ) { -- GitLab From 2851cce730e8d986f7fbd8eef8397b5aea806aa7 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 7 Mar 2025 10:22:12 +0100 Subject: [PATCH 0349/1221] correction --- lib_dec/FEC_HQ_core_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 471f15dfa..b748c1785 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -2024,7 +2024,7 @@ void save_synthesis_hq_fec_fx( Copy_Scale_sig( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st->Qprev_synth_buffer_fx ) ); /*Q0*/ } - IF( st->core == ACELP_CORE ) + IF( st->core != ACELP_CORE ) { IF( GE_16( output_frame, L_FRAME16k ) ) { -- GitLab From 7ad3ba2cbf01ffbfc70feb1c499fceafa669cda1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 14:58:16 +0530 Subject: [PATCH 0350/1221] Fix for LTV crash issue Fix for LTV crash : 4 ISM with metadata at 48 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL ROOM IR out, random FER at 5% --- lib_dec/dec_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 00f372154..191065855 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3807,7 +3807,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 + *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } -- GitLab From 9975eec712315c691ba9a8d4edfdfe461af839f7 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 7 Mar 2025 15:04:57 +0100 Subject: [PATCH 0351/1221] first draft of the improvement. --- lib_enc/ivas_sns_enc_fx.c | 102 +++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e6038186e..75c111483 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -171,6 +171,103 @@ static Word16 sns_1st_cod_fx( return index; } +static Word16 sns_1st_cod_fx_q15( + const Word32 *sns_fx, /* i : vector to quantize */ + const Word16 L_frame, + const Word16 core, + Word32 *snsq_fx /* o : quantized sns Q16 */ +) +{ + Word16 index; + const Word16 split_len = M / 2; + move16(); + const Word16 *means; + const Word16 means_fix = 2; // Q15 + push_wmops("sns_1st_cod_fx_q15"); + move16(); + /* remove means */ + means = NULL; + SWITCH( L_frame ) + { + case L_FRAME16k: + means = &sns_1st_means_16k[core - 1][0]; + break; + case L_FRAME25_6k: + means = &sns_1st_means_25k6[core - 1][0]; + break; + case L_FRAME32k: + means = &sns_1st_means_32k[core - 1][0]; + break; + default: + assert( !"illegal frame length in sns_1st_cod" ); + } + FOR( Word16 i = 0; i < M; ++i ) + { + Word32 tmp = L_mult( means[i], means_fix ); // Q16 + snsq_fx[i] = L_add(sns_fx[i], L_negate( tmp ) ); + move32(); + } + + index = 0; + move16(); + FOR( Word16 split = 0; split < 2; ++split ) + { + const Word16 *cdbk_ptr; + Word16 j0, j1; + Word16 dist_split; + Word64 dist_min_fx; + const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 + move16(); + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + + j0 = imult1616( split, split_len ); + j1 = add( j0, split_len ); + + cdbk_ptr = cdbk; + dist_min_fx = 0x7fffffffffffffffull; + dist_split = 0; + FOR( Word16 i = 0; i < 32; ++i ) + { + Word64 dist_fx = 0; + move64(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 dist; + Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + move16(); + dist = ( L_add(snsq_fx[j], L_negate( tmp_1 ) ) ); + dist_fx = W_mac_32_32( dist_fx, dist, dist ); + } + + if ( LT_64( dist_fx, dist_min_fx ) ) + { + dist_min_fx= dist_fx; + dist_split =i ; + } + } + + /* set quantized vector */ + cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + move32(); + } + + /* for second split shift by five bits to store both indices as one 10 bit value */ + IF( EQ_16( split, 1 ) ) + { + dist_split = shl( dist_split, 5 ); + } + + index = add( index, dist_split ); + } + pop_wmops(); + return index; +} + /*------------------------------------------------------------------- * sns_2st_cod() * @@ -276,7 +373,7 @@ void sns_avq_cod_fx( Word16 indxt[256], nbits, nbt, nit; Word32 snsmid_q0_fx[M]; - index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx ); + index[0] = sns_1st_cod_fx_q15( sns_fx, L_frame, core, sns_q_fx ); move16(); nit = 1 + 2; move16(); @@ -303,7 +400,8 @@ void sns_avq_cod_fx( { index++; - index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); + index[0] = sns_1st_cod_fx_q15( snsmid_fx, L_frame, core, snsmid_q_fx ); +// index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); move16(); nit = 1 + 2; move16(); -- GitLab From 09a6bfaf999b961e0d50083e7d8a1c556359b889 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 7 Mar 2025 15:34:59 +0100 Subject: [PATCH 0352/1221] addressed some code review comments in sns_1st_cod_fx_q15(). --- lib_enc/ivas_sns_enc_fx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 75c111483..2bb03a952 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -226,6 +226,8 @@ static Word16 sns_1st_cod_fx_q15( cdbk_ptr = cdbk; dist_min_fx = 0x7fffffffffffffffull; dist_split = 0; + move64(); + move16(); FOR( Word16 i = 0; i < 32; ++i ) { Word64 dist_fx = 0; @@ -234,12 +236,11 @@ static Word16 sns_1st_cod_fx_q15( { Word32 dist; Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - move16(); dist = ( L_add(snsq_fx[j], L_negate( tmp_1 ) ) ); dist_fx = W_mac_32_32( dist_fx, dist, dist ); } - if ( LT_64( dist_fx, dist_min_fx ) ) + IF ( LT_64( dist_fx, dist_min_fx ) ) { dist_min_fx= dist_fx; dist_split =i ; @@ -257,7 +258,7 @@ static Word16 sns_1st_cod_fx_q15( } /* for second split shift by five bits to store both indices as one 10 bit value */ - IF( EQ_16( split, 1 ) ) + if( EQ_16( split, 1 ) ) { dist_split = shl( dist_split, 5 ); } -- GitLab From d8dcbe89e4e4c1ccc8443c600ad384770391e699 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 7 Mar 2025 18:42:08 +0100 Subject: [PATCH 0353/1221] formatting --- lib_enc/ivas_sns_enc_fx.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 2bb03a952..9395fc6d4 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -183,7 +183,7 @@ static Word16 sns_1st_cod_fx_q15( move16(); const Word16 *means; const Word16 means_fix = 2; // Q15 - push_wmops("sns_1st_cod_fx_q15"); + push_wmops( "sns_1st_cod_fx_q15" ); move16(); /* remove means */ means = NULL; @@ -204,7 +204,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_add(sns_fx[i], L_negate( tmp ) ); + snsq_fx[i] = L_add( sns_fx[i], L_negate( tmp ) ); move32(); } @@ -214,8 +214,8 @@ static Word16 sns_1st_cod_fx_q15( { const Word16 *cdbk_ptr; Word16 j0, j1; - Word16 dist_split; - Word64 dist_min_fx; + Word16 dist_split; + Word64 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; @@ -226,26 +226,26 @@ static Word16 sns_1st_cod_fx_q15( cdbk_ptr = cdbk; dist_min_fx = 0x7fffffffffffffffull; dist_split = 0; - move64(); - move16(); - FOR( Word16 i = 0; i < 32; ++i ) - { - Word64 dist_fx = 0; - move64(); - FOR( Word16 j = j0; j < j1; ++j ) - { - Word32 dist; - Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - dist = ( L_add(snsq_fx[j], L_negate( tmp_1 ) ) ); - dist_fx = W_mac_32_32( dist_fx, dist, dist ); - } - - IF ( LT_64( dist_fx, dist_min_fx ) ) - { - dist_min_fx= dist_fx; - dist_split =i ; - } - } + move64(); + move16(); + FOR( Word16 i = 0; i < 32; ++i ) + { + Word64 dist_fx = 0; + move64(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 dist; + Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); + dist_fx = W_mac_32_32( dist_fx, dist, dist ); + } + + IF( LT_64( dist_fx, dist_min_fx ) ) + { + dist_min_fx = dist_fx; + dist_split = i; + } + } /* set quantized vector */ cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; @@ -258,14 +258,14 @@ static Word16 sns_1st_cod_fx_q15( } /* for second split shift by five bits to store both indices as one 10 bit value */ - if( EQ_16( split, 1 ) ) + if ( EQ_16( split, 1 ) ) { dist_split = shl( dist_split, 5 ); } index = add( index, dist_split ); } - pop_wmops(); + pop_wmops(); return index; } @@ -402,7 +402,7 @@ void sns_avq_cod_fx( index++; index[0] = sns_1st_cod_fx_q15( snsmid_fx, L_frame, core, snsmid_q_fx ); -// index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); + // index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); move16(); nit = 1 + 2; move16(); -- GitLab From a58d5ed734a3394bd99eb84c056023f4a9707fc8 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 10 Mar 2025 08:43:15 +0100 Subject: [PATCH 0354/1221] use long testvectors for USAN tests too --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 58547f2ab..cb532dd7d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1307,7 +1307,7 @@ ivas-pytest-enc-usan: before_script: - CLANG_NUM=3 - DUT_DECODER_PATH=./$REF_DECODER_PATH - - TEST_SUITE=$SHORT_TEST_SUITE_ENCODER + - TEST_SUITE=$LONG_TEST_SUITE_ENCODER <<: *ivas-pytest-sanitizers-anchor ### jobs that test flt encoder -> fx decoder @@ -1397,7 +1397,7 @@ ivas-pytest-dec-usan: before_script: - CLANG_NUM=3 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - - TEST_SUITE=$SHORT_TEST_SUITE + - TEST_SUITE=$LONG_TEST_SUITE_NO_RENDERER <<: *ivas-pytest-sanitizers-anchor # --------------------------------------------------------------- -- GitLab From 18bf870b5406fd0ab15d1557dc93bc10e8df1ccb Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 10 Mar 2025 13:59:00 +0100 Subject: [PATCH 0355/1221] sns_1st_cod_fx_q15() implemented with a 32 bit multiplication. --- lib_enc/ivas_sns_enc_fx.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 9395fc6d4..c52efe14f 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -215,7 +215,7 @@ static Word16 sns_1st_cod_fx_q15( const Word16 *cdbk_ptr; Word16 j0, j1; Word16 dist_split; - Word64 dist_min_fx; + Word32 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; @@ -224,23 +224,26 @@ static Word16 sns_1st_cod_fx_q15( j1 = add( j0, split_len ); cdbk_ptr = cdbk; - dist_min_fx = 0x7fffffffffffffffull; + dist_min_fx = MAXVAL_WORD32; dist_split = 0; - move64(); + move32(); move16(); FOR( Word16 i = 0; i < 32; ++i ) { - Word64 dist_fx = 0; - move64(); + Word32 dist_fx = 0; + move32(); FOR( Word16 j = j0; j < j1; ++j ) { Word32 dist; Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); - dist_fx = W_mac_32_32( dist_fx, dist, dist ); + dist = L_shr( dist, 4 ); // TODO: Magic shift. + dist = L_mult( extract_l( dist ), extract_l( dist ) ); + dist = L_shr( dist, 4 ); // TODO: Magic shift + dist_fx = L_add( dist_fx, dist ); } - IF( LT_64( dist_fx, dist_min_fx ) ) + IF( LT_32( dist_fx, dist_min_fx ) ) { dist_min_fx = dist_fx; dist_split = i; -- GitLab From 5eea1e167939ee65d40b0d1d9628b5fffcba3809 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 10 Mar 2025 14:30:29 +0100 Subject: [PATCH 0356/1221] appl --- lib_enc/ivas_sns_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index c52efe14f..98c8f56c4 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -237,9 +237,9 @@ static Word16 sns_1st_cod_fx_q15( Word32 dist; Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); - dist = L_shr( dist, 4 ); // TODO: Magic shift. + dist = L_shr( dist, 4 ); // TODO: Magic shift. dist = L_mult( extract_l( dist ), extract_l( dist ) ); - dist = L_shr( dist, 4 ); // TODO: Magic shift + dist = L_shr( dist, 4 ); // TODO: Magic shift dist_fx = L_add( dist_fx, dist ); } -- GitLab From 78da1419bd4a7830326af0f61a20c884dbb2eb47 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 10 Mar 2025 15:11:47 +0100 Subject: [PATCH 0357/1221] apply the scalefac in some more places --- .gitlab-ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 15c944725..b53943d9e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -518,7 +518,7 @@ stages: - exit_code=0 - rm -rf .pytest_cache || true - - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $MERGE_TARGET_ENCODER_PATH --ref_decoder_path $MERGE_TARGET_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --ref_encoder_path $MERGE_TARGET_ENCODER_PATH --ref_decoder_path $MERGE_TARGET_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? - if [ $exit_code -ne 0 ]; then - exit_code=$EXIT_CODE_NON_BE @@ -661,7 +661,7 @@ stages: - make -j # need to restore cache again - *overwrite-pytest-cache-with-artifact - - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN $comp_args --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true - python3 scripts/parse_xml_report.py $XML_REPORT_MAIN $CSV_MAIN ### compare the two csv files for regressions @@ -799,10 +799,13 @@ stages: - fi - *build-float-ref-and-dut-binaries + - INV_LEVEL_SCALING=$(awk "BEGIN {print 1.0 / $LEVEL_SCALING}") + - comp_args="--mld --ssnr --odg --scalefac $INV_LEVEL_SCALING" + ### run pytest - exit_code=0 - - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report-ref.html --self-contained-html --junit-xml=report-junit-ref.xml --mld --ssnr --odg -n auto --testcase_timeout $testcase_timeout --dut_encoder_path $REF_ENCODER_PATH --dut_decoder_path $REF_DECODER_PATH --compare_to_input || exit_code=$? - - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report-dut.html --self-contained-html --junit-xml=report-junit-dut.xml --mld --ssnr --odg -n auto --testcase_timeout $testcase_timeout --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH --compare_to_input || exit_code=$? + - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report-ref.html --self-contained-html --junit-xml=report-junit-ref.xml $comp_args -n auto --testcase_timeout $testcase_timeout --dut_encoder_path $REF_ENCODER_PATH --dut_decoder_path $REF_DECODER_PATH --compare_to_input || exit_code=$? + - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report-dut.html --self-contained-html --junit-xml=report-junit-dut.xml $comp_args -n auto --testcase_timeout $testcase_timeout --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH --compare_to_input || exit_code=$? - zero_errors_ref=$(cat report-junit-ref.xml | grep -c 'errors="0"') || true - zero_errors_dut=$(cat report-junit-dut.xml | grep -c 'errors="0"') || true - python3 scripts/parse_xml_report.py report-junit-ref.xml report-ref.csv -- GitLab From e5668dda7f0ab8d18636164edf0451e1a6c9f798 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 09:30:57 +0530 Subject: [PATCH 0358/1221] Fix for 3GPP issue 1345: Decoder crash for Stereo at 32kbps in stereo_dft_dec_res_fx() Link #1345 --- lib_dec/ivas_stereo_dft_dec_fx.c | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 8dcc7ada9..fb54476fa 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1368,23 +1368,23 @@ void stereo_dft_dec_res_fx( /*Inverse MDCT*/ TCX_MDCT_Inverse( res_buf, q_res, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + scale_sig( win, L_FRAME8k + STEREO_DFT_OVL_8k, -1 ); + + Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); IF( !prev_bfi ) { /*OLA*/ /*overlapping parts*/ - Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); + FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( L_add( hCPE->hStereoDft->res_cod_mem_fx[i], L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx */ + win[i] = extract_h( L_add( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx -17 (q_shift -1)*/ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* q_res_cod_mem_fx */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* -1 +15 +1 +1 */ move32(); } - IF( q_shift != 0 ) - { - v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); - } - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + + move16(); } ELSE @@ -1396,23 +1396,30 @@ void stereo_dft_dec_res_fx( move16(); FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( Madd_32_16( Mpy_32_16_1( hCPE->hStereoDft->res_cod_mem_fx[i], sub( MAX_16, mult( fac, fac ) ) ), - L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), - sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q0 */ + win[i] = extract_h( Madd_32_16( Mpy_32_16_1( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), sub( MAX_16, mult( fac, fac ) ) ), + L_shl( L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), q_shift ), + sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q(q_shift -1) */ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* Q16 */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* Q16 */ move32(); fac = add( fac, step ); } } - Copy( win, out_16, L_FRAME8k ); /* Q0 */ + IF( q_shift != 0 ) + { + v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); + } + + hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + + Copy( win, out_16, L_FRAME8k ); /* Q(q_shift -1 ) */ IF( hCPE->hCoreCoder[0]->core == ACELP_CORE ) { /* bass post-filter */ bass_psfilter_fx( hCPE->hStereoDft->hBpf, hCPE->hCoreCoder[0]->Opt_AMR_WB, out_16, L_FRAME8k, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx + ( L_FRAME8k / STEREO_DFT_L_SUBFR_8k ), hCPE->hCoreCoder[0]->bpf_off, - hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, 0, bpf_error_signal_8k_16 ); + hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, sub( q_shift, 1 ), bpf_error_signal_8k_16 ); Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_8k_16, bpf_error_signal_8k, L_FRAME8k, Q15 ); /* Q15 */ res_bpf_flag = res_bpf_adapt_ivas_fx( hCPE->hStereoDft, bpf_error_signal_8k, res_buf, q_res ); @@ -1430,7 +1437,7 @@ void stereo_dft_dec_res_fx( } } #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, 15 ); /* Q15 */ + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ #else Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ #endif @@ -1445,7 +1452,7 @@ void stereo_dft_dec_res_fx( hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, 15 ); /* Q15 */ + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ #else Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ #endif @@ -1454,7 +1461,7 @@ void stereo_dft_dec_res_fx( { /* This step is needed to ensure output is properly populated with scaled values in all cases*/ #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, 15 ); /* Q15 */ + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ #else Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ #endif -- GitLab From f934b4d2d794ed257ff77f5cffff9ec1e6ebd66e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 09:48:48 +0530 Subject: [PATCH 0359/1221] Fix for 3GPP issue 1037: Wrong variable type used in the fixed-point code - 1 Link #1037 --- lib_com/cng_exc_fx.c | 2 +- lib_com/cnst.h | 6 +- lib_com/common_api_types.h | 50 +- lib_com/fft_evs.c | 2 +- lib_com/ivas_cnst.h | 10 +- lib_com/ivas_rom_com_fx.c | 24 +- lib_com/ivas_spar_com_fx.c | 8 +- lib_com/ivas_stat_com.h | 250 +++---- lib_com/ivas_tools_fx.c | 6 +- lib_com/longarith.c | 44 +- lib_com/lsf_dec_bfi_fx.c | 2 +- lib_com/mslvq_com.c | 6 +- lib_com/parameter_bitmaping_fx.c | 26 +- lib_com/prot_fx.h | 6 +- lib_com/rom_basop_util.c | 2 +- lib_com/rom_com.h | 2 +- lib_com/stat_com.h | 13 +- lib_dec/FEC_clas_estim_fx.c | 2 +- lib_dec/acelp_core_switch_dec_fx.c | 1 - lib_dec/core_switching_dec_fx.c | 2 +- lib_dec/dec_uv_fx.c | 22 +- lib_dec/er_dec_acelp_fx.c | 2 +- lib_dec/ivas_binRenderer_internal_fx.c | 4 +- lib_dec/ivas_dirac_dec_fx.c | 2 +- lib_dec/ivas_ism_param_dec_fx.c | 6 +- lib_dec/ivas_jbm_dec_fx.c | 26 +- lib_dec/ivas_mc_param_dec_fx.c | 10 +- lib_dec/ivas_rom_dec.c | 44 +- lib_dec/ivas_rom_dec.h | 16 +- lib_dec/ivas_spar_md_dec_fx.c | 10 +- lib_dec/ivas_stat_dec.h | 524 +++++++-------- lib_dec/ivas_stereo_switching_dec_fx.c | 8 +- lib_dec/ivas_svd_dec_fx.c | 1 - lib_dec/jbm_jb4sb.h | 2 +- lib_dec/jbm_pcmdsp_apa.h | 8 +- lib_dec/jbm_pcmdsp_window.h | 2 +- lib_enc/amr_wb_enc_fx.c | 2 +- lib_enc/avq_cod_fx.c | 12 +- lib_enc/core_enc_init_fx.c | 8 +- lib_enc/core_enc_reconf_fx.c | 2 +- lib_enc/enc_acelp_fx.c | 4 +- lib_enc/ivas_ism_metadata_enc_fx.c | 2 +- lib_enc/ivas_mcmasa_enc_fx.c | 2 +- lib_enc/ivas_mct_enc_fx.c | 2 +- lib_enc/ivas_mdct_core_enc_fx.c | 2 +- lib_enc/ivas_qmetadata_enc_fx.c | 6 +- lib_enc/ivas_sns_enc_fx.c | 10 +- lib_enc/ivas_spar_md_enc_fx.c | 2 +- lib_enc/ivas_stereo_dft_enc_fx.c | 6 +- lib_enc/ivas_stereo_td_enc_fx.c | 3 +- lib_enc/lib_enc.c | 64 +- lib_enc/lib_enc.h | 64 +- lib_enc/lsf_enc_fx.c | 4 +- lib_enc/lsf_msvq_ma_enc.c | 2 +- lib_enc/prot_fx_enc.h | 24 +- lib_enc/stat_enc.h | 624 +++++++++--------- lib_enc/swb_bwe_enc_fx.c | 2 +- lib_enc/swb_pre_proc_fx.c | 2 +- lib_enc/tcx_utils_enc_fx.c | 6 +- lib_enc/transient_detection_fx.c | 6 +- .../ivas_dirac_dec_binaural_functions_fx.c | 22 +- lib_rend/ivas_dirac_decorr_dec_fx.c | 4 +- lib_rend/ivas_reverb_fx.c | 32 +- lib_rend/ivas_rom_binaural_crend_head.h | 180 ++--- lib_rend/ivas_rom_binaural_crend_head_fx.c | 180 ++--- lib_rend/ivas_rom_rend_fx.c | 20 +- lib_rend/lib_rend.h | 2 +- 67 files changed, 1215 insertions(+), 1237 deletions(-) diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index 3eab0b1f5..4153afa32 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -47,7 +47,7 @@ void CNG_exc_fx( Word16 *cng_ener_seed1, Word16 exc3[], /*Q_exc*/ Word16 Opt_AMR_WB, - const int16_t element_mode /* i : IVAS Element mode */ + const Word16 element_mode /* i : IVAS Element mode */ ) { Word16 i, tmp, tmp2, exp, exp2, Q_ener; diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 87aafb11a..7c93498af 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -239,7 +239,7 @@ enum{ #define L_FRAME48k_EXT 1200 /* Extended MDCT frame size in samples at 48kHz */ /* Conversion of ns to samples for a given sampling frequency */ -#define NS2SA( fs, x ) ( int16_t )( ( ( ( int32_t )( fs ) / 100L ) * ( ( x ) / 100L ) ) / 100000L ) +#define NS2SA( fs, x ) ( Word16 )( ( ( ( Word32 )( fs ) / 100L ) * ( ( x ) / 100L ) ) / 100000L ) #define NRG_CHANGE_E 8 #define AVG_FLAT_E 8 #define ACTIVE_FRAME 0xFF @@ -1172,7 +1172,6 @@ enum #define NBITS_NOISE_FILL_LEVEL 3 /* Number of bits used for coding noise filling level for each range */ #define NF_GAIN_BITS ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ) #define MIN_NOISE_FILLING_HOLE 8 -#define HOLE_SIZE_FROM_LTP_FLT( gain ) ( 4 + ( int16_t )( 2.0f * gain * ( 4.0f / 0.625f ) ) ) #define HOLE_SIZE_FROM_LTP( gain ) (add(4, extract_h(L_shr(L_mult0(gain, 0x6666), 10)))) /* gain (Q15), 0x6666 = 2.0*(4.0/0.625) (4Q11) */ #define HOLE_SIZE_FROM_LTP32( gain ) (add(4, extract_h(L_shr(Mpy_32_32(gain, 0x66666667), 11)))) /* gain (Q31), 0x66666667 = 2.0*(4.0/0.625) (4Q27) */ @@ -1469,7 +1468,7 @@ enum #define cbitsnew 16 #define stat_bitsnew 14 -#define ari_q4new ( ( (int32_t) 1 << cbitsnew ) - 1 ) +#define ari_q4new ( ( (Word32) 1 << cbitsnew ) - 1 ) #define ari_q1new ( ari_q4new / 4 + 1 ) #define ari_q2new ( 2 * ari_q1new ) #define ari_q3new ( 3 * ari_q1new ) @@ -1951,7 +1950,6 @@ typedef enum _DCTTYPE #define N_SMC_MIXTURES 6 /* number of mixtures */ #define N_PCA_COEF 12 /* number of PCA components */ #define HALF_N_PCA_COEF_LOG_P12_Q18 2890731 //Q18 of (0.5f * N_PCA_COEF *logf( PI2 )) -#define SMC_ST_MEAN_FACT 0.5 /* forgetting factor of short-term IIR mean filter */ #define SMC_ST_MEAN_RSHIFT_FACT_FX 1 /* SMC_ST_MEAN_FACT equivalent right shift factor */ #define M_LSP_SPMUS 6 /* number of LSPs used in speech/music classifier */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 553a34f56..bc6fd4f1a 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -108,9 +108,9 @@ typedef enum _IVAS_ENC_FEC_INDICATOR typedef struct _IVAS_ENC_CHANNEL_AWARE_CONFIG { - int16_t channelAwareModeEnabled; + Word16 channelAwareModeEnabled; IVAS_ENC_FEC_INDICATOR fec_indicator; - int16_t fec_offset; + Word16 fec_offset; } IVAS_ENC_CHANNEL_AWARE_CONFIG; @@ -130,7 +130,7 @@ typedef struct _IVAS_ISM_METADATA float gainFactor; float yaw; float pitch; - int16_t non_diegetic_flag; + Word16 non_diegetic_flag; } IVAS_ISM_METADATA; @@ -183,29 +183,29 @@ typedef struct ivas_LS_setup_custom IVAS_LSSETUP_CUSTOM_STRUCT; typedef struct _IVAS_LS_CUSTOM_LAYOUT { - int16_t num_spk; + Word16 num_spk; float azimuth[IVAS_MAX_OUTPUT_CHANNELS]; float elevation[IVAS_MAX_OUTPUT_CHANNELS]; Word32 azimuth_fx[IVAS_MAX_OUTPUT_CHANNELS]; // Q22 Word32 elevation_fx[IVAS_MAX_OUTPUT_CHANNELS]; // Q22 - int16_t num_lfe; - int16_t lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; + Word16 num_lfe; + Word16 lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; } IVAS_CUSTOM_LS_DATA; typedef struct _IVAS_JBM_TRACE_DATA { - uint32_t systemTimestamp_ms; - uint16_t extBufferedSamples; - uint16_t lastDecodedWasActive; - int32_t output_Fs; - int16_t dataUnit_flag; - uint16_t sequenceNumber; - uint32_t timeStamp; - uint32_t rcvTime; - - int16_t partial_frame; - int16_t partialCopyOffset; + UWord32 systemTimestamp_ms; + UWord16 extBufferedSamples; + UWord16 lastDecodedWasActive; + Word32 output_Fs; + Word16 dataUnit_flag; + UWord16 sequenceNumber; + UWord32 timeStamp; + UWord32 rcvTime; + + Word16 partial_frame; + Word16 partialCopyOffset; } IVAS_JBM_TRACE_DATA; @@ -217,8 +217,8 @@ typedef struct _IVAS_JBM_TRACE_DATA typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { - int16_t override; - int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ + Word16 override; + Word16 nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ float pAcoustic_rt60[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ float pAcoustic_dsr[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's Diffuse to Source Ratio per center frequency */ @@ -231,12 +231,12 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG Word32 inputPreDelay_fx; /* Offset in seconds from where DSR is computed in the RIR (0 = at source), float, range [0.001..10] */ /* Assumed Q-27*/ /* early reflections */ - int16_t use_er; /* ER activation flag */ - int32_t lowComplexity; /* Low complexity ER flag */ - IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ - float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ - IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ - int32_t AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ + Word16 use_er; /* ER activation flag */ + Word32 lowComplexity; /* Low complexity ER flag */ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ + IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ + Word32 AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ } IVAS_ROOM_ACOUSTICS_CONFIG_DATA; diff --git a/lib_com/fft_evs.c b/lib_com/fft_evs.c index e53404f0b..94c2dea8f 100644 --- a/lib_com/fft_evs.c +++ b/lib_com/fft_evs.c @@ -505,7 +505,7 @@ static void fft15_with_cmplx_data( cmplx *inp_data /*Qx*/ ) */ void fft16( Word32 *re, Word32 *im, Word16 s, Word16 bScale ) { - int i; + Word16 i; if ( s == 2 ) { fft16_with_cmplx_data( (cmplx *) re, bScale ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 6612fac1f..2abb790f1 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1440,12 +1440,12 @@ typedef enum _COV_SMOOTHING_TYPE } COV_SMOOTHING_TYPE; typedef struct { - const int32_t *value; - const uint16_t *length; + const Word32 *value; + const UWord16 *length; } HUFF_TAB; typedef struct { - int32_t value[81]; + Word32 value[81]; unsigned short length[81]; } HUFF_ELEMENTS; @@ -1467,8 +1467,8 @@ typedef struct { typedef struct { - const int16_t (*alpha)[2]; - const int16_t (*beta)[2]; + const Word16 (*alpha)[2]; + const Word16 (*beta)[2]; } HUFF_NODE_TABLE; /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index 8ea2b91e4..a7a8bdcbf 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1617,23 +1617,23 @@ const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBAND }; /* Multi-channel input and output setups */ -const int16_t ls_azimuth_CICP2_idx[2] = { 1, 2 }; -const int16_t ls_elevation_CICP2_idx[2] = { 0, 0 }; +const Word16 ls_azimuth_CICP2_idx[2] = { 1, 2 }; +const Word16 ls_elevation_CICP2_idx[2] = { 0, 0 }; -const int16_t ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; -const int16_t ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; +const Word16 ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; +const Word16 ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; -const int16_t ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; -const int16_t ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; +const Word16 ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; +const Word16 ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; -const int16_t ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; -const int16_t ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; +const Word16 ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; +const Word16 ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; -const int16_t ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; -const int16_t ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; +const Word16 ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; +const Word16 ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; -const int16_t ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; -const int16_t ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; +const Word16 ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; +const Word16 ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; const Word32 shoebox_sin_cos_tbl_fx[11][2] = { { 0, 1073741824 }, // 0 { 536870912, 929887680 }, diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 6c80c1898..96df64aa5 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -3807,7 +3807,7 @@ void ivas_compute_spar_params_fx( { Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - Word16 b, i, ndm; + Word16 b, i, ndm, j; Word16 q_pred_coeffs; ivas_get_pred_coeffs_fx( cov_real, pred_coeffs_re, dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, dtx_vad, from_dirac, dyn_active_w_flag, hSparMd->res_ind, &q_pred_coeffs, q_dm_fv_re ); @@ -3869,7 +3869,7 @@ void ivas_compute_spar_params_fx( #ifdef MSAN_FIX FOR( i = 0; i < ( num_ch - ndm ); i++ ) { - FOR( Word16 j = 0; j < sub( ndm, 1 ); j++ ) + FOR( j = 0; j < sub( ndm, 1 ); j++ ) { hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j], sub( q_tmp, 22 ) ); // q22 move32(); @@ -3878,7 +3878,7 @@ void ivas_compute_spar_params_fx( #else for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) { - for ( int j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) + for ( j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) { hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j], sub( q_tmp, 22 ) ); } @@ -3891,7 +3891,7 @@ void ivas_compute_spar_params_fx( q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx; move16(); - FOR( Word16 j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ ) + FOR( j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ ) { hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j], sub( q_tmp, 22 ) ); // q22 move32(); diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 249d1e963..fb11d3934 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -46,18 +46,18 @@ typedef struct { - int16_t last_angle1_idx; /* last frame index of coded azimuth/yaw */ - int16_t angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ - int16_t last_angle2_idx; /* last frame index of coded elevation/pitch */ - int16_t angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ + Word16 last_angle1_idx; /* last frame index of coded azimuth/yaw */ + Word16 angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ + Word16 last_angle2_idx; /* last frame index of coded elevation/pitch */ + Word16 angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ } ISM_METADATA_ANGLE, *ISM_METADATA_ANGLE_HANDLE; /* ISM metadata handle (storage for one frame of read ISM metadata) */ typedef struct { - int16_t ism_metadata_flag; /* flag whether metadata are coded in particular frame of particular object */ - int16_t last_ism_metadata_flag; /* last frame ism_metadata_flag */ + Word16 ism_metadata_flag; /* flag whether metadata are coded in particular frame of particular object */ + Word16 last_ism_metadata_flag; /* last frame ism_metadata_flag */ Word32 azimuth_fx; /* azimuth value read from the input metadata file */ /* Q22 */ Word32 elevation_fx; /* elevation value read from the input metadata file */ /* Q22 */ @@ -65,25 +65,25 @@ typedef struct Word32 yaw_fx; /* yaw value read from the input metadata file */ /* Q22 */ Word32 pitch_fx; /* pitch value read from the input metadata file */ /* Q22 */ - int16_t non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ + Word16 non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ ISM_METADATA_ANGLE position_angle; /* Angle structs for azimuth and elevation */ ISM_METADATA_ANGLE orientation_angle; /* Angle structs for yaw and pitch */ - int16_t last_radius_idx; /* last frame index of coded radius */ - int16_t radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ + Word16 last_radius_idx; /* last frame index of coded radius */ + Word16 radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ Word32 last_azimuth_fx; /* MD smoothing in DTX- last Q azimuth value */ /* Q22 */ Word32 last_elevation_fx; /* MD smoothing in DTX - last Q elevation value */ /* Q22 */ Word32 last_true_azimuth_fx; /* MD smoothing in DTX- last true Q azimuth value */ /* Q22 */ Word32 last_true_elevation_fx; /* MD smoothing in DTX- last true Q elevation value */ /* Q22 */ - int16_t ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ - int16_t ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ - Word16 last_true_radius_fx; /* last true Q radius value */ + Word16 ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ + Word16 ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ + Word16 last_true_radius_fx; /* last true Q radius value */ - int16_t ism_imp; /* ISM importance flag */ - int16_t ism_md_null_flag; - int16_t ism_md_lowrate_flag; + Word16 ism_imp; /* ISM importance flag */ + Word16 ism_md_null_flag; + Word16 ism_md_lowrate_flag; Word32 q_azimuth_old_fx; Word32 q_elevation_old_fx; @@ -96,15 +96,15 @@ typedef struct typedef struct stereo_dft_config_data_struct { - int16_t dmx_active; - int16_t band_res; - int16_t prm_res; /* Send prm every # DFT frames */ - int16_t res_pred_mode; /* mode : from 0 (off) to 1 (on) */ - int16_t res_cod_mode; /* mode : from 0 (off) to 3 */ - int16_t hybrid_itd_flag; - int16_t ada_wb_res_cod_mode; /* res_cod_mode for adaptive wide band residual coding */ + Word16 dmx_active; + Word16 band_res; + Word16 prm_res; /* Send prm every # DFT frames */ + Word16 res_pred_mode; /* mode : from 0 (off) to 1 (on) */ + Word16 res_cod_mode; /* mode : from 0 (off) to 3 */ + Word16 hybrid_itd_flag; + Word16 ada_wb_res_cod_mode; /* res_cod_mode for adaptive wide band residual coding */ - int16_t force_mono_transmission; + Word16 force_mono_transmission; } STEREO_DFT_CONFIG_DATA, *STEREO_DFT_CONFIG_DATA_HANDLE; @@ -115,20 +115,20 @@ typedef struct stereo_dft_config_data_struct typedef struct { - uint8_t const bandLengthsTCX20[SMDCT_MAX_STEREO_BANDS_TCX20]; /* Length of a band in number of bins. Range is 4..160 */ - const int16_t bdnCnt_TCX20[4]; /* uppermost band for FB,SWB,WB,NB */ - uint8_t const bandLengthsTCX10[SMDCT_MAX_STEREO_BANDS_TCX10]; /* Length of a band in number of bins. Range is 2..80, always divisible by 2 */ - const int16_t bndCnt_TCX10[4]; /* uppermost band for FB,SWB,WB,NB */ + UWord8 const bandLengthsTCX20[SMDCT_MAX_STEREO_BANDS_TCX20]; /* Length of a band in number of bins. Range is 4..160 */ + const Word16 bdnCnt_TCX20[4]; /* uppermost band for FB,SWB,WB,NB */ + UWord8 const bandLengthsTCX10[SMDCT_MAX_STEREO_BANDS_TCX10]; /* Length of a band in number of bins. Range is 2..80, always divisible by 2 */ + const Word16 bndCnt_TCX10[4]; /* uppermost band for FB,SWB,WB,NB */ } MDCTStereoBands_config; /* MDCT stereo frequency band structure */ typedef struct stereo_mdct_dec_band_parameters_struct { - int16_t sfbOffset[MAX_SFB + 1]; /* stereo frequency band start offsets */ - int16_t sfbCnt; /* number of stereo frequency bands */ - int16_t nBandsStereoCore; /* number of stereo frequency bands in the core */ - int16_t sfbIgfStart; /*index for first IGF band*/ + Word16 sfbOffset[MAX_SFB + 1]; /* stereo frequency band start offsets */ + Word16 sfbCnt; /* number of stereo frequency bands */ + Word16 nBandsStereoCore; /* number of stereo frequency bands in the core */ + Word16 sfbIgfStart; /*index for first IGF band*/ } STEREO_MDCT_BAND_PARAMETERS; @@ -139,9 +139,9 @@ typedef struct stereo_mdct_dec_band_parameters_struct typedef struct { - int16_t config_index; - int16_t encoding_active; /* internal state specifying if actual encoding is active or only length evaluation is active */ - int32_t bit_count_estimate; /* uses 22Q10 fixed-point representation */ + Word16 config_index; + Word16 encoding_active; /* internal state specifying if actual encoding is active or only length evaluation is active */ + Word32 bit_count_estimate; /* uses 22Q10 fixed-point representation */ void *ac_handle; } ECSQ_instance; @@ -153,9 +153,9 @@ typedef struct typedef struct ivas_dirac_config_data_struct { - int16_t enc_param_start_band; - int16_t dec_param_estim; - int16_t nbands; + Word16 enc_param_start_band; + Word16 dec_param_estim; + Word16 nbands; } DIRAC_CONFIG_DATA, *DIRAC_CONFIG_DATA_HANDLE; @@ -180,9 +180,9 @@ typedef struct ivas_band_coeffs_t typedef struct ivas_band_coeffs_ind_t { - int16_t pred_index_re[IVAS_SPAR_MAX_CH - 1]; - int16_t drct_index_re[IVAS_SPAR_MAX_C_COEFF]; - int16_t decd_index_re[IVAS_SPAR_MAX_CH - 1]; + Word16 pred_index_re[IVAS_SPAR_MAX_CH - 1]; + Word16 drct_index_re[IVAS_SPAR_MAX_C_COEFF]; + Word16 decd_index_re[IVAS_SPAR_MAX_CH - 1]; } ivas_band_coeffs_ind_t; @@ -192,7 +192,7 @@ typedef struct ivas_spar_md_t ivas_band_coeffs_ind_t band_coeffs_idx[IVAS_MAX_NUM_BANDS]; Word16 num_bands; Word32 min_max_fx[2]; /*q28*/ - int16_t dtx_vad; + Word16 dtx_vad; Word32 en_ratio_slow_fx[IVAS_MAX_NUM_BANDS]; Word32 ref_pow_slow_fx[IVAS_MAX_NUM_BANDS]; Word16 res_ind; @@ -210,7 +210,7 @@ typedef struct ivas_quant_coeffs_t { Word32 min_fx; /* Q28 */ Word32 max_fx; /* Q28 */ - int16_t q_levels[2]; + Word16 q_levels[2]; } ivas_quant_coeffs_t; typedef struct ivas_quant_strat_t @@ -224,23 +224,23 @@ typedef struct ivas_quant_strat_t typedef struct ivas_spar_md_com_cfg { - int16_t max_freq_per_chan[IVAS_SPAR_MAX_CH]; - int16_t num_dmx_chans_per_band[IVAS_MAX_NUM_BANDS]; - int16_t num_decorr_per_band[IVAS_MAX_NUM_BANDS]; - int16_t active_w; - int16_t remix_unmix_order; + Word16 max_freq_per_chan[IVAS_SPAR_MAX_CH]; + Word16 num_dmx_chans_per_band[IVAS_MAX_NUM_BANDS]; + Word16 num_decorr_per_band[IVAS_MAX_NUM_BANDS]; + Word16 active_w; + Word16 remix_unmix_order; ivas_quant_strat_t quant_strat[MAX_QUANT_STRATS]; - int16_t quant_strat_bits; - int16_t nchan_transport; - int16_t num_quant_strats; - int16_t prior_strat; - int16_t tgt_bits_per_blk; - int16_t max_bits_per_blk; - int16_t prev_quant_idx; - int16_t agc_bits_ch_idx; - int16_t planarCP; - int16_t num_umx_chs; - int16_t max_md_bits_spar; + Word16 quant_strat_bits; + Word16 nchan_transport; + Word16 num_quant_strats; + Word16 prior_strat; + Word16 tgt_bits_per_blk; + Word16 max_bits_per_blk; + Word16 prev_quant_idx; + Word16 agc_bits_ch_idx; + Word16 planarCP; + Word16 num_umx_chs; + Word16 max_md_bits_spar; } ivas_spar_md_com_cfg; @@ -248,26 +248,26 @@ typedef struct ivas_spar_md_com_cfg /* arithmetic coder structures */ typedef struct ivas_cell_dim_t { - int16_t dim1; - int16_t dim2; + Word16 dim1; + Word16 dim2; } ivas_cell_dim_t; typedef struct ivas_freq_models_t { - int16_t freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t diff_freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t vals[IVAS_MAX_QUANT_LEVELS]; - int16_t diff_vals[IVAS_MAX_QUANT_LEVELS]; - int16_t num_models; - int16_t diff_num_models; + Word16 freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 diff_freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 vals[IVAS_MAX_QUANT_LEVELS]; + Word16 diff_vals[IVAS_MAX_QUANT_LEVELS]; + Word16 num_models; + Word16 diff_num_models; } ivas_freq_models_t; typedef struct ivas_huff_models_t { - int16_t code_book[IVAS_MAX_QUANT_LEVELS][3]; - int16_t diff_code_book[IVAS_MAX_QUANT_LEVELS][3]; + Word16 code_book[IVAS_MAX_QUANT_LEVELS][3]; + Word16 diff_code_book[IVAS_MAX_QUANT_LEVELS][3]; } ivas_huff_models_t; @@ -275,22 +275,22 @@ typedef struct ivas_huff_models_t /* Entropy coder structures */ typedef struct ivas_huffman_cfg_t { - const int16_t *codebook; - int16_t min_len; - int16_t max_len; - int16_t sym_len; + const Word16 *codebook; + Word16 min_len; + Word16 max_len; + Word16 sym_len; } ivas_huffman_cfg_t; typedef struct ivas_arith_t { - int16_t dyn_model_bits; - const int16_t *pFreq_model; - const int16_t *pAlt_freq_models[IVAS_NUM_PROB_MODELS]; - const int16_t *vals; - int16_t cum_freq[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t range; - int16_t num_models; + Word16 dyn_model_bits; + const Word16 *pFreq_model; + const Word16 *pAlt_freq_models[IVAS_NUM_PROB_MODELS]; + const Word16 *vals; + Word16 cum_freq[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 range; + Word16 num_models; Word32 saved_dist_arr[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; /* Q15 */ } ivas_arith_t; @@ -338,18 +338,18 @@ typedef struct ivas_cov_smooth_state_t Word32 *pPrior_cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_prior_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - int16_t prior_bank_idx; + Word16 prior_bank_idx; Word32 *pSmoothing_factor_fx; /* Q31 */ - int16_t num_bins; + Word16 num_bins; } ivas_cov_smooth_state_t; typedef struct ivas_cov_smooth_cfg_t { Word32 max_update_rate_fx; /* Q31 */ - int16_t min_pool_size; - int16_t max_bands; - int16_t num_bins; + Word16 min_pool_size; + Word16 max_bands; + Word16 num_bins; } ivas_cov_smooth_cfg_t; @@ -357,20 +357,20 @@ typedef struct ivas_cov_smooth_cfg_t /* SPAR bitrate constant table structure */ typedef struct ivas_spar_br_table_t { - int32_t ivas_total_brate; - int16_t isPlanar; - int16_t sba_order; - int16_t bwidth; - int16_t fpcs; - int16_t nchan_transport; + Word32 ivas_total_brate; + Word16 isPlanar; + Word16 sba_order; + Word16 bwidth; + Word16 fpcs; + Word16 nchan_transport; ivas_spar_pmx_strings_t dmx_str; - int16_t active_w; - int16_t tmode; - int32_t core_brs[FOA_CHANNELS][3]; - int16_t q_lvls[MAX_QUANT_STRATS][NUM_MD_Q_COEFS_SET]; - int16_t td_ducking; - int16_t agc_bits_ch_idx; /* 0-3, Indicates core-coder channel index from which AGC bits have been taken from*/ - int16_t usePlanarCoeff; + Word16 active_w; + Word16 tmode; + Word32 core_brs[FOA_CHANNELS][3]; + Word16 q_lvls[MAX_QUANT_STRATS][NUM_MD_Q_COEFS_SET]; + Word16 td_ducking; + Word16 agc_bits_ch_idx; /* 0-3, Indicates core-coder channel index from which AGC bits have been taken from*/ + Word16 usePlanarCoeff; } ivas_spar_br_table_t; @@ -419,7 +419,7 @@ typedef struct ivas_masa_common_spatial_meta_struct typedef struct ivas_omasa_meta_struct { - uint8_t num_dirs; + UWord8 num_dirs; MASA_DIRECTIONAL_SPATIAL_META directional_meta[MASA_MAXIMUM_DIRECTIONS]; MASA_COMMON_SPATIAL_META common_meta; @@ -435,16 +435,16 @@ typedef struct ivas_masa_metadata_frame_struct typedef struct ivas_masa_config_struct { - uint16_t max_metadata_bits; - int16_t block_grouping[5]; - int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; - uint8_t numCodingBands; - uint8_t numTwoDirBands; - uint8_t numberOfDirections; - uint8_t joinedSubframes; - uint8_t useCoherence; - uint8_t coherencePresent; - uint8_t mergeRatiosOverSubframes; + UWord16 max_metadata_bits; + Word16 block_grouping[5]; + Word16 band_grouping[MASA_FREQUENCY_BANDS + 1]; + UWord8 numCodingBands; + UWord8 numTwoDirBands; + UWord8 numberOfDirections; + UWord8 joinedSubframes; + UWord8 useCoherence; + UWord8 coherencePresent; + UWord8 mergeRatiosOverSubframes; IVAS_FORMAT input_ivas_format; } MASA_CODEC_CONFIG; @@ -456,11 +456,11 @@ typedef struct ivas_masa_config_struct typedef struct { - int16_t nbands; - int16_t nblocks; - int16_t start_band; - uint8_t inactiveBands; - int16_t search_effort; + Word16 nbands; + Word16 nblocks; + Word16 start_band; + UWord8 inactiveBands; + Word16 search_effort; MC_LS_SETUP mc_ls_setup; } IVAS_METADATA_CONFIG; @@ -615,10 +615,10 @@ typedef struct ivas_parametric_mc_metadata_struct typedef struct ivas_lfe_window { - int16_t dct_len; - int16_t fade_len; - int16_t zero_pad_len; - int16_t full_len; + Word16 dct_len; + Word16 fade_len; + Word16 zero_pad_len; + Word16 full_len; const Word32 *pWindow_coeffs_fx; @@ -626,14 +626,14 @@ typedef struct ivas_lfe_window typedef struct ivas_lfe_freq_models { - uint16_t entropy_coder_model_fine_sg1[65]; - uint16_t entropy_coder_model_fine_sg2[33]; - uint16_t entropy_coder_model_fine_sg3[9]; - uint16_t entropy_coder_model_fine_sg4[3]; - uint16_t entropy_coder_model_coarse_sg1[33]; - uint16_t entropy_coder_model_coarse_sg2[17]; - uint16_t entropy_coder_model_coarse_sg3[5]; - uint16_t entropy_coder_model_coarse_sg4; + UWord16 entropy_coder_model_fine_sg1[65]; + UWord16 entropy_coder_model_fine_sg2[33]; + UWord16 entropy_coder_model_fine_sg3[9]; + UWord16 entropy_coder_model_fine_sg4[3]; + UWord16 entropy_coder_model_coarse_sg1[33]; + UWord16 entropy_coder_model_coarse_sg2[17]; + UWord16 entropy_coder_model_coarse_sg3[5]; + UWord16 entropy_coder_model_coarse_sg4; } ivas_lfe_freq_models; diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index e460637f7..e15db9a15 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -2970,7 +2970,7 @@ Word64 var_32_fx( Word16 q /* q : q-factor for the array */ ) { - + Word16 i; Word64 mean, var; mean = 0; @@ -2978,14 +2978,14 @@ Word64 var_32_fx( var = 0; move64(); - FOR( int i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { mean = W_add( mean, x[i] ); /*q*/ } mean = mean / len; /* NOTE: No BASOP for 64 bit division q*/ - FOR( int i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { var = W_add( var, Mpy_32_32( L_sub( x[i], W_extract_l( mean ) ), L_sub( x[i], W_extract_l( mean ) ) ) ); /*q + q - 31*/ } diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 8946e41aa..72a763de3 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -52,27 +52,27 @@ *--------------------------------------------------------------------*/ void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ + UWord16 a[], /* i/o: vector of the length lena */ + const UWord16 b[], /* i/o: vector of the length lenb */ + const Word16 lena, /* i/o: length of vector a[] */ + const Word16 lenb /* i/o: length of vector b[] */ ) { - int16_t h; - int32_t carry = 0; + Word16 h; + Word32 carry = 0; assert( lena >= lenb ); for ( h = 0; h < lenb; h++ ) { carry += ( (uint32_t) a[h] ) + ( (uint32_t) b[h] ); - a[h] = (uint16_t) carry; + a[h] = (UWord16) carry; carry = carry >> 16; } for ( ; h < lena; h++ ) { carry = ( (uint32_t) a[h] ) + carry; - a[h] = (uint16_t) carry; + a[h] = (UWord16) carry; carry = carry >> 16; } @@ -91,14 +91,14 @@ void longadd( *--------------------------------------------------------------------*/ void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ + UWord16 a[], /* i : vector of the length lena */ + const Word16 b, /* i : number of bit positions to shift right */ + UWord16 d[], /* o : vector of the length lend */ + Word16 lena, /* i : length of vector a[] */ + const Word16 lend /* i : length of vector d[] */ ) { - int16_t intb, fracb, fracb_u, k; + Word16 intb, fracb, fracb_u, k; intb = b >> 4; @@ -164,16 +164,16 @@ void longshr( *--------------------------------------------------------------------*/ void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ + const UWord16 a[], /* i : vector of the length len */ + const Word16 b, /* i : number of bit positions to shift left */ + UWord16 d[], /* o : vector of the length len */ + const Word16 len /* i : length of vector a[] and d[] */ ) { - int16_t intb; /* integer part of b */ - int16_t fracb; /* shift left value for all upper words a[k] */ - int16_t fracb_l; /* shift right value for all lower words a[k-1] */ - int16_t k = len - 1; + Word16 intb; /* integer part of b */ + Word16 fracb; /* shift left value for all upper words a[k] */ + Word16 fracb_l; /* shift right value for all lower words a[k-1] */ + Word16 k = len - 1; intb = b >> 4; fracb = b & 0xF; diff --git a/lib_com/lsf_dec_bfi_fx.c b/lib_com/lsf_dec_bfi_fx.c index 6292630af..33de5d9ac 100644 --- a/lib_com/lsf_dec_bfi_fx.c +++ b/lib_com/lsf_dec_bfi_fx.c @@ -36,7 +36,7 @@ void lsf_dec_bfi( const Word16 Last_GSC_pit_band_idx, const Word16 Opt_AMR_WB, /* i : IO flag */ const Word8 tcxonly, - const short bwidth /* i: coded bandwidth */ + const Word16 bwidth /* i: coded bandwidth */ ) { Word16 i; diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index a15b11611..6bd8026c4 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -75,10 +75,10 @@ static void make_offset_scale( void create_offset( UWord32 *offset_scale1, UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ) + const Word16 mode, + const Word16 prediction_flag ) { - int16_t tmp, tmp1; + Word16 tmp, tmp1; if ( prediction_flag == 0 ) { diff --git a/lib_com/parameter_bitmaping_fx.c b/lib_com/parameter_bitmaping_fx.c index 180275d8f..0846c618b 100644 --- a/lib_com/parameter_bitmaping_fx.c +++ b/lib_com/parameter_bitmaping_fx.c @@ -58,15 +58,15 @@ static Word16 FixedWidthEncoding( Word16 value, Word16 index ) void GetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ) + Word16 **pStream, + Word16 *pnSize, + Word16 *pnBits ) { - int16_t index; - int16_t iParam, nParams; - int16_t value; + Word16 index; + Word16 iParam, nParams; + Word16 value; void const *pSubStruct; assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pParameter != NULL ) && ( pStream != NULL ) && ( pnSize != NULL ) && ( pnBits != NULL ) ); @@ -168,14 +168,14 @@ void GetParameters_fx( void SetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, void *pParameter, - const int16_t **pStream, - int16_t *pnSize ) + const Word16 **pStream, + Word16 *pnSize ) { - int16_t index; - int16_t iParam, nParams; - int16_t value; + Word16 index; + Word16 iParam, nParams; + Word16 value; void *pSubStruct; assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pParameter != NULL ) && ( pStream != NULL ) && ( pnSize != NULL ) ); diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9b596ca42..d0f0efb72 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -72,10 +72,6 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif -#ifndef TRUNC -#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) -#endif - #define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) #define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) @@ -11101,7 +11097,7 @@ void init_coder_ace_plus_ivas_fx( void core_coder_reconfig_ivas_fx( Encoder_State *st, - const int32_t last_total_brate ); + const Word32 last_total_brate ); void core_coder_mode_switch_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ diff --git a/lib_com/rom_basop_util.c b/lib_com/rom_basop_util.c index c3bfc6eef..eb79cc026 100644 --- a/lib_com/rom_basop_util.c +++ b/lib_com/rom_basop_util.c @@ -1449,7 +1449,7 @@ void BASOP_getTables( const PWord16 **ptwiddle /*Q15*/, const PWord16 **sin_twid ld2_length = sub( 16 - 1 - 1, norm_s( length ) ); /* Extract sort of "eigenvalue" (the 5 left most bits) of length. */ - SWITCH( (unsigned short) L_shl( length, sub( 15, ld2_length ) ) ) + SWITCH( (UWord16) L_shl( length, sub( 15, ld2_length ) ) ) { case 0xa000: /* 640 */ move16(); diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 274a33a18..33661fb58 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -66,7 +66,7 @@ typedef struct Word16 filt_len; /* number of filter coeff. */ Word16 filt_len_fx; /* number of filter coeff. Q0 */ - uint16_t flags; /* flags from config. table */ + UWord16 flags; /* flags from config. table */ UWord16 flags_fx; /* flags from config. table Q0 */ // UNS_Word16 flags_fx; /* flags from config. table Q0 */ diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 9edc28c03..c96dcc884 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -74,7 +74,7 @@ typedef struct typedef struct { Word16 lead_sign_ind; - uint32_t index, size; + UWord32 index, size; Word16 dim, k_val; } PvqEntry; @@ -313,7 +313,7 @@ typedef struct { Word32 low; Word32 high; - uint32_t value; + UWord32 value; Word32 bits_to_follow; } Tastat; typedef struct @@ -490,15 +490,6 @@ typedef Word16 ( *TEncodeValue )( Word16 value, Word16 index ); */ typedef Word16 ( *TDecodeValue )( struct Decoder_State *st, Word16 index, Word16 *pValue ); -/** Linear prediction analysis/synthesis filter definition. - * @param order filter order. - * @param parCoeff filter (PARCOR) coefficients. - * @param state state of the filter. Must be at least of 'order' size. - * @param x the current input value. - * @return the output of the filter. - */ -typedef float ( *TLinearPredictionFilter_flt )( const int16_t order, const float parCoeff[], float *state, float x ); - /** Structure that defines mapping between a parameter and a bitstream. */ typedef struct ParamBitMap { diff --git a/lib_dec/FEC_clas_estim_fx.c b/lib_dec/FEC_clas_estim_fx.c index 9b58084e3..e56a77be1 100644 --- a/lib_dec/FEC_clas_estim_fx.c +++ b/lib_dec/FEC_clas_estim_fx.c @@ -82,7 +82,7 @@ void FEC_clas_estim_fx( Word16 bfi, /* i : bad frame indicator */ /*B*/ Word32 last_core_brate, /* i : bitrate of previous frame */ - const int16_t FEC_mode /* i : ACELP FEC mode */ + const Word16 FEC_mode /* i : ACELP FEC mode */ ) { Word16 i, j, pos; diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index fc8aba043..b2cc593b3 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -847,7 +847,6 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ - // cldfbSynthesis_ivas_fx(realBuffer, imagBuffer, synth_out, (int16_t)(st_fx->output_Fs * 0.01f), st_fx->cldfbSyn); cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 17b3f9fbc..0f361e658 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1290,7 +1290,7 @@ ivas_error core_switching_post_dec_ivas_fx( FD_BWE_DEC_HANDLE hBWE_FD; HQ_DEC_HANDLE hHQ_core; ivas_error error; - int16_t offset; + Word16 offset; L_tmp = 0; move32(); diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index aa898956a..42f3250fb 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -114,17 +114,17 @@ void decod_unvoiced_fx( *-------------------------------------------------------------------*/ void decod_unvoiced_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 coder_type, /* Q0 i : coding type */ - Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ - Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ - Word16 *voice_factors_fx, /* Q15 o : voicing factors */ - Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ - Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ + const Word16 coder_type, /* Q0 i : coding type */ + Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ + Word16 *voice_factors_fx, /* Q15 o : voicing factors */ + Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ + Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ Word16 *gain_buf ) { Word16 gain_pit_fx; /* Quantized pitch gain */ diff --git a/lib_dec/er_dec_acelp_fx.c b/lib_dec/er_dec_acelp_fx.c index 7c3ecaa0a..e30553d38 100644 --- a/lib_dec/er_dec_acelp_fx.c +++ b/lib_dec/er_dec_acelp_fx.c @@ -446,7 +446,7 @@ void con_acelp_fx( ELSE { /* No harmonic part */ - assert( (int) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 ); + assert( (Word32) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 ); set16_fx( &exc[0], 0, add( st->L_frame, shr( st->L_frame, 1 ) ) ); FOR( i = 0; i < st->nb_subfr; i++ ) diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 3fe40c1f3..3c234c098 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -1484,7 +1484,7 @@ void ivas_binaural_add_LFE_fx( Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output Q11*/ ) { - Word16 render_lfe, idx_lfe, gain_fx; + Word16 render_lfe, idx_lfe, gain_fx, idx; IF( st_ivas->hBinRenderer != NULL ) { @@ -1523,7 +1523,7 @@ void ivas_binaural_add_LFE_fx( { v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); // q_input_fx - 1 /* copy LFE to left and right channels */ - FOR( int idx = 0; idx < output_frame; idx++ ) + FOR( idx = 0; idx < output_frame; idx++ ) { input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] = L_shl_sat( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx], 1 ); // saturating to keep same q move32(); diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 7dd7371fd..59d9c9e38 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2216,7 +2216,7 @@ void ivas_dirac_dec_render_sf_fx( DIRAC_DEC_STACK_MEM DirAC_mem; Word32 *p_onset_filter_fx = NULL; - uint16_t coherence_flag; + UWord16 coherence_flag; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word16 scale = 0; move16(); diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 9040a8a71..eae0e9069 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1428,9 +1428,9 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( static void ivas_ism_param_dec_render_sf_fx( Decoder_Struct *st_ivas, IVAS_OUTPUT_SETUP hSetup, - const int16_t nchan_transport, - const int16_t nchan_out, - const int16_t nchan_out_woLFE, + const Word16 nchan_transport, + const Word16 nchan_out, + const Word16 nchan_out_woLFE, Word32 *output_f_fx[], /*Q_output*/ Word16 Q_output[] ) { diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index f632d86c8..428c817ef 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -83,7 +83,7 @@ ivas_error ivas_jbm_dec_tc_fx( Word32 *data_fx /*Q11*/ ) { - Word16 n, output_frame, nchan_out, i; + Word16 n, output_frame, nchan_out, i, ii; Decoder_State *st; /* used for bitstream handling */ Word32 *p_output_fx[MAX_TRANSPORT_CHANNELS]; /* buffer for output synthesis */ Word16 nchan_remapped; @@ -512,14 +512,14 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } #ifdef MSAN_FIX - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx } @@ -534,7 +534,7 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } #ifdef MSAN_FIX - FOR( int ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 } @@ -614,7 +614,7 @@ ivas_error ivas_jbm_dec_tc_fx( st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; move16(); - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -999,7 +999,7 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; @@ -1045,7 +1045,7 @@ ivas_error ivas_jbm_dec_tc_fx( move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -1464,7 +1464,7 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->q_output_mem_fx[ii] ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; @@ -1509,7 +1509,7 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( st_ivas->hSpar != NULL ) { - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -1787,7 +1787,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) { - ivas_mc_paramupmix_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + ivas_mc_paramupmix_dec_digest_tc( st_ivas, (UWord8) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { @@ -1882,7 +1882,7 @@ ivas_error ivas_jbm_dec_render_fx( ivas_error error; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; Word32 *p_tc_fx[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; - Word16 subframe_len, gd_bits, exp, nchan_in, i, j; + Word16 subframe_len, gd_bits, exp, nchan_in, i, j, ch; const Word16 output_q_factor = Q11; move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -2448,7 +2448,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); } /* CLDFB synthesis */ - FOR( Word16 ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { IF( st_ivas->cldfbSynDec[ch] ) { @@ -2476,7 +2476,7 @@ ivas_error ivas_jbm_dec_render_fx( ivas_param_mc_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, channel_active_fx ); - FOR( int ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { IF( st_ivas->cldfbSynDec[ch] ) { diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 897fd4433..be2363469 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -107,7 +107,7 @@ static ivas_error param_mc_get_diff_proto_info_fx( const Word32 *proto_mtx, cons static void param_mc_update_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, Word32 *mixing_matrix[], Word16 *mixing_matrix_fx, Word32 *mixing_matrix_res[], Word16 *mixing_matrix_res_exp, const UWord16 nX, const UWord16 nY ); -static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const int16_t num_freq_bands /*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); +static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const Word16 num_freq_bands /*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); /*------------------------------------------------------------------------- * ivas_param_mc_dec_open() @@ -1509,8 +1509,8 @@ void ivas_param_mc_dec_read_BS_fx( *------------------------------------------------------------------------*/ void ivas_param_mc_dec_digest_tc_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ Word32 *transport_channels_f_fx[], Word16 transport_f_e ) { @@ -2361,7 +2361,7 @@ static void param_mc_protoSignalComputation_fx( Word32 *ImagBuffer_fx, /* i : CLDFB samples of the transport channels (imaginary part) */ Word32 *proto_frame_f_fx, /* o : interleaved complex prototype CLDFB samples */ const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ - const int16_t num_freq_bands /* i : number of frequency bands for the prototypes */ + const Word16 num_freq_bands /* i : number of frequency bands for the prototypes */ ) { Word16 band; @@ -2680,7 +2680,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( Word16 nY_band; Word16 num_lfe_bands; Word16 brange[2]; - uint16_t i; + UWord16 i; Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; Word16 remove_lfe; Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 812d9957f..6f75230c9 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -100,7 +100,7 @@ const Word32 dft_ap_gains_fx[5][3] = { 644245094, -644245120, 1073741824 } }; -const int16_t dft_ap_delays[3][3] = +const Word16 dft_ap_delays[3][3] = { { 2, 47, 61}, {29, 41, 73}, @@ -196,7 +196,7 @@ const Word16 dft_win_8k_fx[70] = * stereo CNA tables *------------------------------------------------------------------------*/ -const int16_t cna_init_bands[CNA_INIT_NBANDS + 1] = +const Word16 cna_init_bands[CNA_INIT_NBANDS + 1] = { 1, 4, 14, 33, 67, 171, 320 }; @@ -235,7 +235,7 @@ const Word16 min_smooth_gains2_fx[SBA_DIRAC_STEREO_NUM_BANDS] = /* all the "probability" tables for the actual AC are in the reversed cumulative counts table format; for example, given the counts table [c0 | c1 | c2 | c3] with c0 + c1 + c2 + c3 = 2 ^ 14, the reversed cumulative counts table is [2 ^ 14 | 2 ^ 14 - c0 | 2 ^ 14 - c0 - c1 | 2 ^ 14 - c0 - c1 - c2 | 2 ^ 14 - c0 - c1 - c2 - c3] */ -const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = +const UWord16 cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = { {0,1024,2048,3072,4096,5120,6144,7168,8192,9216,10240,11264,12288,13312,14336,15360,16384 }, {0,9294,16019,16213,16311,16346,16363,16371,16375,16377,16378,16379,16380,16381,16382,16383,16384 }, @@ -246,7 +246,7 @@ const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] {0,5836,14448,15610,16267,16343,16374,16375,16376,16377,16378,16379,16380,16381,16382,16383,16384 } }; -const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = +const UWord16 sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = { {1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024 }, {9294,6725,194,98,35,17,8,4,2,1,1,1,1,1,1,1 }, @@ -257,7 +257,7 @@ const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = {5836,8612,1162,657,76,31,1,1,1,1,1,1,1,1,1,1 } }; -const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = +const UWord16 cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = { {0,6445,12725,15035,15885,16198,16313,16355,16370,16376,16378,16379,16380,16381,16382,16383,16384 }, {0,3624,8645,11690,13537,14657,15336,15748,15998,16150,16242,16298,16332,16352,16364,16372,16384 }, @@ -276,7 +276,7 @@ const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SI {0,3623,6446,8644,10356,11689,12727,13536,14166,14657,15039,15337,15569,15749,15890,15999,16384 }, }; -const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] = +const UWord16 sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] = { {6445,6280,2310,850,313,115,42,15,6,2,1,1,1,1,1,1 }, {3624,5021,3045,1847,1120,679,412,250,152,92,56,34,20,12,8,12 }, @@ -295,59 +295,59 @@ const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] {3623,2823,2198,1712,1333,1038,809,630,491,382,298,232,180,141,109,385 }, }; -const uint16_t cum_freq_ECSQ_tab_abs_1bit[1 + 2] = +const UWord16 cum_freq_ECSQ_tab_abs_1bit[1 + 2] = { 0, 5462, 16384 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -const uint16_t cum_freq_ECSQ_tab_abs_2bit[1 + 4] = +const UWord16 cum_freq_ECSQ_tab_abs_2bit[1 + 4] = { 0, 2338, 7020, 11702, 16384 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -const uint16_t cum_freq_ECSQ_tab_abs_3bit[1 + 8] = +const UWord16 cum_freq_ECSQ_tab_abs_3bit[1 + 8] = { 0, 1096, 3280, 5464, 7648, 9832, 12016, 14200, 16384 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -const uint16_t cum_freq_ECSQ_tab_abs_4bit[1 + 16] = +const UWord16 cum_freq_ECSQ_tab_abs_4bit[1 + 16] = { 0, 514, 1572, 2630, 3688, 4746, 5804, 6862, 7920, 8978, 10036, 11094, 12152, 13210, 14268, 15326, 16384 }; -const uint16_t sym_freq_ECSQ_tab_abs_1bit[2] = +const UWord16 sym_freq_ECSQ_tab_abs_1bit[2] = { 5462, 10922 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -const uint16_t sym_freq_ECSQ_tab_abs_2bit[4] = +const UWord16 sym_freq_ECSQ_tab_abs_2bit[4] = { 2338, 4682, 4682, 4682 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -const uint16_t sym_freq_ECSQ_tab_abs_3bit[8] = +const UWord16 sym_freq_ECSQ_tab_abs_3bit[8] = { 1096, 2184, 2184, 2184, 2184, 2184, 2184, 2184 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -const uint16_t sym_freq_ECSQ_tab_abs_4bit[16] = +const UWord16 sym_freq_ECSQ_tab_abs_4bit[16] = { 514, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058 }; /* array of tables for uniform coding of absolute values */ -const uint16_t * const cum_freq_ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const cum_freq_ECSQ_tab_abs_lsbs[1 + 4] = { NULL, cum_freq_ECSQ_tab_abs_1bit, cum_freq_ECSQ_tab_abs_2bit, cum_freq_ECSQ_tab_abs_3bit, cum_freq_ECSQ_tab_abs_4bit }; -const uint16_t * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = { NULL, sym_freq_ECSQ_tab_abs_1bit, sym_freq_ECSQ_tab_abs_2bit, sym_freq_ECSQ_tab_abs_3bit, sym_freq_ECSQ_tab_abs_4bit }; @@ -391,7 +391,7 @@ const Word32 dmxmtx_table_fx[BINAURAL_CHANNELS][11] = *-----------------------------------------------------------------------*/ /* Alpha Fine Huffman table df0 */ -static const int16_t huff_nodes_first_band_alpha[32][2] = +static const Word16 huff_nodes_first_band_alpha[32][2] = { { -17, 1 }, { 3, 2 }, @@ -428,7 +428,7 @@ static const int16_t huff_nodes_first_band_alpha[32][2] = }; /* Alpha Fine Huffman table df */ -static const int16_t huff_nodes_alpha_1D_DF[64][2] = +static const Word16 huff_nodes_alpha_1D_DF[64][2] = { { -33, 1 }, { 3, 2 }, @@ -497,7 +497,7 @@ static const int16_t huff_nodes_alpha_1D_DF[64][2] = }; /* Alpha Fine Huffman table dt */ -static const int16_t huff_nodes_alpha_1D_DT[64][2] = +static const Word16 huff_nodes_alpha_1D_DT[64][2] = { { -33, 1 }, { -34, 2 }, @@ -566,19 +566,19 @@ static const int16_t huff_nodes_alpha_1D_DT[64][2] = }; /* Beta Fine Huffman table df0 */ -static const int16_t huff_nodes_first_band_beta[8][2] = +static const Word16 huff_nodes_first_band_beta[8][2] = { { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, 4 }, { -5, 5 }, { -6, 6 }, { -7, 7 }, { -8, -9 } }; /* Beta Fine Huffman table df */ -static const int16_t huff_nodes_beta_1D_DF[16][2] = +static const Word16 huff_nodes_beta_1D_DF[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { 9, 8 }, { -5, -13 }, { 11, 10 }, { -4, -14 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; /* Beta Fine Huffman table dt */ -static const int16_t huff_nodes_beta_1D_DT[16][2] = +static const Word16 huff_nodes_beta_1D_DT[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { -13, 8 }, { -5, 9 }, { -14, 10 }, { -4, 11 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 11752380d..84c1a94a0 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -53,7 +53,7 @@ extern const Word16 dft_alpha_s2_b2_fx[STEREO_DFT_BAND_MAX]; extern const Word32 dft_bpf_weights_fx[]; extern const Word32 dft_ap_gains_fx[5][3]; -extern const int16_t dft_ap_delays[3][3]; +extern const Word16 dft_ap_delays[3][3]; extern const Word16 dft_win232ms_8k_fx[75]; extern const Word16 dft_win232ms_12k8_fx[120]; extern const Word16 dft_win232ms_16k_fx[150]; @@ -62,7 +62,7 @@ extern const Word16 dft_win232ms_48k_fx[450]; extern const Word16 dft_res_pred_weights_fx[][STEREO_DFT_BAND_MAX]; extern const Word16 dft_win_8k_fx[70]; -extern const int16_t cna_init_bands[CNA_INIT_NBANDS + 1]; +extern const Word16 cna_init_bands[CNA_INIT_NBANDS + 1]; extern const Word16 min_smooth_gains1_fx[SBA_DIRAC_STEREO_NUM_BANDS]; @@ -74,12 +74,12 @@ extern const Word16 max_smooth_gains2_fx[SBA_DIRAC_STEREO_NUM_BANDS]; * ECLVQ Stereo ROM tables *----------------------------------------------------------------------------------*/ -extern const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; -extern const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT]; -extern const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; -extern const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE]; -extern const uint16_t *const cum_freq_ECSQ_tab_abs_lsbs[1 + 4]; -extern const uint16_t *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; +extern const UWord16 sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT]; +extern const UWord16 cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; +extern const UWord16 sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE]; +extern const UWord16 *const cum_freq_ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; /*----------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index d1efbbd2c..bb79b956c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -49,11 +49,11 @@ #define IVAS_DEFAULT_DTX_CNG_RAMP ( 8 ) /* PLC constants */ -static const int16_t ivas_spar_dec_plc_num_frames_keep = 9; -// static const int16_t ivas_spar_dec_plc_num_frames_fade_out = 9; -static const int16_t ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; -static const int16_t ivas_spar_dec_plc_max_num_frames_ramp_down = 33; -static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; +static const Word16 ivas_spar_dec_plc_num_frames_keep = 9; +// static const Word16 ivas_spar_dec_plc_num_frames_fade_out = 9; +static const Word16 ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; +static const Word16 ivas_spar_dec_plc_max_num_frames_ramp_down = 33; +static const Word16 ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /*------------------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index b1522be36..5704f4f60 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -49,14 +49,14 @@ /* State of the range decoder */ typedef struct { - uint32_t rc_low; - uint32_t rc_range; + UWord32 rc_low; + UWord32 rc_range; - uint16_t *bit_buffer; - int16_t bit_count; - int16_t max_allowable_bit_count; + UWord16 *bit_buffer; + Word16 bit_count; + Word16 max_allowable_bit_count; - int16_t bit_error_detected; + Word16 bit_error_detected; } RangeUniDecState; @@ -78,11 +78,11 @@ typedef struct stereo_dft_dec_data_struct STEREO_DFT_CONFIG_DATA_HANDLE hConfig; /*Sizes*/ - int16_t N; /* Size of DFT hop size */ - int16_t NFFT; /* Size of DFT */ + Word16 N; /* Size of DFT hop size */ + Word16 NFFT; /* Size of DFT */ /*FFT*/ - int16_t dft_trigo_step; + Word16 dft_trigo_step; const Word16 *dft_trigo_fx; /* Q15 */ const Word16 *dft_trigo_12k8_fx; /* Q15 */ @@ -90,13 +90,13 @@ typedef struct stereo_dft_dec_data_struct const Word16 *dft_trigo_8k_fx; /* Q15 */ - int16_t dft32ms_ovl; /* Overlap size */ + Word16 dft32ms_ovl; /* Overlap size */ const Word16 *win32ms_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_12k8_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_16k_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_8k_fx; /* DFT window */ /* Q15 */ - int16_t dft32ms_ovl2; /* Overlap2 size */ + Word16 dft32ms_ovl2; /* Overlap2 size */ const Word16 *win232ms_fx; /* DFT window */ /* Q15 */ const Word16 *win232ms_12k8_fx; /* DFT window */ /* Q15 */ const Word16 *win232ms_16k_fx; /* DFT window */ /* Q15 */ @@ -105,31 +105,31 @@ typedef struct stereo_dft_dec_data_struct /*Bands*/ - int16_t band_res[STEREO_DFT_DEC_DFT_NB]; - int16_t band_limits[STEREO_DFT_BAND_MAX + 1]; - int16_t nbands; + Word16 band_res[STEREO_DFT_DEC_DFT_NB]; + Word16 band_limits[STEREO_DFT_BAND_MAX + 1]; + Word16 nbands; /*Configuration*/ - int16_t prm_res[STEREO_DFT_DEC_DFT_NB]; + Word16 prm_res[STEREO_DFT_DEC_DFT_NB]; /*Stereo parameters*/ Word32 side_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; /* Q31 */ - int16_t side_gain_flag_1; - int16_t side_gain_flag_2; - int16_t side_gain_index_previous[STEREO_DFT_BAND_MAX]; - int16_t side_gain_index[STEREO_DFT_BAND_MAX]; + Word16 side_gain_flag_1; + Word16 side_gain_flag_2; + Word16 side_gain_index_previous[STEREO_DFT_BAND_MAX]; + Word16 side_gain_index[STEREO_DFT_BAND_MAX]; Word32 gipd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q27 */ - int16_t no_ipd_flag; /* flag to indicate when no IPD gets used */ + Word16 no_ipd_flag; /* flag to indicate when no IPD gets used */ - int16_t itd_xfade_counter; - int32_t last_active_element_brate; - int16_t ipd_xfade_counter; + Word16 itd_xfade_counter; + Word32 last_active_element_brate; + Word16 ipd_xfade_counter; /*residual prediction*/ - int16_t res_pred_mode[STEREO_DFT_DEC_DFT_NB]; /* residual prediction mode: 0(off), 1(stereo filling only), 2(enhanced stereo filling) */ - Word32 itd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q15 */ + Word16 res_pred_mode[STEREO_DFT_DEC_DFT_NB]; /* residual prediction mode: 0(off), 1(stereo filling only), 2(enhanced stereo filling) */ + Word32 itd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q15 */ Word32 itd_xfade_step_fx; /* Q15 */ Word32 itd_xfade_target_fx; /* Q15 */ @@ -139,19 +139,19 @@ typedef struct stereo_dft_dec_data_struct Word32 ipd_xfade_step_fx; /* Q27 */ Word32 ipd_xfade_prev_fx; /* Q27 */ Word32 res_pred_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; /* prediction gain for the residual HFs */ /* Q31 */ - int16_t res_pred_band_min; /* Band min for prediction of residual */ - int16_t past_DMX_pos; - int16_t res_pred_flag_0; - int16_t res_pred_flag_1; - int16_t res_pred_index_previous[STEREO_DFT_BAND_MAX]; + Word16 res_pred_band_min; /* Band min for prediction of residual */ + Word16 past_DMX_pos; + Word16 res_pred_flag_0; + Word16 res_pred_flag_1; + Word16 res_pred_index_previous[STEREO_DFT_BAND_MAX]; - int16_t reverb_flag; - int16_t nbands_respred; + Word16 reverb_flag; + Word16 nbands_respred; /*residual coding*/ - int16_t res_cod_mode[STEREO_DFT_DEC_DFT_NB]; /* mode from 0 (off) to 3 */ - int16_t res_cod_band_max; /* Band max for coding of residual */ - int16_t res_cod_line_max; + Word16 res_cod_mode[STEREO_DFT_DEC_DFT_NB]; /* mode from 0 (off) to 3 */ + Word16 res_cod_band_max; /* Band max for coding of residual */ + Word16 res_cod_line_max; Word32 DFT_past_DMX_fx[STEREO_DFT_PAST_MAX][STEREO_DFT32MS_N_32k]; /* Past DMX for residual prediction */ /* Q(q_DFT_past_DMX_fx) */ Word32 past_res_pred_gain_fx[STEREO_DFT_PAST_MAX][STEREO_DFT_BAND_MAX]; /* Q31 */ Word32 res_gains_ind_fx[2][2 * STEREO_DFT_BAND_MAX]; /* Q26 */ @@ -171,9 +171,9 @@ typedef struct stereo_dft_dec_data_struct BPF_DEC_HANDLE hBpf; TCX_LTP_DEC_HANDLE hTcxLtpDec; - int16_t trans; - int16_t attackPresent; - int16_t wasTransient; + Word16 trans; + Word16 attackPresent; + Word16 wasTransient; basic_allpass_t ap1, ap2, ap3; @@ -188,9 +188,9 @@ typedef struct stereo_dft_dec_data_struct Word32 ap_fade_mem_fx[STEREO_DFT_ALLPASS_FADELEN_16k]; /* Q(q_ap_fade_mem_fx) */ Word16 q_ap_fade_mem_fx; - int16_t ap_wasTransient; - int16_t core_hist[STEREO_DFT_CORE_HIST_MAX]; - int16_t hb_stefi_delay; + Word16 ap_wasTransient; + Word16 core_hist[STEREO_DFT_CORE_HIST_MAX]; + Word16 hb_stefi_delay; Word32 smooth_dmx_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 smooth_res_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 td_gain_fx[STEREO_DFT_CORE_HIST_MAX]; /* Q(q_td_gain) */ @@ -206,16 +206,16 @@ typedef struct stereo_dft_dec_data_struct /* stereo DTX */ Word16 g_state_fx[STEREO_DFT_BAND_MAX]; /* Q15 */ - int16_t frame_sid_nodata; - int16_t frame_nodata; - int16_t frame_sid; + Word16 frame_sid_nodata; + Word16 frame_nodata; + Word16 frame_sid; Word16 scale_fx; /* Q15 */ /* PLC on residual signal */ - int16_t time_offs; - int16_t sg_mem_corrupt; - int16_t recovery_flg; + Word16 time_offs; + Word16 sg_mem_corrupt; + Word16 recovery_flg; /* PLC on residual signal */ Word32 sg_mean_fx; /* Q31 */ @@ -228,7 +228,7 @@ typedef struct stereo_dft_dec_data_struct Word16 q_hb_nrg_subr; Word16 q_res_mem; - int16_t first_frame; + Word16 first_frame; Word32 mixer_mat_smooth_fx[2][4][2 * IVAS_MAX_NUM_BANDS]; /* Q31 */ Word32 g_L_prev_fx; /* Q31 */ Word32 g_R_prev_fx; /* Q31 */ @@ -257,26 +257,26 @@ typedef struct stereo_dec_cng { Word16 cm_fx[STEREO_DFT_BAND_MAX]; /* cm */ /* Q15 */ Word16 coh_fx[STEREO_DFT_BAND_MAX + 1]; /* coherence */ /* Q15 */ - int16_t first_SID; /* first SID indicator */ - int16_t first_SID_after_TD; /* first SID after TD-stereo indicator */ - int16_t prev_sid_nodata; /* previous frame SID/FRAME_NO_DATA indicator */ - int16_t last_tdm_idx; /* last tdm index */ + Word16 first_SID; /* first SID indicator */ + Word16 first_SID_after_TD; /* first SID after TD-stereo indicator */ + Word16 prev_sid_nodata; /* previous frame SID/FRAME_NO_DATA indicator */ + Word16 last_tdm_idx; /* last tdm index */ Word32 c_LR_LT_fx; /* left right cross correlation */ /* Q31 */ - int16_t active_frame_counter; /* counter for active frames */ - int16_t xfade_frame_counter; /* xfade counter */ - int16_t xfade_length; /* number of frames to perform xfade */ - int16_t nr_dft_frames; /* dft frame counter */ - int16_t nr_corr_frames; /* correlation frame counter */ - int16_t nr_sid_frames; /* SID frame counter */ - int16_t last_act_element_mode; /* Element mode of last active frame */ + Word16 active_frame_counter; /* counter for active frames */ + Word16 xfade_frame_counter; /* xfade counter */ + Word16 xfade_length; /* number of frames to perform xfade */ + Word16 nr_dft_frames; /* dft frame counter */ + Word16 nr_corr_frames; /* correlation frame counter */ + Word16 nr_sid_frames; /* SID frame counter */ + Word16 last_act_element_mode; /* Element mode of last active frame */ Word16 olapBufferSynth22_fx[FFTLEN]; /* overlap buffer for secondary channel CNA */ Word32 olapBufferSynth22_32fx[FFTLEN]; /* overlap buffer for secondary channel CNA */ - int16_t flag_cna_fade; /* flag enabling CNA fade out */ + Word16 flag_cna_fade; /* flag enabling CNA fade out */ Word16 maskingNoiseS_fx[L_FRAME16k]; /* masking noise (CNA) for secondary channel */ - int16_t enableSecCNA; /* flag enabling secondary channel CNA */ + Word16 enableSecCNA; /* flag enabling secondary channel CNA */ Word16 c_PS_LT_fx; /* long term cross-correlation between primary and secondary channel */ // Assumed Q15 for initialization. Can be modified later if reqd. - const int16_t *frameSize; /* Frame size in samples */ - const int16_t *fftlen; /* FFT length used for the decomposition */ + const Word16 *frameSize; /* Frame size in samples */ + const Word16 *fftlen; /* FFT length used for the decomposition */ } STEREO_CNG_DEC, *STEREO_CNG_DEC_HANDLE; @@ -287,18 +287,18 @@ typedef struct stereo_dec_cng typedef struct stereo_td_dec_data_structure { - int16_t tdm_last_ratio_idx; /* last TDM ratio index */ - int16_t tdm_last_SM_flag; /* last channel combination scheme flag */ - int16_t tdm_prev_last_SM_flag; /* channel combination scheme flag before last frame */ - int16_t tdm_SM_flag; /* current channel combination scheme flag */ - int16_t tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ - - int16_t tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ - int16_t tdm_low_rate_mode; /* secondary channel low rate mode flag */ + Word16 tdm_last_ratio_idx; /* last TDM ratio index */ + Word16 tdm_last_SM_flag; /* last channel combination scheme flag */ + Word16 tdm_prev_last_SM_flag; /* channel combination scheme flag before last frame */ + Word16 tdm_SM_flag; /* current channel combination scheme flag */ + Word16 tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ + + Word16 tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ + Word16 tdm_low_rate_mode; /* secondary channel low rate mode flag */ Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; - int16_t tdm_Pitch_reuse_flag; - int16_t tdm_LRTD_flag; - int16_t flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ + Word16 tdm_Pitch_reuse_flag; + Word16 tdm_LRTD_flag; + Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ Word32 TCX_old_syn_Overl_fx[L_FRAME16k / 2]; /* past ovrl buffer for possible switching from TD stereo ACELP to MDCT stereo TCX frame */ /* Q11 */ Word16 prevSP_ratio_fx; /* previous SP ratio */ @@ -320,24 +320,24 @@ typedef struct stereo_mdct_dec_data_structure STEREO_MDCT_BAND_PARAMETERS stbParamsTCX20afterACELP; /* stereo frequency band parameters for transition frame */ /* only intraframe */ - int16_t mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ - int16_t global_ild[2]; /* Quantized ILD for the whole spectrum */ - int16_t split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ + Word16 mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ + Word16 global_ild[2]; /* Quantized ILD for the whole spectrum */ + Word16 split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ - int16_t IGFStereoMode[2]; /* MDCT stereo mode for IGF */ + Word16 IGFStereoMode[2]; /* MDCT stereo mode for IGF */ - int16_t use_itd; - int16_t itd_mode; /*0/1*/ - Word32 itd_fx; /* Q15 */ + Word16 use_itd; + Word16 itd_mode; /*0/1*/ + Word32 itd_fx; /* Q15 */ - int16_t reverse_dmx; + Word16 reverse_dmx; Word32 smooth_ratio_fx; /* Q26 */ - int16_t prev_ms_mask[NB_DIV][MAX_SFB]; + Word16 prev_ms_mask[NB_DIV][MAX_SFB]; Word16 lastCoh_fx; /* Q14 */ - int16_t noise_seeds_channels[CPE_CHANNELS]; - int16_t noise_seed_common; - int16_t isSBAStereoMode; + Word16 noise_seeds_channels[CPE_CHANNELS]; + Word16 noise_seed_common; + Word16 isSBAStereoMode; } STEREO_MDCT_DEC_DATA, *STEREO_MDCT_DEC_DATA_HANDLE; @@ -348,18 +348,18 @@ typedef struct stereo_mdct_dec_data_structure typedef struct stereo_tca_dec_data_structure { - int16_t refChanIndx; /* reference channel index in current frame */ - int16_t prevRefChanIndx; /* reference channel index in previous frame */ - int16_t indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ - int16_t indx_ica_gD; /* ICA target gain */ + Word16 refChanIndx; /* reference channel index in current frame */ + Word16 prevRefChanIndx; /* reference channel index in previous frame */ + Word16 indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ + Word16 indx_ica_gD; /* ICA target gain */ Word32 targetGain_fx; /* gain norm applied on target (or right) channel in current frame */ // Q29 Word32 prevTargetGain_fx; /* gain norm applied on target (or right) channel in previous frame */ // Q29 - int16_t corrLagStats; /* corr lag stats in current frame */ - int16_t prevCorrLagStats; /* corr lag stats in previous frame */ + Word16 corrLagStats; /* corr lag stats in current frame */ + Word16 prevCorrLagStats; /* corr lag stats in previous frame */ - int16_t interp_dec_prevNCShift; /* NC Shift in previous frame */ - int16_t interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ + Word16 interp_dec_prevNCShift; /* NC Shift in previous frame */ + Word16 interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ Word32 memChanL_fx[L_DEC_MEM_LEN_ICA]; /* left channel input to correct at the cross-over for Fixed */ @@ -428,10 +428,10 @@ typedef struct stereo_icbwe_dec_data_structure typedef struct { - int16_t dtx_flag; - int16_t sce_id_dtx; + Word16 dtx_flag; + Word16 sce_id_dtx; - int16_t ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ + Word16 ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ } ISM_DTX_DATA_DEC; @@ -478,9 +478,9 @@ typedef struct ivas_dirac_dec_data_structure { DIRAC_CONFIG_DATA_HANDLE hConfig; - int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1]; - int16_t dithering_seed; - int16_t spar_to_dirac_write_idx; + Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1]; + Word16 dithering_seed; + Word16 spar_to_dirac_write_idx; IVAS_FB_MIXER_HANDLE hFbMdft; @@ -521,10 +521,10 @@ typedef struct dirac_output_synthesis_cov_state_structure typedef struct ivas_param_mc_diff_proto_info_structure { - int16_t num_protos_diff; - int16_t *proto_index_diff; - int16_t *num_source_chan_diff; - int16_t **source_chan_idx; + Word16 num_protos_diff; + Word16 *proto_index_diff; + Word16 *num_source_chan_diff; + Word16 **source_chan_idx; Word32 **proto_fac_fx; } PARAM_MC_DIFF_PROTO_INFO; @@ -532,42 +532,42 @@ typedef struct ivas_param_mc_diff_proto_info_structure typedef struct ivas_param_mc_dec_data_structure { - int16_t slot_size; + Word16 slot_size; Word32 *Cldfb_RealBuffer_tc_fx; // Q12 Word16 Cldfb_RealBuffer_tc_e; Word32 *Cldfb_ImagBuffer_tc_fx; // Q12 Word16 Cldfb_ImagBuffer_tc_e; Word16 sz; - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; - int16_t num_freq_bands; - int16_t num_param_bands_synth; + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; + Word16 num_freq_bands; + Word16 num_param_bands_synth; - int16_t band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; + Word16 band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; /*Decoder parameters */ /*Prototypes*/ - int16_t num_outputs_diff; + Word16 num_outputs_diff; PARAM_MC_DIFF_PROTO_INFO *diff_proto_info; PARAM_MC_SYNTHESIS_CONF synthesis_conf; /*Options*/ /* Decorrelator options */ - int16_t max_band_decorr; + Word16 max_band_decorr; /*Decoder states=memories*/ Word32 *proto_frame_f_fx; /* Q11 */ Word32 *proto_frame_dec_f_fx; /* Q11 */ DIRAC_OUTPUT_SYNTHESIS_COV_STATE h_output_synthesis_cov_state; DIRAC_OUTPUT_SYNTHESIS_PARAMS h_output_synthesis_params; - int16_t max_band_energy_compensation; + Word16 max_band_energy_compensation; HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC; Word16 *icc_q_fx; /* ICC parameters*/ /* Q15 */ Word16 *icld_q_fx; /* Q8 */ - int16_t max_param_band_abs_cov; + Word16 max_param_band_abs_cov; Word16 q_proto_frame_f; Word32 *ls_conv_dmx_matrix_fx; /* Q30 */ Word32 *proto_matrix_int_fx; @@ -588,12 +588,12 @@ typedef struct ivas_param_mc_dec_data_structure typedef struct ivas_mc_paramupmix_dec_data_structure { - int16_t num_freq_bands; + Word16 num_freq_bands; ivas_td_decorr_state_t *hTdDecorr[MC_PARAMUPMIX_COMBINATIONS]; - int32_t alpha_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int32_t beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int16_t first_frame; - int16_t free_param_interpolator; + Word32 alpha_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word32 beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word16 first_frame; + Word16 free_param_interpolator; Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; // Q28 @@ -627,30 +627,30 @@ typedef struct ivas_spar_md_dec_state_t ivas_spar_dec_matrices_t spar_coeffs; ivas_spar_dec_matrices_t spar_coeffs_prev; ivas_spar_dec_matrices_t spar_coeffs_tar; - int16_t dtx_md_smoothing_cntr; - int16_t valid_bands[IVAS_MAX_NUM_BANDS]; - int16_t base_band_age[IVAS_MAX_NUM_BANDS]; - int16_t spar_plc_num_lost_frames; - int16_t num_decorr; - int16_t td_decorr_flag; - int16_t spar_plc_enable_fadeout_flag; + Word16 dtx_md_smoothing_cntr; + Word16 valid_bands[IVAS_MAX_NUM_BANDS]; + Word16 base_band_age[IVAS_MAX_NUM_BANDS]; + Word16 spar_plc_num_lost_frames; + Word16 num_decorr; + Word16 td_decorr_flag; + Word16 spar_plc_enable_fadeout_flag; Word32 ***mixer_mat_fx; /* Q(Q_mixer_mat) */ Word32 mixer_mat_prev_fx[MAX_PARAM_SPATIAL_SUBFRAMES + 1][IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS]; /* Q(Q_mixer_mat) */ Word16 Q_mixer_mat; ivas_spar_md_com_cfg spar_md_cfg; ivas_arith_coeffs_t arith_coeffs; ivas_huff_coeffs_t huff_coeffs; - int16_t table_idx; - int16_t dtx_vad; - int16_t spar_hoa_md_flag; - int16_t spar_hoa_dirac2spar_md_flag; - int16_t HOA_md_ind[IVAS_SPAR_MAX_CH]; + Word16 table_idx; + Word16 dtx_vad; + Word16 spar_hoa_md_flag; + Word16 spar_hoa_dirac2spar_md_flag; + Word16 HOA_md_ind[IVAS_SPAR_MAX_CH]; Word32 smooth_buf_fx[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; /* Q0 */ Word16 smooth_fac_fx[IVAS_MAX_NUM_BANDS]; /* Q15 */ Word32 mixer_mat_prev2_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; /* Q(Q_mixer_mat) */ - int16_t first_valid_frame; + Word16 first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; - int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; + Word16 base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; } ivas_spar_md_dec_state_t; @@ -676,11 +676,11 @@ typedef struct { Word16 prev_ql_fx[IVAS_PCA_INTERP]; Word16 prev_qr_fx[IVAS_PCA_INTERP]; - int16_t prev_pca_bypass; + Word16 prev_pca_bypass; Word16 mem_eigVec_interp_fx[IVAS_PCA_LEN_INTERP_EIG_DEC]; /* parser output: */ - int16_t pca_bypass; - int32_t index[2]; + Word16 pca_bypass; + Word32 index[2]; } PCA_DEC_STATE; @@ -690,20 +690,20 @@ typedef struct ivas_spar_dec_lib_t ivas_td_decorr_state_t *hTdDecorr; ivas_spar_md_dec_state_t *hMdDec; IVAS_FB_MIXER_HANDLE hFbMixer; - int16_t AGC_flag; + Word16 AGC_flag; ivas_agc_dec_state_t *hAgcDec; PCA_DEC_STATE *hPCA; - int16_t dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; - int16_t enc_param_start_band; - int32_t core_nominal_brate; /* Nominal bitrate for core coding */ - int16_t i_subframe; - - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; + Word16 dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; + Word16 enc_param_start_band; + Word32 core_nominal_brate; /* Nominal bitrate for core coding */ + Word16 i_subframe; + + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; } SPAR_DEC_DATA, *SPAR_DEC_HANDLE; @@ -712,8 +712,8 @@ typedef struct ivas_spar_dec_lib_t typedef struct ivas_osba_data { Word32 **delayBuffer_fx; - int16_t delayBuffer_size; - int16_t delayBuffer_nchan; + Word16 delayBuffer_size; + Word16 delayBuffer_nchan; } SBA_ISM_DATA, *SBA_ISM_DATA_HANDLE; @@ -724,9 +724,9 @@ typedef struct ivas_osba_data typedef struct sce_dec_data_structure { - int16_t sce_id; /* SCE # identifier */ - int32_t element_brate; /* SCE total bitrate in bps */ - int32_t last_element_brate; /* SCE last total bitrate in bps */ + Word16 sce_id; /* SCE # identifier */ + Word32 element_brate; /* SCE total bitrate in bps */ + Word32 last_element_brate; /* SCE last total bitrate in bps */ /* core coder handle */ DEC_CORE_HANDLE hCoreCoder[1]; @@ -747,15 +747,15 @@ typedef struct sce_dec_data_structure typedef struct cpe_dec_data_structure { - int16_t cpe_id; /* CPE # identifier */ - int32_t element_brate; /* CPE element total bitrate in bps */ - int32_t last_element_brate; /* last CPE element total bitrate in bps */ + Word16 cpe_id; /* CPE # identifier */ + Word32 element_brate; /* CPE element total bitrate in bps */ + Word32 last_element_brate; /* last CPE element total bitrate in bps */ - int16_t element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ - int16_t last_element_mode; /* last element mode */ + Word16 element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ + Word16 last_element_mode; /* last element mode */ - int16_t stereo_switching_counter; - int16_t NbFrameMod; + Word16 stereo_switching_counter; + Word16 NbFrameMod; /* core coder handle */ DEC_CORE_HANDLE hCoreCoder[CPE_CHANNELS]; @@ -768,7 +768,7 @@ typedef struct cpe_dec_data_structure STEREO_ICBWE_DEC_HANDLE hStereoICBWE; /* Stereo inter-channel BWE data handle */ STEREO_CNG_DEC_HANDLE hStereoCng; /* Stereo CNG data structure */ - int16_t nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ + Word16 nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ /* DFT stereo I/O channel buffer memories that need to be updated for TD->DFT stereo switching */ @@ -792,7 +792,7 @@ typedef struct cpe_dec_data_structure /* buffers used for fading between MDCT and DFT Stereo */ - int32_t brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ + Word32 brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ } CPE_DEC_DATA, *CPE_DEC_HANDLE; @@ -803,8 +803,8 @@ typedef struct cpe_dec_data_structure typedef struct mct_dec_block_data_struct { - int16_t ch1, ch2; - int16_t mask[2][MAX_SFB]; + Word16 ch1, ch2; + Word16 mask[2][MAX_SFB]; STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; /* MDCT stereo data handle */ } MCT_DEC_BLOCK_DATA, *MCT_DEC_BLOCK_DATA_HANDLE; @@ -812,14 +812,14 @@ typedef struct mct_dec_block_data_struct typedef struct mct_dec_data_structure { - int16_t nchan_out_woLFE; /* number of active channels within multi-channel configuration */ - int16_t currBlockDataCnt; - int16_t bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ + Word16 nchan_out_woLFE; /* number of active channels within multi-channel configuration */ + Word16 currBlockDataCnt; + Word16 bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ MCT_DEC_BLOCK_DATA_HANDLE hBlockData[MCT_MAX_BLOCKS]; - int16_t chBitRatios[MCT_MAX_CHANNELS]; - int16_t lowE_ch[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ - uint16_t mc_global_ild[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ + Word16 chBitRatios[MCT_MAX_CHANNELS]; + Word16 lowE_ch[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ + UWord16 mc_global_ild[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ } MCT_DEC_DATA, *MCT_DEC_HANDLE; @@ -866,12 +866,12 @@ typedef struct ivas_binaural_rendering_struct IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ EFAP_HANDLE hEFAPdata; /* EFAP structure*/ Word32 *hoa_dec_mtx; /* pointer to HOA decoder mtx */ /*Q29*/ - int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ - int16_t max_band; /* band upto which rendering is performed */ - int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ - int16_t timeSlots; /* number of time slots of binaural renderer */ - int16_t nInChannels; /* number input channels */ - int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ + Word8 rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + Word16 max_band; /* band upto which rendering is performed */ + Word16 conv_band; /* band upto which convolution in cldfb domain is performed */ + Word16 timeSlots; /* number of time slots of binaural renderer */ + Word16 nInChannels; /* number input channels */ + Word8 render_lfe; /* Flag to render LFE in binaural rendering*/ IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ /* Convolution module structure */ @@ -892,18 +892,18 @@ typedef struct ivas_masa_decoder_ext_out_meta_struct { MASA_DECRIPTIVE_META descriptiveMeta; - uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord16 directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; } MASA_DECODER_EXT_OUT_META; typedef struct ivas_masa_decoder_data_struct { - int16_t band_mapping[MASA_FREQUENCY_BANDS + 1]; + Word16 band_mapping[MASA_FREQUENCY_BANDS + 1]; SPHERICAL_GRID_DATA *sph_grid16; MASA_DECODER_EXT_OUT_META *extOutMeta; @@ -922,32 +922,32 @@ typedef struct ivas_masa_decoder_struct /* Data structure for MASA_ISM rendering */ typedef struct ivas_masa_ism_data_structure { - int16_t azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; - int16_t elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; Word32 energy_ratio_ism_fx[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX]; /* Q30 */ Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ - int16_t azimuth_ism_edited[MAX_NUM_OBJECTS]; - int16_t elevation_ism_edited[MAX_NUM_OBJECTS]; - uint8_t ism_is_edited[MAX_NUM_OBJECTS]; + Word16 azimuth_ism_edited[MAX_NUM_OBJECTS]; + Word16 elevation_ism_edited[MAX_NUM_OBJECTS]; + UWord8 ism_is_edited[MAX_NUM_OBJECTS]; - int16_t idx_separated_ism; - int16_t azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; - int16_t elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 idx_separated_ism; + Word16 azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; Word32 q_azimuth_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ Word32 q_elevation_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ Word16 ismPreprocMatrix_fx[2][2][CLDFB_NO_CHANNELS_MAX]; /* Q15 */ - uint8_t objectsMoved; + UWord8 objectsMoved; Word32 eneMoveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ Word32 enePreserveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ Word32 preprocEneTarget_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ Word32 preprocEneRealized_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ Word32 **delayBuffer_fx; /* Q11 */ - int16_t delayBuffer_size; - int16_t delayBuffer_nchan; + Word16 delayBuffer_size; + Word16 delayBuffer_nchan; } MASA_ISM_DATA, *MASA_ISM_DATA_HANDLE; @@ -965,41 +965,41 @@ typedef struct decoder_tc_buffer_structure Word16 no_channels; /*Stores no of channels in tc_fx with values*/ #endif Word16 q_tc_fx; - TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ - int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ - int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ - int16_t nchan_buffer_full; /* number of channels to be fully buffered */ - int16_t n_samples_available; /* samples still available for rendering in the current frame */ - int16_t n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ - int16_t n_samples_rendered; /* samples already rendered in the current frame */ - int16_t n_samples_granularity; /* render granularity */ - int16_t n_samples_flushed; - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; - int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ + TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ + Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ + Word16 nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ + Word16 nchan_buffer_full; /* number of channels to be fully buffered */ + Word16 n_samples_available; /* samples still available for rendering in the current frame */ + Word16 n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ + Word16 n_samples_rendered; /* samples already rendered in the current frame */ + Word16 n_samples_granularity; /* render granularity */ + Word16 n_samples_flushed; + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; + Word16 n_samples_discard; /* number of samples to discard from the beginning of the output */ } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; typedef struct jbm_metadata_structure { - int16_t sf_write_idx; - int16_t sf_md_buffer_length; + Word16 sf_write_idx; + Word16 sf_md_buffer_length; - uint16_t directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ + UWord16 directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ - int16_t slot_read_idx; - int16_t slot_write_idx; - int16_t slot_md_buffer_length; + Word16 slot_read_idx; + Word16 slot_write_idx; + Word16 slot_md_buffer_length; - int16_t sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; + Word16 sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; } JBM_METADATA, *JBM_METADATA_HANDLE; @@ -1010,25 +1010,25 @@ typedef struct jbm_metadata_structure typedef struct decoder_config_structure { - int32_t ivas_total_brate; /* IVAS total bitrate in bps */ - int32_t last_ivas_total_brate; /* last IVAS total bitrate in bps */ - int32_t output_Fs; /* output signal sampling frequency in Hz */ - int16_t nchan_out; /* number of output audio channels */ + Word32 ivas_total_brate; /* IVAS total bitrate in bps */ + Word32 last_ivas_total_brate; /* last IVAS total bitrate in bps */ + Word32 output_Fs; /* output signal sampling frequency in Hz */ + Word16 nchan_out; /* number of output audio channels */ AUDIO_CONFIG output_config; /* output audio configuration */ - int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ - int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ - int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ - int16_t Opt_RendConfigCustom; /* indicates whether Renderer configuration custom setup is used */ + Word16 Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ + Word16 Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ + Word16 Opt_Headrotation; /* indicates whether head-rotation is used */ + Word16 Opt_RendConfigCustom; /* indicates whether Renderer configuration custom setup is used */ IVAS_HEAD_ORIENT_TRK_T orientation_tracking; /* indicates orientation tracking type */ - int16_t Opt_non_diegetic_pan; /* indicates diegetic or not */ + Word16 Opt_non_diegetic_pan; /* indicates diegetic or not */ Word16 non_diegetic_pan_gain_fx; /* non diegetic panning gain*/ /* Q15 */ - int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - int16_t Opt_ExternalOrientation; /* indiates whether external orientations are used */ - int16_t Opt_dpid_on; /* indicates whether Directivity pattern option is used */ - int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ - int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_ExternalOrientation; /* indiates whether external orientations are used */ + Word16 Opt_dpid_on; /* indicates whether Directivity pattern option is used */ + Word16 Opt_aeid_on; /* indicates whether Acoustic environment option is used */ + Word16 Opt_tsm; /* indicates whether time scaling modification is activated */ IVAS_RENDER_FRAMESIZE render_framesize; - int16_t Opt_delay_comp; /* flag indicating delay compensation active */ + Word16 Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; @@ -1047,8 +1047,8 @@ typedef struct Decoder_Struct IVAS_FORMAT ivas_format; /* IVAS format */ IVAS_FORMAT last_ivas_format; /* last frame IVAS format */ - int16_t sid_format; /* IVAS format indicator from SID frame */ - int16_t nchan_transport; /* number of transport channels */ + Word16 sid_format; /* IVAS format indicator from SID frame */ + Word16 nchan_transport; /* number of transport channels */ IVAS_OUTPUT_SETUP hOutSetup; /* output setup structure */ AUDIO_CONFIG intern_config; /* internal audio configuration */ IVAS_OUTPUT_SETUP hIntSetup; /* internal setup structure */ @@ -1056,24 +1056,24 @@ typedef struct Decoder_Struct AUDIO_CONFIG transport_config; /* transport audio configuration */ IVAS_OUTPUT_SETUP hTransSetup; /* transport setup structure */ - int16_t element_mode_init; /* element mode used at initialization */ - int16_t codec_mode; /* Mode 1 or 2 */ - int16_t ini_frame; /* initialization frames counter */ - int16_t ini_active_frame; /* initialization active frames counter */ + Word16 element_mode_init; /* element mode used at initialization */ + Word16 codec_mode; /* Mode 1 or 2 */ + Word16 ini_frame; /* initialization frames counter */ + Word16 ini_active_frame; /* initialization active frames counter */ - int16_t bfi; /* FEC - bad frame indicator */ - int16_t BER_detect; /* BER detect flag */ - int16_t num_bits; /* BER detect flag */ + Word16 bfi; /* FEC - bad frame indicator */ + Word16 BER_detect; /* BER detect flag */ + Word16 num_bits; /* BER detect flag */ - uint16_t *bit_stream; /* Pointer to bitstream buffer */ - int16_t writeFECoffset; /* parameter for debugging JBM stuff */ + UWord16 *bit_stream; /* Pointer to bitstream buffer */ + Word16 writeFECoffset; /* parameter for debugging JBM stuff */ IVAS_LIMITER_HANDLE hLimiter; /* Limiter handle */ /* core-decoder modules */ - int16_t nSCE; /* number of total SCEs */ - int16_t nCPE; /* number of total CPEs */ - int16_t nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ + Word16 nSCE; /* number of total SCEs */ + Word16 nCPE; /* number of total CPEs */ + Word16 nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ SCE_DEC_HANDLE hSCE[MAX_SCE]; /* SCE handles */ CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS]; /* CPE handles */ @@ -1092,12 +1092,12 @@ typedef struct Decoder_Struct LFE_DEC_HANDLE hLFE; /* LFE handle */ ISM_MODE ism_mode; /* ISM format mode */ - int16_t nchan_ism; /* number of ISM channels */ + Word16 nchan_ism; /* number of ISM channels */ MC_MODE mc_mode; /* MC format mode */ - int16_t sba_order; /* Ambisonic (SBA) order */ - int16_t sba_planar; /* Ambisonic (SBA) planar flag */ - int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ - int16_t sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ + Word16 sba_order; /* Ambisonic (SBA) order */ + Word16 sba_planar; /* Ambisonic (SBA) planar flag */ + Word16 sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ + Word16 sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ /* rendering modules */ RENDERER_TYPE renderer_type; /* renderer type */ @@ -1120,7 +1120,7 @@ typedef struct Decoder_Struct Word32 *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */ RENDER_CONFIG_DATA *hRenderConfig; /* Renderer config pointer */ - int32_t binaural_latency_ns; /* Binauralization latency in ns */ + Word32 binaural_latency_ns; /* Binauralization latency in ns */ EXTERNAL_ORIENTATION_HANDLE hExtOrientationData; /* External orientation data structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; /* Combined external and head orientation data structure */ DIRAC_REND_HANDLE hDirACRend; /* DirAC renderer handle */ @@ -1128,16 +1128,16 @@ typedef struct Decoder_Struct MASA_ISM_DATA_HANDLE hMasaIsmData; /* OMASA rendering handle */ SBA_ISM_DATA_HANDLE hSbaIsmData; /* OSBA rendering handle */ - int16_t flag_omasa_brate; + Word16 flag_omasa_brate; /* JBM module */ DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */ JBM_METADATA_HANDLE hJbmMetadata; /* Structure for metadata buffering in JBM */ - int32_t last_active_ivas_total_brate; - int16_t ism_extmeta_active; /* Extended metadata active in decoder */ - int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ + Word32 last_active_ivas_total_brate; + Word16 ism_extmeta_active; /* Extended metadata active in decoder */ + Word16 ism_extmeta_cnt; /* Change frame counter for extended metadata */ Word32 **mem_hp20_out_fx; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* Word32-output audio buffers */ Word16 p_out_len;/*Stores the total no of channels for which memory is allocated to p_output_fx*/ diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 2dd2a30c3..e5e18083d 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -2078,7 +2078,7 @@ void stereo_td2dft_update_fx( ) { Word16 ovl, ovl_TCX, dft32ms_ovl, hq_delay_comp; - Word16 ns, nsLB; + Word16 ns, nsLB, i; Word16 old_out_len, old_outLB_len; Decoder_State **sts; @@ -2181,9 +2181,9 @@ void stereo_td2dft_update_fx( v_add_fx( sts[0]->hHQ_core->old_outLB_fx + nsLB, sts[1]->hHQ_core->old_outLB_fx + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, STEREO_MDCT2DFT_FADE_LEN_48k, old_outLB_len ); #ifndef MSAN_FIX - for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) + for ( i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else - FOR( Word32 i = 0; i < old_outLB_len; i++ ) + FOR( i = 0; i < old_outLB_len; i++ ) #endif { hCPE->old_outLB_mdct_fx[i] = L_shr( hCPE->old_outLB_mdct_fx[i], 1 ); /* Q11 */ @@ -2193,7 +2193,7 @@ void stereo_td2dft_update_fx( #ifndef MSAN_FIX for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else - FOR( Word32 i = 0; i < old_out_len; i++ ) + FOR( i = 0; i < old_out_len; i++ ) #endif { hCPE->old_out_mdct_fx[i] = L_shr( hCPE->old_out_mdct_fx[i], 1 ); /* q_old_out_mdct */ diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index bb73fe7f0..375dbdad0 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -306,7 +306,6 @@ Word16 svd_fx( Word16 iCh, jCh; Word16 lengthSingularValues; Word16 errorMessage, condition; - // int16_t max_length = ((nChannelsL > nChannelsC) ? nChannelsL : nChannelsC); Word32 secDiag_fx[MAX_OUTPUT_CHANNELS]; #ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 secDiag_fx_e = 0; diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 939fad2cb..5b5ff16c5 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -67,7 +67,7 @@ struct JB4_DATAUNIT Word16 qBit; /** the binary encoded access unit */ - uint8_t *data; + UWord8 *data; /** the size of the binary encoded access unit [bits] */ UWord16 dataSize; diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 1fe7481df..7955d0ea6 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -92,7 +92,7 @@ typedef struct apa_state_t *PCMDSP_APA_HANDLE; /*! Allocates memory for state struct and initializes elements. * @return 0 on success, 1 on failure */ ivas_error apa_init( apa_state_t **s, - const int32_t num_channels ); + const Word32 num_channels ); /*! Sets state variables to initial value. */ void apa_reset( apa_state_t *s ); @@ -106,7 +106,7 @@ void apa_reset( apa_state_t *s ); * @param[in] output_Fs sample rate [Hz] * @param[in] num_channels number of channels * @return 0 on success, 1 on failure */ -bool apa_set_rate( apa_state_t *ps, const int32_t output_Fs ); +bool apa_set_rate( apa_state_t *ps, const Word32 output_Fs ); /*! Set scaling. * The scale is given in % and will be valid until changed again. @@ -120,7 +120,7 @@ bool apa_set_renderer_residual_samples( apa_state_t *ps, UWord16 l_r_buf ); bool apa_set_evs_compat_mode( apa_state_t *ps, bool mode ); -uint8_t apa_reconfigure( apa_state_t *ps, uint16_t num_channels, uint16_t l_ts ); +UWord8 apa_reconfigure( apa_state_t *ps, UWord16 num_channels, UWord16 l_ts ); bool apa_set_complexity_options( apa_state_t *s, UWord16 wss, UWord16 css ); @@ -129,5 +129,5 @@ bool apa_set_quality( apa_state_t *s, Word32 quality, UWord16 qualityred, UWord1 bool apa_exit( apa_state_t **s ); UWord8 apa_exec_ivas_fx( apa_state_t *s, const Word32 a_in[], UWord16 l_in, UWord16 maxScaling, Word32 a_out[], UWord16 *l_out ); -uint8_t apa_exec_fx( apa_state_t *s, const Word16 a_in[], UWord16 l_in, UWord16 maxScaling, Word16 a_out[], UWord16 *l_out ); +UWord8 apa_exec_fx( apa_state_t *s, const Word16 a_in[], UWord16 l_in, UWord16 maxScaling, Word16 a_out[], UWord16 *l_out ); #endif /* JBM_PCMDSP_APA_H */ diff --git a/lib_dec/jbm_pcmdsp_window.h b/lib_dec/jbm_pcmdsp_window.h index 3551380de..1d193433e 100644 --- a/lib_dec/jbm_pcmdsp_window.h +++ b/lib_dec/jbm_pcmdsp_window.h @@ -52,7 +52,7 @@ * <------> * n */ -void hannWindow( uint16_t n, float *w ); +void hannWindow( UWord16 n, float *w ); /** Overlap/Add of two signal with a given window. */ /** @param[in] fadeOut signal to fade out diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index 5a3aec3f4..976826949 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -612,7 +612,7 @@ void amr_wb_enc_init_fx( AMRWB_IO_ENC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO encoder handle */ ) { - int16_t i; + Word16 i; /* HF (6-7kHz) BWE */ hAmrwb_IO->seed2_enc = RANDOM_INITSEED; diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 93a0146f3..962b715cd 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -519,7 +519,7 @@ void AVQ_encmux_fx( bit_tmp = add( unusedbitsFlag, unused_bits_idx ); /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ nq_est = mult( 6554, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); - assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); if ( EQ_16( nq_est, 1 ) ) { @@ -946,7 +946,7 @@ void AVQ_encmux_ivas_fx( bit_tmp = add( unusedbitsFlag, unused_bits_idx ); /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ nq_est = mult( 6554 /*.2 in Q15*/, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); - assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); if ( EQ_16( nq_est, 1 ) ) { @@ -1085,8 +1085,8 @@ static void wrte_cv( Word16 *nbits /* i/o: bits */ ) { - int16_t pos, j; - int16_t bits, nq4; + Word16 pos, j; + Word16 bits, nq4; bits = *nbits; move16(); @@ -1145,8 +1145,8 @@ static void wrte_cv_ivas_fx( Word16 *nbits /* i/o: bits */ ) { - int16_t pos, j; - int16_t bits, nq4; + Word16 pos, j; + Word16 bits, nq4; bits = *nbits; move16(); diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index a2995245d..1c60f2ecd 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -30,8 +30,8 @@ static void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, co static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); static void init_core_sig_ana_ivas_fx( Encoder_State *st ); static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ); -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ); +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const Word32 last_total_brate ); +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const Word32 last_total_brate ); /*-----------------------------------------------------------------------* * init_coder_ace_plus_fx() @@ -1324,7 +1324,7 @@ static void init_tcx_ivas_fx( * Initialization of signal buffers *-----------------------------------------------------------------------*/ /*copy of evs function since it was static */ -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ) +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const Word32 last_total_brate ) { LPD_state_HANDLE hLPDmem = st->hLPDmem; @@ -1542,7 +1542,7 @@ static void init_core_sig_ana_ivas_fx( Encoder_State *st ) * * *-----------------------------------------------------------------------*/ -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ) +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const Word32 last_total_brate ) { Word16 mem_syn_r_size_old; Word16 mem_syn_r_size_new; diff --git a/lib_enc/core_enc_reconf_fx.c b/lib_enc/core_enc_reconf_fx.c index 3637dd53f..1ba496b0e 100644 --- a/lib_enc/core_enc_reconf_fx.c +++ b/lib_enc/core_enc_reconf_fx.c @@ -344,7 +344,7 @@ void core_coder_reconfig_fx( void core_coder_reconfig_ivas_fx( Encoder_State *st, - const int32_t last_total_brate ) + const Word32 last_total_brate ) { Word16 i, bwidth, index; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; diff --git a/lib_enc/enc_acelp_fx.c b/lib_enc/enc_acelp_fx.c index 7dd342318..a509a7cd7 100644 --- a/lib_enc/enc_acelp_fx.c +++ b/lib_enc/enc_acelp_fx.c @@ -1761,7 +1761,7 @@ void E_ACELP_4t_fx( const Word16 last_L_frame, /*Q0*/ const Word32 total_brate, /*Q0*/ const Word16 i_subfr, /*Q0*/ - const int16_t cmpl_flag /*Q0*/ ) + const Word16 cmpl_flag /*Q0*/ ) { PulseConfig config; Word16 ind[NPMAXPT * 4]; @@ -1824,7 +1824,7 @@ void E_ACELP_4t_ivas_fx( const Word16 last_L_frame, /*Q0*/ const Word32 total_brate, /*Q0*/ const Word16 i_subfr, /*Q0*/ - const int16_t cmpl_flag, /*Q0*/ + const Word16 cmpl_flag, /*Q0*/ Word16 element_mode /*Q0*/ ) { PulseConfig config; diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index a36ee78e2..4305e5bca 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -216,7 +216,7 @@ ivas_error ivas_ism_metadata_enc_fx( move16(); Word32 valQ_fx; ISM_METADATA_HANDLE hIsmMetaData; - int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; + Word32 element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; Word16 ism_metadata_flag_global; Word16 non_diegetic_flag_global; Word16 ism_imp[MAX_NUM_OBJECTS]; diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index bb6ef0d01..c4d3908ca 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -574,7 +574,7 @@ ivas_error ivas_mcmasa_enc_reconfig_fx( void ivas_mcmasa_enc_close_fx( MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */ - const int32_t input_Fs /* i : input sampling rate */ + const Word32 input_Fs /* i : input sampling rate */ ) { Word16 i, j; diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 55da30e73..d6bc4c7f0 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -421,7 +421,7 @@ ivas_error ivas_mct_enc_fx( } /* joint MCT encoding */ - ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (int16_t) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); + ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (Word16) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 403d379fa..70b2b0034 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -799,7 +799,7 @@ static void applyStereoPreProcessingCplx( * * encoder-side complex-valued stereo pre-processing (crosstalk) *---------------------------------------------------------------*/ -static uint16_t enc_ste_pre_mdct( +static UWord16 enc_ste_pre_mdct( Word32 *sigR0_fx, /* i/o: MDCT samples of the 1st (left) channel q_com*/ Word32 *sigR1_fx, /* i/o: MDCT samples of the 2nd (right) channel q_com*/ Word32 *sigI0_fx, /* i/o: MDST samples of the 1st (left) channel q_com*/ diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 3416ab279..b32c80404 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -160,7 +160,7 @@ static Word16 encode_coherence_indexesDCT1_fx( BSTR_ENC_HANDLE hMetaData /* i : metadata handle */ ); -static UWord64 create_combined_index_fx( uint16_t *idx_dct, const Word16 len, const Word16 *no_cb_vec ); +static UWord64 create_combined_index_fx( UWord16 *idx_dct, const Word16 len, const Word16 *no_cb_vec ); static Word16 encode_surround_coherence_fx( IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ @@ -184,7 +184,7 @@ static void ivas_diffuseness_huff_ec_prepare_fx( UWord16 *avr_idx, Word16 *diffuseness_bits_huff ); -static Word16 coherence_coding_length( const uint16_t *idx_sur_coh_shift, const UWord8 idx_shift_len, const Word16 coding_subbands, const Word16 *no_cv, uint16_t *mr_idx, Word16 *no_cv_shift, Word16 *p_min_idx, Word16 *GR_ord, Word16 *nbits_fr, Word16 *nbits_fr1 ); +static Word16 coherence_coding_length( const UWord16 *idx_sur_coh_shift, const UWord8 idx_shift_len, const Word16 coding_subbands, const Word16 *no_cv, UWord16 *mr_idx, Word16 *no_cv_shift, Word16 *p_min_idx, Word16 *GR_ord, Word16 *nbits_fr, Word16 *nbits_fr1 ); static Word16 write_2dir_info( BSTR_ENC_HANDLE hMetaData, UWord8 *twoDirBands, const Word16 n, const Word16 k ); @@ -2326,7 +2326,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( move16(); UWord16 dist_elevation_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; Word16 gr_param_azimuth_best, avg_azimuth_index_best; - uint16_t dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; UWord16 idx, dist_count; Word16 direction_bits_ec; diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e6038186e..e321f1c7c 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -60,7 +60,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - Word16 index; + Word16 index, i; const Word16 split_len = M / 2; move16(); const Word16 *means; @@ -85,7 +85,7 @@ static Word16 sns_1st_cod_fx( Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; move16(); move16(); - FOR( Word16 i = 0; i < M; ++i ) + FOR( i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 exp_snsq_buffer[i] = 0; @@ -93,11 +93,11 @@ static Word16 sns_1st_cod_fx( snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); move32(); } - FOR( int i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); } - FOR( int i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); @@ -121,7 +121,7 @@ static Word16 sns_1st_cod_fx( dist_min_fx = MAXVAL_WORD32; Word16 exp_dist_min = 31; index_split = 0; - FOR( Word16 i = 0; i < 32; ++i ) + FOR( i = 0; i < 32; ++i ) { Word32 dist_fx = 0; move32(); diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 925f4e702..2ace35473 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -1665,7 +1665,7 @@ static void ivas_write_parameter_bitstream_dtx_fx( Word16 *num_dec, const Word16 num_bands ) { - int16_t i, j; + Word16 i, j; Word32 val; Word16 idx; Word32 pr_min_max[2]; diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 3f7237ce5..ede3d3ad9 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -3302,8 +3302,8 @@ static void stereo_dft_enc_compute_prm_fx( Word32 *dot_prod_nrg_ratio_fx, // Q(31-dot_prod_nrg_ratio_fx_e[]) Word16 *dot_prod_nrg_ratio_fx_e ) { - int16_t b, i; - int16_t b2; + Word16 b, i; + Word16 b2; Word32 *pDFT_L, *pDFT_R; // Word16 DFT_L_e, DFT_R_e; Word32 sum_nrg_L, sum_nrg_R; @@ -3352,7 +3352,7 @@ static void stereo_dft_enc_compute_prm_fx( Word16 sum_past_dot_prod_abs_e, sum_past_dot_prod_abs2_e = 0; Word32 sum_past_nrg_dmx; Word16 sum_past_nrg_dmx_e; - int16_t pos; + Word16 pos; Word32 pIpd[STEREO_DFT_BAND_MAX]; // Q13 Word32 ipd_smooth[STEREO_DFT_BAND_MAX]; // Q13 Word32 ipd_mean_change; // Q13 diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index f8d600276..979978c03 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -1006,9 +1006,8 @@ void stereo_tdm_prep_dwnmx_fx( const Word16 input_q /* i : frame lenght */ ) { -#define USER_ENER Word32 mener; - int16_t i, sw_pos, enr_len; + Word16 i, sw_pos, enr_len; Encoder_State **sts; Word16 mener_e; sts = hCPE->hCoreCoder; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 211c53f8c..9d4736368 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -59,8 +59,8 @@ struct IVAS_ENC bool cmd_stereo; #endif bool switchingActive; /* flag for configuration changes during encoding - currently only used with mono */ - int16_t Opt_RF_ON_loc; - int16_t rf_fec_offset_loc; + Word16 Opt_RF_ON_loc; + Word16 rf_fec_offset_loc; bool ismMetadataProvided[MAX_NUM_OBJECTS]; bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ IVAS_ENC_BANDWIDTH newBandwidthApi; /* maximum encoded bandwidth, as set on API level */ @@ -77,14 +77,14 @@ static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); static ivas_error sanitizeBitrateISM_fx( const ENCODER_CONFIG_HANDLE hEncoderConfig, const bool extMetadataApi ); static Word16 getInputBufferSize_fx( const Encoder_Struct *st_ivas ); -static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, const int32_t inputFs, const int32_t initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); -static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, const int32_t totalBitrate ); +static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, const Word32 totalBitrate ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig ); static void resetIsmMetadataProvidedFlags( IVAS_ENC_HANDLE hIvasEnc ); -static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, int16_t *internalMaxBandwidth ); -static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, int16_t *fecIndicatorInternal ); +static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, Word16 *internalMaxBandwidth ); +static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, Word16 *fecIndicatorInternal ); #ifdef DEBUGGING static ivas_error forcedModeApiToInternal( IVAS_ENC_FORCED_MODE forcedMode, int16_t *forcedModeInternal ); #endif @@ -276,8 +276,8 @@ void IVAS_ENC_Close( ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -296,7 +296,7 @@ ivas_error IVAS_ENC_ConfigureForMono( } hIvasEnc->st_ivas->hEncoderConfig->ivas_format = MONO_FORMAT; - hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (int16_t) is_binaural; + hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (Word16) is_binaural; if ( downmixFromStereo ) { @@ -318,8 +318,8 @@ ivas_error IVAS_ENC_ConfigureForMono( ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -344,7 +344,7 @@ ivas_error IVAS_ENC_ConfigureForStereo( hEncoderConfig = st_ivas->hEncoderConfig; hEncoderConfig->nchan_inp = 2; hEncoderConfig->ivas_format = STEREO_FORMAT; - hEncoderConfig->is_binaural = (int16_t) is_binaural; + hEncoderConfig->is_binaural = (Word16) is_binaural; #ifdef DEBUGGING switch ( stereoMode ) @@ -458,12 +458,12 @@ ivas_error IVAS_ENC_ConfigureForMASAObjects( ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */ ) { @@ -503,7 +503,7 @@ ivas_error IVAS_ENC_ConfigureForObjects( ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const uint16_t ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ) { @@ -551,8 +551,8 @@ ivas_error IVAS_ENC_FeedObjectMetadata( ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -580,7 +580,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->nchan_inp = ivas_sba_get_nchan_fx( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ - hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; + hEncoderConfig->Opt_PCA_ON = (Word16) Opt_PCA_ON; hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -780,8 +780,8 @@ ivas_error IVAS_ENC_FeedMasaMetadata( ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -841,8 +841,8 @@ ivas_error IVAS_ENC_ConfigureForMultichannel( static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, - const int32_t inputFs, - const int32_t initBitrate, + const Word32 inputFs, + const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ) @@ -850,7 +850,7 @@ static ivas_error configureEncoder( Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; ivas_error error; - int32_t cpe_brate; + Word32 cpe_brate; error = IVAS_ERR_OK; @@ -1476,7 +1476,7 @@ static Word16 getInputBufferSize_fx( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ) { if ( hIvasEnc == NULL || numInChannels == NULL ) @@ -1824,8 +1824,8 @@ ivas_error IVAS_ENC_SetBandwidth( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_SetBitrate( - IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t totalBitrate /* i : requested bitrate of the output bitstream */ + IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ) { ivas_error error; @@ -2003,11 +2003,11 @@ const char *IVAS_ENC_GetErrorMessage( static ivas_error printConfigInfo_enc( IVAS_ENC_HANDLE hIvasEnc, - const int16_t channelAwareModeEnabled ) + const Word16 channelAwareModeEnabled ) { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t newBandwidthApi; + Word16 newBandwidthApi; ivas_error error; st_ivas = hIvasEnc->st_ivas; @@ -2237,7 +2237,7 @@ static ivas_error printConfigInfo_enc( static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, - const int32_t totalBitrate ) + const Word32 totalBitrate ) { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; @@ -2753,8 +2753,8 @@ static ivas_error forcedModeApiToInternal( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_PrintConfig( - const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - const int16_t channelAwareModeEnabled /* i : channel-aware mode enabled flag */ + const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + const Word16 channelAwareModeEnabled /* i : channel-aware mode enabled flag */ ) { return printConfigInfo_enc( hIvasEnc, channelAwareModeEnabled ); diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 4911711d7..ab6c39c23 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -68,7 +68,7 @@ typedef struct _IVAS_ENC_DTX_CONFIG { bool enabled; bool variable_SID_rate; - int16_t SID_interval; + Word16 SID_interval; } IVAS_ENC_DTX_CONFIG; typedef enum _IVAS_ENC_SBA_ORDER @@ -169,8 +169,8 @@ ivas_error IVAS_ENC_Open_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -182,8 +182,8 @@ ivas_error IVAS_ENC_ConfigureForMono( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -197,34 +197,34 @@ ivas_error IVAS_ENC_ConfigureForStereo( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMASAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ - const int16_t masaVariant /* i : index specifying the number of MASA transport channels */ + const UWord16 numObjects, /* i : number of objects to be encoded */ + const Word16 masaVariant /* i : index specifying the number of MASA transport channels */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForSBAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ 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_PCA_ON /* i : PCA option flag */ @@ -233,8 +233,8 @@ ivas_error IVAS_ENC_ConfigureForSBAObjects( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -245,8 +245,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -257,8 +257,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMasa( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -268,8 +268,8 @@ ivas_error IVAS_ENC_ConfigureForMasa( /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -285,7 +285,7 @@ void IVAS_ENC_Close( /*! r: error code */ ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const uint16_t ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ); @@ -307,10 +307,10 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( /*! r: error code */ ivas_error IVAS_ENC_EncodeFrameToCompact( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *inputBuffer, /* i : PCM input */ - const int16_t inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ - uint8_t *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ - uint16_t *numOutBits /* o : number of bits written to output bitstream */ + Word16 *inputBuffer, /* i : PCM input */ + const Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ + UWord8 *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ + UWord16 *numOutBits /* o : number of bits written to output bitstream */ ); /* Setter functions - apply changes to encoder configuration */ @@ -324,7 +324,7 @@ ivas_error IVAS_ENC_SetBandwidth( /*! r: error code */ ivas_error IVAS_ENC_SetBitrate( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t totalBitrate /* i : requested bitrate of the output bitstream */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ); /*! r: error code */ @@ -355,13 +355,13 @@ ivas_error IVAS_ENC_GetDelay( /*! r: encoder error code */ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_GetInputBufferSize( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /* Utility functions */ @@ -388,7 +388,7 @@ const char *IVAS_ENC_GetErrorMessage( ivas_error IVAS_ENC_PrintConfig( const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - const int16_t channelAwareModeEnabled /* i : channel-aware mode enabled flag */ + const Word16 channelAwareModeEnabled /* i : channel-aware mode enabled flag */ ); void IVAS_ENC_PrintDisclaimer( diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index a61b2ebff..24179f375 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -31,9 +31,9 @@ static Word32 vq_lvq_lsf_enc( Word16 pred_flag, Word16 mode, Word16 u[], Word16 static Word32 vq_lvq_lsf_enc_ivas_fx( Word16 pred_flag, Word16 mode, Word16 u[], Word16 *levels, Word16 stages, Word16 w[], Word16 Idx[], const Word16 *lsf, const Word16 *pred, Word16 *resq, Word16 *lsfq ); -static void lsf_mid_enc_fx( BSTR_ENC_HANDLE hBstr, int16_t nb_bits, const Word16 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word32 Bin_Ener[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); +static void lsf_mid_enc_fx( BSTR_ENC_HANDLE hBstr, Word16 nb_bits, const Word16 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word32 Bin_Ener[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); -static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, int16_t nb_bits, const Word32 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); +static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, Word16 nb_bits, const Word32 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); /*===========================================================================*/ /* FUNCTION : lsf_enc_fx() */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 7f58a9501..28e1a39de 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -366,7 +366,7 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */ const Word32 *u_fx, /* i : target signal */ const Word16 u_e, /* i : exp for target signal */ - const int16_t maxC_st1, /* i : number of candidates in stage1 */ + const Word16 maxC_st1, /* i : number of candidates in stage1 */ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */ ) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 02f8344d1..10d020ee3 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -143,7 +143,7 @@ void bw_detect_fx( const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ + const Word16 mct_on /* i : flag MCT mode */ ); void core_switching_post_enc_fx( /*done */ @@ -627,7 +627,7 @@ void swb_bwe_enc_fx( void swb_bwe_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ + const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ @@ -1585,7 +1585,7 @@ void E_ACELP_4t_ivas_fx( const Word16 last_L_frame, const Word32 total_brate, const Word16 i_subfr, - const int16_t cmpl_flag, + const Word16 cmpl_flag, Word16 element_mode ); void E_ACELP_innovative_codebook_fx( @@ -3077,15 +3077,15 @@ void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state #ifdef MSAN_FIX Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ #endif - const int16_t igfGridIdx, /* i : IGF grid index */ - Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ - Word16 e_mdct, /* i : exponent of pMDCTspectrum */ - Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 *e_ps, /* i : exponent of pPowerSpectrum */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int8_t isTNSActive, /* i : flag indicating if the TNS is active */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ + const Word16 igfGridIdx, /* i : IGF grid index */ + Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ + Word16 e_mdct, /* i : exponent of pMDCTspectrum */ + Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 *e_ps, /* i : exponent of pPowerSpectrum */ + const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ + const Word8 isTNSActive, /* i : flag indicating if the TNS is active */ + const Word16 sp_aud_decision0, /* i : first stage switching decision */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ ); void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index ad572d2ba..41c6b0468 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -51,9 +51,9 @@ typedef struct { - int16_t id; /* id of the indice */ - uint16_t value; /* value of the quantized indice */ - int16_t nb_bits; /* number of bits used for the quantization of the indice */ + Word16 id; /* id of the indice */ + UWord16 value; /* value of the quantized indice */ + Word16 nb_bits; /* number of bits used for the quantization of the indice */ } Indice, *INDICE_HANDLE; typedef struct @@ -84,12 +84,12 @@ typedef struct typedef struct bitstream_enc_data_structure { - int16_t nb_ind_tot; /* total number of indices already written */ - int16_t nb_bits_tot; /* total number of bits already written */ - Indice *ind_list; /* list of indices */ - int16_t *ivas_max_num_indices; /* maximum total number of indices in the list */ - Indice **ivas_ind_list_zero; /* beginning of the buffer of indices */ - void *st_ivas; /* IVAS encoder structure */ + Word16 nb_ind_tot; /* total number of indices already written */ + Word16 nb_bits_tot; /* total number of bits already written */ + Indice *ind_list; /* list of indices */ + Word16 *ivas_max_num_indices; /* maximum total number of indices in the list */ + Indice **ivas_ind_list_zero; /* beginning of the buffer of indices */ + void *st_ivas; /* IVAS encoder structure */ // Word16 nb_bits_tot_fx; /* total number of bits already written */ // Indice *ind_list_fx; /* list of indices */ Word16 next_ind_fx; /* pointer to the next empty slot in the list of indices */ @@ -128,9 +128,9 @@ typedef struct signal_buffers_enc_data_structure /* Delay buffer: Used to buffer input samples and to define the subblock size of a transient detector. */ typedef struct { - int16_t nSubblockSize; /* Subblock size of a transient detector that uses this delay buffer. */ + Word16 nSubblockSize; /* Subblock size of a transient detector that uses this delay buffer. */ Word16 buffer[L_FRAME48k / NSUBBLOCKS]; - int16_t nDelay; /* Size of the delay buffer in use. Maximum delay from all users of this buffer. */ + Word16 nDelay; /* Size of the delay buffer in use. Maximum delay from all users of this buffer. */ } DelayBuffer; @@ -141,8 +141,8 @@ typedef struct Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ /* IVAS: Q3 */ - int16_t nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ - int16_t nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ + Word16 nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ + Word16 nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ /* Decay factor for the recursive accumulation */ Word16 facAccSubblockNrg; @@ -152,27 +152,25 @@ typedef struct Word16 firState2; Word16 q_firState; - uint16_t ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */ + UWord16 ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */ } SubblockEnergies; /* Attack detection function. */ -typedef void ( *TCheckSubblocksForAttack )( const float *pSubblockNrg, const float *pAccSubblockNrg, int16_t nSubblocks, int16_t nPastSubblocks, float attackRatioThreshold, int16_t *pbIsAttackPresent, int16_t *pAttackIndex ); typedef void ( *TCheckSubblocksForAttack_fx )( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ); /* Transient detector. */ typedef struct TransientDetector { SubblockEnergies *pSubblockEnergies; /* Subblock energies used in this transient detector. */ - int16_t nDelay; /* Delay of the transient detector in number of subblocks, nDelay <= pSubblockEnergies->nDelay. */ - int16_t nSubblocksToCheck; /* Number of subblocks to check for transients. */ - TCheckSubblocksForAttack CheckSubblocksForAttack; /* Function for checking a presence of an attack. */ + Word16 nDelay; /* Delay of the transient detector in number of subblocks, nDelay <= pSubblockEnergies->nDelay. */ + Word16 nSubblocksToCheck; /* Number of subblocks to check for transients. */ TCheckSubblocksForAttack_fx CheckSubblocksForAttack_fx; /* Function for checking a presence of an attack. */ Word16 attackRatioThreshold; /* Attack ratio threshold Q11 */ - int16_t bIsAttackPresent; /* True when an attack was detected. */ - int16_t prev_bIsAttackPresent; /* True if an attack was detected in the previous frame. */ - int16_t attackIndex; /* The index of an attack. */ + Word16 bIsAttackPresent; /* True when an attack was detected. */ + Word16 prev_bIsAttackPresent; /* True if an attack was detected in the previous frame. */ + Word16 attackIndex; /* The index of an attack. */ } TransientDetector; /* Transient detection: Holds all transient detectors and buffers used by them. */ @@ -191,25 +189,25 @@ typedef struct TransientDetection_structure typedef struct vad_structure { - int16_t nb_active_frames; - int16_t hangover_cnt; - int16_t nb_active_frames_he; - int16_t hangover_cnt_he; - int32_t vad_flag_reg_H; - int32_t vad_flag_reg_L; - int32_t vad_prim_reg; - - int16_t vad_flag_cnt_50; - int16_t vad_prim_cnt_16; - - int16_t hangover_cnt_dtx; - int16_t hangover_cnt_music; + Word16 nb_active_frames; + Word16 hangover_cnt; + Word16 nb_active_frames_he; + Word16 hangover_cnt_he; + Word32 vad_flag_reg_H; + Word32 vad_flag_reg_L; + Word32 vad_prim_reg; + + Word16 vad_flag_cnt_50; + Word16 vad_prim_cnt_16; + + Word16 hangover_cnt_dtx; + Word16 hangover_cnt_music; Word16 bcg_flux_fx; // Q4 - int16_t soft_hangover; - int16_t voiced_burst; - int16_t bcg_flux_init; - int16_t nb_active_frames_he1; - int16_t hangover_cnt_he1; + Word16 soft_hangover; + Word16 voiced_burst; + Word16 bcg_flux_init; + Word16 nb_active_frames_he1; + Word16 hangover_cnt_he1; Word16 prim_act_quick_fx; /*Q15 */ /* Noise estimator - primary activity quick */ Word16 prim_act_slow_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_fx; /*Q15 */ /* Noise estimator - primary activity slow rise quick fall */ @@ -217,22 +215,22 @@ typedef struct vad_structure Word16 prim_act_slow_he_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_he_fx; /*Q15 */ /* Q15 Noise estimator - primary activity slow rise quick fall */ - int16_t spectral_tilt_reset; - int16_t consec_inactive; + Word16 spectral_tilt_reset; + Word16 consec_inactive; Word16 ra_deltasum_fx; - int16_t trigger_SID; + Word16 trigger_SID; Word16 snr_sum_vad_fx; /*Q15 */ Word16 running_avg_fx; /*Q15 */ Word32 L_snr_sum_vad_fx; /*Q4*/ - int16_t hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ - int16_t vad_flag; /* VAD flag */ + Word16 hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ + Word16 vad_flag; /* VAD flag */ } VAD_DATA, *VAD_HANDLE; typedef struct cldfb_vad_structure { - int16_t bw_index; /* index of band width */ + Word16 bw_index; /* index of band width */ /* feature */ Word16 sp_center[SP_CENTER_NUM]; /* spectral center*/ @@ -248,8 +246,8 @@ typedef struct cldfb_vad_structure Word32 t_bg_energy; /* time background energy of several frames*/ Word16 scale_t_bg_energy; /* the Scaling of t_bg_energy*/ T_VAD_EXP t_bg_energy_sum; /* number of time background energy*/ - int16_t tbg_energy_count; /* sum of time background energy of several frames*/ - int16_t bg_update_count; /* time of background update*/ + Word16 tbg_energy_count; /* sum of time background energy of several frames*/ + Word16 bg_update_count; /* time of background update*/ Word32 frame_energy_smooth; /* smoothed energy of several frames*/ Word16 frame_energy_smooth_scale; /* the Scaling of frame_energy_smooth*/ @@ -268,14 +266,14 @@ typedef struct cldfb_vad_structure Word16 fg_energy_scale; /* the Scaling of fg_energy*/ Word32 bg_energy; /* background energy sum */ Word16 bg_energy_scale; /* the Scaling of bg_energy*/ - int16_t fg_energy_count; /* number of the foreground energy frame */ - int16_t bg_energy_count; /* number of the background energy frame */ + Word16 fg_energy_count; /* number of the foreground energy frame */ + Word16 bg_energy_count; /* number of the background energy frame */ Word32 fg_energy_est_start; /* flag by that indicate whether if estimate energy*/ - int16_t speech_flag; /* residual number of hangover 1 */ - int16_t continuous_noise_num; /* time of continuous noise frames*/ - int16_t continuous_speech_num; /* time of continuous speech frames*/ - int16_t continuous_speech_num2; /* time 2 of continuous speech frames*/ - int16_t frameloop; /* number of frame*/ + Word16 speech_flag; /* residual number of hangover 1 */ + Word16 continuous_noise_num; /* time of continuous noise frames*/ + Word16 continuous_speech_num; /* time of continuous speech frames*/ + Word16 continuous_speech_num2; /* time 2 of continuous speech frames*/ + Word16 frameloop; /* number of frame*/ Word16 tonality_rate3; /* tonality rate*/ Word16 music_background_rate; /* music background rate*/ Word32 lt_noise_sp_center_diff_sum; /* different sum of long time noise sp_center*/ @@ -283,10 +281,10 @@ typedef struct cldfb_vad_structure Word16 lt_noise_sp_center0; /* long time noise sp_center0*/ Word16 lt_noise_sp_center3; /* long time noise sp_center3*/ Word32 lt_bg_highf_eng; /* average of long time high frequency energy*/ - int16_t update_num_with_snr; /* the number of the background update with SNR*/ - int16_t update_count; - int16_t warm_hang_num; /* the number of hangover for warm up*/ - int16_t vad_flag_for_bk_update; + Word16 update_num_with_snr; /* the number of the background update with SNR*/ + Word16 update_count; + Word16 warm_hang_num; /* the number of hangover for warm up*/ + Word16 vad_flag_for_bk_update; } T_CldfbVadState, *VAD_CLDFB_HANDLE; @@ -326,7 +324,7 @@ typedef struct td_cng_enc_structure Word16 cng_buf_cnt; /* CNG and DTX - Counter of buffered CNG parameters */ Word16 cng_exc2_buf[HO_HIST_SIZE * L_FFT]; /* CNG and DTX - exc2 buffer for storing */ Word16 cng_Qexc_buf[HO_HIST_SIZE]; /* CNG and DTX - Q_exc buffer for storing */ - int32_t cng_brate_buf[HO_HIST_SIZE]; /* CNG and DTX - buffer for storing last_active_brate */ + Word32 cng_brate_buf[HO_HIST_SIZE]; /* CNG and DTX - buffer for storing last_active_brate */ Word16 CNG_att_fx; /* CNG and DTX - attenuation factor for CNG, in dB Q7 */ Word16 ho_16k_lsp[HO_HIST_SIZE]; /* CNG and DTX - 16k LSPs flags */ Word16 act_cnt2; /* CNG and DTX - counter of active frames for CNG_mode switching */ @@ -432,23 +430,23 @@ typedef struct dtx_enc_structure typedef struct igfscfenc_public_data_struct { - int16_t ptrBitIndex; - int16_t bitCount; - int16_t prev[64]; /* no more than 64 SCFs for the IGF energy envelope of one block */ - int16_t prevSave[64]; - int16_t scfCountLongBlock[IGF_NOF_GRIDS]; - int16_t t; - int16_t Tsave; - int16_t contex_saved; - const uint16_t *cf_se00; - const uint16_t *cf_se01; - int16_t cf_off_se01; - const uint16_t *cf_se02; - const int16_t *cf_off_se02; - const uint16_t *cf_se10; - int16_t cf_off_se10; - const uint16_t *cf_se11; - const int16_t *cf_off_se11; + Word16 ptrBitIndex; + Word16 bitCount; + Word16 prev[64]; /* no more than 64 SCFs for the IGF energy envelope of one block */ + Word16 prevSave[64]; + Word16 scfCountLongBlock[IGF_NOF_GRIDS]; + Word16 t; + Word16 Tsave; + Word16 contex_saved; + const UWord16 *cf_se00; + const UWord16 *cf_se01; + Word16 cf_off_se01; + const UWord16 *cf_se02; + const Word16 *cf_off_se02; + const UWord16 *cf_se10; + Word16 cf_off_se10; + const UWord16 *cf_se11; + const Word16 *cf_off_se11; Tastat acState; TastatEnc acState_fx; @@ -749,21 +747,21 @@ typedef struct acelp_cbkcorr_structure typedef struct gsc_enc_structure { - int16_t seed_tcx; /* AC mode (GSC) - seed for noise fill */ - int16_t cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - int16_t mem_last_pit_band; /* AC mode (GSC) - memory of the last band where pitch contribution was significant */ + Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ + Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ + Word16 mem_last_pit_band; /* AC mode (GSC) - memory of the last band where pitch contribution was significant */ Word16 mem_w0_tmp_fx; Word16 mem_syn_tmp_fx[M]; Word16 mid_dyn_fx; /* AC mode (GSC) - signal dynamic Q7 */ - int16_t noise_lev; /* AC mode (GSC) - noise level */ - int16_t past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ + Word16 noise_lev; /* AC mode (GSC) - noise level */ + Word16 past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ Word32 Last_frame_ener_fx; /* AC mode (GSC) - Last frame energy */ - int16_t pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ + Word16 pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous exciation */ Word16 Q_last_exc_dct_in; - Word16 last_ener_fx; /* AC mode (GSC) - previous energy Q0 */ - int16_t last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - Word16 lt_gpitch_fx; /* Q15 */ + Word16 last_ener_fx; /* AC mode (GSC) - previous energy Q0 */ + Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ + Word16 lt_gpitch_fx; /* Q15 */ } GSC_ENC_DATA, *GSC_ENC_HANDLE; @@ -804,14 +802,14 @@ typedef struct hq_enc_structure /* PVQ range coder state */ typedef struct pvq_enc_structure { - uint32_t rc_low; - uint32_t rc_range; - int16_t rc_cache; - int16_t rc_carry; - int16_t rc_carry_count; - int16_t rc_num_bits; - int16_t rc_tot_bits; - int16_t rc_offset; + UWord32 rc_low; + UWord32 rc_range; + Word16 rc_cache; + Word16 rc_carry; + Word16 rc_carry_count; + Word16 rc_num_bits; + Word16 rc_tot_bits; + Word16 rc_offset; } PVQ_ENC_DATA, *PVQ_ENC_HANDLE; @@ -838,33 +836,33 @@ typedef struct sc_vbr_enc_structure Word16 nelp_lp_fit_mem[NELP_LP_ORDER * 2]; /* Q(prev_Q_new) */ Word32 bp1_filt_mem_nb_fx[14]; /* Q(qprevGain_fx) */ - int16_t nelp_enc_seed; + Word16 nelp_enc_seed; Word16 nelp_gain_mem_fx; /* Q0 */ - int16_t last_nelp_mode; - int16_t nelp_mode; + Word16 last_nelp_mode; + Word16 nelp_mode; Word16 qprevIn_fx; Word16 qprevGain_fx; /* PPP variables */ - int16_t pppcountE; - int16_t bump_up; - int16_t last_ppp_mode; - int16_t last_last_ppp_mode; - int16_t ppp_mode; + Word16 pppcountE; + Word16 bump_up; + Word16 last_ppp_mode; + Word16 last_last_ppp_mode; + Word16 ppp_mode; Word16 prev_ppp_gain_pit_fx; /* Q14 */ Word16 prev_tilt_code_fx; /* Q15 */ /* voiced encoder variables */ - int16_t firstTime_voicedenc; + Word16 firstTime_voicedenc; /* DTFS variables */ Word16 dtfs_enc_a_fx[MAXLAG_WI]; /* Q(dtfs_enc_Q) */ Word16 dtfs_enc_b_fx[MAXLAG_WI]; /* Q(dtfs_enc_Q) */ - int16_t dtfs_enc_lag; - int16_t dtfs_enc_nH; - int16_t dtfs_enc_nH_4kHz; + Word16 dtfs_enc_lag; + Word16 dtfs_enc_nH; + Word16 dtfs_enc_nH_4kHz; Word16 dtfs_enc_upper_cut_off_freq_of_interest_fx; /* Q0 */ Word16 dtfs_enc_upper_cut_off_freq_fx; /* Q0 */ Word16 dtfs_enc_Q; @@ -876,23 +874,23 @@ typedef struct sc_vbr_enc_structure Word16 lasterbE_fx[NUM_ERB_WB]; /* Previous Amplitude spectrum (ERB) Q13 */ Word16 Q_prev_cw_en_fx; - int16_t mode_QQF; - int16_t rate_control; + Word16 mode_QQF; + Word16 rate_control; Word16 SNR_THLD_fx; /* Q8 */ - int16_t Q_to_F; - int16_t pattern_m; - int16_t patterncount; - int16_t Last_Resort; - int16_t numactive; /* keep the count of the frames inside current 600 frame block */ + Word16 Q_to_F; + Word16 pattern_m; + Word16 patterncount; + Word16 Last_Resort; + Word16 numactive; /* keep the count of the frames inside current 600 frame block */ Word32 sum_of_rates_fx; /*Q=13 sum of the rates of past 600 active frames*/ Word32 global_avr_rate_fx; /*Q=13 global rate upto current time. recorded a (rate in kbps) *6000*/ - int16_t global_frame_cnt; /* 600 active frame block count. Used to update the global rate */ - int16_t set_ppp_generic; - int16_t avoid_HQ_VBR_NB; + Word16 global_frame_cnt; /* 600 active frame block count. Used to update the global rate */ + Word16 set_ppp_generic; + Word16 avoid_HQ_VBR_NB; - int16_t vbr_generic_ho; - int16_t Local_VAD; - int16_t last_7k2_coder_type; + Word16 vbr_generic_ho; + Word16 Local_VAD; + Word16 last_7k2_coder_type; } SC_VBR_ENC_DATA, *SC_VBR_ENC_HANDLE; @@ -910,7 +908,7 @@ typedef struct amrwb_io_enc_structure Word16 mem_hp400_enc_fx[6]; Word16 mem_hf_enc_fx[L_FIR - 1]; Word16 mem_syn_hf_enc_fx[M]; - int16_t seed2_enc; + Word16 seed2_enc; } AMRWB_IO_ENC_DATA, *AMRWB_IO_ENC_HANDLE; @@ -944,7 +942,7 @@ typedef struct td_bwe_enc_structure Word16 state_syn_shbexc_fx[L_SHB_LAHEAD]; /* Q(prev_Q_bwe_exc - 16) */ Word16 state_lpc_syn_fx[LPC_SHB_ORDER]; /* Q(prev_Q_bwe_exc - 16) */ Word16 old_bwe_exc_fx[PIT16k_MAX * 2]; /*Q_exc*/ - int16_t bwe_seed[2]; + Word16 bwe_seed[2]; Word32 bwe_non_lin_prev_scale_fx; /* Q30 */ Word16 old_bwe_exc_extended_fx[NL_BUFF_OFFSET]; /* Q(prev_Q_bwe_exc - 16) */ Word16 syn_overlap_fx[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain */ @@ -964,7 +962,7 @@ typedef struct td_bwe_enc_structure Word16 shb_inv_filt_mem_fx[LPC_SHB_ORDER]; /* Q(Q_shb_spch) */ Word16 lsp_shb_spacing_fx[3]; /* Q15 */ Word16 prev_swb_GainShape_fx; /* Q15 */ - int16_t prev_frGainAtten; + Word16 prev_frGainAtten; Word16 prev_wb_GainShape; /* Q15 */ Word16 swb_lsp_prev_interp_fx[LPC_SHB_ORDER]; /* Q15 */ @@ -973,25 +971,25 @@ typedef struct td_bwe_enc_structure Word16 fb_tbe_demph_fx; Word16 tilt_mem_fx; /* Q12 */ - int16_t prev_coder_type; + Word16 prev_coder_type; Word16 prev_lsf_diff_fx[LPC_SHB_ORDER - 2]; /* Q15 */ Word16 prev_tilt_para_fx; /* Q10 */ Word16 cur_sub_Aq_fx[M + 1]; /* Q12 */ /* quantized data */ - int16_t lsf_idx[NUM_Q_LSF]; - int16_t m_idx; - int16_t grid_idx; - int16_t idxSubGains; - int16_t idxFrameGain; - int16_t idx_shb_fr_gain; - int16_t idx_res_gs[NB_SUBFR16k]; - int16_t idx_mixFac; - - int16_t lsf_WB; - int16_t gFrame_WB; - - int16_t idxGain; + Word16 lsf_idx[NUM_Q_LSF]; + Word16 m_idx; + Word16 grid_idx; + Word16 idxSubGains; + Word16 idxFrameGain; + Word16 idx_shb_fr_gain; + Word16 idx_res_gs[NB_SUBFR16k]; + Word16 idx_mixFac; + + Word16 lsf_WB; + Word16 gFrame_WB; + + Word16 idxGain; Word16 dec_2_over_3_mem_fx[L_FILT_2OVER3]; Word16 dec_2_over_3_mem_lp_fx[6]; @@ -1041,9 +1039,9 @@ typedef struct fd_bwe_enc_structure typedef struct rf_enc_structure { - int16_t rf_frame_type; - int16_t rf_targetbits_buff[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_frametype[MAX_RF_FEC_OFFSET]; + Word16 rf_frame_type; + Word16 rf_targetbits_buff[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_frametype[MAX_RF_FEC_OFFSET]; ACELP_config acelp_cfg_rf; /* configuration for RF frame */ @@ -1054,31 +1052,31 @@ typedef struct rf_enc_structure struct dispMem_fx rf_dm_fx; Word32 rf_gc_threshold; - int16_t rf_target_bits; + Word16 rf_target_bits; Word16 rf_tilt_buf[NB_SUBFR16k]; - int16_t rf_indx_lsf[MAX_RF_FEC_OFFSET][3]; - int16_t rf_indx_pitch[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_fcb[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_gain[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_EsPred[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_ltfMode[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_lsf[MAX_RF_FEC_OFFSET][3]; + Word16 rf_indx_pitch[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_fcb[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_gain[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_EsPred[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_ltfMode[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_nelp_fid[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_nelp_iG1[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_nelp_iG2[MAX_RF_FEC_OFFSET][2]; + Word16 rf_indx_nelp_fid[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_nelp_iG1[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_nelp_iG2[MAX_RF_FEC_OFFSET][2]; - int16_t rf_indx_tbeGainFr[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_tbeGainFr[MAX_RF_FEC_OFFSET]; - int16_t rf_tcxltp_pitch_int_past; - int16_t rf_last_tns_active; - int16_t rf_second_last_tns_active; - int16_t rf_second_last_core; - int16_t rf_clas[MAX_RF_FEC_OFFSET]; - int16_t rf_gain_tcx[MAX_RF_FEC_OFFSET]; - int16_t rf_tcxltp_param[MAX_RF_FEC_OFFSET]; + Word16 rf_tcxltp_pitch_int_past; + Word16 rf_last_tns_active; + Word16 rf_second_last_tns_active; + Word16 rf_second_last_core; + Word16 rf_clas[MAX_RF_FEC_OFFSET]; + Word16 rf_gain_tcx[MAX_RF_FEC_OFFSET]; + Word16 rf_tcxltp_param[MAX_RF_FEC_OFFSET]; - int16_t RF_bwe_gainFr_ind; + Word16 RF_bwe_gainFr_ind; } RF_ENC_DATA, *RF_ENC_HANDLE; @@ -1088,17 +1086,17 @@ typedef struct rf_enc_structure typedef struct plc_enc_evs_structure { - int16_t nBits; /* number of bits */ + Word16 nBits; /* number of bits */ Word16 Q_new; Word16 Q_exp; - int16_t enableGplc; - int16_t T0_4th; - int16_t T0; - int16_t calcOnlylsf; - int16_t pit_min; - int16_t pit_max; + Word16 enableGplc; + Word16 T0_4th; + Word16 T0; + Word16 calcOnlylsf; + Word16 pit_min; + Word16 pit_max; Word16 mem_MA_14Q1[M]; Word16 mem_AR[M]; @@ -1131,8 +1129,8 @@ typedef struct tec_enc_structure Word16 loTempEnv[CLDFB_NO_COL_MAX]; /* Q7 */ Word16 loTempEnv_ns[CLDFB_NO_COL_MAX]; /* Q7 */ Word16 hiTempEnv[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV]; /* Q7 */ - int16_t tranFlag; - int16_t corrFlag; + Word16 tranFlag; + Word16 corrFlag; } TEC_ENC_DATA, *TEC_ENC_HANDLE; @@ -1143,63 +1141,63 @@ typedef struct tec_enc_structure typedef struct tcx_enc_structure { - int16_t L_frameTCX; + Word16 L_frameTCX; - int16_t tcxMode; /* Chosen TCX mode for this frame */ - int16_t transform_type[2]; /* TCX20/10/5 mode in each subframe */ + Word16 tcxMode; /* Chosen TCX mode for this frame */ + Word16 transform_type[2]; /* TCX20/10/5 mode in each subframe */ /* Core Signal Analysis Outputs */ Word16 noiseTiltFactor; /* compensation for LPC tilt in noise filling Q15 */ - int16_t noiseLevelMemory_cnt; /* counter of consecutive low TCX noise levels */ + Word16 noiseLevelMemory_cnt; /* counter of consecutive low TCX noise levels */ Word16 ltpGainMemory_fx[N_LTP_GAIN_MEMS]; /* for smoothing noiseTransWidth Q15 */ STnsData tnsData[2]; - // int16_t fUseTns[2]; + // Word16 fUseTns[2]; Word8 fUseTns[2]; - int16_t bTnsOnWhithenedSpectra[2]; + Word16 bTnsOnWhithenedSpectra[2]; - // int16_t memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ + // Word16 memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ Word8 memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ Word16 *speech_TCX; Word16 *new_speech_TCX; // Word16 q_speech_TCX; - int16_t tcxltp; - int16_t tcxltp_pitch_int; - int16_t tcxltp_pitch_fr; + Word16 tcxltp; + Word16 tcxltp_pitch_int; + Word16 tcxltp_pitch_fr; Word16 tcxltp_gain; /* Q15 */ - int16_t tcxltp_pitch_int_past; - int16_t tcxltp_pitch_fr_past; + Word16 tcxltp_pitch_int_past; + Word16 tcxltp_pitch_fr_past; Word16 tcxltp_gain_past; /* Q15 */ Word16 tcxltp_norm_corr_past; /* Q15 */ Word16 tcxltp_norm_corr_mem; /* Q15 */ Word16 kernel_switch_corr_past; /* Q15 */ - uint16_t kernel_type[2]; /* transform kernel type in each subframe (MDCT or MDST) */ - uint16_t kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ - uint16_t enc_ste_pre_corr_past; + UWord16 kernel_type[2]; /* transform kernel type in each subframe (MDCT or MDST) */ + UWord16 kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ + UWord16 enc_ste_pre_corr_past; Word32 tfm_mem_fx; /* state of IIR filtered temporal flatness measure Q31 */ Word16 buf_speech_ltp[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; Word16 exp_buf_speech_ltp; Word16 *speech_ltp; Word16 *new_speech_ltp; - int16_t tcxltp_filt_idx; - int16_t tcxltp_bits; - int16_t tcxltp_param[LTPSIZE]; - int16_t tcxltp_on_mem; + Word16 tcxltp_filt_idx; + Word16 tcxltp_bits; + Word16 tcxltp_param[LTPSIZE]; + Word16 tcxltp_on_mem; Word16 measuredBwRatio; /* measured bw; used for TCX noise-filling. 1Q14 */ - int16_t nmStartLine; /* Starting line for the noise measurement */ + Word16 nmStartLine; /* Starting line for the noise measurement */ - int16_t tcx_lpc_shaped_ari; + Word16 tcx_lpc_shaped_ari; Word16 old_out_fx[L_FRAME32k]; /* buffer for OLA; at the encoder, the maximum length is L_FRAME32k (corresponds to maximum internal L_frame length) */ Word16 Q_old_out; /* MDCT switching */ Word16 prev_hi_ener; /* Q8 */ - int16_t prev_hi_sparse; + Word16 prev_hi_sparse; Word16 clas_sec_old_fx; /* Q13 */ - int16_t clas_final_old; + Word16 clas_final_old; Word32 last_gain1; /* Q(31 - st->last_enerBuffer_exp) */ Word32 last_gain2; /* Q(31 - st->last_enerBuffer_exp) */ @@ -1209,7 +1207,7 @@ typedef struct tcx_enc_structure Word16 q_Txnq; Word16 tcx_target_bits_fac; /* Q14 */ - int16_t tns_ms_flag[2]; + Word16 tns_ms_flag[2]; Word32 *spectrum_fx[2]; /* MDCT output for a short block */ Word16 spectrum_e[2]; Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ @@ -1241,9 +1239,9 @@ typedef struct enc_core_structure Word16 idchan; /* channel ID (audio channel number) */ Word16 id_element; /* element ID */ - int16_t element_mode; /* element mode */ + Word16 element_mode; /* element mode */ Word16 last_element_mode; /* element mode */ - int32_t element_brate; /* element bitrate */ + Word32 element_brate; /* element bitrate */ Word16 extl_orig; /* extension layer */ Word32 extl_brate_orig; /* extension layer bitrate */ Word16 codec_mode; /* Mode1 or Mode2 */ @@ -1257,40 +1255,40 @@ typedef struct enc_core_structure BSTR_ENC_HANDLE hBstr; /* encoder bitstream handle */ Word16 last_enerBuffer_exp; - int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME) */ - Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ - - int32_t input_Fs; /* input signal sampling frequency in Hz */ - int32_t total_brate; /* total bitrate in kbps of the codec */ - int32_t last_total_brate; /* last frame's total bitrate in kbps of the codec */ - int32_t last_total_brate_cng; /* last inactive frame's total bitrate in kbps of the codec */ - int16_t core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ - int16_t last_core; /* previous frame core */ - int16_t coder_type; /* core coder type */ - int16_t flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ - int32_t core_brate; /* core bitrate */ - int32_t last_core_brate; /* previous frame core bitrate */ - int16_t extl; /* extension layer */ - int16_t last_extl; /* previous extension layer */ - int32_t extl_brate; /* extension layer bitrate */ - int16_t input_bwidth; /* input signal bandwidth */ - int16_t bwidth; /* encoded bandwidth NB, WB, SWB or FB */ - int16_t max_bwidth; /* maximum encoded bandwidth */ - int16_t last_input_bwidth; /* input signal bandwidth in the previous frame */ - int16_t last_bwidth; /* coded bandwidth in the previous frame */ - int16_t last_bwidth_cng; /* coded bandwidth in the previous inactive frame */ - int16_t bwidth_sw_cnt; /* bandwidth switching counter */ - int16_t L_frame; /* ACELP core internal frame length */ - int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - int16_t Opt_DTX_ON; /* flag indicating DTX operation */ - int16_t cng_type; /* flag indicating LP or CLDFB based SID/CNG */ - int16_t cng_sba_flag; /* flag indicating CNG/SID for SBA 2TC */ - int16_t Opt_SC_VBR; /* flag indicating SC-VBR mode */ - int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ - int16_t low_rate_mode; /* low-rate mode flag */ - int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ + Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME) */ + Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ + + Word32 input_Fs; /* input signal sampling frequency in Hz */ + Word32 total_brate; /* total bitrate in kbps of the codec */ + Word32 last_total_brate; /* last frame's total bitrate in kbps of the codec */ + Word32 last_total_brate_cng; /* last inactive frame's total bitrate in kbps of the codec */ + Word16 core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ + Word16 last_core; /* previous frame core */ + Word16 coder_type; /* core coder type */ + Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ + Word32 core_brate; /* core bitrate */ + Word32 last_core_brate; /* previous frame core bitrate */ + Word16 extl; /* extension layer */ + Word16 last_extl; /* previous extension layer */ + Word32 extl_brate; /* extension layer bitrate */ + Word16 input_bwidth; /* input signal bandwidth */ + Word16 bwidth; /* encoded bandwidth NB, WB, SWB or FB */ + Word16 max_bwidth; /* maximum encoded bandwidth */ + Word16 last_input_bwidth; /* input signal bandwidth in the previous frame */ + Word16 last_bwidth; /* coded bandwidth in the previous frame */ + Word16 last_bwidth_cng; /* coded bandwidth in the previous inactive frame */ + Word16 bwidth_sw_cnt; /* bandwidth switching counter */ + Word16 L_frame; /* ACELP core internal frame length */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_DTX_ON; /* flag indicating DTX operation */ + Word16 cng_type; /* flag indicating LP or CLDFB based SID/CNG */ + Word16 cng_sba_flag; /* flag indicating CNG/SID for SBA 2TC */ + Word16 Opt_SC_VBR; /* flag indicating SC-VBR mode */ + Word16 last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ + Word16 low_rate_mode; /* low-rate mode flag */ + Word16 inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ #ifdef DEBUGGING - int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ + Word16 force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ #ifdef DEBUG_FORCE_DIR char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ #endif @@ -1328,13 +1326,13 @@ typedef struct enc_core_structure * ACELP core parameters *----------------------------------------------------------------------------------*/ - int16_t clas; /* current frame clas */ - int16_t last_clas; /* previous frame signal classification */ + Word16 clas; /* current frame clas */ + Word16 last_clas; /* previous frame signal classification */ Word16 prev_fmerit; /* previous signal classification score Q15 */ Word16 fmerit_dt; /* signal classification score difference Q15 */ - int16_t Nb_ACELP_frames; + Word16 Nb_ACELP_frames; - int16_t pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ + Word16 pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ // Word16 pitch_fx[3]; Word16 voicing_fx[3]; /* open-loop normalized correlation values for three half-frames Q15 */ @@ -1348,7 +1346,7 @@ typedef struct enc_core_structure Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame Qlog2(2.56) */ Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz Q15 */ Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz Q15 */ - int16_t pstreaklen; /* LSF quantizer */ + Word16 pstreaklen; /* LSF quantizer */ Word16 streaklimit_fx; /* LSF quantizer Q15 */ Word16 stab_fac_fx; /* LSF stability factor Q15 */ Word16 clip_var_fx[6]; /* pitch gain clipping memory [2.56x,Q14,Q8,Q0,Q14,Q14] */ @@ -1375,42 +1373,42 @@ typedef struct enc_core_structure Word16 mem_deemph_fx; /* deemphasis filter memory */ Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ - int16_t GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ - int16_t GSC_IVAS_mode; + Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ + Word16 GSC_IVAS_mode; GSC_ENC_HANDLE hGSCEnc; - int16_t Last_pulse_pos; /* FEC - last position of the first glottal pulse in the frame */ + Word16 Last_pulse_pos; /* FEC - last position of the first glottal pulse in the frame */ Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame Qlog2(2.56) */ Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame Qlog2(2.56) */ Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC Qlog2(2.56) */ - int16_t next_force_safety_net; /* FEC - flag to force safety net in next frame */ + Word16 next_force_safety_net; /* FEC - flag to force safety net in next frame */ // Word16 next_force_safety_net_fx; /* FEC - flag to force safety net in next frame */ - int16_t uv_count; /* Stationary noise UV modification - unvoiced counter */ - int16_t act_count; /* Stationary noise UV modification - activation counter */ + Word16 uv_count; /* Stationary noise UV modification - unvoiced counter */ + Word16 act_count; /* Stationary noise UV modification - activation counter */ Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain Q(GE_SHIFT) */ Word16 lspold_s_fx[M]; /* Stationary noise UV modification - old LSP vector Q15 */ - int16_t noimix_seed; /* Stationary noise UV modification - mixture seed */ + Word16 noimix_seed; /* Stationary noise UV modification - mixture seed */ Word16 min_alpha_fx; /* Stationary noise UV modification - minimum alpha Q15 */ Word16 exc_pe_fx; /* Stationary noise UV modification - memory of the preemphasis filter */ - int16_t coder_type_raw; /* raw coder_type (before UNVOICED is lost) */ - int16_t last_coder_type_raw; /* raw last_coder_type (coming from the sigal classification) */ - int16_t last_coder_type; /* previous coding type */ + Word16 coder_type_raw; /* raw coder_type (before UNVOICED is lost) */ + Word16 last_coder_type_raw; /* raw last_coder_type (coming from the sigal classification) */ + Word16 last_coder_type; /* previous coding type */ Word16 old_thres_fx; /* normalized correlation weighting in open-loop pitch Q14 */ Word16 old_corr_fx; /* normalized correlation in previous frame (mean value) Q15 */ - int16_t old_pitch; /* previous pitch for open-loop pitch search */ - int16_t delta_pit; /* open-loop pitch extrapolation correction */ + Word16 old_pitch; /* previous pitch for open-loop pitch search */ + Word16 delta_pit; /* open-loop pitch extrapolation correction */ Word32 ee_old_fx; /* previous frame low/high frequency energy ratio Q6 */ - int16_t min_band; /* minimum critical band of useful bandwidth */ - int16_t max_band; /* maximum critical band of useful bandwidth */ - int16_t tc_cnt; /* TC frame counter */ - int16_t audio_frame_cnt; /* Counter of relative presence of audio frames */ + Word16 min_band; /* minimum critical band of useful bandwidth */ + Word16 max_band; /* maximum critical band of useful bandwidth */ + Word16 tc_cnt; /* TC frame counter */ + Word16 audio_frame_cnt; /* Counter of relative presence of audio frames */ Word32 old_dE1_fx; /* Maximum energy increase in previous frame Q13 */ - int16_t old_ind_deltaMax; /* Index of the sub-subframe of maximum energy in previous frame */ + Word16 old_ind_deltaMax; /* Index of the sub-subframe of maximum energy in previous frame */ Word32 old_enr_ssf_fx[2 * NB_SSF]; /* Maxima of energies per sub-subframes of previous frame */ - int16_t spike_hyst; /* Hysteresis to prevent UC after sharp energy spike */ - int16_t last_harm_flag_acelp; /* harmonicity flag for ACELP @32kbps rate */ + Word16 spike_hyst; /* Hysteresis to prevent UC after sharp energy spike */ + Word16 last_harm_flag_acelp; /* harmonicity flag for ACELP @32kbps rate */ Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ Word16 old_Es_pred_fx; /* old Es_pred for core switching Q8 */ Word16 music_hysteresis_fx; /* Counter of frames after AUDIO coding mode to prevent UC */ @@ -1433,7 +1431,7 @@ typedef struct enc_core_structure Word16 voicing0_sm_fx; Word16 voicing_sm_fx; Word16 LF_EnergyRatio_sm_fx; - int16_t predecision_flag; + Word16 predecision_flag; Word32 diff_sm_fx; /* Q7 */ Word32 energy_sm_fx; /* Q7 */ @@ -1492,9 +1490,9 @@ typedef struct enc_core_structure Word16 lgBin_E_fx[L_FFT / 2]; /* Q8 per bin energy of two frames */ - int16_t sp_aud_decision0; /* 1st stage speech/music decision flag */ - int16_t sp_aud_decision1; /* 1st stage speech/music classification flag */ - int16_t sp_aud_decision2; /* 2nd stage speech/music classification flag */ + Word16 sp_aud_decision0; /* 1st stage speech/music decision flag */ + Word16 sp_aud_decision1; /* 1st stage speech/music classification flag */ + Word16 sp_aud_decision2; /* 2nd stage speech/music classification flag */ /*----------------------------------------------------------------------------------* * VAD/DTX/CNG @@ -1505,9 +1503,9 @@ typedef struct enc_core_structure VAD_CLDFB_HANDLE hVAD_CLDFB; T_CldfbVadState vad_st; - int16_t vad_flag; /* i : VAD flag */ - int16_t sharpFlag; - int16_t localVAD; /* i : local VAD flag */ + Word16 vad_flag; /* i : VAD flag */ + Word16 sharpFlag; + Word16 localVAD; /* i : local VAD flag */ Word32 bckr_tilt_lt; /* Q16 */ Word16 lp_speech_fx; /* Q8 */ @@ -1517,7 +1515,7 @@ typedef struct enc_core_structure Word16 voicing_old_fx; Word16 var_SID_rate_flag_fx; /* CNG and DTX - flag for variable SID rate */ Word16 interval_SID_fx; - int16_t active_cnt; /* counter of active frames */ + Word16 active_cnt; /* counter of active frames */ TD_CNG_ENC_HANDLE hTdCngEnc; @@ -1544,10 +1542,10 @@ typedef struct enc_core_structure *----------------------------------------------------------------------------------*/ HANDLE_FD_CNG_ENC hFdCngEnc; - int16_t fd_cng_reset_flag; + Word16 fd_cng_reset_flag; Word16 last_totalNoise_fx; /* Q8 */ Word16 totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE]; /* Q8 */ - int16_t totalNoise_increase_len; + Word16 totalNoise_increase_len; /*----------------------------------------------------------------------------------* * SC-VBR parameters @@ -1564,7 +1562,7 @@ typedef struct enc_core_structure Word16 old_hpfilt_out_fx; Word32 EnergyLT_fx; /* Q(EnergyLT_fx_exp) */ Word32 Energy_Old_fx; - int16_t TransientHangOver; + Word16 TransientHangOver; HQ_ENC_HANDLE hHQ_core; /* HQ core encoder handle */ @@ -1588,21 +1586,21 @@ typedef struct enc_core_structure Word16 lt_mean_NB_fx; /* Q11 */ Word16 lt_mean_WB_fx; /* Q11 */ Word16 lt_mean_SWB_fx; /* Q11 */ - int16_t count_WB; - int16_t count_SWB; - int16_t count_FB; + Word16 count_WB; + Word16 count_SWB; + Word16 count_FB; /*----------------------------------------------------------------------------------* * Channel-aware mode *----------------------------------------------------------------------------------*/ - int16_t rf_mode; /* flag to signal the RF mode */ - int16_t rf_mode_last; - int16_t last_rf_mode_cng; - int16_t Opt_RF_ON; - int16_t rf_fec_offset; - int16_t rf_target_bits_write; - int16_t rf_fec_indicator; + Word16 rf_mode; /* flag to signal the RF mode */ + Word16 rf_mode_last; + Word16 last_rf_mode_cng; + Word16 Opt_RF_ON; + Word16 rf_fec_offset; + Word16 rf_target_bits_write; + Word16 rf_fec_indicator; RF_ENC_HANDLE hRF; /* RF encoder handle */ @@ -1650,17 +1648,17 @@ typedef struct enc_core_structure Word16 *wspeech_enc; // exp_buf_wspeech_enc Word16 *synth; - int16_t enableTcxLpc; /* global toggle for the TCX LPC quantizer */ - int16_t envWeighted; /* are is{p,f}_old_q[] weighted or not? */ + Word16 enableTcxLpc; /* global toggle for the TCX LPC quantizer */ + Word16 envWeighted; /* are is{p,f}_old_q[] weighted or not? */ - int16_t acelpEnabled; /* Flag indicating if ACELP can be used */ - int16_t tcx10Enabled; /* Flag indicating if TCX 10 can be used */ - int16_t tcx20Enabled; /* Flag indicating if TCX 20 can be used */ + Word16 acelpEnabled; /* Flag indicating if ACELP can be used */ + Word16 tcx10Enabled; /* Flag indicating if TCX 10 can be used */ + Word16 tcx20Enabled; /* Flag indicating if TCX 20 can be used */ Word16 mem_wsp_enc; /* wsp vector memory */ - int16_t nb_bits_header_ace; /* number of bits for the header */ - int16_t nb_bits_header_tcx; /* number of bits for the header */ + Word16 nb_bits_header_ace; /* number of bits for the header */ + Word16 nb_bits_header_tcx; /* number of bits for the header */ Word16 preemph_fac; /*Preemphasis factor Q15*/ Word16 gamma; /* Q15 */ @@ -1669,7 +1667,7 @@ typedef struct enc_core_structure TRAN_DET_HANDLE hTranDet; TransientDetection transientDetection; Word16 transient_info[3]; - int16_t acelpFramesCount; + Word16 acelpFramesCount; Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E Q7 in EVS */ /* Q4 in IVAS */ // float currEnergyLookAhead; @@ -1684,34 +1682,34 @@ typedef struct enc_core_structure Word16 parcorr[2]; Word16 parcorr_mid[2]; - int16_t lpcQuantization; + Word16 lpcQuantization; Word16 numlpc; - int16_t encoderLookahead_enc; - int16_t encoderPastSamples_enc; - int16_t encoderLookahead_FB; + Word16 encoderLookahead_enc; + Word16 encoderPastSamples_enc; + Word16 encoderLookahead_FB; /* pitch_ol for adaptive lag window */ - int16_t old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ + Word16 old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ Word16 old_voicing_la; /* past open loop pitch gain from look-ahead */ Word32 band_energies[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor MODE2_E_MIN */ Word16 band_energies_exp; /* exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */ - int16_t acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ + Word16 acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ - int16_t pit_min; - int16_t pit_fr1; - int16_t pit_fr1b; - int16_t pit_fr2; - int16_t pit_max; - int16_t pit_res_max; + Word16 pit_min; + Word16 pit_fr1; + Word16 pit_fr1b; + Word16 pit_fr2; + Word16 pit_max; + Word16 pit_res_max; /* for FAC */ - int16_t L_frame_past; + Word16 L_frame_past; /*Adaptive BPF*/ - int16_t bpf_gain_param; + Word16 bpf_gain_param; Word32 mem_bpf_fx1[2 * L_FILT16k]; Word32 mem_error_bpf_fx[2 * L_FILT16k]; Word16 bpf_T[NB_SUBFR16k]; @@ -1726,24 +1724,24 @@ typedef struct enc_core_structure Word16 noise_shift_old; } mem_bpf_fx; - int16_t glr; - int16_t glr_idx[2]; + Word16 glr; + Word16 glr_idx[2]; Word32 mean_gc[2]; /* Q15 */ Word16 prev_lsf4_mean; /* Qlog2(2.56) */ - int16_t glr_reset; - int32_t last_sr_core; + Word16 glr_reset; + Word32 last_sr_core; Word16 last_stab_fac; /* Q15 */ Word32 gain_code[NB_SUBFR16k]; /*for rate switching*/ - int16_t rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ - int16_t rate_switching_reset_16kHz; + Word16 rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ + Word16 rate_switching_reset_16kHz; - int16_t enablePlcWaveadjust; - int16_t Tonal_SideInfo; + Word16 enablePlcWaveadjust; + Word16 Tonal_SideInfo; - int16_t seed_acelp; + Word16 seed_acelp; PLC_ENC_EVS_HANDLE hPlcExt; @@ -1752,23 +1750,23 @@ typedef struct enc_core_structure *----------------------------------------------------------------------------------*/ IGF_ENC_INSTANCE_HANDLE hIGFEnc; /* IGF encoder handle */ - int16_t igf; + Word16 igf; /*----------------------------------------------------------------------------------* * TEC *----------------------------------------------------------------------------------*/ - int16_t tec_tfa; + Word16 tec_tfa; TEC_ENC_HANDLE hTECEnc; /* TEC encoder handle */ - int16_t tec_flag; - int16_t tfa_flag; + Word16 tec_flag; + Word16 tfa_flag; Word32 tfa_enr[N_TEC_TFA_SUBFR]; /*---------------------------------------------------------------* * IVAS parameters *---------------------------------------------------------------*/ - int16_t tdm_LRTD_flag; /* LRTD stereo mode flag */ + Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ Word16 cna_dirac_flag; /* CNA in DirAC flag */ /* stereo switching memories */ @@ -1813,24 +1811,24 @@ typedef struct enc_core_structure Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; Word16 prev_lsp_wb_temp_fx[LPC_SHB_ORDER_WB]; - int16_t sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ + Word16 sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ } Encoder_State, *ENC_CORE_HANDLE; typedef struct GainItemStr { - int16_t gainIndex; + Word16 gainIndex; } GainItem; typedef struct context_rc_mem_struct { - int16_t nbits_old; - int16_t ctx; + Word16 nbits_old; + Word16 ctx; Word64 bit_estimate_fx; /* Q23 */ - int16_t rateFlag; - int16_t lastnz; - int16_t nt_half; + Word16 rateFlag; + Word16 lastnz; + Word16 nt_half; } RC_CONTEXT_MEM, *HANDLE_RC_CONTEXT_MEM; diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 2ca0b6d74..b1a3f2f20 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -282,7 +282,7 @@ void wb_bwe_enc_ivas_fx( *-------------------------------------------------------------------*/ void swb_bwe_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ + const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 3bad5fa7f..7bbc54780 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1390,7 +1390,7 @@ void swb_pre_proc_ivas_fx( } /* Dirty downsampling to match Nyquist to upper frequency limit of target */ - lerp( st->input_fx, new_swb_speech, L_resamp, (int16_t) Mpy_32_32( input_Fs, one_by_50_Q31 ) ); + lerp( st->input_fx, new_swb_speech, L_resamp, extract_l( Mpy_32_32( input_Fs, one_by_50_Q31 ) ) ); /* flip the spectrum */ Copy( new_swb_speech, spchTmp, L_resamp ); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 2a6f040ac..7247b6446 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -48,14 +48,12 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, Word8 *noiseFlags, Word16 lowpassLine ) { - Word16 i, lastTone; + Word16 i, lastTone, j; Word32 s, c; Word16 tmp16; Word32 tmp1, tmp2 = 0; /* initialization only to avoid compiler warning, not counted */ move32(); - int j; - IF( resetMemory != 0 ) { FOR( i = 0; i < lowpassLine; i++ ) @@ -81,7 +79,7 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, i = sub( startLine, 1 ); s = 0; move32(); - for ( j = -7; j < 8; j++ ) + FOR( j = -7; j < 8; j++ ) { s = L_add( s, L_shr( powerSpec[i + j], 4 ) ); } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 82d24ceba..3c88ca224 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -1288,7 +1288,7 @@ static void UpdateDelayBuffer( Word16 const *input, Word16 nSamplesAvailable, De move16(); nDelay = pDelayBuffer->nDelay; - assert( ( nDelay >= 0 ) && ( nDelay <= (int) sizeof( pDelayBuffer->buffer ) / (int) sizeof( pDelayBuffer->buffer[0] ) ) ); + assert( ( nDelay >= 0 ) && ( nDelay <= (Word32) sizeof( pDelayBuffer->buffer ) / (Word32) sizeof( pDelayBuffer->buffer[0] ) ) ); assert( nSamplesAvailable <= NSUBBLOCKS * pDelayBuffer->nSubblockSize ); /* If this is not the last frame */ IF( EQ_16( nSamplesAvailable, imult1616( NSUBBLOCKS, pDelayBuffer->nSubblockSize ) ) ) @@ -1307,7 +1307,7 @@ static void UpdateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailabl Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (int) sizeof( pSubblockEnergies->subblockNrg ) / (int) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); + assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ assert( pSubblockEnergies->nDelay >= 1 ); @@ -1332,7 +1332,7 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamples Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (int) sizeof( pSubblockEnergies->subblockNrg ) / (int) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); + assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ assert( pSubblockEnergies->nDelay >= 1 ); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7e41581f4..730705ffd 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -83,8 +83,8 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; typedef struct hrtfGainCache { - int16_t azi; - int16_t ele; + Word16 azi; + Word16 ele; Word32 shVec_fx[HRTF_SH_CHANNELS]; @@ -92,13 +92,13 @@ typedef struct hrtfGainCache typedef struct parambin_rend_config_data { - int16_t separateCenterChannelRendering; + Word16 separateCenterChannelRendering; IVAS_FORMAT ivas_format; MC_MODE mc_mode; - int32_t ivas_total_brate; - int16_t nchan_transport; + Word32 ivas_total_brate; + Word16 nchan_transport; Word32 qualityBasedSmFactor_fx; /* Q31 */ - int16_t processReverb; + Word16 processReverb; ISM_MODE ism_mode; } PARAMBIN_REND_CONFIG, *PARAMBIN_REND_CONFIG_HANDLE; @@ -113,7 +113,7 @@ static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBi static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 Rmat_fx[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q ); -static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const Word16 max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[] /*q_out*/, Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat ); @@ -137,8 +137,8 @@ static void matrixTransp2Mul_fx( Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, #ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx - int Ascale, - int Bscale, + Word32 Ascale, + Word32 Bscale, #endif Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, @@ -3810,8 +3810,8 @@ static void matrixTransp2Mul_fx( Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, #ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx - int Ascale, - int Bscale, + Word32 Ascale, + Word32 Bscale, #endif Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 32803f6c3..e89414542 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -67,7 +67,7 @@ *------------------------------------------------------------------------*/ static void get_lattice_coeffs_fx( const Word16 band_index, const Word16 channel_index, Word16 *lattice_coeffs ); -static void lattice2allpass_fx( const int16_t filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); +static void lattice2allpass_fx( const Word16 filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); /*------------------------------------------------------------------------- * ivas_dirac_dec_decorr_open() @@ -1280,7 +1280,7 @@ static void get_lattice_coeffs_fx( /* convert lattice filter coeffs to all pass transfer function coeffs */ static void lattice2allpass_fx( - const int16_t filter_length, // Q0 + const Word16 filter_length, // Q0 const Word16 *lattice_coeffs_fx, // Q15 Word16 *filter_coeffs_num_real_fx, // Q12 Word16 *filter_coeffs_den_real_fx ) // Q12 diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 6b41815c4..c8e6aa12f 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -165,13 +165,13 @@ static ivas_error calc_jot_t60_coeffs_fx( Word16 *pH_dB_fx, Word16 pH_dB_exp, co * *------------------------------------------------------------------------*/ -static uint16_t binRend_rand( +static UWord16 binRend_rand( REVERB_STRUCT_HANDLE hReverb /* i/o: binaural reverb handle */ ) { hReverb->binRend_RandNext = hReverb->binRend_RandNext * 1103515245 + 12345; - return (uint16_t) ( hReverb->binRend_RandNext / 65536 ) % 32768; + return (UWord16) ( hReverb->binRend_RandNext / 65536 ) % 32768; } @@ -886,9 +886,9 @@ static ivas_error calc_jot_t60_coeffs_fx( Word32 L_tmp; Word16 f0_fx, tmp_fx, lf_target_gain_dB_fx, hf_target_gain_dB_fx, mid_crossing_gain_dB_fx; Word16 lin_gain_lf_fx, lin_gain_hf_fx, shift, expl, exph; - int16_t f_idx, e = pH_dB_exp; + Word16 f_idx, e = pH_dB_exp; move16(); - uint16_t n_points_lf, n_points_hf; + UWord16 n_points_lf, n_points_hf; lf_target_gain_dB_fx = 0; move16(); @@ -1471,7 +1471,7 @@ ivas_error ivas_reverb_open_fx( { ivas_error error; REVERB_HANDLE pState = NULL; - Word16 bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx; + Word16 bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx, i; ivas_reverb_params_t params; Word32 pColor_target_l_fx[RV_LENGTH_NR_FC]; Word32 pColor_target_r_fx[RV_LENGTH_NR_FC]; @@ -1559,7 +1559,7 @@ ivas_error ivas_reverb_open_fx( set_reverb_acoustic_data_fx( ¶ms, input_audio_config, hHrtf, &hRenderConfig->roomAcoustics, subframe_len, nr_fc_input, nr_fc_fft_filter ); Scale_sig32( params.pFc_fx, nr_fc_fft_filter, -2 ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { params.pRt60_fx[i] = L_abs( params.pRt60_fx[i] ); move32(); @@ -1601,7 +1601,7 @@ ivas_error ivas_reverb_open_fx( Word32 *pT60_filter_coeff = (Word32 *) malloc( ( lenT60_filter_coeff ) * sizeof( Word32 * ) ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] ); move32(); @@ -1610,7 +1610,7 @@ ivas_error ivas_reverb_open_fx( pHrtf_avg_pwr_response_r_const[i] = L_shl( params.pHrtf_avg_pwr_response_r_const_fx[i], 5 ); /*Q23+5*/ move32(); } - FOR( Word16 i = 0; i < lenT60_filter_coeff; i++ ) + FOR( i = 0; i < lenT60_filter_coeff; i++ ) { pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); move32(); @@ -1648,20 +1648,20 @@ ivas_error ivas_reverb_open_fx( { /* Computing correlation filters on the basis of target IA coherence */ #ifdef MSAN_FIX - FOR( int i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) + FOR( i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ move32(); } #else - FOR( int i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) + FOR( i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ } #endif // MSAN_FIX Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 3 ); /*Scaling up to Q30*/ move32(); @@ -1670,14 +1670,14 @@ ivas_error ivas_reverb_open_fx( free( pHrtf_inter_aural_coherence_const ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); } - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); move32(); @@ -1699,14 +1699,14 @@ ivas_error ivas_reverb_open_fx( /* Computing coloration filters on the basis of target responses */ ivas_reverb_calc_color_filters_fx( pColor_target_l_fx, pColor_target_r_fx, pTime_window_fx, pState->fft_size, pFft_wf_filter_ch0_fx, pFft_wf_filter_ch1_fx, &q_pFft_wf_filter_ch0_fx, &q_pFft_wf_filter_ch1_fx ); - FOR( int i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); } - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); move32(); @@ -2492,7 +2492,7 @@ ivas_error ivas_binaural_reverb_open_parambin( const Word16 numBins, /* i : number of CLDFB bins Q0 */ const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate Q0 */ + const Word32 sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ) { diff --git a/lib_rend/ivas_rom_binaural_crend_head.h b/lib_rend/ivas_rom_binaural_crend_head.h index bc0d3cd17..2b4c3e919 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.h +++ b/lib_rend/ivas_rom_binaural_crend_head.h @@ -56,13 +56,13 @@ extern Word32 CRendBin_Combined_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_Combined_HRIR_coeff_im_48kHz_fx[15][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -70,13 +70,13 @@ extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNEL /* Sample Rate = 32000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_32kHz_fx[15][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_Combined_HRIR_coeff_im_32kHz_fx[15][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -84,13 +84,13 @@ extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNEL /* Sample Rate = 16000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_16kHz_fx[15][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_Combined_HRIR_coeff_im_16kHz_fx[15][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -105,13 +105,13 @@ extern Word32 CRendBin_FOA_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_48kHz_fx[4][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_FOA_HRIR_coeff_im_48kHz_fx[4][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -119,13 +119,13 @@ extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_32kHz_fx[4][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_FOA_HRIR_coeff_im_32kHz_fx[4][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -133,13 +133,13 @@ extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_16kHz_fx[4][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_FOA_HRIR_coeff_im_16kHz_fx[4][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -153,13 +153,13 @@ extern Word32 CRendBin_HOA2_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_48kHz_fx[9][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_48kHz_fx[9][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -167,13 +167,13 @@ extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_32kHz_fx[9][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_32kHz_fx[9][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -181,13 +181,13 @@ extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_16kHz_fx[9][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_16kHz_fx[9][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -200,13 +200,13 @@ extern Word32 CRendBin_HOA3_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_48kHz_fx[16][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_48kHz_fx[16][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -214,13 +214,13 @@ extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_32kHz_fx[16][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_32kHz_fx[16][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -228,13 +228,13 @@ extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_16kHz_fx[16][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_16kHz_fx[16][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -248,13 +248,13 @@ extern Word32 CRendBin_Combined_BRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][2955]; extern Word32 CRendBin_Combined_BRIR_coeff_im_48kHz_fx[15][BINAURAL_CHANNELS][2955]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS][2885]; @@ -262,13 +262,13 @@ extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS /* Sample Rate = 32000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_32kHz_fx[15][BINAURAL_CHANNELS][2819]; extern Word32 CRendBin_Combined_BRIR_coeff_im_32kHz_fx[15][BINAURAL_CHANNELS][2819]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS][2870]; @@ -276,13 +276,13 @@ extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS /* Sample Rate = 16000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_16kHz_fx[15][BINAURAL_CHANNELS][1774]; extern Word32 CRendBin_Combined_BRIR_coeff_im_16kHz_fx[15][BINAURAL_CHANNELS][1774]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS][2522]; diff --git a/lib_rend/ivas_rom_binaural_crend_head_fx.c b/lib_rend/ivas_rom_binaural_crend_head_fx.c index 068ce0927..be015058b 100644 --- a/lib_rend/ivas_rom_binaural_crend_head_fx.c +++ b/lib_rend/ivas_rom_binaural_crend_head_fx.c @@ -56,35 +56,35 @@ const Word32 CRendBin_Combined_HRIR_latency_s_fx = 44741;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -96,35 +96,35 @@ const Word32 CRendBin_FOA_HRIR_latency_s_fx = 44741; // Q31 /* Sample Rate = 48000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -135,35 +135,35 @@ const Word32 CRendBin_HOA2_HRIR_latency_s_fx = 44741; // Q31 /* Sample Rate = 48000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -173,36 +173,36 @@ const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={N const Word32 CRendBin_HOA3_HRIR_latency_s_fx = 44741;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz = 0; const float CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz[16]={0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -212,34 +212,34 @@ const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={N const Word32 CRendBin_Combined_BRIR_latency_s_fx = 313176;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_48kHz = 22; -const uint16_t CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]={{{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240},{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240}},{{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240},{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240}},{{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240},{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240}},{{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240},{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240}},{{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240},{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240}},{{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240},{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240}},{{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240},{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240}},{{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240},{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240}},{{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240},{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240}},{{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240},{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240}},{{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240},{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240}},{{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240},{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240}},{{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240},{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240}},{{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240},{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240}},{{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240},{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz = 98; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_48kHz = 22; +const UWord16 CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]={{{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240},{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240}},{{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240},{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240}},{{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240},{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240}},{{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240},{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240}},{{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240},{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240}},{{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240},{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240}},{{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240},{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240}},{{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240},{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240}},{{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240},{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240}},{{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240},{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240}},{{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240},{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240}},{{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240},{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240}},{{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240},{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240}},{{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240},{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240}},{{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240},{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz = 98; const float CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz[15]={0.224183f, 0.227455f, 0.241830f, 0.207155f, 0.218087f, 0.222942f, 0.232158f, 0.248203f, 0.249262f, 0.261591f, 0.246276f, 0.279163f, 0.285701f, 0.262541f, 0.271844f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz_fx[15]={7346, 7453, 7924, 6788, 7146, 7305, 7607, 8133, 8167, 8571, 8069, 9147, 9361, 8602, 8907,}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98},{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98},{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98}}; /* Sample Rate = 32000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_32kHz = 22; -const uint16_t CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]={{{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160},{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160}},{{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160},{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160}},{{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160},{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160}},{{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160},{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160}},{{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160},{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160}},{{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160},{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160}},{{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160},{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160}},{{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160},{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160}},{{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160},{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160}},{{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160},{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160}},{{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160},{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160}},{{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160},{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160}},{{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160},{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160}},{{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160},{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160}},{{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160},{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz = 97; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_32kHz = 22; +const UWord16 CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]={{{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160},{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160}},{{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160},{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160}},{{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160},{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160}},{{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160},{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160}},{{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160},{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160}},{{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160},{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160}},{{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160},{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160}},{{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160},{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160}},{{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160},{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160}},{{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160},{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160}},{{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160},{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160}},{{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160},{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160}},{{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160},{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160}},{{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160},{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160}},{{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160},{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz = 97; const float CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz[15]={0.224190f, 0.227445f, 0.241827f, 0.207131f, 0.218113f, 0.222941f, 0.232139f, 0.248192f, 0.249239f, 0.261572f, 0.246309f, 0.279145f, 0.285786f, 0.262528f, 0.271847f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz_fx[15]={7346, 7452, 7924, 6787, 7147, 7305, 7606, 8132, 8167, 8571, 8071, 9147, 9364, 8602, 8907,}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97},{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97},{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97}}; /* Sample Rate = 16000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_16kHz = 23; -const uint16_t CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]={{{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80},{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80}},{{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80},{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80}},{{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80},{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80}},{{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80},{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80}},{{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80},{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80}},{{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80},{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80}},{{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80},{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80}},{{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80},{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80}},{{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80},{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80}},{{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80},{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80}},{{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80},{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80}},{{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80},{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80}},{{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80},{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80}},{{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80},{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80}},{{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80},{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz = 77; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_16kHz = 23; +const UWord16 CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]={{{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80},{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80}},{{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80},{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80}},{{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80},{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80}},{{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80},{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80}},{{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80},{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80}},{{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80},{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80}},{{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80},{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80}},{{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80},{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80}},{{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80},{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80}},{{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80},{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80}},{{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80},{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80}},{{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80},{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80}},{{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80},{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80}},{{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80},{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80}},{{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80},{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz = 77; const float CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz[15]={0.223532f, 0.226827f, 0.248830f, 0.208782f, 0.220391f, 0.219790f, 0.231187f, 0.248730f, 0.251408f, 0.263698f, 0.243858f, 0.281483f, 0.283080f, 0.261660f, 0.273527f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz_fx[15]={7346, 7452, 7924, 6787, 7147, 7305, 7606, 8132, 8167, 8571, 8071, 9147, 9364, 8602, 8907}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]={{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77},{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]={{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77},{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77}}; //BRIR and HRIR coeff tables in Q29 const Word32 CRendBin_Combined_BRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][2955] ={ { diff --git a/lib_rend/ivas_rom_rend_fx.c b/lib_rend/ivas_rom_rend_fx.c index 54940355c..2b46ff611 100644 --- a/lib_rend/ivas_rom_rend_fx.c +++ b/lib_rend/ivas_rom_rend_fx.c @@ -49,9 +49,9 @@ const Word16 diffuse_response_CICP6_fx[5] = { 13824, 13824, 12137, 16495, 16495 const Word16 diffuse_response_CICP14_fx[7] = { 12507, 12507, 9237, 17691, 17691, 4977, 4977 };//Q15 const Word16 diffuse_response_CICP16_fx[9] = { 11324, 11324, 9945, 13513, 13513, 8853, 8853, 9905, 9905 };//Q15 -const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; +const Word16 ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; -const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; +const Word16 ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN] /*Q14*/ = { @@ -91,11 +91,11 @@ const Word16 ap_split_frequencies_fx[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]/*Q14*/ = 0 , 2048, 6144, 16384 }; -const int16_t sba_map_tc[11] = +const Word16 sba_map_tc[11] = { 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 }; -const int16_t sba_map_tc_512[11] = +const Word16 sba_map_tc_512[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 }; @@ -121,11 +121,11 @@ const int16_t sba_map_tc_512[11] = * 13 = 135, 35 * 14 = -135, 35 */ -const int16_t channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; -const int16_t channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; -const int16_t channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; -const int16_t channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; -const int16_t channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; +const Word16 channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; +const Word16 channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; +const Word16 channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; +const Word16 channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; +const Word16 channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; const Word16 surCohEne_fx[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS] /* Q13 */ = { @@ -160,7 +160,7 @@ const Word32 diffuseFieldCoherenceDifferenceZ_fx[BINAURAL_COHERENCE_DIFFERENCE_B * TD ISM binaural renderer ROM tables *----------------------------------------------------------------------------------*/ -const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = +const Word16 HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = { 13, 12, 11 }; diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 22ed7ed65..0a489600a 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -88,7 +88,7 @@ typedef enum IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN, } IVAS_REND_AudioConfigType; -typedef uint16_t IVAS_REND_InputId; +typedef UWord16 IVAS_REND_InputId; typedef enum _IVAS_REND_COMPLEXITY_LEVEL { -- GitLab From 919bec712ef79ca4e3f5d4f559c28d5032974833 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 12:49:24 +0530 Subject: [PATCH 0360/1221] Fix for 3GPP issue 1342: Decoder crash for Stereo at 48/64 kbps mono decoding in IMDCT_ivas_fx() Link #1342 --- lib_com/edct_fx.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index 8d77da13a..b1e2a7dd9 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -592,11 +592,12 @@ void edxt_fx( const UWord16 synthesis /* i : nonzero for inverse Q0*/ ) { - Word16 k, m, fac; + Word16 k, m, fac, hdrm, tmp = 0; const Word16 *cosPtr, *sinPtr; Word16 n; n = 0; move16(); + move16(); cosPtr = NULL; sinPtr = NULL; IF( EQ_16( length, 512 ) ) @@ -735,7 +736,23 @@ void edxt_fx( IF( EQ_16( length, 512 ) ) { + /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */ + hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) ); + IF( LT_16( hdrm, 4 ) ) + { + tmp = sub( hdrm, 4 ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } + DoRTFTn_fx( re, im, 512 ); + + IF( LT_16( hdrm, 4 ) ) + { + tmp = negate( tmp ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } } ELSE /* fft() doesn't support 512 */ { @@ -831,7 +848,23 @@ void edxt_fx( IF( EQ_16( length, 512 ) ) { + /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */ + hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) ); + IF( LT_16( hdrm, 4 ) ) + { + tmp = sub( hdrm, 4 ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } + DoRTFTn_fx( re, im, 512 ); + + IF( LT_16( hdrm, 4 ) ) + { + tmp = negate( tmp ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } } ELSE /* fft() doesn't support 512 */ { -- GitLab From 9d3de014d988ce108565071fe569b5f88bd9faed Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 13:51:43 +0530 Subject: [PATCH 0361/1221] Fix for 3GPP issue 1202: BASOP encoder ParamISM: strong timbre differences in the noise track - 2 [x] Link #1202 [x] Corrected the formula for the computation of xcorr_ene_fx which then rectifies the computation of hISMDTX->coh_fx that leads to proper value of idx being written to the bitstream on the encoder side. --- lib_enc/ivas_ism_dtx_enc_fx.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 64b8991d6..f99043708 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -445,9 +445,9 @@ void ivas_ism_coh_estim_dtx_enc_fx( Word16 sce_id, i; Word32 acorr_ene_fx[MAX_NUM_OBJECTS], xcorr_ene_fx; Word16 acorr_ene_e[MAX_NUM_OBJECTS], xcorr_ene_e; - Word16 norm_inp; - Word16 tot_exp; - Word32 scaled_inp; + Word16 norm_inp, norm_inp0; + Word16 tot_exp, tot_exp2; + Word32 scaled_inp, scaled_inp0; set16_fx( acorr_ene_e, 0, MAX_NUM_OBJECTS ); IF( EQ_16( nchan_transport, 1 ) ) @@ -493,10 +493,13 @@ void ivas_ism_coh_estim_dtx_enc_fx( { norm_inp = norm_l( st->input32_fx[i] ); scaled_inp = L_shl( st->input32_fx[i], norm_inp ); - tot_exp = shl( sub( 20, norm_inp ), 1 ); + tot_exp = shl( sub( sub(31, st->q_inp32), norm_inp ), 1 ); acorr_ene_fx[sce_id] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[sce_id], acorr_ene_e[sce_id], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[sce_id] ); /* exp(acorr_ene_e) */ move32(); - xcorr_ene_fx = BASOP_Util_Add_Mant32Exp( xcorr_ene_fx, xcorr_ene_e, Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &xcorr_ene_e ); /* exp(xcorr_ene_e) */ + norm_inp0 = norm_l( st_id0->input32_fx[i] ); + scaled_inp0 = L_shl( st_id0->input32_fx[i], norm_inp0 ); + tot_exp2 = add( sub( sub( 31, st_id0->q_inp32 ), norm_inp0 ), sub( sub( 31, st->q_inp32 ), norm_inp ) ); + xcorr_ene_fx = BASOP_Util_Add_Mant32Exp( xcorr_ene_fx, xcorr_ene_e, Mult_32_32( scaled_inp, scaled_inp0 ), tot_exp2, &xcorr_ene_e ); /* exp(xcorr_ene_e) */ } Word16 coh_e; Word16 temp_e = acorr_ene_e[hISMDTX->sce_id_dtx] + acorr_ene_e[sce_id]; -- GitLab From 22acde4d19351ed8a7c2fc93c338e6eb44276da5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:01:34 +0530 Subject: [PATCH 0362/1221] Clang formatting changes --- lib_enc/ivas_ism_dtx_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index f99043708..1a4110245 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -493,7 +493,7 @@ void ivas_ism_coh_estim_dtx_enc_fx( { norm_inp = norm_l( st->input32_fx[i] ); scaled_inp = L_shl( st->input32_fx[i], norm_inp ); - tot_exp = shl( sub( sub(31, st->q_inp32), norm_inp ), 1 ); + tot_exp = shl( sub( sub( 31, st->q_inp32 ), norm_inp ), 1 ); acorr_ene_fx[sce_id] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[sce_id], acorr_ene_e[sce_id], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[sce_id] ); /* exp(acorr_ene_e) */ move32(); norm_inp0 = norm_l( st_id0->input32_fx[i] ); -- GitLab From 4d386408b80762fd726b85cf4b3c4923be40ee8b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:07:06 +0530 Subject: [PATCH 0363/1221] Fix for 3GPP issue 1004: Modulation artifact in OMASA at 24 kbps using LTV 3ISM 2TC input and output to MONO Link #1004, #1363 Fixes 3GPP issue #1363: Assert in BASOP decoder function protoSignalComputation2_fx when fed with BASOP encoder MASA bitstream --- lib_rend/ivas_dirac_rend_fx.c | 93 ++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index cc8e4d8bd..958a23a3f 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1692,7 +1692,7 @@ void protoSignalComputation2_fx( Word32 min_sum_total_ratio_fx, min_sum_total_ratio_db_fx; Word32 sum_total_ratio_fx[MASA_SUM_FREQ_RANGE_BINS]; Word16 q_sum_total_ratio; - Word32 a_fx, b_fx; + Word32 a_fx, b_fx, a2_fx, b2_fx; Word16 interpolatorSpaced_fx, interpolatorDmx_fx; Word32 tempSpaced_fx, tempDmx_fx; Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; @@ -1700,6 +1700,7 @@ void protoSignalComputation2_fx( Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; + Word16 head_room, q_Left_Right_power; /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ min_q_shift = Q31; move16(); @@ -1866,8 +1867,10 @@ void protoSignalComputation2_fx( a_fx = 21474836; /*0.01 in Q31*/ /* Temporal smoothing coefficient */ move32(); b_fx = L_sub( ONE_IN_Q31, a_fx ); /* Temporal smoothing coefficient q31*/ - // a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ - // b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ + move32(); + a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ + move32(); + b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ IF( stereo_type_detect->interpolator > 0 ) { @@ -1890,6 +1893,23 @@ void protoSignalComputation2_fx( q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); + head_room = 63; + move16(); + FOR( l = 0; l < num_freq_bands; l++ ) + { + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + + W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); + W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); + + head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); + } + head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); + FOR( l = 0; l < num_freq_bands; l++ ) { re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -1904,26 +1924,26 @@ void protoSignalComputation2_fx( /* Compute reference power */ // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift) - Left_power_fx = W_extract_l( W_shr( W_tmp1, 31 ) ); + Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) ); // q_Left_Right_power // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift) - Right_power_fx = W_extract_l( W_shr( W_tmp2, 31 ) ); + Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) ); // q_Left_Right_power // reference_power_fx[l] = L_add( Left_power_fx, Right_power_fx ); reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift) move64(); - left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { - left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power + right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); - total_hi_power_fx = L_add( total_hi_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) @@ -1960,12 +1980,17 @@ void protoSignalComputation2_fx( test(); IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) { - sum_total_ratio_fx[l] = MAX_16; // q15 + sum_total_ratio_fx[l] = MAX_32; // q15 + move32(); + } + ELSE IF( stereo_type_detect->total_power_fx[l] == 0 ) + { + sum_total_ratio_fx[l] = MAX_32; // q15 move32(); } ELSE { - sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], L_add( stereo_type_detect->total_power_fx[l], EPSILON_FX ), &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) + sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 @@ -2237,45 +2262,45 @@ void protoSignalComputation2_fx( } } - temp = Mpy_32_32( a_fx, left_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_left_bb_power ) ) + temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ) { - stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_left_bb_power = q_temp; + stereo_type_detect->q_left_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->left_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_left_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ) ); // stereo_type_detect->q_left_bb_power + stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power move32(); } - temp = Mpy_32_32( a_fx, right_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_right_bb_power ) ) + temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ) { - stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_right_bb_power = q_temp; + stereo_type_detect->q_right_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->right_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_right_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ) ); // stereo_type_detect->q_right_bb_power + stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power move32(); } - temp = Mpy_32_32( a_fx, total_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_total_bb_power ) ) + temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ) { - stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_total_bb_power = q_temp; + stereo_type_detect->q_total_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->total_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ) ); // stereo_type_detect->q_total_bb_power + stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power move32(); } @@ -2293,8 +2318,7 @@ void protoSignalComputation2_fx( q_lr_bb_power = stereo_type_detect->q_right_bb_power; move16(); } - q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ - + q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power)) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_bb_power, stereo_type_detect->q_total_bb_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 @@ -2305,15 +2329,15 @@ void protoSignalComputation2_fx( // 20480 = 10 in Q11 lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); move16(); - stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); move32(); stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); move16(); @@ -2330,8 +2354,7 @@ void protoSignalComputation2_fx( move32(); q_lr_hi_power = stereo_type_detect->q_right_hi_power; } - q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ - + q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_hi_power, stereo_type_detect->q_total_hi_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 -- GitLab From b2a9054e28a698b6e1f7f91f85e98a0c1d23a73f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:14:28 +0530 Subject: [PATCH 0364/1221] Fix for 3GPP issue 1048: Problem in stereo during bitrate switching and frame erasure Link #1048 --- lib_dec/er_dec_tcx_fx.c | 2 +- lib_dec/ivas_mdct_core_dec_fx.c | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 8c10e5f81..5cc06dabf 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -1168,7 +1168,7 @@ void con_tcx_ivas_fx( /* apply pre-emphasis to the signal */ mem = synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )]; /*Q0*/ move16(); - Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); + Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); st->Mode2_lp_gainc = L_deposit_l( 0 ); st->Mode2_lp_gainp = get_gain2( synth - shl( L_subfr, 1 ), synth - add( shl( L_subfr, 1 ), Tc ), shl( L_subfr, 1 ) ); diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 7f079277a..a5855a0f6 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1282,11 +1282,6 @@ void ivas_mdct_core_reconstruct_fx( ELSE /*ACELP core for ACELP-PLC */ { assert( EQ_16( st->bfi, 1 ) ); - - Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( -2, q_syn ) ); // Q0 - Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( -2, q_syn ) ); // Q0 - q_syn = -2; - move16(); /* PLC: [TCX: TD PLC] */ IF( MCT_flag != 0 ) { @@ -1316,11 +1311,11 @@ void ivas_mdct_core_reconstruct_fx( IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || ( st->hTcxDec->tcxConceal_recalc_exc != 0 ) ) { - Scale_sig( synthFB_fx - add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) + Scale_sig( synthFB_fx - add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), sub( add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), 1 ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) } ELSE { - Scale_sig( synthFB_fx - st->hTcxDec->L_frameTCX, st->hTcxDec->L_frameTCX, sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) + Scale_sig( synthFB_fx - st->hTcxDec->L_frameTCX, sub( st->hTcxDec->L_frameTCX, 1 ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) } lerp( synthFB_fx, synth_fx, st->L_frame, st->hTcxDec->L_frameTCX ); -- GitLab From f0586ef9c852dfb866511c4c31789b6e39d82b34 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:34:44 +0530 Subject: [PATCH 0365/1221] Fix for 3GPP issue 1327: Glitch when stereo is switching from TD to FD Link #1327 --- lib_com/options.h | 1 + lib_enc/ivas_stereo_switching_enc_fx.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 563855275..d03261715 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -171,4 +171,5 @@ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ +#define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ #endif diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 6513a3fa7..cbdbc0501 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -680,6 +680,10 @@ void stereo_switching_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); /* sts[n]->q_inp */ +#ifdef FIX_ISSUE_1327 + hCPE->q_input_mem[n] = sts[n]->q_inp; + move16(); +#endif } } -- GitLab From 17cc7bd3bf313372b8009f59c1ee3cead1cc96b6 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 11 Mar 2025 13:18:07 +0100 Subject: [PATCH 0366/1221] minor wmops improvement in sns_1st_cod_fx_q15. --- lib_enc/ivas_sns_enc_fx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index b615e5abe..3ae1ea424 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -204,7 +204,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_add( sns_fx[i], L_negate( tmp ) ); + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } @@ -234,9 +234,10 @@ static Word16 sns_1st_cod_fx_q15( move32(); FOR( Word16 j = j0; j < j1; ++j ) { + Word32 tmp; Word32 dist; - Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 + dist = L_sub( snsq_fx[j], tmp ); dist = L_shr( dist, 4 ); // TODO: Magic shift. dist = L_mult( extract_l( dist ), extract_l( dist ) ); dist = L_shr( dist, 4 ); // TODO: Magic shift @@ -254,8 +255,8 @@ static Word16 sns_1st_cod_fx_q15( cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( *cdbk_ptr++ , cdbk_fix ); // Q16 snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } -- GitLab From c2d223dab8078c0e12726f33b7396c1235f43dbe Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 19:34:14 +0530 Subject: [PATCH 0367/1221] Bug fixes, ivas_prot.h cleanup, Q documentation updates --- lib_com/bitstream.c | 1 - lib_com/core_com_config.c | 1 - lib_com/fft_fx.c | 20 + lib_com/gs_bitallocation_ivas_fx.c | 1 - lib_com/ivas_agc_com_fx.c | 1 - lib_com/ivas_arith_fx.c | 1 - lib_com/ivas_cov_smooth_fx.c | 1 - lib_com/ivas_dirac_com_fx.c | 1 - lib_com/ivas_entropy_coder_common_fx.c | 1 - lib_com/ivas_fb_mixer_fx.c | 1 - lib_com/ivas_filters_fx.c | 1 - lib_com/ivas_ism_com_fx.c | 1 - lib_com/ivas_lfe_com_fx.c | 1 - lib_com/ivas_masa_com_fx.c | 1 - lib_com/ivas_mc_com_fx.c | 1 - lib_com/ivas_mc_param_com_fx.c | 1 - lib_com/ivas_mcmasa_com-fx.c | 1 - lib_com/ivas_mct_com_fx.c | 2 +- lib_com/ivas_mdct_core_com_fx.c | 1 - lib_com/ivas_mdft_imdft_fx.c | 1 - lib_com/ivas_omasa_com_fx.c | 1 - lib_com/ivas_pca_tools_fx.c | 1 - lib_com/ivas_prot_fx.h | 817 ++++++++++++++++++ lib_com/ivas_qmetadata_com_fx.c | 1 - lib_com/ivas_qspherical_com_fx.c | 1 - lib_com/ivas_sba_config_fx.c | 1 - lib_com/ivas_sns_com_fx.c | 177 ++-- lib_com/ivas_spar_com_fx.c | 1 - lib_com/ivas_spar_com_quant_util_fx.c | 1 - lib_com/ivas_stereo_dft_com_fx.c | 1 - lib_com/ivas_stereo_eclvq_com_fx.c | 1 - lib_com/ivas_stereo_ica_com_fx.c | 1 - lib_com/ivas_stereo_mdct_bands_com_fx.c | 1 - lib_com/ivas_stereo_mdct_stereo_com_fx.c | 1 - lib_com/ivas_stereo_psychlpc_com_fx.c | 2 - lib_com/ivas_stereo_td_bit_alloc_fx.c | 1 - lib_com/ivas_tools_fx.c | 1 - lib_com/ivas_transient_det_fx.c | 1 - lib_com/mslvq_com.c | 1 - lib_com/prot_fx.h | 1 + lib_com/swb_tbe_com.c | 1 - lib_dec/ACcontextMapping_dec_fx.c | 1 - lib_dec/acelp_core_dec_ivas_fx.c | 1 - lib_dec/dec_tcx_fx.c | 1 - lib_dec/igf_dec_fx.c | 5 +- lib_dec/ivas_agc_dec_fx.c | 1 - lib_dec/ivas_binRenderer_internal_fx.c | 1 - lib_dec/ivas_core_dec_fx.c | 1 - lib_dec/ivas_corecoder_dec_reconfig_fx.c | 1 - lib_dec/ivas_cpe_dec_fx.c | 1 - lib_dec/ivas_decision_matrix_dec_fx.c | 1 - lib_dec/ivas_dirac_dec_fx.c | 1 - lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 1 - lib_dec/ivas_entropy_decoder_fx.c | 1 - lib_dec/ivas_init_dec.c | 1 - lib_dec/ivas_ism_dec_fx.c | 1 - lib_dec/ivas_ism_dtx_dec_fx.c | 1 - lib_dec/ivas_ism_metadata_dec_fx.c | 1 - lib_dec/ivas_ism_param_dec_fx.c | 1 - lib_dec/ivas_ism_renderer_fx.c | 1 - lib_dec/ivas_jbm_dec_fx.c | 1 - lib_dec/ivas_lfe_dec_fx.c | 1 - lib_dec/ivas_lfe_plc_fx.c | 1 - lib_dec/ivas_ls_custom_dec_fx.c | 1 - lib_dec/ivas_masa_dec_fx.c | 1 - lib_dec/ivas_mc_param_dec_fx.c | 1 - lib_dec/ivas_mc_paramupmix_dec_fx.c | 1 - lib_dec/ivas_mcmasa_dec_fx.c | 1 - lib_dec/ivas_mct_core_dec_fx.c | 1 - lib_dec/ivas_mct_dec_fx.c | 1 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 1 - lib_dec/ivas_mdct_core_dec_fx.c | 1 - lib_dec/ivas_mono_dmx_renderer_fx.c | 1 - lib_dec/ivas_objectRenderer_internal_fx.c | 1 - lib_dec/ivas_omasa_dec_fx.c | 1 - lib_dec/ivas_osba_dec_fx.c | 1 - lib_dec/ivas_out_setup_conversion_fx.c | 1 - lib_dec/ivas_output_config_fx.c | 1 - lib_dec/ivas_pca_dec_fx.c | 1 - lib_dec/ivas_post_proc_fx.c | 1 - lib_dec/ivas_qmetadata_dec_fx.c | 1 - lib_dec/ivas_qspherical_dec_fx.c | 1 - lib_dec/ivas_range_uni_dec_fx.c | 1 - lib_dec/ivas_sba_dec_fx.c | 1 - lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 1 - lib_dec/ivas_sba_rendering_internal_fx.c | 1 - lib_dec/ivas_sce_dec_fx.c | 1 - lib_dec/ivas_sns_dec_fx.c | 1 - lib_dec/ivas_spar_decoder_fx.c | 1 - lib_dec/ivas_spar_md_dec_fx.c | 1 - lib_dec/ivas_stereo_adapt_GR_dec_fx.c | 1 - lib_dec/ivas_stereo_cng_dec.c | 1 - lib_dec/ivas_stereo_dft_dec.c | 1 - lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 1 - lib_dec/ivas_stereo_dft_dec_fx.c | 1 - lib_dec/ivas_stereo_dft_plc_fx.c | 1 - lib_dec/ivas_stereo_eclvq_dec_fx.c | 1 - lib_dec/ivas_stereo_esf_dec_fx.c | 1 - lib_dec/ivas_stereo_ica_dec_fx.c | 1 - lib_dec/ivas_stereo_icbwe_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_core_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 1 - lib_dec/ivas_stereo_switching_dec_fx.c | 1 - lib_dec/ivas_stereo_td_dec_fx.c | 40 - lib_dec/ivas_svd_dec_fx.c | 1 - lib_dec/ivas_tcx_core_dec_fx.c | 1 - lib_dec/ivas_td_low_rate_dec_fx.c | 1 - lib_dec/lib_dec_fx.c | 1 - lib_dec/lsf_dec_fx.c | 1 - lib_enc/ACcontextMapping_enc_fx.c | 1 - lib_enc/acelp_core_enc_fx.c | 1 - lib_enc/cod4t64_fast.c | 1 - lib_enc/cod_tcx_fx.c | 1 - lib_enc/ext_sig_ana_fx.c | 40 +- lib_enc/igf_enc.c | 1 - lib_enc/ivas_agc_enc_fx.c | 1 - lib_enc/ivas_core_enc_fx.c | 1 - lib_enc/ivas_core_pre_proc_front_fx.c | 1 - lib_enc/ivas_core_pre_proc_fx.c | 1 - lib_enc/ivas_corecoder_enc_reconfig_fx.c | 1 - lib_enc/ivas_cpe_enc_fx.c | 1 - lib_enc/ivas_decision_matrix_enc_fx.c | 1 - lib_enc/ivas_dirac_enc_fx.c | 1 - lib_enc/ivas_enc_cov_handler_fx.c | 1 - lib_enc/ivas_enc_fx.c | 1 - lib_enc/ivas_entropy_coder_fx.c | 1 - lib_enc/ivas_front_vad_fx.c | 25 - lib_enc/ivas_init_enc_fx.c | 1 - lib_enc/ivas_ism_dtx_enc_fx.c | 1 - lib_enc/ivas_ism_enc_fx.c | 1 - lib_enc/ivas_ism_metadata_enc_fx.c | 1 - lib_enc/ivas_ism_param_enc_fx.c | 1 - lib_enc/ivas_lfe_enc_fx.c | 1 - lib_enc/ivas_masa_enc_fx.c | 1 - lib_enc/ivas_mc_param_enc_fx.c | 1 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 1 - lib_enc/ivas_mcmasa_enc_fx.c | 1 - lib_enc/ivas_mct_core_enc_fx.c | 1 - lib_enc/ivas_mct_enc_fx.c | 1 - lib_enc/ivas_mct_enc_mct_fx.c | 1 - lib_enc/ivas_mdct_core_enc_fx.c | 29 +- lib_enc/ivas_omasa_enc_fx.c | 1 - lib_enc/ivas_osba_enc_fx.c | 1 - lib_enc/ivas_pca_enc_fx.c | 1 - lib_enc/ivas_qmetadata_enc_fx.c | 1 - lib_enc/ivas_qspherical_enc_fx.c | 1 - lib_enc/ivas_range_uni_enc_fx.c | 1 - lib_enc/ivas_sba_enc_fx.c | 1 - lib_enc/ivas_sce_enc_fx.c | 1 - lib_enc/ivas_sns_enc_fx.c | 1 - lib_enc/ivas_spar_encoder_fx.c | 1 - lib_enc/ivas_spar_md_enc_fx.c | 1 - lib_enc/ivas_stereo_adapt_GR_enc_fx.c | 1 - lib_enc/ivas_stereo_classifier_fx.c | 1 - lib_enc/ivas_stereo_cng_enc_fx.c | 1 - lib_enc/ivas_stereo_dft_enc_fx.c | 1 - lib_enc/ivas_stereo_dft_enc_itd_fx.c | 1 - lib_enc/ivas_stereo_dft_td_itd_fx.c | 1 - lib_enc/ivas_stereo_dmx_evs_fx.c | 1 - lib_enc/ivas_stereo_eclvq_enc_fx.c | 1 - lib_enc/ivas_stereo_ica_enc_fx.c | 1 - lib_enc/ivas_stereo_icbwe_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_core_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_igf_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 1 - lib_enc/ivas_stereo_switching_enc_fx.c | 1 - lib_enc/ivas_stereo_td_analysis_fx.c | 1 - lib_enc/ivas_stereo_td_enc_fx.c | 1 - lib_enc/ivas_tcx_core_enc_fx.c | 1 - lib_enc/ivas_td_low_rate_enc_fx.c | 1 - lib_enc/lib_enc.c | 1 - lib_enc/lp_exc_e_fx.c | 106 +-- lib_enc/lsf_enc_fx.c | 147 ++-- lib_enc/lsf_msvq_ma_enc.c | 27 +- lib_enc/lsf_msvq_ma_enc_fx.c | 52 +- lib_enc/ltd_stable_fx.c | 63 +- lib_enc/mdct_classifier_fx.c | 99 +-- lib_enc/mdct_selector_fx.c | 36 +- lib_enc/mslvq_enc_fx.c | 52 +- lib_enc/multi_harm_fx.c | 16 +- lib_enc/speech_music_classif_fx.c | 1 - lib_enc/swb_pre_proc_fx.c | 1 - lib_enc/swb_tbe_enc_fx.c | 1 - lib_rend/ivas_allrad_dec_fx.c | 1 - lib_rend/ivas_crend_fx.c | 1 - lib_rend/ivas_dirac_ana_fx.c | 1 - .../ivas_dirac_dec_binaural_functions_fx.c | 1 - lib_rend/ivas_dirac_decorr_dec_fx.c | 1 - lib_rend/ivas_dirac_onsets_dec_fx.c | 1 - lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 1 - lib_rend/ivas_dirac_rend_fx.c | 1 - lib_rend/ivas_efap_fx.c | 1 - lib_rend/ivas_hrtf_fx.c | 1 - lib_rend/ivas_masa_merge_fx.c | 1 - lib_rend/ivas_mcmasa_ana_fx.c | 1 - lib_rend/ivas_objectRenderer_fx.c | 1 - lib_rend/ivas_omasa_ana_fx.c | 1 - lib_rend/ivas_orient_trk_fx.c | 1 - lib_rend/ivas_output_init.c | 1 - lib_rend/ivas_output_init_fx.c | 1 - lib_rend/ivas_reflections_fx.c | 1 - lib_rend/ivas_reverb_delay_line_fx.c | 1 - lib_rend/ivas_sba_rendering_fx.c | 1 - lib_rend/ivas_td_decorr_fx.c | 1 - lib_rend/ivas_vbap_fx.c | 1 - lib_rend/lib_rend.c | 1 - lib_util/hrtf_file_reader.c | 1 - lib_util/ls_custom_file_reader.c | 2 +- lib_util/masa_file_reader.c | 1 - 209 files changed, 1267 insertions(+), 679 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 9c0a53f8f..90b49f8c2 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -43,7 +43,6 @@ #include "stat_dec.h" #include "rom_com.h" #include "mime.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index ed72605de..f0ee8efd8 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 73ff582df..7b63e9c67 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -7636,6 +7636,26 @@ Word16 norm_arr( Word16 *arr, Word16 size ) return q; } +Word16 W_norm_arr( Word64 *arr, Word16 size ) +{ + Word16 q = 63; + Word16 exp = 0; + move16(); + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + if ( arr[i] != 0 ) + { + exp = W_norm( arr[i] ); + } + if ( arr[i] != 0 ) + { + q = s_min( q, exp ); + } + } + return q; +} + Word16 get_min_scalefactor( Word32 x, Word32 y ) { #ifndef FIX_1104_OPT_GETMINSCALEFAC diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 0921dc88c..71b30ea75 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_agc_com_fx.c b/lib_com/ivas_agc_com_fx.c index 94e6b222f..3f6e181ef 100644 --- a/lib_com/ivas_agc_com_fx.c +++ b/lib_com/ivas_agc_com_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_arith_fx.c b/lib_com/ivas_arith_fx.c index 006a31177..311bccff8 100644 --- a/lib_com/ivas_arith_fx.c +++ b/lib_com/ivas_arith_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "wmc_auto.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index acc0df821..3a93ed1f5 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 9b60b2c5c..146587791 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_entropy_coder_common_fx.c b/lib_com/ivas_entropy_coder_common_fx.c index 99381d19a..f52d59859 100644 --- a/lib_com/ivas_entropy_coder_common_fx.c +++ b/lib_com/ivas_entropy_coder_common_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" #include "prot_fx.h" diff --git a/lib_com/ivas_fb_mixer_fx.c b/lib_com/ivas_fb_mixer_fx.c index 883861024..d5cd8d4f1 100644 --- a/lib_com/ivas_fb_mixer_fx.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_filters_fx.c b/lib_com/ivas_filters_fx.c index 7705deb6a..1e9aaf0c2 100644 --- a/lib_com/ivas_filters_fx.c +++ b/lib_com/ivas_filters_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index f1201b06c..5f1a13afb 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_lfe_com_fx.c b/lib_com/ivas_lfe_com_fx.c index 7464c41c2..3d1e7aee6 100644 --- a/lib_com/ivas_lfe_com_fx.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_stat_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_com/ivas_masa_com_fx.c b/lib_com/ivas_masa_com_fx.c index fbe752aad..cfed06357 100644 --- a/lib_com/ivas_masa_com_fx.c +++ b/lib_com/ivas_masa_com_fx.c @@ -36,7 +36,6 @@ #include #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_mc_com_fx.c b/lib_com/ivas_mc_com_fx.c index 62d623b83..8201037a1 100644 --- a/lib_com/ivas_mc_com_fx.c +++ b/lib_com/ivas_mc_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_param_com_fx.c b/lib_com/ivas_mc_param_com_fx.c index a54abe7ab..4469e7f93 100644 --- a/lib_com/ivas_mc_param_com_fx.c +++ b/lib_com/ivas_mc_param_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_mcmasa_com-fx.c b/lib_com/ivas_mcmasa_com-fx.c index da0b8f1c4..23a3800fb 100644 --- a/lib_com/ivas_mcmasa_com-fx.c +++ b/lib_com/ivas_mcmasa_com-fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "ivas_cnst.h" -#include "ivas_prot.h" #include "options.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mct_com_fx.c b/lib_com/ivas_mct_com_fx.c index 1f3c58153..81a56df14 100644 --- a/lib_com/ivas_mct_com_fx.c +++ b/lib_com/ivas_mct_com_fx.c @@ -33,8 +33,8 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com_fx.c b/lib_com/ivas_mdct_core_com_fx.c index 000f3992f..fe313eecd 100644 --- a/lib_com/ivas_mdct_core_com_fx.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mdft_imdft_fx.c b/lib_com/ivas_mdft_imdft_fx.c index b10444307..5d7bee1a6 100644 --- a/lib_com/ivas_mdft_imdft_fx.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_omasa_com_fx.c b/lib_com/ivas_omasa_com_fx.c index ef6350285..1c1d4bf6c 100644 --- a/lib_com/ivas_omasa_com_fx.c +++ b/lib_com/ivas_omasa_com_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_pca_tools_fx.c b/lib_com/ivas_pca_tools_fx.c index 1e36c5e8e..c84078a7d 100644 --- a/lib_com/ivas_pca_tools_fx.c +++ b/lib_com/ivas_pca_tools_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include #include diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 4a72b194a..6b23f8eed 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -5896,4 +5896,821 @@ void reset_metadata_spatial_fx( const Word32 core_brate, /* i : core bitrate */ const Word16 nb_bits_metadata /* i : number of meatdata bits */ ); + +/*=============================================================================================*/ +/* clang-format off */ + +/*----------------------------------------------------------------------------------* + * General IVAS prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: number of channels to be analysed */ + +void copy_encoder_config_ivas_fx( + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Encoder_State *st, /* o : encoder state structure */ + const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ +); + +ivas_error create_mct_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void destroy_cpe_enc( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ +); + +void ivas_mct_enc_close_fx( + MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ +); + +ivas_error pre_proc_front_ivas_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 element_brate, /* i : SCE/CPE element bitrate Q0*/ + const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + const Word16 n, /* i : channel number Q0*/ + Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 *relE_fx, /* o : frame relative energy Q8*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[M + 1], /* o : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, + Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15*/ + Word16 *vad_hover_flag, /* o : VAD hangover flag Q0*/ + Word16 *attack_flag, /* o : flag signaling attack Q0*/ + Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf)*/ + Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf)*/ + Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ + Word16 old_wsp_fx[], /* o : weighted input signal buffer q_old_wsp*/ + Word16 *q_old_wsp, + Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6*/ + Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15*/ + Word16 *loc_harm, /* o : harmonicity flag Q0*/ + Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8*/ + Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 *enerBuffer_fx_exp, /* o : energy buffer */ + Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer fft_buff_fx_q*/ + Word16 *fft_buff_fx_q, /* o : FFT buffer */ + const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ + const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ + const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ + const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ + Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ + Word16 fr_bands_LR_fx_q[CPE_CHANNELS], + const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ + Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q)*/ + Word16 lf_E_LR_fx_q, + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ + Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ + Word16 band_energies_LR_fx_q, + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ + const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ + const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ +#ifdef NONBE_1211_DTX_BR_SWITCHING + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ +#endif + const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ + Word16 *Q_new +#ifdef DEBUG_MODE_INFO + , + const Word16 ch_idx +#endif +); +ivas_error pre_proc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 last_element_mode, /* i : last element mode Q0*/ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word32 last_element_brate, /* i : last element bitrate Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal Q_new-1 */ + Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz Q_new-1 */ + Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame Q_new*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes Q14*/ + Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, /* i : LP prediction errors */ + Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ + Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE Q_new-1*/ + Word16 *Voicing_flag, /* o : voicing flag for HQ FEC Q0*/ + Word16 old_wsp_fx[], /* i : weighted input signal buffer e_old_wsp*/ + Word16 e_old_wsp, + const Word16 loc_harm, /* i : harmonicity flag Q0*/ + const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO Q0*/ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* e_enerBuffer */ + Word16 e_enerBuffer, + Word16 fft_buff_fx[2 * L_FFT], /* Qx */ + Word16 cor_map_sum_fx, /* Q8 */ + Word16 *Q_new +); +/*! r: number of clipped samples */ +void ivas_initialize_handles_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +ivas_error ivas_init_encoder( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_destroy_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +ivas_error ivas_initialize_MD_bstr_enc_fx( + BSTR_ENC_HANDLE *hBstr, /* o : encoder MD bitstream handle */ + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_destroy_MD_bstr_enc_fx( + BSTR_ENC_HANDLE *hMetaData /* i/o: encoder MD bitstream handle */ +); + +ivas_error ivas_init_decoder_front( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +void ivas_mct_dec_close( + MCT_DEC_HANDLE *hMCT /* i/o: MCT decoder structure */ +); + +/*! r: number of channels to be synthesised */ + +void copy_decoder_config( + Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ + Decoder_State *st /* o : decoder state structure */ +); + +void ivas_initialize_handles_dec( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_core_enc_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + const Word16 n_CoreChannels, /* i : number of core channels to be coded Q0*/ + Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal Q_new-1*/ + Word16 Q_new[], + Word32 ener_fx[], /* i : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 epsP_fx_q[], /* i : LP prediction errors */ + Word16 lsp_new_fx[][M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[][M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag[], /* i : VAD hanglover flag Q0*/ + Word16 attack_flag[], /* i : attack flag (GSC or TC) Q0*/ + Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer q_re_im_buf*/ + Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer q_re_im_buf*/ + Word16 *q_re_im_buf, + Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer e_old_wsp*/ + Word16 e_old_wsp[], + const Word16 loc_harm[], /* i : harmonicity flag Q0*/ + const Word16 cor_map_sum_fx[], /* i : speech/music clasif. parameter Q8*/ + const Word16 vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 enerBuffer_fx_exp[], /* o : energy buffer */ + Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer Qx*/ + const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag Q0*/ + const Word16 ivas_format, /* i : IVAS format Q0*/ + const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ +); + +void ivas_renderer_select( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_mc_enc_config_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*! r: flag indicating a valid bitrate */ +Word16 is_IVAS_bitrate_fx( + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +int16_t is_DTXrate( + const int32_t ivas_total_brate /* i : IVAS total bitrate */ +); + + +/*----------------------------------------------------------------------------------* + * JBM prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_jbm_dec_set_discard_samples( + Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ +); + +TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( + Decoder_Struct *st_ivas /* i : IVAS decoder handle */ +); + +void ivas_jbm_dec_tc_buffer_close( + DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ +); + +void ivas_jbm_dec_td_renderers_adapt_subframes( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_jbm_dec_metadata_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_jbm_masa_sf_to_sf_map( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +/*----------------------------------------------------------------------------------* + * ISM prototypes + *----------------------------------------------------------------------------------*/ + +void bitbudget_to_brate( + const Word16 x[], /* i : bitbudgets Q0 */ + Word32 y[], /* o : bitrates Q0 */ + const Word16 N /* i : number of entries to be converted */ +); + +void ivas_ism_reset_metadata( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ +); + +void ivas_ism_reset_metadata_enc( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ +); +void ivas_ism_reset_metadata_API( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ +); + +/*! r: index of the winning codeword */ +Word16 ism_quant_meta_fx( + const Word32 val, /* i : scalar value to quantize Q22 */ + Word32 *valQ, /* o : quantized value Q22 */ + const Word32 borders_fx[], /* i : level borders Q22 */ + const Word32 q_step_fx, /* i : quantization step Q22 */ + const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */ + const Word16 cbsize /* i : codebook size */ +); + +ivas_error ivas_ism_metadata_enc_create_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 n_ISms, /* i : number of objects */ + Word32 element_brate_tmp[] /* o : element bitrate per object */ +); + +/*----------------------------------------------------------------------------------* + * Parametric ISM prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: ISM format mode */ + +ivas_error ivas_param_ism_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_param_ism_enc_close_fx( + PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ + const Word32 input_Fs /* i : input sampling_rate */ +); + +void ivas_ism_metadata_close( + ISM_METADATA_HANDLE hIsmMetaData[], /* i/o : object metadata handles */ + const Word16 first_idx /* i : index of first handle to deallocate */ +); + + +ivas_error ivas_ism_enc_config( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*----------------------------------------------------------------------------------* + * ISM DTX prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_ism_dtx_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_ism_metadata_sid_enc_fx( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + const Word16 flag_noisy_speech, /* i : noisy speech flag */ + const Word16 nchan_ism, /* i : number of objects */ + const Word16 nchan_transport, /* i : number of transport channels */ + const ISM_MODE ism_mode, /* i : ISM mode */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const Word16 sid_flag, /* i : indication of SID frame */ + const Word16 md_diff_flag[], /* i : metadata differental flag */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + Word16 nb_bits_metadata[] /* o : number of metadata bits */ +); + + + +void ivas_param_ism_compute_noisy_speech_flag_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*----------------------------------------------------------------------------------* + * DFT Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void stereo_dft_dec_destroy( + STEREO_DFT_DEC_DATA_HANDLE *hStereoDft /* i/o: decoder DFT stereo handle */ +); + +/*----------------------------------------------------------------------------------* + * Range Coder prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: Read bit */ +UWord16 rc_uni_dec_read_bit( + RangeUniDecState *rc_st_dec /* i/o: RC state handle */ +); + +/*! r: Read bit */ +UWord16 rc_uni_dec_read_bit_prob_fast( + RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ + const Word16 freq0, /* i : Frequency for symbol 0 */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +); + +/*! r: Read bits */ +UWord16 rc_uni_dec_read_bits( + RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ + const Word16 bits /* i : Number of bits */ +); + + +/*----------------------------------------------------------------------------------* + * TD Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void tdm_bit_alloc( + const Word16 ivas_format, /* i : IVAS format */ + const Word16 ism_mode, /* i : ISM mode in combined format */ + const Word32 element_brate_wo_meta, /* i : element bitrate without metadata */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reusage flag */ + Word32 *total_brate_pri, /* o : Allocated primary channel bitrate */ + Word32 *total_brate_sec, /* o : Allocated secondary channel bitrate */ + Word16 *tdm_low_rate_mode, /* o : secondary channel low rate mode flag */ + const Word16 coder_type, /* i : secondary channel coder type */ + const Word16 ener_ratio_idx, /* i : correlation ratio indexe */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 bwidth_pri, /* i : bandwidth of the primary channel */ + const Word16 bwidth_sec, /* i : bandwidth of the secondary channel */ + const Word16 flag_ACELP16k_pri, /* i : ACELP@16kHz core flag, primary chan. */ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 coder_type0, /* i : coder type (temporary in the encoder, from bitstream in decoder) */ + const Word16 tdm_inst_ratio_idx /* i : instantaneous correlation ratio index */ +); + + +/*! r: value of the indice */ +uint16_t get_indice_st( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 pos, /* i : absolute position in the bitstream */ + const Word16 nb_bits /* i : number of bits to quantize the indice */ +); + +/*----------------------------------------------------------------------------------* + * MDCT Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void stereo_mdct_core_enc_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples Q0*/ + Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP Qx*/ + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe Q6*/ +); + +Word16 write_stereo_to_bitstream_fx +( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +); + +/*----------------------------------------------------------------------------------* + * Stereo CNG prototypes + *----------------------------------------------------------------------------------*/ +void stereo_cng_dec_update( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ +); + + +/*----------------------------------------------------------------------------------* + * Framework general prototypes + *----------------------------------------------------------------------------------*/ + +void mvc2c( + const uint8_t x[], /* i : input vector */ + uint8_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void stereo_switching_dec( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ +); + + +/*! r: number of bits written */ + + + +/*----------------------------------------------------------------------------------* + * MCT prototypes + *----------------------------------------------------------------------------------*/ +void ivas_mdct_core_whitening_enc_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples */ + Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ + Word16 pitch_buf[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe */ + Word32 *mdst_spectrum_long[CPE_CHANNELS], /* o : buffer for MDST spectrum */ + Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* o : buffer TNS bits */ + Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening */ + Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* o : size of TNS */ + Word16 p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to parameter array */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ + const Word16 nChannels, /* i : total number of coded channels */ +Word16 mdst_spectrum_e[CPE_CHANNELS][NB_DIV], +Word16 orig_spectrum_e[CPE_CHANNELS][NB_DIV] +); + +void splitAvailableBitsMCT_fx( + void **sts, /* i/o: encoder/decoder state structure */ + const Word16 total_bits, /* i : total number of available bits */ + const Word16 split_ratio[MCT_MAX_CHANNELS], /* i : ratio for splitting the bits Q0 */ + const Word16 enc_dec, /* i : encoder or decoder flag */ + const Word16 nchan /* i : number of channels */ +); + +void enc_prm_igf_mdct( + Encoder_State *st, /* i : Encoder state handle */ + BSTR_ENC_HANDLE hBstr /* i/o: Bitstream handle */ +); + +/*----------------------------------------------------------------------------------* + * Q Metadata prototypes for DirAC and MASA + *----------------------------------------------------------------------------------*/ +/*! r: number of bits written */ + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_decode( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */ +); + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_decode_hr_384_512( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const SPHERICAL_GRID_DATA *sph_grid16, /* i : spherical grid for deindexing */ + const Word16 bits_sph_idx, + const Word16 bits_sp_coh, + const UWord8 ncoding_bands_config +); + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_sid_decode( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const Word16 nchan_transport, /* i : number of transport channels */ + Word16 *element_mode, /* o : element mode */ + const Word16 ivas_format /* i : IVAS format */ +); + + +UWord16 ivas_qmetadata_reorder_generic_fx( + const Word16 signed_value +); + +void ivas_sba_set_cna_cng_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +/*! r: number of ambisonics metadata channels */ + +void ivas_sba_dirac_stereo_config( + STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */ +); + + +Word16 ivas_get_sba_dirac_stereo_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +/*----------------------------------------------------------------------------------* + * DirAC prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_dirac_enc_reconfigure( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +ivas_error ivas_mc_paramupmix_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_mc_paramupmix_enc_close_fx( + MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ + const int32_t input_Fs /* i : input sampling rate */ +); + +ivas_error ivas_mc_paramupmix_dec_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_mc_paramupmix_dec_close( + MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */ +); + +void ivas_mc_paramupmix_dec_read_BS( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_State *st, /* i/o: decoder state structure */ + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */ + Word16 *nb_bits /* o : number of bits written */ +); + +void ivas_mc_paramupmix_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + const Word16 nSamplesForRendering /* i : number of samples provided */ +); + +void ivas_param_mc_set_coded_bands_fx( + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* i/o: handle for the Parametric MC parameter coding state */ +); + +UWord16 ivas_param_mc_get_configuration_index_fx( + const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +/*----------------------------------------------------------------------------------* + * SPAR prototypes + *----------------------------------------------------------------------------------*/ + +/* MD module */ + +/*! r: number of MD subframes */ +ivas_error ivas_spar_md_dec_open( + ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const Word16 num_channels, /* i : number of internal channels */ + const Word16 sba_order, /* i : SBA order */ + const Word16 sid_format, /* i : SID format */ + const Word32 last_active_ivas_total_brate /* i : IVAS last active bitrate */ +); + +void ivas_spar_md_dec_close( + ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ +); + +ivas_error ivas_spar_md_dec_init( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const Word16 num_channels, /* i : number of internal channels */ + const Word16 sba_order /* i : SBA order */ +); + +/* Transient detector module */ +ivas_error ivas_transient_det_open_fx( + ivas_trans_det_state_t **hTranDet, /* i/o: Transient detector handle */ + const Word32 sampling_rate /* i : sampling rate */ +); + +void ivas_transient_det_close_fx( + ivas_trans_det_state_t **hTranDet /* i/o: Transient detector handle */ +); + +void ivas_huffman_encode_fx( + ivas_huffman_cfg_t *huff_cfg, + Word16 in, + Word16 *hcode, + Word16 *hlen +); + +ivas_error ivas_huffman_decode( + ivas_huffman_cfg_t *huff_cfg, + Decoder_State *st0, + Word16 *dec_out +); + +void ivas_arith_decode_cmplx_cell_array( + ivas_arith_t *pArith_re, + ivas_arith_t *pArith_re_diff, + Decoder_State *st0, + ivas_cell_dim_t *pCell_dims, + Word16 *pDo_diff, const Word16 nB, + Word16 *pSymbol_re, + Word16 *pSymbol_re_old +); + +void ivas_map_prior_coeffs_quant( + ivas_spar_md_prev_t *pSpar_md_prior, + ivas_spar_md_com_cfg *pSpar_md_cfg, + const Word16 qsi, + const Word16 nB +); + +void ivas_clear_band_coeff_idx( + ivas_band_coeffs_ind_t *pband_coeff_idx, + const UWord16 num_bands +); + + +/*----------------------------------------------------------------------------------* + * MASA prototypes + *----------------------------------------------------------------------------------*/ +ivas_error ivas_masa_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_masa_enc_close_fx( + MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */ +); + +int16_t ivas_qmetadata_encode_extended_gr_length_fx( + const UWord16 value, + const UWord16 alphabet_size, + const Word16 gr_param); + +void ivas_qmetadata_encode_extended_gr_fx( + BSTR_ENC_HANDLE hMetaData, /* i/o: q_metadata handle */ + const UWord16 value, /* i : value to be encoded */ + const UWord16 alphabet_size, /* i : alphabet size */ + const Word16 gr_param); /* i : GR order */ + + +void ivas_set_qmetadata_maxbit_req_fx( + IVAS_QMETADATA_HANDLE hQMetaData, /* o : qmetadata structure where the requirement value is set */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +); + + +/*---------------------------------------------------------------------------------* + * Binaural FastConv Renderer Prototypes +*-----------------------------------------------------------------------------------*/ + + +void ivas_binaural_hrtf_close( + HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i/o: decoder binaural hrtf handle */ +); + +/*----------------------------------------------------------------------------------* + * renderer prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_ism_renderer_close( + ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ +); + + +/*----------------------------------------------------------------------------------* + * Amplitude Panning VBAP prototypes + *----------------------------------------------------------------------------------*/ + +void panning_wrap_angles( + const float azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ + const float ele_deg, /* i : elevation in degrees for panning direction (positive up) */ + float *azi_wrapped, /* o : wrapped azimuth component */ + float *ele_wrapped /* o : wrapped elevation component */ +); + + +/*----------------------------------------------------------------------------------* + * McMASA prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_mcmasa_dec_reconfig( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +); + +void ivas_mcmasa_dmx_modify_fx( + const Word16 n_samples, /* i : input frame length in samples */ + Word32 dmx_fx[][L_FRAME48k + NS2SA(48000, IVAS_FB_ENC_DELAY_NS)], /* i/o: downmix signal to be transformed into another format Qx*/ + Word16 dmx_Q[], /* i/o : Q of the intput signal which is being transformed*/ + const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0 */ + const Word16 n_chnls_dmx_new /* i : number of downmix channels in the target format Q0*/ +); + +ivas_error ivas_mono_dmx_renderer_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +void ivas_mono_dmx_renderer_close( + MONO_DOWNMIX_RENDERER_HANDLE *hMonoDmxRenderer /* i/ i/o: Mono downmix structure */ +); + + +/*----------------------------------------------------------------------------------* + * LFE encoder low pass filter prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_lfe_lpf_enc_close_fx( + ivas_filters_process_state_t **hLfeLpf /* i/o: LFE LPF handle */ +); + + +/*----------------------------------------------------------------------------------* + * LFE Coding prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_create_lfe_enc_fx( + LFE_ENC_HANDLE *hLFE, /* o : IVAS LFE encoder structure */ + const Word32 input_Fs /* i : input sampling rate */ +); + +void ivas_lfe_enc_close_fx( + LFE_ENC_HANDLE *hLFE /* i/o: LFE encoder handle */ +); + +void ivas_filters_init_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + const Word32 *filt_coeff_fx, /* i : filter coefficients Q31- *filt_coeff_e */ + const Word16 *filt_coeff_e, /* i : exponents of filter coefficients */ + const Word16 order ) ; + +void ivas_filter_process_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ + const Word16 length, /* i : filter order */ + Word16 q_factor ); + +/*----------------------------------------------------------------------------------* + * OSBA prototypes + *----------------------------------------------------------------------------------*/ +ivas_error ivas_osba_enc_reconfig( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_set_surplus_brate_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +#ifdef DEBUG_MODE_INFO + , + const int16_t *nb_bits_metadata /* i : number of metadata bits */ +#endif +); + +void ivas_set_surplus_brate_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int32_t *ism_total_brate /* i : ISM total bitrate */ +); + +ivas_error ivas_omasa_separate_object_renderer_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_omasa_separate_object_renderer_close( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +/*----------------------------------------------------------------------------------* + * Filter-bank (FB) Mixer + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_fb_set_cfg( + IVAS_FB_CFG **pFb_cfg_out, /* o : FB config. handle */ + const Word16 ivas_format, /* i : IVAS format */ + const Word16 num_in_chans, /* i : number of FB input channels */ + const Word16 num_out_chans, /* i : number of FB output channels */ + const Word16 active_w_mixing, /* i : active_w_mixing flag */ + const Word32 sampling_Fs, /* i : sampling rate */ + const Word16 nachan_dirac_ana /* i : number of DirAR analysis channels */ +); + + +/*=============================================================================================*/ + #endif diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index 79a585e8b..c9ad84097 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 5caa850cb..6661026a8 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sba_config_fx.c b/lib_com/ivas_sba_config_fx.c index 38785956c..b3a0806d4 100644 --- a/lib_com/ivas_sba_config_fx.c +++ b/lib_com/ivas_sba_config_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index f35de8eb0..fa64b0092 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include @@ -61,12 +60,11 @@ void sns_compute_scf_fx( Word64 sum; Word32 L_tmp; const Word32 *pow_tilt; + Word16 q_shift, q_out, f_tmp; + Word16 bw, inv_bw, exp; const UWord8 nBands = pPsychParams->nBands; move16(); const UWord8 *bandLengths = pPsychParams->bandLengths; - Word8 bw = 0; - move16(); - Word16 q_shift; const Word16 w_0 = 2730; // (1.0f / 12.0f) in Q15 move16(); @@ -88,91 +86,83 @@ void sns_compute_scf_fx( IF( bandLengths == NULL ) { - bw = (Word8) shr( L_frame, 6 ); + bw = shr( L_frame, 6 ); move16(); + + exp = norm_s( bw ); + inv_bw = div_s( ONE_IN_Q14, shl( bw, exp ) ); // Q:15+14-exp = 29-exp + inv_bw = shl( inv_bw, sub( exp, 14 ) ); // Q15 + /* Energy per band */ k = 0; move16(); FOR( i = 0; i < nBands; ++i ) { - x_64[i] = 0; + sum = 0; move64(); FOR( n = 0; n < bw; ( ++n, ++k ) ) { - x_64[i] = W_add( x_64[i], W_deposit32_l( spectrum[k] ) ); // Q_in - move64(); + /* x[i] += spectrum[k]; + inv_bw is for x[i] /= bw; */ + sum = W_mac_32_16( sum, spectrum[k], inv_bw ); // Q_in+15+1 } + x_64[i] = sum; // Q_in+16 + move64(); } } ELSE { /* Energy per band */ k = 0; - move32(); + move16(); FOR( i = 0; i < nBands; ++i ) { - x_64[i] = 0; + exp = norm_s( bandLengths[i] ); + inv_bw = div_s( ONE_IN_Q14, shl( bandLengths[i], exp ) ); // Q:15+14-exp + inv_bw = shl( inv_bw, sub( exp, 14 ) ); // Q15 + + sum = 0; move64(); FOR( n = 0; n < bandLengths[i]; ( ++n, ++k ) ) { - x_64[i] = W_add( x_64[i], W_deposit32_l( spectrum[k] ) ); // Q_in - move64(); + /* x[i] += spectrum[k]; + inv_bw is for x[i] /= bandLengths[i]; */ + sum = W_mac_32_16( sum, spectrum[k], inv_bw ); // Q_in+15+1 } + x_64[i] = sum; // Q_in+16 + move64(); } } /* Move accumulated values to 32-bit */ - q_shift = 0; - move16(); - IF( x_64[0] != 0 ) + q_shift = W_norm_arr( x_64, nBands ); // W_norm_arr return 63 when all the values of the input buffer are zeroes + IF( EQ_16( q_shift, 63 ) ) { - q_shift = W_norm( x_64[0] ); - } - FOR( i = 1; i < nBands; ++i ) - { - IF( x_64[i] != 0 ) - { - q_shift = s_min( q_shift, W_norm( x_64[i] ) ); - } - } - FOR( i = 0; i < nBands; ++i ) - { - x[i] = W_extract_l( W_shl( x_64[i], sub( q_shift, 32 ) ) ); // Q_in + (q_shift - 32) - } + /* If all the values of x_64 are zeros, the scale factor (scf) values will be calculated as zeroes as per the below operations. + To avoid extra computations in such a case, set scf values as zeroes and return. */ - IF( bandLengths == NULL ) - { - Word16 inv_bw; - bw = (Word8) shr( L_frame, 6 ); - move16(); - inv_bw = div_l( ONE_IN_Q16 /*1 Q16*/, bw ); // Q15 - FOR( i = 0; i < nBands; ++i ) - { - x[i] = Mpy_32_16_1( x[i], inv_bw ); // Q_in + (q_shift - 32) - move32(); - } + set_zero_fx( scf, SNS_NPTS ); + + return; } - ELSE + + FOR( i = 0; i < nBands; ++i ) { - FOR( i = 0; i < nBands; ++i ) - { - Word16 inv_bw = div_l( ONE_IN_Q16 /*1 Q16*/, bandLengths[i] ); // Q15 - x[i] = Mpy_32_16_1( x[i], inv_bw ); // Q_in + (q_shift - 32) - move32(); - } + x[i] = W_extract_h( W_shl( x_64[i], q_shift ) ); // Q: Q_in+16+q_shift-32 = Q_in+q_shift-16 + move32(); } /* Smoothing */ - xs[0] = L_add( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[1], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[0] = Madd_32_16( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), x[1], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); FOR( i = 1; i < FDNS_NPTS - 1; i++ ) { - xs[i] = L_add( L_add( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), Mpy_32_16_1( x[i - 1], 8192 /* 0.25 in Q15 */ ) ), Mpy_32_16_1( x[i + 1], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[i] = Madd_32_16( Madd_32_16( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), x[i - 1], 8192 /* 0.25 in Q15 */ ), x[i + 1], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); } - xs[FDNS_NPTS - 1] = L_add( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[FDNS_NPTS - 1] = Madd_32_16( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); /* Pre-emphasis */ @@ -194,86 +184,83 @@ void sns_compute_scf_fx( FOR( i = 0; i < FDNS_NPTS; i++ ) { - xs[i] = Mpy_32_32( xs[i], pow_tilt[i] ); // Q_in + (q_shift - 32) + xs[i] = Mpy_32_32( xs[i], pow_tilt[i] ); // Q_in+q_shift-16+23-31 = Q_in+q_shift-24 move32(); } /* Noise floor at -40dB */ sum = 0; move64(); - FOR( Word16 ind = 0; ind < FDNS_NPTS; ind++ ) + FOR( i = 0; i < FDNS_NPTS; i++ ) { - sum = W_add( sum, W_deposit32_l( xs[ind] ) ); // Q_in + (q_shift - 32) + sum = W_mac_32_16( sum, xs[i], 1 ); // Q_in+q_shift-24+1 } - mean = W_extract_l( W_shr( sum, 6 ) ); // Q_in + (q_shift - 32) - nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // Q_in + (q_shift - 32) - nf = L_max( nf, 0 /* powf( 2.0f, -32.0f ) in Q31 */ ); // Q_in + (q_shift - 32) + q_out = sub( add( Q_in, q_shift ), 24 ); + + /* mean = sum / FDNS_NPTS; + -Q6 is for division with FDNS_NPTS and -Q1 is to reduce Q by one */ + mean = W_shl_sat_l( sum, -Q7 ); // q_out + nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // q_out + nf = L_max( nf, L_shl( 256, sub( q_out, 40 ) ) /* powf( 2.0f, -32.0f ) in Q40 */ ); // q_out FOR( i = 0; i < FDNS_NPTS; i++ ) { - if ( LT_32( xs[i], nf ) ) - { - xs[i] = nf; // Q_in + (q_shift - 32) - move32(); - } + xs[i] = L_max( xs[i], nf ); // q_out + move32(); } /* Log-domain */ FOR( i = 0; i < FDNS_NPTS; i++ ) { - Word16 e_tmp = norm_l( xs[i] ); - Word16 f_tmp = Log2_norm_lc( L_shl( xs[i], e_tmp ) ); /*Q16*/ - e_tmp = sub( sub( 34, e_tmp ), Q_in ); - /* Note: Mpy_32_16 is used temporarily for this computation, It needs to be replaced with appropriate BASOP. */ - xl[i] = Mpy_32_16( e_tmp, f_tmp, 16384 ); /* Q16 */ + /* xl[i] = logf( xs[i] ) * scale_log; + scale_log = INV_LOG_2 * 0.5f; */ + + exp = norm_l( xs[i] ); + f_tmp = Log2_norm_lc( L_shl( xs[i], exp ) ); // Q15 + exp = sub( sub( 30, exp ), q_out ); + L_tmp = L_mac( L_deposit_h( exp ), f_tmp, 1 ); // Q16 + xl[i] = L_shr( L_tmp, 1 ); // Q16 move32(); } /* Downsampling */ - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[0], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[0], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[4], w_5 ); // Q16 - xl4[0] = L_tmp; // Q16 - move32(); + L_tmp = Madd_32_16( Mpy_32_16_1( xl[0], w_0 ), xl[0], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); // Q16 + xl4[0] = Madd_32_16( L_tmp, xl[4], w_5 ); // Q16 + FOR( n = 1; n < SNS_NPTS - 1; n++ ) { - Word16 n4 = shl( n, 2 ); - - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[n4 - 1], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 1], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 3], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 4], w_5 ); // Q16 - xl4[n] = L_tmp; // Q16 + L_tmp = Mpy_32_16_1( xl[4 * n - 1], w_0 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 1], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 3], w_4 ); // Q16 + xl4[n] = Madd_32_16( L_tmp, xl[4 * n + 4], w_5 ); // Q16 move32(); } - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 5], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); // Q16 - xl4[SNS_NPTS - 1] = L_tmp; // Q16 + L_tmp = Mpy_32_16_1( xl[FDNS_NPTS - 5], w_0 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); // Q16 + xl4[SNS_NPTS - 1] = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); // Q16 move32(); /* Remove mean and scaling */ sum = 0; move64(); - FOR( Word16 ind = 0; ind < SNS_NPTS; ind++ ) + FOR( i = 0; i < SNS_NPTS; i++ ) { - sum = W_add( sum, W_deposit32_l( xl4[ind] ) ); // Q16 + sum = W_mac_32_16( sum, xl4[i], 1 ); // Q16+1 } - mean = W_extract_l( W_shr( sum, 4 ) ); // Q16 + /* mean = sum / SNS_NPTS; + -Q4 is for division with SNS_NPTS and -Q1 is to reduce Q by one */ + mean = W_shl_sat_l( sum, -Q5 ); // Q16 FOR( i = 0; i < SNS_NPTS; i++ ) { diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 96df64aa5..929eaa2c5 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -36,7 +36,6 @@ #include "basop_util.h" #include "ivas_stat_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_com/ivas_spar_com_quant_util_fx.c b/lib_com/ivas_spar_com_quant_util_fx.c index 8292de5c1..cfd03a3b3 100644 --- a/lib_com/ivas_spar_com_quant_util_fx.c +++ b/lib_com/ivas_spar_com_quant_util_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_dft_com_fx.c b/lib_com/ivas_stereo_dft_com_fx.c index 80e64c0cc..6d63bc6d1 100644 --- a/lib_com/ivas_stereo_dft_com_fx.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c index d0ffff39c..958781473 100644 --- a/lib_com/ivas_stereo_eclvq_com_fx.c +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index 9aa880842..8548797a4 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_stereo_mdct_bands_com_fx.c b/lib_com/ivas_stereo_mdct_bands_com_fx.c index c21abcf8c..43f2f16c7 100644 --- a/lib_com/ivas_stereo_mdct_bands_com_fx.c +++ b/lib_com/ivas_stereo_mdct_bands_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_mdct_stereo_com_fx.c b/lib_com/ivas_stereo_mdct_stereo_com_fx.c index dd94358af..0a773169d 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com_fx.c +++ b/lib_com/ivas_stereo_mdct_stereo_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include #include "prot_fx.h" diff --git a/lib_com/ivas_stereo_psychlpc_com_fx.c b/lib_com/ivas_stereo_psychlpc_com_fx.c index cb3c39df2..df5140895 100644 --- a/lib_com/ivas_stereo_psychlpc_com_fx.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -33,9 +33,7 @@ #include #include "options.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_stereo_td_bit_alloc_fx.c b/lib_com/ivas_stereo_td_bit_alloc_fx.c index 9074473d7..b54c1d3de 100644 --- a/lib_com/ivas_stereo_td_bit_alloc_fx.c +++ b/lib_com/ivas_stereo_td_bit_alloc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "stat_enc.h" #include "rom_com.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "prot_fx.h" diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index e15db9a15..04d6f7bf5 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index 97025b46f..3b9a8cfd7 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -36,7 +36,6 @@ #include "wmc_auto.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_com.h" diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 6bd8026c4..12234a4c0 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d0f0efb72..db0953cd9 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4701,6 +4701,7 @@ Word16 find_guarded_bits_fx( Word32 n ); Word16 L_norm_arr( const Word32 *arr, Word16 size ); Word16 norm_arr( Word16 *arr, Word16 size ); +Word16 W_norm_arr( Word64 *arr, Word16 size ); Word16 get_min_scalefactor( Word32 x, Word32 y ); diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 1f112c911..7905c7145 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -41,7 +41,6 @@ #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include diff --git a/lib_dec/ACcontextMapping_dec_fx.c b/lib_dec/ACcontextMapping_dec_fx.c index 34e74a06f..22e9fff01 100644 --- a/lib_dec/ACcontextMapping_dec_fx.c +++ b/lib_dec/ACcontextMapping_dec_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" /*-------------------------------------------------------------------* * ACcontextMapping_decode2_no_mem_s17_LC() diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 11379a62d..782654623 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -41,7 +41,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 191065855..d1ed7ad8c 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "options.h" #include "math.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 907a4a350..c1b0ce93a 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -9,7 +9,6 @@ #include "options.h" #include "stl.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "cnst.h" #include "stat_dec.h" @@ -2932,14 +2931,14 @@ static void IGF_getWhiteSpectralData_ivas( { ak = 0; move32(); - move16(); FOR( j = i - level; j < stop; j++ ) { tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) } - ak = Mult_32_16( ak, quo ); + ak = L_deposit_h( BASOP_Util_Divide3216_Scale( ak, sub( stop, sub( i, level ) ), &tmp_e ) ); + ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); n = shr( n, 1 ); diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index e73d89158..a196a1abd 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 3c234c098..8527e6703 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 5bb4736e9..7b4e5f267 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 697f9d715..25c0bea42 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -32,7 +32,6 @@ #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 9bf53f1de..6a6294377 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_decision_matrix_dec_fx.c b/lib_dec/ivas_decision_matrix_dec_fx.c index f7fd5e8e2..717bb3b93 100644 --- a/lib_dec/ivas_decision_matrix_dec_fx.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "stat_dec.h" #include "rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 59d9c9e38..d8288e561 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index e03913f8a..b247fd653 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -41,7 +41,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_entropy_decoder_fx.c b/lib_dec/ivas_entropy_decoder_fx.c index e637a6a93..f8bf3c091 100644 --- a/lib_dec/ivas_entropy_decoder_fx.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 8db782c4e..b11669460 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 664e3eeac..643874a82 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_ism_dtx_dec_fx.c b/lib_dec/ivas_ism_dtx_dec_fx.c index cbf088597..0f023a7ef 100644 --- a/lib_dec/ivas_ism_dtx_dec_fx.c +++ b/lib_dec/ivas_ism_dtx_dec_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_ism_metadata_dec_fx.c b/lib_dec/ivas_ism_metadata_dec_fx.c index a6f5e47b6..3288903ab 100644 --- a/lib_dec/ivas_ism_metadata_dec_fx.c +++ b/lib_dec/ivas_ism_metadata_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index eae0e9069..3aed4d3b1 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -34,7 +34,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "rom_com.h" diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index a19ba70ec..7cd93affa 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_stat_com.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 428c817ef..210425b88 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index e68c0142d..672d3fbe6 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "rom_com.h" diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 018f99fe7..210c266eb 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_ls_custom_dec_fx.c b/lib_dec/ivas_ls_custom_dec_fx.c index 45f59d82f..5ad390f9a 100644 --- a/lib_dec/ivas_ls_custom_dec_fx.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include #include "options.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index 806785c15..384865a1a 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index be2363469..697ae6345 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index 9ea666237..3c2ba7587 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "rom_com.h" diff --git a/lib_dec/ivas_mcmasa_dec_fx.c b/lib_dec/ivas_mcmasa_dec_fx.c index c2228b610..1b1715c21 100644 --- a/lib_dec/ivas_mcmasa_dec_fx.c +++ b/lib_dec/ivas_mcmasa_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_core_dec_fx.c b/lib_dec/ivas_mct_core_dec_fx.c index be457da47..fe39fd8e3 100644 --- a/lib_dec/ivas_mct_core_dec_fx.c +++ b/lib_dec/ivas_mct_core_dec_fx.c @@ -39,7 +39,6 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 081eca88d..884a44c9e 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index 69f601724..c275820fb 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index a5855a0f6..35d38d03a 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -40,7 +40,6 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include diff --git a/lib_dec/ivas_mono_dmx_renderer_fx.c b/lib_dec/ivas_mono_dmx_renderer_fx.c index bb5dead22..2eb8d84df 100644 --- a/lib_dec/ivas_mono_dmx_renderer_fx.c +++ b/lib_dec/ivas_mono_dmx_renderer_fx.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 391a27522..b88b68915 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index bf7fba094..afa604684 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_prot_rend.h" diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 07ea14ea2..6f1a233c9 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 4811911fd..84b6fe46d 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" diff --git a/lib_dec/ivas_output_config_fx.c b/lib_dec/ivas_output_config_fx.c index cb96d3b0d..3a0960960 100644 --- a/lib_dec/ivas_output_config_fx.c +++ b/lib_dec/ivas_output_config_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 08ac17799..98611ab7c 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 397f26bbc..9357394a5 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index 81768af44..c78c51c52 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_qspherical_dec_fx.c b/lib_dec/ivas_qspherical_dec_fx.c index d34b5402a..f6ac39a99 100644 --- a/lib_dec/ivas_qspherical_dec_fx.c +++ b/lib_dec/ivas_qspherical_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_range_uni_dec_fx.c b/lib_dec/ivas_range_uni_dec_fx.c index e629111ce..9a49680e8 100644 --- a/lib_dec/ivas_range_uni_dec_fx.c +++ b/lib_dec/ivas_range_uni_dec_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_dec.h" #include "cnst.h" diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index efd766f76..f04350366 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 573a9c17f..0c7544682 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index a42c67389..8748342ed 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index 89581565c..a6be10c08 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 170256181..fd25e7ea7 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index 812027468..34a194898 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -37,7 +37,6 @@ #include "ivas_stat_dec.h" #include "prot_fx.h" #include "string.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index bb79b956c..7f487a75c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c index 8446af47d..2bade4786 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "rom_dec.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 4d50ba350..223860db0 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 166ac72e5..f0fd1978b 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "rom_dec.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index 0781d49a6..e82005965 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index fb54476fa..1c18ffacb 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "rom_dec.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index d3415a8eb..90d9c5823 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_eclvq_dec_fx.c b/lib_dec/ivas_stereo_eclvq_dec_fx.c index 693df8c77..dfa411145 100644 --- a/lib_dec/ivas_stereo_eclvq_dec_fx.c +++ b/lib_dec/ivas_stereo_eclvq_dec_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_stereo_esf_dec_fx.c b/lib_dec/ivas_stereo_esf_dec_fx.c index 80603f6c0..d4219f1e6 100644 --- a/lib_dec/ivas_stereo_esf_dec_fx.c +++ b/lib_dec/ivas_stereo_esf_dec_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index b49ab5399..694aad0b4 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 22a8c4a90..3b32072f3 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 04781a9cb..a6b350d33 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -37,7 +37,6 @@ #include "prot_fx.h" #include "cnst.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 69083a078..3f39bd9ac 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index e5e18083d..09b683a16 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_dec/ivas_stereo_td_dec_fx.c b/lib_dec/ivas_stereo_td_dec_fx.c index 8ab7da035..023c9a2e5 100644 --- a/lib_dec/ivas_stereo_td_dec_fx.c +++ b/lib_dec/ivas_stereo_td_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -338,45 +337,6 @@ void tdm_configure_dec_fx( return; } -/*-------------------------------------------------------------------* - * Function tdm_downmix_plain() - * - * downmix Left+Right to Primary+Secondary channel - *-------------------------------------------------------------------*/ - -void tdm_upmix_plain( - float Left[], /* o : left channel */ - float Right[], /* o : right channel */ - const float PCh_2_L[], /* i : primary channel */ - const float SCh_2_R[], /* i : secondary channel */ - const float LR_ratio, /* i : mixing ratio */ - const float inv_den_LR_ratio, /* i : inverse mixing ration */ - const int16_t start_index, /* i : start index */ - const int16_t end_index, /* i : end index */ - const int16_t plus_minus_flag /* i : plus/minus flag */ -) -{ - int16_t i; - - if ( plus_minus_flag == 1 ) - { - for ( i = start_index; i < end_index; i++ ) - { - Left[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * inv_den_LR_ratio; - Right[i] = ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * inv_den_LR_ratio; - } - } - else - { - for ( i = start_index; i < end_index; i++ ) - { - Left[i] = ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * inv_den_LR_ratio; - Right[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * inv_den_LR_ratio; - } - } - - return; -} void tdm_upmix_plain_fx( Word32 Left_fx[], /* o : left channel Qx*/ Word32 Right_fx[], /* o : right channel Qx*/ diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 375dbdad0..1467687d8 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index c908e4dc3..07eba9e64 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -40,7 +40,6 @@ #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index 63819b056..98c1a6a79 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" void tdm_low_rate_dec_fx( diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 66109b555..ef3baee3c 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index d263e6dd3..21e8705f3 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * Local functions diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 44439540f..c52fddf97 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -13,7 +13,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" /* Range coder header file */ #define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) /* evaulated at compile time */ #define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /* evaluated at run time */ diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 0f58bcdad..782006108 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -13,7 +13,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index a901690e3..0e4c02744 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index c54e8ccf4..7c28c3309 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,7 +16,6 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #endif diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 9e6318591..f546c3ef8 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1165,18 +1165,30 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { + Word16 q_mdstWin, scale; L_subframe = idiv1616( L_frameTCX, nSubframes ); /* Q0 */ test(); IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { wtda_ext_fx( hTcxEnc->new_speech_TCX, mdstWin, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX, 3 ); - Scale_sig( mdstWin, L_frameTCX, 1 ); + scale = sub( norm_arr( mdstWin, L_frameTCX ), 1 ); + scale = s_min( 1, scale ); // restricting the Q to zero or less + scale_sig( mdstWin, L_frameTCX, scale ); + q_mdstWin = add( -1, scale ); + move16(); } ELSE { + Word16 sig_len; /* Windowing for the MDST */ WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 ); + sig_len = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ); + scale = sub( norm_arr( mdstWin, sig_len ), 1 ); + scale = s_min( 0, scale ); // restricting the Q to zero or less + scale_sig( mdstWin, sig_len, scale ); + q_mdstWin = scale; + move16(); } IF( EQ_16( transform_type[frameno], TCX_5 ) ) @@ -1184,7 +1196,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outer left folding */ FOR( i = 0; i < left_overlap / 2; i++ ) { - mdstWin[left_overlap / 2 + i] = add_sat( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); // Q0 + mdstWin[left_overlap / 2 + i] = add( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); // q_mdstWin } test(); @@ -1197,16 +1209,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } } @@ -1214,7 +1226,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outer right folding */ FOR( i = 0; i < right_overlap / 2; i++ ) { - mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub_sat( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); // Q0 + mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); // q_mdstWin move16(); } @@ -1229,7 +1241,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 ); - spectrum_e[frameno] = 16; + spectrum_e[frameno] = sub( 16, q_mdstWin ); move16(); TCX_MDST( tcx5Win, spectrum[frameno] + i * tcx5SizeFB, &spectrum_e[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); /* high-band gain control in case of BWS */ @@ -1250,14 +1262,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( } ELSE /* transform_type[frameno] != TCX_5 */ { - spectrum_e[frameno] = 16; + spectrum_e[frameno] = sub( 16, q_mdstWin ); test(); IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { Word16 Q; Copy_Scale_sig_16_32_no_sat( mdstWin, L_tmpbuf, N_MAX + L_MDCT_OVLP_MAX, 16 ); - Q = 16; + Q = add( q_mdstWin, 16 ); move16(); edst_fx( L_tmpbuf, spectrum[frameno], L_subframe, &Q ); spectrum_e[frameno] = 31 - Q; @@ -1284,16 +1296,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } } diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index f6adb0f31..fc7c32fdb 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 104eeb998..d74e10bda 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 5f318e959..f88288ea1 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -36,7 +36,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 46de4e232..42920a46a 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 73403a848..8d00e608c 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index 32e3e7107..f21c8e262 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -35,7 +35,6 @@ #include "ivas_cnst.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "math.h" diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index a9d62a2b0..1152736f6 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #ifdef DEBUGGING diff --git a/lib_enc/ivas_decision_matrix_enc_fx.c b/lib_enc/ivas_decision_matrix_enc_fx.c index 1158f72fa..bd63553bd 100644 --- a/lib_enc/ivas_decision_matrix_enc_fx.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index 7bfa9f268..ac0ce9556 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index 576bbb2c6..c05d59b90 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index 0a2d976e1..e8e1bc59e 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_entropy_coder_fx.c b/lib_enc/ivas_entropy_coder_fx.c index a95f2884c..3c8cf92e2 100644 --- a/lib_enc/ivas_entropy_coder_fx.c +++ b/lib_enc/ivas_entropy_coder_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index f1aeb5398..8b76b37a4 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" @@ -433,30 +432,6 @@ ivas_error front_vad_create_fx( return IVAS_ERR_OK; } -/*-----------------------------------------------------------------------------------------* - * Function front_vad_destroy() - * - * Deallocate Standalone front-VAD module - *-----------------------------------------------------------------------------------------*/ - -void front_vad_destroy( - FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ -) -{ - IF( *hFrontVad != NULL ) - { - free( ( *hFrontVad )->hNoiseEst ); - ( *hFrontVad )->hNoiseEst = NULL; - - free( ( *hFrontVad )->hVAD ); - ( *hFrontVad )->hVAD = NULL; - - free( *hFrontVad ); - *hFrontVad = NULL; - } - - return; -} void front_vad_destroy_fx( FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ ) diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index c65c85356..b49fc9716 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_enc.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 64b8991d6..b29b0c15b 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 22bf88df8..1b648cc98 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index 4305e5bca..6a2e54db6 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "prot_fx.h" diff --git a/lib_enc/ivas_ism_param_enc_fx.c b/lib_enc/ivas_ism_param_enc_fx.c index e6b23fcfc..cda8cffd6 100644 --- a/lib_enc/ivas_ism_param_enc_fx.c +++ b/lib_enc/ivas_ism_param_enc_fx.c @@ -34,7 +34,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "cnst.h" diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 11056b535..96959c9dd 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 21c23c34a..6960629c8 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 2797fa5e4..17fefec7e 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index abd09cbbd..fd5cb6217 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index c4d3908ca..22f21dceb 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "options.h" #include "prot_fx.h" diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 439c227ae..71515571d 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index d6bc4c7f0..56f5e44db 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 88d773b53..a8ba9a320 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 70b2b0034..3272768e9 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -37,7 +37,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -705,8 +704,8 @@ static void applyStereoPreProcessingCplx( } ELSE { - dmxR2_fx = L_sub( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 - dmxI2_fx = L_sub( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 + dmxR2_fx = L_sub( Mpy_32_32( valR2_fx, factDe_fx ), Mpy_32_32( valR1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI2_fx = L_sub( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } } ELSE @@ -1923,7 +1922,6 @@ void ivas_mdct_core_whitening_enc_fx( tcx_subframe_coded_lines = shr( tcx_subframe_coded_lines, shift ); /*tcx_subframe_coded_lines / nSubframes*/ Word16 q_pow = 62, q_pow_tmp = sub( 63, shl( mdst_spectrum_e[0][0], 1 ) ); // add( shl( sub( Q31, mdst_spectrum_e[0][0] ), 1 ), 1 ); move16(); - FOR( n = 0; n < nSubframes; n++ ) { IF( st->hTcxEnc->fUseTns[n] ) @@ -1932,34 +1930,19 @@ void ivas_mdct_core_whitening_enc_fx( { powerSpec_fx64[i] = W_mult_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ); move64(); - IF( powerSpec_fx64[i] == 0 ) - { - q_pow = s_min( q_pow, 62 ); - } - ELSE - - { - q_pow = s_min( q_pow, W_norm( powerSpec_fx64[i] ) ); - } } + q_pow = W_norm_arr( powerSpec_fx64, L_subframeTCX ); } ELSE { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpec_fx64[i] = W_add( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), W_mult_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ) ); + powerSpec_fx64[i] = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ); move64(); - IF( powerSpec_fx64[i] == 0 ) - { - q_pow = s_min( q_pow, 62 ); - } - ELSE - - { - q_pow = s_min( q_pow, W_norm( powerSpec_fx64[i] ) ); - } } + q_pow = W_norm_arr( powerSpec_fx64, L_subframeTCX ); } + FOR( i = 0; i < L_subframeTCX; i++ ) { powerSpec_fx64[i] = W_shl( powerSpec_fx64[i], q_pow ); diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 7c8b78ffb..5d79265f4 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 1229624de..2a6944c50 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" diff --git a/lib_enc/ivas_pca_enc_fx.c b/lib_enc/ivas_pca_enc_fx.c index 410d5dd52..2cb347a02 100644 --- a/lib_enc/ivas_pca_enc_fx.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include #include diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index b32c80404..2d6080995 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" diff --git a/lib_enc/ivas_qspherical_enc_fx.c b/lib_enc/ivas_qspherical_enc_fx.c index a6f40c8f0..2e7a289f9 100644 --- a/lib_enc/ivas_qspherical_enc_fx.c +++ b/lib_enc/ivas_qspherical_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_range_uni_enc_fx.c b/lib_enc/ivas_range_uni_enc_fx.c index cf32c644d..6c322a3d9 100644 --- a/lib_enc/ivas_range_uni_enc_fx.c +++ b/lib_enc/ivas_range_uni_enc_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_stat_enc.h" diff --git a/lib_enc/ivas_sba_enc_fx.c b/lib_enc/ivas_sba_enc_fx.c index 8fdca5815..e630a70d9 100644 --- a/lib_enc/ivas_sba_enc_fx.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -39,7 +39,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 8c2c945d6..2983ea2f0 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e321f1c7c..93ee56461 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_spar_encoder_fx.c b/lib_enc/ivas_spar_encoder_fx.c index 674a80549..3b380f2eb 100644 --- a/lib_enc/ivas_spar_encoder_fx.c +++ b/lib_enc/ivas_spar_encoder_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 2ace35473..997581476 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c index 70c2165f8..8e79b2288 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index bfe683d6b..3e148a5ae 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -39,7 +39,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index 255b6e938..aa7c2d0aa 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index ede3d3ad9..3eb6c0e82 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -38,7 +38,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 862102d3b..8a887de89 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -38,7 +38,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index 58e66a01a..df4fe3edd 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "prot_fx.h" #include "rom_com.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index c3cb68719..ae8a8203e 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_eclvq_enc_fx.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c index f4962c802..3abc07811 100644 --- a/lib_enc/ivas_stereo_eclvq_enc_fx.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 78c324cce..057798706 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 78891c5f7..bc84ba419 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 28b0e41b9..b68578542 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c index 57bb18e80..851df60d5 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -38,7 +38,6 @@ #include "cnst.h" #include "stat_enc.h" #include "ivas_stat_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index b1213a750..a61b2b010 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index cbdbc0501..2fe8b6c84 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index efae1e80d..44c08efa8 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 979978c03..d2ff2c0c2 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 28044b45d..1e66c1488 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -39,7 +39,6 @@ #include "rom_com.h" #include "basop_proto_func.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "rom_com_fx.h" diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 34215025f..2daa9ed50 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -39,7 +39,6 @@ #include "ivas_cnst.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 9d4736368..9093ffc40 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -39,7 +39,6 @@ #include "debug.h" #endif #include "lib_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/lp_exc_e_fx.c b/lib_enc/lp_exc_e_fx.c index 0887698f7..01005f641 100644 --- a/lib_enc/lp_exc_e_fx.c +++ b/lib_enc/lp_exc_e_fx.c @@ -53,7 +53,8 @@ Word16 lp_filt_exc_enc_fx( Word16 wtmp, wtmp1; Word32 Ltmp; - Word16 use_prev_sf_pit_gain = 0; + Word16 use_prev_sf_pit_gain = 0; // Q0 + move16(); gain1 = 0; move16(); @@ -66,7 +67,8 @@ Word16 lp_filt_exc_enc_fx( test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) ) { - use_prev_sf_pit_gain = 1; + use_prev_sf_pit_gain = 1; // Q0 + move16(); } exp_ener = 0; move16(); @@ -75,7 +77,7 @@ Word16 lp_filt_exc_enc_fx( test(); IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) ) { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener move16(); } @@ -89,7 +91,7 @@ Word16 lp_filt_exc_enc_fx( wtmp1 = 0; move16(); test(); - IF( ( EQ_16( *lp_flag, LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) + IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) { test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) ) @@ -100,6 +102,7 @@ Word16 lp_filt_exc_enc_fx( Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } ELSE @@ -110,20 +113,21 @@ Word16 lp_filt_exc_enc_fx( Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } if ( LT_16( exp_ener, exp_ener1 ) ) { - wtmp = shr( wtmp, 1 ); + wtmp = shr( wtmp, 1 ); // exp_ener + 1 } if ( GT_16( exp_ener, exp_ener1 ) ) { - wtmp1 = shr( wtmp1, 1 ); + wtmp1 = shr( wtmp1, 1 ); // exp_ener1 + 1 } /*-----------------------------------------------------------------* @@ -132,18 +136,18 @@ Word16 lp_filt_exc_enc_fx( test(); test(); - IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( EQ_16( *lp_flag, LOW_PASS ) ) ) + IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) ) { /* use the LP filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( exc_tmp, &exc[i_subfr], L_subfr ); - Copy( y1_tmp, y1, L_subfr ); - Copy( xn2_tmp, xn2, L_subfr ); + Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new + Copy( y1_tmp, y1, L_subfr ); // Q_new-1+shift + Copy( xn2_tmp, xn2, L_subfr ); // Q_new-1+shift IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain2; + *gain_pit = gain2; // Q14 move16(); g_corr[0] = g_corr2[0]; move16(); @@ -162,7 +166,7 @@ Word16 lp_filt_exc_enc_fx( move16(); IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain1; + *gain_pit = gain1; // Q14 move16(); } } @@ -193,7 +197,8 @@ Word16 lp_filt_exc_enc_ivas_fx( Word16 wtmp, wtmp1; Word32 Ltmp; - Word16 use_prev_sf_pit_gain = 0; + Word16 use_prev_sf_pit_gain = 0; // Q0 + move16(); gain1 = 0; move16(); @@ -206,7 +211,8 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) ) { - use_prev_sf_pit_gain = 1; + use_prev_sf_pit_gain = 1; // Q0 + move16(); } exp_ener = 0; move16(); @@ -215,13 +221,13 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) ) { - IF( use_prev_sf_pit_gain == 1 ) + IF( EQ_16( use_prev_sf_pit_gain, 1 ) ) { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener } - else + ELSE { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener } } @@ -235,7 +241,7 @@ Word16 lp_filt_exc_enc_ivas_fx( wtmp1 = 0; move16(); test(); - IF( ( EQ_16( *lp_flag, LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) + IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) { test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) ) @@ -246,6 +252,7 @@ Word16 lp_filt_exc_enc_ivas_fx( Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } ELSE @@ -256,15 +263,16 @@ Word16 lp_filt_exc_enc_ivas_fx( Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } - IF( use_prev_sf_pit_gain == 1 ) + IF( EQ_16( use_prev_sf_pit_gain, 1 ) ) { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } ELSE { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } } @@ -284,18 +292,18 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); test(); - IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( EQ_16( *lp_flag, LOW_PASS ) ) ) + IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) ) { /* use the LP filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( exc_tmp, &exc[i_subfr], L_subfr ); - Copy( y1_tmp, y1, L_subfr ); - Copy( xn2_tmp, xn2, L_subfr ); + Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new + Copy( y1_tmp, y1, L_subfr ); // Q_new-1+shift + Copy( xn2_tmp, xn2, L_subfr ); // Q_new-1+shift IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain2; + *gain_pit = gain2; // Q14 move16(); g_corr[0] = g_corr2[0]; move16(); @@ -314,7 +322,7 @@ Word16 lp_filt_exc_enc_ivas_fx( move16(); IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain1; + *gain_pit = gain1; // Q14 move16(); } } @@ -367,9 +375,9 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation { FOR( i = 0; i < L_subfr; i++ ) { - exc_tmp[i] = mult( exc[i], 8192 ); + exc_tmp[i] = mult( exc[i], 8192 /*0.25.Q15*/ ); // Q_new move16(); - xn_tmp[i] = mult( xn[i], 8192 ); + xn_tmp[i] = mult( xn[i], 8192 /*0.25.Q15*/ ); // Q_new move16(); } Overflow = 0; @@ -383,14 +391,14 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation test(); if ( EQ_16( clip_gain, 1 ) && GT_16( *gain, 15565 ) ) /* constant in Q14 */ { - *gain = 15565; + *gain = 15565; // 0.95.Q14 move16(); } test(); - if ( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) + IF( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) // 0.65.Q14 { - *gain = 10650; + *gain = 10650; // 0.65.Q14 move16(); } } @@ -403,14 +411,14 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation /* could possibly happen in GSC */ Ltmp = Calc_Energy_Autoscaled( xn2, 0, L_subfr, exp_ener ); i = norm_l( Ltmp ); - ener = extract_h( L_shl( Ltmp, i ) ); + ener = extract_h( L_shl( Ltmp, i ) ); // exp_ener i = sub( 31, i ); *exp_ener = sub( i, *exp_ener ); move16(); } ELSE { - ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); + ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); // Q15 } return ener; @@ -424,9 +432,9 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation *-------------------------------------------------------------------*/ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) */ - const Word16 xn_1[], /* i : target signal */ - const Word16 y1_1[], /* i : filtered adaptive codebook excitation */ - Word16 g_corr[], /* o : correlations and -2 */ + const Word16 xn_1[], /* i : target signal Q_new*/ + const Word16 y1_1[], /* i : filtered adaptive codebook excitation 12 bits*/ + Word16 g_corr[], /* o : correlations and -2 mant/exp*/ const Word16 L_subfr, /* i : vector length */ const Word16 norm_flag /* i : flag for constraining pitch contribution */ , @@ -446,7 +454,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) *----------------------------------------------------------------*/ /* Compute scalar product */ - Copy( xn_1, xn, L_subfr ); + Copy( xn_1, xn, L_subfr ); // Q_new Copy( y1_1, y1, L_subfr ); Overflow = 0; move16(); @@ -457,9 +465,9 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) { FOR( i = 0; i < L_subfr; i++ ) { - xn[i] = mult_r( xn_1[i], 4096 ); + xn[i] = mult_r( xn_1[i], 4096 /*0.125.Q15*/ ); // Q-new move16(); - y1[i] = mult_r( y1_1[i], 4096 ); + y1[i] = mult_r( y1_1[i], 4096 /*0.125.Q15*/ ); move16(); } @@ -484,7 +492,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) } ELSE { - yy = extract_h( Ltmp1 ); + yy = extract_h( Ltmp1 ); // exp_yy /* Ltmp1 = L_shr(Ltmp1, sub(30, exp_yy));*/ /* Compute scalar product */ @@ -499,7 +507,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) g_corr[1] = exp_yy; move16(); /* -2.0*temp1 + 0.01 is done in Gain_enc_2 function*/ - g_corr[2] = xy; + g_corr[2] = xy; // exp_xy move16(); g_corr[3] = exp_xy; move16(); @@ -510,8 +518,8 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) IF( xy >= 0 && NE_16( s_or( yy, xy ), 16384 ) ) { /* compute gain = xy/yy */ - xy = shr( xy, 1 ); /* be sure that xy < yy */ - gain = div_s( xy, yy ); + xy = shr( xy, 1 ); /* be sure that xy < yy */ + gain = div_s( xy, yy ); // Q15 i = sub( exp_xy, exp_yy ); gain = shl_o( gain, i, &Overflow ); /* saturation can occur here */ *Overflow_out |= Overflow; @@ -536,7 +544,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) /* gain_p_snr = sqrt(/) */ tmp = BASOP_Util_Divide1616_Scale( xx, yy, &exp_div ); exp_xx = add( sub( exp_xx, exp_yy ), exp_div ); - tmp = Sqrt16( tmp, &exp_xx ); + tmp = Sqrt16( tmp, &exp_xx ); // exp_xx /* Note: shl works as shl or shr. */ exp_xx = sub( exp_xx, 1 ); @@ -544,8 +552,8 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) gain_p_snr = round_fx_sat( L_shl_sat( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_xx ) ); BASOP_SATURATE_WARNING_ON_EVS - gain = s_min( gain, gain_p_snr ); + gain = s_min( gain, gain_p_snr ); // Q14 } - return gain; + return gain; // Q14 } diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 24179f375..6761dfb82 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -74,8 +74,10 @@ void lsf_enc_fx( const Word16 Q_new ) { Word16 nBits = 0; + move16(); Word16 int_fs; Word16 force_sf = 0; + move16(); Word16 fec_lsf[M], stab, i; Word32 L_tmp; Word16 coder_type, ppp_mode, nelp_mode; @@ -189,7 +191,7 @@ void lsf_enc_fx( lsf2lsp_fx( lsf_new, lsp_new, M, int_fs ); test(); - IF( EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) ) + IF( EQ_16( st_fx->last_core, HQ_CORE ) && ( st_fx->core == ACELP_CORE ) ) { /* don't use old LSF values if this is the first ACELP frame after HQ frames */ Copy( lsf_new, st_fx->lsf_old_fx, M ); @@ -216,7 +218,7 @@ void lsf_enc_fx( FEC_lsf_estim_enc_fx( st_fx, fec_lsf ); /* in case of FEC in decoder - calculate LSF stability */ - stab = lsf_stab_fx( lsf_new, fec_lsf, 0, st_fx->L_frame ); + stab = lsf_stab_fx( lsf_new, fec_lsf, 0, st_fx->L_frame ); // Q15 test(); test(); @@ -255,8 +257,8 @@ void lsf_enc_fx( if ( st_fx->rate_switching_reset ) { /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st_fx->lsp_old_fx, M ); - Copy( lsf_new, st_fx->lsf_old_fx, M ); + Copy( lsp_new, st_fx->lsp_old_fx, M ); // Q15 + Copy( lsf_new, st_fx->lsf_old_fx, M ); // Q15 } /* Mid-frame LSF encoding */ lsf_mid_enc_fx( st_fx->hBstr, st_fx->acelp_cfg.mid_lsf_bits, int_fs, st_fx->lsp_old_fx, lsp_new, lsp_mid, coder_type, st_fx->bwidth, st_fx->Bin_E_old_fx, st_fx->Bin_E_fx, Q_new + QSCALE - 2, ppp_mode, nelp_mode ); @@ -265,7 +267,7 @@ void lsf_enc_fx( IF( EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) ) { /* don't use old LSP/LSF values if this is the first ACELP frame after HQ frames */ - Copy( lsp_mid, st_fx->lsp_old_fx, M ); + Copy( lsp_mid, st_fx->lsp_old_fx, M ); // Q15 lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, int_fs ); } @@ -299,10 +301,10 @@ void lsf_enc_fx( void lsf_enc_ivas_fx( Encoder_State *st, /* i/o: state structure */ - Word16 *lsf_new, /* o : quantized LSF vector */ - Word16 *lsp_new, /* i/o: LSP vector to quantize/quantized */ - Word16 *lsp_mid, /* i/o : mid-frame LSP vector */ - Word16 *Aq, /* o : quantized A(z) for 4 subframes */ + Word16 *lsf_new, /* o : quantized LSF vector Q(x2.56)*/ + Word16 *lsp_new, /* i/o: LSP vector to quantize/quantized Q15*/ + Word16 *lsp_mid, /* i/o : mid-frame LSP vector Q15*/ + Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ @@ -462,15 +464,15 @@ void lsf_enc_ivas_fx( IF( NE_16( st->last_L_frame, st->L_frame ) ) { /* FEC - in case of core switching, use old LSFs */ - Copy( st->lsf_old_fx, st->lsfoldbfi1_fx, M ); - Copy( st->lsf_old_fx, st->lsfoldbfi0_fx, M ); - Copy( st->lsf_old_fx, st->lsf_adaptive_mean_fx, M ); + Copy( st->lsf_old_fx, st->lsfoldbfi1_fx, M ); // Q15 + Copy( st->lsf_old_fx, st->lsfoldbfi0_fx, M ); // Q15 + Copy( st->lsf_old_fx, st->lsf_adaptive_mean_fx, M ); // Q15 } FEC_lsf_estim_enc_fx( st, fec_lsf ); /* in case of FEC in decoder - calculate LSF stability */ - stab = lsf_stab_ivas_fx( lsf_new, fec_lsf, 0, st->L_frame ); + stab = lsf_stab_ivas_fx( lsf_new, fec_lsf, 0, st->L_frame ); // Q15 test(); test(); @@ -509,8 +511,8 @@ void lsf_enc_ivas_fx( IF( st->rate_switching_reset ) { /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st->lsp_old_fx, M ); - Copy( lsf_new, st->lsf_old_fx, M ); + Copy( lsp_new, st->lsp_old_fx, M ); // Q15 + Copy( lsf_new, st->lsf_old_fx, M ); // Q15 } /* Mid-frame LSF encoding */ lsf_mid_enc_ivas_fx( st->hBstr, st->acelp_cfg.mid_lsf_bits, st->sr_core, st->lsp_old_fx, lsp_new, lsp_mid, coder_type, st->bwidth, st->Bin_E_old_fx, Q_new + QSCALE - 2, ppp_mode, nelp_mode ); @@ -529,9 +531,9 @@ void lsf_enc_ivas_fx( { IF( EQ_16( st->active_cnt, 1 ) ) { - Copy( lsp_mid, st->lsp_old_fx, M ); + Copy( lsp_mid, st->lsp_old_fx, M ); // Q15 lsp2lsf_fx( lsp_mid, st->lsf_old_fx, M, st->sr_core ); - Copy( lsp_new, lsp_mid, M ); + Copy( lsp_new, lsp_mid, M ); // Q15 } /* LSP interpolation and conversion of LSPs to A(z) - two-subframe mode */ @@ -546,7 +548,7 @@ void lsf_enc_ivas_fx( *------------------------------------------------------------------*/ IF( NE_32( st->core_brate, SID_2k40 ) ) { - st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st->lsf_old_fx, 0, st->L_frame ); + st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st->lsf_old_fx, 0, st->L_frame ); // Q15 } return; } @@ -847,8 +849,8 @@ static Word16 qlsf_Mode_Select_fx( /*========================================================================*/ void lsf_end_enc_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) */ - Word16 *qlsf, /* o : quantized LSF */ + const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) x2.56*/ + Word16 *qlsf, /* o : quantized LSF x2.56*/ const Word16 nBits_in, /* i : number of bits to spend on ISF quantization */ const Word16 coder_type_org, /* i : coding type */ Word16 Q_ener, /* i : Q valuen for Bin_Ener */ @@ -1008,7 +1010,7 @@ void lsf_end_enc_fx( IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) { /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ - st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); + st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); // Q15 move16(); } @@ -1211,7 +1213,7 @@ void lsf_end_enc_fx( { lpc_param[i] = TCQIdx0[i]; move16(); - bits_param_lpc[i] = BC_TCVQ_BIT_ALLOC_40B[i]; + bits_param_lpc[i] = BC_TCVQ_BIT_ALLOC_40B[i]; // Q0 move16(); } } @@ -1352,8 +1354,8 @@ void lsf_end_enc_fx( void lsf_end_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) */ - Word16 *qlsf, /* o : quantized LSF */ + const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) x2.56*/ + Word16 *qlsf, /* o : quantized LSF x2.56*/ const Word16 nBits_in, /* i : number of bits to spend on ISF quantization */ const Word16 coder_type_org, /* i : coding type */ Word16 Q_ener, /* i : Q valuen for Bin_Ener */ @@ -1944,10 +1946,10 @@ void lsf_end_enc_ivas_fx( static void first_VQstages( const Word16 *const *cb, - Word16 u[], /* i : vector to be encoded (prediction and mean removed) */ + Word16 u[], /* i : vector to be encoded (prediction and mean removed) x2.56*/ Word16 *levels, /* i : number of levels in each stage */ Word16 stagesVQ, /* i : number of stages */ - Word16 w[], /* i : weights */ + Word16 w[], /* i : weights Q8*/ Word16 N, /* i : vector dimension */ Word16 max_inner, /* i : maximum number of swaps in inner loop */ Word16 indices_VQstage[] ) @@ -2338,10 +2340,10 @@ static void first_VQstages_ivas_fx( static Word32 vq_lvq_lsf_enc( Word16 pred_flag, Word16 mode, - Word16 u[], + Word16 u[], // x2.56 Word16 *levels, Word16 stages, - Word16 w[], + Word16 w[], // Q8 Word16 Idx[], const Word16 *lsf, const Word16 *pred, @@ -2370,13 +2372,13 @@ static Word32 vq_lvq_lsf_enc( { cb = &Quantizers_fx[CB_lsf[mode]]; move16(); - mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][sub( levels[stagesVQ], min_lat_bits_SN_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][( levels[stagesVQ] - min_lat_bits_SN_fx[mode] )] ); // Q0 } ELSE /* predictive */ { cb = &Quantizers_p_fx[CB_p_lsf[mode]]; move16(); - mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][sub( levels[stagesVQ], min_lat_bits_pred_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][( levels[stagesVQ] - min_lat_bits_pred_fx[mode] )] ); // Q0 } IF( stagesVQ > 0 ) { @@ -2421,7 +2423,7 @@ static Word32 vq_lvq_lsf_enc( { L_tmp = L_mac( L_tmp, mult( diff[j], shl_o( w[j], 1, &Overflow ) ), diff[j] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ } - e[i] = L_tmp; + e[i] = L_tmp; /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ move32(); } @@ -2447,10 +2449,10 @@ static Word32 vq_lvq_lsf_enc( static Word32 vq_lvq_lsf_enc_ivas_fx( Word16 pred_flag, Word16 mode, - Word16 u[], + Word16 u[], // x2.56 Word16 *levels, Word16 stages, - Word16 w[], + Word16 w[], // Q8 Word16 Idx[], const Word16 *lsf, const Word16 *pred, @@ -2478,7 +2480,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( LT_16( mode, 6 ) ) { move16(); - mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( levels[stagesVQ], min_lat_bits_SN[mode] )] ); + mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][( levels[stagesVQ] - min_lat_bits_SN[mode] )] ); } ELSE { @@ -2492,7 +2494,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( LT_16( mode, 6 ) || EQ_16( mode, 12 ) ) { move16(); - mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( levels[stagesVQ], min_lat_bits_pred_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][( levels[stagesVQ] - min_lat_bits_pred_fx[mode] )] ); } ELSE { @@ -2572,7 +2574,7 @@ static void BcTcvq_1st_fx( Word16 c[][16], Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2)*/ Word16 Q_fx[][16][2], - Word16 W_fx[][2] /*Q10*/ + Word16 W_fx[][2] /*Q8*/ ) { Word16 state, prev_state; @@ -2633,7 +2635,7 @@ static void BcTcvq_2nd_fx( Word16 c[][16], Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2) */ Word16 Q_fx[][16][2], /*x2.56*/ - Word16 W_fx[][2], /*Q10*/ + Word16 W_fx[][2], /*Q8*/ const Word16 itc_fx[][2][2] /*Q15*/ ) { @@ -2921,12 +2923,12 @@ static Word32 BcTcvq_FixSearch_fx( Q_fx[stage][*prev_state][1] = add( CB_fx[stage4][bestCode][1], pred_fx[1] ); move16(); - minDist_fx = L_shr( minDist_fx, 2 ); + minDist_fx = L_shr( minDist_fx, 2 ); /*2.56*2.56*Q(-5 - 2)*/ return minDist_fx; } static Word16 optimalPath_fx( - Word32 cDist_fx[][16], - Word32 blockDist_fx[], + Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2)*/ + Word32 blockDist_fx[], /*2.56*2.56*Q(-5 - 2)*/ Word16 blockCodeword[][4], Word16 bestCodeword[], Word16 codeWord[][16], @@ -2985,10 +2987,11 @@ static Word16 optimalPath_fx( static void quantEnc_fx( Word16 *y_fx, Word16 c[], - const Word16 CB_SUB1_fx[][128][2], - const Word16 CB_SUB2_fx[][64][2], - const Word16 CB_SUB3_fx[][32][2], - const Word16 itc_fx[][2][2] ) + const Word16 CB_SUB1_fx[][128][2], /*x2.56*/ + const Word16 CB_SUB2_fx[][64][2], /*x2.56*/ + const Word16 CB_SUB3_fx[][32][2], /*x2.56*/ + const Word16 itc_fx[][2][2] // Q15 +) { Word16 i, j; Word16 stage; @@ -3103,9 +3106,9 @@ static void buildCode_fx( } static void BcTcvq_fx( Word16 snFlag, - const Word16 *x_fx, - Word16 *y_fx, - const Word16 *weight_fx, + const Word16 *x_fx, // x2.65 + Word16 *y_fx, // x2.65 + const Word16 *weight_fx, // Q8 Word16 *ind ) { Word16 X_fx[N_STAGE_VQ][N_DIM], W_fx[N_STAGE_VQ][N_DIM]; @@ -3162,9 +3165,9 @@ static void BcTcvq_fx( { FOR( j = 0; j < N_DIM; j++ ) { - X_fx[i][j] = x_fx[( N_DIM * i ) + j]; + X_fx[i][j] = x_fx[( N_DIM * i ) + j]; // x2.65 move16(); - W_fx[i][j] = weight_fx[( N_DIM * i ) + j]; + W_fx[i][j] = weight_fx[( N_DIM * i ) + j]; // x2.56 move16(); } } @@ -3259,10 +3262,10 @@ static void BcTcvq_fx( } static Word16 SVQ_2d_fx( - Word16 *x_fx, - Word16 *y_fx, - const Word16 *W_fx, - const Word16 CB_fx[][8], + Word16 *x_fx, // x2.65 + Word16 *y_fx, // x2.65 + const Word16 *W_fx, // Q8 + const Word16 CB_fx[][8], // x2.65 Word16 Size ) { Word16 i, j; @@ -3280,7 +3283,7 @@ static Word16 SVQ_2d_fx( { temp16_fx = sub( x_fx[j], CB_fx[i][j] ); distortion_fx = L_add( distortion_fx, - L_shr( Mult_32_16( L_mult( temp16_fx, temp16_fx ), W_fx[j] ), 1 ) ); + L_shr( Mult_32_16( L_mult( temp16_fx, temp16_fx ), W_fx[j] ), 1 ) ); // (2*x2.65 + Q1 + Q8) - Q15 - Q1 } IF( LT_32( distortion_fx, temp_fx ) ) @@ -3403,9 +3406,9 @@ Word32 qlsf_ARSN_tcvq_Enc_16k_fx( } static void FFT_Mid_Interpol_16k_fx( - Word32 Bin_Ener_old[], /* i/o: Old 2nd FFT Bin energy (128) */ - Word32 Bin_Ener[], /* i : Current 2nd FFT Bin energy (128) */ - Word32 Bin_Ener_mid[] /* o : LP weighting filter (numerator) */ + Word32 Bin_Ener_old[], /* i/o: Old 2nd FFT Bin energy (128) Q_ener*/ + Word32 Bin_Ener[], /* i : Current 2nd FFT Bin energy (128) Q_ener*/ + Word32 Bin_Ener_mid[] /* o : LP weighting filter (numerator) Q_ener*/ ) { Word16 i; @@ -3642,12 +3645,12 @@ static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 nb_bits, /* i : number of bits */ const Word32 int_fs, /* i : internal (ACELP) sampling frequency*/ - const Word16 qlsp0[], /* i : quantized LSPs from frame beginning*/ - const Word16 qlsp1[], /* i : quantized LSPs from frame end */ - Word16 lsp[], /* i/o: mid-frame LSP */ + const Word16 qlsp0[], /* i : quantized LSPs from frame beginning Q15*/ + const Word16 qlsp1[], /* i : quantized LSPs from frame end Q15*/ + Word16 lsp[], /* i/o: mid-frame LSP Q15*/ const Word16 coder_type, /* i : coding type */ const Word16 bwidth, /* i : input signal bandwidth */ - Word32 Bin_Ener[], /* i : per bin log energy spectrum */ + Word32 Bin_Ener[], /* i : per bin log energy spectrum Q_ener*/ Word16 Q_ener, /* i : Q value of Bin_ener */ Word16 ppp_mode, Word16 nelp_mode ) @@ -3681,19 +3684,19 @@ static void lsf_mid_enc_ivas_fx( { case 5: { - ratio = tbl_mid_voi_wb_5b_fx; + ratio = tbl_mid_voi_wb_5b_fx; // Q13 move16(); BREAK; } case 4: { - ratio = tbl_mid_voi_wb_4b_fx; + ratio = tbl_mid_voi_wb_4b_fx; // Q13 move16(); BREAK; } case 1: { - ratio = tbl_mid_voi_wb_1b_fx; + ratio = tbl_mid_voi_wb_1b_fx; // Q13 move16(); BREAK; } @@ -3701,7 +3704,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( coder_type, UNVOICED ) ) { - ratio = tbl_mid_unv_wb_5b_fx; + ratio = tbl_mid_unv_wb_5b_fx; // Q13 } ELSE { @@ -3710,19 +3713,19 @@ static void lsf_mid_enc_ivas_fx( { case 5: { - ratio = tbl_mid_gen_wb_5b_fx; + ratio = tbl_mid_gen_wb_5b_fx; // Q13 move16(); BREAK; } case 4: { - ratio = tbl_mid_gen_wb_4b_fx; + ratio = tbl_mid_gen_wb_4b_fx; // Q13 move16(); BREAK; } case 2: { - ratio = tbl_mid_gen_wb_2b_fx; + ratio = tbl_mid_gen_wb_2b_fx; // Q13 move16(); BREAK; } @@ -3734,7 +3737,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( ppp_mode, 1 ) ) { - ratio = tbl_mid_voi_wb_1b_fx; + ratio = tbl_mid_voi_wb_1b_fx; // Q13 move16(); nb_bits = 1; move16(); @@ -3743,7 +3746,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( nelp_mode, 1 ) ) { - ratio = tbl_mid_unv_wb_4b_fx; + ratio = tbl_mid_unv_wb_4b_fx; // Q13 move16(); nb_bits = 4; move16(); @@ -3765,7 +3768,7 @@ static void lsf_mid_enc_ivas_fx( FOR( j = 0; j < M; j++ ) { /* qlsf[j] = (1.0f - ratio[k*M+j]) * qlsf0[j] + ratio[k*M+j] * qlsf1[j]; */ - L_tmp = L_mult( sub( 0x2000, ratio[k1 + j] ), qlsf0[j] ); + L_tmp = L_mult( sub( 0x2000 /*1.Q13*/, ratio[k1 + j] ), qlsf0[j] ); L_tmp = L_mac( L_tmp, ratio[k1 + j], qlsf1[j] ); qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); @@ -3802,7 +3805,7 @@ static void lsf_mid_enc_ivas_fx( FOR( j = 0; j < M; j++ ) { /* qlsf[j] = (1.0f - ratio[idx*M+j]) * qlsf0[j] + ratio[idx*M+j] * qlsf1[j]; */ - L_tmp = L_mult( sub( 0x2000, ratio[idx * M + j] ), qlsf0[j] ); + L_tmp = L_mult( sub( 0x2000 /*1.Q13*/, ratio[idx * M + j] ), qlsf0[j] ); L_tmp = L_mac( L_tmp, ratio[idx * M + j], qlsf1[j] ); qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 28e1a39de..60375ddcc 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -37,7 +37,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" @@ -93,7 +92,7 @@ Word16 msvq_stage1_dct_search_fx( Word32 *dist1_ptr_fx, /* o : resulting stage 1 MSEs in DCT-N domain */ Word16 *dist1_ptr_e ) { - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; // Q20 Word32 u_mr_fx[FDCNG_VQ_MAX_LEN]; Word16 dist1_ptr_e_buf[2 * LSFMBEST_MAX]; Word64 mse_trunc_segm_fx[FDCNG_VQ_DCT_NSEGM]; @@ -127,7 +126,7 @@ Word16 msvq_stage1_dct_search_fx( tmp_e = s_max( 12, u_e ); FOR( i = 0; i < n_ana; i++ ) { - u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); + u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); // tmp_e move32(); } @@ -136,9 +135,9 @@ Word16 msvq_stage1_dct_search_fx( /* init search state ptr's at the top */ set32_fx( dist1_ptr_fx, MAX_32, maxC_st1 ); set16_fx( dist1_ptr_e_buf, 32, maxC_st1 ); - st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ - st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */ - st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ + st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ // st1_mse_pair_e + st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */ + st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ set64_fx( mse_trunc_segm_fx, 0, n_segm ); // set16_fx( mse_trunc_segm_e, u_e, FDCNG_VQ_DCT_NSEGM ); @@ -152,7 +151,7 @@ Word16 msvq_stage1_dct_search_fx( FOR( i = 0; i < trunc_dct_cols_per_segment[segm]; i++ ) { - mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); + mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); // Q41 move64(); } @@ -163,7 +162,7 @@ Word16 msvq_stage1_dct_search_fx( /* unweighted segmented search DCT domain loop */ j_full = add( j, cum_entries_per_segment[segm] ); /* or simply use j_full++ */ - mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ + mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ // Q41 move64(); dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */ @@ -176,10 +175,10 @@ Word16 msvq_stage1_dct_search_fx( SHIFT( 1 ); ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/ #undef WMC_TOOL_SKIP - mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ + mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ // Q41 } Word16 L_tmp = W_norm( mse_fx ); - st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ + st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ // st1_mse_ptr_e move32(); st1_mse_ptr_e[j_full] = sub( shl( tmp_e, 1 ), L_tmp ); move16(); @@ -362,9 +361,9 @@ Word16 msvq_stage1_dct_search_fx( /*! r: (updated p_max) */ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( - const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors */ + const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors st1_syn_vec_e*/ const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */ - const Word32 *u_fx, /* i : target signal */ + const Word32 *u_fx, /* i : target signal u_e*/ const Word16 u_e, /* i : exp for target signal */ const Word16 maxC_st1, /* i : number of candidates in stage1 */ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ @@ -390,7 +389,7 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */ FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ ) { - high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); + high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); // tmp_e move32(); } acc = 0; @@ -457,7 +456,7 @@ void msvq_enc_ivas_fx( Word16 j; const Word16 *cbp, *cb_stage; Word32 resid_buf_fx[2 * LSFMBEST_MAX * M_MAX], *resid_fx[2]; - Word32 *pTmp, *p1, *p2; + Word32 *pTmp, *p1, *p2; // pTmp_e Word16 pTmp_e; Word16 *indices[2], m, s, c, c2, p_max, i; Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX]; diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index b81cc18e8..aa2255c68 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -36,10 +36,10 @@ val2 = shr( ( cbp )[2], 4 ); \ val3 = add( add( shr( lshl( ( cbp )[2], 12 ), 4 ), lshr( lshl( ( cbp )[1], 12 ), 8 ) ), s_and( ( cbp )[0], 0xF ) ); /*--------------------------------------------------------------------------* - * depack_mul_values() + * depack_mul_values_fx() * *--------------------------------------------------------------------------*/ -static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N ) +static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N ) { Word16 i, val0, val1, val2, val3; Word32 en; @@ -69,7 +69,7 @@ static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp * depack_sub_values() * *--------------------------------------------------------------------------*/ -static void depack_sub_values( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N ) +static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N ) { Word16 j, val0, val1, val2, val3; @@ -93,7 +93,7 @@ static void depack_sub_values( Word16 *pTmp, const Word16 *p1, const Word16 *cbp * * Unroll of inner search loop for maxC == 8 *--------------------------------------------------------------------------*/ -static Word16 msvq_enc_find_p_max_8( Word32 dist[] ) +static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] ) { Word16 p_max; @@ -144,7 +144,7 @@ static Word16 msvq_enc_find_p_max_8( Word32 dist[] ) * * Unroll of inner search loop for maxC == 6 *--------------------------------------------------------------------------*/ -static Word16 msvq_enc_find_p_max_6( Word32 dist[] ) +static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] ) { Word16 p_max; @@ -194,7 +194,7 @@ void msvq_enc_fx( const Word16 maxC, /* i : Tree search size (number of candidates kept from */ /* one stage to the next == M-best) */ const Word16 stages, /* i : Number of stages */ - const Word16 w[], /* i : Weights */ + const Word16 w[], /* i : Weights Q8*/ const Word16 N, /* i : Vector dimension */ const Word16 maxN, /* i : Codebook dimension */ Word16 Idx[] /* o : Indices */ @@ -231,11 +231,11 @@ void msvq_enc_fx( set16_fx( parents, 0, maxC ); - func_ptr = msvq_enc_find_p_max_6; + func_ptr = msvq_enc_find_p_max_6_fx; move16(); if ( EQ_16( maxC, 8 ) ) { - func_ptr = msvq_enc_find_p_max_8; + func_ptr = msvq_enc_find_p_max_8_fx; move16(); } @@ -326,7 +326,7 @@ void msvq_enc_fx( FOR( j = 0; j < levels[s]; j++ ) { /* Compute weighted codebook element and its energy */ - en = depack_mul_values( Tmp + start, w + start, cbp, n ); + en = depack_mul_values_fx( Tmp + start, w + start, cbp, n ); cbp += N34; /* pointer is incremented */ @@ -378,7 +378,7 @@ void msvq_enc_fx( move16(); Copy( p1, pTmp, start ); - depack_sub_values( pTmp + start, p1 + start, &cb[s][p2i * N34], n ); + depack_sub_values_fx( pTmp + start, p1 + start, &cb[s][p2i * N34], n ); Copy( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) ); pTmp += N; @@ -407,12 +407,12 @@ void msvq_enc_fx( *--------------------------------------------------------------------------*/ void midlsf_enc_fx( - const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ - const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ - const Word16 lsf[], /* i: lsf coefficients (3Q12) */ - Word16 *idx, /* o: codebook index */ - const Word16 lpcorder, /* i: order of the lpc */ - const Word32 *Bin_Ener_128_fx, + const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 lsf[], /* i: lsf coefficients (3Q12) */ + Word16 *idx, /* o: codebook index */ + const Word16 lpcorder, /* i: order of the lpc */ + const Word32 *Bin_Ener_128_fx, // Q_ener const Word16 Q_ener, const Word8 narrowBand, const Word32 sr_core, @@ -502,8 +502,8 @@ void midlsf_enc_fx( * Returns: number of indices *--------------------------------------------------------------------------*/ Word16 Q_lsf_tcxlpc_fx( - /* const */ Word16 lsf[], /* i : original lsf */ - Word16 lsf_q[], /* o : quantized lsf */ + /* const */ Word16 lsf[], /* i : original lsf 14Q1 * 1.28 */ + Word16 lsf_q[], /* o : quantized lsf (14Q1*1.28)*/ Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ Word16 indices[], /* o : VQ indices */ const Word16 lpcorder, /* i : LPC order */ @@ -511,7 +511,7 @@ Word16 Q_lsf_tcxlpc_fx( const Word16 cdk, /* i : codebook selector */ const Word16 mem_MA[], /* i : MA memory */ const Word16 coder_type, - const Word32 *Bin_Ener, + const Word32 *Bin_Ener, // Q_ener const Word16 Q_ener ) { Word16 weights[M + 1]; @@ -578,7 +578,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { - lsf_q_ind[i] = lsf_q[i]; + lsf_q_ind[i] = lsf_q[i]; /*(14Q1*1.28)*/ move16(); } @@ -891,7 +891,7 @@ Word16 enc_lsf_tcxlpc_ivas_fx( Word16 lsf_msvq_ma_encprm_fx( BSTR_ENC_HANDLE hBstr, - Word16 *param_lpc, + Word16 *param_lpc, // Q0 Word16 core, Word16 acelp_mode, Word16 acelp_midLpc, @@ -916,7 +916,7 @@ Word16 lsf_msvq_ma_encprm_fx( IF( NE_16( acelp_mode, VOICED ) ) { test(); - IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + IF( ( core == ACELP_CORE ) && acelp_midLpc ) { push_next_indice_fx( hBstr, *param_lpc, bits_midlpc ); @@ -928,7 +928,7 @@ Word16 lsf_msvq_ma_encprm_fx( } Word16 lsf_msvq_ma_encprm_ivas_fx( BSTR_ENC_HANDLE hBstr, - const Word16 *param_lpc, + const Word16 *param_lpc, // Q0 const Word16 core, const Word16 acelp_mode, const Word16 acelp_midLpc, @@ -953,7 +953,7 @@ Word16 lsf_msvq_ma_encprm_ivas_fx( IF( NE_16( acelp_mode, VOICED ) ) { test(); - IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + IF( ( core == ACELP_CORE ) && acelp_midLpc ) { push_next_indice( hBstr, *param_lpc, bits_midlpc ); @@ -971,7 +971,7 @@ Word16 lsf_msvq_ma_encprm_ivas_fx( *--------------------------------------------------------------------------*/ Word16 lsf_bctcvq_encprm_fx( BSTR_ENC_HANDLE hBstr, - Word16 *param_lpc, + Word16 *param_lpc, // Q0 Word16 *bits_param_lpc, Word16 no_indices ) { @@ -990,7 +990,7 @@ Word16 lsf_bctcvq_encprm_fx( } Word16 lsf_bctcvq_encprm_ivas_fx( BSTR_ENC_HANDLE hBstr, - const Word16 *param_lpc, + const Word16 *param_lpc, // Q0 const Word16 *bits_param_lpc, const Word16 no_indices ) { diff --git a/lib_enc/ltd_stable_fx.c b/lib_enc/ltd_stable_fx.c index a6e3ae1cc..036fe2a7e 100644 --- a/lib_enc/ltd_stable_fx.c +++ b/lib_enc/ltd_stable_fx.c @@ -21,7 +21,7 @@ void ltd_stable_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ Word16 *ltd_stable_rate, /* o : time-domain stable rate*/ - const Word32 frame_energy, /* i : current frame energy*/ + const Word32 frame_energy, /* i : current frame energy Q_frames_power*/ const Word16 frameloop, /* i : amount of frames*/ const Word16 Q_frames_power /* i : the Scaling of frames_power*/ ) @@ -57,7 +57,7 @@ void ltd_stable_fx( move16(); Q_apow = 0; move16(); - frames_power_32 = hVAD_CLDFB->frames_power_32; + frames_power_32 = hVAD_CLDFB->frames_power_32; // Q_frames_power_last_32 Q_frames_power_last_32 = hVAD_CLDFB->Q_frames_power_32; move16(); leadingzero_midamp = 31; @@ -76,7 +76,7 @@ void ltd_stable_fx( IF( GE_16( Q_frames_power32, 40 ) ) { zerop001 = L_shr( CNT0P001, 1 ); - frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, sub( Q_frames_power32, 39 ) ); + frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, sub( Q_frames_power32, 39 ) ); // Q_frames_power32 Q_frames_power32 = 39; move16(); } @@ -86,14 +86,14 @@ void ltd_stable_fx( frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, 1 ); zerop001 = L_shr( CNT0P001, sub( 40, Q_frames_power32 ) ); } - frames_power_32[0] = L_add( frame_energy_Sqr32, zerop001 ); + frames_power_32[0] = L_add( frame_energy_Sqr32, zerop001 ); // Q_frames_power32 move32(); IF( LT_16( frameloop, 3 ) ) { FOR( i = 1; i < 40; i++ ) { - frames_power_32[i] = frames_power_32[0]; + frames_power_32[i] = frames_power_32[0]; // Q_frames_power32 move32(); } } @@ -104,7 +104,7 @@ void ltd_stable_fx( move32(); FOR( i = 1; i < 40; i++ ) { - maxVal = L_max( maxVal, frames_power_32[i] ); + maxVal = L_max( maxVal, frames_power_32[i] ); // Q_frames_power32 } leadingzero = 31; move16(); @@ -119,7 +119,7 @@ void ltd_stable_fx( scale1 = sub( scale1, leadingzero ); FOR( i = 1; i < 40; i++ ) { - frames_power_32[i] = L_shr( frames_power_32[i], scale1 ); + frames_power_32[i] = L_shr( frames_power_32[i], scale1 ); // Q_frames_power32 move32(); } } @@ -140,7 +140,7 @@ void ltd_stable_fx( FOR( i = 0; i < 20; i++ ) { - mid_frame_ampadd32[i] = L_add( L_shr( frames_power_32[2 * i], 1 ), L_shr( frames_power_32[2 * i + 1], 1 ) ); + mid_frame_ampadd32[i] = L_add( L_shr( frames_power_32[2 * i], 1 ), L_shr( frames_power_32[2 * i + 1], 1 ) ); // Q_frames_power32 move32(); } @@ -148,16 +148,18 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - maxVal = L_max( maxVal, mid_frame_ampadd32[i] ); + maxVal = L_max( maxVal, mid_frame_ampadd32[i] ); // Q_frames_power32 } leadingzero_midamp = 31; move16(); if ( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 20; i++ ) { - mid_frame_amp32[i] = L_shl( mid_frame_ampadd32[i], leadingzero_midamp ); + mid_frame_amp32[i] = L_shl( mid_frame_ampadd32[i], leadingzero_midamp ); // Q_frames_power32 + leadingzero_midamp move32(); } @@ -165,19 +167,19 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 5 ) ); + seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 5 ) ); // Q_frames_power32 + leadingzero_midamp - 5 } - seg_amp32 = MUL_F( seg_amp32, 0x0666 ); + seg_amp32 = MUL_F( seg_amp32, 0x0666 /*(1/20).Q15*/ ); dif32 = 0; move32(); apow32 = 0; move32(); - seg_amp32tmp = L_shl( seg_amp32, 5 ); + seg_amp32tmp = L_shl( seg_amp32, 5 ); // Q_frames_power32 + leadingzero_midamp FOR( i = 0; i < 20; i++ ) { - tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); + tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); // Q_frames_power32 + leadingzero_midamp move32(); } @@ -185,22 +187,24 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - maxVal = L_max( maxVal, L_abs( tmp32[i] ) ); + maxVal = L_max( maxVal, L_abs( tmp32[i] ) ); // Q_frames_power32 + leadingzero_midamp - 5 } leadingzero_tmp32 = 31; move16(); if ( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); + } FOR( i = 0; i < 20; i++ ) { - tmp16[i] = extract_h( L_shl( tmp32[i], leadingzero_tmp32 ) ); + tmp16[i] = extract_h( L_shl( tmp32[i], leadingzero_tmp32 ) ); //// Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16 } FOR( i = 0; i < 20; i++ ) { - tmp_mul = L_mult_sat( tmp16[i], tmp16[i] ); - tmp_mul = L_shr( tmp_mul, 5 ); + tmp_mul = L_mult_sat( tmp16[i], tmp16[i] ); // 2 * (Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16) + 1 + tmp_mul = L_shr( tmp_mul, 5 ); // 2 * (Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16) - 4 dif32 = L_add( dif32, tmp_mul ); tmp = extract_h( mid_frame_amp32[i] ); @@ -244,7 +248,9 @@ void ltd_stable_fx( leadingzero_midamp = 31; move16(); if ( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 14; i++ ) { @@ -256,15 +262,15 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 14; i++ ) { - seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 4 ) ); + seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 4 ) ); // Q_frames_power32 - 4 } - seg_amp32 = MUL_F( seg_amp32, 0x0924 ); + seg_amp32 = MUL_F( seg_amp32, 0x0924 /*(1/14).Q15*/ ); dif32 = 0; move32(); apow32 = 0; move32(); - seg_amp32tmp = L_shl( seg_amp32, 4 ); + seg_amp32tmp = L_shl( seg_amp32, 4 ); // Q_frames_power32 FOR( i = 0; i < 14; i++ ) { tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); @@ -280,7 +286,9 @@ void ltd_stable_fx( leadingzero_tmp32 = 31; move16(); if ( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); + } FOR( i = 0; i < 14; i++ ) { @@ -367,8 +375,10 @@ void ltd_stable_fx( } leadingzero_midamp = 31; move16(); - if ( maxVal ) + IF( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 8; i++ ) { @@ -382,7 +392,7 @@ void ltd_stable_fx( { seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 3 ) ); } - seg_amp32 = MUL_F( seg_amp32, 0x1000 ); + seg_amp32 = MUL_F( seg_amp32, 0x1000 /*(1/8).Q15*/ ); dif32 = 0; move32(); @@ -403,9 +413,10 @@ void ltd_stable_fx( } leadingzero_tmp32 = 31; move16(); - if ( maxVal ) + IF( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); - + } FOR( i = 0; i < 8; i++ ) { tmp32[i] = L_shl( tmp32[i], leadingzero_tmp32 ); @@ -482,7 +493,7 @@ void ltd_stable_fx( ltd_stable_rate[2] = shr( ltd_stable_rate[2], ltd_stable_rate_Qtmp ); move16(); - ltd_stable_rate[3] = add( mult( ltd_stable_rate[3], 0x7333 ), mult( ltd_stable_rate[2], 0x0ccc ) ); + ltd_stable_rate[3] = add( mult( ltd_stable_rate[3], 0x7333 /*0.9.Q15*/ ), mult( ltd_stable_rate[2], 0x0ccc /*0.1.Q15*/ ) ); move16(); FOR( i = 55; i > 0; i-- ) diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index eec85c254..a4e19e040 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -46,7 +46,7 @@ * Square magnitude of fft spectrum *----------------------------------------------------------------------------*/ static void dft_mag_square_fx( - const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ + const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] Qx*/ Word32 magSq[], /* o : Magnitude square spectrum */ const Word16 n /* i : Input vector length */ ) @@ -57,7 +57,7 @@ static void dft_mag_square_fx( /* Magnitude square at 0. */ pMagSq = &magSq[0]; - pRe = &x[0]; + pRe = &x[0]; // Qx *pMagSq++ = L_mult0( *pRe, *pRe ); pRe++; move32(); @@ -70,13 +70,13 @@ static void dft_mag_square_fx( { acc = L_mult0( *pRe, *pRe ); pRe++; - *pMagSq++ = L_mac0( acc, *pIm, *pIm ); + *pMagSq++ = L_mac0( acc, *pIm, *pIm ); // 2*Qx pIm--; move32(); } /* The magnitude square at N/2 */ - *pMagSq = L_mult0( *pRe, *pRe ); + *pMagSq = L_mult0( *pRe, *pRe ); // 2*Qx move32(); return; } @@ -89,7 +89,7 @@ static void dft_mag_square_fx( Word16 mdct_classifier_fx( /* o: MDCT A/B decision */ const Word16 *fft_buff, /* i: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ Encoder_State *st_fx, /* i/o: Encoder state variable */ - Word32 *cldfbBuf_Ener, + Word32 *cldfbBuf_Ener, // enerBuffer_exp Word16 enerBuffer_exp, const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ ) @@ -260,7 +260,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision { IF( max_i > 0 ) { - IF( GT_16( np, 0 ) ) + IF( ( np > 0 ) ) { d_acc = sub( add( d_acc, max_i ), pos_last ); } @@ -277,7 +277,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision IF( pe != 0 ) { expo = norm_l( pe ); - man = L_shl( pe, expo ); + man = L_shl( pe, expo ); // expo Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); @@ -309,35 +309,35 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision /* gain11 = 8*(gain1 - cldfbBuf_Ener[0]/8)/7; */ acc = L_shr( cldfbBuf_Ener[0], 3 ); acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 4681 ); + acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); gain11 = L_shl( acc, 3 ); gain4 = L_deposit_l( 0 ); FOR( k = 0; k < 12; k++ ) { - gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 ) ); + gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 /*(1/12).Q15*/ ) ); } peak_H1 = L_add( cldfbBuf_Ener[25], 0 ); - Mpy_32_16_ss( cldfbBuf_Ener[25], 6554, &avrg_H1, &lsb16 ); + Mpy_32_16_ss( cldfbBuf_Ener[25], 6554 /*0.4.Q15*/, &avrg_H1, &lsb16 ); FOR( k = 1; k < 5; k++ ) { IF( GT_32( cldfbBuf_Ener[k + 25], peak_H1 ) ) { peak_H1 = L_add( cldfbBuf_Ener[k + 25], 0 ); } - avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 ) ); + avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 /*0.4.Q15*/ ) ); } peak_H2 = L_add( cldfbBuf_Ener[20], 0 ); - Mpy_32_16_ss( cldfbBuf_Ener[20], 6554, &avrg_H2, &lsb16 ); + Mpy_32_16_ss( cldfbBuf_Ener[20], 6554 /*0.4.Q15*/, &avrg_H2, &lsb16 ); FOR( k = 1; k < 5; k++ ) { IF( GT_32( cldfbBuf_Ener[k + 20], peak_H2 ) ) { peak_H2 = L_add( cldfbBuf_Ener[k + 20], 0 ); } - avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 ) ); + avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 /*0.4.Q15*/ ) ); } // End peak_l = L_deposit_l( 0 ); @@ -400,7 +400,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision condition4 = 0; move16(); - L_tmp = Mult_32_16( peak_h, 12603 ); + L_tmp = Mult_32_16( peak_h, 12603 /*1/2.56.Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -418,7 +418,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision exp1 = norm_l( avrg_l ); } - L_tmp1 = Mult_32_16( peak_l, 12603 ); + L_tmp1 = Mult_32_16( peak_l, 12603 /*1/2.56.Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -438,7 +438,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision move16(); } - L_tmp = Mult_32_16( peak_h, 12800 ); + L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -448,7 +448,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision exp = norm_l( L_tmp ); } - L_tmp1 = Mult_32_16( peak_l, 6400 ); + L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -476,7 +476,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision test(); test(); test(); - IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) ) { condition4 = 1; move16(); @@ -498,21 +498,21 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision } /* Smooth decision from instantaneous decision*/ - acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ - clas_sec = mac_r( acc, c, 0x7fff - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ + acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ + clas_sec = mac_r( acc, c, 0x7fff /*1.Q15*/ - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ /* Do thresholding with hysteresis */ IF( GT_16( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ) { - gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); + gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp move32(); - gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); + gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp move32(); } ELSE { - hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); + hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp move32(); - hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); + hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp move32(); gain1_tmp = gain1; move32(); @@ -582,10 +582,11 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision return clas_final; /* Q0 */ } + Word16 mdct_classifier_ivas_fx( Encoder_State *st, /* i/o: Encoder state variable */ const Word16 *fft_buff, /* i : FFT spectrum from fft_rel */ - const Word32 enerBuffer[], /* i : energy buffer */ + const Word32 enerBuffer[], /* i : energy buffer enerBuffer_exp*/ Word16 enerBuffer_exp, const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ ) @@ -772,7 +773,7 @@ Word16 mdct_classifier_ivas_fx( IF( pe != 0 ) { expo = norm_l( pe ); - man = L_shl( pe, expo ); + man = L_shl( pe, expo ); // expo Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); @@ -795,32 +796,32 @@ Word16 mdct_classifier_ivas_fx( { IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) { - gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); - gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); - gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); + gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); // enerBuffer_exp - 3 + gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); // enerBuffer_exp - 3 + gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); // enerBuffer_exp - 3 } ELSE { - gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); - gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 ) ); - gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 ) ); + gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); // enerBuffer_exp + gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp + gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp } } IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) { - acc = L_shr( enerBuffer[0], 3 ); - acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 4681 ); - gain11 = L_shl( acc, 3 ); + acc = L_shr( enerBuffer[0], 3 ); // enerBuffer_exp - 3 + acc = L_sub( gain1, acc ); // enerBuffer_exp - 3 + acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); // enerBuffer_exp - 3 + gain11 = L_shl( acc, 3 ); // enerBuffer_exp gain4 = L_deposit_l( 0 ); } ELSE { - acc = Mult_32_16( enerBuffer[0], 5461 ); - acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 6553 ); + acc = Mult_32_16( enerBuffer[0], 5461 /*0.16.Q15*/ ); // enerBuffer_exp + acc = L_sub( gain1, acc ); // enerBuffer_exp + acc = Mult_32_16( acc, 6553 /*0.4.Q15*/ ); // enerBuffer_exp gain11 = (Word32) W_mult_32_16( acc, 6 ); gain4 = L_deposit_l( 0 ); } @@ -830,28 +831,28 @@ Word16 mdct_classifier_ivas_fx( { IF( EQ_16( gain4_start, GAIN4_START_SWB ) ) { - gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 ) ); + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 /*(1/12).Q15*/ ) ); } ELSE { - gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 ) ); + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 /*(1/9).Q1.15*/ ) ); } } - peak_H1 = enerBuffer[H1_start]; + peak_H1 = enerBuffer[H1_start]; // enerBuffer_exp move32(); - avrg_H1 = enerBuffer[H1_start]; + avrg_H1 = enerBuffer[H1_start]; // enerBuffer_exp move32(); FOR( i = 1; i < H_length; i++ ) { IF( GT_32( enerBuffer[H1_start + i], peak_H1 ) ) { - peak_H1 = enerBuffer[H1_start + i]; + peak_H1 = enerBuffer[H1_start + i]; // enerBuffer_exp move32(); } - avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); + avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); // enerBuffer_exp } peak_H2 = enerBuffer[H2_start]; @@ -969,7 +970,7 @@ Word16 mdct_classifier_ivas_fx( move16(); } - L_tmp = Mult_32_16( peak_h, 12800 ); + L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -979,7 +980,7 @@ Word16 mdct_classifier_ivas_fx( exp = norm_l( L_tmp ); } - L_tmp1 = Mult_32_16( peak_l, 6400 ); + L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -1007,8 +1008,8 @@ Word16 mdct_classifier_ivas_fx( test(); test(); test(); - IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || - ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || + ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) ) { condition4 = 1; move16(); diff --git a/lib_enc/mdct_selector_fx.c b/lib_enc/mdct_selector_fx.c index 52c30f7ef..c4cc7d0db 100644 --- a/lib_enc/mdct_selector_fx.c +++ b/lib_enc/mdct_selector_fx.c @@ -62,14 +62,14 @@ static Word16 get_sparseness( /* Returns sparseness measur FOR( i = 1; i < n - 1; ++i ) { - if ( GT_16( Bin_E[i], s_max( s_max( Bin_E[i - 1], Bin_E[i + 1] ), thr ) ) ) + IF( GT_16( Bin_E[i], s_max( s_max( Bin_E[i - 1], Bin_E[i + 1] ), thr ) ) ) { num_max = add( num_max, 1 ); } } n = shr( sub( n, 2 ), 1 ); - return div_s( sub( n, num_max ), n ); + return div_s( sub( n, num_max ), n ); // Q15 } /*--------------------------------------------------------------------------* * get_mean_ener() @@ -78,7 +78,7 @@ static Word16 get_sparseness( /* Returns sparseness measur *--------------------------------------------------------------------------*/ static Word16 get_mean_ener( /* Returns mean energy in dB (Q8) */ - const Word32 enerBuffer[], /* i : CLDFB buffers */ + const Word32 enerBuffer[], /* i : CLDFB buffers enerBuffer_exp*/ Word16 enerBuffer_exp, /* i : exponent of enerBuffer */ Word16 n /* i : number of bins */ ) @@ -87,8 +87,10 @@ static Word16 get_mean_ener( /* Returns mean energy i Word16 i, shift, frac_nrg, exp_nrg; shift = sub( 14, norm_s( n ) ); - if ( LT_16( shl( 1, shift ), n ) ) + IF( LT_16( shl( 1, shift ), n ) ) + { shift = add( shift, 1 ); + } L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < n; ++i ) @@ -104,7 +106,7 @@ static Word16 get_mean_ener( /* Returns mean energy i exp_nrg = sub( add( exp_nrg, shift ), sub( 31, enerBuffer_exp ) ); L_tmp = Mpy_32_16( exp_nrg, frac_nrg, 9864 ); /* log10(2) in Q15 */ - return round_fx( L_shl( L_tmp, 8 ) ); + return round_fx( L_shl( L_tmp, 8 ) ); // Q8 } /*--------------------------------------------------------------------------* * MDCT_selector_fx() @@ -117,7 +119,7 @@ void MDCT_selector_fx( Word16 sp_floor, /* i : Noise floor estimate Q7 */ const Word16 Etot, /* i : Total energy Q8 */ const Word16 cor_map_sum, /* i : harmonicity factor Q8 */ - const Word32 enerBuffer[], /* i : CLDFB buffers */ + const Word32 enerBuffer[], /* i : CLDFB buffers enerBuffer_exp*/ const Word16 enerBuffer_exp /* i : exponent of enerBuffer */ ) { @@ -135,7 +137,7 @@ void MDCT_selector_fx( sp_floor = shl( sp_floor, 1 ); /* convert to Q8 */ - IF( EQ_16( st->bwidth, NB ) ) + IF( ( st->bwidth == NB ) ) { lob_cldfb = 3200 / 400; move16(); @@ -188,7 +190,7 @@ void MDCT_selector_fx( frame_voicing = add( shr( st->voicing_fx[0], 1 ), shr( st->voicing_fx[1], 1 ) ); /* Spectral sparseness */ - sparseness = get_sparseness( st->lgBin_E_fx, lob_fft, sub( Etot, MDCT_SW_SIG_PEAK_THR ) ); + sparseness = get_sparseness( st->lgBin_E_fx, lob_fft, sub( Etot, MDCT_SW_SIG_PEAK_THR ) ); // Q15 /* Hi band energy */ hi_ener = get_mean_ener( &enerBuffer[lob_cldfb], enerBuffer_exp, sub( hib_cldfb, lob_cldfb ) ); @@ -255,23 +257,23 @@ void MDCT_selector_fx( IF( EQ_16( st->mdct_sw_enable, MODE1 ) ) { - sig_lo_level_thr = MDCT_SW_1_SIG_LO_LEVEL_THR; + sig_lo_level_thr = MDCT_SW_1_SIG_LO_LEVEL_THR; // Q8 move16(); - sig_hi_level_thr = MDCT_SW_1_SIG_HI_LEVEL_THR; + sig_hi_level_thr = MDCT_SW_1_SIG_HI_LEVEL_THR; // Q8 move16(); - cor_thr = MDCT_SW_1_COR_THR; + cor_thr = MDCT_SW_1_COR_THR; // Q8 move16(); - cor_thr2 = MDCT_SW_1_COR_THR2; + cor_thr2 = MDCT_SW_1_COR_THR2; // Q8 move16(); - voicing_thr = MDCT_SW_1_VOICING_THR; + voicing_thr = MDCT_SW_1_VOICING_THR; // Q15 move16(); - voicing_thr2 = MDCT_SW_1_VOICING_THR2; + voicing_thr2 = MDCT_SW_1_VOICING_THR2; // Q15 move16(); - sparseness_thr = MDCT_SW_1_SPARSENESS_THR; + sparseness_thr = MDCT_SW_1_SPARSENESS_THR; // Q15 move16(); - sparseness_thr2 = MDCT_SW_1_SPARSENESS_THR2; + sparseness_thr2 = MDCT_SW_1_SPARSENESS_THR2; // Q15 move16(); - hi_ener_lo_thr = MDCT_SW_1_HI_ENER_LO_THR; + hi_ener_lo_thr = MDCT_SW_1_HI_ENER_LO_THR; // Q8 move16(); } ELSE /* st->mdct_sw_enable == MODE2 */ diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index 771ef480b..af5a82b69 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -58,19 +58,19 @@ Word32 mslvq_fx( IF( pred_flag == 0 ) { - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // Qlog2(2.56) /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; - p_scales = scales_fx[mode_glb]; - p_no_lead = no_lead_fx[mode_glb]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 + p_scales = scales_fx[mode_glb]; // Q11 + p_no_lead = no_lead_fx[mode_glb]; // Q0 } ELSE { - p_sigma = sigma_p_fx[mode]; + p_sigma = sigma_p_fx[mode]; // Qlog2(2.56) /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_p_fx[mode]; - p_scales = scales_p_fx[mode_glb]; - p_no_lead = no_lead_p_fx[mode_glb]; + p_inv_sigma = inv_sigma_p_fx[mode]; // Q15 + p_scales = scales_p_fx[mode_glb]; // Q11 + p_no_lead = no_lead_p_fx[mode_glb]; // Q0 } /* first subvector */ @@ -184,15 +184,15 @@ Word32 mslvq_cng_fx( mode_glb = add( START_CNG, idx_cv ); move16(); - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 move16(); - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; + p_scales = scales_fx[mode_glb]; // Q11 move16(); - p_no_lead = no_lead_fx[mode_glb]; + p_no_lead = no_lead_fx[mode_glb]; // Q0 move16(); - p_no_scales = &no_scales[shl( mode_glb, 1 )]; + p_no_scales = &no_scales[( mode_glb << 1 )]; move16(); /* check if LSF component permutation is needed or not */ @@ -247,11 +247,11 @@ Word32 mslvq_cng_ivas_fx( mode_glb = add( START_CNG, idx_cv ); move16(); - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 move16(); - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; + p_scales = scales_fx[mode_glb]; // Q11 move16(); no_scales[0] = 0; @@ -773,7 +773,7 @@ static void sort_desc_ind_fx( move16(); } sorted = 0; - FOR( k = sub( len, 1 ); k > 0; k-- ) + FOR( k = ( len - 1 ); k > 0; k-- ) { IF( sorted ) { @@ -837,7 +837,7 @@ void index_lvq_fx( /* for first subvector */ IF( GT_16( idx_scale[0], -1 ) ) { - index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[i_mult2( mode, len_offset ) + idx_scale[0]] ) ); + index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[( mode * len_offset ) + idx_scale[0]] ) ); } /* for second subvector */ @@ -845,7 +845,7 @@ void index_lvq_fx( IF( GT_16( idx_scale[1], -1 ) ) { - index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[i_mult2( mode, len_offset ) + idx_scale[1]] ) ); + index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[( mode * len_offset ) + idx_scale[1]] ) ); } idx64 = W_mult0_32_32( index1, p_offset_scale2[mode * len_offset + p_no_scales[mode * 2 + 1]] ); index2_64 = W_deposit32_l( index2 ); @@ -854,9 +854,9 @@ void index_lvq_fx( /* convert to 3 short */ index[0] = ( ( idx64 ) & ( 0x7fff ) ); move16(); - index[1] = ( idx64 >> 15 ) & ( 0x7fff ); + index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff ); move16(); - index[2] = ( idx64 >> 30 ) & ( 0x7fff ); + index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff ); move16(); return; } @@ -900,9 +900,9 @@ void index_lvq_ivas_fx( /* convert to 3 short */ index[0] = ( ( idx64 ) & ( 0x7fff ) ); move16(); - index[1] = ( idx64 >> 15 ) & ( 0x7fff ); + index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff ); move16(); - index[2] = ( idx64 >> 30 ) & ( 0x7fff ); + index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff ); move16(); return; @@ -1059,7 +1059,7 @@ static Word16 encode_sign_pc1_fx( /* o : index of signs IF( cv[i] < 0 ) { idx_sign = add( idx_sign, ( shl( 1, cnt ) ) ); - cnt++; + cnt = add( cnt, 1 ); } if ( cv[i] > 0 ) @@ -1091,7 +1091,7 @@ static void take_out_val_fx( FOR( i = 0; i < len; i++ ) { - IF( NE_16( v[i], val ) ) + if ( NE_16( v[i], val ) ) { v_out[cnt++] = v[i]; move16(); @@ -1125,7 +1125,7 @@ Word16 c2idx_fx( /* o: index */ move16(); FOR( i = 1; i <= p[0]; i++ ) { - skip = add( skip, C_VQ[sub( n, i )][sub( k, 1 )] ); + skip = add( skip, C_VQ[( n - i )][( k - 1 )] ); // Q0 } p0 = p[0]; diff --git a/lib_enc/multi_harm_fx.c b/lib_enc/multi_harm_fx.c index 78ef81c60..1bae597b6 100644 --- a/lib_enc/multi_harm_fx.c +++ b/lib_enc/multi_harm_fx.c @@ -53,7 +53,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity /* length of the useful part of the spectrum (up to 6.4kHz) */ L = L_FFT / 2; move16(); - if ( EQ_16( bwidth, NB ) ) + if ( ( bwidth == NB ) ) { /* length of the useful part of the spectrum (up to 3.6kHz) */ L = 76; @@ -170,14 +170,14 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity mean_dyn = round_fx( L_acc ); /*Q7*/ test(); - IF( LT_16( mean_dyn, 1229 ) /*9.6f*/ && *cor_strong_limit != 0 ) + IF( LT_16( mean_dyn, 1229 ) /*9.6f.Q7*/ && *cor_strong_limit != 0 ) { *cor_strong_limit = 0; move16(); *st_last_sw_dyn = mean_dyn; move16(); } - ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f*/ ) + ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f.Q7*/ ) { *cor_strong_limit = 1; move16(); @@ -290,7 +290,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity cor_strong = 0; move16(); - pt1 = cor_map_LT; + pt1 = cor_map_LT; // Q15 move16(); pt2 = cor_map; move16(); @@ -306,7 +306,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity /* cor_map_LT_sum += *pt1 */ Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */ - if ( GT_16( *pt1, 31130 ) /*0.95f*/ ) + if ( GT_16( *pt1, 31130 ) /*0.95f.Q15*/ ) { cor_strong = 1; move16(); @@ -316,7 +316,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity pt2++; } - IF( EQ_16( bwidth, NB ) ) + IF( ( bwidth == NB ) ) { /* cor_map_LT_sum *= 1.53f; */ /* tmp2 *= 1.53f; */ @@ -396,7 +396,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni /* length of the useful part of the spectrum (up to 6.4kHz) */ L = L_FFT / 2; move16(); - if ( EQ_16( bwidth, NB ) ) + if ( ( bwidth == NB ) ) { /* length of the useful part of the spectrum (up to 3.6kHz) */ L = 76; @@ -654,7 +654,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni } tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8 - IF( EQ_16( bwidth, NB ) ) + IF( ( bwidth == NB ) ) { /* cor_map_LT_sum *= 1.53f; */ /* tmp2 *= 1.53f; */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 353de8ec9..e04f5172b 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -17,7 +17,6 @@ #include "debug.h" #endif #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 7bbc54780..5c96a2f29 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" #include "stl.h" #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 61ca9b101..ba8ee5aa8 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "stl.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 008e27d6c..770b62764 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -36,7 +36,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index 81437c49d..e50ad32e1 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 9cc764afb..93a100e17 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -34,7 +34,6 @@ #include #include "ivas_cnst.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 730705ffd..0deb14c9b 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_binauralRenderer.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index e89414542..b8b3c3ac7 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index 4eae9c286..e9af8483a 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 29eac3635..40ed0ad58 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 958a23a3f..e254ed6dd 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_efap_fx.c b/lib_rend/ivas_efap_fx.c index 52ca3e6f9..7a74e62da 100644 --- a/lib_rend/ivas_efap_fx.c +++ b/lib_rend/ivas_efap_fx.c @@ -36,7 +36,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_hrtf_fx.c b/lib_rend/ivas_hrtf_fx.c index 5d53d2ae3..e3965fbff 100644 --- a/lib_rend/ivas_hrtf_fx.c +++ b/lib_rend/ivas_hrtf_fx.c @@ -36,7 +36,6 @@ #include "ivas_prot_rend.h" #include "ivas_error.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 8b7e6575d..430fab2c7 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "lib_rend.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 25fddaa80..8b56b6855 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "options.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 93fe67436..7b1e1fe91 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index d7387ecd4..2c28b32bd 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -35,7 +35,6 @@ #include #include "ivas_cnst.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_stat_rend.h" diff --git a/lib_rend/ivas_orient_trk_fx.c b/lib_rend/ivas_orient_trk_fx.c index bb6f26346..a124bf4bd 100644 --- a/lib_rend/ivas_orient_trk_fx.c +++ b/lib_rend/ivas_orient_trk_fx.c @@ -33,7 +33,6 @@ #include "common_api_types.h" #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 054e5e981..6fba496d5 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -37,7 +37,6 @@ #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------------* diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c index bbe6ae4b5..74be74497 100644 --- a/lib_rend/ivas_output_init_fx.c +++ b/lib_rend/ivas_output_init_fx.c @@ -1,6 +1,5 @@ #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #ifdef FIX_DISCLAIMER #include diff --git a/lib_rend/ivas_reflections_fx.c b/lib_rend/ivas_reflections_fx.c index a02a29d0d..d6e397234 100644 --- a/lib_rend/ivas_reflections_fx.c +++ b/lib_rend/ivas_reflections_fx.c @@ -39,7 +39,6 @@ #include "ivas_prot_rend.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "debug.h" diff --git a/lib_rend/ivas_reverb_delay_line_fx.c b/lib_rend/ivas_reverb_delay_line_fx.c index 44550803a..ab41b43c2 100644 --- a/lib_rend/ivas_reverb_delay_line_fx.c +++ b/lib_rend/ivas_reverb_delay_line_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_sba_rendering_fx.c b/lib_rend/ivas_sba_rendering_fx.c index 4323fc96f..d544acd13 100644 --- a/lib_rend/ivas_sba_rendering_fx.c +++ b/lib_rend/ivas_sba_rendering_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index 6d5b23f12..0fc5c21df 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index 06cbd83a6..b90b3a456 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ae3166520..2c81911a1 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -33,7 +33,6 @@ #include "options.h" #include "lib_rend.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 930bb79dc..0316d8b30 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -34,7 +34,6 @@ #include #include "prot_fx.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 90d47b7c9..f4f43e496 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -33,7 +33,7 @@ #include "ls_custom_file_reader.h" #include #include -#include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot_fx.h" diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 9351d9bc9..efab80b79 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "masa_file_reader.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include #include -- GitLab From 9c746ad1a61ff9c6b55615830b67b0e0db3ff4d0 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 11 Mar 2025 15:08:51 +0100 Subject: [PATCH 0368/1221] Resolve unused else branch in save_synthesis_hq_fec_fx with comment. Enable NB-only updates related to NB FEC tools --- lib_dec/FEC_HQ_core_fx.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index b748c1785..69e53fa9e 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -725,10 +725,9 @@ void HQ_FEC_Mem_update_fx( move32(); #endif move32(); // tmp_energy_fx -#ifdef ADD_IVAS_HQ_CODE_FEC + IF( EQ_16( output_frame, L_FRAME8k ) ) { -#endif IF( is_transient ) { @@ -759,10 +758,10 @@ void HQ_FEC_Mem_update_fx( } } } -#ifndef ADD_IVAS_HQ_CODE_FEC + IF( EQ_16( output_frame, L_FRAME8k ) ) { -#endif + /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */ test(); IF( ( EQ_16( hqswb_clas, HQ_HVQ ) ) || ( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) ) @@ -976,9 +975,9 @@ void HQ_FEC_Mem_update_fx( move16(); hHQ_core->old_is_transient[0] = is_transient; move16(); -#ifdef ADD_IVAS_HQ_CODE_FEC + } -#endif + return; } @@ -2023,6 +2022,12 @@ void save_synthesis_hq_fec_fx( { Copy_Scale_sig( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st->Qprev_synth_buffer_fx ) ); /*Q0*/ } + /* IVAS Floating point code has the commented-out else branch below, but it does not appear to be necessary. To be verified + else + { + mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + */ IF( st->core != ACELP_CORE ) { -- GitLab From 235ba45d379371dea5f7b2a5e1091501f69b2cfe Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 11 Mar 2025 15:09:38 +0100 Subject: [PATCH 0369/1221] Cleanup of unused float code --- lib_dec/FEC_HQ_core_fx.c | 88 ---------------------------------------- 1 file changed, 88 deletions(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 69e53fa9e..4c7e1b0f6 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -2062,91 +2062,3 @@ void save_synthesis_hq_fec_fx( } return; } - - -#ifdef ADD_IVAS_HQ_CODE_FEC -/*-------------------------------------------------------------------------- - * save_synthesis_hq_fec() - * - * Save synthesis for HQ FEC - *-------------------------------------------------------------------------*/ - -void save_synthesis_hq_fec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *output, /* i : decoded synthesis */ - const int16_t output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -) -{ - int16_t post_hq_delay; - - switch ( st->element_mode ) - { - case EVS_MONO: - post_hq_delay = NS2SA( st->output_Fs, POST_HQ_DELAY_NS ); - break; - case IVAS_SCE: - post_hq_delay = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); - break; - case IVAS_CPE_DFT: - if ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) - { - post_hq_delay = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); - } - else - { - post_hq_delay = 0; - } - break; - default: - post_hq_delay = 0; - break; - } - - - if ( ( st->codec_mode == MODE1 && st->hTcxDec != NULL ) && ( ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) ) || st->core == HQ_CORE ) ) - { - mvr2r( st->hTcxDec->synth_history + output_frame, st->hTcxDec->synth_history, output_frame - post_hq_delay + NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ); - mvr2r( output, st->hTcxDec->old_synthFB + output_frame - post_hq_delay, output_frame ); - - if ( st->element_mode == EVS_MONO ) - { - /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill - this buffer are not available for all cases, the impact on the output is limited */ - set_f( st->hTcxDec->old_synthFB + 2 * output_frame - post_hq_delay, 0.f, post_hq_delay ); - if ( output_frame >= L_FRAME16k ) - { - mvr2r( st->prev_synth_buffer, st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS ), NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - } - else - { - mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - - if ( st->core != ACELP_CORE ) - { - if ( output_frame >= L_FRAME16k ) - { - mvr2r( st->delay_buf_out, st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA( st->output_Fs, DELAY_CLDFB_NS ), NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ); - mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - else - { - mvr2r( st->delay_buf_out, st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS ), NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ); - mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - else - { - if ( st->core != ACELP_CORE ) - { - mvr2r( st->delay_buf_out, st->hTcxDec->old_synthFB + 2 * output_frame - post_hq_delay, post_hq_delay ); - mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - - return; -} -#endif -- GitLab From 7027097814fca9e108640c2793a4620025705dfc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 19:41:16 +0530 Subject: [PATCH 0370/1221] Clang formatting changes --- lib_com/gs_bitallocation_ivas_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 71b30ea75..9243f640e 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -2,11 +2,11 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "assert.h" /* Debug prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" -- GitLab From 9ee05fd4391d61c51264202878c5275114fe6fd3 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 11 Mar 2025 15:32:37 +0100 Subject: [PATCH 0371/1221] Fix clang format --- lib_dec/FEC_HQ_core_fx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 4c7e1b0f6..04bd114e1 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -975,7 +975,6 @@ void HQ_FEC_Mem_update_fx( move16(); hHQ_core->old_is_transient[0] = is_transient; move16(); - } return; @@ -2022,7 +2021,7 @@ void save_synthesis_hq_fec_fx( { Copy_Scale_sig( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st->Qprev_synth_buffer_fx ) ); /*Q0*/ } - /* IVAS Floating point code has the commented-out else branch below, but it does not appear to be necessary. To be verified + /* IVAS Floating point code has the commented-out else branch below, but it does not appear to be necessary. To be verified else { mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); -- GitLab From 00f498d4a1ae0d70a519e8e6e72da411f24cddb3 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 11 Mar 2025 16:39:49 +0100 Subject: [PATCH 0372/1221] Revert cleanup of ADD_IVAS_HQ_CODE_FEC --- lib_dec/FEC_HQ_core_fx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 04bd114e1..989f42821 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -725,9 +725,10 @@ void HQ_FEC_Mem_update_fx( move32(); #endif move32(); // tmp_energy_fx - +#ifdef ADD_IVAS_HQ_CODE_FEC IF( EQ_16( output_frame, L_FRAME8k ) ) { +#endif IF( is_transient ) { @@ -758,10 +759,10 @@ void HQ_FEC_Mem_update_fx( } } } - +#ifndef ADD_IVAS_HQ_CODE_FEC IF( EQ_16( output_frame, L_FRAME8k ) ) { - +#endif /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */ test(); IF( ( EQ_16( hqswb_clas, HQ_HVQ ) ) || ( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) ) @@ -975,8 +976,9 @@ void HQ_FEC_Mem_update_fx( move16(); hHQ_core->old_is_transient[0] = is_transient; move16(); +#ifdef ADD_IVAS_HQ_CODE_FEC } - +#endif return; } -- GitLab From a8fcdde081f1bb0882d63d63c957f4f3d579f094 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 11 Mar 2025 13:59:28 -0400 Subject: [PATCH 0373/1221] proposed fix for 1376 --- lib_com/options.h | 1 + lib_enc/enc_pit_exc_fx.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index d03261715..4102e9726 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,4 +172,5 @@ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ +#define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ #endif diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 3ed50017c..7e5734e70 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -578,7 +578,9 @@ void enc_pit_exc_ivas_fx( Word16 use_fcb; Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ +#ifndef FIX_ISSUE_1376 Word16 h1_q15[PIT_EXC_L_SUBFR + ( M + 1 )]; +#endif Word16 q_h1; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; @@ -771,11 +773,15 @@ void enc_pit_exc_ivas_fx( * Codebook target computation * (No LP filtering of the adaptive excitation) *-----------------------------------------------------------------*/ +#ifndef FIX_ISSUE_1376 Copy_Scale_sig( h1, h1_q15, L_subfr, 1 ); // Q14 -> Q15 lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1_q15, xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ - +#else + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1, + xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ +#endif IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); -- GitLab From faf14982b95e2bcf4ed8ff33aadb9cfeee9c857c Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 6 Mar 2025 16:00:04 +0100 Subject: [PATCH 0374/1221] update .gitlab-ci.yaml - remove -p BASOP from instrumentation job and getWmops.sh --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac52a99a7..58547f2ab 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -977,7 +977,7 @@ build-codec-linux-instrumented-make: script: - *print-common-info - *update-scripts-repo - - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP + - bash scripts/prepare_instrumentation.sh -m MEM_ONLY - make -j -C $INSTR_DIR build-codec-linux-debugging-make: @@ -1730,7 +1730,7 @@ voip-be-on-merge-request: stage: test variables: ret_val: 0 - GET_WMOPS_ARGS: "mem_only basop" + GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: - *print-common-info -- GitLab From 68843a329d7d298a5aeef1d8e39170fb1b615e15 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:40:51 +0530 Subject: [PATCH 0375/1221] Fix for 3GPP issue 1344: Decoder segfault for Stereo at 24.4kbps in ivas_fec_noise_filling_fx() Link #1344 --- lib_dec/FEC_HQ_phase_ecu_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index dd63b6508..34d01d7fe 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -4595,11 +4595,11 @@ static void ivas_fec_noise_filling_fx( { L_tmp = L_mult( *sinq_tab, *sinq_tab ); /*Q30 */ sinq_tab++; - q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ - q1 = round_fx( L_tmp ); /*Q15 */ - L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ - L_tmp = L_mac( L_tmp, shr( *pt6++, Q_old_out ), q2 ); /*Qsynth+16 */ - ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ + q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ + q1 = round_fx( L_tmp ); /*Q15 */ + L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ + L_tmp = L_add( L_tmp, L_shr( Mpy_32_16_1( L_deposit_h( *pt6++ ), q2 ), Q_old_out ) ); /*Qsynth+16 */ + ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ move16(); } -- GitLab From 723e7ccd6e5bff12d5486ca4a22b4dd38cbd5096 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:36:41 +0530 Subject: [PATCH 0376/1221] Fix for 3GPP issue 1346: Decoder crash for Stereo at 24.4kbps JBM decoding in ivas_hq_core_dec_fx() Link #1346 --- lib_com/lerp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/lerp.c b/lib_com/lerp.c index bb33d9922..28719205a 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -430,7 +430,7 @@ static void lerp_proc32( Word32 *f /*Qx*/, Word32 *f_out /*Qx*/, Word16 bufferNe { diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/ } - *ptr++ = L_add_sat( f[idx], Mpy_32_16_1( L_sub( f[idx + 1], f[idx] ), diff ) ); /*Qx*/ + *ptr++ = L_add_sat( f[idx], L_sub( Mpy_32_16_1( f[idx + 1], diff ), Mpy_32_16_1( f[idx], diff ) ) ); /*Qx*/ move32(); pos = L_add( pos, shift ); /*Q16*/ idx = extract_h( pos ); -- GitLab From 89e55c686bea6575c8cf32d17c8b18f4a4366c39 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 6 Mar 2025 18:44:47 +0530 Subject: [PATCH 0377/1221] Fix for 3GPP issue 1307: Missing signal in BASOP enc-dec path compared to float enc-dec path using selection test MASA at 24.4 kbps with DTX enabled Link #1307 --- lib_enc/nois_est_fx.c | 37 ++++++++++++++++++++----------------- lib_enc/stat_enc.h | 3 +++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 68eed3d65..0851e4c17 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -326,6 +326,10 @@ void noise_est_init_ivas_fx( hNoiseEst->Etot_sq_st_est_fx = 1600; /* 400 in Q2 */ move16(); move16(); + hNoiseEst->L_Etot_st_est_fx = 167772160; /* 20.0f in Q23 */ + hNoiseEst->L_Etot_sq_st_est_fx = 26214400; /* 400 in Q16 */ + move32(); + move32(); hNoiseEst->epsP_0_2_lp_fx = 4096; /*1.0 Q12*/ move16(); hNoiseEst->epsP_0_2_ad_lp_fx = 0; @@ -2195,9 +2199,9 @@ void noise_est_ivas_fx( Word16 vad_bwidth_fx; /* vad ns control variabel for input bwidth from teh BWD */ /* for DTX operation */ - Word16 lim_Etot_fx; /* Q8 */ - Word16 lim_Etot_sq_fx; /* Q2 */ - Word16 st_E_var_est_fx; /* Q2 */ + Word16 lim_Etot_fx; /* Q8 */ + Word32 lim_Etot_sq_fx; /* Q16 */ + Word32 st_E_var_est_fx; NOISE_EST_HANDLE hNoiseEst; SP_MUS_CLAS_HANDLE hSpMusClas; Word32 Le_min_scaled; @@ -2720,32 +2724,31 @@ void noise_est_ivas_fx( Lnon_sta2 = L_deposit_l( 1024 ); /* 1.0 in Q10 */ } - lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ - lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ + lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ + lim_Etot_sq_fx = L_mult0( lim_Etot_fx, lim_Etot_fx ); /* Q16 */ IF( LT_16( ini_frame, 150 ) ) { /* Allow use of quicker filter during init - if needed */ /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ - hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); // Q8 - move16(); + hNoiseEst->L_Etot_st_est_fx = Madd_32_16_r( L_mult0( 8192, lim_Etot_fx ), hNoiseEst->L_Etot_st_est_fx, 24576 ); // Q23 + move32(); /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ - hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); // Q2 - move16(); + hNoiseEst->L_Etot_sq_st_est_fx = Madd_32_16_r( Mult_32_16( lim_Etot_sq_fx, 8192 ), hNoiseEst->L_Etot_sq_st_est_fx, 24576 ); // Q16 + move32(); } ELSE { /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ - hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); // Q8 - move16(); + hNoiseEst->L_Etot_st_est_fx = Madd_32_16_r( L_mult0( 8192, lim_Etot_fx ), hNoiseEst->L_Etot_st_est_fx, 24576 ); // Q23 + move32(); /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ - hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); // Q2 - move16(); + hNoiseEst->L_Etot_sq_st_est_fx = Madd_32_16_r( Mult_32_16( lim_Etot_sq_fx, 8192 ), hNoiseEst->L_Etot_sq_st_est_fx, 24576 ); // Q16 + move32(); } - st_E_var_est_fx = sub( hNoiseEst->Etot_sq_st_est_fx, extract_h( L_shl_r( L_mult( hNoiseEst->Etot_st_est_fx, hNoiseEst->Etot_st_est_fx ), 1 ) ) ); // Q2 - - + Word16 exp_tmp; + st_E_var_est_fx = BASOP_Util_Add_Mant32Exp( hNoiseEst->L_Etot_sq_st_est_fx, Q15, L_negate( Mpy_32_32( hNoiseEst->L_Etot_st_est_fx, hNoiseEst->L_Etot_st_est_fx ) ), Q16, &exp_tmp ); // exp(exp_tmp) /*-----------------------------------------------------------------* * Count frames since last correlation or harmonic event *-----------------------------------------------------------------*/ @@ -2775,7 +2778,7 @@ void noise_est_ivas_fx( } test(); test(); - IF( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 /* 30.0f in Q8 */ ) && GT_16( st_E_var_est_fx, 32 /* 8.0f in Q2 */ ) ) + IF( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 /* 30.0f in Q8 */ ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( st_E_var_est_fx, exp_tmp, 524288 /* 8.0f in Q16 */, Q15 ), 1 ) ) { /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ *st_harm_cor_cnt = s_max( 1, shr( add( *st_harm_cor_cnt, 2 ), 2 ) ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 6fd9ce6f3..ad572d2ba 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -566,6 +566,9 @@ typedef struct noise_estimation_structure Word16 Etot_st_est_fx; /* Q8 Noise estimation - short term estimate of E{ Etot } */ Word16 Etot_sq_st_est_fx; /* Q2 Noise estimation - short term estimate of E{ Etot^2 } */ + Word32 L_Etot_st_est_fx; /* Q23 Noise estimation - short term estimate of E{ Etot } */ + Word32 L_Etot_sq_st_est_fx; /* Q16 Noise estimation - short term estimate of E{ Etot^2 } */ + Word16 aEn_inac_cnt; } NOISE_EST_DATA, *NOISE_EST_HANDLE; -- GitLab From e0b75f08f9eeed3a08ce3d092079cba9034e7f06 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 07:28:01 +0530 Subject: [PATCH 0378/1221] Clean up of prot.h file --- Workspace_msvc/lib_com.vcxproj | 3 - Workspace_msvc/lib_com.vcxproj.filters | 9 - lib_com/ari_hm_fx.c | 1 - lib_com/arith_coder_fx.c | 1 - lib_com/basop_tcx_utils.c | 2 +- lib_com/bitalloc_fx.c | 1 - lib_com/bitstream.c | 3 +- lib_com/cldfb.c | 1 - lib_com/cng_exc.c | 57 - lib_com/codec_tcx_common.c | 1 - lib_com/core_com_config.c | 60 +- lib_com/deemph.c | 3 +- lib_com/delay_comp.c | 3 +- lib_com/disclaimer.c | 2 +- lib_com/enr_1_az.c | 3 +- lib_com/env_adj.c | 3 +- lib_com/env_stab.c | 3 +- lib_com/env_stab_trans.c | 3 +- lib_com/fd_cng_com_fx.c | 1 - lib_com/fft.c | 2 +- lib_com/fft_fx.c | 2 +- lib_com/fft_rel.c | 3 +- lib_com/fill_spectrum.c | 3 +- lib_com/findpulse.c | 3 +- lib_com/float_to_fix_ops.c | 1 - lib_com/frame_ener_fx.c | 3 +- lib_com/get_gain_fx.c | 3 +- lib_com/gs_bitallocation_ivas_fx.c | 1 - lib_com/gs_gains.c | 1 - lib_com/gs_preech_fx.c | 3 +- lib_com/hp50_fx.c | 3 +- lib_com/hq2_core_com.c | 2 +- lib_com/hq_conf.c | 3 +- lib_com/hq_tools_fx.c | 1 - lib_com/ifft_rel.c | 3 +- lib_com/int_lsp.c | 3 +- lib_com/interleave_spectrum.c | 3 +- lib_com/interpol.c | 3 +- lib_com/ivas_agc_com_fx.c | 2 +- lib_com/ivas_arith_fx.c | 3 +- lib_com/ivas_avq_pos_reorder_com_fx.c | 2 +- lib_com/ivas_cov_smooth_fx.c | 1 - lib_com/ivas_dirac_com_fx.c | 3 +- lib_com/ivas_entropy_coder_common_fx.c | 2 +- lib_com/ivas_fb_mixer_fx.c | 3 +- lib_com/ivas_ism_com_fx.c | 3 +- lib_com/ivas_lfe_com_fx.c | 2 +- lib_com/ivas_masa_com_fx.c | 3 +- lib_com/ivas_mc_com_fx.c | 2 +- lib_com/ivas_mc_param_com_fx.c | 1 - lib_com/ivas_mct_com_fx.c | 2 +- lib_com/ivas_mdct_core_com_fx.c | 3 +- lib_com/ivas_mdft_imdft_fx.c | 3 +- lib_com/ivas_omasa_com_fx.c | 3 +- lib_com/ivas_pca_tools_fx.c | 1 - lib_com/ivas_qmetadata_com_fx.c | 3 +- lib_com/ivas_qspherical_com_fx.c | 4 +- lib_com/ivas_sba_config_fx.c | 2 +- lib_com/ivas_sns_com_fx.c | 1 - lib_com/ivas_spar_com_fx.c | 1 - lib_com/ivas_spar_com_quant_util_fx.c | 1 - lib_com/ivas_stereo_dft_com_fx.c | 2 +- lib_com/ivas_stereo_eclvq_com_fx.c | 2 +- lib_com/ivas_stereo_ica_com_fx.c | 1 - lib_com/ivas_stereo_mdct_bands_com_fx.c | 3 +- lib_com/ivas_stereo_psychlpc_com_fx.c | 2 +- lib_com/ivas_stereo_td_bit_alloc_fx.c | 3 +- lib_com/ivas_tools_fx.c | 3 +- lib_com/ivas_transient_det_fx.c | 3 +- lib_com/lag_wind.c | 1 - lib_com/lerp.c | 129 - lib_com/limit_t0.c | 231 - lib_com/longarith.c | 3 +- lib_com/lsp_conv_poly_fx.c | 3 +- lib_com/modif_fs.c | 3 +- lib_com/mslvq_com.c | 3 +- lib_com/mslvq_com_fx.c | 1 - lib_com/preemph.c | 2 +- lib_com/prot.h | 8340 ----------------- lib_com/prot_fx.h | 793 +- lib_com/pvq_com_fx.c | 1 - lib_com/residu_fx.c | 1 - lib_com/rom_com.c | 3 +- lib_com/rom_com_fx.c | 2 +- lib_com/swb_tbe_com.c | 1 - lib_com/swb_tbe_com_fx.c | 1 - lib_com/tcx_mdct_window.c | 1 - lib_com/tcx_utils_fx.c | 1 - lib_com/tns_base.c | 1 - lib_com/tools.c | 1199 +-- lib_com/tools_fx.c | 1 - lib_com/wtda.c | 3 +- lib_dec/acelp_core_dec_ivas_fx.c | 1 - lib_dec/acelp_core_switch_dec_fx.c | 1 - lib_dec/ari_hm_dec.c | 3 +- lib_dec/arith_coder_dec_fx.c | 1 - lib_dec/avq_dec_fx.c | 1 - lib_dec/cng_dec_fx.c | 1 - lib_dec/core_dec_init_fx.c | 1 - lib_dec/core_dec_switch_fx.c | 1 - lib_dec/dec_tcx_fx.c | 1 - lib_dec/gs_dec_fx.c | 1 - lib_dec/hf_synth_fx.c | 1 - lib_dec/hq_core_dec_fx.c | 1 - lib_dec/igf_dec_fx.c | 3 +- lib_dec/init_dec_fx.c | 1 - lib_dec/ivas_agc_dec_fx.c | 1 - lib_dec/ivas_binRenderer_internal_fx.c | 3 +- lib_dec/ivas_core_dec_fx.c | 3 +- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 1 - lib_dec/ivas_cpe_dec_fx.c | 3 +- lib_dec/ivas_decision_matrix_dec_fx.c | 3 +- lib_dec/ivas_dirac_dec_fx.c | 3 +- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 3 +- lib_dec/ivas_entropy_decoder_fx.c | 3 +- lib_dec/ivas_init_dec.c | 3 +- lib_dec/ivas_ism_dec_fx.c | 3 +- lib_dec/ivas_ism_dtx_dec_fx.c | 3 +- lib_dec/ivas_ism_metadata_dec_fx.c | 1 - lib_dec/ivas_ism_param_dec_fx.c | 3 +- lib_dec/ivas_ism_renderer_fx.c | 1 - lib_dec/ivas_jbm_dec_fx.c | 3 +- lib_dec/ivas_lfe_dec_fx.c | 1 - lib_dec/ivas_lfe_plc_fx.c | 1 - lib_dec/ivas_ls_custom_dec_fx.c | 3 +- lib_dec/ivas_masa_dec_fx.c | 1 - lib_dec/ivas_mc_param_dec_fx.c | 3 +- lib_dec/ivas_mc_paramupmix_dec_fx.c | 1 - lib_dec/ivas_mcmasa_dec_fx.c | 2 +- lib_dec/ivas_mct_core_dec_fx.c | 3 +- lib_dec/ivas_mct_dec_fx.c | 1 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 3 +- lib_dec/ivas_mdct_core_dec_fx.c | 3 +- lib_dec/ivas_mono_dmx_renderer_fx.c | 1 - lib_dec/ivas_objectRenderer_internal_fx.c | 3 +- lib_dec/ivas_omasa_dec_fx.c | 3 +- lib_dec/ivas_osba_dec_fx.c | 3 +- lib_dec/ivas_out_setup_conversion_fx.c | 3 +- lib_dec/ivas_pca_dec_fx.c | 3 +- lib_dec/ivas_post_proc_fx.c | 1 - lib_dec/ivas_qmetadata_dec_fx.c | 3 +- lib_dec/ivas_qspherical_dec_fx.c | 2 +- lib_dec/ivas_range_uni_dec_fx.c | 3 +- lib_dec/ivas_sba_dec_fx.c | 3 +- lib_dec/ivas_sba_rendering_internal_fx.c | 3 +- lib_dec/ivas_sce_dec_fx.c | 1 - lib_dec/ivas_sns_dec_fx.c | 3 +- lib_dec/ivas_spar_decoder_fx.c | 3 +- lib_dec/ivas_spar_md_dec_fx.c | 3 +- lib_dec/ivas_stereo_adapt_GR_dec_fx.c | 3 +- lib_dec/ivas_stereo_cng_dec.c | 3 +- lib_dec/ivas_stereo_dft_dec.c | 1 - lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 3 +- lib_dec/ivas_stereo_dft_dec_fx.c | 1 - lib_dec/ivas_stereo_dft_plc_fx.c | 1 - lib_dec/ivas_stereo_eclvq_dec_fx.c | 2 +- lib_dec/ivas_stereo_ica_dec_fx.c | 3 +- lib_dec/ivas_stereo_icbwe_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_core_dec_fx.c | 3 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 3 +- lib_dec/ivas_stereo_switching_dec_fx.c | 3 +- lib_dec/ivas_stereo_td_dec_fx.c | 1 - lib_dec/ivas_svd_dec_fx.c | 3 +- lib_dec/ivas_tcx_core_dec_fx.c | 3 +- lib_dec/ivas_td_low_rate_dec_fx.c | 1 - lib_dec/jbm_jb4_circularbuffer.c | 2 +- lib_dec/jbm_jb4_circularbuffer.h | 2 +- lib_dec/jbm_jb4_inputbuffer.c | 2 +- lib_dec/jbm_jb4_jmf.c | 2 +- lib_dec/jbm_jb4sb.c | 1 - lib_dec/jbm_pcmdsp_apa.c | 3 +- lib_dec/lib_dec_fx.c | 5 +- lib_dec/swb_tbe_dec_fx.c | 1 - lib_dec/tonalMDCTconcealment_fx.c | 1 - lib_enc/ACcontextMapping_enc_fx.c | 1 - lib_enc/FEC_enc_fx.c | 1 - lib_enc/SNR_calc_fx.c | 1 - lib_enc/acelp_core_enc_fx.c | 1 - lib_enc/acelp_core_switch_enc_fx.c | 1 - lib_enc/ari_hm_enc_fx.c | 4 +- lib_enc/avq_cod_fx.c | 4 +- lib_enc/cng_enc_fx.c | 10 +- lib_enc/cod2t32_fx.c | 1 - lib_enc/cod4t64_fast.c | 1 - lib_enc/cod4t64_fx.c | 3 +- lib_enc/cod_tcx_fx.c | 2 - lib_enc/core_enc_init_fx.c | 1 - lib_enc/core_enc_switch_fx.c | 5 +- lib_enc/dtx_fx.c | 1 - lib_enc/enc_gen_voic_fx.c | 3 +- lib_enc/enc_higher_acelp_fx.c | 3 +- lib_enc/enc_pit_exc_fx.c | 1 - lib_enc/enc_prm_fx.c | 3 +- lib_enc/enc_tran_fx.c | 1 - lib_enc/enc_uv_fx.c | 3 +- lib_enc/eval_pit_contr_fx.c | 1 - lib_enc/evs_enc_fx.c | 3 +- lib_enc/fd_cng_enc_fx.c | 1 - lib_enc/find_wsp_fx.c | 3 +- lib_enc/gain_enc_fx.c | 1 - lib_enc/gaus_enc_fx.c | 1 - lib_enc/gs_enc_fx.c | 2 - lib_enc/hq_classifier_enc_fx.c | 1 - lib_enc/hq_core_enc_fx.c | 10 +- lib_enc/hq_env_enc_fx.c | 1 - lib_enc/hq_hr_enc_fx.c | 1 - lib_enc/hq_lr_enc_fx.c | 1 - lib_enc/hvq_enc_fx.c | 1 - lib_enc/igf_enc.c | 38 +- lib_enc/igf_enc_fx.c | 3 +- lib_enc/igf_scf_enc.c | 3 +- lib_enc/init_enc_fx.c | 1 - lib_enc/inov_enc_fx.c | 1 - lib_enc/ivas_agc_enc_fx.c | 3 +- lib_enc/ivas_core_enc_fx.c | 3 +- lib_enc/ivas_core_pre_proc_front_fx.c | 2 - lib_enc/ivas_core_pre_proc_fx.c | 3 +- lib_enc/ivas_corecoder_enc_reconfig_fx.c | 1 - lib_enc/ivas_cpe_enc_fx.c | 3 +- lib_enc/ivas_decision_matrix_enc_fx.c | 3 +- lib_enc/ivas_dirac_enc_fx.c | 1 - lib_enc/ivas_enc_cov_handler_fx.c | 3 +- lib_enc/ivas_enc_fx.c | 3 +- lib_enc/ivas_entropy_coder_fx.c | 1 - lib_enc/ivas_front_vad_fx.c | 3 +- lib_enc/ivas_init_enc_fx.c | 3 +- lib_enc/ivas_ism_dtx_enc_fx.c | 3 +- lib_enc/ivas_ism_enc_fx.c | 3 +- lib_enc/ivas_ism_metadata_enc_fx.c | 3 +- lib_enc/ivas_ism_param_enc_fx.c | 1 - lib_enc/ivas_lfe_enc_fx.c | 3 +- lib_enc/ivas_masa_enc_fx.c | 1 - lib_enc/ivas_mc_param_enc_fx.c | 2 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 3 +- lib_enc/ivas_mcmasa_enc_fx.c | 1 - lib_enc/ivas_mct_core_enc_fx.c | 4 +- lib_enc/ivas_mct_enc_fx.c | 3 +- lib_enc/ivas_mct_enc_mct_fx.c | 1 - lib_enc/ivas_mdct_core_enc_fx.c | 3 +- lib_enc/ivas_omasa_enc_fx.c | 1 - lib_enc/ivas_osba_enc_fx.c | 3 +- lib_enc/ivas_pca_enc_fx.c | 3 +- lib_enc/ivas_qmetadata_enc_fx.c | 4 +- lib_enc/ivas_qspherical_enc_fx.c | 1 - lib_enc/ivas_range_uni_enc_fx.c | 2 +- lib_enc/ivas_sba_enc_fx.c | 3 +- lib_enc/ivas_sce_enc_fx.c | 1 - lib_enc/ivas_sns_enc_fx.c | 3 +- lib_enc/ivas_spar_encoder_fx.c | 1 - lib_enc/ivas_spar_md_enc_fx.c | 2 - lib_enc/ivas_stereo_adapt_GR_enc_fx.c | 2 +- lib_enc/ivas_stereo_classifier_fx.c | 3 +- lib_enc/ivas_stereo_cng_enc_fx.c | 3 +- lib_enc/ivas_stereo_dft_enc_fx.c | 3 +- lib_enc/ivas_stereo_dft_enc_itd_fx.c | 1 - lib_enc/ivas_stereo_dft_td_itd_fx.c | 3 +- lib_enc/ivas_stereo_dmx_evs_fx.c | 2 - lib_enc/ivas_stereo_eclvq_enc_fx.c | 1 - lib_enc/ivas_stereo_ica_enc_fx.c | 3 +- lib_enc/ivas_stereo_icbwe_enc_fx.c | 3 +- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_igf_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 1 - lib_enc/ivas_stereo_switching_enc_fx.c | 3 +- lib_enc/ivas_stereo_td_analysis_fx.c | 3 +- lib_enc/ivas_stereo_td_enc_fx.c | 3 +- lib_enc/ivas_tcx_core_enc_fx.c | 3 +- lib_enc/ivas_td_low_rate_enc_fx.c | 1 - lib_enc/lib_enc.c | 1 - lib_enc/lsf_enc_fx.c | 1 - lib_enc/lsf_msvq_ma_enc.c | 1 - lib_enc/mdct_classifier_fx.c | 1 - lib_enc/mslvq_enc_fx.c | 3 +- lib_enc/nelp_enc_fx.c | 1 - lib_enc/peak_vq_enc_fx.c | 1 - lib_enc/pit_enc_fx.c | 1 - lib_enc/range_enc_fx.c | 1 - lib_enc/speech_music_classif_fx.c | 1 - lib_enc/stat_noise_uv_enc_fx.c | 1 - lib_enc/swb_bwe_enc_fx.c | 3 +- lib_enc/swb_bwe_enc_lr_fx.c | 1 - lib_enc/swb_tbe_enc.c | 46 - lib_enc/swb_tbe_enc_fx.c | 1 - lib_enc/tcq_core_enc_fx.c | 1 - lib_enc/tns_base_enc_fx.c | 1 - lib_enc/transition_enc_fx.c | 1 - lib_rend/ivas_allrad_dec_fx.c | 2 +- lib_rend/ivas_crend_fx.c | 3 +- lib_rend/ivas_dirac_ana_fx.c | 3 +- .../ivas_dirac_dec_binaural_functions_fx.c | 1 - lib_rend/ivas_dirac_decorr_dec_fx.c | 3 +- lib_rend/ivas_dirac_onsets_dec_fx.c | 3 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 3 +- lib_rend/ivas_dirac_rend_fx.c | 3 +- lib_rend/ivas_efap_fx.c | 1 - lib_rend/ivas_hrtf_fx.c | 2 +- lib_rend/ivas_limiter_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 3 +- lib_rend/ivas_mcmasa_ana_fx.c | 3 +- lib_rend/ivas_objectRenderer_fx.c | 3 +- lib_rend/ivas_objectRenderer_hrFilt_fx.c | 3 +- lib_rend/ivas_objectRenderer_mix_fx.c | 3 +- lib_rend/ivas_objectRenderer_sfx_fx.c | 3 +- lib_rend/ivas_objectRenderer_sources_fx.c | 3 +- lib_rend/ivas_objectRenderer_vec_fx.c | 3 +- lib_rend/ivas_omasa_ana_fx.c | 3 +- lib_rend/ivas_output_init.c | 2 +- lib_rend/ivas_reflections_fx.c | 3 +- lib_rend/ivas_render_config_fx.c | 3 +- lib_rend/ivas_reverb_delay_line_fx.c | 3 +- lib_rend/ivas_reverb_fft_filter_fx.c | 3 +- lib_rend/ivas_reverb_filter_design_fx.c | 1 - lib_rend/ivas_reverb_fx.c | 3 +- lib_rend/ivas_reverb_iir_filter_fx.c | 3 +- lib_rend/ivas_reverb_utils_fx.c | 3 +- lib_rend/ivas_rotation_fx.c | 3 +- lib_rend/ivas_sba_rendering_fx.c | 1 - lib_rend/ivas_shoebox_fx.c | 1 - lib_rend/ivas_td_decorr_fx.c | 1 - lib_rend/ivas_vbap_fx.c | 3 +- lib_rend/lib_rend.c | 1 - lib_util/hrtf_file_reader.c | 3 +- lib_util/ls_custom_file_reader.c | 2 +- lib_util/mime_io.c | 2 +- lib_util/render_config_reader.c | 2 +- lib_util/rotation_file_reader.c | 1 - lib_util/vector3_pair_file_reader.c | 1 - 327 files changed, 990 insertions(+), 10601 deletions(-) delete mode 100644 lib_com/cng_exc.c delete mode 100644 lib_com/limit_t0.c delete mode 100644 lib_com/prot.h delete mode 100644 lib_enc/swb_tbe_enc.c diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 8c42f19ca..5b26a2911 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -138,7 +138,6 @@ - @@ -238,7 +237,6 @@ - @@ -324,7 +322,6 @@ - diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 8f2be8853..b9769e3ec 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -304,9 +304,6 @@ common_all_c - - common_all_c - common_all_c @@ -412,9 +409,6 @@ common_all_c - - common_all_c - common_all_c @@ -588,9 +582,6 @@ common_h - - common_h - common_h diff --git a/lib_com/ari_hm_fx.c b/lib_com/ari_hm_fx.c index 076bc8d92..46f8ecea1 100644 --- a/lib_com/ari_hm_fx.c +++ b/lib_com/ari_hm_fx.c @@ -10,7 +10,6 @@ #include "basop_util.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) void UnmapIndex( diff --git a/lib_com/arith_coder_fx.c b/lib_com/arith_coder_fx.c index de22a7cf3..846b4dcea 100644 --- a/lib_com/arith_coder_fx.c +++ b/lib_com/arith_coder_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "prot.h" #include "basop_util.h" #include "basop_proto_func.h" #include "cnst.h" diff --git a/lib_com/basop_tcx_utils.c b/lib_com/basop_tcx_utils.c index 378faae0f..8038c4f91 100644 --- a/lib_com/basop_tcx_utils.c +++ b/lib_com/basop_tcx_utils.c @@ -40,7 +40,7 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stl.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #define WMC_TOOL_SKIP diff --git a/lib_com/bitalloc_fx.c b/lib_com/bitalloc_fx.c index 92a8e3928..30ae2d47b 100644 --- a/lib_com/bitalloc_fx.c +++ b/lib_com/bitalloc_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ void bitalloc_fx( Word16 *y, /* i : reordered norm of sub-vectors Q0 */ diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index e5754fa35..9c0a53f8f 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -38,7 +38,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "stat_dec.h" @@ -1884,7 +1883,7 @@ static void decision_matrix_core_dec( * Set up MDCT core switching if indicated in the bitstream *-------------------------------------------------------------------*/ -void mdct_switching_dec( +void mdct_switching_dec_ivas_fx( Decoder_State *st /* i/o: decoder state structure */ ) { diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 1907ef327..38195b65d 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "stat_dec.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_com_fx.h" diff --git a/lib_com/cng_exc.c b/lib_com/cng_exc.c deleted file mode 100644 index 494305e6f..000000000 --- a/lib_com/cng_exc.c +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - -#define A2 0.2f -#define GAIN_VAR 0.000011f - - -/*-------------------------------------------------------* - * cng_params_upd() - * - * update CNG parameters - *-------------------------------------------------------*/ diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common.c index f6da34b55..1ebc2829c 100644 --- a/lib_com/codec_tcx_common.c +++ b/lib_com/codec_tcx_common.c @@ -6,7 +6,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "rom_basop_util.h" diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index fdf935461..ed72605de 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -38,10 +38,9 @@ #include #include "options.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 @@ -551,63 +550,6 @@ int16_t sr2fscale( return (int16_t) ( ( FSCALE_DENOM * sr_core ) / 12800 ); } -/*-------------------------------------------------------------------* - * getCoreSamplerateMode2_flt() - * - * - *-------------------------------------------------------------------*/ - -int32_t getCoreSamplerateMode2_flt( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ -) -{ - int32_t sr_core = 0; - - if ( bwidth == NB ) - { - sr_core = INT_FS_12k8; - } - else if ( element_mode == EVS_MONO && ( ( bwidth == WB && total_brate < ACELP_13k20 ) || ( bwidth == SWB && total_brate <= ACELP_13k20 ) || ( rf_mode == 1 ) ) ) - { - sr_core = INT_FS_12k8; - } - else if ( element_mode > EVS_MONO && flag_ACELP16k == 0 ) - { - sr_core = INT_FS_12k8; - } - else if ( bwidth == WB || ( bwidth == SWB && total_brate <= ACELP_32k ) || ( bwidth == FB && total_brate <= ACELP_32k ) ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE && element_mode == IVAS_SCE && !is_ism_format ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE_ISM && element_mode == IVAS_SCE && is_ism_format ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE && element_mode == IVAS_SCE && is_ism_format ) - { - sr_core = 25600; - } - else if ( ( ( bwidth == SWB || bwidth == FB ) && element_mode == EVS_MONO && total_brate <= HQ_64k ) || ( element_mode > IVAS_SCE && ( ( bwidth == SWB && total_brate <= IVAS_96k ) || ( bwidth == FB && total_brate <= IVAS_96k ) ) ) ) - { - sr_core = 25600; - } - else if ( bwidth == SWB || bwidth == FB ) - { - sr_core = 32000; - } - - return sr_core; -} - Word32 getCoreSamplerateMode2( const Word16 element_mode, /* i : IVAS element mode Q0*/ const Word32 total_brate, /* i : total bitrate Q0*/ diff --git a/lib_com/deemph.c b/lib_com/deemph.c index b2b43cf72..c03a050bc 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -36,9 +36,8 @@ #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" void deemph_fx_32( diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 9e6c450cd..edccca074 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------------- * get_delay() diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index ba0973f97..1a01c2c32 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -36,7 +36,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_com/enr_1_az.c b/lib_com/enr_1_az.c index 81fb78262..5c99cdfa5 100644 --- a/lib_com/enr_1_az.c +++ b/lib_com/enr_1_az.c @@ -37,9 +37,8 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" Word16 Enr_1_Az_fx_o( /* o : impulse response energy Q3 */ diff --git a/lib_com/env_adj.c b/lib_com/env_adj.c index 18520e188..5a83dbe5f 100644 --- a/lib_com/env_adj.c +++ b/lib_com/env_adj.c @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*--------------------------------------------------------------------------* * env_adj() diff --git a/lib_com/env_stab.c b/lib_com/env_stab.c index b80fd0a8b..a3140b4e4 100644 --- a/lib_com/env_stab.c +++ b/lib_com/env_stab.c @@ -39,11 +39,10 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" #include "stl.h" -#include "prot_fx.h" /*--------------------------------------------------------------------------* * Local constants *--------------------------------------------------------------------------*/ diff --git a/lib_com/env_stab_trans.c b/lib_com/env_stab_trans.c index 8c6ec265f..829bef5f4 100644 --- a/lib_com/env_stab_trans.c +++ b/lib_com/env_stab_trans.c @@ -38,10 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*--------------------------------------------------------------------------* * env_stab_transient_detect() * diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index e04a13fdf..78809ed2c 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot.h" #define FFT_SCALING_512 1073741824 // Q22 #define FFT_SCALING_640 1342177280 // Q22 diff --git a/lib_com/fft.c b/lib_com/fft.c index 352a24be9..e262f3909 100644 --- a/lib_com/fft.c +++ b/lib_com/fft.c @@ -39,7 +39,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index acadbb06b..73ff582df 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -44,7 +44,7 @@ #include "options.h" #include #include "cnst.h" -// #include "prot.h" +// #include "prot_fx.h" #include "prot_fx.h" //#include "cnst_fx.h" #include "rom_com.h" diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c index 839b2faaf..1d020cabd 100644 --- a/lib_com/fft_rel.c +++ b/lib_com/fft_rel.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* * Local constants diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index 12ed75f0a..bd9080a7b 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/findpulse.c b/lib_com/findpulse.c index f2347d5b3..68853e061 100644 --- a/lib_com/findpulse.c +++ b/lib_com/findpulse.c @@ -37,10 +37,9 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*----------------------------------------------------------------------------------* * findpulse() diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 41d90359f..1f7c28fd8 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -3,7 +3,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_com/frame_ener_fx.c b/lib_com/frame_ener_fx.c index 4428c0796..68fdf33c3 100644 --- a/lib_com/frame_ener_fx.c +++ b/lib_com/frame_ener_fx.c @@ -38,9 +38,8 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*----------------------------------------------------------------------------------* * fer_energy() * diff --git a/lib_com/get_gain_fx.c b/lib_com/get_gain_fx.c index d4c2413c3..8ec4f5a40 100644 --- a/lib_com/get_gain_fx.c +++ b/lib_com/get_gain_fx.c @@ -36,9 +36,8 @@ #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*----------------------------------------------------------------------------------* * get_gain() diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index eef3d50c6..0921dc88c 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -5,7 +5,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot.h" /* Function prototypes */ #include "assert.h" /* Debug prototypes */ diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c index 9adb448a4..8fa769475 100644 --- a/lib_com/gs_gains.c +++ b/lib_com/gs_gains.c @@ -39,7 +39,6 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index 2e9e5eb96..3b3eaa777 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -39,9 +39,8 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index 9820eb3c8..f5e7105cf 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -37,9 +37,8 @@ #include #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #define HP20_COEFF_SCALE ( 2 ) diff --git a/lib_com/hq2_core_com.c b/lib_com/hq2_core_com.c index bc4edb869..121dae06a 100644 --- a/lib_com/hq2_core_com.c +++ b/lib_com/hq2_core_com.c @@ -39,7 +39,7 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "basop_proto_func.h" #include "wmc_auto.h" diff --git a/lib_com/hq_conf.c b/lib_com/hq_conf.c index c139a493c..90a256cea 100644 --- a/lib_com/hq_conf.c +++ b/lib_com/hq_conf.c @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" void hq_configure_fx( diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index 4426f85d9..cf3ce202e 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -39,7 +39,6 @@ #include "rom_com.h" /* Static table prototypes FIP version */ #include "stl.h" /* required for wmc_tool */ #include "prot_fx.h" -#include "prot.h" #include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* diff --git a/lib_com/ifft_rel.c b/lib_com/ifft_rel.c index 423eea46d..9e64a4e25 100644 --- a/lib_com/ifft_rel.c +++ b/lib_com/ifft_rel.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-----------------------------------------------------------------* * Local constants *-----------------------------------------------------------------*/ diff --git a/lib_com/int_lsp.c b/lib_com/int_lsp.c index 0f673b8fd..570e9ebd9 100644 --- a/lib_com/int_lsp.c +++ b/lib_com/int_lsp.c @@ -37,10 +37,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" void int_lsp_fx( diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum.c index 745ee6ac3..5c4c98e29 100644 --- a/lib_com/interleave_spectrum.c +++ b/lib_com/interleave_spectrum.c @@ -37,10 +37,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/interpol.c b/lib_com/interpol.c index 45021f1c2..a490a7552 100644 --- a/lib_com/interpol.c +++ b/lib_com/interpol.c @@ -36,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" -#include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_com/ivas_agc_com_fx.c b/lib_com/ivas_agc_com_fx.c index b2c09fa07..94e6b222f 100644 --- a/lib_com/ivas_agc_com_fx.c +++ b/lib_com/ivas_agc_com_fx.c @@ -38,7 +38,7 @@ #include "ivas_prot_fx.h" #include #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" /*------------------------------------------------------------------------------------------* * Local constants diff --git a/lib_com/ivas_arith_fx.c b/lib_com/ivas_arith_fx.c index 2f729bbd4..006a31177 100644 --- a/lib_com/ivas_arith_fx.c +++ b/lib_com/ivas_arith_fx.c @@ -33,9 +33,8 @@ #include #include "options.h" #include "wmc_auto.h" -#include "prot.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_avq_pos_reorder_com_fx.c b/lib_com/ivas_avq_pos_reorder_com_fx.c index ac539b787..25f8be3ad 100644 --- a/lib_com/ivas_avq_pos_reorder_com_fx.c +++ b/lib_com/ivas_avq_pos_reorder_com_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-----------------------------------------------------------------* diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index 445ea8c78..acc0df821 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "ivas_prot.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 557db9696..9b60b2c5c 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -37,10 +37,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_entropy_coder_common_fx.c b/lib_com/ivas_entropy_coder_common_fx.c index d28828d6f..99381d19a 100644 --- a/lib_com/ivas_entropy_coder_common_fx.c +++ b/lib_com/ivas_entropy_coder_common_fx.c @@ -35,7 +35,7 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_fb_mixer_fx.c b/lib_com/ivas_fb_mixer_fx.c index 43f468fb0..883861024 100644 --- a/lib_com/ivas_fb_mixer_fx.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -34,13 +34,12 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index d3f18a795..f1201b06c 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -35,13 +35,12 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_com/ivas_lfe_com_fx.c b/lib_com/ivas_lfe_com_fx.c index 4d993d64f..7464c41c2 100644 --- a/lib_com/ivas_lfe_com_fx.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -34,7 +34,7 @@ #include "math.h" #include "options.h" #include "ivas_stat_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_masa_com_fx.c b/lib_com/ivas_masa_com_fx.c index 35db926d0..fbe752aad 100644 --- a/lib_com/ivas_masa_com_fx.c +++ b/lib_com/ivas_masa_com_fx.c @@ -34,14 +34,13 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_rom_com_fx.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_com_fx.c b/lib_com/ivas_mc_com_fx.c index 88d6c1b5e..62d623b83 100644 --- a/lib_com/ivas_mc_com_fx.c +++ b/lib_com/ivas_mc_com_fx.c @@ -34,7 +34,7 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_param_com_fx.c b/lib_com/ivas_mc_param_com_fx.c index d69da849a..a54abe7ab 100644 --- a/lib_com/ivas_mc_param_com_fx.c +++ b/lib_com/ivas_mc_param_com_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_com.h" diff --git a/lib_com/ivas_mct_com_fx.c b/lib_com/ivas_mct_com_fx.c index b220d69a7..1f3c58153 100644 --- a/lib_com/ivas_mct_com_fx.c +++ b/lib_com/ivas_mct_com_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com_fx.c b/lib_com/ivas_mdct_core_com_fx.c index a5cfb8673..000f3992f 100644 --- a/lib_com/ivas_mdct_core_com_fx.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -34,9 +34,8 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* diff --git a/lib_com/ivas_mdft_imdft_fx.c b/lib_com/ivas_mdft_imdft_fx.c index 0f24fba81..b10444307 100644 --- a/lib_com/ivas_mdft_imdft_fx.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -33,14 +33,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" #include #include -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_omasa_com_fx.c b/lib_com/ivas_omasa_com_fx.c index eb230b224..ef6350285 100644 --- a/lib_com/ivas_omasa_com_fx.c +++ b/lib_com/ivas_omasa_com_fx.c @@ -35,11 +35,10 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "rom_com.h" #include -#include "prot_fx.h" /*--------------------------------------------------------------- * Local constants diff --git a/lib_com/ivas_pca_tools_fx.c b/lib_com/ivas_pca_tools_fx.c index 5689e81c0..1e36c5e8e 100644 --- a/lib_com/ivas_pca_tools_fx.c +++ b/lib_com/ivas_pca_tools_fx.c @@ -38,7 +38,6 @@ #include #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index cbc67de00..79a585e8b 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -37,10 +37,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 8ef48be2e..5caa850cb 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -37,12 +37,10 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_sba_config_fx.c b/lib_com/ivas_sba_config_fx.c index 94ceb8e3c..38785956c 100644 --- a/lib_com/ivas_sba_config_fx.c +++ b/lib_com/ivas_sba_config_fx.c @@ -37,7 +37,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index 788fb3c56..f35de8eb0 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 0ebae0de6..fc6e60310 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "basop_util.h" #include "ivas_stat_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" diff --git a/lib_com/ivas_spar_com_quant_util_fx.c b/lib_com/ivas_spar_com_quant_util_fx.c index 0f0e003dd..8292de5c1 100644 --- a/lib_com/ivas_spar_com_quant_util_fx.c +++ b/lib_com/ivas_spar_com_quant_util_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "math.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_stereo_dft_com_fx.c b/lib_com/ivas_stereo_dft_com_fx.c index 1157fffcf..80e64c0cc 100644 --- a/lib_com/ivas_stereo_dft_com_fx.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -36,7 +36,7 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c index b4fb66429..d0ffff39c 100644 --- a/lib_com/ivas_stereo_eclvq_com_fx.c +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -37,7 +37,7 @@ #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*--------------------------------------------------------------- diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index 78a3c90ca..9aa880842 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_mdct_bands_com_fx.c b/lib_com/ivas_stereo_mdct_bands_com_fx.c index b1750fd16..c21abcf8c 100644 --- a/lib_com/ivas_stereo_mdct_bands_com_fx.c +++ b/lib_com/ivas_stereo_mdct_bands_com_fx.c @@ -37,9 +37,8 @@ #include "ivas_rom_com.h" #include "ivas_prot.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_com/ivas_stereo_psychlpc_com_fx.c b/lib_com/ivas_stereo_psychlpc_com_fx.c index 996b262db..cb3c39df2 100644 --- a/lib_com/ivas_stereo_psychlpc_com_fx.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "ivas_rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_stereo_td_bit_alloc_fx.c b/lib_com/ivas_stereo_td_bit_alloc_fx.c index 14ab8131e..9074473d7 100644 --- a/lib_com/ivas_stereo_td_bit_alloc_fx.c +++ b/lib_com/ivas_stereo_td_bit_alloc_fx.c @@ -38,9 +38,8 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index 9cd1a063e..e460637f7 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -34,11 +34,10 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define ANGLE_90_DEG_Q22 377487360 diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index b5ea507eb..97025b46f 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -34,11 +34,10 @@ #include "options.h" #include "math.h" #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_stat_com.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind.c index e0871fa70..9fb287271 100644 --- a/lib_com/lag_wind.c +++ b/lib_com/lag_wind.c @@ -37,7 +37,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/lerp.c b/lib_com/lerp.c index 28719205a..4e306b936 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -36,154 +36,25 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" - /*-------------------------------------------------------------* * Local function prototypes *-------------------------------------------------------------*/ -static void lerp_proc_flt( const float *f, float *f_out, const int16_t bufferNewSize, const int16_t bufferOldSize ); - - /*-------------------------------------------------------------* * procedure lerp_flt() * * * * * *-------------------------------------------------------------*/ -void lerp_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize_inp ) -{ - float maxFac; - int16_t bufferOldSize, tmpNewSize; - - maxFac = 507.0 / 128.0; - bufferOldSize = bufferOldSize_inp; - - if ( (float) bufferNewSize / bufferOldSize > maxFac ) - { - tmpNewSize = bufferOldSize * 2; - while ( bufferNewSize > bufferOldSize ) - { - if ( (float) bufferNewSize / bufferOldSize <= maxFac ) - { - tmpNewSize = bufferNewSize; - } - - lerp_proc_flt( f, f_out, tmpNewSize, bufferOldSize ); - - f = f_out; - bufferOldSize = tmpNewSize; - tmpNewSize *= 2; - } - } - else if ( (float) bufferOldSize / bufferNewSize > maxFac ) - { - tmpNewSize = bufferOldSize / 2; - while ( bufferNewSize < bufferOldSize ) - { - if ( (float) bufferOldSize / bufferNewSize <= maxFac ) - { - tmpNewSize = bufferNewSize; - } - - lerp_proc_flt( f, f_out, tmpNewSize, bufferOldSize ); - - f = f_out; - bufferOldSize = tmpNewSize; - tmpNewSize /= 2; - } - } - else - { - lerp_proc_flt( f, f_out, bufferNewSize, bufferOldSize ); - } - - return; -} - /*-------------------------------------------------------------* * procedure lerp_proc_flt() * * * * * *-------------------------------------------------------------*/ -static void lerp_proc_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize ) -{ - int16_t i, idx; - float pos, shift, diff; - float buf[2 * L_FRAME_MAX]; - Word16 tmp; - - if ( bufferNewSize == bufferOldSize ) - { - mvr2r( f, buf, bufferNewSize ); - mvr2r( buf, f_out, bufferNewSize ); - return; - } - - /* Using the basop code to avoid reading beyond end of input for bufferOldSize=320, bufferNewSize=640 */ - tmp = div_s( bufferOldSize, shl( bufferNewSize, 4 ) ); - shift = (float) ( L_shl( L_deposit_l( tmp ), 4 - 15 + 16 ) ) / 65536.0f; - pos = 0.5f * shift - 0.5f; - - if ( shift < 0.3f ) - { - pos = pos - 0.13f; - } - - /* first point of interpolation */ - if ( pos < 0 ) - { - buf[0] = f[0] + pos * ( f[1] - f[0] ); - } - else - { - idx = (int16_t) pos; - diff = pos - idx; - buf[0] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - } - - pos += shift; - - for ( i = 1; i < bufferNewSize - 1; i++ ) - { - idx = (int16_t) pos; - diff = pos - idx; - - buf[i] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - pos += shift; - } - - - /* last point */ - idx = (int16_t) pos; - - if ( pos > bufferOldSize - 1 ) - { - idx = bufferOldSize - 2; - } - - diff = pos - idx; - - buf[bufferNewSize - 1] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - - mvr2r( buf, f_out, bufferNewSize ); - - return; -} - - /*-------------------------------------------------------------* * Local constants *-------------------------------------------------------------*/ diff --git a/lib_com/limit_t0.c b/lib_com/limit_t0.c deleted file mode 100644 index d49cad283..000000000 --- a/lib_com/limit_t0.c +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------* - * Local constants - *-------------------------------------------------*/ - -#define LIMIT_PIT_REL_LOWER 2 /* delta interval to extend pitch coding in relative Q */ -#define LIMIT_PIT_REL_UPPER 0 - -/*-------------------------------------------------* - * limit_T0() - * - * Close-loop pitch lag search limitation - *-------------------------------------------------*/ - -void limit_T0( - const int16_t L_frame, /* i : length of the frame */ - const int16_t delta, /* i : Half the close-loop searched interval */ - const int16_t pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ - const int16_t limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) */ - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_max /* o : higher pitch limit */ -) -{ - int16_t delta2, T1; - int16_t pit_min, pit_max; - - if ( limit_flag == 0 ) /* restrained Q limits */ - { - /* set limits */ - if ( L_frame == L_FRAME ) - { - pit_max = PIT_MAX; - pit_min = PIT_MIN; - } - else /* L_frame == L_FRAME16k */ - { - pit_max = PIT16k_MAX; - pit_min = PIT16k_MIN; - } - - delta2 = 2 * delta - 1; - - T1 = T0; - if ( T0_frac >= 2 ) - { - T1++; - } - *T0_min = T1 - delta; - - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_min = *T0_max - delta2; - } - } - else /* extended Q limits */ - { - - /* set limits */ - if ( L_frame == L_FRAME ) - { - pit_max = PIT_MAX; - pit_min = PIT_MIN_EXTEND; - - if ( limit_flag == 2 ) - { - pit_min = PIT_MIN_DOUBLEEXTEND; - } - } - else /* L_frame == L_FRAME16k */ - { - pit_max = PIT16k_MAX; - pit_min = PIT16k_MIN_EXTEND; - } - - delta2 = 2 * delta - 1; - - T1 = T0; - if ( T0_frac >= 2 ) - { - T1++; - } - *T0_min = T1 - delta; - - if ( pit_flag == 0 ) - { - /* subframes with absolute search: keep Q range */ - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_min = *T0_max - delta2; - } - } - else - { - /* subframes with relative search: extend Q range */ - if ( *T0_min < pit_min - LIMIT_PIT_REL_LOWER ) - { - *T0_min = pit_min - LIMIT_PIT_REL_LOWER; - } - - if ( *T0_min < L_INTERPOL ) - { - *T0_min = L_INTERPOL; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max + LIMIT_PIT_REL_UPPER ) - { - *T0_max = pit_max + LIMIT_PIT_REL_UPPER; - *T0_min = *T0_max - delta2; - } - } - } - - return; -} - - -/*-------------------------------------------------* - * Routine limit_T0_voiced_ivas() - * - * Close-loop pitch lag search limitation - *-------------------------------------------------*/ - -void limit_T0_voiced_ivas( - const int16_t nbits, - const int16_t res, - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - const int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_min_frac, /* o : lower pitch limit */ - int16_t *T0_max, /* o : higher pitch limit */ - int16_t *T0_max_frac, /* o : higher pitch limit */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max /* i : Maximum pitch lag */ -) -{ - int16_t T1, temp1, temp2; - - /* Mid-point */ - T1 = T0; - if ( ( T0_res > 1 ) && ( T0_frac >= ( T0_res >> 1 ) ) ) - { - T1++; - } - - /* Lower-bound */ - temp1 = ( T1 * res ) - ( 1 << ( nbits - 1 ) ); - temp2 = temp1 / res; - *T0_min = temp2; - *T0_min_frac = temp1 - temp2 * res; - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - *T0_min_frac = 0; - } - - /* Higher-bound */ - temp1 = ( *T0_min * res ) + *T0_min_frac + ( 1 << nbits ) - 1; - temp2 = temp1 / res; - *T0_max = temp2; - *T0_max_frac = temp1 - temp2 * res; - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_max_frac = res - 1; - temp1 = ( *T0_max * res ) + *T0_max_frac - ( 1 << nbits ) + 1; - temp2 = temp1 / res; - *T0_min = temp2; - *T0_min_frac = temp1 - temp2 * res; - } - - return; -} diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 66c5dd15e..8946e41aa 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -37,10 +37,9 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_com/lsp_conv_poly_fx.c b/lib_com/lsp_conv_poly_fx.c index 61ead2bf2..4f493cacd 100644 --- a/lib_com/lsp_conv_poly_fx.c +++ b/lib_com/lsp_conv_poly_fx.c @@ -6,10 +6,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index 1b2836252..7ed3cb59b 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -38,10 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" void Interpolate_allpass_steep_32( diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 34e2083b9..a15b11611 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -38,10 +38,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index d97830a5f..10e560433 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "stl.h" diff --git a/lib_com/preemph.c b/lib_com/preemph.c index 490a18aef..9ebc0f72a 100644 --- a/lib_com/preemph.c +++ b/lib_com/preemph.c @@ -36,7 +36,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-------------------------------------------------------------* diff --git a/lib_com/prot.h b/lib_com/prot.h deleted file mode 100644 index f5d69075e..000000000 --- a/lib_com/prot.h +++ /dev/null @@ -1,8340 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#ifndef PROT_H -#define PROT_H - -#include -#include -#include -#include "options.h" -#include "typedef.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "stat_com.h" -#include "ivas_stat_com.h" -#include "ivas_stat_enc.h" -#include "ivas_stat_dec.h" -#include "cnst.h" -#include "stl.h" -#include "ivas_error_utils.h" - - -/*----------------------------------------------------------------------------------* - * Prototypes of global macros - *----------------------------------------------------------------------------------*/ - -#ifndef min -#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef max -#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef TRUNC -#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) -#endif - -#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) -#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) - -#ifndef ABSVAL -#define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) -#endif - -#ifndef SQR -#define SQR( a ) ( ( a ) * ( a ) ) -#endif - -#ifndef SWAP -#define SWAP( a, b ) \ - { \ - tempr = ( a ); \ - ( a ) = ( b ); \ - ( b ) = tempr; \ - } -#endif - -#ifndef swap -#define swap( x, y, type ) \ - { \ - type u__p; \ - u__p = x; \ - x = y; \ - y = u__p; \ - } -#endif - -#define set_max( a, b ) \ - { \ - if ( ( b ) > *a ) \ - { \ - *a = ( b ); \ - } \ - } /* If the first argument is already the highes or lowest, nothing is done. */ -#define set_min( a, b ) \ - { \ - if ( ( b ) < *a ) \ - { \ - *a = ( b ); \ - } \ - } /* Otherwise, the 2nd arg is stored at the address of the first arg. */ - - -/*----------------------------------------------------------------------------------* - * MODE1 prototypes - *----------------------------------------------------------------------------------*/ - -/*! r: inverse square root of input value */ -float inv_sqrt( - const float x /* i : input value */ -); - -/*! r: output random value */ -int16_t own_random( - int16_t *seed /* i/o: random seed */ -); - -/*! r: sign of x (+1/-1) */ -float sign( - const float x /* i : input value of x */ -); - -/*! r: logarithm2 of x */ -float log2_f( - const float x /* i : input value of x */ -); - -int16_t norm_ul_float( - uint32_t UL_var1 ); - -/*! r: sum of all vector elements */ -int16_t sum_s( - const int16_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all vector elements */ -float sum_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all squared vector elements */ -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -void set_c( - int8_t y[], /* i/o: Vector to set */ - const int8_t a, /* i : Value to set the vector to */ - const int32_t N /* i : Length of the vector */ -); - -void set_s( - int16_t y[], /* i/o: Vector to set */ - const int16_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ -); - -void set_l( - int32_t y[], /* i/o: Vector to set */ - const int32_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Length of the vector */ -); - -void set_f( - float y[], /* i/o: Vector to set */ - const float a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ -); - -void set_zero_fx( - Word32 *vec, /* o : input vector */ - const Word16 lvec /* i : length of the vector */ -); -void set_zero2_fx( - Word32 *vec, /* o : input vector */ - const Word32 lvec /* i : length of the vector */ -); -void set16_zero_fx( - Word16 *vec, /* o : input vector */ - const Word16 lvec /* i : length of the vector */ -); - -void set_zero( - float *vec, /* o : input vector */ - const int16_t lvec /* i : length of the vector */ -); - -void mvr2r( - const float x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2s( - const int16_t x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvl2l( - const int32_t x[], /* i : input vector */ - int32_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); - -Word16 maximumAbs_l( - const Word32 *vec, /* i : input vector */ - const Word16 lvec, /* i : length of input vector */ - Word32 *max_val /* o : maximum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum_s( - const int16_t *vec, /* i : Input vector */ - const int16_t lvec, /* i : Vector length */ - int16_t *min_val /* o : minimum value in the input vector */ -); - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -); - -/*! r: vector mean */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: dot product of x[] and y[] */ -float dotp( - const float x[], /* i : vector x[] */ - const float y[], /* i : vector y[] */ - const int16_t n /* i : vector length */ -); - -void conv( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response (or second input vector) */ - float y[], /* o : output vetor (result of convolution) */ - const int16_t L /* i : vector size */ -); - -void fir( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response of the FIR filter */ - float y[], /* o : output vector (result of filtering) */ - float mem[], /* i/o: memory of the input signal (M samples) */ - const int16_t L, /* i : input vector size */ - const int16_t K, /* i : order of the FIR filter (M+1 coefs.) */ - const int16_t upd /* i : 1 = update the memory, 0 = not */ -); - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_sub( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 - vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_mult( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 .* vector 2*/ - const int16_t N /* i : Vector length */ -); - -void v_multc( - const float x[], /* i : Input vector */ - const float c, /* i : Constant */ - float y[], /* o : Output vector that contains c*x */ - const int16_t N /* i : Vector length */ -); - -/*! r: index of the winning codeword */ -int16_t squant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float cb[], /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -); - -int16_t squant_int( - uint8_t x, /* i : scalar value to quantize */ - uint8_t *xq, /* o : quantized value */ - const uint8_t *cb, /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: index of the winning codevector */ -int16_t vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: index of the winning codevector */ -int16_t w_vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - const int16_t weights[], /* i : error weights */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize, /* i : codebook size */ - const int16_t reverse /* i : reverse codebook vectors */ -); - -/*! r: index of the winning codeword */ -int16_t usquant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta, /* i : quantization step */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: dequanzited gain */ -float usdequant( - const int16_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ -); - -void v_sort_float( - float *r, /* i/o: Vector to be sorted in place */ - const int16_t lo, /* i : Low limit of sorting range */ - const int16_t up /* i : High limit of sorting range */ -); - -void sort( - uint16_t *x, /* i/o: Vector to be sorted */ - uint16_t len /* i/o: vector length */ -); - -void sort_l( - Word32 *x, /* i/o: Vector to be sorted */ - Word16 len /* i/o: vector length */ -); - -/*! r: variance of vector */ -float var( - const float *x, /* i : input vector */ - const int16_t len /* i : length of inputvector */ -); - -/*! r: standard deviation */ -float std_dev( - const float *x, /* i : input vector */ - const int16_t len /* i : length of the input vector */ -); - -/*! r: the dot product x'*A*x */ -float dot_product_mat( - const float *x, /* i : vector x */ - const float *A, /* i : matrix A */ - const int16_t m /* i : vector length */ -); - -float root_a( - float a ); - -float root_a_over_b( - float a, - float b ); - -void polezero_filter( - const float *in, /* i : input vector */ - float *out, /* o : output vector */ - const int16_t N, /* i : input vector size */ - const float *b, /* i : numerator coefficients */ - const float *a, /* i : denominator coefficients */ - const int16_t order, /* i : filter order */ - float *mem /* i/o: filter memory */ -); - -double rint_new( - double x /* i/o: Round to the nearest integer with mid point exception */ -); - -double anint( - double x /* i/o: Round to the nearest integer */ -); - -/*! r: Output either 1 if Numeric, 0 if NaN or Inf */ -int16_t is_numeric_float( - float x /* i : Input value which is checked if numeric or not */ -); - -void delay_signal_float( - float x[], /* i/o: signal to be delayed */ - const int16_t len, /* i : length of the input signal */ - float mem[], /* i/o: synchronization memory */ - const int16_t delay /* i : delay in samples */ -); - -ivas_error push_indice( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t id, /* i : ID of the indice */ - uint16_t value, /* i : value of the quantized indice */ - int16_t nb_bits /* i : number of bits used to quantize the indice */ -); - -ivas_error push_next_indice( - BSTR_ENC_HANDLE hBstr, - UWord16 value, /* i : value of the quantized indice */ - Word16 nb_bits /* i : number of bits used to quantize the indice */ -); - -ivas_error push_next_bits( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ - const Word16 nb_bits /* i : number of bits to pack */ -); - -/*! r: maximum number of indices */ -Word16 get_ivas_max_num_indices_fx( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -/*! r: maximum number of indices */ -int16_t get_BWE_max_num_indices( - const int32_t extl_brate /* i : extensiona layer bitrate */ -); - -/*! r: maximum number of indices */ -Word16 get_ivas_max_num_indices_metadata_fx( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); -ivas_error ind_list_realloc( - INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ - const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ - Encoder_Struct *st_ivas /* i : IVAS encoder structure */ -); - -ivas_error check_ind_list_limits( - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -); - -void move_indices( - INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ - INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ - const int16_t nb_indices /* i : number of moved indices */ -); - -/*! r: index of the indice in the list, -1 if not found */ -int16_t find_indice( - BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ - const int16_t id, /* i : ID of the indice */ - uint16_t *value, /* o : value of the quantized indice */ - int16_t *nb_bits /* o : number of bits used to quantize the indice */ -); - -/*! r: number of deleted indices */ -uint16_t delete_indice( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t id /* i : ID of the indice */ -); - -/*! r: value of the indice */ -uint16_t get_next_indice( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_next_indice_1( - Decoder_State *st /* i/o: decoder state structure */ -); - -void get_next_indice_tmp( - Decoder_State *st, /* o : decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_indice( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos, /* i : absolute position in the bitstream */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_indice_1( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos /* i : absolute position in the bitstream */ -); - -void reset_indices_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t max_num_indices /* i : max number of indices */ -); - -void reset_indices_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -ivas_error write_indices_ivas( - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - uint16_t *bit_stream, /* i/o: output bitstream */ - uint16_t *num_bits /* i/o: number of bits written to output */ -); - -Word16 rate2EVSmode_float( - const Word32 brate, /* i : bitrate */ - int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ -); - - -/*! r: 1 = OK, 0 = something wrong */ -ivas_error read_indices( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t bit_stream[], /* i : bitstream buffer */ - UWord16 num_bits, /* i : number of bits in bitstream */ - int16_t *prev_ft_speech, - int16_t *CNG, - int16_t bfi /* i : bad frame indicator */ -); - - -void ivas_set_bitstream_pointers( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -Decoder_State **reset_elements( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -void convertSerialToBytestream( - const uint16_t *const serial, /* i : input serial bitstream with values 0 and 1 */ - const uint16_t num_bits, /* i : number of bits in the input bitstream */ - uint8_t *const bytestream /* o : output compact bitstream (bytestream) */ -); - -void convertBytestreamToSerial( - const uint8_t *const bytestream, /* i : input compact bitstream (bytestream) */ - const uint16_t num_bits, /* i : number of bits in the input bitstream */ - uint16_t *const serial /* o : output serial bitstream with values 0 and 1 */ -); - -void mdct_switching_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -void evs_dec_previewFrame_float( - uint8_t *bitstream, /* i : bitstream pointer */ - int16_t bitstreamSize, /* i : bitstream size */ - int16_t *partialCopyFrameType, /* o : frame type of the partial copy */ - int16_t *partialCopyOffset /* o : offset of the partial copy relative to the primary copy */ -); - - -void getPartialCopyInfo_float( - Decoder_State *st, /* i : decoder state structure */ - int16_t *sharpFlag ); - -void get_NextCoderType( - uint8_t *bitstream, /* i : bitstream */ - int16_t *next_coder_type /* o : next coder type */ -); - -int16_t print_disclaimer( - FILE *fPtr ); - - -/*! r: delay value in ns */ -int32_t get_delay( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t io_fs, /* i : input/output sampling frequency */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ -); - -void decision_matrix_enc( - Encoder_State *st, /* i/o: encoder state structure */ - int16_t *hq_core_type /* o : HQ core type */ -); - -void signaling_enc( - Encoder_State *st /* i : encoder state structure */ -); - -int16_t signaling_mode1_tcx20_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t push /* i : flag to push indice */ -); - -void decision_matrix_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *sharpFlag, /* o : formant sharpening flag */ - int16_t *hq_core_type, /* o : HQ core type */ - int16_t *core_switching_flag /* o : ACELP->HQ switching frame flag */ -); - - -void amr_wb_dec_init( - AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ -); - -void hf_synth_amr_wb_init( - AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ -); - -void hf_synth_amr_wb_reset( - AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth_amr_wb( - AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ - ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t output_frame, /* i : output frame length */ - const float *Aq, /* i : quantized Az */ - const float *exc, /* i : excitation at 12.8 kHz */ - float *synth, /* i/o: synthesis signal at 12.8 kHz */ - int16_t *amr_io_class, /* i : signal class (determined by FEC algorithm) */ - float *synth_out, /* i/o: synthesis signal at output Fs */ - float fmerit, /* i : classify parameter from FEC */ - const int16_t *hf_gain, /* i : decoded HF gain */ - const float *voice_factors, /* i : voicing factors */ - const float pitch_buf[], /* i : pitch buffer */ - const float ng_ener_ST, /* i : Noise gate - short-term energy */ - const float *lsf_new /* i : ISF vector */ -); - -void hf_cod_init( - float *mem_hp400_enc, /* o : memory of hp 400 Hz filter */ - float *mem_hf1_enc, /* o : HF band-pass filter memory */ - float *mem_syn_hf_enc, /* o : HF synthesis memory */ - float *mem_hf2_enc, /* o : HF band-pass filter memory */ - float *gain_alpha /* o : smoothing gain for transitions between active and inactive frames */ -); - -void hf_cod( - const int32_t core_brate, /* i : core bitrate */ - const float *speech16k, /* i : original speech at 16 kHz */ - const float Aq[], /* i : quantized Aq */ - const float exc[], /* i : excitation at 12.8 kHz */ - float synth[], /* i : 12.8kHz synthesis signal */ - int16_t *seed2_enc, /* i/o: random seed for HF noise gen */ - float *mem_hp400_enc, /* i/o: memory of hp 400 Hz filter */ - float *mem_syn_hf_enc, /* i/o: HF synthesis memory */ - float *mem_hf1_enc, /* i/o: HF band-pass filter memory */ - float *mem_hf2_enc, /* i/o: HF band-pass filter memory */ - const int16_t *dtxHangoverCount, - float *gain_alpha, /* i/o: smoothing gain for transitions between active and inactive frames */ - int16_t *hf_gain /* o : HF gain to be transmitted to decoder */ -); - -void hf_synth_init( - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth_reset( - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth( - ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t output_frame, /* i : output frame length */ - const float *Aq, /* i : quantized Az */ - const float *exc, /* i : excitation at 12.8 kHz */ - float *synth, /* i/o: 12.8kHz synthesis signal */ - float *synth16k /* i/o: 16kHz synthesis signal */ -); - -void fft_rel( - float x[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ -); - -void ifft_rel( - float io[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ -); - -void preemph( - float *signal, /* i/o: signal */ - const float mu, /* i : preemphasis factor */ - const int16_t L, /* i : vector size */ - float *mem /* i/o: memory (x[-1]) */ -); -void preemph_ivas_fx( - Word32 *signal, /* i/o: signal Qx*/ - const Word16 mu, /* i : preemphasis factor Q15*/ - const Word16 L, /* i : vector size Q0*/ - Word32 *mem /* i/o: memory (x[-1]) Qx*/ -); - -void cb_shape( - const int16_t preemphFlag, /* i : flag for pre-emphasis */ - const int16_t pitchFlag, /* i : flag for pitch sharpening */ - const int16_t scramblingFlag, /* i : flag for phase scrambling */ - const int16_t formantFlag, /* i : flag for formant sharpening */ - const int16_t formantTiltFlag, /* i : flag for formant tilt */ - const float g1, /* i : formant sharpening numerator weighting */ - const float g2, /* i : formant sharpening denominator weighting */ - const float *p_Aq, /* i : LP filter coefficients */ - float *code, /* i/o: signal to shape */ - const float tilt_code, /* i : tilt of code */ - const float pt_pitch, /* i : pointer to current subframe fractional pitch*/ - const int16_t L_subfr /* i : subfframe length */ -); - -void CNG_exc( - const int32_t core_brate, /* i : core bitrate */ - const int16_t L_frame, /* i : length of the frame */ - float *Enew, /* i/o: decoded SID energy */ - int16_t *seed, /* i/o: random generator seed */ - float exc[], /* o : current non-enhanced excitation */ - float exc2[], /* o : current enhanced excitation */ - float *lp_ener, /* i/o: LP filtered E */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - int16_t *first_CNG, /* i/o: first CNG frame flag for energy init. */ - int16_t *cng_ener_seed, /* i/o: random generator seed for CNG energy */ - float bwe_exc[], /* o : excitation for SWB TBE */ - const int16_t allow_cn_step, /* i : allow CN step */ - int16_t *last_allow_cn_step, /* i/o: last CN_step */ - const int16_t num_ho, /* i : number of selected hangover frames */ - float q_env[], - float *lp_env, - float *old_env, - float *exc_mem, - float *exc_mem1, - int16_t *sid_bw, - int16_t *cng_ener_seed1, - float exc3[], - const int16_t Opt_AMR_WB, /* i : AMR-WB interop flag */ - const int16_t element_mode /* i : IVAS Element mode */ -); - - -void cng_params_postupd( - const int16_t ho_circ_ptr, /* i : pointer for CNG averaging buffers */ - int16_t *cng_buf_cnt, /* i/o: counter for CNG store buffers */ - const float *cng_exc2_buf, /* i : Excitation buffer */ - const int32_t *cng_brate_buf, /* i : bitrate buffer */ - float ho_env_circ[], /* i/o: Envelope buffer */ - const int16_t element_mode, /* i : Element mode */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void calculate_hangover_attenuation_gain( - Encoder_State *st, /* i : encoder state structure */ - float *att, /* o : attenuation factor */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -int16_t get_cng_mode_ivas( - const int32_t last_active_brate /* i : last active bitrate */ -); - -void disf_ns_28b( - int16_t *indice, /* i : quantized indices, use indice[0] = -1 in the decoder*/ - float *isf_q /* o : ISF in the frequency domain (0..6400) */ -); - -void limit_T0( - const int16_t L_frame, /* i : length of the frame */ - const int16_t delta, /* i : Half the close-loop searched interval */ - const int16_t pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ - const int16_t limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_max /* o : higher pitch limit */ -); - -/*! r: interpolated value */ -float interpolation( - const float *x, /* i : input vector */ - const float *win, /* i : interpolation window */ - const int16_t frac, /* i : fraction */ - const int16_t up_samp, /* i : upsampling factor */ - const int16_t nb_coef /* i : nb of filter coef */ -); - -void deemph( - float *signal, /* i/o: signal */ - const float mu, /* i : deemphasis factor */ - const int16_t L, /* i : vector size */ - float *mem /* i/o: memory (y[-1]) */ -); - -void weight_a( - const float *a, /* i : LP filter coefficients */ - float *ap, /* o : weighted LP filter coefficients */ - const float gamma, /* i : weighting factor */ - const int16_t m /* i : order of LP filter */ -); - -void weight_a_subfr( - const int16_t nb_subfr, /* i : number of subframes */ - const float *a, /* i : LP filter coefficients */ - float *ap, /* o : weighted LP filter coefficients */ - const float gamma, /* i : weighting factor */ - const int16_t m /* i : order of LP filter */ -); - -void syn_12k8( - const int16_t L_frame, /* i : length of the frame */ - const float *Aq, /* i : LP filter coefficients */ - const float *exc, /* i : input signal */ - float *synth, /* o : output signal */ - float *mem, /* i/o: initial filter states */ - const int16_t update_m /* i : update memory flag: 0 --> no memory update */ -); /* 1 --> update of memory */ - -void syn_filt( - const float a[], /* i : LP filter coefficients */ - const int16_t m, /* i : order of LP filter */ - const float x[], /* i : input signal */ - float y[], /* o : output signal */ - const int16_t l, /* i : size of filtering */ - float mem[], /* i/o: initial filter states */ - const int16_t update_m /* i : update memory flag: 0 --> no memory update */ -); /* 1 --> update of memory */ - -void synth_mem_updt2_flt( - const int16_t L_frame, /* i : frame length */ - const int16_t last_L_frame, /* i : frame length */ - float old_exc[], /* i/o: excitation buffer */ - float mem_syn_r[], /* i/o: synthesis filter memory */ - float mem_syn2[], /* o : synthesis filter memory for find_target */ - float mem_syn[], /* o : synthesis filter memory for find_target */ - const int16_t dec /* i : flag for decoder indication */ -); - -void int_lsp( - const int16_t L_frame, /* i : length of the frame */ - const float lsp_old[], /* i : LSPs from past frame */ - const float lsp_new[], /* i : LSPs from present frame */ - float *Aq, /* o : LP coefficients in both subframes */ - const int16_t m, /* i : order of LP filter */ - const float *int_coeffs, /* i : interpolation coefficients */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - -void int_lsp4( - const int16_t L_frame, /* i : length of the frame */ - const float lsp_old[], /* i : previous end-frame LSPs */ - const float lsp_mid[], /* i : current mid-frame LSPs */ - const float lsp_new[], /* i : current end-frame LSPs */ - float *Aq, /* o : LP coefficients in both subframes */ - const int16_t m, /* i : order of LP filter */ - int16_t relax_prev_lsf_interp /* i : relax prev frame lsf interp after erasure */ -); - -/*! r: length of output */ -int16_t modify_Fs( - const float sigIn[], /* i : signal to decimate */ - const int16_t lg, /* i : length of input */ - const int32_t fin, /* i : frequency of input */ - float sigOut[], /* o : decimated signal */ - const int32_t fout, /* i : frequency of output */ - float mem[], /* i/o: filter memory */ - const int16_t nblp /* i : flag indicating if NB low-pass is applied */ -); - -void pred_lt4_flt( - const float excI[], /* i : input excitation buffer */ - float excO[], /* o : output excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const int16_t L_subfr, /* i : subframe size */ - const float *win, /* i : interpolation window */ - const int16_t nb_coef, /* i : nb of filter coef */ - const int16_t up_sample /* i : up_sample */ -); - -void pred_lt4_tc_flt( - float exc[], /* i : excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const float *win, /* i : interpolation window */ - const int16_t imp_pos, /* i : glottal impulse position */ - const int16_t i_subfr /* i : subframe index */ -); - -void residu( - const float *a, /* i : LP filter coefficients */ - const int16_t m, /* i : order of LP filter */ - const float *x, /* i : input signal (usually speech) */ - float *y, /* o : output signal (usually residual) */ - const int16_t l /* i : size of filtering */ -); - -void calc_residu( - const float *speech, /* i : weighted speech signal */ - float *res, /* o : residual signal */ - const float *p_Aq, /* i : quantized LP filter coefficients */ - const int16_t L_frame /* i : size of frame */ -); - -/*! r: impulse response energy */ -float enr_1_Az( - const float Aq[], /* i : LP filter coefs */ - const int16_t len /* i : impulse response length */ -); - -void Es_pred_enc( - float *Es_pred, /* o : predicited scaled innovation energy */ - int16_t *Es_pred_indice, /* o : indice corresponding to above parameter */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : length of the subframe */ - const float *res, /* i : residual signal */ - const float *voicing, /* i : normal. correlattion in three 1/2frames */ - const int16_t nb_bits, /* i : allocated number of bits */ - const int16_t no_ltp /* i : no_ltp flag */ -); - -void create_offset( - UWord32 *offset_scale1, - UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ); - -float mslvq( - float *pTmp, /* i : M-dimensional input vector */ - float *quant, /* o : quantized vector */ - float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - int16_t *idx_lead, /* o : leader index for each 8-dim subvector */ - int16_t *idx_scale, /* o : scale index for each subvector */ - const float *w, /* i : weights for LSF quantization */ - const int16_t mode, /* i : number indicating the coding mode */ - const int16_t mode_glb, /* i : LVQ coding mode */ - const int16_t pred_flag /* i : prediction flag (0: safety net, 1 - predictive )*/ -); - -void permute( - float *pTmp1, /* i/o: vector whose components are to be permuted */ - const int16_t *perm /* i : permutation info (indexes that should be interchanged), max two perms */ -); - -void sort_desc_ind( - float *s, - const int16_t len, - int16_t *ind ); - -float mslvq_cng( - int16_t idx_cv, /* i : index of cv from previous stage */ - float *pTmp, /* i : 16 dimensional input vector */ - float *quant, /* o : quantized vector */ - float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - int16_t *idx_lead, /* o : leader index for each 8-dim subvector */ - int16_t *idx_scale, /* o : scale index for each subvector */ - const float *w /* i : weights for LSF quantization */ -); - -int16_t deindex_lvq_cng( - int16_t *index, /* i : index to be decoded, as an array of 3 short */ - float *x_lvq, /* o : decoded codevector */ - const int16_t idx_cv, /* i : relative mode_lvq, wrt START_CNG */ - const int16_t no_bits /* i : number of bits for lattice */ -); - -void multiply32_32_64( - UWord32 x, /* i : operand 1 */ - UWord32 y, /* i : operand 2 */ - UWord32 *res /* o : result as array of two uint32 */ -); - -int16_t deindex_lvq( - int16_t *index, /* i : index to be decoded, as an array of 3 short */ - float *x_lvq, /* o : decoded codevector */ - const int16_t mode, /* i : LVQ coding mode (select scales & no_lead ), or idx_cv */ - const int16_t sf_flag, /* i : safety net flag */ - const int16_t no_bits /* i : number of bits for lattice */ -); - -void index_lvq( - float *quant, /* i : codevector to be indexed (2 8-dim subvectors) */ - int16_t *idx_lead, /* i : leader class index for each subvector */ - int16_t *idx_scale, /* i : scale index for each subvector */ - const int16_t mode, /* i : integer signaling the quantizer structure for the current bitrate */ - int16_t *index, /* o : encoded index (represented on 3 short each with 15 bits ) */ - const int16_t prediction_flag /* i : predictive mode or not */ -); - -int16_t qlsf_ARSN_tcvq_Dec_16k( - float *y, /* o : Quantized LSF vector */ - int16_t *indice, /* i : Indices */ - const int16_t nBits /* i : number of bits */ -); - - -int16_t lsf_bctcvq_decprm_ivas( - Decoder_State *st, - int16_t *param_lpc ); - - -void disf_2s_36b( - int16_t *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */ - float *isf_q, /* o : quantized ISFs in the cosine domain */ - float *mem_AR, /* i/o: quantizer memory for AR model */ - float *mem_MA /* i/o: quantizer memory for MA model */ -); - -void disf_2s_46b( - int16_t *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */ - float *isf_q, /* o : quantized ISFs in the cosine domain */ - float *mem_AR, /* o : quantizer memory for AR model */ - float *mem_MA /* i/o: quantizer memory for MA model */ -); - -void re8_k2y( - const int16_t *k, /* i : Voronoi index k[0..7] */ - const int16_t m, /* i : Voronoi modulo (m = 2^r = 1<=2) */ - int16_t *y /* o : 8-dimensional point y[0..7] in RE8 */ -); - -void re8_PPV( - const float x[], /* i : point in R^8 */ - int16_t y[] /* o : point in RE8 (8-dimensional integer vector) */ -); - -void enhancer( - const int16_t codec_mode, /* i : flag indicating Codec Mode */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t cbk_index, /* i : */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t coder_type, /* i : coding type */ - const int16_t L_frame, /* i : frame size */ - const float voice_fac, /* i : subframe voicing estimation */ - const float stab_fac, /* i : LP filter stablility measure */ - const float norm_gain_code, /* i : normalized innovative cb. gain */ - const float gain_inov, /* i : gain of the unscaled innovation */ - float *gc_threshold, /* i/o: code threshold */ - float *code, /* i/o: innovation */ - float *exc2, /* i/o: adapt. excitation/total exc. */ - const float gain_pit, /* i : Quantized pitch gain */ - float *dispMem /* i/o: Phase dispersion algorithm memory */ -); - -void phase_dispersion_flt( - const float gain_code, /* i : gain of code */ - const float gain_pit, /* i : gain of pitch */ - float code[], /* i/o: code vector */ - const int16_t mode, /* i : level, 0=hi, 1=lo, 2=off */ - float disp_mem[] /* i/o: static memory (size = 8) */ -); - -void re8_vor( - int16_t y[], /* i : point in RE8 (8-dimensional integer vector) */ - int16_t *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */ - int16_t k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4 */ - int16_t c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */ - int16_t *ka /* o : identifier of absolute leader (needed to index c)*/ -); - -void DoRTFT480( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT320( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT160( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT128( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT120( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT80( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT20( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT40( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFTn( - float *x, /* i/o: real part of input and output data */ - float *y, /* i/o: imaginary part of input and output data */ - const int16_t n /* i : size of the FFT n=(2^k) up to 1024 */ -); - -void BASOP_cfft_ivas( - Word32 *re, /* i/o: real part */ - Word32 *im, /* i/o: imag part */ - Word16 s, /* i : stride real and imag part */ - Word16 *scale /* i : scalefactor */ -); - -void fft( - float *re, /* i/o: real part */ - float *im, /* i/o: imag part */ - const int16_t length, /* i : length of fft */ - const int16_t s /* i : sign */ -); - -void rfft( - float *x, /* i/o: values */ - const float *w, /* i : window */ - const int16_t length, /* i : length of fft */ - const int16_t isign /* i : sign */ -); - -void sinq( - const float tmp, /* i : sinus factor cos(tmp*i+phi) */ - const float phi, /* i : sinus phase cos(tmp*i+phi) */ - const int16_t N, /* i : size of output */ - float x[] /* o : output vector */ -); - -void edct2( - const int16_t n, - const int16_t isgn, - float *in, - float *a, - const int16_t *ip, - const float *w ); - -void stat_noise_uv_mod( - const int16_t coder_type, /* i : coder type */ - float noisiness, /* i : noisiness parameter */ - const float *const lsp_old, /* i : old LSP vector at 4th sfr */ - const float *const lsp_new, /* i : LSP vector at 4th sfr */ - const float *const lsp_mid, /* i : LSP vector at 2nd sfr */ - float *Aq, /* o : A(z) quantized for the 4 subframes */ - float *exc2, /* o : excitation buffer */ - const int16_t bfi, /* i : bad frame indicator */ - float *ge_sm, /* i/o: smoothed excitation gain */ - int16_t *uv_count, /* i/o: unvoiced counter */ - int16_t *act_count, /* i/o: activation counter */ - float lspold_s[], /* i/o: old LSP */ - int16_t *noimix_seed, /* i/o: mixture seed */ - float *st_min_alpha, /* i/o: minimum alpha */ - float *exc_pe, /* i/o: memory of the preemphasis filter */ - const int32_t bitrate, /* i : core bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void limit_band_noise_level_calc( - const int16_t *wnorm, /* i : reordered norm of sub-vectors */ - int16_t *limit, /* o : highest band of bit allocation */ - const int32_t core_brate, /* i : core bitrate */ - float *noise_level /* o : noise level */ -); - -/*! r: hqswb_clas */ -int16_t peak_avrg_ratio( - const int32_t total_brate, /* i : total bitrate */ - const float *input_hi, /* i : input signal */ - const int16_t N, /* i : number of coefficients */ - int16_t *mode_count, /* i/o: HQ_HARMONIC mode count */ - int16_t *mode_count1 /* i/o: HQ_NORMAL mode count */ -); - -/*! r: Number of coefficients in nf codebook */ -int16_t build_nf_codebook( - const int16_t flag_32K_env_ho, /* i : Envelope attenuation hangover flag */ - const float *coeff, /* i : Coded spectral coefficients */ - const int16_t *sfm_start, /* i : Subband start indices */ - const int16_t *sfmsize, /* i : Subband widths */ - const int16_t *sfm_end, /* i : Subband end indices */ - const int16_t nb_sfm, /* i : Last coded band */ - const int16_t *R, /* i : Per-band bit allocation */ - float *CodeBook, /* o : Noise-fill codebook */ - float *CodeBook_mod /* o : Densified noise-fill codebook */ -); - -void apply_noisefill_HQ( - const int16_t *R, /* i : bit allocation */ - const int16_t length, /* i : input frame length */ - const int16_t flag_32K_env_ho, /* i : envelope stability hangover flag */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t last_sfm, /* i : last coded subband */ - const float *CodeBook, /* i : Noise-fill codebook */ - const float *CodeBook_mod, /* i : Densified noise-fill codebook */ - const int16_t cb_size, /* i : Codebook length */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : Subband band width */ - float *coeff /* i/o: coded/noisefilled spectrum */ -); - -void harm_bwe_fine( - const int16_t *R, /* i : bit allocation */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t high_sfm, /* i : higher transition band to BWE */ - const int16_t num_sfm, /* i : total number of bands */ - const int16_t *norm, /* i : quantization indices for norms */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - float *coeff, /* i/o: coded/noisefilled normalized spectrum */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - float *coeff_fine /* o : BWE fine structure */ -); - -void hvq_bwe_fine( - const int16_t last_sfm, /* i : last coded subband */ - const int16_t num_sfm, /* i : total number of bands */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *peak_idx, /* i : Peak index */ - const int16_t Npeaks, /* i : Number of peaks */ - int16_t *peak_pos, /* i/o: Peak positions */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - float *coeff, /* i/o: coded/noisefilled normalized spectrum */ - int16_t *bwe_peaks, /* o : Positions of peaks in BWE */ - float *coeff_fine /* o : HVQ BWE fine structure */ -); - -void hq_fold_bwe( - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t num_sfm, /* i : Number of subbands */ - float *coeff /* i/o: coded/noisefilled normalized spectrum */ -); - -void apply_nf_gain( - const int16_t nf_idx, /* i : noise fill gain index */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *R, /* i : bit allocation */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - float *coeff /* i/o: coded/noisefilled normalized spectrum */ - -); - -void hq_generic_fine( - float *coeff, /* i : coded/noisefilled normalized spectrum */ - const int16_t last_sfm, /* i : Last coded band */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out1 /* o : HQ GENERIC input */ -); - -void harm_bwe( - const float *coeff_fine, /* i : fine structure for BWE */ - const float *coeff, /* i : coded/noisefilled normalized spectrum */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t high_sfm, /* i : higher transition band to BWE */ - const int16_t *R, /* i : bit allocation */ - const int16_t prev_hq_mode, /* i : previous hq mode */ - int16_t *norm, /* i/o: quantization indices for norms */ - float *noise_level, /* i/o: noise levels for harmonic modes */ - float *prev_noise_level, /* i/o: noise factor in previous frame */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - const int16_t element_mode /* i : element mode */ -); - -void hvq_bwe( - const float *coeff, /* i : coded/noisefilled spectrum */ - const float *coeff_fine, /* i : BWE fine structure */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfm_len, /* i : Subband length */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t prev_hq_mode, /* i : previous hq mode */ - const int16_t *bwe_peaks, /* i : HVQ bwe peaks */ - const int16_t bin_th, /* i : HVQ transition bin */ - const int16_t num_sfm, /* i : Number of bands */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t *R, /* i : Bit allocation */ - int16_t *norm, /* i/o: quantization indices for norms */ - float *noise_level, /* i/o: noise levels for harmonic modes */ - float *prev_noise_level, /* i/o: noise factor in previous frame */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out /* o : coded/noisefilled spectrum */ -); - -void hvq_concat_bands( - const int16_t pvq_bands, /* i : Number of bands in concatenated PVQ target */ - const int16_t *sel_bnds, /* i : Array of selected high bands */ - const int16_t n_sel_bnds, /* i : Number of selected high bands */ - int16_t *hvq_band_start, /* o : Band start indices */ - int16_t *hvq_band_width, /* o : Band widths */ - int16_t *hvq_band_end /* o : Band end indices */ -); - -void hq_generic_bwe( - const int16_t HQ_mode, /* i : HQ mode */ - float *coeff_out1, /* i/o: BWE input & temporary buffer */ - const float *hq_generic_fenv, /* i : SWB frequency envelopes */ - float *coeff_out, /* o : SWB signal in MDCT domain */ - const int16_t hq_generic_offset, /* i : frequency offset for representing hq generic*/ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - const int16_t hq_generic_exc_clas, /* i : hq generic hf excitation class */ - const int16_t *sfm_end, /* i : End of bands */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t num_env_bands, /* i : Number of coded envelope bands */ - const int16_t *R /* i : Bit allocation */ -); - -void map_hq_generic_fenv_norm( - const int16_t hqswb_clas, /* i : signal classification flag */ - const float *hq_generic_fenv, /* i : HQ GENERIC envelope */ - int16_t *ynrm, /* o : high band norm indices */ - int16_t *normqlg2, /* o : high band norm values */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t hq_generic_offset /* i : Freq offset for HQ GENERIC */ -); - -/*! r: Number of bits consumed for the delta coding */ -int16_t calc_nor_delta_hf( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *t_audio, /* i : transform-domain coefficients */ - int16_t *ynrm, /* i/o: norm indices */ - int16_t *Rsubband, /* i/o: sub-band bit allocation */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t *sfmsize, /* i : band length */ - const int16_t *sfm_start, /* i : Start index of bands */ - const int16_t core_sfm /* i : index of the end band for core */ -); - -/*! r: Number of bits consumed for the delta coding */ -int16_t get_nor_delta_hf( - Decoder_State *st, /* i/o: Decoder state */ - int16_t *ynrm, /* i/o: norm indices */ - int16_t *Rsubband, /* i/o: sub-band bit allocation */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t core_sfm ); /* i : index of the end band for core */ - -void hq_wb_nf_bwe( - const float *coeff, /* i : coded/noisefilled normal. spectrum */ - const int16_t is_transient, /* i : is transient flag */ - const int16_t prev_bfi, /* i : previous bad frame indicator */ - const float *normq_v, /* i : norms */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : Subband band width */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *R, /* i : bit allocation */ - const int16_t prev_is_transient, /* i : previous transient flag */ - float *prev_normq, /* i/o: previous norms */ - float *prev_env, /* i/o: previous noise envelopes */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */ - int16_t *prev_R, /* i/o: previous frame bit allocation info. */ - float *coeff_out /* o : coded/noisefilled spectrum */ -); - -/*! r: Number of bits */ -int16_t encode_envelope_indices( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t numnrmibits, /* i : Bitrate of fall-back coding mode */ - int16_t *difidx, /* i/o: Diff indices/encoded diff indices */ - int16_t *LCmode, /* o : Coding mode */ - const int16_t flag_pack, /* i : indicator of packing or estimating bits */ - const int16_t flag_HQ2, /* i : indicator of HQ2 core */ - const int16_t is_transient /* i : transient flag */ -); - -void diff_envelope_coding( - const int16_t is_transient, /* i : transient indicator */ - const int16_t num_env_bands, /* i : number of envelope bands to code */ - const int16_t start_norm, /* i : start of envelope coding */ - int16_t *ynrm, /* i/o: quantization indices for norms */ - int16_t *normqlg2, /* i/o: quantized norms */ - int16_t *difidx /* o : differential code */ -); - -/*! r: Number of bits */ -int16_t decode_envelope_indices( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t start_norm, /* i : First SDE encoded norm */ - const int16_t num_sfm, /* i : Number of norms */ - const int16_t numnrmibits, /* i : Bitrate of fall-back coding mode */ - int16_t *ynrm, /* o : Decoded norm indices */ - const int16_t flag_HQ2, /* i : indicator of HQ2 core */ - const int16_t is_transient /* i : transient flag */ -); - -/*! r: Number of bits */ -void dequantize_norms( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t start_norm, /* i : First SDE encoded norm */ - const int16_t num_sfm, /* i : Number of norms */ - const int16_t is_transient, /* i : Transient flag */ - int16_t *ynrm, /* o : Decoded norm indices */ - int16_t *normqlg2 /* o : Log2 of decoded norms */ -); - -void hq_configure( - const int16_t length, /* i : Frame length */ - const int16_t hqswb_clas, /* i : HQ SWB class */ - const int32_t core_brate, /* i : core bitrate */ - int16_t *num_sfm, /* o : Total number of subbands */ - int16_t *nb_sfm, /* o : Total number of coded bands */ - int16_t *start_norm, /* o : First norm to be SDE encoded */ - int16_t *num_sde_norm, /* o : Number of norms for SDE encoding */ - int16_t *numnrmibits, /* o : Number of bits in fall-back norm encoding */ - int16_t *hq_generic_offset, /* o : Freq offset for HQ GENERIC */ - int16_t *sfmsize, /* o : Subband bandwidths */ - int16_t *sfm_start, /* o : Subband start coefficients */ - int16_t *sfm_end /* o : Subband end coefficients */ -); - -/*! r: Consumed bits */ -int16_t hvq_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t hvq_bits, /* i : HVQ bit budget */ - const int16_t Npeaks, /* i : Number of peaks */ - const int16_t *ynrm, /* i : Envelope coefficients */ - int16_t *R, /* i/o: Bit allocation/updated bit allocation */ - int16_t *peaks, /* i/o: Peak pos. / Encoded peak pos. */ - float *nf_gains, /* i/o: Noise fill gains / Quant. nf gains */ - float *noise_level, /* o : Quantized noise level */ - const float *pe_gains, /* i : Peak gains */ - const float *coefs, /* i : spectrum coefficients */ - float *coefs_out /* o : encoded spectrum coefficients */ -); -/*! r: Consumed bits */ -int16_t hq_classifier_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t length, /* i : Frame length */ - int16_t *is_transient, /* o : Transient flag */ - int16_t *hqswb_clas /* o : HQ class */ -); - -void hq_bit_allocation( - const int32_t core_brate, /* i : Core bitrate */ - const int16_t length, /* i : Frame length */ - const int16_t hqswb_clas, /* i : HQ class */ - int16_t *num_bits, /* i/o: Remaining bit budget */ - const int16_t *normqlg2, /* i : Quantized norms */ - const int16_t nb_sfm, /* i : Number sub bands to be encoded */ - const int16_t *sfmsize, /* i : Sub band bandwidths */ - float *noise_level, /* o : HVQ noise level */ - int16_t *R, /* o : Bit allocation per sub band */ - int16_t *Rsubband, /* o : Fractional bit allocation (Q3) */ - int16_t *sum, /* o : Sum of allocated shape bits */ - int16_t *core_sfm, /* o : Last coded band in core */ - const int16_t num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ -); - -void enforce_zero_for_min_envelope( - const int16_t hqswb_clas, /* i : HQ coding class */ - const int16_t *ynrm, /* i : Envelope indices */ - float *coefsq, /* i/o: Quantized spectrum/zeroed spectrum */ - int16_t nb_sfm, /* i : Number of coded sub bands */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end /* i : Sub band end indices */ -); - -void apply_envelope( - const float *coeff, /* i/o: Coded/noisefilled normalized spectrum */ - const int16_t *norm, /* i : Envelope */ - const float *norm_adj, /* i : Envelope adjustment */ - const int16_t num_sfm, /* i : Total number of bands */ - const int16_t last_sfm, /* i : Last coded band */ - const int16_t HQ_mode, /* i : HQ mode */ - const int16_t length, /* i : Frame length */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end, /* i : Sub band end indices */ - float *normq_v, /* o : Envelope with adjustment */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - float *coeff_out1 /* o : noisefilled spectrum for HQ SWB BWE */ -); - -void apply_envelope_enc( - float *coeff, /* i/o: Normalized/scaled normalized spectrum */ - const int16_t *norm, /* i : Envelope */ - const int16_t num_sfm, /* i : Total number of bands */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end /* i : Sub band end indices */ -); - -/*! r: Leading_sign_index, index, size, k_val */ -PvqEntry mpvq_encode_vec( - const int16_t *vec_in, /* i : Signed pulse train */ - const int16_t dim_in, /* i : Dimension */ - int16_t k_val_local /* i/o: Num unit pulses */ -); - -/*! r: Size, dim, k_val */ -PvqEntry get_size_mpvq_calc_offset( - const int16_t dim_in, /* i : Dimension */ - const int16_t k_val_in, /* i : Num unit pulses */ - uint32_t *h_mem /* o : Offsets */ -); - -void mpvq_decode_vec( - const PvqEntry *entry, /* i : Sign_ind, index, dim, k_val */ - uint32_t *h_mem, /* i : A/U offsets */ - int16_t *vec_out /* o : Pulse train */ -); - -/*! r: Multiplication result */ -uint32_t UMult_32_32( - const uint32_t UL_var1, /* i : factor 1 */ - const uint32_t UL_var2 /* i : factor 2 */ -); - -/*! r: inverse */ -uint32_t UL_inverse_float( - const uint32_t UL_val, /* i : input value Q_exp */ - int16_t *exp /* i/o: input exp / result exp */ -); - -/*! r: ratio */ -Word16 ratio_float( - const Word32 numer, /* i : numerator */ - const Word32 denom, /* i : denominator */ - Word16 *expo /* i/o: input exp / result exp */ -); - -/*! r: Angle between 0 and EVS_PI/2 radian (Q14) */ -Word16 atan2_fx_flt( - const Word32 y, /* i : near side (Argument must be positive) (Q15) */ - const Word32 x /* i : opposite side (Q15) */ -); - -void pvq_encode_frame( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *coefs_norm, /* i : normalized coefficients to encode */ - float *coefs_quant, /* o : quantized coefficients */ - float *gopt, /* o : optimal shape gains */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *pulse_vector, /* o : non-normalized pulse shapes */ - const int16_t *sfm_start, /* i : indices of first coefficients in the bands */ - const int16_t *sfm_end, /* i : indices of last coefficients in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - const int16_t nb_sfm, /* i : total number of bands */ - const int16_t *R, /* i : bitallocation per band (Q3) */ - const int16_t pvq_bits, /* i : number of bits avaiable */ - const int16_t core /* i : core */ -); - -void pvq_decode_frame( - Decoder_State *st, /* i/o: Decoder state */ - float *coefs_quant, /* o : quantized coefficients */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *pulse_vector, /* o : non-normalized pulse shapes */ - const int16_t *sfm_start, /* i : indices of first coeffs in the bands */ - const int16_t *sfm_end, /* i : indices of last coeffs in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - const int16_t nb_sfm, /* i : total number of bands */ - const int16_t *R, /* i : bitallocation per band (Q3) */ - const int16_t pvq_bits, /* i : number of bits avaiable */ - const int16_t core /* i : core */ -); - -void srt_vec_ind( - const int16_t *linear, /* linear input */ - int16_t *srt, /* sorted output */ - int16_t *I, /* index for sorted output */ - const int16_t length ); - -void srt_vec_ind_f( - const float *linear, /* linear input */ - float *srt, /* sorted output */ - int16_t *I, /* index for sorted output */ - const int16_t length /* length of vector */ -); - -/*! r: floor(sqrt(input)) */ -uint32_t floor_sqrt_exact( - const uint32_t input /* i : unsigned input [0.. UINT_MAX/4] */ -); - -void fine_gain_quant( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t *ord, /* i : Indices for energy order */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t *gain_bits, /* i : Gain adjustment bits per sub band */ - float *fg_pred, /* i/o: Predicted gains / Corrected gains */ - const float *gopt /* i : Optimal gains */ -); - -void apply_gain( - const int16_t *ord, /* i : Indices for energy order */ - const int16_t *band_start, /* i : Sub band start indices */ - const int16_t *band_end, /* i : Sub band end indices */ - const int16_t num_sfm, /* i : Number of bands */ - const float *gains, /* i : Band gain vector */ - float *xq /* i/o: float synthesis / gain adjusted synth */ -); - -void fine_gain_pred( - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end, /* i : Sub band end indices */ - const int16_t *sfm_size, /* i : Sub band bandwidths */ - const int16_t *i_sort, /* i : Energy sorting indices */ - const int16_t *K, /* i : Number of pulses per band */ - const int16_t *maxpulse, /* i : Maximum pulse per band */ - const int16_t *R, /* i : Bits per sub band (Q3) */ - const int16_t num_sfm, /* i : Number of sub bands */ - float *xq, /* i/o: Quantized vector /quantized vector with finegain adj */ - int16_t *y, /* i/o: Quantized vector */ - float *fg_pred, /* o : Predicted fine gains */ - const int16_t core /* i : Core */ -); - -void fine_gain_dec( - Decoder_State *st, /* i/o: Decoder state struct */ - const int16_t *ord, /* i : Indices for energy order */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t *gain_bits, /* i : Gain adjustment bits per sub band */ - float *fg_pred /* i/o: Predicted gains / Corrected gains */ -); - -void get_max_pulses( - const int16_t *band_start, /* i : Sub band start indices */ - const int16_t *band_end, /* i : Sub band end indices */ - const int16_t *k_sort, /* i : Indices for sorting by energy */ - const int16_t *npulses, /* i : Pulses per sub band */ - const int16_t BANDS, /* i : Number of bands */ - int16_t *inp_vector, /* i/o: Encoded shape vectors */ - int16_t *maxpulse /* o : Maximum pulse height per band */ -); - -Word32 ar_div_ivas( - Word32 num, - Word32 denum ); - -void ar_encoder_start( - PARCODEC arInst, - TCQ_PBITSTREAM bsInst, - int16_t max_bits ); - -void ar_decoder_start( - PARCODEC arInst, - TCQ_PBITSTREAM bsInst ); - -void ar_encoder_done( - PARCODEC arInst ); - -void ar_decoder_done( - PARCODEC arInst ); - - -Word32 Mult_32_16( - Word32 a, - Word16 b ); - -Word32 Mult_32_32( - Word32 a, - Word32 b ); - - -void decode_mangitude_tcq_fx_ivas( - ARCODEC *pardec, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *positions, - Word32 *out, - Word32 *surplus_fx ); - -void decode_signs_fx_ivas( - ARCODEC *pardec, - Word16 size, - Word32 *out ); - -void srt_vec_ind_fx_ivas( - const Word32 *linear, - Word32 *srt, - Word16 *I, - Word16 length ); - - -void bit_allocation_second_fx2( - Word32 *Rk, - Word32 *Rk_sort, - Word16 BANDS, - const Word16 *band_width, - Word16 *k_sort, - Word16 *k_num, - const Word16 *p2a_flags, - const Word16 p2a_bands, - const Word16 *last_bitalloc, - const Word16 input_frame ); - - -Word32 encode_magnitude_tcq_fx_ivas( - ARCODEC *parenc, - float *magn_fx, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *savedstates, - Word32 *est_frame_bits_fx ); - -Word32 encode_signs_fx_ivas( - ARCODEC *parenc, - float *magn, - Word16 size, - Word16 npos, - Word32 *est_frame_bits_fx ); - -Word32 encode_magnitude_usq_fx_ivas( - ARCODEC *parenc, - float *magn_fx, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *est_frame_bits_fx ); - -ivas_error tcq_core_LR_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int32_t inp_vector[], - const float coefs_norm[], - float coefs_quant[], - const int16_t bit_budget, /* number of bits */ - const int16_t nb_sfm, - const int16_t *sfm_start, - const int16_t *sfm_end, - const int16_t *sfmsize, - Word32 *Rk_fx, - int16_t *npulses, - int16_t *k_sort, - const int16_t *p2a_flags, - const int16_t p2a_bands, - const int16_t *last_bitalloc, - const int16_t input_frame, - const int16_t adjustFlag, - const int16_t is_transient ); - -void tcq_core_LR_dec( - Decoder_State *st, - int32_t *inp_vector, - const int16_t bit_budget, - const int16_t bands, - const int16_t *band_start, - const int16_t *band_width, - Word32 *Rk_fx, - int16_t npulses[], - int16_t *k_sort, - const int16_t *p2a_flags, - const int16_t p2a_bands, - const int16_t *last_bitalloc, - const int16_t input_frame, - const int16_t adjustFlag, - const int16_t *is_transient ); - - -void TCQLSB( - int16_t bcount, - float *abuffer, - float *mbuffer, - float *sbuffer, - int16_t *dpath ); - -void RestoreTCQ( - float *magn, - int16_t size, - int16_t *bcount, - float *mbuffer ); - -void SaveTCQdata( - PARCODEC arInst, - int16_t *dpath, - int16_t bcount ); - -void LoadTCQdata( - PARCODEC arInst, - int16_t *dpath, - int16_t bcount ); - -void RestoreTCQdec( - int32_t *magn, - int16_t size, - int16_t *bcount, - float *mbuffer ); - -void TCQLSBdec( - int16_t *dpath, - float *mbuffer, - int16_t bcount ); - -void bit_allocation_second_fx2( - Word32 *Rk, - Word32 *Rk_sort, - Word16 BANDS, - const Word16 *band_width, - Word16 *k_sort, - Word16 *k_num, - const Word16 *p2a_flags, - const Word16 p2a_bands, - const Word16 *last_bitalloc, - const Word16 input_frame ); - -void io_ini_enc( - const int32_t argc, /* i : command line arguments number */ - char *argv[], /* i : command line arguments */ - FILE **f_input, /* o : input signal file */ - FILE **f_stream, /* o : output bitstream file */ - FILE **f_rate, /* o : bitrate switching profile (0 if N/A) */ - FILE **f_bwidth, /* o : bandwidth switching profile (0 if N/A) */ - FILE **f_metadata, /* o : metadata files (NULL if N/A) */ -#ifdef DEBUGGING - FILE **f_force, /* o : force switching profile (0 if N/A) */ -#endif - FILE **f_rf, /* o : channel aware configuration file */ - int16_t *quietMode, /* o : limit printouts */ - int16_t *noDelayCmp, /* o : turn off delay compensation */ - Encoder_Struct *st /* o : IVAS encoder structure */ -); - -void read_next_rfparam( - int16_t *rf_fec_offset, /* o : RF offset */ - int16_t *rf_fec_indicator, /* o : RF FEC indicator */ - FILE *f_rf /* i : file pointer to read parameters */ -); - -void read_next_brate( - int32_t *total_brate, /* i/o: total bitrate */ - const int32_t last_total_brate, /* i : last total bitrate */ - FILE *f_rate, /* i : bitrate switching profile (0 if N/A) */ - const int16_t element_mode, /* i : IVAS element mode */ - int32_t input_Fs, /* i : input sampling frequency */ - int16_t *Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - int16_t *Opt_SC_VBR, /* i/o: SC-VBR flag */ - int16_t *codec_mode /* i/o: Mode 1 or 2 */ -); - -void read_next_bwidth( - int16_t *max_bwidth, /* i/o: maximum encoded bandwidth */ - FILE *f_bwidth, /* i : bandwidth switching profile (0 if N/A) */ - int32_t *bwidth_profile_cnt, /* i/o: counter of frames for bandwidth switching profile file */ - int32_t input_Fs /* i : input sampling rate */ -); - -#ifdef DEBUGGING -void read_next_force( - int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ - FILE *f_force, /* i : force switching profile (0 if N/A) */ - int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ -); -#endif - -ivas_error init_encoder_ivas_fx( - Encoder_State *st, /* i/o: state structure */ - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - const Word16 idchan, /* i : channel ID */ - const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ - const Word16 interval_SID, /* i : interval for SID update */ - const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const Word32 element_brate /* i : element bitrate */ -); - -void LPDmem_enc_init( - LPD_state_HANDLE hLPDmem /* i/o: LP memories */ -); - -ivas_error evs_enc( - Encoder_State *st, /* i/o: state structure */ - const int16_t *data, /* i : input signal */ - float *mem_hp20_in, /* i/o: hp20 filter memory */ - const int16_t n_samples /* i : number of input samples */ -); -void amr_wb_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t *data, /* i : input signal */ - float *mem_hp20_in, /* i/o: hp20 filter memory */ - const int16_t n_samples /* i : number of input samples */ -); - -void sc_vbr_enc_init( - SC_VBR_ENC_HANDLE hSC_VBR /* i/o: SC-VBR encoder handle */ -); - -void amr_wb_enc_init( - AMRWB_IO_ENC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO encoder handle */ -); - -void pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t input_frame, /* i : frame length */ - float old_inp_12k8[], /* i/o: buffer of old input signal */ - float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ - float **inp, /* o : ptr. to inp. signal in the current frame*/ - float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ - float *ener, /* o : residual energy from Levinson-Durbin */ - int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ - float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - float epsP[M + 1], /* i/o: LP prediction errors */ - float lsp_new[M], /* i/o: LSPs at the end of the frame */ - float lsp_mid[M], /* i/o: LSPs in the middle of the frame */ - int16_t *vad_hover_flag, /* i : VAD hangover flag */ - int16_t *attack_flag, /* o : attack flag */ - float *new_inp_resamp16k, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - int16_t *Voicing_flag, /* o : voicing flag for HQ FEC */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - int16_t *hq_core_type /* o : HQ core type */ -); - - -/*! r: HQ_CORE/TCX_20_CORE decision */ -int16_t mdct_classifier( - Encoder_State *st, /* i/o: Encoder state variable */ - const float *fft_buff, /* i : FFT spectrum from fft_rel */ - const float enerBuffer[], /* i : energy buffer */ - const int32_t brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ -); - -void MDCT_selector( - Encoder_State *st, /* i/o: Encoder State */ - const float sp_floor, /* i : Noise floor estimate */ - const float Etot, /* i : Total energy */ - const float cor_map_sum, /* i : sum of correlation map */ - const float enerBuffer[] /* i : energy buffer */ -); - -ivas_error acelp_core_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 inp[], /* i : input signal of the current frame Q_new*/ - Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ - Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ - const Word32 epsP[M + 1], /* i : LP prediction errors Qx*/ - Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ - Word16 lsp_mid[M], /* i : LSPs in the middle of the frame Q15*/ - const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ - const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ - Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ - Word16 *voice_factors_fx, /* o : voicing factors Q15*/ - Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn_12k8_16*/ - Word16 *q_old_syn_12k8_16, - Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ - Word16 *unbits, /* o : number of unused bits Q0*/ - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ - Word16 Q_new ); - -ivas_error acelp_core_switch_dec_bfi( - Decoder_State *st /* i/o: decoder state structure */ -); - -void acelp_core_switch_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float inp12k8[], /* i : input signal @12.8 kHz */ - const float inp16k[], /* i : input signal @16 kHz */ - const float A[NB_SUBFR16k * ( M + 1 )] /* i : A(z) unquantized for the 4 subframes */ -); - -/*! r: length of output */ -int16_t modify_Fs_intcub3m_sup( - const float sigIn[], /* i : signal to decimate with memory of 2 samples (indexes -2 & -1) */ - const int16_t lg, /* i : length of input */ - const int32_t fin, /* i : frequency of input */ - float sigOut[], /* o : decimated signal */ - const int32_t fout, /* i : frequency of output */ - int16_t *delayout /* o : delay of output */ -); - -void core_switching_OLA( - const float *mem_over_hp, /* i : upsampling filter memory */ - const int16_t last_L_frame, /* i : last L_frame lengthture */ - const int32_t output_Fs, /* i : output sampling rate */ - float *synth, /* i/o: synthesized signal from HQ core */ - const float *synth_subfr_out, /* i : synthesized signal from ACELP core */ - float *synth_subfr_bwe, /* i : synthesized BWE from ACELP core */ - const int16_t output_frame, /* i : output frame length */ - const int16_t bwidth /* i : output bandwidth */ -); - -void retro_interp4_5( - const float *syn, - float *pst_old_syn ); - -void retro_interp5_4( - float *pst_old_syn ); -void core_switching_hq_prepare_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *num_bits, /* i/o: bit budget update */ - const int16_t input_frame /* i : input frame length */ -); - -ivas_error acelp_core_switch_dec( - Decoder_State *st, /* i/o: decoder structure */ - float *synth_subfr_out, /* o : synthesized ACELP subframe */ - float *tmp_synth_bwe, /* o : synthesized ACELP subframe BWE */ - const int16_t output_frame, /* i : input frame length */ - const int16_t core_switching_flag, /* i : core switching flag */ - float *mem_synth, /* o : synthesis to overlap */ - const int16_t nchan_out /* i : number of output channels */ -); - -void ResetSHBbuffer_Enc( - TD_BWE_ENC_HANDLE hBWE_TD /* i/o: TD BWE data handle */ -); - -void ResetSHBbuffer_Dec( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t extl /* i : BWE extension layer */ -); - -void calc_st_filt( - const float *apond2, /* i : coefficients of numerator */ - const float *apond1, /* i : coefficients of denominator */ - float *parcor0, /* o : 1st parcor calcul. on composed filter */ - float *sig_ltp_ptr, /* i/o: input of 1/A(gamma1) : scaled by 1/g0 */ - float *mem_zero, /* i/o: All zero memory */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - - -void scale_st_ivas( - const float *sig_in, /* i : postfilter input signal */ - float *sig_out, /* i/o: postfilter output signal */ - float *gain_prec, /* i/o: last value of gain for subframe */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - -void filt_mu( - const float *sig_in, /* i : signal (beginning at sample -1) */ - float *sig_out, /* o : output signal */ - const float parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - -void PostShortTerm( - float *sig_in, /* i : input signal (ptr. to current subframe */ - float *lpccoeff, /* i : LPC coefficients for current subframe */ - float *sig_out, /* o : postfiltered output */ - float *mem_stp, /* i/o: postfilter memory */ - float *ptr_mem_stp, /* i/o: pointer to postfilter memory */ - float *ptr_gain_prec, /* i/o: for gain adjustment */ - float *mem_zero, /* i/o: null memory to compute h_st */ - const float formant_fac /* i : Strength of post-filter [0,1] */ -); - -/*! r: Formant filter strength [0,1] */ -float swb_formant_fac( - const float lpc_shb2, /* i : 2nd HB LPC coefficient */ - float *tilt_mem /* i/o: Tilt smoothing memory */ -); - -void GenShapedSHBExcitation( - float *excSHB, /* o : synthesized shaped shb exctiation */ - const float *lpc_shb, /* i : lpc coefficients */ - float *exc16kWhtnd, /* o : whitened synthesized shb excitation */ - float *mem_csfilt, /* i/o: memory */ - float *mem_genSHBexc_filt_down_shb, /* i/o: memory */ - float *state_lpc_syn, /* i/o: memory */ - const int16_t coder_type, /* i : coding type */ - const float *bwe_exc_extended, /* i : bandwidth extended excitation */ - int16_t bwe_seed[], /* i/o: random number generator seed */ - float voice_factors[], /* i : voicing factor */ - const int16_t extl, /* i : extension layer */ - float *tbe_demph, /* i/o: de-emphasis memory */ - float *tbe_premph, /* i/o: pre-emphasis memory */ - float *lpc_shb_sf, /* i : LP coefficients */ - float *shb_ener_sf, /* i : SHB subframe energies */ - float *shb_res_gshape, /* i : SHB LP residual gain shape */ - float *shb_res, /* i : SHB residual used in encoder only */ - int16_t *vf_ind, /* i/o: Mixing factor index */ - const float formant_fac, /* i : Formant sharpening factor [0..1] */ - float fb_state_lpc_syn[], /* i/o: memory */ - float *fb_tbe_demph, /* i/o: fb de-emphasis memory */ - const int32_t total_brate, /* i : overall bitrate */ - const int16_t prev_bfi, /* i : previous frame was lost flag */ - const int16_t element_mode, /* i : element mode */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - float *nlExc16k, /* i/o: NL exc for IC-BWE */ - float *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const int32_t extl_brate, /* i : TD BWE bitrate */ - const int16_t MSFlag, /* i : Multi-source flag */ - float EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - float *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - float *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - float *Env_error, /* o : error in SHB residual envelope modelling*/ - float Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -); - -void GenSHBSynth( - const float *shb_target_speech, /* i : input synthesized speech */ - float *shb_syn_speech_32k, /* o : output highband component */ - float Hilbert_Mem[], /* i/o: memory */ - float state_lsyn_filt_shb_local[], /* i/o: memory */ - const int16_t L_frame, /* i : ACELP Frame length */ - int16_t *syn_dm_phase ); - -void ScaleShapedSHB( - const int16_t length, /* i : SHB overlap length */ - float *synSHB, /* i/o: synthesized shb signal */ - float *overlap, /* i/o: buffer for overlap-add */ - const float *subgain, /* i : subframe gain */ - const float frame_gain, /* i : frame gain */ - const float *win, /* i : window */ - const float *subwin /* i : subframes window */ -); - -void Interpolate_allpass_steep( - const float *in, /* i : input array of size N */ - float *mem, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - float *out /* o : output array of size 2*N */ -); - -void Decimate_allpass_steep( - const float *in, /* i : input array of size N */ - float *mem, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - float *out /* o : output array of size N/2 */ -); - -void interpolate_3_over_2_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem /* i/o: memory */ -); - -void decimate_2_over_3_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem, /* i/o: memory */ - float *lp_mem ); - -void interpolate_3_over_1_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem /* i/o: memory */ -); - -void InitSWBencBuffer( - TD_BWE_ENC_HANDLE hBWE_TD /* i/o: TD BWE data handle */ -); - -void InitSWBencBufferStates( - TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *shb_speech /* o : SHB target signal (6-14kHz) at 16kHz */ -); - -void swb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - STEREO_ICBWE_ENC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const float *new_speech, /* i : original input signal */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - float *White_exc16k, /* o : shaped white excitation for the FB TBE */ - const float pitch_buf[] /* i : pitch for each subframe */ -); - -void swb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - const float old_syn_12k8_16k[], /* i : low band synthesis at 12.8kHz or 16kHz */ - float *White_exc16k, /* o : shaped white excitation for the FB TBE */ - float *synth, /* i/o: ACELP core synthesis/final synthesis */ - float *pitch_buf ); - -void flip_and_downmix_generic( - float input[], /* i : input spectrum */ - float output[], /* o : output spectrum */ - const int16_t length, /* i : length of spectra */ - float mem1_ext[HILBERT_ORDER1], /* i/o: Hilbert filter memory */ - float mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory */ - float mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory */ - int16_t *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -); -void flip_and_downmix_generic_fx_32( - Word32 input[], /* i : input spectrum Qx*/ - Word32 output[], /* o : output spectrum Qx*/ - const Word16 length, /* i : length of spectra */ - Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ - Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -); -void non_linearity( - const float input[], /* i : input signal */ - float output[], /* i : output signal */ - float old_bwe_exc_extended[], /* i/o: memory bugffer */ - const int16_t length, /* i : input length */ - float *prev_scale, /* i/o: memory */ - const int16_t coder_type, /* i : Coder Type */ - const float *voice_factors, /* i : Voice Factors */ - const int16_t L_frame /* i : ACELP frame length */ -); - -void interp_code_5over2( - const float inp_code[], /* i : input vector */ - float interp_code[], /* o : output vector */ - const int16_t inp_length /* i : length of the input vector */ -); - -void interp_code_4over2( - const float inp_code[], /* i : input vector */ - float interp_code[], /* o : output vector */ - const int16_t inp_length /* i : length of the input vector */ -); - -void flip_spectrum_and_decimby4( - const float input[], /* i : input spectrum */ - float output[], /* o : output spectrum */ - const int16_t length, /* i : vector length */ - float mem1[], /* i/o: memory */ - float mem2[], /* i/o: memory */ - const int16_t ramp_flag /* i : flag to trigger slow ramp-up of output */ -); - -void GenShapedWBExcitation( - float *excSHB, /* o : synthesized shaped shb exctiation */ - const float *lpc_shb, /* i : lpc coefficients */ - float *exc4kWhtnd, /* o : whitened synthesized shb excitation */ - float *mem_csfilt, /* i/o: memory */ - float *mem_genSHBexc_filt_down1, /* i/o: memory */ - float *mem_genSHBexc_filt_down2, /* i/o: memory */ - float *mem_genSHBexc_filt_down3, /* i/o: memory */ - float *state_lpc_syn, /* i/o: memory */ - const int16_t coder_type, /* i : coding type */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - int16_t bwe_seed[], /* i/o: random number generator seed */ - const float voice_factors[], /* i : voicing factor */ - const int16_t uv_flag, /* i : unvoiced flag */ - const int16_t igf_flag ); - -void GenWBSynth( - const float *input_synspeech, /* i : input synthesized speech */ - float *shb_syn_speech_16k, /* o : output highband compnent */ - float *state_lsyn_filt_shb1, /* i/o: memory */ - float *state_lsyn_filt_shb2 /* i/o: memory */ -); - -void wb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *hb_speech, /* i : HB target signal (6-8kHz) at 16kHz */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float pitch_buf[], /* i : pitch for each subframe */ - const float voicing[] /* o : OL maximum normalized correlation */ -); - -void wb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - float *synth /* i/o: ACELP core synthesis/final synthesis */ -); - -void tbe_write_bitstream( - Encoder_State *st /* i/o: encoder state structure */ -); - -void tbe_read_bitstream( - Decoder_State *st /* i/o: decoder state structure */ -); - -void GenTransition( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *outputHB, /* o : synthesized HB transitions signal */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t element_mode, /* i : element mode */ - const int16_t L_frame, /* i : ACELP frame length */ - const int16_t rf_flag, /* i : RF flag */ - const int32_t total_brate /* i : total bitrate */ -); - - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ); - -void GenTransition_WB( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *outputHB, /* o : synthesized HB transitions signal */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -); - -void td_bwe_dec_init( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t extl, /* i : BWE extension layer */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void TBEreset_enc( - TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t last_core, /* i : last core */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void TBEreset_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -/*! r: TBE bit consumption per frame */ -int16_t get_tbe_bits( - const int32_t total_brate, /* i : overall bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t rf_mode /* i : channel aware mode */ -); - -void fb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float new_input[], /* i : input speech at 48 kHz sample rate */ - const float fb_exc[] /* i : FB excitation from the SWB part */ -); - -void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* i/o: high-band synthesis */ - float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ - const int16_t output_frame /* i : output frame length */ -); - -void calc_tilt_bwe( - const float *sp, /* i : input signal */ - float *tilt, /* o : signal tilt */ - const int16_t N /* i : signal length */ -); - -void fd_bwe_enc_init( - FD_BWE_ENC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -); - -void swb_pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - float *new_swb_speech, /* o : original input signal at 32kHz */ - float *shb_speech, /* o : SHB target signal (6-14kHz) at 16kHz */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : imag buffer */ - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ -); - -void wb_pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const float *new_inp_resamp16k, /* i : original input signal */ - float *hb_speech /* o : HB target signal (6-8kHz) at 16kHz */ -); - -void wb_bwe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_wb_speech /* i : original input signal at 16kHz */ -); - -void wb_bwe_dec_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const float output[], /* i : synthesis @internal Fs */ - float *synth, /* i/o: ACELP core synthesis/final synthesis */ - float *hb_synth, /* o : SHB synthesis/final synthesis */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const float voice_factors[], /* i : voicing factors */ - const float pitch_buf[] /* i : pitch buffer */ -); - -void swb_bwe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const float *old_input_12k8, /* i : input signal @12.8kHz for SWB BWE */ - const float *old_input_16k, /* i : input signal @16kHz for SWB BWE */ - const float *old_syn_12k8_16k, /* i : ACELP core synthesis at 12.8kHz or 16kHz*/ - const float *new_swb_speech, /* i : original input signal at 32kHz */ - const float *shb_speech /* i : SHB target signal (6-14kHz) at 16kHz */ -); - -void swb_bwe_enc_hr( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_input, /* i : input signal */ - const int16_t input_frame, /* i : frame length */ - const int16_t unbits /* i : number of core unused bits */ -); - -void fd_bwe_dec_init_flt( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -); - -void swb_bwe_dec_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const float output[], /* i : synthesis @internal Fs */ - const float *synth, /* i : ACELP core synthesis/final synthesis */ - float *hb_synth, /* o : SHB synthesis/final synthesis */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame /* i : frame length */ -); - -void hr_bwe_dec_init_flt( - HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ -); - -void swb_bwe_dec_hr( - Decoder_State *st, /* i/o: decoder state structure */ - const float *syn_12k8_16k, /* i : ACELP core synthesis @16kHz */ - float *hb_synth, /* o : SHB synthesis */ - const int16_t output_frame, /* i : frame length */ - const int16_t unbits, /* i : number of core unused bits */ - const float pitch_buf[] /* i : pitch buffer */ -); - - -void calc_normal_length( - const int16_t core, /* i : core */ - const float *sp, /* i : input signal */ - const int16_t mode, /* i : input mode */ - const int16_t extl, /* i : extension layer */ - int16_t *L_swb_norm, /* o : normalize length */ - int16_t *prev_L_swb_norm /* i/o: last normalize length */ -); - -void calc_norm_envelop( - const float SWB_signal[], /* i : SWB spectrum */ - float *envelope, /* o : normalized envelope */ - const int16_t L_swb_norm, /* i : length of envelope */ - const int16_t SWB_flength, /* i : Length of input/output */ - const int16_t st_offset /* i : offset */ -); - -void time_envelop_shaping( - float werr[], /* i/o: SHB synthesis */ - float SWB_tenv[], /* i/o: frequency envelope */ - const int16_t L /* i : frame length */ -); - -void time_reduce_pre_echo( - const float *synth, /* i : ACELP core synthesis */ - float *error, /* o : SHB BWE synthesis */ - float prev_td_energy, /* o : last td energy */ - const int16_t L /* i : subframe length */ -); - -int16_t WB_BWE_gain_pred( - float *WB_fenv, /* o : WB frequency envelopes */ - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - const int16_t coder_type, /* i : coding type */ - const int16_t prev_code_type, /* i : coding type of last frame */ - const float prev_WB_fenv, /* i : envelope for last frame */ - const float voice_factors[], /* i : voicing factors */ - const float pitch_buf[], /* i : pitch buffer */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - const float last_wb_bwe_ener, /* i : previous frame wb bwe signal energy */ - const int16_t last_extl, /* i : extl. layer for last frame */ - const float tilt ); - -void WB_BWE_decoding( - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - float *WB_fenv, /* i : WB frequency envelopes */ - float *WB_signal, /* o : WB signal in MDCT domain */ - const int16_t WB_flength, /* i : Length of input/output */ - const int16_t mode, /* i : classification for WB signal */ - const int16_t last_extl, /* i : extl. layer for last frame */ - float *prev_Energy, /* i/o: energy for last frame */ - float *prev_WB_fenv, /* i/o: envelope for last frame */ - int16_t *prev_L_wb_norm, /* i/o: length for last frame wb norm */ - const int16_t extl, /* i : extension layer */ - const int16_t coder_type, /* i : coding type */ - const int32_t total_brate, /* i : core layer bitrate */ - int16_t *Seed, /* i/o: random generator seed */ - int16_t *prev_flag, /* i/o: attenu flag of last frame */ - int16_t prev_coder_type /* i : coding type of last frame */ -); - -void SWB_BWE_decoding( - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - float *SWB_fenv, /* i/o: SWB frequency envelopes */ - float *SWB_signal, /* o : SWB signal in MDCT domain */ - const int16_t SWB_flength, /* i : Length of input/output */ - const int16_t mode, /* i : classification for SWB signal */ - int16_t *frica_flag, /* o : fricative signal flag */ - float *prev_Energy, /* i/o: energy for last frame */ - float *prev_SWB_fenv, /* i/o: envelope for last frame */ - int16_t *prev_L_swb_norm, /* i/o: length for last frame wb norm */ - const float tilt_nb, /* i : tilt of synthesis wb signal */ - int16_t *Seed, /* i/o: random generator seed */ - const int16_t st_offset, /* i : offset value due to different core */ - float *prev_weight, /* i/o: excitation weight value of last frame */ - const int16_t extl, /* i : extension layer */ - const int16_t last_extl /* i : extension layer of last frame */ -); - -void CNG_reset_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors, /* o : voicing factors */ - int16_t VBR_cng_reset_flag ); - -/*! r: stability flag */ -uint16_t a2rc( - const float *a, /* i : LPC coefficients */ - float *refl, /* o : Reflection co-efficients */ - const int16_t lpcorder /* i : LPC order */ -); - - -void analy_sp( - const int16_t element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int32_t input_Fs, /* i : input sampling rate */ - float *speech, /* i : speech buffer */ - float *Bin_E, /* o : per bin log energy spectrum */ - float *Bin_E_old, /* o : per bin log energy spectrum for mid-frame */ - float *fr_bands, /* o : per band energy spectrum (2 analyses) */ - float lf_E[], /* o : per bin E for first VOIC_BINS bins (without DC) */ - float *Etot, /* o : total input energy */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *band_ener, /* o : energy in critical frequency bands without minimum noise floor E_MIN */ - float *PS, /* o : Per bin energy spectrum */ - float *fft_buff /* o : FFT coefficients */ -); - -void CNG_enc( - Encoder_State *st, /* i/o: State structure */ - float Aq[], /* o : LP coefficients */ - const float *speech, /* i : pointer to current frame input speech buffer */ - float enr, /* i : frame energy output from Levinson recursion */ - const float *lsp_mid, /* i : mid frame LSPs */ - float *lsp_new, /* i/o: current frame LSPs */ - float *lsf_new, /* i/o: current frame LSFs */ - int16_t *allow_cn_step, /* o : allow CN step */ - float *q_env, - int16_t *sid_bw ); - -void swb_CNG_enc( - Encoder_State *st, /* i/o: State structure */ - const float *shb_speech, /* i : SHB target signal (6-14kHz) at 16kHz */ - const float *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz */ -); - -void lsf_enc( - Encoder_State *st, /* i/o: state structure */ - float *lsf_new, /* o : quantized LSF vector */ - float *lsp_new, /* i/o: LSP vector to quantize/quantized */ - float *lsp_mid, /* i : mid-frame LSP vector */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const int16_t GSC_IVAS_mode, /* i : GSC IVAS mode */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void isf_enc_amr_wb( - Encoder_State *st, /* i/o: state structure */ - float *isf_new, /* o : quantized ISF vector */ - float *isp_new, /* i/o: ISP vector to quantize/quantized */ - float *Aq /* o : quantized A(z) for 4 subframes */ -); - -void find_targets( - const float *speech, /* i : pointer to the speech frame */ - const float *mem_syn, /* i : memory of the synthesis filter */ - const int16_t i_subfr, /* i : subframe index */ - float *mem_w0, /* i/o: weighting filter denominator memory */ - const float *p_Aq, /* i : interpolated quantized A(z) filter */ - const float *res, /* i : residual signal */ - const int16_t L_subfr, /* i : length of vectors for gain quantization */ - const float *Ap, /* i : unquantized A(z) filter with bandwidth expansion */ - const float tilt_fac, /* i : tilt factor */ - float *xn, /* o : Close-loop Pitch search target vector */ - float *cn, /* o : target vector in residual domain */ - float *h1 /* o : impulse response of weighted synthesis filter */ -); - -Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ - const Word16 pos1, /* i: position of the pulse 1 */ - const Word16 pos2, /* i: position of the pulse 2 */ - const Word16 N /* i: number of bits FOR position */ -); -void find_tilt( - const float fr_bands[], /* i : energy in frequency bands */ - const float bckr[], /* i : per band background noise energy estimate */ - float ee[2], /* o : lf/hf E ration for present frame */ - const int16_t pitch[3], /* i : open loop pitch values for 3 half-frames */ - const float voicing[3], /* i : normalized correlation for 3 half-frames */ - const float *lf_E, /* i : per bin energy for low frequencies */ - const float corr_shift, /* i : normalized correlation correction */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t max_band, /* i : maximum critical band */ - float hp_E[], /* o : energy in HF */ - const int16_t codec_mode, /* i : Mode 1 or 2 */ - float *bckr_tilt_lt, /* i/o: lf/hf E ratio of background noise */ - int16_t Opt_vbr_mode ); - -void init_gp_clip( - float mem[] /* o : memory of gain of pitch clipping algorithm */ -); - -int16_t gp_clip( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float *voicing, /* i : normalized correlations (from OL pitch) */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t coder_type, /* i : coding type */ - const float xn[], /* i : target vector */ - float mem[] /* i/o: memory of gain of pitch clipping algorithm */ -); - -void gp_clip_test_lsf( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float lsf[], /* i : LSF vector */ - float mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - -void gp_clip_test_gain_pit( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float gain_pit, /* i : gain of quantized pitch */ - float mem[] /* i/o: memory of gain of pitch clipping algorithm */ -); - -void analy_lp( - const float speech[], /* i : pointer to the denoised speech frame */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_look, /* i : look-ahead length */ - float *ener, /* o : residual signal energy */ - float A[], /* o : A(z) filter coefficients */ - float epsP[], /* o : LP analysis residual energies for each iteration */ - float lsp_new[], /* o : current frame ISPs */ - float lsp_mid[], /* o : current mid-frame ISPs */ - float lsp_old[], /* i/o: previous frame unquantized ISPs */ - const int16_t Top[2], /* i : open loop pitch lag */ - const float Tnc[2], /* i : open loop pitch gain */ - const int32_t sr_core, /* i : internal sampling rate */ - const int16_t sec_chan_low_rate /* i : TD secondary channel flag */ -); - -void analy_lp_AMR_WB( - const float speech[], /* i : pointer to the speech frame */ - float *ener, /* o : residual energy from Levinson-Durbin */ - float A[], /* o : A(z) filter coefficients */ - float epsP[], /* o : LP analysis residual energies for each iteration */ - float isp_new[], /* o : current frame ISPs */ - float isp_old[], /* i/o: previous frame unquantized ISPs */ - float isf_new[], /* o : current frame ISFs */ - const int16_t Top, /* i : open loop pitch lag */ - const float Tnc /* i : open loop pitch gain */ -); - -void noise_est_init( - NOISE_EST_HANDLE hNoiseEst /* i/o: Noise estimation handle */ -); - -void speech_music_clas_init( - SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */ -); - -void long_enr( - Encoder_State *st, /* i/o: encoder state structure */ - const float Etot, /* i : total channel energy */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ - FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[] /* i : total channel energy LR channels */ -); - -void noise_est_pre( - const float Etot, /* i : Energy of current frame */ - const int16_t ini_frame, /* i : Frame number (init) */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation data handle */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t last_element_mode /* i : last element mode */ -); - -void noise_est_down( - const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ - float bckr[], /* i/o: per band background noise energy estimate */ - float tmpN[], /* o : temporary noise update */ - float enr[], /* o : averaged energy over both subframes */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *totalNoise, /* o : noise estimate over all critical bands */ - const float Etot, /* i : Energy of current frame */ - float *Etot_last, /* i/o: Energy of last frame */ - float *Etot_v_h2 /* i/o: Energy variaions of noise frames */ -); - -void noise_est( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t old_pitch1, /* i : previous frame OL pitch[1] */ - const float tmpN[], /* i : temporary noise update */ - const float *epsP, /* i : LP prediction error energies */ - const float Etot, /* i : total channel E */ - const float relE, /* i : relative frame energy */ - const float corr_shift, /* i : normalized correlation correction */ - const float enr[], /* i : averaged energy over both subframes */ - float fr_bands[], /* i : spectrum per critical bands of the current frame */ - float *cor_map_sum, /* o : sum of correlation map from mult-harm analysis */ - float *ncharX, /* o : noise character for sp/mus classifier */ - float *sp_div, /* o : soectral diversity feature */ - float *non_staX, /* o : non-stationarity for sp/mus classifier */ - int16_t *loc_harm, /* o : multi-harmonicity flag for UV classifier */ - const float *lf_E, /* i : per bin energy for low frequencies */ - int16_t *st_harm_cor_cnt, /* i : 1st harm correlation timer */ - const float Etot_l_lp, /* i : Smoothed low energy */ - float *sp_floor, /* o : noise floor estimate */ - float S_map[], /* o : short-term correlation map */ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ - const int16_t ini_frame /* i : Frame number (init) */ -); - -void vad_param_updt( - Encoder_State *st, /* i/o: encoder state structure */ - const float corr_shift, /* i : correlation shift */ - const float corr_shiftR, /* i : correlation shift right channel */ - const float A[], /* i : A(z) unquantized for the 4 subframes */ - const int16_t old_pitch1, /* i : previous frame OL pitch[1] */ - FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const int16_t n_channels /* i : number of channels */ -); - - -void lp_gain_updt( - const int16_t i_subfr, /* i : subframe number */ - const float gain_pit, /* i : Decoded gain pitch */ - const float norm_gain_code, /* i : Normalised gain code */ - float *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) */ - float *lp_gainc, /* i/o: LP-filtered code gain (FEC) */ - const int16_t L_frame /* i : length of the frame */ -); - -void GSC_enc_init( - GSC_ENC_HANDLE hGSCEnc /* i/o: GSC data handle */ -); - - -/*! r: index of the last band where pitch contribution is significant */ -int16_t Pit_exc_contribution_len( - Encoder_State *st, /* i/o: state structure */ - const float *dct_res, /* i : DCT of residual */ - float *dct_pitex, /* i/o: DCT of pitch contribution */ - float *pitch_buf, /* i/o: Pitch per subframe */ - int16_t *hangover /* i : Hangover for the time contribution switching */ -); - -int16_t stab_est( - float etot, /* i : Total energy of the current frame */ - float *lt_diff_etot, /* i/o: Long term total energy variation */ - float *mem_etot, /* i/o: Total energy memory */ - int16_t *nb_thr_3, /* i/o: Number of consecutives frames of level 3 */ - int16_t *nb_thr_1, /* i/o: Number of consecutives frames of level 1 */ - float *thresh, /* i/o: Detection thresold */ - int16_t *last_music_flag, /* i/o: Previous music detection ouptut */ - const int16_t vad_flag /* i : VAD flag */ -); - -float gsc_gainQ( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const float y_gain4[], /* i : gain per band */ - float y_gainQ[], /* o : quantized gain per band */ - const int32_t core_brate, /* i : Core rate */ - const int16_t coder_type, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t L_frame, /* i : frame length */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int32_t core_brate_inp /* i : true core brate */ -); - -void Comp_and_apply_gain( - float exc_diffQ[], /* i/o: gain per band */ - float Ener_per_bd_iQ[], /* o : Quant Ener per band */ - float Ener_per_bd_yQ[], /* o : Ener per band for quantize y */ - int16_t Mbands_gn, /* i : number of bands */ - const int16_t ReUseGain /* i : Reuse the gain in Ener_per_bd_yQ */ -); - -void bands_and_bit_alloc_ivas_fx( - const Word16 cor_strong_limit, /* i : HF correlation */ - const Word16 noise_lev, /* i : dwn scaling factor */ - const Word32 core_brate, /* i : core bit rate */ - const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ - const Word16 bits_used, /* i : Number of bit used before frequency Q */ - Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ - const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ - Word16 *max_ener_band, /* o : Sorted order */ - Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ - Word16 *nb_subbands, /* o : Number of subband allowed */ - const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ - Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ - Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ - const Word16 coder_type, /* i : coding type */ - const Word16 bwidth, /* i : input signal bandwidth */ - const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ - const Word16 L_frame, /* i : frame length */ - const Word16 element_mode, /* i : element mode */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ -); - -void GSC_dec_init_ivas( - GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ -); - -void decod_audio( - Decoder_State *st, /* i/o: decoder static memory */ - float dct_epit[], /* o : GSC excitation in DCT domain */ - const float *Aq, /* i : LP filter coefficient */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc_dct_in, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *lsf_new, /* i : current frame ISF vector */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reuse flag */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void gsc_dec( - Decoder_State *st, /* i/o: State structure */ - float exc_dct_in[], /* i/o: dct of pitch-only/total excitation */ - const int16_t pit_band_idx, /* i : pitch band index */ - const int16_t Diff_len, /* i : */ - const int16_t bits_used, /* i : total number of bits used */ - const int16_t nb_subfr, /* i : Number of subframe considered */ - const int16_t coder_type, /* i : coding type */ - int16_t *last_bin, /* i : last bin of bit allocation */ - const float *lsf_new, /* i : ISFs at the end of the frame */ - float *exc_wo_nf, /* o : excitation (in f domain) without noisefill*/ - float *tmp_noise /* o : long-term noise energy */ -); - -void dec_pit_exc( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *code, /* o : innovation */ - float *exc, /* i/o: adapt. excitation exc */ - const int16_t nb_subfr, /* i : Number of subframe considered */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void music_postfilt_init_flt( - MUSIC_POSTFILT_HANDLE hMusicPF /* i/o: LD music postfilter handle */ -); - -void LD_music_post_filter( - MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ - const float dtc_in[], /* i : input synthesis */ - float dtc_out[], /* o : output synthesis */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t coder_type, /* i : Coder type : -1 in case of IO */ - const int16_t Last_coder_type /* i : last Coder type */ -); - -void Post_music_postP( - float dct_buffer_in[], /* i/o: excitation buffer */ - float exc_buffer_out[], /* o : DCT output buffer */ - float *exc2, /* i/o: Current excitation to be overwriten */ - const float *mem_tmp, /* i : previous frame synthesis memory */ - float *st_mem_syn2, /* i/o: current frame synthesis memory */ - const float *Aq, /* i : LPC filter coefficients */ - float *syn /* i/o: 12k8 synthesis */ -); - -void Prep_music_postP( - float exc_buffer_in[], /* i/o: excitation buffer */ - float dct_buffer_out[], /* o : DCT output buffer */ - float filt_lfE[], /* i/o: long term spectrum energy */ - const int16_t last_core, /* i : last core */ - const float *pitch_buf, /* i : current frame pitch information */ - float *LDm_enh_lp_gbin /* o : smoothed suppression gain, per bin FFT */ -); - -void speech_music_classif( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_inp, /* i : new input signal */ - const float *inp, /* i : input signal to locate attach position */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const float lsp_new[M], /* i : LSPs in current frame */ - const float cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.) */ - const float epsP[M + 1], /* i : LP prediciton error */ - const float PS[], /* i : energy spectrum */ - const float Etot, /* i : total frame energy */ - const float old_cor, /* i : max correlation from previous frame */ - int16_t *attack_flag, /* o : attack flag (GSC or TC) */ - const float non_staX, /* i : unbound non-stationarity for sp/mus classifier */ - const float relE, /* i : relative frame energy */ - int16_t *high_lpn_flag, /* o : sp/mus LPN flag */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); -void ivas_find_wsp_fx( - const Word16 L_frame, /* i : length of the frame Q0*/ - const Word16 L_subfr, /* i : length of subframe Q0*/ - const Word16 nb_subfr, /* i : number of subframes Q0*/ - const Word16 *A_fx, - /* i : A(z) filter coefficients */ // Q12 - Word16 *Aw_fx, - /* o : weighted A(z) filter coefficients */ // Q12 - const Word16 *speech_fx, - /* i : pointer to the denoised speech frame */ // Q_new - const Word16 tilt_fact, - /* i : tilt factor */ // Q15 - Word16 *wsp_fx, - /* o : poitnter to the weighted speech frame */ // Q_new - Word16 *mem_wsp_fx, - /* i/o: W(Z) denominator memory */ // Q_new - const Word16 gamma, - /* i : weighting factor */ // Q15 - const Word16 L_look /* i : look-ahead Q0*/ -); - -void gain_enc_amr_wb( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const int32_t core_brate, /* i : core bitrate */ - float *gain_pit, /* i/o: Pitch gain / Quantized pitch gain */ - float *gain_code, /* o : Quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - float *past_qua_en /* i/o: gain quantization memory (4 words) */ -); - -void gain_enc_lbr( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe index */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const int16_t L_subfr /* i : subfr Lenght */ -); - -void gain_enc_mless( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t element_mode, /* i : element mode */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain /* i : gain pitch clipping flag (1 = clipping) */ -); - -void gain_enc_SQ( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t i_subfr, /* i : subframe index */ - const float *xn, /* i : target vector */ - const float *yy1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain /* i : gain pitch clipping flag (1 = clipping) */ -); - -/*! r: Return index of quantization */ -int16_t gain_enc_gaus( - float *gain, /* i/o: Code gain to quantize */ - const int16_t bits, /* i : number of bits to quantize */ - const float lowBound, /* i : lower bound of quantizer (dB) */ - const float topBound /* i : upper bound of quantizer (dB) */ -); - -void E_corr_xy2( - const float xn[], /* i : target vector */ - const float y1[], /* i : filtered excitation components 1 */ - const float y2[], /* i : filtered excitation components 2 */ - float g_corr[], /* o : correlations between x, y1, y2, y3, y4 */ - const int16_t L_subfr /* i : subframe size */ -); - - -/*! r: coding type */ -int16_t find_uv( - Encoder_State *st, /* i/o: encoder state structure */ - const float *pitch_fr, /* i : pointer to adjusted fractional pitch (4 val.) */ - const float *voicing_fr, /* i : refined correlation for each subframes */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float *ee, /* i : lf/hf Energy ratio for present frame */ - float *dE1X, /* o : sudden energy increase for S/M classifier */ - const float corr_shift, /* i : normalized correlation correction in noise */ - const float relE, /* i : relative frame energy */ - const float Etot, /* i : total energy */ - const float hp_E[], /* i : energy in HF */ - int16_t *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ - const int16_t last_core_orig, /* i : original last core */ - STEREO_CLASSIF_HANDLE hStereoClf /* i/o: stereo classifier structure */ -); - -/*! r: classification for current frames */ -int16_t signal_clas( - Encoder_State *st, /* i/o: encoder state structure */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float *ee, /* i : lf/hf E ration for 2 half-frames */ - const float relE, /* i : frame relative E to the long term average */ - const int16_t L_look, /* i : look-ahead */ - int16_t *clas_mod /* o : class flag for NOOP detection */ -); - -void select_TC( - const int16_t codec_mode, /* i : codec mode */ - const int16_t tc_cnt, /* i : TC frame counter */ - int16_t *coder_type, /* i/o: coder type */ - const int16_t localVAD /* i : VAD without hangover */ -); - - -void wb_vad_init( - VAD_HANDLE hVAD /* i/o: VAD data handle */ -); - -int16_t dtx_hangover_addition( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t vad_flag, /* i : VAD flag */ - const float snr, /* i : input single SNR estimate */ - const int16_t cldfb_subtraction, /* i : */ - int16_t *vad_hover_flag, /* o : VAD hangover flag */ - VAD_HANDLE hVAD, /* i/o: VAD handle for L or R channel */ - NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ - int16_t *rem_dtx_ho /* o : Expected remaining hangover frames */ -); - -int16_t wb_vad( - Encoder_State *st, /* i/o: encoder state structure */ - const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ - int16_t *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */ - int16_t *clean_speech_HO, /* o : SC-VBR clean speech HO flag */ - int16_t *NB_speech_HO, /* o : SC-VBR NB speech HO flag */ - float *snr_sum_he, /* i : voicing metric from SAD */ - int16_t *localVAD_HE_SAD, /* o : HE_SAD decision without hangovers */ - int16_t *flag_noisy_speech_snr, /* o : */ - VAD_HANDLE hVAD, /* i/o: VAD handle */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ - float lp_speech, /* i : long term active speech energy average */ - float lp_noise /* i : long term noise energy */ -); - -void bw_detect( - Encoder_State *st, /* i/o: Encoder State */ - const float signal_in[], /* i : input signal */ - float *spectrum, /* i : MDCT spectrum */ - const float *enerBuffer, /* i : energy buffer */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ -); - -void set_bw( - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - Encoder_State *st, /* i/o: Encoder State */ - const int16_t codec_mode /* i : codec mode */ -); - -float gaus_encode( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - const float *h1, /* i : weighted filter input response */ - const float *xn, /* i : target vector */ - float *exc, /* o : pointer to excitation signal frame */ - float *mem_w0, /* o : weighting filter denominator memory */ - float *gp_clip_mem, /* o : memory of gain of pitch clipping algorithm */ - float *tilt_code, /* o : synthesis excitation spectrum tilt */ - float *code, /* o : algebraic excitation */ - float *gain_code, /* o : Code gain. */ - float *y2, /* o : zero-memory filtered adaptive excitation */ - float *gain_inov, /* o : innovation gain */ - float *voice_fac, /* o : voicing factor */ - float *gain_pit, /* o : adaptive excitation gain */ - float *norm_gain_code /* o : normalized innovative cb. gain */ -); - -void td_cng_enc_init( - TD_CNG_ENC_HANDLE hTdCngEnc, /* i/o: DTX/TD CNG data handle */ - const int16_t Opt_DTX_ON, /* i : flag indicating DTX operation */ - const int16_t max_bwidth /* i : maximum encoded bandwidth */ -); - -void dtx( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t vad, /* i : VAD flag for DTX */ - const float speech[] /* i : Pointer to the speech frame */ -); - -void dtx_hangover_control( - Encoder_State *st, /* i/o: encoder state structure */ - const float lsp_new[M] /* i : current frame LSPs */ -); - - -void updt_enc_common( - Encoder_State *st /* i/o: encoder state structure */ -); - -void updt_IO_switch_enc( - Encoder_State *st, /* i/o: state structure */ - const int16_t input_frame /* i : input frame length */ -); - -void transition_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - int16_t *tc_subfr, /* i/o: TC subframe index */ - int16_t *Jopt_flag, /* i : joint optimization flag */ - int16_t *position, /* i/o: maximum of residual signal index */ - int16_t *T0, /* i/o: close loop integer pitch */ - int16_t *T0_frac, /* i/o: close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: lower limit for close-loop search */ - int16_t *T0_max, /* i/o: higher limit for close-loop search */ - float *exc, /* i/o: pointer to excitation signal frame */ - float *y1, /* o : zero-memory filtered adaptive excitation */ - const float *h1, /* i : weighted filter input response */ - const float *xn, /* i : target vector */ - float *xn2, /* o : target vector for innovation search */ - float *gp_cl, /* i/o: memory of gain of pitch clipping algorithm */ - float *gain_pit, /* o : adaptive excitation gain */ - float *g_corr, /* o : ACELP correlation values */ - int16_t *clip_gain, /* i/o: adaptive gain clipping flag */ - float **pt_pitch, /* o : floating pitch values */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits /* i/o: unused bits */ -); - -void tc_classif_enc( - const int16_t L_frame, /* i : length of the frame */ - int16_t *tc_subfr, /* i/o: TC subframe index */ - int16_t *position, /* i/o: maximum of residual signal index */ - const int16_t attack_flag, /* i : attack flag */ - const int16_t pitch, /* i : open loop pitch estimates for first halfframe */ - const float *res /* i : pointer to the LP residual signal frame */ -); - - -void gain_enc_tc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t i_subfr, /* i : subframe index */ - const float xn[], /* i : target vector */ - const float y2[], /* i : zero-memory filtered algebraic codebook excitation */ - const float code[], /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : pitch gain / Quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - - -/*! r: comfort noise gain factor */ -float AVQ_cod( - const float xri[], /* i : vector to quantize */ - int16_t xriq[], /* o : quantized normalized vector (assuming the bit budget is enough) */ - const int16_t nb_bits, /* i : number of allocated bits */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void AVQ_encmux( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t extl, /* i : extension layer */ - int16_t xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ - int16_t *nb_bits, /* i/o: number of allocated bits */ - const int16_t Nsv, /* i : number of subvectors */ - int16_t nq[], /* o : AVQ nq index */ - int16_t avq_bit_sFlag, /* i : flag indicating AVQ bit savings */ - int16_t trgtSvPos /* i : target SV for AVQ bit savings */ -); - -void ordr_esti( - const int16_t k, /* i : sub-vector index */ - int16_t *Mpos, /* i/o: dominant sub-vector position from ACV */ - int16_t svOrder[], /* i/o: AVQ sub-vector order */ - const int16_t Nsv /* i : total sub-vectors in a sub-frames */ -); - -void re8_cod( - int16_t x[], /* i : point in RE8 (8-dimensional integer vector) */ - int16_t *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ - uint16_t *I, /* o : index of c (pointer to unsigned 16-bit word) */ - int16_t k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index */ -); - -void pre_exc( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : frame length */ - const float *speech, /* i : input speech */ - const float *p_Aq, /* i : 12k8 Lp coefficient */ - const float *p_A, /* i : unquantized A(q) filter with bandwidth expansion */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : current sub frame indicator */ - float *Ap, /* o : weighted LP filter coefficients */ - const float *res, /* i : residual signal */ - float *h1, /* o : impulse response of weighted synthesis filter */ - float *xn, /* o : close-loop Pitch search target vector */ - float *cn, /* o : target vector in residual domain */ - float *mem_syn, /* i/o: memory of the synthesis filter */ - float *mem_w0, /* i/o: weighting filter denominator memory */ - const int16_t L_subfr /* i : subframe length */ -); - - -void encod_amr_wb( - Encoder_State *st, /* i/o: state structure */ - const float speech[], /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float Aq[], /* i : 12k8 Lp coefficient */ - const float *res, /* i : residual signal */ - float *syn, /* i/o: core synthesis */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - int16_t hf_gain[NB_SUBFR], /* o : decoded HF gain */ - const float *speech16k /* i : input speech @16kHz */ -); - -void stat_noise_uv_enc( - Encoder_State *st, /* i/o: state structure */ - const float *epsP, /* i : LP prediction errors */ - const float *isp_new, /* i : immittance spectral pairs at 4th sfr */ - const float *isp_mid, /* i : immittance spectral pairs at 2nd sfr */ - float *Aq, /* i/o: A(z) quantized for the 4 subframes */ - float *exc2, /* i/o: excitation buffer */ - const int16_t uc_two_stage_flag /* o : flag undicating two-stage UC */ -); - -void re8_compute_base_index( - const int16_t *x, /* i : Elemen of Q2, Q3 or Q4 */ - const int16_t ka, /* i : Identifier of the absolute leader related to x */ - uint16_t *I /* o : index */ -); - -void transf_cdbk_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const int16_t i_subfr, /* i : subframe index */ - float cn[], /* i/o: target vector in residual domain */ - float exc[], /* i/o: pointer to excitation signal frame */ - const float *p_Aq, /* i : 12k8 Lp coefficient */ - const float Ap[], /* i : weighted LP filter coefficients */ - const float h1[], /* i : weighted filter input response */ - float xn[], /* i/o: target vector */ - float xn2[], /* i/o: target vector for innovation search */ - float y1[], /* i/o: zero-memory filtered adaptive excitation */ - const float y2[], /* i : zero-memory filtered innovative excitation */ - const float Es_pred, /* i : predicited scaled innovation energy */ - float *gain_pit, /* i/o: adaptive excitation gain */ - const float gain_code, /* i : innovative excitation gain */ - float g_corr[], /* o : ACELP correlation values */ - const int16_t clip_gain, /* i : adaptive gain clipping flag */ - float *gain_preQ, /* o : prequantizer excitation gain */ - float code_preQ[], /* o : prequantizer excitation */ - int16_t *unbits /* i/o: number of AVQ unused bits */ -); -void deemph_lpc( - float *p_Aq_cuerr, /* i : LP coefficients current frame */ - float *p_Aq_old, /* i : LP coefficients previous frame */ - float *LPC_de_curr, /* o : De-emphasized LP coefficients current frame */ - float *LPC_de_old, /* o : De-emphasized LP coefficients previous frame*/ - const int16_t deemph_old ); - -void Interpol_delay( - float *out, /* o : pitch interpolation output */ - float *last, /* i : last frame pitch lag */ - float *current, /* i : current frame pitch lag */ - int16_t SubNum, /* i : subframe number */ - const float *frac /* i : interpolation constant */ -); - -void dequantize_uvg( - int16_t iG1, /* i : gain 1 index */ - int16_t *iG2, /* i : gain 2 index */ - float *G, /* o : quantized gain */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void generate_nelp_excitation( - int16_t *seed, /* i/o: random number seed */ - float *Gains, /* i : excitation gains */ - float *output, /* o : excitation output */ - float gain_fac /* i : gain factor */ -); - -void nelp_encoder( - Encoder_State *st, /* i/o: encoder state */ - float *in, /* i : residual signal */ - float *exc, /* o : NELP quantized excitation signal */ - const int16_t reduce_gains ); - -void encod_nelp( - Encoder_State *st, /* i/o: state structure */ - const float *speech, /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float *Aq, /* i : 12k8 Lp coefficient */ - float *res, /* o : residual signal */ - float *synth, /* o : core synthesis */ - float *tmp_noise, /* o : long-term noise energy */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void realft( - float *data, /* i/o: data array */ - int16_t n, /* i : length of data array */ - int16_t isign /* i : sign +1 or -1 */ -); - -ivas_error DTFS_new( - DTFS_STRUCTURE **dtfs_out ); - -void DTFS_copy( - DTFS_STRUCTURE *Xout, /* o : DTFS */ - DTFS_STRUCTURE Xinp /* i : DTFS */ -); - -void DTFS_sub( - DTFS_STRUCTURE *tmp, /* o : output DFTS */ - DTFS_STRUCTURE X1, /* i : DTFS input 1 */ - DTFS_STRUCTURE X2 /* i : DTFS input 2 */ -); - -void DTFS_to_fs( - const float *x, /* i : Time domain signal */ - const int16_t N, /* i : Length of input vector */ - DTFS_STRUCTURE *X, /* o : DTFS structure with a, b, lag */ - const int32_t sampling_rate, - const int16_t FR_flag /* i : FR flag */ -); - -void DTFS_fs_inv( - DTFS_STRUCTURE *X, /* i : DTFS */ - float *x, /* o : time domain sig */ - const int16_t N, /* i : Output length */ - float ph0 /* i : Input phase */ -); - -void DTFS_car2pol( - DTFS_STRUCTURE *X /* i/o: DTFS structure a, b, lag */ - /* input in Cartesion, output in Polar */ -); - -void DTFS_pol2car( - DTFS_STRUCTURE *X /* i/o: DTFS structure a, b, lag */ - /* input in Polar, output in Cartesian */ -); - -/*! r: Return Input RMS between f1/f2 b4 scaling */ -float DTFS_setEngyHarm( - float f1, /* i : lower band freq of input to control energy */ - float f2, /* i : upper band freq of input to control energy */ - float g1, /* i : lower band freq of output to control energy */ - float g2, /* i : upper band freq of output to control energy */ - float en2, /* i : Target Energy to set the DTFS to */ - DTFS_STRUCTURE *X /* i/o: DTFS to adjust the energy of */ -); - -void DTFS_to_erb( - DTFS_STRUCTURE X, /* i : DTFS input */ - float *out /* o : ERB output */ -); - -void DTFS_zeroPadd( - const int16_t N, /* i : Target lag */ - DTFS_STRUCTURE *X /* i/o: DTFS */ -); - -/*! r: Energy */ -float DTFS_getEngy( - DTFS_STRUCTURE X /* i : DTFS to compute energy of */ -); - -void DTFS_adjustLag( - DTFS_STRUCTURE *X_DTFS, /* i/o: DTFS to adjust lag for */ - const int16_t N /* i : Target lag */ -); - -void DTFS_poleFilter( - DTFS_STRUCTURE *X, /* i/o: DTFS to poleFilter inplace */ - const float *LPC, /* i : LPCs */ - const int16_t N /* i : LPCORDER */ -); - -void DTFS_zeroFilter( - DTFS_STRUCTURE *X, /* i/o: DTFS to zeroFilter inplace */ - const float *LPC, /* i : LPCs */ - const int16_t N /* i : LPCORDER */ -); - -float DTFS_alignment_full( - DTFS_STRUCTURE X1_DTFS, /* i : reference DTFS */ - DTFS_STRUCTURE X2_DTFS, /* i : DTFS to shift */ - const int16_t num_steps /* i : resolution */ -); - -void DTFS_phaseShift( - DTFS_STRUCTURE *X, /* i : DTFS to shift */ - float ph /* i : phase to shift */ -); - -void erb_add( - float *curr_erb, /* i/o: current ERB */ - const int16_t l, /* i : current lag */ - const float *prev_erb, /* i : previous ERB */ - const int16_t pl, /* i : previous lag */ - const int16_t *index, /* i : ERB index */ - const int16_t num_erb /* i : number of ERBs */ -); - -void erb_slot( - int16_t lag, /* i : input lag */ - int16_t *out, /* o : ERB slots */ - float *mfreq, /* i : ERB frequencies */ - int16_t num_erb /* i : number of ERBs */ -); - -void erb_diff( - const float *prev_erb, /* i : previous ERB */ - const int16_t pl, /* i : previous lag */ - const float *curr_erb, /* i : current ERB */ - const int16_t l, /* i : current lag */ - const float *curr_lsp, /* i : current LSP coefficients */ - float *out, /* o : ERB difference */ - int16_t *index, /* i : ERB index */ - const int16_t num_erb /* i : Number of ERBs */ -); - -void DTFS_erb_inv( - float *in, /* i : ERB inpt */ - int16_t *slot, /* i : ERB slots filled based on lag */ - float *mfreq, /* i : erb frequence edges */ - DTFS_STRUCTURE *X, /* o : DTFS after erb-inv */ - const int16_t num_erb /* i : Number of ERB bands */ -); - -ivas_error ppp_quarter_encoder( - int16_t *returnFlag, /* o : return value */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - DTFS_STRUCTURE *CURRCW_Q, /* o : Quantized (amp/phase) DTFS */ - DTFS_STRUCTURE *TARGETCW, /* o : DTFS with quant phase but unquant Amp */ - const int16_t prevCW_lag, /* i : previous lag */ - DTFS_STRUCTURE vCURRCW_NQ, /* i : Unquantized DTFS */ - const float *curr_lpc, /* i : LPCS */ - float *lastLgainE, /* i/o: last low band gain */ - float *lastHgainE, /* i/o: last high band gain */ - float *lasterbE, /* i/o: last ERB vector */ - DTFS_STRUCTURE PREV_CW_E /* i : past DTFS */ -); - -ivas_error WIsyn( - DTFS_STRUCTURE PREVCW, /* i : Prev frame DTFS */ - DTFS_STRUCTURE *CURR_CW_DTFS, /* i/o: Curr frame DTFS */ - const float *curr_lpc, /* i : LPC */ - float *ph_offset, /* i/o: Phase offset to line up at end of frame */ - float *out, /* o : Waveform Interpolated time domain signal */ - const int16_t N, /* i : Number of samples of output to generate */ - const int16_t FR_flag /* i : called for post-smoothing in FR */ -); - -void set_ppp_mode( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t noisy_speech_HO, /* i : SC-VBR noisy speech HO flag */ - const int16_t clean_speech_HO, /* i : SC-VBR clean speech HO flag */ - const int16_t NB_speech_HO, /* i : SC-VBR NB speech HO flag */ - const int16_t localVAD_he /* i : HE-SAD flag without hangover */ -); - -ivas_error ppp_voiced_encoder( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - SC_VBR_ENC_HANDLE hSC_VBR, /* i/o: SC-VBR state structure */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t last_coder_type_raw, /* i : raw last_coder_type */ - const float old_pitch_buf[], /* i : buffer of old subframe pitch values */ - float *in, /* i : residual signal */ - float *out, /* o : Quantized residual signal */ - const int16_t delay, /* i : open loop pitch */ - float *lpc1, /* i : prev frame de-emphasized LPC */ - float *lpc2, /* i : current frame de-emphasized LPC */ - float *exc, /* i : previous frame quantized excitation */ - float *pitch /* o : floating pitch values for each subframe */ -); - -ivas_error encod_ppp( - Encoder_State *st, /* i/o: state structure */ - const float speech[], /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float Aq[], /* i : 12k8 Lp coefficient */ - float *res, /* i/o: residual signal */ - float *synth, /* i/o: core synthesis */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void reset_rf_indices( - RF_ENC_HANDLE hRF, /* i/o: RF state structure */ - const int16_t L_frame, /* i : frame length */ - int16_t *rf_target_bits_write ); - -void signaling_enc_rf( - Encoder_State *st /* i/o: encoder state structure */ -); - -ivas_error acelp_core_dec( - Decoder_State *st, /* i/o: Decoder state structure */ - float output[], /* o : synthesis @internal Fs */ - float synth[], /* o : synthesis */ - float save_hb_synth[], /* o : HB synthesis */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - float pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe */ - int16_t *unbits, /* o : number of unused bits */ - int16_t *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const float tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t last_element_mode, /* i : last element mode */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t nchan_out, /* i : number of output channels */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t read_sid_info /* i : read SID info flag */ -); - -void bass_psfilter_init( - BPF_DEC_HANDLE hBPF /* o : BPF data handle */ -); - -void bass_psfilter( - BPF_DEC_HANDLE hBPF, /* o : BPF data handle */ - const int16_t Opt_AMR_WB, /* i : AMR-WB IO flag */ - const float synth_in[], /* i : synthesis (at 16kHz) */ - const int16_t L_frame, /* i : length of the last frame */ - const float pitch_buf[], /* i : pitch for every subfr [0,1,2,3] */ - const int16_t bpf_off, /* i : do not use BPF when set to 1 */ - float v_stab, /* i : stability factor */ - float *v_stab_smooth, /* i : smoothed stability factor */ - const int16_t coder_type, /* i : coder_type */ - float bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ -); - -void CNG_reset_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors /* o : voicing factors */ -); - -void updt_dec( - Decoder_State *st, /* i/o: state structure */ - const float *old_exc, /* i : buffer of excitation */ - const float *pitch_buf, /* i : floating pitch values for each subframe */ - const float Es_pred, /* i : predicited scaled innovation energy */ - const float *Aq, /* i : A(z) quantized for all subframes */ - const float *lsf_new, /* i : current frame LSF vector */ - const float *lsp_new, /* i : current frame LSP vector */ - const float voice_factors[], /* i : voicing factors */ - const float *old_bwe_exc, /* i : buffer of excitation */ - const float *gain_buf /* o : floating pitch gain for each subframe */ -); - -void updt_IO_switch_dec( - const int16_t output_frame, /* i : output frame length */ - Decoder_State *st /* i/o: state structure */ -); - -void updt_dec_common( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t concealWholeFrameTmp, /* i : concealWholeFrameTmp flag */ - const float *synth /* i : decoded synthesis */ -); - -void td_cng_dec_init( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - -void CNG_dec( - Decoder_State *st, /* i/o: State structure */ - const int16_t last_element_mode, /* i : last element mode */ - float Aq[], /* o : LP coefficients */ - float *lsp_new, /* i/o: current frame LSPs */ - float *lsf_new, /* i/o: current frame LSFs */ - int16_t *allow_cn_step, /* o : allow cn step */ - int16_t *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - float *q_env ); - -void swb_CNG_dec( - Decoder_State *st, /* i/o: State structure */ - const float *synth, /* i : ACELP core synthesis at 32kHz */ - float *shb_synth, /* o : high-band CNG synthesis */ - const int16_t sid_bw /* i : 0-NB/WB, 1-SWB SID */ -); - -void lsf_dec( - Decoder_State *st, /* i/o: State structure */ - const int16_t tc_subfr, /* i : TC subframe index */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - int16_t *LSF_Q_prediction, /* o : LSF prediction mode */ - float *lsf_new, /* o : de-quantized LSF vector */ - float *lsp_new, /* o : de-quantized LSP vector */ - float *lsp_mid, /* o : de-quantized mid-frame LSP vector */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void isf_dec_amr_wb( - Decoder_State *st, /* i/o: State structure */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - float *isf_new, /* o : de-quantized ISF vector */ - float *isp_new /* o : de-quantized ISP vector */ -); - -void Es_pred_dec( - float *Es_pred, /* o : predicted scaled innovation energy */ - const int16_t enr_idx, /* i : indice */ - const int16_t nb_bits, /* i : number of bits */ - const int16_t no_ltp /* i : no LTP flag */ -); - -void gaus_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - float *code, /* o : gaussian excitation */ - float *norm_gain_code, /* o : gain of the normalized gaussian excitation */ - float *lp_gainp, /* i/o: lp filtered pitch gain(FER) */ - float *lp_gainc, /* i/o: lp filtered code gain (FER) */ - float *gain_inov, /* o : unscaled innovation gain */ - float *tilt_code, /* o : synthesis excitation spectrum tilt */ - float *voice_fac, /* o : estimated voicing factor */ - float *gain_pit, /* o : reset pitch gain */ - float *pt_pitch, /* o : reset floating pitch buffer */ - float *exc, /* o : excitation signal frame */ - float *gain_code, /* o : gain of the gaussian excitation */ - float *exc2 /* o : scaled excitation signal frame */ -); - -void gain_dec_amr_wb( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *past_qua_en, /* i/o: gain quantization memory (4 words) */ - float *gain_inov, /* o : unscaled innovation gain */ - const float *code, /* i : algebraic code excitation */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -void gain_dec_lbr( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe index */ - const float *code, /* i : algebraic excitation */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ - const int16_t L_subfr /* i : subframe length */ -); - -void gain_dec_mless( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe number */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *code, /* i : algebraic code excitation */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -void gain_dec_SQ( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe number */ - const float *code, /* i : algebraic code excitation */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -/*! r: quantized codebook gain */ -float gain_dec_gaus( - const int16_t index, /* i : quantization index */ - const int16_t bits, /* i : number of bits to quantize */ - const float lowBound, /* i : lower bound of quantizer (dB) */ - const float topBound, /* i : upper bound of quantizer (dB) */ - const float gain_inov, /* i : unscaled innovation gain */ - float *norm_gain_code /* o : gain of normalized gaus. excit. */ -); - -/*! r: floating pitch value */ -float pit_decode_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : length of the frame */ - int16_t i_subfr, /* i : subframe index */ - const int16_t coder_type, /* i : coding type */ - int16_t *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: delta search min for sf 2 & 4 */ - int16_t *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void abs_pit_dec_flt( - const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ - int16_t pitch_index, /* i : pitch index */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac /* o : pitch fraction */ -); - -void delta_pit_dec_flt( - const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ - const int16_t pitch_index, /* i : pitch index */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - const int16_t T0_min /* i : delta search min */ -); - -void pit_Q_dec_flt( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t pitch_index, /* i : pitch index */ - const int16_t nBits, /* i : # of Q bits */ - const int16_t delta, /* i : Half the CL searched interval */ - const int16_t pit_flag, /* i : absolute(0) or delta(1) pitch Q */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_min, /* i/o: delta search min */ - int16_t *T0_max, /* i/o: delta search max */ - int16_t *BER_detect /* o : BER detect flag */ -); - -void pit16k_Q_dec_flt( - const int16_t pitch_index, /* i : pitch index */ - const int16_t nBits, /* i : # of Q bits */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_min, /* i/o: delta search min */ - int16_t *T0_max, /* i/o: delta search max */ - int16_t *BER_detect /* o : BER detect flag */ -); - - -void inov_decode( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const int16_t i_subfr, /* i : subframe index */ - const float *p_Aq, /* i : LP filter coefficients */ - const float tilt_code, /* i : tilt of of the excitation of previous subframe */ - const float pt_pitch, /* i : pointer to current subframe fractional pitch */ - float *code, /* o : algebraic excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void dec_acelp_1t64( - Decoder_State *st, /* i/o: decoder state structure */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void dec_acelp_2t32( - Decoder_State *st, /* i/o: decoder state structure */ - float code[] /* o : algebraic (fixed) codebook excitation */ -); - -void dec_acelp_4t64( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t nbbits, /* i : number of bits per codebook */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - - -void FEC_exc_estim( - Decoder_State *st, /* i/o: Decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - float *old_exc, /* i/o: excitation buffer */ - float *exc2, /* o : excitation buffer (for synthesis) */ - float *exc_dct_in, /* o : GSC excitation in DCT domain */ - float *pitch_buf, /* o : Floating pitch for each subframe */ - float *tmp_tc, /* o : FEC pitch */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - float *lsf_new, /* i : ISFs at the end of the frame */ - float *tmp_noise /* o : long-term noise energy */ -); - -void FEC_lsf2lsp_interp_flt( - Decoder_State *st, /* i/o: Decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - float *Aq, /* o : calculated A(z) for 4 subframes */ - float *lsf, /* o : estimated LSF vector */ - float *lsp /* o : estimated LSP vector */ -); - -void FEC_lsf_estim_enc( - Encoder_State *st, /* i : Encoder static memory */ - float *lsf /* o : estimated LSF vector */ -); - -float frame_energy( - const int16_t L_frame, /* i : length of the frame */ - const float *pitch, /* i : pitch values for each subframe */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float lp_speech, /* i : long term active speech energy average */ - float *frame_ener /* o : pitch-synchronous energy at frame end */ -); - -void FEC_SinOnset( - float *exc, /* i/o: exc vector to modify */ - int16_t puls_pos, /* i : Last pulse position desired */ - int16_t T0, /* i : decoded first frame pitch */ - float enr_q, /* i : energy provided by the encoder */ - float *Aq, /* i : Lsp coefficient */ - const int16_t L_frame /* i : Frame length */ -); - -int16_t FEC_enhACB( - const int16_t L_frame, /* i : Frame length */ - const int16_t last_L_frame, /* i : frame length of last frame */ - float *exc_io, /* i/o: Adaptive codebook memory */ - const int16_t new_pit, /* i : decoded first frame pitch */ - const int16_t puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ - const float bfi_pitch /* i : Pitch used for concealment */ -); - -void FEC_scale_syn( - const int16_t L_frame, /* i : length of the frame */ - int16_t clas, /* i/o: frame classification */ - const int16_t last_good, /* i : last good frame classification */ - float *synth, /* i/o: synthesized speech at Fs = 12k8 Hz */ - const float *pitch, /* i : pitch values for each subframe */ - float enr_old, /* i : energy at the end of prvious frame */ - float enr_q, /* i : transmitted energy for current frame */ - const int16_t coder_type, /* i : coding type */ - const int16_t LSF_Q_prediction, /* i : LSF prediction mode */ - int16_t *scaling_flag, /* i/o: flag to indicate energy control of syn */ - float *lp_ener_FEC_av, /* i/o: averaged voiced signal energy */ - float *lp_ener_FEC_max, /* i/o: averaged voiced signal energy */ - const int16_t bfi, /* i : current frame BFI */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t prev_bfi, /* i : previous frame BFI */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - float *exc, /* i/o: excitation signal without enhancement */ - float *exc2, /* i/o: excitation signal with enhancement */ - const float Aq[], /* i : LP filter coefs */ - float *old_enr_LP, /* i/o: LP filter E of last good voiced frame */ - const float *mem_tmp, /* i : temp. initial synthesis filter states */ - float *mem_syn, /* o : initial synthesis filter states */ - const int16_t avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ - const int16_t force_scaling /* i : force scaling */ -); - -void FEC_pitch_estim( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t last_core, /* i : last core */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t clas, /* i : current frame classification */ - const int16_t last_good, /* i : last good clas information */ - const float pitch_buf[], /* i : Floating pitch for each subframe */ - const float old_pitch_buf[], /* i : buffer of old subframe pitch values */ - float *bfi_pitch, /* i/o: update of the estimated pitch for FEC */ - int16_t *bfi_pitch_frame, /* o : frame length when pitch was updated */ - int16_t *upd_cnt, /* i/o: update counter */ - const int16_t coder_type ); - -void FEC_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i : configuration of the ACELP */ - const float *synth, /* i : pointer to synthesized speech for E computation */ - const int16_t coder_type, /* i : type of coder */ - int16_t clas, /* i : signal clas for current frame */ - const float *fpit, /* i : close loop fractional pitch buffer */ - const float *res, /* i : LP residual signal frame */ - int16_t *last_pulse_pos, /* i/o: Position of the last pulse */ - const int16_t L_frame, /* i : Frame length */ - const int32_t total_brate /* i : total codec bitrate */ -); - -int16_t FEC_pos_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *last_pulse_pos, /* o : Last glottal pulse position in the lost ACB */ - float *enr_q, /* o : Decoded energy */ - const int16_t nBits_es_Pred /* i : number of bits for Es_pred Q */ -); - -void improv_amr_wb_gs( - const int16_t clas, /* i : bitrate allocated to the core */ - const int16_t coder_type, /* i : coder_type */ - const int32_t core_brate, /* i : bitrate allocated to the core */ - int16_t *seed_tcx, /* i/o: Seed used for noise generation */ - float *old_Aq, /* i/o: old LPC filter coefficient */ - float *mem_syn2, /* i/o: synthesis memory */ - const float lt_voice_fac, /* i/o: long term voice factor */ - const int16_t locattack, /* i : Flag for a detected attack */ - float *Aq, /* i/o: Decoded LP filter coefficient */ - float *exc2, /* i/o: Decoded complete excitation */ - float *mem_tmp, /* i/o: synthesis temporary memory */ - float *syn, /* i/o: Decoded synthesis to be updated */ - const float *pitch_buf, /* i : Decoded pitch buffer */ - const float Last_ener, /* i : Last energy */ - const int16_t rate_switching_reset, /* i : rate switching reset flag */ - const int16_t last_coder_type, /* i : Last coder_type */ - const int16_t VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ -); - -int16_t tc_classif( - Decoder_State *st /* i/o: decoder state structure */ -); - -void transition_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t tc_subfr, /* i : TC subframe index */ - int16_t *Jopt_flag, /* i : joint optimization flag */ - float *exc, /* i/o: current frame excitation signal */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: delta search min for sf 2 & 4 */ - int16_t *T0_max, /* i/o: delta search max for sf 2 & 4 */ - float **pt_pitch, /* o : floating pitch values */ - int16_t *position, /* i/o: first glottal impulse position in frame */ - float *bwe_exc /* i/o: excitation for SWB TBE */ -); - -void gain_dec_tc( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe number */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const float *code, /* i : algebraic code excitation */ - float *gain_pit, /* o : pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excit. */ -); - -void stat_noise_uv_dec( - Decoder_State *st, /* i/o: decoder static memory */ - const float *lsp_new, /* i : end-frame LSP vector */ - const float *lsp_mid, /* i : mid-frame LSP vector */ - float *Aq, /* o : A(z) quantized for the 4 subframes */ - float *exc2, /* i/o: excitation buffer */ - const int16_t uc_two_stage_flag /* 1 : flag undicating two-stage UC */ -); - -void sc_vbr_dec_init_flt( - SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */ -); - -void decod_nelp( - Decoder_State *st, /* i/o: decoder static memory */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *exc, /* o : adapt. excitation exc */ - float *exc2, /* o : adapt. excitation/total exc */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* o : excitation for SWB TBE */ - const int16_t bfi, /* i : bad frame indicator */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -void nelp_decoder( - Decoder_State *st, /* i/o: decoder static memory */ - float *exc_nelp, /* o : adapt. excitation/total exc */ - float *exc, /* o : adapt. excitation exc */ - int16_t bfi, /* i : frame error rate */ - const int16_t coder_type, /* i : coding type */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error decod_ppp( - Decoder_State *st, /* i/o: state structure */ - const float Aq[], /* i : 12k8 Lp coefficient */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t bfi /* i : BFI flag */ -); - -ivas_error ppp_quarter_decoder( - Decoder_State *st, /* i/o: decoder state structure */ - DTFS_STRUCTURE *CURRCW_Q_DTFS, /* i/o: Current CW DTFS */ - int16_t prevCW_lag, /* i : Previous lag */ - float *lastLgainD, /* i/o: Last gain lowband */ - float *lastHgainD, /* i/o: Last gain highwband */ - float *lasterbD, /* i/o: Last ERB vector */ - int16_t bfi, /* i : FER flag */ - DTFS_STRUCTURE PREV_CW_D /* i : Previous DTFS */ -); - -ivas_error ppp_voiced_decoder( - Decoder_State *st, /* i/o: state structure */ - float *out, /* o : residual signal */ - const float *lpc2, /* i : current frame LPC */ - float *exc, /* i : previous frame excitation */ - float *pitch, /* o : floating pitch values for each subframe */ - const int16_t bfi /* i : BFI flag */ -); - -void AVQ_demuxdec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t xriq[], /* o : decoded subvectors [0..8*Nsv-1] */ - int16_t *nb_bits, /* i/o: number of allocated bits */ - const int16_t Nsv, /* i : number of subvectors */ - int16_t nq[], /* i/o: AVQ nq index */ - int16_t avq_bit_sFlag, /* i : flag for AVQ bit saving solution*/ - int16_t trgtSvPos /* i : target SV for AVQ bit savings */ -); - - -void Init_post_filter_ivas( - PFSTAT_HANDLE hPFstat /* i : post-filter state memories */ -); - -void nb_post_filt_ivas( - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : sub-frame length */ - PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ - float *lp_noise, /* i/o: long term noise energy */ - const float tmp_noise, /* i : noise energy */ - float *synth, /* i/o: synthesis */ - const float *Aq, /* i : LP filter coefficient */ - const float *pitch_buf, /* i : Floating pitch for each subframe */ - const int16_t coder_type, /* i : coder_type -> deactivated in AUDIO */ - const int16_t BER_detect, /* i : BER detect flag */ - const int16_t disable_hpf /* i : flag to diabled HPF */ -); - -void decod_unvoiced( - Decoder_State *st, /* i/o: decoder static memory */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* o : adapt. excitation exc */ - float *exc2, /* o : adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - float *gain_buf /* o : floating pitch gain for each subfram */ -); - -void decod_tran( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits, /* i/o: number of unused bits */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error decod_gen_voic( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const int16_t do_WI, /* i : FEC fast recovery flag */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits, /* i/o: number of unused bits */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void decod_amr_wb( - Decoder_State *st, /* i/o: decoder static memory */ - const float *Aq, /* i : LP filter coefficients */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - int16_t hf_gain[NB_SUBFR], /* o : decoded HF gain */ - float *voice_factors, /* o : voicing factors */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error init_decoder( - Decoder_State *st, /* o : Decoder static variables structure */ - const int16_t idchan, /* i : channel ID */ - const MC_MODE mc_mode /* i : MC mode */ -); - -void destroy_cldfb_decoder_flt( - Decoder_State *st /* o : Decoder static variables structure */ -); - -void HQ_core_dec_init_flt( - HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ -); - -void HQ_nbfec_init_flt( - HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ -); - -ivas_error evs_dec( - Decoder_State *st, /* i/o: Decoder state structure */ - float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ - float *output, /* o : output synthesis signal */ - FRAME_MODE frameMode /* i : Decoder frame mode */ -); - -void get_next_frame_parameters( - Decoder_State *st /* i/o: Decoder state structure */ -); - -ivas_error amr_wb_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ - float *output /* o : synthesis output */ -); - -void transf_cdbk_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const int16_t i_subfr, /* i : subframe index */ - const float Es_pred, /* i : predicited scaled innovation energy */ - const float gain_code, /* i : innovative excitation gain */ - float *gain_preQ, /* o : prequantizer excitation gain */ - float *norm_gain_preQ, /* o : normalized prequantizer excitation gain */ - float code_preQ[], /* o : prequantizer excitation */ - int16_t *unbits /* o : number of AVQ unused bits */ -); - -/*! r: decoded gain */ -float gain_dequant( - int16_t index, /* i : quantization index */ - const float min_val, /* i : value of lower limit */ - const float max_val, /* i : value of upper limit */ - const int16_t bits /* i : number of bits to dequantize */ -); - -void hq_core_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *audio, /* i : input audio signal */ - const int16_t input_frame, /* i : frame length */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t Voicing_flag, /* i : Voicing flag for FER method selection */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -int16_t detect_transient( - Encoder_State *st, /* i/o: encoder state structure */ - const float *in, /* i : input signal */ - const int16_t L /* i : length */ -); - -void wtda( - const float *new_audio, /* i : input audio */ - float *wtda_audio, /* o : windowed audio */ - float *old_wtda, /* i/o: windowed audio from previous frame */ - const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ - const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t L /* i : length */ -); - -void wtda_ext( - const float *new_audio, /* i : input audio */ - float *wtda_audio, /* o : windowed audio */ - const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ - const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t L, /* i : length */ - const uint16_t kernel_type /* i : transform kernel type (0 - 3) */ -); - -void tcx_get_windows_mode1_flt( - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - float *left_win, /* o : left overlap window */ - float *right_win, /* o : right overlap window */ - float *left_win_int, /* o : left overlap window */ - float *right_win_int, /* o : right overlap window */ - const int16_t L /* i : length */ -); - -void direct_transform( - const float *in32, /* i : input signal */ - float *out32, /* o : output transformation */ - const int16_t is_transient, /* i : transient flag */ - const int16_t L, /* i : length */ - const int16_t element_mode /* i : IVAS element mode */ -); - - -void interleave_spectrum( - float *coefs, /* i/o: input and output coefficients */ - const int16_t length /* i : length of spectrum */ -); - -void hq_hr_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float *coefs, /* i/o: transform-domain coefficients */ - const int16_t length, /* i : length of spectrum */ - int16_t *num_bits, /* i/o: number of available bits */ - const int16_t is_transient, /* i : transient flag */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void huff_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : Number of codewords to decode */ - const int16_t buffer_len, /* i : Number of bits to read */ - const int16_t num_lengths, /* i : Number of different huffman codeword lengths */ - const int16_t *thres, /* i : Threshold of first codeword of each length */ - const int16_t *offset, /* i : Offset for first codeword */ - const int16_t *huff_tab, /* i : Huffman table order by codeword lengths */ - int16_t *index /* o : Decoded index */ -); - -void reordernorm( - const int16_t *ynrm, /* i : quantization indices for norms */ - const int16_t *normqlg2, /* i : quantized norms */ - int16_t *idxbuf, /* o : reordered quantization indices */ - int16_t *normbuf, /* o : reordered quantized norms */ - const int16_t nb_sfm /* i : number of bands */ -); - -void diffcod( - const int16_t N, /* i : number of sub-vectors */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx /* o : differential code */ -); - -void diffcod_lrmdct( - const int16_t N, /* i : number of sub-vectors */ - const int16_t be_ref, /* i : band energy reference */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx, /* o : differential code */ - const int16_t is_transient /* i : transient flag */ -); - -void bitallocsum( - int16_t *R, /* i : bit-allocation vector */ - const int16_t nb_sfm, /* i : number of sub-vectors */ - int16_t *sum, /* o : total number of bits allocated */ - int16_t *Rsubband, /* o : rate per subband (Q3) */ - const int16_t num_bits, /* i : number of bits */ - const int16_t length, /* i : length of spectrum */ - const int16_t *sfmsize /* i : Length of bands */ -); -/*! r: BWE class */ -int16_t swb_bwe_gain_deq_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t core, /* i : core */ - float *SWB_tenv, /* o : time-domain BWE envelope */ - float *SWB_fenv, /* o : frequency-domain BWE envelope */ - const int16_t hr_flag, /* i : high rate flag */ - const int16_t hqswb_clas /* i : HQ BWE class */ -); - -void save_old_syn( - const int16_t L_frame, /* i : frame length */ - const float syn[], /* i : ACELP synthesis */ - float old_syn[], /* o : old synthesis buffer */ - float old_syn_12k8_16k[], /* i/o: old synthesis buffer */ - const float preemph_fac, /* i : preemphasis factor */ - float *mem_deemph /* i/o: deemphasis filter memory */ -); - -void hq_generic_hf_decoding( - const int16_t HQ_mode, /* i : HQ mode */ - float *coeff_out1, /* i/o: BWE input & temporary buffer */ - const float *hq_generic_fenv, /* i : SWB frequency envelopes */ - float *coeff_out, /* o : SWB signal in MDCT domain */ - const int16_t hq_generic_offset, /* i : frequency offset for representing hq swb bwe*/ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - const int16_t hq_swb_bwe_exc_clas, /* i : bwe excitation class */ - const int16_t *R ); - -void hq_core_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float out[], /* o : output synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching frame flag */ - float *output /* o : LB synthesis in case of ACELP-HQ switch */ -); - -void IMDCT( - float *x, - float *old_syn_overl, - float *syn_Overl_TDAC, - float *xn_buf, - const float *tcx_aldo_window_1_trunc, - const float *tcx_aldo_window_2, - const float *tcx_mdct_window_half, - const float *tcx_mdct_window_minimum, - const float *tcx_mdct_window_trans, - const int16_t tcx_mdct_window_half_length, - const int16_t tcx_mdct_window_min_length, - int16_t index, - const uint16_t kernel_type, /* i : TCX transform kernel type */ - const int16_t left_rect, - const int16_t tcx_offset, - const int16_t overlap, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t L_spec_TCX5, - const int16_t L_frame_glob, - const int16_t frame_cnt, - const int16_t bfi, - float *old_out, - const int16_t FB_flag, - Decoder_State *st, - const int16_t fullband, - float *acelp_zir ); - -void hq_hr_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *t_audio_q, /* o : transform-domain coefficients */ - const int16_t length, /* i : frame length */ - const int16_t num_bits, /* i : number of available bits */ - int16_t *ynrm, /* o : norm quantization index vector */ - int16_t *is_transient, /* o : transient flag */ - int16_t *hqswb_clas, /* o : HQ SWB class */ - float *SWB_fenv, /* o : SWB frequency envelopes */ - const int16_t core_switching_flag /* i : Core switching flag */ - -); - -void hdecnrm_context( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index, /* o : indices of quantized norms */ - int16_t *n_length /* o : decoded stream length */ -); - -void hdecnrm_tran( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index /* o : indices of quantized norms */ -); - -void hdecnrm_resize( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of SFMs */ - int16_t *index /* o : norm quantization index vector */ -); - -void hdecnrm( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index /* o : indices of quantized norms */ -); - -/*! r: index of last band */ -int16_t find_last_band( - const int16_t *bitalloc, /* i : bit allocation */ - const int16_t nb_sfm /* i : number of possibly coded bands */ -); - -void fill_spectrum( - float *coeff, /* i/o: normalized MLT spectrum / nf spectrum */ - int16_t *R, /* i : number of pulses per band */ - const int16_t is_transient, /* i : transient flag */ - int16_t norm[], /* i : quantization indices for norms */ - const float *hq_generic_fenv, /* i : HQ GENERIC envelope */ - const int16_t hq_generic_offset, /* i : HQ GENERIC offset */ - const int16_t nf_idx, /* i : noise fill index */ - const int16_t length, /* i : Length of spectrum (32 or 48 kHz) */ - const float env_stab, /* i : Envelope stability measure [0..1] */ - int16_t *no_att_hangover, /* i/o: Frame counter for attenuation hangover */ - float *energy_lt, /* i/o: Long-term energy measure for transient detection */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - const int16_t hq_generic_exc_clas, /* i : HF excitation class */ - const int16_t core_sfm, /* i : index of the end band for core */ - int16_t HQ_mode, /* i : HQ mode */ - float noise_level[], /* i : noise level for harmonic modes */ - int32_t core_brate, /* i : target bitrate */ - float prev_noise_level[], /* i/o: noise factor in previous frame */ - int16_t *prev_R, /* i/o: bit allocation info. in previous frame */ - float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */ - const int16_t *peak_idx, /* i : peak positions */ - const int16_t Npeaks, /* i : number of peaks */ - const int16_t *npulses, /* i : Number of assigned pulses per band */ - int16_t prev_is_transient, /* i : previous transient flag */ - float *prev_normq, /* i : previous norms */ - float *prev_env, /* i : previous noise envelopes */ - int16_t prev_bfi, /* i : previous bad frame indicator */ - const int16_t *sfmsize, /* i : Length of bands */ - const int16_t *sfm_start, /* i : Start of bands */ - const int16_t *sfm_end, /* i : End of bands */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length for harmonic mode */ - int16_t prev_hq_mode, /* i : previous HQ mode */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t num_env_bands, /* i : Number of envelope bands */ - const int16_t element_mode /* i : element mode */ -); - -void de_interleave_spectrum( - float *coefs, /* i/o: input and output coefficients */ - int16_t length /* i : length of spectrum */ -); - -void inverse_transform( - const float *InMDCT, /* i : input MDCT vector */ - float *Out, /* o : output vector */ - const int16_t IsTransient, /* i : transient flag */ - const int16_t L, /* i : output frame length */ - const int16_t L_inner, /* i : length of the transform */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void window_ola( - const float *ImdctOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t L, /* i : length */ - const int16_t right_mode, - const int16_t left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t use_bfi_win, /* i : use BFI windowing */ - const int16_t oldHqVoicing, /* i : previous HqVoicing */ - float *oldgapsynth /* i : previous gapsynth */ -); - -void window_ola_ext( - const float *ImdstOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t L, /* i : length */ - const int16_t right_mode, - const int16_t left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const uint16_t kernel_type /* i : transform kernel type */ -); - -void map_quant_weight( - const int16_t normqlg2[], /* i : quantized norms */ - int16_t wnorm[], /* o : weighted norm */ - const int16_t is_transient /* i : transient flag */ -); - -void recovernorm( - const int16_t *const idxbuf, /* i : reordered quantization indices */ - int16_t *ynrm, /* o : recovered quantization indices */ - int16_t *normqlg2, /* o : recovered quantized norms */ - const int16_t nb_sfm /* i : number of subbands */ -); - -void reordvct( - int16_t *y, /* i/o: vector to rearrange */ - const int16_t N, /* i : dimensions */ - int16_t *idx /* o : reordered vector index */ -); - -void bitalloc( - int16_t *y, /* i : reordered norm of sub-vectors */ - int16_t *idx, /* i : reordered sub-vector indices */ - int16_t sum, /* i : number of available bits */ - int16_t N, /* i : number of norms */ - int16_t K, /* i : maximum number of bits per dimension */ - int16_t *r, /* o : bit-allacation vector */ - const int16_t *sfmsize, /* i : Length of bands */ - const int16_t hqswb_clas /* i : signal classification flag */ -); - -/*! r: Integer (truncated) number of allocated bits */ -int16_t BitAllocF( - int16_t *y, /* i : norm of sub-vectors */ - int32_t bit_rate, /* i : bitrate */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - int16_t *R, /* o : bit-allocation indicator */ - int16_t *Rsubband, /* o : sub-band bit-allocation vector (Q3) */ - const int16_t hqswb_clas, /* i : hq swb class */ - const int16_t num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ -); - -/*! r: Integer (truncated) number of allocated bits */ -int16_t BitAllocWB( - int16_t *y, /* i : norm of sub-vectors */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - int16_t *R, /* o : bit-allocation indicator */ - int16_t *Rsubband ); /* o : sub-band bit-allocation vector (Q3) */ - -/*! r: Number of low frequency bands */ -int16_t hvq_pvq_bitalloc( - int16_t num_bits, /* i/o: Number of available bits (including gain bits) */ - const int32_t core_brate, /* i : bitrate */ - const int16_t bwidth, /* i : Encoded bandwidth */ - const int16_t *ynrm, /* i : Envelope coefficients */ - const int32_t manE_peak, /* i : Peak energy mantissa */ - const int16_t expE_peak, /* i : Peak energy exponent */ - int16_t *Rk, /* o : bit allocation for concatenated vector */ - int16_t *R, /* i/o: Global bit allocation */ - int16_t *sel_bands, /* o : Selected bands for encoding */ - int16_t *n_sel_bands /* o : No. of selected bands for encoding */ -); - -void floating_point_add_float( - int32_t *mx, /* i/o: mantissa of the addend Q31 */ - int16_t *ex, /* i/o: exponent of the addend Q0 */ - const int32_t my, /* i : mantissa of the adder Q31 */ - const int16_t ey /* i : exponent of the adder Q0 */ -); - -/*! r: Number of bits needed */ -int16_t rc_get_bits2( - const int16_t N, /* i : Number of bits currently used */ - const uint32_t range /* i : Range of range coder */ -); - -void rc_enc_init( - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - int16_t tot_bits /* i : Total bit budget */ -); - -void rc_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const uint32_t cum_freq, /* i : Cumulative frequency up to symbol */ - const uint32_t sym_freq, /* i : Symbol probability */ - const uint32_t tot /* i : Total cumulative frequency */ -); - -void rc_enc_finish( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ /* i/o: PVQ encoder handle */ -); - -void rc_enc_bits( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const uint32_t value, /* i : Value to encode */ - const int16_t bits /* i : Number of bits used */ -); - -void rc_enc_uniform( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - uint32_t value, /* i : Value to encode */ - uint32_t tot /* i : Maximum value */ -); - -void rc_dec_init( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - int16_t tot_bits /* i : Total bit budget */ -); - -/*! r: Decoded value */ -uint32_t rc_decode( - int16_t *BER_detect, /* o : Bit error detection flag */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - uint32_t tot /* i : Total cumulative frequency */ -); - -void rc_dec_update( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const uint32_t cum_freq, /* i : Cumulative frequency */ - const uint32_t sym_freq /* i : Symbol frequency */ -); - -/*! r: Decoded value */ -uint32_t rc_dec_bits( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const int16_t bits /* i : Number of bits */ -); - -/*! r: Decoded value */ -uint32_t rc_dec_uniform( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const uint32_t tot /* i : Maximum value */ -); - -void rc_dec_finish( - Decoder_State *st, /* i/o: decoder state structure */ - PVQ_DEC_HANDLE hPVQ /* i/o: PVQ decoder handle */ -); - -/*! r: number of bits encoded */ -int16_t pvq_core_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - float coefs_norm[], /* i/o: normalized coefficients to encode */ - float coefs_quant[], /* o : quantized coefficients */ - const int16_t bits_tot, /* i : total number of bits */ - const int16_t nb_sfm, /* i : number of bands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : subband width */ - int16_t *R, /* i/o: Bit allocation/Adjusted bit alloc. (Q3) */ - int16_t *Rs, /* i/o: Integer bit allocation */ - int16_t *npulses, /* o : number of pulses */ - int16_t *maxpulse, /* i : maximum pulse per band */ - const int16_t core /* i : number of bands */ -); - -/*! r: number of bits decoded */ -int16_t pvq_core_dec( - Decoder_State *st, /* i/o: Decoder state */ - const int16_t *sfm_start, /* i : indices of first coeffs in the bands */ - const int16_t *sfm_end, /* i : indices of last coeffs in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - float coefs_quant[], /* o : output MDCT */ - const int16_t bits_tot, /* i : bit budget */ - const int16_t nb_sfm, /* i : number of bands */ - int16_t *R, /* i/o: Bit allocation/Adjusted bit alloc.(Q3) */ - int16_t *Rs, /* i/o: Integer bit allocation */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *maxpulse, /* o : maximum pulse per band */ - const int16_t core /* i : core */ -); - -void pvq_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const float *x, /* i : vector to quantize */ - int16_t *y, /* o : quantized vector (non-scaled integer)*/ - float *xq, /* o : quantized vector (scaled float) */ - const int16_t pulses, /* i : number of allocated pulses */ - const int16_t N, /* i : Length of vector */ - const float gain /* i : Gain */ -); - -void pvq_decode( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - float *xq, /* o : decoded vector (scaled float) */ - int16_t *y, /* o : decoded vector (non-scaled short)*/ - const int16_t K, /* i : number of allocated pulses */ - const int16_t N, /* i : Length of vector */ - const float gain /* i : Gain */ -); - -void rangeCoderFinalizationFBits( - const int16_t Brc, /* i : Current number of decoded bits */ - const uint32_t INTrc, /* i : Range coder state */ - int16_t *FBits /* i : Fractional finalization bits */ -); - -void bandBitsAdjustment( - const int16_t Brc, /* i : Current number of read quanta in range coder */ - const uint32_t INTrc, /* i : Range coder state */ - const int16_t Bavail, /* i : Available number of quanta */ - const int16_t Nbands, /* i : Number of bands */ - const int16_t D, /* i : Remaining number of bands to encode */ - const int16_t L, /* i : Size of current band */ - const int16_t Bband, /* i : Quanta allocation for current band */ - const int16_t Breserv, /* i : Quanta reservoir */ - int16_t *Bband_adj, /* o : Actual used number of quanta */ - int16_t *Brem, /* o : Quanta remaining */ - int16_t *Breservplus /* o : Quanta pool size */ -); - -void conservativeL1Norm( - const int16_t L, /* i : Length of vector segment */ - const int16_t Qvec, /* i : Assigned number of quanta */ - const int16_t Fcons, /* i : Conservative rounding flag */ - const int16_t Qavail, /* i : Input quanta remaining */ - const int16_t Qreserv, /* i : Input quanta in reservoir */ - const int16_t Dspec, /* i : assigned diracs from bitalloc */ - int16_t *Dvec, /* o : actual number of diracs */ - int16_t *Qspare, /* o : Output quanta remaining */ - int16_t *Qreservplus, /* o : Output quanta in reservoir */ - int16_t *Dspecplus /* o : Output number of diracs */ -); - -void NearOppSplitAdjustment( - const int16_t qband, /* i : quanta for current band */ - const int16_t qzero, /* i : range coder finalization quanta */ - const int16_t Qac, /* i : range coder current quanta */ - const uint32_t INTac, /* i : range coder state */ - const int16_t qglobal, /* i : quanta input */ - const int16_t FlagCons, /* i : conservative rounding flag */ - const int16_t Np, /* i : number of parts */ - const int16_t Nhead, /* i : first part */ - const int16_t Ntail, /* i : remaining parts */ - const int16_t Nnear, /* i : length of near component */ - const int16_t Nopp, /* i : length of opposite component */ - int16_t oppRQ3, /* i : ratio */ - int16_t *qnear, /* o : quantized near */ - int16_t *qopp, /* o : quantized opposite */ - int16_t *qglobalupd /* o : quanta remaining */ -); - -/*! r: Approximate integer division for positive input */ -int32_t intLimCDivPos( - const int32_t NUM, /* i : numerator */ - const int16_t DEN /* i : denominator */ -); - -/*! r: Approximate integer division */ -int16_t shrtCDivSignedApprox_flt( - const int16_t num, /* i : numerator */ - const int16_t den /* i : denominator */ -); - -void QuantaPerDsDirac( - const int16_t td, /* i : Length of vector segment */ - const int16_t dsDiracIndex, /* i : Quanta table index */ - const uint8_t *const *dimFrQuanta, /* i : Quanta lookup table */ - int16_t *Quanta /* i : Quanta */ -); - -void obtainEnergyQuantizerDensity( - const int16_t L_in, /* i : left vector energy */ - const int16_t R_in, /* i : right vector energy */ - int16_t *Density /* o : quantizer density */ -); - -void densityAngle2RmsProjDec( - const int16_t D, /* i : density */ - const int16_t indexphi, /* i : decoded index from AR dec */ - int16_t *oppQ15, /* o : opposite */ - int16_t *nearQ15, /* o : near */ - int16_t *oppRatioQ3 /* o : ratio */ -); - -void densityAngle2RmsProjEnc( - const int16_t D, /* i : density */ - const int16_t phiQ14uq, /* i : angle */ - int16_t *indexphi, /* o : index */ - int16_t *oppQ15, /* o : opposite */ - int16_t *nearQ15, /* o : near */ - int16_t *oppRatioQ3 /* o : ratio */ -); - -void env_adj( - const int16_t *pulses, /* i : number of pulses per band */ - const int16_t length, /* i : length of spectrum */ - const int16_t last_sfm, /* i : Index of last band */ - float *adj, /* o : Adjustment factors for the envelope */ - const float env_stab, /* i : Envelope stability parameter */ - const int16_t *sfmsize /* i : Length of bands */ -); - -float env_stability( - const int16_t *ynrm, /* i : Norm vector for current frame */ - const int16_t nb_sfm, /* i : Number of sub-bands */ - int16_t *mem_norm, /* i/o: Norm vector memory from past frame */ - int16_t *mem_env_delta, /* i/o: Envelope stability memory for smoothing*/ - const int16_t core_switching_flag /* i : Core switching flag */ -); - -/*! r: New speech/music state */ -float env_stab_smo( - float env_stab, /* i : env_stab value */ - float *env_stab_state_p, /* i/o: env_stab state probabilities */ - int16_t *ho_cnt /* i/o: hangover counter for speech state */ -); -void core_switching_post_enc( - Encoder_State *st, /* i/o: encoder state structure */ - // const float *old_inp_12k8, /* i : old input signal @12.8kHz */ - float *old_inp_12k8, /* i : old input signal @12.8kHz */ - // const float *old_inp_16k, /* i : old input signal @16kHz */ - float *old_inp_16k, /* i : old input signal @16kHz */ - // const float A[] /* i : unquant. LP filter coefs. */ - Word16 A_fx[], /* i : unquant. LP filter coefs. */ - Word16 Q_new ); -ivas_error core_switching_post_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *synth, /* i/o: output synthesis */ - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching frame flag */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode /* i : element mode of previous frame */ -); - -ivas_error core_switching_pre_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t output_frame, /* i : frame length */ - const int32_t last_core_brate_st0, /* i : channel 0 last core bitrate */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode, /* i : last_element_mode */ - const int32_t last_element_brate /* i : last element bitrate */ -); - -void bandwidth_switching_detect( - Decoder_State *st /* i/o: decoder state structure */ -); - -void bw_switching_pre_proc( - Decoder_State *st, /* i/o: decoder state structure */ - const float *old_syn_12k8_16k, /* i : ACELP core synthesis @ 12.8kHz or 16kHz */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t nchan_out /* i : number of output channels */ -); - -void updt_bw_switching( - Decoder_State *st, /* i/o: decoder state structure */ - const float *synth /* i : float synthesis signal */ -); - -void swb_tbe_reset( - float mem_csfilt[], - float mem_genSHBexc_filt_down_shb[], - float state_lpc_syn[], - float syn_overlap[], - float state_syn_shbexc[], - float *tbe_demph, - float *tbe_premph, - float mem_stp_swb[], - float *gain_prec_swb ); - -void swb_tbe_reset_synth( - float genSHBsynth_Hilbert_Mem[], - float genSHBsynth_state_lsyn_filt_shb_local[] ); - -void find_td_envelope( - const float inp[], - const int16_t len, - const int16_t len_h, - float mem_h[], - float out[] ); - -void fb_tbe_reset_enc( - float elliptic_bpf_2_48k_mem[][4], - float *prev_fb_energy ); - -void fb_tbe_reset_synth( - float fbbwe_hpf_mem[][4], - float *prev_fbbwe_ratio ); - -void wb_tbe_extras_reset( - float mem_genSHBexc_filt_down_wb2[], - float mem_genSHBexc_filt_down_wb3[] ); - -void wb_tbe_extras_reset_synth( - float state_lsyn_filt_shb[], - float state_lsyn_filt_dwn_shb[], - float mem_resamp_HB[] ); - -void tbe_celp_exc_flt( - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - float *bwe_exc, /* i/o: BWE excitation */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - float *error, /* i/o: error */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -); - -void prep_tbe_exc( - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const float gain_pit, /* i : Pitch gain */ - const float gain_code, /* i : algebraic codebook gain */ - const float code[], /* i : algebraic excitation */ - const float voice_fac, /* i : voicing factor */ - float *voice_factors, /* o : TBE voicing factor */ - float bwe_exc[], /* i/o: excitation for TBE */ - const float gain_preQ, /* i : prequantizer excitation gain */ - const float code_preQ[], /* i : prequantizer excitation */ - const int16_t T0, /* i : integer pitch variables */ - const int16_t coder_type, /* i : coding type */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -); - -void synthesise_fb_high_band( - const float excitation_in[], /* i : full band excitation */ - float output[], /* o : high band speech - 14.0 to 20 kHz */ - const float fb_exc_energy, /* i : full band excitation energy */ - const float ratio_float, /* i : energy ratio */ - const int16_t L_frame, /* i : ACELP frame length */ - const int16_t bfi, /* i : BFI flag */ - float *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ - float bpf_memory[][4] /* i/o: memory for elliptic bpf 48k */ -); - -void elliptic_bpf_48k_generic( - const float input[], /* i : input signal */ - float output[], /* o : output signal */ - float memory[][4], /* i/o: 4 arrays for memory */ - const float full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 */ -); - -void HQ_FEC_processing( - Decoder_State *st, /* i/o: decoder state structure */ - float *t_audio_q, /* o : MDCT coeffs. (for synthesis) */ - int16_t is_transient, /* i : Old flag for transient */ - float ynrm_values[][MAX_PGF], /* i : Old average Norm values for each group of bands */ - float r_p_values[][MAX_ROW], /* i : Computed y-intercept and slope by Regression */ - int16_t num_Sb, /* i : Number of sub-band group */ - int16_t nb_sfm, /* i : Number of sub-band */ - int16_t *Num_bands_p, /* i : Number of coeffs. for each sub-band */ - int16_t output_frame, /* i : Frame size */ - const int16_t *sfm_start, /* i : Start of bands */ - const int16_t *sfm_end /* i : End of bands */ -); - -void HQ_FEC_Mem_update( - Decoder_State *st, /* i/o: decoder state structure */ - const float *t_audio_q, - float *normq, - int16_t *ynrm, - const int16_t *Num_bands_p, - const int16_t is_transient, - const int16_t hqswb_clas, - const int16_t c_switching_flag, - const int16_t nb_sfm, - const int16_t num_Sb, - float *mean_en_high, - const int16_t hq_core_type, /* i : normal or low-rate MDCT(HQ) core */ - const int16_t output_frame /* i : Frame size */ -); - -void time_domain_FEC_HQ( - Decoder_State *st, /* i : Decoder State */ - float *wtda_audio, /* i : input */ - float *out, /* o : output audio */ - const float mean_en_high, /* i : transient flag */ - const int16_t output_frame /* i : Frame size */ -); - -void save_synthesis_hq_fec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *output, /* i : decoded synthesis */ - const int16_t output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -); - -void Next_good_after_burst_erasures( - const float *ImdctOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t ol_size /* i : overlap size */ -); - - -void reset_preecho_dec( - HQ_DEC_HANDLE hHQ_core /* i/o: HQ decoder handle */ -); - -void preecho_sb( - const int32_t core_brate, /* i : core bitrate */ - const float wtda_audio[], /* i : imdct signal */ - float *rec_sig, /* i : reconstructed signal, output of the imdct transform */ - const int16_t framelength, /* i : frame length */ - float *memfilt_lb, /* i/o: memory */ - float *mean_prev_hb, /* i/o: memory */ - float *smoothmem, /* i/o: memory */ - float *mean_prev, /* i/o: memory */ - float *mean_prev_nc, /* i/o: memory */ - float *wmold_hb, /* i/o: memory */ - int16_t *prevflag, /* i/o: flag */ - int16_t *pastpre, /* i/o: flag */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void hq2_core_configure( - const int16_t frame_length, /* i : frame length */ - const int16_t num_bits, /* i : number of bits */ - const int16_t is_transient, /* i : transient flag */ - int16_t *bands, - int16_t *length, - int16_t band_width[], - int16_t band_start[], - int16_t band_end[], - Word32 *L_qint, /* o : Q29 */ - Word16 *eref_fx, /* o : Q10 */ - Word16 *bit_alloc_weight_fx, /* o : Q13 */ - int16_t *gqlevs, - int16_t *Ngq, - int16_t *p2a_bands, - float *p2a_th, - float *pd_thresh, - float *ld_slope, - float *ni_coef, - float *ni_pd_th, - int32_t bwe_br ); - -void hq_lr_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float t_audio[], /* i/o: transform-domain coefs. */ - const int16_t inner_frame, /* i : inner frame length */ - int16_t *num_bits, /* i/o: number of available bits */ - const int16_t is_transient /* i : transient flag */ -); - -void hq_lr_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float yout[], /* o : transform-domain output coefs. */ - const int16_t inner_frame, /* i : inner frame length */ - int16_t num_bits, /* i : number of available bits */ - int16_t *is_transient /* o : transient flag */ -); - -void hq2_bit_alloc( - const float band_energy[], /* i : band energy of each subband */ - const int16_t bands, /* i : total number of subbands in a frame */ - Word32 L_Rk[], /* i/o: Bit allocation/Adjusted bit alloc. */ - int16_t *bit_budget, /* i/o: bit bugdet */ - int16_t *p2a_flags, /* i : HF tonal indicator */ - const Word16 weight_fx, /* i : weight (Q13) */ - const int16_t band_width[], /* i : Sub band bandwidth */ - const int16_t num_bits, /* i : available bits */ - const int16_t hqswb_clas, /* i : HQ2 class information */ - const int16_t bwidth, /* i : input bandwidth */ - const int16_t is_transient /* i : indicator HQ_TRANSIENT or not */ -); - -void hq2_noise_inject( - float y2hat[], - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - float Ep[], - float Rk[], - const int16_t npulses[], - int16_t ni_seed, - const int16_t bands, - const int16_t ni_start_band, - const int16_t bw_low, - const int16_t bw_high, - const float enerL, - const float enerH, - float last_ni_gain[], - float last_env[], - int16_t *last_max_pos_pulse, - int16_t *p2a_flags, - int16_t p2a_bands, - const int16_t hqswb_clas, - const int16_t bwidth, - const int32_t bwe_br ); - -void mdct_spectrum_denorm( - const int32_t inp_vector[], - float y2[], - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - const float band_energy[], - const int16_t npulses[], - const int16_t bands, - const float ld_slope, - const float pd_thresh ); - -void reverse_transient_frame_energies( - float band_energy[], /* o : band energies */ - const int16_t bands /* i : number of bands */ -); - - -void hvq_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t num_bits, /* i : Number of available bits */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t *ynrm, /* i : Envelope coefficients */ - int16_t *R, /* i/o: Bit allocation/updated bit allocation */ - float *noise_level, /* o : Noise level */ - int16_t *peak_idx, /* o : Peak position vector */ - int16_t *Npeaks, /* o : Total number of peaks */ - float *coefsq_norm, /* o : Output vector */ - const int16_t core /* i : Core */ -); - -void hq_configure_bfi( - int16_t *nb_sfm, /* o : Number of sub bands */ - int16_t *num_Sb, /* o : Number of FEC sub bands ? */ - int16_t *num_bands_p, /* o : FEC sub bands */ - const int16_t **sfmsize, /* o : Subband bandwidths */ - const int16_t **sfm_start, /* o : Subband start coefficients */ - const int16_t **sfm_end /* o : Subband end coefficients */ -); - -void swb_bwe_enc_lr( - Encoder_State *st, /* i/o: encoder state structure */ - const float m_core[], /* i : core synthesis (MDCT) */ - const float m_orig[], /* i/o: scaled orig signal (MDCT) */ - float m[], /* o : output, SWB part (MDCT) */ - const int32_t total_brate, /* i : total bitrate for selecting subband pattern */ - int16_t BANDS, - int16_t *band_start, - int16_t *band_end, - float *band_energy, - int16_t *p2a_flags, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - int16_t *prev_frm_index, - const int16_t har_bands, - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - int16_t band_width[], - const float y2_ni[], - int16_t *ni_seed ); - -void swb_bwe_dec_lr( - Decoder_State *st, /* i/o: decoder state structure */ - const float m_core[], /* i : lowband synthesis */ - float m[], /* o : highband synthesis with lowband zeroed */ - const int32_t total_brate, /* i : total bitrate for selecting subband pattern */ - int16_t BANDS, - int16_t *band_start, - int16_t *band_end, - float *band_energy, - int16_t *p2a_flags, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - const int16_t har_bands, - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - int16_t band_width[], - const float y2_ni[], - int16_t *ni_seed ); - -int16_t get_usebit_npswb( - const int16_t hqswb_clas ); - -void GetPredictedSignal( - const float *predBuf, /* i : prediction buffer */ - float *outBuf, /* o : output buffer */ - const int16_t lag, /* i : prediction buffer offset */ - const int16_t fLen, /* i : length of loop (output) */ - const float gain /* i : gain to be applied */ -); - -void convert_lagIndices_pls2smp( - int16_t lagIndices_in[], - int16_t nBands_search, - int16_t lagIndices_out[], - const float sspectra[], - const int16_t sbWidth[], - const int16_t fLenLow ); - -void FindNBiggest2_simple( - const float *inBuf, /* i : input buffer (searched) */ - GainItem *g, /* o : N biggest components found */ - const int16_t nIdx, /* i : search length */ - int16_t *n, /* i : number of components searched (N biggest) */ - const int16_t N_NBIGGESTSEARCH ); - -void updat_prev_frm( - float y2[], - float t_audio[], - const int32_t bwe_br, - const int16_t length, - const int16_t inner_frame, - const int16_t bands, - const int16_t bwidth, - const int16_t is_transient, - const int16_t hqswb_clas, - int16_t *prev_hqswb_clas, - int16_t *prev_SWB_peak_pos, - int16_t prev_SWB_peak_pos_tmp[], - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - const int16_t bws_cnt ); - -void hf_parinitiz( - const int32_t total_brate, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - int16_t wBands[], - const int16_t **subband_search_offset, - const int16_t **subband_offsets, - int16_t *nBands, - int16_t *nBands_search, - int16_t *swb_lowband, - int16_t *swb_highband ); - -float spectrumsmooth_noiseton( - float spectra[], - const float spectra_ni[], - float sspectra[], - float sspectra_diff[], - float sspectra_ni[], - const int16_t fLenLow, - int16_t *ni_seed ); - -void noiseinj_hf( - float xSynth_har[], - const float th_g[], - const float band_energy[], - float *prev_En_sb, - const int16_t p2a_flags[], - const int16_t BANDS, - const int16_t band_start[], - const int16_t band_end[], - const int16_t fLenLow ); - -void noise_extr_corcod( - float spectra[], - const float spectra_ni[], - float sspectra[], - float sspectra_diff[], - float sspectra_ni[], - const int16_t fLenLow, - int16_t prev_hqswb_clas, - float *prev_ni_ratio ); - -void genhf_noise( - float noise_flr[], - float xSynth_har[], - float *predBuf, - int16_t bands, /* i : total number of subbands in a frame */ - int16_t harmonic_band, /* i : Number of LF harmonic frames */ - int16_t har_freq_est2, - int16_t pos_max_hfe2, - int16_t *pul_res, - GainItem pk_sf[], - const int16_t fLenLow, - const int16_t fLenHigh, - const int16_t sbWidth[], - const int16_t lagIndices[], - const int16_t subband_offsets[], - const int16_t subband_search_offset[] ); - -void ton_ene_est( - float xSynth_har[], - float be_tonal[], - float band_energy[], - int16_t band_start[], - int16_t band_end[], - int16_t band_width[], - const int16_t fLenLow, - const int16_t fLenHigh, - int16_t bands, - int16_t har_bands, - float ni_lvl, - GainItem pk_sf[], - int16_t *pul_res ); - -void Gettonl_scalfact( - float *outBuf, /* o : synthesized spectrum */ - const float *codbuf, /* i : core coder */ - const int16_t fLenLow, /* i : lowband length */ - const int16_t fLenHigh, /* i : highband length */ - int16_t harmonic_band, /* i : Number of LF harmonic frames */ - int16_t bands, /* i : total number of subbands in a frame */ - float *band_energy, /* i : band energy of each subband */ - int16_t *band_start, /* i : subband start indices */ - int16_t *band_end, /* i : subband end indices */ - const int16_t p2aflags[], - float be_tonal[], - GainItem *pk_sf, - int16_t *pul_res ); - -void SpectrumSmoothing( - float *inBuf, - float *outBuf, - const int16_t fLen, - const float th_cut ); - -void hq2_bit_alloc_har( - float *y, /* i : band energy of sub-vectors */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - Word32 *L_Rsubband, - int16_t p2a_bands, - int32_t core_brate, /* i : core bitrate */ - int16_t p2a_flags[], - int16_t band_width[] ); - -void GetSynthesizedSpecThinOut( - const float *predBuf, - float *outBuf, - const int16_t nBands, - const int16_t *sbWidth, - const int16_t *lagIndices, - const float *lagGains, - const int16_t predBufLen ); - -void return_bits_normal2( - int16_t *bit_budget, - const int16_t p2a_flags[], - const int16_t bands, - const int16_t bits_lagIndices[] ); - -void GetlagGains( - const float *predBuf, - const float *band_energy, - const int16_t nBands, - const int16_t *sbWidth, - const int16_t *lagIndices, - const int16_t predBufLen, - float *lagGains ); - -void preset_hq2_swb( - const int16_t hqswb_clas, - const int16_t band_end[], - int16_t *har_bands, - int16_t p2a_bands, - const int16_t length, - const int16_t bands, - int16_t *lowlength, - int16_t *highlength, - float m[] ); - -void post_hq2_swb( - const float m[], - const int16_t lowlength, - const int16_t highlength, - const int16_t hqswb_clas, - const int16_t har_bands, - const int16_t bands, - const int16_t p2a_flags[], - const int16_t band_start[], - const int16_t band_end[], - float y2[], - int16_t npulses[] ); - -void har_denorm_pulcnt( - float spectra[], /* i/o: MDCT domain spectrum */ - const int16_t band_start[], /* i : Number subbands/Frame */ - const int16_t band_end[], /* i : Band Start of each SB */ - const float band_energy[], /* i : Band end of each SB */ - const int16_t band_width[], - const int16_t npulses[], - const int16_t har_bands /* i : No. of harmonic bands */ -); - -int16_t har_est( - float spectra[], - const int16_t N, - int16_t *har_freq_est1, - int16_t *har_freq_est2, - int16_t *flag_dis, - int16_t *prev_frm_hfe2, - const int16_t subband_search_offset[], - const int16_t sbWidth[], - int16_t *prev_stab_hfe2 ); - -void spt_shorten_domain_pre( - const int16_t band_start[], - const int16_t band_end[], - const int16_t prev_SWB_peak_pos[], - const int16_t BANDS, - const int32_t bwe_br, - int16_t new_band_start[], - int16_t new_band_end[], - int16_t new_band_width[] ); - -void spt_shorten_domain_band_save( - const int16_t bands, - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - int16_t org_band_start[], - int16_t org_band_end[], - int16_t org_band_width[] ); - -void spt_shorten_domain_band_restore( - const int16_t bands, - int16_t band_start[], - int16_t band_end[], - int16_t band_width[], - const int16_t org_band_start[], - const int16_t org_band_end[], - const int16_t org_band_width[] ); - -void spt_swb_peakpos_tmp_save( - const float y2[], - const int16_t bands, - const int16_t band_start[], - const int16_t band_end[], - int16_t prev_SWB_peak_pos_tmp[] ); - -void hq_ecu( - const float *prevsynth, /* i : buffer of previously synthesized signal */ - float *ecu_rec, /* o : reconstructed frame in tda domain */ - int16_t *time_offs, /* i/o: Sample offset for consecutive frame losses*/ - float *X_sav, /* i/o: Stored spectrum of prototype frame */ - int16_t *num_p, /* i/o: Number of identified peaks */ - int16_t *plocs, /* i/o: Peak locations */ - float *plocsi, /* i/o: Interpolated peak locations */ - const float env_stab, /* i : Envelope stability parameter */ - int16_t *last_fec, /* i/o: Flag for usage of pitch dependent ECU */ - const int16_t ph_ecu_HqVoicing, /* i : HQ Voicing flag */ - int16_t *ph_ecu_active, /* i : Phase ECU active flag */ - float *gapsynth, /* o : Gap synthesis */ - const int16_t prev_bfi, /* i : indicating burst frame error */ - const int16_t old_is_transient[2], /* i : flags indicating previous transient frames*/ - float *mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ - float Xavg[LGW_MAX], /* i/o: Frequency group average gain to fade to */ - float *beta_mute, /* o : Factor for long-term mute */ - const int16_t output_frame, /* i : frame length */ - Decoder_State *st /* i/o: decoder state structure */ -); - -void peakfinder( - const float *x0, /* i : vector from which the maxima will be found */ - const int16_t len0, /* i : length of input vector */ - int16_t *plocs, /* o : the indicies of the identified peaks in x0 */ - int16_t *cInd, /* o : number of identified peaks */ - const float sel, /* i : The amount above surrounding data for a peak to be identified */ - const int16_t endpoints /* i : Flag to include endpoints in peak search */ -); - -/*! r: interpolated maximum position */ -float imax_pos( - const float *y /* i : Input vector for peak interpolation */ -); - - -void fft3( - const float X[], /* i : input frame */ - float Y[], /* o : DFT of input frame */ - const int16_t n /* i : block length (must be radix 3) */ -); - -void ifft3( - const float X[], /* i : input frame */ - float Y[], /* o : iDFT of input frame */ - const int16_t n /* i : block length (must be radix 3) */ -); - -/*! r: updated estimate of background noise */ -void minimumStatistics( - float *noiseLevelMemory, /* i/o: internal state */ - int16_t *noiseLevelIndex, /* i/o: internal state */ - int16_t *currLevelIndex, /* i/o: internal state (circular buffer) */ - float *noiseEstimate, /* i/o: previous estimate of background noise */ - float *lastFrameLevel, /* i/o: level of the last frame */ - float currentFrameLevel, /* i : level of the current frame */ - const float minLev, /* i : minimum level */ - const int16_t buffSize /* i : buffer size */ -); - -void E_ACELP_toeplitz_mul( - const float R[], - const float c[], - float d[] ); - -void E_ACELP_innovative_codebook( - const float *exc, /* i : pointer to the excitation frame */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - const int16_t T0_res, /* i : pitch resolution */ - const float pitch_gain, /* i : adaptive codebook gain */ - const float tilt_code, /* i : tilt factor */ - ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */ - const int16_t i_subfr, /* i : subframe index */ - const float *Aq, /* i : quantized LPC coefficients */ - const float *h1, /* i : impulse response of weighted synthesis filter */ - const float *xn, /* i : Close-loop Pitch search target vector */ - const float *cn, /* i : Innovative codebook search target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - float *y2, /* o : zero-memory filtered algebraic excitation */ - const int16_t acelpautoc, /* i : autocorrelation mode enabled */ - int16_t **pt_indice, /* i/o: quantization indices pointer */ - float *code, /* o : innovative codebook */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t last_L_frame, /* i : length of the last frame */ - const int32_t total_brate /* i : total bitrate */ -); - -int16_t E_ACELP_code43bit( - const float code[], - uint32_t *ps, - int16_t *p, - uint16_t idxs[] ); -void D_ACELP_indexing_ivas( - float code[], - PulseConfig config, - const int16_t num_tracks, - int16_t prm[], - int16_t *BER_detect ); - -void D_ACELP_decode_43bit( - uint16_t idxs[], - float code[], - int16_t *pulsestrack ); - -void fcb_pulse_track_joint_decode_ivas( - uint16_t *idxs, - const int16_t wordcnt, - uint32_t *index_n, - const int16_t *pulse_num, - const int16_t track_num ); - -void lag_wind_flt( - float r[], /* i/o: autocorrelations */ - const int16_t m, /* i : order of LP filter */ - const int32_t sr_core, /* i : sampling rate */ - const int16_t strength /* i : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */ -); - -void adapt_lag_wind_fx( - float r[], /* i/o: autocorrelations */ - const int16_t m, /* i : order of LP filter */ - const int16_t Top, /* i : open loop pitch lags from curr. frame (or NULL if n/a) */ - const float Tnc, /* i : open loop pitch gains from curr. frame (NULL if n/a) */ - const int32_t sr_core /* i : core sampling rate */ -); - -void core_coder_reconfig( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_total_brate /* i : last total bitrate */ -); - -void core_coder_mode_switch( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_total_brate, /* i : last bitrate */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void enc_acelp_tcx_main( - Encoder_State *st, /* i/o: encoder state structure */ - const float new_samples[], /* i : new samples */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const float lsp_new[M], /* i : LSPs at the end of the frame */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float pitch_buf[], /* o : floating pitch for each subframe */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void getTCXMode_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - Decoder_State *st0, /* i : bitstream */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void getTCXWindowing_ivas( - const Word16 core, /* i : current frame mode */ - const Word16 last_core, /* i : last frame mode */ - const Word16 element_mode, /* i : element mode */ - TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ - Decoder_State *st0 /* i : bitstream */ -); - -void getLPCparam_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t param_lpc[], /* o : LTP parameters */ - Decoder_State *st0, /* i : bitstream */ - const int16_t ch, /* i : channel */ - const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ -); - -void getTCXparam_ivas( - Decoder_State *st, /* i/o: Decoder State handle */ - Decoder_State *st0, /* i : bitstream */ - CONTEXT_HM_CONFIG hm_cfg, /* i/o: HM config */ - int16_t param[], /* o : decoded parameters */ - const int16_t bits_common, /* i : number of common bits */ - const int16_t start_bit_pos, /* i : position of the start bit */ - const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ - int16_t p_param[2], /* o : pointer to parameters for next round of bs reading*/ - int16_t nTnsBitsTCX10[2], - const int16_t pre_past_flag ); - -void pitch_pred_linear_fit_flt( - const int16_t nbLostCmpt, /* i : bfi counter */ - const int16_t last_good, /* i : last classification type */ - float *old_pitch_buf, /* i : pitch lag buffer */ - float *old_fpitch, /* i/o: pitch used for initial ACB generation */ - float *T0_out, /* o : estimated close loop pitch */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max, /* i : Maximum pitch lag */ - float *mem_pitch_gain, /* i : lag pitch gain [0] is the most recent subfr lag */ - const int16_t limitation, - const int16_t plc_use_future_lag, /* i : number of subframes to predict */ - int16_t *extrapolationFailed, /* o : flag if extrap decides not to change the pitch */ - const int16_t nb_subfr /* i : number of ACELP subframes */ -); - -void get_subframe_pitch_flt( - const int16_t nSubframes, /* i : number of subframes */ - float pitchStart, /* i : starting pitch lag (in subframe -1) */ - float pitchEnd, /* i : ending pitch lag (in subframe nSubframes-1) */ - float *pitchBuf /* o : interpolated pitch lag per subframe */ -); - -void core_encode_openloop( - Encoder_State *st, /* i/o: encoder state structure */ - const float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const float lsp_new[M], /* i : LSPs at the end of the frame */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - float *pitch_buf, /* i/o: floating pitch values for each subfr*/ - float *voice_factors, /* o : voicing factors */ - float *ptr_bwe_exc, /* o : excitation for SWB TBE */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void core_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - float *pitch_fr, /* i/o: fraction pitch values */ - float *voicing_fr, /* i/o: fractional voicing values */ - const float currTempFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac /* i : LP filter stability */ -); - -void core_encode_twodiv( - Encoder_State *st, /* i/o: coder memory state */ - const float new_samples[], /* i : new samples */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void core_encode_update( - Encoder_State *st /* i/o: encoder state structure */ -); - -void core_encode_update_cng( - Encoder_State *st, /* i/o: encoder state structure */ - float *timeDomainBuffer, - float *A, - const float Aw[] /* i : weighted A(z) unquant. for subframes*/ -); - -void core_signal_analysis_high_bitrate( - const float *new_samples, - const int16_t T_op[3], /* i : open-loop pitch values for quantiz. */ - float lsp_new[], - float lsp_mid[], - Encoder_State *st, - float *mdst_spectrum[2], - int16_t pTnsSize[], - int16_t pTnsBits[], - int16_t param_core[], - int16_t *ltpBits, - float *windowed_samples, /* i/o: backup of windowed time signal */ - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t last_element_mode, - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void encode_acelp_gains( - const float *code, - const int16_t gains_mode, - const float mean_ener_code, - const int16_t clip_gain, - ACELP_CbkCorr *g_corr, - float *gain_pit, - float *gain_code, - int16_t **pt_indice, - float *past_gcode, - float *gain_inov, - const int16_t L_subfr, - float *code2, - float *gain_code2, - const int16_t noisy_speech_flag ); - -int16_t gain_enc_gacelp_uv( - const float *code, /* i : algebraic excitation */ - const float *code2, /* i : gaussian excitation */ - const int16_t lcode, /* i : Subframe size */ - const float mean_ener, /* i : quantized mean energy of the frame */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_code2, /* o : quantized codebook gain */ - ACELP_CbkCorr *coeff, /* i/o: correlations , -2,, -2 and 2 */ - float *past_gcode, /* i/o: past gain of code */ - float *gain_inov, /* o : unscaled innovation gain */ - const int16_t noisy_speech_flag /* i : noisy speech flag */ -); - -int16_t Mode2_gain_enc_mless( - const float *code, /* i : algebraic excitation */ - const int16_t lcode, /* i : Subframe size */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - ACELP_CbkCorr *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const float mean_ener, /* i : mean_ener defined in open-loop (3 bits) */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - float *past_gcode, /* i/o: past gain of code */ - float *gain_inov, /* o : unscaled innovation gain */ - const int16_t coder_type /* i : type of coder */ -); - -void decode_acelp_gains( - const float *code, - const int16_t gains_mode, - const float mean_ener_code, - float *gain_pit, - float *gain_code, - int16_t **pt_indice, - float *past_gpit, - float *past_gcode, - float *gain_inov, - const int16_t L_subfr, - float *code2, - float *gain_code2 ); - -void gain_dec_gacelp_uv( - int16_t index, /* i/o: Quantization index vector */ - const float *code, /* i : algebraic code excitation */ - const float *code2, /* i : algebraic code excitation */ - const float mean_ener, /* i : mean energy */ - const int16_t lcode, /* i : Subframe size */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codebook gain */ - float *gain_code2, /* o : Quantized codebook gain */ - float *past_gpit, /* i/o: past gain of pitch */ - float *past_gcode, /* i/o: past energy of code */ - float *gain_inov /* o : unscaled innovation gain */ -); - -void limit_T0_voiced_ivas( - const int16_t nbits, - const int16_t res, - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - const int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_min_frac, /* o : lower pitch limit */ - int16_t *T0_max, /* o : higher pitch limit */ - int16_t *T0_max_frac, /* o : higher pitch limit */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max /* i : Maximum pitch lag */ -); - - -/*! r: floating pitch value */ -float Mode2_pit_decode_flt( - const int16_t coder_type, /* i : coding model */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t L_subfr, /* i : sub-frame length */ - int16_t **pt_indice, /* i/o: quantization indices pointer */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_res, /* i/o: pitch resolution */ - int16_t *T0_min, /* i/o: lower limit for close-loop search */ - int16_t *T0_min_frac, /* i/o: lower limit for close-loop search */ - int16_t *T0_max, /* i/o: higher limit for close-loop search */ - int16_t *T0_max_frac, /* i/o: higher limit for close-loop search */ - const int16_t pit_min, - const int16_t pit_fr1, - const int16_t pit_fr1b, - const int16_t pit_fr2, - const int16_t pit_max, - const int16_t pit_res_max ); - -void Mode2_abs_pit_dec_flt( - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_res, /* o : pitch resolution */ - int16_t **pt_indice, /* i/o: pointer to Vector of Q indexes */ - const int16_t pit_min, - const int16_t pit_fr1, - const int16_t pit_fr2, - const int16_t pit_res_max ); - -void Mode2_delta_pit_dec_flt( - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* i : delta search min */ - int16_t *T0_min_frac, /* i : delta search min */ - int16_t **pt_indice /* i/o: pointer to Vector of Q indexes */ -); - -void formant_post_filt_ivas( - PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ - float *synth_in, /* i : 12k8 synthesis */ - const float *Aq, /* i : LP filter coefficient */ - float *synth_out, /* i/o: input signal */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : sub-frame length */ - const float lp_noise, /* i : background noise energy */ - const int32_t brate, /* i : bitrate */ - const int16_t off_flag /* i : Off flag */ -); - - -int16_t dlpc_avq( - int16_t *index, /* i : Quantization indices */ - float *LSF_Q, /* o : Quantized LSF vectors */ - const int16_t numlpc, /* i : Number of sets of lpc */ - const int32_t sr_core /* i : internal sampling rate */ -); - -int16_t decode_lpc_avq( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t numlpc, /* i : Number of sets of lpc */ - int16_t *param_lpc, /* o : lpc parameters */ - const int16_t ch, /* i : channel */ - const int16_t element_mode, /* i : element mode */ - const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ -); - - -void vlpc_2st_dec_flt( - float *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ - int16_t *indx, /* i : index[] (4 bits per words) */ - const int16_t mode, /* i : 0=abs, >0=rel */ - const int32_t sr_core /* i : internal sampling rate */ -); - -void lsf_weight_2st_flt( - const float *lsfq, - float *w, - const int16_t mode, - const int32_t sr_core ); - -void mdct_window_sine_flt( - float *window, - const int32_t Fs, - const int16_t n, - const int16_t window_type, - const int16_t element_mode ); - -void mdct_window_aldo_flt( - float *window1, - float *window2, - const int16_t n ); - -void AVQ_cod_lpc( - const float nvec[], /* i : vector to quantize */ - int16_t nvecq[], /* o : quantized normalized vector (assuming the bit budget is enough) */ - int16_t *indx, /* o : index[] (4 bits per words) */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void AVQ_dec_lpc_ivas( - const int16_t indx[], /* i : index[] (4 bits per words) */ - int16_t nvecq[], /* o : vector quantized */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void vlpc_1st_dec_flt( - const int16_t index, /* i : codebook index */ - float *lsfq, /* i/o: i:prediction o:quantized lsf */ - const int32_t sr_core ); - -void WindowSignal_flt( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - int16_t offset, /* i : left folding point offset relative to the input signal pointer */ - const int16_t left_overlap_mode, /* i : overlap mode of left window half */ - const int16_t right_overlap_mode, /* i : overlap mode of right window half */ - int16_t *left_overlap_length, /* o : TCX window left overlap length */ - int16_t *right_overlap_length, /* o : TCX window right overlap length */ - const float in[], /* i : input signal */ - int16_t *L_frame, /* i/o: frame length */ - float out[], /* o : output windowed signal */ - const int16_t truncate_aldo, /* i : nonzero to truncate long ALDO slope */ - const int16_t fullband /* i : fullband flag */ -); - -void HBAutocorrelation( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - float speech[], /* i : speech */ - int16_t L_frame_glob, /* i/o: frame length */ - float *r /* o : autocorrelations vector */ -); - -void TNSAnalysis( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const int16_t L_frame, /* i : frame length */ - int16_t L_spec, /* i : length of the spectrum */ - const int16_t transform_type, /* i : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */ - const int16_t isAfterACELP, /* i : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */ - float spectrum[], /* i : MDCT spectrum of the subframe */ - TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ - const float ltp_gain, /* i : ltp gain */ - STnsData *pTnsData, /* o : TNS data */ - int8_t *pfUseTns, /* o : Flag indicating if TNS is used */ - float *predictionGain /* o : TNS prediction gain */ -); - -void CalculateTnsFilt( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - const float pSpectrum[], /* i : MDCT spectrum */ - STnsData *pTnsData, /* o : TNS data struct */ - float *predictionGain /* o : TNS prediction gain */ -); - -void ShapeSpectrum( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - float gainlpc[], /* o : MDCT gains for the previous frame */ - const int16_t L_frame_glob, /* i : frame length */ - int16_t L_spec, /* i : length of the spectrum */ - float spectrum[], /* i/o: MDCT spectrum */ - const int8_t fUseTns, /* i : Flag indicating if TNS is used */ - Encoder_State *st, /* i/o: encoder state structure */ - float *scf /* i : scale factors */ -); - -void QuantizeSpectrum( - Encoder_State *st, /* i/o: encoder state structure */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coeffs (M+1) */ - float gainlpc[], /* i : MDCT gains of the previous frame */ - float synth[], /* o : synthesis buffer */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - int16_t prm[], /* o : tcx parameters */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -/*! r: index of next coefficient */ -int16_t get_next_coeff_mapped_ivas( - int16_t ii[2], /* i/o: coefficient indexes */ - int32_t *pp, /* o : peak(1)/hole(0) indicator */ - int16_t *idx, /* o : index in unmapped domain */ - CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ -); - - -void ACcontextMapping_encode2_no_mem_s17_LC( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - int16_t nt, - int16_t lastnz, - int16_t nbbits, - int16_t resQMaxBits, - CONTEXT_HM_CONFIG *hm_cfg ); - -int16_t ACcontextMapping_decode2_no_mem_s17_LC_ivas( - Decoder_State *st, /* i/o: decoder state */ - int16_t *x, /* o : decoded spectrum */ - int16_t nt, /* i : size of spectrum */ - int16_t nbbits, /* i : bit budget */ - int16_t resQMaxBits, /* i : residual coding maximum bits */ - CONTEXT_HM_CONFIG *hm_cfg /* i : context-based harmonic model configuration */ -); - -int16_t ACcontextMapping_encode2_estimate_no_mem_s17_LC( - const int16_t *x, - const int16_t nt, - int16_t *lastnz, - int16_t *nEncoded, - const int16_t target, - int16_t *stop, - CONTEXT_HM_CONFIG *hm_cfg ); - -void RCcontextMapping_encode2_no_mem_s17_LCS( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - const int16_t nt, - int16_t lastnz, - const int16_t nbbits, - const int16_t resQMaxBits, - CONTEXT_HM_CONFIG *hm_cfg ); - -int16_t RCcontextMapping_decode2_no_mem_s17_LCS( - Decoder_State *st, /* i/o: decoder state */ - int16_t *x, /* o : decoded spectrum */ - const int16_t nt, /* i : size of spectrum */ - const int16_t nbbits, /* i : bit budget */ - const int16_t resQMaxBits, /* i : residual coding maximum bits */ - CONTEXT_HM_CONFIG *hm_cfg /* i : context-based harmonic model configuration */ -); - -int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( - int16_t *x, /* Spectral coefficients */ - const int16_t nt, /* L - size of spectrum (no. of spectral coefficients) */ - int16_t *lastnz_out, - int16_t *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ - const int16_t target, /* Target bits */ - int16_t *stop, - int16_t mode, - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ -); - -Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( - Word16 *x, /* Q0 */ - const Word16 nt, /* Q0 */ - const Word16 target, /* Q0 */ - HANDLE_RC_CONTEXT_MEM hContextMem ); - -Word16 RCcontextMapping_encode2_estimate_bandWise_fx( - Word16 *x, /* Q0 */ - const Word16 start_line, /* Q0 */ - const Word16 end_line, /* Q0 */ - HANDLE_RC_CONTEXT_MEM hContextMem /* Q0 */ -); - -void tcx_get_windows_flt( - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - int16_t *left_overlap, /* o : left overlap length */ - const float **left_win, /* o : left overlap window */ - int16_t *right_overlap, /* o : right overlap length */ - const float **right_win, /* o : right overlap window */ - const int16_t fullband /* i : fullband flag */ -); - -void tcx_windowing_analysis_flt( - const float *signal, /* i : signal vector */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_overlap, /* i : left overlap length */ - const float *left_win, /* i : left overlap window */ - const int16_t right_overlap, /* i : right overlap length */ - const float *right_win, /* i : right overlap window */ - float *output /* o : windowed signal vector */ -); - -void tcx_windowing_synthesis_current_frame_flt( - float *signal, /* i/o: signal vector */ - const float *window, /* i : TCX window vector */ - const float *window_half, /* i : TCX window vector for half-overlap window */ - const float *window_min, /* i : TCX minimum overlap window */ - const int16_t window_length, /* i : TCX window length */ - const int16_t window_half_length, /* i : TCX half window length */ - const int16_t window_min_length, /* i : TCX minimum overlap length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t left_mode, /* i : overlap mode of left window half */ - float *acelp_zir, /* i/o: acelp ZIR */ - const float *old_syn, /* i : old synthesis */ - const float *syn_overl, /* i : overlap synthesis */ - const float *A_zir, - const float *window_trans, /* i : window for transition from ACELP */ - int16_t acelp_zir_len, - const int16_t acelp_mem_len, - const int16_t last_core_bfi, /* i : last mode */ - const int16_t last_is_cng, - const int16_t fullbandScale ); - -void tcx_windowing_synthesis_past_frame_flt( - float *signal, /* i/o: signal vector */ - const float *window, /* i : TCX window vector */ - const float *window_half, /* i : TCX window vector for half-overlap window */ - const float *window_min, /* i : TCX minimum overlap window */ - const int16_t window_length, /* i : TCX window length */ - const int16_t window_half_length, /* i : TCX half window length */ - const int16_t window_min_length, /* i : TCX minimum overlap length */ - const int16_t right_mode /* i : overlap mode (left_mode of current frame) */ -); - -void ProcessIGF( - Encoder_State *st, /* i : Encoder state */ - float *pMDCTSpectrum, /* i : MDCT spectrum */ - const float *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int16_t frameno, /* i : flag indicating index of current subframe */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void ProcessStereoIGF( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - float *pITFMDCTSpectrum[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subframe*/ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void AnalyzePowerSpectrum( - Encoder_State *st, /* i/o: encoder states */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_frameTCX, /* i : full band frame length */ - const int16_t left_overlap, /* i : left overlap length */ - const int16_t right_overlap, /* i : right overlap length */ - const float mdctSpectrum[], /* i : MDCT spectrum */ - const float signal[], /* i : windowed signal corresponding to mdctSpectrum */ - float powerSpec[] /* o : Power spectrum */ -); - -void lpc2mdct_flt( - float *lpcCoeffs, - const int16_t lpcOrder, - float mdct_gains[], - const int16_t length, - const int16_t noInverse ); - -void mdct_preShaping( - float x[], - const int16_t lg, - const float gains[] ); - -void mdct_noiseShaping_flt( - float x[], - const int16_t lg, - const float gains[], - const int16_t nBands ); - - -void PsychAdaptLowFreqDeemph_flt( - float x[], - const float lpcGains[], - float lf_deemph_factors[] ); - -void AdaptLowFreqDeemph_flt( - float x[], - int16_t tcx_lpc_shaped_ari, - const float lpcGains[], - const int16_t lg, - float lf_deemph_factors[] ); - - -void tcx_noise_filling_flt( - float *Q, - const int16_t noiseFillSeed, - const int16_t iFirstLine, - const int16_t lowpassLine, - const int16_t nTransWidth, - const int16_t L_frame, - const float tiltCompFactor, - float fac_ns, - Word16 *infoTCXNoise, - const int16_t element_mode /* i : IVAS element mode */ -); - - -void tcx_decoder_memory_update_flt( - Decoder_State *st, /* i/o: decoder memory state */ - const float *xn_buf, /* i : mdct output buffer */ - float *synth, /* i/o: synth */ - const float *A /* i : Quantized LPC coefficients */ -); - - -/*! r: number of bits used (including "bits") */ -int16_t tcx_ari_res_invQ_spec_flt( - float x_Q[], /* i/o: quantized spectrum */ - const int16_t L_frame, /* i : number of lines */ - const int16_t prm[], /* i : bitstream */ - int16_t target_bits, /* i : number of bits available */ - int16_t bits, /* i : number of bits used so far */ - const float deadzone, /* i : quantizer deadzone */ - const float x_fac[] /* i : spectrum post-quantization factors */ -); - - -void ari_copy_states( - Tastat *source, - Tastat *dest ); - - -void ari_start_encoding_14bits( - Tastat *s ); - - -void ari_start_decoding_14bits_ivas( - Decoder_State *st, - Tastat *s ); - -int16_t ari_start_decoding_14bits_prm_ivas( - const int16_t *ptr, - int16_t bp, - Tastat *s ); - -void ari_decode_14bits_s17_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s, - const uint16_t *cum_freq ); - -void ari_decode_14bits_s27_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s, - const uint16_t *cum_freq ); - -void ari_decode_14bits_bit_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s ); - -/*! r: Q15 */ -Word16 expfp_evs_fx( - const Word16 x, /* i : mantissa Q15-e */ - const Word16 x_e /* i : exponent Q0 */ -); - - -void tcx_arith_render_envelope_ivas_fx( - const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/ - const Word16 L_frame, /* i : number of spectral lines Q0*/ - const Word16 L_spec, /* i : length of the coded spectrum Q0*/ - const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/ - const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/ - const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/ - Word32 env[] /* o : shaped signal envelope Q16*/ -); - -int16_t ari_encode_14bits_range( - int16_t *ptr, - int16_t bp, - int32_t bits, - Tastat *s, - uint16_t cum_freq_low, - uint16_t cum_freq_high ); - - -int16_t ari_done_cbr_encoding_14bits( - int16_t *ptr, - int16_t bp, - int32_t bits, - Tastat *s ); - - -void tcx_arith_encode_envelope( - float spectrum[], /* i/o: MDCT coefficients */ - int16_t signs[], /* o : signs (spectrum[.]<0) */ - const int16_t L_frame, /* i : frame or MDCT length */ - const int16_t L_spec, /* i : length w/o BW limitation */ - Encoder_State *st, /* i/o: coder state */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - int16_t target_bits, /* i : number of available bits */ - int16_t prm[], /* o : bitstream parameters */ - const int16_t use_hm, /* i : use HM in current frame? */ - int16_t prm_hm[], /* o : HM parameter area */ - const int16_t tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - int16_t *arith_bits, /* o : bits used for ari. coding */ - int16_t *signaling_bits, /* o : bits used for signaling */ - const int16_t low_complexity /* i : low-complexity flag */ -); - -void tcx_arith_decode_envelope( - Decoder_State *st, /* i/o: coder state */ - float q_spectrum[], /* o : quantised MDCT coefficients */ - const int16_t L_frame, /* i : frame or MDCT length */ - int16_t L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const int16_t target_bits, /* i : number of available bits */ - const int16_t prm[], /* i : bitstream parameters */ - const int16_t use_hm, /* i : use HM in current frame? */ - const int16_t prm_hm[], /* i : HM parameter area */ - int16_t tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - int16_t *arith_bits, /* o : bits used for ari. coding */ - int16_t *signaling_bits, /* o : bits used for signaling */ - const int16_t low_complexity /* i : low-complexity flag */ -); - -void tcx_arith_decode_envelope_ivas_fx( - Decoder_State *st, /* i/o: coder state */ - Word32 q_spectrum[], /* o : quantised MDCT coefficients */ - Word16 *q_spectrum_e, /* o : MDCT exponent */ - const Word16 L_frame, /* i : frame or MDCT length */ - Word16 L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const Word16 target_bits, /* i : number of available bits */ - Word16 prm[], /* i : bitstream parameters */ - const Word16 use_hm, /* i : use HM in current frame? */ - const Word16 prm_hm[], /* i : HM parameter area */ - Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - Word16 *arith_bits, /* o : bits used for ari. coding */ - Word16 *signaling_bits, /* o : bits used for signaling */ - const Word16 low_complexity /* i : low-complexity flag */ -); - - -void UnmapIndex_fx( - const Word16 PeriodicityIndex, /* Q0 */ - const Word16 Bandwidth, /* Q0 */ - const Word16 LtpPitchLag, /* Q0 */ - const Word8 SmallerLags, /* Q0 */ - Word16 *FractionalResolution, /* Q0 */ - Word32 *Lag /* Q0 */ -); - -/*! r: PeriodicityIndex */ -int16_t SearchPeriodicityIndex( - const float Mdct[], /* i : Coefficients, Mdct[0..NumCoeffs-1] */ - const float UnfilteredMdct[], /* i : Unfiltered coefficients, UnfilteredMdct[0..NumCoeffs-1] */ - const int16_t NumCoeffs, /* i : Number of coefficients */ - const int16_t shortTargetBits, /* i : Target bit budget (excl. Done flag) */ - const int16_t LtpPitchLag, /* i : TCX-LTP pitch */ - const float LtpGain, /* i : LTP gain */ - float *RelativeScore /* o : Energy concentration factor */ -); - - -int16_t EncodeIndex( - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t PeriodicityIndex, - BSTR_ENC_HANDLE hBstr ); - - -Word16 CountIndexBits_fx( - Word16 Bandwidth, /* 0: NB, 1: (S)WB Q0*/ - Word16 PeriodicityIndex /* Q0 */ -); - -int16_t DecodeIndex( - Decoder_State *st, - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t *PeriodicityIndex ); - -#define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) -#define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) - - -Word32 tcx_hm_render_fx( - const Word32 lag, /* i: pitch lag Q0 */ - const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ - Word16 p[] /* o: harmonic model Q13 */ -); - - -void tcx_hm_modify_envelope_fx( - const Word16 gain, /* i: HM gain Q11 */ - const Word32 lag, /* i: pitch lag Q0 */ - const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ - const Word16 p[], /* i: harmonic model Q13 */ - Word32 env[], /* i/o: envelope Q16 */ - const Word16 L_frame /* i: number of spectral lines Q0 */ -); - -void tcx_hm_analyse( - const float abs_spectrum[], /* i : absolute spectrum */ - const int16_t L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const int16_t targetBits, /* i : target bit budget */ - const int16_t coder_type, /* i : GC/VC coder type */ - int16_t prm_hm[], /* o : HM parameters */ - int16_t LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - const float LtpGain, /* i : LTP gain */ - int16_t *hm_bits /* o : bit consumption */ -); - -void tcx_hm_decode_ivas( - const int16_t L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const int16_t targetBits, /* i : target bit budget */ - const int16_t coder_type, /* i : GC/VC coder type */ - const int16_t prm_hm[], /* i : HM parameters */ - const int16_t LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - int16_t *hm_bits /* o : bit consumption */ -); - -void tcx_hm_decode( - const Word16 L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const Word16 targetBits, /* i : target bit budget */ - const Word16 coder_type, /* i : GC/VC coder type */ - const Word16 prm_hm[], /* i : HM parameters */ - const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - Word16 *hm_bits /* o : bit consumption */ -); - -void coder_tcx( - Encoder_State *st, /* i/o: encoder state structure */ - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ - float synth[], /* o : decoded synthesis */ - const int16_t L_frame_glob, /* i : frame length */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - int16_t nb_bits, /* i : bit budget */ - float spectrum[], /* i/o: MDCT spectrum */ - int16_t prm[], /* o : tcx parameters */ - CONTEXT_HM_CONFIG *hm_cfg, - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void coder_tcx_post( - Encoder_State *st, /* i/o: encoder memory state */ - float *A, /* o : Quantized LPC coefficients */ - const float *Ai /* i : Unquantized (interpolated) LPC coefficients */ -); - -void decoder_tcx( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - float A[], /* i : coefficients NxAz[M+1] */ - Word16 Aind[], /* i : frame-independent coefficients Az[M+1]*/ - float synth[], /* i/o: synth[-M..lg] */ - float synthFB[], /* i/o: encoder memory state */ - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void decoder_tcx_post( - Decoder_State *st, /* i/o: decoder memory state */ - float *synth, - float *synthFB, - float *A, /* i : A(z) filter coefficients */ - const int16_t bfi, - const int16_t isMCT ); - -void coder_acelp( - Encoder_State *st, /* i/o: coder memory state */ - const float A[], /* i : coefficients 4xAz[M+1] */ - const float Aq[], /* i : coefficients 4xAz_q[M+1] */ - const float speech[], /* i : speech[-M..lg] */ - LPD_state *LPDmem, /* i/o: ACELP memories */ - int16_t *prm, /* o : acelp parameters */ - const float stab_fac, - const int16_t target_bits, - float *gain_pitch_buf, /* o : gain pitch values */ - float *gain_code_buf, /* o : gain code values */ - float *pitch_buf, /* o : pitch values for each subfr.*/ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void coder_acelp_rf( - const int16_t target_bits, /* i : target bits */ - const float speech[], /* i : speech[-M..lg] */ - const int16_t coder_type, /* i : coding type */ - const int16_t rf_frame_type, /* i : rf_frame_type */ - const float A[], /* i : coefficients 4xAz[M+1] */ - const float Aq[], /* i : coefficients 4xAz_q[M+1] */ - const float voicing[], /* i : open-loop LTP gain */ - const int16_t T_op[], /* i : open-loop LTP lag */ - const float stab_fac, /* i : LP stability factor */ - Encoder_State *st, /* i/o: coder memory state */ - ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */ - float *exc_rf, /* i/o: pointer to RF excitation */ - float *syn_rf /* i/o: pointer to RF synthesis */ -); - -void decoder_acelp( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - const float A[], /* i : coefficients NxAz[M+1] */ - ACELP_config acelp_cfg, /* i : ACELP config */ - float synth[], /* i/o: synthesis */ - int16_t *pT, /* o : pitch for all subframe */ - float *pgainT, /* o : pitch gain for all subfr */ - const float stab_fac, /* i : stability of isf */ - float *pitch_buffer, /* o : pitch values for each subfr.*/ - float *voice_factors, /* o : voicing factors */ - const int16_t LSF_Q_prediction, /* i : LSF prediction mode */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void writeTCXMode_fx( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ - Word16 *nbits_start /* o : nbits start Q0*/ -); - -void writeTCXWindowing_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 overlap_mode /* i : overlap mode Q0*/ -); - -void writeLPCparam( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const int16_t param_lpc[], /* i : LPC parameters to write */ - const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ - const int16_t no_param_lpc, /* i : number of LPC parameters */ - int16_t *nbits_lpc /* o : LPC bits written */ -); - -void enc_prm( - Encoder_State *st, /* i/o: encoder state structure */ - int16_t param[], /* i : parameters */ - int16_t param_lpc[], /* i : LPC parameters */ - CONTEXT_HM_CONFIG hm_cfg[], - const int16_t bits_param_lpc[], - const int16_t no_param_lpc ); - -void writeTCXparam( - Encoder_State *st, /* i/o: Encoder State handle */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ - int16_t param[], /* i : parameters */ - const int16_t nbits_header, - const int16_t nbits_start, - const int16_t nbits_lpc, - const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ - int16_t p_param[2], /* i/o: pointer to parameters from previous bs writing */ - const int16_t target_bitsTCX10[2], - const int16_t pre_past_flag ); - -void enc_prm_rf( - Encoder_State *st, /* i/o: encoder memory state */ - const int16_t rf_frame_type, - const int16_t fec_offset ); - -void dec_prm_hm_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t *prm_hm, - const int16_t hm_size ); - -void dec_prm_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t param[], /* o : decoded parameters */ - int16_t param_lpc[], /* i : LPC parameters */ - int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ - int16_t *bitsRead ); -void gaus_L2_dec_flt( - float *code, /* o : decoded gaussian codevector */ - float tilt_code, - const float *A, - float formant_enh_num, - int16_t *seed_acelp /* i/o: random seed */ -); - -/*! r: interpolated value */ -float interpolation( - const float *x, /* i : input vector */ - const float *win, /* i : interpolation window */ - const int16_t frac, /* i : fraction */ - const int16_t up_samp, /* i : upsampling factor */ - const int16_t nb_coef /* i : nb of filter coef */ -); - -void predict_signal_flt( - const float excI[], /* i : input excitation buffer */ - float excO[], /* o : output excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const int16_t frac_max, /* i : max fraction */ - const int16_t L_subfr /* i : subframe size */ -); - -void tcx_ltp_encode( - Encoder_State *st, - const int16_t tcxMode, - const int16_t L_frame, - const float *speech, - float *speech_ltp, - const float *wsp, - const int16_t Top[], - int16_t *ltp_param, - int16_t *ltp_bits, - float *A, - const int16_t disable_ltp, - const int16_t element_mode ); - -void tcx_ltp_post_flt( - Decoder_State *st, - TCX_LTP_DEC_HANDLE hTcxLtpDec, - const int16_t core, - const int16_t output_frame, - const int16_t L_frame, - float sig[], - const float tcx_buf[] ); - -int16_t tcx_ltp_decode_params_flt( - int16_t *ltp_param, - int16_t *pitch_int, - int16_t *pitch_fr, - float *gain, - const int16_t pitmin, - const int16_t pitfr1, - const int16_t pitfr2, - const int16_t pitmax, - const int16_t pitres ); - -void create_IDCT_N_Matrix( - float *inv_matrixFloatQ, /* i/o: RAM buffer */ - const int16_t N, /* i : DCT length, number of time samples */ - const int16_t n_cols, /* i : number of dct coeffs (as DCT may be truncated) */ - const int16_t alloc_size /* i : RAM buffer size in elements */ -); - -void dctT2_N_apply_matrix( - const float *input, /* i : input in fdcng or DCT(fdcng) domain */ - float *output, /* o : output in DCT(fdcng) or fdcng ordomain */ - const int16_t dct_dim, /* i : dct processing dim possibly truncated */ - const int16_t fdcngvq_dim, /* i : fdcng domain length */ - const float *matrix, /* i : IDCT matrix */ - const int16_t matrix_row_dim, /* i : */ - const DCTTYPE dcttype /* i : matrix operation type */ -); - -void extend_dctN_input( - const float *input, /* i : input in fdcng domain */ - const float *dct_input, /* i : input in dctN(fdcng) domain */ - const int16_t in_dim, /* i : in_dim == N */ - float *ext_sig, /* o : extended output in fdcng domain */ - const int16_t out_dim, /* i : output total dim */ - float *matrix, /* i : idct synthesis matrix N rows, n_cols columns */ - const int16_t n_cols, /* i : number of columns == DCT truncation length */ - const DCTTYPE dcttype /* i : matrix operation type */ -); - - -void PulseResynchronization( - const float *src_exc, /* i : Input excitation buffer */ - float *dst_exc, /* o : output excitation buffer */ - const int16_t nFrameLength, /* i : frame length */ - const int16_t nSubframes, /* i : Number of subframes */ - const float pitchStart, /* i : Pitch at the end of the last frame */ - const float pitchEnd /* i : Pitch at the end of the current frame */ -); - -void con_acelp( - float A[], /* i : coefficients NxAz[M+1] */ - const int16_t coder_type, /* i : ACELP coder type */ - float synth[], /* i/o: synthesis */ - int16_t *pT, /* o : pitch for all subframe */ - float *pgainT, /* o : pitch gain for all subfr */ - float stab_fac, /* i : stability of isf */ - Decoder_State *st, /* i/o: coder memory state */ - float pitch_buffer[], /* i/o: floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void con_tcx( - Decoder_State *st, /* i/o: coder memory state */ - float synth[], /* i/o: synth[] */ - const float coh, /* i : coherence of stereo signal */ - int16_t *noise_seed, /* i/o: noise seed for stereo */ - const int16_t only_left, /* i : TD-PLC only in left channel */ - const float A_cng[] /* i : CNG LP filter coefficients */ -); - -int16_t lsf_msvq_ma_decprm_ivas( - Decoder_State *st, - int16_t *param_lpc ); - -int16_t dec_lsf_tcxlpc_ivas( - Decoder_State *st, /* i : Decoder state */ - int16_t **indices, /* o : Ptr to VQ indices */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk /* i : codebook selector */ -); - -int16_t D_lsf_tcxlpc_ivas( - const int16_t indices[], /* i : VQ indices */ - float lsf_q[], /* o : quantized lsf */ - Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk, /* i : codebook selector */ - const float mem_MA[] /* i : MA memory */ -); - -int16_t Q_lsf_tcxlpc( - /* const */ float lsf[], /* i : original lsf */ - float lsf_q[], /* o : quantized lsf */ - Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ - int16_t indices[], /* o : VQ indices */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk, /* i : codebook selector */ - const float mem_MA[], /* i : MA memory */ - const int16_t coder_type, /* i : acelp extended mode */ - const float *Bin_Ener /* i : Spectrum energy */ -); - -void midlsf_enc( - const float qlsf0[], - const float qlsf1[], - const float lsf[], - int16_t *idx, - const int16_t N, - const float *Bin_Ener, - const int16_t narrowBand, - const int32_t sr_core, - const int16_t coder_type ); - -void lsf_end_enc( - Encoder_State *st, - const float *lsf, - float *qlsf, - const int16_t nBits, - const int16_t coder_type_org, - const int16_t force_sf, - int16_t *lpc_param, - int16_t *no_stages, - int16_t *bits_param_lpc, - const int16_t coder_type_raw, - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void lsf_end_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t coder_type_org, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t nBits, /* i : number of bits used for ISF quantization*/ - float *qlsf, /* o : quantized LSFs in the cosine domain */ - int16_t *lpc_param, /* i : LPC parameters */ - int16_t *LSF_Q_prediction, /* o : LSF prediction mode */ - int16_t *nb_indices, /* o : number of indices */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void lpc_quantization( - Encoder_State *st, - const float lsp[], - const float lspmid[], - float lsp_q[], - float lsf_q[], - float lspmid_q[], - const int16_t coder_type, - const int16_t acelp_midLpc, - int16_t param_lpc[], - int16_t nbits_lpc[], - int16_t *bits_param_lpc, - int16_t *no_param_lpc ); - -void lpc_unquantize( - Decoder_State *st, - float *lsf, - float *lsp, - int16_t *param_lpc, - float *lspmid, - float *lsfmid, - const int16_t coder_type, - int16_t *LSF_Q_prediction /* o : LSF prediction mode */ -); - -void dlpc_bfi_flt( - const int16_t L_frame, - float *lsf_q, /* o : quantized lsfs */ - const float *lsfold, /* i : past quantized lsf */ - const int16_t last_good, /* i : last good received frame */ - const int16_t nbLostCmpt, /* i : counter of consecutive bad frames */ - float mem_MA[], /* i/o: quantizer memory for MA model */ - float mem_AR[], /* i/o: quantizer memory for MA model */ - float *stab_fac, /* i : lsf stability factor */ - float *lsf_adaptive_mean, /* i : lsf adaptive mean, updated when BFI==0 */ - const int16_t numlpc, /* i : Number of division per superframe */ - float lsf_cng[], - const int16_t plcBackgroundNoiseUpdated, - float *lsf_q_cng, /* o : quantized lsfs of background noise */ - float *old_lsf_q_cng, /* o : old quantized lsfs for background noise */ - const float lsfBase[] /* i : base for differential lsf coding */ -); - -void Unified_weighting( - const float Bin_Ener_128[], /* i : FFT Bin energy 128 bins in two sets */ - const float lsf[], /* i : LSF vector */ - float w[], /* o : LP weighting filter (numerator) */ - const int16_t narrowBand, /* i : flag for Narrowband */ - const int16_t unvoiced, /* i : flag for Unvoiced frame */ - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t order /* i : LP order */ -); - -int16_t vad_init( - VAD_CLDFB_HANDLE hVAD_CLDFB /* i/o: CLDFB VAD state */ -); - -int16_t vad_proc( - float realValues[16][60], /* i : CLDFB real values */ - float imagValues[16][60], /* i : CLDFB imag values */ - float *sb_power, /* i/o: Energy of CLDFB data */ - const int16_t numBands, /* i : number of input bands */ - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - int16_t *cldfb_addition, - const int16_t vada_flag /* i : VAD flag */ -); - - -int16_t update_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const float snr, /* i : frequency domain SNR */ - const float tsnr, /* i : time domain SNR */ - const float frame_energy, /* i : current frame energy */ - const float high_eng, /* i : current frame high frequency energy */ - const int16_t vad_flag, /* i : VAD flag */ - const int16_t music_backgound_f /* i : background music flag */ -); - -void frame_spec_dif_cor_rate( - float spec_amp[], /* i : spectral amplitude */ - float pre_spec_low_dif[], /* i/o: low spectrum different */ - float f_tonality_rate[] /* o : tonality rate */ -); - - -void SNR_calc( - const float frame_sb_energy[], /* i : energy of sub-band divided non-uniformly*/ - const float sb_bg_energy[], /* i : sub-band background energy */ - const float t_bg_energy, /* i : time background energy of several frames*/ - float *snr, /* o : frequency domain SNR */ - float *tsnr, /* o : time domain SNR */ - const float frame_energy, /* i : current frame energy */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void background_update( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - float frame_energy, /* i : current frame energy 2 */ - const int16_t update_flag, /* i : current frame update flag */ - const int16_t music_backgound_f, /* i : background music flag */ - const float snr ); - -void bg_music_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - int16_t *music_backgound_f, /* i : background music flag */ - const float frame_energy /* i : current frame energy 1 */ -); - -void est_energy( - float sb_power[], /* o : energy of sub-band divided uniformly */ - float frame_sb_energy[], /* o : energy of sub-band divided non-uniformly*/ - float *p_frame_energy, /* o : frame energy 1 */ - float *p_frame_energy2, /* o : frame energy 2 */ - float *p_high_energy, /* o : high frequency energy */ - const int16_t bw /* i : bandwidth */ -); - - -int16_t comvad_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const float snr, /* i : frequency domain SNR */ - const float tsnr, /* i : time domain SNR */ - const float snr_flux, /* i : average tsnr of several frames */ - const float lt_snr, /* i : long time SNR calculated by fg_energy and bg_energy*/ - const float lt_snr_org, /* i : original long time SNR */ - const float lf_snr, /* i : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const float frame_energy, /* i : current frame energy */ - const int16_t music_backgound_f, /* i : background music flag */ - int16_t *cldfb_addition, - const int16_t vada_flag /* i : VAD flag */ -); - -void calc_snr_flux( - float tsnr, /* i : time-domain SNR */ - float pre_snr[], /* i/o: time-domain SNR storage */ - float *snr_flux /* o : average tsnr */ -); - -void calc_lt_snr( - float *lt_snr_org, /* o : original long time SNR */ - float *lt_snr, /* o : long time SNR calculated by fg_energy and bg_energy*/ - const float fg_energy, /* i : foreground energy sum */ - const int16_t fg_energy_count, /* i : number of the foreground energy frame */ - const float bg_energy, /* i : background energy sum */ - const int16_t bg_energy_count, /* i : number of the background energy frame */ - const int16_t bw_index, /* i : band width index */ - const float lt_noise_sp_center0 /* i : long time noise spectral center by 0 */ -); - -void calc_lf_snr( - float *lf_snr_smooth, /* o : smoothed lf_snr */ - float *lf_snr, /* o : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const float l_speech_snr, /* i : sum of active frames snr */ - const int16_t l_speech_snr_count, /* i : number of the active frame */ - const float l_silence_snr, /* i : sum of the nonactive frames snr */ - const int16_t l_silence_snr_count, /* i : number of the nonactive frame */ - const int16_t fg_energy_count, /* i : number of the foreground energy frame */ - const int16_t bg_energy_count, /* i : number of the background energy frame */ - const int16_t bw_index /* i : band width index */ -); - -float construct_snr_thresh( - const float sp_center[], /* i : spectral center */ - const float snr_flux, /* i : snr flux */ - const float lt_snr, /* i : long time time domain snr */ - const float lf_snr, /* i : long time frequency domain snr */ - const int16_t continuous_speech_num, /* i : continuous speech number */ - const int16_t continuous_noise_num, /* i : continuous noise number */ - const int16_t fg_energy_est_start, /* i : whether if estimated energy */ - const int16_t bw_index /* i : band width index */ -); - -void minimum_statistics_flt( - const int16_t len, /* i : Vector length */ - const int16_t lenFFT, /* i : Length of the FFT part of the vectors */ - float *psize_flt, - float *msPeriodog, /* i : Periodograms */ - float *msNoiseFloor, - float *msNoiseEst, /* o : Noise estimates */ - float *msAlpha, - float *msPsd, - float *msPsdFirstMoment, - float *msPsdSecondMoment, - float *msMinBuf, - float *msBminWin, - float *msBminSubWin, - float *msCurrentMin, - float *msCurrentMinOut, - float *msCurrentMinSubWindow, - int16_t *msLocalMinFlag, - int16_t *msNewMinFlag, - float *msPeriodogBuf, - int16_t *msPeriodogBufPtr, - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t enc_dec, /* i : encoder/decoder indicator */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void generate_comfort_noise_enc( - Encoder_State *st /* i/o: encoder state structure */ -); - -void generate_comfort_noise_dec( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nchan_out /* i : number of output channels */ -); - -void generate_comfort_noise_dec_hf( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t cng_flag /* i : CNG Flag */ -); - -void generate_masking_noise( - float *timeDomainBuffer, /* i/o: time-domain signal */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t length, /* i : frame size */ - const int16_t core, /* i : core */ - const int16_t return_noise, /* i : noise is returned instead of added */ - const int16_t secondary, /* i : indicator for secondary channel */ - const int16_t element_mode, /* i : element mode */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -); - -void generate_masking_noise_update_seed( - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void generate_masking_noise_mdct( - float *mdctBuffer, /* i/o: time-domain signal */ - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void SynthesisSTFT_dirac_flt( - float *fftBuffer, /* i : FFT bins */ - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t samples_out, - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void generate_masking_noise_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - float *Cldfb_RealBuffer, /* o : CLDFD real buffer */ - float *Cldfb_ImagBuffer, /* o : CLDFD imaginary buffer */ - const int16_t slot_index, /* i : CLDFB slot index */ - const int16_t cna_flag, /* i : CNA flag for LB and HB */ - const int16_t fd_cng_flag /* i : FD-CNG flag for HB */ -); - -void generate_stereo_masking_noise( - float *syn, /* i/o: time-domain signal */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t fadeOut, /* i : only fade out of previous state */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -); - -void apply_scale_flt( - float *scale, /* i : scale factor */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t brate, /* i : Bit rate */ - const SCALE_SETUP *scaleTable, /* i : Scale table */ - const int16_t scaleTableSize /* i : Size of scale table */ -); - -void compress_range_flt( - float *in, - float *out, - const int16_t len ); - -void expand_range_flt( - float *in, - float *out, - const int16_t len ); - -void bandcombinepow_flt( - const float *bandpow, /* i : Power for each band */ - const int16_t nband, /* i : Number of bands */ - int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ - const int16_t npart, /* i : Number of partitions */ - const float *psize_inv_flt, /* i : Inverse partition sizes */ - float *partpow /* o : Power for each partition */ -); - -void scalebands_flt( - const float *partpow, /* i : Power for each partition */ - int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ - const int16_t npart, /* i : Number of partitions */ - int16_t *midband, /* i : Central band of each partition */ - const int16_t nFFTpart, /* i : Number of FFT partitions */ - const int16_t nband, /* i : Number of bands */ - float *bandpow, /* o : Power for each band */ - const int16_t flag_fft_en ); - -void AnalysisSTFT_flt( - const float *timeDomainInput, - float *fftBuffer, /* o : FFT bins */ - HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void SynthesisSTFT_flt( - float *fftBuffer, - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t tcx_transition, - HANDLE_FD_CNG_COM hFdCngCom, - const int16_t element_mode, /* i : element mode */ - const int16_t nchan_out /* i : number of output channels */ -); - -void lpc_from_spectrum_flt( - HANDLE_FD_CNG_COM hFdCngCom, - const int16_t start, - const int16_t stop, - const float preemph_fac ); - -ivas_error createFdCngDec( - HANDLE_FD_CNG_DEC *hFdCngDec ); - -void deleteFdCngDec( - HANDLE_FD_CNG_DEC *hFdCngDec ); - -void initFdCngDec( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - -void configureFdCngDec( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ - const int16_t bwidth, - const int32_t total_brate, - const int16_t L_frame, - const int16_t last_L_frame, - const int16_t element_mode ); - -void ApplyFdCng( - float *timeDomainInput, - float *powerSpectrum, - float **realBuffer, /* i/o: Real part of the buffer */ - float **imagBuffer, /* i/o: Imaginary part of the buffer */ - Decoder_State *st, - const int16_t concealWholeFrame, /* i : binary flag indicating frame loss */ - const int16_t is_music ); - -void generate_comfort_noise_dec( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nchan_out /* i : number of output channels */ -); - -/*! r: CNG energy */ -float cng_energy( - const int16_t element_mode, /* i : element mode */ - const int16_t bwidth, /* i : audio bandwidh */ - const int16_t CNG_mode, /* i : mode for DTX configuration */ - const float CNG_att, /* i : attenuation factor for CNG */ - const float *inputBuffer, /* i : input signal */ - const int16_t len /* i : vector length */ -); - -void FdCng_decodeSID( - Decoder_State *st /* i/o: decoder state structure */ -); - -void FdCng_exc_flt( - HANDLE_FD_CNG_COM hFdCngCom, - int16_t *CNG_mode, - const int16_t L_frame, - const float *lsp_old, - const int16_t first_CNG, - float *lsp_CNG, - float *Aq, /* o : LPC coeffs */ - float *lsp_new, /* o : lsp */ - float *lsf_new, /* o : lsf */ - float *exc, /* o : LP excitation */ - float *exc2, /* o : LP excitation */ - float *bwe_exc /* o : LP excitation for BWE */ -); - -void noisy_speech_detection( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ - const int16_t vad, /* i : VAD flag */ - const float syn[] /* i : input time-domain frame */ -); - -void deleteFdCngEnc( - HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure */ -); - - -void resetFdCngEnc( - Encoder_State *st /* i/o: encoder state structure */ -); - -void perform_noise_estimation_enc( - float *band_energies, /* i : energy in critical bands without minimum noise floor E_MIN */ - float *enerBuffer, /* i : energy buffer */ - HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ - const int32_t input_Fs, /* i : input sampling rate */ - CPE_ENC_HANDLE hCPE ); - -void AdjustFirstSID( - Encoder_State *st /* i/o: encoder state structure */ -); - -void FdCng_encodeSID( - Encoder_State *st /* i/o: encoder state structure */ -); - -void GetParameters( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ); - -void SetParameters( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - void *pParameter, - const int16_t **pStream, - int16_t *pnSize ); - -void WriteToBitstream( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - const int16_t **pStream, - int16_t *pnSize, - BSTR_ENC_HANDLE hBstr, - int16_t *pnBits ); - -void ReadFromBitstream( - ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, - Decoder_State *st, - int16_t **pStream, - int16_t *pnSize ); - -void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); -void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); -void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); -void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); - -int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); - -int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); -int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -void ResetTnsData_flt( - STnsData *pTnsData ); - -void ClearTnsFilterCoefficients_flt( - STnsFilter *pTnsFilter ); - - -int16_t DetectTnsFilt( - const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ - const float pSpectrum[], /* i : MDCT spectrum */ - TRAN_DET_HANDLE hTranDet, /* i : transient detection handle */ - const int16_t isTCX10, /* i : TCX10 or TCX20? */ - const float ltp_gain, /* i : LTP gain */ - STnsData *pTnsData, /* o : TNS data struct */ - float *predictionGain /* o : TNS prediction gain */ -); - -void EncodeTnsData( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ - int16_t *stream, /* o : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - int16_t *pnBits /* o : number of written bits */ -); - -int16_t DecodeTnsData_ivas( - STnsConfig const *pTnsConfig, - const int16_t *stream, - int16_t *pnSize, - STnsData *pTnsData ); - -void WriteTnsData( - const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ - const int16_t *stream, /* i : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - BSTR_ENC_HANDLE hBstr, /* o : bitstream */ - int16_t *pnBits /* o : number of written bits */ -); - -void ReadTnsData_ivas( - STnsConfig const *pTnsConfig, - Decoder_State *st, - int16_t *pnBits, - int16_t *stream, - int16_t *pnSize ); - -void cldfbAnalysis_ivas( - const float *timeIn, /* i : time buffer */ - float **realBuffer, /* o : real value buffer */ - float **imagBuffer, /* o : imag value buffer */ - const int16_t samplesToProcess, /* i : number of input samples */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ -); - -void cldfbAnalysis_ts_ivas( - const float *timeIn, /* i : time buffer */ - float realBuffer[CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ - float imagBuffer[CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ - const int16_t samplesToProcess, /* i : samples to process */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ -); - -void cldfbSynthesis_ivas( - float **realBuffer, /* i : real values */ - float **imagBuffer, /* i : imag values */ - float *timeOut, /* o : synthesized output */ - const int16_t samplesToProcess, /* i : number of samples */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ -); - -void configureCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ - const int32_t sampling_rate /* i : sampling rate */ -); - - -void analysisCldfbEncoder_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const float *timeIn, - const int16_t samplesToProcess, - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float *ppBuf_Ener ); - -void analysisCldfbEncoder_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word32 *timeIn, /*q11*/ - Word16 timeInq, /*q0*/ - Word16 samplesToProcess, /*q0*/ - Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word32 *ppBuf_Ener, - Word16 *enerBuffSum_exp, - CLDFB_SCALE_FACTOR *scale ); - -ivas_error openCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const int32_t sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - -void resampleCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ - const int32_t newSamplerate /* i : new samplerate to operate */ -); - -ivas_error cldfb_save_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void cldfb_restore_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void cldfb_reset_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - -void fft_cldfb( - float *data, /* i/o: input/output vector */ - const int16_t size /* i : size of fft operation */ -); - -void BITS_ALLOC_init_config_acelp_IVAS( - const int32_t bit_rate, - const int16_t narrowBand, - const int16_t nb_subfr, - ACELP_config *acelp_cfg /* o : configuration structure of ACELP */ -); - -int16_t BITS_ALLOC_config_acelp_IVAS( - const int16_t bits_frame, /* i : remaining bit budget for the frame */ - const int16_t coder_type, /* i : acelp coder type */ - ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t nb_subfr /* i : number of subframes */ -); - - -void FEC_clas_estim( - const float *syn, - const float *pitch, /* i : pitch values for each subframe */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t coder_type, /* i : coder type */ - const int16_t codec_mode, /* i : codec mode */ - float *mem_syn_clas_estim, /* i/o: memory of the synthesis signal for frame class estimation */ - int16_t *clas, /* i/o: frame classification */ - float *lp_speech, /* i/o: long term active speech energy average */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - int16_t *decision_hyst, /* i/o: hysteresis of the music/speech decision */ - int16_t *locattack, /* i/o: detection of attack (mainly to localized speech burst) */ - int16_t *UV_cnt, /* i/o: number of consecutives frames classified as UV */ - float *LT_UV_cnt, /* i/o: long term consecutives frames classified as UV */ - float *Last_ener, /* i/o: last_energy frame */ - int16_t *amr_io_class, /* i/o: classification for AMR-WB IO mode */ - float *lt_diff_etot, /* i/o: long-term total energy variation */ - float *class_para, /* o : classification para. fmerit1 */ - const float LTP_Gain, /* i : */ - const int16_t narrowBand, /* i : */ - const SIGNAL_CLASSIFIER_MODE mode, /* i : */ - const int16_t bfi, /* i : */ - const float preemph_fac, /* i : */ - const int16_t tcxonly, /* i : */ - const int32_t last_core_brate, /* i : last core bitrate */ - const int16_t FEC_mode /* i : ACELP FEC mode */ -); - - -void SetTCXModeInfo( - Encoder_State *st, /* i/o: encoder state structure */ - TRAN_DET_HANDLE hTranDet, /* i/o: transient detection handle */ - int16_t *tcxModeOverlap /* o : window overlap of current frame */ -); - -void TCX_MDCT_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDST_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDCT_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDST_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDXT_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const uint16_t kernel_type ); - -void post_decoder_flt( - Decoder_State *st, - float synth_buf[], - const float pit_gain[], - const int16_t pitch[], - float signal_out[], - float bpf_noise_buf[] ); -void cldfb_synth_set_bandsToZero_flt( - Decoder_State *st, /* i/o: decoder state structure */ - float **rAnalysis, - float **iAnalysis, - const int16_t nTimeSlots ); - -void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ -); - -void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ -); - -void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ -); - -void open_decoder_LPD( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t last_element_mode, /* i : last element mode */ - const int16_t is_init /* i : indicate call during initialization */ -); - -void acelp_plc_mdct_transition( - Decoder_State *st /* i/o: Decoder state */ -); - -void tcxltp_dec_init( - TCX_LTP_DEC_HANDLE hTcxLtpDec, - const int16_t ini_frame, - const int16_t last_codec_mode, - const int16_t element_mode, - const int16_t pit_max, - const int32_t sr_core ); - -void reset_tcx_overl_buf( - TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ -); - -void update_decoder_LPD_cng_flt( - Decoder_State *st, /* i/o: decoder state structure */ - float *timeDomainBuffer, - float *A, - float *bpf_noise_buf ); - -void reconfig_decoder_LPD_ivas( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t bits_frame, /* i : bit budget */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t L_frame_old /* i : frame length */ -); - -void mode_switch_decoder_LPD( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t last_total_brate, /* i : last frame total bitrate */ - const int16_t frame_size_index, /* i : index determining the frame size */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t last_element_mode /* i : last element mode */ -); - -void dec_acelp_tcx_frame( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *concealWholeFrame, /* i/o: concealment flag */ - float *output, /* o : synthesis */ - float *bpf_noise_buf, /* i/o: BPF noise buffer */ - float *pcmbufFB, /* o : synthesis @output_FS */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float pitch_buf[], /* o : floating pitch for each subframe */ - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -); - -void decoder_LPD( - Decoder_State *st, /* i/o: decoder memory state pointer */ - float signal_out[], /* o : signal with LPD delay (7 subfrs) */ - float signal_outFB[], /* o : synthesis @output_FS */ - int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ - float *bpf_noise_buf, /* i/o: BPF noise buffer */ - int16_t bfi, /* i : BFI flag */ - int16_t *bitsRead, /* o : number of read bits */ - int16_t param[], /* o : buffer of parameters */ - float *pitch_buf, /* i/o: floating pitch values for each subfr*/ - float *voice_factors, /* o : voicing factors */ - float *ptr_bwe_exc /* o : excitation for SWB TBE */ -); - -int16_t tcxGetNoiseFillingTilt_flt( - const float A[], - const int16_t L_frame, - const int16_t mode, - float *noiseTiltFactor ); - -void tcxFormantEnhancement_flt( - float xn_buf[], - const float *gainlpc, - float spectrum[], - const int16_t L_frame ); - -void tcxInvertWindowGrouping_flt( - TCX_CONFIG_HANDLE hTcxCfg, - float xn_buf[], - float spectrum[], - const int16_t L_frame, - const int8_t fUseTns, - const int16_t last_core, - const int16_t index, - const int16_t frame_cnt, - const int16_t bfi ); - -void tcx5SpectrumInterleaving( - const int16_t tcx5Size, - float *spectrum ); - -void tcx5SpectrumDeinterleaving( - const int16_t tcx5Size, - float *spectrum ); - -void tcx5TnsGrouping( - const int16_t L_frame, - const int16_t L_spec, - float *spectrum ); - -void tcx5TnsUngrouping( - const int16_t L_frame, - const int16_t L_spec, - float *spectrum, - const int16_t enc_dec ); - -void lerp_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize ); - -void encoderSideLossSimulation( - Encoder_State *st, - PLC_ENC_EVS_HANDLE hPlc_Ext, - float *isf_q, - const float stab_fac, - const int16_t calcOnlyISF, - const int16_t L_frame ); - -void enc_prm_side_Info( - PLC_ENC_EVS_HANDLE hPlc_Ext, - Encoder_State *st ); - -void GplcTcxEncSetup( - const int16_t tcxltp_pitch_int, - PLC_ENC_EVS_HANDLE hPlc_Ext ); - -int16_t encSideSpecPowDiffuseDetector( - float *isf_ref, - float *isf_con, - const int32_t sr_core, - float *prev_isf4_mean, - const int16_t sw, - const int16_t coder_type ); - -void updateSpecPowDiffuseIdx( - const float gain_pitch_buf[], /* i : gain pitch values */ - const float gain_code_buf[], /* i : gain pitch values */ - int16_t glr_idx[2], /* o : */ - float mean_gc[2] /* o : */ -); - -void getLookAheadResSig_flt( - float *speechLookAhead, - const float *A, - float *res, - const int16_t L_frame, - const int16_t L_subfr, - const int16_t m, - const int16_t numSubFrame ); - -void updatelsfForConcealment_flt( - PLC_ENC_EVS_HANDLE decState, - float *lsf ); - -void getConcealedLP_flt( - PLC_ENC_EVS_HANDLE memDecState, - float *AqCon, - const float xsfBase[], - const int32_t sr_core, - const int16_t last_good, - const int16_t L_frame ); - -void RecLpcSpecPowDiffuseLc_flt( - float *ispq, - float *isp_old, - float *isfq, - Decoder_State *st, - const int16_t reset_q ); - -void modify_lsf_flt( - float *lsf, - const int16_t n, - const int32_t sr_core, - const int16_t reset_q ); - -void init_PLC_enc( - PLC_ENC_EVS_HANDLE hPlcExt, - const int32_t sr_core ); - -void gPLC_encInfo( - PLC_ENC_EVS_HANDLE hPlcExt, - const int32_t total_brate, - const int16_t bwidth, - const int16_t last_clas, - const int16_t coder_type ); - -void resetTecDec( - TEC_DEC_HANDLE hTecDec ); - -void calcGainTemp_TBE( - float **pCldfbRealSrc, - float **pCldfbImagSrc, - float *loBuffer, - const int16_t startPos, /*!< Start position of the current envelope. */ - const int16_t stopPos, /*!< Stop position of the current envelope. */ - const int16_t lowSubband, /* lowSubband */ - float *pGainTemp, - const int16_t code ); - -void procTecTfa_TBE( - float *hb_synth, - float *gain, - const int16_t flat_flag, - const int16_t last_core, - const int16_t L_subfr, - const int16_t code ); - -void resetTecEnc( - TEC_ENC_HANDLE hTecEnc, - const int16_t flag ); - -void calcHiEnvLoBuff( - const int16_t noCols, - const int16_t *pFreqBandTable, /* i : freqbandTable */ - const int16_t nSfb, /* i : Number of scalefactors */ - float **pYBuf, - float *loBuf, - float *hiTempEnv ); - -void calcLoEnvCheckCorrHiLo( - const int16_t noCols, - const int16_t *pFreqBandTable, /* i : freqbandTable */ - float *loBuf, - float *loTempEnv, - float *loTempEnv_ns, - float *hiTempEnv, - int16_t *corr_flag /* o : 0 for original, 1 for TEC */ -); - - -void tecEnc_TBE( - int16_t *corrFlag, - const float *voicing, - const int16_t coder_type ); - -void set_TEC_TFA_code( - const int16_t corrFlag, - int16_t *tec_flag, - int16_t *tfa_flag ); - -float Damping_fact_flt( - const int16_t coder_type, /* i : ACELP core coder type */ - const int16_t nbLostCmpt, /* i : compt for number of consecutive lost frame */ - int16_t last_good, /* i : class of last good received frame */ - float stab_fac, /* i : LSF stability factor */ - float *lp_gainp, /* i/o: low passed pitch gain used for concealment */ - const int16_t core /* i : current core: ACELP = 0, TCX20 = 1, TCX10 = 2 */ -); - -float getLevelSynDeemph( - const float h1Init[], /* i : input value or vector to be processed */ - const float A[], /* i : LPC coefficients */ - const int16_t lenLpcExc, /* i : length of the LPC excitation buffer */ - const float preemph_fac, /* i : preemphasis factor */ - const int16_t numLoops /* i : number of loops */ -); - -void genPlcFiltBWAdap( - const int32_t sr_core, /* i : core sampling rate */ - float *lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */ - const int16_t type, /* i : type of filter, either 0 : lowpass or 1 : highpass */ - const float alpha /* i : fade out factor [0 1) used decrease filter tilt */ -); - -void highPassFiltering( - const int16_t last_good, /* i : last classification type */ - const int16_t L_buffer, /* i : buffer length */ - float exc2[], /* i/o: unvoiced excitation before the high pass filtering */ - const float hp_filt[], /* i : high pass filter coefficients */ - const int16_t l_fir_fer /* i : high pass filter length */ -); - -int16_t GetPLCModeDecision( - Decoder_State *st /* i/o: decoder memory state pointer */ -); - -void addBassPostFilter( - const float *harm_timeIn, - const int16_t samplesToProcess, - float **rAnalysis, - float **iAnalysis, - HANDLE_CLDFB_FILTER_BANK cldfb ); - -ivas_error TonalMDCTConceal_Init_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const uint16_t samplesPerBlock, - const uint16_t nSamplesCore, - const uint16_t nScaleFactors, - TCX_CONFIG_HANDLE hTcxCfg ); - -void TonalMDCTConceal_SaveFreqSignal_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const float *mdctSpectrum, - const uint16_t numSamples, - const uint16_t nNewSamplesCore, - const float *scaleFactors, - const int16_t infoIGFStartLine ); - -void TonalMDCTConceal_UpdateState_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const int16_t numSamples, - const float pitchLag, - const int16_t badBlock, - const int16_t tonalConcealmentActive ); - -void TonalMDCTConceal_SaveTimeSignal_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - float *timeSignal, - const int16_t numSamples ); - -void TonalMDCTConceal_Detect_ivas( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - const float pitchLag, /*IN */ - int16_t *umIndices, /*OUT*/ - const PsychoacousticParameters *psychParamsCurrent /*IN*/ -); - -void TonalMDCTConceal_Apply_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - float *mdctSpectrum, /*OUT*/ - const PsychoacousticParameters *psychParamsCurrent /*IN*/ -); - -void TonalMDCTConceal_InsertNoise_ivas( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - float *mdctSpectrum, /*OUT*/ - const int16_t tonalConcealmentActive, - int16_t *pSeed, /*IN/OUT*/ - const float tiltCompFactor, - const float crossfadeGain, - const float concealment_noise[L_FRAME48k], - const float cngLevelBackgroundTrace_bfi, - const int16_t crossOverFreq ); - -void DetectTonalComponents_flt( - uint16_t indexOfTonalPeak[], - uint16_t lowerIndex[], - uint16_t upperIndex[], - uint16_t *pNumIndexes, - const float lastPitchLag, - const float currentPitchLag, - const float lastMDCTSpectrum[], - const float scaleFactors[], - const float secondLastPowerSpectrum[], - const uint16_t nSamples, - const uint16_t nSamplesCore, - float floorPowerSpectrum, - const PsychoacousticParameters *psychParamsCurrent ); - -void RefineTonalComponents_flt( - uint16_t indexOfTonalPeak[], - uint16_t lowerIndex[], - uint16_t upperIndex[], - float phaseDiff[], - float phases[], - uint16_t *pNumIndexes, - const float lastPitchLag, - const float currentPitchLag, - const float lastMDCTSpectrum[], - const float scaleFactors[], - const float secondLastPowerSpectrum[], - const uint16_t nSamples, - const uint16_t nSamplesCore, - float floorPowerSpectrum, - const PsychoacousticParameters *psychParamsCurrent ); - -ivas_error PsychoacousticParameters_Init( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t nBins, /* i : Number of bins (spectral lines) */ - const int8_t nBands, /* i : Number of spectrum subbands */ - const int16_t isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ - const int16_t isWarped, /* i : Flag indicating if the scale is linear or warped */ - PsychoacousticParameters *pPsychParams ); - -void concealment_init( - const int16_t L_frameTCX, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_decode( - const int16_t core, - float *invkoef, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_update( - const int16_t bfi, - const int16_t core, - const int16_t harmonic, - float *invkoef, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_update2( - const float *outx_new, - T_PLCInfo_HANDLE hPlcInfo, - const int16_t L_frameTCX ); - -void concealment_signal_tuning( - Decoder_State *st, - const int16_t bfi, - float *outx_new, - const int16_t past_core_mode ); - -void waveform_adj2( - T_PLCInfo_HANDLE hPlcInfo, - float *overlapbuf, - float *outx_new, - const int16_t delay, - const int16_t bfi_cnt, - const int16_t bfi ); - -float SFM_Cal( - const float fcoef[], - const int16_t n ); - -void set_state_ivas( - int16_t *state, - const int16_t num, - const int16_t N ); - -int16_t RFFTN( - float *afftData, - const float *trigPtr, - const int16_t len, - const int16_t isign ); - -void DoFFT( - float *re2, - float *im2, - const int16_t length ); - -/*! r: flag indicating a valid bitrate */ -int16_t is_EVS_bitrate( - const int32_t ivas_total_brate, /* i : EVS total bitrate */ - int16_t *Opt_AMR_WB /* i : AMR-WB IO flag */ -); - -int16_t getTcxonly_ivas( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t is_ism_format /* i : flag indicating ISM format */ -); - -int16_t getTnsAllowed( - const int32_t total_brate, /* i : total bitrate */ - const int16_t igf, /* i : flag indicating IGF activity*/ - const int16_t element_mode /* i : IVAS element mode */ -); - -int16_t getCtxHm( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t rf_flag /* i : flag to signal the RF mode */ -); - -int16_t getResq( - const int32_t total_brate /* i : total bitrate */ -); - -int16_t getMdctWindowLength( - const int16_t fscale ); - -int16_t sr2fscale( - const int32_t sr_core /* i : internal sampling rate */ -); - -int32_t getCoreSamplerateMode2_flt( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ -); - -float getTcxBandwidth_flt( - const int16_t bwidth /* i : audio bandwidth */ -); - - -int16_t getCnaPresent( - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -int16_t getTcxLtp( - const int32_t sr_core /* i : internal sampling rate */ -); - -int16_t initPitchLagParameters( - const int32_t sr_core, /* i : internal sampling rate */ - int16_t *pit_min, - int16_t *pit_fr1, - int16_t *pit_fr1b, - int16_t *pit_fr2, - int16_t *pit_max ); - -void attenuateNbSpectrum( - const int16_t L_frame, - float *spectrum ); - -void SetModeIndex( - Encoder_State *st, /* i : Encoder state */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t last_element_mode, /* i : last IVAS element mode */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -int16_t getNumTcxCodedLines( - const int16_t bwidth /* i : audio bandwidth */ -); - -int16_t getTcxLpcShapedAri( - const int32_t total_brate, /* i : total bitrate */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void IGFEncApplyMono( - Encoder_State *st, /* i : Encoder state */ - const int16_t igfGridIdx, /* i : IGF grid index */ - float *pMDCTSpectrum, /* i/o: MDCT spectrum */ - float *pPowerSpectrum, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int16_t isTNSActive, /* i : flag indicating if the TNS is active */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void IGFEncApplyStereo( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ - const int16_t igfGridIdx, /* i : IGF grid index */ - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subframe */ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - - -void IGFEncResetTCX10BitCounter_ivas_fx( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ -); - -ivas_error IGF_Reconfig( - IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */ - const int16_t igf, /* i : IGF on/off */ - const int16_t reset, /* i : reset flag */ - const int32_t brate, /* i : bitrate for configuration */ - const int16_t bwidth, /* i : signal bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -void IGFEncSetMode( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - const int32_t total_brate, /* i : encoder total bitrate */ - const int16_t bwidth, /* i : encoder audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -/*! r: number of bits written per frame */ -int16_t IGFEncWriteBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t *pBitOffset, /* i : ptr to bitOffset counter */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ -); - -/*! r: total number of bits written */ -int16_t IGFEncWriteConcatenatedBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -); - -void IGFDecApplyMono_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i : instance handle of IGF Decoder */ - float *spectrum, /* i/o: MDCT spectrum */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void IGFDecCopyLPCFlatSpectrum_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const float *pSpectrumFlat, /* i : LPC flattend spectrum from TCX dec */ - const int16_t igfGridIdx /* i : IGF grid index */ -); - -void IGFDecReadData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ - Decoder_State *st, /* i : decoder state */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ -); - -/*! r: return igfAllZero flag indicating if no envelope is transmitted */ -int16_t IGFDecReadLevel_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ - Decoder_State *st, /* i : decoder state */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ -); - -void IGFDecRestoreTCX10SubFrameData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ - const int16_t subFrameIdx /* i : index of subframe */ -); - -void init_igf_dec_flt( - IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ -); - -void IGFDecSetMode_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ - const int32_t total_brate, /* i : bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t defaultStartLine, /* i : default start subband index */ - const int16_t defaultStopLine, /* i : default stop subband index */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -void IGFDecStoreTCX10SubFrameData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const int16_t subFrameIdx /* i : index of subframe */ -); - -void IGFDecUpdateInfo_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const int16_t subFrameIdx, /* i : subframe index */ - const int16_t igfGridIdx /* i : IGF grid index */ -); - -/*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFConfiguration_flt( - const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - H_IGF_INFO hIGFInfo, /* o : IGF info handle */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -/*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFGetCFTables_flt( - const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : element mode */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const uint16_t **cf_se00, /* i : CF table for t == 0 and f == 0 */ - const uint16_t **cf_se01, /* i : CF table for t == 0 and f == 1 */ - int16_t *cf_off_se01, /* o : offset for CF table above */ - const uint16_t **cf_se02, /* i : CF tables for t == 0 and f >= 2 */ - const int16_t **cf_off_se02, /* o : offsets for CF tables above */ - const uint16_t **cf_se10, /* i : CF table for t == 1 and f == 0 */ - int16_t *cf_off_se10, /* o : offset for CF table above */ - const uint16_t **cf_se11, /* i : CF tables for t == 1 and f >= 1 */ - const int16_t **cf_off_se11 /* o : offsets for CF tables above */ -); - -/*! r: multiplication factor */ -int16_t IGF_ApplyTransFac_flt( - const int16_t val, /* i : input value for multiplication, Q15 */ - const float transFac /* i : multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */ -); - -/*! r: return bitrate index */ -int16_t IGF_MapBitRateToIndex_flt( - const int32_t brate, /* i : bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - - -void IGFSCFDecoderOpen_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data */ - H_IGF_INFO hIgfInfo, /* i : IGF info handle */ - const int32_t total_brate, - const int16_t bwidth, - const int16_t element_mode, - const int16_t rf_mode ); - -void IGFSCFDecoderReset_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i : handle to public data or NULL in case there was no instance created */ -); - -void IGFSCFDecoderDecode_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data or NULL in case there was no instance created */ - Decoder_State *st, /* i/o: pointer to decoder state */ - int16_t *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t indepFlag /* i : if 1 on input the decoder will be forced to reset, - if 0 on input the decoder will be forced to encode without a reset */ -); - -/*! r: offset value */ -int16_t tbe_celp_exc_offset_flt( - const int16_t T0, /* i : Integer pitch */ - const int16_t T0_frac /* i : Fractional part of the pitch */ -); - -void blend_subfr2_flt( - float *sigIn1, /* i : input signal for fade-out */ - float *sigIn2, /* i : input signal for fade-in */ - float *sigOut /* o : output signal */ -); - -void init_tcx_window_cfg( - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX Config handle */ - const int32_t sr_core, /* i : SR core */ - const int32_t input_Fs, /* i : input/output SR */ - const int16_t L_frame, /* i : L_frame at sr_core */ - const int16_t L_frameTCX, /* i : L_frame at i/o SR */ - const int16_t encoderLookahead_enc, /* i : encoder LA at sr_core */ - const int16_t encoderLookahead_FB, /* i : encoder LA at i/o SR */ - const int16_t mdctWindowLength, /* i : window length at sr_core */ - const int16_t mdctWindowLengthFB, /* i : window length at i/o SR */ - const int16_t element_mode /* i : mode of CPE/SCE */ -); - -void init_tcx_cfg( - TCX_CONFIG_HANDLE hTcxCfg, - const int32_t total_brate, - const int32_t sr_core, - const int32_t input_Fs, - const int16_t L_frame, - const int16_t bwidth, - const int16_t L_frameTCX, - const int16_t fscale, - const int16_t encoderLookahead_enc, - const int16_t encoderLookahead_FB, - const float preemph_fac, - const int16_t tcxonly, - const int16_t rf_mode, - const int16_t igf, - const int16_t infoIGFStopFreq, - const int16_t element_mode, - const int16_t ini_frame, - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -#endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 51fbb12d5..9b596ca42 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -49,14 +49,63 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "stat_dec.h" +#include "stat_com.h" #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" +#include "ivas_stat_com.h" #include "ivas_error.h" #include "ivas_error_utils.h" #include "complex_basop.h" #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 + +/*----------------------------------------------------------------------------------* + * Prototypes of global macros + *----------------------------------------------------------------------------------*/ + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef TRUNC +#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) +#endif + +#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) +#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) + +#ifndef ABSVAL +#define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) +#endif + +#ifndef SQR +#define SQR( a ) ( ( a ) * ( a ) ) +#endif + +#ifndef SWAP +#define SWAP( a, b ) \ + { \ + tempr = ( a ); \ + ( a ) = ( b ); \ + ( b ) = tempr; \ + } +#endif + +#ifndef swap +#define swap( x, y, type ) \ + { \ + type u__p; \ + u__p = x; \ + x = y; \ + y = u__p; \ + } +#endif + /*================================================================================*/ /* conversion functions: */ /*================================================================================*/ @@ -10920,7 +10969,6 @@ void IGFEncConcatenateBitstream( BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ ); -#endif void hq_generic_hf_encoding_fx( const Word32 *coefs_fx, /* i : MDCT coefficients of weighted original */ @@ -11205,3 +11253,746 @@ void WriteToBitstream_ivas_fx( Word16 *pnSize, BSTR_ENC_HANDLE hBstr, Word16 *pnBits ); + + +/*===========================================================================================*/ +/*----------------------------------------------------------------------------------* + * MODE1 prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: inverse square root of input value */ +float inv_sqrt( + const float x /* i : input value */ +); + +/*! r: output random value */ +int16_t own_random( + int16_t *seed /* i/o: random seed */ +); + +/*! r: sign of x (+1/-1) */ +float sign( + const float x /* i : input value of x */ +); + +/*! r: logarithm2 of x */ +float log2_f( + const float x /* i : input value of x */ +); + +int16_t norm_ul_float( + uint32_t UL_var1 ); + +/*! r: sum of all vector elements */ +int16_t sum_s( + const int16_t *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: sum of all vector elements */ +int32_t sum_l( + const int32_t *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: sum of all squared vector elements */ +float sum2_f( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +void set_c( + int8_t y[], /* i/o: Vector to set */ + const int8_t a, /* i : Value to set the vector to */ + const int32_t N /* i : Length of the vector */ +); + +void set_s( + int16_t y[], /* i/o: Vector to set */ + const int16_t a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +); + +void set_l( + int32_t y[], /* i/o: Vector to set */ + const int32_t a, /* i : Value to set the vector to */ + const int16_t N /* i : Length of the vector */ +); + +void set_f( + float y[], /* i/o: Vector to set */ + const float a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +); + +void set_zero_fx( + Word32 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); +void set_zero2_fx( + Word32 *vec, /* o : input vector */ + const Word32 lvec /* i : length of the vector */ +); +void set16_zero_fx( + Word16 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); + +void set_zero( + float *vec, /* o : input vector */ + const int16_t lvec /* i : length of the vector */ +); + +void mvr2r( + const float x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvs2s( + const int16_t x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +uint32_t mvr2s( + const float x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvs2r( + const int16_t x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvl2l( + const int32_t x[], /* i : input vector */ + int32_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + + +/*! r: index of the maximum value in the input vector */ +int16_t maximum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *max_val /* o : maximum value in the input vector */ +); +/*! r: index of the maximum value in the input vector */ +int16_t maximumAbs( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *max_val /* o : maximum value in the input vector */ +); + +Word16 maximumAbs_l( + const Word32 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word32 *max_val /* o : maximum value in the input vector */ +); + +/*! r: index of the minimum value in the input vector */ +int16_t minimum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *min_val /* o : minimum value in the input vector */ +); + +/*! r: index of the minimum value in the input vector */ +int16_t minimum_s( + const int16_t *vec, /* i : Input vector */ + const int16_t lvec, /* i : Vector length */ + int16_t *min_val /* o : minimum value in the input vector */ +); + +/*! r: return index with max energy value in vector */ +int16_t emaximum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *ener_max /* o : maximum energy value */ +); + +/*! r: vector mean */ +float mean( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: dot product of x[] and y[] */ +float dotp( + const float x[], /* i : vector x[] */ + const float y[], /* i : vector y[] */ + const int16_t n /* i : vector length */ +); + +void v_add( + const float x1[], /* i : Input vector 1 */ + const float x2[], /* i : Input vector 2 */ + float y[], /* o : Output vector that contains vector 1 + vector 2 */ + const int16_t N /* i : Vector length */ +); + +void v_sub( + const float x1[], /* i : Input vector 1 */ + const float x2[], /* i : Input vector 2 */ + float y[], /* o : Output vector that contains vector 1 - vector 2 */ + const int16_t N /* i : Vector length */ +); + +/*! r: dequanzited gain */ +float usdequant( + const int16_t idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ +); + +void sort( + uint16_t *x, /* i/o: Vector to be sorted */ + uint16_t len /* i/o: vector length */ +); + +void sort_l( + Word32 *x, /* i/o: Vector to be sorted */ + Word16 len /* i/o: vector length */ +); + + +ivas_error push_indice( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + int16_t id, /* i : ID of the indice */ + uint16_t value, /* i : value of the quantized indice */ + int16_t nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_indice( + BSTR_ENC_HANDLE hBstr, + UWord16 value, /* i : value of the quantized indice */ + Word16 nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_bits( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ + const Word16 nb_bits /* i : number of bits to pack */ +); + +/*! r: maximum number of indices */ +Word16 get_ivas_max_num_indices_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +/*! r: maximum number of indices */ +int16_t get_BWE_max_num_indices( + const int32_t extl_brate /* i : extensiona layer bitrate */ +); + +/*! r: maximum number of indices */ +Word16 get_ivas_max_num_indices_metadata_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); +ivas_error ind_list_realloc( + INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ + const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ + Encoder_Struct *st_ivas /* i : IVAS encoder structure */ +); + +ivas_error check_ind_list_limits( + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +); + +void move_indices( + INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ + INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ + const int16_t nb_indices /* i : number of moved indices */ +); + +/*! r: index of the indice in the list, -1 if not found */ +int16_t find_indice( + BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ + const int16_t id, /* i : ID of the indice */ + uint16_t *value, /* o : value of the quantized indice */ + int16_t *nb_bits /* o : number of bits used to quantize the indice */ +); + +/*! r: number of deleted indices */ +uint16_t delete_indice( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t id /* i : ID of the indice */ +); + +/*! r: value of the indice */ +uint16_t get_next_indice( + Decoder_State *st, /* i/o: decoder state structure */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +/*! r: value of the indice */ +uint16_t get_next_indice_1( + Decoder_State *st /* i/o: decoder state structure */ +); + +void get_next_indice_tmp( + Decoder_State *st, /* o : decoder state structure */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +/*! r: value of the indice */ +uint16_t get_indice( + Decoder_State *st, /* i/o: decoder state structure */ + int16_t pos, /* i : absolute position in the bitstream */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +void reset_indices_enc( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t max_num_indices /* i : max number of indices */ +); + +void reset_indices_dec( + Decoder_State *st /* i/o: decoder state structure */ +); + +Word16 rate2EVSmode_float( + const Word32 brate, /* i : bitrate */ + int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ +); + + +/*! r: 1 = OK, 0 = something wrong */ +ivas_error read_indices( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 num_bits, /* i : number of bits in bitstream */ + int16_t *prev_ft_speech, + int16_t *CNG, + int16_t bfi /* i : bad frame indicator */ +); + + +void ivas_set_bitstream_pointers( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +Decoder_State **reset_elements( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void mdct_switching_dec_ivas_fx( + Decoder_State *st /* i/o: decoder state structure */ +); + +int16_t print_disclaimer( + FILE *fPtr ); + +void fft_rel( + float x[], /* i/o: input/output vector */ + const int16_t n, /* i : vector length */ + const int16_t m /* i : log2 of vector length */ +); + +void preemph_ivas_fx( + Word32 *signal, /* i/o: signal Qx*/ + const Word16 mu, /* i : preemphasis factor Q15*/ + const Word16 L, /* i : vector size Q0*/ + Word32 *mem /* i/o: memory (x[-1]) Qx*/ +); + +void create_offset( + UWord32 *offset_scale1, + UWord32 *offset_scale2, + const int16_t mode, + const int16_t prediction_flag ); + +void BASOP_cfft_ivas( + Word32 *re, /* i/o: real part */ + Word32 *im, /* i/o: imag part */ + Word16 s, /* i : stride real and imag part */ + Word16 *scale /* i : scalefactor */ +); + +Word32 ar_div_ivas( + Word32 num, + Word32 denum ); + +Word32 Mult_32_16( + Word32 a, + Word16 b ); + +Word32 Mult_32_32( + Word32 a, + Word32 b ); + + +void bit_allocation_second_fx2( + Word32 *Rk, + Word32 *Rk_sort, + Word16 BANDS, + const Word16 *band_width, + Word16 *k_sort, + Word16 *k_num, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame ); + +void bit_allocation_second_fx2( + Word32 *Rk, + Word32 *Rk_sort, + Word16 BANDS, + const Word16 *band_width, + Word16 *k_sort, + Word16 *k_num, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame ); + +#ifdef DEBUGGING +void read_next_force( + int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ + FILE *f_force, /* i : force switching profile (0 if N/A) */ + int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ +); +#endif + +ivas_error init_encoder_ivas_fx( + Encoder_State *st, /* i/o: state structure */ + Encoder_Struct *st_ivas, /* i/o: encoder state structure */ + const Word16 idchan, /* i : channel ID */ + const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ + const Word16 interval_SID, /* i : interval for SID update */ + const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const Word32 element_brate /* i : element bitrate */ +); + +ivas_error acelp_core_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 inp[], /* i : input signal of the current frame Q_new*/ + Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word32 epsP[M + 1], /* i : LP prediction errors Qx*/ + Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid[M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ + Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn_12k8_16*/ + Word16 *q_old_syn_12k8_16, + Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word16 *unbits, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ + Word16 Q_new ); + +void flip_and_downmix_generic_fx_32( + Word32 input[], /* i : input spectrum Qx*/ + Word32 output[], /* o : output spectrum Qx*/ + const Word16 length, /* i : length of spectra */ + Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ + Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ +); + +void GenTransition_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 element_mode, /* i : element mode : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 rf_flag, /* i : RF flag : Q0 */ + const Word32 total_brate, /* i : total bitrate : Q0 */ + const Word16 prev_Qx ); + +void GenTransition_WB_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ +); + +Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ + const Word16 pos1, /* i: position of the pulse 1 */ + const Word16 pos2, /* i: position of the pulse 2 */ + const Word16 N /* i: number of bits FOR position */ +); + +void bands_and_bit_alloc_ivas_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 noise_lev, /* i : dwn scaling factor */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ + Word16 *max_ener_band, /* o : Sorted order */ + Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ + Word16 *nb_subbands, /* o : Number of subband allowed */ + const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ + Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ + Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ + const Word16 L_frame, /* i : frame length */ + const Word16 element_mode, /* i : element mode */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +void ivas_find_wsp_fx( + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_subfr, /* i : length of subframe Q0*/ + const Word16 nb_subfr, /* i : number of subframes Q0*/ + const Word16 *A_fx, + /* i : A(z) filter coefficients */ // Q12 + Word16 *Aw_fx, + /* o : weighted A(z) filter coefficients */ // Q12 + const Word16 *speech_fx, + /* i : pointer to the denoised speech frame */ // Q_new + const Word16 tilt_fact, + /* i : tilt factor */ // Q15 + Word16 *wsp_fx, + /* o : poitnter to the weighted speech frame */ // Q_new + Word16 *mem_wsp_fx, + /* i/o: W(Z) denominator memory */ // Q_new + const Word16 gamma, + /* i : weighting factor */ // Q15 + const Word16 L_look /* i : look-ahead Q0*/ +); + +Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( + Word16 *x, /* Q0 */ + const Word16 nt, /* Q0 */ + const Word16 target, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem ); + +Word16 RCcontextMapping_encode2_estimate_bandWise_fx( + Word16 *x, /* Q0 */ + const Word16 start_line, /* Q0 */ + const Word16 end_line, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem /* Q0 */ +); + + +/*! r: Q15 */ +Word16 expfp_evs_fx( + const Word16 x, /* i : mantissa Q15-e */ + const Word16 x_e /* i : exponent Q0 */ +); + + +void tcx_arith_render_envelope_ivas_fx( + const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/ + const Word16 L_frame, /* i : number of spectral lines Q0*/ + const Word16 L_spec, /* i : length of the coded spectrum Q0*/ + const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/ + const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/ + const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/ + Word32 env[] /* o : shaped signal envelope Q16*/ +); + +void tcx_arith_decode_envelope_ivas_fx( + Decoder_State *st, /* i/o: coder state */ + Word32 q_spectrum[], /* o : quantised MDCT coefficients */ + Word16 *q_spectrum_e, /* o : MDCT exponent */ + const Word16 L_frame, /* i : frame or MDCT length */ + Word16 L_spec, /* i : length w/o BW limitation */ + const Word16 A_ind[], /* i : quantised LPC coefficients */ + const Word16 target_bits, /* i : number of available bits */ + Word16 prm[], /* i : bitstream parameters */ + const Word16 use_hm, /* i : use HM in current frame? */ + const Word16 prm_hm[], /* i : HM parameter area */ + Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ + Word16 *arith_bits, /* o : bits used for ari. coding */ + Word16 *signaling_bits, /* o : bits used for signaling */ + const Word16 low_complexity /* i : low-complexity flag */ +); + + +void UnmapIndex_fx( + const Word16 PeriodicityIndex, /* Q0 */ + const Word16 Bandwidth, /* Q0 */ + const Word16 LtpPitchLag, /* Q0 */ + const Word8 SmallerLags, /* Q0 */ + Word16 *FractionalResolution, /* Q0 */ + Word32 *Lag /* Q0 */ +); + +#define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) +#define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) + + +Word32 tcx_hm_render_fx( + const Word32 lag, /* i: pitch lag Q0 */ + const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[] /* o: harmonic model Q13 */ +); + + +void tcx_hm_modify_envelope_fx( + const Word16 gain, /* i: HM gain Q11 */ + const Word32 lag, /* i: pitch lag Q0 */ + const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + const Word16 p[], /* i: harmonic model Q13 */ + Word32 env[], /* i/o: envelope Q16 */ + const Word16 L_frame /* i: number of spectral lines Q0 */ +); + +void tcx_hm_decode( + const Word16 L_frame, /* i : number of spectral lines */ + Word32 env[], /* i/o: envelope shape (Q16) */ + const Word16 targetBits, /* i : target bit budget */ + const Word16 coder_type, /* i : GC/VC coder type */ + const Word16 prm_hm[], /* i : HM parameters */ + const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ + Word16 *hm_bits /* o : bit consumption */ +); + +void writeTCXMode_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + Word16 *nbits_start /* o : nbits start Q0*/ +); + +void writeTCXWindowing_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 overlap_mode /* i : overlap mode Q0*/ +); + +void writeLPCparam( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const int16_t param_lpc[], /* i : LPC parameters to write */ + const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ + const int16_t no_param_lpc, /* i : number of LPC parameters */ + int16_t *nbits_lpc /* o : LPC bits written */ +); + +void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); +void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); +void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); +void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); + +int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); + +int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); +int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +void ResetTnsData_flt( + STnsData *pTnsData ); + +void ClearTnsFilterCoefficients_flt( + STnsFilter *pTnsFilter ); + +void EncodeTnsData( + STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ + STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ + Word16 *stream, /* o : internal data stream */ + Word16 *pnSize, /* o : number of written parameters */ + Word16 *pnBits /* o : number of written bits */ +); + +Word16 DecodeTnsData_ivas( + STnsConfig const *pTnsConfig, + const Word16 *stream, + Word16 *pnSize, + STnsData *pTnsData ); + +void WriteTnsData( + const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ + const Word16 *stream, /* i : internal data stream */ + Word16 *pnSize, /* o : number of written parameters */ + BSTR_ENC_HANDLE hBstr, /* o : bitstream */ + Word16 *pnBits /* o : number of written bits */ +); + +void ReadTnsData_ivas( + STnsConfig const *pTnsConfig, + Decoder_State *st, + Word16 *pnBits, + Word16 *stream, + Word16 *pnSize ); + +void analysisCldfbEncoder_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word32 *timeIn, /*q11*/ + Word16 timeInq, /*q0*/ + Word16 samplesToProcess, /*q0*/ + Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 *ppBuf_Ener, + Word16 *enerBuffSum_exp, + CLDFB_SCALE_FACTOR *scale ); + +ivas_error openCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const int32_t sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + +ivas_error openCldfb_ivas_enc( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const Word32 sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + +void resampleCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ + const Word32 newSamplerate /* i : new samplerate to operate */ +); + +ivas_error cldfb_save_memory_ivas( + HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ +); + +void deleteCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ +); + +/*! r: flag indicating a valid bitrate */ +Word16 is_EVS_bitrate( + const Word32 ivas_total_brate, /* i : EVS total bitrate */ + Word16 *Opt_AMR_WB /* i : AMR-WB IO flag */ +); + +void IGFEncResetTCX10BitCounter_ivas_fx( + const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ +); + +ivas_error IGF_Reconfig( + IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */ + const Word16 igf, /* i : IGF on/off */ + const Word16 reset, /* i : reset flag */ + const Word32 brate, /* i : bitrate for configuration */ + const Word16 bwidth, /* i : signal bandwidth */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); + +void ordr_esti( + const Word16 k, /* i : sub-vector index */ + Word16 *Mpos, /* i/o: dominant sub-vector position from ACV */ + Word16 svOrder[], /* i/o: AVQ sub-vector order */ + const Word16 Nsv /* i : total sub-vectors in a sub-frames */ +); + +/*===========================================================================================*/ +#endif diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index ed914f2a1..479bc04d9 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -4,7 +4,6 @@ #include #include "options.h" /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ diff --git a/lib_com/residu_fx.c b/lib_com/residu_fx.c index 665dbfae6..32d18d1fe 100644 --- a/lib_com/residu_fx.c +++ b/lib_com/residu_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" -#include "prot.h" /*--------------------------------------------------------------------* * residu_ivas_fx() diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index bad47f065..172dadf82 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -38,10 +38,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "wmc_auto.h" -#include "prot_fx.h" /* clang-format off */ diff --git a/lib_com/rom_com_fx.c b/lib_com/rom_com_fx.c index 611658884..49f50e162 100644 --- a/lib_com/rom_com_fx.c +++ b/lib_com/rom_com_fx.c @@ -38,7 +38,7 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "wmc_auto.h" #include "rom_com_fx.h" diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 2aa781a43..1f112c911 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -38,7 +38,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6cdf1185a..7e9471c45 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "ivas_prot_fx.h" diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index cececd8f5..44ce806f7 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/tcx_utils_fx.c b/lib_com/tcx_utils_fx.c index 4e40e4ab2..c5ff95e04 100644 --- a/lib_com/tcx_utils_fx.c +++ b/lib_com/tcx_utils_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" #include "rom_basop_util.h" #include "basop_util.h" -#include "prot.h" #define inv_int InvIntTable diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 515746bd5..101bc1df8 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -12,7 +12,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "basop_util.h" -#include "prot.h" /*---------------------------------------------------------------------------- * Local constants diff --git a/lib_com/tools.c b/lib_com/tools.c index 4d9f5e956..e4ccd9955 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -37,7 +37,6 @@ #include #include "options.h" #include -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" @@ -136,23 +135,6 @@ int16_t sum_s( return tmp; } -/*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - int32_t tmpL; - - tmpL = 0; - for ( i = 0; i < lvec; i++ ) - { - tmpL += vec[i]; - } - - return tmpL; -} /*! r: sum of all vector elements */ Word32 sum_l_fx( const Word32 *vec, /* i : input vector */ @@ -171,23 +153,6 @@ Word32 sum_l_fx( return tmpL; } -/*! r: sum of all vector elements */ -float sum_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - float tmp; - - tmp = 0.0f; - for ( i = 0; i < lvec; i++ ) - { - tmp += vec[i]; - } - - return tmp; -} /*---------------------------------------------------------------------- * sum2_f() @@ -228,22 +193,6 @@ Word32 sum2_f_16_gb_fx( return tmp; } -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - float tmp; - - tmp = 0.0f; - for ( i = 0; i < lvec; i++ ) - { - tmp += vec[i] * vec[i]; - } - - return tmp; -} Word32 sum2_16_exp_fx( const Word16 *vec, /* i : input vector Q(15 - exp) */ @@ -532,101 +481,6 @@ void mvs2s( return; } -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -) -{ - int16_t i; - float temp; - uint32_t noClipping = 0; - - if ( n <= 0 ) - { - /* cannot transfer vectors with size 0 */ - return 0; - } - - if ( (void *) y <= (const void *) x ) - { - for ( i = 0; i < n; i++ ) - { - temp = x[i]; - temp = (float) floor( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - noClipping++; - } - else if ( temp < MIN16B_FLT ) - { - temp = MIN16B_FLT; - noClipping++; - } - - y[i] = (int16_t) temp; - } - } - else - { - for ( i = n - 1; i >= 0; i-- ) - { - temp = x[i]; - temp = (float) floor( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - noClipping++; - } - else if ( temp < MIN16B_FLT ) - { - temp = MIN16B_FLT; - noClipping++; - } - - y[i] = (int16_t) temp; - } - } - - return noClipping; -} - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -) -{ - int16_t i; - - if ( n <= 0 ) - { - /* cannot transfer vectors with size 0 */ - return; - } - - if ( (void *) y < (const void *) x ) - { - for ( i = 0; i < n; i++ ) - { - y[i] = (float) x[i]; - } - } - else - { - for ( i = n - 1; i >= 0; i-- ) - { - y[i] = (float) x[i]; - } - } - - return; -} - - void mvl2l( const int32_t x[], /* i : input vector */ int32_t y[], /* o : output vector */ @@ -659,44 +513,6 @@ void mvl2l( return; } - -/*---------------------------------------------------------------------* - * maximum() - * - * Find index and value of the maximum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = vec[0]; - - for ( j = 1; j < lvec; j++ ) - { - if ( vec[j] > tmp ) - { - ind = j; - tmp = vec[j]; - } - } - - if ( max_val != NULL ) - { - *max_val = tmp; - } - - return ind; -} - - /*! r: index of the maximum value in the input vector */ Word16 maximum_s( const Word16 *vec, /* i : input vector */ @@ -766,42 +582,6 @@ Word16 maximum_l( return ind; } -/*---------------------------------------------------------------------* - * maximumAbs() - * - * Find index and value of the maximum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = (float) fabs( vec[0] ); - - for ( j = 1; j < lvec; j++ ) - { - if ( (float) fabs( vec[j] ) > tmp ) - { - ind = j; - tmp = (float) fabs( vec[j] ); - } - } - - if ( max_val != NULL ) - { - *max_val = tmp; - } - - return ind; -} - /*! r: index of the maximum value in the input vector */ Word16 maximumAbs_l( const Word32 *vec, /* i : input vector */ @@ -835,42 +615,6 @@ Word16 maximumAbs_l( return ind; } -/*---------------------------------------------------------------------* - * minimum() - * - * Find index of a minimum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = vec[0]; - - for ( j = 1; j < lvec; j++ ) - { - if ( vec[j] < tmp ) - { - ind = j; - tmp = vec[j]; - } - } - - if ( min_val != NULL ) - { - *min_val = tmp; - } - - return ind; -} - /*-------------------------------------------------------------------* * minimum_s() * @@ -988,59 +732,6 @@ Word16 minimum_l( return ind; } -/*---------------------------------------------------------------------* - * emaximum() - * - * Find index of a maximum energy in a vector - *---------------------------------------------------------------------*/ - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -) -{ - int16_t j, ind; - float temp; - - *ener_max = 0.0f; - ind = 0; - - for ( j = 0; j < lvec; j++ ) - { - temp = vec[j] * vec[j]; - - if ( temp > *ener_max ) - { - ind = j; - *ener_max = temp; - } - } - - return ind; -} - - -/*---------------------------------------------------------------------* - * mean() - * - * Find the mean of the vector - *---------------------------------------------------------------------*/ - -/*! r: mean of vector */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - float tmp; - - tmp = sum_f( vec, lvec ) / (float) lvec; - - return tmp; -} - /*---------------------------------------------------------------------* * dotp() * @@ -1168,114 +859,6 @@ float inv_sqrt( return (float) ( 1.0 / sqrt( x ) ); } - -/*-------------------------------------------------------------------* - * conv() - * - * Convolution between vectors x[] and h[] written to y[] - * All vectors are of length L. Only the first L samples of the - * convolution are considered. - *-------------------------------------------------------------------*/ - -void conv( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response (or second input vector) */ - float y[], /* o : output vetor (result of convolution) */ - const int16_t L /* i : vector size */ -) -{ - float temp; - int16_t i, n; - for ( n = 0; n < L; n++ ) - { - temp = x[0] * h[n]; - for ( i = 1; i <= n; i++ ) - { - temp += x[i] * h[n - i]; - } - y[n] = temp; - } - - return; -} - -/*-------------------------------------------------------------------* - * fir() - * - * FIR filtering of vector x[] with filter having impulse response h[] - * written to y[] - * The input vector has length L and the FIR filter has an order of K, i.e. - * K+1 coefficients. The memory of the input signal is provided in the vector mem[] - * which has K values - * The maximum length of the input signal is L_FRAME32k and the maximum order - * of the FIR filter is L_FILT_MAX - *-------------------------------------------------------------------*/ - -void fir( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response of the FIR filter */ - float y[], /* o : output vector (result of filtering) */ - float mem[], /* i/o: memory of the input signal (L samples) */ - const int16_t L, /* i : input vector size */ - const int16_t K, /* i : order of the FIR filter (K+1 coefs.) */ - const int16_t upd /* i : 1 = update the memory, 0 = not */ -) -{ - float buf_in[L_FRAME48k + 60], buf_out[L_FRAME48k], s; - int16_t i, j; - - /* prepare the input buffer (copy and update memory) */ - mvr2r( mem, buf_in, K ); - mvr2r( x, buf_in + K, L ); - - if ( upd ) - { - mvr2r( buf_in + L, mem, K ); - } - - /* do the filtering */ - for ( i = 0; i < L; i++ ) - { - s = buf_in[K + i] * h[0]; - - for ( j = 1; j <= K; j++ ) - { - s += h[j] * buf_in[K + i - j]; - } - - buf_out[i] = s; - } - - /* copy to the output buffer */ - mvr2r( buf_out, y, L ); - - return; -} - -/*-------------------------------------------------------------------* - * v_add() - * - * Addition of two vectors sample by sample - *-------------------------------------------------------------------*/ - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] + x2[i]; - } - - return; -} - - /*-------------------------------------------------------------------* * v_add_w64() * @@ -1351,55 +934,9 @@ void v_sub_fixed( } /*-------------------------------------------------------------------* - * v_mult() + * v_multc_fixed() * - * Multiplication of two vectors - *-------------------------------------------------------------------*/ - -void v_mult( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 .* vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] * x2[i]; - } - - return; -} - -/*-------------------------------------------------------------------* - * v_multc() - * - * Multiplication of vector by constant - *-------------------------------------------------------------------*/ - -void v_multc( - const float x[], /* i : Input vector */ - const float c, /* i : Constant */ - float y[], /* o : Output vector that contains c*x */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = c * x[i]; - } - - return; -} - -/*-------------------------------------------------------------------* - * v_multc_fixed() - * - * Multiplication of vector by constant + * Multiplication of vector by constant *-------------------------------------------------------------------*/ void v_multc_fixed( @@ -1456,102 +993,6 @@ void v_multc_fixed_16_16( return; } -/*-------------------------------------------------------------------* - * squant() - * - * Scalar quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Index of the winning codeword and the winning codeword itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codeword */ -int16_t squant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float cb[], /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -) -{ - float dist, mindist, tmp; - int16_t c, idx; - - idx = 0; - mindist = 1e16f; - - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - tmp = x - cb[c]; - dist += tmp * tmp; - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - *xq = cb[idx]; - - return idx; -} - -/*! r: index of the winning codeword */ -int16_t squant_int( - uint8_t x, /* i : scalar value to quantize */ - uint8_t *xq, /* o : quantized value */ - const uint8_t *cb, /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -) -{ - int16_t i, idx; - float mindist, d; - - idx = 0; - mindist = 10000000.0f; - for ( i = 0; i < cbsize; i++ ) - { - d = (float) ( x - cb[i] ) * ( x - cb[i] ); - if ( d < mindist ) - { - mindist = d; - idx = i; - } - } - *xq = cb[idx]; - - return idx; -} - - -/*-------------------------------------------------------------------* - * usquant() - * - * Uniform scalar quantizer according to MMSE criterion - * (nearest neighbour in Euclidean space) - * - * Applies quantization based on scale and round operations. - * Index of the winning codeword and the winning codeword itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codeword */ -int16_t usquant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta, /* i : quantization step */ - const int16_t cbsize /* i : codebook size */ -) -{ - int16_t idx; - - idx = (int16_t) max( 0.f, min( cbsize - 1, ( ( x - qlow ) / delta + 0.5f ) ) ); - *xq = idx * delta + qlow; - - return idx; -} - - /*-------------------------------------------------------------------* * usdequant() * @@ -1573,219 +1014,6 @@ float usdequant( return ( g ); } - -/*-------------------------------------------------------------------* - * vquant() - * - * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Index of the winning codevector and the winning vector itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codevector */ -int16_t vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize /* i : codebook size */ -) -{ - float dist, mindist, tmp; - int16_t c, d, idx, j; - - idx = 0; - mindist = 1e16f; - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - x[d] -= x_mean[d]; - } - } - - j = 0; - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - for ( d = 0; d < dim; d++ ) - { - tmp = x[d] - cb[j++]; - dist += tmp * tmp; - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = 0; d < dim; d++ ) - { - xq[d] = cb[j++]; - } - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - xq[d] += x_mean[d]; - } - } - - return idx; -} - -/*-------------------------------------------------------------------* - * w_vquant() - * - * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Weights are put on the error for each vector element. - * Index of the winning codevector and the winning vector itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codevector */ -int16_t w_vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - const int16_t weights[], /* i : error weights */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize, /* i : codebook size */ - const int16_t rev_vect /* i : reverse codebook vectors */ -) -{ - float dist, mindist, tmp; - int16_t c, d, idx, j, k; - - idx = 0; - mindist = 1e16f; - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - x[d] -= x_mean[d]; - } - } - - j = 0; - if ( rev_vect ) - { - k = dim - 1; - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - - for ( d = k; d >= 0; d-- ) - { - tmp = x[d] - cb[j++]; - dist += weights[d] * ( tmp * tmp ); - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = k; d >= 0; d-- ) - { - xq[d] = cb[j++]; - } - } - else - { - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - - for ( d = 0; d < dim; d++ ) - { - tmp = x[d] - cb[j++]; - dist += weights[d] * ( tmp * tmp ); - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = 0; d < dim; d++ ) - { - xq[d] = cb[j++]; - } - } - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - xq[d] += x_mean[d]; - } - } - - return idx; -} - - -/*----------------------------------------------------------------------------------* - * v_sort() - * - * Sorting of vectors. This is very fast with almost ordered vectors. - *----------------------------------------------------------------------------------*/ - -void v_sort_float( - float *r, /* i/o: Vector to be sorted in place */ - const int16_t lo, /* i : Low limit of sorting range */ - const int16_t up /* I : High limit of sorting range */ -) -{ - int16_t i, j; - float tempr; - - for ( i = up - 1; i >= lo; i-- ) - { - tempr = r[i]; - for ( j = i + 1; j <= up && ( tempr > r[j] ); j++ ) - { - r[j - 1] = r[j]; - } - - r[j - 1] = tempr; - } - - return; -} - void sort( UWord16 *x, /* i/o: Vector to be sorted */ UWord16 len /* i/o: vector length */ @@ -1810,426 +1038,3 @@ void sort( return; } - -/*---------------------------------------------------------------------* - * var() - * - * Calculate the variance of a vector - *---------------------------------------------------------------------*/ - -/*! r: variance of vector */ -float var( - const float *x, /* i : input vector */ - const int16_t len /* i : length of inputvector */ -) -{ - float m; - float v; - int16_t i; - - m = mean( x, len ); - - v = 0.0f; - for ( i = 0; i < len; i++ ) - { - v += ( x[i] - m ) * ( x[i] - m ); - } - v /= len; - - return v; -} - - -/*---------------------------------------------------------------------* - * std_dev() - * - * Calculate the standard deviation of a vector - *---------------------------------------------------------------------*/ - -/*! r: standard deviation */ -float std_dev( - const float *x, /* i : input vector */ - const int16_t len /* i : length of the input vector */ -) -{ - int16_t i; - float std; - - std = 1e-16f; - for ( i = 0; i < len; i++ ) - { - std += x[i] * x[i]; - } - - std = (float) sqrt( std / len ); - - return std; -} - - -/*---------------------------------------------------------------------* - * dot_product_mat() - * - * Calculates dot product of type x'*A*x, where x is column vector of size m, - * and A is square matrix of size m*m - *---------------------------------------------------------------------*/ - -/*! r: the dot product x'*A*x */ -float dot_product_mat( - const float *x, /* i : vector x */ - const float *A, /* i : matrix A */ - const int16_t m /* i : vector & matrix size */ -) -{ - int16_t i, j; - float suma, tmp_sum; - const float *pt_x, *pt_A; - - pt_A = A; - suma = 0; - - for ( i = 0; i < m; i++ ) - { - tmp_sum = 0; - pt_x = x; - for ( j = 0; j < m; j++ ) - { - tmp_sum += *pt_x++ * *pt_A++; - } - - suma += x[i] * tmp_sum; - } - - return suma; -} - - -/*--------------------------------------------------------------------------------* - * polezero_filter() - * - * Y(Z)=X(Z)(b[0]+b[1]z^(-1)+..+b[L]z^(-L))/(a[0]+a[1]z^(-1)+..+a[M]z^(-M)) - * mem[n]=x[n]+cp[0]mem[n-1]+..+cp[M-1]mem[n-M], where cp[i]=-a[i+1]/a[0] - * y[n]=cz[0]mem[n]+cz[1]mem[n-1]+..+cz[L]mem[n-L], where cz[i]=b[i]/a[0] - * mem={mem[n-K] mem[n-K+1] . . . . mem[n-2] mem[n-1]}, where K=max(L,M) - * - * a[0] must be equal to 1.0f! - *---------------------------------------------------------------------------------*/ - -void polezero_filter( - const float *in, /* i : input vector */ - float *out, /* o : output vector */ - const int16_t N, /* i : input vector size */ - const float *b, /* i : numerator coefficients */ - const float *a, /* i : denominator coefficients */ - const int16_t order, /* i : filter order */ - float *mem /* i/o: filter memory */ -) -{ - int16_t i, j, k; - - - for ( i = 0; i < order; i++ ) - { - out[i] = in[i] * b[0]; - for ( j = 0; j < i; j++ ) - { - out[i] += in[i - 1 - j] * b[j + 1] - out[i - 1 - j] * a[j + 1]; - } - - for ( k = order - 1; j < order; j++, k-- ) - { - out[i] += mem[k] * b[j + 1] - mem[k + order] * a[j + 1]; - } - } - - for ( ; i < N; i++ ) - { - out[i] = in[i] * b[0]; - for ( j = 0; j < order; j++ ) - { - out[i] += in[i - 1 - j] * b[j + 1] - out[i - 1 - j] * a[j + 1]; - } - } - - for ( i = 0; i < order; i++ ) - { - mem[i] = in[N - order + i]; - mem[i + order] = out[N - order + i]; - } - - return; -} - -#define WMC_TOOL_SKIP -static float fleft_shift( float input, const int16_t shift ) -{ - return ( input * (float) pow( 2.0, (double) shift ) ); -} - -static float fright_shift( float input, const int16_t shift ) -{ - return ( input * (float) pow( 0.5, (double) shift ) ); -} -#undef WMC_TOOL_SKIP - - -/*--------------------------------------------------------------------------------* - * root_a() - * - * Implements a quadratic approximation to sqrt(a) - * Firstly, a is normalized to lie between 0.25 & 1.0 - * by shifting the input left or right by an even number of - * shifts. Even shifts represent powers of 4 which, after - * the sqrt, can easily be converted to powers of 2 and are - * easily dealt with. - * At the heart of the algorithm is a quadratic - * approximation of the curve sqrt(a) for 0.25 <= a <= 1.0. - * Sqrt(a) approx = 0.27 + 1.0127 * a - 0.2864 * a^2 - * - *---------------------------------------------------------------------------------*/ - -float root_a( - float a ) -{ - int16_t shift_a; - float mod_a; - float approx; - - if ( a <= 0.0f ) - { - return 0.0; - } - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "a" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_a = a; - - shift_a = 0; - while ( mod_a > 1.0 ) - { - mod_a /= 2.0; - shift_a--; - } - - while ( mod_a < 0.5 ) - { - mod_a *= 2.0; - shift_a++; - } -#undef WMC_TOOL_SKIP - - shift_a &= 0xfffe; - mod_a = fleft_shift( a, shift_a ); - - approx = 0.27f + 1.0127f * mod_a - 0.2864f * mod_a * mod_a; - - approx = fright_shift( approx, ( shift_a >> 1 ) ); - - return ( approx ); -} - -/*--------------------------------------------------------------------------------* - * root_a_over_b() - * - * Implements an approximation to sqrt(a/b) - * Firstly a & b are normalized to lie between 0.25 & 1.0 - * by shifting the inputs left or right by an even number - * of shifts. - * Even shifts represent powers of 4 which, after the sqrt, - * become powers of 2 and are easily dealt with. - * At the heart of the algorithm is an approximation of the - * curve sqrt(a/b) for 0.25 <= a <= 1.0 & 0.25 <= b <= 1.0. - * Given the value of b, the 2nd order coefficients p0, p1 - * & p2 can be determined so that... - * Sqrt(a/b) approx = p0 + p1 * a + p2 * a^2 - * where p0 approx = 0.7176 - 0.8815 * b + 0.4429 * b^2 - * p1 approx = 2.6908 - 3.3056 * b + 1.6608 * b^2 - * p2 approx = -0.7609 + 0.9346 * b - 0.4695 * b^2 - * - *---------------------------------------------------------------------------------*/ - -float root_a_over_b( - float a, - float b ) -{ - int16_t shift_a, shift_b, shift; - float mod_a, mod_b; - float p2 = -0.7609f; - float p1 = 2.6908f; - float p0 = 0.7176f; - float b_sqr; - float approx; - - if ( ( a <= 0.0f ) || ( b <= 0.0f ) ) - { - return 0.0; - } -#define WMC_TOOL_SKIP - if ( isinf( a ) ) -#undef WMC_TOOL_SKIP - { - return FLT_MAX; - } -#define WMC_TOOL_SKIP - if ( isinf( b ) ) -#undef WMC_TOOL_SKIP - { - return 0.f; - } - - a += 0x00000001; - b += 0x00000001; - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "a" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_a = a; - - shift_a = 0; - while ( mod_a > 1.0 ) - { - mod_a /= 2.0; - shift_a--; - } - - while ( mod_a < 0.5 ) - { - mod_a *= 2.0; - shift_a++; - } -#undef WMC_TOOL_SKIP - - shift_a &= 0xfffe; - mod_a = fleft_shift( a, shift_a ); - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "b" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_b = b; - - shift_b = 0; - while ( mod_b > 1.0 ) - { - mod_b /= 2.0; - shift_b--; - } - - while ( mod_b < 0.5 ) - { - mod_b *= 2.0; - shift_b++; - } -#undef WMC_TOOL_SKIP - - shift_b &= 0xfffe; - mod_b = fleft_shift( b, shift_b ); - - shift = ( shift_b - shift_a ) >> 1; - - b_sqr = mod_b * mod_b; - - p2 += 0.9346f * mod_b + -0.4695f * b_sqr; - p1 += -3.3056f * mod_b + 1.6608f * b_sqr; - p0 += -0.8815f * mod_b + 0.4429f * b_sqr; - - approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; - - approx = fleft_shift( approx, shift ); - - return ( approx ); -} - -/*--------------------------------------------------------------------------------* - * rint_new() - * - * Round to the nearest integer with mid-point exception - *---------------------------------------------------------------------------------*/ - -double rint_new( - double x ) -{ - int16_t a; - - /* middle value point test */ - if ( ceil( x + 0.5 ) == floor( x + 0.5 ) ) - { - a = (int16_t) ceil( x ); - - if ( a % 2 == 0 ) - { - return ceil( x ); - } - else - { - return floor( x ); - } - } - else - { - return floor( x + 0.5 ); - } -} - - -/*-------------------------------------------------------------------* - * anint() - * - * Round to the nearest integer. - *-------------------------------------------------------------------*/ - -double anint( - double x ) -{ - return ( x ) >= 0 ? (int32_t) ( ( x ) + 0.5 ) : (int32_t) ( (x) -0.5 ); -} - -/*-------------------------------------------------------------------* - * is_numeric_float() - * - * Returns 0 for all NaN and Inf values defined according to IEEE 754 - * floating point number's definition. Returns 1 for numeric values. - *-------------------------------------------------------------------*/ - -int16_t is_numeric_float( - float x ) -{ - union float_int - { - float float_val; - int32_t int_val; - } float_int; - - float_int.float_val = x; - - return ( ( float_int.int_val & 0x7f800000 ) != 0x7f800000 ); -} - -/*-------------------------------------------------------------------* - * delay_signal_float() - * - * Delay buffer by defined number of samples - *-------------------------------------------------------------------*/ - -void delay_signal_float( - float x[], /* i/o: signal to be delayed */ - const int16_t len, /* i : length of the input signal */ - float mem[], /* i/o: synchronization memory */ - const int16_t delay /* i : delay in samples */ -) -{ - float tmp_buffer[L_FRAME48k]; - - mvr2r( mem, tmp_buffer, delay ); - mvr2r( x + len - delay, mem, delay ); - mvr2r( x, x + delay, len - delay ); - mvr2r( tmp_buffer, x, delay ); - - return; -} diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index efa9d7e5a..1aa0bb84a 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -50,7 +50,6 @@ #include "basop32.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot.h" #include "ivas_prot_fx.h" #define INV_BANDS10 3277 /* 1/10 in Q15 */ diff --git a/lib_com/wtda.c b/lib_com/wtda.c index a7ea5314c..3fb408138 100644 --- a/lib_com/wtda.c +++ b/lib_com/wtda.c @@ -37,11 +37,10 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include #include "wmc_auto.h" -#include "prot_fx.h" void wtda_fx32( diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 9597a97ae..11379a62d 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -39,7 +39,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index f1772b9a7..fc8aba043 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ diff --git a/lib_dec/ari_hm_dec.c b/lib_dec/ari_hm_dec.c index da7722325..ef4fb62d5 100644 --- a/lib_dec/ari_hm_dec.c +++ b/lib_dec/ari_hm_dec.c @@ -40,10 +40,9 @@ #include "cnst.h" #include "stl.h" #include "basop_util.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" Word16 DecodeIndex_fx( diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index e5a1220e0..60a59c4da 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -10,7 +10,6 @@ #include "prot_fx.h" #include "basop_util.h" #include "basop_proto_func.h" -#include "prot.h" /* Returns: number of bits consumed */ static Word16 tcx_arith_decode_fx( diff --git a/lib_dec/avq_dec_fx.c b/lib_dec/avq_dec_fx.c index 3bf7e3eb6..a8ba2bfc3 100644 --- a/lib_dec/avq_dec_fx.c +++ b/lib_dec/avq_dec_fx.c @@ -7,7 +7,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ /*-------------------------------------------------------------------* diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index e3401739e..ab349773e 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -6,7 +6,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 8fefa3bb2..dd268fe08 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -7,7 +7,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "rom_com.h" diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index c7d2c5265..2fd3f1d2e 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -8,7 +8,6 @@ #include "basop_util.h" #include "prot_fx.h" #include "rom_com.h" -#include "prot.h" void mode_switch_decoder_LPD_fx( Decoder_State *st, /* i/o: decoder state structure */ diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index e71157a1e..20f7a0adf 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -9,7 +9,6 @@ #include "basop_util.h" #include "stl.h" #include "options.h" -#include "prot.h" #include "math.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 385339664..6c63377fd 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -6,7 +6,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" /*=========================================================================*/ diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index c61bf95ce..ee7a7eca6 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -7,7 +7,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "basop32.h" -#include "prot.h" /*---------------------------------------------------------------------* * Local constants diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 626f25ef4..86cf9784a 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------------- * hq_core_dec() diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 4f74c31ca..907a4a350 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -8,10 +8,9 @@ #include #include "options.h" #include "stl.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "cnst.h" #include "stat_dec.h" #include "basop_util.h" diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4f1db90ff..3865cd61c 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -8,7 +8,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "stl.h" /* required for wmc_tool */ #include "basop_util.h" -#include "prot.h" #include "ivas_prot_fx.h" /*----------------------------------------------------------------------* diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index f5418abc6..e73d89158 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -34,7 +34,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index a6e03eee3..3fe40c1f3 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "cnst.h" @@ -43,7 +43,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 261a3c74e..5bb4736e9 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -36,12 +36,11 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 89ca9a5ba..697f9d715 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -35,7 +35,6 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "prot.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index c22c617c0..9bf53f1de 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -36,10 +36,9 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include diff --git a/lib_dec/ivas_decision_matrix_dec_fx.c b/lib_dec/ivas_decision_matrix_dec_fx.c index a8c151edb..f7fd5e8e2 100644 --- a/lib_dec/ivas_decision_matrix_dec_fx.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -35,11 +35,10 @@ #include "stat_dec.h" #include "rom_com.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------* * ivas_decision_matrix_dec() diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 2cefb0e93..63ee40e2a 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" @@ -43,7 +43,6 @@ #include "ivas_rom_dec.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index afbde5a60..e03913f8a 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -40,7 +40,7 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" @@ -48,7 +48,6 @@ #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_entropy_decoder_fx.c b/lib_dec/ivas_entropy_decoder_fx.c index 0c489fb04..e637a6a93 100644 --- a/lib_dec/ivas_entropy_decoder_fx.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -32,13 +32,12 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 037ef4eb9..8db782c4e 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -40,9 +40,8 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 14e83fe83..664e3eeac 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -32,13 +32,12 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------------* diff --git a/lib_dec/ivas_ism_dtx_dec_fx.c b/lib_dec/ivas_ism_dtx_dec_fx.c index 0365005be..cbf088597 100644 --- a/lib_dec/ivas_ism_dtx_dec_fx.c +++ b/lib_dec/ivas_ism_dtx_dec_fx.c @@ -35,10 +35,9 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * ivas_ism_dtx_dec_fx() diff --git a/lib_dec/ivas_ism_metadata_dec_fx.c b/lib_dec/ivas_ism_metadata_dec_fx.c index 833ed5e16..a6f5e47b6 100644 --- a/lib_dec/ivas_ism_metadata_dec_fx.c +++ b/lib_dec/ivas_ism_metadata_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_stat_enc.h" #include diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 424e6fb86..9040a8a71 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -36,13 +36,12 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 738e5a598..a19ba70ec 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 3b66d3107..f632d86c8 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -35,7 +35,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" @@ -46,7 +46,6 @@ #ifdef DEBUGGING #include "debug.h" #endif -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index 616b15c6e..e68c0142d 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index f5e7816ad..a8b54d3fb 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ls_custom_dec_fx.c b/lib_dec/ivas_ls_custom_dec_fx.c index eabee357b..45f59d82f 100644 --- a/lib_dec/ivas_ls_custom_dec_fx.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -32,10 +32,9 @@ #include #include "options.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index 4ca5c05b0..806785c15 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 4c1d5d190..897fd4433 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -36,7 +36,7 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" @@ -45,7 +45,6 @@ #include "math.h" #include "wmc_auto.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define INV_EPSILON_MANT 214748365 diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index be53d79c8..e03b385b7 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_prot.h" diff --git a/lib_dec/ivas_mcmasa_dec_fx.c b/lib_dec/ivas_mcmasa_dec_fx.c index 687efb3ce..c2228b610 100644 --- a/lib_dec/ivas_mcmasa_dec_fx.c +++ b/lib_dec/ivas_mcmasa_dec_fx.c @@ -35,7 +35,7 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_core_dec_fx.c b/lib_dec/ivas_mct_core_dec_fx.c index 824370bb8..be457da47 100644 --- a/lib_dec/ivas_mct_core_dec_fx.c +++ b/lib_dec/ivas_mct_core_dec_fx.c @@ -33,7 +33,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" #include "cnst.h" @@ -42,7 +42,6 @@ #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index c95a5285a..081eca88d 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index 331bdc253..69f601724 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -34,11 +34,10 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include #include "stat_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*----------------------------------------------------------* diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 190cc6b14..7f079277a 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -33,7 +33,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -44,7 +44,6 @@ #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mono_dmx_renderer_fx.c b/lib_dec/ivas_mono_dmx_renderer_fx.c index 231aee8aa..bb5dead22 100644 --- a/lib_dec/ivas_mono_dmx_renderer_fx.c +++ b/lib_dec/ivas_mono_dmx_renderer_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 3a6480386..391a27522 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index 0fb4163be..bf7fba094 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -35,12 +35,11 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index a5285b5cb..07ea14ea2 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -34,12 +34,11 @@ #include #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 02f37672d..4811911fd 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -34,13 +34,12 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 4a0c62e8d..08ac17799 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "math.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 853aa365f..397f26bbc 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index c225f126a..4bebcda5c 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -39,9 +39,8 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot.h" - #include "prot_fx.h" + #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_qspherical_dec_fx.c b/lib_dec/ivas_qspherical_dec_fx.c index 43ac60305..d34b5402a 100644 --- a/lib_dec/ivas_qspherical_dec_fx.c +++ b/lib_dec/ivas_qspherical_dec_fx.c @@ -37,7 +37,7 @@ #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_range_uni_dec_fx.c b/lib_dec/ivas_range_uni_dec_fx.c index 6d6631f73..e629111ce 100644 --- a/lib_dec/ivas_range_uni_dec_fx.c +++ b/lib_dec/ivas_range_uni_dec_fx.c @@ -38,10 +38,9 @@ #include "rom_com.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /* diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index 417079541..efd766f76 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" @@ -44,7 +44,6 @@ #include #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * ivas_sba_set_cna_cng_flag() * diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index 434fdf5fa..a42c67389 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" @@ -40,7 +40,6 @@ #include #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #ifdef DEBUGGING #include "debug.h" #endif diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index ce4992046..89581565c 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 37489e58f..170256181 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index cddbf8cdf..812027468 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -35,7 +35,7 @@ #include #include "options.h" #include "ivas_stat_dec.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" @@ -45,7 +45,6 @@ #include "ivas_stat_com.h" #include "stat_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index 3ad16b981..2b6b145f9 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -33,13 +33,12 @@ #include #include "options.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" #include "ivas_stat_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c index c67a52b6c..8446af47d 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index b3bddae59..15885a661 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -34,13 +34,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*------------------------------------------------------------------- diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index b0100063a..166ac72e5 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "rom_dec.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index 0db9ab09f..0781d49a6 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -43,7 +43,6 @@ #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 7c1c892aa..c806f358a 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "rom_dec.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index 9e6878faf..d3415a8eb 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" diff --git a/lib_dec/ivas_stereo_eclvq_dec_fx.c b/lib_dec/ivas_stereo_eclvq_dec_fx.c index ed26543d3..693df8c77 100644 --- a/lib_dec/ivas_stereo_eclvq_dec_fx.c +++ b/lib_dec/ivas_stereo_eclvq_dec_fx.c @@ -37,7 +37,7 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index 08ac60ffc..b49ab5399 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -36,12 +36,11 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "basop32.h" #include "ivas_stat_dec.h" diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index b634d4557..22a8c4a90 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index bf343da7f..04781a9cb 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -34,13 +34,12 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "stat_com.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 20fa578f8..69083a078 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -36,10 +36,9 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c8a59cd6a..2dd2a30c3 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" @@ -42,7 +42,6 @@ #include "wmc_auto.h" #include #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_td_dec_fx.c b/lib_dec/ivas_stereo_td_dec_fx.c index e31c9f6bc..8ab7da035 100644 --- a/lib_dec/ivas_stereo_td_dec_fx.c +++ b/lib_dec/ivas_stereo_td_dec_fx.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index a22502188..bb73fe7f0 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -32,13 +32,12 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index 37ffc5128..c908e4dc3 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -34,14 +34,13 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "stat_dec.h" #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" #include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index a4380bd4e..63819b056 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -37,7 +37,6 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer.c index cdabe4700..f9d6d1ca1 100644 --- a/lib_dec/jbm_jb4_circularbuffer.c +++ b/lib_dec/jbm_jb4_circularbuffer.c @@ -38,7 +38,7 @@ #include #include "options.h" #include "string.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local includes */ #include "jbm_jb4_circularbuffer.h" diff --git a/lib_dec/jbm_jb4_circularbuffer.h b/lib_dec/jbm_jb4_circularbuffer.h index de614eeea..9e3102feb 100644 --- a/lib_dec/jbm_jb4_circularbuffer.h +++ b/lib_dec/jbm_jb4_circularbuffer.h @@ -37,7 +37,7 @@ #ifndef JBM_JB4_CIRCULARBUFFER_H #define JBM_JB4_CIRCULARBUFFER_H JBM_JB4_CIRCULARBUFFER_H -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" /** handle for circular buffer (FIFO) with fixed capacity */ diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer.c index 55113ee13..5497a4371 100644 --- a/lib_dec/jbm_jb4_inputbuffer.c +++ b/lib_dec/jbm_jb4_inputbuffer.c @@ -39,7 +39,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include "jbm_jb4_inputbuffer.h" #include "wmc_auto.h" diff --git a/lib_dec/jbm_jb4_jmf.c b/lib_dec/jbm_jb4_jmf.c index 940df5ecb..5ab8242c7 100644 --- a/lib_dec/jbm_jb4_jmf.c +++ b/lib_dec/jbm_jb4_jmf.c @@ -42,7 +42,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local includes */ diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index 4878b7d64..002b4bc10 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -48,7 +48,6 @@ #include "jbm_jb4_inputbuffer.h" #include "jbm_jb4_jmf.h" #include "jbm_jb4sb.h" -#include "prot.h" #include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index 10b91a60c..ac6a28b86 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -44,7 +44,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local headers */ #include "jbm_pcmdsp_apa.h" @@ -54,7 +54,6 @@ #include "rom_dec.h" -#include "prot_fx.h" #define INV_100_Q15 328 #define INV_400_Q15 82 #define INV_80_Q15 410 diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 2cc4c6387..66109b555 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -37,9 +37,8 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" @@ -3398,7 +3397,7 @@ static ivas_error evs_dec_main_fx( move32(); hCoreCoder[0]->output_frame_fx = extract_l( Mult_32_16( hCoreCoder[0]->output_Fs, 0x0290 /*Q0*/ ) ); // Q0 move16(); - mdct_switching_dec( hCoreCoder[0] ); + mdct_switching_dec_ivas_fx( hCoreCoder[0] ); FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index bc8ef03cb..cc9b681fb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #include "rom_dec.h" #include "stl.h" diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 3cf5f51f3..36cadf6ff 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -14,7 +14,6 @@ #include "cnst.h" #include "prot_fx.h" #include "stat_com.h" -#include "prot.h" #include "ivas_prot_fx.h" #define CROSSFADE_THRESHOLD ( 32762 ) // close to 1.0f in Q15 such that (x == 1.0f) is true diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 203f39707..1e8bef488 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "basop_util.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "rom_com.h" diff --git a/lib_enc/FEC_enc_fx.c b/lib_enc/FEC_enc_fx.c index 9106e23e7..87243e8d2 100644 --- a/lib_enc/FEC_enc_fx.c +++ b/lib_enc/FEC_enc_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/SNR_calc_fx.c b/lib_enc/SNR_calc_fx.c index f44530c84..09acfd5dc 100644 --- a/lib_enc/SNR_calc_fx.c +++ b/lib_enc/SNR_calc_fx.c @@ -10,7 +10,6 @@ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 94d7f0471..0f58bcdad 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "rom_com.h" diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 8268d48b1..90768aca1 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -11,7 +11,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ -#include "prot.h" /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ diff --git a/lib_enc/ari_hm_enc_fx.c b/lib_enc/ari_hm_enc_fx.c index a94f45528..76d48ccf4 100644 --- a/lib_enc/ari_hm_enc_fx.c +++ b/lib_enc/ari_hm_enc_fx.c @@ -10,9 +10,7 @@ #include "basop_util.h" #include "rom_com.h" #include "rom_enc.h" -#include "prot.h" -//#include "prot_fx.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 202d60e51..93a0146f3 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -5,9 +5,7 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -#include /* Compilation switches */ -#include "prot.h" /* Function prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 1721476b4..e1b5ca562 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2,12 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_enc.h" /* Encoder static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_enc.h" /* Encoder static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" diff --git a/lib_enc/cod2t32_fx.c b/lib_enc/cod2t32_fx.c index c9bbe5f30..a948a4656 100644 --- a/lib_enc/cod2t32_fx.c +++ b/lib_enc/cod2t32_fx.c @@ -5,7 +5,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index 16651b8f2..a901690e3 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/cod4t64_fx.c b/lib_enc/cod4t64_fx.c index 44cde6f27..99b794b42 100644 --- a/lib_enc/cod4t64_fx.c +++ b/lib_enc/cod4t64_fx.c @@ -5,10 +5,9 @@ #include "options.h" /* VMR-WB compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_enc.h" /* Encoder static table prototypes */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index de9763df0..c54e8ccf4 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,11 +16,9 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include -#include "prot.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#include "prot.h" #endif #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index c2b1c22e1..a2995245d 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -13,7 +13,6 @@ #include "ivas_cnst.h" #include #include "rom_com.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index 82bb5fca9..f3b4aea6b 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -4,14 +4,11 @@ #include #include #include "options.h" -#include "prot.h" -//#include "prot_fx.h" -//#include "basop_mpy.h" +#include "prot_fx.h" #include "cnst.h" /* Common constants */ #include "ivas_cnst.h" #include "rom_com_fx.h" #include "rom_com.h" /* Common constants */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index a6b9e0aa4..6e4d2a043 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -10,7 +10,6 @@ #include #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 1053f8b00..06c49a8d3 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*======================================================================*/ diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index a01550978..64a11be5b 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" #include "prot_fx_enc.h" /*---------------------------------------------------------------------* diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 18948a93f..3ed50017c 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index da2ea5863..ecd4e2f01 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -11,8 +11,7 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index bf04daff5..5b9f67503 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -7,7 +7,6 @@ // #include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 2a621f1d5..cd23c1a6f 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -5,9 +5,8 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index e49463a5c..75e82409e 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index 6970597c8..c86b7e061 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -5,10 +5,9 @@ #include #include #include "options.h" /* Compilation switches */ -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Common constants */ -#include "prot_fx.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ #include "prot_fx_enc.h" #ifdef DEBUGGING diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 9cb2cd8e0..307d42078 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -11,7 +11,6 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "rom_enc.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/find_wsp_fx.c b/lib_enc/find_wsp_fx.c index d08922a2a..155e49904 100644 --- a/lib_enc/find_wsp_fx.c +++ b/lib_enc/find_wsp_fx.c @@ -6,8 +6,7 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 6af068bae..0321cd763 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -7,7 +7,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index a7d60642b..f943b104d 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -7,7 +7,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "rom_enc.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 8ed7e9d6c..375d4c2cf 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -6,8 +6,6 @@ #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" -//#include "prot_fx.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 53ad3dbb2..944cb2649 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -8,7 +8,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-----------------------------------------------------------------* diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index 11583ea11..f22218d13 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -2,12 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/hq_env_enc_fx.c b/lib_enc/hq_env_enc_fx.c index b0875968e..5d47710ed 100644 --- a/lib_enc/hq_env_enc_fx.c +++ b/lib_enc/hq_env_enc_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ /*--------------------------------------------------------------------------------------* * encode_envelope_indices_fx() diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index 4d4742cc1..1cd516b43 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -7,7 +7,6 @@ //#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/hq_lr_enc_fx.c b/lib_enc/hq_lr_enc_fx.c index 424689804..9aca0f646 100644 --- a/lib_enc/hq_lr_enc_fx.c +++ b/lib_enc/hq_lr_enc_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ -#include "prot.h" /*--------------------------------------------------------------------------* * Local function prototypes diff --git a/lib_enc/hvq_enc_fx.c b/lib_enc/hvq_enc_fx.c index 54bc4fb58..b06a1734d 100644 --- a/lib_enc/hvq_enc_fx.c +++ b/lib_enc/hvq_enc_fx.c @@ -8,7 +8,6 @@ //#include "prot_fx.h" #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #define HVQ_ENC_NOISE_DELTA ( (Word16) 3277 ) /* 0.1 in Q15 */ diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 6ac6e6811..f6adb0f31 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -38,13 +38,12 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #define INV_Log2_10_Q15 9864 /*1/log2(10) in Q15*/ @@ -2535,41 +2534,6 @@ void IGFEncResetTCX10BitCounter_ivas_fx( } -/*-------------------------------------------------------------------* - * IGFEncWriteConcatenatedBitstream() - * - * - *-------------------------------------------------------------------*/ - -/*! r: total number of bits written */ -Word16 IGFEncWriteConcatenatedBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -) -{ - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - Word16 i; - Word16 bitsLeft; - UWord8 *pBitstream; - - hPrivateData = &hIGFEnc->igfData; - pBitstream = hPrivateData->igfBitstream; - - for ( i = 0; i < ( hPrivateData->igfBitstreamBits >> 3 ); i++ ) - { - push_next_indice( hBstr, pBitstream[i], 8 ); - } - - bitsLeft = hPrivateData->igfBitstreamBits & 0x7; - if ( bitsLeft > 0 ) - { - push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); - } - - return hIGFEnc->infoTotalBitsWritten; -} - - /*-------------------------------------------------------------------* * IGFEncApplyMono() * diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index ca1759c89..cc4840876 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -8,8 +8,7 @@ #include "options.h" #include "cnst.h" #include "stl.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ #include "stat_enc.h" #include "basop_util.h" diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index 192d7e597..2921b5886 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -36,12 +36,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "stat_enc.h" #include "stat_com.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 5de4e8e92..615ca1b33 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "ivas_cnst.h" #include "ivas_error.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 7bb13239f..46bec5f4d 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 649c5bae5..37d25c508 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -36,10 +36,9 @@ #include #include "options.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "basop_util.h" diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 303adecfd..5f318e959 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -34,12 +34,11 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "wmc_auto.h" #include -#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index f963b55a4..f41eb7f9c 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" @@ -50,7 +49,6 @@ #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*---------------------------------------------------------------* * Local constants diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 1234a6876..a9da7f342 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -37,9 +37,8 @@ #include "ivas_prot.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "basop_util.h" diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index 1b4d5da4a..32e3e7107 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 3fd9c2d7a..811e53d12 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -36,7 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" @@ -45,7 +45,6 @@ #endif #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_enc.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_decision_matrix_enc_fx.c b/lib_enc/ivas_decision_matrix_enc_fx.c index a3194a9d0..1158f72fa 100644 --- a/lib_enc/ivas_decision_matrix_enc_fx.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -35,11 +35,10 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index ec55850fd..7bfa9f268 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index 95a114b67..576bbb2c6 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -32,11 +32,10 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index 2bab65c42..0a2d976e1 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -36,14 +36,13 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_entropy_coder_fx.c b/lib_enc/ivas_entropy_coder_fx.c index eb82aa78a..a95f2884c 100644 --- a/lib_enc/ivas_entropy_coder_fx.c +++ b/lib_enc/ivas_entropy_coder_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index 3844598c6..f1aeb5398 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -36,14 +36,13 @@ #include "ivas_cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" #include #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------------------------* diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 9d31297bd..3eeb45d14 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -34,7 +34,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_enc.h" @@ -42,7 +42,6 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 615660761..64b8991d6 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -34,10 +34,9 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 51af4e5a9..22bf88df8 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -33,12 +33,11 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index a5a1286a2..a36ee78e2 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -38,10 +38,9 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_ism_param_enc_fx.c b/lib_enc/ivas_ism_param_enc_fx.c index bef6912bd..e6b23fcfc 100644 --- a/lib_enc/ivas_ism_param_enc_fx.c +++ b/lib_enc/ivas_ism_param_enc_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index fee34abd8..86237fb31 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -33,12 +33,11 @@ #include #include "options.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index f4fe68c59..21c23c34a 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 36324ae0f..2797fa5e4 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "ivas_rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" @@ -46,7 +45,6 @@ #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- * Local function prototypes diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index 392f1d9ab..9060c786b 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -36,10 +36,9 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index b3f99e27c..bb6ef0d01 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index d11447c03..439c227ae 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -34,14 +34,12 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index dbced19fd..55da30e73 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -36,10 +36,9 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "rom_com.h" diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 7e8547841..88d773b53 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index edfc607ed..403d379fa 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -36,13 +36,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index f09d4513d..7c8b78ffb 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 5eee0975a..648dcdb73 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -36,12 +36,11 @@ #include #include "ivas_cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_enc/ivas_pca_enc_fx.c b/lib_enc/ivas_pca_enc_fx.c index 8b61cb6c8..410d5dd52 100644 --- a/lib_enc/ivas_pca_enc_fx.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 3f0218e97..7a2a28767 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -35,15 +35,13 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" -#include "prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_qspherical_enc_fx.c b/lib_enc/ivas_qspherical_enc_fx.c index eb60d4849..a6f40c8f0 100644 --- a/lib_enc/ivas_qspherical_enc_fx.c +++ b/lib_enc/ivas_qspherical_enc_fx.c @@ -39,7 +39,6 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_range_uni_enc_fx.c b/lib_enc/ivas_range_uni_enc_fx.c index 35ecad69c..cf32c644d 100644 --- a/lib_enc/ivas_range_uni_enc_fx.c +++ b/lib_enc/ivas_range_uni_enc_fx.c @@ -39,7 +39,7 @@ #include "rom_com.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_sba_enc_fx.c b/lib_enc/ivas_sba_enc_fx.c index b247900a0..86427eb2d 100644 --- a/lib_enc/ivas_sba_enc_fx.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -37,13 +37,12 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 9f63c4fc7..8c2c945d6 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 8f93c4d76..e6038186e 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -35,10 +35,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_spar_encoder_fx.c b/lib_enc/ivas_spar_encoder_fx.c index a0c5be842..674a80549 100644 --- a/lib_enc/ivas_spar_encoder_fx.c +++ b/lib_enc/ivas_spar_encoder_fx.c @@ -38,7 +38,6 @@ #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_com.h" -#include "prot.h" #include "math.h" #include "wmc_auto.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 8b23eca5f..925f4e702 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" @@ -42,7 +41,6 @@ #include "ivas_rom_com_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------------------------* * PreProcessor diff --git a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c index 62fed34f7..70c2165f8 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "cnst.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 0c90d5fdc..bfe683d6b 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -38,13 +38,12 @@ #endif #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index 4727cd188..255b6e938 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -36,12 +36,11 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 8578a46ae..3f7237ce5 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -37,10 +37,9 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 70a467232..7900033f4 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index dd7f575b7..58e66a01a 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_prot.h" #include "ivas_rom_com.h" @@ -43,7 +43,6 @@ #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 7b0e7df62..a3388db61 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" @@ -45,7 +44,6 @@ #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_eclvq_enc_fx.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c index cd0e6fe2d..f4962c802 100644 --- a/lib_enc/ivas_stereo_eclvq_enc_fx.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -39,7 +39,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" /* used only for norm_s in the code_length_from_count function */ diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index e0a8a8ed4..351b87cd0 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -36,12 +36,11 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 8c2d136b7..78891c5f7 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -35,12 +35,11 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 2a87ea4f9..28b0e41b9 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "rom_com.h" diff --git a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c index 38be1a6a4..57bb18e80 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "stat_enc.h" diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index 9c729709d..b1213a750 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 190adbf1c..f3ceb2757 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -34,14 +34,13 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 79e05bf09..efae1e80d 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -35,14 +35,13 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 304754fc3..f8d600276 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -44,7 +44,6 @@ #endif #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 84bffa87c..28044b45d 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -35,13 +35,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "basop_proto_func.h" #include "wmc_auto.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #include "rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 4d6a908b3..34215025f 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 1f2fee684..211c53f8c 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -41,7 +41,6 @@ #include "lib_enc.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 709bb47e0..a61b2ebff 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -8,7 +8,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 830f1ecd6..7f58a9501 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -38,7 +38,6 @@ #include "options.h" #include "cnst.h" #include "ivas_prot.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index 265fce7f2..eec85c254 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index d8a78c525..771ef480b 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -6,9 +6,8 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot.h" /* Function prototypes */ -#include "basop32.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ +#include "basop32.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index 3bd8e340d..a7588283a 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" diff --git a/lib_enc/peak_vq_enc_fx.c b/lib_enc/peak_vq_enc_fx.c index 9ea1af949..aa4763aa6 100644 --- a/lib_enc/peak_vq_enc_fx.c +++ b/lib_enc/peak_vq_enc_fx.c @@ -11,7 +11,6 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------------- diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index d53e2eb6e..bcf7d33bb 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "rom_basop_util.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/range_enc_fx.c b/lib_enc/range_enc_fx.c index 05916e801..689b313d8 100644 --- a/lib_enc/range_enc_fx.c +++ b/lib_enc/range_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index a735c498d..353de8ec9 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -19,7 +19,6 @@ #include #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" /*---------------------------------------------------------------------* diff --git a/lib_enc/stat_noise_uv_enc_fx.c b/lib_enc/stat_noise_uv_enc_fx.c index 91dca8d63..0a20db8ed 100644 --- a/lib_enc/stat_noise_uv_enc_fx.c +++ b/lib_enc/stat_noise_uv_enc_fx.c @@ -11,7 +11,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /*======================================================================*/ /* FUNCTION : stat_noise_uv_enc_fx */ diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 3ca3f3f3f..2ca0b6d74 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -4,12 +4,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*---------------------------------------------------------------------* diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index acd984509..1a397c514 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -36,7 +36,6 @@ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" #include "stl.h" -#include "prot.h" /*--------------------------------------------------------------------------* * GetSubbandCorrIndex2_har() diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c deleted file mode 100644 index db4e51127..000000000 --- a/lib_enc/swb_tbe_enc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "ivas_prot.h" diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index a5e4e902b..61ca9b101 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -8,7 +8,6 @@ #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot.h" /* Function prototypes */ diff --git a/lib_enc/tcq_core_enc_fx.c b/lib_enc/tcq_core_enc_fx.c index fbd9775c4..82088be50 100644 --- a/lib_enc/tcq_core_enc_fx.c +++ b/lib_enc/tcq_core_enc_fx.c @@ -10,7 +10,6 @@ #include "ivas_error.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" #define IVAS_FLOAT ivas_error tcq_core_LR_enc_fx( diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index f1881a427..cf6e5dd64 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -12,7 +12,6 @@ #include #include "rom_com_fx.h" #include "rom_com.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 0089fc745..9911d766a 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 4a4c1ff89..008e27d6c 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index 67d47e89d..81437c49d 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -33,7 +33,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" @@ -41,7 +41,6 @@ #include "ivas_rom_binaural_crend_head.h" #include "ivas_stat_rend.h" #include "lib_rend.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 06744dc6e..9cc764afb 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -35,11 +35,10 @@ #include "ivas_cnst.h" #include "ivas_prot_rend.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e2ab6cd3e..7e41581f4 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 01fd1e610..4ea5c5e96 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -35,13 +35,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index c6119cc34..4eae9c286 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -34,14 +34,13 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- * ivas_dirac_dec_onset_detection_open() diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 0624d3910..983343bba 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" @@ -43,7 +43,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index f5e050db1..45ab2e68a 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -35,13 +35,12 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_rend/ivas_efap_fx.c b/lib_rend/ivas_efap_fx.c index 8947809d1..52ca3e6f9 100644 --- a/lib_rend/ivas_efap_fx.c +++ b/lib_rend/ivas_efap_fx.c @@ -35,7 +35,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" diff --git a/lib_rend/ivas_hrtf_fx.c b/lib_rend/ivas_hrtf_fx.c index 506d76efd..5d53d2ae3 100644 --- a/lib_rend/ivas_hrtf_fx.c +++ b/lib_rend/ivas_hrtf_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_error.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_limiter_fx.c b/lib_rend/ivas_limiter_fx.c index 595573016..b66127e09 100644 --- a/lib_rend/ivas_limiter_fx.c +++ b/lib_rend/ivas_limiter_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index e8d06d0bb..8b7e6575d 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -36,9 +36,8 @@ #include "ivas_prot_rend.h" #include "ivas_prot.h" #include "ivas_cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 0b0c8ffeb..25fddaa80 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -37,12 +37,11 @@ #include "options.h" #include "ivas_prot_rend.h" #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 8b689b94b..93fe67436 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -33,14 +33,13 @@ #include "ivas_stat_rend.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" #define float_to_fixed( n, factor ) ( round( n * ( 1 << factor ) ) ) diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index ab09a82b5..a7f46b2a4 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -33,13 +33,12 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* * Local function prototypes diff --git a/lib_rend/ivas_objectRenderer_mix_fx.c b/lib_rend/ivas_objectRenderer_mix_fx.c index a328a51bf..7ee6c828b 100644 --- a/lib_rend/ivas_objectRenderer_mix_fx.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_rom_rend.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_rend/ivas_objectRenderer_sfx_fx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c index caa393355..971e2c2d1 100644 --- a/lib_rend/ivas_objectRenderer_sfx_fx.c +++ b/lib_rend/ivas_objectRenderer_sfx_fx.c @@ -35,9 +35,8 @@ #include #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index af60f7746..307d38351 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -33,11 +33,10 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_vec_fx.c b/lib_rend/ivas_objectRenderer_vec_fx.c index c8efd80ad..4d259a68e 100644 --- a/lib_rend/ivas_objectRenderer_vec_fx.c +++ b/lib_rend/ivas_objectRenderer_vec_fx.c @@ -33,10 +33,9 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 7d6129d20..d7387ecd4 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -37,11 +37,10 @@ #include "ivas_prot_rend.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 980e5ca17..054e5e981 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_rend/ivas_reflections_fx.c b/lib_rend/ivas_reflections_fx.c index e5e8cdb56..a02a29d0d 100644 --- a/lib_rend/ivas_reflections_fx.c +++ b/lib_rend/ivas_reflections_fx.c @@ -33,7 +33,7 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "rom_dec.h" #include "lib_rend.h" #include "ivas_prot_rend.h" @@ -42,7 +42,6 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index 792b485a7..b730b1510 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* * Local constants diff --git a/lib_rend/ivas_reverb_delay_line_fx.c b/lib_rend/ivas_reverb_delay_line_fx.c index 3eeb4ede4..44550803a 100644 --- a/lib_rend/ivas_reverb_delay_line_fx.c +++ b/lib_rend/ivas_reverb_delay_line_fx.c @@ -34,9 +34,8 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "debug.h" /*-----------------------------------------------------------------------------------------* * Function ivas_rev_delay_line_init() diff --git a/lib_rend/ivas_reverb_fft_filter_fx.c b/lib_rend/ivas_reverb_fft_filter_fx.c index 3befcde91..2d0722ceb 100644 --- a/lib_rend/ivas_reverb_fft_filter_fx.c +++ b/lib_rend/ivas_reverb_fft_filter_fx.c @@ -32,11 +32,10 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 428cf3353..652fc898f 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_rend.h" #include diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 9e621ce83..6b41815c4 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "math.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define float_to_fixQ31( n ) ( round( n * 0x7fffffff ) ) diff --git a/lib_rend/ivas_reverb_iir_filter_fx.c b/lib_rend/ivas_reverb_iir_filter_fx.c index 217e16dd8..98b66e0c7 100644 --- a/lib_rend/ivas_reverb_iir_filter_fx.c +++ b/lib_rend/ivas_reverb_iir_filter_fx.c @@ -32,10 +32,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 46ef576a8..ee2bada9d 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "options_warnings.h" /*-----------------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index 39720469b..7ad4c4ccb 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -37,11 +37,10 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" #include -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "debug.h" #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_rend/ivas_sba_rendering_fx.c b/lib_rend/ivas_sba_rendering_fx.c index 7c7a20223..4323fc96f 100644 --- a/lib_rend/ivas_sba_rendering_fx.c +++ b/lib_rend/ivas_sba_rendering_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" diff --git a/lib_rend/ivas_shoebox_fx.c b/lib_rend/ivas_shoebox_fx.c index 9ed0d8d33..7c930104a 100644 --- a/lib_rend/ivas_shoebox_fx.c +++ b/lib_rend/ivas_shoebox_fx.c @@ -36,7 +36,6 @@ #include "ivas_prot_rend.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index af51a7820..6d5b23f12 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_prot.h" diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index e1a6868d8..06cbd83a6 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -34,12 +34,11 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index d9bb5cd41..ef5d5602c 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -32,7 +32,6 @@ #include "basop_util.h" #include "options.h" #include "lib_rend.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 8920e6780..930bb79dc 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -32,9 +32,8 @@ #include "hrtf_file_reader.h" #include -#include "prot.h" -#include "ivas_prot_rend.h" #include "prot_fx.h" +#include "ivas_prot_rend.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 01d1f0307..90d47b7c9 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -34,7 +34,7 @@ #include #include #include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" struct LsCustomFileReader diff --git a/lib_util/mime_io.c b/lib_util/mime_io.c index 782f818d0..2976e1895 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -32,7 +32,7 @@ #include "mime_io.h" #include "mime.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include #include diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index b6122ec0f..e099842be 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -37,7 +37,7 @@ #include #include #include "cmdl_tools.h" -#include "prot.h" +#include "prot_fx.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 468f80765..2299f3265 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -34,7 +34,6 @@ #include #include #include -#include "prot.h" #include "prot_fx.h" diff --git a/lib_util/vector3_pair_file_reader.c b/lib_util/vector3_pair_file_reader.c index ec14ebc71..5745e9595 100644 --- a/lib_util/vector3_pair_file_reader.c +++ b/lib_util/vector3_pair_file_reader.c @@ -35,7 +35,6 @@ #include #include #include -#include "prot.h" #include "options.h" /* only included to get access to the feature-defines */ #include "prot_fx.h" #include "ivas_prot_fx.h" -- GitLab From b93d15320328b41c43e6212734fd40a672c8f264 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 10:13:00 +0530 Subject: [PATCH 0379/1221] Fix for 3GPP issue 1140: Missing conversion of some flt. pt. functions in the BASOP code Link #1140 --- lib_com/float_to_fix_ops.c | 8 ++--- lib_com/ivas_spar_com_fx.c | 39 ++++++++++++++++--------- lib_dec/dec_tcx_fx.c | 19 ++++++------ lib_dec/ivas_lfe_plc_fx.c | 12 ++++---- lib_dec/ivas_mc_paramupmix_dec_fx.c | 6 ++-- lib_dec/ivas_qmetadata_dec_fx.c | 3 +- lib_dec/ivas_spar_md_dec_fx.c | 7 +++-- lib_dec/ivas_stereo_cng_dec.c | 6 ++-- lib_dec/ivas_stereo_dft_dec_fx.c | 38 +++++++++++++++--------- lib_enc/ACcontextMapping_enc_fx.c | 7 +++-- lib_enc/fd_cng_enc_fx.c | 2 +- lib_enc/ivas_agc_enc_fx.c | 2 +- lib_enc/ivas_core_pre_proc_fx.c | 2 +- lib_enc/ivas_cpe_enc_fx.c | 2 +- lib_enc/ivas_init_enc_fx.c | 2 +- lib_enc/ivas_lfe_enc_fx.c | 20 ++++++------- lib_enc/ivas_mc_paramupmix_enc_fx.c | 10 +++---- lib_enc/ivas_osba_enc_fx.c | 2 +- lib_enc/ivas_qmetadata_enc_fx.c | 3 +- lib_enc/ivas_sba_enc_fx.c | 2 +- lib_enc/ivas_stereo_dft_enc_itd_fx.c | 9 ++++-- lib_enc/ivas_stereo_dmx_evs_fx.c | 6 ++-- lib_enc/ivas_stereo_ica_enc_fx.c | 4 +-- lib_enc/ivas_stereo_switching_enc_fx.c | 2 +- lib_rend/ivas_dirac_decorr_dec_fx.c | 4 +-- lib_rend/ivas_dirac_rend_fx.c | 2 +- lib_rend/ivas_reverb_filter_design_fx.c | 6 ++-- lib_rend/ivas_rotation_fx.c | 2 +- lib_rend/lib_rend.c | 12 ++++---- 29 files changed, 137 insertions(+), 102 deletions(-) diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 1f7c28fd8..8b69e05e8 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -183,14 +183,14 @@ Word16 Q_factor( float x ) { Word16 Q = 15; if ( x >= 1 || x <= -1 ) - Q = norm_s( (Word16) abs( (Word32) x ) ); + Q = norm_s( (Word16) L_abs( (Word32) x ) ); return Q; } Word16 Q_factor_L( float x ) { Word16 Q = 31; if ( x >= 1 || x <= -1 ) - Q = norm_l( abs( (Word32) x ) ); + Q = norm_l( L_abs( (Word32) x ) ); return Q; } Word16 Q_factor_L_32( Word32 x ) @@ -206,7 +206,7 @@ Word16 Q_factor_arr( float *x, Word16 l ) for ( int i = 0; i < l; i++ ) { if ( x[i] >= 1 || x[i] <= -1 ) - Q = s_min( Q, norm_s( (Word16) abs( (Word32) x[i] ) ) ); + Q = s_min( Q, norm_s( (Word16) L_abs( (Word32) x[i] ) ) ); } return Q; } @@ -216,7 +216,7 @@ Word16 Q_factor_arrL( float *x, Word16 l ) for ( int i = 0; i < l; i++ ) { if ( x[i] >= 1 || x[i] <= -1 ) - Q = s_min( Q, norm_l( (Word32) abs( (Word32) x[i] ) ) ); + Q = s_min( Q, norm_l( (Word32) L_abs( (Word32) x[i] ) ) ); } return Q; } diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index fc6e60310..6c80c1898 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -4004,7 +4004,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); P_norm_fx[0] = 0; move32(); - FOR( i = 0; i < max( 0, sub( foa_ch, ndm ) ); i++ ) + Word16 len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) { P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4014,7 +4015,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( P_norm_fx[1] = 0; move32(); - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4031,8 +4033,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( } P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31 move32(); - - FOR( i = 0; i < max( 0, ( foa_ch - ndm ) ); i++ ) + len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4045,7 +4047,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4057,6 +4060,7 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } + FOR( ; i < ( num_ch - ndm ); i++ ) { idx = sub( remix_order[i + ndm], ndm ); @@ -4222,7 +4226,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( /*normalize 2nd order*/ norm_fx = 0; move32(); - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + Word16 min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } @@ -4243,7 +4248,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) { @@ -4557,7 +4563,8 @@ void ivas_get_spar_md_from_dirac_fx( move16(); P_norm_fx[0] = 0; move32(); - FOR( i = 0; i < max( 0, sub( foa_ch, ndm ) ); i++ ) + Word16 len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, sub( foa_ch, ndm ) ) { P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4567,7 +4574,8 @@ void ivas_get_spar_md_from_dirac_fx( P_norm_fx[1] = 0; move32(); - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4584,8 +4592,8 @@ void ivas_get_spar_md_from_dirac_fx( } P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31 move32(); - - FOR( i = 0; i < max( 0, ( foa_ch - ndm ) ); i++ ) + len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4598,7 +4606,8 @@ void ivas_get_spar_md_from_dirac_fx( move32(); } } - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4775,7 +4784,8 @@ void ivas_get_spar_md_from_dirac_fx( /*normalize 2nd order*/ norm_fx = 0; move32(); - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + Word16 min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } @@ -4796,7 +4806,8 @@ void ivas_get_spar_md_from_dirac_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) { diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 20f7a0adf..00f372154 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3807,7 +3807,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, (Word16) abs( tmp32 ) * i * 2, &Overflow ); + *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } @@ -3875,7 +3875,8 @@ void decoder_tcx_invQ_fx( test(); IF( !st->tcxonly || ( hTcxCfg->resq && hTcxDec->tcx_lpc_shaped_ari ) ) { - FOR( i = 0; i < max( L_spec, L_frameTCX ); i++ ) + Word16 len = s_max( L_spec, L_frameTCX ); + FOR( i = 0; i < len; i++ ) { xn_buf[i] = ONE_IN_Q14; move16(); @@ -4891,11 +4892,11 @@ void decoder_tcx_tns_fx( move16(); test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 ) { test(); test(); - IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + IF( frame_cnt != 0 && bfi == 0 && st->last_core != ACELP_CORE ) { /* fix sub-window overlap */ hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; @@ -4940,14 +4941,14 @@ void decoder_tcx_tns_fx( test(); test(); test(); - IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) + IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && fUseTns != 0 && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) { /* Apply TNS to get the reconstructed signal */ SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); test(); test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 ) { tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); } @@ -4956,10 +4957,10 @@ void decoder_tcx_tns_fx( test(); test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 ) { test(); - IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ + IF( st->element_mode == EVS_MONO || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ { tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); tmp = L_frameTCX; @@ -5232,7 +5233,7 @@ void decoder_tcx_imdct_fx( { IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); } ELSE { diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index a8b54d3fb..018f99fe7 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -396,7 +396,7 @@ static Word16 lfeplc_lev_dur_fx( IF( LT_16( rc_q_fx[i - 1], 31 ) ) { - IF( GT_32( abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31 + IF( GT_32( L_abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31 { return 1; } @@ -413,7 +413,7 @@ static Word16 lfeplc_lev_dur_fx( } ELSE { - IF( GT_32( abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31 + IF( GT_32( L_abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31 { return 1; } @@ -465,7 +465,7 @@ static Word16 d_a2rc_fx( move32(); km_q_fx = ff_q_fx[m]; move16(); - IF( GE_64( W_shr( abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) ) + IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) ) { FOR( j = 0; j < lpcorder; j++ ) { @@ -826,7 +826,7 @@ static Word32 find_max_delta_fx( IF( !stable ) { - temp = abs( eps_fx ); + temp = L_abs( eps_fx ); IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) ) { exp1 = norm_l( -temp ); @@ -836,12 +836,12 @@ static Word32 find_max_delta_fx( } ELSE { - eps_fx = L_negate( abs( eps_fx ) ); + eps_fx = L_negate( L_abs( eps_fx ) ); } } ELSE { - temp = abs( eps_fx ); + temp = L_abs( eps_fx ); if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) ) { BREAK; diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index e03b385b7..9ea666237 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -132,7 +132,8 @@ void ivas_mc_paramupmix_dec_read_BS( nb_bits_read_orig = 0; move16(); last_bit_pos = sub( last_bit_pos, nb_bits_read_orig ); /* reverse the bitstream for easier reading of indices */ - FOR( i = 0; i < min( MAX_BITS_METADATA, last_bit_pos ); i++ ) + Word16 len = s_min( MAX_BITS_METADATA, last_bit_pos ); + FOR( i = 0; i < len; i++ ) { bstr_meta[i] = st_ivas->bit_stream[last_bit_pos - i]; move16(); @@ -269,7 +270,8 @@ void ivas_mc_paramupmix_dec_render( ivas_mc_paramupmix_dec_sf( st_ivas, output_local_fx ); - FOR( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) + Word16 num_ch = s_min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); + FOR( ch = 0; ch < num_ch; ch++ ) { output_local_fx[ch] += n_samples_sf; } diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index 4bebcda5c..81768af44 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -3257,7 +3257,8 @@ static Word16 read_truncGR_azimuth_fx( move16(); IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) { - FOR( i = 0; i < min( allowed_bits, no_subframes ); i++ ) + Word16 len = s_min( allowed_bits, no_subframes ); + FOR( i = 0; i < len; i++ ) { IF( bitstream[( *pbit_pos )--] == 0 ) { diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index 2b6b145f9..d1efbbd2c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -936,9 +936,10 @@ Word16 ivas_spar_chk_zero_coefs_fx( ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; /*Q0*/ move16(); - FOR( b = 0; b < min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) + Word16 min_bands = s_min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + FOR( b = 0; b < min_bands; b++ ) { - FOR( j = 0; j < sub( add( ndm, ndec ), 1 ); j++ ) + FOR( j = 0; j < ( ( ndm + ndec ) - 1 ); j++ ) { if ( hMdDec->spar_md.band_coeffs[b].pred_re_fx[j] != 0 ) { @@ -948,7 +949,7 @@ Word16 ivas_spar_chk_zero_coefs_fx( } FOR( j = 0; j < ndec; j++ ) { - FOR( k = 0; k < sub( ndm, 1 ); k++ ) + FOR( k = 0; k < ( ndm - 1 ); k++ ) { if ( hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k] != 0 ) { diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 15885a661..4d50ba350 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -585,7 +585,8 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */ ptr_i = ptr_r + 1; - FOR( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) + Word16 len = shr( ( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ) ), 1 ); + FOR( i = 0; i < len; i++ ) { /* Real part in FFT bins */ rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft ); @@ -622,7 +623,8 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */ ptr_i = ptr_r + 1; - FOR( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) + tmp = shr( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ), 1 ); + FOR( i = 0; i < tmp; i++ ) { ( *ptr_r ) = L_shl( Mpy_32_32( ( *ptr_r ), tmp32_1 ), q_shift ); /* q_dft + q_shift */ move32(); diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index c806f358a..8dcc7ada9 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1522,6 +1522,7 @@ void stereo_dft_dec_fx( Word16 q_samp_ratio = Q15; move16(); #endif /* OPT_STEREO_32KBPS_V1 */ + Word16 len; output_frame = (Word16) Mpy_32_32( L_add( st0->output_Fs, FRAMES_PER_SEC_BY_2 ), ONE_BY_FRAMES_PER_SEC_Q31 ); /* Q0 */ @@ -1890,7 +1891,8 @@ void stereo_dft_dec_fx( DFT_R[2 * i + 1] = L_sub( DFT_W, DFT_Y ); /* qDFT */ move32(); } - FOR( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( stop, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { DFT_W = Madd_32_32( Mpy_32_32( hStereoDft->mixer_mat_smooth_fx[0][0][b + k * IVAS_MAX_NUM_BANDS], pDFT_DMX[2 * i] ), L_add( hStereoDft->mixer_mat_smooth_fx[0][1][b + k * IVAS_MAX_NUM_BANDS], @@ -1997,7 +1999,8 @@ void stereo_dft_dec_fx( } ELSE { - FOR( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( stop, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { tmp = L_add( Madd_32_16( pDFT_RES[2 * i], pDFT_DMX[2 * i], g ), DFT_PRED_RES[2 * i] ); /* qDFT */ @@ -2218,8 +2221,8 @@ void stereo_dft_dec_fx( gamma = 0; move16(); } - - FOR( i = max( hFdCngDec->cna_band_limits[b], ( hFdCngCom->startBand / 2 ) ); i < min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); i++ ) + len = s_min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); + FOR( i = s_max( hFdCngDec->cna_band_limits[b], ( hFdCngCom->startBand >> 1 ) ); i < len; i++ ) // i < min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); { Word32 l_tmp; lev1 = *ptr_per++; @@ -2597,6 +2600,7 @@ void stereo_dft_generate_res_pred_fx( q_norm_fac = 0; move16(); #endif /* OPT_STEREO_32KBPS_V1 */ + Word16 len; push_wmops( "gen_respred" ); /* smoothing and limiting parameters */ @@ -2665,7 +2669,8 @@ void stereo_dft_generate_res_pred_fx( move64(); /* calculate band energies (low band only in case of ACELP) */ - FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], bin0 ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { #ifdef OPT_STEREO_32KBPS_V1 dmx_nrg_64bit = W_mac_32_32( W_mac_32_32( dmx_nrg_64bit, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), @@ -2847,7 +2852,8 @@ void stereo_dft_generate_res_pred_fx( } #endif /* OPT_STEREO_32KBPS_V1 */ - FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], bin0 ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { #ifdef OPT_STEREO_32KBPS_V1 DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i] ), 1 ); /* q_dft */ @@ -2969,7 +2975,8 @@ void stereo_dft_generate_res_pred_fx( move32(); dmx_nrg = EPSILON_FIX; move32(); - FOR( i = hStereoDft->band_limits[b]; i < min( bin0, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( bin0, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { dmx_nrg = Madd_32_32( Madd_32_32( dmx_nrg, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ); /* 2 * q_dft - 31 */ @@ -3010,8 +3017,8 @@ void stereo_dft_generate_res_pred_fx( q_sqrt = 0; move16(); } - - FOR( i = hStereoDft->band_limits[b]; i < min( bin0, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( bin0, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( g2, DFT_PRED_RES[2 * i] ), q_sqrt ); /* q_dft */ move32(); @@ -3068,7 +3075,8 @@ void stereo_dft_generate_res_pred_fx( // past_dmx_nrg = EPSILON_FIX; past_dmx_nrg = 0; move32(); - FOR( i = bin0; i < min( ( hStereoDft->NFFT / 2 ), ( STEREO_DFT32MS_N_32k / 2 ) ); i++ ) + len = s_min( shr( hStereoDft->NFFT, 1 ), ( STEREO_DFT32MS_N_32k >> 1 ) ); + FOR( i = bin0; i < len; i++ ) // i < min( ( hStereoDft->NFFT / 2 ), ( hStereoDft->NFFT / 2 ) ) { past_dmx_nrg = L_add( past_dmx_nrg, Madd_32_32( Mpy_32_32( hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i], hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i] ), hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i + 1], hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i + 1] ) ); /* 2 * hStereoDft->q_DFT_past_DMX_fx[d_short_ind] - 31 */ } @@ -3129,7 +3137,8 @@ void stereo_dft_generate_res_pred_fx( } q_shift = sub( hStereoDft->q_dft, hStereoDft->q_DFT_past_DMX_fx[d_short_ind] ); move16(); - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( g2, hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i] ), q_shift ); /* q_dft */ move32(); @@ -3243,7 +3252,8 @@ void stereo_dft_generate_res_pred_fx( move32(); dmx_nrg = EPSILON_FIX; move32(); - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { dmx_nrg = L_add( dmx_nrg, L_shr( Madd_32_32( Mpy_32_32( pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ), 1 ) ); /* 2 * q_dft - 31 - 1 */ @@ -3269,8 +3279,8 @@ void stereo_dft_generate_res_pred_fx( g2 = L_min( Mpy_32_16_1( pred_gain_avg, STEREO_DFT_STEFFI_GAIN_AMP_FX ), Madd_32_16( Mpy_32_16_1( pred_gain_avg, sub( (Word16) ( 0x7FFF ), STEREO_DFT_STEFFI_GAIN_REST_AMT_FX ) ), g2, STEREO_DFT_STEFFI_GAIN_REST_AMT_FX ) ); /* Q31 */ - - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { DFT_PRED_RES[2 * i] = Mpy_32_32( g2, DFT_PRED_RES[2 * i] ); /* Q31 */ move32(); diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 1e8bef488..44439540f 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1341,8 +1341,8 @@ Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( } /* Init current 2-tuple encoding */ - a1 = (Word16) abs( x[a1_i] ); - b1 = (Word16) abs( x[b1_i] ); + a1 = abs_s( x[a1_i] ); + b1 = abs_s( x[b1_i] ); lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); @@ -1731,7 +1731,8 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( /* Main Loop through the 2-tuples */ /*hContextMem->nt_half = end_line >> 1;*/ - FOR( k = start_line; k < min( hContextMem->lastnz, end_line ); k += 2 ) + Word16 len = s_min( hContextMem->lastnz, end_line ); + FOR( k = start_line; k < len; k += 2 ) { a1_i = k; /* Q0 */ move16(); diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 307d42078..2db8b956b 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -3039,7 +3039,7 @@ void FdCngEncodeMDCTStereoSID_fx( /* quantize channel coherence */ coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 ); - coh_idx = max( 0, min( coh_idx, 15 ) ); + coh_idx = s_max( 0, s_min( coh_idx, 15 ) ); /* ---- Write SID bitstream ---- */ diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 37d25c508..104eeb998 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -623,7 +623,7 @@ void ivas_agc_enc_process_fx( temp_16 = BASOP_Util_Divide3232_Scale( temp1, temp2, &div_e ); /* exp(div_e) */ IF( div_e < 0 ) { - temp_16 = shr( temp_16, (Word16) abs( div_e ) ); + temp_16 = shr( temp_16, abs_s( div_e ) ); div_e = 0; move16(); } diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index a9da7f342..73403a848 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -184,7 +184,7 @@ ivas_error pre_proc_ivas_fx( } IF( st->hFdCngEnc != NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) && ( ( NE_16( st->hFdCngEnc->hFdCngCom->frameSize, st->L_frame ) ) || ( NE_16( st->hFdCngEnc->hFdCngCom->CngBandwidth, st->input_bwidth ) ) ) ) { - configureFdCngEnc_ivas_fx( st->hFdCngEnc, max( st->input_bwidth, WB ), flag_1 ); + configureFdCngEnc_ivas_fx( st->hFdCngEnc, s_max( st->input_bwidth, WB ), flag_1 ); } if ( st->ini_frame == 0 ) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 811e53d12..a9d62a2b0 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -856,7 +856,7 @@ ivas_error ivas_cpe_enc_fx( } ELSE { - internal_Fs = max( INT_FS_16k, sts[0]->sr_core ); + internal_Fs = L_max( INT_FS_16k, sts[0]->sr_core ); } /* iDFT at input sampling rate */ diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 3eeb45d14..c65c85356 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -493,7 +493,7 @@ ivas_error ivas_init_encoder( if ( NE_32( ivas_format, MONO_FORMAT ) ) { /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ + hEncoderConfig->max_bwidth = s_max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ move16(); } st_ivas->ism_mode = ISM_MODE_NONE; diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 86237fb31..11056b535 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -170,17 +170,17 @@ static void ivas_lfe_enc_quant_fx( { temp_lfe_dct[4 * i] = pLfe_dct[2 * i]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i] ) ); temp_lfe_dct[4 * i + 1] = pLfe_dct[2 * i + 1]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 1] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 1] ) ); temp_lfe_dct[4 * i + 2] = pLfe_dct[2 * i + num_dct_pass_bins]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 2] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 2] ) ); temp_lfe_dct[4 * i + 3] = pLfe_dct[2 * i + num_dct_pass_bins + 1]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 3] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 3] ) ); } IF( LE_64( lfe_abs_sum, W_shr( IVAS_LFE_ABS_SUM_FLT_THR_Q42, sub( 42, q_pLfe_dct ) ) ) ) @@ -250,9 +250,9 @@ static void ivas_lfe_enc_quant_fx( move16(); } - IF( LT_32( max_of_vals, abs( values[i] ) ) ) + IF( LT_32( max_of_vals, abs_s( values[i] ) ) ) { - max_of_vals = (Word16) abs( values[i] ); + max_of_vals = abs_s( values[i] ); move16(); } } @@ -475,8 +475,8 @@ void ivas_lfe_enc_fx( IF( GT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, min( q_tmp2, sub( q_out1, q_out2 ) ) ); - q_out2 = add( q_out2, min( q_tmp2, sub( q_out1, q_out2 ) ) ); + Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, s_min( q_tmp2, sub( q_out1, q_out2 ) ) ); + q_out2 = add( q_out2, s_min( q_tmp2, sub( q_out1, q_out2 ) ) ); IF( GT_16( q_out1, q_out2 ) ) { Scale_sig32( lfe_dct_fx, num_dct_pass_bins, sub( q_out2, q_out1 ) ); // q_out2 @@ -486,8 +486,8 @@ void ivas_lfe_enc_fx( } ELSE IF( LT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx, num_dct_pass_bins, min( q_tmp1, sub( q_out2, q_out1 ) ) ); - q_out1 = add( q_out1, min( q_tmp1, sub( q_out2, q_out1 ) ) ); + Scale_sig32( lfe_dct_fx, num_dct_pass_bins, s_min( q_tmp1, sub( q_out2, q_out1 ) ) ); + q_out1 = add( q_out1, s_min( q_tmp1, sub( q_out2, q_out1 ) ) ); IF( LT_16( q_out1, q_out2 ) ) { Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, sub( q_out1, q_out2 ) ); // q_out1 diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index 9060c786b..abd09cbbd 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -201,7 +201,7 @@ ivas_error ivas_mc_paramupmix_enc_open_fx( /* still 1.5ms off, since MCT delay is not large enough */ /* param at end of frame */ fb_cfg->prior_input_length = (Word16) ( NS2SA_FX2( input_Fs, 12000000L ) + NS2SA_FX2( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA_FX2( input_Fs, DELAY_FB_1_NS / 2 ) ); - fb_cfg->prior_input_length = (Word16) max( fb_cfg->prior_input_length, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + fb_cfg->prior_input_length = s_max( fb_cfg->prior_input_length, (Word16) input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Allocate and initialize FB mixer handle */ IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMCParamUpmix->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) @@ -496,12 +496,12 @@ static void quantize_pars_fx( Word16 exp_var1 = 0; move16(); Word32 var1 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq0] ), 31 - Q28, &exp_var1 ); - var1 = abs( var1 ); + var1 = L_abs( var1 ); Word16 exp_var2 = 0; move16(); Word32 var2 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq1] ), 31 - Q28, &exp_var2 ); - var2 = abs( var2 ); + var2 = L_abs( var2 ); Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); @@ -591,12 +591,12 @@ static void quantize_beta_fx( Word16 exp_var1 = 0; move16(); Word32 var1 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq0] ), 31 - Q28, &exp_var1 ); - var1 = abs( var1 ); + var1 = L_abs( var1 ); Word16 exp_var2 = 0; move16(); Word32 var2 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq1] ), 31 - Q28, &exp_var2 ); - var2 = abs( var2 ); + var2 = L_abs( var2 ); Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 648dcdb73..1229624de 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -300,7 +300,7 @@ ivas_error ivas_osba_enc_reconfig( } } - ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); + ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); hSpar = st_ivas->hSpar; diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 7a2a28767..3416ab279 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -4089,7 +4089,8 @@ static ivas_error requantize_direction_EC_3_fx( IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) { - FOR( k = 0; k < min( no_subframes, allowed_bits ); k++ ) + Word16 len = s_min( no_subframes, allowed_bits ); + FOR( k = 0; k < len; k++ ) { push_next_indice( hMetaData, q_direction->band_data[j].azimuth_index[k], 1 ); } diff --git a/lib_enc/ivas_sba_enc_fx.c b/lib_enc/ivas_sba_enc_fx.c index 86427eb2d..8fdca5815 100644 --- a/lib_enc/ivas_sba_enc_fx.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -199,7 +199,7 @@ ivas_error ivas_sba_enc_reconfigure_fx( } } - ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); + ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); hSpar = st_ivas->hSpar; diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 7900033f4..862102d3b 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -547,7 +547,8 @@ static Word32 calc_mean_E_ratio_fx( sum_nrg_R_e = 0; move16(); - FOR( i = band_limits[b]; i < min( band_limits[b + 1], STEREO_DFT_N_32k_ENC / 2 ); i++ ) + Word16 len = s_min( band_limits[b + 1], STEREO_DFT_N_32k_ENC >> 1 ); + FOR( i = band_limits[b]; i < len; i++ ) { // sum_xcorr[0] += hItd->xcorr_smooth[2 * i]; sum_xcorr[0] = BASOP_Util_Add_Mant32Exp( sum_xcorr[0], sum_xcorr_e[0], hItd->xcorr_smooth_fx[2 * i], hItd->xcorr_smooth_fx_e[2 * i], &sum_xcorr_e[0] ); @@ -2568,7 +2569,11 @@ void stereo_dft_enc_compute_itd_fx( prev_itd_max = hItd->hybrid_itd_max; move16(); /* enable hybrid ITD handling for very large ITDs*/ - hItd->hybrid_itd_max = ( abs( itd ) > STEREO_DFT_ITD_MAX && abs( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); + // hItd->hybrid_itd_max = ( abs_s( itd ) > STEREO_DFT_ITD_MAX && abs_s( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); + test(); + test(); + test(); + hItd->hybrid_itd_max = ( GT_16( abs_s( itd ), STEREO_DFT_ITD_MAX ) && LT_16( abs_s( itd ), STEREO_DFT_ITD_MAX_ANA ) && !hCPE->hCoreCoder[0]->sp_aud_decision0 && LT_32( hCPE->element_brate, IVAS_32k ) ); move16(); /* Update memory */ hItd->prev_itd = itd; diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index a3388db61..c3cb68719 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -1203,7 +1203,7 @@ static Word32 find_poc_peak_fx( /*compute peak_range*/ tmp1 = idiv1616( hPOC->shift_limit, STEREO_DMX_EVS_FIND_POC_PEAK_TAU ); - peak_range = idiv1616( add( extract_l( abs( itd_cand[n] ) ), tmp1 ), STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 ); // Q0 + peak_range = idiv1616( add( extract_l( abs_s( itd_cand[n] ) ), tmp1 ), STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 ); // Q0 FOR( i = 1; i <= peak_range; i++ ) { @@ -1250,7 +1250,7 @@ static Word32 find_poc_peak_fx( IF( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/ { tmp13_e = 0, tmp15_e = 0; - tmp13 = BASOP_Util_Divide1616_Scale( (Word16) abs( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); + tmp13 = BASOP_Util_Divide1616_Scale( abs_s( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); tmp14 = L_mult( 6554 /*0.2f Q15*/, tmp13 ); // tmp13_e tmp15 = BASOP_Util_Add_Mant32Exp( 644245120 /*0.75f in Q31*/, 0, L_negate( tmp14 ), tmp13_e, &tmp15_e ); tmp15 = Mpy_32_32( tmp15, peakQ_fx[n] ); // tmp15_e + peakQ_e[n] @@ -1299,7 +1299,7 @@ static Word32 find_poc_peak_fx( tmp13_e = 0, tmp15_e = 0; move16(); move16(); - tmp13 = BASOP_Util_Divide1616_Scale( (Word16) abs( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); + tmp13 = BASOP_Util_Divide1616_Scale( abs_s( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); tmp14 = L_mult( 6554 /*0.2f Q15*/, tmp13 ); // tmp13_e tmp15 = BASOP_Util_Add_Mant32Exp( 1610612736 /*0.75f in Q31*/, 0, L_negate( tmp14 ), tmp13_e, &tmp15_e ); diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 351b87cd0..78c324cce 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1737,7 +1737,7 @@ void stereo_tca_enc_fx( prev_ICA_flag = 0; move16(); test(); - if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 ) + if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs_s( hStereoTCA->prevCorrLagStats[2] ) != 0 ) { prev_ICA_flag = 1; move16(); @@ -1924,7 +1924,7 @@ void stereo_tca_enc_fx( /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */ tempS = shr( currentNCShift, 1 ); /* Q0 */ - IF( LE_32( abs( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) ) + IF( LE_32( abs_s( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) ) { adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 ); } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index f3ceb2757..6513a3fa7 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -241,7 +241,7 @@ ivas_error stereo_memory_enc_fx( IF( hCPE->hStereoTCA != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { #ifdef FIX_1132_STACK_CORRUPTION - Word16 tmp = extract_h( abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); + Word16 tmp = extract_h( L_abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); if ( hCPE->hStereoDft->hItd->itd_fx[1] < 0 ) { tmp = negate( tmp ); diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 4ea5c5e96..32803f6c3 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -949,8 +949,8 @@ void ivas_dirac_dec_decorr_process_fx( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = add( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth, q_shift ); move16(); } - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); + h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); + h_freq_domain_decorr_ap_state->q_direct_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); #endif e_reverb_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 45ab2e68a..e01b27767 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4331,7 +4331,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, hDirACRend->num_protos_diff, hDirACRend->proto_index_diff, - hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * min( 4, nchan_transport ), + hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * s_min( 4, nchan_transport ), &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, onset_filter_fx, hDirACRend->h_freq_domain_decorr_ap_params, diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 652fc898f..45e492fc8 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -740,7 +740,7 @@ void ivas_reverb_calc_color_levels_fx( Word16 temp = 0, result_e = 0; move16(); move16(); - cos_w = getCosWord16R2( (Word16) abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 + cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28 H_filter = BASOP_Util_Divide3232_Scale_cadence( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); H_filter = Sqrt32( H_filter, &temp ); @@ -1155,9 +1155,9 @@ void ivas_reverb_get_hrtf_set_properties_fx( IA_coherence[freq_idx] = L_shl( IA_coherence[freq_idx], sub( 27, sub( 15, temp ) ) ); // q = 27 move32(); /* Limiting to (0...1) range in case of small numerical errors or negative values */ - IA_coherence[freq_idx] = min( IA_coherence[freq_idx], ONE_IN_Q27 ); // Q27 + IA_coherence[freq_idx] = L_min( IA_coherence[freq_idx], ONE_IN_Q27 ); // Q27 move32(); - IA_coherence[freq_idx] = max( IA_coherence[freq_idx], 0 ); // Q27 + IA_coherence[freq_idx] = L_max( IA_coherence[freq_idx], 0 ); // Q27 move32(); } diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index 7ad4c4ccb..8b352218b 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -399,7 +399,7 @@ void rotateAziEle_fx( angle = extract_l( L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), 24 ) ); // Q0 } - *azi = s_max( -180, min( 180, angle ) ); + *azi = s_max( -180, s_min( 180, angle ) ); move16(); IF( isPlanar == 0 ) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ef5d5602c..ac856e90c 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1177,8 +1177,8 @@ static Word8 checkObjectPositionChanged_fx( IVAS_ISM_METADATA *previousPos ) { test(); - return !( LT_32( abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && - LT_32( abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); + return !( LT_32( L_abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && + LT_32( L_abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); } static rendering_context getRendCtx( @@ -2018,7 +2018,7 @@ static ivas_error updateMcPanGainsForAmbiOut( Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); - IF( GE_32( abs( temp ), ONE_IN_Q29 ) ) + IF( GE_32( L_abs( temp ), ONE_IN_Q29 ) ) { IF( temp > 0 ) { @@ -2066,7 +2066,7 @@ static ivas_error updateMcPanGainsForAmbiOut( { Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); - IF( GE_32( abs( temp ), ONE_IN_Q29 ) ) + IF( GE_32( L_abs( temp ), ONE_IN_Q29 ) ) { IF( temp > 0 ) { @@ -4537,7 +4537,7 @@ static void renderBufferChannelLerp_fx( /* Process current output channel only if applying non-zero gains */ test(); test(); - IF( GT_32( abs( currentGain ), EPSILON_FX ) || ( gainsPrev != NULL && GT_32( abs( previousGain ), EPSILON_FX ) ) ) + IF( GT_32( L_abs( currentGain ), EPSILON_FX ) || ( gainsPrev != NULL && GT_32( L_abs( previousGain ), EPSILON_FX ) ) ) { /* Reset input pointer to the beginning of input channel */ inSmpl = getSmplPtr_fx( inAudio, inChannelIdx, 0 ); @@ -4546,7 +4546,7 @@ static void renderBufferChannelLerp_fx( outSmpl = getSmplPtr_fx( outAudio, outChnlIdx, 0 ); test(); - IF( gainsPrev == NULL || LE_32( abs( L_sub( L_shr( previousGain, 1 ), L_shr( currentGain, 1 ) ) ), EPSILON_FX ) ) + IF( gainsPrev == NULL || LE_32( L_abs( L_sub( L_shr( previousGain, 1 ), L_shr( currentGain, 1 ) ) ), EPSILON_FX ) ) { /* If no interpolation from previous frame, apply current gain */ DO -- GitLab From b256bc0a153fda00da0b897433978c75e8b05616 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 10:45:15 +0530 Subject: [PATCH 0380/1221] Fix for 3GPP issue 1347: Saturation of energies memory for dtx path Link #1347 --- lib_enc/ivas_core_pre_proc_front_fx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index f41eb7f9c..46de4e232 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1016,14 +1016,14 @@ ivas_error pre_proc_front_ivas_fx( Word16 msNoiseEst_Q = Q31; move16(); move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); IF( zero_flag ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_fx, NPART ); + msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + move16(); } - Scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ - st->hFdCngEnc->msNoiseEst_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); - move16(); perform_noise_estimation_enc_ivas_fx( band_energies_LR_fx, sub( Q31, band_energies_LR_fx_q ), enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); } ELSE @@ -1049,14 +1049,14 @@ ivas_error pre_proc_front_ivas_fx( move16(); Word16 msNoiseEst_Q = Q31; move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_fx, NPART ); /* Q0 */ + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); /* Q0 */ IF( zero_flag ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_fx, NPART ); + msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + move16(); } - Scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ - st->hFdCngEnc->msNoiseEst_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); - move16(); zero_flag = get_zero_flag( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); /* Q0 */ Word16 normmsperiodog = 31; move16(); -- GitLab From 7f96d717a09ef05b48d3a5634b87f05a77a275a9 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 11:49:53 +0530 Subject: [PATCH 0381/1221] ASAN issue fix for decoder --- lib_dec/evs_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index aa997d4c0..f20ff77f3 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -36,7 +36,7 @@ ivas_error evs_dec_fx( Word16 exp, fra; Word16 tmp_buffer_fx[L_FRAME48k]; Word16 tmp16, tmp16_2; - Word16 synth_fx[L_FRAME48k]; + Word16 synth_fx[L_FRAME48k + HQ_DELTA_MAX * HQ_DELAY_COMP]; Word16 fb_exc_fx[L_FRAME16k]; Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; Word16 Q_fb_exc; -- GitLab From 3dbd470196b657f34d7819c75903e28c051dfd83 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 14:58:16 +0530 Subject: [PATCH 0382/1221] Fix for LTV crash issue Fix for LTV crash : 4 ISM with metadata at 48 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL ROOM IR out, random FER at 5% --- lib_dec/dec_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 00f372154..191065855 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3807,7 +3807,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 + *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } -- GitLab From c57cb88294ea3b9fcb94bc3e574592e903c4a79e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 10 Mar 2025 08:43:15 +0100 Subject: [PATCH 0383/1221] use long testvectors for USAN tests too --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 58547f2ab..cb532dd7d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1307,7 +1307,7 @@ ivas-pytest-enc-usan: before_script: - CLANG_NUM=3 - DUT_DECODER_PATH=./$REF_DECODER_PATH - - TEST_SUITE=$SHORT_TEST_SUITE_ENCODER + - TEST_SUITE=$LONG_TEST_SUITE_ENCODER <<: *ivas-pytest-sanitizers-anchor ### jobs that test flt encoder -> fx decoder @@ -1397,7 +1397,7 @@ ivas-pytest-dec-usan: before_script: - CLANG_NUM=3 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - - TEST_SUITE=$SHORT_TEST_SUITE + - TEST_SUITE=$LONG_TEST_SUITE_NO_RENDERER <<: *ivas-pytest-sanitizers-anchor # --------------------------------------------------------------- -- GitLab From a9c9fd5c18a642694f5e0ecd1ebc26d7cb82718e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 12:32:57 +0530 Subject: [PATCH 0384/1221] Fix for 3GPP issue 1341: Usage of open/deleteCldfb() functions - multiple variants Link #1341 --- lib_com/cldfb.c | 107 +++-------------------- lib_com/cnst.h | 6 +- lib_com/prot_fx.h | 15 +--- lib_dec/init_dec_fx.c | 6 +- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 +- lib_dec/ivas_init_dec.c | 4 +- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 +- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +-- lib_enc/init_enc_fx.c | 4 +- lib_enc/ivas_masa_enc_fx.c | 4 +- lib_enc/ivas_omasa_enc_fx.c | 4 +- lib_enc/ivas_stereo_switching_enc_fx.c | 10 +-- lib_enc/ivas_stereo_td_enc_fx.c | 8 +- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 +- 19 files changed, 53 insertions(+), 147 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 38195b65d..7fc8026b5 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1364,8 +1364,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + CODE_TYPE code_type ) { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,7 +1379,14 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - configureCldfb_ivas_fx( hs, sampling_rate ); + IF( code_type == IVAS_ENC ) + { + configureCldfb_ivas_enc_fx( hs, sampling_rate ); + } + ELSE + { + configureCldfb_ivas_fx( hs, sampling_rate ); + } hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1413,65 +1420,6 @@ ivas_error openCldfb_ivas_fx( return IVAS_ERR_OK; } -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs; - Word16 buf_len; - - IF( ( hs = (HANDLE_CLDFB_FILTER_BANK) malloc( sizeof( CLDFB_FILTER_BANK ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - - hs->type = type; - move32(); - hs->prototype = prototype; - move32(); - - configureCldfb_ivas_enc_fx( hs, sampling_rate ); - hs->memory_length = 0; - move32(); - - IF( type == CLDFB_ANALYSIS ) - { - buf_len = sub( hs->p_filter_length, hs->no_channels ); - hs->FilterStates = (Word16 *) malloc( ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); - } - ELSE - { - buf_len = hs->p_filter_length; - move16(); - hs->FilterStates = (Word16 *) malloc( 2 * ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); - } - - if ( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer - move16(); - hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ - move16(); - set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = 0; - move16(); - set16_fx( hs->FilterStates, 0, i_mult( 9 + 16, hs->no_channels ) ); - set16_fx( hs->FilterStates_e, 0, sizeof( hs->FilterStates_e ) / sizeof( hs->FilterStates_e[0] ) ); - - *h_cldfb = hs; - - return IVAS_ERR_OK; -} - /*-------------------------------------------------------------------* * resampleCldfb_ivas() * @@ -1563,41 +1511,6 @@ void analysisCldfbEncoder_ivas_fx( return; } - -/*-------------------------------------------------------------------* - * GetEnergyCldfb_ivas() - * - * Remove handle - *--------------------------------------------------------------------*/ - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs = *h_cldfb; - - test(); - IF( h_cldfb == NULL || *h_cldfb == NULL ) - { - return; - } - - IF( hs->cldfb_state_fx ) - { - free( hs->cldfb_state_fx ); - } - - IF( hs->FilterStates ) - { - free( hs->FilterStates ); - } - - free( hs ); - *h_cldfb = NULL; - - return; -} - void deleteCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 7c93498af..3c014325e 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -803,7 +803,11 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; - +typedef enum +{ + IVAS_ENC, + IVAS_DEC_REND +} CODE_TYPE; typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index db0953cd9..c1aefbe36 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9803,8 +9803,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + CODE_TYPE code_type ); Word32 rand_gauss_fx( Word32 *x, @@ -11944,13 +11944,6 @@ ivas_error openCldfb_ivas( CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const Word32 newSamplerate /* i : new samplerate to operate */ @@ -11960,10 +11953,6 @@ ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - /*! r: flag indicating a valid bitrate */ Word16 is_EVS_bitrate( const Word32 ivas_total_brate, /* i : EVS total bitrate */ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 3865cd61c..4e0cfda18 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 25c0bea42..111c0be0e 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b11669460..236eaad54 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index a6be10c08..cc3980b12 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 3f39bd9ac..c8dde0837 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 09b683a16..34eef94ed 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 615ca1b33..f0338b461 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 6960629c8..9fdebed7a 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -260,7 +260,7 @@ void ivas_masa_enc_close_fx( FOR( i = 0; i < ( *hMasa )->data.num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); } IF( ( *hMasa )->data.hOmasaData != NULL ) diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 5d79265f4..50fb49355 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_enc( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -227,7 +227,7 @@ void ivas_omasa_enc_close_fx( FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); } FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 2fe8b6c84..6c7a1e68d 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -366,8 +366,8 @@ ivas_error stereo_memory_enc_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) || EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) ) { /* Deallocate MDCT CNG structures */ - deleteCldfb_ivas( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); - deleteCldfb_ivas( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index d2ff2c0c2..de9bc09b5 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -263,7 +263,7 @@ ivas_error stereo_set_tdm_fx( /* deallocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc != NULL ) { - deleteCldfb_ivas( &st->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); } /* deallocate BWEs for secondary channel */ @@ -275,7 +275,7 @@ ivas_error stereo_set_tdm_fx( st->hBWE_TD = NULL; } - deleteCldfb_ivas( &st->cldfbSynTd ); + deleteCldfb_ivas_fx( &st->cldfbSynTd ); IF( st->hBWE_FD != NULL ) { @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 93a100e17..5dd3f8384 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 430fab2c7..3aa9f62a9 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 8b56b6855..d56ba2685 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 2c28b32bd..1d849a90f 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2c81911a1..041f278f1 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 0c4a9f1957c11cb72f48d19ccabeb118dec895e5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:42:57 +0530 Subject: [PATCH 0385/1221] Address review comments --- lib_com/cldfb.c | 10 ++++++---- lib_com/cnst.h | 6 +----- lib_com/prot_fx.h | 2 +- lib_dec/init_dec_fx.c | 6 +++--- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 ++-- lib_dec/ivas_init_dec.c | 4 ++-- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 ++-- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +++++----- lib_enc/init_enc_fx.c | 4 ++-- lib_enc/ivas_masa_enc_fx.c | 2 +- lib_enc/ivas_omasa_enc_fx.c | 2 +- lib_enc/ivas_stereo_switching_enc_fx.c | 6 +++--- lib_enc/ivas_stereo_td_enc_fx.c | 4 ++-- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 ++-- 19 files changed, 38 insertions(+), 40 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 7fc8026b5..246a8a8e8 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1365,7 +1365,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ) + const Word16 enc_dec ) /* i : encoder/decoder flag */ { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,14 +1379,17 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - IF( code_type == IVAS_ENC ) + IF( enc_dec == ENC ) { configureCldfb_ivas_enc_fx( hs, sampling_rate ); + hs->Q_cldfb_state = 0; } ELSE { configureCldfb_ivas_fx( hs, sampling_rate ); + hs->Q_cldfb_state = Q11; } + move16(); hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1412,8 +1415,7 @@ ivas_error openCldfb_ivas_fx( hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ move16(); set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = Q11; - move16(); + *h_cldfb = hs; move16(); diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 3c014325e..7c93498af 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -803,11 +803,7 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; -typedef enum -{ - IVAS_ENC, - IVAS_DEC_REND -} CODE_TYPE; + typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c1aefbe36..9fe14b5bd 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9804,7 +9804,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ); + const Word16 enc_dec ); /* i : encoder/decoder flag */ Word32 rand_gauss_fx( Word32 *x, diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4e0cfda18..bd8a2cbd3 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 111c0be0e..8333f146f 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 236eaad54..1ab797ded 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index cc3980b12..12549f49d 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index c8dde0837..5b1378a89 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 34eef94ed..c70e606ac 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index f0338b461..cd5db5377 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 9fdebed7a..da1f836df 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 50fb49355..b5258712b 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 6c7a1e68d..0a526561a 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index de9bc09b5..1544aab76 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 5dd3f8384..1a5013059 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 3aa9f62a9..c74477365 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index d56ba2685..e17b2f9f6 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 1d849a90f..5e175fae5 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 041f278f1..129f72388 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 3a76357964d1df534da0093c5c51d0cd9f9db74e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:49:56 +0530 Subject: [PATCH 0386/1221] Fix for 3GPP issue 1361: Assert in BASOP decoder function ivas_dirac_dec_render_sf_fx for LTV MASA bitstream Link #1361 --- lib_dec/ivas_cpe_dec_fx.c | 4 ---- lib_dec/ivas_dirac_dec_fx.c | 37 ++++++++++++++++++++------------ lib_dec/ivas_stereo_dft_dec_fx.c | 3 ++- lib_rend/ivas_dirac_rend_fx.c | 2 ++ 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 6a6294377..9e934cc88 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -352,10 +352,6 @@ ivas_error ivas_cpe_dec_fx( { sts[0]->total_brate = hCPE->element_brate; /* Only mono downmix was transmitted in this case */ move32(); -#ifdef MSAN_FIX - hCPE->hStereoDft->frame_sid_nodata = 0; - move16(); -#endif } ELSE { diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index d8288e561..422622552 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2204,13 +2204,15 @@ void ivas_dirac_dec_render_sf_fx( Word32 Cldfb_RealBuffer_Temp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Temp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word16 cldfb_buf_q; - Word16 offset, buff_len; + Word16 offset = 0, buff_len = 0; + move16(); + move16(); Word16 q_cldfb, q_temp_cldfb = 0; move16(); Word16 proto_length = 0; move16(); - Word16 q_proto_direct_buffer[CLDFB_SLOTS_PER_SUBFRAME]; - Word16 q_proto_diffuse_buffer[CLDFB_SLOTS_PER_SUBFRAME]; + Word16 q_proto_direct_buffer[CLDFB_SLOTS_PER_SUBFRAME + 1]; + Word16 q_proto_diffuse_buffer[CLDFB_SLOTS_PER_SUBFRAME + 1]; Word16 size, size_ho; DIRAC_DEC_STACK_MEM DirAC_mem; @@ -2258,8 +2260,8 @@ void ivas_dirac_dec_render_sf_fx( } q_cldfb = Q11; move16(); - set16_fx( q_proto_direct_buffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME ); - set16_fx( q_proto_diffuse_buffer, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME ); + set16_fx( q_proto_direct_buffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME + 1 ); + set16_fx( q_proto_diffuse_buffer, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME + 1 ); set_zero_fx( surCohRatio_fx, CLDFB_NO_CHANNELS_MAX ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) @@ -3252,22 +3254,21 @@ void ivas_dirac_dec_render_sf_fx( } } - minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); + minimum_s( q_proto_direct_buffer, add( hSpatParamRendCom->subframe_nbslots[subframe_idx], 1 ), &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - minimum_s( q_proto_diffuse_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q ); + minimum_s( q_proto_diffuse_buffer, add( hSpatParamRendCom->subframe_nbslots[subframe_idx], 1 ), &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q ); } FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, nchan_transport ) ); - buff_len = i_mult( 2, i_mult( nchan_transport, hSpatParamRendCom->num_freq_bands ) ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q - offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) ); buff_len = i_mult( 2, i_mult( hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, q_proto_diffuse_buffer[slot_idx] ) ); // proto_diffuse_buffer_f_q + offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, nchan_transport ) ); + buff_len = i_mult( 2, i_mult( nchan_transport, hSpatParamRendCom->num_freq_bands ) ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q } ELSE IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) { @@ -3307,10 +3308,18 @@ void ivas_dirac_dec_render_sf_fx( BREAK; } } - q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; - move16(); } - + test(); + IF( EQ_16( slot_idx, hSpatParamRendCom->subframe_nbslots[subframe_idx] ) && sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, add( offset, buff_len ) ) > 0 ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + add( offset, buff_len ), sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, add( offset, buff_len ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q + offset = i_mult( i_mult( sub( slot_idx, 1 ), 2 ), i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) ); + buff_len = i_mult( 2, i_mult( hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands ) ); + IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, add( offset, buff_len ) ) > 0 ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + add( offset, buff_len ), sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, add( offset, buff_len ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, q_proto_diffuse_buffer[slot_idx] ) ); // proto_direct_buffer_f_q + } + } ivas_dirac_dec_output_synthesis_get_interpolator_fx( &hDirACRend->h_output_synthesis_psd_params, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); size = i_mult( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 1c18ffacb..3d9e58ad1 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -258,7 +258,8 @@ void stereo_dft_dec_reset_fx( move16(); hStereoDft->ipd_xfade_prev_fx = 0; move32(); - + hStereoDft->frame_sid_nodata = 0; + move16(); #ifdef MSAN_FIX FOR( b = 0; b < 2 * IVAS_MAX_NUM_BANDS; b++ ) { diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index e254ed6dd..35fedfc81 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -871,6 +871,8 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands ); move16(); + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31; + move16(); IF( hDirACRend->proto_signal_decorr_on ) { -- GitLab From 4d1e1c0534ed71289e06ca2e88d94e83e2a4dd82 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:52:47 +0530 Subject: [PATCH 0387/1221] Fix for 3GPP issue 1373: Decoder crash for stereo at 80kbps JBM decoding to Mono in get_scaling_quality_fx() Link #1373 --- lib_dec/jbm_pcmdsp_apa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index ac6a28b86..fc793dff0 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -900,7 +900,7 @@ UWord8 apa_exec_ivas_fx( UWord32 statsResetThreshold, statsResetShift; Word16 Q_a_out; - Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 ); + Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 - Q1 ); statsResetThreshold = 1637; move32(); statsResetShift = 2; -- GitLab From 29426491cb92052cc83785b30729f3e30e83c66e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 12:52:44 +0530 Subject: [PATCH 0388/1221] USAN fix for decoder --- lib_dec/ivas_lfe_plc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 210c266eb..8ed450435 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( -s, err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate(s), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); -- GitLab From 2e871041f0a632bd97de676a98e07331e2961624 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 12:55:14 +0530 Subject: [PATCH 0389/1221] Clang formatting changes --- lib_dec/ivas_lfe_plc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 8ed450435..d98603d2a 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate(s), err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate( s ), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); -- GitLab From f3550e69001068f3187efececff2be68d883b353 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 12 Mar 2025 10:45:04 +0100 Subject: [PATCH 0390/1221] Fix issue 1378 (invalid read access) --- lib_com/options.h | 1 + lib_dec/dec_acelp_fx.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index d03261715..5d1d0d6e1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -171,5 +171,6 @@ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ +#define FIX_1378_ACELP_OUT_OF_BOUNDS /* Avoid index -1 in array read access */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ #endif diff --git a/lib_dec/dec_acelp_fx.c b/lib_dec/dec_acelp_fx.c index 07750469f..51cbef624 100644 --- a/lib_dec/dec_acelp_fx.c +++ b/lib_dec/dec_acelp_fx.c @@ -169,6 +169,7 @@ void D_ACELP_indexing_fx( pulses = pulsestrack[0]; move16(); +#ifndef FIX_1378_ACELP_OUT_OF_BOUNDS /* safety check in case of bit errors */ IF( GE_64( s, pulsestostates[16][pulses - 1] ) ) { @@ -177,9 +178,20 @@ void D_ACELP_indexing_fx( move16(); return; } +#endif IF( pulses ) { +#ifdef FIX_1378_ACELP_OUT_OF_BOUNDS + /* safety check in case of bit errors */ + IF( GE_64( s, pulsestostates[16][pulses - 1] ) ) + { + set16_fx( code, 0, L_SUBFR ); + *BER_detect = 1; + move16(); + return; + } +#endif D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 ); } ELSE -- GitLab From 6d695dc9fe2671871299db840c95b1b32a326336 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Mar 2025 11:15:44 +0100 Subject: [PATCH 0391/1221] preparation for the cleanup. --- lib_enc/ivas_sns_enc_fx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 3ae1ea424..808de8cfd 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -204,7 +204,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } @@ -236,11 +236,15 @@ static Word16 sns_1st_cod_fx_q15( { Word32 tmp; Word32 dist; + Word16 tmp2; + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 dist = L_sub( snsq_fx[j], tmp ); - dist = L_shr( dist, 4 ); // TODO: Magic shift. - dist = L_mult( extract_l( dist ), extract_l( dist ) ); - dist = L_shr( dist, 4 ); // TODO: Magic shift + dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow + + tmp2 = extract_l( dist ); + dist = L_mult( tmp2, tmp2 ); + dist = L_shr( dist, 4 ); // make sure that the sum does not overflow dist_fx = L_add( dist_fx, dist ); } @@ -256,7 +260,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 j = j0; j < j1; ++j ) { Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( *cdbk_ptr++ , cdbk_fix ); // Q16 + Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } -- GitLab From d2f9e30ea388691d3fa7cd5a5965df84900ef8a0 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Mar 2025 11:53:54 +0100 Subject: [PATCH 0392/1221] merge candiate. --- lib_enc/ivas_sns_enc_fx.c | 376 +++++++++++++++++++------------------- 1 file changed, 184 insertions(+), 192 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 808de8cfd..15768d392 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -60,221 +60,214 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - Word16 index, i; - const Word16 split_len = M / 2; - move16(); - const Word16 *means; - const Word16 means_fix = 2; // Q15 - move16(); - /* remove means */ - means = NULL; - SWITCH( L_frame ) + IF( exp_sns == Q15) { - case L_FRAME16k: - means = &sns_1st_means_16k[core - 1][0]; - break; - case L_FRAME25_6k: - means = &sns_1st_means_25k6[core - 1][0]; - break; - case L_FRAME32k: - means = &sns_1st_means_32k[core - 1][0]; - break; - default: - assert( !"illegal frame length in sns_1st_cod" ); - } - Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; - move16(); - move16(); - FOR( i = 0; i < M; ++i ) - { - Word32 tmp = L_mult( means[i], means_fix ); // Q16 - exp_snsq_buffer[i] = 0; + Word16 index; + const Word16 split_len = M / 2; move16(); - snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); - move32(); - } - FOR( i = 0; i < M; i++ ) - { - exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); - } - FOR( i = 0; i < M; i++ ) - { - snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); - move32(); - } - - index = 0; - move16(); - FOR( Word16 split = 0; split < 2; ++split ) - { - const Word16 *cdbk_ptr; - Word16 j0, j1, index_split; - Word32 dist_min_fx; - const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 + const Word16 *means; + const Word16 means_fix = 2; // Q15 move16(); - const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - - j0 = imult1616( split, split_len ); - j1 = add( j0, split_len ); - - cdbk_ptr = cdbk; - dist_min_fx = MAXVAL_WORD32; - Word16 exp_dist_min = 31; - index_split = 0; - FOR( i = 0; i < 32; ++i ) + /* remove means */ + means = NULL; + SWITCH( L_frame ) + { + case L_FRAME16k: + means = &sns_1st_means_16k[core - 1][0]; + break; + case L_FRAME25_6k: + means = &sns_1st_means_25k6[core - 1][0]; + break; + case L_FRAME32k: + means = &sns_1st_means_32k[core - 1][0]; + break; + default: + assert( !"illegal frame length in sns_1st_cod" ); + } + FOR( Word16 i = 0; i < M; ++i ) { - Word32 dist_fx = 0; + Word32 tmp = L_mult( means[i], means_fix ); // Q16 + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); - Word16 exp_dist = 0; + } + + index = 0; + move16(); + FOR( Word16 split = 0; split < 2; ++split ) + { + const Word16 *cdbk_ptr; + Word16 j0, j1; + Word16 dist_split; + Word32 dist_min_fx; + const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); - FOR( Word16 j = j0; j < j1; ++j ) + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + + j0 = imult1616( split, split_len ); + j1 = add( j0, split_len ); + + cdbk_ptr = cdbk; + dist_min_fx = MAXVAL_WORD32; + dist_split = 0; + move32(); + move16(); + FOR( Word16 i = 0; i < 32; ++i ) { - Word32 tmp_fx; - Word16 exp_tmp = 0; - move16(); - Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp ); - Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2 - dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2 + Word32 dist_fx = 0; + move32(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 tmp; + Word32 dist; + Word16 tmp2; + + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 + dist = L_sub( snsq_fx[j], tmp ); + dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow + + tmp2 = extract_l( dist ); + dist = L_mult( tmp2, tmp2 ); + dist = L_shr( dist, 4 ); // make sure that the sum does not overflow + dist_fx = L_add( dist_fx, dist ); + } + + IF( LT_32( dist_fx, dist_min_fx ) ) + { + dist_min_fx = dist_fx; + dist_split = i; + } } - - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) ) + + /* set quantized vector */ + cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; + FOR( Word16 j = j0; j < j1; ++j ) { - dist_min_fx = dist_fx; + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); - exp_dist_min = exp_dist; - move16(); - index_split = i; - move16(); } + + /* for second split shift by five bits to store both indices as one 10 bit value */ + if ( EQ_16( split, 1 ) ) + { + dist_split = shl( dist_split, 5 ); + } + + index = add( index, dist_split ); } - - /* set quantized vector */ - cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; - FOR( Word16 j = j0; j < j1; ++j ) + return index; + } ELSE { + Word16 index, i; + const Word16 split_len = M / 2; + move16(); + const Word16 *means; + const Word16 means_fix = 2; // Q15 + move16(); + /* remove means */ + means = NULL; + SWITCH( L_frame ) { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + case L_FRAME16k: + means = &sns_1st_means_16k[core - 1][0]; + break; + case L_FRAME25_6k: + means = &sns_1st_means_25k6[core - 1][0]; + break; + case L_FRAME32k: + means = &sns_1st_means_32k[core - 1][0]; + break; + default: + assert( !"illegal frame length in sns_1st_cod" ); + } + Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; + move16(); + move16(); + FOR( i = 0; i < M; ++i ) + { + Word32 tmp = L_mult( means[i], means_fix ); // Q16 + exp_snsq_buffer[i] = 0; + move16(); + snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); move32(); } - - /* for second split shift by five bits to store both indices as one 10 bit value */ - IF( EQ_16( split, 1 ) ) + FOR( i = 0; i < M; i++ ) { - index_split = shl( index_split, 5 ); + exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); } - - index = add( index, index_split ); - } - - return index; -} - -static Word16 sns_1st_cod_fx_q15( - const Word32 *sns_fx, /* i : vector to quantize */ - const Word16 L_frame, - const Word16 core, - Word32 *snsq_fx /* o : quantized sns Q16 */ -) -{ - Word16 index; - const Word16 split_len = M / 2; - move16(); - const Word16 *means; - const Word16 means_fix = 2; // Q15 - push_wmops( "sns_1st_cod_fx_q15" ); - move16(); - /* remove means */ - means = NULL; - SWITCH( L_frame ) - { - case L_FRAME16k: - means = &sns_1st_means_16k[core - 1][0]; - break; - case L_FRAME25_6k: - means = &sns_1st_means_25k6[core - 1][0]; - break; - case L_FRAME32k: - means = &sns_1st_means_32k[core - 1][0]; - break; - default: - assert( !"illegal frame length in sns_1st_cod" ); - } - FOR( Word16 i = 0; i < M; ++i ) - { - Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 - move32(); - } - - index = 0; - move16(); - FOR( Word16 split = 0; split < 2; ++split ) - { - const Word16 *cdbk_ptr; - Word16 j0, j1; - Word16 dist_split; - Word32 dist_min_fx; - const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 - move16(); - const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - - j0 = imult1616( split, split_len ); - j1 = add( j0, split_len ); - - cdbk_ptr = cdbk; - dist_min_fx = MAXVAL_WORD32; - dist_split = 0; - move32(); - move16(); - FOR( Word16 i = 0; i < 32; ++i ) + FOR( i = 0; i < M; i++ ) { - Word32 dist_fx = 0; + snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); + } + + index = 0; + move16(); + FOR( Word16 split = 0; split < 2; ++split ) + { + const Word16 *cdbk_ptr; + Word16 j0, j1, index_split; + Word32 dist_min_fx; + const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 + move16(); + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + + j0 = imult1616( split, split_len ); + j1 = add( j0, split_len ); + + cdbk_ptr = cdbk; + dist_min_fx = MAXVAL_WORD32; + Word16 exp_dist_min = 31; + index_split = 0; + FOR( i = 0; i < 32; ++i ) + { + Word32 dist_fx = 0; + move32(); + Word16 exp_dist = 0; + move16(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 tmp_fx; + Word16 exp_tmp = 0; + move16(); + Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp ); + Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2 + dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2 + } + + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) ) + { + dist_min_fx = dist_fx; + move32(); + exp_dist_min = exp_dist; + move16(); + index_split = i; + move16(); + } + } + + /* set quantized vector */ + cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { - Word32 tmp; - Word32 dist; - Word16 tmp2; - - tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - dist = L_sub( snsq_fx[j], tmp ); - dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow - - tmp2 = extract_l( dist ); - dist = L_mult( tmp2, tmp2 ); - dist = L_shr( dist, 4 ); // make sure that the sum does not overflow - dist_fx = L_add( dist_fx, dist ); + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + move32(); } - - IF( LT_32( dist_fx, dist_min_fx ) ) + + /* for second split shift by five bits to store both indices as one 10 bit value */ + IF( EQ_16( split, 1 ) ) { - dist_min_fx = dist_fx; - dist_split = i; + index_split = shl( index_split, 5 ); } + + index = add( index, index_split ); } - - /* set quantized vector */ - cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; - FOR( Word16 j = j0; j < j1; ++j ) - { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 - move32(); - } - - /* for second split shift by five bits to store both indices as one 10 bit value */ - if ( EQ_16( split, 1 ) ) - { - dist_split = shl( dist_split, 5 ); - } - - index = add( index, dist_split ); + + return index; } - pop_wmops(); - return index; } /*------------------------------------------------------------------- @@ -382,7 +375,7 @@ void sns_avq_cod_fx( Word16 indxt[256], nbits, nbt, nit; Word32 snsmid_q0_fx[M]; - index[0] = sns_1st_cod_fx_q15( sns_fx, L_frame, core, sns_q_fx ); + index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx ); move16(); nit = 1 + 2; move16(); @@ -409,8 +402,7 @@ void sns_avq_cod_fx( { index++; - index[0] = sns_1st_cod_fx_q15( snsmid_fx, L_frame, core, snsmid_q_fx ); - // index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); + index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); move16(); nit = 1 + 2; move16(); -- GitLab From 3b55b2d8511ffd924e0ed55b3f5d335860ef1a4d Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 12 Mar 2025 12:00:22 +0100 Subject: [PATCH 0393/1221] Use round_fx instead of extract_h for angle computation. --- lib_com/options.h | 1 + lib_dec/ivas_dirac_dec_fx.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index d03261715..4272caefe 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,4 +172,5 @@ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ +#define FIX_1379_MASA_ANGLE_ROUND #endif diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index d8288e561..7ad651af1 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -1446,10 +1446,17 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { +#ifdef FIX_1379_MASA_ANGLE_ROUND + hSpatParamRendCom->azimuth[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); + move16(); + hSpatParamRendCom->elevation[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); + move16(); +#else hSpatParamRendCom->azimuth[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); move16(); hSpatParamRendCom->elevation[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); move16(); +#endif hSpatParamRendCom->energy_ratio1_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; move32(); hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( ONE_IN_Q30, q_direction->band_data[band].energy_ratio_fx[block] ); @@ -1494,10 +1501,17 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { +#ifdef FIX_1379_MASA_ANGLE_ROUND + hSpatParamRendCom->azimuth2[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); + move16(); + hSpatParamRendCom->elevation2[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); + move16(); +#else hSpatParamRendCom->azimuth2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); move16(); hSpatParamRendCom->elevation2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); move16(); +#endif hSpatParamRendCom->energy_ratio2_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; move32(); hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], q_direction->band_data[band].energy_ratio_fx[block] ); @@ -1704,8 +1718,13 @@ void ivas_qmetadata_to_dirac_fx( IF( hodirac_flag ) { +#ifdef FIX_1379_MASA_ANGLE_ROUND + azi = round_fx( L_shr( ( L_add( azimuth_fx, ONE_IN_Q21 ) ), 6 ) ); + ele = round_fx( L_shr( ( L_add( elevation_fx, ONE_IN_Q21 ) ), 6 ) ); +#else azi = extract_h( L_shr( ( L_add( azimuth_fx, ONE_IN_Q21 ) ), 6 ) ); ele = extract_h( L_shr( ( L_add( elevation_fx, ONE_IN_Q21 ) ), 6 ) ); +#endif /*addition of one to compensate precision loss*/ if ( azi < 0 ) { @@ -1741,8 +1760,13 @@ void ivas_qmetadata_to_dirac_fx( final_1_32 = BASOP_Util_Add_Mant32Exp( final_1_32, final_1_exp, ONE_IN_Q30, 0, &final_1_exp ); /*0.5 in q31*/ final_2_32 = BASOP_Util_Add_Mant32Exp( final_2_32, final_2_exp, ONE_IN_Q30, 0, &final_2_exp ); +#ifdef FIX_1379_MASA_ANGLE_ROUND + azi = round_fx( L_shr( final_1_32, sub( sub( 31, final_1_exp ), 16 ) ) ); + ele = round_fx( L_shr( final_2_32, sub( sub( 31, final_2_exp ), 16 ) ) ); +#else azi = extract_h( L_shr( final_1_32, sub( sub( 31, final_1_exp ), 16 ) ) ); ele = extract_h( L_shr( final_2_32, sub( sub( 31, final_2_exp ), 16 ) ) ); +#endif /*addition of one to compensate precision loss*/ if ( azi < 0 ) @@ -3597,7 +3621,9 @@ void ivas_dirac_dec_render_sf_fx( { Word16 j, k, j2, l; Word16 num_objects, nchan_out_woLFE, lfe_index; +#ifndef FIX_1379_MASA_ANGLE_ROUND Word16 az1, el1; +#endif Word16 n_slots_to_render; Word16 n_samples_to_render; Word16 interp_offset; @@ -3631,13 +3657,20 @@ void ivas_dirac_dec_render_sf_fx( Word16 el_q0 = extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, Q22 ) ); Word32 az1_32, el1_32; rotateAziEle_fixed( az_q0, el_q0, &az1_32, &el1_32, st_ivas->hCombinedOrientationData->Rmat_fx[0], st_ivas->hIntSetup.is_planar_setup ); +#ifndef FIX_1379_MASA_ANGLE_ROUND az1 = extract_h( az1_32 ); el1 = extract_h( el1_32 ); +#endif IF( st_ivas->hEFAPdata != NULL ) { +#ifdef FIX_1379_MASA_ANGLE_ROUND + const Word32 azi_fx = L_shl( az1_32, Q22-Q16 ); // Q16 -> Q22 + const Word32 ele_fx = L_shl( el1_32, Q22-Q16 ); // Q16 -> Q22 +#else const Word32 azi_fx = L_shl( az1, Q22 ); // Q0 -> Q22 const Word32 ele_fx = L_shl( el1, Q22 ); // Q0 -> Q22 +#endif efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], azi_fx, ele_fx, EFAP_MODE_EFAP ); } } -- GitLab From 662acc0a60da5e09d9250445e76ef9fe3be8a655 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Mar 2025 12:01:43 +0100 Subject: [PATCH 0394/1221] applied the clang patch. --- lib_enc/ivas_sns_enc_fx.c | 48 ++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 0fccc8ec8..a7435fb0d 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - IF( exp_sns == Q15) + IF( exp_sns == Q15 ) { Word16 index; const Word16 split_len = M / 2; @@ -86,10 +86,10 @@ static Word16 sns_1st_cod_fx( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } - + index = 0; move16(); FOR( Word16 split = 0; split < 2; ++split ) @@ -101,10 +101,10 @@ static Word16 sns_1st_cod_fx( const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - + j0 = imult1616( split, split_len ); j1 = add( j0, split_len ); - + cdbk_ptr = cdbk; dist_min_fx = MAXVAL_WORD32; dist_split = 0; @@ -119,44 +119,46 @@ static Word16 sns_1st_cod_fx( Word32 tmp; Word32 dist; Word16 tmp2; - + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - dist = L_sub( snsq_fx[j], tmp ); + dist = L_sub( snsq_fx[j], tmp ); dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow - + tmp2 = extract_l( dist ); dist = L_mult( tmp2, tmp2 ); dist = L_shr( dist, 4 ); // make sure that the sum does not overflow dist_fx = L_add( dist_fx, dist ); } - + IF( LT_32( dist_fx, dist_min_fx ) ) { dist_min_fx = dist_fx; dist_split = i; } } - + /* set quantized vector */ cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } - + /* for second split shift by five bits to store both indices as one 10 bit value */ if ( EQ_16( split, 1 ) ) { dist_split = shl( dist_split, 5 ); } - + index = add( index, dist_split ); } return index; - } ELSE { + } + ELSE + { Word16 index, i; const Word16 split_len = M / 2; move16(); @@ -199,7 +201,7 @@ static Word16 sns_1st_cod_fx( snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); } - + index = 0; move16(); FOR( Word16 split = 0; split < 2; ++split ) @@ -210,10 +212,10 @@ static Word16 sns_1st_cod_fx( const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - + j0 = imult1616( split, split_len ); j1 = add( j0, split_len ); - + cdbk_ptr = cdbk; dist_min_fx = MAXVAL_WORD32; Word16 exp_dist_min = 31; @@ -234,7 +236,7 @@ static Word16 sns_1st_cod_fx( Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2 dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2 } - + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) ) { dist_min_fx = dist_fx; @@ -245,7 +247,7 @@ static Word16 sns_1st_cod_fx( move16(); } } - + /* set quantized vector */ cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) @@ -255,16 +257,16 @@ static Word16 sns_1st_cod_fx( snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } - + /* for second split shift by five bits to store both indices as one 10 bit value */ IF( EQ_16( split, 1 ) ) { index_split = shl( index_split, 5 ); } - + index = add( index, index_split ); } - + return index; } } -- GitLab From 820ea273d5140a00c5696978276e99729b1b11ab Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 12 Mar 2025 12:02:11 +0100 Subject: [PATCH 0395/1221] Use round_fx instead of extract_h for angle computation. format fix. --- lib_dec/ivas_dirac_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 7ad651af1..26c7e3441 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3665,8 +3665,8 @@ void ivas_dirac_dec_render_sf_fx( IF( st_ivas->hEFAPdata != NULL ) { #ifdef FIX_1379_MASA_ANGLE_ROUND - const Word32 azi_fx = L_shl( az1_32, Q22-Q16 ); // Q16 -> Q22 - const Word32 ele_fx = L_shl( el1_32, Q22-Q16 ); // Q16 -> Q22 + const Word32 azi_fx = L_shl( az1_32, Q22 - Q16 ); // Q16 -> Q22 + const Word32 ele_fx = L_shl( el1_32, Q22 - Q16 ); // Q16 -> Q22 #else const Word32 azi_fx = L_shl( az1, Q22 ); // Q0 -> Q22 const Word32 ele_fx = L_shl( el1, Q22 ); // Q0 -> Q22 -- GitLab From 4714a44d70693d2ffbbb4eb5ba2f717b14df91f2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 12:32:57 +0530 Subject: [PATCH 0396/1221] Fix for 3GPP issue 1341: Usage of open/deleteCldfb() functions - multiple variants Link #1341 --- lib_com/cldfb.c | 107 +++-------------------- lib_com/cnst.h | 6 +- lib_com/prot_fx.h | 15 +--- lib_dec/init_dec_fx.c | 6 +- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 +- lib_dec/ivas_init_dec.c | 4 +- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 +- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +-- lib_enc/init_enc_fx.c | 4 +- lib_enc/ivas_masa_enc_fx.c | 4 +- lib_enc/ivas_omasa_enc_fx.c | 4 +- lib_enc/ivas_stereo_switching_enc_fx.c | 10 +-- lib_enc/ivas_stereo_td_enc_fx.c | 8 +- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 +- 19 files changed, 53 insertions(+), 147 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 38195b65d..7fc8026b5 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1364,8 +1364,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + CODE_TYPE code_type ) { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,7 +1379,14 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - configureCldfb_ivas_fx( hs, sampling_rate ); + IF( code_type == IVAS_ENC ) + { + configureCldfb_ivas_enc_fx( hs, sampling_rate ); + } + ELSE + { + configureCldfb_ivas_fx( hs, sampling_rate ); + } hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1413,65 +1420,6 @@ ivas_error openCldfb_ivas_fx( return IVAS_ERR_OK; } -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs; - Word16 buf_len; - - IF( ( hs = (HANDLE_CLDFB_FILTER_BANK) malloc( sizeof( CLDFB_FILTER_BANK ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - - hs->type = type; - move32(); - hs->prototype = prototype; - move32(); - - configureCldfb_ivas_enc_fx( hs, sampling_rate ); - hs->memory_length = 0; - move32(); - - IF( type == CLDFB_ANALYSIS ) - { - buf_len = sub( hs->p_filter_length, hs->no_channels ); - hs->FilterStates = (Word16 *) malloc( ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); - } - ELSE - { - buf_len = hs->p_filter_length; - move16(); - hs->FilterStates = (Word16 *) malloc( 2 * ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); - } - - if ( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer - move16(); - hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ - move16(); - set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = 0; - move16(); - set16_fx( hs->FilterStates, 0, i_mult( 9 + 16, hs->no_channels ) ); - set16_fx( hs->FilterStates_e, 0, sizeof( hs->FilterStates_e ) / sizeof( hs->FilterStates_e[0] ) ); - - *h_cldfb = hs; - - return IVAS_ERR_OK; -} - /*-------------------------------------------------------------------* * resampleCldfb_ivas() * @@ -1563,41 +1511,6 @@ void analysisCldfbEncoder_ivas_fx( return; } - -/*-------------------------------------------------------------------* - * GetEnergyCldfb_ivas() - * - * Remove handle - *--------------------------------------------------------------------*/ - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs = *h_cldfb; - - test(); - IF( h_cldfb == NULL || *h_cldfb == NULL ) - { - return; - } - - IF( hs->cldfb_state_fx ) - { - free( hs->cldfb_state_fx ); - } - - IF( hs->FilterStates ) - { - free( hs->FilterStates ); - } - - free( hs ); - *h_cldfb = NULL; - - return; -} - void deleteCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 7c93498af..3c014325e 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -803,7 +803,11 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; - +typedef enum +{ + IVAS_ENC, + IVAS_DEC_REND +} CODE_TYPE; typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index db0953cd9..c1aefbe36 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9803,8 +9803,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + CODE_TYPE code_type ); Word32 rand_gauss_fx( Word32 *x, @@ -11944,13 +11944,6 @@ ivas_error openCldfb_ivas( CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const Word32 newSamplerate /* i : new samplerate to operate */ @@ -11960,10 +11953,6 @@ ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - /*! r: flag indicating a valid bitrate */ Word16 is_EVS_bitrate( const Word32 ivas_total_brate, /* i : EVS total bitrate */ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 3865cd61c..4e0cfda18 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 25c0bea42..111c0be0e 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b11669460..236eaad54 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index a6be10c08..cc3980b12 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 3f39bd9ac..c8dde0837 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 09b683a16..34eef94ed 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 615ca1b33..f0338b461 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 6960629c8..9fdebed7a 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -260,7 +260,7 @@ void ivas_masa_enc_close_fx( FOR( i = 0; i < ( *hMasa )->data.num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); } IF( ( *hMasa )->data.hOmasaData != NULL ) diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 5d79265f4..50fb49355 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_enc( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -227,7 +227,7 @@ void ivas_omasa_enc_close_fx( FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); } FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 2fe8b6c84..6c7a1e68d 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -366,8 +366,8 @@ ivas_error stereo_memory_enc_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) || EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) ) { /* Deallocate MDCT CNG structures */ - deleteCldfb_ivas( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); - deleteCldfb_ivas( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index d2ff2c0c2..de9bc09b5 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -263,7 +263,7 @@ ivas_error stereo_set_tdm_fx( /* deallocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc != NULL ) { - deleteCldfb_ivas( &st->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); } /* deallocate BWEs for secondary channel */ @@ -275,7 +275,7 @@ ivas_error stereo_set_tdm_fx( st->hBWE_TD = NULL; } - deleteCldfb_ivas( &st->cldfbSynTd ); + deleteCldfb_ivas_fx( &st->cldfbSynTd ); IF( st->hBWE_FD != NULL ) { @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 93a100e17..5dd3f8384 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 430fab2c7..3aa9f62a9 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 8b56b6855..d56ba2685 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 2c28b32bd..1d849a90f 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2c81911a1..041f278f1 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From b3f172527adda62f08af43cb0d81f7b553e0f8f2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:42:57 +0530 Subject: [PATCH 0397/1221] Address review comments --- lib_com/cldfb.c | 10 ++++++---- lib_com/cnst.h | 6 +----- lib_com/prot_fx.h | 2 +- lib_dec/init_dec_fx.c | 6 +++--- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 ++-- lib_dec/ivas_init_dec.c | 4 ++-- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 ++-- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +++++----- lib_enc/init_enc_fx.c | 4 ++-- lib_enc/ivas_masa_enc_fx.c | 2 +- lib_enc/ivas_omasa_enc_fx.c | 2 +- lib_enc/ivas_stereo_switching_enc_fx.c | 6 +++--- lib_enc/ivas_stereo_td_enc_fx.c | 4 ++-- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 ++-- 19 files changed, 38 insertions(+), 40 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 7fc8026b5..246a8a8e8 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1365,7 +1365,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ) + const Word16 enc_dec ) /* i : encoder/decoder flag */ { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,14 +1379,17 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - IF( code_type == IVAS_ENC ) + IF( enc_dec == ENC ) { configureCldfb_ivas_enc_fx( hs, sampling_rate ); + hs->Q_cldfb_state = 0; } ELSE { configureCldfb_ivas_fx( hs, sampling_rate ); + hs->Q_cldfb_state = Q11; } + move16(); hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1412,8 +1415,7 @@ ivas_error openCldfb_ivas_fx( hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ move16(); set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = Q11; - move16(); + *h_cldfb = hs; move16(); diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 3c014325e..7c93498af 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -803,11 +803,7 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; -typedef enum -{ - IVAS_ENC, - IVAS_DEC_REND -} CODE_TYPE; + typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c1aefbe36..9fe14b5bd 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9804,7 +9804,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ); + const Word16 enc_dec ); /* i : encoder/decoder flag */ Word32 rand_gauss_fx( Word32 *x, diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4e0cfda18..bd8a2cbd3 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 111c0be0e..8333f146f 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 236eaad54..1ab797ded 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index cc3980b12..12549f49d 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index c8dde0837..5b1378a89 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 34eef94ed..c70e606ac 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index f0338b461..cd5db5377 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 9fdebed7a..da1f836df 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 50fb49355..b5258712b 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 6c7a1e68d..0a526561a 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index de9bc09b5..1544aab76 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 5dd3f8384..1a5013059 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 3aa9f62a9..c74477365 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index d56ba2685..e17b2f9f6 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 1d849a90f..5e175fae5 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 041f278f1..129f72388 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 69a038c82424104d0dff5450e47557ee13853933 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 12 Mar 2025 13:26:21 +0100 Subject: [PATCH 0398/1221] Cleanup in lib_dec/FEC_HQ_core_fx.c, removing ADD_IVAS_HQ_CODE_FEC --- lib_dec/FEC_HQ_core_fx.c | 339 +++++++++++++++++++-------------------- 1 file changed, 167 insertions(+), 172 deletions(-) diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 989f42821..cc03dcf52 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -725,10 +725,9 @@ void HQ_FEC_Mem_update_fx( move32(); #endif move32(); // tmp_energy_fx -#ifdef ADD_IVAS_HQ_CODE_FEC + IF( EQ_16( output_frame, L_FRAME8k ) ) { -#endif IF( is_transient ) { @@ -759,226 +758,222 @@ void HQ_FEC_Mem_update_fx( } } } -#ifndef ADD_IVAS_HQ_CODE_FEC - IF( EQ_16( output_frame, L_FRAME8k ) ) - { -#endif - /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */ - test(); - IF( ( EQ_16( hqswb_clas, HQ_HVQ ) ) || ( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) ) - { - /* First group */ - logqnorm_fx( t_audio_q_fx, 12, ynrm, 32, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) ); - j = ynrm[0]; - move16(); - offset = WID_G1; - move16(); - FOR( i = 1; i < SFM_G1; i++ ) - { - logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) ); - offset = add( offset, WID_G1 ); - } + /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */ + test(); + IF( ( EQ_16( hqswb_clas, HQ_HVQ ) ) || ( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) ) + { + /* First group */ + logqnorm_fx( t_audio_q_fx, 12, ynrm, 32, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) ); + j = ynrm[0]; + move16(); + offset = WID_G1; + move16(); - /* Second group */ - FOR( i = SFM_G1; i < SFM_G1 + 2; i++ ) - { - logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G2, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) ); - offset = add( offset, WID_G2 ); - } + FOR( i = 1; i < SFM_G1; i++ ) + { + logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) ); + offset = add( offset, WID_G1 ); } - /* Memory update for the LGF log2 Norm */ - FOR( i = 0; i < nb_sfm; i++ ) + /* Second group */ + FOR( i = SFM_G1; i < SFM_G1 + 2; i++ ) { - normq_fx[i] = dicn_fx[ynrm[i]]; - move32(); + logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G2, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) ); + offset = add( offset, WID_G2 ); } - k = 0; - move16(); - FOR( i = 0; i < num_Sb; i++ ) - { - norm_values_fx = &hHQ_nbfec->ynrm_values_fx[i][0]; - Copy32( norm_values_fx, &norm_values_fx[1], MAX_PGF - 1 ); + } - L_tmp = L_deposit_l( 0 ); - FOR( j = 0; j < Num_bands_p[i]; j++ ) - { - L_tmp = L_add( L_tmp, L_shr( normq_fx[k], 3 ) ); /*11*/ - k = add( k, 1 ); - } - tmp_fx = shl_o( inv_tbl_fx[Num_bands_p[i]], 1, &Overflow ); /*16*/ - norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/ - move32(); - tmp_energy_fx = L_add( tmp_energy_fx, L_shr( L_tmp, 3 ) ); /*8*/ + /* Memory update for the LGF log2 Norm */ + FOR( i = 0; i < nb_sfm; i++ ) + { + normq_fx[i] = dicn_fx[ynrm[i]]; + move32(); + } + k = 0; + move16(); + FOR( i = 0; i < num_Sb; i++ ) + { + norm_values_fx = &hHQ_nbfec->ynrm_values_fx[i][0]; + Copy32( norm_values_fx, &norm_values_fx[1], MAX_PGF - 1 ); + + L_tmp = L_deposit_l( 0 ); + FOR( j = 0; j < Num_bands_p[i]; j++ ) + { + L_tmp = L_add( L_tmp, L_shr( normq_fx[k], 3 ) ); /*11*/ + k = add( k, 1 ); } - test(); - test(); - IF( ( c_switching_flag ) || ( ( st_fx->last_core == ACELP_CORE ) && ( EQ_16( st_fx->core, HQ_CORE ) ) ) ) + tmp_fx = shl_o( inv_tbl_fx[Num_bands_p[i]], 1, &Overflow ); /*16*/ + norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/ + move32(); + tmp_energy_fx = L_add( tmp_energy_fx, L_shr( L_tmp, 3 ) ); /*8*/ + } + test(); + test(); + IF( ( c_switching_flag ) || ( ( st_fx->last_core == ACELP_CORE ) && ( EQ_16( st_fx->core, HQ_CORE ) ) ) ) + { + FOR( i = 0; i < MAX_SB_NB; i++ ) { - FOR( i = 0; i < MAX_SB_NB; i++ ) + FOR( j = 1; j < MAX_PGF; j++ ) { - FOR( j = 1; j < MAX_PGF; j++ ) - { - hHQ_nbfec->ynrm_values_fx[i][j] = hHQ_nbfec->ynrm_values_fx[i][0]; - move32(); - } + hHQ_nbfec->ynrm_values_fx[i][j] = hHQ_nbfec->ynrm_values_fx[i][0]; + move32(); } } - set16_fx( hHQ_nbfec->Norm_gain_fx, 32767, SFM_N_NB ); /*15*/ - /* st->energy_MA_Curr[1]=Energy of the current frame */ - tmp_fx = inv_tbl_fx[nb_sfm]; - move16(); /*15*/ - L_tmp = Mult_32_16( tmp_energy_fx, tmp_fx ); /*8 + 15 - 15*/ + } + set16_fx( hHQ_nbfec->Norm_gain_fx, 32767, SFM_N_NB ); /*15*/ + /* st->energy_MA_Curr[1]=Energy of the current frame */ + tmp_fx = inv_tbl_fx[nb_sfm]; + move16(); /*15*/ + L_tmp = Mult_32_16( tmp_energy_fx, tmp_fx ); /*8 + 15 - 15*/ - hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h( L_shl_sat( L_tmp, 16 - 8 ) ); - move16(); - /* Moving Average */ - hHQ_nbfec->energy_MA_Curr_fx[0] = s_max( 1, add( mult_r( 26214, hHQ_nbfec->energy_MA_Curr_fx[0] ), mult_r( 6554, hHQ_nbfec->energy_MA_Curr_fx[1] ) ) ); - move16(); + hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h( L_shl_sat( L_tmp, 16 - 8 ) ); + move16(); + /* Moving Average */ + hHQ_nbfec->energy_MA_Curr_fx[0] = s_max( 1, add( mult_r( 26214, hHQ_nbfec->energy_MA_Curr_fx[0] ), mult_r( 6554, hHQ_nbfec->energy_MA_Curr_fx[1] ) ) ); + move16(); + + /*st->diff_energy = (float)fabs((st->energy_MA_Curr[1] - st->energy_MA_Curr[0])/st->energy_MA_Curr[0]); */ + hHQ_nbfec->diff_energy_fx = abs_s( sub( hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0] ) ); + move16(); + exp1 = sub( norm_l( hHQ_nbfec->diff_energy_fx ), 1 ); + exp2 = norm_l( hHQ_nbfec->energy_MA_Curr_fx[0] ); + hHQ_nbfec->diff_energy_fx = div_s( extract_h( L_shl( hHQ_nbfec->diff_energy_fx, exp1 ) ), extract_h( L_shl( hHQ_nbfec->energy_MA_Curr_fx[0], exp2 ) ) ); + move16(); + exp = add( 15, sub( exp1, exp2 ) ); + hHQ_nbfec->diff_energy_fx = shl( hHQ_nbfec->diff_energy_fx, sub( 11, exp ) ); /*11*/ + move16(); - /*st->diff_energy = (float)fabs((st->energy_MA_Curr[1] - st->energy_MA_Curr[0])/st->energy_MA_Curr[0]); */ - hHQ_nbfec->diff_energy_fx = abs_s( sub( hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0] ) ); + /* Classify the stationary mode : 12% */ + IF( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_12P_fx ) ) + { + stat_mode_curr = 1; move16(); - exp1 = sub( norm_l( hHQ_nbfec->diff_energy_fx ), 1 ); - exp2 = norm_l( hHQ_nbfec->energy_MA_Curr_fx[0] ); - hHQ_nbfec->diff_energy_fx = div_s( extract_h( L_shl( hHQ_nbfec->diff_energy_fx, exp1 ) ), extract_h( L_shl( hHQ_nbfec->energy_MA_Curr_fx[0], exp2 ) ) ); + } + ELSE + { + stat_mode_curr = 0; move16(); - exp = add( 15, sub( exp1, exp2 ) ); - hHQ_nbfec->diff_energy_fx = shl( hHQ_nbfec->diff_energy_fx, sub( 11, exp ) ); /*11*/ + } + + /* Apply Hysteresis to prevent frequent mode changing */ + if ( EQ_16( hHQ_nbfec->stat_mode_old, stat_mode_curr ) ) + { + hHQ_nbfec->stat_mode_out = stat_mode_curr; move16(); + } - /* Classify the stationary mode : 12% */ - IF( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_12P_fx ) ) - { - stat_mode_curr = 1; - move16(); - } - ELSE - { - stat_mode_curr = 0; - move16(); - } + hHQ_nbfec->stat_mode_old = stat_mode_curr; + move16(); - /* Apply Hysteresis to prevent frequent mode changing */ - if ( EQ_16( hHQ_nbfec->stat_mode_old, stat_mode_curr ) ) + /* Find max. band index (Minimum value means maximum energy) */ + Min_ind = 0; + move16(); + Min_value = L_deposit_l( 100 ); + FOR( i = 0; i < num_Sb; i++ ) + { + IF( GT_32( Min_value, ynrm[i] ) ) { - hHQ_nbfec->stat_mode_out = stat_mode_curr; + Min_value = ynrm[i]; + move16(); + Min_ind = i; move16(); } + } - hHQ_nbfec->stat_mode_old = stat_mode_curr; - move16(); - - /* Find max. band index (Minimum value means maximum energy) */ - Min_ind = 0; - move16(); - Min_value = L_deposit_l( 100 ); - FOR( i = 0; i < num_Sb; i++ ) + /* Find max. coeff in band 0 */ + Max_ind = 0; + move16(); + IF( Min_ind == 0 ) + { + Max_coeff_fx = L_deposit_l( 0 ); + FOR( i = 0; i < 8; i++ ) { - IF( GT_32( Min_value, ynrm[i] ) ) + L_tmp = L_abs( t_audio_q_fx[i] ); + IF( LT_32( Max_coeff_fx, L_tmp ) ) { - Min_value = ynrm[i]; - move16(); - Min_ind = i; + Max_coeff_fx = L_add( L_tmp, 0 ); + Max_ind = i; move16(); } } + } - /* Find max. coeff in band 0 */ - Max_ind = 0; - move16(); - IF( Min_ind == 0 ) - { - Max_coeff_fx = L_deposit_l( 0 ); - FOR( i = 0; i < 8; i++ ) - { - L_tmp = L_abs( t_audio_q_fx[i] ); - IF( LT_32( Max_coeff_fx, L_tmp ) ) - { - Max_coeff_fx = L_add( L_tmp, 0 ); - Max_ind = i; - move16(); - } - } - } + /* Find energy difference from band 16 */ + k = 1; + move16(); - /* Find energy difference from band 16 */ - k = 1; + FOR( i = k; i < num_Sb; i++ ) + { + en_high_fx[i] = L_deposit_l( 0 ); move16(); - - FOR( i = k; i < num_Sb; i++ ) + FOR( j = 0; j < 2; j++ ) { - en_high_fx[i] = L_deposit_l( 0 ); - move16(); - FOR( j = 0; j < 2; j++ ) - { - /*en_high[i] += 0.5f*st->ynrm_values[i][j+1];*/ - en_high_fx[i] = L_add( en_high_fx[i], L_shr( hHQ_nbfec->ynrm_values_fx[i][j + 1], 1 ) ); /*Q12*/ - move32(); - } + /*en_high[i] += 0.5f*st->ynrm_values[i][j+1];*/ + en_high_fx[i] = L_add( en_high_fx[i], L_shr( hHQ_nbfec->ynrm_values_fx[i][j + 1], 1 ) ); /*Q12*/ + move32(); } + } - *mean_en_high_fx = 0; - move16(); - FOR( i = k; i < num_Sb; i++ ) - { - /* *mean_en_high += (float)(en_high[i]/st->ynrm_values[i][0]);*/ - exp1 = sub( norm_l( en_high_fx[i] ), 1 ); - exp2 = norm_l( hHQ_nbfec->ynrm_values_fx[i][0] ); - tmp_fx = div_s( extract_h( L_shl( en_high_fx[i], exp1 ) ), extract_h( L_shl( hHQ_nbfec->ynrm_values_fx[i][0], exp2 ) ) ); - exp = add( 15, sub( exp1, exp2 ) ); - *mean_en_high_fx = add_o( *mean_en_high_fx, shr_o( tmp_fx, sub( exp, 5 ), &Overflow ), &Overflow ); - move16(); - } - *mean_en_high_fx = mult( *mean_en_high_fx, inv_tbl_fx[sub( num_Sb, k )] ); + *mean_en_high_fx = 0; + move16(); + FOR( i = k; i < num_Sb; i++ ) + { + /* *mean_en_high += (float)(en_high[i]/st->ynrm_values[i][0]);*/ + exp1 = sub( norm_l( en_high_fx[i] ), 1 ); + exp2 = norm_l( hHQ_nbfec->ynrm_values_fx[i][0] ); + tmp_fx = div_s( extract_h( L_shl( en_high_fx[i], exp1 ) ), extract_h( L_shl( hHQ_nbfec->ynrm_values_fx[i][0], exp2 ) ) ); + exp = add( 15, sub( exp1, exp2 ) ); + *mean_en_high_fx = add_o( *mean_en_high_fx, shr_o( tmp_fx, sub( exp, 5 ), &Overflow ), &Overflow ); move16(); + } + *mean_en_high_fx = mult( *mean_en_high_fx, inv_tbl_fx[sub( num_Sb, k )] ); + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( LT_16( Min_ind, 5 ) ) && ( LT_16( abs_s( sub( Min_ind, hHQ_nbfec->old_Min_ind ) ), 2 ) ) && ( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_90P_fx ) ) && ( !st_fx->bfi ) && ( !st_fx->prev_bfi ) && ( !st_fx->prev_old_bfi ) && ( !is_transient ) && ( !hHQ_core->old_is_transient[1] ) && EQ_16( hHQ_nbfec->prev_last_core, HQ_CORE ) && EQ_16( st_fx->last_core, HQ_CORE ) ) + { + hHQ_nbfec->phase_mat_flag = 1; + move16(); test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( LT_16( Min_ind, 5 ) ) && ( LT_16( abs_s( sub( Min_ind, hHQ_nbfec->old_Min_ind ) ), 2 ) ) && ( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_90P_fx ) ) && ( !st_fx->bfi ) && ( !st_fx->prev_bfi ) && ( !st_fx->prev_old_bfi ) && ( !is_transient ) && ( !hHQ_core->old_is_transient[1] ) && EQ_16( hHQ_nbfec->prev_last_core, HQ_CORE ) && EQ_16( st_fx->last_core, HQ_CORE ) ) - { - hHQ_nbfec->phase_mat_flag = 1; - move16(); - test(); - if ( Min_ind == 0 && ( LT_16( Max_ind, 3 ) ) ) - { - hHQ_nbfec->phase_mat_flag = 0; - move16(); - } - } - ELSE + if ( Min_ind == 0 && ( LT_16( Max_ind, 3 ) ) ) { hHQ_nbfec->phase_mat_flag = 0; move16(); } - - hHQ_nbfec->old_Min_ind = Min_ind; + } + ELSE + { + hHQ_nbfec->phase_mat_flag = 0; move16(); } + hHQ_nbfec->old_Min_ind = Min_ind; + move16(); + + FOR( i = 0; i < L_FRAME8k; i++ ) { hHQ_nbfec->old_coeffs_fx[i] = t_audio_q_fx[i]; move32(); } - - hHQ_core->old_is_transient[2] = hHQ_core->old_is_transient[1]; - move16(); - hHQ_core->old_is_transient[1] = hHQ_core->old_is_transient[0]; - move16(); - hHQ_core->old_is_transient[0] = is_transient; - move16(); -#ifdef ADD_IVAS_HQ_CODE_FEC } -#endif + + hHQ_core->old_is_transient[2] = hHQ_core->old_is_transient[1]; + move16(); + hHQ_core->old_is_transient[1] = hHQ_core->old_is_transient[0]; + move16(); + hHQ_core->old_is_transient[0] = is_transient; + move16(); + return; } -- GitLab From fd36d42e8e350de67c728f270289f0d2f6599be2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 10:13:00 +0530 Subject: [PATCH 0399/1221] Fix for 3GPP issue 1140: Missing conversion of some flt. pt. functions in the BASOP code Link #1140 --- lib_dec/dec_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 191065855..00f372154 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3807,7 +3807,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 + *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } -- GitLab From 8fb270faafd8c23f732c12345f308bf57e478807 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 14:58:16 +0530 Subject: [PATCH 0400/1221] Fix for LTV crash issue Fix for LTV crash : 4 ISM with metadata at 48 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL ROOM IR out, random FER at 5% --- lib_dec/dec_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 00f372154..191065855 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3807,7 +3807,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 + *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } -- GitLab From 3e71800d6b502833d646d3214ebfe8a1a66efa39 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 09:48:48 +0530 Subject: [PATCH 0401/1221] Fix for 3GPP issue 1037: Wrong variable type used in the fixed-point code - 1 Link #1037 --- lib_com/cng_exc_fx.c | 2 +- lib_com/cnst.h | 6 +- lib_com/common_api_types.h | 50 +- lib_com/fft_evs.c | 2 +- lib_com/ivas_cnst.h | 10 +- lib_com/ivas_rom_com_fx.c | 24 +- lib_com/ivas_spar_com_fx.c | 8 +- lib_com/ivas_stat_com.h | 250 +++---- lib_com/ivas_tools_fx.c | 6 +- lib_com/longarith.c | 44 +- lib_com/lsf_dec_bfi_fx.c | 2 +- lib_com/mslvq_com.c | 6 +- lib_com/parameter_bitmaping_fx.c | 26 +- lib_com/prot_fx.h | 6 +- lib_com/rom_basop_util.c | 2 +- lib_com/rom_com.h | 2 +- lib_com/stat_com.h | 13 +- lib_dec/FEC_clas_estim_fx.c | 2 +- lib_dec/acelp_core_switch_dec_fx.c | 1 - lib_dec/core_switching_dec_fx.c | 2 +- lib_dec/dec_uv_fx.c | 22 +- lib_dec/er_dec_acelp_fx.c | 2 +- lib_dec/ivas_binRenderer_internal_fx.c | 4 +- lib_dec/ivas_dirac_dec_fx.c | 2 +- lib_dec/ivas_ism_param_dec_fx.c | 6 +- lib_dec/ivas_jbm_dec_fx.c | 26 +- lib_dec/ivas_mc_param_dec_fx.c | 10 +- lib_dec/ivas_rom_dec.c | 44 +- lib_dec/ivas_rom_dec.h | 16 +- lib_dec/ivas_spar_md_dec_fx.c | 10 +- lib_dec/ivas_stat_dec.h | 524 +++++++-------- lib_dec/ivas_stereo_switching_dec_fx.c | 8 +- lib_dec/ivas_svd_dec_fx.c | 1 - lib_dec/jbm_jb4sb.h | 2 +- lib_dec/jbm_pcmdsp_apa.h | 8 +- lib_dec/jbm_pcmdsp_window.h | 2 +- lib_enc/amr_wb_enc_fx.c | 2 +- lib_enc/avq_cod_fx.c | 12 +- lib_enc/core_enc_init_fx.c | 8 +- lib_enc/core_enc_reconf_fx.c | 2 +- lib_enc/enc_acelp_fx.c | 4 +- lib_enc/ivas_ism_metadata_enc_fx.c | 2 +- lib_enc/ivas_mcmasa_enc_fx.c | 2 +- lib_enc/ivas_mct_enc_fx.c | 2 +- lib_enc/ivas_mdct_core_enc_fx.c | 2 +- lib_enc/ivas_qmetadata_enc_fx.c | 6 +- lib_enc/ivas_sns_enc_fx.c | 10 +- lib_enc/ivas_spar_md_enc_fx.c | 2 +- lib_enc/ivas_stereo_dft_enc_fx.c | 6 +- lib_enc/ivas_stereo_td_enc_fx.c | 3 +- lib_enc/lib_enc.c | 64 +- lib_enc/lib_enc.h | 64 +- lib_enc/lsf_enc_fx.c | 4 +- lib_enc/lsf_msvq_ma_enc.c | 2 +- lib_enc/prot_fx_enc.h | 24 +- lib_enc/stat_enc.h | 624 +++++++++--------- lib_enc/swb_bwe_enc_fx.c | 2 +- lib_enc/swb_pre_proc_fx.c | 2 +- lib_enc/tcx_utils_enc_fx.c | 6 +- lib_enc/transient_detection_fx.c | 6 +- .../ivas_dirac_dec_binaural_functions_fx.c | 22 +- lib_rend/ivas_dirac_decorr_dec_fx.c | 4 +- lib_rend/ivas_reverb_fx.c | 32 +- lib_rend/ivas_rom_binaural_crend_head.h | 180 ++--- lib_rend/ivas_rom_binaural_crend_head_fx.c | 180 ++--- lib_rend/ivas_rom_rend_fx.c | 20 +- lib_rend/lib_rend.h | 2 +- 67 files changed, 1215 insertions(+), 1237 deletions(-) diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index 3eab0b1f5..4153afa32 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -47,7 +47,7 @@ void CNG_exc_fx( Word16 *cng_ener_seed1, Word16 exc3[], /*Q_exc*/ Word16 Opt_AMR_WB, - const int16_t element_mode /* i : IVAS Element mode */ + const Word16 element_mode /* i : IVAS Element mode */ ) { Word16 i, tmp, tmp2, exp, exp2, Q_ener; diff --git a/lib_com/cnst.h b/lib_com/cnst.h index bc2ae8403..4e14b310d 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -239,7 +239,7 @@ enum{ #define L_FRAME48k_EXT 1200 /* Extended MDCT frame size in samples at 48kHz */ /* Conversion of ns to samples for a given sampling frequency */ -#define NS2SA( fs, x ) ( int16_t )( ( ( ( int32_t )( fs ) / 100L ) * ( ( x ) / 100L ) ) / 100000L ) +#define NS2SA( fs, x ) ( Word16 )( ( ( ( Word32 )( fs ) / 100L ) * ( ( x ) / 100L ) ) / 100000L ) #define NRG_CHANGE_E 8 #define AVG_FLAT_E 8 #define ACTIVE_FRAME 0xFF @@ -1175,7 +1175,6 @@ enum #define NBITS_NOISE_FILL_LEVEL 3 /* Number of bits used for coding noise filling level for each range */ #define NF_GAIN_BITS ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ) #define MIN_NOISE_FILLING_HOLE 8 -#define HOLE_SIZE_FROM_LTP_FLT( gain ) ( 4 + ( int16_t )( 2.0f * gain * ( 4.0f / 0.625f ) ) ) #define HOLE_SIZE_FROM_LTP( gain ) (add(4, extract_h(L_shr(L_mult0(gain, 0x6666), 10)))) /* gain (Q15), 0x6666 = 2.0*(4.0/0.625) (4Q11) */ #define HOLE_SIZE_FROM_LTP32( gain ) (add(4, extract_h(L_shr(Mpy_32_32(gain, 0x66666667), 11)))) /* gain (Q31), 0x66666667 = 2.0*(4.0/0.625) (4Q27) */ @@ -1472,7 +1471,7 @@ enum #define cbitsnew 16 #define stat_bitsnew 14 -#define ari_q4new ( ( (int32_t) 1 << cbitsnew ) - 1 ) +#define ari_q4new ( ( (Word32) 1 << cbitsnew ) - 1 ) #define ari_q1new ( ari_q4new / 4 + 1 ) #define ari_q2new ( 2 * ari_q1new ) #define ari_q3new ( 3 * ari_q1new ) @@ -1954,7 +1953,6 @@ typedef enum _DCTTYPE #define N_SMC_MIXTURES 6 /* number of mixtures */ #define N_PCA_COEF 12 /* number of PCA components */ #define HALF_N_PCA_COEF_LOG_P12_Q18 2890731 //Q18 of (0.5f * N_PCA_COEF *logf( PI2 )) -#define SMC_ST_MEAN_FACT 0.5 /* forgetting factor of short-term IIR mean filter */ #define SMC_ST_MEAN_RSHIFT_FACT_FX 1 /* SMC_ST_MEAN_FACT equivalent right shift factor */ #define M_LSP_SPMUS 6 /* number of LSPs used in speech/music classifier */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 553a34f56..bc6fd4f1a 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -108,9 +108,9 @@ typedef enum _IVAS_ENC_FEC_INDICATOR typedef struct _IVAS_ENC_CHANNEL_AWARE_CONFIG { - int16_t channelAwareModeEnabled; + Word16 channelAwareModeEnabled; IVAS_ENC_FEC_INDICATOR fec_indicator; - int16_t fec_offset; + Word16 fec_offset; } IVAS_ENC_CHANNEL_AWARE_CONFIG; @@ -130,7 +130,7 @@ typedef struct _IVAS_ISM_METADATA float gainFactor; float yaw; float pitch; - int16_t non_diegetic_flag; + Word16 non_diegetic_flag; } IVAS_ISM_METADATA; @@ -183,29 +183,29 @@ typedef struct ivas_LS_setup_custom IVAS_LSSETUP_CUSTOM_STRUCT; typedef struct _IVAS_LS_CUSTOM_LAYOUT { - int16_t num_spk; + Word16 num_spk; float azimuth[IVAS_MAX_OUTPUT_CHANNELS]; float elevation[IVAS_MAX_OUTPUT_CHANNELS]; Word32 azimuth_fx[IVAS_MAX_OUTPUT_CHANNELS]; // Q22 Word32 elevation_fx[IVAS_MAX_OUTPUT_CHANNELS]; // Q22 - int16_t num_lfe; - int16_t lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; + Word16 num_lfe; + Word16 lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; } IVAS_CUSTOM_LS_DATA; typedef struct _IVAS_JBM_TRACE_DATA { - uint32_t systemTimestamp_ms; - uint16_t extBufferedSamples; - uint16_t lastDecodedWasActive; - int32_t output_Fs; - int16_t dataUnit_flag; - uint16_t sequenceNumber; - uint32_t timeStamp; - uint32_t rcvTime; - - int16_t partial_frame; - int16_t partialCopyOffset; + UWord32 systemTimestamp_ms; + UWord16 extBufferedSamples; + UWord16 lastDecodedWasActive; + Word32 output_Fs; + Word16 dataUnit_flag; + UWord16 sequenceNumber; + UWord32 timeStamp; + UWord32 rcvTime; + + Word16 partial_frame; + Word16 partialCopyOffset; } IVAS_JBM_TRACE_DATA; @@ -217,8 +217,8 @@ typedef struct _IVAS_JBM_TRACE_DATA typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { - int16_t override; - int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ + Word16 override; + Word16 nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ float pAcoustic_rt60[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ float pAcoustic_dsr[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's Diffuse to Source Ratio per center frequency */ @@ -231,12 +231,12 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG Word32 inputPreDelay_fx; /* Offset in seconds from where DSR is computed in the RIR (0 = at source), float, range [0.001..10] */ /* Assumed Q-27*/ /* early reflections */ - int16_t use_er; /* ER activation flag */ - int32_t lowComplexity; /* Low complexity ER flag */ - IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ - float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ - IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ - int32_t AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ + Word16 use_er; /* ER activation flag */ + Word32 lowComplexity; /* Low complexity ER flag */ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ + IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ + Word32 AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ } IVAS_ROOM_ACOUSTICS_CONFIG_DATA; diff --git a/lib_com/fft_evs.c b/lib_com/fft_evs.c index e53404f0b..94c2dea8f 100644 --- a/lib_com/fft_evs.c +++ b/lib_com/fft_evs.c @@ -505,7 +505,7 @@ static void fft15_with_cmplx_data( cmplx *inp_data /*Qx*/ ) */ void fft16( Word32 *re, Word32 *im, Word16 s, Word16 bScale ) { - int i; + Word16 i; if ( s == 2 ) { fft16_with_cmplx_data( (cmplx *) re, bScale ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 6612fac1f..2abb790f1 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1440,12 +1440,12 @@ typedef enum _COV_SMOOTHING_TYPE } COV_SMOOTHING_TYPE; typedef struct { - const int32_t *value; - const uint16_t *length; + const Word32 *value; + const UWord16 *length; } HUFF_TAB; typedef struct { - int32_t value[81]; + Word32 value[81]; unsigned short length[81]; } HUFF_ELEMENTS; @@ -1467,8 +1467,8 @@ typedef struct { typedef struct { - const int16_t (*alpha)[2]; - const int16_t (*beta)[2]; + const Word16 (*alpha)[2]; + const Word16 (*beta)[2]; } HUFF_NODE_TABLE; /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index 8ea2b91e4..a7a8bdcbf 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1617,23 +1617,23 @@ const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBAND }; /* Multi-channel input and output setups */ -const int16_t ls_azimuth_CICP2_idx[2] = { 1, 2 }; -const int16_t ls_elevation_CICP2_idx[2] = { 0, 0 }; +const Word16 ls_azimuth_CICP2_idx[2] = { 1, 2 }; +const Word16 ls_elevation_CICP2_idx[2] = { 0, 0 }; -const int16_t ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; -const int16_t ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; +const Word16 ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; +const Word16 ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; -const int16_t ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; -const int16_t ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; +const Word16 ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; +const Word16 ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; -const int16_t ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; -const int16_t ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; +const Word16 ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; +const Word16 ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; -const int16_t ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; -const int16_t ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; +const Word16 ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; +const Word16 ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; -const int16_t ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; -const int16_t ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; +const Word16 ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; +const Word16 ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; const Word32 shoebox_sin_cos_tbl_fx[11][2] = { { 0, 1073741824 }, // 0 { 536870912, 929887680 }, diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 6c80c1898..96df64aa5 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -3807,7 +3807,7 @@ void ivas_compute_spar_params_fx( { Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - Word16 b, i, ndm; + Word16 b, i, ndm, j; Word16 q_pred_coeffs; ivas_get_pred_coeffs_fx( cov_real, pred_coeffs_re, dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, dtx_vad, from_dirac, dyn_active_w_flag, hSparMd->res_ind, &q_pred_coeffs, q_dm_fv_re ); @@ -3869,7 +3869,7 @@ void ivas_compute_spar_params_fx( #ifdef MSAN_FIX FOR( i = 0; i < ( num_ch - ndm ); i++ ) { - FOR( Word16 j = 0; j < sub( ndm, 1 ); j++ ) + FOR( j = 0; j < sub( ndm, 1 ); j++ ) { hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j], sub( q_tmp, 22 ) ); // q22 move32(); @@ -3878,7 +3878,7 @@ void ivas_compute_spar_params_fx( #else for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) { - for ( int j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) + for ( j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) { hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j], sub( q_tmp, 22 ) ); } @@ -3891,7 +3891,7 @@ void ivas_compute_spar_params_fx( q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx; move16(); - FOR( Word16 j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ ) + FOR( j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ ) { hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j], sub( q_tmp, 22 ) ); // q22 move32(); diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 249d1e963..fb11d3934 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -46,18 +46,18 @@ typedef struct { - int16_t last_angle1_idx; /* last frame index of coded azimuth/yaw */ - int16_t angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ - int16_t last_angle2_idx; /* last frame index of coded elevation/pitch */ - int16_t angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ + Word16 last_angle1_idx; /* last frame index of coded azimuth/yaw */ + Word16 angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ + Word16 last_angle2_idx; /* last frame index of coded elevation/pitch */ + Word16 angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ } ISM_METADATA_ANGLE, *ISM_METADATA_ANGLE_HANDLE; /* ISM metadata handle (storage for one frame of read ISM metadata) */ typedef struct { - int16_t ism_metadata_flag; /* flag whether metadata are coded in particular frame of particular object */ - int16_t last_ism_metadata_flag; /* last frame ism_metadata_flag */ + Word16 ism_metadata_flag; /* flag whether metadata are coded in particular frame of particular object */ + Word16 last_ism_metadata_flag; /* last frame ism_metadata_flag */ Word32 azimuth_fx; /* azimuth value read from the input metadata file */ /* Q22 */ Word32 elevation_fx; /* elevation value read from the input metadata file */ /* Q22 */ @@ -65,25 +65,25 @@ typedef struct Word32 yaw_fx; /* yaw value read from the input metadata file */ /* Q22 */ Word32 pitch_fx; /* pitch value read from the input metadata file */ /* Q22 */ - int16_t non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ + Word16 non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ ISM_METADATA_ANGLE position_angle; /* Angle structs for azimuth and elevation */ ISM_METADATA_ANGLE orientation_angle; /* Angle structs for yaw and pitch */ - int16_t last_radius_idx; /* last frame index of coded radius */ - int16_t radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ + Word16 last_radius_idx; /* last frame index of coded radius */ + Word16 radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ Word32 last_azimuth_fx; /* MD smoothing in DTX- last Q azimuth value */ /* Q22 */ Word32 last_elevation_fx; /* MD smoothing in DTX - last Q elevation value */ /* Q22 */ Word32 last_true_azimuth_fx; /* MD smoothing in DTX- last true Q azimuth value */ /* Q22 */ Word32 last_true_elevation_fx; /* MD smoothing in DTX- last true Q elevation value */ /* Q22 */ - int16_t ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ - int16_t ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ - Word16 last_true_radius_fx; /* last true Q radius value */ + Word16 ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ + Word16 ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ + Word16 last_true_radius_fx; /* last true Q radius value */ - int16_t ism_imp; /* ISM importance flag */ - int16_t ism_md_null_flag; - int16_t ism_md_lowrate_flag; + Word16 ism_imp; /* ISM importance flag */ + Word16 ism_md_null_flag; + Word16 ism_md_lowrate_flag; Word32 q_azimuth_old_fx; Word32 q_elevation_old_fx; @@ -96,15 +96,15 @@ typedef struct typedef struct stereo_dft_config_data_struct { - int16_t dmx_active; - int16_t band_res; - int16_t prm_res; /* Send prm every # DFT frames */ - int16_t res_pred_mode; /* mode : from 0 (off) to 1 (on) */ - int16_t res_cod_mode; /* mode : from 0 (off) to 3 */ - int16_t hybrid_itd_flag; - int16_t ada_wb_res_cod_mode; /* res_cod_mode for adaptive wide band residual coding */ + Word16 dmx_active; + Word16 band_res; + Word16 prm_res; /* Send prm every # DFT frames */ + Word16 res_pred_mode; /* mode : from 0 (off) to 1 (on) */ + Word16 res_cod_mode; /* mode : from 0 (off) to 3 */ + Word16 hybrid_itd_flag; + Word16 ada_wb_res_cod_mode; /* res_cod_mode for adaptive wide band residual coding */ - int16_t force_mono_transmission; + Word16 force_mono_transmission; } STEREO_DFT_CONFIG_DATA, *STEREO_DFT_CONFIG_DATA_HANDLE; @@ -115,20 +115,20 @@ typedef struct stereo_dft_config_data_struct typedef struct { - uint8_t const bandLengthsTCX20[SMDCT_MAX_STEREO_BANDS_TCX20]; /* Length of a band in number of bins. Range is 4..160 */ - const int16_t bdnCnt_TCX20[4]; /* uppermost band for FB,SWB,WB,NB */ - uint8_t const bandLengthsTCX10[SMDCT_MAX_STEREO_BANDS_TCX10]; /* Length of a band in number of bins. Range is 2..80, always divisible by 2 */ - const int16_t bndCnt_TCX10[4]; /* uppermost band for FB,SWB,WB,NB */ + UWord8 const bandLengthsTCX20[SMDCT_MAX_STEREO_BANDS_TCX20]; /* Length of a band in number of bins. Range is 4..160 */ + const Word16 bdnCnt_TCX20[4]; /* uppermost band for FB,SWB,WB,NB */ + UWord8 const bandLengthsTCX10[SMDCT_MAX_STEREO_BANDS_TCX10]; /* Length of a band in number of bins. Range is 2..80, always divisible by 2 */ + const Word16 bndCnt_TCX10[4]; /* uppermost band for FB,SWB,WB,NB */ } MDCTStereoBands_config; /* MDCT stereo frequency band structure */ typedef struct stereo_mdct_dec_band_parameters_struct { - int16_t sfbOffset[MAX_SFB + 1]; /* stereo frequency band start offsets */ - int16_t sfbCnt; /* number of stereo frequency bands */ - int16_t nBandsStereoCore; /* number of stereo frequency bands in the core */ - int16_t sfbIgfStart; /*index for first IGF band*/ + Word16 sfbOffset[MAX_SFB + 1]; /* stereo frequency band start offsets */ + Word16 sfbCnt; /* number of stereo frequency bands */ + Word16 nBandsStereoCore; /* number of stereo frequency bands in the core */ + Word16 sfbIgfStart; /*index for first IGF band*/ } STEREO_MDCT_BAND_PARAMETERS; @@ -139,9 +139,9 @@ typedef struct stereo_mdct_dec_band_parameters_struct typedef struct { - int16_t config_index; - int16_t encoding_active; /* internal state specifying if actual encoding is active or only length evaluation is active */ - int32_t bit_count_estimate; /* uses 22Q10 fixed-point representation */ + Word16 config_index; + Word16 encoding_active; /* internal state specifying if actual encoding is active or only length evaluation is active */ + Word32 bit_count_estimate; /* uses 22Q10 fixed-point representation */ void *ac_handle; } ECSQ_instance; @@ -153,9 +153,9 @@ typedef struct typedef struct ivas_dirac_config_data_struct { - int16_t enc_param_start_band; - int16_t dec_param_estim; - int16_t nbands; + Word16 enc_param_start_band; + Word16 dec_param_estim; + Word16 nbands; } DIRAC_CONFIG_DATA, *DIRAC_CONFIG_DATA_HANDLE; @@ -180,9 +180,9 @@ typedef struct ivas_band_coeffs_t typedef struct ivas_band_coeffs_ind_t { - int16_t pred_index_re[IVAS_SPAR_MAX_CH - 1]; - int16_t drct_index_re[IVAS_SPAR_MAX_C_COEFF]; - int16_t decd_index_re[IVAS_SPAR_MAX_CH - 1]; + Word16 pred_index_re[IVAS_SPAR_MAX_CH - 1]; + Word16 drct_index_re[IVAS_SPAR_MAX_C_COEFF]; + Word16 decd_index_re[IVAS_SPAR_MAX_CH - 1]; } ivas_band_coeffs_ind_t; @@ -192,7 +192,7 @@ typedef struct ivas_spar_md_t ivas_band_coeffs_ind_t band_coeffs_idx[IVAS_MAX_NUM_BANDS]; Word16 num_bands; Word32 min_max_fx[2]; /*q28*/ - int16_t dtx_vad; + Word16 dtx_vad; Word32 en_ratio_slow_fx[IVAS_MAX_NUM_BANDS]; Word32 ref_pow_slow_fx[IVAS_MAX_NUM_BANDS]; Word16 res_ind; @@ -210,7 +210,7 @@ typedef struct ivas_quant_coeffs_t { Word32 min_fx; /* Q28 */ Word32 max_fx; /* Q28 */ - int16_t q_levels[2]; + Word16 q_levels[2]; } ivas_quant_coeffs_t; typedef struct ivas_quant_strat_t @@ -224,23 +224,23 @@ typedef struct ivas_quant_strat_t typedef struct ivas_spar_md_com_cfg { - int16_t max_freq_per_chan[IVAS_SPAR_MAX_CH]; - int16_t num_dmx_chans_per_band[IVAS_MAX_NUM_BANDS]; - int16_t num_decorr_per_band[IVAS_MAX_NUM_BANDS]; - int16_t active_w; - int16_t remix_unmix_order; + Word16 max_freq_per_chan[IVAS_SPAR_MAX_CH]; + Word16 num_dmx_chans_per_band[IVAS_MAX_NUM_BANDS]; + Word16 num_decorr_per_band[IVAS_MAX_NUM_BANDS]; + Word16 active_w; + Word16 remix_unmix_order; ivas_quant_strat_t quant_strat[MAX_QUANT_STRATS]; - int16_t quant_strat_bits; - int16_t nchan_transport; - int16_t num_quant_strats; - int16_t prior_strat; - int16_t tgt_bits_per_blk; - int16_t max_bits_per_blk; - int16_t prev_quant_idx; - int16_t agc_bits_ch_idx; - int16_t planarCP; - int16_t num_umx_chs; - int16_t max_md_bits_spar; + Word16 quant_strat_bits; + Word16 nchan_transport; + Word16 num_quant_strats; + Word16 prior_strat; + Word16 tgt_bits_per_blk; + Word16 max_bits_per_blk; + Word16 prev_quant_idx; + Word16 agc_bits_ch_idx; + Word16 planarCP; + Word16 num_umx_chs; + Word16 max_md_bits_spar; } ivas_spar_md_com_cfg; @@ -248,26 +248,26 @@ typedef struct ivas_spar_md_com_cfg /* arithmetic coder structures */ typedef struct ivas_cell_dim_t { - int16_t dim1; - int16_t dim2; + Word16 dim1; + Word16 dim2; } ivas_cell_dim_t; typedef struct ivas_freq_models_t { - int16_t freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t diff_freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t vals[IVAS_MAX_QUANT_LEVELS]; - int16_t diff_vals[IVAS_MAX_QUANT_LEVELS]; - int16_t num_models; - int16_t diff_num_models; + Word16 freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 diff_freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 vals[IVAS_MAX_QUANT_LEVELS]; + Word16 diff_vals[IVAS_MAX_QUANT_LEVELS]; + Word16 num_models; + Word16 diff_num_models; } ivas_freq_models_t; typedef struct ivas_huff_models_t { - int16_t code_book[IVAS_MAX_QUANT_LEVELS][3]; - int16_t diff_code_book[IVAS_MAX_QUANT_LEVELS][3]; + Word16 code_book[IVAS_MAX_QUANT_LEVELS][3]; + Word16 diff_code_book[IVAS_MAX_QUANT_LEVELS][3]; } ivas_huff_models_t; @@ -275,22 +275,22 @@ typedef struct ivas_huff_models_t /* Entropy coder structures */ typedef struct ivas_huffman_cfg_t { - const int16_t *codebook; - int16_t min_len; - int16_t max_len; - int16_t sym_len; + const Word16 *codebook; + Word16 min_len; + Word16 max_len; + Word16 sym_len; } ivas_huffman_cfg_t; typedef struct ivas_arith_t { - int16_t dyn_model_bits; - const int16_t *pFreq_model; - const int16_t *pAlt_freq_models[IVAS_NUM_PROB_MODELS]; - const int16_t *vals; - int16_t cum_freq[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t range; - int16_t num_models; + Word16 dyn_model_bits; + const Word16 *pFreq_model; + const Word16 *pAlt_freq_models[IVAS_NUM_PROB_MODELS]; + const Word16 *vals; + Word16 cum_freq[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 range; + Word16 num_models; Word32 saved_dist_arr[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; /* Q15 */ } ivas_arith_t; @@ -338,18 +338,18 @@ typedef struct ivas_cov_smooth_state_t Word32 *pPrior_cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_prior_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - int16_t prior_bank_idx; + Word16 prior_bank_idx; Word32 *pSmoothing_factor_fx; /* Q31 */ - int16_t num_bins; + Word16 num_bins; } ivas_cov_smooth_state_t; typedef struct ivas_cov_smooth_cfg_t { Word32 max_update_rate_fx; /* Q31 */ - int16_t min_pool_size; - int16_t max_bands; - int16_t num_bins; + Word16 min_pool_size; + Word16 max_bands; + Word16 num_bins; } ivas_cov_smooth_cfg_t; @@ -357,20 +357,20 @@ typedef struct ivas_cov_smooth_cfg_t /* SPAR bitrate constant table structure */ typedef struct ivas_spar_br_table_t { - int32_t ivas_total_brate; - int16_t isPlanar; - int16_t sba_order; - int16_t bwidth; - int16_t fpcs; - int16_t nchan_transport; + Word32 ivas_total_brate; + Word16 isPlanar; + Word16 sba_order; + Word16 bwidth; + Word16 fpcs; + Word16 nchan_transport; ivas_spar_pmx_strings_t dmx_str; - int16_t active_w; - int16_t tmode; - int32_t core_brs[FOA_CHANNELS][3]; - int16_t q_lvls[MAX_QUANT_STRATS][NUM_MD_Q_COEFS_SET]; - int16_t td_ducking; - int16_t agc_bits_ch_idx; /* 0-3, Indicates core-coder channel index from which AGC bits have been taken from*/ - int16_t usePlanarCoeff; + Word16 active_w; + Word16 tmode; + Word32 core_brs[FOA_CHANNELS][3]; + Word16 q_lvls[MAX_QUANT_STRATS][NUM_MD_Q_COEFS_SET]; + Word16 td_ducking; + Word16 agc_bits_ch_idx; /* 0-3, Indicates core-coder channel index from which AGC bits have been taken from*/ + Word16 usePlanarCoeff; } ivas_spar_br_table_t; @@ -419,7 +419,7 @@ typedef struct ivas_masa_common_spatial_meta_struct typedef struct ivas_omasa_meta_struct { - uint8_t num_dirs; + UWord8 num_dirs; MASA_DIRECTIONAL_SPATIAL_META directional_meta[MASA_MAXIMUM_DIRECTIONS]; MASA_COMMON_SPATIAL_META common_meta; @@ -435,16 +435,16 @@ typedef struct ivas_masa_metadata_frame_struct typedef struct ivas_masa_config_struct { - uint16_t max_metadata_bits; - int16_t block_grouping[5]; - int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; - uint8_t numCodingBands; - uint8_t numTwoDirBands; - uint8_t numberOfDirections; - uint8_t joinedSubframes; - uint8_t useCoherence; - uint8_t coherencePresent; - uint8_t mergeRatiosOverSubframes; + UWord16 max_metadata_bits; + Word16 block_grouping[5]; + Word16 band_grouping[MASA_FREQUENCY_BANDS + 1]; + UWord8 numCodingBands; + UWord8 numTwoDirBands; + UWord8 numberOfDirections; + UWord8 joinedSubframes; + UWord8 useCoherence; + UWord8 coherencePresent; + UWord8 mergeRatiosOverSubframes; IVAS_FORMAT input_ivas_format; } MASA_CODEC_CONFIG; @@ -456,11 +456,11 @@ typedef struct ivas_masa_config_struct typedef struct { - int16_t nbands; - int16_t nblocks; - int16_t start_band; - uint8_t inactiveBands; - int16_t search_effort; + Word16 nbands; + Word16 nblocks; + Word16 start_band; + UWord8 inactiveBands; + Word16 search_effort; MC_LS_SETUP mc_ls_setup; } IVAS_METADATA_CONFIG; @@ -615,10 +615,10 @@ typedef struct ivas_parametric_mc_metadata_struct typedef struct ivas_lfe_window { - int16_t dct_len; - int16_t fade_len; - int16_t zero_pad_len; - int16_t full_len; + Word16 dct_len; + Word16 fade_len; + Word16 zero_pad_len; + Word16 full_len; const Word32 *pWindow_coeffs_fx; @@ -626,14 +626,14 @@ typedef struct ivas_lfe_window typedef struct ivas_lfe_freq_models { - uint16_t entropy_coder_model_fine_sg1[65]; - uint16_t entropy_coder_model_fine_sg2[33]; - uint16_t entropy_coder_model_fine_sg3[9]; - uint16_t entropy_coder_model_fine_sg4[3]; - uint16_t entropy_coder_model_coarse_sg1[33]; - uint16_t entropy_coder_model_coarse_sg2[17]; - uint16_t entropy_coder_model_coarse_sg3[5]; - uint16_t entropy_coder_model_coarse_sg4; + UWord16 entropy_coder_model_fine_sg1[65]; + UWord16 entropy_coder_model_fine_sg2[33]; + UWord16 entropy_coder_model_fine_sg3[9]; + UWord16 entropy_coder_model_fine_sg4[3]; + UWord16 entropy_coder_model_coarse_sg1[33]; + UWord16 entropy_coder_model_coarse_sg2[17]; + UWord16 entropy_coder_model_coarse_sg3[5]; + UWord16 entropy_coder_model_coarse_sg4; } ivas_lfe_freq_models; diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index e460637f7..e15db9a15 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -2970,7 +2970,7 @@ Word64 var_32_fx( Word16 q /* q : q-factor for the array */ ) { - + Word16 i; Word64 mean, var; mean = 0; @@ -2978,14 +2978,14 @@ Word64 var_32_fx( var = 0; move64(); - FOR( int i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { mean = W_add( mean, x[i] ); /*q*/ } mean = mean / len; /* NOTE: No BASOP for 64 bit division q*/ - FOR( int i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { var = W_add( var, Mpy_32_32( L_sub( x[i], W_extract_l( mean ) ), L_sub( x[i], W_extract_l( mean ) ) ) ); /*q + q - 31*/ } diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 8946e41aa..72a763de3 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -52,27 +52,27 @@ *--------------------------------------------------------------------*/ void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ + UWord16 a[], /* i/o: vector of the length lena */ + const UWord16 b[], /* i/o: vector of the length lenb */ + const Word16 lena, /* i/o: length of vector a[] */ + const Word16 lenb /* i/o: length of vector b[] */ ) { - int16_t h; - int32_t carry = 0; + Word16 h; + Word32 carry = 0; assert( lena >= lenb ); for ( h = 0; h < lenb; h++ ) { carry += ( (uint32_t) a[h] ) + ( (uint32_t) b[h] ); - a[h] = (uint16_t) carry; + a[h] = (UWord16) carry; carry = carry >> 16; } for ( ; h < lena; h++ ) { carry = ( (uint32_t) a[h] ) + carry; - a[h] = (uint16_t) carry; + a[h] = (UWord16) carry; carry = carry >> 16; } @@ -91,14 +91,14 @@ void longadd( *--------------------------------------------------------------------*/ void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ + UWord16 a[], /* i : vector of the length lena */ + const Word16 b, /* i : number of bit positions to shift right */ + UWord16 d[], /* o : vector of the length lend */ + Word16 lena, /* i : length of vector a[] */ + const Word16 lend /* i : length of vector d[] */ ) { - int16_t intb, fracb, fracb_u, k; + Word16 intb, fracb, fracb_u, k; intb = b >> 4; @@ -164,16 +164,16 @@ void longshr( *--------------------------------------------------------------------*/ void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ + const UWord16 a[], /* i : vector of the length len */ + const Word16 b, /* i : number of bit positions to shift left */ + UWord16 d[], /* o : vector of the length len */ + const Word16 len /* i : length of vector a[] and d[] */ ) { - int16_t intb; /* integer part of b */ - int16_t fracb; /* shift left value for all upper words a[k] */ - int16_t fracb_l; /* shift right value for all lower words a[k-1] */ - int16_t k = len - 1; + Word16 intb; /* integer part of b */ + Word16 fracb; /* shift left value for all upper words a[k] */ + Word16 fracb_l; /* shift right value for all lower words a[k-1] */ + Word16 k = len - 1; intb = b >> 4; fracb = b & 0xF; diff --git a/lib_com/lsf_dec_bfi_fx.c b/lib_com/lsf_dec_bfi_fx.c index 6292630af..33de5d9ac 100644 --- a/lib_com/lsf_dec_bfi_fx.c +++ b/lib_com/lsf_dec_bfi_fx.c @@ -36,7 +36,7 @@ void lsf_dec_bfi( const Word16 Last_GSC_pit_band_idx, const Word16 Opt_AMR_WB, /* i : IO flag */ const Word8 tcxonly, - const short bwidth /* i: coded bandwidth */ + const Word16 bwidth /* i: coded bandwidth */ ) { Word16 i; diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index a15b11611..6bd8026c4 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -75,10 +75,10 @@ static void make_offset_scale( void create_offset( UWord32 *offset_scale1, UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ) + const Word16 mode, + const Word16 prediction_flag ) { - int16_t tmp, tmp1; + Word16 tmp, tmp1; if ( prediction_flag == 0 ) { diff --git a/lib_com/parameter_bitmaping_fx.c b/lib_com/parameter_bitmaping_fx.c index 180275d8f..0846c618b 100644 --- a/lib_com/parameter_bitmaping_fx.c +++ b/lib_com/parameter_bitmaping_fx.c @@ -58,15 +58,15 @@ static Word16 FixedWidthEncoding( Word16 value, Word16 index ) void GetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ) + Word16 **pStream, + Word16 *pnSize, + Word16 *pnBits ) { - int16_t index; - int16_t iParam, nParams; - int16_t value; + Word16 index; + Word16 iParam, nParams; + Word16 value; void const *pSubStruct; assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pParameter != NULL ) && ( pStream != NULL ) && ( pnSize != NULL ) && ( pnBits != NULL ) ); @@ -168,14 +168,14 @@ void GetParameters_fx( void SetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, void *pParameter, - const int16_t **pStream, - int16_t *pnSize ) + const Word16 **pStream, + Word16 *pnSize ) { - int16_t index; - int16_t iParam, nParams; - int16_t value; + Word16 index; + Word16 iParam, nParams; + Word16 value; void *pSubStruct; assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pParameter != NULL ) && ( pStream != NULL ) && ( pnSize != NULL ) ); diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9b596ca42..d0f0efb72 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -72,10 +72,6 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif -#ifndef TRUNC -#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) -#endif - #define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) #define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) @@ -11101,7 +11097,7 @@ void init_coder_ace_plus_ivas_fx( void core_coder_reconfig_ivas_fx( Encoder_State *st, - const int32_t last_total_brate ); + const Word32 last_total_brate ); void core_coder_mode_switch_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ diff --git a/lib_com/rom_basop_util.c b/lib_com/rom_basop_util.c index c3bfc6eef..eb79cc026 100644 --- a/lib_com/rom_basop_util.c +++ b/lib_com/rom_basop_util.c @@ -1449,7 +1449,7 @@ void BASOP_getTables( const PWord16 **ptwiddle /*Q15*/, const PWord16 **sin_twid ld2_length = sub( 16 - 1 - 1, norm_s( length ) ); /* Extract sort of "eigenvalue" (the 5 left most bits) of length. */ - SWITCH( (unsigned short) L_shl( length, sub( 15, ld2_length ) ) ) + SWITCH( (UWord16) L_shl( length, sub( 15, ld2_length ) ) ) { case 0xa000: /* 640 */ move16(); diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 274a33a18..33661fb58 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -66,7 +66,7 @@ typedef struct Word16 filt_len; /* number of filter coeff. */ Word16 filt_len_fx; /* number of filter coeff. Q0 */ - uint16_t flags; /* flags from config. table */ + UWord16 flags; /* flags from config. table */ UWord16 flags_fx; /* flags from config. table Q0 */ // UNS_Word16 flags_fx; /* flags from config. table Q0 */ diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 9edc28c03..c96dcc884 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -74,7 +74,7 @@ typedef struct typedef struct { Word16 lead_sign_ind; - uint32_t index, size; + UWord32 index, size; Word16 dim, k_val; } PvqEntry; @@ -313,7 +313,7 @@ typedef struct { Word32 low; Word32 high; - uint32_t value; + UWord32 value; Word32 bits_to_follow; } Tastat; typedef struct @@ -490,15 +490,6 @@ typedef Word16 ( *TEncodeValue )( Word16 value, Word16 index ); */ typedef Word16 ( *TDecodeValue )( struct Decoder_State *st, Word16 index, Word16 *pValue ); -/** Linear prediction analysis/synthesis filter definition. - * @param order filter order. - * @param parCoeff filter (PARCOR) coefficients. - * @param state state of the filter. Must be at least of 'order' size. - * @param x the current input value. - * @return the output of the filter. - */ -typedef float ( *TLinearPredictionFilter_flt )( const int16_t order, const float parCoeff[], float *state, float x ); - /** Structure that defines mapping between a parameter and a bitstream. */ typedef struct ParamBitMap { diff --git a/lib_dec/FEC_clas_estim_fx.c b/lib_dec/FEC_clas_estim_fx.c index 9b58084e3..e56a77be1 100644 --- a/lib_dec/FEC_clas_estim_fx.c +++ b/lib_dec/FEC_clas_estim_fx.c @@ -82,7 +82,7 @@ void FEC_clas_estim_fx( Word16 bfi, /* i : bad frame indicator */ /*B*/ Word32 last_core_brate, /* i : bitrate of previous frame */ - const int16_t FEC_mode /* i : ACELP FEC mode */ + const Word16 FEC_mode /* i : ACELP FEC mode */ ) { Word16 i, j, pos; diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index fc8aba043..b2cc593b3 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -847,7 +847,6 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ - // cldfbSynthesis_ivas_fx(realBuffer, imagBuffer, synth_out, (int16_t)(st_fx->output_Fs * 0.01f), st_fx->cldfbSyn); cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 17b3f9fbc..0f361e658 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1290,7 +1290,7 @@ ivas_error core_switching_post_dec_ivas_fx( FD_BWE_DEC_HANDLE hBWE_FD; HQ_DEC_HANDLE hHQ_core; ivas_error error; - int16_t offset; + Word16 offset; L_tmp = 0; move32(); diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index aa898956a..42f3250fb 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -114,17 +114,17 @@ void decod_unvoiced_fx( *-------------------------------------------------------------------*/ void decod_unvoiced_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 coder_type, /* Q0 i : coding type */ - Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ - Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ - Word16 *voice_factors_fx, /* Q15 o : voicing factors */ - Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ - Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ + const Word16 coder_type, /* Q0 i : coding type */ + Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ + Word16 *voice_factors_fx, /* Q15 o : voicing factors */ + Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ + Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ Word16 *gain_buf ) { Word16 gain_pit_fx; /* Quantized pitch gain */ diff --git a/lib_dec/er_dec_acelp_fx.c b/lib_dec/er_dec_acelp_fx.c index 7c3ecaa0a..e30553d38 100644 --- a/lib_dec/er_dec_acelp_fx.c +++ b/lib_dec/er_dec_acelp_fx.c @@ -446,7 +446,7 @@ void con_acelp_fx( ELSE { /* No harmonic part */ - assert( (int) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 ); + assert( (Word32) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 ); set16_fx( &exc[0], 0, add( st->L_frame, shr( st->L_frame, 1 ) ) ); FOR( i = 0; i < st->nb_subfr; i++ ) diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 3fe40c1f3..3c234c098 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -1484,7 +1484,7 @@ void ivas_binaural_add_LFE_fx( Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output Q11*/ ) { - Word16 render_lfe, idx_lfe, gain_fx; + Word16 render_lfe, idx_lfe, gain_fx, idx; IF( st_ivas->hBinRenderer != NULL ) { @@ -1523,7 +1523,7 @@ void ivas_binaural_add_LFE_fx( { v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); // q_input_fx - 1 /* copy LFE to left and right channels */ - FOR( int idx = 0; idx < output_frame; idx++ ) + FOR( idx = 0; idx < output_frame; idx++ ) { input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] = L_shl_sat( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx], 1 ); // saturating to keep same q move32(); diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 63ee40e2a..d0c78b604 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2216,7 +2216,7 @@ void ivas_dirac_dec_render_sf_fx( DIRAC_DEC_STACK_MEM DirAC_mem; Word32 *p_onset_filter_fx = NULL; - uint16_t coherence_flag; + UWord16 coherence_flag; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word16 scale = 0; move16(); diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 9040a8a71..eae0e9069 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1428,9 +1428,9 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( static void ivas_ism_param_dec_render_sf_fx( Decoder_Struct *st_ivas, IVAS_OUTPUT_SETUP hSetup, - const int16_t nchan_transport, - const int16_t nchan_out, - const int16_t nchan_out_woLFE, + const Word16 nchan_transport, + const Word16 nchan_out, + const Word16 nchan_out_woLFE, Word32 *output_f_fx[], /*Q_output*/ Word16 Q_output[] ) { diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index f632d86c8..428c817ef 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -83,7 +83,7 @@ ivas_error ivas_jbm_dec_tc_fx( Word32 *data_fx /*Q11*/ ) { - Word16 n, output_frame, nchan_out, i; + Word16 n, output_frame, nchan_out, i, ii; Decoder_State *st; /* used for bitstream handling */ Word32 *p_output_fx[MAX_TRANSPORT_CHANNELS]; /* buffer for output synthesis */ Word16 nchan_remapped; @@ -512,14 +512,14 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } #ifdef MSAN_FIX - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx } @@ -534,7 +534,7 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } #ifdef MSAN_FIX - FOR( int ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 } @@ -614,7 +614,7 @@ ivas_error ivas_jbm_dec_tc_fx( st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; move16(); - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -999,7 +999,7 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; @@ -1045,7 +1045,7 @@ ivas_error ivas_jbm_dec_tc_fx( move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -1464,7 +1464,7 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->q_output_mem_fx[ii] ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; @@ -1509,7 +1509,7 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( st_ivas->hSpar != NULL ) { - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -1787,7 +1787,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) { - ivas_mc_paramupmix_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + ivas_mc_paramupmix_dec_digest_tc( st_ivas, (UWord8) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { @@ -1882,7 +1882,7 @@ ivas_error ivas_jbm_dec_render_fx( ivas_error error; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; Word32 *p_tc_fx[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; - Word16 subframe_len, gd_bits, exp, nchan_in, i, j; + Word16 subframe_len, gd_bits, exp, nchan_in, i, j, ch; const Word16 output_q_factor = Q11; move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -2448,7 +2448,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); } /* CLDFB synthesis */ - FOR( Word16 ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { IF( st_ivas->cldfbSynDec[ch] ) { @@ -2476,7 +2476,7 @@ ivas_error ivas_jbm_dec_render_fx( ivas_param_mc_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, channel_active_fx ); - FOR( int ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { IF( st_ivas->cldfbSynDec[ch] ) { diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 897fd4433..be2363469 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -107,7 +107,7 @@ static ivas_error param_mc_get_diff_proto_info_fx( const Word32 *proto_mtx, cons static void param_mc_update_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, Word32 *mixing_matrix[], Word16 *mixing_matrix_fx, Word32 *mixing_matrix_res[], Word16 *mixing_matrix_res_exp, const UWord16 nX, const UWord16 nY ); -static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const int16_t num_freq_bands /*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); +static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const Word16 num_freq_bands /*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); /*------------------------------------------------------------------------- * ivas_param_mc_dec_open() @@ -1509,8 +1509,8 @@ void ivas_param_mc_dec_read_BS_fx( *------------------------------------------------------------------------*/ void ivas_param_mc_dec_digest_tc_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ Word32 *transport_channels_f_fx[], Word16 transport_f_e ) { @@ -2361,7 +2361,7 @@ static void param_mc_protoSignalComputation_fx( Word32 *ImagBuffer_fx, /* i : CLDFB samples of the transport channels (imaginary part) */ Word32 *proto_frame_f_fx, /* o : interleaved complex prototype CLDFB samples */ const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ - const int16_t num_freq_bands /* i : number of frequency bands for the prototypes */ + const Word16 num_freq_bands /* i : number of frequency bands for the prototypes */ ) { Word16 band; @@ -2680,7 +2680,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( Word16 nY_band; Word16 num_lfe_bands; Word16 brange[2]; - uint16_t i; + UWord16 i; Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; Word16 remove_lfe; Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 812d9957f..6f75230c9 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -100,7 +100,7 @@ const Word32 dft_ap_gains_fx[5][3] = { 644245094, -644245120, 1073741824 } }; -const int16_t dft_ap_delays[3][3] = +const Word16 dft_ap_delays[3][3] = { { 2, 47, 61}, {29, 41, 73}, @@ -196,7 +196,7 @@ const Word16 dft_win_8k_fx[70] = * stereo CNA tables *------------------------------------------------------------------------*/ -const int16_t cna_init_bands[CNA_INIT_NBANDS + 1] = +const Word16 cna_init_bands[CNA_INIT_NBANDS + 1] = { 1, 4, 14, 33, 67, 171, 320 }; @@ -235,7 +235,7 @@ const Word16 min_smooth_gains2_fx[SBA_DIRAC_STEREO_NUM_BANDS] = /* all the "probability" tables for the actual AC are in the reversed cumulative counts table format; for example, given the counts table [c0 | c1 | c2 | c3] with c0 + c1 + c2 + c3 = 2 ^ 14, the reversed cumulative counts table is [2 ^ 14 | 2 ^ 14 - c0 | 2 ^ 14 - c0 - c1 | 2 ^ 14 - c0 - c1 - c2 | 2 ^ 14 - c0 - c1 - c2 - c3] */ -const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = +const UWord16 cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = { {0,1024,2048,3072,4096,5120,6144,7168,8192,9216,10240,11264,12288,13312,14336,15360,16384 }, {0,9294,16019,16213,16311,16346,16363,16371,16375,16377,16378,16379,16380,16381,16382,16383,16384 }, @@ -246,7 +246,7 @@ const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] {0,5836,14448,15610,16267,16343,16374,16375,16376,16377,16378,16379,16380,16381,16382,16383,16384 } }; -const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = +const UWord16 sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = { {1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024 }, {9294,6725,194,98,35,17,8,4,2,1,1,1,1,1,1,1 }, @@ -257,7 +257,7 @@ const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = {5836,8612,1162,657,76,31,1,1,1,1,1,1,1,1,1,1 } }; -const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = +const UWord16 cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = { {0,6445,12725,15035,15885,16198,16313,16355,16370,16376,16378,16379,16380,16381,16382,16383,16384 }, {0,3624,8645,11690,13537,14657,15336,15748,15998,16150,16242,16298,16332,16352,16364,16372,16384 }, @@ -276,7 +276,7 @@ const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SI {0,3623,6446,8644,10356,11689,12727,13536,14166,14657,15039,15337,15569,15749,15890,15999,16384 }, }; -const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] = +const UWord16 sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] = { {6445,6280,2310,850,313,115,42,15,6,2,1,1,1,1,1,1 }, {3624,5021,3045,1847,1120,679,412,250,152,92,56,34,20,12,8,12 }, @@ -295,59 +295,59 @@ const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] {3623,2823,2198,1712,1333,1038,809,630,491,382,298,232,180,141,109,385 }, }; -const uint16_t cum_freq_ECSQ_tab_abs_1bit[1 + 2] = +const UWord16 cum_freq_ECSQ_tab_abs_1bit[1 + 2] = { 0, 5462, 16384 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -const uint16_t cum_freq_ECSQ_tab_abs_2bit[1 + 4] = +const UWord16 cum_freq_ECSQ_tab_abs_2bit[1 + 4] = { 0, 2338, 7020, 11702, 16384 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -const uint16_t cum_freq_ECSQ_tab_abs_3bit[1 + 8] = +const UWord16 cum_freq_ECSQ_tab_abs_3bit[1 + 8] = { 0, 1096, 3280, 5464, 7648, 9832, 12016, 14200, 16384 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -const uint16_t cum_freq_ECSQ_tab_abs_4bit[1 + 16] = +const UWord16 cum_freq_ECSQ_tab_abs_4bit[1 + 16] = { 0, 514, 1572, 2630, 3688, 4746, 5804, 6862, 7920, 8978, 10036, 11094, 12152, 13210, 14268, 15326, 16384 }; -const uint16_t sym_freq_ECSQ_tab_abs_1bit[2] = +const UWord16 sym_freq_ECSQ_tab_abs_1bit[2] = { 5462, 10922 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -const uint16_t sym_freq_ECSQ_tab_abs_2bit[4] = +const UWord16 sym_freq_ECSQ_tab_abs_2bit[4] = { 2338, 4682, 4682, 4682 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -const uint16_t sym_freq_ECSQ_tab_abs_3bit[8] = +const UWord16 sym_freq_ECSQ_tab_abs_3bit[8] = { 1096, 2184, 2184, 2184, 2184, 2184, 2184, 2184 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -const uint16_t sym_freq_ECSQ_tab_abs_4bit[16] = +const UWord16 sym_freq_ECSQ_tab_abs_4bit[16] = { 514, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058 }; /* array of tables for uniform coding of absolute values */ -const uint16_t * const cum_freq_ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const cum_freq_ECSQ_tab_abs_lsbs[1 + 4] = { NULL, cum_freq_ECSQ_tab_abs_1bit, cum_freq_ECSQ_tab_abs_2bit, cum_freq_ECSQ_tab_abs_3bit, cum_freq_ECSQ_tab_abs_4bit }; -const uint16_t * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = { NULL, sym_freq_ECSQ_tab_abs_1bit, sym_freq_ECSQ_tab_abs_2bit, sym_freq_ECSQ_tab_abs_3bit, sym_freq_ECSQ_tab_abs_4bit }; @@ -391,7 +391,7 @@ const Word32 dmxmtx_table_fx[BINAURAL_CHANNELS][11] = *-----------------------------------------------------------------------*/ /* Alpha Fine Huffman table df0 */ -static const int16_t huff_nodes_first_band_alpha[32][2] = +static const Word16 huff_nodes_first_band_alpha[32][2] = { { -17, 1 }, { 3, 2 }, @@ -428,7 +428,7 @@ static const int16_t huff_nodes_first_band_alpha[32][2] = }; /* Alpha Fine Huffman table df */ -static const int16_t huff_nodes_alpha_1D_DF[64][2] = +static const Word16 huff_nodes_alpha_1D_DF[64][2] = { { -33, 1 }, { 3, 2 }, @@ -497,7 +497,7 @@ static const int16_t huff_nodes_alpha_1D_DF[64][2] = }; /* Alpha Fine Huffman table dt */ -static const int16_t huff_nodes_alpha_1D_DT[64][2] = +static const Word16 huff_nodes_alpha_1D_DT[64][2] = { { -33, 1 }, { -34, 2 }, @@ -566,19 +566,19 @@ static const int16_t huff_nodes_alpha_1D_DT[64][2] = }; /* Beta Fine Huffman table df0 */ -static const int16_t huff_nodes_first_band_beta[8][2] = +static const Word16 huff_nodes_first_band_beta[8][2] = { { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, 4 }, { -5, 5 }, { -6, 6 }, { -7, 7 }, { -8, -9 } }; /* Beta Fine Huffman table df */ -static const int16_t huff_nodes_beta_1D_DF[16][2] = +static const Word16 huff_nodes_beta_1D_DF[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { 9, 8 }, { -5, -13 }, { 11, 10 }, { -4, -14 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; /* Beta Fine Huffman table dt */ -static const int16_t huff_nodes_beta_1D_DT[16][2] = +static const Word16 huff_nodes_beta_1D_DT[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { -13, 8 }, { -5, 9 }, { -14, 10 }, { -4, 11 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 11752380d..84c1a94a0 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -53,7 +53,7 @@ extern const Word16 dft_alpha_s2_b2_fx[STEREO_DFT_BAND_MAX]; extern const Word32 dft_bpf_weights_fx[]; extern const Word32 dft_ap_gains_fx[5][3]; -extern const int16_t dft_ap_delays[3][3]; +extern const Word16 dft_ap_delays[3][3]; extern const Word16 dft_win232ms_8k_fx[75]; extern const Word16 dft_win232ms_12k8_fx[120]; extern const Word16 dft_win232ms_16k_fx[150]; @@ -62,7 +62,7 @@ extern const Word16 dft_win232ms_48k_fx[450]; extern const Word16 dft_res_pred_weights_fx[][STEREO_DFT_BAND_MAX]; extern const Word16 dft_win_8k_fx[70]; -extern const int16_t cna_init_bands[CNA_INIT_NBANDS + 1]; +extern const Word16 cna_init_bands[CNA_INIT_NBANDS + 1]; extern const Word16 min_smooth_gains1_fx[SBA_DIRAC_STEREO_NUM_BANDS]; @@ -74,12 +74,12 @@ extern const Word16 max_smooth_gains2_fx[SBA_DIRAC_STEREO_NUM_BANDS]; * ECLVQ Stereo ROM tables *----------------------------------------------------------------------------------*/ -extern const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; -extern const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT]; -extern const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; -extern const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE]; -extern const uint16_t *const cum_freq_ECSQ_tab_abs_lsbs[1 + 4]; -extern const uint16_t *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; +extern const UWord16 sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT]; +extern const UWord16 cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; +extern const UWord16 sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE]; +extern const UWord16 *const cum_freq_ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; /*----------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index d1efbbd2c..bb79b956c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -49,11 +49,11 @@ #define IVAS_DEFAULT_DTX_CNG_RAMP ( 8 ) /* PLC constants */ -static const int16_t ivas_spar_dec_plc_num_frames_keep = 9; -// static const int16_t ivas_spar_dec_plc_num_frames_fade_out = 9; -static const int16_t ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; -static const int16_t ivas_spar_dec_plc_max_num_frames_ramp_down = 33; -static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; +static const Word16 ivas_spar_dec_plc_num_frames_keep = 9; +// static const Word16 ivas_spar_dec_plc_num_frames_fade_out = 9; +static const Word16 ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; +static const Word16 ivas_spar_dec_plc_max_num_frames_ramp_down = 33; +static const Word16 ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /*------------------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index b1522be36..5704f4f60 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -49,14 +49,14 @@ /* State of the range decoder */ typedef struct { - uint32_t rc_low; - uint32_t rc_range; + UWord32 rc_low; + UWord32 rc_range; - uint16_t *bit_buffer; - int16_t bit_count; - int16_t max_allowable_bit_count; + UWord16 *bit_buffer; + Word16 bit_count; + Word16 max_allowable_bit_count; - int16_t bit_error_detected; + Word16 bit_error_detected; } RangeUniDecState; @@ -78,11 +78,11 @@ typedef struct stereo_dft_dec_data_struct STEREO_DFT_CONFIG_DATA_HANDLE hConfig; /*Sizes*/ - int16_t N; /* Size of DFT hop size */ - int16_t NFFT; /* Size of DFT */ + Word16 N; /* Size of DFT hop size */ + Word16 NFFT; /* Size of DFT */ /*FFT*/ - int16_t dft_trigo_step; + Word16 dft_trigo_step; const Word16 *dft_trigo_fx; /* Q15 */ const Word16 *dft_trigo_12k8_fx; /* Q15 */ @@ -90,13 +90,13 @@ typedef struct stereo_dft_dec_data_struct const Word16 *dft_trigo_8k_fx; /* Q15 */ - int16_t dft32ms_ovl; /* Overlap size */ + Word16 dft32ms_ovl; /* Overlap size */ const Word16 *win32ms_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_12k8_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_16k_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_8k_fx; /* DFT window */ /* Q15 */ - int16_t dft32ms_ovl2; /* Overlap2 size */ + Word16 dft32ms_ovl2; /* Overlap2 size */ const Word16 *win232ms_fx; /* DFT window */ /* Q15 */ const Word16 *win232ms_12k8_fx; /* DFT window */ /* Q15 */ const Word16 *win232ms_16k_fx; /* DFT window */ /* Q15 */ @@ -105,31 +105,31 @@ typedef struct stereo_dft_dec_data_struct /*Bands*/ - int16_t band_res[STEREO_DFT_DEC_DFT_NB]; - int16_t band_limits[STEREO_DFT_BAND_MAX + 1]; - int16_t nbands; + Word16 band_res[STEREO_DFT_DEC_DFT_NB]; + Word16 band_limits[STEREO_DFT_BAND_MAX + 1]; + Word16 nbands; /*Configuration*/ - int16_t prm_res[STEREO_DFT_DEC_DFT_NB]; + Word16 prm_res[STEREO_DFT_DEC_DFT_NB]; /*Stereo parameters*/ Word32 side_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; /* Q31 */ - int16_t side_gain_flag_1; - int16_t side_gain_flag_2; - int16_t side_gain_index_previous[STEREO_DFT_BAND_MAX]; - int16_t side_gain_index[STEREO_DFT_BAND_MAX]; + Word16 side_gain_flag_1; + Word16 side_gain_flag_2; + Word16 side_gain_index_previous[STEREO_DFT_BAND_MAX]; + Word16 side_gain_index[STEREO_DFT_BAND_MAX]; Word32 gipd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q27 */ - int16_t no_ipd_flag; /* flag to indicate when no IPD gets used */ + Word16 no_ipd_flag; /* flag to indicate when no IPD gets used */ - int16_t itd_xfade_counter; - int32_t last_active_element_brate; - int16_t ipd_xfade_counter; + Word16 itd_xfade_counter; + Word32 last_active_element_brate; + Word16 ipd_xfade_counter; /*residual prediction*/ - int16_t res_pred_mode[STEREO_DFT_DEC_DFT_NB]; /* residual prediction mode: 0(off), 1(stereo filling only), 2(enhanced stereo filling) */ - Word32 itd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q15 */ + Word16 res_pred_mode[STEREO_DFT_DEC_DFT_NB]; /* residual prediction mode: 0(off), 1(stereo filling only), 2(enhanced stereo filling) */ + Word32 itd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q15 */ Word32 itd_xfade_step_fx; /* Q15 */ Word32 itd_xfade_target_fx; /* Q15 */ @@ -139,19 +139,19 @@ typedef struct stereo_dft_dec_data_struct Word32 ipd_xfade_step_fx; /* Q27 */ Word32 ipd_xfade_prev_fx; /* Q27 */ Word32 res_pred_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; /* prediction gain for the residual HFs */ /* Q31 */ - int16_t res_pred_band_min; /* Band min for prediction of residual */ - int16_t past_DMX_pos; - int16_t res_pred_flag_0; - int16_t res_pred_flag_1; - int16_t res_pred_index_previous[STEREO_DFT_BAND_MAX]; + Word16 res_pred_band_min; /* Band min for prediction of residual */ + Word16 past_DMX_pos; + Word16 res_pred_flag_0; + Word16 res_pred_flag_1; + Word16 res_pred_index_previous[STEREO_DFT_BAND_MAX]; - int16_t reverb_flag; - int16_t nbands_respred; + Word16 reverb_flag; + Word16 nbands_respred; /*residual coding*/ - int16_t res_cod_mode[STEREO_DFT_DEC_DFT_NB]; /* mode from 0 (off) to 3 */ - int16_t res_cod_band_max; /* Band max for coding of residual */ - int16_t res_cod_line_max; + Word16 res_cod_mode[STEREO_DFT_DEC_DFT_NB]; /* mode from 0 (off) to 3 */ + Word16 res_cod_band_max; /* Band max for coding of residual */ + Word16 res_cod_line_max; Word32 DFT_past_DMX_fx[STEREO_DFT_PAST_MAX][STEREO_DFT32MS_N_32k]; /* Past DMX for residual prediction */ /* Q(q_DFT_past_DMX_fx) */ Word32 past_res_pred_gain_fx[STEREO_DFT_PAST_MAX][STEREO_DFT_BAND_MAX]; /* Q31 */ Word32 res_gains_ind_fx[2][2 * STEREO_DFT_BAND_MAX]; /* Q26 */ @@ -171,9 +171,9 @@ typedef struct stereo_dft_dec_data_struct BPF_DEC_HANDLE hBpf; TCX_LTP_DEC_HANDLE hTcxLtpDec; - int16_t trans; - int16_t attackPresent; - int16_t wasTransient; + Word16 trans; + Word16 attackPresent; + Word16 wasTransient; basic_allpass_t ap1, ap2, ap3; @@ -188,9 +188,9 @@ typedef struct stereo_dft_dec_data_struct Word32 ap_fade_mem_fx[STEREO_DFT_ALLPASS_FADELEN_16k]; /* Q(q_ap_fade_mem_fx) */ Word16 q_ap_fade_mem_fx; - int16_t ap_wasTransient; - int16_t core_hist[STEREO_DFT_CORE_HIST_MAX]; - int16_t hb_stefi_delay; + Word16 ap_wasTransient; + Word16 core_hist[STEREO_DFT_CORE_HIST_MAX]; + Word16 hb_stefi_delay; Word32 smooth_dmx_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 smooth_res_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 td_gain_fx[STEREO_DFT_CORE_HIST_MAX]; /* Q(q_td_gain) */ @@ -206,16 +206,16 @@ typedef struct stereo_dft_dec_data_struct /* stereo DTX */ Word16 g_state_fx[STEREO_DFT_BAND_MAX]; /* Q15 */ - int16_t frame_sid_nodata; - int16_t frame_nodata; - int16_t frame_sid; + Word16 frame_sid_nodata; + Word16 frame_nodata; + Word16 frame_sid; Word16 scale_fx; /* Q15 */ /* PLC on residual signal */ - int16_t time_offs; - int16_t sg_mem_corrupt; - int16_t recovery_flg; + Word16 time_offs; + Word16 sg_mem_corrupt; + Word16 recovery_flg; /* PLC on residual signal */ Word32 sg_mean_fx; /* Q31 */ @@ -228,7 +228,7 @@ typedef struct stereo_dft_dec_data_struct Word16 q_hb_nrg_subr; Word16 q_res_mem; - int16_t first_frame; + Word16 first_frame; Word32 mixer_mat_smooth_fx[2][4][2 * IVAS_MAX_NUM_BANDS]; /* Q31 */ Word32 g_L_prev_fx; /* Q31 */ Word32 g_R_prev_fx; /* Q31 */ @@ -257,26 +257,26 @@ typedef struct stereo_dec_cng { Word16 cm_fx[STEREO_DFT_BAND_MAX]; /* cm */ /* Q15 */ Word16 coh_fx[STEREO_DFT_BAND_MAX + 1]; /* coherence */ /* Q15 */ - int16_t first_SID; /* first SID indicator */ - int16_t first_SID_after_TD; /* first SID after TD-stereo indicator */ - int16_t prev_sid_nodata; /* previous frame SID/FRAME_NO_DATA indicator */ - int16_t last_tdm_idx; /* last tdm index */ + Word16 first_SID; /* first SID indicator */ + Word16 first_SID_after_TD; /* first SID after TD-stereo indicator */ + Word16 prev_sid_nodata; /* previous frame SID/FRAME_NO_DATA indicator */ + Word16 last_tdm_idx; /* last tdm index */ Word32 c_LR_LT_fx; /* left right cross correlation */ /* Q31 */ - int16_t active_frame_counter; /* counter for active frames */ - int16_t xfade_frame_counter; /* xfade counter */ - int16_t xfade_length; /* number of frames to perform xfade */ - int16_t nr_dft_frames; /* dft frame counter */ - int16_t nr_corr_frames; /* correlation frame counter */ - int16_t nr_sid_frames; /* SID frame counter */ - int16_t last_act_element_mode; /* Element mode of last active frame */ + Word16 active_frame_counter; /* counter for active frames */ + Word16 xfade_frame_counter; /* xfade counter */ + Word16 xfade_length; /* number of frames to perform xfade */ + Word16 nr_dft_frames; /* dft frame counter */ + Word16 nr_corr_frames; /* correlation frame counter */ + Word16 nr_sid_frames; /* SID frame counter */ + Word16 last_act_element_mode; /* Element mode of last active frame */ Word16 olapBufferSynth22_fx[FFTLEN]; /* overlap buffer for secondary channel CNA */ Word32 olapBufferSynth22_32fx[FFTLEN]; /* overlap buffer for secondary channel CNA */ - int16_t flag_cna_fade; /* flag enabling CNA fade out */ + Word16 flag_cna_fade; /* flag enabling CNA fade out */ Word16 maskingNoiseS_fx[L_FRAME16k]; /* masking noise (CNA) for secondary channel */ - int16_t enableSecCNA; /* flag enabling secondary channel CNA */ + Word16 enableSecCNA; /* flag enabling secondary channel CNA */ Word16 c_PS_LT_fx; /* long term cross-correlation between primary and secondary channel */ // Assumed Q15 for initialization. Can be modified later if reqd. - const int16_t *frameSize; /* Frame size in samples */ - const int16_t *fftlen; /* FFT length used for the decomposition */ + const Word16 *frameSize; /* Frame size in samples */ + const Word16 *fftlen; /* FFT length used for the decomposition */ } STEREO_CNG_DEC, *STEREO_CNG_DEC_HANDLE; @@ -287,18 +287,18 @@ typedef struct stereo_dec_cng typedef struct stereo_td_dec_data_structure { - int16_t tdm_last_ratio_idx; /* last TDM ratio index */ - int16_t tdm_last_SM_flag; /* last channel combination scheme flag */ - int16_t tdm_prev_last_SM_flag; /* channel combination scheme flag before last frame */ - int16_t tdm_SM_flag; /* current channel combination scheme flag */ - int16_t tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ - - int16_t tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ - int16_t tdm_low_rate_mode; /* secondary channel low rate mode flag */ + Word16 tdm_last_ratio_idx; /* last TDM ratio index */ + Word16 tdm_last_SM_flag; /* last channel combination scheme flag */ + Word16 tdm_prev_last_SM_flag; /* channel combination scheme flag before last frame */ + Word16 tdm_SM_flag; /* current channel combination scheme flag */ + Word16 tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ + + Word16 tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ + Word16 tdm_low_rate_mode; /* secondary channel low rate mode flag */ Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; - int16_t tdm_Pitch_reuse_flag; - int16_t tdm_LRTD_flag; - int16_t flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ + Word16 tdm_Pitch_reuse_flag; + Word16 tdm_LRTD_flag; + Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ Word32 TCX_old_syn_Overl_fx[L_FRAME16k / 2]; /* past ovrl buffer for possible switching from TD stereo ACELP to MDCT stereo TCX frame */ /* Q11 */ Word16 prevSP_ratio_fx; /* previous SP ratio */ @@ -320,24 +320,24 @@ typedef struct stereo_mdct_dec_data_structure STEREO_MDCT_BAND_PARAMETERS stbParamsTCX20afterACELP; /* stereo frequency band parameters for transition frame */ /* only intraframe */ - int16_t mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ - int16_t global_ild[2]; /* Quantized ILD for the whole spectrum */ - int16_t split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ + Word16 mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ + Word16 global_ild[2]; /* Quantized ILD for the whole spectrum */ + Word16 split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ - int16_t IGFStereoMode[2]; /* MDCT stereo mode for IGF */ + Word16 IGFStereoMode[2]; /* MDCT stereo mode for IGF */ - int16_t use_itd; - int16_t itd_mode; /*0/1*/ - Word32 itd_fx; /* Q15 */ + Word16 use_itd; + Word16 itd_mode; /*0/1*/ + Word32 itd_fx; /* Q15 */ - int16_t reverse_dmx; + Word16 reverse_dmx; Word32 smooth_ratio_fx; /* Q26 */ - int16_t prev_ms_mask[NB_DIV][MAX_SFB]; + Word16 prev_ms_mask[NB_DIV][MAX_SFB]; Word16 lastCoh_fx; /* Q14 */ - int16_t noise_seeds_channels[CPE_CHANNELS]; - int16_t noise_seed_common; - int16_t isSBAStereoMode; + Word16 noise_seeds_channels[CPE_CHANNELS]; + Word16 noise_seed_common; + Word16 isSBAStereoMode; } STEREO_MDCT_DEC_DATA, *STEREO_MDCT_DEC_DATA_HANDLE; @@ -348,18 +348,18 @@ typedef struct stereo_mdct_dec_data_structure typedef struct stereo_tca_dec_data_structure { - int16_t refChanIndx; /* reference channel index in current frame */ - int16_t prevRefChanIndx; /* reference channel index in previous frame */ - int16_t indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ - int16_t indx_ica_gD; /* ICA target gain */ + Word16 refChanIndx; /* reference channel index in current frame */ + Word16 prevRefChanIndx; /* reference channel index in previous frame */ + Word16 indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ + Word16 indx_ica_gD; /* ICA target gain */ Word32 targetGain_fx; /* gain norm applied on target (or right) channel in current frame */ // Q29 Word32 prevTargetGain_fx; /* gain norm applied on target (or right) channel in previous frame */ // Q29 - int16_t corrLagStats; /* corr lag stats in current frame */ - int16_t prevCorrLagStats; /* corr lag stats in previous frame */ + Word16 corrLagStats; /* corr lag stats in current frame */ + Word16 prevCorrLagStats; /* corr lag stats in previous frame */ - int16_t interp_dec_prevNCShift; /* NC Shift in previous frame */ - int16_t interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ + Word16 interp_dec_prevNCShift; /* NC Shift in previous frame */ + Word16 interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ Word32 memChanL_fx[L_DEC_MEM_LEN_ICA]; /* left channel input to correct at the cross-over for Fixed */ @@ -428,10 +428,10 @@ typedef struct stereo_icbwe_dec_data_structure typedef struct { - int16_t dtx_flag; - int16_t sce_id_dtx; + Word16 dtx_flag; + Word16 sce_id_dtx; - int16_t ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ + Word16 ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ } ISM_DTX_DATA_DEC; @@ -478,9 +478,9 @@ typedef struct ivas_dirac_dec_data_structure { DIRAC_CONFIG_DATA_HANDLE hConfig; - int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1]; - int16_t dithering_seed; - int16_t spar_to_dirac_write_idx; + Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1]; + Word16 dithering_seed; + Word16 spar_to_dirac_write_idx; IVAS_FB_MIXER_HANDLE hFbMdft; @@ -521,10 +521,10 @@ typedef struct dirac_output_synthesis_cov_state_structure typedef struct ivas_param_mc_diff_proto_info_structure { - int16_t num_protos_diff; - int16_t *proto_index_diff; - int16_t *num_source_chan_diff; - int16_t **source_chan_idx; + Word16 num_protos_diff; + Word16 *proto_index_diff; + Word16 *num_source_chan_diff; + Word16 **source_chan_idx; Word32 **proto_fac_fx; } PARAM_MC_DIFF_PROTO_INFO; @@ -532,42 +532,42 @@ typedef struct ivas_param_mc_diff_proto_info_structure typedef struct ivas_param_mc_dec_data_structure { - int16_t slot_size; + Word16 slot_size; Word32 *Cldfb_RealBuffer_tc_fx; // Q12 Word16 Cldfb_RealBuffer_tc_e; Word32 *Cldfb_ImagBuffer_tc_fx; // Q12 Word16 Cldfb_ImagBuffer_tc_e; Word16 sz; - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; - int16_t num_freq_bands; - int16_t num_param_bands_synth; + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; + Word16 num_freq_bands; + Word16 num_param_bands_synth; - int16_t band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; + Word16 band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; /*Decoder parameters */ /*Prototypes*/ - int16_t num_outputs_diff; + Word16 num_outputs_diff; PARAM_MC_DIFF_PROTO_INFO *diff_proto_info; PARAM_MC_SYNTHESIS_CONF synthesis_conf; /*Options*/ /* Decorrelator options */ - int16_t max_band_decorr; + Word16 max_band_decorr; /*Decoder states=memories*/ Word32 *proto_frame_f_fx; /* Q11 */ Word32 *proto_frame_dec_f_fx; /* Q11 */ DIRAC_OUTPUT_SYNTHESIS_COV_STATE h_output_synthesis_cov_state; DIRAC_OUTPUT_SYNTHESIS_PARAMS h_output_synthesis_params; - int16_t max_band_energy_compensation; + Word16 max_band_energy_compensation; HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC; Word16 *icc_q_fx; /* ICC parameters*/ /* Q15 */ Word16 *icld_q_fx; /* Q8 */ - int16_t max_param_band_abs_cov; + Word16 max_param_band_abs_cov; Word16 q_proto_frame_f; Word32 *ls_conv_dmx_matrix_fx; /* Q30 */ Word32 *proto_matrix_int_fx; @@ -588,12 +588,12 @@ typedef struct ivas_param_mc_dec_data_structure typedef struct ivas_mc_paramupmix_dec_data_structure { - int16_t num_freq_bands; + Word16 num_freq_bands; ivas_td_decorr_state_t *hTdDecorr[MC_PARAMUPMIX_COMBINATIONS]; - int32_t alpha_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int32_t beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int16_t first_frame; - int16_t free_param_interpolator; + Word32 alpha_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word32 beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word16 first_frame; + Word16 free_param_interpolator; Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; // Q28 @@ -627,30 +627,30 @@ typedef struct ivas_spar_md_dec_state_t ivas_spar_dec_matrices_t spar_coeffs; ivas_spar_dec_matrices_t spar_coeffs_prev; ivas_spar_dec_matrices_t spar_coeffs_tar; - int16_t dtx_md_smoothing_cntr; - int16_t valid_bands[IVAS_MAX_NUM_BANDS]; - int16_t base_band_age[IVAS_MAX_NUM_BANDS]; - int16_t spar_plc_num_lost_frames; - int16_t num_decorr; - int16_t td_decorr_flag; - int16_t spar_plc_enable_fadeout_flag; + Word16 dtx_md_smoothing_cntr; + Word16 valid_bands[IVAS_MAX_NUM_BANDS]; + Word16 base_band_age[IVAS_MAX_NUM_BANDS]; + Word16 spar_plc_num_lost_frames; + Word16 num_decorr; + Word16 td_decorr_flag; + Word16 spar_plc_enable_fadeout_flag; Word32 ***mixer_mat_fx; /* Q(Q_mixer_mat) */ Word32 mixer_mat_prev_fx[MAX_PARAM_SPATIAL_SUBFRAMES + 1][IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS]; /* Q(Q_mixer_mat) */ Word16 Q_mixer_mat; ivas_spar_md_com_cfg spar_md_cfg; ivas_arith_coeffs_t arith_coeffs; ivas_huff_coeffs_t huff_coeffs; - int16_t table_idx; - int16_t dtx_vad; - int16_t spar_hoa_md_flag; - int16_t spar_hoa_dirac2spar_md_flag; - int16_t HOA_md_ind[IVAS_SPAR_MAX_CH]; + Word16 table_idx; + Word16 dtx_vad; + Word16 spar_hoa_md_flag; + Word16 spar_hoa_dirac2spar_md_flag; + Word16 HOA_md_ind[IVAS_SPAR_MAX_CH]; Word32 smooth_buf_fx[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; /* Q0 */ Word16 smooth_fac_fx[IVAS_MAX_NUM_BANDS]; /* Q15 */ Word32 mixer_mat_prev2_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; /* Q(Q_mixer_mat) */ - int16_t first_valid_frame; + Word16 first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; - int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; + Word16 base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; } ivas_spar_md_dec_state_t; @@ -676,11 +676,11 @@ typedef struct { Word16 prev_ql_fx[IVAS_PCA_INTERP]; Word16 prev_qr_fx[IVAS_PCA_INTERP]; - int16_t prev_pca_bypass; + Word16 prev_pca_bypass; Word16 mem_eigVec_interp_fx[IVAS_PCA_LEN_INTERP_EIG_DEC]; /* parser output: */ - int16_t pca_bypass; - int32_t index[2]; + Word16 pca_bypass; + Word32 index[2]; } PCA_DEC_STATE; @@ -690,20 +690,20 @@ typedef struct ivas_spar_dec_lib_t ivas_td_decorr_state_t *hTdDecorr; ivas_spar_md_dec_state_t *hMdDec; IVAS_FB_MIXER_HANDLE hFbMixer; - int16_t AGC_flag; + Word16 AGC_flag; ivas_agc_dec_state_t *hAgcDec; PCA_DEC_STATE *hPCA; - int16_t dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; - int16_t enc_param_start_band; - int32_t core_nominal_brate; /* Nominal bitrate for core coding */ - int16_t i_subframe; - - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; + Word16 dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; + Word16 enc_param_start_band; + Word32 core_nominal_brate; /* Nominal bitrate for core coding */ + Word16 i_subframe; + + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; } SPAR_DEC_DATA, *SPAR_DEC_HANDLE; @@ -712,8 +712,8 @@ typedef struct ivas_spar_dec_lib_t typedef struct ivas_osba_data { Word32 **delayBuffer_fx; - int16_t delayBuffer_size; - int16_t delayBuffer_nchan; + Word16 delayBuffer_size; + Word16 delayBuffer_nchan; } SBA_ISM_DATA, *SBA_ISM_DATA_HANDLE; @@ -724,9 +724,9 @@ typedef struct ivas_osba_data typedef struct sce_dec_data_structure { - int16_t sce_id; /* SCE # identifier */ - int32_t element_brate; /* SCE total bitrate in bps */ - int32_t last_element_brate; /* SCE last total bitrate in bps */ + Word16 sce_id; /* SCE # identifier */ + Word32 element_brate; /* SCE total bitrate in bps */ + Word32 last_element_brate; /* SCE last total bitrate in bps */ /* core coder handle */ DEC_CORE_HANDLE hCoreCoder[1]; @@ -747,15 +747,15 @@ typedef struct sce_dec_data_structure typedef struct cpe_dec_data_structure { - int16_t cpe_id; /* CPE # identifier */ - int32_t element_brate; /* CPE element total bitrate in bps */ - int32_t last_element_brate; /* last CPE element total bitrate in bps */ + Word16 cpe_id; /* CPE # identifier */ + Word32 element_brate; /* CPE element total bitrate in bps */ + Word32 last_element_brate; /* last CPE element total bitrate in bps */ - int16_t element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ - int16_t last_element_mode; /* last element mode */ + Word16 element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ + Word16 last_element_mode; /* last element mode */ - int16_t stereo_switching_counter; - int16_t NbFrameMod; + Word16 stereo_switching_counter; + Word16 NbFrameMod; /* core coder handle */ DEC_CORE_HANDLE hCoreCoder[CPE_CHANNELS]; @@ -768,7 +768,7 @@ typedef struct cpe_dec_data_structure STEREO_ICBWE_DEC_HANDLE hStereoICBWE; /* Stereo inter-channel BWE data handle */ STEREO_CNG_DEC_HANDLE hStereoCng; /* Stereo CNG data structure */ - int16_t nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ + Word16 nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ /* DFT stereo I/O channel buffer memories that need to be updated for TD->DFT stereo switching */ @@ -792,7 +792,7 @@ typedef struct cpe_dec_data_structure /* buffers used for fading between MDCT and DFT Stereo */ - int32_t brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ + Word32 brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ } CPE_DEC_DATA, *CPE_DEC_HANDLE; @@ -803,8 +803,8 @@ typedef struct cpe_dec_data_structure typedef struct mct_dec_block_data_struct { - int16_t ch1, ch2; - int16_t mask[2][MAX_SFB]; + Word16 ch1, ch2; + Word16 mask[2][MAX_SFB]; STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; /* MDCT stereo data handle */ } MCT_DEC_BLOCK_DATA, *MCT_DEC_BLOCK_DATA_HANDLE; @@ -812,14 +812,14 @@ typedef struct mct_dec_block_data_struct typedef struct mct_dec_data_structure { - int16_t nchan_out_woLFE; /* number of active channels within multi-channel configuration */ - int16_t currBlockDataCnt; - int16_t bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ + Word16 nchan_out_woLFE; /* number of active channels within multi-channel configuration */ + Word16 currBlockDataCnt; + Word16 bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ MCT_DEC_BLOCK_DATA_HANDLE hBlockData[MCT_MAX_BLOCKS]; - int16_t chBitRatios[MCT_MAX_CHANNELS]; - int16_t lowE_ch[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ - uint16_t mc_global_ild[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ + Word16 chBitRatios[MCT_MAX_CHANNELS]; + Word16 lowE_ch[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ + UWord16 mc_global_ild[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ } MCT_DEC_DATA, *MCT_DEC_HANDLE; @@ -866,12 +866,12 @@ typedef struct ivas_binaural_rendering_struct IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ EFAP_HANDLE hEFAPdata; /* EFAP structure*/ Word32 *hoa_dec_mtx; /* pointer to HOA decoder mtx */ /*Q29*/ - int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ - int16_t max_band; /* band upto which rendering is performed */ - int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ - int16_t timeSlots; /* number of time slots of binaural renderer */ - int16_t nInChannels; /* number input channels */ - int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ + Word8 rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + Word16 max_band; /* band upto which rendering is performed */ + Word16 conv_band; /* band upto which convolution in cldfb domain is performed */ + Word16 timeSlots; /* number of time slots of binaural renderer */ + Word16 nInChannels; /* number input channels */ + Word8 render_lfe; /* Flag to render LFE in binaural rendering*/ IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ /* Convolution module structure */ @@ -892,18 +892,18 @@ typedef struct ivas_masa_decoder_ext_out_meta_struct { MASA_DECRIPTIVE_META descriptiveMeta; - uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord16 directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; } MASA_DECODER_EXT_OUT_META; typedef struct ivas_masa_decoder_data_struct { - int16_t band_mapping[MASA_FREQUENCY_BANDS + 1]; + Word16 band_mapping[MASA_FREQUENCY_BANDS + 1]; SPHERICAL_GRID_DATA *sph_grid16; MASA_DECODER_EXT_OUT_META *extOutMeta; @@ -922,32 +922,32 @@ typedef struct ivas_masa_decoder_struct /* Data structure for MASA_ISM rendering */ typedef struct ivas_masa_ism_data_structure { - int16_t azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; - int16_t elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; Word32 energy_ratio_ism_fx[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX]; /* Q30 */ Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ - int16_t azimuth_ism_edited[MAX_NUM_OBJECTS]; - int16_t elevation_ism_edited[MAX_NUM_OBJECTS]; - uint8_t ism_is_edited[MAX_NUM_OBJECTS]; + Word16 azimuth_ism_edited[MAX_NUM_OBJECTS]; + Word16 elevation_ism_edited[MAX_NUM_OBJECTS]; + UWord8 ism_is_edited[MAX_NUM_OBJECTS]; - int16_t idx_separated_ism; - int16_t azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; - int16_t elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 idx_separated_ism; + Word16 azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; Word32 q_azimuth_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ Word32 q_elevation_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ Word16 ismPreprocMatrix_fx[2][2][CLDFB_NO_CHANNELS_MAX]; /* Q15 */ - uint8_t objectsMoved; + UWord8 objectsMoved; Word32 eneMoveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ Word32 enePreserveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ Word32 preprocEneTarget_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ Word32 preprocEneRealized_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ Word32 **delayBuffer_fx; /* Q11 */ - int16_t delayBuffer_size; - int16_t delayBuffer_nchan; + Word16 delayBuffer_size; + Word16 delayBuffer_nchan; } MASA_ISM_DATA, *MASA_ISM_DATA_HANDLE; @@ -965,41 +965,41 @@ typedef struct decoder_tc_buffer_structure Word16 no_channels; /*Stores no of channels in tc_fx with values*/ #endif Word16 q_tc_fx; - TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ - int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ - int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ - int16_t nchan_buffer_full; /* number of channels to be fully buffered */ - int16_t n_samples_available; /* samples still available for rendering in the current frame */ - int16_t n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ - int16_t n_samples_rendered; /* samples already rendered in the current frame */ - int16_t n_samples_granularity; /* render granularity */ - int16_t n_samples_flushed; - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; - int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ + TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ + Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ + Word16 nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ + Word16 nchan_buffer_full; /* number of channels to be fully buffered */ + Word16 n_samples_available; /* samples still available for rendering in the current frame */ + Word16 n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ + Word16 n_samples_rendered; /* samples already rendered in the current frame */ + Word16 n_samples_granularity; /* render granularity */ + Word16 n_samples_flushed; + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; + Word16 n_samples_discard; /* number of samples to discard from the beginning of the output */ } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; typedef struct jbm_metadata_structure { - int16_t sf_write_idx; - int16_t sf_md_buffer_length; + Word16 sf_write_idx; + Word16 sf_md_buffer_length; - uint16_t directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ + UWord16 directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ - int16_t slot_read_idx; - int16_t slot_write_idx; - int16_t slot_md_buffer_length; + Word16 slot_read_idx; + Word16 slot_write_idx; + Word16 slot_md_buffer_length; - int16_t sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; + Word16 sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; } JBM_METADATA, *JBM_METADATA_HANDLE; @@ -1010,25 +1010,25 @@ typedef struct jbm_metadata_structure typedef struct decoder_config_structure { - int32_t ivas_total_brate; /* IVAS total bitrate in bps */ - int32_t last_ivas_total_brate; /* last IVAS total bitrate in bps */ - int32_t output_Fs; /* output signal sampling frequency in Hz */ - int16_t nchan_out; /* number of output audio channels */ + Word32 ivas_total_brate; /* IVAS total bitrate in bps */ + Word32 last_ivas_total_brate; /* last IVAS total bitrate in bps */ + Word32 output_Fs; /* output signal sampling frequency in Hz */ + Word16 nchan_out; /* number of output audio channels */ AUDIO_CONFIG output_config; /* output audio configuration */ - int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ - int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ - int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ - int16_t Opt_RendConfigCustom; /* indicates whether Renderer configuration custom setup is used */ + Word16 Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ + Word16 Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ + Word16 Opt_Headrotation; /* indicates whether head-rotation is used */ + Word16 Opt_RendConfigCustom; /* indicates whether Renderer configuration custom setup is used */ IVAS_HEAD_ORIENT_TRK_T orientation_tracking; /* indicates orientation tracking type */ - int16_t Opt_non_diegetic_pan; /* indicates diegetic or not */ + Word16 Opt_non_diegetic_pan; /* indicates diegetic or not */ Word16 non_diegetic_pan_gain_fx; /* non diegetic panning gain*/ /* Q15 */ - int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - int16_t Opt_ExternalOrientation; /* indiates whether external orientations are used */ - int16_t Opt_dpid_on; /* indicates whether Directivity pattern option is used */ - int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ - int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_ExternalOrientation; /* indiates whether external orientations are used */ + Word16 Opt_dpid_on; /* indicates whether Directivity pattern option is used */ + Word16 Opt_aeid_on; /* indicates whether Acoustic environment option is used */ + Word16 Opt_tsm; /* indicates whether time scaling modification is activated */ IVAS_RENDER_FRAMESIZE render_framesize; - int16_t Opt_delay_comp; /* flag indicating delay compensation active */ + Word16 Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; @@ -1047,8 +1047,8 @@ typedef struct Decoder_Struct IVAS_FORMAT ivas_format; /* IVAS format */ IVAS_FORMAT last_ivas_format; /* last frame IVAS format */ - int16_t sid_format; /* IVAS format indicator from SID frame */ - int16_t nchan_transport; /* number of transport channels */ + Word16 sid_format; /* IVAS format indicator from SID frame */ + Word16 nchan_transport; /* number of transport channels */ IVAS_OUTPUT_SETUP hOutSetup; /* output setup structure */ AUDIO_CONFIG intern_config; /* internal audio configuration */ IVAS_OUTPUT_SETUP hIntSetup; /* internal setup structure */ @@ -1056,24 +1056,24 @@ typedef struct Decoder_Struct AUDIO_CONFIG transport_config; /* transport audio configuration */ IVAS_OUTPUT_SETUP hTransSetup; /* transport setup structure */ - int16_t element_mode_init; /* element mode used at initialization */ - int16_t codec_mode; /* Mode 1 or 2 */ - int16_t ini_frame; /* initialization frames counter */ - int16_t ini_active_frame; /* initialization active frames counter */ + Word16 element_mode_init; /* element mode used at initialization */ + Word16 codec_mode; /* Mode 1 or 2 */ + Word16 ini_frame; /* initialization frames counter */ + Word16 ini_active_frame; /* initialization active frames counter */ - int16_t bfi; /* FEC - bad frame indicator */ - int16_t BER_detect; /* BER detect flag */ - int16_t num_bits; /* BER detect flag */ + Word16 bfi; /* FEC - bad frame indicator */ + Word16 BER_detect; /* BER detect flag */ + Word16 num_bits; /* BER detect flag */ - uint16_t *bit_stream; /* Pointer to bitstream buffer */ - int16_t writeFECoffset; /* parameter for debugging JBM stuff */ + UWord16 *bit_stream; /* Pointer to bitstream buffer */ + Word16 writeFECoffset; /* parameter for debugging JBM stuff */ IVAS_LIMITER_HANDLE hLimiter; /* Limiter handle */ /* core-decoder modules */ - int16_t nSCE; /* number of total SCEs */ - int16_t nCPE; /* number of total CPEs */ - int16_t nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ + Word16 nSCE; /* number of total SCEs */ + Word16 nCPE; /* number of total CPEs */ + Word16 nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ SCE_DEC_HANDLE hSCE[MAX_SCE]; /* SCE handles */ CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS]; /* CPE handles */ @@ -1092,12 +1092,12 @@ typedef struct Decoder_Struct LFE_DEC_HANDLE hLFE; /* LFE handle */ ISM_MODE ism_mode; /* ISM format mode */ - int16_t nchan_ism; /* number of ISM channels */ + Word16 nchan_ism; /* number of ISM channels */ MC_MODE mc_mode; /* MC format mode */ - int16_t sba_order; /* Ambisonic (SBA) order */ - int16_t sba_planar; /* Ambisonic (SBA) planar flag */ - int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ - int16_t sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ + Word16 sba_order; /* Ambisonic (SBA) order */ + Word16 sba_planar; /* Ambisonic (SBA) planar flag */ + Word16 sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ + Word16 sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ /* rendering modules */ RENDERER_TYPE renderer_type; /* renderer type */ @@ -1120,7 +1120,7 @@ typedef struct Decoder_Struct Word32 *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */ RENDER_CONFIG_DATA *hRenderConfig; /* Renderer config pointer */ - int32_t binaural_latency_ns; /* Binauralization latency in ns */ + Word32 binaural_latency_ns; /* Binauralization latency in ns */ EXTERNAL_ORIENTATION_HANDLE hExtOrientationData; /* External orientation data structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; /* Combined external and head orientation data structure */ DIRAC_REND_HANDLE hDirACRend; /* DirAC renderer handle */ @@ -1128,16 +1128,16 @@ typedef struct Decoder_Struct MASA_ISM_DATA_HANDLE hMasaIsmData; /* OMASA rendering handle */ SBA_ISM_DATA_HANDLE hSbaIsmData; /* OSBA rendering handle */ - int16_t flag_omasa_brate; + Word16 flag_omasa_brate; /* JBM module */ DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */ JBM_METADATA_HANDLE hJbmMetadata; /* Structure for metadata buffering in JBM */ - int32_t last_active_ivas_total_brate; - int16_t ism_extmeta_active; /* Extended metadata active in decoder */ - int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ + Word32 last_active_ivas_total_brate; + Word16 ism_extmeta_active; /* Extended metadata active in decoder */ + Word16 ism_extmeta_cnt; /* Change frame counter for extended metadata */ Word32 **mem_hp20_out_fx; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* Word32-output audio buffers */ Word16 p_out_len;/*Stores the total no of channels for which memory is allocated to p_output_fx*/ diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 2dd2a30c3..e5e18083d 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -2078,7 +2078,7 @@ void stereo_td2dft_update_fx( ) { Word16 ovl, ovl_TCX, dft32ms_ovl, hq_delay_comp; - Word16 ns, nsLB; + Word16 ns, nsLB, i; Word16 old_out_len, old_outLB_len; Decoder_State **sts; @@ -2181,9 +2181,9 @@ void stereo_td2dft_update_fx( v_add_fx( sts[0]->hHQ_core->old_outLB_fx + nsLB, sts[1]->hHQ_core->old_outLB_fx + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, STEREO_MDCT2DFT_FADE_LEN_48k, old_outLB_len ); #ifndef MSAN_FIX - for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) + for ( i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else - FOR( Word32 i = 0; i < old_outLB_len; i++ ) + FOR( i = 0; i < old_outLB_len; i++ ) #endif { hCPE->old_outLB_mdct_fx[i] = L_shr( hCPE->old_outLB_mdct_fx[i], 1 ); /* Q11 */ @@ -2193,7 +2193,7 @@ void stereo_td2dft_update_fx( #ifndef MSAN_FIX for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else - FOR( Word32 i = 0; i < old_out_len; i++ ) + FOR( i = 0; i < old_out_len; i++ ) #endif { hCPE->old_out_mdct_fx[i] = L_shr( hCPE->old_out_mdct_fx[i], 1 ); /* q_old_out_mdct */ diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index bb73fe7f0..375dbdad0 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -306,7 +306,6 @@ Word16 svd_fx( Word16 iCh, jCh; Word16 lengthSingularValues; Word16 errorMessage, condition; - // int16_t max_length = ((nChannelsL > nChannelsC) ? nChannelsL : nChannelsC); Word32 secDiag_fx[MAX_OUTPUT_CHANNELS]; #ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 secDiag_fx_e = 0; diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 939fad2cb..5b5ff16c5 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -67,7 +67,7 @@ struct JB4_DATAUNIT Word16 qBit; /** the binary encoded access unit */ - uint8_t *data; + UWord8 *data; /** the size of the binary encoded access unit [bits] */ UWord16 dataSize; diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 1fe7481df..7955d0ea6 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -92,7 +92,7 @@ typedef struct apa_state_t *PCMDSP_APA_HANDLE; /*! Allocates memory for state struct and initializes elements. * @return 0 on success, 1 on failure */ ivas_error apa_init( apa_state_t **s, - const int32_t num_channels ); + const Word32 num_channels ); /*! Sets state variables to initial value. */ void apa_reset( apa_state_t *s ); @@ -106,7 +106,7 @@ void apa_reset( apa_state_t *s ); * @param[in] output_Fs sample rate [Hz] * @param[in] num_channels number of channels * @return 0 on success, 1 on failure */ -bool apa_set_rate( apa_state_t *ps, const int32_t output_Fs ); +bool apa_set_rate( apa_state_t *ps, const Word32 output_Fs ); /*! Set scaling. * The scale is given in % and will be valid until changed again. @@ -120,7 +120,7 @@ bool apa_set_renderer_residual_samples( apa_state_t *ps, UWord16 l_r_buf ); bool apa_set_evs_compat_mode( apa_state_t *ps, bool mode ); -uint8_t apa_reconfigure( apa_state_t *ps, uint16_t num_channels, uint16_t l_ts ); +UWord8 apa_reconfigure( apa_state_t *ps, UWord16 num_channels, UWord16 l_ts ); bool apa_set_complexity_options( apa_state_t *s, UWord16 wss, UWord16 css ); @@ -129,5 +129,5 @@ bool apa_set_quality( apa_state_t *s, Word32 quality, UWord16 qualityred, UWord1 bool apa_exit( apa_state_t **s ); UWord8 apa_exec_ivas_fx( apa_state_t *s, const Word32 a_in[], UWord16 l_in, UWord16 maxScaling, Word32 a_out[], UWord16 *l_out ); -uint8_t apa_exec_fx( apa_state_t *s, const Word16 a_in[], UWord16 l_in, UWord16 maxScaling, Word16 a_out[], UWord16 *l_out ); +UWord8 apa_exec_fx( apa_state_t *s, const Word16 a_in[], UWord16 l_in, UWord16 maxScaling, Word16 a_out[], UWord16 *l_out ); #endif /* JBM_PCMDSP_APA_H */ diff --git a/lib_dec/jbm_pcmdsp_window.h b/lib_dec/jbm_pcmdsp_window.h index 3551380de..1d193433e 100644 --- a/lib_dec/jbm_pcmdsp_window.h +++ b/lib_dec/jbm_pcmdsp_window.h @@ -52,7 +52,7 @@ * <------> * n */ -void hannWindow( uint16_t n, float *w ); +void hannWindow( UWord16 n, float *w ); /** Overlap/Add of two signal with a given window. */ /** @param[in] fadeOut signal to fade out diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index 5a3aec3f4..976826949 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -612,7 +612,7 @@ void amr_wb_enc_init_fx( AMRWB_IO_ENC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO encoder handle */ ) { - int16_t i; + Word16 i; /* HF (6-7kHz) BWE */ hAmrwb_IO->seed2_enc = RANDOM_INITSEED; diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 93a0146f3..962b715cd 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -519,7 +519,7 @@ void AVQ_encmux_fx( bit_tmp = add( unusedbitsFlag, unused_bits_idx ); /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ nq_est = mult( 6554, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); - assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); if ( EQ_16( nq_est, 1 ) ) { @@ -946,7 +946,7 @@ void AVQ_encmux_ivas_fx( bit_tmp = add( unusedbitsFlag, unused_bits_idx ); /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ nq_est = mult( 6554 /*.2 in Q15*/, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); - assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); if ( EQ_16( nq_est, 1 ) ) { @@ -1085,8 +1085,8 @@ static void wrte_cv( Word16 *nbits /* i/o: bits */ ) { - int16_t pos, j; - int16_t bits, nq4; + Word16 pos, j; + Word16 bits, nq4; bits = *nbits; move16(); @@ -1145,8 +1145,8 @@ static void wrte_cv_ivas_fx( Word16 *nbits /* i/o: bits */ ) { - int16_t pos, j; - int16_t bits, nq4; + Word16 pos, j; + Word16 bits, nq4; bits = *nbits; move16(); diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index a2995245d..1c60f2ecd 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -30,8 +30,8 @@ static void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, co static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); static void init_core_sig_ana_ivas_fx( Encoder_State *st ); static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ); -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ); +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const Word32 last_total_brate ); +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const Word32 last_total_brate ); /*-----------------------------------------------------------------------* * init_coder_ace_plus_fx() @@ -1324,7 +1324,7 @@ static void init_tcx_ivas_fx( * Initialization of signal buffers *-----------------------------------------------------------------------*/ /*copy of evs function since it was static */ -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const int32_t last_total_brate ) +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const Word32 last_total_brate ) { LPD_state_HANDLE hLPDmem = st->hLPDmem; @@ -1542,7 +1542,7 @@ static void init_core_sig_ana_ivas_fx( Encoder_State *st ) * * *-----------------------------------------------------------------------*/ -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const int32_t last_total_brate ) +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const Word32 last_total_brate ) { Word16 mem_syn_r_size_old; Word16 mem_syn_r_size_new; diff --git a/lib_enc/core_enc_reconf_fx.c b/lib_enc/core_enc_reconf_fx.c index 3637dd53f..1ba496b0e 100644 --- a/lib_enc/core_enc_reconf_fx.c +++ b/lib_enc/core_enc_reconf_fx.c @@ -344,7 +344,7 @@ void core_coder_reconfig_fx( void core_coder_reconfig_ivas_fx( Encoder_State *st, - const int32_t last_total_brate ) + const Word32 last_total_brate ) { Word16 i, bwidth, index; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; diff --git a/lib_enc/enc_acelp_fx.c b/lib_enc/enc_acelp_fx.c index 7dd342318..a509a7cd7 100644 --- a/lib_enc/enc_acelp_fx.c +++ b/lib_enc/enc_acelp_fx.c @@ -1761,7 +1761,7 @@ void E_ACELP_4t_fx( const Word16 last_L_frame, /*Q0*/ const Word32 total_brate, /*Q0*/ const Word16 i_subfr, /*Q0*/ - const int16_t cmpl_flag /*Q0*/ ) + const Word16 cmpl_flag /*Q0*/ ) { PulseConfig config; Word16 ind[NPMAXPT * 4]; @@ -1824,7 +1824,7 @@ void E_ACELP_4t_ivas_fx( const Word16 last_L_frame, /*Q0*/ const Word32 total_brate, /*Q0*/ const Word16 i_subfr, /*Q0*/ - const int16_t cmpl_flag, /*Q0*/ + const Word16 cmpl_flag, /*Q0*/ Word16 element_mode /*Q0*/ ) { PulseConfig config; diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index a36ee78e2..4305e5bca 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -216,7 +216,7 @@ ivas_error ivas_ism_metadata_enc_fx( move16(); Word32 valQ_fx; ISM_METADATA_HANDLE hIsmMetaData; - int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; + Word32 element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; Word16 ism_metadata_flag_global; Word16 non_diegetic_flag_global; Word16 ism_imp[MAX_NUM_OBJECTS]; diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index bb6ef0d01..c4d3908ca 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -574,7 +574,7 @@ ivas_error ivas_mcmasa_enc_reconfig_fx( void ivas_mcmasa_enc_close_fx( MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */ - const int32_t input_Fs /* i : input sampling rate */ + const Word32 input_Fs /* i : input sampling rate */ ) { Word16 i, j; diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 55da30e73..d6bc4c7f0 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -421,7 +421,7 @@ ivas_error ivas_mct_enc_fx( } /* joint MCT encoding */ - ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (int16_t) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); + ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (Word16) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 403d379fa..70b2b0034 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -799,7 +799,7 @@ static void applyStereoPreProcessingCplx( * * encoder-side complex-valued stereo pre-processing (crosstalk) *---------------------------------------------------------------*/ -static uint16_t enc_ste_pre_mdct( +static UWord16 enc_ste_pre_mdct( Word32 *sigR0_fx, /* i/o: MDCT samples of the 1st (left) channel q_com*/ Word32 *sigR1_fx, /* i/o: MDCT samples of the 2nd (right) channel q_com*/ Word32 *sigI0_fx, /* i/o: MDST samples of the 1st (left) channel q_com*/ diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 3416ab279..b32c80404 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -160,7 +160,7 @@ static Word16 encode_coherence_indexesDCT1_fx( BSTR_ENC_HANDLE hMetaData /* i : metadata handle */ ); -static UWord64 create_combined_index_fx( uint16_t *idx_dct, const Word16 len, const Word16 *no_cb_vec ); +static UWord64 create_combined_index_fx( UWord16 *idx_dct, const Word16 len, const Word16 *no_cb_vec ); static Word16 encode_surround_coherence_fx( IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ @@ -184,7 +184,7 @@ static void ivas_diffuseness_huff_ec_prepare_fx( UWord16 *avr_idx, Word16 *diffuseness_bits_huff ); -static Word16 coherence_coding_length( const uint16_t *idx_sur_coh_shift, const UWord8 idx_shift_len, const Word16 coding_subbands, const Word16 *no_cv, uint16_t *mr_idx, Word16 *no_cv_shift, Word16 *p_min_idx, Word16 *GR_ord, Word16 *nbits_fr, Word16 *nbits_fr1 ); +static Word16 coherence_coding_length( const UWord16 *idx_sur_coh_shift, const UWord8 idx_shift_len, const Word16 coding_subbands, const Word16 *no_cv, UWord16 *mr_idx, Word16 *no_cv_shift, Word16 *p_min_idx, Word16 *GR_ord, Word16 *nbits_fr, Word16 *nbits_fr1 ); static Word16 write_2dir_info( BSTR_ENC_HANDLE hMetaData, UWord8 *twoDirBands, const Word16 n, const Word16 k ); @@ -2326,7 +2326,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( move16(); UWord16 dist_elevation_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; Word16 gr_param_azimuth_best, avg_azimuth_index_best; - uint16_t dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; UWord16 idx, dist_count; Word16 direction_bits_ec; diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e6038186e..e321f1c7c 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -60,7 +60,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - Word16 index; + Word16 index, i; const Word16 split_len = M / 2; move16(); const Word16 *means; @@ -85,7 +85,7 @@ static Word16 sns_1st_cod_fx( Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; move16(); move16(); - FOR( Word16 i = 0; i < M; ++i ) + FOR( i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 exp_snsq_buffer[i] = 0; @@ -93,11 +93,11 @@ static Word16 sns_1st_cod_fx( snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); move32(); } - FOR( int i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); } - FOR( int i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); @@ -121,7 +121,7 @@ static Word16 sns_1st_cod_fx( dist_min_fx = MAXVAL_WORD32; Word16 exp_dist_min = 31; index_split = 0; - FOR( Word16 i = 0; i < 32; ++i ) + FOR( i = 0; i < 32; ++i ) { Word32 dist_fx = 0; move32(); diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 925f4e702..2ace35473 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -1665,7 +1665,7 @@ static void ivas_write_parameter_bitstream_dtx_fx( Word16 *num_dec, const Word16 num_bands ) { - int16_t i, j; + Word16 i, j; Word32 val; Word16 idx; Word32 pr_min_max[2]; diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 3f7237ce5..ede3d3ad9 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -3302,8 +3302,8 @@ static void stereo_dft_enc_compute_prm_fx( Word32 *dot_prod_nrg_ratio_fx, // Q(31-dot_prod_nrg_ratio_fx_e[]) Word16 *dot_prod_nrg_ratio_fx_e ) { - int16_t b, i; - int16_t b2; + Word16 b, i; + Word16 b2; Word32 *pDFT_L, *pDFT_R; // Word16 DFT_L_e, DFT_R_e; Word32 sum_nrg_L, sum_nrg_R; @@ -3352,7 +3352,7 @@ static void stereo_dft_enc_compute_prm_fx( Word16 sum_past_dot_prod_abs_e, sum_past_dot_prod_abs2_e = 0; Word32 sum_past_nrg_dmx; Word16 sum_past_nrg_dmx_e; - int16_t pos; + Word16 pos; Word32 pIpd[STEREO_DFT_BAND_MAX]; // Q13 Word32 ipd_smooth[STEREO_DFT_BAND_MAX]; // Q13 Word32 ipd_mean_change; // Q13 diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index f8d600276..979978c03 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -1006,9 +1006,8 @@ void stereo_tdm_prep_dwnmx_fx( const Word16 input_q /* i : frame lenght */ ) { -#define USER_ENER Word32 mener; - int16_t i, sw_pos, enr_len; + Word16 i, sw_pos, enr_len; Encoder_State **sts; Word16 mener_e; sts = hCPE->hCoreCoder; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 211c53f8c..9d4736368 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -59,8 +59,8 @@ struct IVAS_ENC bool cmd_stereo; #endif bool switchingActive; /* flag for configuration changes during encoding - currently only used with mono */ - int16_t Opt_RF_ON_loc; - int16_t rf_fec_offset_loc; + Word16 Opt_RF_ON_loc; + Word16 rf_fec_offset_loc; bool ismMetadataProvided[MAX_NUM_OBJECTS]; bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ IVAS_ENC_BANDWIDTH newBandwidthApi; /* maximum encoded bandwidth, as set on API level */ @@ -77,14 +77,14 @@ static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); static ivas_error sanitizeBitrateISM_fx( const ENCODER_CONFIG_HANDLE hEncoderConfig, const bool extMetadataApi ); static Word16 getInputBufferSize_fx( const Encoder_Struct *st_ivas ); -static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, const int32_t inputFs, const int32_t initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); -static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, const int32_t totalBitrate ); +static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, const Word32 totalBitrate ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig ); static void resetIsmMetadataProvidedFlags( IVAS_ENC_HANDLE hIvasEnc ); -static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, int16_t *internalMaxBandwidth ); -static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, int16_t *fecIndicatorInternal ); +static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, Word16 *internalMaxBandwidth ); +static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, Word16 *fecIndicatorInternal ); #ifdef DEBUGGING static ivas_error forcedModeApiToInternal( IVAS_ENC_FORCED_MODE forcedMode, int16_t *forcedModeInternal ); #endif @@ -276,8 +276,8 @@ void IVAS_ENC_Close( ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -296,7 +296,7 @@ ivas_error IVAS_ENC_ConfigureForMono( } hIvasEnc->st_ivas->hEncoderConfig->ivas_format = MONO_FORMAT; - hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (int16_t) is_binaural; + hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (Word16) is_binaural; if ( downmixFromStereo ) { @@ -318,8 +318,8 @@ ivas_error IVAS_ENC_ConfigureForMono( ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -344,7 +344,7 @@ ivas_error IVAS_ENC_ConfigureForStereo( hEncoderConfig = st_ivas->hEncoderConfig; hEncoderConfig->nchan_inp = 2; hEncoderConfig->ivas_format = STEREO_FORMAT; - hEncoderConfig->is_binaural = (int16_t) is_binaural; + hEncoderConfig->is_binaural = (Word16) is_binaural; #ifdef DEBUGGING switch ( stereoMode ) @@ -458,12 +458,12 @@ ivas_error IVAS_ENC_ConfigureForMASAObjects( ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */ ) { @@ -503,7 +503,7 @@ ivas_error IVAS_ENC_ConfigureForObjects( ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const uint16_t ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ) { @@ -551,8 +551,8 @@ ivas_error IVAS_ENC_FeedObjectMetadata( ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -580,7 +580,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->nchan_inp = ivas_sba_get_nchan_fx( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ - hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; + hEncoderConfig->Opt_PCA_ON = (Word16) Opt_PCA_ON; hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -780,8 +780,8 @@ ivas_error IVAS_ENC_FeedMasaMetadata( ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -841,8 +841,8 @@ ivas_error IVAS_ENC_ConfigureForMultichannel( static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, - const int32_t inputFs, - const int32_t initBitrate, + const Word32 inputFs, + const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ) @@ -850,7 +850,7 @@ static ivas_error configureEncoder( Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; ivas_error error; - int32_t cpe_brate; + Word32 cpe_brate; error = IVAS_ERR_OK; @@ -1476,7 +1476,7 @@ static Word16 getInputBufferSize_fx( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ) { if ( hIvasEnc == NULL || numInChannels == NULL ) @@ -1824,8 +1824,8 @@ ivas_error IVAS_ENC_SetBandwidth( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_SetBitrate( - IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t totalBitrate /* i : requested bitrate of the output bitstream */ + IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ) { ivas_error error; @@ -2003,11 +2003,11 @@ const char *IVAS_ENC_GetErrorMessage( static ivas_error printConfigInfo_enc( IVAS_ENC_HANDLE hIvasEnc, - const int16_t channelAwareModeEnabled ) + const Word16 channelAwareModeEnabled ) { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t newBandwidthApi; + Word16 newBandwidthApi; ivas_error error; st_ivas = hIvasEnc->st_ivas; @@ -2237,7 +2237,7 @@ static ivas_error printConfigInfo_enc( static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, - const int32_t totalBitrate ) + const Word32 totalBitrate ) { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; @@ -2753,8 +2753,8 @@ static ivas_error forcedModeApiToInternal( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_PrintConfig( - const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - const int16_t channelAwareModeEnabled /* i : channel-aware mode enabled flag */ + const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + const Word16 channelAwareModeEnabled /* i : channel-aware mode enabled flag */ ) { return printConfigInfo_enc( hIvasEnc, channelAwareModeEnabled ); diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 4911711d7..ab6c39c23 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -68,7 +68,7 @@ typedef struct _IVAS_ENC_DTX_CONFIG { bool enabled; bool variable_SID_rate; - int16_t SID_interval; + Word16 SID_interval; } IVAS_ENC_DTX_CONFIG; typedef enum _IVAS_ENC_SBA_ORDER @@ -169,8 +169,8 @@ ivas_error IVAS_ENC_Open_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -182,8 +182,8 @@ ivas_error IVAS_ENC_ConfigureForMono( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -197,34 +197,34 @@ ivas_error IVAS_ENC_ConfigureForStereo( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMASAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ - const int16_t masaVariant /* i : index specifying the number of MASA transport channels */ + const UWord16 numObjects, /* i : number of objects to be encoded */ + const Word16 masaVariant /* i : index specifying the number of MASA transport channels */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForSBAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ 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_PCA_ON /* i : PCA option flag */ @@ -233,8 +233,8 @@ ivas_error IVAS_ENC_ConfigureForSBAObjects( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -245,8 +245,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -257,8 +257,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMasa( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -268,8 +268,8 @@ ivas_error IVAS_ENC_ConfigureForMasa( /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -285,7 +285,7 @@ void IVAS_ENC_Close( /*! r: error code */ ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const uint16_t ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ); @@ -307,10 +307,10 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( /*! r: error code */ ivas_error IVAS_ENC_EncodeFrameToCompact( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *inputBuffer, /* i : PCM input */ - const int16_t inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ - uint8_t *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ - uint16_t *numOutBits /* o : number of bits written to output bitstream */ + Word16 *inputBuffer, /* i : PCM input */ + const Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ + UWord8 *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ + UWord16 *numOutBits /* o : number of bits written to output bitstream */ ); /* Setter functions - apply changes to encoder configuration */ @@ -324,7 +324,7 @@ ivas_error IVAS_ENC_SetBandwidth( /*! r: error code */ ivas_error IVAS_ENC_SetBitrate( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t totalBitrate /* i : requested bitrate of the output bitstream */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ); /*! r: error code */ @@ -355,13 +355,13 @@ ivas_error IVAS_ENC_GetDelay( /*! r: encoder error code */ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_GetInputBufferSize( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /* Utility functions */ @@ -388,7 +388,7 @@ const char *IVAS_ENC_GetErrorMessage( ivas_error IVAS_ENC_PrintConfig( const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - const int16_t channelAwareModeEnabled /* i : channel-aware mode enabled flag */ + const Word16 channelAwareModeEnabled /* i : channel-aware mode enabled flag */ ); void IVAS_ENC_PrintDisclaimer( diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index a61b2ebff..24179f375 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -31,9 +31,9 @@ static Word32 vq_lvq_lsf_enc( Word16 pred_flag, Word16 mode, Word16 u[], Word16 static Word32 vq_lvq_lsf_enc_ivas_fx( Word16 pred_flag, Word16 mode, Word16 u[], Word16 *levels, Word16 stages, Word16 w[], Word16 Idx[], const Word16 *lsf, const Word16 *pred, Word16 *resq, Word16 *lsfq ); -static void lsf_mid_enc_fx( BSTR_ENC_HANDLE hBstr, int16_t nb_bits, const Word16 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word32 Bin_Ener[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); +static void lsf_mid_enc_fx( BSTR_ENC_HANDLE hBstr, Word16 nb_bits, const Word16 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word32 Bin_Ener[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); -static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, int16_t nb_bits, const Word32 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); +static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, Word16 nb_bits, const Word32 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); /*===========================================================================*/ /* FUNCTION : lsf_enc_fx() */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 7f58a9501..28e1a39de 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -366,7 +366,7 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */ const Word32 *u_fx, /* i : target signal */ const Word16 u_e, /* i : exp for target signal */ - const int16_t maxC_st1, /* i : number of candidates in stage1 */ + const Word16 maxC_st1, /* i : number of candidates in stage1 */ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */ ) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 02f8344d1..10d020ee3 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -143,7 +143,7 @@ void bw_detect_fx( const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ + const Word16 mct_on /* i : flag MCT mode */ ); void core_switching_post_enc_fx( /*done */ @@ -627,7 +627,7 @@ void swb_bwe_enc_fx( void swb_bwe_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ + const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ @@ -1585,7 +1585,7 @@ void E_ACELP_4t_ivas_fx( const Word16 last_L_frame, const Word32 total_brate, const Word16 i_subfr, - const int16_t cmpl_flag, + const Word16 cmpl_flag, Word16 element_mode ); void E_ACELP_innovative_codebook_fx( @@ -3077,15 +3077,15 @@ void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state #ifdef MSAN_FIX Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ #endif - const int16_t igfGridIdx, /* i : IGF grid index */ - Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ - Word16 e_mdct, /* i : exponent of pMDCTspectrum */ - Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 *e_ps, /* i : exponent of pPowerSpectrum */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int8_t isTNSActive, /* i : flag indicating if the TNS is active */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ + const Word16 igfGridIdx, /* i : IGF grid index */ + Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ + Word16 e_mdct, /* i : exponent of pMDCTspectrum */ + Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 *e_ps, /* i : exponent of pPowerSpectrum */ + const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ + const Word8 isTNSActive, /* i : flag indicating if the TNS is active */ + const Word16 sp_aud_decision0, /* i : first stage switching decision */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ ); void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index ad572d2ba..41c6b0468 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -51,9 +51,9 @@ typedef struct { - int16_t id; /* id of the indice */ - uint16_t value; /* value of the quantized indice */ - int16_t nb_bits; /* number of bits used for the quantization of the indice */ + Word16 id; /* id of the indice */ + UWord16 value; /* value of the quantized indice */ + Word16 nb_bits; /* number of bits used for the quantization of the indice */ } Indice, *INDICE_HANDLE; typedef struct @@ -84,12 +84,12 @@ typedef struct typedef struct bitstream_enc_data_structure { - int16_t nb_ind_tot; /* total number of indices already written */ - int16_t nb_bits_tot; /* total number of bits already written */ - Indice *ind_list; /* list of indices */ - int16_t *ivas_max_num_indices; /* maximum total number of indices in the list */ - Indice **ivas_ind_list_zero; /* beginning of the buffer of indices */ - void *st_ivas; /* IVAS encoder structure */ + Word16 nb_ind_tot; /* total number of indices already written */ + Word16 nb_bits_tot; /* total number of bits already written */ + Indice *ind_list; /* list of indices */ + Word16 *ivas_max_num_indices; /* maximum total number of indices in the list */ + Indice **ivas_ind_list_zero; /* beginning of the buffer of indices */ + void *st_ivas; /* IVAS encoder structure */ // Word16 nb_bits_tot_fx; /* total number of bits already written */ // Indice *ind_list_fx; /* list of indices */ Word16 next_ind_fx; /* pointer to the next empty slot in the list of indices */ @@ -128,9 +128,9 @@ typedef struct signal_buffers_enc_data_structure /* Delay buffer: Used to buffer input samples and to define the subblock size of a transient detector. */ typedef struct { - int16_t nSubblockSize; /* Subblock size of a transient detector that uses this delay buffer. */ + Word16 nSubblockSize; /* Subblock size of a transient detector that uses this delay buffer. */ Word16 buffer[L_FRAME48k / NSUBBLOCKS]; - int16_t nDelay; /* Size of the delay buffer in use. Maximum delay from all users of this buffer. */ + Word16 nDelay; /* Size of the delay buffer in use. Maximum delay from all users of this buffer. */ } DelayBuffer; @@ -141,8 +141,8 @@ typedef struct Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ /* IVAS: Q3 */ - int16_t nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ - int16_t nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ + Word16 nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ + Word16 nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ /* Decay factor for the recursive accumulation */ Word16 facAccSubblockNrg; @@ -152,27 +152,25 @@ typedef struct Word16 firState2; Word16 q_firState; - uint16_t ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */ + UWord16 ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */ } SubblockEnergies; /* Attack detection function. */ -typedef void ( *TCheckSubblocksForAttack )( const float *pSubblockNrg, const float *pAccSubblockNrg, int16_t nSubblocks, int16_t nPastSubblocks, float attackRatioThreshold, int16_t *pbIsAttackPresent, int16_t *pAttackIndex ); typedef void ( *TCheckSubblocksForAttack_fx )( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ); /* Transient detector. */ typedef struct TransientDetector { SubblockEnergies *pSubblockEnergies; /* Subblock energies used in this transient detector. */ - int16_t nDelay; /* Delay of the transient detector in number of subblocks, nDelay <= pSubblockEnergies->nDelay. */ - int16_t nSubblocksToCheck; /* Number of subblocks to check for transients. */ - TCheckSubblocksForAttack CheckSubblocksForAttack; /* Function for checking a presence of an attack. */ + Word16 nDelay; /* Delay of the transient detector in number of subblocks, nDelay <= pSubblockEnergies->nDelay. */ + Word16 nSubblocksToCheck; /* Number of subblocks to check for transients. */ TCheckSubblocksForAttack_fx CheckSubblocksForAttack_fx; /* Function for checking a presence of an attack. */ Word16 attackRatioThreshold; /* Attack ratio threshold Q11 */ - int16_t bIsAttackPresent; /* True when an attack was detected. */ - int16_t prev_bIsAttackPresent; /* True if an attack was detected in the previous frame. */ - int16_t attackIndex; /* The index of an attack. */ + Word16 bIsAttackPresent; /* True when an attack was detected. */ + Word16 prev_bIsAttackPresent; /* True if an attack was detected in the previous frame. */ + Word16 attackIndex; /* The index of an attack. */ } TransientDetector; /* Transient detection: Holds all transient detectors and buffers used by them. */ @@ -191,25 +189,25 @@ typedef struct TransientDetection_structure typedef struct vad_structure { - int16_t nb_active_frames; - int16_t hangover_cnt; - int16_t nb_active_frames_he; - int16_t hangover_cnt_he; - int32_t vad_flag_reg_H; - int32_t vad_flag_reg_L; - int32_t vad_prim_reg; - - int16_t vad_flag_cnt_50; - int16_t vad_prim_cnt_16; - - int16_t hangover_cnt_dtx; - int16_t hangover_cnt_music; + Word16 nb_active_frames; + Word16 hangover_cnt; + Word16 nb_active_frames_he; + Word16 hangover_cnt_he; + Word32 vad_flag_reg_H; + Word32 vad_flag_reg_L; + Word32 vad_prim_reg; + + Word16 vad_flag_cnt_50; + Word16 vad_prim_cnt_16; + + Word16 hangover_cnt_dtx; + Word16 hangover_cnt_music; Word16 bcg_flux_fx; // Q4 - int16_t soft_hangover; - int16_t voiced_burst; - int16_t bcg_flux_init; - int16_t nb_active_frames_he1; - int16_t hangover_cnt_he1; + Word16 soft_hangover; + Word16 voiced_burst; + Word16 bcg_flux_init; + Word16 nb_active_frames_he1; + Word16 hangover_cnt_he1; Word16 prim_act_quick_fx; /*Q15 */ /* Noise estimator - primary activity quick */ Word16 prim_act_slow_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_fx; /*Q15 */ /* Noise estimator - primary activity slow rise quick fall */ @@ -217,22 +215,22 @@ typedef struct vad_structure Word16 prim_act_slow_he_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_he_fx; /*Q15 */ /* Q15 Noise estimator - primary activity slow rise quick fall */ - int16_t spectral_tilt_reset; - int16_t consec_inactive; + Word16 spectral_tilt_reset; + Word16 consec_inactive; Word16 ra_deltasum_fx; - int16_t trigger_SID; + Word16 trigger_SID; Word16 snr_sum_vad_fx; /*Q15 */ Word16 running_avg_fx; /*Q15 */ Word32 L_snr_sum_vad_fx; /*Q4*/ - int16_t hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ - int16_t vad_flag; /* VAD flag */ + Word16 hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ + Word16 vad_flag; /* VAD flag */ } VAD_DATA, *VAD_HANDLE; typedef struct cldfb_vad_structure { - int16_t bw_index; /* index of band width */ + Word16 bw_index; /* index of band width */ /* feature */ Word16 sp_center[SP_CENTER_NUM]; /* spectral center*/ @@ -248,8 +246,8 @@ typedef struct cldfb_vad_structure Word32 t_bg_energy; /* time background energy of several frames*/ Word16 scale_t_bg_energy; /* the Scaling of t_bg_energy*/ T_VAD_EXP t_bg_energy_sum; /* number of time background energy*/ - int16_t tbg_energy_count; /* sum of time background energy of several frames*/ - int16_t bg_update_count; /* time of background update*/ + Word16 tbg_energy_count; /* sum of time background energy of several frames*/ + Word16 bg_update_count; /* time of background update*/ Word32 frame_energy_smooth; /* smoothed energy of several frames*/ Word16 frame_energy_smooth_scale; /* the Scaling of frame_energy_smooth*/ @@ -268,14 +266,14 @@ typedef struct cldfb_vad_structure Word16 fg_energy_scale; /* the Scaling of fg_energy*/ Word32 bg_energy; /* background energy sum */ Word16 bg_energy_scale; /* the Scaling of bg_energy*/ - int16_t fg_energy_count; /* number of the foreground energy frame */ - int16_t bg_energy_count; /* number of the background energy frame */ + Word16 fg_energy_count; /* number of the foreground energy frame */ + Word16 bg_energy_count; /* number of the background energy frame */ Word32 fg_energy_est_start; /* flag by that indicate whether if estimate energy*/ - int16_t speech_flag; /* residual number of hangover 1 */ - int16_t continuous_noise_num; /* time of continuous noise frames*/ - int16_t continuous_speech_num; /* time of continuous speech frames*/ - int16_t continuous_speech_num2; /* time 2 of continuous speech frames*/ - int16_t frameloop; /* number of frame*/ + Word16 speech_flag; /* residual number of hangover 1 */ + Word16 continuous_noise_num; /* time of continuous noise frames*/ + Word16 continuous_speech_num; /* time of continuous speech frames*/ + Word16 continuous_speech_num2; /* time 2 of continuous speech frames*/ + Word16 frameloop; /* number of frame*/ Word16 tonality_rate3; /* tonality rate*/ Word16 music_background_rate; /* music background rate*/ Word32 lt_noise_sp_center_diff_sum; /* different sum of long time noise sp_center*/ @@ -283,10 +281,10 @@ typedef struct cldfb_vad_structure Word16 lt_noise_sp_center0; /* long time noise sp_center0*/ Word16 lt_noise_sp_center3; /* long time noise sp_center3*/ Word32 lt_bg_highf_eng; /* average of long time high frequency energy*/ - int16_t update_num_with_snr; /* the number of the background update with SNR*/ - int16_t update_count; - int16_t warm_hang_num; /* the number of hangover for warm up*/ - int16_t vad_flag_for_bk_update; + Word16 update_num_with_snr; /* the number of the background update with SNR*/ + Word16 update_count; + Word16 warm_hang_num; /* the number of hangover for warm up*/ + Word16 vad_flag_for_bk_update; } T_CldfbVadState, *VAD_CLDFB_HANDLE; @@ -326,7 +324,7 @@ typedef struct td_cng_enc_structure Word16 cng_buf_cnt; /* CNG and DTX - Counter of buffered CNG parameters */ Word16 cng_exc2_buf[HO_HIST_SIZE * L_FFT]; /* CNG and DTX - exc2 buffer for storing */ Word16 cng_Qexc_buf[HO_HIST_SIZE]; /* CNG and DTX - Q_exc buffer for storing */ - int32_t cng_brate_buf[HO_HIST_SIZE]; /* CNG and DTX - buffer for storing last_active_brate */ + Word32 cng_brate_buf[HO_HIST_SIZE]; /* CNG and DTX - buffer for storing last_active_brate */ Word16 CNG_att_fx; /* CNG and DTX - attenuation factor for CNG, in dB Q7 */ Word16 ho_16k_lsp[HO_HIST_SIZE]; /* CNG and DTX - 16k LSPs flags */ Word16 act_cnt2; /* CNG and DTX - counter of active frames for CNG_mode switching */ @@ -432,23 +430,23 @@ typedef struct dtx_enc_structure typedef struct igfscfenc_public_data_struct { - int16_t ptrBitIndex; - int16_t bitCount; - int16_t prev[64]; /* no more than 64 SCFs for the IGF energy envelope of one block */ - int16_t prevSave[64]; - int16_t scfCountLongBlock[IGF_NOF_GRIDS]; - int16_t t; - int16_t Tsave; - int16_t contex_saved; - const uint16_t *cf_se00; - const uint16_t *cf_se01; - int16_t cf_off_se01; - const uint16_t *cf_se02; - const int16_t *cf_off_se02; - const uint16_t *cf_se10; - int16_t cf_off_se10; - const uint16_t *cf_se11; - const int16_t *cf_off_se11; + Word16 ptrBitIndex; + Word16 bitCount; + Word16 prev[64]; /* no more than 64 SCFs for the IGF energy envelope of one block */ + Word16 prevSave[64]; + Word16 scfCountLongBlock[IGF_NOF_GRIDS]; + Word16 t; + Word16 Tsave; + Word16 contex_saved; + const UWord16 *cf_se00; + const UWord16 *cf_se01; + Word16 cf_off_se01; + const UWord16 *cf_se02; + const Word16 *cf_off_se02; + const UWord16 *cf_se10; + Word16 cf_off_se10; + const UWord16 *cf_se11; + const Word16 *cf_off_se11; Tastat acState; TastatEnc acState_fx; @@ -749,21 +747,21 @@ typedef struct acelp_cbkcorr_structure typedef struct gsc_enc_structure { - int16_t seed_tcx; /* AC mode (GSC) - seed for noise fill */ - int16_t cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - int16_t mem_last_pit_band; /* AC mode (GSC) - memory of the last band where pitch contribution was significant */ + Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ + Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ + Word16 mem_last_pit_band; /* AC mode (GSC) - memory of the last band where pitch contribution was significant */ Word16 mem_w0_tmp_fx; Word16 mem_syn_tmp_fx[M]; Word16 mid_dyn_fx; /* AC mode (GSC) - signal dynamic Q7 */ - int16_t noise_lev; /* AC mode (GSC) - noise level */ - int16_t past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ + Word16 noise_lev; /* AC mode (GSC) - noise level */ + Word16 past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ Word32 Last_frame_ener_fx; /* AC mode (GSC) - Last frame energy */ - int16_t pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ + Word16 pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous exciation */ Word16 Q_last_exc_dct_in; - Word16 last_ener_fx; /* AC mode (GSC) - previous energy Q0 */ - int16_t last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - Word16 lt_gpitch_fx; /* Q15 */ + Word16 last_ener_fx; /* AC mode (GSC) - previous energy Q0 */ + Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ + Word16 lt_gpitch_fx; /* Q15 */ } GSC_ENC_DATA, *GSC_ENC_HANDLE; @@ -804,14 +802,14 @@ typedef struct hq_enc_structure /* PVQ range coder state */ typedef struct pvq_enc_structure { - uint32_t rc_low; - uint32_t rc_range; - int16_t rc_cache; - int16_t rc_carry; - int16_t rc_carry_count; - int16_t rc_num_bits; - int16_t rc_tot_bits; - int16_t rc_offset; + UWord32 rc_low; + UWord32 rc_range; + Word16 rc_cache; + Word16 rc_carry; + Word16 rc_carry_count; + Word16 rc_num_bits; + Word16 rc_tot_bits; + Word16 rc_offset; } PVQ_ENC_DATA, *PVQ_ENC_HANDLE; @@ -838,33 +836,33 @@ typedef struct sc_vbr_enc_structure Word16 nelp_lp_fit_mem[NELP_LP_ORDER * 2]; /* Q(prev_Q_new) */ Word32 bp1_filt_mem_nb_fx[14]; /* Q(qprevGain_fx) */ - int16_t nelp_enc_seed; + Word16 nelp_enc_seed; Word16 nelp_gain_mem_fx; /* Q0 */ - int16_t last_nelp_mode; - int16_t nelp_mode; + Word16 last_nelp_mode; + Word16 nelp_mode; Word16 qprevIn_fx; Word16 qprevGain_fx; /* PPP variables */ - int16_t pppcountE; - int16_t bump_up; - int16_t last_ppp_mode; - int16_t last_last_ppp_mode; - int16_t ppp_mode; + Word16 pppcountE; + Word16 bump_up; + Word16 last_ppp_mode; + Word16 last_last_ppp_mode; + Word16 ppp_mode; Word16 prev_ppp_gain_pit_fx; /* Q14 */ Word16 prev_tilt_code_fx; /* Q15 */ /* voiced encoder variables */ - int16_t firstTime_voicedenc; + Word16 firstTime_voicedenc; /* DTFS variables */ Word16 dtfs_enc_a_fx[MAXLAG_WI]; /* Q(dtfs_enc_Q) */ Word16 dtfs_enc_b_fx[MAXLAG_WI]; /* Q(dtfs_enc_Q) */ - int16_t dtfs_enc_lag; - int16_t dtfs_enc_nH; - int16_t dtfs_enc_nH_4kHz; + Word16 dtfs_enc_lag; + Word16 dtfs_enc_nH; + Word16 dtfs_enc_nH_4kHz; Word16 dtfs_enc_upper_cut_off_freq_of_interest_fx; /* Q0 */ Word16 dtfs_enc_upper_cut_off_freq_fx; /* Q0 */ Word16 dtfs_enc_Q; @@ -876,23 +874,23 @@ typedef struct sc_vbr_enc_structure Word16 lasterbE_fx[NUM_ERB_WB]; /* Previous Amplitude spectrum (ERB) Q13 */ Word16 Q_prev_cw_en_fx; - int16_t mode_QQF; - int16_t rate_control; + Word16 mode_QQF; + Word16 rate_control; Word16 SNR_THLD_fx; /* Q8 */ - int16_t Q_to_F; - int16_t pattern_m; - int16_t patterncount; - int16_t Last_Resort; - int16_t numactive; /* keep the count of the frames inside current 600 frame block */ + Word16 Q_to_F; + Word16 pattern_m; + Word16 patterncount; + Word16 Last_Resort; + Word16 numactive; /* keep the count of the frames inside current 600 frame block */ Word32 sum_of_rates_fx; /*Q=13 sum of the rates of past 600 active frames*/ Word32 global_avr_rate_fx; /*Q=13 global rate upto current time. recorded a (rate in kbps) *6000*/ - int16_t global_frame_cnt; /* 600 active frame block count. Used to update the global rate */ - int16_t set_ppp_generic; - int16_t avoid_HQ_VBR_NB; + Word16 global_frame_cnt; /* 600 active frame block count. Used to update the global rate */ + Word16 set_ppp_generic; + Word16 avoid_HQ_VBR_NB; - int16_t vbr_generic_ho; - int16_t Local_VAD; - int16_t last_7k2_coder_type; + Word16 vbr_generic_ho; + Word16 Local_VAD; + Word16 last_7k2_coder_type; } SC_VBR_ENC_DATA, *SC_VBR_ENC_HANDLE; @@ -910,7 +908,7 @@ typedef struct amrwb_io_enc_structure Word16 mem_hp400_enc_fx[6]; Word16 mem_hf_enc_fx[L_FIR - 1]; Word16 mem_syn_hf_enc_fx[M]; - int16_t seed2_enc; + Word16 seed2_enc; } AMRWB_IO_ENC_DATA, *AMRWB_IO_ENC_HANDLE; @@ -944,7 +942,7 @@ typedef struct td_bwe_enc_structure Word16 state_syn_shbexc_fx[L_SHB_LAHEAD]; /* Q(prev_Q_bwe_exc - 16) */ Word16 state_lpc_syn_fx[LPC_SHB_ORDER]; /* Q(prev_Q_bwe_exc - 16) */ Word16 old_bwe_exc_fx[PIT16k_MAX * 2]; /*Q_exc*/ - int16_t bwe_seed[2]; + Word16 bwe_seed[2]; Word32 bwe_non_lin_prev_scale_fx; /* Q30 */ Word16 old_bwe_exc_extended_fx[NL_BUFF_OFFSET]; /* Q(prev_Q_bwe_exc - 16) */ Word16 syn_overlap_fx[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain */ @@ -964,7 +962,7 @@ typedef struct td_bwe_enc_structure Word16 shb_inv_filt_mem_fx[LPC_SHB_ORDER]; /* Q(Q_shb_spch) */ Word16 lsp_shb_spacing_fx[3]; /* Q15 */ Word16 prev_swb_GainShape_fx; /* Q15 */ - int16_t prev_frGainAtten; + Word16 prev_frGainAtten; Word16 prev_wb_GainShape; /* Q15 */ Word16 swb_lsp_prev_interp_fx[LPC_SHB_ORDER]; /* Q15 */ @@ -973,25 +971,25 @@ typedef struct td_bwe_enc_structure Word16 fb_tbe_demph_fx; Word16 tilt_mem_fx; /* Q12 */ - int16_t prev_coder_type; + Word16 prev_coder_type; Word16 prev_lsf_diff_fx[LPC_SHB_ORDER - 2]; /* Q15 */ Word16 prev_tilt_para_fx; /* Q10 */ Word16 cur_sub_Aq_fx[M + 1]; /* Q12 */ /* quantized data */ - int16_t lsf_idx[NUM_Q_LSF]; - int16_t m_idx; - int16_t grid_idx; - int16_t idxSubGains; - int16_t idxFrameGain; - int16_t idx_shb_fr_gain; - int16_t idx_res_gs[NB_SUBFR16k]; - int16_t idx_mixFac; - - int16_t lsf_WB; - int16_t gFrame_WB; - - int16_t idxGain; + Word16 lsf_idx[NUM_Q_LSF]; + Word16 m_idx; + Word16 grid_idx; + Word16 idxSubGains; + Word16 idxFrameGain; + Word16 idx_shb_fr_gain; + Word16 idx_res_gs[NB_SUBFR16k]; + Word16 idx_mixFac; + + Word16 lsf_WB; + Word16 gFrame_WB; + + Word16 idxGain; Word16 dec_2_over_3_mem_fx[L_FILT_2OVER3]; Word16 dec_2_over_3_mem_lp_fx[6]; @@ -1041,9 +1039,9 @@ typedef struct fd_bwe_enc_structure typedef struct rf_enc_structure { - int16_t rf_frame_type; - int16_t rf_targetbits_buff[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_frametype[MAX_RF_FEC_OFFSET]; + Word16 rf_frame_type; + Word16 rf_targetbits_buff[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_frametype[MAX_RF_FEC_OFFSET]; ACELP_config acelp_cfg_rf; /* configuration for RF frame */ @@ -1054,31 +1052,31 @@ typedef struct rf_enc_structure struct dispMem_fx rf_dm_fx; Word32 rf_gc_threshold; - int16_t rf_target_bits; + Word16 rf_target_bits; Word16 rf_tilt_buf[NB_SUBFR16k]; - int16_t rf_indx_lsf[MAX_RF_FEC_OFFSET][3]; - int16_t rf_indx_pitch[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_fcb[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_gain[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_EsPred[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_ltfMode[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_lsf[MAX_RF_FEC_OFFSET][3]; + Word16 rf_indx_pitch[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_fcb[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_gain[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_EsPred[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_ltfMode[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_nelp_fid[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_nelp_iG1[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_nelp_iG2[MAX_RF_FEC_OFFSET][2]; + Word16 rf_indx_nelp_fid[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_nelp_iG1[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_nelp_iG2[MAX_RF_FEC_OFFSET][2]; - int16_t rf_indx_tbeGainFr[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_tbeGainFr[MAX_RF_FEC_OFFSET]; - int16_t rf_tcxltp_pitch_int_past; - int16_t rf_last_tns_active; - int16_t rf_second_last_tns_active; - int16_t rf_second_last_core; - int16_t rf_clas[MAX_RF_FEC_OFFSET]; - int16_t rf_gain_tcx[MAX_RF_FEC_OFFSET]; - int16_t rf_tcxltp_param[MAX_RF_FEC_OFFSET]; + Word16 rf_tcxltp_pitch_int_past; + Word16 rf_last_tns_active; + Word16 rf_second_last_tns_active; + Word16 rf_second_last_core; + Word16 rf_clas[MAX_RF_FEC_OFFSET]; + Word16 rf_gain_tcx[MAX_RF_FEC_OFFSET]; + Word16 rf_tcxltp_param[MAX_RF_FEC_OFFSET]; - int16_t RF_bwe_gainFr_ind; + Word16 RF_bwe_gainFr_ind; } RF_ENC_DATA, *RF_ENC_HANDLE; @@ -1088,17 +1086,17 @@ typedef struct rf_enc_structure typedef struct plc_enc_evs_structure { - int16_t nBits; /* number of bits */ + Word16 nBits; /* number of bits */ Word16 Q_new; Word16 Q_exp; - int16_t enableGplc; - int16_t T0_4th; - int16_t T0; - int16_t calcOnlylsf; - int16_t pit_min; - int16_t pit_max; + Word16 enableGplc; + Word16 T0_4th; + Word16 T0; + Word16 calcOnlylsf; + Word16 pit_min; + Word16 pit_max; Word16 mem_MA_14Q1[M]; Word16 mem_AR[M]; @@ -1131,8 +1129,8 @@ typedef struct tec_enc_structure Word16 loTempEnv[CLDFB_NO_COL_MAX]; /* Q7 */ Word16 loTempEnv_ns[CLDFB_NO_COL_MAX]; /* Q7 */ Word16 hiTempEnv[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV]; /* Q7 */ - int16_t tranFlag; - int16_t corrFlag; + Word16 tranFlag; + Word16 corrFlag; } TEC_ENC_DATA, *TEC_ENC_HANDLE; @@ -1143,63 +1141,63 @@ typedef struct tec_enc_structure typedef struct tcx_enc_structure { - int16_t L_frameTCX; + Word16 L_frameTCX; - int16_t tcxMode; /* Chosen TCX mode for this frame */ - int16_t transform_type[2]; /* TCX20/10/5 mode in each subframe */ + Word16 tcxMode; /* Chosen TCX mode for this frame */ + Word16 transform_type[2]; /* TCX20/10/5 mode in each subframe */ /* Core Signal Analysis Outputs */ Word16 noiseTiltFactor; /* compensation for LPC tilt in noise filling Q15 */ - int16_t noiseLevelMemory_cnt; /* counter of consecutive low TCX noise levels */ + Word16 noiseLevelMemory_cnt; /* counter of consecutive low TCX noise levels */ Word16 ltpGainMemory_fx[N_LTP_GAIN_MEMS]; /* for smoothing noiseTransWidth Q15 */ STnsData tnsData[2]; - // int16_t fUseTns[2]; + // Word16 fUseTns[2]; Word8 fUseTns[2]; - int16_t bTnsOnWhithenedSpectra[2]; + Word16 bTnsOnWhithenedSpectra[2]; - // int16_t memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ + // Word16 memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ Word8 memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ Word16 *speech_TCX; Word16 *new_speech_TCX; // Word16 q_speech_TCX; - int16_t tcxltp; - int16_t tcxltp_pitch_int; - int16_t tcxltp_pitch_fr; + Word16 tcxltp; + Word16 tcxltp_pitch_int; + Word16 tcxltp_pitch_fr; Word16 tcxltp_gain; /* Q15 */ - int16_t tcxltp_pitch_int_past; - int16_t tcxltp_pitch_fr_past; + Word16 tcxltp_pitch_int_past; + Word16 tcxltp_pitch_fr_past; Word16 tcxltp_gain_past; /* Q15 */ Word16 tcxltp_norm_corr_past; /* Q15 */ Word16 tcxltp_norm_corr_mem; /* Q15 */ Word16 kernel_switch_corr_past; /* Q15 */ - uint16_t kernel_type[2]; /* transform kernel type in each subframe (MDCT or MDST) */ - uint16_t kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ - uint16_t enc_ste_pre_corr_past; + UWord16 kernel_type[2]; /* transform kernel type in each subframe (MDCT or MDST) */ + UWord16 kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ + UWord16 enc_ste_pre_corr_past; Word32 tfm_mem_fx; /* state of IIR filtered temporal flatness measure Q31 */ Word16 buf_speech_ltp[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; Word16 exp_buf_speech_ltp; Word16 *speech_ltp; Word16 *new_speech_ltp; - int16_t tcxltp_filt_idx; - int16_t tcxltp_bits; - int16_t tcxltp_param[LTPSIZE]; - int16_t tcxltp_on_mem; + Word16 tcxltp_filt_idx; + Word16 tcxltp_bits; + Word16 tcxltp_param[LTPSIZE]; + Word16 tcxltp_on_mem; Word16 measuredBwRatio; /* measured bw; used for TCX noise-filling. 1Q14 */ - int16_t nmStartLine; /* Starting line for the noise measurement */ + Word16 nmStartLine; /* Starting line for the noise measurement */ - int16_t tcx_lpc_shaped_ari; + Word16 tcx_lpc_shaped_ari; Word16 old_out_fx[L_FRAME32k]; /* buffer for OLA; at the encoder, the maximum length is L_FRAME32k (corresponds to maximum internal L_frame length) */ Word16 Q_old_out; /* MDCT switching */ Word16 prev_hi_ener; /* Q8 */ - int16_t prev_hi_sparse; + Word16 prev_hi_sparse; Word16 clas_sec_old_fx; /* Q13 */ - int16_t clas_final_old; + Word16 clas_final_old; Word32 last_gain1; /* Q(31 - st->last_enerBuffer_exp) */ Word32 last_gain2; /* Q(31 - st->last_enerBuffer_exp) */ @@ -1209,7 +1207,7 @@ typedef struct tcx_enc_structure Word16 q_Txnq; Word16 tcx_target_bits_fac; /* Q14 */ - int16_t tns_ms_flag[2]; + Word16 tns_ms_flag[2]; Word32 *spectrum_fx[2]; /* MDCT output for a short block */ Word16 spectrum_e[2]; Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ @@ -1241,9 +1239,9 @@ typedef struct enc_core_structure Word16 idchan; /* channel ID (audio channel number) */ Word16 id_element; /* element ID */ - int16_t element_mode; /* element mode */ + Word16 element_mode; /* element mode */ Word16 last_element_mode; /* element mode */ - int32_t element_brate; /* element bitrate */ + Word32 element_brate; /* element bitrate */ Word16 extl_orig; /* extension layer */ Word32 extl_brate_orig; /* extension layer bitrate */ Word16 codec_mode; /* Mode1 or Mode2 */ @@ -1257,40 +1255,40 @@ typedef struct enc_core_structure BSTR_ENC_HANDLE hBstr; /* encoder bitstream handle */ Word16 last_enerBuffer_exp; - int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME) */ - Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ - - int32_t input_Fs; /* input signal sampling frequency in Hz */ - int32_t total_brate; /* total bitrate in kbps of the codec */ - int32_t last_total_brate; /* last frame's total bitrate in kbps of the codec */ - int32_t last_total_brate_cng; /* last inactive frame's total bitrate in kbps of the codec */ - int16_t core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ - int16_t last_core; /* previous frame core */ - int16_t coder_type; /* core coder type */ - int16_t flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ - int32_t core_brate; /* core bitrate */ - int32_t last_core_brate; /* previous frame core bitrate */ - int16_t extl; /* extension layer */ - int16_t last_extl; /* previous extension layer */ - int32_t extl_brate; /* extension layer bitrate */ - int16_t input_bwidth; /* input signal bandwidth */ - int16_t bwidth; /* encoded bandwidth NB, WB, SWB or FB */ - int16_t max_bwidth; /* maximum encoded bandwidth */ - int16_t last_input_bwidth; /* input signal bandwidth in the previous frame */ - int16_t last_bwidth; /* coded bandwidth in the previous frame */ - int16_t last_bwidth_cng; /* coded bandwidth in the previous inactive frame */ - int16_t bwidth_sw_cnt; /* bandwidth switching counter */ - int16_t L_frame; /* ACELP core internal frame length */ - int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - int16_t Opt_DTX_ON; /* flag indicating DTX operation */ - int16_t cng_type; /* flag indicating LP or CLDFB based SID/CNG */ - int16_t cng_sba_flag; /* flag indicating CNG/SID for SBA 2TC */ - int16_t Opt_SC_VBR; /* flag indicating SC-VBR mode */ - int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ - int16_t low_rate_mode; /* low-rate mode flag */ - int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ + Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME) */ + Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ + + Word32 input_Fs; /* input signal sampling frequency in Hz */ + Word32 total_brate; /* total bitrate in kbps of the codec */ + Word32 last_total_brate; /* last frame's total bitrate in kbps of the codec */ + Word32 last_total_brate_cng; /* last inactive frame's total bitrate in kbps of the codec */ + Word16 core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ + Word16 last_core; /* previous frame core */ + Word16 coder_type; /* core coder type */ + Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ + Word32 core_brate; /* core bitrate */ + Word32 last_core_brate; /* previous frame core bitrate */ + Word16 extl; /* extension layer */ + Word16 last_extl; /* previous extension layer */ + Word32 extl_brate; /* extension layer bitrate */ + Word16 input_bwidth; /* input signal bandwidth */ + Word16 bwidth; /* encoded bandwidth NB, WB, SWB or FB */ + Word16 max_bwidth; /* maximum encoded bandwidth */ + Word16 last_input_bwidth; /* input signal bandwidth in the previous frame */ + Word16 last_bwidth; /* coded bandwidth in the previous frame */ + Word16 last_bwidth_cng; /* coded bandwidth in the previous inactive frame */ + Word16 bwidth_sw_cnt; /* bandwidth switching counter */ + Word16 L_frame; /* ACELP core internal frame length */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_DTX_ON; /* flag indicating DTX operation */ + Word16 cng_type; /* flag indicating LP or CLDFB based SID/CNG */ + Word16 cng_sba_flag; /* flag indicating CNG/SID for SBA 2TC */ + Word16 Opt_SC_VBR; /* flag indicating SC-VBR mode */ + Word16 last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ + Word16 low_rate_mode; /* low-rate mode flag */ + Word16 inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ #ifdef DEBUGGING - int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ + Word16 force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ #ifdef DEBUG_FORCE_DIR char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ #endif @@ -1328,13 +1326,13 @@ typedef struct enc_core_structure * ACELP core parameters *----------------------------------------------------------------------------------*/ - int16_t clas; /* current frame clas */ - int16_t last_clas; /* previous frame signal classification */ + Word16 clas; /* current frame clas */ + Word16 last_clas; /* previous frame signal classification */ Word16 prev_fmerit; /* previous signal classification score Q15 */ Word16 fmerit_dt; /* signal classification score difference Q15 */ - int16_t Nb_ACELP_frames; + Word16 Nb_ACELP_frames; - int16_t pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ + Word16 pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ // Word16 pitch_fx[3]; Word16 voicing_fx[3]; /* open-loop normalized correlation values for three half-frames Q15 */ @@ -1348,7 +1346,7 @@ typedef struct enc_core_structure Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame Qlog2(2.56) */ Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz Q15 */ Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz Q15 */ - int16_t pstreaklen; /* LSF quantizer */ + Word16 pstreaklen; /* LSF quantizer */ Word16 streaklimit_fx; /* LSF quantizer Q15 */ Word16 stab_fac_fx; /* LSF stability factor Q15 */ Word16 clip_var_fx[6]; /* pitch gain clipping memory [2.56x,Q14,Q8,Q0,Q14,Q14] */ @@ -1375,42 +1373,42 @@ typedef struct enc_core_structure Word16 mem_deemph_fx; /* deemphasis filter memory */ Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ - int16_t GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ - int16_t GSC_IVAS_mode; + Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ + Word16 GSC_IVAS_mode; GSC_ENC_HANDLE hGSCEnc; - int16_t Last_pulse_pos; /* FEC - last position of the first glottal pulse in the frame */ + Word16 Last_pulse_pos; /* FEC - last position of the first glottal pulse in the frame */ Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame Qlog2(2.56) */ Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame Qlog2(2.56) */ Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC Qlog2(2.56) */ - int16_t next_force_safety_net; /* FEC - flag to force safety net in next frame */ + Word16 next_force_safety_net; /* FEC - flag to force safety net in next frame */ // Word16 next_force_safety_net_fx; /* FEC - flag to force safety net in next frame */ - int16_t uv_count; /* Stationary noise UV modification - unvoiced counter */ - int16_t act_count; /* Stationary noise UV modification - activation counter */ + Word16 uv_count; /* Stationary noise UV modification - unvoiced counter */ + Word16 act_count; /* Stationary noise UV modification - activation counter */ Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain Q(GE_SHIFT) */ Word16 lspold_s_fx[M]; /* Stationary noise UV modification - old LSP vector Q15 */ - int16_t noimix_seed; /* Stationary noise UV modification - mixture seed */ + Word16 noimix_seed; /* Stationary noise UV modification - mixture seed */ Word16 min_alpha_fx; /* Stationary noise UV modification - minimum alpha Q15 */ Word16 exc_pe_fx; /* Stationary noise UV modification - memory of the preemphasis filter */ - int16_t coder_type_raw; /* raw coder_type (before UNVOICED is lost) */ - int16_t last_coder_type_raw; /* raw last_coder_type (coming from the sigal classification) */ - int16_t last_coder_type; /* previous coding type */ + Word16 coder_type_raw; /* raw coder_type (before UNVOICED is lost) */ + Word16 last_coder_type_raw; /* raw last_coder_type (coming from the sigal classification) */ + Word16 last_coder_type; /* previous coding type */ Word16 old_thres_fx; /* normalized correlation weighting in open-loop pitch Q14 */ Word16 old_corr_fx; /* normalized correlation in previous frame (mean value) Q15 */ - int16_t old_pitch; /* previous pitch for open-loop pitch search */ - int16_t delta_pit; /* open-loop pitch extrapolation correction */ + Word16 old_pitch; /* previous pitch for open-loop pitch search */ + Word16 delta_pit; /* open-loop pitch extrapolation correction */ Word32 ee_old_fx; /* previous frame low/high frequency energy ratio Q6 */ - int16_t min_band; /* minimum critical band of useful bandwidth */ - int16_t max_band; /* maximum critical band of useful bandwidth */ - int16_t tc_cnt; /* TC frame counter */ - int16_t audio_frame_cnt; /* Counter of relative presence of audio frames */ + Word16 min_band; /* minimum critical band of useful bandwidth */ + Word16 max_band; /* maximum critical band of useful bandwidth */ + Word16 tc_cnt; /* TC frame counter */ + Word16 audio_frame_cnt; /* Counter of relative presence of audio frames */ Word32 old_dE1_fx; /* Maximum energy increase in previous frame Q13 */ - int16_t old_ind_deltaMax; /* Index of the sub-subframe of maximum energy in previous frame */ + Word16 old_ind_deltaMax; /* Index of the sub-subframe of maximum energy in previous frame */ Word32 old_enr_ssf_fx[2 * NB_SSF]; /* Maxima of energies per sub-subframes of previous frame */ - int16_t spike_hyst; /* Hysteresis to prevent UC after sharp energy spike */ - int16_t last_harm_flag_acelp; /* harmonicity flag for ACELP @32kbps rate */ + Word16 spike_hyst; /* Hysteresis to prevent UC after sharp energy spike */ + Word16 last_harm_flag_acelp; /* harmonicity flag for ACELP @32kbps rate */ Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ Word16 old_Es_pred_fx; /* old Es_pred for core switching Q8 */ Word16 music_hysteresis_fx; /* Counter of frames after AUDIO coding mode to prevent UC */ @@ -1433,7 +1431,7 @@ typedef struct enc_core_structure Word16 voicing0_sm_fx; Word16 voicing_sm_fx; Word16 LF_EnergyRatio_sm_fx; - int16_t predecision_flag; + Word16 predecision_flag; Word32 diff_sm_fx; /* Q7 */ Word32 energy_sm_fx; /* Q7 */ @@ -1492,9 +1490,9 @@ typedef struct enc_core_structure Word16 lgBin_E_fx[L_FFT / 2]; /* Q8 per bin energy of two frames */ - int16_t sp_aud_decision0; /* 1st stage speech/music decision flag */ - int16_t sp_aud_decision1; /* 1st stage speech/music classification flag */ - int16_t sp_aud_decision2; /* 2nd stage speech/music classification flag */ + Word16 sp_aud_decision0; /* 1st stage speech/music decision flag */ + Word16 sp_aud_decision1; /* 1st stage speech/music classification flag */ + Word16 sp_aud_decision2; /* 2nd stage speech/music classification flag */ /*----------------------------------------------------------------------------------* * VAD/DTX/CNG @@ -1505,9 +1503,9 @@ typedef struct enc_core_structure VAD_CLDFB_HANDLE hVAD_CLDFB; T_CldfbVadState vad_st; - int16_t vad_flag; /* i : VAD flag */ - int16_t sharpFlag; - int16_t localVAD; /* i : local VAD flag */ + Word16 vad_flag; /* i : VAD flag */ + Word16 sharpFlag; + Word16 localVAD; /* i : local VAD flag */ Word32 bckr_tilt_lt; /* Q16 */ Word16 lp_speech_fx; /* Q8 */ @@ -1517,7 +1515,7 @@ typedef struct enc_core_structure Word16 voicing_old_fx; Word16 var_SID_rate_flag_fx; /* CNG and DTX - flag for variable SID rate */ Word16 interval_SID_fx; - int16_t active_cnt; /* counter of active frames */ + Word16 active_cnt; /* counter of active frames */ TD_CNG_ENC_HANDLE hTdCngEnc; @@ -1544,10 +1542,10 @@ typedef struct enc_core_structure *----------------------------------------------------------------------------------*/ HANDLE_FD_CNG_ENC hFdCngEnc; - int16_t fd_cng_reset_flag; + Word16 fd_cng_reset_flag; Word16 last_totalNoise_fx; /* Q8 */ Word16 totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE]; /* Q8 */ - int16_t totalNoise_increase_len; + Word16 totalNoise_increase_len; /*----------------------------------------------------------------------------------* * SC-VBR parameters @@ -1564,7 +1562,7 @@ typedef struct enc_core_structure Word16 old_hpfilt_out_fx; Word32 EnergyLT_fx; /* Q(EnergyLT_fx_exp) */ Word32 Energy_Old_fx; - int16_t TransientHangOver; + Word16 TransientHangOver; HQ_ENC_HANDLE hHQ_core; /* HQ core encoder handle */ @@ -1588,21 +1586,21 @@ typedef struct enc_core_structure Word16 lt_mean_NB_fx; /* Q11 */ Word16 lt_mean_WB_fx; /* Q11 */ Word16 lt_mean_SWB_fx; /* Q11 */ - int16_t count_WB; - int16_t count_SWB; - int16_t count_FB; + Word16 count_WB; + Word16 count_SWB; + Word16 count_FB; /*----------------------------------------------------------------------------------* * Channel-aware mode *----------------------------------------------------------------------------------*/ - int16_t rf_mode; /* flag to signal the RF mode */ - int16_t rf_mode_last; - int16_t last_rf_mode_cng; - int16_t Opt_RF_ON; - int16_t rf_fec_offset; - int16_t rf_target_bits_write; - int16_t rf_fec_indicator; + Word16 rf_mode; /* flag to signal the RF mode */ + Word16 rf_mode_last; + Word16 last_rf_mode_cng; + Word16 Opt_RF_ON; + Word16 rf_fec_offset; + Word16 rf_target_bits_write; + Word16 rf_fec_indicator; RF_ENC_HANDLE hRF; /* RF encoder handle */ @@ -1650,17 +1648,17 @@ typedef struct enc_core_structure Word16 *wspeech_enc; // exp_buf_wspeech_enc Word16 *synth; - int16_t enableTcxLpc; /* global toggle for the TCX LPC quantizer */ - int16_t envWeighted; /* are is{p,f}_old_q[] weighted or not? */ + Word16 enableTcxLpc; /* global toggle for the TCX LPC quantizer */ + Word16 envWeighted; /* are is{p,f}_old_q[] weighted or not? */ - int16_t acelpEnabled; /* Flag indicating if ACELP can be used */ - int16_t tcx10Enabled; /* Flag indicating if TCX 10 can be used */ - int16_t tcx20Enabled; /* Flag indicating if TCX 20 can be used */ + Word16 acelpEnabled; /* Flag indicating if ACELP can be used */ + Word16 tcx10Enabled; /* Flag indicating if TCX 10 can be used */ + Word16 tcx20Enabled; /* Flag indicating if TCX 20 can be used */ Word16 mem_wsp_enc; /* wsp vector memory */ - int16_t nb_bits_header_ace; /* number of bits for the header */ - int16_t nb_bits_header_tcx; /* number of bits for the header */ + Word16 nb_bits_header_ace; /* number of bits for the header */ + Word16 nb_bits_header_tcx; /* number of bits for the header */ Word16 preemph_fac; /*Preemphasis factor Q15*/ Word16 gamma; /* Q15 */ @@ -1669,7 +1667,7 @@ typedef struct enc_core_structure TRAN_DET_HANDLE hTranDet; TransientDetection transientDetection; Word16 transient_info[3]; - int16_t acelpFramesCount; + Word16 acelpFramesCount; Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E Q7 in EVS */ /* Q4 in IVAS */ // float currEnergyLookAhead; @@ -1684,34 +1682,34 @@ typedef struct enc_core_structure Word16 parcorr[2]; Word16 parcorr_mid[2]; - int16_t lpcQuantization; + Word16 lpcQuantization; Word16 numlpc; - int16_t encoderLookahead_enc; - int16_t encoderPastSamples_enc; - int16_t encoderLookahead_FB; + Word16 encoderLookahead_enc; + Word16 encoderPastSamples_enc; + Word16 encoderLookahead_FB; /* pitch_ol for adaptive lag window */ - int16_t old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ + Word16 old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ Word16 old_voicing_la; /* past open loop pitch gain from look-ahead */ Word32 band_energies[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor MODE2_E_MIN */ Word16 band_energies_exp; /* exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */ - int16_t acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ + Word16 acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ - int16_t pit_min; - int16_t pit_fr1; - int16_t pit_fr1b; - int16_t pit_fr2; - int16_t pit_max; - int16_t pit_res_max; + Word16 pit_min; + Word16 pit_fr1; + Word16 pit_fr1b; + Word16 pit_fr2; + Word16 pit_max; + Word16 pit_res_max; /* for FAC */ - int16_t L_frame_past; + Word16 L_frame_past; /*Adaptive BPF*/ - int16_t bpf_gain_param; + Word16 bpf_gain_param; Word32 mem_bpf_fx1[2 * L_FILT16k]; Word32 mem_error_bpf_fx[2 * L_FILT16k]; Word16 bpf_T[NB_SUBFR16k]; @@ -1726,24 +1724,24 @@ typedef struct enc_core_structure Word16 noise_shift_old; } mem_bpf_fx; - int16_t glr; - int16_t glr_idx[2]; + Word16 glr; + Word16 glr_idx[2]; Word32 mean_gc[2]; /* Q15 */ Word16 prev_lsf4_mean; /* Qlog2(2.56) */ - int16_t glr_reset; - int32_t last_sr_core; + Word16 glr_reset; + Word32 last_sr_core; Word16 last_stab_fac; /* Q15 */ Word32 gain_code[NB_SUBFR16k]; /*for rate switching*/ - int16_t rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ - int16_t rate_switching_reset_16kHz; + Word16 rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ + Word16 rate_switching_reset_16kHz; - int16_t enablePlcWaveadjust; - int16_t Tonal_SideInfo; + Word16 enablePlcWaveadjust; + Word16 Tonal_SideInfo; - int16_t seed_acelp; + Word16 seed_acelp; PLC_ENC_EVS_HANDLE hPlcExt; @@ -1752,23 +1750,23 @@ typedef struct enc_core_structure *----------------------------------------------------------------------------------*/ IGF_ENC_INSTANCE_HANDLE hIGFEnc; /* IGF encoder handle */ - int16_t igf; + Word16 igf; /*----------------------------------------------------------------------------------* * TEC *----------------------------------------------------------------------------------*/ - int16_t tec_tfa; + Word16 tec_tfa; TEC_ENC_HANDLE hTECEnc; /* TEC encoder handle */ - int16_t tec_flag; - int16_t tfa_flag; + Word16 tec_flag; + Word16 tfa_flag; Word32 tfa_enr[N_TEC_TFA_SUBFR]; /*---------------------------------------------------------------* * IVAS parameters *---------------------------------------------------------------*/ - int16_t tdm_LRTD_flag; /* LRTD stereo mode flag */ + Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ Word16 cna_dirac_flag; /* CNA in DirAC flag */ /* stereo switching memories */ @@ -1813,24 +1811,24 @@ typedef struct enc_core_structure Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; Word16 prev_lsp_wb_temp_fx[LPC_SHB_ORDER_WB]; - int16_t sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ + Word16 sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ } Encoder_State, *ENC_CORE_HANDLE; typedef struct GainItemStr { - int16_t gainIndex; + Word16 gainIndex; } GainItem; typedef struct context_rc_mem_struct { - int16_t nbits_old; - int16_t ctx; + Word16 nbits_old; + Word16 ctx; Word64 bit_estimate_fx; /* Q23 */ - int16_t rateFlag; - int16_t lastnz; - int16_t nt_half; + Word16 rateFlag; + Word16 lastnz; + Word16 nt_half; } RC_CONTEXT_MEM, *HANDLE_RC_CONTEXT_MEM; diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 2ca0b6d74..b1a3f2f20 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -282,7 +282,7 @@ void wb_bwe_enc_ivas_fx( *-------------------------------------------------------------------*/ void swb_bwe_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ + const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 3bad5fa7f..7bbc54780 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1390,7 +1390,7 @@ void swb_pre_proc_ivas_fx( } /* Dirty downsampling to match Nyquist to upper frequency limit of target */ - lerp( st->input_fx, new_swb_speech, L_resamp, (int16_t) Mpy_32_32( input_Fs, one_by_50_Q31 ) ); + lerp( st->input_fx, new_swb_speech, L_resamp, extract_l( Mpy_32_32( input_Fs, one_by_50_Q31 ) ) ); /* flip the spectrum */ Copy( new_swb_speech, spchTmp, L_resamp ); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 2a6f040ac..7247b6446 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -48,14 +48,12 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, Word8 *noiseFlags, Word16 lowpassLine ) { - Word16 i, lastTone; + Word16 i, lastTone, j; Word32 s, c; Word16 tmp16; Word32 tmp1, tmp2 = 0; /* initialization only to avoid compiler warning, not counted */ move32(); - int j; - IF( resetMemory != 0 ) { FOR( i = 0; i < lowpassLine; i++ ) @@ -81,7 +79,7 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, i = sub( startLine, 1 ); s = 0; move32(); - for ( j = -7; j < 8; j++ ) + FOR( j = -7; j < 8; j++ ) { s = L_add( s, L_shr( powerSpec[i + j], 4 ) ); } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 82d24ceba..3c88ca224 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -1288,7 +1288,7 @@ static void UpdateDelayBuffer( Word16 const *input, Word16 nSamplesAvailable, De move16(); nDelay = pDelayBuffer->nDelay; - assert( ( nDelay >= 0 ) && ( nDelay <= (int) sizeof( pDelayBuffer->buffer ) / (int) sizeof( pDelayBuffer->buffer[0] ) ) ); + assert( ( nDelay >= 0 ) && ( nDelay <= (Word32) sizeof( pDelayBuffer->buffer ) / (Word32) sizeof( pDelayBuffer->buffer[0] ) ) ); assert( nSamplesAvailable <= NSUBBLOCKS * pDelayBuffer->nSubblockSize ); /* If this is not the last frame */ IF( EQ_16( nSamplesAvailable, imult1616( NSUBBLOCKS, pDelayBuffer->nSubblockSize ) ) ) @@ -1307,7 +1307,7 @@ static void UpdateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailabl Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (int) sizeof( pSubblockEnergies->subblockNrg ) / (int) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); + assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ assert( pSubblockEnergies->nDelay >= 1 ); @@ -1332,7 +1332,7 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamples Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (int) sizeof( pSubblockEnergies->subblockNrg ) / (int) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); + assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ assert( pSubblockEnergies->nDelay >= 1 ); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7e41581f4..730705ffd 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -83,8 +83,8 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; typedef struct hrtfGainCache { - int16_t azi; - int16_t ele; + Word16 azi; + Word16 ele; Word32 shVec_fx[HRTF_SH_CHANNELS]; @@ -92,13 +92,13 @@ typedef struct hrtfGainCache typedef struct parambin_rend_config_data { - int16_t separateCenterChannelRendering; + Word16 separateCenterChannelRendering; IVAS_FORMAT ivas_format; MC_MODE mc_mode; - int32_t ivas_total_brate; - int16_t nchan_transport; + Word32 ivas_total_brate; + Word16 nchan_transport; Word32 qualityBasedSmFactor_fx; /* Q31 */ - int16_t processReverb; + Word16 processReverb; ISM_MODE ism_mode; } PARAMBIN_REND_CONFIG, *PARAMBIN_REND_CONFIG_HANDLE; @@ -113,7 +113,7 @@ static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBi static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 Rmat_fx[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q ); -static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const Word16 max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[] /*q_out*/, Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat ); @@ -137,8 +137,8 @@ static void matrixTransp2Mul_fx( Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, #ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx - int Ascale, - int Bscale, + Word32 Ascale, + Word32 Bscale, #endif Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, @@ -3810,8 +3810,8 @@ static void matrixTransp2Mul_fx( Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, #ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx - int Ascale, - int Bscale, + Word32 Ascale, + Word32 Bscale, #endif Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 32803f6c3..e89414542 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -67,7 +67,7 @@ *------------------------------------------------------------------------*/ static void get_lattice_coeffs_fx( const Word16 band_index, const Word16 channel_index, Word16 *lattice_coeffs ); -static void lattice2allpass_fx( const int16_t filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); +static void lattice2allpass_fx( const Word16 filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); /*------------------------------------------------------------------------- * ivas_dirac_dec_decorr_open() @@ -1280,7 +1280,7 @@ static void get_lattice_coeffs_fx( /* convert lattice filter coeffs to all pass transfer function coeffs */ static void lattice2allpass_fx( - const int16_t filter_length, // Q0 + const Word16 filter_length, // Q0 const Word16 *lattice_coeffs_fx, // Q15 Word16 *filter_coeffs_num_real_fx, // Q12 Word16 *filter_coeffs_den_real_fx ) // Q12 diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 6b41815c4..c8e6aa12f 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -165,13 +165,13 @@ static ivas_error calc_jot_t60_coeffs_fx( Word16 *pH_dB_fx, Word16 pH_dB_exp, co * *------------------------------------------------------------------------*/ -static uint16_t binRend_rand( +static UWord16 binRend_rand( REVERB_STRUCT_HANDLE hReverb /* i/o: binaural reverb handle */ ) { hReverb->binRend_RandNext = hReverb->binRend_RandNext * 1103515245 + 12345; - return (uint16_t) ( hReverb->binRend_RandNext / 65536 ) % 32768; + return (UWord16) ( hReverb->binRend_RandNext / 65536 ) % 32768; } @@ -886,9 +886,9 @@ static ivas_error calc_jot_t60_coeffs_fx( Word32 L_tmp; Word16 f0_fx, tmp_fx, lf_target_gain_dB_fx, hf_target_gain_dB_fx, mid_crossing_gain_dB_fx; Word16 lin_gain_lf_fx, lin_gain_hf_fx, shift, expl, exph; - int16_t f_idx, e = pH_dB_exp; + Word16 f_idx, e = pH_dB_exp; move16(); - uint16_t n_points_lf, n_points_hf; + UWord16 n_points_lf, n_points_hf; lf_target_gain_dB_fx = 0; move16(); @@ -1471,7 +1471,7 @@ ivas_error ivas_reverb_open_fx( { ivas_error error; REVERB_HANDLE pState = NULL; - Word16 bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx; + Word16 bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx, i; ivas_reverb_params_t params; Word32 pColor_target_l_fx[RV_LENGTH_NR_FC]; Word32 pColor_target_r_fx[RV_LENGTH_NR_FC]; @@ -1559,7 +1559,7 @@ ivas_error ivas_reverb_open_fx( set_reverb_acoustic_data_fx( ¶ms, input_audio_config, hHrtf, &hRenderConfig->roomAcoustics, subframe_len, nr_fc_input, nr_fc_fft_filter ); Scale_sig32( params.pFc_fx, nr_fc_fft_filter, -2 ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { params.pRt60_fx[i] = L_abs( params.pRt60_fx[i] ); move32(); @@ -1601,7 +1601,7 @@ ivas_error ivas_reverb_open_fx( Word32 *pT60_filter_coeff = (Word32 *) malloc( ( lenT60_filter_coeff ) * sizeof( Word32 * ) ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] ); move32(); @@ -1610,7 +1610,7 @@ ivas_error ivas_reverb_open_fx( pHrtf_avg_pwr_response_r_const[i] = L_shl( params.pHrtf_avg_pwr_response_r_const_fx[i], 5 ); /*Q23+5*/ move32(); } - FOR( Word16 i = 0; i < lenT60_filter_coeff; i++ ) + FOR( i = 0; i < lenT60_filter_coeff; i++ ) { pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); move32(); @@ -1648,20 +1648,20 @@ ivas_error ivas_reverb_open_fx( { /* Computing correlation filters on the basis of target IA coherence */ #ifdef MSAN_FIX - FOR( int i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) + FOR( i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ move32(); } #else - FOR( int i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) + FOR( i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ } #endif // MSAN_FIX Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 3 ); /*Scaling up to Q30*/ move32(); @@ -1670,14 +1670,14 @@ ivas_error ivas_reverb_open_fx( free( pHrtf_inter_aural_coherence_const ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); } - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); move32(); @@ -1699,14 +1699,14 @@ ivas_error ivas_reverb_open_fx( /* Computing coloration filters on the basis of target responses */ ivas_reverb_calc_color_filters_fx( pColor_target_l_fx, pColor_target_r_fx, pTime_window_fx, pState->fft_size, pFft_wf_filter_ch0_fx, pFft_wf_filter_ch1_fx, &q_pFft_wf_filter_ch0_fx, &q_pFft_wf_filter_ch1_fx ); - FOR( int i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); } - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); move32(); @@ -2492,7 +2492,7 @@ ivas_error ivas_binaural_reverb_open_parambin( const Word16 numBins, /* i : number of CLDFB bins Q0 */ const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate Q0 */ + const Word32 sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ) { diff --git a/lib_rend/ivas_rom_binaural_crend_head.h b/lib_rend/ivas_rom_binaural_crend_head.h index bc0d3cd17..2b4c3e919 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.h +++ b/lib_rend/ivas_rom_binaural_crend_head.h @@ -56,13 +56,13 @@ extern Word32 CRendBin_Combined_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_Combined_HRIR_coeff_im_48kHz_fx[15][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -70,13 +70,13 @@ extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNEL /* Sample Rate = 32000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_32kHz_fx[15][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_Combined_HRIR_coeff_im_32kHz_fx[15][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -84,13 +84,13 @@ extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNEL /* Sample Rate = 16000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_16kHz_fx[15][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_Combined_HRIR_coeff_im_16kHz_fx[15][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -105,13 +105,13 @@ extern Word32 CRendBin_FOA_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_48kHz_fx[4][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_FOA_HRIR_coeff_im_48kHz_fx[4][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -119,13 +119,13 @@ extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_32kHz_fx[4][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_FOA_HRIR_coeff_im_32kHz_fx[4][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -133,13 +133,13 @@ extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_16kHz_fx[4][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_FOA_HRIR_coeff_im_16kHz_fx[4][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -153,13 +153,13 @@ extern Word32 CRendBin_HOA2_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_48kHz_fx[9][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_48kHz_fx[9][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -167,13 +167,13 @@ extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_32kHz_fx[9][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_32kHz_fx[9][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -181,13 +181,13 @@ extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_16kHz_fx[9][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_16kHz_fx[9][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -200,13 +200,13 @@ extern Word32 CRendBin_HOA3_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_48kHz_fx[16][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_48kHz_fx[16][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -214,13 +214,13 @@ extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_32kHz_fx[16][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_32kHz_fx[16][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -228,13 +228,13 @@ extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_16kHz_fx[16][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_16kHz_fx[16][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -248,13 +248,13 @@ extern Word32 CRendBin_Combined_BRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][2955]; extern Word32 CRendBin_Combined_BRIR_coeff_im_48kHz_fx[15][BINAURAL_CHANNELS][2955]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS][2885]; @@ -262,13 +262,13 @@ extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS /* Sample Rate = 32000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_32kHz_fx[15][BINAURAL_CHANNELS][2819]; extern Word32 CRendBin_Combined_BRIR_coeff_im_32kHz_fx[15][BINAURAL_CHANNELS][2819]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS][2870]; @@ -276,13 +276,13 @@ extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS /* Sample Rate = 16000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_16kHz_fx[15][BINAURAL_CHANNELS][1774]; extern Word32 CRendBin_Combined_BRIR_coeff_im_16kHz_fx[15][BINAURAL_CHANNELS][1774]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS][2522]; diff --git a/lib_rend/ivas_rom_binaural_crend_head_fx.c b/lib_rend/ivas_rom_binaural_crend_head_fx.c index 068ce0927..be015058b 100644 --- a/lib_rend/ivas_rom_binaural_crend_head_fx.c +++ b/lib_rend/ivas_rom_binaural_crend_head_fx.c @@ -56,35 +56,35 @@ const Word32 CRendBin_Combined_HRIR_latency_s_fx = 44741;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -96,35 +96,35 @@ const Word32 CRendBin_FOA_HRIR_latency_s_fx = 44741; // Q31 /* Sample Rate = 48000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -135,35 +135,35 @@ const Word32 CRendBin_HOA2_HRIR_latency_s_fx = 44741; // Q31 /* Sample Rate = 48000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -173,36 +173,36 @@ const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={N const Word32 CRendBin_HOA3_HRIR_latency_s_fx = 44741;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz = 0; const float CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz[16]={0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -212,34 +212,34 @@ const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={N const Word32 CRendBin_Combined_BRIR_latency_s_fx = 313176;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_48kHz = 22; -const uint16_t CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]={{{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240},{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240}},{{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240},{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240}},{{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240},{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240}},{{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240},{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240}},{{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240},{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240}},{{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240},{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240}},{{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240},{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240}},{{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240},{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240}},{{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240},{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240}},{{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240},{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240}},{{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240},{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240}},{{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240},{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240}},{{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240},{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240}},{{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240},{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240}},{{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240},{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz = 98; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_48kHz = 22; +const UWord16 CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]={{{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240},{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240}},{{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240},{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240}},{{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240},{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240}},{{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240},{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240}},{{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240},{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240}},{{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240},{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240}},{{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240},{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240}},{{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240},{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240}},{{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240},{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240}},{{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240},{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240}},{{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240},{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240}},{{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240},{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240}},{{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240},{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240}},{{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240},{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240}},{{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240},{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz = 98; const float CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz[15]={0.224183f, 0.227455f, 0.241830f, 0.207155f, 0.218087f, 0.222942f, 0.232158f, 0.248203f, 0.249262f, 0.261591f, 0.246276f, 0.279163f, 0.285701f, 0.262541f, 0.271844f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz_fx[15]={7346, 7453, 7924, 6788, 7146, 7305, 7607, 8133, 8167, 8571, 8069, 9147, 9361, 8602, 8907,}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98},{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98},{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98}}; /* Sample Rate = 32000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_32kHz = 22; -const uint16_t CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]={{{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160},{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160}},{{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160},{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160}},{{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160},{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160}},{{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160},{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160}},{{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160},{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160}},{{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160},{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160}},{{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160},{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160}},{{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160},{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160}},{{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160},{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160}},{{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160},{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160}},{{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160},{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160}},{{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160},{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160}},{{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160},{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160}},{{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160},{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160}},{{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160},{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz = 97; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_32kHz = 22; +const UWord16 CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]={{{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160},{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160}},{{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160},{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160}},{{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160},{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160}},{{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160},{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160}},{{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160},{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160}},{{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160},{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160}},{{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160},{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160}},{{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160},{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160}},{{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160},{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160}},{{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160},{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160}},{{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160},{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160}},{{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160},{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160}},{{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160},{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160}},{{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160},{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160}},{{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160},{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz = 97; const float CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz[15]={0.224190f, 0.227445f, 0.241827f, 0.207131f, 0.218113f, 0.222941f, 0.232139f, 0.248192f, 0.249239f, 0.261572f, 0.246309f, 0.279145f, 0.285786f, 0.262528f, 0.271847f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz_fx[15]={7346, 7452, 7924, 6787, 7147, 7305, 7606, 8132, 8167, 8571, 8071, 9147, 9364, 8602, 8907,}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97},{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97},{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97}}; /* Sample Rate = 16000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_16kHz = 23; -const uint16_t CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]={{{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80},{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80}},{{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80},{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80}},{{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80},{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80}},{{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80},{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80}},{{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80},{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80}},{{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80},{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80}},{{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80},{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80}},{{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80},{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80}},{{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80},{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80}},{{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80},{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80}},{{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80},{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80}},{{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80},{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80}},{{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80},{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80}},{{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80},{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80}},{{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80},{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz = 77; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_16kHz = 23; +const UWord16 CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]={{{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80},{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80}},{{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80},{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80}},{{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80},{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80}},{{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80},{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80}},{{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80},{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80}},{{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80},{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80}},{{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80},{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80}},{{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80},{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80}},{{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80},{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80}},{{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80},{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80}},{{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80},{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80}},{{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80},{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80}},{{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80},{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80}},{{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80},{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80}},{{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80},{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz = 77; const float CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz[15]={0.223532f, 0.226827f, 0.248830f, 0.208782f, 0.220391f, 0.219790f, 0.231187f, 0.248730f, 0.251408f, 0.263698f, 0.243858f, 0.281483f, 0.283080f, 0.261660f, 0.273527f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz_fx[15]={7346, 7452, 7924, 6787, 7147, 7305, 7606, 8132, 8167, 8571, 8071, 9147, 9364, 8602, 8907}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]={{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77},{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]={{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77},{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77}}; //BRIR and HRIR coeff tables in Q29 const Word32 CRendBin_Combined_BRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][2955] ={ { diff --git a/lib_rend/ivas_rom_rend_fx.c b/lib_rend/ivas_rom_rend_fx.c index 54940355c..2b46ff611 100644 --- a/lib_rend/ivas_rom_rend_fx.c +++ b/lib_rend/ivas_rom_rend_fx.c @@ -49,9 +49,9 @@ const Word16 diffuse_response_CICP6_fx[5] = { 13824, 13824, 12137, 16495, 16495 const Word16 diffuse_response_CICP14_fx[7] = { 12507, 12507, 9237, 17691, 17691, 4977, 4977 };//Q15 const Word16 diffuse_response_CICP16_fx[9] = { 11324, 11324, 9945, 13513, 13513, 8853, 8853, 9905, 9905 };//Q15 -const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; +const Word16 ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; -const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; +const Word16 ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN] /*Q14*/ = { @@ -91,11 +91,11 @@ const Word16 ap_split_frequencies_fx[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]/*Q14*/ = 0 , 2048, 6144, 16384 }; -const int16_t sba_map_tc[11] = +const Word16 sba_map_tc[11] = { 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 }; -const int16_t sba_map_tc_512[11] = +const Word16 sba_map_tc_512[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 }; @@ -121,11 +121,11 @@ const int16_t sba_map_tc_512[11] = * 13 = 135, 35 * 14 = -135, 35 */ -const int16_t channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; -const int16_t channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; -const int16_t channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; -const int16_t channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; -const int16_t channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; +const Word16 channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; +const Word16 channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; +const Word16 channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; +const Word16 channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; +const Word16 channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; const Word16 surCohEne_fx[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS] /* Q13 */ = { @@ -160,7 +160,7 @@ const Word32 diffuseFieldCoherenceDifferenceZ_fx[BINAURAL_COHERENCE_DIFFERENCE_B * TD ISM binaural renderer ROM tables *----------------------------------------------------------------------------------*/ -const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = +const Word16 HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = { 13, 12, 11 }; diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 22ed7ed65..0a489600a 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -88,7 +88,7 @@ typedef enum IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN, } IVAS_REND_AudioConfigType; -typedef uint16_t IVAS_REND_InputId; +typedef UWord16 IVAS_REND_InputId; typedef enum _IVAS_REND_COMPLEXITY_LEVEL { -- GitLab From 0167cdeab304bc9403484dfd72e7a63bd3674971 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 09:30:57 +0530 Subject: [PATCH 0402/1221] Fix for 3GPP issue 1345: Decoder crash for Stereo at 32kbps in stereo_dft_dec_res_fx() Link #1345 --- lib_dec/ivas_stereo_dft_dec_fx.c | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 8dcc7ada9..fb54476fa 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1368,23 +1368,23 @@ void stereo_dft_dec_res_fx( /*Inverse MDCT*/ TCX_MDCT_Inverse( res_buf, q_res, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + scale_sig( win, L_FRAME8k + STEREO_DFT_OVL_8k, -1 ); + + Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); IF( !prev_bfi ) { /*OLA*/ /*overlapping parts*/ - Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); + FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( L_add( hCPE->hStereoDft->res_cod_mem_fx[i], L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx */ + win[i] = extract_h( L_add( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx -17 (q_shift -1)*/ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* q_res_cod_mem_fx */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* -1 +15 +1 +1 */ move32(); } - IF( q_shift != 0 ) - { - v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); - } - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + + move16(); } ELSE @@ -1396,23 +1396,30 @@ void stereo_dft_dec_res_fx( move16(); FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( Madd_32_16( Mpy_32_16_1( hCPE->hStereoDft->res_cod_mem_fx[i], sub( MAX_16, mult( fac, fac ) ) ), - L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), - sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q0 */ + win[i] = extract_h( Madd_32_16( Mpy_32_16_1( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), sub( MAX_16, mult( fac, fac ) ) ), + L_shl( L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), q_shift ), + sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q(q_shift -1) */ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* Q16 */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* Q16 */ move32(); fac = add( fac, step ); } } - Copy( win, out_16, L_FRAME8k ); /* Q0 */ + IF( q_shift != 0 ) + { + v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); + } + + hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + + Copy( win, out_16, L_FRAME8k ); /* Q(q_shift -1 ) */ IF( hCPE->hCoreCoder[0]->core == ACELP_CORE ) { /* bass post-filter */ bass_psfilter_fx( hCPE->hStereoDft->hBpf, hCPE->hCoreCoder[0]->Opt_AMR_WB, out_16, L_FRAME8k, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx + ( L_FRAME8k / STEREO_DFT_L_SUBFR_8k ), hCPE->hCoreCoder[0]->bpf_off, - hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, 0, bpf_error_signal_8k_16 ); + hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, sub( q_shift, 1 ), bpf_error_signal_8k_16 ); Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_8k_16, bpf_error_signal_8k, L_FRAME8k, Q15 ); /* Q15 */ res_bpf_flag = res_bpf_adapt_ivas_fx( hCPE->hStereoDft, bpf_error_signal_8k, res_buf, q_res ); @@ -1430,7 +1437,7 @@ void stereo_dft_dec_res_fx( } } #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, 15 ); /* Q15 */ + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ #else Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ #endif @@ -1445,7 +1452,7 @@ void stereo_dft_dec_res_fx( hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, 15 ); /* Q15 */ + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ #else Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ #endif @@ -1454,7 +1461,7 @@ void stereo_dft_dec_res_fx( { /* This step is needed to ensure output is properly populated with scaled values in all cases*/ #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, 15 ); /* Q15 */ + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ #else Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ #endif -- GitLab From 93562d4813418102900242d96160cabc25baa6fc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 12:49:24 +0530 Subject: [PATCH 0403/1221] Fix for 3GPP issue 1342: Decoder crash for Stereo at 48/64 kbps mono decoding in IMDCT_ivas_fx() Link #1342 --- lib_com/edct_fx.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index 8d77da13a..b1e2a7dd9 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -592,11 +592,12 @@ void edxt_fx( const UWord16 synthesis /* i : nonzero for inverse Q0*/ ) { - Word16 k, m, fac; + Word16 k, m, fac, hdrm, tmp = 0; const Word16 *cosPtr, *sinPtr; Word16 n; n = 0; move16(); + move16(); cosPtr = NULL; sinPtr = NULL; IF( EQ_16( length, 512 ) ) @@ -735,7 +736,23 @@ void edxt_fx( IF( EQ_16( length, 512 ) ) { + /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */ + hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) ); + IF( LT_16( hdrm, 4 ) ) + { + tmp = sub( hdrm, 4 ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } + DoRTFTn_fx( re, im, 512 ); + + IF( LT_16( hdrm, 4 ) ) + { + tmp = negate( tmp ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } } ELSE /* fft() doesn't support 512 */ { @@ -831,7 +848,23 @@ void edxt_fx( IF( EQ_16( length, 512 ) ) { + /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */ + hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) ); + IF( LT_16( hdrm, 4 ) ) + { + tmp = sub( hdrm, 4 ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } + DoRTFTn_fx( re, im, 512 ); + + IF( LT_16( hdrm, 4 ) ) + { + tmp = negate( tmp ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } } ELSE /* fft() doesn't support 512 */ { -- GitLab From 75cc1287f4487be57d9ac79959c1b53a57cf4224 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:34:44 +0530 Subject: [PATCH 0404/1221] Fix for 3GPP issue 1327: Glitch when stereo is switching from TD to FD Link #1327 --- lib_com/options.h | 1 + lib_enc/ivas_stereo_switching_enc_fx.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 85d81ab5c..dab0c796c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -174,4 +174,5 @@ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ +#define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ #endif diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 6513a3fa7..cbdbc0501 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -680,6 +680,10 @@ void stereo_switching_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); /* sts[n]->q_inp */ +#ifdef FIX_ISSUE_1327 + hCPE->q_input_mem[n] = sts[n]->q_inp; + move16(); +#endif } } -- GitLab From c92e3a4e29c5441e2ee2bd8d09aeac18c3090272 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:14:28 +0530 Subject: [PATCH 0405/1221] Fix for 3GPP issue 1048: Problem in stereo during bitrate switching and frame erasure Link #1048 --- lib_dec/er_dec_tcx_fx.c | 2 +- lib_dec/ivas_mdct_core_dec_fx.c | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 8c10e5f81..5cc06dabf 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -1168,7 +1168,7 @@ void con_tcx_ivas_fx( /* apply pre-emphasis to the signal */ mem = synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )]; /*Q0*/ move16(); - Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); + Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); st->Mode2_lp_gainc = L_deposit_l( 0 ); st->Mode2_lp_gainp = get_gain2( synth - shl( L_subfr, 1 ), synth - add( shl( L_subfr, 1 ), Tc ), shl( L_subfr, 1 ) ); diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 7f079277a..a5855a0f6 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1282,11 +1282,6 @@ void ivas_mdct_core_reconstruct_fx( ELSE /*ACELP core for ACELP-PLC */ { assert( EQ_16( st->bfi, 1 ) ); - - Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( -2, q_syn ) ); // Q0 - Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( -2, q_syn ) ); // Q0 - q_syn = -2; - move16(); /* PLC: [TCX: TD PLC] */ IF( MCT_flag != 0 ) { @@ -1316,11 +1311,11 @@ void ivas_mdct_core_reconstruct_fx( IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || ( st->hTcxDec->tcxConceal_recalc_exc != 0 ) ) { - Scale_sig( synthFB_fx - add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) + Scale_sig( synthFB_fx - add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), sub( add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), 1 ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) } ELSE { - Scale_sig( synthFB_fx - st->hTcxDec->L_frameTCX, st->hTcxDec->L_frameTCX, sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) + Scale_sig( synthFB_fx - st->hTcxDec->L_frameTCX, sub( st->hTcxDec->L_frameTCX, 1 ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) } lerp( synthFB_fx, synth_fx, st->L_frame, st->hTcxDec->L_frameTCX ); -- GitLab From b2ed1c2b5b03c24769e474416e0025a3a0b5d22a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 14:07:06 +0530 Subject: [PATCH 0406/1221] Fix for 3GPP issue 1004: Modulation artifact in OMASA at 24 kbps using LTV 3ISM 2TC input and output to MONO Link #1004, #1363 Fixes 3GPP issue #1363: Assert in BASOP decoder function protoSignalComputation2_fx when fed with BASOP encoder MASA bitstream --- lib_rend/ivas_dirac_rend_fx.c | 94 +++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index e01b27767..aca51e01c 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1770,7 +1770,7 @@ void protoSignalComputation2_fx( Word32 min_sum_total_ratio_fx, min_sum_total_ratio_db_fx; Word32 sum_total_ratio_fx[MASA_SUM_FREQ_RANGE_BINS]; Word16 q_sum_total_ratio; - Word32 a_fx, b_fx; + Word32 a_fx, b_fx, a2_fx, b2_fx; Word16 interpolatorSpaced_fx, interpolatorDmx_fx; Word32 tempSpaced_fx, tempDmx_fx; Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; @@ -1778,7 +1778,7 @@ void protoSignalComputation2_fx( Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; - + Word16 head_room, q_Left_Right_power; /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ min_q_shift = Q31; move16(); @@ -2020,8 +2020,10 @@ void protoSignalComputation2_fx( a_fx = 21474836; /*0.01 in Q31*/ /* Temporal smoothing coefficient */ move32(); b_fx = L_sub( ONE_IN_Q31, a_fx ); /* Temporal smoothing coefficient q31*/ - // a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ - // b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ + move32(); + a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ + move32(); + b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ IF( stereo_type_detect->interpolator > 0 ) { @@ -2044,6 +2046,23 @@ void protoSignalComputation2_fx( q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); + head_room = 63; + move16(); + FOR( l = 0; l < num_freq_bands; l++ ) + { + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + + W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); + W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); + + head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); + } + head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); + FOR( l = 0; l < num_freq_bands; l++ ) { re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -2058,26 +2077,26 @@ void protoSignalComputation2_fx( /* Compute reference power */ // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift) - Left_power_fx = W_extract_l( W_shr( W_tmp1, 31 ) ); + Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) ); // q_Left_Right_power // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift) - Right_power_fx = W_extract_l( W_shr( W_tmp2, 31 ) ); + Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) ); // q_Left_Right_power // reference_power_fx[l] = L_add( Left_power_fx, Right_power_fx ); reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift) move64(); - left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { - left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power + right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); - total_hi_power_fx = L_add( total_hi_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) @@ -2114,12 +2133,17 @@ void protoSignalComputation2_fx( test(); IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) { - sum_total_ratio_fx[l] = MAX_16; // q15 + sum_total_ratio_fx[l] = MAX_32; // q15 + move32(); + } + ELSE IF( stereo_type_detect->total_power_fx[l] == 0 ) + { + sum_total_ratio_fx[l] = MAX_32; // q15 move32(); } ELSE { - sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], L_add( stereo_type_detect->total_power_fx[l], EPSILON_FX ), &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) + sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 @@ -2490,45 +2514,45 @@ void protoSignalComputation2_fx( } } - temp = Mpy_32_32( a_fx, left_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_left_bb_power ) ) + temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ) { - stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_left_bb_power = q_temp; + stereo_type_detect->q_left_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->left_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_left_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ) ); // stereo_type_detect->q_left_bb_power + stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power move32(); } - temp = Mpy_32_32( a_fx, right_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_right_bb_power ) ) + temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ) { - stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_right_bb_power = q_temp; + stereo_type_detect->q_right_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->right_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_right_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ) ); // stereo_type_detect->q_right_bb_power + stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power move32(); } - temp = Mpy_32_32( a_fx, total_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_total_bb_power ) ) + temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ) { - stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_total_bb_power = q_temp; + stereo_type_detect->q_total_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->total_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ) ); // stereo_type_detect->q_total_bb_power + stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power move32(); } @@ -2546,8 +2570,7 @@ void protoSignalComputation2_fx( q_lr_bb_power = stereo_type_detect->q_right_bb_power; move16(); } - q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ - + q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power)) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_bb_power, stereo_type_detect->q_total_bb_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 @@ -2558,15 +2581,15 @@ void protoSignalComputation2_fx( // 20480 = 10 in Q11 lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); move16(); - stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); move32(); stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); move16(); @@ -2583,8 +2606,7 @@ void protoSignalComputation2_fx( move32(); q_lr_hi_power = stereo_type_detect->q_right_hi_power; } - q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ - + q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_hi_power, stereo_type_detect->q_total_hi_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 -- GitLab From 8b5fab74c4d8997d349af0ead331e012172ae097 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 19:34:14 +0530 Subject: [PATCH 0407/1221] Bug fixes, ivas_prot.h cleanup, Q documentation updates --- lib_com/bitstream.c | 1 - lib_com/core_com_config.c | 1 - lib_com/fft_fx.c | 20 + lib_com/gs_bitallocation_ivas_fx.c | 1 - lib_com/ivas_agc_com_fx.c | 1 - lib_com/ivas_arith_fx.c | 1 - lib_com/ivas_cov_smooth_fx.c | 1 - lib_com/ivas_dirac_com_fx.c | 1 - lib_com/ivas_entropy_coder_common_fx.c | 1 - lib_com/ivas_fb_mixer_fx.c | 1 - lib_com/ivas_filters_fx.c | 1 - lib_com/ivas_ism_com_fx.c | 1 - lib_com/ivas_lfe_com_fx.c | 1 - lib_com/ivas_masa_com_fx.c | 1 - lib_com/ivas_mc_com_fx.c | 1 - lib_com/ivas_mc_param_com_fx.c | 1 - lib_com/ivas_mcmasa_com-fx.c | 1 - lib_com/ivas_mct_com_fx.c | 2 +- lib_com/ivas_mdct_core_com_fx.c | 1 - lib_com/ivas_mdft_imdft_fx.c | 1 - lib_com/ivas_omasa_com_fx.c | 1 - lib_com/ivas_pca_tools_fx.c | 1 - lib_com/ivas_prot_fx.h | 817 ++++++++++++++++++ lib_com/ivas_qmetadata_com_fx.c | 1 - lib_com/ivas_qspherical_com_fx.c | 1 - lib_com/ivas_sba_config_fx.c | 1 - lib_com/ivas_sns_com_fx.c | 177 ++-- lib_com/ivas_spar_com_fx.c | 1 - lib_com/ivas_spar_com_quant_util_fx.c | 1 - lib_com/ivas_stereo_dft_com_fx.c | 1 - lib_com/ivas_stereo_eclvq_com_fx.c | 1 - lib_com/ivas_stereo_ica_com_fx.c | 1 - lib_com/ivas_stereo_mdct_bands_com_fx.c | 1 - lib_com/ivas_stereo_mdct_stereo_com_fx.c | 1 - lib_com/ivas_stereo_psychlpc_com_fx.c | 2 - lib_com/ivas_stereo_td_bit_alloc_fx.c | 1 - lib_com/ivas_tools_fx.c | 1 - lib_com/ivas_transient_det_fx.c | 1 - lib_com/mslvq_com.c | 1 - lib_com/prot_fx.h | 1 + lib_com/swb_tbe_com.c | 1 - lib_dec/ACcontextMapping_dec_fx.c | 1 - lib_dec/acelp_core_dec_ivas_fx.c | 1 - lib_dec/dec_tcx_fx.c | 1 - lib_dec/igf_dec_fx.c | 5 +- lib_dec/ivas_agc_dec_fx.c | 1 - lib_dec/ivas_binRenderer_internal_fx.c | 1 - lib_dec/ivas_core_dec_fx.c | 1 - lib_dec/ivas_corecoder_dec_reconfig_fx.c | 1 - lib_dec/ivas_cpe_dec_fx.c | 1 - lib_dec/ivas_decision_matrix_dec_fx.c | 1 - lib_dec/ivas_dirac_dec_fx.c | 1 - lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 1 - lib_dec/ivas_entropy_decoder_fx.c | 1 - lib_dec/ivas_init_dec.c | 1 - lib_dec/ivas_ism_dec_fx.c | 1 - lib_dec/ivas_ism_dtx_dec_fx.c | 1 - lib_dec/ivas_ism_metadata_dec_fx.c | 1 - lib_dec/ivas_ism_param_dec_fx.c | 1 - lib_dec/ivas_ism_renderer_fx.c | 1 - lib_dec/ivas_jbm_dec_fx.c | 1 - lib_dec/ivas_lfe_dec_fx.c | 1 - lib_dec/ivas_lfe_plc_fx.c | 1 - lib_dec/ivas_ls_custom_dec_fx.c | 1 - lib_dec/ivas_masa_dec_fx.c | 1 - lib_dec/ivas_mc_param_dec_fx.c | 1 - lib_dec/ivas_mc_paramupmix_dec_fx.c | 1 - lib_dec/ivas_mcmasa_dec_fx.c | 1 - lib_dec/ivas_mct_core_dec_fx.c | 1 - lib_dec/ivas_mct_dec_fx.c | 1 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 1 - lib_dec/ivas_mdct_core_dec_fx.c | 1 - lib_dec/ivas_mono_dmx_renderer_fx.c | 1 - lib_dec/ivas_objectRenderer_internal_fx.c | 1 - lib_dec/ivas_omasa_dec_fx.c | 1 - lib_dec/ivas_osba_dec_fx.c | 1 - lib_dec/ivas_out_setup_conversion_fx.c | 1 - lib_dec/ivas_output_config_fx.c | 1 - lib_dec/ivas_pca_dec_fx.c | 1 - lib_dec/ivas_post_proc_fx.c | 1 - lib_dec/ivas_qmetadata_dec_fx.c | 1 - lib_dec/ivas_qspherical_dec_fx.c | 1 - lib_dec/ivas_range_uni_dec_fx.c | 1 - lib_dec/ivas_sba_dec_fx.c | 1 - lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 1 - lib_dec/ivas_sba_rendering_internal_fx.c | 1 - lib_dec/ivas_sce_dec_fx.c | 1 - lib_dec/ivas_sns_dec_fx.c | 1 - lib_dec/ivas_spar_decoder_fx.c | 1 - lib_dec/ivas_spar_md_dec_fx.c | 1 - lib_dec/ivas_stereo_adapt_GR_dec_fx.c | 1 - lib_dec/ivas_stereo_cng_dec.c | 1 - lib_dec/ivas_stereo_dft_dec.c | 1 - lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 1 - lib_dec/ivas_stereo_dft_dec_fx.c | 1 - lib_dec/ivas_stereo_dft_plc_fx.c | 1 - lib_dec/ivas_stereo_eclvq_dec_fx.c | 1 - lib_dec/ivas_stereo_esf_dec_fx.c | 1 - lib_dec/ivas_stereo_ica_dec_fx.c | 1 - lib_dec/ivas_stereo_icbwe_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_core_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 1 - lib_dec/ivas_stereo_switching_dec_fx.c | 1 - lib_dec/ivas_stereo_td_dec_fx.c | 40 - lib_dec/ivas_svd_dec_fx.c | 1 - lib_dec/ivas_tcx_core_dec_fx.c | 1 - lib_dec/ivas_td_low_rate_dec_fx.c | 1 - lib_dec/lib_dec_fx.c | 1 - lib_dec/lsf_dec_fx.c | 1 - lib_enc/ACcontextMapping_enc_fx.c | 1 - lib_enc/acelp_core_enc_fx.c | 1 - lib_enc/cod4t64_fast.c | 1 - lib_enc/cod_tcx_fx.c | 1 - lib_enc/ext_sig_ana_fx.c | 40 +- lib_enc/igf_enc.c | 1 - lib_enc/ivas_agc_enc_fx.c | 1 - lib_enc/ivas_core_enc_fx.c | 1 - lib_enc/ivas_core_pre_proc_front_fx.c | 1 - lib_enc/ivas_core_pre_proc_fx.c | 1 - lib_enc/ivas_corecoder_enc_reconfig_fx.c | 1 - lib_enc/ivas_cpe_enc_fx.c | 1 - lib_enc/ivas_decision_matrix_enc_fx.c | 1 - lib_enc/ivas_dirac_enc_fx.c | 1 - lib_enc/ivas_enc_cov_handler_fx.c | 1 - lib_enc/ivas_enc_fx.c | 1 - lib_enc/ivas_entropy_coder_fx.c | 1 - lib_enc/ivas_front_vad_fx.c | 25 - lib_enc/ivas_init_enc_fx.c | 1 - lib_enc/ivas_ism_dtx_enc_fx.c | 1 - lib_enc/ivas_ism_enc_fx.c | 1 - lib_enc/ivas_ism_metadata_enc_fx.c | 1 - lib_enc/ivas_ism_param_enc_fx.c | 1 - lib_enc/ivas_lfe_enc_fx.c | 1 - lib_enc/ivas_masa_enc_fx.c | 1 - lib_enc/ivas_mc_param_enc_fx.c | 1 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 1 - lib_enc/ivas_mcmasa_enc_fx.c | 1 - lib_enc/ivas_mct_core_enc_fx.c | 1 - lib_enc/ivas_mct_enc_fx.c | 1 - lib_enc/ivas_mct_enc_mct_fx.c | 1 - lib_enc/ivas_mdct_core_enc_fx.c | 29 +- lib_enc/ivas_omasa_enc_fx.c | 1 - lib_enc/ivas_osba_enc_fx.c | 1 - lib_enc/ivas_pca_enc_fx.c | 1 - lib_enc/ivas_qmetadata_enc_fx.c | 1 - lib_enc/ivas_qspherical_enc_fx.c | 1 - lib_enc/ivas_range_uni_enc_fx.c | 1 - lib_enc/ivas_sba_enc_fx.c | 1 - lib_enc/ivas_sce_enc_fx.c | 1 - lib_enc/ivas_sns_enc_fx.c | 1 - lib_enc/ivas_spar_encoder_fx.c | 1 - lib_enc/ivas_spar_md_enc_fx.c | 1 - lib_enc/ivas_stereo_adapt_GR_enc_fx.c | 1 - lib_enc/ivas_stereo_classifier_fx.c | 1 - lib_enc/ivas_stereo_cng_enc_fx.c | 1 - lib_enc/ivas_stereo_dft_enc_fx.c | 1 - lib_enc/ivas_stereo_dft_enc_itd_fx.c | 1 - lib_enc/ivas_stereo_dft_td_itd_fx.c | 1 - lib_enc/ivas_stereo_dmx_evs_fx.c | 1 - lib_enc/ivas_stereo_eclvq_enc_fx.c | 1 - lib_enc/ivas_stereo_ica_enc_fx.c | 1 - lib_enc/ivas_stereo_icbwe_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_core_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_igf_enc_fx.c | 1 - lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 1 - lib_enc/ivas_stereo_switching_enc_fx.c | 1 - lib_enc/ivas_stereo_td_analysis_fx.c | 1 - lib_enc/ivas_stereo_td_enc_fx.c | 1 - lib_enc/ivas_tcx_core_enc_fx.c | 1 - lib_enc/ivas_td_low_rate_enc_fx.c | 1 - lib_enc/lib_enc.c | 1 - lib_enc/lp_exc_e_fx.c | 106 +-- lib_enc/lsf_enc_fx.c | 147 ++-- lib_enc/lsf_msvq_ma_enc.c | 27 +- lib_enc/lsf_msvq_ma_enc_fx.c | 52 +- lib_enc/ltd_stable_fx.c | 63 +- lib_enc/mdct_classifier_fx.c | 99 +-- lib_enc/mdct_selector_fx.c | 36 +- lib_enc/mslvq_enc_fx.c | 52 +- lib_enc/multi_harm_fx.c | 16 +- lib_enc/speech_music_classif_fx.c | 1 - lib_enc/swb_pre_proc_fx.c | 1 - lib_enc/swb_tbe_enc_fx.c | 1 - lib_rend/ivas_allrad_dec_fx.c | 1 - lib_rend/ivas_crend_fx.c | 1 - lib_rend/ivas_dirac_ana_fx.c | 1 - .../ivas_dirac_dec_binaural_functions_fx.c | 1 - lib_rend/ivas_dirac_decorr_dec_fx.c | 1 - lib_rend/ivas_dirac_onsets_dec_fx.c | 1 - lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 1 - lib_rend/ivas_dirac_rend_fx.c | 1 - lib_rend/ivas_efap_fx.c | 1 - lib_rend/ivas_hrtf_fx.c | 1 - lib_rend/ivas_masa_merge_fx.c | 1 - lib_rend/ivas_mcmasa_ana_fx.c | 1 - lib_rend/ivas_objectRenderer_fx.c | 1 - lib_rend/ivas_omasa_ana_fx.c | 1 - lib_rend/ivas_orient_trk_fx.c | 1 - lib_rend/ivas_output_init.c | 1 - lib_rend/ivas_output_init_fx.c | 1 - lib_rend/ivas_reflections_fx.c | 1 - lib_rend/ivas_reverb_delay_line_fx.c | 1 - lib_rend/ivas_sba_rendering_fx.c | 1 - lib_rend/ivas_td_decorr_fx.c | 1 - lib_rend/ivas_vbap_fx.c | 1 - lib_rend/lib_rend.c | 1 - lib_util/hrtf_file_reader.c | 1 - lib_util/ls_custom_file_reader.c | 2 +- lib_util/masa_file_reader.c | 1 - 209 files changed, 1267 insertions(+), 679 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 9c0a53f8f..90b49f8c2 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -43,7 +43,6 @@ #include "stat_dec.h" #include "rom_com.h" #include "mime.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index ed72605de..f0ee8efd8 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 73ff582df..7b63e9c67 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -7636,6 +7636,26 @@ Word16 norm_arr( Word16 *arr, Word16 size ) return q; } +Word16 W_norm_arr( Word64 *arr, Word16 size ) +{ + Word16 q = 63; + Word16 exp = 0; + move16(); + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + if ( arr[i] != 0 ) + { + exp = W_norm( arr[i] ); + } + if ( arr[i] != 0 ) + { + q = s_min( q, exp ); + } + } + return q; +} + Word16 get_min_scalefactor( Word32 x, Word32 y ) { #ifndef FIX_1104_OPT_GETMINSCALEFAC diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 0921dc88c..71b30ea75 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_agc_com_fx.c b/lib_com/ivas_agc_com_fx.c index 94e6b222f..3f6e181ef 100644 --- a/lib_com/ivas_agc_com_fx.c +++ b/lib_com/ivas_agc_com_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_arith_fx.c b/lib_com/ivas_arith_fx.c index 006a31177..311bccff8 100644 --- a/lib_com/ivas_arith_fx.c +++ b/lib_com/ivas_arith_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "wmc_auto.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index acc0df821..3a93ed1f5 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 9b60b2c5c..146587791 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_entropy_coder_common_fx.c b/lib_com/ivas_entropy_coder_common_fx.c index 99381d19a..f52d59859 100644 --- a/lib_com/ivas_entropy_coder_common_fx.c +++ b/lib_com/ivas_entropy_coder_common_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" #include "prot_fx.h" diff --git a/lib_com/ivas_fb_mixer_fx.c b/lib_com/ivas_fb_mixer_fx.c index 883861024..d5cd8d4f1 100644 --- a/lib_com/ivas_fb_mixer_fx.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_filters_fx.c b/lib_com/ivas_filters_fx.c index 7705deb6a..1e9aaf0c2 100644 --- a/lib_com/ivas_filters_fx.c +++ b/lib_com/ivas_filters_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index f1201b06c..5f1a13afb 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_lfe_com_fx.c b/lib_com/ivas_lfe_com_fx.c index 7464c41c2..3d1e7aee6 100644 --- a/lib_com/ivas_lfe_com_fx.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_stat_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_com/ivas_masa_com_fx.c b/lib_com/ivas_masa_com_fx.c index fbe752aad..cfed06357 100644 --- a/lib_com/ivas_masa_com_fx.c +++ b/lib_com/ivas_masa_com_fx.c @@ -36,7 +36,6 @@ #include #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_mc_com_fx.c b/lib_com/ivas_mc_com_fx.c index 62d623b83..8201037a1 100644 --- a/lib_com/ivas_mc_com_fx.c +++ b/lib_com/ivas_mc_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_param_com_fx.c b/lib_com/ivas_mc_param_com_fx.c index a54abe7ab..4469e7f93 100644 --- a/lib_com/ivas_mc_param_com_fx.c +++ b/lib_com/ivas_mc_param_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_mcmasa_com-fx.c b/lib_com/ivas_mcmasa_com-fx.c index da0b8f1c4..23a3800fb 100644 --- a/lib_com/ivas_mcmasa_com-fx.c +++ b/lib_com/ivas_mcmasa_com-fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "ivas_cnst.h" -#include "ivas_prot.h" #include "options.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mct_com_fx.c b/lib_com/ivas_mct_com_fx.c index 1f3c58153..81a56df14 100644 --- a/lib_com/ivas_mct_com_fx.c +++ b/lib_com/ivas_mct_com_fx.c @@ -33,8 +33,8 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com_fx.c b/lib_com/ivas_mdct_core_com_fx.c index 000f3992f..fe313eecd 100644 --- a/lib_com/ivas_mdct_core_com_fx.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mdft_imdft_fx.c b/lib_com/ivas_mdft_imdft_fx.c index b10444307..5d7bee1a6 100644 --- a/lib_com/ivas_mdft_imdft_fx.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_omasa_com_fx.c b/lib_com/ivas_omasa_com_fx.c index ef6350285..1c1d4bf6c 100644 --- a/lib_com/ivas_omasa_com_fx.c +++ b/lib_com/ivas_omasa_com_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_pca_tools_fx.c b/lib_com/ivas_pca_tools_fx.c index 1e36c5e8e..c84078a7d 100644 --- a/lib_com/ivas_pca_tools_fx.c +++ b/lib_com/ivas_pca_tools_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include #include diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 4a72b194a..6b23f8eed 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -5896,4 +5896,821 @@ void reset_metadata_spatial_fx( const Word32 core_brate, /* i : core bitrate */ const Word16 nb_bits_metadata /* i : number of meatdata bits */ ); + +/*=============================================================================================*/ +/* clang-format off */ + +/*----------------------------------------------------------------------------------* + * General IVAS prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: number of channels to be analysed */ + +void copy_encoder_config_ivas_fx( + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Encoder_State *st, /* o : encoder state structure */ + const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ +); + +ivas_error create_mct_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void destroy_cpe_enc( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ +); + +void ivas_mct_enc_close_fx( + MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ +); + +ivas_error pre_proc_front_ivas_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 element_brate, /* i : SCE/CPE element bitrate Q0*/ + const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + const Word16 n, /* i : channel number Q0*/ + Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 *relE_fx, /* o : frame relative energy Q8*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[M + 1], /* o : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, + Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15*/ + Word16 *vad_hover_flag, /* o : VAD hangover flag Q0*/ + Word16 *attack_flag, /* o : flag signaling attack Q0*/ + Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf)*/ + Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf)*/ + Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ + Word16 old_wsp_fx[], /* o : weighted input signal buffer q_old_wsp*/ + Word16 *q_old_wsp, + Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6*/ + Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15*/ + Word16 *loc_harm, /* o : harmonicity flag Q0*/ + Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8*/ + Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 *enerBuffer_fx_exp, /* o : energy buffer */ + Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer fft_buff_fx_q*/ + Word16 *fft_buff_fx_q, /* o : FFT buffer */ + const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ + const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ + const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ + const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ + Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ + Word16 fr_bands_LR_fx_q[CPE_CHANNELS], + const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ + Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q)*/ + Word16 lf_E_LR_fx_q, + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ + Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ + Word16 band_energies_LR_fx_q, + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ + const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ + const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ +#ifdef NONBE_1211_DTX_BR_SWITCHING + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ +#endif + const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ + Word16 *Q_new +#ifdef DEBUG_MODE_INFO + , + const Word16 ch_idx +#endif +); +ivas_error pre_proc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 last_element_mode, /* i : last element mode Q0*/ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word32 last_element_brate, /* i : last element bitrate Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal Q_new-1 */ + Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz Q_new-1 */ + Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame Q_new*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes Q14*/ + Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, /* i : LP prediction errors */ + Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ + Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE Q_new-1*/ + Word16 *Voicing_flag, /* o : voicing flag for HQ FEC Q0*/ + Word16 old_wsp_fx[], /* i : weighted input signal buffer e_old_wsp*/ + Word16 e_old_wsp, + const Word16 loc_harm, /* i : harmonicity flag Q0*/ + const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO Q0*/ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* e_enerBuffer */ + Word16 e_enerBuffer, + Word16 fft_buff_fx[2 * L_FFT], /* Qx */ + Word16 cor_map_sum_fx, /* Q8 */ + Word16 *Q_new +); +/*! r: number of clipped samples */ +void ivas_initialize_handles_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +ivas_error ivas_init_encoder( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_destroy_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +ivas_error ivas_initialize_MD_bstr_enc_fx( + BSTR_ENC_HANDLE *hBstr, /* o : encoder MD bitstream handle */ + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_destroy_MD_bstr_enc_fx( + BSTR_ENC_HANDLE *hMetaData /* i/o: encoder MD bitstream handle */ +); + +ivas_error ivas_init_decoder_front( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +void ivas_mct_dec_close( + MCT_DEC_HANDLE *hMCT /* i/o: MCT decoder structure */ +); + +/*! r: number of channels to be synthesised */ + +void copy_decoder_config( + Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ + Decoder_State *st /* o : decoder state structure */ +); + +void ivas_initialize_handles_dec( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_core_enc_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + const Word16 n_CoreChannels, /* i : number of core channels to be coded Q0*/ + Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal Q_new-1*/ + Word16 Q_new[], + Word32 ener_fx[], /* i : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 epsP_fx_q[], /* i : LP prediction errors */ + Word16 lsp_new_fx[][M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[][M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag[], /* i : VAD hanglover flag Q0*/ + Word16 attack_flag[], /* i : attack flag (GSC or TC) Q0*/ + Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer q_re_im_buf*/ + Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer q_re_im_buf*/ + Word16 *q_re_im_buf, + Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer e_old_wsp*/ + Word16 e_old_wsp[], + const Word16 loc_harm[], /* i : harmonicity flag Q0*/ + const Word16 cor_map_sum_fx[], /* i : speech/music clasif. parameter Q8*/ + const Word16 vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 enerBuffer_fx_exp[], /* o : energy buffer */ + Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer Qx*/ + const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag Q0*/ + const Word16 ivas_format, /* i : IVAS format Q0*/ + const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ +); + +void ivas_renderer_select( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_mc_enc_config_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*! r: flag indicating a valid bitrate */ +Word16 is_IVAS_bitrate_fx( + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +int16_t is_DTXrate( + const int32_t ivas_total_brate /* i : IVAS total bitrate */ +); + + +/*----------------------------------------------------------------------------------* + * JBM prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_jbm_dec_set_discard_samples( + Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ +); + +TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( + Decoder_Struct *st_ivas /* i : IVAS decoder handle */ +); + +void ivas_jbm_dec_tc_buffer_close( + DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ +); + +void ivas_jbm_dec_td_renderers_adapt_subframes( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_jbm_dec_metadata_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_jbm_masa_sf_to_sf_map( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +/*----------------------------------------------------------------------------------* + * ISM prototypes + *----------------------------------------------------------------------------------*/ + +void bitbudget_to_brate( + const Word16 x[], /* i : bitbudgets Q0 */ + Word32 y[], /* o : bitrates Q0 */ + const Word16 N /* i : number of entries to be converted */ +); + +void ivas_ism_reset_metadata( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ +); + +void ivas_ism_reset_metadata_enc( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ +); +void ivas_ism_reset_metadata_API( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ +); + +/*! r: index of the winning codeword */ +Word16 ism_quant_meta_fx( + const Word32 val, /* i : scalar value to quantize Q22 */ + Word32 *valQ, /* o : quantized value Q22 */ + const Word32 borders_fx[], /* i : level borders Q22 */ + const Word32 q_step_fx, /* i : quantization step Q22 */ + const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */ + const Word16 cbsize /* i : codebook size */ +); + +ivas_error ivas_ism_metadata_enc_create_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 n_ISms, /* i : number of objects */ + Word32 element_brate_tmp[] /* o : element bitrate per object */ +); + +/*----------------------------------------------------------------------------------* + * Parametric ISM prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: ISM format mode */ + +ivas_error ivas_param_ism_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_param_ism_enc_close_fx( + PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ + const Word32 input_Fs /* i : input sampling_rate */ +); + +void ivas_ism_metadata_close( + ISM_METADATA_HANDLE hIsmMetaData[], /* i/o : object metadata handles */ + const Word16 first_idx /* i : index of first handle to deallocate */ +); + + +ivas_error ivas_ism_enc_config( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*----------------------------------------------------------------------------------* + * ISM DTX prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_ism_dtx_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_ism_metadata_sid_enc_fx( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + const Word16 flag_noisy_speech, /* i : noisy speech flag */ + const Word16 nchan_ism, /* i : number of objects */ + const Word16 nchan_transport, /* i : number of transport channels */ + const ISM_MODE ism_mode, /* i : ISM mode */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const Word16 sid_flag, /* i : indication of SID frame */ + const Word16 md_diff_flag[], /* i : metadata differental flag */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + Word16 nb_bits_metadata[] /* o : number of metadata bits */ +); + + + +void ivas_param_ism_compute_noisy_speech_flag_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*----------------------------------------------------------------------------------* + * DFT Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void stereo_dft_dec_destroy( + STEREO_DFT_DEC_DATA_HANDLE *hStereoDft /* i/o: decoder DFT stereo handle */ +); + +/*----------------------------------------------------------------------------------* + * Range Coder prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: Read bit */ +UWord16 rc_uni_dec_read_bit( + RangeUniDecState *rc_st_dec /* i/o: RC state handle */ +); + +/*! r: Read bit */ +UWord16 rc_uni_dec_read_bit_prob_fast( + RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ + const Word16 freq0, /* i : Frequency for symbol 0 */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +); + +/*! r: Read bits */ +UWord16 rc_uni_dec_read_bits( + RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ + const Word16 bits /* i : Number of bits */ +); + + +/*----------------------------------------------------------------------------------* + * TD Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void tdm_bit_alloc( + const Word16 ivas_format, /* i : IVAS format */ + const Word16 ism_mode, /* i : ISM mode in combined format */ + const Word32 element_brate_wo_meta, /* i : element bitrate without metadata */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reusage flag */ + Word32 *total_brate_pri, /* o : Allocated primary channel bitrate */ + Word32 *total_brate_sec, /* o : Allocated secondary channel bitrate */ + Word16 *tdm_low_rate_mode, /* o : secondary channel low rate mode flag */ + const Word16 coder_type, /* i : secondary channel coder type */ + const Word16 ener_ratio_idx, /* i : correlation ratio indexe */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 bwidth_pri, /* i : bandwidth of the primary channel */ + const Word16 bwidth_sec, /* i : bandwidth of the secondary channel */ + const Word16 flag_ACELP16k_pri, /* i : ACELP@16kHz core flag, primary chan. */ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 coder_type0, /* i : coder type (temporary in the encoder, from bitstream in decoder) */ + const Word16 tdm_inst_ratio_idx /* i : instantaneous correlation ratio index */ +); + + +/*! r: value of the indice */ +uint16_t get_indice_st( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 pos, /* i : absolute position in the bitstream */ + const Word16 nb_bits /* i : number of bits to quantize the indice */ +); + +/*----------------------------------------------------------------------------------* + * MDCT Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void stereo_mdct_core_enc_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples Q0*/ + Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP Qx*/ + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe Q6*/ +); + +Word16 write_stereo_to_bitstream_fx +( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +); + +/*----------------------------------------------------------------------------------* + * Stereo CNG prototypes + *----------------------------------------------------------------------------------*/ +void stereo_cng_dec_update( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ +); + + +/*----------------------------------------------------------------------------------* + * Framework general prototypes + *----------------------------------------------------------------------------------*/ + +void mvc2c( + const uint8_t x[], /* i : input vector */ + uint8_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void stereo_switching_dec( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ +); + + +/*! r: number of bits written */ + + + +/*----------------------------------------------------------------------------------* + * MCT prototypes + *----------------------------------------------------------------------------------*/ +void ivas_mdct_core_whitening_enc_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples */ + Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ + Word16 pitch_buf[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe */ + Word32 *mdst_spectrum_long[CPE_CHANNELS], /* o : buffer for MDST spectrum */ + Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* o : buffer TNS bits */ + Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening */ + Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* o : size of TNS */ + Word16 p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to parameter array */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ + const Word16 nChannels, /* i : total number of coded channels */ +Word16 mdst_spectrum_e[CPE_CHANNELS][NB_DIV], +Word16 orig_spectrum_e[CPE_CHANNELS][NB_DIV] +); + +void splitAvailableBitsMCT_fx( + void **sts, /* i/o: encoder/decoder state structure */ + const Word16 total_bits, /* i : total number of available bits */ + const Word16 split_ratio[MCT_MAX_CHANNELS], /* i : ratio for splitting the bits Q0 */ + const Word16 enc_dec, /* i : encoder or decoder flag */ + const Word16 nchan /* i : number of channels */ +); + +void enc_prm_igf_mdct( + Encoder_State *st, /* i : Encoder state handle */ + BSTR_ENC_HANDLE hBstr /* i/o: Bitstream handle */ +); + +/*----------------------------------------------------------------------------------* + * Q Metadata prototypes for DirAC and MASA + *----------------------------------------------------------------------------------*/ +/*! r: number of bits written */ + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_decode( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */ +); + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_decode_hr_384_512( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const SPHERICAL_GRID_DATA *sph_grid16, /* i : spherical grid for deindexing */ + const Word16 bits_sph_idx, + const Word16 bits_sp_coh, + const UWord8 ncoding_bands_config +); + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_sid_decode( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const Word16 nchan_transport, /* i : number of transport channels */ + Word16 *element_mode, /* o : element mode */ + const Word16 ivas_format /* i : IVAS format */ +); + + +UWord16 ivas_qmetadata_reorder_generic_fx( + const Word16 signed_value +); + +void ivas_sba_set_cna_cng_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +/*! r: number of ambisonics metadata channels */ + +void ivas_sba_dirac_stereo_config( + STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */ +); + + +Word16 ivas_get_sba_dirac_stereo_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +/*----------------------------------------------------------------------------------* + * DirAC prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_dirac_enc_reconfigure( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +ivas_error ivas_mc_paramupmix_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_mc_paramupmix_enc_close_fx( + MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ + const int32_t input_Fs /* i : input sampling rate */ +); + +ivas_error ivas_mc_paramupmix_dec_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_mc_paramupmix_dec_close( + MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */ +); + +void ivas_mc_paramupmix_dec_read_BS( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_State *st, /* i/o: decoder state structure */ + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */ + Word16 *nb_bits /* o : number of bits written */ +); + +void ivas_mc_paramupmix_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + const Word16 nSamplesForRendering /* i : number of samples provided */ +); + +void ivas_param_mc_set_coded_bands_fx( + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* i/o: handle for the Parametric MC parameter coding state */ +); + +UWord16 ivas_param_mc_get_configuration_index_fx( + const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +/*----------------------------------------------------------------------------------* + * SPAR prototypes + *----------------------------------------------------------------------------------*/ + +/* MD module */ + +/*! r: number of MD subframes */ +ivas_error ivas_spar_md_dec_open( + ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const Word16 num_channels, /* i : number of internal channels */ + const Word16 sba_order, /* i : SBA order */ + const Word16 sid_format, /* i : SID format */ + const Word32 last_active_ivas_total_brate /* i : IVAS last active bitrate */ +); + +void ivas_spar_md_dec_close( + ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ +); + +ivas_error ivas_spar_md_dec_init( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const Word16 num_channels, /* i : number of internal channels */ + const Word16 sba_order /* i : SBA order */ +); + +/* Transient detector module */ +ivas_error ivas_transient_det_open_fx( + ivas_trans_det_state_t **hTranDet, /* i/o: Transient detector handle */ + const Word32 sampling_rate /* i : sampling rate */ +); + +void ivas_transient_det_close_fx( + ivas_trans_det_state_t **hTranDet /* i/o: Transient detector handle */ +); + +void ivas_huffman_encode_fx( + ivas_huffman_cfg_t *huff_cfg, + Word16 in, + Word16 *hcode, + Word16 *hlen +); + +ivas_error ivas_huffman_decode( + ivas_huffman_cfg_t *huff_cfg, + Decoder_State *st0, + Word16 *dec_out +); + +void ivas_arith_decode_cmplx_cell_array( + ivas_arith_t *pArith_re, + ivas_arith_t *pArith_re_diff, + Decoder_State *st0, + ivas_cell_dim_t *pCell_dims, + Word16 *pDo_diff, const Word16 nB, + Word16 *pSymbol_re, + Word16 *pSymbol_re_old +); + +void ivas_map_prior_coeffs_quant( + ivas_spar_md_prev_t *pSpar_md_prior, + ivas_spar_md_com_cfg *pSpar_md_cfg, + const Word16 qsi, + const Word16 nB +); + +void ivas_clear_band_coeff_idx( + ivas_band_coeffs_ind_t *pband_coeff_idx, + const UWord16 num_bands +); + + +/*----------------------------------------------------------------------------------* + * MASA prototypes + *----------------------------------------------------------------------------------*/ +ivas_error ivas_masa_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_masa_enc_close_fx( + MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */ +); + +int16_t ivas_qmetadata_encode_extended_gr_length_fx( + const UWord16 value, + const UWord16 alphabet_size, + const Word16 gr_param); + +void ivas_qmetadata_encode_extended_gr_fx( + BSTR_ENC_HANDLE hMetaData, /* i/o: q_metadata handle */ + const UWord16 value, /* i : value to be encoded */ + const UWord16 alphabet_size, /* i : alphabet size */ + const Word16 gr_param); /* i : GR order */ + + +void ivas_set_qmetadata_maxbit_req_fx( + IVAS_QMETADATA_HANDLE hQMetaData, /* o : qmetadata structure where the requirement value is set */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +); + + +/*---------------------------------------------------------------------------------* + * Binaural FastConv Renderer Prototypes +*-----------------------------------------------------------------------------------*/ + + +void ivas_binaural_hrtf_close( + HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i/o: decoder binaural hrtf handle */ +); + +/*----------------------------------------------------------------------------------* + * renderer prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_ism_renderer_close( + ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ +); + + +/*----------------------------------------------------------------------------------* + * Amplitude Panning VBAP prototypes + *----------------------------------------------------------------------------------*/ + +void panning_wrap_angles( + const float azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ + const float ele_deg, /* i : elevation in degrees for panning direction (positive up) */ + float *azi_wrapped, /* o : wrapped azimuth component */ + float *ele_wrapped /* o : wrapped elevation component */ +); + + +/*----------------------------------------------------------------------------------* + * McMASA prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_mcmasa_dec_reconfig( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +); + +void ivas_mcmasa_dmx_modify_fx( + const Word16 n_samples, /* i : input frame length in samples */ + Word32 dmx_fx[][L_FRAME48k + NS2SA(48000, IVAS_FB_ENC_DELAY_NS)], /* i/o: downmix signal to be transformed into another format Qx*/ + Word16 dmx_Q[], /* i/o : Q of the intput signal which is being transformed*/ + const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0 */ + const Word16 n_chnls_dmx_new /* i : number of downmix channels in the target format Q0*/ +); + +ivas_error ivas_mono_dmx_renderer_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +void ivas_mono_dmx_renderer_close( + MONO_DOWNMIX_RENDERER_HANDLE *hMonoDmxRenderer /* i/ i/o: Mono downmix structure */ +); + + +/*----------------------------------------------------------------------------------* + * LFE encoder low pass filter prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_lfe_lpf_enc_close_fx( + ivas_filters_process_state_t **hLfeLpf /* i/o: LFE LPF handle */ +); + + +/*----------------------------------------------------------------------------------* + * LFE Coding prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_create_lfe_enc_fx( + LFE_ENC_HANDLE *hLFE, /* o : IVAS LFE encoder structure */ + const Word32 input_Fs /* i : input sampling rate */ +); + +void ivas_lfe_enc_close_fx( + LFE_ENC_HANDLE *hLFE /* i/o: LFE encoder handle */ +); + +void ivas_filters_init_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + const Word32 *filt_coeff_fx, /* i : filter coefficients Q31- *filt_coeff_e */ + const Word16 *filt_coeff_e, /* i : exponents of filter coefficients */ + const Word16 order ) ; + +void ivas_filter_process_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ + const Word16 length, /* i : filter order */ + Word16 q_factor ); + +/*----------------------------------------------------------------------------------* + * OSBA prototypes + *----------------------------------------------------------------------------------*/ +ivas_error ivas_osba_enc_reconfig( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_set_surplus_brate_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +#ifdef DEBUG_MODE_INFO + , + const int16_t *nb_bits_metadata /* i : number of metadata bits */ +#endif +); + +void ivas_set_surplus_brate_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int32_t *ism_total_brate /* i : ISM total bitrate */ +); + +ivas_error ivas_omasa_separate_object_renderer_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_omasa_separate_object_renderer_close( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +/*----------------------------------------------------------------------------------* + * Filter-bank (FB) Mixer + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_fb_set_cfg( + IVAS_FB_CFG **pFb_cfg_out, /* o : FB config. handle */ + const Word16 ivas_format, /* i : IVAS format */ + const Word16 num_in_chans, /* i : number of FB input channels */ + const Word16 num_out_chans, /* i : number of FB output channels */ + const Word16 active_w_mixing, /* i : active_w_mixing flag */ + const Word32 sampling_Fs, /* i : sampling rate */ + const Word16 nachan_dirac_ana /* i : number of DirAR analysis channels */ +); + + +/*=============================================================================================*/ + #endif diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index 79a585e8b..c9ad84097 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 5caa850cb..6661026a8 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sba_config_fx.c b/lib_com/ivas_sba_config_fx.c index 38785956c..b3a0806d4 100644 --- a/lib_com/ivas_sba_config_fx.c +++ b/lib_com/ivas_sba_config_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index f35de8eb0..fa64b0092 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include @@ -61,12 +60,11 @@ void sns_compute_scf_fx( Word64 sum; Word32 L_tmp; const Word32 *pow_tilt; + Word16 q_shift, q_out, f_tmp; + Word16 bw, inv_bw, exp; const UWord8 nBands = pPsychParams->nBands; move16(); const UWord8 *bandLengths = pPsychParams->bandLengths; - Word8 bw = 0; - move16(); - Word16 q_shift; const Word16 w_0 = 2730; // (1.0f / 12.0f) in Q15 move16(); @@ -88,91 +86,83 @@ void sns_compute_scf_fx( IF( bandLengths == NULL ) { - bw = (Word8) shr( L_frame, 6 ); + bw = shr( L_frame, 6 ); move16(); + + exp = norm_s( bw ); + inv_bw = div_s( ONE_IN_Q14, shl( bw, exp ) ); // Q:15+14-exp = 29-exp + inv_bw = shl( inv_bw, sub( exp, 14 ) ); // Q15 + /* Energy per band */ k = 0; move16(); FOR( i = 0; i < nBands; ++i ) { - x_64[i] = 0; + sum = 0; move64(); FOR( n = 0; n < bw; ( ++n, ++k ) ) { - x_64[i] = W_add( x_64[i], W_deposit32_l( spectrum[k] ) ); // Q_in - move64(); + /* x[i] += spectrum[k]; + inv_bw is for x[i] /= bw; */ + sum = W_mac_32_16( sum, spectrum[k], inv_bw ); // Q_in+15+1 } + x_64[i] = sum; // Q_in+16 + move64(); } } ELSE { /* Energy per band */ k = 0; - move32(); + move16(); FOR( i = 0; i < nBands; ++i ) { - x_64[i] = 0; + exp = norm_s( bandLengths[i] ); + inv_bw = div_s( ONE_IN_Q14, shl( bandLengths[i], exp ) ); // Q:15+14-exp + inv_bw = shl( inv_bw, sub( exp, 14 ) ); // Q15 + + sum = 0; move64(); FOR( n = 0; n < bandLengths[i]; ( ++n, ++k ) ) { - x_64[i] = W_add( x_64[i], W_deposit32_l( spectrum[k] ) ); // Q_in - move64(); + /* x[i] += spectrum[k]; + inv_bw is for x[i] /= bandLengths[i]; */ + sum = W_mac_32_16( sum, spectrum[k], inv_bw ); // Q_in+15+1 } + x_64[i] = sum; // Q_in+16 + move64(); } } /* Move accumulated values to 32-bit */ - q_shift = 0; - move16(); - IF( x_64[0] != 0 ) + q_shift = W_norm_arr( x_64, nBands ); // W_norm_arr return 63 when all the values of the input buffer are zeroes + IF( EQ_16( q_shift, 63 ) ) { - q_shift = W_norm( x_64[0] ); - } - FOR( i = 1; i < nBands; ++i ) - { - IF( x_64[i] != 0 ) - { - q_shift = s_min( q_shift, W_norm( x_64[i] ) ); - } - } - FOR( i = 0; i < nBands; ++i ) - { - x[i] = W_extract_l( W_shl( x_64[i], sub( q_shift, 32 ) ) ); // Q_in + (q_shift - 32) - } + /* If all the values of x_64 are zeros, the scale factor (scf) values will be calculated as zeroes as per the below operations. + To avoid extra computations in such a case, set scf values as zeroes and return. */ - IF( bandLengths == NULL ) - { - Word16 inv_bw; - bw = (Word8) shr( L_frame, 6 ); - move16(); - inv_bw = div_l( ONE_IN_Q16 /*1 Q16*/, bw ); // Q15 - FOR( i = 0; i < nBands; ++i ) - { - x[i] = Mpy_32_16_1( x[i], inv_bw ); // Q_in + (q_shift - 32) - move32(); - } + set_zero_fx( scf, SNS_NPTS ); + + return; } - ELSE + + FOR( i = 0; i < nBands; ++i ) { - FOR( i = 0; i < nBands; ++i ) - { - Word16 inv_bw = div_l( ONE_IN_Q16 /*1 Q16*/, bandLengths[i] ); // Q15 - x[i] = Mpy_32_16_1( x[i], inv_bw ); // Q_in + (q_shift - 32) - move32(); - } + x[i] = W_extract_h( W_shl( x_64[i], q_shift ) ); // Q: Q_in+16+q_shift-32 = Q_in+q_shift-16 + move32(); } /* Smoothing */ - xs[0] = L_add( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[1], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[0] = Madd_32_16( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), x[1], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); FOR( i = 1; i < FDNS_NPTS - 1; i++ ) { - xs[i] = L_add( L_add( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), Mpy_32_16_1( x[i - 1], 8192 /* 0.25 in Q15 */ ) ), Mpy_32_16_1( x[i + 1], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[i] = Madd_32_16( Madd_32_16( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), x[i - 1], 8192 /* 0.25 in Q15 */ ), x[i + 1], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); } - xs[FDNS_NPTS - 1] = L_add( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[FDNS_NPTS - 1] = Madd_32_16( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); /* Pre-emphasis */ @@ -194,86 +184,83 @@ void sns_compute_scf_fx( FOR( i = 0; i < FDNS_NPTS; i++ ) { - xs[i] = Mpy_32_32( xs[i], pow_tilt[i] ); // Q_in + (q_shift - 32) + xs[i] = Mpy_32_32( xs[i], pow_tilt[i] ); // Q_in+q_shift-16+23-31 = Q_in+q_shift-24 move32(); } /* Noise floor at -40dB */ sum = 0; move64(); - FOR( Word16 ind = 0; ind < FDNS_NPTS; ind++ ) + FOR( i = 0; i < FDNS_NPTS; i++ ) { - sum = W_add( sum, W_deposit32_l( xs[ind] ) ); // Q_in + (q_shift - 32) + sum = W_mac_32_16( sum, xs[i], 1 ); // Q_in+q_shift-24+1 } - mean = W_extract_l( W_shr( sum, 6 ) ); // Q_in + (q_shift - 32) - nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // Q_in + (q_shift - 32) - nf = L_max( nf, 0 /* powf( 2.0f, -32.0f ) in Q31 */ ); // Q_in + (q_shift - 32) + q_out = sub( add( Q_in, q_shift ), 24 ); + + /* mean = sum / FDNS_NPTS; + -Q6 is for division with FDNS_NPTS and -Q1 is to reduce Q by one */ + mean = W_shl_sat_l( sum, -Q7 ); // q_out + nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // q_out + nf = L_max( nf, L_shl( 256, sub( q_out, 40 ) ) /* powf( 2.0f, -32.0f ) in Q40 */ ); // q_out FOR( i = 0; i < FDNS_NPTS; i++ ) { - if ( LT_32( xs[i], nf ) ) - { - xs[i] = nf; // Q_in + (q_shift - 32) - move32(); - } + xs[i] = L_max( xs[i], nf ); // q_out + move32(); } /* Log-domain */ FOR( i = 0; i < FDNS_NPTS; i++ ) { - Word16 e_tmp = norm_l( xs[i] ); - Word16 f_tmp = Log2_norm_lc( L_shl( xs[i], e_tmp ) ); /*Q16*/ - e_tmp = sub( sub( 34, e_tmp ), Q_in ); - /* Note: Mpy_32_16 is used temporarily for this computation, It needs to be replaced with appropriate BASOP. */ - xl[i] = Mpy_32_16( e_tmp, f_tmp, 16384 ); /* Q16 */ + /* xl[i] = logf( xs[i] ) * scale_log; + scale_log = INV_LOG_2 * 0.5f; */ + + exp = norm_l( xs[i] ); + f_tmp = Log2_norm_lc( L_shl( xs[i], exp ) ); // Q15 + exp = sub( sub( 30, exp ), q_out ); + L_tmp = L_mac( L_deposit_h( exp ), f_tmp, 1 ); // Q16 + xl[i] = L_shr( L_tmp, 1 ); // Q16 move32(); } /* Downsampling */ - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[0], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[0], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[4], w_5 ); // Q16 - xl4[0] = L_tmp; // Q16 - move32(); + L_tmp = Madd_32_16( Mpy_32_16_1( xl[0], w_0 ), xl[0], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); // Q16 + xl4[0] = Madd_32_16( L_tmp, xl[4], w_5 ); // Q16 + FOR( n = 1; n < SNS_NPTS - 1; n++ ) { - Word16 n4 = shl( n, 2 ); - - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[n4 - 1], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 1], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 3], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 4], w_5 ); // Q16 - xl4[n] = L_tmp; // Q16 + L_tmp = Mpy_32_16_1( xl[4 * n - 1], w_0 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 1], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 3], w_4 ); // Q16 + xl4[n] = Madd_32_16( L_tmp, xl[4 * n + 4], w_5 ); // Q16 move32(); } - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 5], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); // Q16 - xl4[SNS_NPTS - 1] = L_tmp; // Q16 + L_tmp = Mpy_32_16_1( xl[FDNS_NPTS - 5], w_0 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); // Q16 + xl4[SNS_NPTS - 1] = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); // Q16 move32(); /* Remove mean and scaling */ sum = 0; move64(); - FOR( Word16 ind = 0; ind < SNS_NPTS; ind++ ) + FOR( i = 0; i < SNS_NPTS; i++ ) { - sum = W_add( sum, W_deposit32_l( xl4[ind] ) ); // Q16 + sum = W_mac_32_16( sum, xl4[i], 1 ); // Q16+1 } - mean = W_extract_l( W_shr( sum, 4 ) ); // Q16 + /* mean = sum / SNS_NPTS; + -Q4 is for division with SNS_NPTS and -Q1 is to reduce Q by one */ + mean = W_shl_sat_l( sum, -Q5 ); // Q16 FOR( i = 0; i < SNS_NPTS; i++ ) { diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 96df64aa5..929eaa2c5 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -36,7 +36,6 @@ #include "basop_util.h" #include "ivas_stat_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_com/ivas_spar_com_quant_util_fx.c b/lib_com/ivas_spar_com_quant_util_fx.c index 8292de5c1..cfd03a3b3 100644 --- a/lib_com/ivas_spar_com_quant_util_fx.c +++ b/lib_com/ivas_spar_com_quant_util_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_dft_com_fx.c b/lib_com/ivas_stereo_dft_com_fx.c index 80e64c0cc..6d63bc6d1 100644 --- a/lib_com/ivas_stereo_dft_com_fx.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c index d0ffff39c..958781473 100644 --- a/lib_com/ivas_stereo_eclvq_com_fx.c +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index 9aa880842..8548797a4 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_stereo_mdct_bands_com_fx.c b/lib_com/ivas_stereo_mdct_bands_com_fx.c index c21abcf8c..43f2f16c7 100644 --- a/lib_com/ivas_stereo_mdct_bands_com_fx.c +++ b/lib_com/ivas_stereo_mdct_bands_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_mdct_stereo_com_fx.c b/lib_com/ivas_stereo_mdct_stereo_com_fx.c index dd94358af..0a773169d 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com_fx.c +++ b/lib_com/ivas_stereo_mdct_stereo_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include #include "prot_fx.h" diff --git a/lib_com/ivas_stereo_psychlpc_com_fx.c b/lib_com/ivas_stereo_psychlpc_com_fx.c index cb3c39df2..df5140895 100644 --- a/lib_com/ivas_stereo_psychlpc_com_fx.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -33,9 +33,7 @@ #include #include "options.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_stereo_td_bit_alloc_fx.c b/lib_com/ivas_stereo_td_bit_alloc_fx.c index 9074473d7..b54c1d3de 100644 --- a/lib_com/ivas_stereo_td_bit_alloc_fx.c +++ b/lib_com/ivas_stereo_td_bit_alloc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "stat_enc.h" #include "rom_com.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "prot_fx.h" diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index e15db9a15..04d6f7bf5 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index 97025b46f..3b9a8cfd7 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -36,7 +36,6 @@ #include "wmc_auto.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_com.h" diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 6bd8026c4..12234a4c0 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d0f0efb72..db0953cd9 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4701,6 +4701,7 @@ Word16 find_guarded_bits_fx( Word32 n ); Word16 L_norm_arr( const Word32 *arr, Word16 size ); Word16 norm_arr( Word16 *arr, Word16 size ); +Word16 W_norm_arr( Word64 *arr, Word16 size ); Word16 get_min_scalefactor( Word32 x, Word32 y ); diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 1f112c911..7905c7145 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -41,7 +41,6 @@ #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include diff --git a/lib_dec/ACcontextMapping_dec_fx.c b/lib_dec/ACcontextMapping_dec_fx.c index 34e74a06f..22e9fff01 100644 --- a/lib_dec/ACcontextMapping_dec_fx.c +++ b/lib_dec/ACcontextMapping_dec_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" /*-------------------------------------------------------------------* * ACcontextMapping_decode2_no_mem_s17_LC() diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 11379a62d..782654623 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -41,7 +41,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 191065855..d1ed7ad8c 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "options.h" #include "math.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 907a4a350..c1b0ce93a 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -9,7 +9,6 @@ #include "options.h" #include "stl.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "cnst.h" #include "stat_dec.h" @@ -2932,14 +2931,14 @@ static void IGF_getWhiteSpectralData_ivas( { ak = 0; move32(); - move16(); FOR( j = i - level; j < stop; j++ ) { tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) } - ak = Mult_32_16( ak, quo ); + ak = L_deposit_h( BASOP_Util_Divide3216_Scale( ak, sub( stop, sub( i, level ) ), &tmp_e ) ); + ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); n = shr( n, 1 ); diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index e73d89158..a196a1abd 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 3c234c098..8527e6703 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 5bb4736e9..7b4e5f267 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 697f9d715..25c0bea42 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -32,7 +32,6 @@ #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 9bf53f1de..6a6294377 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_decision_matrix_dec_fx.c b/lib_dec/ivas_decision_matrix_dec_fx.c index f7fd5e8e2..717bb3b93 100644 --- a/lib_dec/ivas_decision_matrix_dec_fx.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "stat_dec.h" #include "rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index d0c78b604..b8a7f61bb 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index e03913f8a..b247fd653 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -41,7 +41,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_entropy_decoder_fx.c b/lib_dec/ivas_entropy_decoder_fx.c index e637a6a93..f8bf3c091 100644 --- a/lib_dec/ivas_entropy_decoder_fx.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 8db782c4e..b11669460 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 664e3eeac..643874a82 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_ism_dtx_dec_fx.c b/lib_dec/ivas_ism_dtx_dec_fx.c index cbf088597..0f023a7ef 100644 --- a/lib_dec/ivas_ism_dtx_dec_fx.c +++ b/lib_dec/ivas_ism_dtx_dec_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_ism_metadata_dec_fx.c b/lib_dec/ivas_ism_metadata_dec_fx.c index a6f5e47b6..3288903ab 100644 --- a/lib_dec/ivas_ism_metadata_dec_fx.c +++ b/lib_dec/ivas_ism_metadata_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index eae0e9069..3aed4d3b1 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -34,7 +34,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "rom_com.h" diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index a19ba70ec..7cd93affa 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_stat_com.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 428c817ef..210425b88 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index e68c0142d..672d3fbe6 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "rom_com.h" diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 018f99fe7..210c266eb 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_ls_custom_dec_fx.c b/lib_dec/ivas_ls_custom_dec_fx.c index 45f59d82f..5ad390f9a 100644 --- a/lib_dec/ivas_ls_custom_dec_fx.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include #include "options.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index 806785c15..384865a1a 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index be2363469..697ae6345 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index 9ea666237..3c2ba7587 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "rom_com.h" diff --git a/lib_dec/ivas_mcmasa_dec_fx.c b/lib_dec/ivas_mcmasa_dec_fx.c index c2228b610..1b1715c21 100644 --- a/lib_dec/ivas_mcmasa_dec_fx.c +++ b/lib_dec/ivas_mcmasa_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_core_dec_fx.c b/lib_dec/ivas_mct_core_dec_fx.c index be457da47..fe39fd8e3 100644 --- a/lib_dec/ivas_mct_core_dec_fx.c +++ b/lib_dec/ivas_mct_core_dec_fx.c @@ -39,7 +39,6 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 081eca88d..884a44c9e 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index 69f601724..c275820fb 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index a5855a0f6..35d38d03a 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -40,7 +40,6 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include diff --git a/lib_dec/ivas_mono_dmx_renderer_fx.c b/lib_dec/ivas_mono_dmx_renderer_fx.c index bb5dead22..2eb8d84df 100644 --- a/lib_dec/ivas_mono_dmx_renderer_fx.c +++ b/lib_dec/ivas_mono_dmx_renderer_fx.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 391a27522..b88b68915 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index bf7fba094..afa604684 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_prot_rend.h" diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 07ea14ea2..6f1a233c9 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 4811911fd..84b6fe46d 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" diff --git a/lib_dec/ivas_output_config_fx.c b/lib_dec/ivas_output_config_fx.c index cb96d3b0d..3a0960960 100644 --- a/lib_dec/ivas_output_config_fx.c +++ b/lib_dec/ivas_output_config_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 08ac17799..98611ab7c 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 397f26bbc..9357394a5 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index 81768af44..c78c51c52 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_qspherical_dec_fx.c b/lib_dec/ivas_qspherical_dec_fx.c index d34b5402a..f6ac39a99 100644 --- a/lib_dec/ivas_qspherical_dec_fx.c +++ b/lib_dec/ivas_qspherical_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_range_uni_dec_fx.c b/lib_dec/ivas_range_uni_dec_fx.c index e629111ce..9a49680e8 100644 --- a/lib_dec/ivas_range_uni_dec_fx.c +++ b/lib_dec/ivas_range_uni_dec_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_dec.h" #include "cnst.h" diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index efd766f76..f04350366 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 573a9c17f..0c7544682 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index a42c67389..8748342ed 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index 89581565c..a6be10c08 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 170256181..fd25e7ea7 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index 812027468..34a194898 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -37,7 +37,6 @@ #include "ivas_stat_dec.h" #include "prot_fx.h" #include "string.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index bb79b956c..7f487a75c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c index 8446af47d..2bade4786 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec_fx.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "rom_dec.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 4d50ba350..223860db0 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 166ac72e5..f0fd1978b 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "rom_dec.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index 0781d49a6..e82005965 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index fb54476fa..1c18ffacb 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "rom_dec.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index d3415a8eb..90d9c5823 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_eclvq_dec_fx.c b/lib_dec/ivas_stereo_eclvq_dec_fx.c index 693df8c77..dfa411145 100644 --- a/lib_dec/ivas_stereo_eclvq_dec_fx.c +++ b/lib_dec/ivas_stereo_eclvq_dec_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_stereo_esf_dec_fx.c b/lib_dec/ivas_stereo_esf_dec_fx.c index 80603f6c0..d4219f1e6 100644 --- a/lib_dec/ivas_stereo_esf_dec_fx.c +++ b/lib_dec/ivas_stereo_esf_dec_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index b49ab5399..694aad0b4 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 22a8c4a90..3b32072f3 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 04781a9cb..a6b350d33 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -37,7 +37,6 @@ #include "prot_fx.h" #include "cnst.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 69083a078..3f39bd9ac 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index e5e18083d..09b683a16 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_dec/ivas_stereo_td_dec_fx.c b/lib_dec/ivas_stereo_td_dec_fx.c index 8ab7da035..023c9a2e5 100644 --- a/lib_dec/ivas_stereo_td_dec_fx.c +++ b/lib_dec/ivas_stereo_td_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -338,45 +337,6 @@ void tdm_configure_dec_fx( return; } -/*-------------------------------------------------------------------* - * Function tdm_downmix_plain() - * - * downmix Left+Right to Primary+Secondary channel - *-------------------------------------------------------------------*/ - -void tdm_upmix_plain( - float Left[], /* o : left channel */ - float Right[], /* o : right channel */ - const float PCh_2_L[], /* i : primary channel */ - const float SCh_2_R[], /* i : secondary channel */ - const float LR_ratio, /* i : mixing ratio */ - const float inv_den_LR_ratio, /* i : inverse mixing ration */ - const int16_t start_index, /* i : start index */ - const int16_t end_index, /* i : end index */ - const int16_t plus_minus_flag /* i : plus/minus flag */ -) -{ - int16_t i; - - if ( plus_minus_flag == 1 ) - { - for ( i = start_index; i < end_index; i++ ) - { - Left[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * inv_den_LR_ratio; - Right[i] = ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * inv_den_LR_ratio; - } - } - else - { - for ( i = start_index; i < end_index; i++ ) - { - Left[i] = ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * inv_den_LR_ratio; - Right[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * inv_den_LR_ratio; - } - } - - return; -} void tdm_upmix_plain_fx( Word32 Left_fx[], /* o : left channel Qx*/ Word32 Right_fx[], /* o : right channel Qx*/ diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 375dbdad0..1467687d8 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index c908e4dc3..07eba9e64 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -40,7 +40,6 @@ #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index 63819b056..98c1a6a79 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" void tdm_low_rate_dec_fx( diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 66109b555..ef3baee3c 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index d263e6dd3..21e8705f3 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * Local functions diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 44439540f..c52fddf97 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -13,7 +13,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" /* Range coder header file */ #define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) /* evaulated at compile time */ #define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /* evaluated at run time */ diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 0f58bcdad..782006108 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -13,7 +13,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index a901690e3..0e4c02744 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index c54e8ccf4..7c28c3309 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,7 +16,6 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #endif diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 9e6318591..f546c3ef8 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1165,18 +1165,30 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { + Word16 q_mdstWin, scale; L_subframe = idiv1616( L_frameTCX, nSubframes ); /* Q0 */ test(); IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { wtda_ext_fx( hTcxEnc->new_speech_TCX, mdstWin, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX, 3 ); - Scale_sig( mdstWin, L_frameTCX, 1 ); + scale = sub( norm_arr( mdstWin, L_frameTCX ), 1 ); + scale = s_min( 1, scale ); // restricting the Q to zero or less + scale_sig( mdstWin, L_frameTCX, scale ); + q_mdstWin = add( -1, scale ); + move16(); } ELSE { + Word16 sig_len; /* Windowing for the MDST */ WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 ); + sig_len = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ); + scale = sub( norm_arr( mdstWin, sig_len ), 1 ); + scale = s_min( 0, scale ); // restricting the Q to zero or less + scale_sig( mdstWin, sig_len, scale ); + q_mdstWin = scale; + move16(); } IF( EQ_16( transform_type[frameno], TCX_5 ) ) @@ -1184,7 +1196,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outer left folding */ FOR( i = 0; i < left_overlap / 2; i++ ) { - mdstWin[left_overlap / 2 + i] = add_sat( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); // Q0 + mdstWin[left_overlap / 2 + i] = add( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); // q_mdstWin } test(); @@ -1197,16 +1209,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } } @@ -1214,7 +1226,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outer right folding */ FOR( i = 0; i < right_overlap / 2; i++ ) { - mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub_sat( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); // Q0 + mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); // q_mdstWin move16(); } @@ -1229,7 +1241,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 ); - spectrum_e[frameno] = 16; + spectrum_e[frameno] = sub( 16, q_mdstWin ); move16(); TCX_MDST( tcx5Win, spectrum[frameno] + i * tcx5SizeFB, &spectrum_e[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); /* high-band gain control in case of BWS */ @@ -1250,14 +1262,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( } ELSE /* transform_type[frameno] != TCX_5 */ { - spectrum_e[frameno] = 16; + spectrum_e[frameno] = sub( 16, q_mdstWin ); test(); IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { Word16 Q; Copy_Scale_sig_16_32_no_sat( mdstWin, L_tmpbuf, N_MAX + L_MDCT_OVLP_MAX, 16 ); - Q = 16; + Q = add( q_mdstWin, 16 ); move16(); edst_fx( L_tmpbuf, spectrum[frameno], L_subframe, &Q ); spectrum_e[frameno] = 31 - Q; @@ -1284,16 +1296,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } } diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index f6adb0f31..fc7c32fdb 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 104eeb998..d74e10bda 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 5f318e959..f88288ea1 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -36,7 +36,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 46de4e232..42920a46a 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 73403a848..8d00e608c 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index 32e3e7107..f21c8e262 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -35,7 +35,6 @@ #include "ivas_cnst.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "math.h" diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index a9d62a2b0..1152736f6 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #ifdef DEBUGGING diff --git a/lib_enc/ivas_decision_matrix_enc_fx.c b/lib_enc/ivas_decision_matrix_enc_fx.c index 1158f72fa..bd63553bd 100644 --- a/lib_enc/ivas_decision_matrix_enc_fx.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index 7bfa9f268..ac0ce9556 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index 576bbb2c6..c05d59b90 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index 0a2d976e1..e8e1bc59e 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_entropy_coder_fx.c b/lib_enc/ivas_entropy_coder_fx.c index a95f2884c..3c8cf92e2 100644 --- a/lib_enc/ivas_entropy_coder_fx.c +++ b/lib_enc/ivas_entropy_coder_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index f1aeb5398..8b76b37a4 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" @@ -433,30 +432,6 @@ ivas_error front_vad_create_fx( return IVAS_ERR_OK; } -/*-----------------------------------------------------------------------------------------* - * Function front_vad_destroy() - * - * Deallocate Standalone front-VAD module - *-----------------------------------------------------------------------------------------*/ - -void front_vad_destroy( - FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ -) -{ - IF( *hFrontVad != NULL ) - { - free( ( *hFrontVad )->hNoiseEst ); - ( *hFrontVad )->hNoiseEst = NULL; - - free( ( *hFrontVad )->hVAD ); - ( *hFrontVad )->hVAD = NULL; - - free( *hFrontVad ); - *hFrontVad = NULL; - } - - return; -} void front_vad_destroy_fx( FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ ) diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index c65c85356..b49fc9716 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_enc.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 64b8991d6..b29b0c15b 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 22bf88df8..1b648cc98 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index 4305e5bca..6a2e54db6 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "prot_fx.h" diff --git a/lib_enc/ivas_ism_param_enc_fx.c b/lib_enc/ivas_ism_param_enc_fx.c index e6b23fcfc..cda8cffd6 100644 --- a/lib_enc/ivas_ism_param_enc_fx.c +++ b/lib_enc/ivas_ism_param_enc_fx.c @@ -34,7 +34,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "cnst.h" diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 11056b535..96959c9dd 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 21c23c34a..6960629c8 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 2797fa5e4..17fefec7e 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -38,7 +38,6 @@ #include "ivas_rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index abd09cbbd..fd5cb6217 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index c4d3908ca..22f21dceb 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "options.h" #include "prot_fx.h" diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 439c227ae..71515571d 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index d6bc4c7f0..56f5e44db 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 88d773b53..a8ba9a320 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 70b2b0034..3272768e9 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -37,7 +37,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -705,8 +704,8 @@ static void applyStereoPreProcessingCplx( } ELSE { - dmxR2_fx = L_sub( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 - dmxI2_fx = L_sub( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 + dmxR2_fx = L_sub( Mpy_32_32( valR2_fx, factDe_fx ), Mpy_32_32( valR1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI2_fx = L_sub( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } } ELSE @@ -1923,7 +1922,6 @@ void ivas_mdct_core_whitening_enc_fx( tcx_subframe_coded_lines = shr( tcx_subframe_coded_lines, shift ); /*tcx_subframe_coded_lines / nSubframes*/ Word16 q_pow = 62, q_pow_tmp = sub( 63, shl( mdst_spectrum_e[0][0], 1 ) ); // add( shl( sub( Q31, mdst_spectrum_e[0][0] ), 1 ), 1 ); move16(); - FOR( n = 0; n < nSubframes; n++ ) { IF( st->hTcxEnc->fUseTns[n] ) @@ -1932,34 +1930,19 @@ void ivas_mdct_core_whitening_enc_fx( { powerSpec_fx64[i] = W_mult_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ); move64(); - IF( powerSpec_fx64[i] == 0 ) - { - q_pow = s_min( q_pow, 62 ); - } - ELSE - - { - q_pow = s_min( q_pow, W_norm( powerSpec_fx64[i] ) ); - } } + q_pow = W_norm_arr( powerSpec_fx64, L_subframeTCX ); } ELSE { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpec_fx64[i] = W_add( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), W_mult_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ) ); + powerSpec_fx64[i] = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ); move64(); - IF( powerSpec_fx64[i] == 0 ) - { - q_pow = s_min( q_pow, 62 ); - } - ELSE - - { - q_pow = s_min( q_pow, W_norm( powerSpec_fx64[i] ) ); - } } + q_pow = W_norm_arr( powerSpec_fx64, L_subframeTCX ); } + FOR( i = 0; i < L_subframeTCX; i++ ) { powerSpec_fx64[i] = W_shl( powerSpec_fx64[i], q_pow ); diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 7c8b78ffb..5d79265f4 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 1229624de..2a6944c50 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" diff --git a/lib_enc/ivas_pca_enc_fx.c b/lib_enc/ivas_pca_enc_fx.c index 410d5dd52..2cb347a02 100644 --- a/lib_enc/ivas_pca_enc_fx.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include #include diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index b32c80404..2d6080995 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" diff --git a/lib_enc/ivas_qspherical_enc_fx.c b/lib_enc/ivas_qspherical_enc_fx.c index a6f40c8f0..2e7a289f9 100644 --- a/lib_enc/ivas_qspherical_enc_fx.c +++ b/lib_enc/ivas_qspherical_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_range_uni_enc_fx.c b/lib_enc/ivas_range_uni_enc_fx.c index cf32c644d..6c322a3d9 100644 --- a/lib_enc/ivas_range_uni_enc_fx.c +++ b/lib_enc/ivas_range_uni_enc_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_stat_enc.h" diff --git a/lib_enc/ivas_sba_enc_fx.c b/lib_enc/ivas_sba_enc_fx.c index 8fdca5815..e630a70d9 100644 --- a/lib_enc/ivas_sba_enc_fx.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -39,7 +39,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 8c2c945d6..2983ea2f0 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -38,7 +38,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e321f1c7c..93ee56461 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_spar_encoder_fx.c b/lib_enc/ivas_spar_encoder_fx.c index 674a80549..3b380f2eb 100644 --- a/lib_enc/ivas_spar_encoder_fx.c +++ b/lib_enc/ivas_spar_encoder_fx.c @@ -33,7 +33,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 2ace35473..997581476 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c index 70c2165f8..8e79b2288 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index bfe683d6b..3e148a5ae 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -39,7 +39,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index 255b6e938..aa7c2d0aa 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index ede3d3ad9..3eb6c0e82 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -38,7 +38,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 862102d3b..8a887de89 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -38,7 +38,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index 58e66a01a..df4fe3edd 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "prot_fx.h" #include "rom_com.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index c3cb68719..ae8a8203e 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_stereo_eclvq_enc_fx.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c index f4962c802..3abc07811 100644 --- a/lib_enc/ivas_stereo_eclvq_enc_fx.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 78c324cce..057798706 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 78891c5f7..bc84ba419 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 28b0e41b9..b68578542 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c index 57bb18e80..851df60d5 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -38,7 +38,6 @@ #include "cnst.h" #include "stat_enc.h" #include "ivas_stat_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index b1213a750..a61b2b010 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index cbdbc0501..2fe8b6c84 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index efae1e80d..44c08efa8 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 979978c03..d2ff2c0c2 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 28044b45d..1e66c1488 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -39,7 +39,6 @@ #include "rom_com.h" #include "basop_proto_func.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "rom_com_fx.h" diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 34215025f..2daa9ed50 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -39,7 +39,6 @@ #include "ivas_cnst.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 9d4736368..9093ffc40 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -39,7 +39,6 @@ #include "debug.h" #endif #include "lib_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/lp_exc_e_fx.c b/lib_enc/lp_exc_e_fx.c index 0887698f7..01005f641 100644 --- a/lib_enc/lp_exc_e_fx.c +++ b/lib_enc/lp_exc_e_fx.c @@ -53,7 +53,8 @@ Word16 lp_filt_exc_enc_fx( Word16 wtmp, wtmp1; Word32 Ltmp; - Word16 use_prev_sf_pit_gain = 0; + Word16 use_prev_sf_pit_gain = 0; // Q0 + move16(); gain1 = 0; move16(); @@ -66,7 +67,8 @@ Word16 lp_filt_exc_enc_fx( test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) ) { - use_prev_sf_pit_gain = 1; + use_prev_sf_pit_gain = 1; // Q0 + move16(); } exp_ener = 0; move16(); @@ -75,7 +77,7 @@ Word16 lp_filt_exc_enc_fx( test(); IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) ) { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener move16(); } @@ -89,7 +91,7 @@ Word16 lp_filt_exc_enc_fx( wtmp1 = 0; move16(); test(); - IF( ( EQ_16( *lp_flag, LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) + IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) { test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) ) @@ -100,6 +102,7 @@ Word16 lp_filt_exc_enc_fx( Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } ELSE @@ -110,20 +113,21 @@ Word16 lp_filt_exc_enc_fx( Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } if ( LT_16( exp_ener, exp_ener1 ) ) { - wtmp = shr( wtmp, 1 ); + wtmp = shr( wtmp, 1 ); // exp_ener + 1 } if ( GT_16( exp_ener, exp_ener1 ) ) { - wtmp1 = shr( wtmp1, 1 ); + wtmp1 = shr( wtmp1, 1 ); // exp_ener1 + 1 } /*-----------------------------------------------------------------* @@ -132,18 +136,18 @@ Word16 lp_filt_exc_enc_fx( test(); test(); - IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( EQ_16( *lp_flag, LOW_PASS ) ) ) + IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) ) { /* use the LP filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( exc_tmp, &exc[i_subfr], L_subfr ); - Copy( y1_tmp, y1, L_subfr ); - Copy( xn2_tmp, xn2, L_subfr ); + Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new + Copy( y1_tmp, y1, L_subfr ); // Q_new-1+shift + Copy( xn2_tmp, xn2, L_subfr ); // Q_new-1+shift IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain2; + *gain_pit = gain2; // Q14 move16(); g_corr[0] = g_corr2[0]; move16(); @@ -162,7 +166,7 @@ Word16 lp_filt_exc_enc_fx( move16(); IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain1; + *gain_pit = gain1; // Q14 move16(); } } @@ -193,7 +197,8 @@ Word16 lp_filt_exc_enc_ivas_fx( Word16 wtmp, wtmp1; Word32 Ltmp; - Word16 use_prev_sf_pit_gain = 0; + Word16 use_prev_sf_pit_gain = 0; // Q0 + move16(); gain1 = 0; move16(); @@ -206,7 +211,8 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) ) { - use_prev_sf_pit_gain = 1; + use_prev_sf_pit_gain = 1; // Q0 + move16(); } exp_ener = 0; move16(); @@ -215,13 +221,13 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) ) { - IF( use_prev_sf_pit_gain == 1 ) + IF( EQ_16( use_prev_sf_pit_gain, 1 ) ) { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener } - else + ELSE { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener } } @@ -235,7 +241,7 @@ Word16 lp_filt_exc_enc_ivas_fx( wtmp1 = 0; move16(); test(); - IF( ( EQ_16( *lp_flag, LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) + IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) { test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) ) @@ -246,6 +252,7 @@ Word16 lp_filt_exc_enc_ivas_fx( Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } ELSE @@ -256,15 +263,16 @@ Word16 lp_filt_exc_enc_ivas_fx( Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } - IF( use_prev_sf_pit_gain == 1 ) + IF( EQ_16( use_prev_sf_pit_gain, 1 ) ) { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } ELSE { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } } @@ -284,18 +292,18 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); test(); - IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( EQ_16( *lp_flag, LOW_PASS ) ) ) + IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) ) { /* use the LP filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( exc_tmp, &exc[i_subfr], L_subfr ); - Copy( y1_tmp, y1, L_subfr ); - Copy( xn2_tmp, xn2, L_subfr ); + Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new + Copy( y1_tmp, y1, L_subfr ); // Q_new-1+shift + Copy( xn2_tmp, xn2, L_subfr ); // Q_new-1+shift IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain2; + *gain_pit = gain2; // Q14 move16(); g_corr[0] = g_corr2[0]; move16(); @@ -314,7 +322,7 @@ Word16 lp_filt_exc_enc_ivas_fx( move16(); IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain1; + *gain_pit = gain1; // Q14 move16(); } } @@ -367,9 +375,9 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation { FOR( i = 0; i < L_subfr; i++ ) { - exc_tmp[i] = mult( exc[i], 8192 ); + exc_tmp[i] = mult( exc[i], 8192 /*0.25.Q15*/ ); // Q_new move16(); - xn_tmp[i] = mult( xn[i], 8192 ); + xn_tmp[i] = mult( xn[i], 8192 /*0.25.Q15*/ ); // Q_new move16(); } Overflow = 0; @@ -383,14 +391,14 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation test(); if ( EQ_16( clip_gain, 1 ) && GT_16( *gain, 15565 ) ) /* constant in Q14 */ { - *gain = 15565; + *gain = 15565; // 0.95.Q14 move16(); } test(); - if ( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) + IF( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) // 0.65.Q14 { - *gain = 10650; + *gain = 10650; // 0.65.Q14 move16(); } } @@ -403,14 +411,14 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation /* could possibly happen in GSC */ Ltmp = Calc_Energy_Autoscaled( xn2, 0, L_subfr, exp_ener ); i = norm_l( Ltmp ); - ener = extract_h( L_shl( Ltmp, i ) ); + ener = extract_h( L_shl( Ltmp, i ) ); // exp_ener i = sub( 31, i ); *exp_ener = sub( i, *exp_ener ); move16(); } ELSE { - ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); + ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); // Q15 } return ener; @@ -424,9 +432,9 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation *-------------------------------------------------------------------*/ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) */ - const Word16 xn_1[], /* i : target signal */ - const Word16 y1_1[], /* i : filtered adaptive codebook excitation */ - Word16 g_corr[], /* o : correlations and -2 */ + const Word16 xn_1[], /* i : target signal Q_new*/ + const Word16 y1_1[], /* i : filtered adaptive codebook excitation 12 bits*/ + Word16 g_corr[], /* o : correlations and -2 mant/exp*/ const Word16 L_subfr, /* i : vector length */ const Word16 norm_flag /* i : flag for constraining pitch contribution */ , @@ -446,7 +454,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) *----------------------------------------------------------------*/ /* Compute scalar product */ - Copy( xn_1, xn, L_subfr ); + Copy( xn_1, xn, L_subfr ); // Q_new Copy( y1_1, y1, L_subfr ); Overflow = 0; move16(); @@ -457,9 +465,9 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) { FOR( i = 0; i < L_subfr; i++ ) { - xn[i] = mult_r( xn_1[i], 4096 ); + xn[i] = mult_r( xn_1[i], 4096 /*0.125.Q15*/ ); // Q-new move16(); - y1[i] = mult_r( y1_1[i], 4096 ); + y1[i] = mult_r( y1_1[i], 4096 /*0.125.Q15*/ ); move16(); } @@ -484,7 +492,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) } ELSE { - yy = extract_h( Ltmp1 ); + yy = extract_h( Ltmp1 ); // exp_yy /* Ltmp1 = L_shr(Ltmp1, sub(30, exp_yy));*/ /* Compute scalar product */ @@ -499,7 +507,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) g_corr[1] = exp_yy; move16(); /* -2.0*temp1 + 0.01 is done in Gain_enc_2 function*/ - g_corr[2] = xy; + g_corr[2] = xy; // exp_xy move16(); g_corr[3] = exp_xy; move16(); @@ -510,8 +518,8 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) IF( xy >= 0 && NE_16( s_or( yy, xy ), 16384 ) ) { /* compute gain = xy/yy */ - xy = shr( xy, 1 ); /* be sure that xy < yy */ - gain = div_s( xy, yy ); + xy = shr( xy, 1 ); /* be sure that xy < yy */ + gain = div_s( xy, yy ); // Q15 i = sub( exp_xy, exp_yy ); gain = shl_o( gain, i, &Overflow ); /* saturation can occur here */ *Overflow_out |= Overflow; @@ -536,7 +544,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) /* gain_p_snr = sqrt(/) */ tmp = BASOP_Util_Divide1616_Scale( xx, yy, &exp_div ); exp_xx = add( sub( exp_xx, exp_yy ), exp_div ); - tmp = Sqrt16( tmp, &exp_xx ); + tmp = Sqrt16( tmp, &exp_xx ); // exp_xx /* Note: shl works as shl or shr. */ exp_xx = sub( exp_xx, 1 ); @@ -544,8 +552,8 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) gain_p_snr = round_fx_sat( L_shl_sat( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_xx ) ); BASOP_SATURATE_WARNING_ON_EVS - gain = s_min( gain, gain_p_snr ); + gain = s_min( gain, gain_p_snr ); // Q14 } - return gain; + return gain; // Q14 } diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 24179f375..6761dfb82 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -74,8 +74,10 @@ void lsf_enc_fx( const Word16 Q_new ) { Word16 nBits = 0; + move16(); Word16 int_fs; Word16 force_sf = 0; + move16(); Word16 fec_lsf[M], stab, i; Word32 L_tmp; Word16 coder_type, ppp_mode, nelp_mode; @@ -189,7 +191,7 @@ void lsf_enc_fx( lsf2lsp_fx( lsf_new, lsp_new, M, int_fs ); test(); - IF( EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) ) + IF( EQ_16( st_fx->last_core, HQ_CORE ) && ( st_fx->core == ACELP_CORE ) ) { /* don't use old LSF values if this is the first ACELP frame after HQ frames */ Copy( lsf_new, st_fx->lsf_old_fx, M ); @@ -216,7 +218,7 @@ void lsf_enc_fx( FEC_lsf_estim_enc_fx( st_fx, fec_lsf ); /* in case of FEC in decoder - calculate LSF stability */ - stab = lsf_stab_fx( lsf_new, fec_lsf, 0, st_fx->L_frame ); + stab = lsf_stab_fx( lsf_new, fec_lsf, 0, st_fx->L_frame ); // Q15 test(); test(); @@ -255,8 +257,8 @@ void lsf_enc_fx( if ( st_fx->rate_switching_reset ) { /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st_fx->lsp_old_fx, M ); - Copy( lsf_new, st_fx->lsf_old_fx, M ); + Copy( lsp_new, st_fx->lsp_old_fx, M ); // Q15 + Copy( lsf_new, st_fx->lsf_old_fx, M ); // Q15 } /* Mid-frame LSF encoding */ lsf_mid_enc_fx( st_fx->hBstr, st_fx->acelp_cfg.mid_lsf_bits, int_fs, st_fx->lsp_old_fx, lsp_new, lsp_mid, coder_type, st_fx->bwidth, st_fx->Bin_E_old_fx, st_fx->Bin_E_fx, Q_new + QSCALE - 2, ppp_mode, nelp_mode ); @@ -265,7 +267,7 @@ void lsf_enc_fx( IF( EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) ) { /* don't use old LSP/LSF values if this is the first ACELP frame after HQ frames */ - Copy( lsp_mid, st_fx->lsp_old_fx, M ); + Copy( lsp_mid, st_fx->lsp_old_fx, M ); // Q15 lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, int_fs ); } @@ -299,10 +301,10 @@ void lsf_enc_fx( void lsf_enc_ivas_fx( Encoder_State *st, /* i/o: state structure */ - Word16 *lsf_new, /* o : quantized LSF vector */ - Word16 *lsp_new, /* i/o: LSP vector to quantize/quantized */ - Word16 *lsp_mid, /* i/o : mid-frame LSP vector */ - Word16 *Aq, /* o : quantized A(z) for 4 subframes */ + Word16 *lsf_new, /* o : quantized LSF vector Q(x2.56)*/ + Word16 *lsp_new, /* i/o: LSP vector to quantize/quantized Q15*/ + Word16 *lsp_mid, /* i/o : mid-frame LSP vector Q15*/ + Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ @@ -462,15 +464,15 @@ void lsf_enc_ivas_fx( IF( NE_16( st->last_L_frame, st->L_frame ) ) { /* FEC - in case of core switching, use old LSFs */ - Copy( st->lsf_old_fx, st->lsfoldbfi1_fx, M ); - Copy( st->lsf_old_fx, st->lsfoldbfi0_fx, M ); - Copy( st->lsf_old_fx, st->lsf_adaptive_mean_fx, M ); + Copy( st->lsf_old_fx, st->lsfoldbfi1_fx, M ); // Q15 + Copy( st->lsf_old_fx, st->lsfoldbfi0_fx, M ); // Q15 + Copy( st->lsf_old_fx, st->lsf_adaptive_mean_fx, M ); // Q15 } FEC_lsf_estim_enc_fx( st, fec_lsf ); /* in case of FEC in decoder - calculate LSF stability */ - stab = lsf_stab_ivas_fx( lsf_new, fec_lsf, 0, st->L_frame ); + stab = lsf_stab_ivas_fx( lsf_new, fec_lsf, 0, st->L_frame ); // Q15 test(); test(); @@ -509,8 +511,8 @@ void lsf_enc_ivas_fx( IF( st->rate_switching_reset ) { /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st->lsp_old_fx, M ); - Copy( lsf_new, st->lsf_old_fx, M ); + Copy( lsp_new, st->lsp_old_fx, M ); // Q15 + Copy( lsf_new, st->lsf_old_fx, M ); // Q15 } /* Mid-frame LSF encoding */ lsf_mid_enc_ivas_fx( st->hBstr, st->acelp_cfg.mid_lsf_bits, st->sr_core, st->lsp_old_fx, lsp_new, lsp_mid, coder_type, st->bwidth, st->Bin_E_old_fx, Q_new + QSCALE - 2, ppp_mode, nelp_mode ); @@ -529,9 +531,9 @@ void lsf_enc_ivas_fx( { IF( EQ_16( st->active_cnt, 1 ) ) { - Copy( lsp_mid, st->lsp_old_fx, M ); + Copy( lsp_mid, st->lsp_old_fx, M ); // Q15 lsp2lsf_fx( lsp_mid, st->lsf_old_fx, M, st->sr_core ); - Copy( lsp_new, lsp_mid, M ); + Copy( lsp_new, lsp_mid, M ); // Q15 } /* LSP interpolation and conversion of LSPs to A(z) - two-subframe mode */ @@ -546,7 +548,7 @@ void lsf_enc_ivas_fx( *------------------------------------------------------------------*/ IF( NE_32( st->core_brate, SID_2k40 ) ) { - st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st->lsf_old_fx, 0, st->L_frame ); + st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st->lsf_old_fx, 0, st->L_frame ); // Q15 } return; } @@ -847,8 +849,8 @@ static Word16 qlsf_Mode_Select_fx( /*========================================================================*/ void lsf_end_enc_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) */ - Word16 *qlsf, /* o : quantized LSF */ + const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) x2.56*/ + Word16 *qlsf, /* o : quantized LSF x2.56*/ const Word16 nBits_in, /* i : number of bits to spend on ISF quantization */ const Word16 coder_type_org, /* i : coding type */ Word16 Q_ener, /* i : Q valuen for Bin_Ener */ @@ -1008,7 +1010,7 @@ void lsf_end_enc_fx( IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) { /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ - st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); + st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); // Q15 move16(); } @@ -1211,7 +1213,7 @@ void lsf_end_enc_fx( { lpc_param[i] = TCQIdx0[i]; move16(); - bits_param_lpc[i] = BC_TCVQ_BIT_ALLOC_40B[i]; + bits_param_lpc[i] = BC_TCVQ_BIT_ALLOC_40B[i]; // Q0 move16(); } } @@ -1352,8 +1354,8 @@ void lsf_end_enc_fx( void lsf_end_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) */ - Word16 *qlsf, /* o : quantized LSF */ + const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) x2.56*/ + Word16 *qlsf, /* o : quantized LSF x2.56*/ const Word16 nBits_in, /* i : number of bits to spend on ISF quantization */ const Word16 coder_type_org, /* i : coding type */ Word16 Q_ener, /* i : Q valuen for Bin_Ener */ @@ -1944,10 +1946,10 @@ void lsf_end_enc_ivas_fx( static void first_VQstages( const Word16 *const *cb, - Word16 u[], /* i : vector to be encoded (prediction and mean removed) */ + Word16 u[], /* i : vector to be encoded (prediction and mean removed) x2.56*/ Word16 *levels, /* i : number of levels in each stage */ Word16 stagesVQ, /* i : number of stages */ - Word16 w[], /* i : weights */ + Word16 w[], /* i : weights Q8*/ Word16 N, /* i : vector dimension */ Word16 max_inner, /* i : maximum number of swaps in inner loop */ Word16 indices_VQstage[] ) @@ -2338,10 +2340,10 @@ static void first_VQstages_ivas_fx( static Word32 vq_lvq_lsf_enc( Word16 pred_flag, Word16 mode, - Word16 u[], + Word16 u[], // x2.56 Word16 *levels, Word16 stages, - Word16 w[], + Word16 w[], // Q8 Word16 Idx[], const Word16 *lsf, const Word16 *pred, @@ -2370,13 +2372,13 @@ static Word32 vq_lvq_lsf_enc( { cb = &Quantizers_fx[CB_lsf[mode]]; move16(); - mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][sub( levels[stagesVQ], min_lat_bits_SN_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][( levels[stagesVQ] - min_lat_bits_SN_fx[mode] )] ); // Q0 } ELSE /* predictive */ { cb = &Quantizers_p_fx[CB_p_lsf[mode]]; move16(); - mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][sub( levels[stagesVQ], min_lat_bits_pred_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][( levels[stagesVQ] - min_lat_bits_pred_fx[mode] )] ); // Q0 } IF( stagesVQ > 0 ) { @@ -2421,7 +2423,7 @@ static Word32 vq_lvq_lsf_enc( { L_tmp = L_mac( L_tmp, mult( diff[j], shl_o( w[j], 1, &Overflow ) ), diff[j] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ } - e[i] = L_tmp; + e[i] = L_tmp; /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ move32(); } @@ -2447,10 +2449,10 @@ static Word32 vq_lvq_lsf_enc( static Word32 vq_lvq_lsf_enc_ivas_fx( Word16 pred_flag, Word16 mode, - Word16 u[], + Word16 u[], // x2.56 Word16 *levels, Word16 stages, - Word16 w[], + Word16 w[], // Q8 Word16 Idx[], const Word16 *lsf, const Word16 *pred, @@ -2478,7 +2480,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( LT_16( mode, 6 ) ) { move16(); - mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( levels[stagesVQ], min_lat_bits_SN[mode] )] ); + mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][( levels[stagesVQ] - min_lat_bits_SN[mode] )] ); } ELSE { @@ -2492,7 +2494,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( LT_16( mode, 6 ) || EQ_16( mode, 12 ) ) { move16(); - mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( levels[stagesVQ], min_lat_bits_pred_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][( levels[stagesVQ] - min_lat_bits_pred_fx[mode] )] ); } ELSE { @@ -2572,7 +2574,7 @@ static void BcTcvq_1st_fx( Word16 c[][16], Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2)*/ Word16 Q_fx[][16][2], - Word16 W_fx[][2] /*Q10*/ + Word16 W_fx[][2] /*Q8*/ ) { Word16 state, prev_state; @@ -2633,7 +2635,7 @@ static void BcTcvq_2nd_fx( Word16 c[][16], Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2) */ Word16 Q_fx[][16][2], /*x2.56*/ - Word16 W_fx[][2], /*Q10*/ + Word16 W_fx[][2], /*Q8*/ const Word16 itc_fx[][2][2] /*Q15*/ ) { @@ -2921,12 +2923,12 @@ static Word32 BcTcvq_FixSearch_fx( Q_fx[stage][*prev_state][1] = add( CB_fx[stage4][bestCode][1], pred_fx[1] ); move16(); - minDist_fx = L_shr( minDist_fx, 2 ); + minDist_fx = L_shr( minDist_fx, 2 ); /*2.56*2.56*Q(-5 - 2)*/ return minDist_fx; } static Word16 optimalPath_fx( - Word32 cDist_fx[][16], - Word32 blockDist_fx[], + Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2)*/ + Word32 blockDist_fx[], /*2.56*2.56*Q(-5 - 2)*/ Word16 blockCodeword[][4], Word16 bestCodeword[], Word16 codeWord[][16], @@ -2985,10 +2987,11 @@ static Word16 optimalPath_fx( static void quantEnc_fx( Word16 *y_fx, Word16 c[], - const Word16 CB_SUB1_fx[][128][2], - const Word16 CB_SUB2_fx[][64][2], - const Word16 CB_SUB3_fx[][32][2], - const Word16 itc_fx[][2][2] ) + const Word16 CB_SUB1_fx[][128][2], /*x2.56*/ + const Word16 CB_SUB2_fx[][64][2], /*x2.56*/ + const Word16 CB_SUB3_fx[][32][2], /*x2.56*/ + const Word16 itc_fx[][2][2] // Q15 +) { Word16 i, j; Word16 stage; @@ -3103,9 +3106,9 @@ static void buildCode_fx( } static void BcTcvq_fx( Word16 snFlag, - const Word16 *x_fx, - Word16 *y_fx, - const Word16 *weight_fx, + const Word16 *x_fx, // x2.65 + Word16 *y_fx, // x2.65 + const Word16 *weight_fx, // Q8 Word16 *ind ) { Word16 X_fx[N_STAGE_VQ][N_DIM], W_fx[N_STAGE_VQ][N_DIM]; @@ -3162,9 +3165,9 @@ static void BcTcvq_fx( { FOR( j = 0; j < N_DIM; j++ ) { - X_fx[i][j] = x_fx[( N_DIM * i ) + j]; + X_fx[i][j] = x_fx[( N_DIM * i ) + j]; // x2.65 move16(); - W_fx[i][j] = weight_fx[( N_DIM * i ) + j]; + W_fx[i][j] = weight_fx[( N_DIM * i ) + j]; // x2.56 move16(); } } @@ -3259,10 +3262,10 @@ static void BcTcvq_fx( } static Word16 SVQ_2d_fx( - Word16 *x_fx, - Word16 *y_fx, - const Word16 *W_fx, - const Word16 CB_fx[][8], + Word16 *x_fx, // x2.65 + Word16 *y_fx, // x2.65 + const Word16 *W_fx, // Q8 + const Word16 CB_fx[][8], // x2.65 Word16 Size ) { Word16 i, j; @@ -3280,7 +3283,7 @@ static Word16 SVQ_2d_fx( { temp16_fx = sub( x_fx[j], CB_fx[i][j] ); distortion_fx = L_add( distortion_fx, - L_shr( Mult_32_16( L_mult( temp16_fx, temp16_fx ), W_fx[j] ), 1 ) ); + L_shr( Mult_32_16( L_mult( temp16_fx, temp16_fx ), W_fx[j] ), 1 ) ); // (2*x2.65 + Q1 + Q8) - Q15 - Q1 } IF( LT_32( distortion_fx, temp_fx ) ) @@ -3403,9 +3406,9 @@ Word32 qlsf_ARSN_tcvq_Enc_16k_fx( } static void FFT_Mid_Interpol_16k_fx( - Word32 Bin_Ener_old[], /* i/o: Old 2nd FFT Bin energy (128) */ - Word32 Bin_Ener[], /* i : Current 2nd FFT Bin energy (128) */ - Word32 Bin_Ener_mid[] /* o : LP weighting filter (numerator) */ + Word32 Bin_Ener_old[], /* i/o: Old 2nd FFT Bin energy (128) Q_ener*/ + Word32 Bin_Ener[], /* i : Current 2nd FFT Bin energy (128) Q_ener*/ + Word32 Bin_Ener_mid[] /* o : LP weighting filter (numerator) Q_ener*/ ) { Word16 i; @@ -3642,12 +3645,12 @@ static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 nb_bits, /* i : number of bits */ const Word32 int_fs, /* i : internal (ACELP) sampling frequency*/ - const Word16 qlsp0[], /* i : quantized LSPs from frame beginning*/ - const Word16 qlsp1[], /* i : quantized LSPs from frame end */ - Word16 lsp[], /* i/o: mid-frame LSP */ + const Word16 qlsp0[], /* i : quantized LSPs from frame beginning Q15*/ + const Word16 qlsp1[], /* i : quantized LSPs from frame end Q15*/ + Word16 lsp[], /* i/o: mid-frame LSP Q15*/ const Word16 coder_type, /* i : coding type */ const Word16 bwidth, /* i : input signal bandwidth */ - Word32 Bin_Ener[], /* i : per bin log energy spectrum */ + Word32 Bin_Ener[], /* i : per bin log energy spectrum Q_ener*/ Word16 Q_ener, /* i : Q value of Bin_ener */ Word16 ppp_mode, Word16 nelp_mode ) @@ -3681,19 +3684,19 @@ static void lsf_mid_enc_ivas_fx( { case 5: { - ratio = tbl_mid_voi_wb_5b_fx; + ratio = tbl_mid_voi_wb_5b_fx; // Q13 move16(); BREAK; } case 4: { - ratio = tbl_mid_voi_wb_4b_fx; + ratio = tbl_mid_voi_wb_4b_fx; // Q13 move16(); BREAK; } case 1: { - ratio = tbl_mid_voi_wb_1b_fx; + ratio = tbl_mid_voi_wb_1b_fx; // Q13 move16(); BREAK; } @@ -3701,7 +3704,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( coder_type, UNVOICED ) ) { - ratio = tbl_mid_unv_wb_5b_fx; + ratio = tbl_mid_unv_wb_5b_fx; // Q13 } ELSE { @@ -3710,19 +3713,19 @@ static void lsf_mid_enc_ivas_fx( { case 5: { - ratio = tbl_mid_gen_wb_5b_fx; + ratio = tbl_mid_gen_wb_5b_fx; // Q13 move16(); BREAK; } case 4: { - ratio = tbl_mid_gen_wb_4b_fx; + ratio = tbl_mid_gen_wb_4b_fx; // Q13 move16(); BREAK; } case 2: { - ratio = tbl_mid_gen_wb_2b_fx; + ratio = tbl_mid_gen_wb_2b_fx; // Q13 move16(); BREAK; } @@ -3734,7 +3737,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( ppp_mode, 1 ) ) { - ratio = tbl_mid_voi_wb_1b_fx; + ratio = tbl_mid_voi_wb_1b_fx; // Q13 move16(); nb_bits = 1; move16(); @@ -3743,7 +3746,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( nelp_mode, 1 ) ) { - ratio = tbl_mid_unv_wb_4b_fx; + ratio = tbl_mid_unv_wb_4b_fx; // Q13 move16(); nb_bits = 4; move16(); @@ -3765,7 +3768,7 @@ static void lsf_mid_enc_ivas_fx( FOR( j = 0; j < M; j++ ) { /* qlsf[j] = (1.0f - ratio[k*M+j]) * qlsf0[j] + ratio[k*M+j] * qlsf1[j]; */ - L_tmp = L_mult( sub( 0x2000, ratio[k1 + j] ), qlsf0[j] ); + L_tmp = L_mult( sub( 0x2000 /*1.Q13*/, ratio[k1 + j] ), qlsf0[j] ); L_tmp = L_mac( L_tmp, ratio[k1 + j], qlsf1[j] ); qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); @@ -3802,7 +3805,7 @@ static void lsf_mid_enc_ivas_fx( FOR( j = 0; j < M; j++ ) { /* qlsf[j] = (1.0f - ratio[idx*M+j]) * qlsf0[j] + ratio[idx*M+j] * qlsf1[j]; */ - L_tmp = L_mult( sub( 0x2000, ratio[idx * M + j] ), qlsf0[j] ); + L_tmp = L_mult( sub( 0x2000 /*1.Q13*/, ratio[idx * M + j] ), qlsf0[j] ); L_tmp = L_mac( L_tmp, ratio[idx * M + j], qlsf1[j] ); qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 28e1a39de..60375ddcc 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -37,7 +37,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" @@ -93,7 +92,7 @@ Word16 msvq_stage1_dct_search_fx( Word32 *dist1_ptr_fx, /* o : resulting stage 1 MSEs in DCT-N domain */ Word16 *dist1_ptr_e ) { - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; // Q20 Word32 u_mr_fx[FDCNG_VQ_MAX_LEN]; Word16 dist1_ptr_e_buf[2 * LSFMBEST_MAX]; Word64 mse_trunc_segm_fx[FDCNG_VQ_DCT_NSEGM]; @@ -127,7 +126,7 @@ Word16 msvq_stage1_dct_search_fx( tmp_e = s_max( 12, u_e ); FOR( i = 0; i < n_ana; i++ ) { - u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); + u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); // tmp_e move32(); } @@ -136,9 +135,9 @@ Word16 msvq_stage1_dct_search_fx( /* init search state ptr's at the top */ set32_fx( dist1_ptr_fx, MAX_32, maxC_st1 ); set16_fx( dist1_ptr_e_buf, 32, maxC_st1 ); - st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ - st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */ - st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ + st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ // st1_mse_pair_e + st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */ + st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ set64_fx( mse_trunc_segm_fx, 0, n_segm ); // set16_fx( mse_trunc_segm_e, u_e, FDCNG_VQ_DCT_NSEGM ); @@ -152,7 +151,7 @@ Word16 msvq_stage1_dct_search_fx( FOR( i = 0; i < trunc_dct_cols_per_segment[segm]; i++ ) { - mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); + mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); // Q41 move64(); } @@ -163,7 +162,7 @@ Word16 msvq_stage1_dct_search_fx( /* unweighted segmented search DCT domain loop */ j_full = add( j, cum_entries_per_segment[segm] ); /* or simply use j_full++ */ - mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ + mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ // Q41 move64(); dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */ @@ -176,10 +175,10 @@ Word16 msvq_stage1_dct_search_fx( SHIFT( 1 ); ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/ #undef WMC_TOOL_SKIP - mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ + mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ // Q41 } Word16 L_tmp = W_norm( mse_fx ); - st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ + st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ // st1_mse_ptr_e move32(); st1_mse_ptr_e[j_full] = sub( shl( tmp_e, 1 ), L_tmp ); move16(); @@ -362,9 +361,9 @@ Word16 msvq_stage1_dct_search_fx( /*! r: (updated p_max) */ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( - const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors */ + const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors st1_syn_vec_e*/ const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */ - const Word32 *u_fx, /* i : target signal */ + const Word32 *u_fx, /* i : target signal u_e*/ const Word16 u_e, /* i : exp for target signal */ const Word16 maxC_st1, /* i : number of candidates in stage1 */ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ @@ -390,7 +389,7 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */ FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ ) { - high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); + high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); // tmp_e move32(); } acc = 0; @@ -457,7 +456,7 @@ void msvq_enc_ivas_fx( Word16 j; const Word16 *cbp, *cb_stage; Word32 resid_buf_fx[2 * LSFMBEST_MAX * M_MAX], *resid_fx[2]; - Word32 *pTmp, *p1, *p2; + Word32 *pTmp, *p1, *p2; // pTmp_e Word16 pTmp_e; Word16 *indices[2], m, s, c, c2, p_max, i; Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX]; diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index b81cc18e8..aa2255c68 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -36,10 +36,10 @@ val2 = shr( ( cbp )[2], 4 ); \ val3 = add( add( shr( lshl( ( cbp )[2], 12 ), 4 ), lshr( lshl( ( cbp )[1], 12 ), 8 ) ), s_and( ( cbp )[0], 0xF ) ); /*--------------------------------------------------------------------------* - * depack_mul_values() + * depack_mul_values_fx() * *--------------------------------------------------------------------------*/ -static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N ) +static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N ) { Word16 i, val0, val1, val2, val3; Word32 en; @@ -69,7 +69,7 @@ static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp * depack_sub_values() * *--------------------------------------------------------------------------*/ -static void depack_sub_values( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N ) +static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N ) { Word16 j, val0, val1, val2, val3; @@ -93,7 +93,7 @@ static void depack_sub_values( Word16 *pTmp, const Word16 *p1, const Word16 *cbp * * Unroll of inner search loop for maxC == 8 *--------------------------------------------------------------------------*/ -static Word16 msvq_enc_find_p_max_8( Word32 dist[] ) +static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] ) { Word16 p_max; @@ -144,7 +144,7 @@ static Word16 msvq_enc_find_p_max_8( Word32 dist[] ) * * Unroll of inner search loop for maxC == 6 *--------------------------------------------------------------------------*/ -static Word16 msvq_enc_find_p_max_6( Word32 dist[] ) +static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] ) { Word16 p_max; @@ -194,7 +194,7 @@ void msvq_enc_fx( const Word16 maxC, /* i : Tree search size (number of candidates kept from */ /* one stage to the next == M-best) */ const Word16 stages, /* i : Number of stages */ - const Word16 w[], /* i : Weights */ + const Word16 w[], /* i : Weights Q8*/ const Word16 N, /* i : Vector dimension */ const Word16 maxN, /* i : Codebook dimension */ Word16 Idx[] /* o : Indices */ @@ -231,11 +231,11 @@ void msvq_enc_fx( set16_fx( parents, 0, maxC ); - func_ptr = msvq_enc_find_p_max_6; + func_ptr = msvq_enc_find_p_max_6_fx; move16(); if ( EQ_16( maxC, 8 ) ) { - func_ptr = msvq_enc_find_p_max_8; + func_ptr = msvq_enc_find_p_max_8_fx; move16(); } @@ -326,7 +326,7 @@ void msvq_enc_fx( FOR( j = 0; j < levels[s]; j++ ) { /* Compute weighted codebook element and its energy */ - en = depack_mul_values( Tmp + start, w + start, cbp, n ); + en = depack_mul_values_fx( Tmp + start, w + start, cbp, n ); cbp += N34; /* pointer is incremented */ @@ -378,7 +378,7 @@ void msvq_enc_fx( move16(); Copy( p1, pTmp, start ); - depack_sub_values( pTmp + start, p1 + start, &cb[s][p2i * N34], n ); + depack_sub_values_fx( pTmp + start, p1 + start, &cb[s][p2i * N34], n ); Copy( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) ); pTmp += N; @@ -407,12 +407,12 @@ void msvq_enc_fx( *--------------------------------------------------------------------------*/ void midlsf_enc_fx( - const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ - const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ - const Word16 lsf[], /* i: lsf coefficients (3Q12) */ - Word16 *idx, /* o: codebook index */ - const Word16 lpcorder, /* i: order of the lpc */ - const Word32 *Bin_Ener_128_fx, + const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 lsf[], /* i: lsf coefficients (3Q12) */ + Word16 *idx, /* o: codebook index */ + const Word16 lpcorder, /* i: order of the lpc */ + const Word32 *Bin_Ener_128_fx, // Q_ener const Word16 Q_ener, const Word8 narrowBand, const Word32 sr_core, @@ -502,8 +502,8 @@ void midlsf_enc_fx( * Returns: number of indices *--------------------------------------------------------------------------*/ Word16 Q_lsf_tcxlpc_fx( - /* const */ Word16 lsf[], /* i : original lsf */ - Word16 lsf_q[], /* o : quantized lsf */ + /* const */ Word16 lsf[], /* i : original lsf 14Q1 * 1.28 */ + Word16 lsf_q[], /* o : quantized lsf (14Q1*1.28)*/ Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ Word16 indices[], /* o : VQ indices */ const Word16 lpcorder, /* i : LPC order */ @@ -511,7 +511,7 @@ Word16 Q_lsf_tcxlpc_fx( const Word16 cdk, /* i : codebook selector */ const Word16 mem_MA[], /* i : MA memory */ const Word16 coder_type, - const Word32 *Bin_Ener, + const Word32 *Bin_Ener, // Q_ener const Word16 Q_ener ) { Word16 weights[M + 1]; @@ -578,7 +578,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { - lsf_q_ind[i] = lsf_q[i]; + lsf_q_ind[i] = lsf_q[i]; /*(14Q1*1.28)*/ move16(); } @@ -891,7 +891,7 @@ Word16 enc_lsf_tcxlpc_ivas_fx( Word16 lsf_msvq_ma_encprm_fx( BSTR_ENC_HANDLE hBstr, - Word16 *param_lpc, + Word16 *param_lpc, // Q0 Word16 core, Word16 acelp_mode, Word16 acelp_midLpc, @@ -916,7 +916,7 @@ Word16 lsf_msvq_ma_encprm_fx( IF( NE_16( acelp_mode, VOICED ) ) { test(); - IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + IF( ( core == ACELP_CORE ) && acelp_midLpc ) { push_next_indice_fx( hBstr, *param_lpc, bits_midlpc ); @@ -928,7 +928,7 @@ Word16 lsf_msvq_ma_encprm_fx( } Word16 lsf_msvq_ma_encprm_ivas_fx( BSTR_ENC_HANDLE hBstr, - const Word16 *param_lpc, + const Word16 *param_lpc, // Q0 const Word16 core, const Word16 acelp_mode, const Word16 acelp_midLpc, @@ -953,7 +953,7 @@ Word16 lsf_msvq_ma_encprm_ivas_fx( IF( NE_16( acelp_mode, VOICED ) ) { test(); - IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + IF( ( core == ACELP_CORE ) && acelp_midLpc ) { push_next_indice( hBstr, *param_lpc, bits_midlpc ); @@ -971,7 +971,7 @@ Word16 lsf_msvq_ma_encprm_ivas_fx( *--------------------------------------------------------------------------*/ Word16 lsf_bctcvq_encprm_fx( BSTR_ENC_HANDLE hBstr, - Word16 *param_lpc, + Word16 *param_lpc, // Q0 Word16 *bits_param_lpc, Word16 no_indices ) { @@ -990,7 +990,7 @@ Word16 lsf_bctcvq_encprm_fx( } Word16 lsf_bctcvq_encprm_ivas_fx( BSTR_ENC_HANDLE hBstr, - const Word16 *param_lpc, + const Word16 *param_lpc, // Q0 const Word16 *bits_param_lpc, const Word16 no_indices ) { diff --git a/lib_enc/ltd_stable_fx.c b/lib_enc/ltd_stable_fx.c index a6e3ae1cc..036fe2a7e 100644 --- a/lib_enc/ltd_stable_fx.c +++ b/lib_enc/ltd_stable_fx.c @@ -21,7 +21,7 @@ void ltd_stable_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ Word16 *ltd_stable_rate, /* o : time-domain stable rate*/ - const Word32 frame_energy, /* i : current frame energy*/ + const Word32 frame_energy, /* i : current frame energy Q_frames_power*/ const Word16 frameloop, /* i : amount of frames*/ const Word16 Q_frames_power /* i : the Scaling of frames_power*/ ) @@ -57,7 +57,7 @@ void ltd_stable_fx( move16(); Q_apow = 0; move16(); - frames_power_32 = hVAD_CLDFB->frames_power_32; + frames_power_32 = hVAD_CLDFB->frames_power_32; // Q_frames_power_last_32 Q_frames_power_last_32 = hVAD_CLDFB->Q_frames_power_32; move16(); leadingzero_midamp = 31; @@ -76,7 +76,7 @@ void ltd_stable_fx( IF( GE_16( Q_frames_power32, 40 ) ) { zerop001 = L_shr( CNT0P001, 1 ); - frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, sub( Q_frames_power32, 39 ) ); + frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, sub( Q_frames_power32, 39 ) ); // Q_frames_power32 Q_frames_power32 = 39; move16(); } @@ -86,14 +86,14 @@ void ltd_stable_fx( frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, 1 ); zerop001 = L_shr( CNT0P001, sub( 40, Q_frames_power32 ) ); } - frames_power_32[0] = L_add( frame_energy_Sqr32, zerop001 ); + frames_power_32[0] = L_add( frame_energy_Sqr32, zerop001 ); // Q_frames_power32 move32(); IF( LT_16( frameloop, 3 ) ) { FOR( i = 1; i < 40; i++ ) { - frames_power_32[i] = frames_power_32[0]; + frames_power_32[i] = frames_power_32[0]; // Q_frames_power32 move32(); } } @@ -104,7 +104,7 @@ void ltd_stable_fx( move32(); FOR( i = 1; i < 40; i++ ) { - maxVal = L_max( maxVal, frames_power_32[i] ); + maxVal = L_max( maxVal, frames_power_32[i] ); // Q_frames_power32 } leadingzero = 31; move16(); @@ -119,7 +119,7 @@ void ltd_stable_fx( scale1 = sub( scale1, leadingzero ); FOR( i = 1; i < 40; i++ ) { - frames_power_32[i] = L_shr( frames_power_32[i], scale1 ); + frames_power_32[i] = L_shr( frames_power_32[i], scale1 ); // Q_frames_power32 move32(); } } @@ -140,7 +140,7 @@ void ltd_stable_fx( FOR( i = 0; i < 20; i++ ) { - mid_frame_ampadd32[i] = L_add( L_shr( frames_power_32[2 * i], 1 ), L_shr( frames_power_32[2 * i + 1], 1 ) ); + mid_frame_ampadd32[i] = L_add( L_shr( frames_power_32[2 * i], 1 ), L_shr( frames_power_32[2 * i + 1], 1 ) ); // Q_frames_power32 move32(); } @@ -148,16 +148,18 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - maxVal = L_max( maxVal, mid_frame_ampadd32[i] ); + maxVal = L_max( maxVal, mid_frame_ampadd32[i] ); // Q_frames_power32 } leadingzero_midamp = 31; move16(); if ( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 20; i++ ) { - mid_frame_amp32[i] = L_shl( mid_frame_ampadd32[i], leadingzero_midamp ); + mid_frame_amp32[i] = L_shl( mid_frame_ampadd32[i], leadingzero_midamp ); // Q_frames_power32 + leadingzero_midamp move32(); } @@ -165,19 +167,19 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 5 ) ); + seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 5 ) ); // Q_frames_power32 + leadingzero_midamp - 5 } - seg_amp32 = MUL_F( seg_amp32, 0x0666 ); + seg_amp32 = MUL_F( seg_amp32, 0x0666 /*(1/20).Q15*/ ); dif32 = 0; move32(); apow32 = 0; move32(); - seg_amp32tmp = L_shl( seg_amp32, 5 ); + seg_amp32tmp = L_shl( seg_amp32, 5 ); // Q_frames_power32 + leadingzero_midamp FOR( i = 0; i < 20; i++ ) { - tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); + tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); // Q_frames_power32 + leadingzero_midamp move32(); } @@ -185,22 +187,24 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - maxVal = L_max( maxVal, L_abs( tmp32[i] ) ); + maxVal = L_max( maxVal, L_abs( tmp32[i] ) ); // Q_frames_power32 + leadingzero_midamp - 5 } leadingzero_tmp32 = 31; move16(); if ( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); + } FOR( i = 0; i < 20; i++ ) { - tmp16[i] = extract_h( L_shl( tmp32[i], leadingzero_tmp32 ) ); + tmp16[i] = extract_h( L_shl( tmp32[i], leadingzero_tmp32 ) ); //// Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16 } FOR( i = 0; i < 20; i++ ) { - tmp_mul = L_mult_sat( tmp16[i], tmp16[i] ); - tmp_mul = L_shr( tmp_mul, 5 ); + tmp_mul = L_mult_sat( tmp16[i], tmp16[i] ); // 2 * (Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16) + 1 + tmp_mul = L_shr( tmp_mul, 5 ); // 2 * (Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16) - 4 dif32 = L_add( dif32, tmp_mul ); tmp = extract_h( mid_frame_amp32[i] ); @@ -244,7 +248,9 @@ void ltd_stable_fx( leadingzero_midamp = 31; move16(); if ( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 14; i++ ) { @@ -256,15 +262,15 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 14; i++ ) { - seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 4 ) ); + seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 4 ) ); // Q_frames_power32 - 4 } - seg_amp32 = MUL_F( seg_amp32, 0x0924 ); + seg_amp32 = MUL_F( seg_amp32, 0x0924 /*(1/14).Q15*/ ); dif32 = 0; move32(); apow32 = 0; move32(); - seg_amp32tmp = L_shl( seg_amp32, 4 ); + seg_amp32tmp = L_shl( seg_amp32, 4 ); // Q_frames_power32 FOR( i = 0; i < 14; i++ ) { tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); @@ -280,7 +286,9 @@ void ltd_stable_fx( leadingzero_tmp32 = 31; move16(); if ( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); + } FOR( i = 0; i < 14; i++ ) { @@ -367,8 +375,10 @@ void ltd_stable_fx( } leadingzero_midamp = 31; move16(); - if ( maxVal ) + IF( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 8; i++ ) { @@ -382,7 +392,7 @@ void ltd_stable_fx( { seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 3 ) ); } - seg_amp32 = MUL_F( seg_amp32, 0x1000 ); + seg_amp32 = MUL_F( seg_amp32, 0x1000 /*(1/8).Q15*/ ); dif32 = 0; move32(); @@ -403,9 +413,10 @@ void ltd_stable_fx( } leadingzero_tmp32 = 31; move16(); - if ( maxVal ) + IF( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); - + } FOR( i = 0; i < 8; i++ ) { tmp32[i] = L_shl( tmp32[i], leadingzero_tmp32 ); @@ -482,7 +493,7 @@ void ltd_stable_fx( ltd_stable_rate[2] = shr( ltd_stable_rate[2], ltd_stable_rate_Qtmp ); move16(); - ltd_stable_rate[3] = add( mult( ltd_stable_rate[3], 0x7333 ), mult( ltd_stable_rate[2], 0x0ccc ) ); + ltd_stable_rate[3] = add( mult( ltd_stable_rate[3], 0x7333 /*0.9.Q15*/ ), mult( ltd_stable_rate[2], 0x0ccc /*0.1.Q15*/ ) ); move16(); FOR( i = 55; i > 0; i-- ) diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index eec85c254..a4e19e040 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -46,7 +46,7 @@ * Square magnitude of fft spectrum *----------------------------------------------------------------------------*/ static void dft_mag_square_fx( - const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ + const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] Qx*/ Word32 magSq[], /* o : Magnitude square spectrum */ const Word16 n /* i : Input vector length */ ) @@ -57,7 +57,7 @@ static void dft_mag_square_fx( /* Magnitude square at 0. */ pMagSq = &magSq[0]; - pRe = &x[0]; + pRe = &x[0]; // Qx *pMagSq++ = L_mult0( *pRe, *pRe ); pRe++; move32(); @@ -70,13 +70,13 @@ static void dft_mag_square_fx( { acc = L_mult0( *pRe, *pRe ); pRe++; - *pMagSq++ = L_mac0( acc, *pIm, *pIm ); + *pMagSq++ = L_mac0( acc, *pIm, *pIm ); // 2*Qx pIm--; move32(); } /* The magnitude square at N/2 */ - *pMagSq = L_mult0( *pRe, *pRe ); + *pMagSq = L_mult0( *pRe, *pRe ); // 2*Qx move32(); return; } @@ -89,7 +89,7 @@ static void dft_mag_square_fx( Word16 mdct_classifier_fx( /* o: MDCT A/B decision */ const Word16 *fft_buff, /* i: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ Encoder_State *st_fx, /* i/o: Encoder state variable */ - Word32 *cldfbBuf_Ener, + Word32 *cldfbBuf_Ener, // enerBuffer_exp Word16 enerBuffer_exp, const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ ) @@ -260,7 +260,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision { IF( max_i > 0 ) { - IF( GT_16( np, 0 ) ) + IF( ( np > 0 ) ) { d_acc = sub( add( d_acc, max_i ), pos_last ); } @@ -277,7 +277,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision IF( pe != 0 ) { expo = norm_l( pe ); - man = L_shl( pe, expo ); + man = L_shl( pe, expo ); // expo Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); @@ -309,35 +309,35 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision /* gain11 = 8*(gain1 - cldfbBuf_Ener[0]/8)/7; */ acc = L_shr( cldfbBuf_Ener[0], 3 ); acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 4681 ); + acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); gain11 = L_shl( acc, 3 ); gain4 = L_deposit_l( 0 ); FOR( k = 0; k < 12; k++ ) { - gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 ) ); + gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 /*(1/12).Q15*/ ) ); } peak_H1 = L_add( cldfbBuf_Ener[25], 0 ); - Mpy_32_16_ss( cldfbBuf_Ener[25], 6554, &avrg_H1, &lsb16 ); + Mpy_32_16_ss( cldfbBuf_Ener[25], 6554 /*0.4.Q15*/, &avrg_H1, &lsb16 ); FOR( k = 1; k < 5; k++ ) { IF( GT_32( cldfbBuf_Ener[k + 25], peak_H1 ) ) { peak_H1 = L_add( cldfbBuf_Ener[k + 25], 0 ); } - avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 ) ); + avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 /*0.4.Q15*/ ) ); } peak_H2 = L_add( cldfbBuf_Ener[20], 0 ); - Mpy_32_16_ss( cldfbBuf_Ener[20], 6554, &avrg_H2, &lsb16 ); + Mpy_32_16_ss( cldfbBuf_Ener[20], 6554 /*0.4.Q15*/, &avrg_H2, &lsb16 ); FOR( k = 1; k < 5; k++ ) { IF( GT_32( cldfbBuf_Ener[k + 20], peak_H2 ) ) { peak_H2 = L_add( cldfbBuf_Ener[k + 20], 0 ); } - avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 ) ); + avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 /*0.4.Q15*/ ) ); } // End peak_l = L_deposit_l( 0 ); @@ -400,7 +400,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision condition4 = 0; move16(); - L_tmp = Mult_32_16( peak_h, 12603 ); + L_tmp = Mult_32_16( peak_h, 12603 /*1/2.56.Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -418,7 +418,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision exp1 = norm_l( avrg_l ); } - L_tmp1 = Mult_32_16( peak_l, 12603 ); + L_tmp1 = Mult_32_16( peak_l, 12603 /*1/2.56.Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -438,7 +438,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision move16(); } - L_tmp = Mult_32_16( peak_h, 12800 ); + L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -448,7 +448,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision exp = norm_l( L_tmp ); } - L_tmp1 = Mult_32_16( peak_l, 6400 ); + L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -476,7 +476,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision test(); test(); test(); - IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) ) { condition4 = 1; move16(); @@ -498,21 +498,21 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision } /* Smooth decision from instantaneous decision*/ - acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ - clas_sec = mac_r( acc, c, 0x7fff - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ + acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ + clas_sec = mac_r( acc, c, 0x7fff /*1.Q15*/ - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ /* Do thresholding with hysteresis */ IF( GT_16( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ) { - gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); + gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp move32(); - gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); + gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp move32(); } ELSE { - hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); + hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp move32(); - hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); + hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp move32(); gain1_tmp = gain1; move32(); @@ -582,10 +582,11 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision return clas_final; /* Q0 */ } + Word16 mdct_classifier_ivas_fx( Encoder_State *st, /* i/o: Encoder state variable */ const Word16 *fft_buff, /* i : FFT spectrum from fft_rel */ - const Word32 enerBuffer[], /* i : energy buffer */ + const Word32 enerBuffer[], /* i : energy buffer enerBuffer_exp*/ Word16 enerBuffer_exp, const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ ) @@ -772,7 +773,7 @@ Word16 mdct_classifier_ivas_fx( IF( pe != 0 ) { expo = norm_l( pe ); - man = L_shl( pe, expo ); + man = L_shl( pe, expo ); // expo Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); @@ -795,32 +796,32 @@ Word16 mdct_classifier_ivas_fx( { IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) { - gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); - gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); - gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); + gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); // enerBuffer_exp - 3 + gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); // enerBuffer_exp - 3 + gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); // enerBuffer_exp - 3 } ELSE { - gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); - gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 ) ); - gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 ) ); + gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); // enerBuffer_exp + gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp + gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp } } IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) { - acc = L_shr( enerBuffer[0], 3 ); - acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 4681 ); - gain11 = L_shl( acc, 3 ); + acc = L_shr( enerBuffer[0], 3 ); // enerBuffer_exp - 3 + acc = L_sub( gain1, acc ); // enerBuffer_exp - 3 + acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); // enerBuffer_exp - 3 + gain11 = L_shl( acc, 3 ); // enerBuffer_exp gain4 = L_deposit_l( 0 ); } ELSE { - acc = Mult_32_16( enerBuffer[0], 5461 ); - acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 6553 ); + acc = Mult_32_16( enerBuffer[0], 5461 /*0.16.Q15*/ ); // enerBuffer_exp + acc = L_sub( gain1, acc ); // enerBuffer_exp + acc = Mult_32_16( acc, 6553 /*0.4.Q15*/ ); // enerBuffer_exp gain11 = (Word32) W_mult_32_16( acc, 6 ); gain4 = L_deposit_l( 0 ); } @@ -830,28 +831,28 @@ Word16 mdct_classifier_ivas_fx( { IF( EQ_16( gain4_start, GAIN4_START_SWB ) ) { - gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 ) ); + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 /*(1/12).Q15*/ ) ); } ELSE { - gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 ) ); + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 /*(1/9).Q1.15*/ ) ); } } - peak_H1 = enerBuffer[H1_start]; + peak_H1 = enerBuffer[H1_start]; // enerBuffer_exp move32(); - avrg_H1 = enerBuffer[H1_start]; + avrg_H1 = enerBuffer[H1_start]; // enerBuffer_exp move32(); FOR( i = 1; i < H_length; i++ ) { IF( GT_32( enerBuffer[H1_start + i], peak_H1 ) ) { - peak_H1 = enerBuffer[H1_start + i]; + peak_H1 = enerBuffer[H1_start + i]; // enerBuffer_exp move32(); } - avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); + avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); // enerBuffer_exp } peak_H2 = enerBuffer[H2_start]; @@ -969,7 +970,7 @@ Word16 mdct_classifier_ivas_fx( move16(); } - L_tmp = Mult_32_16( peak_h, 12800 ); + L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -979,7 +980,7 @@ Word16 mdct_classifier_ivas_fx( exp = norm_l( L_tmp ); } - L_tmp1 = Mult_32_16( peak_l, 6400 ); + L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -1007,8 +1008,8 @@ Word16 mdct_classifier_ivas_fx( test(); test(); test(); - IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || - ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || + ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) ) { condition4 = 1; move16(); diff --git a/lib_enc/mdct_selector_fx.c b/lib_enc/mdct_selector_fx.c index 52c30f7ef..c4cc7d0db 100644 --- a/lib_enc/mdct_selector_fx.c +++ b/lib_enc/mdct_selector_fx.c @@ -62,14 +62,14 @@ static Word16 get_sparseness( /* Returns sparseness measur FOR( i = 1; i < n - 1; ++i ) { - if ( GT_16( Bin_E[i], s_max( s_max( Bin_E[i - 1], Bin_E[i + 1] ), thr ) ) ) + IF( GT_16( Bin_E[i], s_max( s_max( Bin_E[i - 1], Bin_E[i + 1] ), thr ) ) ) { num_max = add( num_max, 1 ); } } n = shr( sub( n, 2 ), 1 ); - return div_s( sub( n, num_max ), n ); + return div_s( sub( n, num_max ), n ); // Q15 } /*--------------------------------------------------------------------------* * get_mean_ener() @@ -78,7 +78,7 @@ static Word16 get_sparseness( /* Returns sparseness measur *--------------------------------------------------------------------------*/ static Word16 get_mean_ener( /* Returns mean energy in dB (Q8) */ - const Word32 enerBuffer[], /* i : CLDFB buffers */ + const Word32 enerBuffer[], /* i : CLDFB buffers enerBuffer_exp*/ Word16 enerBuffer_exp, /* i : exponent of enerBuffer */ Word16 n /* i : number of bins */ ) @@ -87,8 +87,10 @@ static Word16 get_mean_ener( /* Returns mean energy i Word16 i, shift, frac_nrg, exp_nrg; shift = sub( 14, norm_s( n ) ); - if ( LT_16( shl( 1, shift ), n ) ) + IF( LT_16( shl( 1, shift ), n ) ) + { shift = add( shift, 1 ); + } L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < n; ++i ) @@ -104,7 +106,7 @@ static Word16 get_mean_ener( /* Returns mean energy i exp_nrg = sub( add( exp_nrg, shift ), sub( 31, enerBuffer_exp ) ); L_tmp = Mpy_32_16( exp_nrg, frac_nrg, 9864 ); /* log10(2) in Q15 */ - return round_fx( L_shl( L_tmp, 8 ) ); + return round_fx( L_shl( L_tmp, 8 ) ); // Q8 } /*--------------------------------------------------------------------------* * MDCT_selector_fx() @@ -117,7 +119,7 @@ void MDCT_selector_fx( Word16 sp_floor, /* i : Noise floor estimate Q7 */ const Word16 Etot, /* i : Total energy Q8 */ const Word16 cor_map_sum, /* i : harmonicity factor Q8 */ - const Word32 enerBuffer[], /* i : CLDFB buffers */ + const Word32 enerBuffer[], /* i : CLDFB buffers enerBuffer_exp*/ const Word16 enerBuffer_exp /* i : exponent of enerBuffer */ ) { @@ -135,7 +137,7 @@ void MDCT_selector_fx( sp_floor = shl( sp_floor, 1 ); /* convert to Q8 */ - IF( EQ_16( st->bwidth, NB ) ) + IF( ( st->bwidth == NB ) ) { lob_cldfb = 3200 / 400; move16(); @@ -188,7 +190,7 @@ void MDCT_selector_fx( frame_voicing = add( shr( st->voicing_fx[0], 1 ), shr( st->voicing_fx[1], 1 ) ); /* Spectral sparseness */ - sparseness = get_sparseness( st->lgBin_E_fx, lob_fft, sub( Etot, MDCT_SW_SIG_PEAK_THR ) ); + sparseness = get_sparseness( st->lgBin_E_fx, lob_fft, sub( Etot, MDCT_SW_SIG_PEAK_THR ) ); // Q15 /* Hi band energy */ hi_ener = get_mean_ener( &enerBuffer[lob_cldfb], enerBuffer_exp, sub( hib_cldfb, lob_cldfb ) ); @@ -255,23 +257,23 @@ void MDCT_selector_fx( IF( EQ_16( st->mdct_sw_enable, MODE1 ) ) { - sig_lo_level_thr = MDCT_SW_1_SIG_LO_LEVEL_THR; + sig_lo_level_thr = MDCT_SW_1_SIG_LO_LEVEL_THR; // Q8 move16(); - sig_hi_level_thr = MDCT_SW_1_SIG_HI_LEVEL_THR; + sig_hi_level_thr = MDCT_SW_1_SIG_HI_LEVEL_THR; // Q8 move16(); - cor_thr = MDCT_SW_1_COR_THR; + cor_thr = MDCT_SW_1_COR_THR; // Q8 move16(); - cor_thr2 = MDCT_SW_1_COR_THR2; + cor_thr2 = MDCT_SW_1_COR_THR2; // Q8 move16(); - voicing_thr = MDCT_SW_1_VOICING_THR; + voicing_thr = MDCT_SW_1_VOICING_THR; // Q15 move16(); - voicing_thr2 = MDCT_SW_1_VOICING_THR2; + voicing_thr2 = MDCT_SW_1_VOICING_THR2; // Q15 move16(); - sparseness_thr = MDCT_SW_1_SPARSENESS_THR; + sparseness_thr = MDCT_SW_1_SPARSENESS_THR; // Q15 move16(); - sparseness_thr2 = MDCT_SW_1_SPARSENESS_THR2; + sparseness_thr2 = MDCT_SW_1_SPARSENESS_THR2; // Q15 move16(); - hi_ener_lo_thr = MDCT_SW_1_HI_ENER_LO_THR; + hi_ener_lo_thr = MDCT_SW_1_HI_ENER_LO_THR; // Q8 move16(); } ELSE /* st->mdct_sw_enable == MODE2 */ diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index 771ef480b..af5a82b69 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -58,19 +58,19 @@ Word32 mslvq_fx( IF( pred_flag == 0 ) { - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // Qlog2(2.56) /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; - p_scales = scales_fx[mode_glb]; - p_no_lead = no_lead_fx[mode_glb]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 + p_scales = scales_fx[mode_glb]; // Q11 + p_no_lead = no_lead_fx[mode_glb]; // Q0 } ELSE { - p_sigma = sigma_p_fx[mode]; + p_sigma = sigma_p_fx[mode]; // Qlog2(2.56) /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_p_fx[mode]; - p_scales = scales_p_fx[mode_glb]; - p_no_lead = no_lead_p_fx[mode_glb]; + p_inv_sigma = inv_sigma_p_fx[mode]; // Q15 + p_scales = scales_p_fx[mode_glb]; // Q11 + p_no_lead = no_lead_p_fx[mode_glb]; // Q0 } /* first subvector */ @@ -184,15 +184,15 @@ Word32 mslvq_cng_fx( mode_glb = add( START_CNG, idx_cv ); move16(); - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 move16(); - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; + p_scales = scales_fx[mode_glb]; // Q11 move16(); - p_no_lead = no_lead_fx[mode_glb]; + p_no_lead = no_lead_fx[mode_glb]; // Q0 move16(); - p_no_scales = &no_scales[shl( mode_glb, 1 )]; + p_no_scales = &no_scales[( mode_glb << 1 )]; move16(); /* check if LSF component permutation is needed or not */ @@ -247,11 +247,11 @@ Word32 mslvq_cng_ivas_fx( mode_glb = add( START_CNG, idx_cv ); move16(); - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 move16(); - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; + p_scales = scales_fx[mode_glb]; // Q11 move16(); no_scales[0] = 0; @@ -773,7 +773,7 @@ static void sort_desc_ind_fx( move16(); } sorted = 0; - FOR( k = sub( len, 1 ); k > 0; k-- ) + FOR( k = ( len - 1 ); k > 0; k-- ) { IF( sorted ) { @@ -837,7 +837,7 @@ void index_lvq_fx( /* for first subvector */ IF( GT_16( idx_scale[0], -1 ) ) { - index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[i_mult2( mode, len_offset ) + idx_scale[0]] ) ); + index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[( mode * len_offset ) + idx_scale[0]] ) ); } /* for second subvector */ @@ -845,7 +845,7 @@ void index_lvq_fx( IF( GT_16( idx_scale[1], -1 ) ) { - index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[i_mult2( mode, len_offset ) + idx_scale[1]] ) ); + index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[( mode * len_offset ) + idx_scale[1]] ) ); } idx64 = W_mult0_32_32( index1, p_offset_scale2[mode * len_offset + p_no_scales[mode * 2 + 1]] ); index2_64 = W_deposit32_l( index2 ); @@ -854,9 +854,9 @@ void index_lvq_fx( /* convert to 3 short */ index[0] = ( ( idx64 ) & ( 0x7fff ) ); move16(); - index[1] = ( idx64 >> 15 ) & ( 0x7fff ); + index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff ); move16(); - index[2] = ( idx64 >> 30 ) & ( 0x7fff ); + index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff ); move16(); return; } @@ -900,9 +900,9 @@ void index_lvq_ivas_fx( /* convert to 3 short */ index[0] = ( ( idx64 ) & ( 0x7fff ) ); move16(); - index[1] = ( idx64 >> 15 ) & ( 0x7fff ); + index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff ); move16(); - index[2] = ( idx64 >> 30 ) & ( 0x7fff ); + index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff ); move16(); return; @@ -1059,7 +1059,7 @@ static Word16 encode_sign_pc1_fx( /* o : index of signs IF( cv[i] < 0 ) { idx_sign = add( idx_sign, ( shl( 1, cnt ) ) ); - cnt++; + cnt = add( cnt, 1 ); } if ( cv[i] > 0 ) @@ -1091,7 +1091,7 @@ static void take_out_val_fx( FOR( i = 0; i < len; i++ ) { - IF( NE_16( v[i], val ) ) + if ( NE_16( v[i], val ) ) { v_out[cnt++] = v[i]; move16(); @@ -1125,7 +1125,7 @@ Word16 c2idx_fx( /* o: index */ move16(); FOR( i = 1; i <= p[0]; i++ ) { - skip = add( skip, C_VQ[sub( n, i )][sub( k, 1 )] ); + skip = add( skip, C_VQ[( n - i )][( k - 1 )] ); // Q0 } p0 = p[0]; diff --git a/lib_enc/multi_harm_fx.c b/lib_enc/multi_harm_fx.c index 78ef81c60..1bae597b6 100644 --- a/lib_enc/multi_harm_fx.c +++ b/lib_enc/multi_harm_fx.c @@ -53,7 +53,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity /* length of the useful part of the spectrum (up to 6.4kHz) */ L = L_FFT / 2; move16(); - if ( EQ_16( bwidth, NB ) ) + if ( ( bwidth == NB ) ) { /* length of the useful part of the spectrum (up to 3.6kHz) */ L = 76; @@ -170,14 +170,14 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity mean_dyn = round_fx( L_acc ); /*Q7*/ test(); - IF( LT_16( mean_dyn, 1229 ) /*9.6f*/ && *cor_strong_limit != 0 ) + IF( LT_16( mean_dyn, 1229 ) /*9.6f.Q7*/ && *cor_strong_limit != 0 ) { *cor_strong_limit = 0; move16(); *st_last_sw_dyn = mean_dyn; move16(); } - ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f*/ ) + ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f.Q7*/ ) { *cor_strong_limit = 1; move16(); @@ -290,7 +290,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity cor_strong = 0; move16(); - pt1 = cor_map_LT; + pt1 = cor_map_LT; // Q15 move16(); pt2 = cor_map; move16(); @@ -306,7 +306,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity /* cor_map_LT_sum += *pt1 */ Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */ - if ( GT_16( *pt1, 31130 ) /*0.95f*/ ) + if ( GT_16( *pt1, 31130 ) /*0.95f.Q15*/ ) { cor_strong = 1; move16(); @@ -316,7 +316,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity pt2++; } - IF( EQ_16( bwidth, NB ) ) + IF( ( bwidth == NB ) ) { /* cor_map_LT_sum *= 1.53f; */ /* tmp2 *= 1.53f; */ @@ -396,7 +396,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni /* length of the useful part of the spectrum (up to 6.4kHz) */ L = L_FFT / 2; move16(); - if ( EQ_16( bwidth, NB ) ) + if ( ( bwidth == NB ) ) { /* length of the useful part of the spectrum (up to 3.6kHz) */ L = 76; @@ -654,7 +654,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni } tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8 - IF( EQ_16( bwidth, NB ) ) + IF( ( bwidth == NB ) ) { /* cor_map_LT_sum *= 1.53f; */ /* tmp2 *= 1.53f; */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 353de8ec9..e04f5172b 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -17,7 +17,6 @@ #include "debug.h" #endif #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 7bbc54780..5c96a2f29 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" #include "stl.h" #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 61ca9b101..ba8ee5aa8 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "stl.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 008e27d6c..770b62764 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -36,7 +36,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index 81437c49d..e50ad32e1 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 9cc764afb..93a100e17 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -34,7 +34,6 @@ #include #include "ivas_cnst.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 730705ffd..0deb14c9b 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_binauralRenderer.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index e89414542..b8b3c3ac7 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index 4eae9c286..e9af8483a 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 983343bba..748b82d5c 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index aca51e01c..b092443be 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_efap_fx.c b/lib_rend/ivas_efap_fx.c index 52ca3e6f9..7a74e62da 100644 --- a/lib_rend/ivas_efap_fx.c +++ b/lib_rend/ivas_efap_fx.c @@ -36,7 +36,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_hrtf_fx.c b/lib_rend/ivas_hrtf_fx.c index 5d53d2ae3..e3965fbff 100644 --- a/lib_rend/ivas_hrtf_fx.c +++ b/lib_rend/ivas_hrtf_fx.c @@ -36,7 +36,6 @@ #include "ivas_prot_rend.h" #include "ivas_error.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 8b7e6575d..430fab2c7 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "lib_rend.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 25fddaa80..8b56b6855 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "options.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 93fe67436..7b1e1fe91 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index d7387ecd4..2c28b32bd 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -35,7 +35,6 @@ #include #include "ivas_cnst.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_stat_rend.h" diff --git a/lib_rend/ivas_orient_trk_fx.c b/lib_rend/ivas_orient_trk_fx.c index bb6f26346..a124bf4bd 100644 --- a/lib_rend/ivas_orient_trk_fx.c +++ b/lib_rend/ivas_orient_trk_fx.c @@ -33,7 +33,6 @@ #include "common_api_types.h" #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 054e5e981..6fba496d5 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -37,7 +37,6 @@ #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------------* diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c index bbe6ae4b5..74be74497 100644 --- a/lib_rend/ivas_output_init_fx.c +++ b/lib_rend/ivas_output_init_fx.c @@ -1,6 +1,5 @@ #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #ifdef FIX_DISCLAIMER #include diff --git a/lib_rend/ivas_reflections_fx.c b/lib_rend/ivas_reflections_fx.c index a02a29d0d..d6e397234 100644 --- a/lib_rend/ivas_reflections_fx.c +++ b/lib_rend/ivas_reflections_fx.c @@ -39,7 +39,6 @@ #include "ivas_prot_rend.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "debug.h" diff --git a/lib_rend/ivas_reverb_delay_line_fx.c b/lib_rend/ivas_reverb_delay_line_fx.c index 44550803a..ab41b43c2 100644 --- a/lib_rend/ivas_reverb_delay_line_fx.c +++ b/lib_rend/ivas_reverb_delay_line_fx.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_sba_rendering_fx.c b/lib_rend/ivas_sba_rendering_fx.c index 4323fc96f..d544acd13 100644 --- a/lib_rend/ivas_sba_rendering_fx.c +++ b/lib_rend/ivas_sba_rendering_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index 6d5b23f12..0fc5c21df 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index 06cbd83a6..b90b3a456 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ac856e90c..60fbd5ec6 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -33,7 +33,6 @@ #include "options.h" #include "lib_rend.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 930bb79dc..0316d8b30 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -34,7 +34,6 @@ #include #include "prot_fx.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 90d47b7c9..f4f43e496 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -33,7 +33,7 @@ #include "ls_custom_file_reader.h" #include #include -#include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot_fx.h" diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 9351d9bc9..efab80b79 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "masa_file_reader.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include #include -- GitLab From 79e96be01a409e9e6e2d690fa04afaa6e22b8d8d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 19:41:16 +0530 Subject: [PATCH 0408/1221] Clang formatting changes --- lib_com/gs_bitallocation_ivas_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 71b30ea75..9243f640e 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -2,11 +2,11 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "assert.h" /* Debug prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" -- GitLab From 935c2b486099e3ac2794e2560befb36618a6e2ef Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 12:52:44 +0530 Subject: [PATCH 0409/1221] USAN fix for decoder --- lib_dec/ivas_lfe_plc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 210c266eb..8ed450435 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( -s, err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate(s), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); -- GitLab From c76b22a8b6f106799e8fe0ccc2a5011decbf8c8b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 12:55:14 +0530 Subject: [PATCH 0410/1221] Clang formatting changes --- lib_dec/ivas_lfe_plc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 8ed450435..d98603d2a 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate(s), err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate( s ), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); -- GitLab From caa91ea0d326115d9d48a9f5f81dfc929a6a6597 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:52:47 +0530 Subject: [PATCH 0411/1221] Fix for 3GPP issue 1373: Decoder crash for stereo at 80kbps JBM decoding to Mono in get_scaling_quality_fx() Link #1373 --- lib_dec/jbm_pcmdsp_apa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index ac6a28b86..fc793dff0 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -900,7 +900,7 @@ UWord8 apa_exec_ivas_fx( UWord32 statsResetThreshold, statsResetShift; Word16 Q_a_out; - Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 ); + Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 - Q1 ); statsResetThreshold = 1637; move32(); statsResetShift = 2; -- GitLab From 8f5c6fa08d6044004b3e9b21815b1c248646132a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 12:32:57 +0530 Subject: [PATCH 0412/1221] Fix for 3GPP issue 1341: Usage of open/deleteCldfb() functions - multiple variants Link #1341 --- lib_com/cldfb.c | 107 +++-------------------- lib_com/cnst.h | 6 +- lib_com/prot_fx.h | 15 +--- lib_dec/init_dec_fx.c | 6 +- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 +- lib_dec/ivas_init_dec.c | 4 +- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 +- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +-- lib_enc/init_enc_fx.c | 4 +- lib_enc/ivas_masa_enc_fx.c | 4 +- lib_enc/ivas_omasa_enc_fx.c | 4 +- lib_enc/ivas_stereo_switching_enc_fx.c | 10 +-- lib_enc/ivas_stereo_td_enc_fx.c | 8 +- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 +- 19 files changed, 53 insertions(+), 147 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 38195b65d..7fc8026b5 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1364,8 +1364,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + CODE_TYPE code_type ) { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,7 +1379,14 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - configureCldfb_ivas_fx( hs, sampling_rate ); + IF( code_type == IVAS_ENC ) + { + configureCldfb_ivas_enc_fx( hs, sampling_rate ); + } + ELSE + { + configureCldfb_ivas_fx( hs, sampling_rate ); + } hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1413,65 +1420,6 @@ ivas_error openCldfb_ivas_fx( return IVAS_ERR_OK; } -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs; - Word16 buf_len; - - IF( ( hs = (HANDLE_CLDFB_FILTER_BANK) malloc( sizeof( CLDFB_FILTER_BANK ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - - hs->type = type; - move32(); - hs->prototype = prototype; - move32(); - - configureCldfb_ivas_enc_fx( hs, sampling_rate ); - hs->memory_length = 0; - move32(); - - IF( type == CLDFB_ANALYSIS ) - { - buf_len = sub( hs->p_filter_length, hs->no_channels ); - hs->FilterStates = (Word16 *) malloc( ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); - } - ELSE - { - buf_len = hs->p_filter_length; - move16(); - hs->FilterStates = (Word16 *) malloc( 2 * ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); - } - - if ( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer - move16(); - hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ - move16(); - set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = 0; - move16(); - set16_fx( hs->FilterStates, 0, i_mult( 9 + 16, hs->no_channels ) ); - set16_fx( hs->FilterStates_e, 0, sizeof( hs->FilterStates_e ) / sizeof( hs->FilterStates_e[0] ) ); - - *h_cldfb = hs; - - return IVAS_ERR_OK; -} - /*-------------------------------------------------------------------* * resampleCldfb_ivas() * @@ -1563,41 +1511,6 @@ void analysisCldfbEncoder_ivas_fx( return; } - -/*-------------------------------------------------------------------* - * GetEnergyCldfb_ivas() - * - * Remove handle - *--------------------------------------------------------------------*/ - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs = *h_cldfb; - - test(); - IF( h_cldfb == NULL || *h_cldfb == NULL ) - { - return; - } - - IF( hs->cldfb_state_fx ) - { - free( hs->cldfb_state_fx ); - } - - IF( hs->FilterStates ) - { - free( hs->FilterStates ); - } - - free( hs ); - *h_cldfb = NULL; - - return; -} - void deleteCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 4e14b310d..8f716f18e 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -806,7 +806,11 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; - +typedef enum +{ + IVAS_ENC, + IVAS_DEC_REND +} CODE_TYPE; typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index db0953cd9..c1aefbe36 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9803,8 +9803,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + CODE_TYPE code_type ); Word32 rand_gauss_fx( Word32 *x, @@ -11944,13 +11944,6 @@ ivas_error openCldfb_ivas( CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const Word32 newSamplerate /* i : new samplerate to operate */ @@ -11960,10 +11953,6 @@ ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - /*! r: flag indicating a valid bitrate */ Word16 is_EVS_bitrate( const Word32 ivas_total_brate, /* i : EVS total bitrate */ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 3865cd61c..4e0cfda18 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 25c0bea42..111c0be0e 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b11669460..236eaad54 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index a6be10c08..cc3980b12 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 3f39bd9ac..c8dde0837 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 09b683a16..34eef94ed 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 615ca1b33..f0338b461 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 6960629c8..9fdebed7a 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -260,7 +260,7 @@ void ivas_masa_enc_close_fx( FOR( i = 0; i < ( *hMasa )->data.num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); } IF( ( *hMasa )->data.hOmasaData != NULL ) diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 5d79265f4..50fb49355 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_enc( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -227,7 +227,7 @@ void ivas_omasa_enc_close_fx( FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); } FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 2fe8b6c84..6c7a1e68d 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -366,8 +366,8 @@ ivas_error stereo_memory_enc_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) || EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) ) { /* Deallocate MDCT CNG structures */ - deleteCldfb_ivas( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); - deleteCldfb_ivas( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index d2ff2c0c2..de9bc09b5 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -263,7 +263,7 @@ ivas_error stereo_set_tdm_fx( /* deallocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc != NULL ) { - deleteCldfb_ivas( &st->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); } /* deallocate BWEs for secondary channel */ @@ -275,7 +275,7 @@ ivas_error stereo_set_tdm_fx( st->hBWE_TD = NULL; } - deleteCldfb_ivas( &st->cldfbSynTd ); + deleteCldfb_ivas_fx( &st->cldfbSynTd ); IF( st->hBWE_FD != NULL ) { @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 93a100e17..5dd3f8384 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 430fab2c7..3aa9f62a9 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 8b56b6855..d56ba2685 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 2c28b32bd..1d849a90f 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 60fbd5ec6..ed513e91a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From a79e6da8ef6a41749574d8a382a62353a7f05bde Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:42:57 +0530 Subject: [PATCH 0413/1221] Address review comments --- lib_com/cldfb.c | 10 ++++++---- lib_com/cnst.h | 6 +----- lib_com/prot_fx.h | 2 +- lib_dec/init_dec_fx.c | 6 +++--- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 ++-- lib_dec/ivas_init_dec.c | 4 ++-- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 ++-- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +++++----- lib_enc/init_enc_fx.c | 4 ++-- lib_enc/ivas_masa_enc_fx.c | 2 +- lib_enc/ivas_omasa_enc_fx.c | 2 +- lib_enc/ivas_stereo_switching_enc_fx.c | 6 +++--- lib_enc/ivas_stereo_td_enc_fx.c | 4 ++-- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 ++-- 19 files changed, 38 insertions(+), 40 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 7fc8026b5..246a8a8e8 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1365,7 +1365,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ) + const Word16 enc_dec ) /* i : encoder/decoder flag */ { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,14 +1379,17 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - IF( code_type == IVAS_ENC ) + IF( enc_dec == ENC ) { configureCldfb_ivas_enc_fx( hs, sampling_rate ); + hs->Q_cldfb_state = 0; } ELSE { configureCldfb_ivas_fx( hs, sampling_rate ); + hs->Q_cldfb_state = Q11; } + move16(); hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1412,8 +1415,7 @@ ivas_error openCldfb_ivas_fx( hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ move16(); set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = Q11; - move16(); + *h_cldfb = hs; move16(); diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 8f716f18e..4e14b310d 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -806,11 +806,7 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; -typedef enum -{ - IVAS_ENC, - IVAS_DEC_REND -} CODE_TYPE; + typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c1aefbe36..9fe14b5bd 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9804,7 +9804,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ); + const Word16 enc_dec ); /* i : encoder/decoder flag */ Word32 rand_gauss_fx( Word32 *x, diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4e0cfda18..bd8a2cbd3 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 111c0be0e..8333f146f 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 236eaad54..1ab797ded 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index cc3980b12..12549f49d 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index c8dde0837..5b1378a89 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 34eef94ed..c70e606ac 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index f0338b461..cd5db5377 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 9fdebed7a..da1f836df 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 50fb49355..b5258712b 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 6c7a1e68d..0a526561a 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index de9bc09b5..1544aab76 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 5dd3f8384..1a5013059 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 3aa9f62a9..c74477365 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index d56ba2685..e17b2f9f6 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 1d849a90f..5e175fae5 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ed513e91a..29030ca0c 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 9f43bf8e9b079b8d78258958d49505d0a356d468 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:49:56 +0530 Subject: [PATCH 0414/1221] Fix for 3GPP issue 1361: Assert in BASOP decoder function ivas_dirac_dec_render_sf_fx for LTV MASA bitstream Link #1361 --- lib_dec/ivas_cpe_dec_fx.c | 4 ---- lib_dec/ivas_dirac_dec_fx.c | 37 ++++++++++++++++++++------------ lib_dec/ivas_stereo_dft_dec_fx.c | 3 ++- lib_rend/ivas_dirac_rend_fx.c | 2 ++ 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 6a6294377..9e934cc88 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -352,10 +352,6 @@ ivas_error ivas_cpe_dec_fx( { sts[0]->total_brate = hCPE->element_brate; /* Only mono downmix was transmitted in this case */ move32(); -#ifdef MSAN_FIX - hCPE->hStereoDft->frame_sid_nodata = 0; - move16(); -#endif } ELSE { diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index b8a7f61bb..ac29a23e0 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2204,13 +2204,15 @@ void ivas_dirac_dec_render_sf_fx( Word32 Cldfb_RealBuffer_Temp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Temp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word16 cldfb_buf_q; - Word16 offset, buff_len; + Word16 offset = 0, buff_len = 0; + move16(); + move16(); Word16 q_cldfb, q_temp_cldfb = 0; move16(); Word16 proto_length = 0; move16(); - Word16 q_proto_direct_buffer[CLDFB_SLOTS_PER_SUBFRAME]; - Word16 q_proto_diffuse_buffer[CLDFB_SLOTS_PER_SUBFRAME]; + Word16 q_proto_direct_buffer[CLDFB_SLOTS_PER_SUBFRAME + 1]; + Word16 q_proto_diffuse_buffer[CLDFB_SLOTS_PER_SUBFRAME + 1]; Word16 size, size_ho; DIRAC_DEC_STACK_MEM DirAC_mem; @@ -2263,8 +2265,8 @@ void ivas_dirac_dec_render_sf_fx( } q_cldfb = Q11; move16(); - set16_fx( q_proto_direct_buffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME ); - set16_fx( q_proto_diffuse_buffer, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME ); + set16_fx( q_proto_direct_buffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME + 1 ); + set16_fx( q_proto_diffuse_buffer, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME + 1 ); set_zero_fx( surCohRatio_fx, CLDFB_NO_CHANNELS_MAX ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) @@ -3477,22 +3479,21 @@ void ivas_dirac_dec_render_sf_fx( } } - minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); + minimum_s( q_proto_direct_buffer, add( hSpatParamRendCom->subframe_nbslots[subframe_idx], 1 ), &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - minimum_s( q_proto_diffuse_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q ); + minimum_s( q_proto_diffuse_buffer, add( hSpatParamRendCom->subframe_nbslots[subframe_idx], 1 ), &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q ); } FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, nchan_transport ) ); - buff_len = i_mult( 2, i_mult( nchan_transport, hSpatParamRendCom->num_freq_bands ) ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q - offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) ); buff_len = i_mult( 2, i_mult( hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, q_proto_diffuse_buffer[slot_idx] ) ); // proto_diffuse_buffer_f_q + offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, nchan_transport ) ); + buff_len = i_mult( 2, i_mult( nchan_transport, hSpatParamRendCom->num_freq_bands ) ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q } ELSE IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) { @@ -3532,10 +3533,18 @@ void ivas_dirac_dec_render_sf_fx( BREAK; } } - q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; - move16(); } - + test(); + IF( EQ_16( slot_idx, hSpatParamRendCom->subframe_nbslots[subframe_idx] ) && sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, add( offset, buff_len ) ) > 0 ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + add( offset, buff_len ), sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, add( offset, buff_len ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q + offset = i_mult( i_mult( sub( slot_idx, 1 ), 2 ), i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) ); + buff_len = i_mult( 2, i_mult( hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands ) ); + IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, add( offset, buff_len ) ) > 0 ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + add( offset, buff_len ), sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, add( offset, buff_len ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, q_proto_diffuse_buffer[slot_idx] ) ); // proto_direct_buffer_f_q + } + } ivas_dirac_dec_output_synthesis_get_interpolator_fx( &hDirACRend->h_output_synthesis_psd_params, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); size = i_mult( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 1c18ffacb..3d9e58ad1 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -258,7 +258,8 @@ void stereo_dft_dec_reset_fx( move16(); hStereoDft->ipd_xfade_prev_fx = 0; move32(); - + hStereoDft->frame_sid_nodata = 0; + move16(); #ifdef MSAN_FIX FOR( b = 0; b < 2 * IVAS_MAX_NUM_BANDS; b++ ) { diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index b092443be..d438dc7f2 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -882,6 +882,8 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands ); move16(); + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31; + move16(); IF( hDirACRend->proto_signal_decorr_on ) { -- GitLab From 4dc8bbbd784951ca74eabf63e230c640b3b60ad5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 07:28:01 +0530 Subject: [PATCH 0415/1221] Clean up of prot.h file --- lib_com/core_com_config.c | 1 + lib_com/gs_bitallocation_ivas_fx.c | 11 ++++++----- lib_com/ivas_arith_fx.c | 1 + lib_com/ivas_dirac_com_fx.c | 1 + lib_com/ivas_fb_mixer_fx.c | 1 + lib_com/ivas_ism_com_fx.c | 1 + lib_com/ivas_lfe_com_fx.c | 1 + lib_com/ivas_mc_com_fx.c | 1 + lib_com/ivas_mct_com_fx.c | 2 +- lib_com/ivas_mdct_core_com_fx.c | 1 + lib_com/ivas_mdft_imdft_fx.c | 1 + lib_com/ivas_qmetadata_com_fx.c | 1 + lib_com/ivas_qspherical_com_fx.c | 1 + lib_com/ivas_sba_config_fx.c | 1 + lib_com/ivas_stereo_dft_com_fx.c | 1 + lib_com/ivas_stereo_psychlpc_com_fx.c | 2 ++ lib_com/ivas_tools_fx.c | 1 + lib_com/ivas_transient_det_fx.c | 1 + lib_com/mslvq_com.c | 1 + lib_com/prot_fx.h | 15 +++++++++++++++ lib_dec/igf_dec_fx.c | 1 + lib_dec/ivas_binRenderer_internal_fx.c | 1 + lib_dec/ivas_core_dec_fx.c | 1 + lib_dec/ivas_cpe_dec_fx.c | 1 + lib_dec/ivas_decision_matrix_dec_fx.c | 1 + lib_dec/ivas_dirac_dec_fx.c | 1 + lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 1 + lib_dec/ivas_entropy_decoder_fx.c | 1 + lib_dec/ivas_ism_dec_fx.c | 1 + lib_dec/ivas_jbm_dec_fx.c | 1 + lib_dec/ivas_ls_custom_dec_fx.c | 1 + lib_dec/ivas_mc_param_dec_fx.c | 1 + lib_dec/ivas_mct_dec_fx.c | 1 + lib_dec/ivas_mct_dec_mct_fx_fx.c | 1 + lib_dec/ivas_objectRenderer_internal_fx.c | 1 + lib_dec/ivas_osba_dec_fx.c | 1 + lib_dec/ivas_out_setup_conversion_fx.c | 1 + lib_dec/ivas_pca_dec_fx.c | 1 + lib_dec/ivas_sba_dec_fx.c | 1 + lib_dec/ivas_sba_rendering_internal_fx.c | 1 + lib_dec/ivas_sns_dec_fx.c | 1 + lib_dec/ivas_spar_md_dec_fx.c | 1 + lib_dec/ivas_stereo_cng_dec.c | 1 + lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 1 + lib_dec/ivas_stereo_ica_dec_fx.c | 1 + lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 1 + lib_dec/ivas_stereo_switching_dec_fx.c | 1 + lib_dec/ivas_svd_dec_fx.c | 1 + lib_dec/ivas_tcx_core_dec_fx.c | 1 + lib_enc/cod_tcx_fx.c | 1 + lib_enc/igf_enc.c | 1 + lib_enc/ivas_agc_enc_fx.c | 1 + lib_enc/ivas_cpe_enc_fx.c | 1 + lib_enc/ivas_decision_matrix_enc_fx.c | 1 + lib_enc/ivas_enc_cov_handler_fx.c | 1 + lib_enc/ivas_enc_fx.c | 1 + lib_enc/ivas_front_vad_fx.c | 1 + lib_enc/ivas_init_enc_fx.c | 1 + lib_enc/ivas_ism_dtx_enc_fx.c | 1 + lib_enc/ivas_ism_enc_fx.c | 1 + lib_enc/ivas_lfe_enc_fx.c | 1 + lib_enc/ivas_mc_paramupmix_enc_fx.c | 1 + lib_enc/ivas_mct_core_enc_fx.c | 1 + lib_enc/ivas_mct_enc_fx.c | 1 + lib_enc/ivas_mdct_core_enc_fx.c | 1 + lib_enc/ivas_osba_enc_fx.c | 1 + lib_enc/ivas_pca_enc_fx.c | 1 + lib_enc/ivas_qmetadata_enc_fx.c | 1 + lib_enc/ivas_sns_enc_fx.c | 1 + lib_enc/ivas_stereo_adapt_GR_enc_fx.c | 1 + lib_enc/ivas_stereo_classifier_fx.c | 1 + lib_enc/ivas_stereo_cng_enc_fx.c | 1 + lib_enc/ivas_stereo_dft_enc_fx.c | 1 + lib_enc/ivas_stereo_ica_enc_fx.c | 1 + lib_enc/ivas_stereo_icbwe_enc_fx.c | 1 + lib_enc/ivas_stereo_switching_enc_fx.c | 1 + lib_enc/ivas_stereo_td_analysis_fx.c | 1 + lib_enc/ivas_stereo_td_enc_fx.c | 1 + lib_enc/lsf_msvq_ma_enc.c | 1 + lib_rend/ivas_allrad_dec_fx.c | 1 + lib_rend/ivas_crend_fx.c | 1 + lib_rend/ivas_dirac_ana_fx.c | 1 + lib_rend/ivas_dirac_decorr_dec_fx.c | 1 + lib_rend/ivas_dirac_onsets_dec_fx.c | 1 + lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 1 + lib_rend/ivas_dirac_rend_fx.c | 1 + lib_rend/ivas_mcmasa_ana_fx.c | 1 + lib_rend/ivas_objectRenderer_fx.c | 1 + lib_rend/ivas_vbap_fx.c | 1 + lib_util/hrtf_file_reader.c | 1 + lib_util/ls_custom_file_reader.c | 2 +- 91 files changed, 111 insertions(+), 7 deletions(-) diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index f0ee8efd8..ed72605de 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -40,6 +40,7 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 9243f640e..0921dc88c 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -2,11 +2,12 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "assert.h" /* Debug prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot.h" /* Function prototypes */ +#include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_arith_fx.c b/lib_com/ivas_arith_fx.c index 311bccff8..006a31177 100644 --- a/lib_com/ivas_arith_fx.c +++ b/lib_com/ivas_arith_fx.c @@ -34,6 +34,7 @@ #include "options.h" #include "wmc_auto.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 146587791..9b60b2c5c 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -36,6 +36,7 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_fb_mixer_fx.c b/lib_com/ivas_fb_mixer_fx.c index d5cd8d4f1..883861024 100644 --- a/lib_com/ivas_fb_mixer_fx.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -35,6 +35,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index 5f1a13afb..f1201b06c 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -36,6 +36,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_lfe_com_fx.c b/lib_com/ivas_lfe_com_fx.c index 3d1e7aee6..7464c41c2 100644 --- a/lib_com/ivas_lfe_com_fx.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include "ivas_stat_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_com/ivas_mc_com_fx.c b/lib_com/ivas_mc_com_fx.c index 8201037a1..62d623b83 100644 --- a/lib_com/ivas_mc_com_fx.c +++ b/lib_com/ivas_mc_com_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mct_com_fx.c b/lib_com/ivas_mct_com_fx.c index 81a56df14..1f3c58153 100644 --- a/lib_com/ivas_mct_com_fx.c +++ b/lib_com/ivas_mct_com_fx.c @@ -33,8 +33,8 @@ #include #include "options.h" #include "ivas_cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" -#include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com_fx.c b/lib_com/ivas_mdct_core_com_fx.c index fe313eecd..000f3992f 100644 --- a/lib_com/ivas_mdct_core_com_fx.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "ivas_cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mdft_imdft_fx.c b/lib_com/ivas_mdft_imdft_fx.c index 5d7bee1a6..b10444307 100644 --- a/lib_com/ivas_mdft_imdft_fx.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -34,6 +34,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index c9ad84097..79a585e8b 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -36,6 +36,7 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 6661026a8..5caa850cb 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -36,6 +36,7 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sba_config_fx.c b/lib_com/ivas_sba_config_fx.c index b3a0806d4..38785956c 100644 --- a/lib_com/ivas_sba_config_fx.c +++ b/lib_com/ivas_sba_config_fx.c @@ -38,6 +38,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_dft_com_fx.c b/lib_com/ivas_stereo_dft_com_fx.c index 6d63bc6d1..80e64c0cc 100644 --- a/lib_com/ivas_stereo_dft_com_fx.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_psychlpc_com_fx.c b/lib_com/ivas_stereo_psychlpc_com_fx.c index df5140895..cb3c39df2 100644 --- a/lib_com/ivas_stereo_psychlpc_com_fx.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -33,7 +33,9 @@ #include #include "options.h" #include "ivas_rom_com.h" +#include "ivas_prot.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index 04d6f7bf5..e15db9a15 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index 3b9a8cfd7..97025b46f 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -36,6 +36,7 @@ #include "wmc_auto.h" #include "prot_fx.h" #include "ivas_cnst.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_com.h" diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 12234a4c0..6bd8026c4 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -40,6 +40,7 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9fe14b5bd..c9ef0e87a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -72,6 +72,10 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif +#ifndef TRUNC +#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) +#endif + #define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) #define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) @@ -11944,6 +11948,13 @@ ivas_error openCldfb_ivas( CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); +ivas_error openCldfb_ivas_enc( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const Word32 sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const Word32 newSamplerate /* i : new samplerate to operate */ @@ -11953,6 +11964,10 @@ ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); +void deleteCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ +); + /*! r: flag indicating a valid bitrate */ Word16 is_EVS_bitrate( const Word32 ivas_total_brate, /* i : EVS total bitrate */ diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index c1b0ce93a..582169c85 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -9,6 +9,7 @@ #include "options.h" #include "stl.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "cnst.h" #include "stat_dec.h" diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 8527e6703..3c234c098 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -34,6 +34,7 @@ #include "options.h" #include #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 7b4e5f267..5bb4736e9 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -37,6 +37,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 9e934cc88..3749fb3fa 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -37,6 +37,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_decision_matrix_dec_fx.c b/lib_dec/ivas_decision_matrix_dec_fx.c index 717bb3b93..f7fd5e8e2 100644 --- a/lib_dec/ivas_decision_matrix_dec_fx.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -34,6 +34,7 @@ #include "options.h" #include "stat_dec.h" #include "rom_com.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index ac29a23e0..776d0c8bb 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index b247fd653..e03913f8a 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -41,6 +41,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_entropy_decoder_fx.c b/lib_dec/ivas_entropy_decoder_fx.c index f8bf3c091..e637a6a93 100644 --- a/lib_dec/ivas_entropy_decoder_fx.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 643874a82..664e3eeac 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 210425b88..428c817ef 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -36,6 +36,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ls_custom_dec_fx.c b/lib_dec/ivas_ls_custom_dec_fx.c index 5ad390f9a..45f59d82f 100644 --- a/lib_dec/ivas_ls_custom_dec_fx.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -31,6 +31,7 @@ *******************************************************************************************************/ #include #include "options.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 697ae6345..be2363469 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -37,6 +37,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 884a44c9e..081eca88d 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,6 +38,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index c275820fb..69f601724 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "ivas_cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index b88b68915..391a27522 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 6f1a233c9..07ea14ea2 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -33,6 +33,7 @@ #include "options.h" #include #include "ivas_cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 84b6fe46d..4811911fd 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -35,6 +35,7 @@ #include #include #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 98611ab7c..08ac17799 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index f04350366..efd766f76 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -36,6 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index 8748342ed..a42c67389 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index fd25e7ea7..170256181 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index 7f487a75c..bb79b956c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -34,6 +34,7 @@ #include "options.h" #include "math.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 223860db0..4d50ba350 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -35,6 +35,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index e82005965..0781d49a6 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index 694aad0b4..b49ab5399 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -37,6 +37,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 5b1378a89..6412f315e 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -35,6 +35,7 @@ #include #include "options.h" #include "ivas_cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c70e606ac..90fa9e175 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -35,6 +35,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 1467687d8..375dbdad0 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index 07eba9e64..c908e4dc3 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -40,6 +40,7 @@ #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 7c28c3309..c54e8ccf4 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,6 +16,7 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #endif diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index fc7c32fdb..f6adb0f31 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -39,6 +39,7 @@ #include "options.h" #include #include "prot_fx.h" +#include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index d74e10bda..104eeb998 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -35,6 +35,7 @@ #include #include #include "options.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 1152736f6..a9d62a2b0 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -37,6 +37,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #ifdef DEBUGGING diff --git a/lib_enc/ivas_decision_matrix_enc_fx.c b/lib_enc/ivas_decision_matrix_enc_fx.c index bd63553bd..1158f72fa 100644 --- a/lib_enc/ivas_decision_matrix_enc_fx.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -36,6 +36,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index c05d59b90..576bbb2c6 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index e8e1bc59e..0a2d976e1 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -37,6 +37,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index 8b76b37a4..0c3852bd5 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -37,6 +37,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index b49fc9716..c65c85356 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_enc.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index b29b0c15b..64b8991d6 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 1b648cc98..22bf88df8 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -34,6 +34,7 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 96959c9dd..11056b535 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -34,6 +34,7 @@ #include "options.h" #include "math.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index fd5cb6217..abd09cbbd 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -37,6 +37,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 71515571d..439c227ae 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 56f5e44db..d6bc4c7f0 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -37,6 +37,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 3272768e9..f67660902 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -37,6 +37,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 2a6944c50..1229624de 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -35,6 +35,7 @@ #include #include #include "ivas_cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" diff --git a/lib_enc/ivas_pca_enc_fx.c b/lib_enc/ivas_pca_enc_fx.c index 2cb347a02..410d5dd52 100644 --- a/lib_enc/ivas_pca_enc_fx.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_cnst.h" #include #include diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 2d6080995..b32c80404 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -36,6 +36,7 @@ #include #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 93ee56461..e321f1c7c 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c index 8e79b2288..70c2165f8 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 3e148a5ae..bfe683d6b 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -39,6 +39,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index aa7c2d0aa..255b6e938 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -37,6 +37,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 3eb6c0e82..ede3d3ad9 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -38,6 +38,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 057798706..78c324cce 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -37,6 +37,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index bc84ba419..78891c5f7 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -36,6 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 0a526561a..2f38045eb 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -35,6 +35,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 44c08efa8..efae1e80d 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -36,6 +36,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 1544aab76..2b550d3e9 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -36,6 +36,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 60375ddcc..6055bb0d1 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -37,6 +37,7 @@ #include #include "options.h" #include "cnst.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 770b62764..008e27d6c 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -36,6 +36,7 @@ #include #include #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index e50ad32e1..81437c49d 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -34,6 +34,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 1a5013059..c21ffd979 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -34,6 +34,7 @@ #include #include "ivas_cnst.h" #include "ivas_prot_rend.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index b8b3c3ac7..e89414542 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index e9af8483a..4eae9c286 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -35,6 +35,7 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 748b82d5c..983343bba 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index d438dc7f2..1822b0132 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -36,6 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index e17b2f9f6..9b3b062b8 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -36,6 +36,7 @@ #include "ivas_cnst.h" #include "options.h" #include "ivas_prot_rend.h" +#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 7b1e1fe91..93fe67436 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -34,6 +34,7 @@ #include #include "options.h" #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index b90b3a456..06cbd83a6 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -35,6 +35,7 @@ #include #include #include "prot_fx.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 0316d8b30..930bb79dc 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -34,6 +34,7 @@ #include #include "prot_fx.h" #include "ivas_prot_rend.h" +#include "ivas_prot.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index f4f43e496..90d47b7c9 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -33,7 +33,7 @@ #include "ls_custom_file_reader.h" #include #include -#include "ivas_prot_fx.h" +#include "ivas_prot.h" #include "prot_fx.h" -- GitLab From 3ac57f17c097e625f3c2047f37c05f61e72fead4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 10:13:00 +0530 Subject: [PATCH 0416/1221] Fix for 3GPP issue 1140: Missing conversion of some flt. pt. functions in the BASOP code Link #1140 --- lib_dec/dec_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index d1ed7ad8c..f231a077b 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3806,7 +3806,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 + *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } -- GitLab From fff2f5b6c2bfcbd2aae16a5bef95589d9213071d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 7 Mar 2025 14:58:16 +0530 Subject: [PATCH 0417/1221] Fix for LTV crash issue Fix for LTV crash : 4 ISM with metadata at 48 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL ROOM IR out, random FER at 5% --- lib_dec/dec_tcx_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index f231a077b..d1ed7ad8c 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3806,7 +3806,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); - *nf_seed = add_o( *nf_seed, shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ), &Overflow ); // abs( tmp32 ) * i * 2 + *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } -- GitLab From 96fd6e2b4d0446831883e4500d6a776e8fad859b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 09:48:48 +0530 Subject: [PATCH 0418/1221] Fix for 3GPP issue 1037: Wrong variable type used in the fixed-point code - 1 Link #1037 --- lib_com/prot_fx.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c9ef0e87a..d2e43e9b2 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -72,10 +72,6 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif -#ifndef TRUNC -#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) -#endif - #define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) #define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) -- GitLab From bd596e48e5bec3ffc756b298498b85d41dde91c4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 19:34:14 +0530 Subject: [PATCH 0419/1221] Bug fixes, ivas_prot.h cleanup, Q documentation updates --- lib_com/core_com_config.c | 1 - lib_com/gs_bitallocation_ivas_fx.c | 1 - lib_com/ivas_arith_fx.c | 1 - lib_com/ivas_dirac_com_fx.c | 1 - lib_com/ivas_fb_mixer_fx.c | 1 - lib_com/ivas_ism_com_fx.c | 1 - lib_com/ivas_lfe_com_fx.c | 1 - lib_com/ivas_mc_com_fx.c | 1 - lib_com/ivas_mct_com_fx.c | 2 +- lib_com/ivas_mdct_core_com_fx.c | 1 - lib_com/ivas_mdft_imdft_fx.c | 1 - lib_com/ivas_qmetadata_com_fx.c | 1 - lib_com/ivas_qspherical_com_fx.c | 1 - lib_com/ivas_sba_config_fx.c | 1 - lib_com/ivas_stereo_dft_com_fx.c | 1 - lib_com/ivas_stereo_psychlpc_com_fx.c | 2 -- lib_com/ivas_tools_fx.c | 1 - lib_com/ivas_transient_det_fx.c | 1 - lib_com/mslvq_com.c | 1 - lib_dec/igf_dec_fx.c | 1 - lib_dec/ivas_binRenderer_internal_fx.c | 1 - lib_dec/ivas_core_dec_fx.c | 1 - lib_dec/ivas_cpe_dec_fx.c | 1 - lib_dec/ivas_decision_matrix_dec_fx.c | 1 - lib_dec/ivas_dirac_dec_fx.c | 1 - lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 1 - lib_dec/ivas_entropy_decoder_fx.c | 1 - lib_dec/ivas_ism_dec_fx.c | 1 - lib_dec/ivas_jbm_dec_fx.c | 1 - lib_dec/ivas_ls_custom_dec_fx.c | 1 - lib_dec/ivas_mc_param_dec_fx.c | 1 - lib_dec/ivas_mct_dec_fx.c | 1 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 1 - lib_dec/ivas_objectRenderer_internal_fx.c | 1 - lib_dec/ivas_osba_dec_fx.c | 1 - lib_dec/ivas_out_setup_conversion_fx.c | 1 - lib_dec/ivas_pca_dec_fx.c | 1 - lib_dec/ivas_sba_dec_fx.c | 1 - lib_dec/ivas_sba_rendering_internal_fx.c | 1 - lib_dec/ivas_sns_dec_fx.c | 1 - lib_dec/ivas_spar_md_dec_fx.c | 1 - lib_dec/ivas_stereo_cng_dec.c | 1 - lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 1 - lib_dec/ivas_stereo_ica_dec_fx.c | 1 - lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 1 - lib_dec/ivas_stereo_switching_dec_fx.c | 1 - lib_dec/ivas_svd_dec_fx.c | 1 - lib_dec/ivas_tcx_core_dec_fx.c | 1 - lib_enc/cod_tcx_fx.c | 1 - lib_enc/igf_enc.c | 1 - lib_enc/ivas_agc_enc_fx.c | 1 - lib_enc/ivas_cpe_enc_fx.c | 1 - lib_enc/ivas_decision_matrix_enc_fx.c | 1 - lib_enc/ivas_enc_cov_handler_fx.c | 1 - lib_enc/ivas_enc_fx.c | 1 - lib_enc/ivas_front_vad_fx.c | 1 - lib_enc/ivas_init_enc_fx.c | 1 - lib_enc/ivas_ism_dtx_enc_fx.c | 1 - lib_enc/ivas_ism_enc_fx.c | 1 - lib_enc/ivas_lfe_enc_fx.c | 1 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 1 - lib_enc/ivas_mct_core_enc_fx.c | 1 - lib_enc/ivas_mct_enc_fx.c | 1 - lib_enc/ivas_mdct_core_enc_fx.c | 1 - lib_enc/ivas_osba_enc_fx.c | 1 - lib_enc/ivas_pca_enc_fx.c | 1 - lib_enc/ivas_qmetadata_enc_fx.c | 1 - lib_enc/ivas_sns_enc_fx.c | 1 - lib_enc/ivas_stereo_adapt_GR_enc_fx.c | 1 - lib_enc/ivas_stereo_classifier_fx.c | 1 - lib_enc/ivas_stereo_cng_enc_fx.c | 1 - lib_enc/ivas_stereo_dft_enc_fx.c | 1 - lib_enc/ivas_stereo_ica_enc_fx.c | 1 - lib_enc/ivas_stereo_icbwe_enc_fx.c | 1 - lib_enc/ivas_stereo_switching_enc_fx.c | 1 - lib_enc/ivas_stereo_td_analysis_fx.c | 1 - lib_enc/ivas_stereo_td_enc_fx.c | 1 - lib_enc/lsf_msvq_ma_enc.c | 1 - lib_rend/ivas_allrad_dec_fx.c | 1 - lib_rend/ivas_crend_fx.c | 1 - lib_rend/ivas_dirac_ana_fx.c | 1 - lib_rend/ivas_dirac_decorr_dec_fx.c | 1 - lib_rend/ivas_dirac_onsets_dec_fx.c | 1 - lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 1 - lib_rend/ivas_dirac_rend_fx.c | 1 - lib_rend/ivas_mcmasa_ana_fx.c | 1 - lib_rend/ivas_objectRenderer_fx.c | 1 - lib_rend/ivas_vbap_fx.c | 1 - lib_util/hrtf_file_reader.c | 1 - lib_util/ls_custom_file_reader.c | 2 +- 90 files changed, 2 insertions(+), 91 deletions(-) diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index ed72605de..f0ee8efd8 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 0921dc88c..71b30ea75 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_arith_fx.c b/lib_com/ivas_arith_fx.c index 006a31177..311bccff8 100644 --- a/lib_com/ivas_arith_fx.c +++ b/lib_com/ivas_arith_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "wmc_auto.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 9b60b2c5c..146587791 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_fb_mixer_fx.c b/lib_com/ivas_fb_mixer_fx.c index 883861024..d5cd8d4f1 100644 --- a/lib_com/ivas_fb_mixer_fx.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_ism_com_fx.c b/lib_com/ivas_ism_com_fx.c index f1201b06c..5f1a13afb 100644 --- a/lib_com/ivas_ism_com_fx.c +++ b/lib_com/ivas_ism_com_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_lfe_com_fx.c b/lib_com/ivas_lfe_com_fx.c index 7464c41c2..3d1e7aee6 100644 --- a/lib_com/ivas_lfe_com_fx.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_stat_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_com/ivas_mc_com_fx.c b/lib_com/ivas_mc_com_fx.c index 62d623b83..8201037a1 100644 --- a/lib_com/ivas_mc_com_fx.c +++ b/lib_com/ivas_mc_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mct_com_fx.c b/lib_com/ivas_mct_com_fx.c index 1f3c58153..81a56df14 100644 --- a/lib_com/ivas_mct_com_fx.c +++ b/lib_com/ivas_mct_com_fx.c @@ -33,8 +33,8 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com_fx.c b/lib_com/ivas_mdct_core_com_fx.c index 000f3992f..fe313eecd 100644 --- a/lib_com/ivas_mdct_core_com_fx.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mdft_imdft_fx.c b/lib_com/ivas_mdft_imdft_fx.c index b10444307..5d7bee1a6 100644 --- a/lib_com/ivas_mdft_imdft_fx.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index 79a585e8b..c9ad84097 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -36,7 +36,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 5caa850cb..6661026a8 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sba_config_fx.c b/lib_com/ivas_sba_config_fx.c index 38785956c..b3a0806d4 100644 --- a/lib_com/ivas_sba_config_fx.c +++ b/lib_com/ivas_sba_config_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_dft_com_fx.c b/lib_com/ivas_stereo_dft_com_fx.c index 80e64c0cc..6d63bc6d1 100644 --- a/lib_com/ivas_stereo_dft_com_fx.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_stereo_psychlpc_com_fx.c b/lib_com/ivas_stereo_psychlpc_com_fx.c index cb3c39df2..df5140895 100644 --- a/lib_com/ivas_stereo_psychlpc_com_fx.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -33,9 +33,7 @@ #include #include "options.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index e15db9a15..04d6f7bf5 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index 97025b46f..3b9a8cfd7 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -36,7 +36,6 @@ #include "wmc_auto.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_com.h" diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 6bd8026c4..12234a4c0 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -40,7 +40,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 582169c85..c1b0ce93a 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -9,7 +9,6 @@ #include "options.h" #include "stl.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "cnst.h" #include "stat_dec.h" diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 3c234c098..8527e6703 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 5bb4736e9..7b4e5f267 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 3749fb3fa..9e934cc88 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_decision_matrix_dec_fx.c b/lib_dec/ivas_decision_matrix_dec_fx.c index f7fd5e8e2..717bb3b93 100644 --- a/lib_dec/ivas_decision_matrix_dec_fx.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "stat_dec.h" #include "rom_com.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 776d0c8bb..ac29a23e0 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index e03913f8a..b247fd653 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -41,7 +41,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_entropy_decoder_fx.c b/lib_dec/ivas_entropy_decoder_fx.c index e637a6a93..f8bf3c091 100644 --- a/lib_dec/ivas_entropy_decoder_fx.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 664e3eeac..643874a82 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 428c817ef..210425b88 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ls_custom_dec_fx.c b/lib_dec/ivas_ls_custom_dec_fx.c index 45f59d82f..5ad390f9a 100644 --- a/lib_dec/ivas_ls_custom_dec_fx.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include #include "options.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index be2363469..697ae6345 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 081eca88d..884a44c9e 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,7 +38,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index 69f601724..c275820fb 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index 391a27522..b88b68915 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 07ea14ea2..6f1a233c9 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -33,7 +33,6 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 4811911fd..84b6fe46d 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 08ac17799..98611ab7c 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index efd766f76..f04350366 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index a42c67389..8748342ed 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 170256181..fd25e7ea7 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_spar_md_dec_fx.c b/lib_dec/ivas_spar_md_dec_fx.c index bb79b956c..7f487a75c 100644 --- a/lib_dec/ivas_spar_md_dec_fx.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 4d50ba350..223860db0 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -35,7 +35,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index 0781d49a6..e82005965 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index b49ab5399..694aad0b4 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 6412f315e..5b1378a89 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -35,7 +35,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 90fa9e175..c70e606ac 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 375dbdad0..1467687d8 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index c908e4dc3..07eba9e64 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -40,7 +40,6 @@ #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index c54e8ccf4..7c28c3309 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,7 +16,6 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #endif diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index f6adb0f31..fc7c32fdb 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -39,7 +39,6 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_agc_enc_fx.c b/lib_enc/ivas_agc_enc_fx.c index 104eeb998..d74e10bda 100644 --- a/lib_enc/ivas_agc_enc_fx.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index a9d62a2b0..1152736f6 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #ifdef DEBUGGING diff --git a/lib_enc/ivas_decision_matrix_enc_fx.c b/lib_enc/ivas_decision_matrix_enc_fx.c index 1158f72fa..bd63553bd 100644 --- a/lib_enc/ivas_decision_matrix_enc_fx.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /* Function prototypes */ diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index 576bbb2c6..c05d59b90 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index 0a2d976e1..e8e1bc59e 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -37,7 +37,6 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index 0c3852bd5..8b76b37a4 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index c65c85356..b49fc9716 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_enc.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 64b8991d6..b29b0c15b 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 22bf88df8..1b648cc98 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 11056b535..96959c9dd 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -34,7 +34,6 @@ #include "options.h" #include "math.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index abd09cbbd..fd5cb6217 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 439c227ae..71515571d 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index d6bc4c7f0..56f5e44db 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index f67660902..3272768e9 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -37,7 +37,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 1229624de..2a6944c50 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -35,7 +35,6 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" diff --git a/lib_enc/ivas_pca_enc_fx.c b/lib_enc/ivas_pca_enc_fx.c index 410d5dd52..2cb347a02 100644 --- a/lib_enc/ivas_pca_enc_fx.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include #include diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index b32c80404..2d6080995 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -36,7 +36,6 @@ #include #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e321f1c7c..93ee56461 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c index 70c2165f8..8e79b2288 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc_fx.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -33,7 +33,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index bfe683d6b..3e148a5ae 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -39,7 +39,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index 255b6e938..aa7c2d0aa 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -37,7 +37,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index ede3d3ad9..3eb6c0e82 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -38,7 +38,6 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 78c324cce..057798706 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -37,7 +37,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 78891c5f7..bc84ba419 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 2f38045eb..0a526561a 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -35,7 +35,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index efae1e80d..44c08efa8 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 2b550d3e9..1544aab76 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -36,7 +36,6 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 6055bb0d1..60375ddcc 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -37,7 +37,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 008e27d6c..770b62764 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -36,7 +36,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index 81437c49d..e50ad32e1 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index c21ffd979..1a5013059 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -34,7 +34,6 @@ #include #include "ivas_cnst.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index e89414542..b8b3c3ac7 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index 4eae9c286..e9af8483a 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -35,7 +35,6 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 983343bba..748b82d5c 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 1822b0132..d438dc7f2 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -36,7 +36,6 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index 9b3b062b8..e17b2f9f6 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -36,7 +36,6 @@ #include "ivas_cnst.h" #include "options.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 93fe67436..7b1e1fe91 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -34,7 +34,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index 06cbd83a6..b90b3a456 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -35,7 +35,6 @@ #include #include #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 930bb79dc..0316d8b30 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -34,7 +34,6 @@ #include #include "prot_fx.h" #include "ivas_prot_rend.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 90d47b7c9..f4f43e496 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -33,7 +33,7 @@ #include "ls_custom_file_reader.h" #include #include -#include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot_fx.h" -- GitLab From 8b5efbd8734b40acd07beecdcbcacf78e277a4e4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 19:41:16 +0530 Subject: [PATCH 0420/1221] Clang formatting changes --- lib_com/gs_bitallocation_ivas_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 71b30ea75..9243f640e 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -2,11 +2,11 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "assert.h" /* Debug prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" -- GitLab From 2f3a79116c56295e2ba3f3ed05e6377b5e1b3a20 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 12:52:44 +0530 Subject: [PATCH 0421/1221] USAN fix for decoder --- lib_dec/ivas_lfe_plc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index d98603d2a..8ed450435 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate( s ), err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate(s), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); -- GitLab From 0a0705bf0317445bdf423faaf4366b2205a0816b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 12:55:14 +0530 Subject: [PATCH 0422/1221] Clang formatting changes --- lib_dec/ivas_lfe_plc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 8ed450435..d98603d2a 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate(s), err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate( s ), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); -- GitLab From 3a5e04634454aff220c1712343e6a318cfc58c05 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 11 Mar 2025 12:32:57 +0530 Subject: [PATCH 0423/1221] Fix for 3GPP issue 1341: Usage of open/deleteCldfb() functions - multiple variants Link #1341 --- lib_com/cldfb.c | 10 ++++------ lib_com/cnst.h | 6 +++++- lib_com/prot_fx.h | 13 +------------ lib_dec/init_dec_fx.c | 6 +++--- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 ++-- lib_dec/ivas_init_dec.c | 4 ++-- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 ++-- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +++++----- lib_enc/init_enc_fx.c | 4 ++-- lib_enc/ivas_masa_enc_fx.c | 2 +- lib_enc/ivas_omasa_enc_fx.c | 2 +- lib_enc/ivas_stereo_switching_enc_fx.c | 6 +++--- lib_enc/ivas_stereo_td_enc_fx.c | 4 ++-- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 ++-- 19 files changed, 40 insertions(+), 49 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 246a8a8e8..7fc8026b5 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1365,7 +1365,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - const Word16 enc_dec ) /* i : encoder/decoder flag */ + CODE_TYPE code_type ) { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,17 +1379,14 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - IF( enc_dec == ENC ) + IF( code_type == IVAS_ENC ) { configureCldfb_ivas_enc_fx( hs, sampling_rate ); - hs->Q_cldfb_state = 0; } ELSE { configureCldfb_ivas_fx( hs, sampling_rate ); - hs->Q_cldfb_state = Q11; } - move16(); hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1415,7 +1412,8 @@ ivas_error openCldfb_ivas_fx( hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ move16(); set32_fx( hs->cldfb_state_fx, 0, buf_len ); - + hs->Q_cldfb_state = Q11; + move16(); *h_cldfb = hs; move16(); diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 4e14b310d..8f716f18e 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -806,7 +806,11 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; - +typedef enum +{ + IVAS_ENC, + IVAS_DEC_REND +} CODE_TYPE; typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d2e43e9b2..c1aefbe36 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9804,7 +9804,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - const Word16 enc_dec ); /* i : encoder/decoder flag */ + CODE_TYPE code_type ); Word32 rand_gauss_fx( Word32 *x, @@ -11944,13 +11944,6 @@ ivas_error openCldfb_ivas( CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const Word32 newSamplerate /* i : new samplerate to operate */ @@ -11960,10 +11953,6 @@ ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - /*! r: flag indicating a valid bitrate */ Word16 is_EVS_bitrate( const Word32 ivas_total_brate, /* i : EVS total bitrate */ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index bd8a2cbd3..4e0cfda18 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 8333f146f..111c0be0e 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 1ab797ded..236eaad54 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index 12549f49d..cc3980b12 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 5b1378a89..c8dde0837 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c70e606ac..34eef94ed 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index cd5db5377..f0338b461 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index da1f836df..9fdebed7a 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index b5258712b..50fb49355 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 0a526561a..6c7a1e68d 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 1544aab76..de9bc09b5 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 1a5013059..5dd3f8384 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index c74477365..3aa9f62a9 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index e17b2f9f6..d56ba2685 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 5e175fae5..1d849a90f 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 29030ca0c..ed513e91a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 1002fad42819c4bdc5c861dbdd2aec1059eba2cc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 12 Mar 2025 11:42:57 +0530 Subject: [PATCH 0424/1221] Address review comments --- lib_com/cldfb.c | 10 ++++++---- lib_com/cnst.h | 6 +----- lib_com/prot_fx.h | 2 +- lib_dec/init_dec_fx.c | 6 +++--- lib_dec/ivas_corecoder_dec_reconfig_fx.c | 4 ++-- lib_dec/ivas_init_dec.c | 4 ++-- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 ++-- lib_dec/ivas_stereo_switching_dec_fx.c | 10 +++++----- lib_enc/init_enc_fx.c | 4 ++-- lib_enc/ivas_masa_enc_fx.c | 2 +- lib_enc/ivas_omasa_enc_fx.c | 2 +- lib_enc/ivas_stereo_switching_enc_fx.c | 6 +++--- lib_enc/ivas_stereo_td_enc_fx.c | 4 ++-- lib_rend/ivas_dirac_ana_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/lib_rend.c | 4 ++-- 19 files changed, 38 insertions(+), 40 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 7fc8026b5..246a8a8e8 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1365,7 +1365,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ) + const Word16 enc_dec ) /* i : encoder/decoder flag */ { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1379,14 +1379,17 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - IF( code_type == IVAS_ENC ) + IF( enc_dec == ENC ) { configureCldfb_ivas_enc_fx( hs, sampling_rate ); + hs->Q_cldfb_state = 0; } ELSE { configureCldfb_ivas_fx( hs, sampling_rate ); + hs->Q_cldfb_state = Q11; } + move16(); hs->memory32 = NULL; hs->FilterStates = NULL; hs->memory_length = 0; @@ -1412,8 +1415,7 @@ ivas_error openCldfb_ivas_fx( hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ move16(); set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = Q11; - move16(); + *h_cldfb = hs; move16(); diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 8f716f18e..4e14b310d 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -806,11 +806,7 @@ typedef enum CLDFB_ANALYSIS, CLDFB_SYNTHESIS } CLDFB_TYPE; -typedef enum -{ - IVAS_ENC, - IVAS_DEC_REND -} CODE_TYPE; + typedef enum { CLDFB_PROTOTYPE_1_25MS, diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c1aefbe36..9fe14b5bd 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9804,7 +9804,7 @@ ivas_error openCldfb_ivas_fx( CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ - CODE_TYPE code_type ); + const Word16 enc_dec ); /* i : encoder/decoder flag */ Word32 rand_gauss_fx( Word32 *x, diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4e0cfda18..bd8a2cbd3 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1447,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1465,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_corecoder_dec_reconfig_fx.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c index 111c0be0e..8333f146f 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig_fx.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -602,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -622,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 236eaad54..1ab797ded 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2264,7 +2264,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2276,7 +2276,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index cc3980b12..12549f49d 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -438,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index c8dde0837..5b1378a89 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -601,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -610,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 34eef94ed..c70e606ac 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -752,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -761,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1100,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index f0338b461..cd5db5377 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1695,7 +1695,7 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -1809,7 +1809,7 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 9fdebed7a..da1f836df 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -152,7 +152,7 @@ ivas_error ivas_masa_enc_open_fx( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 50fb49355..b5258712b 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -124,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_ENC ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 6c7a1e68d..0a526561a 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -417,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -433,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -587,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index de9bc09b5..1544aab76 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -309,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -322,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, IVAS_ENC ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 5dd3f8384..1a5013059 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -107,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index 3aa9f62a9..c74477365 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -499,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index d56ba2685..e17b2f9f6 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -224,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 1d849a90f..5e175fae5 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -133,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ed513e91a..29030ca0c 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8187,7 +8187,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -8195,7 +8195,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, IVAS_DEC_REND ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 500cf508bde93ac74c0a3d5c569c10866906cc50 Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 15:53:43 +0100 Subject: [PATCH 0425/1221] Fix for stereo DMX / PHA mode : Change the resolution and improve the precision of several variables. --- lib_com/options.h | 6 + lib_enc/ivas_stat_enc.h | 9 +- lib_enc/ivas_stereo_dmx_evs_fx.c | 195 ++++++++++++++++++++++++++----- 3 files changed, 181 insertions(+), 29 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index d03261715..a2eba7aad 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,4 +172,10 @@ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ + +#define FIX_1386_STEREO_DMX_EVS_PHA /* Orange: Fix for stereo DMX / PHA mode : Change the filter taps resolution (Q31->Q30), improve precision for the IR window, for the ILD & IPD smoothing in sub-bands, for the ISD counters and for ICCr. */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#undef FIX_ISSUE_1153 /* With FIX_1386_STEREO_DMX_EVS_PHA, the FIX_ISSUE_1153 should not be activated. */ +#endif + #endif diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index ac258cfc1..397eb3cc3 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1183,7 +1183,11 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word32 isd_rate_s_fx; // Q31 +#else Word16 isd_rate_s_fx; // Q15 +#endif Word32 iccr_s_fx; // Q31 Word32 ipd_ff_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word32 Pr_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 @@ -1224,8 +1228,11 @@ typedef struct stereo_dmx_evs_enc_data_structure STEREO_DMX_EVS_POC_HANDLE hPOC; STEREO_DMX_EVS_PHA_HANDLE hPHA; - +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd_fx; // Q0 +#else Word32 itd_fx; // Q16 +#endif Word32 pre_dmx_energy_fx[1]; Word16 pre_dmx_energy_fx_e[1]; diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index ae8a8203e..bfb703c94 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -65,12 +65,20 @@ #define Q_BAND_FX 536870912 /*Q31*/ -#define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 +#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#define STEREO_DMX_EVS_ISD_FORGETTING_Q31 2040109465 +#define STEREO_DMX_EVS_ISD_1MFORGETTING_Q15 1638 +#define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 773094113 +#define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 923417968 +#define STEREO_DMX_EVS_ISD_INVTHRES_H 1270700383 +#else +#define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 11796 #define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 14090 +#endif #define STEREO_DMX_EVS_ICCR_FORGETTING_Q31 1503238554 #define STEREO_DMX_EVS_ICCR_HYST_L_Q31 1610612736 @@ -153,8 +161,12 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word32 itd[], /* o : estimated itd Q16 */ - const Word16 input_frame /* i : input frame length per channel */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd[], /* o : estimated itd Q0 */ +#else + Word32 itd[], /* o : estimated itd Q16 */ +#endif + const Word16 input_frame /* i : input frame length per channel */ ); static void adapt_gain_fx( const Word32 src_fx[], /* i : input signal Q16 */ @@ -196,9 +208,13 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word32 itd_fx[], /* o : estimated itd */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd_fx[], /* o : estimated itd */ +#else + Word32 itd_fx[], /* o : estimated itd */ +#endif + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio */ ); /*-------------------------------------------------------------------* * estimate_itd_wnd_fft() @@ -604,12 +620,21 @@ static void calc_poc_fx( Ni = L_sub( specLi[i], specRi[i] ); // spec_e Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e - // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) + // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), STEREO_DMX_EVS_ISD_INVTHRES_H ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) +#else IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) +#endif { isd_cnt_h = add( isd_cnt_h, 1 ); } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + W_tmp = W_add( W_mult0_32_32( Mpy_32_32_r( Dr, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Dr ), W_mult0_32_32( Mpy_32_32_r( Di, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Di ) ); // Q62 + IF( LT_64( W_add( W_mult0_32_32( Nr, Nr ), W_mult0_32_32( Ni, Ni ) ), W_tmp ) ) // Q62 +#else IF( LT_32( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), Mpy_32_32_r( STEREO_DMX_EVS_ISD_THRES_L_Q31, L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) ) +#endif { isd_cnt_l = add( isd_cnt_l, 1 ); } @@ -618,10 +643,19 @@ static void calc_poc_fx( isd_rate = BASOP_Util_Divide1616_Scale( isd_cnt_h, freq_8k, &isd_rate_e ); // Saturation to handle values close to 1.0f isd_rate = shl_sat( isd_rate, isd_rate_e ); // Q15 +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + hPHA->isd_rate_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ISD_FORGETTING_Q31, hPHA->isd_rate_s_fx ), L_mult( STEREO_DMX_EVS_ISD_1MFORGETTING_Q15, isd_rate ) ); + move32(); +#else hPHA->isd_rate_s_fx = add( mult_r( STEREO_DMX_EVS_ISD_FORGETTING_Q15, hPHA->isd_rate_s_fx ), mult_r( MAX_16 - STEREO_DMX_EVS_ISD_FORGETTING_Q15, isd_rate ) ); move16(); +#endif +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + IF( GT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 ) ) +#else IF( GT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 ) ) +#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD ) ) { @@ -646,7 +680,11 @@ static void calc_poc_fx( hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; move32(); } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + ELSE IF( LT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 ) ) +#else ELSE IF( LT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 ) ) +#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD2 ) ) { @@ -711,11 +749,36 @@ static void calc_poc_fx( FOR( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; ( j++, i++ ) ) { + /* Energy */ + +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + + // Left + W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); // Q(62-(2*specL_e)) -> Q(63 - ((2*specL_e) +1)) + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); // Q(63 - ((2*spec_e) - (L_tmp_e - 1)) + } + tEl[n] = BASOP_Util_Add_Mant32Exp( tEl[n], tEl_e[n], W_round64_L( W_tmp ), sub( shl( spec_e, 1 ), sub( L_tmp_e, 1 ) ), &tEl_e[n] ); + move32(); + + // Right + W_tmp = W_add( W_mult0_32_32( specRr[i], specRr[i] ), W_mult0_32_32( specRi[i], specRi[i] ) ); // Q(62-(2*specR_e)) -> Q(63 - ((2*specR_e) +1)) + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); // Q(63 - ((2*spec_e) - (L_tmp_e - 1)) + } + tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], W_round64_L( W_tmp ), sub( shl( spec_e, 1 ), sub( L_tmp_e, 1 ) ), &tEr_e[n] ); + move32(); +#else tEl[n] = BASOP_Util_Add_Mant32Exp( tEl[n], tEl_e[n], L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &tEl_e[n] ); move32(); tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &tEr_e[n] ); move32(); +#endif /* IPD */ // IPDr = L_add(Mpy_32_32_r(specLr[i], specRr[i]), Mpy_32_32_r(specLi[i], specRi[i])); //2*spec_e @@ -746,11 +809,35 @@ static void calc_poc_fx( tIPDr = L_sub( Mpy_32_32_r( specRr[i], IPDr ), Mpy_32_32_r( specRi[i], IPDi ) ); // spec_e tIPDi = L_add( Mpy_32_32_r( specRr[i], IPDi ), Mpy_32_32_r( specRi[i], IPDr ) ); // spec_e +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + + Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), 0, &Nr_e ); + Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), 0, &Ni_e ); + + // eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), 0, &eneL_e ); + W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); + } + eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, W_round64_L( W_tmp ), sub( 1, L_tmp_e ), &eneL_e ); + + // eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), 0, &eneR_e ); + W_tmp = W_add( W_mult0_32_32( specRr[i], specRr[i] ), W_mult0_32_32( specRi[i], specRi[i] ) ); + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); + } + eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, W_round64_L( W_tmp ), sub( 1, L_tmp_e ), &eneR_e ); +#else Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), shl( spec_e, 1 ), &Nr_e ); Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), shl( spec_e, 1 ), &Ni_e ); eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &eneL_e ); eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &eneR_e ); +#endif } // Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON ); @@ -768,7 +855,13 @@ static void calc_poc_fx( move32(); Pi[n] = L_add( Mpy_32_32_r( ipd_ff[n], Pi[n] ), Mpy_32_32_r( L_sub( MAX_32, ipd_ff[n] ), tPi ) ); move32(); + // Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Pn = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); + Pn = BASOP_Util_Add_Mant32Exp( Pn, 1, EPSILON_FX_M, EPSILON_FX_E, &Pn_e ); + Pn = Isqrt_lc( Pn, &Pn_e ); +#else L_tmp = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); L_tmp_e = 1; move16(); @@ -776,6 +869,8 @@ static void calc_poc_fx( Pn_e = L_tmp_e; move16(); Pn = ISqrt32( L_tmp, &Pn_e ); +#endif + Pr[n] = L_shl_sat( Mpy_32_32_r( Pr[n], Pn ), Pn_e ); // Q31 move32(); Pi[n] = L_shl_sat( Mpy_32_32_r( Pi[n], Pn ), Pn_e ); // Q31 @@ -984,7 +1079,13 @@ static void calc_poc_fx( #ifdef FIX_ISSUE_1153 hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 #else + +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 +#else hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 +#endif + #endif move32(); } @@ -1015,7 +1116,11 @@ static void calc_poc_fx( energy = ISqrt32( energy, &energy_e ); FOR( i = 0; i < hPHA->pha_len; i++ ) { +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), sub( energy_e, 1 ) ); // Q30 +#else hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), energy_e ); // Q31 +#endif move32(); } } @@ -1118,9 +1223,13 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word32 itd_fx[], /* o : estimated itd Q16 */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio Q31 */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd_fx[], /* o : estimated itd Q0 */ +#else + Word32 itd_fx[], /* o : estimated itd Q16 */ +#endif + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) { Word16 itd_cand[CPE_CHANNELS], i, n, cnt[CPE_CHANNELS], Lh, peak_range, *on, *itdLR, prev_off[CPE_CHANNELS], eps_fx; @@ -1430,8 +1539,12 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word32 itd[], /* o : estimated itd Q16 */ - const Word16 input_frame /* i : input frame length per channel */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd[], /* o : estimated itd Q0 */ +#else + Word32 itd[], /* o : estimated itd Q16 */ +#endif + const Word16 input_frame /* i : input frame length per channel */ ) { Word32 specLr[L_FRAME48k / 2 + 1], specLi[L_FRAME48k / 2 + 1], specRr[L_FRAME48k / 2 + 1], specRi[L_FRAME48k / 2 + 1]; @@ -1938,9 +2051,9 @@ void stereo_dmx_evs_enc_fx( hStereoDmxEVS->dmx_weight_fx, hStereoDmxEVS->pre_dmx_energy_fx, hStereoDmxEVS->pre_dmx_energy_fx_e, hStereoDmxEVS->aux_dmx_energy_fx, hStereoDmxEVS->aux_dmx_energy_fx_e ); // Downscaling signals to avoid accumulation overflows - scale_sig32( data_fx[0], input_frame, -5 ); // Q16->Q11 - scale_sig32( data_fx[1], input_frame, -5 ); // Q16->Q11 - scale_sig32( dmx_poc_data, input_frame, -5 ); // Q16->Q11 + scale_sig32( data_fx[0], input_frame, -5 ); // Q31->Q26 + scale_sig32( data_fx[1], input_frame, -5 ); // Q31->Q26 + scale_sig32( dmx_poc_data, input_frame, -5 ); // Q31->Q26 /* pha */ @@ -1969,9 +2082,11 @@ void stereo_dmx_evs_enc_fx( FOR( ( fx_tmp = 0, m = 0 ); m < pha_len; m++ ) { // ftmp += p_data_mem[n - m] * p_prev_taps[m]; - // fx_tmp = BASOP_Util_Add_Mant32Exp(fx_tmp, fx_tmp_e, Mpy_32_32(p_data_mem[n - m], p_prev_taps[m]),15,&fx_tmp_e); - fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q11 + fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q25 } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + fx_tmp = L_shl( fx_tmp, 1 ); // Q26 +#endif mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); move32(); } @@ -1981,7 +2096,7 @@ void stereo_dmx_evs_enc_fx( FOR( n = 0; n < fad_len; n++ ) { // mem_prev[n] += p_data[n] * INV_SQRT_2; - mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q11 + mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q26 move32(); } } @@ -1994,10 +2109,13 @@ void stereo_dmx_evs_enc_fx( FOR( ( fx_tmp = 0, m = 0 ); m < pha_len; m++ ) { // ftmp += p_data_mem[n - m] * p_curr_taps[m]; - fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q11 + fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q25 } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + fx_tmp = L_shl( fx_tmp, 1 ); // Q26 +#endif // dmx_pha_data[n] += ftmp * INV_SQRT_2; - dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); // Q11 + dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); // Q26 move32(); } } @@ -2006,7 +2124,7 @@ void stereo_dmx_evs_enc_fx( FOR( n = 0; n < n_samples; n++ ) { // dmx_pha_data[n] += p_data[n] * INV_SQRT_2; - dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q11 + dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q26 move32(); } } @@ -2016,7 +2134,7 @@ void stereo_dmx_evs_enc_fx( { dmx_pha_data[n] = Mpy_32_32( dmx_pha_data[n], fad_g[n] ); move32(); - dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( mem_prev[n], fad_g[m] ) ); // Q11 + dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( mem_prev[n], fad_g[m] ) ); // Q26 move32(); } @@ -2025,7 +2143,11 @@ void stereo_dmx_evs_enc_fx( curr_prc = hStereoDmxEVS->hPHA->curr_prc; move32(); // if ( abs( (int16_t) hStereoDmxEVS->itd ) > hStereoDmxEVS->hPHA->prc_thres ) +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + IF( GT_16( abs_s( hStereoDmxEVS->itd_fx ), hStereoDmxEVS->hPHA->prc_thres ) ) +#else IF( GT_16( abs_s( round_fx( hStereoDmxEVS->itd_fx ) ), hStereoDmxEVS->hPHA->prc_thres ) ) +#endif { IF( NE_32( hStereoDmxEVS->hPHA->curr_prc, STEREO_DMX_EVS_PRC_POC ) ) { @@ -2102,9 +2224,9 @@ void stereo_dmx_evs_enc_fx( FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len; ( n++, m-- ) ) { - p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q11 + p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q26 move32(); - p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_pha_data[n] ) ); // Q11 + p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_pha_data[n] ) ); // Q26 move32(); } } @@ -2121,16 +2243,15 @@ void stereo_dmx_evs_enc_fx( FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len; ( n++, m-- ) ) { - p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q11 + p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q26 move32(); - p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_poc_data[n] ) ); // Q11 + p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_poc_data[n] ) ); // Q26 move32(); } } } - Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); // Q11->Q0 - + Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); // Q26->Q15 return; } @@ -2383,6 +2504,23 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_len = hStereoDmxEVS->hPHA->fad_len; move16(); +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q14*/, pha_len ); + hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; + move16(); + IF( EQ_32( input_Fs, 16000 ) ) + { + hStereoDmxEVS->hPHA->win_fx[pha_len - 1] = 7373; /*0.45f in Q14*/ + move16(); + } + ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) + { + hStereoDmxEVS->hPHA->win_fx[sub( pha_len, 2 )] = 19302; /*1.1781f in Q14*/ + move16(); + hStereoDmxEVS->hPHA->win_fx[sub( pha_len, 1 )] = 2816; /*0.1718f in Q14*/ + move16(); + } +#else trans_len = idiv1616( pha_len, 20 ); set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q15*/, sub( pha_len, trans_len ) ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; @@ -2396,6 +2534,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( win[n] = mult_r( add( ONE_IN_Q14, getCosWord16R2( imult1616( add( n, 1 ), tmp_r ) ) ), 29491 /*1.8/2 in Q15*/ ); move16(); } +#endif fad_g = hStereoDmxEVS->hPHA->fad_g_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); -- GitLab From 51e86b7db007a58de319961264c44c732d94128c Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 16:48:53 +0100 Subject: [PATCH 0426/1221] clang-format correction. --- lib_enc/ivas_stat_enc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 397eb3cc3..258a3074c 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1184,7 +1184,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure Word16 init_frmCntr; #ifdef FIX_1386_STEREO_DMX_EVS_PHA - Word32 isd_rate_s_fx; // Q31 + Word32 isd_rate_s_fx; // Q31 #else Word16 isd_rate_s_fx; // Q15 #endif @@ -1231,7 +1231,7 @@ typedef struct stereo_dmx_evs_enc_data_structure #ifdef FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx; // Q0 #else - Word32 itd_fx; // Q16 + Word32 itd_fx; // Q16 #endif Word32 pre_dmx_energy_fx[1]; -- GitLab From d27a08ed490024c004de72643145d778599a8c04 Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 16:58:01 +0100 Subject: [PATCH 0427/1221] Useless variable removed. --- lib_enc/ivas_stereo_dmx_evs_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index bfb703c94..e6b6b338f 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2272,7 +2272,11 @@ ivas_error stereo_dmx_evs_init_encoder_fx( Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 *win; +#else Word16 *win, tmp_r; +#endif const Word16 *p_ipd_w; Word16 tmp_e; -- GitLab From efd050064dc3610e93f48cb778b86ef3d6eb3af3 Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 17:23:12 +0100 Subject: [PATCH 0428/1221] Useless variable removed. --- lib_enc/ivas_stereo_dmx_evs_fx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index e6b6b338f..690e0b35e 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2270,11 +2270,13 @@ ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS; Word16 n, input_frame; - Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; - Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; #ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 m, len, pha_len, fad_len, fad_len2, rfft_ipd_coef_step, n0, input_frame_pha; + Word32 *fad_g, fad_r, *ipd_ff; Word16 *win; #else + Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; + Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; Word16 *win, tmp_r; #endif const Word16 *p_ipd_w; -- GitLab From 501aeb9eeb59fea7e379084771af936b51aabea8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Mar 2025 08:55:12 +0530 Subject: [PATCH 0429/1221] Cleanup of ivas_prot_rend.h, bug fixes and instrumentation changes --- Workspace_msvc/lib_rend.vcxproj | 2 +- Workspace_msvc/lib_rend.vcxproj.filters | 6 +- lib_com/ivas_prot.h | 4065 ----------------- lib_dec/ivas_binRenderer_internal_fx.c | 2 +- lib_dec/ivas_dirac_dec_fx.c | 2 +- lib_dec/ivas_init_dec.c | 2 +- lib_dec/ivas_ism_dec_fx.c | 2 +- lib_dec/ivas_ism_param_dec_fx.c | 2 +- lib_dec/ivas_ism_renderer_fx.c | 2 +- lib_dec/ivas_jbm_dec_fx.c | 2 +- lib_dec/ivas_masa_dec_fx.c | 2 +- lib_dec/ivas_mc_param_dec_fx.c | 8 +- lib_dec/ivas_mc_paramupmix_dec_fx.c | 2 +- lib_dec/ivas_mcmasa_dec_fx.c | 2 +- lib_dec/ivas_mct_core_dec_fx.c | 14 +- lib_dec/ivas_mct_dec_fx.c | 2 +- lib_dec/ivas_mdct_core_dec_fx.c | 2 +- lib_dec/ivas_objectRenderer_internal_fx.c | 2 +- lib_dec/ivas_omasa_dec_fx.c | 2 +- lib_dec/ivas_osba_dec_fx.c | 2 +- lib_dec/ivas_out_setup_conversion_fx.c | 2 +- lib_dec/ivas_sba_dec_fx.c | 2 +- lib_dec/ivas_sba_rendering_internal_fx.c | 4 +- lib_dec/ivas_sns_dec_fx.c | 2 +- lib_dec/ivas_spar_decoder_fx.c | 2 +- lib_dec/lib_dec_fx.c | 2 +- lib_enc/cod_tcx_fx.c | 2 +- lib_enc/ivas_ism_dtx_enc_fx.c | 2 +- lib_enc/ivas_mdct_core_enc_fx.c | 10 +- lib_enc/ivas_sns_enc_fx.c | 2 +- lib_enc/swb_bwe_enc_fx.c | 9 +- lib_rend/ivas_allrad_dec_fx.c | 2 +- lib_rend/ivas_crend_fx.c | 2 +- lib_rend/ivas_dirac_ana_fx.c | 2 +- .../ivas_dirac_dec_binaural_functions_fx.c | 2 +- lib_rend/ivas_dirac_decorr_dec_fx.c | 2 +- lib_rend/ivas_dirac_onsets_dec_fx.c | 2 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 2 +- lib_rend/ivas_dirac_rend_fx.c | 2 +- lib_rend/ivas_efap_fx.c | 2 +- lib_rend/ivas_hrtf_fx.c | 2 +- lib_rend/ivas_limiter_fx.c | 2 +- lib_rend/ivas_masa_merge_fx.c | 2 +- lib_rend/ivas_mcmasa_ana_fx.c | 2 +- lib_rend/ivas_objectRenderer_fx.c | 2 +- lib_rend/ivas_objectRenderer_hrFilt_fx.c | 2 +- lib_rend/ivas_objectRenderer_mix_fx.c | 2 +- lib_rend/ivas_objectRenderer_sfx_fx.c | 2 +- lib_rend/ivas_objectRenderer_sources_fx.c | 2 +- lib_rend/ivas_objectRenderer_vec_fx.c | 43 +- lib_rend/ivas_omasa_ana_fx.c | 2 +- lib_rend/ivas_orient_trk_fx.c | 2 +- lib_rend/ivas_output_init.c | 2 +- lib_rend/ivas_output_init_fx.c | 2 +- .../{ivas_prot_rend.h => ivas_prot_rend_fx.h} | 571 +-- lib_rend/ivas_reflections_fx.c | 2 +- lib_rend/ivas_render_config_fx.c | 2 +- lib_rend/ivas_reverb_delay_line_fx.c | 2 +- lib_rend/ivas_reverb_fft_filter_fx.c | 2 +- lib_rend/ivas_reverb_filter_design_fx.c | 2 +- lib_rend/ivas_reverb_fx.c | 2 +- lib_rend/ivas_reverb_iir_filter_fx.c | 2 +- lib_rend/ivas_reverb_utils_fx.c | 2 +- lib_rend/ivas_rotation_fx.c | 2 +- lib_rend/ivas_sba_rendering_fx.c | 2 +- lib_rend/ivas_shoebox_fx.c | 2 +- lib_rend/ivas_td_decorr_fx.c | 2 +- lib_rend/ivas_vbap_fx.c | 2 +- lib_rend/lib_rend.c | 2 +- lib_util/hrtf_file_reader.c | 2 +- 70 files changed, 111 insertions(+), 4741 deletions(-) delete mode 100644 lib_com/ivas_prot.h rename lib_rend/{ivas_prot_rend.h => ivas_prot_rend_fx.h} (69%) diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 1ffab139a..e47858ae3 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -179,7 +179,7 @@ - + diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index 47b4fee01..5c4a49011 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -125,9 +125,6 @@ - - rend_h - rend_h @@ -143,6 +140,9 @@ rend_h + + rend_h + diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h deleted file mode 100644 index 34f11c01f..000000000 --- a/lib_com/ivas_prot.h +++ /dev/null @@ -1,4065 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -#ifndef IVAS_PROT_H -#define IVAS_PROT_H - -#include -#include "options.h" -#include -#include "typedef.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "stat_com.h" -#include "ivas_stat_enc.h" -#include "ivas_stat_dec.h" -#include "ivas_stat_com.h" -#include "ivas_error_utils.h" - - -/* clang-format off */ - -/*----------------------------------------------------------------------------------* - * General IVAS prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_enc( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - const int16_t *data, /* i : input signal */ - const int16_t n_samples /* i : number of input samples */ -); - -void stereo_dmx_evs_enc( - STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS, /* i/o: Stereo downmix for EVS encoder handle */ - const int32_t input_Fs, /* i : input sampling rate */ - int16_t data[CPE_CHANNELS * L_FRAME48k], /* i/o: input signal */ - const int16_t n_samples, /* i : number of input samples */ - const bool is_binaural /* i : indication that input is binaural audio */ -); - -/*! r: number of channels to be analysed */ - -void copy_encoder_config_ivas_fx( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - Encoder_State *st, /* o : encoder state structure */ - const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ -); - - - -ivas_error create_sce_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - const int32_t element_brate /* i : element bitrate */ -); - -ivas_error create_cpe_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t cpe_id, /* i : CPE # identifier */ - const int32_t element_brate /* i : element bitrate */ -); - -ivas_error create_mct_enc_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void destroy_cpe_enc( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ -); - -void ivas_mct_enc_close_fx( - MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ -); - -ivas_error ivas_corecoder_enc_reconfig( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t nSCE_old, /* i : number of SCEs in previous frame */ - const int16_t nCPE_old, /* i : number of CPEs in previous frame */ - const int16_t nchan_transport_old, /* i : number of TCs in previous frame */ - const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */ - const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */ - const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */ -); - -ivas_error ivas_sce_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - const float data_f[], /* i : input signal for single channel */ - const int16_t input_frame, /* i : input frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - - -ivas_error ivas_cpe_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const Word16 cpe_id, /* i : CPE # identifier */ - float data_f_ch0[], /* i : input signal for channel 0 */ - float data_f_ch1[], /* i : input signal for channel 1 */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word16 nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error ivas_mct_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data[MCT_MAX_CHANNELS], /* i : input signal buffers */ - const int16_t input_frame, /* i : input frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error pre_proc_front_ivas( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int32_t element_brate, /* i : SCE/CPE element bitrate */ - const int16_t nb_bits_metadata, /* i : number of metadata bits */ - const int16_t input_frame, /* i : frame length */ - const int16_t n, /* i : channel number */ - float old_inp_12k8[], /* o : buffer of old input signal */ - float old_inp_16k[], /* o : buffer of old input signal @16kHz */ - float *ener, /* o : residual energy from Levinson-Durbin */ - float *relE, /* o : frame relative energy */ - float A[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes */ - float epsP[M + 1], /* o : LP prediction errors */ - float lsp_new[M], /* o : LSPs at the end of the frame */ - float lsp_mid[M], /* o : LSPs in the middle of the frame */ - int16_t *vad_hover_flag, /* o : VAD hangover flag */ - int16_t *attack_flag, /* o : flag signaling attack */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - float old_wsp[], /* o : weighted input signal buffer */ - float pitch_fr[NB_SUBFR], /* o : fractional pitch values */ - float voicing_fr[NB_SUBFR], /* o : fractional pitch gains */ - int16_t *loc_harm, /* o : harmonicity flag */ - float *cor_map_sum, /* o : speech/music clasif. parameter */ - int16_t *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO */ - float enerBuffer[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer */ - float fft_buff[2 * L_FFT], /* o : FFT buffer */ - const float tdm_A_PCh[M + 1], /* i : unq. LP coeff. of primary channel */ - const float tdm_lsp_new_PCh[M], /* i : unq. LSPs of primary channel */ - const float currFlatness, /* i : flatness parameter */ - const int16_t tdm_ratio_idx, /* i : Current Ratio_L index */ - float fr_bands_LR[][2 * NB_BANDS], /* i : energy in frequency bands */ - const float Etot_LR[], /* i : total energy Left & Right channel */ - float lf_E_LR[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ - const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels */ - float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ - const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ - const int16_t force_front_vad, /* i : flag to force VAD decision */ - const int16_t front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int32_t ivas_total_brate /* i : IVAS total bitrate */ -); - -ivas_error pre_proc_front_ivas_fx( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 element_brate, /* i : SCE/CPE element bitrate Q0*/ - const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ - const Word16 input_frame, /* i : frame length Q0*/ - const Word16 n, /* i : channel number Q0*/ - Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1*/ - Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1*/ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ - Word16 *relE_fx, /* o : frame relative energy Q8*/ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes Q12*/ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes Q12*/ - Word32 epsP_fx[M + 1], /* o : LP prediction errors epsP_fx_q*/ - Word16 *epsP_fx_q, - Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15*/ - Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15*/ - Word16 *vad_hover_flag, /* o : VAD hangover flag Q0*/ - Word16 *attack_flag, /* o : flag signaling attack Q0*/ - Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf)*/ - Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf)*/ - Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ - Word16 old_wsp_fx[], /* o : weighted input signal buffer q_old_wsp*/ - Word16 *q_old_wsp, - Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6*/ - Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15*/ - Word16 *loc_harm, /* o : harmonicity flag Q0*/ - Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8*/ - Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO Q0*/ - Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ - Word16 *enerBuffer_fx_exp, /* o : energy buffer */ - Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer fft_buff_fx_q*/ - Word16 *fft_buff_fx_q, /* o : FFT buffer */ - const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ - const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ - const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ - const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ - Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ - Word16 fr_bands_LR_fx_q[CPE_CHANNELS], - const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ - Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q)*/ - Word16 lf_E_LR_fx_q, - const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ - Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ - Word16 band_energies_LR_fx_q, - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ - const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ - const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ - const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING - const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif - const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ - Word16 *Q_new -#ifdef DEBUG_MODE_INFO - , - const Word16 ch_idx -#endif -); -ivas_error pre_proc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 last_element_mode, /* i : last element mode Q0*/ - const Word32 element_brate, /* i : element bitrate Q0*/ - const Word32 last_element_brate, /* i : last element bitrate Q0*/ - const Word16 input_frame, /* i : frame length Q0*/ - Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal Q_new-1 */ - Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz Q_new-1 */ - Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame Q_new*/ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes Q12*/ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes Q14*/ - Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q*/ - Word16 *epsP_fx_q, /* i : LP prediction errors */ - Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame Q15*/ - Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ - Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE Q_new-1*/ - Word16 *Voicing_flag, /* o : voicing flag for HQ FEC Q0*/ - Word16 old_wsp_fx[], /* i : weighted input signal buffer e_old_wsp*/ - Word16 e_old_wsp, - const Word16 loc_harm, /* i : harmonicity flag Q0*/ - const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO Q0*/ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ - const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ - Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* e_enerBuffer */ - Word16 e_enerBuffer, - Word16 fft_buff_fx[2 * L_FFT], /* Qx */ - Word16 cor_map_sum_fx, /* Q8 */ - Word16 *Q_new -); -/*! r: number of clipped samples */ -void ivas_initialize_handles_enc_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_init_encoder( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void ivas_destroy_enc_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_initialize_MD_bstr_enc_fx( - BSTR_ENC_HANDLE *hBstr, /* o : encoder MD bitstream handle */ - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void ivas_destroy_MD_bstr_enc_fx( - BSTR_ENC_HANDLE *hMetaData /* i/o: encoder MD bitstream handle */ -); - -ivas_error ivas_init_decoder_front( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_init_decoder( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_output_buff_dec( - float *p_output_f[], /* i/o: output audio buffers */ - const int16_t nchan_out_buff_old, /* i : previous frame number of output channels*/ - const int16_t nchan_out_buff /* i : number of output channels */ -); -#endif - -ivas_error stereo_dmx_evs_init_encoder( - STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS, /* o : Stereo downmix for EVS encoder handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void stereo_dmx_evs_close_encoder( - STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle */ -); - -ivas_error ivas_dec( - Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ - int16_t *data /* o : output synthesis signal */ -); - - -ivas_error mct_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t b_nchan_change /* i : flag indicating different channel count */ -); - - -void ivas_mct_dec_close( - MCT_DEC_HANDLE *hMCT /* i/o: MCT decoder structure */ -); - -ivas_error ivas_corecoder_dec_reconfig( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nSCE_old, /* i : number of SCEs in previous frame */ - int16_t nCPE_old, /* i : number of CPEs in previous frame */ - const int16_t nchan_transport_old, /* i : number of TCs in previous frame */ - const int16_t sba_dirac_stereo_flag_old, /* i : signal stereo rendering using DFT upmix in previous frame */ - const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */ - const int32_t brate_CPE /* i : bitrate to be set for the CPEs */ -); - -ivas_error ivas_hp20_dec_reconfig( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nchan_hp20_old /* i : number of HP20 filters in previous frame*/ -); - -ivas_error ivas_sce_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - float *output[1], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error ivas_cpe_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t cpe_id, /* i : CPE # identifier */ - float *output[CPE_CHANNELS], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error ivas_mct_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -/*! r: number of channels to be synthesised */ - -void copy_decoder_config( - Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ - Decoder_State *st /* o : decoder state structure */ -); - -void destroy_core_dec( - DEC_CORE_HANDLE hCoreCoder /* i/o: core decoder structure */ -); - - -void ivas_initialize_handles_dec( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_core_enc_fx( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const Word16 n_CoreChannels, /* i : number of core channels to be coded Q0*/ - Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal Q_new-1*/ - Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal Q_new-1*/ - Word16 Q_new[], - Word32 ener_fx[], /* i : residual energy from Levinson-Durbin epsP_fx_q*/ - Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ - Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes Q12*/ - Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q*/ - Word16 epsP_fx_q[], /* i : LP prediction errors */ - Word16 lsp_new_fx[][M], /* i : LSPs at the end of the frame Q15*/ - Word16 lsp_mid_fx[][M], /* i : LSPs in the middle of the frame Q15*/ - const Word16 vad_hover_flag[], /* i : VAD hanglover flag Q0*/ - Word16 attack_flag[], /* i : attack flag (GSC or TC) Q0*/ - Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer q_re_im_buf*/ - Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer q_re_im_buf*/ - Word16 *q_re_im_buf, - Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer e_old_wsp*/ - Word16 e_old_wsp[], - const Word16 loc_harm[], /* i : harmonicity flag Q0*/ - const Word16 cor_map_sum_fx[], /* i : speech/music clasif. parameter Q8*/ - const Word16 vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO Q0*/ - Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ - Word16 enerBuffer_fx_exp[], /* o : energy buffer */ - Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer Qx*/ - const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag Q0*/ - const Word16 ivas_format, /* i : IVAS format Q0*/ - const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ -); - - - -void decod_gen_2sbfr( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const float *Aq, /* i : LP filter coefficient */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : pitch values for primary channel */ -); - -void synchro_synthesis( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output synthesis signal */ - const int16_t output_frame, /* i : Number of samples */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void synchro_synthesis_fixed( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output synthesis signal */ - const int16_t output_frame, /* i : Number of samples */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void stereo_tcx_init_enc( - Encoder_State *st /* i/o: encoder state structure */ -); - - - - -void stereo_tcx_init_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t last_element_mode /* i : element mode of previous frame */ -); - -/*! r: S/M decision (0 = speech or noise, 1 = unclear, 2 = music) */ -int16_t ivas_smc_gmm( - Encoder_State *st, /* i/o: encoder state structure */ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const float Etot, /* i : total frame energy */ - const float lsp_new[M], /* i : LSPs in current frame */ - const float cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.) */ - const float epsP[M + 1], /* i : LP prediciton error */ - const float PS[], /* i : energy spectrum */ - const float non_sta, /* i : unbound non-stationarity */ - const float relE, /* i : relative frame energy */ - int16_t *high_lpn_flag, /* i/o: sp/mus LPN flag */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); - -void ivas_smc_mode_selection( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t element_brate, /* i : element bitrate */ - int16_t smc_dec, /* i : raw decision of the 1st stage classifier */ - const float relE, /* i : relative frame energy */ - const float Etot, /* i : total frame energy */ - int16_t *attack_flag, /* i/o: attack flag (GSC or TC) */ - const float *inp, /* i : input signal */ - const float S_map[], /* i : short-term correlation map */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); - -/*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ -int16_t ivas_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - const float *inp, /* i : new input signal */ - const float *wsp, /* i : input weighted signal */ - const float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - const float *pitch_fr, /* i : fraction pitch values */ - const float *voicing_fr, /* i : fractional voicing values */ - const float currFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac, /* i : LP filter stability */ - float *res_cod_SNR_M, - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ -); - - - -void ivas_decision_matrix_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *sharpFlag, /* o : formant sharpening flag */ - int16_t *core_switching_flag, /* o : ACELP->HQ switching frame flag */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t nchan_out /* i : Number of output channels */ -); - -void set_bw_stereo( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structures */ -); - -/*! r: flag indicating whether the coded BW has changed */ -int16_t set_bw_mct( - CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE encoder structures */ - const int16_t nCPE /* i : number of CPEs */ -); -void dec_acelp_fast( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t cdk_index, /* i : codebook index */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void set_transient_stereo( - CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - float currFlatness[] /* i/o: current flatness */ -); - -/*! r: preliminary flag to force ACELP */ -int16_t transient_analysis( - TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ - const float cor_map_LT[], /* i : LT correlation map */ - const float multi_harm_limit /* i : multi harminic threshold */ -); - -void ivas_post_proc( - SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int16_t n, /* i : channel number */ - float synth[], /* i/o: output synthesis signal */ - float *output[CPE_CHANNELS], /* i/o: output synthesis signal */ - const int16_t output_frame, /* i : output frame length */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void ivas_renderer_select( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_mc_enc_config_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_mc_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t idx, /* i : LS config. index */ - uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ - int16_t *data /* o : output synthesis signal */ -); - -/*! r: MC format mode (MCT, McMASA, ParamMC) */ -MC_MODE ivas_mc_mode_select( - const MC_LS_SETUP mc_ls_setup, /* i : MC loudspeaker setup */ - const int32_t total_brate /* i : IVAS total bitrate */ -); - -/*! r: number of loudspeaker channels */ -int16_t ivas_mc_ls_setup_get_num_channels( - const MC_LS_SETUP mc_ls_setup /* i : loudspeaker setup (CICP) */ -); - -/*! r: output configuration*/ -AUDIO_CONFIG ivas_mc_map_ls_setup_to_output_config( - const MC_LS_SETUP mc_ls_setup /* i : multi channel loudspeaker setup */ -); - -/*! r: multi channel loudspeaker setup */ -MC_LS_SETUP ivas_mc_map_output_config_to_mc_ls_setup( - const AUDIO_CONFIG output_config /* i : output audio configuration */ -); - -void smooth_dft2td_transition( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: synthesis @external Fs */ - const int16_t output_frame /* i : output frame length */ -); - - -/*! r: flag indicating a valid bitrate */ -Word16 is_IVAS_bitrate_fx( - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -int16_t is_DTXrate( - const int32_t ivas_total_brate /* i : IVAS total bitrate */ -); - - -void TonalMdctConceal_create_concealment_noise_ivas( - float concealment_noise[L_FRAME48k], - CPE_DEC_HANDLE hCPE, - const int16_t L_frameTCX, - const int16_t L_frame, - const int16_t idchan, - const int16_t subframe_idx, - const int16_t core, - const float crossfade_gain, - const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode -); - -void TonalMdctConceal_whiten_noise_shape_ivas( - Decoder_State *st, - const int16_t L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE -); - -void dtx_read_padding_bits( - DEC_CORE_HANDLE st, - const int16_t num_bits -); - - - -/*----------------------------------------------------------------------------------* - * JBM prototypes - *----------------------------------------------------------------------------------*/ - - - -ivas_error ivas_jbm_dec_flush_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t tc_granularity_new, /* i : new renderer granularity */ - const RENDERER_TYPE renderer_type_old, /* i : old renderer type */ - const AUDIO_CONFIG intern_config_old, /* i : old internal config */ - const IVAS_OUTPUT_SETUP_HANDLE hIntSetupOld, /* i : old internal output setup */ - const MC_MODE mc_mode_old, /* i : old MC mode */ - const ISM_MODE ism_mode_old, /* i : old ISM mode */ - uint16_t *nSamplesRendered, /* o : number of samples flushed */ - int16_t *data /* o : output synthesis signal */ -); - -void ivas_jbm_dec_feed_tc_to_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nSamplesForRendering, /* i : number of TC samples available for rendering */ - int16_t *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/ - float *data /* i/o: transport channels/output synthesis signal */ -); - -ivas_error ivas_jbm_dec_set_discard_samples( - Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ -); - -void ivas_jbm_dec_get_adapted_linear_interpolator( - const int16_t default_interp_length, /* i : default length of the (full-frame) interpolator */ - const int16_t interp_length, /* i : length of the interpolator to be created */ - float *interpolator /* o : the interpolator */ -); - - - -int16_t ivas_jbm_dec_get_num_tc_channels( - Decoder_Struct *st_ivas /* i : IVAS decoder handle */ -); - -void ivas_jbm_dec_copy_tc_no_tsm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *tc[], /* i : transport channels */ - const int16_t output_frame /* i : output frame size */ -); - - -TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( - Decoder_Struct *st_ivas /* i : IVAS decoder handle */ -); - -/*! r: render granularity */ -int16_t ivas_jbm_dec_get_render_granularity_flt( - const RENDERER_TYPE rendererType, /* i : renderer type */ - const IVAS_FORMAT ivas_format, /* i : ivas format */ - const MC_MODE mc_mode, /* i : MC mode */ - const int32_t output_Fs /* i : sampling rate */ -); - -ivas_error ivas_jbm_dec_tc_buffer_open( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */ - const int16_t nchan_transport_jbm, /* i : number of real transport channels */ - const int16_t nchan_transport_internal, /* i : number of totally buffered channels */ - const int16_t nchan_full, /* i : number of channels to fully store */ - const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ -); - -ivas_error ivas_jbm_dec_tc_buffer_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */ - const int16_t nchan_transport_jbm, /* i : new number of real transport channels */ - const int16_t nchan_transport_internal, /* i : new number of totally buffered channels */ - const int16_t nchan_full, /* i : new number of channels to fully store */ - const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */ -); - -void ivas_jbm_dec_tc_buffer_close( - DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ -); - -void ivas_jbm_dec_td_renderers_adapt_subframes( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_jbm_dec_metadata_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_jbm_masa_sf_to_sf_map( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -/*----------------------------------------------------------------------------------* - * ISM prototypes - *----------------------------------------------------------------------------------*/ - -void bitbudget_to_brate( - const Word16 x[], /* i : bitbudgets Q0 */ - Word32 y[], /* o : bitrates Q0 */ - const Word16 N /* i : number of entries to be converted */ -); - -void ivas_ism_reset_metadata( - ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ -); - -void ivas_ism_reset_metadata_enc( - ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ -); -void ivas_ism_reset_metadata_API( - ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ -); - -/*! r: index of the winning codeword */ -Word16 ism_quant_meta_fx( - const Word32 val, /* i : scalar value to quantize Q22 */ - Word32 *valQ, /* o : quantized value Q22 */ - const Word32 borders_fx[], /* i : level borders Q22 */ - const Word32 q_step_fx, /* i : quantization step Q22 */ - const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */ - const Word16 cbsize /* i : codebook size */ -); - -ivas_error ivas_ism_metadata_enc_create_fx( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t n_ISms, /* i : number of objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ -); - -ivas_error ivas_ism_metadata_dec_create( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t n_ISms, /* i : number of objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ -); - -ivas_error ivas_ism_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data[], /* i : input signal [channels][samples] */ - const int16_t input_frame, /* i : input frame length per channel */ - int16_t *nb_bits_metadata, /* i : number of metadata bits */ - const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ -); - -ivas_error ivas_ism_metadata_dec( - const int32_t ism_total_brate, /* i : ISM total bitrate */ - const int16_t nchan_ism, /* i : number of ISM channels */ - int16_t *nchan_transport, /* o : number of transport channels */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ - const int16_t bfi, /* i : bfi flag */ - int16_t nb_bits_metadata[], /* o : number of metadata bits */ - ISM_MODE ism_mode, /* i : ISM mode */ - ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ - const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ - int16_t *ism_extended_metadata_flag, /* i/o: Extended metadata active in renderer */ - int16_t *ism_extmeta_cnt, /* i/o: Number of change frames observed */ - DEC_CORE_HANDLE st0 /* i : core-coder handle */ -); - - -/*----------------------------------------------------------------------------------* - * Parametric ISM prototypes - *----------------------------------------------------------------------------------*/ - -/*! r: ISM format mode */ - -ivas_error ivas_param_ism_enc_open_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void ivas_param_ism_enc_close_fx( - PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ - const int32_t input_Fs /* i : input sampling_rate */ -); - -void ivas_ism_metadata_close( - ISM_METADATA_HANDLE hIsmMetaData[], /* i/o : object metadata handles */ - const int16_t first_idx /* i : index of first handle to deallocate */ -); - - -ivas_error ivas_ism_enc_config( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - - - - -void ivas_param_ism_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ -); - -void ivas_ism_dec_digest_tc( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - - -void ivas_param_ism_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_param_ism_params_to_masa_param_mapping( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -/*----------------------------------------------------------------------------------* - * ISM DTX prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ism_dtx_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -/*! r: indication of DTX frame */ -int16_t ivas_ism_dtx_enc( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t nchan_transport, /* i : number of transport channels */ - int16_t vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - int16_t md_diff_flag[], /* o : metadata differential flag */ - int16_t *sid_flag /* o : indication of SID frame */ -); - -void ivas_ism_dtx_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t *nb_bits_metadata /* o : number of metadata bits */ -); - -void ivas_ism_metadata_sid_enc_fx( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - const int16_t flag_noisy_speech, /* i : noisy speech flag */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t nchan_transport, /* i : number of transport channels */ - const ISM_MODE ism_mode, /* i : ISM mode */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - const int16_t sid_flag, /* i : indication of SID frame */ - const int16_t md_diff_flag[], /* i : metadata differental flag */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t nb_bits_metadata[] /* o : number of metadata bits */ -); - -void ivas_ism_metadata_sid_dec( - SCE_DEC_HANDLE hSCE[MAX_SCE], /* i/o: SCE decoder structure */ - const int32_t ism_total_brate, /* i : ISM total bitrate */ - const int16_t bfi, /* i : bfi flag */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t nchan_transport, /* i : number of transport channels */ - const ISM_MODE ism_mode, /* i : ISM mode */ - int16_t *flag_noisy_speech, /* o : noisy speech flag */ - int16_t *sce_id_dtx, /* o : SCE DTX ID */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - int16_t nb_bits_metadata[] /* o : number of metadata bits */ -); - - -void ivas_param_ism_compute_noisy_speech_flag_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - - -void update_last_metadata( - const int16_t nchan_ism, /* i : number of objects */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - const int16_t updt_flag[] /* i : last metadata update flag */ -); - -void ivas_ism_dtx_limit_noise_energy_for_near_silence( - SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder structures */ - const int16_t sce_id_dtx, /* i : SCE DTX ID */ - const int16_t nchan_transport /* i : number of transport channels */ -); - -/*----------------------------------------------------------------------------------* - * DFT Stereo prototypes - *----------------------------------------------------------------------------------*/ - - -void stereo_dft_enc_analyze( - Encoder_State **sts, /* i/o: encoder state structure */ - const int16_t n_channels, /* i : number of input channels */ - const int16_t input_frame, /* i : input frame length */ - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: encoder MDCT stereo handle */ - float DFT[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC], /* o : DFT buffers */ - float *input_mem[CPE_CHANNELS] /* i/o: input buffer memory */ -); - -float stereo_dft_enc_synthesize( - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ - float *output, /* o : output synthesis */ - const int16_t chan, /* i : channel number */ - const int32_t input_Fs, /* i : input sampling rate */ - const int32_t output_sampling_rate, /* i : output sampling rate */ - const int16_t L_frame /* i : frame length at internal Fs */ -); - - - - -void stereo_dtf_cng( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */ - const int16_t output_frame /* i : output frame size */ -); - -void stereo_dft_cng_side_gain( - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo encoder handle */ - STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ - const int32_t core_brate, /* i : core bitrate */ - const int32_t last_core_brate, /* i : last core bitrate */ - const int16_t bwidth /* i : audio band-width */ -); - - -void stereo_dft_dequantize_itd( - int16_t *ind, - float *out, - const int32_t output_Fs -); - - - -void stereo_dft_dec_sid_coh( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nbands, /* i : number of DFT stereo bands */ - float *coh, /* i/o: coherence */ - int16_t *nb_bits /* i/o: number of bits read */ -); - -ivas_error stereo_dft_dec_create( - STEREO_DFT_DEC_DATA_HANDLE *hStereoDft, /* i/o: decoder DFT stereo handle */ - const int32_t element_brate, /* i : element bitrate */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const int16_t nchan_transport /* i : number of transport channels */ -); - -void stereo_dft_dec_reset( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i/o: decoder DFT stereo handle */ -); - -void stereo_dft_dec_update( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int16_t output_frame, /* i : output frame length */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void stereo_dft_dec_destroy( - STEREO_DFT_DEC_DATA_HANDLE *hStereoDft /* i/o: decoder DFT stereo handle */ -); - -void stereo_dft_dec_analyze( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const float *input, /* i : input signal */ - float out_DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ - const int16_t chan, /* i : channel number */ - const int16_t input_frame, /* i : input frame size */ - const int16_t output_frame, /* i : output frame size */ - const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : signal type to analyze */ - const int16_t k_offset, /* i : offset of DFT */ - const int16_t delay /* i : delay in samples for input signal */ -); - -void stereo_dft_dec_synthesize( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i : DFT buffers */ - const int16_t chan, /* i : channel number */ - float output[L_FRAME48k], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length */ -); - - -void stereo_dft_res_ecu( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: Decoder DFT stereo handle */ - float *pDFT_RES, /* i/o: residual signal */ - float *const DFT_PRED_RES, /* i/o: residual prediction signal */ - const int16_t k, /* i : Subframe index */ - const int16_t output_frame, /* i : Output frame length */ - const int16_t prev_bfi, /* i : Previous BFI */ - const float dmx_nrg, /* i : Down-mix energy */ - int16_t *num_plocs, /* i/o: Number of peak locations */ - int16_t *plocs, /* i/o: Peak locations (bin) */ - float *plocsi, /* i/o: Peak locations (fractional) */ - float *input_mem /* o : Residual DFT buffer input mem */ -); - -void stereo_dft_res_subst_spec( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: Decoder DFT stereo handle */ - float *pDFT_RES, /* i/o: residual signal */ - const float *const DFT_PRED_RES, /* i : residual prediction signal */ - const int16_t time_offs, /* i : Time offset for phase adjustm. */ - const int16_t L_res, /* i : bandwidth of residual signal */ - const int16_t L_ana, /* i : Length of FFT analysis */ - const int16_t k, /* i : Subframe index */ - int16_t *num_plocs, /* i/o: Number of peak locations */ - int16_t *plocs, /* i/o: Peak locations (bin) */ - float *plocsi, /* i/o: Peak locations (fractional) */ - const int16_t analysis_flag /* i : Flag for running peak analysis */ -); - -void stereo_dft_res_ecu_burst_att( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: Decoder DFT stereo handle */ - float *pDFT_RES, /* i/o: residual signal /att. residual */ - const float dmx_nrg, /* i : dmx energy of current frame */ - const int16_t L_res, /* i : Bandwidth of residual */ - const int16_t L_ana /* i : Length of FFT analysis */ -); - -/*! r: total energy of downmix with maximum swb bandwidth max */ -float stereo_dft_dmx_swb_nrg( - const float *dmx_k0, /* i : first subframe spectrum */ - const float *dmx_k1, /* i : second subframe spectrum */ - const int16_t frame_length /* i : frame lanegth */ -); - -int16_t stereo_dft_sg_recovery( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i/o: Decoder DFT stereo handle */ -); - -void stereo_dft_dec_res( - CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ - float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ - float *output /* o : output frame */ -); - -/*! r: Decision to enable or disable BPF on DFT stereo residual */ - -void bpf_pitch_coherence( - Decoder_State *st, /* i/o: decoder state structure */ - const float pitch_buf[] /* i : pitch for each subframe [0,1,2,3] */ -); - -void stereo_dft_dec_read_BS( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int32_t element_brate, /* i : element bitrate */ - int32_t *total_brate, /* o : total bitrate */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int16_t bwidth, /* i : bandwidth */ - const int16_t output_frame, /* i : output frame length */ - float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ - int16_t *nb_bits, /* o : number of bits read */ - float *coh, /* i/o: Coherence */ - const int16_t ivas_format /* i : ivas format */ -); - -void stereo_dft_dec_smooth_parameters( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int16_t prev_sid_nodata, /* i : Previous SID/No data indicator */ - const int16_t active_frame_counter, /* i : Active frame counter */ - const int32_t element_brate /* i : Element bitrate */ -); - -void stereo_dft_generate_res_pred( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const float samp_ratio, /* i : sampling ratio */ - float *pDFT_DMX, /* i : downmix signal */ - float *DFT_PRED_RES, /* o : residual prediction signal */ - float *pPredGain, /* i : residual prediction gains */ - const int16_t k, /* i : subframe index */ - float *ap_filt_DMX, /* i : enhanced stereo filling signal */ - int16_t *stop, /* o : last FD stereo filling bin */ - const int16_t bfi /* i : BFI flag */ -); - -void stereo_dft_dec_core_switching( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float output[], /* i/o: synthesis @internal Fs */ - float synth[], /* i : synthesis @output Fs */ - float hb_synth[], /* i/o: hb synthesis */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ - const int16_t output_frame, /* i : output frame length */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t sba_dirac_stereo_dtx_flag /* i : DTX indicator for SBA DirAC stereo */ -); - -void init_basic_allpass( - basic_allpass_t *ap, /* i/o: basic allpass structure */ - const float *gains, /* i : allpass filter gains */ - const int16_t *delays /* i : allpass filter delays */ -); - -void filter_with_allpass( - const float *sig, /* i : allpass input signal */ - float *out, /* o : filtered output */ - const int16_t len, /* i : length of input */ - basic_allpass_t *ap /* i/o: basic allpass structure */ -); - -/*! r: used GR order */ - -/*! r: used GR order */ - - -/*! r: number of bits written */ - -/*! r: number of bits written */ - - -void stereo_dft_enc_compute_itd( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - float *DFT_L, - float *DFT_R, - const int16_t k_offset, - const int16_t input_frame, - const int16_t vad_flag_dtx[], - const int16_t vad_hover_flag[], - float *bin_nrgL, - float *bin_nrgR -); - -void stereo_dft_config( - STEREO_DFT_CONFIG_DATA_HANDLE hConfig, /* o : DFT stereo configuration */ - const int32_t brate, /* i : IVAS/CPE/nominal total bitrate */ - int16_t *bits_frame_nominal, /* o : primary channel nominal bits per frame */ - int16_t *bits_frame_nominal_2 /* o : secondary channel nominal bits per frame*/ -); - -int16_t stereo_dft_band_config( - int16_t *band_limits, /* o : DFT band limits */ - const int16_t band_res, /* i : DFT band resolution */ - const int16_t NFFT, /* i : analysis/synthesis window length */ - const int16_t enc_dec /* i : flag to indicate enc vs dec */ -); - -void stereo_dft_dmx_out_reset( - STEREO_DFT_DMX_DATA_HANDLE hStereoDftDmx /* i/o: DFT stereo DMX decoder */ -); - -void stereo_dft_unify_dmx( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */ - Decoder_State *st0, /* i/o: decoder state structure */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */ - float *input_mem, /* i/o: mem of buffer DFT analysis */ - const int16_t prev_sid_nodata /* i : Previous SID/No data indicator */ -); - -void add_HB_to_mono_dmx( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float output[L_FRAME48k], /* i/o: output synthesis */ - float outputHB[L_FRAME48k], /* i : HB synthesis */ - const int16_t last_core, /* i : last core, primary channel */ - const int16_t output_frame /* i : frame length */ -); - -/*----------------------------------------------------------------------------------* - * Range Coder prototypes - *----------------------------------------------------------------------------------*/ - -void rc_uni_dec_init( - RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ - uint16_t *bit_buffer, /* i : Bit buffer */ - const int16_t max_available_bits /* i : Total maximum bits available */ -); - -/*! r: Read symbol */ -uint16_t rc_uni_dec_read_symbol_fastS( - RangeUniDecState *rc_st_dec, /* i/o: Decoder State */ - const uint16_t cum_freq_table[], /* i : Cumulative frequency up to symbol */ - const uint16_t sym_freq_table[], /* i : Symbol frequency */ - const uint16_t alphabet_size, /* i : Number of symbols in the alphabet */ - const uint16_t tot_shift /* i : Total frequency as a power of 2 */ -); - -/*! r: Read bit */ -uint16_t rc_uni_dec_read_bit( - RangeUniDecState *rc_st_dec /* i/o: RC state handle */ -); - -/*! r: Read bit */ -uint16_t rc_uni_dec_read_bit_prob_fast( - RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ - const int16_t freq0, /* i : Frequency for symbol 0 */ - const uint16_t tot_shift /* i : Total frequency as a power of 2 */ -); - -/*! r: Read bits */ -uint16_t rc_uni_dec_read_bits( - RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ - const int16_t bits /* i : Number of bits */ -); - -/*! r: Total number of bits consumed */ -int16_t rc_uni_dec_virtual_finish( - RangeUniDecState *rc_st_dec /* i/o: RC state handle */ -); - -/*! r: Total number of bits consumed */ -int16_t rc_uni_dec_finish( - RangeUniDecState *rc_st_dec /* i/o: RC state handle */ -); - - -/*----------------------------------------------------------------------------------* - * ECLVQ Stereo prototypes - *----------------------------------------------------------------------------------*/ - -float ECSQ_dequantize_gain( - const int16_t index -); - - - -void ECSQ_init_instance( - ECSQ_instance *ecsq_inst, - const int16_t config_index, - void *ac_handle -); - - - -void ECSQ_dequantize_vector( - const int16_t *input, - const float global_gain, - const int16_t N, - float *output -); - - -/*----------------------------------------------------------------------------------* - * ICA Stereo prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_tca_init_enc( - STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle */ - const int32_t input_Fs /* i : input sampling frequency */ -); - -void stereo_tca_enc( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const int16_t input_frame /* i : length of a frame per channel */ -); - -void stereo_tca_init_dec( - STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle */ -); - -void stereo_tca_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *synth[CPE_CHANNELS], /* i/o: output synth */ - const int16_t output_frame /* i : length of a frame per channel */ -); - -void stereo_tca_scale_R_channel( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output, /* i/o: output synthesis, R channel */ - const int16_t output_frame /* i : frame length */ -); - -void adjustTargetSignal( - float *target, - const int16_t prevShift, - const int16_t currShift, - const int16_t L_shift_adapt, - const int16_t method -); - -/*----------------------------------------------------------------------------------* - * IC-BWE Stereo prototypes - *----------------------------------------------------------------------------------*/ - - -void stereo_icBWE_preproc( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int16_t input_frame, /* i : input frame length */ - float shb_speech_nonref[] /* o : SHB speech non-ref channel */ -); - -void stereo_icBWE_enc( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const float shb_speech_ref[], /* i : SHB speech ref channel */ - float shb_speech_nonref[], /* i/o: SHB speech non-ref channel */ - const float *voice_factors /* i : voicing factors */ -); - -void stereo_icBWE_init_dec( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ -); - -void stereo_icBWE_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *synthRef, /* i/o: Reference channel HB synthesis at output Fs */ - float *synth, /* o : Non reference channel HB synthesis at output Fs */ - const float *fb_synth_ref, /* i : ref. high-band synthesis 16-20 kHz */ - const float *voice_factors, /* i : voicing factors */ - const int16_t output_frame /* i : frame length */ -); - -void stereo_icBWE_decproc( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output symthesis */ - float outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ - const int16_t last_core, /* i : last core, primary channel */ - const int16_t last_bwidth, /* i : last bandwidth */ - const int16_t output_frame /* i : frame length */ -); - - -/*----------------------------------------------------------------------------------* - * Stereo classifiers prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_classifier_features( - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t vad_flag, /* i : VAD flag */ - const float lsf_new[], /* i : LSFs at the end of the frame */ - const float epsP[], /* i : LP analysis residual energies for each iteration*/ - const int16_t pitch[], /* i : open-loop pitch values for quantiz. */ - const float voicing[], /* i : OL maximum normalized correlation */ - const float cor_map_sum, /* i : speech/music clasif. parameter */ - const float non_staX, /* i : unbound non-stationarity for sp/mu clas. */ - const float sp_div, /* i : spectral diversity feature */ - const int16_t clas /* i : signal class */ -); - - -void xtalk_classifier_dft( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int16_t itd, /* i : ITD from DFT stereo - used as a feature */ - const float gcc_phat[] /* i : GPHAT cross-channel correlation function */ -); - -/*----------------------------------------------------------------------------------* - * TD Stereo prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_td_init_enc( - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const int16_t last_element_mode /* i : last element mode */ -); - - - -void stereo_tdm_downmix( - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i : TD stereo IVAS encoder structure */ - float *Left_in, /* i/o: Left channel -> Primary channel */ - float *Right_in, /* i/o: Right channel -> Secondary channel */ - const int16_t input_frame, /* i : Number of samples */ - const int16_t tdm_ratio_idx, /* i : TDM ratio index */ - const int16_t tdm_SM_flag, /* i : channel combination scheme flag */ - const int16_t tdm_ratio_idx_SM /* i : TDM ratio index for SM mode */ -); - -void stereo_td_init_dec( - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const int16_t last_element_mode /* i : last element mode */ -); - -void tdm_configure_dec( - const int16_t ivas_format, /* i : IVAS format */ - const int16_t ism_mode, /* i : ISM mode in combined format */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t *tdm_ratio_idx, /* o : ratio index */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -void tdm_upmix_plain( - float Left[], /* o : left channel */ - float Right[], /* o : right channel */ - const float PCh_2_L[], /* i : primary channel */ - const float SCh_2_R[], /* i : secondary channel */ - const float LR_ratio, /* i : mixing ratio */ - const float inv_den_LR_ratio, /* i : inverse mixing ration */ - const int16_t start_index, /* i : start index */ - const int16_t end_index, /* i : end index */ - const int16_t plus_minus_flag /* i : plus/minus flag */ -); - -void stereo_tdm_combine( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *PCh_2_L, /* i/o: Primary channel -> output as L channel */ - float *SCh_2_R, /* i/o: Seconday channel -> output as R channel */ - const int16_t output_frame, /* i : Number of samples */ - const int16_t flag_HB, /* i : flag to distinguish between core (0) and HB (1) synthesis */ - const int16_t tdm_ratio_idx /* i : TDM ratio index */ -); - -/*! r: replication decision; 1 = Use old LP */ -void tdm_ol_pitch_comparison( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - float pitch_fr[CPE_CHANNELS][NB_SUBFR], /* i/o: fractional pitch values */ - float voicing_fr[CPE_CHANNELS][NB_SUBFR] /* i/o: fractional pitch gains */ -); - -void tdm_configure_enc( - const int16_t ivas_format, /* i : IVAS format */ - const int16_t ism_mode, /* i : ISM mode in combined format */ - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const float Etot_last[CPE_CHANNELS], /* i/o: Energy of last frame */ - const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */ - const int16_t tdm_ratio_idx, /* i : ratio index */ - const int16_t tdm_ratio_idx_SM, /* i : ratio index in SM mode */ - const int16_t attack_flag, /* i : Primary channel attack flag */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - - -void tdm_bit_alloc( - const int16_t ivas_format, /* i : IVAS format */ - const int16_t ism_mode, /* i : ISM mode in combined format */ - const int32_t element_brate_wo_meta, /* i : element bitrate without metadata */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reusage flag */ - int32_t *total_brate_pri, /* o : Allocated primary channel bitrate */ - int32_t *total_brate_sec, /* o : Allocated secondary channel bitrate */ - int16_t *tdm_low_rate_mode, /* o : secondary channel low rate mode flag */ - const int16_t coder_type, /* i : secondary channel coder type */ - const int16_t ener_ratio_idx, /* i : correlation ratio indexe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const int16_t bwidth_pri, /* i : bandwidth of the primary channel */ - const int16_t bwidth_sec, /* i : bandwidth of the secondary channel */ - const int16_t flag_ACELP16k_pri, /* i : ACELP@16kHz core flag, primary chan. */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int16_t coder_type0, /* i : coder type (temporary in the encoder, from bitstream in decoder) */ - const int16_t tdm_inst_ratio_idx /* i : instantaneous correlation ratio index */ -); - - -/*! r: value of the indice */ -uint16_t get_indice_st( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t pos, /* i : absolute position in the bitstream */ - const int16_t nb_bits /* i : number of bits to quantize the indice */ -); - -void tdm_low_rate_dec( - Decoder_State *st, /* i/o: decoder static memory */ - float dct_epit[], /* o : GSC excitation in DCT domain */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - const float *lsf_new /* i : ISFs at the end of the frame */ -); - -void tdm_SCh_LSF_intra_pred( - const int32_t element_brate, /* i : element bitrate */ - const float *tdm_lsfQ_PCh, /* i : primary channel LSFs */ - float *pred_lsf_SCh /* o : predicted secondary channel LSFs */ -); - - -void first_VQstages( - const float *const *cb, - const float u[], /* i : vector to be encoded (prediction and mean removed) */ - const int16_t *levels, /* i : number of levels in each stage */ - const int16_t stagesVQ, /* i : number of stages */ - const float w[], /* i : weights */ - const int16_t N, /* i : vector dimension */ - const int16_t max_inner, /* i : maximum number of swaps in inner loop */ - int16_t indices_VQstage[] -); - - -void deindex_lvq_SHB( - UWord32 index, - float *out, - const int16_t nbits, - const int16_t mode -); - -/*----------------------------------------------------------------------------------* - * MDCT Stereo prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_td_itd_mdct_stereo( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder handle */ - const int16_t vad_flag_dtx[], /* i : VAD dtx flags */ - const int16_t vad_hover_flag[], /* i : VAD hangover flags */ - const int16_t input_frame /* i : frame length */ -); - -void QuantizeTCXSpectrum( - Encoder_State *st, /* i : state handle */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const float *x_orig, /* i : shaped MDCT spectrum */ - const float *gainlpc, /* i : FDNS gains */ - const Word16 *Aqind, /* i : frame-independent quantized coefficients (M+1) */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t vad_hover_flag, /* i : VAD hangover flag */ - int16_t *pL_frameTCX, /* o : full frame length */ - int16_t *pL_frame, /* o : frame length */ - int16_t *pL_spec, /* o : length of the coded spectrum */ - int16_t *ptcx_offset, /* o : folding point offset relative to the end of the previous frame */ - int16_t *pnoiseFillingBorder, /* o : noise filling border */ - float spectrum[], /* o : quantized MDCT spectrum */ - CONTEXT_HM_CONFIG *hm_cfg, /* o : Context-based harmonic model configuration */ - int16_t *hm_active, /* o : flag indicating if the harmonic model is active */ - float lf_deemph_fact[], /* o : low frequency deemphasis factors */ - int16_t *nf_seed, /* o : noise filling random seed */ - float *ener, /* o : energy of the quantized spectrum */ - float *gain_tcx, /* o : global gain */ - int16_t prm[] /* o : tcx parameters */ -); - -void EstimateStereoTCXNoiseLevel( - Encoder_State **sts, /* i : state handle */ - float *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum */ - float gain_tcx[][NB_DIV], /* i : global gain */ - int16_t L_frame[][NB_DIV], /* i : frame length */ - int16_t noiseFillingBorder[][NB_DIV], /* i : noise filling border */ - int16_t hm_active[][NB_DIV], /* i : flag indicating if the harmonic model is active */ - const int16_t ignore_chan[], /* i : flag indicating whether the channel should be ignored */ - float fac_ns[][NB_DIV], /* o : noise filling level */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void TNSAnalysisStereo( - Encoder_State **sts, /* i : state handle */ - float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ - const int16_t bWhitenedDomain, /* i : whitened domain flag */ - int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void InternalTCXDecoder( - Encoder_State *st, /* i/o: state handle */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t L_frameTCX, /* i : full frame length */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_spec, /* i : length of the coded spectrum */ - const int16_t tcx_offset, /* i : folding point offset relative to the end of the previous frame */ - const int16_t noiseFillingBorder, /* i : noise filling border */ - const float *x_quant, /* i : quantized spectrum */ - const float ener, /* i : energy of the quantized spectrum */ - float lf_deemph_fact[], /* i/o: low frequency deemphasis factors */ - const float fac_ns, /* i : noise filling level */ - const int16_t nf_seed, /* i : noise filling random seed */ - const float *A, /* i : LPC representation of the FDNS gains */ - float *gainlpc, /* i/o: FDNS gains */ - const int16_t hm_active, /* i : flag indicating if the harmonic model is active */ - float gain_tcx, /* i/o: global gain / quantized global gain */ - float spectrum[], /* o : dequantized spectrum */ - float synth[], /* o : time domain signal */ - int16_t *gain_tcx_q /* o : quantized global gain (at low bitrates) */ -); - -void stereo_mdct_core_enc_fx( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples Q0*/ - Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP Qx*/ - Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe Q6*/ -); - -void initMdctStereoEncData( - STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t bwidth, /* i : bandwidth */ - const int16_t igf, /* i : flag indicating IGF activity */ - const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */ - const int16_t mem_init /* i : initialize memory after malloc */ -); - -ivas_error initMdctItdHandling( - STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void stereo_mdct_enc_destroy( - STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */ -); - -void initMdctStereoDecData( - STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const int16_t igf, /* i : flag indicating IGF activity */ - const H_IGF_GRID igfGrid, /* i : IGF grid configuration */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void stereo_mdct_init_bands( - const int16_t L_frame, /* i : frame length */ - const int16_t tmp_tcx_mode, /* i : tcx mode (TCX10, TCX 20), -1 if transition frame */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t igf, /* i : flag indicating if IGF is used */ - const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */ - int16_t *sfbOffset, /* o : sfb offset table */ - int16_t *sfbCnt /* o : number of sfbs */ -); - -void stereo_mdct_init_igf_start_band( - STEREO_MDCT_BAND_PARAMETERS *stbParams, /* i/o: stereo frequency band parameters */ - const float transFac, /* i : transform factor */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t element_brate /* i : element bitrate */ -); - -void init_tcx_enc_info( - Encoder_State *st, /* i : coder memory state */ - int16_t *L_frame, - int16_t *L_frameTCX, - int16_t *L_spec -); - -void decoder_tcx_invQ( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - float A[], /* i : coefficients NxAz[M+1] */ - Word16 Aind[], /* i : frame-independent coefficients Az[M+1] */ - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - float x[], - float gainlpc2[], - float xn_buf[], - int16_t *fUseTns, /* o : flag that is set if TNS data is present */ - STnsData *tnsData, - float *gain_tcx, - const int16_t **prm_sqQ, - int16_t *nf_seed, - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt /* i : frame counter in the super frame */ -); - -void decoder_tcx_noisefilling( - Decoder_State *st, /* i/o: coder memory state */ - float concealment_noise[L_FRAME48k], - const float A[], /* i : coefficients NxAz[M+1] */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - float x[], - float gainlpc2[], - int16_t *temp_concealment_method, - const float gain_tcx, - const int16_t *prm_sqQ, - int16_t nf_seed, - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t frame_cnt /* i : frame counter in the super frame */ -); - -void decoder_tcx_noiseshaping_igf( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t left_rect, - float x[], - const float gainlpc2[], - int16_t *temp_concealment_method, - const int16_t bfi /* i : Bad frame indicator */ -); - -void decoder_tcx_tns( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - float x[N_MAX], - const int16_t fUseTns, /* i : flag that is set if TNS data is present */ - STnsData *tnsData, - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super frame */ - const int16_t whitenedDomain -); - -void decoder_tcx_imdct( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, /* i : frame length */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - const int16_t tcx_offset, - const int16_t tcx_offsetFB, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t left_rect, - float x[N_MAX], - float xn_buf[], - const uint16_t kernelType, /* i : TCX transform kernel type */ - const int16_t fUseTns, /* i : flag that is set if TNS data is present */ - float synth[], /* i/o: synth[-M..L_frame] */ - float synthFB[], - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super frame */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void init_tcx_info( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, /* i : global frame length */ - const int16_t L_frameTCX_glob, /* i : FB global frame length */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t bfi, /* i : bad frame indicator */ - int16_t *tcx_offset, /* o : folding point offset relative to the end of the previous frame */ - int16_t *tcx_offsetFB, /* o : FB folding point offset relative to the end of the previous frame*/ - int16_t *L_frame, /* o : frame length */ - int16_t *L_frameTCX, /* o : TCX frame length */ - int16_t *left_rect, /* o : left part is rectangular */ - int16_t *L_spec /* o : spectrum length */ -); - -void decoder_tcx_IGF_mono( - Decoder_State *st, /* i/o: coder memory state */ - float x[], /* o : de-quatized coefficients */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t bfi, /* i : bad frame indicator */ - const int16_t frame_cnt /* i : frame counter in the super_frame */ -); - -void decoder_tcx_IGF_stereo( - Decoder_State **sts, /* i/o: coder memory states */ - STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - float *x[CPE_CHANNELS][NB_DIV], /* o : de-quatized coefficients */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t k, /* i : Subframe index */ - const int16_t bfi, /* i : bad frame indicator */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void ms_processing( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const int16_t iSubframe, /* i : subframe number */ - float x_0[], /* i/o: spectrum 1 */ - float x_1[], /* i/o: spectrum 2 */ - int16_t maxSfb /* i : number of stereo frequency bands */ -); - -void ms_inv_mask_processing( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const int16_t iSubframe, /* i : subframe number */ - const float x_0[], /* i : spectrum 1 */ - const float x_1[], /* i : spectrum 2 */ - float x_inv_0[], /* o : inverse spectrum 1 */ - float x_inv_1[], /* o : inverse spectrum 2 */ - int16_t maxSfb /* i : number of stereo frequency bands */ -); - -void IGFDecApplyStereo_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDecL, /* i : instance handle of IGF Decoder */ - const IGF_DEC_INSTANCE_HANDLE hIGFDecR, /* i : instance handle of IGF Decoder */ - float *spectrumL, /* i/o: L MDCT spectrum */ - float *spectrumR, /* i/o: R MDCT spectrum */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t *coreMsMask, - const int16_t restrict_hopsize, - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t bfi_apply_damping /* i : decoder element mode */ -); - -void IGFEncStereoEncoder( - STEREO_MDCT_BAND_PARAMETERS *sfbParam, /* i/o: sfb parameters for the right channel */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : IGF handle */ - const float *mdctSpectrumL, /* i : left spectrum */ - const float *mdctSpectrumR, /* i : right spectrum */ - int16_t *msMask, /* i/o: MS mask */ - int16_t *igfStereoMode, /* o : IGF stereo mode */ - const int16_t mdct_stereo_mode, /* i : MDCT stereo mode */ - const int16_t isTCX20, /* i : flag for indicating TCX20 */ - const int16_t isTransition /* i : flag for transtition */ -); - -void IGFDecReplicateTCX10State_flt( - IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: instance handle of IGF Decoder */ -); - - -void InitPsychLPC( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t L_frame, /* i : frame length */ - const TCX_CONFIG_HANDLE hTcxCfg /* i : TCX configuration handle */ -); - - -void stereo_coder_tcx( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ - float *inv_mdst_spectrum[CPE_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void stereo_decoder_tcx( - STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ - float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ - float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ - const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ - const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ - const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ - const int16_t igf, /* i : flag for IGF activity */ - const int16_t L_frameTCX_l, /* i : TCX frame length of left channel */ - const int16_t L_frameTCX_r, /* i : TCX frame length of right channel */ - const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t last_core_l, /* i : last core for left channel */ - const int16_t last_core_r, /* i : last core for right channel */ - const int16_t tmp_plc_upmix /* i : indicates temp upmix for PLC decision */ -); - -void stereo_mdct_core_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *signal_out[CPE_CHANNELS], /* o : synthesis @internal_FS */ - float signal_outFB[CPE_CHANNELS][L_FRAME48k] /* o : synthesis @output_FS */ -); - -void splitAvailableBits( - const int16_t total_bits, /* i : total available bits for TCX coding */ - const int16_t split_ratio, /* i : split ratio */ - const int16_t isSBAStereoMode, /* i : signal core coding for SBA */ - int16_t *bits_ch0, /* o : bits for channel 0 */ - int16_t *bits_ch1 /* o : bits for channel 1 */ -); - -Word16 write_stereo_to_bitstream_fx -( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ - const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ - BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ -); - - - -void ComputeSpectrumNoiseMeasure( - const float *powerSpec, - const int16_t L_frame, - const int16_t startLine, - const int16_t resetMemory, - int8_t *noiseFlags, - const int16_t lowpassLine -); - -void IGFSaveSpectrumForITF( - IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */ - const int16_t igfGridIdx, /* i : IGF grid index */ - const float *pITFSpectrum /* i : MDCT spectrum */ -); - -void convert_coeffs_to_higher_res( - const float *in1, /* i : first subframe input */ - const float *in2, /* i : second subframe input */ - float *out, /* o : converted output */ - const int16_t len /* i : length of subframes */ -); - -int16_t quantize_sns( - float sns_in[CPE_CHANNELS][NB_DIV][M], - float snsQ_out[CPE_CHANNELS][NB_DIV][M], - Encoder_State **sts, - int16_t *indices, - int16_t *zero_side_flag, - int16_t *sns_stereo_mode -); - -void dequantize_sns( - int16_t indices[CPE_CHANNELS][NPRM_LPC_NEW], - float snsQ_out[CPE_CHANNELS][NB_DIV][M], - Decoder_State **sts -); - -void sns_avq_dec( - int16_t *index, /* i : Quantization indices */ - float SNS_Q[NB_DIV][M], /* o : Quantized SNS vectors */ - const int16_t L_frame, /* i : frame length */ - const int16_t numlpc /* i : Number of sets of lpc */ -); - -void sns_avq_dec_stereo( - int16_t *indexl, /* i : Quantization indices (left channel) */ - int16_t *indexr, /* i : Quantization indices (right channe) */ - const int16_t L_frame, /* i : frame length */ - float *SNS_Ql, /* o : Quantized SNS vectors (left channel) */ - float *SNS_Qr /* o : Quantized SNS vectors (right channe) */ -); - -void convertToMS( - const int16_t L_frame, /* i : frame length */ - float x0[], /* i/o: mid/left channel coefficients */ - float x1[], /* i/o: side/right channel coefficients */ - const float norm_fac /* i : normalization factor */ -); - -void inverseMS( - const int16_t L_frame, /* i : frame length */ - float x0[], /* i/o: mid/left channel coefficients */ - float x1[], /* i/o: side/right channel coefficients */ - const float norm_fac /* i : normalization factor */ -); - -void stereoFdCngCoherence( - Encoder_State **sts, /* i/o: core encoder structures */ - const int16_t last_element_mode, /* i : last element mode */ - float fft_buff[CPE_CHANNELS][2 * L_FFT] /* i : fft buffers for L and R channels */ -); - -void FdCngEncodeMDCTStereoSID( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -); - -void FdCngDecodeMDCTStereoSID( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -); - -ivas_error initMdctStereoDtxData( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder handle */ -); - -void synchonize_channels_mdct_sid( - Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure */ - const int16_t n /* i : channel number */ -); - -void updateBuffersForDmxMdctStereo( - CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */ - const int16_t output_frame, /* i : output frame length */ - float *output[CPE_CHANNELS], /* i/o: decoder output */ - float synth[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis */ -); - -void applyDmxMdctStereo( - const CPE_DEC_HANDLE hCPE, /* i : CPE handle */ - float *output[CPE_CHANNELS], /* o : output from core decoder */ - const int16_t output_frame /* i : output frame length */ -); - -/*----------------------------------------------------------------------------------* - * Front-VAD prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error front_vad_create( - FRONT_VAD_ENC_HANDLE *hFrontVad, /* i/o: front-VAD handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -); - -void front_vad_destroy( - FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ -); - -ivas_error front_vad( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure, nullable */ - Encoder_State *st, /* i/o: encoder state structure */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - FRONT_VAD_ENC_HANDLE *hFrontVads, /* i/o: front-VAD handles */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t input_frame, /* i : frame length */ - int16_t vad_flag_dtx[], /* o : HE-SAD flag with additional DTX HO */ - float fr_bands[][2 * NB_BANDS], /* i : energy in frequency bands */ - float Etot_LR[], /* o : total energy Left & Right channel */ - float lf_E[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ - int16_t localVAD_HE_SAD[], /* o : HE-SAD flag without hangover, LR channels */ - int16_t vad_hover_flag[], /* o : VAD hangover flag */ - float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ - float *PS_out, /* o : energy spectrum */ - float *Bin_E_out /* o : log-energy spectrum of the current frame*/ -); - -ivas_error front_vad_spar( - SPAR_ENC_HANDLE hSpar, /* i/o: SPAR encoder structure */ - const float *omni_in, /* i : omnidirectional input signal */ - ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : encoder configuration handle */ - const int16_t input_frame /* i : input frame length */ -); - - -/*----------------------------------------------------------------------------------* - * Stereo CNG prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_enc_cng_init( - STEREO_CNG_ENC_HANDLE hStereoCng /* i/o: stereo CNG encoder structure */ -); - -void stereo_cng_upd_counters( - STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ - const int32_t element_mode, /* i : element mode */ - const int16_t nbands, /* i : Number of bands in active */ - const float sidSideGain[], /* i : SID side gains */ - const int16_t burst_ho_count, /* i : Hang-over count */ - int16_t *coh_fade_counter /* i : Coherence fade counter */ -); - -void stereo_cng_init_dec( - STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: stereo CNG decoder structure */ - const int16_t *frameSize /* i : pointer to frameSize of channel 0 to be used for channel 1 */ -); - -void stereo_cng_compute_PScorr( - float *output[CPE_CHANNELS], /* i : Output signal */ - float *c_PS_LT, /* i/o: Correlation */ - const int16_t L_frame_0, /* i : L_frame channel 0 */ - const int16_t L_frame_1 /* i : L_frame channel 1 */ -); - -void stereo_cng_dec_update( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int32_t ivas_total_brate /* i : IVAS total bitrate Q0*/ -); - -void stereo_cna_update_params( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i : Output signal */ - const int16_t output_frame, /* i : Output frame length */ - const int16_t tdm_ratio_idx /* i : TDM ratio index */ -); - -void dtx_enc_init( - Encoder_State *st, /* i : Encoder state handle */ - const int16_t var_SID_rate_flag, /* i : flag for variable SID update rate */ - const int16_t interval_SID /* i : interval for SID update */ -); - - -/*----------------------------------------------------------------------------------* - * Framework general prototypes - *----------------------------------------------------------------------------------*/ - -void mvc2c( - const uint8_t x[], /* i : input vector */ - uint8_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -/*! r: Adjusted value */ -ivas_error stereo_memory_dec( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - CPE_DEC_HANDLE hCPE, /* i : CPE decoder structure */ - const int16_t nb_bits_metadata, /* i : number of metadata bits */ - const int32_t output_Fs, /* i : output sampling rate */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const MC_MODE mc_mode, /* i : MC mode */ - const int16_t nchan_transport /* i : number of transport channels */ -); - -void stereo_switching_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ -); - -void stereo_td2dft_update( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int16_t n, /* i : channel number */ - float output[], /* i/o: synthesis @internal Fs */ - float synth[], /* i/o: synthesis @output Fs */ - float hb_synth[], /* i/o: hb synthesis */ - const int16_t output_frame /* i : frame length */ -); - -void stereo_mdct2dft_update( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float output0[], /* i/o: synthesis @internal Fs, ch0 */ - float synth0[] /* i/o: synthesis @output Fs, ch0 */ -); - - -/*! r: number of bits written */ - - - -/*----------------------------------------------------------------------------------* - * MCT prototypes - *----------------------------------------------------------------------------------*/ -void ivas_mdct_core_whitening_enc_fx( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples */ - Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ - Word16 pitch_buf[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word32 *mdst_spectrum_long[CPE_CHANNELS], /* o : buffer for MDST spectrum */ - int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* o : buffer TNS bits */ - Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening */ - int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* o : size of TNS */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to parameter array */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t nChannels, /* i : total number of coded channels */ -Word16 mdst_spectrum_e[CPE_CHANNELS][NB_DIV], -Word16 orig_spectrum_e[CPE_CHANNELS][NB_DIV] -); -void ivas_mct_core_enc( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE encoder structures */ - const int16_t nChannels, /* i : number of channels to be coded */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t switch_bw, /* i : flag bandwidth switch occurance */ - const int16_t lfe_bits, /* i : bits spent for LFE */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ -); - -void ivas_mdct_quant_coder( - CPE_ENC_HANDLE hCPE, /* i/o: Encoder CPE handle */ - int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : bits needed for TNS parameters */ - int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : size of TNS */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* i : pointer to parameter array */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void apply_MCT_enc( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ - float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ - float *inv_mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ - const int16_t nchan /* i : number of channels */ -); - -void write_mct_bitstream( - Encoder_State **sts, /* i/o: encoder state structure */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const int16_t nchan /* i : number of channels */ -); - -void splitAvailableBitsMCT_fx( - void **sts, /* i/o: encoder/decoder state structure */ - const Word16 total_bits, /* i : total number of available bits */ - const Word16 split_ratio[MCT_MAX_CHANNELS], /* i : ratio for splitting the bits Q0 */ - const Word16 enc_dec, /* i : encoder or decoder flag */ - const Word16 nchan /* i : number of channels */ -); - -void getChannelEnergies( - Encoder_State **sts, /* i : Encoder state structure */ - float nrg[MCT_MAX_CHANNELS], /* o : energies */ - const int16_t nchan /* i : number of channels */ -); - -void mctStereoIGF_enc( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - float *orig_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : MDCT spectrum for ITF */ - float powerSpec[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ - float *powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect. */ - float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ -); - -void ivas_mdct_dec_side_bits_frame_channel( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ - Decoder_State *st0, /* i : pointer to bitstream handle */ - int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ - int16_t param[CPE_CHANNELS][DEC_NPRM_DIV * NB_DIV], /* i/o: parameters buffer */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t odd_channel_cpe /* i : flag cpe with odd nb of tc channels */ -); - -void ivas_mct_side_bits( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE decoder structure */ - const int16_t nCPE, /* i : number of CPEs */ - Decoder_State *st0, /* i : decoder handle for Bstr */ - const int16_t bfi, /* i : BFI flag */ - uint16_t *bitstream, /* o : bitstream indices */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -void ivas_mdct_core_invQ( - CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */ - int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* i : number of TNS bits */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* i : pointer to param buffer */ - int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* i : lpc parameters */ - int16_t param[CPE_CHANNELS][DEC_NPRM_DIV * NB_DIV], /* i : param buffer */ - int16_t fUseTns[CPE_CHANNELS][NB_DIV], /* i : flag TNS enabled */ - STnsData tnsData[CPE_CHANNELS][NB_DIV], /* i : TNS parameter */ - float *x_0[CPE_CHANNELS][NB_DIV], /* i/o: signal buffer */ - float *x[CPE_CHANNELS][NB_DIV], /* i/o: signal buffer */ - float Aq[CPE_CHANNELS][( NB_SUBFR16k + 1 ) * ( M + 1 )], /* i : LP coefficients */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : M/S mask */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void ivas_mdct_core_reconstruct( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *x[][NB_DIV], /* i/o: pointers to synthesis @internal_FS */ - float signal_outFB[CPE_CHANNELS][L_FRAME_PLUS], /* o : synthesis @output_FS */ - int16_t fUseTns[CPE_CHANNELS][NB_DIV], /* i : flage TNS enabled */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void ivas_mdct_core_tns_ns( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t fUseTns[CPE_CHANNELS][NB_DIV], /* i : two entries for each channel in TCX10 */ - STnsData tnsData[CPE_CHANNELS][NB_DIV], /* o : TNS parameter */ - float *x[CPE_CHANNELS][NB_DIV], /* o : synthesis @internal_FS */ - float Aq[CPE_CHANNELS][( NB_SUBFR16k + 1 ) * ( M + 1 )], /* o : LP coefficients */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - - -void ivas_mct_dec_mct( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - Decoder_State **sts, /* i/o: decoder state structure */ - const int16_t nchan /* i : number of channels */ -); - -void apply_MCT_dec( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - Decoder_State **sts, /* i/o: decoder state structure */ - float *x[MCT_MAX_CHANNELS][NB_DIV] /* i/o: decoded and dequan. spect. input to MCT */ -); - -void mctStereoIGF_dec( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - Decoder_State **sts, /* i/o: decoder state structure */ - float *x[MCT_MAX_CHANNELS][NB_DIV], /* i/o: decoded and dequantized spectrum */ - const int16_t bfi /* i : bad frame flag */ -); - -void enc_prm_igf_mdct( - Encoder_State *st, /* i : Encoder state handle */ - BSTR_ENC_HANDLE hBstr /* i/o: Bitstream handle */ -); - -void mdct_read_IGF_bits( - Decoder_State *st, /* i/o: Encoder state handle */ - Decoder_State *st0 /* i : pointer to handle where bstr is read */ -); - - -/*----------------------------------------------------------------------------------* - * Q Metadata prototypes for DirAC and MASA - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_qmetadata_enc_encode( - BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ - IVAS_QMETADATA *hQMetaData, /* i/o: q_metadata handle */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -ivas_error ivas_qmetadata_enc_encode_hr_384_512( - BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ - IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle */ - const int16_t bits_sph_idx, - const int16_t bits_sp_coh -); - -void deindex_sph_idx( - const uint16_t sphIndex, /* i : Spherical index */ - const SPHERICAL_GRID_DATA *gridData, /* i : Prepared spherical grid */ - float *theta, /* o : Elevation */ - float *phi /* o : Azimuth */ -); - -/*! r: output index for direction */ -uint16_t index_theta_phi_16( - float * p_theta, /* i/o: input elevation to be indexed */ - float * p_phi, /* i/o: input azimuth to be indexed */ - const SPHERICAL_GRID_DATA *gridData /* i : generated grid data */ -); - -void reset_metadata_spatial( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - BSTR_ENC_HANDLE hMetaData, /* i/o: Metadata bitstream handle */ - const int32_t element_brate, /* i : element bitrate */ - int32_t *total_brate, /* o : total bitrate */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t nb_bits_metadata /* i : number of meatdata bits */ -); - -/*! r: number of bits written */ - -/*! r: number of bits read */ -int16_t ivas_qmetadata_dec_decode( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - uint16_t *bitstream, /* i : bitstream */ - int16_t *index, /* i/o: bitstream position */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -/*! r: number of bits read */ -int16_t ivas_qmetadata_dec_decode_hr_384_512( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */ - uint16_t *bitstream, /* i : bitstream */ - int16_t *index, /* i/o: bitstream position */ - const SPHERICAL_GRID_DATA *sph_grid16, /* i : spherical grid for deindexing */ - const int16_t bits_sph_idx, - const int16_t bits_sp_coh, - const uint8_t ncoding_bands_config -); - -/*! r: number of bits read */ -int16_t ivas_qmetadata_dec_sid_decode( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - uint16_t *bitstream, /* i : bitstream */ - int16_t *index, /* i/o: bitstream position */ - const int16_t nchan_transport, /* i : number of transport channels */ - int16_t *element_mode, /* o : element mode */ - const int16_t ivas_format /* i : IVAS format */ -); - - - - -void restore_metadata_buffer( - BSTR_ENC_HANDLE hMetaData, - const int16_t next_ind_start, - const int16_t bit_pos_start -); - -/*! r: codeword index */ -int16_t masa_sq( - const float in, /* i : input value */ - const float *threshold, /* i : partition */ - const int16_t cb_sz /* i : codebook size */ -); - -void ivas_qmetadata_azimuth_elevation_to_direction_vector( - const float az, /* i : azimuth */ - const float el, /* i : elevation */ - float *dv /* o : direction vector */ -); - -ivas_error only_reduce_bits_direction( - int16_t *reduce_bits_out, - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - int16_t reduce_bits, - const int16_t coding_subbands, - const int16_t no_subframes, - int16_t *ind_order -); - -void quantize_direction_frame( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/ -); - -/*! r: quantized spherical index */ -uint16_t quantize_direction( - const float theta, /* i : input elevation value */ - float phi, /* i : input azimuth value */ - const int16_t no_bits, /* i : number of bits */ - float *theta_q, /* o : quantized elevation */ - float *phi_q, /* o : quantized azimuth */ - uint16_t *index_theta, /* o : quantized elevation index */ - uint16_t *index_phi, /* o : quantized azimuth index */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -int16_t quantize_direction2D( - float phi, /* i : input azimuth value */ - const int16_t no_cw, /* i : number of bits */ - float *phi_q, /* o : quantized azimuth value */ - uint16_t *index_phi, /* o : quantized azimuth index */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -void quantize_direction_frame2D( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* i : input azimuth values */ - float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] /* i : input elevation values */ -); - -void small_requantize_direction_frame( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* i : input azimuth values */ - float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* i : input elevation values */ - const int16_t raw_flag[MASA_MAXIMUM_CODING_SUBBANDS], /* i : raw/EC encoding mode for each subband */ - int16_t bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS], /* i/o: number of bits per subband */ - int16_t *diff /* i/o: number of bits to be reduced */ -); - -/*! r: index azimuth */ -int16_t quantize_phi( - float phi, /* i : azimuth value */ - const int16_t flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */ - float *phi_hat, /* o : quantized azimuth */ - const int16_t n /* i : azimuth codebook size */ -); - -/*! r: decoded elevation value */ -float deindex_elevation( - uint16_t *id_th, /* i : input index */ - const int16_t no_bits, /* i : number of bits for the spherical grid */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -float deindex_azimuth( - int16_t id_phi, /* i : index */ - const int16_t no_bits, /* i : number of bits for the spherical grid */ - const int16_t id_th, /* i : elevation index */ - const int16_t remap, /* i : remapping flag */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -UWord16 ivas_qmetadata_reorder_generic_fx( - const Word16 signed_value -); - -void ivas_sba_config( - const int32_t sba_total_brate, /* i : SBA total bitrate */ - int16_t sba_order, /* i : Ambisonic (SBA) order */ - int16_t nb_channels, /* i : Number of Ambisonic (SBA) channels */ - int16_t *nchan_transport, /* o : number of transport channels */ - const int16_t sba_planar, /* i : SBA planar flag */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE, /* o : number of CPEs */ - int16_t *element_mode /* o : element mode of the core coder */ -); - -void ivas_sba_set_cna_cng_flag( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_sba_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesFlushed, /* o : number of samples flushed */ - int16_t *data /* o : output synthesis signal */ -); - -ivas_error ivas_sba_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t nCldfbSlots, /* i : number of CLDFB slots */ - const int16_t nSamplesForRendering, /* i : number of samples provided */ - float *data[] /* i : transport channel samples */ -); - - - -/*! r: Ambisonic (SBA) order */ -int16_t ivas_sba_get_order( - const int16_t nb_channels, /* i : Number of ambisonic channels */ - const int16_t sba_planar /* i : SBA planar flag */ -); - -/*! r: number of Ambisonic channels */ -int16_t ivas_sba_get_nchan( - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t sba_planar /* i : SBA planar flag */ -); - -/*! r: number of ambisonics metadata channels */ - -void ivas_sba_getTCs( - float *sba_data[], /* i : SBA signals */ - Encoder_Struct *st_ivas, /* i/o: Encoder struct */ - const int16_t input_frame /* i : frame length */ -); - -int16_t ivas_sba_remapTCs( - float *sba_data[], /* i/o: SBA signals */ - Decoder_Struct *st_ivas, /* i/o: decoder struct */ - const int16_t output_frame /* i : frame length */ -); - -void ivas_sba_dirac_stereo_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[CPE_CHANNELS], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t mcmasa /* i : McMASA flag */ -); - -void ivas_sba_dirac_stereo_config( - STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */ -); - - -Word16 ivas_get_sba_dirac_stereo_flag( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_sba_dirac_stereo_smooth_parameters( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */ - const int16_t cross_fade_start_offset, /* i : SPAR mixer delay compensation */ - const int32_t output_Fs, /* i : Fs for delay calculation */ - const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */ -); - - -/*----------------------------------------------------------------------------------* - * DirAC prototypes - *----------------------------------------------------------------------------------*/ - - -ivas_error ivas_dirac_enc_reconfigure( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - - - -ivas_error ivas_dirac_config( - void *st_ivas, /* i/o: IVAS encoder/decoder state structure */ - const int16_t enc_dec /* i : encoder or decoder flag */ -); - -void ivas_dirac_config_bands( - int16_t *band_grouping, /* o : band grouping */ - const int16_t nbands, /* i : number of bands */ - const int16_t max_band, /* i : maximal band index +1 */ - int16_t *dirac_to_spar_md_bands, /* o : mapping of DirAC parameter band index to SPAR FB band index */ - const int8_t useLowerBandRes, /* i : flag indicating lower band resolution for DirAC */ - const int16_t enc_param_start_band, /* i : band index of first DirAC parameter band */ - IVAS_FB_MIXER_HANDLE hFbMdft -); - -void ivas_get_dirac_sba_max_md_bits( - const int32_t sba_total_brate, - int16_t *bits_frame_nominal, - int16_t *metadata_max_bits, - int16_t *qmetadata_max_bit_req, - const int16_t nbands - , - IVAS_FORMAT ivas_format -); - -ivas_error ivas_dirac_sba_config( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - int16_t *element_mode, /* o : element mode of the core coder */ - int32_t sba_total_brate, /* i : SBA total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t nbands /* i : number of frequency bands */ - , - IVAS_FORMAT ivas_format -); - -ivas_error ivas_dirac_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const DIRAC_CONFIG_FLAG flag_configopen /* i/ : Flag determining if we open or reconfigure the DirAC decoder */ -); - -void ivas_dirac_dec_close( - DIRAC_DEC_HANDLE *hDirAC_out -); - -void ivas_dirac_dec_read_BS( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - Decoder_State *st, /* i/o: decoder Core state structure */ - DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial rendering data handle */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q metadata */ - int16_t *nb_bits, /* o : number of bits read */ - const int16_t last_bit_pos, /* i : last read bitstream position */ - const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ -); - -void generate_masking_noise_lb_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - const int16_t nCldfbTs, /* i : number of CLDFB slots that will be rendered */ - const int16_t cna_flag /* i : CNA flag for LB and HB */ -); - - -void ivas_dirac_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_dirac_dec_render_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - float *pppQMfFrame_ts_re[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX], - float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] -); - - -void computeDirectionVectors( - float *intensity_real_x, - float *intensity_real_y, - float *intensity_real_z, - const int16_t enc_param_start_band, - const int16_t num_frequency_bands, - float *direction_vector_x, - float *direction_vector_y, - float *direction_vector_z -); - -void computeDiffuseness( - float *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF], - const float *buffer_energy, - const int16_t num_freq_bands, - float *diffuseness -); - -void ivas_dirac_dec_get_response( - const int16_t azimuth, - const int16_t elevation, - float *response, - const int16_t ambisonics_order -); - - - -ivas_error ivas_mc_paramupmix_enc_open_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_mc_paramupmix_enc_close_fx( - MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -ivas_error ivas_mc_paramupmix_dec_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_mc_paramupmix_dec_close( - MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */ -); - -void ivas_mc_paramupmix_dec_read_BS( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - Decoder_State *st, /* i/o: decoder state structure */ - MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */ - int16_t *nb_bits /* o : number of bits written */ -); - -void ivas_mc_paramupmix_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ - const int16_t nSamplesForRendering /* i : number of samples provided */ -); - -void ivas_param_mc_set_coded_bands_fx( - HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* i/o: handle for the Parametric MC parameter coding state */ -); - -/*! r: number of IVAS transport channels */ - -ivas_error ivas_param_mc_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -ivas_error ivas_param_mc_enc_reconfig( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_param_mc_enc_close( - PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void ivas_param_mc_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ - BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */ - float *data_f[], /* i/o: input/transport MC data */ - const int16_t input_frame /* i : input frame length */ -); - -ivas_error ivas_param_mc_dec_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_param_mc_dec_reconfig( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - - -void ivas_param_mc_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ - float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output*/ -); - -void ivas_param_mc_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_param_mc_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ -); - -/*! r: number of cldfb synthesis instances */ -int16_t param_mc_get_num_cldfb_syntheses( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -); - -UWord16 ivas_param_mc_get_configuration_index_fx( - const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -ivas_error ivas_dirac_dec_output_synthesis_cov_open( - DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i/o: handle for the covariance synthesis parameters */ - DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state, /* i/o: handle for the covariance synthesis state */ - const int16_t max_band_decorr, /* i : uppermost frequency band where decorrelation is applied */ - const int16_t interp_length, /* i : length for interpolating the mixing matrices in time slots */ - const int16_t num_param_bands, /* i : number of parameter bands */ - const int16_t num_param_bands_residual, /* i : number of parameter bands with a residual mixing matrix (i.e. decorrelation */ - const int16_t nchan_in, /* i : number of input (transport) channels */ - const int16_t nchan_out, /* i : number of output channels */ - const float *proto_matrix /* i : the prototype (upmix) matrix (only used if mode == 1) */ -); - -void ivas_dirac_dec_output_synthesis_get_interpolator( - DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i/o: handle for the covariance synthesis parameters */ - const uint16_t interp_length /* i : interpolator length */ -); - -void ivas_dirac_dec_output_synthesis_cov_init( - DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state, /* i/o: pointer to the state of the covariance synthesis */ - const int16_t nchan_in, /* i : number of input (tranport) channels */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t n_param_bands, /* i : number of total parameter bands */ - const int16_t n_param_bands_res /* i : number of parameter bands with a residual mixing matrix (i.e. decorrelation */ -); - -void ivas_dirac_dec_output_synthesis_cov_close( - DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i : handle for the covariance synthesis parameters */ - DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state /* i/o: handle for the covariance synthesis state */ -); - - -void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( - float *Cldfb_RealBuffer_in, /* i : input channel filter bank samples (real part) */ - float *Cldfb_ImagBuffer_in, /* i : input channel filter bank samples (imaginary part) */ - float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ - float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ - float *mixing_matrix[], /* i : parameter band wise mixing matrices (direct part) */ - float *mixing_matrix_res[], /* i : parameter band wise mixing matrices (residual part) */ - const uint16_t slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ - const uint16_t slot_idx_tot, /* i : time slot index for the current slot within the frame */ - const int16_t nX, /* i : number of input channels */ - const int16_t nY, /* i : number of output channels */ - PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ -); - - -void FdCngEncodeDiracMDCTStereoSID( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -); - -void FdCngDecodeDiracMDCTStereoSID( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -); - - -/*----------------------------------------------------------------------------------* - * SPAR prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_spar_enc_open( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder handle */ - const int16_t spar_reconfig_flag /* i : SPAR reconfiguration flag */ -); - -ivas_error ivas_spar_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data_f[], /* i/o: input/transport audio channels */ - const int16_t input_frame, /* i : input frame length */ - int16_t *nb_bits_metadata, /* i : number of MD bits written */ - BSTR_ENC_HANDLE hMetaData /* o : MetaData handle */ -); - -ivas_error ivas_spar_dec_open( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t spar_reconfig_flag /* i : SPAR reconfiguration flag */ -); - - -ivas_error ivas_spar_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - int16_t *nb_bits_read /* o : number of MD bits read */ -); - -void ivas_spar_config( - int32_t ivas_total_brate, /* i : codec total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - int16_t *nchan_transport, /* o : number of transport channels */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE, /* o : number of CPEs */ - int32_t *core_nominal_brate, /* o : core-coding nominal bitrate */ - const int16_t sid_format /* i : IVAS format indicator from SID frame */ -); - -ivas_error ivas_sba_linear_renderer( - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nchan_in, /* i : number of input ambisonics channels */ - const int16_t nchan_ism, /* i : number of objects */ - const AUDIO_CONFIG output_config, /* i : output audio configuration */ - const IVAS_OUTPUT_SETUP output_setup /* i : output format setup */ -); - -void ivas_sba_mix_matrix_determiner( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ - float *output[], /* i/o: transport/output audio channels */ - const int16_t bfi, /* i : BFI flag */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ - const int16_t output_frame, /* i : output frame length */ - const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */ -); - -/* AGC */ -/*! r: AGC enable flag */ - -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 */ - const int16_t nchan_inp /* i : number of input channels */ -); - -void ivas_spar_agc_enc_close( - ivas_agc_enc_state_t **hAgcEnc /* i/o: AGC encoder handle */ -); - -void ivas_agc_enc_process( - ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */ - BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - float **ppPcm_in, /* i : input audio channels */ - float **ppPcm_out, /* o : output audio channels */ - const int16_t n_channels, /* i : number of channels */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -); - -ivas_error ivas_spar_agc_dec_open( - ivas_agc_dec_state_t **hAgcDec, /* i/o: AGC decoder handle */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void ivas_spar_agc_dec_close( - ivas_agc_dec_state_t **hAgcDec /* i/o: AGC decoder handle */ -); - - -void ivas_agc_dec_process( - ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */ - float *pcm_in[], /* i : input audio channels */ - float *pcm_out[], /* o : output audio channels */ - const int16_t n_channels, /* i : number of channels */ - const int16_t output_Fs /* i : output sampling rate */ -); - -void ivas_agc_read_bits( - ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */ - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - const int16_t n_channels, /* i : number of channels */ - const int16_t AGC_flag /* i : AGC on/off flag */ -); - -void ivas_agc_initWindowFunc( - float *pWinFunc, - const int16_t length -); - -void ivas_agc_calcGainParams( - uint16_t *absEmin, - uint16_t *betaE, - uint16_t *maxAttExp, - const int16_t numCoeffs -); - -float ivas_get_mdct_scaling_gain( - const int16_t dct_len_by_2 -); - -void ivas_get_twid_factors( - const int16_t length, - const float **pTwid_re, - const float **pTwid_im -); - -int16_t ivas_get_bw_idx_from_sample_rate( - const int32_t sampling_rate /* i : sampling rate */ -); - -/*! r: config. table index */ -int16_t ivas_get_spar_table_idx( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : IVAS SBA order */ - const int16_t bwidth, /* i : audio bandwidth */ - int16_t *bitlen, /* o : number of bits */ - int16_t *ind /* o : indice */ -); - -/*! r: number of transport channels */ -int16_t ivas_get_sba_num_TCs( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order /* i : IVAS SBA order */ -); - - -void ivas_spar_bitrate_dist( - int32_t core_brates_act[], /* o : bitrates per core-coder */ - const int16_t nAvailBits, /* i : number of available bits */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void ivas_mdct( - const float *pIn, - float *pOut, - const int16_t length -); - -void ivas_dct_windowing( - const int16_t fade_len, - const int16_t full_len, - const int16_t dct_len, - const int16_t zero_pad_len, - const float *pWindow_coeffs, - const int16_t frame_len, - float *pOut_buf, - float *pBuffer_prev, - float *pTemp_lfe -); - -void ivas_tda( - const float *pIn, - float *pOut, - const int16_t length -); - -void ivas_imdct( - const float *pIn, - float *pOut, - const int16_t length -); - -void ivas_itda( - const float *re, - float *pOut, - const int16_t length -); - -void ivas_spar_get_cldfb_gains( - SPAR_DEC_HANDLE hSpar, - HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, - HANDLE_CLDFB_FILTER_BANK cldfbSynDec0, - const DECODER_CONFIG_HANDLE hDecoderConfig -); - -/*! r: 1 if prediction residual channel */ - -void ivas_spar_dec_agc_pca( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* i/o: input/output audio channels */ - const Word16 output_frame /* i : output frame length */ -); - -void ivas_spar_dec_set_render_map( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nCldfbTs /* i : number of CLDFB time slots */ -); - -void ivas_spar_dec_set_render_params( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t n_cldfb_slots /* i : number of cldfb slots in this frame */ -); - -void ivas_spar_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t nCldfbSlots, /* i : number of CLDFB slots */ - const int16_t nSamplesForRendering /* i : number of samples provided */ -); - -void ivas_sba_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nCldfbSlots, /* i : number of CLDFB slots */ - const int16_t nSamplesForRendering /* i : number of samples provided */ -); - -ivas_error ivas_sba_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_spar_dec_upmixer_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* o : output audio channels */ - const int16_t nchan_internal /* i : number of internal channels */ -); - -void ivas_spar_dec_upmixer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* i/o: input/output audio channels */ - const int16_t nchan_internal, /* i : number of internal channels */ - const int16_t output_frame /* i : output frame length */ -); - -/* MD module */ - -void ivas_spar_md_enc_close( - ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */ -); - -void ivas_compute_spar_params( - float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], - const int16_t i_ts, - float ***mixer_mat, - const int16_t start_band, - const int16_t end_band, - const int16_t dtx_vad, - const int16_t num_ch, - const int16_t bands_bw, - const int16_t active_w, - const int16_t active_w_vlbr, - ivas_spar_md_com_cfg *hSparCfg, - ivas_spar_md_t *hSparMd, - float *pWscale, - const int16_t from_dirac, - const int16_t dyn_active_w_flag -); - -void ivas_create_fullr_dmx_mat( - float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], - float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], - float ***mixer_mat, - const int16_t in_chans, - const int16_t start_band, - const int16_t end_band, - const int16_t active_w, - ivas_spar_md_com_cfg *hMdCfg -); - -void ivas_calc_c_p_coeffs( - ivas_spar_md_t *pSparMd, - float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - const int16_t i_ts, - float ***mixer_mat, - const int16_t num_ch, - const int16_t num_dmx, - const int16_t band_idx, - const int16_t dtx_vad, - const int16_t compute_p_flag, - const int16_t dyn_active_w_flag -); - -void ivas_get_spar_md_from_dirac( - float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - float diffuseness[IVAS_MAX_NUM_BANDS], - const int16_t n_ts, - float ***mixer_mat, - ivas_spar_md_t *hSpar_md, - ivas_spar_md_com_cfg *hSpar_md_cfg, - const int16_t start_band, - const int16_t end_band, - const int16_t order, - const int16_t dtx_vad, - float Wscale_d[IVAS_MAX_NUM_BANDS], - const uint8_t useLowerRes, - const int16_t active_w_vlbr, - const int16_t dyn_active_w_flag -); - -/*! r: number of MD subframes */ - -ivas_error ivas_spar_md_dec_matrix_open( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t num_channels, /* i : number of internal channels */ - const int16_t num_md_sub_frames -); - -void ivas_spar_md_dec_matrix_close( - ivas_spar_md_dec_state_t *hMdDecoder, /* i/o: SPAR MD decoder handle */ - const int16_t num_channels /* i : number of internal channels */ -); - -ivas_error ivas_spar_md_dec_open( - ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels, /* i : number of internal channels */ - const int16_t sba_order, /* i : SBA order */ - const int16_t sid_format, /* i : SID format */ - const int32_t last_active_ivas_total_brate /* i : IVAS last active bitrate */ -); - -void ivas_spar_md_dec_close( - ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ -); - -void ivas_spar_get_parameters( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t ts, /* i : time slot index */ - const int16_t num_ch_out, /* i : number of channels out */ - const int16_t num_ch_in, /* i : number of channels in */ - const int16_t num_spar_bands, /* i : number of SPAR bands */ - float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /* o : mixing matrix */ -); - -ivas_error ivas_spar_md_dec_init( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels, /* i : number of internal channels */ - const int16_t sba_order /* i : SBA order */ -); - -void ivas_spar_md_dec_process( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t sba_order /* i : SBA order */ -); - -void ivas_spar_to_dirac( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t dtx_vad, /* i : DTX frame flag */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t bw, /* i : band joining factor */ - const int16_t dyn_active_w_flag /* i : dynamic active W flag */ -); - -void ivas_spar_update_md_hist( - ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */ -); - -int16_t ivas_spar_chk_zero_coefs( - Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ -); - -void ivas_spar_smooth_md_dtx( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t num_md_sub_frames /* i : number of metadata subframes */ -); - -void ivas_spar_setup_md_smoothing( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t num_md_sub_frames /* i : number of metadata subframes */ -); - -void ivas_spar_dec_gen_umx_mat( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t bfi, /* i : bad frame indicator */ - const int16_t num_md_sub_frames -); - - - - - -/* Transient detector module */ -ivas_error ivas_transient_det_open_fx( - ivas_trans_det_state_t **hTranDet, /* i/o: Transient detector handle */ - const Word32 sampling_rate /* i : sampling rate */ -); - -void ivas_transient_det_close_fx( - ivas_trans_det_state_t **hTranDet /* i/o: Transient detector handle */ -); - -void ivas_transient_det_process( - ivas_trans_det_state_t *hTranDet, /* i/o: SPAR TD handle */ - float *pIn_pcm, /* i : input audio channels */ - const int16_t frame_len, /* i : frame length in samples */ - int16_t transient_det[2] /* o : transient det outputs */ -); - -void ivas_td_decorr_get_ducking_gains( - ivas_trans_det_state_t *hTranDet, /* i/o: Transient detector handle */ - float *pIn_pcm, - float *pIn_duck_gains, - float *pOut_duck_gains, - const int16_t frame_len, - const int16_t tdet_flag -); - -#define IVAS_CMULT_FLOAT( in1_re, in1_im, in2_re, in2_im, out1_re, out1_im ) \ - out1_re = ( in1_re * in2_re ) - ( in1_im * in2_im ); MAC(1); MULT(1); \ - out1_im = ( in1_re * in2_im ) + ( in2_re * in1_im ); MAC(1); MULT(1); - -#define IVAS_CALCULATE_ABS( re, im, out ) \ - out = sqrtf( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); SQRT(1); - -#define IVAS_CALCULATE_RABS( re, out ) \ - out = sqrtf( re * re ); MULT(1); SQRT(1); - -#define IVAS_CALCULATE_SQ_ABS( re, im, out ) \ - out = (float) ( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); - -#define IVAS_RMULT_DOUBLE( in1_re, in2_re, out1_re ) \ - out1_re = ( in1_re * in2_re ); DMULT(1); \ - -#define IVAS_CALCULATE_SQ_ABS_N( re, out ) \ - out = (float) ( re * re ); MULT(1); - -#define IVAS_RMULT_FLOAT( in1_re, in2_re, out1_re ) \ - out1_re = ( in1_re * in2_re ); MULT(1); - - -/* PCA */ -void ivas_pca_enc_init( - PCA_ENC_STATE *hPCA /* i/o: PCA encoder structure */ -); - -void ivas_pca_read_bits( - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - PCA_DEC_STATE *hPCA /* i/o: PCA encoder structure */ -); - -void ivas_pca_dec_init( - PCA_DEC_STATE *hPCA /* i/o: PCA decoder structure */ -); - -void ivas_pca_dec( - PCA_DEC_STATE *hPCA, /* i/o: PCA decoder structure */ - const int16_t n_samples, /* i : output frame length */ - const int16_t n_channels, /* i : number of channels */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ - const int16_t bfi, /* i : bad frame indicator */ - float *pcm_out[] /* o : output audio channels */ -); - -void pca_dec_s3( - const int32_t index, - float *q -); - - -void ivas_huffman_encode_fx( - ivas_huffman_cfg_t *huff_cfg, - Word16 in, - Word16 *hcode, - Word16 *hlen -); - - - -ivas_error ivas_huffman_decode( - ivas_huffman_cfg_t *huff_cfg, - Decoder_State *st0, - int16_t *dec_out -); - -void ivas_arith_decode_cmplx_cell_array( - ivas_arith_t *pArith_re, - ivas_arith_t *pArith_re_diff, - Decoder_State *st0, - ivas_cell_dim_t *pCell_dims, - int16_t *pDo_diff, const int16_t nB, - int16_t *pSymbol_re, - int16_t *pSymbol_re_old -); - - - - -void ivas_ari_done_encoding_14bits( - BSTR_ENC_HANDLE hBstr, Tastat *s -); - - -void ivas_wrap_arround( - int16_t *pArr, - const int16_t min_val, - const int16_t max_val, - const int16_t length -); - -void ivas_get_cum_freq_model( - const int16_t *pFreq_model, - const int16_t length, - int16_t *pCum_freq_model -); - -int16_t ivas_map_num_pred_r_to_idx( - const int16_t num_quant_points_pred_r, - const int16_t active_w_flag -); - -int16_t ivas_map_num_drct_r_to_idx( - const int16_t num_quant_points_drct_r -); - -int16_t ivas_map_num_decd_r_to_idx( - const int16_t num_quant_points_decd_r -); - -/* Quantization utilities */ -void ivas_quantise_real_values( - const float *values, - const int16_t q_levels, - const float min_value, - const float max_value, - int16_t *index, - float *quant, - const int16_t dim -); - - -void ivas_spar_quant_dtx_init( - ivas_spar_md_t *spar_md, - float *min_max -); - -void ivas_map_prior_coeffs_quant( - ivas_spar_md_prev_t *pSpar_md_prior, - ivas_spar_md_com_cfg *pSpar_md_cfg, - const int16_t qsi, - const int16_t nB -); - - -void ivas_clear_band_coeffs( - ivas_band_coeffs_t *pband_coeffs, - const uint16_t num_bands -); - -void ivas_clear_band_coeff_idx( - ivas_band_coeffs_ind_t *pband_coeff_idx, - const uint16_t num_bands -); - - -/*----------------------------------------------------------------------------------* - * MASA prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_masa_decode( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *nb_bits_read /* o : number of bits read */ -); - -void generate_gridEq( - SPHERICAL_GRID_DATA *data /* o : data structure for grid */ -); - -ivas_error ivas_masa_enc_open_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_masa_enc_close_fx( - MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */ -); - -void ivas_masa_enc_reconfigure( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_masa_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ - int16_t *data /* o : output synthesis signal */ -); - -ivas_error ivas_masa_encode( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder structure */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - BSTR_ENC_HANDLE hMetaData, /* i/o: Metadata bitstream handle */ - int16_t *nb_bits_metadata, /* o : number of metadata bits written */ - const int16_t nchan_transport, /* i : number of MASA input/transport channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t Opt_DTX_ON, /* i : DTX on flag */ - const int16_t element_mode, /* i : element mode */ - const ISM_MODE ism_mode, /* i : ISM format mode */ - const int16_t nchan_ism, /* i : number of ISM channels */ - ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata handle */ - const int16_t idx_separated_object, /* i : index of the separated object */ - OMASA_ENC_HANDLE hOMasa, /* i : OMASA encoder handle */ - const int16_t ism_imp, /* i : importance of separated object */ - const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ -); - -void ivas_masa_estimate_energy( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder structure */ - float *data_f[], /* i : Input audio channels */ - const int16_t input_frame, /* i : frame length */ - const int16_t nchan_transport /* i : number of MASA input/transport channels */ -); - - -void ivas_masa_set_elements( - const int32_t ivas_total_brate, /* i : codec total bitrate */ - const int16_t mc_mode, /* i : MC format mode */ - const int16_t nchan_transport, /* i : number of MASA input/transport channels */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - int16_t *element_mode, /* o : element mode */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE, /* o : number of CPEs */ - const int16_t ivas_format, /* i : IVAS format */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const int32_t ism_total_brate /* i : initial ISM total bitrate */ -); - -/*! r: valid or not 1/0 */ -int16_t valid_ratio_index( - int16_t index, /* i : index to be checked */ - const int16_t K, /* i : L1 norm to check against */ - const int16_t len /* i : vector length */ -); - -void reconstruct_ism_ratios( - int16_t *ratio_ism_idx, - const int16_t nchan_ism, - const float step, - float *q_energy_ratio_ism -); - -void distribute_evenly_ism( - int16_t *idx, - const int16_t K, - const int16_t nchan_ism -); - - -int16_t ivas_qmetadata_encode_extended_gr_length_fx( - const uint16_t value, - const uint16_t alphabet_size, - const int16_t gr_param); - -void ivas_qmetadata_encode_extended_gr_fx( - BSTR_ENC_HANDLE hMetaData, /* i/o: q_metadata handle */ - const uint16_t value, /* i : value to be encoded */ - const uint16_t alphabet_size, /* i : alphabet size */ - const int16_t gr_param); /* i : GR order */ - -/*! r: CPE bitrate value */ -int32_t calculate_cpe_brate_MASA_ISM( - const ISM_MODE ism_mode, /* i : ism mode */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism /* i : number of objects */ -); - -void ivas_merge_masa_metadata( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */ - OMASA_SPATIAL_META_HANDLE hOMasaMeta /* i : ISM-object metadata to be merged with the MASA metadata */ -); - - -/*!r : number of bits for ISM ratio index */ -int16_t bits_index_ism_ratio( - const int16_t nchan_ism /* i : number of objects */ -); - -void calculate_nbits_meta( - const int16_t nchan_ism, - float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - const int16_t numSf, - const int16_t numCodingBands, - int16_t* bits_ism, - const int16_t idx_sep_obj, - const int16_t ism_imp -); - -/*! r: limitation flag */ -int16_t calculate_brate_limit_flag( - const int16_t ism_imp[], /* i : ISM importance flags */ - const int16_t nchan_ism /* i : number of objects */ -); - -void ivas_masa_set_coding_config( - MASA_CODEC_CONFIG* config, /* i/o: MASA coding config structure */ - int16_t* band_mapping, /* o : Band mapping used */ - const int32_t ivas_total_brate, /* i : codec total bitrate */ - const int16_t nchan_transport, /* i : number of transport channel (mono/stereo) */ - const uint8_t isMcMasa /* i : toggle for selecting McMASA specific config */ -); - -/*! r: Surround coherence significant flag */ -uint8_t ivas_masa_surrcoh_signicant( - float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Surround coherence */ - float diffuse_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Diffuse to total ratio */ - const int16_t nSubFrames, /* i : Number of sub frames */ - const int16_t nBands /* i : Number of frequency bands */ -); - -void masa_compensate_two_dir_energy_ratio_index( - const int16_t ratio_index_1, /* i : Input ratio for direction 1 */ - const int16_t ratio_index_2, /* i : Input ratio for direction 2 */ - int16_t *ratio_index_mod1, /* o : Output modified ratio for direction 1 */ - int16_t *ratio_index_mod2, /* o : Output modified ratio for direction 2 */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -void ivas_set_qmetadata_maxbit_req_fx( - IVAS_QMETADATA_HANDLE hQMetaData, /* o : qmetadata structure where the requirement value is set */ - const IVAS_FORMAT ivas_format /* i : IVAS format */ -); - -void masa_sample_rate_band_correction( - MASA_CODEC_CONFIG *config, /* i/o: MASA codec config */ - int16_t *band_mapping, /* i/o: Band mapping used and modified */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: QMetadata structure for modification */ - const uint8_t maxBand, /* i : max band */ - uint8_t is_encoder, /* i : signals if called at encoder */ - MASA_DECODER_EXT_OUT_META_HANDLE hExtOutMeta /* i/o: MASA decoder metadata ext out buffer */ -); - -void invdct4_transform( - float *v, /* i : input vector */ - uint8_t *invdct_v /* o : transformed vector */ -); - - -void ivas_spar_param_to_masa_param_mapping( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ - const int16_t subframe /* i : Subframe to map */ -); - -/*---------------------------------------------------------------------------------* - * Binaural FastConv Renderer Prototypes -*-----------------------------------------------------------------------------------*/ - - -void ivas_binaural_hrtf_close( - HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i/o: decoder binaural hrtf handle */ -); - -void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ -); - -void ivas_binaural_add_LFE( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t output_frame, /* i : length of input frame */ - float *input_f[], /* i : transport channels */ - float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */ -); - -/*----------------------------------------------------------------------------------* - * renderer prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ism_renderer_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_ism_renderer_close( - ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ -); - -void ivas_ism_render_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t n_samples_to_render /* i : output frame length per channel */ -); - - -void ivas_mc2sba( - IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ - float *in_buffer_td[], /* i : MC signals (on input) and the HOA3 (on output) */ - float *buffer_td[], /* o : MC signals (on input) and the HOA3 (on output) */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order, /* i : SBA order */ - const float gain_lfe /* i : gain for LFE, 0=ignore LFE */ -); - -void ivas_param_mc_mc2sba_cldfb( - IVAS_OUTPUT_SETUP hTransSetup, /* i : transported MC Format */ - float *hoa_encoder, /* i : HOA3 encoder for the transported MC format */ - const int16_t slot_idx, /* i : current slot in the subframe */ - float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) */ - float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) */ - const int16_t nBands, /* i : number of synth CLDFB bands */ - const float gain_lfe /* i : gain applied to LFE */ -); - - -/*----------------------------------------------------------------------------------* - * Amplitude Panning VBAP prototypes - *----------------------------------------------------------------------------------*/ - -void panning_wrap_angles( - const float azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ - const float ele_deg, /* i : elevation in degrees for panning direction (positive up) */ - float *azi_wrapped, /* o : wrapped azimuth component */ - float *ele_wrapped /* o : wrapped elevation component */ -); - -/*----------------------------------------------------------------------------------* - * LS Renderer prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ls_setup_conversion_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_ls_setup_conversion_close( - LSSETUP_CONVERSION_HANDLE *hLsSetUpConversion /* i/o: LS converter handle */ -); - - -void ivas_ls_setup_conversion( - Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ - const int16_t input_chans, /* i : number of input channels to the renderer */ - const int16_t output_frame, /* i : frame length */ - float *input[], /* i : LS input/output synthesis signal */ - float *output[] /* i/o: LS input/output synthesis signal */ -); - -void ivas_ls_setup_conversion_process_mdct( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[] /* i/o: output synthesis signal */ -); - -void ivas_ls_setup_conversion_process_mdct_param_mc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *x[][NB_DIV] /* i/o: output synthesis signal */ -); - -void ivas_lssetupconversion_process_param_mc( - Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ - const int16_t num_timeslots, /* i : number of time slots to process */ - float Cldfb_RealBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ - float Cldfb_ImagBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ - int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ -); - - -/*----------------------------------------------------------------------------------* - * Custom loudspeaker setup prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ls_custom_open( - LSSETUP_CUSTOM_HANDLE *hLsSetupCustom /* o : Custom loudspeaker setup handle */ -); - - - -/*----------------------------------------------------------------------------------* - * McMASA prototypes - *----------------------------------------------------------------------------------*/ - - -ivas_error ivas_mcmasa_dec_reconfig( - Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ -); - -void ivas_mcmasa_setNumTransportChannels( - int16_t* nchan_transport, /* o : Pointer to number of transport channels to be set */ - int16_t* element_mode, /* o : Pointer to element mode to be set */ - const int32_t ivas_total_brate /* i : Total bitrate of IVAS */ -); - -void ivas_mcmasa_set_separate_channel_mode( - uint8_t *separateChannelEnabled, /* o : Pointer to separate channel toggle */ - int16_t *separateChannelIndex, /* o : Pointer to separate channel index */ - const int32_t ivas_total_brate /* i : Total bitrate of IVAS */ -); - -void ivas_mcmasa_split_brate( - const uint8_t separateChannelEnabled, /* i : Transport running in "separate channel" mode */ - const int32_t ivas_total_brate, /* i : Total bitrate available to be split */ - const int16_t nSCE, /* i : Number of SCEs in use (0 or 1) */ - const int16_t nCPE, /* i : Number of CPEs in use (0 or 1) */ - int32_t *brate_sce, /* o : Pointer to SCE element bitrate */ - int32_t *brate_cpe /* o : Pointer to CPE element bitrate */ -); - - -void ivas_mcmasa_dmx_modify_fx( - const Word16 n_samples, /* i : input frame length in samples */ - Word32 dmx_fx[][L_FRAME48k + NS2SA(48000, IVAS_FB_ENC_DELAY_NS)], /* i/o: downmix signal to be transformed into another format Qx*/ - Word16 dmx_Q[], /* i/o : Q of the intput signal which is being transformed*/ - const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0 */ - const Word16 n_chnls_dmx_new /* i : number of downmix channels in the target format Q0*/ -); - -ivas_error ivas_mono_dmx_renderer_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -void ivas_mono_dmx_renderer_close( - MONO_DOWNMIX_RENDERER_HANDLE *hMonoDmxRenderer /* i/ i/o: Mono downmix structure */ -); - -void ivas_mono_downmix_render_passive( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/mono output */ - const int16_t output_frame /* i : output frame length */ -); - - -/*----------------------------------------------------------------------------------* - * LFE encoder low pass filter prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_create_lfe_lpf_enc( - ivas_filters_process_state_t **hLfeLpf, /* o : LFE LPF handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void ivas_lfe_lpf_enc_close_fx( - ivas_filters_process_state_t **hLfeLpf /* i/o: LFE LPF handle */ -); - -void ivas_lfe_lpf_enc_apply( - ivas_filters_process_state_t *hLfeLpf, /* i/o: LFE LPF handle */ - float data_lfe_ch[], /* i/o: LFE signal */ - const int16_t input_frame /* i : input frame length per channel */ -); - - -/*----------------------------------------------------------------------------------* - * LFE Coding prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_create_lfe_enc_fx( - LFE_ENC_HANDLE *hLFE, /* o : IVAS LFE encoder structure */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void ivas_lfe_enc_close_fx( - LFE_ENC_HANDLE *hLFE /* i/o: LFE encoder handle */ -); - -void ivas_lfe_enc( - LFE_ENC_HANDLE hLFE, /* i/o: LFE encoder handle */ - float data_lfe_ch[], /* i : input LFE signal */ - const int16_t input_frame, /* i : input frame length per channel */ - BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ -); - -void ivas_lfe_tdplc( - LFE_DEC_HANDLE hLFE, /* i/o: LFE decoder handle */ - float *prevsynth, /* i : previous frame synthesis */ - float *ytda, /* o : output time-domain buffer */ - const int16_t output_frame /* i : output frame length */ -); -void ivas_lfe_window_init( - LFE_WINDOW_HANDLE hLFEWindow, /* i/o: LFE window handle */ - const int32_t sampling_rate, /* i : sampling rate */ - const int16_t frame_len /* i : frame length in samples */ -); - -void ivas_lfe_lpf_select_filt_coeff( - const int32_t sampling_rate, /* i : sampling rate */ - const int16_t order, /* i : filter order */ - const float **ppFilt_coeff /* o : filter coefficients */ -); - -void ivas_filters_init( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - const float *filt_coeff, /* i : filter coefficients */ - const int16_t order /* i : filter order */ -); - -void ivas_filters_init_fx( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - const Word32 *filt_coeff_fx, /* i : filter coefficients Q31- *filt_coeff_e */ - const Word16 *filt_coeff_e, /* i : exponents of filter coefficients */ - const Word16 order ) ; - -void ivas_filter_process( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - float *pIn_Out, /* i : signal subject to filtering */ - const int16_t length /* i : filter order */ -); - -void ivas_filter_process_fx( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ - const Word16 length, /* i : filter order */ - Word16 q_factor ); - -/*----------------------------------------------------------------------------------* - * OSBA prototypes - *----------------------------------------------------------------------------------*/ -ivas_error ivas_osba_enc_reconfig( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); -ivas_error ivas_osba_data_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ -); - -ivas_error ivas_osba_dirac_td_binaural_jbm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - - -void ivas_osba_data_close( - SBA_ISM_DATA_HANDLE *hSbaIsmData /* i/o: OSBA rendering handle */ -); - - -/*----------------------------------------------------------------------------------* -* OMASA prototypes -*---------------------------------------------------------------------------------*/ - -ivas_error ivas_omasa_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_omasa_enc_close( - OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */ -); - - -ivas_error ivas_omasa_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ - int16_t *data /* o : output synthesis signal */ -); - - - - -void ivas_set_surplus_brate_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -#ifdef DEBUG_MODE_INFO - , - const int16_t *nb_bits_metadata /* i : number of metadata bits */ -#endif -); - -void ivas_set_surplus_brate_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int32_t *ism_total_brate /* i : ISM total bitrate */ -); - - -void ivas_set_ism_importance_interformat( - const int32_t ism_total_brate, /* i/o: ISms total bitrate */ - const int16_t nchan_transport, /* i : number of transported channels */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */ - const float lp_noise_CPE, /* i : LP filtered total noise estimation */ - int16_t ism_imp[] /* o : ISM importance flags */ -); - - -/*! r: adjusted bitrate */ -int32_t ivas_interformat_brate( - const ISM_MODE ism_mode, /* i : ISM mode */ - const int16_t nchan_ism, /* i : number of ISM channels */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t ism_imp, /* i : ISM importance flag */ - const int16_t limit_flag /* i : flag to limit the bitrate increase */ -); - -void ivas_combined_format_brate_sanity( - const int32_t element_brate, /* i : element bitrate */ - const int16_t core, /* i : core */ - const int32_t total_brate, /* i : total bitrate */ - int32_t *core_brate, /* i/o: core bitrate */ - int16_t *inactive_coder_type_flag, /* o : inactive coder_type flag */ - int16_t *diff_nBits /* o : number of differential bits */ -); - -ISM_MODE ivas_omasa_ism_mode_select( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism /* i : number of input ISM's */ -); - -void ivas_set_omasa_TC( - const ISM_MODE ism_mode, /* i : ISM mode */ - const int16_t nchan_ism, /* i : number of input ISMs */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE /* o : number of CPEs */ -); - -void ivas_merge_masa_transports( - float data_in_f1[][L_FRAME48k], /* i : Transport audio signals 1 */ - float *data_in_f2[], /* i : Transport audio signals 2 */ - float *data_out_f[], /* o : Merged transport audio signals */ - const int16_t input_frame, /* i : Input frame size */ - const int16_t num_transport_channels /* i : Number of transport audio signals */ -); - - -ivas_error ivas_omasa_ism_metadata_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int32_t ism_total_brate, /* i : ISM total bitrate */ - int16_t *nchan_ism, /* o : number of ISM separated channels */ - int16_t *nchan_transport_ism, /* o : number of ISM TCs */ - const int16_t dirac_bs_md_write_idx, /* i : DirAC bitstream write index */ - int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ -); - -void ivas_omasa_preProcessStereoTransportsForMovedObjects( - Decoder_Struct *st_ivas, - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - const int16_t nBins, - const int16_t subframe -); - -ivas_error ivas_omasa_separate_object_renderer_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_omasa_separate_object_renderer_close( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_omasa_separate_object_render_jbm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesRendered, /* i : number of samples rendered */ - float input_f[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* o : rendered time signal */ - const int16_t subframes_rendered, /* i : number of subframes rendered */ - const int16_t slots_rendered /* i : number of CLDFB slots rendered */ -); - -void ivas_omasa_encode_masa_to_total( - float masa_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - BSTR_ENC_HANDLE hMetaData, - const int16_t low_bitrate_mode, - const int16_t nbands, - const int16_t nblocks -); - -void ivas_omasa_decode_masa_to_total( - uint16_t *bit_stream, - int16_t *index, - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - const int16_t nbands, - const int16_t nblocks -); - -void ivas_omasa_modify_masa_energy_ratios( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] -); - - -/*----------------------------------------------------------------------------------* - * TD Binaural Object renderer - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_td_binaural_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -); - -ivas_error ivas_td_binaural_renderer_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ -); - -/*----------------------------------------------------------------------------------* - * Filter-bank (FB) Mixer - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_fb_set_cfg( - IVAS_FB_CFG **pFb_cfg_out, /* o : FB config. handle */ - const int16_t ivas_format, /* i : IVAS format */ - const int16_t num_in_chans, /* i : number of FB input channels */ - const int16_t num_out_chans, /* i : number of FB output channels */ - const int16_t active_w_mixing, /* i : active_w_mixing flag */ - const int32_t sampling_Fs, /* i : sampling rate */ - const int16_t nachan_dirac_ana /* i : number of DirAR analysis channels */ -); - -void ivas_fb_mixer_pcm_ingest( - IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ - float *pcm_in[], /* i : input audio channels */ - float **ppOut_pcm, /* o : output audio channels */ - const int16_t frame_length, /* i : frame length */ - const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] -); - -void ivas_fb_mixer_update_prior_input( - IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ - float *pcm_in[], /* i : input audio channels */ - const int16_t length, /* i : length of time slot */ - const int16_t nchan_fb_in /* i : number of analysis channels */ -); - -void ivas_fb_mixer_get_windowed_fr( - IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ - float *pcm_in[], /* i : input audio channels */ - float *frame_f_real[], /* o : real freq domain values */ - float *frame_f_imag[], /* o : imag freq domain values */ - const int16_t length, /* i : number of new samples in time slot */ - const int16_t mdft_len, /* i : MDFT frame length */ - const int16_t nchan_fb_in /* i : number of analysis channels */ -); - -/*! r: number of spectral bands */ - -/* clang-format on */ diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 8527e6703..85fefadbc 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "cnst.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 422622552..7c7d49381 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -36,7 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 1ab797ded..292721723 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -35,7 +35,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" diff --git a/lib_dec/ivas_ism_dec_fx.c b/lib_dec/ivas_ism_dec_fx.c index 643874a82..44b7a0bec 100644 --- a/lib_dec/ivas_ism_dec_fx.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 3aed4d3b1..24e61c5f3 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -34,7 +34,7 @@ #include #include #include "options.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_ism_renderer_fx.c b/lib_dec/ivas_ism_renderer_fx.c index 7cd93affa..2535eb6ee 100644 --- a/lib_dec/ivas_ism_renderer_fx.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -35,7 +35,7 @@ #include "ivas_cnst.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "rom_com.h" diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 210425b88..fdf18e705 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -37,7 +37,7 @@ #include "rom_com.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index 384865a1a..dec4d3465 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -35,7 +35,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 697ae6345..ff895755d 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -37,7 +37,7 @@ #include "rom_enc.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" @@ -1656,7 +1656,7 @@ void ivas_param_mc_dec_digest_tc_fx( test(); IF( is_next_band && skip_next_band ) { - continue; + CONTINUE; } IF( is_next_band ) { @@ -1697,7 +1697,7 @@ void ivas_param_mc_dec_digest_tc_fx( test(); IF( is_next_band && skip_next_band ) { - continue; + CONTINUE; } /* Cx for transport channels */ IF( is_next_band ) @@ -1794,7 +1794,7 @@ void ivas_param_mc_dec_digest_tc_fx( test(); IF( is_next_band && skip_next_band ) { - continue; + CONTINUE; } IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index 3c2ba7587..762b350d1 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -36,7 +36,7 @@ #include "cnst.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_mcmasa_dec_fx.c b/lib_dec/ivas_mcmasa_dec_fx.c index 1b1715c21..d12b190c6 100644 --- a/lib_dec/ivas_mcmasa_dec_fx.c +++ b/lib_dec/ivas_mcmasa_dec_fx.c @@ -33,7 +33,7 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_core_dec_fx.c b/lib_dec/ivas_mct_core_dec_fx.c index fe39fd8e3..b42eb534b 100644 --- a/lib_dec/ivas_mct_core_dec_fx.c +++ b/lib_dec/ivas_mct_core_dec_fx.c @@ -88,9 +88,9 @@ void ivas_mct_side_bits_fx( FOR( ch = 0; ch < nChannels; ch++ ) { st = sts[ch]; - if ( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } mdct_read_IGF_bits_fx( st, st0 ); @@ -231,7 +231,7 @@ void ivas_mct_core_dec( { IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } i = add( i, 1 ); } @@ -258,15 +258,15 @@ void ivas_mct_core_dec( { st = sts[ch]; - if ( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) /*indicates LFE */ + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) /*indicates LFE */ { - continue; + CONTINUE; } test(); - if ( bfi && EQ_16( st->core, ACELP_CORE ) ) /*no igf processing needed*/ + IF( bfi && EQ_16( st->core, ACELP_CORE ) ) /*no igf processing needed*/ { - continue; + CONTINUE; } IF( EQ_16( st->core, TCX_10_CORE ) ) diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 884a44c9e..abf735b5a 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -38,7 +38,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 35d38d03a..151ba7d1e 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1549,7 +1549,7 @@ void ivas_mdct_core_tns_ns_fx( } /* nothing to do for missing LFE */ - continue; + CONTINUE; } FOR( k = 0; k < nSubframes[ch]; k++ ) diff --git a/lib_dec/ivas_objectRenderer_internal_fx.c b/lib_dec/ivas_objectRenderer_internal_fx.c index b88b68915..79683e402 100644 --- a/lib_dec/ivas_objectRenderer_internal_fx.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index afa604684..9975493fb 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -35,7 +35,7 @@ #include "ivas_cnst.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 6f1a233c9..b048470d4 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -34,7 +34,7 @@ #include #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 84b6fe46d..c7bf0655d 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -35,7 +35,7 @@ #include #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index f04350366..eb2a40ecb 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -36,7 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/ivas_sba_rendering_internal_fx.c b/lib_dec/ivas_sba_rendering_internal_fx.c index 8748342ed..bbe63e965 100644 --- a/lib_dec/ivas_sba_rendering_internal_fx.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include @@ -319,7 +319,7 @@ Word16 ivas_sba_remapTCs_fx( Copy32( sba_data_fx[2], sba_data_fx[3], output_frame ); /*Q11*/ } } - IF( GT_16( st_ivas->nchan_transport, 3 ) ) + IF( GE_16( st_ivas->nchan_transport, 3 ) ) { Word16 i = 0; move16(); diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index fd25e7ea7..3bc6d337e 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -372,7 +372,7 @@ void dequantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - continue; + CONTINUE; } nStages = SNS_MSVQ_NSTAGES_SIDE; diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index 34a194898..c6c7565a9 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -37,7 +37,7 @@ #include "ivas_stat_dec.h" #include "prot_fx.h" #include "string.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index ef3baee3c..dc06ddc5a 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -35,7 +35,7 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 7c28c3309..e6fc25e36 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -5401,7 +5401,7 @@ void TNSAnalysisStereo_fx( st = sts[ch]; IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } hTcxEnc = st->hTcxEnc; diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 6623cfd45..9256be408 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -476,7 +476,7 @@ void ivas_ism_coh_estim_dtx_enc_fx( { hISMDTX->coh_fx[sce_id] = 32767; /* 1 in Q15 */ move16(); - continue; + CONTINUE; } st = hSCE[sce_id]->hCoreCoder[0]; diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 3272768e9..9027b2669 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -2543,7 +2543,7 @@ void ivas_mdct_quant_coder_fx( { ignore_chan[ch] = 1; move16(); - continue; + CONTINUE; } IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) @@ -2615,7 +2615,7 @@ void ivas_mdct_quant_coder_fx( IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } FOR( n = 0; n < nSubframes; n++ ) @@ -2646,7 +2646,7 @@ void ivas_mdct_quant_coder_fx( IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } FOR( n = 0; n < nSubframes; n++ ) @@ -2730,9 +2730,9 @@ void ivas_mdct_quant_coder_fx( * Generate Bitstream *---------------------------------------------------------------*/ - if ( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } nbits_start = st->hBstr->nb_bits_tot; move16(); diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 93ee56461..dfd207c3e 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -680,7 +680,7 @@ Word16 quantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - continue; + CONTINUE; } nStages = SNS_MSVQ_NSTAGES_SIDE; diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index b1a3f2f20..44f415dc7 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -586,7 +586,7 @@ void swb_bwe_enc_ivas_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_exp, Q_synth ); + SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_exp, new_input_fx_exp ); } ELSE { @@ -3456,11 +3456,12 @@ static Word16 SWB_BWE_encoding_ivas_fx( global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ - Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, 0 ); - mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, sub( Q_synth, Q16 ), Q_shb, st_fx ); + scale = s_min( L_norm_arr( yos_fx, inner_frame ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, scale ); + mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, sub( add( Q_synth, scale ), Q16 ), Q_shb, st_fx ); push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); - energy_control_ivas_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, sub( Q_synth_lf, Q16 ) ); + energy_control_ivas_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); FOR( n_band = 0; n_band < SWB_FENV; n_band++ ) { diff --git a/lib_rend/ivas_allrad_dec_fx.c b/lib_rend/ivas_allrad_dec_fx.c index 770b62764..5023bee34 100644 --- a/lib_rend/ivas_allrad_dec_fx.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -36,7 +36,7 @@ #include #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_crend_fx.c b/lib_rend/ivas_crend_fx.c index e50ad32e1..36d18f859 100644 --- a/lib_rend/ivas_crend_fx.c +++ b/lib_rend/ivas_crend_fx.c @@ -34,7 +34,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 1a5013059..8124c4967 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -33,7 +33,7 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 0deb14c9b..65a68889a 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -35,7 +35,7 @@ #include #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_binauralRenderer.h" #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index b8b3c3ac7..1ffe0da74 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -36,7 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_dirac_onsets_dec_fx.c b/lib_rend/ivas_dirac_onsets_dec_fx.c index e9af8483a..80adebfdd 100644 --- a/lib_rend/ivas_dirac_onsets_dec_fx.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 40ed0ad58..6cf11887e 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -36,7 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 35fedfc81..031a39855 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -36,7 +36,7 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_efap_fx.c b/lib_rend/ivas_efap_fx.c index 7a74e62da..543decbdd 100644 --- a/lib_rend/ivas_efap_fx.c +++ b/lib_rend/ivas_efap_fx.c @@ -36,7 +36,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_hrtf_fx.c b/lib_rend/ivas_hrtf_fx.c index e3965fbff..93f9fbd83 100644 --- a/lib_rend/ivas_hrtf_fx.c +++ b/lib_rend/ivas_hrtf_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_limiter_fx.c b/lib_rend/ivas_limiter_fx.c index b66127e09..b212e5445 100644 --- a/lib_rend/ivas_limiter_fx.c +++ b/lib_rend/ivas_limiter_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" #include diff --git a/lib_rend/ivas_masa_merge_fx.c b/lib_rend/ivas_masa_merge_fx.c index c74477365..fd20a9fab 100644 --- a/lib_rend/ivas_masa_merge_fx.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "lib_rend.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index e17b2f9f6..f3b4d1755 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -35,7 +35,7 @@ #include #include "ivas_cnst.h" #include "options.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_objectRenderer_fx.c b/lib_rend/ivas_objectRenderer_fx.c index 7b1e1fe91..1b5bc0d1b 100644 --- a/lib_rend/ivas_objectRenderer_fx.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -34,7 +34,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index a7f46b2a4..01e35efe1 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "prot_fx.h" #include -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_objectRenderer_mix_fx.c b/lib_rend/ivas_objectRenderer_mix_fx.c index 7ee6c828b..0e61282d4 100644 --- a/lib_rend/ivas_objectRenderer_mix_fx.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_TdBinauralRenderer.h" #include "ivas_error.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_objectRenderer_sfx_fx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c index 971e2c2d1..210706d5b 100644 --- a/lib_rend/ivas_objectRenderer_sfx_fx.c +++ b/lib_rend/ivas_objectRenderer_sfx_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 307d38351..5787ded3f 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_objectRenderer_vec_fx.c b/lib_rend/ivas_objectRenderer_vec_fx.c index 4d259a68e..0d8c11aab 100644 --- a/lib_rend/ivas_objectRenderer_vec_fx.c +++ b/lib_rend/ivas_objectRenderer_vec_fx.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -87,28 +87,6 @@ Word32 TDREND_SPATIAL_VecNorm_fx( return tmp; } - -/*-------------------------------------------------------------------* - * TDREND_SPATIAL_VecNormalize() - * - * Normalize vector to unit norm - *-------------------------------------------------------------------*/ - -void TDREND_SPATIAL_VecNormalize( - const float *Vec_p, /* i : Input vector */ - float *VecNorm_p /* o : Output vector */ -) -{ - float scaler; - - scaler = inv_sqrt( Vec_p[0] * Vec_p[0] + Vec_p[1] * Vec_p[1] + Vec_p[2] * Vec_p[2] ); - VecNorm_p[0] = scaler * Vec_p[0]; - VecNorm_p[1] = scaler * Vec_p[1]; - VecNorm_p[2] = scaler * Vec_p[2]; - - return; -} - void TDREND_SPATIAL_VecNormalize_fx( const Word32 *Vec_p_fx, /* i : Input vector q */ Word16 q, /* i : Input vector Q-factor */ @@ -172,25 +150,6 @@ void TDREND_SPATIAL_VecMapToNewCoordSystem_fx( return; } -void TDREND_SPATIAL_VecMapToNewCoordSystem( - const float *Vec_p, /* i : Input vector */ - const float *TranslVec_p, /* i : Translation vector */ - const float *DirVec_p, /* i : Direction vector */ - const float *UpVec_p, /* i : Up vector */ - const float *RightVec_p, /* i : Right vector */ - float *MappedVec_p, /* o : Transformed vector */ - float *LisRelPosAbs /* o : Transformed vector ignoring orientation */ -) -{ - v_sub( Vec_p, TranslVec_p, LisRelPosAbs, 3 ); - /* Evalute the relative Vec in the coordinates of the Orientation vectors, */ - /* which form an orthonormal basis */ - MappedVec_p[0] = dotp( LisRelPosAbs, DirVec_p, 3 ); - MappedVec_p[1] = dotp( LisRelPosAbs, RightVec_p, 3 ); - MappedVec_p[2] = dotp( LisRelPosAbs, UpVec_p, 3 ); - return; -} - /*-------------------------------------------------------------------* * TDREND_SPATIAL_EvalOrthonormOrient() * diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index 5e175fae5..ba632c6ba 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -34,7 +34,7 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_stat_rend.h" diff --git a/lib_rend/ivas_orient_trk_fx.c b/lib_rend/ivas_orient_trk_fx.c index a124bf4bd..a25a8db53 100644 --- a/lib_rend/ivas_orient_trk_fx.c +++ b/lib_rend/ivas_orient_trk_fx.c @@ -33,7 +33,7 @@ #include "common_api_types.h" #include #include "options.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include #include diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 6fba496d5..9945d630e 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -34,7 +34,7 @@ #include "options.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c index 74be74497..8beb5a0ec 100644 --- a/lib_rend/ivas_output_init_fx.c +++ b/lib_rend/ivas_output_init_fx.c @@ -1,6 +1,6 @@ #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #ifdef FIX_DISCLAIMER #include #endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend_fx.h similarity index 69% rename from lib_rend/ivas_prot_rend.h rename to lib_rend/ivas_prot_rend_fx.h index b642e05d7..04afce118 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -93,25 +93,6 @@ ivas_error get_channel_config( * Limiter prototypes *----------------------------------------------------------------------------------*/ - -ivas_error ivas_limiter_open( - IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ - const int16_t num_channels, /* i : number of I/O channels */ - const int32_t sampling_rate /* i : sampling rate for processing */ -); - -void ivas_limiter_close( - IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ -); - -void ivas_limiter_dec -( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ - const int16_t num_channels, /* i : number of channels to be processed */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const int16_t BER_detect /* i : BER detect flag */ -); void ivas_limiter_dec_fx( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ Word32 *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ @@ -120,13 +101,7 @@ void ivas_limiter_dec_fx( const Word16 BER_detect, /* i : BER detect flag */ Word16 q_factor /* i : Q factor of the output samples */ ); -void limiter_process( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ - const float threshold, /* i : signal amplitude above which limiting starts to be applied */ - const int16_t BER_detect, /* i : BER detect flag */ - int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ -); + void limiter_process_fx( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ @@ -140,9 +115,9 @@ void limiter_process_fx( *----------------------------------------------------------------------------------*/ ivas_error ivas_td_decorr_dec_open_fx( ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t nchan_internal, /* i : number of internal channels */ - const int16_t ducking_flag /* i : ducking flag */ + const Word32 output_Fs, /* i : output sampling rate */ + const Word16 nchan_internal, /* i : number of internal channels */ + const Word16 ducking_flag /* i : ducking flag */ ); void ivas_td_decorr_dec_close( ivas_td_decorr_state_t **hTdDecorr /* i/o: TD decorrelator handle */ @@ -179,9 +154,6 @@ ivas_error efap_init_data_fx( const Word16 num_speaker_nodes, /* i : number of speaker nodes in the set */ const Word16 efap_mode /* i : indicates whether EFAP or EFIP is used */ ); -void efap_free_data( - EFAP_HANDLE *hEFAPdata /* i/o: EFAP handle to be freed */ -); void efap_determine_gains_fx( EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ @@ -224,14 +196,7 @@ void ivas_sba_prototype_renderer_fx( Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME], - const int16_t subframe /* i : Subframe to render */ -); - -void ivas_sba_prototype_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ - const int16_t subframe /* i : Subframe to render */ + const Word16 subframe /* i : Subframe to render */ ); ivas_error ivas_sba_get_hoa_dec_matrix_fx( @@ -244,11 +209,7 @@ void ivas_dirac_dec_binaural_sba_gain_fx( const Word16 nchan_remapped, /* i : num channels after remapping of TCs */ const Word16 output_frame /* i : output frame length */ ); -void ivas_dirac_dec_binaural_sba_gain( - float *output[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ - const int16_t output_frame /* i : output frame length */ -); + void ivas_dirac_dec_binaural_render_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -274,11 +235,6 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs_fx( HRTFS_PARAMBIN_HANDLE *hHrtfParambin /* i/o: HRTF structure for rendering */ ); -ivas_error ivas_dirac_dec_binaural_copy_hrtfs( - HRTFS_PARAMBIN_HANDLE *hHrtfParambin /* i/o: HRTF structure for rendering */ -); - - ivas_error ivas_dirac_alloc_mem_fx( DIRAC_REND_HANDLE hDirACRend, const RENDERER_TYPE renderer_type, @@ -286,20 +242,6 @@ ivas_error ivas_dirac_alloc_mem_fx( DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem, const Word16 hodirac_flag); -void ivas_dirac_free_mem( - DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem -); - -void initDiffuseResponses( - float *diffuse_response_function, - const int16_t num_channels, - const AUDIO_CONFIG output_config, - const IVAS_OUTPUT_SETUP hOutSetup, - const int16_t ambisonics_order, - const IVAS_FORMAT ivas_format, - int16_t *num_ele_spk_no_diffuse_rendering, - const AUDIO_CONFIG transport_config -); void ivas_dirac_free_mem_fx( DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem ); @@ -341,18 +283,6 @@ void protoSignalComputation_shd_fx( Word32 *p_Rmat_fx, /* Q30 */ Word16 q_cldfb ); -void protoSignalComputation_shd( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float *proto_direct_buffer_f, - float *proto_diffuse_buffer_f, - float *reference_power, - const int16_t slot_index, - const int16_t num_inputs, - const int16_t num_outputs_diff, - const int16_t num_freq_bands, - float *p_Rmat -); void protoSignalComputation1_fx( Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/ @@ -370,17 +300,6 @@ void protoSignalComputation1_fx( const Word16 num_freq_bands, Word16 q_cldfb ); -void protoSignalComputation1( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float *proto_frame_f, - float *proto_direct_buffer_f, - float *reference_power, - float *proto_power_smooth, - const int16_t slot_index, - const int16_t num_outputs_diff, - const int16_t num_freq_bands -); void protoSignalComputation2_fx( Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/ @@ -399,18 +318,6 @@ void protoSignalComputation2_fx( MASA_STEREO_TYPE_DETECT *stereo_type_detect, Word16 q_cldfb ); -void protoSignalComputation2( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float *proto_frame_f, - float *proto_direct_buffer_f, - float *reference_power, - float *proto_power_smooth, - const int16_t isloudspeaker, - const int16_t slot_index, - const int16_t num_freq_bands, - MASA_STEREO_TYPE_DETECT *stereo_type_detect -); void protoSignalComputation4_fx( Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/ @@ -432,11 +339,6 @@ void protoSignalComputation4_fx( Word16 q_cldfb ); -void ivas_dirac_dec_compute_diffuse_proto( - DIRAC_REND_HANDLE hDirACRend, - const int16_t num_freq_bands, - const int16_t slot_idx -); void ivas_dirac_dec_compute_diffuse_proto_fx( DIRAC_REND_HANDLE hDirACRend, const Word16 num_freq_bands, @@ -453,10 +355,6 @@ void computeDirectionAngles_fx( Word16 *elevation ); -void ivas_masa_init_stereotype_detection( - MASA_STEREO_TYPE_DETECT *stereo_type_detect -); - void ivas_masa_init_stereotype_detection_fx( MASA_STEREO_TYPE_DETECT *stereo_type_detect ); @@ -464,9 +362,6 @@ void ivas_masa_init_stereotype_detection_fx( void ivas_masa_stereotype_detection_fx( MASA_STEREO_TYPE_DETECT *stereo_type_detect ); -void ivas_masa_stereotype_detection( - MASA_STEREO_TYPE_DETECT *stereo_type_detect -); void ivas_lfe_synth_with_cldfb_fx( MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, @@ -487,21 +382,6 @@ void rotateAziEle_DirAC_fx( const Word16 band2, /* i : bands to work on (upper bound) */ const Word32 *p_Rmat_fx /* i : pointer to real-space rotation matrix q30*/ ); -void rotateAziEle_DirAC( - int16_t *azi, - int16_t *ele, - const int16_t band1, - const int16_t band2, - const float *p_Rmat -); - -ivas_error ivas_dirac_dec_onset_detection_open( - const int16_t num_channels, - const int16_t num_freq_bands, - const int16_t max_band_decorr, - DIRAC_ONSET_DETECTION_PARAMS *ph_dirac_onset_detection_params, - DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state -); ivas_error ivas_dirac_dec_onset_detection_open_fx( const Word16 num_protos_diff, //Q0 @@ -522,14 +402,6 @@ ivas_error ivas_dirac_dec_decorr_open_fx( const Word32 output_Fs /* i : output sampling rate */ ); -void ivas_dirac_dec_onset_detection_process( - const float *input_power_f, - float *onset_filter, - const int16_t num_protos_diff, - DIRAC_ONSET_DETECTION_PARAMS h_dirac_onset_detection_params, - DIRAC_ONSET_DETECTION_STATE h_dirac_onset_detection_state -); - void ivas_dirac_dec_onset_detection_process_fx( const Word32 *input_power_f, /* Q(0) */ Word32 *onset_filter, /* Q(0) */ @@ -538,33 +410,6 @@ void ivas_dirac_dec_onset_detection_process_fx( DIRAC_ONSET_DETECTION_STATE h_dirac_onset_detection_state ); -ivas_error ivas_dirac_dec_decorr_open( - DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params, - DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state, - const int16_t num_freq_bands, - int16_t num_outputs_diff, - const int16_t num_protos_diff, - const DIRAC_SYNTHESIS_CONFIG synthesisConf, - float *frequency_axis, - const int16_t nchan_transport, /* i : number of transport channels */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void ivas_dirac_dec_decorr_process( - const int16_t num_freq_bands, - int16_t num_channels, - const int16_t num_protos_diff, - const DIRAC_SYNTHESIS_CONFIG synthesisConf, - const int16_t nchan_transport, /* i : number of transport channels */ - const float *input_frame_f, - const int16_t num_protos_dir, - const int16_t *proto_index_dir, - float *frame_dec_f, - float *onset_filter, - HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params, - HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state -); - void ivas_dirac_dec_decorr_process_fx( const Word16 num_freq_bands, Word16 num_channels, @@ -582,32 +427,11 @@ void ivas_dirac_dec_decorr_process_fx( HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state ); -void ivas_dirac_dec_decorr_close( - HANDLE_DIRAC_DECORR_PARAMS *ph_dirac_decorr_params, - HANDLE_DIRAC_DECORR_STATE *ph_dirac_decorr_state -); void ivas_dirac_dec_decorr_close_fx( HANDLE_DIRAC_DECORR_PARAMS *ph_dirac_decorr_params, HANDLE_DIRAC_DECORR_STATE *ph_dirac_decorr_state ); - -ivas_error ivas_dirac_dec_output_synthesis_open( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const RENDERER_TYPE renderer_type, /* i : renderer type */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -void ivas_dirac_dec_output_synthesis_init( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t nchan_out_woLFE, /* i : number of output audio channels without LFE */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - ivas_error ivas_dirac_dec_output_synthesis_open_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ @@ -627,9 +451,7 @@ void ivas_dirac_dec_output_synthesis_init_fx( void ivas_dirac_dec_output_synthesis_close_fx( DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */ ); -void ivas_dirac_dec_output_synthesis_close( - DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */ -); + void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power */ const Word16 q_reference_power, /* i : Estimated power */ @@ -648,23 +470,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word16 md_idx, const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */ const Word16 dec_param_estim); -void ivas_dirac_dec_output_synthesis_process_slot( - const float *reference_power, /* i : Estimated power */ - const float *onset, /* i : onset filter */ - const int16_t *azimuth, - const int16_t *elevation, - const float *diffuseness, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t sh_rot_max_order, - const float *p_Rmat, /* i : rotation matrix */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t ind_slot, /* i : index of the slot to be added to the input covariance */ - const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - const int16_t dec_param_estim /* i : flag to indicate parameter estimation mode */ -); void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ @@ -681,19 +486,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( Word16 *q_cy_auto_diff_smooth_prev ); -void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t nbslots, /* i : number of slots to process */ - const float *onset_filter, - float *diffuseness, - const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - const int16_t dec_param_estim /* i : flag to indicate parameter estimation mode */ -); - void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ @@ -708,25 +500,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word16 *q_Cldfb ); -void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t nbslots, /* i : number of slots to process */ - float *diffuseness_vector, /* i : diffuseness (needed for direction smoothing)*/ - float *reference_power_smooth, - float qualityBasedSmFactor, - const int16_t enc_param_start_band -); - -void compute_hoa_encoder_mtx( - const float *azimuth, - const float *elevation, - float *response, - const int16_t num_responses, - const int16_t ambisonics_order ); - void compute_hoa_encoder_mtx_fx( const Word32 *azimuth, /*q22*/ const Word32 *elevation, /*q22*/ @@ -751,21 +524,6 @@ void ivas_dirac_dec_compute_power_factors_fx( Word32 *diffuse_power_factor ); -void ivas_dirac_dec_compute_directional_responses( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const int16_t *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */ - MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */ - const int16_t *azimuth, - const int16_t *elevation, - const int16_t md_idx, - const float *surCohRatio, - const int16_t shd_rot_max_order, /* i : split-order rotation method */ - const float *p_Rmat, /* i : rotation matrix */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - void ivas_dirac_dec_compute_directional_responses_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ @@ -782,36 +540,6 @@ void ivas_dirac_dec_compute_directional_responses_fx( const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */ ); -void ivas_dirac_dec_get_frequency_axis( - float *frequency_axis, /* o : array of center frequencies of a real filter bank */ - const int32_t output_Fs, /* i : sampling frequency */ - const int16_t num_freq_bands /* i : number of frequency bands */ -); - -ivas_error ivas_spat_hSpatParamRendCom_config( - SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, - const DIRAC_CONFIG_FLAG flag_config_inp, /* i/ : Flag determining if we open or reconfigure the DirAC decoder */ - const int16_t dec_param_estim_flag, - const IVAS_FORMAT ivas_format, - const MC_MODE mc_mode, - const int32_t output_Fs, - const int16_t hodirac_flag, - const int16_t masa_ext_rend_flag -); - -void ivas_spat_hSpatParamRendCom_close( - SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out -); - -void ivas_dirac_rend_close( - DIRAC_REND_HANDLE *hDirACRend_out -); - -ivas_error ivas_dirac_allocate_parameters( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ -); - void ivas_dirac_rend_close_fx( DIRAC_REND_HANDLE *hDirACRend_out ); @@ -833,18 +561,14 @@ ivas_error ivas_spat_hSpatParamRendCom_config_fx( ivas_error ivas_dirac_allocate_parameters_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ + const Word16 params_flag /* i : set of parameters flag */ ); void ivas_dirac_deallocate_parameters_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ + const Word16 params_flag /* i : set of parameters flag */ ); -void ivas_dirac_deallocate_parameters( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ -); void ivas_masa_ext_dirac_render_fx( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA renderer structure */ Word32 *output_f[], /* i/o: input/output signals in time domain q11*/ @@ -862,11 +586,6 @@ void ivas_HRTF_binary_close_fx( TDREND_HRFILT_FiltSet_t **hHrtfTD /* i/o: TD renderer HRTF handle */ ); -ivas_error ivas_HRTF_fastconv_binary_open( - HRTFS_FASTCONV **hHrtfFastConv /* i/o: FASTCONV HRTF structure */ -); - - ivas_error ivas_HRTF_fastconv_binary_open_fx( HRTFS_FASTCONV **hHrtfFastConv /* i/o: FASTCONV HRTF structure */ ); @@ -910,33 +629,6 @@ ivas_error ivas_td_binaural_renderer_unwrap_fx( const Word16 num_subframes /* i : number of subframes to render */ ); -ivas_error ivas_td_binaural_renderer_unwrap( - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD binaural object renderer handle */ - const int16_t num_src, /* i : number of sources to render */ - const int16_t lfe_idx, /* i : LFE channel index */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ - const int16_t ism_md_subframe_update, - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t num_subframes /* i : number of subframes to render */ -); - -ivas_error ivas_td_binaural_renderer_ext( - const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ - const AUDIO_CONFIG inConfig, /* i : Input audio configuration */ - const LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */ - const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData,/* i : Combined head and external orientations */ - const IVAS_ISM_METADATA *currentPos, /* i : Object position */ - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const int16_t ism_md_subframe_update_ext, /* i : Metadata Delay in subframes to sync with audio delay */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t output_frame, /* i : output frame length */ - float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ -); ivas_error ivas_td_binaural_renderer_ext_fx( const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ const AUDIO_CONFIG inConfig, /* i : Input audio configuration */ @@ -964,24 +656,12 @@ ivas_error ivas_td_binaural_open_unwrap_fx( Word16 *SrcInd ); -ivas_error ivas_td_binaural_open_unwrap( - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ - const int32_t output_Fs, /* i : Output sampling rate */ - const int16_t nchan_transport, /* i : Number of channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - const float *directivity, /* i : Directivity pattern (used for ISM) */ - const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ - BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ - int32_t *binaural_latency_ns /* i : Binauralization delay */ -); - ivas_error ivas_td_binaural_open_ext_fx( TDREND_WRAPPER *pTDRend, const AUDIO_CONFIG inConfig, RENDER_CONFIG_DATA *hRendCfg, /* i : Renderer configuration */ LSSETUP_CUSTOM_STRUCT *customLsInput, - const int32_t output_Fs, + const Word32 output_Fs, Word16 *SrcInd, Word16 *num_src ); @@ -990,17 +670,6 @@ void ivas_td_binaural_close_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */ ); -void ivas_td_binaural_close( - BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */ -); - -ivas_error TDREND_GetMix( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - float *output[], /* i/o: ISM object synth/rendered output in 0,1 */ - const int16_t subframe_length, /* i/o: subframe length */ - const int16_t subframe_idx, /* i : Subframe index to 5 ms subframe */ - const int16_t ism_md_subframe_update /* i : Number of subframes to delay metadata to sync with audio */ -); ivas_error TDREND_GetMix_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 */ @@ -1009,13 +678,6 @@ ivas_error TDREND_GetMix_fx( const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */ ); - -ivas_error TDREND_Update_object_positions( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ - const int16_t num_src, /* i : number of sources to render */ - const IVAS_FORMAT in_format, /* i : Format of input sources */ - const ISM_METADATA_HANDLE *hIsmMetaData /* i : Input metadata for ISM objects */ -); void BSplineModelEvalDealloc_fx( ModelParams_t *model, /* i : Model parameters */ ModelEval_t *modelEval /* i : Model evaluation structure */ @@ -1057,16 +719,7 @@ ivas_error TDREND_MIX_SRC_SetPos_fx( const Word16 SrcInd, /* i : Source index */ const Word32 *Vec_p /* i : Position vector */ ); -ivas_error TDREND_MIX_SRC_SetPos( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float *Vec_p /* i : Position vector */ -); -ivas_error TDREND_MIX_SRC_SetDir( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float *Vec_p /* i : Direction vector */ -); + ivas_error TDREND_MIX_SRC_SetDir_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ @@ -1116,19 +769,8 @@ void TDREND_SRC_Init_fx( TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ const TDREND_PosType_t PosType /* i : Position type specifier */ ); -void TDREND_SRC_Init( - TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ - const TDREND_PosType_t PosType /* i : Position type specifier */ -); /* ----- Object renderer - vec ----- */ - -void TDREND_SPATIAL_VecInit( - float *Pos_p, /* o : Output vector */ - const float PosX, /* i : X value */ - const float PosY, /* i : Y value */ - const float PosZ /* i : Z value */ -); void TDREND_SPATIAL_VecInit_fx( Word32 *Pos_p, /* o : Output vector */ const Word32 PosX, /* i : X value */ @@ -1144,21 +786,6 @@ void TDREND_SPATIAL_VecNormalize_fx( Word32 *VecNorm_p_fx /* o : Normalised output vector Q30 */ ); -void TDREND_SPATIAL_VecNormalize( - const float *Vec_p, /* i : Input vector */ - float *VecNorm_p /* o : Output vector */ -); - -void TDREND_SPATIAL_VecMapToNewCoordSystem( - const float *Vec_p, /* i : Input vector */ - const float *TranslVec_p, /* i : Translation vector */ - const float *DirVec_p, /* i : Direction vector */ - const float *UpVec_p, /* i : Up vector */ - const float *RightVec_p, /* i : Right vector */ - float *MappedVec_p, /* o : Transformed vector */ - float *LisRelPosAbs /* o : Transformed vector ignoring orientation */ -); - Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx( Word32 *FrontVecON_p_fx, /* i/o: Normalized front vector Q30 */ Word32 *UpVecON_p_fx, /* i/o: Normalized up vector Q30 */ @@ -1167,14 +794,6 @@ Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx( const Word32 *UpVec_p_fx, /* i : Input up vector orient_q */ const Word16 orient_q /* i : Input up Q-factor */ ); -/*! r: Flag if the orientation has been updated */ -int16_t TDREND_SPATIAL_EvalOrthonormOrient( - float *FrontVecON_p, /* o : Normalized front vector */ - float *UpVecON_p, /* o : Normalized up vector */ - float *RightVecON_p, /* o : Normalized right vector */ - const float *FrontVec_p, /* i : Input front vector */ - const float *UpVec_p /* i : Input up vector */ -); /* ----- Object renderer - mix ----- */ @@ -1183,11 +802,6 @@ ivas_error TDREND_MIX_AddSrc_fx( Word16 *SrcInd, /* o : Source index */ const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ ); -ivas_error TDREND_MIX_AddSrc( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - int16_t *SrcInd, /* o : Source index */ - const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ -); ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -1198,35 +812,15 @@ void TDREND_MIX_Dealloc_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ ); -void TDREND_MIX_Dealloc( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ -); - ivas_error TDREND_MIX_Init_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */ const Word32 output_Fs /* i : Output sampling rate */ ); -ivas_error TDREND_MIX_Init( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ - const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */ - const int32_t output_Fs /* i : Output sampling rate */ -); /* ----- Object renderer - sfx ----- */ -void TDREND_Apply_ITD( - float *input, /* i : Input SCE subframe to be time adjusted */ - float *out_left, /* o : Output left channels with ITD applied */ - float *out_right, /* o : Output right channels with ITD applied */ - int16_t *previtd, /* i/o: Previous ITD value */ - const int16_t itd, /* i : Current subframe ITD value */ - float *mem_itd, /* i/o: ITD buffer memory */ - const int16_t length /* i : Subframe length */ -); - void TDREND_Apply_ITD_fx( Word32 *input_fx, /* i : Input subframe to be time adjusted Qx */ Word32 *out_left_fx, /* o : Output left channel with ITD applied Qx */ @@ -1319,10 +913,10 @@ ivas_error ivas_binaural_reverb_open_fastconv_fx( ivas_error ivas_binaural_reverb_open_parambin( REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const int16_t numBins, /* i : number of CLDFB bins Q0 */ - const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ + const Word16 numBins, /* i : number of CLDFB bins Q0 */ + const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate Q0 */ + const Word32 sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ); @@ -1333,16 +927,6 @@ void ivas_binaural_reverb_close( REVERB_STRUCT_HANDLE *hReverb /* i/o: binaural reverb handle */ ); -void ivas_binaural_reverb_processSubframe( - REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ - const int16_t numInChannels, /* i : num input channels to be processed*/ - const int16_t numSlots, /* i : number of slots to be processed */ - float inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real */ - float inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ - float outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ - float outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o : output CLDFB data imag */ -); - void ivas_binaural_reverb_processSubframe_fx( REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ const Word16 numInChannels, /* i : num inputs to be processed */ @@ -1373,14 +957,7 @@ ivas_error ivas_reverb_process_fx( Word32 *pcm_out[], /* o : the PCM audio with reverb applied */ const Word16 i_ts /* i : (Q0) subframe index */ ); -ivas_error ivas_reverb_process( - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ - const int16_t mix_signals, /* i : add reverb to output signal */ - float *pcm_in[], /* i : the PCM audio to apply reverb on */ - float *pcm_out[], /* o : the PCM audio with reverb applied */ - const int16_t i_ts /* i : subframe index */ -); + void ivas_rev_delay_line_init( ivas_rev_delay_line_t *pDelay, /* o : the delay line to initialize */ Word32 *memory_buffer, /* i : the memory buffer to use for the delay line Q11 */ @@ -1410,7 +987,7 @@ void ivas_rev_delay_line_feed_sample_blk_fx( ); void ivas_reverb_iir_filt_init( ivas_rev_iir_filter_t *iirFilter, /* o : IIR filter */ - const uint16_t maxTaps /* i : maximum number of filter taps */ + const UWord16 maxTaps /* i : maximum number of filter taps */ ); @@ -1469,17 +1046,6 @@ void ivas_reverb_fft_filter_CrossMix_fx( const Word16 fft_size ); -void ivas_reverb_fft_filter_CrossMix( - float *buffer0, - float *buffer1, - const int16_t fft_size -); - -void ivas_reverb_fft_filter_ConvertFFTWF_2_FFTR( - rv_fftwf_type_complex *spectrum, - float *fft_real, - const int16_t fft_size -); void ivas_reverb_fft_filter_ConvertFFTWF_2_FFTR_fx( rv_fftwf_type_complex_fx *spectrum, // i: Qx Word32 *fft_real, // o: Qx @@ -1620,47 +1186,21 @@ void ivas_headTrack_close_fx( HEAD_TRACK_DATA_HANDLE *hHeadTrackData /* i/o: head track handle */ ); -void Euler2Quat( - const float yaw, /* i : yaw (x) */ - const float pitch, /* i : pitch (y) */ - const float roll, /* i : roll (z) */ - IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ -); void Euler2Quat_fx( const Word32 yaw, /* i : yaw (x) Q22 */ const Word32 pitch, /* i : pitch (y) Q22 */ const Word32 roll, /* i : roll (z) Q22 */ IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ ); -float deg2rad( - float degrees -); Word32 deg2rad_fx( Word32 degrees ); -float rad2deg( - float radians -); Word32 rad2deg_fx( Word32 radians ); -void QuatToRotMat( - const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ - float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ -); - - -void rotateAziEle( - float azi_in, /* i : output elevation */ - float ele_in, /* i : input elevation */ - int16_t *azi, /* o : rotated azimuth */ - int16_t *ele, /* o : rotated elevation */ - float Rmat[3][3], /* i : real-space rotation matrix */ - const int16_t isPlanar /* i : is roation planar and elevation meaningless? */ -); void rotateAziEle_fx( Word16 azi_in, /* i : output elevation */ Word16 ele_in, /* i : input elevation */ @@ -1734,21 +1274,21 @@ void rotateFrame_sd_cldfb_fixed( Word32 Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - const int16_t nb_band /* i : number of CLDFB bands to process */ + const Word16 numTimeSlots, /* i : number of time slots to process */ + const Word16 nb_band /* i : number of CLDFB bands to process */ ); ivas_error ivas_external_orientation_open( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData, /* o : external orientation handle */ - const int16_t num_subframes /* i : number of subframes */ + const Word16 num_subframes /* i : number of subframes */ ); void ivas_external_orientation_close_fx( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData /* i/o: external orientation handle */ ); ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ - const int32_t fs, /* i : sampling rate */ - const int16_t num_subframes /* i : number of subframes */ + const Word32 fs, /* i : sampling rate */ + const Word16 num_subframes /* i : number of subframes */ ); void ivas_combined_orientation_close_fx( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData /* i/o: combined orientation handle */ @@ -1808,34 +1348,6 @@ void QuaternionSlerp_fx( * Orientation tracking *----------------------------------------------------------------------------------*/ -ivas_error ivas_orient_trk_Init( - ivas_orient_trk_state_t *pOTR /* i/o: orientation tracker handle */ -); - -ivas_error ivas_orient_trk_SetTrackingType( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : orientation tracking type */ -); - -ivas_error ivas_orient_trk_SetReferenceRotation( - ivas_orient_trk_state_t *pOTR, /* i/o: orientatoin trakcer handle */ - const IVAS_QUATERNION refRot /* i : reference rotation */ -); - - -ivas_error ivas_orient_trk_GetTrackedRotation( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION *pRotation /* i/o: processed rotation */ -); - -ivas_error ivas_orient_trk_Process( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION absRot, /* i : absolute head rotation */ - float updateRate, /* i : rotation update rate [Hz] */ - IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ -); - - ivas_error ivas_orient_trk_Init_fx( ivas_orient_trk_state_t *pOTR /* i/o: orientation tracker handle */ ); @@ -1880,7 +1392,7 @@ ivas_error ivas_orient_trk_Process_fx( ivas_error ivas_mcmasa_ana_open( MCMASA_ANA_HANDLE *hMcMasaPtr, /* i/o: McMASA data handle pointer */ const AUDIO_CONFIG inConfig, /* i : Input config */ - int32_t input_Fs /* i : Sampling frequency */ + Word32 input_Fs /* i : Sampling frequency */ ); void ivas_mcmasa_ana_fx( MCMASA_ANA_HANDLE hMcMasa, /* i/o: McMASA encoder handle */ @@ -1901,14 +1413,6 @@ ivas_error ivas_omasa_ana_open( UWord16 total_num_objects /* i : Number of objects */ ); -void ivas_omasa_ana( - OMASA_ANA_HANDLE hOMasa, /* i/o: OMASA analysis handle */ - float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */ - const int16_t input_frame, /* i : Input frame size */ - const int16_t nchan_transport, /* i : Number of transport channels */ - const int16_t nchan_ism /* i : Number of objects for parameter analysis*/ -); - void ivas_omasa_ana_fx( OMASA_ANA_HANDLE hOMasa, /* i/o: OMASA analysis handle */ Word32 data_in_f_fx[][L_FRAME48k], /* i/o: Input / transport audio signals */ @@ -1928,13 +1432,7 @@ void computeIntensityVector_ana_fx( const Word16 num_frequency_bands, /* i : Number of frequency bands */ Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector 2 * Qx -31 */ ); -void computeIntensityVector_ana( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ - const int16_t num_frequency_bands, /* i : Number of frequency bands */ - float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ -); + void computeReferencePower_ana_fx( const Word16 *band_grouping, /* i : Band grouping for estimation */ Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal input_q */ @@ -1942,13 +1440,6 @@ void computeReferencePower_ana_fx( Word32 *reference_power, /* o : Estimated power */ const Word16 num_freq_bands /* i : Number of frequency bands 2 * input_q - 31 */ ); -void computeReferencePower_ana( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ - float *reference_power, /* o : Estimated power */ - const int16_t num_freq_bands /* i : Number of frequency bands */ -); void ivas_create_masa_out_meta_fx( MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ @@ -1964,17 +1455,6 @@ void ivas_create_masa_out_meta_fx( Word16 surroundingCoherence_q ); -void ivas_create_masa_out_meta( - MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ - SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ - const int16_t nchan_transport, /* i : Number of transport channels */ - float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation */ - float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth */ - float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ - float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ - float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : Estimated surround coherence */ -); - ivas_error ivas_dirac_ana_open_fx( DIRAC_ANA_HANDLE *hDirACPtr, /* i/o: DIRAC data handle pointer */ Word32 input_Fs @@ -2003,11 +1483,6 @@ void ivas_prerend_merge_masa_metadata_fx( Word16 *inEne2_e /* i : TF-energy of input 2 Exponent */ ); -void copy_masa_descriptive_meta( - MASA_DECRIPTIVE_META *outMeta, /* o : metadata to be written */ - MASA_DECRIPTIVE_META *inMeta /* i : input metadata */ -); - ivas_error masaPrerendOpen_fx( MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o : handle to the opened prerenderer */ Word16 numTransports, /* i : number of transport channels */ diff --git a/lib_rend/ivas_reflections_fx.c b/lib_rend/ivas_reflections_fx.c index d6e397234..310bc77e4 100644 --- a/lib_rend/ivas_reflections_fx.c +++ b/lib_rend/ivas_reflections_fx.c @@ -36,7 +36,7 @@ #include "prot_fx.h" #include "rom_dec.h" #include "lib_rend.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_render_config_fx.c b/lib_rend/ivas_render_config_fx.c index b730b1510..056ae1651 100644 --- a/lib_rend/ivas_render_config_fx.c +++ b/lib_rend/ivas_render_config_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_reverb_delay_line_fx.c b/lib_rend/ivas_reverb_delay_line_fx.c index ab41b43c2..d2a6a0c44 100644 --- a/lib_rend/ivas_reverb_delay_line_fx.c +++ b/lib_rend/ivas_reverb_delay_line_fx.c @@ -32,7 +32,7 @@ #include #include "options.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" #include "wmc_auto.h" #include "debug.h" diff --git a/lib_rend/ivas_reverb_fft_filter_fx.c b/lib_rend/ivas_reverb_fft_filter_fx.c index 2d0722ceb..bbe077f8b 100644 --- a/lib_rend/ivas_reverb_fft_filter_fx.c +++ b/lib_rend/ivas_reverb_fft_filter_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include #include "wmc_auto.h" #include "debug.h" diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 45e492fc8..62c97f88f 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include #include #include diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index c8e6aa12f..870f8795d 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "math.h" #include "ivas_rom_rend.h" diff --git a/lib_rend/ivas_reverb_iir_filter_fx.c b/lib_rend/ivas_reverb_iir_filter_fx.c index 98b66e0c7..e09ec7005 100644 --- a/lib_rend/ivas_reverb_iir_filter_fx.c +++ b/lib_rend/ivas_reverb_iir_filter_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index ee2bada9d..b3e1e72fa 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index 8b352218b..aebb80a54 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -38,7 +38,7 @@ #include #include "cnst.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_sba_rendering_fx.c b/lib_rend/ivas_sba_rendering_fx.c index d544acd13..5e097ab2b 100644 --- a/lib_rend/ivas_sba_rendering_fx.c +++ b/lib_rend/ivas_sba_rendering_fx.c @@ -33,7 +33,7 @@ #include #include "options.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include diff --git a/lib_rend/ivas_shoebox_fx.c b/lib_rend/ivas_shoebox_fx.c index 7c930104a..1a4496085 100644 --- a/lib_rend/ivas_shoebox_fx.c +++ b/lib_rend/ivas_shoebox_fx.c @@ -33,7 +33,7 @@ #include "options.h" #include #include -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" #include "prot_fx.h" diff --git a/lib_rend/ivas_td_decorr_fx.c b/lib_rend/ivas_td_decorr_fx.c index 0fc5c21df..0c842e5bd 100644 --- a/lib_rend/ivas_td_decorr_fx.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -35,7 +35,7 @@ #include "options.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "math.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_rend/ivas_vbap_fx.c b/lib_rend/ivas_vbap_fx.c index b90b3a456..7495953e3 100644 --- a/lib_rend/ivas_vbap_fx.c +++ b/lib_rend/ivas_vbap_fx.c @@ -35,7 +35,7 @@ #include #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 129f72388..3ea159d7f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -34,7 +34,7 @@ #include "lib_rend.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 0316d8b30..e667dcfe5 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -33,7 +33,7 @@ #include "hrtf_file_reader.h" #include #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* -- GitLab From abd4aa4c51a795cf555d675ef976e4e369abef02 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Mar 2025 09:53:26 +0530 Subject: [PATCH 0430/1221] Fix for 3GPP issue 1371: Energy burst in MDCT-Stereo coded item at 48kbps Link #1371 Restricting the Q-factor of spectrum and mdst_spectrum to Q-factor 9 before enc_ste_pre_mdct to avoid truncation of the spectrums resolved the issue --- lib_enc/ivas_mdct_core_enc_fx.c | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 9027b2669..9f674473e 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1556,27 +1556,30 @@ void ivas_mdct_core_whitening_enc_fx( } IF( EQ_16( hTcxEnc0->transform_type[n], TCX_5 ) ) { - Word16 length; + Word16 length, len_sbfr; const Word16 tcx5SizeFB = sts[1]->hTcxCfg->tcx5SizeFB; move16(); /* length = max(nSampCore / (2 * NB_DIV), L_subframeTCX / (2 * NB_DIV), NB_DIV = 2 */ length = shr( s_max( nSampCore, L_subframeTCX ), 2 ); + len_sbfr = shr( hTcxEnc0->L_frameTCX, shift ); + assert( hTcxEnc0->L_frameTCX == hTcxEnc1->L_frameTCX ); exp_max = s_max( hTcxEnc0->spectrum_e[n], hTcxEnc1->spectrum_e[n] ); exp_max = s_max( exp_max, mdst_spectrum_e[0][n] ); exp_max = s_max( exp_max, mdst_spectrum_e[1][n] ); // calculate the headroom available - exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], length ), L_norm_arr( hTcxEnc0->spectrum_fx[n], length ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], length ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], length ) ); + exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], len_sbfr ), L_norm_arr( hTcxEnc0->spectrum_fx[n], len_sbfr ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], len_sbfr ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], len_sbfr ) ); q_com = sub( s_min( Q31, add( sub( Q31, exp_max ), exp_com ) ), 6 ); // 6 guarded bits + q_com = s_max( q_com, 9 ); // Keep the Q-factor at least 9 to avoid precision loss inside enc_ste_pre_mdct. exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc1->spectrum_e - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e + scale_sig32( hTcxEnc0->spectrum_fx[n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + scale_sig32( hTcxEnc1->spectrum_fx[n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc1->spectrum_e + scale_sig32( mdst_spectrum_fx[0][n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e + scale_sig32( mdst_spectrum_fx[1][n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e Word16 q_com_orig = q_com; move16(); @@ -1600,17 +1603,18 @@ void ivas_mdct_core_whitening_enc_fx( exp_max = sub( Q31, q_com ); move16(); - exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); q_com = sub( s_min( Q31, add( q_com, exp_com ) ), 6 ); + q_com = s_max( q_com, 9 ); // Keep the Q-factor at least 9 to avoid precision loss inside enc_ste_pre_mdct. exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( hTcxEnc0->spectrum_fx[n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( hTcxEnc1->spectrum_fx[n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( mdst_spectrum_fx[0][n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( mdst_spectrum_fx[1][n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max q_com_orig = q_com; move16(); -- GitLab From 310ce0b982833d52e0c9d6260408faa667aec5e4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Mar 2025 09:56:31 +0530 Subject: [PATCH 0431/1221] Fix for 3GPP issue 1374: Duplicate functions param_mc_get_num_cldfb_syntheses_fx() and param_mc_get_num_cldfb_syntheses_ivas_fx() Link #1374 --- lib_com/ivas_prot_fx.h | 5 ----- lib_dec/ivas_init_dec_fx.c | 4 ++-- lib_dec/ivas_mc_param_dec_fx.c | 33 --------------------------------- 3 files changed, 2 insertions(+), 40 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6b23f8eed..b6cd71cd2 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -669,11 +669,6 @@ Word16 read_flag_EC_DFT( Word16 *flag /* o : flag value */ ); -/*file : ivas_mc_param_dec_fx.c*/ -Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( - Decoder_Struct *st_ivas /* i : Parametric MC handle */ -); - void ivas_init_dec_get_num_cldfb_instances( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ Word16 *numCldfbAnalyses, /* o : number of CLDFB analysis instances */ diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c index b0dbe97b4..ecd38aabe 100644 --- a/lib_dec/ivas_init_dec_fx.c +++ b/lib_dec/ivas_init_dec_fx.c @@ -128,7 +128,7 @@ void ivas_init_dec_get_num_cldfb_instances_ivas_fx( } ELSE { - *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_ivas_fx( st_ivas ); + *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_fx( st_ivas ); move16(); } BREAK; @@ -210,7 +210,7 @@ void ivas_init_dec_get_num_cldfb_instances_ivas_fx( case RENDERER_SBA_LINEAR_ENC: IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { - *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_ivas_fx( st_ivas ); + *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_fx( st_ivas ); move16(); } ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index ff895755d..404854f91 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -3789,36 +3789,3 @@ static void ivas_param_mc_bs_decode_parameter_values_fx( return; } - -Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( - Decoder_Struct *st_ivas /* i : Parametric MC handle */ -) -{ - Word16 num_cldfb_syntheses; - - num_cldfb_syntheses = 0; - move16(); - - /* sanity check*/ - IF( st_ivas->hParamMC == NULL ) - { - assert( 0 && "ParamMC handle does not exist!\n" ); - } - - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - num_cldfb_syntheses = 2; - move16(); - } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) - { - num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - - return num_cldfb_syntheses; -} -- GitLab From de9a2ffff35c5685b90b9cf9ecf6add734b0f011 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Mar 2025 10:00:57 +0530 Subject: [PATCH 0432/1221] Fix for 3GPP issue 1003: Switching artifacts worse in LTV MASA 2TC DTX FER WB to BINAURAL Link #1003 --- lib_com/ivas_prot_fx.h | 1 + lib_com/prot_fx.h | 1 + lib_dec/TonalComponentDetection_fx.c | 176 ++++++++++++++++++++++++- lib_dec/acelp_core_dec_ivas_fx.c | 1 + lib_dec/amr_wb_dec_fx.c | 1 + lib_dec/dec_tcx_fx.c | 6 +- lib_dec/er_dec_tcx_fx.c | 1 + lib_dec/ivas_mdct_core_dec_fx.c | 15 ++- lib_dec/ivas_stereo_switching_dec_fx.c | 2 + lib_dec/tonalMDCTconcealment_fx.c | 5 + 10 files changed, 197 insertions(+), 12 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6b23f8eed..5483d155a 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1974,6 +1974,7 @@ void ivas_DetectTonalComponents_fx( const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, const Word32 secondLastPowerSpectrum[], + const Word16 secondLastPowerSpectrum_e, const Word16 nSamples, const Word16 nSamplesCore, Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9fe14b5bd..b6b9b7f4a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6461,6 +6461,7 @@ void ivas_RefineTonalComponents_fx( const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, const Word32 secondLastPowerSpectrum[], + const Word16 secondLastPowerSpectrum_e, const Word16 nSamples, const Word16 nSamplesCore, const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index ca7bec140..e50abddd6 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -30,6 +30,7 @@ static void modifyThresholds( Word16 F0, Word16 origF0, Word16 *thresholdModific static void RefineThresholdsUsingPitch( const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 *pF0, Word16 *thresholdModification ); static void ivas_RefineThresholdsUsingPitch_fx( const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 *pF0, Word16 *thresholdModification ); static void findTonalComponents( Word16 *indexOfTonalPeak, Word16 *lowerIndex, Word16 *upperIndex, Word16 *numIndexes, Word16 nSamples, const Word32 *powerSpectrum, Word16 F0, Word16 *thresholdModification, Word16 element_mode ); +static void ivas_findTonalComponents_fx( Word16 *indexOfTonalPeak, Word16 *lowerIndex, Word16 *upperIndex, Word16 *numIndexes, Word16 nSamples, const Word32 *powerSpectrum, const Word16 powerSpectrum_e, Word16 F0, Word16 *thresholdModification, Word16 element_mode ); /*-------------------------------------------------------------------* * DetectTonalComponents() @@ -52,7 +53,8 @@ void ivas_DetectTonalComponents_fx( const Word16 scaleFactors[], const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, - const Word32 secondLastPowerSpectrum[], /*Qx*/ + const Word32 secondLastPowerSpectrum[], /*Q31-secondLastPowerSpectrum_e*/ + const Word16 secondLastPowerSpectrum_e, const Word16 nSamples, const Word16 nSamplesCore, Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ @@ -127,7 +129,7 @@ void ivas_DetectTonalComponents_fx( ivas_RefineThresholdsUsingPitch_fx( nSamples, nSamplesCore, secondLastPowerSpectrum, lastPitchLag, currentPitchLag, &F0, thresholdModification ); /* Find peaks in the second last frame */ - findTonalComponents( indexOfTonalPeak, lowerIndex, upperIndex, pNumIndexes, nSamples, secondLastPowerSpectrum, F0, thresholdModification, element_mode ); + ivas_findTonalComponents_fx( indexOfTonalPeak, lowerIndex, upperIndex, pNumIndexes, nSamples, secondLastPowerSpectrum, secondLastPowerSpectrum_e, F0, thresholdModification, element_mode ); } void DetectTonalComponents( @@ -306,7 +308,8 @@ void ivas_RefineTonalComponents_fx( const Word16 scaleFactors[], const Word16 scaleFactors_exp[], const Word16 scaleFactors_max_e, - const Word32 secondLastPowerSpectrum[], /*Qx*/ + const Word32 secondLastPowerSpectrum[], /*Q31-secondLastPowerSpectrum_e*/ + const Word16 secondLastPowerSpectrum_e, const Word16 nSamples, const Word16 nSamplesCore, const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ @@ -322,7 +325,7 @@ void ivas_RefineTonalComponents_fx( ivas_DetectTonalComponents_fx( newIndexOfTonalPeak, newLowerIndex, newUpperIndex, &newNumIndexes, lastPitchLag, currentPitchLag, lastMDCTSpectrum, - lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, nSamples, nSamplesCore, floorPowerSpectrum, + lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, secondLastPowerSpectrum_e, nSamples, nSamplesCore, floorPowerSpectrum, psychParamsCurrent, element_mode ); nPreservedPeaks = 0; @@ -1280,6 +1283,171 @@ static void RefineThresholdsUsingPitch( return; } +static void ivas_findTonalComponents_fx( + Word16 *indexOfTonalPeak, /* OUT Q0*/ + Word16 *lowerIndex, /* OUT Q0*/ + Word16 *upperIndex, /* OUT Q0*/ + Word16 *numIndexes, /* OUT Q0*/ + Word16 nSamples, /* IN */ + const Word32 *powerSpectrum, /* IN Q31-powerSpectrum_e*/ + const Word16 powerSpectrum_e, + Word16 F0, /* IN */ + Word16 *thresholdModification, /* IN Q10*/ + Word16 element_mode ) /* IN */ +{ + Word32 envelope[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/ + Word32 smoothedSpectrum[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/ + Word16 nrOfFIS; + Word16 upperIdx, lowerIdx, lowerBound; + Word16 k, j, m; + Word32 biggerNeighbor; + Word16 tmp_loop1, tmp_loop2, tmp_loop3; + + getEnvelope( nSamples, powerSpectrum, F0, envelope, smoothedSpectrum ); + + + nrOfFIS = 0; + move16(); + lowerBound = 0; + move16(); + + k = GROUP_LENGTH / 2; + move16(); + tmp_loop1 = sub( nSamples, ( GROUP_LENGTH - GROUP_LENGTH / 2 ) ); + tmp_loop2 = sub( nSamples, 1 ); + WHILE( LE_16( k, tmp_loop1 ) ) + { + Word64 mult_64 = W_mult_32_16( envelope[k], thresholdModification[k] ); // (Q31-(powerSpectrum_e+LEVEL_EXP))+1+10 + Word16 lshift = W_norm( mult_64 ); + Word32 mult_32 = W_extract_h( W_shl( mult_64, lshift ) ); //(Q31-(powerSpectrum_e+LEVEL_EXP) + lshift )+11 -32 + Word16 mult_exp = sub( Q31, sub( add( sub( Q31, add( powerSpectrum_e, LEVEL_EXP ) ), add( 10, lshift ) ), 31 ) ); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( smoothedSpectrum[k], ( powerSpectrum_e + LEVEL_EXP ), mult_32, mult_exp ); + /* There is 3 bits headroom in envelope and max of thresholdModification is 16384, so shifting left for 4 would produce overflow only when the result is anyhow close to 1 */ + IF( EQ_16( flag, 1 ) ) + { + /* The check that bin at k is bigger than bins at k-1 and k+1 is needed to avoid deadlocks when the thresholds are low. */ + /* It removes some true peaks, especially if non weighted sum is used for the smoothed spectrum. */ + biggerNeighbor = L_max( powerSpectrum[k - 1], powerSpectrum[k + 1] ); /*Qx*/ + + IF( GE_32( powerSpectrum[k], biggerNeighbor ) ) + { + /* Find the right foot */ + upperIdx = add( k, 1 ); + WHILE( LT_16( upperIdx, tmp_loop2 ) ) + { + IF( LT_32( powerSpectrum[upperIdx], powerSpectrum[upperIdx + 1] ) ) + { + /* Side lobes may increase for certain amount */ + IF( LT_32( L_shl( Mpy_32_16_1( powerSpectrum[upperIdx], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ), powerSpectrum[upperIdx + 1] ) ) + { + BREAK; + } + /* Check for further decrease after a side lobe increase */ + FOR( j = add( upperIdx, 1 ); j < tmp_loop2; j++ ) + { + IF( LT_32( powerSpectrum[j], L_shl( Mpy_32_16_1( powerSpectrum[j + 1], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ) ) ) + { + BREAK; + } + } + /* Side lobe increase must be 2 times smaller than the decrease to the foot */ + /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */ + test(); + test(); + test(); + IF( ( EQ_16( element_mode, EVS_MONO ) && GT_32( Mpy_32_32( L_shl( powerSpectrum[upperIdx + 1], 1 ), powerSpectrum[j] ), Mpy_32_32( powerSpectrum[upperIdx], powerSpectrum[upperIdx] ) ) ) || + ( NE_16( element_mode, EVS_MONO ) && ( GT_64( W_mult_32_32( L_shl( powerSpectrum[upperIdx + 1], 1 ), powerSpectrum[j] ), W_mult_32_32( powerSpectrum[upperIdx], powerSpectrum[upperIdx] ) ) ) ) ) + { + BREAK; + } + upperIdx = sub( j, 1 ); + } + upperIdx = add( upperIdx, 1 ); + } + /* left foot */ + lowerIdx = sub( k, 1 ); + WHILE( GT_16( lowerIdx, lowerBound ) ) + { + IF( LT_32( powerSpectrum[lowerIdx], powerSpectrum[lowerIdx - 1] ) ) + { + /* Side lobes may increase for certain amount */ + IF( LT_32( L_shl( Mpy_32_16_1( powerSpectrum[lowerIdx], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ), powerSpectrum[lowerIdx - 1] ) ) + { + BREAK; + } + /* Check for further decrease after a side lobe increase */ + FOR( j = sub( lowerIdx, 1 ); j > 0; j-- ) + { + IF( LT_32( powerSpectrum[j], L_shl( Mpy_32_16_1( powerSpectrum[j - 1], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ) ) ) + { + BREAK; + } + } + /* Side lobe increase must be 2 times smaller than the decrease to the foot */ + /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */ + IF( GT_32( Mpy_32_32( L_shl( powerSpectrum[lowerIdx - 1], 1 ), powerSpectrum[j] ), Mpy_32_32( powerSpectrum[lowerIdx], powerSpectrum[lowerIdx] ) ) ) + { + BREAK; + } + lowerIdx = add( j, 1 ); + } + lowerIdx = sub( lowerIdx, 1 ); + } + + lowerBound = upperIdx; + move16(); + + /* Check if there is a bigger peak up to the next peak foot */ + tmp_loop3 = s_min( upperIdx, tmp_loop1 ); + FOR( j = s_max( GROUP_LENGTH / 2, lowerIdx ); j <= tmp_loop3; j++ ) + { + if ( GT_32( powerSpectrum[j], powerSpectrum[k] ) ) + { + + k = j; + move16(); + } + } + + assert( ( nrOfFIS == 0 ) || ( indexOfTonalPeak[nrOfFIS - 1] < k ) ); + + lowerIndex[nrOfFIS] = sub( k, GROUP_LENGTH / 2 ); + move16(); + + upperIndex[nrOfFIS] = add( k, ( GROUP_LENGTH - GROUP_LENGTH / 2 - 1 ) ); + move16(); + + test(); + IF( ( nrOfFIS > 0 ) && ( LE_16( lowerIndex[nrOfFIS], upperIndex[nrOfFIS - 1] ) ) ) + { + m = shr( add( k, indexOfTonalPeak[nrOfFIS - 1] ), 1 ); + upperIndex[nrOfFIS - 1] = m; + move16(); + lowerIndex[nrOfFIS] = add( m, 1 ); + move16(); + } + + indexOfTonalPeak[nrOfFIS++] = k; + move16(); + + IF( EQ_16( nrOfFIS, MAX_NUMBER_OF_IDX ) ) + { + BREAK; + } + /* Jump to the next foot of the peak. */ + k = upperIdx; + move16(); + } + } + k = add( k, 1 ); + } + + *numIndexes = nrOfFIS; + move16(); + return; +} + + static void ivas_RefineThresholdsUsingPitch_fx( const Word16 nSamples, const Word16 nSamplesCore, diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 782654623..b21fb44e3 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1476,6 +1476,7 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->hTcxDec != NULL ) { Copy_Scale_sig( psyn_fx + shr( st->L_frame, 1 ), st->hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, st->Q_syn ) ); /*Q-1*/ + st->hTcxDec->Q_old_syn_Overl = -1; } Copy_Scale_sig( psyn_fx + sub( st->L_frame, M + 1 ), st->syn, M + 1, sub( 0, st->Q_syn ) ); /*Q0*/ diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index d45655903..9c2cdd5c0 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -756,6 +756,7 @@ ivas_error amr_wb_dec_fx( /* TCX=Q-1, ACELP2 Q0 */ Copy_Scale_sig( syn_fx + L_FRAME / 2, hTcxDec->old_syn_Overl, L_FRAME / 2, sub( -1, st_fx->Q_syn ) ); + hTcxDec->Q_old_syn_Overl = -1; Copy_Scale_sig( syn_fx + L_FRAME - M - 1, st_fx->syn, M + 1, sub( 0, st_fx->Q_syn ) ); /*------------------------------------------------------------------* diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index d1ed7ad8c..49a6b6f3b 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3608,7 +3608,8 @@ void decoder_tcx_ivas_fx( st->hHQ_core->Q_old_wtda_LB = 0; move16(); - Scale_sig( st->hTcxDec->old_syn_Overl, 320, 1 ); // Scaling to Q_syn + Scale_sig( st->hTcxDec->old_syn_Overl, 320, st->Q_syn - st->hTcxDec->Q_old_syn_Overl ); // Scaling to Q_syn + st->hTcxDec->Q_old_syn_Overl = st->Q_syn; Copy_Scale_sig_16_32_no_sat( st->old_Aq_12_8_fx, st->old_Aq_12_8_fx_32, M + 1, ( sub( 28, ( sub( 15, norm_s( sub( st->old_Aq_12_8_fx[0], 1 ) ) ) ) ) ) ); Scale_sig( synth_fx, L_frame_glob, st->Q_syn ); // Scaling to Q_syn @@ -3625,7 +3626,8 @@ void decoder_tcx_ivas_fx( // Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, ( sub( st->hHQ_core->Q_old_wtda, st->Q_syn ) ) ); st->hHQ_core->Q_old_wtda_LB = st->Q_syn; // Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, ( sub( st->hHQ_core->Q_old_wtda, st->Q_syn ) ) ); - Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 + st->Q_syn ) ); // Scaling to Q-2 + Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 - st->hTcxDec->Q_old_syn_Overl ) ); // Scaling to Q-2 + st->hTcxDec->Q_old_syn_Overl = -2; } /*-------------------------------------------------------------------* diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 5cc06dabf..e804d2009 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -2036,6 +2036,7 @@ void con_tcx_ivas_fx( st->Q_syn = Q_syn; move16(); Scale_sig( hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, Q_syn ) ); /*Q_syn*/ + st->hTcxDec->Q_old_syn_Overl = -1; lerp( hTcxDec->syn_OverlFB, hTcxDec->syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) ); lerp( hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ), shr( L_frame, 1 ) ); hTcxDec->Q_syn_Overl_TDAC = hTcxDec->Q_syn_Overl_TDACFB; diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 151ba7d1e..1899c8bea 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1187,11 +1187,12 @@ void ivas_mdct_core_reconstruct_fx( { Scale_sig( st->hTcxDec->syn_Overl_TDACFB, L_FRAME_MAX / 2, sub( q_win, st->hTcxDec->Q_syn_Overl_TDACFB ) ); // st->hTcxDec->Q_syn_Overl_TDACFB -> q_win Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_syn_Overl_TDAC ) ); // st->hTcxDec->Q_syn_Overl_TDAC -> q_win - Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( q_win, sub( -1, st->Q_syn ) ) ); // Q(-1 - st->Q_syn) -> q_win - Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win + Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_old_syn_Overl ) ); // Q(-1 - st->Q_syn) -> q_win + st->hTcxDec->Q_old_syn_Overl = q_win; + Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win #ifdef MSAN_FIX Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win @@ -1260,7 +1261,8 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( sub( -1, st->Q_syn ), q_win ) ); // q_win -> Q(-1 - st->Q_syn) st->hTcxDec->Q_syn_Overl_TDAC = sub( -1, st->Q_syn ); move16(); - Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( sub( -1, st->Q_syn ), q_win ) ); // q_win -> Q(-1 - st->Q_syn) + Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( sub( -1, st->Q_syn ), st->hTcxDec->Q_old_syn_Overl ) ); // q_win -> Q(-1 - st->Q_syn) + st->hTcxDec->Q_old_syn_Overl = sub( -1, st->Q_syn ); #ifdef MSAN_FIX Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_syn, q_win ) ); // q_win -> q_syn Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_syn, q_win ) ); // q_win -> q_syn @@ -1307,6 +1309,7 @@ void ivas_mdct_core_reconstruct_fx( move16(); st->Q_syn = q_syn; move16(); + st->hTcxDec->Q_old_syn_Overl = add( st->hTcxDec->Q_old_syn_Overl, q_syn ); IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || ( st->hTcxDec->tcxConceal_recalc_exc != 0 ) ) { diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c70e606ac..066f6993d 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -804,6 +804,7 @@ ivas_error stereo_memory_dec_fx( { Copy32( tmpF_buff, st->hTcxDec->old_syn_Overl_32, L_FRAME16k / 2 ); /* Q11 */ Copy_Scale_sig32_16( st->hTcxDec->old_syn_Overl_32, st->hTcxDec->old_syn_Overl, L_FRAME16k / 2, add( st->Q_syn, 5 ) ); //(st->Qsyn - (11 - 16)) + st->hTcxDec->Q_old_syn_Overl = st->Q_syn; } st->hTcxDec->q_old_synth = st->Q_syn; move16(); @@ -2027,6 +2028,7 @@ void stereo_switching_dec( move16(); Copy( sts[0]->delay_buf_out_fx, sts[1]->delay_buf_out_fx, HQ_DELTA_MAX * HQ_DELAY_COMP ); /* Q0 */ Copy( sts[0]->hTcxDec->old_syn_Overl, sts[1]->hTcxDec->old_syn_Overl, 256 ); /* Q_old_syn_Overl*/ + sts[1]->hTcxDec->Q_old_syn_Overl = sts[0]->hTcxDec->Q_old_syn_Overl; } } ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 36cadf6ff..043ae5601 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -814,6 +814,7 @@ static void ivas_CalcPowerSpecAndDetectTonalComponents_fx( hTonalMDCTConc->lastBlockData.scaleFactors_exp, hTonalMDCTConc->lastBlockData.scaleFactors_max_e, powerSpectrum, + powerSpectrum_exp, nSamples, hTonalMDCTConc->nSamplesCore, floorPowerSpectrum, psychParamsCurrent, element_mode ); @@ -1319,6 +1320,8 @@ void TonalMDCTConceal_Detect_ivas_fx( powerSpectrum[i] = Mpy_32_32( t, t ); // Q(31-secondLastMDST_exp+powerSpectrum_exp) move32(); } + powerSpectrum_exp = 0; + move16(); } ELSE { @@ -1336,6 +1339,7 @@ void TonalMDCTConceal_Detect_ivas_fx( powerSpectrum[i] = Mpy_32_32( t, t ); // 2*(Q31 - powerSpectrum_exp -3)-31 move32(); } + powerSpectrum_exp = sub( 31, sub( shl( sub( Q31 - 3, powerSpectrum_exp ), 1 ), 31 ) ); } ivas_RefineTonalComponents_fx( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak, @@ -1352,6 +1356,7 @@ void TonalMDCTConceal_Detect_ivas_fx( hTonalMDCTConc->lastBlockData.scaleFactors_exp, hTonalMDCTConc->lastBlockData.scaleFactors_max_e, powerSpectrum, + powerSpectrum_exp, nSamples, hTonalMDCTConc->nSamplesCore, extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ), element_mode, psychParamsCurrent ); /* floorPowerSpectrum */ -- GitLab From 5d1c2b1c1706aaed8cc43bd85e1bc92a907ac963 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 13 Mar 2025 10:27:26 +0530 Subject: [PATCH 0433/1221] Fix for 3GPP issue 1343: read_indices_fx() variants Link #1343 --- lib_com/bitstream.c | 196 ++++++++----- lib_com/bitstream_fx.c | 357 +---------------------- lib_com/prot_fx.h | 24 +- lib_dec/lib_dec_fx.c | 2 +- lib_enc/acelp_core_switch_enc_fx.c | 13 - lib_enc/dtx_fx.c | 8 +- lib_enc/enc_ppp_fx.c | 12 +- lib_enc/eval_pit_contr_fx.c | 8 - lib_enc/fd_cng_enc_fx.c | 4 +- lib_enc/init_enc_fx.c | 15 - lib_enc/ivas_core_enc_fx.c | 2 +- lib_enc/ivas_corecoder_enc_reconfig_fx.c | 8 +- lib_enc/ivas_init_enc_fx.c | 2 +- lib_enc/ivas_ism_dtx_enc_fx.c | 2 +- lib_enc/ivas_ism_metadata_enc_fx.c | 2 +- lib_enc/ivas_omasa_enc_fx.c | 4 +- lib_enc/ivas_qmetadata_enc_fx.c | 2 +- lib_enc/ivas_sce_enc_fx.c | 2 +- lib_enc/ivas_spar_md_enc_fx.c | 2 +- lib_enc/ivas_stereo_td_enc_fx.c | 2 +- lib_enc/tcx_utils_enc_fx.c | 11 - 21 files changed, 149 insertions(+), 529 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 90b49f8c2..79a659eb0 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1318,33 +1318,6 @@ UWord16 get_indice_st( } #define WMC_TOOL_SKIP -/*-------------------------------------------------------------------* - * reset_indices_enc() - * - * Reset the buffer of encoder indices - *-------------------------------------------------------------------*/ - -void reset_indices_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 max_num_indices /* i : max number of indices */ -) -{ - Word16 i; - - hBstr->nb_bits_tot = 0; - move16(); - hBstr->nb_ind_tot = 0; - move16(); - - FOR( i = 0; i < max_num_indices; i++ ) - { - hBstr->ind_list[i].nb_bits = -1; - move16(); - } - - return; -} - /*-------------------------------------------------------------------* * reset_indices_dec() * @@ -1533,21 +1506,21 @@ static ivas_error write_indices_element_fx( { IF( st_ivas->hSCE[element_id]->hMetaData != NULL ) { - reset_indices_enc( st_ivas->hSCE[element_id]->hMetaData, st_ivas->hSCE[element_id]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hSCE[element_id]->hMetaData, st_ivas->hSCE[element_id]->hMetaData->nb_ind_tot ); } - reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); } ELSE { IF( st_ivas->hCPE[element_id]->hMetaData != NULL ) { - reset_indices_enc( st_ivas->hCPE[element_id]->hMetaData, st_ivas->hCPE[element_id]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[element_id]->hMetaData, st_ivas->hCPE[element_id]->hMetaData->nb_ind_tot ); } FOR( n = 0; n < n_channels; n++ ) { - reset_indices_enc( sts[n]->hBstr, sts[n]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( sts[n]->hBstr, sts[n]->hBstr->nb_ind_tot ); } } @@ -2059,67 +2032,84 @@ void ivas_set_bitstream_pointers( *-------------------------------------------------------------------*/ /*! r: 1 = reading OK, 0 = problem */ -ivas_error read_indices( +ivas_error read_indices_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 bit_stream[], /* i : bitstream buffer */ UWord16 num_bits, /* i : number of bits in bitstream */ - int16_t *prev_ft_speech, - int16_t *CNG, - int16_t bfi /* i : bad frame indicator */ + Word16 *prev_ft_speech, + Word16 *CNG, + Word16 bfi /* i : bad frame indicator */ ) { - int16_t k; + Word16 k; Decoder_State **sts; - int32_t total_brate = 0; - int16_t curr_ft_good_sp, curr_ft_bad_sp; - int16_t g192_sid_first, sid_upd_bad, sid_update; - int16_t speech_bad, speech_lost; - int16_t n; + Word32 total_brate = 0; + move32(); + Word16 curr_ft_good_sp, curr_ft_bad_sp; + Word16 g192_sid_first, sid_upd_bad, sid_update; + Word16 speech_bad, speech_lost; + Word16 n; ivas_error error; error = IVAS_ERR_OK; + move32(); st_ivas->BER_detect = 0; + move16(); st_ivas->num_bits = num_bits; + move16(); sts = reset_elements( st_ivas ); st_ivas->bfi = bfi; + move16(); /* convert the frame length to total bitrate */ - total_brate = (int32_t) ( num_bits * FRAMES_PER_SEC ); + total_brate = imult3216( num_bits, FRAMES_PER_SEC ); + move32(); /* verify that a valid num bits value is present in the G.192 file */ /* only AMRWB, EVS or IVAS bitrates or 0(NO DATA) are allowed in G.192 file frame reading */ - if ( st_ivas->ivas_format != MONO_FORMAT ) + IF( NE_32( st_ivas->ivas_format, MONO_FORMAT ) ) { k = 0; - while ( k < SIZE_IVAS_BRATE_TBL && total_brate != ivas_brate_tbl[k] ) + move16(); + + test(); + WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( total_brate, ivas_brate_tbl[k] ) ) { - k++; + k = add( k, 1 ); } - if ( st_ivas->ivas_format == ISM_FORMAT && ( k < SIZE_IVAS_BRATE_TBL || total_brate <= SID_2k40 ) ) + test(); + test(); + test(); + test(); + IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && ( LT_16( k, SIZE_IVAS_BRATE_TBL ) || LE_32( total_brate, SID_2k40 ) ) ) { st_ivas->element_mode_init = IVAS_SCE; + move16(); } - else if ( ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) && ( total_brate <= SID_2k40 ) ) + ELSE IF( ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) && LE_32( total_brate, SID_2k40 ) ) { st_ivas->element_mode_init = IVAS_SCE; + move16(); } - else if ( k == SIZE_IVAS_BRATE_TBL ) + ELSE IF( EQ_16( k, SIZE_IVAS_BRATE_TBL ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); } - else + ELSE { st_ivas->element_mode_init = -1; + move16(); } } - else /* AMRWB or EVS */ + ELSE /* AMRWB or EVS */ { st_ivas->element_mode_init = EVS_MONO; + move16(); - if ( rate2EVSmode_float( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ + IF( rate2EVSmode_float( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); } @@ -2129,47 +2119,58 @@ ivas_error read_indices( /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA as properly as possible for the ITU-T G.192 format */ /* (total_brate, bfi , st_CNG) = rx_handler(received frame type, [previous frame type], past CNG state, past core) */ curr_ft_good_sp = 0; + move16(); curr_ft_bad_sp = 0; + move16(); - if ( is_DTXrate( total_brate ) == 0 ) + IF( is_DTXrate( total_brate ) == 0 ) { - if ( st_ivas->bfi == 0 ) + IF( st_ivas->bfi == 0 ) { curr_ft_good_sp = 1; + move16(); } - else + ELSE { curr_ft_bad_sp = 1; + move16(); } } sid_update = 0; + move16(); sid_upd_bad = 0; - if ( is_SIDrate( total_brate ) == 1 ) + move16(); + IF( EQ_16( is_SIDrate( total_brate ), 1 ) ) { - if ( st_ivas->bfi == 0 ) + IF( st_ivas->bfi == 0 ) { sid_update = 1; + move16(); } - else + ELSE { sid_upd_bad = 1; /* this frame type may happen in ETSI/3GPP CS cases, a corrupt SID frames */ + move16(); } } /* all zero indices/bits iSP AMRWB SID_update results in a valid LP filter with extremely high LP-filter-gain */ /* all zero indices/bits may be a result of CS bit errors and/or erroneously injected by gateways or by a bad dejitter handlers */ - if ( total_brate == SID_1k75 && sid_update == 1 ) + test(); + IF( EQ_32( total_brate, SID_1k75 ) && EQ_16( sid_update, 1 ) ) { /* valid sid_update received, check for very risky but formally valid content */ - int16_t sum = 0; - for ( k = 0; k < num_bits; ++k ) + Word16 sum = 0; + move16(); + FOR( k = 0; k < num_bits; ++k ) { - sum += ( bit_stream[k] == 1 ); /* check of 35 zeroes */ + sum = add( sum, extract_l( EQ_32( bit_stream[k], 1 ) ) ); /* check of 35 zeroes */ } if ( sum == 0 ) { /* all zeros */ sid_upd_bad = 1; /* initial signal as corrupt (BER likely) */ + move16(); } } @@ -2180,14 +2181,22 @@ ivas_error read_indices( Here we inhibit use of the SID-length info, even though it is available in the G.192 file format after STL/EID-XOR . */ - if ( sid_upd_bad ) + IF( sid_upd_bad ) { sid_upd_bad = 0; + move16(); total_brate = FRAME_NO_DATA; /* treat SID_BAD as a stolen signaling frame --> SPEECH LOST */ + move32(); } g192_sid_first = 0; - if ( st_ivas->ivas_format == MONO_FORMAT && sts[0]->core == AMR_WB_CORE && *prev_ft_speech && total_brate == FRAME_NO_DATA && st_ivas->bfi == 0 ) + move16(); + + test(); + test(); + test(); + test(); + if ( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) && EQ_16( sts[0]->core, AMR_WB_CORE ) && *prev_ft_speech && total_brate == FRAME_NO_DATA && st_ivas->bfi == 0 ) { g192_sid_first = 1; /* SID_FIRST detected for previous AMRWB/AMRWBIO active frames only */ /* It is not possible to perfectly simulate rate switching conditions EVS->AMRWBIO where: @@ -2195,104 +2204,135 @@ ivas_error read_indices( and a good length 0 "SID_FIRST"(NO_DATA) frame is sent in AMRWBIO, due to the one frame state memory in the AMRWB legacy G.192 SID_FIRST encoding */ + move16(); } speech_bad = 0; + move16(); + + test(); if ( st_ivas->bfi != 0 && ( is_DTXrate( total_brate ) == 0 ) ) { speech_bad = 1; /* initial ft assumption, CNG_state decides what to do */ + move16(); } speech_lost = 0; + move16(); + + test(); if ( total_brate == FRAME_NO_DATA && st_ivas->bfi != 0 ) /* unsent NO_DATA or stolen NO_DATA/signaling frame */ { speech_lost = 1; /* initial ft assumption, CNG_state decides what to do */ + move16(); } /* Do not allow decoder to enter CNG-synthesis for any instantly received GOOD+LENGTH==0 frame as this frame was never transmitted, one can not know it is good and has a a length of zero ) */ - if ( *CNG != 0 ) + IF( *CNG != 0 ) { /* We were in CNG synthesis */ if ( curr_ft_good_sp != 0 ) { /* only a good speech frame makes you leave CNG synthesis */ *CNG = 0; + move16(); } } - else + ELSE { /* We were in SPEECH synthesis */ /* only a received/detected SID frame can make the decoder enter into CNG synthsis */ + test(); + test(); if ( g192_sid_first || sid_update || sid_upd_bad ) { *CNG = 1; + move16(); } } /* set bfi, total_brate pair for proper decoding */ /* handle the G.192 _simulated_ untransmitted NO_DATA frame, setting for decoder SPEECH synthesis */ + test(); + test(); if ( *CNG == 0 && total_brate == FRAME_NO_DATA && st_ivas->bfi == 0 ) { st_ivas->bfi = 1; /* SPEECH PLC code will now become active as in a real system */ /* total_brate= 0 */ + move16(); } /* handle bad/lost speech frame(and CS bad SID frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ - if ( ( - bfi != FRAMEMODE_FUTURE && - ( *CNG != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ - ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ + test(); + test(); + test(); + test(); + IF( ( + NE_16( bfi, FRAMEMODE_FUTURE ) && + ( *CNG != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ + ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ { st_ivas->bfi = 0; /* bfi=0 needed to activate CNG code */ + move16(); total_brate = FRAME_NO_DATA; + move32(); } /* update for next frame's G.192 file format's odd SID_FIRST detection (primarily for AMRWBIO) */ + test(); *prev_ft_speech = ( ( curr_ft_good_sp != 0 ) || ( curr_ft_bad_sp != 0 ) ); + move16(); /* st->total brate= total_brate; updated in a good frame below */ - for ( k = 0; k < st_ivas->nCPE; k++ ) + FOR( k = 0; k < st_ivas->nCPE; k++ ) { sts = st_ivas->hCPE[k]->hCoreCoder; - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { sts[n]->bfi = st_ivas->bfi; + move16(); } } - for ( k = 0; k < st_ivas->nSCE; k++ ) + FOR( k = 0; k < st_ivas->nSCE; k++ ) { sts = st_ivas->hSCE[k]->hCoreCoder; sts[0]->bfi = st_ivas->bfi; + move16(); } - if ( st_ivas->bfi == 0 ) + IF( st_ivas->bfi == 0 ) { /* select Mode 1 or Mode 2 */ - if ( st_ivas->ivas_format == MONO_FORMAT ) /* EVS mono */ + IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) ) /* EVS mono */ { decoder_selectCodec( sts[0], total_brate, bit_stream[0] ); st_ivas->hDecoderConfig->Opt_AMR_WB = sts[0]->Opt_AMR_WB; + move16(); } - else /* IVAS */ + ELSE /* IVAS */ { st_ivas->codec_mode = MODE1; + move16(); st_ivas->hDecoderConfig->Opt_AMR_WB = 0; + move16(); } } /* GOOD frame */ - if ( st_ivas->bfi == 0 || st_ivas->bfi == FRAMEMODE_FUTURE ) + test(); + if ( st_ivas->bfi == 0 || EQ_16( st_ivas->bfi, FRAMEMODE_FUTURE ) ) { /* GOOD frame - convert ITU-T G.192 words to short values */ st_ivas->hDecoderConfig->ivas_total_brate = total_brate; + move32(); } st_ivas->bit_stream = bit_stream; - if ( st_ivas->ivas_format == MONO_FORMAT ) + IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) ) { ivas_set_bitstream_pointers( st_ivas ); } diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 6163fc4ff..d4938f399 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -543,7 +543,8 @@ UWord16 get_indice_1_fx( /* o : value of the indice */ *-------------------------------------------------------------------*/ void reset_indices_enc_fx( - BSTR_ENC_HANDLE hBstr /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ + const Word16 max_num_indices /* i : max number of indices */ ) { Word16 i; @@ -559,7 +560,7 @@ void reset_indices_enc_fx( hBstr->last_ind_fx = -1; move16(); - FOR( i = 0; i < MAX_NUM_INDICES; i++ ) + FOR( i = 0; i < max_num_indices; i++ ) { hBstr->ind_list[i].nb_bits = -1; move16(); @@ -1547,358 +1548,6 @@ Word32 BIT_ALLOC_IDX_16KHZ_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 t return L_temp; } - -/*-------------------------------------------------------------------* - * read_indices_fx() - * - * Read indices from an ITU-T G.192 bitstream to the buffer - * Simulate packet losses by inserting frame erasures - *-------------------------------------------------------------------*/ - -Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem */ - Decoder_State *st, /* i/o: decoder state structure */ - FILE *file, /* i : bitstream file */ - Word16 rew_flag /* i : rewind flag (rewind file after reading)*/ -) -{ - Word16 k; - UWord16 utmp, stream[2 + MAX_BITS_PER_FRAME], *pt_stream, *bit_stream_ptr; - Word16 num_bits; - Word32 total_brate; - Word32 L_tmp; - Word16 curr_ft_good_sp, curr_ft_bad_sp; - Word16 g192_sid_first, sid_upd_bad, sid_update; - Word16 speech_bad, speech_lost; - Word16 num_bits_read; - - st->bfi = 0; - move16(); - st->BER_detect = 0; - move16(); - st->mdct_sw_enable = 0; - move16(); - st->mdct_sw = 0; - move16(); - reset_indices_dec_fx( st ); - - /* read the Sync Header field from the bitstream */ - /* in case rew_flag is set, read until first good frame is encountered */ - test(); - test(); - DO - { - /* read the Sync header */ - IF( NE_32( fread( &utmp, sizeof( unsigned short ), 1, file ), 1 ) ) - { - IF( ferror( file ) ) - { - /* error during reading */ - fprintf( stderr, "\nError reading the bitstream !" ); - exit( -1 ); - } - ELSE - { - /* end of file reached */ - return 0; - } - } - - /* set the BFI indicator according the value of Sync Header */ - IF( EQ_16( utmp, SYNC_BAD_FRAME ) ) - { - st->bfi = 1; - move16(); - } - ELSE - { - st->bfi = 0; - move16(); - } - - /* read the Frame Length field from the bitstream */ - IF( NE_32( fread( &num_bits, sizeof( unsigned short ), 1, file ), 1 ) ) - { - IF( ferror( file ) ) - { - /* error during reading */ - fprintf( stderr, "\nError reading the bitstream !" ); - exit( -1 ); - } - ELSE - { - /* end of file reached */ - return 0; - } - } - /* convert the frame length to total bitrate */ - total_brate = L_mult0( num_bits, 50 ); - - /* read ITU-T G.192 serial stream of indices from file to the local buffer */ - /* Validate that the G.192 length is within the defined bit rate range - to not allow writing past the end of the "stream" buffer */ - IF( GT_16( num_bits, MAX_BITS_PER_FRAME ) ) - { - fprintf( stderr, "\nError, too large G.192 frame (size(%d))! Exiting ! \n", num_bits ); - exit( -1 ); - } - - /* verify that a valid num bits value is present in the G.192 file */ - /* only AMRWB or EVS bit rates or 0(NO DATA) are allowed in G.192 file frame reading */ - IF( rate2EVSmode( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ - { - fprintf( stderr, "\nError, illegal bit rate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); - exit( -1 ); - } - pt_stream = stream; - - num_bits_read = (Word16) fread( pt_stream, sizeof( unsigned short ), num_bits, file ); - move16(); - - IF( NE_16( num_bits_read, num_bits ) ) - { - fprintf( stderr, "\nError, invalid number of bits read ! Exiting ! \n" ); - exit( -1 ); - } - } - WHILE( rew_flag && ( st->bfi || ( total_brate < 2800 ) ) ); - - /* G.192 RX DTX handler*/ - IF( !rew_flag ) - { - /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA as properly as possible for the ITU-T G.192 format */ - - /* (total_brate, bfi , st_CNG) = rx_handler(received frame type, [previous frame type], past CNG state, past core) */ - curr_ft_good_sp = 0; - move16(); - curr_ft_bad_sp = 0; - move16(); - - IF( GT_32( total_brate, SID_2k40 ) ) - { - IF( st->bfi == 0 ) - { - curr_ft_good_sp = 1; - move16(); - } - ELSE - { - curr_ft_bad_sp = 1; - move16(); - } - } - sid_update = 0; - move16(); - sid_upd_bad = 0; - move16(); - - test(); - IF( total_brate == SID_1k75 || total_brate == SID_2k40 ) - { - IF( st->bfi == 0 ) - { - sid_update = 1; - move16(); - } - ELSE - { - sid_upd_bad = 1; /* may happen in CS , corrupt but detected sid frame */ - move16(); - } - } - - /* all zero indeces/bits iSP AMRWB SID_update results in a valid LP filter with extremely high LP-filter-gain */ - /* all zero indeces/bits may be a result of CS bit errors and/or erroneously injected by gateways or by a bad dejitter handlers */ - test(); - IF( EQ_32( total_brate, SID_1k75 ) && EQ_16( sid_update, 1 ) ) - { - /* valid sid_update received, check for very risky but formally valid content */ - Word16 sum = 0; - move16(); - FOR( k = 0; k < num_bits; ++k ) - { - sum = add( sum, extract_l( EQ_16( pt_stream[k], G192_BIN1 ) ) ); /* check of 35 zeroes, 35 ones */ - } - if ( sum == 0 ) - { /* all zeros */ - sid_upd_bad = 1; /* initial signal as corrupt (BER likley) */ - move16(); - } - } - - /* AMRWB 26.173 G.192 file reader (read_serial) does not declare/use SID_BAD ft, - it declares every bad synch marked frame initially as a lost_speech frame, - and then the RXDTX handler CNG state decides the decoding mode CNG/SPEECH. - While In the AMRWB ETSI/3GPP format eid a CRC error in a detected SID_UPDATE frame triggers SID_UPD_BAD. - - Here we inhibit use of the SID-length info, even though it is available in the G.192 file format after STL/EID-XOR . - */ - IF( sid_upd_bad ) - { - sid_upd_bad = 0; - move16(); - total_brate = FRAME_NO_DATA; /* treat SID_BAD as a stolen signaling frame --> SPEECH LOST */ - move32(); - } - - g192_sid_first = 0; - move16(); - - test(); - test(); - test(); - if ( EQ_16( st->core, AMR_WB_CORE ) && st->prev_ft_speech_fx && total_brate == FRAME_NO_DATA && st->bfi == 0 ) - { - g192_sid_first = 1; /* SID_FIRST detected for previous AMRWB/AMRWBIO active frames only */ - /* - It is not possible to perfectly simulate rate switching conditions EVS->AMRWBIO where: - the very first SID_FIRST detection is based on a past EVS active frame - and a good length 0 "SID_FIRST"(NO_DATA) frame is sent in AMRWBIO, - , due to the one frame state memory in the AMRWB legacy G.192 SID_FIRST encoding - */ - move16(); - } - - speech_bad = 0; - move16(); - - test(); - if ( GT_32( total_brate, SID_2k40 ) && st->bfi != 0 ) /* CS-type of CRC failure frame */ - { - speech_bad = 1; /* initial assumption, CNG_state decides what to do */ - move16(); - } - - speech_lost = 0; - move16(); - - test(); - if ( total_brate == 0 && st->bfi != 0 ) /* unsent NO_DATA or stolen NO_DATA/signaling frame */ - { - speech_lost = 1; /* initial assumption, CNG_state decides what to do */ - move16(); - } - - /* Do not allow decoder to enter CNG-synthesis for any instantly received GOOD+LENGTH==0 frame - as this frame was never transmitted, one can not know it is good and has a a length of zero ) */ - - IF( st->CNG_fx != 0 ) - { - /* We were in CNG synthesis */ - if ( curr_ft_good_sp != 0 ) - { - /* only a good speech frame makes you leave CNG synthesis */ - st->CNG_fx = 0; - move16(); - } - } - ELSE - { - /* We were in SPEECH synthesis */ - /* only a received SID frame can make the decoder enter into CNG synthsis */ - test(); - test(); - if ( g192_sid_first || sid_update || sid_upd_bad ) - { - st->CNG_fx = 1; - move16(); - } - } - - /* handle the g.192 _simulated_ untransmitted frame, setting for decoder SPEECH synthesis */ - test(); - test(); - if ( ( st->CNG_fx == 0 ) && ( total_brate == 0 && st->bfi == 0 ) ) - { - st->bfi = 1; - move16(); /* SPEECH PLC code will now become active as in a real system */ - /* total_brate= 0 */ - } - - /* handle bad speech frame(and bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ - test(); - test(); - test(); - IF( ( ( st->CNG_fx != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ - ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ - { - st->bfi = 0; - move16(); - total_brate = 0; - move32(); - } - /* update for next frame's G.192 file format's SID_FIRST detection (primarily for AMRWBIO) */ - test(); - st->prev_ft_speech_fx = ( ( curr_ft_good_sp != 0 ) || ( curr_ft_bad_sp != 0 ) ); - move16(); - - /* st->total brate= total_brate ; updated in a good frame below */ - } /* rew_flag */ - - /* get total bit-rate */ -#ifdef DEBUGGING - st->bfi |= file_read_FECpattern(); -#endif - test(); - IF( st->bfi == 0 && !rew_flag ) - { - /* select MODE1 or MODE2 */ - decoder_selectCodec( st, total_brate, *pt_stream ); - } - - Mpy_32_16_ss( total_brate, 5243, &L_tmp, &utmp ); /* 5243 is 1/50 in Q18. (0+18-15=3) */ - st->total_num_bits = extract_l( L_shr( L_tmp, 3 ) ); /* Q0 */ - move16(); - - /* in case rew_flag is set, rewind the file and return */ - /* (used in io_enc() to print out info about technologies and to initialize the codec) */ - IF( rew_flag ) - { - rewind( file ); - st->total_brate = total_brate; - move32(); - return 1; - } - - /* GOOD frame */ - IF( st->bfi == 0 ) - { - /* GOOD frame - convert ITU-T G.192 words to short values */ - bit_stream_ptr = st->bit_stream; - - FOR( k = 0; k < num_bits; ++k ) - { - *bit_stream_ptr++ = (UWord16) EQ_32( *pt_stream++, G192_BIN1 ); - move16(); - } - - /*add two zero bytes for arithmetic coder flush*/ - FOR( k = 0; k < 2 * 8; ++k ) - { - *bit_stream_ptr++ = 0; - move16(); - } - /*a change of the total bitrate should not be - known to the decoder, if the received frame was lost*/ - st->total_brate = total_brate; - move32(); - - mdct_switching_dec( st ); - } -#ifdef DEBUGGING - else - { - bit_stream_ptr = st->bit_stream; - - for ( k = 0; k < num_bits + 2 * 8; ++k ) - { - *bit_stream_ptr++ = 0; - } - } -#endif - return 1; -} - - /*-------------------------------------------------------------------* * read_indices_mime_handle_dtx() * diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9fe14b5bd..1bd007e64 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1323,7 +1323,8 @@ UWord16 get_indice_1_fx( /* o : value of the indice */ ); void reset_indices_enc_fx( - BSTR_ENC_HANDLE hBstr /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ + const Word16 max_num_indices /* i : max number of indices */ ); void reset_indices_dec_fx( @@ -1367,12 +1368,6 @@ Word16 BRATE2IDX16k_fx( Word32 brate ); Word32 BIT_ALLOC_IDX_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 tc ); Word32 BIT_ALLOC_IDX_16KHZ_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 tc ); -Word16 read_indices_fx( /* o : 1 = OK, 0 = something wrong */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - FILE *file, /* i : bitstream file */ - Word16 rew_flag /* i : rewind flag (rewind file after reading) */ -); - Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem */ Decoder_State *st, /* i/o: decoder state structure */ FILE *file, /* i : bitstream file */ @@ -11544,11 +11539,6 @@ uint16_t get_indice( int16_t nb_bits /* i : number of bits that were used to quantize the indice */ ); -void reset_indices_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t max_num_indices /* i : max number of indices */ -); - void reset_indices_dec( Decoder_State *st /* i/o: decoder state structure */ ); @@ -11560,13 +11550,13 @@ Word16 rate2EVSmode_float( /*! r: 1 = OK, 0 = something wrong */ -ivas_error read_indices( +ivas_error read_indices_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 bit_stream[], /* i : bitstream buffer */ UWord16 num_bits, /* i : number of bits in bitstream */ - int16_t *prev_ft_speech, - int16_t *CNG, - int16_t bfi /* i : bad frame indicator */ + Word16 *prev_ft_speech, + Word16 *CNG, + Word16 bfi /* i : bad frame indicator */ ); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index dc06ddc5a..56ffe3924 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -923,7 +923,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( } } - IF( NE_32( ( error = read_indices( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = read_indices_fx( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 90768aca1..d88e1523e 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -160,18 +160,6 @@ void acelp_core_switch_enc_fx( /*----------------------------------------------------------------* * bit-stream: modify the layer of sub frame CELP *----------------------------------------------------------------*/ -#ifdef IVAS_CODE_BITSTREAM - i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); -#ifdef DEBUGGING - assert( i >= 0 && "Internal error in ACELP core switching - unable to find ACELP subframe indices!" ); -#endif - while ( hBstr->ind_list[i].id == TAG_ACELP_SUBFR_LOOP_START ) - { - push_indice( hBstr, IND_CORE_SWITCHING_CELP_SUBFRAME, hBstr->ind_list[i].value, hBstr->ind_list[i].nb_bits ); - i++; - } - delete_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START ); -#else FOR( i = 0; i < 20; i++ ) { hBstr->ind_list[IND_CORE_SWITCHING_CELP_SUBFRAME + i].value = hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].value; /* Q0 */ @@ -181,7 +169,6 @@ void acelp_core_switch_enc_fx( hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits = -1; /* Q0 */ move16(); } -#endif /*----------------------------------------------------------------* * BWE encoding *----------------------------------------------------------------*/ diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 6e4d2a043..154b43c12 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -349,7 +349,7 @@ void dtx_ivas_fx( IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { - reset_indices_enc( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); } } #ifdef NONBE_1211_DTX_BR_SWITCHING @@ -863,11 +863,7 @@ void dtx_fx( /* reset the bitstream (IVAS format signalling was already written) */ IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { -#ifndef IVAS_CODE_BITSTREAM - reset_indices_enc_fx( st_fx->hBstr ); -#else - reset_indices_enc( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); -#endif + reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); } } diff --git a/lib_enc/enc_ppp_fx.c b/lib_enc/enc_ppp_fx.c index f1a87d2d2..c2aeaa7ca 100644 --- a/lib_enc/enc_ppp_fx.c +++ b/lib_enc/enc_ppp_fx.c @@ -189,11 +189,7 @@ ivas_error encod_ppp_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ -#ifndef IVAS_CODE_BITSTREAM - reset_indices_enc_fx( hBstr ); -#else - reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); -#endif + reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); @@ -377,11 +373,7 @@ ivas_error encod_ppp_ivas_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ -#ifndef IVAS_CODE_BITSTREAM - reset_indices_enc_fx( hBstr ); -#else - reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); -#endif + reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index 75e82409e..d5f832f8c 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -381,19 +381,14 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ FOR( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) { -#ifndef IVAS_CODE_BITSTREAM IF( hBstr->ind_list[i].nb_bits != -1 ) { hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[i].nb_bits ); /* Q0 */ hBstr->ind_list[i].nb_bits = -1; move16(); } -#else - delete_indice( hBstr, i ); -#endif } -#ifndef IVAS_CODE_BITSTREAM IF( hBstr->ind_list[IND_ES_PRED].nb_bits != -1 ) { hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_ES_PRED].nb_bits ); /* Q0 */ @@ -401,9 +396,6 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit hBstr->ind_list[IND_ES_PRED].nb_bits = -1; move16(); } -#else - delete_indice( hBstr, i ); -#endif } IF( LT_32( st_fx->core_brate, CFREQ_BITRATE ) ) { diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 2db8b956b..757a69518 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -2695,9 +2695,9 @@ void stereoFdCngCoherence_fx( ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) ) { /* case: no VAD for both channels -> INACTIVE FRAME */ - reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); - reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); /* synchronize SID sending for variable SID rate */ IF( EQ_32( sts[0]->core_brate, sts[1]->core_brate ) ) diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index cd5db5377..ebfd9c4a2 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -136,18 +136,6 @@ ivas_error init_encoder_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); } -#ifdef IVAS_CODE_BITSTREAM - - /* set pointer to the buffer of indices */ - st->hBstr->ind_list = st_ivas->ind_list; - st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; - st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; - st->hBstr->nb_ind_tot = 0; - move16(); - st->hBstr->nb_bits_tot = 0; - move16(); - st->hBstr->st_ivas = st_ivas; -#endif } ELSE { @@ -910,9 +898,6 @@ ivas_error init_encoder_fx( NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ), &st_fx->transientDetection ); - // reset_indices_enc_fx( st_fx->hBstr); - - st_fx->Q_syn2 = 0; move16(); st_fx->Q_syn = 0; diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index f88288ea1..cacbcabd3 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -309,7 +309,7 @@ ivas_error ivas_core_enc_fx( st->hBstr->nb_ind_tot = add( st->hBstr->nb_ind_tot, hStereoTD->tdm_hBstr_tmp.nb_ind_tot ); /* Q0 */ st->hBstr->nb_bits_tot = add( st->hBstr->nb_bits_tot, hStereoTD->tdm_hBstr_tmp.nb_bits_tot ); /* Q0 */ - reset_indices_enc( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); + reset_indices_enc_fx( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); } /*---------------------------------------------------------------------* diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index f21c8e262..a1f2196fb 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -405,7 +405,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( /* only reset indices if it is not the first index list, this already contains the IVAS format bits */ IF( sce_id > 0 || EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { - reset_indices_enc( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->nb_ind_tot ); } } @@ -449,7 +449,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( ( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->nSCE > 0 ) || ( EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) && st_ivas->nSCE > 0 ) ) { - reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); } } } @@ -487,7 +487,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( test(); IF( add( i_mult( cpe_id, CPE_CHANNELS ), n ) > 0 || ( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->nSCE > 0 ) ) { - reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); } IF( hEncoderConfig->Opt_DTX_ON ) @@ -667,7 +667,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( } } - reset_indices_enc( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData, st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData, st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->nb_ind_tot ); FOR( cpe_id = 0; cpe_id < st_ivas->nCPE - 1; cpe_id++ ) { diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index b49fc9716..57858b03e 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -2151,7 +2151,7 @@ ivas_error ivas_initialize_MD_bstr_enc_fx( hMetaData->ivas_max_num_indices = &st_ivas->ivas_max_num_indices_metadata; /* Q0 */ hMetaData->st_ivas = st_ivas; - reset_indices_enc( hMetaData, st_ivas->ivas_max_num_indices_metadata ); + reset_indices_enc_fx( hMetaData, st_ivas->ivas_max_num_indices_metadata ); *hMetaData_out = hMetaData; diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 9256be408..6aba283be 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -191,7 +191,7 @@ Word16 ivas_ism_dtx_enc_fx( IF( dtx_flag ) { /* reset the bitstream (IVAS format signaling was already written) */ - reset_indices_enc( hSCE[0]->hCoreCoder[0]->hBstr, hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( hSCE[0]->hCoreCoder[0]->hBstr, hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot ); } /*------------------------------------------------------------------* diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index 6a2e54db6..8e6e0c93f 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -873,7 +873,7 @@ ivas_error ivas_ism_metadata_enc_fx( /* write metadata only in active frames */ IF( GT_32( hSCE[0]->hCoreCoder[0]->core_brate, SID_2k40 ) ) { - reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot ); } } diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index b5258712b..d31e6d53d 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -336,11 +336,11 @@ ivas_error ivas_omasa_enc_config_fx( /* re-write IVAS format signalling - actual 'ism_mode' was not known before */ IF( st_ivas->nSCE > 0 ) { - reset_indices_enc( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); + reset_indices_enc_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); } ELSE { - reset_indices_enc( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); + reset_indices_enc_fx( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); } ivas_write_format_fx( st_ivas ); diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 2d6080995..7de54c482 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -1209,7 +1209,7 @@ void reset_metadata_spatial_fx( ELSE { /*Reset metadata*/ - reset_indices_enc( hMetaData, hMetaData->nb_ind_tot ); + reset_indices_enc_fx( hMetaData, hMetaData->nb_ind_tot ); } *total_brate = element_brate; diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 2983ea2f0..35b65e4c1 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -608,7 +608,7 @@ ivas_error create_evs_sce_enc_fx( } st_fx->hBstr->ind_list = ind_list; // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; - reset_indices_enc_fx( st_fx->hBstr ); + reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); hSCE->hCoreCoder[0] = st_fx; st_ivas->hSCE[sce_id] = hSCE; diff --git a/lib_enc/ivas_spar_md_enc_fx.c b/lib_enc/ivas_spar_md_enc_fx.c index 997581476..9c4fcc937 100644 --- a/lib_enc/ivas_spar_md_enc_fx.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -849,7 +849,7 @@ ivas_error ivas_spar_md_enc_process_fx( move16(); IF( NE_16( strat, NO_STRAT ) ) { - reset_indices_enc( &hMetaData_tmp, md_indices_allocated ); + reset_indices_enc_fx( &hMetaData_tmp, md_indices_allocated ); ivas_write_spar_md_bitstream_fx( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, strat, qsi ); diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 1544aab76..378068827 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -195,7 +195,7 @@ void stereo_td_init_enc_fx( move32(); hStereoTD->tdm_hBstr_tmp.ivas_max_num_indices = &hStereoTD->max_ind_tdm_tmp; hStereoTD->tdm_hBstr_tmp.st_ivas = NULL; - reset_indices_enc( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); + reset_indices_enc_fx( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); return; } diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 7247b6446..ce7f0e6a6 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3734,7 +3734,6 @@ void ProcessIGF_fx( } } - // IVAS_CODE_BITSTREAM bsStart = hBstr->next_ind_fx; move16(); @@ -3749,21 +3748,11 @@ void ProcessIGF_fx( IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } -#ifndef IVAS_CODE_BITSTREAM bsBits = sub( hBstr->next_ind_fx, bsStart ); IF( !isTCX20 ) { IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot, hBstr->ind_list ); } -#else - PMT( "New bit stream implementation to be checked" ) - bsBits = sub( hBstr->next_ind_fx, bsStart ); - IF( !isTCX20 ) - { - IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot_fx, hBstr->ind_list_fx ); - } - -#endif } void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) -- GitLab From 99819c6d58f906bdeec90ed4efcb326570c5b9f6 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 13 Mar 2025 15:40:36 +0100 Subject: [PATCH 0434/1221] Reduce differences to main. Remove out of scope division change in ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(). Simplify reference power calculation in computeTargetPSDs_direct_subframe_fx(). --- lib_dec/ivas_dirac_dec_fx.c | 2 + lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 52 +++++++++++++++---- lib_rend/ivas_dirac_rend_fx.c | 11 +++- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 283f607e0..48c00ed92 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3848,6 +3848,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); } #endif + exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, i_mult( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, i_mult( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q + exp) hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, exp ); @@ -3934,6 +3935,7 @@ void ivas_dirac_dec_render_sf_fx( } } #endif + FOR( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) { FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index b02d67702..6c77f12ff 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -314,6 +314,7 @@ ivas_error ivas_dirac_dec_output_synthesis_open_fx( dirac_output_synthesis_state->reference_power_smooth_prev_q = Q31; move16(); #endif + IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); @@ -636,13 +637,13 @@ void ivas_dirac_dec_output_synthesis_close_fx( *------------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_process_slot_fx( - const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ + const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ #ifdef FIX_867_CLDFB_NRG_SCALE const Word16 *q_reference_power, /* i : Estimated power Q */ #else const Word16 q_reference_power, /* i : Estimated power Q */ #endif - const Word32 *onset, /* i : onset filter Q31*/ + const Word32 *onset, /* i : onset filter Q31*/ const Word16 *azimuth, const Word16 *elevation, const Word32 *diffuseness, /* Q(q_diffuseness)*/ @@ -1954,7 +1955,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word16 alphaMaxBinFast; Word32 L_tmp; Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS]; -#if 0 +#if 1 Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp; #else Word16 exp = 0, exp1, q_com, q_tmp, min_exp; @@ -2186,7 +2187,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( exp = 0; move16(); -#if 0 +#if 1 tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 #else @@ -2328,6 +2329,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx; p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; + FOR( k = 0; k < num_protos_dir; k++ ) { FOR( l = 0; l < num_freq_bands; l++ ) @@ -2517,6 +2519,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ), Q31 ) ); #endif + *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp) move32(); *( p_gains_dir ) = L_shl_sat( *( p_gains_dir ), sub( h_dirac_output_synthesis_state->gains_dir_prev_q, sub( Q31, exp ) ) ); // gains_dir_prev_q @@ -4050,22 +4053,22 @@ static void computeTargetPSDs_direct_fx( { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else - scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ #endif scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */ v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */ - v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else - scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ #endif scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */ v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */ @@ -4095,8 +4098,12 @@ static void computeTargetPSDs_direct_subframe_fx( Word16 *q_cy_cross_dir_smooth ) { Word16 ch_idx, cur_idx, i, q_tmp; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word32 L_tmp[CLDFB_NO_CHANNELS_MAX]; +#else Word64 W_tmp[CLDFB_NO_CHANNELS_MAX], W_max; set64_fx( W_tmp, 0, CLDFB_NO_CHANNELS_MAX ); +#endif /* segment auxiliary buffer */ Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ @@ -4106,18 +4113,21 @@ static void computeTargetPSDs_direct_subframe_fx( { direct_power[i] = Mpy_32_32( direct_power_factor[i], reference_power[i] ); move32(); +#ifndef FIX_867_CLDFB_NRG_SCALE test(); if ( direct_power[i] == 0 && ( direct_power_factor[i] != 0 && reference_power[i] != 0 ) ) { direct_power[i] = 1; move32(); } +#endif } /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); +#ifndef FIX_867_CLDFB_NRG_SCALE W_max = 0; move64(); FOR( i = 0; i < num_freq_bands; i++ ) @@ -4139,26 +4149,41 @@ static void computeTargetPSDs_direct_subframe_fx( Word16 q_tmp2 = sub( q_tmp, sub( q_reference_power[1], q_reference_power[0] ) ); FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ ) { - cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ + cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ move32(); } + q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); + move16(); #else FOR( i = 0; i < num_freq_bands; i++ ) { cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power+q_tmp*/ move32(); } + q_cy_auto_dir_smooth[ch_idx] = add( *q_reference_power, q_tmp ); + move16(); #endif +#else + q_tmp = L_norm_arr(&direct_responses_square[cur_idx], num_freq_bands); + Copy_Scale_sig32(&direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp); + v_mult_fixed( direct_power, L_tmp, &cy_auto_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, q_tmp) -> q_reference_power + q_tmp + Scale_sig32( &cy_auto_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) ); q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); move16(); +#endif v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE Scale_sig32( &cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) ); #endif } +#ifdef FIX_867_CLDFB_NRG_SCALE *q_cy_cross_dir_smooth = q_reference_power[0]; move16(); +#else + *q_cy_cross_dir_smooth = *q_reference_power; + move16(); +#endif return; } @@ -4195,12 +4220,12 @@ static void computeTargetPSDs_diffuse_fx( { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */ #else - scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ #endif scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */ v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */ @@ -4235,11 +4260,13 @@ static void computeTargetPSDs_diffuse_subframe_fx( v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE + assert( q_reference_power[0] <= q_reference_power[1] ); Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power[0], q_reference_power[1] ) ); q_cy_auto_diff_smooth_new = q_reference_power[0]; move16(); IF( LT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) { + assert( *q_cy_auto_diff_smooth <= q_reference_power[0] ); Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_reference_power[0] ) ); q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth; move16(); @@ -4253,6 +4280,7 @@ static void computeTargetPSDs_diffuse_subframe_fx( #ifdef FIX_867_CLDFB_NRG_SCALE IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) { + assert( q_reference_power[0] <= *q_cy_auto_diff_smooth ); Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_reference_power[0], *q_cy_auto_diff_smooth ) ); } #endif @@ -4266,6 +4294,7 @@ static void computeTargetPSDs_diffuse_subframe_fx( *q_cy_auto_diff_smooth = *q_reference_power; move16(); #endif + return; } @@ -4316,6 +4345,7 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( move16(); } #endif + /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index a5a15ec99..18c9269d5 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1662,7 +1662,6 @@ void protoSignalComputation1_fx( reference_power_fx[l] = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 move32(); - #ifdef FIX_867_CLDFB_NRG_SCALE reference_power_q[qidx] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); @@ -1700,6 +1699,7 @@ void protoSignalComputation1_fx( move16(); } #endif + idx = 2 * l; p_proto_buffer_fx[idx] = RealBuffer_fx[0][0][l]; // q_cldfb move32(); @@ -1863,6 +1863,7 @@ void protoSignalComputation2_fx( *q_proto_power_smooth = add( *q_proto_power_smooth, sub( q_shift, 1 ) ); move16(); #endif + IF( isloudspeaker ) { p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f @@ -2782,6 +2783,7 @@ void protoSignalComputation2_fx( *q_reference_power = sub( add( q_reference_power_64fx, norm_shift ), 32 ); move16(); #endif + *q_proto_frame_f = add( q_cldfb, min_q_shift ); move16(); *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift ); @@ -2876,6 +2878,7 @@ void protoSignalComputation4_fx( q_shift2 = min_q_shift2; min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( i_mult( 2, 4 ) ) ); #endif + FOR( k = 0; k < 4; k++ ) { #ifdef FIX_867_CLDFB_NRG_SCALE @@ -4275,6 +4278,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); + #ifdef FIX_867_CLDFB_NRG_SCALE IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { @@ -4326,6 +4330,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); } #endif + temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q ); @@ -4611,6 +4616,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->masa_stereo_type_detect->q_subtract_power_y = s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y ); move16(); } + #ifdef FIX_867_CLDFB_NRG_SCALE Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) @@ -4661,6 +4667,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); #endif + Word16 proto_power_diff_smooth_prev_temp_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len ); Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len, proto_power_diff_smooth_prev_temp_q ); // hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q + proto_power_diff_smooth_prev_temp_q hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q, proto_power_diff_smooth_prev_temp_q ); @@ -4681,6 +4688,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( Scale_sig32( diffuseness_vector_fx, hSpatParamRendCom->num_freq_bands, 1 ); /*Buffer rescaling*/ + #ifdef FIX_867_CLDFB_NRG_SCALE Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) @@ -4716,6 +4724,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_smooth_q = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ); move16(); #endif + ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hSpatParamRendCom, -- GitLab From 5a376fef9d527defd6b5caf5f7b52ad7a8869bb2 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 13 Mar 2025 15:43:27 +0100 Subject: [PATCH 0435/1221] format (had failed despite being identical with main) --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 6c77f12ff..1692b1b0b 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -637,13 +637,13 @@ void ivas_dirac_dec_output_synthesis_close_fx( *------------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_process_slot_fx( - const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ + const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ #ifdef FIX_867_CLDFB_NRG_SCALE const Word16 *q_reference_power, /* i : Estimated power Q */ #else const Word16 q_reference_power, /* i : Estimated power Q */ #endif - const Word32 *onset, /* i : onset filter Q31*/ + const Word32 *onset, /* i : onset filter Q31*/ const Word16 *azimuth, const Word16 *elevation, const Word32 *diffuseness, /* Q(q_diffuseness)*/ @@ -4053,22 +4053,22 @@ static void computeTargetPSDs_direct_fx( { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ #else - scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ #endif scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */ v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */ - v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ #else - scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ #endif scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */ v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */ @@ -4149,7 +4149,7 @@ static void computeTargetPSDs_direct_subframe_fx( Word16 q_tmp2 = sub( q_tmp, sub( q_reference_power[1], q_reference_power[0] ) ); FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ ) { - cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ + cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ move32(); } q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); @@ -4164,8 +4164,8 @@ static void computeTargetPSDs_direct_subframe_fx( move16(); #endif #else - q_tmp = L_norm_arr(&direct_responses_square[cur_idx], num_freq_bands); - Copy_Scale_sig32(&direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp); + q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands ); + Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp ); v_mult_fixed( direct_power, L_tmp, &cy_auto_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, q_tmp) -> q_reference_power + q_tmp Scale_sig32( &cy_auto_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) ); q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); @@ -4220,12 +4220,12 @@ static void computeTargetPSDs_diffuse_fx( { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ #ifdef FIX_867_CLDFB_NRG_SCALE scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */ scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */ #else - scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ #endif scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */ v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */ -- GitLab From 3901e701b57933ab114fc480a941fa9b7a063f91 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Mar 2025 16:41:31 +0100 Subject: [PATCH 0436/1221] EVS decoder updates: bring BAO closer to FLP wrt. function names --- Workspace_msvc/lib_com.vcxproj | 1 - Workspace_msvc/lib_com.vcxproj.filters | 3 - lib_com/cldfb_evs.c | 49 +-- lib_com/ivas_prot_fx.h | 14 - lib_com/modif_fs.c | 13 +- lib_com/prot_fx.h | 245 +++++------ lib_com/swb_tbe_com.c | 296 ------------- lib_com/swb_tbe_com_fx.c | 279 ++++++++++++- lib_com/tcx_ltp_fx.c | 5 +- lib_dec/acelp_core_dec_fx.c | 4 +- lib_dec/acelp_core_switch_dec_fx.c | 16 +- lib_dec/amr_wb_dec_fx.c | 8 +- lib_dec/bass_psfilter_fx.c | 9 +- lib_dec/core_dec_switch_fx.c | 6 +- lib_dec/core_switching_dec_fx.c | 11 +- lib_dec/evs_dec_fx.c | 85 ++-- lib_dec/init_dec_fx.c | 2 +- lib_dec/ivas_core_dec_fx.c | 4 +- lib_dec/ivas_post_proc_fx.c | 8 +- lib_dec/ivas_stereo_icbwe_dec_fx.c | 8 +- lib_dec/ivas_stereo_switching_dec_fx.c | 4 +- lib_dec/stat_dec.h | 16 +- lib_dec/swb_tbe_dec_fx.c | 553 +++++++++---------------- lib_dec/updt_dec_fx.c | 2 +- lib_enc/swb_pre_proc_fx.c | 3 +- 25 files changed, 677 insertions(+), 967 deletions(-) delete mode 100644 lib_com/swb_tbe_com.c diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 5b26a2911..18ec723d8 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -277,7 +277,6 @@ - diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index b9769e3ec..dc125ad0c 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -430,9 +430,6 @@ common_all_c - - common_all_c - common_all_c diff --git a/lib_com/cldfb_evs.c b/lib_com/cldfb_evs.c index d74b9b646..c28a534d6 100644 --- a/lib_com/cldfb_evs.c +++ b/lib_com/cldfb_evs.c @@ -338,7 +338,7 @@ static void calcModulationAndFolding( Word16 *rY, } -/* cldfbAnalysisFiltering +/* cldfbAnalysis_fx Parameters: cldfbBank I/O: handle to analysis CLDFB filter struct @@ -356,14 +356,15 @@ static void calcModulationAndFolding( Word16 *rY, Returns: void */ -void cldfbAnalysisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, - Word32 **rAnalysis, - Word32 **iAnalysis, - CLDFB_SCALE_FACTOR *scaleFactor, - const Word16 *timeIn, // Q(15-timeIn_e) - const Word16 timeIn_e, - const Word16 nTimeSlots, - Word32 *pWorkBuffer // Qx +void cldfbAnalysis_fx( + HANDLE_CLDFB_FILTER_BANK cldfbBank, + Word32 **rAnalysis, + Word32 **iAnalysis, + CLDFB_SCALE_FACTOR *scaleFactor, + const Word16 *timeIn, // Q(15-timeIn_e) + const Word16 timeIn_e, + const Word16 nTimeSlots, + Word32 *pWorkBuffer // Qx ) { @@ -610,7 +611,7 @@ void cldfbAnalysisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, } -/* cldfbSynthesisFiltering +/* cldfbSynthesis_fx Parameters: cldfbBank I/O: handle to analysis CLDFB filter struct @@ -629,14 +630,15 @@ void cldfbAnalysisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, Returns: void */ -void cldfbSynthesisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, - Word32 **rAnalysis, - Word32 **iAnalysis, - const CLDFB_SCALE_FACTOR *scaleFactor, - Word16 *timeOut, // Q(15-timeOut_e) - const Word16 timeOut_e, - const Word16 nTimeSlots, - Word32 *pWorkBuffer // Qx +void cldfbSynthesis_fx( + HANDLE_CLDFB_FILTER_BANK cldfbBank, + Word32 **rAnalysis, + Word32 **iAnalysis, + const CLDFB_SCALE_FACTOR *scaleFactor, + Word16 *timeOut, // Q(15-timeOut_e) + const Word16 timeOut_e, + const Word16 nTimeSlots, + Word32 *pWorkBuffer // Qx ) { Word16 i; @@ -1186,20 +1188,13 @@ void analysisCldfbEncoder_fx( } /* perform analysis */ - cldfbAnalysisFiltering( - st_fx->cldfbAnaEnc, - ppBuf_Real, - ppBuf_Imag, - scale, - timeIn, - 0, - CLDFB_NO_COL_MAX, - workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAnaEnc, ppBuf_Real, ppBuf_Imag, scale, timeIn, 0, CLDFB_NO_COL_MAX, workBuffer ); enerScale.lb_scale = negate( scale->lb_scale ); enerScale.lb_scale16 = negate( scale->lb_scale ); move16(); move16(); + /* get 16bit respresentation */ AnalysisPostSpectrumScaling_Fx( st_fx->cldfbAnaEnc, diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6b23f8eed..8ce980064 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2289,20 +2289,6 @@ ivas_error ivas_mct_dec_fx( const Word16 output_frame, /* i : output frame length per channel */ const Word16 nb_bits_metadata /* i : number of metadata bits */ ); -void swb_tbe_reset_synth_ivas_fx( - Word32 genSHBsynth_Hilbert_Mem[], - Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[], - Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[] ); - -void InitSWBdecBuffer_ivas_fx( - Decoder_State *st_fx /* i/o: SHB decoder structure */ -); - -void td_bwe_dec_init_ivas_fx( - Decoder_State *st_fx, /* i/o: SHB decoder structure */ - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const Word32 output_Fs /* i : output sampling rate */ -); void ivas_dirac_dec_render_sf_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index 7ed3cb59b..10e64a57d 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -43,7 +43,8 @@ #include "wmc_auto.h" -void Interpolate_allpass_steep_32( +/* IVAS 32-bit variant */ +void Interpolate_allpass_steep_fx32( const Word32 *in_fx, /* i : input array of size N Qx */ Word32 *mem_fx, /* i/o: memory Qx */ const Word16 N, /* i : number of input samples */ @@ -101,6 +102,8 @@ void Interpolate_allpass_steep_32( return; } + +/* IVAS 32-bit variant */ void Decimate_allpass_steep_fx32( const Word32 *in, /* i : input array of size N Qx */ Word32 *mem, /* i/o: memory Qx */ @@ -251,7 +254,9 @@ void Decimate_allpass_steep_fx32( return; } -void interpolate_3_over_2_allpass_32( + +/* IVAS 32-bit variant */ +void interpolate_3_over_2_allpass_fx32( const Word32 *input, /* i : input signal Qx*/ const Word16 len, /* i : number of input samples */ Word32 *out, /* o : output signal Qx*/ @@ -377,8 +382,8 @@ void interpolate_3_over_2_allpass_32( return; } - -void interpolate_3_over_1_allpass_32( +/* IVAS 32-bit variant */ +void interpolate_3_over_1_allpass_fx32( const Word32 *input, /* i : input signal Qx */ const Word16 len, /* i : number of input samples */ Word32 *out, /* o : output signal */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1bd007e64..da761de9d 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -2632,49 +2632,70 @@ Word16 modify_Fs_intcub3m_sup_fx( /* o : length of output void Decimate_allpass_steep_fx( const Word16 *in_fx, - Word16 mem[], /* array of size: 2*ALLPASSSECTIONS_STEEP+1 */ - Word16 N, /* number of input samples */ - Word16 out_fx[] ); + Word16 mem[], /* array of size: 2*ALLPASSSECTIONS_STEEP+1 */ + Word16 N, /* number of input samples */ + Word16 out_fx[] /* o : output array of size N/2 */ +); + +void Decimate_allpass_steep_fx32( + const Word32 *in, /* i : input array of size N */ + Word32 *mem, /* i/o: memory */ + const Word16 N, /* i : number of input samples */ + Word32 *out /* o : output array of size N/2 */ +); void Interpolate_allpass_steep_fx( const Word16 *in_fx, - Word16 mem[], /* array of size: 2*ALLPASSSECTIONS_STEEP+1 */ - Word16 N, /* number of input samples */ - Word16 out_fx[] ); + Word16 mem[], /* array of size: 2*ALLPASSSECTIONS_STEEP+1 */ + Word16 N, /* number of input samples */ + Word16 out_fx[] /* o : output array of size 2*N */ +); + +void Interpolate_allpass_steep_fx32( + const Word32 *in_fx, /* i : input array of size N */ + Word32 *mem_fx, /* i/o: memory */ + const int16_t N, /* i : number of input samples */ + Word32 *out_fx /* o : output array of size 2*N */ +); void interpolate_3_over_2_allpass_fx( - const Word16 *input_fx, - /* i : input signal */ /* Q_input */ - const Word16 len, /* i : number of input samples */ - Word16 *out_fx, - /* o : output signal */ /* Q_input */ - Word16 *mem_fx, - /* i/o: memory */ /* Q_input */ - const Word16 *filt_coeff_fx /* i : filter coefficients */ /* Q15*/ + const Word16 *input_fx, /* i : input signal Q_input */ + const Word16 len, /* i : number of input samples */ + Word16 *out_fx, /* o : output signal Q_input */ + Word16 *mem_fx, /* i/o: memory Q_input */ + const Word16 *filt_coeff_fx /* i : filter coefficients Q15*/ +); + +void interpolate_3_over_2_allpass_fx32( + const Word32 *input, /* i : input signal Qx */ + const int16_t len, /* i : number of input samples */ + Word32 *out, /* o : output signal */ + Word32 *mem /* i/o: memory */ ); void interpolate_3_over_1_allpass_fx( - const Word16 *input_fx, - /* i : input signal */ /* Q_input */ - const Word16 len, /* i : number of input samples */ - Word16 *out_fx, - /* o : output signal */ /* Q_input */ - Word16 *mem_fx /* i/o: memory */ /* Q_input */ + const Word16 *input_fx, /* i : input signal Q_input */ + const Word16 len, /* i : number of input samples */ + Word16 *out_fx, /* o : output signal Q_input */ + Word16 *mem_fx /* i/o: memory Q_input */ +); + +void interpolate_3_over_1_allpass_fx32( + const Word32 *input, /* i : input signal Qx */ + const Word16 len, /* i : number of input samples */ + Word32 *out, /* o : output signal */ + Word32 *mem /* i/o: memory */ ); void decimate_2_over_3_allpass_fx( - const Word16 *input, - /* i : input signal */ /* Q_input */ - const Word16 len, /* i : number of input samples */ - Word16 *out_fx, - /* o : output signal */ /* Q_input */ - Word16 *mem_fx, - /* i/o: memory */ /* Q_input */ - const Word16 *filt_coeff_fx, - /* i : filter coefficients */ /* Q15*/ - const Word16 *lp_num_fx, /* i : Num Coefficients : Q15 */ - const Word16 *lp_den_fx, /* o : Den Coefficients : Q15 */ - Word16 *lp_mem_fx /* o : Filter memories : Q_input */ + const Word16 *input, /* i : input signal Q_input */ + const Word16 len, /* i : number of input samples */ + Word16 *out_fx, /* o : output signal Q_input */ + Word16 *mem_fx, /* i/o: memory Q_input */ + const Word16 *filt_coeff_fx, /* i : filter coefficients Q15 */ + const Word16 *lp_num_fx, /* i : Num Coefficients : Q15 */ + const Word16 *lp_den_fx, /* o : Den Coefficients : Q15 */ + Word16 *lp_mem_fx /* o : Filter memories : Q_input */ ); void retro_interp4_5_fx( @@ -2907,7 +2928,8 @@ void swb_tbe_reset_fx( void swb_tbe_reset_synth_fx( Word32 genSHBsynth_Hilbert_Mem[], - Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[] ); + Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[], + Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[] ); void fb_tbe_reset_synth_fx( Word32 fbbwe_hpf_mem_fx[][4], @@ -3171,7 +3193,7 @@ void GenSHBSynth_fx( const Word16 L_frame, /* i : ACELP Frame length */ Word16 *syn_dm_phase ); -void GenSHBSynth_fx_32( +void GenSHBSynth_fx32( const Word32 *input_synspeech, /* i : input synthesized speech */ Word32 *shb_syn_speech_32k, /* o : output highband component */ Word32 Hilbert_Mem[], /* i/o: memory */ @@ -3192,7 +3214,7 @@ void ScaleShapedSHB_fx( Word16 n_mem3, Word16 prev_Q_bwe_syn2 ); -void ScaleShapedSHB_32( +void ScaleShapedSHB_fx32( const Word16 length, /* i : SHB overlap length */ Word32 *synSHB_fx, /* i/o: synthesized shb signal Qx */ Word32 *overlap_fx, /* i/o: buffer for overlap-add Qx */ @@ -4478,14 +4500,15 @@ void calcGainTemp_TBE_Fx( Word16 *pGainTemp_e, const Word16 code ); -Word16 procTecTfa_TBE_Fx( Word16 *hb_synth_Fx, - Word16 hb_synth_fx_exp, - Word16 *gain_m, - Word16 *gain_e, - Word16 flat_flag, - Word16 last_core, - Word16 l_subfr, - Word16 code ); +Word16 procTecTfa_TBE_Fx( + Word16 *hb_synth_Fx, + Word16 hb_synth_fx_exp, + Word16 *gain_m, + Word16 *gain_e, + Word16 flat_flag, + Word16 last_core, + Word16 l_subfr, + Word16 code ); void calcHiEnvLoBuff_Fix( const Word16 noCols, @@ -4756,24 +4779,26 @@ void r_fft_fx_lc( ); // cldfb_evs -void cldfbAnalysisFiltering( HANDLE_CLDFB_FILTER_BANK anaCldfb, /*!< Handle of Cldfb Analysis Bank */ - Word32 **cldfbReal, /*!< Pointer to real subband slots */ - Word32 **cldfbImag, /*!< Pointer to imag subband slots */ - CLDFB_SCALE_FACTOR *scaleFactor, /*!< Scale factors of CLDFB data */ - const Word16 *timeIn, /*!< Time signal */ - const Word16 timeIn_e, /*!< Time signal */ - const Word16 nTimeSlots, /*!< Time slots to be processed */ - Word32 *pWorkBuffer /*!< pointer to temporal working buffer */ -); - -void cldfbSynthesisFiltering( HANDLE_CLDFB_FILTER_BANK synCldfb, /*!< Handle of Cldfb Synthesis Bank */ - Word32 **CldfbBufferReal, /*!< Pointer to 32 bit real subband slots */ - Word32 **CldfbBufferImag, /*!< Pointer to 32 bit imag subband slots */ - const CLDFB_SCALE_FACTOR *scaleFactor, /*!< Scale factors of CLDFB data */ - Word16 *timeOut, /*!< Time signal */ - const Word16 timeOut_e, /*!< Target exponent for output signal */ - const Word16 nTimeSlots, /*!< number of time slots to be processed */ - Word32 *pWorkBuffer /*!< pointer to temporal working buffer */ +void cldfbAnalysis_fx( + HANDLE_CLDFB_FILTER_BANK anaCldfb, /*!< Handle of Cldfb Analysis Bank */ + Word32 **cldfbReal, /*!< Pointer to real subband slots */ + Word32 **cldfbImag, /*!< Pointer to imag subband slots */ + CLDFB_SCALE_FACTOR *scaleFactor, /*!< Scale factors of CLDFB data */ + const Word16 *timeIn, /*!< Time signal */ + const Word16 timeIn_e, /*!< Time signal */ + const Word16 nTimeSlots, /*!< Time slots to be processed */ + Word32 *pWorkBuffer /*!< pointer to temporal working buffer */ +); + +void cldfbSynthesis_fx( + HANDLE_CLDFB_FILTER_BANK synCldfb, /*!< Handle of Cldfb Synthesis Bank */ + Word32 **CldfbBufferReal, /*!< Pointer to 32 bit real subband slots */ + Word32 **CldfbBufferImag, /*!< Pointer to 32 bit imag subband slots */ + const CLDFB_SCALE_FACTOR *scaleFactor, /*!< Scale factors of CLDFB data */ + Word16 *timeOut, /*!< Time signal */ + const Word16 timeOut_e, /*!< Target exponent for output signal */ + const Word16 nTimeSlots, /*!< number of time slots to be processed */ + Word32 *pWorkBuffer /*!< pointer to temporal working buffer */ ); void configureCldfb( HANDLE_CLDFB_FILTER_BANK h_cldfb, /*!< CLDFB Handle */ @@ -5811,7 +5836,7 @@ Word16 tcx_ltp_decode_params( const Word16 pitres /* Q0 */ ); -void tcx_ltp_post( +void tcx_ltp_post_fx( Decoder_State *st, TCX_LTP_DEC_HANDLE hTcxLtpDec, Word16 core, /* Q0 */ @@ -5821,7 +5846,7 @@ void tcx_ltp_post( Word16 *tcx_buf /* Qx */ ); -void tcx_ltp_post32( +void tcx_ltp_post_fx32( Decoder_State *st, TCX_LTP_DEC_HANDLE hTcxLtpDec, Word16 core, /* Q0 */ @@ -6063,36 +6088,35 @@ void tbe_read_bitstream_fx( ); void GenTransition_fx( - const Word16 *i, /* i : gain shape overlap buffer */ - const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ - Word16 length, /* i : targeted length of transition signal */ - Word16 *output, /* o : synthesized transitions signal */ - Word32 Hilbert_Mem[], /* i/o: memory */ - Word16 state_lsyn_filt_shb_local[], /* i/o: memory */ - Word16 mem_resamp_HB_32k[], /* i/o: memory */ - Word16 *syn_dm_phase, - Word32 output_Fs, - Word16 *up_mem, - Word16 rf_flag, - Word32 bitrate ); + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word16 *output_HB, /* o : synthesized HB transitions signal st_fx->prev_Q_bwe_syn2 */ + const Word32 output_Fs, /* i : output sampling rate */ + Word16 rf_flag, /* i : RF flag */ + Word32 total_bitrate /* i : total bitrate */ +); + +void GenTransition_fx32( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 prev_Qx ); void GenTransition_WB_fx( - const Word16 *i, /* i : gain shape overlap buffer */ - const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ - const Word16 prev_Qx, /* i : scaling of old_hb_synth */ - Word16 length, /* i : targeted length of transition signal */ - Word16 *output, /* o : synthesized transitions signal */ - Word16 state_lsyn_filt_shb1[], - Word16 state_lsyn_filt_shb2[], - Word32 output_Fs, - Word16 *up_mem ); -void TBEreset_dec_ivas_fx( - Decoder_State *st /* i/o: decoder state structure */ + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + const Word16 prev_Qx, /* i : scaling of old_hb_synth */ + Word16 *output, /* o : synthesized transitions signal */ + const Word32 output_Fs /* i : output sampling rate */ +); + +void GenTransition_WB_fx32( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ ); void TBEreset_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 bandwidth /* i : bandwidth mode */ + Decoder_State *st_fx /* i/o: decoder state structure */ ); void td_bwe_dec_init_fx( @@ -9823,33 +9847,6 @@ void generate_masking_noise_dirac_ivas_fx( Word16 *q_cldfb ); // modif_fs/c -void interpolate_3_over_2_allpass_32( - const Word32 *input, /* i : input signal Qx */ - const int16_t len, /* i : number of input samples */ - Word32 *out, /* o : output signal */ - Word32 *mem /* i/o: memory */ -); - -void interpolate_3_over_1_allpass_32( - const Word32 *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - Word32 *out, /* o : output signal */ - Word32 *mem /* i/o: memory */ -); -void Decimate_allpass_steep_fx32( - const Word32 *in, /* i : input array of size N */ - Word32 *mem, /* i/o: memory */ - const Word16 N, /* i : number of input samples */ - Word32 *out /* o : output array of size N/2 */ -); - -void Interpolate_allpass_steep_32( - const Word32 *in_fx, /* i : input array of size N */ - Word32 *mem_fx, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - Word32 *out_fx /* o : output array of size 2*N */ -); - void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_TDAC, Word16 *xn_buf, const Word16 *tcx_aldo_window_1, const PWord16 *tcx_aldo_window_1_trunc, const PWord16 *tcx_aldo_window_2, const PWord16 *tcx_mdct_window_half, const PWord16 *tcx_mdct_window_minimum, const PWord16 *tcx_mdct_window_trans, Word16 tcx_mdct_window_half_length, Word16 tcx_mdct_window_min_length, Word16 index, Word16 left_rect, Word16 tcx_offset, Word16 overlap, Word16 L_frame, Word16 L_frameTCX, Word16 L_spec_TCX5, Word16 L_frame_glob, Word16 frame_cnt, Word16 bfi, Word16 *old_out, Word16 *Q_old_wtda, Decoder_State *st, Word16 fullbandScale, Word16 *acelp_zir ); void IMDCT_ivas_fx( @@ -11677,7 +11674,7 @@ ivas_error acelp_core_enc_ivas_fx( Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ Word16 Q_new ); -void flip_and_downmix_generic_fx_32( +void flip_and_downmix_generic_fx32( Word32 input[], /* i : input spectrum Qx*/ Word32 output[], /* o : output spectrum Qx*/ const Word16 length, /* i : length of spectra */ @@ -11687,22 +11684,6 @@ void flip_and_downmix_generic_fx_32( Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ ); -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ); - -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -); - Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ const Word16 pos1, /* i: position of the pulse 1 */ const Word16 pos2, /* i: position of the pulse 2 */ diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c deleted file mode 100644 index 7905c7145..000000000 --- a/lib_com/swb_tbe_com.c +++ /dev/null @@ -1,296 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include - - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * flip_spectrum_and_decimby4() - * - * - *-------------------------------------------------------------------*/ - - -void GenSHBSynth_fx_32( - const Word32 *input_synspeech, /* i : input synthesized speech Qx*/ - Word32 *shb_syn_speech_32k, /* o : output highband component Qx*/ - Word32 Hilbert_Mem[], /* i/o: memory Qx*/ - Word32 state_lsyn_filt_shb_local[], /* i/o: memory Qx*/ - const Word16 L_frame, /* i : ACELP frame length */ - Word16 *syn_dm_phase ) -{ - Word32 speech_buf_32k[L_FRAME32k]; - Word16 i; - -#ifdef FIX_881_HILBERT_FILTER - Word16 shift = 0; - Word32 maxm32, input_synspeech_temp[L_FRAME16k]; - move16(); - - /* find the maximum value and derive the shift to improve precision of the Hilber filter */ - maxm32 = L_deposit_l( 0 ); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - maxm32 = L_max( maxm32, L_abs( input_synspeech[i] ) ); - } - - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - maxm32 = L_max( maxm32, L_abs( state_lsyn_filt_shb_local[i] ) ); - } - - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); - } - - IF( maxm32 != 0 ) - { - shift = sub( norm_l( maxm32 ), 3 ); - - Copy_Scale_sig32( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); - Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); - } - ELSE - { - Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); - } - - Interpolate_allpass_steep_32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); -#else - Interpolate_allpass_steep_32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); -#endif - - IF( EQ_16( L_frame, L_FRAME ) ) - { - flip_and_downmix_generic_fx_32( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, Hilbert_Mem, Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), syn_dm_phase ); - } - ELSE - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - // shb_syn_speech_32k[i] = ( ( i % 2 ) == 0 ) ? ( -speech_buf_32k[i] ) : ( speech_buf_32k[i] ); - IF( i % 2 == 0 ) - { - shb_syn_speech_32k[i] = L_negate( speech_buf_32k[i] ); // Qx - } - ELSE - { - shb_syn_speech_32k[i] = speech_buf_32k[i]; // Qx - } - move32(); - } - } - -#ifdef FIX_881_HILBERT_FILTER - IF( maxm32 != 0 ) - { - Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); - Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); - } -#endif - - return; -} -void ScaleShapedSHB_32( - const Word16 length, /* i : SHB overlap length */ - Word32 *synSHB_fx, /* i/o: synthesized shb signal Q_inp/Q_new */ - Word32 *overlap_fx, /* i/o: buffer for overlap-add Q_inp/Q_new */ - const Word16 *subgain_fx, /* i : subframe gain Q15 */ - const Word32 frame_gain_fx, /* i : frame gain Q18*/ - const Word16 *win_fx, /* i : window Q15 */ - const Word16 *subwin_fx, /* i : subframes window Q15 */ - Word16 *Q_inp, - Word16 *Q_new ) -{ - const Word16 *skip; - Word16 i, j, k, l_shb_lahead, l_frame; - Word16 join_length, num_join; - Word32 mod_syn_fx[L_FRAME16k + L_SHB_LAHEAD], L_tmp; - Word16 sum_gain_fx; - - /* initilaization */ - l_frame = L_FRAME16k; - l_shb_lahead = L_SHB_LAHEAD; - move16(); - move16(); - skip = skip_bands_SWB_TBE; - - IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) - { - skip = skip_bands_WB_TBE; - l_frame = L_FRAME16k / 4; - l_shb_lahead = L_SHB_LAHEAD / 4; - move16(); - move16(); - } - - /* apply gain for each subframe, and store noise output signal using overlap-add */ - set32_fx( mod_syn_fx, 0, l_frame + l_shb_lahead ); - - IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) - { - sum_gain_fx = 0; - move16(); - FOR( k = 0; k < shr( length, 1 ); k++ ) - { - sum_gain_fx = mult_r( subwin_fx[2 * k + 2], subgain_fx[0] ); - mod_syn_fx[skip[0] + k] = Mpy_32_16_1( synSHB_fx[skip[0] + k], sum_gain_fx ); - move32(); // Qx - mod_syn_fx[skip[0] + k + length / 2] = Mpy_32_16_1( synSHB_fx[skip[0] + k + length / 2], subgain_fx[0] ); // Qx - move32(); - } - FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) - { - FOR( k = 0; k < length; k++ ) - { - L_tmp = L_mult0( subwin_fx[k + 1], subgain_fx[i] ); - sum_gain_fx = round_fx( L_mac0( L_tmp, subwin_fx[length - k - 1], subgain_fx[i - 1] ) ); - mod_syn_fx[skip[i] + k] = L_shl( Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ), 1 ); // Qx - move32(); - } - } - FOR( k = 0; k < shr( length, 1 ); k++ ) - { - sum_gain_fx = mult_r( subwin_fx[length - k * 2 - 2], subgain_fx[i - 1] ); - mod_syn_fx[skip[i] + k] = Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ); // Qx - move32(); - } - } - ELSE - { - num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; - join_length = i_mult( num_join, length ); - j = 0; - move16(); - move16(); - FOR( k = 0; k < length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[k + 1], subgain_fx[0] ) ); // Qx - move32(); - j = add( j, 1 ); - } - FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) - { - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[i * num_join] ); // Qx - move32(); - j = add( j, 1 ); - } - - FOR( k = 0; k < length; k++ ) - { - L_tmp = L_mult0( subwin_fx[length - k - 1], subgain_fx[i * num_join] ); - mod_syn_fx[j] = L_shl( Mpy_32_16_1( synSHB_fx[j], round_fx( L_mac0( L_tmp, subwin_fx[k + 1], subgain_fx[( i + 1 ) * num_join] ) ) ), 1 ); // Qx - move32(); - j = add( j, 1 ); - } - } - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); // Qx - move32(); - j = add( j, 1 ); - } - FOR( k = 0; k < length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[length - k - 1], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ) ); // Qx - move32(); - j = add( j, 1 ); - } - } - - Word16 norm_shift = norm_l( frame_gain_fx ); - if ( frame_gain_fx == 0 ) - { - norm_shift = 31; - move16(); - } - - norm_shift = s_min( norm_shift, 14 ); - norm_shift = sub( norm_shift, 1 ); - - *Q_new = add( *Q_inp, sub( norm_shift, 13 ) ); // Q_new = Q_inp + min(norm_shift,14) - 14; - move16(); - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - overlap_fx[i] = L_shl( overlap_fx[i], sub( *Q_new, *Q_inp ) ); - move32(); - } - - FOR( i = 0; i < l_shb_lahead; i++ ) - { - synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[i] ) ); // Q_new - synSHB_fx[i] = L_add( synSHB_fx[i], overlap_fx[i] ); - synSHB_fx[i + l_shb_lahead] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new - move32(); - move32(); - move32(); - } - - FOR( ; i < l_frame; i++ ) - { - synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new - move32(); - } - - FOR( ; i < l_frame + l_shb_lahead; i++ ) - { - synSHB_fx[i] = L_shl( synSHB_fx[i], sub( *Q_new, *Q_inp ) ); - overlap_fx[i - l_frame] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[l_frame + l_shb_lahead - 1 - i] ) ); // Q_new - move32(); - move32(); - } - - *Q_inp = *Q_new; - move16(); - return; -} diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7e9471c45..04b6ba187 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -72,7 +72,7 @@ void swb_tbe_reset_fx( * Reset the extra parameters needed for synthesis of the SWB TBE output *-------------------------------------------------------------------*/ -void swb_tbe_reset_synth_ivas_fx( +void swb_tbe_reset_synth_fx( Word32 genSHBsynth_Hilbert_Mem[], Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[], Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[] ) @@ -80,17 +80,11 @@ void swb_tbe_reset_synth_ivas_fx( set32_fx( genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE ); set16_fx( genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); - set32_fx( genSHBsynth_state_lsyn_filt_shb_local_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP ); - return; -} -void swb_tbe_reset_synth_fx( - Word32 genSHBsynth_Hilbert_Mem[], - Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[] ) -{ - - set32_fx( genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE ); - set16_fx( genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); + if ( genSHBsynth_state_lsyn_filt_shb_local_fx_32 != NULL ) + { + set32_fx( genSHBsynth_state_lsyn_filt_shb_local_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP ); + } return; } @@ -486,10 +480,12 @@ void flip_and_downmix_generic_fx( *phase_state = j; move16(); + return; } -void flip_and_downmix_generic_fx_32( + +void flip_and_downmix_generic_fx32( Word32 input[], /* i : input spectrum Qx*/ Word32 output[], /* o : output spectrum Qx*/ const Word16 length, /* i : length of spectra */ @@ -5079,6 +5075,92 @@ void GenSHBSynth_fx( } +/* IVAS 32-bit variant */ +void GenSHBSynth_fx32( + const Word32 *input_synspeech, /* i : input synthesized speech Qx*/ + Word32 *shb_syn_speech_32k, /* o : output highband component Qx*/ + Word32 Hilbert_Mem[], /* i/o: memory Qx*/ + Word32 state_lsyn_filt_shb_local[], /* i/o: memory Qx*/ + const Word16 L_frame, /* i : ACELP frame length */ + Word16 *syn_dm_phase ) +{ + Word32 speech_buf_32k[L_FRAME32k]; + Word16 i; + +#ifdef FIX_881_HILBERT_FILTER + Word16 shift = 0; + Word32 maxm32, input_synspeech_temp[L_FRAME16k]; + move16(); + + /* find the maximum value and derive the shift to improve precision of the Hilber filter */ + maxm32 = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + maxm32 = L_max( maxm32, L_abs( input_synspeech[i] ) ); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + maxm32 = L_max( maxm32, L_abs( state_lsyn_filt_shb_local[i] ) ); + } + + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); + } + + IF( maxm32 != 0 ) + { + shift = sub( norm_l( maxm32 ), 3 ); + + Copy_Scale_sig32( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); + } + ELSE + { + Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); + } + + Interpolate_allpass_steep_fx32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); +#else + Interpolate_allpass_steep_fx32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); +#endif + + IF( EQ_16( L_frame, L_FRAME ) ) + { + flip_and_downmix_generic_fx32( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, Hilbert_Mem, Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), syn_dm_phase ); + } + ELSE + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + // shb_syn_speech_32k[i] = ( ( i % 2 ) == 0 ) ? ( -speech_buf_32k[i] ) : ( speech_buf_32k[i] ); + IF( i % 2 == 0 ) + { + shb_syn_speech_32k[i] = L_negate( speech_buf_32k[i] ); // Qx + } + ELSE + { + shb_syn_speech_32k[i] = speech_buf_32k[i]; // Qx + } + move32(); + } + } + +#ifdef FIX_881_HILBERT_FILTER + IF( maxm32 != 0 ) + { + Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); + } +#endif + + return; +} + + /*==============================================================================*/ /* FUNCTION : void ScaleShapedSHB_fx() */ /*------------------------------------------------------------------------------*/ @@ -5300,6 +5382,165 @@ void ScaleShapedSHB_fx( return; } + +/* IVAS 32-bit variant */ +void ScaleShapedSHB_fx32( + const Word16 length, /* i : SHB overlap length */ + Word32 *synSHB_fx, /* i/o: synthesized shb signal Q_inp/Q_new */ + Word32 *overlap_fx, /* i/o: buffer for overlap-add Q_inp/Q_new */ + const Word16 *subgain_fx, /* i : subframe gain Q15 */ + const Word32 frame_gain_fx, /* i : frame gain Q18*/ + const Word16 *win_fx, /* i : window Q15 */ + const Word16 *subwin_fx, /* i : subframes window Q15 */ + Word16 *Q_inp, + Word16 *Q_new ) +{ + const Word16 *skip; + Word16 i, j, k, l_shb_lahead, l_frame; + Word16 join_length, num_join; + Word32 mod_syn_fx[L_FRAME16k + L_SHB_LAHEAD], L_tmp; + Word16 sum_gain_fx; + + /* initilaization */ + l_frame = L_FRAME16k; + l_shb_lahead = L_SHB_LAHEAD; + move16(); + move16(); + skip = skip_bands_SWB_TBE; + + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + skip = skip_bands_WB_TBE; + l_frame = L_FRAME16k / 4; + l_shb_lahead = L_SHB_LAHEAD / 4; + move16(); + move16(); + } + + /* apply gain for each subframe, and store noise output signal using overlap-add */ + set32_fx( mod_syn_fx, 0, l_frame + l_shb_lahead ); + + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + sum_gain_fx = 0; + move16(); + FOR( k = 0; k < shr( length, 1 ); k++ ) + { + sum_gain_fx = mult_r( subwin_fx[2 * k + 2], subgain_fx[0] ); + mod_syn_fx[skip[0] + k] = Mpy_32_16_1( synSHB_fx[skip[0] + k], sum_gain_fx ); + move32(); // Qx + mod_syn_fx[skip[0] + k + length / 2] = Mpy_32_16_1( synSHB_fx[skip[0] + k + length / 2], subgain_fx[0] ); // Qx + move32(); + } + FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) + { + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_fx[k + 1], subgain_fx[i] ); + sum_gain_fx = round_fx( L_mac0( L_tmp, subwin_fx[length - k - 1], subgain_fx[i - 1] ) ); + mod_syn_fx[skip[i] + k] = L_shl( Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ), 1 ); // Qx + move32(); + } + } + FOR( k = 0; k < shr( length, 1 ); k++ ) + { + sum_gain_fx = mult_r( subwin_fx[length - k * 2 - 2], subgain_fx[i - 1] ); + mod_syn_fx[skip[i] + k] = Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ); // Qx + move32(); + } + } + ELSE + { + num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; + join_length = i_mult( num_join, length ); + j = 0; + move16(); + move16(); + FOR( k = 0; k < length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[k + 1], subgain_fx[0] ) ); // Qx + move32(); + j = add( j, 1 ); + } + FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) + { + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[i * num_join] ); // Qx + move32(); + j = add( j, 1 ); + } + + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_fx[length - k - 1], subgain_fx[i * num_join] ); + mod_syn_fx[j] = L_shl( Mpy_32_16_1( synSHB_fx[j], round_fx( L_mac0( L_tmp, subwin_fx[k + 1], subgain_fx[( i + 1 ) * num_join] ) ) ), 1 ); // Qx + move32(); + j = add( j, 1 ); + } + } + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); // Qx + move32(); + j = add( j, 1 ); + } + FOR( k = 0; k < length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[length - k - 1], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ) ); // Qx + move32(); + j = add( j, 1 ); + } + } + + Word16 norm_shift = norm_l( frame_gain_fx ); + if ( frame_gain_fx == 0 ) + { + norm_shift = 31; + move16(); + } + + norm_shift = s_min( norm_shift, 14 ); + norm_shift = sub( norm_shift, 1 ); + + *Q_new = add( *Q_inp, sub( norm_shift, 13 ) ); // Q_new = Q_inp + min(norm_shift,14) - 14; + move16(); + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + overlap_fx[i] = L_shl( overlap_fx[i], sub( *Q_new, *Q_inp ) ); + move32(); + } + + FOR( i = 0; i < l_shb_lahead; i++ ) + { + synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[i] ) ); // Q_new + synSHB_fx[i] = L_add( synSHB_fx[i], overlap_fx[i] ); + synSHB_fx[i + l_shb_lahead] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new + move32(); + move32(); + move32(); + } + + FOR( ; i < l_frame; i++ ) + { + synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new + move32(); + } + + FOR( ; i < l_frame + l_shb_lahead; i++ ) + { + synSHB_fx[i] = L_shl( synSHB_fx[i], sub( *Q_new, *Q_inp ) ); + overlap_fx[i - l_frame] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[l_frame + l_shb_lahead - 1 - i] ) ); // Q_new + move32(); + move32(); + } + + *Q_inp = *Q_new; + move16(); + return; +} + + /*-------------------------------------------------------------------* * ScaleShapedWB() * @@ -5315,15 +5556,11 @@ void ScaleShapedWB_fx( const Word16 *win, /* i : window Q15*/ const Word16 *subwin, /* i : subframes window Q15*/ const Word16 Q_bwe_exc, - Word16 L_frame /* i : Frame length - determines whether 12.8 or 16kHz core in-use */ - , - Word16 dynQ /* i : indicate whether output is dynamic Q, or Q0 */ - , - Word16 *Qx /* o : newly computed Q factor for synSHB */ - , - Word16 prev_Qx /* i : prev_Qx for memory scaling */ - , - Word32 *Hilbert_Mem /* i : Hilbert memory used for computing Qx */ + Word16 L_frame, /* i : Frame length - determines whether 12.8 or 16kHz core in-use */ + Word16 dynQ, /* i : indicate whether output is dynamic Q, or Q0 */ + Word16 *Qx, /* o : newly computed Q factor for synSHB */ + Word16 prev_Qx, /* i : prev_Qx for memory scaling */ + Word32 *Hilbert_Mem /* i : Hilbert memory used for computing Qx */ ) { const Word16 *skip; diff --git a/lib_com/tcx_ltp_fx.c b/lib_com/tcx_ltp_fx.c index 9d7cb9254..322549a6f 100644 --- a/lib_com/tcx_ltp_fx.c +++ b/lib_com/tcx_ltp_fx.c @@ -1252,7 +1252,7 @@ Word16 tcx_ltp_decode_params( return 0; } -void tcx_ltp_post( +void tcx_ltp_post_fx( Decoder_State *st, TCX_LTP_DEC_HANDLE hTcxLtpDec, Word16 core, /* Q0 */ @@ -1616,7 +1616,8 @@ void tcx_ltp_post( } -void tcx_ltp_post32( +/* IVAS 32-bit variant */ +void tcx_ltp_post_fx32( Decoder_State *st, TCX_LTP_DEC_HANDLE hTcxLtpDec, Word16 core, /* Q0 */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index c0ad52a48..b98aefc2c 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1386,7 +1386,7 @@ ivas_error acelp_core_dec_fx( IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) { /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); scaleFactor.hb_scale = scaleFactor.lb_scale; move16(); @@ -1446,7 +1446,7 @@ ivas_error acelp_core_dec_fx( st_fx->Q_syn2 = st_fx->Q_syn; move16(); { - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); + cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); } /* Bring CLDFB output to Q0 */ Scale_sig( synth_out, output_frame, negate( st_fx->Q_syn2 ) ); diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index b2cc593b3..3217e2f2a 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -204,8 +204,7 @@ ivas_error acelp_core_switch_dec_fx( { return error; } - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, synth_intFreq, - negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX_SWITCH, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, synth_intFreq, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX_SWITCH, workBuffer ); cldfb_restore_memory( st_fx->cldfbAna ); /* CLDFB synthesis of the combined signal */ @@ -236,7 +235,7 @@ ivas_error acelp_core_switch_dec_fx( { return error; } - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_subfr_out, 0, CLDFB_NO_COL_MAX_SWITCH, workBuffer ); + cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_subfr_out, 0, CLDFB_NO_COL_MAX_SWITCH, workBuffer ); cldfb_restore_memory( st_fx->cldfbSyn ); *Q_syn = 0; move16(); @@ -578,8 +577,7 @@ ivas_error acelp_core_switch_dec_bfi_fx( { return error; } - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn, - negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer ); cldfb_restore_memory( st_fx->cldfbAna ); scaleFactor.hb_scale = scaleFactor.lb_scale; @@ -590,8 +588,8 @@ ivas_error acelp_core_switch_dec_bfi_fx( { return error; } - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, - negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer ); + cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, + negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer ); /* output to Q0 */ Scale_sig( synth_out, L_FRAME48k, negate( st_fx->Q_syn ) ); // Q0 @@ -830,7 +828,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( { return error; } - /*cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn, + /*cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer);*/ cldfbAnalysis_ivas_fx( syn32, realBuffer, imagBuffer, shr( st_fx->L_frame, 1 ), st_fx->cldfbAna ); cldfb_restore_memory_ivas_fx( st_fx->cldfbAna ); @@ -840,7 +838,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( { return error; } - /*cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, + /*cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer );*/ Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, 1 ); // Q_cldfb_state+1 st_fx->cldfbSyn->Q_cldfb_state = add( st_fx->cldfbSyn->Q_cldfb_state, 1 ); diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index d45655903..4fe8f63f4 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -872,8 +872,7 @@ ivas_error amr_wb_dec_fx( bass_psfilter_fx( st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, L_FRAME, pitch_buf_fx, st_fx->bpf_off, st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, GENERIC, st_fx->Q_syn, bpf_error_signal ); - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, - negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); scaleFactor.hb_scale = scaleFactor.lb_scale; move16(); @@ -898,8 +897,9 @@ ivas_error amr_wb_dec_fx( move16(); } cldfb_synth_set_bandsToZero( st_fx, realBuffer, imagBuffer, CLDFB_NO_COL_MAX, scaleFactor ); + /* CLDFB synthesis of the combined signal */ - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); + cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); /* Bring CLDFB output to Q-1 */ Scale_sig( synth_out_fx, output_frame, negate( st_fx->Q_syn2 ) ); @@ -1095,7 +1095,7 @@ ivas_error amr_wb_dec_fx( move16(); Scale_sig( hTcxLtpDec->tcxltp_mem_in, delta, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) ); Scale_sig( hTcxLtpDec->tcxltp_mem_out, output_frame, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) ); - tcx_ltp_post( st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out_fx, NULL ); + tcx_ltp_post_fx( st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out_fx, NULL ); } /* final output of synthesis signal */ syn_output_fx( st_fx->codec_mode, synth_out_fx, output_frame, output_sp, st_fx->Q_syn2 ); diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index 75cabf160..45cf7feed 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -841,14 +841,7 @@ void addBassPostFilter_fx( } /* do the CLDFB anlysis of filtered signal */ - cldfbAnalysisFiltering( cldfbBank_bpf_Fx, - tmp_R_Fx, - tmp_I_Fx, - &scale, - harm_timeIn_Fx, - timeIn_e, - nTimeSlots, - workBuffer ); + cldfbAnalysis_fx( cldfbBank_bpf_Fx, tmp_R_Fx, tmp_I_Fx, &scale, harm_timeIn_Fx, timeIn_e, nTimeSlots, workBuffer ); /* now do the subtraction */ diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index 2fd3f1d2e..63c35f876 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -197,11 +197,7 @@ void mode_switch_decoder_LPD_fx( ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) { -#ifdef IVAS_CODE TBEreset_dec_fx( st ); -#else - TBEreset_dec_fx( st, st->bwidth ); -#endif } ELSE { @@ -445,7 +441,7 @@ void mode_switch_decoder_LPD_ivas_fx( ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) { - TBEreset_dec_ivas_fx( st ); + TBEreset_dec_fx( st ); } ELSE { diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 0f361e658..1f4f5511f 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -486,7 +486,7 @@ ivas_error core_switching_pre_dec_fx( { return error; } - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, hTcxDec->syn_Overl, 0, no_col, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, hTcxDec->syn_Overl, 0, no_col, workBuffer ); cldfb_restore_memory( st_fx->cldfbAna ); scaleFactor.hb_scale = scaleFactor.lb_scale; @@ -497,7 +497,7 @@ ivas_error core_switching_pre_dec_fx( { return error; } - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, hHQ_core->fer_samples_fx, 0, no_col, workBuffer ); + cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, hHQ_core->fer_samples_fx, 0, no_col, workBuffer ); cldfb_restore_memory( st_fx->cldfbSyn ); } @@ -1206,7 +1206,7 @@ ivas_error core_switching_post_dec_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); IF( EQ_16( output_frame, L_FRAME16k ) ) { @@ -1853,8 +1853,7 @@ ivas_error core_switching_post_dec_ivas_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); - // swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); - swb_tbe_reset_synth_ivas_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); st_fx->hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /* Q0 1.f */ st_fx->hBWE_TD->prev_mix_factor_fx = 32767; /* Q15 1.f */ @@ -1881,7 +1880,7 @@ ivas_error core_switching_post_dec_ivas_fx( } ELSE IF( st_fx->hBWE_TD != NULL && ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) ) { - TBEreset_dec_ivas_fx( st_fx ); + TBEreset_dec_fx( st_fx ); } /* reset FB TBE buffers */ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index f20ff77f3..0e9ef222c 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -54,8 +54,6 @@ ivas_error evs_dec_fx( Word16 Q_synth; Word16 Qpostd_prev; - Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX]; - Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word16 timeIn_e; TD_BWE_DEC_HANDLE hBWE_TD; HQ_DEC_HANDLE hHQ_core; @@ -98,15 +96,6 @@ ivas_error evs_dec_fx( move32(); st_fx->flag_ACELP16k = set_ACELP_flag( EVS_MONO, -1, st_fx->total_brate, 0, 0, -1, -1 ); - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - set32_fx( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer[i] = realBufferTmp[i]; - move32(); - imagBuffer[i] = imagBufferTmp[i]; - move32(); - } if ( st_fx->bfi == 0 ) { st_fx->extl = -1; @@ -279,6 +268,7 @@ ivas_error evs_dec_fx( /*------------------------------------------------------------------* * Decoding *-----------------------------------------------------------------*/ + IF( EQ_16( st_fx->codec_mode, MODE1 ) ) { /*------------------------------------------------------------------* @@ -302,6 +292,7 @@ ivas_error evs_dec_fx( } } } + IF( EQ_16( st_fx->codec_mode, MODE1 ) ) { /*------------------------------------------------------------------* @@ -339,6 +330,7 @@ ivas_error evs_dec_fx( * ACELP core decoding * HQ core decoding *---------------------------------------------------------------------*/ + IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ @@ -413,9 +405,11 @@ ivas_error evs_dec_fx( test(); IF( EQ_16( st_fx->extl, SWB_TBE ) || EQ_16( st_fx->extl, FB_TBE ) || ( NE_16( st_fx->coder_type, AUDIO ) && NE_16( st_fx->coder_type, INACTIVE ) && GT_32( st_fx->core_brate, SID_2k40 ) && EQ_16( st_fx->core, ACELP_CORE ) && GE_32( st_fx->output_Fs, 32000 ) && GT_16( st_fx->bwidth, NB ) && st_fx->bws_cnt > 0 && !st_fx->ppp_mode_dec && !( EQ_16( st_fx->nelp_mode_dec, 1 ) && EQ_16( st_fx->bfi, 1 ) ) ) ) { + /* SWB TBE decoder */ swb_tbe_dec_fx( st_fx, st_fx->coder_type, bwe_exc_extended_fx, st_fx->Q_exc, voice_factors_fx, old_syn_12k8_16k_fx, fb_exc_fx, &Q_fb_exc, hb_synth_fx, &hb_synth_fx_exp, pitch_buf_fx ); - /* FB TBE decoder/synthesis */ + + /* FB TBE decoder */ test(); IF( EQ_16( output_frame, L_FRAME48k ) && EQ_16( st_fx->extl, FB_TBE ) ) { @@ -464,6 +458,7 @@ ivas_error evs_dec_fx( /*---------------------------------------------------------------------* * SWB CNG *---------------------------------------------------------------------*/ + IF( GE_16( output_frame, L_FRAME32k ) ) { /* SHB CNG decoder */ @@ -716,17 +711,16 @@ ivas_error evs_dec_fx( delta = NS2SA_FX2( st_fx->output_Fs, TCXLTP_DELAY_NS ); /*Q0*/ Scale_sig( hTcxLtpDec->tcxltp_mem_in, delta, sub( Qpostd, Qpostd_prev ) ); /*Qpostd*/ Scale_sig( hTcxLtpDec->tcxltp_mem_out, output_frame, sub( Qpostd, Qpostd_prev ) ); /*Qpostd*/ - tcx_ltp_post( st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_fx, NULL ); - + tcx_ltp_post_fx( st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_fx, NULL ); /* final output of synthesis signal */ Copy( synth_fx, output_sp, output_frame ); /*Qpostd*/ } - ELSE /* MODE2 PART */ + ELSE /* Mode 2 */ { /* -------------------------------------------------------------- */ - /* CONCEALMENT */ + /* Mode 2 concealment */ /* -------------------------------------------------------------- */ concealWholeFrame = 0; @@ -766,11 +760,10 @@ ivas_error evs_dec_fx( /* -------------------------------------------------------------- */ - /* DECODE CORE */ + /* Decode core */ /* -------------------------------------------------------------- */ - dec_acelp_tcx_frame_fx( st_fx, &concealWholeFrame, output_sp, - st_fx->p_bpf_noise_buf, pcmbufFB, bwe_exc_extended_fx, voice_factors_fx, pitch_buf_fx ); + dec_acelp_tcx_frame_fx( st_fx, &concealWholeFrame, output_sp, st_fx->p_bpf_noise_buf, pcmbufFB, bwe_exc_extended_fx, voice_factors_fx, pitch_buf_fx ); concealWholeFrameTmp = concealWholeFrame; /*Q0*/ move16(); @@ -779,10 +772,10 @@ ivas_error evs_dec_fx( frameMode = FRAMEMODE_MISSING; move32(); } + IF( st_fx->igf ) { - - /* TBE interface */ + /* TBE for Mode 2 interface */ test(); test(); IF( ( st_fx->bfi == 0 || st_fx->last_core == ACELP_CORE ) && st_fx->core == ACELP_CORE ) @@ -888,24 +881,20 @@ ivas_error evs_dec_fx( IF( ( EQ_16( st_fx->bwidth, SWB ) || EQ_16( st_fx->bwidth, FB ) ) && ( ( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) ) && EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) { - GenTransition_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, shl( NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), 1 ), hb_synth_fx, - hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, - hBWE_TD->mem_resamp_HB_32k_fx, - &( hBWE_TD->syn_dm_phase ), st_fx->output_Fs, hBWE_TD->int_3_over_2_tbemem_dec_fx, st_fx->rf_flag, st_fx->total_brate ); + GenTransition_fx( st_fx->hBWE_TD, hb_synth_fx, st_fx->output_Fs, st_fx->rf_flag, st_fx->total_brate ); hb_synth_fx_exp = st_fx->prev_Q_bwe_syn2; move16(); } ELSE IF( EQ_16( st_fx->bwidth, WB ) && EQ_16( st_fx->last_extl, WB_TBE ) ) { - GenTransition_WB_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, st_fx->prev_Qx, shl( NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), 1 ), hb_synth_fx, - hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, st_fx->output_Fs, hBWE_TD->mem_resamp_HB_fx ); + GenTransition_WB_fx( st_fx->hBWE_TD, st_fx->prev_Qx, hb_synth_fx, st_fx->output_Fs ); hb_synth_fx_exp = st_fx->prev_Qx; move16(); } - TBEreset_dec_fx( st_fx, st_fx->bwidth ); + TBEreset_dec_fx( st_fx ); } ELSE IF( EQ_16( st_fx->last_codec_mode, MODE1 ) ) { @@ -918,7 +907,7 @@ ivas_error evs_dec_fx( move16(); fb_tbe_reset_synth_fx( hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, &hBWE_TD->prev_fbbwe_ratio_fx ); } - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); } } } @@ -932,10 +921,23 @@ ivas_error evs_dec_fx( } /* -------------------------------------------------------------- */ - /* APPLY POSTPROC */ + /* Postprocessing */ /* -------------------------------------------------------------- */ { + Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + set32_fx( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); + realBuffer[i] = realBufferTmp[i]; + move32(); + imagBuffer[i] = imagBufferTmp[i]; + move32(); + } + nab = s_min( st_fx->cldfbAna->no_channels, st_fx->cldfbSyn->no_channels ); /*Q0*/ st_fx->cldfbSyn->lsb = s_min( st_fx->cldfbAna->no_channels, st_fx->cldfbSyn->no_channels ); /*Q0*/ st_fx->cldfbSyn->usb = st_fx->cldfbSyn->no_channels; /*Q0*/ @@ -951,11 +953,12 @@ ivas_error evs_dec_fx( test(); IF( st_fx->hFdCngDec != NULL && ( EQ_32( st_fx->sr_core, 8000 ) || EQ_32( st_fx->sr_core, INT_FS_12k8 ) || EQ_32( st_fx->sr_core, INT_FS_16k ) ) && LE_32( st_fx->total_brate, ACELP_32k ) ) { - /*************************************** - In CLDFB domain: - - perform noise estimation during active frames - - do CNG during inactive frames - ****************************************/ + /* -------------------------------------------------------------- * + * In CLDFB domain: + * - perform noise estimation during active frames + * - do CNG during inactive frames + * -------------------------------------------------------------- */ + HANDLE_FD_CNG_DEC hFdCngDec = st_fx->hFdCngDec; noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD && EQ_16( st_fx->m_frame_type, ACTIVE_FRAME ), output_sp, 0 ); @@ -1003,7 +1006,7 @@ ivas_error evs_dec_fx( } Scale_sig( output_sp, st_fx->L_frame, timeIn_e ); /*timeIn_e*/ timeIn_e = negate( timeIn_e ); - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); st_fx->scaleFactor.hb_scale = st_fx->scaleFactor.lb_scale; move16(); } @@ -1064,7 +1067,7 @@ ivas_error evs_dec_fx( } timeIn_e = negate( timeIn_e ); - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &st_fx->scaleFactor, timeDomainBuffer, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); + cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &st_fx->scaleFactor, timeDomainBuffer, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); } IF( st_fx->flag_cna == 0 ) @@ -1114,8 +1117,7 @@ ivas_error evs_dec_fx( } timeIn_e = s_min( 0, add( timeIn_e, 2 ) ); - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); - /*CLDFB output always in timeIn_e*/ + cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); /*CLDFB output always in timeIn_e*/ /* MODE1 MDCT to ACELP 2 transition */ delay_comp = NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ); @@ -1331,11 +1333,10 @@ ivas_error evs_dec_fx( Scale_sig( output_sp, output_frame, timeIn_e ); /*timeIn_e*/ - tcx_ltp_post( st_fx, hTcxLtpDec, st_fx->core, output_frame /*hTcxDec->L_frameTCX*/, add( NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS ), tmps ), - output_sp, hTcxDec->FBTCXdelayBuf ); + tcx_ltp_post_fx( st_fx, hTcxLtpDec, st_fx->core, output_frame /*hTcxDec->L_frameTCX*/, add( NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS ), tmps ), output_sp, hTcxDec->FBTCXdelayBuf ); Copy( output_sp, synth_fx, output_frame ); /*timeIn_e*/ - } /* end of MODE2 */ + } /* end of Mode 2 */ /*----------------------------------------------------------------* diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index bd8a2cbd3..95f64cdbd 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1286,7 +1286,7 @@ ivas_error init_decoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_ivas_fx( st_fx, st_fx->hBWE_TD, st_fx->output_Fs ); + td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, st_fx->output_Fs ); #ifdef MSAN_FIX st_fx->hBWE_TD->prev_hb_synth_fx_exp = 31; move16(); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 7b4e5f267..6d38de35a 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -915,11 +915,11 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) && ( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) ) { - GenTransition_fixed( st->hBWE_TD, hb_synth_32_fx[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate, st->prev_Qx ); + GenTransition_fx32( st->hBWE_TD, hb_synth_32_fx[n], output_Fs, st->L_frame, st->prev_Qx ); } ELSE IF( EQ_16( st->bwidth, WB ) && EQ_16( st->last_extl, WB_TBE ) ) { - GenTransition_WB_fixed( st->hBWE_TD, hb_synth_32_fx[n], output_Fs ); + GenTransition_WB_fx32( st->hBWE_TD, hb_synth_32_fx[n], output_Fs ); } /* Memories Scaling */ diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 9357394a5..13fcb6183 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -92,7 +92,7 @@ void ivas_post_proc_fx( IF( NE_16( sts[n]->core, TCX_20_CORE ) && NE_16( sts[n]->core, TCX_10_CORE ) ) { /* TCX-LTP Postfilter: used in Mode 1 to update memories and to avoid discontinuities when the past frame was TCX */ - tcx_ltp_post32( sts[n], hTcxLtpDec, ACELP_CORE, output_frame, 0, synth, NULL, output_q ); + tcx_ltp_post_fx32( sts[n], hTcxLtpDec, ACELP_CORE, output_frame, 0, synth, NULL, output_q ); } ELSE { @@ -115,7 +115,7 @@ void ivas_post_proc_fx( Copy32( sts[n]->hHQ_core->oldOut_fx + numZeros, sts[n]->hTcxDec->FBTCXdelayBuf_32, delay_comp ); /*Q11*/ } - tcx_ltp_post32( sts[n], hTcxLtpDec, sts[n]->core, output_frame, add( NS2SA_FX2( output_Fs, ACELP_LOOK_NS ), delay_comp ), synth, sts[n]->hTcxDec->FBTCXdelayBuf_32, output_q ); + tcx_ltp_post_fx32( sts[n], hTcxLtpDec, sts[n]->core, output_frame, add( NS2SA_FX2( output_Fs, ACELP_LOOK_NS ), delay_comp ), synth, sts[n]->hTcxDec->FBTCXdelayBuf_32, output_q ); } } } @@ -152,12 +152,12 @@ void ivas_post_proc_fx( IF( NE_16( sts[0]->core, TCX_20_CORE ) && NE_16( sts[0]->core, TCX_10_CORE ) ) { /* update memories and to avoid discontinuities when the past frame was TCX */ - tcx_ltp_post32( sts[0], hTcxLtpDec, ACELP_CORE, output_frame, 0, output[k], NULL, output_q ); + tcx_ltp_post_fx32( sts[0], hTcxLtpDec, ACELP_CORE, output_frame, 0, output[k], NULL, output_q ); } ELSE { /*Use channel 0 side info.*/ - tcx_ltp_post32( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem_fx[k], output_q ); + tcx_ltp_post_fx32( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem_fx[k], output_q ); } } } diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 3b32072f3..4f289a9c4 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -630,7 +630,7 @@ void stereo_icBWE_dec_fx( Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, sub( tmp, Q_syn_shb ) ); /* tmp */ Scale_sig32( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, sub( tmp, hStereoICBWE->prev_Q_syn_shb_ola_nonref ) ); /* tmp */ - ScaleShapedSHB_32( SHB_OVERLAP_LEN, shb_synth_nonref_fx, hStereoICBWE->mem_syn_shb_ola_nonref_fx, hStereoICBWE->gshapeRef_fx, ( Mpy_32_16_1( L_shl( hStereoICBWE->gFrameRef_fx, 1 ), mult_r( gsMapping_fx, 29492 /* 0.9 in Q15 */ ) ) ), window_shb_fx, subwin_shb_fx, &tmp, &temp1_fx ); + ScaleShapedSHB_fx32( SHB_OVERLAP_LEN, shb_synth_nonref_fx, hStereoICBWE->mem_syn_shb_ola_nonref_fx, hStereoICBWE->gshapeRef_fx, ( Mpy_32_16_1( L_shl( hStereoICBWE->gFrameRef_fx, 1 ), mult_r( gsMapping_fx, 29492 /* 0.9 in Q15 */ ) ) ), window_shb_fx, subwin_shb_fx, &tmp, &temp1_fx ); hStereoICBWE->prev_Q_syn_shb_ola_nonref = tmp; move16(); @@ -664,7 +664,7 @@ void stereo_icBWE_dec_fx( Q_syn_shb = tmp; move16(); - GenSHBSynth_fx_32( shb_synth_nonref_fx, error_fx, hStereoICBWE->memShbHilbert_nonref_fx, hStereoICBWE->memShbInterp_nonref_fx, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); + GenSHBSynth_fx32( shb_synth_nonref_fx, error_fx, hStereoICBWE->memShbHilbert_nonref_fx, hStereoICBWE->memShbInterp_nonref_fx, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); } ELSE { @@ -797,7 +797,7 @@ void stereo_icBWE_dec_fx( Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); /* tmp */ Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); /* tmp */ - interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hStereoICBWE->memShb_fsout_nonref_fx ); + interpolate_3_over_2_allpass_fx32( error_fx, L_FRAME32k, synth_fx, hStereoICBWE->memShb_fsout_nonref_fx ); hStereoICBWE->prev_Q_fsout = tmp; move16(); } @@ -1313,7 +1313,7 @@ void stereo_icBWE_decproc_fx( } } /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ - td_bwe_dec_init_ivas_fx( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_TD, output_Fs ); + td_bwe_dec_init_fx( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_TD, output_Fs ); fd_bwe_dec_init( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_FD ); } diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index c70e606ac..2195a970a 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -626,7 +626,7 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_ivas_fx( st, st->hBWE_TD, st->output_Fs ); + td_bwe_dec_init_fx( st, st->hBWE_TD, st->output_Fs ); st->prev_Q_bwe_exc = 31; move16(); @@ -872,7 +872,7 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_ivas_fx( st, st->hBWE_TD, st->output_Fs ); + td_bwe_dec_init_fx( st, st->hBWE_TD, st->output_Fs ); st->prev_Q_bwe_exc = 31; move16(); diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 530cd41d0..ca0f73316 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -967,7 +967,7 @@ typedef struct td_bwe_dec_structure Word16 state_syn_shbexc_fx[L_SHB_LAHEAD]; Word16 syn_overlap_fx[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain*/ - Word32 syn_overlap_fx_32[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain*/ + Word32 syn_overlap_fx_32[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain, IVAS 32-bit variant */ /* previous frame parameters for frame error concealment */ Word16 lsp_prevfrm_fx[LPC_SHB_ORDER]; @@ -997,19 +997,19 @@ typedef struct td_bwe_dec_structure Word16 mem_genSHBexc_filt_down_wb3_fx[2 * ALLPASSSECTIONS_STEEP + 1]; Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[2 * ALLPASSSECTIONS_STEEP]; - Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[2 * ALLPASSSECTIONS_STEEP]; + Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[2 * ALLPASSSECTIONS_STEEP]; /* IVAS 32-bit variant */ Word16 state_lsyn_filt_shb_fx[2 * ALLPASSSECTIONS_STEEP]; - Word32 state_lsyn_filt_shb_fx_32[2 * ALLPASSSECTIONS_STEEP]; + Word32 state_lsyn_filt_shb_fx_32[2 * ALLPASSSECTIONS_STEEP]; /* IVAS 32-bit variant */ Word16 state_lsyn_filt_dwn_shb_fx[2 * ALLPASSSECTIONS_STEEP]; - Word32 state_lsyn_filt_dwn_shb_fx_32[2 * ALLPASSSECTIONS_STEEP]; + Word32 state_lsyn_filt_dwn_shb_fx_32[2 * ALLPASSSECTIONS_STEEP]; /* IVAS 32-bit variant */ Word16 mem_resamp_HB_fx[INTERP_3_1_MEM_LEN]; - Word32 mem_resamp_HB_fx_32[INTERP_3_1_MEM_LEN]; + Word32 mem_resamp_HB_fx_32[INTERP_3_1_MEM_LEN]; /* IVAS 32-bit variant */ Word16 mem_resamp_HB_32k_fx[2 * ALLPASSSECTIONS_STEEP + 1]; - Word32 mem_resamp_HB_32k_fx_32[2 * ALLPASSSECTIONS_STEEP + 1]; + Word32 mem_resamp_HB_32k_fx_32[2 * ALLPASSSECTIONS_STEEP + 1]; /* IVAS 32-bit variant */ Word16 state_32and48k_WB_upsample_fx[2 * ALLPASSSECTIONS_STEEP]; /* !!! this memory in FLP is called mem_resamp_HB */ @@ -1090,10 +1090,10 @@ typedef struct td_bwe_dec_structure Word16 old_core_synth_fx[L_FRAME16k]; Word16 old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH]; - Word32 old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH]; + Word32 old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH]; /* IVAS 32-bit variant */ Word16 int_3_over_2_tbemem_dec_fx[INTERP_3_2_MEM_LEN]; - Word32 int_3_over_2_tbemem_dec_fx_32[INTERP_3_2_MEM_LEN]; + Word32 int_3_over_2_tbemem_dec_fx_32[INTERP_3_2_MEM_LEN]; /* IVAS 32-bit variant */ Word16 old_hb_synth_fx[L_FRAME48k]; diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index cc9b681fb..8b2ecb302 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -413,52 +413,6 @@ void rescale_genWB_mem( Decoder_State *st_fx, Word16 sf ) } } -void InitSWBdecBuffer_ivas_fx( - Decoder_State *st_fx /* i/o: SHB decoder structure */ -) -{ - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, ( PIT16k_MAX * 2 ) ); - hBWE_TD->bwe_seed[0] = 23; - move16(); - hBWE_TD->bwe_seed[1] = 59; - move16(); - - set16_fx( hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); - hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move16(); - - set32_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, 0, HILBERT_MEM_SIZE ); - set16_fx( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); /* Interp all pass memory */ - set32_fx( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP ); /* Interp all pass memory */ - - hBWE_TD->syn_dm_phase = 0; - move16(); - hBWE_TD->prev_fbbwe_ratio_fx = 32767 /*1.0f Q15*/; - move16(); - - /* these are fd-bwe constants */ - hBWE_TD->prev_wb_bwe_frame_pow_fx = 4194l /*0.001f Q22*/; /* Q22 */ - move32(); - hBWE_TD->prev_swb_bwe_frame_pow_fx = 4194l /*0.001f Q22*/; /* Q22 */ - move32(); - st_fx->prev_Q_bwe_exc = 31; - move16(); - st_fx->prev_ener_fx_Q = 31; - move16(); - st_fx->prev_Qx = 0; - move16(); - st_fx->prev_frame_pow_exp = 0; - move16(); - st_fx->prev_Q_bwe_syn = 0; - move16(); - st_fx->prev_Q_bwe_syn2 = 0; - move16(); - return; -} - void InitSWBdecBuffer_fx( Decoder_State *st_fx /* i/o: SHB decoder structure */ @@ -478,7 +432,8 @@ void InitSWBdecBuffer_fx( move16(); set32_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, 0, HILBERT_MEM_SIZE ); - set16_fx( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); /* Interp all pass memory */ + set16_fx( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); /* Interp all pass memory */ + set32_fx( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP ); /* Interp all pass memory */ hBWE_TD->syn_dm_phase = 0; move16(); @@ -4893,35 +4848,33 @@ void tbe_read_bitstream_fx( * buffer to fill the gap caused by the delay alignment buffer when * switching from TBE to IGF *---------------------------------------------------------------------*/ + void GenTransition_fx( - const Word16 *input, /* i : gain shape overlap buffer Q11 */ - const Word16 *old_hb_synth, /* i : synthesized HB from previous frame Q(15 - hb_synth_fx_exp)*/ - Word16 length, /* i : targeted length of transition signal */ - Word16 *output, /* o : synthesized transitions signal st_fx->prev_Q_bwe_syn2 */ - Word32 Hilbert_Mem[], /* i/o: memory st_fx->prev_Q_bwe_syn2 */ - Word16 state_lsyn_filt_shb_local[], /* i/o: memory st_fx->prev_Q_bwe_syn2*/ - Word16 mem_resamp_HB_32k[], /* i/o: memory */ - Word16 *syn_dm_phase, - Word32 target_fs, - Word16 *up_mem, - Word16 rf_flag, - Word32 bitrate ) + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word16 *output_HB, /* o : synthesized HB transitions signal st_fx->prev_Q_bwe_syn2 */ + const Word32 output_Fs, /* i : output sampling rate */ + Word16 rf_flag, /* i : RF flag */ + Word32 total_bitrate /* i : total bitrate */ +) { - Word16 i; + Word16 i, length; Word16 syn_overlap_32k[L_FRAME32k]; Word32 L_tmp; Word16 ol_len = 2 * SHB_OVERLAP_LEN; + /* set targeted length of transition signal */ + length = shl( NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ), 1 ); + /* upsample overlap snippet */ - Interpolate_allpass_steep_fx( input, state_lsyn_filt_shb_local, SHB_OVERLAP_LEN, syn_overlap_32k ); + Interpolate_allpass_steep_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, SHB_OVERLAP_LEN, syn_overlap_32k ); /* perform spectral flip and downmix with overlap snippet to match HB synth */ test(); - IF( ( rf_flag != 0 ) || EQ_32( bitrate, ACELP_9k60 ) ) + IF( ( rf_flag != 0 ) || EQ_32( total_bitrate, ACELP_9k60 ) ) { - flip_and_downmix_generic_fx( syn_overlap_32k, syn_overlap_32k, 2 * SHB_OVERLAP_LEN, Hilbert_Mem, - Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), - syn_dm_phase ); + flip_and_downmix_generic_fx( syn_overlap_32k, syn_overlap_32k, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, + hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), + &( hBWE_TD->syn_dm_phase ) ); } ELSE { @@ -4937,25 +4890,91 @@ void GenTransition_fx( /* cross fade of overlap snippet and mirrored HB synth from previous frame */ FOR( i = 0; i < ol_len; i++ ) { - L_tmp = L_mult( window_shb_32k_fx[i], old_hb_synth[L_SHB_TRANSITION_LENGTH - 1 - i] ); - output[i] = mac_r( L_tmp, window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i], syn_overlap_32k[i] ); + L_tmp = L_mult( window_shb_32k_fx[i], hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i] ); + output_HB[i] = mac_r( L_tmp, window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i], syn_overlap_32k[i] ); move16(); } /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ FOR( ; i < length; i++ ) { - output[i] = old_hb_synth[L_SHB_TRANSITION_LENGTH - 1 - i]; + output_HB[i] = hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i]; move16(); } - IF( EQ_32( target_fs, 48000 ) ) + IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_2_allpass_fx( output_HB, length, output_HB, hBWE_TD->int_3_over_2_tbemem_dec_fx, allpass_poles_3_ov_2 ); + } + ELSE IF( EQ_32( output_Fs, 16000 ) ) + { + Decimate_allpass_steep_fx( output_HB, hBWE_TD->mem_resamp_HB_32k_fx, L_FRAME32k, output_HB ); + } + + return; +} + +/* IVAS 32-bit variant */ +void GenTransition_fx32( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 prev_Qx ) +{ + Word16 i, length; + + Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_fx32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + test(); + IF( EQ_16( L_frame, L_FRAME ) ) + { + flip_and_downmix_generic_fx32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); + } + ELSE + { + FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); + } + ELSE + { + syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; + } + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) { - interpolate_3_over_2_allpass_fx( output, length, output, up_mem, allpass_poles_3_ov_2 ); + outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); + move32(); } - ELSE IF( EQ_32( target_fs, 16000 ) ) + + IF( EQ_32( output_Fs, 48000 ) ) { - Decimate_allpass_steep_fx( output, mem_resamp_HB_32k, L_FRAME32k, output ); + interpolate_3_over_2_allpass_fx32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( output_Fs, 16000 ) ) + { + Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); } return; @@ -4963,32 +4982,30 @@ void GenTransition_fx( /*---------------------------------------------------------------------* - * GenTransition_WB_fx() + * GenTransition_WB() * *---------------------------------------------------------------------*/ void GenTransition_WB_fx( - const Word16 *input, /* i : gain shape overlap buffer */ - const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ - const Word16 prev_Qx, /* i : scaling of old_hb_synth */ - Word16 length, /* i : targeted length of transition signal */ - Word16 *output, /* o : synthesized transitions signal */ - Word16 state_lsyn_filt_shb1[], - Word16 state_lsyn_filt_shb2[], - Word32 output_Fs, - Word16 *up_mem ) + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + const Word16 prev_Qx, /* i : scaling of old_hb_synth */ + Word16 *output, /* o : synthesized transitions signal */ + const Word32 output_Fs /* i : output sampling rate */ +) { - Word16 i; + Word16 i, length; Word32 L_tmp; Word16 speech_buf_16k1[L_FRAME16k], speech_buf_16k2[L_FRAME16k]; Word16 upsampled_synth[L_FRAME48k]; Word16 input_scaled[SHB_OVERLAP_LEN / 2]; - /* upsample overlap snippet */ - Copy_Scale_sig( input, input_scaled, SHB_OVERLAP_LEN / 2, prev_Qx ); - Interpolate_allpass_steep_fx( input_scaled, state_lsyn_filt_shb1, SHB_OVERLAP_LEN / 2, speech_buf_16k1 ); - Interpolate_allpass_steep_fx( speech_buf_16k1, state_lsyn_filt_shb2, SHB_OVERLAP_LEN, speech_buf_16k2 ); + /* set targeted length of transition signal */ + length = shl( NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ), 1 ); + /* upsample overlap snippet */ + Copy_Scale_sig( hBWE_TD->syn_overlap_fx, input_scaled, SHB_OVERLAP_LEN / 2, prev_Qx ); + Interpolate_allpass_steep_fx( input_scaled, hBWE_TD->state_lsyn_filt_shb_fx, SHB_OVERLAP_LEN / 2, speech_buf_16k1 ); + Interpolate_allpass_steep_fx( speech_buf_16k1, hBWE_TD->state_lsyn_filt_dwn_shb_fx, SHB_OVERLAP_LEN, speech_buf_16k2 ); /* perform spectral flip and downmix with overlap snippet to match HB synth */ FOR( i = 0; i < SHB_OVERLAP_LEN; i += 2 ) @@ -5000,7 +5017,7 @@ void GenTransition_WB_fx( /* cross fade of overlap snippet and mirrored HB synth from previous frame */ FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { - L_tmp = L_mult( window_shb_fx[i], old_hb_synth[L_SHB_TRANSITION_LENGTH - 1 - i] ); + L_tmp = L_mult( window_shb_fx[i], hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i] ); output[i] = mac_r( L_tmp, window_shb_fx[L_SHB_LAHEAD - 1 - i], speech_buf_16k2[i] ); move16(); output[i] = mult_r( output[i], 21299 ); @@ -5010,105 +5027,116 @@ void GenTransition_WB_fx( /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ FOR( ; i < length; i++ ) { - output[i] = mult_r( old_hb_synth[L_SHB_TRANSITION_LENGTH - 1 - i], 21299 ); + output[i] = mult_r( hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], 21299 ); move16(); } /* upsampling if necessary */ IF( EQ_32( output_Fs, 32000 ) ) { - Interpolate_allpass_steep_fx( output, up_mem, L_FRAME16k, upsampled_synth ); + Interpolate_allpass_steep_fx( output, hBWE_TD->mem_resamp_HB_fx, L_FRAME16k, upsampled_synth ); Copy( upsampled_synth, output, L_FRAME32k ); } ELSE IF( EQ_32( output_Fs, 48000 ) ) { - interpolate_3_over_1_allpass_fx( output, L_FRAME16k, upsampled_synth, up_mem ); + interpolate_3_over_1_allpass_fx( output, L_FRAME16k, upsampled_synth, hBWE_TD->mem_resamp_HB_fx ); Copy( upsampled_synth, output, L_FRAME48k ); } return; } -/*---------------------------------------------------------------------* - * TBEreset_dec_fx() - * - *---------------------------------------------------------------------*/ -void TBEreset_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 bandwidth /* i : bandwidth mode */ +/* IVAS 32-bit variant */ +void GenTransition_WB_fx32( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ ) { - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; + Word16 i, length; + Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; + Word32 upsampled_synth_fx[L_FRAME48k]; - IF( NE_16( st_fx->last_core, ACELP_CORE ) ) + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_fx32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); + Interpolate_allpass_steep_fx32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) { - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); + IF( i % 2 == 0 ) + { + speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); + move32(); + } + ELSE + { + speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); move32(); - st_fx->prev_Q_bwe_exc = 31; - move16(); } - test(); - IF( EQ_16( bandwidth, WB ) ) + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) { - wb_tbe_extras_reset_fx( hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); - wb_tbe_extras_reset_synth_fx( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_32and48k_WB_upsample_fx, hBWE_TD->mem_resamp_HB_fx ); + outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } - set16_fx( hBWE_TD->mem_genSHBexc_filt_down_shb_fx, 0, 7 ); - set16_fx( hBWE_TD->state_lpc_syn_fx, 0, 10 ); - set16_fx( hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); - set16_fx( hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); - set32_fx( hBWE_TD->mem_csfilt_fx, 0, 2 ); + /* upsampling if necessary */ + IF( EQ_32( output_Fs, 32000 ) ) + { + Interpolate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); } - ELSE IF( EQ_16( bandwidth, SWB ) || EQ_16( bandwidth, FB ) ) + ELSE IF( EQ_32( output_Fs, 48000 ) ) { - swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, - hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), - &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); - - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); - - set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); - set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); - set32_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx_32, 0, INTERP_3_2_MEM_LEN ); - set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - set32_fx( hBWE_TD->mem_resamp_HB_32k_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - - IF( EQ_16( bandwidth, FB ) ) - { - st_fx->prev_fb_ener_adjust_fx = 0; - move16(); - set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - hBWE_TD->fb_tbe_demph_fx = 0; - move16(); - fb_tbe_reset_synth_fx( hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, &hBWE_TD->prev_fbbwe_ratio_fx ); - } + interpolate_3_over_1_allpass_fx32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); } return; } -void TBEreset_dec_ivas_fx( - Decoder_State *st /* i/o: decoder state structure */ + +/*---------------------------------------------------------------------* + * TBEreset_dec() + * + *---------------------------------------------------------------------*/ + +void TBEreset_dec_fx( + Decoder_State *st_fx /* i/o: decoder state structure */ ) { TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; - hBWE_TD = st->hBWE_TD; - - IF( st->last_core != ACELP_CORE ) + IF( NE_16( st_fx->last_core, ACELP_CORE ) ) { set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); move32(); - st->prev_Q_bwe_exc = 31; + st_fx->prev_Q_bwe_exc = 31; move16(); } + test(); - IF( EQ_16( st->bwidth, WB ) ) + IF( EQ_16( st_fx->bwidth, WB ) ) { wb_tbe_extras_reset_fx( hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); wb_tbe_extras_reset_synth_fx( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_32and48k_WB_upsample_fx, hBWE_TD->mem_resamp_HB_fx ); @@ -5120,28 +5148,25 @@ void TBEreset_dec_ivas_fx( set32_fx( hBWE_TD->syn_overlap_fx_32, 0, L_SHB_LAHEAD ); set32_fx( hBWE_TD->mem_csfilt_fx, 0, 2 ); } - ELSE IF( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) + ELSE IF( EQ_16( st_fx->bwidth, SWB ) || EQ_16( st_fx->bwidth, FB ) ) { - swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); + swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), + &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); + + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); - set16_fx( st->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); set32_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx_32, 0, INTERP_3_2_MEM_LEN ); set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); set32_fx( hBWE_TD->mem_resamp_HB_32k_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /* Q0 1.f */ - move32(); - hBWE_TD->prev_mix_factor_fx = 32767; /* Q15 1.f */ - move16(); - // swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); - swb_tbe_reset_synth_ivas_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); - - IF( EQ_16( st->bwidth, FB ) ) + IF( EQ_16( st_fx->bwidth, FB ) ) { - if ( st->hBWE_FD != NULL ) + if ( st_fx->hBWE_FD != NULL ) { - st->prev_fb_ener_adjust_fx = 0; + st_fx->prev_fb_ener_adjust_fx = 0; move16(); } set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); @@ -5154,84 +5179,13 @@ void TBEreset_dec_ivas_fx( return; } + /*-------------------------------------------------------------------* * td_bwe_dec_init() * * Initialize TD BWE state structure at the decoder *-------------------------------------------------------------------*/ -void td_bwe_dec_init_ivas_fx( - Decoder_State *st_fx, /* i/o: SHB decoder structure */ - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const Word32 output_Fs /* i : output sampling rate */ -) -{ - Word16 i; - - /* init. SHB buffers */; - InitSWBdecBuffer_ivas_fx( st_fx ); - - /* reset SHB buffers */ - ResetSHBbuffer_Dec_fx( st_fx ); - IF( EQ_32( output_Fs, 48000 ) ) - { - set32_fx( hBWE_TD->fbbwe_hpf_mem_fx[0], 0, 4 ); - set32_fx( hBWE_TD->fbbwe_hpf_mem_fx[1], 0, 4 ); - set32_fx( hBWE_TD->fbbwe_hpf_mem_fx[2], 0, 4 ); - set32_fx( hBWE_TD->fbbwe_hpf_mem_fx[3], 0, 4 ); - set16_fx( hBWE_TD->fbbwe_hpf_mem_fx_Q, 0, 4 ); - } - - set16_fx( hBWE_TD->mem_resamp_HB_fx, 0, INTERP_3_1_MEM_LEN ); - set32_fx( hBWE_TD->mem_resamp_HB_fx_32, 0, INTERP_3_1_MEM_LEN ); - set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - set32_fx( hBWE_TD->mem_resamp_HB_32k_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - - hBWE_TD->tilt_mem_fx = 0; - move16(); - set16_fx( hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); - hBWE_TD->prev_tilt_para_fx = 0; - move16(); - set16_fx( hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); - set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); - set32_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx_32, 0, INTERP_3_2_MEM_LEN ); - /* TD BWE post-processing */ - hBWE_TD->ptr_mem_stp_swb_fx = hBWE_TD->mem_stp_swb_fx + LPC_SHB_ORDER - 1; - set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->swb_lsp_prev_interp_fx[i] = swb_lsp_prev_interp_init[i]; - move16(); - } - - hBWE_TD->prev1_shb_ener_sf_fx = 32767; /* Q15*/ - move16(); - hBWE_TD->prev2_shb_ener_sf_fx = 32767; /* Q15*/ - move16(); - hBWE_TD->prev3_shb_ener_sf_fx = 32767; /* Q15*/ - move16(); - hBWE_TD->prev_res_shb_gshape_fx = 8192; /* 0.125 in Q14*/ - move16(); - hBWE_TD->prev_mixFactors_fx = 16384; /* 0.5 in Q15*/ - move16(); - hBWE_TD->prev_GainShape_fx = 0; - move16(); - st_fx->prev_Q_bwe_exc_fb = 51; - move16(); - set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - hBWE_TD->fb_tbe_demph_fx = 0; - move16(); - - set16_fx( hBWE_TD->old_hb_synth_fx, 0, L_FRAME48k ); - - hBWE_TD->prev_ener_fx = L_deposit_l( 0 ); - move32(); - - return; -} - - void td_bwe_dec_init_fx( Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ @@ -5255,7 +5209,7 @@ void td_bwe_dec_init_fx( } set16_fx( hBWE_TD->mem_resamp_HB_fx, 0, INTERP_3_1_MEM_LEN ); - + set32_fx( hBWE_TD->mem_resamp_HB_fx_32, 0, INTERP_3_1_MEM_LEN ); set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); set32_fx( hBWE_TD->mem_resamp_HB_32k_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); @@ -5267,6 +5221,7 @@ void td_bwe_dec_init_fx( set16_fx( hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); set32_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx_32, 0, INTERP_3_2_MEM_LEN ); + /* TD BWE post-processing */ hBWE_TD->ptr_mem_stp_swb_fx = hBWE_TD->mem_stp_swb_fx + LPC_SHB_ORDER - 1; set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); @@ -7045,7 +7000,7 @@ void ivas_swb_tbe_dec_fx( } /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ - GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); + GenSHBSynth_fx32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); @@ -7112,7 +7067,7 @@ void ivas_swb_tbe_dec_fx( move32(); } } - interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + interpolate_3_over_2_allpass_fx32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); } ELSE IF( EQ_32( st->output_Fs, 32000 ) ) { @@ -7143,7 +7098,6 @@ void ivas_swb_tbe_dec_fx( Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); } - /* Update previous frame parameters for FEC */ Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); IF( EQ_16( st->codec_mode, MODE1 ) ) @@ -7183,138 +7137,3 @@ void ivas_swb_tbe_dec_fx( return; } - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ) -{ - Word16 i, length; - - Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); - - /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ - test(); - test(); - test(); - test(); - IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) - { - flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); - } - ELSE - { - FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); - } - ELSE - { - syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; - } - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); - move32(); - } - - IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( output_Fs, 16000 ) ) - { - Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); - } - - return; -} -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -) -{ - Word16 i, length; - Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; - Word32 upsampled_synth_fx[L_FRAME48k]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); - Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); - - /* perform spectral flip and downmix with overlap snippet to match HB synth */ - FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); - move32(); - } - ELSE - { - speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* upsampling if necessary */ - IF( EQ_32( output_Fs, 32000 ) ) - { - Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); - } - ELSE IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); - } - - return; -} diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 67621c442..00ba69535 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -254,7 +254,7 @@ void updt_IO_switch_dec_fx( move32(); hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 1.f*/ move16(); - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); } IF( EQ_16( output_frame, L_FRAME48k ) ) diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 5c96a2f29..acdd971fd 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -715,8 +715,7 @@ void swb_pre_proc_fx( CldfbHB_ener = L_mult( sub( Cldfbtemp1, 1741 /*3.401 Q9*/ ), 3495 ); /* 3495 = Q19 log10(2)*0.1/log10(32768), Q = 19+9+1 = 29 */ hBWE_TD->cldfbHBLT = mac_r( CldfbHB_ener, 29491 /*0.9 Q15*/, hBWE_TD->cldfbHBLT ); /* cldfbHBLT is in Q13 */ } - cldfbSynthesisFiltering( st_fx->cldfbSynTd, realBufferFlipped, imagBufferFlipped, - cldfbScale, shb_speech_fx, 0, CLDFB_NO_COL_MAX, cldfbWorkBuffer ); + cldfbSynthesis_fx( st_fx->cldfbSynTd, realBufferFlipped, imagBufferFlipped, cldfbScale, shb_speech_fx, 0, CLDFB_NO_COL_MAX, cldfbWorkBuffer ); *Q_shb_spch = 0; /*shb_speech_fx : Q0*/ move16(); -- GitLab From c45a368e662702b4ca45a8a8d34a5c66800c5c43 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Mar 2025 18:09:24 +0100 Subject: [PATCH 0437/1221] fix EVS decoding --- lib_dec/swb_tbe_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 8b2ecb302..9a1ed38d4 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4890,7 +4890,7 @@ void GenTransition_fx( /* cross fade of overlap snippet and mirrored HB synth from previous frame */ FOR( i = 0; i < ol_len; i++ ) { - L_tmp = L_mult( window_shb_32k_fx[i], hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i] ); + L_tmp = L_mult( window_shb_32k_fx[i], hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i] ); output_HB[i] = mac_r( L_tmp, window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i], syn_overlap_32k[i] ); move16(); } @@ -4898,7 +4898,7 @@ void GenTransition_fx( /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ FOR( ; i < length; i++ ) { - output_HB[i] = hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i]; + output_HB[i] = hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i]; move16(); } -- GitLab From d49a54e049fca4ef2c791cccc7ae6c3ea4dd6470 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Mar 2025 19:06:41 +0100 Subject: [PATCH 0438/1221] fix IVAS decoding --- lib_dec/core_switching_dec_fx.c | 2 +- lib_dec/evs_dec_fx.c | 2 +- lib_dec/swb_tbe_dec_fx.c | 6 +++++- lib_dec/updt_dec_fx.c | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 1f4f5511f..587eb8b0c 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1206,7 +1206,7 @@ ivas_error core_switching_post_dec_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); IF( EQ_16( output_frame, L_FRAME16k ) ) { diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 0e9ef222c..002fae3ba 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -907,7 +907,7 @@ ivas_error evs_dec_fx( move16(); fb_tbe_reset_synth_fx( hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, &hBWE_TD->prev_fbbwe_ratio_fx ); } - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); } } } diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 9a1ed38d4..8c1346358 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -5154,13 +5154,17 @@ void TBEreset_dec_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); set32_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx_32, 0, INTERP_3_2_MEM_LEN ); set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); set32_fx( hBWE_TD->mem_resamp_HB_32k_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); + hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /* Q0 1.f */ + move32(); + hBWE_TD->prev_mix_factor_fx = 32767; /* Q15 1.f */ + move16(); IF( EQ_16( st_fx->bwidth, FB ) ) { diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 00ba69535..4704d15c7 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -254,7 +254,7 @@ void updt_IO_switch_dec_fx( move32(); hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 1.f*/ move16(); - swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, NULL ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); } IF( EQ_16( output_frame, L_FRAME48k ) ) -- GitLab From 30924148768f5b7bb44239a67324096777b93705 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Mar 2025 21:39:40 +0100 Subject: [PATCH 0439/1221] fix --- lib_dec/ivas_core_dec_fx.c | 63 +++++++++++--------------------------- lib_dec/swb_tbe_dec_fx.c | 4 +-- 2 files changed, 20 insertions(+), 47 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 6d38de35a..b0190bfec 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -64,6 +64,7 @@ ivas_error ivas_core_dec_fx( Decoder_State **sts, *st; STEREO_ICBWE_DEC_HANDLE hStereoICBWE; STEREO_TD_DEC_DATA_HANDLE hStereoTD; + STEREO_CNG_DEC_HANDLE hStereoCng; Word16 sharpFlag[CPE_CHANNELS]; Word16 tmp_buffer_fx[L_FRAME48k]; set16_fx( tmp_buffer_fx, 0, L_FRAME48k ); @@ -146,6 +147,7 @@ ivas_error ivas_core_dec_fx( last_element_mode = IVAS_SCE; move16(); hStereoTD = NULL; + hStereoCng = NULL; p_output_mem_fx = NULL; nchan_out = 1; move16(); @@ -170,6 +172,7 @@ ivas_error ivas_core_dec_fx( move16(); hStereoICBWE = hCPE->hStereoICBWE; hStereoTD = hCPE->hStereoTD; + hStereoCng = hCPE->hStereoCng; p_output_mem_fx = hCPE->output_mem_fx[1]; nchan_out = hCPE->nchan_out; @@ -242,8 +245,6 @@ ivas_error ivas_core_dec_fx( move16(); st->GSC_IVAS_mode = 0; move16(); - st->element_brate = element_brate; - move32(); st->use_partial_copy = 0; move16(); st->rf_flag = 0; @@ -345,8 +346,7 @@ ivas_error ivas_core_dec_fx( /* MDCT stereo -> DFT stereo switching */ test(); - test(); - IF( hCPE != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) && EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) ) { Word16 ovl, fade_len; IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) @@ -370,9 +370,9 @@ ivas_error ivas_core_dec_fx( } test(); - if ( hCPE != NULL && hCPE->hStereoCng != NULL ) + if ( hStereoCng != NULL ) { - hCPE->hStereoCng->flag_cna_fade = 0; + hStereoCng->flag_cna_fade = 0; move16(); } @@ -413,7 +413,7 @@ ivas_error ivas_core_dec_fx( test(); IF( hCPE != NULL && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->brate_surplus > 0 ) { - ivas_combined_format_brate_sanity_fx( hCPE->element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); + ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } /*------------------------------------------------------------------* @@ -534,20 +534,11 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, add( M, 1 ), sub( norm_s( sub( st->hFdCngDec->hFdCngCom->A_cng[0], 1 ) ), 3 ) ); // Qx } - IF( hCPE == NULL ) - { - IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, NULL, read_sid_info ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - ELSE + IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) { - IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hCPE->hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) - { - return error; - } + return error; } + #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 #else @@ -594,7 +585,6 @@ ivas_error ivas_core_dec_fx( IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { Word16 Qsyn_temp; - STEREO_CNG_DEC_HANDLE hStereoCng; IVAS_FORMAT ivas_format; Qsyn_temp = st->Q_syn; @@ -620,14 +610,6 @@ ivas_error ivas_core_dec_fx( st->hHQ_core->Q_old_wtda = 0; move16(); - IF( hCPE == NULL ) - { - hStereoCng = NULL; - } - ELSE - { - hStereoCng = hCPE->hStereoCng; - } IF( st_ivas == NULL ) { ivas_format = 0; @@ -784,7 +766,7 @@ ivas_error ivas_core_dec_fx( sts[0] = hCPE->hCoreCoder[0]; sts[1] = hCPE->hCoreCoder[1]; - IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) + IF( LE_32( last_element_brate, IVAS_SID_5k2 ) ) { sts[0]->hHQ_core->exp_old_out = sub( 15, sts[0]->hHQ_core->Q_old_wtda ); move16(); @@ -793,7 +775,7 @@ ivas_error ivas_core_dec_fx( } updateBuffersForDmxMdctStereo_fx( hCPE, output_frame, output_32_fx[0], output_32_fx[1], synth_16_fx ); - IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) + IF( LE_32( last_element_brate, IVAS_SID_5k2 ) ) { sts[0]->hHQ_core->Q_old_wtda = sub( 15, sts[0]->hHQ_core->exp_old_out ); move16(); @@ -836,7 +818,7 @@ ivas_error ivas_core_dec_fx( *---------------------------------------------------------------------*/ test(); - IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hCPE->hStereoCng != NULL ) + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; @@ -846,13 +828,13 @@ ivas_error ivas_core_dec_fx( move16(); Q_output = 11; move16(); - c_PS_LT_fx = L_deposit_h( hCPE->hStereoCng->c_PS_LT_fx ); + c_PS_LT_fx = L_deposit_h( hStereoCng->c_PS_LT_fx ); Q_c_PS_LT = Q31; move16(); stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); - hCPE->hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); + hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); } /*---------------------------------------------------------------------* @@ -976,16 +958,7 @@ ivas_error ivas_core_dec_fx( ivas_format = UNDEFINED_FORMAT; move32(); } - IF( hCPE != NULL ) - { - last_element_mode = hCPE->last_element_mode; - move16(); - } - ELSE - { - last_element_mode = IVAS_SCE; - move16(); - } + IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, ivas_format, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) { return error; @@ -1011,7 +984,7 @@ ivas_error ivas_core_dec_fx( test(); test(); test(); - IF( n == 0 && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->last_core == ACELP_CORE && st->core != ACELP_CORE && ( EQ_16( nchan_out, 1 ) || ( hCPE != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) ) ) + IF( n == 0 && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->last_core == ACELP_CORE && st->core != ACELP_CORE && ( EQ_16( nchan_out, 1 ) || EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } @@ -1588,7 +1561,7 @@ ivas_error ivas_core_dec_fx( Word16 q; q = 11; move16(); - IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) + IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) ) { stereo_mdct2dft_update_fx( hCPE, output_32_fx[0], synth_32_fx[0] ); } diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 8c1346358..58ec4b696 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -5017,7 +5017,7 @@ void GenTransition_WB_fx( /* cross fade of overlap snippet and mirrored HB synth from previous frame */ FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { - L_tmp = L_mult( window_shb_fx[i], hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i] ); + L_tmp = L_mult( window_shb_fx[i], hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i] ); output[i] = mac_r( L_tmp, window_shb_fx[L_SHB_LAHEAD - 1 - i], speech_buf_16k2[i] ); move16(); output[i] = mult_r( output[i], 21299 ); @@ -5027,7 +5027,7 @@ void GenTransition_WB_fx( /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ FOR( ; i < length; i++ ) { - output[i] = mult_r( hBWE_TD->old_hb_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], 21299 ); + output[i] = mult_r( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], 21299 ); move16(); } -- GitLab From 8ff96d33177255f3b14316c4fac4e72b65e0d921 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Mar 2025 21:52:10 +0100 Subject: [PATCH 0440/1221] revert removal --- lib_dec/ivas_core_dec_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index b0190bfec..6d7d4fc97 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -245,6 +245,8 @@ ivas_error ivas_core_dec_fx( move16(); st->GSC_IVAS_mode = 0; move16(); + st->element_brate = element_brate; + move32(); st->use_partial_copy = 0; move16(); st->rf_flag = 0; -- GitLab From 33e789648b126bcdbc980b3424e231e828a691d3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 09:36:32 +0530 Subject: [PATCH 0441/1221] LTV crash fix by correcting Q in swb_bwe, few synthesis buffer related fixes --- lib_com/rom_com.c | 48 +++++++++++++++++----------------- lib_com/rom_com.h | 8 ------ lib_com/syn_filt_fx.c | 8 +++--- lib_enc/acelp_core_enc_fx.c | 28 +++++++++----------- lib_enc/enc_uv_fx.c | 2 +- lib_enc/ivas_tcx_core_enc_fx.c | 5 ---- lib_enc/prot_fx_enc.h | 2 +- lib_enc/swb_bwe_enc_fx.c | 2 +- 8 files changed, 44 insertions(+), 59 deletions(-) diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 172dadf82..87b323d0a 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -1769,35 +1769,35 @@ static const Word16 filter_LP30_300K_fx[LFE_PLC_FDEL + 1] = const Resampling_cfg resampling_cfg_tbl[] = { /* fin fout up.fact. den.fac. len.out filter coefs. filter length/2 filter mem./2 flags */ - { 8000, 8000, 12800, 12800, 8, 8, 5, 256, /*filter5_39s320_120,*/ filter5_39s320_120_fx, 15, 15, RS_INV_FAC, RS_INV_FAC }, - { 12800, 12800, 8000, 8000, 5, 5, 8, 160, /*filter5_39s320_120,*/ filter5_39s320_120_fx, L_FILT_UP8k, L_FILT_UP8k, RS_INV_FAC, RS_INV_FAC }, - { 16000, 16000, 8000, 8000, 6, 6, 12, 160, /*filter_LP12_180H,*/ filter_LP12_180H_fx, 180 / 6, 180 / 6, 0, 0 }, - { 12800, 12800, 16000, 16000, 15, 15, 12, 320, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT_UP16k, L_FILT_UP16k, 0, 0 }, - { 12800, 12800, 32000, 32000, 15, 15, 6, 640, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT_UP32k, L_FILT_UP32k, 0, 0 }, - { 12800, 12800, 48000, 48000, 15, 15, 4, 960, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT_UP48k, L_FILT_UP48k, 0, 0 }, + { 8000, 12800, 8, 5, 256, /*filter5_39s320_120,*/ filter5_39s320_120_fx, 15, RS_INV_FAC }, + { 12800, 8000, 5, 8, 160, /*filter5_39s320_120,*/ filter5_39s320_120_fx, L_FILT_UP8k, RS_INV_FAC }, + { 16000, 8000, 6, 12, 160, /*filter_LP12_180H,*/ filter_LP12_180H_fx, 180 / 6, 0 }, + { 12800, 16000, 15, 12, 320, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT_UP16k, 0 }, + { 12800, 32000, 15, 6, 640, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT_UP32k, 0 }, + { 12800, 48000, 15, 4, 960, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT_UP48k, 0 }, - { 16000, 16000, 12800, 12800, 12, 12, 15, 256, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT16k, L_FILT16k, 0, 0 }, - { 16000, 16000, 32000, 32000, 12, 12, 6, 640, /*filter_LP12_180H, */ filter_LP12_180H_fx, L_FILT16k, L_FILT16k, 0, 0 }, - { 16000, 16000, 48000, 48000, 12, 12, 4, 960, /*filter_LP12_180H,*/ filter_LP12_180H_fx, L_FILT16k, L_FILT16k, 0, 0 }, - - { 32000, 32000, 12800, 12800, 6, 6, 15, 256, /*filter_LP15_180H,*/ filter_LP15_180H_13b_fx, L_FILT32k, L_FILT32k, 0, 0 }, - { 32000, 32000, 16000, 16000, 6, 6, 12, 320, /*filter_LP12_180H,*/ filter_LP12_180H_13b_fx, L_FILT32k, L_FILT32k, 0, 0 }, - { 32000, 32000, 25600, 25600, 12, 12, 15, 512, /*filter_LP15_360H,*/ filter_LP15_360H_13b_fx, L_FILT32k, L_FILT32k, 0, 0 }, - { 32000, 32000, 48000, 48000, 3, 3, 2, 960, /*filter_LP3_90H,*/ filter_LP3_90H_fx, L_FILT32k, L_FILT32k, 0, 0 }, - - { 48000, 48000, 12800, 12800, 4, 4, 15, 256, /*filter_LP15_180H,*/ filter_LP15_180H_13b_fx, L_FILT48k, L_FILT48k, 0, 0 }, - { 48000, 48000, 16000, 16000, 4, 4, 12, 320, /*filter_LP12_180H,*/ filter_LP12_180H_13b_fx, L_FILT48k, L_FILT48k, 0, 0 }, - { 48000, 48000, 25600, 25600, 8, 8, 15, 512, /*filter_LP15_360H,*/ filter_LP15_360H_13b_fx, L_FILT48k, L_FILT48k, 0, 0 }, - { 48000, 48000, 32000, 32000, 2, 2, 3, 640, /*filter_LP3_90H,*/ filter_LP3_90H_fx, L_FILT48k, L_FILT48k, 0, 0 }, + { 16000, 12800, 12, 15, 256, /*filter_LP15_180H,*/ filter_LP15_180H_fx, L_FILT16k, 0, }, + { 16000, 32000, 12, 6, 640, /*filter_LP12_180H, */ filter_LP12_180H_fx, L_FILT16k, 0, }, + { 16000, 48000, 12, 4, 960, /*filter_LP12_180H,*/ filter_LP12_180H_fx, L_FILT16k, 0, }, + + { 32000, 12800, 6, 15, 256, /*filter_LP15_180H,*/ filter_LP15_180H_13b_fx, L_FILT32k, 0, }, + { 32000, 16000, 6, 12, 320, /*filter_LP12_180H,*/ filter_LP12_180H_13b_fx, L_FILT32k, 0, }, + { 32000, 25600, 12, 15, 512, /*filter_LP15_360H,*/ filter_LP15_360H_13b_fx, L_FILT32k, 0, }, + { 32000, 48000, 3, 2, 960, /*filter_LP3_90H,*/ filter_LP3_90H_fx, L_FILT32k, 0, }, + + { 48000, 12800, 4, 15, 256, /*filter_LP15_180H,*/ filter_LP15_180H_13b_fx, L_FILT48k, 0, }, + { 48000, 16000, 4, 12, 320, /*filter_LP12_180H,*/ filter_LP12_180H_13b_fx, L_FILT48k, 0, }, + { 48000, 25600, 8, 15, 512, /*filter_LP15_360H,*/ filter_LP15_360H_13b_fx, L_FILT48k, 0, }, + { 48000, 32000, 2, 3, 640, /*filter_LP3_90H,*/ filter_LP3_90H_fx, L_FILT48k, 0, }, /* configs with NB 4kHz low-pass */ - { 16000, 16000, 12800, 12800, 12, 12, 15, 256, /*filter_LP24_90H,*/ filter_LP24_90H_fx, L_FILT16k, L_FILT16k, 0, 0 }, - { 32000, 32000, 12800, 12800, 6, 6, 15, 256, /*filter_LP24_90H,*/ filter_LP24_90H_13b_fx, L_FILT32k, L_FILT32k, 0, 0 }, - { 48000, 48000, 12800, 12800, 4, 4, 15, 256, /*filter_LP24_90H,*/ filter_LP24_90H_13b_fx, L_FILT48k, L_FILT48k, 0, 0 }, + { 16000, 12800, 12, 15, 256, /*filter_LP24_90H,*/ filter_LP24_90H_fx, L_FILT16k, 0, }, + { 32000, 12800, 6, 15, 256, /*filter_LP24_90H,*/ filter_LP24_90H_13b_fx, L_FILT32k, 0, }, + { 48000, 12800, 4, 15, 256, /*filter_LP24_90H,*/ filter_LP24_90H_13b_fx, L_FILT48k, 0, }, /* entry for LFE PLC */ - { 1600, 1600, 48000, 48000, 30, 30, 1, 960, /*filter_LP30_300K,*/ filter_LP30_300K_fx, LFE_PLC_FDEL/30,LFE_PLC_FDEL / 30, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, /* 0, */ 0, 0, 0, 0, 0 } /* trailing entry (just to calculate the length of this table) */ + { 1600, 48000, 30, 1, 960, /*filter_LP30_300K,*/ filter_LP30_300K_fx, LFE_PLC_FDEL / 30, 0, }, + { 0, 0, 0, 0, 0, /* 0, */ 0, 0, 0, } /* trailing entry (just to calculate the length of this table) */ }; //den fac value for last entry is calculated as den.fac = (num.fac*fin)/fout diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 33661fb58..aec0ddc1e 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -49,13 +49,8 @@ #define INTERP_EXP 0 typedef struct { - Word32 fin; /* input frequency */ Word32 fin_fx; /* input frequency Q0 */ - - Word32 fout; /* output frequency */ Word32 fout_fx; /* output frequency Q0 */ - - Word16 fac_num; /* numerator of resampling factor */ Word16 fac_num_fx; /* numerator of resampling factor Q0 */ Word16 fac_den_fx; /* denominator of resampling factor Q0 */ @@ -63,10 +58,7 @@ typedef struct const Word16 *filter_fx; /* resampling filter coefficients Q14 */ - Word16 filt_len; /* number of filter coeff. */ Word16 filt_len_fx; /* number of filter coeff. Q0 */ - - UWord16 flags; /* flags from config. table */ UWord16 flags_fx; /* flags from config. table Q0 */ // UNS_Word16 flags_fx; /* flags from config. table Q0 */ diff --git a/lib_com/syn_filt_fx.c b/lib_com/syn_filt_fx.c index 968cc8359..ada0d243e 100644 --- a/lib_com/syn_filt_fx.c +++ b/lib_com/syn_filt_fx.c @@ -213,14 +213,14 @@ void syn_filt_fx( FOR( i = 0; i < l; i++ ) { - s = L_mult( a0, x[i] ); + s = L_mult( a0, x[i] ); // Qx + Qa - shift + 1 FOR( j = 1; j <= m; j++ ) { - s = L_msu_sat( s, shr( a[j], shift ), yy[i - j] ); + s = L_msu_sat( s, a[j], yy[i - j] ); // Qa + Qx - shift + 1 } - s = L_shl_sat( s, q ); - yy[i] = extract_h( s ); + s = L_shl_sat( s, q ); // Qx + (Qa + q)Q15 - shift + 1 = Qx - shift + Q16 + yy[i] = extract_h( s ); // Qx - shift move16(); y[i] = extract_h( s ); move16(); diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 782006108..3c540ab07 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1123,7 +1123,11 @@ ivas_error acelp_core_enc_ivas_fx( move16(); st->hLPDmem->q_mem_syn = st->Q_syn; move16(); - + // Scaling Aq to Q12 + FOR(Word16 k = 0; k < NB_SUBFR16k; k++) + { + Scale_sig(&Aq[(M + 1) * k], M + 1, sub(norm_s(Aq[(M + 1) * k]), 2)); + } /* synthesis at 12.8kHz sampling rate */ syn_12k8_fx( st->L_frame, Aq, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, sub( Q_new, 1 ), st->Q_syn ); @@ -1274,6 +1278,11 @@ ivas_error acelp_core_enc_ivas_fx( /* Check LSF stability (distance between old LSFs and current LSFs) */ st->stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); // Q15 move16(); + } + // Scaling Aq to Q12 + FOR(Word16 k = 0; k < NB_SUBFR16k; k++) + { + Scale_sig(&Aq[(M + 1) * k], M + 1, sub(norm_s(Aq[(M + 1) * k]), 2)); } test(); IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) @@ -1312,13 +1321,7 @@ ivas_error acelp_core_enc_ivas_fx( { v_multc_fixed_16_16( res_fx, att_fx, res_fx, st->L_frame ); } - - // Scaling Aq and Aw to Q12 - FOR( Word16 k = 0; k < NB_SUBFR16k; k++ ) - { - Scale_sig( &Aq[( M + 1 ) * k], M + 1, sub( norm_s( Aq[( M + 1 ) * k] ), 2 ) ); - Scale_sig( &Aw[( M + 1 ) * k], M + 1, sub( norm_s( Aw[( M + 1 ) * k] ), 2 ) ); - } + /*-----------------------------------------------------------------* * Determine TC subframe classification *-----------------------------------------------------------------*/ @@ -1418,17 +1421,12 @@ ivas_error acelp_core_enc_ivas_fx( encod_gen_voic_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, 0, Q_new ); } - FOR( i = 0; i < NB_SUBFR16k; i++ ) - { - Scale_sig( &Aq[i * ( M + 1 )], ( M + 1 ), sub( Q12, sub( Q14, norm_s( Aq[i * ( M + 1 )] ) ) ) ); // Q12 - } - /* update mem_syn1_flt for ACELP core switching */ Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); // Q_syn /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( syn_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); // st->Q_syn - + Copy( syn_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); // hLPDmem->q_mem_syn + //st->Q_syn = Q_new - 1; Scale_sig( syn_fx, L_FRAME16k, sub( st->Q_syn, Q_new - 1 ) ); // Q_syn /* save and delay synthesis to be used by SWB BWE */ IF( st->hBWE_FD != NULL ) diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index cd23c1a6f..b0c67abf5 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -23,7 +23,7 @@ void encod_unvoiced_fx( const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC Q0*/ const Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *syn_fx, /* o : core synthesis Q_new*/ + Word16 *syn_fx, /* o : core synthesis Q_new -1 */ Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 1e66c1488..d5898cd4a 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -398,11 +398,6 @@ void stereo_tcx_core_enc( Q_exc = Q_new; st->prev_Q_new = Q_exc; - Scale_sig( st->synth, st->L_frame, st->Q_syn ); - IF( st->tcxonly == 0 ) - { - st->wspeech_enc[st->L_frame - 1] = shl( st->wspeech_enc[st->L_frame - 1], st->Q_syn ); - } IF( st->hTdCngEnc ) { FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 10d020ee3..3698eba02 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2043,7 +2043,7 @@ void encod_unvoiced_ivas_fx( const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC Q0*/ const Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *syn_fx, /* o : core synthesis Q_new*/ + Word16 *syn_fx, /* o : core synthesis Q_new - 1*/ Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 44f415dc7..3fe7d30fb 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -591,7 +591,7 @@ void swb_bwe_enc_ivas_fx( ELSE { SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, new_input_fx_exp, Q_synth ); + SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, new_input_fx_exp, new_input_fx_exp ); } -- GitLab From c7608e5062990ae9fd76d5ec4020dd28f327761c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 09:39:37 +0530 Subject: [PATCH 0442/1221] Clang formatting changes --- lib_com/rom_com.h | 8 ++++---- lib_enc/acelp_core_enc_fx.c | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index aec0ddc1e..10bce5bb2 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -49,8 +49,8 @@ #define INTERP_EXP 0 typedef struct { - Word32 fin_fx; /* input frequency Q0 */ - Word32 fout_fx; /* output frequency Q0 */ + Word32 fin_fx; /* input frequency Q0 */ + Word32 fout_fx; /* output frequency Q0 */ Word16 fac_num_fx; /* numerator of resampling factor Q0 */ Word16 fac_den_fx; /* denominator of resampling factor Q0 */ @@ -59,8 +59,8 @@ typedef struct const Word16 *filter_fx; /* resampling filter coefficients Q14 */ Word16 filt_len_fx; /* number of filter coeff. Q0 */ - UWord16 flags_fx; /* flags from config. table Q0 */ - // UNS_Word16 flags_fx; /* flags from config. table Q0 */ + UWord16 flags_fx; /* flags from config. table Q0 */ + // UNS_Word16 flags_fx; /* flags from config. table Q0 */ } Resampling_cfg; diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 3c540ab07..d2d5ac4e6 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1124,9 +1124,9 @@ ivas_error acelp_core_enc_ivas_fx( st->hLPDmem->q_mem_syn = st->Q_syn; move16(); // Scaling Aq to Q12 - FOR(Word16 k = 0; k < NB_SUBFR16k; k++) + FOR( Word16 k = 0; k < NB_SUBFR16k; k++ ) { - Scale_sig(&Aq[(M + 1) * k], M + 1, sub(norm_s(Aq[(M + 1) * k]), 2)); + Scale_sig( &Aq[( M + 1 ) * k], M + 1, sub( norm_s( Aq[( M + 1 ) * k] ), 2 ) ); } /* synthesis at 12.8kHz sampling rate */ syn_12k8_fx( st->L_frame, Aq, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, sub( Q_new, 1 ), st->Q_syn ); @@ -1279,10 +1279,10 @@ ivas_error acelp_core_enc_ivas_fx( st->stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); // Q15 move16(); } - // Scaling Aq to Q12 - FOR(Word16 k = 0; k < NB_SUBFR16k; k++) + // Scaling Aq to Q12 + FOR( Word16 k = 0; k < NB_SUBFR16k; k++ ) { - Scale_sig(&Aq[(M + 1) * k], M + 1, sub(norm_s(Aq[(M + 1) * k]), 2)); + Scale_sig( &Aq[( M + 1 ) * k], M + 1, sub( norm_s( Aq[( M + 1 ) * k] ), 2 ) ); } test(); IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) @@ -1321,7 +1321,7 @@ ivas_error acelp_core_enc_ivas_fx( { v_multc_fixed_16_16( res_fx, att_fx, res_fx, st->L_frame ); } - + /*-----------------------------------------------------------------* * Determine TC subframe classification *-----------------------------------------------------------------*/ @@ -1426,7 +1426,7 @@ ivas_error acelp_core_enc_ivas_fx( /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ Copy( syn_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); // hLPDmem->q_mem_syn - //st->Q_syn = Q_new - 1; + // st->Q_syn = Q_new - 1; Scale_sig( syn_fx, L_FRAME16k, sub( st->Q_syn, Q_new - 1 ) ); // Q_syn /* save and delay synthesis to be used by SWB BWE */ IF( st->hBWE_FD != NULL ) -- GitLab From 44f4004254dac2ba28aa7ac41236efee5f9f3e61 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 12:36:17 +0530 Subject: [PATCH 0443/1221] Fix for 3GPP issue 1393: Instrumented version of the StereoDmxEVS encoder crashes in the Pit_exc_contribution_len_fx() function --- lib_enc/eval_pit_contr_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index d5f832f8c..aef5fd637 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -182,7 +182,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit test(); if ( GE_16( st_fx->GSC_IVAS_mode, 1 ) || LT_32( st_fx->core_brate, ACELP_9k60 ) ) { - av_corr = shl( av_corr, 1 ); /*Q2 Correlation really poor at low rate, time domain still valide*/ + av_corr = shl_sat( av_corr, 1 ); /*Q2 Correlation really poor at low rate, time domain still valide*/ } min_corr = abs_s( sub( mfreq_loc_Q2fx[0], av_corr ) ); /*Q2*/ -- GitLab From cba1fbbb918cbf17254100eb23eea9d1bdbb31e7 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 11:23:47 +0100 Subject: [PATCH 0444/1221] more simplifications + formatting --- lib_com/prot_fx.h | 1 - lib_dec/core_switching_dec_fx.c | 4 +- lib_dec/ivas_core_dec_fx.c | 109 ++++++++++++-------------------- lib_dec/ivas_mct_dec_fx.c | 2 +- 4 files changed, 42 insertions(+), 74 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index da761de9d..801c2a098 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -8072,7 +8072,6 @@ ivas_error core_switching_post_dec_ivas_fx( Word16 *synth, /* i/o: output synthesis Qsynth*/ Word32 *output_fx, /* i/o: LB synth/upsampled LB synth Q4*/ Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame Qx*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo Q0*/ const Word16 output_frame, /* i : frame length Q0*/ const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 587eb8b0c..bc5703241 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1269,7 +1269,6 @@ ivas_error core_switching_post_dec_ivas_fx( Word16 *synth, /* i/o: output synthesis Qsynth*/ Word32 *output_fx, /* i/o: LB synth/upsampled LB synth Q4*/ Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame Qx*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo Q0*/ const Word16 output_frame, /* i : frame length Q0*/ const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ @@ -1523,11 +1522,12 @@ ivas_error core_switching_post_dec_ivas_fx( test(); test(); test(); - IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( ivas_format, ISM_FORMAT ) && EQ_16( st_fx->core, TCX_20_CORE ) /* <- means TCX in general, TCX10 is forbidden after ACELP */ ) ) && LE_32( st_fx->last_core_brate, SID_2k40 ) && GT_32( st_fx->core_brate, SID_2k40 ) ) + IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || ( st_fx->is_ism_format && EQ_16( st_fx->core, TCX_20_CORE ) /* <- means TCX in general, TCX10 is forbidden after ACELP */ ) ) && LE_32( st_fx->last_core_brate, SID_2k40 ) && GT_32( st_fx->core_brate, SID_2k40 ) ) { /* smooth transitions to avoid pops in car noise items */ smoothTransitionDtxToTcx_fx( synth, output_frame, delay_comp ); } + /* Reset memories of CLDFBs */ IF( st_fx->cldfbAna != NULL ) { diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 6d7d4fc97..832702084 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -48,6 +48,7 @@ * * Principal IVAS core decoder routine, where number of core channels is 1 or 2 *-------------------------------------------------------------------*/ + ivas_error ivas_core_dec_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ @@ -65,15 +66,11 @@ ivas_error ivas_core_dec_fx( STEREO_ICBWE_DEC_HANDLE hStereoICBWE; STEREO_TD_DEC_DATA_HANDLE hStereoTD; STEREO_CNG_DEC_HANDLE hStereoCng; + FD_BWE_DEC_HANDLE hBWE_FD; Word16 sharpFlag[CPE_CHANNELS]; Word16 tmp_buffer_fx[L_FRAME48k]; - set16_fx( tmp_buffer_fx, 0, L_FRAME48k ); Word16 tmp16, tmp16_2, j; - tmp16 = 0; - move16(); Word16 Q_white_exc; - Q_white_exc = 0; - move16(); Word16 tmps, incr; Word32 bwe_exc_extended_fx[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; @@ -110,15 +107,8 @@ ivas_error ivas_core_dec_fx( move16(); move16(); - FOR( i = 0; i < CPE_CHANNELS; i++ ) - { - set16_fx( pitch_buf_fx[i], 0, NB_SUBFR16k ); - set16_fx( output_16_fx[i], 0, L_FRAME48k ); - } - Word16 tdm_lsfQ_PCh_fx[M], tdm_lspQ_PCh_fx[M]; Word32 conceal_eof_gain32; - Flag Overflow; error = IVAS_ERR_OK; @@ -151,6 +141,7 @@ ivas_error ivas_core_dec_fx( p_output_mem_fx = NULL; nchan_out = 1; move16(); + test(); IF( st_ivas != NULL && EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { @@ -174,7 +165,6 @@ ivas_error ivas_core_dec_fx( hStereoTD = hCPE->hStereoTD; hStereoCng = hCPE->hStereoCng; p_output_mem_fx = hCPE->output_mem_fx[1]; - nchan_out = hCPE->nchan_out; move16(); @@ -184,19 +174,12 @@ ivas_error ivas_core_dec_fx( move16(); } - IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) ) + test(); + test(); + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) { - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) - { - use_cldfb_for_dft = 1; - move16(); - } - ELSE - { - use_cldfb_for_dft = 0; - move16(); - } + use_cldfb_for_dft = 1; + move16(); } } @@ -286,10 +269,8 @@ ivas_error ivas_core_dec_fx( IF( !st->bfi && st->prev_bfi && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) #endif { - conceal_eof_gain32 = L_shr_sat( st->hTcxDec->conceal_eof_gain32, sub( 16, st->hTcxDec->conceal_eof_gain_e ) ); // e = 31 - Q , 16 - e => 16 - (31 - Q) => Q - 15, // shr(16 -e ) = shr(Q -15) => 15 - Q ==> Q15 - FOR( i = 0; i < st->hTcxDec->L_frameTCX; i++ ) { L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_fx[i] ); // Q0 (15+1+0 - (15 + 1) @@ -312,6 +293,7 @@ ivas_error ivas_core_dec_fx( set16_fx( voice_factors_fx[n], 0, NB_SUBFR16k ); set32_fx( hb_synth_32_fx[n], 0, L_FRAME48k ); set16_fx( hb_synth_16_fx[n], 0, L_FRAME48k ); + /*------------------------------------------------------------------* * Decision matrix (selection of technologies) *-----------------------------------------------------------------*/ @@ -469,6 +451,7 @@ ivas_error ivas_core_dec_fx( /*---------------------------------------------------------------------* * Preprocessing (preparing) for ACELP/HQ core switching *---------------------------------------------------------------------*/ + Word16 Q_olapBufferSynth, Q_olapBufferSynth2; Q_olapBufferSynth = Q15; /*Initializing with max values to avoid warnings*/ @@ -501,8 +484,8 @@ ivas_error ivas_core_dec_fx( { /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; - set16_fx( output_16_fx[n], 0, L_FRAME48k ); Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; + IF( save_hb_synth_32_fx ) { save_hb_synth_16_fx = save_hb_synth_fx_arr; @@ -622,7 +605,9 @@ ivas_error ivas_core_dec_fx( ivas_format = st_ivas->ivas_format; move32(); } + stereo_tcx_core_dec_fx( st, frameMode[n], output_16_fx[n], synth_16_fx[n], pitch_buf_fx[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hStereoCng, nchan_out, ivas_format ); + st->hHQ_core->Q_old_wtda_LB = st->hHQ_core->Q_old_wtda; move16(); Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, Q11 ); // Q11 @@ -722,6 +707,7 @@ ivas_error ivas_core_dec_fx( move16(); move16(); sts = hCPE->hCoreCoder; + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; @@ -765,6 +751,7 @@ ivas_error ivas_core_dec_fx( ELSE IF( EQ_16( hCPE->nchan_out, 1 ) ) { Word16 shift1, shift2; + sts[0] = hCPE->hCoreCoder[0]; sts[1] = hCPE->hCoreCoder[1]; @@ -775,6 +762,7 @@ ivas_error ivas_core_dec_fx( sts[1]->hHQ_core->exp_old_out = sub( 15, sts[1]->hHQ_core->Q_old_wtda ); move16(); } + updateBuffersForDmxMdctStereo_fx( hCPE, output_frame, output_32_fx[0], output_32_fx[1], synth_16_fx ); IF( LE_32( last_element_brate, IVAS_SID_5k2 ) ) @@ -846,6 +834,7 @@ ivas_error ivas_core_dec_fx( FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; + hBWE_FD = st->hBWE_FD; /*---------------------------------------------------------------------* * TD-BWE for ACELP to TCX transitions @@ -932,6 +921,7 @@ ivas_error ivas_core_dec_fx( #endif Copy( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } + /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ @@ -949,19 +939,7 @@ ivas_error ivas_core_dec_fx( #endif } - IVAS_FORMAT ivas_format; - IF( st_ivas != NULL ) - { - ivas_format = st_ivas->ivas_format; - move32(); - } - ELSE - { - ivas_format = UNDEFINED_FORMAT; - move32(); - } - - IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, ivas_format, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) { return error; } @@ -990,6 +968,7 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } + /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ @@ -1035,17 +1014,17 @@ ivas_error ivas_core_dec_fx( test(); test(); - IF( NE_16( st->last_extl, WB_BWE ) && EQ_16( st->extl, WB_BWE ) && st->hBWE_FD != NULL ) + IF( NE_16( st->last_extl, WB_BWE ) && EQ_16( st->extl, WB_BWE ) && hBWE_FD != NULL ) { test(); if ( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) ) { - st->hBWE_FD->prev_mode = st->hBWE_FD->prev_mode; + hBWE_FD->prev_mode = hBWE_FD->prev_mode; move16(); } - st->hBWE_FD->prev_L_swb_norm = st->hBWE_FD->prev_L_swb_norm; + hBWE_FD->prev_L_swb_norm = hBWE_FD->prev_L_swb_norm; move16(); - st->hBWE_FD->prev_flag = st->hBWE_FD->prev_flag; + hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } @@ -1070,9 +1049,6 @@ ivas_error ivas_core_dec_fx( Q_synth_fx = Q_synth; move16(); - FD_BWE_DEC_HANDLE hBWE_FD; - hBWE_FD = st->hBWE_FD; - Copy_Scale_sig_32_16( output_32_fx[n], output_16_fx[n], L_FRAME48k, sub( Q_input, Q11 ) ); // Q_input Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 test(); @@ -1129,6 +1105,10 @@ ivas_error ivas_core_dec_fx( * SWB(FB) TBE decoding * SWB(FB) BWE decoding *---------------------------------------------------------------------*/ + + Q_white_exc = 0; + move16(); + test(); test(); test(); @@ -1149,10 +1129,8 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { /* SWB TBE decoder */ - Q_white_exc = 0; - move16(); - ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); // prev_Qx @@ -1176,7 +1154,7 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 - Copy_Scale_sig_32_16( st->hBWE_FD->L_old_wtda_swb_fx32, st->hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp + Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } /*---------------------------------------------------------------------* @@ -1246,6 +1224,7 @@ ivas_error ivas_core_dec_fx( /*-------------------------------------------------------------------* * Inter-channel BWE decoding *-------------------------------------------------------------------*/ + test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { @@ -1442,24 +1421,13 @@ ivas_error ivas_core_dec_fx( { Word16 exp; Word32 fra; - SWITCH( output_frame ) + + tmp16 = 34; /*ouput_frame == L_FRAME 48k: Q15*/ + move16(); + if ( EQ_16( output_frame, L_FRAME32k ) ) { - case L_FRAME8k: - tmp16 = 205; - move16(); - BREAK; /*Q15*/ - case L_FRAME16k: - tmp16 = 102; - move16(); - BREAK; /*Q15*/ - case L_FRAME32k: - tmp16 = 51; - move16(); - BREAK; /*Q15*/ - case L_FRAME48k: - tmp16 = 34; - move16(); - BREAK; /*Q15*/ + tmp16 = 51; /*Q15*/ + move16(); } L_tmp = L_deposit_l( 2 ); /*0.001 in Q11*/ @@ -1499,6 +1467,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ + IF( hCPE != NULL ) { FOR( Word32 ch_ind = 0; ch_ind < n_channels; ch_ind++ ) @@ -1639,11 +1608,11 @@ ivas_error ivas_core_dec_fx( st->q_prev_synth_buffer_fx = sub( exp_max, st->q_prev_synth_buffer_fx ); move16(); } + /* Save synthesis for HQ FEC */ save_synthesis_hq_fec_fx( st, output_fx_loc, output_frame, hCPE ); /* Updates */ - ivas_updt_dec_common_fx( st, NORMAL_HQ_CORE, -1, output_32_fx[n], Q11 ); Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index abf735b5a..69165de42 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -448,7 +448,7 @@ ivas_error ivas_mct_dec_fx( { dirac_stereo_flag = 0; } - IF( NE_32( ( error = core_switching_post_dec_ivas_fx( sts[n], synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_mem_fx, st_ivas->ivas_format, 0, output_frame, 0 /*core_switching_flag*/, dirac_stereo_flag, -1, hCPE->last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = core_switching_post_dec_ivas_fx( sts[n], synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_mem_fx, 0, output_frame, 0 /*core_switching_flag*/, dirac_stereo_flag, -1, hCPE->last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) { return error; } -- GitLab From 1fccd069610822438bb649b740492d4fe6dcbc4d Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 11:31:15 +0100 Subject: [PATCH 0445/1221] simplification --- lib_dec/ivas_core_dec_fx.c | 49 ++++++++------------------------------ 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 832702084..af2f6e109 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1468,48 +1468,14 @@ ivas_error ivas_core_dec_fx( * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - IF( hCPE != NULL ) - { - FOR( Word32 ch_ind = 0; ch_ind < n_channels; ch_ind++ ) - { - IF( hCPE->hCoreCoder[ch_ind] != NULL ) - { - IF( hCPE->hCoreCoder[ch_ind]->hHQ_core != NULL ) - { -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); // Q11 - -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); // Q11 -#endif - } - } - } - } - IF( hSCE != NULL ) - { - IF( hSCE->hCoreCoder[0] != NULL ) - { - IF( hSCE->hCoreCoder[0]->hHQ_core != NULL ) - { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 #endif - } - } - } - - Word16 exp_max; - Word32 output_fx_loc[L_FRAME48k]; - exp_max = 0; - move16(); IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) { test(); @@ -1565,8 +1531,13 @@ ivas_error ivas_core_dec_fx( * Common updates *--------------------------------------------------------*/ - /*Scale Memories*/ + Word16 exp_max; + Word32 output_fx_loc[L_FRAME48k]; + exp_max = 0; + move16(); + + /*Scale Memories*/ test(); test(); test(); -- GitLab From cf6c5f4f0d9ed1b2bbc2cd0e77ef178f471d47af Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 17:46:57 +0530 Subject: [PATCH 0446/1221] LTV crash fix --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7e9471c45..946dcf778 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -934,7 +934,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( { L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); } - g0 = extract_h( L_shl( L_g0, 14 ) ); + g0 = extract_h( L_shl_sat( L_g0, 14 ) ); /* Scale signal i of 1/A(gamma1) */ IF( GT_16( g0, 1024 ) ) -- GitLab From 0a4e91348249d5bc0bc69345c4c3ca2679619b49 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 13:18:30 +0100 Subject: [PATCH 0447/1221] harmonize 'hPlcInfo' --- Workspace_msvc/lib_com.vcxproj | 1 - Workspace_msvc/lib_com.vcxproj.filters | 3 - lib_com/prot_fx.h | 235 +++++++++++++------------ lib_dec/amr_wb_dec_fx.c | 8 +- lib_dec/core_dec_init_fx.c | 2 +- lib_dec/dec_LPD_fx.c | 15 +- lib_dec/dec_tcx_fx.c | 48 +++-- lib_dec/evs_dec_fx.c | 34 ++-- lib_dec/hq_core_dec_fx.c | 44 ++--- lib_dec/ivas_core_dec_fx.c | 8 +- lib_dec/ivas_tcx_core_dec_fx.c | 2 +- lib_dec/stat_dec.h | 1 - lib_dec/updt_dec_fx.c | 4 +- lib_dec/waveadjust_fec_dec_fx.c | 200 +++++++++------------ 14 files changed, 271 insertions(+), 334 deletions(-) diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 18ec723d8..7a2aa8a7f 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -315,7 +315,6 @@ - diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index dc125ad0c..d167891a6 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -570,9 +570,6 @@ common_h - - common_h - common_h diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 801c2a098..39a5f56e2 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6340,77 +6340,135 @@ void td_cng_dec_init_ivas_fx( ); // wavadjust_fec_dec_fx.c -void set_state( Word16 *state, Word16 num, Word16 N ); -void concealment_init_x( Word16 N, void *_plcInfo ); +void set_state( + Word16 *state, + Word16 num, + Word16 N ); + +void concealment_init_x( + Word16 N, + void *_plcInfo ); + void concealment_init_ivas_fx( const Word16 L_frameTCX, T_PLCInfo_HANDLE hPlcInfo ); -void concealment_update_x( Word16 bfi, Word16 curr_mode, Word16 harmonic, Word32 *invkoef, Word16 *invkoef_scale, void *_plcInfo ); -Word16 Sqrt_x_fast( Word32 value ); - -Word32 dot_w32_accuracy_x( Word16 *s1, Word16 *s2, Word16 nbits, Word16 N ); - -Word16 int_div_s_x( Word16 a, Word16 b ); - -Word16 GetW32Norm_x( Word32 *s, Word16 N ); - -Word16 harmo_x( Word32 *X, Word16 Framesize, Word16 pitch ); - -void LpFilter2_x( Word16 *x, Word16 *y, Word16 N ); - -void sig_tilt_x( Word16 *s, Word16 FrameSize, Word32 *enr1, Word32 *enr2 ); -void get_maxConv_and_pitch_x( Word16 *s_LP, Word16 s, Word16 e, Word16 N, Word32 *maxConv, Word16 *maxConv_bits, Word16 *pitch ); - -Word16 get_voicing_x( Word16 *s_LP, Word16 pitch, Word32 covMax, Word16 maxConv_bits, Word16 Framesize ); - -void pitch_modify_x( Word16 *s_LP, Word16 *voicing, Word16 *pitch, Word16 FrameSize ); - -Word16 Is_Periodic_x( Word32 *mdct_data, Word16 cov_max, Word16 zp, Word32 ener, Word32 ener_mean, Word16 pitch, Word16 Framesize ); - -Word16 get_conv_relation_x( Word16 *s_LP, Word16 shift, Word16 N ); - -void concealment_decode_fix( Word16 curr_mode, Word32 *invkoef, Word16 *invkoef_scale, void *_plcInfo ); - -Word32 Spl_Energy_x( const Word16 *vector, const Word16 vector_length, Word16 *scale_factor ); +void concealment_update_x( + Word16 bfi, + Word16 curr_mode, + Word16 harmonic, + Word32 *invkoef, + Word16 *invkoef_scale, + void *_plcInfo ); + +Word16 Sqrt_x_fast( + Word32 value ); + +Word32 dot_w32_accuracy_x( + Word16 *s1, + Word16 *s2, + Word16 nbits, + Word16 N ); + +Word16 int_div_s_x( + Word16 a, + Word16 b ); -void Log10OfEnergy_x( const Word16 *s, Word32 *enerlogval, const Word16 len ); +Word16 GetW32Norm_x( + Word32 *s, + Word16 N ); + +Word16 harmo_x( + Word32 *X, + Word16 Framesize, + Word16 pitch ); + +void LpFilter2_x( + Word16 *x, + Word16 *y, + Word16 N ); + +void sig_tilt_x( + Word16 *s, + Word16 FrameSize, + Word32 *enr1, + Word32 *enr2 ); + +void get_maxConv_and_pitch_x( + Word16 *s_LP, + Word16 s, + Word16 e, + Word16 N, + Word32 *maxConv, + Word16 *maxConv_bits, + Word16 *pitch ); + +Word16 get_voicing_x( + Word16 *s_LP, + Word16 pitch, + Word32 covMax, + Word16 maxConv_bits, + Word16 Framesize ); + +void pitch_modify_x( + Word16 *s_LP, + Word16 *voicing, + Word16 *pitch, + Word16 FrameSize ); + +Word16 Is_Periodic_x( + Word32 *mdct_data, + Word16 cov_max, + Word16 zp, + Word32 ener, + Word32 ener_mean, + Word16 pitch, + Word16 Framesize ); + +Word16 get_conv_relation_x( + Word16 *s_LP, + Word16 shift, + Word16 N ); + +void concealment_decode_fix( + Word16 curr_mode, + Word32 *invkoef, + Word16 *invkoef_scale, + void *_plcInfo ); + +Word32 Spl_Energy_x( + const Word16 *vector, + const Word16 vector_length, + Word16 *scale_factor ); + +void Log10OfEnergy_x( + const Word16 *s, + Word32 *enerlogval, + const Word16 len ); -void concealment_update2_x( const Word16 *outx_new, void *_plcInfo, const Word16 FrameSize ); +void concealment_update2_x( + const Word16 *outx_new, + void *_plcInfo, + const Word16 FrameSize ); -Word16 ffr_getSfWord16( Word16 *vector, /*!< Pointer to i vector */ - Word16 len ); +Word16 ffr_getSfWord16( + Word16 *vector, /*!< Pointer to i vector */ + Word16 len ); -void waveform_adj2_fix( Word16 *overlapbuf, - Word16 *outx_new, - Word16 *data_noise, - Word16 *outx_new_n1, - Word16 *nsapp_gain, - Word16 *nsapp_gain_n, - Word16 *recovery_gain, - Word16 step_concealgain, - Word16 pitch, - Word16 Framesize, - Word16 delay, - Word16 bfi_cnt, - Word16 bfi ); +void waveform_adj2_fix( + T_PLCInfo_HANDLE hPlcInfo, + Word16 *overlapbuf, + Word16 *outx_new, + const Word16 delay, + const Word16 bfi_cnt, + const Word16 bfi ); -void concealment_signal_tuning_fx( Word16 bfi, - Word16 curr_mode, - Word16 *outx_new_fx, - void *_plcInfo, - Word16 nbLostCmpt, - Word16 pre_bfi, - Word16 *OverlapBuf_fx, - Word16 past_core_mode, - Word16 *outdata2_fx, - Decoder_State *st ); +void concealment_signal_tuning_fx( + Decoder_State *st, + const Word16 bfi, + Word16 *outx_new_fx /*Qoutx_new_fx*/, + const Word16 past_core ); -// TonalComponentDetect.c -/* Detect tonal components in the lastMDCTSpectrum, use - * secondLastPowerSpectrum for the precise location of the peaks and - * store them in indexOfTonalPeak. Updates lowerIndex, upperIndex, - * pNumIndexes accordingly. */ void DetectTonalComponents( Word16 indexOfTonalPeak[], Word16 lowerIndex[], @@ -6434,12 +6492,6 @@ void DetectTonalComponents( #endif ); -/* When called, the tonal components are already stored in - * indexOfTonalPeak. Detect tonal components in the lastMDCTSpectrum, - * use secondLastPowerSpectrum for the precise location of the peaks and - * then keep in indexOfTonalPeak only the tonal components that are - * again detected Updates indexOfTonalPeak, lowerIndex, upperIndex, - * phaseDiff, phases, pNumIndexes accordingly. */ void RefineTonalComponents( Word16 indexOfTonalPeak[], Word16 lowerIndex[], @@ -6537,26 +6589,13 @@ void TonalMDCTConceal_SaveFreqSignal_ivas_fx( const Word16 gain_tcx_exp, const Word16 infoIGFStartLine ); -/* The call to TonalMDCTConceal_UpdateState() should be called after TonalMDCTConceal_Apply. */ -TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState( TonalMDCTConcealPtr self, - Word16 nNewSamples, - Word32 pitchLag, - Word16 badBlock, - Word8 tonalConcealmentActive ); - -/* The call to TonalMDCTConceal_SaveTimeSignal() should be at the - * place where the TD signal corresponds to the FD signal stored with TonalMDCTConceal_SaveFreqSignal. */ -void TonalMDCTConceal_SaveTimeSignal( - TonalMDCTConcealPtr hTonalMDCTConc, - Word16 *timeSignal, - Word16 nNewSamples ); +TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState( + TonalMDCTConcealPtr self, + Word16 nNewSamples, + Word32 pitchLag, + Word16 badBlock, + Word8 tonalConcealmentActive ); -/* Calculates MDST, power spectrum and performs peak detection. - * Uses the TD signal in pastTimeSignal; if pastTimeSignal is NULL, uses the - * TD signal stored using TonalMDCTConceal_SaveTimeSignal. If the - * second last frame was also lost, it is expected that pastTimeSignal - * could hold a signal somewhat different from the one stored in - * TonalMDCTConceal_SaveTimeSignal (e.g. including fade-out).*/ void TonalMDCTConceal_Detect( const TonalMDCTConcealPtr self, /*IN */ const Word32 pitchLag, /*IN */ @@ -6568,9 +6607,6 @@ void TonalMDCTConceal_Detect( #endif ); -/* Conceals the lost frame using the FD signal previously stored using - * TonalMDCTConceal_SaveFreqSignal. Stores the concealed harmonic part of - * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ void TonalMDCTConceal_Apply( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ Word32* mdctSpectrum, /*IN/OUT*/ @@ -6586,9 +6622,6 @@ void TonalMDCTConceal_Apply_ivas_fx( Word16 mdctSpectrum_exp[L_FRAME48k], /*IN */ const PsychoacousticParameters *psychParamsCurrent ); -/* Conceals the lost frame using the FD signal previously stored using - * TonalMDCTConceal_SaveFreqSignal. Stores the concealed noise part of - * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ void TonalMDCTConceal_InsertNoise_ivas_fx( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ Word32 *mdctSpectrum, @@ -6603,10 +6636,6 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( const Word16 cngLevelBackgroundTrace_e, const Word16 crossOverFreq ); - -/* Conceals the lost frame using the FD signal previously stored using - * TonalMDCTConceal_SaveFreqSignal. Stores the concealed noise part of - * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ void TonalMDCTConceal_InsertNoise( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ Word32 *mdctSpectrum, /*OUT*/ @@ -6619,24 +6648,12 @@ void TonalMDCTConceal_InsertNoise( const Word16concealment_noise[L_FRAME48k], #endif const Word16 crossOverFreq ); -/* Conceals the lost frame using the FD signal previously stored using - * TonalMDCTConceal_SaveFreqSignal. Stores the concealed harmonic part of - * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ -void TonalMDCTConceal_Apply( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - Word32* mdctSpectrum, /*IN/OUT*/ - Word16* mdctSpectrum_exp /*IN */ -#ifdef IVAS_CODE_MDCT_GSHAPE - , const PsychoacousticParameters* psychParamsCurrent) -#endif - ); -/* The call to TonalMDCTConceal_SaveTimeSignal() should be at the - * place where the TD signal corresponds to the FD signal stored with TonalMDCTConceal_SaveFreqSignal. */ void TonalMDCTConceal_SaveTimeSignal( TonalMDCTConcealPtr hTonalMDCTConc, Word16 *timeSignal, Word16 nNewSamples ); + void TonalMDCTConceal_SaveTimeSignal_ivas_fx( TonalMDCTConcealPtr hTonalMDCTConc, Word16 *timeSignal, diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 4fe8f63f4..0eb807f6e 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -218,7 +218,7 @@ ivas_error amr_wb_dec_fx( /* st_fx->old_out_fx, st_fx->L_frameTCX); */ FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { - hHQ_core->old_out_fx[i] = shl( mult_r( hHQ_core->old_out_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); + hHQ_core->old_out_fx[i] = shl( mult_r( hHQ_core->old_out_fx[i], st_fx->hPlcInfo->recovery_gain ), 1 ); move16(); } } @@ -963,7 +963,7 @@ ivas_error amr_wb_dec_fx( test(); test(); - IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->plcInfo.concealment_method, TCX_NONTONAL ) && LT_32( st_fx->plcInfo.nbLostCmpt, 4 ) ) + IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_32( st_fx->hPlcInfo->nbLostCmpt, 4 ) ) { waveadj_rec = 1; move16(); @@ -1075,9 +1075,7 @@ ivas_error amr_wb_dec_fx( move16(); } - waveform_adj2_fix( st_fx->tonalMDCTconceal.secondLastPcmOut, synth_out_fx + tmps, st_fx->plcInfo.data_noise, &st_fx->plcInfo.outx_new_n1_fx, - &st_fx->plcInfo.nsapp_gain_fx, &st_fx->plcInfo.nsapp_gain_n_fx, &st_fx->plcInfo.recovery_gain, st_fx->plcInfo.step_concealgain_fx, - st_fx->plcInfo.Pitch_fx, st_fx->plcInfo.FrameSize, tmps, add( extract_l( st_fx->plcInfo.nbLostCmpt ), 1 ), st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth_out_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); } /* HP filter */ diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index dd268fe08..2071964eb 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -1029,7 +1029,7 @@ void open_decoder_LPD_fx( test(); IF( EQ_16( st->ini_frame, 0 ) || LT_32( st->last_total_brate, HQ_48k ) || EQ_16( st->last_codec_mode, MODE1 ) || st->force_lpd_reset ) { - concealment_init_x( hTcxDec->L_frameTCX, &st->plcInfo ); + concealment_init_x( hTcxDec->L_frameTCX, &st->hPlcInfo ); } } diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index f3443349a..55d6ac36e 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -455,7 +455,7 @@ void decoder_LPD_fx( } if ( bfi ) { - st->plcInfo.nbLostCmpt = add( st->plcInfo.nbLostCmpt, 1 ); + st->hPlcInfo->nbLostCmpt = add( st->hPlcInfo->nbLostCmpt, 1 ); move16(); } } @@ -752,21 +752,18 @@ void decoder_LPD_fx( EQ_16( st->last_codec_mode, MODE2 ) ) ) { /* waveform adjustment */ + concealment_signal_tuning_fx( st, bfi, synthFB, past_core_mode ); - concealment_signal_tuning_fx( bfi, st->core, - synthFB, &st->plcInfo, st->nbLostCmpt, st->prev_bfi, - st->tonalMDCTconceal.secondLastPcmOut, - past_core_mode, st->tonalMDCTconceal.lastPcmOut, st ); test(); test(); test(); - IF( ( bfi || st->prev_bfi ) && st->plcInfo.Pitch_fx && ( ( st->plcInfo.concealment_method == TCX_NONTONAL ) ) ) + IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch_fx && ( ( st->hPlcInfo->concealment_method == TCX_NONTONAL ) ) ) { lerp( synthFB, synth, L_frame, L_frameTCX ); test(); if ( !bfi && st->prev_bfi ) { - st->plcInfo.Pitch_fx = 0; + st->hPlcInfo->Pitch_fx = 0; move16(); } } @@ -977,13 +974,13 @@ void decoder_LPD_fx( { if ( !bfi ) { - st->plcInfo.nbLostCmpt = 0; + st->hPlcInfo->nbLostCmpt = 0; move16(); } IF( st->core == 0 ) { - set_state( st->plcInfo.Transient, st->core, MAX_POST_LEN ); + set_state( st->hPlcInfo->Transient, st->core, MAX_POST_LEN ); } } diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index d1ed7ad8c..deca51e1c 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -763,42 +763,42 @@ void decoder_tcx_fx( { IF( EQ_16( st->nbLostCmpt, 1 ) ) { - st->plcInfo.concealment_method = TCX_NONTONAL; + st->hPlcInfo->concealment_method = TCX_NONTONAL; move16(); /* tonal/non-tonal decision */ test(); test(); - IF( EQ_16( st->plcInfo.Transient[0], 1 ) && EQ_16( st->plcInfo.Transient[1], 1 ) && EQ_16( st->plcInfo.Transient[2], 1 ) ) + IF( EQ_16( st->hPlcInfo->Transient[0], 1 ) && EQ_16( st->hPlcInfo->Transient[1], 1 ) && EQ_16( st->hPlcInfo->Transient[2], 1 ) ) { Word16 sum_word16 = 0; move16(); FOR( i = 9; i >= 0; i-- ) { - sum_word16 = add( sum_word16, st->plcInfo.TCX_Tonality[i] ); + sum_word16 = add( sum_word16, st->hPlcInfo->TCX_Tonality[i] ); } if ( GE_16( sum_word16, 6 ) ) { - st->plcInfo.concealment_method = TCX_TONAL; + st->hPlcInfo->concealment_method = TCX_TONAL; move16(); } } if ( st->tonal_mdct_plc_active ) { - st->plcInfo.concealment_method = TCX_TONAL; + st->hPlcInfo->concealment_method = TCX_TONAL; move16(); } } if ( GT_16( L_frameTCX, hTcxDec->L_frameTCX ) ) { - st->plcInfo.concealment_method = TCX_TONAL; + st->hPlcInfo->concealment_method = TCX_TONAL; move16(); } - temp_concealment_method = st->plcInfo.concealment_method; + temp_concealment_method = st->hPlcInfo->concealment_method; move16(); if ( EQ_16( st->core, TCX_10_CORE ) ) @@ -810,7 +810,7 @@ void decoder_tcx_fx( /* get the starting location of the subframe in the frame */ IF( EQ_16( st->core, TCX_10_CORE ) ) { - st->plcInfo.subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); + st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); move16(); } } @@ -1011,10 +1011,10 @@ void decoder_tcx_fx( IF( bfi && ( EQ_16( temp_concealment_method, TCX_NONTONAL ) ) ) { /* x_e =31-x_scale; */ - concealment_decode_fix( core, x, &x_e, &st->plcInfo ); + concealment_decode_fix( core, x, &x_e, &st->hPlcInfo ); } /* update spectrum buffer, tonality flag, etc. */ - concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, &st->plcInfo ); + concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, &st->hPlcInfo ); } /*-----------------------------------------------------------* @@ -1305,7 +1305,7 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, { test(); /* run lpc gain compensation not for waveform adjustment */ - IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->plcInfo.concealment_method, TCX_TONAL ) ) + IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) { UWord32 dmy; tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/ @@ -1475,20 +1475,19 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, move16(); /* run lpc gain compensation not for waveform adjustment */ test(); - IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->plcInfo.concealment_method, TCX_TONAL ) ) + IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) { - st_fx->plcInfo.recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, - st_fx->last_concealed_gain_syn_deemph ), - st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ + st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, + st_fx->last_concealed_gain_syn_deemph ), + st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ move16(); } ELSE { - st_fx->plcInfo.recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/ + st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/ move16(); } - st_fx->plcInfo.step_concealgain_fx = - round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( step ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 3 ) ); /*Q15*/ + st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( step ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 3 ) ); /*Q15*/ move16(); } @@ -1585,7 +1584,7 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, test(); test(); /* run lpc gain compensation not for waveform adjustment */ - IF( 0 == st_fx->enablePlcWaveadjust || ( st_fx->hPlcInfo != NULL && EQ_16( st_fx->plcInfo.concealment_method, TCX_TONAL ) ) ) + IF( 0 == st_fx->enablePlcWaveadjust || ( st_fx->hPlcInfo != NULL && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) ) { UWord32 dmy; tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/ @@ -1805,20 +1804,17 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, /* run lpc gain compensation not for waveform adjustment */ test(); - IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->plcInfo.concealment_method, TCX_TONAL ) ) + IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) { - st_fx->plcInfo.recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, - st_fx->last_concealed_gain_syn_deemph ), - st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ + st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ move16(); } ELSE { - st_fx->plcInfo.recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/ + st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/ move16(); } - st_fx->plcInfo.step_concealgain_fx = - round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/ + st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/ move16(); } diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 002fae3ba..18f8c2501 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -148,12 +148,12 @@ ivas_error evs_dec_fx( /* st_fx->old_out_fx, st_fx->L_frameTCX); */ FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { - hHQ_core->old_out_fx[i] = shl_sat( mult_r( hHQ_core->old_out_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ + hHQ_core->old_out_fx[i] = shl_sat( mult_r( hHQ_core->old_out_fx[i], st_fx->hPlcInfo->recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ move16(); } FOR( i = 0; i < st_fx->L_frame; i++ ) { - hHQ_core->old_out_LB_fx[i] = shl_sat( mult_r( hHQ_core->old_out_LB_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ + hHQ_core->old_out_LB_fx[i] = shl_sat( mult_r( hHQ_core->old_out_LB_fx[i], st_fx->hPlcInfo->recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ move16(); } /* attenuate PLC buffers, if no aldo window @@ -510,7 +510,7 @@ ivas_error evs_dec_fx( test(); test(); test(); - IF( EQ_16( st_fx->core, ACELP_CORE ) && !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->plcInfo.concealment_method, TCX_NONTONAL ) && LT_32( st_fx->plcInfo.nbLostCmpt, 4 ) ) + IF( EQ_16( st_fx->core, ACELP_CORE ) && !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_32( st_fx->hPlcInfo->nbLostCmpt, 4 ) ) { tmps = 0; move16(); @@ -519,20 +519,8 @@ ivas_error evs_dec_fx( tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); /*Q0*/ } - waveform_adj2_fix( st_fx->tonalMDCTconceal.secondLastPcmOut, - synth_fx + tmps, - st_fx->plcInfo.data_noise, - &st_fx->plcInfo.outx_new_n1_fx, - &st_fx->plcInfo.nsapp_gain_fx, - &st_fx->plcInfo.nsapp_gain_n_fx, - &st_fx->plcInfo.recovery_gain, - st_fx->plcInfo.step_concealgain_fx, - st_fx->plcInfo.Pitch_fx, - st_fx->plcInfo.FrameSize, - tmps, - add( extract_l( st_fx->plcInfo.nbLostCmpt ), 1 ), - st_fx->bfi ); - st_fx->plcInfo.Pitch_fx = 0; + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); + st_fx->hPlcInfo->Pitch_fx = 0; move16(); } @@ -629,6 +617,7 @@ ivas_error evs_dec_fx( Copy( tmp_buffer_fx, st_fx->hb_prev_synth_buffer_fx, tmps ); /*Q15 - hBWE_TD->prev_hb_synth_fx_exp*/ } + /* Delay hb_synth */ tmp16 = sub( hb_synth_fx_exp, hBWE_TD->prev_hb_synth_fx_exp ); IF( tmp16 != 0 ) @@ -900,6 +889,7 @@ ivas_error evs_dec_fx( { swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); + IF( EQ_16( st_fx->extl, FB_TBE ) ) { set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); @@ -907,6 +897,7 @@ ivas_error evs_dec_fx( move16(); fb_tbe_reset_synth_fx( hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, &hBWE_TD->prev_fbbwe_ratio_fx ); } + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); } } @@ -1019,6 +1010,7 @@ ivas_error evs_dec_fx( Copy( st_fx->hFdCngDec->hFdCngCom->A_cng, A, M + 1 ); /*Q12*/ update_decoder_LPD_cng( st_fx, st_fx->coder_type, timeDomainBuffer, A, st_fx->p_bpf_noise_buf ); + /* Generate additional comfort noise to mask potential coding artefacts */ test(); test(); @@ -1037,6 +1029,7 @@ ivas_error evs_dec_fx( move16(); } } + /* check if the CLDFB works on the right sample rate */ IF( NE_16( i_mult( st_fx->cldfbAna->no_channels, st_fx->cldfbAna->no_col ), st_fx->L_frame ) ) { @@ -1242,11 +1235,11 @@ ivas_error evs_dec_fx( ( ( EQ_16( st_fx->last_core, ACELP_CORE ) ) && ( NE_16( st_fx->bwidth, NB ) && EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) ) && ( GT_32( st_fx->output_Fs, 8000 ) ) ) { + /* Add the delayed hb_synth component to the delayed core synthesis */ add_vec_fx( output_sp, negate( timeIn_e ), hb_synth_fx, hb_synth_fx_exp, output_sp, negate( timeIn_e ), output_frame ); } } - IF( EQ_32( st_fx->output_Fs, 8000 ) ) { tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ); /*Q0*/ @@ -1260,19 +1253,23 @@ ivas_error evs_dec_fx( test(); test(); test(); + /* TCX/ACELP/HQ-CORE->TCX */ IF( ( st_fx->bfi && GT_16( st_fx->last_core, ACELP_CORE ) ) || GT_16( st_fx->core, ACELP_CORE ) ) { test(); test(); test(); test(); + /* TCX / HQ-CORE / TD-TCX-PLC -> TCX / TD-TCX-PLC */ IF( GT_16( st_fx->last_core_bfi, ACELP_CORE ) || ( st_fx->bfi && st_fx->last_core > ACELP_CORE ) || ( st_fx->prev_bfi && st_fx->last_con_tcx ) ) { Copy_Scale_sig( hTcxDec->FBTCXdelayBuf, output_sp, tmps, negate( timeIn_e ) ); /*Q0*/ Copy_Scale_sig( pcmbufFB, output_sp + tmps, sub( hTcxDec->L_frameTCX, tmps ), negate( timeIn_e ) ); /*Q0*/ } + /* ACELP -> TCX */ ELSE { + /*cross-fading between LB-TCX and FB-TCX over 2.3125ms*/ Word16 step, alpha; i = 15; @@ -1307,6 +1304,7 @@ ivas_error evs_dec_fx( } } } + /* TCX/TD TCX PLC->ACELP */ ELSE IF( ( EQ_16( st_fx->last_codec_mode, MODE2 ) ) && ( GT_16( st_fx->last_core, ACELP_CORE ) ) ) { Word16 step, alpha; diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 86cf9784a..3082c299a 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -490,30 +490,18 @@ void hq_core_dec_fx( test(); test(); test(); - IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && st_fx->plcInfo.concealment_method == TCX_NONTONAL && LT_32( st_fx->plcInfo.nbLostCmpt, 4 ) ) + IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && st_fx->hPlcInfo->concealment_method == TCX_NONTONAL && LT_32( st_fx->hPlcInfo->nbLostCmpt, 4 ) ) { - st_fx->plcInfo.recovery_gain = shl_sat( st_fx->plcInfo.recovery_gain, *Q_synth ); /* Q14 + Q_synth */ + st_fx->hPlcInfo->recovery_gain = shl_sat( st_fx->hPlcInfo->recovery_gain, *Q_synth ); /* Q14 + Q_synth */ move16(); IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) { - Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->plcInfo.FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->plcInfo.FrameSize, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->FrameSize, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); st_fx->tonalMDCTconceal.q_lastPcmOut = 0; move16(); } - waveform_adj2_fix( st_fx->tonalMDCTconceal.secondLastPcmOut, - synth, - st_fx->plcInfo.data_noise, - &st_fx->plcInfo.outx_new_n1_fx, - &st_fx->plcInfo.nsapp_gain_fx, - &st_fx->plcInfo.nsapp_gain_n_fx, - &st_fx->plcInfo.recovery_gain, - st_fx->plcInfo.step_concealgain_fx, - st_fx->plcInfo.Pitch_fx, - st_fx->plcInfo.FrameSize, - 0, - add( extract_l( st_fx->plcInfo.nbLostCmpt ), 1 ), - st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); } IF( GE_16( output_frame, L_FRAME16k ) ) @@ -1122,30 +1110,18 @@ void ivas_hq_core_dec_fx( test(); test(); test(); - IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->plcInfo.concealment_method, TCX_NONTONAL ) && LT_32( st_fx->plcInfo.nbLostCmpt, 4 ) ) + IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_32( st_fx->hPlcInfo->nbLostCmpt, 4 ) ) { - st_fx->plcInfo.recovery_gain = shl_sat( st_fx->plcInfo.recovery_gain, *Q_synth ); /* Q15 */ + st_fx->hPlcInfo->recovery_gain = shl_sat( st_fx->hPlcInfo->recovery_gain, *Q_synth ); /* Q15 */ move16(); IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) { - Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->plcInfo.FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->plcInfo.FrameSize, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->FrameSize, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); st_fx->tonalMDCTconceal.q_lastPcmOut = 0; move16(); } - waveform_adj2_fix( st_fx->tonalMDCTconceal.secondLastPcmOut, - synth, - st_fx->plcInfo.data_noise, - &st_fx->plcInfo.outx_new_n1_fx, - &st_fx->plcInfo.nsapp_gain_fx, - &st_fx->plcInfo.nsapp_gain_n_fx, - &st_fx->plcInfo.recovery_gain, - st_fx->plcInfo.step_concealgain_fx, - st_fx->plcInfo.Pitch_fx, - st_fx->plcInfo.FrameSize, - 0, - add( extract_l( st_fx->plcInfo.nbLostCmpt ), 1 ), - st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); } IF( GE_16( output_frame, L_FRAME16k ) ) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index af2f6e109..4806a6431 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1275,14 +1275,12 @@ ivas_error ivas_core_dec_fx( tmps = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); IF( st->tonalMDCTconceal.q_lastPcmOut != 0 ) { - Scale_sig( st->tonalMDCTconceal.secondLastPcmOut, shr( st->plcInfo.FrameSize, 1 ), negate( st->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st->tonalMDCTconceal.lastPcmOut, st->plcInfo.FrameSize, negate( st->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st->tonalMDCTconceal.secondLastPcmOut, shr( st->hPlcInfo->FrameSize, 1 ), negate( st->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st->tonalMDCTconceal.lastPcmOut, st->hPlcInfo->FrameSize, negate( st->tonalMDCTconceal.q_lastPcmOut ) ); st->tonalMDCTconceal.q_lastPcmOut = 0; move16(); } - waveform_adj2_fix( st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, st->plcInfo.data_noise, &st->plcInfo.outx_new_n1_fx, - &st->plcInfo.nsapp_gain_fx, &st->plcInfo.nsapp_gain_n_fx, &st->plcInfo.recovery_gain, st->plcInfo.step_concealgain_fx, - st->plcInfo.Pitch_fx, st->plcInfo.FrameSize, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); + waveform_adj2_fix( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); st->hPlcInfo->Pitch = 0; move16(); diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index 07eba9e64..8c63ef7df 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -639,7 +639,7 @@ void stereo_tcx_core_dec_fx( move16(); } /* waveform adjustment */ - concealment_signal_tuning_fx( bfi, st->core, synthFB_fx, &st->plcInfo, st->nbLostCmpt, st->prev_bfi, st->hTonalMDCTConc->secondLastPcmOut, st->last_core_bfi, st->hTonalMDCTConc->lastPcmOut, st ); + concealment_signal_tuning_fx( bfi, st->core, synthFB_fx, &st->hPlcInfo, st->nbLostCmpt, st->prev_bfi, st->hTonalMDCTConc->secondLastPcmOut, st->last_core_bfi, st->hTonalMDCTConc->lastPcmOut, st ); test(); test(); diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index ca0f73316..2dea95aa6 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1908,7 +1908,6 @@ typedef struct Decoder_State Word16 enablePlcWaveadjust; Word16 tonality_flag; T_PLCInfo_HANDLE hPlcInfo; - T_PLCInfo plcInfo; Word16 VAD; Word16 flag_cna; diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 4704d15c7..a24cd7f59 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -740,7 +740,7 @@ void updt_dec_common_fx( IF( st_fx->hTcxDec != NULL && st_fx->enablePlcWaveadjust && !concealWholeFrameTmp && NE_16( st_fx->core, AMR_WB_CORE ) ) { /* update the parameters used in waveform adjustment */ - concealment_update2_x( (const Word16 *) synth, &st_fx->plcInfo, hTcxDec->L_frameTCX ); + concealment_update2_x( (const Word16 *) synth, &st_fx->hPlcInfo, hTcxDec->L_frameTCX ); } st_fx->last_total_brate_ber = st_fx->total_brate; @@ -1163,7 +1163,7 @@ void ivas_updt_dec_common_fx( IF( st_fx->hTcxDec != NULL && st_fx->enablePlcWaveadjust && !concealWholeFrameTmp && NE_16( st_fx->core, AMR_WB_CORE ) ) { /* update the parameters used in waveform adjustment */ - concealment_update2_x( (const Word16 *) synth, &st_fx->plcInfo, hTcxDec->L_frameTCX ); + concealment_update2_x( (const Word16 *) synth, &st_fx->hPlcInfo, hTcxDec->L_frameTCX ); } st_fx->last_total_brate_ber = st_fx->total_brate; diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c index 80241a24c..df7425c52 100644 --- a/lib_dec/waveadjust_fec_dec_fx.c +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -1261,20 +1261,16 @@ static void add_noise( Word16 *const sbuf, /*Qsbuf*/ return; } -static Word16 waveform_adj_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ - Word16 *outdata2, /*Qoutdata2*/ - Word16 *outx_new, /*Qoutx_new*/ - Word16 *data_noise, /*Qoutx_new*/ - Word16 *outx_new_n1, /*Q0*/ - Word16 *nsapp_gain, /*Q15*/ - Word16 *nsapp_gain_n, /*Q15*/ - Word16 Framesize, - Word8 T_bfi, - Word16 voicing, /*Q15*/ - Word16 curr_mode, - Word16 pitch /*Q0*/ ) +static Word16 waveform_adj_fix( + T_PLCInfo_HANDLE hPlcInfo, + Word16 *overlapbuf, /*Qoverlapbuf*/ + Word16 *outdata2, /*Qoutdata2*/ + Word16 *outx_new, /*Qoutx_new*/ + const Word16 Framesize, + const Word16 voicing, /*Q15*/ + const Word16 core ) { - Word16 i, zp1, zp2, Framesizediv2, s16MaxCoefNorm; + Word16 i, zp1, zp2, Framesizediv2, s16MaxCoefNorm, pitch; Word16 sbuf[L_FRAME_MAX]; Word16 tmp; @@ -1282,6 +1278,8 @@ static Word16 waveform_adj_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ zp1 = zero_pass_w32_x( outdata2, Framesizediv2 ); zp2 = zero_pass_w32_x( outdata2 + Framesizediv2, Framesizediv2 ); + pitch = hPlcInfo->Pitch; + /* judge if the pitch is usable */ tmp = 1; move16(); @@ -1300,7 +1298,7 @@ static Word16 waveform_adj_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ test(); test(); test(); - IF( T_bfi && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( curr_mode, 1 ) ) ) + IF( hPlcInfo->T_bfi && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) { Word16 i1 = 0, i2 = 0; Word16 pos1, pos2, pos3; @@ -1383,15 +1381,18 @@ static Word16 waveform_adj_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ last good frame) is still needed and overlapbuf overlaps outdata2 */ Copy( &sbuf[Framesize / 4], pitch125_data, shr( imult1616( 3, Framesize ), 2 ) ); - *nsapp_gain = 0; + hPlcInfo->nsapp_gain_fx = 0; move16(); - *nsapp_gain_n = sub( 32767, shr( voicing, 1 ) ); /* q15 */ + hPlcInfo->nsapp_gain_n_fx = sub( 32767, shr( voicing, 1 ) ); /* q15 */ tmp = Framesize; move16(); + /* use last good signal for noise generation */ - add_noise( sbuf, outx_new_n1, outdata2, tmp, nsapp_gain, nsapp_gain_n, 1 ); + add_noise( sbuf, &( hPlcInfo->outx_new_n1_fx ), outdata2, tmp, &( hPlcInfo->nsapp_gain_fx ), &( hPlcInfo->nsapp_gain_n_fx ), 1 ); + /* save current (noisy) output from IMDCT */ - MVR2R_WORD16( outx_new, data_noise, tmp ); + MVR2R_WORD16( outx_new, hPlcInfo->data_noise, tmp ); + /* overlapbuf can now be filled with sbuf, needed for subsequently lost frames */ Copy( pitch125_data, &overlapbuf[Framesize / 4], shr( imult1616( 3, Framesize ), 2 ) ); } @@ -1400,31 +1401,31 @@ static Word16 waveform_adj_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ outx_new[i] = sbuf[i]; move16(); } + return pitch; } -void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ - Word16 *outx_new, /*Qoutx_new*/ - Word16 *data_noise, /*Qoutx_new*/ - Word16 *outx_new_n1, /*Q0*/ - Word16 *nsapp_gain, /*Q15*/ - Word16 *nsapp_gain_n, /*Q15*/ - Word16 *recovery_gain, /*Q14*/ - Word16 step_concealgain, /*Q15*/ - Word16 pitch, /*Q0*/ - Word16 Framesize, - Word16 delay, - Word16 bfi_cnt, - Word16 bfi ) + +void waveform_adj2_fix( + T_PLCInfo_HANDLE hPlcInfo, + Word16 *overlapbuf, /*Qoverlapbuf*/ + Word16 *outx_new, /*Qoutx_new*/ + const Word16 delay, + const Word16 bfi_cnt, + const Word16 bfi ) { - Word16 i, n, tablescale, ratio, - dat, Framesizesubn, Framesizesubp, tmp16, s, ptable, temp_OUT, s16MaxCoefNorm, s16MaxCoefNorm2; + Word16 i, n, tablescale, ratio, dat, Framesizesubn, Framesizesubp, tmp16, s, ptable, temp_OUT, s16MaxCoefNorm, s16MaxCoefNorm2; Word16 sbuf[L_FRAME_MAX]; + Word16 pitch, L_frameTCX; + pitch = hPlcInfo->Pitch_fx; + move16(); + L_frameTCX = hPlcInfo->FrameSize; + move16(); n = 0; move16(); - Framesizesubn = sub( Framesize, n ); - Framesizesubp = sub( Framesize, pitch ); + Framesizesubn = sub( L_frameTCX, n ); + Framesizesubp = sub( L_frameTCX, pitch ); IF( pitch > 0 ) { WHILE( Framesizesubn > 0 ) @@ -1437,21 +1438,21 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ move16(); } n = add( n, pitch ); - Framesizesubn = sub( Framesize, n ); + Framesizesubn = sub( L_frameTCX, n ); } - FOR( i = 0; i < Framesize; i++ ) + FOR( i = 0; i < L_frameTCX; i++ ) { overlapbuf[i] = sbuf[i]; move16(); } { - Word16 size = Framesize; - Word16 *noise_ptr = data_noise; + Word16 size = L_frameTCX; + Word16 *noise_ptr = hPlcInfo->data_noise; move16(); /* use last (noisy) output from IMDCT for noise generation */ - add_noise( sbuf, outx_new_n1, noise_ptr, size, nsapp_gain, nsapp_gain_n, 0 ); + add_noise( sbuf, &( hPlcInfo->outx_new_n1_fx ), noise_ptr, size, &( hPlcInfo->nsapp_gain_fx ), &( hPlcInfo->nsapp_gain_n_fx ), 0 ); /* save current (noisy) output from IMDCT */ IF( bfi ) @@ -1462,7 +1463,7 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ test(); IF( EQ_16( bfi_cnt, 4 ) || bfi == 0 ) { - SWITCH( Framesize ) + SWITCH( L_frameTCX ) { case 160: { @@ -1510,40 +1511,40 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ Word16 gain_zero_start = 10000; move16(); - IF( step_concealgain > 0 ) + IF( hPlcInfo->step_concealgain_fx > 0 ) { - gain_zero_start = BASOP_Util_Divide1616_Scale( *recovery_gain, step_concealgain, &s ); + gain_zero_start = BASOP_Util_Divide1616_Scale( hPlcInfo->recovery_gain, hPlcInfo->step_concealgain_fx, &s ); gain_zero_start = shl( gain_zero_start, sub( s, 14 ) ); /* q0 */ gain_zero_start = add( gain_zero_start, 1 ); } if ( delay > 0 ) { - Framesize = sub( Framesize, delay ); + L_frameTCX = sub( L_frameTCX, delay ); } - s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf, Framesize ), 1 ); - s16MaxCoefNorm2 = ffr_getSfWord16( outx_new, Framesize ); - tmp16 = vadmin( gain_zero_start, Framesize ); + s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf, L_frameTCX ), 1 ); + s16MaxCoefNorm2 = ffr_getSfWord16( outx_new, L_frameTCX ); + tmp16 = vadmin( gain_zero_start, L_frameTCX ); FOR( i = 0; i < tmp16; i++ ) { ratio = extract_l( L_shr( L_mult( i, ptable ), tablescale ) ); dat = shl( sbuf[i], s16MaxCoefNorm ); - temp_OUT = mult( *recovery_gain, sub( 32767, ratio ) ); + temp_OUT = mult( hPlcInfo->recovery_gain, sub( 32767, ratio ) ); outx_new[i] = round_fx_sat( L_add_sat( L_shr_sat( L_mult( temp_OUT, dat ), sub( s16MaxCoefNorm, 1 ) ), L_shr_sat( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ) ); move16(); - *recovery_gain = sub_sat( *recovery_gain, shr_r( step_concealgain, 1 ) ); /* q14 */ + hPlcInfo->recovery_gain = sub_sat( hPlcInfo->recovery_gain, shr_r( hPlcInfo->step_concealgain_fx, 1 ) ); /* q14 */ } - FOR( i = gain_zero_start; i < Framesize; i++ ) + FOR( i = gain_zero_start; i < L_frameTCX; i++ ) { ratio = extract_l( L_shr( L_mult( i, ptable ), tablescale ) ); outx_new[i] = round_fx_sat( L_shr_sat( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ); move16(); } - if ( *recovery_gain < 0 ) + if ( hPlcInfo->recovery_gain < 0 ) { - *recovery_gain = 0; + hPlcInfo->recovery_gain = 0; move16(); } } @@ -1551,9 +1552,9 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ { /* overlap-and-add */ Word16 tmp; - s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf, Framesize ), 1 ); - s16MaxCoefNorm2 = ffr_getSfWord16( outx_new, Framesize ); - FOR( i = 0; i < Framesize; i++ ) + s16MaxCoefNorm = sub( ffr_getSfWord16( sbuf, L_frameTCX ), 1 ); + s16MaxCoefNorm2 = ffr_getSfWord16( outx_new, L_frameTCX ); + FOR( i = 0; i < L_frameTCX; i++ ) { dat = shl( sbuf[i], s16MaxCoefNorm ); tmp = extract_l( L_shr( L_mult( i, ptable ), tablescale ) ); @@ -1564,7 +1565,7 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ } ELSE { - FOR( i = 0; i < Framesize; i++ ) + FOR( i = 0; i < L_frameTCX; i++ ) { outx_new[i] = sbuf[i]; move16(); @@ -1574,71 +1575,44 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ return; } -void concealment_signal_tuning_fx( Word16 bfi, Word16 curr_mode, Word16 *outx_new_fx /*Qoutx_new_fx*/, void *_plcInfo, Word16 nbLostCmpt, Word16 pre_bfi, Word16 *OverlapBuf_fx /*QOverlapBuf_fx*/, Word16 past_core_mode, Word16 *outdata2_fx /*Qoutdata2_fx*/, Decoder_State *st ) +void concealment_signal_tuning_fx( + Decoder_State *st, + const Word16 bfi, + Word16 *outx_new_fx /*Qoutx_new_fx*/, + const Word16 past_core ) { - T_PLCInfo *plcInfo = (T_PLCInfo *) _plcInfo; - Word16 FrameSize = plcInfo->FrameSize; - Word16 Pitch = plcInfo->Pitch_fx; + T_PLCInfo_HANDLE hPlcInfo = st->hPlcInfo; + Word16 FrameSize = hPlcInfo->FrameSize; Word16 voicing_fx = 0; + Word16 *OverlapBuf_fx = st->hTonalMDCTConc->secondLastPcmOut; + Word16 *outdata2_fx = st->hTonalMDCTConc->lastPcmOut; move16(); move16(); move16(); move16(); + IF( bfi ) { - test(); - IF( st->enablePlcWaveadjust && plcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */ + IF( st->enablePlcWaveadjust && hPlcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */ { - - IF( EQ_16( nbLostCmpt, 1 ) ) + IF( EQ_16( st->nbLostCmpt, 1 ) ) { - plcInfo->Pitch_fx = pitch_search_fx( outdata2_fx, - outx_new_fx, - FrameSize, - &voicing_fx, - plcInfo->zp_fx, - ( plcInfo->ener_fx ), - ( plcInfo->ener_mean_fx ), - plcInfo->data_reci2_fx, - curr_mode ); + hPlcInfo->Pitch_fx = pitch_search_fx( outdata2_fx, outx_new_fx, FrameSize, &voicing_fx, hPlcInfo->zp_fx, ( hPlcInfo->ener_fx ), ( hPlcInfo->ener_mean_fx ), hPlcInfo->data_reci2_fx, st->core ); move16(); - IF( plcInfo->Pitch_fx ) /* waveform adjustment for the first lost frame */ + IF( hPlcInfo->Pitch_fx ) /* waveform adjustment for the first lost frame */ { - plcInfo->Pitch_fx = waveform_adj_fix( OverlapBuf_fx, - outdata2_fx, - outx_new_fx, - plcInfo->data_noise, - &plcInfo->outx_new_n1_fx, - &plcInfo->nsapp_gain_fx, - &plcInfo->nsapp_gain_n_fx, - FrameSize, - plcInfo->T_bfi_fx, - voicing_fx, - curr_mode, - plcInfo->Pitch_fx ); + hPlcInfo->Pitch_fx = waveform_adj_fix( hPlcInfo, OverlapBuf_fx, outdata2_fx, outx_new_fx, FrameSize, voicing_fx, st->core ); move16(); } } - ELSE IF( LT_16( nbLostCmpt, 5 ) ) /* waveform adjustment for the 2nd~4th lost frame */ + ELSE IF( LT_16( st->nbLostCmpt, 5 ) ) /* waveform adjustment for the 2nd~4th lost frame */ { - waveform_adj2_fix( OverlapBuf_fx, - outx_new_fx, - plcInfo->data_noise, - &plcInfo->outx_new_n1_fx, - &plcInfo->nsapp_gain_fx, - &plcInfo->nsapp_gain_n_fx, - &plcInfo->recovery_gain, - plcInfo->step_concealgain_fx, - Pitch, - FrameSize, - 0, - nbLostCmpt, - bfi ); + waveform_adj2_fix( hPlcInfo, OverlapBuf_fx, outx_new_fx, 0, st->nbLostCmpt, bfi ); } } - plcInfo->T_bfi_fx = 1; + hPlcInfo->T_bfi_fx = 1; move16(); } ELSE @@ -1646,34 +1620,22 @@ void concealment_signal_tuning_fx( Word16 bfi, Word16 curr_mode, Word16 *outx_ne test(); test(); test(); - IF( pre_bfi && - past_core_mode != 0 && + IF( st->prev_bfi && + past_core != ACELP_CORE && GE_32( st->last_total_brate, 48000 ) && EQ_16( st->last_codec_mode, MODE2 ) ) { - IF( plcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */ + IF( hPlcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */ { - IF( LT_32( plcInfo->nbLostCmpt, 4 ) ) /* smoothing of the concealed signal with the good signal */ + IF( LT_32( hPlcInfo->nbLostCmpt, 4 ) ) /* smoothing of the concealed signal with the good signal */ { - waveform_adj2_fix( OverlapBuf_fx, - outx_new_fx, - plcInfo->data_noise, - &plcInfo->outx_new_n1_fx, - &plcInfo->nsapp_gain_fx, - &plcInfo->nsapp_gain_n_fx, - &plcInfo->recovery_gain, - plcInfo->step_concealgain_fx, - Pitch, - FrameSize, - 0, - add( extract_l( plcInfo->nbLostCmpt ), 1 ), - bfi ); + waveform_adj2_fix( hPlcInfo, OverlapBuf_fx, outx_new_fx, 0, add( extract_l( hPlcInfo->nbLostCmpt ), 1 ), bfi ); } } } ELSE { - plcInfo->T_bfi_fx = 0; + hPlcInfo->T_bfi_fx = 0; move16(); } } -- GitLab From c56229ccb6432185115d2b5959d22a85923e9adf Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 14:33:10 +0100 Subject: [PATCH 0448/1221] more harmonize 'hPlcInfo' --- lib_com/options.h | 1 + lib_com/prot_fx.h | 18 ++-- lib_dec/amr_wb_dec_fx.c | 3 +- lib_dec/core_dec_init_fx.c | 2 +- lib_dec/dec_tcx_fx.c | 12 ++- lib_dec/evs_dec_fx.c | 3 +- lib_dec/hq_core_dec_fx.c | 8 +- lib_dec/ivas_core_dec_fx.c | 8 +- lib_dec/ivas_tcx_core_dec_fx.c | 10 +- lib_dec/stat_dec.h | 9 +- lib_dec/updt_dec_fx.c | 4 +- lib_dec/waveadjust_fec_dec_fx.c | 168 +++++++++++++++++++------------- 12 files changed, 148 insertions(+), 98 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index d03261715..abdbbc918 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,4 +172,5 @@ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ +//#define FIX_WAVEADJUST /* fix waveform adjustment decoder PLC */ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 919ed1105..4eca45c35 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6346,20 +6346,20 @@ void set_state( Word16 N ); void concealment_init_x( - Word16 N, - void *_plcInfo ); + const Word16 L_frameTCX, + T_PLCInfo_HANDLE hPlcInfo ); void concealment_init_ivas_fx( const Word16 L_frameTCX, T_PLCInfo_HANDLE hPlcInfo ); void concealment_update_x( - Word16 bfi, - Word16 curr_mode, - Word16 harmonic, - Word32 *invkoef, + const Word16 bfi, + const Word16 core, + const Word16 tonality, + Word32 *invkoef /*Qinvkoef_scale*/, Word16 *invkoef_scale, - void *_plcInfo ); + T_PLCInfo_HANDLE hPlcInfo ); Word16 Sqrt_x_fast( Word32 value ); @@ -6434,7 +6434,7 @@ void concealment_decode_fix( Word16 curr_mode, Word32 *invkoef, Word16 *invkoef_scale, - void *_plcInfo ); + T_PLCInfo_HANDLE hPlcInfo ); Word32 Spl_Energy_x( const Word16 *vector, @@ -6448,7 +6448,7 @@ void Log10OfEnergy_x( void concealment_update2_x( const Word16 *outx_new, - void *_plcInfo, + T_PLCInfo_HANDLE hPlcInfo, const Word16 FrameSize ); Word16 ffr_getSfWord16( diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 0a71cae59..2aa9f82b3 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -214,8 +214,7 @@ ivas_error amr_wb_dec_fx( test(); IF( !st_fx->bfi && st_fx->prev_bfi && ( EQ_16( st_fx->last_codec_mode, MODE2 ) ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) ) { - /* v_multc(st_fx->old_out_fx, st_fx->plcInfo.recovery_gain, */ - /* st_fx->old_out_fx, st_fx->L_frameTCX); */ + /* v_multc(st_fx->old_out_fx, st_fx->hPlcInfo.recovery_gain, st_fx->old_out_fx, st_fx->L_frameTCX); */ FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { hHQ_core->old_out_fx[i] = shl( mult_r( hHQ_core->old_out_fx[i], st_fx->hPlcInfo->recovery_gain ), 1 ); diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 2071964eb..0968d10c5 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -1029,7 +1029,7 @@ void open_decoder_LPD_fx( test(); IF( EQ_16( st->ini_frame, 0 ) || LT_32( st->last_total_brate, HQ_48k ) || EQ_16( st->last_codec_mode, MODE1 ) || st->force_lpd_reset ) { - concealment_init_x( hTcxDec->L_frameTCX, &st->hPlcInfo ); + concealment_init_x( hTcxDec->L_frameTCX, st->hPlcInfo ); } } diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 9742bcab5..8ecc60d6d 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -1011,10 +1011,10 @@ void decoder_tcx_fx( IF( bfi && ( EQ_16( temp_concealment_method, TCX_NONTONAL ) ) ) { /* x_e =31-x_scale; */ - concealment_decode_fix( core, x, &x_e, &st->hPlcInfo ); + concealment_decode_fix( core, x, &x_e, st->hPlcInfo ); } /* update spectrum buffer, tonality flag, etc. */ - concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, &st->hPlcInfo ); + concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, st->hPlcInfo ); } /*-----------------------------------------------------------* @@ -4406,7 +4406,11 @@ void decoder_tcx_noisefilling_fx( /* get the starting location of the subframe in the frame */ IF( EQ_16( st->core, TCX_10_CORE ) ) { +#ifdef FIX_WAVEADJUST + st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); +#else st->hPlcInfo->subframe = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); +#endif move16(); } } @@ -4797,11 +4801,11 @@ void decoder_tcx_noiseshaping_igf_fx( /* spectrum concealment */ IF( bfi && EQ_16( *temp_concealment_method, TCX_NONTONAL ) ) { - concealment_decode_fix( st->core, x_fx, x_e, &st->hPlcInfo ); + concealment_decode_fix( st->core, x_fx, x_e, st->hPlcInfo ); } /* update spectrum buffer, tonality flag, etc. */ - concealment_update_x( bfi, st->core, st->tonality_flag, x_fx, x_e, &st->hPlcInfo ); + concealment_update_x( bfi, st->core, st->tonality_flag, x_fx, x_e, st->hPlcInfo ); *x_len = s_max( *x_len, st->hPlcInfo->L_frameTCX ); move16(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 5d493afca..2a9115237 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -143,8 +143,7 @@ ivas_error evs_dec_fx( test(); IF( !st_fx->bfi && st_fx->prev_bfi && ( EQ_16( st_fx->last_codec_mode, MODE2 ) ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) ) { - /* v_multc(st_fx->old_out_fx, st_fx->plcInfo.recovery_gain, */ - /* st_fx->old_out_fx, st_fx->L_frameTCX); */ + /* v_multc(st_fx->old_out_fx, st_fx->hPlcInfo.recovery_gain, st_fx->old_out_fx, st_fx->L_frameTCX); */ FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { hHQ_core->old_out_fx[i] = shl_sat( mult_r( hHQ_core->old_out_fx[i], st_fx->hPlcInfo->recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 3082c299a..e45c30601 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -496,8 +496,8 @@ void hq_core_dec_fx( move16(); IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) { - Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->FrameSize, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); st_fx->tonalMDCTconceal.q_lastPcmOut = 0; move16(); } @@ -1116,8 +1116,8 @@ void ivas_hq_core_dec_fx( move16(); IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) { - Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->FrameSize, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); st_fx->tonalMDCTconceal.q_lastPcmOut = 0; move16(); } diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index e10f4134f..e29d51717 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1275,14 +1275,18 @@ ivas_error ivas_core_dec_fx( tmps = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); IF( st->tonalMDCTconceal.q_lastPcmOut != 0 ) { - Scale_sig( st->tonalMDCTconceal.secondLastPcmOut, shr( st->hPlcInfo->FrameSize, 1 ), negate( st->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st->tonalMDCTconceal.lastPcmOut, st->hPlcInfo->FrameSize, negate( st->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st->tonalMDCTconceal.secondLastPcmOut, shr( st->hPlcInfo->L_frameTCX, 1 ), negate( st->tonalMDCTconceal.q_lastPcmOut ) ); + Scale_sig( st->tonalMDCTconceal.lastPcmOut, st->hPlcInfo->L_frameTCX, negate( st->tonalMDCTconceal.q_lastPcmOut ) ); st->tonalMDCTconceal.q_lastPcmOut = 0; move16(); } waveform_adj2_fix( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); +#ifdef FIX_WAVEADJUST + st->hPlcInfo->Pitch_fx = 0; +#else st->hPlcInfo->Pitch = 0; +#endif move16(); } } diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index 8c63ef7df..f840b00be 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -639,18 +639,26 @@ void stereo_tcx_core_dec_fx( move16(); } /* waveform adjustment */ - concealment_signal_tuning_fx( bfi, st->core, synthFB_fx, &st->hPlcInfo, st->nbLostCmpt, st->prev_bfi, st->hTonalMDCTConc->secondLastPcmOut, st->last_core_bfi, st->hTonalMDCTConc->lastPcmOut, st ); + concealment_signal_tuning_fx( st, bfi, synthFB_fx, st->last_core_bfi ); test(); test(); test(); +#ifdef FIX_WAVEADJUST + IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch_fx && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) +#else IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) +#endif { lerp( synthFB_fx, synth_fx, st->L_frame, hTcxDec->L_frameTCX ); if ( !bfi && st->prev_bfi ) { +#ifdef FIX_WAVEADJUST + st->hPlcInfo->Pitch_fx = 0; +#else st->hPlcInfo->Pitch = 0; +#endif move16(); } } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 2dea95aa6..2727bac44 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -174,12 +174,14 @@ typedef struct typedef struct { Word16 L_frameTCX; - Word16 FrameSize; +#ifndef FIX_WAVEADJUST Word16 Pitch; +#endif Word16 Pitch_fx; - +#ifndef FIX_WAVEADJUST Word16 T_bfi; +#endif Word8 T_bfi_fx; Word16 Transient[MAX_POST_LEN]; @@ -194,14 +196,15 @@ typedef struct Word32 ener_mean_fx; Word32 ener_fx; - Word16 zp; Word16 zp_fx; Word16 recovery_gain; /*outside waveformadjustment: Q14 - insinde waveformadjustment: Q15*/ Word16 step_concealgain_fx; Word16 concealment_method; +#ifndef FIX_WAVEADJUST Word16 subframe; +#endif Word16 subframe_fx; Word16 nbLostCmpt; diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index a24cd7f59..d401388d3 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -740,7 +740,7 @@ void updt_dec_common_fx( IF( st_fx->hTcxDec != NULL && st_fx->enablePlcWaveadjust && !concealWholeFrameTmp && NE_16( st_fx->core, AMR_WB_CORE ) ) { /* update the parameters used in waveform adjustment */ - concealment_update2_x( (const Word16 *) synth, &st_fx->hPlcInfo, hTcxDec->L_frameTCX ); + concealment_update2_x( (const Word16 *) synth, st_fx->hPlcInfo, hTcxDec->L_frameTCX ); } st_fx->last_total_brate_ber = st_fx->total_brate; @@ -1163,7 +1163,7 @@ void ivas_updt_dec_common_fx( IF( st_fx->hTcxDec != NULL && st_fx->enablePlcWaveadjust && !concealWholeFrameTmp && NE_16( st_fx->core, AMR_WB_CORE ) ) { /* update the parameters used in waveform adjustment */ - concealment_update2_x( (const Word16 *) synth, &st_fx->hPlcInfo, hTcxDec->L_frameTCX ); + concealment_update2_x( (const Word16 *) synth, st_fx->hPlcInfo, hTcxDec->L_frameTCX ); } st_fx->last_total_brate_ber = st_fx->total_brate; diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c index df7425c52..837a45ba6 100644 --- a/lib_dec/waveadjust_fec_dec_fx.c +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -35,28 +35,36 @@ void set_state( Word16 *state, Word16 num, Word16 N ) /*i/o: Qx */ } state[tmp] = num; move16(); + + return; } -void concealment_update_x( Word16 bfi, Word16 curr_mode, Word16 tonality, Word32 *invkoef /*Qinvkoef_scale*/, Word16 *invkoef_scale, void *_plcInfo ) +void concealment_update_x( + const Word16 bfi, + const Word16 core, + const Word16 tonality, + Word32 *invkoef /*Qinvkoef_scale*/, + Word16 *invkoef_scale, + T_PLCInfo_HANDLE hPlcInfo ) { - T_PLCInfo *plcInfo = (T_PLCInfo *) _plcInfo; - Word32 *data_reci2 = plcInfo->data_reci2_fx; - Word16 *tcx_tonality = plcInfo->TCX_Tonality; - Word16 FrameSize = plcInfo->FrameSize; - Word16 subframe = plcInfo->subframe_fx; + Word32 *data_reci2 = hPlcInfo->data_reci2_fx; + Word16 *tcx_tonality = hPlcInfo->TCX_Tonality; + Word16 L_frameTCX = hPlcInfo->L_frameTCX; + Word16 subframe = hPlcInfo->subframe_fx; Word16 i; move16(); move16(); - IF( EQ_16( curr_mode, 1 ) ) + + IF( EQ_16( core, TCX_20_CORE ) ) { - set_state( plcInfo->Transient, curr_mode, MAX_POST_LEN ); + set_state( hPlcInfo->Transient, core, MAX_POST_LEN ); - FOR( i = 0; i < FrameSize; i++ ) + FOR( i = 0; i < L_frameTCX; i++ ) { data_reci2[i] = invkoef[i]; move32(); } - plcInfo->data_reci2_scale = *invkoef_scale; + hPlcInfo->data_reci2_scale = *invkoef_scale; move16(); IF( !bfi ) { @@ -68,7 +76,7 @@ void concealment_update_x( Word16 bfi, Word16 curr_mode, Word16 tonality, Word32 IF( subframe == 0 ) { - set_state( plcInfo->Transient, curr_mode, MAX_POST_LEN ); + set_state( hPlcInfo->Transient, core, MAX_POST_LEN ); IF( !bfi ) { @@ -83,7 +91,7 @@ void concealment_update_x( Word16 bfi, Word16 curr_mode, Word16 tonality, Word32 { Word32 *ptr = data_reci2 + subframe; - Word16 FrameSize2 = shr( FrameSize, 1 ); + Word16 FrameSize2 = shr( L_frameTCX, 1 ); FOR( i = 0; i < FrameSize2; i++ ) { @@ -91,13 +99,15 @@ void concealment_update_x( Word16 bfi, Word16 curr_mode, Word16 tonality, Word32 move32(); } - plcInfo->data_reci2_scale = *invkoef_scale; + hPlcInfo->data_reci2_scale = *invkoef_scale; move16(); } } + return; } + static Word16 zero_pass_w32_x( const Word16 *s, const Word16 N ) /* i: Qx*/ /* o: 2*Qx-31*/ { Word16 i; @@ -601,15 +611,17 @@ Word16 get_conv_relation_x( Word16 *s_LP /*Qx*/, Word16 shIFt, Word16 N ) /*o :Q return tmp; } -static Word16 pitch_search_fx( Word16 *s /*Qs*/, /* lastPcmOut */ - Word16 *outx_new /*Qoutx_new*/, - Word16 Framesize, - Word16 *voicing /*Q15*/, - Word16 zp, /*Q0*/ - Word32 ener /*Q8*/, - Word32 ener_mean /*Q8*/, - Word32 *mdct_data /*Qmdct*/, - Word16 curr_mode ) + +static Word16 pitch_search_fx( + Word16 *s /*Qs*/, /* lastPcmOut */ + Word16 *outx_new /*Qoutx_new*/, + Word16 Framesize, + Word16 *voicing /*Q15*/, + Word16 zp, /*Q0*/ + Word32 ener /*Q8*/, + Word32 ener_mean /*Q8*/, + Word32 *mdct_data /*Qmdct*/, + Word16 curr_mode ) { Word16 pitch = 0; Word32 cov_max = L_deposit_l( 0 ), tilt_enr1, tilt_enr2; @@ -767,78 +779,85 @@ static Word16 pitch_search_fx( Word16 *s /*Qs*/, /* lastPcmOut */ return pitch; } -void concealment_init_x( Word16 N, void *_plcInfo ) +void concealment_init_x( + const Word16 L_frameTCX, + T_PLCInfo_HANDLE hPlcInfo ) { - T_PLCInfo *plcInfo = (T_PLCInfo *) _plcInfo; Word16 i; - plcInfo->FrameSize = N; + hPlcInfo->L_frameTCX = L_frameTCX; move16(); - plcInfo->Pitch_fx = 0; + hPlcInfo->Pitch_fx = 0; move16(); - plcInfo->T_bfi_fx = 0; + hPlcInfo->T_bfi_fx = 0; move16(); - plcInfo->outx_new_n1_fx = 0; + hPlcInfo->outx_new_n1_fx = 0; move16(); - plcInfo->nsapp_gain_fx = 0; + hPlcInfo->nsapp_gain_fx = 0; move16(); - plcInfo->nsapp_gain_n_fx = 0; + hPlcInfo->nsapp_gain_n_fx = 0; move16(); - plcInfo->ener_mean_fx = L_deposit_l( 15213 ); /*Q8 59.4260f*256*/ - plcInfo->ener_fx = L_deposit_l( 0 ); - plcInfo->zp_fx = N; + hPlcInfo->ener_mean_fx = L_deposit_l( 15213 ); /*Q8 59.4260f*256*/ + hPlcInfo->ener_fx = L_deposit_l( 0 ); + hPlcInfo->zp_fx = L_frameTCX; move16(); - plcInfo->recovery_gain = 0; + hPlcInfo->recovery_gain = 0; move16(); - plcInfo->step_concealgain_fx = 0; + hPlcInfo->step_concealgain_fx = 0; move16(); - plcInfo->concealment_method = TCX_NONTONAL; + hPlcInfo->concealment_method = TCX_NONTONAL; move16(); - plcInfo->subframe_fx = 0; + hPlcInfo->subframe_fx = 0; move16(); - plcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 ); + hPlcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 ); move16(); - plcInfo->seed = 21845; + hPlcInfo->seed = 21845; move16(); FOR( i = 0; i < TCX_TONALITY_INIT_CNT; i++ ) { - plcInfo->TCX_Tonality[i] = 1; + hPlcInfo->TCX_Tonality[i] = 1; move16(); } FOR( i = TCX_TONALITY_INIT_CNT; i < DEC_STATE_LEN; i++ ) { - plcInfo->TCX_Tonality[i] = 0; + hPlcInfo->TCX_Tonality[i] = 0; move16(); } FOR( i = 0; i < MAX_POST_LEN; i++ ) { - plcInfo->Transient[i] = 1; + hPlcInfo->Transient[i] = 1; move16(); } FOR( i = 0; i < L_FRAME_MAX; i++ ) { - plcInfo->data_reci2_fx[i] = L_deposit_l( 0 ); + hPlcInfo->data_reci2_fx[i] = L_deposit_l( 0 ); } + return; } + + void concealment_init_ivas_fx( const Word16 L_frameTCX, T_PLCInfo_HANDLE hPlcInfo ) { Word16 i; + hPlcInfo->L_frameTCX = L_frameTCX; move16(); - hPlcInfo->FrameSize = L_frameTCX; - move16(); +#ifndef FIX_WAVEADJUST hPlcInfo->Pitch = 0; move16(); +#endif hPlcInfo->Pitch_fx = 0; move16(); +#ifndef FIX_WAVEADJUST hPlcInfo->T_bfi = 0; move16(); +#endif hPlcInfo->T_bfi_fx = 0; move16(); hPlcInfo->outx_new_n1_fx = 0; @@ -849,8 +868,6 @@ void concealment_init_ivas_fx( move16(); hPlcInfo->ener_mean_fx = L_deposit_l( 15213 ); hPlcInfo->ener_fx = L_deposit_l( 0 ); - hPlcInfo->zp = L_frameTCX; - move16(); hPlcInfo->zp_fx = L_frameTCX; move16(); hPlcInfo->recovery_gain = 0; @@ -859,8 +876,10 @@ void concealment_init_ivas_fx( move16(); hPlcInfo->concealment_method = TCX_NONTONAL; move16(); +#ifndef FIX_WAVEADJUST hPlcInfo->subframe = 0; move16(); +#endif hPlcInfo->subframe_fx = 0; move16(); hPlcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 ); @@ -900,21 +919,25 @@ static Word16 own_random_fix( /* o : output random value */ return ( *seed ); } -void concealment_decode_fix( Word16 curr_mode, Word32 *invkoef /*Qinvkoef_scale*/, Word16 *invkoef_scale, void *_plcInfo ) +void concealment_decode_fix( + Word16 curr_mode, + Word32 *invkoef /*Qinvkoef_scale*/, + Word16 *invkoef_scale, + T_PLCInfo_HANDLE hPlcInfo ) { - T_PLCInfo *plcInfo = (T_PLCInfo *) _plcInfo; Word16 i; - Word16 N = plcInfo->FrameSize; - Word16 *seed = &( plcInfo->seed ); + Word16 N = hPlcInfo->L_frameTCX; + Word16 *seed = &( hPlcInfo->seed ); Word16 sign; move16(); - IF( plcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */ + + IF( hPlcInfo->concealment_method == TCX_NONTONAL ) /* #define TCX_NONTONAL 0 */ { IF( EQ_16( curr_mode, 1 ) ) { /* copy the data of the last frame */ - MVR2R_WORD32( plcInfo->data_reci2_fx, invkoef, N ); - *invkoef_scale = plcInfo->data_reci2_scale; + MVR2R_WORD32( hPlcInfo->data_reci2_fx, invkoef, N ); + *invkoef_scale = hPlcInfo->data_reci2_scale; move16(); /* sign randomization */ FOR( i = 0; i < N; i++ ) @@ -928,6 +951,7 @@ void concealment_decode_fix( Word16 curr_mode, Word32 *invkoef /*Qinvkoef_scale* } } } + return; } @@ -1103,25 +1127,29 @@ Word32 con_Log10( Word32 i_s32Val /*Qi_s32Val*/, Word16 i_s16Q /*Q0*/ ) /*o; Q26 return s32Out; } -void concealment_update2_x( const Word16 *outx_new /*Qoutx_new*/, void *_plcInfo, const Word16 FrameSize ) +void concealment_update2_x( + const Word16 *outx_new /*Qoutx_new*/, + T_PLCInfo_HANDLE hPlcInfo, + const Word16 FrameSize ) { - T_PLCInfo *plcInfo = (T_PLCInfo *) _plcInfo; - - plcInfo->zp_fx = zero_pass_w32_x( outx_new, FrameSize ); + hPlcInfo->zp_fx = zero_pass_w32_x( outx_new, FrameSize ); move16(); - Log10OfEnergy_x( outx_new, &plcInfo->ener_fx, FrameSize ); /* Q8 */ + Log10OfEnergy_x( outx_new, &hPlcInfo->ener_fx, FrameSize ); /* Q8 */ test(); - IF( LT_16( plcInfo->zp_fx, 100 ) && GT_32( plcInfo->ener_fx, L_shl( 50, 8 ) ) ) + IF( LT_16( hPlcInfo->zp_fx, 100 ) && GT_32( hPlcInfo->ener_fx, L_shl( 50, 8 ) ) ) { - plcInfo->ener_mean_fx = L_add( Mpy_32_16_1( plcInfo->ener_mean_fx, 32112 /* 0.98 Q15 */ ), - Mpy_32_16_1( plcInfo->ener_fx, 655 /* 0.02 Q15 */ ) ); + hPlcInfo->ener_mean_fx = L_add( Mpy_32_16_1( hPlcInfo->ener_mean_fx, 32112 /* 0.98 Q15 */ ), + Mpy_32_16_1( hPlcInfo->ener_fx, 655 /* 0.02 Q15 */ ) ); move32(); } + return; } -static Word16 array_max_indx_fx( Word16 *s /*Qs*/, Word16 N ) +static Word16 array_max_indx_fx( + Word16 *s /*Qs*/, + Word16 N ) { Word16 i, indx = 0; move16(); @@ -1278,7 +1306,7 @@ static Word16 waveform_adj_fix( zp1 = zero_pass_w32_x( outdata2, Framesizediv2 ); zp2 = zero_pass_w32_x( outdata2 + Framesizediv2, Framesizediv2 ); - pitch = hPlcInfo->Pitch; + pitch = hPlcInfo->Pitch_fx; /* judge if the pitch is usable */ tmp = 1; @@ -1298,7 +1326,11 @@ static Word16 waveform_adj_fix( test(); test(); test(); +#ifdef FIX_WAVEADJUST + IF( hPlcInfo->T_bfi_fx && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) +#else IF( hPlcInfo->T_bfi && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) +#endif { Word16 i1 = 0, i2 = 0; Word16 pos1, pos2, pos3; @@ -1420,7 +1452,7 @@ void waveform_adj2_fix( pitch = hPlcInfo->Pitch_fx; move16(); - L_frameTCX = hPlcInfo->FrameSize; + L_frameTCX = hPlcInfo->L_frameTCX; move16(); n = 0; move16(); @@ -1582,7 +1614,7 @@ void concealment_signal_tuning_fx( const Word16 past_core ) { T_PLCInfo_HANDLE hPlcInfo = st->hPlcInfo; - Word16 FrameSize = hPlcInfo->FrameSize; + Word16 L_frameTCX = hPlcInfo->L_frameTCX; Word16 voicing_fx = 0; Word16 *OverlapBuf_fx = st->hTonalMDCTConc->secondLastPcmOut; Word16 *outdata2_fx = st->hTonalMDCTConc->lastPcmOut; @@ -1598,12 +1630,12 @@ void concealment_signal_tuning_fx( { IF( EQ_16( st->nbLostCmpt, 1 ) ) { - hPlcInfo->Pitch_fx = pitch_search_fx( outdata2_fx, outx_new_fx, FrameSize, &voicing_fx, hPlcInfo->zp_fx, ( hPlcInfo->ener_fx ), ( hPlcInfo->ener_mean_fx ), hPlcInfo->data_reci2_fx, st->core ); + hPlcInfo->Pitch_fx = pitch_search_fx( outdata2_fx, outx_new_fx, L_frameTCX, &voicing_fx, hPlcInfo->zp_fx, ( hPlcInfo->ener_fx ), ( hPlcInfo->ener_mean_fx ), hPlcInfo->data_reci2_fx, st->core ); move16(); IF( hPlcInfo->Pitch_fx ) /* waveform adjustment for the first lost frame */ { - hPlcInfo->Pitch_fx = waveform_adj_fix( hPlcInfo, OverlapBuf_fx, outdata2_fx, outx_new_fx, FrameSize, voicing_fx, st->core ); + hPlcInfo->Pitch_fx = waveform_adj_fix( hPlcInfo, OverlapBuf_fx, outdata2_fx, outx_new_fx, L_frameTCX, voicing_fx, st->core ); move16(); } } -- GitLab From 6fe5bbb0b145006fd81900dbbf93e99bb753c867 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 15:14:30 +0100 Subject: [PATCH 0449/1221] add missing check against NULL --- lib_dec/dec_tcx_fx.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 8ecc60d6d..7ea9b0b01 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -1803,19 +1803,22 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, } /* run lpc gain compensation not for waveform adjustment */ - test(); - IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) - { - st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ - move16(); - } - ELSE + IF( st_fx->hPlcInfo != NULL ) { - st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/ + test(); + IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) + { + st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ + move16(); + } + ELSE + { + st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/ + move16(); + } + st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/ move16(); } - st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/ - move16(); } /*-----------------------------------------------------------* -- GitLab From 10869930f6c418522009a6fb8f44ec0ca7e1e6d1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 15:55:00 +0100 Subject: [PATCH 0450/1221] fix --- lib_dec/ivas_core_dec_fx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index e29d51717..456269c13 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1470,13 +1470,16 @@ ivas_error ivas_core_dec_fx( * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ + IF( st->hHQ_core != NULL ) + { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 #endif + } IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) { -- GitLab From ff84b4b1f1fd68d063c4bb518f43ecdfe1441d2a Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 18:09:16 +0100 Subject: [PATCH 0451/1221] harmonize hTonalMDCTConc + remove a duplication of the handle --- lib_dec/amr_wb_dec_fx.c | 2 +- lib_dec/core_dec_init_fx.c | 20 ++++++++------------ lib_dec/dec_LPD_fx.c | 4 ++-- lib_dec/dec_tcx_fx.c | 23 ++++++++++------------- lib_dec/er_util_fx.c | 34 ++++++---------------------------- lib_dec/evs_dec_fx.c | 2 +- lib_dec/hq_core_dec_fx.c | 20 ++++++++++---------- lib_dec/init_dec_fx.c | 16 ++++++++++++++++ lib_dec/ivas_core_dec_fx.c | 8 ++++---- lib_dec/stat_dec.h | 2 -- 10 files changed, 58 insertions(+), 73 deletions(-) diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 2aa9f82b3..db4ad2bb0 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -1075,7 +1075,7 @@ ivas_error amr_wb_dec_fx( move16(); } - waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth_out_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth_out_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); } /* HP filter */ diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 0968d10c5..e104766c0 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -1034,28 +1034,24 @@ void open_decoder_LPD_fx( } /* PLC: [TCX: Tonal Concealment] */ -#if 0 - PMT("handle to tonalMDCTconceal is missing") -#endif - //#ifdef ADD_IVAS_HTONALMDCTCONC test(); test(); - IF( /*st->ADD_IVAS_HTONALMDCTCONC != NULL &&*/ !( st->element_mode > EVS_MONO && NE_16( st->ini_frame, 0 ) && EQ_16( st->tonalMDCTconceal.nSamples, st->hTcxDec->L_frameTCX ) ) ) + IF( st->hTonalMDCTConc != NULL && !( st->element_mode > EVS_MONO && NE_16( st->ini_frame, 0 ) && EQ_16( st->hTonalMDCTConc->nSamples, st->hTcxDec->L_frameTCX ) ) ) { - st->tonalMDCTconceal.nScaleFactors = 0; + st->hTonalMDCTConc->nScaleFactors = 0; move16(); - st->tonalMDCTconceal.nSamples = 0; + st->hTonalMDCTConc->nSamples = 0; move16(); - st->tonalMDCTconceal.lastPcmOut = 0x0; + st->hTonalMDCTConc->lastPcmOut = 0x0; move16(); - st->tonalMDCTconceal.q_lastPcmOut = Q15; + st->hTonalMDCTConc->q_lastPcmOut = Q15; move16(); - st->tonalMDCTconceal.lastBlockData.tonalConcealmentActive = 0; + st->hTonalMDCTConc->lastBlockData.tonalConcealmentActive = 0; move16(); - st->tonalMDCTconceal.lastBlockData.nSamples = 0; + st->hTonalMDCTConc->lastBlockData.nSamples = 0; move16(); - TonalMDCTConceal_Init( &st->tonalMDCTconceal, hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg ); + TonalMDCTConceal_Init( st->hTonalMDCTConc, hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg ); } st->last_tns_active = 0; move16(); diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index 55d6ac36e..d5294eb7a 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -634,7 +634,7 @@ void decoder_LPD_fx( /* PLC: [TCX: Tonal Concealment] */ /* Signal that this frame is not TCX */ - TonalMDCTConceal_UpdateState( &st->tonalMDCTconceal, 0, 0, 0, 0 ); + TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, 0, 0, 0, 0 ); IF( bfi == 0 ) { @@ -771,7 +771,7 @@ void decoder_LPD_fx( IF( !bfi ) { - TonalMDCTConceal_SaveTimeSignal( &st->tonalMDCTconceal, synthFB, L_frameTCX ); + TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX ); } #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT decoder_tcx_post_fx( st, synth, synthFB, Aq, bfi, 0 ); diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 7ea9b0b01..e5140d513 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -821,8 +821,7 @@ void decoder_tcx_fx( IF( bfi == 0 ) { - TonalMDCTConceal_SaveFreqSignal( &st->tonalMDCTconceal, x, x_e, L_frameTCX, - L_frame, gainlpc2, gainlpc2_e, gain_tcx_e ); + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, x_e, L_frameTCX, L_frame, gainlpc2, gainlpc2_e, gain_tcx_e ); } ELSE { @@ -852,8 +851,8 @@ void decoder_tcx_fx( Word16 exp1, exp2; Word32 E_2ndlast, E_last; - E_2ndlast = CalculateAbsEnergy_fx( 1, &( st->tonalMDCTconceal.lastBlockData.spectralData[0] ), infoIGFStartLine, &exp2 ); - E_last = CalculateAbsEnergy_fx( 1, &( st->tonalMDCTconceal.lastBlockData.spectralData[1] ), infoIGFStartLine, &exp1 ); + E_2ndlast = CalculateAbsEnergy_fx( 1, &( st->hTonalMDCTConc->lastBlockData.spectralData[0] ), infoIGFStartLine, &exp2 ); + E_last = CalculateAbsEnergy_fx( 1, &( st->hTonalMDCTConc->lastBlockData.spectralData[1] ), infoIGFStartLine, &exp1 ); BASOP_Util_Divide_MantExp( extract_h( E_2ndlast ), exp2, extract_h( E_last ), exp1, &tmp1, &tmp2 ); @@ -865,7 +864,7 @@ void decoder_tcx_fx( FOR( i = 0; i < infoIGFStartLine; i += 2 ) { move32(); - st->tonalMDCTconceal.lastBlockData.spectralData[i] = st->tonalMDCTconceal.lastBlockData.spectralData[i + 1]; + st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; } } ELSE IF( LT_16( tmp1, 4096 /*0.5 in Q13*/ ) ) @@ -873,7 +872,7 @@ void decoder_tcx_fx( FOR( i = 0; i < infoIGFStartLine; i += 2 ) { move32(); - st->tonalMDCTconceal.lastBlockData.spectralData[i + 1] = st->tonalMDCTconceal.lastBlockData.spectralData[i]; + st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i]; } } } @@ -892,7 +891,7 @@ void decoder_tcx_fx( tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor ); - TonalMDCTConceal_InsertNoise( &st->tonalMDCTconceal, x, &x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, &x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT concealment_noise, @@ -980,7 +979,7 @@ void decoder_tcx_fx( test(); IF( bfi && st->tonal_mdct_plc_active ) { - TonalMDCTConceal_Apply( &st->tonalMDCTconceal, x, &x_e ); + TonalMDCTConceal_Apply( st->hTonalMDCTConc, x, &x_e ); } tmp32 = L_deposit_h( 0 ); @@ -996,11 +995,8 @@ void decoder_tcx_fx( tmp8 = 1; move16(); } - TonalMDCTConceal_UpdateState( &st->tonalMDCTconceal, - L_frameTCX, - tmp32, - bfi, - tmp8 ); + + TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, L_frameTCX, tmp32, bfi, tmp8 ); IF( st->enablePlcWaveadjust ) { @@ -1013,6 +1009,7 @@ void decoder_tcx_fx( /* x_e =31-x_scale; */ concealment_decode_fix( core, x, &x_e, st->hPlcInfo ); } + /* update spectrum buffer, tonality flag, etc. */ concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, st->hPlcInfo ); } diff --git a/lib_dec/er_util_fx.c b/lib_dec/er_util_fx.c index 8c94ecf98..55462ffe1 100644 --- a/lib_dec/er_util_fx.c +++ b/lib_dec/er_util_fx.c @@ -439,8 +439,6 @@ Word16 GetPLCModeDecision_ivas_fx( test(); test(); test(); - // PMT("handle to tonalMDCTconceal is missing") - //#ifdef ADD_IVAS_HTONALMDCTCONC IF( ( st->hTonalMDCTConc != NULL && EQ_16( st->last_core, TCX_20_CORE ) ) && ( EQ_16( st->second_last_core, TCX_20_CORE ) ) && ( ( LE_32( st->old_fpitch, L_deposit_h( shr( st->L_frame, 1 ) ) ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) ) /* it is fine to call the detection even if no ltp information is available, meaning that st->old_fpitch == @@ -454,12 +452,8 @@ Word16 GetPLCModeDecision_ivas_fx( { pitch = L_add( st->old_fpitch, 0 ); /*Q16*/ } - // TonalMDCTConceal_Detect_ivas_fx(&st->tonalMDCTconceal, pitch, &numIndices - // , (st->element_mode == IVAS_CPE_MDCT ? &(st->hTcxCfg->psychParamsTCX20) : st->hTcxCfg->psychParamsCurrent) - //); - TonalMDCTConceal_Detect_ivas_fx( st->hTonalMDCTConc, pitch, &numIndices, ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ), - st->element_mode ); + TonalMDCTConceal_Detect_ivas_fx( st->hTonalMDCTConc, pitch, &numIndices, ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ), st->element_mode ); test(); test(); @@ -554,6 +548,7 @@ Word16 GetPLCModeDecision_fx( core = st->last_core_bfi; move16(); } + IF( EQ_16( st->nbLostCmpt, 1 ) ) { st->tonal_mdct_plc_active = 0; @@ -569,9 +564,7 @@ Word16 GetPLCModeDecision_fx( test(); test(); test(); - // PMT("handle to tonalMDCTconceal is missing") - //#ifdef ADD_IVAS_HTONALMDCTCONC - IF( ( /*st->ADD_IVAS_HTONALMDCTCONC != NULL &&*/ EQ_16( st->last_core, TCX_20_CORE ) ) && ( EQ_16( st->second_last_core, TCX_20_CORE ) ) && ( ( LE_32( st->old_fpitch, L_deposit_h( shr( st->L_frame, 1 ) ) ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) ) + IF( ( st->hTonalMDCTConc != NULL && EQ_16( st->last_core, TCX_20_CORE ) ) && ( EQ_16( st->second_last_core, TCX_20_CORE ) ) && ( ( LE_32( st->old_fpitch, L_deposit_h( shr( st->L_frame, 1 ) ) ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) ) /* it is fine to call the detection even if no ltp information is available, meaning that st->old_fpitch == st->tcxltp_second_last_pitch == st->L_frame */ @@ -585,24 +578,9 @@ Word16 GetPLCModeDecision_fx( { pitch = L_add( st->old_fpitch, 0 ); /*Q16*/ } - IF( st->element_mode == EVS_MONO ) - { - TonalMDCTConceal_Detect( &st->tonalMDCTconceal, pitch, &numIndices, st->element_mode -#ifdef ADD_IVAS_HTONALMDCTCONC - , - ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) -#endif - ); - } - ELSE - { - TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode -#ifdef ADD_IVAS_HTONALMDCTCONC - , - ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) -#endif - ); - } + + TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode, + ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) ); test(); test(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 2a9115237..f343a8523 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -514,7 +514,7 @@ ivas_error evs_dec_fx( tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); /*Q0*/ } - waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); st_fx->hPlcInfo->Pitch_fx = 0; move16(); } diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index e45c30601..0abb75592 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -494,14 +494,14 @@ void hq_core_dec_fx( { st_fx->hPlcInfo->recovery_gain = shl_sat( st_fx->hPlcInfo->recovery_gain, *Q_synth ); /* Q14 + Q_synth */ move16(); - IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) + IF( st_fx->hTonalMDCTConc->q_lastPcmOut != 0 ) { - Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - st_fx->tonalMDCTconceal.q_lastPcmOut = 0; + Scale_sig( st_fx->hTonalMDCTConc->secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) ); + Scale_sig( st_fx->hTonalMDCTConc->lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) ); + st_fx->hTonalMDCTConc->q_lastPcmOut = 0; move16(); } - waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); } IF( GE_16( output_frame, L_FRAME16k ) ) @@ -1114,14 +1114,14 @@ void ivas_hq_core_dec_fx( { st_fx->hPlcInfo->recovery_gain = shl_sat( st_fx->hPlcInfo->recovery_gain, *Q_synth ); /* Q15 */ move16(); - IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) + IF( st_fx->hTonalMDCTConc->q_lastPcmOut != 0 ) { - Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st_fx->tonalMDCTconceal.lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); - st_fx->tonalMDCTconceal.q_lastPcmOut = 0; + Scale_sig( st_fx->hTonalMDCTConc->secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) ); + Scale_sig( st_fx->hTonalMDCTConc->lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) ); + st_fx->hTonalMDCTConc->q_lastPcmOut = 0; move16(); } - waveform_adj2_fix( st_fx->hPlcInfo, st_fx->tonalMDCTconceal.secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); + waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi ); } IF( GE_16( output_frame, L_FRAME16k ) ) diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 95f64cdbd..4bb98922f 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -507,6 +507,14 @@ ivas_error init_decoder_fx( { st_fx->hTcxCfg = NULL; } + + /* Tonal MDCT concealment data structure */ + + if ( ( st_fx->hTonalMDCTConc = (TonalMDCTConcealPtr) malloc( sizeof( TonalMDCTConceal_INSTANCE ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TonalMDCTConcealment\n" ) ); + } + st_fx->prev_coder_type = GENERIC; move16(); @@ -748,6 +756,14 @@ ivas_error init_decoder_fx( st_fx->last_vbr_hw_BWE_disable_dec = 0; move16(); + /*-----------------------------------------------------------------* + * Mode 2 initialization + *-----------------------------------------------------------------*/ + + IF( ( st_fx->hPlcInfo = (T_PLCInfo_HANDLE) malloc( sizeof( T_PLCInfo ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for PLC handle\n" ) ); + } st_fx->enablePlcWaveadjust = 0; move16(); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 456269c13..a4e5a8b29 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1273,11 +1273,11 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->core, ACELP_CORE ) && !st->bfi && st->prev_bfi && GE_32( st->last_total_brate, HQ_48k ) && EQ_16( st->last_codec_mode, MODE2 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_16( st->hPlcInfo->nbLostCmpt, 4 ) ) { tmps = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); - IF( st->tonalMDCTconceal.q_lastPcmOut != 0 ) + IF( st->hTonalMDCTConc->q_lastPcmOut != 0 ) { - Scale_sig( st->tonalMDCTconceal.secondLastPcmOut, shr( st->hPlcInfo->L_frameTCX, 1 ), negate( st->tonalMDCTconceal.q_lastPcmOut ) ); - Scale_sig( st->tonalMDCTconceal.lastPcmOut, st->hPlcInfo->L_frameTCX, negate( st->tonalMDCTconceal.q_lastPcmOut ) ); - st->tonalMDCTconceal.q_lastPcmOut = 0; + Scale_sig( st->hTonalMDCTConc->secondLastPcmOut, shr( st->hPlcInfo->L_frameTCX, 1 ), negate( st->hTonalMDCTConc->q_lastPcmOut ) ); + Scale_sig( st->hTonalMDCTConc->lastPcmOut, st->hPlcInfo->L_frameTCX, negate( st->hTonalMDCTConc->q_lastPcmOut ) ); + st->hTonalMDCTConc->q_lastPcmOut = 0; move16(); } waveform_adj2_fix( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 2727bac44..928b0df04 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1885,8 +1885,6 @@ typedef struct Decoder_State Word16 last_ctx_hm_enabled; - struct tonalmdctconceal tonalMDCTconceal; - TonalMDCTConcealPtr hTonalMDCTConc; Word16 tonal_mdct_plc_active; Word16 last_tns_active; -- GitLab From d3e828a2a18b2b47e038c6bf1c1a5bfc53077915 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 19:25:35 +0100 Subject: [PATCH 0452/1221] revert initialization --- lib_dec/er_util_fx.c | 8 ++++++-- lib_dec/ivas_core_dec_fx.c | 2 ++ lib_dec/ivas_jbm_dec_fx.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib_dec/er_util_fx.c b/lib_dec/er_util_fx.c index 55462ffe1..9735129ec 100644 --- a/lib_dec/er_util_fx.c +++ b/lib_dec/er_util_fx.c @@ -579,8 +579,12 @@ Word16 GetPLCModeDecision_fx( pitch = L_add( st->old_fpitch, 0 ); /*Q16*/ } - TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode, - ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) ); + TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode +#ifdef IVAS_CODE_MDCT_GSHAPE + , + ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) +#endif + ); test(); test(); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index a4e5a8b29..cc8425baa 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -480,6 +480,8 @@ ivas_error ivas_core_dec_fx( * HQ core decoding *---------------------------------------------------------------------*/ + set16_fx( output_16_fx[n], 0, L_FRAME48k ); /* this is needed for instances like L_norm_arr( p_output_fx[i], L_FRAME48k ) */ + IF( st->core == ACELP_CORE ) { /* ACELP core decoder */ diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 4fa2055bd..d111b4ac4 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -409,7 +409,7 @@ ivas_error ivas_jbm_dec_tc_fx( move16(); FOR( i = 0; i < 2; i++ ) { - s = s_min( s, L_norm_arr( p_output_fx[i], L_FRAME48k ) - 11 ) /* Guard bits */; + s = s_min( s, L_norm_arr( p_output_fx[i], L_FRAME48k ) - 11 ) /* Guard bits */; // L_frame should be used instead of L_FRAME48k */ } FOR( i = 0; i < 2; i++ ) { -- GitLab From 6b7b8ea6c807963a113b2eee24d0852e4aae2e2f Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Mar 2025 20:58:46 +0100 Subject: [PATCH 0453/1221] activate NONBE_FIX_1402_WAVEADJUST to fix EVS non-BE --- lib_com/options.h | 2 +- lib_dec/dec_tcx_fx.c | 2 +- lib_dec/ivas_core_dec_fx.c | 2 +- lib_dec/ivas_tcx_core_dec_fx.c | 4 ++-- lib_dec/stat_dec.h | 6 +++--- lib_dec/waveadjust_fec_dec_fx.c | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index abdbbc918..99fec7e7c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -172,5 +172,5 @@ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ -//#define FIX_WAVEADJUST /* fix waveform adjustment decoder PLC */ +#define NONBE_FIX_1402_WAVEADJUST /* VA: BASOP iisue 1402: fix waveform adjustment decoder PLC */ #endif diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index e5140d513..941b34956 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -4406,7 +4406,7 @@ void decoder_tcx_noisefilling_fx( /* get the starting location of the subframe in the frame */ IF( EQ_16( st->core, TCX_10_CORE ) ) { -#ifdef FIX_WAVEADJUST +#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); #else st->hPlcInfo->subframe = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index cc8425baa..d85cfbf94 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1284,7 +1284,7 @@ ivas_error ivas_core_dec_fx( } waveform_adj2_fix( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); -#ifdef FIX_WAVEADJUST +#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->Pitch_fx = 0; #else st->hPlcInfo->Pitch = 0; diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index f840b00be..c187c351c 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -644,7 +644,7 @@ void stereo_tcx_core_dec_fx( test(); test(); test(); -#ifdef FIX_WAVEADJUST +#ifdef NONBE_FIX_1402_WAVEADJUST IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch_fx && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) #else IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) @@ -654,7 +654,7 @@ void stereo_tcx_core_dec_fx( if ( !bfi && st->prev_bfi ) { -#ifdef FIX_WAVEADJUST +#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->Pitch_fx = 0; #else st->hPlcInfo->Pitch = 0; diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 928b0df04..6ac335a52 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -175,11 +175,11 @@ typedef struct { Word16 L_frameTCX; -#ifndef FIX_WAVEADJUST +#ifndef NONBE_FIX_1402_WAVEADJUST Word16 Pitch; #endif Word16 Pitch_fx; -#ifndef FIX_WAVEADJUST +#ifndef NONBE_FIX_1402_WAVEADJUST Word16 T_bfi; #endif Word8 T_bfi_fx; @@ -202,7 +202,7 @@ typedef struct Word16 concealment_method; -#ifndef FIX_WAVEADJUST +#ifndef NONBE_FIX_1402_WAVEADJUST Word16 subframe; #endif Word16 subframe_fx; diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c index 837a45ba6..f993caa8d 100644 --- a/lib_dec/waveadjust_fec_dec_fx.c +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -848,13 +848,13 @@ void concealment_init_ivas_fx( hPlcInfo->L_frameTCX = L_frameTCX; move16(); -#ifndef FIX_WAVEADJUST +#ifndef NONBE_FIX_1402_WAVEADJUST hPlcInfo->Pitch = 0; move16(); #endif hPlcInfo->Pitch_fx = 0; move16(); -#ifndef FIX_WAVEADJUST +#ifndef NONBE_FIX_1402_WAVEADJUST hPlcInfo->T_bfi = 0; move16(); #endif @@ -876,7 +876,7 @@ void concealment_init_ivas_fx( move16(); hPlcInfo->concealment_method = TCX_NONTONAL; move16(); -#ifndef FIX_WAVEADJUST +#ifndef NONBE_FIX_1402_WAVEADJUST hPlcInfo->subframe = 0; move16(); #endif @@ -1326,7 +1326,7 @@ static Word16 waveform_adj_fix( test(); test(); test(); -#ifdef FIX_WAVEADJUST +#ifdef NONBE_FIX_1402_WAVEADJUST IF( hPlcInfo->T_bfi_fx && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) #else IF( hPlcInfo->T_bfi && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) -- GitLab From ed62ce7c7e7cffe63c2aa1d5e9cda46f8545377f Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 10:06:23 +0100 Subject: [PATCH 0454/1221] review of core decoder handles --- lib_com/bitstream_fx.c | 652 ------------------------------------ lib_com/prot_fx.h | 19 -- lib_dec/acelp_core_dec_fx.c | 2 +- lib_dec/evs_dec_fx.c | 3 +- lib_dec/init_dec_fx.c | 6 - lib_dec/ivas_cpe_dec_fx.c | 2 - lib_dec/ivas_sce_dec_fx.c | 2 - lib_dec/stat_dec.h | 433 +++++++----------------- 8 files changed, 133 insertions(+), 986 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index d4938f399..141d1996e 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -1548,516 +1548,6 @@ Word32 BIT_ALLOC_IDX_16KHZ_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 t return L_temp; } -/*-------------------------------------------------------------------* - * read_indices_mime_handle_dtx() - * - * Handle DTX for MIME and RTP_DUMP decoding. - * Returns the actual total_brate. - *-------------------------------------------------------------------*/ - -static Word32 read_indices_mime_handle_dtx( - Decoder_State *st, - Word16 isAMRWB_IOmode, - Word16 core_mode, - Word32 total_brate, - Word16 sti, - Word16 speech_lost, - Word16 no_data ) -{ - Word16 curr_ft_good_sp = 0; - Word16 speech_bad = 0; - Word16 sid_upd_bad = 0, sid_update = 0; - Word16 amrwb_sid_first = 0; /* derived from sti SID_FIRST indicator in AMRWB payload */ - move16(); - move16(); - move16(); - move16(); - move16(); - - /* keep st->CNG , st_bfi and total_brate updated for proper synthesis in DTX and FER */ - IF( GT_32( total_brate, SID_2k40 ) ) - { - if ( NE_16( st->bfi, 1 ) ) /* so far derived from q bit in AMRWB/AMRWBIO cases */ - { - curr_ft_good_sp = 1; - move16(); - } - } - - /* handle q_bit and lost_sp clash , assume worst case */ - IF( speech_lost != 0 ) /* overrides a good q_bit */ - { - curr_ft_good_sp = 0; - move16(); - st->bfi = 1; /* override qbit */ - move16(); - } - - /* now_bfi_fx has been set based on q_bit and ToC fields */ - - - /* SID_UPDATE check */ - test(); - IF( EQ_32( total_brate, SID_1k75 ) || EQ_32( total_brate, SID_2k40 ) ) - { - IF( st->bfi == 0 ) - { - /* typically from q bit */ - sid_update = 1; - move16(); - } - ELSE - { - sid_upd_bad = 1; /* may happen in saving from e.g. a CS-connection */ - move16(); - } - } - - test(); - test(); - IF( isAMRWB_IOmode && total_brate == 0 && sti == 0 ) - { - IF( st->bfi ) - { - sid_upd_bad = 1; /* corrupt sid_first, signaled as bad sid */ - move16(); - } - ELSE - { - amrwb_sid_first = 1; /* 1-sti */ - move16(); - } - } - - test(); - test(); - test(); - test(); - IF( sid_upd_bad != 0 && ( ( isAMRWB_IOmode != 0 && st->Opt_AMR_WB == 0 ) || /* switch to AMRWBIO */ - ( NE_16( isAMRWB_IOmode, 1 ) && EQ_16( st->Opt_AMR_WB, 1 ) ) /* switch from AMRWBIO */ - ) ) - { - /* do not allow a normal start of CNG synthesis if this SID(with BER or FER) is a switch to/from AMRWBIO */ - sid_upd_bad = 0; /* revert this detection due to AMRWBIO/EVS mode switch */ - move16(); - total_brate = 0; - move32(); - no_data = 1; - move16(); - assert( st->bfi == 1 ); /* bfi stays 1 */ - } - - test(); - if ( GT_32( total_brate, SID_2k40 ) && EQ_16( st->bfi, 1 ) ) /* typically from q bit */ - { - speech_bad = 1; /* initial assumption, CNG synt state decides what to actually do */ - move16(); - } - /* all frame types decoded */ - - /* update CNG synthesis state */ - /* Decoder can only enter CNG-synthesis for CNG frame types (sid_upd, sid_bad, sid_first) */ - IF( st->CNG_fx != 0 ) - { - /* We were in CNG synthesis */ - if ( curr_ft_good_sp != 0 ) - { - /* only a good speech frame makes decoder leave CNG synthesis */ - st->CNG_fx = 0; - move16(); - } - } - ELSE - { - /* We were in SPEECH synthesis */ - /* only a received SID frame can make the decoder enter into CNG synthesis */ - test(); - test(); - if ( amrwb_sid_first || sid_update || sid_upd_bad ) - { - st->CNG_fx = 1; - move16(); - } - } - - /* Now modify bfi flag for the decoder's SPEECH/CNG synthesis logic */ - /* in SPEECH synthesis, make sure to activate speech plc for a received no_data frame, - no_data frames may be injected by the network or by the dejitter buffer */ - /* modify bfi_flag to stay/move into the correct decoder PLC section */ - test(); - if ( ( st->CNG_fx == 0 ) && ( no_data != 0 ) ) - { - /* treat no_data received in speech synthesis as SP_LOST frames, SPEECH PLC code will now become active */ - st->bfi = 1; - move16(); - /* total_brate= 0; always zero for no_data */ - } - - /* in CNG */ - /* handle bad speech frame(and bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ - test(); - test(); - test(); - test(); - IF( ( st->CNG_fx != 0 && ( speech_bad || speech_lost || no_data ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ - sid_upd_bad ) /* SID_UPD_BAD --> start/stay CNG */ - { - st->bfi = 0; /* mark as good to not start speech PLC */ - move16(); - total_brate = 0; /* this zeroing needed for speech_bad, sid_bad frames */ - move32(); - } - - - /* now bfi, total_brate are set by RX-DTX handler:: - bfi==0, total_brate!=0 cng or speech pending bitrate - bfi==0, total_brate==0 cng will continue or start(sid_first, sid_bad) - bfi==1, total_brate!=0 speech plc - bfi==1, total_brate==0 , speech plc - */ - - - /* handle available AMRWB/AMRWBIO MIME header ToC rate-info at startup */ - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->bfi, 1 ) && st->ini_frame == 0 ) && - ( ( st->amrwb_rfc4867_flag != 0 ) || ( st->amrwb_rfc4867_flag == 0 && isAMRWB_IOmode != 0 ) ) ) /*AMRWB ToC */ - { - Word32 init_rate; - - init_rate = total_brate; /* default , may have been modified from original ToC value */ - move32(); - - test(); - IF( speech_lost != 0 || no_data != 0 ) - { - init_rate = ACELP_12k65; /* make sure the decoder starts up in a selected AMRWB mode */ - move32(); - } - ELSE IF( speech_bad != 0 ) - { - init_rate = AMRWB_IOmode2rate[core_mode]; /* read from from ToC */ - move32(); - } - st->total_brate = init_rate; /* not updated on bfi as decoderSelectCodec is not called below */ - move32(); - st->core_brate = init_rate; - move32(); - } - - return total_brate; -} - - -/*-------------------------------------------------------------------* - * read_indices_mime_handle_sti_and_all_zero_bits() - * - * Handle STI and frames with all zero bits for MIME and RTP_DUMP decoding. - *-------------------------------------------------------------------*/ - -static void read_indices_mime_handle_sti_and_all_zero_bits( - Decoder_State *st, - Word32 *total_brate, - Word16 sti ) -{ - Word16 k; - - IF( sti == 0 ) - { - *total_brate = 0; /* signal received SID_FIRST as a good frame with no bits */ - move32(); - FOR( k = 0; k < 35; k++ ) - { - st->bfi = s_or( st->bfi, st->bit_stream[k] ); /* partity check of 35 zeroes, any single 1 gives BFI */ - move16(); - } - } - /* all zero bit SID_update results in a valid LP filter with extremely high LP-filter-gain */ - /* all zero bits signal may be a result of CS bit errors or erronesouly injected by gateways or bad dejitter handlers */ - IF( EQ_16( sti, 1 ) ) - { /*sid_update received */ - Word16 sum = 0; - move16(); - FOR( k = 0; k < 35; k++ ) - { - sum = add( sum, st->bit_stream[k] ); /* check of 35 zeroes */ - } - - if ( sum == 0 ) - { - st->bfi = 1; /* eventually becomes SID_UPD_BAD */ - move16(); - } - } -} - - -/*------------------------------------------------------------------------------------------* - * read_indices_mime() - * - * Read indices from MIME formatted bitstream to the buffer - * The magic word and number of channnels should be consumed before calling this function - *-------------------------------------------------------------------------------------------*/ - -Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem */ - Decoder_State *st, /* i/o: decoder state structure */ - FILE *file, /* i : bitstream file */ - Word16 rew_flag /* i : rewind flag (rewind file after reading) */ -) -{ - Word16 k, isAMRWB_IOmode, cmi, core_mode = -1, qbit, sti; - UWord8 header; - UWord8 pFrame[( MAX_BITS_PER_FRAME + 7 ) >> 3]; - UWord8 mask = 0x80, *pt_pFrame = pFrame; - UWord16 *bit_stream_ptr; - Word16 num_bits; - Word32 total_brate; - UWord16 utmp; - Word32 L_tmp; - Word16 speech_lost = 0, no_data = 0; - Word16 num_bytes_read; - - move16(); - move16(); - move16(); - move16(); - - st->BER_detect = 0; - move16(); - st->bfi = 0; - move16(); - st->mdct_sw_enable = 0; - move16(); - st->mdct_sw = 0; - move16(); - reset_indices_dec_fx( st ); - - /* read the FT Header field from the bitstream */ - IF( NE_32( fread( &header, sizeof( UWord8 ), 1, file ), 1 ) ) - { - IF( ferror( file ) ) - { - /* error during reading */ - fprintf( stderr, "\nError reading the bitstream !" ); - exit( -1 ); - } - ELSE - { - /* end of file reached */ - return 0; - } - } - - /* init local RXDTX flags */ - sti = -1; - move16(); - - IF( st->amrwb_rfc4867_flag != 0 ) - { - /* RFC 4867 - 5.3 .... - Each stored speech frame starts with a one-octet frame header with - the following format: - 0 1 2 3 4 5 6 7 - +-+-+-+-+-+-+-+-+ - |P| FT |Q|P|P| - +-+-+-+-+-+-+-+-+ - The FT field and the Q bit are defined in the same way as in - Section 4.3.2. The P bits are padding and MUST be set to 0, and MUST be ignored. */ - - isAMRWB_IOmode = 1; - move16(); - qbit = s_and( shr( header, 2 ), 0x01 ); /* b2 bit (b7 is the F bit ) */ - st->bfi = !qbit; - move16(); - core_mode = s_and( shr( header, 3 ), 0x0F ); /* b6..b3 */ - total_brate = AMRWB_IOmode2rate[core_mode]; /* get the frame length from the header */ - move32(); - } - ELSE - { - /*0 1 2 3 4 5 6 7 MS-bit ---> LS-bit - +-+-+-+-+-+-+-+-+ - |H|F|E|x| brate | - +-+-+-+-+-+-+-+-+ - where : - "E|x| brate " is the 6 bit "FT" -field - x is unused if E=0, (should be 0 ) - x is the q-bit if E=1, q==1(good), Q==0(bad, maybe bit errors in payload ) - H,F always 0 in RTP format. - */ - isAMRWB_IOmode = extract_l( GT_16( s_and( header, 0x20 ), 0 ) ); /* get EVS mode-from header */ /* b2 */ - core_mode = s_and( header, 0x0F ); /* b4,b5,b6,b7 */ - - IF( isAMRWB_IOmode ) - { - qbit = extract_l( GT_16( s_and( header, 0x10 ), 0 ) ); /* get Q bit, valid for IO rates */ /* b3 */ - total_brate = AMRWB_IOmode2rate[core_mode]; - move32(); - } - ELSE - { - qbit = 1; /* assume good q_bit for the unused EVS-mode bit, complete ToC validity checked later */ - move16(); - total_brate = PRIMARYmode2rate[core_mode]; - move32(); - } - st->bfi = !qbit; - move16(); - } - - - /* set up RX-DTX-handler input */ - if ( EQ_16( core_mode, 14 ) ) - { - /* SP_LOST */ - speech_lost = 1; - move16(); - } - if ( EQ_16( core_mode, 15 ) ) - { - /* NO_DATA unsent CNG frame OR any frame marked or injected as no_data by e.g a signaling layer or dejitter buffer */ - no_data = 1; - move16(); - } - - Mpy_32_16_ss( total_brate, 5243, &L_tmp, &utmp ); /* 5243 is 1/50 in Q18. (0+18-15=3) */ - num_bits = extract_l( L_shr( L_tmp, 3 ) ); /* Q0 */ - st->total_num_bits = num_bits; - move16(); - - IF( total_brate < 0 ) - { - /* validate that total_brate (derived from RTP packet or a file header) is one of the defined bit rates */ - fprintf( stderr, "\n Error. Illegal total bit rate (= %d) in MIME ToC header \n", total_brate ); - /* num_bits = -1; not needed as BASOP multiplication preserves sign */ - } - - /* Check correctness of ToC headers */ - IF( st->amrwb_rfc4867_flag == 0 ) - { - /* EVS ToC header (FT field(b2-b7), H bit (b0), F bit (b1) , (EVS-modebit(b2)=0 unused(Qbit)(b3)==0) */ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( isAMRWB_IOmode == 0 ) && ( ( num_bits < 0 ) || ( s_and( header, 0x80 ) > 0 ) || ( s_and( header, 0x40 ) > 0 ) || s_and( header, 0x30 ) != 0x00 ) ) - { - /* incorrect FT header */ - fprintf( stderr, "\nError in EVS FT ToC header(%02x) ! ", header ); - exit( -1 ); - } - ELSE IF( ( isAMRWB_IOmode != 0 ) && ( ( num_bits < 0 ) || ( s_and( header, 0x80 ) > 0 ) || ( s_and( header, 0x40 ) > 0 ) ) ) /* AMRWBIO */ - { - /* incorrect IO FT header */ - fprintf( stderr, "\nError in EVS(AMRWBIO) FT ToC header(%02x) ! ", header ); - exit( -1 ); - } - } - ELSE - { - /* legacy AMRWB ToC, is only using Padding bits which MUST be ignored */ - IF( num_bits < 0 ) - { - /* incorrect FT header */ - fprintf( stderr, "\nError in AMRWB RFC4867 Toc(FT) header(%02x) !", header ); - exit( -1 ); - } - } - - /* read serial stream of indices from file to the local buffer */ - num_bytes_read = extract_l( fread( pFrame, sizeof( UWord8 ), shr( add( num_bits, 7 ), 3 ), file ) ); - IF( NE_16( num_bytes_read, shr( add( num_bits, 7 ), 3 ) ) ) - { - fprintf( stderr, "\nError, invalid number of bytes read ! Exiting ! \n" ); - exit( -1 ); - } - - /* in case rew_flag is set, rewind the file and return */ - /* (used in io_dec() to attempt print out info about technologies and to initialize the codec ) */ - IF( rew_flag ) - { - st->total_brate = total_brate; /* used for the codec banner output */ - move32(); - test(); - test(); - IF( st->bfi == 0 && speech_lost == 0 && no_data == 0 ) - { - decoder_selectCodec( st, total_brate, unpack_bit( &pt_pFrame, &mask ) ? G192_BIN1 : G192_BIN0 ); - } - return 1; - } - - - /* unpack speech data */ - bit_stream_ptr = st->bit_stream; - FOR( k = 0; k < num_bits; k++ ) - { - IF( isAMRWB_IOmode ) - { - st->bit_stream[sort_ptr[core_mode][k]] = unpack_bit( &pt_pFrame, &mask ); - move16(); - bit_stream_ptr++; - } - ELSE - { - *bit_stream_ptr++ = unpack_bit( &pt_pFrame, &mask ); - move16(); - } - } - - /* unpack auxiliary bits */ - /* Note: the cmi bits are unpacked for demo purposes; */ - test(); - IF( isAMRWB_IOmode && EQ_32( total_brate, SID_1k75 ) ) - { - sti = unpack_bit( &pt_pFrame, &mask ); - cmi = shl( unpack_bit( &pt_pFrame, &mask ), 3 ); - cmi = s_or( cmi, shl( unpack_bit( &pt_pFrame, &mask ), 2 ) ); - cmi = s_or( cmi, shl( unpack_bit( &pt_pFrame, &mask ), 1 ) ); - cmi = s_or( cmi, unpack_bit( &pt_pFrame, &mask ) ); - - read_indices_mime_handle_sti_and_all_zero_bits( st, &total_brate, sti ); - } - - /*add two zero bytes for arithmetic coder flush*/ - FOR( k = 0; k < 2 * 8; ++k ) - { - *bit_stream_ptr++ = 0; - move16(); - } - - /* MIME RX_DTX handler */ - IF( !rew_flag ) - { - total_brate = read_indices_mime_handle_dtx( st, isAMRWB_IOmode, core_mode, total_brate, sti, speech_lost, no_data ); - } - - IF( st->bfi == 0 ) - { - /* select MODE1 or MODE2 in MIME */ - IF( *st->bit_stream ) - { - decoder_selectCodec( st, total_brate, G192_BIN1 ); - } - ELSE - { - decoder_selectCodec( st, total_brate, G192_BIN0 ); - } - /* a change of the total bitrate should not be known to the decoder, if the received frame was truly lost */ - st->total_brate = total_brate; - move32(); - mdct_switching_dec( st ); - } - /* else{ bfi stay in past synthesis mode(SP,CNG) } */ - - return 1; -} /*-------------------------------------------------------------------* * berCheck() @@ -2418,148 +1908,6 @@ void get_NextCoderType_fx( move16(); } -/*-------------------------------------------------------------------* - * read_indices_from_djb_fx() - * - * Read indices from the de-jitter buffer payload (works also for AMR-WB IO mode) - *-------------------------------------------------------------------*/ - -void read_indices_from_djb_fx( - Decoder_State *st, /* i/o: decoder state structure */ - UWord8 *pt_stream, /* i : bitstream file */ - Word16 num_bits, /* i : input frame length in bits */ - Word16 isAMRWB_IOmode, - Word16 core_mode, - Word16 qbit, - Word16 partialframe, /* i : partial frame information */ - Word16 next_coder_type /* i : next coder type information */ -) -{ - Word16 k; - UWord8 mask = 0x80; - Word16 no_data = 0; - Word16 sti = -1; - UWord16 *bit_stream_ptr; - Word32 total_brate; - Word16 speech_lost = 0; - - move16(); - move16(); - move16(); - move16(); - - st->bfi = 0; - move16(); - st->BER_detect = 0; - move16(); - st->mdct_sw_enable = 0; - move16(); - st->mdct_sw = 0; - move16(); - reset_indices_dec_fx( st ); - - st->bfi = !qbit; - move16(); - total_brate = L_mult0( num_bits, 50 ); - st->total_num_bits = num_bits; - move16(); - - IF( num_bits == 0 ) /* guess type of missing frame for SP_LOST and NO_DATA */ - { - speech_lost = st->CNG_fx == 0; - move16(); - move16(); - no_data = st->CNG_fx != 0; - move16(); - } - - test(); - IF( partialframe || st->prev_use_partial_copy ) - { - st->next_coder_type = next_coder_type; - move16(); - } - ELSE - { - st->next_coder_type = INACTIVE; - move16(); - } - - if ( EQ_16( partialframe, 1 ) ) - { - st->bfi = 2; - move16(); - } - - /* unpack speech data */ - bit_stream_ptr = st->bit_stream; - /* convert bitstream from compact bytes to short values and store it in decoder state */ - FOR( k = 0; k < num_bits; k++ ) - { - test(); - IF( EQ_16( st->bitstreamformat, VOIP_RTPDUMP ) && isAMRWB_IOmode ) - { - st->bit_stream[sort_ptr[core_mode][k]] = unpack_bit( &pt_stream, &mask ); - move16(); - bit_stream_ptr++; - } - ELSE - { - *bit_stream_ptr++ = unpack_bit( &pt_stream, &mask ); - move16(); - } - } - - /* unpack auxiliary bits */ - test(); - IF( isAMRWB_IOmode && EQ_32( total_brate, SID_1k75 ) ) - { - IF( EQ_16( st->bitstreamformat, VOIP_RTPDUMP ) ) - { - /* A.2.2.1.3: AMR-WB SID_1k75 frame is followed by STI bit and CMI bits */ - sti = unpack_bit( &pt_stream, &mask ); - } - ELSE - { - /* VOIP_G192_RTP does not contain STI and CMI */ - sti = 1; - move16(); - } - read_indices_mime_handle_sti_and_all_zero_bits( st, &total_brate, sti ); - } - - /* add two zero bytes for arithmetic coder flush */ - FOR( k = 0; k < 8 * 2; ++k ) - { - *bit_stream_ptr++ = 0; - move16(); - } - - total_brate = read_indices_mime_handle_dtx( st, isAMRWB_IOmode, core_mode, total_brate, sti, speech_lost, no_data ); - /* st->CNG_fx set inside */ - - IF( NE_16( st->bfi, 1 ) ) - { - /* select Mode 1 or Mode 2 */ - IF( *st->bit_stream ) - { - decoder_selectCodec( st, total_brate, G192_BIN1 ); - } - ELSE - { - decoder_selectCodec( st, total_brate, G192_BIN0 ); - } - - - /* a change of the total bitrate should not be known to the decoder, if the received frame was truly lost */ - st->total_brate = total_brate; - move32(); - - mdct_switching_dec( st ); - } -} - - /*-------------------------------------------------------------------* * get_indice_preview() * diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 4eca45c35..e1d7a8be8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1368,12 +1368,6 @@ Word16 BRATE2IDX16k_fx( Word32 brate ); Word32 BIT_ALLOC_IDX_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 tc ); Word32 BIT_ALLOC_IDX_16KHZ_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 tc ); -Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem */ - Decoder_State *st, /* i/o: decoder state structure */ - FILE *file, /* i : bitstream file */ - Word16 rew_flag /* i : rewind flag (rewind file after reading)*/ -); - void getPartialCopyInfo( Decoder_State *st, /* i : decoder state structure */ Word16 *coder_type, @@ -1405,19 +1399,6 @@ void get_NextCoderType_fx( Word16 *next_coder_type /* o : next coder type */ ); -void read_indices_from_djb_fx( - Decoder_State *st, /* i/o: decoder state structure */ - UWord8 *pt_stream, /* i : bitstream file */ - Word16 nbits /* i : number of bits */ - , - Word16 isAMRWB_IOmode, - Word16 core_mode, - Word16 qbit, - Word16 partialframe /* i : partial frame information */ - , - Word16 next_coder_type /* i : next coder type information */ -); - void evs_dec_previewFrame( UWord8 *bitstream, /* i : bitstream pointer */ Word16 bitstreamSize, /* i : bitstream size */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 05f60ae53..0f94a7558 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -554,7 +554,7 @@ ivas_error acelp_core_dec_fx( IF( st_fx->cng_type == LP_CNG ) { - CNG_dec_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); + CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); /* comfort noise generation */ CNG_exc_fx( st_fx->core_brate, st_fx->L_frame, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index f343a8523..1ad2c50c7 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -350,10 +350,11 @@ ivas_error evs_dec_fx( * Postprocessing for ACELP/HQ core switching *---------------------------------------------------------------------*/ - if ( ( error = core_switching_post_dec_fx( st_fx, synth_fx, output_frame, core_switching_flag, st_fx->last_element_mode, &Qpostd ) ) != IVAS_ERR_OK ) + if ( ( error = core_switching_post_dec_fx( st_fx, synth_fx, output_frame, core_switching_flag, EVS_MONO, &Qpostd ) ) != IVAS_ERR_OK ) { return error; } + /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 4bb98922f..accfdc083 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -358,10 +358,6 @@ ivas_error init_decoder_fx( } st_fx->cng_type = -1; move16(); - st_fx->CNG_fx = 0; - move16(); /* RTXDTX handler CNG=1 nonCNG= 0,*/ - st_fx->prev_ft_speech_fx = 1; - move16(); /* RXDTX handeler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ st_fx->first_CNG = 0; move16(); Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); // Q15 @@ -843,8 +839,6 @@ ivas_error init_decoder_fx( move16(); st_fx->element_mode = EVS_MONO; /* element mode */ move16(); - st_fx->last_element_mode = st_fx->element_mode; /* element mode */ - move16(); st_fx->element_brate = -1; /* element bitrate */ move16(); st_fx->low_rate_mode = 0; /* low-rate mode flag */ diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 9e934cc88..0bd3092a5 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -1097,8 +1097,6 @@ ivas_error create_cpe_dec( move32(); st->is_ism_format = 0; move16(); - st->ivas_format = st_ivas->ivas_format; - move32(); IF( NE_32( ( error = init_decoder_ivas_fx( st, n, st_ivas->mc_mode ) ), IVAS_ERR_OK ) ) { diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index 26dc69191..cbe9e4da8 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -408,8 +408,6 @@ ivas_error create_sce_dec( move16(); st->is_ism_format = 0; move16(); - st->ivas_format = st_ivas->ivas_format; - move16(); test(); if ( EQ_16( (Word16) st_ivas->ivas_format, ISM_FORMAT ) || EQ_16( (Word16) st_ivas->ivas_format, MASA_ISM_FORMAT ) ) diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 6ac335a52..0e708ba36 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1258,115 +1258,74 @@ typedef struct Decoder_State * Common parameters *----------------------------------------------------------------------------------*/ - Word16 idchan; /* channel ID (audio channel number) */ - Word16 element_mode; /* element mode */ + Word16 idchan; /* channel ID (audio channel number) */ + Word16 element_mode; /* element mode */ +#ifdef DEBUGGING + Word16 id_element; /* element ID */ +#endif Word32 element_brate; /* element bitrate */ Word16 codec_mode; /* Mode 1 or 2 */ Word16 mdct_sw_enable; /* MDCT switching enable flag */ Word16 mdct_sw; /* MDCT switching indicator */ Word16 last_codec_mode; /* last used codec mode */ - UWord16 *bit_stream; /* pointer to bitstream buffer */ - - Word16 next_bit_pos; /* position of the next bit to be read from the bitstream */ - - Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ - Word16 sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ - Word16 amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ - Word16 total_num_bits; /* == st->total_brate / 50 */ - - Word16 BER_detect; /* flag to signal detected bit error in the bitstream */ - - Word32 output_Fs; /* output sampling rate */ - - Word16 output_frame_fx; /* Output frame length Q0*/ - - Word32 total_brate; /* total bitrate in kbps of the codec */ - - Word32 last_total_brate; /* last total bitrate in kbps of the codec */ - // Word32 last_total_brate_fx; /* last total bitrate in kbps of the codec Q0*/ - - Word32 last_total_brate_ber; /* last total bitrate in kbps of the codec - used only when first frame is lost and BER is detected afterwards */ - - Word16 bits_frame_nominal; /* avg bits per frame on active frame */ - Word32 last_bits_frame_nominal; /* last avg bits per frame on active frame */ - Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ - Word16 bits_frame_channel; /* bits frame channel */ - Word16 side_bits_frame_channel; /* bits frame channel */ - - Word16 core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ - - Word16 coder_type; /* coder type */ - Word16 transform_type[2]; /* TCX20/10/5 mode in each subframe */ - - Word32 core_brate; /* core bitrate */ - - Word32 last_core_brate; /* previous frame core bitrate */ - - Word16 extl; /* extension layer */ - - Word16 extl_orig; /* extension layer */ - - Word16 last_extl; /* previous extension layer */ - - Word32 extl_brate; /* extension layer bitrate */ - - Word32 extl_brate_orig; /* extension layer bitrate */ - - Word16 L_frame; /* ACELP core internal frame length */ - - Word16 bwidth; /* encoded signal bandwidth */ - - Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - - Word16 Opt_VOIP_fx; /* flag indicating VOIP mode with JBM */ - - Word16 ini_frame; /* initialization frames counter */ - + UWord16 *bit_stream; /* pointer to bitstream buffer */ + Word16 next_bit_pos; /* position of the next bit to be read from the bitstream */ + Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ + Word16 sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ + Word16 amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ + Word16 total_num_bits; /* == st->total_brate / 50 */ + Word16 BER_detect; /* flag to signal detected bit error in the bitstream */ + Word32 output_Fs; /* output sampling rate */ + Word16 output_frame_fx; /* Output frame length Q0*/ + Word32 total_brate; /* total bitrate in kbps of the codec */ + Word32 last_total_brate; /* last total bitrate in kbps of the codec */ + Word32 last_total_brate_ber; /* last total bitrate in kbps of the codec - used only when first frame is lost and BER is detected afterwards */ + Word16 bits_frame_nominal; /* avg bits per frame on active frame */ + Word32 last_bits_frame_nominal; /* last avg bits per frame on active frame */ + Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ + Word16 bits_frame_channel; /* bits frame channel */ + Word16 side_bits_frame_channel; /* bits frame channel */ + Word16 core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ + Word16 coder_type; /* coder type */ + Word16 transform_type[2]; /* TCX20/10/5 mode in each subframe */ + Word32 core_brate; /* core bitrate */ + Word32 last_core_brate; /* previous frame core bitrate */ + Word16 extl; /* extension layer */ + Word16 extl_orig; /* extension layer */ + Word16 last_extl; /* previous extension layer */ + Word32 extl_brate; /* extension layer bitrate */ + Word32 extl_brate_orig; /* extension layer bitrate */ + Word16 L_frame; /* ACELP core internal frame length */ + Word16 bwidth; /* encoded signal bandwidth */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_VOIP_fx; /* flag indicating VOIP mode with JBM */ + Word16 ini_frame; /* initialization frames counter */ Word16 prev_coder_type; /* coding type of last frame */ Word16 low_rate_mode; /* low-rate mode flag */ Word16 last_low_rate_mode; /* previous frame low-rate mode flag */ Word16 inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ - Word16 CNG_fx; /* RXDTX handler: CNG=1, nonCNG=0 */ - Word16 prev_ft_speech_fx; /* RXDTX handler: previous frametype flag for G.192 format AMRWB SID_FIRST detection */ - - - // note_ : produces failures if added below their float parts - Word16 old_exc_fx[L_EXC_MEM_DEC]; /* old excitation Q_exc*/ - Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame Q2.56*/ - Word16 lsp_old_fx[M]; /* old LSP vector at the end of the frame Q15*/ - /*----------------------------------------------------------------------------------* * ACELP core parameters *----------------------------------------------------------------------------------*/ - - Word16 tilt_code_fx; /* tilt of code Q15*/ - - - Word16 mem_syn1_fx[M]; /* synthesis filter memory (for core switching and FD BWE) */ - Word16 mem_syn2_fx[M]; /* synthesis filter memory Q_syn*/ + Word16 old_exc_fx[L_EXC_MEM_DEC]; /* old excitation Q_exc*/ + Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame Q2.56*/ + Word16 lsp_old_fx[M]; /* old LSP vector at the end of the frame Q15*/ + Word16 tilt_code_fx; /* tilt of code Q15*/ + Word16 mem_syn1_fx[M]; /* synthesis filter memory (for core switching and FD BWE) */ + Word16 mem_syn2_fx[M]; /* synthesis filter memory Q_syn*/ Word16 mem_syn3_fx[M]; - - Word16 mem_deemph_fx; /* deemphasis filter memory Q_syn*/ - - Word16 mem_AR_fx[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean)(Qx2.56) */ - - Word16 mem_MA_fx[M]; /* MA memory of LSF quantizer (past quantized residual)(Qx2.56)*/ - - Word16 stab_fac_fx; /* LSF stability factor Q15*/ - + Word16 mem_deemph_fx; /* deemphasis filter memory Q_syn*/ + Word16 mem_AR_fx[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean)(Qx2.56) */ + Word16 mem_MA_fx[M]; /* MA memory of LSF quantizer (past quantized residual)(Qx2.56)*/ + Word16 stab_fac_fx; /* LSF stability factor Q15*/ Word16 stab_fac_smooth_fx; /* low-pass filtered stability factor Q15*/ - - Word16 last_coder_type; /* previous coder type */ - - Word16 agc_mem_fx[2]; /* memory of AGC for saturation control Q0*/ - + Word16 last_coder_type; /* previous coder type */ + Word16 agc_mem_fx[2]; /* memory of AGC for saturation control Q0*/ Word16 mid_lsf_int; - Word16 safety_net; - Word32 log_energy_diff_lt_fx; /*In range of word16*/ /*Q-15*/ Word16 stab_fac_smooth_lt_fx; /*In range of word16*/ /*Q-15*/ Word32 log_energy_old_fx; @@ -1379,145 +1338,89 @@ typedef struct Decoder_State Word16 no_scales_p_fx[MAX_NO_MODES_p][2]; /* LSF LVQ structure Q0*/ Word32 L_mem_hp_out_fx[5]; /* hp filter memory for synthesis */ - - Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ - - Word16 GSC_IVAS_mode; /* AC mode (GSC) - GSC IVAS mode */ - + Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ + Word16 GSC_IVAS_mode; /* AC mode (GSC) - GSC IVAS mode */ Word16 Last_GSC_noisy_speech_flag; /* AC mode (GSC) - mem of the past flag to indicate GSC osn SWB noisy speech */ - GSC_DEC_HANDLE hGSCDec; - Word32 gc_threshold_fx; /* Noise enhancer - threshold for gain_code Q16*/ - + Word32 gc_threshold_fx; /* Noise enhancer - threshold for gain_code Q16*/ struct dispMem_fx dm_fx; /* Noise enhancer - phase dispersion algorithm memory */ ZERO_BWE_DEC_HANDLE hBWE_zero; /* HF (6-7kHz) BWE */ - Word16 unv_cnt; /* Stationary noise UV modification - unvoiced frame counter */ - - Word16 uv_count; /* Stationary noise UV modification - unvoiced counter */ - - Word16 act_count; /* Stationary noise UV modification - activation counter */ - - Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain Q(GE_SHIFT)*/ - - Word16 lspold_s_fx[M]; /* Stationary noise UV modification - old LSP vector Q15*/ - - Word16 noimix_seed; /* Stationary noise UV modification - mixture seed */ - - Word16 min_alpha_fx; /* Stationary noise UV modification - minimum alpha Q15*/ - - Word16 Q_stat_noise; /* Q of Exc_pe */ - - Word16 exc_pe_fx; /* Stationary noise UV modification - scale (Q_stat_noise) */ - + Word16 unv_cnt; /* Stationary noise UV modification - unvoiced frame counter */ + Word16 uv_count; /* Stationary noise UV modification - unvoiced counter */ + Word16 act_count; /* Stationary noise UV modification - activation counter */ + Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain Q(GE_SHIFT)*/ + Word16 lspold_s_fx[M]; /* Stationary noise UV modification - old LSP vector Q15*/ + Word16 noimix_seed; /* Stationary noise UV modification - mixture seed */ + Word16 min_alpha_fx; /* Stationary noise UV modification - minimum alpha Q15*/ + Word16 Q_stat_noise; /* Q of Exc_pe */ + Word16 exc_pe_fx; /* Stationary noise UV modification - scale (Q_stat_noise) */ Word16 Q_stat_noise_ge; /* Q of ge_sm_fx */ - - Word16 bfi; /* FEC - bad frame indicator */ - - Word16 prev_bfi; /* FEC - previous bad frame indicator */ - - Word16 prev_old_bfi; /* FEC - previous old bad frame indicator */ - - Word16 seed; /* FEC - seed for random generator for excitation */ - // Word16 seed_fx; /* FEC - seed for random generator for excitation Q0*/ - - - Word16 last_good; /* FEC - clas of last good received */ - - Word16 lp_gainp_fx; /* FEC - low-pass filtered pitch gain Q14 */ - - Word16 lp_gainc_fx; /* FEC - low-pass filtered code gain Q3*/ - - Word32 lp_ener_fx; /* FEC - low-pass filtered energy Q6*/ - - Word32 enr_old_fx; /* FEC - energy of the concealed frame Q0*/ - - Word16 bfi_pitch_fx; /* FEC - pitch for FEC */ - - Word16 bfi_pitch_frame; /* FEC - frame length when pitch for FEC is saved */ - + Word16 bfi; /* FEC - bad frame indicator */ + Word16 prev_bfi; /* FEC - previous bad frame indicator */ + Word16 prev_old_bfi; /* FEC - previous old bad frame indicator */ + Word16 seed; /* FEC - seed for random generator for excitation */ + Word16 last_good; /* FEC - clas of last good received */ + Word16 lp_gainp_fx; /* FEC - low-pass filtered pitch gain Q14 */ + Word16 lp_gainc_fx; /* FEC - low-pass filtered code gain Q3*/ + Word32 lp_ener_fx; /* FEC - low-pass filtered energy Q6*/ + Word32 enr_old_fx; /* FEC - energy of the concealed frame Q0*/ + Word16 bfi_pitch_fx; /* FEC - pitch for FEC */ + Word16 bfi_pitch_frame; /* FEC - frame length when pitch for FEC is saved */ Word16 old_pitch_buf_16_fx[2 * NB_SUBFR16k + 2]; /* FEC - buffer of old subframe pitch values Q6 */ Word32 old_pitch_buf_fx[2 * NB_SUBFR16k + 2]; /* FEC - buffer of old subframe pitch values 15Q16 */ - - Word16 upd_cnt; /* FEC - counter of frames since last update */ - - Word16 scaling_flag; /* FEC - flag to indicate energy control of syn */ - - Word32 lp_ener_FEC_av; /* FEC - averaged voiced signal energy Q0 */ - - Word32 lp_ener_FEC_max; /* FEC - averaged voiced signal energy Q0 */ - - Word16 old_enr_LP; /* FEC - LP filter gain Q5*/ - - Word16 prev_nbLostCmpt; /* FEC - compt for number of consecutive lost frame at the previous frame*/ - Word16 mode_lvq; /* FEC - index for LSF mean vector*/ - - - Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame (Qx2.56)*/ - - Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame (Qx2.56) */ - - Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC (Qx2.56)*/ - - Word16 decision_hyst; /* FEC - hysteresis of the music/speech decision */ - - Word16 lp_ener_FER_fx; /* FEC - long-term active-signal average energy Q8*/ - - + Word16 upd_cnt; /* FEC - counter of frames since last update */ + Word16 scaling_flag; /* FEC - flag to indicate energy control of syn */ + Word32 lp_ener_FEC_av; /* FEC - averaged voiced signal energy Q0 */ + Word32 lp_ener_FEC_max; /* FEC - averaged voiced signal energy Q0 */ + Word16 old_enr_LP; /* FEC - LP filter gain Q5*/ + Word16 prev_nbLostCmpt; /* FEC - compt for number of consecutive lost frame at the previous frame*/ + Word16 mode_lvq; /* FEC - index for LSF mean vector*/ + Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame (Qx2.56)*/ + Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame (Qx2.56) */ + Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC (Qx2.56)*/ + Word16 decision_hyst; /* FEC - hysteresis of the music/speech decision */ + Word16 lp_ener_FER_fx; /* FEC - long-term active-signal average energy Q8*/ WI_DEC_HANDLE hWIDec; - Word16 relax_prev_lsf_interp; - Word16 mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM]; /* FEC - memory of the synthesis signal for frame class estimation */ - Word16 bpf_off; /* Bass post-filter - do not use BPF when this flag is set to 1 */ - + Word16 bpf_off; /* Bass post-filter - do not use BPF when this flag is set to 1 */ BPF_DEC_HANDLE hBPF; /* Bass post-filter handle */ - HANDLE_CLDFB_FILTER_BANK cldfbAna; /* main analysis filter bank handle */ - - HANDLE_CLDFB_FILTER_BANK cldfbBPF; /* BPF analysis filter bank handle */ - - HANDLE_CLDFB_FILTER_BANK cldfbSyn; /* main synthesis filter bank handle */ - + HANDLE_CLDFB_FILTER_BANK cldfbAna; /* main analysis filter bank handle */ + HANDLE_CLDFB_FILTER_BANK cldfbBPF; /* BPF analysis filter bank handle */ + HANDLE_CLDFB_FILTER_BANK cldfbSyn; /* main synthesis filter bank handle */ HANDLE_CLDFB_FILTER_BANK cldfbSynHB; /* high band synthesis filter bank needed in SBA2Stereo DTX handling */ - Word16 last_active_bandsToZero_bwdec; Word16 last_flag_filter_NB; - Word16 perc_bwddec; /*Q14*/ - Word16 active_frame_cnt_bwddec; Word16 flag_buffer[20]; Word16 total_frame_cnt_bwddec; - Word32 avg_nrg_LT; - Word16 Ng_ener_ST_fx; /* Noise gate - short-term energy Q8*/ - Word16 last_L_frame; /* ACELP@16kHz - last value of st->L_frame */ - + Word16 last_L_frame; /* ACELP@16kHz - last value of st->L_frame */ Word16 mem_preemp_preQ_fx; /* ACELP@16kHz - prequantizer preemhasis memory */ - - Word16 last_nq_preQ; /* ACELP@16kHz - AVQ subquantizer number of the last sub-band of the last subframe */ - - Word16 last_code_preq; /* ACELP@16kHz - last coefficient of the pre-quantizer contribution */ - - Word16 use_acelp_preq; /* ACELP@16kHz - flag of prequantizer usage */ - + Word16 last_nq_preQ; /* ACELP@16kHz - AVQ subquantizer number of the last sub-band of the last subframe */ + Word16 last_code_preq; /* ACELP@16kHz - last coefficient of the pre-quantizer contribution */ + Word16 use_acelp_preq; /* ACELP@16kHz - flag of prequantizer usage */ /* NB and formant post-filter */ PFSTAT_HANDLE hPFstat; /* NB and formant post-filter states */ - Word16 psf_lp_noise_fx; - Word16 last_voice_factor_fx; /* Q6*/ - + Word16 last_voice_factor_fx; /* Q6*/ + Word16 prev_synth_buffer_fx[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS )]; /*Updated IVAS size is 96*/ + Word32 prev_synth_buffer32_fx[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS )]; + Word16 q_prev_synth_buffer_fx; + Word16 Qprev_synth_buffer_fx; Word16 old_bfi_cnt; /* HQ core - # of bfi until previous frame(for FEC) */ @@ -1526,23 +1429,16 @@ typedef struct Decoder_State *----------------------------------------------------------------------------------*/ Word16 first_CNG; /* DTX/CNG - first CNG frame flag */ - - Word16 cng_type; /* DTX/CNG - flag indicating LP or CLDFB based SID/CNG */ - + Word16 cng_type; /* DTX/CNG - flag indicating LP or CLDFB based SID/CNG */ Word16 last_vad; - Word32 last_active_brate; /* DTX/CNG - last active frame bitrate used for CNG_mode control */ + Word16 last_CNG_L_frame; /* DTX/CNG - last CNG frame length */ - Word16 last_CNG_L_frame; /* DTX/CNG - last CNG frame length */ - // Word16 last_CNG_L_frame_fx; /* DTX/CNG - last CNG frame length */ - - Word16 CNG_mode; /* DTX/CNG - mode for DTX configuration */ - // Word16 CNG_mode_fx; /* DTX/CNG - mode for DTX configuration */ + Word16 active_cnt; + Word16 CNG_mode; /* DTX/CNG - mode for DTX configuration */ Word16 lspCNG_fx[M]; /* CNG and DTX - LP filtered ISPs Q15*/ - Word16 active_cnt; - TD_CNG_DEC_HANDLE hTdCngDec; Word16 masa_sid_format; @@ -1559,20 +1455,12 @@ typedef struct Decoder_State SC_VBR_DEC_HANDLE hSC_VBR; Word16 last_ppp_mode_dec; - Word16 ppp_mode_dec; - Word16 last_nelp_mode_dec; - Word16 nelp_mode_dec; - - Word16 prev_gain_pit_dec_fx; /*Q14*/ - - + Word16 prev_gain_pit_dec_fx; /*Q14*/ Word16 prev_tilt_code_dec_fx; /*Q15*/ - Word16 vbr_hw_BWE_disable_dec; - Word16 last_vbr_hw_BWE_disable_dec; /*----------------------------------------------------------------------------------* @@ -1602,7 +1490,6 @@ typedef struct Decoder_State *----------------------------------------------------------------------------------*/ HR_BWE_DEC_HANDLE hBWE_FD_HR; - Word16 Qprev_synth_buffer_fx; /*----------------------------------------------------------------------------------* * HQ core parameters @@ -1611,26 +1498,18 @@ typedef struct Decoder_State HQ_DEC_HANDLE hHQ_core; Word16 last_core; - Word16 last_core_from_bs; /* last frame core as coded in TCX bitstream */ - // Word16 last_core_bs_fx; Word16 last_L_frame_ori; - Word16 previoussynth_fx[L_FRAME48k]; Word32 previoussynth_fx_32[L_FRAME48k]; - - Word16 old_synth_sw_fx[NS2SA( 48000, FRAME_SIZE_NS - ACELP_LOOK_NS - DELAY_BWE_TOTAL_NS )]; - Word16 delay_buf_out_fx[HQ_DELTA_MAX * HQ_DELAY_COMP]; /*Q0*/ Word32 delay_buf_out32_fx[HQ_DELTA_MAX * HQ_DELAY_COMP]; /*Q11*/ - Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ Word32 old_Aq_12_8_fx_32[M + 1]; /* Q28 old Aq[] for core switching */ - - Word16 old_Es_pred_fx; /* old Es_pred for core switching */ + Word16 old_Es_pred_fx; /* old Es_pred for core switching */ HQ_NBFEC_HANDLE hHQ_nbfec; @@ -1641,42 +1520,28 @@ typedef struct Decoder_State TD_BWE_DEC_HANDLE hBWE_TD; Word16 old_bwe_delay; - Word16 hb_prev_synth_buffer_fx[NS2SA( 48000, DELAY_BWE_TOTAL_NS )]; /* WB/SWB bandwidth switching */ - Word16 tilt_wb_fx; // Q11 - - Word16 tilt_swb_fx; // Q24 - + Word16 tilt_wb_fx; // Q11 + Word16 tilt_swb_fx; // Q24 Word16 prev_ener_shb_fx; // Q1 - Word32 enerLH_fx; Word16 enerLH_fx_Q; - Word32 prev_enerLH_fx; // Q1 - Word32 enerLL_fx; Word16 enerLL_fx_Q; - Word32 prev_enerLL_fx; // Q1 - Word16 prev_fractive; - Word16 prev_bws_cnt; - Word16 bws_cnt; - Word16 bws_cnt1; - Word16 attenu_fx; - Word16 last_inner_frame; - Word16 last_bwidth; - Word16 t_audio_q_fx[L_FRAME]; + // in FLP, the folowing ones are part of TD_CNG_DEC_HANDLE Word16 interpol_3_2_cng_dec_fx[INTERP_3_2_MEM_LEN]; /*----------------------------------------------------------------------------------* @@ -1704,11 +1569,10 @@ typedef struct Decoder_State Word16 prev_ener_fx_Q; Word16 last_wb_bwe_ener_fx; Word16 prev_fb_ener_adjust_fx; + Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; - Word16 prev_synth_buffer_fx[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS )]; /*Updated IVAS size is 96*/ - Word16 q_prev_synth_buffer_fx; + // in FLP, the folowing one is part of TD_BWE_DEC_HANDLE Word16 GainShape_Delay[NUM_SHB_SUBFR / 2]; - Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; /*----------------------------------------------------------------------------------* * SWB BWE structure @@ -1720,6 +1584,7 @@ typedef struct Decoder_State * SWB DTX/CNG parameters *----------------------------------------------------------------------------------*/ + // in FLP, the folowing ones are part of TD_CNG_DEC_HANDLE Word16 shb_cng_ener_fx; Word16 wb_cng_ener_fx; Word16 last_wb_cng_ener_fx; @@ -1741,6 +1606,7 @@ typedef struct Decoder_State /*----------------------------------------------------------------------------------* * TCX LTP decoder handle *----------------------------------------------------------------------------------*/ + TCX_LTP_DEC_HANDLE hTcxLtpDec; /*----------------------------------------------------------------------------------* @@ -1749,6 +1615,7 @@ typedef struct Decoder_State TCX_DEC_HANDLE hTcxDec; + /* in floating point implementation, different buffers are used: lp_error_ener <-> pst_lp_ener, mem_error <-> pst_mem_deemp_err */ Word32 lp_error_ener; Word32 mem_error; @@ -1777,43 +1644,25 @@ typedef struct Decoder_State Word16 L_frame_past; Word16 L_frameTCX_past; - Word16 lsfold_uw[M]; /* old lsf (unweighted) */ - - Word16 lspold_uw[M]; /* old lsp (unweighted) */ - - Word16 seed_tcx_plc; /* seed memory (for random function in TCX PLC) */ - - + Word16 lsfold_uw[M]; /* old lsf (unweighted) */ + Word16 lspold_uw[M]; /* old lsp (unweighted) */ + Word16 seed_tcx_plc; /* seed memory (for random function in TCX PLC) */ Word16 past_gpit; /* past gain of pitch (for frame recovery) */ Word32 past_gcode; /* past energy (!) of code (for frame recovery) */ /*15Q16*/ - - Word16 lsf_cng[M]; /* xSF coefficients used for CNG generation (long term) */ - - Word16 lspold_cng[M]; /* xSP coefficients used for CNG generation (long term) */ - - Word16 lsp_q_cng[M]; /* xSP coefficients used for CNG generation (short term interpolated) */ - - Word16 old_lsp_q_cng[M]; /* xSP coefficients used for CNG generation (short term interpolated) */ - - Word16 lsf_q_cng[M]; /* xSF coefficients used for CNG generation (short term interpolated) */ - - Word16 old_lsf_q_cng[M]; /* xSF: old quantized lsfs for background noise */ - - Word16 Aq_cng[( NB_SUBFR16k + 1 ) * ( M + 1 )]; /* LPC coefficients derived from CNG estimate */ - - Word16 mem_syn_unv_back[M]; /* filter memory for unvoiced synth */ - - Word16 plcBackgroundNoiseUpdated; /* flag: Is background noise estimate updated? */ - - Word16 last_gain_syn_deemph; /*Q15*/ - + Word16 lsf_cng[M]; /* xSF coefficients used for CNG generation (long term) */ + Word16 lspold_cng[M]; /* xSP coefficients used for CNG generation (long term) */ + Word16 lsp_q_cng[M]; /* xSP coefficients used for CNG generation (short term interpolated) */ + Word16 old_lsp_q_cng[M]; /* xSP coefficients used for CNG generation (short term interpolated) */ + Word16 lsf_q_cng[M]; /* xSF coefficients used for CNG generation (short term interpolated) */ + Word16 old_lsf_q_cng[M]; /* xSF: old quantized lsfs for background noise */ + Word16 Aq_cng[( NB_SUBFR16k + 1 ) * ( M + 1 )]; /* LPC coefficients derived from CNG estimate */ + Word16 mem_syn_unv_back[M]; /* filter memory for unvoiced synth */ + Word16 plcBackgroundNoiseUpdated; /* flag: Is background noise estimate updated? */ + Word16 last_gain_syn_deemph; /*Q15*/ Word16 last_gain_syn_deemph_e; - Word16 last_concealed_gain_syn_deemph; /*Q15*/ - Word16 last_concealed_gain_syn_deemph_e; - /* variables for framing */ Word16 nb_subfr; @@ -1831,10 +1680,7 @@ typedef struct Decoder_State /*Preemphasis factor*/ Word16 preemph_fac; /*0Q15*/ - - Word16 gamma; - Word16 inv_gamma; /*for AMR-WB like 6.4 to 7 kHz upsampling and noise filling*/ @@ -1844,33 +1690,23 @@ typedef struct Decoder_State Word16 last_core_bfi; /* PLC - mode in previous frame */ Word16 nbLostCmpt; /* PLC - compt for number of consecutive lost frame */ - Word32 old_fpitch; /* last pitch of previous frame */ /*15Q16*/ - + Word32 old_fpitch; /* last pitch of previous frame */ /*15Q16*/ Word32 old_fpitchFB; /* PLC - last pitch of previous FB frame (depends on output sr) */ /*15Q16*/ - - Word16 clas_dec; /* PLC - frame class at the decoder */ - - Word16 mem_pitch_gain[2 * NB_SUBFR16k + 2]; /* Pitch gain memory Q14 */ - - Word16 plc_use_future_lag; /* PLC - flag indicating if info (pitch lag / pitch gain) about future frame is usable */ + Word16 clas_dec; /* PLC - frame class at the decoder */ + Word16 mem_pitch_gain[2 * NB_SUBFR16k + 2]; /* Pitch gain memory Q14 */ + Word16 plc_use_future_lag; /* PLC - flag indicating if info (pitch lag / pitch gain) about future frame is usable */ Word32 Mode2_lp_gainc; /* 15Q16 low passed code gain used for concealment*/ Word32 Mode2_lp_gainp; /* 15Q16 low passed pitch gain used for concealment*/ - Word16 cummulative_damping; /*Q15*/ - Word16 cngTDLevel; Word16 cngTDLevel_e; - - Word16 prev_widow_left_rect; - Word16 reset_mem_AR; - Word16 classifier_Q_mem_syn; /*scalingfactor of mem_syn_clas_estim_fx in MODE2 */ - Word16 rate_switching_init; + Word16 prev_widow_left_rect; // should be removed /* LPC quantization */ Word16 lpcQuantization; @@ -1959,6 +1795,7 @@ typedef struct Decoder_State Word16 tec_flag; Word16 tfa_flag; TEC_DEC_HANDLE hTECDec; + /*----------------------------------------------------------------------------------* * IVAS parameters *----------------------------------------------------------------------------------*/ @@ -1968,21 +1805,11 @@ typedef struct Decoder_State Word16 cng_sba_flag; /* CNG in SBA flag */ /* MCT Channel mode indication: LFE, ignore channel? */ - // note_ : one extra value in evs ivas macro code MCT_CHAN_MODE mct_chan_mode; Word16 cng_ism_flag; /* CNG in ISM format flag */ Word16 is_ism_format; /* Indication whether the codec operates in ISM format */ - Word16 last_element_mode; /* element mode */ - // Word16 coder_type; /* low-rate mode flag */ - Word32 prev_synth_buffer32_fx[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS )]; - -#ifdef DEBUGGING - Word16 id_element; /* element ID */ -#endif - IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ - } Decoder_State, *DEC_CORE_HANDLE; #endif -- GitLab From 982c7d04e0f18c3744876399fa4ef1d6d1387fbd Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 11:38:07 +0100 Subject: [PATCH 0455/1221] remove unused functions --- lib_com/bitstream.c | 86 -------------------- lib_com/bitstream_fx.c | 176 +---------------------------------------- lib_com/prot_fx.h | 2 +- lib_dec/lib_dec_fx.c | 2 +- 4 files changed, 6 insertions(+), 260 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 79a659eb0..de66f07f2 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1849,92 +1849,6 @@ static void decision_matrix_core_dec( return; } -/*-------------------------------------------------------------------* - * mdct_switching_dec() - * - * Set up MDCT core switching if indicated in the bitstream - *-------------------------------------------------------------------*/ - -void mdct_switching_dec_ivas_fx( - Decoder_State *st /* i/o: decoder state structure */ -) -{ - if ( !st->bfi ) - { - - if ( st->Opt_AMR_WB ) - { - return; - } - - - if ( st->total_brate == ACELP_13k20 || st->total_brate == ACELP_32k ) - { - st->mdct_sw_enable = MODE1; - } - else if ( ACELP_16k40 <= st->total_brate && st->total_brate <= ACELP_24k40 ) - { - st->mdct_sw_enable = MODE2; - } - - if ( st->codec_mode == MODE1 && st->mdct_sw_enable == MODE1 ) - { - /* Read ahead core signaling */ - int16_t next_bit_pos_save = st->next_bit_pos; - int16_t core_save = st->core; - int16_t bwidth_save = st->bwidth; - - decision_matrix_core_dec( st ); /* sets st->core */ - - if ( st->core == TCX_20_CORE ) - { - /* Trigger TCX */ - st->codec_mode = MODE2; - st->mdct_sw = MODE1; - } - else - { - /* Rewind bitstream */ - st->next_bit_pos = next_bit_pos_save; - if ( st->bfi ) - { - st->core = core_save; - st->bwidth = bwidth_save; - } - } - } - else if ( st->codec_mode == MODE2 && st->mdct_sw_enable == MODE2 ) - { - /* Read ahead core signaling */ - int16_t next_bit_pos_save = st->next_bit_pos; - int16_t core_save = st->core; - int16_t bwidth_save = st->bwidth; - - dec_prm_core( st ); /* sets st->core */ - - if ( st->core == HQ_CORE ) - { - /* Trigger HQ_CORE */ - st->codec_mode = MODE1; - st->mdct_sw = MODE2; - } - else - { - /* Rewind bitstream */ - st->next_bit_pos = next_bit_pos_save; - if ( st->bfi ) - { - st->core = core_save; - } - /* always reset bwidth, to not interfere with BER logic */ - st->bwidth = bwidth_save; - } - } - } - - return; -} - /*-------------------------------------------------------------------* * reset_elements() diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 141d1996e..17b7d0495 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -143,29 +143,6 @@ void pack_bit( return; } -/*-------------------------------------------------------------------* - * unpack_bit() - * - * unpack a bit from packed octet - *-------------------------------------------------------------------*/ -static Word16 unpack_bit( - UWord8 **pt, /* i/o: pointer to octet array from which bit will be read */ - UWord8 *mask /* i/o: mask to indicate the bit in the octet */ -) -{ - Word16 bit; - - bit = s_and( **pt, *mask ) != 0; - *mask = (UWord8) shr( *mask, 1 ); - move16(); - IF( *mask == 0 ) - { - *mask = 0x80; - move16(); - ( *pt )++; - } - return bit; -} /*-------------------------------------------------------------------* * rate2AMRWB_IOmode() @@ -945,154 +922,6 @@ return; } -static void decoder_selectCodec( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 total_brate, /* i : total bitrate */ - const Word16 bit0 ) -{ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - /* check if we are in AMR-WB IO mode */ - IF( EQ_32( total_brate, SID_1k75 ) || - EQ_32( total_brate, ACELP_6k60 ) || EQ_32( total_brate, ACELP_8k85 ) || EQ_32( total_brate, ACELP_12k65 ) || - EQ_32( total_brate, ACELP_14k25 ) || EQ_32( total_brate, ACELP_15k85 ) || EQ_32( total_brate, ACELP_18k25 ) || - EQ_32( total_brate, ACELP_19k85 ) || EQ_32( total_brate, ACELP_23k05 ) || EQ_32( total_brate, ACELP_23k85 ) ) - { - st->Opt_AMR_WB = 1; - move16(); - } - ELSE IF( total_brate != FRAME_NO_DATA ) - { - st->Opt_AMR_WB = 0; - move16(); - } - - /* select MODE1 or MODE2 */ - IF( st->Opt_AMR_WB ) - { - st->codec_mode = MODE1; - move16(); /**/ - } - ELSE - { - SWITCH( total_brate ) - { - case 0: - st->codec_mode = st->last_codec_mode; - move16(); - BREAK; - case 2400: - st->codec_mode = st->last_codec_mode; - move16(); - BREAK; - case 2800: - st->codec_mode = MODE1; - move16(); - BREAK; - case 7200: - st->codec_mode = MODE1; - move16(); - BREAK; - case 8000: - st->codec_mode = MODE1; - move16(); - BREAK; - case 9600: - st->codec_mode = MODE2; - move16(); - BREAK; - case 13200: - st->codec_mode = MODE1; - move16(); - BREAK; - case 16400: - st->codec_mode = MODE2; - move16(); - BREAK; - case 24400: - st->codec_mode = MODE2; - move16(); - BREAK; - case 32000: - st->codec_mode = MODE1; - move16(); - BREAK; - case 48000: - st->codec_mode = MODE2; - move16(); - BREAK; - case 64000: - st->codec_mode = MODE1; - move16(); - BREAK; - case 96000: - st->codec_mode = MODE2; - move16(); - BREAK; - case 128000: - st->codec_mode = MODE2; - move16(); - BREAK; - default: - /* validate that total_brate (derived from RTP packet or a file header) is one of the defined bit rates */ - st->codec_mode = st->last_codec_mode; - st->bfi = 1; - move16(); - move16(); - BREAK; - } - } - - IF( st->ini_frame == 0 ) - { - if ( EQ_16( st->codec_mode, -1 ) ) - { - st->codec_mode = MODE1; - move16(); - } - st->last_codec_mode = st->codec_mode; - move16(); - } - - /* set SID/CNG type */ - IF( EQ_32( total_brate, SID_2k40 ) ) - { - IF( EQ_16( bit0, G192_BIN0 ) ) - { - st->cng_type = LP_CNG; - move16(); - - /* force MODE1 when selecting LP_CNG */ - st->codec_mode = MODE1; - move16(); - } - ELSE - { - st->cng_type = FD_CNG; - move16(); - test(); - if ( EQ_16( st->last_codec_mode, MODE2 ) && EQ_32( st->last_total_brate, 13200 ) ) - { - st->codec_mode = MODE1; - move16(); - } - } - st->hTdCngDec->last_cng_type_fx = st->cng_type; /* CNG type switching at the first correctly received SID frame */ - move16(); - } - - - return; -} - - static void dec_prm_core( Decoder_State *st ) { Word16 n, frame_size_index, num_bits; @@ -1320,7 +1149,7 @@ static void decision_matrix_core_dec( * Set up MDCT core switching if indicated in the bit stream *-------------------------------------------------------------------*/ -static void mdct_switching_dec( +void mdct_switching_dec_fx( Decoder_State *st /* i/o: decoder state structure */ ) { @@ -1421,8 +1250,11 @@ static void mdct_switching_dec( move16(); } } + + return; } + /*-------------------------------------------------------------------* * BRATE2IDX_fx() * diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index e1d7a8be8..09158b339 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -11555,7 +11555,7 @@ Decoder_State **reset_elements( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); -void mdct_switching_dec_ivas_fx( +void mdct_switching_dec_fx( Decoder_State *st /* i/o: decoder state structure */ ); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 56ffe3924..413585447 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -3396,7 +3396,7 @@ static ivas_error evs_dec_main_fx( move32(); hCoreCoder[0]->output_frame_fx = extract_l( Mult_32_16( hCoreCoder[0]->output_Fs, 0x0290 /*Q0*/ ) ); // Q0 move16(); - mdct_switching_dec_ivas_fx( hCoreCoder[0] ); + mdct_switching_dec_fx( hCoreCoder[0] ); FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { -- GitLab From 86c756775ac0e308876fd2744b4c53b11ad9f62c Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 11:49:13 +0100 Subject: [PATCH 0456/1221] harmonize handle 'hTdCngDec' --- lib_com/prot_fx.h | 4 - lib_dec/cng_dec_fx.c | 225 ++++++++++--------------- lib_dec/core_switching_dec_fx.c | 13 +- lib_dec/evs_dec_fx.c | 2 +- lib_dec/hq_hr_dec_fx.c | 4 +- lib_dec/hq_lr_dec_fx.c | 2 +- lib_dec/init_dec_fx.c | 25 +-- lib_dec/ivas_core_dec_fx.c | 4 +- lib_dec/ivas_sce_dec_fx.c | 2 +- lib_dec/ivas_stereo_switching_dec_fx.c | 6 +- lib_dec/stat_dec.h | 140 +++++---------- lib_dec/swb_bwe_dec_fx.c | 103 +++++------ lib_dec/swb_bwe_dec_hr_fx.c | 2 +- lib_dec/swb_tbe_dec_fx.c | 16 +- 14 files changed, 210 insertions(+), 338 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 09158b339..b695f1978 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6316,10 +6316,6 @@ void td_cng_dec_init_fx( DEC_CORE_HANDLE st /* i/o: decoder state structure */ ); -void td_cng_dec_init_ivas_fx( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - // wavadjust_fec_dec_fx.c void set_state( Word16 *state, diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index ab349773e..6fb8e28ae 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -1377,9 +1377,8 @@ void swb_CNG_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz Qsyn*/ Word16 *shb_synth_fx, /* o : high-band CNG synthesis Qx*/ - const Word16 sid_bw /* i : 0-NB/WB, 1-SWB SID Q0*/ - , - const Word16 Qsyn /* i : Q value of ACELP core synthesis */ + const Word16 sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0*/ + const Word16 Qsyn /* i : Q value of ACELP core synthesis */ ) { test(); @@ -1393,18 +1392,18 @@ void swb_CNG_dec_fx( } st_fx->last_vad_fx = 0; move16(); - st_fx->hTdCngDec->burst_cnt = 0; + st_fx->hTdCngDec->burst_cnt_fx = 0; move16(); } ELSE { st_fx->last_vad_fx = 1; move16(); - st_fx->hTdCngDec->burst_cnt = add( st_fx->hTdCngDec->burst_cnt, 1 ); + st_fx->hTdCngDec->burst_cnt_fx = add( st_fx->hTdCngDec->burst_cnt_fx, 1 ); move16(); - if ( GT_16( st_fx->hTdCngDec->burst_cnt, 10 ) ) + if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) ) { - st_fx->hTdCngDec->burst_cnt = 0; + st_fx->hTdCngDec->burst_cnt_fx = 0; move16(); } } @@ -1431,18 +1430,18 @@ void swb_CNG_dec_ivas_fx( } st_fx->last_vad_fx = 0; move16(); - st_fx->hTdCngDec->burst_cnt = 0; + st_fx->hTdCngDec->burst_cnt_fx = 0; move16(); } ELSE { st_fx->last_vad_fx = 1; move16(); - st_fx->hTdCngDec->burst_cnt = add_sat( st_fx->hTdCngDec->burst_cnt, 1 ); // saturation reached? + st_fx->hTdCngDec->burst_cnt_fx = add_sat( st_fx->hTdCngDec->burst_cnt_fx, 1 ); // saturation reached? move16(); - if ( GT_16( st_fx->hTdCngDec->burst_cnt, 10 ) ) + if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) ) { - st_fx->hTdCngDec->burst_cnt = 0; + st_fx->hTdCngDec->burst_cnt_fx = 0; move16(); } } @@ -1466,6 +1465,7 @@ static void shb_CNG_decod_fx( { Word16 i; Word16 idx_ener_fx; + TD_CNG_DEC_HANDLE hTdCngDec; Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1]; Word16 shb_lspCNG_fx[LPC_SHB_ORDER]; Word16 excTmp_fx[L_FRAME16k]; @@ -1489,7 +1489,9 @@ static void shb_CNG_decod_fx( move16(); Word16 q; TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + hTdCngDec = st_fx->hTdCngDec; IF( st_fx->bfi == 0 ) { @@ -1506,8 +1508,8 @@ static void shb_CNG_decod_fx( IF( st_fx->element_mode == EVS_MONO ) { /* de-quantization of SHB CNG parameters */ - L_tmp = L_mult( idx_ener_fx, 27400 ); /*Q14 */ - st_fx->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 295924 ), 6 ) ); /*Q8 */ + L_tmp = L_mult( idx_ener_fx, 27400 ); /*Q14 */ + hTdCngDec->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 295924 ), 6 ) ); /*Q8 */ move16(); } ELSE @@ -1519,21 +1521,21 @@ static void shb_CNG_decod_fx( /* SHB spectrum estimation */ - interp_fx = s_min( st_fx->shb_dtx_count_fx, 32 ); + interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 ); interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/ FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - tmp2 = mult( interp_fx, st_fx->lsp_shb_prev_fx[i] ); /*Q14*/ - tmp = mult( sub( 32767, interp_fx ), st_fx->lsp_shb_prev_prev_fx[i] ); /*Q14*/ + tmp2 = mult( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] ); /*Q14*/ + tmp = mult( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ); /*Q14*/ shb_lspCNG_fx[i] = add( tmp2, tmp ); move16(); /*Q14*/ } IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - if ( LT_16( st_fx->shb_dtx_count_fx, 1000 ) ) + if ( LT_16( hTdCngDec->shb_dtx_count_fx, 1000 ) ) { - st_fx->shb_dtx_count_fx = add( st_fx->shb_dtx_count_fx, 1 ); + hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 ); move16(); } } @@ -1555,10 +1557,10 @@ static void shb_CNG_decod_fx( wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */ if ( !st_fx->first_CNG ) { - st_fx->wb_cng_ener_fx = wb_ener16_fx; + hTdCngDec->wb_cng_ener_fx = wb_ener16_fx; move16(); /*Q8 */ } - if ( GT_16( abs_s( sub( wb_ener16_fx, st_fx->wb_cng_ener_fx ) ), 3072 ) ) + if ( GT_16( abs_s( sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx ) ), 3072 ) ) { allow_cn_step_fx = 1; move16(); @@ -1566,52 +1568,52 @@ static void shb_CNG_decod_fx( IF( EQ_16( allow_cn_step_fx, 1 ) ) { - st_fx->wb_cng_ener_fx = wb_ener16_fx; + hTdCngDec->wb_cng_ener_fx = wb_ener16_fx; move16(); /*Q8 */ } ELSE { - tmp = sub( wb_ener16_fx, st_fx->wb_cng_ener_fx ); /*Q8 */ - tmp = mult_r( tmp, 29491 ); /*Q8 */ - st_fx->wb_cng_ener_fx = add( st_fx->wb_cng_ener_fx, tmp ); /*Q8 */ + tmp = sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx ); /*Q8 */ + tmp = mult_r( tmp, 29491 ); /*Q8 */ + hTdCngDec->wb_cng_ener_fx = add( hTdCngDec->wb_cng_ener_fx, tmp ); /*Q8 */ move16(); } test(); test(); IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && ( st_fx->bfi == 0 ) ) { - st_fx->last_wb_cng_ener_fx = st_fx->wb_cng_ener_fx; + hTdCngDec->last_wb_cng_ener_fx = hTdCngDec->wb_cng_ener_fx; move16(); if ( !st_fx->first_CNG ) { - st_fx->shb_cng_ener_fx = st_fx->last_shb_cng_ener_fx; + hTdCngDec->shb_cng_ener_fx = hTdCngDec->last_shb_cng_ener_fx; move16(); } } - gain_fx = sub( st_fx->wb_cng_ener_fx, st_fx->last_wb_cng_ener_fx ); /* Q8 */ + gain_fx = sub( hTdCngDec->wb_cng_ener_fx, hTdCngDec->last_wb_cng_ener_fx ); /* Q8 */ if ( GT_16( gain_fx, 15 ) ) { gain_fx = 15; move16(); } - step_fx = sub( add( gain_fx, st_fx->last_shb_cng_ener_fx ), st_fx->shb_cng_ener_fx ); /*Q8 */ + step_fx = sub( add( gain_fx, hTdCngDec->last_shb_cng_ener_fx ), hTdCngDec->shb_cng_ener_fx ); /*Q8 */ test(); IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st_fx->last_core_brate, SID_2k40 ) ) { - st_fx->shb_cng_ener_fx = add( st_fx->shb_cng_ener_fx, step_fx ); /* Q8 */ + hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, step_fx ); /* Q8 */ move16(); } ELSE { - st_fx->shb_cng_ener_fx = add( st_fx->shb_cng_ener_fx, mult( 8192, step_fx ) ); /*Q8 */ + hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, mult( 8192, step_fx ) ); /*Q8 */ move16(); } /* generate white noise excitation */ FOR( i = 0; i < L_FRAME16k; i++ ) { - excTmp_fx[i] = shr_r( Random( &st_fx->swb_cng_seed ), 8 ); + excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 ); move16(); /*Q-8*/ } @@ -1632,23 +1634,23 @@ static void shb_CNG_decod_fx( ener_excSHB_fx = round_fx( L_tmp ); /*Qq */ IF( EQ_16( st_fx->last_vad_fx, 1 ) ) { - st_fx->trans_cnt_fx = 0; + hTdCngDec->trans_cnt_fx = 0; move16(); test(); - IF( GT_16( st_fx->hTdCngDec->burst_cnt, 3 ) && NE_16( st_fx->last_core, HQ_CORE ) ) + IF( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st_fx->last_core, HQ_CORE ) ) { - st_fx->trans_cnt_fx = 5; + hTdCngDec->trans_cnt_fx = 5; move16(); } } - ener_fx = st_fx->shb_cng_ener_fx; + ener_fx = hTdCngDec->shb_cng_ener_fx; move16(); /*Q8 */ - IF( st_fx->trans_cnt_fx > 0 ) + IF( hTdCngDec->trans_cnt_fx > 0 ) { - i = extract_l( L_mult0( st_fx->trans_cnt_fx, 17 ) ); /*Q0 */ - ener_fx = add_sat( st_fx->shb_cng_ener_fx, mult( sin_table256_fx[i], sub_sat( st_fx->last_shb_ener_fx, st_fx->shb_cng_ener_fx ) ) ); /*Q8 */ - st_fx->trans_cnt_fx = sub( st_fx->trans_cnt_fx, 1 ); + i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) ); /*Q0 */ + ener_fx = add_sat( hTdCngDec->shb_cng_ener_fx, mult( sin_table256_fx[i], sub_sat( hTdCngDec->last_shb_ener_fx, hTdCngDec->shb_cng_ener_fx ) ) ); /*Q8 */ + hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 ); move16(); } @@ -1712,7 +1714,7 @@ static void shb_CNG_decod_fx( IF( EQ_32( st_fx->output_Fs, 48000 ) ) { - interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, st_fx->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); + interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); } ResetSHBbuffer_Dec_fx( st_fx ); @@ -1729,6 +1731,7 @@ static void shb_CNG_decod_ivas_fx( { Word16 i; Word16 idx_ener; + TD_CNG_DEC_HANDLE hTdCngDec; Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1]; Word16 shb_lspCNG_fx[LPC_SHB_ORDER]; Word16 excTmp_fx[L_FRAME16k]; @@ -1750,7 +1753,9 @@ static void shb_CNG_decod_ivas_fx( Word16 allow_cn_step_fx; Word16 q; TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + hTdCngDec = st->hTdCngDec; allow_cn_step_fx = 0; move16(); @@ -1770,37 +1775,37 @@ static void shb_CNG_decod_ivas_fx( /* de-quantization of SHB CNG parameters */ IF( st->element_mode == EVS_MONO ) { - st->hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 6850 ), 36991 ); // Q11 + hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 6850 ), 36991 ); // Q11 move32(); } ELSE { - st->hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 8807 ), 36991 ); // Q11 + hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 8807 ), 36991 ); // Q11 move32(); } } } /* SHB spectrum estimation */ - interp_fx = s_min( st->hTdCngDec->shb_dtx_count, 32 ); + interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 ); interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/ FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - shb_lspCNG_fx[i] = add( mult_r( interp_fx, st->hTdCngDec->lsp_shb_prev_fx[i] ), mult_r( sub( 32767, interp_fx ), st->hTdCngDec->lsp_shb_prev_prev_fx[i] ) ); // Q14 + shb_lspCNG_fx[i] = add( mult_r( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] ), mult_r( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ) ); // Q14 move16(); } - IF( LE_16( st->hTdCngDec->shb_dtx_count, 1000 ) ) + IF( LE_16( hTdCngDec->shb_dtx_count_fx, 1000 ) ) { - st->hTdCngDec->shb_dtx_count = add( st->hTdCngDec->shb_dtx_count, 1 ); + hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 ); move16(); } E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/ E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER ); - Copy_Scale_sig( shb_lpcCNG_fx, st->hTdCngDec->shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), -1 ) ); /* Q15 */ + Copy_Scale_sig( shb_lpcCNG_fx, hTdCngDec->shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), -1 ) ); /* Q15 */ Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */ @@ -1821,10 +1826,10 @@ static void shb_CNG_decod_ivas_fx( Word32 wb_ener32_fx = L_shl( wb_ener16_fx, 3 ); /*wb_ener_fx in Q11 */ if ( EQ_16( st->first_CNG, 0 ) ) { - st->hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx; + hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx; move32(); /*Q11 */ } - if ( GT_32( L_abs( L_sub( wb_ener32_fx, st->hTdCngDec->wb_cng_ener_fx_32 ) ), 24576 ) ) /* 12.0f in Q11 */ + if ( GT_32( L_abs( L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 ) ), 24576 ) ) /* 12.0f in Q11 */ { allow_cn_step_fx = 1; move16(); @@ -1832,52 +1837,52 @@ static void shb_CNG_decod_ivas_fx( IF( EQ_16( allow_cn_step_fx, 1 ) ) { - st->hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx; + hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx; move32(); /*Q11 */ } ELSE { - tmp = L_sub( wb_ener32_fx, st->hTdCngDec->wb_cng_ener_fx_32 ); /*Q11 */ - tmp = Mpy_32_16_1( tmp, 29491 ); /*Q11 */ - st->hTdCngDec->wb_cng_ener_fx_32 = L_add( st->hTdCngDec->wb_cng_ener_fx_32, tmp ); /*Q11 */ + tmp = L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 ); /*Q11 */ + tmp = Mpy_32_16_1( tmp, 29491 ); /*Q11 */ + hTdCngDec->wb_cng_ener_fx_32 = L_add( hTdCngDec->wb_cng_ener_fx_32, tmp ); /*Q11 */ move32(); } test(); test(); IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && EQ_16( st->bfi, 0 ) ) { - st->hTdCngDec->last_wb_cng_ener_fx_32 = st->hTdCngDec->wb_cng_ener_fx_32; /* Q11 */ + hTdCngDec->last_wb_cng_ener_fx_32 = hTdCngDec->wb_cng_ener_fx_32; /* Q11 */ move32(); if ( !st->first_CNG ) { - st->hTdCngDec->shb_cng_ener_fx_32 = st->hTdCngDec->last_shb_cng_ener_fx_32; /* Q11 */ + hTdCngDec->shb_cng_ener_fx_32 = hTdCngDec->last_shb_cng_ener_fx_32; /* Q11 */ move32(); } } - gain_fx = L_sub( st->hTdCngDec->wb_cng_ener_fx_32, st->hTdCngDec->last_wb_cng_ener_fx_32 ); /*Q11 */ + gain_fx = L_sub( hTdCngDec->wb_cng_ener_fx_32, hTdCngDec->last_wb_cng_ener_fx_32 ); /*Q11 */ if ( GT_32( gain_fx, 30720 ) ) { gain_fx = 30720; move32(); } - step_fx = L_sub( L_add( gain_fx, st->hTdCngDec->last_shb_cng_ener_fx_32 ), st->hTdCngDec->shb_cng_ener_fx_32 ); /*Q11 */ + step_fx = L_sub( L_add( gain_fx, hTdCngDec->last_shb_cng_ener_fx_32 ), hTdCngDec->shb_cng_ener_fx_32 ); /*Q11 */ test(); IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st->last_core_brate, SID_2k40 ) ) { - st->hTdCngDec->shb_cng_ener_fx_32 = L_add( st->hTdCngDec->shb_cng_ener_fx_32, step_fx ); /* Q11 */ + hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, step_fx ); /* Q11 */ move32(); } ELSE { - st->hTdCngDec->shb_cng_ener_fx_32 = L_add( st->hTdCngDec->shb_cng_ener_fx_32, L_shr( step_fx, 2 ) ); /*Q11 */ + hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, L_shr( step_fx, 2 ) ); /*Q11 */ move32(); } /* generate white noise excitation */ FOR( i = 0; i < L_FRAME16k; i++ ) { - excTmp_fx[i] = shr_r( Random( &st->hTdCngDec->swb_cng_seed ), 8 ); + excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 ); move16(); /*Q-8*/ } @@ -1896,29 +1901,26 @@ static void shb_CNG_decod_ivas_fx( L_tmp = L_shl( L_tmp, q ); q = sub( q, 32 ); ener_excSHB_fx = round_fx( L_tmp ); /*Qq */ -#ifdef MSAN_FIX + IF( EQ_16( st->last_vad_fx, 1 ) ) -#else - IF( EQ_16( st->last_vad, 1 ) ) -#endif { - st->hTdCngDec->trans_cnt = 0; + hTdCngDec->trans_cnt_fx = 0; move16(); test(); - if ( GT_16( st->hTdCngDec->burst_cnt, 3 ) && NE_16( st->last_core, HQ_CORE ) ) + if ( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st->last_core, HQ_CORE ) ) { - st->hTdCngDec->trans_cnt = 5; + hTdCngDec->trans_cnt_fx = 5; move16(); } } - ener_fx = st->hTdCngDec->shb_cng_ener_fx_32; + ener_fx = hTdCngDec->shb_cng_ener_fx_32; move32(); /*Q11 */ - IF( GT_16( st->hTdCngDec->trans_cnt, 0 ) ) + IF( GT_16( st->hTdCngDec->trans_cnt_fx, 0 ) ) { - i = extract_l( L_mult0( st->hTdCngDec->trans_cnt, 17 ) ); /*Q0 */ - ener_fx = L_add( st->hTdCngDec->shb_cng_ener_fx_32, Mpy_32_16_1( L_sub( st->hTdCngDec->last_shb_ener_fx, st->hTdCngDec->shb_cng_ener_fx_32 ), sin_table256_fx[i] ) ); /*Q11 */ - st->hTdCngDec->trans_cnt = sub( st->hTdCngDec->trans_cnt, 1 ); + i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) ); /*Q0 */ + ener_fx = L_add( hTdCngDec->shb_cng_ener_fx_32, Mpy_32_16_1( L_sub( hTdCngDec->last_shb_ener_fx_32, hTdCngDec->shb_cng_ener_fx_32 ), sin_table256_fx[i] ) ); /*Q11 */ + hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 ); move16(); } @@ -1960,7 +1962,7 @@ static void shb_CNG_decod_ivas_fx( L_tmp = L_deposit_h( tmp_16 ); /*Q31 */ tmp_16 = sub( add( 5, exp ), add( q, exp1 ) ); L_gain_fx = Isqrt_lc( L_tmp, &tmp_16 ); /*Q31-Qtmp */ - st->hTdCngDec->shb_cng_gain_fx_32 = ener_fx; + hTdCngDec->shb_cng_gain_fx_32 = ener_fx; move32(); FOR( i = 0; i < L_FRAME16k; i++ ) { @@ -1988,7 +1990,7 @@ static void shb_CNG_decod_ivas_fx( IF( EQ_32( st->output_Fs, 48000 ) ) { - interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, st->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); + interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); } Scale_sig( shb_synth_fx, L_FRAME48k, -3 ); /* Qx - 3 */ @@ -2005,62 +2007,6 @@ static void shb_CNG_decod_ivas_fx( void td_cng_dec_init_fx( DEC_CORE_HANDLE st /* i/o: decoder state structure */ ) -{ - TD_CNG_DEC_HANDLE hTdCngDec; - - hTdCngDec = st->hTdCngDec; - - hTdCngDec->cng_seed = RANDOM_INITSEED; - move16(); - hTdCngDec->cng_ener_seed = RANDOM_INITSEED; - move16(); - hTdCngDec->cng_ener_seed1 = RANDOM_INITSEED; - move16(); - hTdCngDec->old_enr_index = -1; - move16(); - hTdCngDec->Enew_fx = L_deposit_l( 0 ); /* Q6*/ - move16(); - hTdCngDec->last_allow_cn_step = 0; - move16(); - hTdCngDec->ho_hist_ptr = -1; - move16(); - hTdCngDec->ho_sid_bw = L_deposit_l( 0 ); - move16(); - set16_fx( hTdCngDec->ho_lsp_hist_fx, 0, HO_HIST_SIZE * M ); - set32_fx( hTdCngDec->ho_ener_hist_fx, 0, HO_HIST_SIZE ); - set32_fx( hTdCngDec->ho_env_hist_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG ); - hTdCngDec->ho_hist_size = 0; - move16(); - hTdCngDec->act_cnt = 0; - move16(); - hTdCngDec->ho_circ_ptr = -1; - move16(); - set16_fx( hTdCngDec->ho_lsp_circ_fx, 0, HO_HIST_SIZE * M ); - set32_fx( hTdCngDec->ho_ener_circ_fx, 0, HO_HIST_SIZE ); - set32_fx( hTdCngDec->ho_env_circ_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG ); - hTdCngDec->ho_circ_size = 0; - move16(); - - set16_fx( hTdCngDec->ho_16k_lsp, 0, HO_HIST_SIZE ); - hTdCngDec->act_cnt2 = 0; - move16(); - hTdCngDec->num_ho = 0; - move16(); - hTdCngDec->last_cng_type_fx = -1; - move16(); - set32_fx( hTdCngDec->lp_env_fx, 0, NUM_ENV_CNG ); - set16_fx( hTdCngDec->exc_mem_fx, 0, 24 ); - set16_fx( hTdCngDec->exc_mem1_fx, 0, 30 ); - set32_fx( hTdCngDec->old_env_fx, 0, NUM_ENV_CNG ); - hTdCngDec->burst_cnt = 0; - move16(); - - return; -} - -void td_cng_dec_init_ivas_fx( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -) { Word16 i; TD_CNG_DEC_HANDLE hTdCngDec; @@ -2080,6 +2026,8 @@ void td_cng_dec_init_ivas_fx( Copy( st->lsp_old_fx, st->lspCNG_fx, M ); // Q(15) hTdCngDec->last_allow_cn_step = 0; move16(); + hTdCngDec->shb_cng_ener_fx = -1541; // Q8 + move16(); hTdCngDec->shb_cng_ener_fx_32 = -12329; // -6.02 in Q(11) move32(); IF( st->element_mode != EVS_MONO ) @@ -2091,10 +2039,16 @@ void td_cng_dec_init_ivas_fx( move32(); } + hTdCngDec->wb_cng_ener_fx = -1541; // Q8 + move16(); hTdCngDec->wb_cng_ener_fx_32 = -12329; // Q(11) move32(); + hTdCngDec->last_wb_cng_ener_fx = -1541; // Q8 + move16(); hTdCngDec->last_wb_cng_ener_fx_32 = -12329; // Q(11) move32(); + hTdCngDec->last_shb_cng_ener_fx = -1541; // Q8 + move16(); hTdCngDec->last_shb_cng_ener_fx_32 = -12329; // Q(11) move32(); hTdCngDec->swb_cng_seed = RANDOM_INITSEED; @@ -2146,17 +2100,18 @@ void td_cng_dec_init_ivas_fx( move16(); } - hTdCngDec->shb_dtx_count = 0; + hTdCngDec->shb_dtx_count_fx = 0; move16(); - hTdCngDec->trans_cnt = 0; + hTdCngDec->trans_cnt_fx = 0; move16(); - hTdCngDec->burst_cnt = 0; + hTdCngDec->burst_cnt_fx = 0; move16(); - hTdCngDec->last_shb_ener_fx = 2; // 0.001 in Q11 + hTdCngDec->last_shb_ener_fx = 0; // Q8 + move16(); + hTdCngDec->last_shb_ener_fx_32 = 2; // 0.001 in Q11 move32(); - set16_fx( hTdCngDec->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); return; diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 127e28d97..005345fba 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -277,7 +277,7 @@ void bw_switching_pre_proc_fx( { st_fx->prev_ener_shb_fx = 0; move16(); - set16_fx( st_fx->prev_SWB_fenv_fx, 0, SWB_FENV ); + set16_fx( st_fx->hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); } ELSE IF( ( ( st_fx->core == ACELP_CORE && ( EQ_16( st_fx->last_core, HQ_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) || EQ_16( st_fx->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st_fx->core, st_fx->last_core ) && NE_16( st_fx->extl, st_fx->last_extl ) ) ) && GE_16( st_fx->last_bwidth, SWB ) ) { @@ -1230,9 +1230,9 @@ ivas_error core_switching_post_dec_fx( test(); test(); test(); - IF( EQ_32( st_fx->output_Fs, 48000 ) && ( ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) && ( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) ) ) + IF( st_fx->hTdCngDec != NULL && EQ_32( st_fx->output_Fs, 48000 ) && ( ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) && ( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) ) ) { - set16_fx( st_fx->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); + set16_fx( st_fx->hTdCngDec->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); } /* reset FB TBE buffers */ @@ -1903,9 +1903,9 @@ ivas_error core_switching_post_dec_ivas_fx( test(); test(); test(); - IF( EQ_32( st_fx->output_Fs, 48000 ) && ( ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) && ( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) ) ) + IF( st_fx->hTdCngDec != NULL && EQ_32( st_fx->output_Fs, 48000 ) && ( ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) && ( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) ) ) { - set16_fx( st_fx->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); + set16_fx( st_fx->hTdCngDec->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); } return error; @@ -3146,12 +3146,11 @@ void ivas_bw_switching_pre_proc_fx( test(); IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) { - st->prev_ener_shb_fx = 0; move16(); IF( st->hBWE_FD != NULL ) { - set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); + set16_fx( st->hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); } } ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 1ad2c50c7..8d72233a5 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -683,7 +683,7 @@ ivas_error evs_dec_fx( fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( sub( 30, shl( hb_synth_fx_exp, 1 ) ), exp ); L_tmp = Mpy_32_16( exp, fra, LG10 ); - st_fx->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, 10 ) ); /*Q8*/ + st_fx->hTdCngDec->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, 10 ) ); /*Q8*/ } } hBWE_TD->prev_hb_synth_fx_exp = hb_synth_fx_exp; diff --git a/lib_dec/hq_hr_dec_fx.c b/lib_dec/hq_hr_dec_fx.c index f96b8f597..d72f0ec45 100644 --- a/lib_dec/hq_hr_dec_fx.c +++ b/lib_dec/hq_hr_dec_fx.c @@ -61,7 +61,7 @@ void ivas_hq_pred_hb_bws_fx( IF( GE_16( st_fx->last_inner_frame, L_FRAME32k ) && st_fx->hBWE_FD != NULL ) { - set16_fx( st_fx->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV ); + set16_fx( st_fx->hBWE_FD->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV ); } return; @@ -125,7 +125,7 @@ void hq_pred_hb_bws_fx( IF( GE_16( st_fx->last_inner_frame, L_FRAME32k ) ) { - set16_fx( st_fx->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV ); + set16_fx( st_fx->hBWE_FD->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV ); } return; diff --git a/lib_dec/hq_lr_dec_fx.c b/lib_dec/hq_lr_dec_fx.c index 61c1d0938..7d5d6a34b 100644 --- a/lib_dec/hq_lr_dec_fx.c +++ b/lib_dec/hq_lr_dec_fx.c @@ -893,7 +893,7 @@ void hq_lr_dec_fx( test(); IF( GE_16( st_fx->last_inner_frame, L_FRAME32k ) && st_fx->hBWE_FD != NULL ) { - set16_fx( st_fx->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV ); + set16_fx( st_fx->hBWE_FD->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV ); } updat_prev_frm_fx( L_y2, L_yout, L_bwe_br, length_fx, inner_frame, bands_fx, st_fx->bwidth, *is_transient_fx, hqswb_clas_fx, &hHQ_core->prev_hqswb_clas, diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index accfdc083..3bb5894f3 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -361,16 +361,6 @@ ivas_error init_decoder_fx( st_fx->first_CNG = 0; move16(); Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); // Q15 - st_fx->shb_cng_ener_fx = -1541; // Q8 - move16(); - st_fx->wb_cng_ener_fx = -1541; // Q8 - move16(); - st_fx->last_wb_cng_ener_fx = -1541; // Q8 - move16(); - st_fx->last_shb_cng_ener_fx = -1541; // Q8 - move16(); - st_fx->swb_cng_seed = RANDOM_INITSEED; - move16(); st_fx->CNG_mode = -1; move16(); @@ -379,22 +369,9 @@ ivas_error init_decoder_fx( st_fx->last_CNG_L_frame = L_FRAME; move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - st_fx->lsp_shb_prev_fx[i] = lsp_shb_prev_tbl_fx[i]; // Q15 - move16(); - st_fx->lsp_shb_prev_prev_fx[i] = st_fx->lsp_shb_prev_fx[i]; // Q15 - move16(); - } - st_fx->shb_dtx_count_fx = 0; - move16(); st_fx->last_vad_fx = 0; move16(); - st_fx->trans_cnt_fx = 0; - move16(); - st_fx->last_shb_ener_fx = 0; // Q8 - move16(); /* HF (6-7kHz) BWE */ move16(); @@ -1220,7 +1197,7 @@ ivas_error init_decoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init_ivas_fx( st_fx ); + td_cng_dec_init_fx( st_fx ); } ELSE { diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index d85cfbf94..8344b0447 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1451,9 +1451,9 @@ ivas_error ivas_core_dec_fx( L_tmp = BASOP_Util_Add_Mant32Exp( fra, 6, L_tmp, exp, &exp ); L_tmp = Mpy_32_16_1( L_tmp, 24660 ); exp = add( exp, 2 ); - st->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 7 ) ) ); /*Q8*/ + st->hTdCngDec->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 7 ) ) ); /*Q8*/ move16(); - st->hTdCngDec->last_shb_ener_fx = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ + st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } } diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index cbe9e4da8..6e1893015 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -454,7 +454,7 @@ ivas_error create_sce_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init_ivas_fx( st ); + td_cng_dec_init_fx( st ); } /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index ed73fa75f..d524ecd7a 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -501,7 +501,7 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init_ivas_fx( st ); + td_cng_dec_init_fx( st ); } } @@ -643,7 +643,7 @@ ivas_error stereo_memory_dec_fx( } fd_bwe_dec_init_fx( st->hBWE_FD ); - set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); + set16_fx( st->hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); st->last_wb_bwe_ener_fx = 0; move16(); st->prev_fb_ener_adjust_fx = 0; @@ -890,7 +890,7 @@ ivas_error stereo_memory_dec_fx( } fd_bwe_dec_init_fx( st->hBWE_FD ); - set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); + set16_fx( st->hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); st->last_wb_bwe_ener_fx = 0; move16(); st->prev_fb_ener_adjust_fx = 0; diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 0e708ba36..639918f24 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -665,33 +665,34 @@ typedef struct td_cng_dec_structure Word16 act_cnt2; /* DTX/CNG - counter of active frames for CNG_mode switching */ - // Word16 act_cnt2; /* DTX/CNG - counter of active frames for CNG_mode switching */ Word32 old_env_fx[20]; Word32 lp_env_fx[20]; Word16 exc_mem_fx[24]; Word16 exc_mem1_fx[30]; - Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1]; /* Assumed in Q12 */ - Word16 shb_cng_gain_fx; /* Assumed in Q8 */ - Word16 swb_cng_seed; - Word16 shb_dtx_count; - Word16 trans_cnt; Word16 interpol_3_2_cng_dec_fx[INTERP_3_2_MEM_LEN]; - Word32 shb_cng_ener_fx_32; // Q(11) - Word32 shb_cng_gain_fx_32; // Q(11) - Word32 wb_cng_ener_fx_32; // Q(11) - Word32 last_wb_cng_ener_fx_32; // Q(11) - Word32 last_shb_cng_ener_fx_32; // Q(11) + /* SWB DTX/CNG parameters */ + Word16 shb_cng_ener_fx; + Word32 shb_cng_ener_fx_32; // Q(11) + Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1]; /* Assumed in Q12 */ + Word16 shb_cng_gain_fx; /* Assumed in Q8 */ + Word32 shb_cng_gain_fx_32; // Q(11) + Word16 wb_cng_ener_fx; + Word32 wb_cng_ener_fx_32; // Q(11) + Word16 last_wb_cng_ener_fx; + Word32 last_wb_cng_ener_fx_32; // Q(11) + Word16 last_shb_cng_ener_fx; + Word32 last_shb_cng_ener_fx_32; // Q(11) + Word16 swb_cng_seed; Word16 lsp_shb_prev_fx[LPC_SHB_ORDER]; // Q(14) Word16 lsp_shb_prev_prev_fx[LPC_SHB_ORDER]; // Q(14) - - Word16 burst_cnt; - Word32 last_shb_ener_fx; // Q(11) - - Word16 last_cng_type_fx; /* DTX/CNG - flag indicating last frame LP or CLDFB based SID/CNG */ - + Word16 shb_dtx_count_fx; + Word16 trans_cnt_fx; + Word16 burst_cnt_fx; + Word16 last_shb_ener_fx; + Word32 last_shb_ener_fx_32; // Q(11) } TD_CNG_DEC_DATA, *TD_CNG_DEC_HANDLE; @@ -1113,42 +1114,26 @@ typedef struct td_bwe_dec_structure typedef struct fd_bwe_dec_structure { - Word16 old_wtda_wb_fx_exp; - Word16 L_old_wtda_swb_fx[L_FRAME48k]; Word32 L_old_wtda_swb_fx32[L_FRAME48k]; - Word16 old_wtda_swb_fx_exp; - Word16 old_syn_12k8_16k_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; /*Q_syn2-1*/ - Word16 mem_deemph_old_syn_fx; - Word16 prev_mode; - - + Word16 prev_SWB_fenv_fx[SWB_FENV]; Word16 prev_Energy_fx; - Word32 prev_Energy_wb_fx; - Word16 prev_L_swb_norm; - Word16 Seed; - Word16 memExp1; - Word16 prev_frica_flag; - Word16 mem_imdct_fx[L_FRAME48k]; - Word16 mem_imdct_exp_fx; - Word16 prev_td_energy_fx; - Word16 prev_weight_fx; - Word16 prev_flag; - + //float last_wb_bwe_ener; + //float prev_fb_ener_adjust; } FD_BWE_DEC_DATA, *FD_BWE_DEC_HANDLE; @@ -1159,22 +1144,13 @@ typedef struct fd_bwe_dec_structure typedef struct hr_swb_bwe_dec_structure { - - Word16 bwe_highrate_seed; Word16 bwe_highrate_seed_fx; - Word16 t_audio_prev_fx[2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_START_FREQ_COEF]; - Word16 t_audio_prev_fx_exp[NUM_TIME_SWITCHING_BLOCKS]; - - Word16 old_is_transient_hr_bwe; Word16 old_is_transient_hr_bwe_fx; - Word32 L_mem_EnergyLT_fx; - Word16 mem_EnergyLT_fx_exp; - } HR_BWE_DEC_DATA, *HR_BWE_DEC_HANDLE; @@ -1202,45 +1178,26 @@ typedef struct amrwb_io_dec_structure { Word16 past_qua_en_fx[GAIN_PRED_ORDER]; /* gain quantization memory (used also in AMR-WB IO mode) */ - Word16 prev_r_fx; /* HF BWE - previous sub-frame gain */ - - Word16 fmerit_w_sm_fx; /* HF BWE - fmerit parameter memory */ - - Word16 frame_count; /* HF BWE - frame count */ - Word16 frame_count_fx; /* HF BWE - frame count */ - Word16 ne_min_fx; /* HF BWE - minimum Noise gate - short-term energy */ - - Word16 fmerit_m_sm_fx; /* HF BWE - memory of fmerit_m param */ - + Word16 prev_r_fx; /* HF BWE - previous sub-frame gain */ + Word16 fmerit_w_sm_fx; /* HF BWE - fmerit parameter memory */ + Word16 frame_count_fx; /* HF BWE - frame count */ + Word16 ne_min_fx; /* HF BWE - minimum Noise gate - short-term energy */ + Word16 fmerit_m_sm_fx; /* HF BWE - memory of fmerit_m param */ Word16 voice_fac_amr_wb_hf; /* HF BWE - voice factor */ - - Word16 unvoicing_fx; /* HF BWE - unvoiced parameter */ - - Word16 unvoicing_sm_fx; /* HF BWE - smoothed unvoiced parameter */ - - Word16 unvoicing_flag; /* HF BWE - unvoiced flag */ - Word16 unvoicing_flag_fx; /* HF BWE - unvoiced flag */ - - Word16 voicing_flag; /* HF BWE - voiced flag */ - Word16 voicing_flag_fx; /* HF BWE - voiced flag */ - - Word16 start_band_old; /* HF BWE - previous start point for copying frequency band */ - Word16 start_band_old_fx; /* HF BWE - previous start point for copying frequency band */ - Word32 OptCrit_old_fx; /* HF BWE - previous criterion value for deciding the start point */ + Word16 unvoicing_fx; /* HF BWE - unvoiced parameter */ + Word16 unvoicing_sm_fx; /* HF BWE - smoothed unvoiced parameter */ + Word16 unvoicing_flag_fx; /* HF BWE - unvoiced flag */ + Word16 voicing_flag_fx; /* HF BWE - voiced flag */ + Word16 start_band_old_fx; /* HF BWE - previous start point for copying frequency band */ + Word32 OptCrit_old_fx; /* HF BWE - previous criterion value for deciding the start point */ /* Improvement of unvoiced and audio signals in AMR-WB IO mode */ - Word16 UV_cnt; /* number of consecutives frames classified as UV */ - Word16 UV_cnt_fx; /* number of consecutives frames classified as UV */ - Word16 LT_UV_cnt_fx; /* long-term consecutives frames classified as UV */ - - Word16 Last_ener_fx; /* last_energy frame */ - + Word16 UV_cnt_fx; /* number of consecutives frames classified as UV */ + Word16 LT_UV_cnt_fx; /* long-term consecutives frames classified as UV */ + Word16 Last_ener_fx; /* last_energy frame */ Word16 lt_diff_etot_fx[MAX_LT]; /* stability estimation - long-term total energy variation */ - - Word16 old_Aq_fx[68]; /* old LPC filter coefficient */ - - Word16 lt_voice_fac_fx; /* average voice factor over 4 sub-frames */ - + Word16 old_Aq_fx[68]; /* old LPC filter coefficient */ + Word16 lt_voice_fac_fx; /* average voice factor over 4 sub-frames */ } AMRWB_IO_DEC_DATA, *AMRWB_IO_DEC_HANDLE; @@ -1430,7 +1387,7 @@ typedef struct Decoder_State Word16 first_CNG; /* DTX/CNG - first CNG frame flag */ Word16 cng_type; /* DTX/CNG - flag indicating LP or CLDFB based SID/CNG */ - Word16 last_vad; + Word16 last_vad_fx; Word32 last_active_brate; /* DTX/CNG - last active frame bitrate used for CNG_mode control */ Word16 last_CNG_L_frame; /* DTX/CNG - last CNG frame length */ @@ -1541,9 +1498,6 @@ typedef struct Decoder_State Word16 last_bwidth; Word16 t_audio_q_fx[L_FRAME]; - // in FLP, the folowing ones are part of TD_CNG_DEC_HANDLE - Word16 interpol_3_2_cng_dec_fx[INTERP_3_2_MEM_LEN]; - /*----------------------------------------------------------------------------------* * Fixed point only *----------------------------------------------------------------------------------*/ @@ -1559,7 +1513,6 @@ typedef struct Decoder_State Word16 prev_Qx; Word16 prev_Q_bwe_exc; Word16 prev_Q_synth; - Word16 prev_SWB_fenv_fx[SWB_FENV]; Word16 Q_syn; Word16 Q_syn2; @@ -1580,23 +1533,6 @@ typedef struct Decoder_State FD_BWE_DEC_HANDLE hBWE_FD; - /*----------------------------------------------------------------------------------* - * SWB DTX/CNG parameters - *----------------------------------------------------------------------------------*/ - - // in FLP, the folowing ones are part of TD_CNG_DEC_HANDLE - Word16 shb_cng_ener_fx; - Word16 wb_cng_ener_fx; - Word16 last_wb_cng_ener_fx; - Word16 last_shb_cng_ener_fx; - Word16 swb_cng_seed; - Word16 lsp_shb_prev_prev_fx[LPC_SHB_ORDER]; - Word16 lsp_shb_prev_fx[LPC_SHB_ORDER]; - Word16 shb_dtx_count_fx; - Word16 last_vad_fx; - Word16 trans_cnt_fx; - Word16 last_shb_ener_fx; - /*----------------------------------------------------------------------------------* * LD music post-filter *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index b91dcdf32..af23bc98e 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -19,6 +19,7 @@ * * predict SWB parameters for bandwidth switching *-------------------------------------------------------------------*/ + static Word16 para_pred_bws_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 *signal_wb_fx, /* i : wideband frequency signal Q_syn*/ @@ -27,6 +28,7 @@ static Word16 para_pred_bws_fx( { Word16 i, j, k; Word16 mode; + FD_BWE_DEC_HANDLE hBWE_FD; Word16 tmp, tmp_den, tmp_num; Word32 L_tmp, L_tmp_max; Word16 exp; @@ -39,6 +41,7 @@ static Word16 para_pred_bws_fx( Word16 coder_type = st_fx->coder_type; move16(); + hBWE_FD = st_fx->hBWE_FD; mode = NORMAL; move16(); @@ -226,16 +229,16 @@ static Word16 para_pred_bws_fx( FOR( i = 0; i < SWB_FENV; i++ ) { test(); - IF( NE_16( st_fx->prev_coder_type, coder_type ) && GT_16( mult_r( SWB_fenv_fx[i], 16384 ), st_fx->prev_SWB_fenv_fx[i] ) ) + IF( NE_16( st_fx->prev_coder_type, coder_type ) && GT_16( mult_r( SWB_fenv_fx[i], 16384 ), hBWE_FD->prev_SWB_fenv_fx[i] ) ) { /*SWB_fenv_fx[i] = add(mult_r(SWB_fenv_fx[i], 3277), mult_r(st_fx->prev_SWB_fenv_fx[i], 29491)); */ - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 3277 ), st_fx->prev_SWB_fenv_fx[i], 29491 ) ); + SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 3277 ), hBWE_FD->prev_SWB_fenv_fx[i], 29491 ) ); move16(); } ELSE { /*SWB_fenv_fx[i] = add(mult_r(SWB_fenv_fx[i], st_fx->attenu_fx), mult_r(st_fx->prev_SWB_fenv_fx[i], sub(32767, st_fx->attenu_fx))); */ - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], st_fx->attenu_fx ), st_fx->prev_SWB_fenv_fx[i], sub( 32767, st_fx->attenu_fx ) ) ); + SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], st_fx->attenu_fx ), hBWE_FD->prev_SWB_fenv_fx[i], sub( 32767, st_fx->attenu_fx ) ) ); move16(); } } @@ -257,9 +260,9 @@ static Word16 para_pred_bws_fx( { FOR( i = 0; i < SWB_FENV; i++ ) { - if ( GT_16( mult_r( SWB_fenv_fx[i], 16384 ), st_fx->prev_SWB_fenv_fx[i] ) ) + if ( GT_16( mult_r( SWB_fenv_fx[i], 16384 ), hBWE_FD->prev_SWB_fenv_fx[i] ) ) { - SWB_fenv_fx[i] = st_fx->prev_SWB_fenv_fx[i]; + SWB_fenv_fx[i] = hBWE_FD->prev_SWB_fenv_fx[i]; move16(); } } @@ -268,7 +271,7 @@ static Word16 para_pred_bws_fx( FOR( i = 0; i < SWB_FENV; i++ ) { /*SWB_fenv_fx[i] = add(mult_r(SWB_fenv_fx[i], 29491), mult_r(st_fx->prev_SWB_fenv_fx[i], 3277)); */ - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 29491 ), st_fx->prev_SWB_fenv_fx[i], 3277 ) ); + SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 29491 ), hBWE_FD->prev_SWB_fenv_fx[i], 3277 ) ); move16(); } st_fx->attenu_fx = 3277; /*Q15*/ @@ -349,16 +352,18 @@ Word16 WB_BWE_gain_deq_fx( * * WB BWE decoder (only for 16kHz signals) *-------------------------------------------------------------------*/ -Word16 ivas_wb_bwe_dec_fx( /* o : Q_syn_hb */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word16 output[], /* i : suntehsis @ internal Fs Q_input */ - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const Word16 output_frame, /* i : frame length */ - Word16 *voice_factors_fx, /* i : voicing factors Q15 */ - const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ - Word16 *Qpost ) + +/* o : Q_syn_hb */ +Word16 ivas_wb_bwe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 output[], /* i : suntehsis @ internal Fs Q_input */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const Word16 output_frame, /* i : frame length */ + Word16 *voice_factors_fx, /* i : voicing factors Q15 */ + const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ + Word16 *Qpost ) { Word16 mode; Word16 WB_fenv_fx[SWB_FENV]; @@ -438,11 +443,11 @@ Word16 ivas_wb_bwe_dec_fx( /* o : } if ( NE_16( st_fx->last_extl, WB_BWE ) ) { - st_fx->prev_SWB_fenv_fx[0] = 0; + hBWE_FD->prev_SWB_fenv_fx[0] = 0; move16(); } - mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type, st_fx->prev_SWB_fenv_fx[0], + mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type, hBWE_FD->prev_SWB_fenv_fx[0], voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); } } @@ -453,14 +458,14 @@ Word16 ivas_wb_bwe_dec_fx( /* o : move16(); FOR( i = 0; i < 2; i++ ) { - WB_fenv_fx[i] = mult_r( st_fx->prev_SWB_fenv_fx[i], 24576 ); + WB_fenv_fx[i] = mult_r( hBWE_FD->prev_SWB_fenv_fx[i], 24576 ); move16(); } } test(); IF( NE_16( st_fx->last_extl, WB_BWE ) || st_fx->bfi ) { - Copy( WB_fenv_fx, st_fx->prev_SWB_fenv_fx, 2 ); + Copy( WB_fenv_fx, hBWE_FD->prev_SWB_fenv_fx, 2 ); } exp = norm_l( hBWE_FD->prev_Energy_wb_fx ); @@ -476,7 +481,7 @@ Word16 ivas_wb_bwe_dec_fx( /* o : move32(); } WB_BWE_decoding_fx( ysynth_fx, WB_fenv_fx, ysynth_32, L_FRAME16k, mode, - st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, + st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->extl, coder_type, st_fx->total_brate, &hBWE_FD->Seed, &hBWE_FD->prev_flag, st_fx->prev_coder_type, Q_syn, &Q_syn_hb ); IF( EQ_32( st_fx->output_Fs, 32000 ) ) @@ -579,11 +584,11 @@ Word16 wb_bwe_dec_fx( if ( NE_16( st_fx->last_extl, WB_BWE ) ) { - st_fx->prev_SWB_fenv_fx[0] = 0; + hBWE_FD->prev_SWB_fenv_fx[0] = 0; move16(); } - mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type, st_fx->prev_SWB_fenv_fx[0], + mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type, hBWE_FD->prev_SWB_fenv_fx[0], voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); } } @@ -594,14 +599,14 @@ Word16 wb_bwe_dec_fx( move16(); FOR( i = 0; i < 2; i++ ) { - WB_fenv_fx[i] = mult_r( st_fx->prev_SWB_fenv_fx[i], 24576 ); + WB_fenv_fx[i] = mult_r( hBWE_FD->prev_SWB_fenv_fx[i], 24576 ); move16(); } } test(); IF( NE_16( st_fx->last_extl, WB_BWE ) || st_fx->bfi ) { - Copy( WB_fenv_fx, st_fx->prev_SWB_fenv_fx, 2 ); + Copy( WB_fenv_fx, hBWE_FD->prev_SWB_fenv_fx, 2 ); } exp = norm_l( hBWE_FD->prev_Energy_wb_fx ); @@ -617,7 +622,7 @@ Word16 wb_bwe_dec_fx( move32(); } WB_BWE_decoding_fx( ysynth_fx, WB_fenv_fx, ysynth_32, L_FRAME16k, mode, - st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, + st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->extl, coder_type, st_fx->total_brate, &hBWE_FD->Seed, &hBWE_FD->prev_flag, st_fx->prev_coder_type, Q_syn, &Q_syn_hb ); IF( EQ_32( st_fx->output_Fs, 32000 ) ) @@ -646,13 +651,15 @@ Word16 wb_bwe_dec_fx( * * Decoding of SWB parameters *-------------------------------------------------------------------*/ -Word16 swb_bwe_gain_deq_fx( /* o : BWE class */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word16 core, /* i : core : Q0 */ - Word16 *SWB_tenv, /* o : time-domain BWE envelope : Q0 */ - Word16 *SWB_fenv, /* o : frequency-domain BWE envelope : Q1 */ - const Word16 hr_flag, /* i : high rate flag : Q0 */ - const Word16 hqswb_clas /* i : HQ BWE class : Q0 */ + +/* o : BWE class */ +Word16 swb_bwe_gain_deq_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 core, /* i : core : Q0 */ + Word16 *SWB_tenv, /* o : time-domain BWE envelope : Q0 */ + Word16 *SWB_fenv, /* o : frequency-domain BWE envelope : Q1 */ + const Word16 hr_flag, /* i : high rate flag : Q0 */ + const Word16 hqswb_clas /* i : HQ BWE class : Q0 */ ) { Word16 index, mode, n_band; @@ -883,12 +890,14 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class * * SWB BWE decoder *-------------------------------------------------------------------*/ -Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ - const Word16 output_frame, /* i : frame length */ - Word16 *Qpost ) + +/*o : Q_syn_hb */ +Word16 swb_bwe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 output_frame, /* i : frame length */ + Word16 *Qpost ) { Word16 i, l_subfr; Word16 mode; @@ -997,19 +1006,19 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ move16(); } - Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); + Copy( hBWE_FD->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); } /* reconstruction of MDCT spectrum of the error signal */ set32_fx( ysynth_32, 0, output_frame ); IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, ysynth_32, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, ysynth_32, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); } ELSE { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, ysynth_32, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, ysynth_32, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); } @@ -1163,8 +1172,6 @@ void fd_bwe_dec_init( FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ ) { - hBWE_FD->old_wtda_wb_fx_exp = 0; - move16(); set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); hBWE_FD->old_wtda_swb_fx_exp = 0; @@ -1174,7 +1181,7 @@ void fd_bwe_dec_init( hBWE_FD->prev_mode = NORMAL; move16(); - set16_fx( st_fx->prev_SWB_fenv_fx, 0, SWB_FENV ); + set16_fx( hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); hBWE_FD->prev_Energy_fx = 0; move16(); hBWE_FD->prev_L_swb_norm = 8; @@ -1362,7 +1369,7 @@ Word16 swb_bwe_dec_fx32( move16(); } - Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); + Copy( hBWE_FD->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); } /* reconstruction of MDCT spectrum of the error signal */ @@ -1370,11 +1377,11 @@ Word16 swb_bwe_dec_fx32( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); } ELSE { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); } test(); diff --git a/lib_dec/swb_bwe_dec_hr_fx.c b/lib_dec/swb_bwe_dec_hr_fx.c index 18867ce40..9fae1ded5 100644 --- a/lib_dec/swb_bwe_dec_hr_fx.c +++ b/lib_dec/swb_bwe_dec_hr_fx.c @@ -1306,7 +1306,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB } FOR( i = 0; i < SWB_FENV; i++ ) { - st_fx->prev_SWB_fenv_fx[i] = st_fx->prev_ener_shb_fx; /*gain_e + 15*/ + st_fx->hBWE_FD->prev_SWB_fenv_fx[i] = st_fx->prev_ener_shb_fx; /*gain_e + 15*/ move16(); } diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 58ec4b696..fc5e2f6c7 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -1969,7 +1969,7 @@ void swb_tbe_dec_fx( move16(); shb_ener_sf_32 = L_deposit_l( 0 ); set16_fx( shaped_shb_excitationTemp, 0, L_FRAME16k ); - st_fx->shb_dtx_count_fx = 0; + st_fx->hTdCngDec->shb_dtx_count_fx = 0; move16(); is_fractive = 0; move16(); @@ -2555,8 +2555,11 @@ void swb_tbe_dec_fx( move16(); /* SWB CNG/DTX - update memories */ - Copy( st_fx->lsp_shb_prev_fx, st_fx->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); /* Q15 */ - Copy( lsf_shb, st_fx->lsp_shb_prev_fx, LPC_SHB_ORDER ); /* Q15 */ + if ( st_fx->hTdCngDec != NULL ) + { + Copy( st_fx->hTdCngDec->lsp_shb_prev_fx, st_fx->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); /* Q15 */ + Copy( lsf_shb, st_fx->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); /* Q15 */ + } /* vind = (short)(mixFactors*8.0f); */ vind = shl( mixFactors, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ @@ -3365,8 +3368,7 @@ void swb_tbe_dec_fx( L_tmp = Isqrt_lc( L_tmp, &exp ); tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ } - set16_fx( st_fx->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ - + set16_fx( st_fx->hBWE_FD->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ /* rescale the memories if Q_bwe_exc is different from previous frame */ sc = sub( Q_bwe_exc, st_fx->prev_Q_bwe_syn2 ); @@ -5526,7 +5528,7 @@ void ivas_swb_tbe_dec_fx( set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); if ( st->hTdCngDec != NULL ) { - st->hTdCngDec->shb_dtx_count = 0; + st->hTdCngDec->shb_dtx_count_fx = 0; move16(); } is_fractive = 0; @@ -6994,7 +6996,7 @@ void ivas_swb_tbe_dec_fx( L_tmp = Isqrt_lc( L_tmp, &exp ); tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ } - set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ + set16_fx( st->hBWE_FD->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ } FOR( i = 0; i < L_FRAME16k; i++ ) -- GitLab From def9699d92348d878dbd2464308e9f947f9f9d64 Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 12:01:45 +0100 Subject: [PATCH 0457/1221] remove unused functions --- lib_com/bitstream.c | 189 -------------------------------------------- 1 file changed, 189 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index de66f07f2..d8d4563ed 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1660,195 +1660,6 @@ static void decoder_selectCodec( return; } -/*-------------------------------------------------------------------* - * dec_prm_core() - * - * - *-------------------------------------------------------------------*/ - -static void dec_prm_core( - Decoder_State *st ) -{ - int16_t n, frame_size_index = -1; - - st->core = -1; - - if ( st->total_brate == FRAME_NO_DATA ) - { - st->m_frame_type = ZERO_FRAME; - } - else if ( st->total_brate == SID_2k40 ) - { - st->m_frame_type = SID_FRAME; - } - else - { - st->m_frame_type = ACTIVE_FRAME; - for ( n = 0; n < FRAME_SIZE_NB; ++n ) - { - if ( FrameSizeConfig[n].frame_bits == st->total_brate / FRAMES_PER_SEC ) - { - frame_size_index = n; - break; - } - } - - /* Get audio bandwidth info */ - st->bwidth = get_next_indice( st, FrameSizeConfig[frame_size_index].bandwidth_bits ); - st->bwidth += FrameSizeConfig[frame_size_index].bandwidth_min; - if ( st->bwidth > FB ) - { - st->bwidth = FB; - st->BER_detect = 1; - } - - if ( st->bwidth > SWB && st->total_brate < ACELP_16k40 ) - { - st->bwidth = SWB; - st->BER_detect = 1; - } - /* Skip reserved bit */ - get_next_indice_tmp( st, FrameSizeConfig[frame_size_index].reserved_bits ); - - if ( get_next_indice_1( st ) ) /* TCX */ - { - if ( get_next_indice_1( st ) ) - { - st->core = HQ_CORE; - } - else - { - st->core = TCX_20_CORE; - } - } - else /* ACELP */ - { - st->core = ACELP_CORE; - } - } - - return; -} - -/*-----------------------------------------------------------------* - * decision_matrix_core_dec() - * - * Read core signaling bits from the bitstream - * Set st->core, and st->bwidth if signalled together with the core. - *-----------------------------------------------------------------*/ - -static void decision_matrix_core_dec( - Decoder_State *st /* i/o: decoder state structure */ -) -{ - int16_t start_idx; - int32_t ind; - int16_t nBits; - - assert( st->bfi != 1 ); - - st->core = -1; - st->bwidth = -1; - - if ( st->total_brate == FRAME_NO_DATA || st->total_brate == SID_2k40 ) - { - st->core = ACELP_CORE; - } - /* SC-VBR */ - else if ( st->total_brate == PPP_NELP_2k80 ) - { - st->core = ACELP_CORE; - return; - } - - /*---------------------------------------------------------------------* - * ACELP/HQ core selection - *---------------------------------------------------------------------*/ - - if ( st->total_brate < ACELP_24k40 ) - { - st->core = ACELP_CORE; - } - else if ( st->total_brate >= ACELP_24k40 && st->total_brate <= ACELP_64k ) - { - /* read the ACELP/HQ core selection bit */ - st->core = get_next_indice( st, 1 ) * HQ_CORE; - } - else - { - st->core = HQ_CORE; - } - - /*-----------------------------------------------------------------* - * Read ACELP signaling bits from the bitstream - *-----------------------------------------------------------------*/ - - if ( st->core == ACELP_CORE ) - { - /* find the section in the ACELP signaling table corresponding to bitrate */ - start_idx = 0; - while ( acelp_sig_tbl[start_idx] != st->total_brate ) - { - start_idx++; - } - - /* skip the bitrate */ - start_idx += 1; - - /* retrieve the number of bits */ - nBits = (int16_t) acelp_sig_tbl[start_idx++]; - - /* retrieve the signaling indice */ - ind = acelp_sig_tbl[start_idx + get_next_indice( st, nBits )]; - st->bwidth = ( ind >> 3 ) & 0x7; - - /* convert signaling indice into signaling information */ - if ( ( ind & 0x7 ) == LR_MDCT ) - { - st->core = HQ_CORE; - } - } - - /*-----------------------------------------------------------------* - * Read HQ signaling bits from the bitstream - * Set HQ core type - *-----------------------------------------------------------------*/ - - if ( st->core == HQ_CORE ) - { - /* read the HQ/TCX core switching flag */ - if ( get_next_indice( st, 1 ) ) - { - st->core = TCX_20_CORE; - } - - /* For TCX: read/set band-width (needed for different I/O sampling rate support) */ - if ( st->core == TCX_20_CORE && st->total_brate > ACELP_16k40 ) - { - ind = get_next_indice( st, 2 ); - - if ( ind == 0 ) - { - st->bwidth = NB; - } - else if ( ind == 1 ) - { - st->bwidth = WB; - } - else if ( ind == 2 ) - { - st->bwidth = SWB; - } - else - { - st->bwidth = FB; - } - } - } - - return; -} - /*-------------------------------------------------------------------* * reset_elements() -- GitLab From 192a52ea6cf1496cbaf33cf32d92359f30870469 Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 12:45:02 +0100 Subject: [PATCH 0458/1221] fix EVS decoding --- lib_com/bitstream_fx.c | 153 +++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 75 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 17b7d0495..712a6905e 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -1153,101 +1153,104 @@ void mdct_switching_dec_fx( Decoder_State *st /* i/o: decoder state structure */ ) { - IF( st->Opt_AMR_WB != 0 ) + if ( !st->bfi ) { - return; - } - - test(); - test(); - IF( EQ_32( st->total_brate, ACELP_13k20 ) || EQ_32( st->total_brate, ACELP_32k ) ) - { - st->mdct_sw_enable = MODE1; - move16(); - } - ELSE IF( LE_32( ACELP_16k40, st->total_brate ) && LE_32( st->total_brate, ACELP_24k40 ) ) - { - st->mdct_sw_enable = MODE2; - move16(); - } - - test(); - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->mdct_sw_enable, MODE1 ) ) - { - /* Read ahead core mode signaling */ - Word16 next_bit_pos_save; - Word16 core_save; - Word16 bwidth_save; - - next_bit_pos_save = st->next_bit_pos; - move16(); - core_save = st->core; - move16(); - bwidth_save = st->bwidth; - move16(); - - decision_matrix_core_dec( st ); /* sets st->core */ + IF( st->Opt_AMR_WB != 0 ) + { + return; + } - IF( EQ_16( st->core, TCX_20_CORE ) ) + test(); + test(); + IF( EQ_32( st->total_brate, ACELP_13k20 ) || EQ_32( st->total_brate, ACELP_32k ) ) { - /* Trigger TCX */ - st->codec_mode = MODE2; + st->mdct_sw_enable = MODE1; move16(); - st->mdct_sw = MODE1; + } + ELSE IF( LE_32( ACELP_16k40, st->total_brate ) && LE_32( st->total_brate, ACELP_24k40 ) ) + { + st->mdct_sw_enable = MODE2; move16(); } - ELSE + + test(); + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->mdct_sw_enable, MODE1 ) ) { - /* Rewind bitstream */ - st->next_bit_pos = next_bit_pos_save; + /* Read ahead core mode signaling */ + Word16 next_bit_pos_save; + Word16 core_save; + Word16 bwidth_save; + + next_bit_pos_save = st->next_bit_pos; move16(); - IF( st->bfi != 0 ) + core_save = st->core; + move16(); + bwidth_save = st->bwidth; + move16(); + + decision_matrix_core_dec( st ); /* sets st->core */ + + IF( EQ_16( st->core, TCX_20_CORE ) ) { - st->core = core_save; + /* Trigger TCX */ + st->codec_mode = MODE2; move16(); - st->bwidth = bwidth_save; + st->mdct_sw = MODE1; + move16(); + } + ELSE + { + /* Rewind bitstream */ + st->next_bit_pos = next_bit_pos_save; move16(); + IF( st->bfi != 0 ) + { + st->core = core_save; + move16(); + st->bwidth = bwidth_save; + move16(); + } } } - } - ELSE IF( EQ_16( st->codec_mode, MODE2 ) && EQ_16( st->mdct_sw_enable, MODE2 ) ) - { - /* Read ahead core mode signaling */ - Word16 next_bit_pos_save; - Word16 core_save; - Word16 bwidth_save; - - next_bit_pos_save = st->next_bit_pos; - move16(); - core_save = st->core; - move16(); - bwidth_save = st->bwidth; - move16(); - - dec_prm_core( st ); /* sets st->core */ - - IF( EQ_16( st->core, HQ_CORE ) ) + ELSE IF( EQ_16( st->codec_mode, MODE2 ) && EQ_16( st->mdct_sw_enable, MODE2 ) ) { - /* Trigger HQ_CORE */ - st->codec_mode = MODE1; + /* Read ahead core mode signaling */ + Word16 next_bit_pos_save; + Word16 core_save; + Word16 bwidth_save; + + next_bit_pos_save = st->next_bit_pos; move16(); - st->mdct_sw = MODE2; + core_save = st->core; move16(); - } - ELSE - { - /* Rewind bitstream */ - st->next_bit_pos = next_bit_pos_save; + bwidth_save = st->bwidth; move16(); - if ( st->bfi != 0 ) + + dec_prm_core( st ); /* sets st->core */ + + IF( EQ_16( st->core, HQ_CORE ) ) { - st->core = core_save; + /* Trigger HQ_CORE */ + st->codec_mode = MODE1; + move16(); + st->mdct_sw = MODE2; + move16(); + } + ELSE + { + /* Rewind bitstream */ + st->next_bit_pos = next_bit_pos_save; + move16(); + if ( st->bfi != 0 ) + { + st->core = core_save; + move16(); + } + /* always reset bwidth, to not interfere with BER logic */ + st->bwidth = bwidth_save; move16(); } - /* always reset bwidth, to not interfere with BER logic */ - st->bwidth = bwidth_save; - move16(); } } -- GitLab From fcb3d0ebde44fa1b5f81fb7d1cc7aac41468eaef Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 13:17:29 +0100 Subject: [PATCH 0459/1221] harmonize TD BSE --- lib_com/prot_fx.h | 8 ++---- lib_dec/cng_dec_fx.c | 6 +++-- lib_dec/core_switching_dec_fx.c | 8 +++--- lib_dec/stat_dec.h | 4 --- lib_dec/swb_tbe_dec_fx.c | 48 ++++++++++++++++++--------------- lib_dec/updt_dec_fx.c | 2 +- 6 files changed, 37 insertions(+), 39 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index b695f1978..46da3aff7 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6004,13 +6004,9 @@ Word32 calc_gain_inov( /* returns innovation gain /* Lib_dec */ ////////////////////////////////// // swb_tbe_dec.c - -void InitSWBdecBuffer_fx( - Decoder_State *swb_dnc_fx /* i/o: SHB decoder structure */ -); - void ResetSHBbuffer_Dec_fx( - Decoder_State *st_fx /* i/o: decoder state structure */ + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + const Word16 extl /* i : BWE extension layer */ ); void wb_tbe_dec_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index 6fb8e28ae..fe349d074 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -1717,7 +1717,7 @@ static void shb_CNG_decod_fx( interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); } - ResetSHBbuffer_Dec_fx( st_fx ); + ResetSHBbuffer_Dec_fx( st_fx->hBWE_TD, st_fx->extl ); return; } @@ -1994,7 +1994,9 @@ static void shb_CNG_decod_ivas_fx( } Scale_sig( shb_synth_fx, L_FRAME48k, -3 ); /* Qx - 3 */ - ResetSHBbuffer_Dec_fx( st ); + + ResetSHBbuffer_Dec_fx( st->hBWE_TD, st->extl ); + return; } diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 005345fba..240c5b0d7 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1202,7 +1202,7 @@ ivas_error core_switching_post_dec_fx( swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); - set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + set16_fx( hBWE_TD->GainShape_Delay_fx, 0, NUM_SHB_SUBFR / 2 ); swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); IF( EQ_16( output_frame, L_FRAME16k ) ) @@ -1843,11 +1843,11 @@ ivas_error core_switching_post_dec_ivas_fx( swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); - set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + set16_fx( hBWE_TD->GainShape_Delay_fx, 0, NUM_SHB_SUBFR / 2 ); swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); - st_fx->hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /* Q0 1.f */ - st_fx->hBWE_TD->prev_mix_factor_fx = 32767; /* Q15 1.f */ + hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /* Q0 1.f */ + hBWE_TD->prev_mix_factor_fx = 32767; /* Q15 1.f */ move16(); move16(); diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 639918f24..cbb3a96f5 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1300,7 +1300,6 @@ typedef struct Decoder_State Word16 Last_GSC_noisy_speech_flag; /* AC mode (GSC) - mem of the past flag to indicate GSC osn SWB noisy speech */ GSC_DEC_HANDLE hGSCDec; - Word32 gc_threshold_fx; /* Noise enhancer - threshold for gain_code Q16*/ struct dispMem_fx dm_fx; /* Noise enhancer - phase dispersion algorithm memory */ @@ -1524,9 +1523,6 @@ typedef struct Decoder_State Word16 prev_fb_ener_adjust_fx; Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; - // in FLP, the folowing one is part of TD_BWE_DEC_HANDLE - Word16 GainShape_Delay[NUM_SHB_SUBFR / 2]; - /*----------------------------------------------------------------------------------* * SWB BWE structure *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index fc5e2f6c7..da3df53f1 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -411,10 +411,12 @@ void rescale_genWB_mem( Decoder_State *st_fx, Word16 sf ) hBWE_TD->mem_csfilt_fx[i] = L_shl( hBWE_TD->mem_csfilt_fx[i], sf ); move32(); } + + return; } -void InitSWBdecBuffer_fx( +static void InitSWBdecBuffer_fx( Decoder_State *st_fx /* i/o: SHB decoder structure */ ) { @@ -461,15 +463,16 @@ void InitSWBdecBuffer_fx( } -void ResetSHBbuffer_Dec_fx( Decoder_State *st_fx /* i/o: SHB encoder structure */ ) +void ResetSHBbuffer_Dec_fx( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + const Word16 extl /* i : BWE extension layer */ +) { Word16 i; Word16 f; Word16 inc; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - IF( NE_16( st_fx->extl, WB_TBE ) ) + IF( NE_16( extl, WB_TBE ) ) { f = 1489; move16(); /* Q15 */ @@ -491,7 +494,7 @@ void ResetSHBbuffer_Dec_fx( Decoder_State *st_fx /* i/o: SHB encoder structure * set16_fx( hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); set16_fx( hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - IF( EQ_16( st_fx->extl, FB_TBE ) ) + IF( EQ_16( extl, FB_TBE ) ) { set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); hBWE_TD->fb_tbe_demph_fx = 0; @@ -514,7 +517,7 @@ void ResetSHBbuffer_Dec_fx( Decoder_State *st_fx /* i/o: SHB encoder structure * /* States for FEC */ - IF( NE_16( st_fx->extl, WB_TBE ) ) + IF( NE_16( extl, WB_TBE ) ) { FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { @@ -550,7 +553,7 @@ void ResetSHBbuffer_Dec_fx( Decoder_State *st_fx /* i/o: SHB encoder structure * set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); hBWE_TD->gain_prec_swb_fx = 16384; /*Q14 =1*/ move16(); - set16_fx( &st_fx->GainShape_Delay[0], 0, NUM_SHB_SUBFR / 2 ); + set16_fx( hBWE_TD->GainShape_Delay_fx, 0, NUM_SHB_SUBFR / 2 ); hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /* Q0 1.f */ move32(); hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 1.f*/ @@ -2224,7 +2227,7 @@ void swb_tbe_dec_fx( { FOR( j = 0; j < 4; j++ ) { - GainShape[add( i * 4, j )] = mult_r( st_fx->cummulative_damping, st_fx->GainShape_Delay[4 + i] ); + GainShape[add( i * 4, j )] = mult_r( st_fx->cummulative_damping, hBWE_TD->GainShape_Delay_fx[4 + i] ); move16(); } } @@ -2329,13 +2332,13 @@ void swb_tbe_dec_fx( } /* get the gainshape delay */ - Copy( &st_fx->GainShape_Delay[4], &st_fx->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + Copy( &hBWE_TD->GainShape_Delay_fx[4], &hBWE_TD->GainShape_Delay_fx[0], NUM_SHB_SUBFR / 4 ); test(); IF( ( st_fx->rf_flag != 0 ) || EQ_32( st_fx->total_brate, ACELP_9k60 ) ) { FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) { - st_fx->GainShape_Delay[i + 4] = s_min( s_max( GainShape[i * 4], 3277 /*0.1f Q15*/ ), 16384 /*0.5f Q15*/ ); + hBWE_TD->GainShape_Delay_fx[i + 4] = s_min( s_max( GainShape[i * 4], 3277 /*0.1f Q15*/ ), 16384 /*0.5f Q15*/ ); move16(); } } @@ -2343,7 +2346,7 @@ void swb_tbe_dec_fx( { FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) { - st_fx->GainShape_Delay[i + 4] = GainShape[i * 4]; + hBWE_TD->GainShape_Delay_fx[i + 4] = GainShape[i * 4]; move16(); } } @@ -3557,9 +3560,9 @@ static void gradientGainShape( /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ FOR( j = 0; j < 3; j++ ) { - GainGrad0[j] = sub( shr( st_fx->GainShape_Delay[j + 1], 1 ), shr( st_fx->GainShape_Delay[j], 1 ) ); + GainGrad0[j] = sub( shr( hBWE_TD->GainShape_Delay_fx[j + 1], 1 ), shr( hBWE_TD->GainShape_Delay_fx[j], 1 ) ); move16(); /* Q14 */ - GainGrad1[j] = sub( shr( st_fx->GainShape_Delay[j + 5], 1 ), shr( st_fx->GainShape_Delay[j + 4], 1 ) ); + GainGrad1[j] = sub( shr( hBWE_TD->GainShape_Delay_fx[j + 5], 1 ), shr( hBWE_TD->GainShape_Delay_fx[j + 4], 1 ) ); move16(); /* Q14 */ GainGradFEC[j + 1] = add( mult_r( GainGrad0[j], 13107 ), mult_r( GainGrad1[j], 19660 ) ); move16(); /* Q14 */ @@ -3588,17 +3591,17 @@ static void gradientGainShape( test(); IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && ( GainGradFEC[0] > 0 ) ) { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), GainGradFEC[0] ); + GainShapeTemp[0] = add( shr( hBWE_TD->GainShape_Delay_fx[7], 1 ), GainGradFEC[0] ); move16(); } ELSE IF( GainGradFEC[0] > 0 ) { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), mult_r( GainGradFEC[0], 16384 ) ); + GainShapeTemp[0] = add( shr( hBWE_TD->GainShape_Delay_fx[7], 1 ), mult_r( GainGradFEC[0], 16384 ) ); move16(); /* Q14 */ } ELSE { - GainShapeTemp[0] = shr( st_fx->GainShape_Delay[7], 1 ); + GainShapeTemp[0] = shr( hBWE_TD->GainShape_Delay_fx[7], 1 ); move16(); /* Q14 */ } @@ -5158,7 +5161,7 @@ void TBEreset_dec_fx( swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32 ); - set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + set16_fx( hBWE_TD->GainShape_Delay_fx, 0, NUM_SHB_SUBFR / 2 ); set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); set32_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx_32, 0, INTERP_3_2_MEM_LEN ); set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); @@ -5204,7 +5207,8 @@ void td_bwe_dec_init_fx( InitSWBdecBuffer_fx( st_fx ); /* reset SHB buffers */ - ResetSHBbuffer_Dec_fx( st_fx ); + ResetSHBbuffer_Dec_fx( hBWE_TD, st_fx->extl ); + IF( EQ_32( output_Fs, 48000 ) ) { set32_fx( hBWE_TD->fbbwe_hpf_mem_fx[0], 0, 4 ); @@ -5786,7 +5790,7 @@ void ivas_swb_tbe_dec_fx( { FOR( j = 0; j < 4; j++ ) { - GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); + GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, hBWE_TD->GainShape_Delay_fx[4 + i] ); move16(); } } @@ -5883,10 +5887,10 @@ void ivas_swb_tbe_dec_fx( } /* get the gainshape delay */ - Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + Copy( &hBWE_TD->GainShape_Delay_fx[4], &hBWE_TD->GainShape_Delay_fx[0], NUM_SHB_SUBFR / 4 ); FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) { - st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ + hBWE_TD->GainShape_Delay_fx[i + 4] = GainShape_fx[i * 4]; /*Q15*/ move16(); } diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index d401388d3..42a9e1ede 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -249,7 +249,7 @@ void updt_IO_switch_dec_fx( { swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &hBWE_TD->tbe_demph_fx, &hBWE_TD->tbe_premph_fx, hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); - set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + set16_fx( hBWE_TD->GainShape_Delay_fx, 0, NUM_SHB_SUBFR / 2 ); hBWE_TD->prev_pow_exc16kWhtnd_fx32 = 1; /*Q0 1.f*/ move32(); hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 1.f*/ -- GitLab From 298ebca0b7b7d1ae3b0e00fdeffff587e47238f0 Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 16:40:21 +0100 Subject: [PATCH 0460/1221] harmonize 'hBWE_FD' --- lib_com/prot_fx.h | 3 +- lib_dec/cng_dec_fx.c | 8 +- lib_dec/core_dec_init_fx.c | 2 +- lib_dec/core_switching_dec_fx.c | 4 +- lib_dec/dec_tcx_fx.c | 6 +- lib_dec/evs_dec_fx.c | 6 +- lib_dec/init_dec_fx.c | 18 +- lib_dec/ivas_core_dec_fx.c | 74 +++--- lib_dec/ivas_stereo_icbwe_dec_fx.c | 8 +- lib_dec/ivas_stereo_switching_dec_fx.c | 72 ++--- lib_dec/stat_dec.h | 87 ++---- lib_dec/swb_bwe_dec_fx.c | 88 +++---- lib_dec/swb_tbe_dec_fx.c | 349 ++++++++++++------------- lib_dec/updt_dec_fx.c | 2 +- 14 files changed, 307 insertions(+), 420 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 46da3aff7..f9c69e8d6 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6081,7 +6081,6 @@ void GenTransition_fx32( void GenTransition_WB_fx( TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const Word16 prev_Qx, /* i : scaling of old_hb_synth */ Word16 *output, /* o : synthesized transitions signal */ const Word32 output_Fs /* i : output sampling rate */ ); @@ -6097,8 +6096,8 @@ void TBEreset_dec_fx( ); void td_bwe_dec_init_fx( - Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + const Word16 extl, /* i : BWE extension layer */ const Word32 output_Fs /* i : output sampling rate */ ); diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index fe349d074..945f0ca75 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -1700,13 +1700,13 @@ static void shb_CNG_decod_fx( /* rescale the Hilbert memories to Q0 */ FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) { - hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], st_fx->prev_Q_bwe_syn2 ); /* st_fx->prev_Q_bwe_syn2 */ + hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */ move32(); } FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { - hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], st_fx->prev_Q_bwe_syn2 ); /* st_fx->prev_Q_bwe_syn2 */ + hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */ move16(); } } @@ -1976,13 +1976,13 @@ static void shb_CNG_decod_ivas_fx( /* rescale the Hilbert memories to Q0 */ FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) { - hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], st->prev_Q_bwe_syn2 ); /* st_fx->prev_Q_bwe_syn2 */ + hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */ move32(); } FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { - hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], st->prev_Q_bwe_syn2 ); /* st_fx->prev_Q_bwe_syn2 */ + hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */ move16(); } } diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index e104766c0..967a93bfb 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -836,7 +836,7 @@ void open_decoder_LPD_fx( st->Mode2_lp_gainp = L_deposit_l( 0 ); /* 15Q16 */ move32(); - st->prev_widow_left_rect = 0; + st->hTcxDec->prev_widow_left_rect = 0; move16(); if ( st->hTcxDec != NULL ) { diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 240c5b0d7..0bef8c97b 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -1150,7 +1150,7 @@ ivas_error core_switching_post_dec_fx( move16(); hBWE_FD->prev_weight_fx = 6554; move16(); /*0.2 in Q15*/ - st_fx->prev_fb_ener_adjust_fx = 0; + hBWE_FD->prev_fb_ener_adjust_fx = 0; move16(); } @@ -1782,7 +1782,7 @@ ivas_error core_switching_post_dec_ivas_fx( move16(); hBWE_FD->prev_weight_fx = 6554; move16(); /*0.2 in Q15*/ - st_fx->prev_fb_ener_adjust_fx = 0; + hBWE_FD->prev_fb_ener_adjust_fx = 0; move16(); } diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 941b34956..510370aee 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -153,7 +153,7 @@ void decoder_tcx_fx( L_frameTCX = st->L_frameTCX_past; move16(); - left_rect = st->prev_widow_left_rect; + left_rect = hTcxDec->prev_widow_left_rect; move16(); IF( left_rect != 0 ) @@ -190,7 +190,7 @@ void decoder_tcx_fx( move16(); left_rect = 1; move16(); - st->prev_widow_left_rect = 1; + hTcxDec->prev_widow_left_rect = 1; move16(); } ELSE @@ -202,7 +202,7 @@ void decoder_tcx_fx( move16(); left_rect = 0; move16(); - st->prev_widow_left_rect = 0; + hTcxDec->prev_widow_left_rect = 0; move16(); } diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 8d72233a5..5797a6b5a 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -865,14 +865,14 @@ ivas_error evs_dec_fx( { GenTransition_fx( st_fx->hBWE_TD, hb_synth_fx, st_fx->output_Fs, st_fx->rf_flag, st_fx->total_brate ); - hb_synth_fx_exp = st_fx->prev_Q_bwe_syn2; + hb_synth_fx_exp = st_fx->hBWE_TD->prev_Q_bwe_syn2; move16(); } ELSE IF( EQ_16( st_fx->bwidth, WB ) && EQ_16( st_fx->last_extl, WB_TBE ) ) { - GenTransition_WB_fx( st_fx->hBWE_TD, st_fx->prev_Qx, hb_synth_fx, st_fx->output_Fs ); + GenTransition_WB_fx( st_fx->hBWE_TD, hb_synth_fx, st_fx->output_Fs ); - hb_synth_fx_exp = st_fx->prev_Qx; + hb_synth_fx_exp = st_fx->hBWE_TD->prev_Qx; move16(); } diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 3bb5894f3..934433132 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -126,7 +126,7 @@ ivas_error init_decoder_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); } - fd_bwe_dec_init( st_fx, st_fx->hBWE_FD ); + fd_bwe_dec_init_fx( st_fx->hBWE_FD ); } ELSE { @@ -193,7 +193,6 @@ ivas_error init_decoder_fx( st_fx->last_voice_factor_fx = 0; // Q6 move16(); - set16_fx( st_fx->prev_lpc_wb_fx, 0, LPC_SHB_ORDER_WB ); test(); test(); @@ -512,12 +511,10 @@ ivas_error init_decoder_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, st_fx->output_Fs ); + td_bwe_dec_init_fx( st_fx->hBWE_TD, st_fx->extl, st_fx->output_Fs ); -#ifdef MSAN_FIX - st_fx->hBWE_TD->prev_hb_synth_fx_exp = 31; + st_fx->prev_Q_bwe_exc = 31; move16(); -#endif } ELSE { @@ -1273,11 +1270,10 @@ ivas_error init_decoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, st_fx->output_Fs ); -#ifdef MSAN_FIX - st_fx->hBWE_TD->prev_hb_synth_fx_exp = 31; + td_bwe_dec_init_fx( st_fx->hBWE_TD, st_fx->extl, st_fx->output_Fs ); + + st_fx->prev_Q_bwe_exc = 31; move16(); -#endif } ELSE { @@ -1299,7 +1295,7 @@ ivas_error init_decoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); } - fd_bwe_dec_init( st_fx, st_fx->hBWE_FD ); + fd_bwe_dec_init_fx( st_fx->hBWE_FD ); } ELSE { diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 8344b0447..83d1d1187 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -66,6 +66,7 @@ ivas_error ivas_core_dec_fx( STEREO_ICBWE_DEC_HANDLE hStereoICBWE; STEREO_TD_DEC_DATA_HANDLE hStereoTD; STEREO_CNG_DEC_HANDLE hStereoCng; + TD_BWE_DEC_HANDLE hBWE_TD; FD_BWE_DEC_HANDLE hBWE_FD; Word16 sharpFlag[CPE_CHANNELS]; Word16 tmp_buffer_fx[L_FRAME48k]; @@ -836,6 +837,7 @@ ivas_error ivas_core_dec_fx( FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; + hBWE_TD = st->hBWE_TD; hBWE_FD = st->hBWE_FD; /*---------------------------------------------------------------------* @@ -882,7 +884,7 @@ ivas_error ivas_core_dec_fx( test(); test(); test(); - IF( ( st->last_core == ACELP_CORE ) && ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) || EQ_16( st->core, HQ_CORE ) ) && st->hBWE_TD != NULL ) + IF( ( st->last_core == ACELP_CORE ) && ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) || EQ_16( st->core, HQ_CORE ) ) && hBWE_TD != NULL ) { test(); test(); @@ -890,38 +892,38 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) && ( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) ) { - GenTransition_fx32( st->hBWE_TD, hb_synth_32_fx[n], output_Fs, st->L_frame, st->prev_Qx ); + GenTransition_fx32( hBWE_TD, hb_synth_32_fx[n], output_Fs, st->L_frame, hBWE_TD->prev_Qx ); } ELSE IF( EQ_16( st->bwidth, WB ) && EQ_16( st->last_extl, WB_TBE ) ) { - GenTransition_WB_fx32( st->hBWE_TD, hb_synth_32_fx[n], output_Fs ); + GenTransition_WB_fx32( hBWE_TD, hb_synth_32_fx[n], output_Fs ); } /* Memories Scaling */ - Copy_Scale_sig_32_16( st->hBWE_TD->syn_overlap_fx_32, st->hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, sub( st->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bwe_syn2 - Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); // prev_Qx - Copy_Scale_sig_32_16( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, ALLPASSSECTIONS_STEEP * 2, sub( st->prev_Qx, Q11 ) ); // prev_Qx - Copy_Scale_sig_32_16( st->hBWE_TD->state_lsyn_filt_shb_fx_32, st->hBWE_TD->state_lsyn_filt_shb_fx, ALLPASSSECTIONS_STEEP * 2, sub( st->prev_Qx, Q11 ) ); // prev_Qx - Copy_Scale_sig_32_16( st->hBWE_TD->mem_resamp_HB_fx_32, st->hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( st->prev_Qx, Q11 ) ); // prev_Qx + Copy_Scale_sig_32_16( hBWE_TD->syn_overlap_fx_32, hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bwe_syn2 + Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx + Copy_Scale_sig_32_16( hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, hBWE_TD->state_lsyn_filt_dwn_shb_fx, ALLPASSSECTIONS_STEEP * 2, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx + Copy_Scale_sig_32_16( hBWE_TD->state_lsyn_filt_shb_fx_32, hBWE_TD->state_lsyn_filt_shb_fx, ALLPASSSECTIONS_STEEP * 2, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx + Copy_Scale_sig_32_16( hBWE_TD->mem_resamp_HB_fx_32, hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx } /* Memories Re-Scaling */ - IF( st->hBWE_TD != NULL ) + IF( hBWE_TD != NULL ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 #endif - Copy( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); + Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } /*---------------------------------------------------------------------* @@ -937,7 +939,7 @@ ivas_error ivas_core_dec_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx #else - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx + Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx #endif } @@ -955,7 +957,7 @@ ivas_error ivas_core_dec_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx #else - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx + Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx #endif } @@ -986,7 +988,7 @@ ivas_error ivas_core_dec_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 #endif } @@ -1081,9 +1083,9 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 // Q_input can get value <= -5 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 #endif IF( hBWE_FD != NULL ) @@ -1091,15 +1093,15 @@ ivas_error ivas_core_dec_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 #endif } - IF( st->hBWE_TD != NULL ) + IF( hBWE_TD != NULL ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 #endif } @@ -1133,8 +1135,8 @@ ivas_error ivas_core_dec_fx( /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 - Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); // prev_Qx + Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 + Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx IF( GT_16( Q_white_exc, 31 ) ) { @@ -1208,8 +1210,8 @@ ivas_error ivas_core_dec_fx( #else Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, L_FRAME48k, negate( add( Q11, q ) ) ); #endif - Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, st->prev_Q_bwe_syn ) ); // Q8 - Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, ( 2 * ALLPASSSECTIONS_STEEP ), sub( st->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bew_syn2 + Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ); // Q8 + Copy_Scale_sig_32_16( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, ( 2 * ALLPASSSECTIONS_STEEP ), sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bew_syn2 swb_CNG_dec_ivas_fx( st, synth_fxl, hb_synth_16_fx[n], sid_bw[n], negate( q ) ); @@ -1219,8 +1221,8 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, ( Q11 ) ); // Q11 } - Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, st->prev_Q_bwe_syn ) ) ); // Q0 - Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( st->prev_Q_bwe_syn2, Q11 ) ) ); + Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 + Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); } /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 4f289a9c4..04aeccbb5 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -1312,9 +1312,13 @@ void stereo_icBWE_decproc_fx( move32(); } } + /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ - td_bwe_dec_init_fx( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_TD, output_Fs ); - fd_bwe_dec_init( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_FD ); + td_bwe_dec_init_fx( hCPE->hCoreCoder[0]->hBWE_TD, -1, output_Fs ); + fd_bwe_dec_init_fx( hCPE->hCoreCoder[0]->hBWE_FD ); + + hCPE->hCoreCoder[0]->prev_Q_bwe_exc = 31; + move16(); } test(); diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index d524ecd7a..edd5a0fbb 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -626,16 +626,10 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_fx( st, st->hBWE_TD, st->output_Fs ); + td_bwe_dec_init_fx( st->hBWE_TD, -1, st->output_Fs ); st->prev_Q_bwe_exc = 31; move16(); - st->prev_Qx = 0; - move16(); - st->prev_ener_fx_Q = 31; - move16(); - st->prev_frame_pow_exp = 0; - move16(); IF( ( st->hBWE_FD = (FD_BWE_DEC_HANDLE) malloc( sizeof( FD_BWE_DEC_DATA ) ) ) == NULL ) { @@ -643,19 +637,6 @@ ivas_error stereo_memory_dec_fx( } fd_bwe_dec_init_fx( st->hBWE_FD ); - set16_fx( st->hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); - st->last_wb_bwe_ener_fx = 0; - move16(); - st->prev_fb_ener_adjust_fx = 0; - move16(); - - fd_bwe_dec_init( st, st->hBWE_FD ); - st->hBWE_FD->old_wtda_swb_fx_exp = 0; - move16(); - st->hBWE_FD->mem_imdct_exp_fx = 0; - move16(); - st->prev_Q_synth = 0; - move16(); } /* Allocated FD_CNG instance for primary channel*/ @@ -873,16 +854,10 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_fx( st, st->hBWE_TD, st->output_Fs ); + td_bwe_dec_init_fx( st->hBWE_TD, -1, st->output_Fs ); st->prev_Q_bwe_exc = 31; move16(); - st->prev_Qx = 0; - move16(); - st->prev_ener_fx_Q = 31; - move16(); - st->prev_frame_pow_exp = 0; - move16(); IF( ( st->hBWE_FD = (FD_BWE_DEC_HANDLE) malloc( sizeof( FD_BWE_DEC_DATA ) ) ) == NULL ) { @@ -890,19 +865,6 @@ ivas_error stereo_memory_dec_fx( } fd_bwe_dec_init_fx( st->hBWE_FD ); - set16_fx( st->hBWE_FD->prev_SWB_fenv_fx, 0, SWB_FENV ); - st->last_wb_bwe_ener_fx = 0; - move16(); - st->prev_fb_ener_adjust_fx = 0; - move16(); - - fd_bwe_dec_init( st, st->hBWE_FD ); - st->hBWE_FD->old_wtda_swb_fx_exp = 0; - move16(); - st->hBWE_FD->mem_imdct_exp_fx = 0; - move16(); - st->prev_Q_synth = 0; - move16(); } } ELSE /* tdm_LRTD_flag == 0 */ @@ -1985,19 +1947,29 @@ void stereo_switching_dec( move16(); Copy( sts[0]->Q_subfr, sts[1]->Q_subfr, L_Q_MEM ); - sts[1]->prev_Q_bwe_syn = sts[0]->prev_Q_bwe_syn; - move16(); - sts[1]->prev_Q_bwe_syn2 = sts[0]->prev_Q_bwe_syn2; - move16(); + test(); + IF( sts[0]->hBWE_TD != NULL && sts[1]->hBWE_TD != NULL ) + { + sts[1]->hBWE_TD->prev_Q_bwe_syn = sts[0]->hBWE_TD->prev_Q_bwe_syn; + move16(); + sts[1]->hBWE_TD->prev_Q_bwe_syn2 = sts[0]->hBWE_TD->prev_Q_bwe_syn2; + move16(); + + sts[1]->hBWE_TD->prev_Q_bwe_exc_fb = sts[0]->hBWE_TD->prev_Q_bwe_exc_fb; + move16(); + sts[1]->hBWE_TD->prev_Qx = sts[0]->hBWE_TD->prev_Qx; + move16(); + } + + test(); + IF( sts[0]->hBWE_FD != NULL && sts[1]->hBWE_FD != NULL ) + { + sts[1]->hBWE_FD->prev_Q_synth = sts[0]->hBWE_FD->prev_Q_synth; + move16(); + } - sts[1]->prev_Q_bwe_exc_fb = sts[0]->prev_Q_bwe_exc_fb; - move16(); - sts[1]->prev_Qx = sts[0]->prev_Qx; - move16(); sts[1]->prev_Q_bwe_exc = sts[0]->prev_Q_bwe_exc; move16(); - sts[1]->prev_Q_synth = sts[0]->prev_Q_synth; - move16(); sts[1]->Q_syn = sts[0]->Q_syn; move16(); sts[1]->Q_syn2 = sts[0]->Q_syn2; diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index cbb3a96f5..c1b6381e5 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -964,135 +964,86 @@ typedef struct td_bwe_dec_structure { /* states for the filters used in generating SHB excitation from WB excitation */ Word16 state_lpc_syn_fx[LPC_SHB_ORDER]; - Word32 mem_csfilt_fx[2]; /* states for the filters used in generating SHB signal from SHB excitation*/ Word16 state_syn_shbexc_fx[L_SHB_LAHEAD]; - Word16 syn_overlap_fx[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain*/ Word32 syn_overlap_fx_32[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain, IVAS 32-bit variant */ /* previous frame parameters for frame error concealment */ Word16 lsp_prevfrm_fx[LPC_SHB_ORDER]; - Word32 GainFrame_prevfrm_fx; - Word16 GainShape_Delay_fx[NUM_SHB_SUBFR / 2]; - Word16 GainAttn_fx; - Word16 old_bwe_exc_fx[PIT16k_MAX * 2]; /*Q_exc*/ - Word16 bwe_seed[2]; - Word32 bwe_non_lin_prev_scale_fx; - Word16 old_bwe_exc_extended_fx[NL_BUFF_OFFSET]; - Word32 genSHBsynth_Hilbert_Mem_fx[HILBERT_MEM_SIZE]; Word16 mem_genSHBexc_filt_down_shb_fx[2 * ALLPASSSECTIONS_STEEP + 1]; - Word16 mem_genSHBexc_filt_down_wb2_fx[2 * ALLPASSSECTIONS_STEEP + 1]; - Word16 mem_genSHBexc_filt_down_wb3_fx[2 * ALLPASSSECTIONS_STEEP + 1]; - Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[2 * ALLPASSSECTIONS_STEEP]; Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[2 * ALLPASSSECTIONS_STEEP]; /* IVAS 32-bit variant */ - Word16 state_lsyn_filt_shb_fx[2 * ALLPASSSECTIONS_STEEP]; Word32 state_lsyn_filt_shb_fx_32[2 * ALLPASSSECTIONS_STEEP]; /* IVAS 32-bit variant */ - Word16 state_lsyn_filt_dwn_shb_fx[2 * ALLPASSSECTIONS_STEEP]; Word32 state_lsyn_filt_dwn_shb_fx_32[2 * ALLPASSSECTIONS_STEEP]; /* IVAS 32-bit variant */ - Word16 mem_resamp_HB_fx[INTERP_3_1_MEM_LEN]; Word32 mem_resamp_HB_fx_32[INTERP_3_1_MEM_LEN]; /* IVAS 32-bit variant */ - Word16 mem_resamp_HB_32k_fx[2 * ALLPASSSECTIONS_STEEP + 1]; Word32 mem_resamp_HB_32k_fx_32[2 * ALLPASSSECTIONS_STEEP + 1]; /* IVAS 32-bit variant */ + Word32 prev_pow_exc16kWhtnd_fx32; /* power of the LB excitation signal in the previous frame */ + Word16 prev_mix_factor_fx; /* mixing factor in the previous frame */ Word16 state_32and48k_WB_upsample_fx[2 * ALLPASSSECTIONS_STEEP]; /* !!! this memory in FLP is called mem_resamp_HB */ - Word32 prev_pow_exc16kWhtnd_fx32; /* power of the LB excitation signal in the previous frame */ - Word16 prev_mix_factor_fx; /* mixing factor in the previous frame */ - Word16 syn_dm_phase; - Word32 fbbwe_hpf_mem_fx[4][4]; - Word16 fbbwe_hpf_mem_fx_Q[4]; - Word32 prev_wb_bwe_frame_pow_fx; - Word32 prev_swb_bwe_frame_pow_fx; - Word32 prev_ener_fx; - Word16 prev_GainShape_fx; - Word16 fb_state_lpc_syn_fx[LPC_SHB_ORDER]; - Word16 fb_tbe_demph_fx; - Word16 prev_fbbwe_ratio_fx; - Word16 tbe_demph_fx; - Word16 tbe_premph_fx; - Word16 mem_stp_swb_fx[LPC_SHB_ORDER]; - Word16 *ptr_mem_stp_swb_fx; - Word16 gain_prec_swb_fx; - Word16 mem_zero_swb_fx[LPC_SHB_ORDER]; Word16 swb_lsp_prev_interp_fx[LPC_SHB_ORDER]; - Word32 prev1_shb_ener_sf_fx, prev2_shb_ener_sf_fx, prev3_shb_ener_sf_fx; - Word16 prev_res_shb_gshape_fx, prev_mixFactors_fx; - Word16 tilt_mem_fx; - Word16 prev_lsf_diff_fx[LPC_SHB_ORDER - 2]; /*Q15*/ - - Word16 prev_tilt_para_fx; /*Q10*/ - - Word16 cur_sub_Aq_fx[M + 1]; /*Q12*/ - + Word16 prev_tilt_para_fx; /*Q10*/ + Word16 cur_sub_Aq_fx[M + 1]; /*Q12*/ /* quantized data */ Word16 lsf_idx[NUM_Q_LSF]; - Word16 m_idx; - Word16 grid_idx; - Word16 idxSubGains; - Word16 idxFrameGain; - Word16 idx_shb_fr_gain; - Word16 idx_res_gs[NB_SUBFR16k]; - Word16 idx_mixFac; Word16 lsf_WB; - Word16 gFrame_WB; Word16 idxGain; Word16 old_core_synth_fx[L_FRAME16k]; - Word16 old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH]; Word32 old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH]; /* IVAS 32-bit variant */ @@ -1104,7 +1055,13 @@ typedef struct td_bwe_dec_structure Word16 tilt_swb_fec_fx; /* FEC - SWB TBE TILT */ Word16 prev_hb_synth_fx_exp; - + Word16 prev_frame_pow_exp; + Word16 prev_ener_fx_Q; + Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; + Word16 prev_Q_bwe_syn; + Word16 prev_Q_bwe_syn2; + Word16 prev_Q_bwe_exc_fb; + Word16 prev_Qx; } TD_BWE_DEC_DATA, *TD_BWE_DEC_HANDLE; @@ -1132,8 +1089,9 @@ typedef struct fd_bwe_dec_structure Word16 prev_td_energy_fx; Word16 prev_weight_fx; Word16 prev_flag; - //float last_wb_bwe_ener; - //float prev_fb_ener_adjust; + Word16 last_wb_bwe_ener_fx; + Word16 prev_Q_synth; + Word16 prev_fb_ener_adjust_fx; } FD_BWE_DEC_DATA, *FD_BWE_DEC_HANDLE; @@ -1500,28 +1458,17 @@ typedef struct Decoder_State /*----------------------------------------------------------------------------------* * Fixed point only *----------------------------------------------------------------------------------*/ + Word16 Q_exc; Word16 Q_exc_cng; Word16 prev_Q_exc; Word16 Q_subfr[L_Q_MEM]; - Word16 prev_Q_bwe_syn; - Word16 prev_Q_bwe_syn2; - - Word16 prev_Q_bwe_exc_fb; - Word16 prev_Qx; - Word16 prev_Q_bwe_exc; - Word16 prev_Q_synth; - Word16 Q_syn; Word16 Q_syn2; Word16 Q_syn_cng; Word16 prev_Q_syn; - Word16 prev_frame_pow_exp; - Word16 prev_ener_fx_Q; - Word16 last_wb_bwe_ener_fx; - Word16 prev_fb_ener_adjust_fx; - Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; + Word16 prev_Q_bwe_exc; /*----------------------------------------------------------------------------------* * SWB BWE structure @@ -1638,8 +1585,6 @@ typedef struct Decoder_State Word16 classifier_Q_mem_syn; /*scalingfactor of mem_syn_clas_estim_fx in MODE2 */ Word16 rate_switching_init; - Word16 prev_widow_left_rect; // should be removed - /* LPC quantization */ Word16 lpcQuantization; Word16 numlpc; diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index af23bc98e..42d2a9cc4 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -426,7 +426,7 @@ Word16 ivas_wb_bwe_dec_fx( { /* de-quantization */ mode = WB_BWE_gain_deq_fx( st_fx, WB_fenv_fx ); - st_fx->last_wb_bwe_ener_fx = extract_l( Mpy_32_16_r( L_add( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 /*0.5f in Q15*/ ) ); + st_fx->hBWE_FD->last_wb_bwe_ener_fx = extract_l( Mpy_32_16_r( L_add( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 /*0.5f in Q15*/ ) ); move16(); } ELSE @@ -448,7 +448,7 @@ Word16 ivas_wb_bwe_dec_fx( } mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type, hBWE_FD->prev_SWB_fenv_fx[0], - voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); + voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->hBWE_FD->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); } } ELSE @@ -469,21 +469,23 @@ Word16 ivas_wb_bwe_dec_fx( } exp = norm_l( hBWE_FD->prev_Energy_wb_fx ); - IF( GT_16( add( st_fx->prev_Q_synth, exp ), Q_syn ) ) + IF( GT_16( add( hBWE_FD->prev_Q_synth, exp ), Q_syn ) ) { - hBWE_FD->prev_Energy_wb_fx = L_shr( hBWE_FD->prev_Energy_wb_fx, sub( st_fx->prev_Q_synth, Q_syn ) ); + hBWE_FD->prev_Energy_wb_fx = L_shr( hBWE_FD->prev_Energy_wb_fx, sub( hBWE_FD->prev_Q_synth, Q_syn ) ); move32(); } ELSE { - Q_syn = add( st_fx->prev_Q_synth, exp ); + Q_syn = add( hBWE_FD->prev_Q_synth, exp ); hBWE_FD->prev_Energy_wb_fx = L_shl( hBWE_FD->prev_Energy_wb_fx, exp ); move32(); } + WB_BWE_decoding_fx( ysynth_fx, WB_fenv_fx, ysynth_32, L_FRAME16k, mode, st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->extl, coder_type, st_fx->total_brate, &hBWE_FD->Seed, &hBWE_FD->prev_flag, st_fx->prev_coder_type, Q_syn, &Q_syn_hb ); + IF( EQ_32( st_fx->output_Fs, 32000 ) ) { set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME16k ); @@ -492,7 +494,9 @@ Word16 ivas_wb_bwe_dec_fx( { set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME32k ); } + Inverse_Transform( ysynth_32, &Q_syn_hb, t_audio32_tmp, 0, output_frame, output_frame, st_fx->element_mode ); + window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); @@ -502,13 +506,16 @@ Word16 ivas_wb_bwe_dec_fx( /* add HB synth from hf_synth() */ v_add_16( hb_synth_fx, synth_fx, hb_synth_fx, output_frame ); } + hBWE_FD->prev_mode = mode; move16(); - st_fx->prev_Q_synth = Q_syn; + hBWE_FD->prev_Q_synth = Q_syn; move16(); + return Q_syn_hb; } + Word16 wb_bwe_dec_fx( Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ @@ -565,7 +572,7 @@ Word16 wb_bwe_dec_fx( { /* de-quantization */ mode = WB_BWE_gain_deq_fx( st_fx, WB_fenv_fx ); - st_fx->last_wb_bwe_ener_fx = mult_r( add_sat( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 ); // this would not saturate if written like : rounf_fx(L_mac(L_mult(WB_fenv_fx[0], 16384), WB_fenv_fx[1], 16384)) + hBWE_FD->last_wb_bwe_ener_fx = mult_r( add_sat( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 ); // this would not saturate if written like : rounf_fx(L_mac(L_mult(WB_fenv_fx[0], 16384), WB_fenv_fx[1], 16384)) move16(); } ELSE @@ -589,7 +596,7 @@ Word16 wb_bwe_dec_fx( } mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type, hBWE_FD->prev_SWB_fenv_fx[0], - voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); + voice_factors_fx, pitch_buf_fx, tmp_brate, hBWE_FD->last_wb_bwe_ener_fx, Q_syn, st_fx->last_extl, st_fx->tilt_wb_fx ); } } ELSE @@ -610,21 +617,23 @@ Word16 wb_bwe_dec_fx( } exp = norm_l( hBWE_FD->prev_Energy_wb_fx ); - IF( GT_16( add( st_fx->prev_Q_synth, exp ), Q_syn ) ) + IF( GT_16( add( hBWE_FD->prev_Q_synth, exp ), Q_syn ) ) { - hBWE_FD->prev_Energy_wb_fx = L_shr( hBWE_FD->prev_Energy_wb_fx, sub( st_fx->prev_Q_synth, Q_syn ) ); + hBWE_FD->prev_Energy_wb_fx = L_shr( hBWE_FD->prev_Energy_wb_fx, sub( hBWE_FD->prev_Q_synth, Q_syn ) ); move32(); } ELSE { - Q_syn = add( st_fx->prev_Q_synth, exp ); + Q_syn = add( hBWE_FD->prev_Q_synth, exp ); hBWE_FD->prev_Energy_wb_fx = L_shl( hBWE_FD->prev_Energy_wb_fx, exp ); move32(); } + WB_BWE_decoding_fx( ysynth_fx, WB_fenv_fx, ysynth_32, L_FRAME16k, mode, st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, hBWE_FD->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->extl, coder_type, st_fx->total_brate, &hBWE_FD->Seed, &hBWE_FD->prev_flag, st_fx->prev_coder_type, Q_syn, &Q_syn_hb ); + IF( EQ_32( st_fx->output_Fs, 32000 ) ) { set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME16k ); @@ -633,13 +642,15 @@ Word16 wb_bwe_dec_fx( { set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME32k ); } + Inverse_Transform( ysynth_32, &Q_syn_hb, t_audio32_tmp, 0, output_frame, output_frame, st_fx->element_mode ); + window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); hBWE_FD->prev_mode = mode; move16(); - st_fx->prev_Q_synth = Q_syn; + hBWE_FD->prev_Q_synth = Q_syn; move16(); return Q_syn_hb; @@ -1049,11 +1060,11 @@ Word16 swb_bwe_dec_fx( } ELSE IF( st_fx->bfi ) { - fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; + fb_ener_adjust_fx = hBWE_FD->prev_fb_ener_adjust_fx; move16(); } - st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; + hBWE_FD->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; move16(); IF( EQ_16( mode, TRANSIENT ) ) { @@ -1167,8 +1178,7 @@ Word16 swb_bwe_dec_fx( * Initialize FD BWE state structure at the decoder *-------------------------------------------------------------------*/ -void fd_bwe_dec_init( - Decoder_State *st_fx, /* i/o: decoder state structure */ +void fd_bwe_dec_init_fx( FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ ) { @@ -1176,8 +1186,6 @@ void fd_bwe_dec_init( set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); hBWE_FD->old_wtda_swb_fx_exp = 0; move16(); - hBWE_FD->mem_imdct_exp_fx = 0; - move16(); hBWE_FD->prev_mode = NORMAL; move16(); @@ -1191,13 +1199,15 @@ void fd_bwe_dec_init( hBWE_FD->prev_frica_flag = 0; move16(); set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->mem_imdct_exp_fx = 0; + move16(); hBWE_FD->prev_td_energy_fx = 0; move16(); hBWE_FD->prev_weight_fx = 6554; /*0.2 in Q15*/ move16(); hBWE_FD->prev_flag = 0; move16(); - st_fx->last_wb_bwe_ener_fx = 0; + hBWE_FD->last_wb_bwe_ener_fx = 0; move16(); hBWE_FD->prev_Energy_wb_fx = L_deposit_l( 0 ); move32(); @@ -1205,12 +1215,12 @@ void fd_bwe_dec_init( move16(); /* Previous frame LPC initialization for PPP */ - st_fx->prev_Q_synth = 0; + hBWE_FD->prev_Q_synth = 0; move16(); hBWE_FD->mem_deemph_old_syn_fx = 0; move16(); - st_fx->prev_fb_ener_adjust_fx = 0; + hBWE_FD->prev_fb_ener_adjust_fx = 0; move16(); return; @@ -1411,11 +1421,11 @@ Word16 swb_bwe_dec_fx32( } ELSE IF( st_fx->bfi ) { - fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; + fb_ener_adjust_fx = hBWE_FD->prev_fb_ener_adjust_fx; move16(); } - st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; + hBWE_FD->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; move16(); IF( EQ_16( mode, TRANSIENT ) ) { @@ -1551,35 +1561,3 @@ Word16 swb_bwe_dec_fx32( return Q_syn_hb; } - - -void fd_bwe_dec_init_fx( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -) -{ - set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->prev_Energy_fx = 0; - move16(); - hBWE_FD->prev_L_swb_norm = 8; - move16(); - hBWE_FD->Seed = 21211; - move16(); - hBWE_FD->prev_frica_flag = 0; - move16(); - set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); - hBWE_FD->prev_td_energy_fx = 0; - move16(); - hBWE_FD->prev_weight_fx = 0; - move16(); - hBWE_FD->prev_flag = 0; - move16(); - hBWE_FD->prev_Energy_wb_fx = 0; - move32(); - hBWE_FD->mem_deemph_old_syn_fx = 0; - move16(); - - return; -} diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index da3df53f1..492c927b6 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -25,16 +25,8 @@ static void rescale_genWB_mem( Decoder_State *st_fx, Word16 sf ); static void Dequant_lower_LSF_fx( const Word16 lsf_idx[], Word16 lsf_q[] ); static void Map_higher_LSF_fx( Word16 lsf_q[], const Word16 m, const Word16 grid_in[] ); static void Dequant_mirror_point_fx( const Word16 lsf_q[], const Word16 m_idx, Word16 *m ); -Word16 dotp_loc( - const Word16 x[], /* i : vector x[] */ - const Word32 y[], /* i : vector y[] */ - const Word16 n /* i : vector length */ -); - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ); - +static Word16 dotp_loc( const Word16 x[], const Word32 y[], const Word16 n ); +static void find_max_mem_dec_m3( Decoder_State *st, Word16 *n_mem3 ); /* gain shape concealment code */ static void gradientGainShape( Decoder_State *st_fx, Word16 *GainShape, Word32 *GainFrame ); @@ -417,12 +409,8 @@ void rescale_genWB_mem( Decoder_State *st_fx, Word16 sf ) static void InitSWBdecBuffer_fx( - Decoder_State *st_fx /* i/o: SHB decoder structure */ -) + TD_BWE_DEC_HANDLE hBWE_TD /* TD BWE data handle */ ) { - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, ( PIT16k_MAX * 2 ) ); hBWE_TD->bwe_seed[0] = 23; move16(); @@ -447,18 +435,19 @@ static void InitSWBdecBuffer_fx( move32(); hBWE_TD->prev_swb_bwe_frame_pow_fx = 4194l /*0.001f Q22*/; /* Q22 */ move32(); - st_fx->prev_Q_bwe_exc = 31; + hBWE_TD->prev_ener_fx_Q = 31; move16(); - st_fx->prev_ener_fx_Q = 31; + hBWE_TD->prev_Qx = 0; move16(); - st_fx->prev_Qx = 0; + hBWE_TD->prev_frame_pow_exp = 0; move16(); - st_fx->prev_frame_pow_exp = 0; + hBWE_TD->prev_Q_bwe_syn = 0; move16(); - st_fx->prev_Q_bwe_syn = 0; + hBWE_TD->prev_Q_bwe_syn2 = 0; move16(); - st_fx->prev_Q_bwe_syn2 = 0; + hBWE_TD->prev_hb_synth_fx_exp = 31; move16(); + return; } @@ -783,11 +772,11 @@ void ivas_wb_tbe_dec_fx( IF( EQ_32( st_fx->extl_brate, WB_TBE_0k35 ) ) { /* convert LSPs back into LP coeffs */ - lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_LBR_WB ); + lsp2lpc_fx( lpc_wb + 1, lsf_wb, hBWE_TD->prev_lpc_wb_fx, LPC_SHB_ORDER_LBR_WB ); set16_fx( lpc_wb + LPC_SHB_ORDER_LBR_WB + 1, 0, ( LPC_SHB_ORDER_WB - LPC_SHB_ORDER_LBR_WB ) ); FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { - st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + hBWE_TD->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; move16(); } FOR( i = 1; i < LPC_SHB_ORDER_LBR_WB + 1; i++ ) @@ -801,10 +790,10 @@ void ivas_wb_tbe_dec_fx( ELSE { /* convert LSPs back into LP coeffs */ - lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_WB ); + lsp2lpc_fx( lpc_wb + 1, lsf_wb, hBWE_TD->prev_lpc_wb_fx, LPC_SHB_ORDER_WB ); FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { - st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + hBWE_TD->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; move16(); } FOR( i = 1; i < LPC_SHB_ORDER_WB + 1; i++ ) @@ -968,15 +957,15 @@ void ivas_wb_tbe_dec_fx( } curr_frame_pow_exp = add( n, n ); - IF( GT_16( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ) + IF( GT_16( hBWE_TD->prev_frame_pow_exp, curr_frame_pow_exp ) ) { - curr_frame_pow = L_shr( curr_frame_pow, sub( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ); - curr_frame_pow_exp = st_fx->prev_frame_pow_exp; + curr_frame_pow = L_shr( curr_frame_pow, sub( hBWE_TD->prev_frame_pow_exp, curr_frame_pow_exp ) ); + curr_frame_pow_exp = hBWE_TD->prev_frame_pow_exp; move16(); } ELSE { - hBWE_TD->prev_wb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_wb_bwe_frame_pow_fx, sub( curr_frame_pow_exp, st_fx->prev_frame_pow_exp ) ); + hBWE_TD->prev_wb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_wb_bwe_frame_pow_fx, sub( curr_frame_pow_exp, hBWE_TD->prev_frame_pow_exp ) ); move32(); } @@ -1032,7 +1021,7 @@ void ivas_wb_tbe_dec_fx( hBWE_TD->prev_wb_bwe_frame_pow_fx = curr_frame_pow; move32(); - st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + hBWE_TD->prev_frame_pow_exp = curr_frame_pow_exp; move16(); /* generate 16kHz SHB signal (6 - 8 kHz) from 2kHz signal */ @@ -1090,8 +1079,10 @@ void ivas_wb_tbe_dec_fx( } n_mem = s_max( n_mem, 0 ); - if ( GT_16( sub( Qx, st_fx->prev_Qx ), n_mem ) ) - Qx = add( st_fx->prev_Qx, n_mem ); + if ( GT_16( sub( Qx, hBWE_TD->prev_Qx ), n_mem ) ) + { + Qx = add( hBWE_TD->prev_Qx, n_mem ); + } FOR( i = 0; i < ( L_FRAME16k + L_SHB_LAHEAD ) / 4; i++ ) { @@ -1101,13 +1092,13 @@ void ivas_wb_tbe_dec_fx( FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { - hBWE_TD->state_lsyn_filt_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + hBWE_TD->state_lsyn_filt_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_shb_fx[i], sub( Qx, hBWE_TD->prev_Qx ) ); move16(); } FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { - hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i], sub( Qx, hBWE_TD->prev_Qx ) ); move16(); } @@ -1121,56 +1112,58 @@ void ivas_wb_tbe_dec_fx( move16(); } - max = 0; - move16(); - FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) - { - max = s_max( max, abs_s( synth[cnt] ) ); - } - - IF( max == 0 ) + IF( st_fx->hBWE_FD != NULL ) { - st_fx->last_wb_bwe_ener_fx = 0; + max = 0; move16(); - } - ELSE - { - n = norm_s( max ); FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) { - synth_frac[cnt] = shl( synth[cnt], n ); /*Q14*/ - move16(); + max = s_max( max, abs_s( synth[cnt] ) ); } - n = sub( sub( 14, n ), Qx ); - Lacc = 0; - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) + IF( max == 0 ) { - L_tmp = L_mult( synth_frac[i], synth_frac[i] ); /* Q29 */ - Lacc = L_add( Lacc, L_shr( L_tmp, 7 ) ); /* Q22 */ + st_fx->hBWE_FD->last_wb_bwe_ener_fx = 0; + move16(); } + ELSE + { + n = norm_s( max ); + FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + { + synth_frac[cnt] = shl( synth[cnt], n ); /*Q14*/ + move16(); + } + n = sub( sub( 14, n ), Qx ); - L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ - exp = norm_l( L_tmp ); - tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); - exp = sub( add( exp, 22 ), 30 ); - tmp = div_s( 16384, tmp ); - L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ - st_fx->last_wb_bwe_ener_fx = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ - move16(); - } + Lacc = 0; + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult( synth_frac[i], synth_frac[i] ); /* Q29 */ + Lacc = L_add( Lacc, L_shr( L_tmp, 7 ) ); /* Q22 */ + } + L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ + exp = norm_l( L_tmp ); + tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); + exp = sub( add( exp, 22 ), 30 ); + tmp = div_s( 16384, tmp ); + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ + st_fx->hBWE_FD->last_wb_bwe_ener_fx = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ + move16(); + } + } IF( EQ_32( st_fx->output_Fs, 32000 ) ) /* 32kHz sampling rate, but only WB output - interpolate */ { - Scale_sig( hBWE_TD->state_32and48k_WB_upsample_fx, 2 * ALLPASSSECTIONS_STEEP, sub( Qx, st_fx->prev_Qx ) ); + Scale_sig( hBWE_TD->state_32and48k_WB_upsample_fx, 2 * ALLPASSSECTIONS_STEEP, sub( Qx, hBWE_TD->prev_Qx ) ); Interpolate_allpass_steep_fx( synth, hBWE_TD->state_32and48k_WB_upsample_fx, L_FRAME16k, upsampled_synth ); Copy( upsampled_synth, synth, L_FRAME32k ); } ELSE IF( EQ_32( st_fx->output_Fs, 48000 ) ) { - Scale_sig( hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( Qx, st_fx->prev_Qx ) ); + Scale_sig( hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( Qx, hBWE_TD->prev_Qx ) ); ivas_interpolate_3_over_1_allpass_fx( synth, L_FRAME16k, upsampled_synth, hBWE_TD->mem_resamp_HB_fx ); Copy( upsampled_synth, synth, L_FRAME48k ); } @@ -1196,7 +1189,7 @@ void ivas_wb_tbe_dec_fx( move16(); hBWE_TD->prev_wb_bwe_frame_pow_fx = 4194l /*0.001f Q22*/; /* Q22 */ move32(); - st_fx->prev_frame_pow_exp = 0; + hBWE_TD->prev_frame_pow_exp = 0; move16(); } @@ -1223,7 +1216,7 @@ void ivas_wb_tbe_dec_fx( st_fx->prev_Q_bwe_exc = Q_bwe_exc; move16(); - st_fx->prev_Qx = Qx; + hBWE_TD->prev_Qx = Qx; move16(); return; @@ -1421,11 +1414,11 @@ void wb_tbe_dec_fx( IF( EQ_32( st_fx->extl_brate, WB_TBE_0k35 ) ) { /* convert LSPs back into LP coeffs */ - lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_LBR_WB ); + lsp2lpc_fx( lpc_wb + 1, lsf_wb, hBWE_TD->prev_lpc_wb_fx, LPC_SHB_ORDER_LBR_WB ); set16_fx( lpc_wb + LPC_SHB_ORDER_LBR_WB + 1, 0, LPC_SHB_ORDER_WB - LPC_SHB_ORDER_LBR_WB ); FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { - st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + hBWE_TD->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; move16(); } FOR( i = 1; i < LPC_SHB_ORDER_LBR_WB + 1; i++ ) @@ -1439,10 +1432,10 @@ void wb_tbe_dec_fx( ELSE { /* convert LSPs back into LP coeffs */ - lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_WB ); + lsp2lpc_fx( lpc_wb + 1, lsf_wb, hBWE_TD->prev_lpc_wb_fx, LPC_SHB_ORDER_WB ); FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { - st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + hBWE_TD->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; move16(); } FOR( i = 1; i < LPC_SHB_ORDER_WB + 1; i++ ) @@ -1606,15 +1599,15 @@ void wb_tbe_dec_fx( } curr_frame_pow_exp = add( n, n ); - IF( GT_16( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ) + IF( GT_16( hBWE_TD->prev_frame_pow_exp, curr_frame_pow_exp ) ) { - curr_frame_pow = L_shr( curr_frame_pow, sub( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ); - curr_frame_pow_exp = st_fx->prev_frame_pow_exp; + curr_frame_pow = L_shr( curr_frame_pow, sub( hBWE_TD->prev_frame_pow_exp, curr_frame_pow_exp ) ); + curr_frame_pow_exp = hBWE_TD->prev_frame_pow_exp; move16(); } ELSE { - hBWE_TD->prev_wb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_wb_bwe_frame_pow_fx, sub( curr_frame_pow_exp, st_fx->prev_frame_pow_exp ) ); + hBWE_TD->prev_wb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_wb_bwe_frame_pow_fx, sub( curr_frame_pow_exp, hBWE_TD->prev_frame_pow_exp ) ); move32(); } @@ -1668,7 +1661,7 @@ void wb_tbe_dec_fx( hBWE_TD->prev_wb_bwe_frame_pow_fx = curr_frame_pow; move32(); - st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + hBWE_TD->prev_frame_pow_exp = curr_frame_pow_exp; move16(); /* generate 16kHz SHB signal (6 - 8 kHz) from 2kHz signal */ @@ -1695,13 +1688,17 @@ void wb_tbe_dec_fx( FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { if ( GT_16( abs_s( hBWE_TD->state_lsyn_filt_shb_fx[i] ), max ) ) + { max = abs_s( hBWE_TD->state_lsyn_filt_shb_fx[i] ); + } } FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { if ( GT_16( abs_s( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] ), max ) ) + { max = abs_s( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] ); + } } IF( EQ_32( st_fx->output_Fs, 32000 ) ) @@ -1726,8 +1723,10 @@ void wb_tbe_dec_fx( } n_mem = s_max( n_mem, 0 ); - if ( GT_16( sub( Qx, st_fx->prev_Qx ), n_mem ) ) - Qx = add( st_fx->prev_Qx, n_mem ); + if ( GT_16( sub( Qx, hBWE_TD->prev_Qx ), n_mem ) ) + { + Qx = add( hBWE_TD->prev_Qx, n_mem ); + } FOR( i = 0; i < ( L_FRAME16k + L_SHB_LAHEAD ) / 4; i++ ) { @@ -1737,13 +1736,13 @@ void wb_tbe_dec_fx( FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { - hBWE_TD->state_lsyn_filt_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + hBWE_TD->state_lsyn_filt_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_shb_fx[i], sub( Qx, hBWE_TD->prev_Qx ) ); move16(); } FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) { - hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] = shl( hBWE_TD->state_lsyn_filt_dwn_shb_fx[i], sub( Qx, hBWE_TD->prev_Qx ) ); move16(); } @@ -1757,56 +1756,58 @@ void wb_tbe_dec_fx( move16(); } - max = 0; - move16(); - FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + IF( st_fx->hBWE_FD != NULL ) { - max = s_max( max, abs_s( synth[cnt] ) ); - } - - IF( max == 0 ) - { - st_fx->last_wb_bwe_ener_fx = 0; + max = 0; move16(); - } - ELSE - { - n = norm_s( max ); FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) { - synth_frac[cnt] = shl( synth[cnt], n ); /*Q14*/ - move16(); + max = s_max( max, abs_s( synth[cnt] ) ); } - n = sub( sub( 14, n ), Qx ); - Lacc = 0; - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) + IF( max == 0 ) { - L_tmp = L_mult( synth_frac[i], synth_frac[i] ); /* Q29 */ - Lacc = L_add( Lacc, L_shr( L_tmp, 7 ) ); /* Q22 */ + st_fx->hBWE_FD->last_wb_bwe_ener_fx = 0; + move16(); } + ELSE + { + n = norm_s( max ); + FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + { + synth_frac[cnt] = shl( synth[cnt], n ); /*Q14*/ + move16(); + } + n = sub( sub( 14, n ), Qx ); - L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ - exp = norm_l( L_tmp ); - tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); - exp = sub( add( exp, 22 ), 30 ); - tmp = div_s( 16384, tmp ); - L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ - st_fx->last_wb_bwe_ener_fx = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ - move16(); - } + Lacc = 0; + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult( synth_frac[i], synth_frac[i] ); /* Q29 */ + Lacc = L_add( Lacc, L_shr( L_tmp, 7 ) ); /* Q22 */ + } + L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ + exp = norm_l( L_tmp ); + tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); + exp = sub( add( exp, 22 ), 30 ); + tmp = div_s( 16384, tmp ); + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ + st_fx->hBWE_FD->last_wb_bwe_ener_fx = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ + move16(); + } + } IF( EQ_32( st_fx->output_Fs, 32000 ) ) /* 32kHz sampling rate, but only WB output - interpolate */ { - Scale_sig( hBWE_TD->state_32and48k_WB_upsample_fx, 2 * ALLPASSSECTIONS_STEEP, sub( Qx, st_fx->prev_Qx ) ); + Scale_sig( hBWE_TD->state_32and48k_WB_upsample_fx, 2 * ALLPASSSECTIONS_STEEP, sub( Qx, hBWE_TD->prev_Qx ) ); Interpolate_allpass_steep_fx( synth, hBWE_TD->state_32and48k_WB_upsample_fx, L_FRAME16k, upsampled_synth ); Copy( upsampled_synth, synth, L_FRAME32k ); } ELSE IF( EQ_32( st_fx->output_Fs, 48000 ) ) { - Scale_sig( hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( Qx, st_fx->prev_Qx ) ); + Scale_sig( hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( Qx, hBWE_TD->prev_Qx ) ); interpolate_3_over_1_allpass_fx( synth, L_FRAME16k, upsampled_synth, hBWE_TD->mem_resamp_HB_fx ); Copy( upsampled_synth, synth, L_FRAME48k ); } @@ -1832,7 +1833,7 @@ void wb_tbe_dec_fx( move16(); hBWE_TD->prev_wb_bwe_frame_pow_fx = 4194l /*0.001f Q22*/; /* Q22 */ move32(); - st_fx->prev_frame_pow_exp = 0; + hBWE_TD->prev_frame_pow_exp = 0; move16(); } @@ -1859,7 +1860,7 @@ void wb_tbe_dec_fx( st_fx->prev_Q_bwe_exc = Q_bwe_exc; move16(); - st_fx->prev_Qx = Qx; + hBWE_TD->prev_Qx = Qx; move16(); return; @@ -2626,7 +2627,7 @@ void swb_tbe_dec_fx( Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ /* -------- end of rescaling memories -------- */ - Q_bwe_exc_fb = st_fx->prev_Q_bwe_exc_fb; + Q_bwe_exc_fb = hBWE_TD->prev_Q_bwe_exc_fb; move16(); IF( GT_32( st_fx->total_brate, ACELP_32k ) ) @@ -2643,26 +2644,26 @@ void swb_tbe_dec_fx( coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified, st_fx->extl, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf, shb_ener_sf_32, shb_res_gshape, shb_res_dummy, &vind, formant_fac, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, st_fx->prev_bfi ); + &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, hBWE_TD->prev_Q_bwe_syn, st_fx->total_brate, st_fx->prev_bfi ); *Q_white_exc = Q_bwe_exc_fb; move16(); IF( EQ_16( st_fx->extl, FB_TBE ) ) { - st_fx->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + hBWE_TD->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; move16(); } ELSE { /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ - st_fx->prev_Q_bwe_exc_fb = 51; + hBWE_TD->prev_Q_bwe_exc_fb = 51; move16(); } /* rescale the TBE post proc memory */ FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - hBWE_TD->mem_stp_swb_fx[i] = shl( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st_fx->prev_Q_bwe_syn ) ); + hBWE_TD->mem_stp_swb_fx[i] = shl( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, hBWE_TD->prev_Q_bwe_syn ) ); move16(); } @@ -2688,11 +2689,7 @@ void swb_tbe_dec_fx( curr_pow = L_shr( curr_pow, 2 ); /* Q(2*Q_bwe_exc) */ } - Lscale = root_a_over_b_fx( curr_pow, - shl( Q_bwe_exc, 1 ), - prev_pow, - shl( Q_bwe_exc, 1 ), - &exp ); + Lscale = root_a_over_b_fx( curr_pow, shl( Q_bwe_exc, 1 ), prev_pow, shl( Q_bwe_exc, 1 ), &exp ); FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { @@ -3021,7 +3018,7 @@ void swb_tbe_dec_fx( /* if( ener_tmp_fx[i]*GainShape_tmp_fx[i] > st_fx->prev_ener_fx*st_fx->prev_GainShape_fx ) */ L_tmp1 = Mult_32_16( ener_tmp[i], GainShape_tmp[i] ); /* (2*Q_bwe_exc) */ L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st_fx->prev_ener_fx_Q) */ - tmp = sub( shl( Q_bwe_exc, 1 ), shl( st_fx->prev_ener_fx_Q, 1 ) ); + tmp = sub( shl( Q_bwe_exc, 1 ), shl( hBWE_TD->prev_ener_fx_Q, 1 ) ); L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ IF( GT_32( L_tmp1, L_tmp2 ) ) { @@ -3057,7 +3054,7 @@ void swb_tbe_dec_fx( move32(); hBWE_TD->prev_GainShape_fx = GainShape_tmp[i]; move16(); - st_fx->prev_ener_fx_Q = Q_bwe_exc; + hBWE_TD->prev_ener_fx_Q = Q_bwe_exc; move16(); } FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) @@ -3074,13 +3071,13 @@ void swb_tbe_dec_fx( } ELSE { - st_fx->prev_ener_fx_Q = Q_bwe_exc; + hBWE_TD->prev_ener_fx_Q = Q_bwe_exc; move16(); } /* Back up the Q_bwe_exc associated with shaped_shb_excitation for the next frame*/ - st_fx->prev_Q_bwe_syn = Q_bwe_exc; + hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); /* Scale the shaped excitation */ @@ -3091,13 +3088,7 @@ void swb_tbe_dec_fx( GainFrame, /* Q18 */ window_shb_fx, subwin_shb_fx, - &Q_bwe_exc, &Qx, n_mem3, st_fx->prev_Q_bwe_syn2 ); - /* i: GainShape Q15 */ - /* i: GainFrame Q18 */ - /* i: shaped_shb_excitation Q_bwe_exc */ - /* o: shaped_shb_excitation Q_bwe_exc */ - /* o: st_fx->syn_overlap_fx Q_bwe_exc */ - + &Q_bwe_exc, &Qx, n_mem3, hBWE_TD->prev_Q_bwe_syn2 ); max = 0; move16(); @@ -3135,31 +3126,31 @@ void swb_tbe_dec_fx( curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); - tmp = sub( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ); + tmp = sub( hBWE_TD->prev_frame_pow_exp, curr_frame_pow_exp ); IF( tmp > 0 ) /* shifting prev */ { IF( GT_16( tmp, 32 ) ) { - st_fx->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); + hBWE_TD->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); move16(); tmp = 32; move16(); } hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); move32(); - st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + hBWE_TD->prev_frame_pow_exp = curr_frame_pow_exp; move16(); } ELSE /* shifting curr */ { IF( LT_16( tmp, -32 ) ) { - curr_frame_pow_exp = sub( st_fx->prev_frame_pow_exp, 32 ); + curr_frame_pow_exp = sub( hBWE_TD->prev_frame_pow_exp, 32 ); tmp = -32; move16(); } curr_frame_pow = L_shr( curr_frame_pow, -tmp ); - curr_frame_pow_exp = st_fx->prev_frame_pow_exp; + curr_frame_pow_exp = hBWE_TD->prev_frame_pow_exp; move16(); } test(); @@ -3324,10 +3315,9 @@ void swb_tbe_dec_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow; move32(); - st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + hBWE_TD->prev_frame_pow_exp = curr_frame_pow_exp; move16(); - { Word64 prev_ener_shb64 = 0; move64(); @@ -3338,7 +3328,6 @@ void swb_tbe_dec_fx( L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); } - /* st->prev_ener_shb = sqrt(st->prev_ener_shb/L_FRAME16k) */ L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ st_fx->prev_ener_shb_fx = 0; @@ -3374,7 +3363,7 @@ void swb_tbe_dec_fx( set16_fx( st_fx->hBWE_FD->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ /* rescale the memories if Q_bwe_exc is different from previous frame */ - sc = sub( Q_bwe_exc, st_fx->prev_Q_bwe_syn2 ); + sc = sub( Q_bwe_exc, hBWE_TD->prev_Q_bwe_syn2 ); IF( sc != 0 ) { FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) @@ -3537,10 +3526,11 @@ void swb_tbe_dec_fx( move32(); *Q_synth = Q_bwe_exc; move16(); - st_fx->prev_Q_bwe_syn2 = Q_bwe_exc; + hBWE_TD->prev_Q_bwe_syn2 = Q_bwe_exc; move16(); - st_fx->prev_Qx = Q_bwe_exc; + hBWE_TD->prev_Qx = Q_bwe_exc; move16(); + return; } @@ -3834,7 +3824,9 @@ static void Dequant_mirror_point_fx( return; } -Word16 dotp_loc( + + +static Word16 dotp_loc( const Word16 x[], /* i : vector x[] Qx */ const Word32 y[], /* i : vector y[] Qy */ const Word16 n /* i : vector length */ @@ -4993,7 +4985,6 @@ void GenTransition_fx32( void GenTransition_WB_fx( TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const Word16 prev_Qx, /* i : scaling of old_hb_synth */ Word16 *output, /* o : synthesized transitions signal */ const Word32 output_Fs /* i : output sampling rate */ ) @@ -5008,7 +4999,7 @@ void GenTransition_WB_fx( length = shl( NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ), 1 ); /* upsample overlap snippet */ - Copy_Scale_sig( hBWE_TD->syn_overlap_fx, input_scaled, SHB_OVERLAP_LEN / 2, prev_Qx ); + Copy_Scale_sig( hBWE_TD->syn_overlap_fx, input_scaled, SHB_OVERLAP_LEN / 2, hBWE_TD->prev_Qx ); Interpolate_allpass_steep_fx( input_scaled, hBWE_TD->state_lsyn_filt_shb_fx, SHB_OVERLAP_LEN / 2, speech_buf_16k1 ); Interpolate_allpass_steep_fx( speech_buf_16k1, hBWE_TD->state_lsyn_filt_dwn_shb_fx, SHB_OVERLAP_LEN, speech_buf_16k2 ); @@ -5175,7 +5166,7 @@ void TBEreset_dec_fx( { if ( st_fx->hBWE_FD != NULL ) { - st_fx->prev_fb_ener_adjust_fx = 0; + st_fx->hBWE_FD->prev_fb_ener_adjust_fx = 0; move16(); } set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); @@ -5196,18 +5187,18 @@ void TBEreset_dec_fx( *-------------------------------------------------------------------*/ void td_bwe_dec_init_fx( - Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + const Word16 extl, /* i : BWE extension layer */ const Word32 output_Fs /* i : output sampling rate */ ) { Word16 i; /* init. SHB buffers */; - InitSWBdecBuffer_fx( st_fx ); + InitSWBdecBuffer_fx( hBWE_TD ); /* reset SHB buffers */ - ResetSHBbuffer_Dec_fx( hBWE_TD, st_fx->extl ); + ResetSHBbuffer_Dec_fx( hBWE_TD, extl ); IF( EQ_32( output_Fs, 48000 ) ) { @@ -5254,7 +5245,7 @@ void td_bwe_dec_init_fx( move16(); hBWE_TD->prev_GainShape_fx = 0; move16(); - st_fx->prev_Q_bwe_exc_fb = 51; + hBWE_TD->prev_Q_bwe_exc_fb = 51; move16(); set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); hBWE_TD->fb_tbe_demph_fx = 0; @@ -5265,6 +5256,8 @@ void td_bwe_dec_init_fx( hBWE_TD->prev_ener_fx = L_deposit_l( 0 ); move32(); + set16_fx( hBWE_TD->prev_lpc_wb_fx, 0, LPC_SHB_ORDER_WB ); + return; } @@ -5403,9 +5396,11 @@ static void rescale_genSHB_mem_dec_ivas( move16(); hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); move16(); + + return; } -void find_max_mem_dec_m3( +static void find_max_mem_dec_m3( Decoder_State *st, Word16 *n_mem3 ) { @@ -6190,7 +6185,7 @@ void ivas_swb_tbe_dec_fx( /* -------- end of rescaling memories -------- */ - Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; + Q_bwe_exc_fb = hBWE_TD->prev_Q_bwe_exc_fb; move16(); Q_shb = 0; @@ -6202,7 +6197,7 @@ void ivas_swb_tbe_dec_fx( st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, + &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, hBWE_TD->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); @@ -6210,21 +6205,21 @@ void ivas_swb_tbe_dec_fx( move16(); IF( EQ_16( st->extl, FB_TBE ) ) { - st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + hBWE_TD->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; move16(); } ELSE { /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ - st->prev_Q_bwe_exc_fb = 51; + hBWE_TD->prev_Q_bwe_exc_fb = 51; move16(); } /* rescale the TBE post proc memory */ FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); + hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, hBWE_TD->prev_Q_bwe_syn ) ); move16(); } /* fill-in missing SHB excitation */ @@ -6266,11 +6261,7 @@ void ivas_swb_tbe_dec_fx( curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ } - Lscale = root_a_over_b_fx( curr_pow_fx, - shl( Q_bwe_exc, 1 ), - prev_pow_fx, - shl( Q_bwe_exc, 1 ), - &exp ); + Lscale = root_a_over_b_fx( curr_pow_fx, shl( Q_bwe_exc, 1 ), prev_pow_fx, shl( Q_bwe_exc, 1 ), &exp ); FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { @@ -6601,7 +6592,7 @@ void ivas_swb_tbe_dec_fx( { L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ - tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); + tmp = sub( shl( Q_bwe_exc, 1 ), shl( hBWE_TD->prev_ener_fx_Q, 1 ) ); L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ IF( GT_32( L_tmp1, L_tmp2 ) ) { @@ -6635,7 +6626,7 @@ void ivas_swb_tbe_dec_fx( move32(); hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; move16(); - st->prev_ener_fx_Q = Q_bwe_exc; + hBWE_TD->prev_ener_fx_Q = Q_bwe_exc; move16(); } @@ -6653,10 +6644,10 @@ void ivas_swb_tbe_dec_fx( } ELSE { - st->prev_ener_fx_Q = Q_bwe_exc; + hBWE_TD->prev_ener_fx_Q = Q_bwe_exc; move16(); } - st->prev_Q_bwe_syn = Q_bwe_exc; + hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); @@ -6722,7 +6713,7 @@ void ivas_swb_tbe_dec_fx( GainFrame_fx, /* Q18 */ window_shb_fx, subwin_shb_fx, - &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); + &Q_bwe_exc, &Qx, n_mem3_new, hBWE_TD->prev_Q_bwe_syn2 ); IF( hStereoICBWE != NULL ) { @@ -6767,31 +6758,31 @@ void ivas_swb_tbe_dec_fx( } } curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); - tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); + tmp = sub( hBWE_TD->prev_frame_pow_exp, curr_frame_pow_exp ); IF( tmp > 0 ) /* shifting prev */ { IF( GT_16( tmp, 32 ) ) { - st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); + hBWE_TD->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); move16(); tmp = 32; move16(); } hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; + hBWE_TD->prev_frame_pow_exp = curr_frame_pow_exp; move16(); } ELSE /* shifting curr */ { IF( LT_16( tmp, -32 ) ) { - curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); + curr_frame_pow_exp = sub( hBWE_TD->prev_frame_pow_exp, 32 ); tmp = -32; move16(); } curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); - curr_frame_pow_exp = st->prev_frame_pow_exp; + curr_frame_pow_exp = hBWE_TD->prev_frame_pow_exp; move16(); } test(); @@ -6957,7 +6948,7 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; + hBWE_TD->prev_frame_pow_exp = curr_frame_pow_exp; move16(); Word64 prev_ener_shb64 = 0; @@ -7140,9 +7131,9 @@ void ivas_swb_tbe_dec_fx( move32(); hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; move16(); - st->prev_Q_bwe_syn2 = Q_bwe_exc; + hBWE_TD->prev_Q_bwe_syn2 = Q_bwe_exc; move16(); - st->prev_Qx = Q_bwe_exc; + hBWE_TD->prev_Qx = Q_bwe_exc; move16(); return; diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 42a9e1ede..0e1b951bb 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -259,7 +259,7 @@ void updt_IO_switch_dec_fx( IF( EQ_16( output_frame, L_FRAME48k ) ) { - st_fx->prev_fb_ener_adjust_fx = 0; + hBWE_FD->prev_fb_ener_adjust_fx = 0; move16(); set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); hBWE_TD->fb_tbe_demph_fx = 0; -- GitLab From 65c894a0ec01a2d6ba477c7360060692f47bd3b4 Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 19:16:06 +0100 Subject: [PATCH 0461/1221] harmonize HQ struct members + cleaning in stat_dec.h --- lib_com/prot_fx.h | 8 +- lib_com/stat_com.h | 15 -- lib_dec/core_switching_dec_fx.c | 8 +- lib_dec/evs_dec_fx.c | 14 +- lib_dec/hq_core_dec_fx.c | 6 +- lib_dec/ivas_core_dec_fx.c | 18 +- lib_dec/ivas_cpe_dec_fx.c | 12 +- lib_dec/ivas_jbm_dec_fx.c | 36 ++-- lib_dec/ivas_mct_dec_fx.c | 4 +- lib_dec/ivas_post_proc_fx.c | 6 +- lib_dec/ivas_stereo_switching_dec_fx.c | 16 +- lib_dec/stat_dec.h | 277 ++++++------------------- lib_dec/tonalMDCTconcealment_fx.c | 35 ++-- 13 files changed, 147 insertions(+), 308 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index f9c69e8d6..c4bc98162 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6562,7 +6562,7 @@ void TonalMDCTConceal_SaveFreqSignal_ivas_fx( const Word16 gain_tcx_exp, const Word16 infoIGFStartLine ); -TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState( +void TonalMDCTConceal_UpdateState( TonalMDCTConcealPtr self, Word16 nNewSamples, Word32 pitchLag, @@ -9600,9 +9600,9 @@ ivas_error acelp_core_dec_fx( // evs_dec_fx.c ivas_error evs_dec_fx( - Decoder_State *st_fx, /* i/o : Decoder state structure */ - Word16 output_sp[], /* o : output synthesis signal */ - frameMode_fx frameMode /* i : Decoder frame mode */ + Decoder_State *st_fx, /* i/o : Decoder state structure */ + Word16 output_sp[], /* o : output synthesis signal */ + FRAME_MODE frameMode /* i : Decoder frame mode */ ); void fft_cldfb_fx( diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index c96dcc884..f99d49802 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -693,21 +693,6 @@ typedef enum /*---------------------------------------------------------------* * IGF * *---------------------------------------------------------------*/ -/*----------------------------------------------------------------------------------* - * NB postfilter / formant postfilter static variables - *----------------------------------------------------------------------------------*/ -typedef struct pfstat_structure -{ - Word16 on; /* On/off flag */ - Word16 reset; /* reset flag */ - Word16 mem_pf_in[L_SUBFR]; /* Input memory Qqmem_pf_in */ - Word16 mem_stp[L_SUBFR]; /* 1/A(gamma1) memory Qqmem_stp*/ - Word16 mem_res2[DECMEM_RES2]; /* A(gamma2) residual Q_syn*/ - Word16 mem_zero[M]; /* null memory to compute i.r. of A(gamma2)/A(gamma1) Q_qmem_zero*/ - Word16 gain_prec; /*Q14*/ /* for gain adjustment */ - -} PFSTAT, *PFSTAT_HANDLE; - typedef struct { diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 0bef8c97b..b913dedb1 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -2315,7 +2315,7 @@ ivas_error core_switching_pre_dec_ivas_fx( st->hHQ_core->last_max_pos_pulse = 0; move16(); - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + set16_fx( st->hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM ); st->hHQ_core->prev_frm_hfe2 = 0; st->hHQ_core->prev_stab_hfe2 = 0; move16(); @@ -2681,7 +2681,7 @@ ivas_error core_switching_pre_dec_ivas_fx( st->hHQ_core->last_max_pos_pulse = 0; move16(); - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + set16_fx( st->hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM ); st->hHQ_core->prev_frm_hfe2 = 0; st->hHQ_core->prev_stab_hfe2 = 0; move16(); @@ -2702,7 +2702,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) { set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + set32_fx( st->hHQ_core->old_out_LB_fx32, 0, L_FRAME16k ); set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); } @@ -2724,7 +2724,7 @@ ivas_error core_switching_pre_dec_ivas_fx( ELSE { set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + set32_fx( st->hHQ_core->old_out_LB_fx32, 0, L_FRAME16k ); } } diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 5797a6b5a..74340b530 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -16,9 +16,9 @@ *--------------------------------------------------------------------------*/ ivas_error evs_dec_fx( - Decoder_State *st_fx, /* i/o : Decoder state structure */ - Word16 output_sp[], /* o : output synthesis signal Q0*/ - frameMode_fx frameMode /* i : Decoder frame mode */ + Decoder_State *st_fx, /* i/o : Decoder state structure */ + Word16 output_sp[], /* o : output synthesis signal Q0*/ + FRAME_MODE frameMode /* i : Decoder frame mode */ ) { Word16 i, j, output_frame; @@ -863,16 +863,16 @@ ivas_error evs_dec_fx( IF( ( EQ_16( st_fx->bwidth, SWB ) || EQ_16( st_fx->bwidth, FB ) ) && ( ( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) ) && EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) { - GenTransition_fx( st_fx->hBWE_TD, hb_synth_fx, st_fx->output_Fs, st_fx->rf_flag, st_fx->total_brate ); + GenTransition_fx( hBWE_TD, hb_synth_fx, st_fx->output_Fs, st_fx->rf_flag, st_fx->total_brate ); - hb_synth_fx_exp = st_fx->hBWE_TD->prev_Q_bwe_syn2; + hb_synth_fx_exp = hBWE_TD->prev_Q_bwe_syn2; move16(); } ELSE IF( EQ_16( st_fx->bwidth, WB ) && EQ_16( st_fx->last_extl, WB_TBE ) ) { - GenTransition_WB_fx( st_fx->hBWE_TD, hb_synth_fx, st_fx->output_Fs ); + GenTransition_WB_fx( hBWE_TD, hb_synth_fx, st_fx->output_Fs ); - hb_synth_fx_exp = st_fx->hBWE_TD->prev_Qx; + hb_synth_fx_exp = hBWE_TD->prev_Qx; move16(); } diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 0abb75592..714245514 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -1201,17 +1201,15 @@ void HQ_core_dec_init_fx( ) { set16_fx( hHQ_core->old_out_fx, 0, L_FRAME48k ); + set32_fx( hHQ_core->old_out_fx32, 0, L_FRAME48k ); set16_fx( hHQ_core->old_out_LB_fx, 0, L_FRAME32k ); - set32_fx( hHQ_core->oldOut_fx, 0, L_FRAME48k ); - set32_fx( hHQ_core->old_outLB_fx, 0, L_FRAME32k ); + set32_fx( hHQ_core->old_out_LB_fx32, 0, L_FRAME32k ); hHQ_core->Q_old_wtda = 15; hHQ_core->Q_old_postdec = 0; hHQ_core->Q_old_wtda_LB = 0; move16(); move16(); move16(); - move16(); - move16(); hHQ_core->last_hq_core_type = -1; /* Q0 */ move16(); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 83d1d1187..37c32a8b1 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -337,12 +337,12 @@ ivas_error ivas_core_dec_fx( IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 #endif - L_lerp_fx_q11( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_outLB_fx, sts[0]->L_frame, sts[0]->last_L_frame ); - Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda_LB + L_lerp_fx_q11( sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->L_frame, sts[0]->last_L_frame ); + Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda_LB } IF( NE_16( sts[0]->L_frame, L_FRAME16k ) ) { @@ -530,7 +530,7 @@ ivas_error ivas_core_dec_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 #else - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 #endif Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 IF( st->cldfbAna ) @@ -1477,11 +1477,11 @@ ivas_error ivas_core_dec_fx( IF( st->hHQ_core != NULL ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 #endif } diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 0bd3092a5..8e25e5116 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -125,9 +125,9 @@ ivas_error ivas_cpe_dec_fx( IF( hCPE->hCoreCoder[ind1] && hCPE->hCoreCoder[ind1]->hHQ_core ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 #endif } } @@ -136,9 +136,9 @@ ivas_error ivas_cpe_dec_fx( IF( hCPE->hCoreCoder[ind1]->hHQ_core ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 #else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 #endif hCPE->hCoreCoder[ind1]->hHQ_core->q_old_outLB_fx = Q11; move16(); @@ -155,7 +155,7 @@ ivas_error ivas_cpe_dec_fx( test(); IF( hCPE->hCoreCoder[ind1] && hCPE->hCoreCoder[ind1]->hHQ_core ) { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[ind1]->hHQ_core->oldOut_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda, Q11 ) ); // Q_old_wtda + Copy_Scale_sig_32_16( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda, Q11 ) ); // Q_old_wtda } } FOR( Word16 ind1 = 0; ind1 < 2; ind1++ ) @@ -163,7 +163,7 @@ ivas_error ivas_cpe_dec_fx( test(); IF( hCPE->hCoreCoder[ind1] && hCPE->hCoreCoder[ind1]->hHQ_core ) { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[ind1]->hHQ_core->old_outLB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda + Copy_Scale_sig_32_16( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda } } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index d111b4ac4..5b46df06e 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -435,11 +435,11 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q #else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q #endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); @@ -550,8 +550,8 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB - q ); // Q_old_wtda_LB - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda - q ); // Q_old_wtda_LB + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB - q ); // Q_old_wtda_LB + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda - q ); // Q_old_wtda_LB } IF( hCPE->hStereoDft != NULL ) { @@ -972,11 +972,11 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q #else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q #endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); @@ -1033,8 +1033,8 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda } IF( hCPE->hStereoDft != NULL ) { @@ -1432,11 +1432,11 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { #ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q #else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q #endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); @@ -1496,8 +1496,8 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda } IF( hCPE->hStereoDft != NULL ) { diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 98b1e02f2..4eb0ad686 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -411,10 +411,10 @@ ivas_error ivas_mct_dec_fx( { #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->oldOut_fx, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); #else Copy_Scale_sig_16_32_DEPREC( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->oldOut_fx, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); #endif ivas_post_proc_fx( NULL, hCPE, n, synth_fx_32[n], NULL, output_frame, 1, Q11 ); #ifdef MSAN_FIX diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 13fcb6183..3361d8b14 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -112,7 +112,7 @@ void ivas_post_proc_fx( { Word16 numZeros = (Word16) ( NS2SA_FX2( output_Fs, N_ZERO_MDCT_NS ) ); /*Q0*/ move16(); - Copy32( sts[n]->hHQ_core->oldOut_fx + numZeros, sts[n]->hTcxDec->FBTCXdelayBuf_32, delay_comp ); /*Q11*/ + Copy32( sts[n]->hHQ_core->old_out_fx32 + numZeros, sts[n]->hTcxDec->FBTCXdelayBuf_32, delay_comp ); /*Q11*/ } tcx_ltp_post_fx32( sts[n], hTcxLtpDec, sts[n]->core, output_frame, add( NS2SA_FX2( output_Fs, ACELP_LOOK_NS ), delay_comp ), synth, sts[n]->hTcxDec->FBTCXdelayBuf_32, output_q ); @@ -416,7 +416,7 @@ void stereo_dft_dec_core_switching_fx( delay_comp = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); /*Q0*/ move16(); - Copy32( &st->hHQ_core->oldOut_fx[nZeros - ( delay_comp + NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ + Copy32( &st->hHQ_core->old_out_fx32[nZeros - ( delay_comp + NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ Word16 mem_len; @@ -605,7 +605,7 @@ void stereo_dft_dec_core_switching_fx( Word16 numZeros = (Word16) ( NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS ) ); /*Q0*/ Word32 tmp_fade_fx[max( STEREO_DFT_ALLPASS_FADELEN_12k8, STEREO_DFT_ALLPASS_FADELEN_16k )]; - Copy32( st->hHQ_core->old_outLB_fx + numZeros, hCPE->hStereoDft->ap_fade_mem_fx, ap_fade_len ); /*st->hHQ_core->q_old_outLB_fx*/ + Copy32( st->hHQ_core->old_out_LB_fx32 + numZeros, hCPE->hStereoDft->ap_fade_mem_fx, ap_fade_len ); /*st->hHQ_core->q_old_outLB_fx*/ hCPE->hStereoDft->q_ap_fade_mem_fx = st->hHQ_core->q_old_outLB_fx; move16(); diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index edd5a0fbb..a977b6a96 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -420,11 +420,11 @@ ivas_error stereo_memory_dec_fx( test(); IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - v_add_32( hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, hCPE->hCoreCoder[1]->hHQ_core->oldOut_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ - v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ + v_add_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[1]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ + v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ - v_add_32( hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, hCPE->hCoreCoder[1]->hHQ_core->old_outLB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k ); /* q_old_outLB_fx */ - v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k ); /* exp(exp_old_out) */ + v_add_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[1]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k ); /* q_old_outLB_fx */ + v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k ); /* exp(exp_old_out) */ } /*--------------------------------------------------------------* @@ -576,7 +576,7 @@ ivas_error stereo_memory_dec_fx( move16(); len = NS2SA_FX2( st->output_Fs, 3000000 ); /* Q0 */ move16(); - Copy32( st->hHQ_core->oldOut_fx + nZeros, hCPE->output_mem_fx[1], len ); /* exp(exp_old_out) */ + Copy32( st->hHQ_core->old_out_fx32 + nZeros, hCPE->output_mem_fx[1], len ); /* exp(exp_old_out) */ } /* deallocated HQ-core for second channel */ @@ -1990,7 +1990,7 @@ void stereo_switching_dec( // 32bit buffer - Copy32( sts[0]->hHQ_core->oldOut_fx, sts[1]->hHQ_core->oldOut_fx, L_FRAME48k ); /* exp(exp_old_out) */ + Copy32( sts[0]->hHQ_core->old_out_fx32, sts[1]->hHQ_core->old_out_fx32, L_FRAME48k ); /* exp(exp_old_out) */ Copy32( sts[0]->delay_buf_out32_fx, sts[1]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP ); /* Q11 */ Copy32( sts[0]->hTcxDec->old_syn_Overl_32, sts[1]->hTcxDec->old_syn_Overl_32, 256 ); /* Q_old_syn_Overl*/ // 16 bit buffer @@ -2151,7 +2151,7 @@ void stereo_td2dft_update_fx( move16(); /* update buffers used for fading when switching to DFT Stereo */ - v_add_fx( sts[0]->hHQ_core->old_outLB_fx + nsLB, sts[1]->hHQ_core->old_outLB_fx + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); + v_add_fx( sts[0]->hHQ_core->old_out_LB_fx32 + nsLB, sts[1]->hHQ_core->old_out_LB_fx32 + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, STEREO_MDCT2DFT_FADE_LEN_48k, old_outLB_len ); #ifndef MSAN_FIX for ( i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) @@ -2162,7 +2162,7 @@ void stereo_td2dft_update_fx( hCPE->old_outLB_mdct_fx[i] = L_shr( hCPE->old_outLB_mdct_fx[i], 1 ); /* Q11 */ move32(); } - v_add_fx( sts[0]->hHQ_core->oldOut_fx + ns, sts[1]->hHQ_core->oldOut_fx + ns, hCPE->old_out_mdct_fx, old_out_len ); /* exp(exp_old_out) */ + v_add_fx( sts[0]->hHQ_core->old_out_fx32 + ns, sts[1]->hHQ_core->old_out_fx32 + ns, hCPE->old_out_mdct_fx, old_out_len ); /* exp(exp_old_out) */ #ifndef MSAN_FIX for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index c1b6381e5..712ead8f4 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -58,21 +58,7 @@ typedef enum FRAMEMODE_NORMAL = 0x0, /* frame available */ FRAMEMODE_MISSING = 0x1, /* frame missing => conceal */ FRAMEMODE_FUTURE = 0x2 -} FRAME_MODE, - frameMode_fx; - -typedef enum -{ - TONALMDCTCONCEAL_OK = 0, - - __error_codes_start = -100, - - TONALMDCTCONCEAL_NSAMPLES_LARGER_THAN_MAXBLOCKSIZE, - TONALMDCTCONCEAL_INVALIDPOINTER, - TONALMDCTCONCEAL_UNEXPECTED_ERROR, - - __error_codes_end -} TONALMDCTCONCEAL_ERROR; +} FRAME_MODE; /*---------------------------------------------------------------* @@ -201,14 +187,11 @@ typedef struct Word16 step_concealgain_fx; Word16 concealment_method; - #ifndef NONBE_FIX_1402_WAVEADJUST Word16 subframe; #endif Word16 subframe_fx; - Word16 nbLostCmpt; - Word16 seed; } T_PLCInfo, *T_PLCInfo_HANDLE; @@ -222,17 +205,12 @@ typedef struct { UWord16 nSamples; UWord16 nSamplesCore; - - Float32 *spectralData_float; Word16 *spectralData; - Word16 spectralData_exp; Word16 *scaleFactors; - Word16 *scaleFactors_exp; Word16 scaleFactors_max_e; Word16 gain_tcx_exp; - Word16 blockIsValid; Word16 blockIsConcealed; Word16 tonalConcealmentActive; @@ -244,9 +222,7 @@ typedef struct UWord16 indexOfTonalPeak[MAX_NUMBER_OF_IDX]; UWord16 lowerIndex[MAX_NUMBER_OF_IDX]; UWord16 upperIndex[MAX_NUMBER_OF_IDX]; - - Word16 phaseDiff[MAX_NUMBER_OF_IDX]; // Q12 /* This one can be stored with 16 bits in range 0..2*PI */ - + Word16 phaseDiff[MAX_NUMBER_OF_IDX]; // Q12 /* This one can be stored with 16 bits in range 0..2*PI */ Word16 phase_currentFramePredicted[MAX_NUMBER_OF_IDX * GROUP_LENGTH]; // Q13 /* This one can be stored with 16 bits in range [-pi;pi] 2Q13, but the code has to be adapted to use moduo(2*PI) after adding */ } TonalComponentsInfo; @@ -265,21 +241,13 @@ typedef struct tonalmdctconceal blockData secondLastBlockData; Word16 scaleFactorsBuffers[2][FDNS_NPTS]; /* Contains also global gain. */ - Word16 scaleFactorsBuffers_exp[2][FDNS_NPTS]; - - Word16 spectralDataBuffers[2][L_FRAME_MAX]; /* 16 bits is enough, because it is stored before applying scale factors. Take care that power spectrum is also stored here. */ - + Word16 spectralDataBuffers[2][L_FRAME_MAX]; /* 16 bits is enough, because it is stored before applying scale factors. Take care that power spectrum is also stored here. */ Word16 timeDataBuffer[( 3 * L_FRAME_MAX ) / 2]; /* 16 bits are enough for the TD signal */ - Word16 *lastPcmOut; - Word16 *secondLastPcmOut; - Word16 q_lastPcmOut; - Word16 *secondLastPowerSpectrum; - Word16 secondLastPowerSpectrum_exp; Word32 scaleFactorsBackground_fx[FDNS_NPTS]; @@ -295,6 +263,7 @@ typedef struct tonalmdctconceal Word16 faded_signal_nrg_exp; Word16 nFramesLost; TonalComponentsInfo *pTCI; + } TonalMDCTConceal_INSTANCE, *TonalMDCTConcealPtr; @@ -399,8 +368,6 @@ typedef struct igfdec_instance_struct typedef struct tec_dec_structure { - - // fixed variable Word16 pGainTemp_m[CLDFB_NO_COL_MAX]; Word16 pGainTemp_e[CLDFB_NO_COL_MAX]; Word16 loBuffer[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG]; @@ -429,12 +396,9 @@ typedef struct tcx_ltp_dec_structure Word32 tcxltp_mem_out_32[L_FRAME48k]; Word16 exp_tcxltp_mem_out; - Word16 tcxltp_pitch_int_post_prev; Word16 tcxltp_pitch_fr_post_prev; - Word16 tcxltp_gain_post_prev; - Word16 tcxltp_filt_idx_prev; } TCX_LTP_DEC_DATA, *TCX_LTP_DEC_HANDLE; @@ -486,7 +450,6 @@ typedef struct tcx_dec_structure Word16 FBTCXdelayBuf[111]; /* 2.3125ms at 48kHz -> 111 samples */ Word32 FBTCXdelayBuf_32[111]; /* 2.3125ms at 48kHz -> 111 samples */ - /*TCX resisual Q*/ Word16 resQBits[NB_DIV]; /* number of bits read for the residual Quantization in TCX*/ @@ -522,7 +485,6 @@ typedef struct tcx_dec_structure Word16 tcxConceal_recalc_exc; Word16 cummulative_damping_tcx; // Q15 - } TCX_DEC_DATA, *TCX_DEC_HANDLE; @@ -560,39 +522,43 @@ typedef struct WI_dec_structure /*----------------------------------------------------------------------------------* - * LD music post-filter + * NB postfilter / formant postfilter static variables *----------------------------------------------------------------------------------*/ -typedef struct ld_music_postfilt_structure +typedef struct pfstat_structure { - Word16 LDm_mem_etot_fx; /* LD music post-filter - total energy memory */ + Word16 on; /* On/off flag */ + Word16 reset; /* reset flag */ + Word16 mem_pf_in[L_SUBFR]; /* Input memory Qqmem_pf_in */ + Word16 mem_stp[L_SUBFR]; /* 1/A(gamma1) memory Qqmem_stp*/ + Word16 mem_res2[DECMEM_RES2]; /* A(gamma2) residual Q_syn*/ + Word16 mem_zero[M]; /* null memory to compute i.r. of A(gamma2)/A(gamma1) Q_qmem_zero*/ + Word16 gain_prec; /*Q14*/ /* for gain adjustment */ - Word16 LDm_last_music_flag; /* LD music post-filter - last music flag */ +} PFSTAT, *PFSTAT_HANDLE; - Word16 LDm_nb_thr_1; /* LD music post-filter - number of consecutive frames of level 1 */ - Word16 LDm_nb_thr_3; +/*----------------------------------------------------------------------------------* + * LD music post-filter + *----------------------------------------------------------------------------------*/ +typedef struct ld_music_postfilt_structure +{ + Word16 LDm_mem_etot_fx; /* LD music post-filter - total energy memory */ + Word16 LDm_last_music_flag; /* LD music post-filter - last music flag */ + Word16 LDm_nb_thr_1; /* LD music post-filter - number of consecutive frames of level 1 */ + Word16 LDm_nb_thr_3; Word16 dct_post_old_exc_fx[DCT_L_POST - OFFSET2]; - - Word16 LDm_thres_fx[4]; /* LD music post-filter - Classification threshold */ - - Word16 LDm_lt_diff_etot_fx[MAX_LT]; /* LD music post-filter - long-term total energy variation */ - + Word16 LDm_thres_fx[4]; /* LD music post-filter - Classification threshold */ + Word16 LDm_lt_diff_etot_fx[MAX_LT]; /* LD music post-filter - long-term total energy variation */ Word16 LDm_enh_lp_gbin_fx[VOIC_BINS_HR]; /* LD music post-filter - smoothed suppression gain, per bin FFT */ - - Word32 LDm_enh_lf_EO_fx[VOIC_BINS_HR]; /* LD music post-filter - old per bin E for previous half frame */ - - Word16 LDm_enh_min_ns_gain_fx; /* LD music post-filter - minimum suppression gain */ - - Word32 LDm_bckr_noise_fx[MBANDS_GN_LD]; /* LD music post-filter - background noise estimation per critical band */ + Word32 LDm_enh_lf_EO_fx[VOIC_BINS_HR]; /* LD music post-filter - old per bin E for previous half frame */ + Word16 LDm_enh_min_ns_gain_fx; /* LD music post-filter - minimum suppression gain */ + Word32 LDm_bckr_noise_fx[MBANDS_GN_LD]; /* LD music post-filter - background noise estimation per critical band */ Word16 filt_lfE_fx[DCT_L_POST]; - Word16 last_nonfull_music; - Word16 Old_ener_Q; /* Old energy scaling factor */ - } MUSIC_POSTFILT_DATA, *MUSIC_POSTFILT_HANDLE; /*----------------------------------------------------------------------------------* @@ -603,18 +569,13 @@ typedef struct bass_postfilt_structure { Word16 pst_old_syn_fx[NBPSF_PIT_MAX]; /* Bass post-filter - old synthesis buffer 1 Q_syn2-1*/ Word16 q_pst_old_syn; - Word16 pst_mem_deemp_err_fx; /* Bass post-filter - filter memory of noise LP filter Q_syn2-1*/ - - Word16 pst_lp_ener_fx; /* Bass post-filter - long-term energy Q8*/ - - Word16 Track_on_hist[L_TRACK_HIST]; /* Bass post-filter - History of half frame usage */ - + Word16 pst_mem_deemp_err_fx; /* Bass post-filter - filter memory of noise LP filter Q_syn2-1*/ + Word16 pst_lp_ener_fx; /* Bass post-filter - long-term energy Q8*/ + Word16 Track_on_hist[L_TRACK_HIST]; /* Bass post-filter - History of half frame usage */ Word16 vibrato_hist[L_TRACK_HIST]; /* Bass post-filter - History of frames declared as vibrato */ - // Word16 vibrato_hist[L_TRACK_HIST]; /* Bass post-filter - History of frames declared as vibrato */ Word16 psf_att_fx; /* Bass post-filter - post filter attenuation factor */ Word16 mem_mean_pit_fx[L_TRACK_HIST]; /* Bass post-filter - average pitch memory */ - } BPF_DEC_DATA, *BPF_DEC_HANDLE; /*------------------------------------------------------------------------------------------* @@ -623,54 +584,32 @@ typedef struct bass_postfilt_structure typedef struct td_cng_dec_structure { - Word16 cng_seed; /* DTX/CNG - seed for white noise random generator */ - // Word16 cng_seed; /*CNG and DTX - seed for white noise random generator*/ - Word32 Enew_fx; /* CNG and DTX - decoded residual energy Q6*/ - + Word16 cng_seed; /* DTX/CNG - seed for white noise random generator */ + Word32 Enew_fx; /* CNG and DTX - decoded residual energy Q6*/ Word16 old_enr_index; /* DTX/CNG - index of last encoded CNG energy */ - Word16 cng_ener_seed; /* DTX/CNG - seed for random generator for variation of excitation energy */ - Word16 cng_ener_seed1; - Word16 last_allow_cn_step; - - Word16 ho_hist_size; /* DTX/CNG - size of DTX hangover history buffer for averaging, <0,HO_HIST_SIZE> */ - - Word16 ho_hist_ptr; /* DTX/CNG - pointer for averaging buffers */ - + Word16 ho_hist_size; /* DTX/CNG - size of DTX hangover history buffer for averaging, <0,HO_HIST_SIZE> */ + Word16 ho_hist_ptr; /* DTX/CNG - pointer for averaging buffers */ Word32 ho_sid_bw; /* DTX/CNG - SID bandwidth flags */ - // Word32 ho_sid_bw; /* CNG and DTX - SID bandwidth flags */ Word16 ho_lsp_hist_fx[HO_HIST_SIZE * M]; /* CNG and DTX - old LSP buffer for averaging */ Word32 ho_ener_hist_fx[HO_HIST_SIZE]; /* CNG and DTX - energy buffer for averaging */ /*Q6 */ Word32 ho_env_hist_fx[HO_HIST_SIZE * NUM_ENV_CNG]; - - - Word16 act_cnt; /* DTX/CNG - counter of active frames */ - - Word16 ho_circ_size; /* DTX/CNG - size of DTX hangover history buffer for averaging, <0,HO_HIST_SIZE> */ - - Word16 ho_circ_ptr; /* DTX/CNG - pointer for averaging buffers */ - // Word16 ho_circ_ptr; /* CNG and DTX - pointer for averaging buffers */ - + Word16 act_cnt; /* DTX/CNG - counter of active frames */ + Word16 ho_circ_size; /* DTX/CNG - size of DTX hangover history buffer for averaging, <0,HO_HIST_SIZE> */ + Word16 ho_circ_ptr; /* DTX/CNG - pointer for averaging buffers */ Word16 ho_lsp_circ_fx[HO_HIST_SIZE * M]; /* CNG and DTX - old LSP buffer for averaging */ Word32 ho_ener_circ_fx[HO_HIST_SIZE]; /* CNG and DTX - energy buffer for averaging */ /* Q6 */ Word32 ho_env_circ_fx[HO_HIST_SIZE * NUM_ENV_CNG]; - - - Word16 num_ho; /* DTX/CNG - number of selected hangover frames */ - + Word16 num_ho; /* DTX/CNG - number of selected hangover frames */ Word16 ho_16k_lsp[HO_HIST_SIZE]; /* DTX/CNG - 16k LSPs flags */ - // Word16 ho_16k_lsp[HO_HIST_SIZE]; /* DTX/CNG - 16k LSPs flags */ - - - Word16 act_cnt2; /* DTX/CNG - counter of active frames for CNG_mode switching */ + Word16 act_cnt2; /* DTX/CNG - counter of active frames for CNG_mode switching */ Word32 old_env_fx[20]; Word32 lp_env_fx[20]; Word16 exc_mem_fx[24]; Word16 exc_mem1_fx[30]; - Word16 interpol_3_2_cng_dec_fx[INTERP_3_2_MEM_LEN]; /* SWB DTX/CNG parameters */ @@ -708,36 +647,27 @@ typedef struct sc_vbr_dec_structure /* DTFS variables */ Word16 dtfs_dec_a_fx[MAXLAG_WI]; /*Variable Q format in dtfs_dec_Q*/ Word16 dtfs_dec_b_fx[MAXLAG_WI]; /*Variable Q format in dtfs_dec_Q*/ - Word16 dtfs_dec_lag; - Word16 dtfs_dec_nH; - Word16 dtfs_dec_nH_4kHz; - Word16 dtfs_dec_upper_cut_off_freq_of_interest_fx; /*Q0*/ Word16 dtfs_dec_upper_cut_off_freq_fx; /*Q0*/ Word16 ph_offset_D_fx; /* normalized by 2Pi Q15*/ Word16 lastLgainD_fx; /* previous gain value for the low band Q11*/ Word16 lastHgainD_fx; /* previous gain value for the high band Q11 */ Word16 lasterbD_fx[NUM_ERB_WB]; /* previous amplitude spectrum (ERB) Q13*/ - - Word16 dtfs_dec_Q; /*Q0*/ + Word16 dtfs_dec_Q; /*Q0*/ /* NELP decoder variables */ Word32 bp1_filt_mem_nb_dec_fx[14]; /* qfm currently Q0*/ Word16 bp1_filt_mem_wb_dec_fx[8]; /* qfm currently Q0*/ Word16 shape1_filt_mem_dec_fx[10]; /* qfm currently Q0*/ Word16 shape2_filt_mem_dec_fx[10]; /* qfm currently Q0*/ - Word16 shape3_filt_mem_dec_fx[10]; /* qfm currently Q0*/ - Word16 nelp_dec_seed; - Word16 FadeScale_fx; /*Q15*/ - } SC_VBR_DEC_DATA, *SC_VBR_DEC_HANDLE; /*----------------------------------------------------------------------------------* @@ -747,46 +677,24 @@ typedef struct sc_vbr_dec_structure typedef struct hq_nbfec_structure { Word16 prev_last_core; /* !!! note: the parameter is identical to last_core in IVAS */ - // Word16 prev_last_core; /* !!! note: the parameter is identical to last_core in IVAS */ Word16 diff_energy_fx; - Word16 stat_mode_out; - Word16 stat_mode_old; - - Word16 phase_mat_flag; - Word16 phase_mat_next; - Word16 old_Min_ind; - Word16 old_auOut_2fr_fx[L_FRAME8k * 2]; - Word16 old_out_pha_fx[2][N_LEAD_NB]; /* FEC for HQ Core, 0-phase matching old_out, 1-overlapping original old_out and phase matching old_out*/ - Word32 ynrm_values_fx[MAX_SB_NB][MAX_PGF]; - Word32 r_p_values_fx[MAX_SB_NB][MAX_ROW]; - Word16 Norm_gain_fx[SFM_N_NB]; - - /*Word16 old_hqswb_clas;*/ /* only used in inactive code, where it might probably be replaced by old_hqswb_clas_fx */ - - Word16 HQ_FEC_seed; - Word16 energy_MA_Curr_fx[2]; - Word16 prev_sign_switch[HQ_FEC_SIGN_SFM]; - Word16 prev_sign_switch_2[HQ_FEC_SIGN_SFM]; - Word32 old_coeffs_fx[L_FRAME8k]; /* HQ core - old coefficients (for FEC) */ - Word32 oldIMDCTout_fx[L_FRAME8k / 2]; - Word16 prev_oldauOut_fx[L_FRAME8k]; @@ -798,86 +706,52 @@ typedef struct hq_nbfec_structure typedef struct hq_dec_structure { - - Word32 oldOut_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ - Word16 old_out_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ + Word32 old_out_fx32[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ + Word16 old_out_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ Word16 exp_old_out; - Word16 old_out_LB_fx[L_FRAME32k]; /* HQ core - previous synthesis for OLA for Low Band */ - Word32 old_outLB_fx[L_FRAME32k]; + Word32 old_out_LB_fx32[L_FRAME32k]; Word16 q_old_outLB_fx; - Word16 Q_old_wtda_LB; Word16 Q_old_wtda; Word16 Q_old_postdec; /*scaling of the output of core_switching_post_dec_fx() */ - Word16 last_hq_core_type; - Word16 old_is_transient[3]; /* HQ core - previous transient flag (for FEC) */ Word16 mem_norm[SFM_N_ENV_STAB]; /* Q0 */ - - Word16 mem_env_delta; /* Q11 */ - - Word16 no_att_hangover; /* Q0 */ - - Word32 energy_lt_fx; /* Q13 */ - + Word16 mem_env_delta; /* Q11 */ + Word16 no_att_hangover; /* Q0 */ + Word32 energy_lt_fx; /* Q13 */ Word16 hq_generic_seed; - Word16 prev_noise_level_fx[2]; /* Q15 */ - Word16 prev_hqswb_clas; - - Word16 prev_R; /* the table of bit allocation of last frame */ - - Word16 prev_SWB_peak_pos[SPT_SHORTEN_SBNUM]; - + Word16 prev_R; /* the table of bit allocation of last frame */ Word32 prev_coeff_out_fx[L_HQ_WB_BWE]; /* Q12 */ /* the coefficients of last frame */ Word16 prev_SWB_peak_pos_fx[SPT_SHORTEN_SBNUM]; - Word16 HqVoicing; Word16 fer_samples_fx[L_FRAME48k]; Word16 Q_fer_samples; Word32 prev_normq_fx[SFM_N_WB]; /* Q14 */ /* previous norms */ - - - Word32 prev_env_fx[SFM_N_WB]; /* previous noise envelopes */ - + Word32 prev_env_fx[SFM_N_WB]; /* previous noise envelopes */ Word16 prev_env_Q[SFM_N_WB]; - Word32 last_ni_gain_fx[BANDS_MAX]; - Word16 last_env_fx[BANDS_MAX]; - Word16 last_max_pos_pulse; /* pre-echo reduction */ - Word16 memfilt_lb_fx; /* Q0 */ - + Word16 memfilt_lb_fx; /* Q0 */ Word32 mean_prev_hb_fx; /* Q0 */ - - Word16 smoothmem_fx; /* Q15 */ - - Word32 mean_prev_fx; /* Q0 */ - + Word16 smoothmem_fx; /* Q15 */ + Word32 mean_prev_fx; /* Q0 */ Word32 mean_prev_nc_fx; /* Q0 */ - - Word16 wmold_hb_fx; /* Q15 */ - + Word16 wmold_hb_fx; /* Q15 */ Word16 prevflag; - Word16 pastpre; - - Word16 prev_frm_hfe2; - Word16 prev_stab_hfe2; - - Word16 prev_ni_ratio_fx; /* 15 */ - + Word16 prev_ni_ratio_fx; /* 15 */ Word16 prev_En_sb_fx[NB_SWB_SUBBANDS]; /* QsEn(4) */ /*----------------------------------------------------------------------------------* @@ -886,50 +760,30 @@ typedef struct hq_dec_structure /* HQ PHASE ECU internal state */ Word16 time_offs; - Word16 X_sav_fx[PH_ECU_SPEC_SIZE]; - Word16 Q_X_sav; - Word16 num_p; - Word16 plocs[MAX_PLOCS]; - Word32 plocsi_fx[MAX_PLOCS]; - Word16 env_stab_fx; - Word16 mem_norm_hqfec[SFM_N_ENV_STAB]; - Word16 mem_env_delta_hqfec; - Word16 env_stab_plc_fx; - Word16 env_stab_state_p_fx[NUM_ENV_STAB_PLC_STATES]; - Word16 envstabplc_hocnt; Word16 mag_chg_1st_fx[LGW_MAX]; /* i/o: per band magnitude modifier for transients*/ - - Word16 Xavg_fx[LGW_MAX]; /* Frequency group average gain to fade to */ - - Word16 beta_mute_fx; /* Factor for long-term mute */ + Word16 Xavg_fx[LGW_MAX]; /* Frequency group average gain to fade to */ + Word16 beta_mute_fx; /* Factor for long-term mute */ Word16 last_fec; - Word16 ph_ecu_HqVoicing; - Word16 oldHqVoicing; - Word16 oldgapsynth_fx[L_FRAME48k]; - Word16 ph_ecu_active; /* Set if Phase ECU was used in last bad frame */ - Word16 ni_seed_forfec; - Word16 ber_occured_in_pvq; /* flag for BER detection from PVQ routines */ - } HQ_DEC_DATA, *HQ_DEC_HANDLE; @@ -939,20 +793,15 @@ typedef struct hq_dec_structure typedef struct zero_bwe_dec_structure { - Word16 seed2; /* HF (6-7kHz) BWE - seed for random signal generator */ - - - Word16 mem_hp400_fx[6]; /* HF (6-7kHz) BWE - hp400 filter memory */ - Word16 q_mem_hp400_fx; - - Word16 mem_hf_fx[2 * L_FILT16k]; /* HF (6-7kHz) BWE - band-pass filter memory Q(-2-memExp1)*/ - - Word16 mem_syn_hf_fx[M]; /* HF (6-7kHz) BWE - synthesis filter memory Q0*/ - + Word16 seed2; /* HF (6-7kHz) BWE - seed for random signal generator */ + Word16 mem_hp400_fx[6]; /* HF (6-7kHz) BWE - hp400 filter memory */ + Word16 q_mem_hp400_fx; /* Exponent for mem_hp400_fx[] scaling */ + Word16 mem_hf_fx[2 * L_FILT16k]; /* HF (6-7kHz) BWE - band-pass filter memory Q(-2-memExp1)*/ + Word16 mem_syn_hf_fx[M]; /* HF (6-7kHz) BWE - synthesis filter memory Q0 */ Word16 delay_syn_hf_fx[NS2SA( 16000, DELAY_CLDFB_NS )]; /* HF (6-7kHz) BWE - To synchronise BWE content with postfiltered synthesis Q0*/ + Word16 mem_hp_interp_fx[INTERP_3_1_MEM_LEN]; /* HF (6-7 kHz) BWE - interp. memory */ + Word16 memExp1; /* Exponent for mem_hf_fx scaling */ - Word16 mem_hp_interp_fx[INTERP_3_1_MEM_LEN]; /* HF (6-7 kHz) BWE - interp. memory */ - Word16 memExp1; /* Exponent for mem_hf_fx scaling*/ } ZERO_BWE_DEC_DATA, *ZERO_BWE_DEC_HANDLE; diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 043ae5601..650e8572b 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -554,11 +554,12 @@ void TonalMDCTConceal_SaveFreqSignal_ivas_fx( } -TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState( TonalMDCTConcealPtr hTonalMDCTConc, - Word16 nNewSamples, // Q0 - Word32 pitchLag, // Qx - Word16 badBlock, // Q0 - Word8 tonalConcealmentActive ) +void TonalMDCTConceal_UpdateState( + TonalMDCTConcealPtr hTonalMDCTConc, + Word16 nNewSamples, // Q0 + Word32 pitchLag, // Qx + Word16 badBlock, // Q0 + Word8 tonalConcealmentActive ) { Word8 newBlockIsValid; @@ -598,13 +599,16 @@ TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState( TonalMDCTConcealPtr hTonalM hTonalMDCTConc->lastPitchLag = pitchLag; move32(); - return TONALMDCTCONCEAL_OK; + return; } -static void FindPhases( /* o: currenc phase [-pi;pi] 2Q13 */ - TonalMDCTConcealPtr const hTonalMDCTConc, /* i: pointer to internal structure */ - Word32 secondLastMDCT[], /* i: MDST spectrum data Qx +31 -diff_exp */ - Word32 secondLastMDST[], /* i: MDCT spectrum data Qx */ - Word16 diff_exp ) /* i: exp_MDST - exp_MDCT */ + + +/* o: currenc phase [-pi;pi] 2Q13 */ +static void FindPhases( + TonalMDCTConcealPtr const hTonalMDCTConc, /* i: pointer to internal structure */ + Word32 secondLastMDCT[], /* i: MDST spectrum data Qx +31 -diff_exp */ + Word32 secondLastMDST[], /* i: MDCT spectrum data Qx */ + Word16 diff_exp ) /* i: exp_MDST - exp_MDCT */ { Word16 i; Word16 l; @@ -624,6 +628,8 @@ static void FindPhases( /* o: currenc move16(); } } + + return; } #define BANDWIDTH 7.0f @@ -634,9 +640,10 @@ static void FindPhases( /* o: currenc #define N 931758243 /* FL2WORD32(sin(EVS_PI/BANDWIDTH)); */ #define J 31946 /* FL2WORD16(sin((3*EVS_PI)/BANDWIDTH)); */ -static void FindPhaseDifferences( /* o: Phase difference [-pi;pi] 2Q13*/ - TonalMDCTConcealPtr const hTonalMDCTConc, /* i: Pointer to internal structure */ - Word32 powerSpectrum[] ) /* i: Power spectrum data Qx */ +/* o: Phase difference [-pi;pi] 2Q13*/ +static void FindPhaseDifferences( + TonalMDCTConcealPtr const hTonalMDCTConc, /* i: Pointer to internal structure */ + Word32 powerSpectrum[] ) /* i: Power spectrum data Qx */ { Word16 i, k; Word16 *phaseDiff; -- GitLab From 716155453002246429268512ac5a76b0a0d99454 Mon Sep 17 00:00:00 2001 From: vaclav Date: Sat, 15 Mar 2025 19:44:10 +0100 Subject: [PATCH 0462/1221] clang-format --- lib_dec/ivas_jbm_dec_fx.c | 2 +- lib_dec/ivas_post_proc_fx.c | 2 +- lib_dec/ivas_stereo_switching_dec_fx.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 5b46df06e..c5e3d451a 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -604,7 +604,7 @@ ivas_error ivas_jbm_dec_tc_fx( } } #else - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 #endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 3361d8b14..03fe4063a 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -417,7 +417,7 @@ void stereo_dft_dec_core_switching_fx( move16(); Copy32( &st->hHQ_core->old_out_fx32[nZeros - ( delay_comp + NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ - Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ + Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ Word16 mem_len; mem_len = NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /*Q0*/ diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index a977b6a96..6bf2d7a45 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -421,10 +421,10 @@ ivas_error stereo_memory_dec_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { v_add_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[1]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ - v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ + v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); /* exp(exp_old_out) */ v_add_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[1]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k ); /* q_old_outLB_fx */ - v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k ); /* exp(exp_old_out) */ + v_multc_fixed_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, 16384 /* 0.5 in Q15 */, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k ); /* exp(exp_old_out) */ } /*--------------------------------------------------------------* @@ -1990,7 +1990,7 @@ void stereo_switching_dec( // 32bit buffer - Copy32( sts[0]->hHQ_core->old_out_fx32, sts[1]->hHQ_core->old_out_fx32, L_FRAME48k ); /* exp(exp_old_out) */ + Copy32( sts[0]->hHQ_core->old_out_fx32, sts[1]->hHQ_core->old_out_fx32, L_FRAME48k ); /* exp(exp_old_out) */ Copy32( sts[0]->delay_buf_out32_fx, sts[1]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP ); /* Q11 */ Copy32( sts[0]->hTcxDec->old_syn_Overl_32, sts[1]->hTcxDec->old_syn_Overl_32, 256 ); /* Q_old_syn_Overl*/ // 16 bit buffer -- GitLab From 4cfa5c7d239bebcb63096b7eea40ba63f7dcf6c1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 14:18:39 +0530 Subject: [PATCH 0463/1221] Fix for 3GPP issue 1382: High MLD > 20, obvious audible differences between float and fixed, SBA 24.4 kbps, 32 khz - 1 Link #1382 --- lib_enc/ivas_tcx_core_enc_fx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index d5898cd4a..9066c1ca6 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -769,6 +769,8 @@ Word16 ivas_acelp_tcx20_switching_fx( Word32 tcx_snr; Flag Overflow; Word32 gain, noise; + Word16 noise_e = 0; + move16(); Word32 *pt_ener_sfr, ener_sfr[NB_SUBFR16k]; /* Initialization */ @@ -1214,12 +1216,15 @@ Word16 ivas_acelp_tcx20_switching_fx( gain = get_gain2( wsp + i, wsp + sub( i, T0 ), L_SUBFR ); noise = L_deposit_l( 1 ); - + noise_e = 0; + move16(); FOR( j = 0; j < L_SUBFR; j++ ) { - tmp16 = round_fx_o( L_shl_o( Mpy_32_16_r( gain, wsp[i + j - T0] ), 15, &Overflow ), &Overflow ); // q_in - tmp16 = sub_o( wsp[i + j], tmp16, &Overflow ); // q_in - noise = L_mac0_o( noise, tmp16, tmp16, &Overflow ); // 2*q_in// + tmp32 = Mpy_32_16_1( gain, wsp[i + j - T0] ); // Q16 + q_inp - 15 + tmp32 = L_sub( wsp[i + j], L_shr( tmp32, 1 ) ); // q_inp + tmp16 = norm_l( tmp32 ); + tmp32 = L_shl( tmp32, tmp16 ); // q_inp +tmp16 + noise = BASOP_Util_Add_Mant32Exp( noise, noise_e, Mpy_32_32( tmp32, tmp32 ), shl( sub( 31, add( q_inp, tmp16 ) ), 1 ), &noise_e ); // noise_e } test(); IF( noise == 0 || EQ_32( noise, 1 ) ) @@ -1238,7 +1243,7 @@ Word16 ivas_acelp_tcx20_switching_fx( ELSE { noise = Mpy_32_16_1( noise, scale ); - tmp32 = L_add( BASOP_Util_Log2( noise ), L_shl( sub( 31, add( q_inp, q_inp ) ), 25 ) ); // Q25 + tmp32 = L_add( BASOP_Util_Log2( noise ), L_shl( noise_e, 25 ) ); // Q25 } tmp32 = L_sub( *pt_ener_sfr, tmp32 ); // Q25 temp_energy = BASOP_Util_Add_Mant32Exp( tmp32, 6, temp_energy, ener_e, &ener_e ); -- GitLab From 4743eb2a3441f408b6a2b31b51de60755c516da6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 17:27:26 +0530 Subject: [PATCH 0464/1221] Few more changes to resolve deviations in paths --- lib_com/ivas_prot_fx.h | 6 +-- lib_enc/core_enc_init_fx.c | 4 +- lib_enc/ivas_core_pre_proc_front_fx.c | 2 +- lib_enc/ivas_cpe_enc_fx.c | 8 +-- lib_enc/ivas_ism_enc_fx.c | 4 +- lib_enc/ivas_sce_enc_fx.c | 6 +-- lib_enc/ivas_stat_enc.h | 2 +- lib_enc/ivas_stereo_dft_enc_itd_fx.c | 2 +- lib_enc/ivas_tcx_core_enc_fx.c | 12 ++--- lib_enc/prot_fx_enc.h | 2 +- lib_enc/stat_enc.h | 5 +- lib_enc/tcx_ltp_enc_fx.c | 4 +- lib_enc/transient_detection_fx.c | 77 +++++++++++++++------------ 13 files changed, 74 insertions(+), 60 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 71de2db03..40eb28b70 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2985,7 +2985,7 @@ Word16 ivas_acelp_tcx20_switching_fx( Word16 non_staX, /* i : unbound non-stationarity for sp/mu clas */ Word16 *pitch_fr, /* i : fraction pitch values */ Word16 *voicing_fr, /* i : fractional voicing values */ - Word16 currFlatness, /* i : flatness */ + Word32 currFlatness, /* i : flatness */ Word16 lsp_mid[M], /* i : LSPs at the middle of the frame */ Word16 stab_fac, /* i : LP filter stability */ Word32 *res_cod_SNR_M, @@ -3102,7 +3102,7 @@ Word16 transient_analysis_ivas_fx( void set_transient_stereo_fx( CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - Word16 currFlatness[] /* i/o: current flatness Q7*/ + Word32 currFlatness[] /* i/o: current flatness Q21*/ ); void ivas_smc_mode_selection_fx( @@ -5955,7 +5955,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 *fft_buff_fx_q, /* o : FFT buffer */ const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ - const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ + const Word32 currFlatness_fx, /* i : flatness parameter Q21*/ const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ Word16 fr_bands_LR_fx_q[CPE_CHANNELS], diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 1c60f2ecd..bfe17fcd2 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -1028,8 +1028,8 @@ void init_coder_ace_plus_ivas_fx( { st->acelpFramesCount = 0; move16(); - st->prevTempFlatness_fx = 128 /*1.0f Q7*/; - move16(); + st->prevTempFlatness_32fx = ONE_IN_Q21 /*1.0f Q21*/; + move32(); } /* Initialize TBE */ diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 42920a46a..45098926e 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -115,7 +115,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 *fft_buff_fx_q, /* o : FFT buffer */ const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ - const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ + const Word32 currFlatness_fx, /* i : flatness parameter Q21*/ const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ Word16 fr_bands_LR_fx_q[CPE_CHANNELS], diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 1152736f6..ea70a33d3 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -103,7 +103,7 @@ ivas_error ivas_cpe_enc_fx( Word16 vad_flag_dtx[CPE_CHANNELS]; /* HE-SAD flag with additional DTX HO */ Word32 enerBuffer_fx[CPE_CHANNELS][CLDFB_NO_CHANNELS_MAX]; /* energy buffer */ Word16 enerBuffer_fx_exp[CPE_CHANNELS]; /* energy buffer */ - Word16 currFlatness_fx[CPE_CHANNELS]; /* flatness parameter Q7 */ + Word32 currFlatness_fx[CPE_CHANNELS]; /* flatness parameter Q21 */ Word16 tdm_ratio_idx, tdm_ratio_idx_SM; /* temp. TD stereo parameters */ Word16 tdm_SM_or_LRTD_Pri; /* temp. TD stereo parameters */ @@ -517,7 +517,7 @@ ivas_error ivas_cpe_enc_fx( IF( sts[n]->hTranDet == NULL ) { currFlatness_fx[n] = 0; - move16(); + move32(); CONTINUE; } @@ -527,8 +527,8 @@ ivas_error ivas_cpe_enc_fx( RunTransientDetection_ivas_fx( sts[n]->input_fx, input_frame, sts[n]->hTranDet, sts[n]->q_inp ); // Note q of sts[n]->input_fx changes inside function } - currFlatness_fx[n] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) sts[n]->hTranDet, NSUBBLOCKS, 0 ); // Q7 - move16(); + currFlatness_fx[n] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) sts[n]->hTranDet, NSUBBLOCKS, 0 ); // Q21 + move32(); } /* Synchonize detection for downmix-based stereo */ diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 1b648cc98..c2f77c159 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -88,7 +88,7 @@ ivas_error ivas_ism_enc_fx( Word16 vad_flag_dtx[MAX_NUM_OBJECTS][1]; /* HE-SAD flag with additional DTX HO */ Word32 enerBuffer_fx[MAX_NUM_OBJECTS][1][CLDFB_NO_CHANNELS_MAX]; /* energy buffer */ Word16 enerBuffer_fx_exp[MAX_NUM_OBJECTS][1]; /* energy buffer */ - Word16 currFlatness_fx[1]; /* flatness parameter */ + Word32 currFlatness_fx[1]; /* flatness parameter */ Word16 fft_buff_fx[MAX_NUM_OBJECTS][1][2 * L_FFT]; /* FFT buffer */ Word16 fft_buff_fx_q[MAX_NUM_OBJECTS][1]; /* FFT buffer */ Word32 fr_bands_fx[1][2 * NB_BANDS]; /* energy in frequency bands */ @@ -213,7 +213,7 @@ ivas_error ivas_ism_enc_fx( RunTransientDetection_ivas_fx( st->input_fx, input_frame, st->hTranDet, st->q_inp ); - currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q7 + currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q21 move16(); /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 35b65e4c1..3a0f19c50 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -78,7 +78,7 @@ ivas_error ivas_sce_enc_fx( Word16 pitch_fr_fx[1][NB_SUBFR]; /* fractional pitch values */ Word16 voicing_fr_fx[1][NB_SUBFR]; /* fractional pitch gains */ Word16 relE_fx[1]; /* frame relative energy Q8 */ - Word16 currFlatness_fx[1]; /* flatness parameter Q7 */ + Word32 currFlatness_fx[1]; /* flatness parameter Q7 */ Word16 Etot_LR_fx[1]; /* total energy Q8 */ Word32 realBuffer_fx[1][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* real buffer */ Word32 imagBuffer_fx[1][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* imag buffer */ @@ -180,8 +180,8 @@ ivas_error ivas_sce_enc_fx( RunTransientDetection_ivas_fx( st->input_fx, input_frame, st->hTranDet, q_input ); } - currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q7 - move16(); + currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q21 + move32(); /*----------------------------------------------------------------* * Configuration of core encoder diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index ac258cfc1..918acc417 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -66,7 +66,7 @@ typedef struct stereo_itd_data_struct Word16 prev_index; Word32 prev_avg_max_fx; Word16 prev_avg_max_fx_e; - Word16 currFlatness_fx; + Word32 currFlatness_fx; /* Xtalk classifier */ Word32 prev_m1_fx; // Q31 diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index 8a887de89..af10f7dea 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -2233,7 +2233,7 @@ void stereo_dft_enc_compute_itd_fx( test(); test(); test(); - IF( flag_noisy_speech_snr == 0 && EQ_16( hCPE->hCoreCoder[0]->vad_flag, 1 ) && hItd->detected_itd_flag == 0 && ( LT_16( hItd->currFlatness_fx, 192 ) /* 1.5 in Q7*/ || EQ_16( hCPE->hCoreCoder[0]->sp_aud_decision0, 1 ) ) ) + IF( flag_noisy_speech_snr == 0 && EQ_16( hCPE->hCoreCoder[0]->vad_flag, 1 ) && hItd->detected_itd_flag == 0 && ( LT_32( hItd->currFlatness_fx, 3145728 ) /* 1.5 in Q21*/ || EQ_16( hCPE->hCoreCoder[0]->sp_aud_decision0, 1 ) ) ) { // hItd->itd_thres *= 1.5f; hItd->itd_thres_fx = L_shl_sat( Mpy_32_32( hItd->itd_thres_fx, 1610612736 ), 1 ); /* Saturation added to avoid assertions (this needs to be investigated) */ diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 9066c1ca6..67c41eed3 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -732,7 +732,7 @@ Word16 ivas_acelp_tcx20_switching_fx( Word16 non_staX, /*Q8 i : unbound non-stationarity for sp/mu clas*/ Word16 *pitch_fr, /*Q6 i : fraction pitch values */ Word16 *voicing_fr, /*Q15 i : fractional voicing values */ - Word16 currFlatness, /*Q7 i : flatness */ + Word32 currFlatness, /*Q21 i : flatness */ Word16 lsp_mid[M], /*Q15 i : LSPs at the middle of the frame */ Word16 stab_fac, /* i : LP filter stability */ Word32 *res_cod_SNR_M, @@ -1275,8 +1275,8 @@ Word16 ivas_acelp_tcx20_switching_fx( test(); if ( ( GT_32( snr_acelp, tcx_snr ) ) && ( LT_32( snr_acelp, L_add( tcx_snr, 131072 /*2.0f Q16*/ ) ) ) && - ( LT_16( add_o( st->prevTempFlatness_fx, currFlatness, &Overflow ), 416 /*3.25f Q7*/ ) || EQ_16( stab_fac, 0x7fff ) || - ( !flag_16k_smc && ( st->sp_aud_decision0 > 0 ) && LT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 2560 /*20.f Q7*/ ) ) ) && + ( LT_32( L_add_o( st->prevTempFlatness_32fx, currFlatness, &Overflow ), 6815744 /*3.25f Q21*/ ) || EQ_16( stab_fac, 0x7fff ) || + ( !flag_16k_smc && ( st->sp_aud_decision0 > 0 ) && LT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 41943040/*20.f Q21*/ ) ) ) && ( LE_16( st->Nb_ACELP_frames, 6 ) ) ) { dsnr = -131072 /*-2.0f Q16*/; @@ -1288,7 +1288,7 @@ Word16 ivas_acelp_tcx20_switching_fx( test(); if ( ( LT_32( snr_acelp, tcx_snr ) ) && ( GT_32( snr_acelp, L_sub( tcx_snr, 131072 /*2.0f Q16*/ ) ) ) && - ( GT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) ) && + ( GT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 6815744 /*3.25f Q21*/ ) ) && ( GE_16( st->Nb_ACELP_frames, 6 ) ) ) { dsnr = 131072 /*2.0f Q16*/; @@ -1334,7 +1334,7 @@ Word16 ivas_acelp_tcx20_switching_fx( /* Select ACELP or TCX */ test(); test(); - IF( GT_32( L_add( snr_acelp, dsnr ), tcx_snr ) && ( st->sp_aud_decision0 == 0 || GT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) ) ) + IF( GT_32( L_add( snr_acelp, dsnr ), tcx_snr ) && ( st->sp_aud_decision0 == 0 || GT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 6815744/*3.25f Q21*/ ) ) ) { smc_dec_ol = 0; move16(); @@ -1358,7 +1358,7 @@ Word16 ivas_acelp_tcx20_switching_fx( } #endif - st->prevTempFlatness_fx = currFlatness; + st->prevTempFlatness_32fx = currFlatness; move16(); return smc_dec_ol; } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 3698eba02..151cd0f89 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1131,7 +1131,7 @@ void RunTransientDetection_ivas_fx( * @return average temporal flatness measure with exponent AVG_FLAT_E */ Word16 GetTCXAvgTemporalFlatnessMeasure_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ); -Word16 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ); +Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ); /** Get the maximum energy change using subblock energies aligned with the TCX. * @param pTransientDetection Structure that contains transient detectors to be run. diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 41c6b0468..86af426bc 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -140,7 +140,9 @@ typedef struct DelayBuffer *pDelayBuffer; /* Delay buffer. */ Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) - Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ /* IVAS: Q3 */ + Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ + Word32 subblockNrgChange_32fx[NSUBBLOCKS + MAX_TD_DELAY]; /* IVAS: subblockNrgChange_exp */ + Word16 subblockNrgChange_exp[NSUBBLOCKS + MAX_TD_DELAY]; Word16 nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ Word16 nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ @@ -1669,6 +1671,7 @@ typedef struct enc_core_structure Word16 transient_info[3]; Word16 acelpFramesCount; Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E Q7 in EVS */ /* Q4 in IVAS */ + Word32 prevTempFlatness_32fx; /* Q21 in IVAS */ // float currEnergyLookAhead; Word32 currEnergyLookAhead_fx; // Q31 diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index e1d478e95..94773b288 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -1035,13 +1035,13 @@ void tcx_ltp_encode_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - tempFlatness_fx = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ); // Q7 + tempFlatness_fx = extract_l(L_shr(GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14)); // Q7 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ); // Q3 } ELSE { - tempFlatness_fx = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, nPrevSubblocks ); // Q7 + tempFlatness_fx = extract_l(L_shr((GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, nPrevSubblocks )), 14)); // Q7 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks ); // Q3 } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 3c88ca224..44bd8cc3c 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -419,16 +419,17 @@ Word16 GetTCXAvgTemporalFlatnessMeasure_fx( struct TransientDetection const *pTr return i; } -Word16 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ) +Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ) { - Word16 i; + Word32 i; TransientDetector const *pTransientDetector; SubblockEnergies const *pSubblockEnergies; Word16 nDelay; Word16 nRelativeDelay; - Word16 const *pSubblockNrgChange; + Word32 const *pSubblockNrgChange; + Word16 const *pSubblockNrgChange_exp; Word32 sumTempFlatness; - Word16 nTotBlocks; + Word16 nTotBlocks, sumTempFlatness_exp, exp; /* Initialization */ pTransientDetector = &pTransientDetection->transientDetector; @@ -445,15 +446,21 @@ Word16 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const assert( ( nPrevSubblocks <= nRelativeDelay ) && ( nCurrentSubblocks <= NSUBBLOCKS + nDelay ) ); - pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange[sub( nRelativeDelay, nPrevSubblocks )]; // subblockNrgChange Q3 + pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange_32fx[( nRelativeDelay - nPrevSubblocks )]; + pSubblockNrgChange_exp = &pSubblockEnergies->subblockNrgChange_exp[( nRelativeDelay - nPrevSubblocks )]; + sumTempFlatness = 0; + move32(); + sumTempFlatness_exp = 0; + move16(); FOR( i = 0; i < nTotBlocks; i++ ) { - sumTempFlatness = L_add( sumTempFlatness, L_deposit_l( pSubblockNrgChange[i] ) ); + sumTempFlatness = BASOP_Util_Add_Mant32Exp( sumTempFlatness, sumTempFlatness_exp, pSubblockNrgChange[i], pSubblockNrgChange_exp[i], &sumTempFlatness_exp ); } /* exponent = AVG_FLAT_E */ - i = div_l( L_shl( sumTempFlatness, 5 ), nTotBlocks ); // Q7 - + i = BASOP_Util_Divide3232_Scale_cadence( sumTempFlatness, nTotBlocks, &exp ); + exp = add( exp, sub( sumTempFlatness_exp, 31 ) ); + i = L_shl_sat( i, sub( exp, 10 ) ); // Can be saturated, since it is used for comparision againt 3.25/20.0f, Q21 return i; } @@ -546,7 +553,8 @@ Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, SubblockEnergies const *pSubblockEnergies; Word16 nDelay; Word16 nRelativeDelay; - Word16 const *pSubblockNrgChange; + Word32 const *pSubblockNrgChange; + Word16 const *pSubblockNrgChange_exp; Word16 maxEnergyChange; Word16 nTotBlocks; @@ -563,7 +571,8 @@ Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, maxEnergyChange = 0 /*0.0f Q3*/; move16(); assert( ( nPrevSubblocks <= nRelativeDelay ) && ( nCurrentSubblocks <= NSUBBLOCKS + nDelay ) ); - pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange[nRelativeDelay - nPrevSubblocks]; + pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange_32fx[nRelativeDelay - nPrevSubblocks]; + pSubblockNrgChange_exp = &pSubblockEnergies->subblockNrgChange_exp[nRelativeDelay - nPrevSubblocks]; IF( s_or( pTransientDetector->bIsAttackPresent, isTCX10 ) ) /* frame is TCX-10 */ { @@ -602,7 +611,7 @@ Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, FOR( i = 0; i < nTotBlocks; i++ ) { - maxEnergyChange = s_max( maxEnergyChange, pSubblockNrgChange[i] ); + maxEnergyChange = s_max( maxEnergyChange, extract_l( L_shl_sat( pSubblockNrgChange[i], sub( pSubblockNrgChange_exp[i], 28 ) ) ) ); // Q3 } move16(); @@ -875,7 +884,7 @@ void SetTCXModeInfo_ivas_fx( move16(); } } - tmp = BASOP_Util_Divide3216_Scale( ONE_IN_Q23, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); + tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q21, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); tmp = shl_sat( tmp, exp_diff ); // Q15 test(); IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) @@ -905,7 +914,7 @@ void SetTCXModeInfo_ivas_fx( *tcxModeOverlap = ALDO_WINDOW; move16(); } - tmp = BASOP_Util_Divide3216_Scale( ONE_IN_Q23, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); + tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q21, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); tmp = shl_sat( tmp, exp_diff ); // Q15 test(); IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) @@ -1124,7 +1133,8 @@ static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, De set32_fx( pSubblockEnergies->subblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize ); set32_fx( pSubblockEnergies->accSubblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize + 1 ); - set16_fx( pSubblockEnergies->subblockNrgChange, ONE_IN_Q3, nMaxBuffSize ); + set32_fx( pSubblockEnergies->subblockNrgChange_32fx, ONE_IN_Q15, nMaxBuffSize ); + set16_fx( pSubblockEnergies->subblockNrgChange_exp, 16, nMaxBuffSize ); IF( nDelay != 0 ) { pSubblockEnergies->nDelay = idiv1616( nDelay, pDelayBuffer->nSubblockSize ); @@ -1340,12 +1350,14 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamples /* Shift old subblock energies */ FOR( i = 0; i < pSubblockEnergies->nDelay; i++ ) { + move32(); move32(); move32(); move16(); pSubblockEnergies->subblockNrg[i] = pSubblockEnergies->subblockNrg[i + NSUBBLOCKS]; pSubblockEnergies->accSubblockNrg[i] = pSubblockEnergies->accSubblockNrg[i + NSUBBLOCKS]; - pSubblockEnergies->subblockNrgChange[i] = pSubblockEnergies->subblockNrgChange[i + NSUBBLOCKS]; + pSubblockEnergies->subblockNrgChange_32fx[i] = pSubblockEnergies->subblockNrgChange_32fx[i + NSUBBLOCKS]; + pSubblockEnergies->subblockNrgChange_exp[i] = pSubblockEnergies->subblockNrgChange_exp[i + NSUBBLOCKS]; } /* Compute filtered subblock energies for the new samples */ @@ -1492,7 +1504,8 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp Word16 facAccSubblockNrg; Word32 *pSubblockNrg; Word32 *pAccSubblockNrg; - Word16 *pSubblockNrgChange; + Word32 *pSubblockNrgChange; + Word16 *pSubblockNrgChange_exp; Word32 *pAccSubblockTmp; Word16 nWindows; Word16 w, k, k2; @@ -1513,7 +1526,8 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp delayBuffer = &pDelayBuffer->buffer[sub( pDelayBuffer->nDelay, nPartialDelay )]; pSubblockNrg = &pSubblockEnergies->subblockNrg[nDelay]; pAccSubblockNrg = &pSubblockEnergies->accSubblockNrg[nDelay]; - pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange[nDelay]; + pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange_32fx[nDelay]; + pSubblockNrgChange_exp = &pSubblockEnergies->subblockNrgChange_exp[nDelay]; /* nWindows = (nSamplesAvailable + nPartialDelay) / nSubblockSize */ nWindows = shr( div_s( add( nSamplesAvailable, nPartialDelay ), shl( nSubblockSize, 7 ) ), 8 ); @@ -1564,19 +1578,16 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp IF( GT_32( w0, w1 ) ) { - k2 = BASOP_Util_Divide3232_uu_1616_Scale( w0, w1, &k ); + pSubblockNrgChange[w] = BASOP_Util_Divide3232_Scale_cadence( w0, w1, &k ); + pSubblockNrgChange_exp[w] = k; } ELSE { - k2 = BASOP_Util_Divide3232_uu_1616_Scale( w1, w0, &k ); + pSubblockNrgChange[w] = BASOP_Util_Divide3232_Scale_cadence( w1, w0, &k ); + pSubblockNrgChange_exp[w] = k; } + move32(); move16(); - pSubblockNrgChange[w] = MAX_16; - IF( LT_16( k, 12 ) ) - { - move16(); - pSubblockNrgChange[w] = shr_r( k2, sub( 12, k ) ); - } } } } @@ -1803,17 +1814,17 @@ Word16 transient_analysis_ivas_fx( *-------------------------------------------------------------------*/ void set_transient_stereo_fx( CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - Word16 currFlatness[] /* i/o: current flatness */ + Word32 currFlatness[] /* i/o: current flatness */ ) { Word16 n, attackIsPresent; - Word16 currFlatnessMax; + Word32 currFlatnessMax; Encoder_State **sts; sts = hCPE->hCoreCoder; /* for DFT/TD based stereo ,map avg. flatness to individual stereo channels (M/S or X/Y) */ - maximum_fx( currFlatness, CPE_CHANNELS, &currFlatnessMax ); + maximum_32_fx( currFlatness, CPE_CHANNELS, &currFlatnessMax ); attackIsPresent = 0; move16(); @@ -1822,7 +1833,7 @@ void set_transient_stereo_fx( attackIsPresent = s_max( attackIsPresent, sts[n]->hTranDet->transientDetector.bIsAttackPresent ); } - set16_fx( currFlatness, currFlatnessMax, CPE_CHANNELS ); + set32_fx( currFlatness, currFlatnessMax, CPE_CHANNELS ); FOR( n = 0; n < CPE_CHANNELS; n++ ) { @@ -1850,8 +1861,8 @@ void set_transient_stereo_fx( move16(); FOR( n = 0; n < CPE_CHANNELS; n++ ) { - hCPE->hStereoDft->hItd->currFlatness_fx = s_max( hCPE->hStereoDft->hItd->currFlatness_fx, currFlatness[n] ); - move16(); + hCPE->hStereoDft->hItd->currFlatness_fx = L_max( hCPE->hStereoDft->hItd->currFlatness_fx, currFlatness[n] ); + move32(); } } @@ -1861,8 +1872,8 @@ void set_transient_stereo_fx( move16(); FOR( n = 0; n < CPE_CHANNELS; n++ ) { - hCPE->hStereoMdct->hItd->currFlatness_fx = s_max( hCPE->hStereoMdct->hItd->currFlatness_fx, currFlatness[n] ); - move16(); + hCPE->hStereoMdct->hItd->currFlatness_fx = L_max( hCPE->hStereoMdct->hItd->currFlatness_fx, currFlatness[n] ); + move32(); } } -- GitLab From ab4cf272f064a27adf3a7a8ed24a13d3279ee59f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 17:31:12 +0530 Subject: [PATCH 0465/1221] Clang formatting changes --- lib_enc/ivas_tcx_core_enc_fx.c | 4 ++-- lib_enc/stat_enc.h | 14 +++++++------- lib_enc/tcx_ltp_enc_fx.c | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 67c41eed3..3dc5f5b8a 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -1276,7 +1276,7 @@ Word16 ivas_acelp_tcx20_switching_fx( if ( ( GT_32( snr_acelp, tcx_snr ) ) && ( LT_32( snr_acelp, L_add( tcx_snr, 131072 /*2.0f Q16*/ ) ) ) && ( LT_32( L_add_o( st->prevTempFlatness_32fx, currFlatness, &Overflow ), 6815744 /*3.25f Q21*/ ) || EQ_16( stab_fac, 0x7fff ) || - ( !flag_16k_smc && ( st->sp_aud_decision0 > 0 ) && LT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 41943040/*20.f Q21*/ ) ) ) && + ( !flag_16k_smc && ( st->sp_aud_decision0 > 0 ) && LT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 41943040 /*20.f Q21*/ ) ) ) && ( LE_16( st->Nb_ACELP_frames, 6 ) ) ) { dsnr = -131072 /*-2.0f Q16*/; @@ -1334,7 +1334,7 @@ Word16 ivas_acelp_tcx20_switching_fx( /* Select ACELP or TCX */ test(); test(); - IF( GT_32( L_add( snr_acelp, dsnr ), tcx_snr ) && ( st->sp_aud_decision0 == 0 || GT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 6815744/*3.25f Q21*/ ) ) ) + IF( GT_32( L_add( snr_acelp, dsnr ), tcx_snr ) && ( st->sp_aud_decision0 == 0 || GT_32( L_add_sat( st->prevTempFlatness_32fx, currFlatness ), 6815744 /*3.25f Q21*/ ) ) ) { smc_dec_ol = 0; move16(); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 86af426bc..7ca996af5 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -137,14 +137,14 @@ typedef struct /* Subblock energies: Holds subblock energies and recursively accumulated energies. Also buffers the energies. */ typedef struct { - DelayBuffer *pDelayBuffer; /* Delay buffer. */ - Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) - Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) - Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ + DelayBuffer *pDelayBuffer; /* Delay buffer. */ + Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) + Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) + Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ Word32 subblockNrgChange_32fx[NSUBBLOCKS + MAX_TD_DELAY]; /* IVAS: subblockNrgChange_exp */ Word16 subblockNrgChange_exp[NSUBBLOCKS + MAX_TD_DELAY]; - Word16 nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ - Word16 nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ + Word16 nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ + Word16 nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ /* Decay factor for the recursive accumulation */ Word16 facAccSubblockNrg; @@ -1671,7 +1671,7 @@ typedef struct enc_core_structure Word16 transient_info[3]; Word16 acelpFramesCount; Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E Q7 in EVS */ /* Q4 in IVAS */ - Word32 prevTempFlatness_32fx; /* Q21 in IVAS */ + Word32 prevTempFlatness_32fx; /* Q21 in IVAS */ // float currEnergyLookAhead; Word32 currEnergyLookAhead_fx; // Q31 diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index 94773b288..19afa8243 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -1035,13 +1035,13 @@ void tcx_ltp_encode_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - tempFlatness_fx = extract_l(L_shr(GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14)); // Q7 + tempFlatness_fx = extract_l( L_shr( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14 ) ); // Q7 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ); // Q3 } ELSE { - tempFlatness_fx = extract_l(L_shr((GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, nPrevSubblocks )), 14)); // Q7 + tempFlatness_fx = extract_l( L_shr( ( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, nPrevSubblocks ) ), 14 ) ); // Q7 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks ); // Q3 } -- GitLab From ac57521b4efd1fe54807aa6e25dc72c035ede9d2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 17:43:31 +0530 Subject: [PATCH 0466/1221] Fix for 3GPP issue 1383: audible spatial leakage issue at SBA 160 kbps, 48 khz Link #1383 --- lib_enc/ivas_dirac_enc_fx.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index ac0ce9556..db5ee872b 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -1203,19 +1203,22 @@ void ivas_dirac_param_est_enc_fx( move16(); } - Word16 buffer_intensity_real_single_q; + Word16 buffer_intensity_real_single_q, min_shift = MAX_16; + move16(); buffer_intensity_real_single_q = hDirAC->buffer_intensity_real_q[0][0][0]; move16(); FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { FOR( j = 0; j < hDirAC->no_col_avg_diff; j++ ) { + min_shift = s_min( min_shift, L_norm_arr( hDirAC->buffer_intensity_real_fx[i][j], num_freq_bands ) ); FOR( k = 0; k < num_freq_bands; k++ ) { buffer_intensity_real_single_q = s_min( buffer_intensity_real_single_q, hDirAC->buffer_intensity_real_q[i][j][k] ); } } } + buffer_intensity_real_single_q = add( buffer_intensity_real_single_q, min_shift ); FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { FOR( j = 0; j < hDirAC->no_col_avg_diff; j++ ) @@ -1569,8 +1572,20 @@ static void computeIntensityVector_enc_fx( #endif } #ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC - norm = s_min( W_norm( tmp_1 ), W_norm( tmp_2 ) ); - norm = s_min( norm, W_norm( tmp_3 ) ); + norm = 63; + move16(); + IF( tmp_1 != 0 ) + { + norm = s_min( norm, W_norm( tmp_1 ) ); + } + IF( tmp_2 != 0 ) + { + norm = s_min( norm, W_norm( tmp_2 ) ); + } + IF( tmp_3 != 0 ) + { + norm = s_min( norm, W_norm( tmp_3 ) ); + } intensity_real[0][i] = W_extract_h( W_shl( tmp_1, norm ) ); // shift_value - (gb - norm) move32(); intensity_real[1][i] = W_extract_h( W_shl( tmp_2, norm ) ); // shift_value - (gb - norm) -- GitLab From d8e83fdebe3801b56625147534c4faa07444a521 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 09:16:55 +0100 Subject: [PATCH 0467/1221] added some comments for an easier review. --- lib_enc/ivas_sns_enc_fx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 7b1aa46de..4b171bdf0 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - IF( exp_sns == Q15 ) + IF( exp_sns == 15 ) { Word16 index; const Word16 split_len = M / 2; @@ -72,20 +72,20 @@ static Word16 sns_1st_cod_fx( SWITCH( L_frame ) { case L_FRAME16k: - means = &sns_1st_means_16k[core - 1][0]; + means = &sns_1st_means_16k[core - 1][0]; // Q14 break; case L_FRAME25_6k: - means = &sns_1st_means_25k6[core - 1][0]; + means = &sns_1st_means_25k6[core - 1][0]; // Q14 break; case L_FRAME32k: - means = &sns_1st_means_32k[core - 1][0]; + means = &sns_1st_means_32k[core - 1][0]; // Q14 break; default: assert( !"illegal frame length in sns_1st_cod" ); } FOR( Word16 i = 0; i < M; ++i ) { - Word32 tmp = L_mult( means[i], means_fix ); // Q16 + Word32 tmp = L_mult( means[i], means_fix ); // Q14->Q16 snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } @@ -100,7 +100,7 @@ static Word16 sns_1st_cod_fx( Word32 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); - const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; // Q12 j0 = imult1616( split, split_len ); j1 = add( j0, split_len ); @@ -114,14 +114,14 @@ static Word16 sns_1st_cod_fx( { Word32 dist_fx = 0; move32(); - FOR( Word16 j = j0; j < j1; ++j ) + FOR( Word16 j = j0; j < j1; ++j ) // j1-j0=split_len. split_len=M/2. M=16 { Word32 tmp; Word32 dist; Word16 tmp2; - tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - dist = L_sub( snsq_fx[j], tmp ); + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12-Q16 + dist = L_sub( snsq_fx[j], tmp ); // Q16 dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow tmp2 = extract_l( dist ); @@ -781,7 +781,7 @@ Word16 quantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - CONTINUE; + continue; } nStages = SNS_MSVQ_NSTAGES_SIDE; -- GitLab From 86fa164c1590e85947839ecac8f1f458af4255b6 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 09:19:06 +0100 Subject: [PATCH 0468/1221] applied the formatting patch. --- lib_enc/ivas_sns_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 4b171bdf0..e981c338f 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -121,8 +121,8 @@ static Word16 sns_1st_cod_fx( Word16 tmp2; tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12-Q16 - dist = L_sub( snsq_fx[j], tmp ); // Q16 - dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow + dist = L_sub( snsq_fx[j], tmp ); // Q16 + dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow tmp2 = extract_l( dist ); dist = L_mult( tmp2, tmp2 ); -- GitLab From 92f9f5352bea6de80a9ea7870e1be34c2de0872b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 17 Mar 2025 15:23:28 +0530 Subject: [PATCH 0469/1221] Fix for 3GPP issue 1389: BWE energy bursts for transition frames in LTV for stereo 16.4kbps WB Link #1389 --- lib_enc/prot_fx_enc.h | 2 +- lib_enc/swb_bwe_enc_fx.c | 56 +++++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 3698eba02..5104fd611 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1078,7 +1078,7 @@ Word16 WB_BWE_encoding_fx( /* o : classification of wb Word16 WB_BWE_encoding_ivas_fx( /* o : classification of wb signal */ Encoder_State *st_fx, /* i/o: Encoder structure */ - const Word16 *yos_fx, /* i : MDCT coefficients of weighted original */ + const Word32 *yos_fx, /* i : MDCT coefficients of weighted original */ Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ Word16 Q_synth, Word16 Q_synth_lf ); diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 3fe7d30fb..e0d846458 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -211,11 +211,9 @@ void wb_bwe_enc_ivas_fx( Word16 Sample_Delay_WB_BWE; Word16 old_input_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k]; Word32 yorig_32[L_FRAME16k]; - Word16 yorig_fx[L_FRAME16k]; Word32 L_wtda_synth_fx[2 * L_FRAME16k]; Word16 *new_input_fx; /* pointer to original input signal */ - Word16 scl, new_input_fx_exp; - Word16 Q_synth; + Word16 new_input_fx_exp; FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; Word16 WB_fenv_fx[SWB_FENV]; @@ -239,7 +237,7 @@ void wb_bwe_enc_ivas_fx( /* MDCT of the core synthesis signal */ /*---------------------------------------------------------------------*/ - new_input_fx_exp = 0; + new_input_fx_exp = -1; move16(); wtda_fx( old_input_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, @@ -249,22 +247,7 @@ void wb_bwe_enc_ivas_fx( /* DCT of the ACELP core synthesis */ direct_transform_fx( L_wtda_synth_fx, yorig_32, 0, L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); - /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ - scl = sub( 16 + 8 /*MAX_Q_NEW_INPUT*/, new_input_fx_exp ); - /* Possible to Upscale? */ - IF( scl > 0 ) - { - /* Yes */ - /* Calc Room to Upscale */ - Q_synth = Find_Max_Norm32( yorig_32, L_FRAME16k ); - - /* Stay within MAX_Q_NEW_INPUT */ - scl = s_min( Q_synth, scl ); - } - Copy_Scale_sig32_16( yorig_32, yorig_fx, L_FRAME16k, scl ); - Q_synth = sub( add( sub( new_input_fx_exp, 16 ), scl ), 1 ); - - mode = WB_BWE_encoding_ivas_fx( st_fx, yorig_fx, WB_fenv_fx, Q_synth, Q_synth ); + mode = WB_BWE_encoding_ivas_fx( st_fx, yorig_32, WB_fenv_fx, new_input_fx_exp, new_input_fx_exp ); move16(); push_indice( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); } @@ -2517,7 +2500,7 @@ Word16 WB_BWE_encoding_fx( /* o : classification of wb Word16 WB_BWE_encoding_ivas_fx( /* o : classification of wb signal */ Encoder_State *st_fx, /* i/o: Encoder structure */ - const Word16 *yos_fx, /* i : MDCT coefficients of weighted original */ + const Word32 *yos_fx, /* i : MDCT coefficients of weighted original */ Word16 *WB_fenv_fx, /* i/o: energy of WB envelope */ Word16 Q_synth, Word16 Q_synth_lf ) @@ -2531,35 +2514,48 @@ Word16 WB_BWE_encoding_ivas_fx( /* o : classification of Word16 ener_40, exp; Word32 L_tmp; Word16 tmp; - + Word64 energy_fx_64; + Word16 q_shift, scale; + Word16 q_WB_fenv[2]; + Word16 yos_fx_16[L_FRAME16k]; n_band = 0; move16(); FOR( i = 0; i < 2; i++ ) { - energy_fx = L_deposit_l( 0 ); + energy_fx_64 = 0; + move64(); FOR( n_coeff = swb_bwe_subband[n_band]; n_coeff < swb_bwe_subband[n_band + 2]; n_coeff++ ) { - energy_fx = L_add( energy_fx, L_shr( L_mult0( yos_fx[n_coeff], yos_fx[n_coeff] ), 6 ) ); /*2*Q_synth-6 */ + energy_fx_64 = W_add( energy_fx_64, W_mult0_32_32( yos_fx[n_coeff], yos_fx[n_coeff] ) ); /*2*Q_synth*/ } + q_shift = W_norm( energy_fx_64 ); + energy_fx = W_extract_h( W_shl( energy_fx_64, q_shift ) ); /*2*Q_synth + q_shift - 32*/ + q_shift = sub( q_shift, 32 ); L_WB_fenv_fx[i] = energy_fx; - move32(); /*2*Q_synth-6 */ + move32(); + q_WB_fenv[i] = add( shl( Q_synth, 1 ), q_shift ); + move16(); n_band = add( n_band, 2 ); } - mode = FD_BWE_class_fx( yos_fx, 0, 0, Q_synth, 0, st_fx ); - energy_control_ivas_fx( st_fx, ACELP_CORE, mode, st_fx->coder_type, yos_fx, 0, energy_factor_fx, Q_synth_lf ); + scale = s_min( L_norm_arr( yos_fx, L_FRAME16k ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, L_FRAME16k, scale ); + + mode = FD_BWE_class_fx( yos_fx_16, 0, 0, sub( add( Q_synth, scale ), Q16 ), 0, st_fx ); + + energy_control_ivas_fx( st_fx, ACELP_CORE, mode, st_fx->coder_type, yos_fx_16, 0, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); FOR( i = 0; i < 2; i++ ) { ener_40 = mult_r( shr( energy_factor_fx[shl( i, 1 )], 1 ), 26214 ); /*Q19 */ - L_tmp = Mpy_32_16_1( L_WB_fenv_fx[i], ener_40 ); /*2*Q_synth-2 */ + L_tmp = Mpy_32_16_1( L_WB_fenv_fx[i], ener_40 ); /*q_WB_fenv[i]+4 */ IF( L_tmp ) { exp = norm_l( L_tmp ); tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); - /*exp = 30-exp-(2*Q_synth-2); */ - exp = sub( sub( 30, exp ), ( sub( shl( Q_synth, 1 ), 2 ) ) ); + /*exp = 30-exp-(q_WB_fenv[i]+4); */ + exp = sub( sub( 30, exp ), ( add( q_WB_fenv[i], 4 ) ) ); L_tmp = Mpy_32_16( exp, tmp, 32767 ); /* Q16 */ WB_fenv_fx[i] = round_fx( L_shl( L_tmp, 10 ) ); /*Q10 */ move16(); -- GitLab From 09de1b628265221b838c5565322dde8fed0e6a70 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 10:59:04 +0100 Subject: [PATCH 0470/1221] updated the style to the standard of the rest of the code. the magic shifts have been explained. total 150.00 603.963 644.322 631.525 --- lib_enc/ivas_sns_enc_fx.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index e981c338f..9396c4ede 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - IF( exp_sns == 15 ) + IF( exp_sns == Q15 ) { Word16 index; const Word16 split_len = M / 2; @@ -118,15 +118,12 @@ static Word16 sns_1st_cod_fx( { Word32 tmp; Word32 dist; - Word16 tmp2; - tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12-Q16 + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16 dist = L_sub( snsq_fx[j], tmp ); // Q16 - dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow - - tmp2 = extract_l( dist ); - dist = L_mult( tmp2, tmp2 ); - dist = L_shr( dist, 4 ); // make sure that the sum does not overflow + dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom. + dist = Mpy_32_32( dist, dist ); + dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow dist_fx = L_add( dist_fx, dist ); } -- GitLab From 2fcbd3b31d85c9d7851d7af55adf98fd8361097f Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 11:11:27 +0100 Subject: [PATCH 0471/1221] applied the clang formatting patch. --- lib_enc/ivas_sns_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 9396c4ede..d9dea23b0 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -121,7 +121,7 @@ static Word16 sns_1st_cod_fx( tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16 dist = L_sub( snsq_fx[j], tmp ); // Q16 - dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom. + dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom. dist = Mpy_32_32( dist, dist ); dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow dist_fx = L_add( dist_fx, dist ); -- GitLab From 2931b1d877bb33073dd9420816d69962c35f3ea2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 18 Mar 2025 10:02:06 +0530 Subject: [PATCH 0472/1221] Fix for 3GPP issue 1384: Decoder crash for Stereo at 16.4kbps in cng_params_upd_ivas_fx() Link #1384 --- lib_com/cng_exc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index 4153afa32..ed94b1531 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -1166,7 +1166,7 @@ void cng_params_upd_ivas_fx( L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ tmp = add( add( Q_exc, Q_exc ), 1 ); - sp[i] = L_shr( L_tmp, sub( tmp, 6 ) ); + sp[i] = L_shr_o( L_tmp, sub( tmp, 6 ), &Overflow ); move32(); /* Q6 */ ptR++; ptI--; -- GitLab From 5ad3ab89bdfc73c1b4f5256a5088e864012362cf Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Tue, 18 Mar 2025 15:30:28 +0100 Subject: [PATCH 0473/1221] Switch cleaned for fix 1386. --- lib_com/options.h | 6 +--- lib_enc/ivas_stat_enc.h | 4 +-- lib_enc/ivas_stereo_dmx_evs_fx.c | 50 ++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 9b5981930..41377f07a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -174,9 +174,5 @@ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ #define NONBE_FIX_1402_WAVEADJUST /* VA: BASOP iisue 1402: fix waveform adjustment decoder PLC */ #define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ - -#define FIX_1386_STEREO_DMX_EVS_PHA /* Orange: Fix for stereo DMX / PHA mode : Change the filter taps resolution (Q31->Q30), improve precision for the IR window, for the ILD & IPD smoothing in sub-bands, for the ISD counters and for ICCr. */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA -#undef FIX_ISSUE_1153 /* With FIX_1386_STEREO_DMX_EVS_PHA, the FIX_ISSUE_1153 should not be activated. */ -#endif +#define NONBE_FIX_1386_STEREO_DMX_EVS_PHA /* Orange: Fix for stereo DMX / PHA mode : Change the filter taps resolution (Q31->Q30), improve precision for the IR window, for the ILD & IPD smoothing in sub-bands, for the ISD counters and for ICCr. */ #endif diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 19f9a436e..ef278d188 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1183,7 +1183,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word32 isd_rate_s_fx; // Q31 #else Word16 isd_rate_s_fx; // Q15 @@ -1228,7 +1228,7 @@ typedef struct stereo_dmx_evs_enc_data_structure STEREO_DMX_EVS_POC_HANDLE hPOC; STEREO_DMX_EVS_PHA_HANDLE hPHA; -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx; // Q0 #else Word32 itd_fx; // Q16 diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 690e0b35e..933270c33 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -68,7 +68,7 @@ #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA #define STEREO_DMX_EVS_ISD_FORGETTING_Q31 2040109465 #define STEREO_DMX_EVS_ISD_1MFORGETTING_Q15 1638 #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 773094113 @@ -161,7 +161,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ #else Word32 itd[], /* o : estimated itd Q16 */ @@ -208,7 +208,7 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd */ #else Word32 itd_fx[], /* o : estimated itd */ @@ -621,7 +621,7 @@ static void calc_poc_fx( Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), STEREO_DMX_EVS_ISD_INVTHRES_H ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) #else IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) @@ -629,7 +629,7 @@ static void calc_poc_fx( { isd_cnt_h = add( isd_cnt_h, 1 ); } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA W_tmp = W_add( W_mult0_32_32( Mpy_32_32_r( Dr, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Dr ), W_mult0_32_32( Mpy_32_32_r( Di, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Di ) ); // Q62 IF( LT_64( W_add( W_mult0_32_32( Nr, Nr ), W_mult0_32_32( Ni, Ni ) ), W_tmp ) ) // Q62 #else @@ -643,7 +643,7 @@ static void calc_poc_fx( isd_rate = BASOP_Util_Divide1616_Scale( isd_cnt_h, freq_8k, &isd_rate_e ); // Saturation to handle values close to 1.0f isd_rate = shl_sat( isd_rate, isd_rate_e ); // Q15 -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->isd_rate_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ISD_FORGETTING_Q31, hPHA->isd_rate_s_fx ), L_mult( STEREO_DMX_EVS_ISD_1MFORGETTING_Q15, isd_rate ) ); move32(); #else @@ -651,7 +651,7 @@ static void calc_poc_fx( move16(); #endif -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 ) ) #else IF( GT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 ) ) @@ -680,7 +680,7 @@ static void calc_poc_fx( hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; move32(); } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA ELSE IF( LT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 ) ) #else ELSE IF( LT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 ) ) @@ -752,7 +752,7 @@ static void calc_poc_fx( /* Energy */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA // Left W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); // Q(62-(2*specL_e)) -> Q(63 - ((2*specL_e) +1)) @@ -809,7 +809,7 @@ static void calc_poc_fx( tIPDr = L_sub( Mpy_32_32_r( specRr[i], IPDr ), Mpy_32_32_r( specRi[i], IPDi ) ); // spec_e tIPDi = L_add( Mpy_32_32_r( specRr[i], IPDi ), Mpy_32_32_r( specRi[i], IPDr ) ); // spec_e -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), 0, &Nr_e ); Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), 0, &Ni_e ); @@ -857,7 +857,7 @@ static void calc_poc_fx( move32(); // Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Pn = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); Pn = BASOP_Util_Add_Mant32Exp( Pn, 1, EPSILON_FX_M, EPSILON_FX_E, &Pn_e ); Pn = Isqrt_lc( Pn, &Pn_e ); @@ -1076,17 +1076,17 @@ static void calc_poc_fx( FOR( i = 0; i < hPHA->pha_len; i++ ) { // hPHA->p_curr_taps[n][i] *= hPHA->win[i]; -#ifdef FIX_ISSUE_1153 +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 #else -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef FIX_ISSUE_1153 hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 #else hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 #endif -#endif +#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA move32(); } @@ -1094,6 +1094,7 @@ static void calc_poc_fx( move32(); energy_e = 0; move16(); +#ifndef NONBE_FIX_1386_STEREO_DMX_EVS_PHA #ifdef FIX_ISSUE_1153 Word16 shift = L_norm_arr( hPHA->p_curr_taps_fx[n], hPHA->pha_len ); IF( shift ) @@ -1103,20 +1104,25 @@ static void calc_poc_fx( move16(); } #endif +#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA FOR( i = 0; i < hPHA->pha_len; i++ ) { +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA + energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); +#else #ifdef FIX_ISSUE_1153 energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), shl( sub( 1, shift ), 1 ), &energy_e ); #else energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); #endif +#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA } // energy = (float) inv_sqrt( energy + EPSILON ); energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, EPSILON_FX_M, EPSILON_FX_E, &energy_e ); energy = ISqrt32( energy, &energy_e ); FOR( i = 0; i < hPHA->pha_len; i++ ) { -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), sub( energy_e, 1 ) ); // Q30 #else hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), energy_e ); // Q31 @@ -1223,7 +1229,7 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd Q0 */ #else Word32 itd_fx[], /* o : estimated itd Q16 */ @@ -1539,7 +1545,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ #else Word32 itd[], /* o : estimated itd Q16 */ @@ -2084,7 +2090,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_prev_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q25 } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 #endif mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); @@ -2111,7 +2117,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_curr_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q25 } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 #endif // dmx_pha_data[n] += ftmp * INV_SQRT_2; @@ -2143,7 +2149,7 @@ void stereo_dmx_evs_enc_fx( curr_prc = hStereoDmxEVS->hPHA->curr_prc; move32(); // if ( abs( (int16_t) hStereoDmxEVS->itd ) > hStereoDmxEVS->hPHA->prc_thres ) -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_16( abs_s( hStereoDmxEVS->itd_fx ), hStereoDmxEVS->hPHA->prc_thres ) ) #else IF( GT_16( abs_s( round_fx( hStereoDmxEVS->itd_fx ) ), hStereoDmxEVS->hPHA->prc_thres ) ) @@ -2270,7 +2276,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS; Word16 n, input_frame; -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 m, len, pha_len, fad_len, fad_len2, rfft_ipd_coef_step, n0, input_frame_pha; Word32 *fad_g, fad_r, *ipd_ff; Word16 *win; @@ -2510,7 +2516,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_len = hStereoDmxEVS->hPHA->fad_len; move16(); -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q14*/, pha_len ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; move16(); -- GitLab From a404a8de1d3b4cf1fb84d0d403907e3ee4387ede Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 18 Mar 2025 13:54:07 +0530 Subject: [PATCH 0474/1221] Optimizations for SBA path in decoder Test case:: // SBA at 80 kbps, 32kHz in, 32kHz out, HOA3 out Scale_sig32 (14), Copy32 (1.1), cldfbSynthesis_ivas_fx (3) and IGF_getWhiteSpectralData_ivas(1.25) WMOPS reduced. --- lib_com/cldfb.c | 74 ++++++++++++++----- lib_com/ivas_prot_fx.h | 26 +++++-- lib_com/options.h | 3 +- lib_com/prot_fx.h | 11 ++- lib_dec/acelp_core_dec_ivas_fx.c | 18 ++++- lib_dec/acelp_core_switch_dec_fx.c | 4 + lib_dec/core_switching_dec_fx.c | 8 ++ lib_dec/dec_tcx_fx.c | 35 +++++++++ lib_dec/igf_dec_fx.c | 47 ++++++++++++ lib_dec/ivas_dirac_dec_fx.c | 16 ++++ lib_dec/ivas_ism_param_dec_fx.c | 4 + lib_dec/ivas_jbm_dec_fx.c | 24 ++++++ lib_dec/ivas_mc_param_dec_fx.c | 5 ++ lib_dec/ivas_mc_paramupmix_dec_fx.c | 11 ++- lib_dec/ivas_osba_dec_fx.c | 15 +++- lib_dec/ivas_sba_dec_fx.c | 18 ++++- lib_dec/ivas_spar_decoder_fx.c | 53 +++++++++++-- lib_enc/swb_pre_proc_fx.c | 4 + .../ivas_dirac_dec_binaural_functions_fx.c | 4 + lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 36 +++++---- lib_rend/ivas_dirac_rend_fx.c | 4 + 21 files changed, 356 insertions(+), 64 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 246a8a8e8..48fe4d9bc 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1097,10 +1097,13 @@ void cldfbAnalysis_ts_fx_fixed_q( * Conduct inverse multple overlap cmplex low delay MDCT *--------------------------------------------------------------------*/ void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + const Word16 shift, /* i : scale for state buffer */ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ) { @@ -1266,25 +1269,56 @@ void cldfbSynthesis_ivas_fx( } /* synthesis prototype filter */ - FOR( i = 0; i < L2; i++ ) +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( 0 == shift ) + { +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ + FOR( i = 0; i < L2; i++ ) + { + accu0 = Madd_32_16( synthesisBuffer_fx[i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[i] ), p_filter_sf ); // Qx - 1 + accu1 = Madd_32_16( synthesisBuffer_fx[1 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 1 * L2 + i )] ), p_filter_sf ); // Qx - 1 + accu2 = Madd_32_16( synthesisBuffer_fx[2 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 2 * L2 + i )] ), p_filter_sf ); // Qx - 1 + accu3 = Madd_32_16( synthesisBuffer_fx[3 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 3 * L2 + i )] ), p_filter_sf ); // Qx - 1 + accu4 = Madd_32_16( synthesisBuffer_fx[4 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 4 * L2 + i )] ), p_filter_sf ); // Qx - 1 + + synthesisBuffer_fx[i] = accu0; + move32(); + synthesisBuffer_fx[1 * L2 + i] = accu1; + move32(); + synthesisBuffer_fx[2 * L2 + i] = accu2; + move32(); + synthesisBuffer_fx[3 * L2 + i] = accu3; + move32(); + synthesisBuffer_fx[4 * L2 + i] = accu4; + move32(); + } +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + } + ELSE { - accu0 = Madd_32_16( synthesisBuffer_fx[i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[i] ), p_filter_sf ); // Qx - 1 - accu1 = Madd_32_16( synthesisBuffer_fx[1 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 1 * L2 + i )] ), p_filter_sf ); // Qx - 1 - accu2 = Madd_32_16( synthesisBuffer_fx[2 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 2 * L2 + i )] ), p_filter_sf ); // Qx - 1 - accu3 = Madd_32_16( synthesisBuffer_fx[3 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 3 * L2 + i )] ), p_filter_sf ); // Qx - 1 - accu4 = Madd_32_16( synthesisBuffer_fx[4 * L2 + i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[( 4 * L2 + i )] ), p_filter_sf ); // Qx - 1 - synthesisBuffer_fx[i] = accu0; - move32(); - synthesisBuffer_fx[1 * L2 + i] = accu1; - move32(); - synthesisBuffer_fx[2 * L2 + i] = accu2; - move32(); - synthesisBuffer_fx[3 * L2 + i] = accu3; - move32(); - synthesisBuffer_fx[4 * L2 + i] = accu4; - move32(); + FOR( i = 0; i < L2; i++ ) + { + Word32 prod = L_shl_sat( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter_sf ), shift ); + accu0 = Madd_32_16( synthesisBuffer_fx[i], prod, p_filter[i] ); // Qx - 1 + accu1 = Madd_32_16( synthesisBuffer_fx[1 * L2 + i], prod, p_filter[( 1 * L2 + i )] ); // Qx - 1 + accu2 = Madd_32_16( synthesisBuffer_fx[2 * L2 + i], prod, p_filter[( 2 * L2 + i )] ); // Qx - 1 + accu3 = Madd_32_16( synthesisBuffer_fx[3 * L2 + i], prod, p_filter[( 3 * L2 + i )] ); // Qx - 1 + accu4 = Madd_32_16( synthesisBuffer_fx[4 * L2 + i], prod, p_filter[( 4 * L2 + i )] ); // Qx - 1 + + synthesisBuffer_fx[i] = accu0; + move32(); + synthesisBuffer_fx[1 * L2 + i] = accu1; + move32(); + synthesisBuffer_fx[2 * L2 + i] = accu2; + move32(); + synthesisBuffer_fx[3 * L2 + i] = accu3; + move32(); + synthesisBuffer_fx[4 * L2 + i] = accu4; + move32(); + } } +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = 0; i < M1; i++ ) { diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 4255ca842..ab043fc0f 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3786,8 +3786,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - Word32 *output_fx[], /* o : rendered time signal */ - Word16 out_len /*Store the length of values in each channel*/ + Word32 *output_fx[] /* o : rendered time signal */ +#ifndef OPT_SBA_AVOID_SPAR_RESCALE + , + Word16 out_len /*Store the length of values in each channel*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); ivas_error ivas_osba_ism_metadata_dec_fx( @@ -5343,15 +5346,22 @@ ivas_error ivas_sba_dec_render_fx( const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - Word32 *output_fx[], /* o : rendered time signal Q11*/ - Word16 out_len /*Store the length of values in each channel*/ + Word32 *output_fx[] /* o : rendered time signal Q11*/ +#ifndef OPT_SBA_AVOID_SPAR_RESCALE + , + Word16 out_len /*Store the length of values in each channel*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); void ivas_spar_dec_upmixer_sf_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - Word32 *output_fx[], /* o : output audio channels */ - const Word16 nchan_internal, /* i : number of internal channels */ - Word16 out_len ); + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Word32 *output_fx[], /* o : output audio channels */ + const Word16 nchan_internal /* i : number of internal channels */ +#ifndef OPT_SBA_AVOID_SPAR_RESCALE + , + Word16 out_len +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ +); ivas_error ivas_spar_md_enc_open_fx( ivas_spar_md_enc_state_t **hMdEnc_in, /* i/o: SPAR MD encoder handle */ diff --git a/lib_com/options.h b/lib_com/options.h index c51d10333..02f7d18f3 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -168,10 +168,11 @@ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ #define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ #define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ -//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ #define NONBE_FIX_1402_WAVEADJUST /* VA: BASOP iisue 1402: fix waveform adjustment decoder PLC */ #define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ +#define OPT_SBA_AVOID_SPAR_RESCALE /* Optimization made to spar decoder and IGF */ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c4bc98162..65f0d2e69 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9751,10 +9751,13 @@ void cldfbAnalysis_ivas_fx( ); void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + const Word16 shift, /* i : scale for state buffer */ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 8499d1335..2ca524bb0 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1932,7 +1932,11 @@ ivas_error acelp_core_dec_ivas_fx( } } +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, 0, st->cldfbSynHB ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, st->cldfbSynHB ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( save_hb_synth_fx, L_FRAME48k, negate( ( sub( Q_real, 1 ) ) ) ); // Q0 Scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 @@ -1952,7 +1956,11 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // Q_real-1 st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, 0, st->cldfbSyn ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, st->cldfbSyn ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( synth_fx, L_FRAME48k, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSynHB->Q_cldfb_state = Q10; @@ -1991,7 +1999,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); @@ -1999,7 +2007,11 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, st->cldfbSyn ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, st->cldfbSyn ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ #ifdef MSAN_FIX scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 #else @@ -2108,7 +2120,11 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), 0, st->cldfbSyn ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ #ifdef MSAN_FIX Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 3217e2f2a..6a1e60b06 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -845,7 +845,11 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), 0, st_fx->cldfbSyn ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); move16(); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index b913dedb1..1f6b0dd51 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -2058,7 +2058,11 @@ static void core_switch_lb_upsamp_fx( } /* synthesis of the combined signal */ +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), 0, st->cldfbSyn ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), st->cldfbSyn ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ /*rescaling whole buffer to a common Q*/ no_col = st->cldfbSyn->no_col; @@ -2375,7 +2379,11 @@ ivas_error core_switching_pre_dec_ivas_fx( return error; } +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, 0, st->cldfbSyn ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfb_restore_memory_ivas_fx( st->cldfbSyn ); Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 510370aee..8ff50f8a5 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -2682,7 +2682,11 @@ void IMDCT_ivas_fx( } move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + set16_fx( win_fx, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) >> 1 ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 tcx_offset_tmp = add( tcx_offset, shr( L_ola, 1 ) ); set16_fx( xn_buf_fx, 0, tcx_offset_tmp ); /* zero left end of buffer */ @@ -2861,9 +2865,16 @@ void IMDCT_ivas_fx( q_tmp_fx_32 = q_xn_buf_fx_32; move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + Word16 diff = sub( q_tmp_fx_32, q_win ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + old_out_fx_32[ind] = L_shl( old_out_fx[ind], diff ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ old_out_fx_32[ind] = L_shl( old_out_fx[ind], sub( q_tmp_fx_32, q_win ) ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move32(); } @@ -2871,8 +2882,13 @@ void IMDCT_ivas_fx( FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], diff ) ); + xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ old_out_fx[ind] = (Word16) L_shr( old_out_fx_32[ind], sub( q_tmp_fx_32, q_win ) ); xn_buf_fx[ind] = (Word16) L_shr( xn_buf_fx_32[ind], sub( q_tmp_fx_32, q_win ) ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move16(); move16(); } @@ -2896,20 +2912,39 @@ void IMDCT_ivas_fx( q_tmp_fx_32 = sub( q_xn_buf_fx_32, res_e ); // v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + Word16 q_diff = sub( q_xn_buf_fx_32, q_win ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = extract_l( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = (Word16) L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], sub( q_xn_buf_fx_32, q_win ) ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move16(); } window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, &q_old_out, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + q_diff = sub( q_old_out, q_win ); + + Word16 diff = sub( q_tmp_fx_32, q_win ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + old_out_fx[ind] = shr_sat( old_out_fx[ind], q_diff ); + move16(); + xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff ); + move16(); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ old_out_fx[ind] = shr_sat( old_out_fx[ind], sub( q_old_out, q_win ) ); move16(); xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], sub( q_tmp_fx_32, q_win ) ); move16(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } } aldo = 1; diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index c1b0ce93a..5bfa7476a 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -2883,7 +2883,9 @@ static void IGF_getWhiteSpectralData_ivas( Word16 j; Word32 ak; Word16 ak_e; +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Word16 tmp_16; +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 tmp_e; Word16 out_e_arr[IGF_START_MX + MAX_IGF_SFB_LEN]; Word16 max_out_e; @@ -2902,12 +2904,38 @@ static void IGF_getWhiteSpectralData_ivas( Word16 guard_bits = add( find_guarded_bits_fx( add( i_mult( 2, level ), 1 ) ), 1 ) / 2; s_l = sub( s_l, guard_bits ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + Word16 shift = sub( shl( s_l, 1 ), 32 ); + Word16 eff_e = sub( shl( sub( in_e, s_l ), 1 ), 15 ); + Word16 diff = add( 21, in_e ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ + Word16 quo = BASOP_Util_Divide3216_Scale( ONE_IN_Q30, add( shl( level, 1 ), 1 ), &tmp_e ); tmp_e = add( tmp_e, 1 ); ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + ak_e = sub( ak_e, 1 ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ + FOR( i = start; i < stop - level; i++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + Word64 temp = 0; + move64(); + FOR( j = i - level; j < i + level + 1; j++ ) + { + temp = W_mac_32_32( temp, in[j], in[j] ); + } + ak = Mult_32_16( W_shl_sat_l( temp, shift ), quo ); // add( shl( level, 1 ), 1 ), &tmp_e ) ); + + + n = sub( ak_e, norm_l( ak ) ); + n = shr( n, 1 ); + + out_e_arr[i] = sub( diff, n ); + move16(); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ ak = 0; move32(); move32(); @@ -2924,11 +2952,29 @@ static void IGF_getWhiteSpectralData_ivas( out_e_arr[i] = add( sub( 21, n ), in_e ); move16(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ max_out_e = s_max( max_out_e, out_e_arr[i] ); } FOR( ; i < stop; i++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + Word64 temp = 0; + move64(); + + FOR( j = i - level; j < stop; j++ ) + { + temp = W_mac_32_32( temp, in[j], in[j] ); + } + + ak = L_deposit_h( BASOP_Util_Divide3216_Scale( W_shl_sat_l( temp, shift ), sub( stop, sub( i, level ) ), &tmp_e ) ); + ak_e = add( tmp_e, eff_e ); // tmp_e + 2 * (in_e - s_l) - 15 + n = sub( ak_e, add( norm_l( ak ), 1 ) ); + n = shr( n, 1 ); + + out_e_arr[i] = sub( diff, n ); + move16(); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ ak = 0; move32(); @@ -2945,6 +2991,7 @@ static void IGF_getWhiteSpectralData_ivas( out_e_arr[i] = add( sub( 21, n ), in_e ); move16(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ max_out_e = s_max( max_out_e, out_e_arr[i] ); } diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 7c7d49381..ae4098f19 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3747,7 +3747,11 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[ch]->Q_cldfb_state = ( Q6 - 1 ); move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 no_col = st_ivas->cldfbSynDec[ch]->no_col; move16(); @@ -3850,7 +3854,11 @@ void ivas_dirac_dec_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; move32(); } +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, 0, st_ivas->cldfbSynDec[idx_in] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( !st_ivas->hLsSetupCustom->separate_ch_found ) { @@ -3890,7 +3898,11 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state ) ); // Q6-1 st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state = ( Q6 - 1 ); move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[cldfbSynIdx] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, st_ivas->cldfbSynDec[cldfbSynIdx] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ // Calculating length of output Word16 no_col = st_ivas->cldfbSynDec[cldfbSynIdx]->no_col; @@ -3959,7 +3971,11 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = ( Q6 - 1 ); move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[idx_in] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, st_ivas->cldfbSynDec[idx_in] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ // Scaling output from Q6-1 to Q11 Scale_sig32( p_out, out_len, ( Q11 - ( Q6 - 1 ) ) ); diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 24e61c5f3..c818af237 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1535,7 +1535,11 @@ static void ivas_ism_param_dec_render_sf_fx( Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( sub( Q_real, 1 ), Q11 ) ); // Q_real-1 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( Q11, sub( Q_real, 1 ) ) ); // Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index c5e3d451a..e7ee06648 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -2147,7 +2147,11 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2195,7 +2199,11 @@ ivas_error ivas_jbm_dec_render_fx( hSpar->hMdDec->Q_mixer_mat = 30; move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2233,7 +2241,11 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/ { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism] ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism], 960 ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2245,7 +2257,11 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2257,7 +2273,11 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2859,7 +2879,11 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available ); /* render the last subframe */ +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx, L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 404854f91..db56ad03e 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -2240,8 +2240,13 @@ void ivas_param_mc_dec_render_fx( Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); scale_sig32( output_f_fx[ch], len, 5 - 11 ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), + imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 } diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index e70730926..f4d6cb535 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -874,8 +874,12 @@ static void ivas_mc_paramupmix_dec_sf( scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q5 - Q11 ); // Q11 -> Q5 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5; move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), 0, st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 - scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q5 -> Q11 +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ + scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q5 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); } @@ -909,8 +913,13 @@ static void ivas_mc_paramupmix_dec_sf( ptr_re_fx[0] = Cldfb_RealBuffer_fx[ch][slot_idx]; // Q6 ptr_im_fx[0] = Cldfb_ImagBuffer_fx[ch][slot_idx]; // Q6 +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), + hMCParamUpmix->num_freq_bands, 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); // Q6 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index b048470d4..493301743 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -129,8 +129,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - Word32 *output_fx[], /* o : rendered time signal Q11*/ - Word16 out_len /*Store the length of values in each channel*/ + Word32 *output_fx[] /* o : rendered time signal Q11*/ +#ifndef OPT_SBA_AVOID_SPAR_RESCALE + , + Word16 out_len /*Store the length of values in each channel*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 n; @@ -147,7 +150,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( channel_offset = st_ivas->nchan_ism; move16(); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_fx[channel_offset] ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_fx[channel_offset], out_len ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -233,7 +240,11 @@ ivas_error ivas_osba_render_sf_fx( v_shr( p_output[n], Q11 - Q11, output_ism[n], nSamplesAsked ); // Q11 } +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output ) ), IVAS_ERR_OK ) ) +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output, 960 ) ), IVAS_ERR_OK ) ) +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index eb2a40ecb..f89e9601f 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -873,8 +873,11 @@ ivas_error ivas_sba_dec_render_fx( const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested Q0*/ UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered Q0*/ UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render Q0*/ - Word32 *output_fx[], /* o : rendered time signal Q11*/ - Word16 out_len /*Store the length of values in each channel*/ + Word32 *output_fx[] /* o : rendered time signal Q11*/ +#ifndef OPT_SBA_AVOID_SPAR_RESCALE + , + Word16 out_len /*Store the length of values in each channel*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 slots_to_render, first_sf, last_sf, subframe_idx; @@ -883,11 +886,15 @@ ivas_error ivas_sba_dec_render_fx( SPAR_DEC_HANDLE hSpar; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word32 *output_f_local_fx[MAX_OUTPUT_CHANNELS]; +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Word16 output_f_local_len; +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ivas_error error; +#ifndef OPT_SBA_AVOID_SPAR_RESCALE output_f_local_len = out_len; move16(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ hSpar = st_ivas->hSpar; hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_internal = ivas_sba_get_nchan_metadata_fx( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); @@ -919,13 +926,18 @@ ivas_error ivas_sba_dec_render_fx( { Word16 n_samples_sf = imult1616( slot_size, hSpar->subframe_nbslots[subframe_idx] ); /*Q0*/ +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal, output_f_local_len ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ch = 0; ch < nchan_out; ch++ ) { output_f_local_fx[ch] = output_f_local_fx[ch] + n_samples_sf; /*Q11*/ } - +#ifndef OPT_SBA_AVOID_SPAR_RESCALE output_f_local_len = sub( output_f_local_len, n_samples_sf ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index c6c7565a9..461b18fbc 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -787,8 +787,11 @@ void ivas_spar_get_cldfb_gains_fx( cldfbAnalysis_ts_fx_fixed_q( ts_inout_fx, ts_re_fx, ts_im_fx, num_cldfb_bands, cldfbAnaDec0, &q_cldfb ); cldfb_reset_memory_fx( cldfbSynDec0 ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, 0, cldfbSynDec0 ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, cldfbSynDec0 ); - +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( sample = 0; sample < stride; sample++ ) { T_fx[( ( slot * stride ) + sample )][slot] = ts_inout_fx[sample]; /*Q21*/ @@ -1683,10 +1686,14 @@ void ivas_spar_dec_digest_tc_fx( *-------------------------------------------------------------------*/ void ivas_spar_dec_upmixer_sf_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - Word32 *output_fx[], /* o : output audio channels Q11*/ - const Word16 nchan_internal, /* i : number of internal channels Q0*/ - Word16 out_len ) + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Word32 *output_fx[], /* o : output audio channels Q11*/ + const Word16 nchan_internal /* i : number of internal channels Q0*/ +#ifndef OPT_SBA_AVOID_SPAR_RESCALE + , + Word16 out_len +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ +) { Word16 cldfb_band, num_cldfb_bands, numch_in, numch_out; Word32 *cldfb_in_ts_re_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; @@ -1882,11 +1889,18 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + Word16 diff = sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], diff ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/ +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] ) ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move32(); hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band] = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/ move32(); @@ -2066,10 +2080,12 @@ void ivas_spar_dec_upmixer_sf_fx( } IF( LT_16( split_band, IVAS_MAX_NUM_BANDS ) ) { +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Copy32( hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], hSpar->hMdDec->mixer_mat_prev_fx[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ Copy32( hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ Copy32( hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ Copy32( hSpar->hMdDec->mixer_mat_prev_fx[4][0][0], hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { @@ -2077,6 +2093,17 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( b = 0; b < num_spar_bands; b++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + hSpar->hMdDec->mixer_mat_prev_fx[0][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b]; + hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b]; + hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[3][out_ch][in_ch][b]; + hSpar->hMdDec->mixer_mat_prev_fx[3][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b]; + move32(); + move32(); + move32(); + move32(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ + hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][( b + ( md_sf * IVAS_MAX_NUM_BANDS ) )]; /*hSpar->hMdDec->Q_mixer_mat*/ move32(); } @@ -2129,18 +2156,26 @@ void ivas_spar_dec_upmixer_sf_fx( IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) && !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) { +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state-6*/ st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); move16(); Scale_sig32( output_fx[ch], out_len, -6 ); /*Q5*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[idx_in] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, st_ivas->cldfbSynDec[idx_in] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Scale_sig32( output_fx[ch], out_len, 6 ); /*Q11*/ Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, 6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state+6*/ st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = add( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); move16(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } idx_in = add( idx_in, 1 ); @@ -2152,18 +2187,26 @@ void ivas_spar_dec_upmixer_sf_fx( /* CLDFB to time synthesis (overwrite mixer output) */ FOR( out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) { +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Scale_sig32( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx, st_ivas->cldfbSynDec[out_ch]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state-6*/ st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state, 6 ); move16(); Scale_sig32( output_fx[out_ch], out_len, -6 ); /*Q5*/ +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[out_ch] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } +#ifndef OPT_SBA_AVOID_SPAR_RESCALE Scale_sig32( output_fx[out_ch], out_len, 6 ); /*Q11*/ Scale_sig32( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx, st_ivas->cldfbSynDec[out_ch]->p_filter_length, 6 ); /*st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state+6*/ st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state = add( st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state, 6 ); move16(); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } } diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index acdd971fd..b73b0f992 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1263,7 +1263,11 @@ void swb_pre_proc_ivas_fx( thr = icbwe_thr_TDM_fx; regV = icbwe_regressionValuesTDM_fx; +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, 0, st->cldfbSynTd ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, st->cldfbSynTd ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Copy_Scale_sig_32_16( shb_speech_fx_32, shb_speech, L_FRAME16k, negate( sub( q_reImBuffer, 1 ) ) ); *Q_shb_spch = 0; move16(); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 65a68889a..b5dd1f8b9 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -2600,7 +2600,11 @@ static void ivas_dirac_dec_binaural_process_output_fx( outSlotRePr_fx = &( outSlotRe_fx[0] ); outSlotImPr_fx = &( outSlotIm_fx[0] ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, 0, cldfbSynDec[chA] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 ); move16(); } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index aa19285cf..1b4ee91b2 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -1333,22 +1333,22 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/ } - /*Directional gain*/ - FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) + FOR( l = 0; l < num_freq_bands; l++ ) { - FOR( l = 0; l < num_freq_bands; l++ ) - { - aux_buf[l] = L_sub( ONE_IN_Q30, diffuseness[l] ); // Q30 - move32(); - ratio_float[l] = L_sub( ONE_IN_Q31, h_dirac_output_synthesis_state.direct_power_factor_fx[num_freq_bands + l] ); // Q31 - move32(); - ratio_float[l + num_freq_bands] = L_sub( ONE_IN_Q31, ratio_float[l] ); // Q31 - move32(); - } + aux_buf[l] = L_sub( ONE_IN_Q30, diffuseness[l] ); // Q30 + move32(); + ratio_float[l] = L_sub( ONE_IN_Q31, h_dirac_output_synthesis_state.direct_power_factor_fx[num_freq_bands + l] ); // Q31 + move32(); + ratio_float[l + num_freq_bands] = L_sub( ONE_IN_Q31, ratio_float[l] ); // Q31 + move32(); + } - v_mult_fixed( aux_buf, ratio_float, ratio_float, num_freq_bands ); //(Q30, Q31) -> Q30 - v_mult_fixed( aux_buf, &ratio_float[num_freq_bands], &ratio_float[num_freq_bands], num_freq_bands ); //(Q30, Q31) -> Q30 + v_mult_fixed( aux_buf, ratio_float, ratio_float, num_freq_bands ); //(Q30, Q31) -> Q30 + v_mult_fixed( aux_buf, &ratio_float[num_freq_bands], &ratio_float[num_freq_bands], num_freq_bands ); //(Q30, Q31) -> Q30 + /*Directional gain*/ + FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) + { v_mult_fixed( ratio_float, // Q30 &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands], // Q31 &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], //(Q30, Q31) -> Q30 @@ -1642,6 +1642,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( } /*Directional stream*/ + Word16 offset = shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ); FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) { IF( hodirac_flag ) @@ -1709,7 +1710,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( ELSE { p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx + - shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) + + offset + shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 ); IF( EQ_16( proto_direct_index[ch_idx], 0 ) ) { @@ -1781,11 +1782,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( } ELSE { - FOR( l = 0; l < num_freq_bands_diff; l++ ) - { - p_gains_diff++; - p_gains_diff_prev++; - } + p_gains_diff += num_freq_bands_diff; + p_gains_diff_prev += num_freq_bands_diff; } } diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 031a39855..e2e369389 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4212,7 +4212,11 @@ static void ivas_masa_ext_dirac_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; // q_cldfb } Word16 out_size = imult1616( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); +#ifdef OPT_SBA_AVOID_SPAR_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, 0, hMasaExtRend->cldfbSynRend[idx_in] ); +#else /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, hMasaExtRend->cldfbSynRend[idx_in] ); +#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, sub( 11, q_out ) ); // q11 idx_in++; } -- GitLab From 79149552d20c26f57d5dbfd4d0b64e32f9f0ec96 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 19 Mar 2025 09:41:47 +0530 Subject: [PATCH 0475/1221] Disabling macro for another optimization --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 02f7d18f3..c9207fb3c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -168,7 +168,7 @@ #define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ #define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ #define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ -#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ -- GitLab From 604eace3891c889c327584d6c718160b8039a419 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 19 Mar 2025 10:52:37 +0530 Subject: [PATCH 0476/1221] Fix for 3GPP issue 1385: Decoder crash for Stereo at 32 kbps FER in ivas_cpe_dec_fx() Link #1385 --- lib_dec/ivas_cpe_dec_fx.c | 8 ++++---- lib_dec/ivas_stereo_dft_dec_fx.c | 16 ++++++++-------- lib_dec/ivas_stereo_switching_dec_fx.c | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 8e25e5116..05fec7736 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -729,8 +729,8 @@ ivas_error ivas_cpe_dec_fx( hCPE->hStereoDft->q_res_cod_mem_fx = hCPE->hStereoDft->q_dft; move16(); stereo_dft_unify_dmx_fx( hCPE->hStereoDft, sts[0], DFT_fx, hCPE->input_mem_fx[1], hCPE->hStereoCng->prev_sid_nodata ); - scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( Q16, hCPE->hStereoDft->q_res_cod_mem_fx ) ); // Q16 - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( Q15, hCPE->hStereoDft->q_res_cod_mem_fx ) ); // Q15 + hCPE->hStereoDft->q_res_cod_mem_fx = Q15; move16(); } ELSE @@ -754,8 +754,8 @@ ivas_error ivas_cpe_dec_fx( move16(); } stereo_dft_dec_fx( hCPE->hStereoDft, sts[0], DFT_fx, hCPE->input_mem_fx[1], hCPE->hStereoCng, 0, 0, 0, 0, 0, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); - scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( Q16, hCPE->hStereoDft->q_res_cod_mem_fx ) ); // Q16 - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( Q15, hCPE->hStereoDft->q_res_cod_mem_fx ) ); // Q15 + hCPE->hStereoDft->q_res_cod_mem_fx = Q15; move16(); } diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 3d9e58ad1..9c1b488cb 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -146,7 +146,7 @@ void stereo_dft_dec_reset_fx( set16_fx( hStereoDft->res_cod_mode, hStereoDft->hConfig->res_cod_mode, STEREO_DFT_DEC_DFT_NB ); hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->hConfig->band_res][hStereoDft->hConfig->res_cod_mode]; set32_fx( hStereoDft->res_cod_mem_fx, 0, STEREO_DFT_OVL_8k ); - hStereoDft->q_res_cod_mem_fx = Q16; + hStereoDft->q_res_cod_mem_fx = Q15; move16(); hStereoDft->res_pred_band_min = s_max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); @@ -1357,7 +1357,7 @@ void stereo_dft_dec_res_fx( IF( EQ_16( hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET - 1], STEREO_DFT_RES_COD_OFF ) ) { set32_fx( hCPE->hStereoDft->res_cod_mem_fx, 0, STEREO_DFT_OVL_8k ); - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + hCPE->hStereoDft->q_res_cod_mem_fx = Q15; move16(); set32_fx( hCPE->input_mem_fx[1], 0, NS2SA( 8000, STEREO_DFT32MS_OVL_NS ) ); set16_fx( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); @@ -1370,7 +1370,7 @@ void stereo_dft_dec_res_fx( scale_sig( win, L_FRAME8k + STEREO_DFT_OVL_8k, -1 ); - Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); + Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q15 ); IF( !prev_bfi ) { /*OLA*/ @@ -1378,9 +1378,9 @@ void stereo_dft_dec_res_fx( FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( L_add( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx -17 (q_shift -1)*/ + win[i] = extract_h( L_add( hCPE->hStereoDft->res_cod_mem_fx[i], L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx -17 (q_shift -1)*/ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* -1 +15 +1 +1 */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* -1 +15 +1 */ move32(); } @@ -1396,11 +1396,11 @@ void stereo_dft_dec_res_fx( move16(); FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( Madd_32_16( Mpy_32_16_1( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), sub( MAX_16, mult( fac, fac ) ) ), + win[i] = extract_h( Madd_32_16( Mpy_32_16_1( hCPE->hStereoDft->res_cod_mem_fx[i], sub( MAX_16, mult( fac, fac ) ) ), L_shl( L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), q_shift ), sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q(q_shift -1) */ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* Q16 */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* Q15 */ move32(); fac = add( fac, step ); } @@ -1411,7 +1411,7 @@ void stereo_dft_dec_res_fx( v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); } - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + hCPE->hStereoDft->q_res_cod_mem_fx = Q15; Copy( win, out_16, L_FRAME8k ); /* Q(q_shift -1 ) */ diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 6bf2d7a45..6c2ad055c 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -1841,7 +1841,7 @@ void stereo_switching_dec( /* reset residual coding / ESF (secondary channel) */ set32_fx( hCPE->hStereoDft->res_cod_mem_fx, 0, STEREO_DFT_OVL_8k ); - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + hCPE->hStereoDft->q_res_cod_mem_fx = Q15; move16(); set32_fx( hCPE->input_mem_fx[1], 0, NS2SA_FX2( sts[0]->output_Fs, STEREO_DFT32MS_OVL_NS ) ); -- GitLab From 59bcdc58e714d691d3f13c4309bc5928ef3f304d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 19 Mar 2025 11:49:11 +0530 Subject: [PATCH 0477/1221] Synth scaling changes, msan fix for decoder and bug fix in fd_cng_enc --- lib_com/cng_exc_fx.c | 5 ++--- lib_com/modif_fs_fx.c | 34 +++++++----------------------- lib_com/prot_fx.h | 8 +++---- lib_enc/amr_wb_enc_fx.c | 5 ++--- lib_enc/cng_enc_fx.c | 6 ++---- lib_enc/fd_cng_enc_fx.c | 2 +- lib_enc/ivas_front_vad_fx.c | 2 +- lib_enc/ivas_stereo_icbwe_enc_fx.c | 2 +- lib_enc/pre_proc_fx.c | 5 ++--- lib_rend/ivas_dirac_rend_fx.c | 3 +++ 10 files changed, 25 insertions(+), 47 deletions(-) diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index 4153afa32..aa1ceea81 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -295,10 +295,9 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) /* calculate the spectrum of random excitation signal */ Copy( exc2, fft_io, L_frame ); - Word16 Q_new_inp, mem_decim_size; // TO be removed IF( EQ_16( L_frame, L_FRAME16k ) ) { - modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 ); } /* fft_rel(fft_io, L_FFT, LOG2_L_FFT); */ @@ -411,7 +410,7 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) IF( EQ_16( L_frame, L_FRAME16k ) ) { - modify_Fs_fx( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 ); } /* enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame; */ diff --git a/lib_com/modif_fs_fx.c b/lib_com/modif_fs_fx.c index 6079e5db5..bcbff13d5 100644 --- a/lib_com/modif_fs_fx.c +++ b/lib_com/modif_fs_fx.c @@ -330,9 +330,7 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ Word16 sigOut_fx[], /* o : decimated signal Q0 */ const Word32 fout, /* i : frequency of output Q0 */ Word16 mem_fx[], /* i/o: filter memory Q0 */ - const Word16 nblp, /* i : flag indicating if NB low-pass is applied */ - Word16 *Q_new_inp, // TO be removed - Word16 *mem_decim_size // TO be removed + const Word16 nblp /* i : flag indicating if NB low-pass is applied */ ) { Word16 i; @@ -364,17 +362,13 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ /*-------------------------------------------------------------------* * Find the resampling configuration *-------------------------------------------------------------------*/ - *Q_new_inp = 0; - move16(); + /* check if fin and fout are the same */ IF( EQ_32( fin, fout ) ) { /* just copy the signal_fx and quit */ Copy( sigIn_fx, sigOut_fx, lg ); - *mem_decim_size = 0; - *Q_new_inp = 0; - move16(); - move16(); + return lg; } ELSE @@ -439,8 +433,6 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ } mem_len = shl( filt_len, 1 ); - *mem_decim_size = mem_len; - move16(); signal_fx = signal_tab_fx + 2 * L_FILT_MAX + sub( L_FRAME48k, add( mem_len, lg ) ); signal_ana_fx = signal_fx; mem_len_ana = mem_len; @@ -508,7 +500,7 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ } /* interpolation */ - datastep = shr( div_s( shl( fac_den, 7 ), shl( fac_num, 10 ) ), 12 ); + datastep = shr( div_s( shl( fac_den, 8 ), shl( fac_num, 11 ) ), 12 ); /* equivalent to 'datastep = fac_den % fac_num' */ temp_n = i_mult2( datastep, fac_num ); /*Q0*/ fracstep = sub( fac_den, temp_n ); @@ -550,9 +542,6 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ FOR( i = 0; i < lg_out; i++ ) { sigOut_fx[i] = round_fx( L_shl( L_mult( sigOut_fx[i], num_den ), 1 ) ); /*Q0*/ - *Q_new_inp = -1; - move16(); - move16(); } } ELSE @@ -562,16 +551,17 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ test(); if ( GT_32( fin, 16000 ) && ( EQ_16( lg_out, L_FRAME ) || EQ_16( lg_out, L_FRAME16k ) || EQ_16( lg_out, 512 ) ) ) { +#ifdef BASOP_NOGLOB_DECLARE_LOCAL num_den = shl_o( num_den, 1, &Overflow ); - //*Q_new_inp = 2; +#else + num_den = shl( num_den, 1 ); +#endif } FOR( i = 0; i < lg_out; i++ ) { sigOut_fx[i] = mult_r( sigOut_fx[i], num_den ); /*Q0*/ move16(); } - *Q_new_inp = -1; - move16(); } } ELSE @@ -579,13 +569,10 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ IF( EQ_16( fac_num, 8 ) ) { num_den = 26214; - move16(); FOR( i = 0; i < lg_out; i++ ) { sigOut_fx[i] = mult_r( sigOut_fx[i], num_den ); /*Q-1*/ move16(); - *Q_new_inp = -2; - move16(); } } ELSE @@ -594,9 +581,6 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ FOR( i = 0; i < lg_out; i++ ) { sigOut_fx[i] = round_fx( L_mac( L_deposit_h( sigOut_fx[i] ), sigOut_fx[i], num_den ) ); /*Q0*/ - *Q_new_inp = -1; - move16(); - move16(); } } } @@ -607,8 +591,6 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ { sigOut_fx[i] = mult_r( sigOut_fx[i], 16384 ); move16(); /*Q-1*/ - *Q_new_inp = -2; - move16(); } } /* update the filter memory */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 65f0d2e69..70b70859c 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -2592,14 +2592,12 @@ Word16 modify_Fs_ivas_fx( /* o : length of output Q // modif_fs_fx.c Word16 modify_Fs_fx( /* o : length of output Q0 */ const Word16 sigIn_fx[], /* i : signal to decimate Q0 */ - Word16 lg, /* i : length of input Q0 */ - const Word32 fin, /* i : frequency of input Q0 */ + Word16 lg, /* i : length of i Q0 */ + const Word32 fin, /* i : frequency of i Q0 */ Word16 sigOut_fx[], /* o : decimated signal Q0 */ const Word32 fout, /* i : frequency of output Q0 */ Word16 mem_fx[], /* i/o: filter memory Q0 */ - const Word16 nblp, /* i : flag indicating if NB low-pass is applied */ - Word16 *Q_new_inp, // TO be removed - Word16 *mem_decim_size // TO be removed + const Word16 nblp /* i : flag indicating if NB low-pass is applied */ ); Word16 modify_Fs_intcub3m_sup_fx( /* o : length of output */ diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index 976826949..b1b2257e2 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -262,8 +262,7 @@ void amr_wb_enc_fx( /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ - Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( st->input_fx, input_frame, st->input_Fs, new_inp, 12800, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( st->input_fx, input_frame, st->input_Fs, new_inp, 12800, st->mem_decim_fx, 0 ); /* update signal buffer */ Copy( new_inp, st->buf_speech_enc + L_FRAME, L_FRAME ); /* Q0 */ @@ -450,7 +449,7 @@ void amr_wb_enc_fx( } ELSE IF( EQ_32( st->input_Fs, 32000 ) || EQ_32( st->input_Fs, 48000 ) ) { - modify_Fs_fx( st->input_fx, input_frame, st->input_Fs, new_inp_16k, 16000, st->mem_decim16k_fx, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( st->input_fx, input_frame, st->input_Fs, new_inp_16k, 16000, st->mem_decim16k_fx, 0 ); } /*----------------------------------------------------------------* diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index e1b5ca562..b65d41403 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -761,8 +761,7 @@ void CNG_enc_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0 ); } fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT ); @@ -1936,8 +1935,7 @@ void CNG_enc_ivas_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0 ); } fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT ); diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 757a69518..9c3a236d7 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -2700,7 +2700,7 @@ void stereoFdCngCoherence_fx( reset_indices_enc_fx( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); /* synchronize SID sending for variable SID rate */ - IF( EQ_32( sts[0]->core_brate, sts[1]->core_brate ) ) + IF( NE_32( sts[0]->core_brate, sts[1]->core_brate ) ) { sts[0]->core_brate = SID_2k40; move32(); diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index baaf33027..b37e61829 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -230,7 +230,7 @@ ivas_error front_vad_fx( MVR2R_WORD16( hFrontVad->buffer_12k8_fx + L_FFT, hFrontVad->buffer_12k8_fx, L_FFT / 2 ); /* Resample to 12k8 */ - modify_Fs_fx( sts[n]->input_fx, input_frame, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2, INT_FS_12k8, hFrontVad->mem_decim_fx, ( sts[0]->max_bwidth == NB ), &Qband, &mem_decim_size ); + modify_Fs_ivas_fx( sts[n]->input_fx, input_frame, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2, INT_FS_12k8, hFrontVad->mem_decim_fx, ( sts[0]->max_bwidth == NB ), &Qband, &mem_decim_size ); /* Preemphasis */ hFrontVad->mem_preemph_fx = shl( hFrontVad->mem_preemph_fx, sub( add( Q_inp, Qband ), hFrontVad->q_mem_preemph_fx ) ); /* Q_inp + Qband */ diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index bc84ba419..ad038f0fa 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -1395,7 +1395,7 @@ void stereo_icBWE_preproc_fx( Scale_sig( temp_inp_fx, L_FRAME48k, sub( 0, hStereoICBWE->q_dataChan_fx ) ); /* q_dataChan_fx */ /* IVAS-219: Re-wire the shb nonref estimation through a lite CLDFB */ - modify_Fs_fx( temp_inp_fx, L_FRAME32k, 32000, tempSHB_fx, 16000, hStereoICBWE->mem_decim_shb_ch0_fx, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_ivas_fx( temp_inp_fx, L_FRAME32k, 32000, tempSHB_fx, 16000, hStereoICBWE->mem_decim_shb_ch0_fx, 0, &Q_new_inp, &mem_decim_size ); Copy_Scale_sig( tempSHB_fx, shb_speech_nonref_fx, L_FRAME16k, sub( q_shb_speech_nonref_fx, Q_new_inp ) ); /* q_shb_speech_nonref_fx */ diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 4ce9403a6..6844945c0 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -213,8 +213,7 @@ void pre_proc_fx( /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ - Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ) ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* @@ -1017,7 +1016,7 @@ void pre_proc_fx( } ELSE IF( EQ_32( st->input_Fs, 32000 ) || EQ_32( st->input_Fs, 48000 ) ) { - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_16k, sr_core_tmp, st->mem_decim16k_fx, 0, &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_16k, sr_core_tmp, st->mem_decim16k_fx, 0 ); } ELSE /* keep memories up-to-date in case of bitrate switching */ { diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index e2e369389..4e0d3ab71 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -870,6 +870,9 @@ ivas_error ivas_dirac_alloc_mem_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands ); +#ifdef MSAN_FIX + set_zero_fx( hDirAC_mem->proto_direct_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len ); +#endif move16(); hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31; move16(); -- GitLab From dba7d7b4f255481595450c51ee5bcbc557e3a25b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 19 Mar 2025 12:36:30 +0530 Subject: [PATCH 0478/1221] Fix for 3GPP issue 1408: Decoder crash for ParamMC 5.1 at 48/64/80 kbps decoding to mono in ivas_ls_setup_conversion_fx() Link #1408 --- lib_dec/ivas_jbm_dec_fx.c | 11 ----------- lib_dec/ivas_mc_param_dec_fx.c | 17 ++++++++++++----- lib_dec/ivas_out_setup_conversion_fx.c | 6 +++--- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index e7ee06648..1918ce3f3 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1288,18 +1288,7 @@ ivas_error ivas_jbm_dec_tc_fx( test(); IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) { - s = Q16 - Q11; - move16(); - s = sub( s, find_guarded_bits_fx( st_ivas->nchan_transport ) ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, s ); - } ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); - } } } ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index db56ad03e..b2a8bd30b 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -123,7 +123,7 @@ ivas_error ivas_param_mc_dec_open_fx( Word16 nchan_out_transport; Word16 nchan_out_cov; Word32 proto_matrix_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word32 proto_mtx_norm_fx; + Word32 proto_mtx_norm_fx, tmp32; Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; Word16 max_param_band_residual; UWord16 config_index; @@ -374,20 +374,27 @@ ivas_error ivas_param_mc_dec_open_fx( Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), 4 ); /*Q.26*/ IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) { - proto_mtx_norm_fx = ONE_IN_Q26; /*Q26*/ + tmp32 = ONE_IN_Q26; /*Q26*/ move32(); FOR( k = 0; k < nchan_transport * nchan_out_cov; k++ ) { - proto_mtx_norm_fx = L_max( L_abs( proto_mtx_norm_fx ), L_abs( proto_matrix_fx[k] ) ); /*Q.26*/ + tmp32 = L_max( L_abs( tmp32 ), L_abs( proto_matrix_fx[k] ) ); /*Q.26*/ } - proto_mtx_norm_fx = divide3232( ONE_IN_Q26, proto_mtx_norm_fx ); /*Q15*/ + proto_mtx_norm_fx = divide3232( ONE_IN_Q26, tmp32 ); /*Q15*/ /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */ FOR( k = 0; k < nchan_transport; k++ ) { FOR( Word16 i = 0; i < nchan_out_cov; i++ ) { - st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mult_32_16( proto_matrix_fx[k * nchan_out_cov + i], extract_l( proto_mtx_norm_fx ) ), 4 ); /*Q.30*/ + IF( EQ_32( proto_matrix_fx[k * nchan_out_cov + i], tmp32 ) ) + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = ONE_IN_Q30; // Q30 + } + ELSE + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mult_32_16( proto_matrix_fx[k * nchan_out_cov + i], extract_l( proto_mtx_norm_fx ) ), 4 ); /*Q.30*/ + } move32(); } } diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index c7bf0655d..756eed60e 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -586,14 +586,14 @@ void ivas_ls_setup_conversion_fx( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ const Word16 input_chans, /* i : number of input channels to the renderer */ const Word16 output_frame, /* i : frame length */ - Word32 *input[], /* i : LS input/output synthesis signal Q16*/ - Word32 *output[] /* i/o: LS input/output synthesis signal Q16*/ + Word32 *input[], /* i : LS input/output synthesis signal Qx*/ + Word32 *output[] /* i/o: LS input/output synthesis signal Qx*/ ) { Word16 chInIdx, chOutIdx, idx; LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; Word32 dmxCoeff, tmpVal; - Word32 output_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // Q16 + Word32 output_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // Qx push_wmops( "LS_Renderer" ); -- GitLab From 6e0435fbb92fa433185b53278926e67f754f5368 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 19 Mar 2025 13:06:11 +0530 Subject: [PATCH 0479/1221] Q documentation for lib enc files --- lib_enc/gs_enc_fx.c | 151 ++++++--- lib_enc/guided_plc_enc_fx.c | 124 ++++---- lib_enc/ivas_tcx_core_enc_fx.c | 191 +++++------ lib_enc/ivas_td_low_rate_enc_fx.c | 64 ++-- lib_enc/lead_indexing_fx.c | 73 +++-- lib_enc/lib_enc.c | 511 +++++++++++++++++++++--------- lib_enc/lib_enc.h | 48 +-- lib_enc/long_enr_fx.c | 66 ++-- 8 files changed, 756 insertions(+), 472 deletions(-) diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 375d4c2cf..1642d1253 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -23,8 +23,8 @@ static Word16 edyn_fx( const Word16 *vec, const Word16 lvec, Word16 Qnew ); void encod_audio_fx( Encoder_State *st_fx, /* i/o: State structure */ const Word16 speech[], /* i : input speech Q_new */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12 */ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12 */ const Word16 *res, /* i : residual signal Q_new */ Word16 *synth, /* i/o: core synthesis Q-1 */ Word16 *exc, /* i/o: current non-enhanced excitation Q_new */ @@ -32,10 +32,10 @@ void encod_audio_fx( Word16 *voice_factors, /* o : voicing factors Q15 */ Word16 *bwe_exc, /* o : excitation for SWB TBE Q0 */ const Word16 attack_flag, /* i : Flag that point to an attack coded with AC mode (GSC) */ - Word16 *lsf_new, /* i : current frame ISF vector */ - Word16 *tmp_noise, /* o : noise energy */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 *lsf_new, /* i : current frame ISF vector Qx2.56 */ + Word16 *tmp_noise, /* o : noise energy Q2*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 Q_new, Word16 shift ) { @@ -43,9 +43,11 @@ void encod_audio_fx( Word16 i, i_subfr, nb_subfr, last_pit_bin; Word16 T0_tmp, T0_frac_tmp, nb_subfr_flag; Word16 tmp_nb_bits_tot = 0; + move16(); Word16 Es_pred; Word16 dct_res[L_FRAME16k], dct_epit[L_FRAME16k]; Word16 m_mean = 0; + move16(); Word16 saved_bit_pos; Word16 exc_wo_nf[L_FRAME16k]; Word32 Lm_mean; @@ -65,7 +67,7 @@ void encod_audio_fx( move16(); T0_frac_tmp = 0; move16(); - Copy( hLPDmem->mem_syn, hGSCEnc->mem_syn_tmp_fx, M ); + Copy( hLPDmem->mem_syn, hGSCEnc->mem_syn_tmp_fx, M ); /* hLPDmem->q_mem_syn */ hGSCEnc->mem_w0_tmp_fx = hLPDmem->mem_w0; move16(); Es_pred = 0; @@ -78,7 +80,7 @@ void encod_audio_fx( *---------------------------------------------------------------*/ #ifdef GSC_IVAS // TVB -->>>>>> test(); - if ( GT_16( st_fx->element_mode, EVS_MONO ) && st_fx->idchan == 0 ) + IF( ( st_fx->element_mode > EVS_MONO ) && st_fx->idchan == 0 ) { push_indice_fx( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); } @@ -99,6 +101,7 @@ void encod_audio_fx( test(); test(); test(); + test(); IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( NE_16( st_fx->coder_type, INACTIVE ) && ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && GE_32( st_fx->total_brate, ACELP_13k20 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && GT_32( st_fx->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) && GE_16( st_fx->bwidth, SWB ) && !st_fx->flag_ACELP16k ) ) ) ) { @@ -113,7 +116,7 @@ void encod_audio_fx( FOR( i = 0; i < 5; i++ ) { test(); - if ( GT_16( abs_s( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - i - 1] ), 1536 ) && EQ_16( hGSCEnc->cor_strong_limit, 1 ) ) + if ( GT_16( abs_s( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - i - 1] ), 1536 /*6.0 in Q8*/ ) && EQ_16( hGSCEnc->cor_strong_limit, 1 ) ) { hGSCEnc->cor_strong_limit = 0; move16(); @@ -121,6 +124,9 @@ void encod_audio_fx( } } test(); + test(); + test(); + test(); IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( st_fx->GSC_noisy_speech && st_fx->GSC_IVAS_mode == 0 ) ) { nb_subfr = NB_SUBFR; @@ -166,10 +172,14 @@ void encod_audio_fx( nb_subfr_flag = 1; move16(); } + + test(); + test(); + test(); IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && ( GT_16( hSpMusClas->mold_corr_fx, 26214 ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) && NE_16( st_fx->coder_type, INACTIVE ) ) ) { nb_subfr = shl( nb_subfr, 1 ); - nb_subfr_flag |= 0x2; + nb_subfr_flag = s_or( nb_subfr_flag, 0x2 ); logic16(); } @@ -194,14 +204,22 @@ void encod_audio_fx( * Compute adaptive (pitch) excitation contribution *---------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + test(); + test(); test(); IF( !( st_fx->GSC_IVAS_mode > 0 && EQ_16( st_fx->L_frame, i_mult( nb_subfr, 2 * L_SUBFR ) ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) && ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || st_fx->GSC_noisy_speech ) && ( ( EQ_16( nb_subfr, NB_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && EQ_16( st_fx->L_frame, L_FRAME16k ) ) ) ) ) { - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + IF( ( st_fx->element_mode > EVS_MONO ) ) { nb_bits = 5; + move16(); } ELSE { @@ -235,17 +253,20 @@ void encod_audio_fx( { /*st_fx->mid_dyn_fx = 0.2f * st_fx->mid_dyn_fx + 0.8f * m_mean;*/ hGSCEnc->mid_dyn_fx = round_fx( L_mac( L_mult( 26214, m_mean ), 6554, hGSCEnc->mid_dyn_fx ) ); /*Q7*/ + move16(); } ELSE { /*st_fx->mid_dyn_fx = 0.6f * st_fx->mid_dyn_fx + 0.4f * m_mean;*/ hGSCEnc->mid_dyn_fx = round_fx( L_mac( L_mult( 13107, m_mean ), 19661, hGSCEnc->mid_dyn_fx ) ); /*Q7*/ + move16(); } IF( NE_16( st_fx->coder_type, INACTIVE ) ) { hGSCEnc->noise_lev = sub( ( NOISE_LEVEL_SP3 + 1 ), usquant_fx( hGSCEnc->mid_dyn_fx, &m_mean, MIN_DYNAMIC_FX, shr( GSF_NF_DELTA_FX, 1 ), GSC_NF_STEPS ) ); - + move16(); hGSCEnc->noise_lev = s_min( hGSCEnc->noise_lev, NOISE_LEVEL_SP3 ); + move16(); } hGSCEnc->past_dyn_dec = hGSCEnc->noise_lev; @@ -253,6 +274,7 @@ void encod_audio_fx( IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) ) { hGSCEnc->noise_lev = NOISE_LEVEL_SP2; + move16(); IF( EQ_16( st_fx->GSC_IVAS_mode, 3 ) ) /* Music like */ { hGSCEnc->noise_lev = NOISE_LEVEL_SP0; @@ -267,12 +289,14 @@ void encod_audio_fx( ELSE IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { hGSCEnc->noise_lev = s_max( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ); + move16(); push_indice_fx( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ), 2 ); } ELSE IF( st_fx->GSC_noisy_speech ) { hGSCEnc->noise_lev = NOISE_LEVEL_SP3; move16(); + move16(); } ELSE { @@ -373,8 +397,8 @@ void encod_audio_fx( void encod_audio_ivas_fx( Encoder_State *st_fx, /* i/o: State structure */ const Word16 speech[], /* i : input speech Q_new */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12 */ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12 */ const Word16 *res, /* i : residual signal Q_new */ Word16 *synth, /* i/o: core synthesis Q-1 */ Word16 *exc, /* i/o: current non-enhanced excitation Q_new */ @@ -382,8 +406,8 @@ void encod_audio_ivas_fx( Word16 *voice_factors, /* o : voicing factors Q15 */ Word16 *bwe_exc, /* o : excitation for SWB TBE Q0 */ const Word16 attack_flag, /* i : Flag that point to an attack coded with AC mode (GSC) */ - Word16 *lsf_new, /* i : current frame ISF vector */ - Word16 *tmp_noise, /* o : noise energy */ + Word16 *lsf_new, /* i : current frame ISF vector Qx2.56 */ + Word16 *tmp_noise, /* o : noise energy Q8*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ Word16 Q_new, @@ -428,7 +452,7 @@ void encod_audio_ivas_fx( *---------------------------------------------------------------*/ test(); - if ( GT_16( st_fx->element_mode, EVS_MONO ) && st_fx->idchan == 0 ) + if ( ( st_fx->element_mode > EVS_MONO ) && st_fx->idchan == 0 ) { push_indice( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); } @@ -449,6 +473,7 @@ void encod_audio_ivas_fx( test(); test(); test(); + test(); IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( NE_16( st_fx->coder_type, INACTIVE ) && ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && GE_32( st_fx->total_brate, ACELP_13k20 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && GT_32( st_fx->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) && GE_16( st_fx->bwidth, SWB ) && !st_fx->flag_ACELP16k ) ) ) ) { @@ -471,6 +496,9 @@ void encod_audio_ivas_fx( } } test(); + test(); + test(); + test(); IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( st_fx->GSC_noisy_speech && st_fx->GSC_IVAS_mode == 0 ) ) { nb_subfr = NB_SUBFR; @@ -516,6 +544,10 @@ void encod_audio_ivas_fx( nb_subfr_flag = 1; move16(); } + + test(); + test(); + test(); IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && ( GT_16( hSpMusClas->mold_corr_fx, 26214 ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) && NE_16( st_fx->coder_type, INACTIVE ) ) ) { nb_subfr = shl( nb_subfr, 1 ); @@ -523,6 +555,7 @@ void encod_audio_ivas_fx( logic16(); } + test(); IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 2 ); @@ -544,14 +577,22 @@ void encod_audio_ivas_fx( * Compute adaptive (pitch) excitation contribution *---------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + test(); + test(); test(); IF( !( st_fx->GSC_IVAS_mode > 0 && EQ_16( st_fx->L_frame, i_mult( nb_subfr, 2 * L_SUBFR ) ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) && ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || st_fx->GSC_noisy_speech ) && ( ( EQ_16( nb_subfr, NB_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && EQ_16( st_fx->L_frame, L_FRAME16k ) ) ) ) ) { - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + IF( ( st_fx->element_mode > EVS_MONO ) ) { nb_bits = 5; + move16(); } ELSE { @@ -585,17 +626,20 @@ void encod_audio_ivas_fx( { /*st_fx->mid_dyn_fx = 0.2f * st_fx->mid_dyn_fx + 0.8f * m_mean;*/ hGSCEnc->mid_dyn_fx = round_fx( L_mac( L_mult( 26214, m_mean ), 6554, hGSCEnc->mid_dyn_fx ) ); /*Q7*/ + move16(); } ELSE { /*st_fx->mid_dyn_fx = 0.6f * st_fx->mid_dyn_fx + 0.4f * m_mean;*/ hGSCEnc->mid_dyn_fx = round_fx( L_mac( L_mult( 13107, m_mean ), 19661, hGSCEnc->mid_dyn_fx ) ); /*Q7*/ + move16(); } IF( NE_16( st_fx->coder_type, INACTIVE ) ) { hGSCEnc->noise_lev = sub( ( NOISE_LEVEL_SP3 + 1 ), usquant_fx( hGSCEnc->mid_dyn_fx, &m_mean, MIN_DYNAMIC_FX, shr( GSF_NF_DELTA_FX, 1 ), GSC_NF_STEPS ) ); - + move16(); hGSCEnc->noise_lev = s_min( hGSCEnc->noise_lev, NOISE_LEVEL_SP3 ); + move16(); } hGSCEnc->past_dyn_dec = hGSCEnc->noise_lev; @@ -603,6 +647,7 @@ void encod_audio_ivas_fx( IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) ) { hGSCEnc->noise_lev = NOISE_LEVEL_SP2; + move16(); IF( EQ_16( st_fx->GSC_IVAS_mode, 3 ) ) /* Music like */ { hGSCEnc->noise_lev = NOISE_LEVEL_SP0; @@ -708,7 +753,7 @@ void encod_audio_ivas_fx( * Synthesis *--------------------------------------------------------------------------------------*/ - p_Aq = Aq; + p_Aq = Aq; /* Q12 */ FOR( i_subfr = 0; i_subfr < st_fx->L_frame; i_subfr += L_SUBFR ) { Syn_filt_s( 1, p_Aq, M, &exc_wo_nf[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 ); @@ -721,7 +766,7 @@ void encod_audio_ivas_fx( hLPDmem->mem_w0 = hGSCEnc->mem_w0_tmp_fx; /*_DIFF_FLOAT_FIX_ The way it is written in the original fix point is that at this point mem_w0 falls back to its original value (before enc_pit_exc, seems not the case in float */ move16(); - Copy( exc_wo_nf, exc, st_fx->L_frame ); + Copy( exc_wo_nf, exc, st_fx->L_frame ); /* Q_new */ return; } @@ -753,14 +798,14 @@ void encod_audio_ivas_fx( void gsc_enc_fx( Encoder_State *st_fx, /* i/o: State structure */ - Word16 res_dct_in[], /* i : dct of residual signal */ - Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation */ + Word16 res_dct_in[], /* i : dct of residual signal Q_exc*/ + Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ const Word16 Diff_len, const Word16 bits_used, const Word16 nb_subfr, - Word16 *lsf_new, /* i : ISFs at the end of the frame */ - Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill */ - Word16 *tmp_noise, /* o : noise energy */ + Word16 *lsf_new, /* i : ISFs at the end of the frame Qx2.56*/ + Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ + Word16 *tmp_noise, /* o : noise energy Q2*/ Word16 Q_exc ) { Word16 y2_filt[L_FRAME16k]; @@ -794,6 +839,7 @@ void gsc_enc_fx( *--------------------------------------------------------------------------------------*/ bit = bits_used; + move16(); test(); test(); test(); @@ -841,10 +887,14 @@ void gsc_enc_fx( { IF( LE_32( st_fx->core_brate, brate_intermed_tbl[i] ) ) { - break; + BREAK; } i++; } + + test(); + test(); + test(); if ( GT_16( st_fx->element_mode, EVS_MONO ) && EQ_16( st_fx->coder_type, AUDIO ) && LE_32( st_fx->core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ { @@ -854,6 +904,7 @@ void gsc_enc_fx( mean_gain = gsc_gainQ_fx( hBstr, /*st_fX->element_mode, st_fx->idchan,IVAS_CODE*/ Ener_per_bd_iQ, Ener_per_bd_iQ, brate_intermed_tbl[i], st_fx->coder_type, st_fx->bwidth /*, st_fx->L_frame, st_fx->tdm_LRTD_flag, st_fx->core_brate*/ ); *tmp_noise = mult_r( 320, mean_gain ); /*10 in Q5 lp_gainc in Q3 */ + move16(); /*--------------------------------------------------------------------------------------* * Frequency encoder @@ -873,7 +924,7 @@ void gsc_enc_fx( { tmp = pvq_core_enc_fx( hBstr, concat_in, concat_out, &Q_tmp, bit, nb_subbands, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); - Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); + Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ bit = sub( bit, tmp ); } /* write unused bits */ @@ -974,11 +1025,11 @@ void gsc_enc_ivas_fx( const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ const Word16 bits_used, /* i : Number of bit used before frequency Q */ const Word16 nb_subfr, /* i : Number of subframe considered */ - const Word16 *lsf_new_fx, + const Word16 *lsf_new_fx, /* Qx2.56 */ /* i : ISFs at the end of the frame */ // Q15 Word16 *exc_wo_nf_fx, /* o : excitation (in f domain) without noisefill */ // Q_exc - Word16 *tmp_noise_fx, /* o : long-term noise energy */ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q8*/ Word16 *Q_exc ) { Word16 i; @@ -1031,7 +1082,7 @@ void gsc_enc_ivas_fx( * (non valuable temporal content present in exc_dct_in is already zeroed) *--------------------------------------------------------------------------------------*/ - v_sub_16( res_dct_in_fx, exc_dct_in_fx, exc_diff_fx, st->L_frame ); + v_sub_16( res_dct_in_fx, exc_dct_in_fx, exc_diff_fx, st->L_frame ); /* Q_exc */ exc_diff_fx[0] = 0; move16(); @@ -1064,18 +1115,18 @@ void gsc_enc_ivas_fx( { IF( LE_32( st->core_brate, brate_intermed_tbl[i] ) ) { - break; + BREAK; } - i = add( i, 1 ); + i++; } test(); test(); test(); - IF( st->element_mode > EVS_MONO && EQ_16( st->coder_type, AUDIO ) && - LE_32( st->core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ + if ( st->element_mode > EVS_MONO && EQ_16( st->coder_type, AUDIO ) && + LE_32( st->core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ { - i = sub( i, 1 ); + i--; } mean_gain_fx = gsc_gainQ_ivas_fx( hBstr, st->element_mode, st->idchan, Ener_per_bd_iQ_fx, Ener_per_bd_iQ_fx, brate_intermed_tbl[i], st->coder_type, st->bwidth, st->L_frame, st->tdm_LRTD_flag, st->core_brate ); @@ -1129,18 +1180,18 @@ void gsc_enc_ivas_fx( j = emaximum_fx( Q12, concat_out_fx, shl( nb_subbands, 4 ), &L_tmp ); IF( LE_16( add( abs_s( concat_out_fx[j] ), 41 /* 0.01f in Q12 */ ), ONE_IN_Q12 ) ) { - max_eq = 32767; + max_eq = 32767; /* Q15 */ move16(); } ELSE { - max_eq = div_s( ONE_IN_Q12, add( abs_s( concat_out_fx[j] ), 41 /* 0.01f in Q12 */ ) ); + max_eq = div_s( ONE_IN_Q12, add( abs_s( concat_out_fx[j] ), 41 /* 0.01f in Q12 */ ) ); /* Q15 */ } } FOR( j = 0; j < nb_subbands; j++ ) { - Copy( concat_out_fx + i_mult( j, 16 ), exc_diffQ_fx + i_mult( max_ener_band[j], 16 ), 16 ); + Copy( concat_out_fx + i_mult( j, 16 ), exc_diffQ_fx + i_mult( max_ener_band[j], 16 ), 16 ); /* Q12 */ IF( GT_16( max_ener_band[j], last_bin ) ) { @@ -1209,7 +1260,7 @@ void gsc_enc_ivas_fx( { FOR( i = 64; i < st->L_frame; i++ ) { - exc_diffQ_fx[i] = mult( exc_diffQ_fx[i], max_eq ); + exc_diffQ_fx[i] = mult( exc_diffQ_fx[i], max_eq ); /* Q12 */ move16(); } } @@ -1217,7 +1268,7 @@ void gsc_enc_ivas_fx( { FOR( i = 0; i < L_FRAME; i++ ) { - exc_diffQ_fx[i] = mult( exc_diffQ_fx[i], max_eq ); + exc_diffQ_fx[i] = mult( exc_diffQ_fx[i], max_eq ); /* Q12 */ move16(); } } @@ -1229,13 +1280,13 @@ void gsc_enc_ivas_fx( Word16 Q_exc_new = s_min( *Q_exc, hGSCEnc->Q_last_exc_dct_in ); IF( NE_16( Q_exc_new, hGSCEnc->Q_last_exc_dct_in ) ) { - Scale_sig( hGSCEnc->last_exc_dct_in_fx, st->L_frame, sub( Q_exc_new, hGSCEnc->Q_last_exc_dct_in ) ); + Scale_sig( hGSCEnc->last_exc_dct_in_fx, st->L_frame, sub( Q_exc_new, hGSCEnc->Q_last_exc_dct_in ) ); /* Q_exc_new */ hGSCEnc->Q_last_exc_dct_in = Q_exc_new; move16(); } ELSE { - Scale_sig( exc_dct_in_fx, st->L_frame, sub( Q_exc_new, *Q_exc ) ); + Scale_sig( exc_dct_in_fx, st->L_frame, sub( Q_exc_new, *Q_exc ) ); /* Q_exc_new */ *Q_exc = Q_exc_new; move16(); } @@ -1275,7 +1326,7 @@ void gsc_enc_ivas_fx( /*=======================================================================*/ static Word16 edyn_fx( /* o : ratio of max to mean */ - const Word16 *vec, /* i : input vector */ + const Word16 *vec, /* i : input vector Qnew*/ const Word16 lvec, /* i : length of input vector */ Word16 Qnew ) { @@ -1286,6 +1337,7 @@ static Word16 edyn_fx( /* o : ratio of max to mean */ Word16 scale; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif ener_mean = L_shl( 1, shl( Qnew, 1 ) ); /*2*Qnew*/ @@ -1323,10 +1375,10 @@ static Word16 edyn_fx( /* o : ratio of max to mean */ } ELSE { - dyn = 1280; + dyn = 1280; /* 10.0f in Q7 */ move16(); } - return dyn; + return dyn; /* Q7 */ } @@ -1341,7 +1393,7 @@ void GSC_enc_init_fx( ) { /* AC mode */ - hGSCEnc->seed_tcx = 15687; + hGSCEnc->seed_tcx = 15687; /* Q0 */ move16(); hGSCEnc->cor_strong_limit = 1; move16(); @@ -1351,6 +1403,7 @@ void GSC_enc_init_fx( set16_fx( hGSCEnc->last_bitallocation_band, 0, 6 ); hGSCEnc->mem_last_pit_band = BAND1k2 + 1; + move16(); hGSCEnc->Last_frame_ener_fx = MAX_32; move32(); hGSCEnc->lt_gpitch_fx = 0; @@ -1363,8 +1416,8 @@ void GSC_enc_init_fx( move16(); set16_fx( hGSCEnc->mem_syn_tmp_fx, 0, M ); - hGSCEnc->mid_dyn_fx = 5120; - move16(); /*40 -> Q7 */ + hGSCEnc->mid_dyn_fx = 5120; /*40 -> Q7 */ + move16(); hGSCEnc->noise_lev = NOISE_LEVEL_SP0; move16(); hGSCEnc->past_dyn_dec = 0; diff --git a/lib_enc/guided_plc_enc_fx.c b/lib_enc/guided_plc_enc_fx.c index 9aa2ecb65..60a3f8f50 100644 --- a/lib_enc/guided_plc_enc_fx.c +++ b/lib_enc/guided_plc_enc_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "stat_enc.h" @@ -19,8 +18,8 @@ * *-------------------------------------------------------------------*/ static void coderLookAheadInnovation( - Word16 A_3Q12[], /* input: coefficients NxAz[M+1] */ - Word16 *pT, /* out: pitch */ + Word16 A_3Q12[], /* input: coefficients NxAz[M+1] Q12*/ + Word16 *pT, /* out: pitch Q0*/ PLC_ENC_EVS_HANDLE st, /* i/o: coder memory state */ Word16 *speechLookAhead_Qx, /* i: input speech in Q(st->Qold) */ Word16 *old_exc, /* i: input excitation in Q(st->Qold) */ @@ -41,13 +40,18 @@ static void coderLookAheadInnovation( Word32 max_ps, max_ps_tmp; Word16 max_ps_e; Word16 tmp_loop; + move32(); + move16(); + move16(); #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* Debug init (not instrumented) */ T0_fx = -3000; + move16(); subfr_len = shl( L_SUBFR, 1 ); /* 2*L_SUBFR */ if ( GT_16( L_FRAME16k, L_frame ) ) { @@ -59,10 +63,10 @@ static void coderLookAheadInnovation( * - BASOP specific initialization. * *------------------------------------------------------------------------*/ /* initialization */ - exc_Qx = exc_buf_Qx + L_EXC_MEM + 8; + exc_Qx = exc_buf_Qx + L_EXC_MEM + 8; /* Q(st->Qold) */ FOR( i = 0; i < L_EXC_MEM + 8; i++ ) { - exc_buf_Qx[i] = old_exc[i]; + exc_buf_Qx[i] = old_exc[i]; /* Q(st->Qold) */ move16(); } @@ -72,17 +76,17 @@ static void coderLookAheadInnovation( *------------------------------------------------------------------------*/ /* find LP residual signal for look-ahead part */ getLookAheadResSig( speechLookAhead_Qx, A_3Q12, exc_Qx, L_frame, 2 ); - Scale_sig( exc_Qx, subfr_len, 1 ); + Scale_sig( exc_Qx, subfr_len, 1 ); /* Q(st->Qold) + 1 */ /* find target signals */ - prev_pitch = st->T0_4th; + prev_pitch = st->T0_4th; /* Q0 */ move16(); /* find best candidate of pitch lag */ - T0_fx = st->T0_4th; + T0_fx = st->T0_4th; /* Q0 */ move16(); - mantissa_max = -0x7fffffffL; + mantissa_max = -0x7fffffffL; /* Q15 */ move32(); - max_ps = -0x7fffffffL; + max_ps = -0x7fffffffL; /* Q15 */ move32(); max_ps_e = 16; move16(); @@ -90,14 +94,14 @@ static void coderLookAheadInnovation( /*find maximum*/ exc_max = 0; move16(); - tmp_loop = s_min( -prev_pitch + search_range + subfr_len, 0 ); + tmp_loop = s_min( -prev_pitch + search_range + subfr_len, 0 ); /* Q0 */ FOR( i = -prev_pitch - search_range; i < tmp_loop; i++ ) { - exc_max = s_max( exc_Qx[i], exc_max ); + exc_max = s_max( exc_Qx[i], exc_max ); /* Q(st->Qold) + 1 */ } FOR( i = 0; i < subfr_len; i++ ) { - exc_max = s_max( exc_max, exc_Qx[i] ); + exc_max = s_max( exc_max, exc_Qx[i] ); /* Q(st->Qold) + 1 */ } /*calculate scaling factor for optimal precision and assure no overflow in dotproduct*/ exc_sh = sub( 15, norm_s( sub( subfr_len, 1 ) ) ); /*ceil(ld(subfr_len))*/ @@ -105,15 +109,15 @@ static void coderLookAheadInnovation( exc_sh = shr( add( exc_sh, 1 ), 1 ); /*scale buffer only where its needed*/ - tmp_loop = s_min( -prev_pitch + search_range + subfr_len, 0 ); + tmp_loop = s_min( -prev_pitch + search_range + subfr_len, 0 ); /* Q0 */ FOR( i = -prev_pitch - search_range; i < tmp_loop; i++ ) { - exc_Qx[i] = shr( exc_Qx[i], exc_sh ); + exc_Qx[i] = shr( exc_Qx[i], exc_sh ); /* Q(st->Qold) + 1 */ move16(); } FOR( i = 0; i < subfr_len; i++ ) { - exc_Qx[i] = shr( exc_Qx[i], exc_sh ); + exc_Qx[i] = shr( exc_Qx[i], exc_sh ); /* Q(st->Qold) + 1 */ move16(); } @@ -122,7 +126,7 @@ static void coderLookAheadInnovation( move16(); FOR( i = -prev_pitch - search_range; i < -prev_pitch + search_range + subfr_len; i++ ) { - alp_ini = L_mac( alp_ini, exc_Qx[i], exc_Qx[i] ); + alp_ini = L_mac( alp_ini, exc_Qx[i], exc_Qx[i] ); /* 2*(Q(st->Qold) + 1) + 1 */ } FOR( i = -search_range; i < search_range; i++ ) @@ -138,24 +142,24 @@ static void coderLookAheadInnovation( FOR( k = 0; k < subfr_len; k++ ) { - ps = L_mac( ps, exc_Qx[k], exc_Qx[k - prev_pitch - i] ); + ps = L_mac( ps, exc_Qx[k], exc_Qx[k - prev_pitch - i] ); /* 2*(Q(st->Qold) + 1) + 1 */ } /*calculate "small" dotproducts in order to subtract them from the "bigger" one*/ - FOR( k = negate( add( prev_pitch, search_range ) ); k < -prev_pitch - i; k++ ) + FOR( k = -( ( prev_pitch + search_range ) ); k < -prev_pitch - i; k++ ) { - alp_s1 = L_mac( alp_s1, exc_Qx[k], exc_Qx[k] ); + alp_s1 = L_mac( alp_s1, exc_Qx[k], exc_Qx[k] ); /* 2*(Q(st->Qold) + 1) + 1 */ } tmp_loop = sub( add( search_range, subfr_len ), prev_pitch ); FOR( k = +subfr_len - i - prev_pitch; k < tmp_loop; k++ ) { - alp_s2 = L_mac( alp_s2, exc_Qx[k], exc_Qx[k] ); + alp_s2 = L_mac( alp_s2, exc_Qx[k], exc_Qx[k] ); /* 2*(Q(st->Qold) + 1) + 1 */ } alp = L_sub( alp_ini, L_add( alp_s1, alp_s2 ) ); alp = L_max( alp, 1 ); /* alp must not be 0 */ alp_e = shl( exc_sh, 1 ); ps_e = shl( exc_sh, 1 ); - alp = ISqrt32( alp, &alp_e ); + alp = ISqrt32( alp, &alp_e ); /* Q31-alp_e */ ps = Mpy_32_16_1( ps, round_fx( alp ) ); /*alp_e+ps_e*/ ps_e = add( alp_e, ps_e ); @@ -173,7 +177,7 @@ static void coderLookAheadInnovation( T0_fx = add( prev_pitch, i ); } } - mantissa_max = max_ps; + mantissa_max = max_ps; /* Q31-ps_e */ move32(); if ( mantissa_max < 0 ) { @@ -239,9 +243,9 @@ void enc_prm_side_Info_fx( void encoderSideLossSimulation_fx( Encoder_State *st, PLC_ENC_EVS_HANDLE hPlc_Ext, - Word16 *lsf_q, /* Q1*1.28 */ - const Word16 stab_fac, /* Q15 */ - const Word16 calcOnlyISF, + Word16 *lsf_q, /* Qx2.56 */ + const Word16 stab_fac, /* Q15 */ + const Word16 calcOnlyISF, /* Q0 */ const Word16 L_frame ) { Word16 lspLocal_Q15[M]; @@ -251,11 +255,11 @@ void encoderSideLossSimulation_fx( /* Decoder State Update */ IF( EQ_16( L_frame, L_FRAME_16k ) ) { - lsf2lsp_fx( lsf_q, lspLocal_Q15, M, INT_FS_16k_FX ); + lsf2lsp_fx( lsf_q, lspLocal_Q15, M, INT_FS_16k_FX ); /* Q15 */ } ELSE { - lsf2lsp_fx( lsf_q, lspLocal_Q15, M, INT_FS_FX ); + lsf2lsp_fx( lsf_q, lspLocal_Q15, M, INT_FS_FX ); /* Q15 */ } @@ -263,8 +267,8 @@ void encoderSideLossSimulation_fx( st->narrowBand, st->sr_core ); - Copy( st->mem_MA_fx, hPlc_Ext->mem_MA_14Q1, M ); - Copy( st->mem_AR_fx, hPlc_Ext->mem_AR, M ); + Copy( st->mem_MA_fx, hPlc_Ext->mem_MA_14Q1, M ); /* Qx2.56 */ + Copy( st->mem_AR_fx, hPlc_Ext->mem_AR, M ); /* Qx2.56 */ /* ISF parameter processing for concealment */ @@ -272,15 +276,15 @@ void encoderSideLossSimulation_fx( hPlc_Ext->stab_fac_Q15 = stab_fac; move16(); - Copy( lsf_q, hPlc_Ext->lsfold_14Q1, M ); - Copy( lspLocal_Q15, hPlc_Ext->lspold_Q15, M ); + Copy( lsf_q, hPlc_Ext->lsfold_14Q1, M ); /* Qx2.56 */ + Copy( lspLocal_Q15, hPlc_Ext->lspold_Q15, M ); /* Q15 */ IF( calcOnlyISF != 0 ) { /* ISF concealment simulation */ getConcealedLSF( hPlc_Ext, xsfBase, st->clas, L_frame ); - hPlc_Ext->T0 = hPlc_Ext->T0_4th; + hPlc_Ext->T0 = hPlc_Ext->T0_4th; /* Q0 */ move16(); } ELSE @@ -300,9 +304,9 @@ void encoderSideLossSimulation_fx( getConcealedLP( hPlc_Ext, A_3Q12, xsfBase, st->clas, L_frame ); /* apply encoder side PLC simulation */ - hPlc_Ext->pit_min = st->pit_min; + hPlc_Ext->pit_min = st->pit_min; /* Q0 */ move16(); - hPlc_Ext->pit_max = st->pit_max; + hPlc_Ext->pit_max = st->pit_max; /* Q0 */ move16(); coderLookAheadInnovation( A_3Q12, &( hPlc_Ext->T0 ), hPlc_Ext, speechLookAhead_Qx, old_exc_Qx, L_frame ); } @@ -336,11 +340,11 @@ void GplcTcxEncSetup_fx( * *-------------------------------------------------------------------*/ Word16 encSideSpecPowDiffuseDetector_fx( - Word16 *lsf_ref, - Word16 *lsf_con, - const Word32 sr_core, - Word16 *prev_lsf4_mean, - const Word8 sw, + Word16 *lsf_ref, /* Qx2.56 */ + Word16 *lsf_con, /* Qx2.56 */ + const Word32 sr_core, /* Q0 */ + Word16 *prev_lsf4_mean, /* Qx2.56 */ + const Word8 sw, /* Q0 */ const Word16 coder_type ) { Word16 tmp; @@ -355,14 +359,14 @@ Word16 encSideSpecPowDiffuseDetector_fx( /* calculate the mean of the lowest 4 LSFs */ - L_tmp = L_mult( lsf_ref[0], 8192 /*1.0/4.0 Q15*/ ); - L_tmp = L_mac( L_tmp, lsf_ref[1], 8192 /*1.0/4.0 Q15*/ ); - L_tmp = L_mac( L_tmp, lsf_ref[2], 8192 /*1.0/4.0 Q15*/ ); - lsf4_mean = mac_r( L_tmp, lsf_ref[3], 8192 /*1.0/4.0 Q15*/ ); + L_tmp = L_mult( lsf_ref[0], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */ + L_tmp = L_mac( L_tmp, lsf_ref[1], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */ + L_tmp = L_mac( L_tmp, lsf_ref[2], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */ + lsf4_mean = mac_r( L_tmp, lsf_ref[3], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */ IF( sw ) { - Copy( lsf_con, lsf_mod, M ); + Copy( lsf_con, lsf_mod, M ); /* Qx2.56 */ modify_lsf( lsf_mod, M, sr_core, 1 ); @@ -372,28 +376,29 @@ Word16 encSideSpecPowDiffuseDetector_fx( cum_dist2 = 0; cnt_imprv = 0; + move16(); IF( EQ_32( sr_core, INT_FS_16k ) ) { - th = 2560; - move16(); /* LSF */ - th_dif = 288; - move16(); /* LSF */ + th = 2560; /* Qx2.56 */ + move16(); /* LSF */ + th_dif = 288; /* Qx2.56 */ + move16(); /* LSF */ } ELSE { - th = 2048; - move16(); /* LSF */ - th_dif = 230; - move16(); /* LSF */ + th = 2048; /* Qx2.56 */ + move16(); /* LSF */ + th_dif = 230; /* Qx2.56 */ + move16(); /* LSF */ } FOR( i = 0; i < M; i++ ) { tmp = sub( lsf_con[i], lsf_ref[i] ); - dist1 = L_mult( tmp, tmp ); + dist1 = L_mult( tmp, tmp ); /* 2*(Qx2.56)+1 */ tmp = sub( lsf_mod[i], lsf_ref[i] ); - dist2 = L_mult( tmp, tmp ); + dist2 = L_mult( tmp, tmp ); /* 2*(Qx2.56)+1 */ if ( GT_32( dist1, dist2 ) ) { @@ -409,6 +414,7 @@ Word16 encSideSpecPowDiffuseDetector_fx( test(); test(); test(); + test(); if ( GT_32( cum_dist1, L_add( cum_dist2, Mpy_32_16_1( cum_dist2, 4915 ) ) ) && GT_16( sub( lsf4_mean, *prev_lsf4_mean ), th_dif ) && LT_16( *prev_lsf4_mean, th ) && GT_16( cnt_imprv, 2 ) && EQ_16( coder_type, GENERIC ) ) { idx = 1; @@ -438,17 +444,19 @@ void updateSpecPowDiffuseIdx_fx( Word16 k; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif move32(); move16(); - st->mean_gc[1] = st->gain_code[0]; - min_gp = st->bpf_gainT[0]; + st->mean_gc[1] = st->gain_code[0]; /* Q15 */ + min_gp = st->bpf_gainT[0]; /* Q15 */ FOR( k = 1; k < 4; k++ ) { st->mean_gc[1] = L_add_o( st->mean_gc[1], st->gain_code[k], &Overflow ); + move32(); min_gp = s_min( min_gp, st->bpf_gainT[k] ); } @@ -460,5 +468,5 @@ void updateSpecPowDiffuseIdx_fx( st->glr_idx[0] = 0; } move16(); - st->mean_gc[0] = st->mean_gc[1]; + st->mean_gc[0] = st->mean_gc[1]; /* Q15 */ } diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 3dc5f5b8a..eabfe87b4 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -78,27 +78,27 @@ void stereo_tcx_init_enc_fx( move16(); } - st->hTcxCfg->coder_type = st->coder_type; + st->hTcxCfg->coder_type = st->coder_type; /* Q0 */ move16(); test(); test(); - IF( !st->tcxonly && !st->localVAD && EQ_16( st->hTcxCfg->coder_type, GENERIC ) ) + if ( !st->tcxonly && !st->localVAD && EQ_16( st->hTcxCfg->coder_type, GENERIC ) ) { st->hTcxCfg->coder_type = UNVOICED; move16(); } /*sampling rate*/ - total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); + total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); /* Q0 */ st->sr_core = getCoreSamplerateMode2( st->element_mode, total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); move32(); st->fscale = sr2fscale_fx( st->sr_core ); move16(); /*frame size*/ - st->L_frame = extract_l( Mpy_32_32( st->sr_core, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + st->L_frame = extract_l( Mpy_32_32( st->sr_core, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ move16(); - st->hTcxEnc->L_frameTCX = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + st->hTcxEnc->L_frameTCX = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ move16(); test(); @@ -117,17 +117,17 @@ void stereo_tcx_init_enc_fx( } /*TCX tools*/ - st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, total_brate, st->rf_mode ); + st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, total_brate, st->rf_mode ); /* Q0 */ move16(); - st->hTcxCfg->resq = getResq( total_brate ); + st->hTcxCfg->resq = getResq( total_brate ); /* Q0 */ move16(); - st->hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( total_brate, st->rf_mode, st->element_mode ); + st->hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( total_brate, st->rf_mode, st->element_mode ); /* Q0 */ move16(); - st->igf = getIgfPresent_fx( st->element_mode, total_brate, st->bwidth, st->rf_mode ); + st->igf = getIgfPresent_fx( st->element_mode, total_brate, st->bwidth, st->rf_mode ); /* Q0 */ move16(); prev_IsTNSAllowed = st->hTcxCfg->fIsTNSAllowed; move16(); - IF( NE_16( st->element_mode, EVS_MONO ) ) + if ( ( st->element_mode != EVS_MONO ) ) { st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( total_brate, st->igf, st->element_mode ); move16(); @@ -154,8 +154,8 @@ void stereo_tcx_init_enc_fx( void stereo_tcx_core_enc( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 new_samples_12k8[], /* i : buffer of input signal @12.8 kHz */ - const Word16 new_samples_16k[], /* i : buffer of input signal @16 kHz */ + const Word16 new_samples_12k8[], /* i : buffer of input signal @12.8 kHz Q_new*/ + const Word16 new_samples_16k[], /* i : buffer of input signal @16 kHz Q_new*/ const Word16 Aw_fx[], /* i : weighted A(z) unquant. for subframes, Q12 */ Word16 lsp_new_fx[], /* i : LSPs at the end of the frame, Q15 */ Word16 lsp_mid_fx[], /* i : LSPs in the middle of the frame, Q15 */ @@ -242,14 +242,14 @@ void stereo_tcx_core_enc( *---------------------------------------------------------------*/ /* Subtract the bits of common header */ - st->bits_frame_core = extract_l( L_sub( Mpy_32_32( st->total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ), hBstr->nb_bits_tot ) ); + st->bits_frame_core = extract_l( L_sub( Mpy_32_32( st->total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ), hBstr->nb_bits_tot ) ); /* Q0 */ move16(); /*Get Bits of TCX header*/ nbits_header = 3; /* Coder types (2) + last_core for bfi (1) */ move16(); - IF( st->tcxonly ) + if ( st->tcxonly ) { /* TCX20/10 flag */ nbits_header = add( nbits_header, 1 ); @@ -281,7 +281,7 @@ void stereo_tcx_core_enc( move16(); /* check minimum pitch for quantization */ - IF( LT_16( T_op[i], PIT_MIN_SHORTER ) ) + if ( LT_16( T_op[i], PIT_MIN_SHORTER ) ) { T_op[i] = shl( T_op[i], 1 ); move16(); @@ -302,11 +302,11 @@ void stereo_tcx_core_enc( IF( EQ_16( st->L_frame, L_FRAME ) ) { - p_new_samples = new_samples_12k8; + p_new_samples = new_samples_12k8; /* Q_new */ } ELSE { - p_new_samples = new_samples_16k; + p_new_samples = new_samples_16k; /* Q_new */ } /*--------------------------------------------------------------* @@ -351,7 +351,7 @@ void stereo_tcx_core_enc( q_ind_val = 0; move16(); test(); - IF( NE_16( st->last_core, ACELP_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) + if ( ( st->last_core != ACELP_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) { q_ind_val = 1; move16(); @@ -372,10 +372,9 @@ void stereo_tcx_core_enc( *---------------------------------------------------------------*/ /* TODO: integrate this. */ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS st->prev_Q_new = 0; st->Q_old = 0; -#endif + Q_new = 0; move16(); input_frame = idiv1616U( extract_l( L_shr( st->input_Fs, 1 ) ), FRAMES_PER_SEC / 2 ); @@ -389,27 +388,31 @@ void stereo_tcx_core_enc( core_signal_analysis_high_bitrate_ivas_fx( p_new_samples, T_op, lsp_new_fx, lsp_mid_fx, st, tnsSize, tnsBits, param_core, <pBits, NULL, st->L_frame, hTcxEnc->L_frameTCX, last_element_mode, vad_hover_flag, NULL, NULL, &Q_new, NULL ); bitsAvailable = sub( st->bits_frame_core, nbits_header ); - IF( st->igf ) + if ( st->igf ) { bitsAvailable = sub( bitsAvailable, st->hIGFEnc->infoTotalBitsWritten ); } - const Word16 Q_ener = Q_new + Q_SCALE - 2; // Q_new + Q_SCALE -2 + const Word16 Q_ener = add( Q_new, sub( Q_SCALE, 2 ) ); // Q_new + Q_SCALE -2 Q_exc = Q_new; st->prev_Q_new = Q_exc; + move16(); + move16(); + move16(); IF( st->hTdCngEnc ) { FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) { - Scale_sig( st->hTdCngEnc->cng_exc2_buf + ii * L_FFT, L_FFT, sub( Q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ) ); + Scale_sig( st->hTdCngEnc->cng_exc2_buf + ii * L_FFT, L_FFT, sub( Q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ) ); /* Q_exc */ st->hTdCngEnc->cng_Qexc_buf[ii] = Q_exc; + move16(); } } - Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( Q_new, st->hLPDmem->q_lpd_old_exc ) ); + Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( Q_new, st->hLPDmem->q_lpd_old_exc ) ); /* Q_exc */ st->hLPDmem->q_lpd_old_exc = Q_new; move16(); - Scale_sig( st->hLPDmem->syn, M + 1, sub( st->Q_syn, st->hLPDmem->q_lpd_syn ) ); + Scale_sig( st->hLPDmem->syn, M + 1, sub( st->Q_syn, st->hLPDmem->q_lpd_syn ) ); /* st->Q_syn */ st->hLPDmem->q_lpd_syn = st->Q_syn; move16(); @@ -432,8 +435,8 @@ void stereo_tcx_core_enc( IF( st->rate_switching_reset ) { - Copy( lsp_q_fx, st->lsp_old_fx, M ); - Copy( lsf_q_fx, st->lsf_old_fx, M ); + Copy( lsp_q_fx, st->lsp_old_fx, M ); /* Q15 */ + Copy( lsf_q_fx, st->lsf_old_fx, M ); /* Qx2.56 */ } } @@ -515,12 +518,12 @@ void stereo_tcx_core_enc( * Run TCX10/20 Core *---------------------------------------------------------------*/ - hTcxEnc->measuredBwRatio = ONE_IN_Q14; + hTcxEnc->measuredBwRatio = ONE_IN_Q14; /* Q14 */ move16(); FOR( n = 0; n < n_subframes; n++ ) { - target_bits[n] = sub( idiv1616( add( bitsAvailable, sub( sub( n_subframes, 1 ), n ) ), n_subframes ), tnsBits[n] ); + target_bits[n] = sub( idiv1616( add( bitsAvailable, sub( sub( n_subframes, 1 ), n ) ), n_subframes ), tnsBits[n] ); /* Q0 */ move16(); test(); @@ -541,7 +544,7 @@ void stereo_tcx_core_enc( { tmp1 = idiv1616( tmp1, n_subframes ); } - tmp2 = imult1616( n, NPRM_DIV ); + tmp2 = imult1616( n, NPRM_DIV ); /* Q0 */ QuantizeSpectrum_ivas_fx( st, A_q_fx, A_q_ind, gainlpc_fx[n], gainlpc_e[n], st->synth + tmp1, target_bits[n], tnsSize[n], param_core + tmp2, n, &hm_cfg[n], vad_hover_flag ); } @@ -557,8 +560,8 @@ void stereo_tcx_core_enc( s = s_min( s, norm_s( st->wspeech_enc[st->L_frame - 1] ) ); st->wspeech_enc[st->L_frame - 1] = shl( st->wspeech_enc[st->L_frame - 1], s ); } - Scale_sig( st->synth, st->L_frame, s ); - Scale_sig( st->hLPDmem->syn, M + 1, s ); + Scale_sig( st->synth, st->L_frame, s ); /* st->Q_syn + s */ + Scale_sig( st->hLPDmem->syn, M + 1, s ); /* st->Q_syn + s */ Q_new = add( Q_new, s ); move16(); move16(); @@ -578,8 +581,8 @@ void stereo_tcx_core_enc( IF( st->enableTcxLpc && st->core != ACELP_CORE ) { /* Update lsf / lsp memory */ - Copy( lsf_tcx_q_fx, st->lsf_old_fx, M ); - Copy( lsp_tcx_q_fx, st->lsp_old_fx, M ); + Copy( lsf_tcx_q_fx, st->lsf_old_fx, M ); /* Qx2.56 */ + Copy( lsp_tcx_q_fx, st->lsp_old_fx, M ); /* Q15 */ st->envWeighted = 1; move16(); @@ -592,12 +595,12 @@ void stereo_tcx_core_enc( /* check resonance for pitch clipping algorithm */ gp_clip_test_lsf_ivas_fx( st->element_mode, st->core_brate, st->lsf_old_fx, st->clip_var_fx, 0 ); - Copy( st->lsf_old_fx, st->mem_AR_fx, M ); + Copy( st->lsf_old_fx, st->mem_AR_fx, M ); /* Qx2.56 */ } ELSE { - Copy( lsf_q_fx, st->lsf_old_fx, M ); - Copy( lsp_q_fx, st->lsp_old_fx, M ); + Copy( lsf_q_fx, st->lsf_old_fx, M ); /* Qx2.56 */ + Copy( lsp_q_fx, st->lsp_old_fx, M ); /* Q15 */ } test(); @@ -607,7 +610,7 @@ void stereo_tcx_core_enc( /* update CNG parameters in active frames */ test(); test(); - IF( EQ_16( st->bwidth, NB ) && st->enableTcxLpc && NE_16( st->core, ACELP_CORE ) ) + IF( EQ_16( st->bwidth, NB ) && st->enableTcxLpc && ( st->core != ACELP_CORE ) ) { Word16 buf_fx[L_LP], res_fx[L_FRAME], A_fx[M + 1], tmp_fx, lsptmp_fx[M]; Word32 A_fx32[M + 1], r_fx[M + 1]; @@ -615,7 +618,7 @@ void stereo_tcx_core_enc( assert( st->L_frame == L_FRAME ); - Copy( st->synth + L_FRAME - L_LP, buf_fx, L_LP ); + Copy( st->synth + L_FRAME - L_LP, buf_fx, L_LP ); /* st->Q_syn */ tmp_fx = st->synth[L_FRAME - L_LP - 1]; move16(); preemph_copy_fx( buf_fx, buf_fx, st->preemph_fac, L_LP, &tmp_fx ); @@ -624,7 +627,8 @@ void stereo_tcx_core_enc( lev_dur_fx( A_fx32, r_fx, M, NULL, Q12, Q_r ); FOR( Word16 j = 0; j < M; j++ ) { - A_fx[j] = extract_l( A_fx32[j] ); + A_fx[j] = extract_l( A_fx32[j] ); /* Q12 */ + move16(); } E_LPC_a_lsp_conversion( A_fx, lsptmp_fx, lsp_new_fx, M ); Residu3_fx( A_fx, buf_fx + L_LP - L_FRAME, res_fx, L_FRAME, 0 ); @@ -645,7 +649,7 @@ void stereo_tcx_core_enc( IF( EQ_16( st->L_frame, L_FRAME ) ) { /* store LSPs@16k, potentially to be used in CNG@16k */ - Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); + Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); /* Q15 */ } /* Set 16k LSP flag for CNG buffer */ @@ -674,25 +678,25 @@ void stereo_tcx_core_enc( total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); - IF( NE_16( param_core[1 + NOISE_FILL_RANGES], 0 ) ) + IF( ( param_core[1 + NOISE_FILL_RANGES] != 0 ) ) { Word32 tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxEnc->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxEnc->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /* 15Q16 */ tcxltp_pitch_tmp = L_shr( tcxltp_pitch_tmp, 10 ); // Q6 - set16_fx( pitch_buf_fx, extract_l( tcxltp_pitch_tmp ), NB_SUBFR16k ); + set16_fx( pitch_buf_fx, extract_l( tcxltp_pitch_tmp ), NB_SUBFR16k ); /* Q6 */ } ELSE { - set16_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q6, NB_SUBFR16k ); + set16_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q6, NB_SUBFR16k ); /* Q6 */ } /* Memory scaling to keep everything in common q */ Word16 curr_q_syn = sub( shl( Q_new, 1 ), 1 ); - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); - Scale_sig( st->hLPDmem->mem_syn, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); - Scale_sig( st->hLPDmem->mem_syn2, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); - st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( s_min( Q_new, st->hLPDmem->q_mem_syn ), Q_new ) ); + Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ + Scale_sig( st->hLPDmem->mem_syn, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ + Scale_sig( st->hLPDmem->mem_syn2, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ + st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( s_min( Q_new, st->hLPDmem->q_mem_syn ), Q_new ) ); /* s_min( Q_new, st->hLPDmem->q_mem_syn ) */ move16(); - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); - Scale_sig( st->hLPDmem->mem_syn3, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); + Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ + Scale_sig( st->hLPDmem->mem_syn3, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ st->hLPDmem->q_mem_syn = s_min( curr_q_syn, st->hLPDmem->q_mem_syn ); move16(); st->hLPDmem->q_lpd_syn = Q_new; @@ -701,7 +705,7 @@ void stereo_tcx_core_enc( { FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) { - Scale_sig( st->hTdCngEnc->cng_exc2_buf + ii * L_FFT, L_FFT, sub( Q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ) ); + Scale_sig( st->hTdCngEnc->cng_exc2_buf + ii * L_FFT, L_FFT, sub( Q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ) ); /* Q_exc */ st->hTdCngEnc->cng_Qexc_buf[ii] = Q_exc; move16(); } @@ -710,6 +714,7 @@ void stereo_tcx_core_enc( IF( st->tcxonly == 0 ) { st->wspeech_enc[st->L_frame - 1] = shl( st->wspeech_enc[st->L_frame - 1], -st->Q_syn ); + move16(); } pop_wmops(); @@ -734,10 +739,10 @@ Word16 ivas_acelp_tcx20_switching_fx( Word16 *voicing_fr, /*Q15 i : fractional voicing values */ Word32 currFlatness, /*Q21 i : flatness */ Word16 lsp_mid[M], /*Q15 i : LSPs at the middle of the frame */ - Word16 stab_fac, /* i : LP filter stability */ + Word16 stab_fac, /* i : LP filter stability Q15*/ Word32 *res_cod_SNR_M, Word16 *res_cod_SNR_M_e, - const Word16 flag_16k_smc /* i : flag to compute parameters with 16kHz core */ + const Word16 flag_16k_smc /* i : flag to compute parameters with 16kHz core Q0*/ ) { TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; @@ -799,7 +804,7 @@ Word16 ivas_acelp_tcx20_switching_fx( L_frame_tmp = L_frame; move16(); - x_fx = hTcxEnc->spectrum_long_fx; + x_fx = hTcxEnc->spectrum_long_fx; /* Q15 */ move32(); e_x = 31 - 15; move16(); @@ -808,16 +813,16 @@ Word16 ivas_acelp_tcx20_switching_fx( /* Check minimum pitch for quantization */ FOR( i = 0; i < 4; i++ ) { - pitch_fr_local[i] = pitch_fr[i]; + pitch_fr_local[i] = pitch_fr[i]; /* Q6 */ move16(); - voicing_fr_local[i] = voicing_fr[i]; + voicing_fr_local[i] = voicing_fr[i]; /* Q15 */ move16(); } E_LPC_f_lsp_a_conversion( lsp_mid, A_q_tcx_fx, M ); Q_A_q_tcx = sub( 14, norm_s( A_q_tcx_fx[0] ) ); scale_A = sub( Q12, Q_A_q_tcx ); - Copy_Scale_sig( A_q_tcx_fx, A_q_tcx_fx, M + 1, scale_A ); + Copy_Scale_sig( A_q_tcx_fx, A_q_tcx_fx, M + 1, scale_A ); /* Q12 */ /*--------------------------------------------------------------* * Estimate TCX SNR @@ -826,7 +831,7 @@ Word16 ivas_acelp_tcx20_switching_fx( target = L_add( 0x11A5D28, 0 ); /* 0x11A5D28 -> 850.f * log2(10)/10 (Q16) */ IF( flag_16k_smc ) { - tcx_offset = st->hTcxCfg->tcx_offset; + tcx_offset = st->hTcxCfg->tcx_offset; /* Q0 */ move16(); IF( st->last_core == ACELP_CORE ) @@ -890,9 +895,9 @@ Word16 ivas_acelp_tcx20_switching_fx( } } - Copy( inp_fx + sub( tcx_offset, shr( overlap, 1 ) ), xn_buf_fx, add( L_frame, overlap ) ); + Copy( inp_fx + sub( tcx_offset, shr( overlap, 1 ) ), xn_buf_fx, add( L_frame, overlap ) ); /* q_inp */ - L_frame_4 = shr( L_frame, 2 ); + L_frame_4 = shr( L_frame, 2 ); /* q0 */ IF( st->last_core == ACELP_CORE ) { test(); @@ -906,21 +911,21 @@ Word16 ivas_acelp_tcx20_switching_fx( { FOR( i = 0; i < overlap; i++ ) { - xn_buf_fx[i] = mult( xn_buf_fx[i], window_fx[i] ); + xn_buf_fx[i] = mult( xn_buf_fx[i], window_fx[i] ); /* q_inp */ move16(); } } FOR( i = 0; i < overlap; i++ ) { - xn_buf_fx[L_frame + i] = mult( xn_buf_fx[L_frame + i], window_fx[overlap - 1 - i] ); + xn_buf_fx[L_frame + i] = mult( xn_buf_fx[L_frame + i], window_fx[overlap - 1 - i] ); /* q_inp */ move16(); } e_x = sub( 16, q_inp ); /*exponent for xn_buf_fx*/ move16(); TCX_MDCT( xn_buf_fx, x_fx, &e_x, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); scale_A = getScaleFactor32( x_fx, L_frame ); - Copy_Scale_sig32( x_fx, x_fx, L_frame, scale_A ); + Copy_Scale_sig32( x_fx, x_fx, L_frame, scale_A ); /* Q31-e_x+scale_A */ e_x = sub( e_x, scale_A ); tmp16 = mult_r( shl( L_frame, 5 ), 29309 /*16*0.0559017 Q15*/ ); /* L_frame / sqrt(2*NORM_MDCT_FACTOR); Q9 */ @@ -941,7 +946,7 @@ Word16 ivas_acelp_tcx20_switching_fx( { com_gainlpc_e = s_max( com_gainlpc_e, gainlpc_e[i] ); } - Copy_Scale_sig32( x_fx, x_fx, L_frame, -com_gainlpc_e ); + Copy_Scale_sig32( x_fx, x_fx, L_frame, -com_gainlpc_e ); /* Q31-e_x-com_gainlpc_e */ e_x = add( e_x, com_gainlpc_e ); mdct_shaping( x_fx, L_frame, gainlpc_fx, gainlpc_e ); @@ -972,17 +977,17 @@ Word16 ivas_acelp_tcx20_switching_fx( /* calc quadruple energy */ ener = L_deposit_l( 1 ); - tmp16 = extract_h( L_shl( x_fx[0], s ) ); - ener = L_mac( ener, tmp16, tmp16 ); + tmp16 = extract_h( L_shl( x_fx[0], s ) ); /* Q15-e_x+s */ + ener = L_mac( ener, tmp16, tmp16 ); /* 2*(Q15-e_x+s)+1 */ - tmp16 = extract_h( L_shl( x_fx[1], s ) ); - ener = L_mac( ener, tmp16, tmp16 ); + tmp16 = extract_h( L_shl( x_fx[1], s ) ); /* Q15-e_x+s */ + ener = L_mac( ener, tmp16, tmp16 ); /* 2*(Q15-e_x+s)+1 */ - tmp16 = extract_h( L_shl( x_fx[2], s ) ); - ener = L_mac( ener, tmp16, tmp16 ); + tmp16 = extract_h( L_shl( x_fx[2], s ) ); /* Q15-e_x+s */ + ener = L_mac( ener, tmp16, tmp16 ); /* 2*(Q15-e_x+s)+1 */ - tmp16 = extract_h( L_shl( x_fx[3], s ) ); - ener = L_mac( ener, tmp16, tmp16 ); + tmp16 = extract_h( L_shl( x_fx[3], s ) ); /* Q15-e_x+s */ + ener = L_mac( ener, tmp16, tmp16 ); /* 2*(Q15-e_x+s)+1 */ s = shl( sub( e_x, s ), 1 ); @@ -998,7 +1003,7 @@ Word16 ivas_acelp_tcx20_switching_fx( FOR( iter = 0; iter < 10; iter++ ) { - fac = L_shr( fac, 1 ); + fac = L_shr( fac, 1 ); /* q0 */ offset = L_sub( offset, fac ); ener = L_deposit_l( 0 ); @@ -1006,33 +1011,33 @@ Word16 ivas_acelp_tcx20_switching_fx( { tmp32 = L_sub( en[i], offset ); - IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ { ener = L_add( ener, tmp32 ); } tmp32 = L_sub( en[i + 1], offset ); - IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ { ener = L_add( ener, tmp32 ); } tmp32 = L_sub( en[i + 2], offset ); - IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ { ener = L_add( ener, tmp32 ); } tmp32 = L_sub( en[i + 3], offset ); - IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 3.f * log2(10)/10 */ { ener = L_add( ener, tmp32 ); } - IF( GT_32( ener, target ) ) + if ( GT_32( ener, target ) ) { offset = L_add( offset, fac ); BREAK; @@ -1086,7 +1091,7 @@ Word16 ivas_acelp_tcx20_switching_fx( Word16 temp_e, e_num, e_den, temp_ene_e; temp_ene_e = ener_e; move16(); - tmp32 = Sqrt32( ener, &temp_ene_e ); + tmp32 = Sqrt32( ener, &temp_ene_e ); /* Q31-temp_ene_e */ /*Approximate SNR of TCX*/ set32_fx( x_fx, tmp32, L_frame ); /* ener_e */ mdct_noiseShaping_ivas_fx( x_fx, &temp_ene_e, L_frame, gainlpc_noinv, gainlpc_noinv_e ); @@ -1113,10 +1118,10 @@ Word16 ivas_acelp_tcx20_switching_fx( FOR( i = bands[iter]; i < bands[iter + 1]; i++ ) { - nrg_s = BASOP_Util_Add_Mant32Exp( nrg_s, e_num, Mpy_32_32( y_fx[i], y_fx[i] ), shl( e_x, 1 ), &e_num ); - nrg_n = BASOP_Util_Add_Mant32Exp( nrg_n, e_den, Mpy_32_32( x_fx[i], x_fx[i] ), shl( temp_ene_e, 1 ), &e_den ); + nrg_s = BASOP_Util_Add_Mant32Exp( nrg_s, e_num, Mpy_32_32( y_fx[i], y_fx[i] ), shl( e_x, 1 ), &e_num ); /* Q31-e_num */ + nrg_n = BASOP_Util_Add_Mant32Exp( nrg_n, e_den, Mpy_32_32( x_fx[i], x_fx[i] ), shl( temp_ene_e, 1 ), &e_den ); /* Q31-e_den */ } - res_cod_SNR_M[iter] = BASOP_Util_Divide3232_Scale_cadence( nrg_s, nrg_n, &temp_e ); + res_cod_SNR_M[iter] = BASOP_Util_Divide3232_Scale_cadence( nrg_s, nrg_n, &temp_e ); /* Q31-res_cod_SNR_M_e[iter] */ move32(); res_cod_SNR_M_e[iter] = add( temp_e, sub( e_num, e_den ) ); move16(); @@ -1126,7 +1131,7 @@ Word16 ivas_acelp_tcx20_switching_fx( pt_ener_sfr = ener_sfr; tcx_snr = L_deposit_l( 0 ); - L_loop = L_frame; + L_loop = L_frame; /* Q0 */ move16(); if ( flag_16k_smc ) { @@ -1135,16 +1140,16 @@ Word16 ivas_acelp_tcx20_switching_fx( } Word16 temp32_e = 0; move16(); - Word32 temp_energy = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( ener_e ), 25 ) ); - temp_energy = L_add( temp_energy, 201326592 /* 6 in Q25*/ ); - temp_energy = L_shr( temp_energy, 9 ); /*temp_energy is log(( ener * L_SUBFR ))*/ + Word32 temp_energy = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( ener_e ), 25 ) ); /* Q25 */ + temp_energy = L_add( temp_energy, 201326592 /* 6 in Q25*/ ); /* Q25 */ + temp_energy = L_shr( temp_energy, 9 ); /*temp_energy is log(( ener * L_SUBFR ))*/ FOR( i = 0; i < L_loop; i += L_SUBFR ) { tmp32 = L_deposit_l( 0 ); FOR( j = 0; j < L_SUBFR; j++ ) { - tmp32 = BASOP_Util_Add_Mant32Exp( tmp32, temp32_e, L_mult0( wsp[i + j], wsp[i + j] ), sub( 31, add( q_inp, q_inp ) ), &temp32_e ); + tmp32 = BASOP_Util_Add_Mant32Exp( tmp32, temp32_e, L_mult0( wsp[i + j], wsp[i + j] ), sub( 31, add( q_inp, q_inp ) ), &temp32_e ); /* Q31-temp32_e */ } IF( tmp32 == 0 ) { @@ -1159,17 +1164,17 @@ Word16 ivas_acelp_tcx20_switching_fx( } ELSE { - tmp32 = L_add( BASOP_Util_Log2( tmp32 ), L_shl( L_deposit_l( temp32_e ), 25 ) ); - *pt_ener_sfr = tmp32; + tmp32 = L_add( BASOP_Util_Log2( tmp32 ), L_shl( L_deposit_l( temp32_e ), 25 ) ); /* Q25 */ + *pt_ener_sfr = tmp32; /* Q25 */ move32(); tmp32 = L_shr( tmp32, 9 ); /* 15Q16 */ } tcx_snr = L_sub( L_add( tcx_snr, tmp32 ), temp_energy ); /*15Q16*/ pt_ener_sfr++; } - tmp16 = BASOP_Util_Divide1616_Scale( L_SUBFR, L_loop, &temp32_e ); - tmp16 = shl( tmp16, temp32_e ); - tcx_snr = Mpy_32_16_1( tcx_snr, tmp16 ); + tmp16 = BASOP_Util_Divide1616_Scale( L_SUBFR, L_loop, &temp32_e ); /* Q15-temp32_e */ + tmp16 = shl( tmp16, temp32_e ); /* Q15 */ + tcx_snr = Mpy_32_16_1( tcx_snr, tmp16 ); /* Q16 */ tcx_snr = L_shl( Mpy_32_16_1( tcx_snr, 0x6054 /* 0x6054 -> 10/log2(10) (2Q13) */ ), 2 ); /* Q16*/ /*--------------------------------------------------------------* @@ -1213,7 +1218,7 @@ Word16 ivas_acelp_tcx20_switching_fx( T0 = shr( add( pitch_fr_local[i2], ( 1 << 5 ) ), 6 ); } - gain = get_gain2( wsp + i, wsp + sub( i, T0 ), L_SUBFR ); + gain = get_gain2( wsp + i, wsp + sub( i, T0 ), L_SUBFR ); /*Q16*/ noise = L_deposit_l( 1 ); noise_e = 0; diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 2daa9ed50..c959ef758 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -51,17 +51,17 @@ void tdm_low_rate_enc( Encoder_State *st, /* i/o: State structure */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 *res, /* i : residual signal */ - Word16 *synth, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *synth, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ Word16 *pitch_buf, /* i/o: floating pitch values for each subframe */ // Q6 - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 attack_flag, /* i : GSC attack flag */ - const Word16 *lsf_new, /* i : current frame ISF vector */ - Word16 *tmp_noise, /* o : long-term noise energy */ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/ + const Word16 attack_flag, /* i : GSC attack flag Q0*/ + const Word16 *lsf_new, /* i : current frame ISF vector Qx2.56*/ + Word16 *tmp_noise, /* o : long-term noise energy Q11*/ Word16 Q_new ) { const Word16 *p_Aq; @@ -88,7 +88,7 @@ void tdm_low_rate_enc( hLPDmem->tilt_code = 0; move16(); set16_fx( dct_epit_fx, 0, L_FRAME ); - set16_fx( pitch_buf, L_SUBFR_Q6, NB_SUBFR ); + set16_fx( pitch_buf, L_SUBFR_Q6, NB_SUBFR ); /* Q6 */ last_pit_bin = L_FRAME / 2; move16(); @@ -103,7 +103,7 @@ void tdm_low_rate_enc( *--------------------------------------------------------------------------------------*/ /* Find the current total number of bits used */ - tmp_nb_bits_tot = st->hBstr->nb_bits_tot; + tmp_nb_bits_tot = st->hBstr->nb_bits_tot; /* Q0 */ move16(); if ( st->extl_brate > 0 ) @@ -152,17 +152,17 @@ void tdm_low_rate_enc( * Synthesis *--------------------------------------------------------------------------------------*/ - p_Aq = Aq; + p_Aq = Aq; /* Q12 */ FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) { - E_UTIL_synthesis( 0, p_Aq, &exc_wo_nf_fx[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1, M ); + E_UTIL_synthesis( 0, p_Aq, &exc_wo_nf_fx[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1, M ); /* Q_new */ p_Aq += ( M + 1 ); } /*--------------------------------------------------------------------------------------* * Updates *--------------------------------------------------------------------------------------*/ - Copy( exc_wo_nf_fx, exc_fx, L_FRAME ); + Copy( exc_wo_nf_fx, exc_fx, L_FRAME ); /* Q_new */ return; } @@ -250,9 +250,9 @@ void encod_gen_2sbfr( coder_type = GENERIC; move16(); - p_Aw = Aw; - p_Aq = Aq; - pt_pitch = pitch_buf; + p_Aw = Aw; /* e(norm_s(Aw[0]+1) */ + p_Aq = Aq; /* e(norm_s(Aw[0]+1) */ + pt_pitch = pitch_buf; /*Q6*/ /*------------------------------------------------------------------* * ACELP subframe loop @@ -314,7 +314,7 @@ void encod_gen_2sbfr( lp_filt_exc_enc_ivas_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); #endif /* update long-term pitch gain for speech/music classifier */ - st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277, gain_pit ) ); // Q14 + st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277 /*Q15*/, gain_pit ) ); // Q14 move16(); /*-----------------------------------------------------------------* @@ -331,7 +331,7 @@ void encod_gen_2sbfr( IF( st->Opt_SC_VBR ) { - IF( EQ_16( st->hSC_VBR->last_ppp_mode, 1 ) ) + if ( EQ_16( st->hSC_VBR->last_ppp_mode, 1 ) ) { /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */ st->clip_var_fx[1] = gain_pit; @@ -348,9 +348,9 @@ void encod_gen_2sbfr( #ifndef FIX_1320_LOWRATE_ACELP hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); #else - Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx_sat( Lgcode ); /*Q0*/ - hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); + Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx_sat( Lgcode ); /*Q0*/ + hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); /* Q15 */ #endif move16(); @@ -361,8 +361,8 @@ void encod_gen_2sbfr( #ifndef FIX_1320_LOWRATE_ACELP hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); #else - Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ - Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ + Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ @@ -388,11 +388,11 @@ void encod_gen_2sbfr( FOR( i = 0; i < 2 * L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); - Ltmp = L_mult( gcode16, code[i] ); /* Q10 */ - Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */ - Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */ - Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/ + exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); /* Q_new-1 */ + Ltmp = L_mult( gcode16, code[i] ); /* Q10 */ + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */ + Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/ exc[i + i_subfr] = round_fx_sat( Ltmp ); move16(); move16(); @@ -404,7 +404,7 @@ void encod_gen_2sbfr( prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); - voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; + voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; /* Q15 */ move16(); /*-----------------------------------------------------------------* @@ -428,8 +428,8 @@ void encod_gen_2sbfr( /* SC-VBR */ IF( st->Opt_SC_VBR ) { - st->hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; - st->hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + st->hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */ + st->hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); move16(); } diff --git a/lib_enc/lead_indexing_fx.c b/lib_enc/lead_indexing_fx.c index ff2933014..70e0c4796 100644 --- a/lib_enc/lead_indexing_fx.c +++ b/lib_enc/lead_indexing_fx.c @@ -22,8 +22,8 @@ static Word16 fcb_encode_pos_fx( const Word16 pos_vector[], const Word16 pulse_n *-------------------------------------------------------------------*/ void re8_compute_base_index_fx( const Word16 *x, /* i : Elemen of Q2, Q3 or Q4 */ - const Word16 ka, /* i : Identifier of the absolute leader related to x */ - UWord16 *I /* o : index */ + const Word16 ka, /* i : Identifier of the absolute leader related to x Q0*/ + UWord16 *I /* o : index Q0*/ ) { Word16 i, j, k1, m; @@ -35,9 +35,9 @@ void re8_compute_base_index_fx( Word16 code_index; UWord16 offset; - a1 = vals_a[ka]; + a1 = vals_a[ka]; /* Q0 */ move16(); - a2 = vals_q[ka]; + a2 = vals_q[ka]; /* Q0 */ move16(); /* the sign process */ @@ -48,7 +48,7 @@ void re8_compute_base_index_fx( move16(); code_index = 0; move16(); - k1 = a2[0]; + k1 = a2[0]; /* Q0 */ move16(); test(); @@ -59,15 +59,15 @@ void re8_compute_base_index_fx( { IF( x[i] != 0 ) { - sign_8p = shl( sign_8p, 1 ); + sign_8p = shl( sign_8p, 1 ); /* Q0 */ setor_8p_temp[m] = i; move16(); - m = add( m, 1 ); + m++; } - IF( x[i] < 0 ) + if ( x[i] < 0 ) { - sign_8p = add( sign_8p, 1 ); + sign_8p = add( sign_8p, 1 ); /* Q0 */ } } @@ -78,33 +78,35 @@ void re8_compute_base_index_fx( move16(); *I = extract_l( L_add( offset, (Word32) code_index ) ); + move16(); } ELSE { FOR( i = 0; i < 8; i++ ) { - setor_8p[i] = abs_s( x[i] ); + setor_8p[i] = abs_s( x[i] ); /* Q0 */ + move16(); IF( x[i] != 0 ) { - sign_8p = shl( sign_8p, 1 ); - m = add( m, 1 ); + sign_8p = shl( sign_8p, 1 ); /* Q0 */ + m++; } - IF( x[i] < 0 ) + if ( x[i] < 0 ) { - sign_8p = add( sign_8p, 1 ); + sign_8p = add( sign_8p, 1 ); /* Q0 */ } } - IF( NE_16( k1, m ) ) + if ( NE_16( k1, m ) ) { - sign_8p = shr( sign_8p, 1 ); + sign_8p = shr( sign_8p, 1 ); /* Q0 */ } /* code level by level */ - code_level = sub( a2[1], 1 ); + code_level = sub( a2[1], 1 ); /* Q0 */ code_area = 8; move16(); @@ -119,15 +121,15 @@ void re8_compute_base_index_fx( { IF( NE_16( setor_8p[i], a1[j] ) ) { - setor_8p_temp[m] = i; + setor_8p_temp[m] = i; /* Q0 */ move16(); - setor_8p[m] = setor_8p[i]; + setor_8p[m] = setor_8p[i]; /* Q0 */ move16(); - m = add( m, 1 ); + m++; } } - code_index = extract_l( L_mult0( code_index, select_table22[m][code_area] ) ); - code_index = add( code_index, fcb_encode_pos_fx( setor_8p_temp, code_area, m ) ); + code_index = extract_l( L_mult0( code_index, select_table22[m][code_area] ) ); /* Q0 */ + code_index = add( code_index, fcb_encode_pos_fx( setor_8p_temp, code_area, m ) ); /* Q0 */ code_area = m; move16(); } @@ -136,18 +138,19 @@ void re8_compute_base_index_fx( { FOR( i = 0; i < code_area; i++ ) { - IF( EQ_16( setor_8p[i], a1[1] ) ) + if ( EQ_16( setor_8p[i], a1[1] ) ) { - code_index = add( code_index, i ); + code_index = add( code_index, i ); /* Q0 */ } } } code_index = add( shl( code_index, k1 ), sign_8p ); - offset = Is[ka]; + offset = Is[ka]; /* Q0 */ move16(); - *I = extract_l( L_add( offset, (Word32) code_index ) ); + *I = extract_l( L_add( offset, (Word32) code_index ) ); /* Q0 */ + move16(); } } @@ -156,10 +159,10 @@ void re8_compute_base_index_fx( * * Base function to compute base index for RE8 *-------------------------------------------------------------------*/ -static Word16 fcb_encode_pos_fx( /* o : Code index */ - const Word16 pos_vector[], /* i : Position vectort */ - const Word16 pulse_num, /* i : Pulse number */ - const Word16 pos_num /* i : Position number */ +static Word16 fcb_encode_pos_fx( /* o : Code index Q0*/ + const Word16 pos_vector[], /* i : Position vectort Q0*/ + const Word16 pulse_num, /* i : Pulse number Q0*/ + const Word16 pos_num /* i : Position number Q0*/ ) { Word16 i, j; @@ -171,10 +174,10 @@ static Word16 fcb_encode_pos_fx( /* o : Code index temp = sub( pulse_num, 1 ); - select_table23 = select_table22[pos_num]; + select_table23 = select_table22[pos_num]; /* Q0 */ move16(); - code_index = sub( select_table23[pulse_num], select_table23[sub( pulse_num, pos_vector[0] )] ); + code_index = sub( select_table23[pulse_num], select_table23[( pulse_num - pos_vector[0] )] ); /* Q0 */ j = 1; move16(); @@ -184,12 +187,12 @@ static Word16 fcb_encode_pos_fx( /* o : Code index { temp1 = sub( pos_num, j ); - select_table23 = select_table22[temp1]; + select_table23 = select_table22[temp1]; /* Q0 */ move16(); - code_index = add( code_index, sub( select_table23[sub( temp, pos_vector[i] )], select_table23[sub( pulse_num, pos_vector[j] )] ) ); + code_index = add( code_index, sub( select_table23[( temp - pos_vector[i] )], select_table23[( pulse_num - pos_vector[j] )] ) ); /* Q0 */ - j = add( j, 1 ); + j++; } return code_index; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 9093ffc40..09e3efc84 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -157,6 +157,7 @@ ivas_error IVAS_ENC_Open( st_ivas->mc_mode = MC_MODE_NONE; st_ivas->ism_mode = ISM_MODE_NONE; st_ivas->sba_analysis_order = 0; + move16(); return IVAS_ERR_OK; } @@ -223,6 +224,7 @@ ivas_error IVAS_ENC_Open_fx( st_ivas->mc_mode = MC_MODE_NONE; st_ivas->ism_mode = ISM_MODE_NONE; st_ivas->sba_analysis_order = 0; + move16(); return IVAS_ERR_OK; } @@ -237,18 +239,19 @@ void IVAS_ENC_Close( ) { /* Free all memory */ - if ( phIvasEnc == NULL || *phIvasEnc == NULL ) + test(); + IF( phIvasEnc == NULL || *phIvasEnc == NULL ) { return; } - if ( ( *phIvasEnc )->isConfigured ) + IF( ( *phIvasEnc )->isConfigured ) { ivas_destroy_enc_fx( ( *phIvasEnc )->st_ivas ); } - else + ELSE { - if ( ( *phIvasEnc )->st_ivas->hEncoderConfig ) + IF( ( *phIvasEnc )->st_ivas->hEncoderConfig ) { free( ( *phIvasEnc )->st_ivas->hEncoderConfig ); ( *phIvasEnc )->st_ivas->hEncoderConfig = NULL; @@ -289,17 +292,20 @@ ivas_error IVAS_ENC_ConfigureForMono( error = IVAS_ERR_OK; - if ( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } hIvasEnc->st_ivas->hEncoderConfig->ivas_format = MONO_FORMAT; hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (Word16) is_binaural; + move16(); + move16(); if ( downmixFromStereo ) { hIvasEnc->st_ivas->hEncoderConfig->stereo_dmx_evs = 1; + move16(); } hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -334,7 +340,7 @@ ivas_error IVAS_ENC_ConfigureForStereo( ivas_error error; - if ( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -342,8 +348,11 @@ ivas_error IVAS_ENC_ConfigureForStereo( st_ivas = hIvasEnc->st_ivas; hEncoderConfig = st_ivas->hEncoderConfig; hEncoderConfig->nchan_inp = 2; + move16(); hEncoderConfig->ivas_format = STEREO_FORMAT; + move16(); hEncoderConfig->is_binaural = (Word16) is_binaural; + move16(); #ifdef DEBUGGING switch ( stereoMode ) @@ -412,7 +421,7 @@ ivas_error IVAS_ENC_ConfigureForMASAObjects( return error; } - IF( GT_16( numObjects, MAX_NUM_OBJECTS ) ) + IF( GT_32( numObjects, MAX_NUM_OBJECTS ) ) { return IVAS_ERR_TOO_MANY_INPUTS; } @@ -469,22 +478,27 @@ ivas_error IVAS_ENC_ConfigureForObjects( Encoder_Struct *st_ivas; ivas_error error; - if ( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } - if ( numObjects > MAX_NUM_OBJECTS ) + IF( GT_32( numObjects, MAX_NUM_OBJECTS ) ) { return IVAS_ERR_TOO_MANY_INPUTS; } st_ivas = hIvasEnc->st_ivas; st_ivas->hEncoderConfig->ivas_format = ISM_FORMAT; + move16(); st_ivas->hEncoderConfig->element_mode_init = IVAS_SCE; + move16(); st_ivas->hEncoderConfig->nchan_inp = numObjects; + move16(); st_ivas->hEncoderConfig->nchan_ism = numObjects; + move16(); st_ivas->hEncoderConfig->ism_extended_metadata_flag = ism_extended_metadata; + move16(); hIvasEnc->extMetadataApi = ( ism_extended_metadata == 1 ); hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -510,17 +524,19 @@ ivas_error IVAS_ENC_FeedObjectMetadata( error = IVAS_ERR_OK; - if ( !hIvasEnc->isConfigured ) + IF( !hIvasEnc->isConfigured ) { return IVAS_ERR_NOT_CONFIGURED; } - if ( hIvasEnc->st_ivas->hEncoderConfig->ivas_format != ISM_FORMAT && hIvasEnc->st_ivas->hEncoderConfig->ivas_format != MASA_ISM_FORMAT && hIvasEnc->st_ivas->hEncoderConfig->ivas_format != SBA_ISM_FORMAT ) + test(); + test(); + IF( NE_16( hIvasEnc->st_ivas->hEncoderConfig->ivas_format, ISM_FORMAT ) && NE_16( hIvasEnc->st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) && NE_16( hIvasEnc->st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) { return IVAS_ERR_METADATA_NOT_EXPECTED; } - if ( ismIndex > hIvasEnc->st_ivas->hEncoderConfig->nchan_inp ) + IF( GT_32( ismIndex, hIvasEnc->st_ivas->hEncoderConfig->nchan_inp ) ) { return IVAS_ERR_INVALID_INDEX; } @@ -531,7 +547,7 @@ ivas_error IVAS_ENC_FeedObjectMetadata( Word32 pitch_fx = float_to_fix( metadata.pitch, Q22 ); /* Q22 */ error = ivas_set_ism_metadata_fx( hIvasEnc->st_ivas->hIsmMetaData[ismIndex], azimuth_fx, elevation_fx, radius_fx, yaw_fx, pitch_fx, metadata.non_diegetic_flag ); - if ( error != IVAS_ERR_OK ) + IF( error != IVAS_ERR_OK ) { return error; } @@ -563,7 +579,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( ENCODER_CONFIG_HANDLE hEncoderConfig; ivas_error error; - if ( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -574,12 +590,17 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->element_mode_init = IVAS_SCE; /* Just needs to be something not mono, will be set later */ hEncoderConfig->sba_planar = isPlanar; hEncoderConfig->sba_order = order; + move16(); + move16(); + move16(); /* Input in ACN/SN3D in all cases (3D and planar): get number of channels */ hEncoderConfig->nchan_inp = ivas_sba_get_nchan_fx( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ + move16(); hEncoderConfig->Opt_PCA_ON = (Word16) Opt_PCA_ON; + move16(); hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -614,12 +635,17 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( hEncoderConfig->element_mode_init = IVAS_SCE; /* Just needs to be something not mono, will be set later */ hEncoderConfig->sba_planar = isPlanar; hEncoderConfig->sba_order = order; + move16(); + move16(); + move16(); /* Input in ACN/SN3D in all cases (3D and planar): get number of channels */ hEncoderConfig->nchan_inp = ivas_sba_get_nchan_fx( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ + move16(); hEncoderConfig->Opt_PCA_ON = (Word16) Opt_PCA_ON; + move16(); hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -790,7 +816,7 @@ ivas_error IVAS_ENC_ConfigureForMultichannel( ENCODER_CONFIG_HANDLE hEncoderConfig; ivas_error error; - if ( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -798,31 +824,34 @@ ivas_error IVAS_ENC_ConfigureForMultichannel( hEncoderConfig = hIvasEnc->st_ivas->hEncoderConfig; hEncoderConfig->ivas_format = MC_FORMAT; + move16(); hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; /*just for initialization*/ + move16(); - switch ( mcLayout ) + SWITCH( mcLayout ) { case IVAS_ENC_MC_5_1: hEncoderConfig->mc_input_setup = MC_LS_SETUP_5_1; - break; + BREAK; case IVAS_ENC_MC_7_1: hEncoderConfig->mc_input_setup = MC_LS_SETUP_7_1; - break; + BREAK; case IVAS_ENC_MC_5_1_2: hEncoderConfig->mc_input_setup = MC_LS_SETUP_5_1_2; - break; + BREAK; case IVAS_ENC_MC_5_1_4: hEncoderConfig->mc_input_setup = MC_LS_SETUP_5_1_4; - break; + BREAK; case IVAS_ENC_MC_7_1_4: hEncoderConfig->mc_input_setup = MC_LS_SETUP_7_1_4; - break; + BREAK; default: return IVAS_ERR_INVALID_MC_LAYOUT; - break; + BREAK; } hEncoderConfig->nchan_inp = ivas_mc_ls_setup_get_num_channels_fx( hEncoderConfig->mc_input_setup ); + move16(); hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -860,7 +889,7 @@ static ivas_error configureEncoder( * Bandwidth limitation *-----------------------------------------------------------------*/ - if ( ( error = setBandwidth_fx( hIvasEnc, initBandwidth ) ) != IVAS_ERR_OK ) + IF( ( error = setBandwidth_fx( hIvasEnc, initBandwidth ) ) != IVAS_ERR_OK ) { return error; } @@ -869,32 +898,39 @@ static ivas_error configureEncoder( * DTX/CNG *-----------------------------------------------------------------*/ - if ( dtxConfig.enabled ) + IF( dtxConfig.enabled ) { hEncoderConfig->Opt_DTX_ON = 1; + move16(); - if ( dtxConfig.variable_SID_rate ) + IF( dtxConfig.variable_SID_rate ) { hEncoderConfig->var_SID_rate_flag = 1; hEncoderConfig->interval_SID = 0; + move16(); + move16(); } - else + ELSE { hEncoderConfig->var_SID_rate_flag = 0; + move16(); - if ( dtxConfig.SID_interval >= 3 && dtxConfig.SID_interval <= 100 ) + test(); + IF( GE_16( dtxConfig.SID_interval, 3 ) && LE_16( dtxConfig.SID_interval, 100 ) ) { hEncoderConfig->interval_SID = dtxConfig.SID_interval; + move16(); } - else + ELSE { return IVAS_ERR_INVALID_DTX_UPDATE_RATE; } } } - else + ELSE { hEncoderConfig->Opt_DTX_ON = 0; + move16(); } /*-----------------------------------------------------------------* @@ -902,36 +938,42 @@ static ivas_error configureEncoder( *-----------------------------------------------------------------*/ hEncoderConfig->ivas_total_brate = initBitrate; + move32(); /* SC-VBR at 5.90 kbps */ - if ( hEncoderConfig->ivas_total_brate == ACELP_5k90 ) + IF( EQ_32( hEncoderConfig->ivas_total_brate, ACELP_5k90 ) ) { hEncoderConfig->ivas_total_brate = ACELP_7k20; hEncoderConfig->Opt_SC_VBR = 1; hEncoderConfig->last_Opt_SC_VBR = hEncoderConfig->Opt_SC_VBR; + move32(); + move16(); + move16(); - if ( hEncoderConfig->max_bwidth != NB ) + if ( ( hEncoderConfig->max_bwidth != NB ) ) { hEncoderConfig->max_bwidth = WB; + move16(); } } /* check if the entered bitrate is supported */ - if ( hEncoderConfig->ivas_format != UNDEFINED_FORMAT && hEncoderConfig->ivas_format != MONO_FORMAT ) /* IVAS */ + test(); + IF( NE_16( hEncoderConfig->ivas_format, UNDEFINED_FORMAT ) && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) /* IVAS */ { - if ( !is_IVAS_bitrate_fx( hEncoderConfig->ivas_total_brate ) ) + IF( !is_IVAS_bitrate_fx( hEncoderConfig->ivas_total_brate ) ) { - if ( hEncoderConfig->Opt_SC_VBR ) + IF( hEncoderConfig->Opt_SC_VBR ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Incorrect bitrate specification in IVAS [bps]: %d", ACELP_5k90 ); } - else + ELSE { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Incorrect bitrate specification in IVAS [bps]: %d", hEncoderConfig->ivas_total_brate ); } } - if ( hEncoderConfig->ivas_format == STEREO_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, STEREO_FORMAT ) ) { #ifdef DEBUGGING if ( hIvasEnc->cmd_stereo ) @@ -942,57 +984,64 @@ static ivas_error configureEncoder( hEncoderConfig->stereo_mode_cmdl = 1; #endif - if ( hEncoderConfig->ivas_total_brate >= MIN_BRATE_MDCT_STEREO ) + if ( GE_32( hEncoderConfig->ivas_total_brate, MIN_BRATE_MDCT_STEREO ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); #ifdef DEBUGGING hEncoderConfig->stereo_mode_cmdl = 0; #endif } } - if ( ( hEncoderConfig->element_mode_init == IVAS_CPE_TD || hEncoderConfig->element_mode_init == IVAS_CPE_DFT ) && hEncoderConfig->ivas_total_brate > IVAS_48k ) + test(); + test(); + IF( ( EQ_16( hEncoderConfig->element_mode_init, IVAS_CPE_TD ) || EQ_16( hEncoderConfig->element_mode_init, IVAS_CPE_DFT ) ) && GT_32( hEncoderConfig->ivas_total_brate, IVAS_48k ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for TD/DFT Stereo specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } - if ( hEncoderConfig->element_mode_init == IVAS_CPE_MDCT && hEncoderConfig->ivas_total_brate < IVAS_48k ) + test(); + IF( EQ_16( hEncoderConfig->element_mode_init, IVAS_CPE_MDCT ) && LT_32( hEncoderConfig->ivas_total_brate, IVAS_48k ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for MDCT Stereo specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } - if ( hEncoderConfig->ivas_total_brate > IVAS_256k ) + IF( GT_32( hEncoderConfig->ivas_total_brate, IVAS_256k ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for Stereo specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } } - else if ( hEncoderConfig->ivas_format == ISM_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, ISM_FORMAT ) ) { - if ( ( error = sanitizeBitrateISM_fx( hEncoderConfig, hIvasEnc->extMetadataApi ) ) != IVAS_ERR_OK ) + IF( ( error = sanitizeBitrateISM_fx( hEncoderConfig, hIvasEnc->extMetadataApi ) ) != IVAS_ERR_OK ) { return error; } } - else if ( hEncoderConfig->ivas_format == SBA_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) ) { /* nothing */ } - else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, MASA_FORMAT ) ) { /* adapt element_mode according to the bitrate */ - if ( hEncoderConfig->nchan_inp == 2 && hEncoderConfig->element_mode_init != IVAS_SCE ) + test(); + IF( EQ_16( hEncoderConfig->nchan_inp, 2 ) && NE_16( hEncoderConfig->element_mode_init, IVAS_SCE ) ) { - if ( hEncoderConfig->ivas_total_brate >= IVAS_48k ) + IF( GE_32( hEncoderConfig->ivas_total_brate, IVAS_48k ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } - else if ( hEncoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + ELSE IF( LT_32( hEncoderConfig->ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_DFT; + move16(); } } } - else if ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( st_ivas->hEncoderConfig->ivas_total_brate, hEncoderConfig->nchan_ism ); move32(); @@ -1000,51 +1049,59 @@ static ivas_error configureEncoder( cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, st_ivas->hEncoderConfig->ivas_total_brate, hEncoderConfig->nchan_ism ); /*adapt element_mode according to the bit-rate*/ - if ( hEncoderConfig->element_mode_init != IVAS_SCE ) + IF( NE_16( hEncoderConfig->element_mode_init, IVAS_SCE ) ) { - if ( cpe_brate >= IVAS_48k ) + if ( GE_32( cpe_brate, IVAS_48k ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } } } - else if ( hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) { st_ivas->ism_mode = ISM_MODE_NONE; + move16(); } } - else /* EVS mono */ + ELSE /* EVS mono */ { hEncoderConfig->ivas_format = MONO_FORMAT; + move16(); hEncoderConfig->element_mode_init = EVS_MONO; + move16(); - if ( !is_EVS_bitrate( hEncoderConfig->ivas_total_brate, &hEncoderConfig->Opt_AMR_WB ) ) + IF( !is_EVS_bitrate( hEncoderConfig->ivas_total_brate, &hEncoderConfig->Opt_AMR_WB ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Incorrect bitrate specification in EVS mono: %d", hEncoderConfig->ivas_total_brate ); } - if ( hEncoderConfig->stereo_dmx_evs == 1 ) + IF( EQ_16( hEncoderConfig->stereo_dmx_evs, 1 ) ) { hEncoderConfig->nchan_inp = 2; + move16(); } } /*-----------------------------------------------------------------* * Input sampling frequency *-----------------------------------------------------------------*/ - - if ( inputFs != 8000 && inputFs != 16000 && inputFs != 32000 && inputFs != 48000 ) + test(); + test(); + test(); + IF( NE_32( inputFs, 8000 ) && NE_32( inputFs, 16000 ) && NE_32( inputFs, 32000 ) && NE_32( inputFs, 48000 ) ) { return IVAS_ERR_INVALID_SAMPLING_RATE; } hEncoderConfig->input_Fs = inputFs; + move32(); /*-----------------------------------------------------------------* * Channel-aware mode *-----------------------------------------------------------------*/ - if ( ( error = setChannelAwareConfig_fx( hIvasEnc, caConfig ) ) != IVAS_ERR_OK ) + IF( ( error = setChannelAwareConfig_fx( hIvasEnc, caConfig ) ) != IVAS_ERR_OK ) { return error; } @@ -1054,25 +1111,31 @@ static ivas_error configureEncoder( *-----------------------------------------------------------------*/ st_ivas->codec_mode = MODE1; /* Note: in IVAS, set MODE1 */ + move16(); - if ( hEncoderConfig->ivas_format == MONO_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { - if ( hEncoderConfig->Opt_AMR_WB ) + IF( hEncoderConfig->Opt_AMR_WB ) { st_ivas->codec_mode = MODE1; + move16(); } - else + ELSE { st_ivas->codec_mode = get_codec_mode( hEncoderConfig->ivas_total_brate ); + move16(); } } - if ( hEncoderConfig->ivas_total_brate == IVAS_13k2 && hEncoderConfig->Opt_RF_ON == 1 ) + test(); + IF( EQ_32( hEncoderConfig->ivas_total_brate, IVAS_13k2 ) && EQ_16( hEncoderConfig->Opt_RF_ON, 1 ) ) { st_ivas->codec_mode = MODE2; + move16(); } st_ivas->last_codec_mode = st_ivas->codec_mode; + move16(); /*-----------------------------------------------------------------* * Sanity checks @@ -1080,21 +1143,31 @@ static ivas_error configureEncoder( assert( hEncoderConfig->ivas_format != UNDEFINED_FORMAT && "\n IVAS format undefined" ); - if ( ( hEncoderConfig->ivas_format != MONO_FORMAT || hEncoderConfig->stereo_dmx_evs ) && hEncoderConfig->input_Fs == 8000 ) + test(); + test(); + IF( ( NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) || hEncoderConfig->stereo_dmx_evs ) && EQ_32( hEncoderConfig->input_Fs, 8000 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "8kHz input sampling rate is not supported in IVAS." ); } - if ( hEncoderConfig->Opt_DTX_ON && hEncoderConfig->ivas_format != MONO_FORMAT && - ( ( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_get_sba_num_TCs_fx( hEncoderConfig->ivas_total_brate, 1 ) > 2 ) || - hEncoderConfig->ivas_format == MC_FORMAT || hEncoderConfig->ivas_format == MASA_ISM_FORMAT || hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) ) + test(); + test(); + test(); + test(); + test(); + test(); + IF( hEncoderConfig->Opt_DTX_ON && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) && + ( ( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) && GT_16( ivas_get_sba_num_TCs_fx( hEncoderConfig->ivas_total_brate, 1 ), 2 ) ) || + EQ_16( hEncoderConfig->ivas_format, MC_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) ) { return IVAS_ERROR( IVAS_ERR_DTX_NOT_SUPPORTED, "DTX is not supported in this IVAS format and element mode." ); } - + test(); + test(); + test(); #ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH - if ( hEncoderConfig->Opt_PCA_ON && !( ( hEncoderConfig->ivas_format == SBA_FORMAT || hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) + IF( hEncoderConfig->Opt_PCA_ON && !( ( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) && EQ_32( hEncoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( hEncoderConfig->sba_order, SBA_FOA_ORDER ) ) ) #else if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) #endif @@ -1102,12 +1175,15 @@ static ivas_error configureEncoder( return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } - if ( ( error = sanitizeBandwidth_fx( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = sanitizeBandwidth_fx( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } - if ( hEncoderConfig->is_binaural && !( ( hEncoderConfig->ivas_format == MONO_FORMAT && hEncoderConfig->stereo_dmx_evs ) || hEncoderConfig->ivas_format == STEREO_FORMAT ) ) + test(); + test(); + test(); + IF( hEncoderConfig->is_binaural && !( ( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) && hEncoderConfig->stereo_dmx_evs ) || EQ_16( hEncoderConfig->ivas_format, STEREO_FORMAT ) ) ) { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "'-binaural' option is supported only with '-stereo' or '-stereo_dmx_evs'" ); } @@ -1116,22 +1192,24 @@ static ivas_error configureEncoder( * Finalize initialization *-----------------------------------------------------------------*/ - if ( ( error = ivas_init_encoder( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_init_encoder( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( hEncoderConfig->ivas_format == MONO_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { hIvasEnc->hCoreCoder = st_ivas->hSCE[0]->hCoreCoder[0]; /* Note: this is needed for switching in EVS mono */ } - else + ELSE { hIvasEnc->hCoreCoder = NULL; } hIvasEnc->Opt_RF_ON_loc = hEncoderConfig->Opt_RF_ON; hIvasEnc->rf_fec_offset_loc = hEncoderConfig->rf_fec_offset; + move16(); + move16(); hIvasEnc->isConfigured = true; @@ -1171,19 +1249,24 @@ static ivas_error configureEncoder_fx( IF( dtxConfig.enabled ) { hEncoderConfig->Opt_DTX_ON = 1; + move16(); IF( dtxConfig.variable_SID_rate ) { hEncoderConfig->var_SID_rate_flag = 1; hEncoderConfig->interval_SID = 0; + move16(); + move16(); } ELSE { hEncoderConfig->var_SID_rate_flag = 0; - + move16(); + test(); IF( GE_16( dtxConfig.SID_interval, 3 ) && LE_16( dtxConfig.SID_interval, 100 ) ) { hEncoderConfig->interval_SID = dtxConfig.SID_interval; + move16(); } ELSE { @@ -1194,6 +1277,7 @@ static ivas_error configureEncoder_fx( ELSE { hEncoderConfig->Opt_DTX_ON = 0; + move16(); } /*-----------------------------------------------------------------* @@ -1201,21 +1285,27 @@ static ivas_error configureEncoder_fx( *-----------------------------------------------------------------*/ hEncoderConfig->ivas_total_brate = initBitrate; + move16(); /* SC-VBR at 5.90 kbps */ - IF( hEncoderConfig->ivas_total_brate == ACELP_5k90 ) + IF( EQ_32( hEncoderConfig->ivas_total_brate, ACELP_5k90 ) ) { hEncoderConfig->ivas_total_brate = ACELP_7k20; hEncoderConfig->Opt_SC_VBR = 1; hEncoderConfig->last_Opt_SC_VBR = hEncoderConfig->Opt_SC_VBR; + move32(); + move16(); + move16(); - IF( NE_16( hEncoderConfig->max_bwidth, NB ) ) + IF( ( hEncoderConfig->max_bwidth != NB ) ) { hEncoderConfig->max_bwidth = WB; + move16(); } } /* check if the entered bitrate is supported */ + test(); IF( NE_16( hEncoderConfig->ivas_format, UNDEFINED_FORMAT ) && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) /* IVAS */ { IF( !is_IVAS_bitrate_fx( hEncoderConfig->ivas_total_brate ) ) @@ -1230,26 +1320,32 @@ static ivas_error configureEncoder_fx( } } - IF( hEncoderConfig->ivas_format == STEREO_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, STEREO_FORMAT ) ) { { hEncoderConfig->element_mode_init = IVAS_CPE_DFT; - IF( hEncoderConfig->ivas_total_brate >= MIN_BRATE_MDCT_STEREO ) + move16(); + IF( GE_32( hEncoderConfig->ivas_total_brate, MIN_BRATE_MDCT_STEREO ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } } + test(); + test(); IF( ( EQ_16( hEncoderConfig->element_mode_init, IVAS_CPE_TD ) || EQ_32( hEncoderConfig->element_mode_init, IVAS_CPE_DFT ) ) && GT_32( hEncoderConfig->ivas_total_brate, IVAS_48k ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for TD/DFT Stereo specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( EQ_16( hEncoderConfig->element_mode_init, IVAS_CPE_MDCT ) && LT_32( hEncoderConfig->ivas_total_brate, IVAS_48k ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for MDCT Stereo specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_256k ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for Stereo specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); @@ -1269,15 +1365,18 @@ static ivas_error configureEncoder_fx( ELSE IF( EQ_16( hEncoderConfig->ivas_format, MASA_FORMAT ) ) { /* adapt element_mode according to the bitrate */ + test(); IF( EQ_16( hEncoderConfig->nchan_inp, 2 ) && NE_16( hEncoderConfig->element_mode_init, IVAS_SCE ) ) { IF( GE_32( hEncoderConfig->ivas_total_brate, IVAS_48k ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } ELSE IF( LT_32( hEncoderConfig->ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_DFT; + move16(); } } } @@ -1293,6 +1392,7 @@ static ivas_error configureEncoder_fx( IF( GE_32( cpe_brate, IVAS_48k ) ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } } } @@ -1305,6 +1405,7 @@ static ivas_error configureEncoder_fx( { hEncoderConfig->ivas_format = MONO_FORMAT; hEncoderConfig->element_mode_init = EVS_MONO; + move16(); IF( !is_EVS_bitrate( hEncoderConfig->ivas_total_brate, &hEncoderConfig->Opt_AMR_WB ) ) { @@ -1314,19 +1415,23 @@ static ivas_error configureEncoder_fx( IF( EQ_16( hEncoderConfig->stereo_dmx_evs, 1 ) ) { hEncoderConfig->nchan_inp = 2; + move16(); } } /*-----------------------------------------------------------------* * Input sampling frequency *-----------------------------------------------------------------*/ - + test(); + test(); + test(); IF( NE_32( inputFs, 8000 ) && NE_32( inputFs, 16000 ) && NE_32( inputFs, 32000 ) && NE_32( inputFs, 48000 ) ) { return IVAS_ERR_INVALID_SAMPLING_RATE; } hEncoderConfig->input_Fs = inputFs; + move32(); /*-----------------------------------------------------------------* * Channel-aware mode @@ -1342,25 +1447,31 @@ static ivas_error configureEncoder_fx( *-----------------------------------------------------------------*/ st_ivas->codec_mode = MODE1; /* Note: in IVAS, set MODE1 */ + move16(); IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { IF( hEncoderConfig->Opt_AMR_WB ) { st_ivas->codec_mode = MODE1; + move16(); } ELSE { st_ivas->codec_mode = get_codec_mode( hEncoderConfig->ivas_total_brate ); + move16(); } } - IF( hEncoderConfig->ivas_total_brate == IVAS_13k2 && hEncoderConfig->Opt_RF_ON == 1 ) + test(); + IF( EQ_32( hEncoderConfig->ivas_total_brate, IVAS_13k2 ) && EQ_16( hEncoderConfig->Opt_RF_ON, 1 ) ) { st_ivas->codec_mode = MODE2; + move16(); } st_ivas->last_codec_mode = st_ivas->codec_mode; + move16(); /*-----------------------------------------------------------------* * Sanity checks @@ -1368,11 +1479,19 @@ static ivas_error configureEncoder_fx( assert( hEncoderConfig->ivas_format != UNDEFINED_FORMAT && "\n IVAS format undefined" ); + test(); + test(); IF( ( NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) || hEncoderConfig->stereo_dmx_evs ) && EQ_32( hEncoderConfig->input_Fs, 8000 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "8kHz input sampling rate is not supported in IVAS." ); } + test(); + test(); + test(); + test(); + test(); + test(); IF( hEncoderConfig->Opt_DTX_ON && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) && ( ( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) && GT_32( ivas_get_sba_num_TCs_fx( hEncoderConfig->ivas_total_brate, 1 ), 2 ) ) || EQ_16( hEncoderConfig->ivas_format, MC_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) ) @@ -1380,7 +1499,9 @@ static ivas_error configureEncoder_fx( return IVAS_ERROR( IVAS_ERR_DTX_NOT_SUPPORTED, "DTX is not supported in this IVAS format and element mode." ); } - + test(); + test(); + test(); IF( hEncoderConfig->Opt_PCA_ON && !( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) && EQ_32( hEncoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( hEncoderConfig->sba_order, SBA_FOA_ORDER ) ) ) { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); @@ -1391,6 +1512,9 @@ static ivas_error configureEncoder_fx( return error; } + test(); + test(); + test(); IF( hEncoderConfig->is_binaural && !( ( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) && hEncoderConfig->stereo_dmx_evs ) || EQ_16( hEncoderConfig->ivas_format, STEREO_FORMAT ) ) ) { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "'-binaural' option is supported only with '-stereo' or '-stereo_dmx_evs'" ); @@ -1416,6 +1540,8 @@ static ivas_error configureEncoder_fx( hIvasEnc->Opt_RF_ON_loc = hEncoderConfig->Opt_RF_ON; hIvasEnc->rf_fec_offset_loc = hEncoderConfig->rf_fec_offset; + move16(); + move16(); hIvasEnc->isConfigured = true; @@ -1429,7 +1555,7 @@ static ivas_error configureEncoder_fx( ivas_error IVAS_ENC_GetDelay( const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - Word16 *delay /* o : encoder delay */ + Word16 *delay /* o : encoder delay Q0*/ ) { ENCODER_CONFIG_HANDLE hEncoderConfig; @@ -1446,10 +1572,10 @@ ivas_error IVAS_ENC_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *delay = NS2SA_FX2( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); + *delay = NS2SA_FX2( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); /*Q0*/ move16(); - *delay = imult1616( *delay, hEncoderConfig->nchan_inp ); + *delay = imult1616( *delay, hEncoderConfig->nchan_inp ); /*Q0*/ move16(); return IVAS_ERR_OK; @@ -1478,17 +1604,19 @@ ivas_error IVAS_ENC_GetNumInChannels( Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ) { - if ( hIvasEnc == NULL || numInChannels == NULL ) + test(); + IF( hIvasEnc == NULL || numInChannels == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( !hIvasEnc->isConfigured ) + IF( !hIvasEnc->isConfigured ) { return IVAS_ERR_NOT_CONFIGURED; } *numInChannels = hIvasEnc->st_ivas->hEncoderConfig->nchan_inp; + move16(); return IVAS_ERR_OK; } @@ -1528,10 +1656,10 @@ ivas_error IVAS_ENC_GetInputBufferSize( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_EncodeFrameToSerial( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - Word16 *inputBuffer, /* i : PCM input, Q0 */ - Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ - UWord16 *outputBitStream, /* o : pointer to serial output bitstream. The array must already be allocated and be of size at least IVAS_MAX_BITS_PER_FRAME */ - UWord16 *numOutBits /* o : number of bits written to output bitstream. Each bit is stored as a single uint16_t value */ + Word16 *inputBuffer, /* i : PCM input, Q0 Q0*/ + Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() Q0*/ + UWord16 *outputBitStream, /* o : pointer to serial output bitstream. The array must already be allocated and be of size at least IVAS_MAX_BITS_PER_FRAME Q0*/ + UWord16 *numOutBits /* o : number of bits written to output bitstream. Each bit is stored as a single uint16_t value Q0*/ ) { Encoder_Struct *st_ivas; @@ -1768,7 +1896,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } /* write indices into bitstream buffer */ - IF( EQ_16( hEncoderConfig->element_mode_init, EVS_MONO ) ) + IF( hEncoderConfig->element_mode_init == EVS_MONO ) { test(); IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) && ( hCoreCoder->element_mode == EVS_MONO ) ) @@ -1806,7 +1934,7 @@ ivas_error IVAS_ENC_SetBandwidth( ivas_error error; /* Do additional checks for user-facing function */ - if ( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -1830,7 +1958,7 @@ ivas_error IVAS_ENC_SetBitrate( ivas_error error; /* Do additional checks for user-facing function */ - if ( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -1855,7 +1983,7 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error error; /* Do additional checks for user-facing function */ - if ( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + IF( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -1956,6 +2084,7 @@ IVAS_ENC_DTX_CONFIG IVAS_ENC_GetDefaultDtxConfig( void ) IVAS_ENC_DTX_CONFIG defaultDtxConfig; defaultDtxConfig.enabled = false; defaultDtxConfig.SID_interval = 0; + move16(); defaultDtxConfig.variable_SID_rate = false; return defaultDtxConfig; @@ -2022,11 +2151,11 @@ static ivas_error printConfigInfo_enc( * Print bitrate *-----------------------------------------------------------------*/ - if ( st_ivas->hEncoderConfig->Opt_SC_VBR ) + IF( st_ivas->hEncoderConfig->Opt_SC_VBR ) { fprintf( stdout, "Average bitrate: %.2f kbps\n", (float) ACELP_5k90 / 1000 ); } - else + ELSE { fprintf( stdout, "Bitrate: %.2f kbps\n", (float) hEncoderConfig->ivas_total_brate / 1000 ); } @@ -2035,18 +2164,18 @@ static ivas_error printConfigInfo_enc( * Print IVAS format *-----------------------------------------------------------------*/ - if ( hEncoderConfig->ivas_format == MONO_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { - if ( hEncoderConfig->stereo_dmx_evs ) + IF( hEncoderConfig->stereo_dmx_evs ) { fprintf( stdout, "IVAS format: stereo downmix to bit-exact EVS mono\n" ); } - else + ELSE { fprintf( stdout, "IVAS format: bit-exact EVS mono\n" ); } } - else if ( hEncoderConfig->ivas_format == STEREO_FORMAT ) + ELSE IF( hEncoderConfig->ivas_format == STEREO_FORMAT ) { #ifdef DEBUGGING if ( hEncoderConfig->stereo_mode_cmdl == 1 ) @@ -2076,64 +2205,65 @@ static ivas_error printConfigInfo_enc( } #endif } - else if ( hEncoderConfig->ivas_format == ISM_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, ISM_FORMAT ) ) { - if ( hEncoderConfig->ivas_total_brate <= ACELP_32k && hEncoderConfig->nchan_inp > 2 ) + test(); + IF( LE_32( hEncoderConfig->ivas_total_brate, ACELP_32k ) && GT_16( hEncoderConfig->nchan_inp, 2 ) ) { fprintf( stdout, "IVAS format: Param-ISM (%i streams)\n", hEncoderConfig->nchan_inp ); } - else + ELSE { fprintf( stdout, "IVAS format: ISM (%i streams)\n", hEncoderConfig->nchan_inp ); } } - else if ( hEncoderConfig->ivas_format == SBA_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) ) { fprintf( stdout, "IVAS format: Scene Based Audio, Ambisonic order %i %s ", hEncoderConfig->sba_order, hEncoderConfig->sba_planar ? "(Planar)" : "" ); - if ( hEncoderConfig->Opt_PCA_ON ) + IF( hEncoderConfig->Opt_PCA_ON ) { fprintf( stdout, "- PCA configured with signal adaptive decision " ); } fprintf( stdout, "\n" ); } - else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, MASA_FORMAT ) ) { fprintf( stdout, "IVAS format: MASA format\n" ); } - else if ( hEncoderConfig->ivas_format == MC_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, MC_FORMAT ) ) { - if ( hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 ) + IF( hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 ) { fprintf( stdout, "IVAS mode: Multi-Channel 5.1 \n" ); } - else if ( hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 ) + ELSE IF( hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 ) { fprintf( stdout, "IVAS mode: Multi-Channel 7.1 \n" ); } - else if ( hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 ) + ELSE IF( hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 ) { fprintf( stdout, "IVAS mode: Multi-Channel 5.1+2 \n" ); } - else if ( hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 ) + ELSE IF( hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 ) { fprintf( stdout, "IVAS mode: Multi-Channel 5.1+4\n" ); } - else if ( hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1_4 ) + ELSE IF( hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1_4 ) { fprintf( stdout, "IVAS mode: Multi-Channel 7.1+4\n" ); } } - else if ( hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) { fprintf( stdout, "IVAS format: combined ISM and SBA (%i ISM stream(s))\n", hEncoderConfig->nchan_ism ); } - else if ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT ) + ELSE IF( EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { fprintf( stdout, "IVAS format: combined ISM and MASA (%i ISM stream(s))\n", hEncoderConfig->nchan_ism ); } - if ( hEncoderConfig->is_binaural ) + IF( hEncoderConfig->is_binaural ) { fprintf( stdout, "Optional indication: binaural audio\n" ); } @@ -2142,13 +2272,13 @@ static ivas_error printConfigInfo_enc( * Print CNG update interval, if DTX is activated *-----------------------------------------------------------------*/ - if ( hEncoderConfig->Opt_DTX_ON ) + IF( hEncoderConfig->Opt_DTX_ON ) { - if ( hEncoderConfig->var_SID_rate_flag ) + IF( hEncoderConfig->var_SID_rate_flag ) { fprintf( stdout, "DTX: ON, variable CNG update interval\n" ); } - else + ELSE { fprintf( stdout, "DTX: ON, CNG update interval = %d frames\n", hEncoderConfig->interval_SID ); } @@ -2158,54 +2288,57 @@ static ivas_error printConfigInfo_enc( * Print potential limitation of audio bandwidth *-----------------------------------------------------------------*/ - if ( ( error = bandwidthApiToInternal( hIvasEnc->newBandwidthApi, &newBandwidthApi ) ) != IVAS_ERR_OK ) + IF( ( error = bandwidthApiToInternal( hIvasEnc->newBandwidthApi, &newBandwidthApi ) ) != IVAS_ERR_OK ) { return error; } - if ( st_ivas->hEncoderConfig->Opt_SC_VBR && !hEncoderConfig->Opt_DTX_ON ) + test(); + IF( st_ivas->hEncoderConfig->Opt_SC_VBR && !hEncoderConfig->Opt_DTX_ON ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "\nError: SC-VBR 5900 bps not supported without DTX\n\n" ); } - if ( hEncoderConfig->ivas_format == MONO_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { - if ( newBandwidthApi != hEncoderConfig->max_bwidth ) + IF( NE_16( newBandwidthApi, hEncoderConfig->max_bwidth ) ) { - if ( newBandwidthApi == FB ) + IF( EQ_16( newBandwidthApi, FB ) ) { fprintf( stdout, "\nFB coding not supported below %.2f kbps. ", ACELP_16k40 / 1000.f ); - if ( hEncoderConfig->max_bwidth == WB ) + IF( EQ_16( hEncoderConfig->max_bwidth, WB ) ) { fprintf( stdout, "Switching to WB.\n" ); } - else + ELSE { fprintf( stdout, "Switching to SWB.\n" ); } } - else if ( newBandwidthApi == SWB ) + ELSE IF( EQ_16( newBandwidthApi, SWB ) ) { fprintf( stdout, "\nSWB coding not supported below %.2f kbps. Switching to WB.\n", ACELP_9k60 / 1000.f ); } } /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ - if ( ( newBandwidthApi == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) + test(); + test(); + IF( ( ( newBandwidthApi == NB ) || EQ_32( hEncoderConfig->input_Fs, 8000 ) ) && GT_32( hEncoderConfig->ivas_total_brate, ACELP_24k40 ) ) { fprintf( stdout, "\nError: Unsupported mode NB %d bps, NB mode supports rates 5900-24400 bps\n\n", hEncoderConfig->ivas_total_brate ); return IVAS_ERR_INVALID_BITRATE; } } - else + ELSE { - if ( newBandwidthApi != hEncoderConfig->max_bwidth ) + IF( NE_16( newBandwidthApi, hEncoderConfig->max_bwidth ) ) { - if ( hEncoderConfig->ivas_format == ISM_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, ISM_FORMAT ) ) { fprintf( stdout, "\nFB coding not supported below %.2f kbps for %i objects. Switching to SWB.\n", hEncoderConfig->nchan_ism * MIN_BRATE_FB_ISM / 1000.f, hEncoderConfig->nchan_ism ); } - else + ELSE { fprintf( stdout, "\nFB coding not supported below %.2f kbps. Switching to SWB.\n", MIN_BRATE_FB_STEREO / 1000.f ); } @@ -2216,9 +2349,9 @@ static ivas_error printConfigInfo_enc( * Print Channel-aware limitation *-----------------------------------------------------------------*/ - if ( channelAwareModeEnabled ) + IF( channelAwareModeEnabled ) { - if ( hEncoderConfig->Opt_RF_ON == 0 ) + IF( hEncoderConfig->Opt_RF_ON == 0 ) { fprintf( stdout, "\nChannel-aware mode is supported at 13.2 kbps 32/48 kHz only. Switching to normal mode.\n" ); } @@ -2247,65 +2380,76 @@ static ivas_error setBitrate( hEncoderConfig->ivas_total_brate = totalBitrate; hIvasEnc->switchingActive = true; + move32(); /* channel-aware mode is supported only at 13.20 kbps */ - if ( hEncoderConfig->Opt_RF_ON && hEncoderConfig->ivas_total_brate != ACELP_13k20 ) + test(); + IF( hEncoderConfig->Opt_RF_ON && NE_32( hEncoderConfig->ivas_total_brate, ACELP_13k20 ) ) { assert( 0 && "\nChannel-aware mode is supported only at 13.20 kbps\n" ); hEncoderConfig->Opt_RF_ON = 0; + move16(); } - if ( hEncoderConfig->ivas_total_brate == ACELP_5k90 ) + IF( EQ_32( hEncoderConfig->ivas_total_brate, ACELP_5k90 ) ) { st_ivas->hEncoderConfig->Opt_SC_VBR = 1; hEncoderConfig->ivas_total_brate = ACELP_7k20; + move16(); + move32(); } - else + ELSE { st_ivas->hEncoderConfig->Opt_SC_VBR = 0; + move16(); } /* check if the entered bitrate is supported */ - if ( hEncoderConfig->element_mode_init > EVS_MONO ) + IF( hEncoderConfig->element_mode_init > EVS_MONO ) { - if ( !is_IVAS_bitrate_fx( hEncoderConfig->ivas_total_brate ) ) + IF( !is_IVAS_bitrate_fx( hEncoderConfig->ivas_total_brate ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Incorrect bitrate specification in IVAS: %d", hEncoderConfig->ivas_total_brate ); } } - else + ELSE { - if ( !is_EVS_bitrate( hEncoderConfig->ivas_total_brate, &hEncoderConfig->Opt_AMR_WB ) ) + IF( !is_EVS_bitrate( hEncoderConfig->ivas_total_brate, &hEncoderConfig->Opt_AMR_WB ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Incorrect bitrate specification in EVS mono: %d", hEncoderConfig->ivas_total_brate ); } /* in case of 8kHz signal, limit the total bitrate to 24.40 kbps */ - if ( hEncoderConfig->input_Fs == 8000 && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) + test(); + IF( EQ_32( hEncoderConfig->input_Fs, 8000 ) && GT_32( hEncoderConfig->ivas_total_brate, ACELP_24k40 ) ) { hEncoderConfig->ivas_total_brate = ACELP_24k40; + move32(); } } - if ( hEncoderConfig->ivas_format == ISM_FORMAT ) + IF( EQ_16( hEncoderConfig->ivas_format, ISM_FORMAT ) ) { - if ( ( error = sanitizeBitrateISM_fx( hEncoderConfig, hIvasEnc->extMetadataApi ) ) != IVAS_ERR_OK ) + IF( ( error = sanitizeBitrateISM_fx( hEncoderConfig, hIvasEnc->extMetadataApi ) ) != IVAS_ERR_OK ) { return error; } } st_ivas->codec_mode = MODE1; + move16(); - if ( hEncoderConfig->element_mode_init == EVS_MONO ) + IF( hEncoderConfig->element_mode_init == EVS_MONO ) { - if ( hEncoderConfig->Opt_AMR_WB ) + IF( hEncoderConfig->Opt_AMR_WB ) { st_ivas->codec_mode = MODE1; + move16(); } - else + ELSE { st_ivas->codec_mode = get_codec_mode( hEncoderConfig->ivas_total_brate ); + move16(); } } @@ -2332,16 +2476,22 @@ static ivas_error setChannelAwareConfig_fx( hEncoderConfig = st_ivas->hEncoderConfig; /* channel-aware mode is supported only at 13.20 kbps and with WB or SWB bandwidth */ + test(); + test(); + test(); IF( ( caConfig.channelAwareModeEnabled && NE_32( st_ivas->hEncoderConfig->ivas_total_brate, ACELP_13k20 ) ) || ( hEncoderConfig->Opt_RF_ON && EQ_32( hEncoderConfig->input_Fs, 8000 ) ) ) { hEncoderConfig->Opt_RF_ON = 0; + move16(); hEncoderConfig->rf_fec_offset = 0; + move16(); return IVAS_ERR_OK; } IF( caConfig.channelAwareModeEnabled ) { hEncoderConfig->Opt_RF_ON = 1; + move16(); /* Convert FEC indicator from API type */ IF( ( error = fecIndicatorApiToInternal( caConfig.fec_indicator, &newFecIndicator ) ) != IVAS_ERR_OK ) @@ -2350,14 +2500,21 @@ static ivas_error setChannelAwareConfig_fx( } /* Set new values only if they differ from current values */ + test(); IF( ( NE_16( newFecIndicator, hEncoderConfig->rf_fec_indicator ) || NE_16( caConfig.fec_offset, hEncoderConfig->rf_fec_offset ) ) ) { hEncoderConfig->rf_fec_indicator = newFecIndicator; + move16(); /* Check if new FEC offset has a valid value */ + test(); + test(); + test(); + test(); IF( EQ_16( caConfig.fec_offset, 0 ) || EQ_16( caConfig.fec_offset, 2 ) || EQ_16( caConfig.fec_offset, 3 ) || EQ_16( caConfig.fec_offset, 5 ) || EQ_16( caConfig.fec_offset, 7 ) ) { hEncoderConfig->rf_fec_offset = caConfig.fec_offset; + move16(); } ELSE { @@ -2369,10 +2526,12 @@ static ivas_error setChannelAwareConfig_fx( /* Save a copy of FEC offset value - needed during encoding */ hIvasEnc->rf_fec_offset_loc = hEncoderConfig->rf_fec_offset; + move16(); } ELSE { hEncoderConfig->Opt_RF_ON = 0; + move16(); } return IVAS_ERR_OK; @@ -2410,13 +2569,14 @@ static ivas_error doCommonConfigureChecks( static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ) { - if ( hIvasEnc == NULL || hIvasEnc->st_ivas == NULL ) + test(); + IF( hIvasEnc == NULL || hIvasEnc->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } /* Currently settings can be changed only after configuration step */ - if ( !hIvasEnc->isConfigured ) + IF( !hIvasEnc->isConfigured ) { return IVAS_ERR_NOT_CONFIGURED; } @@ -2442,25 +2602,34 @@ static ivas_error sanitizeBandwidth_fx( max_bwidth_tmp = hIvasEnc->newBandwidthApi; /* Prevent st_ivas->max_bwidth from being higher than Fs/2 */ - IF( EQ_32( hEncoderConfig->input_Fs, 8000 ) && GT_16( max_bwidth_tmp, NB ) ) + test(); + test(); + test(); + IF( EQ_32( hEncoderConfig->input_Fs, 8000 ) && ( max_bwidth_tmp > NB ) ) { max_bwidth_tmp = NB; + move16(); } ELSE IF( EQ_32( hEncoderConfig->input_Fs, 16000 ) && GT_16( max_bwidth_tmp, WB ) ) { max_bwidth_tmp = WB; + move16(); } ELSE IF( EQ_32( hEncoderConfig->input_Fs, 32000 ) && GT_16( max_bwidth_tmp, SWB ) ) { max_bwidth_tmp = SWB; + move16(); } /* NB coding not supported in IVAS. Switching to WB. */ - IF( EQ_16( max_bwidth_tmp, NB ) && NE_16( hEncoderConfig->ivas_format, UNDEFINED_FORMAT ) && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) + test(); + test(); + IF( ( max_bwidth_tmp == NB ) && NE_16( hEncoderConfig->ivas_format, UNDEFINED_FORMAT ) && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { IF( GE_32( hEncoderConfig->input_Fs, 16000 ) ) { max_bwidth_tmp = WB; + move16(); } ELSE { @@ -2510,16 +2679,23 @@ static ivas_error sanitizeBandwidth_fx( { iDiv_and_mod_32( hEncoderConfig->ivas_total_brate, hEncoderConfig->nchan_ism, &quo, &rem, 0 ); } + + test(); + test(); + test(); + test(); IF( EQ_16( max_bwidth_tmp, FB ) && ( ( NE_16( hEncoderConfig->ivas_format, ISM_FORMAT ) && LT_32( hEncoderConfig->ivas_total_brate, MIN_BRATE_FB_STEREO ) ) || ( EQ_16( hEncoderConfig->ivas_format, ISM_FORMAT ) && LT_32( quo, MIN_BRATE_FB_ISM ) ) ) ) { max_bwidth_tmp = SWB; + move16(); } } IF( NE_16( hEncoderConfig->max_bwidth, max_bwidth_tmp ) ) { hEncoderConfig->max_bwidth = max_bwidth_tmp; + move16(); hIvasEnc->switchingActive = true; } @@ -2535,31 +2711,37 @@ static ivas_error sanitizeBitrateISM_fx( const ENCODER_CONFIG_HANDLE hEncoderConfig, const bool extMetadataApi ) { + test(); IF( GT_32( hEncoderConfig->ivas_total_brate, IVAS_128k ) && EQ_16( hEncoderConfig->nchan_inp, 1 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for 1 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( GT_32( hEncoderConfig->ivas_total_brate, IVAS_256k ) && EQ_16( hEncoderConfig->nchan_inp, 2 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for 2 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( GT_32( hEncoderConfig->ivas_total_brate, IVAS_384k ) && EQ_16( hEncoderConfig->nchan_inp, 3 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for 3 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_16k4 ) && EQ_16( hEncoderConfig->nchan_inp, 2 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 2 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_24k4 ) && EQ_16( hEncoderConfig->nchan_inp, 3 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 3 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } + test(); IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_24k4 ) && EQ_16( hEncoderConfig->nchan_inp, 4 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 4 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); @@ -2568,10 +2750,12 @@ static ivas_error sanitizeBitrateISM_fx( IF( extMetadataApi ) { hEncoderConfig->ism_extended_metadata_flag = (Word16) GE_32( hEncoderConfig->ivas_total_brate, ISM_EXTENDED_METADATA_BRATE ); + move16(); } ELSE { hEncoderConfig->ism_extended_metadata_flag = 0; + move16(); } return IVAS_ERR_OK; @@ -2601,15 +2785,19 @@ static ivas_error setBandwidth_fx( hIvasEnc->newBandwidthApi = newBandwidth; /* NB coding not supported in IVAS. Switching to WB. */ - IF( newBandwidth == NB && hEncoderConfig->ivas_format != UNDEFINED_FORMAT && hEncoderConfig->ivas_format != MONO_FORMAT ) + test(); + test(); + IF( ( newBandwidth == NB ) && NE_16( hEncoderConfig->ivas_format, UNDEFINED_FORMAT ) && NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { newBandwidth = WB; + move16(); } IF( hEncoderConfig->max_bwidth != newBandwidth ) { hEncoderConfig->max_bwidth = newBandwidth; hIvasEnc->switchingActive = true; + move16(); } return IVAS_ERR_OK; @@ -2785,33 +2973,56 @@ static void init_encoder_config( ) { hEncoderConfig->ivas_total_brate = ACELP_12k65; + move32(); hEncoderConfig->max_bwidth = SWB; + move16(); hEncoderConfig->input_Fs = 16000; + move32(); hEncoderConfig->nchan_inp = 1; + move16(); hEncoderConfig->element_mode_init = EVS_MONO; + move16(); hEncoderConfig->ivas_format = UNDEFINED_FORMAT; + move16(); hEncoderConfig->is_binaural = 0; + move16(); hEncoderConfig->Opt_SC_VBR = 0; + move16(); hEncoderConfig->last_Opt_SC_VBR = 0; + move16(); hEncoderConfig->Opt_AMR_WB = 0; + move16(); hEncoderConfig->Opt_DTX_ON = 0; + move16(); hEncoderConfig->Opt_RF_ON = 0; + move16(); hEncoderConfig->rf_fec_offset = 0; + move16(); hEncoderConfig->rf_fec_indicator = 1; + move16(); hEncoderConfig->interval_SID = FIXED_SID_RATE; + move16(); hEncoderConfig->var_SID_rate_flag = 1; + move16(); hEncoderConfig->mc_input_setup = MC_LS_SETUP_INVALID; + move16(); hEncoderConfig->stereo_dmx_evs = 0; + move16(); hEncoderConfig->nchan_ism = 0; + move16(); hEncoderConfig->sba_order = 0; + move16(); hEncoderConfig->sba_planar = 0; + move16(); hEncoderConfig->ism_extended_metadata_flag = 0; + move16(); #ifdef DEBUGGING hEncoderConfig->stereo_mode_cmdl = 0; hEncoderConfig->force = -1; hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; #endif hEncoderConfig->Opt_PCA_ON = 0; + move16(); return; } diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index ab6c39c23..8cf6be1cd 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -169,8 +169,8 @@ ivas_error IVAS_ENC_Open_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -182,8 +182,8 @@ ivas_error IVAS_ENC_ConfigureForMono( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -197,8 +197,8 @@ ivas_error IVAS_ENC_ConfigureForStereo( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -209,8 +209,8 @@ ivas_error IVAS_ENC_ConfigureForObjects( /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMASAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const UWord16 numObjects, /* i : number of objects to be encoded */ @@ -220,8 +220,8 @@ ivas_error IVAS_ENC_ConfigureForMASAObjects( /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForSBAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const UWord16 numObjects, /* i : number of objects to be encoded */ @@ -233,8 +233,8 @@ ivas_error IVAS_ENC_ConfigureForSBAObjects( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -245,8 +245,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -257,8 +257,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMasa( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -268,8 +268,8 @@ ivas_error IVAS_ENC_ConfigureForMasa( /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 inputFs, /* i : input sampling frequency */ - const Word32 bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -285,7 +285,7 @@ void IVAS_ENC_Close( /*! r: error code */ ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const UWord16 ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ); @@ -307,8 +307,8 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( /*! r: error code */ ivas_error IVAS_ENC_EncodeFrameToCompact( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - Word16 *inputBuffer, /* i : PCM input */ - const Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ + Word16 *inputBuffer, /* i : PCM input */ + const Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ UWord8 *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ UWord16 *numOutBits /* o : number of bits written to output bitstream */ ); @@ -324,7 +324,7 @@ ivas_error IVAS_ENC_SetBandwidth( /*! r: error code */ ivas_error IVAS_ENC_SetBitrate( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ); /*! r: error code */ @@ -355,13 +355,13 @@ ivas_error IVAS_ENC_GetDelay( /*! r: encoder error code */ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_GetInputBufferSize( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - Word16 *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /* Utility functions */ diff --git a/lib_enc/long_enr_fx.c b/lib_enc/long_enr_fx.c index 5fe465f29..af57edd3b 100644 --- a/lib_enc/long_enr_fx.c +++ b/lib_enc/long_enr_fx.c @@ -18,11 +18,11 @@ void ivas_long_enr_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) Q8 */ - const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - Word16 high_lpn_flag, /* i : sp/mus LPN flag */ + const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover Q0*/ + Word16 high_lpn_flag, /* i : sp/mus LPN flag Q0*/ FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const Word16 n_chan, /* i : number of channels */ - const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ + const Word16 n_chan, /* i : number of channels Q0*/ + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels Q0*/ const Word16 Etot_LR[] /* i : total channel energy LR channels Q8 */ ) @@ -42,13 +42,13 @@ void ivas_long_enr_fx( { FOR( n = 0; n < n_chan; n++ ) { - hFrontVad[n]->lp_noise_fx = hFrontVad[n]->hNoiseEst->totalNoise_fx; + hFrontVad[n]->lp_noise_fx = hFrontVad[n]->hNoiseEst->totalNoise_fx; /* Q8 */ move16(); - tmp = add( hFrontVad[n]->lp_noise_fx, 2560 ); + tmp = add( hFrontVad[n]->lp_noise_fx, 2560 ); /* Q8 */ - IF( LT_16( hFrontVad[n]->lp_speech_fx, tmp ) ) + if ( LT_16( hFrontVad[n]->lp_speech_fx, tmp ) ) { - hFrontVad[n]->lp_speech_fx = tmp; + hFrontVad[n]->lp_speech_fx = tmp; /* Q8 */ move16(); } } @@ -59,34 +59,34 @@ void ivas_long_enr_fx( IF( LT_16( hFrontVad[0]->ini_frame, 150 ) ) { - smooth_prev = 31130; - smooth_curr = 1638; + smooth_prev = 31130; /* 0.95f in Q15 */ + smooth_curr = 1638; /* 0.05f in Q15 */ move16(); move16(); } ELSE { - smooth_prev = 32113; - smooth_curr = 655; + smooth_prev = 32113; /* 0.98f in Q15 */ + smooth_curr = 655; /* 0.02f in Q15 */ move16(); move16(); } FOR( n = 0; n < n_chan; n++ ) { - hFrontVad[n]->lp_noise_fx = add( mult_r( smooth_prev, hFrontVad[n]->lp_noise_fx ), mult_r( smooth_curr, hFrontVad[n]->hNoiseEst->totalNoise_fx ) ); + hFrontVad[n]->lp_noise_fx = add( mult_r( smooth_prev, hFrontVad[n]->lp_noise_fx ), mult_r( smooth_curr, hFrontVad[n]->hNoiseEst->totalNoise_fx ) ); /* Q8 */ move16(); test(); IF( localVAD_HE_SAD_LR[n] && !high_lpn_flag ) { - IF( LT_16( sub( hFrontVad[n]->lp_speech_fx, Etot_LR[n] ), 2560 ) ) + IF( LT_16( sub( hFrontVad[n]->lp_speech_fx, Etot_LR[n] ), 2560 /*10.0f in Q8*/ ) ) { - hFrontVad[n]->lp_speech_fx = add( mult_r( 32113, hFrontVad[n]->lp_speech_fx ), mult_r( 655, Etot_LR[n] ) ); + hFrontVad[n]->lp_speech_fx = add( mult_r( 32113 /*0.98f in Q15*/, hFrontVad[n]->lp_speech_fx ), mult_r( 655 /*0.02f in Q15*/, Etot_LR[n] ) ); /* Q8 */ move16(); } ELSE { - hFrontVad[n]->lp_speech_fx = sub( hFrontVad[n]->lp_speech_fx, 13 ); + hFrontVad[n]->lp_speech_fx = sub( hFrontVad[n]->lp_speech_fx, 13 /*0.05f in Q8*/ ); /* Q8 */ move16(); } } @@ -94,7 +94,7 @@ void ivas_long_enr_fx( } FOR( n = 0; n < n_chan; n++ ) { - hFrontVad[n]->hNoiseEst->Etot_last_fx = Etot_LR[n]; + hFrontVad[n]->hNoiseEst->Etot_last_fx = Etot_LR[n]; /* Q8 */ move16(); } } @@ -102,7 +102,7 @@ void ivas_long_enr_fx( { IF( LT_16( st_fx->ini_frame, 4 ) ) { - st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; + st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; /* Q8 */ move16(); tmp = add( st_fx->lp_noise_fx, 2560 ); /*10.0 in Q8*/ st_fx->lp_speech_fx = s_max( st_fx->lp_speech_fx, tmp ); @@ -115,8 +115,8 @@ void ivas_long_enr_fx( } else { st->lp_noise = 0.98f * st->lp_noise + 0.02f * st->totalNoise; } */ - alpha = 655; - move16(); /* 0.02 Q15 */ + alpha = 655; /* 0.02 Q15 */ + move16(); if ( LT_16( st_fx->ini_frame, 150 ) ) /* should match HE_LT_CNT_INIT_FX */ { alpha = 1638; @@ -141,7 +141,7 @@ void ivas_long_enr_fx( } } /* Update */ - st_fx->hNoiseEst->Etot_last_fx = Etot; + st_fx->hNoiseEst->Etot_last_fx = Etot; /* Q8 */ move16(); } @@ -154,9 +154,9 @@ void ivas_long_enr_fx( void long_enr_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ - const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - Word16 high_lpn_flag /* i : sp/mus LPN flag */ + const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) Q8*/ + const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover Q0*/ + Word16 high_lpn_flag /* i : sp/mus LPN flag Q0*/ ) { Word16 tmp; @@ -171,10 +171,11 @@ void long_enr_fx( { IF( LT_16( st_fx->ini_frame, 4 ) ) { - st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; + st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; /* Q8 */ + move16(); + tmp = add( st_fx->lp_noise_fx, 2560 ); /*10.0 in Q8*/ + st_fx->lp_speech_fx = s_max( st_fx->lp_speech_fx, tmp ); /* Q8 */ move16(); - tmp = add( st_fx->lp_noise_fx, 2560 ); /*10.0 in Q8*/ - st_fx->lp_speech_fx = s_max( st_fx->lp_speech_fx, tmp ); } ELSE { @@ -183,14 +184,15 @@ void long_enr_fx( } else { st->lp_noise = 0.98f * st->lp_noise + 0.02f * st->totalNoise; } */ - alpha = 655; - move16(); /* 0.02 Q15 */ + alpha = 655; /* 0.02 Q15 */ + move16(); if ( LT_16( st_fx->ini_frame, 150 ) ) /* should match HE_LT_CNT_INIT_FX */ { - alpha = 1638; - move16(); /* 0.05 Q15 */ + alpha = 1638; /* 0.05 Q15 */ + move16(); } st_fx->lp_noise_fx = noise_est_AR1_Qx( hNoiseEst->totalNoise_fx, st_fx->lp_noise_fx, alpha ); /* Q8 state, alpha in Q15 */ + move16(); test(); IF( ( localVAD_HE_SAD != 0 ) && ( high_lpn_flag == 0 ) ) @@ -199,10 +201,12 @@ void long_enr_fx( { /* st->lp_speech = 0.98f * st->lp_speech + 0.02f * Etot; */ st_fx->lp_speech_fx = noise_est_AR1_Qx( Etot, st_fx->lp_speech_fx, 655 ); /* Q8 state, 0.02 in Q15 */ + move16(); } ELSE { st_fx->lp_speech_fx = sub( st_fx->lp_speech_fx, 13 ); /* st->lp_speech = st->lp_speech - 0.05f; linear decay*/ + move16(); } } } -- GitLab From 241044c58c76d4a8aeaed13211b6cbfe95594ddb Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 19 Mar 2025 11:15:50 +0100 Subject: [PATCH 0480/1221] add missing move16(), move32(); don't change variable name to stay closer to float and the other variant --- lib_enc/ivas_sns_enc_fx.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 7b1aa46de..2271b6ac6 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -96,7 +96,7 @@ static Word16 sns_1st_cod_fx( { const Word16 *cdbk_ptr; Word16 j0, j1; - Word16 dist_split; + Word16 index_split; Word32 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); @@ -107,7 +107,7 @@ static Word16 sns_1st_cod_fx( cdbk_ptr = cdbk; dist_min_fx = MAXVAL_WORD32; - dist_split = 0; + index_split = 0; move32(); move16(); FOR( Word16 i = 0; i < 32; ++i ) @@ -133,12 +133,14 @@ static Word16 sns_1st_cod_fx( IF( LT_32( dist_fx, dist_min_fx ) ) { dist_min_fx = dist_fx; - dist_split = i; + move32(); + index_split = i; + move16(); } } /* set quantized vector */ - cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; + cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 @@ -150,10 +152,10 @@ static Word16 sns_1st_cod_fx( /* for second split shift by five bits to store both indices as one 10 bit value */ if ( EQ_16( split, 1 ) ) { - dist_split = shl( dist_split, 5 ); + index_split = shl( index_split, 5 ); } - index = add( index, dist_split ); + index = add( index, index_split ); } return index; } -- GitLab From 67ba34472b700e514fd795ef6f95487b4f87182a Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 19 Mar 2025 11:18:10 +0100 Subject: [PATCH 0481/1221] continue using CONTINUE instead of continue --- lib_enc/ivas_sns_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 88c2a5b7c..22cd98cad 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -780,7 +780,7 @@ Word16 quantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - continue; + CONTINUE; } nStages = SNS_MSVQ_NSTAGES_SIDE; -- GitLab From aab935947c105d35e6ae8145ea8a905643a6e599 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 19 Mar 2025 12:29:56 +0100 Subject: [PATCH 0482/1221] touch all artifact files at start of regression check suppress warnings in case of all-BE when files are not generated --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb532dd7d..6b578e90d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -601,6 +601,9 @@ stages: script: - *print-common-info + # create empty files for all artifacts to suppress warnings in case of no regressions found or all is BE + - touch $XML_REPORT_BRANCH $XML_REPORT_MAIN $HTML_REPORT_BRANCH $HTML_REPORT_MAIN $CSV_BRANCH $CSV_MAIN $SUMMARY_HTML_ARTIFACT_NAME $FLOAT_REF_COMMIT_FILE $CUT_COMMIT_FILE $MERGE_TARGET_COMMIT_FILE regressions_crashes.csv regressions_MLD.csv regressions_MAXIMUM_ABS_DIFF.csv regressions_MIN_SSNR.csv regressions_MIN_ODG.csv improvements_crashes.csv improvements_MLD.csv improvements_MAXIMUM_ABS_DIFF.csv improvements_MIN_SSNR.csv improvements_MIN_ODG.csv + - set -euxo pipefail - if [ -s $FAILED_TESTCASES_LIST ]; then -- GitLab From 79c7cdec9969237a100b61300b684c22f7820215 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 19 Mar 2025 12:58:27 +0100 Subject: [PATCH 0483/1221] add print_stacktrace=1 to UBSAN_OPTIONS --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b578e90d..e72616da9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -751,7 +751,7 @@ stages: - set -euxo pipefail - make_args="CLANG=$CLANG_NUM" - if [[ $CLANG_NUM == 3 ]]; then - - export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1" + - export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1,print_stacktrace=1" - python3 scripts/basop_create_ignorelist_for_ubsan.py - make_args="$make_args IGNORELIST=1" - fi -- GitLab From ccaf06000db8df006806e2c49e43dc11bd6f6c3a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 19 Mar 2025 13:08:59 +0100 Subject: [PATCH 0484/1221] also suppress warning for images folder --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e72616da9..91fbd0569 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -603,6 +603,7 @@ stages: # create empty files for all artifacts to suppress warnings in case of no regressions found or all is BE - touch $XML_REPORT_BRANCH $XML_REPORT_MAIN $HTML_REPORT_BRANCH $HTML_REPORT_MAIN $CSV_BRANCH $CSV_MAIN $SUMMARY_HTML_ARTIFACT_NAME $FLOAT_REF_COMMIT_FILE $CUT_COMMIT_FILE $MERGE_TARGET_COMMIT_FILE regressions_crashes.csv regressions_MLD.csv regressions_MAXIMUM_ABS_DIFF.csv regressions_MIN_SSNR.csv regressions_MIN_ODG.csv improvements_crashes.csv improvements_MLD.csv improvements_MAXIMUM_ABS_DIFF.csv improvements_MIN_SSNR.csv improvements_MIN_ODG.csv + - mkdir $IMAGES_ARTIFACT_NAME - set -euxo pipefail @@ -649,7 +650,6 @@ stages: - mv tests/dut tests/dut_branch # create the summary based on the branch - - mkdir $IMAGES_ARTIFACT_NAME - for MEASURE in MLD DIFF SSNR ODG;do python3 scripts/create_histogram_summary.py $CSV_BRANCH $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME -- GitLab From ba11d5e9e26ead4c2d50d98825b80dcfef56024d Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 19 Mar 2025 13:20:45 +0100 Subject: [PATCH 0485/1221] merge REMOVE_EVS_DUPLICATES2 into REMOVE_EVS_DUPLICATES --- lib_com/options.h | 1 - lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 2 +- lib_dec/acelp_core_dec_fx.c | 3 +-- lib_dec/dec_LPD_fx.c | 2 +- lib_dec/dec_ace_fx.c | 2 +- lib_dec/dec_tran_fx.c | 2 +- lib_enc/analy_lp_fx.c | 10 +++++----- lib_enc/cod_ace_fx.c | 2 +- lib_enc/enc_gen_voic_fx.c | 2 +- lib_enc/enc_tran_fx.c | 2 +- lib_enc/ivas_core_pre_proc_front_fx.c | 2 +- lib_enc/ivas_core_pre_proc_fx.c | 4 ++-- lib_enc/ivas_front_vad_fx.c | 2 +- lib_enc/pre_proc_fx.c | 6 +++--- lib_enc/prot_fx_enc.h | 4 ++-- 16 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 4e17909b0..9d6f852ac 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -176,5 +176,4 @@ #define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ #define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions, ACELP low-band decoder */ -#define REMOVE_EVS_DUPLICATES2 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 99925342c..8c42651b2 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3284,7 +3284,7 @@ void synthesise_fb_high_band_fx( Word16 bpf_memory_Q[], Word16 Qout ); -#ifndef REMOVE_EVS_DUPLICATES2 +#ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ #ifdef ADD_IVAS_TBE_CODE diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e279f0d48..af0a37011 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7324,7 +7324,7 @@ void tbe_celp_exc( /* _ None */ /*======================================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES2 +#ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ #ifdef ADD_IVAS_TBE_CODE diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index b0fe937cd..d336c80ed 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1658,8 +1658,7 @@ ivas_error acelp_core_dec_fx( hf_synth_reset_fx( st_fx->hBWE_zero ); } #else - hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, - st_fx->Q_syn2, st_fx->hBWE_zero->delay_syn_hf_fx, &st_fx->hBWE_zero->memExp1, st_fx->hBWE_zero->mem_hp_interp_fx, st_fx->extl, st_fx->CNG_mode ); + hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, st_fx->Q_syn2 ); #endif } diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index f74c3e913..f53234ded 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -556,7 +556,7 @@ void decoder_LPD_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES int_lsp4_ivas_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp ); #else int_lsp4_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp ); diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index 5d644c289..16f749156 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -532,7 +532,7 @@ void decoder_acelp_fx( move16(); IF( st->igf != 0 ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES prep_tbe_exc_ivas_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); #else diff --git a/lib_dec/dec_tran_fx.c b/lib_dec/dec_tran_fx.c index 96eace777..c5b06724a 100644 --- a/lib_dec/dec_tran_fx.c +++ b/lib_dec/dec_tran_fx.c @@ -254,7 +254,7 @@ void decod_tran_fx( tmp_idx_2 = idiv1616( i_subfr, L_SUBFR ); } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, diff --git a/lib_enc/analy_lp_fx.c b/lib_enc/analy_lp_fx.c index b5764ec43..78a02eeec 100644 --- a/lib_enc/analy_lp_fx.c +++ b/lib_enc/analy_lp_fx.c @@ -37,7 +37,7 @@ void analy_lp_ivas_fx( const Word16 Top[2], /* i :(q0) open loop pitch lag */ const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES const Word16 element_mode, /* i : element mode */ #endif const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ @@ -77,7 +77,7 @@ void analy_lp_ivas_fx( /* Autocorrelations */ autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 ); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( element_mode, EVS_MONO ) ) #endif { @@ -132,7 +132,7 @@ void analy_lp_ivas_fx( return; } -#ifndef REMOVE_EVS_DUPLICATES2 +#ifndef REMOVE_EVS_DUPLICATES void analy_lp_fx( const Word16 speech[], /* i : pointer to the speech frame Q_new*/ const Word16 L_frame, /* i : length of the frame Q0*/ @@ -204,7 +204,7 @@ void analy_lp_fx( IF( EQ_16( sec_chan_low_rate, 1 ) ) { /* LSP interpolation */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 ); #else int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 ); @@ -213,7 +213,7 @@ void analy_lp_fx( ELSE { /* LSP interpolation */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); #else int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index aa823cbda..743874351 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -409,7 +409,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * IF( st->igf != 0 ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index e82b1d243..519fd776b 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -367,7 +367,7 @@ void encod_gen_voic_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 25368fac5..fce1ceb0c 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -308,7 +308,7 @@ Word16 encod_tran_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); #else diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 6920aa6f5..d686f109f 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1210,7 +1210,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, element_mode, i, Q_new_loc, Q_r ); #else analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 6be8c474e..cbc0bd5a6 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -1138,7 +1138,7 @@ ivas_error ivas_compute_core_buffers_fx( IF( Q_new ) { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, sub( *Q_new, 1 ), Q_r ); #else analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, sub( *Q_new, 1 ), Q_r ); @@ -1146,7 +1146,7 @@ ivas_error ivas_compute_core_buffers_fx( } ELSE { -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, -1, Q_r ); #else diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index eaa6e6146..3e9ff3284 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -647,7 +647,7 @@ ivas_error front_vad_spar_fx( hFrontVad->q_buffer_12k8 = Q_inp_12k8; move16(); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, st->element_mode, 0, Q_inp_12k8, Q_r ); #else analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, 0 /* <-- sec_chan_low_rate */, Q_inp_12k8, Q_r ); diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 062dc3fa4..a5d619359 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -214,7 +214,7 @@ void pre_proc_fx( * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ Word16 Q_new_inp, mem_decim_size; // TO be removed - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ), &Q_new_inp, &mem_decim_size ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* @@ -415,7 +415,7 @@ void pre_proc_fx( alw_voicing[1] = st->voicing_fx[2]; move16(); -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES analy_lp_ivas_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, EVS_MONO, 0, *Q_new, Q_r ); #else analy_lp_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, -1 /*IVAS_CODE !! LowRateFlag*/, *Q_new, Q_r ); @@ -1136,7 +1136,7 @@ void pre_proc_fx( Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); } -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES analy_lp_ivas_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, EVS_MONO, 0, *Q_new, Q_r ); #else analy_lp_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, -1 /*IVAS_CODE !! LowRateFlag*/, *Q_new, Q_r ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 8bfce57a0..2427d92a8 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -82,14 +82,14 @@ void analy_lp_ivas_fx( const Word16 Top[2], /* i :(q0) open loop pitch lag */ const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ -#ifdef REMOVE_EVS_DUPLICATES2 +#ifdef REMOVE_EVS_DUPLICATES const Word16 element_mode, /* i : element mode */ #endif const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ Word16 Q_new, /*i: stores Q for speech*/ Word16 *Q_r /*stores q for ener*/ ); -#ifndef REMOVE_EVS_DUPLICATES2 +#ifndef REMOVE_EVS_DUPLICATES void analy_lp_fx( const Word16 speech[], /* i : pointer to the speech frame Q_new*/ const Word16 L_frame, /* i : length of the frame Q0*/ -- GitLab From fe1734da642d7873d24d1ba64cb20dccf9c06be1 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 19 Mar 2025 13:36:13 +0100 Subject: [PATCH 0486/1221] cleaning --- lib_dec/acelp_core_dec_fx.c | 202 +----------------------------------- 1 file changed, 4 insertions(+), 198 deletions(-) diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index d336c80ed..71976a730 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -359,11 +359,7 @@ ivas_error acelp_core_dec_fx( } /* update synthesis filter memories */ -#ifdef REMOVE_EVS_DUPLICATES - ivas_synth_mem_updt2_fx( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); -#else synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); -#endif Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); // Q_exc Copy_Scale_sig( st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/ @@ -559,11 +555,8 @@ ivas_error acelp_core_dec_fx( /* decode CNG parameters */ IF( st_fx->cng_type == LP_CNG ) { -#ifdef REMOVE_EVS_DUPLICATES - CNG_dec_ivas_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); -#else + CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); -#endif /* comfort noise generation */ CNG_exc_fx( st_fx->core_brate, st_fx->L_frame, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, @@ -599,39 +592,10 @@ ivas_error acelp_core_dec_fx( } i = st_fx->Q_exc; move16(); -#ifdef REMOVE_EVS_DUPLICATES - test(); - IF( st_fx->hMusicPF && st_fx->hGSCDec ) - { -#ifdef REMOVE_EVS_DUPLICATES - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) - { - Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, - st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); - } - ELSE -#endif - { - Rescale_exc( st_fx->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, - imult1616( st_fx->L_frame, HIBND_ACB_L_FAC ), 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); - } - } - IF( st_fx->hPFstat != NULL ) - { - Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, - &st_fx->mem_deemph_fx, st_fx->hBPF->pst_old_syn_fx, &st_fx->hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); - } - ELSE - { - Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, - &st_fx->mem_deemph_fx, NULL, NULL, &st_fx->agc_mem_fx[1], NULL, 0, 0, NULL ); - } -#else Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); -#endif Copy_Scale_sig( exc2_fx, exc2_fx, st_fx->L_frame, sub( st_fx->Q_exc, i ) ); // Q_exc /* update past excitation signals for LD music post-filter */ @@ -705,11 +669,7 @@ ivas_error acelp_core_dec_fx( } #ifdef NONBE_FIX_GSC_BSTR -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif @@ -719,11 +679,7 @@ ivas_error acelp_core_dec_fx( IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) { #ifdef NONBE_FIX_GSC_BSTR -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, TRANSITION, -1, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif @@ -815,11 +771,7 @@ ivas_error acelp_core_dec_fx( IF( st_fx->stab_fac_fx == 0 && st_fx->old_bfi_cnt > 0 && NE_16( st_fx->clas_dec, VOICED_CLAS ) && NE_16( st_fx->clas_dec, ONSET ) && st_fx->relax_prev_lsf_interp == 0 && !( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES - int_lsp4_ivas_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid_fx, lsp_new_fx, Aq_fx, M, 2 ); -#else int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid_fx, lsp_new_fx, Aq_fx, M, 2 ); -#endif } /*---------------------------------------------------------------* @@ -851,11 +803,7 @@ ivas_error acelp_core_dec_fx( ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) ) { /* UNVOICED frames */ -#ifdef REMOVE_EVS_DUPLICATES - decod_unvoiced_ivas_fx( st_fx, Aq_fx, Es_pred_fx, uc_two_stage_flag, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); -#else decod_unvoiced_fx( st_fx, Aq_fx, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); -#endif } ELSE IF( EQ_16( st_fx->ppp_mode_dec, 1 ) ) { @@ -872,28 +820,16 @@ ivas_error acelp_core_dec_fx( } ELSE IF( EQ_16( st_fx->coder_type, TRANSITION ) ) { -#ifdef REMOVE_EVS_DUPLICATES - decod_tran_ivas_fx( st_fx, st_fx->L_frame, tc_subfr_fx, Aq_fx, Es_pred_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, sharpFlag, gain_buf ); -#else decod_tran_fx( st_fx, st_fx->L_frame, tc_subfr_fx, Aq_fx, Es_pred_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, sharpFlag, gain_buf ); -#endif } ELSE IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES - decod_audio_ivas_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf ); -#else decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf ); -#endif tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ } ELSE { -#ifdef REMOVE_EVS_DUPLICATES - IF( NE_32( ( error = decod_gen_voic_ivas_fx( st_fx, st_fx->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf, 0, NULL ) ), IVAS_ERR_OK ) ) -#else IF( NE_32( ( error = decod_gen_voic_fx( st_fx, st_fx->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf /*, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf*/ ) ), IVAS_ERR_OK ) ) -#endif { return error; } @@ -906,7 +842,6 @@ ivas_error acelp_core_dec_fx( /* synthesis for ACELP core switching and SWB BWE */ syn_12k8_fx( st_fx->L_frame, Aq_fx, exc_fx, temp_buf_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); - /* save and delay synthesis to be used by SWB BWE */ IF( hBWE_FD != NULL ) { @@ -917,11 +852,7 @@ ivas_error acelp_core_dec_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode, 0, EVS_MONO ); -#else Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); -#endif /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames *------------------------------------------------------------*/ @@ -1049,13 +980,9 @@ ivas_error acelp_core_dec_fx( k = add( k, 1 ); } -#ifdef REMOVE_EVS_DUPLICATES - FEC_scale_syn_ivas_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, - &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, - exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); -#else - FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); -#endif + FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); test(); test(); @@ -1134,13 +1061,8 @@ ivas_error acelp_core_dec_fx( { save_old_syn_fx( st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); } - /* Apply energy matching when switching to inactive frames */ -#ifdef REMOVE_EVS_DUPLICATES - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode, 0, EVS_MONO ); -#else Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); -#endif /* udate past excitation signals for LD music post-filter */ IF( hMusicPF != NULL ) @@ -1214,15 +1136,9 @@ ivas_error acelp_core_dec_fx( * (smoothing is performed in the excitation domain and signal is resynthesized after) *------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - FEC_scale_syn_ivas_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, - &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, - exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); -#else FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); -#endif } /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ @@ -1317,11 +1233,7 @@ ivas_error acelp_core_dec_fx( Copy( syn_fx, temp_buf + L_SYN_MEM, L_FRAME16k ); st_fx->hPFstat->on = 1; move16(); -#ifdef REMOVE_EVS_DUPLICATES - formant_post_filt_ivas_fx( st_fx->hPFstat, temp_buf + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME16k, st_fx->lp_noise, st_fx->total_brate, 0 ); -#else formant_post_filt_fx( st_fx->hPFstat, temp_buf + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME16k, st_fx->lp_noise, st_fx->total_brate, 0 ); -#endif } ELSE IF( GE_16( st_fx->last_bwidth, WB ) ) { @@ -1383,21 +1295,13 @@ ivas_error acelp_core_dec_fx( move32(); } /*Noise estimate*/ -#ifdef REMOVE_EVS_DUPLICATES - IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) && !st_fx->cng_ism_flag ) -#else IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) /* && !st->cng_ism_flag IVAS_CODE */ ) -#endif { #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT PMT( "Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done" ) ApplyFdCng_fx( syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else -#ifdef REMOVE_EVS_DUPLICATES - ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, realBuffer, imagBuffer, NULL, st_fx, 0, ( st_fx->coder_type == AUDIO && !st_fx->GSC_noisy_speech ) ); #else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) ); -#endif #endif } /* CNA: Generate additional comfort noise to mask potential coding artefacts */ @@ -1480,82 +1384,6 @@ ivas_error acelp_core_dec_fx( bass_psfilter_fx( st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, st_fx->L_frame, pitch_buf_fx, st_fx->bpf_off, st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, st_fx->coder_type, st_fx->Q_syn, bpf_error_signal ); } - -#ifdef REMOVE_EVS_DUPLICATES - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) - { - /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); - - scaleFactor.hb_scale = scaleFactor.lb_scale; - move16(); - - /* analysis and add the BPF error signal */ - i = 0; - move16(); - if ( st_fx->bpf_off == 0 ) - { - i = CLDFB_NO_COL_MAX; - move16(); - } - - addBassPostFilter_fx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate( st_fx->Q_syn ), - i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor ); - - /* set output mask for upsampling */ - IF( EQ_16( st_fx->bwidth, NB ) ) - { - /* set NB mask for upsampling */ - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, 10 ); - move16(); - } - ELSE IF( NE_16( st_fx->cldfbSyn->bandsToZero, sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ) ) ) - { - /* in case of BW switching, re-init to default */ - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ); - move16(); - } - - /*WB/SWB-FD_CNG*/ - scaleFactor.hb_scale = scaleFactor.lb_scale; - move16(); - - test(); - IF( !st_fx->cng_sba_flag || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - test(); - test(); - test(); - IF( ( ( st_fx->core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) && ( EQ_16( st_fx->cng_type, FD_CNG ) ) && ( LT_16( st_fx->hFdCngDec->hFdCngCom->numCoreBands, st_fx->cldfbSyn->no_channels ) ) ) - { - generate_comfort_noise_dec_hf_fx( realBuffer, imagBuffer, &scaleFactor.hb_scale, st_fx ); - - st_fx->cldfbSyn->bandsToZero = 0; - move16(); - IF( LT_16( st_fx->hFdCngDec->hFdCngCom->regularStopBand, st_fx->cldfbSyn->no_channels ) ) - { - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->hFdCngDec->hFdCngCom->regularStopBand ); - move16(); - } - st_fx->cldfbSyn->lsb = st_fx->cldfbAna->no_channels; - move16(); - } - } - - /* synthesis of the combined signal */ - st_fx->Q_syn2 = st_fx->Q_syn; - move16(); - cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); - - /* Bring CLDFB output to Q0 */ - Scale_sig( synth_out, output_frame, negate( st_fx->Q_syn2 ) ); - st_fx->Q_syn2 = 0; - move16(); - - /* save synthesis - needed in case of core switching */ - Copy( synth_out, st_fx->previoussynth_fx, output_frame ); - } -#else test(); IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) { @@ -1630,7 +1458,6 @@ ivas_error acelp_core_dec_fx( /* save synthesis - needed in case of core switching */ Copy( synth_out, st_fx->previoussynth_fx, output_frame ); } -#endif /*-----------------------------------------------------------------* * Bandwidth extension 6kHz-7kHz @@ -1647,33 +1474,12 @@ ivas_error acelp_core_dec_fx( IF( ( EQ_16( st_fx->L_frame, L_FRAME ) && NE_16( st_fx->bwidth, NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st_fx->extl, -1 ) || EQ_16( st_fx->extl, SWB_CNG ) || ( EQ_16( st_fx->extl, WB_BWE ) && st_fx->extl_brate == 0 && NE_16( st_fx->coder_type, AUDIO ) ) ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) - { - hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, - st_fx->Q_syn2, st_fx->hBWE_zero->delay_syn_hf_fx, &st_fx->hBWE_zero->memExp1, st_fx->hBWE_zero->mem_hp_interp_fx, st_fx->extl, st_fx->CNG_mode ); - } - ELSE - { - hf_synth_reset_fx( st_fx->hBWE_zero ); - } -#else hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, st_fx->Q_syn2 ); - -#endif } -#ifdef REMOVE_EVS_DUPLICATES ELSE { hf_synth_reset_fx( st_fx->hBWE_zero ); -#ifdef MSAN_FIX - IF( NE_16( st_fx->element_mode, EVS_MONO ) ) - { - set16_fx( st_fx->hBWE_zero->mem_hp400_fx, 0, 6 ); - } -#endif } -#endif } /*-----------------------------------------------------------------* -- GitLab From aeb3579d8691ce91d31fe54a95f1fd7be2417b5c Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 19 Mar 2025 14:39:36 +0100 Subject: [PATCH 0487/1221] clang-format --- lib_dec/acelp_core_switch_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 1a856bcda..0b0e7f1b4 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -826,7 +826,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( #ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) #else - Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) + Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) #endif IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st_fx->cldfbAna ) ), IVAS_ERR_OK ) ) { -- GitLab From 35a2935e2ff025aa9fd7b0b0524c0745f361551e Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 19 Mar 2025 14:45:27 +0100 Subject: [PATCH 0488/1221] fix merge issue causing build error --- lib_dec/acelp_core_dec_ivas_fx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 86cbb3618..35e71287e 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -45,8 +45,6 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" -static void rescale_fdCngDec( HANDLE_FD_CNG_DEC hFdCngDec, Word16 old_NoiseExp ); - /*-------------------------------------------------------------------* * acelp_core_dec_ivas_fx() @@ -2589,9 +2587,3 @@ ivas_error acelp_core_dec_ivas_fx( pop_wmops(); return error; } - - -static void rescale_fdCngDec( HANDLE_FD_CNG_DEC hFdCngDec, Word16 Exp_diff ) -{ - Scale_sig32( hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, Exp_diff ); -} -- GitLab From 233e91e06ca68d137bb383e8c12427ec6623ef38 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 19 Mar 2025 16:27:22 +0100 Subject: [PATCH 0489/1221] Correct rescale buffer boundaries of proto_power_smooth_fx. --- lib_rend/ivas_dirac_rend_fx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 18c9269d5..503b1f3e8 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1815,9 +1815,10 @@ void protoSignalComputation2_fx( #ifdef FIX_867_CLDFB_NRG_SCALE IF( isloudspeaker ) { - q_shift = getScaleFactor32( proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = getScaleFactor32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = - 2; scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 -- GitLab From f41bd4034140df724f20b323bb428b547ea1dd24 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 19 Mar 2025 16:37:34 +0100 Subject: [PATCH 0490/1221] Correct rescale buffer boundaries of proto_power_smooth_fx. Correction. --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 10 +--------- lib_rend/ivas_dirac_rend_fx.c | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 1692b1b0b..d88d83a93 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -1955,11 +1955,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word16 alphaMaxBinFast; Word32 L_tmp; Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS]; -#if 1 Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp; -#else - Word16 exp = 0, exp1, q_com, q_tmp, min_exp; -#endif Word32 tmp32; move16(); @@ -2187,13 +2183,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( exp = 0; move16(); -#if 1 + tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 -#else - L_tmp = BASOP_Util_Divide3232_Scale_cadence( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ - smoothedDirectionSmoothness = L_shl_sat( L_tmp, exp ); // Q31 -#endif h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31 move32(); diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 503b1f3e8..006b53ec9 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1818,7 +1818,6 @@ void protoSignalComputation2_fx( q_shift = getScaleFactor32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - q_shift = - 2; scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 -- GitLab From 415682e308b8082a2ccdf70b594913c672da865f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 20 Mar 2025 10:11:14 +0530 Subject: [PATCH 0491/1221] Fix for 3GPP issue 1409: Stereo Encoder: Differences in DTX for LTV 16 kHz signal Link #1409 --- lib_enc/cng_enc_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index b65d41403..f148d3e4c 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -1876,7 +1876,7 @@ void CNG_enc_ivas_fx( { E_LPC_f_lsp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M ); exp = sub( Q14, norm_s( Aq[0] ) ); - Scale_sig( Aq, M, sub( Q12, exp ) ); // Q12 + Scale_sig( Aq, M + 1, sub( Q12, exp ) ); // Q12 } tmp_loop = shr( st_fx->L_frame, 6 ); @@ -1986,19 +1986,19 @@ void CNG_enc_ivas_fx( move16(); BREAK; case L_FRAME32k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME32k_Q31; move16(); BREAK; case L_FRAME16k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME16k_Q31; move16(); BREAK; case L_FRAME8k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME8k_Q31; move16(); BREAK; case L_FRAME4k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME4k_Q31; move16(); BREAK; default: -- GitLab From 556608f757feebcf49295e970bdd086d6c42fcce Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 20 Mar 2025 15:47:00 +0530 Subject: [PATCH 0492/1221] Bug fix in CNG_enc_ivas_fx, saturation removal and correction of macro value for MASA path --- lib_com/ivas_cnst.h | 2 +- lib_com/rom_com.c | 15 +++++++++++++++ lib_com/rom_com.h | 19 ++++++++++--------- lib_com/swb_tbe_com_fx.c | 2 +- lib_enc/cng_enc_fx.c | 8 ++++---- lib_enc/swb_tbe_enc_fx.c | 24 ++++++++++++------------ 6 files changed, 43 insertions(+), 27 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 2abb790f1..9243b3f50 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1285,7 +1285,7 @@ enum #define MASA_RATIO_THRESHOLD 0.1f #define MASA_ANGLE_TOLERANCE 0.5f #define MASA_RATIO_THRESHOLD_FX 214748365 // 0.1 in Q31 -#define MASA_RATIO_TOLERANCE_FX 214748364/*0.1 Q30*/ +#define MASA_RATIO_TOLERANCE_FX 107374182 // 0.1 in Q30 #define MASA_ANGLE_TOLERANCE_FX ONE_IN_Q21 // 0.5 in Q22 #define MASA_LIMIT_NO_BANDS_SUR_COH 8 #define MINIMUM_BIT_BUDGET_NORMAL_META 100 diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 87b323d0a..e6f392ff0 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -25351,6 +25351,21 @@ const Word16 lsp_shb_prev_tbl_fx[LPC_SHB_ORDER] = { 13107, 14746 }; + +const Word16 lsp_shb_prev_tbl_swb_tbe_enc_fx[LPC_SHB_ORDER] = { + // Q15 + 32767, + 31165, + 26509, + 19262, + 10123, + 0, + -10124, + -19261, + -26509, + -31166, +}; + const Word16 ivas_lsp_shb_prev_tbl_fx[LPC_SHB_ORDER] = { /* Q15 */ 1489, diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 10bce5bb2..73156b989 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -1504,15 +1504,16 @@ extern const Word16 tab_hup_l_fx[]; // Q15 extern const Word16 mfreq_loc_Q2fx[]; // Q0 extern const Word16 mfreq_loc_div_25[]; // Q0 -extern const Word16 band_len_idx[]; // Q0 -extern const Word16 band_len_ener_shift[]; // Q0 -extern const Word16 fine_gain_pred_sqrt_bw[]; // Q11 -extern const Word16 ivas_band_len_idx[]; // Q0 -extern const Word16 ivas_band_len_ener_shift[]; // Q0 -extern const Word16 ivas_fine_gain_pred_sqrt_bw[]; // Q11 -extern const Word16 Mean_isf_wb[]; // Q2.56 -extern const Word16 lsp_shb_prev_tbl_fx[]; // Q15 -extern const Word16 ivas_lsp_shb_prev_tbl_fx[]; // Q15 +extern const Word16 band_len_idx[]; // Q0 +extern const Word16 band_len_ener_shift[]; // Q0 +extern const Word16 fine_gain_pred_sqrt_bw[]; // Q11 +extern const Word16 ivas_band_len_idx[]; // Q0 +extern const Word16 ivas_band_len_ener_shift[]; // Q0 +extern const Word16 ivas_fine_gain_pred_sqrt_bw[]; // Q11 +extern const Word16 Mean_isf_wb[]; // Q2.56 +extern const Word16 lsp_shb_prev_tbl_fx[]; // Q15 +extern const Word16 lsp_shb_prev_tbl_swb_tbe_enc_fx[]; // Q15 +extern const Word16 ivas_lsp_shb_prev_tbl_fx[]; // Q15 extern const Word16 tab_ari_qnew[4][4]; // enhancer.c diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 238478b1a..04b6ba187 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -930,7 +930,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( { L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); } - g0 = extract_h( L_shl_sat( L_g0, 14 ) ); + g0 = extract_h( L_shl( L_g0, 14 ) ); /* Scale signal i of 1/A(gamma1) */ IF( GT_16( g0, 1024 ) ) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index b65d41403..99e99bef7 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -1305,19 +1305,19 @@ void CNG_enc_ivas_fx( move16(); BREAK; case L_FRAME32k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME32k_Q31; move16(); BREAK; case L_FRAME16k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME16k_Q31; move16(); BREAK; case L_FRAME8k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME8k_Q31; move16(); BREAK; case L_FRAME4k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME4k_Q31; move16(); BREAK; default: diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index ba8ee5aa8..9b4f15dc5 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -21,7 +21,6 @@ #define ENVSHBRES_ACORR_MIN 40 /* minimum lag for calculating autocorrelation function on SHB residual TD envelope */ #define ENVSHBRES_ACORR_MAX 80 /* maximum lag for calculating autocorrelation function on SHB residual TD envelope */ - /*-----------------------------------------------------------------* * Local functions *-----------------------------------------------------------------*/ @@ -551,7 +550,7 @@ void InitSWBencBuffer_ivas_fx( FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_fx[i]; + hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_swb_tbe_enc_fx[i]; move16(); } @@ -3109,14 +3108,7 @@ void swb_tbe_enc_ivas_fx( } } - /* stab_check = a2lsp( lsf_shb, lpc_shb, LPC_SHB_ORDER ); - stab_check missing */ - /* LPC to LSP conversion */ - /* LPC: Q12, LSP: Q15 */ - E_LPC_a_lsp_conversion( lpc_shb_fx, lsp_shb_fx, hBWE_TD->prev_lsp_shb_fx, LPC_SHB_ORDER ); - - /* LSP to LSF conversion */ - /* LSP: Q15, LSF: Q15 */ - E_LPC_lsp_lsf_conversion( lsp_shb_fx, lsf_shb_fx, LPC_SHB_ORDER ); + /* stab_check = a2lsp( lsf_shb, lpc_shb, LPC_SHB_ORDER ); */ test(); test(); @@ -3124,8 +3116,8 @@ void swb_tbe_enc_ivas_fx( { FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - // hBWE_TD->prev_lsp_shb_fx[i] = i / 20.0f; - hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_fx[i]; + // hBWE_TD->prev_lsp_shb_fx[i] = i / 20.0f; // This value in float enc is lsf. + hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_swb_tbe_enc_fx[i]; // lsf converted to lsp as fixed enc stores lsp. move16(); } } @@ -3135,6 +3127,14 @@ void swb_tbe_enc_ivas_fx( // mvr2r( hBWE_TD->prev_lsp_shb, lsf_shb, LPC_SHB_ORDER ); // } + /* LPC to LSP conversion */ + /* LPC: Q12, LSP: Q15 */ + E_LPC_a_lsp_conversion( lpc_shb_fx, lsp_shb_fx, hBWE_TD->prev_lsp_shb_fx, LPC_SHB_ORDER ); + + /* LSP to LSF conversion */ + /* LSP: Q15, LSF: Q15 */ + E_LPC_lsp_lsf_conversion( lsp_shb_fx, lsf_shb_fx, LPC_SHB_ORDER ); + Copy( lsp_shb_fx, hBWE_TD->prev_lsp_shb_fx, LPC_SHB_ORDER ); Copy( lsf_shb_fx, lsf_shb_orig_fx, LPC_SHB_ORDER ); -- GitLab From e538224816eff3d9455bc28e81be5d5eb29c18d0 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Mar 2025 11:24:07 +0100 Subject: [PATCH 0493/1221] [revert-me] change branch for getting the scripts --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91fbd0569..a42d849c6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" + BASOP_CI_BRANCH_PC_REPO: "ci/split-output-files-b4-comparison" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From 7cd676169f61f8c3016e85673416355e6d3833cb Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Mar 2025 11:28:53 +0100 Subject: [PATCH 0494/1221] add split comparison support to CI config --- .gitlab-ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a42d849c6..7dc0f45f6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,6 +44,7 @@ variables: ENCODER_TEST: "" DELTA_ODG: "" COMPARE_DMX: "" + SPLIT_COMPARISON: "" SKIP_REGRESSION_CHECK: "" FAILED_TESTCASES_LIST: "failed-testcases.txt" ERRORS_TESTCASES_LIST: "errors-testcases.txt" @@ -402,6 +403,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; fi # DMX comparison only in manual job with no other metrics - if [ "$COMPARE_DMX" = "true" ]; then @@ -1416,6 +1418,7 @@ ivas-pytest-compare_ref-long-enc: - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$LONG_TEST_SUITE_ENCODER" - LEVEL_SCALING=1.0 + - SPLIT_COMPARISON="true" <<: *ivas-pytest-anchor ivas-pytest-compare_ref-long-dec: @@ -1427,6 +1430,7 @@ ivas-pytest-compare_ref-long-dec: - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - TEST_SUITE="$LONG_TEST_SUITE" - LEVEL_SCALING=1.0 + - SPLIT_COMPARISON="true" <<: *ivas-pytest-anchor ivas-pytest-compare_ref-long-enc-lev-10: @@ -1438,6 +1442,7 @@ ivas-pytest-compare_ref-long-enc-lev-10: - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$LONG_TEST_SUITE_ENCODER" - LEVEL_SCALING=0.3162 + - SPLIT_COMPARISON="true" <<: *ivas-pytest-anchor ivas-pytest-compare_ref-long-dec-lev-10: @@ -1449,6 +1454,7 @@ ivas-pytest-compare_ref-long-dec-lev-10: - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - TEST_SUITE="$LONG_TEST_SUITE" - LEVEL_SCALING=0.3162 + - SPLIT_COMPARISON="true" <<: *ivas-pytest-anchor ivas-pytest-compare_ref-long-enc-lev+10: @@ -1460,6 +1466,7 @@ ivas-pytest-compare_ref-long-enc-lev+10: - DUT_DECODER_PATH=./$REF_DECODER_PATH - TEST_SUITE="$LONG_TEST_SUITE_ENCODER" - LEVEL_SCALING=3.162 + - SPLIT_COMPARISON="true" <<: *ivas-pytest-anchor ivas-pytest-compare_ref-long-dec-lev+10: @@ -1471,6 +1478,7 @@ ivas-pytest-compare_ref-long-dec-lev+10: - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - TEST_SUITE="$LONG_TEST_SUITE" - LEVEL_SCALING=3.162 + - SPLIT_COMPARISON="true" <<: *ivas-pytest-anchor ivas-smoke-test-saturation: -- GitLab From 15eeaa14adea56366265d954eab302a8b248fedd Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 20 Mar 2025 18:50:36 +0530 Subject: [PATCH 0495/1221] Fix for 3GPP issue 1339: Artifact in IGF part for first active frame after DTX period in MDCT-Stereo Link #1339 --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index b68578542..a73120286 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -360,6 +360,32 @@ void stereo_mdct_core_enc_fx( } q_spec = sub( Q31, q_spec ); + /*find headroom to increase precision*/ + Word16 hdrm_min = MAX_16; + move16(); + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + length = sts[ch]->hTcxEnc->L_frameTCX; + move16(); + } + ELSE + { + length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + } + FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[k], length ) ); + hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][k], length ) ); + } + } + + IF( hdrm_min != 0 ) + { + q_spec = sub( add( hdrm_min, q_spec ), 1 ); /*1 guard bit to avoid over-flows*/ + } + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { Word16 n_sb = NB_DIV; -- GitLab From 3d8caf909acee8773088b0a5fa9363ece42c48e1 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Mar 2025 15:13:24 +0100 Subject: [PATCH 0496/1221] add COMPLEXITY/logs folder to artifacts --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91fbd0569..7a28b9871 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1748,6 +1748,7 @@ voip-be-on-merge-request: expire_in: 2 week paths: - $CI_JOB_NAME-public + - COMPLEXITY/logs complexity-stereo-in-stereo-out: extends: -- GitLab From 8cd0343d0ca9bf8a7b540a5b16c36c1c6f268701 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Mar 2025 16:02:06 +0100 Subject: [PATCH 0497/1221] remove log folder b4 running COMPLEXITY check this should avoid archiving any old logs in case not all of them are overwritten (e.g. when new modes are added) --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7a28b9871..abd8e02ef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1741,6 +1741,8 @@ voip-be-on-merge-request: - *update-ltv-repo - *build-float-ref-and-dut-binaries - *complexity-measurements-setup + # delete previous jobs logfiles if present (-f flag ensures return calue of 0 even in first run where this folder is not present) + - rm -rf COMPLEXITY/logs - which coan artifacts: name: "$CI_JOB_NAME--$CI_COMMIT_REF_NAME--sha-$CI_COMMIT_SHA" -- GitLab From 469ab4619d538f0df6037890fd6abfa8e8cadb48 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 27 Feb 2025 10:39:39 +0100 Subject: [PATCH 0498/1221] - added some wmops push/pop, - added FIX_xxxx_SPEEDUP_00: not implemented, no bitstream - added FIX_xxxx_SPEEDUP_01: not implemented yet --- lib_com/basop_util.c | 6 +- lib_dec/ivas_jbm_dec_fx.c | 2 +- .../ivas_dirac_dec_binaural_functions_fx.c | 72 +++++++++++++++++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index b7ee35ab3..fa8d097df 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1010,6 +1010,7 @@ Word32 div_w( Word32 L_num, Word32 L_den ) } } + Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { Word32 z; @@ -1017,6 +1018,8 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word16 sy; Word32 sign; + //push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); + /* assert (x >= (Word32)0); */ assert( y != (Word32) 0 ); @@ -1038,6 +1041,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) IF( x == (Word32) 0 ) { *s = 0; + //pop_wmops(); return ( (Word32) 0 ); } @@ -1058,7 +1062,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { z = L_negate( z ); } - + //pop_wmops(); return z; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 1918ce3f3..ce60c0d65 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1875,7 +1875,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - push_wmops( "ivas_dec_render" ); + push_wmops( "ivas_dec_render (IDR)" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index b5dd1f8b9..8153775b7 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,6 +45,9 @@ #include "wmc_auto.h" +//#define FIX_xxxx_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream +//#define FIX_xxxx_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui + Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -504,8 +507,9 @@ void ivas_dirac_dec_binaural_render_fx( FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); + push_wmops( "IDR binaural internal (IDRBI)" ); ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx ); - + pop_wmops();/*push_wmops( "IDR binaural internal (IDRBI)" );*/ FOR( ch = 0; ch < nchan_out; ch++ ) { output_fx_local[ch] += n_samples_sf; @@ -708,6 +712,7 @@ static void ivas_dirac_dec_binaural_internal_fx( } } /* CLDFB Analysis of input */ + push_wmops( "IDRBI CLDFB ANALYSYS" ); FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { FOR( ch = 0; ch < numInChannels; ch++ ) @@ -857,6 +862,7 @@ static void ivas_dirac_dec_binaural_internal_fx( } } } + pop_wmops(); /*push_wmops( "IDRBI CLDFB ANALYSYS" );*/ test(); IF( EQ_32( config_data.ivas_format, SBA_FORMAT ) || EQ_32( config_data.ivas_format, SBA_ISM_FORMAT ) ) @@ -921,7 +927,9 @@ static void ivas_dirac_dec_binaural_internal_fx( } test(); + push_wmops( "IDRBI cov matrices" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); + pop_wmops();/*push_wmops( "IDRBI cov matrices" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -959,7 +967,9 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); } + push_wmops( "IDRBI proc matrices (IRDBI pm)" ); ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); + pop_wmops(); /*push_wmops( "IDRBI proc matrices (IRDBI pm)" );*/ q_inp = Q6; move16(); @@ -1005,8 +1015,10 @@ static void ivas_dirac_dec_binaural_internal_fx( hDiracDecBin->q_processMtxDecPrev = q_mat; move16(); + push_wmops( "IDRBI processOutput" ); ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); - + pop_wmops(); /*push_wmops( "IDRBI processOutput" ); + */ hDiracDecBin->hDiffuseDist = NULL; hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); @@ -1843,6 +1855,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); } + push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" ); FOR( bin = 0; bin < nBins; bin++ ) { Word32 tmpMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], gain_fx; @@ -1866,6 +1879,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_CrEne = Q31; move16(); + push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" ); IF( GT_16( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ) { hDiracDecBin->ChEne_fx[1][bin] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ); @@ -1935,7 +1949,9 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->q_ChCrossOut, prototypeMtx_fx, Mre_fx, Mim_fx, &q_M, hDiracDecBin->reqularizationFactor_fx ); + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" );*/ + push_wmops( "IDRBI pm LOOP1 sec B" ); IF( LT_16( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ) { CxRe_fx[0][0] = hDiracDecBin->ChEne_fx[0][bin]; @@ -1989,9 +2005,13 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( #endif resultMtxRe_fx, resultMtxIm_fx, &q_res ); + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec B" );*/ + /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */ + + push_wmops( "IDRBI pm LOOP1 sec C" ); IF( LT_16( bin, max_band_decorr ) ) { Word32 decorrelationReductionFactor_fx; @@ -2107,7 +2127,9 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_Mdec = Q31; move16(); } + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec C" );*/ + push_wmops( "IDRBI pm LOOP1 sec D" ); /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */ tmp1 = L_add( CrEneL_fx, CrEneR_fx ); exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); @@ -2198,6 +2220,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_processMtxDec_bin = q_processMtxDec[bin]; move16(); move16(); + /* Store processing matrices */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -2232,7 +2255,10 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); q_processMtxDec[bin] = sub( q_Mdec, 16 ); move16(); + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec D" );*/ + + push_wmops( "IDRBI pm LOOP1 sec E" ); IF( separateCenterChannelRendering ) { /* The rendering of the separate center channel in masa + mono mode. @@ -2322,7 +2348,10 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec E" );*/ } + pop_wmops(); /*push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" );*/ + /* Aligning Q-factors of all bins in the processing matrices to a common Q-factor */ minimum_s( q_processMtx, nBins, &hDiracDecBin->q_processMtx ); minimum_s( q_processMtxPrev, nBins, &hDiracDecBin->q_processMtxPrev ); @@ -2342,6 +2371,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( minimum_s( q_processMtxDec, nBins, &hDiracDecBin->q_processMtxDec ); minimum_s( q_processMtxDecPrev, nBins, &hDiracDecBin->q_processMtxDecPrev ); + push_wmops( "IRDBI pm LOOP2" ); FOR( bin = 0; bin < nBins; bin++ ) { FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -2381,6 +2411,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } + pop_wmops(); /*push_wmops( "IRDBI pm LOOP2" );*/ return; } @@ -4354,7 +4385,9 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + push_wmops( "formulate2x2MixingMatrix Division" ); maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4377,9 +4410,12 @@ static void formulate2x2MixingMatrix_fx( Cout_im = Mpy_32_32( Cout_im, maxEneDiv_fx ); q_cout = sub( add( q_cout, q_maxEneDiv ), 31 ); + push_wmops( "formulate2x2MixingMatrix cholesky" ); /* Cholesky decomposition of target / output covariance matrix */ chol2x2_fx( E_out1, E_out2, q_eout, Cout_re, Cout_im, q_cout, KyRe_fx, KyIm_fx, &q_ky ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix cholesky" );*/ + push_wmops( "formulate2x2MixingMatrix Eigendecomp" ); /* Eigendecomposition of input covariance matrix */ eig2x2_fx( E_in1, E_in2, q_ein, Cin_re, Cin_im, q_cin, Uxre_fx, Uxim_fx, &q_Ux, Sx_fx, &q_Sx ); @@ -4397,7 +4433,9 @@ static void formulate2x2MixingMatrix_fx( move32(); matrixDiagMul_fx( Uxre_fx, Uxim_fx, q_Ux, Sx_fx, q_Sx, Kxre_fx, Kxim_fx, &q_Kx ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Eigendecomp" );*/ + push_wmops( "formulate2x2MixingMatrix RegSMInv" ); /* Regularize the diagonal Sx for matrix inversion */ Sx_fx[0] = L_max( L_shr( Sx_fx[0], 1 ), Mpy_32_16_1( Sx_fx[1], regularizationFactor_fx ) ); Sx_fx[1] = L_max( L_shr( Sx_fx[1], 1 ), L_shl( Mpy_32_16_1( Sx_fx[0], regularizationFactor_fx ), 1 ) ); @@ -4432,8 +4470,9 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp @@ -4469,8 +4508,9 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4487,7 +4527,9 @@ static void formulate2x2MixingMatrix_fx( move32(); Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); + pop_wmops(); + push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" ); /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -4513,17 +4555,29 @@ static void formulate2x2MixingMatrix_fx( move32(); } } + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ q_temp = sub( add( q_ky, q_GhatQ ), 31 ); + push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" ); /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ + push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ + push_wmops( "oPtoA MT1M" ); +#ifdef FIX_xxxx_SPEEDUP_01 + matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); + + eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#endif + pop_wmops();/*push_wmops( "oPtoA MT1M" );*/ IF( D_fx[0] == 0 ) { @@ -4537,8 +4591,10 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); exp = sub( exp, sub( Q30, q_D ) ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); @@ -4555,7 +4611,9 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4657,7 +4715,9 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ + push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ #if ( BINAURAL_CHANNELS != 2 ) FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -4740,7 +4800,9 @@ static void formulate2x2MixingMatrix_fx( { Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); @@ -4811,6 +4873,8 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Mre_fx, Mim_fx, q_M ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" );*/ + return; } -- GitLab From 679ca05f9e94d39c8df4ff0a4b107b9fd89782bc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 27 Feb 2025 10:41:26 +0100 Subject: [PATCH 0499/1221] change names of macros from xxxx to 1326 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 8153775b7..716b16262 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,8 +45,8 @@ #include "wmc_auto.h" -//#define FIX_xxxx_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -//#define FIX_xxxx_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui +//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream +//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -4568,7 +4568,7 @@ static void formulate2x2MixingMatrix_fx( /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ push_wmops( "oPtoA MT1M" ); -#ifdef FIX_xxxx_SPEEDUP_01 +#ifdef FIX_1326_SPEEDUP_01 matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -- GitLab From 50fbdde0ea69c9e131293ad7a4abecf64498c847 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 27 Feb 2025 16:56:36 +0100 Subject: [PATCH 0500/1221] added and activated FIX_1326_SPEEDUP_00 - 07 --- .../ivas_dirac_dec_binaural_functions_fx.c | 190 +++++++++++++++++- 1 file changed, 182 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 716b16262..d1fb6c23c 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,8 +46,13 @@ #include "wmc_auto.h" //#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui - +#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS +#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS +#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS +#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS +#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -3280,6 +3285,19 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) +#ifdef FIX_1326_SPEEDUP_02 + IF ( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) + { + Ure_fx[0][0] = ONE_IN_Q31; + move32(); + Ure_fx[1][1] = ONE_IN_Q31; + move32(); + *q_U = Q31; + move16(); + + return; + } +#else IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( D_fx[0], *q_D, EPSILON_MANT, EPSILON_EXP ), -1 ) ) { Ure_fx[0][0] = ONE_IN_Q31; @@ -3291,8 +3309,24 @@ static void eig2x2_fx( return; } +#endif /* Numeric case, when input is near an identity matrix with a gain */ +#ifdef FIX_1326_SPEEDUP_03 //178.932 + tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 + + IF( LT_32( pm_fx, L_shl_sat(tmp1, sub(q_tmp1,q_tmp2) ) ) ) + { + Ure_fx[0][0] = ONE_IN_Q30; + move32(); + Ure_fx[1][1] = ONE_IN_Q30; + move32(); + *q_U = Q30; + move16(); + + return; + } +#else tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_16( q_tmp1, q_tmp2 ) ) @@ -3323,6 +3357,7 @@ static void eig2x2_fx( return; } } +#endif q_U_1 = 0; q_U_2 = 0; @@ -3431,10 +3466,22 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); + +#ifdef FIX_1326_SPEEDUP_04 + Word16 exp_tmp2; + Word32 eps_tmp; + + tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &exp_tmp2 ); + eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, exp_tmp2 ) ); + + tmp3 = L_add( L_shr ( tmp2,1), L_shr(eps_tmp,1) ); // Add Epsilon if relevant + + exp_tmp3 = add(exp_tmp2 , 1); +#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); - tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); +#endif #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); @@ -4387,7 +4434,7 @@ static void formulate2x2MixingMatrix_fx( { push_wmops( "formulate2x2MixingMatrix Division" ); maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4468,6 +4515,28 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE +#ifdef FIX_1326_SPEEDUP_05 + { + Word16 shift = norm_l( temp ); + temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); + exp_temp = sub( 31, q_ein ); + if ( temp == 0 ) + { + exp_temp = EPSILON_EXP; + move32(); + } + if (temp == 0) + { + temp = EPSILON_MANT; + move32(); + } + temp = ISqrt32( temp , &exp_temp); + shift = sub( 31, q_eout ); + Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); + move32(); + exp = add( shift, exp_temp ); + } +#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); @@ -4478,6 +4547,7 @@ static void formulate2x2MixingMatrix_fx( Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif } +#endif #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif @@ -4506,16 +4576,36 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE +#ifdef FIX_1326_SPEEDUP_06 + { + Word16 shift = norm_l( temp ); + temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); + exp_temp = sub(31, q_ein); + if ( temp == 0 ) + { + exp_temp = add( 0, EPSILON_EXP ); + } + if (temp == 0) + { + temp = L_add( 0, EPSILON_MANT ); + } + temp = ISqrt32( temp, &exp_temp ); + shift = sub( 31, q_eout ); + Ghat_fx[1] = Mpy_32_32( temp, ISqrt32( E_out2, &shift ) ); + exp_temp = add( shift, exp_temp ); + } +#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif } +#endif #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif @@ -4555,21 +4645,86 @@ static void formulate2x2MixingMatrix_fx( move32(); } } - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ q_temp = sub( add( q_ky, q_GhatQ ), 31 ); push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" ); /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ push_wmops( "oPtoA MT1M" ); #ifdef FIX_1326_SPEEDUP_01 - matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); + // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); + + { + Word16 chA, chB; + { + chA = 0, chB = 0; + tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), + Are_fx[1][0], Are_fx[1][0] ), + Aim_fx[0][0], Aim_fx[0][0] ), + Aim_fx[1][0], Aim_fx[1][0] ); + move32(); + } + { + chA = 0, chB = 1; + tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), + Are_fx[1][1], Are_fx[1][0] ), + Aim_fx[0][1], Aim_fx[0][0] ), + Aim_fx[1][1], Aim_fx[1][0] ); + move32(); + tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), + Are_fx[1][1], Aim_fx[1][0] ), + Aim_fx[0][1], Are_fx[0][0] ), + Aim_fx[1][1], Are_fx[1][0] ); + move32(); + } + { + chA = 1, chB = 0; + tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), + Are_fx[1][1], Are_fx[1][1] ), + Aim_fx[0][1], Aim_fx[0][1] ), + Aim_fx[1][1], Aim_fx[1][1] ); + move32(); + } + { + chA = 1, chB = 1; + } + + q_temp = sub( add( q_A, q_A ), 31 ); + + move16(); + Word16 ZeroState = add( 1, 0 ); + if (tmpRe_fx[0][0] != 0) + { + ZeroState = add(0, 0); + } + if ( tmpRe_fx[1][1] != 0 ) + { + ZeroState = add( 0, 0 ); + } + if ( tmpRe_fx[1][0] != 0 ) + { + ZeroState = add( 0, 0 ); + } + if ( tmpIm_fx[1][0] != 0 ) + { + ZeroState = add( 0, 0 ); + } + + if ( sub(ZeroState,1) == 0 ) + { + q_temp = Q31; + move16(); + } + + } + eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); #else @@ -4579,6 +4734,24 @@ static void formulate2x2MixingMatrix_fx( #endif pop_wmops();/*push_wmops( "oPtoA MT1M" );*/ +#ifdef FIX_1326_SPEEDUP_07 + IF( D_fx[0] == 0 ) + { + //temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + //exp = ONE_DIV_EPSILON_EXP; + div_fx[0] = L_add(0,2047986068); //Sqrt32( temp, &exp ); // Q = 31 - exp + exp = add(0,20); + } + ELSE + { + exp = sub( 31, q_D ); + div_fx[0] = ISqrt32( D_fx[0], &exp ); + //temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + //exp = sub( exp, sub( Q30, q_D ) ); + //div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + move32(); + } +#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4598,6 +4771,7 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); +#endif IF( D_fx[1] == 0 ) { -- GitLab From d12ec4121777398516e9a8bab2665f62e16c43c0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 16:32:41 +0100 Subject: [PATCH 0501/1221] apply clang patch --- lib_com/basop_util.c | 6 +- .../ivas_dirac_dec_binaural_functions_fx.c | 139 +++++++++--------- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index fa8d097df..609ca234d 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1018,7 +1018,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word16 sy; Word32 sign; - //push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); + // push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); /* assert (x >= (Word32)0); */ assert( y != (Word32) 0 ); @@ -1041,7 +1041,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) IF( x == (Word32) 0 ) { *s = 0; - //pop_wmops(); + // pop_wmops(); return ( (Word32) 0 ); } @@ -1062,7 +1062,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { z = L_negate( z ); } - //pop_wmops(); + // pop_wmops(); return z; } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index d1fb6c23c..577ee62f7 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -514,7 +514,7 @@ void ivas_dirac_dec_binaural_render_fx( Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); push_wmops( "IDR binaural internal (IDRBI)" ); ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx ); - pop_wmops();/*push_wmops( "IDR binaural internal (IDRBI)" );*/ + pop_wmops(); /*push_wmops( "IDR binaural internal (IDRBI)" );*/ FOR( ch = 0; ch < nchan_out; ch++ ) { output_fx_local[ch] += n_samples_sf; @@ -934,7 +934,7 @@ static void ivas_dirac_dec_binaural_internal_fx( test(); push_wmops( "IDRBI cov matrices" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); - pop_wmops();/*push_wmops( "IDRBI cov matrices" );*/ + pop_wmops(); /*push_wmops( "IDRBI cov matrices" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -1023,7 +1023,7 @@ static void ivas_dirac_dec_binaural_internal_fx( push_wmops( "IDRBI processOutput" ); ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); pop_wmops(); /*push_wmops( "IDRBI processOutput" ); - */ + */ hDiracDecBin->hDiffuseDist = NULL; hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); @@ -3286,7 +3286,7 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) #ifdef FIX_1326_SPEEDUP_02 - IF ( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) + IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { Ure_fx[0][0] = ONE_IN_Q31; move32(); @@ -3312,20 +3312,20 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 //178.932 +#ifdef FIX_1326_SPEEDUP_03 // 178.932 tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 - IF( LT_32( pm_fx, L_shl_sat(tmp1, sub(q_tmp1,q_tmp2) ) ) ) - { - Ure_fx[0][0] = ONE_IN_Q30; - move32(); - Ure_fx[1][1] = ONE_IN_Q30; - move32(); - *q_U = Q30; - move16(); + IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) + { + Ure_fx[0][0] = ONE_IN_Q30; + move32(); + Ure_fx[1][1] = ONE_IN_Q30; + move32(); + *q_U = Q30; + move16(); - return; - } + return; + } #else tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 @@ -3470,13 +3470,13 @@ static void eig2x2_fx( #ifdef FIX_1326_SPEEDUP_04 Word16 exp_tmp2; Word32 eps_tmp; - + tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &exp_tmp2 ); eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, exp_tmp2 ) ); - tmp3 = L_add( L_shr ( tmp2,1), L_shr(eps_tmp,1) ); // Add Epsilon if relevant + tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); // Add Epsilon if relevant - exp_tmp3 = add(exp_tmp2 , 1); + exp_tmp3 = add( exp_tmp2, 1 ); #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); @@ -4525,17 +4525,17 @@ static void formulate2x2MixingMatrix_fx( exp_temp = EPSILON_EXP; move32(); } - if (temp == 0) + if ( temp == 0 ) { temp = EPSILON_MANT; move32(); } - temp = ISqrt32( temp , &exp_temp); + temp = ISqrt32( temp, &exp_temp ); shift = sub( 31, q_eout ); Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); move32(); exp = add( shift, exp_temp ); - } + } #else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); @@ -4580,12 +4580,12 @@ static void formulate2x2MixingMatrix_fx( { Word16 shift = norm_l( temp ); temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub(31, q_ein); + exp_temp = sub( 31, q_ein ); if ( temp == 0 ) { exp_temp = add( 0, EPSILON_EXP ); } - if (temp == 0) + if ( temp == 0 ) { temp = L_add( 0, EPSILON_MANT ); } @@ -4663,46 +4663,46 @@ static void formulate2x2MixingMatrix_fx( { Word16 chA, chB; - { + { chA = 0, chB = 0; - tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), - Are_fx[1][0], Are_fx[1][0] ), - Aim_fx[0][0], Aim_fx[0][0] ), - Aim_fx[1][0], Aim_fx[1][0] ); - move32(); - } - { - chA = 0, chB = 1; - tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), - Are_fx[1][1], Are_fx[1][0] ), - Aim_fx[0][1], Aim_fx[0][0] ), - Aim_fx[1][1], Aim_fx[1][0] ); - move32(); - tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), - Are_fx[1][1], Aim_fx[1][0] ), - Aim_fx[0][1], Are_fx[0][0] ), - Aim_fx[1][1], Are_fx[1][0] ); - move32(); - } - { - chA = 1, chB = 0; - tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), - Are_fx[1][1], Are_fx[1][1] ), - Aim_fx[0][1], Aim_fx[0][1] ), - Aim_fx[1][1], Aim_fx[1][1] ); - move32(); - } - { - chA = 1, chB = 1; - } + tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), + Are_fx[1][0], Are_fx[1][0] ), + Aim_fx[0][0], Aim_fx[0][0] ), + Aim_fx[1][0], Aim_fx[1][0] ); + move32(); + } + { + chA = 0, chB = 1; + tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), + Are_fx[1][1], Are_fx[1][0] ), + Aim_fx[0][1], Aim_fx[0][0] ), + Aim_fx[1][1], Aim_fx[1][0] ); + move32(); + tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), + Are_fx[1][1], Aim_fx[1][0] ), + Aim_fx[0][1], Are_fx[0][0] ), + Aim_fx[1][1], Are_fx[1][0] ); + move32(); + } + { + chA = 1, chB = 0; + tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), + Are_fx[1][1], Are_fx[1][1] ), + Aim_fx[0][1], Aim_fx[0][1] ), + Aim_fx[1][1], Aim_fx[1][1] ); + move32(); + } + { + chA = 1, chB = 1; + } q_temp = sub( add( q_A, q_A ), 31 ); move16(); Word16 ZeroState = add( 1, 0 ); - if (tmpRe_fx[0][0] != 0) + if ( tmpRe_fx[0][0] != 0 ) { - ZeroState = add(0, 0); + ZeroState = add( 0, 0 ); } if ( tmpRe_fx[1][1] != 0 ) { @@ -4717,12 +4717,11 @@ static void formulate2x2MixingMatrix_fx( ZeroState = add( 0, 0 ); } - if ( sub(ZeroState,1) == 0 ) + if ( sub( ZeroState, 1 ) == 0 ) { - q_temp = Q31; + q_temp = Q31; move16(); } - } @@ -4732,23 +4731,23 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); #endif - pop_wmops();/*push_wmops( "oPtoA MT1M" );*/ + pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ #ifdef FIX_1326_SPEEDUP_07 IF( D_fx[0] == 0 ) { - //temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - //exp = ONE_DIV_EPSILON_EXP; - div_fx[0] = L_add(0,2047986068); //Sqrt32( temp, &exp ); // Q = 31 - exp - exp = add(0,20); + // temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + // exp = ONE_DIV_EPSILON_EXP; + div_fx[0] = L_add( 0, 2047986068 ); // Sqrt32( temp, &exp ); // Q = 31 - exp + exp = add( 0, 20 ); } ELSE { exp = sub( 31, q_D ); div_fx[0] = ISqrt32( D_fx[0], &exp ); - //temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); - //exp = sub( exp, sub( Q30, q_D ) ); - //div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + // temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + // exp = sub( exp, sub( Q30, q_D ) ); + // div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); } #else @@ -4787,7 +4786,7 @@ static void formulate2x2MixingMatrix_fx( { push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4889,7 +4888,7 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ @@ -4976,7 +4975,7 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); -- GitLab From f12a124db1300a8f344276a4b674747fa464a264 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 17:04:07 +0100 Subject: [PATCH 0502/1221] added FIX_1326_SPEEDUP_08 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 577ee62f7..2dac2b867 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -53,6 +53,7 @@ #define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS #define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS #define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4772,6 +4773,20 @@ static void formulate2x2MixingMatrix_fx( move32(); #endif +#ifdef FIX_1326_SPEEDUP_08 + // This is just a shortcut to already existing optimizations (FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC) - but makes everything even faster + { + div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 + exp1 = add( 0, 20 ); // move32(); + } + + IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt + { + exp1 = sub( 31, q_D ); + div_fx[1] = ISqrt32( D_fx[1], &exp1 ); + move32(); + } +#else IF( D_fx[1] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4791,7 +4806,7 @@ static void formulate2x2MixingMatrix_fx( } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 move32(); - +#endif q_div = sub( 31, s_max( exp, exp1 ) ); div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); // q_div -- GitLab From 56305ddde36fee4fe6ecfb9e50494117be5a6c74 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 17:07:26 +0100 Subject: [PATCH 0503/1221] fixed warning --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 2dac2b867..7c243d7d8 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3770,6 +3770,7 @@ static void matrixMul_fx( return; } +#ifndef FIX_1326_SPEEDUP_01 static void matrixTransp1Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -3883,6 +3884,7 @@ static void matrixTransp1Mul_fx( return; } +#endif /*FIX_1326_SPEEDUP_01*/ static void matrixTransp2Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -4663,7 +4665,7 @@ static void formulate2x2MixingMatrix_fx( // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); { - Word16 chA, chB; + //Word16 chA, chB; { chA = 0, chB = 0; tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), @@ -4673,7 +4675,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - chA = 0, chB = 1; + //chA = 0, chB = 1; tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), Are_fx[1][1], Are_fx[1][0] ), Aim_fx[0][1], Aim_fx[0][0] ), @@ -4686,7 +4688,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - chA = 1, chB = 0; + //chA = 1, chB = 0; tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), Are_fx[1][1], Are_fx[1][1] ), Aim_fx[0][1], Aim_fx[0][1] ), @@ -4694,7 +4696,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - chA = 1, chB = 1; + //chA = 1, chB = 1; } q_temp = sub( add( q_A, q_A ), 31 ); -- GitLab From 4b66449d1b749bc14b31ea0e1ef9a1715ef29613 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 17:11:02 +0100 Subject: [PATCH 0504/1221] apply clang patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7c243d7d8..1544b4f1a 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4665,7 +4665,7 @@ static void formulate2x2MixingMatrix_fx( // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); { - //Word16 chA, chB; + // Word16 chA, chB; { chA = 0, chB = 0; tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), @@ -4675,7 +4675,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - //chA = 0, chB = 1; + // chA = 0, chB = 1; tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), Are_fx[1][1], Are_fx[1][0] ), Aim_fx[0][1], Aim_fx[0][0] ), @@ -4688,7 +4688,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - //chA = 1, chB = 0; + // chA = 1, chB = 0; tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), Are_fx[1][1], Are_fx[1][1] ), Aim_fx[0][1], Aim_fx[0][1] ), @@ -4696,7 +4696,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - //chA = 1, chB = 1; + // chA = 1, chB = 1; } q_temp = sub( add( q_A, q_A ), 31 ); -- GitLab From 03b77f5ce70483c1024a794f419882ab4a15a1bb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 09:26:29 +0100 Subject: [PATCH 0505/1221] activated SPEEDUP8 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 1544b4f1a..f024f53ba 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,14 +46,14 @@ #include "wmc_auto.h" //#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS -#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS -#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS -#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS -#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS +//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS +//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS +//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs +//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs +//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs! Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- -- GitLab From 86520445e6af996f9ead2625174d24694c6d8ae8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 11:13:06 +0100 Subject: [PATCH 0506/1221] activate SPEEDUP 07 small version --- .../ivas_dirac_dec_binaural_functions_fx.c | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f024f53ba..c452437f1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -52,8 +52,8 @@ //#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS //#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs! +#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs , no replacement of divSqrt +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4746,12 +4746,18 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - exp = sub( 31, q_D ); - div_fx[0] = ISqrt32( D_fx[0], &exp ); - // temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); - // exp = sub( exp, sub( Q30, q_D ) ); - // div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp +#if 1 //old code + push_wmops( "formulate2x2MixingMatrix Division" ); + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + exp = sub( exp, sub( Q30, q_D ) ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ + div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + move32(); +#else + exp = sub(31, q_D); + div_fx[0] = ISqrt32_2( D_fx[0], &exp ); move32(); +#endif } #else IF( D_fx[0] == 0 ) -- GitLab From 12809f5b6359704415a114ddde609e193c899283 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 11:18:14 +0100 Subject: [PATCH 0507/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index c452437f1..1e37860c9 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4746,18 +4746,18 @@ static void formulate2x2MixingMatrix_fx( } ELSE { -#if 1 //old code +#if 1 // old code push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); exp = sub( exp, sub( Q30, q_D ) ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); #else - exp = sub(31, q_D); + exp = sub( 31, q_D ); div_fx[0] = ISqrt32_2( D_fx[0], &exp ); move32(); -#endif +#endif } #else IF( D_fx[0] == 0 ) -- GitLab From 9028c88021ef93cc2cfadb421f1db6be435a788c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 12:22:09 +0100 Subject: [PATCH 0508/1221] activated speedup 01 02 03 04 --- .../ivas_dirac_dec_binaural_functions_fx.c | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 1e37860c9..06b5be3ee 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,14 +46,14 @@ #include "wmc_auto.h" //#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS -//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS -//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs -//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs , no replacement of divSqrt -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! +#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS +#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS +//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE +//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -- > DONT USE +#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // ? WMOPS //Big DIffs , no replacement of divSqrt , PIPELINE GREEN, --> USE +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! -- > USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4521,8 +4521,12 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_05 { Word16 shift = norm_l( temp ); +#if 1 // oldcode + temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); +#else + temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 31, q_ein ); + exp_temp = sub( 30, q_ein ); if ( temp == 0 ) { exp_temp = EPSILON_EXP; @@ -4533,6 +4537,7 @@ static void formulate2x2MixingMatrix_fx( temp = EPSILON_MANT; move32(); } +#endif temp = ISqrt32( temp, &exp_temp ); shift = sub( 31, q_eout ); Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); @@ -4582,8 +4587,11 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_06 { Word16 shift = norm_l( temp ); +#if 0 //oldcode + temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); +#else temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 31, q_ein ); + exp_temp = sub( 31 - 1, q_ein ); if ( temp == 0 ) { exp_temp = add( 0, EPSILON_EXP ); @@ -4592,10 +4600,22 @@ static void formulate2x2MixingMatrix_fx( { temp = L_add( 0, EPSILON_MANT ); } +#endif +#if 1 //oldcode - new code introduces too much noise + push_wmops( "formulate2x2MixingMatrix Division" ); + temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ + exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 +#endif +#else temp = ISqrt32( temp, &exp_temp ); shift = sub( 31, q_eout ); - Ghat_fx[1] = Mpy_32_32( temp, ISqrt32( E_out2, &shift ) ); - exp_temp = add( shift, exp_temp ); + Ghat_fx[1] = Mpy_32_32( temp, Sqrt32( E_out2, &shift ) ); + exp1 = add( shift, exp_temp ); +#endif + } #else { -- GitLab From 90d2563bf00e217b994ad64a27421f37adb0b628 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 12:35:34 +0100 Subject: [PATCH 0509/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 06b5be3ee..5fcc8a2d1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -54,6 +54,7 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -- > DONT USE #define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // ? WMOPS //Big DIffs , no replacement of divSqrt , PIPELINE GREEN, --> USE #define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! -- > USE +#define FIX_1326_SPEEDUP_09 // Relocate matrixMul Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4587,7 +4588,7 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_06 { Word16 shift = norm_l( temp ); -#if 0 //oldcode +#if 0 // oldcode temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); #else temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); @@ -4601,7 +4602,7 @@ static void formulate2x2MixingMatrix_fx( temp = L_add( 0, EPSILON_MANT ); } #endif -#if 1 //oldcode - new code introduces too much noise +#if 1 // oldcode - new code introduces too much noise push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ @@ -4614,8 +4615,7 @@ static void formulate2x2MixingMatrix_fx( shift = sub( 31, q_eout ); Ghat_fx[1] = Mpy_32_32( temp, Sqrt32( E_out2, &shift ) ); exp1 = add( shift, exp_temp ); -#endif - +#endif } #else { @@ -4749,10 +4749,17 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#ifdef FIX_1326_SPEEDUP_09 + matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); +#endif #else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); + +#ifdef FIX_1326_SPEEDUP_09 + matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); +#endif #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ @@ -4860,7 +4867,9 @@ static void formulate2x2MixingMatrix_fx( move16(); } +#ifndef FIX_1326_SPEEDUP_09 matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); +#endif exp = L_norm_arr( div_fx, BINAURAL_CHANNELS ); scale_sig32( div_fx, BINAURAL_CHANNELS, exp ); -- GitLab From 33a98171ada436d22c6f538c5ad3dbefd93bebb0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 14:30:57 +0100 Subject: [PATCH 0510/1221] activate speedup 09 10 11 for testing --- .../ivas_dirac_dec_binaural_functions_fx.c | 80 ++++++++++++++----- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 5fcc8a2d1..e99cb6b34 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,16 +45,25 @@ #include "wmc_auto.h" -//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS -#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS -//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE -//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -- > DONT USE -#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // ? WMOPS //Big DIffs , no replacement of divSqrt , PIPELINE GREEN, --> USE -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! -- > USE -#define FIX_1326_SPEEDUP_09 // Relocate matrixMul +// MHZ NUMBERS: +// NULL: 179.292 + + +//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence --> DONT USE +//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE +//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE +//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE +//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS +//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS +//#define FIX_1326_SPEEDUP_14 // Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -2142,6 +2151,14 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); +#ifdef FIX_1326_SPEEDUP_11 + { + Word16 shift1 = s_max( 0, sub( q_tmp2, q_CrEne ) ); + Word16 shift2 = s_max( 0, sub( q_CrEne, q_tmp2 ) ); + realizedOutputEne_fx = L_add( L_shr( tmp1, shift2 ), L_shr( tmp2, shift1 ) ); + q_realizedOutputEne = s_min( q_CrEne, q_tmp2 ); + } +#else IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); @@ -2154,7 +2171,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_realizedOutputEne = q_tmp2; move16(); } - +#endif exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 1 ); targetOutputEne_fx = L_add( L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ), L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ) ); q_targetOutputEne = add( hDiracDecBin->q_ChEneOut, exp ); @@ -2177,9 +2194,17 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_missingOutputEne = q_targetOutputEne; move16(); } - tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); +#ifdef FIX_1326_SPEEDUP_13 + { + Word16 exp_temp; + tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + tmp2 = ISqrt32( tmp2, &exp_temp ); + gain_fx = Mpy_32_32(tmp2, Sqrt32(tmp1, &exp1)); + q_gain = sub( 31, add( exp_temp, exp1 ) ); + } +#else { Word16 exp_temp; tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); @@ -2188,6 +2213,8 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } gain_fx = Sqrt32( tmp2, &exp2 ); q_gain = sub( 31, exp2 ); +#endif + // 1073741824 = 4 in Q28 IF( LT_16( q_gain, Q28 ) ) @@ -4749,17 +4776,11 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#ifdef FIX_1326_SPEEDUP_09 - matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); -#endif #else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#ifdef FIX_1326_SPEEDUP_09 - matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); -#endif #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ @@ -4849,7 +4870,19 @@ static void formulate2x2MixingMatrix_fx( div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); // q_div move32(); + // 1310720000 = 10,000.0f in Q17 +#ifdef FIX_1326_SPEEDUP_09 + { + Word16 shift1 = s_max( sub( Q17, q_div ), 0 ); + Word16 shift2 = s_max( sub( q_div, Q17 ), 0 ); + + div_fx[0] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[0], shift2 ) ); // q_div + move32(); + div_fx[1] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[1], shift2 ) ); // q_div + move32(); + } +#else IF( LT_16( q_div, Q17 ) ) { div_fx[0] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[0] ); // q_div @@ -4866,10 +4899,9 @@ static void formulate2x2MixingMatrix_fx( q_div = Q17; move16(); } +#endif -#ifndef FIX_1326_SPEEDUP_09 matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); -#endif exp = L_norm_arr( div_fx, BINAURAL_CHANNELS ); scale_sig32( div_fx, BINAURAL_CHANNELS, exp ); @@ -4884,7 +4916,11 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpRe_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { +#ifdef FIX_1326_SPEEDUP_10 + hdrm_re[chA][chB] = W_norm( W_tmp ); +#else hdrm_re[chA][chB] = sub( W_norm( W_tmp ), 0 ); +#endif move16(); W_tmp = W_shl( W_tmp, hdrm_re[chA][chB] ); tmpRe_fx[chA][chB] = W_extract_h( W_tmp ); @@ -4901,7 +4937,11 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpIm_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { +#ifdef FIX_1326_SPEEDUP_10 + hdrm_im[chA][chB] = W_norm( W_tmp ); +#else hdrm_im[chA][chB] = sub( W_norm( W_tmp ), 0 ); +#endif move16(); W_tmp = W_shl( W_tmp, hdrm_im[chA][chB] ); tmpIm_fx[chA][chB] = W_extract_h( W_tmp ); -- GitLab From 1a23f8d8deb4ce90aeac714fd274f3fa6c380f16 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 14:56:15 +0100 Subject: [PATCH 0511/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e99cb6b34..2336151e0 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -58,12 +58,12 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE //#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS //#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE //#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -//#define FIX_1326_SPEEDUP_14 // +//#define FIX_1326_SPEEDUP_14 // Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -2201,7 +2201,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( Word16 exp_temp; tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); tmp2 = ISqrt32( tmp2, &exp_temp ); - gain_fx = Mpy_32_32(tmp2, Sqrt32(tmp1, &exp1)); + gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) ); q_gain = sub( 31, add( exp_temp, exp1 ) ); } #else @@ -2214,7 +2214,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( gain_fx = Sqrt32( tmp2, &exp2 ); q_gain = sub( 31, exp2 ); #endif - + // 1073741824 = 4 in Q28 IF( LT_16( q_gain, Q28 ) ) -- GitLab From c8151a8382939a33af975c6c5bf7e192030fcc10 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 15:33:23 +0100 Subject: [PATCH 0512/1221] added assert testing --- .../ivas_dirac_dec_binaural_functions_fx.c | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 2336151e0..cc6d977f0 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -58,12 +58,12 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE //#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS -//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -//#define FIX_1326_SPEEDUP_14 // +//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) +//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) +//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) +//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -->USE? (pipe coming) +#define FIX_1326_SPEEDUP_14 // test Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -3213,8 +3213,14 @@ static void eig2x2_fx( pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ + #ifdef FIX_1326_SPEEDUP_14 + static int tstcnt = 0; + #endif IF( L_and( c_re == 0, c_im == 0 ) ) { +#ifdef FIX_1326_SPEEDUP_14 + tstcnt ++; +#endif /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 a_fx = (E1 - E2)^2 pm_fx = 0.5 * sqrt(max(0, a_fx)) = 0.5 * max(0, (e1 - e2)) */ @@ -3232,6 +3238,9 @@ static void eig2x2_fx( q_crossSquare = sub( add( q_c, q_c ), 31 ); IF( EQ_32( e1, e2 ) ) { +#ifdef FIX_1326_SPEEDUP_14 + tstcnt++; +#endif /* if e1 - e2 = 0, then a_fx = 4 * crossSquare_fx pm_fx = 0.5 * sqrt(max(0, 4 * crossSquare_fx)) = sqrt(0, crossSquare_fx)*/ test(); @@ -3265,6 +3274,9 @@ static void eig2x2_fx( IF( GT_16( sub( q_c, q_e ), Q15 ) ) { +#ifdef FIX_1326_SPEEDUP_14 + tstcnt++; +#endif pm_fx = L_shr( L_max( 0, L_abs( L_sub( e1, e2 ) ) ), 1 ); q_tmp2 = q_e; move16(); @@ -3288,6 +3300,10 @@ static void eig2x2_fx( } } } +#ifdef FIX_1326_SPEEDUP_14 + if (tstcnt>10000) + assert(0); +#endif // add_fx = 0.5 * (e1 + e2) add_fx = L_shr( L_add( e1, e2 ), 1 ); q_tmp1 = q_e; @@ -4669,7 +4685,6 @@ static void formulate2x2MixingMatrix_fx( move32(); pop_wmops(); - push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" ); /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -4695,14 +4710,11 @@ static void formulate2x2MixingMatrix_fx( move32(); } } - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ q_temp = sub( add( q_ky, q_GhatQ ), 31 ); - push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" ); /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx @@ -4980,7 +4992,7 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" );*/ push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ -- GitLab From c6d0d7dab2acc799534d4a284cf603826d37460c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 15:35:49 +0100 Subject: [PATCH 0513/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index cc6d977f0..c5b3500b2 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3213,13 +3213,13 @@ static void eig2x2_fx( pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ - #ifdef FIX_1326_SPEEDUP_14 +#ifdef FIX_1326_SPEEDUP_14 static int tstcnt = 0; - #endif +#endif IF( L_and( c_re == 0, c_im == 0 ) ) { #ifdef FIX_1326_SPEEDUP_14 - tstcnt ++; + tstcnt++; #endif /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 a_fx = (E1 - E2)^2 @@ -3301,8 +3301,8 @@ static void eig2x2_fx( } } #ifdef FIX_1326_SPEEDUP_14 - if (tstcnt>10000) - assert(0); + if ( tstcnt > 10000 ) + assert( 0 ); #endif // add_fx = 0.5 * (e1 + e2) add_fx = L_shr( L_add( e1, e2 ), 1 ); -- GitLab From 2986c80dd253c39ee60868f08bd0e89d2b64a683 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 09:52:48 +0100 Subject: [PATCH 0514/1221] deactivate SPeedup 14, activate Speedup 13 for testing --- .../ivas_dirac_dec_binaural_functions_fx.c | 75 +++++++++++++++---- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index c5b3500b2..ad9769583 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -49,7 +49,6 @@ // NULL: 179.292 -//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence --> DONT USE //#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE //#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE //#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE @@ -58,12 +57,18 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE //#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) -//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) -//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) -//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -->USE? (pipe coming) -#define FIX_1326_SPEEDUP_14 // test +//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS --> DONTUSE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) +//#define FIX_1326_SPEEDUP_14 // test wether any of these paths is realy necessary, then assert --> DONTUSE (pipes red, asserts!) +//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) +//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) + + + + Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -943,9 +948,9 @@ static void ivas_dirac_dec_binaural_internal_fx( } test(); - push_wmops( "IDRBI cov matrices" ); + push_wmops( "IDRBI cov matrices (IDRBCM)" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); - pop_wmops(); /*push_wmops( "IDRBI cov matrices" );*/ + pop_wmops(); /*push_wmops( "IDRBI cov matrices (IDRBCM)" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -1168,7 +1173,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ move16(); - + push_wmops( "IDRBCM inits" ); q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) ); scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) ); hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; @@ -1202,6 +1207,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ move16(); } + pop_wmops(); /*push_wmops( "IDRBCM inits" );*/ /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ applyLowBitRateEQ = 0; @@ -1214,11 +1220,13 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); IF( EQ_32( ivas_total_brate, IVAS_16k4 ) ) { + push_wmops( "IDRBCM Determine EQ_low_rates" ); FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) { lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = L_add( L_shr( lowBitRateBinauralEQ_fx[bin], 1 ), ONE_IN_Q30 ); // Q31 move32(); } + pop_wmops(); /*push_wmops( "IDRBCM Determine EQ_low_rates" );*/ } ELSE { @@ -1237,6 +1245,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below + push_wmops( "IDRBCM input Matrix" ); /* Calculate input covariance matrix */ FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { @@ -1271,7 +1280,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); } } + pop_wmops(); /*push_wmops( "IDRBCM input Matrix" );*/ + push_wmops( "IDRBCM apply EQ_low" ); /* Apply EQ at low bit rates */ IF( applyLowBitRateEQ != 0 ) { @@ -1324,7 +1335,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } } } + pop_wmops(); /*push_wmops( "IDRBCM apply EQ_low" );*/ + push_wmops( "IDRBCM target matrix" ); /* Determine target covariance matrix containing target binaural properties */ FOR( bin = 0; bin < nBins; bin++ ) { @@ -1484,12 +1497,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word32 hrtfEneCenter_fx, hrtfEneSides_fx, hrtfEneRealized_fx; Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; - +#ifdef FIX_1326_SPEEDUP_15 + hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); //Q25 +#else hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 - +#endif /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. * spreadCoh = 0: Only panning @@ -1518,11 +1533,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the left source of the three coherent sources */ getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); - +#ifdef FIX_1326_SPEEDUP_15 + hrtfEneSides_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), rImagpTmp_fx, rImagpTmp_fx ), lImagpTmp_fx, lImagpTmp_fx ), lRealpTmp_fx, lRealpTmp_fx ); // Q25 +#else hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 +#endif lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 @@ -1610,12 +1628,21 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); } +#ifdef FIX_1326_SPEEDUP_15 + hrtfEne_fx[0] = Madd_32_32( Mpy_32_32( lRealp_fx, lRealp_fx ), lImagp_fx, lImagp_fx ); // Q( 2*q_lr - 31 ) + hrtfEne_fx[1] = Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) + move32(); + move32(); + hrtfCrossRe_fx = Madd_32_32( Mpy_32_32( lRealp_fx, rRealp_fx ), lImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) + hrtfCrossIm_fx = Madd_32_32( Mpy_32_32( -lImagp_fx, rRealp_fx ), lRealp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) +#else hrtfEne_fx[0] = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), Mpy_32_32( lImagp_fx, lImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfEne_fx[1] = L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), Mpy_32_32( rImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) move32(); move32(); hrtfCrossRe_fx = L_add( Mpy_32_32( lRealp_fx, rRealp_fx ), Mpy_32_32( lImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfCrossIm_fx = L_add( Mpy_32_32( -lImagp_fx, rRealp_fx ), Mpy_32_32( lRealp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) +#endif /* Add direct part (1 or 2) covariance matrix */ dirEne_fx = Mpy_32_32( ratio_fx, meanEnePerCh_fx ); // Q(q_meanEnePerCh - 1) @@ -1690,7 +1717,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } ELSE { +#ifdef FIX_1326_SPEEDUP_15 + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( Madd_32_16( L_shl( surCoh_fx, 16 ), hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); +#else hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( L_add( Mpy_32_16_1( hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), L_shl( surCoh_fx, 16 ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); +#endif } move32(); } @@ -1706,6 +1737,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } + pop_wmops();/*push_wmops( "IDRBCM target matrix" );*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -3435,10 +3467,25 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); + +#ifdef FIX_1326_SPEEDUP_16 + + { + Word16 tmp2_exp; + Word32 eps_tmp; + tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &tmp2_exp ); + + //Add epsilon if relevant + eps_tmp = L_shl_sat( epsilon_mant, sub(epsilon_exp, tmp2_exp )); + tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); + + exp_tmp3 = add( tmp2_exp, 1 ); + } +#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); - tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); +#endif #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); -- GitLab From fb3e05c804ec9194ab97c64ce3769c51424ae600 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 09:54:39 +0100 Subject: [PATCH 0515/1221] deactivate SPeedup 14, activate Speedup 13 for testing --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index ad9769583..620b4e323 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -61,7 +61,7 @@ //#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS --> DONTUSE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) +#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) //#define FIX_1326_SPEEDUP_14 // test wether any of these paths is realy necessary, then assert --> DONTUSE (pipes red, asserts!) //#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) -- GitLab From 52740b20377af49c2a78be634f9adf9112b934fa Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 10:09:06 +0100 Subject: [PATCH 0516/1221] apply clang format patch --- .../ivas_dirac_dec_binaural_functions_fx.c | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 620b4e323..7721c3eaa 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -67,8 +67,6 @@ //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) - - Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -1498,12 +1496,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; #ifdef FIX_1326_SPEEDUP_15 - hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); //Q25 + hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); // Q25 #else - hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 - L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 - L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 - Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 + L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 + L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 + Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 #endif /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. @@ -1536,15 +1534,15 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric #ifdef FIX_1326_SPEEDUP_15 hrtfEneSides_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), rImagpTmp_fx, rImagpTmp_fx ), lImagpTmp_fx, lImagpTmp_fx ), lRealpTmp_fx, lRealpTmp_fx ); // Q25 #else - hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 - L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 - L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 - Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 + L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 + L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 + Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 #endif - lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 - lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 - rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 - rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 + lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 + rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 + rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 /* Apply the gain for the right source of the three coherent sources. * -30 degrees to 330 wrapping due to internal functions. */ @@ -1737,7 +1735,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } - pop_wmops();/*push_wmops( "IDRBCM target matrix" );*/ + pop_wmops(); /*push_wmops( "IDRBCM target matrix" );*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -3475,12 +3473,12 @@ static void eig2x2_fx( Word32 eps_tmp; tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &tmp2_exp ); - //Add epsilon if relevant - eps_tmp = L_shl_sat( epsilon_mant, sub(epsilon_exp, tmp2_exp )); + // Add epsilon if relevant + eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, tmp2_exp ) ); tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); exp_tmp3 = add( tmp2_exp, 1 ); - } + } #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); -- GitLab From deae6b08447d0260424ce2f4b4d8455a94172ed5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 10:15:25 +0100 Subject: [PATCH 0517/1221] fix build warning --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7721c3eaa..4db8980e1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1916,7 +1916,11 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); Word32 tmp1, tmp2, res1, res2; Word16 q_tmp1, q_tmp2, q_realizedOutputEne, q_targetOutputEne, q_missingOutputEne, q_gain; +#ifdef FIX_1326_SPEEDUP_13 + Word16 exp1, q_processMtx_bin, q_processMtxDec_bin; +#else Word16 exp1, exp2, q_processMtx_bin, q_processMtxDec_bin; +#endif CrEneL_fx = 0; move32(); -- GitLab From 2248f4d1a256b06ffc8e850d8f3c368a1be827e7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 11:08:02 +0100 Subject: [PATCH 0518/1221] ctivated speedup 15, 16 to test --- .../ivas_dirac_dec_binaural_functions_fx.c | 118 +----------------- 1 file changed, 6 insertions(+), 112 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 4db8980e1..45e1d2bed 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -53,18 +53,14 @@ //#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE //#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE //#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE -//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE -//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE //#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS --> DONTUSE -#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) -//#define FIX_1326_SPEEDUP_14 // test wether any of these paths is realy necessary, then assert --> DONTUSE (pipes red, asserts!) -//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) -//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) +#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -3246,15 +3242,8 @@ static void eig2x2_fx( a_fx = (e1 + e2) * (e1 + e2) - 4.0f * ((e1 * e2) - crossSquare_fx) = (e1 - e2)^2 + 4 * crossSquare_fx pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ - -#ifdef FIX_1326_SPEEDUP_14 - static int tstcnt = 0; -#endif IF( L_and( c_re == 0, c_im == 0 ) ) { -#ifdef FIX_1326_SPEEDUP_14 - tstcnt++; -#endif /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 a_fx = (E1 - E2)^2 pm_fx = 0.5 * sqrt(max(0, a_fx)) = 0.5 * max(0, (e1 - e2)) */ @@ -3272,9 +3261,6 @@ static void eig2x2_fx( q_crossSquare = sub( add( q_c, q_c ), 31 ); IF( EQ_32( e1, e2 ) ) { -#ifdef FIX_1326_SPEEDUP_14 - tstcnt++; -#endif /* if e1 - e2 = 0, then a_fx = 4 * crossSquare_fx pm_fx = 0.5 * sqrt(max(0, 4 * crossSquare_fx)) = sqrt(0, crossSquare_fx)*/ test(); @@ -3308,9 +3294,6 @@ static void eig2x2_fx( IF( GT_16( sub( q_c, q_e ), Q15 ) ) { -#ifdef FIX_1326_SPEEDUP_14 - tstcnt++; -#endif pm_fx = L_shr( L_max( 0, L_abs( L_sub( e1, e2 ) ) ), 1 ); q_tmp2 = q_e; move16(); @@ -3334,10 +3317,6 @@ static void eig2x2_fx( } } } -#ifdef FIX_1326_SPEEDUP_14 - if ( tstcnt > 10000 ) - assert( 0 ); -#endif // add_fx = 0.5 * (e1 + e2) add_fx = L_shr( L_add( e1, e2 ), 1 ); q_tmp1 = q_e; @@ -4611,33 +4590,6 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE -#ifdef FIX_1326_SPEEDUP_05 - { - Word16 shift = norm_l( temp ); -#if 1 // oldcode - temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); -#else - - temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 30, q_ein ); - if ( temp == 0 ) - { - exp_temp = EPSILON_EXP; - move32(); - } - if ( temp == 0 ) - { - temp = EPSILON_MANT; - move32(); - } -#endif - temp = ISqrt32( temp, &exp_temp ); - shift = sub( 31, q_eout ); - Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); - move32(); - exp = add( shift, exp_temp ); - } -#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); @@ -4648,7 +4600,7 @@ static void formulate2x2MixingMatrix_fx( Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif } -#endif + #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif @@ -4677,39 +4629,6 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE -#ifdef FIX_1326_SPEEDUP_06 - { - Word16 shift = norm_l( temp ); -#if 0 // oldcode - temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); -#else - temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 31 - 1, q_ein ); - if ( temp == 0 ) - { - exp_temp = add( 0, EPSILON_EXP ); - } - if ( temp == 0 ) - { - temp = L_add( 0, EPSILON_MANT ); - } -#endif -#if 1 // oldcode - new code introduces too much noise - push_wmops( "formulate2x2MixingMatrix Division" ); - temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ - exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 -#endif -#else - temp = ISqrt32( temp, &exp_temp ); - shift = sub( 31, q_eout ); - Ghat_fx[1] = Mpy_32_32( temp, Sqrt32( E_out2, &shift ) ); - exp1 = add( shift, exp_temp ); -#endif - } -#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); @@ -4720,7 +4639,7 @@ static void formulate2x2MixingMatrix_fx( Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif } -#endif + #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif @@ -4845,30 +4764,6 @@ static void formulate2x2MixingMatrix_fx( #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ -#ifdef FIX_1326_SPEEDUP_07 - IF( D_fx[0] == 0 ) - { - // temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - // exp = ONE_DIV_EPSILON_EXP; - div_fx[0] = L_add( 0, 2047986068 ); // Sqrt32( temp, &exp ); // Q = 31 - exp - exp = add( 0, 20 ); - } - ELSE - { -#if 1 // old code - push_wmops( "formulate2x2MixingMatrix Division" ); - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); - exp = sub( exp, sub( Q30, q_D ) ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ - div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp - move32(); -#else - exp = sub( 31, q_D ); - div_fx[0] = ISqrt32_2( D_fx[0], &exp ); - move32(); -#endif - } -#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4888,7 +4783,6 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#endif #ifdef FIX_1326_SPEEDUP_08 // This is just a shortcut to already existing optimizations (FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC) - but makes everything even faster -- GitLab From 7263a7eebb093028a1980e52b0b2db57ea6182fb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:26:44 +0100 Subject: [PATCH 0519/1221] add SPEEDUP 17, 18, inactive --- .../ivas_dirac_dec_binaural_functions_fx.c | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 45e1d2bed..3a10590f6 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -49,19 +49,20 @@ // NULL: 179.292 -//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) -#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) - +//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? +//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -3343,6 +3344,7 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) + #ifdef FIX_1326_SPEEDUP_02 IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { @@ -3370,7 +3372,7 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 // 178.932 +#ifdef FIX_1326_SPEEDUP_03 tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) @@ -3469,7 +3471,11 @@ static void eig2x2_fx( #endif #if 1 +#ifdef FIX_1326_SPEEDUP_17 + tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); +#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); +#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3557,7 +3563,11 @@ static void eig2x2_fx( #endif #if 1 +#ifdef FIX_1326_SPEEDUP_17 + tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); +#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); +#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3619,7 +3629,19 @@ static void eig2x2_fx( move16(); } } +#ifdef FIX_1326_SPEEDUP_18 + if( q_U_1 != 0 ) + { + *q_U = q_U_1; + move16(); + } + if (q_U_1 == 0) + { + *q_U = q_U_2; + move16(); + } +#else IF( q_U_1 != 0 ) { *q_U = q_U_1; @@ -3629,6 +3651,7 @@ static void eig2x2_fx( *q_U = q_U_2; } move16(); +#endif return; } @@ -4508,7 +4531,11 @@ static void formulate2x2MixingMatrix_fx( ELSE { push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, maxEne_fx, &exp ); +#else maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); +#endif pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } @@ -4630,6 +4657,11 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + if ( E_out2 == 0 ) + { + static int a = 0; + a++; + } temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); @@ -4777,7 +4809,12 @@ static void formulate2x2MixingMatrix_fx( ELSE { push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[0], &exp ); +#else + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); +#endif exp = sub( exp, sub( Q30, q_D ) ); pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ } @@ -4811,7 +4848,11 @@ static void formulate2x2MixingMatrix_fx( ELSE { push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[1], &exp1 ); +#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); +#endif pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } @@ -5021,7 +5062,11 @@ static void formulate2x2MixingMatrix_fx( Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, temp, &exp ); +#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); +#endif pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); -- GitLab From f2a018b19a1fe121adfedb8c38abe8f8bf8c3604 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:41:59 +0100 Subject: [PATCH 0520/1221] add modified version of division '1/x' --- lib_com/basop_util.c | 35 +++++++++++++++++++++++++++++++++++ lib_com/basop_util.h | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 609ca234d..0449ff125 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1066,6 +1066,41 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) return z; } +/*1bit HR in x > 0*/ +Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) +{ + Word32 z; + //Word16 sx; + Word16 sy; + Word32 sign; + + /* assert (x >= (Word32)0); */ + assert( y != (Word32) 0 ); + + sign = 0; + move16(); + + IF( y < 0 ) + { + y = L_negate( y ); + sign = L_xor( sign, 1 ); + } + + sy = norm_l( y ); + y = L_shl( y, sy ); + move16(); + *s = add( 0, sy ); + move16(); + + z = div_w( x, y ); + + if ( sign != 0 ) + { + z = L_negate( z ); + } + return z; + +} Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { Word16 z; diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index a6db7dc8d..697f0b9c6 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -332,6 +332,10 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word32 y, /*!< i : Denominator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ +Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ + + Word16 *s ); /*!< o : Additional scalefactor difference*/ /************************************************************************/ /*! -- GitLab From bdab4c96801c4c19d454e6d280ccc0cbf73752b1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:46:15 +0100 Subject: [PATCH 0521/1221] applied clang format patch --- lib_com/basop_util.c | 3 +-- lib_com/basop_util.h | 6 +++--- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 0449ff125..5eee369f8 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1070,7 +1070,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) { Word32 z; - //Word16 sx; + // Word16 sx; Word16 sy; Word32 sign; @@ -1099,7 +1099,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) z = L_negate( z ); } return z; - } Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 697f0b9c6..1ef2cd8e7 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -332,10 +332,10 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word32 y, /*!< i : Denominator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ -Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ - Word32 y, /*!< i : Denominator*/ +Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ - Word16 *s ); /*!< o : Additional scalefactor difference*/ + Word16 *s ); /*!< o : Additional scalefactor difference*/ /************************************************************************/ /*! diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 3a10590f6..399ac50ca 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3372,7 +3372,7 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 +#ifdef FIX_1326_SPEEDUP_03 tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) @@ -3630,13 +3630,13 @@ static void eig2x2_fx( } } #ifdef FIX_1326_SPEEDUP_18 - if( q_U_1 != 0 ) + if ( q_U_1 != 0 ) { *q_U = q_U_1; move16(); } - if (q_U_1 == 0) + if ( q_U_1 == 0 ) { *q_U = q_U_2; move16(); @@ -4812,7 +4812,7 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_17 temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[0], &exp ); #else - + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); #endif exp = sub( exp, sub( Q30, q_D ) ); -- GitLab From 0fb2d30b8285abdbc76468fc43848939f863a03c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:47:08 +0100 Subject: [PATCH 0522/1221] activated SPEEDUP 17, 18, for test --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 399ac50ca..682a881cd 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -61,8 +61,8 @@ //#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? -//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? +#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? +#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From 73f2a5078c6fd02f318924c41ebb28d74ab3abf7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 09:35:17 +0100 Subject: [PATCH 0523/1221] Activate all SPEEDUP macros available and change division 1/x a bit --- lib_com/basop_util.c | 8 +++-- .../ivas_dirac_dec_binaural_functions_fx.c | 35 ++++++++++--------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 5eee369f8..60174c3c9 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1080,12 +1080,16 @@ Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) sign = 0; move16(); - IF( y < 0 ) + if( y < 0 ) { - y = L_negate( y ); sign = L_xor( sign, 1 ); } + if ( y < 0 ) + { + y = L_negate( y ); + } + sy = norm_l( y ); y = L_shl( y, sy ); move16(); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 682a881cd..f3e6b54d6 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,23 +46,24 @@ #include "wmc_auto.h" // MHZ NUMBERS: -// NULL: 179.292 - - -//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE -//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? -#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? +// NULL: 178.407 +// ALL: 169.499 + + +#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE +#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE +#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From f2b3f155d5d77c922553381a7659f1452230a77f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 10:33:50 +0100 Subject: [PATCH 0524/1221] deactivate 1/x macro, activate all others --- lib_com/basop_util.c | 2 +- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 60174c3c9..273667255 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1080,7 +1080,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) sign = 0; move16(); - if( y < 0 ) + if ( y < 0 ) { sign = L_xor( sign, 1 ); } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f3e6b54d6..333e7603a 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -62,7 +62,7 @@ #define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE #define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE +//#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE #define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From d4f5a9acea1e0583a3f4f4ffd2b6e4d2af7a7dec Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 09:46:33 +0000 Subject: [PATCH 0525/1221] revert divison variation --- lib_com/basop_util.c | 44 +------------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 273667255..b7ee35ab3 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1010,7 +1010,6 @@ Word32 div_w( Word32 L_num, Word32 L_den ) } } - Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { Word32 z; @@ -1018,8 +1017,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word16 sy; Word32 sign; - // push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); - /* assert (x >= (Word32)0); */ assert( y != (Word32) 0 ); @@ -1041,7 +1038,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) IF( x == (Word32) 0 ) { *s = 0; - // pop_wmops(); return ( (Word32) 0 ); } @@ -1062,48 +1058,10 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { z = L_negate( z ); } - // pop_wmops(); - return z; -} - -/*1bit HR in x > 0*/ -Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) -{ - Word32 z; - // Word16 sx; - Word16 sy; - Word32 sign; - /* assert (x >= (Word32)0); */ - assert( y != (Word32) 0 ); - - sign = 0; - move16(); - - if ( y < 0 ) - { - sign = L_xor( sign, 1 ); - } - - if ( y < 0 ) - { - y = L_negate( y ); - } - - sy = norm_l( y ); - y = L_shl( y, sy ); - move16(); - *s = add( 0, sy ); - move16(); - - z = div_w( x, y ); - - if ( sign != 0 ) - { - z = L_negate( z ); - } return z; } + Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { Word16 z; -- GitLab From cb8c3aa9793f09e28933e9ca9de5da91447c425b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 09:47:44 +0000 Subject: [PATCH 0526/1221] more revert division variation --- lib_com/basop_util.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 1ef2cd8e7..a6db7dc8d 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -332,10 +332,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word32 y, /*!< i : Denominator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ -Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ - Word32 y, /*!< i : Denominator*/ - - Word16 *s ); /*!< o : Additional scalefactor difference*/ /************************************************************************/ /*! -- GitLab From a0f0eac658a432e0bba4ec28c6db3350bdde6f7b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 11:51:31 +0100 Subject: [PATCH 0527/1221] cleanup useless speedup macros --- .../ivas_dirac_dec_binaural_functions_fx.c | 123 +++--------------- 1 file changed, 15 insertions(+), 108 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 333e7603a..8da4f82e7 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -47,22 +47,16 @@ // MHZ NUMBERS: // NULL: 178.407 -// ALL: 169.499 +// ALL: 169.499 77 (170.650 wo 17) #define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE #define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE #define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE #define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET #define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE -#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE #define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE #define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -1333,7 +1327,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } pop_wmops(); /*push_wmops( "IDRBCM apply EQ_low" );*/ - push_wmops( "IDRBCM target matrix" ); + push_wmops( "IDRBCM target matrix (IDRBCMtm)" ); /* Determine target covariance matrix containing target binaural properties */ FOR( bin = 0; bin < nBins; bin++ ) { @@ -1359,6 +1353,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh ) q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 ); // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f) /* Determine direct part target covariance matrix (for 1 or 2 directions) */ + push_wmops( "IDRBCMtm LOOP1" ); FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) { Word16 aziDeg, eleDeg; @@ -1437,6 +1432,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric diffuseness_fx = 0; move32(); } + IF( isIsmDirection ) { /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ @@ -1446,7 +1442,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric { diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/ } - IF( separateCenterChannelRendering ) { /* In masa + mono rendering mode, the center directions originate from phantom sources, so the @@ -1493,14 +1488,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word32 hrtfEneCenter_fx, hrtfEneSides_fx, hrtfEneRealized_fx; Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; -#ifdef FIX_1326_SPEEDUP_15 - hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); // Q25 -#else + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 -#endif + /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. * spreadCoh = 0: Only panning @@ -1529,14 +1522,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the left source of the three coherent sources */ getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); -#ifdef FIX_1326_SPEEDUP_15 - hrtfEneSides_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), rImagpTmp_fx, rImagpTmp_fx ), lImagpTmp_fx, lImagpTmp_fx ), lRealpTmp_fx, lRealpTmp_fx ); // Q25 -#else + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 -#endif + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 @@ -1624,21 +1615,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); } -#ifdef FIX_1326_SPEEDUP_15 - hrtfEne_fx[0] = Madd_32_32( Mpy_32_32( lRealp_fx, lRealp_fx ), lImagp_fx, lImagp_fx ); // Q( 2*q_lr - 31 ) - hrtfEne_fx[1] = Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) - move32(); - move32(); - hrtfCrossRe_fx = Madd_32_32( Mpy_32_32( lRealp_fx, rRealp_fx ), lImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) - hrtfCrossIm_fx = Madd_32_32( Mpy_32_32( -lImagp_fx, rRealp_fx ), lRealp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) -#else hrtfEne_fx[0] = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), Mpy_32_32( lImagp_fx, lImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfEne_fx[1] = L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), Mpy_32_32( rImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) move32(); move32(); hrtfCrossRe_fx = L_add( Mpy_32_32( lRealp_fx, rRealp_fx ), Mpy_32_32( lImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfCrossIm_fx = L_add( Mpy_32_32( -lImagp_fx, rRealp_fx ), Mpy_32_32( lRealp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) -#endif /* Add direct part (1 or 2) covariance matrix */ dirEne_fx = Mpy_32_32( ratio_fx, meanEnePerCh_fx ); // Q(q_meanEnePerCh - 1) @@ -1655,6 +1637,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); move32(); } + pop_wmops(); //push_wmops( "IDRBCMtm LOOP1" ); /* Add diffuse / ambient part covariance matrix */ diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 @@ -1713,11 +1696,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } ELSE { -#ifdef FIX_1326_SPEEDUP_15 - hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( Madd_32_16( L_shl( surCoh_fx, 16 ), hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); -#else hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( L_add( Mpy_32_16_1( hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), L_shl( surCoh_fx, 16 ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); -#endif } move32(); } @@ -1733,7 +1712,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } - pop_wmops(); /*push_wmops( "IDRBCM target matrix" );*/ + pop_wmops(); /*push_wmops( "IDRBCM target matrix (IDRBCMtm)" );;*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -2183,14 +2162,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); -#ifdef FIX_1326_SPEEDUP_11 - { - Word16 shift1 = s_max( 0, sub( q_tmp2, q_CrEne ) ); - Word16 shift2 = s_max( 0, sub( q_CrEne, q_tmp2 ) ); - realizedOutputEne_fx = L_add( L_shr( tmp1, shift2 ), L_shr( tmp2, shift1 ) ); - q_realizedOutputEne = s_min( q_CrEne, q_tmp2 ); - } -#else + IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); @@ -2203,7 +2175,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_realizedOutputEne = q_tmp2; move16(); } -#endif + exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 1 ); targetOutputEne_fx = L_add( L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ), L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ) ); q_targetOutputEne = add( hDiracDecBin->q_ChEneOut, exp ); @@ -3373,21 +3345,7 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 - tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 - IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) - { - Ure_fx[0][0] = ONE_IN_Q30; - move32(); - Ure_fx[1][1] = ONE_IN_Q30; - move32(); - *q_U = Q30; - move16(); - - return; - } -#else tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_16( q_tmp1, q_tmp2 ) ) @@ -3418,7 +3376,6 @@ static void eig2x2_fx( return; } } -#endif q_U_1 = 0; q_U_2 = 0; @@ -3472,11 +3429,7 @@ static void eig2x2_fx( #endif #if 1 -#ifdef FIX_1326_SPEEDUP_17 - tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); -#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); -#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3564,11 +3517,7 @@ static void eig2x2_fx( #endif #if 1 -#ifdef FIX_1326_SPEEDUP_17 - tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); -#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); -#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -4531,13 +4480,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, maxEne_fx, &exp ); -#else maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); -#endif - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4620,9 +4563,7 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp @@ -4664,9 +4605,7 @@ static void formulate2x2MixingMatrix_fx( a++; } temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4797,6 +4736,7 @@ static void formulate2x2MixingMatrix_fx( #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ + IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4804,20 +4744,15 @@ static void formulate2x2MixingMatrix_fx( exp = sub( exp, sub( Q30, 62 ) ); #else temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + move32(); exp = ONE_DIV_EPSILON_EXP; + move16(); #endif } ELSE { - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[0], &exp ); -#else - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); -#endif exp = sub( exp, sub( Q30, q_D ) ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); @@ -4848,13 +4783,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[1], &exp1 ); -#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); -#endif - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4869,17 +4798,6 @@ static void formulate2x2MixingMatrix_fx( // 1310720000 = 10,000.0f in Q17 -#ifdef FIX_1326_SPEEDUP_09 - { - Word16 shift1 = s_max( sub( Q17, q_div ), 0 ); - Word16 shift2 = s_max( sub( q_div, Q17 ), 0 ); - - div_fx[0] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[0], shift2 ) ); // q_div - move32(); - div_fx[1] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[1], shift2 ) ); // q_div - move32(); - } -#else IF( LT_16( q_div, Q17 ) ) { div_fx[0] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[0] ); // q_div @@ -4896,7 +4814,6 @@ static void formulate2x2MixingMatrix_fx( q_div = Q17; move16(); } -#endif matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); @@ -4913,11 +4830,7 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpRe_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { -#ifdef FIX_1326_SPEEDUP_10 - hdrm_re[chA][chB] = W_norm( W_tmp ); -#else hdrm_re[chA][chB] = sub( W_norm( W_tmp ), 0 ); -#endif move16(); W_tmp = W_shl( W_tmp, hdrm_re[chA][chB] ); tmpRe_fx[chA][chB] = W_extract_h( W_tmp ); @@ -5062,13 +4975,7 @@ static void formulate2x2MixingMatrix_fx( { Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, temp, &exp ); -#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); -#endif - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); -- GitLab From f97ec39f828d4e605dcca2ed09a3bf3d3cce0f44 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 11:54:30 +0100 Subject: [PATCH 0528/1221] apply clang format patch --- .../ivas_dirac_dec_binaural_functions_fx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 8da4f82e7..101f76a37 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1489,10 +1489,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; - hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 - L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 - L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 - Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 + L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 + L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 + Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. @@ -1523,10 +1523,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the left source of the three coherent sources */ getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); - hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 - L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 - L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 - Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 + L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 + L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 + Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 @@ -1637,7 +1637,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); move32(); } - pop_wmops(); //push_wmops( "IDRBCMtm LOOP1" ); + pop_wmops(); // push_wmops( "IDRBCMtm LOOP1" ); /* Add diffuse / ambient part covariance matrix */ diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 -- GitLab From 1d475785f8351fd7f3fa6f8021878273a945563e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 12:00:04 +0100 Subject: [PATCH 0529/1221] deactivate all speedups --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 101f76a37..4a55a37cc 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -50,14 +50,14 @@ // ALL: 169.499 77 (170.650 wo 17) -#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From cc08c7185e22852fd126643e5ba085e19571e393 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 12:16:25 +0000 Subject: [PATCH 0530/1221] cleaup a bit --- .../ivas_dirac_dec_binaural_functions_fx.c | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 4a55a37cc..ce36e0ae3 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1432,7 +1432,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric diffuseness_fx = 0; move32(); } - IF( isIsmDirection ) { /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ @@ -1442,6 +1441,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric { diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/ } + IF( separateCenterChannelRendering ) { /* In masa + mono rendering mode, the center directions originate from phantom sources, so the @@ -1527,11 +1527,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 - - lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 - lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 - rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 - rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 + lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 + rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 + rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 /* Apply the gain for the right source of the three coherent sources. * -30 degrees to 330 wrapping due to internal functions. */ @@ -2162,7 +2161,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); - IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); @@ -2198,6 +2196,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_missingOutputEne = q_targetOutputEne; move16(); } + tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); #ifdef FIX_1326_SPEEDUP_13 @@ -2258,7 +2257,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_processMtxDec_bin = q_processMtxDec[bin]; move16(); move16(); - /* Store processing matrices */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -3216,6 +3214,7 @@ static void eig2x2_fx( a_fx = (e1 + e2) * (e1 + e2) - 4.0f * ((e1 * e2) - crossSquare_fx) = (e1 - e2)^2 + 4 * crossSquare_fx pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ + IF( L_and( c_re == 0, c_im == 0 ) ) { /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 @@ -3345,7 +3344,6 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ - tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_16( q_tmp1, q_tmp2 ) ) @@ -3425,6 +3423,7 @@ static void eig2x2_fx( #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); + tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); #endif @@ -3513,6 +3512,7 @@ static void eig2x2_fx( #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); + tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); #endif @@ -4563,13 +4563,13 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif } - #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif @@ -4599,19 +4599,14 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - if ( E_out2 == 0 ) - { - static int a = 0; - a++; - } temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif } - #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif @@ -4796,7 +4791,6 @@ static void formulate2x2MixingMatrix_fx( div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); // q_div move32(); - // 1310720000 = 10,000.0f in Q17 IF( LT_16( q_div, Q17 ) ) { -- GitLab From 4f33c171f1892b375ef96274ab4ada09801f2509 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 13:54:05 +0100 Subject: [PATCH 0531/1221] activate the big chunks - SPEEDUP 8, 13 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index ce36e0ae3..f63f27eb0 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -53,8 +53,8 @@ //#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE //#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE //#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE //#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE -- GitLab From 4c1d9288ffd0180ca25a2b0f083d3adf4770accb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 14:32:17 +0100 Subject: [PATCH 0532/1221] activated spedups 1 , 2, 4, 16, 18 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f63f27eb0..7dee99218 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -50,14 +50,14 @@ // ALL: 169.499 77 (170.650 wo 17) -//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE #define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE #define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE -//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE +#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -4618,7 +4618,7 @@ static void formulate2x2MixingMatrix_fx( move32(); Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); - pop_wmops(); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix RegSMInv" );*/ /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) -- GitLab From 9c07d08c9a8733f22592fb9146b9563e089f45c9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 15:56:56 +0100 Subject: [PATCH 0533/1221] rename optimiztion macros, move macros to options.h --- lib_com/options.h | 3 + .../ivas_dirac_dec_binaural_functions_fx.c | 140 +----------------- 2 files changed, 11 insertions(+), 132 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index ccaeca46a..ab7efb8fd 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -176,4 +176,7 @@ #define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ #define OPT_SBA_AVOID_SPAR_RESCALE /* Optimization made to spar decoder and IGF */ #define NONBE_FIX_1386_STEREO_DMX_EVS_PHA /* Orange: Fix for stereo DMX / PHA mode : Change the filter taps resolution (Q31->Q30), improve precision for the IR window, for the ILD & IPD smoothing in sub-bands, for the ISD counters and for ICCr. */ +#define FIX_1326_SUBSTITUTE_CMPMANT32EXP /* FhG: Minor WMOPS tuning*/ +#define FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT /* FhG: WMOPS tuning */ +#define FIX_1326_SPEEDUP_eig2x2_fx /* FhG: Minor WMOPS tuning*/ #endif diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7dee99218..7f2c6b4d4 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,18 +46,6 @@ #include "wmc_auto.h" // MHZ NUMBERS: -// NULL: 178.407 -// ALL: 169.499 77 (170.650 wo 17) - - -#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -1892,11 +1880,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); Word32 tmp1, tmp2, res1, res2; Word16 q_tmp1, q_tmp2, q_realizedOutputEne, q_targetOutputEne, q_missingOutputEne, q_gain; -#ifdef FIX_1326_SPEEDUP_13 - Word16 exp1, q_processMtx_bin, q_processMtxDec_bin; -#else Word16 exp1, exp2, q_processMtx_bin, q_processMtxDec_bin; -#endif CrEneL_fx = 0; move32(); @@ -2199,13 +2183,12 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); -#ifdef FIX_1326_SPEEDUP_13 +#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT { - Word16 exp_temp; - tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - tmp2 = ISqrt32( tmp2, &exp_temp ); + tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp2 ); + tmp2 = ISqrt32( tmp2, &exp2 ); gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) ); - q_gain = sub( 31, add( exp_temp, exp1 ) ); + q_gain = sub( 31, add( exp2, exp1 ) ); } #else { @@ -3317,7 +3300,7 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) -#ifdef FIX_1326_SPEEDUP_02 +#ifdef FIX_1326_SUBSTITUTE_CMPMANT32EXP IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { Ure_fx[0][0] = ONE_IN_Q31; @@ -3406,27 +3389,10 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); - -#ifdef FIX_1326_SPEEDUP_16 - - { - Word16 tmp2_exp; - Word32 eps_tmp; - tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &tmp2_exp ); - - // Add epsilon if relevant - eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, tmp2_exp ) ); - tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); - - exp_tmp3 = add( tmp2_exp, 1 ); - } -#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); -#endif - #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); @@ -3499,22 +3465,10 @@ static void eig2x2_fx( q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); -#ifdef FIX_1326_SPEEDUP_04 - Word16 exp_tmp2; - Word32 eps_tmp; - - tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &exp_tmp2 ); - eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, exp_tmp2 ) ); - - tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); // Add Epsilon if relevant - - exp_tmp3 = add( exp_tmp2, 1 ); -#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); -#endif #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); @@ -3815,7 +3769,6 @@ static void matrixMul_fx( return; } -#ifndef FIX_1326_SPEEDUP_01 static void matrixTransp1Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -3929,7 +3882,6 @@ static void matrixTransp1Mul_fx( return; } -#endif /*FIX_1326_SPEEDUP_01*/ static void matrixTransp2Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -4655,80 +4607,10 @@ static void formulate2x2MixingMatrix_fx( /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ push_wmops( "oPtoA MT1M" ); -#ifdef FIX_1326_SPEEDUP_01 - // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); - - { - // Word16 chA, chB; - { - chA = 0, chB = 0; - tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), - Are_fx[1][0], Are_fx[1][0] ), - Aim_fx[0][0], Aim_fx[0][0] ), - Aim_fx[1][0], Aim_fx[1][0] ); - move32(); - } - { - // chA = 0, chB = 1; - tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), - Are_fx[1][1], Are_fx[1][0] ), - Aim_fx[0][1], Aim_fx[0][0] ), - Aim_fx[1][1], Aim_fx[1][0] ); - move32(); - tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), - Are_fx[1][1], Aim_fx[1][0] ), - Aim_fx[0][1], Are_fx[0][0] ), - Aim_fx[1][1], Are_fx[1][0] ); - move32(); - } - { - // chA = 1, chB = 0; - tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), - Are_fx[1][1], Are_fx[1][1] ), - Aim_fx[0][1], Aim_fx[0][1] ), - Aim_fx[1][1], Aim_fx[1][1] ); - move32(); - } - { - // chA = 1, chB = 1; - } - - q_temp = sub( add( q_A, q_A ), 31 ); - - move16(); - Word16 ZeroState = add( 1, 0 ); - if ( tmpRe_fx[0][0] != 0 ) - { - ZeroState = add( 0, 0 ); - } - if ( tmpRe_fx[1][1] != 0 ) - { - ZeroState = add( 0, 0 ); - } - if ( tmpRe_fx[1][0] != 0 ) - { - ZeroState = add( 0, 0 ); - } - if ( tmpIm_fx[1][0] != 0 ) - { - ZeroState = add( 0, 0 ); - } - - if ( sub( ZeroState, 1 ) == 0 ) - { - q_temp = Q31; - move16(); - } - } - - - eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ @@ -4753,11 +4635,9 @@ static void formulate2x2MixingMatrix_fx( move32(); #ifdef FIX_1326_SPEEDUP_08 - // This is just a shortcut to already existing optimizations (FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC) - but makes everything even faster - { - div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 - exp1 = add( 0, 20 ); // move32(); - } + //Sqrt(1) + div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 + exp1 = add( 0, 20 ); IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt { @@ -4841,11 +4721,7 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpIm_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { -#ifdef FIX_1326_SPEEDUP_10 - hdrm_im[chA][chB] = W_norm( W_tmp ); -#else hdrm_im[chA][chB] = sub( W_norm( W_tmp ), 0 ); -#endif move16(); W_tmp = W_shl( W_tmp, hdrm_im[chA][chB] ); tmpIm_fx[chA][chB] = W_extract_h( W_tmp ); -- GitLab From 596a724fac86c406dc66f1a2353bddeaff67a42f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 15:06:07 +0000 Subject: [PATCH 0534/1221] fix: rename some mocros Cleanup: push/pop wmops --- .../ivas_dirac_dec_binaural_functions_fx.c | 67 ++----------------- 1 file changed, 6 insertions(+), 61 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7f2c6b4d4..e8052b08c 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,8 +45,6 @@ #include "wmc_auto.h" -// MHZ NUMBERS: - Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -506,9 +504,8 @@ void ivas_dirac_dec_binaural_render_fx( FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); - push_wmops( "IDR binaural internal (IDRBI)" ); ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx ); - pop_wmops(); /*push_wmops( "IDR binaural internal (IDRBI)" );*/ + FOR( ch = 0; ch < nchan_out; ch++ ) { output_fx_local[ch] += n_samples_sf; @@ -711,7 +708,6 @@ static void ivas_dirac_dec_binaural_internal_fx( } } /* CLDFB Analysis of input */ - push_wmops( "IDRBI CLDFB ANALYSYS" ); FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { FOR( ch = 0; ch < numInChannels; ch++ ) @@ -861,7 +857,6 @@ static void ivas_dirac_dec_binaural_internal_fx( } } } - pop_wmops(); /*push_wmops( "IDRBI CLDFB ANALYSYS" );*/ test(); IF( EQ_32( config_data.ivas_format, SBA_FORMAT ) || EQ_32( config_data.ivas_format, SBA_ISM_FORMAT ) ) @@ -926,9 +921,7 @@ static void ivas_dirac_dec_binaural_internal_fx( } test(); - push_wmops( "IDRBI cov matrices (IDRBCM)" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); - pop_wmops(); /*push_wmops( "IDRBI cov matrices (IDRBCM)" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -966,9 +959,7 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); } - push_wmops( "IDRBI proc matrices (IRDBI pm)" ); ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); - pop_wmops(); /*push_wmops( "IDRBI proc matrices (IRDBI pm)" );*/ q_inp = Q6; move16(); @@ -1014,10 +1005,8 @@ static void ivas_dirac_dec_binaural_internal_fx( hDiracDecBin->q_processMtxDecPrev = q_mat; move16(); - push_wmops( "IDRBI processOutput" ); ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); - pop_wmops(); /*push_wmops( "IDRBI processOutput" ); - */ + hDiracDecBin->hDiffuseDist = NULL; hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); @@ -1151,7 +1140,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ move16(); - push_wmops( "IDRBCM inits" ); + q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) ); scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) ); hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; @@ -1185,7 +1174,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ move16(); } - pop_wmops(); /*push_wmops( "IDRBCM inits" );*/ /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ applyLowBitRateEQ = 0; @@ -1198,13 +1186,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); IF( EQ_32( ivas_total_brate, IVAS_16k4 ) ) { - push_wmops( "IDRBCM Determine EQ_low_rates" ); FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) { lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = L_add( L_shr( lowBitRateBinauralEQ_fx[bin], 1 ), ONE_IN_Q30 ); // Q31 move32(); } - pop_wmops(); /*push_wmops( "IDRBCM Determine EQ_low_rates" );*/ } ELSE { @@ -1223,7 +1209,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below - push_wmops( "IDRBCM input Matrix" ); /* Calculate input covariance matrix */ FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { @@ -1258,9 +1243,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); } } - pop_wmops(); /*push_wmops( "IDRBCM input Matrix" );*/ - push_wmops( "IDRBCM apply EQ_low" ); /* Apply EQ at low bit rates */ IF( applyLowBitRateEQ != 0 ) { @@ -1313,9 +1296,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } } } - pop_wmops(); /*push_wmops( "IDRBCM apply EQ_low" );*/ - push_wmops( "IDRBCM target matrix (IDRBCMtm)" ); /* Determine target covariance matrix containing target binaural properties */ FOR( bin = 0; bin < nBins; bin++ ) { @@ -1341,7 +1322,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh ) q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 ); // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f) /* Determine direct part target covariance matrix (for 1 or 2 directions) */ - push_wmops( "IDRBCMtm LOOP1" ); FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) { Word16 aziDeg, eleDeg; @@ -1624,7 +1604,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); move32(); } - pop_wmops(); // push_wmops( "IDRBCMtm LOOP1" ); /* Add diffuse / ambient part covariance matrix */ diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 @@ -1699,7 +1678,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } - pop_wmops(); /*push_wmops( "IDRBCM target matrix (IDRBCMtm)" );;*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -1865,7 +1843,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); } - push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" ); FOR( bin = 0; bin < nBins; bin++ ) { Word32 tmpMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], gain_fx; @@ -1889,7 +1866,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_CrEne = Q31; move16(); - push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" ); IF( GT_16( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ) { hDiracDecBin->ChEne_fx[1][bin] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ); @@ -1959,9 +1935,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->q_ChCrossOut, prototypeMtx_fx, Mre_fx, Mim_fx, &q_M, hDiracDecBin->reqularizationFactor_fx ); - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" );*/ - push_wmops( "IDRBI pm LOOP1 sec B" ); IF( LT_16( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ) { CxRe_fx[0][0] = hDiracDecBin->ChEne_fx[0][bin]; @@ -2015,13 +1989,9 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( #endif resultMtxRe_fx, resultMtxIm_fx, &q_res ); - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec B" );*/ - /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */ - - push_wmops( "IDRBI pm LOOP1 sec C" ); IF( LT_16( bin, max_band_decorr ) ) { Word32 decorrelationReductionFactor_fx; @@ -2137,9 +2107,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_Mdec = Q31; move16(); } - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec C" );*/ - push_wmops( "IDRBI pm LOOP1 sec D" ); /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */ tmp1 = L_add( CrEneL_fx, CrEneR_fx ); exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); @@ -2274,10 +2242,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); q_processMtxDec[bin] = sub( q_Mdec, 16 ); move16(); - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec D" );*/ - - push_wmops( "IDRBI pm LOOP1 sec E" ); IF( separateCenterChannelRendering ) { /* The rendering of the separate center channel in masa + mono mode. @@ -2367,10 +2332,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec E" );*/ } - pop_wmops(); /*push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" );*/ - /* Aligning Q-factors of all bins in the processing matrices to a common Q-factor */ minimum_s( q_processMtx, nBins, &hDiracDecBin->q_processMtx ); minimum_s( q_processMtxPrev, nBins, &hDiracDecBin->q_processMtxPrev ); @@ -2390,7 +2352,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( minimum_s( q_processMtxDec, nBins, &hDiracDecBin->q_processMtxDec ); minimum_s( q_processMtxDecPrev, nBins, &hDiracDecBin->q_processMtxDecPrev ); - push_wmops( "IRDBI pm LOOP2" ); FOR( bin = 0; bin < nBins; bin++ ) { FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -2430,7 +2391,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } - pop_wmops(); /*push_wmops( "IRDBI pm LOOP2" );*/ return; } @@ -3393,6 +3353,7 @@ static void eig2x2_fx( q_tmp2 = sub( 31, q_tmp2 ); tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); + #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); @@ -3464,7 +3425,6 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); - tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); @@ -3533,7 +3493,7 @@ static void eig2x2_fx( move16(); } } -#ifdef FIX_1326_SPEEDUP_18 +#ifdef FIX_1326_SPEEDUP_eig2x2_fx if ( q_U_1 != 0 ) { *q_U = q_U_1; @@ -4455,12 +4415,9 @@ static void formulate2x2MixingMatrix_fx( Cout_im = Mpy_32_32( Cout_im, maxEneDiv_fx ); q_cout = sub( add( q_cout, q_maxEneDiv ), 31 ); - push_wmops( "formulate2x2MixingMatrix cholesky" ); /* Cholesky decomposition of target / output covariance matrix */ chol2x2_fx( E_out1, E_out2, q_eout, Cout_re, Cout_im, q_cout, KyRe_fx, KyIm_fx, &q_ky ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix cholesky" );*/ - push_wmops( "formulate2x2MixingMatrix Eigendecomp" ); /* Eigendecomposition of input covariance matrix */ eig2x2_fx( E_in1, E_in2, q_ein, Cin_re, Cin_im, q_cin, Uxre_fx, Uxim_fx, &q_Ux, Sx_fx, &q_Sx ); @@ -4478,9 +4435,7 @@ static void formulate2x2MixingMatrix_fx( move32(); matrixDiagMul_fx( Uxre_fx, Uxim_fx, q_Ux, Sx_fx, q_Sx, Kxre_fx, Kxim_fx, &q_Kx ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Eigendecomp" );*/ - push_wmops( "formulate2x2MixingMatrix RegSMInv" ); /* Regularize the diagonal Sx for matrix inversion */ Sx_fx[0] = L_max( L_shr( Sx_fx[0], 1 ), Mpy_32_16_1( Sx_fx[1], regularizationFactor_fx ) ); Sx_fx[1] = L_max( L_shr( Sx_fx[1], 1 ), L_shl( Mpy_32_16_1( Sx_fx[0], regularizationFactor_fx ), 1 ) ); @@ -4570,7 +4525,6 @@ static void formulate2x2MixingMatrix_fx( move32(); Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix RegSMInv" );*/ /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -4603,17 +4557,12 @@ static void formulate2x2MixingMatrix_fx( /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); - push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ - push_wmops( "oPtoA MT1M" ); matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); - pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ - - IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4634,7 +4583,7 @@ static void formulate2x2MixingMatrix_fx( div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#ifdef FIX_1326_SPEEDUP_08 +#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT //Sqrt(1) div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 exp1 = add( 0, 20 ); @@ -4760,9 +4709,7 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" );*/ - push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ #if ( BINAURAL_CHANNELS != 2 ) FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -4916,8 +4863,6 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Mre_fx, Mim_fx, q_M ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" );*/ - return; } -- GitLab From cfab49b3830826388292f9fe62787a1c773e620c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 16:44:16 +0100 Subject: [PATCH 0535/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e8052b08c..be86281ef 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4584,9 +4584,9 @@ static void formulate2x2MixingMatrix_fx( move32(); #ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT - //Sqrt(1) + // Sqrt(1) div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 - exp1 = add( 0, 20 ); + exp1 = add( 0, 20 ); IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt { -- GitLab From 5f45790784cd617c8a35309386167a8b4ff6a65b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Mar 2025 07:55:08 +0000 Subject: [PATCH 0536/1221] revert:push_wmops: renamed label --- lib_dec/ivas_jbm_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index ce60c0d65..1918ce3f3 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1875,7 +1875,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - push_wmops( "ivas_dec_render (IDR)" ); + push_wmops( "ivas_dec_render" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ -- GitLab From 7ab17f0711234491d62a812cbb9755d5152bfc71 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Mar 2025 09:52:45 +0100 Subject: [PATCH 0537/1221] introduce FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 --- .../ivas_dirac_dec_binaural_functions_fx.c | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index be86281ef..141fe8c4b 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +#define FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 #include #include "options.h" #include @@ -4563,6 +4563,28 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); + +#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 + IF( D_fx[0] == 0 ) + { +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 + exp = sub( exp, sub( Q30, 62 ) ); +#else + temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + move32(); + exp = ONE_DIV_EPSILON_EXP; + move16(); +#endif + div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + move32(); + } + ELSE + { + exp = sub( 31, q_D ); + div_fx[0] = ISqrt32( D_fx[0], &exp ); + } +#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4582,6 +4604,7 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); +#endif /*FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2*/ #ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT // Sqrt(1) -- GitLab From 49363e47e693b6ea13b06be69fae0947b1c0d33c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Mar 2025 10:40:35 +0100 Subject: [PATCH 0538/1221] Revert "introduce FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2" This reverts commit 18d10e60341ba2cd76c8161c396c02a8e7293290. --- .../ivas_dirac_dec_binaural_functions_fx.c | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 141fe8c4b..be86281ef 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ -#define FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 + #include #include "options.h" #include @@ -4563,28 +4563,6 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); - -#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 - IF( D_fx[0] == 0 ) - { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 - exp = sub( exp, sub( Q30, 62 ) ); -#else - temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - move32(); - exp = ONE_DIV_EPSILON_EXP; - move16(); -#endif - div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp - move32(); - } - ELSE - { - exp = sub( 31, q_D ); - div_fx[0] = ISqrt32( D_fx[0], &exp ); - } -#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4604,7 +4582,6 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#endif /*FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2*/ #ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT // Sqrt(1) -- GitLab From 08714e91ed77822c6202f130621c6bf6a5219c6c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 10:26:18 +0530 Subject: [PATCH 0539/1221] Scaling related fix in ivas_enc_fx --- lib_enc/ivas_enc_fx.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index e8e1bc59e..ff5f65b32 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -344,13 +344,22 @@ ivas_error ivas_enc_fx( { norm_data_in = s_min( norm_data_in, L_norm_arr( data_fx[i], input_frame ) ); } - norm_data_in = sub( norm_data_in, 7 ); /*guard bit is 4->to handle overflow in cldfbAnalysis*/ - FOR( i = 0; i < hEncoderConfig->nchan_ism + st_ivas->nchan_transport; i++ ) + IF( LT_16( norm_data_in, 31 ) ) + { + norm_data_in = sub( norm_data_in, 7 ); /*guard bit is 4->to handle overflow in cldfbAnalysis*/ + norm_data_in = s_min( norm_data_in, 20 ); // limit Q to 31 (11 + norm) + FOR( i = 0; i < hEncoderConfig->nchan_ism + st_ivas->nchan_transport; i++ ) + { + scale_sig32( data_fx[i], input_frame, norm_data_in ); /* st_ivas->q_data_fx + norm_data_in */ + } + st_ivas->q_data_fx = add( st_ivas->q_data_fx, norm_data_in ); + move16(); + } + ELSE { - scale_sig32( data_fx[i], input_frame, norm_data_in ); /* st_ivas->q_data_fx + norm_data_in */ + st_ivas->q_data_fx = 31; + move16(); } - st_ivas->q_data_fx = add( st_ivas->q_data_fx, norm_data_in ); - move16(); } /* Estimate MASA parameters for the objects */ -- GitLab From 40d86c8bcee1e0e4af87fe44f6688fa553e23764 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 10:57:19 +0530 Subject: [PATCH 0540/1221] Fix for 3GPP issue 1404: Stereo LTV signal at 24.4kbps and 32kbps: Modulated noise in BWE region for one-sided signal Link #1404 --- lib_com/rom_com.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index e6f392ff0..03eae8a5a 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -22050,27 +22050,8 @@ const Word32 sigma_BWE_fx[] = {//Q31 40792208 }; /* for 3 bits first stage */ -const Word16 inv_modified_sigma_BWE_fx[] = {//Q1 - 259, -254, -267, -266, -293, -315, -598, -622, -288, -288, -297, -297, -319, -346, -598, -622 -}; - -const Word16 modified_sigma_BWE_fx[] =//Q(log2(2.56) -{ 323, +const Word16 inv_modified_sigma_BWE_fx[] = {//x2.56 +323, 329, 313, 314, @@ -22085,8 +22066,27 @@ const Word16 modified_sigma_BWE_fx[] =//Q(log2(2.56) 262, 242, 140, -134 }; +134 +}; +const Word16 modified_sigma_BWE_fx[] =//Q15 +{ 259, +254, +267, +266, +293, +315, +598, +622, +288, +288, +297, +297, +319, +346, +598, +622 }; + const Word16 SHB_LSF_mean_fx[10] = {//Q15 1353, 2646, 4046, -- GitLab From 12e48fda59637f7114c70df3f2cd79efa5133e03 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 14:43:50 +0530 Subject: [PATCH 0541/1221] Fix for 3GPP issue 1390: Stereo Encoder 13.2 kbps: Wrong Classification for Noisy Content on LTV Link #1390 --- lib_enc/analy_sp_fx.c | 4 ++++ lib_enc/ivas_cpe_enc_fx.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index 185bac26b..bd4ad12ba 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -399,6 +399,10 @@ static void find_enr_dft_ivas_fx( BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 2]; // // *q_Bin_E move32(); + Word16 norm = getScaleFactor32( BinE_fx, L_FFT ); + scale_sig32( BinE_fx, L_FFT, norm ); + *q_Bin_E = add( *q_Bin_E, norm ); + move16(); L_lerp_fx( BinE_fx, Bin_E_fx, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2, q_Bin_E ); MVR2R_WORD32( Bin_E_fx, ptE_fx, VOIC_BINS ); // *q_Bin_E diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index ea70a33d3..a98aa4f53 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -707,7 +707,7 @@ ivas_error ivas_cpe_enc_fx( sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); move16(); shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ + Copy_Scale_sig_32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, sub( add( sts[1]->q_inp, shift ), sts[1]->q_inp32 ) ); /* sts[1]->q_inp + shift */ sts[1]->q_inp = add( sts[1]->q_inp, shift ); move16(); Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ @@ -722,7 +722,7 @@ ivas_error ivas_cpe_enc_fx( sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); move16(); shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[0]->q_inp + shift */ + Copy_Scale_sig_32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, sub( add( sts[0]->q_inp, shift ), sts[0]->q_inp32 ) ); /* sts[0]->q_inp + shift */ sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ -- GitLab From e73fb419ee9c8c74d68cd744eb9df07a92f68a0b Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Mar 2025 11:16:02 +0100 Subject: [PATCH 0542/1221] create two sets of histograms + respective webpages --- .gitlab-ci.yml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7dc0f45f6..15f70e917 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -371,10 +371,12 @@ stages: variables: # keep "mld" in artifact name for backwards compatibility reasons CSV_ARTIFACT_NAME: "mld--$CI_JOB_NAME-$CI_JOB_ID--sha-$CI_COMMIT_SHORT_SHA.csv" + CSV_ARTIFACT_SPLIT: "mld--split--$CI_JOB_NAME-$CI_JOB_ID--sha-$CI_COMMIT_SHORT_SHA.csv" MERGED_CSV_ARTIFACT_NAME: "$CI_JOB_NAME--merged_csv--$CI_JOB_ID.csv" PAGES_HTML_ARTIFACT_NAME: "$CI_JOB_NAME-index.html" SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" + IMAGES_ARTIFACT_SPLIT: "images_split_$CI_JOB_NAME" script: - set -euxo pipefail - *print-common-info @@ -417,10 +419,29 @@ stages: - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + ### create histograms - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME $REPORT_ARG + # if split comparison is done, we need to create two pages, one for the "whole file" values and one for the "split" values + - if [ "$SPLIT_COMPARISON" = "true" ]; then + # use -v flag ("inverse") to also have the header in the output file + - grep -v "_whole" $CSV_ARTIFACT_NAME > $CSV_ARTIFACT_SPLIT + - grep -v "_split" $CSV_ARTIFACT_NAME > $CSV_ARTIFACT_NAME + - mkdir $IMAGES_ARTIFACT_SPLIT + - for MEASURE in $summary_args;do + - python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT/summary_"$MEASURE".csv $IMAGES_ARTIFACT_SPLIT/summary_"$MEASURE".png --measure $MEASURE + - done + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_SPLIT --measures $summary_args + - else + # touch files to suppress warning for missing artifacts + - touch $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT + - fi + + # this part creates the "whole file" histograms - mkdir $IMAGES_ARTIFACT_NAME - - for MEASURE in $summary_args;do python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME --measures $summary_args + - for MEASURE in $summary_args;do + - python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; + - done + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_NAME --measures $summary_args - if [ $USE_LTV -eq 1 ] && [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then - id_previous=$(python3 ci/get_id_of_last_job_occurence.py $CI_DEFAULT_BRANCH $CI_JOB_NAME $CI_PROJECT_ID) @@ -460,9 +481,11 @@ stages: - report.html - $PAGES_HTML_ARTIFACT_NAME - $CSV_ARTIFACT_NAME + - $CSV_ARTIFACT_SPLIT - $MERGED_CSV_ARTIFACT_NAME - $SUMMARY_HTML_ARTIFACT_NAME - $IMAGES_ARTIFACT_NAME + - $IMAGES_ARTIFACT_SPLIT expose_as: "pytest compare results" reports: junit: -- GitLab From 9e6a9b23e43baf835c90a13a79b5ba19b69b730a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 16:08:21 +0530 Subject: [PATCH 0543/1221] Cleanup of pre-processor macros in the main branch --- apps/renderer.c | 4 - lib_com/basop32.c | 4 - lib_com/bits_alloc_fx.c | 62 -- lib_com/bitstream_fx.c | 2 - lib_com/cldfb.c | 6 - lib_com/cnst.h | 2 - lib_com/disclaimer.c | 4 - lib_com/edct_fx.c | 2 - lib_com/fft_fx.c | 26 - lib_com/gs_bitallocation_fx.c | 2 - lib_com/gs_inact_switching_fx.c | 9 - lib_com/ivas_dirac_com_fx.c | 68 -- lib_com/ivas_prot_fx.h | 28 - lib_com/ivas_qmetadata_com_fx.c | 68 -- lib_com/ivas_spar_com_fx.c | 18 - lib_com/ivas_tools_fx.c | 221 ------- lib_com/lerp.c | 4 - lib_com/low_rate_band_att_fx.c | 4 - lib_com/lsf_tools_fx.c | 2 - lib_com/mslvq_com_fx.c | 8 - lib_com/options.h | 110 ---- lib_com/prot_fx.h | 15 - lib_com/rom_com.c | 12 - lib_com/swb_bwe_com_fx.c | 16 - lib_com/swb_bwe_com_lr_fx.c | 4 - lib_com/swb_tbe_com_fx.c | 10 - lib_com/tcq_position_arith_fx.c | 8 - lib_com/tcx_mdct_fx.c | 6 - lib_com/tools.c | 45 -- lib_com/tools_fx.c | 59 -- lib_com/trans_direct_fx.c | 2 - lib_com/trans_inv_fx.c | 6 - lib_dec/FEC_HQ_phase_ecu_fx.c | 28 - lib_dec/FEC_fx.c | 8 - lib_dec/TonalComponentDetection_fx.c | 8 - lib_dec/acelp_core_dec_fx.c | 10 - lib_dec/acelp_core_dec_ivas_fx.c | 166 ----- lib_dec/acelp_core_switch_dec_fx.c | 12 - lib_dec/core_switching_dec_fx.c | 27 - lib_dec/dec_gen_voic_fx.c | 4 - lib_dec/dec_tcx_fx.c | 34 - lib_dec/decision_matrix_dec_fx.c | 2 - lib_dec/fd_cng_dec_fx.c | 14 - lib_dec/gs_dec_fx.c | 16 - lib_dec/hq_core_dec_fx.c | 5 - lib_dec/hq_hr_dec_fx.c | 10 - lib_dec/igf_dec_fx.c | 45 -- lib_dec/init_dec_fx.c | 6 - lib_dec/ivas_binRenderer_internal_fx.c | 70 --- lib_dec/ivas_core_dec_fx.c | 75 --- lib_dec/ivas_cpe_dec_fx.c | 8 - lib_dec/ivas_dirac_dec_fx.c | 20 - lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 144 ----- lib_dec/ivas_init_dec.c | 2 - lib_dec/ivas_ism_param_dec_fx.c | 6 - lib_dec/ivas_jbm_dec_fx.c | 97 --- lib_dec/ivas_mc_param_dec_fx.c | 69 -- lib_dec/ivas_mc_paramupmix_dec_fx.c | 14 - lib_dec/ivas_mct_dec_fx.c | 28 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 24 - lib_dec/ivas_mdct_core_dec_fx.c | 33 - lib_dec/ivas_omasa_dec_fx.c | 8 - lib_dec/ivas_osba_dec_fx.c | 12 - lib_dec/ivas_out_setup_conversion_fx.c | 2 - lib_dec/ivas_post_proc_fx.c | 24 - lib_dec/ivas_qmetadata_dec_fx.c | 22 - lib_dec/ivas_sba_dec_fx.c | 22 - lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 20 - lib_dec/ivas_spar_decoder_fx.c | 153 ----- lib_dec/ivas_stat_dec.h | 2 - lib_dec/ivas_stereo_cng_dec.c | 4 - lib_dec/ivas_stereo_dft_dec_fx.c | 42 -- lib_dec/ivas_stereo_ica_dec_fx.c | 5 - lib_dec/ivas_stereo_icbwe_dec_fx.c | 14 - lib_dec/ivas_stereo_mdct_core_dec_fx.c | 5 - lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 5 - lib_dec/ivas_stereo_switching_dec_fx.c | 10 - lib_dec/ivas_svd_dec_fx.c | 592 ------------------ lib_dec/ivas_tcx_core_dec_fx.c | 18 - lib_dec/ivas_td_low_rate_dec_fx.c | 5 - lib_dec/jbm_pcmdsp_apa.c | 2 - lib_dec/lead_deindexing_fx.c | 4 - lib_dec/lib_dec_fx.c | 82 --- lib_dec/stat_dec.h | 9 - lib_dec/swb_tbe_dec_fx.c | 6 - lib_dec/tonalMDCTconcealment_fx.c | 20 - lib_dec/transition_dec_fx.c | 4 - lib_dec/waveadjust_fec_dec_fx.c | 16 - lib_enc/acelp_core_enc_fx.c | 40 -- lib_enc/acelp_core_switch_enc_fx.c | 8 - lib_enc/bass_psfilter_enc_fx.c | 4 - lib_enc/cng_enc_fx.c | 2 - lib_enc/cod_ace_fx.c | 43 -- lib_enc/cod_tcx_fx.c | 11 - lib_enc/cod_uv_fx.c | 18 - lib_enc/core_enc_init_fx.c | 8 - lib_enc/core_enc_ol_fx.c | 2 - lib_enc/core_enc_reconf_fx.c | 2 - lib_enc/core_enc_switch_fx.c | 4 - lib_enc/core_switching_enc_fx.c | 2 - lib_enc/decision_matrix_enc_fx.c | 2 - lib_enc/dtx_fx.c | 25 - lib_enc/enc_acelp_fx.c | 6 - lib_enc/enc_acelpx_fx.c | 4 - lib_enc/enc_gen_voic_fx.c | 4 - lib_enc/enc_pit_exc_fx.c | 12 - lib_enc/enc_tran_fx.c | 2 - lib_enc/enc_uv_fx.c | 4 - lib_enc/energy_fx.c | 4 - lib_enc/ext_sig_ana_fx.c | 18 - lib_enc/find_tilt_fx.c | 4 - lib_enc/gaus_enc_fx.c | 5 - lib_enc/hq_classifier_enc_fx.c | 4 - lib_enc/hq_core_enc_fx.c | 6 - lib_enc/igf_enc.c | 35 -- lib_enc/init_enc_fx.c | 14 - lib_enc/inov_enc_fx.c | 2 - lib_enc/ivas_core_enc_fx.c | 13 - lib_enc/ivas_core_pre_proc_front_fx.c | 32 - lib_enc/ivas_core_pre_proc_fx.c | 6 - lib_enc/ivas_cpe_enc_fx.c | 44 -- lib_enc/ivas_dirac_enc_fx.c | 66 -- lib_enc/ivas_front_vad_fx.c | 4 - lib_enc/ivas_ism_dtx_enc_fx.c | 4 - lib_enc/ivas_ism_enc_fx.c | 10 - lib_enc/ivas_ism_metadata_enc_fx.c | 6 - lib_enc/ivas_masa_enc_fx.c | 4 - lib_enc/ivas_mc_param_enc_fx.c | 8 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 6 - lib_enc/ivas_mcmasa_enc_fx.c | 4 - lib_enc/ivas_mct_core_enc_fx.c | 11 - lib_enc/ivas_mct_enc_mct_fx.c | 8 - lib_enc/ivas_mdct_core_enc_fx.c | 29 - lib_enc/ivas_omasa_enc_fx.c | 4 - lib_enc/ivas_osba_enc_fx.c | 22 - lib_enc/ivas_qmetadata_enc_fx.c | 17 - lib_enc/ivas_sce_enc_fx.c | 6 - lib_enc/ivas_sns_enc_fx.c | 5 - lib_enc/ivas_stat_enc.h | 12 - lib_enc/ivas_stereo_classifier_fx.c | 4 - lib_enc/ivas_stereo_dft_enc_fx.c | 12 - lib_enc/ivas_stereo_dft_enc_itd_fx.c | 51 -- lib_enc/ivas_stereo_dmx_evs_fx.c | 131 ---- lib_enc/ivas_stereo_ica_enc_fx.c | 22 - lib_enc/ivas_stereo_icbwe_enc_fx.c | 10 - lib_enc/ivas_stereo_mdct_core_enc_fx.c | 10 - lib_enc/ivas_stereo_mdct_igf_enc_fx.c | 2 - lib_enc/ivas_stereo_switching_enc_fx.c | 8 - lib_enc/ivas_stereo_td_analysis_fx.c | 29 - lib_enc/ivas_stereo_td_enc_fx.c | 2 - lib_enc/ivas_tcx_core_enc_fx.c | 20 - lib_enc/ivas_td_low_rate_enc_fx.c | 38 -- lib_enc/lib_enc.c | 4 - lib_enc/nois_est_fx.c | 2 - lib_enc/pit_enc_fx.c | 2 - lib_enc/pre_proc_fx.c | 4 - lib_enc/prot_fx_enc.h | 8 - lib_enc/spec_flatness_fx.c | 4 - lib_enc/speech_music_classif_fx.c | 47 -- lib_enc/stat_enc.h | 5 - lib_enc/swb_bwe_enc_fx.c | 21 - lib_enc/swb_pre_proc_fx.c | 4 - lib_enc/swb_tbe_enc_fx.c | 4 - lib_enc/tcx_ltp_enc_fx.c | 4 - lib_enc/tcx_utils_enc_fx.c | 6 - lib_enc/tns_base_enc_fx.c | 4 - lib_enc/transient_detection_fx.c | 9 - lib_enc/transition_enc_fx.c | 16 - .../ivas_dirac_dec_binaural_functions_fx.c | 426 ------------- lib_rend/ivas_dirac_decorr_dec_fx.c | 115 ---- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 34 - lib_rend/ivas_dirac_rend_fx.c | 30 - lib_rend/ivas_mcmasa_ana_fx.c | 2 - lib_rend/ivas_objectRenderer_hrFilt_fx.c | 2 - lib_rend/ivas_objectRenderer_sources_fx.c | 2 - lib_rend/ivas_output_init_fx.c | 4 - lib_rend/ivas_prot_rend_fx.h | 2 - lib_rend/ivas_reverb_fx.c | 9 - lib_rend/ivas_rotation_fx.c | 2 - lib_rend/ivas_stat_rend.h | 4 - lib_rend/lib_rend.c | 2 - lib_rend/lib_rend.h | 2 - lib_util/hrtf_file_reader.c | 4 - 183 files changed, 4669 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index ceb1a448e..47548d438 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -699,10 +699,8 @@ int main( lfeRoutingConfigs[i] = NULL; } -#ifdef FIX_DISCLAIMER IVAS_REND_PrintDisclaimer(); -#endif CmdlnArgs args = parseCmdlnArgs( argc, argv ); if ( args.nonDiegeticPan && !( ( args.inConfig.numAudioObjects == 0 && args.inConfig.multiChannelBuses[0].audioConfig == IVAS_AUDIO_CONFIG_MONO ) || @@ -864,7 +862,6 @@ int main( exit( -1 ); } -#ifdef FIX_DISCLAIMER fprintf( stdout, "Input audio file: %s\n", args.inputFilePath ); fprintf( stdout, "Output audio file: %s\n\n", args.outputFilePath ); @@ -907,7 +904,6 @@ int main( exit( -1 ); } -#endif /* === Configure === */ if ( ( error = IVAS_REND_InitConfig( hIvasRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) { diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 7fab24660..20dbe663e 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -2563,10 +2563,8 @@ Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ) { var_out = shr_o( var1, var2, Overflow ); -#ifdef FIX_1049_SHR_RO_COMPLEXITY #ifdef WMOPS multiCounter[currCounter].shr--; -#endif #endif if ( var2 > 0 ) { @@ -2577,13 +2575,11 @@ Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ) } } -#ifdef FIX_1049_SHR_RO_COMPLEXITY #ifdef WMOPS multiCounter[currCounter].shr_r++; #endif BASOP_CHECK(); -#endif return ( var_out ); } diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 88b276126..cb71f0f28 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -773,9 +773,7 @@ ivas_error config_acelp1( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signalling_bits, /* i : number of signalling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -795,9 +793,7 @@ ivas_error config_acelp1( Word16 flag_hardcoded, coder_type_sw, fix_first; Word32 core_brate; #ifdef DEBUGGING -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) active_cnt; -#endif #endif ivas_error error; @@ -1078,13 +1074,9 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, -1, -1 )]; move16(); @@ -1205,11 +1197,7 @@ ivas_error config_acelp1( { test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ -#else - IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -1427,14 +1415,10 @@ ivas_error config_acelp1( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || /* @12.8kHz core except of GSC */ ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ ) -#else - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) -#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -1498,13 +1482,9 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( flag_hardcoded /* EVS */ || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1613,12 +1593,8 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1658,13 +1634,9 @@ ivas_error config_acelp1( } } } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -1805,12 +1777,8 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ -#else - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ubits = 0; move16(); @@ -1930,9 +1898,7 @@ ivas_error config_acelp1_IVAS( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signaling_bits, /* i : number of signaling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -2214,12 +2180,8 @@ ivas_error config_acelp1_IVAS( test(); test(); /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ -#ifdef NONBE_FIX_GSC_BSTR IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && ( coder_type != INACTIVE ) && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( ( coder_type == INACTIVE ) && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, -1 )]; move16(); @@ -2344,11 +2306,7 @@ ivas_error config_acelp1_IVAS( { test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ -#else - IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -2564,13 +2522,9 @@ ivas_error config_acelp1_IVAS( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) /* @12.8kHz core except of GSC */ || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ ) -#else - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) -#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -2634,13 +2588,9 @@ ivas_error config_acelp1_IVAS( test(); test(); /* algebraic codebook bit-budget */ -#ifdef NONBE_FIX_GSC_BSTR IF( flag_hardcoded /* EVS */ || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2741,12 +2691,8 @@ ivas_error config_acelp1_IVAS( test(); test(); /* AVQ codebook */ -#ifdef NONBE_FIX_GSC_BSTR IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2784,13 +2730,9 @@ ivas_error config_acelp1_IVAS( } } } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -2931,12 +2873,8 @@ ivas_error config_acelp1_IVAS( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ -#else - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ubits = 0; move16(); diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 712a6905e..e144c2cc9 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -526,10 +526,8 @@ void reset_indices_enc_fx( { Word16 i; -#ifdef MSAN_FIX hBstr->nb_ind_tot = 0; move16(); -#endif hBstr->nb_bits_tot = 0; move16(); hBstr->next_ind_fx = 0; diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 48fe4d9bc..408580169 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1101,9 +1101,7 @@ void cldfbSynthesis_ivas_fx( Word32 **imagBuffer_fx, /* i : imag values Qx*/ Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ const Word16 samplesToProcess, /* i : number of processed samples */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE const Word16 shift, /* i : scale for state buffer */ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ) { @@ -1269,10 +1267,8 @@ void cldfbSynthesis_ivas_fx( } /* synthesis prototype filter */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( 0 == shift ) { -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = 0; i < L2; i++ ) { accu0 = Madd_32_16( synthesisBuffer_fx[i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[i] ), p_filter_sf ); // Qx - 1 @@ -1292,7 +1288,6 @@ void cldfbSynthesis_ivas_fx( synthesisBuffer_fx[4 * L2 + i] = accu4; move32(); } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE } ELSE { @@ -1318,7 +1313,6 @@ void cldfbSynthesis_ivas_fx( move32(); } } -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = 0; i < M1; i++ ) { diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 7c93498af..1cc1a8ffe 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -932,9 +932,7 @@ typedef enum #define GAIN_PRED_ORDER 4 /* Gain quantization - prediction order for gain quantizer (only for AMR-WB IO mode) */ #define MEAN_ENER 30 /* Gain quantization - average innovation energy */ -#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD #define DTX_THR 5 /* DTX - lp_noise threshold for DTX at higher bitrates */ -#endif #define DTX_HIST_SIZE 8 /* CNG & DTX - number of last signal frames used for CNG averaging */ #define CNG_ISF_FACT 0.9f /* CNG & DTX - CNG spectral envelope smoothing factor */ diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index 1a01c2c32..3b1677365 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -44,11 +44,7 @@ int16_t print_disclaimer( FILE *fPtr ) { fprintf( fPtr, "\n==================================================================================================\n" ); -#ifdef FIX_DISCLAIMER fprintf( fPtr, " IVAS Codec BASOP Baseline\n" ); -#else - fprintf( fPtr, " IVAS Codec Baseline\n" ); -#endif fprintf( fPtr, " \n" ); fprintf( fPtr, " Based on EVS Codec (Floating Point) 3GPP TS26.443 Nov 04, 2021,\n" ); fprintf( fPtr, " Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0\n" ); diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index b1e2a7dd9..1b303d285 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -395,9 +395,7 @@ void edct_16fx( Word16 Len2, i2; const Word16 *px, *pt; Word16 *py; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow; Overflow = 0; diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 7b63e9c67..31b11a9ea 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -7596,12 +7596,6 @@ Word16 L_norm_arr( const Word32 *arr, Word16 size ) Word16 q = 31; move16(); FOR( Word16 i = 0; i < size; i++ ) -#ifndef FIX_1103_OPT_L_NORM_ARR - IF( arr[i] != 0 ) - { - q = s_min( q, norm_l( arr[i] ) ); - } -#else { Word16 q_tst; @@ -7612,7 +7606,6 @@ Word16 L_norm_arr( const Word32 *arr, Word16 size ) } } -#endif return q; } @@ -7658,24 +7651,6 @@ Word16 W_norm_arr( Word64 *arr, Word16 size ) Word16 get_min_scalefactor( Word32 x, Word32 y ) { -#ifndef FIX_1104_OPT_GETMINSCALEFAC - Word16 scf = Q31; - move16(); - test(); - IF( x == 0 && y == 0 ) - { - return 0; - } - IF( x != 0 ) - { - scf = s_min( scf, norm_l( x ) ); - } - IF( y != 0 ) - { - scf = s_min( scf, norm_l( y ) ); - } - return scf; -#else Word16 scf_y; Word16 scf = Q31; move16(); @@ -7699,7 +7674,6 @@ Word16 get_min_scalefactor( Word32 x, Word32 y ) } return scf; -#endif } diff --git a/lib_com/gs_bitallocation_fx.c b/lib_com/gs_bitallocation_fx.c index 87ba794d4..0ce59482f 100644 --- a/lib_com/gs_bitallocation_fx.c +++ b/lib_com/gs_bitallocation_fx.c @@ -75,10 +75,8 @@ void bands_and_bit_alloc_fx( Word16 SWB_bit_budget; Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; Word16 w_sum_bit; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) GSC_IVAS_mode; (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; #endif diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index c0feb91f5..421b2a705 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -162,13 +162,8 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 L_frame, /* i : Frame lenght */ -#ifndef NONBE_FIX_GSC_BSTR - const Word32 total_brate, /* i : total bit rate */ -#endif const Word16 Q_exc, /* i : input and output format of exc2 */ const Word16 bfi, /* i : frame lost indicator */ const Word16 last_core, /* i : Last core used */ @@ -224,11 +219,7 @@ void Inac_switch_ematch_ivas_fx( move16(); } } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( coder_type == INACTIVE ) && inactive_coder_type_flag ) -#else - ELSE IF( ( coder_type == INACTIVE ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) -#endif { /* Find spectrum and energy per band for inactive frames */ edct_16fx( exc2, dct_exc_tmp, L_frame, 5, element_mode ); diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 146587791..7d481d181 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -609,10 +609,8 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_y, /* o: Q30*/ Word32 *direction_vector_z, /* o: Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 *i_e_band -#endif ) { Word16 i; @@ -631,7 +629,6 @@ void computeDirectionVectors_fixed( scaled_x = L_shl( *intensity_real_x, norm_x ); scaled_y = L_shl( *intensity_real_y, norm_y ); scaled_z = L_shl( *intensity_real_z, norm_z ); -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC IF( i_e_band != NULL ) { e_x = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_x ) ); @@ -644,12 +641,6 @@ void computeDirectionVectors_fixed( e_y = sub( i_e, norm_y ); e_z = sub( i_e, norm_z ); } -#else - - e_x = sub( i_e, norm_x ); - e_y = sub( i_e, norm_y ); - e_z = sub( i_e, norm_z ); -#endif temp1 = BASOP_Util_Add_Mant32Exp( Mult_32_32( scaled_x, scaled_x ), shl( e_x, 1 ), Mult_32_32( scaled_y, scaled_y ), shl( e_y, 1 ), &exp1 ); intensityNorm = BASOP_Util_Add_Mant32Exp( temp1, exp1, Mult_32_32( scaled_z, scaled_z ), shl( e_z, 1 ), &intensityNorm_e ); @@ -966,17 +957,12 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv = L_add( 0, 0 ); Word16 shift_qtotal; if ( shift_q < 0 ) { -#ifdef FIX_USAN_ISSUES shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); -#else - shiftEquiv = L_lshl( 0x80000000, shift_q ); -#endif } if ( shift_q >= 0 ) { @@ -990,27 +976,6 @@ void computeDiffuseness_fixed( energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); move32(); } -#else - Word16 shift_q = sub( q_tmp, q_ene ); - IF( shift_q < 0 ) - { - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp_c[k], min_q_shift1 ); - energy_slow[k] = L_add( L_shl( energy_slow[k], shift_q ), tmp ); - move32(); - } - } - ELSE - { - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp_c[k], min_q_shift1 ); - energy_slow[k] = L_add( energy_slow[k], L_shr( tmp, shift_q ) ); - move32(); - } - } -#endif q_ene = s_min( q_ene, q_tmp ); @@ -1019,14 +984,9 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS if ( shift_q < 0 ) { -#ifdef FIX_USAN_ISSUES shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); -#else - shiftEquiv = L_lshl( 0x80000000, shift_q ); -#endif } if ( shift_q >= 0 ) { @@ -1044,34 +1004,6 @@ void computeDiffuseness_fixed( move32(); } } -#else - IF( shift_q > 0 ) - { - FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) - { - p_tmp = buffer_intensity[j][i]; - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp[k], min_q_shift2 ); - intensity_slow[j * num_freq_bands + k] = L_add( intensity_slow[j * num_freq_bands + k], L_shr( tmp, shift_q ) ); - move32(); - } - } - } - ELSE - { - FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) - { - p_tmp = buffer_intensity[j][i]; - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp[k], min_q_shift2 ); - intensity_slow[j * num_freq_bands + k] = L_add( L_shl( intensity_slow[j * num_freq_bands + k], shift_q ), tmp ); - move32(); - } - } - } -#endif q_intensity = s_min( q_intensity, q_tmp ); } diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index ab043fc0f..fab166b6d 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1309,7 +1309,6 @@ Word16 matrix_diag_product_fx( Word32 *Z, /* o : resulting matrix after the matrix multiplication */ Word16 *Z_e ); -#ifdef OPT_BASOP_ADD_v1 Word16 matrix_diag_product_fx_2( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ const Word16 X_e, @@ -1321,7 +1320,6 @@ Word16 matrix_diag_product_fx_2( const Word16 entriesY, /* i : number of entries in the diagonal Q0*/ Word32 *Z, /* o : resulting matrix after the matrix multiplication Q31 - Z_e*/ Word16 *Z_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix */ @@ -3238,10 +3236,8 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_y, /*Q30*/ Word32 *direction_vector_z, /*Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 *i_e_band -#endif ); @@ -3787,10 +3783,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ Word32 *output_fx[] /* o : rendered time signal */ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); ivas_error ivas_osba_ism_metadata_dec_fx( @@ -4706,21 +4698,11 @@ Word32 dot_product_cholesky_fx( const Word16 N /* i : vector & matrix size */ ); -#ifndef DOT_PROD_CHOLESKY_64BIT -Word32 dot_product_cholesky_fixed( - const Word32 *x, /* i : vector x */ - const Word32 *A, /* i : Cholesky matrix A */ - const Word16 N, /* i : vector & matrix size */ - const Word16 exp_x, - const Word16 exp_A, - Word16 *exp_sum ); -#else Word64 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ const Word16 N /* i : vector & matrix size */ ); -#endif void v_mult_mat_fx( Word32 *y_fx, /* o : the product x*A */ @@ -5347,20 +5329,12 @@ ivas_error ivas_sba_dec_render_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ Word32 *output_fx[] /* o : rendered time signal Q11*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); void ivas_spar_dec_upmixer_sf_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ Word32 *output_fx[], /* o : output audio channels */ const Word16 nchan_internal /* i : number of internal channels */ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); ivas_error ivas_spar_md_enc_open_fx( @@ -5967,9 +5941,7 @@ ivas_error pre_proc_front_ivas_fx( const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index c9ad84097..ee11f2b02 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -152,10 +152,8 @@ ivas_error ivas_qmetadata_allocate_memory_fx( { set32_fx( hQMetaData->q_direction[dir].band_data[j].elevation_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); set32_fx( hQMetaData->q_direction[dir].band_data[j].azimuth_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); -#ifdef MSAN_FIX set32_fx( hQMetaData->q_direction[dir].band_data[j].q_elevation_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); set32_fx( hQMetaData->q_direction[dir].band_data[j].q_azimuth_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); -#endif set32_fx( hQMetaData->q_direction[dir].band_data[j].energy_ratio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); } } @@ -315,14 +313,8 @@ ivas_error only_reduce_bits_direction_fx( Word16 *bits_dir0; Word16 bits_sph_idx_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef FIX_QMETADATA_PENALTY Word32 penalty[MASA_MAXIMUM_CODING_SUBBANDS]; Word16 tmp; -#else - Word16 penalty[MASA_MAXIMUM_CODING_SUBBANDS]; - Word16 shift, tmp, tmp_e, flag; - Word32 tmp_32; -#endif FOR( j = 0; j < coding_subbands; j++ ) { FOR( k = 0; k < no_subframes; k++ ) @@ -407,7 +399,6 @@ ivas_error only_reduce_bits_direction_fx( } ELSE { -#ifdef FIX_QMETADATA_PENALTY Word16 m, sorted, index1, index2; @@ -457,65 +448,6 @@ ivas_error only_reduce_bits_direction_fx( } -#else - FOR( j = 0; j < coding_subbands; j++ ) - { - penalty[j] = 0; - move16(); - tmp_32 = 0; - move32(); - shift = find_guarded_bits_fx( no_subframes ); - - flag = 1; - move16(); - // This change was done due to loss of precision from BASOP_Util_Divide3232_Scale which was leading to penalty getting calculated wrongly - // and hence ind_order being sorted incorrectly which might cause infinite loop. - FOR( k = 0; k < no_subframes - 1; k++ ) - { - IF( NE_16( bits_sph_idx_orig[j][k], bits_sph_idx_orig[j][k + 1] ) ) - { - flag = 0; - move16(); - } - } - - IF( flag ) - { - tmp = 0; - move16(); - FOR( k = 0; k < no_subframes; k++ ) - { - IF( bits_sph_idx_orig[j][k] > 0 ) - { - tmp = add( tmp, sub( bits_sph_idx_orig[j][k], q_direction->band_data[j].bits_sph_idx[k] ) ); - } - } - - tmp = BASOP_Util_Divide1616_Scale( tmp, bits_sph_idx_orig[j][0], &tmp_e ); - - tmp_32 = L_shl( tmp, tmp_e ); /* Q15 */ - - penalty[j] = extract_l( L_shr( tmp_32, shift ) ); /* Q15 - shift */ - move16(); - // Division by no_subframes for penalty[j] not required - } - ELSE - { - FOR( k = 0; k < no_subframes; k++ ) - { - IF( bits_sph_idx_orig[j][k] > 0 ) - { - tmp = BASOP_Util_Divide3232_Scale( extract_l( L_sub( bits_sph_idx_orig[j][k], q_direction->band_data[j].bits_sph_idx[k] ) ), bits_sph_idx_orig[j][k], &tmp_e ); - tmp_32 = L_add( tmp_32, L_shl( tmp, tmp_e ) ); - } - } - penalty[j] = extract_l( L_shr( tmp_32, shift ) ); /* Q15 - shift */ - move16(); - // Division by no_subframes for penalty[j] not required - } - } - sort_desc_ind_16_fx( penalty, coding_subbands, ind_order ); -#endif } *reduce_bits_out = negate( reduce_bits ); diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 929eaa2c5..9f6d8b422 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -2631,11 +2631,7 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( test(); IF( W_norm( re ) == 0 || W_norm( recon_uu_re[i][j] ) == 0 ) { -#ifdef FIX_ISSUE_1122 recon_uu_re[i][j] = L_shr( recon_uu_re[i][j], 1 ); // q_recon_uu_re[i][j] - 1 -#else - re1[m] = L_shr( re1[m], 1 ); // q_recon_uu_re[i][j]-1 -#endif move32(); q_recon_uu_re[i][j] = sub( q_recon_uu_re[i][j], 1 ); move16(); @@ -3834,11 +3830,7 @@ void ivas_compute_spar_params_fx( } ELSE { -#ifdef FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr_r( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22 -#else - hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22 -#endif move32(); } } @@ -3865,7 +3857,6 @@ void ivas_compute_spar_params_fx( Word16 q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx; IF( NE_16( ndm, 1 ) ) { -#ifdef MSAN_FIX FOR( i = 0; i < ( num_ch - ndm ); i++ ) { FOR( j = 0; j < sub( ndm, 1 ); j++ ) @@ -3874,15 +3865,6 @@ void ivas_compute_spar_params_fx( move32(); } } -#else - for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) - { - for ( j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) - { - hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j], sub( q_tmp, 22 ) ); - } - } -#endif hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx = Q22; move16(); } diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index 04d6f7bf5..ca8dec276 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -306,12 +306,6 @@ void v_add_inc_fx( const Word16 N /* i : Vector length Q0*/ ) { -#ifndef FIX_1107_VADDINC - Word16 i; - Word16 ix1 = 0; - Word16 ix2 = 0; - Word16 iy = 0; -#else Word16 i, ix1, ix2, iy; /* The use of this function is currently always for the interleaved input format, */ @@ -334,7 +328,6 @@ void v_add_inc_fx( ix1 = 0; ix2 = 0; iy = 0; -#endif move16(); move16(); move16(); @@ -604,44 +597,6 @@ void v_sub32_fx( * Therefore, S=A*A' where A is upper triangular matrix of size (m*m+m)/2 (zeros ommitted, column-wise) *---------------------------------------------------------------------*/ -#ifndef DOT_PROD_CHOLESKY_64BIT -/*! r: the dot product x'*A*A'*x */ -Word32 dot_product_cholesky_fixed( - const Word32 *x, /* i : vector x Q31 - exp_x*/ - const Word32 *A, /* i : Cholesky matrix A Q31 - exp_A*/ - const Word16 N, /* i : vector & matrix size Q0*/ - const Word16 exp_x, - const Word16 exp_A, - Word16 *exp_sum ) -{ - Word16 i, j; - Word32 suma, tmp_sum, mul; - const Word32 *pt_x, *pt_A; - Word16 mul_exp, tmp_sum_exp; - mul_exp = add( exp_x, exp_A ); - pt_A = A; - suma = 0; - move32(); - FOR( i = 0; i < N; i++ ) - { - tmp_sum = 0; - move32(); - tmp_sum_exp = 0; - move16(); - pt_x = x; - - FOR( j = 0; j <= i; j++ ) - { - mul = Mpy_32_32( *pt_x++, *pt_A++ ); /*Q31 - (exp_x + exp_A)*/ - tmp_sum = BASOP_Util_Add_Mant32Exp( tmp_sum, tmp_sum_exp, mul, mul_exp, &tmp_sum_exp ); // exp_x+exp_A - } - - suma = BASOP_Util_Add_Mant32Exp( suma, *exp_sum, Mpy_32_32( tmp_sum, tmp_sum ), shl( tmp_sum_exp, 1 ), exp_sum ); /*Q31 - exp_sum*/ - } - - return suma; -} -#else /*! r: the dot product x'*A*A'*x */ Word64 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x Q31 - exp_x*/ @@ -677,7 +632,6 @@ Word64 dot_product_cholesky_fixed( return suma; } -#endif void v_mult_mat_fixed( Word32 *y, /* o : the product x*A Qx - guardbits*/ @@ -978,9 +932,6 @@ Word16 matrix_product_mant_exp_fx( Word16 out_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word16 *Zp_fx_e = out_e; Word16 row, col; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ Word64 temp; Word16 temp_e; Word16 prod_e = add( X_fx_e, Y_fx_e ); @@ -1007,13 +958,7 @@ Word16 matrix_product_mant_exp_fx( FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = k + i * rowsX; - y_idx = k + j * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1051,13 +996,7 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = i + k * rowsX; - y_idx = j + k * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1095,13 +1034,7 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = k + i * rowsX; - y_idx = j + k * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1140,13 +1073,7 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = i + k * rowsX; - y_idx = k + j * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1204,9 +1131,6 @@ Word16 matrix_product_fx( ) { Word16 i, j, k; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; /* Processing */ @@ -1227,13 +1151,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1254,13 +1172,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1281,13 +1193,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -1310,13 +1216,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ // TODO: overflow of Z_fx to be checked move32(); } @@ -1341,9 +1241,6 @@ Word16 matrix_product_q30_fx( ) { Word16 i, j, k; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; Word64 W_tmp; @@ -1366,14 +1263,7 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 -#else /* OPT_BASOP_ADD_v1 */ - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 -#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1397,14 +1287,7 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 -#else /* OPT_BASOP_ADD_v1 */ - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 -#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1428,11 +1311,6 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifndef OPT_BASOP_ADD_v1 - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ -#endif /* OPT_BASOP_ADD_v1 */ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 } @@ -1459,14 +1337,7 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 -#else /* OPT_BASOP_ADD_v1 */ - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 -#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1499,9 +1370,6 @@ Word16 matrix_product_mant_exp( Word16 *Zp_e = Z_e; Word32 L_tmp; Word16 tmp_e; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1523,16 +1391,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[k + i * rowsX], Y_e[k + j * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - //( *Zp ) += X[k + i * rowsX] * Y[k + j * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1560,16 +1420,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[i + k * rowsX], Y_e[j + k * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[j + k * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); ( *Zp_e ) = tmp_e; @@ -1596,16 +1448,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[k + i * rowsX], Y_e[j + k * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - //( *Zp ) += X_fx[k + i * rowsX] * Y_fx[j + k * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1635,16 +1479,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[i + k * rowsX], Y_e[k + j * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[k + j * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1675,9 +1511,6 @@ Word16 matrix_diag_product_fx( { Word16 i, j; Word32 *Zp = Z; -#ifndef OPT_BASOP_ADD_v1 - Word16 tmp; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1690,12 +1523,7 @@ Word16 matrix_diag_product_fx( { FOR( i = 0; i < colsX; ++i ) { -#ifdef OPT_BASOP_ADD_v1 *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - tmp = add( j, imult1616( i, rowsX ) ); - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1726,7 +1554,6 @@ Word16 matrix_diag_product_fx( return EXIT_SUCCESS; } -#ifdef OPT_BASOP_ADD_v1 Word16 matrix_diag_product_fx_2( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ const Word16 X_e, @@ -1818,7 +1645,6 @@ Word16 matrix_diag_product_fx_2( return EXIT_SUCCESS; } -#endif /* OPT_BASOP_ADD_v1 */ Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ @@ -1835,9 +1661,6 @@ Word16 matrix_diag_product_fx_1( Word16 i, j; Word32 *Zp = Z; Word16 *Z_ep = Z_e; -#ifndef OPT_BASOP_ADD_v1 - Word16 tmp; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1850,19 +1673,10 @@ Word16 matrix_diag_product_fx_1( { FOR( i = 0; i < colsX; ++i ) { -#ifdef OPT_BASOP_ADD_v1 *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - tmp = add( j, imult1616( i, rowsX ) ); /*Q0*/ - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; -#ifdef OPT_BASOP_ADD_v1 *( Z_ep ) = add( X_e[j + i * rowsX], Y_e[j] ); -#else /* OPT_BASOP_ADD_v1 */ - *( Z_ep ) = add( X_e[tmp], Y_e[j] ); -#endif /* OPT_BASOP_ADD_v1 */ move16(); Z_ep++; } @@ -1908,9 +1722,6 @@ Word16 diag_matrix_product_fx( { Word16 i, j; Word32 *Zp = Z; -#ifndef OPT_BASOP_ADD_v1 - Word16 tmp; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1923,12 +1734,7 @@ Word16 diag_matrix_product_fx( { FOR( j = 0; j < entriesY; ++j ) { -#ifdef OPT_BASOP_ADD_v1 *( Zp ) = Mpy_32_32( X[i + j * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - tmp = add( i, imult1616( j, rowsX ) ); /*Q0*/ - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1974,9 +1780,6 @@ Word16 matrix_product_diag_fx( { Word16 j, k; Word32 *Zp = Z; -#ifndef OPT_BASOP_ADD_v1 - Word16 y_idx, x_idx; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1995,13 +1798,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -2019,13 +1816,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -2045,13 +1836,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -2071,13 +1856,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; diff --git a/lib_com/lerp.c b/lib_com/lerp.c index 4e306b936..6f148057f 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -356,10 +356,6 @@ void L_lerp_fx( Word32 *f /*q*/, Word32 *f_out /*q*/, Word16 bufferNewSize /*Q0* f[ind] = L_shr( f[ind], guard_bits ); /*Q(guard_bits)*/ move32(); } -#ifndef MSAN_FIX - FOR( Word16 ind = 0; ind < bufferNewSize; ind++ ) - f_out[ind] = L_shr( f_out[ind], guard_bits ); -#endif } IF( GT_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) ) diff --git a/lib_com/low_rate_band_att_fx.c b/lib_com/low_rate_band_att_fx.c index 9958b9d5f..e51d2807b 100644 --- a/lib_com/low_rate_band_att_fx.c +++ b/lib_com/low_rate_band_att_fx.c @@ -75,15 +75,11 @@ void ivas_fine_gain_pred_fx( L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */ exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) ); L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */ -#ifndef FIX_ISSUE_987 - Mpy_32_16_ss( L_tmp, ivas_fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ -#else Word16 norm = norm_s( bw ); Word16 tmp1, tmp_exp = sub( 15, norm ); tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp ); tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) ); Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ -#endif gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */ test(); diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 08e74b9b7..54f0ae3ed 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -604,7 +604,6 @@ Word16 lpc2lsp_fx( return ( 1 ); } -#ifdef FIX_ISSUE_1165 /*===================================================================*/ /* FUNCTION : lpc2lsp_ivas_fx () */ /*-------------------------------------------------------------------*/ @@ -749,7 +748,6 @@ Word16 lpc2lsp_ivas_fx( return ( 1 ); } -#endif /*===================================================================*/ /* FUNCTION : lsp2lpc_fx () */ diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index 10e560433..cf2ad8a8a 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -461,12 +461,10 @@ static Word16 decode_indexes_ivas_fx( IF( index[i] < 0 ) { set16_fx( x_lvq, 0, 2 * LATTICE_DIM ); -#ifdef MSAN_FIX scales_mslvq[0] = 0; move16(); scales_mslvq[1] = 0; move16(); -#endif index[i] = 0; return 1; } @@ -491,10 +489,8 @@ static Word16 decode_indexes_ivas_fx( FOR( i = 0; i < LATTICE_DIM; i++ ) { x_lvq[i] = 0; -#ifdef MSAN_FIX scales_mslvq[0] = 0; move16(); -#endif } } ELSE @@ -503,12 +499,10 @@ static Word16 decode_indexes_ivas_fx( { /* safety check in case of bit errors */ set16_fx( x_lvq, 0, 2 * LATTICE_DIM ); -#ifdef MSAN_FIX scales_mslvq[0] = 0; move16(); scales_mslvq[1] = 0; move16(); -#endif return 1; } @@ -549,10 +543,8 @@ static Word16 decode_indexes_ivas_fx( x_lvq[i] = 0; move16(); } -#ifdef MSAN_FIX scales_mslvq[1] = 0; move16(); -#endif } ELSE { diff --git a/lib_com/options.h b/lib_com/options.h index ab7efb8fd..76bfee2ae 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -67,116 +67,6 @@ #define BASOP_NOGLOB_DECLARE_LOCAL #endif -#define IVAS_FLOAT_FIXED_CONVERSIONS /* Temporary macro to keep track of intermediate flt to fixed and fixed to flt conversions */ -#define MSAN_FIX -#define FIX_TMP_714 -#define BASOP_NOGLOB_TMP_715 -#define EVS_FUNC_MODIFIED -#define REMOVE_IVAS_UNUSED_PARAMETERS_WARNING /*temporary operation on unused EVS parameters to remove warnings, these parameters will be used in IVAS */ -#define MOD_BIT_ALLOC_ROM_TABLE /* Just to highlight modification in bit allocation table and to ensure these modifications doesn't affect EVS modes*/ -#define SIMPLIFY_CODE_BE // Simplify synthesis loop -#define CR_2109_to_2112_cd0_ce0 /* This is related to the CRs include in the 26.444 package of 21-12. Concerns lead_deindexing and */ -#define FIX_QMETADATA_PENALTY /* Nokia: transform penalty calculation in qmetadata into integer operations */ -#define FIX_1013_CRASH_HQ_CORE_DEC /* Ittiam: Saturation added on the lines of EVS */ -#define NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS /* DLB: adjust prerendering and mixing gain in OSBA encoder. This is fix to float codes*/ -#define NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO /* Eri: issue 1233: Address possible division by zero in hf_spectrum_sparseness() */ -#define FIX_ISSUE_1062_AND_1068_TON_ENE_EST_FX -#define FIX_ISSUE_987 -#define FIX_1054_IF_ELSE_CMPLX /* VA: Fix 1054 incorrect counting of complexity when ELSE-IF sequence is encoutered in two functions */ -#define FIX_1052_COPY_CMPLX_DISCREPANCY /* VA: modify IF-ELSE statements used in Copy*() functions to avoid dependency on x[] and y[] in RAM */ -#define FIX_1049_SHR_RO_COMPLEXITY /* VA: fix for issue 1049: incorrect counting of complexity in the shr_ro() function */ -#define NONBE_IMPROVE_DIRAC_INTENSITY_PREC -#define FIX_1103_OPT_L_NORM_ARR /* FhG: Optimize L_norm_arr(), avoid IF */ -#define FIX_1105_OPT_MINIMUM_SL /* FhG: Optimize minimum_s(), minimum_l(), avoid IF */ -#define FIX_1104_OPT_GETMINSCALEFAC /* FhG: Optimize get_min_scalefactor(), avoid IF */ -#define FIX_1106_SIMPLIFY_SET32FX /* FhG: simplify set32_fx() */ -#define FIX_1107_VADDINC /* FhG: Optimize v_add_inc_fx() for most frequent case */ -#define FIX_1009_OPT_PARAMMC_RENDER /* FhG: Optimize ivas_param_mc_dec_render_fx() */ -#define FIX_1109_OPTIM_MCT_STEREO_IGF_DEC /* FhG: optimize mctStereoIGF_dec_fx() */ -#define FIX_1110_OPTIM_DIRAC_DECORR_PROC /* FhG: optimize ivas_dirac_dec_decorr_process() */ -#define FIX_1127_IMPROVE_SBA_MLD /* Ittiam: Avoid saturation for DiRAC reference power */ -#define FIX_1100_REMOVE_LPC_RESCALING /* VA: Remove the rescaling of LPC coefficient to Q12 as residu and syn-filt are already taking care of it*/ -#define FIX_1133_IMPROVE_MC_MLD /* Ittiam: Correcting wrong updation of exponents in ivas_mc_paramupmix_param_est_enc_fx() */ -#define FIX_ISSUE_1122 /* Ittiam: Fix issue 1122: corrected incorrect scaling of a buffer leading to incorrect metadata bits */ -#define FIX_ISSUE_1125 /* Ittiam: Fix issue 1125: interfering talker flag not triggered on short test vector */ -#define FIX_1132_STACK_CORRUPTION /* Stack corruption issue due of extending index access*/ -#define FIX_ISSUE_1092 /* Ittiam: Fix for Issue 1092: BASOP asserts in stereo fx encoder for selection test inputs*/ -#define FIX_ISSUE_1135 /* Ittiam: Fix for Issue 1135: downmixing difference between float and fixed-point (DFT - stereo) */ -#define FIX_ISSUE_1148 -#define FIX_ISSUE_1147 /* Ittiam: Fix for issue 1147: Added saturation in DetectTnsFilt_fx.*/ -#define FIX_ISSUE_1150 /* Ittiam: Fix for Issue 1150: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from tcx_ltp_find_gain function*/ -#define FIX_ISSUE_1151 /* Ittiam: Fix for Issue 1151: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from sp_mus_classif_gmm_fx function*/ -#define FIX_ISSUE_1153 /* Ittiam: Fix for Issue 1153: Assertion error observed in stereo_dmx_evs_enc_fx from calc_poc_fx function*/ -#define FIX_ISSUE_1154 /* Ittiam: Fix for Issue 1154: Encoder crash for ParamMC 7.1 at 96kbps in ivas_param_mc_param_est_enc_fx() */ -#define FIX_ISSUE_1157 /* Ittiam: Fix for Issue 1157: Encoder crash for Stereo at 48/64kbps DTX on/off in kernel_switch_trafo_fx() */ -#define FIX_ISSUE_1152 /* Ittiam: Fix for issue 1152: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from find_tilt_fx function*/ -#define FIX_ISSUE_1156 /* Ittiam: Fix for Issue 1156: Encoder crash for Stereo at 32kbps in SWB_BWE_encoding_ivas_fx() */ -#define FIX_DISCLAIMER /* VA: Add disclaimer for external renderer + Add info about IVAS reference version (FLP issue 1225) */ -#define FIX_ISSUE_1167 /* Ittiam: Fix for Issue 1167: Encoder crash for OSBA ISM3SBA1 at 13.2 and 16.4 kbps in gauss_L2_ivas_fx() */ -#define FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC /* FhG: Reduce workload of binaural rendering: replace 1./tmp & sqrt by Isqrt32 */ -#define FIX_1113_OPT_DIRAC_BIN_REND /* FhG: Various optimizations to ivas_dirac_dec_binaual_functions.c */ -#define FIX_ISSUE_1187 /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/ -#define FIX_ISSUE_1186 /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */ -#define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */ -#define FIX_ISSUE_1185 /* Ittiam: Fix for issue 1185: Assertion in ivas_dirac_dec_binaural_internal_fx() for crash in decoder in fft30_with_cmplx_data()*/ -#define FIX_ISSUE_1209 /* Ittiam: Fix for issue 1209: Assertion exit in BASOP encoder (stereo_dmx_evs)*/ -#define FIX_ISSUE_1218 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ -#define FIX_ISSUE_1290 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ -#define IVAS_ISSUE_1188_EVS_CRASH /* Ittiam: Fix for issue 1188: Issue due to ASAN */ -#define FIX_ISSUE_1155 /* Ittiam: Fix for issue 1155: Encoder crash for Stereo at 32kbps in PostShortTerm_ivas_enc_fx()*/ -#define FIX_1010_OPT_DIV /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_SINGLE_RESCALE /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_GIVENS /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_GIVENS_INV /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_NORM_NOSAT /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_SEC_SINGLE_RESCALE /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1072_SPEEDUP_matrixTransp2Mul_fx /* FhG: complexity optimization (non-be) */ -#define FIX_1072_REDUCE_DIVS /* FhG: complexity optimization (non-be) */ -#define FIX_ISSUE_1230 /* Ittiam: Fix for issue 1230: Basop Enc audible differences and distortion @16kbps */ -#define NONBE_1211_DTX_BR_SWITCHING /* VA: port float issue 1211: fix crash in MASA DTX bitrate switching */ -#define FIX_1189_GSC_IVAS_OMASA /* VA: Fix for issue 1189: Bitstream desynchornization due to reading/writing of the GSC_IVAS_mode parameter */ -#define NONBE_1273_ISM_METADATA_COUNTER /* VA: BASOP issue 1265, FLP issue 1273: fix counter overflow in ISM metadata encoder */ -#define NONBE_FIX_GSC_BSTR /* VA: issue 1264 FLP (1189 BASOP): Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA */ -#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF /* FhG: fix for issue 1101: complexity of spar dec upmixer */ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ -#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS /* FhG: Defines 1.0f-weight variables, uses Madd operation instead of L_add_sat */ -#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS /* FhG: Splits single loop with IF-statements into two low-complex loops */ -#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_HQ_CONSTANTS /* FhG: IMPROVE PRECISION: Uses 1/6 and 1/20 in full-precise Q31 constants instead of Q15 */ -#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL /* FhG: Uses unique shift amount in each loop iteration */ -#define FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS /* FhG ivas_spar_com.c: Zeroes very small negative coeffs via L_shr_r (was L_shr) */ -#define FIX_ISSUE_1237 /* VA: replacement of Copy_Scale_sig_16_32_DEPREC() that are doing 16 bits left shift by Copy_Scale_sig_16_32_no_sat() */ -#define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ -#define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ -#define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ -#define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ -#define FIX_ISSUE_1291 /* Ittiam: Wrong use of imult1616() in ACELP rescaling */ -#define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ -#define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ -#define FIX_USAN_ISSUES /* Ittiam: Fix issues reported by USAN */ -#define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ -#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ -#define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ -#define FIX_ISSUE_1247 -#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ -#define FIX_1285_DECODER_CRASH -#define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ -#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* FhG: Minor WMOPS tuning, nonbe */ -#define FIX_1320_LOWRATE_ACELP -#define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ -#define FIX_1298 /* VA: fix possible assert in gaus_enc */ -#define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ -#define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ -#define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ -#define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ -#define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ -#define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ -#define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ -#define NONBE_FIX_1402_WAVEADJUST /* VA: BASOP iisue 1402: fix waveform adjustment decoder PLC */ -#define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ -#define OPT_SBA_AVOID_SPAR_RESCALE /* Optimization made to spar decoder and IGF */ -#define NONBE_FIX_1386_STEREO_DMX_EVS_PHA /* Orange: Fix for stereo DMX / PHA mode : Change the filter taps resolution (Q31->Q30), improve precision for the IR window, for the ILD & IPD smoothing in sub-bands, for the ISD counters and for ICCr. */ -#define FIX_1326_SUBSTITUTE_CMPMANT32EXP /* FhG: Minor WMOPS tuning*/ -#define FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT /* FhG: WMOPS tuning */ -#define FIX_1326_SPEEDUP_eig2x2_fx /* FhG: Minor WMOPS tuning*/ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 70b70859c..71c1590c2 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -881,13 +881,11 @@ Word16 lpc2lsp_fx( Word16 *old_freq, Word16 order ); -#ifdef FIX_ISSUE_1165 Word16 lpc2lsp_ivas_fx( Word32 *a, Word16 *freq, Word16 *old_freq, Word16 order ); -#endif void lsp2lpc_fx( Word16 *a, @@ -4864,9 +4862,7 @@ ivas_error config_acelp1( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signalling_bits, /* i : number of signalling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -5854,13 +5850,8 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 L_frame, /* i : Frame lenght */ -#ifndef NONBE_FIX_GSC_BSTR - const Word32 core_brate, /* i : Core bit rate */ -#endif const Word16 Q_exc, /* i : input and output format of exc2 */ const Word16 bfi, /* i : frame lost indicator */ const Word16 last_core, /* i : Last core used */ @@ -9753,9 +9744,7 @@ void cldfbSynthesis_ivas_fx( Word32 **imagBuffer_fx, /* i : imag values Qx*/ Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ const Word16 samplesToProcess, /* i : number of processed samples */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE const Word16 shift, /* i : scale for state buffer */ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); @@ -10995,9 +10984,7 @@ ivas_error config_acelp1_IVAS( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signaling_bits, /* i : number of signaling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -11064,9 +11051,7 @@ void calculate_hangover_attenuation_gain_ivas_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ -#ifdef FIX_920_IGF_INIT_ERROR const Word32 igf_brate, /* i : IGF configuration bitrate */ -#endif const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index e6f392ff0..551a84feb 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -16790,7 +16790,6 @@ const Word16 GSC_freq_bits[] = 26, 96, 0, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_22k60*/ 26, 96, 0, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4 /* ACELP_24k40*/ }; // Q0 -#ifdef MOD_BIT_ALLOC_ROM_TABLE const Word32 GSC_freq_bits_fx[] =/*Q18*/ { 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_5k00*/ @@ -16823,17 +16822,6 @@ const Word32 GSC_freq_bits_fx_Q18[] =/*Q18*/ 6815744, 25165824, 0, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, 6815744, 25165824, 0, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, }; -#else -const Word32 GSC_freq_bits_fx[] = -{ - 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_7k20*/ - 5505024, 19660800, -1048576, 6815744, 4194304, 3145728, 2883584, 2359296, 0, 0, 1048576, 1048576, 262144, 262144, 786432, 0, 0, /* ACELP_8k00*/ - 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_11k60*/ - 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k15*/ - 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k85*/ - 8126464, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_13k20*/ -}; -#endif const Word16 Compl_GSC_freq_bits[] = { 5, 10, 10, 10 /* bitrate > ACELP_16k40 && FS = 16kHz */ diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index eda099cd9..228d43247 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -2533,11 +2533,7 @@ void hq_generic_decoding_fx( IF( L_tmp != 0 ) { exp = norm_l( L_tmp ); -#ifdef EVS_FUNC_MODIFIED frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#else - frac = round_fx( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#endif tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ @@ -2868,11 +2864,7 @@ void hq_generic_decoding_fx( tmp4_fx = mult_r( tmp3_fx, 1638 /* 0.05 in Q15 */ ); WHILE( tmp3_fx > 1024 /* 1 in Q10*/ ) { -#ifdef EVS_FUNC_MODIFIED L_tmp1 = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ -#else - L_tmp1 = Mult_32_16( L_shl( *pit1_fx, 5 ), tmp3_fx ); /*15 + 5 + 10 -15 */ -#endif *pit1_fx-- = L_tmp1; move32(); tmp3_fx = sub( tmp3_fx, tmp4_fx ); @@ -3089,11 +3081,7 @@ void hq_generic_decoding_ivas_fx( IF( L_tmp != 0 ) { exp = norm_l( L_tmp ); -#ifdef EVS_FUNC_MODIFIED frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#else - frac = round_fx( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#endif tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ @@ -3424,11 +3412,7 @@ void hq_generic_decoding_ivas_fx( tmp4_fx = mult_r( tmp3_fx, 1638 /* 0.05 in Q15 */ ); WHILE( tmp3_fx > 1024 /* 1 in Q10*/ ) { -#ifdef EVS_FUNC_MODIFIED L_tmp1 = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ -#else - L_tmp1 = Mult_32_16( L_shl( *pit1_fx, 5 ), tmp3_fx ); /*15 + 5 + 10 -15 */ -#endif *pit1_fx-- = L_tmp1; move32(); tmp3_fx = sub( tmp3_fx, tmp4_fx ); diff --git a/lib_com/swb_bwe_com_lr_fx.c b/lib_com/swb_bwe_com_lr_fx.c index d0b8d0100..8fd876f1c 100644 --- a/lib_com/swb_bwe_com_lr_fx.c +++ b/lib_com/swb_bwe_com_lr_fx.c @@ -2366,11 +2366,7 @@ void ton_ene_est_fx( exp_normn = norm_s( peak_fx[k] ); fac_fx = div_s( shl( temp2_fx, exp_normd ), shl( peak_fx[k], exp_normn ) ); -#ifdef FIX_ISSUE_1062_AND_1068_TON_ENE_EST_FX fac_fx = shl_sat( fac_fx, sub( add( Qss, exp_normn ), add( Qtemp2, exp_normd ) ) ); /* Qtemp2+exp_normd-(Qss+exp_normn)+15 -> 15*/ -#else - fac_fx = shl( fac_fx, sub( add( Qss, exp_normn ), add( Qtemp2, exp_normd ) ) ); /* Qtemp2+exp_normd-(Qss+exp_normn)+15 -> 15*/ -#endif } ni_gain_fx[k] = mult_r( avg_pe_fx[k], fac_fx ); /* Qavg_pe[k] */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 04b6ba187..2a2841966 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -1036,11 +1036,7 @@ static void filt_mu_fx( FOR( n = 0; n < SubFrameLength; n++ ) { temp = mult_r( mu, ( *ptrs++ ) ); -#ifdef FIX_ISSUE_1155 temp = add_sat( temp, *ptrs ); /*Q12 */ -#else - temp = add( temp, *ptrs ); /*Q12 */ -#endif sig_out[n] = shl_o( mult_r( ga, temp ), 1, &Overflow ); move16(); /*Q12 */ } @@ -5087,7 +5083,6 @@ void GenSHBSynth_fx32( Word32 speech_buf_32k[L_FRAME32k]; Word16 i; -#ifdef FIX_881_HILBERT_FILTER Word16 shift = 0; Word32 maxm32, input_synspeech_temp[L_FRAME16k]; move16(); @@ -5123,9 +5118,6 @@ void GenSHBSynth_fx32( } Interpolate_allpass_steep_fx32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); -#else - Interpolate_allpass_steep_fx32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); -#endif IF( EQ_16( L_frame, L_FRAME ) ) { @@ -5148,14 +5140,12 @@ void GenSHBSynth_fx32( } } -#ifdef FIX_881_HILBERT_FILTER IF( maxm32 != 0 ) { Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); } -#endif return; } diff --git a/lib_com/tcq_position_arith_fx.c b/lib_com/tcq_position_arith_fx.c index 0466dc133..3abd527ca 100644 --- a/lib_com/tcq_position_arith_fx.c +++ b/lib_com/tcq_position_arith_fx.c @@ -1983,11 +1983,7 @@ Word32 encode_magnitude_tcq_fx( move16(); bits_fx = L_deposit_l( 0 ); -#ifdef IVAS_ISSUE_1188_EVS_CRASH tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - ( nzpos - 1 )] ) ); -#else - tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos - 1] ) ); -#endif *est_frame_bits_fx = L_add( *est_frame_bits_fx, tcq_bits_fx ); move32(); @@ -2470,11 +2466,7 @@ void decode_mangitude_tcq_fx( move16(); bits_fx = L_deposit_l( 0 ); -#ifdef IVAS_ISSUE_1188_EVS_CRASH tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - ( nzpos - 1 )] ) ); -#else - tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos - 1] ) ); -#endif IF( EQ_16( nzpos, npulses ) ) { diff --git a/lib_com/tcx_mdct_fx.c b/lib_com/tcx_mdct_fx.c index 1fc57871d..b2cee32e6 100644 --- a/lib_com/tcx_mdct_fx.c +++ b/lib_com/tcx_mdct_fx.c @@ -106,9 +106,7 @@ void TCX_MDCT( Word16 i; Word16 factor, neg_factor; Word16 factor_e; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -164,9 +162,7 @@ void TCX_MDST( Word16 i; Word16 factor, neg_factor; Word16 factor_e; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -226,9 +222,7 @@ void TCX_MDCT_Inverse( Word16 L2 = l, R2 = r; Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2]; Word16 fac_e; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif L2 = shr( l, 1 ); R2 = shr( r, 1 ); diff --git a/lib_com/tools.c b/lib_com/tools.c index e4ccd9955..b1a9f4d13 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -628,45 +628,23 @@ Word16 minimum_s( Word16 *min_val /* o : minimum value in the input vector */ ) { -#ifdef FIX_1105_OPT_MINIMUM_SL Word16 i, ind; -#else - Word16 i, ind, tmp; -#endif ind = 0; move16(); -#ifndef FIX_1105_OPT_MINIMUM_SL - tmp = vec[0]; - move16(); -#endif FOR( i = 1; i < lvec; i++ ) { -#ifdef FIX_1105_OPT_MINIMUM_SL if ( LT_16( vec[i], vec[ind] ) ) { ind = i; move16(); } -#else - IF( LT_16( vec[i], tmp ) ) - { - ind = i; - move16(); - tmp = vec[i]; - move16(); - } -#endif } if ( min_val != NULL ) { -#ifdef FIX_1105_OPT_MINIMUM_SL *min_val = vec[ind]; -#else - *min_val = tmp; -#endif move16(); } @@ -687,45 +665,22 @@ Word16 minimum_l( ) { Word16 i, ind; -#ifndef FIX_1105_OPT_MINIMUM_SL - Word32 tmp; -#endif ind = 0; -#ifndef FIX_1105_OPT_MINIMUM_SL - tmp = vec[0]; -#endif move16(); -#ifndef FIX_1105_OPT_MINIMUM_SL - move32(); -#endif FOR( i = 1; i < lvec; i++ ) { -#ifdef FIX_1105_OPT_MINIMUM_SL if ( LT_32( vec[i], vec[ind] ) ) { ind = i; move16(); } -#else - IF( LT_32( vec[i], tmp ) ) - { - ind = i; - tmp = vec[i]; - move16(); - move32(); - } -#endif } if ( min_val != NULL ) { -#ifdef FIX_1105_OPT_MINIMUM_SL *min_val = vec[ind]; -#else - *min_val = tmp; -#endif move32(); } diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index fad2d64a8..d403c583d 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -483,16 +483,10 @@ void Copy( move16(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */ return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i] = x[i]; @@ -500,9 +494,6 @@ void Copy( } return; -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } /*-------------------------------------------------------------------* * Copy64: @@ -524,16 +515,10 @@ void Copy64( move64(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */ return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i] = x[i]; @@ -541,9 +526,6 @@ void Copy64( } return; -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } void set64_fx( @@ -580,16 +562,10 @@ void Copy_pword( move16(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */ return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i].v.im = x[i].v.im; @@ -599,9 +575,6 @@ void Copy_pword( } return; -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } /*-------------------------------------------------------------------* * Copy32: @@ -623,23 +596,14 @@ void Copy32( move32(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i] = x[i]; move32(); } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } void set8_fx( @@ -688,7 +652,6 @@ void set32_fx( const Word16 N /* i : Lenght of the vector */ ) { -#ifdef FIX_1106_SIMPLIFY_SET32FX Word16 i; FOR( i = 0; i < N; i++ ) @@ -696,26 +659,6 @@ void set32_fx( y[i] = a; move32(); } -#else - Word16 i, tmp; - tmp = extract_l( a ); - IF( EQ_32( L_deposit_l( tmp ), a ) ) - { - FOR( i = 0; i < N; i++ ) - { - y[i] = L_deposit_l( tmp ); - move32(); - } - } - ELSE - { - FOR( i = 0; i < N; i++ ) - { - y[i] = a; - move32(); - } - } -#endif return; } @@ -801,7 +744,6 @@ void Copy_Scale_sig_16_32_DEPREC( } return; } -#ifdef FIX_ISSUE_1237 #ifdef DEBUGGING if ( exp0 >= 16 ) { @@ -809,7 +751,6 @@ void Copy_Scale_sig_16_32_DEPREC( } #else assert( exp0 < 16 ); -#endif #endif tmp = shl_o( 1, exp0, &Overflow ); FOR( i = 0; i < lg; i++ ) diff --git a/lib_com/trans_direct_fx.c b/lib_com/trans_direct_fx.c index d4792fb75..6a3cdf108 100644 --- a/lib_com/trans_direct_fx.c +++ b/lib_com/trans_direct_fx.c @@ -40,9 +40,7 @@ void direct_transform_fx( Word16 shift, Qmin = 31; Word32 L_tmp; Word16 Qs[NUM_TIME_SWITCHING_BLOCKS]; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( element_mode ); -#endif move16(); segment_length = shr( L, 1 ); diff --git a/lib_com/trans_inv_fx.c b/lib_com/trans_inv_fx.c index 0033e2c9e..0683e266c 100644 --- a/lib_com/trans_inv_fx.c +++ b/lib_com/trans_inv_fx.c @@ -515,11 +515,7 @@ void preecho_sb_fx( tmp_fx1 = norm_l( es_mdct_hb_fx[i] ); tmp_fxL1 = L_shl( es_mdct_hb_fx[i], tmp_fx1 ); tmp_fxL2 = L_shl( mean_prev_hb_fx_loc, tmp_fx1 ); -#ifdef FIX_1013_CRASH_HQ_CORE_DEC tmp_fx1 = round_fx_sat( tmp_fxL1 ); -#else - tmp_fx1 = round_fx( tmp_fxL1 ); -#endif tmp_fx2 = round_fx( tmp_fxL2 ); tmp_fx3 = div_s( tmp_fx2, tmp_fx1 ); min_g_hb_fx[i] = Frac_sqrt( tmp_fx3 ); @@ -996,9 +992,7 @@ void Inverse_Transform( Word16 segment_length_div2, segment_length_div4; Word16 tmp, q_out; Word32 L_temp; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( element_mode ); -#endif /* This value is used to right shift all vectors returned by 'iedct_short_fx()' */ /* to bring them to a scaling that is equal to the 1st 'Q' returned by the 1st */ /* call to 'iedct_short_fx()' minus these guard bits. */ diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 34d01d7fe..74f1bfc09 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -1590,11 +1590,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[*pPlocs], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( *pPlocs ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1605,11 +1601,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && EQ_16( *pPlocs, 1 ) ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[*pPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( sub( *pPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1655,11 +1647,7 @@ static void ivas_spec_ana_fx( IF( EQ_16( currPlocs, ( sub( Lprot2_1, DELTA_CORR_F0_INT ) ) ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[currPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( sub( currPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1673,11 +1661,7 @@ static void ivas_spec_ana_fx( * whould point */ IF( n > 0 ) /* fs/2 which makes special case . */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[currPlocs - 2], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( sub( currPlocs, 2 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -4005,11 +3989,7 @@ static void ivas_fec_ecu_dft_fx( tmp = Exp16Array( *Nfft, Tfr16 ); *exp = add( tmp, add( 2, norm_s( *Nfft ) ) ); move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#else - Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#endif *exp = s_min( *exp, 15 ); DoRTFTn_fx( Tfr32, Tfi32, *Nfft ); @@ -4125,20 +4105,12 @@ static void fec_ecu_dft_fx( tmp = Exp16Array( *Nfft, Tfr16 ); *exp = add( tmp, add( 2, norm_s( *Nfft ) ) ); move16(); -#ifdef FIX_ISSUE_1237 { -#ifdef FIX_ISSUE_1237_KEEP_EVS_BE Word16 loctmp = *exp; move16(); loctmp = s_min( 15, loctmp ); Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, loctmp ); /*Qin+exp; */ /*Even with limiting loctmp, if Copy_Scale_sig_16_32_no_sat() is used, can lead to 1 difference */ -#else - Copy_Scale_sig_16_32_no_sat( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#endif } -#else - Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#endif DoRTFTn_fx( Tfr32, Tfi32, *Nfft ); N_LP = shr( *Nfft, 1 ); diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index 35bb254af..612816efd 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -504,11 +504,7 @@ void FEC_exc_estim_fx( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) -#else - IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) ) -#endif { st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag; move16(); @@ -670,11 +666,7 @@ void FEC_exc_estim_fx( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) -#else - IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) -#endif { /* For GSC - the excitation is already computed */ Copy( exc, exc2, st_fx->L_frame ); diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index e50abddd6..e820f1399 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -76,13 +76,11 @@ void ivas_DetectTonalComponents_fx( pScaledMdctSpectrum[i] = L_shl( lastMDCTSpectrum[i], 16 ); /*15-lastMDCTSpectrum_exp+16 -> 31 - lastMDCTSpectrum_exp*/ move32(); } -#ifdef MSAN_FIX FOR( Word16 i = 0; i < FDNS_NPTS; i++ ) { sns_int_scf_fx[i] = L_shl_sat( scaleFactors[i], add( 1, scaleFactors_exp[i] ) ); // Q16 move32(); } -#endif IF( psychParamsCurrent == NULL ) { nBands = FDNS_NPTS; @@ -94,12 +92,6 @@ void ivas_DetectTonalComponents_fx( } ELSE { -#ifndef MSAN_FIX - FOR( Word16 i = 0; i < FDNS_NPTS; i++ ) - { - sns_int_scf_fx[i] = L_shl( scaleFactors[i], add( 1, scaleFactors_exp[i] ) ); // Q16 - } -#endif q_pScaledMdctSpectrum = sub( 31, lastMDCTSpectrum_exp ); sns_shape_spectrum_fx( pScaledMdctSpectrum, &q_pScaledMdctSpectrum, psychParamsCurrent, sns_int_scf_fx, 16, nSamplesCore, NULL ); q_pScaledMdctSpectrum = add( q_pScaledMdctSpectrum, 1 ); diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 0f94a7558..7a3c78644 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -113,7 +113,6 @@ ivas_error acelp_core_dec_fx( FD_BWE_DEC_HANDLE hBWE_FD; TCX_DEC_HANDLE hTcxDec; ivas_error error; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( tdm_lspQ_PCh ); (void) ( tdm_lsfQ_PCh ); (void) ( use_cldfb_for_dft ); @@ -125,7 +124,6 @@ ivas_error acelp_core_dec_fx( (void) ( output ); (void) ( read_sid_info ); (void) hStereoCng; -#endif hMusicPF = st_fx->hMusicPF; hBPF = st_fx->hBPF; hBWE_TD = st_fx->hBWE_TD; @@ -666,21 +664,13 @@ ivas_error acelp_core_dec_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif test(); test(); IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) { -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, TRANSITION, -1, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif } } diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 2ca524bb0..5807f2c67 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -83,22 +83,14 @@ ivas_error acelp_core_dec_ivas_fx( Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ -#ifdef MSAN_FIX Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ -#else - Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ -#endif Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ Word32 enr_q_fx; /* E information for FER protection */ Word16 tmp_noise_fx; /* Long term temporary noise energy */ Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ Word16 FEC_pitch_fx; /* FEC pitch */ -#ifdef MSAN_FIX Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ -#else - Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ -#endif Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ Word16 i, j, int_fs; Word16 tc_subfr; @@ -133,13 +125,9 @@ ivas_error acelp_core_dec_ivas_fx( ivas_error error; Word32 bpf_error_signal_fx[L_FRAME16k]; -#ifdef MSAN_FIX set32_fx( bpf_error_signal_fx, 0, L_FRAME16k ); -#endif Word16 bpf_error_signal_16fx[L_FRAME16k]; -#ifdef MSAN_FIX set16_fx( bpf_error_signal_16fx, 0, L_FRAME16k ); -#endif set16_fx( Aq_fx, 0, NB_SUBFR16k * ( M + 1 ) ); set16_fx( old_bwe_exc_fx, 0, ( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ) ); Word16 tmp; @@ -178,7 +166,6 @@ ivas_error acelp_core_dec_ivas_fx( IF( EQ_32( st->core_brate, SID_2k40 ) ) { FdCng_decodeSID_ivas_fx( st ); -#ifdef FIX_ISSUE_1218 Word16 n1, n2; n1 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART ); n2 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); @@ -188,9 +175,6 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( old_NoiseEstExp, common_e ) ); st->hFdCngDec->hFdCngCom->sidNoiseEstExp = common_e; move16(); -#else - rescale_fdCngDec( st->hFdCngDec, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); -#endif } FOR( i = 0; i < NPART; i++ ) { @@ -621,11 +605,7 @@ ivas_error acelp_core_dec_ivas_fx( { test(); test(); -#ifdef FIX_1189_GSC_IVAS_OMASA IF( EQ_16( st->coder_type, AUDIO ) || ( EQ_16( st->coder_type, INACTIVE ) && EQ_16( st->inactive_coder_type_flag, 1 ) ) ) -#else - IF( EQ_16( st->coder_type, AUDIO ) || ( st->coder_type == INACTIVE && LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { st->GSC_IVAS_mode = get_next_indice_fx( st, 2 ); move16(); @@ -642,14 +622,6 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->cng_type == LP_CNG ) { CNG_dec_ivas_fx( st, last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sid_bw, q_env_fx ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - FOR( Word32 nsf = 0; nsf < NB_SUBFR16k; nsf++ ) - { - Scale_sig( Aq_fx + imult3216( nsf, ( M + 1 ) ), M + 1, sub( norm_s( Aq_fx[nsf * ( M + 1 )] ), Q2 ) ); - Aq_fx[nsf * ( M + 1 )] = ONE_IN_Q12; - move16(); - } -#endif Copy( Aq_fx, st->Aq_cng, add( M, 1 ) ); /* comfort noise generation */ @@ -746,11 +718,7 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->hMusicPF && st->hGSCDec ) { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, -#ifdef FIX_ISSUE_1291 L_FRAME32k, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); -#else - imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); -#endif } IF( st->hPFstat != NULL ) { @@ -781,9 +749,6 @@ ivas_error acelp_core_dec_ivas_fx( /* synthesis at 12.8kHz sampling rate */ -#ifndef FIX_1100_REMOVE_LPC_RESCALING - Aq_fx[0] = ONE_IN_Q12; -#endif move16(); syn_12k8_fx( st->L_frame, Aq_fx, exc2_fx, psyn_fx, st->mem_syn2_fx, 1, st->Q_exc, st->Q_syn ); syn_12k8_fx( st->L_frame, Aq_fx, exc3_fx, syn1_fx, st->mem_syn3_fx, 1, st->Q_exc, st->Q_syn ); @@ -804,11 +769,7 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn -> Q(-1) IF( st->hBWE_FD != NULL ) { -#ifdef FIX_ISSUE_1290 save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); -#else - save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); -#endif } } @@ -848,21 +809,13 @@ ivas_error acelp_core_dec_ivas_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, st->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif test(); test(); IF( EQ_16( st->coder_type, TRANSITION ) && LT_16( tc_subfr, L_SUBFR ) && EQ_16( st->L_frame, L_FRAME ) ) { -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, TRANSITION, -1, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif } } @@ -944,18 +897,6 @@ ivas_error acelp_core_dec_ivas_fx( st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); move16(); } -#ifndef FIX_1100_REMOVE_LPC_RESCALING -#ifndef MSAN_FIX - for ( int nsf = 0; nsf < NB_SUBFR16k; nsf++ ) -#else - FOR( Word32 nsf = 0; nsf < st->nb_subfr; nsf++ ) -#endif - { - Scale_sig( Aq_fx + imult3216( nsf, ( M + 1 ) ), M + 1, sub( norm_s( Aq_fx[nsf * ( M + 1 )] ), Q2 ) ); // Q(x-2) - Aq_fx[nsf * ( M + 1 )] = ONE_IN_Q12; - move16(); - } -#endif test(); IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) { @@ -1129,11 +1070,7 @@ ivas_error acelp_core_dec_ivas_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ -#ifdef NONBE_FIX_GSC_BSTR Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#else - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#endif /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames @@ -1291,18 +1228,6 @@ ivas_error acelp_core_dec_ivas_fx( lsf_dec_bfi( MODE1, lsf_new_fx, st->lsf_old_fx, st->lsf_adaptive_mean_fx, NULL, st->mem_MA_fx, st->mem_AR_fx, st->stab_fac_fx, st->last_coder_type, st->L_frame, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, 0, st->bwidth ); FEC_lsf2lsp_interp( st, st->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING -#ifndef MSAN_FIX - for ( int nsf = 0; nsf < NB_SUBFR16k; nsf++ ) -#else - FOR( Word32 nsf = 0; nsf < st->nb_subfr; nsf++ ) -#endif - { - Scale_sig( Aq_fx + imult3216( nsf, ( M + 1 ) ), M + 1, sub( norm_s( Aq_fx[nsf * ( M + 1 )] ), Q2 ) ); // Qx->Q(x-2) - Aq_fx[nsf * ( M + 1 )] = ONE_IN_Q12; - move16(); - } -#endif IF( EQ_16( st->nelp_mode_dec, 1 ) ) { /* SC-VBR */ @@ -1340,11 +1265,7 @@ ivas_error acelp_core_dec_ivas_fx( } /* Apply energy matching when switching to inactive frames */ -#ifdef NONBE_FIX_GSC_BSTR Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#else - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#endif /* update past excitation signals for LD music post-filter */ IF( st->hMusicPF != NULL ) @@ -1766,23 +1687,14 @@ ivas_error acelp_core_dec_ivas_fx( pRealSave_fx[i] = realBufferSave_fx[i]; pImagSave_fx[i] = imagBufferSave_fx[i]; } -#ifndef MSAN_FIX - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 -#endif IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 -#endif Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 } -#ifdef MSAN_FIX FOR( i = 0; i < st->L_frame; i++ ) -#else - for ( i = 0; i < L_FRAME16k; i++ ) -#endif { syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); // Q12 move32(); @@ -1803,15 +1715,7 @@ ivas_error acelp_core_dec_ivas_fx( q_bpf_error_signal = Q6; move16(); -#ifdef MSAN_FIX -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#endif -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn ); // Q6 -#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 @@ -1910,9 +1814,6 @@ ivas_error acelp_core_dec_ivas_fx( #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifndef MSAN_FIX - Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); // Q_real-1 -#endif FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { @@ -1932,11 +1833,7 @@ ivas_error acelp_core_dec_ivas_fx( } } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, 0, st->cldfbSynHB ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, st->cldfbSynHB ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( save_hb_synth_fx, L_FRAME48k, negate( ( sub( Q_real, 1 ) ) ) ); // Q0 Scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 @@ -1956,11 +1853,7 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // Q_real-1 st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( synth_fx, L_FRAME48k, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSynHB->Q_cldfb_state = Q10; @@ -2003,20 +1896,9 @@ ivas_error acelp_core_dec_ivas_fx( #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); -#endif -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ -#ifdef MSAN_FIX scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 -#else - Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); -#endif scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); @@ -2030,11 +1912,7 @@ ivas_error acelp_core_dec_ivas_fx( Word16 nSamples = NS2SA_FX2( i_mult( st->L_frame, FRAMES_PER_SEC ), FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ -#ifndef MSAN_FIX - for ( i = 0; i < L_FRAME16k; i++ ) -#else FOR( i = 0; i < st->L_frame; i++ ) -#endif { syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); move32(); @@ -2057,11 +1935,7 @@ ivas_error acelp_core_dec_ivas_fx( // Get Q-factor q_bpf_error_signal = Q6; move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 @@ -2116,21 +1990,10 @@ ivas_error acelp_core_dec_ivas_fx( #else /* OPT_STEREO_32KBPS_V1 */ scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); -#endif -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ -#ifdef MSAN_FIX Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 -#else - Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); -#endif Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); @@ -2146,11 +2009,7 @@ ivas_error acelp_core_dec_ivas_fx( } /* Copy output signal */ -#ifndef MSAN_FIX - Scale_sig( syn_tmp_fx, L_FRAME16k + L_SUBFR, -st->Q_syn ); -#else Scale_sig( syn_tmp_fx, add( st->L_frame, L_SUBFR ), negate( st->Q_syn ) ); // Q0 -#endif IF( st->element_mode > EVS_MONO ) { Copy( psyn_fx, output_fx, st->L_frame ); /*Q_syn*/ @@ -2173,24 +2032,14 @@ ivas_error acelp_core_dec_ivas_fx( IF( ( EQ_16( st->L_frame, L_FRAME ) && ( st->bwidth != NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st->extl, -1 ) || EQ_16( st->extl, SWB_CNG ) || ( EQ_16( st->extl, WB_BWE ) && st->extl_brate == 0 && NE_16( st->coder_type, AUDIO ) ) ) ) ) { -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q0 -#else - Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); -#endif hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2 ); -#ifdef MSAN_FIX Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, output_frame, 0 ); -#else - Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, L_FRAME48k, 0 ); -#endif } ELSE { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } } @@ -2225,11 +2074,7 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( !st->ppp_mode_dec && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#endif non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc } @@ -2270,18 +2115,7 @@ ivas_error acelp_core_dec_ivas_fx( { Copy_Scale_sig_32_16( save_hb_synth_fx, save_hb_synth_fx16, L_FRAME48k, 0 ); // Q0 } -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q_syn2 -#else - Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); -#endif -#ifndef FIX_1100_REMOVE_LPC_RESCALING - if ( st->hFdCngDec ) - { - st->hFdCngDec->hFdCngCom->A_cng[0] = ONE_IN_Q12; - move16(); - } -#endif } pop_wmops(); diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 6a1e60b06..9013f2f03 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -128,11 +128,7 @@ ivas_error acelp_core_switch_dec_fx( * Excitation decoding *----------------------------------------------------------------*/ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); -#else - config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); -#endif decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); @@ -819,11 +815,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( *----------------------------------------------------------------*/ /* CLDFB analysis of the synthesis at internal sampling rate */ Qtmp = sub( 11, st_fx->Q_syn ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) -#else - Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) -#endif IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st_fx->cldfbAna ) ), IVAS_ERR_OK ) ) { return error; @@ -845,11 +837,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), 0, st_fx->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); move16(); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 1f6b0dd51..05125318f 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -898,9 +898,7 @@ ivas_error core_switching_post_dec_fx( HQ_DEC_HANDLE hHQ_core; ivas_error error; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( last_element_mode ); -#endif hBWE_TD = st_fx->hBWE_TD; hBWE_FD = st_fx->hBWE_FD; hHQ_core = st_fx->hHQ_core; @@ -2058,11 +2056,7 @@ static void core_switch_lb_upsamp_fx( } /* synthesis of the combined signal */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ /*rescaling whole buffer to a common Q*/ no_col = st->cldfbSyn->no_col; @@ -2100,13 +2094,8 @@ static void smoothTransitionDtxToTcx_fx( Word16 i, filter_len; Word16 w, step, fade_in; Word32 mem; -#ifdef MSAN_FIX - Word16 smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; - Word16 smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; -#else Word16 smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; Word16 smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; -#endif set16_fx( smoothing_input_buffer, 0, 2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k ); set16_fx( smoothing_out_buffer, 0, 2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k ); @@ -2241,10 +2230,8 @@ ivas_error core_switching_pre_dec_ivas_fx( test(); IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) { -#ifdef MSAN_FIX st->hBWE_TD->prev_hb_synth_fx_exp = 31; move16(); -#endif // MSAN_FIX /* reset BWE memories */ set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; @@ -2262,9 +2249,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->hBWE_FD != NULL ) @@ -2379,11 +2364,7 @@ ivas_error core_switching_pre_dec_ivas_fx( return error; } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfb_restore_memory_ivas_fx( st->cldfbSyn ); Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); @@ -2587,9 +2568,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->hBWE_FD != NULL ) @@ -2639,9 +2618,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->hBWE_FD != NULL ) @@ -2662,11 +2639,7 @@ ivas_error core_switching_pre_dec_ivas_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#else - Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#endif Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); st->cldfbAna->Q_cldfb_state = Q10; move16(); diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index bdfac224f..325beb9f3 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -693,11 +693,7 @@ ivas_error decod_gen_voic_ivas_fx( * Transform domain contribution decoding *-----------------------------------------------------------------*/ test(); -#ifdef NONBE_FIX_GSC_BSTR IF( !st_fx->inactive_coder_type_flag && st_fx->coder_type == INACTIVE ) -#else - IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( st_fx->coder_type == INACTIVE ) ) -#endif { transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); } diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 8ff50f8a5..e2ea02dcc 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -2682,11 +2682,7 @@ void IMDCT_ivas_fx( } move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE set16_fx( win_fx, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) >> 1 ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 tcx_offset_tmp = add( tcx_offset, shr( L_ola, 1 ) ); set16_fx( xn_buf_fx, 0, tcx_offset_tmp ); /* zero left end of buffer */ @@ -2865,16 +2861,10 @@ void IMDCT_ivas_fx( q_tmp_fx_32 = q_xn_buf_fx_32; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 diff = sub( q_tmp_fx_32, q_win ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE old_out_fx_32[ind] = L_shl( old_out_fx[ind], diff ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - old_out_fx_32[ind] = L_shl( old_out_fx[ind], sub( q_tmp_fx_32, q_win ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move32(); } @@ -2882,13 +2872,8 @@ void IMDCT_ivas_fx( FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], diff ) ); xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - old_out_fx[ind] = (Word16) L_shr( old_out_fx_32[ind], sub( q_tmp_fx_32, q_win ) ); - xn_buf_fx[ind] = (Word16) L_shr( xn_buf_fx_32[ind], sub( q_tmp_fx_32, q_win ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move16(); move16(); } @@ -2912,39 +2897,24 @@ void IMDCT_ivas_fx( q_tmp_fx_32 = sub( q_xn_buf_fx_32, res_e ); // v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 q_diff = sub( q_xn_buf_fx_32, q_win ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = extract_l( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = (Word16) L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], sub( q_xn_buf_fx_32, q_win ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move16(); } window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, &q_old_out, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE q_diff = sub( q_old_out, q_win ); Word16 diff = sub( q_tmp_fx_32, q_win ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE old_out_fx[ind] = shr_sat( old_out_fx[ind], q_diff ); move16(); xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff ); move16(); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - old_out_fx[ind] = shr_sat( old_out_fx[ind], sub( q_old_out, q_win ) ); - move16(); - xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], sub( q_tmp_fx_32, q_win ) ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } } aldo = 1; @@ -4441,11 +4411,7 @@ void decoder_tcx_noisefilling_fx( /* get the starting location of the subframe in the frame */ IF( EQ_16( st->core, TCX_10_CORE ) ) { -#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); -#else - st->hPlcInfo->subframe = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); -#endif move16(); } } diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index f9833e80a..0bc7794dc 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -713,7 +713,6 @@ void decision_matrix_dec_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR /*-----------------------------------------------------------------* * set inactive coder_type flag in ACELP core *-----------------------------------------------------------------*/ @@ -727,6 +726,5 @@ void decision_matrix_dec_fx( move16(); } -#endif return; } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index c509d5d10..df18d3dba 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -187,9 +187,7 @@ void initFdCngDec_ivas_fx( st->CNG_mode = -1; move16(); Copy( st->lsp_old_fx, st->lspCNG_fx, M ); /*Q15*/ -#ifdef MSAN_FIX hFdCngDec->hFdCngCom->sid_frame_counter = 0; -#endif return; } @@ -1765,12 +1763,8 @@ Word16 ApplyFdCng_ivas_fx( { FOR( ; j <= hFdCngCom->part[k]; j++ ) { -#ifdef FIX_ISSUE_1218 /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ -#else - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ -#endif move32(); } } @@ -5275,11 +5269,7 @@ void generate_stereo_masking_noise_fx( IF( st->idchan == 0 ) { hFdCngCom = st->hFdCngDec->hFdCngCom; -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#endif Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); @@ -5287,11 +5277,7 @@ void generate_stereo_masking_noise_fx( IF( !fadeOut ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#endif generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 /* Generate masking noise for secondary channel */ IF( flag_sec_CNA ) diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 6c63377fd..8f29eb9d1 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -92,11 +92,7 @@ void decod_audio_fx( } /* set bit-allocation */ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif /*---------------------------------------------------------------* * Decode energy dynamics @@ -522,11 +518,7 @@ void decod_audio_ivas_fx( } /* set bit-allocation */ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif /*---------------------------------------------------------------* * Decode energy dynamics @@ -1372,14 +1364,10 @@ void gsc_dec_ivas_fx( } pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); -#ifdef MSAN_FIX IF( nb_subbands > 0 ) { Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ } -#else - Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ -#endif seed_init = 0; move16(); @@ -1435,11 +1423,7 @@ void gsc_dec_ivas_fx( } if ( concat_out[j] < 0 ) { -#ifdef BASOP_NOGLOB_TMP_715 seed_init = add_sat( seed_init, 3 ); /* Q0 */ -#else - seed_init = add( seed_init, 3 ); -#endif } } diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 714245514..4d1ef6774 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -627,9 +627,7 @@ void ivas_hq_core_dec_fx( set16_fx( gapsynth_fx, 0, L_FRAME48k ); set16_fx( num_bands_p, 0, MAX_SB_NB ); set16_fx( ynrm, 39, NB_SFM ); /* Initialize to the smallest value */ -#ifdef MSAN_FIX set16_fx( wtda_audio_16, 0, 2 * L_FRAME48k ); -#endif mean_en_high_fx = 0; move16(); Q_audio = 12; @@ -951,9 +949,6 @@ void ivas_hq_core_dec_fx( index = tcx_cfg->tcx_last_overlap_mode; /* Q0 */ move16(); -#ifndef MSAN_FIX - Copy_Scale_sig_32_16( wtda_audio, wtda_audio_16, 2 * L_FRAME48k, -13 ); -#endif /* LB synthesis */ E_audio = sub( 31, Q_audio ); diff --git a/lib_dec/hq_hr_dec_fx.c b/lib_dec/hq_hr_dec_fx.c index d72f0ec45..89864bc3b 100644 --- a/lib_dec/hq_hr_dec_fx.c +++ b/lib_dec/hq_hr_dec_fx.c @@ -100,7 +100,6 @@ void hq_pred_hb_bws_fx( } ELSE { -#ifdef EVS_FUNC_MODIFIED st_fx->prev_ener_shb_fx = 0; move16(); L_tmp = L_deposit_l( 0 ); @@ -111,15 +110,6 @@ void hq_pred_hb_bws_fx( L_tmp = Mpy_32_16_1( L_tmp, 2979 ); // Q1 st_fx->prev_ener_shb_fx = extract_l( L_tmp ); /*Q1*/ move16(); -#else - st_fx->prev_ener_shb_fx = 0; - move16(); - FOR( i = 0; i < SWB_FENV - 3; i++ ) - { - st_fx->prev_ener_shb_fx = add( st_fx->prev_ener_shb_fx, SWB_fenv[i] ); /*Q1*/ - } - st_fx->prev_ener_shb_fx = mult( st_fx->prev_ener_shb_fx, 2979 ); /*Q1*/ -#endif } } diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 5bfa7476a..60e649a08 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -2883,9 +2883,6 @@ static void IGF_getWhiteSpectralData_ivas( Word16 j; Word32 ak; Word16 ak_e; -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Word16 tmp_16; -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 tmp_e; Word16 out_e_arr[IGF_START_MX + MAX_IGF_SFB_LEN]; Word16 max_out_e; @@ -2904,23 +2901,18 @@ static void IGF_getWhiteSpectralData_ivas( Word16 guard_bits = add( find_guarded_bits_fx( add( i_mult( 2, level ), 1 ) ), 1 ) / 2; s_l = sub( s_l, guard_bits ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 shift = sub( shl( s_l, 1 ), 32 ); Word16 eff_e = sub( shl( sub( in_e, s_l ), 1 ), 15 ); Word16 diff = add( 21, in_e ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 quo = BASOP_Util_Divide3216_Scale( ONE_IN_Q30, add( shl( level, 1 ), 1 ), &tmp_e ); tmp_e = add( tmp_e, 1 ); ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 -#ifdef OPT_SBA_AVOID_SPAR_RESCALE ak_e = sub( ak_e, 1 ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = start; i < stop - level; i++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word64 temp = 0; move64(); FOR( j = i - level; j < i + level + 1; j++ ) @@ -2935,30 +2927,11 @@ static void IGF_getWhiteSpectralData_ivas( out_e_arr[i] = sub( diff, n ); move16(); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - ak = 0; - move32(); - move32(); - FOR( j = i - level; j < i + level + 1; j++ ) - { - tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l - ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) - } - ak = Mult_32_16( ak, quo ); // add( shl( level, 1 ), 1 ), &tmp_e ) ); - - - n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); - n = shr( n, 1 ); - - out_e_arr[i] = add( sub( 21, n ), in_e ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ max_out_e = s_max( max_out_e, out_e_arr[i] ); } FOR( ; i < stop; i++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word64 temp = 0; move64(); @@ -2974,24 +2947,6 @@ static void IGF_getWhiteSpectralData_ivas( out_e_arr[i] = sub( diff, n ); move16(); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - ak = 0; - move32(); - - FOR( j = i - level; j < stop; j++ ) - { - tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l - ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) - } - ak = L_deposit_h( BASOP_Util_Divide3216_Scale( ak, sub( stop, sub( i, level ) ), &tmp_e ) ); - ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 - - n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); - n = shr( n, 1 ); - - out_e_arr[i] = add( sub( 21, n ), in_e ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ max_out_e = s_max( max_out_e, out_e_arr[i] ); } diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 934433132..b588fdce1 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -315,10 +315,8 @@ ivas_error init_decoder_fx( move16(); /*1; Q15*/ st_fx->exc_pe_fx = 0; // Q_stat_noise move16(); -#ifdef MSAN_FIX st_fx->Q_stat_noise = 31; move16(); -#endif // MSAN_FIX /*-----------------------------------------------------------------* * LD music post-filter *-----------------------------------------------------------------*/ @@ -1036,10 +1034,8 @@ ivas_error init_decoder_ivas_fx( move16(); st_fx->exc_pe_fx = 0; move16(); -#ifdef MSAN_FIX st_fx->Q_stat_noise = 31; move16(); -#endif st_fx->prev_coder_type = GENERIC; move16(); @@ -1139,9 +1135,7 @@ ivas_error init_decoder_ivas_fx( } hf_synth_init_fx( st_fx->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st_fx->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } ELSE { diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 85fefadbc..f78f14e8e 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -66,17 +66,11 @@ static void ivas_binRenderer_filterModule_fx( { Word16 bandIdx, k, chIdx, tapIdx; Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx; -#ifdef OPT_BASOP_ADD_v1 Word16 Q_filterStates; -#else /* OPT_BASOP_ADD_v1 */ - Word16 *Q_filterStates; -#endif /* OPT_BASOP_ADD_v1 */ const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx; Word16 shift_q; -#ifdef OPT_BASOP_ADD_v1 Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStatesLeft; move16(); -#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -84,9 +78,6 @@ static void ivas_binRenderer_filterModule_fx( { filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] ); filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] ); -#ifndef OPT_BASOP_ADD_v1 - Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx][0] ); -#endif /* OPT_BASOP_ADD_v1 */ filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29 filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29 @@ -108,13 +99,6 @@ static void ivas_binRenderer_filterModule_fx( filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1]; move32(); -#ifndef OPT_BASOP_ADD_v1 - shift_q = sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ); - outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); - outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); - outRealRight_fx = W_shr( outRealRight_fx, shift_q ); - outImagRight_fx = W_shr( outImagRight_fx, shift_q ); -#endif /* OPT_BASOP_ADD_v1 */ outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates @@ -127,40 +111,24 @@ static void ivas_binRenderer_filterModule_fx( outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates -#ifndef OPT_BASOP_ADD_v1 - Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ } -#ifdef OPT_BASOP_ADD_v1 shift_q = add( sub( Q_filterStates, Q_curr ), 1 ); -#else /* OPT_BASOP_ADD_v1 */ - shift_q = add( sub( Q_filterStates[1], Q_curr ), 1 ); -#endif /* OPT_BASOP_ADD_v1 */ -#ifdef OPT_BASOP_ADD_v1 IF( shift_q != 0 ) { -#endif /* OPT_BASOP_ADD_v1 */ outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); // Q_curr outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); // Q_curr outRealRight_fx = W_shr( outRealRight_fx, shift_q ); // Q_curr outImagRight_fx = W_shr( outImagRight_fx, shift_q ); // Q_curr -#ifdef OPT_BASOP_ADD_v1 hBinRenderer->hBinRenConvModule->Q_filterStatesLeft = Q_curr; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx]; move32(); filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx]; move32(); -#ifndef OPT_BASOP_ADD_v1 - Q_filterStates[0] = Q_curr; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ /* Left Real and Imag */ @@ -346,12 +314,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#ifndef OPT_BASOP_ADD_v1 - IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -365,12 +327,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#ifndef OPT_BASOP_ADD_v1 - IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#endif /* OPT_BASOP_ADD_v1 */ FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { @@ -384,12 +340,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#ifndef OPT_BASOP_ADD_v1 - IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#endif /* OPT_BASOP_ADD_v1 */ } } /* set memories */ @@ -434,12 +384,8 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); -#ifdef OPT_BASOP_ADD_v1 hBinRenConvModule->Q_filterStatesLeft = 31; move16(); -#else /* OPT_BASOP_ADD_v1 */ - set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTapsArray[bandIdx] ); -#endif /* OPT_BASOP_ADD_v1 */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftBRIRReal_fx[bandIdx][tmp]; @@ -453,12 +399,8 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); -#ifdef OPT_BASOP_ADD_v1 hBinRenConvModule->Q_filterStatesLeft = 31; move16(); -#else /* OPT_BASOP_ADD_v1 */ - set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTaps ); -#endif /* OPT_BASOP_ADD_v1 */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp]; @@ -1323,10 +1265,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; -#ifndef OPT_BASOP_ADD_v1 - free( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] ); - hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = NULL; -#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); @@ -1335,10 +1273,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; -#ifndef OPT_BASOP_ADD_v1 - free( hBinRenConvModule->Q_filterStatesLeft[bandIdx] ); - hBinRenConvModule->Q_filterStatesLeft[bandIdx] = NULL; -#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx ); @@ -1347,10 +1281,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx ); hBinRenConvModule->filterStatesLeftImag_fx = NULL; -#ifndef OPT_BASOP_ADD_v1 - free( hBinRenConvModule->Q_filterStatesLeft ); - hBinRenConvModule->Q_filterStatesLeft = NULL; -#endif /* OPT_BASOP_ADD_v1 */ free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 37c32a8b1..4e654030b 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -336,11 +336,7 @@ ivas_error ivas_core_dec_fx( Word16 ovl, fade_len; IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#endif L_lerp_fx_q11( sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->L_frame, sts[0]->last_L_frame ); Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda_LB } @@ -527,11 +523,7 @@ ivas_error ivas_core_dec_fx( return error; } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 -#else - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 -#endif Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 IF( st->cldfbAna ) { @@ -551,9 +543,6 @@ ivas_error ivas_core_dec_fx( st->cldfbSyn->Q_cldfb_state = Q11; move16(); } -#ifndef FIX_ISSUE_1279 /* the update of prev_Q_syn is already done inside rescale_mem( ) */ - st->prev_Q_syn = st->Q_syn; -#endif move16(); IF( save_hb_synth_32_fx ) @@ -641,11 +630,7 @@ ivas_error ivas_core_dec_fx( ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 -#ifdef MSAN_FIX Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 -#else - Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); -#endif Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 } @@ -660,11 +645,7 @@ ivas_error ivas_core_dec_fx( td_stereo_param_updt_fx( st->lsp_old_fx, st->lsf_old_fx, st->old_pitch_buf_16_fx + st->nb_subfr, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, hStereoTD->tdm_Pri_pitch_buf_fx, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 -#endif } } /* n_channels loop */ @@ -910,19 +891,11 @@ ivas_error ivas_core_dec_fx( /* Memories Re-Scaling */ IF( hBWE_TD != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 -#endif Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } @@ -936,11 +909,7 @@ ivas_error ivas_core_dec_fx( test(); IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) && !( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#else - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#endif } IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) @@ -954,11 +923,7 @@ ivas_error ivas_core_dec_fx( test(); IF( sba_dirac_stereo_flag && hSCE && EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#else - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#endif } /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ @@ -985,11 +950,7 @@ ivas_error ivas_core_dec_fx( } ELSE { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 -#endif } Scale_sig32( output_32_fx[n], L_FRAME48k, ( Q11 - Q4 ) ); // Q11 @@ -1003,16 +964,12 @@ ivas_error ivas_core_dec_fx( move16(); } -#ifdef MSAN_FIX IF( Q_synth > 0 ) { Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Q_synth = 0; move16(); } -#else - Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); -#endif /*------------------reset-code-start---------------------*/ @@ -1078,31 +1035,17 @@ ivas_error ivas_core_dec_fx( } /* Memories Re-Scaling */ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 // Q_input can get value <= -5 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 -#endif IF( hBWE_FD != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 -#endif } IF( hBWE_TD != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 -#endif } /*---------------------------------------------------------------------* @@ -1205,11 +1148,7 @@ ivas_error ivas_core_dec_fx( q = 2; move16(); Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); // Q0 -#else - Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, L_FRAME48k, negate( add( Q11, q ) ) ); -#endif Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ); // Q8 Copy_Scale_sig_32_16( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, ( 2 * ALLPASSSECTIONS_STEEP ), sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bew_syn2 @@ -1242,7 +1181,6 @@ ivas_error ivas_core_dec_fx( move32(); } stereo_icBWE_dec_fx( hCPE, hb_synth_32_fx[0], hb_synth_32_fx[1], tmp_buffer_fx /*fb_synth_ref*/, voice_factors_fx[0], output_frame, &q, Q_white_exc ); -#ifdef MSAN_FIX test(); test(); test(); @@ -1254,10 +1192,6 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } -#else - Scale_sig32( hb_synth_32_fx[0], L_FRAME48k, sub( Q11, q ) ); - Scale_sig32( hb_synth_32_fx[1], L_FRAME48k, sub( Q11, q ) ); -#endif } IF( EQ_16( st->element_mode, EVS_MONO ) ) @@ -1286,11 +1220,7 @@ ivas_error ivas_core_dec_fx( } waveform_adj2_fix( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); -#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->Pitch_fx = 0; -#else - st->hPlcInfo->Pitch = 0; -#endif move16(); } } @@ -1476,13 +1406,8 @@ ivas_error ivas_core_dec_fx( IF( st->hHQ_core != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 -#endif } IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 05fec7736..c10c6beda 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -124,22 +124,14 @@ ivas_error ivas_cpe_dec_fx( test(); IF( hCPE->hCoreCoder[ind1] && hCPE->hCoreCoder[ind1]->hHQ_core ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 -#endif } } FOR( Word16 ind1 = 0; ind1 < 2; ind1++ ) { IF( hCPE->hCoreCoder[ind1]->hHQ_core ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#endif hCPE->hCoreCoder[ind1]->hHQ_core->q_old_outLB_fx = Q11; move16(); } diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index ae4098f19..b45f54d48 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2113,11 +2113,7 @@ void ivas_dirac_dec_render_fx( FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { -#ifdef MSAN_FIX ivas_dirac_dec_render_sf_fx( st_ivas, output_f_local_fx, nchan_transport, NULL, NULL ); -#else - ivas_dirac_dec_render_sf_fx( st_ivas, output_f_local, nchan_transport, NULL, NULL ); -#endif // MSAN_FIX n_samples_sf = i_mult( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->slot_size ); @@ -3747,11 +3743,7 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[ch]->Q_cldfb_state = ( Q6 - 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 no_col = st_ivas->cldfbSynDec[ch]->no_col; move16(); @@ -3854,11 +3846,7 @@ void ivas_dirac_dec_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; move32(); } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, 0, st_ivas->cldfbSynDec[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( !st_ivas->hLsSetupCustom->separate_ch_found ) { @@ -3898,11 +3886,7 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state ) ); // Q6-1 st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state = ( Q6 - 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[cldfbSynIdx] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, st_ivas->cldfbSynDec[cldfbSynIdx] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ // Calculating length of output Word16 no_col = st_ivas->cldfbSynDec[cldfbSynIdx]->no_col; @@ -3971,11 +3955,7 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = ( Q6 - 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, st_ivas->cldfbSynDec[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ // Scaling output from Q6-1 to Q11 Scale_sig32( p_out, out_len, ( Q11 - ( Q6 - 1 ) ) ); diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index b247fd653..114083fad 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -723,11 +723,7 @@ Word16 computeMixingMatrices_fx( Word32 G_hat_fx[MAX_OUTPUT_CHANNELS]; Word16 G_hat_buff_e[MAX_OUTPUT_CHANNELS]; -#ifdef OPT_BASOP_ADD_v1 Word16 mat_mult_buffer2_e, mat_mult_buffer3_e; -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer1_e, mat_mult_buffer2_e, mat_mult_buffer3_e; -#endif /* OPT_BASOP_ADD_v1 */ Word32 mat_mult_buffer3_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; @@ -777,9 +773,7 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); -#ifdef OPT_BASOP_ADD_v1 Word16 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ /* Computing Ky */ FOR( i = 0; i < lengthCy; ++i ) { @@ -792,12 +786,9 @@ Word16 computeMixingMatrices_fx( move32(); Ky_fx_e[i + ( j * lengthCy )] = tmp_e; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, tmp_e ); -#endif /* OPT_BASOP_ADD_v1 */ } } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCy * lengthCy; ++i ) { Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); @@ -805,7 +796,6 @@ Word16 computeMixingMatrices_fx( Ky_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Decomposition of Cx @@ -816,9 +806,7 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); svd_fx( svd_in_buffer_fx, Cx_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCx, lengthCx ); -#ifdef OPT_BASOP_ADD_v1 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { FOR( j = 0; j < lengthCx; ++j ) @@ -830,12 +818,9 @@ Word16 computeMixingMatrices_fx( move32(); Kx_fx_e[( i + ( j * lengthCx ) )] = tmp_e; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, tmp_e ); -#endif /* OPT_BASOP_ADD_v1 */ } } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCx * lengthCx; ++i ) { Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); @@ -843,7 +828,6 @@ Word16 computeMixingMatrices_fx( Kx_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -967,49 +951,15 @@ Word16 computeMixingMatrices_fx( /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ -#ifdef OPT_BASOP_ADD_v1 Word16 mat_mult_buffer1_fx_e; -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer1_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word16 Q_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; - set16_fx( Q_e_arr, Q_e, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); - - matrix_product_mant_exp( Kx_fx, Kx_fx_e, lengthCx, lengthCx, 1, Q_fx, Q_e_arr, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer2_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( Kx_fx, Kx_fx_e[0], lengthCx, lengthCx, 1, Q_fx, Q_e, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); matrix_diag_product_fx_2( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); matrix_product_mant_exp_fx( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e[0], lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_diag_product_fx_1( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); - - matrix_product_mant_exp( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e, lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); - - exp = mat_mult_buffer1_fx_e[0]; - move16(); - FOR( i = 1; i < lengthCy * lengthCx; i++ ) - { - if ( LT_16( exp, mat_mult_buffer1_fx_e[i] ) ) - { - exp = mat_mult_buffer1_fx_e[i]; - move16(); - } - } - - FOR( i = 0; i < lengthCy * lengthCx; i++ ) - { - mat_mult_buffer1_fx[i] = L_shr( mat_mult_buffer1_fx[i], sub( exp, mat_mult_buffer1_fx_e[i] ) ); // Q(31-exp) - move32(); - } - - mat_mult_buffer1_e = exp; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ IF( LT_16( lengthCx, lengthCy ) ) { @@ -1018,11 +968,7 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCx; move16(); -#ifdef OPT_BASOP_ADD_v1 svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); -#else /* OPT_BASOP_ADD_v1 */ - svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); -#endif /* OPT_BASOP_ADD_v1 */ } ELSE { @@ -1031,11 +977,7 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCy; move16(); -#ifdef OPT_BASOP_ADD_v1 svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); -#else /* OPT_BASOP_ADD_v1 */ - svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); -#endif /* OPT_BASOP_ADD_v1 */ } /* Actually Processing P */ @@ -1046,46 +988,25 @@ Word16 computeMixingMatrices_fx( svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, lengthCy, lengthCx ); svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); -#ifdef OPT_BASOP_ADD_v1 mat_mult_buffer1_fx_e = 0; -#else /* OPT_BASOP_ADD_v1 */ - mat_mult_buffer1_e = 0; -#endif /* OPT_BASOP_ADD_v1 */ move16(); mat_mult_buffer2_e = 0; move16(); -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, mat_mult_buffer3_fx, &mat_mult_buffer3_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, lengthCy, lengthCx, 0, - mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, - mat_mult_buffer3_fx, &mat_mult_buffer3_e ); -#endif /* OPT_BASOP_ADD_v1 */ /************************ Formulate M **********************/ -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - - matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; -#ifdef OPT_BASOP_ADD_v1 Word16 mat_mult_buffer1_fx_e1[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; set16_fx( mat_mult_buffer1_fx_e1, mat_mult_buffer1_fx_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Formulate Cr @@ -1096,15 +1017,9 @@ Word16 computeMixingMatrices_fx( Word16 Cx_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; set16_fx( Cx_e_arr, Cx_fx_e, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1 ); matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); - - matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ exp = mixing_matrix_fx_e[0]; move16(); @@ -1143,11 +1058,7 @@ Word16 computeMixingMatrices_fx( } /* Avoid Meaningless negative main diagonal elements */ -#ifdef OPT_BASOP_ADD_v1 IF( Cr_fx[i + ( i * lengthCy )] < 0 ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( Cr_fx[i + ( i * lengthCy )], exp, 0, 0 ) < 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { Cr_fx[i + ( i * lengthCy )] = 0; move32(); @@ -1209,11 +1120,7 @@ Word16 computeMixingMatrices_fx( { /* Avoid correction for very small energies, main diagonal elements of Cy_tilde_p may be negative */ -#ifdef OPT_BASOP_ADD_v1 IF( Cy_tilde_p_fx[i + ( i * lengthCy )] < 0 ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( Cy_tilde_p_fx[i + ( i * lengthCy )], mat_mult_buffer2_e, 0, 0 ) < 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1232,12 +1139,8 @@ Word16 computeMixingMatrices_fx( move16(); } -#ifdef OPT_BASOP_ADD_v1 Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, adj_e[i] ) ); IF( GT_32( adj_fx_p[i], temp ) ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], adj_e[i], 1073741824, 3 ) > 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1322,11 +1225,7 @@ Word16 computeMixingMatricesResidual_fx( Word16 mixing_matrix_e = 0, mat_mult_buffer1_e, adj_e, mat_mult_buffer3_e, mat_mult_buffer2_e; move16(); -#ifdef MSAN_FIX Word32 svd_s_buffer_fx[MAX_OUTPUT_CHANNELS] = { 0 }; -#else - Word32 svd_s_buffer_fx[MAX_OUTPUT_CHANNELS]; -#endif Word16 svd_s_buffer_e[MAX_OUTPUT_CHANNELS]; Word32 L_tmp; Word16 tmp_e; @@ -1370,9 +1269,7 @@ Word16 computeMixingMatricesResidual_fx( svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); /* Computing Ky */ -#ifdef OPT_BASOP_ADD_v1 Word16 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCy; ++i ) { FOR( j = 0; j < lengthCy; ++j ) @@ -1384,13 +1281,10 @@ Word16 computeMixingMatricesResidual_fx( move32(); Ky_fx_e[i + j * lengthCy] = tmp_e; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, tmp_e ); -#endif /* OPT_BASOP_ADD_v1 */ } } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCy * lengthCy; ++i ) { Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); @@ -1398,7 +1292,6 @@ Word16 computeMixingMatricesResidual_fx( Ky_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Decomposition of Cx @@ -1410,9 +1303,7 @@ Word16 computeMixingMatricesResidual_fx( * square root of the diagonal of Cx */ /* Computing Kx */ -#ifdef OPT_BASOP_ADD_v1 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { exp = Cx_e; @@ -1421,12 +1312,9 @@ Word16 computeMixingMatricesResidual_fx( move32(); Kx_fx_e[i] = exp; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, exp ); -#endif /* OPT_BASOP_ADD_v1 */ } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCx; ++i ) { Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); @@ -1434,7 +1322,6 @@ Word16 computeMixingMatricesResidual_fx( Kx_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Regularization of Sx @@ -1442,25 +1329,13 @@ Word16 computeMixingMatricesResidual_fx( limit_fx = Kx_fx[0]; move32(); -#ifndef OPT_BASOP_ADD_v1 - limit_e = Kx_fx_e[0]; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 1; i < lengthCx; i++ ) { -#ifdef OPT_BASOP_ADD_v1 IF( GT_32( Kx_fx[i], limit_fx ) ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( Kx_fx[i], Kx_fx_e[i], limit_fx, limit_e ) > 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { limit_fx = Kx_fx[i]; move32(); -#ifndef OPT_BASOP_ADD_v1 - limit_e = Kx_fx_e[i]; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ } } @@ -1468,11 +1343,7 @@ Word16 computeMixingMatricesResidual_fx( L_tmp = L_add( L_tmp, EPSILLON_FX ); limit_fx = L_tmp; move16(); -#ifdef OPT_BASOP_ADD_v1 limit_e = add( Kx_fx_e[0], reg_Sx_e ); -#else /* OPT_BASOP_ADD_v1 */ - limit_e = add( limit_e, reg_Sx_e ); -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -1622,15 +1493,8 @@ Word16 computeMixingMatricesResidual_fx( *-----------------------------------------------------------------*/ -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); set16_fx( mat_mult_buffer1_buff_e, mat_mult_buffer1_buff_e[0], MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - - matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; @@ -1715,12 +1579,8 @@ Word16 computeMixingMatricesResidual_fx( move32(); adj_buff_e[i] = scale; move16(); -#ifdef OPT_BASOP_ADD_v1 Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, scale ) ); IF( GT_32( adj_fx_p[i], temp ) ) // 1073741824 -> 1.0f in Q30 -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], scale, 1073741824, 3 ) > 0 ) // 1073741824 -> 1.0f in Q30 -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -2115,12 +1975,8 @@ Word16 computeMixingMatricesISM_fx( } } -#ifdef OPT_BASOP_ADD_v1 Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, temp_e[i] ) ); IF( GT_32( adj_fx[i], temp ) ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( adj_fx[i], temp_e[i], MAX_32, 2 ) > 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx[i] = MAX_32; move32(); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 292721723..4770d2193 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1266,9 +1266,7 @@ ivas_error ivas_init_decoder_fx( { return error; } -#ifdef MSAN_FIX set16_fx( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 0, CLDFB_NO_COL_MAX ); -#endif test(); IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup ) { diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index c818af237..7686a5e8a 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -511,9 +511,7 @@ static ivas_error ivas_param_ism_rendering_init_fx( { set32_fx( hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx], 0, PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX ); } -#ifdef MSAN_FIX set16_fx( hParamIsmRendering->exp_mixing_matrix_lin_old_fx, 0, CLDFB_NO_CHANNELS_MAX ); -#endif /* memory allocation for proto matrix and interpolator */ IF( ( hParamIsmRendering->proto_matrix_fx = (Word16 *) malloc( hOutSetup.nchan_out_woLFE * nchan_transport * sizeof( Word16 ) ) ) == NULL ) @@ -1535,11 +1533,7 @@ static void ivas_ism_param_dec_render_sf_fx( Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( sub( Q_real, 1 ), Q11 ) ); // Q_real-1 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( Q11, sub( Q_real, 1 ) ) ); // Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 1918ce3f3..93e8bb4eb 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -129,10 +129,8 @@ ivas_error ivas_jbm_dec_tc_fx( set_zero_fx( st_ivas->p_output_fx[n], L_FRAME48k ); st_ivas->hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n]; } -#ifdef MSAN_FIX st_ivas->hTcBuffer->no_channels = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); move16(); -#endif } Word16 ch; @@ -434,19 +432,13 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( hCPE->hCoreCoder[0] != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } IF( hCPE->hStereoDft != NULL ) { -#ifdef MSAN_FIX IF( LE_16( st_ivas->nchan_transport, 1 ) ) { st = hCPE->hCoreCoder[0]; @@ -494,9 +486,6 @@ ivas_error ivas_jbm_dec_tc_fx( } } } -#else - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); -#endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // q_dft hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; move16(); @@ -517,14 +506,10 @@ ivas_error ivas_jbm_dec_tc_fx( hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } -#ifdef MSAN_FIX FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx } -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); -#endif ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame, st_ivas->ivas_format == MC_FORMAT ); @@ -532,14 +517,10 @@ ivas_error ivas_jbm_dec_tc_fx( { Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } -#ifdef MSAN_FIX FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 } -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); -#endif scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) @@ -555,7 +536,6 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( hCPE->hStereoDft != NULL ) { -#ifdef MSAN_FIX IF( LE_16( st_ivas->nchan_transport, 1 ) ) { st = hCPE->hCoreCoder[0]; @@ -603,9 +583,6 @@ ivas_error ivas_jbm_dec_tc_fx( } } } -#else - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 -#endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; test(); @@ -971,13 +948,8 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( hCPE->hCoreCoder[0] != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q -#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -1004,24 +976,16 @@ ivas_error ivas_jbm_dec_tc_fx( hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); -#endif ivas_sba_dirac_stereo_dec_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame, 0 ); FOR( i = 0; i < 2; i++ ) { Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, negate( s ) ); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); -#endif scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 FOR( i = 0; i < CPE_CHANNELS; ++i ) @@ -1420,13 +1384,8 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -1458,23 +1417,15 @@ ivas_error ivas_jbm_dec_tc_fx( hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); -#endif ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame, 1 ); FOR( i = 0; i < 2; i++ ) { Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); -#endif // MSAN_FIX scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) @@ -1916,10 +1867,8 @@ ivas_error ivas_jbm_dec_render_fx( } } -#ifdef MSAN_FIX st_ivas->hTcBuffer->no_channels = st_ivas->hTcBuffer->nchan_buffer_full; move16(); -#endif // MSAN_FIX /*----------------------------------------------------------------* * Update combined orientation access index *----------------------------------------------------------------*/ @@ -2014,7 +1963,6 @@ ivas_error ivas_jbm_dec_render_fx( ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) { /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ -#ifdef MSAN_FIX FOR( i = 0; i < st_ivas->nchan_transport; i++ ) { FOR( j = 0; j < 16; j++ ) @@ -2025,16 +1973,6 @@ ivas_error ivas_jbm_dec_render_fx( move32(); } } -#else - FOR( i = 0; i < 15; i++ ) - { - FOR( j = 0; j < 16; j++ ) - { - st_ivas->hIsmRendererData->gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q30 -> Q29 - st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q30 -> Q29 - } - } -#endif ivas_ism2sba_sf_fx( st_ivas->hTcBuffer->tc_fx, p_output_fx, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); Word16 sba_num_chans = imult1616( add( st_ivas->hIntSetup.ambisonics_order, 1 ), add( st_ivas->hIntSetup.ambisonics_order, 1 ) ); FOR( j = 0; j < sba_num_chans; j++ ) @@ -2043,7 +1981,6 @@ ivas_error ivas_jbm_dec_render_fx( } -#ifdef MSAN_FIX FOR( i = 0; i < st_ivas->nchan_transport; i++ ) { FOR( j = 0; j < 16; j++ ) @@ -2054,16 +1991,6 @@ ivas_error ivas_jbm_dec_render_fx( move32(); } } -#else - FOR( i = 0; i < 15; i++ ) - { - FOR( j = 0; j < 16; j++ ) - { - st_ivas->hIsmRendererData->gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q29 -> Q30 - st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q29 -> Q30 - } - } -#endif } /* Binaural rendering */ @@ -2136,11 +2063,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2188,11 +2111,7 @@ ivas_error ivas_jbm_dec_render_fx( hSpar->hMdDec->Q_mixer_mat = 30; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2230,11 +2149,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/ { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism] ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism], 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2246,11 +2161,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2262,11 +2173,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2868,11 +2775,7 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available ); /* render the last subframe */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx, L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index b2a8bd30b..4c0e7fcc6 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1862,9 +1862,6 @@ void ivas_param_mc_dec_render_fx( /* format converter */ Word16 channel_active[MAX_OUTPUT_CHANNELS]; UWord16 nband_synth; -#ifndef MSAN_FIX - UWord16 nchan_out_init, nbands_to_zero; -#endif UWord32 output_Fs; Word16 tmp_q = 0; move16(); @@ -1878,10 +1875,6 @@ void ivas_param_mc_dec_render_fx( nchan_transport = st_ivas->nchan_transport; move16(); nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); -#ifndef MSAN_FIX - nchan_out_init = nchan_out_transport; - move16(); -#endif output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); @@ -1891,12 +1884,6 @@ void ivas_param_mc_dec_render_fx( { nchan_out_cldfb = BINAURAL_CHANNELS; set16_fx( channel_active, 1, nchan_out_cldfb ); -#ifndef MSAN_FIX - IF( st_ivas->hCombinedOrientationData ) - { - nchan_out_init = MAX_INTERN_CHANNELS; - } -#endif nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); } ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) @@ -1924,21 +1911,12 @@ void ivas_param_mc_dec_render_fx( /* set everything to zero that will not be decoded */ nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; move16(); -#ifdef MSAN_FIX FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) -#else - FOR( ch = 0; ch < nchan_out_init; ch++ ) -#endif { FOR( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) { -#ifdef MSAN_FIX set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); -#else - set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); - set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); -#endif } } @@ -1973,31 +1951,8 @@ void ivas_param_mc_dec_render_fx( slot_idx_start_cldfb_synth = 0; move16(); -#ifndef FIX_1009_OPT_PARAMMC_RENDER - Flag is_zero = 1; - move32(); -#endif FOR( j = 0; j < st_ivas->hParamMC->hMetadataPMC->nbands_coded; j++ ) { -#ifndef FIX_1009_OPT_PARAMMC_RENDER - is_zero = 1; - move16(); - FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_len; i++ ) - { - IF( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j][i] != 0 ) - { - is_zero = 0; - move16(); - } - } - IF( is_zero ) - { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; - move16(); - } - is_zero = 1; - move16(); -#else Flag is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_len ); { if ( is_zero != 0 ) @@ -2006,23 +1961,10 @@ void ivas_param_mc_dec_render_fx( move16(); } } -#endif IF( LT_16( st_ivas->hParamMC->band_grouping[j], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) ) { -#ifndef FIX_1009_OPT_PARAMMC_RENDER - FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len; i++ ) - { - IF( NE_32( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j][i], 0 ) ) - { - is_zero = 0; - move16(); - } - } - IF( is_zero ) -#else is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len ); if ( is_zero != 0 ) -#endif { hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[j] = 0; move16(); @@ -2247,13 +2189,8 @@ void ivas_param_mc_dec_render_fx( Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); scale_sig32( output_f_fx[ch], len, 5 - 11 ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), - imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 } @@ -2742,9 +2679,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( set_zero_fx( mat_mult_buffer1_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); set_zero_fx( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); -#ifdef MSAN_FIX set_zero_fx( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); -#endif Word16 proto_matrix_noLFE_e = 0; move16(); @@ -2941,11 +2876,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) { -#ifdef OPT_BASOP_ADD_v1 if ( Cproto_diag_fx[ch_idx1] < 0 ) -#else /* OPT_BASOP_ADD_v1 */ - if ( BASOP_Util_Cmp_Mant32Exp( Cproto_diag_fx[ch_idx1], Cproto_diag_e, 0, 0 ) < 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { Cproto_diag_fx[ch_idx1] = 0; move16(); diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index f4d6cb535..40f9f46e2 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -716,13 +716,8 @@ static void ivas_mc_paramupmix_dec_sf( Word16 noparamupmix_delay, n_samples_rendered; MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; Word16 subframeIdx, idx_in, maxBand; -#ifdef MSAN_FIX Word32 Cldfb_RealBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; Word32 Cldfb_ImagBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; -#else - Word32 Cldfb_RealBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_ImagBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif // MSAN_FIX Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -874,11 +869,7 @@ static void ivas_mc_paramupmix_dec_sf( scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q5 - Q11 ); // Q11 -> Q5 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), 0, st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q5 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); @@ -913,13 +904,8 @@ static void ivas_mc_paramupmix_dec_sf( ptr_re_fx[0] = Cldfb_RealBuffer_fx[ch][slot_idx]; // Q6 ptr_im_fx[0] = Cldfb_ImagBuffer_fx[ch][slot_idx]; // Q6 -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), hMCParamUpmix->num_freq_bands, 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), - hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); // Q6 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 4eb0ad686..7e1597749 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -84,10 +84,8 @@ ivas_error ivas_mct_dec_fx( set16_fx( x_len[0], 0, NB_DIV ); set16_fx( x_len[1], 0, NB_DIV ); Decoder_State **sts; -#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS Word32 *p_output_orig_fx[2]; Word32 synth_32_fx[CPE_CHANNELS][L_FRAME_PLUS]; -#endif Word16 synth_fx[CPE_CHANNELS][L_FRAME_PLUS]; //(Q_synth) Word32 ivas_total_brate; ivas_error error; @@ -164,7 +162,6 @@ ivas_error ivas_mct_dec_fx( /* MCT side bits decoder */ ivas_mct_side_bits_fx( hMCT, st_ivas->hCPE, nCPE, st_ivas->hCPE[0]->hCoreCoder[0], st_ivas->bfi, st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream, ivas_total_brate, nb_bits_metadata ); -#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS /* in case of switching from an SID frame (with ACELP core) to MCT, buffer of L_FRAME_PLUS samples is needed -> use synth[] as a temporary buffer */ IF( st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) { @@ -174,7 +171,6 @@ ivas_error ivas_mct_dec_fx( output_fx[n] = synth_32_fx[n]; } } -#endif FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { @@ -348,13 +344,8 @@ ivas_error ivas_mct_dec_fx( x_fx[n][0] = output_fx[n + ( cpe_id * CPE_CHANNELS )]; // Q11 x_fx[n][1] = output_fx[n + ( cpe_id * CPE_CHANNELS )] + ( L_FRAME48k / 2 ); // Q11 } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ); - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ); -#endif ivas_mdct_core_reconstruct_fx( hCPE, x_fx, synth_fx, fUseTns[cpe_id], 1, q_output, e_sig ); Word16 hdrm, sh; @@ -385,7 +376,6 @@ ivas_error ivas_mct_dec_fx( } } -#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS /* set pointers back */ test(); IF( cpe_id == 0 && st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) @@ -396,7 +386,6 @@ ivas_error ivas_mct_dec_fx( } } -#endif /*----------------------------------------------------------------* * CoreCoder Post-processing and updates @@ -409,19 +398,10 @@ ivas_error ivas_mct_dec_fx( test(); IF( ( st_ivas->sba_dirac_stereo_flag != 0 ) && ( NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) || GE_16( cpe_id, sub( nCPE, 2 ) ) ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); -#else - Copy_Scale_sig_16_32_DEPREC( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); -#endif ivas_post_proc_fx( NULL, hCPE, n, synth_fx_32[n], NULL, output_frame, 1, Q11 ); -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx_32[n], synth_fx[n], output_frame, sub( sub( 15, e_sig[n] ), Q11 ) ); // Q0 -#else - Copy_Scale_sig_32_16( synth_fx_32[n], synth_fx[n], L_FRAME48k, 0 - Q11 ); -#endif } /* Postprocessing for ACELP/MDCT core switching and synchronization */ @@ -452,11 +432,7 @@ ivas_error ivas_mct_dec_fx( { return error; } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 -#endif /* Save synthesis for HQ FEC */ Word32 output_fx_[L_FRAME48k]; Copy32( output_fx[( cpe_id * CPE_CHANNELS ) + n], output_fx_, L_FRAME48k ); // Q11 @@ -476,11 +452,7 @@ ivas_error ivas_mct_dec_fx( { IF( hCPE->hCoreCoder[n] ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 -#endif } } diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index c275820fb..0f20c1ec0 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -313,17 +313,6 @@ void mctStereoIGF_dec_fx( test(); IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) || NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) ) { -#ifndef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC - tmp = BASOP_Util_Divide1616_Scale( sts[0]->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e ); - L_spec[0] = shr( tmp, add( 15, negate( tmp_e ) ) ); - move16(); - - tmp = BASOP_Util_Divide1616_Scale( sts[0]->L_frame, nSubframes, &tmp_e ); - L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) ); - - tmp = BASOP_Util_Divide1616_Scale( sts[0]->hTcxDec->L_frameTCX, nSubframes, &tmp_e ); - L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) ); -#else Word16 shr_div, shr_k; assert( nSubframes == 1 || nSubframes == 2 ); @@ -334,7 +323,6 @@ void mctStereoIGF_dec_fx( move16(); L_frame_nSubframe = shr( sts[0]->L_frame, shr_div ); L_frameTCX_nSubframe = shr( sts[0]->hTcxDec->L_frameTCX, shr_div ); -#endif init_tcx_info_fx( sts[0], L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[0], &tcx_offsetFB[0], &L_frame[0], &L_frameTCX[0], &left_rect[0], &L_spec[0] ); @@ -344,28 +332,16 @@ void mctStereoIGF_dec_fx( decoder_tcx_IGF_stereo_fx( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, p_x_e, p_x_len, L_frame[0], left_rect[0], k, bfi, 1 /* MCT_flag */ ); // Shifting output with variable exponent back to Q12 -#ifdef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC shr_k = sub( 31 - Q12, p_x_e[0][k] ); -#endif FOR( Word16 i = 0; i < p_x_len[0][k]; i++ ) { -#ifndef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC - p_x[0][k][i] = L_shr( p_x[0][k][i], sub( 31 - Q12, p_x_e[0][k] ) ); -#else p_x[0][k][i] = L_shr( p_x[0][k][i], shr_k ); -#endif move32(); } -#ifdef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC shr_k = sub( 31 - Q12, p_x_e[1][k] ); -#endif FOR( Word16 i = 0; i < p_x_len[1][k]; i++ ) { -#ifndef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC - p_x[1][k][i] = L_shr( p_x[1][k][i], sub( 31 - Q12, p_x_e[1][k] ) ); -#else p_x[1][k][i] = L_shr( p_x[1][k][i], shr_k ); -#endif move32(); } } diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 1899c8bea..71839557a 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -684,10 +684,8 @@ void ivas_mdct_core_invQ_fx( { spectralData_tmp[k] = malloc( N_MAX * sizeof( Word32 ) ); } -#ifdef MSAN_FIX set32_fx( spectralData_tmp[0], 0, L_FRAME_MAX ); set32_fx( spectralData_tmp[1], 0, L_FRAME_MAX ); -#endif // MSAN_FIX push_wmops( "mdct_core_invQ" ); sts = hCPE->hCoreCoder; @@ -728,18 +726,8 @@ void ivas_mdct_core_invQ_fx( common_exp = s_max( sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ); -#ifdef MSAN_FIX -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 Copy_Scale_sig_16_32_no_sat( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 -#else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 - Copy_Scale_sig_16_32_DEPREC( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 -#endif -#else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_FRAME_MAX, 15 - ( common_exp - sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp1 - Copy_Scale_sig_16_32_DEPREC( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_FRAME_MAX, 15 - ( common_exp - sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp2 -#endif // MSAN_FIX sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp = sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp = common_exp; move16(); @@ -751,13 +739,8 @@ void ivas_mdct_core_invQ_fx( /* both input in same Q */ stereo_decoder_tcx_fx( hCPE->hStereoMdct, ms_mask, x_0[1], &spectralData_tmp[0], &spectralData_tmp[1], &hCPE->hStereoMdct->mdct_stereo_mode[0], sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], L_frameTCX[1], 0, sts[0]->last_core, sts[1]->last_core, 1, &q_r, &q_l ); -#ifdef MSAN_FIX Copy_Scale_sig_32_16( spectralData_tmp[0], sts[0]->hTonalMDCTConc->lastBlockData.spectralData, L_frameTCX[0], -15 ); // q_l - 15 Copy_Scale_sig_32_16( spectralData_tmp[1], sts[1]->hTonalMDCTConc->lastBlockData.spectralData, L_frameTCX[1], -15 ); // q_r - 15 -#else - Copy_Scale_sig_32_16( spectralData_tmp[0], sts[0]->hTonalMDCTConc->lastBlockData.spectralData, L_FRAME_MAX, -15 ); - Copy_Scale_sig_32_16( spectralData_tmp[1], sts[1]->hTonalMDCTConc->lastBlockData.spectralData, L_FRAME_MAX, -15 ); -#endif sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp = sub( 30, q_l ); sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp = sub( 30, q_r ); move16(); @@ -1193,13 +1176,8 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win -#ifdef MSAN_FIX Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win -#else - Scale_sig( synth_buf_fx, 3136, sub( q_win, q_syn ) ); - Scale_sig( synth_bufFB_fx, 3136, sub( q_win, q_syn ) ); -#endif Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win FOR( k = 0; k < nSubframes[ch]; k++ ) { @@ -1263,13 +1241,8 @@ void ivas_mdct_core_reconstruct_fx( move16(); Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( sub( -1, st->Q_syn ), st->hTcxDec->Q_old_syn_Overl ) ); // q_win -> Q(-1 - st->Q_syn) st->hTcxDec->Q_old_syn_Overl = sub( -1, st->Q_syn ); -#ifdef MSAN_FIX Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_syn, q_win ) ); // q_win -> q_syn Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_syn, q_win ) ); // q_win -> q_syn -#else - Scale_sig( synth_buf_fx, 3136, sub( q_syn, q_win ) ); - Scale_sig( synth_bufFB_fx, 3136, sub( q_syn, q_win ) ); -#endif Scale_sig( st->syn, M + 1, add( st->Q_syn, 2 ) ); Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn @@ -1400,11 +1373,7 @@ void ivas_mdct_core_reconstruct_fx( move16(); st->last_coder_type = st->coder_type; move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x -#else - Copy_Scale_sig_16_32_DEPREC( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x -#endif } IF( GT_16( e_sig[0], e_sig[1] ) ) @@ -1508,9 +1477,7 @@ void ivas_mdct_core_tns_ns_fx( move16(); set32_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); -#ifdef MSAN_FIX set32_fx( sns_int_scf_fx, 0, FDNS_NPTS ); -#endif /* TNS, ITF, IMDCT and updates */ diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index adee0fc91..8f7da758d 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -713,22 +713,14 @@ void ivas_omasa_dirac_rend_jbm_fx( ivas_dirac_dec_render_fx( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); -#ifdef MSAN_FIX FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ ) -#else - FOR( Word16 ind1 = 0; ind1 < MAX_CICP_CHANNELS - 1; ind1++ ) -#endif // MSAN_FIX { scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, -1 ); // Q30 -> Q29 } ivas_omasa_separate_object_render_jbm_fx( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); -#ifdef MSAN_FIX FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ ) -#else - FOR( Word16 ind1 = 0; ind1 < MAX_CICP_CHANNELS - 1; ind1++ ) -#endif // MSAN_FIX { scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, 1 ); // Q29 -> Q30 } diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 493301743..80413b21a 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -130,10 +130,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ Word32 *output_fx[] /* o : rendered time signal Q11*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 n; @@ -150,11 +146,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( channel_offset = st_ivas->nchan_ism; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_fx[channel_offset] ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_fx[channel_offset], out_len ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -240,11 +232,7 @@ ivas_error ivas_osba_render_sf_fx( v_shr( p_output[n], Q11 - Q11, output_ism[n], nSamplesAsked ); // Q11 } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 756eed60e..fc69d3919 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -479,12 +479,10 @@ ivas_error ivas_ls_setup_conversion_open_fx( set32_fx( hLsSetUpConversion->targetEnergyPrev_fx[0], 0, MAX_SFB + 2 ); set32_fx( hLsSetUpConversion->dmxEnergyPrev_fx[0], 0, MAX_SFB + 2 ); -#ifdef MSAN_FIX hLsSetUpConversion->te_prev_exp[0] = 0; hLsSetUpConversion->dmx_prev_exp[0] = 0; move16(); move16(); -#endif } /* Initialize the DMX conversion matrix */ diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 03fe4063a..c0e69b916 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -243,12 +243,6 @@ void stereo_dft_dec_core_switching_fx( move16(); } -#ifndef MSAN_FIX - IF( st->p_bpf_noise_buf_32 ) - { - Scale_sig32( st->p_bpf_noise_buf_32, L_FRAME16k, sub( *q, Q11 ) ); - } -#endif test(); test(); @@ -273,9 +267,7 @@ void stereo_dft_dec_core_switching_fx( test(); IF( st->p_bpf_noise_buf_32 && NE_16( st->core, HQ_CORE ) ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 2, 0, q, q_DFT ); } /* st->p_bpf_noise_buf not updated FOR HQ core -> skip analysis and set input memory to zero */ @@ -294,11 +286,7 @@ void stereo_dft_dec_core_switching_fx( { Word16 mem_len = NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /*Q0*/ move16(); -#ifdef MSAN_FIX Word32 mem_len_inv = mem_len_inv_tbl[( mem_len / 25 ) - 1]; -#else - Word32 mem_len_inv = mem_len_inv_tbl[( mem_len / 25 )]; -#endif move32(); Word16 qmem_len = norm_l( mem_len ); Word32 mem_len_fx = L_shl( mem_len, qmem_len ); @@ -441,9 +429,7 @@ void stereo_dft_dec_core_switching_fx( /* BPF */ IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); } } @@ -472,9 +458,7 @@ void stereo_dft_dec_core_switching_fx( /* BPF */ IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); } @@ -549,9 +533,7 @@ void stereo_dft_dec_core_switching_fx( /* BPF */ IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); } @@ -723,12 +705,6 @@ void stereo_dft_dec_core_switching_fx( } } -#ifndef MSAN_FIX - IF( st->p_bpf_noise_buf_32 ) - { - Scale_sig32( st->p_bpf_noise_buf_32, L_FRAME16k, negate( sub( *q, Q11 ) ) ); - } -#endif return; } diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index c78c51c52..6e36c7765 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -1113,7 +1113,6 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( } } -#ifdef MSAN_FIX FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) @@ -1122,19 +1121,8 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( move32(); } } -#else - FOR( b = 0; b < MASA_MAXIMUM_CODING_SUBBANDS; b++ ) - { - FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) - { - hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[0][b][m] ); - move32(); - } - } -#endif // MSAN_FIX IF( EQ_32( hQMetaData->no_directions, 2 ) ) { -#ifdef MSAN_FIX FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) @@ -1143,16 +1131,6 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( move32(); } } -#else - FOR( b = 0; b < MASA_MAXIMUM_CODING_SUBBANDS; b++ ) - { - FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) - { - hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[1][b][m] ); - move32(); - } - } -#endif // MSAN_FIX } /* Store status information for renderer use */ hQMetaData->ec_flag = 0; diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index f89e9601f..c8c3d80a5 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -349,12 +349,8 @@ ivas_error ivas_sba_dec_reconfigure_fx( test(); test(); test(); -#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH test(); IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) -#else - IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) -#endif { IF( ( hSpar->hPCA = (PCA_DEC_STATE *) malloc( sizeof( PCA_DEC_STATE ) ) ) == NULL ) { @@ -874,10 +870,6 @@ ivas_error ivas_sba_dec_render_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered Q0*/ UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render Q0*/ Word32 *output_fx[] /* o : rendered time signal Q11*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 slots_to_render, first_sf, last_sf, subframe_idx; @@ -886,15 +878,8 @@ ivas_error ivas_sba_dec_render_fx( SPAR_DEC_HANDLE hSpar; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word32 *output_f_local_fx[MAX_OUTPUT_CHANNELS]; -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Word16 output_f_local_len; -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ivas_error error; -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - output_f_local_len = out_len; - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ hSpar = st_ivas->hSpar; hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_internal = ivas_sba_get_nchan_metadata_fx( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); @@ -926,18 +911,11 @@ ivas_error ivas_sba_dec_render_fx( { Word16 n_samples_sf = imult1616( slot_size, hSpar->subframe_nbslots[subframe_idx] ); /*Q0*/ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal, output_f_local_len ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ch = 0; ch < nchan_out; ch++ ) { output_f_local_fx[ch] = output_f_local_fx[ch] + n_samples_sf; /*Q11*/ } -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - output_f_local_len = sub( output_f_local_len, n_samples_sf ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 0c7544682..50db27aa5 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -725,12 +725,10 @@ static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs( ELSE { set32_fx( hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, 0, output_frame ); -#ifdef MSAN_FIX hStereoDft->hb_nrg_subr_fx[0] = 0; move32(); hStereoDft->hb_nrg_subr_fx[1] = 0; move32(); -#endif // MSAN_FIX } hStereoDft->hb_nrg_subr_fx[0] = hStereoDft->hb_nrg_subr_fx[0]; // imult3216(hStereoDft->hb_nrg_subr_fx[0] , shr(hStereoDft->NFFT, 1)); /*hStereoDft->q_hb_nrg_subr*/ move32(); @@ -1240,12 +1238,10 @@ void ivas_sba_dirac_stereo_dec_fx( CPE_DEC_HANDLE hCPE; STEREO_DFT_DEC_DATA_HANDLE hStereoDft; -#ifdef MSAN_FIX FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { set32_fx( DFT[i], 0, STEREO_DFT_BUF_MAX ); } -#endif hSCE = st_ivas->hSCE[0]; hCPE = st_ivas->hCPE[0]; @@ -1257,18 +1253,10 @@ void ivas_sba_dirac_stereo_dec_fx( q_dft[1] = hCPE->hStereoDft->q_dft; move16(); -#ifdef MSAN_FIX Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), negate( sub( Q11, hCPE->hStereoDft->q_dft ) ) ); /*hSCE->q_prev_hb_synth_fx + hCPE->hStereoDft->q_dft - Q11*/ -#else - Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), -( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif IF( hSCE != NULL ) { -#ifdef MSAN_FIX Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), negate( sub( Q11, hCPE->hStereoDft->q_dft ) ) ); /*hSCE->q_prev_hb_synth_fx + hCPE->hStereoDft->q_dft - Q11*/ -#else - Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), -( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif // MSAN_FIX hSCE->q_prev_hb_synth_fx = hCPE->hStereoDft->q_dft; move16(); } @@ -1398,18 +1386,10 @@ void ivas_sba_dirac_stereo_dec_fx( set32_fx( output[ch], 0, output_frame ); } -#ifdef MSAN_FIX Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); /*hSCE->q_prev_hb_synth_fx + Q11 - hCPE->hStereoDft->q_dft*/ -#else - Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), ( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif IF( hSCE != NULL ) { -#ifdef MSAN_FIX Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); /*hSCE->q_prev_hb_synth_fx + Q11 - hCPE->hStereoDft->q_dft*/ -#else - Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), ( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif // MSAN_FIX hSCE->q_prev_hb_synth_fx = Q11; move16(); } diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index 461b18fbc..c3e2ad096 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -787,11 +787,7 @@ void ivas_spar_get_cldfb_gains_fx( cldfbAnalysis_ts_fx_fixed_q( ts_inout_fx, ts_re_fx, ts_im_fx, num_cldfb_bands, cldfbAnaDec0, &q_cldfb ); cldfb_reset_memory_fx( cldfbSynDec0 ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, 0, cldfbSynDec0 ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, cldfbSynDec0 ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( sample = 0; sample < stride; sample++ ) { T_fx[( ( slot * stride ) + sample )][slot] = ts_inout_fx[sample]; /*Q21*/ @@ -1161,10 +1157,8 @@ void ivas_spar_get_parameters_fx( split_band = SPAR_DIRAC_SPLIT_START_BAND; move16(); -#ifdef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS Word16 add_weight_fx = sub( MAX_WORD16, weight_fx ); Word16 add_weight_20ms_fx = sub( MAX_WORD16, weight_20ms_fx ); -#endif FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ ) @@ -1179,13 +1173,8 @@ void ivas_spar_get_parameters_fx( { IF( GT_16( hSpar->i_subframe, 3 ) ) { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS - par_mat_fx[out_ch][in_ch][spar_band] = L_add_sat( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], sub( MAX_WORD16, weight_fx ) ), - Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ) ); /*hSpar->hMdDec->Q_mixer_mat*/ -#else par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ), hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], add_weight_fx ); -#endif move32(); } ELSE @@ -1202,12 +1191,8 @@ void ivas_spar_get_parameters_fx( /* 20ms Transport channel reconstruction with matching encoder/decoder processing */ Word16 prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */ move16(); -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS - par_mat_fx[out_ch][in_ch][spar_band] = L_add_sat( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], sub( MAX_WORD16, weight_20ms_fx ) ), Mpy_32_16_1( hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ) ); /*hSpar->hMdDec->Q_mixer_mat*/ -#else par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], add_weight_20ms_fx ), hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ); /*hSpar->hMdDec->Q_mixer_mat*/ -#endif move32(); } } @@ -1367,17 +1352,10 @@ static void ivas_spar_calc_smooth_facs_fx( smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 move32(); } -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_HQ_CONSTANTS - smooth_short_avg_fx[b] = Mpy_32_16_1( smooth_short_avg_fx[b], 5461 /*(1/6 in Q15)*/ ); // Q0 - move32(); - smooth_long_avg_fx[b] = Mpy_32_16_1( smooth_long_avg_fx[b], 1639 /*(1/20 in Q15)*/ ); // Q0 - move32(); -#else smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 move32(); smooth_long_avg_fx[b] = Mpy_32_32( smooth_long_avg_fx[b], 107374182 /*(1/20 in Q31)*/ ); // Q0 move32(); -#endif /* calculate smoothing factor based on energy averages */ /* reduce factor for higher short-term energy */ @@ -1689,10 +1667,6 @@ void ivas_spar_dec_upmixer_sf_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ Word32 *output_fx[], /* o : output audio channels Q11*/ const Word16 nchan_internal /* i : number of internal channels Q0*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 cldfb_band, num_cldfb_bands, numch_in, numch_out; @@ -1793,9 +1767,7 @@ void ivas_spar_dec_upmixer_sf_fx( * Prepare CLDFB buffers *---------------------------------------------------------------------*/ -#ifdef MSAN_FIX set_zero_fx( &Pcm_tmp_fx[0][0], ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) * L_FRAME48k ); -#endif // MSAN_FIX /* set-up pointers */ IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) ) { @@ -1871,9 +1843,7 @@ void ivas_spar_dec_upmixer_sf_fx( ivas_spar_calc_smooth_facs_fx( cldfb_in_ts_re_fx[0], cldfb_in_ts_im_fx[0], q_cldfb, num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_buf_fx ); } -#ifdef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL Word16 sh_l = sub( 31, q1 ); -#endif FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { md_idx = hSpar->render_to_md_map[( ts + slot_idx_start )]; /*Q0*/ @@ -1889,18 +1859,12 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 diff = sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], diff ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/ -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] ) ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move32(); hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band] = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/ move32(); @@ -1908,68 +1872,6 @@ void ivas_spar_dec_upmixer_sf_fx( } } } -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS - FOR( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) - { - Word32 out_re_fx[IVAS_SPAR_MAX_CH]; - Word32 out_im_fx[IVAS_SPAR_MAX_CH]; - Word32 cldfb_par_fx; /*q1*/ - ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band; - - FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) - { - out_re_fx[out_ch] = 0; - move32(); - out_im_fx[out_ch] = 0; - move32(); - FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - IF( b_skip_mat[out_ch][in_ch] == 0 ) - { - IF( LT_16( cldfb_band, CLDFB_PAR_WEIGHT_START_BAND ) ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */ - { - spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; /*Q0*/ - move16(); - cldfb_par_fx = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/ - move32(); - } - ELSE - { - Word64 acc = 0; - move64(); - FOR( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) - { - /* accumulate contributions from all SPAR bands */ - acc = W_mac_32_32( acc, mixer_mat_fx[out_ch][in_ch][spar_band], bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band] ); // q1+ Q23 - } - cldfb_par_fx = W_shl_sat_l( acc, -23 ); // q1 - } - - out_re_fx[out_ch] = Madd_32_32( out_re_fx[out_ch], cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ - move32(); - out_im_fx[out_ch] = Madd_32_32( out_im_fx[out_ch], cldfb_in_ts_im_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ - move32(); - } - } - } - - /*update CLDFB data with the parameter-modified data*/ - FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) - { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); -#else - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ - move32(); -#endif - } - } -#else /* FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS */ /* Note: This version splits the cldfb band loop into 2 loops, removing some inner-loop IF_statements */ Word16 min_cldf_band = s_min( CLDFB_PAR_WEIGHT_START_BAND, num_cldfb_bands ); Word32 out_re_fx[IVAS_SPAR_MAX_CH]; @@ -2004,17 +1906,10 @@ void ivas_spar_dec_upmixer_sf_fx( /*update CLDFB data with the parameter-modified data*/ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); -#else cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ move32(); cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ move32(); -#endif } } @@ -2052,20 +1947,12 @@ void ivas_spar_dec_upmixer_sf_fx( /*update CLDFB data with the parameter-modified data*/ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); -#else cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ move32(); cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ move32(); -#endif } } -#endif /* FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS */ test(); IF( ( EQ_16( ( add( add( slot_idx_start, ts ), 1 ) ), hSpar->num_slots ) ) || ( NE_16( ( shr( md_idx, 2 ) /* md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME */ ), ( hSpar->render_to_md_map[( ( slot_idx_start + ts ) + 1 )] / JBM_CLDFB_SLOTS_IN_SUBFRAME /*It's value is 4*/ ) ) ) ) { @@ -2080,12 +1967,6 @@ void ivas_spar_dec_upmixer_sf_fx( } IF( LT_16( split_band, IVAS_MAX_NUM_BANDS ) ) { -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], hSpar->hMdDec->mixer_mat_prev_fx[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[4][0][0], hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { @@ -2093,7 +1974,6 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( b = 0; b < num_spar_bands; b++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE hSpar->hMdDec->mixer_mat_prev_fx[0][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b]; hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b]; hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[3][out_ch][in_ch][b]; @@ -2102,7 +1982,6 @@ void ivas_spar_dec_upmixer_sf_fx( move32(); move32(); move32(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][( b + ( md_sf * IVAS_MAX_NUM_BANDS ) )]; /*hSpar->hMdDec->Q_mixer_mat*/ move32(); @@ -2156,26 +2035,10 @@ void ivas_spar_dec_upmixer_sf_fx( IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) && !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) { -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state-6*/ - st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); - move16(); - Scale_sig32( output_fx[ch], out_len, -6 ); /*Q5*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, st_ivas->cldfbSynDec[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( output_fx[ch], out_len, 6 ); /*Q11*/ - Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, 6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state+6*/ - st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = add( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } idx_in = add( idx_in, 1 ); @@ -2187,26 +2050,10 @@ void ivas_spar_dec_upmixer_sf_fx( /* CLDFB to time synthesis (overwrite mixer output) */ FOR( out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) { -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx, st_ivas->cldfbSynDec[out_ch]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state-6*/ - st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state, 6 ); - move16(); - Scale_sig32( output_fx[out_ch], out_len, -6 ); /*Q5*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[out_ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( output_fx[out_ch], out_len, 6 ); /*Q11*/ - Scale_sig32( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx, st_ivas->cldfbSynDec[out_ch]->p_filter_length, 6 ); /*st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state+6*/ - st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state = add( st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state, 6 ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 5704f4f60..429a99ca4 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -961,9 +961,7 @@ typedef struct decoder_tc_buffer_structure Word32 *tc_buffer_fx; /* the buffer itself */ Word16 tc_buff_len; /*stores memory length of tc buffer*/ Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ // VE2SB: TBV -#ifdef MSAN_FIX Word16 no_channels; /*Stores no of channels in tc_fx with values*/ -#endif Word16 q_tc_fx; TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 223860db0..478f96dc1 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -683,12 +683,8 @@ static void stereo_dft_generate_comfort_noise_fx( factor = L_min( L_add( L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ), W_extract_l( W_mult0_32_32( Mpy_32_16_1( L_sub( factor, L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ) ), ONE_BY_MAX_K ), hStereoCng->xfade_frame_counter ) ) ), factor ); /* q_div */ FOR( ; j <= hFdCngCom->part[k]; j++ ) { -#ifdef FIX_ISSUE_1218 /* NOTE: saturation is added here as part of issue 1218 fix. After rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ hFdCngCom->cngNoiseLevel[j] = L_shl_sat( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ -#else - hFdCngCom->cngNoiseLevel[j] = L_shl( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ -#endif move32(); } } diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 9c1b488cb..324f2b7f3 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -96,9 +96,7 @@ void stereo_dft_dec_reset_fx( { Word16 i; Word16 j, b; -#ifdef MSAN_FIX set_zero_fx( hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ) ); -#endif /*Configuration*/ set16_fx( hStereoDft->prm_res, hStereoDft->hConfig->prm_res, STEREO_DFT_DEC_DFT_NB ); @@ -122,25 +120,13 @@ void stereo_dft_dec_reset_fx( set16_fx( hStereoDft->res_pred_index_previous, 0, STEREO_DFT_BAND_MAX ); -#ifdef MSAN_FIX FOR( i = 0; i < STEREO_DFT_BAND_MAX * 2; i++ ) { hStereoDft->res_gains_ind_fx[0][i] = 1006632960; /* 15.0f in Q26 */ move32(); } -#else - FOR( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) - { - hStereoDft->res_gains_ind_fx[0][i] = 1006632960; /* 15.0f in Q26 */ - move32(); - } -#endif -#ifdef MSAN_FIX set32_fx( hStereoDft->res_gains_ind_fx[1], 0, STEREO_DFT_BAND_MAX * 2 ); -#else - set32_fx( hStereoDft->res_gains_ind_fx[1], 0, STEREO_DFT_BAND_MAX ); -#endif /*residual coding*/ set16_fx( hStereoDft->res_cod_mode, hStereoDft->hConfig->res_cod_mode, STEREO_DFT_DEC_DFT_NB ); @@ -260,7 +246,6 @@ void stereo_dft_dec_reset_fx( move32(); hStereoDft->frame_sid_nodata = 0; move16(); -#ifdef MSAN_FIX FOR( b = 0; b < 2 * IVAS_MAX_NUM_BANDS; b++ ) { FOR( i = 0; i < 2; i++ ) @@ -272,19 +257,6 @@ void stereo_dft_dec_reset_fx( } } } -#else - FOR( b = 0; b < hStereoDft->nbands; b++ ) - { - FOR( i = 0; i < 2; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - hStereoDft->mixer_mat_smooth_fx[i][j][b] = 0; - move32(); - } - } - } -#endif hStereoDft->first_frame = 1; move16(); hStereoDft->g_L_prev_fx = 0; @@ -429,9 +401,7 @@ ivas_error stereo_dft_dec_create_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TCX-LTP handle\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hStereoDft_loc->hb_nrg_subr_fx, STEREO_DFT_NBDIV ); /*Setting hb_nrg_subr_fx to zero*/ -#endif // MSAN_FIX hStereoDft_loc->hConfig->force_mono_transmission = 0; move16(); @@ -1436,11 +1406,7 @@ void stereo_dft_dec_res_fx( move32(); } } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ -#else - Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ -#endif IF( res_bpf_flag ) { v_sub_32( output, bpf_error_signal_8k, output, L_FRAME8k ); @@ -1451,20 +1417,12 @@ void stereo_dft_dec_res_fx( set16_fx( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ -#else - Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ -#endif } ELSE { /* This step is needed to ensure output is properly populated with scaled values in all cases*/ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ -#else - Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ -#endif } return; diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index 694aad0b4..73cf9ccd0 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -59,13 +59,8 @@ void stereo_tca_dec_fx( ) { /* Buffers, input Left and right channels @ input_Fs*/ -#ifdef MSAN_FIX Word32 bufChanL_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k] = { 0 }; Word32 bufChanR_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k] = { 0 }; -#else - Word32 bufChanL_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k]; - Word32 bufChanR_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k]; -#endif Word32 *ptrChanL_fx, *ptrChanR_fx; Word32 *target_fx; Word16 target_idx, prevNCShift, currentNCShift, l_shift_adapt; diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 04aeccbb5..1c2ecffaf 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -234,12 +234,10 @@ void stereo_icBWE_dec_fx( ELSE { set32_fx( hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, 0, output_frame ); -#ifdef MSAN_FIX hCPE->hStereoDft->hb_nrg_subr_fx[0] = 0; move32(); hCPE->hStereoDft->hb_nrg_subr_fx[1] = 0; move32(); -#endif // MSAN_FIX } hCPE->hStereoDft->hb_nrg_subr_fx[0] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[0], shl( shr( hCPE->hStereoDft->NFFT, 1 ), 6 ) ) ); // 2 * (Qsynth + SynthRef_shift) - 40 // 2 * (Qx + SynthRef_shift) - 31 - 15 move32(); @@ -719,11 +717,7 @@ void stereo_icBWE_dec_fx( { IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { -#ifdef FIX_TMP_714 tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 -#else - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 -#endif tmp = mult_r( tmp, gsMapping_fx ); // Q14 tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) @@ -819,11 +813,7 @@ void stereo_icBWE_dec_fx( hStereoICBWE->prev_Q_fsout = tmp; move16(); } -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, sub( *Q_syn, add( 1, tmp ) ) ); -#else Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); /* Qsyn - 1 */ -#endif *Q_syn = sub( *Q_syn, 1 ); @@ -886,11 +876,7 @@ void stereo_icBWE_dec_fx( { IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { -#ifdef FIX_TMP_714 tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 -#else - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 -#endif tmp = mult_r( tmp, gsMapping_fx ); // Q14 tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index a6b350d33..cd7e92f71 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -540,13 +540,8 @@ void stereo_mdct_core_dec_fx( move16(); } } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ -#endif ivas_mdct_core_reconstruct_fx( hCPE, x_fx, signal_outFB_tmp_fx, fUseTns, 0, Q11, e_sigFB ); Copy32( signal_out_tmp_fx[0], signal_out_fx[0], L_FRAME48k ); /* Q11 */ diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 5b1378a89..5248839f5 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -904,13 +904,8 @@ void updateBuffersForDmxMdctStereo_fx( move16(); sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 ); move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 -#endif } return; diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 6c2ad055c..1a6ea257b 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -197,9 +197,7 @@ static ivas_error allocate_CoreCoder_fx( } hf_synth_init_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->cldfbAna == NULL ) @@ -2153,21 +2151,13 @@ void stereo_td2dft_update_fx( /* update buffers used for fading when switching to DFT Stereo */ v_add_fx( sts[0]->hHQ_core->old_out_LB_fx32 + nsLB, sts[1]->hHQ_core->old_out_LB_fx32 + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, STEREO_MDCT2DFT_FADE_LEN_48k, old_outLB_len ); -#ifndef MSAN_FIX - for ( i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) -#else FOR( i = 0; i < old_outLB_len; i++ ) -#endif { hCPE->old_outLB_mdct_fx[i] = L_shr( hCPE->old_outLB_mdct_fx[i], 1 ); /* Q11 */ move32(); } v_add_fx( sts[0]->hHQ_core->old_out_fx32 + ns, sts[1]->hHQ_core->old_out_fx32 + ns, hCPE->old_out_mdct_fx, old_out_len ); /* exp(exp_old_out) */ -#ifndef MSAN_FIX - for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) -#else FOR( i = 0; i < old_out_len; i++ ) -#endif { hCPE->old_out_mdct_fx[i] = L_shr( hCPE->old_out_mdct_fx[i], 1 ); /* q_old_out_mdct */ move32(); diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 1467687d8..dd9859504 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -70,11 +70,7 @@ static void biDiagonalReductionLeft_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ @@ -88,11 +84,7 @@ static void biDiagonalReductionLeft_fx( static void biDiagonalReductionRight_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC, /* Q0 */ @@ -105,11 +97,7 @@ static void biDiagonalReductionRight_fx( static void singularVectorsAccumulationLeft_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) as Input, Q31 as output */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC /* Q0 */ @@ -119,16 +107,8 @@ static void singularVectorsAccumulationRight_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* singularVectors_e */ Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* singularVectors_e */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_e, -#else Word16 *secDiag_e, -#endif const Word16 nChannelsC /* Q0 */ ); @@ -168,7 +148,6 @@ static void ApplyRotation_fx( const Word16 nChannels /* Q0 */ ); -#ifdef FIX_1010_OPT_GIVENS_INV static void GivensRotation2_fx( const Word32 x, /* exp(x_e) */ const Word16 x_e, @@ -178,7 +157,6 @@ static void GivensRotation2_fx( Word32 *resultInv, Word16 *out_e, Word16 *outInv_e ); -#endif static Word32 GivensRotation_fx( const Word32 x, /* exp(x_e) */ @@ -306,11 +284,7 @@ Word16 svd_fx( Word16 lengthSingularValues; Word16 errorMessage, condition; Word32 secDiag_fx[MAX_OUTPUT_CHANNELS]; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_fx_e = 0; -#else Word16 secDiag_fx_e[MAX_OUTPUT_CHANNELS]; -#endif move16(); Word32 eps_x_fx = 0, temp_fx; move16(); @@ -320,10 +294,6 @@ Word16 svd_fx( push_wmops( "svd_fx" ); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - set32_fx( secDiag_fx, 0, MAX_OUTPUT_CHANNELS ); - set16_fx( singularValues_fx_e, 0, MAX_OUTPUT_CHANNELS ); -#endif /* Collecting Values */ FOR( iCh = 0; iCh < nChannelsL; iCh++ ) @@ -336,22 +306,14 @@ Word16 svd_fx( } /* Householder reduction */ -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - HouseholderReduction_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, InputMatrix_e, singularValues_fx_e, &secDiag_fx_e, nChannelsL, nChannelsC, &eps_x_fx, &eps_x_fx_e ); -#else HouseholderReduction_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, InputMatrix_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, &eps_x_fx, &eps_x_fx_e ); -#endif /* Set extremely small values to zero if needed */ // flushToZeroArray(singularValues, max_length); // flushToZeroMat(singularVectors_Left, nChannelsL, nChannelsL); // flushToZeroMat(singularVectors_Right, nChannelsC, nChannelsC); /* BidagonalDiagonalisation */ -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - errorMessage = BidagonalDiagonalisation_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, singularValues_fx_e, &secDiag_fx_e, nChannelsL, nChannelsC, eps_x_fx, eps_x_fx_e ); /* Q0 */ -#else errorMessage = BidagonalDiagonalisation_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, eps_x_fx, eps_x_fx_e ); /* Q0 */ -#endif /* Sort the singular values descending order */ lengthSingularValues = s_min( nChannelsL, nChannelsC ); /* Q0 */ @@ -423,11 +385,7 @@ static Word16 BidagonalDiagonalisation_fx( Word32 singularVectors_Right_fx[][MAX_OUTPUT_CHANNELS], /* i/o: right singular vectors (V) singularValues_fx_e*/ Word32 secDiag_fx[MAX_OUTPUT_CHANNELS], /* i/o: secDiag_fx_e*/ Word16 singularValues_fx_e[MAX_OUTPUT_CHANNELS], /* i/o: singular values vector (S) */ -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 *secDiag_fx_e, /* i/o: */ -#else Word16 *secDiag_new_e, /* i/o: */ -#endif const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ const Word32 eps_x, /* i : eps_x_e*/ @@ -441,9 +399,7 @@ static Word16 BidagonalDiagonalisation_fx( move16(); move16(); Word16 temp_exp; -#ifdef FIX_1010_OPT_NORM_NOSAT Word16 temp_exp2; -#endif Word32 g = 0; move16(); Word16 g_e = 0; @@ -451,14 +407,8 @@ static Word16 BidagonalDiagonalisation_fx( Word16 convergence, iteration, found_split; Word16 error = 0; move16(); -#ifdef FIX_1010_OPT_GIVENS_INV Word32 temp; -#endif Word16 singularValues_new_e[MAX_OUTPUT_CHANNELS]; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_new_e[MAX_OUTPUT_CHANNELS]; - set16_fx( secDiag_new_e, *secDiag_fx_e, MAX_OUTPUT_CHANNELS ); -#endif Copy( singularValues_fx_e, singularValues_new_e, MAX_OUTPUT_CHANNELS ); FOR( iCh = nChannelsC - 1; iCh >= 0; iCh-- ) /* nChannelsC */ @@ -527,46 +477,17 @@ static Word16 BidagonalDiagonalisation_fx( c = singularValues_fx[kCh]; /* exp(singularValues_new_e) */ c_e = singularValues_new_e[kCh]; -#ifdef FIX_1010_OPT_GIVENS_INV GivensRotation2_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_fx[kCh], &temp, &singularValues_new_e[kCh], &temp_exp ); /* exp(singularValues_new_e) */ c = Mpy_32_32( c, temp ); c_e = add( c_e, temp_exp ); -#else - singularValues_fx[kCh] = GivensRotation_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_new_e[kCh] ); /* exp(singularValues_new_e) */ - c = BASOP_Util_Divide3232_Scale_cadence( c, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (c_e - singularValues_new_e)) */ - c_e = add( temp_exp, sub( c_e, singularValues_new_e[kCh] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( c_e > 0 ) - { - c = L_shl_sat( c, c_e ); // Q31 - c_e = 0; - move16(); - } -#else temp_exp2 = norm_l( c ); c = L_shl( c, temp_exp2 ); c_e = sub( c_e, temp_exp2 ); -#endif -#ifdef FIX_1010_OPT_GIVENS_INV s = Mpy_32_32( -g, temp ); s_e = add( g_e, temp_exp ); -#else - s = BASOP_Util_Divide3232_Scale_cadence( -g, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (g_e - singularValues_new_e))*/ - s_e = add( temp_exp, sub( g_e, singularValues_new_e[kCh] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( s_e > 0 ) - { - s = L_shl_sat( s, s_e ); // Q31 - s_e = 0; - move16(); - } -#else temp_exp2 = norm_l( s ); s = L_shl( s, temp_exp2 ); s_e = sub( s_e, temp_exp2 ); -#endif ApplyRotation_fx( singularVectors_Left_fx, c, c_e, s, s_e, 0, x11_e, 0, x12_e, &f1, &f1_e, &f2, &f2_e, kCh, split, nChannelsL ); /* nChannelsL */ } } @@ -617,24 +538,6 @@ static Word16 BidagonalDiagonalisation_fx( // rescaling block Copy( singularValues_new_e, singularValues_fx_e, MAX_OUTPUT_CHANNELS ); -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 max_exp = -31; - move16(); - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - if ( secDiag_fx[iCh] ) - { - max_exp = s_max( max_exp, secDiag_new_e[iCh] ); - } - } - *secDiag_fx_e = max_exp; - move16(); - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - secDiag_fx[iCh] = L_shr_r( secDiag_fx[iCh], sub( *secDiag_fx_e, secDiag_new_e[iCh] ) ); /* exp(secDiag_fx_e) */ - move32(); - } -#endif return ( error ); } @@ -658,13 +561,9 @@ static void ApplyQRTransform_fx( const Word16 nChannelsC /* i : number of columns in the matrix to be decomposed Q0*/ ) { -#ifdef FIX_1010_OPT_GIVENS_INV Word32 temp; Word16 temp_e; -#endif -#ifdef FIX_1010_OPT_NORM_NOSAT Word16 temp_norm_e; -#endif Word16 ch, split; Word32 d = 0, g = 0, r = 0, x_ii = 0, x_split = 0, x_kk = 0, mu = 0, aux = 0; move32(); @@ -767,47 +666,17 @@ static void ApplyQRTransform_fx( g = Mpy_32_32( c, secDiag[ch + 1] ); /* exp(c_e + secDiag_e) */ g_e = add( c_e, secDiag_e[ch + 1] ); -#ifdef FIX_1010_OPT_GIVENS_INV GivensRotation2_fx( d, d_e, r, r_e, &secDiag[ch], &temp, &secDiag_e[ch], &temp_e ); /* exp(secDiag_e) */ c = Mpy_32_32( d, temp ); c_e = add( temp_e, d_e ); -#else - secDiag[ch] = GivensRotation_fx( d, d_e, r, r_e, &secDiag_e[ch] ); /* exp(secDiag_e) */ - move32(); - c = BASOP_Util_Divide3232_Scale_cadence( d, maxWithSign_fx( secDiag[ch] ), &c_e ); /* exp(c_e + (d_e + secDiag_e)) */ - c_e = add( c_e, sub( d_e, secDiag_e[ch] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( c_e > 0 ) - { - c = L_shl_sat( c, c_e ); // Q31 - c_e = 0; - move16(); - } -#else temp_norm_e = norm_l( c ); c = L_shl( c, temp_norm_e ); c_e = sub( c_e, temp_norm_e ); -#endif -#ifdef FIX_1010_OPT_GIVENS_INV s = Mpy_32_32( r, temp ); s_e = add( r_e, temp_e ); -#else - s = BASOP_Util_Divide3232_Scale_cadence( r, maxWithSign_fx( secDiag[ch] ), &s_e ); /* exp(s_e + (r_e - sec_Diag_e))*/ - s_e = add( s_e, sub( r_e, secDiag_e[ch] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( s_e > 0 ) - { - s = L_shl_sat( s, s_e ); // Q31 - s_e = 0; - move16(); - } -#else temp_norm_e = norm_l( s ); s = L_shl( s, temp_norm_e ); s_e = sub( s_e, temp_norm_e ); -#endif r = Mpy_32_32( s, singularValues[ch + 1] ); /* exp(r_e + secDiag_e) */ r_e = add( s_e, singularValues_e[ch + 1] ); x_split = Mpy_32_32( c, singularValues[ch + 1] ); /* exp(c_e + secDiag_e) */ @@ -821,48 +690,21 @@ static void ApplyQRTransform_fx( // ApplyRotation(singularVectors_Right, c, s, x_ii, aux, &d, &g, ch + 1, ch, nChannelsC); ApplyRotation_fx( singularVectors_Right, c, c_e, s, s_e, x_ii, x_ii_e, aux, aux_e, &d, &d_e, &g, &g_e, ch + 1, ch, nChannelsC ); -#ifdef FIX_1010_OPT_GIVENS_INV GivensRotation2_fx( d, d_e, r, r_e, &singularValues[ch], &aux, &singularValues_e[ch], &aux_e ); /* exp(singularValues_e) */ -#else - singularValues[ch] = GivensRotation_fx( d, d_e, r, r_e, &singularValues_e[ch] ); /* exp(singularValues_e) */ - move32(); -#endif IF( singularValues[ch] != 0 ) { -#ifndef FIX_1010_OPT_GIVENS_INV - aux = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, singularValues[ch], &aux_e ); /* exp(aux_e + (1 - singularValues_e)) */ - aux_e = add( aux_e, sub( 1, singularValues_e[ch] ) ); -#endif c = Mpy_32_32( d, aux ); /* exp(d_e + aux_e) */ c_e = add( d_e, aux_e ); -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( c_e > 0 ) - { - c = L_shl_sat( c, c_e ); // Q31 - c_e = 0; - move16(); - } -#else temp_norm_e = norm_l( c ); c = L_shl( c, temp_norm_e ); c_e = sub( c_e, temp_norm_e ); -#endif s = Mpy_32_32( r, aux ); /* exp(r_e + aux_e) */ s_e = add( r_e, aux_e ); -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( s_e > 0 ) - { - s = L_shl_sat( s, s_e ); // Q31 - s_e = 0; - move16(); - } -#else temp_norm_e = norm_l( s ); s = L_shl( s, temp_norm_e ); s_e = sub( s_e, temp_norm_e ); -#endif } // ApplyRotation(singularVectors_Left, c, s, g, x_split, &d, &x_ii, ch + 1, ch, nChannelsL); @@ -915,7 +757,6 @@ static void ApplyRotation_fx( *g = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), add( c_e, x12_e ), Mpy_32_32( L_negate( s ), x11 ), add( s_e, x11_e ), g_e ); /* exp(g_e) */ move32(); -#ifdef SVD_WMOPS_OPT Word16 c_q = sub( 31, c_e ); Word16 s_q = sub( 31, s_e ); Word32 op1, op2; @@ -957,42 +798,6 @@ static void ApplyRotation_fx( singularVector[ch][currentIndex1] = W_sat_l( temp ); // Q(singularVector) move32(); } -#else -#ifndef FIX_MINOR_SVD_WMOPS_MR1010X - FOR( ch = 0; ch < nChannels; ch++ ) - { - x11 = singularVector[ch][currentIndex2]; - move32(); - x12 = singularVector[ch][currentIndex1]; - move32(); - singularVector[ch][currentIndex2] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ - move32(); - singularVector[ch][currentIndex2] = L_shl_sat( singularVector[ch][currentIndex2], temp_exp ); /* exp(temp_exp) */ - move32(); - singularVector[ch][currentIndex1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( L_negate( s ), x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ - move32(); - singularVector[ch][currentIndex1] = L_shl_sat( singularVector[ch][currentIndex1], temp_exp ); /* exp(temp_exp) */ - move32(); - } -#else - Word32 s_neg = L_negate( s ); - Word32 temp; - FOR( ch = 0; ch < nChannels; ch++ ) - { - x11 = singularVector[ch][currentIndex2]; - move32(); - x12 = singularVector[ch][currentIndex1]; - move32(); - temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ - singularVector[ch][currentIndex2] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ - move32(); - temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( s_neg, x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ - singularVector[ch][currentIndex1] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ - move32(); - } - -#endif -#endif return; } @@ -1024,7 +829,6 @@ static void HouseholderReduction_fx( Word16 sig_x_fx_e = 0; move16(); -#ifdef FIX_1010_OPT_SINGLE_RESCALE Word16 iCh, jCh; Word16 singularVectors_Left_fx_e[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; FOR( jCh = 0; jCh < nChannelsL; jCh++ ) @@ -1035,25 +839,15 @@ static void HouseholderReduction_fx( move16(); } } -#endif /* Bidiagonal Reduction for every channel */ FOR( nCh = 0; nCh < nChannelsC; nCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - biDiagonalReductionLeft_fx( singularVectors_Left_fx, singularValues_fx, secDiag_fx, &singularVectors_Left_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); - biDiagonalReductionRight_fx( singularVectors_Left_fx, secDiag_fx, &singularVectors_Left_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); -#else biDiagonalReductionLeft_fx( singularVectors_Left_fx, singularValues_fx, secDiag_fx, singularVectors_Left_fx_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); biDiagonalReductionRight_fx( singularVectors_Left_fx, secDiag_fx, singularVectors_Left_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); -#endif Word16 L_temp_e; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word32 L_temp = BASOP_Util_Add_Mant32Exp( L_abs( singularValues_fx[nCh] ), singularValues_fx_e[nCh], L_abs( secDiag_fx[nCh] ), *secDiag_fx_e, &L_temp_e ); /* exp(L_temp_e) */ -#else Word32 L_temp = BASOP_Util_Add_Mant32Exp( L_abs( singularValues_fx[nCh] ), singularValues_fx_e[nCh], L_abs( secDiag_fx[nCh] ), secDiag_fx_e[nCh], &L_temp_e ); /* exp(L_temp_e) */ -#endif IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_temp, L_temp_e, *eps_x_fx, *eps_x_fx_e ), 1 ) ) { *eps_x_fx = L_temp; /* exp(L_temp_e) */ @@ -1064,19 +858,10 @@ static void HouseholderReduction_fx( } /* SingularVecotr Accumulation */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_e, *secDiag_fx_e, nChannelsC ); - singularVectorsAccumulationLeft_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Left_e, singularValues_fx_e, nChannelsL, nChannelsC ); -#else -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_fx_e, *secDiag_fx_e, nChannelsC ); -#else singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_fx_e, secDiag_fx_e, nChannelsC ); -#endif singularVectorsAccumulationLeft_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Left_fx_e, singularValues_fx_e, nChannelsL, nChannelsC ); -#endif return; } @@ -1091,11 +876,7 @@ static void biDiagonalReductionLeft_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ @@ -1111,39 +892,11 @@ static void biDiagonalReductionLeft_fx( Word16 norm_x_e, f_e, r_e; Word32 L_temp; Word16 L_temp_e; -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 sing_exp[MAX_OUTPUT_CHANNELS]; - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; - FOR( jCh = 0; jCh < MAX_OUTPUT_CHANNELS; jCh++ ) - { - set16_fx( sing_exp2[jCh], *singularVectors_e, MAX_OUTPUT_CHANNELS ); - } -#endif secDiag[currChannel] = Mpy_32_32( *sig_x, *g ); /* exp(sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - // rescaling block - IF( GT_16( *sig_x_e, *secDiag_e ) ) - { - FOR( Word16 i = 0; i < MAX_OUTPUT_CHANNELS; i++ ){ - IF( NE_16( i, currChannel ) ){ - secDiag[i] = L_shl( secDiag[i], sub( *secDiag_e, *sig_x_e ) ); /* sig_x_e */ - move32(); - } -} -*secDiag_e = *sig_x_e; -move16(); -} -ELSE IF( LT_16( *sig_x_e, *secDiag_e ) ) -{ - secDiag[currChannel] = L_shr_r( secDiag[currChannel], sub( *secDiag_e, *sig_x_e ) ); /* exp(secDiag_e) */ - move32(); -} -#else secDiag_e[currChannel] = *sig_x_e; move16(); -#endif /* Setting values to 0 */ ( *sig_x ) = 0; @@ -1158,54 +911,26 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), *singularVectors_e, sig_x_e ); /* exp(sig_x_e) */ -#else ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ -#endif } IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ { -#ifdef FIX_1010_OPT_DIV Word16 invVal_e; Word32 invVal; invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); -#endif norm_x = 0; move32(); norm_x_e = 0; move16(); FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_DIV -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[jCh][currChannel] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[jCh][currChannel], maxWithSign_fx( *sig_x ), &sing_exp[jCh] ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ - move32(); - sing_exp[jCh] = add( sing_exp[jCh], sub( *singularVectors_e, *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else - singularVectors[jCh][currChannel] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[jCh][currChannel], maxWithSign_fx( *sig_x ), &L_temp_e ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ - move32(); - singularVectors2_e[jCh][currChannel] = add( L_temp_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#else Word16 temp_e = norm_l( singularVectors[jCh][currChannel] ); singularVectors[jCh][currChannel] = Mpy_32_32( L_shl( singularVectors[jCh][currChannel], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp[jCh] = sub( add( invVal_e, sub( *singularVectors_e, *sig_x_e ) ), temp_e ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else singularVectors2_e[jCh][currChannel] = sub( add( invVal_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ), temp_e ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#endif } IF( GT_16( norm_x_e, 0 ) ) { @@ -1219,38 +944,18 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ L_temp = Sqrt32( norm_x, &L_temp_e ); L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); -#ifndef FIX_MINOR_SVD_WMOPS_MR1010X - IF( singularVectors[currChannel][idx] >= 0 ) - { - ( *g ) = L_negate( L_temp ); - move32(); - } - ELSE - { - ( *g ) = L_negate( L_negate( L_temp ) ); - move32(); - } -#else if ( singularVectors[currChannel][idx] >= 0 ) { L_temp = L_negate( L_temp ); } ( *g ) = L_temp; move32(); -#endif -#ifndef FIX_1010_OPT_SINGLE_RESCALE - r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[currChannel], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ - singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], sing_exp[currChannel], -( *g ), 0, &sing_exp[currChannel] ); /* sing_exp */ -#else r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ -#endif move32(); -#ifdef FIX_1010_OPT_DIV invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); -#endif FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { @@ -1260,28 +965,15 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ move16(); FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( sing_exp[jCh], *singularVectors_e ), &norm_x_e ); /* exp(norm_x_e) */ -#else norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( singularVectors2_e[jCh][currChannel], singularVectors2_e[jCh][iCh] ), &norm_x_e ); /* exp(norm_x_e) */ -#endif } -#ifndef FIX_1010_OPT_DIV - f = BASOP_Util_Divide3232_Scale_cadence( norm_x, maxWithSign_fx( r ), &f_e ); /* f_e + (norm_x_e - r_e) */ - f_e = add( f_e, sub( norm_x_e, r_e ) ); -#else f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ f_e = add( invVal_e, sub( norm_x_e, r_e ) ); -#endif FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], *singularVectors_e, Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, sing_exp[jCh] ), &sing_exp2[jCh][iCh] ); /* exp( sing_exp2) */ -#else singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], singularVectors2_e[jCh][iCh], Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, singularVectors2_e[jCh][currChannel] ), &singularVectors2_e[jCh][iCh] ); -#endif move32(); } } @@ -1291,37 +983,10 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ { singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp2[jCh][currChannel] = add( sing_exp[jCh], *sig_x_e ); -#else singularVectors2_e[jCh][currChannel] = add( singularVectors2_e[jCh][currChannel], *sig_x_e ); -#endif move16(); } -#ifndef FIX_1010_OPT_SINGLE_RESCALE - // rescaling block - Word16 exp_max = *singularVectors_e; - move16(); - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsL; jCh++ ) - { - exp_max = s_max( exp_max, sing_exp2[jCh][iCh] ); - } - } - - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsL; jCh++ ) - { - singularVectors[jCh][iCh] = L_shr_r( singularVectors[jCh][iCh], sub( exp_max, sing_exp2[jCh][iCh] ) ); /* exp(exp_max) */ - move32(); - } - } - *singularVectors_e = exp_max; - move16(); -#endif } // rescaling block @@ -1343,16 +1008,8 @@ return; static void biDiagonalReductionRight_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_exp[]) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 *secDiag_e, -#else Word16 *secDiag_exp, -#endif const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC, /* Q0 */ const Word16 currChannel, /* Q0 */ @@ -1364,22 +1021,8 @@ static void biDiagonalReductionRight_fx( Word16 iCh, jCh, idx; Word32 norm_x, r; Word16 norm_x_e, r_e; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_exp[MAX_OUTPUT_CHANNELS]; -#endif Word32 L_temp; Word16 L_temp_e; -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 sing_exp[MAX_OUTPUT_CHANNELS]; - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; - FOR( jCh = 0; jCh < MAX_OUTPUT_CHANNELS; jCh++ ) - { - set16_fx( sing_exp2[jCh], *singularVectors_e, MAX_OUTPUT_CHANNELS ); - } -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - set16_fx( secDiag_exp, *secDiag_e, MAX_OUTPUT_CHANNELS ); -#endif /* Setting values to 0 */ ( *sig_x ) = 0; @@ -1393,11 +1036,7 @@ static void biDiagonalReductionRight_fx( FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[currChannel][jCh] ), *singularVectors_e, sig_x_e ); /* exp(sig_x_e) */ -#else ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[currChannel][jCh] ), singularVectors2_e[currChannel][jCh], sig_x_e ); /* exp(sig_x_e) */ -#endif } IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ @@ -1407,41 +1046,17 @@ static void biDiagonalReductionRight_fx( norm_x_e = 0; move16(); -#ifdef FIX_1010_OPT_DIV Word16 invVal_e, temp_e; Word32 invVal; invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); -#endif FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /*nChannelsC */ { -#ifndef FIX_1010_OPT_DIV -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[currChannel][jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( *sig_x ), &sing_exp[jCh] ); /* exp(sing_exp + (singularVectors_e - sig_x_e)) */ - move32(); - sing_exp[jCh] = add( sing_exp[jCh], sub( *singularVectors_e, *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else - singularVectors[currChannel][jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( *sig_x ), &L_temp_e ); /* exp(sing_exp + (singularVectors_e - sig_x_e)) */ - move32(); - singularVectors2_e[currChannel][jCh] = add( L_temp_e, sub( singularVectors2_e[currChannel][jCh], *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( singularVectors2_e[currChannel][jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#else temp_e = norm_l( singularVectors[currChannel][jCh] ); singularVectors[currChannel][jCh] = Mpy_32_32( L_shl( singularVectors[currChannel][jCh], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp[jCh] = add( sub( invVal_e, temp_e ), sub( *singularVectors_e, *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else singularVectors2_e[currChannel][jCh] = add( sub( invVal_e, temp_e ), sub( singularVectors2_e[currChannel][jCh], *sig_x_e ) ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( singularVectors2_e[currChannel][jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#endif } IF( GT_16( norm_x_e, 0 ) ) { @@ -1465,44 +1080,19 @@ static void biDiagonalReductionRight_fx( move32(); } -#ifndef FIX_1010_OPT_SINGLE_RESCALE - r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ - singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], sing_exp[idx], -( *g ), 0, &sing_exp[idx] ); /* exp(sing_exp) */ -#else r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* exp(sing_exp) */ -#endif move32(); -#ifdef FIX_1010_OPT_DIV invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); -#endif FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_DIV -#ifndef FIX_1010_OPT_SINGLE_RESCALE - secDiag[jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( r ), &secDiag_exp[jCh] ); /* exp(secDiag_exp + (sing_exp - r_e) */ - move32(); - secDiag_exp[jCh] = add( secDiag_exp[jCh], sub( sing_exp[jCh], r_e ) ); - move32(); -#else - secDiag[jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( r ), &secDiag_exp[jCh] ); /* exp(secDiag_exp + (sing_exp - r_e) */ - move32(); - secDiag_exp[jCh] = add( secDiag_exp[jCh], sub( singularVectors2_e[currChannel][jCh], r_e ) ); - move32(); -#endif -#else temp_e = norm_l( singularVectors[currChannel][jCh] ); secDiag[jCh] = Mpy_32_32( L_shl( singularVectors[currChannel][jCh], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - secDiag_exp[jCh] = add( sub( invVal_e, temp_e ), sub( sing_exp[jCh], r_e ) ); -#else secDiag_exp[jCh] = add( sub( invVal_e, temp_e ), sub( singularVectors2_e[currChannel][jCh], r_e ) ); -#endif move16(); -#endif } FOR( iCh = currChannel + 1; iCh < nChannelsL; iCh++ ) /* nChannelsL */ @@ -1513,20 +1103,12 @@ static void biDiagonalReductionRight_fx( move16(); FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[iCh][jCh], singularVectors[currChannel][jCh] ), add( *singularVectors_e, sing_exp[jCh] ), &norm_x_e ); /* exp(norm_x_e) */ -#else norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[iCh][jCh], singularVectors[currChannel][jCh] ), add( singularVectors2_e[iCh][jCh], singularVectors2_e[currChannel][jCh] ), &norm_x_e ); /* exp(norm_x_e) */ -#endif } FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], *singularVectors_e, Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &sing_exp2[iCh][jCh] ); /* exp(sing_exp2) */ -#else singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ -#endif move32(); } } @@ -1535,54 +1117,12 @@ static void biDiagonalReductionRight_fx( { singularVectors[currChannel][jCh] = Mpy_32_32( singularVectors[currChannel][jCh], ( *sig_x ) ); /* exp(sing_exp + sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp2[currChannel][jCh] = add( sing_exp[jCh], *sig_x_e ); -#else singularVectors2_e[currChannel][jCh] = add( singularVectors2_e[currChannel][jCh], *sig_x_e ); -#endif move16(); } -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - /*rescaling block*/ - Word16 exp_max = *secDiag_e; - move16(); - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - exp_max = s_max( exp_max, secDiag_exp[jCh] ); - } - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - secDiag[jCh] = L_shr_r( secDiag[jCh], sub( exp_max, secDiag_exp[jCh] ) ); /* exp(exp_max) */ - move32(); - } - *secDiag_e = exp_max; - move16(); -#endif - -#ifndef FIX_1010_OPT_SINGLE_RESCALE - exp_max = *singularVectors_e; - move16(); - FOR( iCh = 0; iCh < nChannelsL; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - exp_max = s_max( exp_max, sing_exp2[iCh][jCh] ); - } - } - FOR( iCh = 0; iCh < nChannelsL; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - singularVectors[iCh][jCh] = L_shr_r( singularVectors[iCh][jCh], sub( exp_max, sing_exp2[iCh][jCh] ) ); /* exp(exp_max) */ - move32(); - } - } - *singularVectors_e = exp_max; - move16(); -#endif } } @@ -1598,11 +1138,7 @@ static void biDiagonalReductionRight_fx( static void singularVectorsAccumulationLeft_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* input exp(singularVectors_Left_e), output Q31 */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC /* Q0 */ @@ -1612,13 +1148,6 @@ static void singularVectorsAccumulationLeft_fx( Word16 nChannels; Word32 norm_y, t_jj, t_ii; Word16 norm_y_e, t_jj_e, t_ii_e, temp_exp; -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; - FOR( nCh = 0; nCh < MAX_OUTPUT_CHANNELS; nCh++ ) - { - set16_fx( sing_exp2[nCh], singularVectors_e, MAX_OUTPUT_CHANNELS ); - } -#endif /* Processing */ nChannels = s_min( nChannelsL, nChannelsC ); /* min(nChannelsL,ChannelsC) Q0*/ @@ -1638,13 +1167,8 @@ static void singularVectorsAccumulationLeft_fx( IF( t_ii ) /*if (fabsf(t_ii) > EPSILON *fabsf(t_ii)) {*/ { -#ifdef FIX_1010_OPT_DIV t_ii = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( t_ii ), &temp_exp ); t_ii_e = sub( temp_exp, t_ii_e ); -#else - t_ii = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxWithSign_fx( t_ii ), &temp_exp ); /* exp(1 + (temp_exp + tii_e)) */ - t_ii_e = add( 1, sub( temp_exp, t_ii_e ) ); -#endif Word16 tempe; Word32 temp = BASOP_Util_Divide3232_Scale_cadence( t_ii, maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &tempe ); tempe = add( tempe, sub( t_ii_e, singularVectors_Left_e[nCh][nCh] ) ); @@ -1659,13 +1183,9 @@ static void singularVectorsAccumulationLeft_fx( move16(); FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ), add( sing_exp2[k][nCh], sing_exp2[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ -#else prod[k] = W_mult0_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ); prod_e[k] = add( singularVectors_Left_e[k][nCh], singularVectors_Left_e[k][iCh] ); max_e = s_max( max_e, prod_e[k] ); -#endif } FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ @@ -1678,18 +1198,10 @@ static void singularVectorsAccumulationLeft_fx( norm_y = W_extract_h( acc ); norm_y_e = add( sub( max_e, acc_e ), 1 ); t_jj = Mpy_32_32( temp, norm_y ); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - t_jj_e = add( temp_exp, sub( add( t_ii_e, norm_y_e ), sing_exp2[nCh][nCh] ) ); -#else t_jj_e = add( tempe, norm_y_e ); -#endif FOR( k = nCh; k < nChannelsL; k++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors_Left[k][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[k][iCh], sing_exp2[k][iCh], Mpy_32_32( t_jj, singularVectors_Left[k][nCh] ), add( t_jj_e, sing_exp2[k][nCh] ), &sing_exp2[k][iCh] ); /* exp(sing_exp2) */ -#else singularVectors_Left[k][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[k][iCh], singularVectors_Left_e[k][iCh], Mpy_32_32( t_jj, singularVectors_Left[k][nCh] ), add( t_jj_e, singularVectors_Left_e[k][nCh] ), &singularVectors_Left_e[k][iCh] ); /* exp(sing_exp2) */ -#endif move32(); } } @@ -1698,11 +1210,7 @@ static void singularVectorsAccumulationLeft_fx( { singularVectors_Left[iCh][nCh] = Mpy_32_32( singularVectors_Left[iCh][nCh], t_ii ); /* exp(sing_exp2 + t_ii_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp2[iCh][nCh] = add( sing_exp2[iCh][nCh], t_ii_e ); -#else singularVectors_Left_e[iCh][nCh] = add( singularVectors_Left_e[iCh][nCh], t_ii_e ); -#endif move16(); } } @@ -1714,11 +1222,7 @@ static void singularVectorsAccumulationLeft_fx( move32(); } } -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors_Left[nCh][nCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[nCh][nCh], sing_exp2[nCh][nCh], ONE_IN_Q30, 1, &sing_exp2[nCh][nCh] ); /* exp(sing_exp2) */ -#else singularVectors_Left[nCh][nCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[nCh][nCh], singularVectors_Left_e[nCh][nCh], ONE_IN_Q30, 1, &singularVectors_Left_e[nCh][nCh] ); /* exp(sing_exp2) */ -#endif move32(); } // fclose(fp); @@ -1726,11 +1230,7 @@ static void singularVectorsAccumulationLeft_fx( { FOR( iCh = 0; iCh < nChannelsC; iCh++ ) { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], sing_exp2[nCh][iCh] ); /* Q31 */ -#else singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ -#endif move32(); } } @@ -1748,16 +1248,8 @@ static void singularVectorsAccumulationRight_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_Left_e) */ Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* input exp(singularVectors_Left_e), output Q31 */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_e, -#else Word16 *secDiag_e, -#endif const Word16 nChannelsC /* Q0 */ ) { @@ -1783,22 +1275,11 @@ static void singularVectorsAccumulationRight_fx( FOR( iCh = nCh + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC*/ { -#ifdef FIX_1010_OPT_DIV ratio_float = L_deposit_h( BASOP_Util_Divide3232_Scale( singularVectors_Left[nCh][iCh], maxWithSign_fx( singularVectors_Left[nCh][nCh + 1] ), &temp_exp1 ) ); /* exp(temp_exp1) */ singularVectors_Right[iCh][nCh] = L_deposit_h( BASOP_Util_Divide3232_Scale( ratio_float, maxWithSign_fx( t_ii ), &sing_right_exp[iCh][nCh] ) ); /* exp(sing_right_exp + (temp_exp1 - secDiag_e) */ -#else - ratio_float = BASOP_Util_Divide3232_Scale_cadence( singularVectors_Left[nCh][iCh], maxWithSign_fx( singularVectors_Left[nCh][nCh + 1] ), &temp_exp1 ); /* exp(temp_exp1) */ - singularVectors_Right[iCh][nCh] = BASOP_Util_Divide3232_Scale_cadence( ratio_float, maxWithSign_fx( t_ii ), &sing_right_exp[iCh][nCh] ); /* exp(sing_right_exp + (temp_exp1 - secDiag_e) */ -#endif -#ifdef FIX_1010_OPT_SINGLE_RESCALE temp_exp1 = add( temp_exp1, sub( singularVectors_Left_e[nCh][iCh], singularVectors_Left_e[nCh][nCh + 1] ) ); -#endif move32(); -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - sing_right_exp[iCh][nCh] = add( sing_right_exp[iCh][nCh], sub( temp_exp1, secDiag_e ) ); -#else sing_right_exp[iCh][nCh] = add( sing_right_exp[iCh][nCh], sub( temp_exp1, secDiag_e[nCh + 1] ) ); -#endif move16(); // singularVectors_Right[iCh][nCh] = L_shl_sat( singularVectors_Right[iCh][nCh], temp_exp2 ); } @@ -1812,11 +1293,7 @@ static void singularVectorsAccumulationRight_fx( FOR( k = nCh + 1; k < nChannelsC; k++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[nCh][k], singularVectors_Right[k][iCh] ), add( singularVectors_e, sing_right_exp[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ -#else norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[nCh][k], singularVectors_Right[k][iCh] ), add( singularVectors_Left_e[nCh][k], sing_right_exp[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ -#endif } FOR( k = nCh + 1; k < nChannelsC; k++ ) /* nChannelsC */ @@ -1853,7 +1330,6 @@ static void singularVectorsAccumulationRight_fx( *-------------------------------------------------------------------------*/ -#ifdef FIX_1010_OPT_GIVENS_INV static void GivensRotation2_fx( const Word32 x, /* exp(x_e) */ const Word16 x_e, @@ -1875,7 +1351,6 @@ static void GivensRotation2_fx( *resultInv = ISqrt32( r, outInv_e ); move32(); } -#endif static Word32 GivensRotation_fx( const Word32 x, /* exp(x_e) */ @@ -1884,62 +1359,10 @@ static Word32 GivensRotation_fx( const Word16 z_e, Word16 *out_e ) { -#ifdef FIX_1010_OPT_GIVENS Word32 r; -#else - Word32 x_abs, z_abs; - Word32 cotan, tan, r; - Word16 temp_exp; - Word32 L_temp; -#endif -#ifdef FIX_1010_OPT_GIVENS r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( z, z ), shl( z_e, 1 ), Mpy_32_32( x, x ), shl( x_e, 1 ), out_e ); r = Sqrt32( r, out_e ); -#else - x_abs = L_abs( x ); - z_abs = L_abs( z ); - test(); - IF( LE_32( x_abs, Mpy_32_32( CONVERGENCE_FACTOR_FX, x_abs ) ) && LE_32( z_abs, Mpy_32_32( CONVERGENCE_FACTOR_FX, z_abs ) ) ) - { - r = 0; - move32(); - } - ELSE IF( BASOP_Util_Cmp_Mant32Exp( x_abs, x_e, z_abs, z_e ) >= 0 ) - { - IF( LE_32( x_abs, SVD_MINIMUM_VALUE_FX ) ) - { - r = 0; - move32(); - } - ELSE - { - cotan = BASOP_Util_Divide3232_Scale_cadence( z_abs, x_abs, &temp_exp ); /* exp(temp_exp + (z_e - x_e) */ - temp_exp = add( temp_exp, sub( z_e, x_e ) ); - L_temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, Mpy_32_32( cotan, cotan ), 2 * temp_exp, &temp_exp ); /* exp(temp_exp) */ - L_temp = Sqrt32( L_temp, &temp_exp ); - r = Mpy_32_32( x_abs, L_temp ); /* exp(x_e + temp_exp) */ - *out_e = add( x_e, temp_exp ); - } - } - ELSE - { - IF( LE_32( z_abs, SVD_MINIMUM_VALUE_FX ) ) - { - r = 0; - move32(); - } - ELSE - { - tan = BASOP_Util_Divide3232_Scale_cadence( x_abs, z_abs, &temp_exp ); /* exp(temp_exp + (x_e - z_e) */ - temp_exp = add( temp_exp, sub( x_e, z_e ) ); - L_temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, Mpy_32_32( tan, tan ), shl( temp_exp, 1 ), &temp_exp ); /* exp(temp_exp) */ - L_temp = Sqrt32( L_temp, &temp_exp ); - r = Mpy_32_32( z_abs, L_temp ); /* exp(z_e + temp_exp) */ - *out_e = add( z_e, temp_exp ); - } - } -#endif return ( r ); } @@ -1953,20 +1376,6 @@ static Word32 maxWithSign_fx( const Word32 a /* Qx */ ) { -#ifndef FIX_MINOR_SVD_WMOPS_MR1010X - IF( GT_32( L_abs( a ), SVD_MINIMUM_VALUE_FX ) ) - { - return a; - } - ELSE IF( a < 0 ) - { - return -SVD_MINIMUM_VALUE_FX; - } - ELSE - { - return SVD_MINIMUM_VALUE_FX; - } -#else Word32 result; IF( a >= 0 ) { @@ -1977,7 +1386,6 @@ static Word32 maxWithSign_fx( result = L_min( a, -SVD_MINIMUM_VALUE_FX ); } return result; -#endif } /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index c187c351c..aa5a379e8 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -644,21 +644,13 @@ void stereo_tcx_core_dec_fx( test(); test(); test(); -#ifdef NONBE_FIX_1402_WAVEADJUST IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch_fx && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) -#else - IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) -#endif { lerp( synthFB_fx, synth_fx, st->L_frame, hTcxDec->L_frameTCX ); if ( !bfi && st->prev_bfi ) { -#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->Pitch_fx = 0; -#else - st->hPlcInfo->Pitch = 0; -#endif move16(); } } @@ -816,21 +808,11 @@ void stereo_tcx_core_dec_fx( move16(); /* Postfiltering */ -#ifndef MSAN_FIX - IF( st->p_bpf_noise_buf_32 ) - { - Copy_Scale_sig_32_16( st->p_bpf_noise_buf_32, st->p_bpf_noise_buf, st->L_frame, negate( Q11 ) ); - } -#endif post_decoder( st, synth_buf_fx, pit_gain_fx, pitch, signal_out_fx, st->p_bpf_noise_buf ); test(); -#ifdef MSAN_FIX IF( st->p_bpf_noise_buf_32 && st->tcxonly == 0 ) -#else - IF( st->p_bpf_noise_buf_32 ) -#endif // MSAN_FIX { Copy_Scale_sig_16_32_no_sat( st->p_bpf_noise_buf, st->p_bpf_noise_buf_32, st->L_frame, Q11 ); /* q_p_bpf + Q11 */ } diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index 98c1a6a79..3191a8b4a 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -137,7 +137,6 @@ void tdm_low_rate_dec_fx( edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, find_guarded_bits_fx( L_FRAME ), IVAS_CPE_TD ); -#ifdef FIX_USAN_ISSUES IF( bwe_exc != NULL ) { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, @@ -148,10 +147,6 @@ void tdm_low_rate_dec_fx( Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], NULL, st->hGSCDec->last_exc_dct_in_fx, L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); } -#else - Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, - L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); -#endif /*----------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected *----------------------------------------------------------------------*/ diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index fc793dff0..e2528e619 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -270,9 +270,7 @@ UWord8 apa_reconfigure( free( ps->buf_out_fx ); ps->buf_out_fx = (Word16 *) malloc( sizeof( Word16 ) * ps->buf_out_capacity ); -#ifdef MSAN_FIX memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) ); -#endif ps->Q_buf_out = Q15; move16(); IF( !ps->buf_out_fx ) diff --git a/lib_dec/lead_deindexing_fx.c b/lib_dec/lead_deindexing_fx.c index 786e0c276..ecc5f6fe0 100644 --- a/lib_dec/lead_deindexing_fx.c +++ b/lib_dec/lead_deindexing_fx.c @@ -192,7 +192,6 @@ void re8_decode_base_index_fx( m1 = sub( k1, 1 ); m2 = 8; move16(); -#ifdef CR_2109_to_2112_cd0_ce0 l = 1; move16(); FOR( i = 0; i < 8; i++ ) @@ -206,9 +205,6 @@ void re8_decode_base_index_fx( test(); /* if the signs are constrained and all components are non-zero */ IF( EQ_16( k1, 7 ) && ( l > 0 ) ) -#else - IF( k1 == 7 ) -#endif { m2 = 7; move16(); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 413585447..77deb9e7d 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -44,9 +44,6 @@ #include "jbm_pcmdsp_fifo.h" #include #include -#ifndef FIX_DISCLAIMER -#include -#endif #include "wmc_auto.h" #define INV_1000_Q31 2147484 /*1/1000 IN Q31*/ @@ -3061,85 +3058,6 @@ const char *IVAS_DEC_GetErrorMessage( return ivas_error_to_string( error ); } -#ifndef FIX_DISCLAIMER -/*---------------------------------------------------------------------* - * get_channel_config() - * - * Gets a str related to input config - *---------------------------------------------------------------------*/ - -static ivas_error get_channel_config( - AUDIO_CONFIG config, - Word8 *str ) -{ - IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_MONO ) ) - { - strcpy( (char *) str, "Mono" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_STEREO ) ) - { - strcpy( (char *) str, "Stereo" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1 ) ) - { - strcpy( (char *) str, "Multichannel 5.1 (CICP6)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_7_1 ) ) - { - strcpy( (char *) str, "Multichannel 7.1 (CICP12)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1_2 ) ) - { - strcpy( (char *) str, "Multichannel 5.1+2 (CICP14)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1_4 ) ) - { - strcpy( (char *) str, "Multichannel 5.1+4 (CICP16)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_7_1_4 ) ) - { - strcpy( (char *) str, "Multichannel 7.1+4 (CICP19)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) - { - strcpy( (char *) str, "Multichannel (custom loudspeaker layout)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_FOA ) ) - { - strcpy( (char *) str, "Ambisonics: First Order (FOA)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_HOA2 ) ) - { - strcpy( (char *) str, "Ambisonics: Second Order (HOA2)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_HOA3 ) ) - { - strcpy( (char *) str, "Ambisonics: Third Order (HOA3)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL ) ) - { - strcpy( (char *) str, "Binaural: no room" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) - { - strcpy( (char *) str, "Binaural: room with impulse responses" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) - { - strcpy( (char *) str, "Binaural: room with reverb" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) - { - strcpy( (char *) str, "External renderer" ); - } - ELSE - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Error: Incorrect Input/Output Configuration" ); - } - - return IVAS_ERR_OK; -} -#endif /*---------------------------------------------------------------------* * printConfigInfo_dec( ) diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 712ead8f4..fcd5142a4 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -161,13 +161,7 @@ typedef struct { Word16 L_frameTCX; -#ifndef NONBE_FIX_1402_WAVEADJUST - Word16 Pitch; -#endif Word16 Pitch_fx; -#ifndef NONBE_FIX_1402_WAVEADJUST - Word16 T_bfi; -#endif Word8 T_bfi_fx; Word16 Transient[MAX_POST_LEN]; @@ -187,9 +181,6 @@ typedef struct Word16 step_concealgain_fx; Word16 concealment_method; -#ifndef NONBE_FIX_1402_WAVEADJUST - Word16 subframe; -#endif Word16 subframe_fx; Word16 nbLostCmpt; Word16 seed; diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 492c927b6..1b51a29fb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -6070,12 +6070,6 @@ void ivas_swb_tbe_dec_fx( tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); /* convert LSPs to LP coefficients */ E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - /* Bring the LPCs to Q12 */ - Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); - lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this - move16(); -#endif } } diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 650e8572b..e74df3a96 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -146,28 +146,20 @@ ivas_error TonalMDCTConceal_Init_ivas_fx( hTonalMDCTConc->tcx_cfg = hTcxCfg; hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->lastBlockData.spectralData, 0, L_FRAME_MAX ); -#endif move16(); hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->secondLastBlockData.spectralData, 0, L_FRAME_MAX ); -#endif move16(); hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData; move16(); hTonalMDCTConc->secondLastPowerSpectrum_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp; move16(); hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->lastBlockData.scaleFactors, 0, FDNS_NPTS ); -#endif move16(); hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->secondLastBlockData.scaleFactors, 0, FDNS_NPTS ); -#endif move16(); hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0]; move16(); @@ -234,9 +226,7 @@ ivas_error TonalMDCTConceal_Init_ivas_fx( move16(); /* just the second half of the second last pcm output is needed */ -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->timeDataBuffer, 0, ( 3 * L_FRAME_MAX ) / 2 ); -#endif hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) / 2 )]; hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - min( L_FRAME_MAX, nSamples )]; /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */ @@ -1226,9 +1216,7 @@ void TonalMDCTConceal_Detect_ivas_fx( Word16 element_mode ) { Word32 secondLastMDST[L_FRAME_MAX]; -#ifdef MSAN_FIX set32_fx( secondLastMDST, 0, L_FRAME_MAX ); -#endif Word32 secondLastMDCT[L_FRAME_MAX]; Word16 secondLastMDCT_exp; Word32 *powerSpectrum = secondLastMDST; @@ -1236,9 +1224,7 @@ void TonalMDCTConceal_Detect_ivas_fx( Word16 nSamples; // Word16 nBands; Word32 sns_int_scf_fx[FDNS_NPTS]; -#ifdef MSAN_FIX set32_fx( sns_int_scf_fx, 0, FDNS_NPTS ); -#endif nSamples = hTonalMDCTConc->nSamples; move16(); @@ -1302,11 +1288,7 @@ void TonalMDCTConceal_Detect_ivas_fx( { /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */ /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */ -#ifdef MSAN_FIX Word16 temp_power_spectrum_q = 0; -#else - Word16 power_spectrum_q; -#endif nSamples = hTonalMDCTConc->nNonZeroSamples; move16(); Copy_Scale_sig_16_32_DEPREC( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples, Q15 ); @@ -3511,9 +3493,7 @@ void TonalMdctConceal_whiten_noise_shape_ivas_fx( psychParams = st->hTonalMDCTConc->psychParams; hFdCngCom = st->hFdCngDec->hFdCngCom; -#ifdef MSAN_FIX set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); -#endif IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) { diff --git a/lib_dec/transition_dec_fx.c b/lib_dec/transition_dec_fx.c index b82378198..b9ad17fcf 100644 --- a/lib_dec/transition_dec_fx.c +++ b/lib_dec/transition_dec_fx.c @@ -56,9 +56,7 @@ void transition_dec_fx( Word16 i, offset, temp, tmp; Word16 limit_flag; Word16 i_subfridx; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( Opt_AMR_WB ); -#endif i_subfridx = i_subfr / L_SUBFR; /*i_subfr / L_SUBFR*/ /* Set limit_flag to 0 for restrained limits, and 1 for extended limits */ @@ -830,9 +828,7 @@ Word16 tc_classif_fx( /*o: Q0*/ ) { Word16 tc_subfr, indice; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( L_frame ); -#endif IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { IF( get_next_indice_fx( st_fx, 1 ) ) diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c index f993caa8d..75a514cc2 100644 --- a/lib_dec/waveadjust_fec_dec_fx.c +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -848,16 +848,8 @@ void concealment_init_ivas_fx( hPlcInfo->L_frameTCX = L_frameTCX; move16(); -#ifndef NONBE_FIX_1402_WAVEADJUST - hPlcInfo->Pitch = 0; - move16(); -#endif hPlcInfo->Pitch_fx = 0; move16(); -#ifndef NONBE_FIX_1402_WAVEADJUST - hPlcInfo->T_bfi = 0; - move16(); -#endif hPlcInfo->T_bfi_fx = 0; move16(); hPlcInfo->outx_new_n1_fx = 0; @@ -876,10 +868,6 @@ void concealment_init_ivas_fx( move16(); hPlcInfo->concealment_method = TCX_NONTONAL; move16(); -#ifndef NONBE_FIX_1402_WAVEADJUST - hPlcInfo->subframe = 0; - move16(); -#endif hPlcInfo->subframe_fx = 0; move16(); hPlcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 ); @@ -1326,11 +1314,7 @@ static Word16 waveform_adj_fix( test(); test(); test(); -#ifdef NONBE_FIX_1402_WAVEADJUST IF( hPlcInfo->T_bfi_fx && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) -#else - IF( hPlcInfo->T_bfi && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) -#endif { Word16 i1 = 0, i2 = 0; Word16 pos1, pos2, pos3; diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index d2d5ac4e6..a93690738 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -395,11 +395,7 @@ ivas_error acelp_core_enc_fx( IF( !nelp_mode && !ppp_mode ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, -#else - st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, -#endif tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -465,11 +461,7 @@ ivas_error acelp_core_enc_fx( tc_classif_enc_fx( Q_new, st_fx->L_frame, &tc_subfr_fx, &position, attack_flag, st_fx->pitch[0], res_fx ); config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#ifdef NONBE_FIX_GSC_BSTR -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, -#else - -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, -#endif tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -522,11 +514,7 @@ ivas_error acelp_core_enc_fx( /* Configure ACELP bit allocation */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#ifdef NONBE_FIX_GSC_BSTR -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, -#else - -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, -#endif st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /* redo LSF quantization */ @@ -772,21 +760,17 @@ ivas_error acelp_core_enc_ivas_fx( Word32 Bin_E_fx[L_FFT], Bin_E_old_fx[L_FFT / 2]; Word16 clip_var_fx, mem_w0_bck_fx, streaklimit_fx; -#ifdef MSAN_FIX set16_fx( old_bwe_exc_fx, 0, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); set16_fx( old_exc_fx, 0, L_EXC ); set16_fx( Aq, 0, NB_SUBFR16k * ( M + 1 ) ); set16_fx( syn_fx, 0, L_FRAME16k ); -#endif Word16 tilt_code_bck_fx; Word32 gc_threshold_bck_fx; Word16 clip_var_bck_fx[6]; Word32 q_env_fx[NUM_ENV_CNG]; -#ifdef MSAN_FIX set32_fx( q_env_fx, 0, NUM_ENV_CNG ); set16_fx( exc2_fx, 0, L_FRAME16k ); -#endif Word16 exc3_fx[L_FRAME16k]; Word16 syn1_fx[L_FRAME16k]; Word16 *tdm_Pri_pitch_buf_fx; @@ -1189,11 +1173,7 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( !nelp_mode && !ppp_mode ) { -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif } /*-----------------------------------------------------------------* @@ -1330,11 +1310,7 @@ ivas_error acelp_core_enc_ivas_fx( { tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif } /*---------------------------------------------------------------* @@ -1393,11 +1369,7 @@ ivas_error acelp_core_enc_ivas_fx( lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); /* Configure ACELP bit allocation */ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif /* redo LSF quantization */ lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL, Q_new ); @@ -1459,11 +1431,7 @@ ivas_error acelp_core_enc_ivas_fx( IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) { Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn -#ifdef MSAN_FIX Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 1 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); // st->Q_syn -#else - Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 2 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); -#endif st->hTcxEnc->q_Txnq = st->Q_syn; move16(); } @@ -1488,11 +1456,7 @@ ivas_error acelp_core_enc_ivas_fx( *-----------------------------------------------------------------*/ Scale_sig( syn_fx, L_FRAME, sub( s_min( st->Q_syn, Q_new ), st->Q_syn ) ); // min( st->Q_syn, Q_new ) -#ifdef MSAN_FIX Scale_sig( res_fx, st->L_frame, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); // min( st->Q_syn, Q_new ) -#else - Scale_sig( res_fx, L_FRAME16k, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); -#endif FEC_encode_ivas_fx( hBstr, st->acelp_cfg, syn_fx, st->coder_type, st->clas, pitch_buf, res_fx, &st->Last_pulse_pos, st->L_frame, st->total_brate, s_min( st->Q_syn, Q_new ) ); IF( st->hBWE_TD != NULL ) { @@ -1557,11 +1521,7 @@ ivas_error acelp_core_enc_ivas_fx( IF( !st->Opt_SC_VBR && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { /* Apply a non linearity to the SHB excitation */ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#endif non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, Q_new, st->coder_type, voice_factors_fx, st->L_frame ); Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index d88e1523e..f9058b9b9 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -149,11 +149,7 @@ void acelp_core_switch_enc_fx( *----------------------------------------------------------------*/ config_acelp1( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, -#ifdef NONBE_FIX_GSC_BSTR GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#else - GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#endif encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); @@ -264,11 +260,7 @@ void acelp_core_switch_enc_ivas_fx( *----------------------------------------------------------------*/ config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, -#ifdef NONBE_FIX_GSC_BSTR GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#else - GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#endif encod_gen_voic_core_switch_ivas_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); diff --git a/lib_enc/bass_psfilter_enc_fx.c b/lib_enc/bass_psfilter_enc_fx.c index a1d672fe0..a241101ba 100644 --- a/lib_enc/bass_psfilter_enc_fx.c +++ b/lib_enc/bass_psfilter_enc_fx.c @@ -269,11 +269,7 @@ Word16 bass_pf_enc_fx( st = sub( s2, s2_old ); FOR( i = 0; i < tmp16; i++ ) { -#ifdef FIX_ISSUE_1187 noise_buf[i] = shl_sat( mem_bpf->noise_buf[i], st ); -#else - noise_buf[i] = shl( mem_bpf->noise_buf[i], st ); -#endif move16(); } Copy( noise_buf + l_subfr, mem_bpf->noise_buf, tmp16 ); diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 6c99a4306..e2b29ba59 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2011,14 +2011,12 @@ void CNG_enc_ivas_fx( /* convert log2 of residual signal energy */ /*enr = (float)log10( enr + 0.1f ) / (float)log10( 2.0f ); */ -#ifdef FIX_ISSUE_1245 IF( L_ener == 0 ) { enr = -850; /*log(0.1) base 2 in Q8*/ move16(); } ELSE -#endif { hi = norm_l( L_ener ); lo = Log2_norm_lc( L_shl( L_ener, hi ) ); diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index e701b8e46..d3725dcba 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -37,14 +37,8 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * Word16 *bwe_exc /* o : excitation for SWB TBE Qx */ ) { -#ifndef SIMPLIFY_CODE_BE - Word16 i, j, i_subfr, j_subfr; - Word16 tmp, tmp2, Es_pred; - Word32 gain_code_vect[2]; -#else Word16 i, i_subfr, j_subfr; Word16 tmp, Es_pred; -#endif Word16 T0, T0_min, T0_min_frac, T0_max, T0_max_frac, T0_res; Word16 T0_frac; Word16 gain_pit, voice_fac; @@ -103,11 +97,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * /* Configure ACELP */ -#ifndef MSAN_FIX - hLPDmem->nbits = BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr ); -#else BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr ); -#endif /* Init Framing parameters */ move16(); @@ -324,12 +314,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); -#ifndef SIMPLIFY_CODE_BE - gain_code_vect[0] = gain_code; - move32(); - gain_code_vect[1] = gain_code; - move32(); -#endif /*----------------------------------------------------------* * - voice factor (for pitch enhancement) * *----------------------------------------------------------*/ @@ -361,32 +345,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * /*-------------------------------------------------------* * - Find the total excitation. * *-------------------------------------------------------*/ -#ifndef SIMPLIFY_CODE_BE - tmp2 = shr( L_SUBFR, 1 ); - FOR( j = 0; j < 2; j++ ) - { - FOR( i = sub( tmp2, shr( L_SUBFR, 1 ) ); i < tmp2; i++ ) - { - /* code in Q9, gain_pit in Q14; exc Q_new */ - Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); - Ltmp = L_shl( Ltmp, Q_new_p5 ); - Ltmp = L_mac( Ltmp, gain_pit, exc[i + i_subfr] ); - BASOP_SATURATE_WARNING_OFF_EVS - exc2[i] = round_fx( L_shl( Ltmp, 1 ) ); - BASOP_SATURATE_WARNING_ON_EVS - - Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code[i] ); - Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); - Ltmp = L_add( Ltmp, Ltmp2 ); - BASOP_SATURATE_WARNING_OFF_EVS - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - BASOP_SATURATE_WARNING_ON_EVS - exc[i + i_subfr] = round_fx( Ltmp ); - } - tmp2 = L_SUBFR; - move16(); - } -#else FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14; exc Q_new */ @@ -402,7 +360,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); move16(); } -#endif /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index e6fc25e36..54f57b287 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -14,11 +14,9 @@ #include "stl.h" // #include "basop_mpy.h" #include "prot_fx_enc.h" -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -1717,9 +1715,7 @@ void EstimateStereoTCXNoiseLevel_fx( Word16 *fac_ns_q; Word32 total_brate; -#ifdef MSAN_FIX set32_fx( combined_q_spectrum, 0, N_MAX ); -#endif FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -4365,9 +4361,6 @@ void coder_tcx_fx( Word16 winMDST[N_MAX + L_MDCT_OVLP_MAX]; Word16 *pWinMDST; Word16 left_overlap_mode, right_overlap_mode; -#ifndef MSAN_FIX - LPD_state_HANDLE hLPDmem = st->hLPDmem; -#endif TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; left_overlap = right_overlap = -1; @@ -4533,10 +4526,6 @@ void coder_tcx_fx( st, hm_cfg ); -#ifndef MSAN_FIX - hLPDmem->nbits = add( hLPDmem->nbits, add( tnsBits, ltpBits ) ); - move16(); -#endif } diff --git a/lib_enc/cod_uv_fx.c b/lib_enc/cod_uv_fx.c index 8eccddc0b..8b1e8a144 100644 --- a/lib_enc/cod_uv_fx.c +++ b/lib_enc/cod_uv_fx.c @@ -135,7 +135,6 @@ void gauss_L2_ivas_fx( *gain = L_deposit_l( 0 ); move32(); /*Update correlations for gains coding */ -#ifdef FIX_ISSUE_1167 tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */ tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */ FOR( i = 0; i < L_SUBFR; i++ ) @@ -144,34 +143,17 @@ void gauss_L2_ivas_fx( tmp32 = L_mac0( tmp32, tmp16, tmp16 ); /* Q16 */ tmp32_2 = L_mac0( tmp32_2, tmp16, shr( y2[i], 1 ) ); /* Q16 */ } -#else - tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ - tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ - FOR( i = 0; i < L_SUBFR; i++ ) - { - tmp32 = L_mac0( tmp32, y11[i], y11[i] ); /* Q18 */ - tmp32_2 = L_mac0( tmp32_2, y11[i], y2[i] ); /* Q18 */ - } -#endif tmp16 = norm_l( tmp32 ); // To be checked g_corr->y1y1 = round_fx_sat( L_shl( tmp32, tmp16 ) ); -#ifdef FIX_ISSUE_1167 g_corr->y1y1_e = sub( 31 - 16, tmp16 ); -#else - g_corr->y1y1_e = sub( 31 - 18, tmp16 ); -#endif move16(); move16(); tmp16 = norm_l( tmp32_2 ); g_corr->y1y2 = round_fx_sat( L_shl( tmp32_2, tmp16 ) ); -#ifdef FIX_ISSUE_1167 g_corr->y1y2_e = sub( 31 - 16, tmp16 ); -#else - g_corr->y1y2_e = sub( 31 - 18, tmp16 ); -#endif move16(); move16(); } diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index bfe17fcd2..405b3ac2b 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -299,11 +299,9 @@ static void init_tcx_fx( Word16 i; Word16 fscaleFB; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) MCT_flag; (void) total_brate; (void) last_total_brate; -#endif // PMT("init_tcx_fx needs an entire review to adapt to IVAS") fscaleFB = div_l( L_shl( st->input_Fs, LD_FSCALE_DENOM + 1 ), 12800 ); @@ -945,9 +943,7 @@ static void init_modes_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ -#ifdef FIX_920_IGF_INIT_ERROR const Word32 igf_brate, /* i : IGF configuration bitrate */ -#endif const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ) { @@ -1080,11 +1076,7 @@ void init_coder_ace_plus_ivas_fx( test(); IF( st->igf && st->hIGFEnc != NULL ) { -#ifdef FIX_920_IGF_INIT_ERROR IGFEncSetMode_ivas_fx( st->hIGFEnc, igf_brate, st->bwidth, st->element_mode, st->rf_mode ); -#else - IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); -#endif } ELSE IF( st->hIGFEnc != NULL ) { diff --git a/lib_enc/core_enc_ol_fx.c b/lib_enc/core_enc_ol_fx.c index 04857c334..18f48e904 100644 --- a/lib_enc/core_enc_ol_fx.c +++ b/lib_enc/core_enc_ol_fx.c @@ -80,10 +80,8 @@ void core_encode_openloop_fx( Word16 w_rf[M + 1], lsf_uq_rf[M + 1]; Word16 lsf_q_1st_rf[M + 1], lsf_q_d_rf[M + 1], lsf_q_rf[M + 1]; Word16 lsp_old_q_rf[M + 1], lsf_old_q_rf[M + 1]; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) vad_hover_flag; (void) vad_flag_dtx; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); diff --git a/lib_enc/core_enc_reconf_fx.c b/lib_enc/core_enc_reconf_fx.c index 1ba496b0e..9e7380aaa 100644 --- a/lib_enc/core_enc_reconf_fx.c +++ b/lib_enc/core_enc_reconf_fx.c @@ -24,9 +24,7 @@ void core_coder_reconfig_fx( { Word16 i, bwidth, index; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) last_total_brate; -#endif /*Configuration of ACELP*/ BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index f3b4aea6b..2f21f1015 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -408,11 +408,7 @@ void core_coder_mode_switch_ivas_fx( Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); -#ifdef FIX_920_IGF_INIT_ERROR init_coder_ace_plus_ivas_fx( st, last_total_brate, st->total_brate, MCT_flag ); -#else - init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); -#endif if ( st->hLPDmem != NULL ) { st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; diff --git a/lib_enc/core_switching_enc_fx.c b/lib_enc/core_switching_enc_fx.c index dc3062298..5290509cd 100644 --- a/lib_enc/core_switching_enc_fx.c +++ b/lib_enc/core_switching_enc_fx.c @@ -997,10 +997,8 @@ void core_switching_pre_enc_ivas_fx( tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); -#ifdef FIX_ISSUE_1230 hBWE_FD->Q_new_input_hp = 0; move16(); -#endif IF( NE_16( st_fx->last_extl, WB_BWE ) ) { diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index 3624cf374..c95bc9d5b 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -386,7 +386,6 @@ void decision_matrix_enc_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR /*-----------------------------------------------------------------* * set inactive coder_type flag in ACELP core *-----------------------------------------------------------------*/ @@ -400,7 +399,6 @@ void decision_matrix_enc_fx( move16(); } -#endif return; } diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 154b43c12..44be8dcc6 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -29,9 +29,6 @@ #define CNG_TYPE_HO 20 /* hangover for switching between CNG types */ -#ifndef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD -#define DTX_THR 5 /* LP_NOISE level */ -#endif #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ #define MAX_BRATE_DTX_IVAS IVAS_80k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ @@ -64,9 +61,7 @@ static void update_SID_cnt_fx( DTX_ENC_HANDLE hDtxEnc, const Word32 core_brate, /*==================================================================================*/ void dtx_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ const Word16 vad, /* i : vad flag for DTX Q0*/ const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ @@ -83,21 +78,15 @@ void dtx_ivas_fx( Flag Overflow = 0; move32(); #endif -#ifdef NONBE_1211_DTX_BR_SWITCHING Word32 total_brate_ref; total_brate_ref = st_fx->total_brate; move32(); -#endif IF( st_fx->dtx_sce_sba != 0 ) { last_br_cng_flag = 1; last_br_flag = 1; -#ifndef NONBE_1211_DTX_BR_SWITCHING - br_dtx_flag = 1; - move16(); -#endif move16(); move16(); } @@ -112,15 +101,9 @@ void dtx_ivas_fx( test(); test(); -#ifdef NONBE_1211_DTX_BR_SWITCHING last_br_flag = ( st_fx->element_mode == EVS_MONO && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) ) || ( st_fx->element_mode != EVS_MONO && LE_32( last_ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); -#else - last_br_flag = LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_IVAS ) ); - br_dtx_flag = 0; - move16(); -#endif } /* Initialization */ @@ -217,10 +200,8 @@ void dtx_ivas_fx( * Select SID or FRAME_NO_DATA frame if DTX is enabled *------------------------------------------------------------------------*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING br_dtx_flag = 1; move16(); -#endif IF( st_fx->dtx_sce_sba == 0 ) { @@ -230,11 +211,7 @@ void dtx_ivas_fx( test(); br_dtx_flag = ( ( st_fx->element_mode == EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || -#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); -#else - LT_16( st_fx->lp_noise_fx, 3840 /*15 in Q8*/ ); -#endif } test(); test(); @@ -352,13 +329,11 @@ void dtx_ivas_fx( reset_indices_enc_fx( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); } } -#ifdef NONBE_1211_DTX_BR_SWITCHING ELSE IF( st_fx->element_mode != EVS_MONO ) { st_fx->total_brate = total_brate_ref; move32(); } -#endif /*------------------------------------------------------------------------* * Reset counters when in active frame (not in SID or FRAME_NO_DATA frame) diff --git a/lib_enc/enc_acelp_fx.c b/lib_enc/enc_acelp_fx.c index a509a7cd7..4317bdbb3 100644 --- a/lib_enc/enc_acelp_fx.c +++ b/lib_enc/enc_acelp_fx.c @@ -1387,7 +1387,6 @@ void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const return; } -#ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; @@ -1712,7 +1711,6 @@ void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, } return; } -#endif /* * E_ACELP_4t_fx @@ -1869,11 +1867,7 @@ void E_ACELP_4t_ivas_fx( } ELSE { -#ifdef FIX_ISSUE_1165 E_ACELP_4tsearch_ivas_fx( dn, cn, H, code, &config, ind, y ); -#else - E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); -#endif } E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index ); return; diff --git a/lib_enc/enc_acelpx_fx.c b/lib_enc/enc_acelpx_fx.c index f18da2ef2..9612696ed 100644 --- a/lib_enc/enc_acelpx_fx.c +++ b/lib_enc/enc_acelpx_fx.c @@ -781,11 +781,7 @@ void E_ACELP_4tsearchx_ivas_fx( alp = shr( alp, 1 ); Scale_sig( cor, L_SUBFR, -1 ); /*Q8*/ Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/ -#ifndef MSAN_FIX - Scale_sig( dn, 2 * L_SUBFR, -1 ); -#else Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ -#endif } diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 06c49a8d3..62f740fb2 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -656,11 +656,7 @@ void encod_gen_voic_ivas_fx( *-----------------------------------------------------------------*/ test(); -#ifdef NONBE_FIX_GSC_BSTR IF( !st_fx->inactive_coder_type_flag && EQ_16( st_fx->coder_type, INACTIVE ) ) -#else - IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && EQ_16( st_fx->coder_type, INACTIVE ) ) -#endif { transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr_fx, cn_fx, exc_fx, p_Aq_fx, p_Aw_fx, h1_fx, xn_fx, xn2_fx, y1_fx, y2_fx, Es_pred_fx, &gain_pit_fx, gain_code_fx, g_corr_fx, clip_gain_fx, &gain_preQ_fx, code_preQ_fx, unbits_fx, Q_new, shift ); diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 7e5734e70..7af329a1c 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -578,9 +578,6 @@ void enc_pit_exc_ivas_fx( Word16 use_fcb; Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ -#ifndef FIX_ISSUE_1376 - Word16 h1_q15[PIT_EXC_L_SUBFR + ( M + 1 )]; -#endif Word16 q_h1; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; @@ -602,9 +599,7 @@ void enc_pit_exc_ivas_fx( move16(); Pitch_CT = GENERIC; move16(); -#ifdef MSAN_FIX set16_fx( cn1, 0, PIT_EXC_L_SUBFR ); -#endif test(); test(); IF( st_fx->GSC_IVAS_mode > 0 && ( st_fx->GSC_noisy_speech || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) @@ -773,15 +768,8 @@ void enc_pit_exc_ivas_fx( * Codebook target computation * (No LP filtering of the adaptive excitation) *-----------------------------------------------------------------*/ -#ifndef FIX_ISSUE_1376 - Copy_Scale_sig( h1, h1_q15, L_subfr, 1 ); // Q14 -> Q15 - - lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1_q15, - xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ -#else lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1, xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ -#endif IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 5b9f67503..4cda393d5 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -478,9 +478,7 @@ Word16 encod_tran_ivas_fx( L_frame_fx = st_fx->L_frame; move16(); -#ifdef MSAN_FIX set16_fx( h1, 0, L_SUBFR + ( M + 1 ) ); -#endif /*------------------------------------------------------------------* * Initializations diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index b0c67abf5..8a77b9e2b 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -453,14 +453,10 @@ void encod_unvoiced_ivas_fx( voice_factors_fx[i_subfr / L_SUBFR] = 0; move16(); -#ifdef FIX_ISSUE_1148 if ( st_fx->hBWE_TD != NULL ) { interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); } -#else - interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); -#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/energy_fx.c b/lib_enc/energy_fx.c index 7dc96a4e3..0168e52b1 100644 --- a/lib_enc/energy_fx.c +++ b/lib_enc/energy_fx.c @@ -451,11 +451,7 @@ void background_update_fx( tmp = L_shr( 2147 /* 0.000001 Q31 */, sub( 31, scale_sb_energy ) ); /* scale_sb_energy */ FOR( i = 0; i < SNR_sb_num; i++ ) { -#ifdef FIX_ISSUE_1209 sb_bg_energy[i] = L_add_sat( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ -#else - sb_bg_energy[i] = L_add( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ -#endif move32(); } } diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index f546c3ef8..087d892e3 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -967,10 +967,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( Q_win_temp[frameno] = *q_win; move16(); -#ifdef MSAN_FIX Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len[frameno], *q_win ); // q_win -#endif IF( EQ_16( frameno, 1 ) ) { Scale_sig32( windowed_samples + 2, win_len[0], sub( *q_win, Q_win_temp[0] ) ); // q_win @@ -1384,27 +1382,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( st->igf ) { Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); -#else ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); -#endif } } } -#ifndef MSAN_FIX - IF( windowed_samples != NULL ) - { - FOR( frameno = 0; frameno < nSubframes; frameno++ ) - { - IF( !( ( EQ_16( transform_type[frameno], TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) ) - { - Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len, *q_win ); - } - } - } -#endif IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { diff --git a/lib_enc/find_tilt_fx.c b/lib_enc/find_tilt_fx.c index ea71b09bc..ed8ff425e 100644 --- a/lib_enc/find_tilt_fx.c +++ b/lib_enc/find_tilt_fx.c @@ -93,11 +93,7 @@ void find_tilt_fx( } tmp = BASOP_Util_Divide3232_Scale( lp_bckr, hp_bckr, &e_tmp ); -#ifdef FIX_ISSUE_1152 Ltmp = L_shr_r_sat( L_deposit_h( tmp ), sub( 15, e_tmp ) ); -#else - Ltmp = L_shr_r( L_deposit_h( tmp ), sub( 15, e_tmp ) ); -#endif *bckr_tilt_lt = L_add( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Mpy_32_16_r( Ltmp, 3277 ) ); /* Q16 */ diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index f943b104d..edddc6a88 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -979,13 +979,8 @@ void gauss2v_ivas_fx( /* eneri = round_fx(ener[i]) + round_fx(ener[j]) + 2*round_fx(dotprod) */ /* Use ScalingShift to stay aligned with ener[] */ eneri = L_shl( dotprod, 1 ); /* One left shift added for factor of 2 */ -#ifndef FIX_1298 - eneri = L_add( ener[i], eneri ); - eneri = L_add( ener[j], eneri ); /* Q31 */ -#else eneri = L_add_sat( ener[i], eneri ); eneri = L_add_sat( ener[j], eneri ); /* Q31 */ -#endif lo1 = L_Extract_lc( cor32, &hi1 ); cor2 = Sad_32( 0, hi1, lo1 ); /* Square + Add */ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 944cb2649..2b53082f7 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -83,7 +83,6 @@ static Word16 hf_spectrum_sparseness_fx( crest_mod_fx = 0; move32(); maximum_l( A_fx, L_SPEC_HB, &Amax_fx ); -#ifdef NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO IF( Amax_fx == 0 ) { /* For all-zero input the crest is 1.0 */ @@ -94,7 +93,6 @@ static Word16 hf_spectrum_sparseness_fx( } ELSE { -#endif thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */ movmean_fx = 0; /* avoid uninitialized warning */ move32(); @@ -160,9 +158,7 @@ static Word16 hf_spectrum_sparseness_fx( move32(); st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e ); move16(); -#ifdef NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO } -#endif *crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_lp_fx ) ), Mpy_32_32( ONE_IN_Q31 - HQ_CREST_FAC_SM_FX, crest_fx ) ); /* Q(st->hHQ_core->crest_lp_q) */ move32(); *crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_mod_lp_fx ) ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), crest_mod_fx ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */ diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index f22218d13..6bc466e3d 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -374,7 +374,6 @@ void HQ_core_enc_init_fx( hHQ_core->last_max_pos_pulse = 0; move16(); -#ifdef MSAN_FIX hHQ_core->crest_lp_fx = HQ_CREST_THRESHOLD_FX; /* Q28 */ move32(); hHQ_core->crest_lp_q = Q28; @@ -383,7 +382,6 @@ void HQ_core_enc_init_fx( move32(); hHQ_core->crest_mod_lp_q = Q29; move16(); -#endif return; } @@ -482,11 +480,7 @@ void hq_core_enc_ivas_fx( Q_audio = sub( Q16, q ); TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); Q_audio = sub( Q31, Q_audio ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ -#else - Copy_Scale_sig_16_32_DEPREC( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ -#endif inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ is_transient = 0; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index fc7c32fdb..d5f071784 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -716,13 +716,8 @@ static void IGF_CalculateEnvelope_ivas_fx( Word32 mean_y_fx_tmp = 0; move32(); mean_xy_fx = mean_x2_fx = 0; -#ifdef FIX_ISSUE_1214 mean_x_e = 15; mean_xy_e = mean_y_e = mean_x2_e = 31; -#else - mean_x_e = mean_y_e = 15; - mean_xy_e = mean_x2_e = 31; -#endif move16(); move16(); move16(); @@ -738,21 +733,12 @@ static void IGF_CalculateEnvelope_ivas_fx( mean_x_fx = add( mean_x_fx, x ); /*Q0*/ mean_x2_fx = L_add( mean_x2_fx, L_mult0( x, x ) ); /*Q0*/ -#ifdef FIX_ISSUE_1214 /*y = 20.f * log10f( max( 1.f, powerSpectrum[i] ) );*/ IF( LE_64( W_deposit32_l( pPowerSpectrum_fx[sb] ), W_shl( 1, ( sub( 31, e_ps[sb] ) ) ) ) ) { y = 0; move16(); } -#else - - /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ - IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) - { - y = imult1616( 20, ( -18 /* log10f(1e-018f) */ ) ); - } -#endif ELSE { y = imult1616( 20, extract_l( L_shr( Mult_32_16( ( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps[sb], Q25 ) ) ), INV_Log2_10_Q15 ), Q25 ) ) ); /*Q0*/ @@ -1258,21 +1244,12 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); } } -#ifdef FIX_ISSUE_1214 tmp_tb_fx = shr_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ tmp_sb_fx = shr_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ -#else - tmp_tb_fx = shl_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - tmp_sb_fx = shl_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, tmp_tb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, tmp_tb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ - hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, tmp_sb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, tmp_sb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ -#endif move16(); move16(); move16(); @@ -2541,9 +2518,7 @@ void IGFEncResetTCX10BitCounter_ivas_fx( void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ -#endif const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ @@ -2563,9 +2538,7 @@ void IGFEncApplyMono_ivas_fx( Word32 common_pPowerSpectrum_fx[N_MAX + L_MDCT_OVLP_MAX]; -#ifdef MSAN_FIX set32_fx( common_pPowerSpectrum_fx, 0, N_MAX + L_MDCT_OVLP_MAX ); -#endif Word16 common_pPowerSpectrum_exp = MIN16B; move16(); @@ -2624,20 +2597,12 @@ void IGFEncApplyMono_ivas_fx( IF( pPowerSpectrumParameter_fx ) { -#ifndef MSAN_FIX - FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) -#else FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) -#endif { common_pPowerSpectrum_exp = s_max( common_pPowerSpectrum_exp, pPowerSpectrumParameter_exp[i] ); } -#ifndef MSAN_FIX - FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) -#else FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) -#endif { common_pPowerSpectrum_fx[i] = L_shl( pPowerSpectrumParameter_fx[i], sub( pPowerSpectrumParameter_exp[i], common_pPowerSpectrum_exp ) ); move16(); diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index ebfd9c4a2..1d695659c 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1398,11 +1398,7 @@ ivas_error init_encoder_ivas_fx( st->exp_buf_wspeech_enc = 0; move16(); /* initializations */ -#ifndef MSAN_FIX - set32_fx( st->Bin_E_old_fx, 0, shr( L_FFT, 2 ) ); -#else set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); -#endif st->q_Bin_E_old = Q31; move16(); set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); @@ -1821,10 +1817,8 @@ ivas_error init_encoder_ivas_fx( } fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX st->Q_old_wtda = 0; move16(); -#endif } ELSE { @@ -2069,7 +2063,6 @@ ivas_error init_encoder_ivas_fx( set16_fx( st->totalNoise_increase_hist_fx, 0, TOTALNOISE_HIST_SIZE ); st->totalNoise_increase_len = 0; move16(); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; IF( hTcxEnc != NULL ) { @@ -2080,10 +2073,8 @@ ivas_error init_encoder_ivas_fx( move32(); st->currEnergyHF_e_fx = 0; move16(); -#ifdef MSAN_FIX st->prevEnergyHF_fx = 0; move32(); -#endif /* Initialize TCX */ @@ -2097,12 +2088,7 @@ ivas_error init_encoder_ivas_fx( st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); /* Initialize ACELP */ -#endif -#ifdef FIX_920_IGF_INIT_ERROR init_coder_ace_plus_ivas_fx( st, st->last_total_brate, igf_brate, 0 ); -#else - init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); -#endif IF( st->hLPDmem != NULL ) { diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 46bec5f4d..e47b14559 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -89,9 +89,7 @@ Word16 inov_encode_fx( Word16 Rw[L_SUBFR]; Word16 acelpautoc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) last_L_frame; -#endif stack_pulses = 0; move16(); diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index cacbcabd3..1e7a13d45 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -118,14 +118,12 @@ ivas_error ivas_core_enc_fx( set32_fx( new_swb_speech_buffer_fx, 0, L_FRAME48k + STEREO_DFT_OVL_MAX ); set16_fx( new_swb_speech_buffer_fx_16, 0, L_FRAME48k + STEREO_DFT_OVL_MAX ); -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) { set_zero_fx( bwe_exc_extended_fx[i], L_FRAME32k + NL_BUFF_OFFSET ); set16_fx( old_syn_12k8_16k_fx[i], 0, L_FRAME16k ); } set16_fx( shb_speech_fx, 0, L_FRAME16k ); -#endif push_wmops( "ivas_core_enc" ); @@ -215,7 +213,6 @@ ivas_error ivas_core_enc_fx( /*---------------------------------------------------------------------* * Pre-processing, incl. Decision matrix *---------------------------------------------------------------------*/ -#ifdef MSAN_FIX IF( st->cldfbAnaEnc ) { Word16 tmp_shift = L_norm_arr( enerBuffer_fx[n], st->cldfbAnaEnc->no_channels ); @@ -227,16 +224,6 @@ ivas_error ivas_core_enc_fx( move16(); } } -#else - Word16 tmp_shift = getScaleFactor32( enerBuffer_fx[n], CLDFB_NO_CHANNELS_MAX ); - tmp_shift = sub( tmp_shift, 5 ); - IF( tmp_shift < 0 ) - { - scale_sig32( enerBuffer_fx[n], CLDFB_NO_CHANNELS_MAX, tmp_shift ); - enerBuffer_fx_exp[n] = sub( enerBuffer_fx_exp[n], tmp_shift ); - move16(); - } -#endif Scale_sig( fft_buff_fx[n], ( 2 * L_FFT ), -1 ); // To create 1 headroom for addition of magnitude square spectrum // fft_buff_fx_exp = add(fft_buff_fx_exp,1); diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 45098926e..bf7c36eef 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -131,9 +131,7 @@ ivas_error pre_proc_front_ivas_fx( const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO @@ -212,10 +210,6 @@ ivas_error pre_proc_front_ivas_fx( Word16 new_inp_out_size; Word16 Q_new_inp; Word16 mem_decim_size; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - Word16 Q_new; - Word16 corr_shift_fx; -#endif Word16 dummy_fx; Word16 ncharX_fx; @@ -259,13 +253,8 @@ ivas_error pre_proc_front_ivas_fx( IF( hSCE != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#endif hSCE->hCoreCoder[n]->q_inp32 = Q11; move16(); Scale_sig( hSCE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ @@ -282,13 +271,8 @@ ivas_error pre_proc_front_ivas_fx( } ELSE { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#endif hCPE->hCoreCoder[n]->q_inp32 = Q11; move16(); Scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ @@ -316,13 +300,11 @@ ivas_error pre_proc_front_ivas_fx( } #endif -#ifdef MSAN_FIX FOR( Word16 k = 0; k < CLDFB_NO_COL_MAX; k++ ) { set32_fx( realBuffer_fx[k], 0, CLDFB_NO_CHANNELS_MAX ); set32_fx( imagBuffer_fx[k], 0, CLDFB_NO_CHANNELS_MAX ); } -#endif Word16 sf_energySum[CLDFB_NO_CHANNELS_MAX]; Word16 Q_to_be_looked_into = -1; @@ -365,9 +347,6 @@ ivas_error pre_proc_front_ivas_fx( IF( hSCE != NULL ) { st = hSCE->hCoreCoder[n]; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - signal_in = hSCE->hCoreCoder[n]->input; -#endif signal_in_fx = hSCE->hCoreCoder[n]->input_fx; /* hSCE->hCoreCoder[n]->q_inp */ signal32_in_fx = hSCE->hCoreCoder[n]->input32_fx; /* hSCE->hCoreCoder[n]->q_inp32 */ element_mode = IVAS_SCE; @@ -381,9 +360,6 @@ ivas_error pre_proc_front_ivas_fx( ELSE /* CPE */ { st = hCPE->hCoreCoder[n]; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - signal_in = hCPE->hCoreCoder[n]->input; -#endif signal_in_fx = hCPE->hCoreCoder[n]->input_fx; /* hSCE->hCoreCoder[n]->q_inp */ signal32_in_fx = hCPE->hCoreCoder[n]->input32_fx; /* hSCE->hCoreCoder[n]->q_inp32 */ element_mode = hCPE->element_mode; @@ -1092,11 +1068,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } -#ifdef NONBE_1211_DTX_BR_SWITCHING dtx_ivas_fx( st, last_ivas_total_brate, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, *Q_new ); -#else - dtx_ivas_fx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, *Q_new ); -#endif test(); test(); @@ -1464,11 +1436,7 @@ ivas_error pre_proc_front_ivas_fx( st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, Etot_fx, hp_E_fx, &flag_spitch, last_core_orig, hStereoClassif, *Q_new /*q_inp_12k8*/, fr_bands_fx_q ); // Q0 -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); -#else - Copy_Scale_sig_16_32_DEPREC( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); -#endif #ifdef DEBUG_FORCE_DIR if ( st->force_dir[0] != '\0' ) diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 8d00e608c..ca53a227a 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -282,11 +282,7 @@ ivas_error pre_proc_ivas_fx( } ELSE IF( GT_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( ( st->vad_flag == 0 && GE_16( st->bwidth, SWB ) && GE_16( st->max_bwidth, SWB ) ) || ( st->localVAD == 0 && ( LE_16( st->bwidth, WB ) || LE_16( st->max_bwidth, WB ) ) ) ) ) { -#ifdef NONBE_FIX_GSC_BSTR /* inactive frames will be coded by AVQ technology (exceptionally it can be later rewritten to GSC technology in ivas_combined_format_brate_sanity()) */ -#else - /* inactive frames will be coded by AVQ technology */ -#endif st->coder_type = INACTIVE; move16(); } @@ -734,9 +730,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 *preemp_start_idx = NULL; Word32 sig_out[960], max_32; /*Word16 Q_exp, Q_wsp_exp*/; -#ifdef MSAN_FIX set16_fx( new_inp_resamp16k_fx, 0, L_FRAME16k ); -#endif set16_fx( epsP_h, 0, M + 1 ); set16_fx( epsP_l, 0, M + 1 ); signal_in_fx = st->input_fx; /* st->q_inp */ diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index ea70a33d3..6108b138c 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -78,9 +78,7 @@ ivas_error ivas_cpe_enc_fx( Word16 Q_new[CPE_CHANNELS] = { 0 }; Word16 fft_buff_fx[CPE_CHANNELS][2 * L_FFT]; /* FFT buffer */ Word16 fft_buff_fx_q[CPE_CHANNELS]; /* FFT buffer */ -#ifdef MSAN_FIX set16_fx( fft_buff_fx_q, 0, CPE_CHANNELS ); -#endif Word16 fft_buff_fx_final_q = MAX_16; move16(); Word32 ener_fx[CPE_CHANNELS]; /* residual energy from Levinson-Durbin Q6 */ @@ -176,7 +174,6 @@ ivas_error ivas_cpe_enc_fx( set16_fx( voicing_fr_fx[0], 0, NB_SUBFR ); set16_fx( voicing_fr_fx[1], 0, NB_SUBFR ); -#ifdef MSAN_FIX FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { set16_zero_fx( fft_buff_fx[i], 2 * L_FFT ); @@ -185,7 +182,6 @@ ivas_error ivas_cpe_enc_fx( set16_zero_fx( old_inp_12k8_16fx[i], L_INP_12k8 ); set_zero_fx( old_inp_12k8_fx[i], L_INP_12k8 ); } -#endif /*------------------------------------------------------------------* * CPE initialization - core coder *-----------------------------------------------------------------*/ @@ -288,9 +284,7 @@ ivas_error ivas_cpe_enc_fx( move16(); Word16 front_create_flag = 0; move16(); -#ifdef MSAN_FIX set32_fx( band_energies_LR_fx, 0, 2 * NB_BANDS ); -#endif IF( hCPE->hFrontVad[0] != NULL && NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { @@ -375,13 +369,8 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Set TD stereo parameters *----------------------------------------------------------------*/ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ -#endif Word16 shift = getScaleFactor32( sts[1]->input32_fx, input_frame ); scale_sig32( sts[1]->input32_fx, input_frame, shift ); /* Q11 + shift */ sts[1]->q_inp32 = add( Q11, shift ); @@ -408,7 +397,6 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ -#ifdef FIX_ISSUE_1247 shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); @@ -426,25 +414,6 @@ ivas_error ivas_cpe_enc_fx( Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); -#else - shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ - sts[1]->q_inp = add( sts[1]->q_inp, shift ); - move16(); - - shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ - sts[0]->q_inp = add( sts[0]->q_inp, shift ); - move16(); -#endif Word16 q_inp = s_min( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), s_min( sts[1]->q_inp, sts[1]->q_old_inp ) ); @@ -682,9 +651,6 @@ ivas_error ivas_cpe_enc_fx( // printf("\n%f %f ", hCPE->hStereoClassif->is_speech, hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0]); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { -#ifndef MSAN_FIX - hCPE->hStereoClassif->xtalk_score_fx = floatToFixed( hCPE->hStereoClassif->xtalk_score, 31 ); -#endif // !MSAN_FIX /*flt2fix: dft_synthesize*/ test(); if ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) @@ -866,7 +832,6 @@ ivas_error ivas_cpe_enc_fx( move16(); stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, sts[0]->input32_fx, &out_start_ind, &out_end_ind, 0, input_Fs, input_Fs, 0, NULL ); -#ifdef FIX_ISSUE_1135 // Normalise the input buffer from Q15 Word16 input_norm, q_inp32, common_q, fir_delay_len; input_norm = L_norm_arr( sts[0]->input32_fx + out_start_ind, sub( out_end_ind, out_start_ind ) ); @@ -887,9 +852,6 @@ ivas_error ivas_cpe_enc_fx( move16(); sts[0]->q_old_inp = common_q; move16(); -#else - Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, sts[0]->q_inp ), Q15 ) ); // Q15 -#endif /* iDFT & resampling to 12.8kHz internal sampling rate */ stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_inp_12k8_fx[0] + L_INP_MEM, &out_12k8_start_ind[0], &out_12k8_end_ind[0], 0, input_Fs, INT_FS_12k8, 0, NULL ); @@ -956,11 +918,7 @@ ivas_error ivas_cpe_enc_fx( &ener_fx[n], &relE_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], &vad_hover_flag[n], &attack_flag[n], realBuffer_fx[n], imagBuffer_fx[n], &q_re_im_buf[n], old_wsp_fx[n], &q_old_wsp, pitch_fr_fx[n], voicing_fr_fx[n], &loc_harm[n], &cor_map_sum_fx[n], &vad_flag_dtx[n], enerBuffer_fx[n], &enerBuffer_fx_exp[n], fft_buff_fx[n], &fft_buff_fx_q[n], A_fx[0], lsp_new_fx[0], currFlatness_fx[n], tdm_ratio_idx, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, q_lf_E[n], localVAD_HE_SAD, -#ifdef NONBE_1211_DTX_BR_SWITCHING band_energies_LR_fx, q_band_energies_LR, 0, front_vad_flag, 0, 0, ivas_format, st_ivas->hMCT != NULL, st_ivas->hEncoderConfig->last_ivas_total_brate, ivas_total_brate, &Q_new[n] -#else - band_energies_LR_fx, q_band_energies_LR, 0, front_vad_flag, 0, 0, ivas_format, st_ivas->hMCT != NULL, ivas_total_brate, &Q_new[n] -#endif #ifdef DEBUG_MODE_INFO , ( st_ivas->nSCE + ( cpe_id * CPE_CHANNELS ) + n ) @@ -1418,9 +1376,7 @@ ivas_error create_cpe_enc_fx( hCPE->input_mem_fx[n] = NULL; } } -#ifdef MSAN_FIX set16_fx( hCPE->q_input_mem, Q15, CPE_CHANNELS ); -#endif /*-----------------------------------------------------------------* * stereo classifier: allocate and initialize diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index db5ee872b..59447c022 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -52,11 +52,9 @@ static void computeIntensityVector_enc_fx( const Word16 enc_param_start_band, /* i : first band to process */ const Word16 num_frequency_bands, Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 q_cldfb, Word16 q_intensity_real[DIRAC_MAX_NBANDS] -#endif ); /*------------------------------------------------------------------------- @@ -761,7 +759,6 @@ void computeReferencePower_enc_fx_dirac( *dirac_mono_flag = ivas_dirac_get_mono_flag_fx( band_grouping, Cldfb_RealBuffer, Cldfb_ImagBuffer, e_Cldfb, nchan_ana, mono_frame_count ); /* Q0 */ move16(); } -#ifdef FIX_1127_IMPROVE_SBA_MLD Word16 gb = 0; move16(); FOR( i = 0; i < num_freq_bands; i++ ) @@ -774,7 +771,6 @@ void computeReferencePower_enc_fx_dirac( } e_reference_W = sub( 31, sub( add( shl( sub( 31, e_Cldfb ), 1 ), 1 ), gb ) ); e_reference_temp = e_reference_W; -#endif move16(); FOR( i = 0; i < num_freq_bands; i++ ) { @@ -791,14 +787,8 @@ void computeReferencePower_enc_fx_dirac( FOR( j = brange[0]; j < brange[1]; j++ ) { -#ifdef FIX_1127_IMPROVE_SBA_MLD reference_power_W[i] = W_add( reference_power_W[i], W_shr( W_mult_32_32( Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ), gb ) ); /* exp(2 * e_Cldfb) */ reference_power_W[i] = W_add( reference_power_W[i], W_shr( W_mult_32_32( Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ), gb ) ); /* exp(2 * e_Cldfb) */ -#else - reference_power_W[i] = W_mac_32_32( reference_power_W[i], Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ); - reference_power_W[i] = W_mac_32_32( reference_power_W[i], Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ); - e_reference_W = imult1616( (Word16) 2, e_Cldfb ); -#endif move64(); move64(); } @@ -810,14 +800,8 @@ void computeReferencePower_enc_fx_dirac( /* abs()^2 */ FOR( j = brange[0]; j < brange[1]; j++ ) { -#ifdef FIX_1127_IMPROVE_SBA_MLD reference_power_temp[i] = W_add( reference_power_temp[i], W_shr( W_mult_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), gb ) ); /* exp(2 * e_Cldfb) */ reference_power_temp[i] = W_add( reference_power_temp[i], W_shr( W_mult_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ), gb ) ); /* exp(2 * e_Cldfb) */ -#else - reference_power_temp[i] = W_mac_32_32( reference_power_temp[i], Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ); - reference_power_temp[i] = W_mac_32_32( reference_power_temp[i], Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ); - e_reference_temp = imult1616( (Word16) 2, e_Cldfb ); -#endif move64(); move64(); } @@ -974,11 +958,7 @@ void ivas_dirac_param_est_enc_fx( Word32 *p_Cldfb_ImagBuffer_fx[DIRAC_MAX_ANA_CHANS]; Word16 cldfb_q; Word32 intensity_real_fx[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word16 intensity_real_q[DIRAC_MAX_NBANDS]; -#else - Word16 intensity_real_q; -#endif Word32 direction_vector_fx[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; Word16 direction_vector_q; Word32 diffuseness_vector_fx[DIRAC_MAX_NBANDS]; @@ -1008,10 +988,6 @@ void ivas_dirac_param_est_enc_fx( cldfb_q = 0; move16(); -#ifndef NONBE_IMPROVE_DIRAC_INTENSITY_PREC - intensity_real_q = 0; - move16(); -#endif direction_vector_q = 0; move16(); @@ -1148,15 +1124,10 @@ void ivas_dirac_param_est_enc_fx( hDirAC->hConfig->enc_param_start_band, num_freq_bands, intensity_real_fx -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , cldfb_q, intensity_real_q -#endif ); -#ifndef NONBE_IMPROVE_DIRAC_INTENSITY_PREC - intensity_real_q = sub( shl( cldfb_q, 1 ), 31 ); // 2 * Q_Cldfb + 1 - 32; -#endif IF( !hodirac_flag ) { computeDirectionVectors_fixed( @@ -1168,13 +1139,8 @@ void ivas_dirac_param_est_enc_fx( direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2] -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , 31, intensity_real_q -#else - , - sub( 31, intensity_real_q ) -#endif ); direction_vector_q = Q30; @@ -1190,11 +1156,7 @@ void ivas_dirac_param_est_enc_fx( { /* only real part needed */ Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); /* intensity_real_q */ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Copy( intensity_real_q, &hDirAC->buffer_intensity_real_q[i][index - 1][0], num_freq_bands ); -#else - set16_fx( &hDirAC->buffer_intensity_real_q[i][index - 1][0], intensity_real_q, num_freq_bands ); -#endif } Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); /* exp(reference_power_exp) */ FOR( i = 0; i < num_freq_bands; i++ ) @@ -1406,12 +1368,7 @@ void ivas_dirac_param_est_enc_fx( Scale_sig32( dir_v_fx, 3, -1 ); ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Q29, -#else - - Q30, -#endif &q_direction->band_data[band_m_idx].azimuth_fx[block_m_idx], &q_direction->band_data[band_m_idx].elevation_fx[block_m_idx] ); } @@ -1506,11 +1463,9 @@ static void computeIntensityVector_enc_fx( const Word16 enc_param_start_band, /* i : first band to process Q0*/ const Word16 num_frequency_bands, /* Q0 */ Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] /* q_intensity_real */ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 q_cldfb, Word16 q_intensity_real[DIRAC_MAX_NBANDS] -#endif ) { /* Reminder @@ -1520,20 +1475,16 @@ static void computeIntensityVector_enc_fx( Word16 i, j; Word32 real, img; Word16 brange[2]; -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word16 shift_value = sub( shl( q_cldfb, 1 ), 31 ); -#endif FOR( i = 0; i < num_frequency_bands; i++ ) { brange[0] = hDirAC->band_grouping[i + enc_param_start_band]; /* Q0 */ move16(); brange[1] = hDirAC->band_grouping[i + enc_param_start_band + 1]; /* Q0 */ move16(); -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word16 num_bins = sub( brange[1], brange[0] ); Word16 gb = find_guarded_bits_fx( num_bins ); Word16 norm; -#endif intensity_real[0][i] = 0; move32(); intensity_real[1][i] = 0; @@ -1552,7 +1503,6 @@ static void computeIntensityVector_enc_fx( move32(); img = Cldfb_ImagBuffer[0][j]; move32(); -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word64 t1, t2, t3; t1 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), Cldfb_ImagBuffer[3][j], img ); /* 2 * q_cldfb + 1 */ t2 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), Cldfb_ImagBuffer[1][j], img ); /* 2 * q_cldfb + 1 */ @@ -1564,14 +1514,7 @@ static void computeIntensityVector_enc_fx( tmp_1 = W_add( tmp_1, t1 ); /* 2 * q_cldfb + 1 */ tmp_2 = W_add( tmp_2, t2 ); /* 2 * q_cldfb + 1 */ tmp_3 = W_add( tmp_3, t3 ); /* 2 * q_cldfb + 1 */ -#else - /* Intensity is XYZ order, audio is WYZX order. */ - tmp_1 = W_add( tmp_1, W_add( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), W_mult_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); - tmp_2 = W_add( tmp_2, W_add( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), W_mult_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); - tmp_3 = W_add( tmp_3, W_add( W_mult_32_32( Cldfb_RealBuffer[2][j], real ), W_mult_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); -#endif } -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC norm = 63; move16(); IF( tmp_1 != 0 ) @@ -1593,15 +1536,6 @@ static void computeIntensityVector_enc_fx( intensity_real[2][i] = W_extract_h( W_shl( tmp_3, norm ) ); // shift_value - (gb - norm) q_intensity_real[i] = sub( shift_value, sub( gb, norm ) ); move16(); -#else - - intensity_real[0][i] = W_extract_h( tmp_1 ); // output Q= 2* input_q + 1 - 32 - move32(); - intensity_real[1][i] = W_extract_h( tmp_2 ); // output Q= 2* input_q + 1 - 32 - move32(); - intensity_real[2][i] = W_extract_h( tmp_3 ); // output Q= 2* input_q + 1 - 32 - move32(); -#endif } return; diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index b37e61829..a53e40ee6 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -621,11 +621,7 @@ ivas_error front_vad_spar_fx( corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ -#ifdef NONBE_1211_DTX_BR_SWITCHING dtx_ivas_fx( st, hEncoderConfig->last_ivas_total_brate, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); -#else - dtx_ivas_fx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); -#endif /* linear prediction analysis */ alw_pitch_lag_12k8[0] = st->old_pitch_la; /* Q0 */ diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 6aba283be..b06acfbac 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -174,11 +174,7 @@ Word16 ivas_ism_dtx_enc_fx( ( EQ_16( nchan_ism, 2 ) && LE_32( ivas_total_brate, IVAS_48k ) ) || ( EQ_16( nchan_ism, 3 ) && LE_32( ivas_total_brate, IVAS_80k ) ) || ( EQ_16( nchan_ism, 4 ) && LE_32( ivas_total_brate, IVAS_96k ) ) || -#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD LT_16( lp_noise_max_fx, ( DTX_THR << 8 ) ) ) ) -#else - LT_16( lp_noise_max_fx, ( 15 << 8 ) ) ) ) -#endif { dtx_flag = 0; move16(); diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index c2f77c159..7f9962098 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -116,12 +116,10 @@ ivas_error ivas_ism_enc_fx( error = IVAS_ERR_OK; move32(); -#ifdef MSAN_FIX FOR( i = 0; i < MAX_NUM_OBJECTS; i++ ) { set16_zero_fx( old_inp_12k8_fx[i][0], L_INP_12k8 ); } -#endif set16_fx( q_re_im_buf, 0, MAX_NUM_OBJECTS ); @@ -247,11 +245,7 @@ ivas_error ivas_ism_enc_fx( error = pre_proc_front_ivas_fx( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8_fx[sce_id][0], old_inp_16k_fx[sce_id][0], &ener_fx[sce_id][0], &relE_fx[sce_id][0], A_fx[sce_id][0], Aw_fx[sce_id][0], epsP_fx[sce_id][0], &epsP_fx_q[sce_id][0], lsp_new_fx[sce_id][0], lsp_mid_fx[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer_fx[sce_id][0], imagBuffer_fx[sce_id][0], &q_re_im_buf[sce_id], old_wsp_fx[sce_id][0], &q_old_wsp, pitch_fr_fx[sce_id][0], voicing_fr_fx[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum_fx[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer_fx[sce_id][0], &enerBuffer_fx_exp[sce_id][0], -#ifdef NONBE_1211_DTX_BR_SWITCHING fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] -#else - fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] -#endif #ifdef DEBUG_MODE_INFO , st->id_element @@ -286,11 +280,7 @@ ivas_error ivas_ism_enc_fx( test(); IF( st_ivas->hSCE[j] && st_ivas->hSCE[j]->hCoreCoder[0] ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ -#endif st_ivas->hSCE[j]->hCoreCoder[0]->q_inp32 = Q11; move16(); } diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index 8e6e0c93f..1efbb2123 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -314,10 +314,8 @@ ivas_error ivas_ism_metadata_enc_fx( } ELSE IF( EQ_16( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ) ) { -#ifdef NONBE_1273_ISM_METADATA_COUNTER hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; move16(); -#endif lowrate_metadata_flag[ch] = 1; move16(); hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; @@ -650,10 +648,8 @@ ivas_error ivas_ism_metadata_enc_fx( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); -#ifdef NONBE_1273_ISM_METADATA_COUNTER hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); move16(); -#endif } ELSE { @@ -821,10 +817,8 @@ ivas_error ivas_ism_metadata_enc_fx( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); -#ifdef NONBE_1273_ISM_METADATA_COUNTER hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); move16(); -#endif } ELSE { diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index da1f836df..080a62a9d 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -987,11 +987,7 @@ ivas_error ivas_masa_enc_config_fx( /* Setup importance weights for two-direction band selection. */ IF( EQ_16( hMasa->config.numberOfDirections, 2 ) ) { -#ifdef MSAN_FIX set32_fx( hMasa->data.importanceWeight_fx, ONE_IN_Q30 /*1.0f Q30*/, MASA_FREQUENCY_BANDS ); -#else - set32_fx( hMasa->data.importanceWeight_fx, ONE_IN_Q30 /*1.0f Q30*/, hMasa->config.numCodingBands ); -#endif IF( EQ_16( hMasa->config.numCodingBands, 5 ) ) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 17fefec7e..039bbdf98 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1010,11 +1010,7 @@ static void ivas_param_mc_param_est_enc_fx( Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e ); } L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); -#ifdef FIX_ISSUE_1154 L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( L_tmp, EPSILLON_FX ), &tmp_e ) ); -#else - L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_tmp, &tmp_e ) ); -#endif tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); @@ -1392,11 +1388,7 @@ static void ivas_param_mc_quantize_ilds_fx( ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_fx[ref_channel_idx][ref_channel_idx], Cx_e[ref_channel_idx][ref_channel_idx], &ref_ener_e ); } ref_ener_fx = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); -#ifdef FIX_ISSUE_1154 L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( ref_ener_fx, EPSILLON_FX ), &tmp_e ) ); -#else - L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], ref_ener_fx, &tmp_e ) ); -#endif tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); /*10 in Q21 = 1342177280*/ ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q21 diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index fd5cb6217..cad29b146 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -1040,12 +1040,6 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( IF( LT_16( maxbands, IVAS_MAX_NUM_BANDS ) ) { -#ifndef FIX_1133_IMPROVE_MC_MLD - *exp_alphas = 0; - move16(); - *exp_betas = 0; - move16(); -#endif FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) { FOR( bnd = maxbands; bnd < IVAS_MAX_NUM_BANDS; bnd++ ) diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index 22f21dceb..0071b67ea 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -940,13 +940,11 @@ void ivas_mcmasa_param_est_enc_fx( Word16 surroundingCoherence_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; Word16 numAnalysisChannels; -#ifdef MSAN_FIX FOR( i = 0; i < MCMASA_MAX_ANA_CHANS; i++ ) { set_zero_fx( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ); set_zero_fx( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ); } -#endif num_freq_bins = idiv1616( input_frame, MDFT_NO_COL_MAX ); num_freq_bands = hMcMasa->nbands; @@ -1181,10 +1179,8 @@ void ivas_mcmasa_param_est_enc_fx( direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], c_e -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , NULL -#endif ); /* Power and intensity estimation for diffuseness */ diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 71515571d..548a56717 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -270,7 +270,6 @@ void ivas_mct_core_enc_fx( nCPE = add( nCPE, 1 ); } -#ifdef MSAN_FIX FOR( ch = 0; ch < MCT_MAX_CHANNELS; ch++ ) { set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k ); @@ -278,7 +277,6 @@ void ivas_mct_core_enc_fx( move16(); set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX ); } -#endif // MSAN_FIX FOR( ch = 0; ch < nChannels; ch++ ) { set32_fx( inv_spectrum_long_fx[ch], 0, L_FRAME48k ); @@ -334,7 +332,6 @@ void ivas_mct_core_enc_fx( IF( switch_bw ) { -#ifdef FIX_USAN_ISSUES IF( sts[ch_core]->hIGFEnc == NULL ) { initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, @@ -345,10 +342,6 @@ void ivas_mct_core_enc_fx( initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); } -#else - initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, - sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); -#endif } IF( sts[ch_core]->igf ) @@ -653,11 +646,7 @@ void ivas_mct_core_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#else ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif st->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index a8ba9a320..78bf976d1 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -1116,11 +1116,7 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[p_ch[ch]], sub( Q31, q_powerSpec[p_ch[ch]] ), N_MAX + L_MDCT_OVLP_MAX ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#else ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); @@ -1161,11 +1157,7 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powerSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#else ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 9f674473e..4b5b3fcbe 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -429,17 +429,9 @@ static void kernel_switch_update_transforms_fx( Word32 factor; n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); -#ifdef MSAN_FIX Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 -#else - Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), -Q1 ); // Q0 -> Q-1 -#endif wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 -#ifdef MSAN_FIX Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 -#else - Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), Q1 ); // Q-1 -> Q0 -#endif Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); @@ -545,11 +537,7 @@ static void kernel_switch_update_transforms_fx( Copy_Scale_sig_32_16( windowedTimeSignal + 2, windowedTimeSignal_16 + 2, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), -Q16 ); // *q_windowedTimeSignal - Q16 WindowSignal( hTcxCfg, shr( leftOverlap, 1 ), RECTANGULAR_OVERLAP, MIN_OVERLAP, &leftOverlap, &rightOverlap, windowedTimeSignal_16 + 2, &s, tcx5Win, 0, 1 ); // *q_windowedTimeSignal - Q16 Copy_Scale_sig_16_32_no_sat( tcx5Win, tcx5Win_32, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), Q16 ); // *q_windowedTimeSignal -#ifdef FIX_ISSUE_1157 q_shift = -Q8; -#else - q_shift = -Q7; -#endif move16(); scale_sig32( tcx5Win_32, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift kernel_switch_trafo_fx( tcx5Win_32, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift @@ -579,11 +567,7 @@ static void kernel_switch_update_transforms_fx( ELSE /* tcxTransType != TCX_5 */ { Word16 q_shift, q_com, q_temp; -#ifdef FIX_ISSUE_1157 q_shift = -Q8; -#else - q_shift = -Q7; -#endif move16(); scale_sig32( windowedTimeSignal + 2, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift kernel_switch_trafo_fx( windowedTimeSignal + 2, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift @@ -912,13 +896,8 @@ static UWord16 enc_ste_pre_mdct( absMagnR_fx = Sqrt32( L_add( Mpy_32_32( sigR1_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI1_fx[s], sigI1_fx[s] ) ), &absMagnR_e ); corr_fx = L_add( corr_fx, L_add( Mpy_32_32( sigR0_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI0_fx[s], sigI1_fx[s] ) ) ); // q_com*2 - 31 -#ifdef FIX_ISSUE_1092 sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 -#else - sumL_fx = L_add( sumL_fx, L_add( sigR0_fx[s], sigI0_fx[s] ) ); // q_com - sumR_fx = L_add( sumR_fx, L_add( sigR1_fx[s], sigI1_fx[s] ) ); // q_com -#endif sumMagnL_fx = BASOP_Util_Add_Mant32Exp( sumMagnL_fx, sumMagnL_e, absMagnL_fx, absMagnL_e, &sumMagnL_e ); sumMagnR_fx = BASOP_Util_Add_Mant32Exp( sumMagnR_fx, sumMagnR_e, absMagnR_fx, absMagnR_e, &sumMagnR_e ); sumPrdLR_fx = BASOP_Util_Add_Mant32Exp( sumPrdLR_fx, sumPrdLR_e, Mpy_32_32( absMagnL_fx, absMagnR_fx ), add( absMagnL_e, absMagnR_e ), &sumPrdLR_e ); @@ -930,11 +909,7 @@ static UWord16 enc_ste_pre_mdct( temp1 = L_shl( preproLen, x1 ); corr_fx = Mpy_32_32( corr_fx, temp1 ); x1 = sub( 62, add( shl( *q_com, 1 ), x1 ) ); -#ifdef FIX_ISSUE_1092 corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( sub( *q_com, 1 ), 1 ) ), &x1 ); -#else - corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( *q_com, 1 ) ), &x1 ); -#endif IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( corr_fx, x1, -maxSqrValue_fx, 52 ), -1 ) ) { @@ -1181,7 +1156,6 @@ void ivas_mdct_core_whitening_enc_fx( push_wmops( "mdct_core_whitening" ); -#ifdef MSAN_FIX FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { FOR( i = 0; i < NB_DIV; i++ ) @@ -1195,7 +1169,6 @@ void ivas_mdct_core_whitening_enc_fx( set16_fx( orig_spectrum_e[ch], 0, NB_DIV ); } set16_fx( q_windowedSignal, Q31, CPE_CHANNELS ); -#endif q_com = Q31; q_min = 0; move16(); @@ -1235,9 +1208,7 @@ void ivas_mdct_core_whitening_enc_fx( orig_spectrum[ch][1] = orig_spectrum_long[ch] + N_TCX10_MAX; mdst_spectrum_fx[ch][0] = mdst_spectrum_long_fx[ch]; mdst_spectrum_fx[ch][1] = mdst_spectrum_long_fx[ch] + N_TCX10_MAX; -#ifdef MSAN_FIX set32_fx( temp_buffer, 0, 15 * L_FRAME48k / 8 ); -#endif } windowedSignal_fx[0] = orig_spectrum_long[0]; /* NOTE temporarily available */ diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index d31e6d53d..1433c988f 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -1050,10 +1050,8 @@ static void ivas_omasa_param_est_enc_fx( move16(); /* Need to initialize renormalization_factors, and variables to be normalized */ -#ifdef MSAN_FIX set_zero_fx( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); set_zero_fx( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); -#endif set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands ); set_zero_fx( diffuseness_m_fx, hOMasa->nbands ); @@ -1202,10 +1200,8 @@ static void ivas_omasa_param_est_enc_fx( intensity_real_e = sub( add( 62, guard_bits ), shl( q, 1 ) ); computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , NULL -#endif ); /* Power estimation for diffuseness */ diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 0ca93e1a1..dbff29d68 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -77,11 +77,7 @@ static void ivas_merge_sba_transports_fx( { FOR( j = 0; j < input_frame; j++ ) { -#ifdef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS data_out_f[i][j] = L_shr( L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ), Q1 ); -#else - data_out_f[i][j] = L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ); -#endif move32(); } } @@ -479,9 +475,6 @@ static void ivas_osba_render_ism_to_sba_fx( Word16 azimuth_fx, elevation_fx; Word32 gains_fx[MAX_INPUT_CHANNELS]; Word32 g1_fx, g2_fx; -#ifndef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS - Word32 output_gain_fx; -#endif Word16 nchan_sba; nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) ); @@ -524,21 +517,6 @@ static void ivas_osba_render_ism_to_sba_fx( } *Q_data = sub( *Q_data, 2 ); -#ifndef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS - /* Gain with loudness-matching gains */ - // output_gain = 0.7499f; - output_gain_fx = 1610397988; // 0.7499f in Q31 - move32(); - FOR( j = 0; j < nchan_sba; j++ ) - { - FOR( k = 0; k < input_frame; k++ ) - { - // data_out_f[j][k] *= output_gain; - data_out_fx[j][k] = Mpy_32_32( data_out_fx[j][k], output_gain_fx ); - move32(); - } - } -#endif return; } diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 7de54c482..10380f422 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -2500,11 +2500,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( } ELSE { -#ifdef FIX_USAN_ISSUES avg_elevation_index = (UWord16) L_add( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ); -#else - avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ) ); -#endif } // avg_elevation_index = (uint16_t) ( ( avg_elevation_index + avg_elevation_alphabet ) % avg_elevation_alphabet ); avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index, avg_elevation_alphabet ) % avg_elevation_alphabet ); @@ -2639,13 +2635,8 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( FOR( avg_azimuth_offset = 0; avg_azimuth_offset < q_direction->cfg.search_effort; avg_azimuth_offset++ ) { set_zero_fx( avg_direction_vector, 3 ); -#ifdef FIX_USAN_ISSUES avg_azimuth_index = (UWord16) L_add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); avg_azimuth_index = (UWord16) ( L_add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); -#else - avg_azimuth_index = (UWord16) add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); - avg_azimuth_index = (UWord16) ( add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); -#endif all_zero_dist_azimuth_indexes = 1; move16(); azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); @@ -5452,11 +5443,7 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { -#ifdef FIX_USAN_ISSUES no_idx16 = add( shr( nbits_fr, 4 ), 1 ); -#else - no_idx16 = shr_r( nbits_fr, 4 ); -#endif } /* write combined index */ @@ -5478,11 +5465,7 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { -#ifdef FIX_USAN_ISSUES no_idx16 = add( shr( nbits_fr1, 4 ), 1 ); -#else - no_idx16 = shr_r( nbits_fr1, 4 ); -#endif } assert( no_idx16 <= 4 ); diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 3a0f19c50..b2e0e9c69 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -120,9 +120,7 @@ ivas_error ivas_sce_enc_fx( * Initialization - general *-----------------------------------------------------------------*/ -#ifdef MSAN_FIX set16_zero_fx( old_inp_12k8_fx[0], L_INP_12k8 ); -#endif Copy32( data_fx, st->input32_fx, input_frame ); // Q(q_data_fx) q_input = sub( add( L_norm_arr( st->input32_fx, input_frame ), q_data_fx ), 16 ); @@ -253,11 +251,7 @@ ivas_error ivas_sce_enc_fx( &ener_fx[0], &relE_fx[0], A_fx[0], Aw_fx[0], epsP_fx[0], &epsP_fx_q[0], lsp_new_fx[0], lsp_mid_fx[0], &vad_hover_flag[0], &attack_flag[0], realBuffer_fx[0], imagBuffer_fx[0], &q_re_im_buf, old_wsp_fx[0], &q_old_wsp, pitch_fr_fx[0], voicing_fr_fx[0], &loc_harm[0], &cor_map_sum_fx[0], &vad_flag_dtx[0], enerBuffer_fx[0], &enerBuffer_fx_exp[0], fft_buff_fx[0], &fft_buff_fx_q[0], A_fx[0], lsp_new_fx[0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, flag_16k_smc, -#ifdef NONBE_1211_DTX_BR_SWITCHING st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[0] -#else - st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[0] -#endif #ifdef DEBUG_MODE_INFO , st->id_element diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 22cd98cad..b7de878a1 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -817,15 +817,10 @@ Word16 quantize_sns_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -#ifdef MSAN_FIX FOR( k = 0; k < nSubframes; k++ ) { scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); // Q(31-sns_e_tmp[ch][k]) } -#else - scale_sig32( snsQ_out_fx[ch][0], M, sub( sns_e_tmp[ch][0], *sns_e ) ); - scale_sig32( snsQ_out_fx[ch][1], M, sub( sns_e_tmp[ch][1], *sns_e ) ); -#endif } /* get back to L/F representation */ test(); diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index ef278d188..4a6543026 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -88,12 +88,8 @@ typedef struct stereo_itd_data_struct Word16 prev_sum_nrg_L_lb_fx_e; Word32 prev_xcorr_lb_fx[STEREO_DFT_XCORR_LB_MAX]; Word16 prev_xcorr_lb_fx_e; -#ifdef FIX_ISSUE_1092 Word32 E_band_n_fx[STEREO_DFT_ITD_VAD_BAND_NUM]; /*E_band_n_exp*/ Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM]; -#else - Word32 E_band_n_fx[STEREO_DFT_ITD_VAD_BAND_NUM]; /*Q0*/ -#endif Word32 xcorr_smooth_fx[STEREO_DFT_N_32k_ENC]; Word16 xcorr_smooth_fx_e[STEREO_DFT_N_32k_ENC]; Word32 lp_phat_peak_fx; /* low-pass GCC PHAT peak value */ // Q31 @@ -1183,11 +1179,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word32 isd_rate_s_fx; // Q31 -#else - Word16 isd_rate_s_fx; // Q15 -#endif Word32 iccr_s_fx; // Q31 Word32 ipd_ff_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word32 Pr_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 @@ -1228,11 +1220,7 @@ typedef struct stereo_dmx_evs_enc_data_structure STEREO_DMX_EVS_POC_HANDLE hPOC; STEREO_DMX_EVS_PHA_HANDLE hPHA; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx; // Q0 -#else - Word32 itd_fx; // Q16 -#endif Word32 pre_dmx_energy_fx[1]; Word16 pre_dmx_energy_fx_e[1]; diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 3e148a5ae..3e69a0ca6 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -1697,11 +1697,7 @@ static void edge_detect_fx( } } -#ifndef FIX_1297_OVERFLOW - *edge_str = extract_l( L_shr( edge_min, 10 ) ); // Q15 -#else *edge_str = extract_h( L_shl_sat( edge_min, 16 - 10 ) ); // Q15 -#endif move16(); *edge_type = et; // Q0 move16(); diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 3eb6c0e82..cebbc2619 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -593,10 +593,8 @@ void stereo_dft_enc_reset_fx( move16(); hStereoDft->dmx_res_all_prev_fx = 1; move32(); -#ifdef MSAN_FIX hStereoDft->dmx_res_all_prev_fx_e = 31; move16(); -#endif hStereoDft->last_res_cod_mode_modify_flag = 0; move16(); hStereoDft->res_cod_sw_flag = 0; @@ -750,9 +748,7 @@ void stereo_enc_itd_init_fx( hItd->prev_xcorr_lb_fx_e = 0; move16(); set32_fx( hItd->E_band_n_fx, ITD_VAD_E_BAND_N_INIT, STEREO_DFT_ITD_VAD_BAND_NUM ); -#ifdef FIX_ISSUE_1092 set16_fx( hItd->E_band_n_exp, Q31, STEREO_DFT_ITD_VAD_BAND_NUM ); -#endif hItd->vad_frm_cnt = 0; move16(); hItd->pre_vad = 0; @@ -1102,11 +1098,7 @@ void stereo_dft_enc_analyze_fx( { FOR( n = 0; n < n_channels; n++ ) { -#ifdef MSAN_FIX Scale_sig( hStereoDft->input_mem_itd_fx[n], dft_ovl, sub( sts[n]->q_inp, hStereoDft->q_input_mem_itd[n] ) ); // Q(sts[n]->q_inp) -#else - Scale_sig( hStereoDft->input_mem_itd_fx[n], STEREO_DFT_OVL_MAX, sts[n]->q_inp - hStereoDft->q_input_mem_itd[n] ); -#endif // MSAN_FIX hStereoDft->q_input_mem_itd[n] = sts[n]->q_inp; move16(); Copy( hStereoDft->input_mem_itd_fx[n], input_mem[n], dft_ovl ); @@ -1657,11 +1649,7 @@ void stereo_dft_enc_process_fx( pDFT_L_fx = hStereoDft->DFT_fx[0]; pDFT_R_fx = hStereoDft->DFT_fx[1]; -#ifdef MSAN_FIX FOR( i = 0; i < hStereoDft->NFFT; i++ ) -#else - FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) -#endif // MSAN_FIX { tmp_e = norm_l( hStereoDft->DFT_fx[0][i] ); pDFT_L_fx[i] = L_shl( hStereoDft->DFT_fx[0][i], tmp_e ); diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index af10f7dea..b7429e2e7 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -203,12 +203,8 @@ static void stereo_dft_quantize_itd_fx( *-------------------------------------------------------------------------*/ static Word32 itd_vad_ms_snr_calc_fx( -#ifdef FIX_ISSUE_1092 Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], -#else - Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 -#endif Word32 *Spd, // Q(31-Spd_e) Word16 *Spd_e, Word32 *E_band, // Q(31-E_band_e) @@ -251,11 +247,7 @@ static Word32 itd_vad_ms_snr_calc_fx( // snr[i] = E_band[i] / E_band_n[i]; snr[i] = BASOP_Util_Divide3232_Scale_cadence( E_band[i], E_band_n[i], &snr_e[i] ); move32(); -#ifdef FIX_ISSUE_1092 snr_e[i] = add( snr_e[i], sub( E_band_e[i], E_band_n_exp[i] ) ); -#else - snr_e[i] = add( snr_e[i], sub( E_band_e[i], 31 ) ); -#endif move16(); // if ( snr[i] < 1 ) IF( BASOP_Util_Cmp_Mant32Exp( snr[i], snr_e[i], 1, 31 ) < 0 ) @@ -291,12 +283,8 @@ static Word32 itd_vad_ms_snr_calc_fx( * *-------------------------------------------------------------------------*/ static void itd_vad_background_update_fx( -#ifdef FIX_ISSUE_1092 Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], -#else - Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 -#endif Word16 *vad_frm_cnt, const Word32 ms_snr, // Q(31-ms_snr_e) const Word16 ms_snr_e, @@ -338,19 +326,10 @@ static void itd_vad_background_update_fx( Word16 q_temp = norm_l( *vad_frm_cnt ); L_temp = L_shl( *vad_frm_cnt, q_temp ); L_temp_e = sub( 31, q_temp ); -#ifdef FIX_ISSUE_1092 L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( E_band_n_exp[i], L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); -#else - L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( 31, L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); -#endif E_band_n[i] = BASOP_Util_Divide3232_Scale_cadence( L_temp, L_add( *vad_frm_cnt, 1 ), &E_band_n_e_tmp ); move32(); -#ifdef FIX_ISSUE_1092 E_band_n_exp[i] = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); -#else - E_band_n_e_tmp = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); - E_band_n[i] = L_shr_r( E_band_n[i], sub( 31, E_band_n_e_tmp ) ); // Q31 -#endif move16(); } } @@ -362,7 +341,6 @@ static void itd_vad_background_update_fx( FOR( i = 0; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) { // E_band_n[i] = 0.96f * E_band_n[i] + 0.04f * E_band[i]; -#ifdef FIX_ISSUE_1092 E_band_n[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 2061584302 /*0.96 in Q31*/, E_band_n[i] ), E_band_n_exp[i], Mpy_32_32( 85899346 /*0.04 in Q31*/, E_band[i] ), E_band_e[i], &E_band_n_e_tmp ); move32(); E_band_n_exp[i] = E_band_n_e_tmp; @@ -375,20 +353,6 @@ static void itd_vad_background_update_fx( E_band_n_exp[i] = 0; move16(); } -#else - E_band_n[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 2061584302, E_band_n[i] ), 31, Mpy_32_32( 85899346, E_band[i] ), E_band_e[i], &E_band_n_e_tmp ); - move32(); - // if ( E_band_n[i] < 1.0f ) - IF( BASOP_Util_Cmp_Mant32Exp( E_band_n[i], E_band_n_e_tmp, MAX_32, 0 ) < 0 ) - { - E_band_n[i] = MAX_32; - move32(); - E_band_n_e_tmp = 0; - move16(); - } - E_band_n[i] = L_shr_r( E_band_n[i], sub( 31, E_band_n_e_tmp ) ); // Q31 - move32(); -#endif } } } @@ -402,12 +366,8 @@ static void itd_vad_background_update_fx( *-------------------------------------------------------------------------*/ static Word16 stereo_dft_enc_itd_vad_fx( -#ifdef FIX_ISSUE_1092 Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], -#else - Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 -#endif Word16 *vad_frm_cnt, Word32 *Spd_L, // Q(31-Spd_L_e) Word16 *Spd_L_e, @@ -434,17 +394,10 @@ static Word16 stereo_dft_enc_itd_vad_fx( Spd_e[i] = sub( Spd_e[i], 1 ); move16(); } -#ifdef FIX_ISSUE_1092 *mssnr = itd_vad_ms_snr_calc_fx( E_band_n, E_band_n_exp, Spd, Spd_e, E_band, E_band_e, mssnr_e ); move32(); itd_vad_background_update_fx( E_band_n, E_band_n_exp, vad_frm_cnt, *mssnr, *mssnr_e, E_band, E_band_e ); -#else - *mssnr = itd_vad_ms_snr_calc_fx( E_band_n, Spd, Spd_e, E_band, E_band_e, mssnr_e ); - move32(); - - itd_vad_background_update_fx( E_band_n, vad_frm_cnt, *mssnr, *mssnr_e, E_band, E_band_e ); -#endif // if ( *mssnr < ITD_VAD_THRSHOLD ) IF( BASOP_Util_Cmp_Mant32Exp( *mssnr, *mssnr_e, ITD_VAD_THRSHOLD_Q31, 0 ) < 0 ) { @@ -1476,11 +1429,7 @@ void stereo_dft_enc_compute_itd_fx( } // L_temp = sum2_32_fx( &Spd_L[1], 11, &L_temp_e ); sum_nrg_L_lb = BASOP_Util_Add_Mant32Exp( sum_nrg_L_lb, sum_nrg_L_lb_e, L_temp, L_temp_e, &sum_nrg_L_lb_e ); -#ifdef FIX_ISSUE_1092 vad_flag_itd = stereo_dft_enc_itd_vad_fx( hItd->E_band_n_fx, hItd->E_band_n_exp, &( hItd->vad_frm_cnt ), Spd_L, Spd_L_e, Spd_R, Spd_R_e, &mssnr, &mssnr_e ); -#else - vad_flag_itd = stereo_dft_enc_itd_vad_fx( hItd->E_band_n_fx, &( hItd->vad_frm_cnt ), Spd_L, Spd_L_e, Spd_R, Spd_R_e, &mssnr, &mssnr_e ); -#endif vad_flag_itd = vad_flag_itd && vad_flag_dtx[0]; // if ( sum_nrg_L < EPSILON ) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 933270c33..2ed17e25a 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -68,17 +68,11 @@ #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA #define STEREO_DMX_EVS_ISD_FORGETTING_Q31 2040109465 #define STEREO_DMX_EVS_ISD_1MFORGETTING_Q15 1638 #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 773094113 #define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 923417968 #define STEREO_DMX_EVS_ISD_INVTHRES_H 1270700383 -#else -#define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 -#define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 11796 -#define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 14090 -#endif #define STEREO_DMX_EVS_ICCR_FORGETTING_Q31 1503238554 #define STEREO_DMX_EVS_ICCR_HYST_L_Q31 1610612736 @@ -161,11 +155,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ -#else - Word32 itd[], /* o : estimated itd Q16 */ -#endif const Word16 input_frame /* i : input frame length per channel */ ); static void adapt_gain_fx( @@ -208,11 +198,7 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd */ -#else - Word32 itd_fx[], /* o : estimated itd */ -#endif const Word16 input_frame, /* i : input frame length per channel */ const Word32 ratio_fixed /* i : adapting ratio */ ); @@ -621,20 +607,12 @@ static void calc_poc_fx( Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), STEREO_DMX_EVS_ISD_INVTHRES_H ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) -#else - IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) -#endif { isd_cnt_h = add( isd_cnt_h, 1 ); } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA W_tmp = W_add( W_mult0_32_32( Mpy_32_32_r( Dr, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Dr ), W_mult0_32_32( Mpy_32_32_r( Di, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Di ) ); // Q62 IF( LT_64( W_add( W_mult0_32_32( Nr, Nr ), W_mult0_32_32( Ni, Ni ) ), W_tmp ) ) // Q62 -#else - IF( LT_32( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), Mpy_32_32_r( STEREO_DMX_EVS_ISD_THRES_L_Q31, L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) ) -#endif { isd_cnt_l = add( isd_cnt_l, 1 ); } @@ -643,19 +621,10 @@ static void calc_poc_fx( isd_rate = BASOP_Util_Divide1616_Scale( isd_cnt_h, freq_8k, &isd_rate_e ); // Saturation to handle values close to 1.0f isd_rate = shl_sat( isd_rate, isd_rate_e ); // Q15 -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->isd_rate_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ISD_FORGETTING_Q31, hPHA->isd_rate_s_fx ), L_mult( STEREO_DMX_EVS_ISD_1MFORGETTING_Q15, isd_rate ) ); move32(); -#else - hPHA->isd_rate_s_fx = add( mult_r( STEREO_DMX_EVS_ISD_FORGETTING_Q15, hPHA->isd_rate_s_fx ), mult_r( MAX_16 - STEREO_DMX_EVS_ISD_FORGETTING_Q15, isd_rate ) ); - move16(); -#endif -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 ) ) -#else - IF( GT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 ) ) -#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD ) ) { @@ -680,11 +649,7 @@ static void calc_poc_fx( hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; move32(); } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA ELSE IF( LT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 ) ) -#else - ELSE IF( LT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 ) ) -#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD2 ) ) { @@ -752,7 +717,6 @@ static void calc_poc_fx( /* Energy */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA // Left W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); // Q(62-(2*specL_e)) -> Q(63 - ((2*specL_e) +1)) @@ -773,12 +737,6 @@ static void calc_poc_fx( } tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], W_round64_L( W_tmp ), sub( shl( spec_e, 1 ), sub( L_tmp_e, 1 ) ), &tEr_e[n] ); move32(); -#else - tEl[n] = BASOP_Util_Add_Mant32Exp( tEl[n], tEl_e[n], L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &tEl_e[n] ); - move32(); - tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &tEr_e[n] ); - move32(); -#endif /* IPD */ // IPDr = L_add(Mpy_32_32_r(specLr[i], specRr[i]), Mpy_32_32_r(specLi[i], specRi[i])); //2*spec_e @@ -809,7 +767,6 @@ static void calc_poc_fx( tIPDr = L_sub( Mpy_32_32_r( specRr[i], IPDr ), Mpy_32_32_r( specRi[i], IPDi ) ); // spec_e tIPDi = L_add( Mpy_32_32_r( specRr[i], IPDi ), Mpy_32_32_r( specRi[i], IPDr ) ); // spec_e -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), 0, &Nr_e ); Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), 0, &Ni_e ); @@ -831,13 +788,6 @@ static void calc_poc_fx( W_tmp = W_shl( W_tmp, L_tmp_e ); } eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, W_round64_L( W_tmp ), sub( 1, L_tmp_e ), &eneR_e ); -#else - Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), shl( spec_e, 1 ), &Nr_e ); - Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), shl( spec_e, 1 ), &Ni_e ); - - eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &eneL_e ); - eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &eneR_e ); -#endif } // Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON ); @@ -857,19 +807,9 @@ static void calc_poc_fx( move32(); // Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Pn = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); Pn = BASOP_Util_Add_Mant32Exp( Pn, 1, EPSILON_FX_M, EPSILON_FX_E, &Pn_e ); Pn = Isqrt_lc( Pn, &Pn_e ); -#else - L_tmp = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); - L_tmp_e = 1; - move16(); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp_e ); - Pn_e = L_tmp_e; - move16(); - Pn = ISqrt32( L_tmp, &Pn_e ); -#endif Pr[n] = L_shl_sat( Mpy_32_32_r( Pr[n], Pn ), Pn_e ); // Q31 move32(); @@ -1076,17 +1016,7 @@ static void calc_poc_fx( FOR( i = 0; i < hPHA->pha_len; i++ ) { // hPHA->p_curr_taps[n][i] *= hPHA->win[i]; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA - hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 -#else - -#ifdef FIX_ISSUE_1153 hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 -#else - hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 -#endif - -#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA move32(); } @@ -1094,39 +1024,16 @@ static void calc_poc_fx( move32(); energy_e = 0; move16(); -#ifndef NONBE_FIX_1386_STEREO_DMX_EVS_PHA -#ifdef FIX_ISSUE_1153 - Word16 shift = L_norm_arr( hPHA->p_curr_taps_fx[n], hPHA->pha_len ); - IF( shift ) - { - scale_sig32( hPHA->p_curr_taps_fx[n], hPHA->pha_len, 1 ); - shift = 1; - move16(); - } -#endif -#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA FOR( i = 0; i < hPHA->pha_len; i++ ) { -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA - energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); -#else -#ifdef FIX_ISSUE_1153 - energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), shl( sub( 1, shift ), 1 ), &energy_e ); -#else energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); -#endif -#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA } // energy = (float) inv_sqrt( energy + EPSILON ); energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, EPSILON_FX_M, EPSILON_FX_E, &energy_e ); energy = ISqrt32( energy, &energy_e ); FOR( i = 0; i < hPHA->pha_len; i++ ) { -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), sub( energy_e, 1 ) ); // Q30 -#else - hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), energy_e ); // Q31 -#endif move32(); } } @@ -1229,11 +1136,7 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd Q0 */ -#else - Word32 itd_fx[], /* o : estimated itd Q16 */ -#endif const Word16 input_frame, /* i : input frame length per channel */ const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) @@ -1545,11 +1448,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ -#else - Word32 itd[], /* o : estimated itd Q16 */ -#endif const Word16 input_frame /* i : input frame length per channel */ ) { @@ -2090,9 +1989,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_prev_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q25 } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 -#endif mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); move32(); } @@ -2117,9 +2014,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_curr_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q25 } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 -#endif // dmx_pha_data[n] += ftmp * INV_SQRT_2; dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); // Q26 move32(); @@ -2149,11 +2044,7 @@ void stereo_dmx_evs_enc_fx( curr_prc = hStereoDmxEVS->hPHA->curr_prc; move32(); // if ( abs( (int16_t) hStereoDmxEVS->itd ) > hStereoDmxEVS->hPHA->prc_thres ) -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_16( abs_s( hStereoDmxEVS->itd_fx ), hStereoDmxEVS->hPHA->prc_thres ) ) -#else - IF( GT_16( abs_s( round_fx( hStereoDmxEVS->itd_fx ) ), hStereoDmxEVS->hPHA->prc_thres ) ) -#endif { IF( NE_32( hStereoDmxEVS->hPHA->curr_prc, STEREO_DMX_EVS_PRC_POC ) ) { @@ -2276,15 +2167,9 @@ ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS; Word16 n, input_frame; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 m, len, pha_len, fad_len, fad_len2, rfft_ipd_coef_step, n0, input_frame_pha; Word32 *fad_g, fad_r, *ipd_ff; Word16 *win; -#else - Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; - Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; - Word16 *win, tmp_r; -#endif const Word16 *p_ipd_w; Word16 tmp_e; @@ -2516,7 +2401,6 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_len = hStereoDmxEVS->hPHA->fad_len; move16(); -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q14*/, pha_len ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; move16(); @@ -2532,21 +2416,6 @@ ivas_error stereo_dmx_evs_init_encoder_fx( hStereoDmxEVS->hPHA->win_fx[sub( pha_len, 1 )] = 2816; /*0.1718f in Q14*/ move16(); } -#else - trans_len = idiv1616( pha_len, 20 ); - set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q15*/, sub( pha_len, trans_len ) ); - hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; - move16(); - // tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 ); - tmp_r = div_s( 1, add( shl( trans_len, 1 ), 1 ) ); - win = &( hStereoDmxEVS->hPHA->win_fx[pha_len - trans_len] ); - FOR( n = 0; n < trans_len; n++ ) - { - // win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * 1.8f; - win[n] = mult_r( add( ONE_IN_Q14, getCosWord16R2( imult1616( add( n, 1 ), tmp_r ) ) ), 29491 /*1.8/2 in Q15*/ ); - move16(); - } -#endif fad_g = hStereoDmxEVS->hPHA->fad_g_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 057798706..8410f7546 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1094,11 +1094,7 @@ static void corrStatsEst_fx( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */ move32(); -#ifdef FIX_USAN_ISSUES Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ -#else - Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -hStereoTCA->delay_0_mem_fx[0], hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ -#endif inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 { @@ -1968,22 +1964,8 @@ void stereo_tca_enc_fx( Word16 temp_exp, tempF_16fx; Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */ -#ifndef FIX_1300_ICA_SHIFT_QUANT_IMPROV - IF( temp_exp < 0 ) - { - scalar_value = shl( scalar_value, sub( temp_exp, Q3 ) ); // Q12 - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, ONE_IN_Q11, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ - move16(); - } - ELSE - { - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, shl( 1, sub( 14, temp_exp ) ), ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ - move16(); - } -#else scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ -#endif tempF_fx = tempF_16fx; move32(); @@ -2263,7 +2245,6 @@ static void unclr_calc_corr_features_fx( side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */ ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); /* Q31-ener_side_exp */ -#ifdef FIX_ISSUE_1125 Word16 n1, n2, prod_i_exp; Word32 x, y, prod_i; n1 = norm_l( buf1[i] ); @@ -2273,9 +2254,6 @@ static void unclr_calc_corr_features_fx( prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31 prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) ); sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */ -#else - sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); /* Q31-sum_prod_exp */ -#endif } /* average energy of L and R channels */ diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index ad038f0fa..25e2366dd 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -809,11 +809,7 @@ void stereo_icBWE_enc_ivas_fx( Copy_Scale_sig( hStereoICBWE->mem_shb_speech_ref_fx, hStereoICBWE->mem_shb_speech_ref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ) ); // mem_shb_speech_ref_e set32_fx( shb_frame_ref_fx, 0, L_LOOK_16k + L_FRAME16k ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#else - Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#endif hStereoICBWE->mem_shb_speech_ref_e = max_e; shb_frame_ref_e = max_e; move16(); @@ -827,11 +823,7 @@ void stereo_icBWE_enc_ivas_fx( max_e = s_max( hStereoICBWE->mem_shb_speech_nonref_e, shb_speech_nonref_e ); Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#else - Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#endif hStereoICBWE->mem_shb_speech_nonref_e = max_e; shb_frame_nonref_e = max_e; move16(); @@ -1233,9 +1225,7 @@ void stereo_icBWE_preproc_fx( Word32 gD_fx; Word32 input_Fs; -#ifdef MSAN_FIX set16_fx( temp_inp_fx, 0, L_FRAME48k ); -#endif /* initialization */ hStereoTCA = hCPE->hStereoTCA; /* Stereo TCA encoder handle */ diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index b68578542..4255980ad 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -178,10 +178,8 @@ void stereo_mdct_core_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -#ifdef MSAN_FIX set32_fx( mdst_spectrum_long_fx[ch], 0, N_MAX ); set32_fx( orig_spectrum_long_fx[ch], 0, N_MAX ); -#endif p_mdst_spectrum_long_fx[ch] = mdst_spectrum_long_fx[ch]; p_orig_spectrum_long_fx[ch] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][0] = orig_spectrum_long_fx[ch]; @@ -674,11 +672,7 @@ void stereo_mdct_core_enc_fx( q_spectrum = sub( Q31, st->hTcxEnc->spectrum_e[n] ); Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#else ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#endif } } } @@ -719,11 +713,7 @@ void stereo_mdct_core_enc_fx( Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#else ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#endif } } } diff --git a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c index 851df60d5..6c3588cab 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -166,12 +166,10 @@ static void IGF_MsStereoDecision_fx( Word16 pc_target_e, pc_src_e; Word16 tmp1, tmp1_e, tmp2, tmp2_e; -#ifdef MSAN_FIX pc_target_e = 0; pc_src_e = 0; move16(); move16(); -#endif // MSAN_FIX Word16 coh_src = calcCoh_fx( &specL_fx[strt_cpy], &specR_fx[strt_cpy], q_spec, width, &cc_src_fx, &cc_src_e, &pc_src_fx, &pc_src_e ); Word16 coh_target = calcCoh_fx( &specL_fx[hGrid->swb_offset[sfb]], &specR_fx[hGrid->swb_offset[sfb]], q_spec, width, &cc_target_fx, &cc_target_e, &pc_target_fx, &pc_target_e ); diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 0a526561a..5f1208ba7 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -239,16 +239,12 @@ ivas_error stereo_memory_enc_fx( test(); IF( hCPE->hStereoTCA != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { -#ifdef FIX_1132_STACK_CORRUPTION Word16 tmp = extract_h( L_abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); if ( hCPE->hStereoDft->hItd->itd_fx[1] < 0 ) { tmp = negate( tmp ); } set16_fx( hCPE->hStereoTCA->prevCorrLagStats, tmp, 3 ); -#else - set16_fx( hCPE->hStereoTCA->prevCorrLagStats, extract_h( hCPE->hStereoDft->hItd->itd_fx[1] ), 3 ); -#endif IF( hCPE->hStereoDft->hItd->itd_fx[1] >= 0 ) { hCPE->hStereoTCA->prevRefChanIndx = L_CH_INDX; @@ -448,10 +444,8 @@ ivas_error stereo_memory_enc_fx( } fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX st->Q_old_wtda = 0; move16(); -#endif } /* allocate stereo CNG structure */ @@ -679,10 +673,8 @@ void stereo_switching_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); /* sts[n]->q_inp */ -#ifdef FIX_ISSUE_1327 hCPE->q_input_mem[n] = sts[n]->q_inp; move16(); -#endif } } diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 44c08efa8..f9b6b0bf3 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -72,13 +72,8 @@ #define RATIO_MAX 1.5f /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ -#ifdef FIX_1301_CORRECT_TD_CNST #define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ -#else -#define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ -#endif #define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ #define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ #define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ @@ -260,11 +255,7 @@ Word16 stereo_tdm_ener_analysis_fx( rms_thd_fx = L_shr( rms_thd_fx, 2 ); /*Q16*/ /*rms_thd_fx *= 0.25f*/ test(); test(); -#ifdef FIX_1301_CORRECT_TD_CNST IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 4915200 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) -#else - IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 75 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) -#endif { rms_thd_fx = L_shr( rms_thd_fx, 5 ); /* Q16*/ /*rms_thd_fx *= 0.03125f*/ } @@ -338,10 +329,8 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } -#ifdef FIX_1301_CORRECT_TD_CNST rms_L_fx = L_shl( rms_L_fx, sub( Q16, q_rms_L ) ); /* All the following energy comparison are done in Q16 */ rms_R_fx = L_shl( rms_R_fx, sub( Q16, q_rms_R ) ); -#endif test(); IF( EQ_16( hStereoTD->prev_fr_LRTD_TD_dec, 1 ) && side_can_change == 0 ) { @@ -440,11 +429,7 @@ Word16 stereo_tdm_ener_analysis_fx( ELSE { /*ratio_L = ( 1.0f - cosf( EVS_PI * ratio_L / 2.0f ) ) / 2.0f;*/ -#ifdef FIX_1301_CORRECT_TD_CNST ratio_L_fx = L_deposit_h( sub_sat( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) -#else - ratio_L_fx = L_deposit_h( sub( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) -#endif } test(); @@ -650,22 +635,14 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } -#ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 -#else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 -#endif move32(); test(); IF( EQ_16( hStereoTD->tdm_SM_modi_flag, 1 ) && hStereoTD->tdm_LRTD_flag == 0 ) { idx = shr( add( hStereoTD->tdm_last_ratio_idx, add( LRTD_STEREO_MID_IS_PRIM, 1 ) ), 1 ); -#ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 -#else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 -#endif move32(); } @@ -756,10 +733,8 @@ Word16 stereo_tdm_ener_analysis_fx( hCPE->hStereoClassif->ratio_L_fx = ratio_L_fx; /* 31 - ratio_L_e */ move32(); -#ifdef FIX_ISSUE_1125 hCPE->hStereoClassif->ratio_L_e = 1; move16(); -#endif return idx; } @@ -1073,11 +1048,7 @@ static void NOOP_decision_fx( } ELSE { -#ifdef FIX_1301_CORRECT_TD_CNST if ( LT_32( sts[0]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) ) -#else - if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) -#endif { tdm_NOOP_switch_flag = 1; move16(); diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 378068827..8f1d2d9c9 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -336,10 +336,8 @@ ivas_error stereo_set_tdm_fx( } fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX st->Q_old_wtda = 0; move16(); -#endif } } diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index eabfe87b4..159012ac2 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -789,7 +789,6 @@ Word16 ivas_acelp_tcx20_switching_fx( L_frame = L_FRAME; move16(); } -#ifdef MSAN_FIX set16_fx( window_fx, 0, L_LOOK_16k ); set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); FOR( i = 0; i < L_LOOK_16k; i++ ) @@ -799,7 +798,6 @@ Word16 ivas_acelp_tcx20_switching_fx( window_p_fx[i].v.im = 0; move16(); } -#endif L_frame_tmp = L_frame; move16(); @@ -854,7 +852,6 @@ Word16 ivas_acelp_tcx20_switching_fx( overlap = st->hTcxCfg->tcx_mdct_window_delay; move16(); -#ifdef MSAN_FIX FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length / 2; i++ ) { window_fx[st->hTcxCfg->tcx_mdct_window_length - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 @@ -862,15 +859,6 @@ Word16 ivas_acelp_tcx20_switching_fx( window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 move16(); } -#else - FOR( i = 0; i < L_LOOK_16k / 2; i++ ) - { - window_fx[L_LOOK_16k / 2 - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 - move16(); - window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 - move16(); - } -#endif } ELSE { @@ -1047,12 +1035,8 @@ Word16 ivas_acelp_tcx20_switching_fx( IF( LE_32( offset, 0xAA153 ) ) /* 0xAA153 -> 32.f * log2(10)/10 */ { -#ifdef FIX_USAN_ISSUES offset = (Word32) 0xFFD57AB5; /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ move32(); -#else - offset = L_add( 0xFFD57AB5, 0 ); /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ -#endif } offset_tcx = offset; move32(); @@ -1155,11 +1139,7 @@ Word16 ivas_acelp_tcx20_switching_fx( { *pt_ener_sfr = -668739840; /* 0xFFEC1185 -> log2(1e-6) in 6Q25 */ move32(); -#ifdef FIX_USAN_ISSUES tmp32 = (Word32) 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ -#else - tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ -#endif move32(); } ELSE diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index c959ef758..63cbb30e9 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -221,13 +221,9 @@ void encod_gen_2sbfr( LPD_state_HANDLE hLPDmem = st->hLPDmem; -#ifdef FIX_1320_LOWRATE_ACELP Word16 gcode16; Word32 Lgcode, Ltmp; -#endif -#ifdef MSAN_FIX set16_fx( cn, 0, 2 * L_SUBFR ); /* Target vector in residual domain */ -#endif /*------------------------------------------------------------------* * Initializations @@ -268,11 +264,7 @@ void encod_gen_2sbfr( Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new -#ifndef FIX_1320_LOWRATE_ACELP - find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); -#else find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); -#endif q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2, 2 * L_SUBFR, sub( 11, q_h1 ) ); @@ -298,21 +290,13 @@ void encod_gen_2sbfr( * Gain clipping test to avoid unstable synthesis on frame erasure *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, Q_new ); // Q0 -#else clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, sub( Q_new, 1 ) ); // Q0 -#endif /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ -#ifndef FIX_1320_LOWRATE_ACELP - lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); -#else lp_filt_exc_enc_ivas_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); -#endif /* update long-term pitch gain for speech/music classifier */ st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277 /*Q15*/, gain_pit ) ); // Q14 move16(); @@ -345,22 +329,15 @@ void encod_gen_2sbfr( gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); -#ifndef FIX_1320_LOWRATE_ACELP - hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); -#else Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_sat( Lgcode ); /*Q0*/ hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); /* Q15 */ -#endif move16(); /*-----------------------------------------------------------------* * Update memory of the weighting filter *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); -#else Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); @@ -368,7 +345,6 @@ void encod_gen_2sbfr( Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#endif move16(); /*-----------------------------------------------------------------* @@ -376,15 +352,6 @@ void encod_gen_2sbfr( * Save the non-enhanced excitation for FEC_exc *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - FOR( i = 0; i < 2 * L_SUBFR; i++ ) - { - exc2[i + i_subfr] = mult( gain_pit, exc[i + i_subfr] ); - move16(); - exc[i + i_subfr] = add( exc2[i + i_subfr], mult( extract_h( gain_code ), code[i] ) ); - move16(); - } -#else FOR( i = 0; i < 2 * L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ @@ -397,7 +364,6 @@ void encod_gen_2sbfr( move16(); move16(); } -#endif /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ @@ -411,11 +377,7 @@ void encod_gen_2sbfr( * Synthesize speech to update mem_syn_flt[]. * Update A(z) filters *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - E_UTIL_synthesis( 0, p_Aq, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1, M ); -#else Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); -#endif p_Aw += 2 * ( M + 1 ); p_Aq += 2 * ( M + 1 ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 09e3efc84..877fc2045 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1166,11 +1166,7 @@ static ivas_error configureEncoder( test(); test(); test(); -#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH IF( hEncoderConfig->Opt_PCA_ON && !( ( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) && EQ_32( hEncoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( hEncoderConfig->sba_order, SBA_FOA_ORDER ) ) ) -#else - if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) -#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 0851e4c17..e59ef07d9 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -923,9 +923,7 @@ void noise_est_fx( NOISE_EST_HANDLE hNoiseEst; SP_MUS_CLAS_HANDLE hSpMusClas; hSpMusClas = st_fx->hSpMusClas; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( ncharX ); -#endif /* Check if LR-VAD */ { diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index bcf7d33bb..b19fb7e56 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -80,9 +80,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc Word16 pit_flag, delta, mult_Top, nBits; Word16 L_sufr_sft; Word16 T_op[2]; /* values for two half-frames */ -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) tdm_Pitch_reuse_flag; -#endif L_sufr_sft = 6; move16(); diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 6844945c0..efecb33ed 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -1104,11 +1104,7 @@ void pre_proc_fx( test(); test(); test(); -#ifndef CR_2109_to_2112_cd0_ce0 - IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA || NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) -#else IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) -#endif { /* update signal buffers */ Copy( new_inp_resamp16k, st->buf_speech_enc + L_FRAME16k, L_FRAME16k ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 042b5af90..f80373787 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -178,9 +178,7 @@ void dtx_fx( void dtx_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ const Word16 vad, /* i : vad flag for DTX Q0*/ const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ @@ -1235,9 +1233,7 @@ void AVQ_cod_lpc_fx( void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ -#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -1553,9 +1549,7 @@ void Mode2_pit_encode_fx( Word16 pit_res_max ); void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); -#ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); -#endif void E_ACELP_4t_fx( Word16 dn[], /* Qdn */ @@ -3074,9 +3068,7 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | ); void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ -#endif const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/spec_flatness_fx.c b/lib_enc/spec_flatness_fx.c index c2451886d..d7bd9a6e9 100644 --- a/lib_enc/spec_flatness_fx.c +++ b/lib_enc/spec_flatness_fx.c @@ -221,11 +221,7 @@ void spec_flatness_fx( SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q ); SFM_Qtmp = sub( SFM_Qtmp, SFM_Q ); -#ifdef FIX_ISSUE_1209 sSFM[1] = add_sat( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); -#else - sSFM[1] = add( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); -#endif move16(); /*sSFM3*/ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index e04f5172b..ff9e2d936 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -890,20 +890,12 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */ L_tmp = L_shl( tmp, sub( 1, exp3 ) ); /*Q16 */ -#ifdef FIX_ISSUE_1151 ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ -#else - ps_sta = L_add( ps_sta, L_tmp ); /*Q16 */ -#endif } } /**pFV++ = (float)log(ps_sta + 1e-5f);*/ -#ifdef FIX_ISSUE_1151 ps_sta = L_add_sat( ps_sta, 336 ); -#else - ps_sta = L_add( ps_sta, 336 ); -#endif e_tmp = norm_l( ps_sta ); f_tmp = Log2_norm_lc( L_shl( ps_sta, e_tmp ) ); e_tmp = sub( 30 - 16, e_tmp ); @@ -1617,16 +1609,8 @@ Word16 ivas_smc_gmm_fx( Word16 flag_odv; Word32 lps_fx, lpm_fx, lpn_fx; Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; -#ifndef DOT_PROD_CHOLESKY_64BIT - Word32 lprob_fx; - Word16 lprob_exp = 0; -#else Word64 wprob_fx; -#endif Word32 fvm_fx[N_PCA_COEF]; -#ifndef DOT_PROD_CHOLESKY_64BIT - Word16 fvm_exp = 0; -#endif Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; @@ -2213,38 +2197,16 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); -#ifndef DOT_PROD_CHOLESKY_64BIT - fvm_exp = sub( 31, Qfact_FV ); - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#else wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#endif move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); -#ifndef DOT_PROD_CHOLESKY_64BIT - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#else wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#endif move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); -#ifndef DOT_PROD_CHOLESKY_64BIT - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#else wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#endif move32(); } @@ -2258,21 +2220,12 @@ Word16 ivas_smc_gmm_fx( *high_lpn_flag = 1; move32(); } -#ifndef FIX_1297_OVERFLOW - hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 11 ) ); // Q7 - move16(); - hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 11 ) ); // Q7 - move16(); - hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q7 - move16(); -#else hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lpn_fx = extract_h( L_shl_sat( lpn_fx, 16 - 11 ) ); // Q7 move16(); -#endif /* determine HQ Generic speech class */ IF( st->hHQ_core != NULL ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 7ca996af5..64ab13ea2 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -701,9 +701,6 @@ typedef struct sp_mus_clas_structure typedef struct lpd_state_structure { -#ifndef MSAN_FIX - Word16 nbits; /* number of bits used by ACELP or TCX */ -#endif /* signal memory */ Word16 syn[1 + M]; /* Synthesis memory (non-pe) */ @@ -1012,9 +1009,7 @@ typedef struct td_bwe_enc_structure typedef struct fd_bwe_enc_structure { Word16 new_input_hp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS )]; // Q_new_input_hp -#ifdef FIX_ISSUE_1230 Word16 Q_new_input_hp; -#endif Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS )]; // q0 Word16 old_input_wb_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; /* Q(-1) */ Word16 old_input_lp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS )]; // st->hBWE_FD->prev_Q_input_lp diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index e0d846458..26c8382ca 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -307,9 +307,7 @@ void swb_bwe_enc_ivas_fx( move32(); #endif Word16 fb_band_begin; -#ifdef FIX_ISSUE_1230 Word16 q_new_input_hp; -#endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; @@ -385,7 +383,6 @@ void swb_bwe_enc_ivas_fx( Copy( old_input_16k_fx + L_INP_MEM + L_FRAME16k - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); } -#ifdef FIX_ISSUE_1230 q_new_input_hp = s_min( Q_shb_speech, hBWE_FD->Q_new_input_hp ); IF( LT_16( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ) { @@ -400,10 +397,6 @@ void swb_bwe_enc_ivas_fx( hBWE_FD->Q_new_input_hp = Q_shb_speech; move16(); -#else - Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); - Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); -#endif Copy( shb_speech_fx + L_FRAME16k - Sample_Delay_HP, hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); new_input_fx = old_input_fx + Sample_Delay_SWB_BWE; Copy( hBWE_FD->old_input_fx, old_input_fx, Sample_Delay_SWB_BWE ); @@ -513,11 +506,7 @@ void swb_bwe_enc_ivas_fx( { Q_shb = sub( Q_synth_hf, 4 ); } -#ifdef FIX_ISSUE_1230 Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, q_new_input_hp ) ); -#else - Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, Q_shb_speech ) ); -#endif /* FB BWE encoding */ IF( EQ_16( st_fx->extl, FB_BWE ) ) @@ -3229,11 +3218,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( expn = sub( sub( 30, expn ), sub( shl( Q_insig_lp, 1 ), 7 ) ); expd = norm_l( WB_tenv_syn_fx ); -#ifdef FIX_ISSUE_1156 den = round_fx_o( L_shl( WB_tenv_syn_fx, expd ), &Overflow ); -#else - den = round_fx( L_shl( WB_tenv_syn_fx, expd ) ); -#endif expd = sub( sub( 30, expd ), sub( shl( Q_insig_lp, 1 ), 7 ) ); scale = shr( sub( den, num ), 15 ); @@ -4145,17 +4130,11 @@ void fd_bwe_enc_init_fx( ) { set16_fx( hBWE_FD->new_input_hp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ) ); -#ifdef FIX_ISSUE_1230 hBWE_FD->Q_new_input_hp = 0; move16(); -#endif set16_fx( hBWE_FD->old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) ); set16_fx( hBWE_FD->old_input_wb_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ) ); -#ifndef MSAN_FIX - set16_fx( hBWE_FD->old_input_lp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_SWB_TBE_16k_NS ) ); -#else set16_fx( hBWE_FD->old_input_lp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ) ); -#endif set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); hBWE_FD->prev_mode = NORMAL; move16(); diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index b73b0f992..c49c32e03 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1263,11 +1263,7 @@ void swb_pre_proc_ivas_fx( thr = icbwe_thr_TDM_fx; regV = icbwe_regressionValuesTDM_fx; -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, 0, st->cldfbSynTd ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, st->cldfbSynTd ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Copy_Scale_sig_32_16( shb_speech_fx_32, shb_speech, L_FRAME16k, negate( sub( q_reImBuffer, 1 ) ) ); *Q_shb_spch = 0; move16(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 9b4f15dc5..2b8f487bd 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -1391,11 +1391,7 @@ void wb_tbe_enc_ivas_fx( move32(); } -#ifdef FIX_ISSUE_1165 lpc2lsp_ivas_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB ); -#else - lpc2lsp_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB ); -#endif FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index 19afa8243..25a3bdee7 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -536,11 +536,7 @@ static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_fra BASOP_SATURATE_WARNING_ON_EVS /* Quantize gain */ -#ifdef FIX_ISSUE_1150 g = shr( sub_o( g, 0x1000, &Overflow ), 13 ); -#else - g = shr( sub( g, 0x1000 ), 13 ); -#endif g = s_max( g, -1 ); *gain_index = g; diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index ce7f0e6a6..c84843384 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3785,9 +3785,7 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) *---------------------------------------------------------------------*/ void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ -#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -3834,11 +3832,7 @@ void ProcessIGF_ivas_fx( IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, *q_spectrum ) ); -#ifndef MSAN_FIX - IGFEncApplyMono_ivas_fx( st, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); -#else IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); -#endif curr_order = 0; move16(); diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index cf6e5dd64..05b35813a 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -229,11 +229,7 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) ); FOR( i = 0; i < n; i++ ) { -#ifdef FIX_ISSUE_1147 tmpbuf[i] = round_fx_sat( L_shl( pSpectrum[iStartLine + i], shift ) ); -#else - tmpbuf[i] = round_fx( L_shl( pSpectrum[iStartLine + i], shift ) ); -#endif move16(); } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 44bd8cc3c..92f01b5dd 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -678,18 +678,13 @@ void RunTransientDetection_ivas_fx( IF( GT_16( sub( q_input, pSubblockEnergies->q_firState ), shift ) ) { Scale_sig( input_fx, length, add( sub( pSubblockEnergies->q_firState, q_input ), shift ) ); // q_firState + shift -#ifdef FIX_ISSUE_1186 q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift -#endif pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift move16(); pSubblockEnergies->firState2 = shl( pSubblockEnergies->firState2, shift ); // q_firState + shift move16(); pSubblockEnergies->q_firState = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift move16(); -#ifndef FIX_ISSUE_1186 - q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift -#endif } ELSE { @@ -715,11 +710,7 @@ void RunTransientDetection_ivas_fx( } /* Update subblock energies. */ -#ifdef MSAN_FIX Scale_sig( filteredInput_fx, length, sub( 0, q_input ) ); // q0 -#else - Scale_sig( filteredInput_fx, L_FRAME_MAX, 8 ); -#endif UpdateSubblockEnergies_ivas_fx( filteredInput_fx, length, pSubblockEnergies ); /* Run transient detectors. */ diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 9911d766a..7fe813d12 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -213,11 +213,7 @@ void transition_enc_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, -#else - L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, -#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -329,11 +325,7 @@ void transition_enc_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, -#else - st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, -#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* @@ -1042,11 +1034,7 @@ void transition_enc_ivas_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, -#else - L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, -#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -1158,11 +1146,7 @@ void transition_enc_ivas_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, -#else - st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, -#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index be86281ef..fb3a89350 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -72,10 +72,8 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; #define INV_TAN30_FX 28377 // Q14 #define EPSILON_MANT 1180591621 /* 1e-12 = 0.5497558*(2^-39) in Q70 */ #define EPSILON_EXP ( -39 ) -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC #define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ #define ONE_DIV_EPSILON_EXP ( 40 ) -#endif #define ADAPT_HTPROTO_ROT_LIM_1 0.8f #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */ @@ -135,10 +133,8 @@ static void matrixTransp2Mul_fx( Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx Word32 Ascale, Word32 Bscale, -#endif Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); @@ -813,12 +809,9 @@ static void ivas_dirac_dec_binaural_internal_fx( IF( hDiracDecBin->useTdDecorr ) { -#ifdef FIX_ISSUE_1185 Word32 tmp_arr[60]; -#endif FOR( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ ) { -#ifdef FIX_ISSUE_1185 q_cldfb[ch][slot] = sub( q_input, 1 ); move16(); @@ -836,15 +829,6 @@ static void ivas_dirac_dec_binaural_internal_fx( scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( q_input, st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) ); st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = q_input; move16(); -#else - q_cldfb[ch][slot] = q_input; - move16(); - cldfbAnalysis_ts_fx_fixed_q( - &( st_ivas->hTcBuffer->tc_fx[ch][nBins * slot + offsetSamples] ), - Cldfb_RealBuffer_in_fx[ch][slot], - Cldfb_ImagBuffer_in_fx[ch][slot], - nBins, st_ivas->cldfbAnaDec[ch], &q_cldfb[ch][slot] ); -#endif /*FIX_ISSUE_1185*/ test(); test(); @@ -886,10 +870,8 @@ static void ivas_dirac_dec_binaural_internal_fx( { scale_sig32( Cldfb_RealBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 scale_sig32( Cldfb_ImagBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 -#ifdef FIX_ISSUE_1185 q_cldfb[cha][slot] = 6; move16(); -#endif } } @@ -1983,10 +1965,8 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); matrixTransp2Mul_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx 1 /*int Ascale*/, 0 /*int Bscale*/, -#endif resultMtxRe_fx, resultMtxIm_fx, &q_res ); /* When below the frequency limit where decorrelation is applied, we inject the decorrelated @@ -2151,23 +2131,12 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); -#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT { tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp2 ); tmp2 = ISqrt32( tmp2, &exp2 ); gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) ); q_gain = sub( 31, add( exp2, exp1 ) ); } -#else - { - Word16 exp_temp; - tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - tmp2 = BASOP_Util_Divide3232_Scale_cadence( tmp1, tmp2, &exp ); - exp2 = add( exp, sub( exp1, exp_temp ) ); - } - gain_fx = Sqrt32( tmp2, &exp2 ); - q_gain = sub( 31, exp2 ); -#endif // 1073741824 = 4 in Q28 @@ -2610,11 +2579,7 @@ static void ivas_dirac_dec_binaural_process_output_fx( outSlotRePr_fx = &( outSlotRe_fx[0] ); outSlotImPr_fx = &( outSlotIm_fx[0] ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, 0, cldfbSynDec[chA] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 ); move16(); } @@ -3260,7 +3225,6 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) -#ifdef FIX_1326_SUBSTITUTE_CMPMANT32EXP IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { Ure_fx[0][0] = ONE_IN_Q31; @@ -3272,19 +3236,6 @@ static void eig2x2_fx( return; } -#else - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( D_fx[0], *q_D, EPSILON_MANT, EPSILON_EXP ), -1 ) ) - { - Ure_fx[0][0] = ONE_IN_Q31; - move32(); - Ure_fx[1][1] = ONE_IN_Q31; - move32(); - *q_U = Q31; - move16(); - - return; - } -#endif /* Numeric case, when input is near an identity matrix with a gain */ tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 @@ -3493,7 +3444,6 @@ static void eig2x2_fx( move16(); } } -#ifdef FIX_1326_SPEEDUP_eig2x2_fx if ( q_U_1 != 0 ) { *q_U = q_U_1; @@ -3505,17 +3455,6 @@ static void eig2x2_fx( *q_U = q_U_2; move16(); } -#else - IF( q_U_1 != 0 ) - { - *q_U = q_U_1; - } - ELSE - { - *q_U = q_U_2; - } - move16(); -#endif return; } @@ -3570,11 +3509,6 @@ static void matrixMul_fx( Word16 chA, chB; Word16 min_q_shift1, min_q_shift2; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); -#ifndef FIX_1113_OPT_DIRAC_BIN_REND -#ifndef IVAS_ENH64_CADENCE_CHANGES - Word32 tmp1, tmp2; -#endif -#endif min_q_shift1 = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); min_q_shift2 = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); @@ -3603,7 +3537,6 @@ static void matrixMul_fx( outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], Bim_fx[0][chB] ), Are_fx[chA][1], Bim_fx[1][chB] ) ) ); move32(); #else -#ifdef FIX_1113_OPT_DIRAC_BIN_REND outRe_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[0][chB] ), Are_fx[chA][1], Bre_fx[1][chB] ), Aim_fx[chA][0], Bim_fx[0][chB] ), @@ -3614,106 +3547,6 @@ static void matrixMul_fx( Are_fx[chA][0], Bim_fx[0][chB] ), Are_fx[chA][1], Bim_fx[1][chB] ); move32(); -#else - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && Bre_fx[0][chB] >= 0 ) || ( Are_fx[chA][0] < 0 && Bre_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Are_fx[chA][0], Bre_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( Bre_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && Bre_fx[1][chB] >= 0 ) || ( Are_fx[chA][1] < 0 && Bre_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Are_fx[chA][1], Bre_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( Bre_fx[1][chB] ) ) ); - } - outRe_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && Bim_fx[0][chB] >= 0 ) || ( Aim_fx[chA][0] < 0 && Bim_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Aim_fx[chA][0], Bim_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( Bim_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && Bim_fx[1][chB] >= 0 ) || ( Aim_fx[chA][1] < 0 && Bim_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Aim_fx[chA][1], Bim_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( Bim_fx[1][chB] ) ) ); - } - outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && Bre_fx[0][chB] >= 0 ) || ( Aim_fx[chA][0] < 0 && Bre_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Aim_fx[chA][0], Bre_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( Bre_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && Bre_fx[1][chB] >= 0 ) || ( Aim_fx[chA][1] < 0 && Bre_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Aim_fx[chA][1], Bre_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( Bre_fx[1][chB] ) ) ); - } - outIm_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && Bim_fx[0][chB] >= 0 ) || ( Are_fx[chA][0] < 0 && Bim_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Are_fx[chA][0], Bim_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( Bim_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && Bim_fx[1][chB] >= 0 ) || ( Are_fx[chA][1] < 0 && Bim_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Are_fx[chA][1], Bim_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( Bim_fx[1][chB] ) ) ); - } - outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); -#endif #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */ } } @@ -3742,15 +3575,11 @@ static void matrixTransp1Mul_fx( { Word16 chA, chB; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); -#ifndef FIX_1113_OPT_DIRAC_BIN_REND - Word32 tmp1, tmp2; -#endif FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { -#ifdef FIX_1113_OPT_DIRAC_BIN_REND outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), Are_fx[1][chA], Bre_fx[1][chB] ), Aim_fx[0][chA], Bim_fx[0][chB] ), @@ -3761,74 +3590,6 @@ static void matrixTransp1Mul_fx( Aim_fx[0][chA], Bre_fx[0][chB] ), Aim_fx[1][chA], Bre_fx[1][chB] ); move32(); -#else - test(); - test(); - test(); - IF( ( ( ( Are_fx[0][chA] >= 0 ) && ( Bre_fx[0][chB] >= 0 ) ) || ( ( Are_fx[0][chA] < 0 ) && ( Bre_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( Are_fx[0][chA], Bre_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[0][chA] ), L_abs( Bre_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Are_fx[1][chA] >= 0 ) && ( Bre_fx[1][chB] >= 0 ) ) || ( ( Are_fx[1][chA] < 0 ) && ( Bre_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Are_fx[1][chA], Bre_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[1][chA] ), L_abs( Bre_fx[1][chB] ) ) ); - outRe_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - test(); - test(); - test(); - IF( ( ( ( L_negate( Aim_fx[0][chA] ) >= 0 ) && ( Bim_fx[0][chB] >= 0 ) ) || ( ( L_negate( Aim_fx[0][chA] ) < 0 ) && ( Bim_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( -Aim_fx[0][chA], Bim_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( -Aim_fx[0][chA] ), L_abs( Bim_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Aim_fx[1][chA] >= 0 ) && ( Bim_fx[1][chB] >= 0 ) ) || ( ( Aim_fx[1][chA] < 0 ) && ( Bim_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Aim_fx[1][chA], Bim_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[1][chA] ), L_abs( Bim_fx[1][chB] ) ) ); - outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], L_sub( tmp1, tmp2 ) ); - move32(); - - test(); - test(); - test(); - IF( ( ( ( L_negate( Aim_fx[0][chA] ) >= 0 ) && ( Bre_fx[0][chB] >= 0 ) ) || ( ( L_negate( Aim_fx[0][chA] ) < 0 ) && ( Bre_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( -Aim_fx[0][chA], Bre_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( -Aim_fx[0][chA] ), L_abs( Bre_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Aim_fx[1][chA] >= 0 ) && ( Bre_fx[1][chB] >= 0 ) ) || ( ( Aim_fx[1][chA] < 0 ) && ( Bre_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Aim_fx[1][chA], Bre_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[1][chA] ), L_abs( Bre_fx[1][chB] ) ) ); - outIm_fx[chA][chB] = L_sub( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( ( ( Are_fx[0][chA] >= 0 ) && ( Bim_fx[0][chB] >= 0 ) ) || ( ( Are_fx[0][chA] < 0 ) && ( Bim_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( Are_fx[0][chA], Bim_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[0][chA] ), L_abs( Bim_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Are_fx[1][chA] >= 0 ) && ( Bim_fx[1][chB] >= 0 ) ) || ( ( Are_fx[1][chA] < 0 ) && ( Bim_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Are_fx[1][chA], Bim_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[1][chA] ), L_abs( Bim_fx[1][chB] ) ) ); - outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); -#endif } } *q_out = sub( add( q_A, q_B ), 31 ); @@ -3850,10 +3611,8 @@ static void matrixTransp2Mul_fx( Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx Word32 Ascale, Word32 Bscale, -#endif Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) @@ -3861,15 +3620,8 @@ static void matrixTransp2Mul_fx( Word16 chA, chB; Word16 min_q_shift; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); -#ifndef FIX_1113_OPT_DIRAC_BIN_REND -#ifndef IVAS_ENH64_CADENCE_CHANGES - Word32 tmp1, tmp2; -#endif -#endif -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx IF( Ascale == 1 ) -#endif { min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); scale_sig32( Are_fx[0], size, min_q_shift ); @@ -3878,9 +3630,7 @@ static void matrixTransp2Mul_fx( move16(); } -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx IF( Bscale == 1 ) -#endif { min_q_shift = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); scale_sig32( Bre_fx[0], size, min_q_shift ); @@ -3903,7 +3653,6 @@ static void matrixTransp2Mul_fx( outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], L_negate( Bim_fx[chB][0] ) ), Are_fx[chA][1], L_negate( Bim_fx[chB][1] ) ) ) ); move32(); #else -#ifdef FIX_1113_OPT_DIRAC_BIN_REND outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[chB][0] ), Are_fx[chA][1], Bre_fx[chB][1] ), Aim_fx[chA][0], Bim_fx[chB][0] ), @@ -3914,75 +3663,6 @@ static void matrixTransp2Mul_fx( Are_fx[chA][0], Bim_fx[chB][0] ), Are_fx[chA][1], Bim_fx[chB][1] ); move32(); -#else - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && Bre_fx[chB][0] >= 0 ) || ( Are_fx[chA][0] < 0 && Bre_fx[chB][0] < 0 ) ) - tmp1 = Mpy_32_32( Are_fx[chA][0], Bre_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( Bre_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && Bre_fx[chB][1] >= 0 ) || ( Are_fx[chA][1] < 0 && Bre_fx[chB][1] < 0 ) ) - tmp2 = Mpy_32_32( Are_fx[chA][1], Bre_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( Bre_fx[chB][1] ) ) ); - outRe_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && L_negate( Bim_fx[chB][0] ) >= 0 ) || ( Aim_fx[chA][0] < 0 && L_negate( Bim_fx[chB][0] ) < 0 ) ) - tmp1 = Mpy_32_32( Aim_fx[chA][0], -Bim_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( -Bim_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && L_negate( Bim_fx[chB][1] ) >= 0 ) || ( Aim_fx[chA][1] < 0 && L_negate( Bim_fx[chB][1] ) < 0 ) ) - tmp2 = Mpy_32_32( Aim_fx[chA][1], -Bim_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( -Bim_fx[chB][1] ) ) ); - outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); - - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && Bre_fx[chB][0] >= 0 ) || ( Aim_fx[chA][0] < 0 && Bre_fx[chB][0] < 0 ) ) - tmp1 = Mpy_32_32( Aim_fx[chA][0], Bre_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( Bre_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && Bre_fx[chB][1] >= 0 ) || ( Aim_fx[chA][1] < 0 && Bre_fx[chB][1] < 0 ) ) - tmp2 = Mpy_32_32( Aim_fx[chA][1], Bre_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( Bre_fx[chB][1] ) ) ); - outIm_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && L_negate( Bim_fx[chB][0] ) >= 0 ) || ( Are_fx[chA][0] < 0 && L_negate( Bim_fx[chB][0] ) < 0 ) ) - tmp1 = Mpy_32_32( Are_fx[chA][0], -Bim_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( -Bim_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && L_negate( Bim_fx[chB][1] ) >= 0 ) || ( Are_fx[chA][1] < 0 && L_negate( Bim_fx[chB][1] ) < 0 ) ) - tmp2 = Mpy_32_32( Are_fx[chA][1], -Bim_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( -Bim_fx[chB][1] ) ) ); - outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); -#endif #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */ } } @@ -4057,15 +3737,6 @@ static void chol2x2_fx( } ELSE { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - outRe[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[0][0], &exp ); - move32(); - q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); - - outIm[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_im, outRe[0][0], &exp ); - move32(); - q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); -#else Word32 denom; Word16 den_exp; Word32 my_outRe, my_outIm; @@ -4091,7 +3762,6 @@ static void chol2x2_fx( outIm[1][0] = Mpy_32_32( denom, my_outIm ); move32(); q_im = sub( q_im, den_exp ); -#endif } if ( outRe[1][0] == 0 ) { @@ -4110,16 +3780,11 @@ static void chol2x2_fx( // 4611686 = Q62 IF( e1 == 0 ) { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( temp, 4611686, &exp ); - q_tmp = add( sub( 31, exp ), sub( q_tmp, 62 ) ); -#else Word16 norm = norm_l( temp ); temp = L_shl( temp, norm ); q_tmp = add( q_tmp, norm ); temp = Mpy_32_32( temp, ONE_DIV_EPSILON_MANT ); q_tmp = sub( q_tmp, ONE_DIV_EPSILON_EXP ); -#endif } ELSE { @@ -4168,16 +3833,6 @@ static void chol2x2_fx( // 4611686 = Q62 IF( outRe[1][1] == 0 ) { -#if !defined( FIX_1072_REDUCE_DIVS ) - outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); - move32(); - q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) ); - - outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, 4611686, &exp ); - move32(); - q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); - -#else // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); Word32 tmp1 = 1953125005; /* 1/4611686 Q62 */ exp = 9; @@ -4190,19 +3845,9 @@ static void chol2x2_fx( outIm[0][1] = Mpy_32_32( tmp1, -c_im ); move32(); q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); -#endif } ELSE { -#if !defined( FIX_1072_REDUCE_DIVS ) - outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); - move32(); - q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); - - outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, outRe[1][1], &exp ); - move32(); - q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); -#else { // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); Word32 tmp1 = BASOP_Util_Divide3232_Scale_cadence( 0x7FFFFFFF, outRe[1][1], &exp ); @@ -4215,7 +3860,6 @@ static void chol2x2_fx( move32(); q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); } -#endif } if ( outRe[0][1] == 0 ) { @@ -4380,15 +4024,10 @@ static void formulate2x2MixingMatrix_fx( // 4611686 = Q62 IF( maxEne_fx == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC maxEneDiv_fx = ONE_DIV_EPSILON_MANT; move32(); q_maxEneDiv = 31 - ONE_DIV_EPSILON_EXP; move16(); -#else - maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12f in Q62 - q_maxEneDiv = add( sub( 31, exp ), sub( Q30, 62 ) ); -#endif } ELSE { @@ -4448,7 +4087,6 @@ static void formulate2x2MixingMatrix_fx( IF( temp == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC IF( E_out1 == 0 ) { Ghat_fx[0] = 0; @@ -4462,10 +4100,6 @@ static void formulate2x2MixingMatrix_fx( exp = sub( exp, sub( q_eout, 62 ) ); Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp } -#else - temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, 4611686, &exp ); // 4611686 = Q62 - exp = sub( exp, sub( q_eout, 62 ) ); -#endif } ELSE { @@ -4473,20 +4107,14 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp -#endif } -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp -#endif move32(); temp = Mpy_32_32( E_in1, 2147484 ); // 2147484 = 0.001f in Q31 temp = L_max( temp, E_in2 ); // q_ein IF( temp == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC IF( E_out2 == 0 ) { /* We can set hard-coded results */ Ghat_fx[1] = 0; @@ -4499,10 +4127,6 @@ static void formulate2x2MixingMatrix_fx( exp1 = sub( exp1, sub( q_eout, 62 ) ); Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 } -#else - temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 - exp1 = sub( exp1, sub( q_eout, 62 ) ); -#endif } ELSE { @@ -4510,13 +4134,8 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 -#endif } -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 -#endif move32(); q_Ghat = sub( 31, s_max( exp, exp1 ) ); @@ -4565,15 +4184,10 @@ static void formulate2x2MixingMatrix_fx( IF( D_fx[0] == 0 ) { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 - exp = sub( exp, sub( Q30, 62 ) ); -#else temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ move32(); exp = ONE_DIV_EPSILON_EXP; move16(); -#endif } ELSE { @@ -4583,7 +4197,6 @@ static void formulate2x2MixingMatrix_fx( div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT // Sqrt(1) div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 exp1 = add( 0, 20 ); @@ -4594,25 +4207,6 @@ static void formulate2x2MixingMatrix_fx( div_fx[1] = ISqrt32( D_fx[1], &exp1 ); move32(); } -#else - IF( D_fx[1] == 0 ) - { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp1 ); // 4611686 = 1e-12 in Q62 - exp1 = sub( exp1, sub( Q30, 62 ) ); -#else - temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - exp1 = ONE_DIV_EPSILON_EXP; -#endif - } - ELSE - { - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); - exp1 = sub( exp1, sub( Q30, q_D ) ); - } - div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 - move32(); -#endif q_div = sub( 31, s_max( exp, exp1 ) ); div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); // q_div @@ -4704,10 +4298,8 @@ static void formulate2x2MixingMatrix_fx( } matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx 1 /*int Ascale*/, 0 /*int Bscale*/, -#endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ @@ -4718,7 +4310,6 @@ static void formulate2x2MixingMatrix_fx( { IF( Sx_fx[chB] == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Pre_fx[chA][chB] = Mpy_32_32( Pre_fx[chA][chB], ONE_DIV_EPSILON_MANT ); // q_Pre[chA][chB] = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP); q_Pre[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); @@ -4727,26 +4318,12 @@ static void formulate2x2MixingMatrix_fx( Pim_fx[chA][chB] = Mpy_32_32( Pim_fx[chA][chB], ONE_DIV_EPSILON_MANT ); // q_Pim[chA][chB] = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP); q_Pim[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); -#else - Pre_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pre_fx[chA][chB], 4611686, &exp ); // 4611686 = 1e-12 in Q62 - q_Pre[chA][chB] = add( sub( q_P, 62 ), sub( 31, exp ) ); - Pim_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pim_fx[chA][chB], 4611686, &exp ); // 4611686 = 1e-12 in Q62 - q_Pim[chA][chB] = add( sub( q_P, 62 ), sub( 31, exp ) ); -#endif } ELSE { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Word16 Pre_shift, Pim_shift; -#endif temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Pre_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pre_fx[chA][chB], temp, &exp ); - q_Pre[chA][chB] = add( sub( q_P, sub( 31, exp_temp ) ), sub( 31, exp ) ); - Pim_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pim_fx[chA][chB], temp, &exp ); - q_Pim[chA][chB] = add( sub( q_P, sub( 31, exp_temp ) ), sub( 31, exp ) ); -#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); Pre_shift = norm_l( Pre_fx[chA][chB] ); Pim_shift = norm_l( Pim_fx[chA][chB] ); @@ -4755,7 +4332,6 @@ static void formulate2x2MixingMatrix_fx( q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); q_Pre[chA][chB] = add( q_temp, Pre_shift ); q_Pim[chA][chB] = add( q_temp, Pim_shift ); -#endif } if ( Pre_fx[chA][chB] == 0 ) { @@ -4858,10 +4434,8 @@ static void formulate2x2MixingMatrix_fx( matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp ); matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx 1 /*int Ascale*/, 0 /*int Bscale*/, -#endif Mre_fx, Mim_fx, q_M ); return; } diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 1ffe0da74..1afac99c4 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -55,12 +55,10 @@ #define DIRAC_DUCK_ALPHA_FX 1717986944 /* Q31 */ #define ONE_M_DIRAC_DUCK_ALPHA 429496736 /* Q31 */ -#ifdef FIX_1110_OPTIM_DIRAC_DECORR_PROC /* Maximal useful q-format, represents range of 2^-126 (float min) */ #define MAX_Q_FX 157 -#endif /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ @@ -590,18 +588,6 @@ void ivas_dirac_dec_decorr_process_fx( Word16 decorr_buff_tot_len = imult1616( imult1616( shl( decorr_buffer_len, 1 ), max_band_decorr ), num_channels ); guarded_bits = 0; -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - FOR( Word16 i = 0; i < decorr_buff_tot_len; i++ ) - { - IF( h_freq_domain_decorr_ap_state->decorr_buffer_fx[i] != 0 ) - { - guarded_bits = s_max( find_guarded_bits_fx( 2 ), 3 ); - } - } - q_shift = sub( getScaleFactor32( h_freq_domain_decorr_ap_state->decorr_buffer_fx, decorr_buff_tot_len ), guarded_bits ); - Scale_sig32( h_freq_domain_decorr_ap_state->decorr_buffer_fx, decorr_buff_tot_len, q_shift ); - q_decorr_buf = add( q_decorr_buf, q_shift ); -#else Flag is_zero = is_zero_arr( h_freq_domain_decorr_ap_state->decorr_buffer_fx, decorr_buff_tot_len ); if ( is_zero == 0 ) { @@ -617,7 +603,6 @@ void ivas_dirac_dec_decorr_process_fx( q_decorr_buf = add( q_decorr_buf, q_shift ); } } -#endif q_shift = getScaleFactor32( aux_buffer_fx, imult1616( imult1616( 2, num_protos_dir ), max_band_decorr_temp ) ); Word16 buf_len = shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ); @@ -681,15 +666,8 @@ void ivas_dirac_dec_decorr_process_fx( /* MA part of filter impulse response */ FOR( l = 0; l < filter_length; l++ ) { -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - frame_ma_fx[2 * l] = Mpy_32_16_1( input_real_fx, filter_coeff_num_real_fx[l] ); // Q_qux -3 = q_deorr - // frame_ma_fx[2 * l] = L_shr(frame_ma_fx[2 * l],3); // scaling to q_decorr_buf - frame_ma_fx[add( shl( l, 1 ), 1 )] = Mpy_32_16_1( input_imag_fx, filter_coeff_num_real_fx[l] ); // Q_qux - 3 = q_deorr - // frame_ma_fx[2 * l + 1] = L_shr(frame_ma_fx[2 * l + 1], 3); // scaling to q_decorr_buf -#else frame_ma_fx[2 * l] = Mpy_32_16_1( input_real_fx, filter_coeff_num_real_fx[l] ); // Q_qux -3 = q_deorr frame_ma_fx[2 * l + 1] = Mpy_32_16_1( input_imag_fx, filter_coeff_num_real_fx[l] ); // Q_qux - 3 = q_deorr -#endif move32(); move32(); } @@ -705,32 +683,14 @@ void ivas_dirac_dec_decorr_process_fx( filter_frame_real_fx = decorr_buffer_ptr_fx[0]; // q_decorr filter_frame_imag_fx = decorr_buffer_ptr_fx[1]; // q_decorr -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - decorr_buffer_ptr_fx += shl( decorr_buffer_step, 1 ); -#else Word16 decorr_buffer_step2x = shl( decorr_buffer_step, 1 ); decorr_buffer_ptr_fx += decorr_buffer_step2x; move16(); -#endif FOR( l = 1; l < filter_length; l++ ) { // q adjustment needed// -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - decorr_buffer_ptr_fx[0] = L_add( decorr_buffer_ptr_fx[0], frame_ma_fx[2 * l] ); // q_decorr - Word32 temp_1 = Mpy_32_16_1( filter_frame_real_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 - temp_1 = L_shl( temp_1, 3 ); // q_decorr - decorr_buffer_ptr_fx[0] = L_sub( decorr_buffer_ptr_fx[0], temp_1 ); // q_deocor - decorr_buffer_ptr_fx[1] = L_add( decorr_buffer_ptr_fx[1], frame_ma_fx[add( shl( l, 1 ), 1 )] ); // q_decorr - Word32 temp_2 = Mpy_32_16_1( filter_frame_imag_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 - temp_2 = L_shl( temp_2, 3 ); // q_decorr - decorr_buffer_ptr_fx[1] = L_sub( decorr_buffer_ptr_fx[1], temp_2 ); // q_decorr - decorr_buffer_ptr_fx += imult1616( 2, decorr_buffer_step ); - move32(); - move32(); - move32(); -#else Word32 temp_1 = Mpy_32_16_1( filter_frame_real_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 temp_1 = L_shl( temp_1, 3 ); // q_decorr decorr_buffer_ptr_fx[0] = L_sub( L_add( decorr_buffer_ptr_fx[0], frame_ma_fx[2 * l] ), temp_1 ); // q_deocor @@ -743,7 +703,6 @@ void ivas_dirac_dec_decorr_process_fx( decorr_buffer_ptr_fx += decorr_buffer_step2x; move16(); -#endif } } } @@ -764,7 +723,6 @@ void ivas_dirac_dec_decorr_process_fx( e_direct_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); // scaling to get max precision for aux_buffer values// -#ifdef MSAN_FIX q_shift = Q31; move16(); offset = shl( max_band_decorr, 1 ); @@ -777,10 +735,6 @@ void ivas_dirac_dec_decorr_process_fx( { scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], offset, q_shift ); } -#else - q_shift = L_norm_arr( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels ); - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); -#endif q_frame_f = add( q_frame_f, q_shift ); @@ -802,24 +756,8 @@ void ivas_dirac_dec_decorr_process_fx( q_direct_energy = q_aux_buffer; move16(); -#ifdef FIX_1110_OPTIM_DIRAC_DECORR_PROC /* Attention: this loop reports norm=0, whenever any data is 0. */ /* Therefore, useful left-shifts are skipped, accuracy is lost. */ -#endif -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - /* calculate the power of the decorrelated signal */ - FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) - { - offset1 = shl( imult1616( ch_idx, num_freq_bands ), 1 ); - offset2 = shl( imult1616( ch_idx, max_band_decorr ), 1 ); - FOR( Word16 i = 0; i < 2 * max_band_decorr; i++ ) - { - aux_64[add( offset2, i )] = W_mult0_32_32( frame_dec_fx[add( offset1, i )], frame_dec_fx[add( offset1, i )] ); - move64(); - norm = s_min( norm, W_norm( aux_64[add( offset2, i )] ) ); - } - } -#else /* calculate the power of the decorrelated signal */ Word64 *m64_aux = aux_64; move32(); @@ -849,7 +787,6 @@ void ivas_dirac_dec_decorr_process_fx( move32(); } norm = W_norm( min64 ); -#endif norm = sub( norm, 1 /*find_guarded_bits_fx( 2 )*/ ); FOR( Word16 i = 0; i < 2 * num_channels * max_band_decorr; i++ ) { @@ -866,34 +803,6 @@ void ivas_dirac_dec_decorr_process_fx( /* smooth energies */ -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - v_multc_fixed( aux_buffer_fx, ONE_M_DIRAC_DUCK_ALPHA, aux_buffer_fx, imult1616( num_channels, max_band_decorr ) ); // q_aux_buffer - - v_multc_fixed( h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, DIRAC_DUCK_ALPHA_FX, h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, imult1616( num_channels, max_band_decorr ) ); // same-q - - v_add_fixed_me( aux_buffer_fx, sub( 31, q_aux_buffer ), h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, e_reverb_energy_smooth, h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, &e_reverb_energy_smooth, imult1616( num_channels, max_band_decorr ), 0 ); - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = sub( 31, e_reverb_energy_smooth ); - - v_multc_fixed( direct_energy_fx, ONE_M_DIRAC_DUCK_ALPHA, direct_energy_fx, imult1616( num_protos_dir, max_band_decorr ) ); // same q - - v_multc_fixed( h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, DIRAC_DUCK_ALPHA_FX, h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, imult1616( num_protos_dir, max_band_decorr ) ); // same q - - v_add_fixed_me( direct_energy_fx, sub( 31, q_direct_energy ), h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, e_direct_energy_smooth, h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, &e_direct_energy_smooth, imult1616( num_protos_dir, max_band_decorr ), 0 ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = sub( 31, e_direct_energy_smooth ); - move16(); - - // scaling energy buffers for better precision for higher values// - q_shift = L_norm_arr( h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, imult1616( num_protos_dir, max_band_decorr ) ); - Scale_sig32( h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, imult1616( num_protos_dir, max_band_decorr ), q_shift ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = add( h_freq_domain_decorr_ap_state->q_direct_energy_smooth, q_shift ); - move16(); - - - q_shift = L_norm_arr( h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, imult1616( num_channels, max_band_decorr ) ); - Scale_sig32( h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, imult1616( num_channels, max_band_decorr ), q_shift ); - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = add( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth, q_shift ); - move16(); -#else Word16 len = imult1616( num_channels, max_band_decorr ); Word16 aux_e = sub( 31, q_aux_buffer ); Word16 max_e = s_max( aux_e, e_reverb_energy_smooth ); @@ -950,13 +859,11 @@ void ivas_dirac_dec_decorr_process_fx( } h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); h_freq_domain_decorr_ap_state->q_direct_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); -#endif e_reverb_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); e_direct_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); // this step is b/c we are left shifting frame_dec_fx at the end of below for loop/ -#ifdef MSAN_FIX q_shift = Q31; move16(); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -969,10 +876,6 @@ void ivas_dirac_dec_decorr_process_fx( { Scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); } -#else - q_shift = sub( L_norm_arr( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels ), 2 ); - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); -#endif q_frame_f = add( q_frame_f, q_shift ); FOR( ch_idx = 0; ch_idx < num_channels; ch_idx++ ) @@ -1006,13 +909,8 @@ void ivas_dirac_dec_decorr_process_fx( duck_gain = shl( duck_gain, sub( e_duck_gain, 1 ) ); // Q14 -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_f - frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )], duck_gain ), 1 ); // q_frame_f -#else frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_f frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 1 ); // q_frame_f -#endif move32(); move32(); } @@ -1029,13 +927,8 @@ void ivas_dirac_dec_decorr_process_fx( } */ duck_gain = shl_sat( duck_gain, sub( e_duck_gain, 1 ) ); // Q14 -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 2 ); // q_frame_dec - frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )], duck_gain ), 2 ); // q_frame_dec -#else frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_dec frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 1 ); // q_frame_dec -#endif move32(); move32(); } @@ -1061,27 +954,19 @@ void ivas_dirac_dec_decorr_process_fx( q_shift = sf; move16(); // scaling it to sf -#ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } -#else - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q -#endif q_frame_f = add( q_frame_f, sf ); } ELSE IF( q_shift < 0 ) { // scaling it to input q -#ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } -#else - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q -#endif q_frame_f = q_input_frame; q_if_local = 0; move16(); diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 1b4ee91b2..87cdb6699 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -1079,7 +1079,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { -#ifdef FIX_1072_SPEEDUP_gainpanning /*is there any difference in any bitstream?*/ Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); FOR( Word16 kk = 0; kk < tmp16; kk++ ) { @@ -1088,17 +1087,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); -#else - FOR( Word16 kk = 0; kk < tmp16; kk++ ) - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ - move32(); - } - h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; - move16(); -#endif } -#ifdef FIX_1072_SPEEDUP_gainpanning Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { @@ -1108,11 +1097,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word32 aux; IF( temp_q1 < 0 ) { -#ifdef FIX_USAN_ISSUES Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 ); -#else - Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); -#endif FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); @@ -1142,25 +1127,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } -#else - FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) - { - v_mult_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx, - &h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands], - aux_buf, - num_freq_bands ); /*temp_q*/ - - IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) - { - Scale_sig32( aux_buf, num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ) ); /*temp_q->(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ - } - - v_add_fixed( aux_buf, - &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], - &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], - num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ - } -#endif /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 4e0d3ab71..59c93ae55 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -778,9 +778,7 @@ ivas_error ivas_dirac_alloc_mem_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->frame_dec_f_fx, 2 * num_outputs_diff * num_freq_bands ); -#endif hDirAC_mem->frame_dec_f_len = imult1616( imult1616( 2, num_outputs_diff ), num_freq_bands ); } } @@ -813,12 +811,7 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_len = size_ho; move16(); -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->cy_cross_dir_smooth_fx, size_ho ); -#else - set_zero_fx( hDirAC_mem->cy_cross_dir_smooth_fx, size ); - hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_len = size_ho; -#endif IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { @@ -870,9 +863,7 @@ ivas_error ivas_dirac_alloc_mem_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands ); -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->proto_direct_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len ); -#endif move16(); hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31; move16(); @@ -896,9 +887,7 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirAC_mem->proto_diffuse_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_outputs_diff ), num_freq_bands ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->proto_diffuse_buffer_f_fx, hDirAC_mem->proto_diffuse_buffer_f_len ); -#endif } } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx = hDirAC_mem->proto_direct_buffer_f_fx; @@ -961,9 +950,7 @@ ivas_error ivas_dirac_alloc_mem_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->onset_filter_fx, imult1616( num_outputs_diff, num_freq_bands ) ); -#endif } } } @@ -985,9 +972,7 @@ ivas_error ivas_dirac_alloc_mem_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->onset_filter_fx, imult1616( 2, num_freq_bands ) ); -#endif } } @@ -1725,11 +1710,7 @@ void protoSignalComputation2_fx( q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], num_freq_bands ), L_norm_arr( ImagBuffer_fx[l][0], num_freq_bands ) ); min_q_shift = s_min( min_q_shift, q_shift ); -#ifdef MSAN_FIX q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ); -#else - q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ), L_norm_arr( ImagBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ) ); -#endif // MSAN_FIX temp_q_shift = s_min( temp_q_shift, q_shift ); } @@ -2775,13 +2756,8 @@ void ivas_dirac_dec_compute_diffuse_proto_fx( Word16 new_diff_e = s_max( diff_e, old_diff_e ); Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx, diffuse_start, sub( old_diff_e, new_diff_e ) ); // 31-new_diff_e -#ifdef MSAN_FIX Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx + diffuse_start, i_mult( shl( num_freq_bands_diff, 1 ), hDirACRend->hOutSetup.nchan_out_woLFE ), sub( diff_e, new_diff_e ) ); // 31-new_diff_e -#else - Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx + diffuse_start, - sub( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_len, diffuse_start ), sub( diff_e, new_diff_e ) ); -#endif h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q = sub( 31, new_diff_e ); move16(); @@ -2972,10 +2948,8 @@ void ivas_masa_init_stereotype_detection_fx( move16(); stereo_type_detect->target_power_y_smooth_fx = 0; move32(); -#ifdef MSAN_FIX stereo_type_detect->q_target_power_y_smooth = 31; move16(); -#endif stereo_type_detect->lr_total_bb_ratio_db_fx = 0; move32(); @@ -4215,11 +4189,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; // q_cldfb } Word16 out_size = imult1616( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, 0, hMasaExtRend->cldfbSynRend[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, hMasaExtRend->cldfbSynRend[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, sub( 11, q_out ) ); // q11 idx_in++; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index f3b4d1755..d5df77045 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -754,10 +754,8 @@ void ivas_mcmasa_param_est_ana_fx( computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , NULL -#endif ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index 01e35efe1..30bf8f00a 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -393,9 +393,7 @@ static void GenerateITD_fx( Word16 num_az_idx, num_ev_idx; Word16 BM_idx[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; Word16 itdMod_e; -#ifdef MSAN_FIX set16_fx( AzIdx, 0, HRTF_MODEL_BSPLINE_NUM_COEFFS ); -#endif // MSAN_FIX /* Wrap the requested azimuth to the range of the BSplines */ azim_fx = L_add( azim_fx, model->azimKSeq_fx[0] ); diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 5787ded3f..7e35b80b2 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -573,10 +573,8 @@ static void TDREND_SRC_SPATIAL_Init_fx( TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, ONE_IN_Q30 ); /*Assuming Q30*/ } -#ifdef MSAN_FIX SrcSpatial_p->q_Pos_p = Q31; move16(); -#endif /* Source directional attenuation */ SrcSpatial_p->DirAttenEnabled = FALSE; // Q0 diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c index 8beb5a0ec..3b01f62ca 100644 --- a/lib_rend/ivas_output_init_fx.c +++ b/lib_rend/ivas_output_init_fx.c @@ -1,9 +1,7 @@ #include "ivas_prot_fx.h" #include "ivas_prot_rend_fx.h" -#ifdef FIX_DISCLAIMER #include -#endif Word16 ivas_get_nchan_buffers_dec_ivas_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -161,7 +159,6 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx( return nchan_out_buff; } -#ifdef FIX_DISCLAIMER /*---------------------------------------------------------------------* * get_channel_config() * @@ -272,4 +269,3 @@ ivas_error get_channel_config( return IVAS_ERR_OK; } -#endif diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 04afce118..695e05fdf 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -81,12 +81,10 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx( const Word32 ivas_total_brate /* i : total IVAS bitrate */ ); -#ifdef FIX_DISCLAIMER ivas_error get_channel_config( const AUDIO_CONFIG config, /* i : audio configuration */ Word8 *str /* o : string with the configuration name */ ); -#endif /*----------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 870f8795d..9b149940c 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1529,9 +1529,7 @@ ivas_error ivas_reverb_open_fx( params.pDsr_fx = params.pRt60_fx + nr_fc_fft_filter; params.pFc_fx = &pState->fft_filter_color_0.fft_spectrum_fx[0]; params.pHrtf_inter_aural_coherence_fx = &pState->fft_filter_color_1.fft_spectrum_fx[0]; -#ifdef MSAN_FIX set32_fx( pState->fft_filter_color_1.fft_spectrum_fx, 0, RV_FILTER_MAX_FFT_SIZE ); -#endif /* Note: these temp buffers can only be used before the final step of the FFT filter design : */ /* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */ @@ -1647,18 +1645,11 @@ ivas_error ivas_reverb_open_fx( IF( pState->do_corr_filter ) { /* Computing correlation filters on the basis of target IA coherence */ -#ifdef MSAN_FIX FOR( i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ move32(); } -#else - FOR( i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) - { - pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ - } -#endif // MSAN_FIX Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) ); FOR( i = 0; i < nr_fc_fft_filter; i++ ) diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index aebb80a54..e6f8f2653 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -2271,12 +2271,10 @@ void SHrotmatgen_fx( Word16 R_lm1[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM]; -#ifdef MSAN_FIX FOR( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { set16_fx( R_lm1[i], 0, HEADROT_SHMAT_DIM ); } -#endif Word16 R_l[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM]; Word32 result; SHrotmat[0][0] = ONE_IN_Q14; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 386644ab1..a8f32514d 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -666,11 +666,7 @@ typedef struct ivas_binaural_rendering_conv_module_struct_fx Word32 ***filterStatesLeftReal_fx; Word32 ***filterStatesLeftImag_fx; -#ifdef OPT_BASOP_ADD_v1 Word16 Q_filterStatesLeft; -#else /* OPT_BASOP_ADD_v1 */ - Word16 ***Q_filterStatesLeft; -#endif /* OPT_BASOP_ADD_v1 */ Word16 numTapsArray[BINAURAL_CONVBANDS]; Word16 numTaps; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 3ea159d7f..84e771106 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8481,7 +8481,6 @@ static void intermidiate_ext_dirac_render( } } -#ifdef FIX_DISCLAIMER static ivas_error printConfigInfo_rend( IVAS_REND_HANDLE hIvasRend /* i : IVAS renderer handle */ ) @@ -8574,4 +8573,3 @@ void IVAS_REND_PrintDisclaimer( void ) return; } -#endif diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 0a489600a..e837daa4f 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -324,7 +324,6 @@ void IVAS_REND_Close( ); -#ifdef FIX_DISCLAIMER /* Disclaimer and info printing */ void IVAS_REND_PrintInputConfig( @@ -338,7 +337,6 @@ ivas_error IVAS_REND_PrintConfig( void IVAS_REND_PrintDisclaimer( void ); -#endif /* clang-format on */ diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index e667dcfe5..c2e3d8a2a 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1201,11 +1201,7 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); -#ifdef MSAN_FIX floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRImag_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); -#else - floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); -#endif } } } -- GitLab From 88209e93b149fd65a8921985e32feab918a34692 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 16:13:40 +0530 Subject: [PATCH 0544/1221] Clang formatting --- lib_com/bits_alloc_fx.c | 96 ++++++------ lib_com/cldfb.c | 8 +- lib_com/gs_inact_switching_fx.c | 22 +-- lib_com/ivas_dirac_com_fx.c | 3 +- lib_com/ivas_prot_fx.h | 3 +- lib_com/ivas_qmetadata_com_fx.c | 2 - lib_com/prot_fx.h | 130 ++++++++-------- lib_com/swb_bwe_com_fx.c | 4 +- lib_com/tools_fx.c | 50 +++--- lib_dec/FEC_HQ_phase_ecu_fx.c | 8 +- lib_dec/acelp_core_dec_ivas_fx.c | 38 ++--- lib_dec/fd_cng_dec_fx.c | 4 +- lib_dec/ivas_binRenderer_internal_fx.c | 3 - lib_dec/ivas_core_dec_fx.c | 10 +- lib_dec/ivas_mdct_core_dec_fx.c | 10 +- lib_dec/ivas_spar_decoder_fx.c | 2 +- lib_dec/ivas_stat_dec.h | 2 +- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 +- lib_dec/ivas_svd_dec_fx.c | 145 +++++++++--------- lib_enc/acelp_core_enc_fx.c | 2 +- lib_enc/cod_tcx_fx.c | 1 - lib_enc/core_enc_init_fx.c | 4 +- lib_enc/dtx_fx.c | 10 +- lib_enc/enc_acelpx_fx.c | 2 +- lib_enc/hq_core_enc_fx.c | 4 +- lib_enc/igf_enc.c | 4 +- lib_enc/ivas_core_pre_proc_front_fx.c | 14 +- lib_enc/ivas_dirac_enc_fx.c | 21 +-- lib_enc/ivas_mcmasa_enc_fx.c | 6 +- lib_enc/ivas_mdct_core_enc_fx.c | 12 +- lib_enc/ivas_omasa_enc_fx.c | 6 +- lib_enc/ivas_stat_enc.h | 2 +- lib_enc/ivas_stereo_dmx_evs_fx.c | 20 +-- lib_enc/ivas_stereo_ica_enc_fx.c | 8 +- lib_enc/ivas_stereo_icbwe_enc_fx.c | 2 +- lib_enc/ivas_stereo_td_analysis_fx.c | 14 +- lib_enc/ivas_td_low_rate_enc_fx.c | 4 +- lib_enc/prot_fx_enc.h | 18 +-- lib_enc/speech_music_classif_fx.c | 12 +- lib_enc/tcx_utils_enc_fx.c | 4 +- lib_enc/transient_detection_fx.c | 4 +- .../ivas_dirac_dec_binaural_functions_fx.c | 6 +- lib_rend/ivas_mcmasa_ana_fx.c | 6 +- 43 files changed, 355 insertions(+), 381 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index cb71f0f28..8162a98d3 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -762,31 +762,31 @@ static ivas_error acelp_FCB_allocator_ivas( *--------------------------------------------------------------------*/ ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ) { Word16 i, bits, nb_subfr; @@ -1887,31 +1887,31 @@ ivas_error config_acelp1( *--------------------------------------------------------------------*/ ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ) { Word16 i, bits, nb_subfr; diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 408580169..845ec1f11 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1097,10 +1097,10 @@ void cldfbAnalysis_ts_fx_fixed_q( * Conduct inverse multple overlap cmplex low delay MDCT *--------------------------------------------------------------------*/ void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ const Word16 shift, /* i : scale for state buffer */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ) diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 421b2a705..54fef9e37 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -158,18 +158,18 @@ void Inac_swtch_ematch_fx( void Inac_switch_ematch_ivas_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 L_frame, /* i : Frame lenght */ - const Word16 Q_exc, /* i : input and output format of exc2 */ - const Word16 bfi, /* i : frame lost indicator */ - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode, /* i : Last codec mode */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const Word16 element_mode /* i : element mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ + const Word16 element_mode /* i : element mode */ ) { Word16 Ener_per_bd[MBANDS_GN16k]; diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 7d481d181..b16b94f1d 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -610,8 +610,7 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_z, /* o: Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ , - Word16 *i_e_band -) + Word16 *i_e_band ) { Word16 i; Word32 intensityNorm; diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index fab166b6d..246f4d297 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3237,8 +3237,7 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_z, /*Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ , - Word16 *i_e_band -); + Word16 *i_e_band ); UWord8 ivas_masa_surrcoh_signicant_fx( diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index ee11f2b02..a5fbf9e83 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -446,8 +446,6 @@ ivas_error only_reduce_bits_direction_fx( } } } - - } *reduce_bits_out = negate( reduce_bits ); diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 71c1590c2..d7ed9a140 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4851,31 +4851,31 @@ Word16 BITS_ALLOC_config_acelp( const Word16 nb_subfr ); ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ); Word16 set_ACELP_flag( @@ -5846,18 +5846,18 @@ void Inac_swtch_ematch_fx( ); void Inac_switch_ematch_ivas_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 L_frame, /* i : Frame lenght */ - const Word16 Q_exc, /* i : input and output format of exc2 */ - const Word16 bfi, /* i : frame lost indicator */ - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode, /* i : Last codec mode */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const Word16 element_mode /* i : element mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ + const Word16 element_mode /* i : element mode */ ); // igf_base_fx.c @@ -9740,10 +9740,10 @@ void cldfbAnalysis_ivas_fx( ); void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ const Word16 shift, /* i : scale for state buffer */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); @@ -10973,31 +10973,31 @@ void lsf_syn_mem_backup_ivas_fx( Word16 *pstreaklen ); ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ); ivas_error push_next_indice( @@ -11051,8 +11051,8 @@ void calculate_hangover_attenuation_gain_ivas_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word32 igf_brate, /* i : IGF configuration bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ + const Word32 igf_brate, /* i : IGF configuration bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); void core_coder_reconfig_ivas_fx( diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index 228d43247..11da78c46 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -2534,7 +2534,7 @@ void hq_generic_decoding_fx( { exp = norm_l( L_tmp ); frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ - tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ + tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ @@ -3082,7 +3082,7 @@ void hq_generic_decoding_ivas_fx( { exp = norm_l( L_tmp ); frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ - tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ + tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index d403c583d..5219d076c 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -487,13 +487,13 @@ void Copy( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i] = x[i]; - move16(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move16(); + } - return; + return; } /*-------------------------------------------------------------------* * Copy64: @@ -519,13 +519,13 @@ void Copy64( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i] = x[i]; - move64(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move64(); + } - return; + return; } void set64_fx( @@ -566,15 +566,15 @@ void Copy_pword( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i].v.im = x[i].v.im; - y[i].v.re = x[i].v.re; - move16(); - move16(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i].v.im = x[i].v.im; + y[i].v.re = x[i].v.re; + move16(); + move16(); + } - return; + return; } /*-------------------------------------------------------------------* * Copy32: @@ -599,11 +599,11 @@ void Copy32( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i] = x[i]; - move32(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move32(); + } } void set8_fx( diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 74f1bfc09..b8c16474e 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -1590,7 +1590,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */ { - Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( *pPlocs ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1601,7 +1601,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && EQ_16( *pPlocs, 1 ) ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ { - Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( sub( *pPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1647,7 +1647,7 @@ static void ivas_spec_ana_fx( IF( EQ_16( currPlocs, ( sub( Lprot2_1, DELTA_CORR_F0_INT ) ) ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ { - Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( sub( currPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1661,7 +1661,7 @@ static void ivas_spec_ana_fx( * whould point */ IF( n > 0 ) /* fs/2 which makes special case . */ { - Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( sub( currPlocs, 2 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 5807f2c67..ea82f09de 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -77,21 +77,21 @@ ivas_error acelp_core_dec_ivas_fx( { Word32 synth_fx[960], save_hb_synth_fx[960] /*, bwe_exc_extended_fx[L_FRAME32k + NL_BUFF_OFFSET]*/; - Word16 old_exc_fx[L_EXC_DEC], *exc_fx; /* excitation signal buffer */ - Word16 syn_tmp_fx[L_FRAME16k + L_SUBFR], *psyn_fx; /* synthesis signal buffer */ - Word16 output_frame; /* frame length at output sampling freq. */ - Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ - Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ - Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ - Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ - Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ - Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ - Word32 enr_q_fx; /* E information for FER protection */ - Word16 tmp_noise_fx; /* Long term temporary noise energy */ - Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ - Word16 FEC_pitch_fx; /* FEC pitch */ + Word16 old_exc_fx[L_EXC_DEC], *exc_fx; /* excitation signal buffer */ + Word16 syn_tmp_fx[L_FRAME16k + L_SUBFR], *psyn_fx; /* synthesis signal buffer */ + Word16 output_frame; /* frame length at output sampling freq. */ + Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ + Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ + Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ + Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ + Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ + Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ + Word32 enr_q_fx; /* E information for FER protection */ + Word16 tmp_noise_fx; /* Long term temporary noise energy */ + Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ + Word16 FEC_pitch_fx; /* FEC pitch */ Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ - Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ + Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ Word16 i, j, int_fs; Word16 tc_subfr; Word16 allow_cn_step; @@ -1810,7 +1810,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) + scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); @@ -1892,13 +1892,13 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, st->cldfbSyn ); - scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 + scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); @@ -1988,12 +1988,12 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), 0, st->cldfbSyn ); - Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 + Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index df18d3dba..c1289b8a3 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -5270,7 +5270,7 @@ void generate_stereo_masking_noise_fx( { hFdCngCom = st->hFdCngDec->hFdCngCom; Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ - Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ + Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); @@ -5278,7 +5278,7 @@ void generate_stereo_masking_noise_fx( IF( !fadeOut ) { Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ - generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 + generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 /* Generate masking noise for secondary channel */ IF( flag_sec_CNA ) { diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index f78f14e8e..c05b8beb2 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -339,7 +339,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - } } /* set memories */ @@ -1264,7 +1263,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; - } free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); @@ -1272,7 +1270,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; - } free( hBinRenConvModule->filterStatesLeftReal_fx ); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 4e654030b..588640d0a 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -524,7 +524,7 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 - Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 + Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 IF( st->cldfbAna ) { scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, Q10 - Q11 ); /* 9 * (Word16)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f) , Q10 */ @@ -630,8 +630,8 @@ ivas_error ivas_core_dec_fx( ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 - Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 - Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 + Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 + Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 } /*---------------------------------------------------------------------* @@ -1147,8 +1147,8 @@ ivas_error ivas_core_dec_fx( q = 2; move16(); - Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 - Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); // Q0 + Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 + Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); // Q0 Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ); // Q8 Copy_Scale_sig_32_16( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, ( 2 * ALLPASSSECTIONS_STEEP ), sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bew_syn2 diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 71839557a..7d5f7d737 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1172,13 +1172,13 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_syn_Overl_TDAC ) ); // st->hTcxDec->Q_syn_Overl_TDAC -> q_win Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_old_syn_Overl ) ); // Q(-1 - st->Q_syn) -> q_win st->hTcxDec->Q_old_syn_Overl = q_win; - Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win + Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win - Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win + Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win FOR( k = 0; k < nSubframes[ch]; k++ ) { init_tcx_info_fx( st, L_frame_global[ch], L_frame_globalTCX[ch], k, bfi, &tcx_offset[ch], diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index c3e2ad096..a7b66ff87 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -1352,7 +1352,7 @@ static void ivas_spar_calc_smooth_facs_fx( smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 move32(); } - smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 + smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 move32(); smooth_long_avg_fx[b] = Mpy_32_32( smooth_long_avg_fx[b], 107374182 /*(1/20 in Q31)*/ ); // Q0 move32(); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 429a99ca4..891be05be 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -961,7 +961,7 @@ typedef struct decoder_tc_buffer_structure Word32 *tc_buffer_fx; /* the buffer itself */ Word16 tc_buff_len; /*stores memory length of tc buffer*/ Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ // VE2SB: TBV - Word16 no_channels; /*Stores no of channels in tc_fx with values*/ + Word16 no_channels; /*Stores no of channels in tc_fx with values*/ Word16 q_tc_fx; TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 1c2ecffaf..c9f7cac92 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -718,8 +718,8 @@ void stereo_icBWE_dec_fx( IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) { temp1_fx = 0; @@ -813,7 +813,7 @@ void stereo_icBWE_dec_fx( hStereoICBWE->prev_Q_fsout = tmp; move16(); } - Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); /* Qsyn - 1 */ + Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); /* Qsyn - 1 */ *Q_syn = sub( *Q_syn, 1 ); @@ -877,8 +877,8 @@ void stereo_icBWE_dec_fx( IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) { temp1_fx = 0; diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index dd9859504..8a9224ffa 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -294,7 +294,6 @@ Word16 svd_fx( push_wmops( "svd_fx" ); - /* Collecting Values */ FOR( iCh = 0; iCh < nChannelsL; iCh++ ) { @@ -385,11 +384,11 @@ static Word16 BidagonalDiagonalisation_fx( Word32 singularVectors_Right_fx[][MAX_OUTPUT_CHANNELS], /* i/o: right singular vectors (V) singularValues_fx_e*/ Word32 secDiag_fx[MAX_OUTPUT_CHANNELS], /* i/o: secDiag_fx_e*/ Word16 singularValues_fx_e[MAX_OUTPUT_CHANNELS], /* i/o: singular values vector (S) */ - Word16 *secDiag_new_e, /* i/o: */ - const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ - const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ - const Word32 eps_x, /* i : eps_x_e*/ - const Word16 eps_x_e /* i : */ + Word16 *secDiag_new_e, /* i/o: */ + const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ + const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ + const Word32 eps_x, /* i : eps_x_e*/ + const Word16 eps_x_e /* i : */ ) { Word16 kCh, nCh, iCh, jCh, split; @@ -898,52 +897,52 @@ static void biDiagonalReductionLeft_fx( secDiag_e[currChannel] = *sig_x_e; move16(); -/* Setting values to 0 */ -( *sig_x ) = 0; -move32(); -( *g ) = 0; -move32(); - -IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ -{ - idx = currChannel; - move16(); - - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ - { - ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ - } + /* Setting values to 0 */ + ( *sig_x ) = 0; + move32(); + ( *g ) = 0; + move32(); - IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ + IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ { - Word16 invVal_e; - Word32 invVal; - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); - norm_x = 0; - move32(); - norm_x_e = 0; + idx = currChannel; move16(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { + ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ + } + + IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ + { + Word16 invVal_e; + Word32 invVal; + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); + norm_x = 0; + move32(); + norm_x_e = 0; + move16(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { Word16 temp_e = norm_l( singularVectors[jCh][currChannel] ); singularVectors[jCh][currChannel] = Mpy_32_32( L_shl( singularVectors[jCh][currChannel], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); singularVectors2_e[jCh][currChannel] = sub( add( invVal_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ), temp_e ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ - } - IF( GT_16( norm_x_e, 0 ) ) - { - norm_x = MAX_32; - move32(); - norm_x_e = 0; + } + IF( GT_16( norm_x_e, 0 ) ) + { + norm_x = MAX_32; + move32(); + norm_x_e = 0; + move16(); + } + L_temp_e = norm_x_e; move16(); - } - L_temp_e = norm_x_e; - move16(); - L_temp = Sqrt32( norm_x, &L_temp_e ); - L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 - //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); + L_temp = Sqrt32( norm_x, &L_temp_e ); + L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 + //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); if ( singularVectors[currChannel][idx] >= 0 ) { L_temp = L_negate( L_temp ); @@ -951,52 +950,51 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ ( *g ) = L_temp; move32(); - r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ - singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ - move32(); + r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ + singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ + move32(); - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); - FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ - { - norm_x = 0; - move32(); - norm_x_e = 0; - move16(); - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { + norm_x = 0; + move32(); + norm_x_e = 0; + move16(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( singularVectors2_e[jCh][currChannel], singularVectors2_e[jCh][iCh] ), &norm_x_e ); /* exp(norm_x_e) */ - } + } - f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ + f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ f_e = add( invVal_e, sub( norm_x_e, r_e ) ); - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ - { + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], singularVectors2_e[jCh][iCh], Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, singularVectors2_e[jCh][currChannel] ), &singularVectors2_e[jCh][iCh] ); - move32(); + move32(); + } } - } - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ - { - singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ - move32(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { + singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ + move32(); singularVectors2_e[jCh][currChannel] = add( singularVectors2_e[jCh][currChannel], *sig_x_e ); - move16(); + move16(); + } } + // rescaling block + singularValues[currChannel] = Mpy_32_32( ( *sig_x ), ( *g ) ); /* sig_x_e */ + move32(); + singularValues_e[currChannel] = *sig_x_e; + move16(); } - // rescaling block - singularValues[currChannel] = Mpy_32_32( ( *sig_x ), ( *g ) ); /* sig_x_e */ - move32(); - singularValues_e[currChannel] = *sig_x_e; - move16(); -} - -return; + return; } /*------------------------------------------------------------------------- @@ -1108,7 +1106,7 @@ static void biDiagonalReductionRight_fx( FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { - singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ + singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ move32(); } } @@ -1120,9 +1118,6 @@ static void biDiagonalReductionRight_fx( singularVectors2_e[currChannel][jCh] = add( singularVectors2_e[currChannel][jCh], *sig_x_e ); move16(); } - - - } } @@ -1230,7 +1225,7 @@ static void singularVectorsAccumulationLeft_fx( { FOR( iCh = 0; iCh < nChannelsC; iCh++ ) { - singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ + singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ move32(); } } diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index a93690738..f9f941dbd 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1430,7 +1430,7 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) { - Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn + Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 1 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); // st->Q_syn st->hTcxEnc->q_Txnq = st->Q_syn; move16(); diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 54f57b287..bb35cf037 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -4525,7 +4525,6 @@ void coder_tcx_fx( n, st, hm_cfg ); - } diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 405b3ac2b..14dbd5962 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -943,8 +943,8 @@ static void init_modes_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word32 igf_brate, /* i : IGF configuration bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ + const Word32 igf_brate, /* i : IGF configuration bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ) { TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 44be8dcc6..9a66572ab 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -60,12 +60,12 @@ static void update_SID_cnt_fx( DTX_ENC_HANDLE hDtxEnc, const Word32 core_brate, /* _ None */ /*==================================================================================*/ void dtx_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ + Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ - const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ - const Word16 vad, /* i : vad flag for DTX Q0*/ - const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ - Word16 Q_speech /* i : Q factor for speech */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ + const Word16 vad, /* i : vad flag for DTX Q0*/ + const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ + Word16 Q_speech /* i : Q factor for speech */ ) { Word16 alpha, i, j, Q_speech2; diff --git a/lib_enc/enc_acelpx_fx.c b/lib_enc/enc_acelpx_fx.c index 9612696ed..240f9859c 100644 --- a/lib_enc/enc_acelpx_fx.c +++ b/lib_enc/enc_acelpx_fx.c @@ -781,7 +781,7 @@ void E_ACELP_4tsearchx_ivas_fx( alp = shr( alp, 1 ); Scale_sig( cor, L_SUBFR, -1 ); /*Q8*/ Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/ - Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ + Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ } diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index 6bc466e3d..ff19cfebc 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -481,8 +481,8 @@ void hq_core_enc_ivas_fx( TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); Q_audio = sub( Q31, Q_audio ); Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ - inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ - L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ + inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ + L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ is_transient = 0; move16(); move16(); diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index d5f071784..2680bd9f6 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2517,8 +2517,8 @@ void IGFEncResetTCX10BitCounter_ivas_fx( *-------------------------------------------------------------------*/ void IGFEncApplyMono_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ + Encoder_State *st, /* i : Encoder state */ + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index bf7c36eef..96c1b168f 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -125,14 +125,14 @@ ivas_error pre_proc_front_ivas_fx( const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ Word16 band_energies_LR_fx_q, - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ - const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ - const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ - const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ + const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ + const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ - const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ + const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO , diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index 59447c022..615a6f4b6 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -51,11 +51,9 @@ static void computeIntensityVector_enc_fx( Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const Word16 enc_param_start_band, /* i : first band to process */ const Word16 num_frequency_bands, - Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] - , + Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS], Word16 q_cldfb, - Word16 q_intensity_real[DIRAC_MAX_NBANDS] -); + Word16 q_intensity_real[DIRAC_MAX_NBANDS] ); /*------------------------------------------------------------------------- * ivas_dirac_enc_open() @@ -1123,11 +1121,9 @@ void ivas_dirac_param_est_enc_fx( Cldfb_ImagBuffer_fx, hDirAC->hConfig->enc_param_start_band, num_freq_bands, - intensity_real_fx - , + intensity_real_fx, cldfb_q, - intensity_real_q - ); + intensity_real_q ); IF( !hodirac_flag ) { computeDirectionVectors_fixed( @@ -1138,10 +1134,8 @@ void ivas_dirac_param_est_enc_fx( num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], - direction_vector_fx[2] - , - 31, intensity_real_q - ); + direction_vector_fx[2], + 31, intensity_real_q ); direction_vector_q = Q30; move16(); @@ -1465,8 +1459,7 @@ static void computeIntensityVector_enc_fx( Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] /* q_intensity_real */ , Word16 q_cldfb, - Word16 q_intensity_real[DIRAC_MAX_NBANDS] -) + Word16 q_intensity_real[DIRAC_MAX_NBANDS] ) { /* Reminder * X = a + ib; Y = c + id diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index 0071b67ea..7a5718e99 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -1178,10 +1178,8 @@ void ivas_mcmasa_param_est_enc_fx( num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], - direction_vector_fx[2], c_e - , - NULL - ); + direction_vector_fx[2], c_e, + NULL ); /* Power and intensity estimation for diffuseness */ computeIntensityVector_enc_fx( diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 4b5b3fcbe..f7da231a3 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -429,11 +429,11 @@ static void kernel_switch_update_transforms_fx( Word32 factor; n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 - Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 - scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 + Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 + scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, s, &exp_tmp ); @@ -896,8 +896,8 @@ static UWord16 enc_ste_pre_mdct( absMagnR_fx = Sqrt32( L_add( Mpy_32_32( sigR1_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI1_fx[s], sigI1_fx[s] ) ), &absMagnR_e ); corr_fx = L_add( corr_fx, L_add( Mpy_32_32( sigR0_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI0_fx[s], sigI1_fx[s] ) ) ); // q_com*2 - 31 - sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 - sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 + sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 + sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 sumMagnL_fx = BASOP_Util_Add_Mant32Exp( sumMagnL_fx, sumMagnL_e, absMagnL_fx, absMagnL_e, &sumMagnL_e ); sumMagnR_fx = BASOP_Util_Add_Mant32Exp( sumMagnR_fx, sumMagnR_e, absMagnR_fx, absMagnR_e, &sumMagnR_e ); sumPrdLR_fx = BASOP_Util_Add_Mant32Exp( sumPrdLR_fx, sumPrdLR_e, Mpy_32_32( absMagnL_fx, absMagnR_fx ), add( absMagnL_e, absMagnR_e ), &sumPrdLR_e ); diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 1433c988f..f1187bc6c 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -1199,10 +1199,8 @@ static void ivas_omasa_param_est_enc_fx( computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, guard_bits ); intensity_real_e = sub( add( 62, guard_bits ), shl( q, 1 ) ); - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e - , - NULL - ); + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e, + NULL ); /* Power estimation for diffuseness */ diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 4a6543026..f421fd034 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1179,7 +1179,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; - Word32 isd_rate_s_fx; // Q31 + Word32 isd_rate_s_fx; // Q31 Word32 iccr_s_fx; // Q31 Word32 ipd_ff_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word32 Pr_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 2ed17e25a..625ff8ee9 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -155,8 +155,8 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word16 itd[], /* o : estimated itd Q0 */ - const Word16 input_frame /* i : input frame length per channel */ + Word16 itd[], /* o : estimated itd Q0 */ + const Word16 input_frame /* i : input frame length per channel */ ); static void adapt_gain_fx( const Word32 src_fx[], /* i : input signal Q16 */ @@ -198,9 +198,9 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word16 itd_fx[], /* o : estimated itd */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio */ + Word16 itd_fx[], /* o : estimated itd */ + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio */ ); /*-------------------------------------------------------------------* * estimate_itd_wnd_fft() @@ -1136,9 +1136,9 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word16 itd_fx[], /* o : estimated itd Q0 */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio Q31 */ + Word16 itd_fx[], /* o : estimated itd Q0 */ + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) { Word16 itd_cand[CPE_CHANNELS], i, n, cnt[CPE_CHANNELS], Lh, peak_range, *on, *itdLR, prev_off[CPE_CHANNELS], eps_fx; @@ -1448,8 +1448,8 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word16 itd[], /* o : estimated itd Q0 */ - const Word16 input_frame /* i : input frame length per channel */ + Word16 itd[], /* o : estimated itd Q0 */ + const Word16 input_frame /* i : input frame length per channel */ ) { Word32 specLr[L_FRAME48k / 2 + 1], specLi[L_FRAME48k / 2 + 1], specRr[L_FRAME48k / 2 + 1], specRi[L_FRAME48k / 2 + 1]; diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 8410f7546..78ea50d7e 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1095,8 +1095,8 @@ static void corrStatsEst_fx( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */ move32(); Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ - inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ - IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 + inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ + IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 { set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 ); hStereoTCA->delay_0_mem_exp = temp; @@ -1964,8 +1964,8 @@ void stereo_tca_enc_fx( Word16 temp_exp, tempF_16fx; Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */ - scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ + scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ tempF_fx = tempF_16fx; move32(); diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 25e2366dd..02d20543b 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -822,7 +822,7 @@ void stereo_icBWE_enc_ivas_fx( set32_fx( shb_frame_nonref_fx, 0, L_LOOK_16k + L_FRAME16k ); max_e = s_max( hStereoICBWE->mem_shb_speech_nonref_e, shb_speech_nonref_e ); - Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e + Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e hStereoICBWE->mem_shb_speech_nonref_e = max_e; shb_frame_nonref_e = max_e; diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index f9b6b0bf3..6ffd05c0c 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -71,13 +71,13 @@ #define RATIO_MAX 1.5f /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ -#define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ -#define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ -#define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ -#define B_ADAP_FX_Q16 ( 10486 ) /* 0.16f in Q16 */ +#define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ +#define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ +#define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ +#define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ +#define B_ADAP_FX_Q16 ( 10486 ) /* 0.16f in Q16 */ #define PC_LIMIT 64 #define RATIO_PG_HR 0.94f diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 63cbb30e9..bdc39e797 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -338,8 +338,8 @@ void encod_gen_2sbfr( * Update memory of the weighting filter *-----------------------------------------------------------------*/ - Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ - Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ + Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index f80373787..3f7f17fe7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -177,12 +177,12 @@ void dtx_fx( ); void dtx_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ + Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ - const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ - const Word16 vad, /* i : vad flag for DTX Q0*/ - const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ - Word16 Q_speech /* i : Q factor for speech */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ + const Word16 vad, /* i : vad flag for DTX Q0*/ + const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ + Word16 Q_speech /* i : Q factor for speech */ ); Word16 dtx_hangover_addition_fx( @@ -1232,8 +1232,8 @@ void AVQ_cod_lpc_fx( ); void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ + Encoder_State *st, /* i : Encoder state */ + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -3067,8 +3067,8 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | Word16 last_core_acelp /**< in: Q0 | indictaor if last frame was acelp coded */ ); -void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ - Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ +void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index ff9e2d936..b9f47136f 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -890,7 +890,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */ L_tmp = L_shl( tmp, sub( 1, exp3 ) ); /*Q16 */ - ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ + ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ } } @@ -2201,12 +2201,12 @@ Word16 ivas_smc_gmm_fx( ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); } @@ -2220,7 +2220,7 @@ Word16 ivas_smc_gmm_fx( *high_lpn_flag = 1; move32(); } - hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 + hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 move16(); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index c84843384..e0a944981 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3784,8 +3784,8 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) * *---------------------------------------------------------------------*/ void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ + Encoder_State *st, /* i : Encoder state */ + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 92f01b5dd..60d661db4 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -678,8 +678,8 @@ void RunTransientDetection_ivas_fx( IF( GT_16( sub( q_input, pSubblockEnergies->q_firState ), shift ) ) { Scale_sig( input_fx, length, add( sub( pSubblockEnergies->q_firState, q_input ), shift ) ); // q_firState + shift - q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift - pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift + q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift + pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift move16(); pSubblockEnergies->firState2 = shl( pSubblockEnergies->firState2, shift ); // q_firState + shift move16(); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index fb3a89350..2376babcd 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -72,9 +72,9 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; #define INV_TAN30_FX 28377 // Q14 #define EPSILON_MANT 1180591621 /* 1e-12 = 0.5497558*(2^-39) in Q70 */ #define EPSILON_EXP ( -39 ) -#define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ -#define ONE_DIV_EPSILON_EXP ( 40 ) -#define ADAPT_HTPROTO_ROT_LIM_1 0.8f +#define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ +#define ONE_DIV_EPSILON_EXP ( 40 ) +#define ADAPT_HTPROTO_ROT_LIM_1 0.8f #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */ diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index d5df77045..cfdd43116 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -753,10 +753,8 @@ void ivas_mcmasa_param_est_ana_fx( /* Direction estimation */ computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) - , - NULL - ); /* Q direction_vector_fx = Q30*/ + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ), + NULL ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx ); /*2*inp_q-31*/ -- GitLab From 7699604cbeba5c4b0b36310220d689d2b157f8d4 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Mar 2025 14:32:20 +0100 Subject: [PATCH 0545/1221] workaround for grep with input=output --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 15f70e917..33a38214e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -425,7 +425,8 @@ stages: - if [ "$SPLIT_COMPARISON" = "true" ]; then # use -v flag ("inverse") to also have the header in the output file - grep -v "_whole" $CSV_ARTIFACT_NAME > $CSV_ARTIFACT_SPLIT - - grep -v "_split" $CSV_ARTIFACT_NAME > $CSV_ARTIFACT_NAME + - cp $CSV_ARTIFACT_NAME tmp.csv + - grep -v "_split" tmp.csv > $CSV_ARTIFACT_NAME - mkdir $IMAGES_ARTIFACT_SPLIT - for MEASURE in $summary_args;do - python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT/summary_"$MEASURE".csv $IMAGES_ARTIFACT_SPLIT/summary_"$MEASURE".png --measure $MEASURE -- GitLab From 9c244dff1eb59d3e8b6a8eebddf12a295ddf02d4 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Mar 2025 14:34:00 +0100 Subject: [PATCH 0546/1221] [revert-me] limit to stereo testcases for faster testing --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33a38214e..57378accb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -224,7 +224,7 @@ stages: - enc_dmx_arg="--compare_enc_dmx" - fi - - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest $TEST_SUITE -k stereo -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR @@ -416,7 +416,7 @@ stages: ### run pytest - exit_code=0 - - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest -k stereo --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true ### create histograms -- GitLab From f40595a1e0584e88670c723566ce112d9a40dc40 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 17:25:41 +0530 Subject: [PATCH 0547/1221] Fix for 3GPP issue 1414: ApplyFdCng_ivas_fx() called twice Link #1414 --- lib_dec/acelp_core_dec_ivas_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index ea82f09de..bd8c6ec93 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -660,7 +660,7 @@ ivas_error acelp_core_dec_ivas_fx( STEREO_DFT_FD_FILT_COMP_Q31, st->hFdCngDec->hFdCngCom->sidNoiseEst[i] ); move32(); } - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + Word16 new_sidNoiseEstExp = 31 - Q4; move16(); Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, new_sidNoiseEstExp ) ); // Q(31-sidNoiseEstExp) -- GitLab From cbaf8b9d93e19d7127a83fac9d21b7336ce35768 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 21 Mar 2025 16:00:36 +0100 Subject: [PATCH 0548/1221] Revert "[revert-me] limit to stereo testcases for faster testing" This reverts commit 9c244dff1eb59d3e8b6a8eebddf12a295ddf02d4. --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 57378accb..33a38214e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -224,7 +224,7 @@ stages: - enc_dmx_arg="--compare_enc_dmx" - fi - - python3 -m pytest $TEST_SUITE -k stereo -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? .update-scripts-repo: &update-scripts-repo - cd $SCRIPTS_DIR @@ -416,7 +416,7 @@ stages: ### run pytest - exit_code=0 - - python3 -m pytest -k stereo --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? + - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true ### create histograms -- GitLab From 0d5424b95a3ba5400bc9936d4f968f0c49d9b630 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 24 Mar 2025 09:18:10 +0530 Subject: [PATCH 0549/1221] Q-factor of synthesis memory buffers of LPDmem struct updates --- lib_com/lsf_tools_fx.c | 8 ++++---- lib_enc/cod_tcx_fx.c | 4 ++-- lib_enc/core_enc_init_fx.c | 6 ++++++ lib_enc/init_enc_fx.c | 14 ++++---------- lib_enc/ivas_tcx_core_enc_fx.c | 16 ++-------------- lib_enc/ivas_td_low_rate_enc_fx.c | 1 + lib_enc/tcx_utils_enc_fx.c | 9 ++++++++- 7 files changed, 27 insertions(+), 31 deletions(-) diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 54f0ae3ed..5f0b3b57b 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -3044,11 +3044,11 @@ void lsf_syn_mem_backup_ivas_fx( /* back-up memories */ FOR( i = 0; i < M; i++ ) { - mem_syn_bck[i] = hLPDmem->mem_syn[i]; // Q: ( 15 - st_fx->hLPDmem->e_mem_syn ) + mem_syn_bck[i] = hLPDmem->mem_syn[i]; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); } - *mem_w0_bck = hLPDmem->mem_w0; // ( 15 - st_fx->hLPDmem->e_mem_syn ) + *mem_w0_bck = hLPDmem->mem_w0; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); @@ -3263,12 +3263,12 @@ void lsf_syn_mem_restore_ivas_fx( } /* restoring memories */ - hLPDmem->mem_w0 = mem_w0_bck; // Q(15 - st_fx->hLPDmem->e_mem_syn ) + hLPDmem->mem_w0 = mem_w0_bck; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); FOR( i = 0; i < M; i++ ) { - hLPDmem->mem_syn[i] = mem_syn_bck[i]; // Q(15 - st_fx->hLPDmem->e_mem_syn ) + hLPDmem->mem_syn[i] = mem_syn_bck[i]; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); } diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index bb35cf037..4bb44eae2 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -3743,7 +3743,7 @@ void QuantizeTCXSpectrum_fx( } /* Quantize original spectrum */ - sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); + sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, ( mult( hTcxEnc->tcx_target_bits_fac, shl( sqTargetBits, 1 ) ) ), L_spec, &sqGain_e ); tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly ); @@ -4730,7 +4730,7 @@ void InternalTCXDecoder_fx( } ELSE { - mdct_shaping( spectrum_fx, L_frame, gainlpc_fx, gainlpc_e ); + mdct_noiseShaping_ivas_fx( spectrum_fx, spectrum_e, L_frame, gainlpc_fx, gainlpc_e ); } /*-----------------------------------------------------------* * Apply gain * diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 14dbd5962..05f838a3a 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -1561,6 +1561,10 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh { set16_fx( hLPDmem->syn, 0, 1 + M ); set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); + hLPDmem->q_lpd_syn = Q15; + hLPDmem->q_mem_syn = Q15; + move16(); + move16(); } IF( st->hTcxEnc != NULL ) @@ -1591,6 +1595,8 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); set16_fx( hLPDmem->syn, 0, M ); hLPDmem->q_lpd_syn = Q15; + hLPDmem->q_mem_syn = Q15; + move16(); move16(); } IF( st->hTcxEnc != NULL ) diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 1d695659c..ea944dd75 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -998,16 +998,18 @@ void LPDmem_enc_init_ivas_fx( set16_fx( hLPDmem->mem_syn2, 0, M ); set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); set16_fx( hLPDmem->mem_syn3, 0, M ); + hLPDmem->q_lpd_old_exc = Q15; + move16(); hLPDmem->q_lpd_syn = Q15; move16(); + hLPDmem->q_mem_syn = Q15; + move16(); hLPDmem->mem_w0 = 0; move16(); hLPDmem->tilt_code = 0; move16(); hLPDmem->gc_threshold = 0; move32(); - hLPDmem->q_mem_syn = Q15; - move16(); hLPDmem->dm_fx.prev_state = 0; move16(); /* This corresponds to st_fx->dispMem in FLP */ hLPDmem->dm_fx.prev_gain_code = 0; @@ -1019,14 +1021,6 @@ void LPDmem_enc_init_ivas_fx( move16(); } - hLPDmem->q_lpd_syn = Q15; - move16(); - hLPDmem->q_lpd_old_exc = Q15; - move16(); - hLPDmem->q_mem_syn = Q15; - move16(); - - return; } diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 159012ac2..8dbd4731c 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -562,9 +562,9 @@ void stereo_tcx_core_enc( } Scale_sig( st->synth, st->L_frame, s ); /* st->Q_syn + s */ Scale_sig( st->hLPDmem->syn, M + 1, s ); /* st->Q_syn + s */ + st->hLPDmem->q_lpd_syn = add( st->hLPDmem->q_lpd_syn, s ); Q_new = add( Q_new, s ); move16(); - move16(); coder_tcx_post_ivas_fx( st, st->hLPDmem, st->hTcxCfg, st->synth, A_q_fx, Aw_fx, st->wspeech_enc, Q_new ); @@ -688,19 +688,7 @@ void stereo_tcx_core_enc( { set16_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q6, NB_SUBFR16k ); /* Q6 */ } - /* Memory scaling to keep everything in common q */ - Word16 curr_q_syn = sub( shl( Q_new, 1 ), 1 ); - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - Scale_sig( st->hLPDmem->mem_syn, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - Scale_sig( st->hLPDmem->mem_syn2, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( s_min( Q_new, st->hLPDmem->q_mem_syn ), Q_new ) ); /* s_min( Q_new, st->hLPDmem->q_mem_syn ) */ - move16(); - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - Scale_sig( st->hLPDmem->mem_syn3, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - st->hLPDmem->q_mem_syn = s_min( curr_q_syn, st->hLPDmem->q_mem_syn ); - move16(); - st->hLPDmem->q_lpd_syn = Q_new; - move16(); + IF( st->hTdCngEnc != NULL ) { FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index bdc39e797..77ddb35aa 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -157,6 +157,7 @@ void tdm_low_rate_enc( { E_UTIL_synthesis( 0, p_Aq, &exc_wo_nf_fx[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1, M ); /* Q_new */ p_Aq += ( M + 1 ); + scale_sig( hLPDmem->mem_syn, M, sub( hLPDmem->q_mem_syn, Q_new ) ); // Q_new -> hLPDmem->q_mem_syn } /*--------------------------------------------------------------------------------------* diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index e0a944981..7d268b92a 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2799,12 +2799,14 @@ void tcx_encoder_memory_update_ivas_fx( Copy( xn_buf, synth, L_frame_glob ); Copy( synth + sub( L_frame_glob, M + 1 ), LPDmem->syn, M + 1 ); + LPDmem->q_lpd_syn = Q_new; + move16(); IF( st->tcxonly == 0 ) { /* Update weighted synthesis */ Residu3_fx( Ai + imult1616( sub( st->nb_subfr, 1 ), ( M + 1 ) ), synth + sub( L_frame_glob, 1 ), &tmp, 1, 0 ); - LPDmem->mem_w0 = sub_sat( wsig[sub( L_frame_glob, 1 )], tmp ); + LPDmem->mem_w0 = sub_sat( wsig[L_frame_glob - 1], tmp ); move16(); } @@ -2817,6 +2819,11 @@ void tcx_encoder_memory_update_ivas_fx( Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M ); Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M ); Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM ); + + /* Aligning the Q-factor of the remaining synthesis memory buffers */ + Scale_sig( LPDmem->mem_syn1_fx, M, sub( Q_new, LPDmem->q_mem_syn ) ); + Scale_sig( LPDmem->mem_syn3, M, sub( Q_new, LPDmem->q_mem_syn ) ); + LPDmem->q_mem_syn = Q_new; // resultant q of synth after E_UTIL_f_preemph2 move16(); -- GitLab From 7745e2b1aacfd73bfa93953a048a3ff824c6da1c Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 24 Mar 2025 10:41:39 +0530 Subject: [PATCH 0550/1221] Fix for 3GPP issue 1425: IssueAssert in generate_masking_noise_dirac_ivas_fx of BASOP decoder when fed with MASA bitstream from BASOP encoder Link #1425 --- lib_dec/fd_cng_dec_fx.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index c1289b8a3..2f9c567c1 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1318,13 +1318,10 @@ Word16 ApplyFdCng_ivas_fx( e_shift = sub( s, q_norm ); } } - FOR( ; k < hFdCngCom->npart; k++ ) + FOR( ; j < FFTCLDFBLEN; j++ ) { - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], sub( s, e_shift ) ); /*Q: s*/ - move32(); - } + cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], sub( s, e_shift ) ); /*Q: s*/ + move32(); } *cngNoiseLevel_exp = add( add( hFdCngDec->bandNoiseShape_exp, s2 ), e_shift ); @@ -1685,14 +1682,13 @@ Word16 ApplyFdCng_ivas_fx( } /* adapt scaling for rest of the buffer */ s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); - FOR( ; k < hFdCngCom->npart; k++ ) + + FOR( ; j < FFTCLDFBLEN; j++ ) { - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ - move32(); - } + cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ + move32(); } + *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); move16(); } @@ -1759,15 +1755,15 @@ Word16 ApplyFdCng_ivas_fx( } /* adapt scaling for rest of the buffer */ s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); - FOR( ; k < hFdCngCom->npart; k++ ) + + FOR( ; j < FFTCLDFBLEN; j++ ) { - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ - cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ - move32(); - } + /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ + cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ + move32(); } + + *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); move16(); } -- GitLab From c63f60e770047a825baac275d55b4f17dd6a44d7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 24 Mar 2025 15:07:19 +0530 Subject: [PATCH 0551/1221] Fix for 3GPP issue 1419: BER detect in Stereo Decoder at 13.2 kbps DTX Link #1419 --- lib_enc/lsf_enc_fx.c | 2 +- lib_enc/mslvq_enc_fx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 6761dfb82..e6d08c49d 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -733,7 +733,7 @@ static void lsfq_CNG_ivas_fx( /* MSVQ_ROM to be updated */ mslvq_cng_ivas_fx( idx_cv, dd, qlsf, ddq, idx_lead_cng, idx_scale_cng, wghts ); - index_lvq_ivas_fx( ddq, idx_lead_cng, idx_scale_cng, START_CNG + idx_cv, idx_lvq, 0 ); + index_lvq_ivas_fx( ddq, idx_lead_cng, idx_scale_cng, START_CNG_IVAS + idx_cv, idx_lvq, 0 ); Vr_add( qlsf, &CNG_SN1_fx[idx_cv * M], qlsf, M ); /* write the VQ index to the bitstream */ diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index af5a82b69..f15b80655 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -244,7 +244,7 @@ Word32 mslvq_cng_ivas_fx( /* for CNG there is only one bitrate but several lattice quantizer structures, depending on the previous VQ stage */ - mode_glb = add( START_CNG, idx_cv ); + mode_glb = add( START_CNG_IVAS, idx_cv ); move16(); p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 -- GitLab From c93ce9f445b6840fec45c9e206da6e8d6cf7353f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 24 Mar 2025 15:13:17 +0530 Subject: [PATCH 0552/1221] Fix for 3GPP issue 1410: Major Difference for Stereo input at noisy segments 13.2 kbps DTX 32kHz SWB Link #1410 --- lib_enc/ivas_core_pre_proc_front_fx.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 96c1b168f..4ff34272f 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1855,7 +1855,7 @@ static void calculate_energy_buffer_ivas_fx( const Word32 input_Fs, /* i : input sampling rate Q0*/ Word16 *enerBuffer_dft_e ) { - Word16 i, j; + Word16 i, j, guard_bits; Word64 nrg_DMX_fx[CLDFB_NO_CHANNELS_MAX]; Word64 *p_nrg_DMX_fx; Word32 *pDFT_DMX_fx; /*q_DFT_DMX_fx*/ @@ -1863,8 +1863,6 @@ static void calculate_energy_buffer_ivas_fx( Word16 band_res_dft_fx, chan_width_f_fx, start, stop; Word16 norm_nrg_DMX_fx; Word64 max_abs_nrg_DMX_fx; - Flag overflow = 0; - move32(); max_abs_nrg_DMX_fx = 0; move64(); @@ -1881,22 +1879,23 @@ static void calculate_energy_buffer_ivas_fx( start = 1; move16(); - pDFT_DMX_fx = hCPE->hStereoDft->DFT_fx[0]; /*q_DFT_DMX_fx = 31-hCPE->hStereoDft->DFT_fx_e[0]*/ + guard_bits = add( find_guarded_bits_fx( extract_h( chan_width_bins_fx ) ), 1 ); /* Q0 */ + + pDFT_DMX_fx = hCPE->hStereoDft->DFT_fx[0]; /* q_DFT_DMX_fx = 31 - hCPE->hStereoDft->DFT_fx_e[0] */ p_nrg_DMX_fx = nrg_DMX_fx; - *p_nrg_DMX_fx = Mpy_32_32( pDFT_DMX_fx[0], pDFT_DMX_fx[0] ); /*2 * q_DFT_DMX_fx -31 */ + *p_nrg_DMX_fx = W_shr( W_mult_32_32( pDFT_DMX_fx[0], pDFT_DMX_fx[0] ), guard_bits ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits */ move64(); FOR( i = 0; i < no_channels; i++ ) { - stop = extract_l( L_shr( L_add( Mpy_32_16_1( chan_width_bins_fx, add( i, 1 ) ), 1 ), 1 ) ); + stop = extract_l( L_shr( L_add( Mpy_32_16_1( chan_width_bins_fx, add( i, 1 ) ), 1 ), 1 ) ); /* Q0 */ FOR( j = start; j < stop; j++ ) { - *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, Mpy_32_32( pDFT_DMX_fx[2 * j], pDFT_DMX_fx[2 * j] ) ); /*2 * q_DFT_DMX_fx -31 */ + *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, W_shr( W_mult_32_32( pDFT_DMX_fx[2 * j], pDFT_DMX_fx[2 * j] ), guard_bits ) ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits */ move64(); - *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, Mpy_32_32( pDFT_DMX_fx[2 * j + 1], pDFT_DMX_fx[2 * j + 1] ) ); + *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, W_shr( W_mult_32_32( pDFT_DMX_fx[2 * j + 1], pDFT_DMX_fx[2 * j + 1] ), guard_bits ) ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits */ move64(); - // 2 * DFT_fx_e } IF( GT_64( W_abs( *p_nrg_DMX_fx ), max_abs_nrg_DMX_fx ) ) { @@ -1910,11 +1909,11 @@ static void calculate_energy_buffer_ivas_fx( norm_nrg_DMX_fx = W_norm( max_abs_nrg_DMX_fx ); FOR( i = 0; i < no_channels; i++ ) /* Consider only used channels, dependent on Fs */ { - enerBuffer_dft_fx[i] = W_extract_h( W_shl_o( nrg_DMX_fx[i], norm_nrg_DMX_fx, &overflow ) ) / 3; /*q_enerBuffer_dft_fx=2 * q_DFT_DMX_fx -31+ norm_nrg_DMX_fx -32*/ + enerBuffer_dft_fx[i] = Mpy_32_16_1( W_extract_h( W_shl( nrg_DMX_fx[i], norm_nrg_DMX_fx ) ), 10923 /* 1/3 in Q15 */ ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits + norm_nrg_DMX_fx - 32 */ move32(); } - *enerBuffer_dft_e = sub( add( 32, shl( hCPE->hStereoDft->DFT_fx_e[0], 1 ) ), norm_nrg_DMX_fx ); /*31-q_enerBuffer_dft_fx*/ + *enerBuffer_dft_e = sub( add( shl( hCPE->hStereoDft->DFT_fx_e[0], 1 ), guard_bits ), norm_nrg_DMX_fx ); move16(); /* Set remaining entries of enerBuffer to zero */ -- GitLab From ca78d64b8655295422fafd8100f4bd609b71a8c9 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 10:53:47 +0100 Subject: [PATCH 0553/1221] [revert-me] use other branch for testing --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33a38214e..7f9c4b622 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "ci/split-output-files-b4-comparison" + BASOP_CI_BRANCH_PC_REPO: "kiene/tmp-branch-for-ltv-split-testing" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From 542102d19ee03f87649465f81b357f905e50d55b Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 10:56:26 +0100 Subject: [PATCH 0554/1221] exclude JBM from split comparison splitting is only done on wav outputs, but not on tracefiles --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7f9c4b622..18ee8f878 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -405,7 +405,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k 'not JBM'" fi # DMX comparison only in manual job with no other metrics - if [ "$COMPARE_DMX" = "true" ]; then -- GitLab From 80cef4c62c104565540aed445c886e6d3876fc24 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 12:25:04 +0100 Subject: [PATCH 0555/1221] try different env var export --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 18ee8f878..ee9864b39 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -405,7 +405,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k 'not JBM'" fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k not JBM" fi # DMX comparison only in manual job with no other metrics - if [ "$COMPARE_DMX" = "true" ]; then -- GitLab From 1c525e918c69a670c88b58cf98bc4e7e088eedcd Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 12:31:59 +0100 Subject: [PATCH 0556/1221] move reference creation to also exclude JBM cases there --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ee9864b39..95e4fa282 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -397,7 +397,6 @@ stages: - if [ "$COMPARE_DMX" = "true" ] || [ "$ENCODER_TEST" = "true" ]; then - BUILD_WITH_DEBUG_MODE_INFO="true" - fi - - *build-and-create-float-ref-outputs - comp_args="--mld --ssnr --odg" @@ -407,6 +406,8 @@ stages: - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k not JBM" fi + - *build-and-create-float-ref-outputs + # DMX comparison only in manual job with no other metrics - if [ "$COMPARE_DMX" = "true" ]; then - comp_args="--compare_enc_dmx" -- GitLab From 5c3730f6c0ac44821c85cc9af520ef5f3b368806 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 12:37:23 +0100 Subject: [PATCH 0557/1221] fix missing ; --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95e4fa282..5d9caaa88 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -404,7 +404,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k not JBM" fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k not JBM"; fi - *build-and-create-float-ref-outputs -- GitLab From 86bf628facb296a90adc606fe831a8167539b17d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 12:47:04 +0100 Subject: [PATCH 0558/1221] add escaped qoutes --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d9caaa88..836829bbc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -404,7 +404,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k not JBM"; fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM\""; fi - *build-and-create-float-ref-outputs -- GitLab From 222bf462ed4a61c0bcb48c7e4617bab1c2284e28 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 24 Mar 2025 13:52:15 +0100 Subject: [PATCH 0559/1221] Use L_norm_arr instead of getScaleFactor32. Add assert checking proto_power_smooth q values. --- lib_dec/ivas_dirac_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 1c06de82d..a52390f68 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3774,7 +3774,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ) ) ); + exp = s_min( exp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ) ) ); } FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { @@ -3804,7 +3804,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - exp = s_min( exp, getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + exp = s_min( exp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); } FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { -- GitLab From dc953d6b954c44e839c54a0de07d5da3716131c7 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 7 Mar 2025 15:04:57 +0100 Subject: [PATCH 0560/1221] first draft of the improvement. --- lib_enc/ivas_sns_enc_fx.c | 102 +++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index dfd207c3e..36c5cebec 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -170,6 +170,103 @@ static Word16 sns_1st_cod_fx( return index; } +static Word16 sns_1st_cod_fx_q15( + const Word32 *sns_fx, /* i : vector to quantize */ + const Word16 L_frame, + const Word16 core, + Word32 *snsq_fx /* o : quantized sns Q16 */ +) +{ + Word16 index; + const Word16 split_len = M / 2; + move16(); + const Word16 *means; + const Word16 means_fix = 2; // Q15 + push_wmops("sns_1st_cod_fx_q15"); + move16(); + /* remove means */ + means = NULL; + SWITCH( L_frame ) + { + case L_FRAME16k: + means = &sns_1st_means_16k[core - 1][0]; + break; + case L_FRAME25_6k: + means = &sns_1st_means_25k6[core - 1][0]; + break; + case L_FRAME32k: + means = &sns_1st_means_32k[core - 1][0]; + break; + default: + assert( !"illegal frame length in sns_1st_cod" ); + } + FOR( Word16 i = 0; i < M; ++i ) + { + Word32 tmp = L_mult( means[i], means_fix ); // Q16 + snsq_fx[i] = L_add(sns_fx[i], L_negate( tmp ) ); + move32(); + } + + index = 0; + move16(); + FOR( Word16 split = 0; split < 2; ++split ) + { + const Word16 *cdbk_ptr; + Word16 j0, j1; + Word16 dist_split; + Word64 dist_min_fx; + const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 + move16(); + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + + j0 = imult1616( split, split_len ); + j1 = add( j0, split_len ); + + cdbk_ptr = cdbk; + dist_min_fx = 0x7fffffffffffffffull; + dist_split = 0; + FOR( Word16 i = 0; i < 32; ++i ) + { + Word64 dist_fx = 0; + move64(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 dist; + Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + move16(); + dist = ( L_add(snsq_fx[j], L_negate( tmp_1 ) ) ); + dist_fx = W_mac_32_32( dist_fx, dist, dist ); + } + + if ( LT_64( dist_fx, dist_min_fx ) ) + { + dist_min_fx= dist_fx; + dist_split =i ; + } + } + + /* set quantized vector */ + cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + move32(); + } + + /* for second split shift by five bits to store both indices as one 10 bit value */ + IF( EQ_16( split, 1 ) ) + { + dist_split = shl( dist_split, 5 ); + } + + index = add( index, dist_split ); + } + pop_wmops(); + return index; +} + /*------------------------------------------------------------------- * sns_2st_cod() * @@ -275,7 +372,7 @@ void sns_avq_cod_fx( Word16 indxt[256], nbits, nbt, nit; Word32 snsmid_q0_fx[M]; - index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx ); + index[0] = sns_1st_cod_fx_q15( sns_fx, L_frame, core, sns_q_fx ); move16(); nit = 1 + 2; move16(); @@ -302,7 +399,8 @@ void sns_avq_cod_fx( { index++; - index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); + index[0] = sns_1st_cod_fx_q15( snsmid_fx, L_frame, core, snsmid_q_fx ); +// index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); move16(); nit = 1 + 2; move16(); -- GitLab From d557e115a42e4ca5fa1ff56a95ad0c97f312ed0d Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 7 Mar 2025 15:34:59 +0100 Subject: [PATCH 0561/1221] addressed some code review comments in sns_1st_cod_fx_q15(). --- lib_enc/ivas_sns_enc_fx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 36c5cebec..edcc33905 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -225,6 +225,8 @@ static Word16 sns_1st_cod_fx_q15( cdbk_ptr = cdbk; dist_min_fx = 0x7fffffffffffffffull; dist_split = 0; + move64(); + move16(); FOR( Word16 i = 0; i < 32; ++i ) { Word64 dist_fx = 0; @@ -233,12 +235,11 @@ static Word16 sns_1st_cod_fx_q15( { Word32 dist; Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - move16(); dist = ( L_add(snsq_fx[j], L_negate( tmp_1 ) ) ); dist_fx = W_mac_32_32( dist_fx, dist, dist ); } - if ( LT_64( dist_fx, dist_min_fx ) ) + IF ( LT_64( dist_fx, dist_min_fx ) ) { dist_min_fx= dist_fx; dist_split =i ; @@ -256,7 +257,7 @@ static Word16 sns_1st_cod_fx_q15( } /* for second split shift by five bits to store both indices as one 10 bit value */ - IF( EQ_16( split, 1 ) ) + if( EQ_16( split, 1 ) ) { dist_split = shl( dist_split, 5 ); } -- GitLab From 9d90ec3885d76536134f7a8f26b8bbee36ca6a27 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 7 Mar 2025 18:42:08 +0100 Subject: [PATCH 0562/1221] formatting --- lib_enc/ivas_sns_enc_fx.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index edcc33905..d5a15eaa1 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -182,7 +182,7 @@ static Word16 sns_1st_cod_fx_q15( move16(); const Word16 *means; const Word16 means_fix = 2; // Q15 - push_wmops("sns_1st_cod_fx_q15"); + push_wmops( "sns_1st_cod_fx_q15" ); move16(); /* remove means */ means = NULL; @@ -203,7 +203,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_add(sns_fx[i], L_negate( tmp ) ); + snsq_fx[i] = L_add( sns_fx[i], L_negate( tmp ) ); move32(); } @@ -213,8 +213,8 @@ static Word16 sns_1st_cod_fx_q15( { const Word16 *cdbk_ptr; Word16 j0, j1; - Word16 dist_split; - Word64 dist_min_fx; + Word16 dist_split; + Word64 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; @@ -225,26 +225,26 @@ static Word16 sns_1st_cod_fx_q15( cdbk_ptr = cdbk; dist_min_fx = 0x7fffffffffffffffull; dist_split = 0; - move64(); - move16(); - FOR( Word16 i = 0; i < 32; ++i ) - { - Word64 dist_fx = 0; - move64(); - FOR( Word16 j = j0; j < j1; ++j ) - { - Word32 dist; - Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - dist = ( L_add(snsq_fx[j], L_negate( tmp_1 ) ) ); - dist_fx = W_mac_32_32( dist_fx, dist, dist ); - } - - IF ( LT_64( dist_fx, dist_min_fx ) ) - { - dist_min_fx= dist_fx; - dist_split =i ; - } - } + move64(); + move16(); + FOR( Word16 i = 0; i < 32; ++i ) + { + Word64 dist_fx = 0; + move64(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 dist; + Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); + dist_fx = W_mac_32_32( dist_fx, dist, dist ); + } + + IF( LT_64( dist_fx, dist_min_fx ) ) + { + dist_min_fx = dist_fx; + dist_split = i; + } + } /* set quantized vector */ cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; @@ -257,14 +257,14 @@ static Word16 sns_1st_cod_fx_q15( } /* for second split shift by five bits to store both indices as one 10 bit value */ - if( EQ_16( split, 1 ) ) + if ( EQ_16( split, 1 ) ) { dist_split = shl( dist_split, 5 ); } index = add( index, dist_split ); } - pop_wmops(); + pop_wmops(); return index; } @@ -401,7 +401,7 @@ void sns_avq_cod_fx( index++; index[0] = sns_1st_cod_fx_q15( snsmid_fx, L_frame, core, snsmid_q_fx ); -// index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); + // index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); move16(); nit = 1 + 2; move16(); -- GitLab From 8ae004120e7dac853096aa92ebbad6163de5b8ac Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 10 Mar 2025 13:59:00 +0100 Subject: [PATCH 0563/1221] sns_1st_cod_fx_q15() implemented with a 32 bit multiplication. --- lib_enc/ivas_sns_enc_fx.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index d5a15eaa1..3f614483f 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -214,7 +214,7 @@ static Word16 sns_1st_cod_fx_q15( const Word16 *cdbk_ptr; Word16 j0, j1; Word16 dist_split; - Word64 dist_min_fx; + Word32 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; @@ -223,23 +223,26 @@ static Word16 sns_1st_cod_fx_q15( j1 = add( j0, split_len ); cdbk_ptr = cdbk; - dist_min_fx = 0x7fffffffffffffffull; + dist_min_fx = MAXVAL_WORD32; dist_split = 0; - move64(); + move32(); move16(); FOR( Word16 i = 0; i < 32; ++i ) { - Word64 dist_fx = 0; - move64(); + Word32 dist_fx = 0; + move32(); FOR( Word16 j = j0; j < j1; ++j ) { Word32 dist; Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); - dist_fx = W_mac_32_32( dist_fx, dist, dist ); + dist = L_shr( dist, 4 ); // TODO: Magic shift. + dist = L_mult( extract_l( dist ), extract_l( dist ) ); + dist = L_shr( dist, 4 ); // TODO: Magic shift + dist_fx = L_add( dist_fx, dist ); } - IF( LT_64( dist_fx, dist_min_fx ) ) + IF( LT_32( dist_fx, dist_min_fx ) ) { dist_min_fx = dist_fx; dist_split = i; -- GitLab From 08931100877083b6da7c75702f4c0dde3110e2b2 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 10 Mar 2025 14:30:29 +0100 Subject: [PATCH 0564/1221] appl --- lib_enc/ivas_sns_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 3f614483f..b2da2ca78 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -236,9 +236,9 @@ static Word16 sns_1st_cod_fx_q15( Word32 dist; Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); - dist = L_shr( dist, 4 ); // TODO: Magic shift. + dist = L_shr( dist, 4 ); // TODO: Magic shift. dist = L_mult( extract_l( dist ), extract_l( dist ) ); - dist = L_shr( dist, 4 ); // TODO: Magic shift + dist = L_shr( dist, 4 ); // TODO: Magic shift dist_fx = L_add( dist_fx, dist ); } -- GitLab From d6bea61a73d6e70eb0f592b0f34476ef9264809f Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 11 Mar 2025 13:18:07 +0100 Subject: [PATCH 0565/1221] minor wmops improvement in sns_1st_cod_fx_q15. --- lib_enc/ivas_sns_enc_fx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index b2da2ca78..b57674417 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -203,7 +203,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_add( sns_fx[i], L_negate( tmp ) ); + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } @@ -233,9 +233,10 @@ static Word16 sns_1st_cod_fx_q15( move32(); FOR( Word16 j = j0; j < j1; ++j ) { + Word32 tmp; Word32 dist; - Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - dist = ( L_add( snsq_fx[j], L_negate( tmp_1 ) ) ); + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 + dist = L_sub( snsq_fx[j], tmp ); dist = L_shr( dist, 4 ); // TODO: Magic shift. dist = L_mult( extract_l( dist ), extract_l( dist ) ); dist = L_shr( dist, 4 ); // TODO: Magic shift @@ -253,8 +254,8 @@ static Word16 sns_1st_cod_fx_q15( cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( *cdbk_ptr++ , cdbk_fix ); // Q16 snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } -- GitLab From 8d92d646939725ff3b80d83422f87b9b620cad9b Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Mar 2025 11:15:44 +0100 Subject: [PATCH 0566/1221] preparation for the cleanup. --- lib_enc/ivas_sns_enc_fx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index b57674417..54bceec9a 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -203,7 +203,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } @@ -235,11 +235,15 @@ static Word16 sns_1st_cod_fx_q15( { Word32 tmp; Word32 dist; + Word16 tmp2; + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 dist = L_sub( snsq_fx[j], tmp ); - dist = L_shr( dist, 4 ); // TODO: Magic shift. - dist = L_mult( extract_l( dist ), extract_l( dist ) ); - dist = L_shr( dist, 4 ); // TODO: Magic shift + dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow + + tmp2 = extract_l( dist ); + dist = L_mult( tmp2, tmp2 ); + dist = L_shr( dist, 4 ); // make sure that the sum does not overflow dist_fx = L_add( dist_fx, dist ); } @@ -255,7 +259,7 @@ static Word16 sns_1st_cod_fx_q15( FOR( Word16 j = j0; j < j1; ++j ) { Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( *cdbk_ptr++ , cdbk_fix ); // Q16 + Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } -- GitLab From 95d4681f8725fb3c0850ec3083e444eb5695697e Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Mar 2025 11:53:54 +0100 Subject: [PATCH 0567/1221] merge candiate. --- lib_enc/ivas_sns_enc_fx.c | 376 +++++++++++++++++++------------------- 1 file changed, 184 insertions(+), 192 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 54bceec9a..7cda2970b 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,221 +59,214 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - Word16 index, i; - const Word16 split_len = M / 2; - move16(); - const Word16 *means; - const Word16 means_fix = 2; // Q15 - move16(); - /* remove means */ - means = NULL; - SWITCH( L_frame ) + IF( exp_sns == Q15) { - case L_FRAME16k: - means = &sns_1st_means_16k[core - 1][0]; - break; - case L_FRAME25_6k: - means = &sns_1st_means_25k6[core - 1][0]; - break; - case L_FRAME32k: - means = &sns_1st_means_32k[core - 1][0]; - break; - default: - assert( !"illegal frame length in sns_1st_cod" ); - } - Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; - move16(); - move16(); - FOR( i = 0; i < M; ++i ) - { - Word32 tmp = L_mult( means[i], means_fix ); // Q16 - exp_snsq_buffer[i] = 0; + Word16 index; + const Word16 split_len = M / 2; move16(); - snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); - move32(); - } - FOR( i = 0; i < M; i++ ) - { - exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); - } - FOR( i = 0; i < M; i++ ) - { - snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); - move32(); - } - - index = 0; - move16(); - FOR( Word16 split = 0; split < 2; ++split ) - { - const Word16 *cdbk_ptr; - Word16 j0, j1, index_split; - Word32 dist_min_fx; - const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 + const Word16 *means; + const Word16 means_fix = 2; // Q15 move16(); - const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - - j0 = imult1616( split, split_len ); - j1 = add( j0, split_len ); - - cdbk_ptr = cdbk; - dist_min_fx = MAXVAL_WORD32; - Word16 exp_dist_min = 31; - index_split = 0; - FOR( i = 0; i < 32; ++i ) + /* remove means */ + means = NULL; + SWITCH( L_frame ) + { + case L_FRAME16k: + means = &sns_1st_means_16k[core - 1][0]; + break; + case L_FRAME25_6k: + means = &sns_1st_means_25k6[core - 1][0]; + break; + case L_FRAME32k: + means = &sns_1st_means_32k[core - 1][0]; + break; + default: + assert( !"illegal frame length in sns_1st_cod" ); + } + FOR( Word16 i = 0; i < M; ++i ) { - Word32 dist_fx = 0; + Word32 tmp = L_mult( means[i], means_fix ); // Q16 + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); - Word16 exp_dist = 0; + } + + index = 0; + move16(); + FOR( Word16 split = 0; split < 2; ++split ) + { + const Word16 *cdbk_ptr; + Word16 j0, j1; + Word16 dist_split; + Word32 dist_min_fx; + const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); - FOR( Word16 j = j0; j < j1; ++j ) + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + + j0 = imult1616( split, split_len ); + j1 = add( j0, split_len ); + + cdbk_ptr = cdbk; + dist_min_fx = MAXVAL_WORD32; + dist_split = 0; + move32(); + move16(); + FOR( Word16 i = 0; i < 32; ++i ) { - Word32 tmp_fx; - Word16 exp_tmp = 0; - move16(); - Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp ); - Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2 - dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2 + Word32 dist_fx = 0; + move32(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 tmp; + Word32 dist; + Word16 tmp2; + + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 + dist = L_sub( snsq_fx[j], tmp ); + dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow + + tmp2 = extract_l( dist ); + dist = L_mult( tmp2, tmp2 ); + dist = L_shr( dist, 4 ); // make sure that the sum does not overflow + dist_fx = L_add( dist_fx, dist ); + } + + IF( LT_32( dist_fx, dist_min_fx ) ) + { + dist_min_fx = dist_fx; + dist_split = i; + } } - - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) ) + + /* set quantized vector */ + cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; + FOR( Word16 j = j0; j < j1; ++j ) { - dist_min_fx = dist_fx; + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); - exp_dist_min = exp_dist; - move16(); - index_split = i; - move16(); } + + /* for second split shift by five bits to store both indices as one 10 bit value */ + if ( EQ_16( split, 1 ) ) + { + dist_split = shl( dist_split, 5 ); + } + + index = add( index, dist_split ); } - - /* set quantized vector */ - cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; - FOR( Word16 j = j0; j < j1; ++j ) + return index; + } ELSE { + Word16 index, i; + const Word16 split_len = M / 2; + move16(); + const Word16 *means; + const Word16 means_fix = 2; // Q15 + move16(); + /* remove means */ + means = NULL; + SWITCH( L_frame ) { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 - snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + case L_FRAME16k: + means = &sns_1st_means_16k[core - 1][0]; + break; + case L_FRAME25_6k: + means = &sns_1st_means_25k6[core - 1][0]; + break; + case L_FRAME32k: + means = &sns_1st_means_32k[core - 1][0]; + break; + default: + assert( !"illegal frame length in sns_1st_cod" ); + } + Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; + move16(); + move16(); + FOR( i = 0; i < M; ++i ) + { + Word32 tmp = L_mult( means[i], means_fix ); // Q16 + exp_snsq_buffer[i] = 0; + move16(); + snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); move32(); } - - /* for second split shift by five bits to store both indices as one 10 bit value */ - IF( EQ_16( split, 1 ) ) + FOR( i = 0; i < M; i++ ) { - index_split = shl( index_split, 5 ); + exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); } - - index = add( index, index_split ); - } - - return index; -} - -static Word16 sns_1st_cod_fx_q15( - const Word32 *sns_fx, /* i : vector to quantize */ - const Word16 L_frame, - const Word16 core, - Word32 *snsq_fx /* o : quantized sns Q16 */ -) -{ - Word16 index; - const Word16 split_len = M / 2; - move16(); - const Word16 *means; - const Word16 means_fix = 2; // Q15 - push_wmops( "sns_1st_cod_fx_q15" ); - move16(); - /* remove means */ - means = NULL; - SWITCH( L_frame ) - { - case L_FRAME16k: - means = &sns_1st_means_16k[core - 1][0]; - break; - case L_FRAME25_6k: - means = &sns_1st_means_25k6[core - 1][0]; - break; - case L_FRAME32k: - means = &sns_1st_means_32k[core - 1][0]; - break; - default: - assert( !"illegal frame length in sns_1st_cod" ); - } - FOR( Word16 i = 0; i < M; ++i ) - { - Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 - move32(); - } - - index = 0; - move16(); - FOR( Word16 split = 0; split < 2; ++split ) - { - const Word16 *cdbk_ptr; - Word16 j0, j1; - Word16 dist_split; - Word32 dist_min_fx; - const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 - move16(); - const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - - j0 = imult1616( split, split_len ); - j1 = add( j0, split_len ); - - cdbk_ptr = cdbk; - dist_min_fx = MAXVAL_WORD32; - dist_split = 0; - move32(); - move16(); - FOR( Word16 i = 0; i < 32; ++i ) + FOR( i = 0; i < M; i++ ) { - Word32 dist_fx = 0; + snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); + } + + index = 0; + move16(); + FOR( Word16 split = 0; split < 2; ++split ) + { + const Word16 *cdbk_ptr; + Word16 j0, j1, index_split; + Word32 dist_min_fx; + const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 + move16(); + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + + j0 = imult1616( split, split_len ); + j1 = add( j0, split_len ); + + cdbk_ptr = cdbk; + dist_min_fx = MAXVAL_WORD32; + Word16 exp_dist_min = 31; + index_split = 0; + FOR( i = 0; i < 32; ++i ) + { + Word32 dist_fx = 0; + move32(); + Word16 exp_dist = 0; + move16(); + FOR( Word16 j = j0; j < j1; ++j ) + { + Word32 tmp_fx; + Word16 exp_tmp = 0; + move16(); + Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp ); + Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2 + dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2 + } + + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) ) + { + dist_min_fx = dist_fx; + move32(); + exp_dist_min = exp_dist; + move16(); + index_split = i; + move16(); + } + } + + /* set quantized vector */ + cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { - Word32 tmp; - Word32 dist; - Word16 tmp2; - - tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - dist = L_sub( snsq_fx[j], tmp ); - dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow - - tmp2 = extract_l( dist ); - dist = L_mult( tmp2, tmp2 ); - dist = L_shr( dist, 4 ); // make sure that the sum does not overflow - dist_fx = L_add( dist_fx, dist ); + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + move32(); } - - IF( LT_32( dist_fx, dist_min_fx ) ) + + /* for second split shift by five bits to store both indices as one 10 bit value */ + IF( EQ_16( split, 1 ) ) { - dist_min_fx = dist_fx; - dist_split = i; + index_split = shl( index_split, 5 ); } + + index = add( index, index_split ); } - - /* set quantized vector */ - cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; - FOR( Word16 j = j0; j < j1; ++j ) - { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 - Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 - move32(); - } - - /* for second split shift by five bits to store both indices as one 10 bit value */ - if ( EQ_16( split, 1 ) ) - { - dist_split = shl( dist_split, 5 ); - } - - index = add( index, dist_split ); + + return index; } - pop_wmops(); - return index; } /*------------------------------------------------------------------- @@ -381,7 +374,7 @@ void sns_avq_cod_fx( Word16 indxt[256], nbits, nbt, nit; Word32 snsmid_q0_fx[M]; - index[0] = sns_1st_cod_fx_q15( sns_fx, L_frame, core, sns_q_fx ); + index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx ); move16(); nit = 1 + 2; move16(); @@ -408,8 +401,7 @@ void sns_avq_cod_fx( { index++; - index[0] = sns_1st_cod_fx_q15( snsmid_fx, L_frame, core, snsmid_q_fx ); - // index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); + index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx ); move16(); nit = 1 + 2; move16(); -- GitLab From b934c216373187aabab3803c34d2bbdd46829394 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 12 Mar 2025 12:01:43 +0100 Subject: [PATCH 0568/1221] applied the clang patch. --- lib_enc/ivas_sns_enc_fx.c | 48 ++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 7cda2970b..7b1aa46de 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - IF( exp_sns == Q15) + IF( exp_sns == Q15 ) { Word16 index; const Word16 split_len = M / 2; @@ -86,10 +86,10 @@ static Word16 sns_1st_cod_fx( FOR( Word16 i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 - snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 + snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } - + index = 0; move16(); FOR( Word16 split = 0; split < 2; ++split ) @@ -101,10 +101,10 @@ static Word16 sns_1st_cod_fx( const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - + j0 = imult1616( split, split_len ); j1 = add( j0, split_len ); - + cdbk_ptr = cdbk; dist_min_fx = MAXVAL_WORD32; dist_split = 0; @@ -119,44 +119,46 @@ static Word16 sns_1st_cod_fx( Word32 tmp; Word32 dist; Word16 tmp2; - + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - dist = L_sub( snsq_fx[j], tmp ); + dist = L_sub( snsq_fx[j], tmp ); dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow - + tmp2 = extract_l( dist ); dist = L_mult( tmp2, tmp2 ); dist = L_shr( dist, 4 ); // make sure that the sum does not overflow dist_fx = L_add( dist_fx, dist ); } - + IF( LT_32( dist_fx, dist_min_fx ) ) { dist_min_fx = dist_fx; dist_split = i; } } - + /* set quantized vector */ cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { - Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 + Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 + snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } - + /* for second split shift by five bits to store both indices as one 10 bit value */ if ( EQ_16( split, 1 ) ) { dist_split = shl( dist_split, 5 ); } - + index = add( index, dist_split ); } return index; - } ELSE { + } + ELSE + { Word16 index, i; const Word16 split_len = M / 2; move16(); @@ -199,7 +201,7 @@ static Word16 sns_1st_cod_fx( snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); } - + index = 0; move16(); FOR( Word16 split = 0; split < 2; ++split ) @@ -210,10 +212,10 @@ static Word16 sns_1st_cod_fx( const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; - + j0 = imult1616( split, split_len ); j1 = add( j0, split_len ); - + cdbk_ptr = cdbk; dist_min_fx = MAXVAL_WORD32; Word16 exp_dist_min = 31; @@ -234,7 +236,7 @@ static Word16 sns_1st_cod_fx( Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2 dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2 } - + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) ) { dist_min_fx = dist_fx; @@ -245,7 +247,7 @@ static Word16 sns_1st_cod_fx( move16(); } } - + /* set quantized vector */ cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) @@ -255,16 +257,16 @@ static Word16 sns_1st_cod_fx( snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16 move32(); } - + /* for second split shift by five bits to store both indices as one 10 bit value */ IF( EQ_16( split, 1 ) ) { index_split = shl( index_split, 5 ); } - + index = add( index, index_split ); } - + return index; } } -- GitLab From 451006570aed7b42153a3ce4ba4ced74e21b28c5 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 19 Mar 2025 11:15:50 +0100 Subject: [PATCH 0569/1221] add missing move16(), move32(); don't change variable name to stay closer to float and the other variant --- lib_enc/ivas_sns_enc_fx.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 7b1aa46de..2271b6ac6 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -96,7 +96,7 @@ static Word16 sns_1st_cod_fx( { const Word16 *cdbk_ptr; Word16 j0, j1; - Word16 dist_split; + Word16 index_split; Word32 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); @@ -107,7 +107,7 @@ static Word16 sns_1st_cod_fx( cdbk_ptr = cdbk; dist_min_fx = MAXVAL_WORD32; - dist_split = 0; + index_split = 0; move32(); move16(); FOR( Word16 i = 0; i < 32; ++i ) @@ -133,12 +133,14 @@ static Word16 sns_1st_cod_fx( IF( LT_32( dist_fx, dist_min_fx ) ) { dist_min_fx = dist_fx; - dist_split = i; + move32(); + index_split = i; + move16(); } } /* set quantized vector */ - cdbk_ptr = &cdbk[imult1616( dist_split, split_len )]; + cdbk_ptr = &cdbk[imult1616( index_split, split_len )]; FOR( Word16 j = j0; j < j1; ++j ) { Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16 @@ -150,10 +152,10 @@ static Word16 sns_1st_cod_fx( /* for second split shift by five bits to store both indices as one 10 bit value */ if ( EQ_16( split, 1 ) ) { - dist_split = shl( dist_split, 5 ); + index_split = shl( index_split, 5 ); } - index = add( index, dist_split ); + index = add( index, index_split ); } return index; } -- GitLab From af35e72f6dd60c918968a8c593f2223bbabe8cac Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 09:16:55 +0100 Subject: [PATCH 0570/1221] added some comments for an easier review. --- lib_enc/ivas_sns_enc_fx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 2271b6ac6..c38da5958 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - IF( exp_sns == Q15 ) + IF( exp_sns == 15 ) { Word16 index; const Word16 split_len = M / 2; @@ -72,20 +72,20 @@ static Word16 sns_1st_cod_fx( SWITCH( L_frame ) { case L_FRAME16k: - means = &sns_1st_means_16k[core - 1][0]; + means = &sns_1st_means_16k[core - 1][0]; // Q14 break; case L_FRAME25_6k: - means = &sns_1st_means_25k6[core - 1][0]; + means = &sns_1st_means_25k6[core - 1][0]; // Q14 break; case L_FRAME32k: - means = &sns_1st_means_32k[core - 1][0]; + means = &sns_1st_means_32k[core - 1][0]; // Q14 break; default: assert( !"illegal frame length in sns_1st_cod" ); } FOR( Word16 i = 0; i < M; ++i ) { - Word32 tmp = L_mult( means[i], means_fix ); // Q16 + Word32 tmp = L_mult( means[i], means_fix ); // Q14->Q16 snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16 move32(); } @@ -100,7 +100,7 @@ static Word16 sns_1st_cod_fx( Word32 dist_min_fx; const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15 move16(); - const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; + const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; // Q12 j0 = imult1616( split, split_len ); j1 = add( j0, split_len ); @@ -114,14 +114,14 @@ static Word16 sns_1st_cod_fx( { Word32 dist_fx = 0; move32(); - FOR( Word16 j = j0; j < j1; ++j ) + FOR( Word16 j = j0; j < j1; ++j ) // j1-j0=split_len. split_len=M/2. M=16 { Word32 tmp; Word32 dist; Word16 tmp2; - tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16 - dist = L_sub( snsq_fx[j], tmp ); + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12-Q16 + dist = L_sub( snsq_fx[j], tmp ); // Q16 dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow tmp2 = extract_l( dist ); @@ -783,7 +783,7 @@ Word16 quantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - CONTINUE; + continue; } nStages = SNS_MSVQ_NSTAGES_SIDE; -- GitLab From f4682bc8978736c28c26fe17b1944c7fc517becb Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 09:19:06 +0100 Subject: [PATCH 0571/1221] applied the formatting patch. --- lib_enc/ivas_sns_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index c38da5958..cccf25c6b 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -121,8 +121,8 @@ static Word16 sns_1st_cod_fx( Word16 tmp2; tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12-Q16 - dist = L_sub( snsq_fx[j], tmp ); // Q16 - dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow + dist = L_sub( snsq_fx[j], tmp ); // Q16 + dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow tmp2 = extract_l( dist ); dist = L_mult( tmp2, tmp2 ); -- GitLab From ec203c64954af8985ff7be3973c14bd71298c1ed Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 10:59:04 +0100 Subject: [PATCH 0572/1221] updated the style to the standard of the rest of the code. the magic shifts have been explained. total 150.00 603.963 644.322 631.525 --- lib_enc/ivas_sns_enc_fx.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index cccf25c6b..69398ae7e 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -59,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - IF( exp_sns == 15 ) + IF( exp_sns == Q15 ) { Word16 index; const Word16 split_len = M / 2; @@ -118,15 +118,12 @@ static Word16 sns_1st_cod_fx( { Word32 tmp; Word32 dist; - Word16 tmp2; - tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12-Q16 + tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16 dist = L_sub( snsq_fx[j], tmp ); // Q16 - dist = L_shr( dist, 4 ); // make sure that the next multiplication does not overflow - - tmp2 = extract_l( dist ); - dist = L_mult( tmp2, tmp2 ); - dist = L_shr( dist, 4 ); // make sure that the sum does not overflow + dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom. + dist = Mpy_32_32( dist, dist ); + dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow dist_fx = L_add( dist_fx, dist ); } -- GitLab From 56793b3541e5053f09eccdfe95f9d36d40067229 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 17 Mar 2025 11:11:27 +0100 Subject: [PATCH 0573/1221] applied the clang formatting patch. --- lib_enc/ivas_sns_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 69398ae7e..88c2a5b7c 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -121,7 +121,7 @@ static Word16 sns_1st_cod_fx( tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16 dist = L_sub( snsq_fx[j], tmp ); // Q16 - dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom. + dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom. dist = Mpy_32_32( dist, dist ); dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow dist_fx = L_add( dist_fx, dist ); -- GitLab From 869ad0393008c0d7b617f13f692ca463fd837d81 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 19 Mar 2025 11:18:10 +0100 Subject: [PATCH 0574/1221] continue using CONTINUE instead of continue --- lib_enc/ivas_sns_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 88c2a5b7c..22cd98cad 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -780,7 +780,7 @@ Word16 quantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - continue; + CONTINUE; } nStages = SNS_MSVQ_NSTAGES_SIDE; -- GitLab From 6d0693316b9506bb18a65e3352a2fdc49a2f5263 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 18 Mar 2025 10:02:06 +0530 Subject: [PATCH 0575/1221] Fix for 3GPP issue 1384: Decoder crash for Stereo at 16.4kbps in cng_params_upd_ivas_fx() Link #1384 --- lib_com/cng_exc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index aa1ceea81..b314357ad 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -1165,7 +1165,7 @@ void cng_params_upd_ivas_fx( L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ tmp = add( add( Q_exc, Q_exc ), 1 ); - sp[i] = L_shr( L_tmp, sub( tmp, 6 ) ); + sp[i] = L_shr_o( L_tmp, sub( tmp, 6 ), &Overflow ); move32(); /* Q6 */ ptR++; ptI--; -- GitLab From 1591c3ed6e24eb945f29f0ef4b2736f8df630e44 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 19 Mar 2025 12:36:30 +0530 Subject: [PATCH 0576/1221] Fix for 3GPP issue 1408: Decoder crash for ParamMC 5.1 at 48/64/80 kbps decoding to mono in ivas_ls_setup_conversion_fx() Link #1408 --- lib_dec/ivas_jbm_dec_fx.c | 11 ----------- lib_dec/ivas_mc_param_dec_fx.c | 17 ++++++++++++----- lib_dec/ivas_out_setup_conversion_fx.c | 6 +++--- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index e7ee06648..1918ce3f3 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1288,18 +1288,7 @@ ivas_error ivas_jbm_dec_tc_fx( test(); IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) { - s = Q16 - Q11; - move16(); - s = sub( s, find_guarded_bits_fx( st_ivas->nchan_transport ) ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, s ); - } ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx ); - FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i ) - { - Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); - } } } ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index db56ad03e..b2a8bd30b 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -123,7 +123,7 @@ ivas_error ivas_param_mc_dec_open_fx( Word16 nchan_out_transport; Word16 nchan_out_cov; Word32 proto_matrix_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word32 proto_mtx_norm_fx; + Word32 proto_mtx_norm_fx, tmp32; Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; Word16 max_param_band_residual; UWord16 config_index; @@ -374,20 +374,27 @@ ivas_error ivas_param_mc_dec_open_fx( Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), 4 ); /*Q.26*/ IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) { - proto_mtx_norm_fx = ONE_IN_Q26; /*Q26*/ + tmp32 = ONE_IN_Q26; /*Q26*/ move32(); FOR( k = 0; k < nchan_transport * nchan_out_cov; k++ ) { - proto_mtx_norm_fx = L_max( L_abs( proto_mtx_norm_fx ), L_abs( proto_matrix_fx[k] ) ); /*Q.26*/ + tmp32 = L_max( L_abs( tmp32 ), L_abs( proto_matrix_fx[k] ) ); /*Q.26*/ } - proto_mtx_norm_fx = divide3232( ONE_IN_Q26, proto_mtx_norm_fx ); /*Q15*/ + proto_mtx_norm_fx = divide3232( ONE_IN_Q26, tmp32 ); /*Q15*/ /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */ FOR( k = 0; k < nchan_transport; k++ ) { FOR( Word16 i = 0; i < nchan_out_cov; i++ ) { - st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mult_32_16( proto_matrix_fx[k * nchan_out_cov + i], extract_l( proto_mtx_norm_fx ) ), 4 ); /*Q.30*/ + IF( EQ_32( proto_matrix_fx[k * nchan_out_cov + i], tmp32 ) ) + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = ONE_IN_Q30; // Q30 + } + ELSE + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mult_32_16( proto_matrix_fx[k * nchan_out_cov + i], extract_l( proto_mtx_norm_fx ) ), 4 ); /*Q.30*/ + } move32(); } } diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index c7bf0655d..756eed60e 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -586,14 +586,14 @@ void ivas_ls_setup_conversion_fx( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ const Word16 input_chans, /* i : number of input channels to the renderer */ const Word16 output_frame, /* i : frame length */ - Word32 *input[], /* i : LS input/output synthesis signal Q16*/ - Word32 *output[] /* i/o: LS input/output synthesis signal Q16*/ + Word32 *input[], /* i : LS input/output synthesis signal Qx*/ + Word32 *output[] /* i/o: LS input/output synthesis signal Qx*/ ) { Word16 chInIdx, chOutIdx, idx; LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; Word32 dmxCoeff, tmpVal; - Word32 output_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // Q16 + Word32 output_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // Qx push_wmops( "LS_Renderer" ); -- GitLab From daf39ebc2fb46799a2c5367e4314fd6335300640 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 20 Mar 2025 15:47:00 +0530 Subject: [PATCH 0577/1221] Bug fix in CNG_enc_ivas_fx, saturation removal and correction of macro value for MASA path --- lib_com/ivas_cnst.h | 2 +- lib_com/rom_com.c | 15 +++++++++++++++ lib_com/rom_com.h | 19 ++++++++++--------- lib_com/swb_tbe_com_fx.c | 2 +- lib_enc/cng_enc_fx.c | 8 ++++---- lib_enc/swb_tbe_enc_fx.c | 24 ++++++++++++------------ 6 files changed, 43 insertions(+), 27 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 2abb790f1..9243b3f50 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1285,7 +1285,7 @@ enum #define MASA_RATIO_THRESHOLD 0.1f #define MASA_ANGLE_TOLERANCE 0.5f #define MASA_RATIO_THRESHOLD_FX 214748365 // 0.1 in Q31 -#define MASA_RATIO_TOLERANCE_FX 214748364/*0.1 Q30*/ +#define MASA_RATIO_TOLERANCE_FX 107374182 // 0.1 in Q30 #define MASA_ANGLE_TOLERANCE_FX ONE_IN_Q21 // 0.5 in Q22 #define MASA_LIMIT_NO_BANDS_SUR_COH 8 #define MINIMUM_BIT_BUDGET_NORMAL_META 100 diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 87b323d0a..e6f392ff0 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -25351,6 +25351,21 @@ const Word16 lsp_shb_prev_tbl_fx[LPC_SHB_ORDER] = { 13107, 14746 }; + +const Word16 lsp_shb_prev_tbl_swb_tbe_enc_fx[LPC_SHB_ORDER] = { + // Q15 + 32767, + 31165, + 26509, + 19262, + 10123, + 0, + -10124, + -19261, + -26509, + -31166, +}; + const Word16 ivas_lsp_shb_prev_tbl_fx[LPC_SHB_ORDER] = { /* Q15 */ 1489, diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 10bce5bb2..73156b989 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -1504,15 +1504,16 @@ extern const Word16 tab_hup_l_fx[]; // Q15 extern const Word16 mfreq_loc_Q2fx[]; // Q0 extern const Word16 mfreq_loc_div_25[]; // Q0 -extern const Word16 band_len_idx[]; // Q0 -extern const Word16 band_len_ener_shift[]; // Q0 -extern const Word16 fine_gain_pred_sqrt_bw[]; // Q11 -extern const Word16 ivas_band_len_idx[]; // Q0 -extern const Word16 ivas_band_len_ener_shift[]; // Q0 -extern const Word16 ivas_fine_gain_pred_sqrt_bw[]; // Q11 -extern const Word16 Mean_isf_wb[]; // Q2.56 -extern const Word16 lsp_shb_prev_tbl_fx[]; // Q15 -extern const Word16 ivas_lsp_shb_prev_tbl_fx[]; // Q15 +extern const Word16 band_len_idx[]; // Q0 +extern const Word16 band_len_ener_shift[]; // Q0 +extern const Word16 fine_gain_pred_sqrt_bw[]; // Q11 +extern const Word16 ivas_band_len_idx[]; // Q0 +extern const Word16 ivas_band_len_ener_shift[]; // Q0 +extern const Word16 ivas_fine_gain_pred_sqrt_bw[]; // Q11 +extern const Word16 Mean_isf_wb[]; // Q2.56 +extern const Word16 lsp_shb_prev_tbl_fx[]; // Q15 +extern const Word16 lsp_shb_prev_tbl_swb_tbe_enc_fx[]; // Q15 +extern const Word16 ivas_lsp_shb_prev_tbl_fx[]; // Q15 extern const Word16 tab_ari_qnew[4][4]; // enhancer.c diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 238478b1a..04b6ba187 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -930,7 +930,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( { L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); } - g0 = extract_h( L_shl_sat( L_g0, 14 ) ); + g0 = extract_h( L_shl( L_g0, 14 ) ); /* Scale signal i of 1/A(gamma1) */ IF( GT_16( g0, 1024 ) ) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index b65d41403..99e99bef7 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -1305,19 +1305,19 @@ void CNG_enc_ivas_fx( move16(); BREAK; case L_FRAME32k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME32k_Q31; move16(); BREAK; case L_FRAME16k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME16k_Q31; move16(); BREAK; case L_FRAME8k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME8k_Q31; move16(); BREAK; case L_FRAME4k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME4k_Q31; move16(); BREAK; default: diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index ba8ee5aa8..9b4f15dc5 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -21,7 +21,6 @@ #define ENVSHBRES_ACORR_MIN 40 /* minimum lag for calculating autocorrelation function on SHB residual TD envelope */ #define ENVSHBRES_ACORR_MAX 80 /* maximum lag for calculating autocorrelation function on SHB residual TD envelope */ - /*-----------------------------------------------------------------* * Local functions *-----------------------------------------------------------------*/ @@ -551,7 +550,7 @@ void InitSWBencBuffer_ivas_fx( FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_fx[i]; + hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_swb_tbe_enc_fx[i]; move16(); } @@ -3109,14 +3108,7 @@ void swb_tbe_enc_ivas_fx( } } - /* stab_check = a2lsp( lsf_shb, lpc_shb, LPC_SHB_ORDER ); - stab_check missing */ - /* LPC to LSP conversion */ - /* LPC: Q12, LSP: Q15 */ - E_LPC_a_lsp_conversion( lpc_shb_fx, lsp_shb_fx, hBWE_TD->prev_lsp_shb_fx, LPC_SHB_ORDER ); - - /* LSP to LSF conversion */ - /* LSP: Q15, LSF: Q15 */ - E_LPC_lsp_lsf_conversion( lsp_shb_fx, lsf_shb_fx, LPC_SHB_ORDER ); + /* stab_check = a2lsp( lsf_shb, lpc_shb, LPC_SHB_ORDER ); */ test(); test(); @@ -3124,8 +3116,8 @@ void swb_tbe_enc_ivas_fx( { FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - // hBWE_TD->prev_lsp_shb_fx[i] = i / 20.0f; - hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_fx[i]; + // hBWE_TD->prev_lsp_shb_fx[i] = i / 20.0f; // This value in float enc is lsf. + hBWE_TD->prev_lsp_shb_fx[i] = lsp_shb_prev_tbl_swb_tbe_enc_fx[i]; // lsf converted to lsp as fixed enc stores lsp. move16(); } } @@ -3135,6 +3127,14 @@ void swb_tbe_enc_ivas_fx( // mvr2r( hBWE_TD->prev_lsp_shb, lsf_shb, LPC_SHB_ORDER ); // } + /* LPC to LSP conversion */ + /* LPC: Q12, LSP: Q15 */ + E_LPC_a_lsp_conversion( lpc_shb_fx, lsp_shb_fx, hBWE_TD->prev_lsp_shb_fx, LPC_SHB_ORDER ); + + /* LSP to LSF conversion */ + /* LSP: Q15, LSF: Q15 */ + E_LPC_lsp_lsf_conversion( lsp_shb_fx, lsf_shb_fx, LPC_SHB_ORDER ); + Copy( lsp_shb_fx, hBWE_TD->prev_lsp_shb_fx, LPC_SHB_ORDER ); Copy( lsf_shb_fx, lsf_shb_orig_fx, LPC_SHB_ORDER ); -- GitLab From 516b2695912defd25c5952a507b7222e2c6af793 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Mar 2025 15:13:24 +0100 Subject: [PATCH 0578/1221] add COMPLEXITY/logs folder to artifacts --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91fbd0569..7a28b9871 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1748,6 +1748,7 @@ voip-be-on-merge-request: expire_in: 2 week paths: - $CI_JOB_NAME-public + - COMPLEXITY/logs complexity-stereo-in-stereo-out: extends: -- GitLab From ff1b7531fcd80872adf384296c6a2f639e5f70a3 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 20 Mar 2025 16:02:06 +0100 Subject: [PATCH 0579/1221] remove log folder b4 running COMPLEXITY check this should avoid archiving any old logs in case not all of them are overwritten (e.g. when new modes are added) --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7a28b9871..abd8e02ef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1741,6 +1741,8 @@ voip-be-on-merge-request: - *update-ltv-repo - *build-float-ref-and-dut-binaries - *complexity-measurements-setup + # delete previous jobs logfiles if present (-f flag ensures return calue of 0 even in first run where this folder is not present) + - rm -rf COMPLEXITY/logs - which coan artifacts: name: "$CI_JOB_NAME--$CI_COMMIT_REF_NAME--sha-$CI_COMMIT_SHA" -- GitLab From 1a5211b704558c3b8342995161d61068b4e681ce Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 20 Mar 2025 10:11:14 +0530 Subject: [PATCH 0580/1221] Fix for 3GPP issue 1409: Stereo Encoder: Differences in DTX for LTV 16 kHz signal Link #1409 --- lib_enc/cng_enc_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 99e99bef7..6c99a4306 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -1876,7 +1876,7 @@ void CNG_enc_ivas_fx( { E_LPC_f_lsp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M ); exp = sub( Q14, norm_s( Aq[0] ) ); - Scale_sig( Aq, M, sub( Q12, exp ) ); // Q12 + Scale_sig( Aq, M + 1, sub( Q12, exp ) ); // Q12 } tmp_loop = shr( st_fx->L_frame, 6 ); @@ -1986,19 +1986,19 @@ void CNG_enc_ivas_fx( move16(); BREAK; case L_FRAME32k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME32k_Q31; move16(); BREAK; case L_FRAME16k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME16k_Q31; move16(); BREAK; case L_FRAME8k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME8k_Q31; move16(); BREAK; case L_FRAME4k: - inv_frame_len = ONE_BY_L_FRAME48k_Q31; + inv_frame_len = ONE_BY_L_FRAME4k_Q31; move16(); BREAK; default: -- GitLab From 05c15d809f7b0d956df12413d1c5f2c9ee35fa7e Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 15:53:43 +0100 Subject: [PATCH 0581/1221] Fix for stereo DMX / PHA mode : Change the resolution and improve the precision of several variables. --- lib_com/options.h | 3 - lib_enc/ivas_stat_enc.h | 9 +- lib_enc/ivas_stereo_dmx_evs_fx.c | 195 ++++++++++++++++++++++++++----- 3 files changed, 175 insertions(+), 32 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 5be5d8a48..dab0c796c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -175,7 +175,4 @@ #define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ #define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ #define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ -#define NONBE_FIX_1402_WAVEADJUST /* VA: BASOP iisue 1402: fix waveform adjustment decoder PLC */ -#define FIX_ISSUE_1376 /* VA: Fix for issue 1376 (issue with GSC excitation) */ -#define OPT_SBA_AVOID_SPAR_RESCALE /* Optimization made to spar decoder and IGF */ #endif diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 918acc417..c817a0825 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1183,7 +1183,11 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word32 isd_rate_s_fx; // Q31 +#else Word16 isd_rate_s_fx; // Q15 +#endif Word32 iccr_s_fx; // Q31 Word32 ipd_ff_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word32 Pr_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 @@ -1224,8 +1228,11 @@ typedef struct stereo_dmx_evs_enc_data_structure STEREO_DMX_EVS_POC_HANDLE hPOC; STEREO_DMX_EVS_PHA_HANDLE hPHA; - +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd_fx; // Q0 +#else Word32 itd_fx; // Q16 +#endif Word32 pre_dmx_energy_fx[1]; Word16 pre_dmx_energy_fx_e[1]; diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index ae8a8203e..bfb703c94 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -65,12 +65,20 @@ #define Q_BAND_FX 536870912 /*Q31*/ -#define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 +#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#define STEREO_DMX_EVS_ISD_FORGETTING_Q31 2040109465 +#define STEREO_DMX_EVS_ISD_1MFORGETTING_Q15 1638 +#define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 773094113 +#define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 923417968 +#define STEREO_DMX_EVS_ISD_INVTHRES_H 1270700383 +#else +#define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 11796 #define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 14090 +#endif #define STEREO_DMX_EVS_ICCR_FORGETTING_Q31 1503238554 #define STEREO_DMX_EVS_ICCR_HYST_L_Q31 1610612736 @@ -153,8 +161,12 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word32 itd[], /* o : estimated itd Q16 */ - const Word16 input_frame /* i : input frame length per channel */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd[], /* o : estimated itd Q0 */ +#else + Word32 itd[], /* o : estimated itd Q16 */ +#endif + const Word16 input_frame /* i : input frame length per channel */ ); static void adapt_gain_fx( const Word32 src_fx[], /* i : input signal Q16 */ @@ -196,9 +208,13 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word32 itd_fx[], /* o : estimated itd */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd_fx[], /* o : estimated itd */ +#else + Word32 itd_fx[], /* o : estimated itd */ +#endif + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio */ ); /*-------------------------------------------------------------------* * estimate_itd_wnd_fft() @@ -604,12 +620,21 @@ static void calc_poc_fx( Ni = L_sub( specLi[i], specRi[i] ); // spec_e Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e - // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) + // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), STEREO_DMX_EVS_ISD_INVTHRES_H ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) +#else IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) +#endif { isd_cnt_h = add( isd_cnt_h, 1 ); } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + W_tmp = W_add( W_mult0_32_32( Mpy_32_32_r( Dr, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Dr ), W_mult0_32_32( Mpy_32_32_r( Di, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Di ) ); // Q62 + IF( LT_64( W_add( W_mult0_32_32( Nr, Nr ), W_mult0_32_32( Ni, Ni ) ), W_tmp ) ) // Q62 +#else IF( LT_32( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), Mpy_32_32_r( STEREO_DMX_EVS_ISD_THRES_L_Q31, L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) ) +#endif { isd_cnt_l = add( isd_cnt_l, 1 ); } @@ -618,10 +643,19 @@ static void calc_poc_fx( isd_rate = BASOP_Util_Divide1616_Scale( isd_cnt_h, freq_8k, &isd_rate_e ); // Saturation to handle values close to 1.0f isd_rate = shl_sat( isd_rate, isd_rate_e ); // Q15 +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + hPHA->isd_rate_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ISD_FORGETTING_Q31, hPHA->isd_rate_s_fx ), L_mult( STEREO_DMX_EVS_ISD_1MFORGETTING_Q15, isd_rate ) ); + move32(); +#else hPHA->isd_rate_s_fx = add( mult_r( STEREO_DMX_EVS_ISD_FORGETTING_Q15, hPHA->isd_rate_s_fx ), mult_r( MAX_16 - STEREO_DMX_EVS_ISD_FORGETTING_Q15, isd_rate ) ); move16(); +#endif +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + IF( GT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 ) ) +#else IF( GT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 ) ) +#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD ) ) { @@ -646,7 +680,11 @@ static void calc_poc_fx( hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; move32(); } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + ELSE IF( LT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 ) ) +#else ELSE IF( LT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 ) ) +#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD2 ) ) { @@ -711,11 +749,36 @@ static void calc_poc_fx( FOR( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; ( j++, i++ ) ) { + /* Energy */ + +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + + // Left + W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); // Q(62-(2*specL_e)) -> Q(63 - ((2*specL_e) +1)) + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); // Q(63 - ((2*spec_e) - (L_tmp_e - 1)) + } + tEl[n] = BASOP_Util_Add_Mant32Exp( tEl[n], tEl_e[n], W_round64_L( W_tmp ), sub( shl( spec_e, 1 ), sub( L_tmp_e, 1 ) ), &tEl_e[n] ); + move32(); + + // Right + W_tmp = W_add( W_mult0_32_32( specRr[i], specRr[i] ), W_mult0_32_32( specRi[i], specRi[i] ) ); // Q(62-(2*specR_e)) -> Q(63 - ((2*specR_e) +1)) + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); // Q(63 - ((2*spec_e) - (L_tmp_e - 1)) + } + tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], W_round64_L( W_tmp ), sub( shl( spec_e, 1 ), sub( L_tmp_e, 1 ) ), &tEr_e[n] ); + move32(); +#else tEl[n] = BASOP_Util_Add_Mant32Exp( tEl[n], tEl_e[n], L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &tEl_e[n] ); move32(); tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &tEr_e[n] ); move32(); +#endif /* IPD */ // IPDr = L_add(Mpy_32_32_r(specLr[i], specRr[i]), Mpy_32_32_r(specLi[i], specRi[i])); //2*spec_e @@ -746,11 +809,35 @@ static void calc_poc_fx( tIPDr = L_sub( Mpy_32_32_r( specRr[i], IPDr ), Mpy_32_32_r( specRi[i], IPDi ) ); // spec_e tIPDi = L_add( Mpy_32_32_r( specRr[i], IPDi ), Mpy_32_32_r( specRi[i], IPDr ) ); // spec_e +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + + Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), 0, &Nr_e ); + Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), 0, &Ni_e ); + + // eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), 0, &eneL_e ); + W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); + } + eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, W_round64_L( W_tmp ), sub( 1, L_tmp_e ), &eneL_e ); + + // eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), 0, &eneR_e ); + W_tmp = W_add( W_mult0_32_32( specRr[i], specRr[i] ), W_mult0_32_32( specRi[i], specRi[i] ) ); + L_tmp_e = W_norm( W_tmp ); + IF( L_tmp_e != 0 ) + { + W_tmp = W_shl( W_tmp, L_tmp_e ); + } + eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, W_round64_L( W_tmp ), sub( 1, L_tmp_e ), &eneR_e ); +#else Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), shl( spec_e, 1 ), &Nr_e ); Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), shl( spec_e, 1 ), &Ni_e ); eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &eneL_e ); eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &eneR_e ); +#endif } // Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON ); @@ -768,7 +855,13 @@ static void calc_poc_fx( move32(); Pi[n] = L_add( Mpy_32_32_r( ipd_ff[n], Pi[n] ), Mpy_32_32_r( L_sub( MAX_32, ipd_ff[n] ), tPi ) ); move32(); + // Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Pn = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); + Pn = BASOP_Util_Add_Mant32Exp( Pn, 1, EPSILON_FX_M, EPSILON_FX_E, &Pn_e ); + Pn = Isqrt_lc( Pn, &Pn_e ); +#else L_tmp = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); L_tmp_e = 1; move16(); @@ -776,6 +869,8 @@ static void calc_poc_fx( Pn_e = L_tmp_e; move16(); Pn = ISqrt32( L_tmp, &Pn_e ); +#endif + Pr[n] = L_shl_sat( Mpy_32_32_r( Pr[n], Pn ), Pn_e ); // Q31 move32(); Pi[n] = L_shl_sat( Mpy_32_32_r( Pi[n], Pn ), Pn_e ); // Q31 @@ -984,7 +1079,13 @@ static void calc_poc_fx( #ifdef FIX_ISSUE_1153 hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 #else + +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 +#else hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 +#endif + #endif move32(); } @@ -1015,7 +1116,11 @@ static void calc_poc_fx( energy = ISqrt32( energy, &energy_e ); FOR( i = 0; i < hPHA->pha_len; i++ ) { +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), sub( energy_e, 1 ) ); // Q30 +#else hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), energy_e ); // Q31 +#endif move32(); } } @@ -1118,9 +1223,13 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word32 itd_fx[], /* o : estimated itd Q16 */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio Q31 */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd_fx[], /* o : estimated itd Q0 */ +#else + Word32 itd_fx[], /* o : estimated itd Q16 */ +#endif + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) { Word16 itd_cand[CPE_CHANNELS], i, n, cnt[CPE_CHANNELS], Lh, peak_range, *on, *itdLR, prev_off[CPE_CHANNELS], eps_fx; @@ -1430,8 +1539,12 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word32 itd[], /* o : estimated itd Q16 */ - const Word16 input_frame /* i : input frame length per channel */ +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 itd[], /* o : estimated itd Q0 */ +#else + Word32 itd[], /* o : estimated itd Q16 */ +#endif + const Word16 input_frame /* i : input frame length per channel */ ) { Word32 specLr[L_FRAME48k / 2 + 1], specLi[L_FRAME48k / 2 + 1], specRr[L_FRAME48k / 2 + 1], specRi[L_FRAME48k / 2 + 1]; @@ -1938,9 +2051,9 @@ void stereo_dmx_evs_enc_fx( hStereoDmxEVS->dmx_weight_fx, hStereoDmxEVS->pre_dmx_energy_fx, hStereoDmxEVS->pre_dmx_energy_fx_e, hStereoDmxEVS->aux_dmx_energy_fx, hStereoDmxEVS->aux_dmx_energy_fx_e ); // Downscaling signals to avoid accumulation overflows - scale_sig32( data_fx[0], input_frame, -5 ); // Q16->Q11 - scale_sig32( data_fx[1], input_frame, -5 ); // Q16->Q11 - scale_sig32( dmx_poc_data, input_frame, -5 ); // Q16->Q11 + scale_sig32( data_fx[0], input_frame, -5 ); // Q31->Q26 + scale_sig32( data_fx[1], input_frame, -5 ); // Q31->Q26 + scale_sig32( dmx_poc_data, input_frame, -5 ); // Q31->Q26 /* pha */ @@ -1969,9 +2082,11 @@ void stereo_dmx_evs_enc_fx( FOR( ( fx_tmp = 0, m = 0 ); m < pha_len; m++ ) { // ftmp += p_data_mem[n - m] * p_prev_taps[m]; - // fx_tmp = BASOP_Util_Add_Mant32Exp(fx_tmp, fx_tmp_e, Mpy_32_32(p_data_mem[n - m], p_prev_taps[m]),15,&fx_tmp_e); - fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q11 + fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q25 } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + fx_tmp = L_shl( fx_tmp, 1 ); // Q26 +#endif mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); move32(); } @@ -1981,7 +2096,7 @@ void stereo_dmx_evs_enc_fx( FOR( n = 0; n < fad_len; n++ ) { // mem_prev[n] += p_data[n] * INV_SQRT_2; - mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q11 + mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q26 move32(); } } @@ -1994,10 +2109,13 @@ void stereo_dmx_evs_enc_fx( FOR( ( fx_tmp = 0, m = 0 ); m < pha_len; m++ ) { // ftmp += p_data_mem[n - m] * p_curr_taps[m]; - fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q11 + fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q25 } +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + fx_tmp = L_shl( fx_tmp, 1 ); // Q26 +#endif // dmx_pha_data[n] += ftmp * INV_SQRT_2; - dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); // Q11 + dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); // Q26 move32(); } } @@ -2006,7 +2124,7 @@ void stereo_dmx_evs_enc_fx( FOR( n = 0; n < n_samples; n++ ) { // dmx_pha_data[n] += p_data[n] * INV_SQRT_2; - dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q11 + dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( p_data[n], INV_SQRT_2_Q31 ) ); // Q26 move32(); } } @@ -2016,7 +2134,7 @@ void stereo_dmx_evs_enc_fx( { dmx_pha_data[n] = Mpy_32_32( dmx_pha_data[n], fad_g[n] ); move32(); - dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( mem_prev[n], fad_g[m] ) ); // Q11 + dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( mem_prev[n], fad_g[m] ) ); // Q26 move32(); } @@ -2025,7 +2143,11 @@ void stereo_dmx_evs_enc_fx( curr_prc = hStereoDmxEVS->hPHA->curr_prc; move32(); // if ( abs( (int16_t) hStereoDmxEVS->itd ) > hStereoDmxEVS->hPHA->prc_thres ) +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + IF( GT_16( abs_s( hStereoDmxEVS->itd_fx ), hStereoDmxEVS->hPHA->prc_thres ) ) +#else IF( GT_16( abs_s( round_fx( hStereoDmxEVS->itd_fx ) ), hStereoDmxEVS->hPHA->prc_thres ) ) +#endif { IF( NE_32( hStereoDmxEVS->hPHA->curr_prc, STEREO_DMX_EVS_PRC_POC ) ) { @@ -2102,9 +2224,9 @@ void stereo_dmx_evs_enc_fx( FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len; ( n++, m-- ) ) { - p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q11 + p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q26 move32(); - p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_pha_data[n] ) ); // Q11 + p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_pha_data[n] ) ); // Q26 move32(); } } @@ -2121,16 +2243,15 @@ void stereo_dmx_evs_enc_fx( FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len; ( n++, m-- ) ) { - p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q11 + p_dmx_data[n] = Mpy_32_32( p_dmx_data[n], fad_g[n] ); // Q26 move32(); - p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_poc_data[n] ) ); // Q11 + p_dmx_data[n] = L_add( p_dmx_data[n], Mpy_32_32( fad_g[m], dmx_poc_data[n] ) ); // Q26 move32(); } } } - Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); // Q11->Q0 - + Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); // Q26->Q15 return; } @@ -2383,6 +2504,23 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_len = hStereoDmxEVS->hPHA->fad_len; move16(); +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q14*/, pha_len ); + hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; + move16(); + IF( EQ_32( input_Fs, 16000 ) ) + { + hStereoDmxEVS->hPHA->win_fx[pha_len - 1] = 7373; /*0.45f in Q14*/ + move16(); + } + ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) + { + hStereoDmxEVS->hPHA->win_fx[sub( pha_len, 2 )] = 19302; /*1.1781f in Q14*/ + move16(); + hStereoDmxEVS->hPHA->win_fx[sub( pha_len, 1 )] = 2816; /*0.1718f in Q14*/ + move16(); + } +#else trans_len = idiv1616( pha_len, 20 ); set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q15*/, sub( pha_len, trans_len ) ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; @@ -2396,6 +2534,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( win[n] = mult_r( add( ONE_IN_Q14, getCosWord16R2( imult1616( add( n, 1 ), tmp_r ) ) ), 29491 /*1.8/2 in Q15*/ ); move16(); } +#endif fad_g = hStereoDmxEVS->hPHA->fad_g_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); -- GitLab From 52335369cfb04ff88a64b903228b5689c4bfb786 Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 16:48:53 +0100 Subject: [PATCH 0582/1221] clang-format correction. --- lib_enc/ivas_stat_enc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index c817a0825..19f9a436e 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1184,7 +1184,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure Word16 init_frmCntr; #ifdef FIX_1386_STEREO_DMX_EVS_PHA - Word32 isd_rate_s_fx; // Q31 + Word32 isd_rate_s_fx; // Q31 #else Word16 isd_rate_s_fx; // Q15 #endif @@ -1231,7 +1231,7 @@ typedef struct stereo_dmx_evs_enc_data_structure #ifdef FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx; // Q0 #else - Word32 itd_fx; // Q16 + Word32 itd_fx; // Q16 #endif Word32 pre_dmx_energy_fx[1]; -- GitLab From 7d123bed506e5e0330996c61b3ac5e9e2ff487ce Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 16:58:01 +0100 Subject: [PATCH 0583/1221] Useless variable removed. --- lib_enc/ivas_stereo_dmx_evs_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index bfb703c94..e6b6b338f 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2272,7 +2272,11 @@ ivas_error stereo_dmx_evs_init_encoder_fx( Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; +#ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 *win; +#else Word16 *win, tmp_r; +#endif const Word16 *p_ipd_w; Word16 tmp_e; -- GitLab From 817f786fe481d93cbac99aee4c36b119c30edd8e Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Wed, 12 Mar 2025 17:23:12 +0100 Subject: [PATCH 0584/1221] Useless variable removed. --- lib_enc/ivas_stereo_dmx_evs_fx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index e6b6b338f..690e0b35e 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2270,11 +2270,13 @@ ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS; Word16 n, input_frame; - Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; - Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; #ifdef FIX_1386_STEREO_DMX_EVS_PHA + Word16 m, len, pha_len, fad_len, fad_len2, rfft_ipd_coef_step, n0, input_frame_pha; + Word32 *fad_g, fad_r, *ipd_ff; Word16 *win; #else + Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; + Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; Word16 *win, tmp_r; #endif const Word16 *p_ipd_w; -- GitLab From 1394fcfe99910683e2983fc50f71aec0e53343a7 Mon Sep 17 00:00:00 2001 From: Arnaud Lefort Date: Tue, 18 Mar 2025 15:30:28 +0100 Subject: [PATCH 0585/1221] Switch cleaned for fix 1386. --- lib_enc/ivas_stat_enc.h | 4 +-- lib_enc/ivas_stereo_dmx_evs_fx.c | 50 ++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 19f9a436e..ef278d188 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1183,7 +1183,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word32 isd_rate_s_fx; // Q31 #else Word16 isd_rate_s_fx; // Q15 @@ -1228,7 +1228,7 @@ typedef struct stereo_dmx_evs_enc_data_structure STEREO_DMX_EVS_POC_HANDLE hPOC; STEREO_DMX_EVS_PHA_HANDLE hPHA; -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx; // Q0 #else Word32 itd_fx; // Q16 diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 690e0b35e..933270c33 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -68,7 +68,7 @@ #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA #define STEREO_DMX_EVS_ISD_FORGETTING_Q31 2040109465 #define STEREO_DMX_EVS_ISD_1MFORGETTING_Q15 1638 #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 773094113 @@ -161,7 +161,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ #else Word32 itd[], /* o : estimated itd Q16 */ @@ -208,7 +208,7 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd */ #else Word32 itd_fx[], /* o : estimated itd */ @@ -621,7 +621,7 @@ static void calc_poc_fx( Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), STEREO_DMX_EVS_ISD_INVTHRES_H ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) #else IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) @@ -629,7 +629,7 @@ static void calc_poc_fx( { isd_cnt_h = add( isd_cnt_h, 1 ); } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA W_tmp = W_add( W_mult0_32_32( Mpy_32_32_r( Dr, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Dr ), W_mult0_32_32( Mpy_32_32_r( Di, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Di ) ); // Q62 IF( LT_64( W_add( W_mult0_32_32( Nr, Nr ), W_mult0_32_32( Ni, Ni ) ), W_tmp ) ) // Q62 #else @@ -643,7 +643,7 @@ static void calc_poc_fx( isd_rate = BASOP_Util_Divide1616_Scale( isd_cnt_h, freq_8k, &isd_rate_e ); // Saturation to handle values close to 1.0f isd_rate = shl_sat( isd_rate, isd_rate_e ); // Q15 -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->isd_rate_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ISD_FORGETTING_Q31, hPHA->isd_rate_s_fx ), L_mult( STEREO_DMX_EVS_ISD_1MFORGETTING_Q15, isd_rate ) ); move32(); #else @@ -651,7 +651,7 @@ static void calc_poc_fx( move16(); #endif -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 ) ) #else IF( GT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 ) ) @@ -680,7 +680,7 @@ static void calc_poc_fx( hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; move32(); } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA ELSE IF( LT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 ) ) #else ELSE IF( LT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 ) ) @@ -752,7 +752,7 @@ static void calc_poc_fx( /* Energy */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA // Left W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); // Q(62-(2*specL_e)) -> Q(63 - ((2*specL_e) +1)) @@ -809,7 +809,7 @@ static void calc_poc_fx( tIPDr = L_sub( Mpy_32_32_r( specRr[i], IPDr ), Mpy_32_32_r( specRi[i], IPDi ) ); // spec_e tIPDi = L_add( Mpy_32_32_r( specRr[i], IPDi ), Mpy_32_32_r( specRi[i], IPDr ) ); // spec_e -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), 0, &Nr_e ); Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), 0, &Ni_e ); @@ -857,7 +857,7 @@ static void calc_poc_fx( move32(); // Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Pn = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); Pn = BASOP_Util_Add_Mant32Exp( Pn, 1, EPSILON_FX_M, EPSILON_FX_E, &Pn_e ); Pn = Isqrt_lc( Pn, &Pn_e ); @@ -1076,17 +1076,17 @@ static void calc_poc_fx( FOR( i = 0; i < hPHA->pha_len; i++ ) { // hPHA->p_curr_taps[n][i] *= hPHA->win[i]; -#ifdef FIX_ISSUE_1153 +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 #else -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef FIX_ISSUE_1153 hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 #else hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 #endif -#endif +#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA move32(); } @@ -1094,6 +1094,7 @@ static void calc_poc_fx( move32(); energy_e = 0; move16(); +#ifndef NONBE_FIX_1386_STEREO_DMX_EVS_PHA #ifdef FIX_ISSUE_1153 Word16 shift = L_norm_arr( hPHA->p_curr_taps_fx[n], hPHA->pha_len ); IF( shift ) @@ -1103,20 +1104,25 @@ static void calc_poc_fx( move16(); } #endif +#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA FOR( i = 0; i < hPHA->pha_len; i++ ) { +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA + energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); +#else #ifdef FIX_ISSUE_1153 energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), shl( sub( 1, shift ), 1 ), &energy_e ); #else energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); #endif +#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA } // energy = (float) inv_sqrt( energy + EPSILON ); energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, EPSILON_FX_M, EPSILON_FX_E, &energy_e ); energy = ISqrt32( energy, &energy_e ); FOR( i = 0; i < hPHA->pha_len; i++ ) { -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), sub( energy_e, 1 ) ); // Q30 #else hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), energy_e ); // Q31 @@ -1223,7 +1229,7 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd Q0 */ #else Word32 itd_fx[], /* o : estimated itd Q16 */ @@ -1539,7 +1545,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ #else Word32 itd[], /* o : estimated itd Q16 */ @@ -2084,7 +2090,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_prev_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q25 } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 #endif mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); @@ -2111,7 +2117,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_curr_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q25 } -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 #endif // dmx_pha_data[n] += ftmp * INV_SQRT_2; @@ -2143,7 +2149,7 @@ void stereo_dmx_evs_enc_fx( curr_prc = hStereoDmxEVS->hPHA->curr_prc; move32(); // if ( abs( (int16_t) hStereoDmxEVS->itd ) > hStereoDmxEVS->hPHA->prc_thres ) -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_16( abs_s( hStereoDmxEVS->itd_fx ), hStereoDmxEVS->hPHA->prc_thres ) ) #else IF( GT_16( abs_s( round_fx( hStereoDmxEVS->itd_fx ) ), hStereoDmxEVS->hPHA->prc_thres ) ) @@ -2270,7 +2276,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS; Word16 n, input_frame; -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 m, len, pha_len, fad_len, fad_len2, rfft_ipd_coef_step, n0, input_frame_pha; Word32 *fad_g, fad_r, *ipd_ff; Word16 *win; @@ -2510,7 +2516,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_len = hStereoDmxEVS->hPHA->fad_len; move16(); -#ifdef FIX_1386_STEREO_DMX_EVS_PHA +#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q14*/, pha_len ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; move16(); -- GitLab From f8db9100fcea5b92a5b5f5ee79ccb7fabdac6789 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 27 Feb 2025 10:39:39 +0100 Subject: [PATCH 0586/1221] - added some wmops push/pop, - added FIX_xxxx_SPEEDUP_00: not implemented, no bitstream - added FIX_xxxx_SPEEDUP_01: not implemented yet --- lib_com/basop_util.c | 6 +- lib_dec/ivas_jbm_dec_fx.c | 2 +- .../ivas_dirac_dec_binaural_functions_fx.c | 72 +++++++++++++++++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index b7ee35ab3..fa8d097df 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1010,6 +1010,7 @@ Word32 div_w( Word32 L_num, Word32 L_den ) } } + Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { Word32 z; @@ -1017,6 +1018,8 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word16 sy; Word32 sign; + //push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); + /* assert (x >= (Word32)0); */ assert( y != (Word32) 0 ); @@ -1038,6 +1041,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) IF( x == (Word32) 0 ) { *s = 0; + //pop_wmops(); return ( (Word32) 0 ); } @@ -1058,7 +1062,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { z = L_negate( z ); } - + //pop_wmops(); return z; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 1918ce3f3..ce60c0d65 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1875,7 +1875,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - push_wmops( "ivas_dec_render" ); + push_wmops( "ivas_dec_render (IDR)" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index b5dd1f8b9..8153775b7 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,6 +45,9 @@ #include "wmc_auto.h" +//#define FIX_xxxx_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream +//#define FIX_xxxx_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui + Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -504,8 +507,9 @@ void ivas_dirac_dec_binaural_render_fx( FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); + push_wmops( "IDR binaural internal (IDRBI)" ); ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx ); - + pop_wmops();/*push_wmops( "IDR binaural internal (IDRBI)" );*/ FOR( ch = 0; ch < nchan_out; ch++ ) { output_fx_local[ch] += n_samples_sf; @@ -708,6 +712,7 @@ static void ivas_dirac_dec_binaural_internal_fx( } } /* CLDFB Analysis of input */ + push_wmops( "IDRBI CLDFB ANALYSYS" ); FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { FOR( ch = 0; ch < numInChannels; ch++ ) @@ -857,6 +862,7 @@ static void ivas_dirac_dec_binaural_internal_fx( } } } + pop_wmops(); /*push_wmops( "IDRBI CLDFB ANALYSYS" );*/ test(); IF( EQ_32( config_data.ivas_format, SBA_FORMAT ) || EQ_32( config_data.ivas_format, SBA_ISM_FORMAT ) ) @@ -921,7 +927,9 @@ static void ivas_dirac_dec_binaural_internal_fx( } test(); + push_wmops( "IDRBI cov matrices" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); + pop_wmops();/*push_wmops( "IDRBI cov matrices" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -959,7 +967,9 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); } + push_wmops( "IDRBI proc matrices (IRDBI pm)" ); ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); + pop_wmops(); /*push_wmops( "IDRBI proc matrices (IRDBI pm)" );*/ q_inp = Q6; move16(); @@ -1005,8 +1015,10 @@ static void ivas_dirac_dec_binaural_internal_fx( hDiracDecBin->q_processMtxDecPrev = q_mat; move16(); + push_wmops( "IDRBI processOutput" ); ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); - + pop_wmops(); /*push_wmops( "IDRBI processOutput" ); + */ hDiracDecBin->hDiffuseDist = NULL; hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); @@ -1843,6 +1855,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); } + push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" ); FOR( bin = 0; bin < nBins; bin++ ) { Word32 tmpMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], gain_fx; @@ -1866,6 +1879,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_CrEne = Q31; move16(); + push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" ); IF( GT_16( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ) { hDiracDecBin->ChEne_fx[1][bin] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ); @@ -1935,7 +1949,9 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->q_ChCrossOut, prototypeMtx_fx, Mre_fx, Mim_fx, &q_M, hDiracDecBin->reqularizationFactor_fx ); + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" );*/ + push_wmops( "IDRBI pm LOOP1 sec B" ); IF( LT_16( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ) { CxRe_fx[0][0] = hDiracDecBin->ChEne_fx[0][bin]; @@ -1989,9 +2005,13 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( #endif resultMtxRe_fx, resultMtxIm_fx, &q_res ); + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec B" );*/ + /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */ + + push_wmops( "IDRBI pm LOOP1 sec C" ); IF( LT_16( bin, max_band_decorr ) ) { Word32 decorrelationReductionFactor_fx; @@ -2107,7 +2127,9 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_Mdec = Q31; move16(); } + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec C" );*/ + push_wmops( "IDRBI pm LOOP1 sec D" ); /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */ tmp1 = L_add( CrEneL_fx, CrEneR_fx ); exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); @@ -2198,6 +2220,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_processMtxDec_bin = q_processMtxDec[bin]; move16(); move16(); + /* Store processing matrices */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -2232,7 +2255,10 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); q_processMtxDec[bin] = sub( q_Mdec, 16 ); move16(); + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec D" );*/ + + push_wmops( "IDRBI pm LOOP1 sec E" ); IF( separateCenterChannelRendering ) { /* The rendering of the separate center channel in masa + mono mode. @@ -2322,7 +2348,10 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } + pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec E" );*/ } + pop_wmops(); /*push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" );*/ + /* Aligning Q-factors of all bins in the processing matrices to a common Q-factor */ minimum_s( q_processMtx, nBins, &hDiracDecBin->q_processMtx ); minimum_s( q_processMtxPrev, nBins, &hDiracDecBin->q_processMtxPrev ); @@ -2342,6 +2371,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( minimum_s( q_processMtxDec, nBins, &hDiracDecBin->q_processMtxDec ); minimum_s( q_processMtxDecPrev, nBins, &hDiracDecBin->q_processMtxDecPrev ); + push_wmops( "IRDBI pm LOOP2" ); FOR( bin = 0; bin < nBins; bin++ ) { FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -2381,6 +2411,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } + pop_wmops(); /*push_wmops( "IRDBI pm LOOP2" );*/ return; } @@ -4354,7 +4385,9 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + push_wmops( "formulate2x2MixingMatrix Division" ); maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4377,9 +4410,12 @@ static void formulate2x2MixingMatrix_fx( Cout_im = Mpy_32_32( Cout_im, maxEneDiv_fx ); q_cout = sub( add( q_cout, q_maxEneDiv ), 31 ); + push_wmops( "formulate2x2MixingMatrix cholesky" ); /* Cholesky decomposition of target / output covariance matrix */ chol2x2_fx( E_out1, E_out2, q_eout, Cout_re, Cout_im, q_cout, KyRe_fx, KyIm_fx, &q_ky ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix cholesky" );*/ + push_wmops( "formulate2x2MixingMatrix Eigendecomp" ); /* Eigendecomposition of input covariance matrix */ eig2x2_fx( E_in1, E_in2, q_ein, Cin_re, Cin_im, q_cin, Uxre_fx, Uxim_fx, &q_Ux, Sx_fx, &q_Sx ); @@ -4397,7 +4433,9 @@ static void formulate2x2MixingMatrix_fx( move32(); matrixDiagMul_fx( Uxre_fx, Uxim_fx, q_Ux, Sx_fx, q_Sx, Kxre_fx, Kxim_fx, &q_Kx ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Eigendecomp" );*/ + push_wmops( "formulate2x2MixingMatrix RegSMInv" ); /* Regularize the diagonal Sx for matrix inversion */ Sx_fx[0] = L_max( L_shr( Sx_fx[0], 1 ), Mpy_32_16_1( Sx_fx[1], regularizationFactor_fx ) ); Sx_fx[1] = L_max( L_shr( Sx_fx[1], 1 ), L_shl( Mpy_32_16_1( Sx_fx[0], regularizationFactor_fx ), 1 ) ); @@ -4432,8 +4470,9 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp @@ -4469,8 +4508,9 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4487,7 +4527,9 @@ static void formulate2x2MixingMatrix_fx( move32(); Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); + pop_wmops(); + push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" ); /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -4513,17 +4555,29 @@ static void formulate2x2MixingMatrix_fx( move32(); } } + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ q_temp = sub( add( q_ky, q_GhatQ ), 31 ); + push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" ); /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ + push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ + push_wmops( "oPtoA MT1M" ); +#ifdef FIX_xxxx_SPEEDUP_01 + matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); + + eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#endif + pop_wmops();/*push_wmops( "oPtoA MT1M" );*/ IF( D_fx[0] == 0 ) { @@ -4537,8 +4591,10 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); exp = sub( exp, sub( Q30, q_D ) ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); @@ -4555,7 +4611,9 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4657,7 +4715,9 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ + push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ #if ( BINAURAL_CHANNELS != 2 ) FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -4740,7 +4800,9 @@ static void formulate2x2MixingMatrix_fx( { Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); + pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); @@ -4811,6 +4873,8 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Mre_fx, Mim_fx, q_M ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" );*/ + return; } -- GitLab From 1ab4b454e41d0ab88e1189d667c1a3f38943ccf3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 27 Feb 2025 10:41:26 +0100 Subject: [PATCH 0587/1221] change names of macros from xxxx to 1326 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 8153775b7..716b16262 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,8 +45,8 @@ #include "wmc_auto.h" -//#define FIX_xxxx_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -//#define FIX_xxxx_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui +//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream +//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -4568,7 +4568,7 @@ static void formulate2x2MixingMatrix_fx( /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ push_wmops( "oPtoA MT1M" ); -#ifdef FIX_xxxx_SPEEDUP_01 +#ifdef FIX_1326_SPEEDUP_01 matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -- GitLab From f35583b7b5e0cbad554dcd9ee197307a3b158791 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 27 Feb 2025 16:56:36 +0100 Subject: [PATCH 0588/1221] added and activated FIX_1326_SPEEDUP_00 - 07 --- .../ivas_dirac_dec_binaural_functions_fx.c | 190 +++++++++++++++++- 1 file changed, 182 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 716b16262..d1fb6c23c 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,8 +46,13 @@ #include "wmc_auto.h" //#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : rollout loop in mul, only 3 out of 4 results are needed - maybe a=b can also benefitcui - +#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS +#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS +#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS +#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS +#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -3280,6 +3285,19 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) +#ifdef FIX_1326_SPEEDUP_02 + IF ( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) + { + Ure_fx[0][0] = ONE_IN_Q31; + move32(); + Ure_fx[1][1] = ONE_IN_Q31; + move32(); + *q_U = Q31; + move16(); + + return; + } +#else IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( D_fx[0], *q_D, EPSILON_MANT, EPSILON_EXP ), -1 ) ) { Ure_fx[0][0] = ONE_IN_Q31; @@ -3291,8 +3309,24 @@ static void eig2x2_fx( return; } +#endif /* Numeric case, when input is near an identity matrix with a gain */ +#ifdef FIX_1326_SPEEDUP_03 //178.932 + tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 + + IF( LT_32( pm_fx, L_shl_sat(tmp1, sub(q_tmp1,q_tmp2) ) ) ) + { + Ure_fx[0][0] = ONE_IN_Q30; + move32(); + Ure_fx[1][1] = ONE_IN_Q30; + move32(); + *q_U = Q30; + move16(); + + return; + } +#else tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_16( q_tmp1, q_tmp2 ) ) @@ -3323,6 +3357,7 @@ static void eig2x2_fx( return; } } +#endif q_U_1 = 0; q_U_2 = 0; @@ -3431,10 +3466,22 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); + +#ifdef FIX_1326_SPEEDUP_04 + Word16 exp_tmp2; + Word32 eps_tmp; + + tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &exp_tmp2 ); + eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, exp_tmp2 ) ); + + tmp3 = L_add( L_shr ( tmp2,1), L_shr(eps_tmp,1) ); // Add Epsilon if relevant + + exp_tmp3 = add(exp_tmp2 , 1); +#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); - tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); +#endif #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); @@ -4387,7 +4434,7 @@ static void formulate2x2MixingMatrix_fx( { push_wmops( "formulate2x2MixingMatrix Division" ); maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4468,6 +4515,28 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE +#ifdef FIX_1326_SPEEDUP_05 + { + Word16 shift = norm_l( temp ); + temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); + exp_temp = sub( 31, q_ein ); + if ( temp == 0 ) + { + exp_temp = EPSILON_EXP; + move32(); + } + if (temp == 0) + { + temp = EPSILON_MANT; + move32(); + } + temp = ISqrt32( temp , &exp_temp); + shift = sub( 31, q_eout ); + Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); + move32(); + exp = add( shift, exp_temp ); + } +#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); @@ -4478,6 +4547,7 @@ static void formulate2x2MixingMatrix_fx( Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif } +#endif #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif @@ -4506,16 +4576,36 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE +#ifdef FIX_1326_SPEEDUP_06 + { + Word16 shift = norm_l( temp ); + temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); + exp_temp = sub(31, q_ein); + if ( temp == 0 ) + { + exp_temp = add( 0, EPSILON_EXP ); + } + if (temp == 0) + { + temp = L_add( 0, EPSILON_MANT ); + } + temp = ISqrt32( temp, &exp_temp ); + shift = sub( 31, q_eout ); + Ghat_fx[1] = Mpy_32_32( temp, ISqrt32( E_out2, &shift ) ); + exp_temp = add( shift, exp_temp ); + } +#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif } +#endif #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif @@ -4555,21 +4645,86 @@ static void formulate2x2MixingMatrix_fx( move32(); } } - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ q_temp = sub( add( q_ky, q_GhatQ ), 31 ); push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" ); /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ push_wmops( "oPtoA MT1M" ); #ifdef FIX_1326_SPEEDUP_01 - matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); + // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); + + { + Word16 chA, chB; + { + chA = 0, chB = 0; + tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), + Are_fx[1][0], Are_fx[1][0] ), + Aim_fx[0][0], Aim_fx[0][0] ), + Aim_fx[1][0], Aim_fx[1][0] ); + move32(); + } + { + chA = 0, chB = 1; + tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), + Are_fx[1][1], Are_fx[1][0] ), + Aim_fx[0][1], Aim_fx[0][0] ), + Aim_fx[1][1], Aim_fx[1][0] ); + move32(); + tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), + Are_fx[1][1], Aim_fx[1][0] ), + Aim_fx[0][1], Are_fx[0][0] ), + Aim_fx[1][1], Are_fx[1][0] ); + move32(); + } + { + chA = 1, chB = 0; + tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), + Are_fx[1][1], Are_fx[1][1] ), + Aim_fx[0][1], Aim_fx[0][1] ), + Aim_fx[1][1], Aim_fx[1][1] ); + move32(); + } + { + chA = 1, chB = 1; + } + + q_temp = sub( add( q_A, q_A ), 31 ); + + move16(); + Word16 ZeroState = add( 1, 0 ); + if (tmpRe_fx[0][0] != 0) + { + ZeroState = add(0, 0); + } + if ( tmpRe_fx[1][1] != 0 ) + { + ZeroState = add( 0, 0 ); + } + if ( tmpRe_fx[1][0] != 0 ) + { + ZeroState = add( 0, 0 ); + } + if ( tmpIm_fx[1][0] != 0 ) + { + ZeroState = add( 0, 0 ); + } + + if ( sub(ZeroState,1) == 0 ) + { + q_temp = Q31; + move16(); + } + + } + eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); #else @@ -4579,6 +4734,24 @@ static void formulate2x2MixingMatrix_fx( #endif pop_wmops();/*push_wmops( "oPtoA MT1M" );*/ +#ifdef FIX_1326_SPEEDUP_07 + IF( D_fx[0] == 0 ) + { + //temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + //exp = ONE_DIV_EPSILON_EXP; + div_fx[0] = L_add(0,2047986068); //Sqrt32( temp, &exp ); // Q = 31 - exp + exp = add(0,20); + } + ELSE + { + exp = sub( 31, q_D ); + div_fx[0] = ISqrt32( D_fx[0], &exp ); + //temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + //exp = sub( exp, sub( Q30, q_D ) ); + //div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + move32(); + } +#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4598,6 +4771,7 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); +#endif IF( D_fx[1] == 0 ) { -- GitLab From 53b1831e4ce530c0d8939abe31b35b684f04979f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 16:32:41 +0100 Subject: [PATCH 0589/1221] apply clang patch --- lib_com/basop_util.c | 6 +- .../ivas_dirac_dec_binaural_functions_fx.c | 139 +++++++++--------- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index fa8d097df..609ca234d 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1018,7 +1018,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word16 sy; Word32 sign; - //push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); + // push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); /* assert (x >= (Word32)0); */ assert( y != (Word32) 0 ); @@ -1041,7 +1041,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) IF( x == (Word32) 0 ) { *s = 0; - //pop_wmops(); + // pop_wmops(); return ( (Word32) 0 ); } @@ -1062,7 +1062,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { z = L_negate( z ); } - //pop_wmops(); + // pop_wmops(); return z; } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index d1fb6c23c..577ee62f7 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -514,7 +514,7 @@ void ivas_dirac_dec_binaural_render_fx( Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); push_wmops( "IDR binaural internal (IDRBI)" ); ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx ); - pop_wmops();/*push_wmops( "IDR binaural internal (IDRBI)" );*/ + pop_wmops(); /*push_wmops( "IDR binaural internal (IDRBI)" );*/ FOR( ch = 0; ch < nchan_out; ch++ ) { output_fx_local[ch] += n_samples_sf; @@ -934,7 +934,7 @@ static void ivas_dirac_dec_binaural_internal_fx( test(); push_wmops( "IDRBI cov matrices" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); - pop_wmops();/*push_wmops( "IDRBI cov matrices" );*/ + pop_wmops(); /*push_wmops( "IDRBI cov matrices" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -1023,7 +1023,7 @@ static void ivas_dirac_dec_binaural_internal_fx( push_wmops( "IDRBI processOutput" ); ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); pop_wmops(); /*push_wmops( "IDRBI processOutput" ); - */ + */ hDiracDecBin->hDiffuseDist = NULL; hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); @@ -3286,7 +3286,7 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) #ifdef FIX_1326_SPEEDUP_02 - IF ( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) + IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { Ure_fx[0][0] = ONE_IN_Q31; move32(); @@ -3312,20 +3312,20 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 //178.932 +#ifdef FIX_1326_SPEEDUP_03 // 178.932 tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 - IF( LT_32( pm_fx, L_shl_sat(tmp1, sub(q_tmp1,q_tmp2) ) ) ) - { - Ure_fx[0][0] = ONE_IN_Q30; - move32(); - Ure_fx[1][1] = ONE_IN_Q30; - move32(); - *q_U = Q30; - move16(); + IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) + { + Ure_fx[0][0] = ONE_IN_Q30; + move32(); + Ure_fx[1][1] = ONE_IN_Q30; + move32(); + *q_U = Q30; + move16(); - return; - } + return; + } #else tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 @@ -3470,13 +3470,13 @@ static void eig2x2_fx( #ifdef FIX_1326_SPEEDUP_04 Word16 exp_tmp2; Word32 eps_tmp; - + tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &exp_tmp2 ); eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, exp_tmp2 ) ); - tmp3 = L_add( L_shr ( tmp2,1), L_shr(eps_tmp,1) ); // Add Epsilon if relevant + tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); // Add Epsilon if relevant - exp_tmp3 = add(exp_tmp2 , 1); + exp_tmp3 = add( exp_tmp2, 1 ); #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); @@ -4525,17 +4525,17 @@ static void formulate2x2MixingMatrix_fx( exp_temp = EPSILON_EXP; move32(); } - if (temp == 0) + if ( temp == 0 ) { temp = EPSILON_MANT; move32(); } - temp = ISqrt32( temp , &exp_temp); + temp = ISqrt32( temp, &exp_temp ); shift = sub( 31, q_eout ); Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); move32(); exp = add( shift, exp_temp ); - } + } #else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); @@ -4580,12 +4580,12 @@ static void formulate2x2MixingMatrix_fx( { Word16 shift = norm_l( temp ); temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub(31, q_ein); + exp_temp = sub( 31, q_ein ); if ( temp == 0 ) { exp_temp = add( 0, EPSILON_EXP ); } - if (temp == 0) + if ( temp == 0 ) { temp = L_add( 0, EPSILON_MANT ); } @@ -4663,46 +4663,46 @@ static void formulate2x2MixingMatrix_fx( { Word16 chA, chB; - { + { chA = 0, chB = 0; - tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), - Are_fx[1][0], Are_fx[1][0] ), - Aim_fx[0][0], Aim_fx[0][0] ), - Aim_fx[1][0], Aim_fx[1][0] ); - move32(); - } - { - chA = 0, chB = 1; - tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), - Are_fx[1][1], Are_fx[1][0] ), - Aim_fx[0][1], Aim_fx[0][0] ), - Aim_fx[1][1], Aim_fx[1][0] ); - move32(); - tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), - Are_fx[1][1], Aim_fx[1][0] ), - Aim_fx[0][1], Are_fx[0][0] ), - Aim_fx[1][1], Are_fx[1][0] ); - move32(); - } - { - chA = 1, chB = 0; - tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), - Are_fx[1][1], Are_fx[1][1] ), - Aim_fx[0][1], Aim_fx[0][1] ), - Aim_fx[1][1], Aim_fx[1][1] ); - move32(); - } - { - chA = 1, chB = 1; - } + tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), + Are_fx[1][0], Are_fx[1][0] ), + Aim_fx[0][0], Aim_fx[0][0] ), + Aim_fx[1][0], Aim_fx[1][0] ); + move32(); + } + { + chA = 0, chB = 1; + tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), + Are_fx[1][1], Are_fx[1][0] ), + Aim_fx[0][1], Aim_fx[0][0] ), + Aim_fx[1][1], Aim_fx[1][0] ); + move32(); + tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), + Are_fx[1][1], Aim_fx[1][0] ), + Aim_fx[0][1], Are_fx[0][0] ), + Aim_fx[1][1], Are_fx[1][0] ); + move32(); + } + { + chA = 1, chB = 0; + tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), + Are_fx[1][1], Are_fx[1][1] ), + Aim_fx[0][1], Aim_fx[0][1] ), + Aim_fx[1][1], Aim_fx[1][1] ); + move32(); + } + { + chA = 1, chB = 1; + } q_temp = sub( add( q_A, q_A ), 31 ); move16(); Word16 ZeroState = add( 1, 0 ); - if (tmpRe_fx[0][0] != 0) + if ( tmpRe_fx[0][0] != 0 ) { - ZeroState = add(0, 0); + ZeroState = add( 0, 0 ); } if ( tmpRe_fx[1][1] != 0 ) { @@ -4717,12 +4717,11 @@ static void formulate2x2MixingMatrix_fx( ZeroState = add( 0, 0 ); } - if ( sub(ZeroState,1) == 0 ) + if ( sub( ZeroState, 1 ) == 0 ) { - q_temp = Q31; + q_temp = Q31; move16(); } - } @@ -4732,23 +4731,23 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); #endif - pop_wmops();/*push_wmops( "oPtoA MT1M" );*/ + pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ #ifdef FIX_1326_SPEEDUP_07 IF( D_fx[0] == 0 ) { - //temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - //exp = ONE_DIV_EPSILON_EXP; - div_fx[0] = L_add(0,2047986068); //Sqrt32( temp, &exp ); // Q = 31 - exp - exp = add(0,20); + // temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + // exp = ONE_DIV_EPSILON_EXP; + div_fx[0] = L_add( 0, 2047986068 ); // Sqrt32( temp, &exp ); // Q = 31 - exp + exp = add( 0, 20 ); } ELSE { exp = sub( 31, q_D ); div_fx[0] = ISqrt32( D_fx[0], &exp ); - //temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); - //exp = sub( exp, sub( Q30, q_D ) ); - //div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + // temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + // exp = sub( exp, sub( Q30, q_D ) ); + // div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); } #else @@ -4787,7 +4786,7 @@ static void formulate2x2MixingMatrix_fx( { push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4889,7 +4888,7 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ @@ -4976,7 +4975,7 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); - pop_wmops();/*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); -- GitLab From 08deb10bdc6ee2f4688cec4b2e10293c5fa7ba19 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 17:04:07 +0100 Subject: [PATCH 0590/1221] added FIX_1326_SPEEDUP_08 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 577ee62f7..2dac2b867 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -53,6 +53,7 @@ #define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS #define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS #define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4772,6 +4773,20 @@ static void formulate2x2MixingMatrix_fx( move32(); #endif +#ifdef FIX_1326_SPEEDUP_08 + // This is just a shortcut to already existing optimizations (FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC) - but makes everything even faster + { + div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 + exp1 = add( 0, 20 ); // move32(); + } + + IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt + { + exp1 = sub( 31, q_D ); + div_fx[1] = ISqrt32( D_fx[1], &exp1 ); + move32(); + } +#else IF( D_fx[1] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4791,7 +4806,7 @@ static void formulate2x2MixingMatrix_fx( } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 move32(); - +#endif q_div = sub( 31, s_max( exp, exp1 ) ); div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); // q_div -- GitLab From 55f867a1af26a4153aafe537ae6c1294552ed7c5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 17:07:26 +0100 Subject: [PATCH 0591/1221] fixed warning --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 2dac2b867..7c243d7d8 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3770,6 +3770,7 @@ static void matrixMul_fx( return; } +#ifndef FIX_1326_SPEEDUP_01 static void matrixTransp1Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -3883,6 +3884,7 @@ static void matrixTransp1Mul_fx( return; } +#endif /*FIX_1326_SPEEDUP_01*/ static void matrixTransp2Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -4663,7 +4665,7 @@ static void formulate2x2MixingMatrix_fx( // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); { - Word16 chA, chB; + //Word16 chA, chB; { chA = 0, chB = 0; tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), @@ -4673,7 +4675,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - chA = 0, chB = 1; + //chA = 0, chB = 1; tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), Are_fx[1][1], Are_fx[1][0] ), Aim_fx[0][1], Aim_fx[0][0] ), @@ -4686,7 +4688,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - chA = 1, chB = 0; + //chA = 1, chB = 0; tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), Are_fx[1][1], Are_fx[1][1] ), Aim_fx[0][1], Aim_fx[0][1] ), @@ -4694,7 +4696,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - chA = 1, chB = 1; + //chA = 1, chB = 1; } q_temp = sub( add( q_A, q_A ), 31 ); -- GitLab From 187febb7fb8d24325911889c5441f6373ec3f5e2 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 4 Mar 2025 17:11:02 +0100 Subject: [PATCH 0592/1221] apply clang patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7c243d7d8..1544b4f1a 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4665,7 +4665,7 @@ static void formulate2x2MixingMatrix_fx( // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); { - //Word16 chA, chB; + // Word16 chA, chB; { chA = 0, chB = 0; tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), @@ -4675,7 +4675,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - //chA = 0, chB = 1; + // chA = 0, chB = 1; tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), Are_fx[1][1], Are_fx[1][0] ), Aim_fx[0][1], Aim_fx[0][0] ), @@ -4688,7 +4688,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - //chA = 1, chB = 0; + // chA = 1, chB = 0; tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), Are_fx[1][1], Are_fx[1][1] ), Aim_fx[0][1], Aim_fx[0][1] ), @@ -4696,7 +4696,7 @@ static void formulate2x2MixingMatrix_fx( move32(); } { - //chA = 1, chB = 1; + // chA = 1, chB = 1; } q_temp = sub( add( q_A, q_A ), 31 ); -- GitLab From 3029cb4d6b89ab8eff9b6115e57344f9981c9946 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 09:26:29 +0100 Subject: [PATCH 0593/1221] activated SPEEDUP8 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 1544b4f1a..f024f53ba 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,14 +46,14 @@ #include "wmc_auto.h" //#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS -#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS -#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS -#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS -#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS +//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS +//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS +//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs +//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs +//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs! Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- -- GitLab From 13aaba5d9f609e048bdcdf102eaab5be8573b3ad Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 11:13:06 +0100 Subject: [PATCH 0594/1221] activate SPEEDUP 07 small version --- .../ivas_dirac_dec_binaural_functions_fx.c | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f024f53ba..c452437f1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -52,8 +52,8 @@ //#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS //#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs! +#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs , no replacement of divSqrt +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4746,12 +4746,18 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - exp = sub( 31, q_D ); - div_fx[0] = ISqrt32( D_fx[0], &exp ); - // temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); - // exp = sub( exp, sub( Q30, q_D ) ); - // div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp +#if 1 //old code + push_wmops( "formulate2x2MixingMatrix Division" ); + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + exp = sub( exp, sub( Q30, q_D ) ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ + div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + move32(); +#else + exp = sub(31, q_D); + div_fx[0] = ISqrt32_2( D_fx[0], &exp ); move32(); +#endif } #else IF( D_fx[0] == 0 ) -- GitLab From 22c89e001bfb9427c4d97c0413a80163f57d723c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 11:18:14 +0100 Subject: [PATCH 0595/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index c452437f1..1e37860c9 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4746,18 +4746,18 @@ static void formulate2x2MixingMatrix_fx( } ELSE { -#if 1 //old code +#if 1 // old code push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); exp = sub( exp, sub( Q30, q_D ) ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); #else - exp = sub(31, q_D); + exp = sub( 31, q_D ); div_fx[0] = ISqrt32_2( D_fx[0], &exp ); move32(); -#endif +#endif } #else IF( D_fx[0] == 0 ) -- GitLab From d8ff057a51e3e22604ffb296cdd1bca905918765 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 12:22:09 +0100 Subject: [PATCH 0596/1221] activated speedup 01 02 03 04 --- .../ivas_dirac_dec_binaural_functions_fx.c | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 1e37860c9..06b5be3ee 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,14 +46,14 @@ #include "wmc_auto.h" //#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -//#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS -//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS -//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs -//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 2.8 WMOPS //Big DIffs , no replacement of divSqrt -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! +#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS +#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS +//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE +//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -- > DONT USE +#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // ? WMOPS //Big DIffs , no replacement of divSqrt , PIPELINE GREEN, --> USE +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! -- > USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4521,8 +4521,12 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_05 { Word16 shift = norm_l( temp ); +#if 1 // oldcode + temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); +#else + temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 31, q_ein ); + exp_temp = sub( 30, q_ein ); if ( temp == 0 ) { exp_temp = EPSILON_EXP; @@ -4533,6 +4537,7 @@ static void formulate2x2MixingMatrix_fx( temp = EPSILON_MANT; move32(); } +#endif temp = ISqrt32( temp, &exp_temp ); shift = sub( 31, q_eout ); Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); @@ -4582,8 +4587,11 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_06 { Word16 shift = norm_l( temp ); +#if 0 //oldcode + temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); +#else temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 31, q_ein ); + exp_temp = sub( 31 - 1, q_ein ); if ( temp == 0 ) { exp_temp = add( 0, EPSILON_EXP ); @@ -4592,10 +4600,22 @@ static void formulate2x2MixingMatrix_fx( { temp = L_add( 0, EPSILON_MANT ); } +#endif +#if 1 //oldcode - new code introduces too much noise + push_wmops( "formulate2x2MixingMatrix Division" ); + temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ + exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 +#endif +#else temp = ISqrt32( temp, &exp_temp ); shift = sub( 31, q_eout ); - Ghat_fx[1] = Mpy_32_32( temp, ISqrt32( E_out2, &shift ) ); - exp_temp = add( shift, exp_temp ); + Ghat_fx[1] = Mpy_32_32( temp, Sqrt32( E_out2, &shift ) ); + exp1 = add( shift, exp_temp ); +#endif + } #else { -- GitLab From 84ba37670d88e4552d717dc88ebdb681121b95b8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 12:35:34 +0100 Subject: [PATCH 0597/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 06b5be3ee..5fcc8a2d1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -54,6 +54,7 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -- > DONT USE #define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // ? WMOPS //Big DIffs , no replacement of divSqrt , PIPELINE GREEN, --> USE #define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! -- > USE +#define FIX_1326_SPEEDUP_09 // Relocate matrixMul Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -4587,7 +4588,7 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_06 { Word16 shift = norm_l( temp ); -#if 0 //oldcode +#if 0 // oldcode temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); #else temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); @@ -4601,7 +4602,7 @@ static void formulate2x2MixingMatrix_fx( temp = L_add( 0, EPSILON_MANT ); } #endif -#if 1 //oldcode - new code introduces too much noise +#if 1 // oldcode - new code introduces too much noise push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ @@ -4614,8 +4615,7 @@ static void formulate2x2MixingMatrix_fx( shift = sub( 31, q_eout ); Ghat_fx[1] = Mpy_32_32( temp, Sqrt32( E_out2, &shift ) ); exp1 = add( shift, exp_temp ); -#endif - +#endif } #else { @@ -4749,10 +4749,17 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#ifdef FIX_1326_SPEEDUP_09 + matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); +#endif #else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); + +#ifdef FIX_1326_SPEEDUP_09 + matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); +#endif #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ @@ -4860,7 +4867,9 @@ static void formulate2x2MixingMatrix_fx( move16(); } +#ifndef FIX_1326_SPEEDUP_09 matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); +#endif exp = L_norm_arr( div_fx, BINAURAL_CHANNELS ); scale_sig32( div_fx, BINAURAL_CHANNELS, exp ); -- GitLab From ed23bfb94952e39a5e4826aef8e3831012b6749f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 14:30:57 +0100 Subject: [PATCH 0598/1221] activate speedup 09 10 11 for testing --- .../ivas_dirac_dec_binaural_functions_fx.c | 80 ++++++++++++++----- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 5fcc8a2d1..e99cb6b34 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,16 +45,25 @@ #include "wmc_auto.h" -//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence in current bitstream -#define FIX_1326_SPEEDUP_01 // optimize matrixTransp1Mul_fx -> eig2x2_fx : .4 WMOPS -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS -#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS -//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE -//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs -- > DONT USE -#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // ? WMOPS //Big DIffs , no replacement of divSqrt , PIPELINE GREEN, --> USE -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs, PIPELINE GREEN! -- > USE -#define FIX_1326_SPEEDUP_09 // Relocate matrixMul +// MHZ NUMBERS: +// NULL: 179.292 + + +//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence --> DONT USE +//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE +//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE +//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE +//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS +//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS +//#define FIX_1326_SPEEDUP_14 // Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -2142,6 +2151,14 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); +#ifdef FIX_1326_SPEEDUP_11 + { + Word16 shift1 = s_max( 0, sub( q_tmp2, q_CrEne ) ); + Word16 shift2 = s_max( 0, sub( q_CrEne, q_tmp2 ) ); + realizedOutputEne_fx = L_add( L_shr( tmp1, shift2 ), L_shr( tmp2, shift1 ) ); + q_realizedOutputEne = s_min( q_CrEne, q_tmp2 ); + } +#else IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); @@ -2154,7 +2171,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_realizedOutputEne = q_tmp2; move16(); } - +#endif exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 1 ); targetOutputEne_fx = L_add( L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ), L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ) ); q_targetOutputEne = add( hDiracDecBin->q_ChEneOut, exp ); @@ -2177,9 +2194,17 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_missingOutputEne = q_targetOutputEne; move16(); } - tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); +#ifdef FIX_1326_SPEEDUP_13 + { + Word16 exp_temp; + tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + tmp2 = ISqrt32( tmp2, &exp_temp ); + gain_fx = Mpy_32_32(tmp2, Sqrt32(tmp1, &exp1)); + q_gain = sub( 31, add( exp_temp, exp1 ) ); + } +#else { Word16 exp_temp; tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); @@ -2188,6 +2213,8 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } gain_fx = Sqrt32( tmp2, &exp2 ); q_gain = sub( 31, exp2 ); +#endif + // 1073741824 = 4 in Q28 IF( LT_16( q_gain, Q28 ) ) @@ -4749,17 +4776,11 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#ifdef FIX_1326_SPEEDUP_09 - matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); -#endif #else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#ifdef FIX_1326_SPEEDUP_09 - matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); -#endif #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ @@ -4849,7 +4870,19 @@ static void formulate2x2MixingMatrix_fx( div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); // q_div move32(); + // 1310720000 = 10,000.0f in Q17 +#ifdef FIX_1326_SPEEDUP_09 + { + Word16 shift1 = s_max( sub( Q17, q_div ), 0 ); + Word16 shift2 = s_max( sub( q_div, Q17 ), 0 ); + + div_fx[0] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[0], shift2 ) ); // q_div + move32(); + div_fx[1] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[1], shift2 ) ); // q_div + move32(); + } +#else IF( LT_16( q_div, Q17 ) ) { div_fx[0] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[0] ); // q_div @@ -4866,10 +4899,9 @@ static void formulate2x2MixingMatrix_fx( q_div = Q17; move16(); } +#endif -#ifndef FIX_1326_SPEEDUP_09 matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); -#endif exp = L_norm_arr( div_fx, BINAURAL_CHANNELS ); scale_sig32( div_fx, BINAURAL_CHANNELS, exp ); @@ -4884,7 +4916,11 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpRe_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { +#ifdef FIX_1326_SPEEDUP_10 + hdrm_re[chA][chB] = W_norm( W_tmp ); +#else hdrm_re[chA][chB] = sub( W_norm( W_tmp ), 0 ); +#endif move16(); W_tmp = W_shl( W_tmp, hdrm_re[chA][chB] ); tmpRe_fx[chA][chB] = W_extract_h( W_tmp ); @@ -4901,7 +4937,11 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpIm_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { +#ifdef FIX_1326_SPEEDUP_10 + hdrm_im[chA][chB] = W_norm( W_tmp ); +#else hdrm_im[chA][chB] = sub( W_norm( W_tmp ), 0 ); +#endif move16(); W_tmp = W_shl( W_tmp, hdrm_im[chA][chB] ); tmpIm_fx[chA][chB] = W_extract_h( W_tmp ); -- GitLab From 9f4a6477e7ca13411cb30936b04cb8063fbdd6b0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 14:56:15 +0100 Subject: [PATCH 0599/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e99cb6b34..2336151e0 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -58,12 +58,12 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE //#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS +#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS //#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE //#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -//#define FIX_1326_SPEEDUP_14 // +//#define FIX_1326_SPEEDUP_14 // Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -2201,7 +2201,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( Word16 exp_temp; tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); tmp2 = ISqrt32( tmp2, &exp_temp ); - gain_fx = Mpy_32_32(tmp2, Sqrt32(tmp1, &exp1)); + gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) ); q_gain = sub( 31, add( exp_temp, exp1 ) ); } #else @@ -2214,7 +2214,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( gain_fx = Sqrt32( tmp2, &exp2 ); q_gain = sub( 31, exp2 ); #endif - + // 1073741824 = 4 in Q28 IF( LT_16( q_gain, Q28 ) ) -- GitLab From 28e5f0861d369268d41334c1223c17b2ea83d6fd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 15:33:23 +0100 Subject: [PATCH 0600/1221] added assert testing --- .../ivas_dirac_dec_binaural_functions_fx.c | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 2336151e0..cc6d977f0 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -58,12 +58,12 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE //#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS -#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS -//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -//#define FIX_1326_SPEEDUP_14 // +//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) +//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) +//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) +//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -->USE? (pipe coming) +#define FIX_1326_SPEEDUP_14 // test Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -3213,8 +3213,14 @@ static void eig2x2_fx( pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ + #ifdef FIX_1326_SPEEDUP_14 + static int tstcnt = 0; + #endif IF( L_and( c_re == 0, c_im == 0 ) ) { +#ifdef FIX_1326_SPEEDUP_14 + tstcnt ++; +#endif /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 a_fx = (E1 - E2)^2 pm_fx = 0.5 * sqrt(max(0, a_fx)) = 0.5 * max(0, (e1 - e2)) */ @@ -3232,6 +3238,9 @@ static void eig2x2_fx( q_crossSquare = sub( add( q_c, q_c ), 31 ); IF( EQ_32( e1, e2 ) ) { +#ifdef FIX_1326_SPEEDUP_14 + tstcnt++; +#endif /* if e1 - e2 = 0, then a_fx = 4 * crossSquare_fx pm_fx = 0.5 * sqrt(max(0, 4 * crossSquare_fx)) = sqrt(0, crossSquare_fx)*/ test(); @@ -3265,6 +3274,9 @@ static void eig2x2_fx( IF( GT_16( sub( q_c, q_e ), Q15 ) ) { +#ifdef FIX_1326_SPEEDUP_14 + tstcnt++; +#endif pm_fx = L_shr( L_max( 0, L_abs( L_sub( e1, e2 ) ) ), 1 ); q_tmp2 = q_e; move16(); @@ -3288,6 +3300,10 @@ static void eig2x2_fx( } } } +#ifdef FIX_1326_SPEEDUP_14 + if (tstcnt>10000) + assert(0); +#endif // add_fx = 0.5 * (e1 + e2) add_fx = L_shr( L_add( e1, e2 ), 1 ); q_tmp1 = q_e; @@ -4669,7 +4685,6 @@ static void formulate2x2MixingMatrix_fx( move32(); pop_wmops(); - push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" ); /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -4695,14 +4710,11 @@ static void formulate2x2MixingMatrix_fx( move32(); } } - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q" );*/ q_temp = sub( add( q_ky, q_GhatQ ), 31 ); - push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" ); /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix MMUL K*Ghat*Q*Kx" );*/ push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx @@ -4980,7 +4992,7 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA" );*/ + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" );*/ push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ -- GitLab From 5bc6b7e7231f8d5c414732810069176823c42576 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 5 Mar 2025 15:35:49 +0100 Subject: [PATCH 0601/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index cc6d977f0..c5b3500b2 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3213,13 +3213,13 @@ static void eig2x2_fx( pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ - #ifdef FIX_1326_SPEEDUP_14 +#ifdef FIX_1326_SPEEDUP_14 static int tstcnt = 0; - #endif +#endif IF( L_and( c_re == 0, c_im == 0 ) ) { #ifdef FIX_1326_SPEEDUP_14 - tstcnt ++; + tstcnt++; #endif /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 a_fx = (E1 - E2)^2 @@ -3301,8 +3301,8 @@ static void eig2x2_fx( } } #ifdef FIX_1326_SPEEDUP_14 - if (tstcnt>10000) - assert(0); + if ( tstcnt > 10000 ) + assert( 0 ); #endif // add_fx = 0.5 * (e1 + e2) add_fx = L_shr( L_add( e1, e2 ), 1 ); -- GitLab From 5a63dbac1775e86223f59bb6aadfec88bcb43757 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 09:52:48 +0100 Subject: [PATCH 0602/1221] deactivate SPeedup 14, activate Speedup 13 for testing --- .../ivas_dirac_dec_binaural_functions_fx.c | 75 +++++++++++++++---- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index c5b3500b2..ad9769583 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -49,7 +49,6 @@ // NULL: 179.292 -//#define FIX_1326_SPEEDUP_00 //make sqrt(1) a const - catch bitstreams //no occurence --> DONT USE //#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE //#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE //#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE @@ -58,12 +57,18 @@ //#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE //#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) -//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) -//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS --> USE? (pipe 48851 fails --> DONTUSEYET) -//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS -->DONTUSE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS -->USE? (pipe coming) -#define FIX_1326_SPEEDUP_14 // test +//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS --> DONTUSE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) +//#define FIX_1326_SPEEDUP_14 // test wether any of these paths is realy necessary, then assert --> DONTUSE (pipes red, asserts!) +//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) +//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) + + + + Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -943,9 +948,9 @@ static void ivas_dirac_dec_binaural_internal_fx( } test(); - push_wmops( "IDRBI cov matrices" ); + push_wmops( "IDRBI cov matrices (IDRBCM)" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); - pop_wmops(); /*push_wmops( "IDRBI cov matrices" );*/ + pop_wmops(); /*push_wmops( "IDRBI cov matrices (IDRBCM)" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -1168,7 +1173,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ move16(); - + push_wmops( "IDRBCM inits" ); q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) ); scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) ); hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; @@ -1202,6 +1207,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ move16(); } + pop_wmops(); /*push_wmops( "IDRBCM inits" );*/ /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ applyLowBitRateEQ = 0; @@ -1214,11 +1220,13 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); IF( EQ_32( ivas_total_brate, IVAS_16k4 ) ) { + push_wmops( "IDRBCM Determine EQ_low_rates" ); FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) { lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = L_add( L_shr( lowBitRateBinauralEQ_fx[bin], 1 ), ONE_IN_Q30 ); // Q31 move32(); } + pop_wmops(); /*push_wmops( "IDRBCM Determine EQ_low_rates" );*/ } ELSE { @@ -1237,6 +1245,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below + push_wmops( "IDRBCM input Matrix" ); /* Calculate input covariance matrix */ FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { @@ -1271,7 +1280,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); } } + pop_wmops(); /*push_wmops( "IDRBCM input Matrix" );*/ + push_wmops( "IDRBCM apply EQ_low" ); /* Apply EQ at low bit rates */ IF( applyLowBitRateEQ != 0 ) { @@ -1324,7 +1335,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } } } + pop_wmops(); /*push_wmops( "IDRBCM apply EQ_low" );*/ + push_wmops( "IDRBCM target matrix" ); /* Determine target covariance matrix containing target binaural properties */ FOR( bin = 0; bin < nBins; bin++ ) { @@ -1484,12 +1497,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word32 hrtfEneCenter_fx, hrtfEneSides_fx, hrtfEneRealized_fx; Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; - +#ifdef FIX_1326_SPEEDUP_15 + hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); //Q25 +#else hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 - +#endif /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. * spreadCoh = 0: Only panning @@ -1518,11 +1533,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the left source of the three coherent sources */ getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); - +#ifdef FIX_1326_SPEEDUP_15 + hrtfEneSides_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), rImagpTmp_fx, rImagpTmp_fx ), lImagpTmp_fx, lImagpTmp_fx ), lRealpTmp_fx, lRealpTmp_fx ); // Q25 +#else hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 +#endif lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 @@ -1610,12 +1628,21 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); } +#ifdef FIX_1326_SPEEDUP_15 + hrtfEne_fx[0] = Madd_32_32( Mpy_32_32( lRealp_fx, lRealp_fx ), lImagp_fx, lImagp_fx ); // Q( 2*q_lr - 31 ) + hrtfEne_fx[1] = Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) + move32(); + move32(); + hrtfCrossRe_fx = Madd_32_32( Mpy_32_32( lRealp_fx, rRealp_fx ), lImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) + hrtfCrossIm_fx = Madd_32_32( Mpy_32_32( -lImagp_fx, rRealp_fx ), lRealp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) +#else hrtfEne_fx[0] = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), Mpy_32_32( lImagp_fx, lImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfEne_fx[1] = L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), Mpy_32_32( rImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) move32(); move32(); hrtfCrossRe_fx = L_add( Mpy_32_32( lRealp_fx, rRealp_fx ), Mpy_32_32( lImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfCrossIm_fx = L_add( Mpy_32_32( -lImagp_fx, rRealp_fx ), Mpy_32_32( lRealp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) +#endif /* Add direct part (1 or 2) covariance matrix */ dirEne_fx = Mpy_32_32( ratio_fx, meanEnePerCh_fx ); // Q(q_meanEnePerCh - 1) @@ -1690,7 +1717,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } ELSE { +#ifdef FIX_1326_SPEEDUP_15 + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( Madd_32_16( L_shl( surCoh_fx, 16 ), hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); +#else hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( L_add( Mpy_32_16_1( hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), L_shl( surCoh_fx, 16 ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); +#endif } move32(); } @@ -1706,6 +1737,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } + pop_wmops();/*push_wmops( "IDRBCM target matrix" );*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -3435,10 +3467,25 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); + +#ifdef FIX_1326_SPEEDUP_16 + + { + Word16 tmp2_exp; + Word32 eps_tmp; + tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &tmp2_exp ); + + //Add epsilon if relevant + eps_tmp = L_shl_sat( epsilon_mant, sub(epsilon_exp, tmp2_exp )); + tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); + + exp_tmp3 = add( tmp2_exp, 1 ); + } +#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); - tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); +#endif #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); -- GitLab From 31992274c6aa136f14ca37af5d9bdd9413f46f58 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 09:54:39 +0100 Subject: [PATCH 0603/1221] deactivate SPeedup 14, activate Speedup 13 for testing --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index ad9769583..620b4e323 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -61,7 +61,7 @@ //#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS --> DONTUSE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) +#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) //#define FIX_1326_SPEEDUP_14 // test wether any of these paths is realy necessary, then assert --> DONTUSE (pipes red, asserts!) //#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) -- GitLab From b2b27affb27707f75906b1bfbea775a8da70a0d5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 10:09:06 +0100 Subject: [PATCH 0604/1221] apply clang format patch --- .../ivas_dirac_dec_binaural_functions_fx.c | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 620b4e323..7721c3eaa 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -67,8 +67,6 @@ //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) - - Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -1498,12 +1496,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; #ifdef FIX_1326_SPEEDUP_15 - hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); //Q25 + hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); // Q25 #else - hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 - L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 - L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 - Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 + L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 + L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 + Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 #endif /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. @@ -1536,15 +1534,15 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric #ifdef FIX_1326_SPEEDUP_15 hrtfEneSides_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), rImagpTmp_fx, rImagpTmp_fx ), lImagpTmp_fx, lImagpTmp_fx ), lRealpTmp_fx, lRealpTmp_fx ); // Q25 #else - hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 - L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 - L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 - Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 + L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 + L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 + Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 #endif - lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 - lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 - rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 - rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 + lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 + rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 + rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 /* Apply the gain for the right source of the three coherent sources. * -30 degrees to 330 wrapping due to internal functions. */ @@ -1737,7 +1735,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } - pop_wmops();/*push_wmops( "IDRBCM target matrix" );*/ + pop_wmops(); /*push_wmops( "IDRBCM target matrix" );*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -3475,12 +3473,12 @@ static void eig2x2_fx( Word32 eps_tmp; tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &tmp2_exp ); - //Add epsilon if relevant - eps_tmp = L_shl_sat( epsilon_mant, sub(epsilon_exp, tmp2_exp )); + // Add epsilon if relevant + eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, tmp2_exp ) ); tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); exp_tmp3 = add( tmp2_exp, 1 ); - } + } #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); -- GitLab From 1461021e3412cc39bfa852758c76edeff3ba25b9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 10:15:25 +0100 Subject: [PATCH 0605/1221] fix build warning --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7721c3eaa..4db8980e1 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1916,7 +1916,11 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); Word32 tmp1, tmp2, res1, res2; Word16 q_tmp1, q_tmp2, q_realizedOutputEne, q_targetOutputEne, q_missingOutputEne, q_gain; +#ifdef FIX_1326_SPEEDUP_13 + Word16 exp1, q_processMtx_bin, q_processMtxDec_bin; +#else Word16 exp1, exp2, q_processMtx_bin, q_processMtxDec_bin; +#endif CrEneL_fx = 0; move32(); -- GitLab From 0df435dc0501754f7af9b1d8248813bae39ff4df Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 7 Mar 2025 11:08:02 +0100 Subject: [PATCH 0606/1221] ctivated speedup 15, 16 to test --- .../ivas_dirac_dec_binaural_functions_fx.c | 118 +----------------- 1 file changed, 6 insertions(+), 112 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 4db8980e1..45e1d2bed 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -53,18 +53,14 @@ //#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE //#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE //#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_05 // div->sqrt =>isqrt // 3.5 WMOPS //Quite bad diffs --> DONT USE -//#define FIX_1326_SPEEDUP_06 // div->sqrt =>isqrt // 3.0 WMOPS //Quite bad diffs --> DONT USE -//#define FIX_1326_SPEEDUP_07 // div->sqrt =>isqrt // 0 WMOPS --> DONT USE //#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE //#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET //#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_12 // tiny speedup // <.1 WMOPS --> DONTUSE -#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE? (pipe tbd) -//#define FIX_1326_SPEEDUP_14 // test wether any of these paths is realy necessary, then assert --> DONTUSE (pipes red, asserts!) -//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) -//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) +#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -3246,15 +3242,8 @@ static void eig2x2_fx( a_fx = (e1 + e2) * (e1 + e2) - 4.0f * ((e1 * e2) - crossSquare_fx) = (e1 - e2)^2 + 4 * crossSquare_fx pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ - -#ifdef FIX_1326_SPEEDUP_14 - static int tstcnt = 0; -#endif IF( L_and( c_re == 0, c_im == 0 ) ) { -#ifdef FIX_1326_SPEEDUP_14 - tstcnt++; -#endif /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 a_fx = (E1 - E2)^2 pm_fx = 0.5 * sqrt(max(0, a_fx)) = 0.5 * max(0, (e1 - e2)) */ @@ -3272,9 +3261,6 @@ static void eig2x2_fx( q_crossSquare = sub( add( q_c, q_c ), 31 ); IF( EQ_32( e1, e2 ) ) { -#ifdef FIX_1326_SPEEDUP_14 - tstcnt++; -#endif /* if e1 - e2 = 0, then a_fx = 4 * crossSquare_fx pm_fx = 0.5 * sqrt(max(0, 4 * crossSquare_fx)) = sqrt(0, crossSquare_fx)*/ test(); @@ -3308,9 +3294,6 @@ static void eig2x2_fx( IF( GT_16( sub( q_c, q_e ), Q15 ) ) { -#ifdef FIX_1326_SPEEDUP_14 - tstcnt++; -#endif pm_fx = L_shr( L_max( 0, L_abs( L_sub( e1, e2 ) ) ), 1 ); q_tmp2 = q_e; move16(); @@ -3334,10 +3317,6 @@ static void eig2x2_fx( } } } -#ifdef FIX_1326_SPEEDUP_14 - if ( tstcnt > 10000 ) - assert( 0 ); -#endif // add_fx = 0.5 * (e1 + e2) add_fx = L_shr( L_add( e1, e2 ), 1 ); q_tmp1 = q_e; @@ -4611,33 +4590,6 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE -#ifdef FIX_1326_SPEEDUP_05 - { - Word16 shift = norm_l( temp ); -#if 1 // oldcode - temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); -#else - - temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 30, q_ein ); - if ( temp == 0 ) - { - exp_temp = EPSILON_EXP; - move32(); - } - if ( temp == 0 ) - { - temp = EPSILON_MANT; - move32(); - } -#endif - temp = ISqrt32( temp, &exp_temp ); - shift = sub( 31, q_eout ); - Ghat_fx[0] = Mpy_32_32( Sqrt32( E_out1, &shift ), temp ); - move32(); - exp = add( shift, exp_temp ); - } -#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); @@ -4648,7 +4600,7 @@ static void formulate2x2MixingMatrix_fx( Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif } -#endif + #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif @@ -4677,39 +4629,6 @@ static void formulate2x2MixingMatrix_fx( #endif } ELSE -#ifdef FIX_1326_SPEEDUP_06 - { - Word16 shift = norm_l( temp ); -#if 0 // oldcode - temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); -#else - temp = L_add( L_shl( temp, sub( shift, 1 ) ), L_shl_sat( EPSILON_MANT, sub( sub( EPSILON_EXP, shift ), 1 ) ) ); - exp_temp = sub( 31 - 1, q_ein ); - if ( temp == 0 ) - { - exp_temp = add( 0, EPSILON_EXP ); - } - if ( temp == 0 ) - { - temp = L_add( 0, EPSILON_MANT ); - } -#endif -#if 1 // oldcode - new code introduces too much noise - push_wmops( "formulate2x2MixingMatrix Division" ); - temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ - exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 -#endif -#else - temp = ISqrt32( temp, &exp_temp ); - shift = sub( 31, q_eout ); - Ghat_fx[1] = Mpy_32_32( temp, Sqrt32( E_out2, &shift ) ); - exp1 = add( shift, exp_temp ); -#endif - } -#else { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); @@ -4720,7 +4639,7 @@ static void formulate2x2MixingMatrix_fx( Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif } -#endif + #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif @@ -4845,30 +4764,6 @@ static void formulate2x2MixingMatrix_fx( #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ -#ifdef FIX_1326_SPEEDUP_07 - IF( D_fx[0] == 0 ) - { - // temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - // exp = ONE_DIV_EPSILON_EXP; - div_fx[0] = L_add( 0, 2047986068 ); // Sqrt32( temp, &exp ); // Q = 31 - exp - exp = add( 0, 20 ); - } - ELSE - { -#if 1 // old code - push_wmops( "formulate2x2MixingMatrix Division" ); - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); - exp = sub( exp, sub( Q30, q_D ) ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ - div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp - move32(); -#else - exp = sub( 31, q_D ); - div_fx[0] = ISqrt32_2( D_fx[0], &exp ); - move32(); -#endif - } -#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4888,7 +4783,6 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#endif #ifdef FIX_1326_SPEEDUP_08 // This is just a shortcut to already existing optimizations (FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC) - but makes everything even faster -- GitLab From 69673ab7ad9c95dcf1627806e09aa357fdebbd90 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:26:44 +0100 Subject: [PATCH 0607/1221] add SPEEDUP 17, 18, inactive --- .../ivas_dirac_dec_binaural_functions_fx.c | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 45e1d2bed..3a10590f6 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -49,19 +49,20 @@ // NULL: 179.292 -//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE? (pipe tbd) -#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .18 WMOPS --> USE? (pipe tbd) - +//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? +//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -3343,6 +3344,7 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) + #ifdef FIX_1326_SPEEDUP_02 IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { @@ -3370,7 +3372,7 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 // 178.932 +#ifdef FIX_1326_SPEEDUP_03 tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) @@ -3469,7 +3471,11 @@ static void eig2x2_fx( #endif #if 1 +#ifdef FIX_1326_SPEEDUP_17 + tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); +#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); +#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3557,7 +3563,11 @@ static void eig2x2_fx( #endif #if 1 +#ifdef FIX_1326_SPEEDUP_17 + tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); +#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); +#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3619,7 +3629,19 @@ static void eig2x2_fx( move16(); } } +#ifdef FIX_1326_SPEEDUP_18 + if( q_U_1 != 0 ) + { + *q_U = q_U_1; + move16(); + } + if (q_U_1 == 0) + { + *q_U = q_U_2; + move16(); + } +#else IF( q_U_1 != 0 ) { *q_U = q_U_1; @@ -3629,6 +3651,7 @@ static void eig2x2_fx( *q_U = q_U_2; } move16(); +#endif return; } @@ -4508,7 +4531,11 @@ static void formulate2x2MixingMatrix_fx( ELSE { push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, maxEne_fx, &exp ); +#else maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); +#endif pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } @@ -4630,6 +4657,11 @@ static void formulate2x2MixingMatrix_fx( } ELSE { + if ( E_out2 == 0 ) + { + static int a = 0; + a++; + } temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); @@ -4777,7 +4809,12 @@ static void formulate2x2MixingMatrix_fx( ELSE { push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[0], &exp ); +#else + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); +#endif exp = sub( exp, sub( Q30, q_D ) ); pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ } @@ -4811,7 +4848,11 @@ static void formulate2x2MixingMatrix_fx( ELSE { push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[1], &exp1 ); +#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); +#endif pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } @@ -5021,7 +5062,11 @@ static void formulate2x2MixingMatrix_fx( Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); push_wmops( "formulate2x2MixingMatrix Division" ); +#ifdef FIX_1326_SPEEDUP_17 + temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, temp, &exp ); +#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); +#endif pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); -- GitLab From 3a0cffad0b3aa100c59fde2e9ad9b196ea356718 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:41:59 +0100 Subject: [PATCH 0608/1221] add modified version of division '1/x' --- lib_com/basop_util.c | 35 +++++++++++++++++++++++++++++++++++ lib_com/basop_util.h | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 609ca234d..0449ff125 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1066,6 +1066,41 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) return z; } +/*1bit HR in x > 0*/ +Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) +{ + Word32 z; + //Word16 sx; + Word16 sy; + Word32 sign; + + /* assert (x >= (Word32)0); */ + assert( y != (Word32) 0 ); + + sign = 0; + move16(); + + IF( y < 0 ) + { + y = L_negate( y ); + sign = L_xor( sign, 1 ); + } + + sy = norm_l( y ); + y = L_shl( y, sy ); + move16(); + *s = add( 0, sy ); + move16(); + + z = div_w( x, y ); + + if ( sign != 0 ) + { + z = L_negate( z ); + } + return z; + +} Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { Word16 z; diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index a6db7dc8d..697f0b9c6 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -332,6 +332,10 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word32 y, /*!< i : Denominator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ +Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ + + Word16 *s ); /*!< o : Additional scalefactor difference*/ /************************************************************************/ /*! -- GitLab From 3d2baa32087e1f1c306173c1f2e1c42abe211064 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:46:15 +0100 Subject: [PATCH 0609/1221] applied clang format patch --- lib_com/basop_util.c | 3 +-- lib_com/basop_util.h | 6 +++--- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 0449ff125..5eee369f8 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1070,7 +1070,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) { Word32 z; - //Word16 sx; + // Word16 sx; Word16 sy; Word32 sign; @@ -1099,7 +1099,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) z = L_negate( z ); } return z; - } Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 697f0b9c6..1ef2cd8e7 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -332,10 +332,10 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word32 y, /*!< i : Denominator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ -Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ - Word32 y, /*!< i : Denominator*/ +Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ - Word16 *s ); /*!< o : Additional scalefactor difference*/ + Word16 *s ); /*!< o : Additional scalefactor difference*/ /************************************************************************/ /*! diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 3a10590f6..399ac50ca 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3372,7 +3372,7 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 +#ifdef FIX_1326_SPEEDUP_03 tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) @@ -3630,13 +3630,13 @@ static void eig2x2_fx( } } #ifdef FIX_1326_SPEEDUP_18 - if( q_U_1 != 0 ) + if ( q_U_1 != 0 ) { *q_U = q_U_1; move16(); } - if (q_U_1 == 0) + if ( q_U_1 == 0 ) { *q_U = q_U_2; move16(); @@ -4812,7 +4812,7 @@ static void formulate2x2MixingMatrix_fx( #ifdef FIX_1326_SPEEDUP_17 temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[0], &exp ); #else - + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); #endif exp = sub( exp, sub( Q30, q_D ) ); -- GitLab From a5afdebd29f50e791a8e28b08238d9b3e3a17288 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 08:47:08 +0100 Subject: [PATCH 0610/1221] activated SPEEDUP 17, 18, for test --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 399ac50ca..682a881cd 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -61,8 +61,8 @@ //#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? -//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? +#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? +#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From aae527e7587b9c3d377db06797222a69456bfe09 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 09:35:17 +0100 Subject: [PATCH 0611/1221] Activate all SPEEDUP macros available and change division 1/x a bit --- lib_com/basop_util.c | 8 +++-- .../ivas_dirac_dec_binaural_functions_fx.c | 35 ++++++++++--------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 5eee369f8..60174c3c9 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1080,12 +1080,16 @@ Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) sign = 0; move16(); - IF( y < 0 ) + if( y < 0 ) { - y = L_negate( y ); sign = L_xor( sign, 1 ); } + if ( y < 0 ) + { + y = L_negate( y ); + } + sy = norm_l( y ); y = L_shl( y, sy ); move16(); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 682a881cd..f3e6b54d6 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,23 +46,24 @@ #include "wmc_auto.h" // MHZ NUMBERS: -// NULL: 179.292 - - -//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -//#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -//#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE -//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_17 // use 1/x // 1 WMOPS --> USE? -#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE? +// NULL: 178.407 +// ALL: 169.499 + + +#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET +#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE +#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE +#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From 38525c07c62527406c0c04d66a1f95c757d4b736 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 10:33:50 +0100 Subject: [PATCH 0612/1221] deactivate 1/x macro, activate all others --- lib_com/basop_util.c | 2 +- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 60174c3c9..273667255 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1080,7 +1080,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) sign = 0; move16(); - if( y < 0 ) + if ( y < 0 ) { sign = L_xor( sign, 1 ); } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f3e6b54d6..333e7603a 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -62,7 +62,7 @@ #define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE #define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE +//#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE #define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From 45c6f17c7b9c4fa732ce46c2742b0048e55a3d89 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 09:46:33 +0000 Subject: [PATCH 0613/1221] revert divison variation --- lib_com/basop_util.c | 44 +------------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 273667255..b7ee35ab3 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1010,7 +1010,6 @@ Word32 div_w( Word32 L_num, Word32 L_den ) } } - Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { Word32 z; @@ -1018,8 +1017,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) Word16 sy; Word32 sign; - // push_wmops( "BASOP_Util_Divide3232_Scale_cadence" ); - /* assert (x >= (Word32)0); */ assert( y != (Word32) 0 ); @@ -1041,7 +1038,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) IF( x == (Word32) 0 ) { *s = 0; - // pop_wmops(); return ( (Word32) 0 ); } @@ -1062,48 +1058,10 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { z = L_negate( z ); } - // pop_wmops(); - return z; -} - -/*1bit HR in x > 0*/ -Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, Word32 y, Word16 *s ) -{ - Word32 z; - // Word16 sx; - Word16 sy; - Word32 sign; - /* assert (x >= (Word32)0); */ - assert( y != (Word32) 0 ); - - sign = 0; - move16(); - - if ( y < 0 ) - { - sign = L_xor( sign, 1 ); - } - - if ( y < 0 ) - { - y = L_negate( y ); - } - - sy = norm_l( y ); - y = L_shl( y, sy ); - move16(); - *s = add( 0, sy ); - move16(); - - z = div_w( x, y ); - - if ( sign != 0 ) - { - z = L_negate( z ); - } return z; } + Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { Word16 z; -- GitLab From b372178a2c4a1c77cc6c3f08fc81a442ba894dae Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 09:47:44 +0000 Subject: [PATCH 0614/1221] more revert division variation --- lib_com/basop_util.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 1ef2cd8e7..a6db7dc8d 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -332,10 +332,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word32 y, /*!< i : Denominator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ -Word32 BASOP_Util_Divide3232_Scale_cadence_1( Word32 x, /*!< i : Numerator*/ - Word32 y, /*!< i : Denominator*/ - - Word16 *s ); /*!< o : Additional scalefactor difference*/ /************************************************************************/ /*! -- GitLab From 6ba452cc2c2961151899e7a4b230ff5d0a18e621 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 11:51:31 +0100 Subject: [PATCH 0615/1221] cleanup useless speedup macros --- .../ivas_dirac_dec_binaural_functions_fx.c | 123 +++--------------- 1 file changed, 15 insertions(+), 108 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 333e7603a..8da4f82e7 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -47,22 +47,16 @@ // MHZ NUMBERS: // NULL: 178.407 -// ALL: 169.499 +// ALL: 169.499 77 (170.650 wo 17) #define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE #define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -#define FIX_1326_SPEEDUP_03 // speedup eig2x2_fx // .1 WMOPS --> USE #define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE #define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_09 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -#define FIX_1326_SPEEDUP_10 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET -#define FIX_1326_SPEEDUP_11 // tiny speedup // .1 WMOPS pipe 48851 fails --> DONTUSEYET #define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE -#define FIX_1326_SPEEDUP_15 // replace Ladd(Mpy) -> Madd // .1 WMOPS --> USE #define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_17 // use 1/x // 1.25WMOPS --> USE #define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -1333,7 +1327,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } pop_wmops(); /*push_wmops( "IDRBCM apply EQ_low" );*/ - push_wmops( "IDRBCM target matrix" ); + push_wmops( "IDRBCM target matrix (IDRBCMtm)" ); /* Determine target covariance matrix containing target binaural properties */ FOR( bin = 0; bin < nBins; bin++ ) { @@ -1359,6 +1353,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh ) q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 ); // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f) /* Determine direct part target covariance matrix (for 1 or 2 directions) */ + push_wmops( "IDRBCMtm LOOP1" ); FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) { Word16 aziDeg, eleDeg; @@ -1437,6 +1432,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric diffuseness_fx = 0; move32(); } + IF( isIsmDirection ) { /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ @@ -1446,7 +1442,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric { diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/ } - IF( separateCenterChannelRendering ) { /* In masa + mono rendering mode, the center directions originate from phantom sources, so the @@ -1493,14 +1488,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word32 hrtfEneCenter_fx, hrtfEneSides_fx, hrtfEneRealized_fx; Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; -#ifdef FIX_1326_SPEEDUP_15 - hrtfEneCenter_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ), lImagp_fx, lImagp_fx ), lRealp_fx, lRealp_fx ); // Q25 -#else + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 -#endif + /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. * spreadCoh = 0: Only panning @@ -1529,14 +1522,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the left source of the three coherent sources */ getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); -#ifdef FIX_1326_SPEEDUP_15 - hrtfEneSides_fx = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), rImagpTmp_fx, rImagpTmp_fx ), lImagpTmp_fx, lImagpTmp_fx ), lRealpTmp_fx, lRealpTmp_fx ); // Q25 -#else + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 -#endif + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 @@ -1624,21 +1615,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); } -#ifdef FIX_1326_SPEEDUP_15 - hrtfEne_fx[0] = Madd_32_32( Mpy_32_32( lRealp_fx, lRealp_fx ), lImagp_fx, lImagp_fx ); // Q( 2*q_lr - 31 ) - hrtfEne_fx[1] = Madd_32_32( Mpy_32_32( rRealp_fx, rRealp_fx ), rImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) - move32(); - move32(); - hrtfCrossRe_fx = Madd_32_32( Mpy_32_32( lRealp_fx, rRealp_fx ), lImagp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) - hrtfCrossIm_fx = Madd_32_32( Mpy_32_32( -lImagp_fx, rRealp_fx ), lRealp_fx, rImagp_fx ); // Q( 2*q_lr - 31 ) -#else hrtfEne_fx[0] = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), Mpy_32_32( lImagp_fx, lImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfEne_fx[1] = L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), Mpy_32_32( rImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) move32(); move32(); hrtfCrossRe_fx = L_add( Mpy_32_32( lRealp_fx, rRealp_fx ), Mpy_32_32( lImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) hrtfCrossIm_fx = L_add( Mpy_32_32( -lImagp_fx, rRealp_fx ), Mpy_32_32( lRealp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) -#endif /* Add direct part (1 or 2) covariance matrix */ dirEne_fx = Mpy_32_32( ratio_fx, meanEnePerCh_fx ); // Q(q_meanEnePerCh - 1) @@ -1655,6 +1637,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); move32(); } + pop_wmops(); //push_wmops( "IDRBCMtm LOOP1" ); /* Add diffuse / ambient part covariance matrix */ diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 @@ -1713,11 +1696,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } ELSE { -#ifdef FIX_1326_SPEEDUP_15 - hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( Madd_32_16( L_shl( surCoh_fx, 16 ), hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); -#else hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( L_add( Mpy_32_16_1( hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), L_shl( surCoh_fx, 16 ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); -#endif } move32(); } @@ -1733,7 +1712,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } - pop_wmops(); /*push_wmops( "IDRBCM target matrix" );*/ + pop_wmops(); /*push_wmops( "IDRBCM target matrix (IDRBCMtm)" );;*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -2183,14 +2162,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); -#ifdef FIX_1326_SPEEDUP_11 - { - Word16 shift1 = s_max( 0, sub( q_tmp2, q_CrEne ) ); - Word16 shift2 = s_max( 0, sub( q_CrEne, q_tmp2 ) ); - realizedOutputEne_fx = L_add( L_shr( tmp1, shift2 ), L_shr( tmp2, shift1 ) ); - q_realizedOutputEne = s_min( q_CrEne, q_tmp2 ); - } -#else + IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); @@ -2203,7 +2175,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_realizedOutputEne = q_tmp2; move16(); } -#endif + exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 1 ); targetOutputEne_fx = L_add( L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ), L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ) ); q_targetOutputEne = add( hDiracDecBin->q_ChEneOut, exp ); @@ -3373,21 +3345,7 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ -#ifdef FIX_1326_SPEEDUP_03 - tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 - IF( LT_32( pm_fx, L_shl_sat( tmp1, sub( q_tmp1, q_tmp2 ) ) ) ) - { - Ure_fx[0][0] = ONE_IN_Q30; - move32(); - Ure_fx[1][1] = ONE_IN_Q30; - move32(); - *q_U = Q30; - move16(); - - return; - } -#else tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_16( q_tmp1, q_tmp2 ) ) @@ -3418,7 +3376,6 @@ static void eig2x2_fx( return; } } -#endif q_U_1 = 0; q_U_2 = 0; @@ -3472,11 +3429,7 @@ static void eig2x2_fx( #endif #if 1 -#ifdef FIX_1326_SPEEDUP_17 - tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); -#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); -#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3564,11 +3517,7 @@ static void eig2x2_fx( #endif #if 1 -#ifdef FIX_1326_SPEEDUP_17 - tmp2 = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, tmp3, &exp ); -#else tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); -#endif exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -4531,13 +4480,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, maxEne_fx, &exp ); -#else maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); -#endif - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4620,9 +4563,7 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp @@ -4664,9 +4605,7 @@ static void formulate2x2MixingMatrix_fx( a++; } temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - push_wmops( "formulate2x2MixingMatrix Division" ); temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4797,6 +4736,7 @@ static void formulate2x2MixingMatrix_fx( #endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ + IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4804,20 +4744,15 @@ static void formulate2x2MixingMatrix_fx( exp = sub( exp, sub( Q30, 62 ) ); #else temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + move32(); exp = ONE_DIV_EPSILON_EXP; + move16(); #endif } ELSE { - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[0], &exp ); -#else - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); -#endif exp = sub( exp, sub( Q30, q_D ) ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); @@ -4848,13 +4783,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, D_fx[1], &exp1 ); -#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); -#endif - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ exp1 = sub( exp1, sub( Q30, q_D ) ); } div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 @@ -4869,17 +4798,6 @@ static void formulate2x2MixingMatrix_fx( // 1310720000 = 10,000.0f in Q17 -#ifdef FIX_1326_SPEEDUP_09 - { - Word16 shift1 = s_max( sub( Q17, q_div ), 0 ); - Word16 shift2 = s_max( sub( q_div, Q17 ), 0 ); - - div_fx[0] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[0], shift2 ) ); // q_div - move32(); - div_fx[1] = L_min( L_shr( 1310720000, shift1 ), L_shr( div_fx[1], shift2 ) ); // q_div - move32(); - } -#else IF( LT_16( q_div, Q17 ) ) { div_fx[0] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[0] ); // q_div @@ -4896,7 +4814,6 @@ static void formulate2x2MixingMatrix_fx( q_div = Q17; move16(); } -#endif matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); @@ -4913,11 +4830,7 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpRe_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { -#ifdef FIX_1326_SPEEDUP_10 - hdrm_re[chA][chB] = W_norm( W_tmp ); -#else hdrm_re[chA][chB] = sub( W_norm( W_tmp ), 0 ); -#endif move16(); W_tmp = W_shl( W_tmp, hdrm_re[chA][chB] ); tmpRe_fx[chA][chB] = W_extract_h( W_tmp ); @@ -5062,13 +4975,7 @@ static void formulate2x2MixingMatrix_fx( { Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - push_wmops( "formulate2x2MixingMatrix Division" ); -#ifdef FIX_1326_SPEEDUP_17 - temp = BASOP_Util_Divide3232_Scale_cadence_1( ONE_IN_Q30, temp, &exp ); -#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); -#endif - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Division" )*/ q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); -- GitLab From 2f4289477bb50734e7a76d280226c897c5027656 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 11:54:30 +0100 Subject: [PATCH 0616/1221] apply clang format patch --- .../ivas_dirac_dec_binaural_functions_fx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 8da4f82e7..101f76a37 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1489,10 +1489,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; Word16 w1_fx, w2_fx, w3_fx, eq_fx; - hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 - L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 - L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 - Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 + L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 + L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 + Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. * The following formulas determine the gains for these sources. @@ -1523,10 +1523,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the left source of the three coherent sources */ getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); - hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 - L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 - L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 - Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 + L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 + L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 + Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 @@ -1637,7 +1637,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); move32(); } - pop_wmops(); //push_wmops( "IDRBCMtm LOOP1" ); + pop_wmops(); // push_wmops( "IDRBCMtm LOOP1" ); /* Add diffuse / ambient part covariance matrix */ diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 -- GitLab From deed66fec4fd1df35c794f25dbe636f224c31cdc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 12:00:04 +0100 Subject: [PATCH 0617/1221] deactivate all speedups --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 101f76a37..4a55a37cc 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -50,14 +50,14 @@ // ALL: 169.499 77 (170.650 wo 17) -#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE +//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE + +//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; -- GitLab From 2f158f47a3bab10f597dc5dbb245e40676bbc61f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 12:16:25 +0000 Subject: [PATCH 0618/1221] cleaup a bit --- .../ivas_dirac_dec_binaural_functions_fx.c | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 4a55a37cc..ce36e0ae3 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1432,7 +1432,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric diffuseness_fx = 0; move32(); } - IF( isIsmDirection ) { /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ @@ -1442,6 +1441,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric { diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/ } + IF( separateCenterChannelRendering ) { /* In masa + mono rendering mode, the center directions originate from phantom sources, so the @@ -1527,11 +1527,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 - - lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 - lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 - rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 - rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 + lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 + rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 + rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 /* Apply the gain for the right source of the three coherent sources. * -30 degrees to 330 wrapping due to internal functions. */ @@ -2162,7 +2161,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); - IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); @@ -2198,6 +2196,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_missingOutputEne = q_targetOutputEne; move16(); } + tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); #ifdef FIX_1326_SPEEDUP_13 @@ -2258,7 +2257,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_processMtxDec_bin = q_processMtxDec[bin]; move16(); move16(); - /* Store processing matrices */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -3216,6 +3214,7 @@ static void eig2x2_fx( a_fx = (e1 + e2) * (e1 + e2) - 4.0f * ((e1 * e2) - crossSquare_fx) = (e1 - e2)^2 + 4 * crossSquare_fx pm_fx = 0.5f * sqrtf(max(0.0f, a_fx)) add_fx = 0.5f * (e1 + e2)*/ + IF( L_and( c_re == 0, c_im == 0 ) ) { /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0 @@ -3345,7 +3344,6 @@ static void eig2x2_fx( #endif /* Numeric case, when input is near an identity matrix with a gain */ - tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 IF( LT_16( q_tmp1, q_tmp2 ) ) @@ -3425,6 +3423,7 @@ static void eig2x2_fx( #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); + tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); #endif @@ -3513,6 +3512,7 @@ static void eig2x2_fx( #else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); + tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); #endif @@ -4563,13 +4563,13 @@ static void formulate2x2MixingMatrix_fx( ELSE { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif } - #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp #endif @@ -4599,19 +4599,14 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - if ( E_out2 == 0 ) - { - static int a = 0; - a++; - } temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); #ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif } - #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 #endif @@ -4796,7 +4791,6 @@ static void formulate2x2MixingMatrix_fx( div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); // q_div move32(); - // 1310720000 = 10,000.0f in Q17 IF( LT_16( q_div, Q17 ) ) { -- GitLab From 58910c3860c2b7207f8c0564e876a9c0f0f13d8d Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 13:54:05 +0100 Subject: [PATCH 0619/1221] activate the big chunks - SPEEDUP 8, 13 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index ce36e0ae3..f63f27eb0 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -53,8 +53,8 @@ //#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE //#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE //#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -//#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE +#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE +#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE //#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE //#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE -- GitLab From bd0e99e7ebb01473578e95e36bfaca331d4e4fbe Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 14:32:17 +0100 Subject: [PATCH 0620/1221] activated spedups 1 , 2, 4, 16, 18 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f63f27eb0..7dee99218 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -50,14 +50,14 @@ // ALL: 169.499 77 (170.650 wo 17) -//#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -//#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -//#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE +#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE +#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE #define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE #define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE -//#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -//#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE +#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE +#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -4618,7 +4618,7 @@ static void formulate2x2MixingMatrix_fx( move32(); Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); - pop_wmops(); + pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix RegSMInv" );*/ /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) -- GitLab From b3b061a24408282095e8ca07e2fd9bf23aba388d Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 15:56:56 +0100 Subject: [PATCH 0621/1221] rename optimiztion macros, move macros to options.h --- .../ivas_dirac_dec_binaural_functions_fx.c | 140 +----------------- 1 file changed, 8 insertions(+), 132 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7dee99218..7f2c6b4d4 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -46,18 +46,6 @@ #include "wmc_auto.h" // MHZ NUMBERS: -// NULL: 178.407 -// ALL: 169.499 77 (170.650 wo 17) - - -#define FIX_1326_SPEEDUP_01 // optimize matrixT1mul->eig2x2_fx // .4 WMOPS --> USE -#define FIX_1326_SPEEDUP_02 // speedup eig2x2_fx // .3 WMOPS --> USE -#define FIX_1326_SPEEDUP_04 // speedup eig2x2_fx // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_08 // "-" // 3.0 WMOPS //small diffs --> USE -#define FIX_1326_SPEEDUP_13 // replace div/sqrt->isqrt // 2.9 WMOPS --> USE - -#define FIX_1326_SPEEDUP_16 // tiny speedup like 04 // .2 WMOPS --> USE -#define FIX_1326_SPEEDUP_18 // structural speedup // 1 WMOPS --> USE Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; @@ -1892,11 +1880,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); Word32 tmp1, tmp2, res1, res2; Word16 q_tmp1, q_tmp2, q_realizedOutputEne, q_targetOutputEne, q_missingOutputEne, q_gain; -#ifdef FIX_1326_SPEEDUP_13 - Word16 exp1, q_processMtx_bin, q_processMtxDec_bin; -#else Word16 exp1, exp2, q_processMtx_bin, q_processMtxDec_bin; -#endif CrEneL_fx = 0; move32(); @@ -2199,13 +2183,12 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); -#ifdef FIX_1326_SPEEDUP_13 +#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT { - Word16 exp_temp; - tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - tmp2 = ISqrt32( tmp2, &exp_temp ); + tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp2 ); + tmp2 = ISqrt32( tmp2, &exp2 ); gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) ); - q_gain = sub( 31, add( exp_temp, exp1 ) ); + q_gain = sub( 31, add( exp2, exp1 ) ); } #else { @@ -3317,7 +3300,7 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) -#ifdef FIX_1326_SPEEDUP_02 +#ifdef FIX_1326_SUBSTITUTE_CMPMANT32EXP IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { Ure_fx[0][0] = ONE_IN_Q31; @@ -3406,27 +3389,10 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); - -#ifdef FIX_1326_SPEEDUP_16 - - { - Word16 tmp2_exp; - Word32 eps_tmp; - tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &tmp2_exp ); - - // Add epsilon if relevant - eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, tmp2_exp ) ); - tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); - - exp_tmp3 = add( tmp2_exp, 1 ); - } -#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); -#endif - #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); @@ -3499,22 +3465,10 @@ static void eig2x2_fx( q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); -#ifdef FIX_1326_SPEEDUP_04 - Word16 exp_tmp2; - Word32 eps_tmp; - - tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &exp_tmp2 ); - eps_tmp = L_shl_sat( epsilon_mant, sub( epsilon_exp, exp_tmp2 ) ); - - tmp3 = L_add( L_shr( tmp2, 1 ), L_shr( eps_tmp, 1 ) ); // Add Epsilon if relevant - - exp_tmp3 = add( exp_tmp2, 1 ); -#else tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); -#endif #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); @@ -3815,7 +3769,6 @@ static void matrixMul_fx( return; } -#ifndef FIX_1326_SPEEDUP_01 static void matrixTransp1Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -3929,7 +3882,6 @@ static void matrixTransp1Mul_fx( return; } -#endif /*FIX_1326_SPEEDUP_01*/ static void matrixTransp2Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -4655,80 +4607,10 @@ static void formulate2x2MixingMatrix_fx( /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ push_wmops( "oPtoA MT1M" ); -#ifdef FIX_1326_SPEEDUP_01 - // matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); - - { - // Word16 chA, chB; - { - chA = 0, chB = 0; - tmpRe_fx[0][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][0], Are_fx[0][0] ), - Are_fx[1][0], Are_fx[1][0] ), - Aim_fx[0][0], Aim_fx[0][0] ), - Aim_fx[1][0], Aim_fx[1][0] ); - move32(); - } - { - // chA = 0, chB = 1; - tmpRe_fx[1][0] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][0] ), - Are_fx[1][1], Are_fx[1][0] ), - Aim_fx[0][1], Aim_fx[0][0] ), - Aim_fx[1][1], Aim_fx[1][0] ); - move32(); - tmpIm_fx[1][0] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Aim_fx[0][0] ), - Are_fx[1][1], Aim_fx[1][0] ), - Aim_fx[0][1], Are_fx[0][0] ), - Aim_fx[1][1], Are_fx[1][0] ); - move32(); - } - { - // chA = 1, chB = 0; - tmpRe_fx[1][1] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][1], Are_fx[0][1] ), - Are_fx[1][1], Are_fx[1][1] ), - Aim_fx[0][1], Aim_fx[0][1] ), - Aim_fx[1][1], Aim_fx[1][1] ); - move32(); - } - { - // chA = 1, chB = 1; - } - - q_temp = sub( add( q_A, q_A ), 31 ); - - move16(); - Word16 ZeroState = add( 1, 0 ); - if ( tmpRe_fx[0][0] != 0 ) - { - ZeroState = add( 0, 0 ); - } - if ( tmpRe_fx[1][1] != 0 ) - { - ZeroState = add( 0, 0 ); - } - if ( tmpRe_fx[1][0] != 0 ) - { - ZeroState = add( 0, 0 ); - } - if ( tmpIm_fx[1][0] != 0 ) - { - ZeroState = add( 0, 0 ); - } - - if ( sub( ZeroState, 1 ) == 0 ) - { - q_temp = Q31; - move16(); - } - } - - - eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#else matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); -#endif pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ @@ -4753,11 +4635,9 @@ static void formulate2x2MixingMatrix_fx( move32(); #ifdef FIX_1326_SPEEDUP_08 - // This is just a shortcut to already existing optimizations (FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC) - but makes everything even faster - { - div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 - exp1 = add( 0, 20 ); // move32(); - } + //Sqrt(1) + div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 + exp1 = add( 0, 20 ); IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt { @@ -4841,11 +4721,7 @@ static void formulate2x2MixingMatrix_fx( W_tmp = W_mult0_32_32( tmpIm_fx[chA][chB], div_fx[chB] ); IF( W_tmp != 0 ) { -#ifdef FIX_1326_SPEEDUP_10 - hdrm_im[chA][chB] = W_norm( W_tmp ); -#else hdrm_im[chA][chB] = sub( W_norm( W_tmp ), 0 ); -#endif move16(); W_tmp = W_shl( W_tmp, hdrm_im[chA][chB] ); tmpIm_fx[chA][chB] = W_extract_h( W_tmp ); -- GitLab From e97ec324fd308f6a492143ca03e7d28118b1eeb0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 15:06:07 +0000 Subject: [PATCH 0622/1221] fix: rename some mocros Cleanup: push/pop wmops --- .../ivas_dirac_dec_binaural_functions_fx.c | 67 ++----------------- 1 file changed, 6 insertions(+), 61 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 7f2c6b4d4..e8052b08c 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -45,8 +45,6 @@ #include "wmc_auto.h" -// MHZ NUMBERS: - Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; /*------------------------------------------------------------------------- @@ -506,9 +504,8 @@ void ivas_dirac_dec_binaural_render_fx( FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); - push_wmops( "IDR binaural internal (IDRBI)" ); ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx ); - pop_wmops(); /*push_wmops( "IDR binaural internal (IDRBI)" );*/ + FOR( ch = 0; ch < nchan_out; ch++ ) { output_fx_local[ch] += n_samples_sf; @@ -711,7 +708,6 @@ static void ivas_dirac_dec_binaural_internal_fx( } } /* CLDFB Analysis of input */ - push_wmops( "IDRBI CLDFB ANALYSYS" ); FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { FOR( ch = 0; ch < numInChannels; ch++ ) @@ -861,7 +857,6 @@ static void ivas_dirac_dec_binaural_internal_fx( } } } - pop_wmops(); /*push_wmops( "IDRBI CLDFB ANALYSYS" );*/ test(); IF( EQ_32( config_data.ivas_format, SBA_FORMAT ) || EQ_32( config_data.ivas_format, SBA_ISM_FORMAT ) ) @@ -926,9 +921,7 @@ static void ivas_dirac_dec_binaural_internal_fx( } test(); - push_wmops( "IDRBI cov matrices (IDRBCM)" ); ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); - pop_wmops(); /*push_wmops( "IDRBI cov matrices (IDRBCM)" );*/ IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -966,9 +959,7 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); } - push_wmops( "IDRBI proc matrices (IRDBI pm)" ); ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); - pop_wmops(); /*push_wmops( "IDRBI proc matrices (IRDBI pm)" );*/ q_inp = Q6; move16(); @@ -1014,10 +1005,8 @@ static void ivas_dirac_dec_binaural_internal_fx( hDiracDecBin->q_processMtxDecPrev = q_mat; move16(); - push_wmops( "IDRBI processOutput" ); ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); - pop_wmops(); /*push_wmops( "IDRBI processOutput" ); - */ + hDiracDecBin->hDiffuseDist = NULL; hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); @@ -1151,7 +1140,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ move16(); - push_wmops( "IDRBCM inits" ); + q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) ); scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) ); hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; @@ -1185,7 +1174,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ move16(); } - pop_wmops(); /*push_wmops( "IDRBCM inits" );*/ /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ applyLowBitRateEQ = 0; @@ -1198,13 +1186,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); IF( EQ_32( ivas_total_brate, IVAS_16k4 ) ) { - push_wmops( "IDRBCM Determine EQ_low_rates" ); FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) { lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = L_add( L_shr( lowBitRateBinauralEQ_fx[bin], 1 ), ONE_IN_Q30 ); // Q31 move32(); } - pop_wmops(); /*push_wmops( "IDRBCM Determine EQ_low_rates" );*/ } ELSE { @@ -1223,7 +1209,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below - push_wmops( "IDRBCM input Matrix" ); /* Calculate input covariance matrix */ FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) { @@ -1258,9 +1243,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); } } - pop_wmops(); /*push_wmops( "IDRBCM input Matrix" );*/ - push_wmops( "IDRBCM apply EQ_low" ); /* Apply EQ at low bit rates */ IF( applyLowBitRateEQ != 0 ) { @@ -1313,9 +1296,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } } } - pop_wmops(); /*push_wmops( "IDRBCM apply EQ_low" );*/ - push_wmops( "IDRBCM target matrix (IDRBCMtm)" ); /* Determine target covariance matrix containing target binaural properties */ FOR( bin = 0; bin < nBins; bin++ ) { @@ -1341,7 +1322,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh ) q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 ); // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f) /* Determine direct part target covariance matrix (for 1 or 2 directions) */ - push_wmops( "IDRBCMtm LOOP1" ); FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) { Word16 aziDeg, eleDeg; @@ -1624,7 +1604,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); move32(); } - pop_wmops(); // push_wmops( "IDRBCMtm LOOP1" ); /* Add diffuse / ambient part covariance matrix */ diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 @@ -1699,7 +1678,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); } - pop_wmops(); /*push_wmops( "IDRBCM target matrix (IDRBCMtm)" );;*/ test(); /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ @@ -1865,7 +1843,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); } - push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" ); FOR( bin = 0; bin < nBins; bin++ ) { Word32 tmpMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], gain_fx; @@ -1889,7 +1866,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_CrEne = Q31; move16(); - push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" ); IF( GT_16( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ) { hDiracDecBin->ChEne_fx[1][bin] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ); @@ -1959,9 +1935,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->q_ChCrossOut, prototypeMtx_fx, Mre_fx, Mim_fx, &q_M, hDiracDecBin->reqularizationFactor_fx ); - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec A (formulate2x2MixingMatrix)" );*/ - push_wmops( "IDRBI pm LOOP1 sec B" ); IF( LT_16( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ) { CxRe_fx[0][0] = hDiracDecBin->ChEne_fx[0][bin]; @@ -2015,13 +1989,9 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( #endif resultMtxRe_fx, resultMtxIm_fx, &q_res ); - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec B" );*/ - /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */ - - push_wmops( "IDRBI pm LOOP1 sec C" ); IF( LT_16( bin, max_band_decorr ) ) { Word32 decorrelationReductionFactor_fx; @@ -2137,9 +2107,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( q_Mdec = Q31; move16(); } - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec C" );*/ - push_wmops( "IDRBI pm LOOP1 sec D" ); /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */ tmp1 = L_add( CrEneL_fx, CrEneR_fx ); exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); @@ -2274,10 +2242,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( move16(); q_processMtxDec[bin] = sub( q_Mdec, 16 ); move16(); - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec D" );*/ - - push_wmops( "IDRBI pm LOOP1 sec E" ); IF( separateCenterChannelRendering ) { /* The rendering of the separate center channel in masa + mono mode. @@ -2367,10 +2332,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } - pop_wmops(); /*push_wmops( "IDRBI pm LOOP1 sec E" );*/ } - pop_wmops(); /*push_wmops( "IRDBI pm LOOP1 (IDRBI pm LOOP1)" );*/ - /* Aligning Q-factors of all bins in the processing matrices to a common Q-factor */ minimum_s( q_processMtx, nBins, &hDiracDecBin->q_processMtx ); minimum_s( q_processMtxPrev, nBins, &hDiracDecBin->q_processMtxPrev ); @@ -2390,7 +2352,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( minimum_s( q_processMtxDec, nBins, &hDiracDecBin->q_processMtxDec ); minimum_s( q_processMtxDecPrev, nBins, &hDiracDecBin->q_processMtxDecPrev ); - push_wmops( "IRDBI pm LOOP2" ); FOR( bin = 0; bin < nBins; bin++ ) { FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -2430,7 +2391,6 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } } } - pop_wmops(); /*push_wmops( "IRDBI pm LOOP2" );*/ return; } @@ -3393,6 +3353,7 @@ static void eig2x2_fx( q_tmp2 = sub( 31, q_tmp2 ); tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); + #if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); @@ -3464,7 +3425,6 @@ static void eig2x2_fx( tmp2 = Mpy_32_32( s_fx, s_fx ); q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 ); - tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); q_tmp2 = sub( 31, q_tmp2 ); @@ -3533,7 +3493,7 @@ static void eig2x2_fx( move16(); } } -#ifdef FIX_1326_SPEEDUP_18 +#ifdef FIX_1326_SPEEDUP_eig2x2_fx if ( q_U_1 != 0 ) { *q_U = q_U_1; @@ -4455,12 +4415,9 @@ static void formulate2x2MixingMatrix_fx( Cout_im = Mpy_32_32( Cout_im, maxEneDiv_fx ); q_cout = sub( add( q_cout, q_maxEneDiv ), 31 ); - push_wmops( "formulate2x2MixingMatrix cholesky" ); /* Cholesky decomposition of target / output covariance matrix */ chol2x2_fx( E_out1, E_out2, q_eout, Cout_re, Cout_im, q_cout, KyRe_fx, KyIm_fx, &q_ky ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix cholesky" );*/ - push_wmops( "formulate2x2MixingMatrix Eigendecomp" ); /* Eigendecomposition of input covariance matrix */ eig2x2_fx( E_in1, E_in2, q_ein, Cin_re, Cin_im, q_cin, Uxre_fx, Uxim_fx, &q_Ux, Sx_fx, &q_Sx ); @@ -4478,9 +4435,7 @@ static void formulate2x2MixingMatrix_fx( move32(); matrixDiagMul_fx( Uxre_fx, Uxim_fx, q_Ux, Sx_fx, q_Sx, Kxre_fx, Kxim_fx, &q_Kx ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Eigendecomp" );*/ - push_wmops( "formulate2x2MixingMatrix RegSMInv" ); /* Regularize the diagonal Sx for matrix inversion */ Sx_fx[0] = L_max( L_shr( Sx_fx[0], 1 ), Mpy_32_16_1( Sx_fx[1], regularizationFactor_fx ) ); Sx_fx[1] = L_max( L_shr( Sx_fx[1], 1 ), L_shl( Mpy_32_16_1( Sx_fx[0], regularizationFactor_fx ), 1 ) ); @@ -4570,7 +4525,6 @@ static void formulate2x2MixingMatrix_fx( move32(); Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix RegSMInv" );*/ /* Matrix multiplication, tmp = Ky' * G_hat * Q */ FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -4603,17 +4557,12 @@ static void formulate2x2MixingMatrix_fx( /* A = Ky' * G_hat * Q * Kx (see publication) */ matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); - push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx For matrix A that is P = A(A'A)^0.5 */ - push_wmops( "oPtoA MT1M" ); matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp ); eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); - pop_wmops(); /*push_wmops( "oPtoA MT1M" );*/ - - IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4634,7 +4583,7 @@ static void formulate2x2MixingMatrix_fx( div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#ifdef FIX_1326_SPEEDUP_08 +#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT //Sqrt(1) div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 exp1 = add( 0, 20 ); @@ -4760,9 +4709,7 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix nrst orthonrm PtoA (oPtoA)" );*/ - push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" ); /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ #if ( BINAURAL_CHANNELS != 2 ) FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -4916,8 +4863,6 @@ static void formulate2x2MixingMatrix_fx( 0 /*int Bscale*/, #endif Mre_fx, Mim_fx, q_M ); - pop_wmops(); /*push_wmops( "formulate2x2MixingMatrix Ky P Kx^-1" );*/ - return; } -- GitLab From 133ff3454de12dab5071edcad4ba1c5831b9e509 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 19 Mar 2025 16:44:16 +0100 Subject: [PATCH 0623/1221] apply clang format patch --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index e8052b08c..be86281ef 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4584,9 +4584,9 @@ static void formulate2x2MixingMatrix_fx( move32(); #ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT - //Sqrt(1) + // Sqrt(1) div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 - exp1 = add( 0, 20 ); + exp1 = add( 0, 20 ); IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt { -- GitLab From 6a3d32f5fc301c4af2dc2d946263172e9cdd27d8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Mar 2025 07:55:08 +0000 Subject: [PATCH 0624/1221] revert:push_wmops: renamed label --- lib_dec/ivas_jbm_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index ce60c0d65..1918ce3f3 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1875,7 +1875,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - push_wmops( "ivas_dec_render (IDR)" ); + push_wmops( "ivas_dec_render" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ -- GitLab From 008633965b65860ce39d557f082be18ff7424330 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Mar 2025 09:52:45 +0100 Subject: [PATCH 0625/1221] introduce FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 --- .../ivas_dirac_dec_binaural_functions_fx.c | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index be86281ef..141fe8c4b 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +#define FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 #include #include "options.h" #include @@ -4563,6 +4563,28 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); + +#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 + IF( D_fx[0] == 0 ) + { +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 + exp = sub( exp, sub( Q30, 62 ) ); +#else + temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + move32(); + exp = ONE_DIV_EPSILON_EXP; + move16(); +#endif + div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + move32(); + } + ELSE + { + exp = sub( 31, q_D ); + div_fx[0] = ISqrt32( D_fx[0], &exp ); + } +#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4582,6 +4604,7 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); +#endif /*FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2*/ #ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT // Sqrt(1) -- GitLab From 2f5ee23c86dd5b2145aca5febf5d7a65449ead0b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 20 Mar 2025 10:40:35 +0100 Subject: [PATCH 0626/1221] Revert "introduce FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2" This reverts commit 18d10e60341ba2cd76c8161c396c02a8e7293290. --- .../ivas_dirac_dec_binaural_functions_fx.c | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 141fe8c4b..be86281ef 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ -#define FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 + #include #include "options.h" #include @@ -4563,28 +4563,6 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); - -#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2 - IF( D_fx[0] == 0 ) - { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 - exp = sub( exp, sub( Q30, 62 ) ); -#else - temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - move32(); - exp = ONE_DIV_EPSILON_EXP; - move16(); -#endif - div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp - move32(); - } - ELSE - { - exp = sub( 31, q_D ); - div_fx[0] = ISqrt32( D_fx[0], &exp ); - } -#else IF( D_fx[0] == 0 ) { #ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC @@ -4604,7 +4582,6 @@ static void formulate2x2MixingMatrix_fx( } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#endif /*FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT_2*/ #ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT // Sqrt(1) -- GitLab From be7d8ed1ac65f84906e8710a18301a4f5212ec91 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 10:26:18 +0530 Subject: [PATCH 0627/1221] Scaling related fix in ivas_enc_fx --- lib_enc/ivas_enc_fx.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index e8e1bc59e..ff5f65b32 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -344,13 +344,22 @@ ivas_error ivas_enc_fx( { norm_data_in = s_min( norm_data_in, L_norm_arr( data_fx[i], input_frame ) ); } - norm_data_in = sub( norm_data_in, 7 ); /*guard bit is 4->to handle overflow in cldfbAnalysis*/ - FOR( i = 0; i < hEncoderConfig->nchan_ism + st_ivas->nchan_transport; i++ ) + IF( LT_16( norm_data_in, 31 ) ) + { + norm_data_in = sub( norm_data_in, 7 ); /*guard bit is 4->to handle overflow in cldfbAnalysis*/ + norm_data_in = s_min( norm_data_in, 20 ); // limit Q to 31 (11 + norm) + FOR( i = 0; i < hEncoderConfig->nchan_ism + st_ivas->nchan_transport; i++ ) + { + scale_sig32( data_fx[i], input_frame, norm_data_in ); /* st_ivas->q_data_fx + norm_data_in */ + } + st_ivas->q_data_fx = add( st_ivas->q_data_fx, norm_data_in ); + move16(); + } + ELSE { - scale_sig32( data_fx[i], input_frame, norm_data_in ); /* st_ivas->q_data_fx + norm_data_in */ + st_ivas->q_data_fx = 31; + move16(); } - st_ivas->q_data_fx = add( st_ivas->q_data_fx, norm_data_in ); - move16(); } /* Estimate MASA parameters for the objects */ -- GitLab From ee02c290eea286b0afbbe5283ef69ee93a229428 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 16:08:21 +0530 Subject: [PATCH 0628/1221] Cleanup of pre-processor macros in the main branch --- apps/renderer.c | 4 - lib_com/basop32.c | 4 - lib_com/bits_alloc_fx.c | 62 -- lib_com/bitstream_fx.c | 2 - lib_com/cldfb.c | 6 - lib_com/cnst.h | 2 - lib_com/disclaimer.c | 4 - lib_com/edct_fx.c | 2 - lib_com/fft_fx.c | 26 - lib_com/gs_bitallocation_fx.c | 2 - lib_com/gs_inact_switching_fx.c | 9 - lib_com/ivas_dirac_com_fx.c | 68 -- lib_com/ivas_prot_fx.h | 28 - lib_com/ivas_qmetadata_com_fx.c | 68 -- lib_com/ivas_spar_com_fx.c | 18 - lib_com/ivas_tools_fx.c | 221 ------- lib_com/lerp.c | 4 - lib_com/low_rate_band_att_fx.c | 4 - lib_com/lsf_tools_fx.c | 2 - lib_com/mslvq_com_fx.c | 8 - lib_com/options.h | 71 --- lib_com/prot_fx.h | 15 - lib_com/rom_com.c | 12 - lib_com/swb_bwe_com_fx.c | 16 - lib_com/swb_bwe_com_lr_fx.c | 4 - lib_com/swb_tbe_com_fx.c | 10 - lib_com/tcq_position_arith_fx.c | 8 - lib_com/tcx_mdct_fx.c | 6 - lib_com/tools.c | 45 -- lib_com/tools_fx.c | 59 -- lib_com/trans_direct_fx.c | 2 - lib_com/trans_inv_fx.c | 6 - lib_dec/FEC_HQ_phase_ecu_fx.c | 28 - lib_dec/FEC_fx.c | 8 - lib_dec/TonalComponentDetection_fx.c | 8 - lib_dec/acelp_core_dec_fx.c | 10 - lib_dec/acelp_core_dec_ivas_fx.c | 166 ----- lib_dec/acelp_core_switch_dec_fx.c | 12 - lib_dec/core_switching_dec_fx.c | 27 - lib_dec/dec_gen_voic_fx.c | 4 - lib_dec/dec_tcx_fx.c | 34 - lib_dec/decision_matrix_dec_fx.c | 2 - lib_dec/fd_cng_dec_fx.c | 14 - lib_dec/gs_dec_fx.c | 16 - lib_dec/hq_core_dec_fx.c | 5 - lib_dec/hq_hr_dec_fx.c | 10 - lib_dec/igf_dec_fx.c | 45 -- lib_dec/init_dec_fx.c | 6 - lib_dec/ivas_binRenderer_internal_fx.c | 70 --- lib_dec/ivas_core_dec_fx.c | 75 --- lib_dec/ivas_cpe_dec_fx.c | 8 - lib_dec/ivas_dirac_dec_fx.c | 20 - lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 144 ----- lib_dec/ivas_init_dec.c | 2 - lib_dec/ivas_ism_param_dec_fx.c | 6 - lib_dec/ivas_jbm_dec_fx.c | 97 --- lib_dec/ivas_mc_param_dec_fx.c | 69 -- lib_dec/ivas_mc_paramupmix_dec_fx.c | 14 - lib_dec/ivas_mct_dec_fx.c | 28 - lib_dec/ivas_mct_dec_mct_fx_fx.c | 24 - lib_dec/ivas_mdct_core_dec_fx.c | 33 - lib_dec/ivas_omasa_dec_fx.c | 8 - lib_dec/ivas_osba_dec_fx.c | 12 - lib_dec/ivas_out_setup_conversion_fx.c | 2 - lib_dec/ivas_post_proc_fx.c | 24 - lib_dec/ivas_qmetadata_dec_fx.c | 22 - lib_dec/ivas_sba_dec_fx.c | 22 - lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 20 - lib_dec/ivas_spar_decoder_fx.c | 153 ----- lib_dec/ivas_stat_dec.h | 2 - lib_dec/ivas_stereo_cng_dec.c | 4 - lib_dec/ivas_stereo_dft_dec_fx.c | 42 -- lib_dec/ivas_stereo_ica_dec_fx.c | 5 - lib_dec/ivas_stereo_icbwe_dec_fx.c | 14 - lib_dec/ivas_stereo_mdct_core_dec_fx.c | 5 - lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 5 - lib_dec/ivas_stereo_switching_dec_fx.c | 10 - lib_dec/ivas_svd_dec_fx.c | 592 ------------------ lib_dec/ivas_tcx_core_dec_fx.c | 18 - lib_dec/ivas_td_low_rate_dec_fx.c | 5 - lib_dec/jbm_pcmdsp_apa.c | 2 - lib_dec/lead_deindexing_fx.c | 4 - lib_dec/lib_dec_fx.c | 82 --- lib_dec/stat_dec.h | 9 - lib_dec/swb_tbe_dec_fx.c | 6 - lib_dec/tonalMDCTconcealment_fx.c | 20 - lib_dec/transition_dec_fx.c | 4 - lib_dec/waveadjust_fec_dec_fx.c | 16 - lib_enc/acelp_core_enc_fx.c | 40 -- lib_enc/acelp_core_switch_enc_fx.c | 8 - lib_enc/bass_psfilter_enc_fx.c | 4 - lib_enc/cng_enc_fx.c | 2 - lib_enc/cod_ace_fx.c | 43 -- lib_enc/cod_tcx_fx.c | 11 - lib_enc/cod_uv_fx.c | 18 - lib_enc/core_enc_init_fx.c | 8 - lib_enc/core_enc_ol_fx.c | 2 - lib_enc/core_enc_reconf_fx.c | 2 - lib_enc/core_enc_switch_fx.c | 4 - lib_enc/core_switching_enc_fx.c | 2 - lib_enc/decision_matrix_enc_fx.c | 2 - lib_enc/dtx_fx.c | 25 - lib_enc/enc_acelp_fx.c | 6 - lib_enc/enc_acelpx_fx.c | 4 - lib_enc/enc_gen_voic_fx.c | 4 - lib_enc/enc_pit_exc_fx.c | 12 - lib_enc/enc_tran_fx.c | 2 - lib_enc/enc_uv_fx.c | 4 - lib_enc/energy_fx.c | 4 - lib_enc/ext_sig_ana_fx.c | 18 - lib_enc/find_tilt_fx.c | 4 - lib_enc/gaus_enc_fx.c | 5 - lib_enc/hq_classifier_enc_fx.c | 4 - lib_enc/hq_core_enc_fx.c | 6 - lib_enc/igf_enc.c | 35 -- lib_enc/init_enc_fx.c | 14 - lib_enc/inov_enc_fx.c | 2 - lib_enc/ivas_core_enc_fx.c | 13 - lib_enc/ivas_core_pre_proc_front_fx.c | 32 - lib_enc/ivas_core_pre_proc_fx.c | 6 - lib_enc/ivas_cpe_enc_fx.c | 44 -- lib_enc/ivas_dirac_enc_fx.c | 66 -- lib_enc/ivas_front_vad_fx.c | 4 - lib_enc/ivas_ism_dtx_enc_fx.c | 4 - lib_enc/ivas_ism_enc_fx.c | 10 - lib_enc/ivas_ism_metadata_enc_fx.c | 6 - lib_enc/ivas_masa_enc_fx.c | 4 - lib_enc/ivas_mc_param_enc_fx.c | 8 - lib_enc/ivas_mc_paramupmix_enc_fx.c | 6 - lib_enc/ivas_mcmasa_enc_fx.c | 4 - lib_enc/ivas_mct_core_enc_fx.c | 11 - lib_enc/ivas_mct_enc_mct_fx.c | 8 - lib_enc/ivas_mdct_core_enc_fx.c | 29 - lib_enc/ivas_omasa_enc_fx.c | 4 - lib_enc/ivas_osba_enc_fx.c | 22 - lib_enc/ivas_qmetadata_enc_fx.c | 17 - lib_enc/ivas_sce_enc_fx.c | 6 - lib_enc/ivas_sns_enc_fx.c | 5 - lib_enc/ivas_stat_enc.h | 12 - lib_enc/ivas_stereo_classifier_fx.c | 4 - lib_enc/ivas_stereo_dft_enc_fx.c | 12 - lib_enc/ivas_stereo_dft_enc_itd_fx.c | 51 -- lib_enc/ivas_stereo_dmx_evs_fx.c | 131 ---- lib_enc/ivas_stereo_ica_enc_fx.c | 22 - lib_enc/ivas_stereo_icbwe_enc_fx.c | 10 - lib_enc/ivas_stereo_mdct_core_enc_fx.c | 10 - lib_enc/ivas_stereo_mdct_igf_enc_fx.c | 2 - lib_enc/ivas_stereo_switching_enc_fx.c | 8 - lib_enc/ivas_stereo_td_analysis_fx.c | 29 - lib_enc/ivas_stereo_td_enc_fx.c | 2 - lib_enc/ivas_tcx_core_enc_fx.c | 20 - lib_enc/ivas_td_low_rate_enc_fx.c | 38 -- lib_enc/lib_enc.c | 4 - lib_enc/nois_est_fx.c | 2 - lib_enc/pit_enc_fx.c | 2 - lib_enc/pre_proc_fx.c | 4 - lib_enc/prot_fx_enc.h | 8 - lib_enc/spec_flatness_fx.c | 4 - lib_enc/speech_music_classif_fx.c | 47 -- lib_enc/stat_enc.h | 5 - lib_enc/swb_bwe_enc_fx.c | 21 - lib_enc/swb_pre_proc_fx.c | 4 - lib_enc/swb_tbe_enc_fx.c | 4 - lib_enc/tcx_ltp_enc_fx.c | 4 - lib_enc/tcx_utils_enc_fx.c | 6 - lib_enc/tns_base_enc_fx.c | 4 - lib_enc/transient_detection_fx.c | 9 - lib_enc/transition_enc_fx.c | 16 - .../ivas_dirac_dec_binaural_functions_fx.c | 426 ------------- lib_rend/ivas_dirac_decorr_dec_fx.c | 115 ---- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 34 - lib_rend/ivas_dirac_rend_fx.c | 30 - lib_rend/ivas_mcmasa_ana_fx.c | 2 - lib_rend/ivas_objectRenderer_hrFilt_fx.c | 2 - lib_rend/ivas_objectRenderer_sources_fx.c | 2 - lib_rend/ivas_output_init_fx.c | 4 - lib_rend/ivas_prot_rend_fx.h | 2 - lib_rend/ivas_reverb_fx.c | 9 - lib_rend/ivas_rotation_fx.c | 2 - lib_rend/ivas_stat_rend.h | 4 - lib_rend/lib_rend.c | 2 - lib_rend/lib_rend.h | 2 - lib_util/hrtf_file_reader.c | 4 - 183 files changed, 4630 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index ceb1a448e..47548d438 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -699,10 +699,8 @@ int main( lfeRoutingConfigs[i] = NULL; } -#ifdef FIX_DISCLAIMER IVAS_REND_PrintDisclaimer(); -#endif CmdlnArgs args = parseCmdlnArgs( argc, argv ); if ( args.nonDiegeticPan && !( ( args.inConfig.numAudioObjects == 0 && args.inConfig.multiChannelBuses[0].audioConfig == IVAS_AUDIO_CONFIG_MONO ) || @@ -864,7 +862,6 @@ int main( exit( -1 ); } -#ifdef FIX_DISCLAIMER fprintf( stdout, "Input audio file: %s\n", args.inputFilePath ); fprintf( stdout, "Output audio file: %s\n\n", args.outputFilePath ); @@ -907,7 +904,6 @@ int main( exit( -1 ); } -#endif /* === Configure === */ if ( ( error = IVAS_REND_InitConfig( hIvasRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) { diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 7fab24660..20dbe663e 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -2563,10 +2563,8 @@ Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ) { var_out = shr_o( var1, var2, Overflow ); -#ifdef FIX_1049_SHR_RO_COMPLEXITY #ifdef WMOPS multiCounter[currCounter].shr--; -#endif #endif if ( var2 > 0 ) { @@ -2577,13 +2575,11 @@ Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ) } } -#ifdef FIX_1049_SHR_RO_COMPLEXITY #ifdef WMOPS multiCounter[currCounter].shr_r++; #endif BASOP_CHECK(); -#endif return ( var_out ); } diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 88b276126..cb71f0f28 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -773,9 +773,7 @@ ivas_error config_acelp1( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signalling_bits, /* i : number of signalling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -795,9 +793,7 @@ ivas_error config_acelp1( Word16 flag_hardcoded, coder_type_sw, fix_first; Word32 core_brate; #ifdef DEBUGGING -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) active_cnt; -#endif #endif ivas_error error; @@ -1078,13 +1074,9 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, -1, -1 )]; move16(); @@ -1205,11 +1197,7 @@ ivas_error config_acelp1( { test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ -#else - IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -1427,14 +1415,10 @@ ivas_error config_acelp1( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || /* @12.8kHz core except of GSC */ ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ ) -#else - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) -#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -1498,13 +1482,9 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( flag_hardcoded /* EVS */ || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1613,12 +1593,8 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1658,13 +1634,9 @@ ivas_error config_acelp1( } } } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -1805,12 +1777,8 @@ ivas_error config_acelp1( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ -#else - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ubits = 0; move16(); @@ -1930,9 +1898,7 @@ ivas_error config_acelp1_IVAS( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signaling_bits, /* i : number of signaling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -2214,12 +2180,8 @@ ivas_error config_acelp1_IVAS( test(); test(); /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ -#ifdef NONBE_FIX_GSC_BSTR IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && ( coder_type != INACTIVE ) && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( ( coder_type == INACTIVE ) && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, -1 )]; move16(); @@ -2344,11 +2306,7 @@ ivas_error config_acelp1_IVAS( { test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ -#else - IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -2564,13 +2522,9 @@ ivas_error config_acelp1_IVAS( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) /* @12.8kHz core except of GSC */ || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ ) -#else - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) -#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -2634,13 +2588,9 @@ ivas_error config_acelp1_IVAS( test(); test(); /* algebraic codebook bit-budget */ -#ifdef NONBE_FIX_GSC_BSTR IF( flag_hardcoded /* EVS */ || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2741,12 +2691,8 @@ ivas_error config_acelp1_IVAS( test(); test(); /* AVQ codebook */ -#ifdef NONBE_FIX_GSC_BSTR IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) -#else - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) -#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2784,13 +2730,9 @@ ivas_error config_acelp1_IVAS( } } } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) -#else - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -2931,12 +2873,8 @@ ivas_error config_acelp1_IVAS( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ -#else - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ -#endif { acelp_cfg->ubits = 0; move16(); diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 712a6905e..e144c2cc9 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -526,10 +526,8 @@ void reset_indices_enc_fx( { Word16 i; -#ifdef MSAN_FIX hBstr->nb_ind_tot = 0; move16(); -#endif hBstr->nb_bits_tot = 0; move16(); hBstr->next_ind_fx = 0; diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 48fe4d9bc..408580169 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1101,9 +1101,7 @@ void cldfbSynthesis_ivas_fx( Word32 **imagBuffer_fx, /* i : imag values Qx*/ Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ const Word16 samplesToProcess, /* i : number of processed samples */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE const Word16 shift, /* i : scale for state buffer */ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ) { @@ -1269,10 +1267,8 @@ void cldfbSynthesis_ivas_fx( } /* synthesis prototype filter */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( 0 == shift ) { -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = 0; i < L2; i++ ) { accu0 = Madd_32_16( synthesisBuffer_fx[i], Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter[i] ), p_filter_sf ); // Qx - 1 @@ -1292,7 +1288,6 @@ void cldfbSynthesis_ivas_fx( synthesisBuffer_fx[4 * L2 + i] = accu4; move32(); } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE } ELSE { @@ -1318,7 +1313,6 @@ void cldfbSynthesis_ivas_fx( move32(); } } -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = 0; i < M1; i++ ) { diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 4e14b310d..379dd7c85 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -935,9 +935,7 @@ typedef enum #define GAIN_PRED_ORDER 4 /* Gain quantization - prediction order for gain quantizer (only for AMR-WB IO mode) */ #define MEAN_ENER 30 /* Gain quantization - average innovation energy */ -#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD #define DTX_THR 5 /* DTX - lp_noise threshold for DTX at higher bitrates */ -#endif #define DTX_HIST_SIZE 8 /* CNG & DTX - number of last signal frames used for CNG averaging */ #define CNG_ISF_FACT 0.9f /* CNG & DTX - CNG spectral envelope smoothing factor */ diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index 1a01c2c32..3b1677365 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -44,11 +44,7 @@ int16_t print_disclaimer( FILE *fPtr ) { fprintf( fPtr, "\n==================================================================================================\n" ); -#ifdef FIX_DISCLAIMER fprintf( fPtr, " IVAS Codec BASOP Baseline\n" ); -#else - fprintf( fPtr, " IVAS Codec Baseline\n" ); -#endif fprintf( fPtr, " \n" ); fprintf( fPtr, " Based on EVS Codec (Floating Point) 3GPP TS26.443 Nov 04, 2021,\n" ); fprintf( fPtr, " Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0\n" ); diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index b1e2a7dd9..1b303d285 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -395,9 +395,7 @@ void edct_16fx( Word16 Len2, i2; const Word16 *px, *pt; Word16 *py; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow; Overflow = 0; diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 7b63e9c67..31b11a9ea 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -7596,12 +7596,6 @@ Word16 L_norm_arr( const Word32 *arr, Word16 size ) Word16 q = 31; move16(); FOR( Word16 i = 0; i < size; i++ ) -#ifndef FIX_1103_OPT_L_NORM_ARR - IF( arr[i] != 0 ) - { - q = s_min( q, norm_l( arr[i] ) ); - } -#else { Word16 q_tst; @@ -7612,7 +7606,6 @@ Word16 L_norm_arr( const Word32 *arr, Word16 size ) } } -#endif return q; } @@ -7658,24 +7651,6 @@ Word16 W_norm_arr( Word64 *arr, Word16 size ) Word16 get_min_scalefactor( Word32 x, Word32 y ) { -#ifndef FIX_1104_OPT_GETMINSCALEFAC - Word16 scf = Q31; - move16(); - test(); - IF( x == 0 && y == 0 ) - { - return 0; - } - IF( x != 0 ) - { - scf = s_min( scf, norm_l( x ) ); - } - IF( y != 0 ) - { - scf = s_min( scf, norm_l( y ) ); - } - return scf; -#else Word16 scf_y; Word16 scf = Q31; move16(); @@ -7699,7 +7674,6 @@ Word16 get_min_scalefactor( Word32 x, Word32 y ) } return scf; -#endif } diff --git a/lib_com/gs_bitallocation_fx.c b/lib_com/gs_bitallocation_fx.c index 87ba794d4..0ce59482f 100644 --- a/lib_com/gs_bitallocation_fx.c +++ b/lib_com/gs_bitallocation_fx.c @@ -75,10 +75,8 @@ void bands_and_bit_alloc_fx( Word16 SWB_bit_budget; Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; Word16 w_sum_bit; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) GSC_IVAS_mode; (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; #endif diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index c0feb91f5..421b2a705 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -162,13 +162,8 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 L_frame, /* i : Frame lenght */ -#ifndef NONBE_FIX_GSC_BSTR - const Word32 total_brate, /* i : total bit rate */ -#endif const Word16 Q_exc, /* i : input and output format of exc2 */ const Word16 bfi, /* i : frame lost indicator */ const Word16 last_core, /* i : Last core used */ @@ -224,11 +219,7 @@ void Inac_switch_ematch_ivas_fx( move16(); } } -#ifdef NONBE_FIX_GSC_BSTR ELSE IF( ( coder_type == INACTIVE ) && inactive_coder_type_flag ) -#else - ELSE IF( ( coder_type == INACTIVE ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) -#endif { /* Find spectrum and energy per band for inactive frames */ edct_16fx( exc2, dct_exc_tmp, L_frame, 5, element_mode ); diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 146587791..7d481d181 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -609,10 +609,8 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_y, /* o: Q30*/ Word32 *direction_vector_z, /* o: Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 *i_e_band -#endif ) { Word16 i; @@ -631,7 +629,6 @@ void computeDirectionVectors_fixed( scaled_x = L_shl( *intensity_real_x, norm_x ); scaled_y = L_shl( *intensity_real_y, norm_y ); scaled_z = L_shl( *intensity_real_z, norm_z ); -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC IF( i_e_band != NULL ) { e_x = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_x ) ); @@ -644,12 +641,6 @@ void computeDirectionVectors_fixed( e_y = sub( i_e, norm_y ); e_z = sub( i_e, norm_z ); } -#else - - e_x = sub( i_e, norm_x ); - e_y = sub( i_e, norm_y ); - e_z = sub( i_e, norm_z ); -#endif temp1 = BASOP_Util_Add_Mant32Exp( Mult_32_32( scaled_x, scaled_x ), shl( e_x, 1 ), Mult_32_32( scaled_y, scaled_y ), shl( e_y, 1 ), &exp1 ); intensityNorm = BASOP_Util_Add_Mant32Exp( temp1, exp1, Mult_32_32( scaled_z, scaled_z ), shl( e_z, 1 ), &intensityNorm_e ); @@ -966,17 +957,12 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_energy[i], min_q_shift1 ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS Word16 shift_q = sub( q_tmp, q_ene ); Word32 shiftEquiv = L_add( 0, 0 ); Word16 shift_qtotal; if ( shift_q < 0 ) { -#ifdef FIX_USAN_ISSUES shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); -#else - shiftEquiv = L_lshl( 0x80000000, shift_q ); -#endif } if ( shift_q >= 0 ) { @@ -990,27 +976,6 @@ void computeDiffuseness_fixed( energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); move32(); } -#else - Word16 shift_q = sub( q_tmp, q_ene ); - IF( shift_q < 0 ) - { - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp_c[k], min_q_shift1 ); - energy_slow[k] = L_add( L_shl( energy_slow[k], shift_q ), tmp ); - move32(); - } - } - ELSE - { - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp_c[k], min_q_shift1 ); - energy_slow[k] = L_add( energy_slow[k], L_shr( tmp, shift_q ) ); - move32(); - } - } -#endif q_ene = s_min( q_ene, q_tmp ); @@ -1019,14 +984,9 @@ void computeDiffuseness_fixed( q_tmp = add( q_factor_intensity[i], min_q_shift2 ); shift_q = sub( q_tmp, q_intensity ); -#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS if ( shift_q < 0 ) { -#ifdef FIX_USAN_ISSUES shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); -#else - shiftEquiv = L_lshl( 0x80000000, shift_q ); -#endif } if ( shift_q >= 0 ) { @@ -1044,34 +1004,6 @@ void computeDiffuseness_fixed( move32(); } } -#else - IF( shift_q > 0 ) - { - FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) - { - p_tmp = buffer_intensity[j][i]; - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp[k], min_q_shift2 ); - intensity_slow[j * num_freq_bands + k] = L_add( intensity_slow[j * num_freq_bands + k], L_shr( tmp, shift_q ) ); - move32(); - } - } - } - ELSE - { - FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) - { - p_tmp = buffer_intensity[j][i]; - FOR( k = 0; k < num_freq_bands; k++ ) - { - tmp = L_shl( p_tmp[k], min_q_shift2 ); - intensity_slow[j * num_freq_bands + k] = L_add( L_shl( intensity_slow[j * num_freq_bands + k], shift_q ), tmp ); - move32(); - } - } - } -#endif q_intensity = s_min( q_intensity, q_tmp ); } diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index ab043fc0f..fab166b6d 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1309,7 +1309,6 @@ Word16 matrix_diag_product_fx( Word32 *Z, /* o : resulting matrix after the matrix multiplication */ Word16 *Z_e ); -#ifdef OPT_BASOP_ADD_v1 Word16 matrix_diag_product_fx_2( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ const Word16 X_e, @@ -1321,7 +1320,6 @@ Word16 matrix_diag_product_fx_2( const Word16 entriesY, /* i : number of entries in the diagonal Q0*/ Word32 *Z, /* o : resulting matrix after the matrix multiplication Q31 - Z_e*/ Word16 *Z_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix */ @@ -3238,10 +3236,8 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_y, /*Q30*/ Word32 *direction_vector_z, /*Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 *i_e_band -#endif ); @@ -3787,10 +3783,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ Word32 *output_fx[] /* o : rendered time signal */ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); ivas_error ivas_osba_ism_metadata_dec_fx( @@ -4706,21 +4698,11 @@ Word32 dot_product_cholesky_fx( const Word16 N /* i : vector & matrix size */ ); -#ifndef DOT_PROD_CHOLESKY_64BIT -Word32 dot_product_cholesky_fixed( - const Word32 *x, /* i : vector x */ - const Word32 *A, /* i : Cholesky matrix A */ - const Word16 N, /* i : vector & matrix size */ - const Word16 exp_x, - const Word16 exp_A, - Word16 *exp_sum ); -#else Word64 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ const Word16 N /* i : vector & matrix size */ ); -#endif void v_mult_mat_fx( Word32 *y_fx, /* o : the product x*A */ @@ -5347,20 +5329,12 @@ ivas_error ivas_sba_dec_render_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ Word32 *output_fx[] /* o : rendered time signal Q11*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); void ivas_spar_dec_upmixer_sf_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ Word32 *output_fx[], /* o : output audio channels */ const Word16 nchan_internal /* i : number of internal channels */ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ); ivas_error ivas_spar_md_enc_open_fx( @@ -5967,9 +5941,7 @@ ivas_error pre_proc_front_ivas_fx( const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index c9ad84097..ee11f2b02 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -152,10 +152,8 @@ ivas_error ivas_qmetadata_allocate_memory_fx( { set32_fx( hQMetaData->q_direction[dir].band_data[j].elevation_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); set32_fx( hQMetaData->q_direction[dir].band_data[j].azimuth_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); -#ifdef MSAN_FIX set32_fx( hQMetaData->q_direction[dir].band_data[j].q_elevation_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); set32_fx( hQMetaData->q_direction[dir].band_data[j].q_azimuth_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); -#endif set32_fx( hQMetaData->q_direction[dir].band_data[j].energy_ratio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); } } @@ -315,14 +313,8 @@ ivas_error only_reduce_bits_direction_fx( Word16 *bits_dir0; Word16 bits_sph_idx_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef FIX_QMETADATA_PENALTY Word32 penalty[MASA_MAXIMUM_CODING_SUBBANDS]; Word16 tmp; -#else - Word16 penalty[MASA_MAXIMUM_CODING_SUBBANDS]; - Word16 shift, tmp, tmp_e, flag; - Word32 tmp_32; -#endif FOR( j = 0; j < coding_subbands; j++ ) { FOR( k = 0; k < no_subframes; k++ ) @@ -407,7 +399,6 @@ ivas_error only_reduce_bits_direction_fx( } ELSE { -#ifdef FIX_QMETADATA_PENALTY Word16 m, sorted, index1, index2; @@ -457,65 +448,6 @@ ivas_error only_reduce_bits_direction_fx( } -#else - FOR( j = 0; j < coding_subbands; j++ ) - { - penalty[j] = 0; - move16(); - tmp_32 = 0; - move32(); - shift = find_guarded_bits_fx( no_subframes ); - - flag = 1; - move16(); - // This change was done due to loss of precision from BASOP_Util_Divide3232_Scale which was leading to penalty getting calculated wrongly - // and hence ind_order being sorted incorrectly which might cause infinite loop. - FOR( k = 0; k < no_subframes - 1; k++ ) - { - IF( NE_16( bits_sph_idx_orig[j][k], bits_sph_idx_orig[j][k + 1] ) ) - { - flag = 0; - move16(); - } - } - - IF( flag ) - { - tmp = 0; - move16(); - FOR( k = 0; k < no_subframes; k++ ) - { - IF( bits_sph_idx_orig[j][k] > 0 ) - { - tmp = add( tmp, sub( bits_sph_idx_orig[j][k], q_direction->band_data[j].bits_sph_idx[k] ) ); - } - } - - tmp = BASOP_Util_Divide1616_Scale( tmp, bits_sph_idx_orig[j][0], &tmp_e ); - - tmp_32 = L_shl( tmp, tmp_e ); /* Q15 */ - - penalty[j] = extract_l( L_shr( tmp_32, shift ) ); /* Q15 - shift */ - move16(); - // Division by no_subframes for penalty[j] not required - } - ELSE - { - FOR( k = 0; k < no_subframes; k++ ) - { - IF( bits_sph_idx_orig[j][k] > 0 ) - { - tmp = BASOP_Util_Divide3232_Scale( extract_l( L_sub( bits_sph_idx_orig[j][k], q_direction->band_data[j].bits_sph_idx[k] ) ), bits_sph_idx_orig[j][k], &tmp_e ); - tmp_32 = L_add( tmp_32, L_shl( tmp, tmp_e ) ); - } - } - penalty[j] = extract_l( L_shr( tmp_32, shift ) ); /* Q15 - shift */ - move16(); - // Division by no_subframes for penalty[j] not required - } - } - sort_desc_ind_16_fx( penalty, coding_subbands, ind_order ); -#endif } *reduce_bits_out = negate( reduce_bits ); diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 929eaa2c5..9f6d8b422 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -2631,11 +2631,7 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( test(); IF( W_norm( re ) == 0 || W_norm( recon_uu_re[i][j] ) == 0 ) { -#ifdef FIX_ISSUE_1122 recon_uu_re[i][j] = L_shr( recon_uu_re[i][j], 1 ); // q_recon_uu_re[i][j] - 1 -#else - re1[m] = L_shr( re1[m], 1 ); // q_recon_uu_re[i][j]-1 -#endif move32(); q_recon_uu_re[i][j] = sub( q_recon_uu_re[i][j], 1 ); move16(); @@ -3834,11 +3830,7 @@ void ivas_compute_spar_params_fx( } ELSE { -#ifdef FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr_r( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22 -#else - hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22 -#endif move32(); } } @@ -3865,7 +3857,6 @@ void ivas_compute_spar_params_fx( Word16 q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx; IF( NE_16( ndm, 1 ) ) { -#ifdef MSAN_FIX FOR( i = 0; i < ( num_ch - ndm ); i++ ) { FOR( j = 0; j < sub( ndm, 1 ); j++ ) @@ -3874,15 +3865,6 @@ void ivas_compute_spar_params_fx( move32(); } } -#else - for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) - { - for ( j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) - { - hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j], sub( q_tmp, 22 ) ); - } - } -#endif hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx = Q22; move16(); } diff --git a/lib_com/ivas_tools_fx.c b/lib_com/ivas_tools_fx.c index 04d6f7bf5..ca8dec276 100644 --- a/lib_com/ivas_tools_fx.c +++ b/lib_com/ivas_tools_fx.c @@ -306,12 +306,6 @@ void v_add_inc_fx( const Word16 N /* i : Vector length Q0*/ ) { -#ifndef FIX_1107_VADDINC - Word16 i; - Word16 ix1 = 0; - Word16 ix2 = 0; - Word16 iy = 0; -#else Word16 i, ix1, ix2, iy; /* The use of this function is currently always for the interleaved input format, */ @@ -334,7 +328,6 @@ void v_add_inc_fx( ix1 = 0; ix2 = 0; iy = 0; -#endif move16(); move16(); move16(); @@ -604,44 +597,6 @@ void v_sub32_fx( * Therefore, S=A*A' where A is upper triangular matrix of size (m*m+m)/2 (zeros ommitted, column-wise) *---------------------------------------------------------------------*/ -#ifndef DOT_PROD_CHOLESKY_64BIT -/*! r: the dot product x'*A*A'*x */ -Word32 dot_product_cholesky_fixed( - const Word32 *x, /* i : vector x Q31 - exp_x*/ - const Word32 *A, /* i : Cholesky matrix A Q31 - exp_A*/ - const Word16 N, /* i : vector & matrix size Q0*/ - const Word16 exp_x, - const Word16 exp_A, - Word16 *exp_sum ) -{ - Word16 i, j; - Word32 suma, tmp_sum, mul; - const Word32 *pt_x, *pt_A; - Word16 mul_exp, tmp_sum_exp; - mul_exp = add( exp_x, exp_A ); - pt_A = A; - suma = 0; - move32(); - FOR( i = 0; i < N; i++ ) - { - tmp_sum = 0; - move32(); - tmp_sum_exp = 0; - move16(); - pt_x = x; - - FOR( j = 0; j <= i; j++ ) - { - mul = Mpy_32_32( *pt_x++, *pt_A++ ); /*Q31 - (exp_x + exp_A)*/ - tmp_sum = BASOP_Util_Add_Mant32Exp( tmp_sum, tmp_sum_exp, mul, mul_exp, &tmp_sum_exp ); // exp_x+exp_A - } - - suma = BASOP_Util_Add_Mant32Exp( suma, *exp_sum, Mpy_32_32( tmp_sum, tmp_sum ), shl( tmp_sum_exp, 1 ), exp_sum ); /*Q31 - exp_sum*/ - } - - return suma; -} -#else /*! r: the dot product x'*A*A'*x */ Word64 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x Q31 - exp_x*/ @@ -677,7 +632,6 @@ Word64 dot_product_cholesky_fixed( return suma; } -#endif void v_mult_mat_fixed( Word32 *y, /* o : the product x*A Qx - guardbits*/ @@ -978,9 +932,6 @@ Word16 matrix_product_mant_exp_fx( Word16 out_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word16 *Zp_fx_e = out_e; Word16 row, col; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ Word64 temp; Word16 temp_e; Word16 prod_e = add( X_fx_e, Y_fx_e ); @@ -1007,13 +958,7 @@ Word16 matrix_product_mant_exp_fx( FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = k + i * rowsX; - y_idx = k + j * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1051,13 +996,7 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = i + k * rowsX; - y_idx = j + k * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1095,13 +1034,7 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = k + i * rowsX; - y_idx = j + k * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1140,13 +1073,7 @@ Word16 matrix_product_mant_exp_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e -#else /* OPT_BASOP_ADD_v1 */ - x_idx = i + k * rowsX; - y_idx = k + j * rowsY; - temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e -#endif /* OPT_BASOP_ADD_v1 */ } /* Maximize accumulated value to 32-bit */ temp_e = W_norm( temp ); @@ -1204,9 +1131,6 @@ Word16 matrix_product_fx( ) { Word16 i, j, k; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; /* Processing */ @@ -1227,13 +1151,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1254,13 +1172,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1281,13 +1193,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -1310,13 +1216,7 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); /*Qx + Qy - 31*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ -#endif /* OPT_BASOP_ADD_v1 */ // TODO: overflow of Z_fx to be checked move32(); } @@ -1341,9 +1241,6 @@ Word16 matrix_product_q30_fx( ) { Word16 i, j, k; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; Word64 W_tmp; @@ -1366,14 +1263,7 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 -#else /* OPT_BASOP_ADD_v1 */ - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 -#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1397,14 +1287,7 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 -#else /* OPT_BASOP_ADD_v1 */ - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 -#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1428,11 +1311,6 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifndef OPT_BASOP_ADD_v1 - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ -#endif /* OPT_BASOP_ADD_v1 */ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 } @@ -1459,14 +1337,7 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 -#else /* OPT_BASOP_ADD_v1 */ - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 -#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1499,9 +1370,6 @@ Word16 matrix_product_mant_exp( Word16 *Zp_e = Z_e; Word32 L_tmp; Word16 tmp_e; -#ifndef OPT_BASOP_ADD_v1 - Word16 x_idx, y_idx; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1523,16 +1391,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[k + i * rowsX], Y_e[k + j * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - //( *Zp ) += X[k + i * rowsX] * Y[k + j * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1560,16 +1420,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[i + k * rowsX], Y_e[j + k * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[j + k * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); ( *Zp_e ) = tmp_e; @@ -1596,16 +1448,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[k + i * rowsX], Y_e[j + k * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - //( *Zp ) += X_fx[k + i * rowsX] * Y_fx[j + k * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1635,16 +1479,8 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[i + k * rowsX], Y_e[k + j * rowsY] ); -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[k + j * rowsY]; - L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ - tmp_e = add( X_e[x_idx], Y_e[y_idx] ); -#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1675,9 +1511,6 @@ Word16 matrix_diag_product_fx( { Word16 i, j; Word32 *Zp = Z; -#ifndef OPT_BASOP_ADD_v1 - Word16 tmp; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1690,12 +1523,7 @@ Word16 matrix_diag_product_fx( { FOR( i = 0; i < colsX; ++i ) { -#ifdef OPT_BASOP_ADD_v1 *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - tmp = add( j, imult1616( i, rowsX ) ); - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1726,7 +1554,6 @@ Word16 matrix_diag_product_fx( return EXIT_SUCCESS; } -#ifdef OPT_BASOP_ADD_v1 Word16 matrix_diag_product_fx_2( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ const Word16 X_e, @@ -1818,7 +1645,6 @@ Word16 matrix_diag_product_fx_2( return EXIT_SUCCESS; } -#endif /* OPT_BASOP_ADD_v1 */ Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ @@ -1835,9 +1661,6 @@ Word16 matrix_diag_product_fx_1( Word16 i, j; Word32 *Zp = Z; Word16 *Z_ep = Z_e; -#ifndef OPT_BASOP_ADD_v1 - Word16 tmp; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1850,19 +1673,10 @@ Word16 matrix_diag_product_fx_1( { FOR( i = 0; i < colsX; ++i ) { -#ifdef OPT_BASOP_ADD_v1 *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - tmp = add( j, imult1616( i, rowsX ) ); /*Q0*/ - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; -#ifdef OPT_BASOP_ADD_v1 *( Z_ep ) = add( X_e[j + i * rowsX], Y_e[j] ); -#else /* OPT_BASOP_ADD_v1 */ - *( Z_ep ) = add( X_e[tmp], Y_e[j] ); -#endif /* OPT_BASOP_ADD_v1 */ move16(); Z_ep++; } @@ -1908,9 +1722,6 @@ Word16 diag_matrix_product_fx( { Word16 i, j; Word32 *Zp = Z; -#ifndef OPT_BASOP_ADD_v1 - Word16 tmp; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1923,12 +1734,7 @@ Word16 diag_matrix_product_fx( { FOR( j = 0; j < entriesY; ++j ) { -#ifdef OPT_BASOP_ADD_v1 *( Zp ) = Mpy_32_32( X[i + j * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - tmp = add( i, imult1616( j, rowsX ) ); /*Q0*/ - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1974,9 +1780,6 @@ Word16 matrix_product_diag_fx( { Word16 j, k; Word32 *Zp = Z; -#ifndef OPT_BASOP_ADD_v1 - Word16 y_idx, x_idx; -#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1995,13 +1798,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -2019,13 +1816,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -2045,13 +1836,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -2071,13 +1856,7 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { -#ifdef OPT_BASOP_ADD_v1 ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ -#else /* OPT_BASOP_ADD_v1 */ - x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ -#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; diff --git a/lib_com/lerp.c b/lib_com/lerp.c index 4e306b936..6f148057f 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -356,10 +356,6 @@ void L_lerp_fx( Word32 *f /*q*/, Word32 *f_out /*q*/, Word16 bufferNewSize /*Q0* f[ind] = L_shr( f[ind], guard_bits ); /*Q(guard_bits)*/ move32(); } -#ifndef MSAN_FIX - FOR( Word16 ind = 0; ind < bufferNewSize; ind++ ) - f_out[ind] = L_shr( f_out[ind], guard_bits ); -#endif } IF( GT_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) ) diff --git a/lib_com/low_rate_band_att_fx.c b/lib_com/low_rate_band_att_fx.c index 9958b9d5f..e51d2807b 100644 --- a/lib_com/low_rate_band_att_fx.c +++ b/lib_com/low_rate_band_att_fx.c @@ -75,15 +75,11 @@ void ivas_fine_gain_pred_fx( L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */ exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) ); L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */ -#ifndef FIX_ISSUE_987 - Mpy_32_16_ss( L_tmp, ivas_fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ -#else Word16 norm = norm_s( bw ); Word16 tmp1, tmp_exp = sub( 15, norm ); tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp ); tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) ); Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ -#endif gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */ test(); diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 08e74b9b7..54f0ae3ed 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -604,7 +604,6 @@ Word16 lpc2lsp_fx( return ( 1 ); } -#ifdef FIX_ISSUE_1165 /*===================================================================*/ /* FUNCTION : lpc2lsp_ivas_fx () */ /*-------------------------------------------------------------------*/ @@ -749,7 +748,6 @@ Word16 lpc2lsp_ivas_fx( return ( 1 ); } -#endif /*===================================================================*/ /* FUNCTION : lsp2lpc_fx () */ diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index 10e560433..cf2ad8a8a 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -461,12 +461,10 @@ static Word16 decode_indexes_ivas_fx( IF( index[i] < 0 ) { set16_fx( x_lvq, 0, 2 * LATTICE_DIM ); -#ifdef MSAN_FIX scales_mslvq[0] = 0; move16(); scales_mslvq[1] = 0; move16(); -#endif index[i] = 0; return 1; } @@ -491,10 +489,8 @@ static Word16 decode_indexes_ivas_fx( FOR( i = 0; i < LATTICE_DIM; i++ ) { x_lvq[i] = 0; -#ifdef MSAN_FIX scales_mslvq[0] = 0; move16(); -#endif } } ELSE @@ -503,12 +499,10 @@ static Word16 decode_indexes_ivas_fx( { /* safety check in case of bit errors */ set16_fx( x_lvq, 0, 2 * LATTICE_DIM ); -#ifdef MSAN_FIX scales_mslvq[0] = 0; move16(); scales_mslvq[1] = 0; move16(); -#endif return 1; } @@ -549,10 +543,8 @@ static Word16 decode_indexes_ivas_fx( x_lvq[i] = 0; move16(); } -#ifdef MSAN_FIX scales_mslvq[1] = 0; move16(); -#endif } ELSE { diff --git a/lib_com/options.h b/lib_com/options.h index dab0c796c..16c9498d6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -67,77 +67,6 @@ #define BASOP_NOGLOB_DECLARE_LOCAL #endif -#define IVAS_FLOAT_FIXED_CONVERSIONS /* Temporary macro to keep track of intermediate flt to fixed and fixed to flt conversions */ -#define MSAN_FIX -#define FIX_TMP_714 -#define BASOP_NOGLOB_TMP_715 -#define EVS_FUNC_MODIFIED -#define REMOVE_IVAS_UNUSED_PARAMETERS_WARNING /*temporary operation on unused EVS parameters to remove warnings, these parameters will be used in IVAS */ -#define MOD_BIT_ALLOC_ROM_TABLE /* Just to highlight modification in bit allocation table and to ensure these modifications doesn't affect EVS modes*/ -#define SIMPLIFY_CODE_BE // Simplify synthesis loop -#define CR_2109_to_2112_cd0_ce0 /* This is related to the CRs include in the 26.444 package of 21-12. Concerns lead_deindexing and */ -#define FIX_QMETADATA_PENALTY /* Nokia: transform penalty calculation in qmetadata into integer operations */ -#define FIX_1013_CRASH_HQ_CORE_DEC /* Ittiam: Saturation added on the lines of EVS */ -#define NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS /* DLB: adjust prerendering and mixing gain in OSBA encoder. This is fix to float codes*/ -#define NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO /* Eri: issue 1233: Address possible division by zero in hf_spectrum_sparseness() */ -#define FIX_ISSUE_1062_AND_1068_TON_ENE_EST_FX -#define FIX_ISSUE_987 -#define FIX_1054_IF_ELSE_CMPLX /* VA: Fix 1054 incorrect counting of complexity when ELSE-IF sequence is encoutered in two functions */ -#define FIX_1052_COPY_CMPLX_DISCREPANCY /* VA: modify IF-ELSE statements used in Copy*() functions to avoid dependency on x[] and y[] in RAM */ -#define FIX_1049_SHR_RO_COMPLEXITY /* VA: fix for issue 1049: incorrect counting of complexity in the shr_ro() function */ -#define NONBE_IMPROVE_DIRAC_INTENSITY_PREC -#define FIX_1103_OPT_L_NORM_ARR /* FhG: Optimize L_norm_arr(), avoid IF */ -#define FIX_1105_OPT_MINIMUM_SL /* FhG: Optimize minimum_s(), minimum_l(), avoid IF */ -#define FIX_1104_OPT_GETMINSCALEFAC /* FhG: Optimize get_min_scalefactor(), avoid IF */ -#define FIX_1106_SIMPLIFY_SET32FX /* FhG: simplify set32_fx() */ -#define FIX_1107_VADDINC /* FhG: Optimize v_add_inc_fx() for most frequent case */ -#define FIX_1009_OPT_PARAMMC_RENDER /* FhG: Optimize ivas_param_mc_dec_render_fx() */ -#define FIX_1109_OPTIM_MCT_STEREO_IGF_DEC /* FhG: optimize mctStereoIGF_dec_fx() */ -#define FIX_1110_OPTIM_DIRAC_DECORR_PROC /* FhG: optimize ivas_dirac_dec_decorr_process() */ -#define FIX_1127_IMPROVE_SBA_MLD /* Ittiam: Avoid saturation for DiRAC reference power */ -#define FIX_1100_REMOVE_LPC_RESCALING /* VA: Remove the rescaling of LPC coefficient to Q12 as residu and syn-filt are already taking care of it*/ -#define FIX_1133_IMPROVE_MC_MLD /* Ittiam: Correcting wrong updation of exponents in ivas_mc_paramupmix_param_est_enc_fx() */ -#define FIX_ISSUE_1122 /* Ittiam: Fix issue 1122: corrected incorrect scaling of a buffer leading to incorrect metadata bits */ -#define FIX_ISSUE_1125 /* Ittiam: Fix issue 1125: interfering talker flag not triggered on short test vector */ -#define FIX_1132_STACK_CORRUPTION /* Stack corruption issue due of extending index access*/ -#define FIX_ISSUE_1092 /* Ittiam: Fix for Issue 1092: BASOP asserts in stereo fx encoder for selection test inputs*/ -#define FIX_ISSUE_1135 /* Ittiam: Fix for Issue 1135: downmixing difference between float and fixed-point (DFT - stereo) */ -#define FIX_ISSUE_1148 -#define FIX_ISSUE_1147 /* Ittiam: Fix for issue 1147: Added saturation in DetectTnsFilt_fx.*/ -#define FIX_ISSUE_1150 /* Ittiam: Fix for Issue 1150: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from tcx_ltp_find_gain function*/ -#define FIX_ISSUE_1151 /* Ittiam: Fix for Issue 1151: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from sp_mus_classif_gmm_fx function*/ -#define FIX_ISSUE_1153 /* Ittiam: Fix for Issue 1153: Assertion error observed in stereo_dmx_evs_enc_fx from calc_poc_fx function*/ -#define FIX_ISSUE_1154 /* Ittiam: Fix for Issue 1154: Encoder crash for ParamMC 7.1 at 96kbps in ivas_param_mc_param_est_enc_fx() */ -#define FIX_ISSUE_1157 /* Ittiam: Fix for Issue 1157: Encoder crash for Stereo at 48/64kbps DTX on/off in kernel_switch_trafo_fx() */ -#define FIX_ISSUE_1152 /* Ittiam: Fix for issue 1152: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from find_tilt_fx function*/ -#define FIX_ISSUE_1156 /* Ittiam: Fix for Issue 1156: Encoder crash for Stereo at 32kbps in SWB_BWE_encoding_ivas_fx() */ -#define FIX_DISCLAIMER /* VA: Add disclaimer for external renderer + Add info about IVAS reference version (FLP issue 1225) */ -#define FIX_ISSUE_1167 /* Ittiam: Fix for Issue 1167: Encoder crash for OSBA ISM3SBA1 at 13.2 and 16.4 kbps in gauss_L2_ivas_fx() */ -#define FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC /* FhG: Reduce workload of binaural rendering: replace 1./tmp & sqrt by Isqrt32 */ -#define FIX_1113_OPT_DIRAC_BIN_REND /* FhG: Various optimizations to ivas_dirac_dec_binaual_functions.c */ -#define FIX_ISSUE_1187 /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/ -#define FIX_ISSUE_1186 /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */ -#define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */ -#define FIX_ISSUE_1185 /* Ittiam: Fix for issue 1185: Assertion in ivas_dirac_dec_binaural_internal_fx() for crash in decoder in fft30_with_cmplx_data()*/ -#define FIX_ISSUE_1209 /* Ittiam: Fix for issue 1209: Assertion exit in BASOP encoder (stereo_dmx_evs)*/ -#define FIX_ISSUE_1218 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ -#define FIX_ISSUE_1290 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ -#define IVAS_ISSUE_1188_EVS_CRASH /* Ittiam: Fix for issue 1188: Issue due to ASAN */ -#define FIX_ISSUE_1155 /* Ittiam: Fix for issue 1155: Encoder crash for Stereo at 32kbps in PostShortTerm_ivas_enc_fx()*/ -#define FIX_1010_OPT_DIV /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_SINGLE_RESCALE /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_GIVENS /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_GIVENS_INV /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_NORM_NOSAT /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1010_OPT_SEC_SINGLE_RESCALE /* FhG: SVD complexity optimizations (non-be) */ -#define FIX_1072_SPEEDUP_matrixTransp2Mul_fx /* FhG: complexity optimization (non-be) */ -#define FIX_1072_REDUCE_DIVS /* FhG: complexity optimization (non-be) */ -#define FIX_ISSUE_1230 /* Ittiam: Fix for issue 1230: Basop Enc audible differences and distortion @16kbps */ -#define NONBE_1211_DTX_BR_SWITCHING /* VA: port float issue 1211: fix crash in MASA DTX bitrate switching */ -#define FIX_1189_GSC_IVAS_OMASA /* VA: Fix for issue 1189: Bitstream desynchornization due to reading/writing of the GSC_IVAS_mode parameter */ -#define NONBE_1273_ISM_METADATA_COUNTER /* VA: BASOP issue 1265, FLP issue 1273: fix counter overflow in ISM metadata encoder */ -#define NONBE_FIX_GSC_BSTR /* VA: issue 1264 FLP (1189 BASOP): Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA */ -#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF /* FhG: fix for issue 1101: complexity of spar dec upmixer */ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ #define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS /* FhG: Defines 1.0f-weight variables, uses Madd operation instead of L_add_sat */ #define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS /* FhG: Splits single loop with IF-statements into two low-complex loops */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 70b70859c..71c1590c2 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -881,13 +881,11 @@ Word16 lpc2lsp_fx( Word16 *old_freq, Word16 order ); -#ifdef FIX_ISSUE_1165 Word16 lpc2lsp_ivas_fx( Word32 *a, Word16 *freq, Word16 *old_freq, Word16 order ); -#endif void lsp2lpc_fx( Word16 *a, @@ -4864,9 +4862,7 @@ ivas_error config_acelp1( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signalling_bits, /* i : number of signalling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -5854,13 +5850,8 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 L_frame, /* i : Frame lenght */ -#ifndef NONBE_FIX_GSC_BSTR - const Word32 core_brate, /* i : Core bit rate */ -#endif const Word16 Q_exc, /* i : input and output format of exc2 */ const Word16 bfi, /* i : frame lost indicator */ const Word16 last_core, /* i : Last core used */ @@ -9753,9 +9744,7 @@ void cldfbSynthesis_ivas_fx( Word32 **imagBuffer_fx, /* i : imag values Qx*/ Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ const Word16 samplesToProcess, /* i : number of processed samples */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE const Word16 shift, /* i : scale for state buffer */ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); @@ -10995,9 +10984,7 @@ ivas_error config_acelp1_IVAS( ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ const Word16 signaling_bits, /* i : number of signaling bits */ const Word16 coder_type, /* i : coder type */ -#ifdef NONBE_FIX_GSC_BSTR const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ -#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -11064,9 +11051,7 @@ void calculate_hangover_attenuation_gain_ivas_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ -#ifdef FIX_920_IGF_INIT_ERROR const Word32 igf_brate, /* i : IGF configuration bitrate */ -#endif const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index e6f392ff0..551a84feb 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -16790,7 +16790,6 @@ const Word16 GSC_freq_bits[] = 26, 96, 0, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_22k60*/ 26, 96, 0, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4 /* ACELP_24k40*/ }; // Q0 -#ifdef MOD_BIT_ALLOC_ROM_TABLE const Word32 GSC_freq_bits_fx[] =/*Q18*/ { 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_5k00*/ @@ -16823,17 +16822,6 @@ const Word32 GSC_freq_bits_fx_Q18[] =/*Q18*/ 6815744, 25165824, 0, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, 6815744, 25165824, 0, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, }; -#else -const Word32 GSC_freq_bits_fx[] = -{ - 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_7k20*/ - 5505024, 19660800, -1048576, 6815744, 4194304, 3145728, 2883584, 2359296, 0, 0, 1048576, 1048576, 262144, 262144, 786432, 0, 0, /* ACELP_8k00*/ - 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_11k60*/ - 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k15*/ - 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k85*/ - 8126464, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_13k20*/ -}; -#endif const Word16 Compl_GSC_freq_bits[] = { 5, 10, 10, 10 /* bitrate > ACELP_16k40 && FS = 16kHz */ diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index eda099cd9..228d43247 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -2533,11 +2533,7 @@ void hq_generic_decoding_fx( IF( L_tmp != 0 ) { exp = norm_l( L_tmp ); -#ifdef EVS_FUNC_MODIFIED frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#else - frac = round_fx( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#endif tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ @@ -2868,11 +2864,7 @@ void hq_generic_decoding_fx( tmp4_fx = mult_r( tmp3_fx, 1638 /* 0.05 in Q15 */ ); WHILE( tmp3_fx > 1024 /* 1 in Q10*/ ) { -#ifdef EVS_FUNC_MODIFIED L_tmp1 = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ -#else - L_tmp1 = Mult_32_16( L_shl( *pit1_fx, 5 ), tmp3_fx ); /*15 + 5 + 10 -15 */ -#endif *pit1_fx-- = L_tmp1; move32(); tmp3_fx = sub( tmp3_fx, tmp4_fx ); @@ -3089,11 +3081,7 @@ void hq_generic_decoding_ivas_fx( IF( L_tmp != 0 ) { exp = norm_l( L_tmp ); -#ifdef EVS_FUNC_MODIFIED frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#else - frac = round_fx( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ -#endif tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ @@ -3424,11 +3412,7 @@ void hq_generic_decoding_ivas_fx( tmp4_fx = mult_r( tmp3_fx, 1638 /* 0.05 in Q15 */ ); WHILE( tmp3_fx > 1024 /* 1 in Q10*/ ) { -#ifdef EVS_FUNC_MODIFIED L_tmp1 = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ -#else - L_tmp1 = Mult_32_16( L_shl( *pit1_fx, 5 ), tmp3_fx ); /*15 + 5 + 10 -15 */ -#endif *pit1_fx-- = L_tmp1; move32(); tmp3_fx = sub( tmp3_fx, tmp4_fx ); diff --git a/lib_com/swb_bwe_com_lr_fx.c b/lib_com/swb_bwe_com_lr_fx.c index d0b8d0100..8fd876f1c 100644 --- a/lib_com/swb_bwe_com_lr_fx.c +++ b/lib_com/swb_bwe_com_lr_fx.c @@ -2366,11 +2366,7 @@ void ton_ene_est_fx( exp_normn = norm_s( peak_fx[k] ); fac_fx = div_s( shl( temp2_fx, exp_normd ), shl( peak_fx[k], exp_normn ) ); -#ifdef FIX_ISSUE_1062_AND_1068_TON_ENE_EST_FX fac_fx = shl_sat( fac_fx, sub( add( Qss, exp_normn ), add( Qtemp2, exp_normd ) ) ); /* Qtemp2+exp_normd-(Qss+exp_normn)+15 -> 15*/ -#else - fac_fx = shl( fac_fx, sub( add( Qss, exp_normn ), add( Qtemp2, exp_normd ) ) ); /* Qtemp2+exp_normd-(Qss+exp_normn)+15 -> 15*/ -#endif } ni_gain_fx[k] = mult_r( avg_pe_fx[k], fac_fx ); /* Qavg_pe[k] */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 04b6ba187..2a2841966 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -1036,11 +1036,7 @@ static void filt_mu_fx( FOR( n = 0; n < SubFrameLength; n++ ) { temp = mult_r( mu, ( *ptrs++ ) ); -#ifdef FIX_ISSUE_1155 temp = add_sat( temp, *ptrs ); /*Q12 */ -#else - temp = add( temp, *ptrs ); /*Q12 */ -#endif sig_out[n] = shl_o( mult_r( ga, temp ), 1, &Overflow ); move16(); /*Q12 */ } @@ -5087,7 +5083,6 @@ void GenSHBSynth_fx32( Word32 speech_buf_32k[L_FRAME32k]; Word16 i; -#ifdef FIX_881_HILBERT_FILTER Word16 shift = 0; Word32 maxm32, input_synspeech_temp[L_FRAME16k]; move16(); @@ -5123,9 +5118,6 @@ void GenSHBSynth_fx32( } Interpolate_allpass_steep_fx32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); -#else - Interpolate_allpass_steep_fx32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); -#endif IF( EQ_16( L_frame, L_FRAME ) ) { @@ -5148,14 +5140,12 @@ void GenSHBSynth_fx32( } } -#ifdef FIX_881_HILBERT_FILTER IF( maxm32 != 0 ) { Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); } -#endif return; } diff --git a/lib_com/tcq_position_arith_fx.c b/lib_com/tcq_position_arith_fx.c index 0466dc133..3abd527ca 100644 --- a/lib_com/tcq_position_arith_fx.c +++ b/lib_com/tcq_position_arith_fx.c @@ -1983,11 +1983,7 @@ Word32 encode_magnitude_tcq_fx( move16(); bits_fx = L_deposit_l( 0 ); -#ifdef IVAS_ISSUE_1188_EVS_CRASH tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - ( nzpos - 1 )] ) ); -#else - tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos - 1] ) ); -#endif *est_frame_bits_fx = L_add( *est_frame_bits_fx, tcq_bits_fx ); move32(); @@ -2470,11 +2466,7 @@ void decode_mangitude_tcq_fx( move16(); bits_fx = L_deposit_l( 0 ); -#ifdef IVAS_ISSUE_1188_EVS_CRASH tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - ( nzpos - 1 )] ) ); -#else - tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos - 1] ) ); -#endif IF( EQ_16( nzpos, npulses ) ) { diff --git a/lib_com/tcx_mdct_fx.c b/lib_com/tcx_mdct_fx.c index 1fc57871d..b2cee32e6 100644 --- a/lib_com/tcx_mdct_fx.c +++ b/lib_com/tcx_mdct_fx.c @@ -106,9 +106,7 @@ void TCX_MDCT( Word16 i; Word16 factor, neg_factor; Word16 factor_e; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -164,9 +162,7 @@ void TCX_MDST( Word16 i; Word16 factor, neg_factor; Word16 factor_e; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -226,9 +222,7 @@ void TCX_MDCT_Inverse( Word16 L2 = l, R2 = r; Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2]; Word16 fac_e; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) element_mode; -#endif L2 = shr( l, 1 ); R2 = shr( r, 1 ); diff --git a/lib_com/tools.c b/lib_com/tools.c index e4ccd9955..b1a9f4d13 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -628,45 +628,23 @@ Word16 minimum_s( Word16 *min_val /* o : minimum value in the input vector */ ) { -#ifdef FIX_1105_OPT_MINIMUM_SL Word16 i, ind; -#else - Word16 i, ind, tmp; -#endif ind = 0; move16(); -#ifndef FIX_1105_OPT_MINIMUM_SL - tmp = vec[0]; - move16(); -#endif FOR( i = 1; i < lvec; i++ ) { -#ifdef FIX_1105_OPT_MINIMUM_SL if ( LT_16( vec[i], vec[ind] ) ) { ind = i; move16(); } -#else - IF( LT_16( vec[i], tmp ) ) - { - ind = i; - move16(); - tmp = vec[i]; - move16(); - } -#endif } if ( min_val != NULL ) { -#ifdef FIX_1105_OPT_MINIMUM_SL *min_val = vec[ind]; -#else - *min_val = tmp; -#endif move16(); } @@ -687,45 +665,22 @@ Word16 minimum_l( ) { Word16 i, ind; -#ifndef FIX_1105_OPT_MINIMUM_SL - Word32 tmp; -#endif ind = 0; -#ifndef FIX_1105_OPT_MINIMUM_SL - tmp = vec[0]; -#endif move16(); -#ifndef FIX_1105_OPT_MINIMUM_SL - move32(); -#endif FOR( i = 1; i < lvec; i++ ) { -#ifdef FIX_1105_OPT_MINIMUM_SL if ( LT_32( vec[i], vec[ind] ) ) { ind = i; move16(); } -#else - IF( LT_32( vec[i], tmp ) ) - { - ind = i; - tmp = vec[i]; - move16(); - move32(); - } -#endif } if ( min_val != NULL ) { -#ifdef FIX_1105_OPT_MINIMUM_SL *min_val = vec[ind]; -#else - *min_val = tmp; -#endif move32(); } diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index fad2d64a8..d403c583d 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -483,16 +483,10 @@ void Copy( move16(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */ return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i] = x[i]; @@ -500,9 +494,6 @@ void Copy( } return; -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } /*-------------------------------------------------------------------* * Copy64: @@ -524,16 +515,10 @@ void Copy64( move64(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */ return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i] = x[i]; @@ -541,9 +526,6 @@ void Copy64( } return; -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } void set64_fx( @@ -580,16 +562,10 @@ void Copy_pword( move16(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */ return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i].v.im = x[i].v.im; @@ -599,9 +575,6 @@ void Copy_pword( } return; -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } /*-------------------------------------------------------------------* * Copy32: @@ -623,23 +596,14 @@ void Copy32( move32(); } -#ifdef FIX_1052_COPY_CMPLX_DISCREPANCY return; -#endif } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - ELSE - { -#endif FOR( i = L - 1; i >= 0; i-- ) { y[i] = x[i]; move32(); } -#ifndef FIX_1052_COPY_CMPLX_DISCREPANCY - } -#endif } void set8_fx( @@ -688,7 +652,6 @@ void set32_fx( const Word16 N /* i : Lenght of the vector */ ) { -#ifdef FIX_1106_SIMPLIFY_SET32FX Word16 i; FOR( i = 0; i < N; i++ ) @@ -696,26 +659,6 @@ void set32_fx( y[i] = a; move32(); } -#else - Word16 i, tmp; - tmp = extract_l( a ); - IF( EQ_32( L_deposit_l( tmp ), a ) ) - { - FOR( i = 0; i < N; i++ ) - { - y[i] = L_deposit_l( tmp ); - move32(); - } - } - ELSE - { - FOR( i = 0; i < N; i++ ) - { - y[i] = a; - move32(); - } - } -#endif return; } @@ -801,7 +744,6 @@ void Copy_Scale_sig_16_32_DEPREC( } return; } -#ifdef FIX_ISSUE_1237 #ifdef DEBUGGING if ( exp0 >= 16 ) { @@ -809,7 +751,6 @@ void Copy_Scale_sig_16_32_DEPREC( } #else assert( exp0 < 16 ); -#endif #endif tmp = shl_o( 1, exp0, &Overflow ); FOR( i = 0; i < lg; i++ ) diff --git a/lib_com/trans_direct_fx.c b/lib_com/trans_direct_fx.c index d4792fb75..6a3cdf108 100644 --- a/lib_com/trans_direct_fx.c +++ b/lib_com/trans_direct_fx.c @@ -40,9 +40,7 @@ void direct_transform_fx( Word16 shift, Qmin = 31; Word32 L_tmp; Word16 Qs[NUM_TIME_SWITCHING_BLOCKS]; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( element_mode ); -#endif move16(); segment_length = shr( L, 1 ); diff --git a/lib_com/trans_inv_fx.c b/lib_com/trans_inv_fx.c index 0033e2c9e..0683e266c 100644 --- a/lib_com/trans_inv_fx.c +++ b/lib_com/trans_inv_fx.c @@ -515,11 +515,7 @@ void preecho_sb_fx( tmp_fx1 = norm_l( es_mdct_hb_fx[i] ); tmp_fxL1 = L_shl( es_mdct_hb_fx[i], tmp_fx1 ); tmp_fxL2 = L_shl( mean_prev_hb_fx_loc, tmp_fx1 ); -#ifdef FIX_1013_CRASH_HQ_CORE_DEC tmp_fx1 = round_fx_sat( tmp_fxL1 ); -#else - tmp_fx1 = round_fx( tmp_fxL1 ); -#endif tmp_fx2 = round_fx( tmp_fxL2 ); tmp_fx3 = div_s( tmp_fx2, tmp_fx1 ); min_g_hb_fx[i] = Frac_sqrt( tmp_fx3 ); @@ -996,9 +992,7 @@ void Inverse_Transform( Word16 segment_length_div2, segment_length_div4; Word16 tmp, q_out; Word32 L_temp; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( element_mode ); -#endif /* This value is used to right shift all vectors returned by 'iedct_short_fx()' */ /* to bring them to a scaling that is equal to the 1st 'Q' returned by the 1st */ /* call to 'iedct_short_fx()' minus these guard bits. */ diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 34d01d7fe..74f1bfc09 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -1590,11 +1590,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[*pPlocs], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( *pPlocs ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1605,11 +1601,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && EQ_16( *pPlocs, 1 ) ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[*pPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( sub( *pPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1655,11 +1647,7 @@ static void ivas_spec_ana_fx( IF( EQ_16( currPlocs, ( sub( Lprot2_1, DELTA_CORR_F0_INT ) ) ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[currPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( sub( currPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1673,11 +1661,7 @@ static void ivas_spec_ana_fx( * whould point */ IF( n > 0 ) /* fs/2 which makes special case . */ { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 -#else - Copy_Scale_sig_16_32_DEPREC( &xfp[currPlocs - 2], xfp_32, 3, Q16 ); // Q + 16 -#endif acc = L_deposit_h( sub( currPlocs, 2 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -4005,11 +3989,7 @@ static void ivas_fec_ecu_dft_fx( tmp = Exp16Array( *Nfft, Tfr16 ); *exp = add( tmp, add( 2, norm_s( *Nfft ) ) ); move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#else - Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#endif *exp = s_min( *exp, 15 ); DoRTFTn_fx( Tfr32, Tfi32, *Nfft ); @@ -4125,20 +4105,12 @@ static void fec_ecu_dft_fx( tmp = Exp16Array( *Nfft, Tfr16 ); *exp = add( tmp, add( 2, norm_s( *Nfft ) ) ); move16(); -#ifdef FIX_ISSUE_1237 { -#ifdef FIX_ISSUE_1237_KEEP_EVS_BE Word16 loctmp = *exp; move16(); loctmp = s_min( 15, loctmp ); Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, loctmp ); /*Qin+exp; */ /*Even with limiting loctmp, if Copy_Scale_sig_16_32_no_sat() is used, can lead to 1 difference */ -#else - Copy_Scale_sig_16_32_no_sat( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#endif } -#else - Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ -#endif DoRTFTn_fx( Tfr32, Tfi32, *Nfft ); N_LP = shr( *Nfft, 1 ); diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index 35bb254af..612816efd 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -504,11 +504,7 @@ void FEC_exc_estim_fx( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) -#else - IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) ) -#endif { st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag; move16(); @@ -670,11 +666,7 @@ void FEC_exc_estim_fx( test(); test(); test(); -#ifdef NONBE_FIX_GSC_BSTR IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) -#else - IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) -#endif { /* For GSC - the excitation is already computed */ Copy( exc, exc2, st_fx->L_frame ); diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index e50abddd6..e820f1399 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -76,13 +76,11 @@ void ivas_DetectTonalComponents_fx( pScaledMdctSpectrum[i] = L_shl( lastMDCTSpectrum[i], 16 ); /*15-lastMDCTSpectrum_exp+16 -> 31 - lastMDCTSpectrum_exp*/ move32(); } -#ifdef MSAN_FIX FOR( Word16 i = 0; i < FDNS_NPTS; i++ ) { sns_int_scf_fx[i] = L_shl_sat( scaleFactors[i], add( 1, scaleFactors_exp[i] ) ); // Q16 move32(); } -#endif IF( psychParamsCurrent == NULL ) { nBands = FDNS_NPTS; @@ -94,12 +92,6 @@ void ivas_DetectTonalComponents_fx( } ELSE { -#ifndef MSAN_FIX - FOR( Word16 i = 0; i < FDNS_NPTS; i++ ) - { - sns_int_scf_fx[i] = L_shl( scaleFactors[i], add( 1, scaleFactors_exp[i] ) ); // Q16 - } -#endif q_pScaledMdctSpectrum = sub( 31, lastMDCTSpectrum_exp ); sns_shape_spectrum_fx( pScaledMdctSpectrum, &q_pScaledMdctSpectrum, psychParamsCurrent, sns_int_scf_fx, 16, nSamplesCore, NULL ); q_pScaledMdctSpectrum = add( q_pScaledMdctSpectrum, 1 ); diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 0f94a7558..7a3c78644 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -113,7 +113,6 @@ ivas_error acelp_core_dec_fx( FD_BWE_DEC_HANDLE hBWE_FD; TCX_DEC_HANDLE hTcxDec; ivas_error error; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( tdm_lspQ_PCh ); (void) ( tdm_lsfQ_PCh ); (void) ( use_cldfb_for_dft ); @@ -125,7 +124,6 @@ ivas_error acelp_core_dec_fx( (void) ( output ); (void) ( read_sid_info ); (void) hStereoCng; -#endif hMusicPF = st_fx->hMusicPF; hBPF = st_fx->hBPF; hBWE_TD = st_fx->hBWE_TD; @@ -666,21 +664,13 @@ ivas_error acelp_core_dec_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif test(); test(); IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) { -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, TRANSITION, -1, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif } } diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 2ca524bb0..5807f2c67 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -83,22 +83,14 @@ ivas_error acelp_core_dec_ivas_fx( Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ -#ifdef MSAN_FIX Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ -#else - Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ -#endif Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ Word32 enr_q_fx; /* E information for FER protection */ Word16 tmp_noise_fx; /* Long term temporary noise energy */ Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ Word16 FEC_pitch_fx; /* FEC pitch */ -#ifdef MSAN_FIX Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ -#else - Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ -#endif Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ Word16 i, j, int_fs; Word16 tc_subfr; @@ -133,13 +125,9 @@ ivas_error acelp_core_dec_ivas_fx( ivas_error error; Word32 bpf_error_signal_fx[L_FRAME16k]; -#ifdef MSAN_FIX set32_fx( bpf_error_signal_fx, 0, L_FRAME16k ); -#endif Word16 bpf_error_signal_16fx[L_FRAME16k]; -#ifdef MSAN_FIX set16_fx( bpf_error_signal_16fx, 0, L_FRAME16k ); -#endif set16_fx( Aq_fx, 0, NB_SUBFR16k * ( M + 1 ) ); set16_fx( old_bwe_exc_fx, 0, ( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ) ); Word16 tmp; @@ -178,7 +166,6 @@ ivas_error acelp_core_dec_ivas_fx( IF( EQ_32( st->core_brate, SID_2k40 ) ) { FdCng_decodeSID_ivas_fx( st ); -#ifdef FIX_ISSUE_1218 Word16 n1, n2; n1 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART ); n2 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); @@ -188,9 +175,6 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( old_NoiseEstExp, common_e ) ); st->hFdCngDec->hFdCngCom->sidNoiseEstExp = common_e; move16(); -#else - rescale_fdCngDec( st->hFdCngDec, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); -#endif } FOR( i = 0; i < NPART; i++ ) { @@ -621,11 +605,7 @@ ivas_error acelp_core_dec_ivas_fx( { test(); test(); -#ifdef FIX_1189_GSC_IVAS_OMASA IF( EQ_16( st->coder_type, AUDIO ) || ( EQ_16( st->coder_type, INACTIVE ) && EQ_16( st->inactive_coder_type_flag, 1 ) ) ) -#else - IF( EQ_16( st->coder_type, AUDIO ) || ( st->coder_type == INACTIVE && LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) -#endif { st->GSC_IVAS_mode = get_next_indice_fx( st, 2 ); move16(); @@ -642,14 +622,6 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->cng_type == LP_CNG ) { CNG_dec_ivas_fx( st, last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sid_bw, q_env_fx ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - FOR( Word32 nsf = 0; nsf < NB_SUBFR16k; nsf++ ) - { - Scale_sig( Aq_fx + imult3216( nsf, ( M + 1 ) ), M + 1, sub( norm_s( Aq_fx[nsf * ( M + 1 )] ), Q2 ) ); - Aq_fx[nsf * ( M + 1 )] = ONE_IN_Q12; - move16(); - } -#endif Copy( Aq_fx, st->Aq_cng, add( M, 1 ) ); /* comfort noise generation */ @@ -746,11 +718,7 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->hMusicPF && st->hGSCDec ) { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, -#ifdef FIX_ISSUE_1291 L_FRAME32k, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); -#else - imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); -#endif } IF( st->hPFstat != NULL ) { @@ -781,9 +749,6 @@ ivas_error acelp_core_dec_ivas_fx( /* synthesis at 12.8kHz sampling rate */ -#ifndef FIX_1100_REMOVE_LPC_RESCALING - Aq_fx[0] = ONE_IN_Q12; -#endif move16(); syn_12k8_fx( st->L_frame, Aq_fx, exc2_fx, psyn_fx, st->mem_syn2_fx, 1, st->Q_exc, st->Q_syn ); syn_12k8_fx( st->L_frame, Aq_fx, exc3_fx, syn1_fx, st->mem_syn3_fx, 1, st->Q_exc, st->Q_syn ); @@ -804,11 +769,7 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn -> Q(-1) IF( st->hBWE_FD != NULL ) { -#ifdef FIX_ISSUE_1290 save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); -#else - save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); -#endif } } @@ -848,21 +809,13 @@ ivas_error acelp_core_dec_ivas_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, st->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif test(); test(); IF( EQ_16( st->coder_type, TRANSITION ) && LT_16( tc_subfr, L_SUBFR ) && EQ_16( st->L_frame, L_FRAME ) ) { -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, TRANSITION, -1, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif } } @@ -944,18 +897,6 @@ ivas_error acelp_core_dec_ivas_fx( st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); move16(); } -#ifndef FIX_1100_REMOVE_LPC_RESCALING -#ifndef MSAN_FIX - for ( int nsf = 0; nsf < NB_SUBFR16k; nsf++ ) -#else - FOR( Word32 nsf = 0; nsf < st->nb_subfr; nsf++ ) -#endif - { - Scale_sig( Aq_fx + imult3216( nsf, ( M + 1 ) ), M + 1, sub( norm_s( Aq_fx[nsf * ( M + 1 )] ), Q2 ) ); // Q(x-2) - Aq_fx[nsf * ( M + 1 )] = ONE_IN_Q12; - move16(); - } -#endif test(); IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) { @@ -1129,11 +1070,7 @@ ivas_error acelp_core_dec_ivas_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ -#ifdef NONBE_FIX_GSC_BSTR Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#else - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#endif /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames @@ -1291,18 +1228,6 @@ ivas_error acelp_core_dec_ivas_fx( lsf_dec_bfi( MODE1, lsf_new_fx, st->lsf_old_fx, st->lsf_adaptive_mean_fx, NULL, st->mem_MA_fx, st->mem_AR_fx, st->stab_fac_fx, st->last_coder_type, st->L_frame, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, 0, st->bwidth ); FEC_lsf2lsp_interp( st, st->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING -#ifndef MSAN_FIX - for ( int nsf = 0; nsf < NB_SUBFR16k; nsf++ ) -#else - FOR( Word32 nsf = 0; nsf < st->nb_subfr; nsf++ ) -#endif - { - Scale_sig( Aq_fx + imult3216( nsf, ( M + 1 ) ), M + 1, sub( norm_s( Aq_fx[nsf * ( M + 1 )] ), Q2 ) ); // Qx->Q(x-2) - Aq_fx[nsf * ( M + 1 )] = ONE_IN_Q12; - move16(); - } -#endif IF( EQ_16( st->nelp_mode_dec, 1 ) ) { /* SC-VBR */ @@ -1340,11 +1265,7 @@ ivas_error acelp_core_dec_ivas_fx( } /* Apply energy matching when switching to inactive frames */ -#ifdef NONBE_FIX_GSC_BSTR Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#else - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); -#endif /* update past excitation signals for LD music post-filter */ IF( st->hMusicPF != NULL ) @@ -1766,23 +1687,14 @@ ivas_error acelp_core_dec_ivas_fx( pRealSave_fx[i] = realBufferSave_fx[i]; pImagSave_fx[i] = imagBufferSave_fx[i]; } -#ifndef MSAN_FIX - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 -#endif IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 -#endif Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 } -#ifdef MSAN_FIX FOR( i = 0; i < st->L_frame; i++ ) -#else - for ( i = 0; i < L_FRAME16k; i++ ) -#endif { syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); // Q12 move32(); @@ -1803,15 +1715,7 @@ ivas_error acelp_core_dec_ivas_fx( q_bpf_error_signal = Q6; move16(); -#ifdef MSAN_FIX -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#endif -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn ); // Q6 -#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 @@ -1910,9 +1814,6 @@ ivas_error acelp_core_dec_ivas_fx( #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifndef MSAN_FIX - Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); // Q_real-1 -#endif FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { @@ -1932,11 +1833,7 @@ ivas_error acelp_core_dec_ivas_fx( } } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, 0, st->cldfbSynHB ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, st->cldfbSynHB ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( save_hb_synth_fx, L_FRAME48k, negate( ( sub( Q_real, 1 ) ) ) ); // Q0 Scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 @@ -1956,11 +1853,7 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // Q_real-1 st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( synth_fx, L_FRAME48k, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSynHB->Q_cldfb_state = Q10; @@ -2003,20 +1896,9 @@ ivas_error acelp_core_dec_ivas_fx( #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); -#endif -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ -#ifdef MSAN_FIX scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 -#else - Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); -#endif scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); @@ -2030,11 +1912,7 @@ ivas_error acelp_core_dec_ivas_fx( Word16 nSamples = NS2SA_FX2( i_mult( st->L_frame, FRAMES_PER_SEC ), FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ -#ifndef MSAN_FIX - for ( i = 0; i < L_FRAME16k; i++ ) -#else FOR( i = 0; i < st->L_frame; i++ ) -#endif { syn_32_fx[i] = L_shr( L_deposit_h( psyn_fx[i] ), add( 4, st->Q_syn ) ); move32(); @@ -2057,11 +1935,7 @@ ivas_error acelp_core_dec_ivas_fx( // Get Q-factor q_bpf_error_signal = Q6; move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#else - Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 -#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 @@ -2116,21 +1990,10 @@ ivas_error acelp_core_dec_ivas_fx( #else /* OPT_STEREO_32KBPS_V1 */ scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); -#endif -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ -#ifdef MSAN_FIX Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 -#else - Scale_sig32( synth_fx, L_FRAME48k, -( Q_real - 1 ) ); -#endif Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); @@ -2146,11 +2009,7 @@ ivas_error acelp_core_dec_ivas_fx( } /* Copy output signal */ -#ifndef MSAN_FIX - Scale_sig( syn_tmp_fx, L_FRAME16k + L_SUBFR, -st->Q_syn ); -#else Scale_sig( syn_tmp_fx, add( st->L_frame, L_SUBFR ), negate( st->Q_syn ) ); // Q0 -#endif IF( st->element_mode > EVS_MONO ) { Copy( psyn_fx, output_fx, st->L_frame ); /*Q_syn*/ @@ -2173,24 +2032,14 @@ ivas_error acelp_core_dec_ivas_fx( IF( ( EQ_16( st->L_frame, L_FRAME ) && ( st->bwidth != NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st->extl, -1 ) || EQ_16( st->extl, SWB_CNG ) || ( EQ_16( st->extl, WB_BWE ) && st->extl_brate == 0 && NE_16( st->coder_type, AUDIO ) ) ) ) ) { -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q0 -#else - Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); -#endif hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2 ); -#ifdef MSAN_FIX Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, output_frame, 0 ); -#else - Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, L_FRAME48k, 0 ); -#endif } ELSE { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } } @@ -2225,11 +2074,7 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( !st->ppp_mode_dec && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#endif non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc } @@ -2270,18 +2115,7 @@ ivas_error acelp_core_dec_ivas_fx( { Copy_Scale_sig_32_16( save_hb_synth_fx, save_hb_synth_fx16, L_FRAME48k, 0 ); // Q0 } -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q_syn2 -#else - Copy_Scale_sig_32_16( synth_fx, synth_fx16, L_FRAME48k, 0 ); -#endif -#ifndef FIX_1100_REMOVE_LPC_RESCALING - if ( st->hFdCngDec ) - { - st->hFdCngDec->hFdCngCom->A_cng[0] = ONE_IN_Q12; - move16(); - } -#endif } pop_wmops(); diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 6a1e60b06..9013f2f03 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -128,11 +128,7 @@ ivas_error acelp_core_switch_dec_fx( * Excitation decoding *----------------------------------------------------------------*/ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); -#else - config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); -#endif decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); @@ -819,11 +815,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( *----------------------------------------------------------------*/ /* CLDFB analysis of the synthesis at internal sampling rate */ Qtmp = sub( 11, st_fx->Q_syn ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) -#else - Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) -#endif IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st_fx->cldfbAna ) ), IVAS_ERR_OK ) ) { return error; @@ -845,11 +837,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), 0, st_fx->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); move16(); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 1f6b0dd51..05125318f 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -898,9 +898,7 @@ ivas_error core_switching_post_dec_fx( HQ_DEC_HANDLE hHQ_core; ivas_error error; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( last_element_mode ); -#endif hBWE_TD = st_fx->hBWE_TD; hBWE_FD = st_fx->hBWE_FD; hHQ_core = st_fx->hHQ_core; @@ -2058,11 +2056,7 @@ static void core_switch_lb_upsamp_fx( } /* synthesis of the combined signal */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ /*rescaling whole buffer to a common Q*/ no_col = st->cldfbSyn->no_col; @@ -2100,13 +2094,8 @@ static void smoothTransitionDtxToTcx_fx( Word16 i, filter_len; Word16 w, step, fade_in; Word32 mem; -#ifdef MSAN_FIX - Word16 smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; - Word16 smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; -#else Word16 smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; Word16 smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; -#endif set16_fx( smoothing_input_buffer, 0, 2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k ); set16_fx( smoothing_out_buffer, 0, 2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k ); @@ -2241,10 +2230,8 @@ ivas_error core_switching_pre_dec_ivas_fx( test(); IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) { -#ifdef MSAN_FIX st->hBWE_TD->prev_hb_synth_fx_exp = 31; move16(); -#endif // MSAN_FIX /* reset BWE memories */ set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; @@ -2262,9 +2249,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->hBWE_FD != NULL ) @@ -2379,11 +2364,7 @@ ivas_error core_switching_pre_dec_ivas_fx( return error; } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, 0, st->cldfbSyn ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfb_restore_memory_ivas_fx( st->cldfbSyn ); Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); @@ -2587,9 +2568,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->hBWE_FD != NULL ) @@ -2639,9 +2618,7 @@ ivas_error core_switching_pre_dec_ivas_fx( IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->hBWE_FD != NULL ) @@ -2662,11 +2639,7 @@ ivas_error core_switching_pre_dec_ivas_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#else - Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#endif Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); st->cldfbAna->Q_cldfb_state = Q10; move16(); diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index bdfac224f..325beb9f3 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -693,11 +693,7 @@ ivas_error decod_gen_voic_ivas_fx( * Transform domain contribution decoding *-----------------------------------------------------------------*/ test(); -#ifdef NONBE_FIX_GSC_BSTR IF( !st_fx->inactive_coder_type_flag && st_fx->coder_type == INACTIVE ) -#else - IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( st_fx->coder_type == INACTIVE ) ) -#endif { transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); } diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 8ff50f8a5..e2ea02dcc 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -2682,11 +2682,7 @@ void IMDCT_ivas_fx( } move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE set16_fx( win_fx, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) >> 1 ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 tcx_offset_tmp = add( tcx_offset, shr( L_ola, 1 ) ); set16_fx( xn_buf_fx, 0, tcx_offset_tmp ); /* zero left end of buffer */ @@ -2865,16 +2861,10 @@ void IMDCT_ivas_fx( q_tmp_fx_32 = q_xn_buf_fx_32; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 diff = sub( q_tmp_fx_32, q_win ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE old_out_fx_32[ind] = L_shl( old_out_fx[ind], diff ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - old_out_fx_32[ind] = L_shl( old_out_fx[ind], sub( q_tmp_fx_32, q_win ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move32(); } @@ -2882,13 +2872,8 @@ void IMDCT_ivas_fx( FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], diff ) ); xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - old_out_fx[ind] = (Word16) L_shr( old_out_fx_32[ind], sub( q_tmp_fx_32, q_win ) ); - xn_buf_fx[ind] = (Word16) L_shr( xn_buf_fx_32[ind], sub( q_tmp_fx_32, q_win ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move16(); move16(); } @@ -2912,39 +2897,24 @@ void IMDCT_ivas_fx( q_tmp_fx_32 = sub( q_xn_buf_fx_32, res_e ); // v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 q_diff = sub( q_xn_buf_fx_32, q_win ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = extract_l( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = (Word16) L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], sub( q_xn_buf_fx_32, q_win ) ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move16(); } window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, &q_old_out, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE q_diff = sub( q_old_out, q_win ); Word16 diff = sub( q_tmp_fx_32, q_win ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( Word16 ind = 0; ind < L_frame; ind++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE old_out_fx[ind] = shr_sat( old_out_fx[ind], q_diff ); move16(); xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff ); move16(); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - old_out_fx[ind] = shr_sat( old_out_fx[ind], sub( q_old_out, q_win ) ); - move16(); - xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], sub( q_tmp_fx_32, q_win ) ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } } aldo = 1; @@ -4441,11 +4411,7 @@ void decoder_tcx_noisefilling_fx( /* get the starting location of the subframe in the frame */ IF( EQ_16( st->core, TCX_10_CORE ) ) { -#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); -#else - st->hPlcInfo->subframe = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) ); -#endif move16(); } } diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index f9833e80a..0bc7794dc 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -713,7 +713,6 @@ void decision_matrix_dec_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR /*-----------------------------------------------------------------* * set inactive coder_type flag in ACELP core *-----------------------------------------------------------------*/ @@ -727,6 +726,5 @@ void decision_matrix_dec_fx( move16(); } -#endif return; } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index c509d5d10..df18d3dba 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -187,9 +187,7 @@ void initFdCngDec_ivas_fx( st->CNG_mode = -1; move16(); Copy( st->lsp_old_fx, st->lspCNG_fx, M ); /*Q15*/ -#ifdef MSAN_FIX hFdCngDec->hFdCngCom->sid_frame_counter = 0; -#endif return; } @@ -1765,12 +1763,8 @@ Word16 ApplyFdCng_ivas_fx( { FOR( ; j <= hFdCngCom->part[k]; j++ ) { -#ifdef FIX_ISSUE_1218 /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ -#else - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ -#endif move32(); } } @@ -5275,11 +5269,7 @@ void generate_stereo_masking_noise_fx( IF( st->idchan == 0 ) { hFdCngCom = st->hFdCngDec->hFdCngCom; -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#endif Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); @@ -5287,11 +5277,7 @@ void generate_stereo_masking_noise_fx( IF( !fadeOut ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#endif generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 /* Generate masking noise for secondary channel */ IF( flag_sec_CNA ) diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index 6c63377fd..8f29eb9d1 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -92,11 +92,7 @@ void decod_audio_fx( } /* set bit-allocation */ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif /*---------------------------------------------------------------* * Decode energy dynamics @@ -522,11 +518,7 @@ void decod_audio_ivas_fx( } /* set bit-allocation */ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif /*---------------------------------------------------------------* * Decode energy dynamics @@ -1372,14 +1364,10 @@ void gsc_dec_ivas_fx( } pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); -#ifdef MSAN_FIX IF( nb_subbands > 0 ) { Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ } -#else - Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ -#endif seed_init = 0; move16(); @@ -1435,11 +1423,7 @@ void gsc_dec_ivas_fx( } if ( concat_out[j] < 0 ) { -#ifdef BASOP_NOGLOB_TMP_715 seed_init = add_sat( seed_init, 3 ); /* Q0 */ -#else - seed_init = add( seed_init, 3 ); -#endif } } diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 714245514..4d1ef6774 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -627,9 +627,7 @@ void ivas_hq_core_dec_fx( set16_fx( gapsynth_fx, 0, L_FRAME48k ); set16_fx( num_bands_p, 0, MAX_SB_NB ); set16_fx( ynrm, 39, NB_SFM ); /* Initialize to the smallest value */ -#ifdef MSAN_FIX set16_fx( wtda_audio_16, 0, 2 * L_FRAME48k ); -#endif mean_en_high_fx = 0; move16(); Q_audio = 12; @@ -951,9 +949,6 @@ void ivas_hq_core_dec_fx( index = tcx_cfg->tcx_last_overlap_mode; /* Q0 */ move16(); -#ifndef MSAN_FIX - Copy_Scale_sig_32_16( wtda_audio, wtda_audio_16, 2 * L_FRAME48k, -13 ); -#endif /* LB synthesis */ E_audio = sub( 31, Q_audio ); diff --git a/lib_dec/hq_hr_dec_fx.c b/lib_dec/hq_hr_dec_fx.c index d72f0ec45..89864bc3b 100644 --- a/lib_dec/hq_hr_dec_fx.c +++ b/lib_dec/hq_hr_dec_fx.c @@ -100,7 +100,6 @@ void hq_pred_hb_bws_fx( } ELSE { -#ifdef EVS_FUNC_MODIFIED st_fx->prev_ener_shb_fx = 0; move16(); L_tmp = L_deposit_l( 0 ); @@ -111,15 +110,6 @@ void hq_pred_hb_bws_fx( L_tmp = Mpy_32_16_1( L_tmp, 2979 ); // Q1 st_fx->prev_ener_shb_fx = extract_l( L_tmp ); /*Q1*/ move16(); -#else - st_fx->prev_ener_shb_fx = 0; - move16(); - FOR( i = 0; i < SWB_FENV - 3; i++ ) - { - st_fx->prev_ener_shb_fx = add( st_fx->prev_ener_shb_fx, SWB_fenv[i] ); /*Q1*/ - } - st_fx->prev_ener_shb_fx = mult( st_fx->prev_ener_shb_fx, 2979 ); /*Q1*/ -#endif } } diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 5bfa7476a..60e649a08 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -2883,9 +2883,6 @@ static void IGF_getWhiteSpectralData_ivas( Word16 j; Word32 ak; Word16 ak_e; -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Word16 tmp_16; -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 tmp_e; Word16 out_e_arr[IGF_START_MX + MAX_IGF_SFB_LEN]; Word16 max_out_e; @@ -2904,23 +2901,18 @@ static void IGF_getWhiteSpectralData_ivas( Word16 guard_bits = add( find_guarded_bits_fx( add( i_mult( 2, level ), 1 ) ), 1 ) / 2; s_l = sub( s_l, guard_bits ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 shift = sub( shl( s_l, 1 ), 32 ); Word16 eff_e = sub( shl( sub( in_e, s_l ), 1 ), 15 ); Word16 diff = add( 21, in_e ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 quo = BASOP_Util_Divide3216_Scale( ONE_IN_Q30, add( shl( level, 1 ), 1 ), &tmp_e ); tmp_e = add( tmp_e, 1 ); ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 -#ifdef OPT_SBA_AVOID_SPAR_RESCALE ak_e = sub( ak_e, 1 ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( i = start; i < stop - level; i++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word64 temp = 0; move64(); FOR( j = i - level; j < i + level + 1; j++ ) @@ -2935,30 +2927,11 @@ static void IGF_getWhiteSpectralData_ivas( out_e_arr[i] = sub( diff, n ); move16(); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - ak = 0; - move32(); - move32(); - FOR( j = i - level; j < i + level + 1; j++ ) - { - tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l - ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) - } - ak = Mult_32_16( ak, quo ); // add( shl( level, 1 ), 1 ), &tmp_e ) ); - - - n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); - n = shr( n, 1 ); - - out_e_arr[i] = add( sub( 21, n ), in_e ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ max_out_e = s_max( max_out_e, out_e_arr[i] ); } FOR( ; i < stop; i++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word64 temp = 0; move64(); @@ -2974,24 +2947,6 @@ static void IGF_getWhiteSpectralData_ivas( out_e_arr[i] = sub( diff, n ); move16(); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - ak = 0; - move32(); - - FOR( j = i - level; j < stop; j++ ) - { - tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l - ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) - } - ak = L_deposit_h( BASOP_Util_Divide3216_Scale( ak, sub( stop, sub( i, level ) ), &tmp_e ) ); - ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 - - n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); - n = shr( n, 1 ); - - out_e_arr[i] = add( sub( 21, n ), in_e ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ max_out_e = s_max( max_out_e, out_e_arr[i] ); } diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 934433132..b588fdce1 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -315,10 +315,8 @@ ivas_error init_decoder_fx( move16(); /*1; Q15*/ st_fx->exc_pe_fx = 0; // Q_stat_noise move16(); -#ifdef MSAN_FIX st_fx->Q_stat_noise = 31; move16(); -#endif // MSAN_FIX /*-----------------------------------------------------------------* * LD music post-filter *-----------------------------------------------------------------*/ @@ -1036,10 +1034,8 @@ ivas_error init_decoder_ivas_fx( move16(); st_fx->exc_pe_fx = 0; move16(); -#ifdef MSAN_FIX st_fx->Q_stat_noise = 31; move16(); -#endif st_fx->prev_coder_type = GENERIC; move16(); @@ -1139,9 +1135,7 @@ ivas_error init_decoder_ivas_fx( } hf_synth_init_fx( st_fx->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st_fx->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } ELSE { diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index 85fefadbc..f78f14e8e 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -66,17 +66,11 @@ static void ivas_binRenderer_filterModule_fx( { Word16 bandIdx, k, chIdx, tapIdx; Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx; -#ifdef OPT_BASOP_ADD_v1 Word16 Q_filterStates; -#else /* OPT_BASOP_ADD_v1 */ - Word16 *Q_filterStates; -#endif /* OPT_BASOP_ADD_v1 */ const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx; Word16 shift_q; -#ifdef OPT_BASOP_ADD_v1 Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStatesLeft; move16(); -#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -84,9 +78,6 @@ static void ivas_binRenderer_filterModule_fx( { filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] ); filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] ); -#ifndef OPT_BASOP_ADD_v1 - Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx][0] ); -#endif /* OPT_BASOP_ADD_v1 */ filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29 filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29 @@ -108,13 +99,6 @@ static void ivas_binRenderer_filterModule_fx( filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1]; move32(); -#ifndef OPT_BASOP_ADD_v1 - shift_q = sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ); - outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); - outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); - outRealRight_fx = W_shr( outRealRight_fx, shift_q ); - outImagRight_fx = W_shr( outImagRight_fx, shift_q ); -#endif /* OPT_BASOP_ADD_v1 */ outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates @@ -127,40 +111,24 @@ static void ivas_binRenderer_filterModule_fx( outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates -#ifndef OPT_BASOP_ADD_v1 - Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ } -#ifdef OPT_BASOP_ADD_v1 shift_q = add( sub( Q_filterStates, Q_curr ), 1 ); -#else /* OPT_BASOP_ADD_v1 */ - shift_q = add( sub( Q_filterStates[1], Q_curr ), 1 ); -#endif /* OPT_BASOP_ADD_v1 */ -#ifdef OPT_BASOP_ADD_v1 IF( shift_q != 0 ) { -#endif /* OPT_BASOP_ADD_v1 */ outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); // Q_curr outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); // Q_curr outRealRight_fx = W_shr( outRealRight_fx, shift_q ); // Q_curr outImagRight_fx = W_shr( outImagRight_fx, shift_q ); // Q_curr -#ifdef OPT_BASOP_ADD_v1 hBinRenderer->hBinRenConvModule->Q_filterStatesLeft = Q_curr; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx]; move32(); filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx]; move32(); -#ifndef OPT_BASOP_ADD_v1 - Q_filterStates[0] = Q_curr; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ /* Left Real and Imag */ @@ -346,12 +314,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#ifndef OPT_BASOP_ADD_v1 - IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -365,12 +327,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#ifndef OPT_BASOP_ADD_v1 - IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#endif /* OPT_BASOP_ADD_v1 */ FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { @@ -384,12 +340,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#ifndef OPT_BASOP_ADD_v1 - IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#endif /* OPT_BASOP_ADD_v1 */ } } /* set memories */ @@ -434,12 +384,8 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); -#ifdef OPT_BASOP_ADD_v1 hBinRenConvModule->Q_filterStatesLeft = 31; move16(); -#else /* OPT_BASOP_ADD_v1 */ - set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTapsArray[bandIdx] ); -#endif /* OPT_BASOP_ADD_v1 */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftBRIRReal_fx[bandIdx][tmp]; @@ -453,12 +399,8 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); -#ifdef OPT_BASOP_ADD_v1 hBinRenConvModule->Q_filterStatesLeft = 31; move16(); -#else /* OPT_BASOP_ADD_v1 */ - set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTaps ); -#endif /* OPT_BASOP_ADD_v1 */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp]; @@ -1323,10 +1265,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; -#ifndef OPT_BASOP_ADD_v1 - free( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] ); - hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = NULL; -#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); @@ -1335,10 +1273,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; -#ifndef OPT_BASOP_ADD_v1 - free( hBinRenConvModule->Q_filterStatesLeft[bandIdx] ); - hBinRenConvModule->Q_filterStatesLeft[bandIdx] = NULL; -#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx ); @@ -1347,10 +1281,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx ); hBinRenConvModule->filterStatesLeftImag_fx = NULL; -#ifndef OPT_BASOP_ADD_v1 - free( hBinRenConvModule->Q_filterStatesLeft ); - hBinRenConvModule->Q_filterStatesLeft = NULL; -#endif /* OPT_BASOP_ADD_v1 */ free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 37c32a8b1..4e654030b 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -336,11 +336,7 @@ ivas_error ivas_core_dec_fx( Word16 ovl, fade_len; IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#endif L_lerp_fx_q11( sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->L_frame, sts[0]->last_L_frame ); Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_out_LB_fx32, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda_LB } @@ -527,11 +523,7 @@ ivas_error ivas_core_dec_fx( return error; } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 -#else - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 -#endif Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 IF( st->cldfbAna ) { @@ -551,9 +543,6 @@ ivas_error ivas_core_dec_fx( st->cldfbSyn->Q_cldfb_state = Q11; move16(); } -#ifndef FIX_ISSUE_1279 /* the update of prev_Q_syn is already done inside rescale_mem( ) */ - st->prev_Q_syn = st->Q_syn; -#endif move16(); IF( save_hb_synth_32_fx ) @@ -641,11 +630,7 @@ ivas_error ivas_core_dec_fx( ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 -#ifdef MSAN_FIX Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 -#else - Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); -#endif Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 } @@ -660,11 +645,7 @@ ivas_error ivas_core_dec_fx( td_stereo_param_updt_fx( st->lsp_old_fx, st->lsf_old_fx, st->old_pitch_buf_16_fx + st->nb_subfr, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, hStereoTD->tdm_Pri_pitch_buf_fx, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 -#endif } } /* n_channels loop */ @@ -910,19 +891,11 @@ ivas_error ivas_core_dec_fx( /* Memories Re-Scaling */ IF( hBWE_TD != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 -#endif Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } @@ -936,11 +909,7 @@ ivas_error ivas_core_dec_fx( test(); IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) && !( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#else - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#endif } IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) @@ -954,11 +923,7 @@ ivas_error ivas_core_dec_fx( test(); IF( sba_dirac_stereo_flag && hSCE && EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#else - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx -#endif } /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ @@ -985,11 +950,7 @@ ivas_error ivas_core_dec_fx( } ELSE { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 -#endif } Scale_sig32( output_32_fx[n], L_FRAME48k, ( Q11 - Q4 ) ); // Q11 @@ -1003,16 +964,12 @@ ivas_error ivas_core_dec_fx( move16(); } -#ifdef MSAN_FIX IF( Q_synth > 0 ) { Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Q_synth = 0; move16(); } -#else - Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); -#endif /*------------------reset-code-start---------------------*/ @@ -1078,31 +1035,17 @@ ivas_error ivas_core_dec_fx( } /* Memories Re-Scaling */ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 // Q_input can get value <= -5 Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 -#endif IF( hBWE_FD != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 -#endif } IF( hBWE_TD != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hBWE_TD->old_tbe_synth_fx, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 -#endif } /*---------------------------------------------------------------------* @@ -1205,11 +1148,7 @@ ivas_error ivas_core_dec_fx( q = 2; move16(); Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); // Q0 -#else - Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, L_FRAME48k, negate( add( Q11, q ) ) ); -#endif Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ); // Q8 Copy_Scale_sig_32_16( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, ( 2 * ALLPASSSECTIONS_STEEP ), sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bew_syn2 @@ -1242,7 +1181,6 @@ ivas_error ivas_core_dec_fx( move32(); } stereo_icBWE_dec_fx( hCPE, hb_synth_32_fx[0], hb_synth_32_fx[1], tmp_buffer_fx /*fb_synth_ref*/, voice_factors_fx[0], output_frame, &q, Q_white_exc ); -#ifdef MSAN_FIX test(); test(); test(); @@ -1254,10 +1192,6 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } -#else - Scale_sig32( hb_synth_32_fx[0], L_FRAME48k, sub( Q11, q ) ); - Scale_sig32( hb_synth_32_fx[1], L_FRAME48k, sub( Q11, q ) ); -#endif } IF( EQ_16( st->element_mode, EVS_MONO ) ) @@ -1286,11 +1220,7 @@ ivas_error ivas_core_dec_fx( } waveform_adj2_fix( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); -#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->Pitch_fx = 0; -#else - st->hPlcInfo->Pitch = 0; -#endif move16(); } } @@ -1476,13 +1406,8 @@ ivas_error ivas_core_dec_fx( IF( st->hHQ_core != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, st->hHQ_core->Q_old_wtda ) ); // Q11 -#endif } IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 05fec7736..c10c6beda 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -124,22 +124,14 @@ ivas_error ivas_cpe_dec_fx( test(); IF( hCPE->hCoreCoder[ind1] && hCPE->hCoreCoder[ind1]->hHQ_core ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx32, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 -#endif } } FOR( Word16 ind1 = 0; ind1 < 2; ind1++ ) { IF( hCPE->hCoreCoder[ind1]->hHQ_core ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 -#endif hCPE->hCoreCoder[ind1]->hHQ_core->q_old_outLB_fx = Q11; move16(); } diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index a52390f68..40a9ca2d7 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2113,11 +2113,7 @@ void ivas_dirac_dec_render_fx( FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { -#ifdef MSAN_FIX ivas_dirac_dec_render_sf_fx( st_ivas, output_f_local_fx, nchan_transport, NULL, NULL ); -#else - ivas_dirac_dec_render_sf_fx( st_ivas, output_f_local, nchan_transport, NULL, NULL ); -#endif // MSAN_FIX n_samples_sf = i_mult( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->slot_size ); @@ -4108,11 +4104,7 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[ch]->Q_cldfb_state = ( Q6 - 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Word16 no_col = st_ivas->cldfbSynDec[ch]->no_col; move16(); @@ -4215,11 +4207,7 @@ void ivas_dirac_dec_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; move32(); } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, 0, st_ivas->cldfbSynDec[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ IF( !st_ivas->hLsSetupCustom->separate_ch_found ) { @@ -4259,11 +4247,7 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state ) ); // Q6-1 st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state = ( Q6 - 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[cldfbSynIdx] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, st_ivas->cldfbSynDec[cldfbSynIdx] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ // Calculating length of output Word16 no_col = st_ivas->cldfbSynDec[cldfbSynIdx]->no_col; @@ -4332,11 +4316,7 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = ( Q6 - 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, st_ivas->cldfbSynDec[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ // Scaling output from Q6-1 to Q11 Scale_sig32( p_out, out_len, ( Q11 - ( Q6 - 1 ) ) ); diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index b247fd653..114083fad 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -723,11 +723,7 @@ Word16 computeMixingMatrices_fx( Word32 G_hat_fx[MAX_OUTPUT_CHANNELS]; Word16 G_hat_buff_e[MAX_OUTPUT_CHANNELS]; -#ifdef OPT_BASOP_ADD_v1 Word16 mat_mult_buffer2_e, mat_mult_buffer3_e; -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer1_e, mat_mult_buffer2_e, mat_mult_buffer3_e; -#endif /* OPT_BASOP_ADD_v1 */ Word32 mat_mult_buffer3_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; @@ -777,9 +773,7 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); -#ifdef OPT_BASOP_ADD_v1 Word16 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ /* Computing Ky */ FOR( i = 0; i < lengthCy; ++i ) { @@ -792,12 +786,9 @@ Word16 computeMixingMatrices_fx( move32(); Ky_fx_e[i + ( j * lengthCy )] = tmp_e; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, tmp_e ); -#endif /* OPT_BASOP_ADD_v1 */ } } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCy * lengthCy; ++i ) { Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); @@ -805,7 +796,6 @@ Word16 computeMixingMatrices_fx( Ky_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Decomposition of Cx @@ -816,9 +806,7 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); svd_fx( svd_in_buffer_fx, Cx_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCx, lengthCx ); -#ifdef OPT_BASOP_ADD_v1 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { FOR( j = 0; j < lengthCx; ++j ) @@ -830,12 +818,9 @@ Word16 computeMixingMatrices_fx( move32(); Kx_fx_e[( i + ( j * lengthCx ) )] = tmp_e; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, tmp_e ); -#endif /* OPT_BASOP_ADD_v1 */ } } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCx * lengthCx; ++i ) { Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); @@ -843,7 +828,6 @@ Word16 computeMixingMatrices_fx( Kx_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -967,49 +951,15 @@ Word16 computeMixingMatrices_fx( /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ -#ifdef OPT_BASOP_ADD_v1 Word16 mat_mult_buffer1_fx_e; -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer1_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word16 Q_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; - set16_fx( Q_e_arr, Q_e, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); - - matrix_product_mant_exp( Kx_fx, Kx_fx_e, lengthCx, lengthCx, 1, Q_fx, Q_e_arr, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer2_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( Kx_fx, Kx_fx_e[0], lengthCx, lengthCx, 1, Q_fx, Q_e, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); matrix_diag_product_fx_2( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); matrix_product_mant_exp_fx( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e[0], lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_diag_product_fx_1( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); - - matrix_product_mant_exp( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e, lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); - - exp = mat_mult_buffer1_fx_e[0]; - move16(); - FOR( i = 1; i < lengthCy * lengthCx; i++ ) - { - if ( LT_16( exp, mat_mult_buffer1_fx_e[i] ) ) - { - exp = mat_mult_buffer1_fx_e[i]; - move16(); - } - } - - FOR( i = 0; i < lengthCy * lengthCx; i++ ) - { - mat_mult_buffer1_fx[i] = L_shr( mat_mult_buffer1_fx[i], sub( exp, mat_mult_buffer1_fx_e[i] ) ); // Q(31-exp) - move32(); - } - - mat_mult_buffer1_e = exp; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ IF( LT_16( lengthCx, lengthCy ) ) { @@ -1018,11 +968,7 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCx; move16(); -#ifdef OPT_BASOP_ADD_v1 svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); -#else /* OPT_BASOP_ADD_v1 */ - svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); -#endif /* OPT_BASOP_ADD_v1 */ } ELSE { @@ -1031,11 +977,7 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCy; move16(); -#ifdef OPT_BASOP_ADD_v1 svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); -#else /* OPT_BASOP_ADD_v1 */ - svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); -#endif /* OPT_BASOP_ADD_v1 */ } /* Actually Processing P */ @@ -1046,46 +988,25 @@ Word16 computeMixingMatrices_fx( svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, lengthCy, lengthCx ); svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); -#ifdef OPT_BASOP_ADD_v1 mat_mult_buffer1_fx_e = 0; -#else /* OPT_BASOP_ADD_v1 */ - mat_mult_buffer1_e = 0; -#endif /* OPT_BASOP_ADD_v1 */ move16(); mat_mult_buffer2_e = 0; move16(); -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, mat_mult_buffer3_fx, &mat_mult_buffer3_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, lengthCy, lengthCx, 0, - mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, - mat_mult_buffer3_fx, &mat_mult_buffer3_e ); -#endif /* OPT_BASOP_ADD_v1 */ /************************ Formulate M **********************/ -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - - matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; -#ifdef OPT_BASOP_ADD_v1 Word16 mat_mult_buffer1_fx_e1[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; set16_fx( mat_mult_buffer1_fx_e1, mat_mult_buffer1_fx_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Formulate Cr @@ -1096,15 +1017,9 @@ Word16 computeMixingMatrices_fx( Word16 Cx_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; set16_fx( Cx_e_arr, Cx_fx_e, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1 ); matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); -#else /* OPT_BASOP_ADD_v1 */ - matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); - - matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); -#endif /* OPT_BASOP_ADD_v1 */ exp = mixing_matrix_fx_e[0]; move16(); @@ -1143,11 +1058,7 @@ Word16 computeMixingMatrices_fx( } /* Avoid Meaningless negative main diagonal elements */ -#ifdef OPT_BASOP_ADD_v1 IF( Cr_fx[i + ( i * lengthCy )] < 0 ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( Cr_fx[i + ( i * lengthCy )], exp, 0, 0 ) < 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { Cr_fx[i + ( i * lengthCy )] = 0; move32(); @@ -1209,11 +1120,7 @@ Word16 computeMixingMatrices_fx( { /* Avoid correction for very small energies, main diagonal elements of Cy_tilde_p may be negative */ -#ifdef OPT_BASOP_ADD_v1 IF( Cy_tilde_p_fx[i + ( i * lengthCy )] < 0 ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( Cy_tilde_p_fx[i + ( i * lengthCy )], mat_mult_buffer2_e, 0, 0 ) < 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1232,12 +1139,8 @@ Word16 computeMixingMatrices_fx( move16(); } -#ifdef OPT_BASOP_ADD_v1 Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, adj_e[i] ) ); IF( GT_32( adj_fx_p[i], temp ) ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], adj_e[i], 1073741824, 3 ) > 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1322,11 +1225,7 @@ Word16 computeMixingMatricesResidual_fx( Word16 mixing_matrix_e = 0, mat_mult_buffer1_e, adj_e, mat_mult_buffer3_e, mat_mult_buffer2_e; move16(); -#ifdef MSAN_FIX Word32 svd_s_buffer_fx[MAX_OUTPUT_CHANNELS] = { 0 }; -#else - Word32 svd_s_buffer_fx[MAX_OUTPUT_CHANNELS]; -#endif Word16 svd_s_buffer_e[MAX_OUTPUT_CHANNELS]; Word32 L_tmp; Word16 tmp_e; @@ -1370,9 +1269,7 @@ Word16 computeMixingMatricesResidual_fx( svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); /* Computing Ky */ -#ifdef OPT_BASOP_ADD_v1 Word16 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCy; ++i ) { FOR( j = 0; j < lengthCy; ++j ) @@ -1384,13 +1281,10 @@ Word16 computeMixingMatricesResidual_fx( move32(); Ky_fx_e[i + j * lengthCy] = tmp_e; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, tmp_e ); -#endif /* OPT_BASOP_ADD_v1 */ } } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCy * lengthCy; ++i ) { Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); @@ -1398,7 +1292,6 @@ Word16 computeMixingMatricesResidual_fx( Ky_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Decomposition of Cx @@ -1410,9 +1303,7 @@ Word16 computeMixingMatricesResidual_fx( * square root of the diagonal of Cx */ /* Computing Kx */ -#ifdef OPT_BASOP_ADD_v1 max_e = -32; -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { exp = Cx_e; @@ -1421,12 +1312,9 @@ Word16 computeMixingMatricesResidual_fx( move32(); Kx_fx_e[i] = exp; move16(); -#ifdef OPT_BASOP_ADD_v1 max_e = s_max( max_e, exp ); -#endif /* OPT_BASOP_ADD_v1 */ } -#ifdef OPT_BASOP_ADD_v1 FOR( i = 0; i < lengthCx; ++i ) { Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); @@ -1434,7 +1322,6 @@ Word16 computeMixingMatricesResidual_fx( Kx_fx_e[i] = max_e; move16(); } -#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Regularization of Sx @@ -1442,25 +1329,13 @@ Word16 computeMixingMatricesResidual_fx( limit_fx = Kx_fx[0]; move32(); -#ifndef OPT_BASOP_ADD_v1 - limit_e = Kx_fx_e[0]; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 1; i < lengthCx; i++ ) { -#ifdef OPT_BASOP_ADD_v1 IF( GT_32( Kx_fx[i], limit_fx ) ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( Kx_fx[i], Kx_fx_e[i], limit_fx, limit_e ) > 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { limit_fx = Kx_fx[i]; move32(); -#ifndef OPT_BASOP_ADD_v1 - limit_e = Kx_fx_e[i]; - move16(); -#endif /* OPT_BASOP_ADD_v1 */ } } @@ -1468,11 +1343,7 @@ Word16 computeMixingMatricesResidual_fx( L_tmp = L_add( L_tmp, EPSILLON_FX ); limit_fx = L_tmp; move16(); -#ifdef OPT_BASOP_ADD_v1 limit_e = add( Kx_fx_e[0], reg_Sx_e ); -#else /* OPT_BASOP_ADD_v1 */ - limit_e = add( limit_e, reg_Sx_e ); -#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -1622,15 +1493,8 @@ Word16 computeMixingMatricesResidual_fx( *-----------------------------------------------------------------*/ -#ifdef OPT_BASOP_ADD_v1 matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); set16_fx( mat_mult_buffer1_buff_e, mat_mult_buffer1_buff_e[0], MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); -#else /* OPT_BASOP_ADD_v1 */ - Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - - matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); -#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; @@ -1715,12 +1579,8 @@ Word16 computeMixingMatricesResidual_fx( move32(); adj_buff_e[i] = scale; move16(); -#ifdef OPT_BASOP_ADD_v1 Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, scale ) ); IF( GT_32( adj_fx_p[i], temp ) ) // 1073741824 -> 1.0f in Q30 -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], scale, 1073741824, 3 ) > 0 ) // 1073741824 -> 1.0f in Q30 -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -2115,12 +1975,8 @@ Word16 computeMixingMatricesISM_fx( } } -#ifdef OPT_BASOP_ADD_v1 Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, temp_e[i] ) ); IF( GT_32( adj_fx[i], temp ) ) -#else /* OPT_BASOP_ADD_v1 */ - IF( BASOP_Util_Cmp_Mant32Exp( adj_fx[i], temp_e[i], MAX_32, 2 ) > 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { adj_fx[i] = MAX_32; move32(); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 292721723..4770d2193 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1266,9 +1266,7 @@ ivas_error ivas_init_decoder_fx( { return error; } -#ifdef MSAN_FIX set16_fx( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 0, CLDFB_NO_COL_MAX ); -#endif test(); IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup ) { diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index c818af237..7686a5e8a 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -511,9 +511,7 @@ static ivas_error ivas_param_ism_rendering_init_fx( { set32_fx( hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx], 0, PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX ); } -#ifdef MSAN_FIX set16_fx( hParamIsmRendering->exp_mixing_matrix_lin_old_fx, 0, CLDFB_NO_CHANNELS_MAX ); -#endif /* memory allocation for proto matrix and interpolator */ IF( ( hParamIsmRendering->proto_matrix_fx = (Word16 *) malloc( hOutSetup.nchan_out_woLFE * nchan_transport * sizeof( Word16 ) ) ) == NULL ) @@ -1535,11 +1533,7 @@ static void ivas_ism_param_dec_render_sf_fx( Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( sub( Q_real, 1 ), Q11 ) ); // Q_real-1 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = sub( Q_real, 1 ); move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( Q11, sub( Q_real, 1 ) ) ); // Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 1918ce3f3..93e8bb4eb 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -129,10 +129,8 @@ ivas_error ivas_jbm_dec_tc_fx( set_zero_fx( st_ivas->p_output_fx[n], L_FRAME48k ); st_ivas->hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n]; } -#ifdef MSAN_FIX st_ivas->hTcBuffer->no_channels = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); move16(); -#endif } Word16 ch; @@ -434,19 +432,13 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( hCPE->hCoreCoder[0] != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } IF( hCPE->hStereoDft != NULL ) { -#ifdef MSAN_FIX IF( LE_16( st_ivas->nchan_transport, 1 ) ) { st = hCPE->hCoreCoder[0]; @@ -494,9 +486,6 @@ ivas_error ivas_jbm_dec_tc_fx( } } } -#else - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); -#endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // q_dft hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; move16(); @@ -517,14 +506,10 @@ ivas_error ivas_jbm_dec_tc_fx( hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } -#ifdef MSAN_FIX FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx } -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); -#endif ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame, st_ivas->ivas_format == MC_FORMAT ); @@ -532,14 +517,10 @@ ivas_error ivas_jbm_dec_tc_fx( { Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } -#ifdef MSAN_FIX FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 } -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); -#endif scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) @@ -555,7 +536,6 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( hCPE->hStereoDft != NULL ) { -#ifdef MSAN_FIX IF( LE_16( st_ivas->nchan_transport, 1 ) ) { st = hCPE->hCoreCoder[0]; @@ -603,9 +583,6 @@ ivas_error ivas_jbm_dec_tc_fx( } } } -#else - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 -#endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; test(); @@ -971,13 +948,8 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( hCPE->hCoreCoder[0] != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q -#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -1004,24 +976,16 @@ ivas_error ivas_jbm_dec_tc_fx( hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); -#endif ivas_sba_dirac_stereo_dec_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame, 0 ); FOR( i = 0; i < 2; i++ ) { Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, negate( s ) ); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); -#endif scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 FOR( i = 0; i < CPE_CHANNELS; ++i ) @@ -1420,13 +1384,8 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q -#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -1458,23 +1417,15 @@ ivas_error ivas_jbm_dec_tc_fx( hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); -#endif ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame, 1 ); FOR( i = 0; i < 2; i++ ) { Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 -#else - Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); -#endif // MSAN_FIX scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) @@ -1916,10 +1867,8 @@ ivas_error ivas_jbm_dec_render_fx( } } -#ifdef MSAN_FIX st_ivas->hTcBuffer->no_channels = st_ivas->hTcBuffer->nchan_buffer_full; move16(); -#endif // MSAN_FIX /*----------------------------------------------------------------* * Update combined orientation access index *----------------------------------------------------------------*/ @@ -2014,7 +1963,6 @@ ivas_error ivas_jbm_dec_render_fx( ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) { /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ -#ifdef MSAN_FIX FOR( i = 0; i < st_ivas->nchan_transport; i++ ) { FOR( j = 0; j < 16; j++ ) @@ -2025,16 +1973,6 @@ ivas_error ivas_jbm_dec_render_fx( move32(); } } -#else - FOR( i = 0; i < 15; i++ ) - { - FOR( j = 0; j < 16; j++ ) - { - st_ivas->hIsmRendererData->gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q30 -> Q29 - st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q30 -> Q29 - } - } -#endif ivas_ism2sba_sf_fx( st_ivas->hTcBuffer->tc_fx, p_output_fx, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); Word16 sba_num_chans = imult1616( add( st_ivas->hIntSetup.ambisonics_order, 1 ), add( st_ivas->hIntSetup.ambisonics_order, 1 ) ); FOR( j = 0; j < sba_num_chans; j++ ) @@ -2043,7 +1981,6 @@ ivas_error ivas_jbm_dec_render_fx( } -#ifdef MSAN_FIX FOR( i = 0; i < st_ivas->nchan_transport; i++ ) { FOR( j = 0; j < 16; j++ ) @@ -2054,16 +1991,6 @@ ivas_error ivas_jbm_dec_render_fx( move32(); } } -#else - FOR( i = 0; i < 15; i++ ) - { - FOR( j = 0; j < 16; j++ ) - { - st_ivas->hIsmRendererData->gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q29 -> Q30 - st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q29 -> Q30 - } - } -#endif } /* Binaural rendering */ @@ -2136,11 +2063,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2188,11 +2111,7 @@ ivas_error ivas_jbm_dec_render_fx( hSpar->hMdDec->Q_mixer_mat = 30; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2230,11 +2149,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/ { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism] ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism], 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2246,11 +2161,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2262,11 +2173,7 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -2868,11 +2775,7 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available ); /* render the last subframe */ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_osba_dirac_td_binaural_jbm_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx, L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index b2a8bd30b..4c0e7fcc6 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1862,9 +1862,6 @@ void ivas_param_mc_dec_render_fx( /* format converter */ Word16 channel_active[MAX_OUTPUT_CHANNELS]; UWord16 nband_synth; -#ifndef MSAN_FIX - UWord16 nchan_out_init, nbands_to_zero; -#endif UWord32 output_Fs; Word16 tmp_q = 0; move16(); @@ -1878,10 +1875,6 @@ void ivas_param_mc_dec_render_fx( nchan_transport = st_ivas->nchan_transport; move16(); nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); -#ifndef MSAN_FIX - nchan_out_init = nchan_out_transport; - move16(); -#endif output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); @@ -1891,12 +1884,6 @@ void ivas_param_mc_dec_render_fx( { nchan_out_cldfb = BINAURAL_CHANNELS; set16_fx( channel_active, 1, nchan_out_cldfb ); -#ifndef MSAN_FIX - IF( st_ivas->hCombinedOrientationData ) - { - nchan_out_init = MAX_INTERN_CHANNELS; - } -#endif nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); } ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) @@ -1924,21 +1911,12 @@ void ivas_param_mc_dec_render_fx( /* set everything to zero that will not be decoded */ nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; move16(); -#ifdef MSAN_FIX FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) -#else - FOR( ch = 0; ch < nchan_out_init; ch++ ) -#endif { FOR( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) { -#ifdef MSAN_FIX set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); -#else - set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); - set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); -#endif } } @@ -1973,31 +1951,8 @@ void ivas_param_mc_dec_render_fx( slot_idx_start_cldfb_synth = 0; move16(); -#ifndef FIX_1009_OPT_PARAMMC_RENDER - Flag is_zero = 1; - move32(); -#endif FOR( j = 0; j < st_ivas->hParamMC->hMetadataPMC->nbands_coded; j++ ) { -#ifndef FIX_1009_OPT_PARAMMC_RENDER - is_zero = 1; - move16(); - FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_len; i++ ) - { - IF( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j][i] != 0 ) - { - is_zero = 0; - move16(); - } - } - IF( is_zero ) - { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; - move16(); - } - is_zero = 1; - move16(); -#else Flag is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_len ); { if ( is_zero != 0 ) @@ -2006,23 +1961,10 @@ void ivas_param_mc_dec_render_fx( move16(); } } -#endif IF( LT_16( st_ivas->hParamMC->band_grouping[j], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) ) { -#ifndef FIX_1009_OPT_PARAMMC_RENDER - FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len; i++ ) - { - IF( NE_32( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j][i], 0 ) ) - { - is_zero = 0; - move16(); - } - } - IF( is_zero ) -#else is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len ); if ( is_zero != 0 ) -#endif { hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[j] = 0; move16(); @@ -2247,13 +2189,8 @@ void ivas_param_mc_dec_render_fx( Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); scale_sig32( output_f_fx[ch], len, 5 - 11 ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), - imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 } @@ -2742,9 +2679,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( set_zero_fx( mat_mult_buffer1_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); set_zero_fx( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); -#ifdef MSAN_FIX set_zero_fx( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); -#endif Word16 proto_matrix_noLFE_e = 0; move16(); @@ -2941,11 +2876,7 @@ static void ivas_param_mc_get_mixing_matrices_fx( FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) { -#ifdef OPT_BASOP_ADD_v1 if ( Cproto_diag_fx[ch_idx1] < 0 ) -#else /* OPT_BASOP_ADD_v1 */ - if ( BASOP_Util_Cmp_Mant32Exp( Cproto_diag_fx[ch_idx1], Cproto_diag_e, 0, 0 ) < 0 ) -#endif /* OPT_BASOP_ADD_v1 */ { Cproto_diag_fx[ch_idx1] = 0; move16(); diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index f4d6cb535..40f9f46e2 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -716,13 +716,8 @@ static void ivas_mc_paramupmix_dec_sf( Word16 noparamupmix_delay, n_samples_rendered; MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; Word16 subframeIdx, idx_in, maxBand; -#ifdef MSAN_FIX Word32 Cldfb_RealBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; Word32 Cldfb_ImagBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; -#else - Word32 Cldfb_RealBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_ImagBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif // MSAN_FIX Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -874,11 +869,7 @@ static void ivas_mc_paramupmix_dec_sf( scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q5 - Q11 ); // Q11 -> Q5 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), 0, st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q5 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); @@ -913,13 +904,8 @@ static void ivas_mc_paramupmix_dec_sf( ptr_re_fx[0] = Cldfb_RealBuffer_fx[ch][slot_idx]; // Q6 ptr_im_fx[0] = Cldfb_ImagBuffer_fx[ch][slot_idx]; // Q6 -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), hMCParamUpmix->num_freq_bands, 0, st_ivas->cldfbSynDec[ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), - hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); // Q6 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 4eb0ad686..7e1597749 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -84,10 +84,8 @@ ivas_error ivas_mct_dec_fx( set16_fx( x_len[0], 0, NB_DIV ); set16_fx( x_len[1], 0, NB_DIV ); Decoder_State **sts; -#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS Word32 *p_output_orig_fx[2]; Word32 synth_32_fx[CPE_CHANNELS][L_FRAME_PLUS]; -#endif Word16 synth_fx[CPE_CHANNELS][L_FRAME_PLUS]; //(Q_synth) Word32 ivas_total_brate; ivas_error error; @@ -164,7 +162,6 @@ ivas_error ivas_mct_dec_fx( /* MCT side bits decoder */ ivas_mct_side_bits_fx( hMCT, st_ivas->hCPE, nCPE, st_ivas->hCPE[0]->hCoreCoder[0], st_ivas->bfi, st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream, ivas_total_brate, nb_bits_metadata ); -#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS /* in case of switching from an SID frame (with ACELP core) to MCT, buffer of L_FRAME_PLUS samples is needed -> use synth[] as a temporary buffer */ IF( st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) { @@ -174,7 +171,6 @@ ivas_error ivas_mct_dec_fx( output_fx[n] = synth_32_fx[n]; } } -#endif FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { @@ -348,13 +344,8 @@ ivas_error ivas_mct_dec_fx( x_fx[n][0] = output_fx[n + ( cpe_id * CPE_CHANNELS )]; // Q11 x_fx[n][1] = output_fx[n + ( cpe_id * CPE_CHANNELS )] + ( L_FRAME48k / 2 ); // Q11 } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ); - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ); -#endif ivas_mdct_core_reconstruct_fx( hCPE, x_fx, synth_fx, fUseTns[cpe_id], 1, q_output, e_sig ); Word16 hdrm, sh; @@ -385,7 +376,6 @@ ivas_error ivas_mct_dec_fx( } } -#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS /* set pointers back */ test(); IF( cpe_id == 0 && st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) @@ -396,7 +386,6 @@ ivas_error ivas_mct_dec_fx( } } -#endif /*----------------------------------------------------------------* * CoreCoder Post-processing and updates @@ -409,19 +398,10 @@ ivas_error ivas_mct_dec_fx( test(); IF( ( st_ivas->sba_dirac_stereo_flag != 0 ) && ( NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) || GE_16( cpe_id, sub( nCPE, 2 ) ) ) ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); -#else - Copy_Scale_sig_16_32_DEPREC( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); -#endif ivas_post_proc_fx( NULL, hCPE, n, synth_fx_32[n], NULL, output_frame, 1, Q11 ); -#ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx_32[n], synth_fx[n], output_frame, sub( sub( 15, e_sig[n] ), Q11 ) ); // Q0 -#else - Copy_Scale_sig_32_16( synth_fx_32[n], synth_fx[n], L_FRAME48k, 0 - Q11 ); -#endif } /* Postprocessing for ACELP/MDCT core switching and synchronization */ @@ -452,11 +432,7 @@ ivas_error ivas_mct_dec_fx( { return error; } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 -#endif /* Save synthesis for HQ FEC */ Word32 output_fx_[L_FRAME48k]; Copy32( output_fx[( cpe_id * CPE_CHANNELS ) + n], output_fx_, L_FRAME48k ); // Q11 @@ -476,11 +452,7 @@ ivas_error ivas_mct_dec_fx( { IF( hCPE->hCoreCoder[n] ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 -#endif } } diff --git a/lib_dec/ivas_mct_dec_mct_fx_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c index c275820fb..0f20c1ec0 100644 --- a/lib_dec/ivas_mct_dec_mct_fx_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -313,17 +313,6 @@ void mctStereoIGF_dec_fx( test(); IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) || NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) ) { -#ifndef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC - tmp = BASOP_Util_Divide1616_Scale( sts[0]->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e ); - L_spec[0] = shr( tmp, add( 15, negate( tmp_e ) ) ); - move16(); - - tmp = BASOP_Util_Divide1616_Scale( sts[0]->L_frame, nSubframes, &tmp_e ); - L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) ); - - tmp = BASOP_Util_Divide1616_Scale( sts[0]->hTcxDec->L_frameTCX, nSubframes, &tmp_e ); - L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) ); -#else Word16 shr_div, shr_k; assert( nSubframes == 1 || nSubframes == 2 ); @@ -334,7 +323,6 @@ void mctStereoIGF_dec_fx( move16(); L_frame_nSubframe = shr( sts[0]->L_frame, shr_div ); L_frameTCX_nSubframe = shr( sts[0]->hTcxDec->L_frameTCX, shr_div ); -#endif init_tcx_info_fx( sts[0], L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[0], &tcx_offsetFB[0], &L_frame[0], &L_frameTCX[0], &left_rect[0], &L_spec[0] ); @@ -344,28 +332,16 @@ void mctStereoIGF_dec_fx( decoder_tcx_IGF_stereo_fx( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, p_x_e, p_x_len, L_frame[0], left_rect[0], k, bfi, 1 /* MCT_flag */ ); // Shifting output with variable exponent back to Q12 -#ifdef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC shr_k = sub( 31 - Q12, p_x_e[0][k] ); -#endif FOR( Word16 i = 0; i < p_x_len[0][k]; i++ ) { -#ifndef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC - p_x[0][k][i] = L_shr( p_x[0][k][i], sub( 31 - Q12, p_x_e[0][k] ) ); -#else p_x[0][k][i] = L_shr( p_x[0][k][i], shr_k ); -#endif move32(); } -#ifdef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC shr_k = sub( 31 - Q12, p_x_e[1][k] ); -#endif FOR( Word16 i = 0; i < p_x_len[1][k]; i++ ) { -#ifndef FIX_1109_OPTIM_MCT_STEREO_IGF_DEC - p_x[1][k][i] = L_shr( p_x[1][k][i], sub( 31 - Q12, p_x_e[1][k] ) ); -#else p_x[1][k][i] = L_shr( p_x[1][k][i], shr_k ); -#endif move32(); } } diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 1899c8bea..71839557a 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -684,10 +684,8 @@ void ivas_mdct_core_invQ_fx( { spectralData_tmp[k] = malloc( N_MAX * sizeof( Word32 ) ); } -#ifdef MSAN_FIX set32_fx( spectralData_tmp[0], 0, L_FRAME_MAX ); set32_fx( spectralData_tmp[1], 0, L_FRAME_MAX ); -#endif // MSAN_FIX push_wmops( "mdct_core_invQ" ); sts = hCPE->hCoreCoder; @@ -728,18 +726,8 @@ void ivas_mdct_core_invQ_fx( common_exp = s_max( sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ); -#ifdef MSAN_FIX -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 Copy_Scale_sig_16_32_no_sat( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 -#else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 - Copy_Scale_sig_16_32_DEPREC( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 -#endif -#else - Copy_Scale_sig_16_32_DEPREC( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_FRAME_MAX, 15 - ( common_exp - sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp1 - Copy_Scale_sig_16_32_DEPREC( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_FRAME_MAX, 15 - ( common_exp - sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp2 -#endif // MSAN_FIX sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp = sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp = common_exp; move16(); @@ -751,13 +739,8 @@ void ivas_mdct_core_invQ_fx( /* both input in same Q */ stereo_decoder_tcx_fx( hCPE->hStereoMdct, ms_mask, x_0[1], &spectralData_tmp[0], &spectralData_tmp[1], &hCPE->hStereoMdct->mdct_stereo_mode[0], sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], L_frameTCX[1], 0, sts[0]->last_core, sts[1]->last_core, 1, &q_r, &q_l ); -#ifdef MSAN_FIX Copy_Scale_sig_32_16( spectralData_tmp[0], sts[0]->hTonalMDCTConc->lastBlockData.spectralData, L_frameTCX[0], -15 ); // q_l - 15 Copy_Scale_sig_32_16( spectralData_tmp[1], sts[1]->hTonalMDCTConc->lastBlockData.spectralData, L_frameTCX[1], -15 ); // q_r - 15 -#else - Copy_Scale_sig_32_16( spectralData_tmp[0], sts[0]->hTonalMDCTConc->lastBlockData.spectralData, L_FRAME_MAX, -15 ); - Copy_Scale_sig_32_16( spectralData_tmp[1], sts[1]->hTonalMDCTConc->lastBlockData.spectralData, L_FRAME_MAX, -15 ); -#endif sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp = sub( 30, q_l ); sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp = sub( 30, q_r ); move16(); @@ -1193,13 +1176,8 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win -#ifdef MSAN_FIX Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win -#else - Scale_sig( synth_buf_fx, 3136, sub( q_win, q_syn ) ); - Scale_sig( synth_bufFB_fx, 3136, sub( q_win, q_syn ) ); -#endif Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win FOR( k = 0; k < nSubframes[ch]; k++ ) { @@ -1263,13 +1241,8 @@ void ivas_mdct_core_reconstruct_fx( move16(); Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( sub( -1, st->Q_syn ), st->hTcxDec->Q_old_syn_Overl ) ); // q_win -> Q(-1 - st->Q_syn) st->hTcxDec->Q_old_syn_Overl = sub( -1, st->Q_syn ); -#ifdef MSAN_FIX Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_syn, q_win ) ); // q_win -> q_syn Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_syn, q_win ) ); // q_win -> q_syn -#else - Scale_sig( synth_buf_fx, 3136, sub( q_syn, q_win ) ); - Scale_sig( synth_bufFB_fx, 3136, sub( q_syn, q_win ) ); -#endif Scale_sig( st->syn, M + 1, add( st->Q_syn, 2 ) ); Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn @@ -1400,11 +1373,7 @@ void ivas_mdct_core_reconstruct_fx( move16(); st->last_coder_type = st->coder_type; move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x -#else - Copy_Scale_sig_16_32_DEPREC( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x -#endif } IF( GT_16( e_sig[0], e_sig[1] ) ) @@ -1508,9 +1477,7 @@ void ivas_mdct_core_tns_ns_fx( move16(); set32_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); -#ifdef MSAN_FIX set32_fx( sns_int_scf_fx, 0, FDNS_NPTS ); -#endif /* TNS, ITF, IMDCT and updates */ diff --git a/lib_dec/ivas_omasa_dec_fx.c b/lib_dec/ivas_omasa_dec_fx.c index adee0fc91..8f7da758d 100644 --- a/lib_dec/ivas_omasa_dec_fx.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -713,22 +713,14 @@ void ivas_omasa_dirac_rend_jbm_fx( ivas_dirac_dec_render_fx( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); -#ifdef MSAN_FIX FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ ) -#else - FOR( Word16 ind1 = 0; ind1 < MAX_CICP_CHANNELS - 1; ind1++ ) -#endif // MSAN_FIX { scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, -1 ); // Q30 -> Q29 } ivas_omasa_separate_object_render_jbm_fx( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); -#ifdef MSAN_FIX FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ ) -#else - FOR( Word16 ind1 = 0; ind1 < MAX_CICP_CHANNELS - 1; ind1++ ) -#endif // MSAN_FIX { scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, 1 ); // Q29 -> Q30 } diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 493301743..80413b21a 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -130,10 +130,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ Word32 *output_fx[] /* o : rendered time signal Q11*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 n; @@ -150,11 +146,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( channel_offset = st_ivas->nchan_ism; move16(); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_fx[channel_offset] ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_fx[channel_offset], out_len ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } @@ -240,11 +232,7 @@ ivas_error ivas_osba_render_sf_fx( v_shr( p_output[n], Q11 - Q11, output_ism[n], nSamplesAsked ); // Q11 } -#ifdef OPT_SBA_AVOID_SPAR_RESCALE IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output ) ), IVAS_ERR_OK ) ) -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output, 960 ) ), IVAS_ERR_OK ) ) -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ { return error; } diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index 756eed60e..fc69d3919 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -479,12 +479,10 @@ ivas_error ivas_ls_setup_conversion_open_fx( set32_fx( hLsSetUpConversion->targetEnergyPrev_fx[0], 0, MAX_SFB + 2 ); set32_fx( hLsSetUpConversion->dmxEnergyPrev_fx[0], 0, MAX_SFB + 2 ); -#ifdef MSAN_FIX hLsSetUpConversion->te_prev_exp[0] = 0; hLsSetUpConversion->dmx_prev_exp[0] = 0; move16(); move16(); -#endif } /* Initialize the DMX conversion matrix */ diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index 03fe4063a..c0e69b916 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -243,12 +243,6 @@ void stereo_dft_dec_core_switching_fx( move16(); } -#ifndef MSAN_FIX - IF( st->p_bpf_noise_buf_32 ) - { - Scale_sig32( st->p_bpf_noise_buf_32, L_FRAME16k, sub( *q, Q11 ) ); - } -#endif test(); test(); @@ -273,9 +267,7 @@ void stereo_dft_dec_core_switching_fx( test(); IF( st->p_bpf_noise_buf_32 && NE_16( st->core, HQ_CORE ) ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 2, 0, q, q_DFT ); } /* st->p_bpf_noise_buf not updated FOR HQ core -> skip analysis and set input memory to zero */ @@ -294,11 +286,7 @@ void stereo_dft_dec_core_switching_fx( { Word16 mem_len = NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /*Q0*/ move16(); -#ifdef MSAN_FIX Word32 mem_len_inv = mem_len_inv_tbl[( mem_len / 25 ) - 1]; -#else - Word32 mem_len_inv = mem_len_inv_tbl[( mem_len / 25 )]; -#endif move32(); Word16 qmem_len = norm_l( mem_len ); Word32 mem_len_fx = L_shl( mem_len, qmem_len ); @@ -441,9 +429,7 @@ void stereo_dft_dec_core_switching_fx( /* BPF */ IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); } } @@ -472,9 +458,7 @@ void stereo_dft_dec_core_switching_fx( /* BPF */ IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); } @@ -549,9 +533,7 @@ void stereo_dft_dec_core_switching_fx( /* BPF */ IF( st->p_bpf_noise_buf_32 ) { -#ifdef MSAN_FIX Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( *q, Q11 ) ); /*q*/ -#endif stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); } @@ -723,12 +705,6 @@ void stereo_dft_dec_core_switching_fx( } } -#ifndef MSAN_FIX - IF( st->p_bpf_noise_buf_32 ) - { - Scale_sig32( st->p_bpf_noise_buf_32, L_FRAME16k, negate( sub( *q, Q11 ) ) ); - } -#endif return; } diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index c78c51c52..6e36c7765 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -1113,7 +1113,6 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( } } -#ifdef MSAN_FIX FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) @@ -1122,19 +1121,8 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( move32(); } } -#else - FOR( b = 0; b < MASA_MAXIMUM_CODING_SUBBANDS; b++ ) - { - FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) - { - hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[0][b][m] ); - move32(); - } - } -#endif // MSAN_FIX IF( EQ_32( hQMetaData->no_directions, 2 ) ) { -#ifdef MSAN_FIX FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) @@ -1143,16 +1131,6 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( move32(); } } -#else - FOR( b = 0; b < MASA_MAXIMUM_CODING_SUBBANDS; b++ ) - { - FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) - { - hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[1][b][m] ); - move32(); - } - } -#endif // MSAN_FIX } /* Store status information for renderer use */ hQMetaData->ec_flag = 0; diff --git a/lib_dec/ivas_sba_dec_fx.c b/lib_dec/ivas_sba_dec_fx.c index f89e9601f..c8c3d80a5 100644 --- a/lib_dec/ivas_sba_dec_fx.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -349,12 +349,8 @@ ivas_error ivas_sba_dec_reconfigure_fx( test(); test(); test(); -#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH test(); IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) -#else - IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) -#endif { IF( ( hSpar->hPCA = (PCA_DEC_STATE *) malloc( sizeof( PCA_DEC_STATE ) ) ) == NULL ) { @@ -874,10 +870,6 @@ ivas_error ivas_sba_dec_render_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered Q0*/ UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render Q0*/ Word32 *output_fx[] /* o : rendered time signal Q11*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len /*Store the length of values in each channel*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 slots_to_render, first_sf, last_sf, subframe_idx; @@ -886,15 +878,8 @@ ivas_error ivas_sba_dec_render_fx( SPAR_DEC_HANDLE hSpar; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word32 *output_f_local_fx[MAX_OUTPUT_CHANNELS]; -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Word16 output_f_local_len; -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ivas_error error; -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - output_f_local_len = out_len; - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ hSpar = st_ivas->hSpar; hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_internal = ivas_sba_get_nchan_metadata_fx( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); @@ -926,18 +911,11 @@ ivas_error ivas_sba_dec_render_fx( { Word16 n_samples_sf = imult1616( slot_size, hSpar->subframe_nbslots[subframe_idx] ); /*Q0*/ -#ifdef OPT_SBA_AVOID_SPAR_RESCALE ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal, output_f_local_len ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ch = 0; ch < nchan_out; ch++ ) { output_f_local_fx[ch] = output_f_local_fx[ch] + n_samples_sf; /*Q11*/ } -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - output_f_local_len = sub( output_f_local_len, n_samples_sf ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 0c7544682..50db27aa5 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -725,12 +725,10 @@ static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs( ELSE { set32_fx( hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, 0, output_frame ); -#ifdef MSAN_FIX hStereoDft->hb_nrg_subr_fx[0] = 0; move32(); hStereoDft->hb_nrg_subr_fx[1] = 0; move32(); -#endif // MSAN_FIX } hStereoDft->hb_nrg_subr_fx[0] = hStereoDft->hb_nrg_subr_fx[0]; // imult3216(hStereoDft->hb_nrg_subr_fx[0] , shr(hStereoDft->NFFT, 1)); /*hStereoDft->q_hb_nrg_subr*/ move32(); @@ -1240,12 +1238,10 @@ void ivas_sba_dirac_stereo_dec_fx( CPE_DEC_HANDLE hCPE; STEREO_DFT_DEC_DATA_HANDLE hStereoDft; -#ifdef MSAN_FIX FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { set32_fx( DFT[i], 0, STEREO_DFT_BUF_MAX ); } -#endif hSCE = st_ivas->hSCE[0]; hCPE = st_ivas->hCPE[0]; @@ -1257,18 +1253,10 @@ void ivas_sba_dirac_stereo_dec_fx( q_dft[1] = hCPE->hStereoDft->q_dft; move16(); -#ifdef MSAN_FIX Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), negate( sub( Q11, hCPE->hStereoDft->q_dft ) ) ); /*hSCE->q_prev_hb_synth_fx + hCPE->hStereoDft->q_dft - Q11*/ -#else - Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), -( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif IF( hSCE != NULL ) { -#ifdef MSAN_FIX Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), negate( sub( Q11, hCPE->hStereoDft->q_dft ) ) ); /*hSCE->q_prev_hb_synth_fx + hCPE->hStereoDft->q_dft - Q11*/ -#else - Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), -( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif // MSAN_FIX hSCE->q_prev_hb_synth_fx = hCPE->hStereoDft->q_dft; move16(); } @@ -1398,18 +1386,10 @@ void ivas_sba_dirac_stereo_dec_fx( set32_fx( output[ch], 0, output_frame ); } -#ifdef MSAN_FIX Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); /*hSCE->q_prev_hb_synth_fx + Q11 - hCPE->hStereoDft->q_dft*/ -#else - Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), ( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif IF( hSCE != NULL ) { -#ifdef MSAN_FIX Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); /*hSCE->q_prev_hb_synth_fx + Q11 - hCPE->hStereoDft->q_dft*/ -#else - Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), ( Q11 - hCPE->hStereoDft->q_dft ) ); -#endif // MSAN_FIX hSCE->q_prev_hb_synth_fx = Q11; move16(); } diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index 461b18fbc..c3e2ad096 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -787,11 +787,7 @@ void ivas_spar_get_cldfb_gains_fx( cldfbAnalysis_ts_fx_fixed_q( ts_inout_fx, ts_re_fx, ts_im_fx, num_cldfb_bands, cldfbAnaDec0, &q_cldfb ); cldfb_reset_memory_fx( cldfbSynDec0 ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, 0, cldfbSynDec0 ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, cldfbSynDec0 ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( sample = 0; sample < stride; sample++ ) { T_fx[( ( slot * stride ) + sample )][slot] = ts_inout_fx[sample]; /*Q21*/ @@ -1161,10 +1157,8 @@ void ivas_spar_get_parameters_fx( split_band = SPAR_DIRAC_SPLIT_START_BAND; move16(); -#ifdef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS Word16 add_weight_fx = sub( MAX_WORD16, weight_fx ); Word16 add_weight_20ms_fx = sub( MAX_WORD16, weight_20ms_fx ); -#endif FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ ) @@ -1179,13 +1173,8 @@ void ivas_spar_get_parameters_fx( { IF( GT_16( hSpar->i_subframe, 3 ) ) { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS - par_mat_fx[out_ch][in_ch][spar_band] = L_add_sat( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], sub( MAX_WORD16, weight_fx ) ), - Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ) ); /*hSpar->hMdDec->Q_mixer_mat*/ -#else par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ), hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], add_weight_fx ); -#endif move32(); } ELSE @@ -1202,12 +1191,8 @@ void ivas_spar_get_parameters_fx( /* 20ms Transport channel reconstruction with matching encoder/decoder processing */ Word16 prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */ move16(); -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS - par_mat_fx[out_ch][in_ch][spar_band] = L_add_sat( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], sub( MAX_WORD16, weight_20ms_fx ) ), Mpy_32_16_1( hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ) ); /*hSpar->hMdDec->Q_mixer_mat*/ -#else par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], add_weight_20ms_fx ), hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ); /*hSpar->hMdDec->Q_mixer_mat*/ -#endif move32(); } } @@ -1367,17 +1352,10 @@ static void ivas_spar_calc_smooth_facs_fx( smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 move32(); } -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_HQ_CONSTANTS - smooth_short_avg_fx[b] = Mpy_32_16_1( smooth_short_avg_fx[b], 5461 /*(1/6 in Q15)*/ ); // Q0 - move32(); - smooth_long_avg_fx[b] = Mpy_32_16_1( smooth_long_avg_fx[b], 1639 /*(1/20 in Q15)*/ ); // Q0 - move32(); -#else smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 move32(); smooth_long_avg_fx[b] = Mpy_32_32( smooth_long_avg_fx[b], 107374182 /*(1/20 in Q31)*/ ); // Q0 move32(); -#endif /* calculate smoothing factor based on energy averages */ /* reduce factor for higher short-term energy */ @@ -1689,10 +1667,6 @@ void ivas_spar_dec_upmixer_sf_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ Word32 *output_fx[], /* o : output audio channels Q11*/ const Word16 nchan_internal /* i : number of internal channels Q0*/ -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - , - Word16 out_len -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ ) { Word16 cldfb_band, num_cldfb_bands, numch_in, numch_out; @@ -1793,9 +1767,7 @@ void ivas_spar_dec_upmixer_sf_fx( * Prepare CLDFB buffers *---------------------------------------------------------------------*/ -#ifdef MSAN_FIX set_zero_fx( &Pcm_tmp_fx[0][0], ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) * L_FRAME48k ); -#endif // MSAN_FIX /* set-up pointers */ IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) ) { @@ -1871,9 +1843,7 @@ void ivas_spar_dec_upmixer_sf_fx( ivas_spar_calc_smooth_facs_fx( cldfb_in_ts_re_fx[0], cldfb_in_ts_im_fx[0], q_cldfb, num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_buf_fx ); } -#ifdef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL Word16 sh_l = sub( 31, q1 ); -#endif FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { md_idx = hSpar->render_to_md_map[( ts + slot_idx_start )]; /*Q0*/ @@ -1889,18 +1859,12 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE Word16 diff = sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], diff ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/ -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] ) ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ move32(); hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band] = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/ move32(); @@ -1908,68 +1872,6 @@ void ivas_spar_dec_upmixer_sf_fx( } } } -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS - FOR( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) - { - Word32 out_re_fx[IVAS_SPAR_MAX_CH]; - Word32 out_im_fx[IVAS_SPAR_MAX_CH]; - Word32 cldfb_par_fx; /*q1*/ - ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band; - - FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) - { - out_re_fx[out_ch] = 0; - move32(); - out_im_fx[out_ch] = 0; - move32(); - FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - IF( b_skip_mat[out_ch][in_ch] == 0 ) - { - IF( LT_16( cldfb_band, CLDFB_PAR_WEIGHT_START_BAND ) ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */ - { - spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; /*Q0*/ - move16(); - cldfb_par_fx = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/ - move32(); - } - ELSE - { - Word64 acc = 0; - move64(); - FOR( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) - { - /* accumulate contributions from all SPAR bands */ - acc = W_mac_32_32( acc, mixer_mat_fx[out_ch][in_ch][spar_band], bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band] ); // q1+ Q23 - } - cldfb_par_fx = W_shl_sat_l( acc, -23 ); // q1 - } - - out_re_fx[out_ch] = Madd_32_32( out_re_fx[out_ch], cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ - move32(); - out_im_fx[out_ch] = Madd_32_32( out_im_fx[out_ch], cldfb_in_ts_im_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ - move32(); - } - } - } - - /*update CLDFB data with the parameter-modified data*/ - FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) - { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); -#else - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ - move32(); -#endif - } - } -#else /* FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS */ /* Note: This version splits the cldfb band loop into 2 loops, removing some inner-loop IF_statements */ Word16 min_cldf_band = s_min( CLDFB_PAR_WEIGHT_START_BAND, num_cldfb_bands ); Word32 out_re_fx[IVAS_SPAR_MAX_CH]; @@ -2004,17 +1906,10 @@ void ivas_spar_dec_upmixer_sf_fx( /*update CLDFB data with the parameter-modified data*/ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); -#else cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ move32(); cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ move32(); -#endif } } @@ -2052,20 +1947,12 @@ void ivas_spar_dec_upmixer_sf_fx( /*update CLDFB data with the parameter-modified data*/ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { -#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL - cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); - cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ - move32(); -#else cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ move32(); cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ move32(); -#endif } } -#endif /* FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS */ test(); IF( ( EQ_16( ( add( add( slot_idx_start, ts ), 1 ) ), hSpar->num_slots ) ) || ( NE_16( ( shr( md_idx, 2 ) /* md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME */ ), ( hSpar->render_to_md_map[( ( slot_idx_start + ts ) + 1 )] / JBM_CLDFB_SLOTS_IN_SUBFRAME /*It's value is 4*/ ) ) ) ) { @@ -2080,12 +1967,6 @@ void ivas_spar_dec_upmixer_sf_fx( } IF( LT_16( split_band, IVAS_MAX_NUM_BANDS ) ) { -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], hSpar->hMdDec->mixer_mat_prev_fx[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ - Copy32( hSpar->hMdDec->mixer_mat_prev_fx[4][0][0], hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hSpar->hMdDec->Q_mixer_mat*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { @@ -2093,7 +1974,6 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( b = 0; b < num_spar_bands; b++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE hSpar->hMdDec->mixer_mat_prev_fx[0][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b]; hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b]; hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[3][out_ch][in_ch][b]; @@ -2102,7 +1982,6 @@ void ivas_spar_dec_upmixer_sf_fx( move32(); move32(); move32(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][( b + ( md_sf * IVAS_MAX_NUM_BANDS ) )]; /*hSpar->hMdDec->Q_mixer_mat*/ move32(); @@ -2156,26 +2035,10 @@ void ivas_spar_dec_upmixer_sf_fx( IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) && !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) { -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state-6*/ - st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); - move16(); - Scale_sig32( output_fx[ch], out_len, -6 ); /*Q5*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, st_ivas->cldfbSynDec[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( output_fx[ch], out_len, 6 ); /*Q11*/ - Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, 6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state+6*/ - st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = add( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } idx_in = add( idx_in, 1 ); @@ -2187,26 +2050,10 @@ void ivas_spar_dec_upmixer_sf_fx( /* CLDFB to time synthesis (overwrite mixer output) */ FOR( out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) { -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx, st_ivas->cldfbSynDec[out_ch]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state-6*/ - st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state, 6 ); - move16(); - Scale_sig32( output_fx[out_ch], out_len, -6 ); /*Q5*/ -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[out_ch] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } -#ifndef OPT_SBA_AVOID_SPAR_RESCALE - Scale_sig32( output_fx[out_ch], out_len, 6 ); /*Q11*/ - Scale_sig32( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx, st_ivas->cldfbSynDec[out_ch]->p_filter_length, 6 ); /*st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state+6*/ - st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state = add( st_ivas->cldfbSynDec[out_ch]->Q_cldfb_state, 6 ); - move16(); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 5704f4f60..429a99ca4 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -961,9 +961,7 @@ typedef struct decoder_tc_buffer_structure Word32 *tc_buffer_fx; /* the buffer itself */ Word16 tc_buff_len; /*stores memory length of tc buffer*/ Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ // VE2SB: TBV -#ifdef MSAN_FIX Word16 no_channels; /*Stores no of channels in tc_fx with values*/ -#endif Word16 q_tc_fx; TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 223860db0..478f96dc1 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -683,12 +683,8 @@ static void stereo_dft_generate_comfort_noise_fx( factor = L_min( L_add( L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ), W_extract_l( W_mult0_32_32( Mpy_32_16_1( L_sub( factor, L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ) ), ONE_BY_MAX_K ), hStereoCng->xfade_frame_counter ) ) ), factor ); /* q_div */ FOR( ; j <= hFdCngCom->part[k]; j++ ) { -#ifdef FIX_ISSUE_1218 /* NOTE: saturation is added here as part of issue 1218 fix. After rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ hFdCngCom->cngNoiseLevel[j] = L_shl_sat( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ -#else - hFdCngCom->cngNoiseLevel[j] = L_shl( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ -#endif move32(); } } diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 9c1b488cb..324f2b7f3 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -96,9 +96,7 @@ void stereo_dft_dec_reset_fx( { Word16 i; Word16 j, b; -#ifdef MSAN_FIX set_zero_fx( hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ) ); -#endif /*Configuration*/ set16_fx( hStereoDft->prm_res, hStereoDft->hConfig->prm_res, STEREO_DFT_DEC_DFT_NB ); @@ -122,25 +120,13 @@ void stereo_dft_dec_reset_fx( set16_fx( hStereoDft->res_pred_index_previous, 0, STEREO_DFT_BAND_MAX ); -#ifdef MSAN_FIX FOR( i = 0; i < STEREO_DFT_BAND_MAX * 2; i++ ) { hStereoDft->res_gains_ind_fx[0][i] = 1006632960; /* 15.0f in Q26 */ move32(); } -#else - FOR( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) - { - hStereoDft->res_gains_ind_fx[0][i] = 1006632960; /* 15.0f in Q26 */ - move32(); - } -#endif -#ifdef MSAN_FIX set32_fx( hStereoDft->res_gains_ind_fx[1], 0, STEREO_DFT_BAND_MAX * 2 ); -#else - set32_fx( hStereoDft->res_gains_ind_fx[1], 0, STEREO_DFT_BAND_MAX ); -#endif /*residual coding*/ set16_fx( hStereoDft->res_cod_mode, hStereoDft->hConfig->res_cod_mode, STEREO_DFT_DEC_DFT_NB ); @@ -260,7 +246,6 @@ void stereo_dft_dec_reset_fx( move32(); hStereoDft->frame_sid_nodata = 0; move16(); -#ifdef MSAN_FIX FOR( b = 0; b < 2 * IVAS_MAX_NUM_BANDS; b++ ) { FOR( i = 0; i < 2; i++ ) @@ -272,19 +257,6 @@ void stereo_dft_dec_reset_fx( } } } -#else - FOR( b = 0; b < hStereoDft->nbands; b++ ) - { - FOR( i = 0; i < 2; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - hStereoDft->mixer_mat_smooth_fx[i][j][b] = 0; - move32(); - } - } - } -#endif hStereoDft->first_frame = 1; move16(); hStereoDft->g_L_prev_fx = 0; @@ -429,9 +401,7 @@ ivas_error stereo_dft_dec_create_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TCX-LTP handle\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hStereoDft_loc->hb_nrg_subr_fx, STEREO_DFT_NBDIV ); /*Setting hb_nrg_subr_fx to zero*/ -#endif // MSAN_FIX hStereoDft_loc->hConfig->force_mono_transmission = 0; move16(); @@ -1436,11 +1406,7 @@ void stereo_dft_dec_res_fx( move32(); } } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ -#else - Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ -#endif IF( res_bpf_flag ) { v_sub_32( output, bpf_error_signal_8k, output, L_FRAME8k ); @@ -1451,20 +1417,12 @@ void stereo_dft_dec_res_fx( set16_fx( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ -#else - Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ -#endif } ELSE { /* This step is needed to ensure output is properly populated with scaled values in all cases*/ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ -#else - Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ -#endif } return; diff --git a/lib_dec/ivas_stereo_ica_dec_fx.c b/lib_dec/ivas_stereo_ica_dec_fx.c index 694aad0b4..73cf9ccd0 100644 --- a/lib_dec/ivas_stereo_ica_dec_fx.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -59,13 +59,8 @@ void stereo_tca_dec_fx( ) { /* Buffers, input Left and right channels @ input_Fs*/ -#ifdef MSAN_FIX Word32 bufChanL_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k] = { 0 }; Word32 bufChanR_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k] = { 0 }; -#else - Word32 bufChanL_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k]; - Word32 bufChanR_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k]; -#endif Word32 *ptrChanL_fx, *ptrChanR_fx; Word32 *target_fx; Word16 target_idx, prevNCShift, currentNCShift, l_shift_adapt; diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 04aeccbb5..1c2ecffaf 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -234,12 +234,10 @@ void stereo_icBWE_dec_fx( ELSE { set32_fx( hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, 0, output_frame ); -#ifdef MSAN_FIX hCPE->hStereoDft->hb_nrg_subr_fx[0] = 0; move32(); hCPE->hStereoDft->hb_nrg_subr_fx[1] = 0; move32(); -#endif // MSAN_FIX } hCPE->hStereoDft->hb_nrg_subr_fx[0] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[0], shl( shr( hCPE->hStereoDft->NFFT, 1 ), 6 ) ) ); // 2 * (Qsynth + SynthRef_shift) - 40 // 2 * (Qx + SynthRef_shift) - 31 - 15 move32(); @@ -719,11 +717,7 @@ void stereo_icBWE_dec_fx( { IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { -#ifdef FIX_TMP_714 tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 -#else - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 -#endif tmp = mult_r( tmp, gsMapping_fx ); // Q14 tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) @@ -819,11 +813,7 @@ void stereo_icBWE_dec_fx( hStereoICBWE->prev_Q_fsout = tmp; move16(); } -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, sub( *Q_syn, add( 1, tmp ) ) ); -#else Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); /* Qsyn - 1 */ -#endif *Q_syn = sub( *Q_syn, 1 ); @@ -886,11 +876,7 @@ void stereo_icBWE_dec_fx( { IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { -#ifdef FIX_TMP_714 tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 -#else - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 -#endif tmp = mult_r( tmp, gsMapping_fx ); // Q14 tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index a6b350d33..cd7e92f71 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -540,13 +540,8 @@ void stereo_mdct_core_dec_fx( move16(); } } -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ -#endif ivas_mdct_core_reconstruct_fx( hCPE, x_fx, signal_outFB_tmp_fx, fUseTns, 0, Q11, e_sigFB ); Copy32( signal_out_tmp_fx[0], signal_out_fx[0], L_FRAME48k ); /* Q11 */ diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 5b1378a89..5248839f5 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -904,13 +904,8 @@ void updateBuffersForDmxMdctStereo_fx( move16(); sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 ); move16(); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 -#else - Copy_Scale_sig_16_32_DEPREC( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 - Copy_Scale_sig_16_32_DEPREC( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 -#endif } return; diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 6c2ad055c..1a6ea257b 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -197,9 +197,7 @@ static ivas_error allocate_CoreCoder_fx( } hf_synth_init_fx( st->hBWE_zero ); -#ifdef MSAN_FIX set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif } IF( st->cldfbAna == NULL ) @@ -2153,21 +2151,13 @@ void stereo_td2dft_update_fx( /* update buffers used for fading when switching to DFT Stereo */ v_add_fx( sts[0]->hHQ_core->old_out_LB_fx32 + nsLB, sts[1]->hHQ_core->old_out_LB_fx32 + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, STEREO_MDCT2DFT_FADE_LEN_48k, old_outLB_len ); -#ifndef MSAN_FIX - for ( i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) -#else FOR( i = 0; i < old_outLB_len; i++ ) -#endif { hCPE->old_outLB_mdct_fx[i] = L_shr( hCPE->old_outLB_mdct_fx[i], 1 ); /* Q11 */ move32(); } v_add_fx( sts[0]->hHQ_core->old_out_fx32 + ns, sts[1]->hHQ_core->old_out_fx32 + ns, hCPE->old_out_mdct_fx, old_out_len ); /* exp(exp_old_out) */ -#ifndef MSAN_FIX - for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) -#else FOR( i = 0; i < old_out_len; i++ ) -#endif { hCPE->old_out_mdct_fx[i] = L_shr( hCPE->old_out_mdct_fx[i], 1 ); /* q_old_out_mdct */ move32(); diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 1467687d8..dd9859504 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -70,11 +70,7 @@ static void biDiagonalReductionLeft_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ @@ -88,11 +84,7 @@ static void biDiagonalReductionLeft_fx( static void biDiagonalReductionRight_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC, /* Q0 */ @@ -105,11 +97,7 @@ static void biDiagonalReductionRight_fx( static void singularVectorsAccumulationLeft_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) as Input, Q31 as output */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC /* Q0 */ @@ -119,16 +107,8 @@ static void singularVectorsAccumulationRight_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* singularVectors_e */ Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* singularVectors_e */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_e, -#else Word16 *secDiag_e, -#endif const Word16 nChannelsC /* Q0 */ ); @@ -168,7 +148,6 @@ static void ApplyRotation_fx( const Word16 nChannels /* Q0 */ ); -#ifdef FIX_1010_OPT_GIVENS_INV static void GivensRotation2_fx( const Word32 x, /* exp(x_e) */ const Word16 x_e, @@ -178,7 +157,6 @@ static void GivensRotation2_fx( Word32 *resultInv, Word16 *out_e, Word16 *outInv_e ); -#endif static Word32 GivensRotation_fx( const Word32 x, /* exp(x_e) */ @@ -306,11 +284,7 @@ Word16 svd_fx( Word16 lengthSingularValues; Word16 errorMessage, condition; Word32 secDiag_fx[MAX_OUTPUT_CHANNELS]; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_fx_e = 0; -#else Word16 secDiag_fx_e[MAX_OUTPUT_CHANNELS]; -#endif move16(); Word32 eps_x_fx = 0, temp_fx; move16(); @@ -320,10 +294,6 @@ Word16 svd_fx( push_wmops( "svd_fx" ); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - set32_fx( secDiag_fx, 0, MAX_OUTPUT_CHANNELS ); - set16_fx( singularValues_fx_e, 0, MAX_OUTPUT_CHANNELS ); -#endif /* Collecting Values */ FOR( iCh = 0; iCh < nChannelsL; iCh++ ) @@ -336,22 +306,14 @@ Word16 svd_fx( } /* Householder reduction */ -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - HouseholderReduction_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, InputMatrix_e, singularValues_fx_e, &secDiag_fx_e, nChannelsL, nChannelsC, &eps_x_fx, &eps_x_fx_e ); -#else HouseholderReduction_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, InputMatrix_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, &eps_x_fx, &eps_x_fx_e ); -#endif /* Set extremely small values to zero if needed */ // flushToZeroArray(singularValues, max_length); // flushToZeroMat(singularVectors_Left, nChannelsL, nChannelsL); // flushToZeroMat(singularVectors_Right, nChannelsC, nChannelsC); /* BidagonalDiagonalisation */ -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - errorMessage = BidagonalDiagonalisation_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, singularValues_fx_e, &secDiag_fx_e, nChannelsL, nChannelsC, eps_x_fx, eps_x_fx_e ); /* Q0 */ -#else errorMessage = BidagonalDiagonalisation_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, eps_x_fx, eps_x_fx_e ); /* Q0 */ -#endif /* Sort the singular values descending order */ lengthSingularValues = s_min( nChannelsL, nChannelsC ); /* Q0 */ @@ -423,11 +385,7 @@ static Word16 BidagonalDiagonalisation_fx( Word32 singularVectors_Right_fx[][MAX_OUTPUT_CHANNELS], /* i/o: right singular vectors (V) singularValues_fx_e*/ Word32 secDiag_fx[MAX_OUTPUT_CHANNELS], /* i/o: secDiag_fx_e*/ Word16 singularValues_fx_e[MAX_OUTPUT_CHANNELS], /* i/o: singular values vector (S) */ -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 *secDiag_fx_e, /* i/o: */ -#else Word16 *secDiag_new_e, /* i/o: */ -#endif const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ const Word32 eps_x, /* i : eps_x_e*/ @@ -441,9 +399,7 @@ static Word16 BidagonalDiagonalisation_fx( move16(); move16(); Word16 temp_exp; -#ifdef FIX_1010_OPT_NORM_NOSAT Word16 temp_exp2; -#endif Word32 g = 0; move16(); Word16 g_e = 0; @@ -451,14 +407,8 @@ static Word16 BidagonalDiagonalisation_fx( Word16 convergence, iteration, found_split; Word16 error = 0; move16(); -#ifdef FIX_1010_OPT_GIVENS_INV Word32 temp; -#endif Word16 singularValues_new_e[MAX_OUTPUT_CHANNELS]; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_new_e[MAX_OUTPUT_CHANNELS]; - set16_fx( secDiag_new_e, *secDiag_fx_e, MAX_OUTPUT_CHANNELS ); -#endif Copy( singularValues_fx_e, singularValues_new_e, MAX_OUTPUT_CHANNELS ); FOR( iCh = nChannelsC - 1; iCh >= 0; iCh-- ) /* nChannelsC */ @@ -527,46 +477,17 @@ static Word16 BidagonalDiagonalisation_fx( c = singularValues_fx[kCh]; /* exp(singularValues_new_e) */ c_e = singularValues_new_e[kCh]; -#ifdef FIX_1010_OPT_GIVENS_INV GivensRotation2_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_fx[kCh], &temp, &singularValues_new_e[kCh], &temp_exp ); /* exp(singularValues_new_e) */ c = Mpy_32_32( c, temp ); c_e = add( c_e, temp_exp ); -#else - singularValues_fx[kCh] = GivensRotation_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_new_e[kCh] ); /* exp(singularValues_new_e) */ - c = BASOP_Util_Divide3232_Scale_cadence( c, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (c_e - singularValues_new_e)) */ - c_e = add( temp_exp, sub( c_e, singularValues_new_e[kCh] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( c_e > 0 ) - { - c = L_shl_sat( c, c_e ); // Q31 - c_e = 0; - move16(); - } -#else temp_exp2 = norm_l( c ); c = L_shl( c, temp_exp2 ); c_e = sub( c_e, temp_exp2 ); -#endif -#ifdef FIX_1010_OPT_GIVENS_INV s = Mpy_32_32( -g, temp ); s_e = add( g_e, temp_exp ); -#else - s = BASOP_Util_Divide3232_Scale_cadence( -g, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (g_e - singularValues_new_e))*/ - s_e = add( temp_exp, sub( g_e, singularValues_new_e[kCh] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( s_e > 0 ) - { - s = L_shl_sat( s, s_e ); // Q31 - s_e = 0; - move16(); - } -#else temp_exp2 = norm_l( s ); s = L_shl( s, temp_exp2 ); s_e = sub( s_e, temp_exp2 ); -#endif ApplyRotation_fx( singularVectors_Left_fx, c, c_e, s, s_e, 0, x11_e, 0, x12_e, &f1, &f1_e, &f2, &f2_e, kCh, split, nChannelsL ); /* nChannelsL */ } } @@ -617,24 +538,6 @@ static Word16 BidagonalDiagonalisation_fx( // rescaling block Copy( singularValues_new_e, singularValues_fx_e, MAX_OUTPUT_CHANNELS ); -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 max_exp = -31; - move16(); - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - if ( secDiag_fx[iCh] ) - { - max_exp = s_max( max_exp, secDiag_new_e[iCh] ); - } - } - *secDiag_fx_e = max_exp; - move16(); - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - secDiag_fx[iCh] = L_shr_r( secDiag_fx[iCh], sub( *secDiag_fx_e, secDiag_new_e[iCh] ) ); /* exp(secDiag_fx_e) */ - move32(); - } -#endif return ( error ); } @@ -658,13 +561,9 @@ static void ApplyQRTransform_fx( const Word16 nChannelsC /* i : number of columns in the matrix to be decomposed Q0*/ ) { -#ifdef FIX_1010_OPT_GIVENS_INV Word32 temp; Word16 temp_e; -#endif -#ifdef FIX_1010_OPT_NORM_NOSAT Word16 temp_norm_e; -#endif Word16 ch, split; Word32 d = 0, g = 0, r = 0, x_ii = 0, x_split = 0, x_kk = 0, mu = 0, aux = 0; move32(); @@ -767,47 +666,17 @@ static void ApplyQRTransform_fx( g = Mpy_32_32( c, secDiag[ch + 1] ); /* exp(c_e + secDiag_e) */ g_e = add( c_e, secDiag_e[ch + 1] ); -#ifdef FIX_1010_OPT_GIVENS_INV GivensRotation2_fx( d, d_e, r, r_e, &secDiag[ch], &temp, &secDiag_e[ch], &temp_e ); /* exp(secDiag_e) */ c = Mpy_32_32( d, temp ); c_e = add( temp_e, d_e ); -#else - secDiag[ch] = GivensRotation_fx( d, d_e, r, r_e, &secDiag_e[ch] ); /* exp(secDiag_e) */ - move32(); - c = BASOP_Util_Divide3232_Scale_cadence( d, maxWithSign_fx( secDiag[ch] ), &c_e ); /* exp(c_e + (d_e + secDiag_e)) */ - c_e = add( c_e, sub( d_e, secDiag_e[ch] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( c_e > 0 ) - { - c = L_shl_sat( c, c_e ); // Q31 - c_e = 0; - move16(); - } -#else temp_norm_e = norm_l( c ); c = L_shl( c, temp_norm_e ); c_e = sub( c_e, temp_norm_e ); -#endif -#ifdef FIX_1010_OPT_GIVENS_INV s = Mpy_32_32( r, temp ); s_e = add( r_e, temp_e ); -#else - s = BASOP_Util_Divide3232_Scale_cadence( r, maxWithSign_fx( secDiag[ch] ), &s_e ); /* exp(s_e + (r_e - sec_Diag_e))*/ - s_e = add( s_e, sub( r_e, secDiag_e[ch] ) ); -#endif -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( s_e > 0 ) - { - s = L_shl_sat( s, s_e ); // Q31 - s_e = 0; - move16(); - } -#else temp_norm_e = norm_l( s ); s = L_shl( s, temp_norm_e ); s_e = sub( s_e, temp_norm_e ); -#endif r = Mpy_32_32( s, singularValues[ch + 1] ); /* exp(r_e + secDiag_e) */ r_e = add( s_e, singularValues_e[ch + 1] ); x_split = Mpy_32_32( c, singularValues[ch + 1] ); /* exp(c_e + secDiag_e) */ @@ -821,48 +690,21 @@ static void ApplyQRTransform_fx( // ApplyRotation(singularVectors_Right, c, s, x_ii, aux, &d, &g, ch + 1, ch, nChannelsC); ApplyRotation_fx( singularVectors_Right, c, c_e, s, s_e, x_ii, x_ii_e, aux, aux_e, &d, &d_e, &g, &g_e, ch + 1, ch, nChannelsC ); -#ifdef FIX_1010_OPT_GIVENS_INV GivensRotation2_fx( d, d_e, r, r_e, &singularValues[ch], &aux, &singularValues_e[ch], &aux_e ); /* exp(singularValues_e) */ -#else - singularValues[ch] = GivensRotation_fx( d, d_e, r, r_e, &singularValues_e[ch] ); /* exp(singularValues_e) */ - move32(); -#endif IF( singularValues[ch] != 0 ) { -#ifndef FIX_1010_OPT_GIVENS_INV - aux = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, singularValues[ch], &aux_e ); /* exp(aux_e + (1 - singularValues_e)) */ - aux_e = add( aux_e, sub( 1, singularValues_e[ch] ) ); -#endif c = Mpy_32_32( d, aux ); /* exp(d_e + aux_e) */ c_e = add( d_e, aux_e ); -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( c_e > 0 ) - { - c = L_shl_sat( c, c_e ); // Q31 - c_e = 0; - move16(); - } -#else temp_norm_e = norm_l( c ); c = L_shl( c, temp_norm_e ); c_e = sub( c_e, temp_norm_e ); -#endif s = Mpy_32_32( r, aux ); /* exp(r_e + aux_e) */ s_e = add( r_e, aux_e ); -#ifndef FIX_1010_OPT_NORM_NOSAT - IF( s_e > 0 ) - { - s = L_shl_sat( s, s_e ); // Q31 - s_e = 0; - move16(); - } -#else temp_norm_e = norm_l( s ); s = L_shl( s, temp_norm_e ); s_e = sub( s_e, temp_norm_e ); -#endif } // ApplyRotation(singularVectors_Left, c, s, g, x_split, &d, &x_ii, ch + 1, ch, nChannelsL); @@ -915,7 +757,6 @@ static void ApplyRotation_fx( *g = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), add( c_e, x12_e ), Mpy_32_32( L_negate( s ), x11 ), add( s_e, x11_e ), g_e ); /* exp(g_e) */ move32(); -#ifdef SVD_WMOPS_OPT Word16 c_q = sub( 31, c_e ); Word16 s_q = sub( 31, s_e ); Word32 op1, op2; @@ -957,42 +798,6 @@ static void ApplyRotation_fx( singularVector[ch][currentIndex1] = W_sat_l( temp ); // Q(singularVector) move32(); } -#else -#ifndef FIX_MINOR_SVD_WMOPS_MR1010X - FOR( ch = 0; ch < nChannels; ch++ ) - { - x11 = singularVector[ch][currentIndex2]; - move32(); - x12 = singularVector[ch][currentIndex1]; - move32(); - singularVector[ch][currentIndex2] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ - move32(); - singularVector[ch][currentIndex2] = L_shl_sat( singularVector[ch][currentIndex2], temp_exp ); /* exp(temp_exp) */ - move32(); - singularVector[ch][currentIndex1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( L_negate( s ), x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ - move32(); - singularVector[ch][currentIndex1] = L_shl_sat( singularVector[ch][currentIndex1], temp_exp ); /* exp(temp_exp) */ - move32(); - } -#else - Word32 s_neg = L_negate( s ); - Word32 temp; - FOR( ch = 0; ch < nChannels; ch++ ) - { - x11 = singularVector[ch][currentIndex2]; - move32(); - x12 = singularVector[ch][currentIndex1]; - move32(); - temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ - singularVector[ch][currentIndex2] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ - move32(); - temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( s_neg, x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ - singularVector[ch][currentIndex1] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ - move32(); - } - -#endif -#endif return; } @@ -1024,7 +829,6 @@ static void HouseholderReduction_fx( Word16 sig_x_fx_e = 0; move16(); -#ifdef FIX_1010_OPT_SINGLE_RESCALE Word16 iCh, jCh; Word16 singularVectors_Left_fx_e[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; FOR( jCh = 0; jCh < nChannelsL; jCh++ ) @@ -1035,25 +839,15 @@ static void HouseholderReduction_fx( move16(); } } -#endif /* Bidiagonal Reduction for every channel */ FOR( nCh = 0; nCh < nChannelsC; nCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - biDiagonalReductionLeft_fx( singularVectors_Left_fx, singularValues_fx, secDiag_fx, &singularVectors_Left_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); - biDiagonalReductionRight_fx( singularVectors_Left_fx, secDiag_fx, &singularVectors_Left_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); -#else biDiagonalReductionLeft_fx( singularVectors_Left_fx, singularValues_fx, secDiag_fx, singularVectors_Left_fx_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); biDiagonalReductionRight_fx( singularVectors_Left_fx, secDiag_fx, singularVectors_Left_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); -#endif Word16 L_temp_e; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word32 L_temp = BASOP_Util_Add_Mant32Exp( L_abs( singularValues_fx[nCh] ), singularValues_fx_e[nCh], L_abs( secDiag_fx[nCh] ), *secDiag_fx_e, &L_temp_e ); /* exp(L_temp_e) */ -#else Word32 L_temp = BASOP_Util_Add_Mant32Exp( L_abs( singularValues_fx[nCh] ), singularValues_fx_e[nCh], L_abs( secDiag_fx[nCh] ), secDiag_fx_e[nCh], &L_temp_e ); /* exp(L_temp_e) */ -#endif IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_temp, L_temp_e, *eps_x_fx, *eps_x_fx_e ), 1 ) ) { *eps_x_fx = L_temp; /* exp(L_temp_e) */ @@ -1064,19 +858,10 @@ static void HouseholderReduction_fx( } /* SingularVecotr Accumulation */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_e, *secDiag_fx_e, nChannelsC ); - singularVectorsAccumulationLeft_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Left_e, singularValues_fx_e, nChannelsL, nChannelsC ); -#else -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_fx_e, *secDiag_fx_e, nChannelsC ); -#else singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_fx_e, secDiag_fx_e, nChannelsC ); -#endif singularVectorsAccumulationLeft_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Left_fx_e, singularValues_fx_e, nChannelsL, nChannelsC ); -#endif return; } @@ -1091,11 +876,7 @@ static void biDiagonalReductionLeft_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ @@ -1111,39 +892,11 @@ static void biDiagonalReductionLeft_fx( Word16 norm_x_e, f_e, r_e; Word32 L_temp; Word16 L_temp_e; -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 sing_exp[MAX_OUTPUT_CHANNELS]; - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; - FOR( jCh = 0; jCh < MAX_OUTPUT_CHANNELS; jCh++ ) - { - set16_fx( sing_exp2[jCh], *singularVectors_e, MAX_OUTPUT_CHANNELS ); - } -#endif secDiag[currChannel] = Mpy_32_32( *sig_x, *g ); /* exp(sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - // rescaling block - IF( GT_16( *sig_x_e, *secDiag_e ) ) - { - FOR( Word16 i = 0; i < MAX_OUTPUT_CHANNELS; i++ ){ - IF( NE_16( i, currChannel ) ){ - secDiag[i] = L_shl( secDiag[i], sub( *secDiag_e, *sig_x_e ) ); /* sig_x_e */ - move32(); - } -} -*secDiag_e = *sig_x_e; -move16(); -} -ELSE IF( LT_16( *sig_x_e, *secDiag_e ) ) -{ - secDiag[currChannel] = L_shr_r( secDiag[currChannel], sub( *secDiag_e, *sig_x_e ) ); /* exp(secDiag_e) */ - move32(); -} -#else secDiag_e[currChannel] = *sig_x_e; move16(); -#endif /* Setting values to 0 */ ( *sig_x ) = 0; @@ -1158,54 +911,26 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), *singularVectors_e, sig_x_e ); /* exp(sig_x_e) */ -#else ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ -#endif } IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ { -#ifdef FIX_1010_OPT_DIV Word16 invVal_e; Word32 invVal; invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); -#endif norm_x = 0; move32(); norm_x_e = 0; move16(); FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_DIV -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[jCh][currChannel] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[jCh][currChannel], maxWithSign_fx( *sig_x ), &sing_exp[jCh] ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ - move32(); - sing_exp[jCh] = add( sing_exp[jCh], sub( *singularVectors_e, *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else - singularVectors[jCh][currChannel] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[jCh][currChannel], maxWithSign_fx( *sig_x ), &L_temp_e ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ - move32(); - singularVectors2_e[jCh][currChannel] = add( L_temp_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#else Word16 temp_e = norm_l( singularVectors[jCh][currChannel] ); singularVectors[jCh][currChannel] = Mpy_32_32( L_shl( singularVectors[jCh][currChannel], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp[jCh] = sub( add( invVal_e, sub( *singularVectors_e, *sig_x_e ) ), temp_e ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else singularVectors2_e[jCh][currChannel] = sub( add( invVal_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ), temp_e ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#endif } IF( GT_16( norm_x_e, 0 ) ) { @@ -1219,38 +944,18 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ L_temp = Sqrt32( norm_x, &L_temp_e ); L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); -#ifndef FIX_MINOR_SVD_WMOPS_MR1010X - IF( singularVectors[currChannel][idx] >= 0 ) - { - ( *g ) = L_negate( L_temp ); - move32(); - } - ELSE - { - ( *g ) = L_negate( L_negate( L_temp ) ); - move32(); - } -#else if ( singularVectors[currChannel][idx] >= 0 ) { L_temp = L_negate( L_temp ); } ( *g ) = L_temp; move32(); -#endif -#ifndef FIX_1010_OPT_SINGLE_RESCALE - r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[currChannel], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ - singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], sing_exp[currChannel], -( *g ), 0, &sing_exp[currChannel] ); /* sing_exp */ -#else r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ -#endif move32(); -#ifdef FIX_1010_OPT_DIV invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); -#endif FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { @@ -1260,28 +965,15 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ move16(); FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( sing_exp[jCh], *singularVectors_e ), &norm_x_e ); /* exp(norm_x_e) */ -#else norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( singularVectors2_e[jCh][currChannel], singularVectors2_e[jCh][iCh] ), &norm_x_e ); /* exp(norm_x_e) */ -#endif } -#ifndef FIX_1010_OPT_DIV - f = BASOP_Util_Divide3232_Scale_cadence( norm_x, maxWithSign_fx( r ), &f_e ); /* f_e + (norm_x_e - r_e) */ - f_e = add( f_e, sub( norm_x_e, r_e ) ); -#else f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ f_e = add( invVal_e, sub( norm_x_e, r_e ) ); -#endif FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], *singularVectors_e, Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, sing_exp[jCh] ), &sing_exp2[jCh][iCh] ); /* exp( sing_exp2) */ -#else singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], singularVectors2_e[jCh][iCh], Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, singularVectors2_e[jCh][currChannel] ), &singularVectors2_e[jCh][iCh] ); -#endif move32(); } } @@ -1291,37 +983,10 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ { singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp2[jCh][currChannel] = add( sing_exp[jCh], *sig_x_e ); -#else singularVectors2_e[jCh][currChannel] = add( singularVectors2_e[jCh][currChannel], *sig_x_e ); -#endif move16(); } -#ifndef FIX_1010_OPT_SINGLE_RESCALE - // rescaling block - Word16 exp_max = *singularVectors_e; - move16(); - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsL; jCh++ ) - { - exp_max = s_max( exp_max, sing_exp2[jCh][iCh] ); - } - } - - FOR( iCh = 0; iCh < nChannelsC; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsL; jCh++ ) - { - singularVectors[jCh][iCh] = L_shr_r( singularVectors[jCh][iCh], sub( exp_max, sing_exp2[jCh][iCh] ) ); /* exp(exp_max) */ - move32(); - } - } - *singularVectors_e = exp_max; - move16(); -#endif } // rescaling block @@ -1343,16 +1008,8 @@ return; static void biDiagonalReductionRight_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_exp[]) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 *singularVectors_e, -#else Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 *secDiag_e, -#else Word16 *secDiag_exp, -#endif const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC, /* Q0 */ const Word16 currChannel, /* Q0 */ @@ -1364,22 +1021,8 @@ static void biDiagonalReductionRight_fx( Word16 iCh, jCh, idx; Word32 norm_x, r; Word16 norm_x_e, r_e; -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_exp[MAX_OUTPUT_CHANNELS]; -#endif Word32 L_temp; Word16 L_temp_e; -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 sing_exp[MAX_OUTPUT_CHANNELS]; - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; - FOR( jCh = 0; jCh < MAX_OUTPUT_CHANNELS; jCh++ ) - { - set16_fx( sing_exp2[jCh], *singularVectors_e, MAX_OUTPUT_CHANNELS ); - } -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - set16_fx( secDiag_exp, *secDiag_e, MAX_OUTPUT_CHANNELS ); -#endif /* Setting values to 0 */ ( *sig_x ) = 0; @@ -1393,11 +1036,7 @@ static void biDiagonalReductionRight_fx( FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[currChannel][jCh] ), *singularVectors_e, sig_x_e ); /* exp(sig_x_e) */ -#else ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[currChannel][jCh] ), singularVectors2_e[currChannel][jCh], sig_x_e ); /* exp(sig_x_e) */ -#endif } IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ @@ -1407,41 +1046,17 @@ static void biDiagonalReductionRight_fx( norm_x_e = 0; move16(); -#ifdef FIX_1010_OPT_DIV Word16 invVal_e, temp_e; Word32 invVal; invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); -#endif FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /*nChannelsC */ { -#ifndef FIX_1010_OPT_DIV -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[currChannel][jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( *sig_x ), &sing_exp[jCh] ); /* exp(sing_exp + (singularVectors_e - sig_x_e)) */ - move32(); - sing_exp[jCh] = add( sing_exp[jCh], sub( *singularVectors_e, *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else - singularVectors[currChannel][jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( *sig_x ), &L_temp_e ); /* exp(sing_exp + (singularVectors_e - sig_x_e)) */ - move32(); - singularVectors2_e[currChannel][jCh] = add( L_temp_e, sub( singularVectors2_e[currChannel][jCh], *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( singularVectors2_e[currChannel][jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#else temp_e = norm_l( singularVectors[currChannel][jCh] ); singularVectors[currChannel][jCh] = Mpy_32_32( L_shl( singularVectors[currChannel][jCh], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp[jCh] = add( sub( invVal_e, temp_e ), sub( *singularVectors_e, *sig_x_e ) ); - move16(); - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#else singularVectors2_e[currChannel][jCh] = add( sub( invVal_e, temp_e ), sub( singularVectors2_e[currChannel][jCh], *sig_x_e ) ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( singularVectors2_e[currChannel][jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ -#endif -#endif } IF( GT_16( norm_x_e, 0 ) ) { @@ -1465,44 +1080,19 @@ static void biDiagonalReductionRight_fx( move32(); } -#ifndef FIX_1010_OPT_SINGLE_RESCALE - r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ - singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], sing_exp[idx], -( *g ), 0, &sing_exp[idx] ); /* exp(sing_exp) */ -#else r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* exp(sing_exp) */ -#endif move32(); -#ifdef FIX_1010_OPT_DIV invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); -#endif FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_DIV -#ifndef FIX_1010_OPT_SINGLE_RESCALE - secDiag[jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( r ), &secDiag_exp[jCh] ); /* exp(secDiag_exp + (sing_exp - r_e) */ - move32(); - secDiag_exp[jCh] = add( secDiag_exp[jCh], sub( sing_exp[jCh], r_e ) ); - move32(); -#else - secDiag[jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( r ), &secDiag_exp[jCh] ); /* exp(secDiag_exp + (sing_exp - r_e) */ - move32(); - secDiag_exp[jCh] = add( secDiag_exp[jCh], sub( singularVectors2_e[currChannel][jCh], r_e ) ); - move32(); -#endif -#else temp_e = norm_l( singularVectors[currChannel][jCh] ); secDiag[jCh] = Mpy_32_32( L_shl( singularVectors[currChannel][jCh], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - secDiag_exp[jCh] = add( sub( invVal_e, temp_e ), sub( sing_exp[jCh], r_e ) ); -#else secDiag_exp[jCh] = add( sub( invVal_e, temp_e ), sub( singularVectors2_e[currChannel][jCh], r_e ) ); -#endif move16(); -#endif } FOR( iCh = currChannel + 1; iCh < nChannelsL; iCh++ ) /* nChannelsL */ @@ -1513,20 +1103,12 @@ static void biDiagonalReductionRight_fx( move16(); FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[iCh][jCh], singularVectors[currChannel][jCh] ), add( *singularVectors_e, sing_exp[jCh] ), &norm_x_e ); /* exp(norm_x_e) */ -#else norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[iCh][jCh], singularVectors[currChannel][jCh] ), add( singularVectors2_e[iCh][jCh], singularVectors2_e[currChannel][jCh] ), &norm_x_e ); /* exp(norm_x_e) */ -#endif } FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], *singularVectors_e, Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &sing_exp2[iCh][jCh] ); /* exp(sing_exp2) */ -#else singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ -#endif move32(); } } @@ -1535,54 +1117,12 @@ static void biDiagonalReductionRight_fx( { singularVectors[currChannel][jCh] = Mpy_32_32( singularVectors[currChannel][jCh], ( *sig_x ) ); /* exp(sing_exp + sig_x_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp2[currChannel][jCh] = add( sing_exp[jCh], *sig_x_e ); -#else singularVectors2_e[currChannel][jCh] = add( singularVectors2_e[currChannel][jCh], *sig_x_e ); -#endif move16(); } -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - /*rescaling block*/ - Word16 exp_max = *secDiag_e; - move16(); - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - exp_max = s_max( exp_max, secDiag_exp[jCh] ); - } - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - secDiag[jCh] = L_shr_r( secDiag[jCh], sub( exp_max, secDiag_exp[jCh] ) ); /* exp(exp_max) */ - move32(); - } - *secDiag_e = exp_max; - move16(); -#endif - -#ifndef FIX_1010_OPT_SINGLE_RESCALE - exp_max = *singularVectors_e; - move16(); - FOR( iCh = 0; iCh < nChannelsL; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - exp_max = s_max( exp_max, sing_exp2[iCh][jCh] ); - } - } - FOR( iCh = 0; iCh < nChannelsL; iCh++ ) - { - FOR( jCh = 0; jCh < nChannelsC; jCh++ ) - { - singularVectors[iCh][jCh] = L_shr_r( singularVectors[iCh][jCh], sub( exp_max, sing_exp2[iCh][jCh] ) ); /* exp(exp_max) */ - move32(); - } - } - *singularVectors_e = exp_max; - move16(); -#endif } } @@ -1598,11 +1138,7 @@ static void biDiagonalReductionRight_fx( static void singularVectorsAccumulationLeft_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* input exp(singularVectors_Left_e), output Q31 */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC /* Q0 */ @@ -1612,13 +1148,6 @@ static void singularVectorsAccumulationLeft_fx( Word16 nChannels; Word32 norm_y, t_jj, t_ii; Word16 norm_y_e, t_jj_e, t_ii_e, temp_exp; -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; - FOR( nCh = 0; nCh < MAX_OUTPUT_CHANNELS; nCh++ ) - { - set16_fx( sing_exp2[nCh], singularVectors_e, MAX_OUTPUT_CHANNELS ); - } -#endif /* Processing */ nChannels = s_min( nChannelsL, nChannelsC ); /* min(nChannelsL,ChannelsC) Q0*/ @@ -1638,13 +1167,8 @@ static void singularVectorsAccumulationLeft_fx( IF( t_ii ) /*if (fabsf(t_ii) > EPSILON *fabsf(t_ii)) {*/ { -#ifdef FIX_1010_OPT_DIV t_ii = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( t_ii ), &temp_exp ); t_ii_e = sub( temp_exp, t_ii_e ); -#else - t_ii = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxWithSign_fx( t_ii ), &temp_exp ); /* exp(1 + (temp_exp + tii_e)) */ - t_ii_e = add( 1, sub( temp_exp, t_ii_e ) ); -#endif Word16 tempe; Word32 temp = BASOP_Util_Divide3232_Scale_cadence( t_ii, maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &tempe ); tempe = add( tempe, sub( t_ii_e, singularVectors_Left_e[nCh][nCh] ) ); @@ -1659,13 +1183,9 @@ static void singularVectorsAccumulationLeft_fx( move16(); FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ), add( sing_exp2[k][nCh], sing_exp2[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ -#else prod[k] = W_mult0_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ); prod_e[k] = add( singularVectors_Left_e[k][nCh], singularVectors_Left_e[k][iCh] ); max_e = s_max( max_e, prod_e[k] ); -#endif } FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ @@ -1678,18 +1198,10 @@ static void singularVectorsAccumulationLeft_fx( norm_y = W_extract_h( acc ); norm_y_e = add( sub( max_e, acc_e ), 1 ); t_jj = Mpy_32_32( temp, norm_y ); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - t_jj_e = add( temp_exp, sub( add( t_ii_e, norm_y_e ), sing_exp2[nCh][nCh] ) ); -#else t_jj_e = add( tempe, norm_y_e ); -#endif FOR( k = nCh; k < nChannelsL; k++ ) /* nChannelsL */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors_Left[k][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[k][iCh], sing_exp2[k][iCh], Mpy_32_32( t_jj, singularVectors_Left[k][nCh] ), add( t_jj_e, sing_exp2[k][nCh] ), &sing_exp2[k][iCh] ); /* exp(sing_exp2) */ -#else singularVectors_Left[k][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[k][iCh], singularVectors_Left_e[k][iCh], Mpy_32_32( t_jj, singularVectors_Left[k][nCh] ), add( t_jj_e, singularVectors_Left_e[k][nCh] ), &singularVectors_Left_e[k][iCh] ); /* exp(sing_exp2) */ -#endif move32(); } } @@ -1698,11 +1210,7 @@ static void singularVectorsAccumulationLeft_fx( { singularVectors_Left[iCh][nCh] = Mpy_32_32( singularVectors_Left[iCh][nCh], t_ii ); /* exp(sing_exp2 + t_ii_e) */ move32(); -#ifndef FIX_1010_OPT_SINGLE_RESCALE - sing_exp2[iCh][nCh] = add( sing_exp2[iCh][nCh], t_ii_e ); -#else singularVectors_Left_e[iCh][nCh] = add( singularVectors_Left_e[iCh][nCh], t_ii_e ); -#endif move16(); } } @@ -1714,11 +1222,7 @@ static void singularVectorsAccumulationLeft_fx( move32(); } } -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors_Left[nCh][nCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[nCh][nCh], sing_exp2[nCh][nCh], ONE_IN_Q30, 1, &sing_exp2[nCh][nCh] ); /* exp(sing_exp2) */ -#else singularVectors_Left[nCh][nCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[nCh][nCh], singularVectors_Left_e[nCh][nCh], ONE_IN_Q30, 1, &singularVectors_Left_e[nCh][nCh] ); /* exp(sing_exp2) */ -#endif move32(); } // fclose(fp); @@ -1726,11 +1230,7 @@ static void singularVectorsAccumulationLeft_fx( { FOR( iCh = 0; iCh < nChannelsC; iCh++ ) { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], sing_exp2[nCh][iCh] ); /* Q31 */ -#else singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ -#endif move32(); } } @@ -1748,16 +1248,8 @@ static void singularVectorsAccumulationRight_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_Left_e) */ Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* input exp(singularVectors_Left_e), output Q31 */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ -#ifndef FIX_1010_OPT_SINGLE_RESCALE - Word16 singularVectors_e, -#else Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], -#endif -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - Word16 secDiag_e, -#else Word16 *secDiag_e, -#endif const Word16 nChannelsC /* Q0 */ ) { @@ -1783,22 +1275,11 @@ static void singularVectorsAccumulationRight_fx( FOR( iCh = nCh + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC*/ { -#ifdef FIX_1010_OPT_DIV ratio_float = L_deposit_h( BASOP_Util_Divide3232_Scale( singularVectors_Left[nCh][iCh], maxWithSign_fx( singularVectors_Left[nCh][nCh + 1] ), &temp_exp1 ) ); /* exp(temp_exp1) */ singularVectors_Right[iCh][nCh] = L_deposit_h( BASOP_Util_Divide3232_Scale( ratio_float, maxWithSign_fx( t_ii ), &sing_right_exp[iCh][nCh] ) ); /* exp(sing_right_exp + (temp_exp1 - secDiag_e) */ -#else - ratio_float = BASOP_Util_Divide3232_Scale_cadence( singularVectors_Left[nCh][iCh], maxWithSign_fx( singularVectors_Left[nCh][nCh + 1] ), &temp_exp1 ); /* exp(temp_exp1) */ - singularVectors_Right[iCh][nCh] = BASOP_Util_Divide3232_Scale_cadence( ratio_float, maxWithSign_fx( t_ii ), &sing_right_exp[iCh][nCh] ); /* exp(sing_right_exp + (temp_exp1 - secDiag_e) */ -#endif -#ifdef FIX_1010_OPT_SINGLE_RESCALE temp_exp1 = add( temp_exp1, sub( singularVectors_Left_e[nCh][iCh], singularVectors_Left_e[nCh][nCh + 1] ) ); -#endif move32(); -#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE - sing_right_exp[iCh][nCh] = add( sing_right_exp[iCh][nCh], sub( temp_exp1, secDiag_e ) ); -#else sing_right_exp[iCh][nCh] = add( sing_right_exp[iCh][nCh], sub( temp_exp1, secDiag_e[nCh + 1] ) ); -#endif move16(); // singularVectors_Right[iCh][nCh] = L_shl_sat( singularVectors_Right[iCh][nCh], temp_exp2 ); } @@ -1812,11 +1293,7 @@ static void singularVectorsAccumulationRight_fx( FOR( k = nCh + 1; k < nChannelsC; k++ ) /* nChannelsC */ { -#ifndef FIX_1010_OPT_SINGLE_RESCALE - norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[nCh][k], singularVectors_Right[k][iCh] ), add( singularVectors_e, sing_right_exp[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ -#else norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[nCh][k], singularVectors_Right[k][iCh] ), add( singularVectors_Left_e[nCh][k], sing_right_exp[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ -#endif } FOR( k = nCh + 1; k < nChannelsC; k++ ) /* nChannelsC */ @@ -1853,7 +1330,6 @@ static void singularVectorsAccumulationRight_fx( *-------------------------------------------------------------------------*/ -#ifdef FIX_1010_OPT_GIVENS_INV static void GivensRotation2_fx( const Word32 x, /* exp(x_e) */ const Word16 x_e, @@ -1875,7 +1351,6 @@ static void GivensRotation2_fx( *resultInv = ISqrt32( r, outInv_e ); move32(); } -#endif static Word32 GivensRotation_fx( const Word32 x, /* exp(x_e) */ @@ -1884,62 +1359,10 @@ static Word32 GivensRotation_fx( const Word16 z_e, Word16 *out_e ) { -#ifdef FIX_1010_OPT_GIVENS Word32 r; -#else - Word32 x_abs, z_abs; - Word32 cotan, tan, r; - Word16 temp_exp; - Word32 L_temp; -#endif -#ifdef FIX_1010_OPT_GIVENS r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( z, z ), shl( z_e, 1 ), Mpy_32_32( x, x ), shl( x_e, 1 ), out_e ); r = Sqrt32( r, out_e ); -#else - x_abs = L_abs( x ); - z_abs = L_abs( z ); - test(); - IF( LE_32( x_abs, Mpy_32_32( CONVERGENCE_FACTOR_FX, x_abs ) ) && LE_32( z_abs, Mpy_32_32( CONVERGENCE_FACTOR_FX, z_abs ) ) ) - { - r = 0; - move32(); - } - ELSE IF( BASOP_Util_Cmp_Mant32Exp( x_abs, x_e, z_abs, z_e ) >= 0 ) - { - IF( LE_32( x_abs, SVD_MINIMUM_VALUE_FX ) ) - { - r = 0; - move32(); - } - ELSE - { - cotan = BASOP_Util_Divide3232_Scale_cadence( z_abs, x_abs, &temp_exp ); /* exp(temp_exp + (z_e - x_e) */ - temp_exp = add( temp_exp, sub( z_e, x_e ) ); - L_temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, Mpy_32_32( cotan, cotan ), 2 * temp_exp, &temp_exp ); /* exp(temp_exp) */ - L_temp = Sqrt32( L_temp, &temp_exp ); - r = Mpy_32_32( x_abs, L_temp ); /* exp(x_e + temp_exp) */ - *out_e = add( x_e, temp_exp ); - } - } - ELSE - { - IF( LE_32( z_abs, SVD_MINIMUM_VALUE_FX ) ) - { - r = 0; - move32(); - } - ELSE - { - tan = BASOP_Util_Divide3232_Scale_cadence( x_abs, z_abs, &temp_exp ); /* exp(temp_exp + (x_e - z_e) */ - temp_exp = add( temp_exp, sub( x_e, z_e ) ); - L_temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, Mpy_32_32( tan, tan ), shl( temp_exp, 1 ), &temp_exp ); /* exp(temp_exp) */ - L_temp = Sqrt32( L_temp, &temp_exp ); - r = Mpy_32_32( z_abs, L_temp ); /* exp(z_e + temp_exp) */ - *out_e = add( z_e, temp_exp ); - } - } -#endif return ( r ); } @@ -1953,20 +1376,6 @@ static Word32 maxWithSign_fx( const Word32 a /* Qx */ ) { -#ifndef FIX_MINOR_SVD_WMOPS_MR1010X - IF( GT_32( L_abs( a ), SVD_MINIMUM_VALUE_FX ) ) - { - return a; - } - ELSE IF( a < 0 ) - { - return -SVD_MINIMUM_VALUE_FX; - } - ELSE - { - return SVD_MINIMUM_VALUE_FX; - } -#else Word32 result; IF( a >= 0 ) { @@ -1977,7 +1386,6 @@ static Word32 maxWithSign_fx( result = L_min( a, -SVD_MINIMUM_VALUE_FX ); } return result; -#endif } /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index c187c351c..aa5a379e8 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -644,21 +644,13 @@ void stereo_tcx_core_dec_fx( test(); test(); test(); -#ifdef NONBE_FIX_1402_WAVEADJUST IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch_fx && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) -#else - IF( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) ) -#endif { lerp( synthFB_fx, synth_fx, st->L_frame, hTcxDec->L_frameTCX ); if ( !bfi && st->prev_bfi ) { -#ifdef NONBE_FIX_1402_WAVEADJUST st->hPlcInfo->Pitch_fx = 0; -#else - st->hPlcInfo->Pitch = 0; -#endif move16(); } } @@ -816,21 +808,11 @@ void stereo_tcx_core_dec_fx( move16(); /* Postfiltering */ -#ifndef MSAN_FIX - IF( st->p_bpf_noise_buf_32 ) - { - Copy_Scale_sig_32_16( st->p_bpf_noise_buf_32, st->p_bpf_noise_buf, st->L_frame, negate( Q11 ) ); - } -#endif post_decoder( st, synth_buf_fx, pit_gain_fx, pitch, signal_out_fx, st->p_bpf_noise_buf ); test(); -#ifdef MSAN_FIX IF( st->p_bpf_noise_buf_32 && st->tcxonly == 0 ) -#else - IF( st->p_bpf_noise_buf_32 ) -#endif // MSAN_FIX { Copy_Scale_sig_16_32_no_sat( st->p_bpf_noise_buf, st->p_bpf_noise_buf_32, st->L_frame, Q11 ); /* q_p_bpf + Q11 */ } diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index 98c1a6a79..3191a8b4a 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -137,7 +137,6 @@ void tdm_low_rate_dec_fx( edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, find_guarded_bits_fx( L_FRAME ), IVAS_CPE_TD ); -#ifdef FIX_USAN_ISSUES IF( bwe_exc != NULL ) { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, @@ -148,10 +147,6 @@ void tdm_low_rate_dec_fx( Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], NULL, st->hGSCDec->last_exc_dct_in_fx, L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); } -#else - Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, - L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); -#endif /*----------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected *----------------------------------------------------------------------*/ diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index fc793dff0..e2528e619 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -270,9 +270,7 @@ UWord8 apa_reconfigure( free( ps->buf_out_fx ); ps->buf_out_fx = (Word16 *) malloc( sizeof( Word16 ) * ps->buf_out_capacity ); -#ifdef MSAN_FIX memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) ); -#endif ps->Q_buf_out = Q15; move16(); IF( !ps->buf_out_fx ) diff --git a/lib_dec/lead_deindexing_fx.c b/lib_dec/lead_deindexing_fx.c index 786e0c276..ecc5f6fe0 100644 --- a/lib_dec/lead_deindexing_fx.c +++ b/lib_dec/lead_deindexing_fx.c @@ -192,7 +192,6 @@ void re8_decode_base_index_fx( m1 = sub( k1, 1 ); m2 = 8; move16(); -#ifdef CR_2109_to_2112_cd0_ce0 l = 1; move16(); FOR( i = 0; i < 8; i++ ) @@ -206,9 +205,6 @@ void re8_decode_base_index_fx( test(); /* if the signs are constrained and all components are non-zero */ IF( EQ_16( k1, 7 ) && ( l > 0 ) ) -#else - IF( k1 == 7 ) -#endif { m2 = 7; move16(); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 413585447..77deb9e7d 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -44,9 +44,6 @@ #include "jbm_pcmdsp_fifo.h" #include #include -#ifndef FIX_DISCLAIMER -#include -#endif #include "wmc_auto.h" #define INV_1000_Q31 2147484 /*1/1000 IN Q31*/ @@ -3061,85 +3058,6 @@ const char *IVAS_DEC_GetErrorMessage( return ivas_error_to_string( error ); } -#ifndef FIX_DISCLAIMER -/*---------------------------------------------------------------------* - * get_channel_config() - * - * Gets a str related to input config - *---------------------------------------------------------------------*/ - -static ivas_error get_channel_config( - AUDIO_CONFIG config, - Word8 *str ) -{ - IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_MONO ) ) - { - strcpy( (char *) str, "Mono" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_STEREO ) ) - { - strcpy( (char *) str, "Stereo" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1 ) ) - { - strcpy( (char *) str, "Multichannel 5.1 (CICP6)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_7_1 ) ) - { - strcpy( (char *) str, "Multichannel 7.1 (CICP12)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1_2 ) ) - { - strcpy( (char *) str, "Multichannel 5.1+2 (CICP14)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1_4 ) ) - { - strcpy( (char *) str, "Multichannel 5.1+4 (CICP16)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_7_1_4 ) ) - { - strcpy( (char *) str, "Multichannel 7.1+4 (CICP19)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) - { - strcpy( (char *) str, "Multichannel (custom loudspeaker layout)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_FOA ) ) - { - strcpy( (char *) str, "Ambisonics: First Order (FOA)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_HOA2 ) ) - { - strcpy( (char *) str, "Ambisonics: Second Order (HOA2)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_HOA3 ) ) - { - strcpy( (char *) str, "Ambisonics: Third Order (HOA3)" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL ) ) - { - strcpy( (char *) str, "Binaural: no room" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) - { - strcpy( (char *) str, "Binaural: room with impulse responses" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) - { - strcpy( (char *) str, "Binaural: room with reverb" ); - } - ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) - { - strcpy( (char *) str, "External renderer" ); - } - ELSE - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Error: Incorrect Input/Output Configuration" ); - } - - return IVAS_ERR_OK; -} -#endif /*---------------------------------------------------------------------* * printConfigInfo_dec( ) diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 712ead8f4..fcd5142a4 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -161,13 +161,7 @@ typedef struct { Word16 L_frameTCX; -#ifndef NONBE_FIX_1402_WAVEADJUST - Word16 Pitch; -#endif Word16 Pitch_fx; -#ifndef NONBE_FIX_1402_WAVEADJUST - Word16 T_bfi; -#endif Word8 T_bfi_fx; Word16 Transient[MAX_POST_LEN]; @@ -187,9 +181,6 @@ typedef struct Word16 step_concealgain_fx; Word16 concealment_method; -#ifndef NONBE_FIX_1402_WAVEADJUST - Word16 subframe; -#endif Word16 subframe_fx; Word16 nbLostCmpt; Word16 seed; diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 492c927b6..1b51a29fb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -6070,12 +6070,6 @@ void ivas_swb_tbe_dec_fx( tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); /* convert LSPs to LP coefficients */ E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - /* Bring the LPCs to Q12 */ - Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); - lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this - move16(); -#endif } } diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 650e8572b..e74df3a96 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -146,28 +146,20 @@ ivas_error TonalMDCTConceal_Init_ivas_fx( hTonalMDCTConc->tcx_cfg = hTcxCfg; hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->lastBlockData.spectralData, 0, L_FRAME_MAX ); -#endif move16(); hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->secondLastBlockData.spectralData, 0, L_FRAME_MAX ); -#endif move16(); hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData; move16(); hTonalMDCTConc->secondLastPowerSpectrum_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp; move16(); hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->lastBlockData.scaleFactors, 0, FDNS_NPTS ); -#endif move16(); hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1]; -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->secondLastBlockData.scaleFactors, 0, FDNS_NPTS ); -#endif move16(); hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0]; move16(); @@ -234,9 +226,7 @@ ivas_error TonalMDCTConceal_Init_ivas_fx( move16(); /* just the second half of the second last pcm output is needed */ -#ifdef MSAN_FIX set16_fx( hTonalMDCTConc->timeDataBuffer, 0, ( 3 * L_FRAME_MAX ) / 2 ); -#endif hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) / 2 )]; hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - min( L_FRAME_MAX, nSamples )]; /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */ @@ -1226,9 +1216,7 @@ void TonalMDCTConceal_Detect_ivas_fx( Word16 element_mode ) { Word32 secondLastMDST[L_FRAME_MAX]; -#ifdef MSAN_FIX set32_fx( secondLastMDST, 0, L_FRAME_MAX ); -#endif Word32 secondLastMDCT[L_FRAME_MAX]; Word16 secondLastMDCT_exp; Word32 *powerSpectrum = secondLastMDST; @@ -1236,9 +1224,7 @@ void TonalMDCTConceal_Detect_ivas_fx( Word16 nSamples; // Word16 nBands; Word32 sns_int_scf_fx[FDNS_NPTS]; -#ifdef MSAN_FIX set32_fx( sns_int_scf_fx, 0, FDNS_NPTS ); -#endif nSamples = hTonalMDCTConc->nSamples; move16(); @@ -1302,11 +1288,7 @@ void TonalMDCTConceal_Detect_ivas_fx( { /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */ /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */ -#ifdef MSAN_FIX Word16 temp_power_spectrum_q = 0; -#else - Word16 power_spectrum_q; -#endif nSamples = hTonalMDCTConc->nNonZeroSamples; move16(); Copy_Scale_sig_16_32_DEPREC( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples, Q15 ); @@ -3511,9 +3493,7 @@ void TonalMdctConceal_whiten_noise_shape_ivas_fx( psychParams = st->hTonalMDCTConc->psychParams; hFdCngCom = st->hFdCngDec->hFdCngCom; -#ifdef MSAN_FIX set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); -#endif IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) { diff --git a/lib_dec/transition_dec_fx.c b/lib_dec/transition_dec_fx.c index b82378198..b9ad17fcf 100644 --- a/lib_dec/transition_dec_fx.c +++ b/lib_dec/transition_dec_fx.c @@ -56,9 +56,7 @@ void transition_dec_fx( Word16 i, offset, temp, tmp; Word16 limit_flag; Word16 i_subfridx; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( Opt_AMR_WB ); -#endif i_subfridx = i_subfr / L_SUBFR; /*i_subfr / L_SUBFR*/ /* Set limit_flag to 0 for restrained limits, and 1 for extended limits */ @@ -830,9 +828,7 @@ Word16 tc_classif_fx( /*o: Q0*/ ) { Word16 tc_subfr, indice; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( L_frame ); -#endif IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { IF( get_next_indice_fx( st_fx, 1 ) ) diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c index f993caa8d..75a514cc2 100644 --- a/lib_dec/waveadjust_fec_dec_fx.c +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -848,16 +848,8 @@ void concealment_init_ivas_fx( hPlcInfo->L_frameTCX = L_frameTCX; move16(); -#ifndef NONBE_FIX_1402_WAVEADJUST - hPlcInfo->Pitch = 0; - move16(); -#endif hPlcInfo->Pitch_fx = 0; move16(); -#ifndef NONBE_FIX_1402_WAVEADJUST - hPlcInfo->T_bfi = 0; - move16(); -#endif hPlcInfo->T_bfi_fx = 0; move16(); hPlcInfo->outx_new_n1_fx = 0; @@ -876,10 +868,6 @@ void concealment_init_ivas_fx( move16(); hPlcInfo->concealment_method = TCX_NONTONAL; move16(); -#ifndef NONBE_FIX_1402_WAVEADJUST - hPlcInfo->subframe = 0; - move16(); -#endif hPlcInfo->subframe_fx = 0; move16(); hPlcInfo->nbLostCmpt = (Word16) L_deposit_l( 0 ); @@ -1326,11 +1314,7 @@ static Word16 waveform_adj_fix( test(); test(); test(); -#ifdef NONBE_FIX_1402_WAVEADJUST IF( hPlcInfo->T_bfi_fx && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) -#else - IF( hPlcInfo->T_bfi && ( LE_16( pitch, Framesizediv2 ) ) && ( GT_16( Framesize, 256 ) ) && ( EQ_16( core, 1 ) ) ) -#endif { Word16 i1 = 0, i2 = 0; Word16 pos1, pos2, pos3; diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index d2d5ac4e6..a93690738 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -395,11 +395,7 @@ ivas_error acelp_core_enc_fx( IF( !nelp_mode && !ppp_mode ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, -#else - st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, -#endif tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -465,11 +461,7 @@ ivas_error acelp_core_enc_fx( tc_classif_enc_fx( Q_new, st_fx->L_frame, &tc_subfr_fx, &position, attack_flag, st_fx->pitch[0], res_fx ); config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#ifdef NONBE_FIX_GSC_BSTR -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, -#else - -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, -#endif tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -522,11 +514,7 @@ ivas_error acelp_core_enc_fx( /* Configure ACELP bit allocation */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#ifdef NONBE_FIX_GSC_BSTR -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, -#else - -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, -#endif st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /* redo LSF quantization */ @@ -772,21 +760,17 @@ ivas_error acelp_core_enc_ivas_fx( Word32 Bin_E_fx[L_FFT], Bin_E_old_fx[L_FFT / 2]; Word16 clip_var_fx, mem_w0_bck_fx, streaklimit_fx; -#ifdef MSAN_FIX set16_fx( old_bwe_exc_fx, 0, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); set16_fx( old_exc_fx, 0, L_EXC ); set16_fx( Aq, 0, NB_SUBFR16k * ( M + 1 ) ); set16_fx( syn_fx, 0, L_FRAME16k ); -#endif Word16 tilt_code_bck_fx; Word32 gc_threshold_bck_fx; Word16 clip_var_bck_fx[6]; Word32 q_env_fx[NUM_ENV_CNG]; -#ifdef MSAN_FIX set32_fx( q_env_fx, 0, NUM_ENV_CNG ); set16_fx( exc2_fx, 0, L_FRAME16k ); -#endif Word16 exc3_fx[L_FRAME16k]; Word16 syn1_fx[L_FRAME16k]; Word16 *tdm_Pri_pitch_buf_fx; @@ -1189,11 +1173,7 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( !nelp_mode && !ppp_mode ) { -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif } /*-----------------------------------------------------------------* @@ -1330,11 +1310,7 @@ ivas_error acelp_core_enc_ivas_fx( { tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif } /*---------------------------------------------------------------* @@ -1393,11 +1369,7 @@ ivas_error acelp_core_enc_ivas_fx( lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); /* Configure ACELP bit allocation */ -#ifdef NONBE_FIX_GSC_BSTR config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#else - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); -#endif /* redo LSF quantization */ lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL, Q_new ); @@ -1459,11 +1431,7 @@ ivas_error acelp_core_enc_ivas_fx( IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) { Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn -#ifdef MSAN_FIX Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 1 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); // st->Q_syn -#else - Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 2 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); -#endif st->hTcxEnc->q_Txnq = st->Q_syn; move16(); } @@ -1488,11 +1456,7 @@ ivas_error acelp_core_enc_ivas_fx( *-----------------------------------------------------------------*/ Scale_sig( syn_fx, L_FRAME, sub( s_min( st->Q_syn, Q_new ), st->Q_syn ) ); // min( st->Q_syn, Q_new ) -#ifdef MSAN_FIX Scale_sig( res_fx, st->L_frame, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); // min( st->Q_syn, Q_new ) -#else - Scale_sig( res_fx, L_FRAME16k, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); -#endif FEC_encode_ivas_fx( hBstr, st->acelp_cfg, syn_fx, st->coder_type, st->clas, pitch_buf, res_fx, &st->Last_pulse_pos, st->L_frame, st->total_brate, s_min( st->Q_syn, Q_new ) ); IF( st->hBWE_TD != NULL ) { @@ -1557,11 +1521,7 @@ ivas_error acelp_core_enc_ivas_fx( IF( !st->Opt_SC_VBR && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { /* Apply a non linearity to the SHB excitation */ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#else - Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc -#endif non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, Q_new, st->coder_type, voice_factors_fx, st->L_frame ); Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index d88e1523e..f9058b9b9 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -149,11 +149,7 @@ void acelp_core_switch_enc_fx( *----------------------------------------------------------------*/ config_acelp1( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, -#ifdef NONBE_FIX_GSC_BSTR GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#else - GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#endif encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); @@ -264,11 +260,7 @@ void acelp_core_switch_enc_ivas_fx( *----------------------------------------------------------------*/ config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, -#ifdef NONBE_FIX_GSC_BSTR GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#else - GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); -#endif encod_gen_voic_core_switch_ivas_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); diff --git a/lib_enc/bass_psfilter_enc_fx.c b/lib_enc/bass_psfilter_enc_fx.c index a1d672fe0..a241101ba 100644 --- a/lib_enc/bass_psfilter_enc_fx.c +++ b/lib_enc/bass_psfilter_enc_fx.c @@ -269,11 +269,7 @@ Word16 bass_pf_enc_fx( st = sub( s2, s2_old ); FOR( i = 0; i < tmp16; i++ ) { -#ifdef FIX_ISSUE_1187 noise_buf[i] = shl_sat( mem_bpf->noise_buf[i], st ); -#else - noise_buf[i] = shl( mem_bpf->noise_buf[i], st ); -#endif move16(); } Copy( noise_buf + l_subfr, mem_bpf->noise_buf, tmp16 ); diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 6c99a4306..e2b29ba59 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2011,14 +2011,12 @@ void CNG_enc_ivas_fx( /* convert log2 of residual signal energy */ /*enr = (float)log10( enr + 0.1f ) / (float)log10( 2.0f ); */ -#ifdef FIX_ISSUE_1245 IF( L_ener == 0 ) { enr = -850; /*log(0.1) base 2 in Q8*/ move16(); } ELSE -#endif { hi = norm_l( L_ener ); lo = Log2_norm_lc( L_shl( L_ener, hi ) ); diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index e701b8e46..d3725dcba 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -37,14 +37,8 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * Word16 *bwe_exc /* o : excitation for SWB TBE Qx */ ) { -#ifndef SIMPLIFY_CODE_BE - Word16 i, j, i_subfr, j_subfr; - Word16 tmp, tmp2, Es_pred; - Word32 gain_code_vect[2]; -#else Word16 i, i_subfr, j_subfr; Word16 tmp, Es_pred; -#endif Word16 T0, T0_min, T0_min_frac, T0_max, T0_max_frac, T0_res; Word16 T0_frac; Word16 gain_pit, voice_fac; @@ -103,11 +97,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * /* Configure ACELP */ -#ifndef MSAN_FIX - hLPDmem->nbits = BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr ); -#else BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr ); -#endif /* Init Framing parameters */ move16(); @@ -324,12 +314,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); -#ifndef SIMPLIFY_CODE_BE - gain_code_vect[0] = gain_code; - move32(); - gain_code_vect[1] = gain_code; - move32(); -#endif /*----------------------------------------------------------* * - voice factor (for pitch enhancement) * *----------------------------------------------------------*/ @@ -361,32 +345,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * /*-------------------------------------------------------* * - Find the total excitation. * *-------------------------------------------------------*/ -#ifndef SIMPLIFY_CODE_BE - tmp2 = shr( L_SUBFR, 1 ); - FOR( j = 0; j < 2; j++ ) - { - FOR( i = sub( tmp2, shr( L_SUBFR, 1 ) ); i < tmp2; i++ ) - { - /* code in Q9, gain_pit in Q14; exc Q_new */ - Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); - Ltmp = L_shl( Ltmp, Q_new_p5 ); - Ltmp = L_mac( Ltmp, gain_pit, exc[i + i_subfr] ); - BASOP_SATURATE_WARNING_OFF_EVS - exc2[i] = round_fx( L_shl( Ltmp, 1 ) ); - BASOP_SATURATE_WARNING_ON_EVS - - Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code[i] ); - Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); - Ltmp = L_add( Ltmp, Ltmp2 ); - BASOP_SATURATE_WARNING_OFF_EVS - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - BASOP_SATURATE_WARNING_ON_EVS - exc[i + i_subfr] = round_fx( Ltmp ); - } - tmp2 = L_SUBFR; - move16(); - } -#else FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14; exc Q_new */ @@ -402,7 +360,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); move16(); } -#endif /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index e6fc25e36..54f57b287 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -14,11 +14,9 @@ #include "stl.h" // #include "basop_mpy.h" #include "prot_fx_enc.h" -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -1717,9 +1715,7 @@ void EstimateStereoTCXNoiseLevel_fx( Word16 *fac_ns_q; Word32 total_brate; -#ifdef MSAN_FIX set32_fx( combined_q_spectrum, 0, N_MAX ); -#endif FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -4365,9 +4361,6 @@ void coder_tcx_fx( Word16 winMDST[N_MAX + L_MDCT_OVLP_MAX]; Word16 *pWinMDST; Word16 left_overlap_mode, right_overlap_mode; -#ifndef MSAN_FIX - LPD_state_HANDLE hLPDmem = st->hLPDmem; -#endif TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; left_overlap = right_overlap = -1; @@ -4533,10 +4526,6 @@ void coder_tcx_fx( st, hm_cfg ); -#ifndef MSAN_FIX - hLPDmem->nbits = add( hLPDmem->nbits, add( tnsBits, ltpBits ) ); - move16(); -#endif } diff --git a/lib_enc/cod_uv_fx.c b/lib_enc/cod_uv_fx.c index 8eccddc0b..8b1e8a144 100644 --- a/lib_enc/cod_uv_fx.c +++ b/lib_enc/cod_uv_fx.c @@ -135,7 +135,6 @@ void gauss_L2_ivas_fx( *gain = L_deposit_l( 0 ); move32(); /*Update correlations for gains coding */ -#ifdef FIX_ISSUE_1167 tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */ tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */ FOR( i = 0; i < L_SUBFR; i++ ) @@ -144,34 +143,17 @@ void gauss_L2_ivas_fx( tmp32 = L_mac0( tmp32, tmp16, tmp16 ); /* Q16 */ tmp32_2 = L_mac0( tmp32_2, tmp16, shr( y2[i], 1 ) ); /* Q16 */ } -#else - tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ - tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ - FOR( i = 0; i < L_SUBFR; i++ ) - { - tmp32 = L_mac0( tmp32, y11[i], y11[i] ); /* Q18 */ - tmp32_2 = L_mac0( tmp32_2, y11[i], y2[i] ); /* Q18 */ - } -#endif tmp16 = norm_l( tmp32 ); // To be checked g_corr->y1y1 = round_fx_sat( L_shl( tmp32, tmp16 ) ); -#ifdef FIX_ISSUE_1167 g_corr->y1y1_e = sub( 31 - 16, tmp16 ); -#else - g_corr->y1y1_e = sub( 31 - 18, tmp16 ); -#endif move16(); move16(); tmp16 = norm_l( tmp32_2 ); g_corr->y1y2 = round_fx_sat( L_shl( tmp32_2, tmp16 ) ); -#ifdef FIX_ISSUE_1167 g_corr->y1y2_e = sub( 31 - 16, tmp16 ); -#else - g_corr->y1y2_e = sub( 31 - 18, tmp16 ); -#endif move16(); move16(); } diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index bfe17fcd2..405b3ac2b 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -299,11 +299,9 @@ static void init_tcx_fx( Word16 i; Word16 fscaleFB; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) MCT_flag; (void) total_brate; (void) last_total_brate; -#endif // PMT("init_tcx_fx needs an entire review to adapt to IVAS") fscaleFB = div_l( L_shl( st->input_Fs, LD_FSCALE_DENOM + 1 ), 12800 ); @@ -945,9 +943,7 @@ static void init_modes_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ -#ifdef FIX_920_IGF_INIT_ERROR const Word32 igf_brate, /* i : IGF configuration bitrate */ -#endif const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ) { @@ -1080,11 +1076,7 @@ void init_coder_ace_plus_ivas_fx( test(); IF( st->igf && st->hIGFEnc != NULL ) { -#ifdef FIX_920_IGF_INIT_ERROR IGFEncSetMode_ivas_fx( st->hIGFEnc, igf_brate, st->bwidth, st->element_mode, st->rf_mode ); -#else - IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); -#endif } ELSE IF( st->hIGFEnc != NULL ) { diff --git a/lib_enc/core_enc_ol_fx.c b/lib_enc/core_enc_ol_fx.c index 04857c334..18f48e904 100644 --- a/lib_enc/core_enc_ol_fx.c +++ b/lib_enc/core_enc_ol_fx.c @@ -80,10 +80,8 @@ void core_encode_openloop_fx( Word16 w_rf[M + 1], lsf_uq_rf[M + 1]; Word16 lsf_q_1st_rf[M + 1], lsf_q_d_rf[M + 1], lsf_q_rf[M + 1]; Word16 lsp_old_q_rf[M + 1], lsf_old_q_rf[M + 1]; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) vad_hover_flag; (void) vad_flag_dtx; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); diff --git a/lib_enc/core_enc_reconf_fx.c b/lib_enc/core_enc_reconf_fx.c index 1ba496b0e..9e7380aaa 100644 --- a/lib_enc/core_enc_reconf_fx.c +++ b/lib_enc/core_enc_reconf_fx.c @@ -24,9 +24,7 @@ void core_coder_reconfig_fx( { Word16 i, bwidth, index; TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) last_total_brate; -#endif /*Configuration of ACELP*/ BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index f3b4aea6b..2f21f1015 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -408,11 +408,7 @@ void core_coder_mode_switch_ivas_fx( Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); -#ifdef FIX_920_IGF_INIT_ERROR init_coder_ace_plus_ivas_fx( st, last_total_brate, st->total_brate, MCT_flag ); -#else - init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); -#endif if ( st->hLPDmem != NULL ) { st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; diff --git a/lib_enc/core_switching_enc_fx.c b/lib_enc/core_switching_enc_fx.c index dc3062298..5290509cd 100644 --- a/lib_enc/core_switching_enc_fx.c +++ b/lib_enc/core_switching_enc_fx.c @@ -997,10 +997,8 @@ void core_switching_pre_enc_ivas_fx( tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); -#ifdef FIX_ISSUE_1230 hBWE_FD->Q_new_input_hp = 0; move16(); -#endif IF( NE_16( st_fx->last_extl, WB_BWE ) ) { diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index 3624cf374..c95bc9d5b 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -386,7 +386,6 @@ void decision_matrix_enc_fx( move16(); } -#ifdef NONBE_FIX_GSC_BSTR /*-----------------------------------------------------------------* * set inactive coder_type flag in ACELP core *-----------------------------------------------------------------*/ @@ -400,7 +399,6 @@ void decision_matrix_enc_fx( move16(); } -#endif return; } diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 154b43c12..44be8dcc6 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -29,9 +29,6 @@ #define CNG_TYPE_HO 20 /* hangover for switching between CNG types */ -#ifndef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD -#define DTX_THR 5 /* LP_NOISE level */ -#endif #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ #define MAX_BRATE_DTX_IVAS IVAS_80k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ @@ -64,9 +61,7 @@ static void update_SID_cnt_fx( DTX_ENC_HANDLE hDtxEnc, const Word32 core_brate, /*==================================================================================*/ void dtx_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ const Word16 vad, /* i : vad flag for DTX Q0*/ const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ @@ -83,21 +78,15 @@ void dtx_ivas_fx( Flag Overflow = 0; move32(); #endif -#ifdef NONBE_1211_DTX_BR_SWITCHING Word32 total_brate_ref; total_brate_ref = st_fx->total_brate; move32(); -#endif IF( st_fx->dtx_sce_sba != 0 ) { last_br_cng_flag = 1; last_br_flag = 1; -#ifndef NONBE_1211_DTX_BR_SWITCHING - br_dtx_flag = 1; - move16(); -#endif move16(); move16(); } @@ -112,15 +101,9 @@ void dtx_ivas_fx( test(); test(); -#ifdef NONBE_1211_DTX_BR_SWITCHING last_br_flag = ( st_fx->element_mode == EVS_MONO && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) ) || ( st_fx->element_mode != EVS_MONO && LE_32( last_ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); -#else - last_br_flag = LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_IVAS ) ); - br_dtx_flag = 0; - move16(); -#endif } /* Initialization */ @@ -217,10 +200,8 @@ void dtx_ivas_fx( * Select SID or FRAME_NO_DATA frame if DTX is enabled *------------------------------------------------------------------------*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING br_dtx_flag = 1; move16(); -#endif IF( st_fx->dtx_sce_sba == 0 ) { @@ -230,11 +211,7 @@ void dtx_ivas_fx( test(); br_dtx_flag = ( ( st_fx->element_mode == EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || -#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); -#else - LT_16( st_fx->lp_noise_fx, 3840 /*15 in Q8*/ ); -#endif } test(); test(); @@ -352,13 +329,11 @@ void dtx_ivas_fx( reset_indices_enc_fx( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); } } -#ifdef NONBE_1211_DTX_BR_SWITCHING ELSE IF( st_fx->element_mode != EVS_MONO ) { st_fx->total_brate = total_brate_ref; move32(); } -#endif /*------------------------------------------------------------------------* * Reset counters when in active frame (not in SID or FRAME_NO_DATA frame) diff --git a/lib_enc/enc_acelp_fx.c b/lib_enc/enc_acelp_fx.c index a509a7cd7..4317bdbb3 100644 --- a/lib_enc/enc_acelp_fx.c +++ b/lib_enc/enc_acelp_fx.c @@ -1387,7 +1387,6 @@ void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const return; } -#ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; @@ -1712,7 +1711,6 @@ void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, } return; } -#endif /* * E_ACELP_4t_fx @@ -1869,11 +1867,7 @@ void E_ACELP_4t_ivas_fx( } ELSE { -#ifdef FIX_ISSUE_1165 E_ACELP_4tsearch_ivas_fx( dn, cn, H, code, &config, ind, y ); -#else - E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); -#endif } E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index ); return; diff --git a/lib_enc/enc_acelpx_fx.c b/lib_enc/enc_acelpx_fx.c index f18da2ef2..9612696ed 100644 --- a/lib_enc/enc_acelpx_fx.c +++ b/lib_enc/enc_acelpx_fx.c @@ -781,11 +781,7 @@ void E_ACELP_4tsearchx_ivas_fx( alp = shr( alp, 1 ); Scale_sig( cor, L_SUBFR, -1 ); /*Q8*/ Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/ -#ifndef MSAN_FIX - Scale_sig( dn, 2 * L_SUBFR, -1 ); -#else Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ -#endif } diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 06c49a8d3..62f740fb2 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -656,11 +656,7 @@ void encod_gen_voic_ivas_fx( *-----------------------------------------------------------------*/ test(); -#ifdef NONBE_FIX_GSC_BSTR IF( !st_fx->inactive_coder_type_flag && EQ_16( st_fx->coder_type, INACTIVE ) ) -#else - IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && EQ_16( st_fx->coder_type, INACTIVE ) ) -#endif { transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr_fx, cn_fx, exc_fx, p_Aq_fx, p_Aw_fx, h1_fx, xn_fx, xn2_fx, y1_fx, y2_fx, Es_pred_fx, &gain_pit_fx, gain_code_fx, g_corr_fx, clip_gain_fx, &gain_preQ_fx, code_preQ_fx, unbits_fx, Q_new, shift ); diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 7e5734e70..7af329a1c 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -578,9 +578,6 @@ void enc_pit_exc_ivas_fx( Word16 use_fcb; Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ -#ifndef FIX_ISSUE_1376 - Word16 h1_q15[PIT_EXC_L_SUBFR + ( M + 1 )]; -#endif Word16 q_h1; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; @@ -602,9 +599,7 @@ void enc_pit_exc_ivas_fx( move16(); Pitch_CT = GENERIC; move16(); -#ifdef MSAN_FIX set16_fx( cn1, 0, PIT_EXC_L_SUBFR ); -#endif test(); test(); IF( st_fx->GSC_IVAS_mode > 0 && ( st_fx->GSC_noisy_speech || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) @@ -773,15 +768,8 @@ void enc_pit_exc_ivas_fx( * Codebook target computation * (No LP filtering of the adaptive excitation) *-----------------------------------------------------------------*/ -#ifndef FIX_ISSUE_1376 - Copy_Scale_sig( h1, h1_q15, L_subfr, 1 ); // Q14 -> Q15 - - lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1_q15, - xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ -#else lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1, xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ -#endif IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 5b9f67503..4cda393d5 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -478,9 +478,7 @@ Word16 encod_tran_ivas_fx( L_frame_fx = st_fx->L_frame; move16(); -#ifdef MSAN_FIX set16_fx( h1, 0, L_SUBFR + ( M + 1 ) ); -#endif /*------------------------------------------------------------------* * Initializations diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index b0c67abf5..8a77b9e2b 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -453,14 +453,10 @@ void encod_unvoiced_ivas_fx( voice_factors_fx[i_subfr / L_SUBFR] = 0; move16(); -#ifdef FIX_ISSUE_1148 if ( st_fx->hBWE_TD != NULL ) { interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); } -#else - interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); -#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/energy_fx.c b/lib_enc/energy_fx.c index 7dc96a4e3..0168e52b1 100644 --- a/lib_enc/energy_fx.c +++ b/lib_enc/energy_fx.c @@ -451,11 +451,7 @@ void background_update_fx( tmp = L_shr( 2147 /* 0.000001 Q31 */, sub( 31, scale_sb_energy ) ); /* scale_sb_energy */ FOR( i = 0; i < SNR_sb_num; i++ ) { -#ifdef FIX_ISSUE_1209 sb_bg_energy[i] = L_add_sat( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ -#else - sb_bg_energy[i] = L_add( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ -#endif move32(); } } diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index f546c3ef8..087d892e3 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -967,10 +967,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( Q_win_temp[frameno] = *q_win; move16(); -#ifdef MSAN_FIX Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len[frameno], *q_win ); // q_win -#endif IF( EQ_16( frameno, 1 ) ) { Scale_sig32( windowed_samples + 2, win_len[0], sub( *q_win, Q_win_temp[0] ) ); // q_win @@ -1384,27 +1382,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( st->igf ) { Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); -#else ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); -#endif } } } -#ifndef MSAN_FIX - IF( windowed_samples != NULL ) - { - FOR( frameno = 0; frameno < nSubframes; frameno++ ) - { - IF( !( ( EQ_16( transform_type[frameno], TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) ) - { - Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len, *q_win ); - } - } - } -#endif IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { diff --git a/lib_enc/find_tilt_fx.c b/lib_enc/find_tilt_fx.c index ea71b09bc..ed8ff425e 100644 --- a/lib_enc/find_tilt_fx.c +++ b/lib_enc/find_tilt_fx.c @@ -93,11 +93,7 @@ void find_tilt_fx( } tmp = BASOP_Util_Divide3232_Scale( lp_bckr, hp_bckr, &e_tmp ); -#ifdef FIX_ISSUE_1152 Ltmp = L_shr_r_sat( L_deposit_h( tmp ), sub( 15, e_tmp ) ); -#else - Ltmp = L_shr_r( L_deposit_h( tmp ), sub( 15, e_tmp ) ); -#endif *bckr_tilt_lt = L_add( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Mpy_32_16_r( Ltmp, 3277 ) ); /* Q16 */ diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index f943b104d..edddc6a88 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -979,13 +979,8 @@ void gauss2v_ivas_fx( /* eneri = round_fx(ener[i]) + round_fx(ener[j]) + 2*round_fx(dotprod) */ /* Use ScalingShift to stay aligned with ener[] */ eneri = L_shl( dotprod, 1 ); /* One left shift added for factor of 2 */ -#ifndef FIX_1298 - eneri = L_add( ener[i], eneri ); - eneri = L_add( ener[j], eneri ); /* Q31 */ -#else eneri = L_add_sat( ener[i], eneri ); eneri = L_add_sat( ener[j], eneri ); /* Q31 */ -#endif lo1 = L_Extract_lc( cor32, &hi1 ); cor2 = Sad_32( 0, hi1, lo1 ); /* Square + Add */ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 944cb2649..2b53082f7 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -83,7 +83,6 @@ static Word16 hf_spectrum_sparseness_fx( crest_mod_fx = 0; move32(); maximum_l( A_fx, L_SPEC_HB, &Amax_fx ); -#ifdef NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO IF( Amax_fx == 0 ) { /* For all-zero input the crest is 1.0 */ @@ -94,7 +93,6 @@ static Word16 hf_spectrum_sparseness_fx( } ELSE { -#endif thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */ movmean_fx = 0; /* avoid uninitialized warning */ move32(); @@ -160,9 +158,7 @@ static Word16 hf_spectrum_sparseness_fx( move32(); st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e ); move16(); -#ifdef NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO } -#endif *crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_lp_fx ) ), Mpy_32_32( ONE_IN_Q31 - HQ_CREST_FAC_SM_FX, crest_fx ) ); /* Q(st->hHQ_core->crest_lp_q) */ move32(); *crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_mod_lp_fx ) ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), crest_mod_fx ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */ diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index f22218d13..6bc466e3d 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -374,7 +374,6 @@ void HQ_core_enc_init_fx( hHQ_core->last_max_pos_pulse = 0; move16(); -#ifdef MSAN_FIX hHQ_core->crest_lp_fx = HQ_CREST_THRESHOLD_FX; /* Q28 */ move32(); hHQ_core->crest_lp_q = Q28; @@ -383,7 +382,6 @@ void HQ_core_enc_init_fx( move32(); hHQ_core->crest_mod_lp_q = Q29; move16(); -#endif return; } @@ -482,11 +480,7 @@ void hq_core_enc_ivas_fx( Q_audio = sub( Q16, q ); TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); Q_audio = sub( Q31, Q_audio ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ -#else - Copy_Scale_sig_16_32_DEPREC( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ -#endif inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ is_transient = 0; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index fc7c32fdb..d5f071784 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -716,13 +716,8 @@ static void IGF_CalculateEnvelope_ivas_fx( Word32 mean_y_fx_tmp = 0; move32(); mean_xy_fx = mean_x2_fx = 0; -#ifdef FIX_ISSUE_1214 mean_x_e = 15; mean_xy_e = mean_y_e = mean_x2_e = 31; -#else - mean_x_e = mean_y_e = 15; - mean_xy_e = mean_x2_e = 31; -#endif move16(); move16(); move16(); @@ -738,21 +733,12 @@ static void IGF_CalculateEnvelope_ivas_fx( mean_x_fx = add( mean_x_fx, x ); /*Q0*/ mean_x2_fx = L_add( mean_x2_fx, L_mult0( x, x ) ); /*Q0*/ -#ifdef FIX_ISSUE_1214 /*y = 20.f * log10f( max( 1.f, powerSpectrum[i] ) );*/ IF( LE_64( W_deposit32_l( pPowerSpectrum_fx[sb] ), W_shl( 1, ( sub( 31, e_ps[sb] ) ) ) ) ) { y = 0; move16(); } -#else - - /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ - IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) - { - y = imult1616( 20, ( -18 /* log10f(1e-018f) */ ) ); - } -#endif ELSE { y = imult1616( 20, extract_l( L_shr( Mult_32_16( ( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps[sb], Q25 ) ) ), INV_Log2_10_Q15 ), Q25 ) ) ); /*Q0*/ @@ -1258,21 +1244,12 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); } } -#ifdef FIX_ISSUE_1214 tmp_tb_fx = shr_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ tmp_sb_fx = shr_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ -#else - tmp_tb_fx = shl_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - tmp_sb_fx = shl_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, tmp_tb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, tmp_tb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ - hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, tmp_sb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, tmp_sb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ -#endif move16(); move16(); move16(); @@ -2541,9 +2518,7 @@ void IGFEncResetTCX10BitCounter_ivas_fx( void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ -#endif const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ @@ -2563,9 +2538,7 @@ void IGFEncApplyMono_ivas_fx( Word32 common_pPowerSpectrum_fx[N_MAX + L_MDCT_OVLP_MAX]; -#ifdef MSAN_FIX set32_fx( common_pPowerSpectrum_fx, 0, N_MAX + L_MDCT_OVLP_MAX ); -#endif Word16 common_pPowerSpectrum_exp = MIN16B; move16(); @@ -2624,20 +2597,12 @@ void IGFEncApplyMono_ivas_fx( IF( pPowerSpectrumParameter_fx ) { -#ifndef MSAN_FIX - FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) -#else FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) -#endif { common_pPowerSpectrum_exp = s_max( common_pPowerSpectrum_exp, pPowerSpectrumParameter_exp[i] ); } -#ifndef MSAN_FIX - FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) -#else FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) -#endif { common_pPowerSpectrum_fx[i] = L_shl( pPowerSpectrumParameter_fx[i], sub( pPowerSpectrumParameter_exp[i], common_pPowerSpectrum_exp ) ); move16(); diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index ebfd9c4a2..1d695659c 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1398,11 +1398,7 @@ ivas_error init_encoder_ivas_fx( st->exp_buf_wspeech_enc = 0; move16(); /* initializations */ -#ifndef MSAN_FIX - set32_fx( st->Bin_E_old_fx, 0, shr( L_FFT, 2 ) ); -#else set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); -#endif st->q_Bin_E_old = Q31; move16(); set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); @@ -1821,10 +1817,8 @@ ivas_error init_encoder_ivas_fx( } fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX st->Q_old_wtda = 0; move16(); -#endif } ELSE { @@ -2069,7 +2063,6 @@ ivas_error init_encoder_ivas_fx( set16_fx( st->totalNoise_increase_hist_fx, 0, TOTALNOISE_HIST_SIZE ); st->totalNoise_increase_len = 0; move16(); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; IF( hTcxEnc != NULL ) { @@ -2080,10 +2073,8 @@ ivas_error init_encoder_ivas_fx( move32(); st->currEnergyHF_e_fx = 0; move16(); -#ifdef MSAN_FIX st->prevEnergyHF_fx = 0; move32(); -#endif /* Initialize TCX */ @@ -2097,12 +2088,7 @@ ivas_error init_encoder_ivas_fx( st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); /* Initialize ACELP */ -#endif -#ifdef FIX_920_IGF_INIT_ERROR init_coder_ace_plus_ivas_fx( st, st->last_total_brate, igf_brate, 0 ); -#else - init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); -#endif IF( st->hLPDmem != NULL ) { diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 46bec5f4d..e47b14559 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -89,9 +89,7 @@ Word16 inov_encode_fx( Word16 Rw[L_SUBFR]; Word16 acelpautoc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) last_L_frame; -#endif stack_pulses = 0; move16(); diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index cacbcabd3..1e7a13d45 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -118,14 +118,12 @@ ivas_error ivas_core_enc_fx( set32_fx( new_swb_speech_buffer_fx, 0, L_FRAME48k + STEREO_DFT_OVL_MAX ); set16_fx( new_swb_speech_buffer_fx_16, 0, L_FRAME48k + STEREO_DFT_OVL_MAX ); -#ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) { set_zero_fx( bwe_exc_extended_fx[i], L_FRAME32k + NL_BUFF_OFFSET ); set16_fx( old_syn_12k8_16k_fx[i], 0, L_FRAME16k ); } set16_fx( shb_speech_fx, 0, L_FRAME16k ); -#endif push_wmops( "ivas_core_enc" ); @@ -215,7 +213,6 @@ ivas_error ivas_core_enc_fx( /*---------------------------------------------------------------------* * Pre-processing, incl. Decision matrix *---------------------------------------------------------------------*/ -#ifdef MSAN_FIX IF( st->cldfbAnaEnc ) { Word16 tmp_shift = L_norm_arr( enerBuffer_fx[n], st->cldfbAnaEnc->no_channels ); @@ -227,16 +224,6 @@ ivas_error ivas_core_enc_fx( move16(); } } -#else - Word16 tmp_shift = getScaleFactor32( enerBuffer_fx[n], CLDFB_NO_CHANNELS_MAX ); - tmp_shift = sub( tmp_shift, 5 ); - IF( tmp_shift < 0 ) - { - scale_sig32( enerBuffer_fx[n], CLDFB_NO_CHANNELS_MAX, tmp_shift ); - enerBuffer_fx_exp[n] = sub( enerBuffer_fx_exp[n], tmp_shift ); - move16(); - } -#endif Scale_sig( fft_buff_fx[n], ( 2 * L_FFT ), -1 ); // To create 1 headroom for addition of magnitude square spectrum // fft_buff_fx_exp = add(fft_buff_fx_exp,1); diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 45098926e..bf7c36eef 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -131,9 +131,7 @@ ivas_error pre_proc_front_ivas_fx( const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO @@ -212,10 +210,6 @@ ivas_error pre_proc_front_ivas_fx( Word16 new_inp_out_size; Word16 Q_new_inp; Word16 mem_decim_size; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - Word16 Q_new; - Word16 corr_shift_fx; -#endif Word16 dummy_fx; Word16 ncharX_fx; @@ -259,13 +253,8 @@ ivas_error pre_proc_front_ivas_fx( IF( hSCE != NULL ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#endif hSCE->hCoreCoder[n]->q_inp32 = Q11; move16(); Scale_sig( hSCE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ @@ -282,13 +271,8 @@ ivas_error pre_proc_front_ivas_fx( } ELSE { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ -#endif hCPE->hCoreCoder[n]->q_inp32 = Q11; move16(); Scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ @@ -316,13 +300,11 @@ ivas_error pre_proc_front_ivas_fx( } #endif -#ifdef MSAN_FIX FOR( Word16 k = 0; k < CLDFB_NO_COL_MAX; k++ ) { set32_fx( realBuffer_fx[k], 0, CLDFB_NO_CHANNELS_MAX ); set32_fx( imagBuffer_fx[k], 0, CLDFB_NO_CHANNELS_MAX ); } -#endif Word16 sf_energySum[CLDFB_NO_CHANNELS_MAX]; Word16 Q_to_be_looked_into = -1; @@ -365,9 +347,6 @@ ivas_error pre_proc_front_ivas_fx( IF( hSCE != NULL ) { st = hSCE->hCoreCoder[n]; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - signal_in = hSCE->hCoreCoder[n]->input; -#endif signal_in_fx = hSCE->hCoreCoder[n]->input_fx; /* hSCE->hCoreCoder[n]->q_inp */ signal32_in_fx = hSCE->hCoreCoder[n]->input32_fx; /* hSCE->hCoreCoder[n]->q_inp32 */ element_mode = IVAS_SCE; @@ -381,9 +360,6 @@ ivas_error pre_proc_front_ivas_fx( ELSE /* CPE */ { st = hCPE->hCoreCoder[n]; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - signal_in = hCPE->hCoreCoder[n]->input; -#endif signal_in_fx = hCPE->hCoreCoder[n]->input_fx; /* hSCE->hCoreCoder[n]->q_inp */ signal32_in_fx = hCPE->hCoreCoder[n]->input32_fx; /* hSCE->hCoreCoder[n]->q_inp32 */ element_mode = hCPE->element_mode; @@ -1092,11 +1068,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } -#ifdef NONBE_1211_DTX_BR_SWITCHING dtx_ivas_fx( st, last_ivas_total_brate, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, *Q_new ); -#else - dtx_ivas_fx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, *Q_new ); -#endif test(); test(); @@ -1464,11 +1436,7 @@ ivas_error pre_proc_front_ivas_fx( st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, Etot_fx, hp_E_fx, &flag_spitch, last_core_orig, hStereoClassif, *Q_new /*q_inp_12k8*/, fr_bands_fx_q ); // Q0 -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); -#else - Copy_Scale_sig_16_32_DEPREC( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); -#endif #ifdef DEBUG_FORCE_DIR if ( st->force_dir[0] != '\0' ) diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 8d00e608c..ca53a227a 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -282,11 +282,7 @@ ivas_error pre_proc_ivas_fx( } ELSE IF( GT_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( ( st->vad_flag == 0 && GE_16( st->bwidth, SWB ) && GE_16( st->max_bwidth, SWB ) ) || ( st->localVAD == 0 && ( LE_16( st->bwidth, WB ) || LE_16( st->max_bwidth, WB ) ) ) ) ) { -#ifdef NONBE_FIX_GSC_BSTR /* inactive frames will be coded by AVQ technology (exceptionally it can be later rewritten to GSC technology in ivas_combined_format_brate_sanity()) */ -#else - /* inactive frames will be coded by AVQ technology */ -#endif st->coder_type = INACTIVE; move16(); } @@ -734,9 +730,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 *preemp_start_idx = NULL; Word32 sig_out[960], max_32; /*Word16 Q_exp, Q_wsp_exp*/; -#ifdef MSAN_FIX set16_fx( new_inp_resamp16k_fx, 0, L_FRAME16k ); -#endif set16_fx( epsP_h, 0, M + 1 ); set16_fx( epsP_l, 0, M + 1 ); signal_in_fx = st->input_fx; /* st->q_inp */ diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index ea70a33d3..6108b138c 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -78,9 +78,7 @@ ivas_error ivas_cpe_enc_fx( Word16 Q_new[CPE_CHANNELS] = { 0 }; Word16 fft_buff_fx[CPE_CHANNELS][2 * L_FFT]; /* FFT buffer */ Word16 fft_buff_fx_q[CPE_CHANNELS]; /* FFT buffer */ -#ifdef MSAN_FIX set16_fx( fft_buff_fx_q, 0, CPE_CHANNELS ); -#endif Word16 fft_buff_fx_final_q = MAX_16; move16(); Word32 ener_fx[CPE_CHANNELS]; /* residual energy from Levinson-Durbin Q6 */ @@ -176,7 +174,6 @@ ivas_error ivas_cpe_enc_fx( set16_fx( voicing_fr_fx[0], 0, NB_SUBFR ); set16_fx( voicing_fr_fx[1], 0, NB_SUBFR ); -#ifdef MSAN_FIX FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { set16_zero_fx( fft_buff_fx[i], 2 * L_FFT ); @@ -185,7 +182,6 @@ ivas_error ivas_cpe_enc_fx( set16_zero_fx( old_inp_12k8_16fx[i], L_INP_12k8 ); set_zero_fx( old_inp_12k8_fx[i], L_INP_12k8 ); } -#endif /*------------------------------------------------------------------* * CPE initialization - core coder *-----------------------------------------------------------------*/ @@ -288,9 +284,7 @@ ivas_error ivas_cpe_enc_fx( move16(); Word16 front_create_flag = 0; move16(); -#ifdef MSAN_FIX set32_fx( band_energies_LR_fx, 0, 2 * NB_BANDS ); -#endif IF( hCPE->hFrontVad[0] != NULL && NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { @@ -375,13 +369,8 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Set TD stereo parameters *----------------------------------------------------------------*/ -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_DEPREC( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ -#endif Word16 shift = getScaleFactor32( sts[1]->input32_fx, input_frame ); scale_sig32( sts[1]->input32_fx, input_frame, shift ); /* Q11 + shift */ sts[1]->q_inp32 = add( Q11, shift ); @@ -408,7 +397,6 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ -#ifdef FIX_ISSUE_1247 shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); @@ -426,25 +414,6 @@ ivas_error ivas_cpe_enc_fx( Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); -#else - shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ - sts[1]->q_inp = add( sts[1]->q_inp, shift ); - move16(); - - shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ - sts[0]->q_inp = add( sts[0]->q_inp, shift ); - move16(); -#endif Word16 q_inp = s_min( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), s_min( sts[1]->q_inp, sts[1]->q_old_inp ) ); @@ -682,9 +651,6 @@ ivas_error ivas_cpe_enc_fx( // printf("\n%f %f ", hCPE->hStereoClassif->is_speech, hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0]); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { -#ifndef MSAN_FIX - hCPE->hStereoClassif->xtalk_score_fx = floatToFixed( hCPE->hStereoClassif->xtalk_score, 31 ); -#endif // !MSAN_FIX /*flt2fix: dft_synthesize*/ test(); if ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) @@ -866,7 +832,6 @@ ivas_error ivas_cpe_enc_fx( move16(); stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, sts[0]->input32_fx, &out_start_ind, &out_end_ind, 0, input_Fs, input_Fs, 0, NULL ); -#ifdef FIX_ISSUE_1135 // Normalise the input buffer from Q15 Word16 input_norm, q_inp32, common_q, fir_delay_len; input_norm = L_norm_arr( sts[0]->input32_fx + out_start_ind, sub( out_end_ind, out_start_ind ) ); @@ -887,9 +852,6 @@ ivas_error ivas_cpe_enc_fx( move16(); sts[0]->q_old_inp = common_q; move16(); -#else - Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, sts[0]->q_inp ), Q15 ) ); // Q15 -#endif /* iDFT & resampling to 12.8kHz internal sampling rate */ stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_inp_12k8_fx[0] + L_INP_MEM, &out_12k8_start_ind[0], &out_12k8_end_ind[0], 0, input_Fs, INT_FS_12k8, 0, NULL ); @@ -956,11 +918,7 @@ ivas_error ivas_cpe_enc_fx( &ener_fx[n], &relE_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], &vad_hover_flag[n], &attack_flag[n], realBuffer_fx[n], imagBuffer_fx[n], &q_re_im_buf[n], old_wsp_fx[n], &q_old_wsp, pitch_fr_fx[n], voicing_fr_fx[n], &loc_harm[n], &cor_map_sum_fx[n], &vad_flag_dtx[n], enerBuffer_fx[n], &enerBuffer_fx_exp[n], fft_buff_fx[n], &fft_buff_fx_q[n], A_fx[0], lsp_new_fx[0], currFlatness_fx[n], tdm_ratio_idx, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, q_lf_E[n], localVAD_HE_SAD, -#ifdef NONBE_1211_DTX_BR_SWITCHING band_energies_LR_fx, q_band_energies_LR, 0, front_vad_flag, 0, 0, ivas_format, st_ivas->hMCT != NULL, st_ivas->hEncoderConfig->last_ivas_total_brate, ivas_total_brate, &Q_new[n] -#else - band_energies_LR_fx, q_band_energies_LR, 0, front_vad_flag, 0, 0, ivas_format, st_ivas->hMCT != NULL, ivas_total_brate, &Q_new[n] -#endif #ifdef DEBUG_MODE_INFO , ( st_ivas->nSCE + ( cpe_id * CPE_CHANNELS ) + n ) @@ -1418,9 +1376,7 @@ ivas_error create_cpe_enc_fx( hCPE->input_mem_fx[n] = NULL; } } -#ifdef MSAN_FIX set16_fx( hCPE->q_input_mem, Q15, CPE_CHANNELS ); -#endif /*-----------------------------------------------------------------* * stereo classifier: allocate and initialize diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index db5ee872b..59447c022 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -52,11 +52,9 @@ static void computeIntensityVector_enc_fx( const Word16 enc_param_start_band, /* i : first band to process */ const Word16 num_frequency_bands, Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 q_cldfb, Word16 q_intensity_real[DIRAC_MAX_NBANDS] -#endif ); /*------------------------------------------------------------------------- @@ -761,7 +759,6 @@ void computeReferencePower_enc_fx_dirac( *dirac_mono_flag = ivas_dirac_get_mono_flag_fx( band_grouping, Cldfb_RealBuffer, Cldfb_ImagBuffer, e_Cldfb, nchan_ana, mono_frame_count ); /* Q0 */ move16(); } -#ifdef FIX_1127_IMPROVE_SBA_MLD Word16 gb = 0; move16(); FOR( i = 0; i < num_freq_bands; i++ ) @@ -774,7 +771,6 @@ void computeReferencePower_enc_fx_dirac( } e_reference_W = sub( 31, sub( add( shl( sub( 31, e_Cldfb ), 1 ), 1 ), gb ) ); e_reference_temp = e_reference_W; -#endif move16(); FOR( i = 0; i < num_freq_bands; i++ ) { @@ -791,14 +787,8 @@ void computeReferencePower_enc_fx_dirac( FOR( j = brange[0]; j < brange[1]; j++ ) { -#ifdef FIX_1127_IMPROVE_SBA_MLD reference_power_W[i] = W_add( reference_power_W[i], W_shr( W_mult_32_32( Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ), gb ) ); /* exp(2 * e_Cldfb) */ reference_power_W[i] = W_add( reference_power_W[i], W_shr( W_mult_32_32( Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ), gb ) ); /* exp(2 * e_Cldfb) */ -#else - reference_power_W[i] = W_mac_32_32( reference_power_W[i], Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ); - reference_power_W[i] = W_mac_32_32( reference_power_W[i], Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ); - e_reference_W = imult1616( (Word16) 2, e_Cldfb ); -#endif move64(); move64(); } @@ -810,14 +800,8 @@ void computeReferencePower_enc_fx_dirac( /* abs()^2 */ FOR( j = brange[0]; j < brange[1]; j++ ) { -#ifdef FIX_1127_IMPROVE_SBA_MLD reference_power_temp[i] = W_add( reference_power_temp[i], W_shr( W_mult_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), gb ) ); /* exp(2 * e_Cldfb) */ reference_power_temp[i] = W_add( reference_power_temp[i], W_shr( W_mult_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ), gb ) ); /* exp(2 * e_Cldfb) */ -#else - reference_power_temp[i] = W_mac_32_32( reference_power_temp[i], Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ); - reference_power_temp[i] = W_mac_32_32( reference_power_temp[i], Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ); - e_reference_temp = imult1616( (Word16) 2, e_Cldfb ); -#endif move64(); move64(); } @@ -974,11 +958,7 @@ void ivas_dirac_param_est_enc_fx( Word32 *p_Cldfb_ImagBuffer_fx[DIRAC_MAX_ANA_CHANS]; Word16 cldfb_q; Word32 intensity_real_fx[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word16 intensity_real_q[DIRAC_MAX_NBANDS]; -#else - Word16 intensity_real_q; -#endif Word32 direction_vector_fx[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; Word16 direction_vector_q; Word32 diffuseness_vector_fx[DIRAC_MAX_NBANDS]; @@ -1008,10 +988,6 @@ void ivas_dirac_param_est_enc_fx( cldfb_q = 0; move16(); -#ifndef NONBE_IMPROVE_DIRAC_INTENSITY_PREC - intensity_real_q = 0; - move16(); -#endif direction_vector_q = 0; move16(); @@ -1148,15 +1124,10 @@ void ivas_dirac_param_est_enc_fx( hDirAC->hConfig->enc_param_start_band, num_freq_bands, intensity_real_fx -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , cldfb_q, intensity_real_q -#endif ); -#ifndef NONBE_IMPROVE_DIRAC_INTENSITY_PREC - intensity_real_q = sub( shl( cldfb_q, 1 ), 31 ); // 2 * Q_Cldfb + 1 - 32; -#endif IF( !hodirac_flag ) { computeDirectionVectors_fixed( @@ -1168,13 +1139,8 @@ void ivas_dirac_param_est_enc_fx( direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2] -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , 31, intensity_real_q -#else - , - sub( 31, intensity_real_q ) -#endif ); direction_vector_q = Q30; @@ -1190,11 +1156,7 @@ void ivas_dirac_param_est_enc_fx( { /* only real part needed */ Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); /* intensity_real_q */ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Copy( intensity_real_q, &hDirAC->buffer_intensity_real_q[i][index - 1][0], num_freq_bands ); -#else - set16_fx( &hDirAC->buffer_intensity_real_q[i][index - 1][0], intensity_real_q, num_freq_bands ); -#endif } Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); /* exp(reference_power_exp) */ FOR( i = 0; i < num_freq_bands; i++ ) @@ -1406,12 +1368,7 @@ void ivas_dirac_param_est_enc_fx( Scale_sig32( dir_v_fx, 3, -1 ); ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Q29, -#else - - Q30, -#endif &q_direction->band_data[band_m_idx].azimuth_fx[block_m_idx], &q_direction->band_data[band_m_idx].elevation_fx[block_m_idx] ); } @@ -1506,11 +1463,9 @@ static void computeIntensityVector_enc_fx( const Word16 enc_param_start_band, /* i : first band to process Q0*/ const Word16 num_frequency_bands, /* Q0 */ Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] /* q_intensity_real */ -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , Word16 q_cldfb, Word16 q_intensity_real[DIRAC_MAX_NBANDS] -#endif ) { /* Reminder @@ -1520,20 +1475,16 @@ static void computeIntensityVector_enc_fx( Word16 i, j; Word32 real, img; Word16 brange[2]; -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word16 shift_value = sub( shl( q_cldfb, 1 ), 31 ); -#endif FOR( i = 0; i < num_frequency_bands; i++ ) { brange[0] = hDirAC->band_grouping[i + enc_param_start_band]; /* Q0 */ move16(); brange[1] = hDirAC->band_grouping[i + enc_param_start_band + 1]; /* Q0 */ move16(); -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word16 num_bins = sub( brange[1], brange[0] ); Word16 gb = find_guarded_bits_fx( num_bins ); Word16 norm; -#endif intensity_real[0][i] = 0; move32(); intensity_real[1][i] = 0; @@ -1552,7 +1503,6 @@ static void computeIntensityVector_enc_fx( move32(); img = Cldfb_ImagBuffer[0][j]; move32(); -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC Word64 t1, t2, t3; t1 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), Cldfb_ImagBuffer[3][j], img ); /* 2 * q_cldfb + 1 */ t2 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), Cldfb_ImagBuffer[1][j], img ); /* 2 * q_cldfb + 1 */ @@ -1564,14 +1514,7 @@ static void computeIntensityVector_enc_fx( tmp_1 = W_add( tmp_1, t1 ); /* 2 * q_cldfb + 1 */ tmp_2 = W_add( tmp_2, t2 ); /* 2 * q_cldfb + 1 */ tmp_3 = W_add( tmp_3, t3 ); /* 2 * q_cldfb + 1 */ -#else - /* Intensity is XYZ order, audio is WYZX order. */ - tmp_1 = W_add( tmp_1, W_add( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), W_mult_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); - tmp_2 = W_add( tmp_2, W_add( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), W_mult_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); - tmp_3 = W_add( tmp_3, W_add( W_mult_32_32( Cldfb_RealBuffer[2][j], real ), W_mult_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); -#endif } -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC norm = 63; move16(); IF( tmp_1 != 0 ) @@ -1593,15 +1536,6 @@ static void computeIntensityVector_enc_fx( intensity_real[2][i] = W_extract_h( W_shl( tmp_3, norm ) ); // shift_value - (gb - norm) q_intensity_real[i] = sub( shift_value, sub( gb, norm ) ); move16(); -#else - - intensity_real[0][i] = W_extract_h( tmp_1 ); // output Q= 2* input_q + 1 - 32 - move32(); - intensity_real[1][i] = W_extract_h( tmp_2 ); // output Q= 2* input_q + 1 - 32 - move32(); - intensity_real[2][i] = W_extract_h( tmp_3 ); // output Q= 2* input_q + 1 - 32 - move32(); -#endif } return; diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index b37e61829..a53e40ee6 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -621,11 +621,7 @@ ivas_error front_vad_spar_fx( corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ -#ifdef NONBE_1211_DTX_BR_SWITCHING dtx_ivas_fx( st, hEncoderConfig->last_ivas_total_brate, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); -#else - dtx_ivas_fx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); -#endif /* linear prediction analysis */ alw_pitch_lag_12k8[0] = st->old_pitch_la; /* Q0 */ diff --git a/lib_enc/ivas_ism_dtx_enc_fx.c b/lib_enc/ivas_ism_dtx_enc_fx.c index 6aba283be..b06acfbac 100644 --- a/lib_enc/ivas_ism_dtx_enc_fx.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -174,11 +174,7 @@ Word16 ivas_ism_dtx_enc_fx( ( EQ_16( nchan_ism, 2 ) && LE_32( ivas_total_brate, IVAS_48k ) ) || ( EQ_16( nchan_ism, 3 ) && LE_32( ivas_total_brate, IVAS_80k ) ) || ( EQ_16( nchan_ism, 4 ) && LE_32( ivas_total_brate, IVAS_96k ) ) || -#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD LT_16( lp_noise_max_fx, ( DTX_THR << 8 ) ) ) ) -#else - LT_16( lp_noise_max_fx, ( 15 << 8 ) ) ) ) -#endif { dtx_flag = 0; move16(); diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index c2f77c159..7f9962098 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -116,12 +116,10 @@ ivas_error ivas_ism_enc_fx( error = IVAS_ERR_OK; move32(); -#ifdef MSAN_FIX FOR( i = 0; i < MAX_NUM_OBJECTS; i++ ) { set16_zero_fx( old_inp_12k8_fx[i][0], L_INP_12k8 ); } -#endif set16_fx( q_re_im_buf, 0, MAX_NUM_OBJECTS ); @@ -247,11 +245,7 @@ ivas_error ivas_ism_enc_fx( error = pre_proc_front_ivas_fx( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8_fx[sce_id][0], old_inp_16k_fx[sce_id][0], &ener_fx[sce_id][0], &relE_fx[sce_id][0], A_fx[sce_id][0], Aw_fx[sce_id][0], epsP_fx[sce_id][0], &epsP_fx_q[sce_id][0], lsp_new_fx[sce_id][0], lsp_mid_fx[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer_fx[sce_id][0], imagBuffer_fx[sce_id][0], &q_re_im_buf[sce_id], old_wsp_fx[sce_id][0], &q_old_wsp, pitch_fr_fx[sce_id][0], voicing_fr_fx[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum_fx[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer_fx[sce_id][0], &enerBuffer_fx_exp[sce_id][0], -#ifdef NONBE_1211_DTX_BR_SWITCHING fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] -#else - fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] -#endif #ifdef DEBUG_MODE_INFO , st->id_element @@ -286,11 +280,7 @@ ivas_error ivas_ism_enc_fx( test(); IF( st_ivas->hSCE[j] && st_ivas->hSCE[j]->hCoreCoder[0] ) { -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ -#else - Copy_Scale_sig_16_32_DEPREC( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ -#endif st_ivas->hSCE[j]->hCoreCoder[0]->q_inp32 = Q11; move16(); } diff --git a/lib_enc/ivas_ism_metadata_enc_fx.c b/lib_enc/ivas_ism_metadata_enc_fx.c index 8e6e0c93f..1efbb2123 100644 --- a/lib_enc/ivas_ism_metadata_enc_fx.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -314,10 +314,8 @@ ivas_error ivas_ism_metadata_enc_fx( } ELSE IF( EQ_16( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ) ) { -#ifdef NONBE_1273_ISM_METADATA_COUNTER hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; move16(); -#endif lowrate_metadata_flag[ch] = 1; move16(); hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; @@ -650,10 +648,8 @@ ivas_error ivas_ism_metadata_enc_fx( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); -#ifdef NONBE_1273_ISM_METADATA_COUNTER hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); move16(); -#endif } ELSE { @@ -821,10 +817,8 @@ ivas_error ivas_ism_metadata_enc_fx( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); -#ifdef NONBE_1273_ISM_METADATA_COUNTER hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); move16(); -#endif } ELSE { diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index da1f836df..080a62a9d 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -987,11 +987,7 @@ ivas_error ivas_masa_enc_config_fx( /* Setup importance weights for two-direction band selection. */ IF( EQ_16( hMasa->config.numberOfDirections, 2 ) ) { -#ifdef MSAN_FIX set32_fx( hMasa->data.importanceWeight_fx, ONE_IN_Q30 /*1.0f Q30*/, MASA_FREQUENCY_BANDS ); -#else - set32_fx( hMasa->data.importanceWeight_fx, ONE_IN_Q30 /*1.0f Q30*/, hMasa->config.numCodingBands ); -#endif IF( EQ_16( hMasa->config.numCodingBands, 5 ) ) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 17fefec7e..039bbdf98 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1010,11 +1010,7 @@ static void ivas_param_mc_param_est_enc_fx( Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e ); } L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); -#ifdef FIX_ISSUE_1154 L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( L_tmp, EPSILLON_FX ), &tmp_e ) ); -#else - L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_tmp, &tmp_e ) ); -#endif tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); @@ -1392,11 +1388,7 @@ static void ivas_param_mc_quantize_ilds_fx( ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_fx[ref_channel_idx][ref_channel_idx], Cx_e[ref_channel_idx][ref_channel_idx], &ref_ener_e ); } ref_ener_fx = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); -#ifdef FIX_ISSUE_1154 L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( ref_ener_fx, EPSILLON_FX ), &tmp_e ) ); -#else - L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], ref_ener_fx, &tmp_e ) ); -#endif tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); /*10 in Q21 = 1342177280*/ ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q21 diff --git a/lib_enc/ivas_mc_paramupmix_enc_fx.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c index fd5cb6217..cad29b146 100644 --- a/lib_enc/ivas_mc_paramupmix_enc_fx.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -1040,12 +1040,6 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( IF( LT_16( maxbands, IVAS_MAX_NUM_BANDS ) ) { -#ifndef FIX_1133_IMPROVE_MC_MLD - *exp_alphas = 0; - move16(); - *exp_betas = 0; - move16(); -#endif FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) { FOR( bnd = maxbands; bnd < IVAS_MAX_NUM_BANDS; bnd++ ) diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index 22f21dceb..0071b67ea 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -940,13 +940,11 @@ void ivas_mcmasa_param_est_enc_fx( Word16 surroundingCoherence_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; Word16 numAnalysisChannels; -#ifdef MSAN_FIX FOR( i = 0; i < MCMASA_MAX_ANA_CHANS; i++ ) { set_zero_fx( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ); set_zero_fx( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ); } -#endif num_freq_bins = idiv1616( input_frame, MDFT_NO_COL_MAX ); num_freq_bands = hMcMasa->nbands; @@ -1181,10 +1179,8 @@ void ivas_mcmasa_param_est_enc_fx( direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], c_e -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , NULL -#endif ); /* Power and intensity estimation for diffuseness */ diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 71515571d..548a56717 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -270,7 +270,6 @@ void ivas_mct_core_enc_fx( nCPE = add( nCPE, 1 ); } -#ifdef MSAN_FIX FOR( ch = 0; ch < MCT_MAX_CHANNELS; ch++ ) { set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k ); @@ -278,7 +277,6 @@ void ivas_mct_core_enc_fx( move16(); set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX ); } -#endif // MSAN_FIX FOR( ch = 0; ch < nChannels; ch++ ) { set32_fx( inv_spectrum_long_fx[ch], 0, L_FRAME48k ); @@ -334,7 +332,6 @@ void ivas_mct_core_enc_fx( IF( switch_bw ) { -#ifdef FIX_USAN_ISSUES IF( sts[ch_core]->hIGFEnc == NULL ) { initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, @@ -345,10 +342,6 @@ void ivas_mct_core_enc_fx( initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); } -#else - initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, - sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); -#endif } IF( sts[ch_core]->igf ) @@ -653,11 +646,7 @@ void ivas_mct_core_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#else ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif st->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index a8ba9a320..78bf976d1 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -1116,11 +1116,7 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[p_ch[ch]], sub( Q31, q_powerSpec[p_ch[ch]] ), N_MAX + L_MDCT_OVLP_MAX ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#else ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); @@ -1161,11 +1157,7 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powerSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#else ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); -#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 9f674473e..4b5b3fcbe 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -429,17 +429,9 @@ static void kernel_switch_update_transforms_fx( Word32 factor; n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); -#ifdef MSAN_FIX Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 -#else - Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), -Q1 ); // Q0 -> Q-1 -#endif wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 -#ifdef MSAN_FIX Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 -#else - Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), Q1 ); // Q-1 -> Q0 -#endif Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); @@ -545,11 +537,7 @@ static void kernel_switch_update_transforms_fx( Copy_Scale_sig_32_16( windowedTimeSignal + 2, windowedTimeSignal_16 + 2, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), -Q16 ); // *q_windowedTimeSignal - Q16 WindowSignal( hTcxCfg, shr( leftOverlap, 1 ), RECTANGULAR_OVERLAP, MIN_OVERLAP, &leftOverlap, &rightOverlap, windowedTimeSignal_16 + 2, &s, tcx5Win, 0, 1 ); // *q_windowedTimeSignal - Q16 Copy_Scale_sig_16_32_no_sat( tcx5Win, tcx5Win_32, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), Q16 ); // *q_windowedTimeSignal -#ifdef FIX_ISSUE_1157 q_shift = -Q8; -#else - q_shift = -Q7; -#endif move16(); scale_sig32( tcx5Win_32, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift kernel_switch_trafo_fx( tcx5Win_32, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift @@ -579,11 +567,7 @@ static void kernel_switch_update_transforms_fx( ELSE /* tcxTransType != TCX_5 */ { Word16 q_shift, q_com, q_temp; -#ifdef FIX_ISSUE_1157 q_shift = -Q8; -#else - q_shift = -Q7; -#endif move16(); scale_sig32( windowedTimeSignal + 2, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift kernel_switch_trafo_fx( windowedTimeSignal + 2, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift @@ -912,13 +896,8 @@ static UWord16 enc_ste_pre_mdct( absMagnR_fx = Sqrt32( L_add( Mpy_32_32( sigR1_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI1_fx[s], sigI1_fx[s] ) ), &absMagnR_e ); corr_fx = L_add( corr_fx, L_add( Mpy_32_32( sigR0_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI0_fx[s], sigI1_fx[s] ) ) ); // q_com*2 - 31 -#ifdef FIX_ISSUE_1092 sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 -#else - sumL_fx = L_add( sumL_fx, L_add( sigR0_fx[s], sigI0_fx[s] ) ); // q_com - sumR_fx = L_add( sumR_fx, L_add( sigR1_fx[s], sigI1_fx[s] ) ); // q_com -#endif sumMagnL_fx = BASOP_Util_Add_Mant32Exp( sumMagnL_fx, sumMagnL_e, absMagnL_fx, absMagnL_e, &sumMagnL_e ); sumMagnR_fx = BASOP_Util_Add_Mant32Exp( sumMagnR_fx, sumMagnR_e, absMagnR_fx, absMagnR_e, &sumMagnR_e ); sumPrdLR_fx = BASOP_Util_Add_Mant32Exp( sumPrdLR_fx, sumPrdLR_e, Mpy_32_32( absMagnL_fx, absMagnR_fx ), add( absMagnL_e, absMagnR_e ), &sumPrdLR_e ); @@ -930,11 +909,7 @@ static UWord16 enc_ste_pre_mdct( temp1 = L_shl( preproLen, x1 ); corr_fx = Mpy_32_32( corr_fx, temp1 ); x1 = sub( 62, add( shl( *q_com, 1 ), x1 ) ); -#ifdef FIX_ISSUE_1092 corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( sub( *q_com, 1 ), 1 ) ), &x1 ); -#else - corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( *q_com, 1 ) ), &x1 ); -#endif IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( corr_fx, x1, -maxSqrValue_fx, 52 ), -1 ) ) { @@ -1181,7 +1156,6 @@ void ivas_mdct_core_whitening_enc_fx( push_wmops( "mdct_core_whitening" ); -#ifdef MSAN_FIX FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { FOR( i = 0; i < NB_DIV; i++ ) @@ -1195,7 +1169,6 @@ void ivas_mdct_core_whitening_enc_fx( set16_fx( orig_spectrum_e[ch], 0, NB_DIV ); } set16_fx( q_windowedSignal, Q31, CPE_CHANNELS ); -#endif q_com = Q31; q_min = 0; move16(); @@ -1235,9 +1208,7 @@ void ivas_mdct_core_whitening_enc_fx( orig_spectrum[ch][1] = orig_spectrum_long[ch] + N_TCX10_MAX; mdst_spectrum_fx[ch][0] = mdst_spectrum_long_fx[ch]; mdst_spectrum_fx[ch][1] = mdst_spectrum_long_fx[ch] + N_TCX10_MAX; -#ifdef MSAN_FIX set32_fx( temp_buffer, 0, 15 * L_FRAME48k / 8 ); -#endif } windowedSignal_fx[0] = orig_spectrum_long[0]; /* NOTE temporarily available */ diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index d31e6d53d..1433c988f 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -1050,10 +1050,8 @@ static void ivas_omasa_param_est_enc_fx( move16(); /* Need to initialize renormalization_factors, and variables to be normalized */ -#ifdef MSAN_FIX set_zero_fx( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); set_zero_fx( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); -#endif set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands ); set_zero_fx( diffuseness_m_fx, hOMasa->nbands ); @@ -1202,10 +1200,8 @@ static void ivas_omasa_param_est_enc_fx( intensity_real_e = sub( add( 62, guard_bits ), shl( q, 1 ) ); computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , NULL -#endif ); /* Power estimation for diffuseness */ diff --git a/lib_enc/ivas_osba_enc_fx.c b/lib_enc/ivas_osba_enc_fx.c index 0ca93e1a1..dbff29d68 100644 --- a/lib_enc/ivas_osba_enc_fx.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -77,11 +77,7 @@ static void ivas_merge_sba_transports_fx( { FOR( j = 0; j < input_frame; j++ ) { -#ifdef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS data_out_f[i][j] = L_shr( L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ), Q1 ); -#else - data_out_f[i][j] = L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ); -#endif move32(); } } @@ -479,9 +475,6 @@ static void ivas_osba_render_ism_to_sba_fx( Word16 azimuth_fx, elevation_fx; Word32 gains_fx[MAX_INPUT_CHANNELS]; Word32 g1_fx, g2_fx; -#ifndef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS - Word32 output_gain_fx; -#endif Word16 nchan_sba; nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) ); @@ -524,21 +517,6 @@ static void ivas_osba_render_ism_to_sba_fx( } *Q_data = sub( *Q_data, 2 ); -#ifndef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS - /* Gain with loudness-matching gains */ - // output_gain = 0.7499f; - output_gain_fx = 1610397988; // 0.7499f in Q31 - move32(); - FOR( j = 0; j < nchan_sba; j++ ) - { - FOR( k = 0; k < input_frame; k++ ) - { - // data_out_f[j][k] *= output_gain; - data_out_fx[j][k] = Mpy_32_32( data_out_fx[j][k], output_gain_fx ); - move32(); - } - } -#endif return; } diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 7de54c482..10380f422 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -2500,11 +2500,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( } ELSE { -#ifdef FIX_USAN_ISSUES avg_elevation_index = (UWord16) L_add( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ); -#else - avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ) ); -#endif } // avg_elevation_index = (uint16_t) ( ( avg_elevation_index + avg_elevation_alphabet ) % avg_elevation_alphabet ); avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index, avg_elevation_alphabet ) % avg_elevation_alphabet ); @@ -2639,13 +2635,8 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( FOR( avg_azimuth_offset = 0; avg_azimuth_offset < q_direction->cfg.search_effort; avg_azimuth_offset++ ) { set_zero_fx( avg_direction_vector, 3 ); -#ifdef FIX_USAN_ISSUES avg_azimuth_index = (UWord16) L_add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); avg_azimuth_index = (UWord16) ( L_add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); -#else - avg_azimuth_index = (UWord16) add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); - avg_azimuth_index = (UWord16) ( add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); -#endif all_zero_dist_azimuth_indexes = 1; move16(); azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); @@ -5452,11 +5443,7 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { -#ifdef FIX_USAN_ISSUES no_idx16 = add( shr( nbits_fr, 4 ), 1 ); -#else - no_idx16 = shr_r( nbits_fr, 4 ); -#endif } /* write combined index */ @@ -5478,11 +5465,7 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { -#ifdef FIX_USAN_ISSUES no_idx16 = add( shr( nbits_fr1, 4 ), 1 ); -#else - no_idx16 = shr_r( nbits_fr1, 4 ); -#endif } assert( no_idx16 <= 4 ); diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 3a0f19c50..b2e0e9c69 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -120,9 +120,7 @@ ivas_error ivas_sce_enc_fx( * Initialization - general *-----------------------------------------------------------------*/ -#ifdef MSAN_FIX set16_zero_fx( old_inp_12k8_fx[0], L_INP_12k8 ); -#endif Copy32( data_fx, st->input32_fx, input_frame ); // Q(q_data_fx) q_input = sub( add( L_norm_arr( st->input32_fx, input_frame ), q_data_fx ), 16 ); @@ -253,11 +251,7 @@ ivas_error ivas_sce_enc_fx( &ener_fx[0], &relE_fx[0], A_fx[0], Aw_fx[0], epsP_fx[0], &epsP_fx_q[0], lsp_new_fx[0], lsp_mid_fx[0], &vad_hover_flag[0], &attack_flag[0], realBuffer_fx[0], imagBuffer_fx[0], &q_re_im_buf, old_wsp_fx[0], &q_old_wsp, pitch_fr_fx[0], voicing_fr_fx[0], &loc_harm[0], &cor_map_sum_fx[0], &vad_flag_dtx[0], enerBuffer_fx[0], &enerBuffer_fx_exp[0], fft_buff_fx[0], &fft_buff_fx_q[0], A_fx[0], lsp_new_fx[0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, flag_16k_smc, -#ifdef NONBE_1211_DTX_BR_SWITCHING st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[0] -#else - st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[0] -#endif #ifdef DEBUG_MODE_INFO , st->id_element diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index 22cd98cad..b7de878a1 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -817,15 +817,10 @@ Word16 quantize_sns_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -#ifdef MSAN_FIX FOR( k = 0; k < nSubframes; k++ ) { scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); // Q(31-sns_e_tmp[ch][k]) } -#else - scale_sig32( snsQ_out_fx[ch][0], M, sub( sns_e_tmp[ch][0], *sns_e ) ); - scale_sig32( snsQ_out_fx[ch][1], M, sub( sns_e_tmp[ch][1], *sns_e ) ); -#endif } /* get back to L/F representation */ test(); diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index ef278d188..4a6543026 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -88,12 +88,8 @@ typedef struct stereo_itd_data_struct Word16 prev_sum_nrg_L_lb_fx_e; Word32 prev_xcorr_lb_fx[STEREO_DFT_XCORR_LB_MAX]; Word16 prev_xcorr_lb_fx_e; -#ifdef FIX_ISSUE_1092 Word32 E_band_n_fx[STEREO_DFT_ITD_VAD_BAND_NUM]; /*E_band_n_exp*/ Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM]; -#else - Word32 E_band_n_fx[STEREO_DFT_ITD_VAD_BAND_NUM]; /*Q0*/ -#endif Word32 xcorr_smooth_fx[STEREO_DFT_N_32k_ENC]; Word16 xcorr_smooth_fx_e[STEREO_DFT_N_32k_ENC]; Word32 lp_phat_peak_fx; /* low-pass GCC PHAT peak value */ // Q31 @@ -1183,11 +1179,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word32 isd_rate_s_fx; // Q31 -#else - Word16 isd_rate_s_fx; // Q15 -#endif Word32 iccr_s_fx; // Q31 Word32 ipd_ff_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word32 Pr_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 @@ -1228,11 +1220,7 @@ typedef struct stereo_dmx_evs_enc_data_structure STEREO_DMX_EVS_POC_HANDLE hPOC; STEREO_DMX_EVS_PHA_HANDLE hPHA; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx; // Q0 -#else - Word32 itd_fx; // Q16 -#endif Word32 pre_dmx_energy_fx[1]; Word16 pre_dmx_energy_fx_e[1]; diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 3e148a5ae..3e69a0ca6 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -1697,11 +1697,7 @@ static void edge_detect_fx( } } -#ifndef FIX_1297_OVERFLOW - *edge_str = extract_l( L_shr( edge_min, 10 ) ); // Q15 -#else *edge_str = extract_h( L_shl_sat( edge_min, 16 - 10 ) ); // Q15 -#endif move16(); *edge_type = et; // Q0 move16(); diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 3eb6c0e82..cebbc2619 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -593,10 +593,8 @@ void stereo_dft_enc_reset_fx( move16(); hStereoDft->dmx_res_all_prev_fx = 1; move32(); -#ifdef MSAN_FIX hStereoDft->dmx_res_all_prev_fx_e = 31; move16(); -#endif hStereoDft->last_res_cod_mode_modify_flag = 0; move16(); hStereoDft->res_cod_sw_flag = 0; @@ -750,9 +748,7 @@ void stereo_enc_itd_init_fx( hItd->prev_xcorr_lb_fx_e = 0; move16(); set32_fx( hItd->E_band_n_fx, ITD_VAD_E_BAND_N_INIT, STEREO_DFT_ITD_VAD_BAND_NUM ); -#ifdef FIX_ISSUE_1092 set16_fx( hItd->E_band_n_exp, Q31, STEREO_DFT_ITD_VAD_BAND_NUM ); -#endif hItd->vad_frm_cnt = 0; move16(); hItd->pre_vad = 0; @@ -1102,11 +1098,7 @@ void stereo_dft_enc_analyze_fx( { FOR( n = 0; n < n_channels; n++ ) { -#ifdef MSAN_FIX Scale_sig( hStereoDft->input_mem_itd_fx[n], dft_ovl, sub( sts[n]->q_inp, hStereoDft->q_input_mem_itd[n] ) ); // Q(sts[n]->q_inp) -#else - Scale_sig( hStereoDft->input_mem_itd_fx[n], STEREO_DFT_OVL_MAX, sts[n]->q_inp - hStereoDft->q_input_mem_itd[n] ); -#endif // MSAN_FIX hStereoDft->q_input_mem_itd[n] = sts[n]->q_inp; move16(); Copy( hStereoDft->input_mem_itd_fx[n], input_mem[n], dft_ovl ); @@ -1657,11 +1649,7 @@ void stereo_dft_enc_process_fx( pDFT_L_fx = hStereoDft->DFT_fx[0]; pDFT_R_fx = hStereoDft->DFT_fx[1]; -#ifdef MSAN_FIX FOR( i = 0; i < hStereoDft->NFFT; i++ ) -#else - FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) -#endif // MSAN_FIX { tmp_e = norm_l( hStereoDft->DFT_fx[0][i] ); pDFT_L_fx[i] = L_shl( hStereoDft->DFT_fx[0][i], tmp_e ); diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index af10f7dea..b7429e2e7 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -203,12 +203,8 @@ static void stereo_dft_quantize_itd_fx( *-------------------------------------------------------------------------*/ static Word32 itd_vad_ms_snr_calc_fx( -#ifdef FIX_ISSUE_1092 Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], -#else - Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 -#endif Word32 *Spd, // Q(31-Spd_e) Word16 *Spd_e, Word32 *E_band, // Q(31-E_band_e) @@ -251,11 +247,7 @@ static Word32 itd_vad_ms_snr_calc_fx( // snr[i] = E_band[i] / E_band_n[i]; snr[i] = BASOP_Util_Divide3232_Scale_cadence( E_band[i], E_band_n[i], &snr_e[i] ); move32(); -#ifdef FIX_ISSUE_1092 snr_e[i] = add( snr_e[i], sub( E_band_e[i], E_band_n_exp[i] ) ); -#else - snr_e[i] = add( snr_e[i], sub( E_band_e[i], 31 ) ); -#endif move16(); // if ( snr[i] < 1 ) IF( BASOP_Util_Cmp_Mant32Exp( snr[i], snr_e[i], 1, 31 ) < 0 ) @@ -291,12 +283,8 @@ static Word32 itd_vad_ms_snr_calc_fx( * *-------------------------------------------------------------------------*/ static void itd_vad_background_update_fx( -#ifdef FIX_ISSUE_1092 Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], -#else - Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 -#endif Word16 *vad_frm_cnt, const Word32 ms_snr, // Q(31-ms_snr_e) const Word16 ms_snr_e, @@ -338,19 +326,10 @@ static void itd_vad_background_update_fx( Word16 q_temp = norm_l( *vad_frm_cnt ); L_temp = L_shl( *vad_frm_cnt, q_temp ); L_temp_e = sub( 31, q_temp ); -#ifdef FIX_ISSUE_1092 L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( E_band_n_exp[i], L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); -#else - L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( 31, L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); -#endif E_band_n[i] = BASOP_Util_Divide3232_Scale_cadence( L_temp, L_add( *vad_frm_cnt, 1 ), &E_band_n_e_tmp ); move32(); -#ifdef FIX_ISSUE_1092 E_band_n_exp[i] = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); -#else - E_band_n_e_tmp = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); - E_band_n[i] = L_shr_r( E_band_n[i], sub( 31, E_band_n_e_tmp ) ); // Q31 -#endif move16(); } } @@ -362,7 +341,6 @@ static void itd_vad_background_update_fx( FOR( i = 0; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) { // E_band_n[i] = 0.96f * E_band_n[i] + 0.04f * E_band[i]; -#ifdef FIX_ISSUE_1092 E_band_n[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 2061584302 /*0.96 in Q31*/, E_band_n[i] ), E_band_n_exp[i], Mpy_32_32( 85899346 /*0.04 in Q31*/, E_band[i] ), E_band_e[i], &E_band_n_e_tmp ); move32(); E_band_n_exp[i] = E_band_n_e_tmp; @@ -375,20 +353,6 @@ static void itd_vad_background_update_fx( E_band_n_exp[i] = 0; move16(); } -#else - E_band_n[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 2061584302, E_band_n[i] ), 31, Mpy_32_32( 85899346, E_band[i] ), E_band_e[i], &E_band_n_e_tmp ); - move32(); - // if ( E_band_n[i] < 1.0f ) - IF( BASOP_Util_Cmp_Mant32Exp( E_band_n[i], E_band_n_e_tmp, MAX_32, 0 ) < 0 ) - { - E_band_n[i] = MAX_32; - move32(); - E_band_n_e_tmp = 0; - move16(); - } - E_band_n[i] = L_shr_r( E_band_n[i], sub( 31, E_band_n_e_tmp ) ); // Q31 - move32(); -#endif } } } @@ -402,12 +366,8 @@ static void itd_vad_background_update_fx( *-------------------------------------------------------------------------*/ static Word16 stereo_dft_enc_itd_vad_fx( -#ifdef FIX_ISSUE_1092 Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], -#else - Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 -#endif Word16 *vad_frm_cnt, Word32 *Spd_L, // Q(31-Spd_L_e) Word16 *Spd_L_e, @@ -434,17 +394,10 @@ static Word16 stereo_dft_enc_itd_vad_fx( Spd_e[i] = sub( Spd_e[i], 1 ); move16(); } -#ifdef FIX_ISSUE_1092 *mssnr = itd_vad_ms_snr_calc_fx( E_band_n, E_band_n_exp, Spd, Spd_e, E_band, E_band_e, mssnr_e ); move32(); itd_vad_background_update_fx( E_band_n, E_band_n_exp, vad_frm_cnt, *mssnr, *mssnr_e, E_band, E_band_e ); -#else - *mssnr = itd_vad_ms_snr_calc_fx( E_band_n, Spd, Spd_e, E_band, E_band_e, mssnr_e ); - move32(); - - itd_vad_background_update_fx( E_band_n, vad_frm_cnt, *mssnr, *mssnr_e, E_band, E_band_e ); -#endif // if ( *mssnr < ITD_VAD_THRSHOLD ) IF( BASOP_Util_Cmp_Mant32Exp( *mssnr, *mssnr_e, ITD_VAD_THRSHOLD_Q31, 0 ) < 0 ) { @@ -1476,11 +1429,7 @@ void stereo_dft_enc_compute_itd_fx( } // L_temp = sum2_32_fx( &Spd_L[1], 11, &L_temp_e ); sum_nrg_L_lb = BASOP_Util_Add_Mant32Exp( sum_nrg_L_lb, sum_nrg_L_lb_e, L_temp, L_temp_e, &sum_nrg_L_lb_e ); -#ifdef FIX_ISSUE_1092 vad_flag_itd = stereo_dft_enc_itd_vad_fx( hItd->E_band_n_fx, hItd->E_band_n_exp, &( hItd->vad_frm_cnt ), Spd_L, Spd_L_e, Spd_R, Spd_R_e, &mssnr, &mssnr_e ); -#else - vad_flag_itd = stereo_dft_enc_itd_vad_fx( hItd->E_band_n_fx, &( hItd->vad_frm_cnt ), Spd_L, Spd_L_e, Spd_R, Spd_R_e, &mssnr, &mssnr_e ); -#endif vad_flag_itd = vad_flag_itd && vad_flag_dtx[0]; // if ( sum_nrg_L < EPSILON ) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 933270c33..2ed17e25a 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -68,17 +68,11 @@ #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA #define STEREO_DMX_EVS_ISD_FORGETTING_Q31 2040109465 #define STEREO_DMX_EVS_ISD_1MFORGETTING_Q15 1638 #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 773094113 #define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 923417968 #define STEREO_DMX_EVS_ISD_INVTHRES_H 1270700383 -#else -#define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 -#define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 11796 -#define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 14090 -#endif #define STEREO_DMX_EVS_ICCR_FORGETTING_Q31 1503238554 #define STEREO_DMX_EVS_ICCR_HYST_L_Q31 1610612736 @@ -161,11 +155,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ -#else - Word32 itd[], /* o : estimated itd Q16 */ -#endif const Word16 input_frame /* i : input frame length per channel */ ); static void adapt_gain_fx( @@ -208,11 +198,7 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd */ -#else - Word32 itd_fx[], /* o : estimated itd */ -#endif const Word16 input_frame, /* i : input frame length per channel */ const Word32 ratio_fixed /* i : adapting ratio */ ); @@ -621,20 +607,12 @@ static void calc_poc_fx( Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), STEREO_DMX_EVS_ISD_INVTHRES_H ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) -#else - IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) -#endif { isd_cnt_h = add( isd_cnt_h, 1 ); } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA W_tmp = W_add( W_mult0_32_32( Mpy_32_32_r( Dr, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Dr ), W_mult0_32_32( Mpy_32_32_r( Di, STEREO_DMX_EVS_ISD_THRES_L_Q31 ), Di ) ); // Q62 IF( LT_64( W_add( W_mult0_32_32( Nr, Nr ), W_mult0_32_32( Ni, Ni ) ), W_tmp ) ) // Q62 -#else - IF( LT_32( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), Mpy_32_32_r( STEREO_DMX_EVS_ISD_THRES_L_Q31, L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) ) -#endif { isd_cnt_l = add( isd_cnt_l, 1 ); } @@ -643,19 +621,10 @@ static void calc_poc_fx( isd_rate = BASOP_Util_Divide1616_Scale( isd_cnt_h, freq_8k, &isd_rate_e ); // Saturation to handle values close to 1.0f isd_rate = shl_sat( isd_rate, isd_rate_e ); // Q15 -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->isd_rate_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ISD_FORGETTING_Q31, hPHA->isd_rate_s_fx ), L_mult( STEREO_DMX_EVS_ISD_1MFORGETTING_Q15, isd_rate ) ); move32(); -#else - hPHA->isd_rate_s_fx = add( mult_r( STEREO_DMX_EVS_ISD_FORGETTING_Q15, hPHA->isd_rate_s_fx ), mult_r( MAX_16 - STEREO_DMX_EVS_ISD_FORGETTING_Q15, isd_rate ) ); - move16(); -#endif -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q31 ) ) -#else - IF( GT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 ) ) -#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD ) ) { @@ -680,11 +649,7 @@ static void calc_poc_fx( hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; move32(); } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA ELSE IF( LT_32( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q31 ) ) -#else - ELSE IF( LT_16( hPHA->isd_rate_s_fx, STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 ) ) -#endif { IF( NE_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD2 ) ) { @@ -752,7 +717,6 @@ static void calc_poc_fx( /* Energy */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA // Left W_tmp = W_add( W_mult0_32_32( specLr[i], specLr[i] ), W_mult0_32_32( specLi[i], specLi[i] ) ); // Q(62-(2*specL_e)) -> Q(63 - ((2*specL_e) +1)) @@ -773,12 +737,6 @@ static void calc_poc_fx( } tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], W_round64_L( W_tmp ), sub( shl( spec_e, 1 ), sub( L_tmp_e, 1 ) ), &tEr_e[n] ); move32(); -#else - tEl[n] = BASOP_Util_Add_Mant32Exp( tEl[n], tEl_e[n], L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &tEl_e[n] ); - move32(); - tEr[n] = BASOP_Util_Add_Mant32Exp( tEr[n], tEr_e[n], L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &tEr_e[n] ); - move32(); -#endif /* IPD */ // IPDr = L_add(Mpy_32_32_r(specLr[i], specRr[i]), Mpy_32_32_r(specLi[i], specRi[i])); //2*spec_e @@ -809,7 +767,6 @@ static void calc_poc_fx( tIPDr = L_sub( Mpy_32_32_r( specRr[i], IPDr ), Mpy_32_32_r( specRi[i], IPDi ) ); // spec_e tIPDi = L_add( Mpy_32_32_r( specRr[i], IPDi ), Mpy_32_32_r( specRi[i], IPDr ) ); // spec_e -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), 0, &Nr_e ); Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), 0, &Ni_e ); @@ -831,13 +788,6 @@ static void calc_poc_fx( W_tmp = W_shl( W_tmp, L_tmp_e ); } eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, W_round64_L( W_tmp ), sub( 1, L_tmp_e ), &eneR_e ); -#else - Nr = BASOP_Util_Add_Mant32Exp( Nr, Nr_e, L_add( Mpy_32_32_r( specLr[i], tIPDr ), Mpy_32_32_r( specLi[i], tIPDi ) ), shl( spec_e, 1 ), &Nr_e ); - Ni = BASOP_Util_Add_Mant32Exp( Ni, Ni_e, L_sub( Mpy_32_32_r( specLi[i], tIPDr ), Mpy_32_32_r( specLr[i], tIPDi ) ), shl( spec_e, 1 ), &Ni_e ); - - eneL = BASOP_Util_Add_Mant32Exp( eneL, eneL_e, L_add( Mpy_32_32_r( specLr[i], specLr[i] ), Mpy_32_32_r( specLi[i], specLi[i] ) ), shl( spec_e, 1 ), &eneL_e ); - eneR = BASOP_Util_Add_Mant32Exp( eneR, eneR_e, L_add( Mpy_32_32_r( specRr[i], specRr[i] ), Mpy_32_32_r( specRi[i], specRi[i] ) ), shl( spec_e, 1 ), &eneR_e ); -#endif } // Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON ); @@ -857,19 +807,9 @@ static void calc_poc_fx( move32(); // Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Pn = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); Pn = BASOP_Util_Add_Mant32Exp( Pn, 1, EPSILON_FX_M, EPSILON_FX_E, &Pn_e ); Pn = Isqrt_lc( Pn, &Pn_e ); -#else - L_tmp = L_add( L_shr( Mpy_32_32_r( Pr[n], Pr[n] ), 1 ), L_shr( Mpy_32_32_r( Pi[n], Pi[n] ), 1 ) ); - L_tmp_e = 1; - move16(); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp_e ); - Pn_e = L_tmp_e; - move16(); - Pn = ISqrt32( L_tmp, &Pn_e ); -#endif Pr[n] = L_shl_sat( Mpy_32_32_r( Pr[n], Pn ), Pn_e ); // Q31 move32(); @@ -1076,17 +1016,7 @@ static void calc_poc_fx( FOR( i = 0; i < hPHA->pha_len; i++ ) { // hPHA->p_curr_taps[n][i] *= hPHA->win[i]; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA - hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 -#else - -#ifdef FIX_ISSUE_1153 hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 -#else - hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 -#endif - -#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA move32(); } @@ -1094,39 +1024,16 @@ static void calc_poc_fx( move32(); energy_e = 0; move16(); -#ifndef NONBE_FIX_1386_STEREO_DMX_EVS_PHA -#ifdef FIX_ISSUE_1153 - Word16 shift = L_norm_arr( hPHA->p_curr_taps_fx[n], hPHA->pha_len ); - IF( shift ) - { - scale_sig32( hPHA->p_curr_taps_fx[n], hPHA->pha_len, 1 ); - shift = 1; - move16(); - } -#endif -#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA FOR( i = 0; i < hPHA->pha_len; i++ ) { -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA - energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); -#else -#ifdef FIX_ISSUE_1153 - energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), shl( sub( 1, shift ), 1 ), &energy_e ); -#else energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); -#endif -#endif // NONBE_FIX_1386_STEREO_DMX_EVS_PHA } // energy = (float) inv_sqrt( energy + EPSILON ); energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, EPSILON_FX_M, EPSILON_FX_E, &energy_e ); energy = ISqrt32( energy, &energy_e ); FOR( i = 0; i < hPHA->pha_len; i++ ) { -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), sub( energy_e, 1 ) ); // Q30 -#else - hPHA->p_curr_taps_fx[n][i] = L_shl_r( Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], energy ), energy_e ); // Q31 -#endif move32(); } } @@ -1229,11 +1136,7 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd_fx[], /* o : estimated itd Q0 */ -#else - Word32 itd_fx[], /* o : estimated itd Q16 */ -#endif const Word16 input_frame, /* i : input frame length per channel */ const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) @@ -1545,11 +1448,7 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 itd[], /* o : estimated itd Q0 */ -#else - Word32 itd[], /* o : estimated itd Q16 */ -#endif const Word16 input_frame /* i : input frame length per channel */ ) { @@ -2090,9 +1989,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_prev_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_prev_taps[m] ) ); // Q25 } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 -#endif mem_prev[n] = L_add( mem_prev[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); move32(); } @@ -2117,9 +2014,7 @@ void stereo_dmx_evs_enc_fx( // ftmp += p_data_mem[n - m] * p_curr_taps[m]; fx_tmp = L_add( fx_tmp, Mpy_32_32( p_data_mem[n - m], p_curr_taps[m] ) ); // Q25 } -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA fx_tmp = L_shl( fx_tmp, 1 ); // Q26 -#endif // dmx_pha_data[n] += ftmp * INV_SQRT_2; dmx_pha_data[n] = L_add( dmx_pha_data[n], Mpy_32_32( fx_tmp, INV_SQRT_2_Q31 ) ); // Q26 move32(); @@ -2149,11 +2044,7 @@ void stereo_dmx_evs_enc_fx( curr_prc = hStereoDmxEVS->hPHA->curr_prc; move32(); // if ( abs( (int16_t) hStereoDmxEVS->itd ) > hStereoDmxEVS->hPHA->prc_thres ) -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA IF( GT_16( abs_s( hStereoDmxEVS->itd_fx ), hStereoDmxEVS->hPHA->prc_thres ) ) -#else - IF( GT_16( abs_s( round_fx( hStereoDmxEVS->itd_fx ) ), hStereoDmxEVS->hPHA->prc_thres ) ) -#endif { IF( NE_32( hStereoDmxEVS->hPHA->curr_prc, STEREO_DMX_EVS_PRC_POC ) ) { @@ -2276,15 +2167,9 @@ ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS; Word16 n, input_frame; -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA Word16 m, len, pha_len, fad_len, fad_len2, rfft_ipd_coef_step, n0, input_frame_pha; Word32 *fad_g, fad_r, *ipd_ff; Word16 *win; -#else - Word16 m, len, pha_len, fad_len, fad_len2, trans_len /*, itrh*/, rfft_ipd_coef_step, n0, input_frame_pha; - Word32 *fad_g, fad_r /*, a_min, a_max, a_step*/, *ipd_ff; - Word16 *win, tmp_r; -#endif const Word16 *p_ipd_w; Word16 tmp_e; @@ -2516,7 +2401,6 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_len = hStereoDmxEVS->hPHA->fad_len; move16(); -#ifdef NONBE_FIX_1386_STEREO_DMX_EVS_PHA set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q14*/, pha_len ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; move16(); @@ -2532,21 +2416,6 @@ ivas_error stereo_dmx_evs_init_encoder_fx( hStereoDmxEVS->hPHA->win_fx[sub( pha_len, 1 )] = 2816; /*0.1718f in Q14*/ move16(); } -#else - trans_len = idiv1616( pha_len, 20 ); - set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q15*/, sub( pha_len, trans_len ) ); - hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; - move16(); - // tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 ); - tmp_r = div_s( 1, add( shl( trans_len, 1 ), 1 ) ); - win = &( hStereoDmxEVS->hPHA->win_fx[pha_len - trans_len] ); - FOR( n = 0; n < trans_len; n++ ) - { - // win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * 1.8f; - win[n] = mult_r( add( ONE_IN_Q14, getCosWord16R2( imult1616( add( n, 1 ), tmp_r ) ) ), 29491 /*1.8/2 in Q15*/ ); - move16(); - } -#endif fad_g = hStereoDmxEVS->hPHA->fad_g_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 057798706..8410f7546 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1094,11 +1094,7 @@ static void corrStatsEst_fx( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */ move32(); -#ifdef FIX_USAN_ISSUES Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ -#else - Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -hStereoTCA->delay_0_mem_fx[0], hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ -#endif inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 { @@ -1968,22 +1964,8 @@ void stereo_tca_enc_fx( Word16 temp_exp, tempF_16fx; Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */ -#ifndef FIX_1300_ICA_SHIFT_QUANT_IMPROV - IF( temp_exp < 0 ) - { - scalar_value = shl( scalar_value, sub( temp_exp, Q3 ) ); // Q12 - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, ONE_IN_Q11, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ - move16(); - } - ELSE - { - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, shl( 1, sub( 14, temp_exp ) ), ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ - move16(); - } -#else scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ -#endif tempF_fx = tempF_16fx; move32(); @@ -2263,7 +2245,6 @@ static void unclr_calc_corr_features_fx( side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */ ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); /* Q31-ener_side_exp */ -#ifdef FIX_ISSUE_1125 Word16 n1, n2, prod_i_exp; Word32 x, y, prod_i; n1 = norm_l( buf1[i] ); @@ -2273,9 +2254,6 @@ static void unclr_calc_corr_features_fx( prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31 prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) ); sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */ -#else - sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); /* Q31-sum_prod_exp */ -#endif } /* average energy of L and R channels */ diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index ad038f0fa..25e2366dd 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -809,11 +809,7 @@ void stereo_icBWE_enc_ivas_fx( Copy_Scale_sig( hStereoICBWE->mem_shb_speech_ref_fx, hStereoICBWE->mem_shb_speech_ref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ) ); // mem_shb_speech_ref_e set32_fx( shb_frame_ref_fx, 0, L_LOOK_16k + L_FRAME16k ); -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#else - Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#endif hStereoICBWE->mem_shb_speech_ref_e = max_e; shb_frame_ref_e = max_e; move16(); @@ -827,11 +823,7 @@ void stereo_icBWE_enc_ivas_fx( max_e = s_max( hStereoICBWE->mem_shb_speech_nonref_e, shb_speech_nonref_e ); Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e -#ifdef FIX_ISSUE_1237 Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#else - Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e -#endif hStereoICBWE->mem_shb_speech_nonref_e = max_e; shb_frame_nonref_e = max_e; move16(); @@ -1233,9 +1225,7 @@ void stereo_icBWE_preproc_fx( Word32 gD_fx; Word32 input_Fs; -#ifdef MSAN_FIX set16_fx( temp_inp_fx, 0, L_FRAME48k ); -#endif /* initialization */ hStereoTCA = hCPE->hStereoTCA; /* Stereo TCA encoder handle */ diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index b68578542..4255980ad 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -178,10 +178,8 @@ void stereo_mdct_core_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -#ifdef MSAN_FIX set32_fx( mdst_spectrum_long_fx[ch], 0, N_MAX ); set32_fx( orig_spectrum_long_fx[ch], 0, N_MAX ); -#endif p_mdst_spectrum_long_fx[ch] = mdst_spectrum_long_fx[ch]; p_orig_spectrum_long_fx[ch] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][0] = orig_spectrum_long_fx[ch]; @@ -674,11 +672,7 @@ void stereo_mdct_core_enc_fx( q_spectrum = sub( Q31, st->hTcxEnc->spectrum_e[n] ); Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#else ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#endif } } } @@ -719,11 +713,7 @@ void stereo_mdct_core_enc_fx( Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ -#ifndef MSAN_FIX - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#else ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); -#endif } } } diff --git a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c index 851df60d5..6c3588cab 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -166,12 +166,10 @@ static void IGF_MsStereoDecision_fx( Word16 pc_target_e, pc_src_e; Word16 tmp1, tmp1_e, tmp2, tmp2_e; -#ifdef MSAN_FIX pc_target_e = 0; pc_src_e = 0; move16(); move16(); -#endif // MSAN_FIX Word16 coh_src = calcCoh_fx( &specL_fx[strt_cpy], &specR_fx[strt_cpy], q_spec, width, &cc_src_fx, &cc_src_e, &pc_src_fx, &pc_src_e ); Word16 coh_target = calcCoh_fx( &specL_fx[hGrid->swb_offset[sfb]], &specR_fx[hGrid->swb_offset[sfb]], q_spec, width, &cc_target_fx, &cc_target_e, &pc_target_fx, &pc_target_e ); diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 0a526561a..5f1208ba7 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -239,16 +239,12 @@ ivas_error stereo_memory_enc_fx( test(); IF( hCPE->hStereoTCA != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { -#ifdef FIX_1132_STACK_CORRUPTION Word16 tmp = extract_h( L_abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); if ( hCPE->hStereoDft->hItd->itd_fx[1] < 0 ) { tmp = negate( tmp ); } set16_fx( hCPE->hStereoTCA->prevCorrLagStats, tmp, 3 ); -#else - set16_fx( hCPE->hStereoTCA->prevCorrLagStats, extract_h( hCPE->hStereoDft->hItd->itd_fx[1] ), 3 ); -#endif IF( hCPE->hStereoDft->hItd->itd_fx[1] >= 0 ) { hCPE->hStereoTCA->prevRefChanIndx = L_CH_INDX; @@ -448,10 +444,8 @@ ivas_error stereo_memory_enc_fx( } fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX st->Q_old_wtda = 0; move16(); -#endif } /* allocate stereo CNG structure */ @@ -679,10 +673,8 @@ void stereo_switching_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); /* sts[n]->q_inp */ -#ifdef FIX_ISSUE_1327 hCPE->q_input_mem[n] = sts[n]->q_inp; move16(); -#endif } } diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 44c08efa8..f9b6b0bf3 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -72,13 +72,8 @@ #define RATIO_MAX 1.5f /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ -#ifdef FIX_1301_CORRECT_TD_CNST #define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ -#else -#define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ -#endif #define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ #define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ #define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ @@ -260,11 +255,7 @@ Word16 stereo_tdm_ener_analysis_fx( rms_thd_fx = L_shr( rms_thd_fx, 2 ); /*Q16*/ /*rms_thd_fx *= 0.25f*/ test(); test(); -#ifdef FIX_1301_CORRECT_TD_CNST IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 4915200 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) -#else - IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 75 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) -#endif { rms_thd_fx = L_shr( rms_thd_fx, 5 ); /* Q16*/ /*rms_thd_fx *= 0.03125f*/ } @@ -338,10 +329,8 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } -#ifdef FIX_1301_CORRECT_TD_CNST rms_L_fx = L_shl( rms_L_fx, sub( Q16, q_rms_L ) ); /* All the following energy comparison are done in Q16 */ rms_R_fx = L_shl( rms_R_fx, sub( Q16, q_rms_R ) ); -#endif test(); IF( EQ_16( hStereoTD->prev_fr_LRTD_TD_dec, 1 ) && side_can_change == 0 ) { @@ -440,11 +429,7 @@ Word16 stereo_tdm_ener_analysis_fx( ELSE { /*ratio_L = ( 1.0f - cosf( EVS_PI * ratio_L / 2.0f ) ) / 2.0f;*/ -#ifdef FIX_1301_CORRECT_TD_CNST ratio_L_fx = L_deposit_h( sub_sat( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) -#else - ratio_L_fx = L_deposit_h( sub( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) -#endif } test(); @@ -650,22 +635,14 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } -#ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 -#else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 -#endif move32(); test(); IF( EQ_16( hStereoTD->tdm_SM_modi_flag, 1 ) && hStereoTD->tdm_LRTD_flag == 0 ) { idx = shr( add( hStereoTD->tdm_last_ratio_idx, add( LRTD_STEREO_MID_IS_PRIM, 1 ) ), 1 ); -#ifdef FIX_ISSUE_1125 ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 -#else - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 -#endif move32(); } @@ -756,10 +733,8 @@ Word16 stereo_tdm_ener_analysis_fx( hCPE->hStereoClassif->ratio_L_fx = ratio_L_fx; /* 31 - ratio_L_e */ move32(); -#ifdef FIX_ISSUE_1125 hCPE->hStereoClassif->ratio_L_e = 1; move16(); -#endif return idx; } @@ -1073,11 +1048,7 @@ static void NOOP_decision_fx( } ELSE { -#ifdef FIX_1301_CORRECT_TD_CNST if ( LT_32( sts[0]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) ) -#else - if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) -#endif { tdm_NOOP_switch_flag = 1; move16(); diff --git a/lib_enc/ivas_stereo_td_enc_fx.c b/lib_enc/ivas_stereo_td_enc_fx.c index 378068827..8f1d2d9c9 100644 --- a/lib_enc/ivas_stereo_td_enc_fx.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -336,10 +336,8 @@ ivas_error stereo_set_tdm_fx( } fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX st->Q_old_wtda = 0; move16(); -#endif } } diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index eabfe87b4..159012ac2 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -789,7 +789,6 @@ Word16 ivas_acelp_tcx20_switching_fx( L_frame = L_FRAME; move16(); } -#ifdef MSAN_FIX set16_fx( window_fx, 0, L_LOOK_16k ); set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); FOR( i = 0; i < L_LOOK_16k; i++ ) @@ -799,7 +798,6 @@ Word16 ivas_acelp_tcx20_switching_fx( window_p_fx[i].v.im = 0; move16(); } -#endif L_frame_tmp = L_frame; move16(); @@ -854,7 +852,6 @@ Word16 ivas_acelp_tcx20_switching_fx( overlap = st->hTcxCfg->tcx_mdct_window_delay; move16(); -#ifdef MSAN_FIX FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length / 2; i++ ) { window_fx[st->hTcxCfg->tcx_mdct_window_length - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 @@ -862,15 +859,6 @@ Word16 ivas_acelp_tcx20_switching_fx( window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 move16(); } -#else - FOR( i = 0; i < L_LOOK_16k / 2; i++ ) - { - window_fx[L_LOOK_16k / 2 - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 - move16(); - window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 - move16(); - } -#endif } ELSE { @@ -1047,12 +1035,8 @@ Word16 ivas_acelp_tcx20_switching_fx( IF( LE_32( offset, 0xAA153 ) ) /* 0xAA153 -> 32.f * log2(10)/10 */ { -#ifdef FIX_USAN_ISSUES offset = (Word32) 0xFFD57AB5; /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ move32(); -#else - offset = L_add( 0xFFD57AB5, 0 ); /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ -#endif } offset_tcx = offset; move32(); @@ -1155,11 +1139,7 @@ Word16 ivas_acelp_tcx20_switching_fx( { *pt_ener_sfr = -668739840; /* 0xFFEC1185 -> log2(1e-6) in 6Q25 */ move32(); -#ifdef FIX_USAN_ISSUES tmp32 = (Word32) 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ -#else - tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ -#endif move32(); } ELSE diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index c959ef758..63cbb30e9 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -221,13 +221,9 @@ void encod_gen_2sbfr( LPD_state_HANDLE hLPDmem = st->hLPDmem; -#ifdef FIX_1320_LOWRATE_ACELP Word16 gcode16; Word32 Lgcode, Ltmp; -#endif -#ifdef MSAN_FIX set16_fx( cn, 0, 2 * L_SUBFR ); /* Target vector in residual domain */ -#endif /*------------------------------------------------------------------* * Initializations @@ -268,11 +264,7 @@ void encod_gen_2sbfr( Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new -#ifndef FIX_1320_LOWRATE_ACELP - find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); -#else find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); -#endif q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2, 2 * L_SUBFR, sub( 11, q_h1 ) ); @@ -298,21 +290,13 @@ void encod_gen_2sbfr( * Gain clipping test to avoid unstable synthesis on frame erasure *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, Q_new ); // Q0 -#else clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, sub( Q_new, 1 ) ); // Q0 -#endif /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ -#ifndef FIX_1320_LOWRATE_ACELP - lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); -#else lp_filt_exc_enc_ivas_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); -#endif /* update long-term pitch gain for speech/music classifier */ st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277 /*Q15*/, gain_pit ) ); // Q14 move16(); @@ -345,22 +329,15 @@ void encod_gen_2sbfr( gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); -#ifndef FIX_1320_LOWRATE_ACELP - hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); -#else Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_sat( Lgcode ); /*Q0*/ hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); /* Q15 */ -#endif move16(); /*-----------------------------------------------------------------* * Update memory of the weighting filter *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); -#else Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); @@ -368,7 +345,6 @@ void encod_gen_2sbfr( Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#endif move16(); /*-----------------------------------------------------------------* @@ -376,15 +352,6 @@ void encod_gen_2sbfr( * Save the non-enhanced excitation for FEC_exc *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - FOR( i = 0; i < 2 * L_SUBFR; i++ ) - { - exc2[i + i_subfr] = mult( gain_pit, exc[i + i_subfr] ); - move16(); - exc[i + i_subfr] = add( exc2[i + i_subfr], mult( extract_h( gain_code ), code[i] ) ); - move16(); - } -#else FOR( i = 0; i < 2 * L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ @@ -397,7 +364,6 @@ void encod_gen_2sbfr( move16(); move16(); } -#endif /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ @@ -411,11 +377,7 @@ void encod_gen_2sbfr( * Synthesize speech to update mem_syn_flt[]. * Update A(z) filters *-----------------------------------------------------------------*/ -#ifndef FIX_1320_LOWRATE_ACELP - E_UTIL_synthesis( 0, p_Aq, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1, M ); -#else Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); -#endif p_Aw += 2 * ( M + 1 ); p_Aq += 2 * ( M + 1 ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 09e3efc84..877fc2045 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1166,11 +1166,7 @@ static ivas_error configureEncoder( test(); test(); test(); -#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH IF( hEncoderConfig->Opt_PCA_ON && !( ( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) || EQ_16( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) && EQ_32( hEncoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( hEncoderConfig->sba_order, SBA_FOA_ORDER ) ) ) -#else - if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) -#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 0851e4c17..e59ef07d9 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -923,9 +923,7 @@ void noise_est_fx( NOISE_EST_HANDLE hNoiseEst; SP_MUS_CLAS_HANDLE hSpMusClas; hSpMusClas = st_fx->hSpMusClas; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( ncharX ); -#endif /* Check if LR-VAD */ { diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index bcf7d33bb..b19fb7e56 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -80,9 +80,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc Word16 pit_flag, delta, mult_Top, nBits; Word16 L_sufr_sft; Word16 T_op[2]; /* values for two half-frames */ -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) tdm_Pitch_reuse_flag; -#endif L_sufr_sft = 6; move16(); diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 6844945c0..efecb33ed 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -1104,11 +1104,7 @@ void pre_proc_fx( test(); test(); test(); -#ifndef CR_2109_to_2112_cd0_ce0 - IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA || NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) -#else IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) -#endif { /* update signal buffers */ Copy( new_inp_resamp16k, st->buf_speech_enc + L_FRAME16k, L_FRAME16k ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 042b5af90..f80373787 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -178,9 +178,7 @@ void dtx_fx( void dtx_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ -#ifdef NONBE_1211_DTX_BR_SWITCHING const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ -#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ const Word16 vad, /* i : vad flag for DTX Q0*/ const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ @@ -1235,9 +1233,7 @@ void AVQ_cod_lpc_fx( void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ -#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -1553,9 +1549,7 @@ void Mode2_pit_encode_fx( Word16 pit_res_max ); void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); -#ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); -#endif void E_ACELP_4t_fx( Word16 dn[], /* Qdn */ @@ -3074,9 +3068,7 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | ); void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ -#endif const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/spec_flatness_fx.c b/lib_enc/spec_flatness_fx.c index c2451886d..d7bd9a6e9 100644 --- a/lib_enc/spec_flatness_fx.c +++ b/lib_enc/spec_flatness_fx.c @@ -221,11 +221,7 @@ void spec_flatness_fx( SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q ); SFM_Qtmp = sub( SFM_Qtmp, SFM_Q ); -#ifdef FIX_ISSUE_1209 sSFM[1] = add_sat( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); -#else - sSFM[1] = add( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); -#endif move16(); /*sSFM3*/ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index e04f5172b..ff9e2d936 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -890,20 +890,12 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */ L_tmp = L_shl( tmp, sub( 1, exp3 ) ); /*Q16 */ -#ifdef FIX_ISSUE_1151 ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ -#else - ps_sta = L_add( ps_sta, L_tmp ); /*Q16 */ -#endif } } /**pFV++ = (float)log(ps_sta + 1e-5f);*/ -#ifdef FIX_ISSUE_1151 ps_sta = L_add_sat( ps_sta, 336 ); -#else - ps_sta = L_add( ps_sta, 336 ); -#endif e_tmp = norm_l( ps_sta ); f_tmp = Log2_norm_lc( L_shl( ps_sta, e_tmp ) ); e_tmp = sub( 30 - 16, e_tmp ); @@ -1617,16 +1609,8 @@ Word16 ivas_smc_gmm_fx( Word16 flag_odv; Word32 lps_fx, lpm_fx, lpn_fx; Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; -#ifndef DOT_PROD_CHOLESKY_64BIT - Word32 lprob_fx; - Word16 lprob_exp = 0; -#else Word64 wprob_fx; -#endif Word32 fvm_fx[N_PCA_COEF]; -#ifndef DOT_PROD_CHOLESKY_64BIT - Word16 fvm_exp = 0; -#endif Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; @@ -2213,38 +2197,16 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); -#ifndef DOT_PROD_CHOLESKY_64BIT - fvm_exp = sub( 31, Qfact_FV ); - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#else wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#endif move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); -#ifndef DOT_PROD_CHOLESKY_64BIT - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#else wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#endif move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); -#ifndef DOT_PROD_CHOLESKY_64BIT - lprob_exp = 0; - move16(); - lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#else wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 -#endif move32(); } @@ -2258,21 +2220,12 @@ Word16 ivas_smc_gmm_fx( *high_lpn_flag = 1; move32(); } -#ifndef FIX_1297_OVERFLOW - hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 11 ) ); // Q7 - move16(); - hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 11 ) ); // Q7 - move16(); - hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q7 - move16(); -#else hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lpn_fx = extract_h( L_shl_sat( lpn_fx, 16 - 11 ) ); // Q7 move16(); -#endif /* determine HQ Generic speech class */ IF( st->hHQ_core != NULL ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 7ca996af5..64ab13ea2 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -701,9 +701,6 @@ typedef struct sp_mus_clas_structure typedef struct lpd_state_structure { -#ifndef MSAN_FIX - Word16 nbits; /* number of bits used by ACELP or TCX */ -#endif /* signal memory */ Word16 syn[1 + M]; /* Synthesis memory (non-pe) */ @@ -1012,9 +1009,7 @@ typedef struct td_bwe_enc_structure typedef struct fd_bwe_enc_structure { Word16 new_input_hp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS )]; // Q_new_input_hp -#ifdef FIX_ISSUE_1230 Word16 Q_new_input_hp; -#endif Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS )]; // q0 Word16 old_input_wb_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; /* Q(-1) */ Word16 old_input_lp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS )]; // st->hBWE_FD->prev_Q_input_lp diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index e0d846458..26c8382ca 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -307,9 +307,7 @@ void swb_bwe_enc_ivas_fx( move32(); #endif Word16 fb_band_begin; -#ifdef FIX_ISSUE_1230 Word16 q_new_input_hp; -#endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; @@ -385,7 +383,6 @@ void swb_bwe_enc_ivas_fx( Copy( old_input_16k_fx + L_INP_MEM + L_FRAME16k - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); } -#ifdef FIX_ISSUE_1230 q_new_input_hp = s_min( Q_shb_speech, hBWE_FD->Q_new_input_hp ); IF( LT_16( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ) { @@ -400,10 +397,6 @@ void swb_bwe_enc_ivas_fx( hBWE_FD->Q_new_input_hp = Q_shb_speech; move16(); -#else - Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); - Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); -#endif Copy( shb_speech_fx + L_FRAME16k - Sample_Delay_HP, hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); new_input_fx = old_input_fx + Sample_Delay_SWB_BWE; Copy( hBWE_FD->old_input_fx, old_input_fx, Sample_Delay_SWB_BWE ); @@ -513,11 +506,7 @@ void swb_bwe_enc_ivas_fx( { Q_shb = sub( Q_synth_hf, 4 ); } -#ifdef FIX_ISSUE_1230 Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, q_new_input_hp ) ); -#else - Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, Q_shb_speech ) ); -#endif /* FB BWE encoding */ IF( EQ_16( st_fx->extl, FB_BWE ) ) @@ -3229,11 +3218,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( expn = sub( sub( 30, expn ), sub( shl( Q_insig_lp, 1 ), 7 ) ); expd = norm_l( WB_tenv_syn_fx ); -#ifdef FIX_ISSUE_1156 den = round_fx_o( L_shl( WB_tenv_syn_fx, expd ), &Overflow ); -#else - den = round_fx( L_shl( WB_tenv_syn_fx, expd ) ); -#endif expd = sub( sub( 30, expd ), sub( shl( Q_insig_lp, 1 ), 7 ) ); scale = shr( sub( den, num ), 15 ); @@ -4145,17 +4130,11 @@ void fd_bwe_enc_init_fx( ) { set16_fx( hBWE_FD->new_input_hp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ) ); -#ifdef FIX_ISSUE_1230 hBWE_FD->Q_new_input_hp = 0; move16(); -#endif set16_fx( hBWE_FD->old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) ); set16_fx( hBWE_FD->old_input_wb_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ) ); -#ifndef MSAN_FIX - set16_fx( hBWE_FD->old_input_lp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_SWB_TBE_16k_NS ) ); -#else set16_fx( hBWE_FD->old_input_lp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ) ); -#endif set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); hBWE_FD->prev_mode = NORMAL; move16(); diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index b73b0f992..c49c32e03 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1263,11 +1263,7 @@ void swb_pre_proc_ivas_fx( thr = icbwe_thr_TDM_fx; regV = icbwe_regressionValuesTDM_fx; -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, 0, st->cldfbSynTd ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, st->cldfbSynTd ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ Copy_Scale_sig_32_16( shb_speech_fx_32, shb_speech, L_FRAME16k, negate( sub( q_reImBuffer, 1 ) ) ); *Q_shb_spch = 0; move16(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 9b4f15dc5..2b8f487bd 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -1391,11 +1391,7 @@ void wb_tbe_enc_ivas_fx( move32(); } -#ifdef FIX_ISSUE_1165 lpc2lsp_ivas_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB ); -#else - lpc2lsp_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB ); -#endif FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index 19afa8243..25a3bdee7 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -536,11 +536,7 @@ static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_fra BASOP_SATURATE_WARNING_ON_EVS /* Quantize gain */ -#ifdef FIX_ISSUE_1150 g = shr( sub_o( g, 0x1000, &Overflow ), 13 ); -#else - g = shr( sub( g, 0x1000 ), 13 ); -#endif g = s_max( g, -1 ); *gain_index = g; diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index ce7f0e6a6..c84843384 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3785,9 +3785,7 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) *---------------------------------------------------------------------*/ void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ -#ifdef MSAN_FIX Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ -#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -3834,11 +3832,7 @@ void ProcessIGF_ivas_fx( IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, *q_spectrum ) ); -#ifndef MSAN_FIX - IGFEncApplyMono_ivas_fx( st, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); -#else IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); -#endif curr_order = 0; move16(); diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index cf6e5dd64..05b35813a 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -229,11 +229,7 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) ); FOR( i = 0; i < n; i++ ) { -#ifdef FIX_ISSUE_1147 tmpbuf[i] = round_fx_sat( L_shl( pSpectrum[iStartLine + i], shift ) ); -#else - tmpbuf[i] = round_fx( L_shl( pSpectrum[iStartLine + i], shift ) ); -#endif move16(); } diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 44bd8cc3c..92f01b5dd 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -678,18 +678,13 @@ void RunTransientDetection_ivas_fx( IF( GT_16( sub( q_input, pSubblockEnergies->q_firState ), shift ) ) { Scale_sig( input_fx, length, add( sub( pSubblockEnergies->q_firState, q_input ), shift ) ); // q_firState + shift -#ifdef FIX_ISSUE_1186 q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift -#endif pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift move16(); pSubblockEnergies->firState2 = shl( pSubblockEnergies->firState2, shift ); // q_firState + shift move16(); pSubblockEnergies->q_firState = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift move16(); -#ifndef FIX_ISSUE_1186 - q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift -#endif } ELSE { @@ -715,11 +710,7 @@ void RunTransientDetection_ivas_fx( } /* Update subblock energies. */ -#ifdef MSAN_FIX Scale_sig( filteredInput_fx, length, sub( 0, q_input ) ); // q0 -#else - Scale_sig( filteredInput_fx, L_FRAME_MAX, 8 ); -#endif UpdateSubblockEnergies_ivas_fx( filteredInput_fx, length, pSubblockEnergies ); /* Run transient detectors. */ diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 9911d766a..7fe813d12 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -213,11 +213,7 @@ void transition_enc_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, -#else - L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, -#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -329,11 +325,7 @@ void transition_enc_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, -#else - st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, -#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* @@ -1042,11 +1034,7 @@ void transition_enc_ivas_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, -#else - L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, -#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -1158,11 +1146,7 @@ void transition_enc_ivas_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#ifdef NONBE_FIX_GSC_BSTR st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, -#else - st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, -#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index be86281ef..fb3a89350 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -72,10 +72,8 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; #define INV_TAN30_FX 28377 // Q14 #define EPSILON_MANT 1180591621 /* 1e-12 = 0.5497558*(2^-39) in Q70 */ #define EPSILON_EXP ( -39 ) -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC #define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ #define ONE_DIV_EPSILON_EXP ( 40 ) -#endif #define ADAPT_HTPROTO_ROT_LIM_1 0.8f #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */ @@ -135,10 +133,8 @@ static void matrixTransp2Mul_fx( Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx Word32 Ascale, Word32 Bscale, -#endif Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); @@ -813,12 +809,9 @@ static void ivas_dirac_dec_binaural_internal_fx( IF( hDiracDecBin->useTdDecorr ) { -#ifdef FIX_ISSUE_1185 Word32 tmp_arr[60]; -#endif FOR( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ ) { -#ifdef FIX_ISSUE_1185 q_cldfb[ch][slot] = sub( q_input, 1 ); move16(); @@ -836,15 +829,6 @@ static void ivas_dirac_dec_binaural_internal_fx( scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( q_input, st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) ); st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = q_input; move16(); -#else - q_cldfb[ch][slot] = q_input; - move16(); - cldfbAnalysis_ts_fx_fixed_q( - &( st_ivas->hTcBuffer->tc_fx[ch][nBins * slot + offsetSamples] ), - Cldfb_RealBuffer_in_fx[ch][slot], - Cldfb_ImagBuffer_in_fx[ch][slot], - nBins, st_ivas->cldfbAnaDec[ch], &q_cldfb[ch][slot] ); -#endif /*FIX_ISSUE_1185*/ test(); test(); @@ -886,10 +870,8 @@ static void ivas_dirac_dec_binaural_internal_fx( { scale_sig32( Cldfb_RealBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 scale_sig32( Cldfb_ImagBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 -#ifdef FIX_ISSUE_1185 q_cldfb[cha][slot] = 6; move16(); -#endif } } @@ -1983,10 +1965,8 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); matrixTransp2Mul_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx 1 /*int Ascale*/, 0 /*int Bscale*/, -#endif resultMtxRe_fx, resultMtxIm_fx, &q_res ); /* When below the frequency limit where decorrelation is applied, we inject the decorrelated @@ -2151,23 +2131,12 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); -#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT { tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp2 ); tmp2 = ISqrt32( tmp2, &exp2 ); gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) ); q_gain = sub( 31, add( exp2, exp1 ) ); } -#else - { - Word16 exp_temp; - tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - tmp2 = BASOP_Util_Divide3232_Scale_cadence( tmp1, tmp2, &exp ); - exp2 = add( exp, sub( exp1, exp_temp ) ); - } - gain_fx = Sqrt32( tmp2, &exp2 ); - q_gain = sub( 31, exp2 ); -#endif // 1073741824 = 4 in Q28 @@ -2610,11 +2579,7 @@ static void ivas_dirac_dec_binaural_process_output_fx( outSlotRePr_fx = &( outSlotRe_fx[0] ); outSlotImPr_fx = &( outSlotIm_fx[0] ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, 0, cldfbSynDec[chA] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 ); move16(); } @@ -3260,7 +3225,6 @@ static void eig2x2_fx( /* Numeric case, when input is practically zeros */ // IF( D_fx[0] < EPSILON_FX ) -#ifdef FIX_1326_SUBSTITUTE_CMPMANT32EXP IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) ) { Ure_fx[0][0] = ONE_IN_Q31; @@ -3272,19 +3236,6 @@ static void eig2x2_fx( return; } -#else - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( D_fx[0], *q_D, EPSILON_MANT, EPSILON_EXP ), -1 ) ) - { - Ure_fx[0][0] = ONE_IN_Q31; - move32(); - Ure_fx[1][1] = ONE_IN_Q31; - move32(); - *q_U = Q31; - move16(); - - return; - } -#endif /* Numeric case, when input is near an identity matrix with a gain */ tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31 @@ -3493,7 +3444,6 @@ static void eig2x2_fx( move16(); } } -#ifdef FIX_1326_SPEEDUP_eig2x2_fx if ( q_U_1 != 0 ) { *q_U = q_U_1; @@ -3505,17 +3455,6 @@ static void eig2x2_fx( *q_U = q_U_2; move16(); } -#else - IF( q_U_1 != 0 ) - { - *q_U = q_U_1; - } - ELSE - { - *q_U = q_U_2; - } - move16(); -#endif return; } @@ -3570,11 +3509,6 @@ static void matrixMul_fx( Word16 chA, chB; Word16 min_q_shift1, min_q_shift2; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); -#ifndef FIX_1113_OPT_DIRAC_BIN_REND -#ifndef IVAS_ENH64_CADENCE_CHANGES - Word32 tmp1, tmp2; -#endif -#endif min_q_shift1 = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); min_q_shift2 = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); @@ -3603,7 +3537,6 @@ static void matrixMul_fx( outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], Bim_fx[0][chB] ), Are_fx[chA][1], Bim_fx[1][chB] ) ) ); move32(); #else -#ifdef FIX_1113_OPT_DIRAC_BIN_REND outRe_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[0][chB] ), Are_fx[chA][1], Bre_fx[1][chB] ), Aim_fx[chA][0], Bim_fx[0][chB] ), @@ -3614,106 +3547,6 @@ static void matrixMul_fx( Are_fx[chA][0], Bim_fx[0][chB] ), Are_fx[chA][1], Bim_fx[1][chB] ); move32(); -#else - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && Bre_fx[0][chB] >= 0 ) || ( Are_fx[chA][0] < 0 && Bre_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Are_fx[chA][0], Bre_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( Bre_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && Bre_fx[1][chB] >= 0 ) || ( Are_fx[chA][1] < 0 && Bre_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Are_fx[chA][1], Bre_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( Bre_fx[1][chB] ) ) ); - } - outRe_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && Bim_fx[0][chB] >= 0 ) || ( Aim_fx[chA][0] < 0 && Bim_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Aim_fx[chA][0], Bim_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( Bim_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && Bim_fx[1][chB] >= 0 ) || ( Aim_fx[chA][1] < 0 && Bim_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Aim_fx[chA][1], Bim_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( Bim_fx[1][chB] ) ) ); - } - outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && Bre_fx[0][chB] >= 0 ) || ( Aim_fx[chA][0] < 0 && Bre_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Aim_fx[chA][0], Bre_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( Bre_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && Bre_fx[1][chB] >= 0 ) || ( Aim_fx[chA][1] < 0 && Bre_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Aim_fx[chA][1], Bre_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( Bre_fx[1][chB] ) ) ); - } - outIm_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && Bim_fx[0][chB] >= 0 ) || ( Are_fx[chA][0] < 0 && Bim_fx[0][chB] < 0 ) ) - { - tmp1 = Mpy_32_32( Are_fx[chA][0], Bim_fx[0][chB] ); - } - ELSE - { - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( Bim_fx[0][chB] ) ) ); - } - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && Bim_fx[1][chB] >= 0 ) || ( Are_fx[chA][1] < 0 && Bim_fx[1][chB] < 0 ) ) - { - tmp2 = Mpy_32_32( Are_fx[chA][1], Bim_fx[1][chB] ); - } - ELSE - { - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( Bim_fx[1][chB] ) ) ); - } - outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); -#endif #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */ } } @@ -3742,15 +3575,11 @@ static void matrixTransp1Mul_fx( { Word16 chA, chB; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); -#ifndef FIX_1113_OPT_DIRAC_BIN_REND - Word32 tmp1, tmp2; -#endif FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { -#ifdef FIX_1113_OPT_DIRAC_BIN_REND outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), Are_fx[1][chA], Bre_fx[1][chB] ), Aim_fx[0][chA], Bim_fx[0][chB] ), @@ -3761,74 +3590,6 @@ static void matrixTransp1Mul_fx( Aim_fx[0][chA], Bre_fx[0][chB] ), Aim_fx[1][chA], Bre_fx[1][chB] ); move32(); -#else - test(); - test(); - test(); - IF( ( ( ( Are_fx[0][chA] >= 0 ) && ( Bre_fx[0][chB] >= 0 ) ) || ( ( Are_fx[0][chA] < 0 ) && ( Bre_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( Are_fx[0][chA], Bre_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[0][chA] ), L_abs( Bre_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Are_fx[1][chA] >= 0 ) && ( Bre_fx[1][chB] >= 0 ) ) || ( ( Are_fx[1][chA] < 0 ) && ( Bre_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Are_fx[1][chA], Bre_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[1][chA] ), L_abs( Bre_fx[1][chB] ) ) ); - outRe_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - test(); - test(); - test(); - IF( ( ( ( L_negate( Aim_fx[0][chA] ) >= 0 ) && ( Bim_fx[0][chB] >= 0 ) ) || ( ( L_negate( Aim_fx[0][chA] ) < 0 ) && ( Bim_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( -Aim_fx[0][chA], Bim_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( -Aim_fx[0][chA] ), L_abs( Bim_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Aim_fx[1][chA] >= 0 ) && ( Bim_fx[1][chB] >= 0 ) ) || ( ( Aim_fx[1][chA] < 0 ) && ( Bim_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Aim_fx[1][chA], Bim_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[1][chA] ), L_abs( Bim_fx[1][chB] ) ) ); - outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], L_sub( tmp1, tmp2 ) ); - move32(); - - test(); - test(); - test(); - IF( ( ( ( L_negate( Aim_fx[0][chA] ) >= 0 ) && ( Bre_fx[0][chB] >= 0 ) ) || ( ( L_negate( Aim_fx[0][chA] ) < 0 ) && ( Bre_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( -Aim_fx[0][chA], Bre_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( -Aim_fx[0][chA] ), L_abs( Bre_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Aim_fx[1][chA] >= 0 ) && ( Bre_fx[1][chB] >= 0 ) ) || ( ( Aim_fx[1][chA] < 0 ) && ( Bre_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Aim_fx[1][chA], Bre_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[1][chA] ), L_abs( Bre_fx[1][chB] ) ) ); - outIm_fx[chA][chB] = L_sub( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( ( ( Are_fx[0][chA] >= 0 ) && ( Bim_fx[0][chB] >= 0 ) ) || ( ( Are_fx[0][chA] < 0 ) && ( Bim_fx[0][chB] < 0 ) ) ) ) - tmp1 = Mpy_32_32( Are_fx[0][chA], Bim_fx[0][chB] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[0][chA] ), L_abs( Bim_fx[0][chB] ) ) ); - test(); - test(); - test(); - IF( ( ( ( Are_fx[1][chA] >= 0 ) && ( Bim_fx[1][chB] >= 0 ) ) || ( ( Are_fx[1][chA] < 0 ) && ( Bim_fx[1][chB] < 0 ) ) ) ) - tmp2 = Mpy_32_32( Are_fx[1][chA], Bim_fx[1][chB] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[1][chA] ), L_abs( Bim_fx[1][chB] ) ) ); - outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); -#endif } } *q_out = sub( add( q_A, q_B ), 31 ); @@ -3850,10 +3611,8 @@ static void matrixTransp2Mul_fx( Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx Word32 Ascale, Word32 Bscale, -#endif Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) @@ -3861,15 +3620,8 @@ static void matrixTransp2Mul_fx( Word16 chA, chB; Word16 min_q_shift; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); -#ifndef FIX_1113_OPT_DIRAC_BIN_REND -#ifndef IVAS_ENH64_CADENCE_CHANGES - Word32 tmp1, tmp2; -#endif -#endif -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx IF( Ascale == 1 ) -#endif { min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); scale_sig32( Are_fx[0], size, min_q_shift ); @@ -3878,9 +3630,7 @@ static void matrixTransp2Mul_fx( move16(); } -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx IF( Bscale == 1 ) -#endif { min_q_shift = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); scale_sig32( Bre_fx[0], size, min_q_shift ); @@ -3903,7 +3653,6 @@ static void matrixTransp2Mul_fx( outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], L_negate( Bim_fx[chB][0] ) ), Are_fx[chA][1], L_negate( Bim_fx[chB][1] ) ) ) ); move32(); #else -#ifdef FIX_1113_OPT_DIRAC_BIN_REND outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[chB][0] ), Are_fx[chA][1], Bre_fx[chB][1] ), Aim_fx[chA][0], Bim_fx[chB][0] ), @@ -3914,75 +3663,6 @@ static void matrixTransp2Mul_fx( Are_fx[chA][0], Bim_fx[chB][0] ), Are_fx[chA][1], Bim_fx[chB][1] ); move32(); -#else - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && Bre_fx[chB][0] >= 0 ) || ( Are_fx[chA][0] < 0 && Bre_fx[chB][0] < 0 ) ) - tmp1 = Mpy_32_32( Are_fx[chA][0], Bre_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( Bre_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && Bre_fx[chB][1] >= 0 ) || ( Are_fx[chA][1] < 0 && Bre_fx[chB][1] < 0 ) ) - tmp2 = Mpy_32_32( Are_fx[chA][1], Bre_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( Bre_fx[chB][1] ) ) ); - outRe_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && L_negate( Bim_fx[chB][0] ) >= 0 ) || ( Aim_fx[chA][0] < 0 && L_negate( Bim_fx[chB][0] ) < 0 ) ) - tmp1 = Mpy_32_32( Aim_fx[chA][0], -Bim_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( -Bim_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && L_negate( Bim_fx[chB][1] ) >= 0 ) || ( Aim_fx[chA][1] < 0 && L_negate( Bim_fx[chB][1] ) < 0 ) ) - tmp2 = Mpy_32_32( Aim_fx[chA][1], -Bim_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( -Bim_fx[chB][1] ) ) ); - outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); - - test(); - test(); - test(); - IF( ( Aim_fx[chA][0] >= 0 && Bre_fx[chB][0] >= 0 ) || ( Aim_fx[chA][0] < 0 && Bre_fx[chB][0] < 0 ) ) - tmp1 = Mpy_32_32( Aim_fx[chA][0], Bre_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][0] ), L_abs( Bre_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Aim_fx[chA][1] >= 0 && Bre_fx[chB][1] >= 0 ) || ( Aim_fx[chA][1] < 0 && Bre_fx[chB][1] < 0 ) ) - tmp2 = Mpy_32_32( Aim_fx[chA][1], Bre_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Aim_fx[chA][1] ), L_abs( Bre_fx[chB][1] ) ) ); - outIm_fx[chA][chB] = L_add( tmp1, tmp2 ); - move32(); - - test(); - test(); - test(); - IF( ( Are_fx[chA][0] >= 0 && L_negate( Bim_fx[chB][0] ) >= 0 ) || ( Are_fx[chA][0] < 0 && L_negate( Bim_fx[chB][0] ) < 0 ) ) - tmp1 = Mpy_32_32( Are_fx[chA][0], -Bim_fx[chB][0] ); - ELSE - tmp1 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][0] ), L_abs( -Bim_fx[chB][0] ) ) ); - test(); - test(); - test(); - IF( ( Are_fx[chA][1] >= 0 && L_negate( Bim_fx[chB][1] ) >= 0 ) || ( Are_fx[chA][1] < 0 && L_negate( Bim_fx[chB][1] ) < 0 ) ) - tmp2 = Mpy_32_32( Are_fx[chA][1], -Bim_fx[chB][1] ); - ELSE - tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( -Bim_fx[chB][1] ) ) ); - outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); - move32(); -#endif #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */ } } @@ -4057,15 +3737,6 @@ static void chol2x2_fx( } ELSE { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - outRe[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[0][0], &exp ); - move32(); - q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); - - outIm[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_im, outRe[0][0], &exp ); - move32(); - q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); -#else Word32 denom; Word16 den_exp; Word32 my_outRe, my_outIm; @@ -4091,7 +3762,6 @@ static void chol2x2_fx( outIm[1][0] = Mpy_32_32( denom, my_outIm ); move32(); q_im = sub( q_im, den_exp ); -#endif } if ( outRe[1][0] == 0 ) { @@ -4110,16 +3780,11 @@ static void chol2x2_fx( // 4611686 = Q62 IF( e1 == 0 ) { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( temp, 4611686, &exp ); - q_tmp = add( sub( 31, exp ), sub( q_tmp, 62 ) ); -#else Word16 norm = norm_l( temp ); temp = L_shl( temp, norm ); q_tmp = add( q_tmp, norm ); temp = Mpy_32_32( temp, ONE_DIV_EPSILON_MANT ); q_tmp = sub( q_tmp, ONE_DIV_EPSILON_EXP ); -#endif } ELSE { @@ -4168,16 +3833,6 @@ static void chol2x2_fx( // 4611686 = Q62 IF( outRe[1][1] == 0 ) { -#if !defined( FIX_1072_REDUCE_DIVS ) - outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); - move32(); - q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) ); - - outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, 4611686, &exp ); - move32(); - q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); - -#else // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); Word32 tmp1 = 1953125005; /* 1/4611686 Q62 */ exp = 9; @@ -4190,19 +3845,9 @@ static void chol2x2_fx( outIm[0][1] = Mpy_32_32( tmp1, -c_im ); move32(); q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); -#endif } ELSE { -#if !defined( FIX_1072_REDUCE_DIVS ) - outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); - move32(); - q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); - - outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, outRe[1][1], &exp ); - move32(); - q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); -#else { // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); Word32 tmp1 = BASOP_Util_Divide3232_Scale_cadence( 0x7FFFFFFF, outRe[1][1], &exp ); @@ -4215,7 +3860,6 @@ static void chol2x2_fx( move32(); q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); } -#endif } if ( outRe[0][1] == 0 ) { @@ -4380,15 +4024,10 @@ static void formulate2x2MixingMatrix_fx( // 4611686 = Q62 IF( maxEne_fx == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC maxEneDiv_fx = ONE_DIV_EPSILON_MANT; move32(); q_maxEneDiv = 31 - ONE_DIV_EPSILON_EXP; move16(); -#else - maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12f in Q62 - q_maxEneDiv = add( sub( 31, exp ), sub( Q30, 62 ) ); -#endif } ELSE { @@ -4448,7 +4087,6 @@ static void formulate2x2MixingMatrix_fx( IF( temp == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC IF( E_out1 == 0 ) { Ghat_fx[0] = 0; @@ -4462,10 +4100,6 @@ static void formulate2x2MixingMatrix_fx( exp = sub( exp, sub( q_eout, 62 ) ); Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp } -#else - temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, 4611686, &exp ); // 4611686 = Q62 - exp = sub( exp, sub( q_eout, 62 ) ); -#endif } ELSE { @@ -4473,20 +4107,14 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp -#endif } -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp -#endif move32(); temp = Mpy_32_32( E_in1, 2147484 ); // 2147484 = 0.001f in Q31 temp = L_max( temp, E_in2 ); // q_ein IF( temp == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC IF( E_out2 == 0 ) { /* We can set hard-coded results */ Ghat_fx[1] = 0; @@ -4499,10 +4127,6 @@ static void formulate2x2MixingMatrix_fx( exp1 = sub( exp1, sub( q_eout, 62 ) ); Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 } -#else - temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 - exp1 = sub( exp1, sub( q_eout, 62 ) ); -#endif } ELSE { @@ -4510,13 +4134,8 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 -#endif } -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 -#endif move32(); q_Ghat = sub( 31, s_max( exp, exp1 ) ); @@ -4565,15 +4184,10 @@ static void formulate2x2MixingMatrix_fx( IF( D_fx[0] == 0 ) { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 - exp = sub( exp, sub( Q30, 62 ) ); -#else temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ move32(); exp = ONE_DIV_EPSILON_EXP; move16(); -#endif } ELSE { @@ -4583,7 +4197,6 @@ static void formulate2x2MixingMatrix_fx( div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); -#ifdef FIX_1326_SUBSTITUTE_DIV_SQRT_IOSQRT // Sqrt(1) div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1 exp1 = add( 0, 20 ); @@ -4594,25 +4207,6 @@ static void formulate2x2MixingMatrix_fx( div_fx[1] = ISqrt32( D_fx[1], &exp1 ); move32(); } -#else - IF( D_fx[1] == 0 ) - { -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp1 ); // 4611686 = 1e-12 in Q62 - exp1 = sub( exp1, sub( Q30, 62 ) ); -#else - temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ - exp1 = ONE_DIV_EPSILON_EXP; -#endif - } - ELSE - { - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); - exp1 = sub( exp1, sub( Q30, q_D ) ); - } - div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 - move32(); -#endif q_div = sub( 31, s_max( exp, exp1 ) ); div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); // q_div @@ -4704,10 +4298,8 @@ static void formulate2x2MixingMatrix_fx( } matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx 1 /*int Ascale*/, 0 /*int Bscale*/, -#endif Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ @@ -4718,7 +4310,6 @@ static void formulate2x2MixingMatrix_fx( { IF( Sx_fx[chB] == 0 ) { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Pre_fx[chA][chB] = Mpy_32_32( Pre_fx[chA][chB], ONE_DIV_EPSILON_MANT ); // q_Pre[chA][chB] = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP); q_Pre[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); @@ -4727,26 +4318,12 @@ static void formulate2x2MixingMatrix_fx( Pim_fx[chA][chB] = Mpy_32_32( Pim_fx[chA][chB], ONE_DIV_EPSILON_MANT ); // q_Pim[chA][chB] = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP); q_Pim[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); -#else - Pre_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pre_fx[chA][chB], 4611686, &exp ); // 4611686 = 1e-12 in Q62 - q_Pre[chA][chB] = add( sub( q_P, 62 ), sub( 31, exp ) ); - Pim_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pim_fx[chA][chB], 4611686, &exp ); // 4611686 = 1e-12 in Q62 - q_Pim[chA][chB] = add( sub( q_P, 62 ), sub( 31, exp ) ); -#endif } ELSE { -#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Word16 Pre_shift, Pim_shift; -#endif temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); -#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC - Pre_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pre_fx[chA][chB], temp, &exp ); - q_Pre[chA][chB] = add( sub( q_P, sub( 31, exp_temp ) ), sub( 31, exp ) ); - Pim_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pim_fx[chA][chB], temp, &exp ); - q_Pim[chA][chB] = add( sub( q_P, sub( 31, exp_temp ) ), sub( 31, exp ) ); -#else temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); Pre_shift = norm_l( Pre_fx[chA][chB] ); Pim_shift = norm_l( Pim_fx[chA][chB] ); @@ -4755,7 +4332,6 @@ static void formulate2x2MixingMatrix_fx( q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); q_Pre[chA][chB] = add( q_temp, Pre_shift ); q_Pim[chA][chB] = add( q_temp, Pim_shift ); -#endif } if ( Pre_fx[chA][chB] == 0 ) { @@ -4858,10 +4434,8 @@ static void formulate2x2MixingMatrix_fx( matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp ); matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, -#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx 1 /*int Ascale*/, 0 /*int Bscale*/, -#endif Mre_fx, Mim_fx, q_M ); return; } diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 1ffe0da74..1afac99c4 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -55,12 +55,10 @@ #define DIRAC_DUCK_ALPHA_FX 1717986944 /* Q31 */ #define ONE_M_DIRAC_DUCK_ALPHA 429496736 /* Q31 */ -#ifdef FIX_1110_OPTIM_DIRAC_DECORR_PROC /* Maximal useful q-format, represents range of 2^-126 (float min) */ #define MAX_Q_FX 157 -#endif /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ @@ -590,18 +588,6 @@ void ivas_dirac_dec_decorr_process_fx( Word16 decorr_buff_tot_len = imult1616( imult1616( shl( decorr_buffer_len, 1 ), max_band_decorr ), num_channels ); guarded_bits = 0; -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - FOR( Word16 i = 0; i < decorr_buff_tot_len; i++ ) - { - IF( h_freq_domain_decorr_ap_state->decorr_buffer_fx[i] != 0 ) - { - guarded_bits = s_max( find_guarded_bits_fx( 2 ), 3 ); - } - } - q_shift = sub( getScaleFactor32( h_freq_domain_decorr_ap_state->decorr_buffer_fx, decorr_buff_tot_len ), guarded_bits ); - Scale_sig32( h_freq_domain_decorr_ap_state->decorr_buffer_fx, decorr_buff_tot_len, q_shift ); - q_decorr_buf = add( q_decorr_buf, q_shift ); -#else Flag is_zero = is_zero_arr( h_freq_domain_decorr_ap_state->decorr_buffer_fx, decorr_buff_tot_len ); if ( is_zero == 0 ) { @@ -617,7 +603,6 @@ void ivas_dirac_dec_decorr_process_fx( q_decorr_buf = add( q_decorr_buf, q_shift ); } } -#endif q_shift = getScaleFactor32( aux_buffer_fx, imult1616( imult1616( 2, num_protos_dir ), max_band_decorr_temp ) ); Word16 buf_len = shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ); @@ -681,15 +666,8 @@ void ivas_dirac_dec_decorr_process_fx( /* MA part of filter impulse response */ FOR( l = 0; l < filter_length; l++ ) { -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - frame_ma_fx[2 * l] = Mpy_32_16_1( input_real_fx, filter_coeff_num_real_fx[l] ); // Q_qux -3 = q_deorr - // frame_ma_fx[2 * l] = L_shr(frame_ma_fx[2 * l],3); // scaling to q_decorr_buf - frame_ma_fx[add( shl( l, 1 ), 1 )] = Mpy_32_16_1( input_imag_fx, filter_coeff_num_real_fx[l] ); // Q_qux - 3 = q_deorr - // frame_ma_fx[2 * l + 1] = L_shr(frame_ma_fx[2 * l + 1], 3); // scaling to q_decorr_buf -#else frame_ma_fx[2 * l] = Mpy_32_16_1( input_real_fx, filter_coeff_num_real_fx[l] ); // Q_qux -3 = q_deorr frame_ma_fx[2 * l + 1] = Mpy_32_16_1( input_imag_fx, filter_coeff_num_real_fx[l] ); // Q_qux - 3 = q_deorr -#endif move32(); move32(); } @@ -705,32 +683,14 @@ void ivas_dirac_dec_decorr_process_fx( filter_frame_real_fx = decorr_buffer_ptr_fx[0]; // q_decorr filter_frame_imag_fx = decorr_buffer_ptr_fx[1]; // q_decorr -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - decorr_buffer_ptr_fx += shl( decorr_buffer_step, 1 ); -#else Word16 decorr_buffer_step2x = shl( decorr_buffer_step, 1 ); decorr_buffer_ptr_fx += decorr_buffer_step2x; move16(); -#endif FOR( l = 1; l < filter_length; l++ ) { // q adjustment needed// -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - decorr_buffer_ptr_fx[0] = L_add( decorr_buffer_ptr_fx[0], frame_ma_fx[2 * l] ); // q_decorr - Word32 temp_1 = Mpy_32_16_1( filter_frame_real_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 - temp_1 = L_shl( temp_1, 3 ); // q_decorr - decorr_buffer_ptr_fx[0] = L_sub( decorr_buffer_ptr_fx[0], temp_1 ); // q_deocor - decorr_buffer_ptr_fx[1] = L_add( decorr_buffer_ptr_fx[1], frame_ma_fx[add( shl( l, 1 ), 1 )] ); // q_decorr - Word32 temp_2 = Mpy_32_16_1( filter_frame_imag_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 - temp_2 = L_shl( temp_2, 3 ); // q_decorr - decorr_buffer_ptr_fx[1] = L_sub( decorr_buffer_ptr_fx[1], temp_2 ); // q_decorr - decorr_buffer_ptr_fx += imult1616( 2, decorr_buffer_step ); - move32(); - move32(); - move32(); -#else Word32 temp_1 = Mpy_32_16_1( filter_frame_real_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 temp_1 = L_shl( temp_1, 3 ); // q_decorr decorr_buffer_ptr_fx[0] = L_sub( L_add( decorr_buffer_ptr_fx[0], frame_ma_fx[2 * l] ), temp_1 ); // q_deocor @@ -743,7 +703,6 @@ void ivas_dirac_dec_decorr_process_fx( decorr_buffer_ptr_fx += decorr_buffer_step2x; move16(); -#endif } } } @@ -764,7 +723,6 @@ void ivas_dirac_dec_decorr_process_fx( e_direct_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); // scaling to get max precision for aux_buffer values// -#ifdef MSAN_FIX q_shift = Q31; move16(); offset = shl( max_band_decorr, 1 ); @@ -777,10 +735,6 @@ void ivas_dirac_dec_decorr_process_fx( { scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], offset, q_shift ); } -#else - q_shift = L_norm_arr( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels ); - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); -#endif q_frame_f = add( q_frame_f, q_shift ); @@ -802,24 +756,8 @@ void ivas_dirac_dec_decorr_process_fx( q_direct_energy = q_aux_buffer; move16(); -#ifdef FIX_1110_OPTIM_DIRAC_DECORR_PROC /* Attention: this loop reports norm=0, whenever any data is 0. */ /* Therefore, useful left-shifts are skipped, accuracy is lost. */ -#endif -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - /* calculate the power of the decorrelated signal */ - FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) - { - offset1 = shl( imult1616( ch_idx, num_freq_bands ), 1 ); - offset2 = shl( imult1616( ch_idx, max_band_decorr ), 1 ); - FOR( Word16 i = 0; i < 2 * max_band_decorr; i++ ) - { - aux_64[add( offset2, i )] = W_mult0_32_32( frame_dec_fx[add( offset1, i )], frame_dec_fx[add( offset1, i )] ); - move64(); - norm = s_min( norm, W_norm( aux_64[add( offset2, i )] ) ); - } - } -#else /* calculate the power of the decorrelated signal */ Word64 *m64_aux = aux_64; move32(); @@ -849,7 +787,6 @@ void ivas_dirac_dec_decorr_process_fx( move32(); } norm = W_norm( min64 ); -#endif norm = sub( norm, 1 /*find_guarded_bits_fx( 2 )*/ ); FOR( Word16 i = 0; i < 2 * num_channels * max_band_decorr; i++ ) { @@ -866,34 +803,6 @@ void ivas_dirac_dec_decorr_process_fx( /* smooth energies */ -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - v_multc_fixed( aux_buffer_fx, ONE_M_DIRAC_DUCK_ALPHA, aux_buffer_fx, imult1616( num_channels, max_band_decorr ) ); // q_aux_buffer - - v_multc_fixed( h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, DIRAC_DUCK_ALPHA_FX, h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, imult1616( num_channels, max_band_decorr ) ); // same-q - - v_add_fixed_me( aux_buffer_fx, sub( 31, q_aux_buffer ), h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, e_reverb_energy_smooth, h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, &e_reverb_energy_smooth, imult1616( num_channels, max_band_decorr ), 0 ); - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = sub( 31, e_reverb_energy_smooth ); - - v_multc_fixed( direct_energy_fx, ONE_M_DIRAC_DUCK_ALPHA, direct_energy_fx, imult1616( num_protos_dir, max_band_decorr ) ); // same q - - v_multc_fixed( h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, DIRAC_DUCK_ALPHA_FX, h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, imult1616( num_protos_dir, max_band_decorr ) ); // same q - - v_add_fixed_me( direct_energy_fx, sub( 31, q_direct_energy ), h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, e_direct_energy_smooth, h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, &e_direct_energy_smooth, imult1616( num_protos_dir, max_band_decorr ), 0 ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = sub( 31, e_direct_energy_smooth ); - move16(); - - // scaling energy buffers for better precision for higher values// - q_shift = L_norm_arr( h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, imult1616( num_protos_dir, max_band_decorr ) ); - Scale_sig32( h_freq_domain_decorr_ap_state->direct_energy_smooth_fx, imult1616( num_protos_dir, max_band_decorr ), q_shift ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = add( h_freq_domain_decorr_ap_state->q_direct_energy_smooth, q_shift ); - move16(); - - - q_shift = L_norm_arr( h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, imult1616( num_channels, max_band_decorr ) ); - Scale_sig32( h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx, imult1616( num_channels, max_band_decorr ), q_shift ); - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = add( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth, q_shift ); - move16(); -#else Word16 len = imult1616( num_channels, max_band_decorr ); Word16 aux_e = sub( 31, q_aux_buffer ); Word16 max_e = s_max( aux_e, e_reverb_energy_smooth ); @@ -950,13 +859,11 @@ void ivas_dirac_dec_decorr_process_fx( } h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); h_freq_domain_decorr_ap_state->q_direct_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); -#endif e_reverb_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); e_direct_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); // this step is b/c we are left shifting frame_dec_fx at the end of below for loop/ -#ifdef MSAN_FIX q_shift = Q31; move16(); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -969,10 +876,6 @@ void ivas_dirac_dec_decorr_process_fx( { Scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); } -#else - q_shift = sub( L_norm_arr( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels ), 2 ); - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); -#endif q_frame_f = add( q_frame_f, q_shift ); FOR( ch_idx = 0; ch_idx < num_channels; ch_idx++ ) @@ -1006,13 +909,8 @@ void ivas_dirac_dec_decorr_process_fx( duck_gain = shl( duck_gain, sub( e_duck_gain, 1 ) ); // Q14 -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_f - frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )], duck_gain ), 1 ); // q_frame_f -#else frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_f frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 1 ); // q_frame_f -#endif move32(); move32(); } @@ -1029,13 +927,8 @@ void ivas_dirac_dec_decorr_process_fx( } */ duck_gain = shl_sat( duck_gain, sub( e_duck_gain, 1 ) ); // Q14 -#ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC - frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 2 ); // q_frame_dec - frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )], duck_gain ), 2 ); // q_frame_dec -#else frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_dec frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 1 ); // q_frame_dec -#endif move32(); move32(); } @@ -1061,27 +954,19 @@ void ivas_dirac_dec_decorr_process_fx( q_shift = sf; move16(); // scaling it to sf -#ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } -#else - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q -#endif q_frame_f = add( q_frame_f, sf ); } ELSE IF( q_shift < 0 ) { // scaling it to input q -#ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } -#else - Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q -#endif q_frame_f = q_input_frame; q_if_local = 0; move16(); diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index d42340ca1..7d3379ae7 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -1097,7 +1097,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { -#ifdef FIX_1072_SPEEDUP_gainpanning /*is there any difference in any bitstream?*/ Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); FOR( Word16 kk = 0; kk < tmp16; kk++ ) { @@ -1106,17 +1105,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); -#else - FOR( Word16 kk = 0; kk < tmp16; kk++ ) - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ - move32(); - } - h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; - move16(); -#endif } -#ifdef FIX_1072_SPEEDUP_gainpanning Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { @@ -1126,11 +1115,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word32 aux; IF( temp_q1 < 0 ) { -#ifdef FIX_USAN_ISSUES Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 ); -#else - Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); -#endif FOR( i = 0; i < num_freq_bands; i++ ) { aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); @@ -1160,25 +1145,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } } -#else - FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) - { - v_mult_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx, - &h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands], - aux_buf, - num_freq_bands ); /*temp_q*/ - - IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) - { - Scale_sig32( aux_buf, num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ) ); /*temp_q->(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ - } - - v_add_fixed( aux_buf, - &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], - &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], - num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ - } -#endif /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index cd5c5d281..6eec3ca40 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -778,9 +778,7 @@ ivas_error ivas_dirac_alloc_mem_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->frame_dec_f_fx, 2 * num_outputs_diff * num_freq_bands ); -#endif hDirAC_mem->frame_dec_f_len = imult1616( imult1616( 2, num_outputs_diff ), num_freq_bands ); } } @@ -824,12 +822,7 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_len = size_ho; move16(); -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->cy_cross_dir_smooth_fx, size_ho ); -#else - set_zero_fx( hDirAC_mem->cy_cross_dir_smooth_fx, size ); - hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_len = size_ho; -#endif IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { @@ -881,9 +874,7 @@ ivas_error ivas_dirac_alloc_mem_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands ); -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->proto_direct_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len ); -#endif move16(); hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31; move16(); @@ -907,9 +898,7 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirAC_mem->proto_diffuse_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_outputs_diff ), num_freq_bands ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->proto_diffuse_buffer_f_fx, hDirAC_mem->proto_diffuse_buffer_f_len ); -#endif } } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx = hDirAC_mem->proto_direct_buffer_f_fx; @@ -983,9 +972,7 @@ ivas_error ivas_dirac_alloc_mem_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->onset_filter_fx, imult1616( num_outputs_diff, num_freq_bands ) ); -#endif } } } @@ -1007,9 +994,7 @@ ivas_error ivas_dirac_alloc_mem_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } -#ifdef MSAN_FIX set_zero_fx( hDirAC_mem->onset_filter_fx, imult1616( 2, num_freq_bands ) ); -#endif } } @@ -1803,11 +1788,7 @@ void protoSignalComputation2_fx( q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], num_freq_bands ), L_norm_arr( ImagBuffer_fx[l][0], num_freq_bands ) ); min_q_shift = s_min( min_q_shift, q_shift ); -#ifdef MSAN_FIX q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ); -#else - q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ), L_norm_arr( ImagBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ) ); -#endif // MSAN_FIX temp_q_shift = s_min( temp_q_shift, q_shift ); } @@ -3160,13 +3141,8 @@ void ivas_dirac_dec_compute_diffuse_proto_fx( Word16 new_diff_e = s_max( diff_e, old_diff_e ); Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx, diffuse_start, sub( old_diff_e, new_diff_e ) ); // 31-new_diff_e -#ifdef MSAN_FIX Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx + diffuse_start, i_mult( shl( num_freq_bands_diff, 1 ), hDirACRend->hOutSetup.nchan_out_woLFE ), sub( diff_e, new_diff_e ) ); // 31-new_diff_e -#else - Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx + diffuse_start, - sub( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_len, diffuse_start ), sub( diff_e, new_diff_e ) ); -#endif h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q = sub( 31, new_diff_e ); move16(); @@ -3357,10 +3333,8 @@ void ivas_masa_init_stereotype_detection_fx( move16(); stereo_type_detect->target_power_y_smooth_fx = 0; move32(); -#ifdef MSAN_FIX stereo_type_detect->q_target_power_y_smooth = 31; move16(); -#endif stereo_type_detect->lr_total_bb_ratio_db_fx = 0; move32(); @@ -4875,11 +4849,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; // q_cldfb } Word16 out_size = imult1616( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); -#ifdef OPT_SBA_AVOID_SPAR_RESCALE cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, 0, hMasaExtRend->cldfbSynRend[idx_in] ); -#else /* OPT_SBA_AVOID_SPAR_RESCALE */ - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, hMasaExtRend->cldfbSynRend[idx_in] ); -#endif /* OPT_SBA_AVOID_SPAR_RESCALE */ scale_sig32( &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, sub( 11, q_out ) ); // q11 idx_in++; } diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index f3b4d1755..d5df77045 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -754,10 +754,8 @@ void ivas_mcmasa_param_est_ana_fx( computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) -#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC , NULL -#endif ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index 01e35efe1..30bf8f00a 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -393,9 +393,7 @@ static void GenerateITD_fx( Word16 num_az_idx, num_ev_idx; Word16 BM_idx[HRTF_MODEL_BSPLINE_NUM_COEFFS_SQ]; Word16 itdMod_e; -#ifdef MSAN_FIX set16_fx( AzIdx, 0, HRTF_MODEL_BSPLINE_NUM_COEFFS ); -#endif // MSAN_FIX /* Wrap the requested azimuth to the range of the BSplines */ azim_fx = L_add( azim_fx, model->azimKSeq_fx[0] ); diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 5787ded3f..7e35b80b2 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -573,10 +573,8 @@ static void TDREND_SRC_SPATIAL_Init_fx( TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, ONE_IN_Q30 ); /*Assuming Q30*/ } -#ifdef MSAN_FIX SrcSpatial_p->q_Pos_p = Q31; move16(); -#endif /* Source directional attenuation */ SrcSpatial_p->DirAttenEnabled = FALSE; // Q0 diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c index 8beb5a0ec..3b01f62ca 100644 --- a/lib_rend/ivas_output_init_fx.c +++ b/lib_rend/ivas_output_init_fx.c @@ -1,9 +1,7 @@ #include "ivas_prot_fx.h" #include "ivas_prot_rend_fx.h" -#ifdef FIX_DISCLAIMER #include -#endif Word16 ivas_get_nchan_buffers_dec_ivas_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -161,7 +159,6 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx( return nchan_out_buff; } -#ifdef FIX_DISCLAIMER /*---------------------------------------------------------------------* * get_channel_config() * @@ -272,4 +269,3 @@ ivas_error get_channel_config( return IVAS_ERR_OK; } -#endif diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index a5ee232df..983c814aa 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -81,12 +81,10 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx( const Word32 ivas_total_brate /* i : total IVAS bitrate */ ); -#ifdef FIX_DISCLAIMER ivas_error get_channel_config( const AUDIO_CONFIG config, /* i : audio configuration */ Word8 *str /* o : string with the configuration name */ ); -#endif /*----------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 870f8795d..9b149940c 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1529,9 +1529,7 @@ ivas_error ivas_reverb_open_fx( params.pDsr_fx = params.pRt60_fx + nr_fc_fft_filter; params.pFc_fx = &pState->fft_filter_color_0.fft_spectrum_fx[0]; params.pHrtf_inter_aural_coherence_fx = &pState->fft_filter_color_1.fft_spectrum_fx[0]; -#ifdef MSAN_FIX set32_fx( pState->fft_filter_color_1.fft_spectrum_fx, 0, RV_FILTER_MAX_FFT_SIZE ); -#endif /* Note: these temp buffers can only be used before the final step of the FFT filter design : */ /* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */ @@ -1647,18 +1645,11 @@ ivas_error ivas_reverb_open_fx( IF( pState->do_corr_filter ) { /* Computing correlation filters on the basis of target IA coherence */ -#ifdef MSAN_FIX FOR( i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ move32(); } -#else - FOR( i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) - { - pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ - } -#endif // MSAN_FIX Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) ); FOR( i = 0; i < nr_fc_fft_filter; i++ ) diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index aebb80a54..e6f8f2653 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -2271,12 +2271,10 @@ void SHrotmatgen_fx( Word16 R_lm1[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM]; -#ifdef MSAN_FIX FOR( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { set16_fx( R_lm1[i], 0, HEADROT_SHMAT_DIM ); } -#endif Word16 R_l[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM]; Word32 result; SHrotmat[0][0] = ONE_IN_Q14; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 378ae7aad..0515e4038 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -683,11 +683,7 @@ typedef struct ivas_binaural_rendering_conv_module_struct_fx Word32 ***filterStatesLeftReal_fx; Word32 ***filterStatesLeftImag_fx; -#ifdef OPT_BASOP_ADD_v1 Word16 Q_filterStatesLeft; -#else /* OPT_BASOP_ADD_v1 */ - Word16 ***Q_filterStatesLeft; -#endif /* OPT_BASOP_ADD_v1 */ Word16 numTapsArray[BINAURAL_CONVBANDS]; Word16 numTaps; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 31110fe26..a25037153 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8557,7 +8557,6 @@ static void intermidiate_ext_dirac_render( } } -#ifdef FIX_DISCLAIMER static ivas_error printConfigInfo_rend( IVAS_REND_HANDLE hIvasRend /* i : IVAS renderer handle */ ) @@ -8650,4 +8649,3 @@ void IVAS_REND_PrintDisclaimer( void ) return; } -#endif diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 0a489600a..e837daa4f 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -324,7 +324,6 @@ void IVAS_REND_Close( ); -#ifdef FIX_DISCLAIMER /* Disclaimer and info printing */ void IVAS_REND_PrintInputConfig( @@ -338,7 +337,6 @@ ivas_error IVAS_REND_PrintConfig( void IVAS_REND_PrintDisclaimer( void ); -#endif /* clang-format on */ diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index e667dcfe5..c2e3d8a2a 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1201,11 +1201,7 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); -#ifdef MSAN_FIX floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRImag_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); -#else - floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); -#endif } } } -- GitLab From 85432c38684fba09d6e9b7978a71e3f0bb3ae957 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 16:13:40 +0530 Subject: [PATCH 0629/1221] Clang formatting --- lib_com/bits_alloc_fx.c | 96 ++++++------ lib_com/cldfb.c | 8 +- lib_com/gs_inact_switching_fx.c | 22 +-- lib_com/ivas_dirac_com_fx.c | 3 +- lib_com/ivas_prot_fx.h | 3 +- lib_com/ivas_qmetadata_com_fx.c | 2 - lib_com/prot_fx.h | 130 ++++++++-------- lib_com/swb_bwe_com_fx.c | 4 +- lib_com/tools_fx.c | 50 +++--- lib_dec/FEC_HQ_phase_ecu_fx.c | 8 +- lib_dec/acelp_core_dec_ivas_fx.c | 38 ++--- lib_dec/fd_cng_dec_fx.c | 4 +- lib_dec/ivas_binRenderer_internal_fx.c | 3 - lib_dec/ivas_core_dec_fx.c | 10 +- lib_dec/ivas_mdct_core_dec_fx.c | 10 +- lib_dec/ivas_spar_decoder_fx.c | 2 +- lib_dec/ivas_stat_dec.h | 2 +- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 +- lib_dec/ivas_svd_dec_fx.c | 145 +++++++++--------- lib_enc/acelp_core_enc_fx.c | 2 +- lib_enc/cod_tcx_fx.c | 1 - lib_enc/core_enc_init_fx.c | 4 +- lib_enc/dtx_fx.c | 10 +- lib_enc/enc_acelpx_fx.c | 2 +- lib_enc/hq_core_enc_fx.c | 4 +- lib_enc/igf_enc.c | 4 +- lib_enc/ivas_core_pre_proc_front_fx.c | 14 +- lib_enc/ivas_dirac_enc_fx.c | 21 +-- lib_enc/ivas_mcmasa_enc_fx.c | 6 +- lib_enc/ivas_mdct_core_enc_fx.c | 12 +- lib_enc/ivas_omasa_enc_fx.c | 6 +- lib_enc/ivas_stat_enc.h | 2 +- lib_enc/ivas_stereo_dmx_evs_fx.c | 20 +-- lib_enc/ivas_stereo_ica_enc_fx.c | 8 +- lib_enc/ivas_stereo_icbwe_enc_fx.c | 2 +- lib_enc/ivas_stereo_td_analysis_fx.c | 14 +- lib_enc/ivas_td_low_rate_enc_fx.c | 4 +- lib_enc/prot_fx_enc.h | 18 +-- lib_enc/speech_music_classif_fx.c | 12 +- lib_enc/tcx_utils_enc_fx.c | 4 +- lib_enc/transient_detection_fx.c | 4 +- .../ivas_dirac_dec_binaural_functions_fx.c | 6 +- lib_rend/ivas_mcmasa_ana_fx.c | 6 +- 43 files changed, 355 insertions(+), 381 deletions(-) diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index cb71f0f28..8162a98d3 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -762,31 +762,31 @@ static ivas_error acelp_FCB_allocator_ivas( *--------------------------------------------------------------------*/ ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ) { Word16 i, bits, nb_subfr; @@ -1887,31 +1887,31 @@ ivas_error config_acelp1( *--------------------------------------------------------------------*/ ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ) { Word16 i, bits, nb_subfr; diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 408580169..845ec1f11 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1097,10 +1097,10 @@ void cldfbAnalysis_ts_fx_fixed_q( * Conduct inverse multple overlap cmplex low delay MDCT *--------------------------------------------------------------------*/ void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ const Word16 shift, /* i : scale for state buffer */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ) diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 421b2a705..54fef9e37 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -158,18 +158,18 @@ void Inac_swtch_ematch_fx( void Inac_switch_ematch_ivas_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 L_frame, /* i : Frame lenght */ - const Word16 Q_exc, /* i : input and output format of exc2 */ - const Word16 bfi, /* i : frame lost indicator */ - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode, /* i : Last codec mode */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const Word16 element_mode /* i : element mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ + const Word16 element_mode /* i : element mode */ ) { Word16 Ener_per_bd[MBANDS_GN16k]; diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index 7d481d181..b16b94f1d 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -610,8 +610,7 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_z, /* o: Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ , - Word16 *i_e_band -) + Word16 *i_e_band ) { Word16 i; Word32 intensityNorm; diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index fab166b6d..246f4d297 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3237,8 +3237,7 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_z, /*Q30*/ Word16 i_e /*Exponent of all the intensity buffers*/ , - Word16 *i_e_band -); + Word16 *i_e_band ); UWord8 ivas_masa_surrcoh_signicant_fx( diff --git a/lib_com/ivas_qmetadata_com_fx.c b/lib_com/ivas_qmetadata_com_fx.c index ee11f2b02..a5fbf9e83 100644 --- a/lib_com/ivas_qmetadata_com_fx.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -446,8 +446,6 @@ ivas_error only_reduce_bits_direction_fx( } } } - - } *reduce_bits_out = negate( reduce_bits ); diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 71c1590c2..d7ed9a140 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4851,31 +4851,31 @@ Word16 BITS_ALLOC_config_acelp( const Word16 nb_subfr ); ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ); Word16 set_ACELP_flag( @@ -5846,18 +5846,18 @@ void Inac_swtch_ematch_fx( ); void Inac_switch_ematch_ivas_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 L_frame, /* i : Frame lenght */ - const Word16 Q_exc, /* i : input and output format of exc2 */ - const Word16 bfi, /* i : frame lost indicator */ - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode, /* i : Last codec mode */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const Word16 element_mode /* i : element mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ + const Word16 element_mode /* i : element mode */ ); // igf_base_fx.c @@ -9740,10 +9740,10 @@ void cldfbAnalysis_ivas_fx( ); void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ const Word16 shift, /* i : scale for state buffer */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); @@ -10973,31 +10973,31 @@ void lsf_syn_mem_backup_ivas_fx( Word16 *pstreaklen ); ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16 *unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ ); ivas_error push_next_indice( @@ -11051,8 +11051,8 @@ void calculate_hangover_attenuation_gain_ivas_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word32 igf_brate, /* i : IGF configuration bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ + const Word32 igf_brate, /* i : IGF configuration bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); void core_coder_reconfig_ivas_fx( diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index 228d43247..11da78c46 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -2534,7 +2534,7 @@ void hq_generic_decoding_fx( { exp = norm_l( L_tmp ); frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ - tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ + tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ @@ -3082,7 +3082,7 @@ void hq_generic_decoding_ivas_fx( { exp = norm_l( L_tmp ); frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ - tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ + tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index d403c583d..5219d076c 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -487,13 +487,13 @@ void Copy( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i] = x[i]; - move16(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move16(); + } - return; + return; } /*-------------------------------------------------------------------* * Copy64: @@ -519,13 +519,13 @@ void Copy64( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i] = x[i]; - move64(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move64(); + } - return; + return; } void set64_fx( @@ -566,15 +566,15 @@ void Copy_pword( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i].v.im = x[i].v.im; - y[i].v.re = x[i].v.re; - move16(); - move16(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i].v.im = x[i].v.im; + y[i].v.re = x[i].v.re; + move16(); + move16(); + } - return; + return; } /*-------------------------------------------------------------------* * Copy32: @@ -599,11 +599,11 @@ void Copy32( return; } - FOR( i = L - 1; i >= 0; i-- ) - { - y[i] = x[i]; - move32(); - } + FOR( i = L - 1; i >= 0; i-- ) + { + y[i] = x[i]; + move32(); + } } void set8_fx( diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 74f1bfc09..b8c16474e 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -1590,7 +1590,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */ { - Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( *pPlocs ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1601,7 +1601,7 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && EQ_16( *pPlocs, 1 ) ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ { - Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( sub( *pPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1647,7 +1647,7 @@ static void ivas_spec_ana_fx( IF( EQ_16( currPlocs, ( sub( Lprot2_1, DELTA_CORR_F0_INT ) ) ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ { - Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( sub( currPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1661,7 +1661,7 @@ static void ivas_spec_ana_fx( * whould point */ IF( n > 0 ) /* fs/2 which makes special case . */ { - Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 + Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 acc = L_deposit_h( sub( currPlocs, 2 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 5807f2c67..ea82f09de 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -77,21 +77,21 @@ ivas_error acelp_core_dec_ivas_fx( { Word32 synth_fx[960], save_hb_synth_fx[960] /*, bwe_exc_extended_fx[L_FRAME32k + NL_BUFF_OFFSET]*/; - Word16 old_exc_fx[L_EXC_DEC], *exc_fx; /* excitation signal buffer */ - Word16 syn_tmp_fx[L_FRAME16k + L_SUBFR], *psyn_fx; /* synthesis signal buffer */ - Word16 output_frame; /* frame length at output sampling freq. */ - Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ - Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ - Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ - Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ - Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ - Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ - Word32 enr_q_fx; /* E information for FER protection */ - Word16 tmp_noise_fx; /* Long term temporary noise energy */ - Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ - Word16 FEC_pitch_fx; /* FEC pitch */ + Word16 old_exc_fx[L_EXC_DEC], *exc_fx; /* excitation signal buffer */ + Word16 syn_tmp_fx[L_FRAME16k + L_SUBFR], *psyn_fx; /* synthesis signal buffer */ + Word16 output_frame; /* frame length at output sampling freq. */ + Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ + Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ + Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ + Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ + Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ + Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ + Word32 enr_q_fx; /* E information for FER protection */ + Word16 tmp_noise_fx; /* Long term temporary noise energy */ + Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ + Word16 FEC_pitch_fx; /* FEC pitch */ Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ - Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ + Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ Word16 i, j, int_fs; Word16 tc_subfr; Word16 allow_cn_step; @@ -1810,7 +1810,7 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) + scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); @@ -1892,13 +1892,13 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, st->cldfbSyn ); - scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 + scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); @@ -1988,12 +1988,12 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), 0, st->cldfbSyn ); - Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 + Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index df18d3dba..c1289b8a3 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -5270,7 +5270,7 @@ void generate_stereo_masking_noise_fx( { hFdCngCom = st->hFdCngDec->hFdCngCom; Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ - Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ + Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); @@ -5278,7 +5278,7 @@ void generate_stereo_masking_noise_fx( IF( !fadeOut ) { Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ - generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 + generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 /* Generate masking noise for secondary channel */ IF( flag_sec_CNA ) { diff --git a/lib_dec/ivas_binRenderer_internal_fx.c b/lib_dec/ivas_binRenderer_internal_fx.c index f78f14e8e..c05b8beb2 100644 --- a/lib_dec/ivas_binRenderer_internal_fx.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -339,7 +339,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - } } /* set memories */ @@ -1264,7 +1263,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; - } free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); @@ -1272,7 +1270,6 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; - } free( hBinRenConvModule->filterStatesLeftReal_fx ); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 4e654030b..588640d0a 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -524,7 +524,7 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 - Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 + Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 IF( st->cldfbAna ) { scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, Q10 - Q11 ); /* 9 * (Word16)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f) , Q10 */ @@ -630,8 +630,8 @@ ivas_error ivas_core_dec_fx( ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 - Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 - Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 + Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 + Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 } /*---------------------------------------------------------------------* @@ -1147,8 +1147,8 @@ ivas_error ivas_core_dec_fx( q = 2; move16(); - Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 - Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); // Q0 + Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, -( Q11 ) ); // Q0 + Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); // Q0 Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ); // Q8 Copy_Scale_sig_32_16( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, ( 2 * ALLPASSSECTIONS_STEEP ), sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ); // prev_Q_bew_syn2 diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 71839557a..7d5f7d737 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1172,13 +1172,13 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_syn_Overl_TDAC ) ); // st->hTcxDec->Q_syn_Overl_TDAC -> q_win Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_old_syn_Overl ) ); // Q(-1 - st->Q_syn) -> q_win st->hTcxDec->Q_old_syn_Overl = q_win; - Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win + Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win - Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win + Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win FOR( k = 0; k < nSubframes[ch]; k++ ) { init_tcx_info_fx( st, L_frame_global[ch], L_frame_globalTCX[ch], k, bfi, &tcx_offset[ch], diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index c3e2ad096..a7b66ff87 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -1352,7 +1352,7 @@ static void ivas_spar_calc_smooth_facs_fx( smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 move32(); } - smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 + smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 move32(); smooth_long_avg_fx[b] = Mpy_32_32( smooth_long_avg_fx[b], 107374182 /*(1/20 in Q31)*/ ); // Q0 move32(); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 429a99ca4..891be05be 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -961,7 +961,7 @@ typedef struct decoder_tc_buffer_structure Word32 *tc_buffer_fx; /* the buffer itself */ Word16 tc_buff_len; /*stores memory length of tc buffer*/ Word32 *tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc Q11 for ivas */ // VE2SB: TBV - Word16 no_channels; /*Stores no of channels in tc_fx with values*/ + Word16 no_channels; /*Stores no of channels in tc_fx with values*/ Word16 q_tc_fx; TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 1c2ecffaf..c9f7cac92 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -718,8 +718,8 @@ void stereo_icBWE_dec_fx( IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) { temp1_fx = 0; @@ -813,7 +813,7 @@ void stereo_icBWE_dec_fx( hStereoICBWE->prev_Q_fsout = tmp; move16(); } - Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); /* Qsyn - 1 */ + Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); /* Qsyn - 1 */ *Q_syn = sub( *Q_syn, 1 ); @@ -877,8 +877,8 @@ void stereo_icBWE_dec_fx( IF( LE_16( ratio_L_fx, 29490 /* 0.9 in Q15*/ ) ) { tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 IF( LT_16( tmp, 4096 /* 0.5 in Q13*/ ) ) { temp1_fx = 0; diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index dd9859504..8a9224ffa 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -294,7 +294,6 @@ Word16 svd_fx( push_wmops( "svd_fx" ); - /* Collecting Values */ FOR( iCh = 0; iCh < nChannelsL; iCh++ ) { @@ -385,11 +384,11 @@ static Word16 BidagonalDiagonalisation_fx( Word32 singularVectors_Right_fx[][MAX_OUTPUT_CHANNELS], /* i/o: right singular vectors (V) singularValues_fx_e*/ Word32 secDiag_fx[MAX_OUTPUT_CHANNELS], /* i/o: secDiag_fx_e*/ Word16 singularValues_fx_e[MAX_OUTPUT_CHANNELS], /* i/o: singular values vector (S) */ - Word16 *secDiag_new_e, /* i/o: */ - const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ - const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ - const Word32 eps_x, /* i : eps_x_e*/ - const Word16 eps_x_e /* i : */ + Word16 *secDiag_new_e, /* i/o: */ + const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ + const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ + const Word32 eps_x, /* i : eps_x_e*/ + const Word16 eps_x_e /* i : */ ) { Word16 kCh, nCh, iCh, jCh, split; @@ -898,52 +897,52 @@ static void biDiagonalReductionLeft_fx( secDiag_e[currChannel] = *sig_x_e; move16(); -/* Setting values to 0 */ -( *sig_x ) = 0; -move32(); -( *g ) = 0; -move32(); - -IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ -{ - idx = currChannel; - move16(); - - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ - { - ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ - } + /* Setting values to 0 */ + ( *sig_x ) = 0; + move32(); + ( *g ) = 0; + move32(); - IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ + IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ { - Word16 invVal_e; - Word32 invVal; - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); - norm_x = 0; - move32(); - norm_x_e = 0; + idx = currChannel; move16(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { + ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ + } + + IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ + { + Word16 invVal_e; + Word32 invVal; + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); + norm_x = 0; + move32(); + norm_x_e = 0; + move16(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { Word16 temp_e = norm_l( singularVectors[jCh][currChannel] ); singularVectors[jCh][currChannel] = Mpy_32_32( L_shl( singularVectors[jCh][currChannel], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); singularVectors2_e[jCh][currChannel] = sub( add( invVal_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ), temp_e ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ - } - IF( GT_16( norm_x_e, 0 ) ) - { - norm_x = MAX_32; - move32(); - norm_x_e = 0; + } + IF( GT_16( norm_x_e, 0 ) ) + { + norm_x = MAX_32; + move32(); + norm_x_e = 0; + move16(); + } + L_temp_e = norm_x_e; move16(); - } - L_temp_e = norm_x_e; - move16(); - L_temp = Sqrt32( norm_x, &L_temp_e ); - L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 - //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); + L_temp = Sqrt32( norm_x, &L_temp_e ); + L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 + //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); if ( singularVectors[currChannel][idx] >= 0 ) { L_temp = L_negate( L_temp ); @@ -951,52 +950,51 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ ( *g ) = L_temp; move32(); - r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ - singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ - move32(); + r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ + singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ + move32(); - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); - FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ - { - norm_x = 0; - move32(); - norm_x_e = 0; - move16(); - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { + norm_x = 0; + move32(); + norm_x_e = 0; + move16(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( singularVectors2_e[jCh][currChannel], singularVectors2_e[jCh][iCh] ), &norm_x_e ); /* exp(norm_x_e) */ - } + } - f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ + f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ f_e = add( invVal_e, sub( norm_x_e, r_e ) ); - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ - { + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], singularVectors2_e[jCh][iCh], Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, singularVectors2_e[jCh][currChannel] ), &singularVectors2_e[jCh][iCh] ); - move32(); + move32(); + } } - } - FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ - { - singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ - move32(); + FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { + singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ + move32(); singularVectors2_e[jCh][currChannel] = add( singularVectors2_e[jCh][currChannel], *sig_x_e ); - move16(); + move16(); + } } + // rescaling block + singularValues[currChannel] = Mpy_32_32( ( *sig_x ), ( *g ) ); /* sig_x_e */ + move32(); + singularValues_e[currChannel] = *sig_x_e; + move16(); } - // rescaling block - singularValues[currChannel] = Mpy_32_32( ( *sig_x ), ( *g ) ); /* sig_x_e */ - move32(); - singularValues_e[currChannel] = *sig_x_e; - move16(); -} - -return; + return; } /*------------------------------------------------------------------------- @@ -1108,7 +1106,7 @@ static void biDiagonalReductionRight_fx( FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { - singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ + singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ move32(); } } @@ -1120,9 +1118,6 @@ static void biDiagonalReductionRight_fx( singularVectors2_e[currChannel][jCh] = add( singularVectors2_e[currChannel][jCh], *sig_x_e ); move16(); } - - - } } @@ -1230,7 +1225,7 @@ static void singularVectorsAccumulationLeft_fx( { FOR( iCh = 0; iCh < nChannelsC; iCh++ ) { - singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ + singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ move32(); } } diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index a93690738..f9f941dbd 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1430,7 +1430,7 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) { - Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn + Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 1 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); // st->Q_syn st->hTcxEnc->q_Txnq = st->Q_syn; move16(); diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 54f57b287..bb35cf037 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -4525,7 +4525,6 @@ void coder_tcx_fx( n, st, hm_cfg ); - } diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 405b3ac2b..14dbd5962 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -943,8 +943,8 @@ static void init_modes_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word32 igf_brate, /* i : IGF configuration bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ + const Word32 igf_brate, /* i : IGF configuration bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ) { TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 44be8dcc6..9a66572ab 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -60,12 +60,12 @@ static void update_SID_cnt_fx( DTX_ENC_HANDLE hDtxEnc, const Word32 core_brate, /* _ None */ /*==================================================================================*/ void dtx_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ + Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ - const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ - const Word16 vad, /* i : vad flag for DTX Q0*/ - const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ - Word16 Q_speech /* i : Q factor for speech */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ + const Word16 vad, /* i : vad flag for DTX Q0*/ + const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ + Word16 Q_speech /* i : Q factor for speech */ ) { Word16 alpha, i, j, Q_speech2; diff --git a/lib_enc/enc_acelpx_fx.c b/lib_enc/enc_acelpx_fx.c index 9612696ed..240f9859c 100644 --- a/lib_enc/enc_acelpx_fx.c +++ b/lib_enc/enc_acelpx_fx.c @@ -781,7 +781,7 @@ void E_ACELP_4tsearchx_ivas_fx( alp = shr( alp, 1 ); Scale_sig( cor, L_SUBFR, -1 ); /*Q8*/ Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/ - Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ + Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ } diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index 6bc466e3d..ff19cfebc 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -481,8 +481,8 @@ void hq_core_enc_ivas_fx( TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); Q_audio = sub( Q31, Q_audio ); Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ - inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ - L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ + inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ + L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ is_transient = 0; move16(); move16(); diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index d5f071784..2680bd9f6 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2517,8 +2517,8 @@ void IGFEncResetTCX10BitCounter_ivas_fx( *-------------------------------------------------------------------*/ void IGFEncApplyMono_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ + Encoder_State *st, /* i : Encoder state */ + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index bf7c36eef..96c1b168f 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -125,14 +125,14 @@ ivas_error pre_proc_front_ivas_fx( const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ Word16 band_energies_LR_fx_q, - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ - const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ - const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ - const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ + const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ + const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ - const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ + const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO , diff --git a/lib_enc/ivas_dirac_enc_fx.c b/lib_enc/ivas_dirac_enc_fx.c index 59447c022..615a6f4b6 100644 --- a/lib_enc/ivas_dirac_enc_fx.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -51,11 +51,9 @@ static void computeIntensityVector_enc_fx( Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const Word16 enc_param_start_band, /* i : first band to process */ const Word16 num_frequency_bands, - Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] - , + Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS], Word16 q_cldfb, - Word16 q_intensity_real[DIRAC_MAX_NBANDS] -); + Word16 q_intensity_real[DIRAC_MAX_NBANDS] ); /*------------------------------------------------------------------------- * ivas_dirac_enc_open() @@ -1123,11 +1121,9 @@ void ivas_dirac_param_est_enc_fx( Cldfb_ImagBuffer_fx, hDirAC->hConfig->enc_param_start_band, num_freq_bands, - intensity_real_fx - , + intensity_real_fx, cldfb_q, - intensity_real_q - ); + intensity_real_q ); IF( !hodirac_flag ) { computeDirectionVectors_fixed( @@ -1138,10 +1134,8 @@ void ivas_dirac_param_est_enc_fx( num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], - direction_vector_fx[2] - , - 31, intensity_real_q - ); + direction_vector_fx[2], + 31, intensity_real_q ); direction_vector_q = Q30; move16(); @@ -1465,8 +1459,7 @@ static void computeIntensityVector_enc_fx( Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] /* q_intensity_real */ , Word16 q_cldfb, - Word16 q_intensity_real[DIRAC_MAX_NBANDS] -) + Word16 q_intensity_real[DIRAC_MAX_NBANDS] ) { /* Reminder * X = a + ib; Y = c + id diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index 0071b67ea..7a5718e99 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -1178,10 +1178,8 @@ void ivas_mcmasa_param_est_enc_fx( num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], - direction_vector_fx[2], c_e - , - NULL - ); + direction_vector_fx[2], c_e, + NULL ); /* Power and intensity estimation for diffuseness */ computeIntensityVector_enc_fx( diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 4b5b3fcbe..f7da231a3 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -429,11 +429,11 @@ static void kernel_switch_update_transforms_fx( Word32 factor; n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 - Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 - scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 + Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 + scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, s, &exp_tmp ); @@ -896,8 +896,8 @@ static UWord16 enc_ste_pre_mdct( absMagnR_fx = Sqrt32( L_add( Mpy_32_32( sigR1_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI1_fx[s], sigI1_fx[s] ) ), &absMagnR_e ); corr_fx = L_add( corr_fx, L_add( Mpy_32_32( sigR0_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI0_fx[s], sigI1_fx[s] ) ) ); // q_com*2 - 31 - sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 - sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 + sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 + sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 sumMagnL_fx = BASOP_Util_Add_Mant32Exp( sumMagnL_fx, sumMagnL_e, absMagnL_fx, absMagnL_e, &sumMagnL_e ); sumMagnR_fx = BASOP_Util_Add_Mant32Exp( sumMagnR_fx, sumMagnR_e, absMagnR_fx, absMagnR_e, &sumMagnR_e ); sumPrdLR_fx = BASOP_Util_Add_Mant32Exp( sumPrdLR_fx, sumPrdLR_e, Mpy_32_32( absMagnL_fx, absMagnR_fx ), add( absMagnL_e, absMagnR_e ), &sumPrdLR_e ); diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index 1433c988f..f1187bc6c 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -1199,10 +1199,8 @@ static void ivas_omasa_param_est_enc_fx( computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, guard_bits ); intensity_real_e = sub( add( 62, guard_bits ), shl( q, 1 ) ); - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e - , - NULL - ); + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e, + NULL ); /* Power estimation for diffuseness */ diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 4a6543026..f421fd034 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1179,7 +1179,7 @@ typedef struct stereo_dmx_evs_correlation_filter_structure { Word16 init_frmCntr; - Word32 isd_rate_s_fx; // Q31 + Word32 isd_rate_s_fx; // Q31 Word32 iccr_s_fx; // Q31 Word32 ipd_ff_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word32 Pr_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 2ed17e25a..625ff8ee9 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -155,8 +155,8 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word16 itd[], /* o : estimated itd Q0 */ - const Word16 input_frame /* i : input frame length per channel */ + Word16 itd[], /* o : estimated itd Q0 */ + const Word16 input_frame /* i : input frame length per channel */ ); static void adapt_gain_fx( const Word32 src_fx[], /* i : input signal Q16 */ @@ -198,9 +198,9 @@ static void create_M_signal_fx( ); static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word16 itd_fx[], /* o : estimated itd */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio */ + Word16 itd_fx[], /* o : estimated itd */ + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio */ ); /*-------------------------------------------------------------------* * estimate_itd_wnd_fft() @@ -1136,9 +1136,9 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word16 itd_fx[], /* o : estimated itd Q0 */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio Q31 */ + Word16 itd_fx[], /* o : estimated itd Q0 */ + const Word16 input_frame, /* i : input frame length per channel */ + const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) { Word16 itd_cand[CPE_CHANNELS], i, n, cnt[CPE_CHANNELS], Lh, peak_range, *on, *itdLR, prev_off[CPE_CHANNELS], eps_fx; @@ -1448,8 +1448,8 @@ static ivas_error estimate_itd_fx( STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure */ const Word32 srcL[], /* i : Lch input signal Q16 */ const Word32 srcR[], /* i : Rch input signal Q16 */ - Word16 itd[], /* o : estimated itd Q0 */ - const Word16 input_frame /* i : input frame length per channel */ + Word16 itd[], /* o : estimated itd Q0 */ + const Word16 input_frame /* i : input frame length per channel */ ) { Word32 specLr[L_FRAME48k / 2 + 1], specLi[L_FRAME48k / 2 + 1], specRr[L_FRAME48k / 2 + 1], specRi[L_FRAME48k / 2 + 1]; diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 8410f7546..78ea50d7e 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1095,8 +1095,8 @@ static void corrStatsEst_fx( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */ move32(); Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ - inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ - IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 + inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ + IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 { set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 ); hStereoTCA->delay_0_mem_exp = temp; @@ -1964,8 +1964,8 @@ void stereo_tca_enc_fx( Word16 temp_exp, tempF_16fx; Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */ - scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ + scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ tempF_fx = tempF_16fx; move32(); diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 25e2366dd..02d20543b 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -822,7 +822,7 @@ void stereo_icBWE_enc_ivas_fx( set32_fx( shb_frame_nonref_fx, 0, L_LOOK_16k + L_FRAME16k ); max_e = s_max( hStereoICBWE->mem_shb_speech_nonref_e, shb_speech_nonref_e ); - Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e + Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e hStereoICBWE->mem_shb_speech_nonref_e = max_e; shb_frame_nonref_e = max_e; diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index f9b6b0bf3..6ffd05c0c 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -71,13 +71,13 @@ #define RATIO_MAX 1.5f /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ -#define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ -#define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ -#define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ -#define B_ADAP_FX_Q16 ( 10486 ) /* 0.16f in Q16 */ +#define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ +#define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ +#define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ +#define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ +#define B_ADAP_FX_Q16 ( 10486 ) /* 0.16f in Q16 */ #define PC_LIMIT 64 #define RATIO_PG_HR 0.94f diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 63cbb30e9..bdc39e797 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -338,8 +338,8 @@ void encod_gen_2sbfr( * Update memory of the weighting filter *-----------------------------------------------------------------*/ - Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ - Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ + Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index f80373787..3f7f17fe7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -177,12 +177,12 @@ void dtx_fx( ); void dtx_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ + Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ - const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ - const Word16 vad, /* i : vad flag for DTX Q0*/ - const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ - Word16 Q_speech /* i : Q factor for speech */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ + const Word16 vad, /* i : vad flag for DTX Q0*/ + const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ + Word16 Q_speech /* i : Q factor for speech */ ); Word16 dtx_hangover_addition_fx( @@ -1232,8 +1232,8 @@ void AVQ_cod_lpc_fx( ); void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ + Encoder_State *st, /* i : Encoder state */ + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -3067,8 +3067,8 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | Word16 last_core_acelp /**< in: Q0 | indictaor if last frame was acelp coded */ ); -void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ - Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ +void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index ff9e2d936..b9f47136f 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -890,7 +890,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */ L_tmp = L_shl( tmp, sub( 1, exp3 ) ); /*Q16 */ - ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ + ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ } } @@ -2201,12 +2201,12 @@ Word16 ivas_smc_gmm_fx( ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); - wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 move32(); } @@ -2220,7 +2220,7 @@ Word16 ivas_smc_gmm_fx( *high_lpn_flag = 1; move32(); } - hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 + hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 move16(); hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 move16(); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index c84843384..e0a944981 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3784,8 +3784,8 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) * *---------------------------------------------------------------------*/ void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ + Encoder_State *st, /* i : Encoder state */ + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 92f01b5dd..60d661db4 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -678,8 +678,8 @@ void RunTransientDetection_ivas_fx( IF( GT_16( sub( q_input, pSubblockEnergies->q_firState ), shift ) ) { Scale_sig( input_fx, length, add( sub( pSubblockEnergies->q_firState, q_input ), shift ) ); // q_firState + shift - q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift - pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift + q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift + pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift move16(); pSubblockEnergies->firState2 = shl( pSubblockEnergies->firState2, shift ); // q_firState + shift move16(); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index fb3a89350..2376babcd 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -72,9 +72,9 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; #define INV_TAN30_FX 28377 // Q14 #define EPSILON_MANT 1180591621 /* 1e-12 = 0.5497558*(2^-39) in Q70 */ #define EPSILON_EXP ( -39 ) -#define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ -#define ONE_DIV_EPSILON_EXP ( 40 ) -#define ADAPT_HTPROTO_ROT_LIM_1 0.8f +#define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ +#define ONE_DIV_EPSILON_EXP ( 40 ) +#define ADAPT_HTPROTO_ROT_LIM_1 0.8f #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */ diff --git a/lib_rend/ivas_mcmasa_ana_fx.c b/lib_rend/ivas_mcmasa_ana_fx.c index d5df77045..cfdd43116 100644 --- a/lib_rend/ivas_mcmasa_ana_fx.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -753,10 +753,8 @@ void ivas_mcmasa_param_est_ana_fx( /* Direction estimation */ computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) - , - NULL - ); /* Q direction_vector_fx = Q30*/ + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ), + NULL ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx ); /*2*inp_q-31*/ -- GitLab From 901841d9134342fbc700ef1ef23f23d12b65c2dc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 20 Mar 2025 18:50:36 +0530 Subject: [PATCH 0630/1221] Fix for 3GPP issue 1339: Artifact in IGF part for first active frame after DTX period in MDCT-Stereo Link #1339 --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 4255980ad..804bcff5c 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -358,6 +358,32 @@ void stereo_mdct_core_enc_fx( } q_spec = sub( Q31, q_spec ); + /*find headroom to increase precision*/ + Word16 hdrm_min = MAX_16; + move16(); + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + length = sts[ch]->hTcxEnc->L_frameTCX; + move16(); + } + ELSE + { + length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + } + FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[k], length ) ); + hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][k], length ) ); + } + } + + IF( hdrm_min != 0 ) + { + q_spec = sub( add( hdrm_min, q_spec ), 1 ); /*1 guard bit to avoid over-flows*/ + } + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { Word16 n_sb = NB_DIV; -- GitLab From fb6609bed16f25f93d4ef85ab3d946b924d7bbd1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 17:25:41 +0530 Subject: [PATCH 0631/1221] Fix for 3GPP issue 1414: ApplyFdCng_ivas_fx() called twice Link #1414 --- lib_dec/acelp_core_dec_ivas_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index ea82f09de..bd8c6ec93 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -660,7 +660,7 @@ ivas_error acelp_core_dec_ivas_fx( STEREO_DFT_FD_FILT_COMP_Q31, st->hFdCngDec->hFdCngCom->sidNoiseEst[i] ); move32(); } - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + Word16 new_sidNoiseEstExp = 31 - Q4; move16(); Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, new_sidNoiseEstExp ) ); // Q(31-sidNoiseEstExp) -- GitLab From b731e4cf2d5033fe8ebd04c93f69a191a6be7041 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 21 Mar 2025 10:57:19 +0530 Subject: [PATCH 0632/1221] Fix for 3GPP issue 1404: Stereo LTV signal at 24.4kbps and 32kbps: Modulated noise in BWE region for one-sided signal Link #1404 --- lib_com/rom_com.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 551a84feb..a5c8a3b7c 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -22038,27 +22038,8 @@ const Word32 sigma_BWE_fx[] = {//Q31 40792208 }; /* for 3 bits first stage */ -const Word16 inv_modified_sigma_BWE_fx[] = {//Q1 - 259, -254, -267, -266, -293, -315, -598, -622, -288, -288, -297, -297, -319, -346, -598, -622 -}; - -const Word16 modified_sigma_BWE_fx[] =//Q(log2(2.56) -{ 323, +const Word16 inv_modified_sigma_BWE_fx[] = {//x2.56 +323, 329, 313, 314, @@ -22073,8 +22054,27 @@ const Word16 modified_sigma_BWE_fx[] =//Q(log2(2.56) 262, 242, 140, -134 }; +134 +}; +const Word16 modified_sigma_BWE_fx[] =//Q15 +{ 259, +254, +267, +266, +293, +315, +598, +622, +288, +288, +297, +297, +319, +346, +598, +622 }; + const Word16 SHB_LSF_mean_fx[10] = {//Q15 1353, 2646, 4046, -- GitLab From bd8ebe21c053e3cd3f389009e459808bddf55488 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 24 Mar 2025 09:18:10 +0530 Subject: [PATCH 0633/1221] Q-factor of synthesis memory buffers of LPDmem struct updates --- lib_com/lsf_tools_fx.c | 8 ++++---- lib_enc/cod_tcx_fx.c | 4 ++-- lib_enc/core_enc_init_fx.c | 6 ++++++ lib_enc/init_enc_fx.c | 14 ++++---------- lib_enc/ivas_tcx_core_enc_fx.c | 16 ++-------------- lib_enc/ivas_td_low_rate_enc_fx.c | 1 + lib_enc/tcx_utils_enc_fx.c | 9 ++++++++- 7 files changed, 27 insertions(+), 31 deletions(-) diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 54f0ae3ed..5f0b3b57b 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -3044,11 +3044,11 @@ void lsf_syn_mem_backup_ivas_fx( /* back-up memories */ FOR( i = 0; i < M; i++ ) { - mem_syn_bck[i] = hLPDmem->mem_syn[i]; // Q: ( 15 - st_fx->hLPDmem->e_mem_syn ) + mem_syn_bck[i] = hLPDmem->mem_syn[i]; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); } - *mem_w0_bck = hLPDmem->mem_w0; // ( 15 - st_fx->hLPDmem->e_mem_syn ) + *mem_w0_bck = hLPDmem->mem_w0; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); @@ -3263,12 +3263,12 @@ void lsf_syn_mem_restore_ivas_fx( } /* restoring memories */ - hLPDmem->mem_w0 = mem_w0_bck; // Q(15 - st_fx->hLPDmem->e_mem_syn ) + hLPDmem->mem_w0 = mem_w0_bck; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); FOR( i = 0; i < M; i++ ) { - hLPDmem->mem_syn[i] = mem_syn_bck[i]; // Q(15 - st_fx->hLPDmem->e_mem_syn ) + hLPDmem->mem_syn[i] = mem_syn_bck[i]; // Q( st_fx->hLPDmem->q_mem_syn ) move16(); } diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index bb35cf037..4bb44eae2 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -3743,7 +3743,7 @@ void QuantizeTCXSpectrum_fx( } /* Quantize original spectrum */ - sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); + sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, ( mult( hTcxEnc->tcx_target_bits_fac, shl( sqTargetBits, 1 ) ) ), L_spec, &sqGain_e ); tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly ); @@ -4730,7 +4730,7 @@ void InternalTCXDecoder_fx( } ELSE { - mdct_shaping( spectrum_fx, L_frame, gainlpc_fx, gainlpc_e ); + mdct_noiseShaping_ivas_fx( spectrum_fx, spectrum_e, L_frame, gainlpc_fx, gainlpc_e ); } /*-----------------------------------------------------------* * Apply gain * diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 14dbd5962..05f838a3a 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -1561,6 +1561,10 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh { set16_fx( hLPDmem->syn, 0, 1 + M ); set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); + hLPDmem->q_lpd_syn = Q15; + hLPDmem->q_mem_syn = Q15; + move16(); + move16(); } IF( st->hTcxEnc != NULL ) @@ -1591,6 +1595,8 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); set16_fx( hLPDmem->syn, 0, M ); hLPDmem->q_lpd_syn = Q15; + hLPDmem->q_mem_syn = Q15; + move16(); move16(); } IF( st->hTcxEnc != NULL ) diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 1d695659c..ea944dd75 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -998,16 +998,18 @@ void LPDmem_enc_init_ivas_fx( set16_fx( hLPDmem->mem_syn2, 0, M ); set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); set16_fx( hLPDmem->mem_syn3, 0, M ); + hLPDmem->q_lpd_old_exc = Q15; + move16(); hLPDmem->q_lpd_syn = Q15; move16(); + hLPDmem->q_mem_syn = Q15; + move16(); hLPDmem->mem_w0 = 0; move16(); hLPDmem->tilt_code = 0; move16(); hLPDmem->gc_threshold = 0; move32(); - hLPDmem->q_mem_syn = Q15; - move16(); hLPDmem->dm_fx.prev_state = 0; move16(); /* This corresponds to st_fx->dispMem in FLP */ hLPDmem->dm_fx.prev_gain_code = 0; @@ -1019,14 +1021,6 @@ void LPDmem_enc_init_ivas_fx( move16(); } - hLPDmem->q_lpd_syn = Q15; - move16(); - hLPDmem->q_lpd_old_exc = Q15; - move16(); - hLPDmem->q_mem_syn = Q15; - move16(); - - return; } diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 159012ac2..8dbd4731c 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -562,9 +562,9 @@ void stereo_tcx_core_enc( } Scale_sig( st->synth, st->L_frame, s ); /* st->Q_syn + s */ Scale_sig( st->hLPDmem->syn, M + 1, s ); /* st->Q_syn + s */ + st->hLPDmem->q_lpd_syn = add( st->hLPDmem->q_lpd_syn, s ); Q_new = add( Q_new, s ); move16(); - move16(); coder_tcx_post_ivas_fx( st, st->hLPDmem, st->hTcxCfg, st->synth, A_q_fx, Aw_fx, st->wspeech_enc, Q_new ); @@ -688,19 +688,7 @@ void stereo_tcx_core_enc( { set16_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q6, NB_SUBFR16k ); /* Q6 */ } - /* Memory scaling to keep everything in common q */ - Word16 curr_q_syn = sub( shl( Q_new, 1 ), 1 ); - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - Scale_sig( st->hLPDmem->mem_syn, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - Scale_sig( st->hLPDmem->mem_syn2, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), curr_q_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( s_min( Q_new, st->hLPDmem->q_mem_syn ), Q_new ) ); /* s_min( Q_new, st->hLPDmem->q_mem_syn ) */ - move16(); - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - Scale_sig( st->hLPDmem->mem_syn3, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); /* s_min( curr_q_syn, st->hLPDmem->q_mem_syn ) */ - st->hLPDmem->q_mem_syn = s_min( curr_q_syn, st->hLPDmem->q_mem_syn ); - move16(); - st->hLPDmem->q_lpd_syn = Q_new; - move16(); + IF( st->hTdCngEnc != NULL ) { FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index bdc39e797..77ddb35aa 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -157,6 +157,7 @@ void tdm_low_rate_enc( { E_UTIL_synthesis( 0, p_Aq, &exc_wo_nf_fx[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1, M ); /* Q_new */ p_Aq += ( M + 1 ); + scale_sig( hLPDmem->mem_syn, M, sub( hLPDmem->q_mem_syn, Q_new ) ); // Q_new -> hLPDmem->q_mem_syn } /*--------------------------------------------------------------------------------------* diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index e0a944981..7d268b92a 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2799,12 +2799,14 @@ void tcx_encoder_memory_update_ivas_fx( Copy( xn_buf, synth, L_frame_glob ); Copy( synth + sub( L_frame_glob, M + 1 ), LPDmem->syn, M + 1 ); + LPDmem->q_lpd_syn = Q_new; + move16(); IF( st->tcxonly == 0 ) { /* Update weighted synthesis */ Residu3_fx( Ai + imult1616( sub( st->nb_subfr, 1 ), ( M + 1 ) ), synth + sub( L_frame_glob, 1 ), &tmp, 1, 0 ); - LPDmem->mem_w0 = sub_sat( wsig[sub( L_frame_glob, 1 )], tmp ); + LPDmem->mem_w0 = sub_sat( wsig[L_frame_glob - 1], tmp ); move16(); } @@ -2817,6 +2819,11 @@ void tcx_encoder_memory_update_ivas_fx( Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M ); Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M ); Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM ); + + /* Aligning the Q-factor of the remaining synthesis memory buffers */ + Scale_sig( LPDmem->mem_syn1_fx, M, sub( Q_new, LPDmem->q_mem_syn ) ); + Scale_sig( LPDmem->mem_syn3, M, sub( Q_new, LPDmem->q_mem_syn ) ); + LPDmem->q_mem_syn = Q_new; // resultant q of synth after E_UTIL_f_preemph2 move16(); -- GitLab From 8302f02911824df48f138cddee6b5aa0baeb2115 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 24 Mar 2025 13:53:09 +0100 Subject: [PATCH 0634/1221] Use L_norm_arr instead of getScaleFactor32. Add assert checking proto_power_smooth q values. --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 7d3379ae7..baed49498 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2190,6 +2190,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth move32(); + assert(h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q); + IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) { p_power_smooth_prev++; -- GitLab From 33cd00b10ccefc173ebe33c35b67b6b655559deb Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 24 Mar 2025 14:04:05 +0100 Subject: [PATCH 0635/1221] Re enable FIX_867_CLDFB_NRG_SCALE --- lib_com/options.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_com/options.h b/lib_com/options.h index 76bfee2ae..f100e4c98 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -69,4 +69,5 @@ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +#define FIX_867_CLDFB_NRG_SCALE #endif -- GitLab From 5515664eb74a2a88ecbe36e28c3242c3d36d0959 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 24 Mar 2025 14:09:20 +0100 Subject: [PATCH 0636/1221] clang format --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index baed49498..6f8557dfb 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2190,7 +2190,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth move32(); - assert(h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q); + assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q ); IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) { -- GitLab From 63b5aab706fbd9d46d767949901e9278515c61a3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 14 Mar 2025 17:46:57 +0530 Subject: [PATCH 0637/1221] LTV crash fix --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..4c91b0c7b 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -930,7 +930,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( { L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); } - g0 = extract_h( L_shl( L_g0, 14 ) ); + g0 = extract_h( L_shl_sat( L_g0, 14 ) ); /* Scale signal i of 1/A(gamma1) */ IF( GT_16( g0, 1024 ) ) -- GitLab From 47bf67bd01e16f22d9733aab5bc358091631e41d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Mar 2025 15:15:28 +0100 Subject: [PATCH 0638/1221] fewer testcases for testing --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 836829bbc..f7db000f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -404,7 +404,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM\""; fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM\ and stereo and at""; fi - *build-and-create-float-ref-outputs -- GitLab From b7437cd508a5b06fd9b51eff92be8e52e1f3826e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Mar 2025 09:35:30 +0530 Subject: [PATCH 0639/1221] Fix for 3GPP issue 1348: Increased noise level in BASOP decoder for band-limited input from float encoder Link #1348 --- lib_dec/dec_tcx_fx.c | 4 ++-- lib_dec/ivas_mdct_core_dec_fx.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index e2ea02dcc..af80ee1f5 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -2636,10 +2636,10 @@ void IMDCT_ivas_fx( { Word32 fac; // fac = shl_sat( mult_r( extract_h( L_shr_sat( hTcxDec->conceal_eof_gain32, sub( 1, hTcxDec->conceal_eof_gain_e ) ) ), st->last_concealed_gain_syn_deemph ), 1 ); - fac = Mpy_32_16_1( hTcxDec->conceal_eof_gain32, st->last_concealed_gain_syn_deemph ); // q = 31 - hTcxDec->conceal_eof_gain_e + fac = Mpy_32_16_1( hTcxDec->conceal_eof_gain32, st->last_concealed_gain_syn_deemph ); // q = 31 - hTcxDec->conceal_eof_gain_e - last_concealed_gain_syn_deemph_e FOR( Word16 ind = 0; ind < overlap; ind++ ) { - old_syn_overl_fx[ind] = extract_l( L_shl_sat( Mpy_32_32( old_syn_overl_fx[ind], fac ), hTcxDec->conceal_eof_gain_e ) ); // Q(-2) + old_syn_overl_fx[ind] = extract_h( L_shl_sat( Mpy_32_16_1( fac, old_syn_overl_fx[ind] ), add( hTcxDec->conceal_eof_gain_e, st->last_concealed_gain_syn_deemph_e ) ) ); // Q(-2) move16(); } } diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 7d5f7d737..fabebede4 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1623,6 +1623,8 @@ void ivas_mdct_core_tns_ns_fx( } q_2 = q_x; move16(); + Word16 length2 = length; + move16(); sns_shape_spectrum_fx( x_fx[ch][k], &q_x, st->hTcxCfg->psychParamsCurrent, sns_int_scf_fx, q_sns_int_scf, st->hTcxCfg->psychParamsCurrent->nBins, &length ); IF( LT_16( q_2, add( q_x, 1 ) ) ) /*scaling to q_2*/ { @@ -1632,7 +1634,7 @@ void ivas_mdct_core_tns_ns_fx( } ELSE /*scaling to q_x+1*/ { - Scale_sig32( &x_fx[ch][k][0] + length, sub( L_spec[ch], length ), sub( add( q_x, 1 ), q_2 ) ); + Scale_sig32( &x_fx[ch][k][0] + length, sub( length2, length ), sub( add( q_x, 1 ), q_2 ) ); q_x = add( q_x, 1 ); } x_e[ch][k] = sub( 31, q_x ); -- GitLab From e737679cced80aae23567ec5c340f2700cfe6e05 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 09:09:07 +0100 Subject: [PATCH 0640/1221] Add some push/pops --- lib_dec/ivas_core_dec_fx.c | 64 +++++++++++++++++++++++++++++++------- lib_dec/ivas_jbm_dec_fx.c | 20 ++++++++++-- lib_dec/swb_tbe_dec_fx.c | 2 ++ 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 588640d0a..c367125e7 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -114,12 +114,12 @@ ivas_error ivas_core_dec_fx( error = IVAS_ERR_OK; move32(); - push_wmops( "ivas_core_dec" ); + push_wmops( "ivas_core_dec (ICD)" ); /*------------------------------------------------------------------* * General initialization *-----------------------------------------------------------------*/ - + push_wmops( "ICD init" ); use_cldfb_for_dft = 0; move16(); tdm_LRTD_flag = -1; @@ -368,7 +368,9 @@ ivas_error ivas_core_dec_fx( { save_hb_synth_32_fx = NULL; } + pop_wmops(); /*push_wmops( "ICD init" );*/ + push_wmops( "ICD SID, sanity" ); /*------------------------------------------------------------------* * Decode SID for MDCT-Stereo DTX mode *-----------------------------------------------------------------*/ @@ -396,7 +398,9 @@ ivas_error ivas_core_dec_fx( { ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } + pop_wmops(); /*push_wmops( "ICD SID, sanity" );*/ + push_wmops( "ICD Coredec" ); /*------------------------------------------------------------------* * Core Decoding *-----------------------------------------------------------------*/ @@ -481,6 +485,7 @@ ivas_error ivas_core_dec_fx( IF( st->core == ACELP_CORE ) { + push_wmops( "ICD ACELP" ); /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; @@ -553,14 +558,16 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) + pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } - + Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 test(); test(); IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { + push_wmops( "ICD TCX" ); Word16 Qsyn_temp; IVAS_FORMAT ivas_format; @@ -615,10 +622,12 @@ ivas_error ivas_core_dec_fx( } st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); move16(); + pop_wmops(); /*push_wmops( "ICD TCX" );*/ } - + IF( EQ_16( st->core, HQ_CORE ) ) { + push_wmops( "ICD HQ decoding" ); /* HQ core decoder */ Word16 Q_output; @@ -632,6 +641,7 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 + pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -649,7 +659,7 @@ ivas_error ivas_core_dec_fx( } } /* n_channels loop */ - + pop_wmops(); /*push_wmops( "ICD Coredec" );*/ /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Decoding @@ -657,6 +667,7 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { + push_wmops( "ICD jTCX Coredec" ); /* active-frame decoding */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) { @@ -785,6 +796,7 @@ ivas_error ivas_core_dec_fx( } } } + pop_wmops(); /*push_wmops( "ICD jTCX Coredec" );*/ } /*---------------------------------------------------------------------* @@ -794,6 +806,7 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { + push_wmops( "ICD Stereo CNG Updates" ); /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; Word32 c_PS_LT_fx; @@ -809,12 +822,14 @@ ivas_error ivas_core_dec_fx( stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); + pop_wmops(); /*push_wmops( "ICD Stereo CNG Updates" );*/ } /*---------------------------------------------------------------------* * Postprocessing, BWEs and updates *---------------------------------------------------------------------*/ + push_wmops( "ICD Postproc, BWE, updates (ICD PP)" ); FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; @@ -825,6 +840,7 @@ ivas_error ivas_core_dec_fx( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ + push_wmops( "ICD PP TDBWE ACELPTCX trans" ); /*core_switching_post_dec*/ Q_synth = sub( 15, e_sig[0] ); @@ -898,11 +914,12 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } + pop_wmops(); /*push_wmops( "ICD PP TDBWE ACELPTCX trans" );*/ /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP ACELP/MDCT switch" ); /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ test(); test(); @@ -937,11 +954,12 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } + pop_wmops(); /*push_wmops( "ICD PP ACELP/MDCT switch" );*/ /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP BWswitch preproc" ); ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); IF( st->hHQ_core == NULL ) @@ -988,12 +1006,13 @@ ivas_error ivas_core_dec_fx( hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } + pop_wmops(); /*push_wmops( "ICD PP BWswitch preproc" );*/ /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP TBE/BWE" ); Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; Word16 Q_syn_hb, sf; @@ -1021,8 +1040,9 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, WB_TBE ) ) { /* WB TBE decoder */ - + push_wmops( "ICD PP TBE/BWE wb_tbe_dec" ); ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_tbe_dec" );*/ } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) { @@ -1030,8 +1050,10 @@ ivas_error ivas_core_dec_fx( } ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) { + push_wmops( "ICD PP TBE/BWE wb_bwe_dec" ); /* WB BWE decoder */ Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_bwe_dec" );*/ } /* Memories Re-Scaling */ @@ -1075,8 +1097,10 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { + push_wmops( "ICD PP TBE/BWE swb_tbe_dec" ); /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec" );*/ Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx @@ -1091,18 +1115,22 @@ ivas_error ivas_core_dec_fx( /* FB TBE decoder */ IF( EQ_16( st->extl, FB_TBE ) ) { + push_wmops( "ICD PP TBE/BWE fb_tbe_dec" ); fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE fb_tbe_dec" );*/ } } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ + push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE" );*/ /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) @@ -1141,6 +1169,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) { + push_wmops( "ICD PP SWB CNG" ); /* SHB CNG decoder */ Word16 synth_fxl[960]; /* Q-2 */ Word16 q; @@ -1162,6 +1191,7 @@ ivas_error ivas_core_dec_fx( Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); + pop_wmops(); /* push_wmops( "ICD PP SWB CNG" );*/ } /*-------------------------------------------------------------------* @@ -1171,6 +1201,7 @@ ivas_error ivas_core_dec_fx( test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { + push_wmops( "ICD PP IC-BWE" ); Word16 q; q = 11; move16(); @@ -1192,10 +1223,12 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } + pop_wmops(); /*push_wmops( "ICD PP IC-BWE" );*/ } IF( EQ_16( st->element_mode, EVS_MONO ) ) { + push_wmops( "ICD PP BFI" ); /*----------------------------------------------------------------* * BFI waveform adjustment *----------------------------------------------------------------*/ @@ -1223,6 +1256,7 @@ ivas_error ivas_core_dec_fx( st->hPlcInfo->Pitch_fx = 0; move16(); } + pop_wmops(); /*push_wmops( "ICD PP BFI" );*/ } /*----------------------------------------------------------------* @@ -1235,6 +1269,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) { + push_wmops( "ICD PP Sync BWE" ); /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ IF( EQ_16( st->L_frame, L_FRAME ) ) { @@ -1388,6 +1423,7 @@ ivas_error ivas_core_dec_fx( st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } + pop_wmops(); /*push_wmops( "ICD PP Sync BWE" );*/ } test(); @@ -1403,7 +1439,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - + push_wmops( "ICD PP TCXLTP" ); IF( st->hHQ_core != NULL ) { Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 @@ -1460,6 +1496,7 @@ ivas_error ivas_core_dec_fx( } Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); + pop_wmops(); /*push_wmops( "ICD PP TCXLTP" );*/ /*--------------------------------------------------------* * Common updates @@ -1468,6 +1505,7 @@ ivas_error ivas_core_dec_fx( Word16 exp_max; Word32 output_fx_loc[L_FRAME48k]; + push_wmops( "ICD PP commonupdates" ); exp_max = 0; move16(); @@ -1522,6 +1560,8 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 + pop_wmops(); /*push_wmops( "ICD PP commonupdates" );*/ + } /* n_channels loop */ FOR( n = 0; n < n_channels; n++ ) @@ -1540,7 +1580,7 @@ ivas_error ivas_core_dec_fx( move16(); } } - + pop_wmops(); /*push_wmops( "ICD Postproc, BWE, updates (ICD PP)" );*/ pop_wmops(); return error; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 93e8bb4eb..31ac1a768 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -96,12 +96,13 @@ ivas_error ivas_jbm_dec_tc_fx( CPE_DEC_HANDLE hCPE; SCE_DEC_HANDLE hSCE; - push_wmops( "ivas_jbm_dec_tc" ); + push_wmops( "ivas_jbm_dec_tc (JBM)" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ + push_wmops( "JBM init" ); output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; @@ -134,7 +135,7 @@ ivas_error ivas_jbm_dec_tc_fx( } Word16 ch; - + pop_wmops(); /*push_wmops( "JBM init" );*/ /*----------------------------------------------------------------* * Decoding + pre-rendering @@ -152,6 +153,7 @@ ivas_error ivas_jbm_dec_tc_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { + push_wmops( "JBM STEREO" ); st_ivas->hCPE[0]->element_brate = ivas_total_brate; move32(); Word16 q_output = 11; @@ -192,9 +194,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } + pop_wmops(); /*push_wmops( "JBM STEREO" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { + push_wmops( "JBM ISM" ); /* Metadata decoding and configuration */ test(); IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) @@ -279,9 +283,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } + pop_wmops();/*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { + push_wmops( "JBM SBA/MASA" ); set16_fx( nb_bits_metadata, 0, MAX_SCE ); @@ -688,9 +694,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } + pop_wmops();/*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { + push_wmops( "JBM MASA_ISM" ); Word16 nchan_ism, nchan_transport_ism; Word16 dirac_bs_md_write_idx; @@ -821,9 +829,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 } } + pop_wmops(); /*push_wmops( "JBM MASA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { + push_wmops( "JBM SBA_ISM" ); Word16 nchan_ism, sba_ch_idx; set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -1092,10 +1102,11 @@ ivas_error ivas_jbm_dec_tc_fx( v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); } } + pop_wmops(); /*push_wmops( "JBM SBA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - + push_wmops( "JBM MC" ); // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; IF( st_ivas->nSCE > 0 ) { @@ -1468,6 +1479,7 @@ ivas_error ivas_jbm_dec_tc_fx( ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); } } + pop_wmops(); /*push_wmops( "JBM MC" );*/ } /*----------------------------------------------------------------* @@ -1476,7 +1488,9 @@ ivas_error ivas_jbm_dec_tc_fx( IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) { + push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); + pop_wmops();/*push_wmops( "JBM syn_out" );*/ } ELSE { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1b51a29fb..1e7af58c8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4713,7 +4713,9 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ + push_wmops( "synthesise_fb_high_band" ); synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) -- GitLab From 3a315e7b4f6b65f2fab68da9a828595775b655d3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 09:29:47 +0100 Subject: [PATCH 0641/1221] apply clang format patch --- lib_dec/ivas_core_dec_fx.c | 12 ++++++------ lib_dec/ivas_jbm_dec_fx.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index c367125e7..c0686bdfd 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -558,9 +558,9 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) - pop_wmops(); /*push_wmops( "ICD ACELP" );*/ + pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } - + Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 test(); @@ -624,7 +624,7 @@ ivas_error ivas_core_dec_fx( move16(); pop_wmops(); /*push_wmops( "ICD TCX" );*/ } - + IF( EQ_16( st->core, HQ_CORE ) ) { push_wmops( "ICD HQ decoding" ); @@ -641,7 +641,7 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ + pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -658,7 +658,7 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 } - } /* n_channels loop */ + } /* n_channels loop */ pop_wmops(); /*push_wmops( "ICD Coredec" );*/ /*---------------------------------------------------------------------* @@ -1125,7 +1125,7 @@ ivas_error ivas_core_dec_fx( /* SWB BWE decoder */ push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 31ac1a768..4745bc5f0 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -283,7 +283,7 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops();/*push_wmops( "JBM ISM" );*/ + pop_wmops(); /*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { @@ -694,7 +694,7 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops();/*push_wmops( "JBM SBA/MASA" );*/ + pop_wmops(); /*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { @@ -1490,7 +1490,7 @@ ivas_error ivas_jbm_dec_tc_fx( { push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); - pop_wmops();/*push_wmops( "JBM syn_out" );*/ + pop_wmops(); /*push_wmops( "JBM syn_out" );*/ } ELSE { -- GitLab From d47ab7007a46d6c7a6c853de24123b9523bf69af Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 25 Mar 2025 10:19:20 +0100 Subject: [PATCH 0642/1221] Reactivate FIX_867_CLDFB_NRG_SCALE. --- lib_com/options.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 4f818e0c3..c56ce1153 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -67,6 +67,8 @@ #define BASOP_NOGLOB_DECLARE_LOCAL #endif +#define FIX_867_CLDFB_NRG_SCALE + /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ -- GitLab From af758d0a32499efb520411f89da34eddfd05bf78 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 25 Mar 2025 10:45:27 +0100 Subject: [PATCH 0643/1221] Correct assert. --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index a837a79f0..0aee3c133 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2259,8 +2259,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth move32(); +#ifdef FIX_867_CLDFB_NRG_SCALE + assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] == h_dirac_output_synthesis_state->proto_power_smooth_q[0] ); + assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] == h_dirac_output_synthesis_state->proto_power_smooth_q[1] ); +#else assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q ); - +#endif IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) { p_power_smooth_prev++; -- GitLab From 74e7078328609715793fb3388b4b6fc52bc8880f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 12:58:54 +0100 Subject: [PATCH 0644/1221] add FIX_1439_SPEEDUP_elliptic_bpf_48k_generic STAGE1 --- lib_com/swb_tbe_com_fx.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..d066448c1 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6693,6 +6693,8 @@ void wb_tbe_extras_reset_synth_fx( * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic + void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6721,6 +6723,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6763,6 +6766,24 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic //STAGE1 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY = W_add( 0, 0 ); + W_tmpX = W_deposit32_l( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ) ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_sub( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 ) ) ); /*Q_input_fx + 11*/ + move32(); + } +#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6776,6 +6797,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } +#endif + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -7004,6 +7027,7 @@ void synthesise_fb_high_band_fx( Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7019,6 +7043,7 @@ void synthesise_fb_high_band_fx( } exp_tmp = sub( Q_fb_exc, 2 ); + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" ); IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ @@ -7029,6 +7054,10 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ + + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); temp1 = sum2_fx_mod( tmp, L_FRAME48k ); L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ @@ -7085,6 +7114,7 @@ void synthesise_fb_high_band_fx( move16(); } } + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; } -- GitLab From 446323f00943955d97a8db2069a04c13daca77a4 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 13:04:15 +0100 Subject: [PATCH 0645/1221] apply clang format patch --- lib_com/swb_tbe_com_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d066448c1..90d703cdd 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6766,7 +6766,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic //STAGE1 +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic // STAGE1 FOR( i = 4; i < L_FRAME48k; i++ ) { Word64 W_tmpX; @@ -6797,7 +6797,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } -#endif +#endif memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; @@ -7054,10 +7054,10 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); temp1 = sum2_fx_mod( tmp, L_FRAME48k ); L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ -- GitLab From 9917716df2d97438400d205f0c0678e3384c0cf7 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 25 Mar 2025 13:40:49 +0100 Subject: [PATCH 0646/1221] Correct assert. --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 0aee3c133..6149ab390 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -4292,21 +4292,20 @@ static void computeTargetPSDs_diffuse_subframe_fx( Word16 ch_idx, cur_idx; Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */ #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 q_cy_auto_diff_smooth_new; + Word16 q_cy_auto_diff_smooth_new, q_diffuse_power; #endif /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE - assert( q_reference_power[0] <= q_reference_power[1] ); - Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power[0], q_reference_power[1] ) ); - q_cy_auto_diff_smooth_new = q_reference_power[0]; - move16(); - IF( LT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) + q_diffuse_power = s_min( q_reference_power[0], q_reference_power[1] ); + Scale_sig32( diffuse_power, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_diffuse_power, q_reference_power[0] ) ); + Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_diffuse_power, q_reference_power[1] ) ); + q_cy_auto_diff_smooth_new = q_diffuse_power; + IF( LT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) ) { - assert( *q_cy_auto_diff_smooth <= q_reference_power[0] ); - Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_reference_power[0] ) ); + Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_cy_auto_diff_smooth_new ) ); q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth; move16(); } @@ -4317,10 +4316,9 @@ static void computeTargetPSDs_diffuse_subframe_fx( cur_idx = imult1616( ch_idx, num_freq_bands ); #ifdef FIX_867_CLDFB_NRG_SCALE - IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power[0] ) ) + IF( GT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) ) { - assert( q_reference_power[0] <= *q_cy_auto_diff_smooth ); - Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_reference_power[0], *q_cy_auto_diff_smooth ) ); + Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_diffuse_power, *q_cy_auto_diff_smooth ) ); } #endif v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ) ); // (q_reference_power, Q31) -> q_reference_power -- GitLab From 9938e11dacdd2d926276133ae94515f158f69647 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 14:32:11 +0100 Subject: [PATCH 0647/1221] fix FIX_1439_SPEEDUP_elliptic_bpf_48k_generic STAGE1 --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 90d703cdd..3f0bcf66c 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6780,7 +6780,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_sub( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); } #else -- GitLab From ff8566555dc4026028908632573ba986fcce3c9b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 15:51:45 +0100 Subject: [PATCH 0648/1221] introduced FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 and FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3, also FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 --- lib_com/prot_fx.h | 16 +++++++++ lib_com/swb_tbe_com_fx.c | 70 +++++++++++++++++++++++++++++++++++----- lib_enc/swb_tbe_enc_fx.c | 13 +++++++- 3 files changed, 90 insertions(+), 9 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d7ed9a140..0baa329fd 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,6 +59,10 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 /*----------------------------------------------------------------------------------* * Prototypes of global macros @@ -3258,6 +3262,17 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 +void elliptic_bpf_48k_generic_fx( + const Word16* input_fx, /* i : i signal Q_input_fx */ + Word16 *Q_input_fx, + Word16 output_fx[], /* o : output signal */ + Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ + Word16 memory_fx_Q[], + const Word16 full_band_bpf[][5], /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ + const Word32 *output32_fx, + const Word16 *scale_output32_fx); +#else void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : i signal Q_input_fx */ Word16 *Q_input_fx, @@ -3266,6 +3281,7 @@ void elliptic_bpf_48k_generic_fx( Word16 memory_fx_Q[], const Word16 full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ); +#endif void synthesise_fb_high_band_fx( const Word16 excitation_in[], /* i : full band excitation */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 3f0bcf66c..1dbe841a3 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -18,6 +18,8 @@ #define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ + + /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6692,9 +6694,8 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ - -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic - +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 +#else void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6703,6 +6704,7 @@ void elliptic_bpf_48k_generic_fx( Word16 memory_fx_Q[], const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) +#endif { Word16 i, j; Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; @@ -6766,14 +6768,14 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic // STAGE1 +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 FOR( i = 4; i < L_FRAME48k; i++ ) { Word64 W_tmpX; - Word64 W_tmpY = W_add( 0, 0 ); - W_tmpX = W_deposit32_l( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ) ); + Word64 W_tmpY; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); @@ -6853,6 +6855,26 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6867,7 +6889,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - +#endif Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -6936,7 +6958,29 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -6954,6 +6998,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } +#endif memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7047,12 +7092,21 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, NULL, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx, tmp32, scale_tmp32 ); +#else elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); +#endif } ELSE { /* for 12.8kHz ACELP core */ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, NULL, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx, tmp32, scale_tmp32 ); +#else elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); +#endif + } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 2b8f487bd..5d860c96f 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7324,8 +7324,11 @@ void fb_tbe_enc_fx( exp_temp = sub( exp_temp, 1 ); Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx, NULL, NULL ); +#else elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#endif Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7449,11 +7452,19 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx, NULL, NULL ); +#else elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#endif } ELSE { +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx, NULL, NULL ); +#else elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#endif } test(); -- GitLab From e3f013ae239351874fd1d87cc7abe9d7f1e1ce3d Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 25 Mar 2025 15:52:19 +0100 Subject: [PATCH 0649/1221] deactivated all speedups --- lib_com/prot_fx.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 0baa329fd..e3d0668a1 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,9 +59,9 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 /*----------------------------------------------------------------------------------* -- GitLab From 4daa1e064ea7bfb832467d3454c1f64bea014a54 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Mar 2025 20:26:54 +0530 Subject: [PATCH 0650/1221] Fix for 3GPP issue 1437: Decoder crash for McMASA 5.1 at 32kbps JBM decoding in ivas_fec_noise_filling_fx() Link #1437 --- lib_dec/FEC_HQ_phase_ecu_fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index b8c16474e..ef09c3de3 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -4565,13 +4565,13 @@ static void ivas_fec_noise_filling_fx( pt6 = &p_mdct_ola[0]; FOR( k = 0; k < tmp_fx; k++ ) { - L_tmp = L_mult( *sinq_tab, *sinq_tab ); /*Q30 */ + L_tmp = L_mult( *sinq_tab, *sinq_tab ); /*Q31 */ sinq_tab++; - q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ - q1 = round_fx( L_tmp ); /*Q15 */ - L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ - L_tmp = L_add( L_tmp, L_shr( Mpy_32_16_1( L_deposit_h( *pt6++ ), q2 ), Q_old_out ) ); /*Qsynth+16 */ - ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ + q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ + q1 = round_fx( L_tmp ); /*Q15 */ + L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ + L_tmp = L_add_sat( L_tmp, L_shr_sat( Mpy_32_16_1( L_deposit_h( *pt6++ ), q2 ), Q_old_out ) ); /*Qsynth+16 */ + ( *pt1++ ) = round_fx_sat( L_tmp ); /*Qsynth */ move16(); } -- GitLab From 95f5e56bdd38560e3edbaa979827f9fc19cd335e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Mar 2025 20:30:08 +0530 Subject: [PATCH 0651/1221] Fix for 3GPP issue 1436: Decoder crash for ParamMC at 48kbps FER mono/stereo decoding at 32 and 48 kHz in ivas_ls_setup_conversion_process_mdct_param_mc_fx() Link #1436 --- lib_dec/ivas_stereo_mdct_core_dec_fx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index cd7e92f71..890e5fc9e 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -469,6 +469,14 @@ void stereo_mdct_core_dec_fx( move16(); move16(); + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + if ( NE_16( hCPE->hCoreCoder[ch]->core, TCX_20_CORE ) ) + { + x_e[ch][1] = x_e[ch][0]; + move16(); + } + } stereo_decoder_tcx_fx( hCPE->hStereoMdct, ms_mask, x_0_fx[1], x_fx[0], x_fx[1], &hCPE->hStereoMdct->mdct_stereo_mode[0], sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], L_frameTCX[1], 0, sts[0]->last_core, sts[1]->last_core, 0, &q_x_1, &q_x_0 ); } -- GitLab From 690a6fe1305f27f94501c7c1bf8609110bb35002 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Mar 2025 20:34:27 +0530 Subject: [PATCH 0652/1221] Bug fix in tcx_ltp_enc and swb_tbe_enc --- lib_enc/swb_tbe_enc_fx.c | 4 ++-- lib_enc/tcx_ltp_enc_fx.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 2b8f487bd..c5d5e651e 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -3835,8 +3835,8 @@ void swb_tbe_enc_ivas_fx( tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ tmp = sub( 32767 /*1.0f Q15*/, tmp ); - Lscale = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + L_tmp = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); + L_tmp = Mult_32_16( L_tmp, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ move16(); } diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index 25a3bdee7..84f83a311 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -931,9 +931,9 @@ void tcx_ltp_encode_ivas_fx( { hTcxEnc->tcxltp_pitch_int_past = L_frame; move16(); - hTcxEnc->tcxltp_pitch_int_past = 0; + hTcxEnc->tcxltp_pitch_fr_past = 0; move16(); - hTcxEnc->tcxltp_pitch_int_past = 0; + hTcxEnc->tcxltp_gain_past = 0; move16(); } -- GitLab From 0d92e4ff01548c56e8f3638544878cc00c661a74 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Mar 2025 12:42:25 +0530 Subject: [PATCH 0653/1221] Fix for 3GPP issue 1434: [regression] Encoder crash for MDCT Stereo at 80 kbps and above in stereo_mdct_core_enc_fx() Link #1434 --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 804bcff5c..3becb30d9 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -363,26 +363,24 @@ void stereo_mdct_core_enc_fx( move16(); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - length = sts[ch]->hTcxEnc->L_frameTCX; - move16(); - } - ELSE + length = sts[ch]->hTcxEnc->L_frameTCX; + move16(); + if ( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); } - FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + + hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[0], length ) ); + hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][0], length ) ); + + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[k], length ) ); - hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][k], length ) ); + hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[1], length ) ); + hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][1], length ) ); } } - IF( hdrm_min != 0 ) - { - q_spec = sub( add( hdrm_min, q_spec ), 1 ); /*1 guard bit to avoid over-flows*/ - } + q_spec = sub( add( hdrm_min, q_spec ), 2 ); /* 2 guard bits to avoid over-flows (1 for stereo_coder_tcx_fx and other for power spectrum calculation )*/ FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -- GitLab From fa18e7dff4ca45f79b937fbf4ad5b23a3cc143ad Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Mar 2025 09:38:56 +0530 Subject: [PATCH 0654/1221] Fix for 3GPP issue 1408: Decoder crash for ParamMC 5.1 at 48/64/80 kbps decoding to mono in ivas_ls_setup_conversion_fx() Link #1408 --- lib_dec/ivas_out_setup_conversion_fx.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index fc69d3919..93a7c204e 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -657,6 +657,7 @@ void ivas_ls_setup_conversion_process_mdct_fx( Word16 transform_type[MAX_CICP_CHANNELS][2]; Word16 frameSize; Word32 targetEnergy[MAX_SFB + 2], dmxEnergy[MAX_SFB + 2]; + Word16 dmxEnergy_exp[MAX_SFB + 2], dmxEnergy_exp_temp; Word32 dmxCoeff; Word32 dmxSignalReal[L_FRAME48k], dmxSignalImag[L_FRAME48k]; Word32 eqGain; @@ -739,6 +740,9 @@ void ivas_ls_setup_conversion_process_mdct_fx( set32_fx( targetEnergy, 0, MAX_SFB + 2 ); set32_fx( dmxEnergy, 0, MAX_SFB + 2 ); + set16_fx( dmxEnergy_exp, 0, MAX_SFB + 2 ); + dmxEnergy_exp_temp = 0; + move16(); FOR( chOutIdx = 0; chOutIdx < outChannels; chOutIdx++ ) { @@ -829,6 +833,7 @@ void ivas_ls_setup_conversion_process_mdct_fx( FOR( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) { Word32 tmpReal, tmpImag, DMXEne; + Word16 DMXEne_exp; start = hLsSetUpConversion->sfbOffset[bandIdx]; move16(); @@ -838,6 +843,8 @@ void ivas_ls_setup_conversion_process_mdct_fx( /* Loop over all the bins in the band */ DMXEne = 0; move32(); + DMXEne_exp = 0; + move16(); FOR( binIdx = start; binIdx < stop; binIdx++ ) { tmpReal = dmxSignalReal[binIdx]; @@ -845,13 +852,20 @@ void ivas_ls_setup_conversion_process_mdct_fx( tmpImag = dmxSignalImag[binIdx]; move32(); - DMXEne = L_add( DMXEne, L_add( Mpy_32_32( tmpReal, tmpReal ), Mpy_32_32( tmpImag, tmpImag ) ) ); + DMXEne = BASOP_Util_Add_Mant32Exp( DMXEne, DMXEne_exp, L_add( Mpy_32_32( tmpReal, tmpReal ), Mpy_32_32( tmpImag, tmpImag ) ), sub( 40, shl( q_output, 1 ) ), &DMXEne_exp ); } - dmxEnergy[bandIdx] = L_add( dmxEnergy[bandIdx], DMXEne ); + dmxEnergy[bandIdx] = BASOP_Util_Add_Mant32Exp( dmxEnergy[bandIdx], dmxEnergy_exp[bandIdx], DMXEne, DMXEne_exp, &dmxEnergy_exp[bandIdx] ); move32(); + dmxEnergy_exp_temp = s_max( dmxEnergy_exp_temp, dmxEnergy_exp[bandIdx] ); } } /* end of out channel loop */ + /* Scaling to common exponent */ + FOR( bandIdx = 0; bandIdx < MAX_SFB + 2; bandIdx++ ) + { + dmxEnergy[bandIdx] = L_shl( dmxEnergy[bandIdx], sub( dmxEnergy_exp[bandIdx], dmxEnergy_exp_temp ) ); + move32(); + } /* Step 3: Peform energy smoothing */ Word16 te_scale = getScaleFactor32( hLsSetUpConversion->targetEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt ); @@ -860,13 +874,13 @@ void ivas_ls_setup_conversion_process_mdct_fx( scale_sig32( hLsSetUpConversion->dmxEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt, dmx_sacle ); Word16 te_max_e = s_max( sub( 40, shl( q_output, 1 ) ), sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ); - Word16 dmx_max_e = s_max( sub( 40, shl( q_output, 1 ) ), sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ); + Word16 dmx_max_e = s_max( dmxEnergy_exp_temp, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ); FOR( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) { targetEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( targetEnergy[bandIdx], sub( te_max_e, sub( 40, shl( q_output, 1 ) ) ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], sub( te_max_e, sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ) ) ) ); move32(); - dmxEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( dmxEnergy[bandIdx], sub( dmx_max_e, sub( 40, shl( q_output, 1 ) ) ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], sub( dmx_max_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ) ) ) ); + dmxEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( dmxEnergy[bandIdx], sub( dmx_max_e, dmxEnergy_exp_temp ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], sub( dmx_max_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ) ) ) ); move32(); hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx] = targetEnergy[bandIdx]; /* te_prev_exp = 40 - 2*q_output */ move32(); -- GitLab From 92576ecee5692b22a8f2f9f514b296ad703f26b7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Mar 2025 10:12:28 +0530 Subject: [PATCH 0655/1221] Fix for 3GPP issue 1424: Audible differences in the CNG generated at SBA 32 kbps and 16.4 kbps, DTX ON Link #1424 --- lib_enc/ivas_front_vad_fx.c | 39 +++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index a53e40ee6..25a936566 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -666,14 +666,45 @@ ivas_error front_vad_spar_fx( old_pitch = st->pitch[1]; move16(); - Scale_sig( wsp_fx, 368, sub( Q8, Q_inp_12k8 ) ); // Q8 - pitch_ol_ivas_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift_fx, &st->old_thres_fx, &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR, Q8 ); + Word16 shift, Q_wsp; + Word16 shift1 = norm_arr( old_wsp_fx, L_WSP_MEM ); + Word16 shift2 = norm_arr( wsp_fx, L_WSP - L_WSP_MEM ); + maximum_abs_16_fx( old_wsp_fx, L_WSP_MEM, &shift ); + if ( !shift ) + { + shift1 = Q15; + move16(); + } + maximum_abs_16_fx( wsp_fx, L_WSP - L_WSP_MEM, &shift ); + if ( !shift ) + { + shift2 = Q15; + move16(); + } + + shift = s_min( Q15, s_min( add( Q_inp_12k8, shift1 ), add( Q_inp_12k8, shift2 ) ) ); + shift = s_min( shift, add( norm_arr( st->mem_decim2_fx, 3 ), st->Q_old_wsp2 ) ); + shift = s_min( shift, add( norm_arr( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ), st->Q_old_wsp2 ) ); + + scale_sig( old_wsp_fx, L_WSP_MEM, sub( shift, Q_inp_12k8 ) ); + scale_sig( wsp_fx, L_WSP - L_WSP_MEM, sub( shift, Q_inp_12k8 ) ); + + Q_wsp = shift; + move16(); + + scale_sig( st->mem_decim2_fx, 3, sub( Q_wsp, st->Q_old_wsp2 ) ); // Q( mem_decim ) = Q( old_wsp2 ) + scale_sig( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM, sub( Q_wsp, st->Q_old_wsp2 ) ); // Q_wsp + + st->Q_old_wsp2 = Q_wsp; + move16(); + + pitch_ol_ivas_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift_fx, &st->old_thres_fx, &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR, Q_wsp ); /* Updates for adaptive lag window memory */ st->old_pitch_la = st->pitch[2]; /* Q0 */ move16(); - Scale_sig( wsp_fx, 368, Q9 - Q8 ); /* Q9 */ - StableHighPitchDetect_ivas_fx( &flag_spitch, st->pitch, st->voicing_fx, wsp_fx, st->localVAD, &st->voicing_sm_fx, &st->voicing0_sm_fx, &st->LF_EnergyRatio_sm_fx, &st->predecision_flag, &st->diff_sm_fx, &st->energy_sm_fx, Q12, st->lgBin_E_fx ); + + StableHighPitchDetect_ivas_fx( &flag_spitch, st->pitch, st->voicing_fx, wsp_fx, st->localVAD, &st->voicing_sm_fx, &st->voicing0_sm_fx, &st->LF_EnergyRatio_sm_fx, &st->predecision_flag, &st->diff_sm_fx, &st->energy_sm_fx, Q_wsp, st->lgBin_E_fx ); IF( st->hSpMusClas != NULL ) { Word16 dummy_int; -- GitLab From 552d615d6e4ee3a56636be80b55a79721c0445fc Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Mar 2025 12:09:08 +0530 Subject: [PATCH 0656/1221] Synth state buffer scaling/rescaling cleanup --- lib_com/cldfb.c | 113 +++++++++++++----- lib_com/options.h | 1 + lib_com/prot_fx.h | 13 +- lib_dec/acelp_core_dec_ivas_fx.c | 29 ++++- lib_dec/acelp_core_switch_dec_fx.c | 9 ++ lib_dec/core_switching_dec_fx.c | 8 ++ lib_dec/ivas_dirac_dec_fx.c | 17 ++- lib_dec/ivas_ism_param_dec_fx.c | 4 + lib_dec/ivas_mc_param_dec_fx.c | 5 + lib_dec/ivas_mc_paramupmix_dec_fx.c | 18 ++- lib_dec/ivas_spar_decoder_fx.c | 12 ++ lib_enc/swb_pre_proc_fx.c | 4 + .../ivas_dirac_dec_binaural_functions_fx.c | 4 + lib_rend/ivas_dirac_rend_fx.c | 4 + 14 files changed, 202 insertions(+), 39 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 845ec1f11..720ee37a0 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -399,18 +399,28 @@ void cldfbAnalysis_ts_fx( /* folding + pre modulation of DST IV */ rr12_fx = L_sub( r1_fx, r2_fx ); // q -1 ri12_fx = L_negate( L_add( i1_fx, i2_fx ) ); // q - 1 - /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ - rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 - rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + rBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), ri12_fx, rot_vctr_im_fx[k] ); // q - 3 + rBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), ri12_fx, rot_vctr_re_fx[k] ); // q - 3 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ move32(); move32(); ///* folding + pre modulation of DCT IV */ ir12_fx = L_add( r1_fx, r2_fx ); // q - 1 ii12_fx = L_sub( i1_fx, i2_fx ); // q - 1 - /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ - iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 - iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + iBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), ii12_fx, rot_vctr_im_fx[k] ); // q - 3 + iBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), ii12_fx, rot_vctr_re_fx[k] ); // q - 3 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ move32(); move32(); } @@ -450,18 +460,28 @@ void cldfbAnalysis_ts_fx( /* folding + pre modulation of DST IV */ rr12_fx = L_add( r1_fx, r2_fx ); // q - 1 ri12_fx = L_sub( i1_fx, i2_fx ); // q - 1 - /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ - rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 - rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + rBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), ri12_fx, rot_vctr_im_fx[k] ); // q - 3 + rBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), ri12_fx, rot_vctr_re_fx[k] ); // q - 3 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + rBuffer_fx[2 * k] = L_sub( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + rBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ri12_fx, rot_vctr_re_fx[k] ) ); // q - 3 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ move32(); move32(); /* folding + pre modulation of DCT IV */ ir12_fx = L_sub( r1_fx, r2_fx ); // q - 1 ii12_fx = L_add( i1_fx, i2_fx ); // q - 1 - /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ - iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 - iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + iBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), ii12_fx, rot_vctr_im_fx[k] ); // q - 3 + iBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), ii12_fx, rot_vctr_re_fx[k] ); // q - 3 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + iBuffer_fx[2 * k] = L_sub( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_im_fx[k] ) ); // q - 3 + iBuffer_fx[2 * k + 1] = L_add( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), Mpy_32_32( ii12_fx, rot_vctr_re_fx[k] ) ); // q - 3 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ move32(); move32(); } @@ -490,8 +510,13 @@ void cldfbAnalysis_ts_fx( FOR( k = 0; k < M2; k++ ) { /*cplxMult(&realBuffer[M1-1-(2*k)],&realBuffer[2*k],rBuffer[2*k],rBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + realBuffer_fx[( ( M1 - 1 ) - ( k * 2 ) )] = Msub_32_32( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_re_fx[k] ), rBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ); // q - 5 + realBuffer_fx[2 * k] = Madd_32_32( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_im_fx[k] ), rBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ); // q - 5 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ realBuffer_fx[( ( M1 - 1 ) - ( k * 2 ) )] = L_sub( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( rBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 realBuffer_fx[2 * k] = L_add( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( rBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ move32(); move32(); } @@ -520,8 +545,13 @@ void cldfbAnalysis_ts_fx( { /* do it inplace */ /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ - imagBuffer_fx[2 * k] = L_sub( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 - imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = L_add( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 +#ifdef OPT_AVOID_STATE_BUF_RESCALE + imagBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ); // q - 5 + imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = Madd_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ); // q - 5 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + imagBuffer_fx[2 * k] = L_sub( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ) ); // q - 5 + imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = L_add( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), Mpy_32_32( iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ) ); // q - 5 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ move32(); move32(); } @@ -542,8 +572,13 @@ void cldfbAnalysis_ts_fx( /*cplxMult(&realBuffer[k], &imagBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ /*realBuffer[k] = rBuffer[k]; imagBuffer[k] = iBuffer[k];*/ - cplx_aux_fx = L_sub( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_re_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_im_fx[k] ) ); // q - 5 - imagBuffer_fx[k] = L_add( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_im_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_re_fx[k] ) ); // q - 5 +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cplx_aux_fx = Msub_32_32( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_re_fx[k] ), imagBuffer_fx[k], rot_vctr_delay_im_fx[k] ); // q - 5 + imagBuffer_fx[k] = Madd_32_32( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_im_fx[k] ), imagBuffer_fx[k], rot_vctr_delay_re_fx[k] ); // q - 5 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + cplx_aux_fx = L_sub( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_re_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_im_fx[k] ) ); // q - 5 + imagBuffer_fx[k] = L_add( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_im_fx[k] ), Mpy_32_32( imagBuffer_fx[k], rot_vctr_delay_re_fx[k] ) ); // q - 5 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ realBuffer_fx[k] = cplx_aux_fx; move32(); move32(); @@ -1091,17 +1126,21 @@ void cldfbAnalysis_ts_fx_fixed_q( return; } + /*-------------------------------------------------------------------* * cldfbSynthesis_ivas() * * Conduct inverse multple overlap cmplex low delay MDCT *--------------------------------------------------------------------*/ void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ - const Word16 shift, /* i : scale for state buffer */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ + const Word16 shift, /* i : scale for state buffer */ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + const Word16 out_shift, /* i : scale for output buffer */ +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ) { @@ -1295,11 +1334,11 @@ void cldfbSynthesis_ivas_fx( FOR( i = 0; i < L2; i++ ) { Word32 prod = L_shl_sat( Mpy_32_16_1( new_samples_fx[L2 - 1 - i], p_filter_sf ), shift ); - accu0 = Madd_32_16( synthesisBuffer_fx[i], prod, p_filter[i] ); // Qx - 1 - accu1 = Madd_32_16( synthesisBuffer_fx[1 * L2 + i], prod, p_filter[( 1 * L2 + i )] ); // Qx - 1 - accu2 = Madd_32_16( synthesisBuffer_fx[2 * L2 + i], prod, p_filter[( 2 * L2 + i )] ); // Qx - 1 - accu3 = Madd_32_16( synthesisBuffer_fx[3 * L2 + i], prod, p_filter[( 3 * L2 + i )] ); // Qx - 1 - accu4 = Madd_32_16( synthesisBuffer_fx[4 * L2 + i], prod, p_filter[( 4 * L2 + i )] ); // Qx - 1 + accu0 = Madd_32_16( synthesisBuffer_fx[i], prod, p_filter[i] ); // Qx -1 + shift + accu1 = Madd_32_16( synthesisBuffer_fx[1 * L2 + i], prod, p_filter[( 1 * L2 + i )] ); // Qx -1 + shift + accu2 = Madd_32_16( synthesisBuffer_fx[2 * L2 + i], prod, p_filter[( 2 * L2 + i )] ); // Qx -1 + shift + accu3 = Madd_32_16( synthesisBuffer_fx[3 * L2 + i], prod, p_filter[( 3 * L2 + i )] ); // Qx -1 + shift + accu4 = Madd_32_16( synthesisBuffer_fx[4 * L2 + i], prod, p_filter[( 4 * L2 + i )] ); // Qx -1 + shift synthesisBuffer_fx[i] = accu0; move32(); @@ -1314,11 +1353,26 @@ void cldfbSynthesis_ivas_fx( } } - FOR( i = 0; i < M1; i++ ) +#ifdef OPT_AVOID_STATE_BUF_RESCALE + IF( 0 == out_shift ) { - ptr_time_out_fx[( M1 - 1 ) - i] = synthesisBuffer_fx[4 * L2 + M1 + i]; - move32(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ + FOR( i = 0; i < M1; i++ ) + { + ptr_time_out_fx[( M1 - 1 ) - i] = synthesisBuffer_fx[4 * L2 + M1 + i]; + move32(); + } +#ifdef OPT_AVOID_STATE_BUF_RESCALE } + ELSE + { + FOR( i = 0; i < M1; i++ ) + { + ptr_time_out_fx[( M1 - 1 ) - i] = L_shl_sat( synthesisBuffer_fx[4 * L2 + M1 + i], out_shift ); + move32(); + } + } +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ ptr_time_out_fx += M1; @@ -1333,7 +1387,6 @@ void cldfbSynthesis_ivas_fx( return; } - void configureCldfb_ivas_enc_fx( HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ const Word32 sampling_rate /* i : sampling rate */ diff --git a/lib_com/options.h b/lib_com/options.h index 4f818e0c3..8f404dd74 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -69,6 +69,7 @@ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +#define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ #define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d7ed9a140..851b461bf 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9740,11 +9740,14 @@ void cldfbAnalysis_ivas_fx( ); void cldfbSynthesis_ivas_fx( - Word32 **realBuffer_fx, /* i : real values Qx*/ - Word32 **imagBuffer_fx, /* i : imag values Qx*/ - Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ - const Word16 samplesToProcess, /* i : number of processed samples */ - const Word16 shift, /* i : scale for state buffer */ + Word32 **realBuffer_fx, /* i : real values Qx*/ + Word32 **imagBuffer_fx, /* i : imag values Qx*/ + Word32 *timeOut_fx, /* o : output time domain samples Qx - 1*/ + const Word16 samplesToProcess, /* i : number of processed samples */ + const Word16 shift, /* i : scale for state buffer */ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + const Word16 out_shift, /* i : scale for output buffer */ +#endif HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index bd8c6ec93..38999e99e 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1807,6 +1807,7 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_imag ); // Q_imag } +#ifndef OPT_AVOID_STATE_BUF_RESCALE #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ @@ -1814,6 +1815,7 @@ ivas_error acelp_core_dec_ivas_fx( #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { @@ -1833,12 +1835,18 @@ ivas_error acelp_core_dec_ivas_fx( } } +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, sub( Q11, Q_real ), -10, st->cldfbSynHB ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, 0, st->cldfbSynHB ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ +#ifndef OPT_AVOID_STATE_BUF_RESCALE Scale_sig32( save_hb_synth_fx, L_FRAME48k, negate( ( sub( Q_real, 1 ) ) ) ); // Q0 Scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSynHB->Q_cldfb_state = Q10; move16(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ /* restore lowband */ FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { @@ -1850,14 +1858,21 @@ ivas_error acelp_core_dec_ivas_fx( move32(); } } +#ifndef OPT_AVOID_STATE_BUF_RESCALE Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // Q_real-1 st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ + +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, sub( Q11, Q_real ), -10, st->cldfbSyn ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, 0, st->cldfbSyn ); Scale_sig32( synth_fx, L_FRAME48k, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSynHB->Q_cldfb_state = Q10; move16(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ } ELSE { @@ -1892,12 +1907,16 @@ ivas_error acelp_core_dec_ivas_fx( #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, 0, st->cldfbSyn ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, 0, st->cldfbSyn ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; @@ -1985,18 +2004,26 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real } +#ifndef OPT_AVOID_STATE_BUF_RESCALE #ifdef OPT_STEREO_32KBPS_V1 scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) #else /* OPT_STEREO_32KBPS_V1 */ scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) #endif /* OPT_STEREO_32KBPS_V1 */ +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), sub( Q10, sub( Q_real, 1 ) ), -10, st->cldfbSyn ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), 0, st->cldfbSyn ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ +#ifndef OPT_AVOID_STATE_BUF_RESCALE Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 Scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q10, sub( Q_real, 1 ) ) ); // Q10 st->cldfbSyn->Q_cldfb_state = Q10; move16(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ IF( st->p_bpf_noise_buf_32 ) { Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 9013f2f03..765749188 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -832,16 +832,25 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( } /*cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer );*/ +#ifndef OPT_AVOID_STATE_BUF_RESCALE Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, 1 ); // Q_cldfb_state+1 st_fx->cldfbSyn->Q_cldfb_state = add( st_fx->cldfbSyn->Q_cldfb_state, 1 ); move16(); Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), 0, st_fx->cldfbSyn ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + Word16 out_len = extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ); + cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, out_len, -1, 0, st_fx->cldfbSyn ); + Copy_Scale_sig_32_16( synth32, synth_out, out_len, -4 ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ + +#ifndef OPT_AVOID_STATE_BUF_RESCALE Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); move16(); Copy_Scale_sig_32_16( synth32, synth_out, L_FRAME48k, -5 ); // 11-5-1 -> 11 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ // Scale_sig( synth_out, L_FRAME48k, negate( st_fx->Q_syn ) ); diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 05125318f..ba7c73741 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -2056,7 +2056,11 @@ static void core_switch_lb_upsamp_fx( } /* synthesis of the combined signal */ +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), 0, 0, st->cldfbSyn ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), 0, st->cldfbSyn ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ /*rescaling whole buffer to a common Q*/ no_col = st->cldfbSyn->no_col; @@ -2364,7 +2368,11 @@ ivas_error core_switching_pre_dec_ivas_fx( return error; } +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, 0, 0, st->cldfbSyn ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, 0, st->cldfbSyn ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ cldfb_restore_memory_ivas_fx( st->cldfbSyn ); Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index b45f54d48..e6c08669e 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3743,7 +3743,11 @@ void ivas_dirac_dec_render_sf_fx( st_ivas->cldfbSynDec[ch]->Q_cldfb_state = ( Q6 - 1 ); move16(); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ Word16 no_col = st_ivas->cldfbSynDec[ch]->no_col; move16(); @@ -3846,7 +3850,11 @@ void ivas_dirac_dec_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; move32(); } +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, 0, 0, st_ivas->cldfbSynDec[idx_in] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_buf_fx[ch][subframe_start_sample] ), num_samples_subframe, 0, st_ivas->cldfbSynDec[idx_in] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE*/ IF( !st_ivas->hLsSetupCustom->separate_ch_found ) { @@ -3886,7 +3894,11 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state ) ); // Q6-1 st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state = ( Q6 - 1 ); move16(); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, 0, st_ivas->cldfbSynDec[cldfbSynIdx] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[cldfbSynIdx] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE*/ // Calculating length of output Word16 no_col = st_ivas->cldfbSynDec[cldfbSynIdx]->no_col; @@ -3954,8 +3966,11 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state ) ); st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = ( Q6 - 1 ); move16(); - +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, 0, st_ivas->cldfbSynDec[idx_in] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, p_out, samplesToProcess, 0, st_ivas->cldfbSynDec[idx_in] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ // Scaling output from Q6-1 to Q11 Scale_sig32( p_out, out_len, ( Q11 - ( Q6 - 1 ) ) ); diff --git a/lib_dec/ivas_ism_param_dec_fx.c b/lib_dec/ivas_ism_param_dec_fx.c index 7686a5e8a..30a32c92c 100644 --- a/lib_dec/ivas_ism_param_dec_fx.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1533,7 +1533,11 @@ static void ivas_ism_param_dec_render_sf_fx( Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( sub( Q_real, 1 ), Q11 ) ); // Q_real-1 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( Q11, sub( Q_real, 1 ) ) ); // Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 4c0e7fcc6..5f93c9676 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -2189,8 +2189,13 @@ void ivas_param_mc_dec_render_fx( Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); scale_sig32( output_f_fx[ch], len, 5 - 11 ); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), + imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 } diff --git a/lib_dec/ivas_mc_paramupmix_dec_fx.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c index 40f9f46e2..783b94940 100644 --- a/lib_dec/ivas_mc_paramupmix_dec_fx.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -866,18 +866,28 @@ static void ivas_mc_paramupmix_dec_sf( RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch][slot_idx]; // Q6 ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch][slot_idx]; // Q6 } +#ifndef OPT_AVOID_STATE_BUF_RESCALE scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q5 - Q11 ); // Q11 -> Q5 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5; move16(); cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), 0, st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q5 - scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q5 -> Q11 +#else /* OPT_AVOID_STATE_BUF_RESCALE */ + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch][0] ), imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), 6, 0, st_ivas->cldfbSynDec[ch] ); // output_fx returned in Q11 +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ + +#ifndef OPT_AVOID_STATE_BUF_RESCALE + scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q5 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; move16(); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ } + +#ifndef OPT_AVOID_STATE_BUF_RESCALE FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { Scale_sig32( output_fx[ch], imult1616( maxBand, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ), 6 ); // Q5 -> Q11 } +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ } ELSE { @@ -903,9 +913,13 @@ static void ivas_mc_paramupmix_dec_sf( ptr_re_fx[0] = Cldfb_RealBuffer_fx[ch][slot_idx]; // Q6 ptr_im_fx[0] = Cldfb_ImagBuffer_fx[ch][slot_idx]; // Q6 - +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), + hMCParamUpmix->num_freq_bands, 0, 0, st_ivas->cldfbSynDec[ch] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( ptr_re_fx, ptr_im_fx, &( pPcm_temp_fx[ch][L_mult0( hMCParamUpmix->num_freq_bands, slot_idx )] ), hMCParamUpmix->num_freq_bands, 0, st_ivas->cldfbSynDec[ch] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ } scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); // Q6 -> Q11 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; diff --git a/lib_dec/ivas_spar_decoder_fx.c b/lib_dec/ivas_spar_decoder_fx.c index a7b66ff87..29a307425 100644 --- a/lib_dec/ivas_spar_decoder_fx.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -787,7 +787,11 @@ void ivas_spar_get_cldfb_gains_fx( cldfbAnalysis_ts_fx_fixed_q( ts_inout_fx, ts_re_fx, ts_im_fx, num_cldfb_bands, cldfbAnaDec0, &q_cldfb ); cldfb_reset_memory_fx( cldfbSynDec0 ); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, 0, 0, cldfbSynDec0 ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, 0, cldfbSynDec0 ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ FOR( sample = 0; sample < stride; sample++ ) { T_fx[( ( slot * stride ) + sample )][slot] = ts_inout_fx[sample]; /*Q21*/ @@ -2037,7 +2041,11 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, 0, st_ivas->cldfbSynDec[idx_in] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[idx_in] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ } } @@ -2052,7 +2060,11 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, 0, st_ivas->cldfbSynDec[out_ch] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, st_ivas->cldfbSynDec[out_ch] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ } } } diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index c49c32e03..ba165cba4 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1263,7 +1263,11 @@ void swb_pre_proc_ivas_fx( thr = icbwe_thr_TDM_fx; regV = icbwe_regressionValuesTDM_fx; +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, 0, 0, st->cldfbSynTd ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, 0, st->cldfbSynTd ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ Copy_Scale_sig_32_16( shb_speech_fx_32, shb_speech, L_FRAME16k, negate( sub( q_reImBuffer, 1 ) ) ); *Q_shb_spch = 0; move16(); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 2376babcd..ce602160f 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -2579,7 +2579,11 @@ static void ivas_dirac_dec_binaural_process_output_fx( outSlotRePr_fx = &( outSlotRe_fx[0] ); outSlotImPr_fx = &( outSlotIm_fx[0] ); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, 0, 0, cldfbSynDec[chA] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, 0, cldfbSynDec[chA] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 ); move16(); } diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 59c93ae55..efa0b35e6 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4189,7 +4189,11 @@ static void ivas_masa_ext_dirac_render_sf_fx( ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; // q_cldfb } Word16 out_size = imult1616( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); +#ifdef OPT_AVOID_STATE_BUF_RESCALE + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, 0, 0, hMasaExtRend->cldfbSynRend[idx_in] ); +#else /* OPT_AVOID_STATE_BUF_RESCALE */ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, 0, hMasaExtRend->cldfbSynRend[idx_in] ); +#endif /* OPT_AVOID_STATE_BUF_RESCALE */ scale_sig32( &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, sub( 11, q_out ) ); // q11 idx_in++; } -- GitLab From 924d09ab17a9ad80c97a386222f30c5a94a2de29 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 26 Mar 2025 09:25:25 +0100 Subject: [PATCH 0657/1221] Increase precision of computeTargetPSDs_direct_subframe_fx(). --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 6149ab390..0f1a33ed5 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -4136,10 +4136,12 @@ static void computeTargetPSDs_direct_subframe_fx( Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/ Word16 *q_cy_cross_dir_smooth ) { - Word16 ch_idx, cur_idx, i, q_tmp; #ifdef FIX_867_CLDFB_NRG_SCALE + Word16 ch_idx, cur_idx, q_tmp; Word32 L_tmp[CLDFB_NO_CHANNELS_MAX]; + Word16 q_cy_auto_dir_smooth_local[2]; #else + Word16 ch_idx, cur_idx, i, q_tmp; Word64 W_tmp[CLDFB_NO_CHANNELS_MAX], W_max; set64_fx( W_tmp, 0, CLDFB_NO_CHANNELS_MAX ); #endif @@ -4148,19 +4150,21 @@ static void computeTargetPSDs_direct_subframe_fx( Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ /* estimate direct and diffuse power */ +#ifndef FIX_867_CLDFB_NRG_SCALE FOR( i = 0; i < num_freq_bands; i++ ) { direct_power[i] = Mpy_32_32( direct_power_factor[i], reference_power[i] ); move32(); -#ifndef FIX_867_CLDFB_NRG_SCALE test(); if ( direct_power[i] == 0 && ( direct_power_factor[i] != 0 && reference_power[i] != 0 ) ) { direct_power[i] = 1; move32(); } -#endif } +#else + v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { @@ -4206,9 +4210,15 @@ static void computeTargetPSDs_direct_subframe_fx( q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands ); Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp ); v_mult_fixed( direct_power, L_tmp, &cy_auto_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, q_tmp) -> q_reference_power + q_tmp - Scale_sig32( &cy_auto_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) ); - q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); + + q_cy_auto_dir_smooth_local[0] = add( add( q_reference_power[0], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_cy_auto_dir_smooth_local[1] = add( add( q_reference_power[1], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ) ) ); + q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] ); move16(); + + Scale_sig32( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[0], q_tmp ) ) ); + Scale_sig32( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[1], q_tmp ) ) ); + #endif v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power #ifdef FIX_867_CLDFB_NRG_SCALE -- GitLab From 44ade3447be3a5b798713ca270cc025965076141 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:33:01 +0100 Subject: [PATCH 0658/1221] introduce FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig and FIX_1439_SPEEDUP_sum2_fx_mod , delete FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 - activate FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig which should be BE --- lib_com/prot_fx.h | 20 ++-- lib_com/swb_tbe_com_fx.c | 214 +++++++++++++++++++++++++++++++++------ lib_com/tools_fx.c | 18 +++- lib_enc/swb_tbe_enc_fx.c | 12 --- 4 files changed, 205 insertions(+), 59 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index e3d0668a1..567545b60 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,7 +62,13 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +//#define FIX_1439_SPEEDUP_sum2_fx_mod // 3liner // 0.25 WMOPS + +// Numbers ALL: 83,2 +// Numbers beOnly: 86,162 +// NUmbers none: 88,183 + /*----------------------------------------------------------------------------------* * Prototypes of global macros @@ -3262,17 +3268,6 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 -void elliptic_bpf_48k_generic_fx( - const Word16* input_fx, /* i : i signal Q_input_fx */ - Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal */ - Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ - Word16 memory_fx_Q[], - const Word16 full_band_bpf[][5], /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ - const Word32 *output32_fx, - const Word16 *scale_output32_fx); -#else void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : i signal Q_input_fx */ Word16 *Q_input_fx, @@ -3281,7 +3276,6 @@ void elliptic_bpf_48k_generic_fx( Word16 memory_fx_Q[], const Word16 full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ); -#endif void synthesise_fb_high_band_fx( const Word16 excitation_in[], /* i : full band excitation */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1dbe841a3..a0ae3dd10 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6694,8 +6694,6 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 -#else void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6704,12 +6702,12 @@ void elliptic_bpf_48k_generic_fx( Word16 memory_fx_Q[], const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) -#endif { Word16 i, j; Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; + Word32 L_output[L_FRAME48k]; FOR( i = 0; i < 4; i++ ) { @@ -6769,36 +6767,190 @@ void elliptic_bpf_48k_generic_fx( L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 - FOR( i = 4; i < L_FRAME48k; i++ ) +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { Word64 W_tmpX; Word64 W_tmpY; + i = 4; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + FOR( ; i < L_FRAME48k / 3; ) + { + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //4 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //5 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); // 3 + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //4 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //5 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //4 + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //5 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //7 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } } + ELSE #else - FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + } + } +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + { + i = 4; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //1 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + FOR( ; i < L_FRAME48k / 3; ) + { + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //4 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //8 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } } + ELSE +#else + { + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } + } +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #endif @@ -6857,6 +7009,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 4; i < L_FRAME48k; i++ ) { Word64 W_tmpX; @@ -6874,7 +7027,8 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } -#else + +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6889,7 +7043,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } -#endif +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -7025,11 +7179,14 @@ void elliptic_bpf_48k_generic_fx( move16(); move16(); Q_temp2 = norm_l( L_tmpMax ); - Scale_sig32( L_output, 960, Q_temp2 ); - FOR( i = 0; i < 960; i++ ) + { - output_fx[i] = extract_h( L_output[i] ); - move16(); + Scale_sig32( L_output, 960, Q_temp2 ); + FOR( i = 0; i < 960; i++ ) + { + output_fx[i] = extract_h( L_output[i] ); + move16(); + } } *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); move16(); /* BASOP_NOGLOB */ @@ -7066,11 +7223,11 @@ void synthesise_fb_high_band_fx( { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; - Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; + Word16 tmp[L_FRAME48k]; push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ @@ -7092,20 +7249,12 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, NULL, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx, tmp32, scale_tmp32 ); -#else elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); -#endif } ELSE { /* for 12.8kHz ACELP core */ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, NULL, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx, tmp32, scale_tmp32 ); -#else elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); -#endif } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ @@ -7113,7 +7262,6 @@ void synthesise_fb_high_band_fx( push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); temp1 = sum2_fx_mod( tmp, L_FRAME48k ); - L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ exp = norm_l( L_tmp ); tmp3 = extract_h( L_shl( L_tmp, exp ) ); diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5219d076c..23c2accb2 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -446,6 +446,21 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element const Word16 lvec /* i : length of input vector */ ) { +#ifdef FIX_1439_SPEEDUP_sum2_fx_mod + Word16 i; + Word64 W_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + W_tmp = W_add(0, 0 ); + FOR( i = 0; i < lvec; i++ ) + { + W_tmp = W_mac_16_16( W_tmp, vec[i], vec[i] ); + } + return W_sat_l(W_shr(W_tmp, 9)); +#else Word16 i; Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -458,8 +473,9 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element { L_tmp = L_add_o( L_tmp, L_shr( L_mult_o( vec[i], vec[i], &Overflow ), 9 ), &Overflow ); } - return L_tmp; +#endif + } /*-------------------------------------------------------------------* * Copy: diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 5d860c96f..6d4761c2f 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7324,11 +7324,7 @@ void fb_tbe_enc_fx( exp_temp = sub( exp_temp, 1 ); Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx, NULL, NULL ); -#else elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -#endif Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7452,19 +7448,11 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx, NULL, NULL ); -#else elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -#endif } ELSE { -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_OUT32 - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx, NULL, NULL ); -#else elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -#endif } test(); -- GitLab From 15247b5509c25c3e30b44bd9b8a797dbe87c8f1b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:35:58 +0100 Subject: [PATCH 0659/1221] apply clang format patch --- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 6 ++---- lib_com/tools_fx.c | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 29ca3986d..4151de02e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,7 +62,7 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS //#define FIX_1439_SPEEDUP_sum2_fx_mod // 3liner // 0.25 WMOPS // Numbers ALL: 83,2 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a0ae3dd10..0c7e1befc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -19,7 +19,6 @@ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ - /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6954,7 +6953,7 @@ void elliptic_bpf_48k_generic_fx( #endif - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; @@ -7028,7 +7027,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7255,7 +7254,6 @@ void synthesise_fb_high_band_fx( { /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); - } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 23c2accb2..7ffc10700 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -454,12 +454,12 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element move32(); #endif - W_tmp = W_add(0, 0 ); + W_tmp = W_add( 0, 0 ); FOR( i = 0; i < lvec; i++ ) { W_tmp = W_mac_16_16( W_tmp, vec[i], vec[i] ); } - return W_sat_l(W_shr(W_tmp, 9)); + return W_sat_l( W_shr( W_tmp, 9 ) ); #else Word16 i; Word32 L_tmp; @@ -475,7 +475,6 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element } return L_tmp; #endif - } /*-------------------------------------------------------------------* * Copy: -- GitLab From d9be131549ca6401e0183bde59701f8c61605f29 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:39:18 +0100 Subject: [PATCH 0660/1221] one instruction less in FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 0c7e1befc..1b61b2bb8 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6896,7 +6896,7 @@ void elliptic_bpf_48k_generic_fx( FOR( ; i < L_FRAME48k / 3; ) { // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -- GitLab From e8ff93c5c166e7c3ad888d8d3d5f3064c5615a21 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:41:22 +0100 Subject: [PATCH 0661/1221] apply clang format patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1b61b2bb8..b5a658136 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6896,7 +6896,7 @@ void elliptic_bpf_48k_generic_fx( FOR( ; i < L_FRAME48k / 3; ) { // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -- GitLab From b5f196f20774a9426f7107654c76857cf7b787a6 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:57:41 +0100 Subject: [PATCH 0662/1221] deactivated all speedups --- lib_com/prot_fx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 4151de02e..d57f93d91 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,11 +62,11 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS //#define FIX_1439_SPEEDUP_sum2_fx_mod // 3liner // 0.25 WMOPS // Numbers ALL: 83,2 -// Numbers beOnly: 86,162 +// Numbers beOnly: 86,156 // NUmbers none: 88,183 -- GitLab From d64e1fa0fd98594c6fe4a99c5f016da8d1a3d80d Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:09:24 +0000 Subject: [PATCH 0663/1221] del macro FIX_1439_SPEEDUP_sum2_fx_mod --- lib_com/prot_fx.h | 3 +-- lib_com/swb_tbe_com_fx.c | 3 --- lib_com/tools_fx.c | 17 +---------------- lib_enc/swb_tbe_enc_fx.c | 1 + 4 files changed, 3 insertions(+), 21 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d57f93d91..b64de07f8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -63,9 +63,8 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS -//#define FIX_1439_SPEEDUP_sum2_fx_mod // 3liner // 0.25 WMOPS -// Numbers ALL: 83,2 +// Numbers ALL: 83,45 // Numbers beOnly: 86,156 // NUmbers none: 88,183 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b5a658136..e2221a33c 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7178,14 +7178,11 @@ void elliptic_bpf_48k_generic_fx( move16(); move16(); Q_temp2 = norm_l( L_tmpMax ); - - { Scale_sig32( L_output, 960, Q_temp2 ); FOR( i = 0; i < 960; i++ ) { output_fx[i] = extract_h( L_output[i] ); move16(); - } } *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); move16(); /* BASOP_NOGLOB */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 7ffc10700..5219d076c 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -446,21 +446,6 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element const Word16 lvec /* i : length of input vector */ ) { -#ifdef FIX_1439_SPEEDUP_sum2_fx_mod - Word16 i; - Word64 W_tmp; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - W_tmp = W_add( 0, 0 ); - FOR( i = 0; i < lvec; i++ ) - { - W_tmp = W_mac_16_16( W_tmp, vec[i], vec[i] ); - } - return W_sat_l( W_shr( W_tmp, 9 ) ); -#else Word16 i; Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -473,8 +458,8 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element { L_tmp = L_add_o( L_tmp, L_shr( L_mult_o( vec[i], vec[i], &Overflow ), 9 ), &Overflow ); } + return L_tmp; -#endif } /*-------------------------------------------------------------------* * Copy: diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 542eee644..c5d5e651e 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7324,6 +7324,7 @@ void fb_tbe_enc_fx( exp_temp = sub( exp_temp, 1 ); Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; -- GitLab From 7ba6c5a392d1f689a24ede6adabc91872876e7ed Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 12:11:27 +0100 Subject: [PATCH 0664/1221] apply clang format patch --- lib_com/swb_tbe_com_fx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e2221a33c..6dda9a39f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7178,11 +7178,11 @@ void elliptic_bpf_48k_generic_fx( move16(); move16(); Q_temp2 = norm_l( L_tmpMax ); - Scale_sig32( L_output, 960, Q_temp2 ); - FOR( i = 0; i < 960; i++ ) - { - output_fx[i] = extract_h( L_output[i] ); - move16(); + Scale_sig32( L_output, 960, Q_temp2 ); + FOR( i = 0; i < 960; i++ ) + { + output_fx[i] = extract_h( L_output[i] ); + move16(); } *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); move16(); /* BASOP_NOGLOB */ -- GitLab From 9bbc9345c38738574816c2cb73ae7ea75aa8eabc Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 26 Mar 2025 12:20:55 +0100 Subject: [PATCH 0665/1221] Fix format. --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 0f1a33ed5..8b94a7cf7 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -4216,8 +4216,8 @@ static void computeTargetPSDs_direct_subframe_fx( q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] ); move16(); - Scale_sig32( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) , sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[0], q_tmp ) ) ); - Scale_sig32( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[1], q_tmp ) ) ); + Scale_sig32( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[0], q_tmp ) ) ); + Scale_sig32( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[1], q_tmp ) ) ); #endif v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power -- GitLab From ad8bba9cfa444272263390af7345b25b115ffad4 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 12:30:58 +0100 Subject: [PATCH 0666/1221] delete FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig --- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 184 ++++----------------------------------- 2 files changed, 16 insertions(+), 170 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index b64de07f8..8a282fac6 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,7 +62,7 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS - deleted completely // Numbers ALL: 83,45 // Numbers beOnly: 86,156 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6dda9a39f..b2a414afe 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6766,194 +6766,40 @@ void elliptic_bpf_48k_generic_fx( L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + FOR( i = 4; i < L_FRAME48k; i++ ) { Word64 W_tmpX; Word64 W_tmpY; - i = 4; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); - i++; - - FOR( ; i < L_FRAME48k / 3; ) - { - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //4 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //5 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); // 3 - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //4 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //5 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //4 - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //5 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //7 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } } - ELSE -#else - { - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - } - } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) - { - i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //1 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - i++; - - FOR( ; i < L_FRAME48k / 3; ) - { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //4 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //8 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - ELSE -#else - { - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #endif - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; -- GitLab From eaa539013d7c11e202990bb7fad44a7322a70fad Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 12:34:52 +0100 Subject: [PATCH 0667/1221] follow-up: apply clang format patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b2a414afe..9a54a26f6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6782,7 +6782,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 82e1f8758cacf2127fd0509672fd3bf5897850cd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 12:42:39 +0100 Subject: [PATCH 0668/1221] delete FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1, STAGE2 and STAGE 3 completely --- lib_com/prot_fx.h | 6 ++-- lib_com/swb_tbe_com_fx.c | 68 ++-------------------------------------- 2 files changed, 6 insertions(+), 68 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 8a282fac6..48232000a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,9 +59,9 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //deleted completely //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS - deleted completely // Numbers ALL: 83,45 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 9a54a26f6..f2b850533 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6765,24 +6765,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6796,8 +6779,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } -#endif - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6853,27 +6834,6 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 - - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6888,7 +6848,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ + Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -6957,29 +6917,7 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -6997,7 +6935,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -#endif + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; -- GitLab From 00f17224f34a586a272a98c13c2cad6b3d645336 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 11:52:15 +0000 Subject: [PATCH 0669/1221] del all changes --- lib_com/prot_fx.h | 9 ------ lib_com/swb_tbe_com_fx.c | 19 +++--------- lib_dec/ivas_core_dec_fx.c | 62 +++++++------------------------------- lib_dec/ivas_jbm_dec_fx.c | 20 ++---------- lib_dec/swb_tbe_dec_fx.c | 2 -- 5 files changed, 18 insertions(+), 94 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 48232000a..851b461bf 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,15 +59,6 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //deleted completely -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //deleted completely -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //deleted completely -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS - deleted completely - -// Numbers ALL: 83,45 -// Numbers beOnly: 86,156 -// NUmbers none: 88,183 - /*----------------------------------------------------------------------------------* * Prototypes of global macros diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index f2b850533..2a2841966 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -18,7 +18,6 @@ #define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ - /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6693,6 +6692,7 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ + void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6704,9 +6704,8 @@ void elliptic_bpf_48k_generic_fx( { Word16 i, j; Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; - Word32 L_output[L_FRAME48k]; FOR( i = 0; i < 4; i++ ) { @@ -6722,7 +6721,6 @@ void elliptic_bpf_48k_generic_fx( move32(); } - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6765,7 +6763,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6833,7 +6830,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6935,7 +6931,6 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7003,13 +6998,12 @@ void synthesise_fb_high_band_fx( { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; + Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; - Word16 tmp[L_FRAME48k]; - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7025,7 +7019,6 @@ void synthesise_fb_high_band_fx( } exp_tmp = sub( Q_fb_exc, 2 ); - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" ); IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ @@ -7036,11 +7029,8 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ - - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); temp1 = sum2_fx_mod( tmp, L_FRAME48k ); + L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ exp = norm_l( L_tmp ); tmp3 = extract_h( L_shl( L_tmp, exp ) ); @@ -7095,7 +7085,6 @@ void synthesise_fb_high_band_fx( move16(); } } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; } diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index c0686bdfd..588640d0a 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -114,12 +114,12 @@ ivas_error ivas_core_dec_fx( error = IVAS_ERR_OK; move32(); - push_wmops( "ivas_core_dec (ICD)" ); + push_wmops( "ivas_core_dec" ); /*------------------------------------------------------------------* * General initialization *-----------------------------------------------------------------*/ - push_wmops( "ICD init" ); + use_cldfb_for_dft = 0; move16(); tdm_LRTD_flag = -1; @@ -368,9 +368,7 @@ ivas_error ivas_core_dec_fx( { save_hb_synth_32_fx = NULL; } - pop_wmops(); /*push_wmops( "ICD init" );*/ - push_wmops( "ICD SID, sanity" ); /*------------------------------------------------------------------* * Decode SID for MDCT-Stereo DTX mode *-----------------------------------------------------------------*/ @@ -398,9 +396,7 @@ ivas_error ivas_core_dec_fx( { ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } - pop_wmops(); /*push_wmops( "ICD SID, sanity" );*/ - push_wmops( "ICD Coredec" ); /*------------------------------------------------------------------* * Core Decoding *-----------------------------------------------------------------*/ @@ -485,7 +481,6 @@ ivas_error ivas_core_dec_fx( IF( st->core == ACELP_CORE ) { - push_wmops( "ICD ACELP" ); /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; @@ -558,7 +553,6 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) - pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 @@ -567,7 +561,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - push_wmops( "ICD TCX" ); Word16 Qsyn_temp; IVAS_FORMAT ivas_format; @@ -622,12 +615,10 @@ ivas_error ivas_core_dec_fx( } st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); move16(); - pop_wmops(); /*push_wmops( "ICD TCX" );*/ } IF( EQ_16( st->core, HQ_CORE ) ) { - push_wmops( "ICD HQ decoding" ); /* HQ core decoder */ Word16 Q_output; @@ -641,7 +632,6 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -658,8 +648,8 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 } - } /* n_channels loop */ - pop_wmops(); /*push_wmops( "ICD Coredec" );*/ + } /* n_channels loop */ + /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Decoding @@ -667,7 +657,6 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { - push_wmops( "ICD jTCX Coredec" ); /* active-frame decoding */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) { @@ -796,7 +785,6 @@ ivas_error ivas_core_dec_fx( } } } - pop_wmops(); /*push_wmops( "ICD jTCX Coredec" );*/ } /*---------------------------------------------------------------------* @@ -806,7 +794,6 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { - push_wmops( "ICD Stereo CNG Updates" ); /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; Word32 c_PS_LT_fx; @@ -822,14 +809,12 @@ ivas_error ivas_core_dec_fx( stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); - pop_wmops(); /*push_wmops( "ICD Stereo CNG Updates" );*/ } /*---------------------------------------------------------------------* * Postprocessing, BWEs and updates *---------------------------------------------------------------------*/ - push_wmops( "ICD Postproc, BWE, updates (ICD PP)" ); FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; @@ -840,7 +825,6 @@ ivas_error ivas_core_dec_fx( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ - push_wmops( "ICD PP TDBWE ACELPTCX trans" ); /*core_switching_post_dec*/ Q_synth = sub( 15, e_sig[0] ); @@ -914,12 +898,11 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } - pop_wmops(); /*push_wmops( "ICD PP TDBWE ACELPTCX trans" );*/ /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ - push_wmops( "ICD PP ACELP/MDCT switch" ); + /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ test(); test(); @@ -954,12 +937,11 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } - pop_wmops(); /*push_wmops( "ICD PP ACELP/MDCT switch" );*/ /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - push_wmops( "ICD PP BWswitch preproc" ); + ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); IF( st->hHQ_core == NULL ) @@ -1006,13 +988,12 @@ ivas_error ivas_core_dec_fx( hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } - pop_wmops(); /*push_wmops( "ICD PP BWswitch preproc" );*/ /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding *---------------------------------------------------------------------*/ - push_wmops( "ICD PP TBE/BWE" ); + Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; Word16 Q_syn_hb, sf; @@ -1040,9 +1021,8 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, WB_TBE ) ) { /* WB TBE decoder */ - push_wmops( "ICD PP TBE/BWE wb_tbe_dec" ); + ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_tbe_dec" );*/ } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) { @@ -1050,10 +1030,8 @@ ivas_error ivas_core_dec_fx( } ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) { - push_wmops( "ICD PP TBE/BWE wb_bwe_dec" ); /* WB BWE decoder */ Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_bwe_dec" );*/ } /* Memories Re-Scaling */ @@ -1097,10 +1075,8 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { - push_wmops( "ICD PP TBE/BWE swb_tbe_dec" ); /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec" );*/ Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx @@ -1115,22 +1091,18 @@ ivas_error ivas_core_dec_fx( /* FB TBE decoder */ IF( EQ_16( st->extl, FB_TBE ) ) { - push_wmops( "ICD PP TBE/BWE fb_tbe_dec" ); fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE fb_tbe_dec" );*/ } } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ - push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ + Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE" );*/ /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) @@ -1169,7 +1141,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) { - push_wmops( "ICD PP SWB CNG" ); /* SHB CNG decoder */ Word16 synth_fxl[960]; /* Q-2 */ Word16 q; @@ -1191,7 +1162,6 @@ ivas_error ivas_core_dec_fx( Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); - pop_wmops(); /* push_wmops( "ICD PP SWB CNG" );*/ } /*-------------------------------------------------------------------* @@ -1201,7 +1171,6 @@ ivas_error ivas_core_dec_fx( test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { - push_wmops( "ICD PP IC-BWE" ); Word16 q; q = 11; move16(); @@ -1223,12 +1192,10 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } - pop_wmops(); /*push_wmops( "ICD PP IC-BWE" );*/ } IF( EQ_16( st->element_mode, EVS_MONO ) ) { - push_wmops( "ICD PP BFI" ); /*----------------------------------------------------------------* * BFI waveform adjustment *----------------------------------------------------------------*/ @@ -1256,7 +1223,6 @@ ivas_error ivas_core_dec_fx( st->hPlcInfo->Pitch_fx = 0; move16(); } - pop_wmops(); /*push_wmops( "ICD PP BFI" );*/ } /*----------------------------------------------------------------* @@ -1269,7 +1235,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) { - push_wmops( "ICD PP Sync BWE" ); /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ IF( EQ_16( st->L_frame, L_FRAME ) ) { @@ -1423,7 +1388,6 @@ ivas_error ivas_core_dec_fx( st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } - pop_wmops(); /*push_wmops( "ICD PP Sync BWE" );*/ } test(); @@ -1439,7 +1403,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - push_wmops( "ICD PP TCXLTP" ); + IF( st->hHQ_core != NULL ) { Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 @@ -1496,7 +1460,6 @@ ivas_error ivas_core_dec_fx( } Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TCXLTP" );*/ /*--------------------------------------------------------* * Common updates @@ -1505,7 +1468,6 @@ ivas_error ivas_core_dec_fx( Word16 exp_max; Word32 output_fx_loc[L_FRAME48k]; - push_wmops( "ICD PP commonupdates" ); exp_max = 0; move16(); @@ -1560,8 +1522,6 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD PP commonupdates" );*/ - } /* n_channels loop */ FOR( n = 0; n < n_channels; n++ ) @@ -1580,7 +1540,7 @@ ivas_error ivas_core_dec_fx( move16(); } } - pop_wmops(); /*push_wmops( "ICD Postproc, BWE, updates (ICD PP)" );*/ + pop_wmops(); return error; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 4745bc5f0..93e8bb4eb 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -96,13 +96,12 @@ ivas_error ivas_jbm_dec_tc_fx( CPE_DEC_HANDLE hCPE; SCE_DEC_HANDLE hSCE; - push_wmops( "ivas_jbm_dec_tc (JBM)" ); + push_wmops( "ivas_jbm_dec_tc" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ - push_wmops( "JBM init" ); output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; @@ -135,7 +134,7 @@ ivas_error ivas_jbm_dec_tc_fx( } Word16 ch; - pop_wmops(); /*push_wmops( "JBM init" );*/ + /*----------------------------------------------------------------* * Decoding + pre-rendering @@ -153,7 +152,6 @@ ivas_error ivas_jbm_dec_tc_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { - push_wmops( "JBM STEREO" ); st_ivas->hCPE[0]->element_brate = ivas_total_brate; move32(); Word16 q_output = 11; @@ -194,11 +192,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } - pop_wmops(); /*push_wmops( "JBM STEREO" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { - push_wmops( "JBM ISM" ); /* Metadata decoding and configuration */ test(); IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) @@ -283,11 +279,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops(); /*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { - push_wmops( "JBM SBA/MASA" ); set16_fx( nb_bits_metadata, 0, MAX_SCE ); @@ -694,11 +688,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops(); /*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { - push_wmops( "JBM MASA_ISM" ); Word16 nchan_ism, nchan_transport_ism; Word16 dirac_bs_md_write_idx; @@ -829,11 +821,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 } } - pop_wmops(); /*push_wmops( "JBM MASA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { - push_wmops( "JBM SBA_ISM" ); Word16 nchan_ism, sba_ch_idx; set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -1102,11 +1092,10 @@ ivas_error ivas_jbm_dec_tc_fx( v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); } } - pop_wmops(); /*push_wmops( "JBM SBA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - push_wmops( "JBM MC" ); + // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; IF( st_ivas->nSCE > 0 ) { @@ -1479,7 +1468,6 @@ ivas_error ivas_jbm_dec_tc_fx( ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); } } - pop_wmops(); /*push_wmops( "JBM MC" );*/ } /*----------------------------------------------------------------* @@ -1488,9 +1476,7 @@ ivas_error ivas_jbm_dec_tc_fx( IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) { - push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); - pop_wmops(); /*push_wmops( "JBM syn_out" );*/ } ELSE { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1e7af58c8..1b51a29fb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4713,9 +4713,7 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - push_wmops( "synthesise_fb_high_band" ); synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); - pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) -- GitLab From f320213c7f16efabac023d217a03a4220cd18683 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 14:10:06 +0100 Subject: [PATCH 0670/1221] Revert "del all changes" This reverts commit 00f17224f34a586a272a98c13c2cad6b3d645336. --- lib_com/prot_fx.h | 9 ++++++ lib_com/swb_tbe_com_fx.c | 19 +++++++++--- lib_dec/ivas_core_dec_fx.c | 62 +++++++++++++++++++++++++++++++------- lib_dec/ivas_jbm_dec_fx.c | 20 ++++++++++-- lib_dec/swb_tbe_dec_fx.c | 2 ++ 5 files changed, 94 insertions(+), 18 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 851b461bf..48232000a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,6 +59,15 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS - deleted completely + +// Numbers ALL: 83,45 +// Numbers beOnly: 86,156 +// NUmbers none: 88,183 + /*----------------------------------------------------------------------------------* * Prototypes of global macros diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..f2b850533 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -18,6 +18,7 @@ #define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ + /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6692,7 +6693,6 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ - void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6704,8 +6704,9 @@ void elliptic_bpf_48k_generic_fx( { Word16 i, j; Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; + Word32 L_output[L_FRAME48k]; FOR( i = 0; i < 4; i++ ) { @@ -6721,6 +6722,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6763,6 +6765,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6830,6 +6833,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6931,6 +6935,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -6998,12 +7003,13 @@ void synthesise_fb_high_band_fx( { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; - Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; + Word16 tmp[L_FRAME48k]; + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7019,6 +7025,7 @@ void synthesise_fb_high_band_fx( } exp_tmp = sub( Q_fb_exc, 2 ); + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" ); IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ @@ -7029,8 +7036,11 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } - temp1 = sum2_fx_mod( tmp, L_FRAME48k ); + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); + temp1 = sum2_fx_mod( tmp, L_FRAME48k ); L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ exp = norm_l( L_tmp ); tmp3 = extract_h( L_shl( L_tmp, exp ) ); @@ -7085,6 +7095,7 @@ void synthesise_fb_high_band_fx( move16(); } } + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; } diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 588640d0a..c0686bdfd 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -114,12 +114,12 @@ ivas_error ivas_core_dec_fx( error = IVAS_ERR_OK; move32(); - push_wmops( "ivas_core_dec" ); + push_wmops( "ivas_core_dec (ICD)" ); /*------------------------------------------------------------------* * General initialization *-----------------------------------------------------------------*/ - + push_wmops( "ICD init" ); use_cldfb_for_dft = 0; move16(); tdm_LRTD_flag = -1; @@ -368,7 +368,9 @@ ivas_error ivas_core_dec_fx( { save_hb_synth_32_fx = NULL; } + pop_wmops(); /*push_wmops( "ICD init" );*/ + push_wmops( "ICD SID, sanity" ); /*------------------------------------------------------------------* * Decode SID for MDCT-Stereo DTX mode *-----------------------------------------------------------------*/ @@ -396,7 +398,9 @@ ivas_error ivas_core_dec_fx( { ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } + pop_wmops(); /*push_wmops( "ICD SID, sanity" );*/ + push_wmops( "ICD Coredec" ); /*------------------------------------------------------------------* * Core Decoding *-----------------------------------------------------------------*/ @@ -481,6 +485,7 @@ ivas_error ivas_core_dec_fx( IF( st->core == ACELP_CORE ) { + push_wmops( "ICD ACELP" ); /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; @@ -553,6 +558,7 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) + pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 @@ -561,6 +567,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { + push_wmops( "ICD TCX" ); Word16 Qsyn_temp; IVAS_FORMAT ivas_format; @@ -615,10 +622,12 @@ ivas_error ivas_core_dec_fx( } st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); move16(); + pop_wmops(); /*push_wmops( "ICD TCX" );*/ } IF( EQ_16( st->core, HQ_CORE ) ) { + push_wmops( "ICD HQ decoding" ); /* HQ core decoder */ Word16 Q_output; @@ -632,6 +641,7 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 + pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -648,8 +658,8 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 } - } /* n_channels loop */ - + } /* n_channels loop */ + pop_wmops(); /*push_wmops( "ICD Coredec" );*/ /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Decoding @@ -657,6 +667,7 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { + push_wmops( "ICD jTCX Coredec" ); /* active-frame decoding */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) { @@ -785,6 +796,7 @@ ivas_error ivas_core_dec_fx( } } } + pop_wmops(); /*push_wmops( "ICD jTCX Coredec" );*/ } /*---------------------------------------------------------------------* @@ -794,6 +806,7 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { + push_wmops( "ICD Stereo CNG Updates" ); /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; Word32 c_PS_LT_fx; @@ -809,12 +822,14 @@ ivas_error ivas_core_dec_fx( stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); + pop_wmops(); /*push_wmops( "ICD Stereo CNG Updates" );*/ } /*---------------------------------------------------------------------* * Postprocessing, BWEs and updates *---------------------------------------------------------------------*/ + push_wmops( "ICD Postproc, BWE, updates (ICD PP)" ); FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; @@ -825,6 +840,7 @@ ivas_error ivas_core_dec_fx( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ + push_wmops( "ICD PP TDBWE ACELPTCX trans" ); /*core_switching_post_dec*/ Q_synth = sub( 15, e_sig[0] ); @@ -898,11 +914,12 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } + pop_wmops(); /*push_wmops( "ICD PP TDBWE ACELPTCX trans" );*/ /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP ACELP/MDCT switch" ); /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ test(); test(); @@ -937,11 +954,12 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } + pop_wmops(); /*push_wmops( "ICD PP ACELP/MDCT switch" );*/ /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP BWswitch preproc" ); ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); IF( st->hHQ_core == NULL ) @@ -988,12 +1006,13 @@ ivas_error ivas_core_dec_fx( hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } + pop_wmops(); /*push_wmops( "ICD PP BWswitch preproc" );*/ /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP TBE/BWE" ); Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; Word16 Q_syn_hb, sf; @@ -1021,8 +1040,9 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, WB_TBE ) ) { /* WB TBE decoder */ - + push_wmops( "ICD PP TBE/BWE wb_tbe_dec" ); ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_tbe_dec" );*/ } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) { @@ -1030,8 +1050,10 @@ ivas_error ivas_core_dec_fx( } ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) { + push_wmops( "ICD PP TBE/BWE wb_bwe_dec" ); /* WB BWE decoder */ Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_bwe_dec" );*/ } /* Memories Re-Scaling */ @@ -1075,8 +1097,10 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { + push_wmops( "ICD PP TBE/BWE swb_tbe_dec" ); /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec" );*/ Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx @@ -1091,18 +1115,22 @@ ivas_error ivas_core_dec_fx( /* FB TBE decoder */ IF( EQ_16( st->extl, FB_TBE ) ) { + push_wmops( "ICD PP TBE/BWE fb_tbe_dec" ); fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE fb_tbe_dec" );*/ } } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ + push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE" );*/ /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) @@ -1141,6 +1169,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) { + push_wmops( "ICD PP SWB CNG" ); /* SHB CNG decoder */ Word16 synth_fxl[960]; /* Q-2 */ Word16 q; @@ -1162,6 +1191,7 @@ ivas_error ivas_core_dec_fx( Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); + pop_wmops(); /* push_wmops( "ICD PP SWB CNG" );*/ } /*-------------------------------------------------------------------* @@ -1171,6 +1201,7 @@ ivas_error ivas_core_dec_fx( test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { + push_wmops( "ICD PP IC-BWE" ); Word16 q; q = 11; move16(); @@ -1192,10 +1223,12 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } + pop_wmops(); /*push_wmops( "ICD PP IC-BWE" );*/ } IF( EQ_16( st->element_mode, EVS_MONO ) ) { + push_wmops( "ICD PP BFI" ); /*----------------------------------------------------------------* * BFI waveform adjustment *----------------------------------------------------------------*/ @@ -1223,6 +1256,7 @@ ivas_error ivas_core_dec_fx( st->hPlcInfo->Pitch_fx = 0; move16(); } + pop_wmops(); /*push_wmops( "ICD PP BFI" );*/ } /*----------------------------------------------------------------* @@ -1235,6 +1269,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) { + push_wmops( "ICD PP Sync BWE" ); /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ IF( EQ_16( st->L_frame, L_FRAME ) ) { @@ -1388,6 +1423,7 @@ ivas_error ivas_core_dec_fx( st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } + pop_wmops(); /*push_wmops( "ICD PP Sync BWE" );*/ } test(); @@ -1403,7 +1439,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - + push_wmops( "ICD PP TCXLTP" ); IF( st->hHQ_core != NULL ) { Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 @@ -1460,6 +1496,7 @@ ivas_error ivas_core_dec_fx( } Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); + pop_wmops(); /*push_wmops( "ICD PP TCXLTP" );*/ /*--------------------------------------------------------* * Common updates @@ -1468,6 +1505,7 @@ ivas_error ivas_core_dec_fx( Word16 exp_max; Word32 output_fx_loc[L_FRAME48k]; + push_wmops( "ICD PP commonupdates" ); exp_max = 0; move16(); @@ -1522,6 +1560,8 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 + pop_wmops(); /*push_wmops( "ICD PP commonupdates" );*/ + } /* n_channels loop */ FOR( n = 0; n < n_channels; n++ ) @@ -1540,7 +1580,7 @@ ivas_error ivas_core_dec_fx( move16(); } } - + pop_wmops(); /*push_wmops( "ICD Postproc, BWE, updates (ICD PP)" );*/ pop_wmops(); return error; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 93e8bb4eb..4745bc5f0 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -96,12 +96,13 @@ ivas_error ivas_jbm_dec_tc_fx( CPE_DEC_HANDLE hCPE; SCE_DEC_HANDLE hSCE; - push_wmops( "ivas_jbm_dec_tc" ); + push_wmops( "ivas_jbm_dec_tc (JBM)" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ + push_wmops( "JBM init" ); output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; @@ -134,7 +135,7 @@ ivas_error ivas_jbm_dec_tc_fx( } Word16 ch; - + pop_wmops(); /*push_wmops( "JBM init" );*/ /*----------------------------------------------------------------* * Decoding + pre-rendering @@ -152,6 +153,7 @@ ivas_error ivas_jbm_dec_tc_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { + push_wmops( "JBM STEREO" ); st_ivas->hCPE[0]->element_brate = ivas_total_brate; move32(); Word16 q_output = 11; @@ -192,9 +194,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } + pop_wmops(); /*push_wmops( "JBM STEREO" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { + push_wmops( "JBM ISM" ); /* Metadata decoding and configuration */ test(); IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) @@ -279,9 +283,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } + pop_wmops(); /*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { + push_wmops( "JBM SBA/MASA" ); set16_fx( nb_bits_metadata, 0, MAX_SCE ); @@ -688,9 +694,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } + pop_wmops(); /*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { + push_wmops( "JBM MASA_ISM" ); Word16 nchan_ism, nchan_transport_ism; Word16 dirac_bs_md_write_idx; @@ -821,9 +829,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 } } + pop_wmops(); /*push_wmops( "JBM MASA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { + push_wmops( "JBM SBA_ISM" ); Word16 nchan_ism, sba_ch_idx; set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -1092,10 +1102,11 @@ ivas_error ivas_jbm_dec_tc_fx( v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); } } + pop_wmops(); /*push_wmops( "JBM SBA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - + push_wmops( "JBM MC" ); // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; IF( st_ivas->nSCE > 0 ) { @@ -1468,6 +1479,7 @@ ivas_error ivas_jbm_dec_tc_fx( ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); } } + pop_wmops(); /*push_wmops( "JBM MC" );*/ } /*----------------------------------------------------------------* @@ -1476,7 +1488,9 @@ ivas_error ivas_jbm_dec_tc_fx( IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) { + push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); + pop_wmops(); /*push_wmops( "JBM syn_out" );*/ } ELSE { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1b51a29fb..1e7af58c8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4713,7 +4713,9 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ + push_wmops( "synthesise_fb_high_band" ); synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) -- GitLab From 3f98982fcc6f4c5dcd29a491e24d9d5b12dc3684 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 14:10:37 +0100 Subject: [PATCH 0671/1221] Revert "delete FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1, STAGE2 and STAGE 3 completely" This reverts commit 82e1f8758cacf2127fd0509672fd3bf5897850cd. --- lib_com/prot_fx.h | 6 ++-- lib_com/swb_tbe_com_fx.c | 68 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 48232000a..8a282fac6 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,9 +59,9 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //deleted completely -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //deleted completely -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS - deleted completely // Numbers ALL: 83,45 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index f2b850533..9a54a26f6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6765,7 +6765,24 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + } +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6779,6 +6796,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } +#endif + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6834,6 +6853,27 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6848,7 +6888,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -6917,7 +6957,29 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -6935,7 +6997,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - +#endif memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; -- GitLab From 9fe773a1e9745f1c9a8ceb8d219dda40be756f29 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 14:10:50 +0100 Subject: [PATCH 0672/1221] Revert "follow-up: apply clang format patch" This reverts commit eaa539013d7c11e202990bb7fad44a7322a70fad. --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 9a54a26f6..b2a414afe 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6782,7 +6782,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From d39775e561d75da6c5593ff8b8edafc6d684f3fb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 14:11:10 +0100 Subject: [PATCH 0673/1221] Revert "delete FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig" This reverts commit ad8bba9cfa444272263390af7345b25b115ffad4. --- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 184 +++++++++++++++++++++++++++++++++++---- 2 files changed, 170 insertions(+), 16 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 8a282fac6..b64de07f8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,7 +62,7 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS - deleted completely +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS // Numbers ALL: 83,45 // Numbers beOnly: 86,156 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b2a414afe..6dda9a39f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6766,40 +6766,194 @@ void elliptic_bpf_48k_generic_fx( L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 - FOR( i = 4; i < L_FRAME48k; i++ ) +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { Word64 W_tmpX; Word64 W_tmpY; + i = 4; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); + i++; + + FOR( ; i < L_FRAME48k / 3; ) + { + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //4 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //5 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); // 3 + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //4 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //5 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //4 + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //5 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //7 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ - FOR( i = 4; i < L_FRAME48k; i++ ) + ELSE +#else { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + } + } +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + { + i = 4; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //1 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + FOR( ; i < L_FRAME48k / 3; ) + { + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //4 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //8 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } + } + ELSE +#else + { + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } } +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #endif - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; -- GitLab From b97f83cb78c87f5ddae7f685e963dfcb783f0ed2 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 26 Mar 2025 14:16:10 +0100 Subject: [PATCH 0674/1221] pull ref branch expicitly --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b1caf927b..186208f7b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -168,7 +168,7 @@ stages: - current_commit_sha=$(git rev-parse HEAD) ### build reference binaries - git checkout $FLOAT_REF_BRANCH - - git pull + - git pull origin $FLOAT_REF_BRANCH - *activate-debug-mode-info-if-set - make clean - make -j -- GitLab From b5613202ae8beb2147304b73c9af9293e4ed78a0 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 26 Mar 2025 14:19:20 +0100 Subject: [PATCH 0675/1221] [revert-me] only run on specific runner for testing the fix --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 186208f7b..4b998a9b8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -479,6 +479,8 @@ stages: stage: check-be needs: ["build-codec-linux-make"] timeout: "300 minutes" + tags: + - "test-fhg-basop-runner-3" variables: XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" -- GitLab From 04d2aba19d0a780fe6f3a91c52929fcd3be34413 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 26 Mar 2025 14:46:43 +0100 Subject: [PATCH 0676/1221] change more "git pull" occurences --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4b998a9b8..75e7e82c6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -184,7 +184,7 @@ stages: - current_commit_sha=$(git rev-parse HEAD) ### build merge target binaries - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - git pull + - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - *activate-debug-mode-info-if-set - make clean - make -j @@ -232,7 +232,7 @@ stages: - git fetch - git restore . # Just as a precaution - git checkout $BASOP_CI_BRANCH_PC_REPO - - git pull + - git pull origin $BASOP_CI_BRANCH_PC_REPO - cd - - cp -r $SCRIPTS_DIR/ci . - cp -r $SCRIPTS_DIR/scripts . @@ -660,7 +660,7 @@ stages: ### run main now - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - git pull + - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - make clean - make -j # need to restore cache again -- GitLab From 09dbfd6044f4a695b6102b0cebc356c5316f8d50 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 26 Mar 2025 14:54:23 +0100 Subject: [PATCH 0677/1221] minimal code cleanup in ivas_smc_gmm_fx(). There were two unncessary IF clauses which could be replaced with L_max. --- lib_enc/speech_music_classif_fx.c | 49 ++++++++++++------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index b9f47136f..a54f9668b 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -856,16 +856,8 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { /*mx = PS_norm[i] > st->past_PS[i] ? PS_norm[i] : st->past_PS[i];*/ - IF( GT_32( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ) - { - mx = PS_norm[i]; - move16(); /*Q25 */ - } - ELSE - { - mx = hSpMusClas->past_PS_fx[i - LOWEST_FBIN]; - move16(); /*Q25 */ - } + mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + move16(); /*Q25 */ /*ps_sta += mx / (dPS[i] + 1e-5f);*/ IF( !dPS[i] ) @@ -1611,7 +1603,7 @@ Word16 ivas_smc_gmm_fx( Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; Word64 wprob_fx; Word32 fvm_fx[N_PCA_COEF]; - Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; + Word32 sum_PS_fx, ps_diff_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; Word16 dlp_mean2var_fx; @@ -1989,32 +1981,29 @@ Word16 ivas_smc_gmm_fx( move32(); /* [14] ps_sta (spectral stationarity) */ - ps_sta_fx = 0; - move32(); - Word16 ps_sta_exp = 0; - move16(); - FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - IF( GT_32( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ) + Word32 ps_sta_fx = 0; + move32(); + Word16 ps_sta_exp = 0; + move16(); + Word32 avoid_divide_by_zero; + avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31 + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - temp32 = BASOP_Util_Divide3232_Scale_cadence( PS_norm_fx[i], ( L_add( dPS_fx[i], L_shr( 21475, sub( 31, Qfact_PS_past ) ) ) ), &temp_exp ); // 31-temp_exp + Word32 tmp_max; + tmp_max = L_max(PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + + temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp move32(); ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); move32(); } - ELSE - { - // ps_sta += hSpMusClas->past_PS[i - LOWEST_FBIN] / ( dPS[i] + 1e-5f ); - temp32 = BASOP_Util_Divide3232_Scale_cadence( hSpMusClas->past_PS_fx[i - LOWEST_FBIN], ( L_add( dPS_fx[i], L_shr( 21475, sub( 31, Qfact_PS_past ) ) ) ), &temp_exp ); // 31-temp_exp - ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); - } + temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); + temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); + move32(); + MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); } - // temp32_log = L_add( BASOP_Util_Log2( L_add( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); - temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); - temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ - *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); - move32(); - MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); /* save ps_diff and ps_sta features for XTALK and UNCLR classifier */ IF( hStereoClassif != NULL ) -- GitLab From 161bea50e3dfc1c9890e2863bfb1502e84199de0 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 26 Mar 2025 14:54:52 +0100 Subject: [PATCH 0678/1221] Revert "[revert-me] only run on specific runner for testing the fix" This reverts commit b5613202ae8beb2147304b73c9af9293e4ed78a0. --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75e7e82c6..13b498f74 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -479,8 +479,6 @@ stages: stage: check-be needs: ["build-codec-linux-make"] timeout: "300 minutes" - tags: - - "test-fhg-basop-runner-3" variables: XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" -- GitLab From 3376fb0af295c9175ae317460529d4412e33812c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 15:04:13 +0100 Subject: [PATCH 0679/1221] activate FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig for be test --- lib_com/prot_fx.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index b64de07f8..06cc69ee5 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,16 +59,22 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 +// *** Currently checking be-nes of all-inactive (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50048 -- DONE GREEN! +// *** Currently checking be speedups ( only FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes +// --> next test: check nonbe speedups +// //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS // Numbers ALL: 83,45 // Numbers beOnly: 86,156 // NUmbers none: 88,183 + + /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ -- GitLab From 849100836e5b419631533f9876f643fc32fa5f9f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 15:19:53 +0100 Subject: [PATCH 0680/1221] minor change --- lib_com/prot_fx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 06cc69ee5..1b4857508 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,7 +60,7 @@ #define TCX_IMDCT_HEADROOM 1 // *** Currently checking be-nes of all-inactive (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50048 -- DONE GREEN! -// *** Currently checking be speedups ( only FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes +// *** Currently checking be speedups ( only FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) // --> next test: check nonbe speedups // //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -- GitLab From 487a8968adfacb6c60b79586317c07c7e7fe72b6 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 15:22:00 +0100 Subject: [PATCH 0681/1221] apply clang format patch --- lib_com/prot_fx.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1b4857508..a50d1656c 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,7 +62,7 @@ // *** Currently checking be-nes of all-inactive (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50048 -- DONE GREEN! // *** Currently checking be speedups ( only FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) // --> next test: check nonbe speedups -// +// //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 @@ -73,8 +73,6 @@ // NUmbers none: 88,183 - - /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ -- GitLab From 20b8d705772047937dcd8b4fae794d73f98f6c58 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 26 Mar 2025 15:24:44 +0100 Subject: [PATCH 0682/1221] applied the clang patch. --- lib_enc/speech_music_classif_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index a54f9668b..fe0839954 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1991,7 +1991,7 @@ Word16 ivas_smc_gmm_fx( FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { Word32 tmp_max; - tmp_max = L_max(PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp move32(); -- GitLab From e4410825eee7d4f4f290c6d079c1b17e4d5ccc61 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Mar 2025 15:40:37 +0530 Subject: [PATCH 0683/1221] Fix for MSAN error observed with decoder pipeline --- lib_dec/ivas_core_dec_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 588640d0a..03f0e4b40 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -73,6 +73,8 @@ ivas_error ivas_core_dec_fx( Word16 tmp16, tmp16_2, j; Word16 Q_white_exc; + set16_fx( tmp_buffer_fx, 0, L_FRAME48k ); + Word16 tmps, incr; Word32 bwe_exc_extended_fx[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; -- GitLab From 1a15ab5b2c336b949add726ff189f512788bc43e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 16:01:16 +0100 Subject: [PATCH 0684/1221] added some push/pop wmops --- lib_dec/swb_tbe_dec_fx.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1e7af58c8..43110cfb8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -5519,6 +5519,8 @@ void ivas_swb_tbe_dec_fx( hBWE_TD = st->hBWE_TD; + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" ); + /* initializations */ GainFrame_fx = 0; move32(); @@ -5559,7 +5561,9 @@ void ivas_swb_tbe_dec_fx( tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; move16(); } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART B" ); /* WB/SWB bandwidth switching */ test(); test(); @@ -5883,6 +5887,9 @@ void ivas_swb_tbe_dec_fx( } } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART B" );*/ + + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART C" ); /* get the gainshape delay */ Copy( &hBWE_TD->GainShape_Delay_fx[4], &hBWE_TD->GainShape_Delay_fx[0], NUM_SHB_SUBFR / 4 ); FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) @@ -5921,7 +5928,9 @@ void ivas_swb_tbe_dec_fx( { set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART C" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART D" ); /* SHB LSF from current frame; and convert to LSP for interpolation */ E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); @@ -6075,6 +6084,9 @@ void ivas_swb_tbe_dec_fx( } } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART D" );*/ + + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART E" ); /* Save the SWB LSP values from current frame for interpolation */ Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); @@ -6128,7 +6140,9 @@ void ivas_swb_tbe_dec_fx( Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); } } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART E" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART F" ); /* From low band excitation, generate highband excitation */ /* -------- start of memory rescaling -------- */ @@ -6329,6 +6343,10 @@ void ivas_swb_tbe_dec_fx( } } ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ + + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART F" );*/ + + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART G" ); /* WB/SWB bandwidth switching */ IF( st->bws_cnt > 0 ) { @@ -6646,7 +6664,10 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART G" );*/ + + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART H" ); /* Gain shape smoothing after quantization */ test(); IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) @@ -6839,6 +6860,9 @@ void ivas_swb_tbe_dec_fx( } } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART H" );*/ + + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART J" ); /* adjust the FEC frame energy */ IF( st->bfi ) { @@ -6996,6 +7020,10 @@ void ivas_swb_tbe_dec_fx( move32(); } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART J" );*/ + + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART K" ); + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth_fx32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); @@ -7132,5 +7160,7 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_Qx = Q_bwe_exc; move16(); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART K" );*/ + return; } -- GitLab From bba34f621436a2f64b4a6357816974485c597a10 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 16:08:31 +0100 Subject: [PATCH 0685/1221] mofified FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig to not differ from original --- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 90 ++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index a50d1656c..19560b368 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,7 +60,7 @@ #define TCX_IMDCT_HEADROOM 1 // *** Currently checking be-nes of all-inactive (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50048 -- DONE GREEN! -// *** Currently checking be speedups ( only FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) +// *** Currently checking be speedups ( only modified version of FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) // --> next test: check nonbe speedups // //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6dda9a39f..d58825e59 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6869,65 +6869,65 @@ void elliptic_bpf_48k_generic_fx( IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //0 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //1 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; FOR( ; i < L_FRAME48k / 3; ) { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat(L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX); //3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //4 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //8 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //8 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; } -- GitLab From 46c6fcf39f425f82cd782e5e184b87dd80cc3f46 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 26 Mar 2025 16:21:14 +0100 Subject: [PATCH 0686/1221] delete most of the recently added push/pop wmops --- lib_dec/swb_tbe_dec_fx.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 43110cfb8..2b42e5b0d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -5519,7 +5519,6 @@ void ivas_swb_tbe_dec_fx( hBWE_TD = st->hBWE_TD; - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" ); /* initializations */ GainFrame_fx = 0; @@ -5561,9 +5560,7 @@ void ivas_swb_tbe_dec_fx( tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; move16(); } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART B" ); /* WB/SWB bandwidth switching */ test(); test(); @@ -5887,9 +5884,6 @@ void ivas_swb_tbe_dec_fx( } } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART B" );*/ - - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART C" ); /* get the gainshape delay */ Copy( &hBWE_TD->GainShape_Delay_fx[4], &hBWE_TD->GainShape_Delay_fx[0], NUM_SHB_SUBFR / 4 ); FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) @@ -5928,9 +5922,7 @@ void ivas_swb_tbe_dec_fx( { set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART C" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART D" ); /* SHB LSF from current frame; and convert to LSP for interpolation */ E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); @@ -6084,9 +6076,6 @@ void ivas_swb_tbe_dec_fx( } } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART D" );*/ - - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART E" ); /* Save the SWB LSP values from current frame for interpolation */ Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); @@ -6140,9 +6129,7 @@ void ivas_swb_tbe_dec_fx( Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); } } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART E" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART F" ); /* From low band excitation, generate highband excitation */ /* -------- start of memory rescaling -------- */ @@ -6344,9 +6331,6 @@ void ivas_swb_tbe_dec_fx( } ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART F" );*/ - - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART G" ); /* WB/SWB bandwidth switching */ IF( st->bws_cnt > 0 ) { @@ -6664,10 +6648,6 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART G" );*/ - - - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART H" ); /* Gain shape smoothing after quantization */ test(); IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) @@ -6860,9 +6840,6 @@ void ivas_swb_tbe_dec_fx( } } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART H" );*/ - - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART J" ); /* adjust the FEC frame energy */ IF( st->bfi ) { @@ -7020,8 +6997,6 @@ void ivas_swb_tbe_dec_fx( move32(); } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART J" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART K" ); /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ -- GitLab From 6c3e64c4387a3f131c09bf634bc35fccf3100940 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Mar 2025 21:17:42 +0530 Subject: [PATCH 0687/1221] Fix for crash observed with -10dB LTV test case on decoder pipeline --- lib_dec/fd_cng_dec_fx.c | 19 +++++++++++++++++-- lib_dec/ivas_ism_dtx_dec_fx.c | 7 ++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 2f9c567c1..4c42a7959 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1531,7 +1531,15 @@ Word16 ApplyFdCng_ivas_fx( move16(); /* This sets the new CNG levels until a SID update overwrites it */ Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it */ /*Q31 - hFdCngDec->bandNoiseShape_exp*/ - *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; + + Word16 shift1 = L_norm_arr( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); + Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) ); + Word16 shift = s_max( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); + + scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), shift ) ); + scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( sub( *cngNoiseLevel_exp, shift2 ), shift ) ); + + *cngNoiseLevel_exp = shift; move16(); /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ @@ -5059,7 +5067,14 @@ void FdCng_decodeSID_ivas_fx( } scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + Word16 shift1 = L_norm_arr( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ); + Word16 shift2 = L_norm_arr( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ) ); + Word16 shift = s_max( sub( hFdCngCom->sidNoiseEstExp, shift1 ), sub( hFdCngCom->cngNoiseLevelExp, shift2 ) ); + + scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( sub( hFdCngCom->sidNoiseEstExp, shift1 ), shift ) ); + scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( sub( hFdCngCom->cngNoiseLevelExp, shift2 ), shift ) ); + + hFdCngCom->cngNoiseLevelExp = shift; move16(); lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); diff --git a/lib_dec/ivas_ism_dtx_dec_fx.c b/lib_dec/ivas_ism_dtx_dec_fx.c index 0f023a7ef..73ea5cd1f 100644 --- a/lib_dec/ivas_ism_dtx_dec_fx.c +++ b/lib_dec/ivas_ism_dtx_dec_fx.c @@ -181,7 +181,12 @@ void ivas_ism_dtx_limit_noise_energy_for_near_silence_fx( cng_noise_nrg_obj_fx = dotp_fixed_o( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len, 9, &Q_cng_noise_nrg_obj ); /*Resultant Q_cng_noise_nrg_obj= (Q_cng_noise_nrg_obj-x)<=31*/ IF( GT_32( cng_noise_nrg_obj_fx, cng_noise_nrg_dominant_fx ) ) { - Word32 temp = divide3232( L_shr( cng_noise_nrg_dominant_fx, 1 ), cng_noise_nrg_obj_fx ); /*Stores value of cng_noise_nrg_dominant_fx/cng_noise_nrg_obj_fx*/ + Word32 temp = 0; + move32(); + IF( L_shr( cng_noise_nrg_dominant_fx, 1 ) ) + { + temp = divide3232( L_shr( cng_noise_nrg_dominant_fx, 1 ), cng_noise_nrg_obj_fx ); /*Stores value of cng_noise_nrg_dominant_fx/cng_noise_nrg_obj_fx*/ + } Word16 Q_temp = add( sub( sub( Q_cng_noise_nrg_dominant, 1 ), Q_cng_noise_nrg_obj ), 15 ); /*Stores resultant Q after divide3232 operation above*/ IF( EQ_16( Q_temp % 2, 1 ) ) /*Making Q_temp even for sqrt function*/ { -- GitLab From 5f567820d4191cc81f2980331fa3ed0b1176e3a7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 25 Mar 2025 19:46:19 +0530 Subject: [PATCH 0688/1221] Fix for 3GPP issue 1397: Stereo Encoder: 48 kbit/s DTX on, click in LTV Link #1397 --- lib_enc/fd_cng_enc_fx.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 9c3a236d7..e51e2b682 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -2839,16 +2839,19 @@ void FdCngEncodeMDCTStereoSID_fx( { IF( lr_in_ptr_fx[ch][p] ) { - t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25 - t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 + t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25 + t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 + ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 + move32(); } ELSE { - t2 = 0; + // 10.f * log10f( EPSILON ) --> -150.0f + // Subsequent additions / subtractions happen on these numbers, so to avoid saturations + // this value is set to -128.0f in Q23 + ms_ptr_fx[ch][p] = -ONE_IN_Q30; // Q23 move32(); } - ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 - move32(); E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19 move32(); } -- GitLab From c27356358db7765ff9c1354ecc13d25583420d47 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 27 Mar 2025 10:21:29 +0100 Subject: [PATCH 0689/1221] Fix rescale boundaries and simplifications. These changes might have already been commited earlier but were lost ? --- lib_rend/ivas_dirac_rend_fx.c | 124 +++++++++++----------------------- 1 file changed, 40 insertions(+), 84 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index e8a798a1a..573ece7cb 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4097,37 +4097,31 @@ static void ivas_masa_ext_dirac_render_sf_fx( #ifdef FIX_867_CLDFB_NRG_SCALE IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { - Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; move16(); } ELSE { - Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; move16(); } IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; move16(); } ELSE { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; move16(); } @@ -4179,37 +4173,31 @@ static void ivas_masa_ext_dirac_render_sf_fx( #ifdef FIX_867_CLDFB_NRG_SCALE IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; move16(); } ELSE { - Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; move16(); } IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[1]; move16(); } ELSE { - Scale_sig32( reference_power_fix, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; move16(); } @@ -4259,37 +4247,31 @@ static void ivas_masa_ext_dirac_render_sf_fx( #ifdef FIX_867_CLDFB_NRG_SCALE IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; move16(); } ELSE { - Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; move16(); } IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; move16(); } ELSE { - Scale_sig32( reference_power_fix, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; move16(); } @@ -4595,44 +4577,28 @@ static void ivas_masa_ext_dirac_render_sf_fx( } #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands * 2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands * 3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + hSpatParamRendCom->num_freq_bands * 4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); move16(); - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 5, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); move16(); - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands * 2, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands * 3, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + hSpatParamRendCom->num_freq_bands * 4, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); move16(); - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - IF( GT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 2, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 3, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + hSpatParamRendCom->num_freq_bands * 4, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); move16(); @@ -4667,27 +4633,23 @@ static void ivas_masa_ext_dirac_render_sf_fx( /*Buffer rescaling*/ #ifdef FIX_867_CLDFB_NRG_SCALE - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx, CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - IF( GT_16( DirAC_mem.reference_power_len, shl( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + FOR( i = 0; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) - Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) } hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + move16(); hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); move16(); DirAC_mem.reference_power_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + move16(); DirAC_mem.reference_power_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); move16(); DirAC_mem.reference_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + move16(); DirAC_mem.reference_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); move16(); #else @@ -4725,37 +4687,31 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; move16(); } ELSE { - Scale_sig32( reference_power_fix, CLDFB_NO_CHANNELS_HALF, sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; move16(); } IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 1 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - IF( GT_16( DirAC_mem.reference_power_len, shr( hSpatParamRendCom->num_freq_bands, 1 ) ) ) + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 2 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 3 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i_mult( hSpatParamRendCom->num_freq_bands, 4 ), sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q } DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; move16(); } ELSE { - Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; move16(); } -- GitLab From fd97a3278968a74991754d649e97fc73a8f36751 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Mar 2025 15:44:31 +0530 Subject: [PATCH 0690/1221] ASAN error fix in encoder and Missing lowrate_pitchGain added inside enc_pit_exc --- lib_enc/enc_pit_exc_fx.c | 2 ++ lib_enc/mslvq_enc_fx.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 7af329a1c..957e41516 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -775,6 +775,8 @@ void enc_pit_exc_ivas_fx( push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } + st_fx->hSpMusClas->lowrate_pitchGain = mac_r( L_mult( 29491 /* 0.9 in Q15 */, st_fx->hSpMusClas->lowrate_pitchGain ), 3277 /* 0.1 in Q15 */, gain_pit ); /* Q14 */ + gpit_tmp = gain_pit; move16(); /*Q14*/ test(); diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index f15b80655..8f8dd4537 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -251,7 +251,7 @@ Word32 mslvq_cng_ivas_fx( move16(); p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; // Q11 + p_scales = scales_ivas_fx[mode_glb]; // Q11 move16(); no_scales[0] = 0; -- GitLab From 128cb148a9380ccff30b26f257b06eada4b205fd Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 27 Mar 2025 13:00:16 +0100 Subject: [PATCH 0691/1221] Improve accuracy of no_phi_masa_inv_fx table and remove all other azimuth/elevation roundings. --- lib_com/ivas_rom_com_fx.c | 15 +++++++++++++++ lib_dec/ivas_dirac_dec_fx.c | 14 +++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index a7a8bdcbf..ffb18d6d2 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1545,6 +1545,7 @@ const Word16 ivas_param_mc_quant_icc_fx[PARAM_MC_SZ_ICC_QUANTIZER] = { /* from 1 to 11 bits*/ /*q factor = 8*/ const Word32 no_phi_masa_inv_fx[NO_SPHERICAL_GRIDS][MAX_NO_THETA] = { +#ifndef FIX_1379_MASA_ANGLE_ROUND { 1073741824 }, { 536870912 }, { 536870912, 1073741824 }, @@ -1556,8 +1557,22 @@ const Word32 no_phi_masa_inv_fx[NO_SPHERICAL_GRIDS][MAX_NO_THETA] = { { 44739242, 45691141, 47721858, 52377649, 61356675, 76695844, 107374182, 178956970, 1073741824, 2147483647 }, { 35791394, 35791394, 37025580, 38347922, 39768215, 42949672, 46684427, 52377649, 59652323, 71582788, 93368854, 126322567, 214748364, 2147483647 }, { 24129029, 24129029, 24403223, 24970740, 25565281, 26512143, 27889398, 29417584, 31580641, 34087042, 37675151, 42107522, 48806446, 56512727, 71582788, 93368854, 143165576, 268435456, 2147483647 } +#else + { 1073741824 }, + { 536870912 }, + { 536870912, 1073741824 }, + { 268435456, 536870912 }, + { 178956971, 306783378, 1073741824, 2147483647 }, + { 153391689, 165191050, 238609294, 1073741824, 2147483647 }, + { 97612893, 102261126, 126322568, 195225786, 715827883, 2147483647 }, + { 65075262, 67108864, 74051160, 93368854, 126322568, 238609294, 2147483647 }, + { 44739243, 45691141, 47721859, 52377650, 61356676, 76695845, 107374182, 178956971, 1073741824, 2147483647 }, + { 35791394, 35791394, 37025580, 38347922, 39768216, 42949673, 46684427, 52377650, 59652324, 71582788, 93368854, 126322568, 214748365, 2147483647 }, + { 24129030, 24129030, 24403223, 24970740, 25565282, 26512144, 27889398, 29417584, 31580642, 34087042, 37675152, 42107523, 48806447, 56512728, 71582788, 93368854, 143165577, 268435456, 2147483647 }, +#endif }; + const Word32 azimuth_cb_fx[8] = { 0, -754974720, -377487360, 377487360, -188743680, 188743680, -566231040, 566231040 }; diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index c72c0d6c8..bd49d13d6 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -1446,7 +1446,7 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND +#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT hSpatParamRendCom->azimuth[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); move16(); hSpatParamRendCom->elevation[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); @@ -1501,7 +1501,7 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND +#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT hSpatParamRendCom->azimuth2[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); move16(); hSpatParamRendCom->elevation2[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); @@ -1718,7 +1718,7 @@ void ivas_qmetadata_to_dirac_fx( IF( hodirac_flag ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND +#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT azi = round_fx( L_shr( ( L_add( azimuth_fx, ONE_IN_Q21 ) ), 6 ) ); ele = round_fx( L_shr( ( L_add( elevation_fx, ONE_IN_Q21 ) ), 6 ) ); #else @@ -1760,7 +1760,7 @@ void ivas_qmetadata_to_dirac_fx( final_1_32 = BASOP_Util_Add_Mant32Exp( final_1_32, final_1_exp, ONE_IN_Q30, 0, &final_1_exp ); /*0.5 in q31*/ final_2_32 = BASOP_Util_Add_Mant32Exp( final_2_32, final_2_exp, ONE_IN_Q30, 0, &final_2_exp ); -#ifdef FIX_1379_MASA_ANGLE_ROUND +#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT azi = round_fx( L_shr( final_1_32, sub( sub( 31, final_1_exp ), 16 ) ) ); ele = round_fx( L_shr( final_2_32, sub( sub( 31, final_2_exp ), 16 ) ) ); #else @@ -3626,7 +3626,7 @@ void ivas_dirac_dec_render_sf_fx( { Word16 j, k, j2, l; Word16 num_objects, nchan_out_woLFE, lfe_index; -#ifndef FIX_1379_MASA_ANGLE_ROUND +#ifndef FIX_1379_MASA_ANGLE_ROUND_NOT Word16 az1, el1; #endif Word16 n_slots_to_render; @@ -3662,14 +3662,14 @@ void ivas_dirac_dec_render_sf_fx( Word16 el_q0 = extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, Q22 ) ); Word32 az1_32, el1_32; rotateAziEle_fixed( az_q0, el_q0, &az1_32, &el1_32, st_ivas->hCombinedOrientationData->Rmat_fx[0], st_ivas->hIntSetup.is_planar_setup ); -#ifndef FIX_1379_MASA_ANGLE_ROUND +#ifndef FIX_1379_MASA_ANGLE_ROUND_NOT az1 = extract_h( az1_32 ); el1 = extract_h( el1_32 ); #endif IF( st_ivas->hEFAPdata != NULL ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND +#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT const Word32 azi_fx = L_shl( az1_32, Q22 - Q16 ); // Q16 -> Q22 const Word32 ele_fx = L_shl( el1_32, Q22 - Q16 ); // Q16 -> Q22 #else -- GitLab From e0b4a0bcb3bfdcc39c93349b42520bb70e695132 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 27 Mar 2025 17:43:17 +0100 Subject: [PATCH 0692/1221] allow failure for complexity number changes see https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/merge_requests/2063 --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 13b498f74..a3fa4217b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1750,6 +1750,9 @@ voip-be-on-merge-request: # delete previous jobs logfiles if present (-f flag ensures return calue of 0 even in first run where this folder is not present) - rm -rf COMPLEXITY/logs - which coan + allow_failure: + exit_codes: + - 123 artifacts: name: "$CI_JOB_NAME--$CI_COMMIT_REF_NAME--sha-$CI_COMMIT_SHA" when: always -- GitLab From 97754fe6471c6857bc76feb9de337b6513f58c63 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 27 Mar 2025 18:14:37 +0100 Subject: [PATCH 0693/1221] Remove wrong round_fx(). Reactivate simplification which also fixes instrumentation (implicit Word16 to Word32 conversion). --- lib_dec/ivas_dirac_dec_fx.c | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index bd49d13d6..c06047113 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -1446,17 +1446,10 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT - hSpatParamRendCom->azimuth[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); - move16(); - hSpatParamRendCom->elevation[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); - move16(); -#else hSpatParamRendCom->azimuth[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); move16(); hSpatParamRendCom->elevation[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); move16(); -#endif hSpatParamRendCom->energy_ratio1_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; move32(); hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( ONE_IN_Q30, q_direction->band_data[band].energy_ratio_fx[block] ); @@ -1501,17 +1494,10 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT - hSpatParamRendCom->azimuth2[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); - move16(); - hSpatParamRendCom->elevation2[meta_write_index][b] = round_fx( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); - move16(); -#else hSpatParamRendCom->azimuth2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); move16(); hSpatParamRendCom->elevation2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); move16(); -#endif hSpatParamRendCom->energy_ratio2_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; move32(); hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], q_direction->band_data[band].energy_ratio_fx[block] ); @@ -1718,13 +1704,8 @@ void ivas_qmetadata_to_dirac_fx( IF( hodirac_flag ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT - azi = round_fx( L_shr( ( L_add( azimuth_fx, ONE_IN_Q21 ) ), 6 ) ); - ele = round_fx( L_shr( ( L_add( elevation_fx, ONE_IN_Q21 ) ), 6 ) ); -#else azi = extract_h( L_shr( ( L_add( azimuth_fx, ONE_IN_Q21 ) ), 6 ) ); ele = extract_h( L_shr( ( L_add( elevation_fx, ONE_IN_Q21 ) ), 6 ) ); -#endif /*addition of one to compensate precision loss*/ if ( azi < 0 ) { @@ -1760,13 +1741,8 @@ void ivas_qmetadata_to_dirac_fx( final_1_32 = BASOP_Util_Add_Mant32Exp( final_1_32, final_1_exp, ONE_IN_Q30, 0, &final_1_exp ); /*0.5 in q31*/ final_2_32 = BASOP_Util_Add_Mant32Exp( final_2_32, final_2_exp, ONE_IN_Q30, 0, &final_2_exp ); -#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT - azi = round_fx( L_shr( final_1_32, sub( sub( 31, final_1_exp ), 16 ) ) ); - ele = round_fx( L_shr( final_2_32, sub( sub( 31, final_2_exp ), 16 ) ) ); -#else azi = extract_h( L_shr( final_1_32, sub( sub( 31, final_1_exp ), 16 ) ) ); ele = extract_h( L_shr( final_2_32, sub( sub( 31, final_2_exp ), 16 ) ) ); -#endif /*addition of one to compensate precision loss*/ if ( azi < 0 ) @@ -3626,7 +3602,7 @@ void ivas_dirac_dec_render_sf_fx( { Word16 j, k, j2, l; Word16 num_objects, nchan_out_woLFE, lfe_index; -#ifndef FIX_1379_MASA_ANGLE_ROUND_NOT +#ifndef FIX_1379_MASA_ANGLE_ROUND Word16 az1, el1; #endif Word16 n_slots_to_render; @@ -3662,14 +3638,14 @@ void ivas_dirac_dec_render_sf_fx( Word16 el_q0 = extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, Q22 ) ); Word32 az1_32, el1_32; rotateAziEle_fixed( az_q0, el_q0, &az1_32, &el1_32, st_ivas->hCombinedOrientationData->Rmat_fx[0], st_ivas->hIntSetup.is_planar_setup ); -#ifndef FIX_1379_MASA_ANGLE_ROUND_NOT +#ifndef FIX_1379_MASA_ANGLE_ROUND az1 = extract_h( az1_32 ); el1 = extract_h( el1_32 ); #endif IF( st_ivas->hEFAPdata != NULL ) { -#ifdef FIX_1379_MASA_ANGLE_ROUND_NOT +#ifdef FIX_1379_MASA_ANGLE_ROUND const Word32 azi_fx = L_shl( az1_32, Q22 - Q16 ); // Q16 -> Q22 const Word32 ele_fx = L_shl( el1_32, Q22 - Q16 ); // Q16 -> Q22 #else -- GitLab From 275083601fc28744d234e543de0f92226eab332e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 09:37:21 +0530 Subject: [PATCH 0694/1221] inp 12k8 precision improvement through pre_proc_front path --- lib_enc/ivas_core_pre_proc_front_fx.c | 205 ++++++++++++-------------- lib_enc/ivas_cpe_enc_fx.c | 62 ++++---- lib_enc/ivas_ism_enc_fx.c | 23 ++- lib_enc/ivas_sce_enc_fx.c | 11 +- lib_enc/speech_music_classif_fx.c | 8 +- 5 files changed, 145 insertions(+), 164 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 4ff34272f..0eb6d1887 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -87,7 +87,7 @@ ivas_error pre_proc_front_ivas_fx( const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ const Word16 input_frame, /* i : frame length Q0*/ const Word16 n, /* i : channel number Q0*/ - Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1*/ + Word16 old_inp_12k8_fx[], /* o : buffer of old input signal (st->Q_inp until preemph, then Q_new, then Q_new-1 towards the end)*/ Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1*/ Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ Word16 *relE_fx, /* o : frame relative energy Q8*/ @@ -149,26 +149,6 @@ ivas_error pre_proc_front_ivas_fx( { st = hCPE->hCoreCoder[n]; } - Word16 old_inp_12k8_e; - Word16 shift = getScaleFactor16( st->old_inp_12k8_fx, 240 ); - Scale_sig( st->old_inp_12k8_fx, 240, shift ); /* exp(st->exp_old_inp_12k8 - shift) */ - st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); - move16(); - shift = getScaleFactor16( old_inp_12k8_fx, 496 ); - Scale_sig( old_inp_12k8_fx, 496, shift ); /* exp(16 - shift) */ - old_inp_12k8_e = sub( Q16, shift ); - IF( GT_16( old_inp_12k8_e, st->exp_old_inp_12k8 ) ) - { - Scale_sig( st->old_inp_12k8_fx, 240, sub( st->exp_old_inp_12k8, old_inp_12k8_e ) ); /* exp(old_inp_12k8_e) */ - st->exp_old_inp_12k8 = old_inp_12k8_e; - move16(); - } - ELSE - { - Scale_sig( old_inp_12k8_fx, 496, sub( old_inp_12k8_e, st->exp_old_inp_12k8 ) ); /* exp(st->exp_old_inp_12k8) */ - old_inp_12k8_e = st->exp_old_inp_12k8; - move16(); - } Word16 q_tmpN_LR[CPE_CHANNELS]; Word16 q_tmpE_LR[CPE_CHANNELS]; @@ -251,41 +231,21 @@ ivas_error pre_proc_front_ivas_fx( temp1F_icatdmResampBuf_fx = (Word16 *) malloc( 45 * sizeof( Word16 * ) ); set16_fx( fft_buff_fx, 0, 512 ); - IF( hSCE != NULL ) - { - Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ - hSCE->hCoreCoder[n]->q_inp32 = Q11; - move16(); - Scale_sig( hSCE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ - hSCE->hCoreCoder[n]->q_inp = -1; - move16(); - Scale_sig( hSCE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q(-1) */ - hSCE->hCoreCoder[n]->q_old_inp = -1; - move16(); + Word16 Q_min = add( sub( 15, st->exp_old_inp_12k8 ), norm_arr( st->old_inp_12k8_fx, L_INP_MEM ) ); + Word16 input_frame_full = shl( input_frame, 1 ); //(old frame input length + new frame input length) + Q_min = s_min( Q_min, sub( add( getScaleFactor32( st->input32_fx - input_frame, input_frame_full ), st->q_inp32 ), 16 ) ); + Q_min = s_max( -1, Q_min ); + Copy_Scale_sig_32_16( st->input32_fx - input_frame, st->input_fx - input_frame, input_frame_full, sub( Q_min, st->q_inp32 ) ); // Q_min + st->q_inp = Q_min; + move16(); + st->q_old_inp = Q_min; + move16(); #ifdef DEBUG_MODE_INFO - in_buff_temp = hSCE->hCoreCoder[n]->input32_fx; - in_q_temp = hSCE->hCoreCoder[n]->q_inp32; + in_buff_temp = hSCE->hCoreCoder[n]->input32_fx; + in_q_temp = hSCE->hCoreCoder[n]->q_inp32; #endif - } - ELSE - { - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ - hCPE->hCoreCoder[n]->q_inp32 = Q11; - move16(); - Scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ - hCPE->hCoreCoder[n]->q_inp = -1; - move16(); - Scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q(-1) */ - hCPE->hCoreCoder[n]->q_old_inp = -1; - move16(); -#ifdef DEBUG_MODE_INFO - in_buff_temp = hCPE->hCoreCoder[n]->input32_fx; - in_q_temp = hCPE->hCoreCoder[n]->q_inp32; -#endif - } + #ifdef DEBUG_MODE_INFO if ( !( hCPE != NULL && hCPE->hStereoTD != NULL && ch_idx > 0 ) ) @@ -307,7 +267,7 @@ ivas_error pre_proc_front_ivas_fx( } Word16 sf_energySum[CLDFB_NO_CHANNELS_MAX]; - Word16 Q_to_be_looked_into = -1; + Word16 Q_inp_const = -1; move16(); Word16 headroom = 0, preemp_len = 0, inp_max = 0; move16(); @@ -456,11 +416,6 @@ ivas_error pre_proc_front_ivas_fx( L_look = L_LOOK_12k8; /* lookahead at 12.8kHz */ move16(); - Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( Q_to_be_looked_into, sub( Q15, old_inp_12k8_e ) ) ); /* Q_to_be_looked_into*/ - old_inp_12k8_e = sub( Q15, Q_to_be_looked_into ); - Scale_sig( st->old_inp_12k8_fx, 240, sub( Q_to_be_looked_into, sub( Q15, st->exp_old_inp_12k8 ) ) ); /* Q_to_be_looked_into */ - st->exp_old_inp_12k8 = sub( Q15, Q_to_be_looked_into ); - move16(); new_inp_12k8_fx = old_inp_12k8_fx + L_INP_MEM; /* pointer to new samples of the input signal in 12.8kHz core */ inp_12k8_fx = new_inp_12k8_fx - L_look; /* pointer to the current frame of input signal in 12.8kHz core */ @@ -471,15 +426,15 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - STEREO_DFT_OVL_12k8 ); /* exp(st->exp_old_inp_12k8) */ + Copy_Scale_sig( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - STEREO_DFT_OVL_12k8, sub( st->q_inp, sub( Q15, st->exp_old_inp_12k8 ) ) ); /* st->q_inp */ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, sub( L_INP_MEM - L_FILT, lMemRecalc_12k8 ) ); /* exp(st->exp_old_inp_12k8) */ + Copy_Scale_sig( st->old_inp_12k8_fx, old_inp_12k8_fx, sub( L_INP_MEM - L_FILT, lMemRecalc_12k8 ), sub( st->q_inp, sub( Q15, st->exp_old_inp_12k8 ) ) ); /* st->q_inp */ } ELSE { - Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - L_FILT ); /* exp(st->exp_old_inp_12k8) */ + Copy_Scale_sig( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - L_FILT, sub( st->q_inp, sub( Q15, st->exp_old_inp_12k8 ) ) ); /* st->q_inp */ } Copy( st->old_wsp_fx, old_wsp_fx, L_WSP_MEM ); /* exp(st->exp_old_wsp) */ @@ -504,12 +459,18 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( EQ_16( element_mode, IVAS_SCE ) || ( EQ_16( element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - analysisCldfbEncoder_ivas_fx( st, signal32_in_fx, 11, input_frame, realBuffer_fx, imagBuffer_fx, realBuffer16, imagBuffer16, enerBuffer_fx, enerBuffer_fx_exp, &cldfbScale ); + scale_sig32( signal32_in_fx - input_frame, input_frame_full, sub( 11, st->q_inp32 ) ); // Q11 + st->q_inp32 = 11; + move16(); + analysisCldfbEncoder_ivas_fx( st, signal32_in_fx, st->q_inp32, input_frame, realBuffer_fx, imagBuffer_fx, realBuffer16, imagBuffer16, enerBuffer_fx, enerBuffer_fx_exp, &cldfbScale ); } ELSE IF( ( EQ_16( element_mode, IVAS_CPE_TD ) && st->idchan == 0 ) || ( EQ_16( st->idchan, 1 ) && st->tdm_LRTD_flag ) ) { /* cldfb analysis only for pri. channel */ - analysisCldfbEncoder_ivas_fx( st, signal32_in_fx - NS2SA_FX2( input_Fs, L_MEM_RECALC_TBE_NS ), 11, input_frame, realBuffer_fx, imagBuffer_fx, realBuffer16, imagBuffer16, enerBuffer_fx, enerBuffer_fx_exp, &cldfbScale ); + scale_sig32( signal32_in_fx - input_frame, input_frame_full, sub( 11, st->q_inp32 ) ); // Q11 + st->q_inp32 = 11; + move16(); + analysisCldfbEncoder_ivas_fx( st, signal32_in_fx - NS2SA_FX2( input_Fs, L_MEM_RECALC_TBE_NS ), st->q_inp32, input_frame, realBuffer_fx, imagBuffer_fx, realBuffer16, imagBuffer16, enerBuffer_fx, enerBuffer_fx_exp, &cldfbScale ); } ELSE IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { @@ -530,16 +491,17 @@ ivas_error pre_proc_front_ivas_fx( * (if not available from downsampled DMX) *----------------------------------------------------------------*/ + Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( st->q_inp, Q_inp_const ) ); /* st->q_inp */ test(); IF( EQ_16( element_mode, IVAS_SCE ) ) { - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_12k8_fx, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* Q0 */ - Scale_sig( new_inp_12k8_fx, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_12k8_fx, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ - Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { @@ -550,27 +512,38 @@ ivas_error pre_proc_front_ivas_fx( Word16 length_inp = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS ); Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ - Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ } - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* Q0 */ - Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ - Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ IF( lMemRecalc > 0 ) { - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx + sub( input_frame, lMemRecalc ), lMemRecalc, input_Fs, new_inp_12k8_fx + sub( L_FRAME, lMemRecalc_12k8 ), INT_FS_12k8, mem_decim_dummy_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* Q0 */ - Scale_sig( new_inp_12k8_fx + L_FRAME - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx + sub( input_frame, lMemRecalc ), lMemRecalc, input_Fs, new_inp_12k8_fx + sub( L_FRAME, lMemRecalc_12k8 ), INT_FS_12k8, mem_decim_dummy_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx + L_FRAME - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ } set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ - Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ } ELSE /* DFT stereo */ { /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* hSCE->hCoreCoder[n]->q_inp */ + Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ + scale_sig( old_inp_12k8_fx, L_INP_MEM - STEREO_DFT_OVL_12k8, sub( Q_inp_const, st->q_inp ) ); + scale_sig( st->input_fx - input_frame, input_frame_full, sub( Q_inp_const, st->q_inp ) ); + Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ + st->q_inp = Q_inp_const; + move16(); + st->q_old_inp = Q_inp_const; + move16(); + } + IF( NE_16( Q_inp_const, st->q_inp ) ) + { + Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ } Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( -1, sub( 15, st->exp_buf_speech_enc ) ) ); /* Q(-1) */ @@ -581,15 +554,15 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, st->buf_speech_enc + L_FRAME32k - STEREO_DFT_OVL_12k8, L_FRAME + STEREO_DFT_OVL_12k8 ); /* Q_to_be_looked_into */ + Copy_Scale_sig( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, st->buf_speech_enc + L_FRAME32k - STEREO_DFT_OVL_12k8, L_FRAME + STEREO_DFT_OVL_12k8, sub( Q_inp_const, st->q_inp ) ); /* Q_inp_const */ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { - Copy( new_inp_12k8_fx - lMemRecalc_12k8, st->buf_speech_enc + L_FRAME32k - lMemRecalc_12k8 - L_FILT, add( L_FRAME + L_FILT, lMemRecalc_12k8 ) ); /* Q_to_be_looked_into */ + Copy_Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, st->buf_speech_enc + L_FRAME32k - lMemRecalc_12k8 - L_FILT, add( L_FRAME + L_FILT, lMemRecalc_12k8 ), sub( Q_inp_const, st->q_inp ) ); /* Q_inp_const */ } ELSE { - Copy( new_inp_12k8_fx, st->buf_speech_enc + L_FRAME32k, L_FRAME ); /* Q_to_be_looked_into */ + Copy_Scale_sig( new_inp_12k8_fx, st->buf_speech_enc + L_FRAME32k, L_FRAME, sub( Q_inp_const, st->q_inp ) ); /* Q_inp_const */ } /*------------------------------------------------------------------* @@ -604,14 +577,18 @@ ivas_error pre_proc_front_ivas_fx( move16(); + st->mem_preemph_fx = shl_sat( st->mem_preemph_fx, sub( st->q_inp, -1 ) ); /*st->q_inp*/ + move16(); + st->mem_preemph_DFT_fx = shl_sat( st->mem_preemph_DFT_fx, sub( st->q_inp, -1 ) ); /*st->q_inp*/ + move16(); test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( new_inp_12k8_fx - STEREO_DFT_OVL_12k8 + L_FRAME, st->inp_12k8_mem_stereo_sw_fx, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); /* memory for TD/DFT stereo switching Q_to_be_looked_into*/ + Copy_Scale_sig( new_inp_12k8_fx - STEREO_DFT_OVL_12k8 + L_FRAME, st->inp_12k8_mem_stereo_sw_fx, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, sub( Q_inp_const, st->q_inp ) ); /* memory for TD/DFT stereo switching Q_inp_const*/ - st->mem_preemph_fx = st->mem_preemph_DFT_fx; /* Q(-1) */ + st->mem_preemph_fx = st->mem_preemph_DFT_fx; /* st->q_inp */ move16(); - st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* Q_new - 1 */ + st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* st->q_inp */ move16(); // PREEMPH_FX( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); @@ -632,9 +609,9 @@ ivas_error pre_proc_front_ivas_fx( { IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { - st->mem_preemph_fx = st->mem_preemph_DFT_fx; + st->mem_preemph_fx = st->mem_preemph_DFT_fx; /* st->q_inp */ move16(); - Copy( st->inp_12k8_mem_stereo_sw_fx, new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); /* Q(-1) */ + Copy_Scale_sig( st->inp_12k8_mem_stereo_sw_fx, new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, sub( st->q_inp, Q_inp_const ) ); /* st->q_inp */ // PREEMPH_FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx ); PREEMPH_32FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), sig_out, PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx ); preemp_start_idx = new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); @@ -643,7 +620,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* == inp_12k8[L_FRAME-1] Q_new - 1 */ + st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* st->q_inp */ move16(); } @@ -662,7 +639,7 @@ ivas_error pre_proc_front_ivas_fx( // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8, sig_out + preemp_len, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - dummy_fx = st->mem_preemph_fx; /* Q(-1) */ + dummy_fx = st->mem_preemph_fx; /* st->q_inp */ move16(); // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8 + L_FRAME, PREEMPH_FAC, lMemRecalc_12k8 + L_FILT, &dummy_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 + L_FRAME, sig_out + preemp_len + L_FRAME, PREEMPH_FAC, lMemRecalc_12k8 + L_FILT, &dummy_fx ); @@ -692,12 +669,15 @@ ivas_error pre_proc_front_ivas_fx( preemp_len = L_FRAME + L_FILT; move16(); } + st->mem_preemph_fx = shl_sat( st->mem_preemph_fx, sub( -1, st->q_inp ) ); /*Q(-1) saturation added as float value goes above 65536 for +10 dB test (ltv48_MC512.wav and ltv48_MC51.wav) */ + move16(); + st->mem_preemph_DFT_fx = shl( st->mem_preemph_DFT_fx, sub( -1, st->q_inp ) ); /*Q(-1)*/ + move16(); maximum_abs_32_fx( sig_out, preemp_len, &max_32 ); inp_max = s_max( extract_h( max_32 ), 1 ); - shift = sub( norm_s( inp_max ), headroom ); - Word16 Q_min; + Word16 shift = add( sub( norm_s( inp_max ), headroom ), st->q_inp ); shift = s_max( shift, 0 ); shift = s_min( shift, Q_MAX ); minimum_fx( st->Q_max, L_Q_MEM, &Q_min ); @@ -720,12 +700,12 @@ ivas_error pre_proc_front_ivas_fx( st->Q_max[i] = shift; move16(); - Copy_Scale_sig32_16( sig_out, preemp_start_idx, preemp_len, *Q_new ); /* Q_to_be_looked_into + Q_new */ + *Q_new = add( *Q_new, Q_inp_const ); + move16(); - Scale_sig( old_inp_12k8_fx, (Word16) ( preemp_start_idx - old_inp_12k8_fx ), *Q_new ); /* Q(-1) */ + Copy_Scale_sig32_16( sig_out, preemp_start_idx, preemp_len, sub( *Q_new, st->q_inp ) ); /* Q_new */ - *Q_new = add( *Q_new, Q_to_be_looked_into ); - move16(); + Scale_sig( old_inp_12k8_fx, (Word16) ( preemp_start_idx - old_inp_12k8_fx ), sub( *Q_new, st->q_inp ) ); /* Q_new */ cldfbScale.hb_scale = cldfbScale.lb_scale; move16(); @@ -870,11 +850,10 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( st->idchan == 0 && NE_16( element_mode, IVAS_CPE_MDCT ) ) { - Scale_sig( st->input_fx, 480, negate( Q_to_be_looked_into ) ); /*scaling from Q_to_be_looked_into to q0*/ - - bw_detect_fx( st, st->input_fx, NULL, enerBuffer_fx, sf_energySum, ivas_format, 0 ); + Word16 input_fx_tmp[480]; + Copy_Scale_sig( st->input_fx, input_fx_tmp, shr( input_frame, 1 ), negate( st->q_inp ) ); /*scaling from Q_inp_const to q0*/ - Scale_sig( st->input_fx, 480, Q_to_be_looked_into ); /*scaling back to Q_to_be_looked_into*/ + bw_detect_fx( st, input_fx_tmp, NULL, enerBuffer_fx, sf_energySum, ivas_format, 0 ); } @@ -1156,10 +1135,8 @@ ivas_error pre_proc_front_ivas_fx( * LP analysis *----------------------------------------------------------------*/ Word16 stab_fac_fx; - Word16 Q_new_loc; Word16 Q_r[2]; set16_fx( Q_r, 0, 2 ); - Q_new_loc = *Q_new; move16(); alw_pitch_lag_12k8[0] = st->old_pitch_la; /* Q0 */ @@ -1183,7 +1160,7 @@ ivas_error pre_proc_front_ivas_fx( } analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, - INT_FS_12k8, i, Q_new_loc, Q_r ); + INT_FS_12k8, i, *Q_new, Q_r ); FOR( Word16 idx = 0; idx < M + 1; idx++ ) { @@ -1223,6 +1200,9 @@ ivas_error pre_proc_front_ivas_fx( st->mem_wsp_q = *Q_new; move16(); move16(); + scale_sig( old_wsp_fx, L_WSP_MEM, sub( *Q_new, *q_old_wsp ) ); + *q_old_wsp = *Q_new; + move16(); ivas_find_wsp_fx( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); @@ -1253,6 +1233,7 @@ ivas_error pre_proc_front_ivas_fx( shift = s_min( add( *q_old_wsp, shift1 ), add( Q_wsp, shift2 ) ); shift = s_min( shift, add( norm_arr( st->mem_decim2_fx, 3 ), st->Q_old_wsp2 ) ); shift = s_min( shift, add( norm_arr( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ), st->Q_old_wsp2 ) ); + shift = s_min( shift, 15 ); scale_sig( old_wsp_fx, L_WSP_MEM, sub( shift, *q_old_wsp ) ); scale_sig( wsp_fx, L_WSP - L_WSP_MEM, sub( shift, Q_wsp ) ); @@ -1616,12 +1597,6 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - IF( flag_16k_smc ) - { - Scale_sig( st->input_fx, input_frame, sub( -1, st->q_inp ) ); /* Q(-1) */ - st->q_inp = -1; - move16(); - } /* these are for ivas_acelp_tcx20_switching_fx */ Scale_sig32( st->hTcxEnc->spectrum_long_fx, N_MAX, sub( st->hTcxEnc->spectrum_long_e, 16 ) ); /* Q(-1) */ st->hTcxEnc->spectrum_long_e = 16; @@ -1632,6 +1607,12 @@ ivas_error pre_proc_front_ivas_fx( move16(); IF( flag_16k_smc ) { + Scale_sig( st->input_fx - input_frame, input_frame_full, sub( -1, st->q_inp ) ); /* Q(-1) */ + st->q_inp = -1; + move16(); + st->q_old_inp = -1; + move16(); + Word16 Q_old_inp_16k = -1; move16(); @@ -1678,7 +1659,7 @@ ivas_error pre_proc_front_ivas_fx( st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q0 move16(); - *Q_new = add( *Q_new, Q_to_be_looked_into ); // actual Q_new + *Q_new = add( *Q_new, Q_inp_const ); // actual Q_new move16(); Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( *Q_new, Q_old_inp_12k8 ) ); /* Q_new */ @@ -1769,9 +1750,15 @@ ivas_error pre_proc_front_ivas_fx( st->exp_old_inp_12k8 = sub( Q15, add( *Q_new, shift ) ); move16(); + Scale_sig( st->input_fx - input_frame, input_frame_full, sub( -1, st->q_inp ) ); + st->q_inp = -1; + move16(); + st->q_old_inp = -1; + move16(); + // Scale_sig( old_inp_12k8_fx, L_INP_12k8, negate( add( *Q_new, 1 ) ) ); - *Q_new = sub( *Q_new, Q_to_be_looked_into ); // ivas_core_enc will assume inp signal (12k8 and 16k) in Q_new - 1 + *Q_new = sub( *Q_new, Q_inp_const ); // ivas_core_enc will assume inp signal (12k8 and 16k) in Q_new - 1 move16(); free( mem_decim_dummy_fx ); diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 72d5d89e8..4e7706baf 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -216,30 +216,29 @@ ivas_error ivas_cpe_enc_fx( #endif } - Copy32( data_fx_ch0, sts[0]->input32_fx, input_frame ); // Q(q_data_fx) - sts[0]->q_inp32 = q_data_fx; + Word16 Q_min = s_min( q_data_fx, add( sts[0]->q_inp32, L_norm_arr( sts[0]->input32_fx - input_frame, input_frame ) ) ); + scale_sig32( sts[0]->input32_fx - input_frame, input_frame, sub( Q_min, sts[0]->q_inp32 ) ); + Copy_Scale_sig32( data_fx_ch0, sts[0]->input32_fx, input_frame, sub( Q_min, q_data_fx ) ); // Q(Q_min) + sts[0]->q_inp32 = Q_min; move16(); + Word16 norm = L_norm_arr( sts[0]->input32_fx, input_frame ); - scale_sig32( sts[0]->input32_fx, input_frame, norm ); - sts[0]->q_inp32 = add( sts[0]->q_inp32, norm ); - move16(); - Copy_Scale_sig32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, 0 ); - sts[0]->q_inp = sub( sts[0]->q_inp32, Q16 ); + Copy_Scale_sig32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, norm ); + sts[0]->q_inp = add( sub( sts[0]->q_inp32, Q16 ), norm ); move16(); IF( data_fx_ch1 != NULL ) /*this may happen for cases with odd number of channels*/ { - Copy32( data_fx_ch1, sts[1]->input32_fx, input_frame ); // Q(q_data_fx) - sts[1]->q_inp32 = q_data_fx; + Q_min = s_min( q_data_fx, add( sts[1]->q_inp32, L_norm_arr( sts[1]->input32_fx - input_frame, input_frame ) ) ); + scale_sig32( sts[1]->input32_fx - input_frame, input_frame, sub( Q_min, sts[1]->q_inp32 ) ); + Copy_Scale_sig32( data_fx_ch1, sts[1]->input32_fx, input_frame, sub( Q_min, q_data_fx ) ); // Q(Q_min) + sts[1]->q_inp32 = Q_min; move16(); norm = L_norm_arr( sts[1]->input32_fx, input_frame ); - scale_sig32( sts[1]->input32_fx, input_frame, norm ); - sts[1]->q_inp32 = add( sts[1]->q_inp32, norm ); - move16(); - Copy_Scale_sig32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, 0 ); - sts[1]->q_inp = sub( sts[1]->q_inp32, Q16 ); + Copy_Scale_sig32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, norm ); + sts[1]->q_inp = add( sub( sts[1]->q_inp32, Q16 ), norm ); move16(); } @@ -369,26 +368,8 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Set TD stereo parameters *----------------------------------------------------------------*/ - Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ - Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ - Word16 shift = getScaleFactor32( sts[1]->input32_fx, input_frame ); - scale_sig32( sts[1]->input32_fx, input_frame, shift ); /* Q11 + shift */ - sts[1]->q_inp32 = add( Q11, shift ); - move16(); - - shift = getScaleFactor32( sts[0]->input32_fx, input_frame ); - scale_sig32( sts[0]->input32_fx, input_frame, shift ); /* Q11 + shift */ - sts[0]->q_inp32 = add( Q11, shift ); - move16(); - Q_inp = s_min( Q_inp, s_min( sts[0]->q_inp32, sts[1]->q_inp32 ) ); - scale_sig32( sts[0]->input32_fx, input_frame, sub( Q_inp, sts[0]->q_inp32 ) ); /* Q_inp */ - scale_sig32( sts[1]->input32_fx, input_frame, sub( Q_inp, sts[1]->q_inp32 ) ); /* Q_inp */ - sts[1]->q_inp32 = sts[0]->q_inp32 = Q_inp; - move16(); - move16(); - - IF( ( error = stereo_set_tdm_fx( hCPE, input_frame, Q_inp ) ) != IVAS_ERR_OK ) + IF( ( error = stereo_set_tdm_fx( hCPE, input_frame, sts[1]->q_inp32 ) ) != IVAS_ERR_OK ) { return error; } @@ -397,7 +378,7 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ - shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); + Word16 shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); move16(); @@ -741,6 +722,8 @@ ivas_error ivas_cpe_enc_fx( move16(); } stereo_tdm_downmix_ivas_fx( hCPE->hStereoTD, sts[0]->input_fx, sts[1]->input_fx, input_frame, tdm_ratio_idx, tdm_SM_flag, tdm_ratio_idx_SM ); + Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( sts[0]->q_inp32, sts[0]->q_inp ) ); + Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( sts[1]->q_inp32, sts[1]->q_inp ) ); /* signal the bitrate for BW selection in the SCh */ sts[0]->bits_frame_channel = 0; @@ -831,6 +814,9 @@ ivas_error ivas_cpe_enc_fx( move16(); move16(); stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, sts[0]->input32_fx, &out_start_ind, &out_end_ind, 0, input_Fs, input_Fs, 0, NULL ); + Scale_sig32( sts[0]->input32_fx - input_frame, add( out_start_ind, input_frame ), sub( Q15, sts[0]->q_inp32 ) ); // scaling initial part of the input buffer + sts[0]->q_inp32 = Q15; + move16(); // Normalise the input buffer from Q15 Word16 input_norm, q_inp32, common_q, fir_delay_len; @@ -890,6 +876,9 @@ ivas_error ivas_cpe_enc_fx( set16_fx( sts[1]->input_fx, 0, input_frame ); sts[1]->q_inp = Q15; move16(); + set32_fx( sts[1]->input32_fx, 0, input_frame ); + sts[1]->q_inp32 = Q31; + move16(); } #ifdef DEBUG_MODE_INFO @@ -1232,6 +1221,9 @@ ivas_error ivas_cpe_enc_fx( Copy( orig_input_fx[n], sts[n]->old_input_signal_fx, input_frame ); /* Q_orig_inp */ sts[n]->q_old_inp = Q_orig_inp[n]; move16(); + Copy_Scale_sig_16_32_no_sat( sts[n]->input_fx - input_frame, sts[n]->input32_fx - input_frame, input_frame, 16 ); // duplicating the data for input32_fx + sts[n]->q_inp32 = add( Q_orig_inp[n], 16 ); + move16(); } } ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) @@ -1239,6 +1231,7 @@ ivas_error ivas_cpe_enc_fx( Copy( sts[0]->input_fx, sts[0]->old_input_signal_fx, input_frame ); /* sts[n]->q_inp */ sts[0]->q_old_inp = sts[0]->q_inp; move16(); + Copy32( sts[0]->input32_fx, sts[0]->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ } ELSE IF( st_ivas->hMCT == NULL ) /* note: in MCT, input buffers are updated later in ivas_mct_enc() */ { @@ -1248,6 +1241,7 @@ ivas_error ivas_cpe_enc_fx( Copy( sts[n]->input_fx, sts[n]->old_input_signal_fx, input_frame ); /* sts[n]->q_inp */ sts[n]->q_old_inp = sts[n]->q_inp; move16(); + Copy32( sts[n]->input32_fx, sts[n]->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ } } diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 7f9962098..81c9e01ef 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -165,10 +165,14 @@ ivas_error ivas_ism_enc_fx( /*------------------------------------------------------------------* * Initialization - general *-----------------------------------------------------------------*/ - Copy32( data[sce_id], st->input32_fx, input_frame ); // Q(q_data) - q_st_inp_16 = sub( L_norm_arr( st->input32_fx, input_frame ), 16 ); - Copy_Scale_sig_32_16( st->input32_fx, st->input_fx, input_frame, q_st_inp_16 ); // q_data -> Q(q_inp + q_data) - st->q_inp = add( q_st_inp_16, q_data ); + Word16 Q_min = s_min( q_data, add( st->q_inp32, L_norm_arr( st->input32_fx - input_frame, input_frame ) ) ); + scale_sig32( st->input32_fx - input_frame, input_frame, sub( Q_min, st->q_inp32 ) ); + Copy_Scale_sig32( data[sce_id], st->input32_fx, input_frame, sub( Q_min, q_data ) ); // Q(Q_min) + st->q_inp32 = Q_min; + move16(); + q_st_inp_16 = sub( getScaleFactor32( st->input32_fx, input_frame ), 16 ); + Copy_Scale_sig_32_16( st->input32_fx, st->input_fx, input_frame, q_st_inp_16 ); // Q_min -> Q(q_inp + Q_min) + st->q_inp = add( q_st_inp_16, Q_min ); move16(); st->element_mode = IVAS_SCE; @@ -275,16 +279,6 @@ ivas_error ivas_ism_enc_fx( *-----------------------------------------------------------------*/ /* compute the dominant sce_id using long term energy */ - FOR( Word16 j = 0; j < st_ivas->nchan_transport; j++ ) - { - test(); - IF( st_ivas->hSCE[j] && st_ivas->hSCE[j]->hCoreCoder[0] ) - { - Copy_Scale_sig_16_32_no_sat( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ - st_ivas->hSCE[j]->hCoreCoder[0]->q_inp32 = Q11; - move16(); - } - } IF( st_ivas->hEncoderConfig->Opt_DTX_ON ) { @@ -480,6 +474,7 @@ ivas_error ivas_ism_enc_fx( Copy( st->input_fx, st->old_input_signal_fx, input_frame ); /* st->q_inp */ st->q_old_inp = st->q_inp; move16(); + Copy32( st->input32_fx, st->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ hSCE->last_element_brate = hSCE->element_brate; /* Q0 */ move32(); diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index b2e0e9c69..f1631ba4f 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -122,10 +122,14 @@ ivas_error ivas_sce_enc_fx( set16_zero_fx( old_inp_12k8_fx[0], L_INP_12k8 ); - Copy32( data_fx, st->input32_fx, input_frame ); // Q(q_data_fx) - q_input = sub( add( L_norm_arr( st->input32_fx, input_frame ), q_data_fx ), 16 ); + Word16 Q_min = s_min( q_data_fx, add( st->q_inp32, L_norm_arr( st->input32_fx - input_frame, input_frame ) ) ); + scale_sig32( st->input32_fx - input_frame, input_frame, sub( Q_min, st->q_inp32 ) ); + Copy_Scale_sig32( data_fx, st->input32_fx, input_frame, sub( Q_min, q_data_fx ) ); // Q(Q_min) + st->q_inp32 = Q_min; + move16(); + q_input = sub( add( L_norm_arr( st->input32_fx, input_frame ), Q_min ), 16 ); - Copy_Scale_sig32_16( st->input32_fx, st->input_fx, input_frame, sub( add( Q16, q_input ), q_data_fx ) ); // Q(q_data_fx) -> Q(q_input) + Copy_Scale_sig32_16( st->input32_fx, st->input_fx, input_frame, sub( add( Q16, q_input ), Q_min ) ); // Q(Q_min) -> Q(q_input) st->q_inp = q_input; move16(); @@ -362,6 +366,7 @@ ivas_error ivas_sce_enc_fx( Copy( st->input_fx, st->old_input_signal_fx, input_frame ); st->q_old_inp = st->q_inp; move16(); + Copy32( st->input32_fx, st->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ hSCE->last_element_brate = hSCE->element_brate; move32(); diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index b9f47136f..63c0d5d54 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2948,11 +2948,11 @@ void ivas_smc_mode_selection_fx( ton = tonal_det_fx( S_map, st->vad_flag, hSpMusClas->tod_S_map_lt_fx, &hSpMusClas->tod_thr_lt_fx, &hSpMusClas->tod_weight_fx, &hSpMusClas->tod_S_mass_prev_fx, &hSpMusClas->tod_S_mass_lt_fx ); // Q22 /* calculate spectral peak-to-average ratio */ - Word16 shift = sub( add( Q_new, Q_SCALE - 2 ), st->hSpMusClas->Q_tod_lt_Bin_E ); + Word16 shift = sub( st->q_Bin_E, st->hSpMusClas->Q_tod_lt_Bin_E ); FOR( i = 0; i < TOD_NSPEC; i++ ) { // st->hSpMusClas->tod_lt_Bin_E[i] = P2A_FACT * st->hSpMusClas->tod_lt_Bin_E[i] + ( 1 - P2A_FACT ) * st->Bin_E[i]; - st->hSpMusClas->tod_lt_Bin_E_fx[i] = Madd_32_16( L_shl( Mpy_32_16_1( st->hSpMusClas->tod_lt_Bin_E_fx[i], P2A_FACT_FX_Q15 ), shift ), st->Bin_E_fx[i], ( 32767 - P2A_FACT_FX_Q15 ) ); // Q = Q_new + Q_SCALE - 2 + st->hSpMusClas->tod_lt_Bin_E_fx[i] = Madd_32_16( L_shl( Mpy_32_16_1( st->hSpMusClas->tod_lt_Bin_E_fx[i], P2A_FACT_FX_Q15 ), shift ), st->Bin_E_fx[i], ( 32767 - P2A_FACT_FX_Q15 ) ); // Q = st->q_Bin_E + Q_SCALE - 2 move32(); } st->hSpMusClas->Q_tod_lt_Bin_E = add( st->hSpMusClas->Q_tod_lt_Bin_E, shift ); @@ -2969,11 +2969,11 @@ void ivas_smc_mode_selection_fx( IF( LE_32( element_brate, IVAS_16k4 ) ) { - thr_sp2a = L_shl( THR_P2A_HIGH_FX, add( Q_new, Q_SCALE - 2 ) ); // Q = Q_new + Q_SCALE - 2 + thr_sp2a = L_shl( THR_P2A_HIGH_FX, st->q_Bin_E ); // Q = st->q_Bin_E } ELSE { - thr_sp2a = L_shl( THR_P2A_FX, add( Q_new, Q_SCALE - 2 ) ); // Q = Q_new + Q_SCALE - 2 + thr_sp2a = L_shl( THR_P2A_FX, st->q_Bin_E ); // Q = st->q_Bin_E } /* initial 3-way selection of coding modes (ACELP/GSC/TCX) */ -- GitLab From d307078616b59d33498ac589a1055838c9ae11c0 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 12:43:47 +0530 Subject: [PATCH 0695/1221] Fix for 3GPP issue 1407: BASOP encoder: Distortion Stereo DTX 24.4 kbps, high MLD Link #1407 --- lib_enc/ivas_cpe_enc_fx.c | 53 ++++++++++++++--------------- lib_enc/ivas_stereo_dft_enc_fx.c | 17 +++------ lib_enc/ivas_stereo_dft_td_itd_fx.c | 36 ++++++++++++++------ 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 4e7706baf..be0afc1a4 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -127,6 +127,7 @@ ivas_error ivas_cpe_enc_fx( Word16 e_old_wsp[CPE_CHANNELS], q_old_wsp; move16(); // Q_new move16(); // Q_new + Word16 q_com; error = IVAS_ERR_OK; move32(); @@ -649,35 +650,31 @@ ivas_error ivas_cpe_enc_fx( hCPE->hStereoDft->Spd_R_smooth_fx_e = sub( hCPE->hStereoDft->Spd_R_smooth_fx_e, temp ); move16(); - shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Copy_Scale_sig_32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, sub( add( sts[1]->q_inp, shift ), sts[1]->q_inp32 ) ); /* sts[1]->q_inp + shift */ - sts[1]->q_inp = add( sts[1]->q_inp, shift ); - move16(); - Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( s_min( sts[1]->q_old_inp, sts[1]->q_inp ), sts[1]->q_old_inp ) ); /* min( sts[1]->q_old_inp, sts[1]->q_inp) */ - sts[1]->q_inp = s_min( sts[1]->q_inp, sts[1]->q_old_inp ); - move16(); - sts[1]->q_old_inp = sts[1]->q_inp; - move16(); - shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[0]->q_old_inp + shift */ - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Copy_Scale_sig_32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, sub( add( sts[0]->q_inp, shift ), sts[0]->q_inp32 ) ); /* sts[0]->q_inp + shift */ - sts[0]->q_inp = add( sts[0]->q_inp, shift ); - move16(); - Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( s_min( sts[0]->q_old_inp, sts[0]->q_inp ), sts[0]->q_old_inp ) ); /* min( sts[1]->q_old_inp, sts[1]->q_inp) */ - sts[0]->q_inp = s_min( sts[0]->q_inp, sts[0]->q_old_inp ); - move16(); - sts[0]->q_old_inp = sts[0]->q_inp; - move16(); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + q_com = sub( add( L_norm_arr( sts[n]->input32_fx, input_frame ), sts[n]->q_inp32 ), 16 ); + q_com = s_min( q_com, add( norm_arr( sts[n]->old_input_signal_fx, input_frame ), sts[n]->q_old_inp ) ); + q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hCPE->hStereoDft->dft_ovl ), hCPE->q_input_mem[n] ) ); + + if ( EQ_16( q_com, Q15 ) ) + { + q_com = 0; + move16(); + } + + Copy_Scale_sig_32_16( sts[n]->input32_fx, sts[n]->input_fx, input_frame, sub( q_com, sts[n]->q_inp32 ) ); + sts[n]->q_inp = q_com; + move16(); + + scale_sig( sts[n]->old_input_signal_fx, input_frame, sub( q_com, sts[n]->q_old_inp ) ); + sts[n]->q_old_inp = q_com; + move16(); + + scale_sig( hCPE->input_mem_fx[n], hCPE->hStereoDft->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) ); + hCPE->q_input_mem[n] = q_com; + move16(); + } stereo_dft_hybrid_ITD_flag_fx( hCPE->hStereoDft->hConfig, input_Fs, hCPE->hStereoDft->hItd->hybrid_itd_max ); diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index cebbc2619..01318af28 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -1064,23 +1064,14 @@ void stereo_dft_enc_analyze_fx( Word16 q_shift, guarded_bits; guarded_bits = find_guarded_bits_fx( NFFT ); - q_shift = sub( getScaleFactor32( pDFT_L, NFFT ), guarded_bits ); - q_shift = s_min( q_shift, sub( getScaleFactor32( pDFT_R, NFFT ), guarded_bits ) ); - FOR( Word16 j = 0; j < NFFT; j++ ) - { - pDFT_L[j] = L_shl( pDFT_L[j], q_shift ); - move32(); - } + q_shift = sub( L_norm_arr( pDFT_L, NFFT ), guarded_bits ); + scale_sig32( pDFT_L, NFFT, q_shift ); DFT_e[0] = sub( DFT_e[0], q_shift ); move16(); - FOR( Word16 j = 0; j < NFFT; j++ ) - { - pDFT_R[j] = L_shl( pDFT_R[j], q_shift ); - move32(); - } - + q_shift = sub( L_norm_arr( pDFT_R, NFFT ), guarded_bits ); + scale_sig32( pDFT_R, NFFT, q_shift ); DFT_e[1] = sub( DFT_e[1], q_shift ); move16(); diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index df4fe3edd..569a5690a 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -380,15 +380,6 @@ void stereo_td_itd_fx( move16(); set16_fx( shift_input, 0, input_frame ); - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - - Scale_sig( &input_mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); // Q(sts[n]->q_inp) - // Scale_sig(&sts[n]->old_input_signal_fx, 1965, sts[n]->q_inp - sts[n]->q_old_inp); - // sts[n]->q_old_inp = sts[n]->q_inp; - q_input_mem[n] = sts[n]->q_inp; - move16(); - } IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { FOR( n = 0; n < CPE_CHANNELS; n++ ) @@ -540,7 +531,7 @@ void stereo_td_itd_mdct_stereo_fx( const Word16 input_frame /* i : frame length */ ) { - Word16 i; + Word16 i, n, q_com; Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC]; Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC]; Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC]; @@ -584,6 +575,31 @@ void stereo_td_itd_mdct_stereo_fx( /*call ITD function*/ stereo_dft_enc_compute_itd_fx( hCPE, DFT_fx[0], DFT_tmp_e[0], DFT_fx[1], DFT_tmp_e[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_e, bin_nrgR_fx, bin_nrgR_e ); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + q_com = add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ); + q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ), hCPE->hCoreCoder[n]->q_old_inp ) ); + q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl ), hCPE->q_input_mem[n] ) ); + + if ( EQ_16( q_com, Q15 ) ) + { + q_com = 0; + move16(); + } + + scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_inp ) ); + hCPE->hCoreCoder[n]->q_inp = q_com; + move16(); + + scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_old_inp ) ); + hCPE->hCoreCoder[n]->q_old_inp = q_com; + move16(); + + scale_sig( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) ); + hCPE->q_input_mem[n] = q_com; + move16(); + } + /* Time Domain ITD compensation using extrapolation */ stereo_td_itd_fx( hStereoMdct->hItd, NULL, NULL, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem_fx, hCPE->q_input_mem ); } -- GitLab From cdb308b8db07cccd2d30a67e92547f673cca4aae Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 14:26:16 +0530 Subject: [PATCH 0696/1221] Fix for 3GPP issue 1427: Basop Encoder Spectral Gaps in Stereo DTX 13.2 kbps Noisy Signal Link #1427 --- lib_enc/ivas_core_pre_proc_front_fx.c | 51 +++++++++++++++++---------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 0eb6d1887..f4f9d5651 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -56,7 +56,7 @@ #define SCE_SMC_THR 16000 -static void calculate_energy_buffer_ivas_fx( CPE_ENC_HANDLE hCPE, Word32 enerBuffer_dft[], const Word16 no_channels, const Word32 input_Fs, Word16 *enerBuffer_dft_e ); +static void calculate_energy_buffer_ivas_fx( CPE_ENC_HANDLE hCPE, Word32 enerBuffer_dft[], const Word16 no_channels, const Word32 input_Fs, Word16 enerBuffer_dft_e[] ); #ifdef IVAS_FIXED_ENC static void calculate_energy_buffer_fx( CPE_ENC_HANDLE hCPE, Word64 enerBuffer_dft_fx[], Word16 *enerBuffer_dft_q_fx, const Word16 no_channels, const Word32 input_Fs ); @@ -222,6 +222,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word16 res_cod_SNR_M_fx_e[STEREO_DFT_BAND_MAX]; Word16 Qfact_PS, q_lf_E_fx; + Word16 enerBuffer_fx_exp_buf[CLDFB_NO_CHANNELS_MAX]; #ifdef DEBUG_MODE_INFO Word32 *in_buff_temp; Word16 in_q_temp; @@ -474,7 +475,7 @@ ivas_error pre_proc_front_ivas_fx( } ELSE IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - calculate_energy_buffer_ivas_fx( hCPE, enerBuffer_fx, st->cldfbAnaEnc->no_channels, input_Fs, enerBuffer_fx_exp ); + calculate_energy_buffer_ivas_fx( hCPE, enerBuffer_fx, st->cldfbAnaEnc->no_channels, input_Fs, enerBuffer_fx_exp_buf ); } ELSE { @@ -841,10 +842,18 @@ ivas_error pre_proc_front_ivas_fx( /*----------------------------------------------------------------* * NB/WB/SWB/FB bandwidth detector *----------------------------------------------------------------*/ - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - sf_energySum[i] = *enerBuffer_fx_exp; - move16(); + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + sf_energySum[i] = enerBuffer_fx_exp_buf[i]; + move16(); + } + } + ELSE + { + set16_fx( sf_energySum, *enerBuffer_fx_exp, CLDFB_NO_CHANNELS_MAX ); } test(); @@ -856,6 +865,15 @@ ivas_error pre_proc_front_ivas_fx( bw_detect_fx( st, input_fx_tmp, NULL, enerBuffer_fx, sf_energySum, ivas_format, 0 ); } + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + maximum_fx( sf_energySum, CLDFB_NO_CHANNELS_MAX, enerBuffer_fx_exp ); + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + enerBuffer_fx[i] = L_shl( enerBuffer_fx[i], sub( sf_energySum[i], *enerBuffer_fx_exp ) ); + move32(); + } + } IF( NE_16( element_mode, IVAS_CPE_MDCT ) ) /* in MDCT stereo, set_bw_stereo() is used instead */ { @@ -1840,7 +1858,7 @@ static void calculate_energy_buffer_ivas_fx( Word32 enerBuffer_dft_fx[], /* o : energy buffer() exp(enerBuffer_dft_e)*/ const Word16 no_channels, /* i : no. of used CLDFB channels Q0*/ const Word32 input_Fs, /* i : input sampling rate Q0*/ - Word16 *enerBuffer_dft_e ) + Word16 enerBuffer_dft_e[] ) { Word16 i, j, guard_bits; Word64 nrg_DMX_fx[CLDFB_NO_CHANNELS_MAX]; @@ -1848,11 +1866,8 @@ static void calculate_energy_buffer_ivas_fx( Word32 *pDFT_DMX_fx; /*q_DFT_DMX_fx*/ Word32 chan_width_bins_fx; Word16 band_res_dft_fx, chan_width_f_fx, start, stop; - Word16 norm_nrg_DMX_fx; - Word64 max_abs_nrg_DMX_fx; + Word16 norm_nrg_DMX_fx[CLDFB_NO_CHANNELS_MAX]; - max_abs_nrg_DMX_fx = 0; - move64(); Word16 temp_q1 = sub( norm_l( input_Fs ), 1 ); Word16 temp_q2 = norm_s( hCPE->hStereoDft->NFFT ); @@ -1884,30 +1899,28 @@ static void calculate_energy_buffer_ivas_fx( *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, W_shr( W_mult_32_32( pDFT_DMX_fx[2 * j + 1], pDFT_DMX_fx[2 * j + 1] ), guard_bits ) ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits */ move64(); } - IF( GT_64( W_abs( *p_nrg_DMX_fx ), max_abs_nrg_DMX_fx ) ) - { - max_abs_nrg_DMX_fx = W_abs( *p_nrg_DMX_fx ); - } + norm_nrg_DMX_fx[i] = W_norm( W_abs( *p_nrg_DMX_fx ) ); + move16(); start = stop; move16(); p_nrg_DMX_fx++; } - norm_nrg_DMX_fx = W_norm( max_abs_nrg_DMX_fx ); FOR( i = 0; i < no_channels; i++ ) /* Consider only used channels, dependent on Fs */ { - enerBuffer_dft_fx[i] = Mpy_32_16_1( W_extract_h( W_shl( nrg_DMX_fx[i], norm_nrg_DMX_fx ) ), 10923 /* 1/3 in Q15 */ ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits + norm_nrg_DMX_fx - 32 */ + enerBuffer_dft_fx[i] = Mpy_32_16_1( W_extract_h( W_shl( nrg_DMX_fx[i], norm_nrg_DMX_fx[i] ) ), 10923 /* 1/3 in Q15 */ ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits + norm_nrg_DMX_fx[i] - 32 */ move32(); + enerBuffer_dft_e[i] = sub( add( shl( hCPE->hStereoDft->DFT_fx_e[0], 1 ), guard_bits ), norm_nrg_DMX_fx[i] ); + move16(); } - *enerBuffer_dft_e = sub( add( shl( hCPE->hStereoDft->DFT_fx_e[0], 1 ), guard_bits ), norm_nrg_DMX_fx ); - move16(); - /* Set remaining entries of enerBuffer to zero */ FOR( ; i < CLDFB_NO_CHANNELS_MAX; i++ ) { enerBuffer_dft_fx[i] = 0; move32(); + enerBuffer_dft_e[i] = 0; + move16(); } return; } -- GitLab From cf8d0c484c6abb583658c0abd34dccff73b50f8d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 15:05:26 +0530 Subject: [PATCH 0697/1221] Q mismatch fix in stereo_icBWE_enc_ivas_fx stack --- lib_com/deemph.c | 11 ++--- lib_com/prot_fx.h | 1 - lib_dec/ivas_stereo_icbwe_dec_fx.c | 2 +- lib_enc/ivas_stereo_ica_enc_fx.c | 8 ++-- lib_enc/ivas_stereo_icbwe_enc_fx.c | 64 +++++++++++++++++++----------- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/lib_com/deemph.c b/lib_com/deemph.c index c03a050bc..9bc20cb6f 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -41,26 +41,23 @@ void deemph_fx_32( - Word16 shift, /*scaled output*/ Word32 *signal, /* i/o: signal Qx*/ const Word16 mu, /* i : deemphasis factor Q15*/ const Word16 L, /* i : vector size */ - Word32 *mem /* i/o: memory (y[-1]) Qx+shift*/ + Word32 *mem /* i/o: memory (y[-1]) Qx*/ ) { Word16 i; - signal[0] = L_add( signal[0], Mpy_32_16_1( ( *mem ), mu ) ); /*Qx*/ + signal[0] = Madd_32_16( signal[0], *mem, mu ); // Qx move32(); FOR( i = 1; i < L; i++ ) { - signal[i] = L_add( signal[i], Mpy_32_16_1( signal[i - 1], mu ) ); /*Qx*/ - signal[i] = L_shl( signal[i], shift ); /*Qx+shift*/ - move32(); + signal[i] = Madd_32_16( signal[i], signal[i - 1], mu ); // Qx move32(); } - *mem = signal[L - 1]; /*Qx+shift*/ + *mem = signal[L - 1]; // Qx move32(); return; diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 851b461bf..ffd1d6032 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1651,7 +1651,6 @@ void deemph_fx( void E_UTIL_deemph2( Word16 shift, Word16 *x, const Word16 mu, const Word16 L, Word16 *mem ); void deemph_fx_32( - Word16 shift, /* i : scaled output */ Word32 *signal, /* i/o: signal */ const Word16 mu, /* i : deemphasis factor */ const Word16 L, /* i : vector size */ diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c9f7cac92..c7bc98566 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -611,7 +611,7 @@ void stereo_icBWE_dec_fx( Q_syn_shb = tmp; move16(); - deemph_fx_32( 0, shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); + deemph_fx_32( shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); hStereoICBWE->prev_Q_memshbspec = Q_syn_shb; move16(); Copy32( shb_synth_nonref_fx + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD ); /* Q_syn_shb */ diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 78ea50d7e..a8a088f20 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -408,8 +408,8 @@ static void deEmphResample_fx( /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */ - deemph_fx_32( 0, buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] ); - deemph_fx_32( 0, buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] ); + deemph_fx_32( buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] ); + deemph_fx_32( buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] ); FOR( i = 0; i < ( input_frame / dsFac1 ); i++ ) { @@ -420,8 +420,8 @@ static void deEmphResample_fx( } /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */ - deemph_fx_32( 0, tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] ); - deemph_fx_32( 0, tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] ); + deemph_fx_32( tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] ); + deemph_fx_32( tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] ); FOR( i = 0; i < ( input_frame / dsFactor ); i++ ) { diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 02d20543b..eba30f762 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -102,14 +102,15 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( const Word32 *shb_frame_target_fx, /* i : target shb Q31-shb_frame_target_e*/ Word16 shb_frame_target_e, Word32 *shb_synth_nonref_fx, /* o : non-ref shb synth Q31-shb_synth_nonref_e*/ - Word16 shb_synth_nonref_e, + Word16 *shb_synth_nonref_e, Word32 *specMapping_fx, /* i/o: current frame's mapping Qx*/ - Word32 *memShbSpecMapping_fx, /* i/o: current frame's mapping Qx*/ - Word32 *memShbSpecXcorr_fx, /* i/o: ic bwe spec mapping scorr memory Q31-memShbSpecXcorr_e*/ + Word32 *memShbSpecMapping_fx, /* i/o: current frame's mapping Q31-memShbSpecMapping_e*/ + Word16 *memShbSpecMapping_e, + Word32 *memShbSpecXcorr_fx, /* i/o: ic bwe spec mapping scorr memory Q31-memShbSpecXcorr_e*/ Word16 *memShbSpecXcorr_e ) { Word16 idx; - + Word16 max_exp; Word16 Txx1_fx = 0, Txx2_fx = 0, Txx3_fx = 0, T_desired_fx = 0; Word16 Txx1_e = 0, Txx2_e = 0, Txx3_e = 0, T_desired_e = 0; Word16 T_nonref_target_fx, temp_fx; @@ -136,10 +137,10 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( temp11_fx = dotp_fixed_ivas_fx( shb_frame_target_fx, shb_frame_target_e, shb_frame_target_fx + 1, shb_frame_target_e, L_FRAME16k - 1, &temp11_exp ); /* Q31-temp1_exp */ /* Calculate rxx(1)/rxx(0) of the non ref synth */ - temp0_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, L_FRAME16k - 3, &temp0_exp ); /* Q31-temp0_exp */ - temp1_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 1, shb_synth_nonref_e, L_FRAME16k - 3, &temp1_exp ); /* Q31-temp1_exp */ - temp2_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 2, shb_synth_nonref_e, L_FRAME16k - 3, &temp2_exp ); /* Q31-temp2_exp */ - temp3_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 3, shb_synth_nonref_e, L_FRAME16k - 3, &temp3_exp ); /* Q31-temp3_exp */ + temp0_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx, *shb_synth_nonref_e, L_FRAME16k - 3, &temp0_exp ); /* Q31-temp0_exp */ + temp1_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx + 1, *shb_synth_nonref_e, L_FRAME16k - 3, &temp1_exp ); /* Q31-temp1_exp */ + temp2_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx + 2, *shb_synth_nonref_e, L_FRAME16k - 3, &temp2_exp ); /* Q31-temp2_exp */ + temp3_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx + 3, *shb_synth_nonref_e, L_FRAME16k - 3, &temp3_exp ); /* Q31-temp3_exp */ exp = s_max( *memShbSpecXcorr_e, s_max( s_max( s_max( temp00_exp, temp11_exp ), s_max( temp0_exp, temp1_exp ) ), s_max( temp2_exp, temp3_exp ) ) ); @@ -291,8 +292,19 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( *specMapping_fx = L_deposit_h( specMapping16 ); move32(); + max_exp = s_max( sub( *memShbSpecMapping_e, norm_l( *memShbSpecMapping_fx ) ), *shb_synth_nonref_e ); + + *memShbSpecMapping_fx = L_shl( *memShbSpecMapping_fx, sub( *memShbSpecMapping_e, max_exp ) ); // max_exp + move32(); + *memShbSpecMapping_e = max_exp; + move16(); + + scale_sig32( shb_synth_nonref_fx, L_FRAME16k, sub( *shb_synth_nonref_e, max_exp ) ); // max_exp + *shb_synth_nonref_e = max_exp; + move16(); + /* IC-BWE spec mapping */ - deemph_fx_32( 0, shb_synth_nonref_fx, extract_h( *specMapping_fx ), L_FRAME16k, memShbSpecMapping_fx ); + deemph_fx_32( shb_synth_nonref_fx, specMapping16, L_FRAME16k, memShbSpecMapping_fx ); // shb_synth_nonref_e return idx; } @@ -429,7 +441,7 @@ static void icbwe_dft_stereo_param_ivas_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i : */ Encoder_State *st, /* i/o: */ Word32 *shb_synth_nonref_fx, /* i/o: Q31-shb_synth_nonref_e*/ - Word16 shb_synth_nonref_e /* i/o: */ + Word16 *shb_synth_nonref_e /* i/o: */ ) { Word16 slopeILD_fx; @@ -439,7 +451,7 @@ static void icbwe_dft_stereo_param_ivas_fx( Word32 *nrg_L_fx, *nrg_R_fx, *nrg_DMX_fx; Word32 sum_nrg_L_fx, sum_nrg_R_fx, sum_nrg_DMX_fx; const Word32 spec_table_fx[4] = { -1288490189, -858993459, -429496730, 0 }; // Q31 - const Word16 slope_table_fx16[4] = { -17788, -10577, -4822, 0 }; // Q13 + const Word16 slope_table_fx16[4] = { -278, -165, -75, 0 }; // Q7 BSTR_ENC_HANDLE hBstr = st->hBstr; normFac_fx = 1342177280; /* 1000 * (10/((14400+10400)/2 - (6400+10400)/2)) */ // Q29 @@ -505,6 +517,7 @@ static void icbwe_dft_stereo_param_ivas_fx( IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) { /* Spec Mapping Estimate */ + Word16 max_exp; Word16 tmp1, exp1; Word32 L_tmp, L_tmp1; L_tmp = Mpy_32_32( hStereoICBWE->mem_nrg_L_fx[1], hStereoICBWE->mem_nrg_R_fx[0] ); // hStereoICBWE->mem_nrg_L_fx_e[1] + hStereoICBWE->mem_nrg_R_fx_e[1] @@ -527,10 +540,20 @@ static void icbwe_dft_stereo_param_ivas_fx( } hStereoICBWE->prevSpecMapping_fx = spec_table_fx[spIndx]; // q31 - /* ic bwe spec mapping application */ - deemph_fx_32( 0, shb_synth_nonref_fx, extract_l( L_shr( hStereoICBWE->prevSpecMapping_fx, 16 ) ), L_FRAME16k, &hStereoICBWE->memShbSpecMapping_fx ); // shb_synth_nonref_e - hStereoICBWE->memShbSpecMapping_e = shb_synth_nonref_e; + + max_exp = s_max( *shb_synth_nonref_e, sub( hStereoICBWE->memShbSpecMapping_e, norm_l( hStereoICBWE->memShbSpecMapping_fx ) ) ); + + hStereoICBWE->memShbSpecMapping_fx = L_shl( hStereoICBWE->memShbSpecMapping_fx, sub( hStereoICBWE->memShbSpecMapping_e, max_exp ) ); // max_exp + move32(); + hStereoICBWE->memShbSpecMapping_e = max_exp; + move16(); + + scale_sig32( shb_synth_nonref_fx, L_FRAME16k, sub( *shb_synth_nonref_e, max_exp ) ); + *shb_synth_nonref_e = max_exp; move16(); + + /* ic bwe spec mapping application */ + deemph_fx_32( shb_synth_nonref_fx, extract_h( hStereoICBWE->prevSpecMapping_fx ), L_FRAME16k, &hStereoICBWE->memShbSpecMapping_fx ); // shb_synth_nonref_e } ELSE { @@ -572,7 +595,7 @@ static void icbwe_dft_stereo_param_ivas_fx( move32(); move16(); - gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); /* Q0 */ + gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); /* Q0 */ hStereoICBWE->gDes_pastFrame_fx = L_deposit_h( gDes_fx ); /* Q31-exp */ hStereoICBWE->gDes_pastFrame_e = exp; @@ -800,7 +823,7 @@ void stereo_icBWE_enc_ivas_fx( move16(); } - icbwe_dft_stereo_param_ivas_fx( hStereoICBWE, hStereoDft, st, shb_synth_nonref_fx, shb_synth_nonref_e ); + icbwe_dft_stereo_param_ivas_fx( hStereoICBWE, hStereoDft, st, shb_synth_nonref_fx, &shb_synth_nonref_e ); } ELSE { @@ -1020,14 +1043,7 @@ void stereo_icBWE_enc_ivas_fx( IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) { /* IC BWE spectral mapping */ - Word32 max_abs_val; - maximum_abs_32_fx( shb_synth_nonref_fx, L_FRAME16k, &max_abs_val ); - IF( max_abs_val > 0 ) - { - scale_sig32( shb_synth_nonref_fx, L_FRAME16k, -1 ); - shb_synth_nonref_e = sub( shb_synth_nonref_e, -1 ); - } - spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); /* Q0 */ + spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_e ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); /* Q0 */ } ELSE { -- GitLab From 272b5e75fb5783e1e393450245399e444392d6e3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 16:33:13 +0530 Subject: [PATCH 0698/1221] Crash fix when Debugging mode was enabled --- lib_enc/ivas_core_pre_proc_front_fx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 0eb6d1887..ec752e71a 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -242,8 +242,16 @@ ivas_error pre_proc_front_ivas_fx( move16(); #ifdef DEBUG_MODE_INFO - in_buff_temp = hSCE->hCoreCoder[n]->input32_fx; - in_q_temp = hSCE->hCoreCoder[n]->q_inp32; + IF( hSCE != NULL ) + { + in_buff_temp = hSCE->hCoreCoder[n]->input32_fx; + in_q_temp = hSCE->hCoreCoder[n]->q_inp32; + } + ELSE + { + in_buff_temp = hCPE->hCoreCoder[n]->input32_fx; + in_q_temp = hCPE->hCoreCoder[n]->q_inp32; + } #endif -- GitLab From 45965109a47920fd540871b564d4702a2328a2b2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 16:35:27 +0530 Subject: [PATCH 0699/1221] Fix for 3GPP issue 1018: ParamISM: Ext-Output: Difference in high-band Link #1018 --- lib_com/swb_tbe_com_fx.c | 125 ++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..238b478c5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -12,11 +12,12 @@ #include "ivas_prot_fx.h" #include "options_warnings.h" -#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ -#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 // Q31 -#define POW_EXC16k_WHTND_FX 178125000 // Q-6 -#define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ -#define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ +#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ +#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 // Q31 +#define POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49 1667313793 // Q49 +#define POW_EXC16k_WHTND_FX 178125000 // Q-6 +#define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ +#define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ /*-----------------------------------------------------------------* * Local function prototypes @@ -3958,7 +3959,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; Word32 pow1, pow22; Word16 scale, temp1, temp2, temp3; - + Word16 Q_White_exc16k; Word16 excTmp2[L_FRAME16k]; Word16 *White_exc16k; Word16 excNoisyEnv[L_FRAME16k]; @@ -3989,12 +3990,13 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word32 White_exc16k_32[L_FRAME16k]; Word16 White_exc16k_tmp[L_FRAME16k]; Word16 Q_temp; - Word16 prev_Q_bwe_exc_fb; - Word16 chk1, chk2; + Word16 prev_Q_bwe_exc_fb, Q_exc16kWhtnd; + Word16 chk1; + Word32 chk2; chk1 = 0; chk2 = 0; move16(); - move16(); + move32(); #if 1 // def ADD_IVAS_TBE_CODE Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; @@ -4262,7 +4264,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( } /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49; move32(); move32(); pow22 = POW_EXC16k_WHTND_FX; @@ -4271,21 +4273,23 @@ void GenShapedSHBExcitation_ivas_dec_fx( // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); Word16 pow1_exp = sub( Q31, Q_pow1 ); Word32 temp_pow = Sqrt32( pow1, &pow1_exp ); - temp_pow = L_shl( Mpy_32_32( temp_pow, pow22_inv ), pow1_exp ); + temp_pow = Mpy_32_32( temp_pow, pow22_inv ); /*Word16 out_exp; Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); temp_pow1 = L_shl(temp_pow1, out_exp);*/ // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); L_tmp = 0; move32(); + shift = getScaleFactor16( White_exc16k, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); move32(); - White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], sub( *Q_bwe_exc, NOISE_QADJ ) ) ); // Q_bwe_exc - NOISE_QADJ + White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], shift ) ); // Q_White_exc16k move16(); L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); } + Q_White_exc16k = add( shift, sub( 49 - 31, pow1_exp ) ); Q_temp = norm_l( L_tmp ); IF( L_tmp == 0 ) { @@ -4323,22 +4327,24 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* calculate pow22 */ /* pow22=0.00001f */ tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - pow22 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Word64 sum = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { - /* White_exc16k[k] *= excNoisyEnv[k]; */ - White_exc16k[k] = mult_r( excNoisyEnv[k], shl( White_exc16k[k], 1 ) ); // Q_excTmp2 + 5 + 1 - 15 ==> Q_excTmp2 - 9 - move16(); - chk2 = s_or( chk2, White_exc16k[k] ); + + White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 + chk2 = L_or( chk2, White_exc16k_32[k] ); /* i: excNoisyEnv in (Q_excTmp2) */ /* i: White_exc16k in Q6 */ - /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + /* o: White_exc16k in (Q_White_exc16k) */ /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2-NOISE_QADJ)*/ + sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ + move16(); } - /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ - Q_pow22 = shl( sub( Q_excTmp2, NOISE_QADJ ), 1 ); - Scale_sig( White_exc16k, L_FRAME16k, sub( *Q_bwe_exc, Q_excTmp2 ) ); + Q_pow22 = W_norm( sum ); + pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); + Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); } #if 1 // def ADD_IVAS_TBE_CODE @@ -4625,7 +4631,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( move16(); } } -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) { @@ -4638,29 +4643,42 @@ void GenShapedSHBExcitation_ivas_dec_fx( temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); Word16 temp_fac = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 + shift = sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ); // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); FOR( k = 0; k < L_FRAME16k; k++ ) { - mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); + mixExc16k[k] = mult_r( shl_sat( White_exc16k[k], shift ), temp_fac ); move16(); } } -#endif tmp = sub( Q_temp, 3 ); FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_FB[k] = White_exc16k[k]; /* Q_bwe_exc-NOISE_QADJ */ + White_exc16k_FB[k] = White_exc16k[k]; /* Q_White_exc16k */ } prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; move16(); - *Q_bwe_exc_fb = sub( *Q_bwe_exc, NOISE_QADJ ); + *Q_bwe_exc_fb = Q_White_exc16k; move16(); + *tbe_demph = shl_sat( *tbe_demph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ - /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ + *tbe_demph = shl_sat( *tbe_demph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); -#if 1 // def ADD_IVAS_TBE_CODE + Q_exc16kWhtnd = getScaleFactor16( exc16kWhtnd, L_FRAME16k ); + Q_exc16kWhtnd = add( Q_exc16kWhtnd, *Q_bwe_exc ); + + shift = getScaleFactor16( White_exc16k, L_FRAME16k ); + + shift = s_min( Q_exc16kWhtnd, add( shift, Q_White_exc16k ) ); + scale_sig( exc16kWhtnd, L_FRAME16k, sub( shift, *Q_bwe_exc ) ); + scale_sig( White_exc16k, L_FRAME16k, sub( shift, Q_White_exc16k ) ); + + Q_exc16kWhtnd = Q_White_exc16k = shift; + move16(); + move16(); + *tbe_premph = shl_sat( *tbe_premph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); + move16(); test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { @@ -4693,11 +4711,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* mixing of LB and gaussian excitation in the first half of the frame */ FOR( k = 0; k < L_FRAME16k / 2; k++ ) { - // exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(fact, mult(shl(White_exc16k[k], *Q_bwe_exc), scale)), mult_r(sub(32767, fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( fact, mult_r( White_exc16k[k], scale ) ), NOISE_QADJ ), - L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + exc16kWhtnd[k] = mac_r( L_mult( fact, mult_r( White_exc16k[k], scale ) ), + sub( 32767, fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd move16(); fact = add_sat( fact, step ); scale = add_sat( scale, step_scale ); @@ -4706,11 +4721,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* mixing of LB and gaussian excitation in the second half of the frame */ FOR( ; k < L_FRAME16k; k++ ) { - // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(new_fact, shl(White_exc16k[k], *Q_bwe_exc)), mult_r(sub(32767, new_fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( new_fact, White_exc16k[k] ), NOISE_QADJ ), - mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + exc16kWhtnd[k] = mac_r( L_mult( new_fact, White_exc16k[k] ), + sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd move16(); } } @@ -4718,14 +4730,9 @@ void GenShapedSHBExcitation_ivas_dec_fx( PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); } ELSE -#endif { -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) -#else - IF( EQ_16( coder_type, UNVOICED ) ) -#endif { L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); test(); @@ -4737,16 +4744,12 @@ void GenShapedSHBExcitation_ivas_dec_fx( scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ FOR( k = 0; k < L_FRAME16k; k++ ) { - /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); - /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx_sat( L_shl_sat( L_tmp, NOISE_QADJ ) ); + exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); move16(); - /* exc16kWhtnd: Q_bwe_exc */ } PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - /* i/o: exc16kWhtnd (Q_bwe_exc) */ - /* i/o: tbe_premph (Q_bwe_exc) */ + /* i/o: exc16kWhtnd (Q_exc16kWhtnd) */ + /* i/o: tbe_premph (Q_exc16kWhtnd) */ } ELSE { @@ -4809,11 +4812,10 @@ void GenShapedSHBExcitation_ivas_dec_fx( FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ + L_tmp = L_mult( temp2, White_exc16k[k + j] ); exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); move16(); - /* Q_bwe_exc */ + /* Q_exc16kWhtnd */ } k = add( k, lSubFr ); @@ -4827,19 +4829,18 @@ void GenShapedSHBExcitation_ivas_dec_fx( temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ temp = div_s( temp, temp2 ); /* Q15 */ temp = mult_r( PREEMPH_FAC, temp ); - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); - /* exc16kWhtnd: Q_bwe_exc; - tbe_premph: Q_bwe_exc*/ + /* exc16kWhtnd: Q_exc16kWhtnd; + tbe_premph: Q_exc16kWhtnd*/ } } } + *tbe_premph = shl_sat( *tbe_premph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + move16(); + Scale_sig( White_exc16k, L_FRAME16k, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); -#if 1 // def ADD_IVAS_TBE_CODE IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( LT_32( bitrate, ACELP_24k40 ) ) -#endif { Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); /* i: exc16kWhtnd in Q_bwe_exc */ -- GitLab From 3c7d0686de4aba38980c66de793f0ef358436540 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 28 Mar 2025 13:45:15 +0100 Subject: [PATCH 0700/1221] remove unnecessary moves16(), move32(), keep closer to original code --- lib_enc/speech_music_classif_fx.c | 40 ++++++++++++++----------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index fe0839954..067c5b51b 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -856,8 +856,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { /*mx = PS_norm[i] > st->past_PS[i] ? PS_norm[i] : st->past_PS[i];*/ - mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); - move16(); /*Q25 */ + mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); /*Q25 */ /*ps_sta += mx / (dPS[i] + 1e-5f);*/ IF( !dPS[i] ) @@ -1981,29 +1980,26 @@ Word16 ivas_smc_gmm_fx( move32(); /* [14] ps_sta (spectral stationarity) */ + Word32 ps_sta_fx = 0; + move32(); + Word16 ps_sta_exp = 0; + move16(); + Word32 avoid_divide_by_zero; + avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31 + + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - Word32 ps_sta_fx = 0; - move32(); - Word16 ps_sta_exp = 0; - move16(); - Word32 avoid_divide_by_zero; - avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31 - FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) - { - Word32 tmp_max; - tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + Word32 tmp_max; + tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); - temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp - move32(); - ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); - move32(); - } - temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); - temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ - *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); - move32(); - MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); + temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp + ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } + temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); + temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); + move32(); + MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); /* save ps_diff and ps_sta features for XTALK and UNCLR classifier */ IF( hStereoClassif != NULL ) -- GitLab From 3660990879c1d4c8526770e863e0e30abe6c0aaf Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 28 Mar 2025 19:49:59 +0100 Subject: [PATCH 0701/1221] fix --- lib_dec/fd_cng_dec_fx.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 6579de9fa..b3fbb225e 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1574,15 +1574,25 @@ Word16 ApplyFdCng_ivas_fx( /* This sets the new CNG levels until a SID update overwrites it */ Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it */ /*Q31 - hFdCngDec->bandNoiseShape_exp*/ - Word16 shift1 = L_norm_arr( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); - Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) ); - Word16 shift = s_max( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; + move16(); + } + ELSE +#endif + { + Word16 shift1 = L_norm_arr( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); + Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) ); + Word16 shift = s_max( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); - scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), shift ) ); - scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( sub( *cngNoiseLevel_exp, shift2 ), shift ) ); + scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), shift ) ); + scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( sub( *cngNoiseLevel_exp, shift2 ), shift ) ); - *cngNoiseLevel_exp = shift; - move16(); + *cngNoiseLevel_exp = shift; + move16(); + } /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); -- GitLab From da9e603319c686969d5186d617c804ec80882239 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 13:55:52 -0400 Subject: [PATCH 0702/1221] replace EVS push_indice_fx with push_indice (from IVAS) --- lib_com/bitstream_fx.c | 6 +-- lib_com/gs_gains_fx.c | 28 ++++++------- lib_com/hq_tools_fx.c | 4 +- lib_com/pvq_com_fx.c | 2 +- lib_enc/FEC_enc_fx.c | 6 +-- lib_enc/acelp_core_enc_fx.c | 4 +- lib_enc/acelp_core_switch_enc_fx.c | 8 ++-- lib_enc/amr_wb_enc_fx.c | 2 +- lib_enc/avq_cod_fx.c | 20 +++++----- lib_enc/cng_enc_fx.c | 24 +++++------ lib_enc/cod2t32_fx.c | 6 +-- lib_enc/cod4t64_fx.c | 30 +++++++------- lib_enc/decision_matrix_enc_fx.c | 64 +++++++++++++++--------------- lib_enc/enc_amr_wb_fx.c | 4 +- lib_enc/enc_gen_voic_fx.c | 6 +-- lib_enc/enc_higher_acelp_fx.c | 4 +- lib_enc/enc_pit_exc_fx.c | 6 +-- lib_enc/enc_tran_fx.c | 62 ++++++++++++++--------------- lib_enc/enc_uv_fx.c | 2 +- lib_enc/eval_pit_contr_fx.c | 6 +-- lib_enc/fd_cng_enc_fx.c | 12 +++--- lib_enc/gain_enc_fx.c | 20 +++++----- lib_enc/gaus_enc_fx.c | 6 +-- lib_enc/gs_enc_fx.c | 20 +++++----- lib_enc/hq_classifier_enc_fx.c | 8 ++-- lib_enc/hq_core_enc_fx.c | 8 ++-- lib_enc/hq_env_enc_fx.c | 24 +++++------ lib_enc/hq_hr_enc_fx.c | 4 +- lib_enc/hq_lr_enc_fx.c | 62 ++++++++++++++--------------- lib_enc/hvq_enc_fx.c | 2 +- lib_enc/isf_enc_amr_wb_fx.c | 34 ++++++++-------- lib_enc/lsf_enc_fx.c | 18 ++++----- lib_enc/nelp_enc_fx.c | 8 ++-- lib_enc/peak_vq_enc_fx.c | 36 ++++++++--------- lib_enc/pit_enc_fx.c | 8 ++-- lib_enc/ppp_enc_fx.c | 8 ++-- lib_enc/range_enc_fx.c | 8 ++-- lib_enc/stat_noise_uv_enc_fx.c | 2 +- lib_enc/swb_bwe_enc_fx.c | 46 ++++++++++----------- lib_enc/swb_bwe_enc_hr_fx.c | 22 +++++----- lib_enc/swb_bwe_enc_lr_fx.c | 6 +-- lib_enc/swb_tbe_enc_fx.c | 28 ++++++------- lib_enc/tcq_core_enc_fx.c | 4 +- lib_enc/transition_enc_fx.c | 36 ++++++++--------- lib_enc/voiced_enc_fx.c | 2 +- 45 files changed, 363 insertions(+), 363 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index e144c2cc9..667958264 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -240,11 +240,11 @@ Word16 rate2EVSmode( } /*-------------------------------------------------------------------* - * push_indice_fx( ) + * push_indice( ) * * Push a new indice into the buffer *-------------------------------------------------------------------*/ - +#if 0 void push_indice_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ Word16 id, /* i : ID of the indice */ @@ -288,7 +288,7 @@ void push_indice_fx( return; } - +#endif /*-------------------------------------------------------------------* * push_next_indice_fx() * * Push a new indice into the buffer at the next position diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index 35236b603..ecfe9aae0 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -1028,7 +1028,7 @@ Word16 gsc_gainQ_fx( /*Q12*/ mean_4g[0] = round_fx( L_tmp ); move16(); idx_g = vquant_fx( mean_4g, Gain_meanNB_fx, mean_4g, Gain_mean_dicNB_fx, 1, 64 ); - push_indice_fx( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); + push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); FOR( i = 0; i < Mbands_gn; i++ ) { @@ -1040,21 +1040,21 @@ Word16 gsc_gainQ_fx( /*Q12*/ move16(); set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 ); idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); IF( LT_32( core_brate, ACELP_9k60 ) ) { idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); } ELSE { idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 7 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 ); } /*add end */ test(); @@ -1122,7 +1122,7 @@ Word16 gsc_gainQ_fx( /*Q12*/ move16(); idx_g = vquant_fx( mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64 ); - push_indice_fx( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); + push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); FOR( i = 0; i < Mbands_gn; i++ ) { @@ -1148,11 +1148,11 @@ Word16 gsc_gainQ_fx( /*Q12*/ move16(); idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 ); /* Update to quantized vector */ @@ -1185,13 +1185,13 @@ Word16 gsc_gainQ_fx( /*Q12*/ ELSE { idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); } } diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index cf3ce202e..0e00b9428 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -2036,7 +2036,7 @@ Word16 calc_nor_delta_hf_fx( /* updating norm & storing delta norm */ add_bits_denv = 2; move16(); - push_indice_fx( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 ); + push_indice( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 ); FOR( i = num_env_bands; i < nb_sfm; ++i ) { IF( Rsubband[i] != 0 ) @@ -2052,7 +2052,7 @@ Word16 calc_nor_delta_hf_fx( delta = min_delta; /*Q0*/ move16(); } - push_indice_fx( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta ); + push_indice( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta ); ynrm[i] = add( ynrm[i], delta ); /*Q0*/ move16(); add_bits_denv = add( add_bits_denv, bitsforDelta ); diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index 479bc04d9..9cf1226d8 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -622,7 +622,7 @@ void fine_gain_quant_fx( gain_db = round_fx_sat( L_shl_o( L_tmp, 17, &Overflow ) ); idx = squant_fx( gain_db, &gain_dbq, finegain_fx[gbits - 1], gain_cb_size[gbits - 1] ); - push_indice_fx( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); + push_indice( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); L_tmp = L_mult0( gain_dbq, 21771 ); /* 21771=0.05*log2(10) */ /* 14+17=31 */ L_tmp = L_shr( L_tmp, 15 ); /* Q16 */ diff --git a/lib_enc/FEC_enc_fx.c b/lib_enc/FEC_enc_fx.c index 87243e8d2..69b14eb9b 100644 --- a/lib_enc/FEC_enc_fx.c +++ b/lib_enc/FEC_enc_fx.c @@ -94,7 +94,7 @@ void FEC_encode_fx( index = 3; move16(); } - push_indice_fx( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); + push_indice( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); } /*-----------------------------------------------------------------* @@ -117,7 +117,7 @@ void FEC_encode_fx( tmpS = s_min( tmpS, 31 ); tmpS = s_max( tmpS, 0 ); - push_indice_fx( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); + push_indice( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); } /*-----------------------------------------------------------------* * Encode last glottal pulse position (8 bits) @@ -157,7 +157,7 @@ void FEC_encode_fx( maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) Q0*/ } - push_indice_fx( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); + push_indice( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); } maxi = 0; move16(); diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index f9f941dbd..795f03403 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -472,7 +472,7 @@ ivas_error acelp_core_enc_fx( IF( nb_bits > 0 ) { Es_pred_enc_fx( &Es_pred_fx, &indice, st_fx->L_frame, res_fx, st_fx->voicing_fx, nb_bits, 0, Q_new ); - push_indice_fx( st_fx->hBstr, IND_ES_PRED, indice, nb_bits ); + push_indice( st_fx->hBstr, IND_ES_PRED, indice, nb_bits ); } @@ -619,7 +619,7 @@ ivas_error acelp_core_enc_fx( WHILE( nBits > 0 ) { i = s_min( nBits, 16 ); // Q0 - push_indice_fx( st_fx->hBstr, IND_UNUSED, 0, i ); + push_indice( st_fx->hBstr, IND_UNUSED, 0, i ); nBits = sub( nBits, i ); // Q0 } } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index f9058b9b9..9b0ed8b58 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -441,7 +441,7 @@ static void encod_gen_voic_core_switch_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*-----------------------------------------------------------------* @@ -489,7 +489,7 @@ static void encod_gen_voic_core_switch_fx( /* write reserved bits */ IF( unbits ) { - push_indice_fx( hBstr, IND_UNUSED, 0, unbits ); + push_indice( hBstr, IND_UNUSED, 0, unbits ); } /*-----------------------------------------------------------------* @@ -838,7 +838,7 @@ static void bwe_switch_enc_fx( } } - push_indice_fx( hBstr, IND_CORE_SWITCHING_AUDIO_DELAY, d1m_fx, AUDIODELAYBITS ); + push_indice( hBstr, IND_CORE_SWITCHING_AUDIO_DELAY, d1m_fx, AUDIODELAYBITS ); tmp = add( i_mult2( d1m_fx, delta_fx ), fdelay_fx ); /* Q0 */ ptmp = &hb_synth_tmp_fx[tmp]; /* Q0 */ @@ -867,7 +867,7 @@ static void bwe_switch_enc_fx( L_tmp1 = L_shl( L_tmp1, sub( q_tmp2, 24 ) ); gain_fx = round_fx_o( Isqrt( L_tmp1 ), &Overflow ); /*Q12 */ ind1_fx = usquant_fx( gain_fx, &gain_fx, shr( MINVALUEOFFIRSTGAIN_FX, 1 ), shr( DELTAOFFIRSTGAIN_FX, 4 ), ( 1 << NOOFGAINBITS1 ) ); /* Q0 */ - push_indice_fx( hBstr, IND_CORE_SWITCHING_AUDIO_GAIN, ind1_fx, NOOFGAINBITS1 ); + push_indice( hBstr, IND_CORE_SWITCHING_AUDIO_GAIN, ind1_fx, NOOFGAINBITS1 ); return; } diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index b1b2257e2..6f46e5c12 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -548,7 +548,7 @@ void amr_wb_enc_fx( * Write VAD information into the bitstream in AMR-WB IO mode *--------------------------------------------------------------------------------------*/ - push_indice_fx( st->hBstr, IND_VAD_FLAG, st->vad_flag, 1 ); + push_indice( st->hBstr, IND_VAD_FLAG, st->vad_flag, 1 ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 962b715cd..b3a49c59e 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -384,20 +384,20 @@ void AVQ_encmux_fx( /* write the unary code */ FOR( ; j > 16; j -= 16 ) { - push_indice_fx( hBstr, nq_ind, 65535, 16 ); + push_indice( hBstr, nq_ind, 65535, 16 ); bits = sub( bits, 16 ); } IF( j > 0 ) { - push_indice_fx( hBstr, nq_ind, extract_l( L_sub( L_shl( 1L, j ), 1L ) ), j ); + push_indice( hBstr, nq_ind, extract_l( L_sub( L_shl( 1L, j ), 1L ) ), j ); bits = sub( bits, j ); } } IF( !overflow ) { /* write the stop bit */ - push_indice_fx( hBstr, nq_ind, 0, 1 ); + push_indice( hBstr, nq_ind, 0, 1 ); bits = sub( bits, 1 ); } @@ -506,13 +506,13 @@ void AVQ_encmux_fx( IF( j > 0 ) { /* write the unary code */ - push_indice_fx( hBstr, nq_ind, sub( shl( 1, j ), 1 ), j ); + push_indice( hBstr, nq_ind, sub( shl( 1, j ), 1 ), j ); } IF( nq[i] != 0 ) { /* write the stop bit */ - push_indice_fx( hBstr, nq_ind, 0, 1 ); + push_indice( hBstr, nq_ind, 0, 1 ); } /*Compute AVQ code book number from unused Bits */ @@ -1099,32 +1099,32 @@ static void wrte_cv( ELSE IF( LT_16( nq, 5 ) ) /* Q2, Q3, Q4 */ { nq4 = shl( nq, 2 ); - push_indice_fx( hBstr, i_ind, I, nq4 ); + push_indice( hBstr, i_ind, I, nq4 ); bits = sub( bits, nq4 ); } ELSE IF( EQ_16( s_and( nq, 1 ), 0 ) ) /* Q4 + Voronoi extensions r=1,2,3,... */ { - push_indice_fx( hBstr, i_ind, I, 4 * 4 ); + push_indice( hBstr, i_ind, I, 4 * 4 ); bits = sub( bits, 4 * 4 ); /*pos = (int16_t)(nq / 2 - 2);*/ /* Voronoi order determination */ pos = sub( shr( nq, 1 ), 2 ); FOR( j = 0; j < 8; j++ ) { - push_indice_fx( hBstr, kv_ind, kv[j], pos ); + push_indice( hBstr, kv_ind, kv[j], pos ); } bits = sub( bits, shl( pos, 3 ) ); } ELSE /* Q3 + Voronoi extensions r=1,2,3,... */ { - push_indice_fx( hBstr, i_ind, I, 4 * 3 ); + push_indice( hBstr, i_ind, I, 4 * 3 ); bits = sub( bits, 4 * 3 ); /*pos = (int16_t)(nq / 2 - 1);*/ /* Voronoi order determination */ pos = sub( shr( nq, 1 ), 1 ); FOR( j = 0; j < 8; j++ ) { - push_indice_fx( hBstr, kv_ind, kv[j], pos ); + push_indice( hBstr, kv_ind, kv[j], pos ); } bits = sub( bits, shl( pos, 3 ) ); diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index e2b29ba59..221454970 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -975,7 +975,7 @@ void CNG_enc_fx( hTdCngEnc->old_enr_index = enr_index; move16(); - push_indice_fx( hBstr, IND_ENERGY, enr_index, num_bits ); + push_indice( hBstr, IND_ENERGY, enr_index, num_bits ); if ( enr_index == 0 ) { enr_index = -5; @@ -1063,7 +1063,7 @@ void CNG_enc_fx( move16(); } } - push_indice_fx( hBstr, IND_CNG_ENV1, min1_idx, 6 ); + push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 ); /* get quantized res_env_details */ FOR( i = 0; i < NUM_ENV_CNG; i++ ) { @@ -1122,28 +1122,28 @@ void CNG_enc_fx( /* dithering bit for AMR-WB IO mode is always set to 0 */ IF( EQ_32( st_fx->core_brate, SID_1k75 ) ) { - push_indice_fx( hBstr, IND_DITHERING, 0, 1 ); + push_indice( hBstr, IND_DITHERING, 0, 1 ); } IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 1, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 ); } ELSE { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 0, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 ); } - push_indice_fx( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, 7 ), 3 ); + push_indice( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, 7 ), 3 ); hTdCngEnc->num_ho = m; move16(); - push_indice_fx( hBstr, IND_SID_TYPE, 0, 1 ); + push_indice( hBstr, IND_SID_TYPE, 0, 1 ); test(); IF( LT_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - push_indice_fx( hBstr, IND_SID_BW, 0, 1 ); + push_indice( hBstr, IND_SID_BW, 0, 1 ); *sid_bw = 0; move16(); } @@ -2458,8 +2458,8 @@ static void shb_CNG_encod_fx( idx_ener_fx = s_max( idx_ener_fx, 0 ); } - push_indice_fx( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); - push_indice_fx( hBstr, IND_SID_BW, 1, 1 ); + push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); + push_indice( hBstr, IND_SID_BW, 1, 1 ); hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; move16(); @@ -2470,7 +2470,7 @@ static void shb_CNG_encod_fx( } else { - push_indice_fx( hBstr, IND_UNUSED, 0, 2 ); + push_indice( hBstr, IND_UNUSED, 0, 2 ); } hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); hTdCngEnc->ho_sid_bw = L_or( hTdCngEnc->ho_sid_bw, 0x1L ); @@ -2482,7 +2482,7 @@ static void shb_CNG_encod_fx( IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - push_indice_fx( hBstr, IND_SID_BW, 0, 1 ); + push_indice( hBstr, IND_SID_BW, 0, 1 ); } } diff --git a/lib_enc/cod2t32_fx.c b/lib_enc/cod2t32_fx.c index a948a4656..dc967e656 100644 --- a/lib_enc/cod2t32_fx.c +++ b/lib_enc/cod2t32_fx.c @@ -292,7 +292,7 @@ void acelp_2t32_fx( } { /* write index to array of indices */ - push_indice_fx( hBstr, IND_ALG_CDBK_2T32, index, 12 ); + push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 ); } return; } @@ -636,11 +636,11 @@ void acelp_1t64_fx( } IF( EQ_16( L_subfr, L_SUBFR ) ) { - push_indice_fx( hBstr, IND_ALG_CDBK_1T64, index, 7 ); + push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 ); } ELSE /* L_subfr == 2*L_SUBFR */ { - push_indice_fx( hBstr, IND_ALG_CDBK_1T64, index, 8 ); + push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 ); } return; diff --git a/lib_enc/cod4t64_fx.c b/lib_enc/cod4t64_fx.c index 99b794b42..457a129b8 100644 --- a/lib_enc/cod4t64_fx.c +++ b/lib_enc/cod4t64_fx.c @@ -330,11 +330,11 @@ Word16 acelp_4t64_fx( bitcnt = s_and( nbbits, 15 ); FOR( i = 0; i < wordcnt; i++ ) { - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], 16 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], 16 ); } IF( bitcnt ) { - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], bitcnt ); + push_indice( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], bitcnt ); } } ELSE @@ -347,7 +347,7 @@ Word16 acelp_4t64_fx( { k = i_mult2( track, NPMAXPT ); index = quant_1p_N1_fx( ind[k], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 5 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 5 ); } } ELSE IF( EQ_16( nbbits, 36 ) ) @@ -357,7 +357,7 @@ Word16 acelp_4t64_fx( k = i_mult2( track, NPMAXPT ); /* k = track * NPMAXPT;*/ index = quant_2p_2N1_fx( ind[k], ind[k + 1], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 9 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 9 ); } } ELSE IF( EQ_16( nbbits, 44 ) ) /* AMR-WB pulse indexing */ @@ -366,14 +366,14 @@ Word16 acelp_4t64_fx( { k = i_mult2( track, NPMAXPT ); index = quant_3p_3N1_fx( ind[k], ind[k + 1], ind[k + 2], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 13 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 13 ); } FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) { k = i_mult2( track, NPMAXPT ); index = quant_2p_2N1_fx( ind[k], ind[k + 1], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 9 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 9 ); } } ELSE IF( EQ_16( nbbits, 52 ) ) /* AMR-WB pulse indexing */ @@ -382,7 +382,7 @@ Word16 acelp_4t64_fx( { k = i_mult2( track, NPMAXPT ); index = quant_3p_3N1_fx( ind[k], ind[k + 1], ind[k + 2], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 13 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 13 ); } } ELSE IF( EQ_16( nbbits, 64 ) ) /* AMR-WB pulse indexing */ @@ -393,7 +393,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 14 ) & 3 ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); } FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) @@ -402,7 +402,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_index & 0x3FFF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); } } ELSE IF( EQ_16( nbbits, 72 ) ) @@ -413,7 +413,7 @@ Word16 acelp_4t64_fx( L_index = quant_5p_5N_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 10 ) & 0x03FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 10 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 10 ); } FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) @@ -422,7 +422,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 14 ) & 3 ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); } FOR( track = 0; track < ( NB_TRACK_FCB_4T - 2 ); track++ ) @@ -431,7 +431,7 @@ Word16 acelp_4t64_fx( L_index = quant_5p_5N_fx( &ind[k], 4 ); index = extract_l( L_index & 0x03FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 10 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 10 ); } FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) @@ -440,7 +440,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_index & 0x3FFF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); } } ELSE IF( EQ_16( nbbits, 88 ) ) @@ -451,7 +451,7 @@ Word16 acelp_4t64_fx( L_index = quant_6p_6N_2_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 11 ) & 0x07FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 11 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 11 ); } FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) @@ -460,7 +460,7 @@ Word16 acelp_4t64_fx( L_index = quant_6p_6N_2_fx( &ind[k], 4 ); index = extract_l( L_index & 0x07FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 11 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 11 ); } } } diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index c95bc9d5b..63a13aa1a 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -449,14 +449,14 @@ Word16 signalling_mode1_tcx20_enc_fx( num_bits = add( num_bits, nBits ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_ACELP_SIGNALLING, sub( idx, start_idx ), nBits ); + push_indice( hBstr, IND_ACELP_SIGNALLING, sub( idx, start_idx ), nBits ); } /* HQ/TCX core switching flag */ num_bits = add( num_bits, 1 ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_MDCT_CORE, 1, 1 ); + push_indice( hBstr, IND_MDCT_CORE, 1, 1 ); } } ELSE @@ -467,7 +467,7 @@ Word16 signalling_mode1_tcx20_enc_fx( num_bits = add( num_bits, 1 ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_CORE, 1, 1 ); + push_indice( hBstr, IND_CORE, 1, 1 ); } } @@ -475,7 +475,7 @@ Word16 signalling_mode1_tcx20_enc_fx( num_bits = add( num_bits, 1 ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_MDCT_CORE, 1, 1 ); + push_indice( hBstr, IND_MDCT_CORE, 1, 1 ); } num_bits = add( num_bits, 2 ); @@ -484,19 +484,19 @@ Word16 signalling_mode1_tcx20_enc_fx( /* write band-width (needed for different I/O sampling rate support) */ IF( EQ_16( st->bwidth, NB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 0, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 0, 2 ); } ELSE IF( EQ_16( st->bwidth, WB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 1, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 1, 2 ); } ELSE IF( EQ_16( st->bwidth, SWB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 2, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 2, 2 ); } ELSE /* st->bwidth == FB */ { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 3, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 3, 2 ); } } } @@ -534,21 +534,21 @@ void signalling_enc_fx( test(); IF( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); /* write ACELP L_frame info */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 0, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 0, 1 ); } ELSE { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 1, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 1, 1 ); } } ELSE { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); } return; @@ -574,7 +574,7 @@ void signalling_enc_fx( IF( EQ_16( ppp_mode, 1 ) || EQ_16( nelp_mode, 1 ) ) { /* 1 bit to distinguish between 2.8kbps PPP/NELP frame and SID frame */ - push_indice_fx( hBstr, IND_CORE, 0, 1 ); + push_indice( hBstr, IND_CORE, 0, 1 ); /* SC-VBR: 0 - PPP_NB, 1 - PPP_WB, 2 - NELP_NB, 3 - NELP_WB */ test(); test(); @@ -586,19 +586,19 @@ void signalling_enc_fx( test(); IF( EQ_16( st_fx->coder_type, VOICED ) && EQ_16( st_fx->bwidth, NB ) && EQ_16( ppp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 0, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 0, 2 ); } ELSE IF( EQ_16( st_fx->coder_type, VOICED ) && NE_16( st_fx->bwidth, NB ) && EQ_16( ppp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 1, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 1, 2 ); } ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) && EQ_16( st_fx->bwidth, NB ) && EQ_16( nelp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 2, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 2, 2 ); } ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) && NE_16( st_fx->bwidth, NB ) && EQ_16( nelp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 3, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 3, 2 ); } } ELSE IF( NE_32( st_fx->core_brate, SID_2k40 ) && ( st_fx->core_brate != FRAME_NO_DATA ) ) @@ -606,7 +606,7 @@ void signalling_enc_fx( /* write the ACELP/HQ core selection bit */ IF( GE_32( st_fx->total_brate, ACELP_24k40 ) ) { - push_indice_fx( hBstr, IND_CORE, 0, 1 ); + push_indice( hBstr, IND_CORE, 0, 1 ); } /* find the section in the ACELP signalling table corresponding to bitrate */ @@ -652,7 +652,7 @@ void signalling_enc_fx( idx++; } - push_indice_fx( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); + push_indice( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); } /* write extension layer flag to distinguish between TBE (0) and BWE (1) */ @@ -664,11 +664,11 @@ void signalling_enc_fx( test(); IF( EQ_16( st_fx->extl, WB_TBE ) || EQ_16( st_fx->extl, SWB_TBE ) || EQ_16( st_fx->extl, FB_TBE ) ) { - push_indice_fx( hBstr, IND_BWE_FLAG, 0, 1 ); + push_indice( hBstr, IND_BWE_FLAG, 0, 1 ); } ELSE IF( EQ_16( st_fx->extl, WB_BWE ) || EQ_16( st_fx->extl, SWB_BWE ) || EQ_16( st_fx->extl, FB_BWE ) ) { - push_indice_fx( hBstr, IND_BWE_FLAG, 1, 1 ); + push_indice( hBstr, IND_BWE_FLAG, 1, 1 ); } } } @@ -678,24 +678,24 @@ void signalling_enc_fx( test(); IF( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); /* write ACELP L_frame info */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 0, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 0, 1 ); } ELSE { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 1, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 1, 1 ); } } ELSE { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); } /* HQ/TCX core switching flag */ - push_indice_fx( hBstr, IND_MDCT_CORE, 0, 1 ); + push_indice( hBstr, IND_MDCT_CORE, 0, 1 ); /* Use ACELP signaling for LR MDCT */ IF( LE_32( st_fx->total_brate, ACELP_16k40 ) ) @@ -719,7 +719,7 @@ void signalling_enc_fx( idx++; } - push_indice_fx( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); + push_indice( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); } ELSE { @@ -727,25 +727,25 @@ void signalling_enc_fx( IF( LE_32( st_fx->core_brate, ACELP_64k ) ) { /* write ACELP/HQ core indication flag */ - push_indice_fx( hBstr, IND_CORE, 1, 1 ); + push_indice( hBstr, IND_CORE, 1, 1 ); } /* write band-width (needed for different I/O sampling rate support) */ IF( EQ_16( st_fx->bwidth, NB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 0, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 0, 2 ); } ELSE IF( EQ_16( st_fx->bwidth, WB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 1, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 1, 2 ); } ELSE IF( EQ_16( st_fx->bwidth, SWB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 2, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 2, 2 ); } ELSE /* st_fx->bwidth == FB */ { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 3, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 3, 2 ); } } } diff --git a/lib_enc/enc_amr_wb_fx.c b/lib_enc/enc_amr_wb_fx.c index 08a20bbb9..4c5268017 100644 --- a/lib_enc/enc_amr_wb_fx.c +++ b/lib_enc/enc_amr_wb_fx.c @@ -170,7 +170,7 @@ void encod_amr_wb_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*-----------------------------------------------------------------* @@ -243,7 +243,7 @@ void encod_amr_wb_fx( hVAD->hangover_cnt, &hAmrwb_IO->gain_alpha_fx, &hf_gain_fx[i_subfr / L_SUBFR], add( Q_new, 1 ), st->Q_syn ); } - push_indice_fx( hBstr, IND_HF_GAIN_MODIFICATION, hf_gain_fx[i_subfr / L_SUBFR], 4 ); + push_indice( hBstr, IND_HF_GAIN_MODIFICATION, hf_gain_fx[i_subfr / L_SUBFR], 4 ); } p_Aw += ( M + 1 ); diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 62f740fb2..00c7d28d7 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -179,7 +179,7 @@ void encod_gen_voic_fx( move16(); } - push_indice_fx( hBstr, IND_HARM_FLAG_ACELP, harm_flag_acelp, 1 ); + push_indice( hBstr, IND_HARM_FLAG_ACELP, harm_flag_acelp, 1 ); } /*------------------------------------------------------------------* @@ -239,7 +239,7 @@ void encod_gen_voic_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit_fx;*/ @@ -387,7 +387,7 @@ void encod_gen_voic_fx( WHILE( unbits_PI_fx > 0 ) { i = s_min( unbits_PI_fx, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); unbits_PI_fx -= i; } IF( st_fx->Opt_SC_VBR ) diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index 64a11be5b..bf248bb5a 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -242,7 +242,7 @@ void transf_cdbk_enc_fx( Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/ *gain_preQ = round_fx( Ltmp ); /* Q2*/ } - push_indice_fx( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS ); + push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS ); /*--------------------------------------------------------------* * Encode and multiplex subvectors into bit-stream @@ -276,7 +276,7 @@ void transf_cdbk_enc_fx( WHILE( *unbits > 0 ) { i = s_min( *unbits, 16 ); - push_indice_fx( st_fx->hBstr, IND_UNUSED, 0, i ); + push_indice( st_fx->hBstr, IND_UNUSED, 0, i ); *unbits -= i; } } diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 957e41516..3cb2cc066 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -291,7 +291,7 @@ void enc_pit_exc_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit;*/ @@ -312,12 +312,12 @@ void enc_pit_exc_fx( IF( GE_32( st_fx->core_brate, MIN_RATE_FCB ) ) { pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 32 ); /* Q0 */ - push_indice_fx( hBstr, IND_PIT_IDX, pit_idx, 5 ); + push_indice( hBstr, IND_PIT_IDX, pit_idx, 5 ); } ELSE { pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 16 ); /* Q0 */ - push_indice_fx( hBstr, IND_PIT_IDX, pit_idx, 4 ); + push_indice( hBstr, IND_PIT_IDX, pit_idx, 4 ); } } else if ( use_fcb == 2 ) diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 4cda393d5..d6935dd0c 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -327,7 +327,7 @@ Word16 encod_tran_fx( WHILE( unbits_PI > 0 ) { i = s_min( unbits_PI, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); unbits_PI -= i; } @@ -336,72 +336,72 @@ Word16 encod_tran_fx( { IF( EQ_16( tc_subfr, TC_0_0 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, TC_0_64 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, TC_0_128 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); } ELSE IF( EQ_16( tc_subfr, TC_0_192 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); } } ELSE /* L_frame == L_FRAME16k */ { IF( tc_subfr == 0 ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 2 ); } ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 2 ); } ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 2, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 2, 2 ); } ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 3, 2 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 3, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); } ELSE IF( EQ_16( tc_subfr, 4 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 3, 2 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 3, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } } diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 8a77b9e2b..a8612725b 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -153,7 +153,7 @@ void encod_unvoiced_fx( #ifdef DEBUGGING assert( st_fx->acelp_cfg.gains_mode[i_subfr_idx] == 7 && "Error: UC two-stage, only 5+2 gain Q is supported" ); #endif - push_indice_fx( st_fx->hBstr, IND_GAIN, index, st_fx->acelp_cfg.gains_mode[i_subfr_idx] ); + push_indice( st_fx->hBstr, IND_GAIN, index, st_fx->acelp_cfg.gains_mode[i_subfr_idx] ); gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index aef5fd637..df629f295 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -409,17 +409,17 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit IF( EQ_16( st_fx->coder_type, INACTIVE ) ) { - push_indice_fx( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 1 ); + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 1 ); } } ELSE { - push_indice_fx( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 3 ); + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 3 ); } } ELSE { - push_indice_fx( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 4 ); + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 4 ); } return last_pit_bin; diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index e51e2b682..2eb13646c 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1217,21 +1217,21 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru } ELSE { - push_indice_fx( hBstr, IND_SID_TYPE, 1, 1 ); - push_indice_fx( hBstr, IND_ACELP_16KHZ, corest->bwidth, 2 ); + push_indice( hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, corest->bwidth, 2 ); IF( EQ_16( corest->L_frame, L_FRAME16k ) ) { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 1, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 ); } ELSE { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 0, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 ); } FOR( i = 0; i < stages_37bits; i++ ) { - push_indice_fx( hBstr, IND_LSF, indices[i], bits_37bits[i] ); + push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); } - push_indice_fx( hBstr, IND_ENERGY, index, 7 ); + push_indice( hBstr, IND_ENERGY, index, 7 ); } /* Interpolate the bin/band-wise levels from the partition levels */ diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 0321cd763..0ccb31ccf 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -428,7 +428,7 @@ void gain_enc_mless_fx( tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */ index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) ); move16(); - push_indice_fx( hBstr, IND_GAIN_PIT, index, nBits ); + push_indice( hBstr, IND_GAIN_PIT, index, nBits ); /* gain_code Q */ /**gain_code /= gcode0;*/ @@ -441,7 +441,7 @@ void gain_enc_mless_fx( } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg ); - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits2 ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits2 ); L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/ } @@ -508,7 +508,7 @@ void gain_enc_mless_fx( * search for the best quantizer *-----------------------------------------------------------------*/ index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0 - push_indice_fx( hBstr, IND_GAIN, index, nBits ); + push_indice( hBstr, IND_GAIN, index, nBits ); } /* *norm_gain_code = *gain_code / *gain_inov; */ @@ -1108,7 +1108,7 @@ void gain_enc_SQ_fx( tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */ index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0 - push_indice_fx( hBstr, IND_GAIN_PIT, index, nBits_pitch ); + push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch ); /* gain_code Q */ /* *gain_code /= gcode0; */ @@ -1121,7 +1121,7 @@ void gain_enc_SQ_fx( } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg ); - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits_code ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits_code ); L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); move32(); /*Q16*/ @@ -1601,7 +1601,7 @@ void gain_enc_tc_fx( *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ move32(); - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } ELSE { @@ -1632,7 +1632,7 @@ void gain_enc_tc_fx( L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); move32(); /* Q14 -> Q16 */ - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } ELSE /* nBits == 3 */ { @@ -1642,7 +1642,7 @@ void gain_enc_tc_fx( L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); move32(); /* Q14 -> Q16 */ - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } } @@ -2438,7 +2438,7 @@ void gain_enc_lbr_fx( *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); { - push_indice_fx( hBstr, IND_GAIN, index, nBits ); + push_indice( hBstr, IND_GAIN, index, nBits ); } return; } @@ -3223,7 +3223,7 @@ void gain_enc_amr_wb_fx( *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); - push_indice_fx( hBstr, IND_GAIN, index, nBits ); + push_indice( hBstr, IND_GAIN, index, nBits ); return; } diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index edddc6a88..081cf7ef0 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -96,7 +96,7 @@ Word16 gaus_encode_fx( move16(); /* low bound = -30; stepSize = 1.71875; inv_stepSize = 0.5818181 */ idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); /* Q0 */ - push_indice_fx( st_fx->hBstr, IND_GAIN, idx, nb_bits ); + push_indice( st_fx->hBstr, IND_GAIN, idx, nb_bits ); /*----------------------------------------------------------------* * Total excitation for Unvoiced coders @@ -638,8 +638,8 @@ void gauss2v_fx( idx = cod_2pos_fx( i, j, sign1, sign2, nvec ); /* Q0 */ move16(); - push_indice_fx( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); - push_indice_fx( hBstr, IND_TILT_FACTOR, index_delta, 3 ); + push_indice( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); + push_indice( hBstr, IND_TILT_FACTOR, index_delta, 3 ); /*----------------------------------------------------------------* * Find quantized gain diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 1642d1253..1a3d2cb56 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -82,16 +82,16 @@ void encod_audio_fx( test(); IF( ( st_fx->element_mode > EVS_MONO ) && st_fx->idchan == 0 ) { - push_indice_fx( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); + push_indice( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); } #endif IF( attack_flag > 0 ) { - push_indice_fx( hBstr, IND_GSC_ATTACK, 1, 1 ); + push_indice( hBstr, IND_GSC_ATTACK, 1, 1 ); } ELSE { - push_indice_fx( hBstr, IND_GSC_ATTACK, 0, 1 ); + push_indice( hBstr, IND_GSC_ATTACK, 0, 1 ); } @@ -105,7 +105,7 @@ void encod_audio_fx( IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( NE_16( st_fx->coder_type, INACTIVE ) && ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && GE_32( st_fx->total_brate, ACELP_13k20 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && GT_32( st_fx->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) && GE_16( st_fx->bwidth, SWB ) && !st_fx->flag_ACELP16k ) ) ) ) { - push_indice_fx( hBstr, IND_GSC_SWB_SPEECH, st_fx->GSC_noisy_speech, 1 ); + push_indice( hBstr, IND_GSC_SWB_SPEECH, st_fx->GSC_noisy_speech, 1 ); } /*---------------------------------------------------------------* * Find and encode the number of subframes @@ -185,12 +185,12 @@ void encod_audio_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { - push_indice_fx( hBstr, IND_HF_NOISE, nb_subfr_flag, 2 ); + push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 2 ); } ELSE IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) { /* nb_subfr_flag can only have the value 0 or 1 */ - push_indice_fx( hBstr, IND_HF_NOISE, nb_subfr_flag, 1 ); + push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 1 ); } } test(); @@ -227,7 +227,7 @@ void encod_audio_fx( move16(); } Es_pred_enc_fx( &Es_pred, &indice, st_fx->L_frame, res, st_fx->voicing_fx, nb_bits, 0, Q_new ); - push_indice_fx( hBstr, IND_ES_PRED, indice, nb_bits ); + push_indice( hBstr, IND_ES_PRED, indice, nb_bits ); } enc_pit_exc_fx( st_fx, speech, Aw, Aq, Es_pred, res, synth, exc, &T0_tmp, @@ -290,7 +290,7 @@ void encod_audio_fx( { hGSCEnc->noise_lev = s_max( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ); move16(); - push_indice_fx( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ), 2 ); + push_indice( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ), 2 ); } ELSE IF( st_fx->GSC_noisy_speech ) { @@ -300,7 +300,7 @@ void encod_audio_fx( } ELSE { - push_indice_fx( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP0 ), 3 ); + push_indice( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP0 ), 3 ); } /*---------------------------------------------------------------* @@ -931,7 +931,7 @@ void gsc_enc_fx( WHILE( bit > 0 ) { i = s_min( bit, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); bit = sub( bit, i ); } /* Reorder Q bands */ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 2b53082f7..300e31e8e 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -258,16 +258,16 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits { IF( GE_16( *hqswb_clas, HQ_GEN_SWB ) ) { - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas - 5, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas - 5, bits ); } ELSE { - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); } } ELSE { - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); } test(); @@ -343,7 +343,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits move16(); } /* write signalling info to the bitstream */ - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) ) { diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index ff19cfebc..66430cb8e 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -229,12 +229,12 @@ void hq_core_enc_fx( { IF( Voicing_flag > 0 ) { - push_indice_fx( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); + push_indice( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); num_bits = sub( num_bits, 1 ); } ELSE { - push_indice_fx( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); + push_indice( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); num_bits = sub( num_bits, 1 ); } } @@ -278,13 +278,13 @@ void hq_core_enc_fx( WHILE( num_bits >= 16 ) { - push_indice_fx( hBstr, IND_UNUSED, 0, 16 ); + push_indice( hBstr, IND_UNUSED, 0, 16 ); num_bits = sub( num_bits, 16 ); } IF( num_bits != 0 ) { - push_indice_fx( hBstr, IND_UNUSED, 0, num_bits ); + push_indice( hBstr, IND_UNUSED, 0, num_bits ); } #ifdef ADD_IVAS_HQ_CODE if ( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) diff --git a/lib_enc/hq_env_enc_fx.c b/lib_enc/hq_env_enc_fx.c index 5d47710ed..f033bd685 100644 --- a/lib_enc/hq_env_enc_fx.c +++ b/lib_enc/hq_env_enc_fx.c @@ -295,13 +295,13 @@ Word16 encode_envelope_indices_fx( /* o : Number of b test(); IF( EQ_16( flag_HQ2, LOW_RATE_HQ_CORE_TRAN ) || EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_HMODE, *LCmode, BITS_DE_HMODE ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, difidx[0], BITS_DE_FCOMP ); + push_indice( hBstr, IND_HQ2_DENG_HMODE, *LCmode, BITS_DE_HMODE ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, difidx[0], BITS_DE_FCOMP ); } ELSE { - push_indice_fx( hBstr, IND_LC_MODE, *LCmode, 2 ); - push_indice_fx( hBstr, IND_YNRM, difidx[0], NORM0_BITS ); + push_indice( hBstr, IND_LC_MODE, *LCmode, 2 ); + push_indice( hBstr, IND_YNRM, difidx[0], NORM0_BITS ); } test(); @@ -331,7 +331,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b m = lshr( m, 1 ); /* Q0 */ } - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); } } ELSE @@ -370,7 +370,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b move16(); } } - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); prevj = j; move16(); } @@ -419,11 +419,11 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); } ELSE { - push_indice_fx( hBstr, IND_YNRM, m, r ); + push_indice( hBstr, IND_YNRM, m, r ); } prevj = j; @@ -515,11 +515,11 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( flag_HQ2 == 0 ) { - push_indice_fx( hBstr, IND_YNRM, v, r ); + push_indice( hBstr, IND_YNRM, v, r ); } ELSE { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); } } } @@ -536,14 +536,14 @@ Word16 encode_envelope_indices_fx( /* o : Number of b r = huffsizn[j]; /* Q0 */ move16(); - push_indice_fx( hBstr, IND_YNRM, m, r ); + push_indice( hBstr, IND_YNRM, m, r ); } } ELSE { FOR( i = 1; i < num_sfm; i++ ) { - push_indice_fx( hBstr, IND_YNRM, difidx[i], NORMI_BITS ); + push_indice( hBstr, IND_YNRM, difidx[i], NORMI_BITS ); } } } diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index 1cd516b43..705db9ecd 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -236,12 +236,12 @@ void hq_hr_enc_fx( IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) { nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); /* Q0 */ - push_indice_fx( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); + push_indice( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); } ELSE { nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); /* Q0 */ - push_indice_fx( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); + push_indice( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); } } /* updates */ diff --git a/lib_enc/hq_lr_enc_fx.c b/lib_enc/hq_lr_enc_fx.c index 9aca0f646..af2780682 100644 --- a/lib_enc/hq_lr_enc_fx.c +++ b/lib_enc/hq_lr_enc_fx.c @@ -115,7 +115,7 @@ static void spt_shorten_domain_set_fx( move16(); } } - push_indice_fx( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); + push_indice( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); *bit_budget = sub( *bit_budget, 1 ); /* Q0 */ move16(); } @@ -313,7 +313,7 @@ void hq_lr_enc_fx( } /* write the classification information into the bitstream */ - push_indice_fx( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas_fx, 2 ); + push_indice( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas_fx, 2 ); ( *num_bits_fx ) = sub( *num_bits_fx, 2 ); move16(); IF( EQ_16( hqswb_clas_fx, HQ_NORMAL ) ) @@ -325,7 +325,7 @@ void hq_lr_enc_fx( ELSE { /* write the transient bit into the bitstream */ - push_indice_fx( st_fx->hBstr, IND_HQ2_SWB_CLAS, is_transient_fx, 1 ); + push_indice( st_fx->hBstr, IND_HQ2_SWB_CLAS, is_transient_fx, 1 ); /* subtract one bit for the transient flag */ ( *num_bits_fx ) = sub( ( *num_bits_fx ), 1 ); @@ -741,7 +741,7 @@ void hq_lr_enc_fx( /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ FOR( i = 0; i < 2; i++ ) { - push_indice_fx( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); + push_indice( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); } } ELSE IF( is_transient_fx == 0 && EQ_16( inner_frame_fx, L_FRAME16k ) ) @@ -970,7 +970,7 @@ void hq_lr_enc_fx( /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ FOR( i = 0; i < 2; i++ ) { - push_indice_fx( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); + push_indice( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); } } ELSE IF( EQ_16( st_fx->bwidth, SWB ) && EQ_16( hqswb_clas_fx, HQ_HARMONIC ) && ( EQ_32( L_bwe_br, HQ_16k40 ) || EQ_32( L_bwe_br, HQ_13k20 ) ) ) @@ -2213,7 +2213,7 @@ static Word16 small_symbol_enc_fx( /* o : bits /* Encoding LSB bit packing */ FOR( i = 0; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); } } @@ -2526,74 +2526,74 @@ static Word16 large_symbol_enc_fx( /* o : bits /* Encoding MSB bits */ IF( *hLCmode0 == 0 ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); bits = BITS_DE_8SMODE; move16(); IF( cnt_outlyer0 == 0 ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); bits = add( bits, BITS_DE_8SMODE_N0 ); IF( EQ_16( cnt_outlyer, 1 ) ) { /* 01 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } ELSE { /* 00 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ } FOR( i = 0; i < pos_outlyer; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = ( pos_outlyer + 1 ); i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); bits = add( bits, BITS_DE_8SMODE_N0 ); IF( EQ_16( cnt_outlyer, 1 ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } ELSE { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); /* Q0 */ } FOR( i = 1; i < pos_outlyer; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = pos_outlyer + 1; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } @@ -2601,12 +2601,12 @@ static Word16 large_symbol_enc_fx( /* o : bits ELSE { bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); - push_indice_fx( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); + push_indice( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); FOR( i = 0; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); bits = add( bits, hessize[tdifidx1[i] + 4] ); /* Q0 */ } @@ -2614,7 +2614,7 @@ static Word16 large_symbol_enc_fx( /* o : bits { FOR( i = 0; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); } /*bits += BANDS * lsbdepth1; */ bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); /* Q0 */ @@ -3115,7 +3115,7 @@ static Word16 band_energy_quant_fx( { deng_cmode = 0; move16(); - push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 1 ); deng_bits = add( ebits, BITS_DE_CMODE ); /* Q0 */ } @@ -3124,7 +3124,7 @@ static Word16 band_energy_quant_fx( /* setting energy difference coding mode and storing it */ deng_cmode = 1; move16(); - push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); deng_bits = add( hbits, BITS_DE_CMODE ); /* Q0 */ @@ -3479,7 +3479,7 @@ static Word16 p2a_threshold_quant_fx( move16(); } - push_indice_fx( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); + push_indice( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); j = add( j, 1 ); } @@ -3768,7 +3768,7 @@ static void mdct_spectrum_fine_gain_enc_fx( move16(); } - push_indice_fx( st_fx->hBstr, IND_HQ2_SUBBAND_GAIN, imin_fx, gqbits ); + push_indice( st_fx->hBstr, IND_HQ2_SUBBAND_GAIN, imin_fx, gqbits ); } return; diff --git a/lib_enc/hvq_enc_fx.c b/lib_enc/hvq_enc_fx.c index b06a1734d..a0acd0bfd 100644 --- a/lib_enc/hvq_enc_fx.c +++ b/lib_enc/hvq_enc_fx.c @@ -335,7 +335,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits q_noise_level[i] = 0; move16(); } - push_indice_fx( st_fx->hBstr, IND_HVQ_BWE_NL, q_noise_level_idx[i], 2 ); + push_indice( st_fx->hBstr, IND_HVQ_BWE_NL, q_noise_level_idx[i], 2 ); bits_used = add( bits_used, 2 ); noise_level[i] = q_noise_level[i]; /* in Q15 */ diff --git a/lib_enc/isf_enc_amr_wb_fx.c b/lib_enc/isf_enc_amr_wb_fx.c index 4851ed155..d58998565 100644 --- a/lib_enc/isf_enc_amr_wb_fx.c +++ b/lib_enc/isf_enc_amr_wb_fx.c @@ -173,11 +173,11 @@ static void qisf_ns_28b_fx( indice[4] = add( sub_VQ_fx( &isf[12], dico5_ns_28b_fx + 4, 4, DICO5_NS_28b - 1, &tmp ), 1 ); /* First vector has a problem -> do not allow */ move16(); /* write indices to array */ - push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 6 ); - push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 6 ); - push_indice_fx( hBstr, IND_ISF_0_2, indice[2], 6 ); - push_indice_fx( hBstr, IND_ISF_0_3, indice[3], 5 ); - push_indice_fx( hBstr, IND_ISF_0_4, indice[4], 5 ); + push_indice( hBstr, IND_ISF_0_0, indice[0], 6 ); + push_indice( hBstr, IND_ISF_0_1, indice[1], 6 ); + push_indice( hBstr, IND_ISF_0_2, indice[2], 6 ); + push_indice( hBstr, IND_ISF_0_3, indice[3], 5 ); + push_indice( hBstr, IND_ISF_0_4, indice[4], 5 ); /* decoding the ISFs */ disf_ns_28b_fx( indice, isf ); @@ -305,11 +305,11 @@ static void qisf_2s_36b_fx( indice[0] = Indirect_dico1[indice[0]]; move16(); /* Make interoperable with G722.2 */ - push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 8 ); - push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 8 ); - push_indice_fx( hBstr, IND_ISF_1_0, indice[2], 7 ); - push_indice_fx( hBstr, IND_ISF_1_1, indice[3], 7 ); - push_indice_fx( hBstr, IND_ISF_1_2, indice[4], 6 ); + push_indice( hBstr, IND_ISF_0_0, indice[0], 8 ); + push_indice( hBstr, IND_ISF_0_1, indice[1], 8 ); + push_indice( hBstr, IND_ISF_1_0, indice[2], 7 ); + push_indice( hBstr, IND_ISF_1_1, indice[3], 7 ); + push_indice( hBstr, IND_ISF_1_2, indice[4], 6 ); return; } @@ -442,13 +442,13 @@ static void qisf_2s_46b_fx( indice[0] = Indirect_dico1[indice[0]]; move16(); /* Make interoperable with G722.2 */ - push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 8 ); - push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 8 ); - push_indice_fx( hBstr, IND_ISF_1_0, indice[2], 6 ); - push_indice_fx( hBstr, IND_ISF_1_1, indice[3], 7 ); - push_indice_fx( hBstr, IND_ISF_1_2, indice[4], 7 ); - push_indice_fx( hBstr, IND_ISF_1_3, indice[5], 5 ); - push_indice_fx( hBstr, IND_ISF_1_4, indice[6], 5 ); + push_indice( hBstr, IND_ISF_0_0, indice[0], 8 ); + push_indice( hBstr, IND_ISF_0_1, indice[1], 8 ); + push_indice( hBstr, IND_ISF_1_0, indice[2], 6 ); + push_indice( hBstr, IND_ISF_1_1, indice[3], 7 ); + push_indice( hBstr, IND_ISF_1_2, indice[4], 7 ); + push_indice( hBstr, IND_ISF_1_3, indice[5], 5 ); + push_indice( hBstr, IND_ISF_1_4, indice[6], 5 ); return; } diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index e6d08c49d..8fe425d74 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -647,11 +647,11 @@ static void lsfq_CNG_fx( Vr_add( qlsf, &CNG_SN1_fx[idx_cv * M], qlsf, M ); /* write the VQ index to the bitstream */ - push_indice_fx( hBstr, IND_ISF_0_0, idx_cv, 4 ); + push_indice( hBstr, IND_ISF_0_0, idx_cv, 4 ); /* write the LVQ index to the bitstream */ - push_indice_fx( hBstr, IND_ISF_0_1, idx_lvq[0], LEN_INDICE ); - push_indice_fx( hBstr, IND_ISF_0_1, idx_lvq[1], LSF_BITS_CNG - 4 - LEN_INDICE ); + push_indice( hBstr, IND_ISF_0_1, idx_lvq[0], LEN_INDICE ); + push_indice( hBstr, IND_ISF_0_1, idx_lvq[1], LSF_BITS_CNG - 4 - LEN_INDICE ); return; } @@ -1117,13 +1117,13 @@ void lsf_end_enc_fx( IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) ) { /* VOICED =2 and GENERIC=3, so "coder_type-2" means VOICED =0 and GENERIC=1*/ - push_indice_fx( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); + push_indice( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); } /* write predictor selection bit */ IF( EQ_16( predmode, 2 ) ) { - push_indice_fx( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); + push_indice( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); } test(); @@ -1134,7 +1134,7 @@ void lsf_end_enc_fx( Bit_alloc1 = &BC_TCVQ_BIT_ALLOC_40B[1]; FOR( i = 0; i < ( M / 2 ) + 3; i++ ) { - push_indice_fx( hBstr, IND_LSF, TCQIdx[i], Bit_alloc1[i] ); + push_indice( hBstr, IND_LSF, TCQIdx[i], Bit_alloc1[i] ); } } ELSE @@ -1175,7 +1175,7 @@ void lsf_end_enc_fx( move16(); cumleft -= num_bits; move16(); - push_indice_fx( hBstr, IND_LSF, indice[i], num_bits ); + push_indice( hBstr, IND_LSF, indice[i], num_bits ); } WHILE( cumleft > 0 ) @@ -1195,7 +1195,7 @@ void lsf_end_enc_fx( } cumleft = sub( cumleft, num_bits ); - push_indice_fx( hBstr, IND_LSF, indice[i], num_bits ); + push_indice( hBstr, IND_LSF, indice[i], num_bits ); i = add( i, 1 ); } } @@ -3636,7 +3636,7 @@ static void lsf_mid_enc_fx( /* convert LSFs back to LSPs */ lsf2lsp_fx( qlsf, lsp, M, int_fs ); - push_indice_fx( hBstr, IND_MID_FRAME_LSF_INDEX, idx, nb_bits ); + push_indice( hBstr, IND_MID_FRAME_LSF_INDEX, idx, nb_bits ); return; } diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index a7588283a..391191175 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -698,9 +698,9 @@ void nelp_encoder_fx( } ELSE { - push_indice_fx( hBstr, IND_IG1, iG1_fx, 5 ); - push_indice_fx( hBstr, IND_IG2A, iG2_fx[0], 6 ); - push_indice_fx( hBstr, IND_IG2B, iG2_fx[1], 6 ); + push_indice( hBstr, IND_IG1, iG1_fx, 5 ); + push_indice( hBstr, IND_IG2A, iG2_fx[0], 6 ); + push_indice( hBstr, IND_IG2B, iG2_fx[1], 6 ); } test(); @@ -1019,7 +1019,7 @@ void nelp_encoder_fx( } ELSE { - push_indice_fx( hBstr, IND_NELP_FID, fid, 2 ); + push_indice( hBstr, IND_NELP_FID, fid, 2 ); } } diff --git a/lib_enc/peak_vq_enc_fx.c b/lib_enc/peak_vq_enc_fx.c index aa4763aa6..dffab4900 100644 --- a/lib_enc/peak_vq_enc_fx.c +++ b/lib_enc/peak_vq_enc_fx.c @@ -559,13 +559,13 @@ Word16 peak_vq_enc_fx( move32(); nf_gains[i] = L_shr( acc, 1 + 2 ); /* nf_gains in Q12. dicn_fx is in Q14. Need extra shift +2. */ move32(); - push_indice_fx( hBstr, IND_HVQ_NF_GAIN, indx, 5 ); + push_indice( hBstr, IND_HVQ_NF_GAIN, indx, 5 ); bits = add( bits, 5 ); } /* Signal number of peaks */ i = sub( max_peaks, vq_peaks ); - push_indice_fx( hBstr, IND_NUM_PEAKS, i, 5 ); + push_indice( hBstr, IND_NUM_PEAKS, i, 5 ); bits = add( bits, 5 ); /* Identify position of first peak and arrange peak gains by position */ @@ -677,8 +677,8 @@ Word16 peak_vq_enc_fx( move16(); } - push_indice_fx( hBstr, IND_FLAGN, FlagN, 1 ); - push_indice_fx( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS ); + push_indice( hBstr, IND_FLAGN, FlagN, 1 ); + push_indice( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS ); IF( FlagN ) { @@ -692,7 +692,7 @@ Word16 peak_vq_enc_fx( r = pgain_huffsizn[j]; move16(); - push_indice_fx( hBstr, IND_PG_IDX, m, r ); + push_indice( hBstr, IND_PG_IDX, m, r ); } } ELSE @@ -700,7 +700,7 @@ Word16 peak_vq_enc_fx( pPgainDifIdx = &pgain_difidx[1]; FOR( i = 0; i < vqPeaksMinus1; i++ ) { - push_indice_fx( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS ); + push_indice( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS ); } } @@ -727,13 +727,13 @@ Word16 peak_vq_enc_fx( num_overlap_bins = sub( 5, sub( vq_peak_idx[i + 1], vq_peak_idx[i] ) ); indx = sub( vq_peak_idx[i], 2 ); quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, num_overlap_bins, core_brate, vq_peaks ); - push_indice_fx( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); + push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); } indx = sub( vq_peak_idx[i], 2 ); quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, 0, core_brate, vq_peaks ); - push_indice_fx( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); + push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); /* Quantize peak positions and sign with HVQ */ @@ -826,7 +826,7 @@ Word16 peak_vq_enc_fx( move16(); } - push_indice_fx( hBstr, IND_HVQ_PVQ_GAIN, pvq_norm[k], HVQ_PVQ_GAIN_BITS ); + push_indice( hBstr, IND_HVQ_PVQ_GAIN, pvq_norm[k], HVQ_PVQ_GAIN_BITS ); pvq_bits = add( pvq_bits, HVQ_PVQ_GAIN_BITS ); pvq_norm[k] = add( pvq_norm[k], 8 ); @@ -1148,7 +1148,7 @@ static void quant_peaks_fx( { *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 0 ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 0, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 ); } ELSE IF( EQ_16( cb_class, 1 ) ) { @@ -1157,7 +1157,7 @@ static void quant_peaks_fx( move16(); *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 0, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 ); } ELSE IF( EQ_16( cb_class, 2 ) ) { @@ -1166,13 +1166,13 @@ static void quant_peaks_fx( move16(); *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 1, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 ); } ELSE { *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 1 ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 1, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 ); } FOR( i = 0; i < 4; i++ ) @@ -1458,23 +1458,23 @@ static Word16 hvq_code_pos_fx( test(); IF( GT_16( delta_bits, sparse_bits ) || delta_bits < 0 ) { - push_indice_fx( hBstr, IND_POS_IDX, HVQ_CP_SPARSE, 1 ); + push_indice( hBstr, IND_POS_IDX, HVQ_CP_SPARSE, 1 ); FOR( i = 0; i < sparse_bits; i++ ) { - push_indice_fx( hBstr, IND_POS_IDX, sparse_result[i], 1 ); + push_indice( hBstr, IND_POS_IDX, sparse_result[i], 1 ); } bits = add( add( bits, sparse_bits ), 1 ); } ELSE { - push_indice_fx( hBstr, IND_POS_IDX, HVQ_CP_DELTA, 1 ); + push_indice( hBstr, IND_POS_IDX, HVQ_CP_DELTA, 1 ); FOR( i = 0; i < num_peaks; i++ ) { j = delta[i]; move16(); - push_indice_fx( hBstr, IND_POS_IDX, hvq_cp_huff_val[j], hvq_cp_huff_len[j] ); + push_indice( hBstr, IND_POS_IDX, hvq_cp_huff_val[j], hvq_cp_huff_len[j] ); } bits = add( add( bits, delta_bits ), 1 ); } @@ -1489,7 +1489,7 @@ static Word16 hvq_code_pos_fx( tmp = 0; move16(); } - push_indice_fx( hBstr, IND_POS_IDX, tmp, 1 ); + push_indice( hBstr, IND_POS_IDX, tmp, 1 ); } bits = add( bits, num_peaks ); diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index b19fb7e56..8eea1b3d5 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -1787,7 +1787,7 @@ void pit_Q_enc_fx( } { - push_indice_fx( hBstr, IND_PITCH, pitch_index, nBits ); + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); } return; @@ -1919,7 +1919,7 @@ void pit16k_Q_enc_fx( } } - push_indice_fx( hBstr, IND_PITCH, pitch_index, nBits ); + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); } ELSE IF( EQ_16( nBits, 9 ) ) /* absolute encoding with 9 bits */ { @@ -1949,14 +1949,14 @@ void pit16k_Q_enc_fx( } } - push_indice_fx( hBstr, IND_PITCH, pitch_index, 9 ); + push_indice( hBstr, IND_PITCH, pitch_index, 9 ); } ELSE /* nBits == 6 */ /* relative encoding with 6 bits */ { /*pitch_index = (T0 - *T0_min) * 4 + T0_frac;*/ pitch_index = add( shl( sub( T0, *T0_min ), 2 ), T0_frac ); - push_indice_fx( hBstr, IND_PITCH, pitch_index, nBits ); + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); } limit_T0_fx( L_FRAME16k, 8, L_SUBFR, limit_flag, T0, T0_frac, T0_min, T0_max ); diff --git a/lib_enc/ppp_enc_fx.c b/lib_enc/ppp_enc_fx.c index 9afb27065..ac3d5836a 100644 --- a/lib_enc/ppp_enc_fx.c +++ b/lib_enc/ppp_enc_fx.c @@ -171,9 +171,9 @@ ivas_error ppp_quarter_encoder_fx( CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx = (Word16) find_remd( Ltempn, 20971, &Ltempd ); move16(); - push_indice_fx( hBstr, IND_AMP0, AMP_IDX_fx[0], 6 ); - push_indice_fx( hBstr, IND_AMP1, AMP_IDX_fx[1], 6 ); - push_indice_fx( hBstr, IND_POWER, POWER_IDX_FX, 6 ); + push_indice( hBstr, IND_AMP0, AMP_IDX_fx[0], 6 ); + push_indice( hBstr, IND_AMP1, AMP_IDX_fx[1], 6 ); + push_indice( hBstr, IND_POWER, POWER_IDX_FX, 6 ); /*Phase copying is done through copy_phase instead of car2pol and pol2car */ copy_phase_fx( TARGETCW_FX, *CURRCW_Q_FX, TARGETCW_FX ); @@ -199,7 +199,7 @@ ivas_error ppp_quarter_encoder_fx( /*DTFS_phaseShift( CURRCW_Q,(float)(PI2*tmp/CURRCW_Q->lag) ); */ Q2phaseShift_fx( CURRCW_Q_FX, tmp_fx, CURRCW_Q_FX->lag_fx, S_fx, C_fx ); - push_indice_fx( hBstr, IND_GLOBAL_ALIGNMENT, shr( add( tmp_fx, 12 ), 2 ), 3 ); + push_indice( hBstr, IND_GLOBAL_ALIGNMENT, shr( add( tmp_fx, 12 ), 2 ), 3 ); free( PREVDTFS_FX ); return error; diff --git a/lib_enc/range_enc_fx.c b/lib_enc/range_enc_fx.c index 689b313d8..767b2ecb5 100644 --- a/lib_enc/range_enc_fx.c +++ b/lib_enc/range_enc_fx.c @@ -423,14 +423,14 @@ void rc_enc_bits_fx( IF( GT_16( bits, 16 ) ) { - push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_lshr( value, 16 ) ), sub( bits, 16 ) ); + push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_lshr( value, 16 ) ), sub( bits, 16 ) ); hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 - push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_and( value, 0x0000ffff ) ), 16 ); + push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_and( value, 0x0000ffff ) ), 16 ); hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 } ELSE { - push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( value ), bits ); + push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( value ), bits ); hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 } } @@ -516,7 +516,7 @@ static void rc_enc_write_fx( Word16 bits /* i : Number of bits Q0*/ ) { - push_indice_fx( hBstr, IND_RC_START, byte, bits ); + push_indice( hBstr, IND_RC_START, byte, bits ); return; } diff --git a/lib_enc/stat_noise_uv_enc_fx.c b/lib_enc/stat_noise_uv_enc_fx.c index 0a20db8ed..1445559a1 100644 --- a/lib_enc/stat_noise_uv_enc_fx.c +++ b/lib_enc/stat_noise_uv_enc_fx.c @@ -94,7 +94,7 @@ void stat_noise_uv_enc_fx( noisiness = s_max( noisiness, 0 ); noisiness = s_min( noisiness, 31 ); - push_indice_fx( st_fx->hBstr, IND_NOISINESS, noisiness, 5 ); + push_indice( st_fx->hBstr, IND_NOISINESS, noisiness, 5 ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 26c8382ca..1ebef7404 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -186,7 +186,7 @@ void wb_bwe_enc_fx( Q_synth = sub( add( sub( new_input_fx_exp, 16 ), scl ), 1 ); mode = WB_BWE_encoding_fx( coder_type, yorig_fx, WB_fenv_fx, st_fx, Q_synth, Q_synth ); - push_indice_fx( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); + push_indice( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); } hBWE_FD->prev_mode = mode; @@ -820,7 +820,7 @@ void swb_bwe_enc_fx( /* write FB BWE frame gain to the bitstream */ IF( EQ_16( st_fx->extl, FB_BWE ) ) { - push_indice_fx( st_fx->hBstr, IND_FB_SLOPE, idxGain, NUM_BITS_FB_FRAMEGAIN ); + push_indice( st_fx->hBstr, IND_FB_SLOPE, idxGain, NUM_BITS_FB_FRAMEGAIN ); } return; @@ -2476,7 +2476,7 @@ Word16 WB_BWE_encoding_fx( /* o : classification of wb index = WB_BWE_fenv_q_fx( WB_fenv_fx, F_2_5_fx, 32, 2 ); - push_indice_fx( st_fx->hBstr, IND_WB_FENV, index, 5 ); + push_indice( st_fx->hBstr, IND_WB_FENV, index, 5 ); return ( mode ); } @@ -2665,7 +2665,7 @@ static Word16 SWB_BWE_encoding_fx( { mode = IsTransient; move16(); - push_indice_fx( hBstr, IND_SWB_CLASS, mode, 2 ); + push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); /* Energy for the different bands and global energies */ global_gain_fx = L_deposit_l( 0 ); @@ -2924,13 +2924,13 @@ static Word16 SWB_BWE_encoding_fx( index = shr( add( SWB_tenv_tmp_fx[n_band], 1024 ), 11 ); } - push_indice_fx( hBstr, IND_SWB_TENV, index, 4 ); + push_indice( hBstr, IND_SWB_TENV, index, 4 ); } MSVQ_Interpol_Tran_fx( SWB_fenv_fx, indice ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[0], 7 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[1], 6 ); + push_indice( hBstr, IND_SWB_FENV, indice[0], 7 ); + push_indice( hBstr, IND_SWB_FENV, indice[1], 6 ); } ELSE { @@ -2955,7 +2955,7 @@ static Word16 SWB_BWE_encoding_fx( global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ mode = FD_BWE_class_fx( yos_fx, global_gain_fx, tilt_nb_fx, Q_synth, Q_shb, st_fx ); - push_indice_fx( hBstr, IND_SWB_CLASS, mode, 2 ); + push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); energy_control_fx( st_fx, ACELP_CORE, mode, -1, yos_fx, st_offset, energy_factor_fx, Q_synth_lf ); @@ -2990,11 +2990,11 @@ static Word16 SWB_BWE_encoding_fx( /* Energy VQ */ msvq_interpol_fx( SWB_fenv_fx, w_env_fx, indice ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[0], 5 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[1], 7 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[2], 6 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[3], 5 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[4], 6 ); + push_indice( hBstr, IND_SWB_FENV, indice[0], 5 ); + push_indice( hBstr, IND_SWB_FENV, indice[1], 7 ); + push_indice( hBstr, IND_SWB_FENV, indice[2], 6 ); + push_indice( hBstr, IND_SWB_FENV, indice[3], 5 ); + push_indice( hBstr, IND_SWB_FENV, indice[4], 6 ); } hBWE_FD->prev_mode = mode; move16(); @@ -3939,7 +3939,7 @@ void hq_generic_encoding_fx( IF( EQ_16( hHQ_core->hq_generic_speech_class, 1 ) ) { - push_indice_fx( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 1, 1 ); + push_indice( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 1, 1 ); *hq_generic_exc_clas = HQ_GENERIC_SP_EXC; move16(); } @@ -3947,8 +3947,8 @@ void hq_generic_encoding_fx( { *hq_generic_exc_clas = decision_hq_generic_class_fx_32( coefs_fx, hq_generic_offset ); move16(); - push_indice_fx( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 0, 1 ); - push_indice_fx( hBstr, IND_HQ_SWB_EXC_CLAS, *hq_generic_exc_clas, 1 ); + push_indice( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 0, 1 ); + push_indice( hBstr, IND_HQ_SWB_EXC_CLAS, *hq_generic_exc_clas, 1 ); } FOR( n_band = 0; n_band < nenv; n_band++ ) @@ -4069,23 +4069,23 @@ void hq_generic_encoding_fx( move16(); } - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[0], 5 ); - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[1], 7 ); - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[2], 6 ); - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[3], 5 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[0], 5 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[1], 7 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[2], 6 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[3], 5 ); IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) { - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[4], 6 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[4], 6 ); } ELSE { - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[4], 5 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[4], 5 ); } IF( EQ_16( st_fx->bwidth, FB ) ) { - push_indice_fx( hBstr, IND_FB_FENV_HQ, indice[5], 5 ); + push_indice( hBstr, IND_FB_FENV_HQ, indice[5], 5 ); } FOR( n_band = 0; n_band < nenv; n_band++ ) diff --git a/lib_enc/swb_bwe_enc_hr_fx.c b/lib_enc/swb_bwe_enc_hr_fx.c index fd4a9f125..8b5a17353 100644 --- a/lib_enc/swb_bwe_enc_hr_fx.c +++ b/lib_enc/swb_bwe_enc_hr_fx.c @@ -189,7 +189,7 @@ void swb_bwe_enc_hr_fx( st_fx->EnergyLT_fx_exp = exp1; move16(); - push_indice_fx( hBstr, IND_HR_IS_TRANSIENT, is_transient, 1 ); + push_indice( hBstr, IND_HR_IS_TRANSIENT, is_transient, 1 ); /*---------------------------------------------------------------------* * OLA and MDCT @@ -309,7 +309,7 @@ void swb_bwe_enc_hr_fx( ind1 = gain_quant_fx( &L_gain_fx, &gain1_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp1 ); - push_indice_fx( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalization with global gain */ @@ -353,7 +353,7 @@ void swb_bwe_enc_hr_fx( { ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx, NUM_ENVLOPE_CODE_HR_TR ); - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR ); + push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR ); nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR ); ind2 = ind1; move16(); @@ -369,7 +369,7 @@ void swb_bwe_enc_hr_fx( ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx + ( NUM_ENVLOPE_CODE_HR_TR2 * 2 ), NUM_ENVLOPE_CODE_HR_TR2 ); } - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR - 1 ); + push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR - 1 ); nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR - 1 ); } @@ -439,7 +439,7 @@ void swb_bwe_enc_hr_fx( L_en_noncoded_fx = L_deposit_h( en_band_fx[N_BANDS_TRANS_BWE_HR - 1] ); /* to Put in Q16+9 */ } - push_indice_fx( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR ); } ELSE @@ -507,7 +507,7 @@ void swb_bwe_enc_hr_fx( L_gain_fx = L_shr( L_tmp, sub( 31 - 16, exp2 ) ); /* 31: 'L_tmp' is already in Q31 */ ind1 = gain_quant_fx( &L_gain_fx, &gain1_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp1 ); - push_indice_fx( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalization with global gain */ @@ -547,8 +547,8 @@ void swb_bwe_enc_hr_fx( ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code1_fx, NUM_ENVLOPE_CODE_HR1 ); ind2 = en_band_quant_fx( en_band_fx + 2, swb_hr_env_code2_fx, NUM_ENVLOPE_CODE_HR2 ); - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR1 ); - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind2, NBITS_ENVELOPE_BWE_HR2 ); + push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR1 ); + push_indice( hBstr, IND_HR_ENVELOPE, ind2, NBITS_ENVELOPE_BWE_HR2 ); nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR1 + NBITS_ENVELOPE_BWE_HR2 ); @@ -673,7 +673,7 @@ void swb_bwe_enc_hr_fx( L_en_noncoded_fx = L_mult0( min_env_fx, 16384 ); } - push_indice_fx( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR ); } ELSE @@ -758,7 +758,7 @@ void swb_bwe_enc_hr_fx( /* Put in Q16 */ L_gain_fx = L_shr( L_temp, sub( 31 - 16, temp2 ) ); /* 31: 'L_temp' is already in Q31 */ ind1 = gain_quant_fx( &L_gain_fx, &gain2_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp2 ); - push_indice_fx( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalize with global gain */ @@ -784,7 +784,7 @@ void swb_bwe_enc_hr_fx( WHILE( nBits > 0 ) { i = s_min( nBits, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); nBits = sub( nBits, i ); } return; diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index 1a397c514..938cdd971 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -806,7 +806,7 @@ static void gethar_noisegn_fx( } } - push_indice_fx( hBstr, IND_NOISEG, imin_fx, 2 ); + push_indice( hBstr, IND_NOISEG, imin_fx, 2 ); /*g=(float) pow (10.0f,gain_table[imin]);*/ L_temp = L_mult( gain_table_SWB_BWE_fx[imin_fx], 27213 ); /* Q14+Q13+1=Q28 log(10)/log(2)=3.3219 27213.23(Q13) */ @@ -909,7 +909,7 @@ static void EncodeSWBSubbands_fx( /* Write the indices into the bitstream */ FOR( k = 0; k < nBands_search_fx; k++ ) { - push_indice_fx( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_mode0_Har[k] ); + push_indice( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_mode0_Har[k] ); } IF( flag_dis == 0 ) @@ -974,7 +974,7 @@ static void EncodeSWBSubbands_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_modeNormal[k] ); + push_indice( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_modeNormal[k] ); } } diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index c5d5e651e..1a14e7acb 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -866,7 +866,7 @@ void wb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_LBR_WB_LSF ); + push_indice( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_LBR_WB_LSF ); } Copy( lbr_wb_bwe_lsfvq_cbook_2bit_fx + i * LPC_SHB_ORDER_LBR_WB, lsp_wb, LPC_SHB_ORDER_LBR_WB ); @@ -928,7 +928,7 @@ void wb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_WB_LSF ); + push_indice( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_WB_LSF ); } Copy( wb_bwe_lsfvq_cbook_8bit_fx + i * LPC_SHB_ORDER_WB, lsp_wb, LPC_SHB_ORDER_WB ); @@ -1162,7 +1162,7 @@ void wb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_UV_FLAG, uv_flag, 1 ); + push_indice( st_fx->hBstr, IND_UV_FLAG, uv_flag, 1 ); /* Quantization of the subframe gain parameter */ QuantizeSHBsubgains_fx( st_fx, GainShape, st_fx->extl ); @@ -2482,7 +2482,7 @@ void swb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_SHB_VF, vf_ind_fx, NUM_BITS_SHB_VF ); + push_indice( st_fx->hBstr, IND_SHB_VF, vf_ind_fx, NUM_BITS_SHB_VF ); } } @@ -5330,7 +5330,7 @@ static void QuantizeSHBsubgains_fx( idxSubGain = closest_centroid_lc_fx( subgains + NUM_SHB_SUBFR / 4, HBCB_SubGain5bit_fx, 1 << NUM_BITS_SHB_SUBGAINS ); Copy( HBCB_SubGain5bit_fx + idxSubGain * NUM_SHB_SUBFR / 4, subgains, NUM_SHB_SUBFR / 4 ); - push_indice_fx( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); + push_indice( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) { @@ -5401,7 +5401,7 @@ static void QuantizeSHBsubgains_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); + push_indice( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); } } @@ -5596,7 +5596,7 @@ static void Quant_shb_ener_sf_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( st_fx->hBstr, IND_SHB_ENER_SF, idxSubEner_fx, NUM_BITS_SHB_ENER_SF ); + push_indice( st_fx->hBstr, IND_SHB_ENER_SF, idxSubEner_fx, NUM_BITS_SHB_ENER_SF ); } return; } @@ -5683,7 +5683,7 @@ static void Quant_shb_res_gshape_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( st_fx->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); + push_indice( st_fx->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); } } } @@ -5787,7 +5787,7 @@ static void QuantizeSHBframegain_fx( 1 << NUM_BITS_SHB_FrameGain, &idxFrameGain, &Q_GainFrame, SHBCB_FrameGain64_fx ); - push_indice_fx( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FrameGain ); + push_indice( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FrameGain ); *rf_gainFrame_ind = idxFrameGain; move16(); /* Q18 */ } @@ -5852,7 +5852,7 @@ static void QuantizeSHBframegain_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); + push_indice( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); } *rf_gainFrame_ind = idxFrameGain; move16(); @@ -7176,7 +7176,7 @@ static void Quant_BWE_LSF_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_LSF, lsf_idx[i], lsf_q_num_bits[i] ); + push_indice( hBstr, IND_SHB_LSF, lsf_idx[i], lsf_q_num_bits[i] ); } } @@ -7186,7 +7186,7 @@ static void Quant_BWE_LSF_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_MIRROR, m_idx, MIRROR_POINT_BITS ); + push_indice( hBstr, IND_SHB_MIRROR, m_idx, MIRROR_POINT_BITS ); } grid_idx = Find_LSF_grid_fx( lsf, lsf_q, m ); @@ -7194,7 +7194,7 @@ static void Quant_BWE_LSF_fx( hBWE_TD->grid_idx = grid_idx; IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_GRID, grid_idx, NUM_LSF_GRID_BITS ); + push_indice( hBstr, IND_SHB_GRID, grid_idx, NUM_LSF_GRID_BITS ); } FOR( i = 0; i < LPC_SHB_ORDER; i++ ) @@ -7407,7 +7407,7 @@ void fb_tbe_enc_fx( } ELSE { - push_indice_fx( st->hBstr, IND_FB_SLOPE, idxGain, 4 ); + push_indice( st->hBstr, IND_FB_SLOPE, idxGain, 4 ); } return; diff --git a/lib_enc/tcq_core_enc_fx.c b/lib_enc/tcq_core_enc_fx.c index 82088be50..d5841094f 100644 --- a/lib_enc/tcq_core_enc_fx.c +++ b/lib_enc/tcq_core_enc_fx.c @@ -449,11 +449,11 @@ ivas_error tcq_core_LR_enc_fx( j = sub( bit_budget, shl( nb_bytes, 3 ) ); FOR( i = 0; i < nb_bytes; i++ ) { - push_indice_fx( hBstr, IND_HQ2_SUBBAND_TCQ, pbs_fx->buf[i], 8 ); + push_indice( hBstr, IND_HQ2_SUBBAND_TCQ, pbs_fx->buf[i], 8 ); } IF( j > 0 ) { - push_indice_fx( hBstr, IND_HQ2_SUBBAND_TCQ, shr( pbs_fx->buf[nb_bytes], ( 8 - j ) ), j ); + push_indice( hBstr, IND_HQ2_SUBBAND_TCQ, shr( pbs_fx->buf[nb_bytes], ( 8 - j ) ), j ); } /* Clear decoding buffer */ set32_fx( coefs_quant_fx, 0, sfm_end[BANDS - 1] + 1 ); diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 7fe813d12..253cc9717 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -389,7 +389,7 @@ void transition_enc_fx( /* 7bit ENCODER */ /* index = (*T0-pit_start)*2 + *T0_frac/2;*/ index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -438,7 +438,7 @@ void transition_enc_fx( limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max for delta search */ index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -502,7 +502,7 @@ void transition_enc_fx( *T0_frac = 0; move16(); } - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -526,7 +526,7 @@ void transition_enc_fx( *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); move16(); index = delta_pit_enc_fx( 2, *T0, *T0_frac, *T0_min ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -607,7 +607,7 @@ void transition_enc_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } } @@ -768,7 +768,7 @@ void transition_enc_fx( /*index = (*T0)*2 + ((*T0_frac)>>1) - (PIT16k_FR2_TC0_2SUBFR*2) + ((PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4);*/ index = add( sub( add( shl( *T0, 1 ), shr( *T0_frac, 1 ) ), ( PIT16k_FR2_TC0_2SUBFR * 2 ) ), ( PIT16k_FR2_TC0_2SUBFR - PIT16k_MIN ) * 4 ); } - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } ELSE IF( EQ_16( nBits, 6 ) ) { @@ -777,7 +777,7 @@ void transition_enc_fx( move16(); index = delta_pit_enc_fx( 4, *T0, *T0_frac, *T0_min ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } IF( EQ_16( nBits, 6 ) ) { @@ -804,7 +804,7 @@ void transition_enc_fx( move16(); set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ - push_indice_fx( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ + push_indice( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ Copy( xn_fx, xn2_fx, L_SUBFR ); /* target vector for codebook search */ set16_fx( y1_fx, 0, L_SUBFR ); /* set filtered adaptive excitation to 0 */ @@ -839,7 +839,7 @@ void transition_enc_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } *Jopt_flag = 1; @@ -1886,7 +1886,7 @@ static void tc_enc_fx( /* write pitch index */ IF( ( GE_16( *T0, L_SUBFR ) ) && ( NE_16( *tc_subfr, 3 * L_SUBFR ) ) ) { - push_indice_fx( hBstr, IND_PITCH, 0, nBits ); + push_indice( hBstr, IND_PITCH, 0, nBits ); } ELSE IF( EQ_16( *tc_subfr, 3 * L_SUBFR ) ) { @@ -1898,7 +1898,7 @@ static void tc_enc_fx( { index = abs_pit_enc_fx( 2, 0, *T0, *T0_frac ); } - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); limit_T0_fx( L_FRAME, 8, 0, 0, *T0, 0, T0_min, T0_max ); } @@ -1907,12 +1907,12 @@ static void tc_enc_fx( IF( EQ_16( nBits, 6 ) ) { index = delta_pit_enc_fx( 2, *T0, *T0_frac, PIT_MIN - 1 ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } ELSE { index = delta_pit_enc_fx( 0, *T0, *T0_frac, PIT_MIN - 1 ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } } } @@ -1926,13 +1926,13 @@ static void tc_enc_fx( ELSE IF( EQ_16( nBits, 6 ) ) { index = add( shl( sub( *T0, PIT16k_MIN ), 1 ), shr( *T0_frac, 1 ) ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } } - push_indice_fx( hBstr, IND_TC_IMP_SHAPE, imp_shape, 3 ); - push_indice_fx( hBstr, IND_TC_IMP_POS, imp_pos, 6 ); - push_indice_fx( hBstr, IND_TC_IMP_SIGN, pitch_sign_fx, 1 ); - push_indice_fx( hBstr, IND_TC_IMP_GAIN, pitch_index, 3 ); + push_indice( hBstr, IND_TC_IMP_SHAPE, imp_shape, 3 ); + push_indice( hBstr, IND_TC_IMP_POS, imp_pos, 6 ); + push_indice( hBstr, IND_TC_IMP_SIGN, pitch_sign_fx, 1 ); + push_indice( hBstr, IND_TC_IMP_GAIN, pitch_index, 3 ); *position = add( imp_pos, i_subfr ); move16(); diff --git a/lib_enc/voiced_enc_fx.c b/lib_enc/voiced_enc_fx.c index b0dba61de..8081b2909 100644 --- a/lib_enc/voiced_enc_fx.c +++ b/lib_enc/voiced_enc_fx.c @@ -1156,7 +1156,7 @@ ivas_error ppp_voiced_encoder_fx( { Q_delta_lag = add( delta_lag_E, 11 ); /* to make it positive always */ - push_indice_fx( hBstr, IND_DELTALAG, Q_delta_lag, 5 ); + push_indice( hBstr, IND_DELTALAG, Q_delta_lag, 5 ); } WIsyn_fx( *dtfs_temp_fx, CURRP_Q_E_FX, lpc2_fx, &( hSC_VBR->ph_offset_E_fx ), out_fx, L_FRAME, 0, S_fx, C_fx, -- GitLab From 5e088823aeb430144a4f3d0827e8efaff2d11a4e Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 14:01:42 -0400 Subject: [PATCH 0703/1221] fix clang --- lib_enc/transition_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 253cc9717..6718552c5 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -803,7 +803,7 @@ void transition_enc_fx( *Jopt_flag = 0; move16(); - set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ + set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ push_indice( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ Copy( xn_fx, xn2_fx, L_SUBFR ); /* target vector for codebook search */ -- GitLab From 7b1d6dbda6d6917bedda67b9bcd73a99f1bee6ea Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 14:05:40 -0400 Subject: [PATCH 0704/1221] replace EVS push_next_indice_fx byt IVAS one --- lib_com/bitstream_fx.c | 4 +- lib_com/igf_base_fx.c | 2 +- lib_com/parameter_bitmaping_fx.c | 2 +- lib_enc/ACcontextMapping_enc_fx.c | 2 +- lib_enc/ari_hm_enc_fx.c | 4 +- lib_enc/decision_matrix_enc_fx.c | 4 +- lib_enc/enc_prm_fx.c | 130 +++++++++++++++--------------- lib_enc/evs_enc_fx.c | 14 ++-- lib_enc/fd_cng_enc_fx.c | 4 +- lib_enc/guided_plc_enc_fx.c | 6 +- lib_enc/igf_enc_fx.c | 4 +- lib_enc/igf_scf_enc_fx.c | 2 +- lib_enc/lsf_msvq_ma_enc_fx.c | 10 +-- lib_enc/qlpc_avq_fx.c | 20 ++--- lib_enc/swb_tbe_enc_fx.c | 28 +++---- 15 files changed, 118 insertions(+), 118 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 667958264..8cb968bf1 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -288,9 +288,8 @@ void push_indice_fx( return; } -#endif /*-------------------------------------------------------------------* - * push_next_indice_fx() * + * push_next_indice() * * Push a new indice into the buffer at the next position *-------------------------------------------------------------------*/ @@ -315,6 +314,7 @@ void push_next_indice_fx( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_com/igf_base_fx.c b/lib_com/igf_base_fx.c index fbccdb519..44cf27c5f 100644 --- a/lib_com/igf_base_fx.c +++ b/lib_com/igf_base_fx.c @@ -1242,7 +1242,7 @@ void IGFCommonFuncsWriteSerialBit( IF( hBstr ) { - push_next_indice_fx( hBstr, bit, 1 ); + push_next_indice( hBstr, bit, 1 ); } *pBitOffset = add( *pBitOffset, 1 ); move16(); diff --git a/lib_com/parameter_bitmaping_fx.c b/lib_com/parameter_bitmaping_fx.c index 0846c618b..923872090 100644 --- a/lib_com/parameter_bitmaping_fx.c +++ b/lib_com/parameter_bitmaping_fx.c @@ -21,7 +21,7 @@ static Word16 PutIntoBitstream_fx( value = *( *pStream )++; codedValue = EncodeValue( value, index ); - push_next_indice_fx( hBstr, codedValue, nBits ); + push_next_indice( hBstr, codedValue, nBits ); return value; } diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index c52fddf97..4e02b1f11 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -343,7 +343,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( /* Push number of encoded tuples */ value = sub( shr( lastnz, 1 ), 1 ); /* Q0 */ - push_next_indice_fx( hBstr, value, nbbits_ntuples ); + push_next_indice( hBstr, value, nbbits_ntuples ); /* Push arithmetic coded bits */ push_next_bits_fx( hBstr, &ptr[nbbits_ntuples], sub( bp, nbbits_ntuples ) ); diff --git a/lib_enc/ari_hm_enc_fx.c b/lib_enc/ari_hm_enc_fx.c index 76d48ccf4..343f1890f 100644 --- a/lib_enc/ari_hm_enc_fx.c +++ b/lib_enc/ari_hm_enc_fx.c @@ -42,12 +42,12 @@ Word16 EncodeIndex_fx( NumRatioBitsBwLtpIndx = NumRatioBits[Bandwidth][LtpPitchIndex]; move16(); - push_next_indice_fx( hBst, s_and( PeriodicityIndex, 0xff ), NumRatioBitsBwLtpIndx ); + push_next_indice( hBst, s_and( PeriodicityIndex, 0xff ), NumRatioBitsBwLtpIndx ); return NumRatioBitsBwLtpIndx; } ELSE { - push_next_indice_fx( hBst, PeriodicityIndex, 8 ); + push_next_indice( hBst, PeriodicityIndex, 8 ); return 8; } } diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index 63a13aa1a..bc5feeb6b 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -527,8 +527,8 @@ void signalling_enc_fx( assert( !st_fx->tcxonly ); assert( st_fx->core == HQ_CORE ); - push_next_indice_fx( hBstr, 1, 1 ); /* TCX */ - push_next_indice_fx( hBstr, 1, 1 ); /* HQ_CORE */ + push_next_indice( hBstr, 1, 1 ); /* TCX */ + push_next_indice( hBstr, 1, 1 ); /* HQ_CORE */ /* write ACELP->HQ core switching flag */ test(); diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index ecd4e2f01..6c052e596 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -33,7 +33,7 @@ static void enc_prm_hm( } /* Flag */ - push_next_indice_fx( hBstr, prm_hm[0], 1 ); + push_next_indice( hBstr, prm_hm[0], 1 ); IF( prm_hm[0] ) { @@ -50,7 +50,7 @@ static void enc_prm_hm( IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) ) { /* Gain index */ - push_next_indice_fx( hBstr, prm_hm[2], kTcxHmNumGainBits ); + push_next_indice( hBstr, prm_hm[2], kTcxHmNumGainBits ); } } } @@ -152,7 +152,7 @@ void enc_prm_rf_ivas_fx( index = 3; move16(); } - push_next_indice_fx( hBstr, index, 2 ); + push_next_indice( hBstr, index, 2 ); IF( EQ_16( rf_frame_type, RF_TCXFD ) ) { @@ -296,9 +296,9 @@ void enc_prm_rf_fx( /* LSF indices */ IF( EQ_16( rf_frame_type, RF_TCXFD ) ) { - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][0], lsf_numbits[0] ); /* VQ 1 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][1], lsf_numbits[1] ); /* VQ 2 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][2], lsf_numbits[2] ); /* VQ 3 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][0], lsf_numbits[0] ); /* VQ 1 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][1], lsf_numbits[1] ); /* VQ 2 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][2], lsf_numbits[2] ); /* VQ 3 */ } /* classification */ @@ -324,12 +324,12 @@ void enc_prm_rf_fx( index = 3; move16(); } - push_next_indice_fx( hBstr, index, 2 ); + push_next_indice( hBstr, index, 2 ); IF( EQ_16( rf_frame_type, RF_TCXFD ) ) { /* TCX global gain = 7 bits */ - push_next_indice_fx( hBstr, hRF->rf_gain_tcx[fec_offset], 7 ); + push_next_indice( hBstr, hRF->rf_gain_tcx[fec_offset], 7 ); /*window info 1 bit for long overlap 2 if minimum or half overlap*/ @@ -345,35 +345,35 @@ void enc_prm_rf_fx( test(); IF( ( EQ_16( rf_frame_type, RF_TCXTD1 ) || EQ_16( rf_frame_type, RF_TCXTD2 ) ) && hTcxEnc->tcxltp != 0 ) { - push_next_indice_fx( hBstr, hRF->rf_tcxltp_param[fec_offset], 9 ); + push_next_indice( hBstr, hRF->rf_tcxltp_param[fec_offset], 9 ); } } } ELSE IF( EQ_16( rf_frame_type, 7 ) ) /* NELP bitstream writing */ { /* LSF indices */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ /* NELP gain indices */ - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_iG1[fec_offset], 5 ); - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][0], 6 ); - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][1], 6 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_iG1[fec_offset], 5 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][0], 6 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][1], 6 ); /* NELP filter selection index */ - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_fid[fec_offset], 2 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_fid[fec_offset], 2 ); /* tbe gainFr */ - push_next_indice_fx( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 5 ); + push_next_indice( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 5 ); } ELSE IF( GE_16( rf_frame_type, 4 ) ) /* rf_frame_type ALL_PRED: 4, NO_PRED: 5, GEN_PRED: 6 */ { /* LSF indices */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ /* ES pred */ - push_next_indice_fx( hBstr, hRF->rf_indx_EsPred[fec_offset], 3 ); + push_next_indice( hBstr, hRF->rf_indx_EsPred[fec_offset], 3 ); ltp_mode = ACELP_LTP_MODE[1][1][rf_frame_type]; /* Q0 */ ltf_mode = ACELP_LTF_MODE[1][1][rf_frame_type]; /* Q0 */ @@ -386,13 +386,13 @@ void enc_prm_rf_fx( n = ACELP_LTP_BITS_SFR[ltp_mode][sfr]; IF( n != 0 ) { - push_next_indice_fx( hBstr, hRF->rf_indx_pitch[fec_offset][sfr], n ); + push_next_indice( hBstr, hRF->rf_indx_pitch[fec_offset][sfr], n ); } /* Adaptive codebook filtering (1 bit) */ IF( EQ_16( ltf_mode, 2 ) ) { - push_next_indice_fx( hBstr, hRF->rf_indx_ltfMode[fec_offset][sfr], 1 ); + push_next_indice( hBstr, hRF->rf_indx_ltfMode[fec_offset][sfr], 1 ); } /*Innovative codebook*/ @@ -403,7 +403,7 @@ void enc_prm_rf_fx( ( EQ_16( rf_frame_type, RF_GENPRED ) && ( sfr == 0 || EQ_16( sfr, 2 ) ) ) ) { - push_next_indice_fx( hBstr, hRF->rf_indx_fcb[fec_offset][sfr], 7 ); + push_next_indice( hBstr, hRF->rf_indx_fcb[fec_offset][sfr], 7 ); } /* Gains (5b, 6b or 7b / subfr) */ @@ -411,11 +411,11 @@ void enc_prm_rf_fx( IF( sfr == 0 || EQ_16( sfr, 2 ) ) { n = ACELP_GAINS_BITS[gains_mode]; - push_next_indice_fx( hBstr, hRF->rf_indx_gain[fec_offset][sfr], n ); + push_next_indice( hBstr, hRF->rf_indx_gain[fec_offset][sfr], n ); } } /* tbe gainFr */ - push_next_indice_fx( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 2 ); + push_next_indice( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 2 ); } /***************/ @@ -429,15 +429,15 @@ void enc_prm_rf_fx( test(); IF( EQ_16( fec_offset, 2 ) ) { - push_next_indice_fx( hBstr, 0, 2 ); + push_next_indice( hBstr, 0, 2 ); } ELSE IF( EQ_16( fec_offset, 3 ) || EQ_16( fec_offset, 5 ) || EQ_16( fec_offset, 7 ) ) { - push_next_indice_fx( hBstr, ( fec_offset - 1 ) / 2, 2 ); + push_next_indice( hBstr, ( fec_offset - 1 ) / 2, 2 ); } /* write RF frame type last in the bitstream */ - push_next_indice_fx( hBstr, rf_frame_type, 3 ); + push_next_indice( hBstr, rf_frame_type, 3 ); } @@ -533,7 +533,7 @@ void enc_prm_fx( IF( st->tcxonly ) { - push_next_indice_fx( hBstr, core == TCX_10_CORE, 1 ); + push_next_indice( hBstr, core == TCX_10_CORE, 1 ); { index = 3; move16(); @@ -553,7 +553,7 @@ void enc_prm_fx( index = 2; move16(); } - push_next_indice_fx( hBstr, index, 2 ); + push_next_indice( hBstr, index, 2 ); } } ELSE @@ -581,13 +581,13 @@ void enc_prm_fx( { idx = add( idx, 1 ); /* Q0 */ } - push_next_indice_fx( hBstr, idx - start_idx, nBits ); - push_next_indice_fx( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ + push_next_indice( hBstr, idx - start_idx, nBits ); + push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ nbits_start = 3; /* Q0 */ } ELSE { - push_next_indice_fx( hBstr, coder_type, 3 ); + push_next_indice( hBstr, coder_type, 3 ); } } ELSE @@ -595,15 +595,15 @@ void enc_prm_fx( IF( EQ_16( st->mdct_sw, MODE1 ) ) { /* 2 bits instead of 3 as TCX is already signaled */ - push_next_indice_fx( hBstr, st->hTcxCfg->coder_type, 2 ); + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); } ELSE { IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) { - push_next_indice_fx( hBstr, 1, 1 ); /* TCX */ - push_next_indice_fx( hBstr, 0, 1 ); /* not HQ_CORE */ - push_next_indice_fx( hBstr, st->hTcxCfg->coder_type, 2 ); + push_next_indice( hBstr, 1, 1 ); /* TCX */ + push_next_indice( hBstr, 0, 1 ); /* not HQ_CORE */ + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); } ELSE { @@ -641,13 +641,13 @@ void enc_prm_fx( { idx = add( idx, 1 ); } - push_next_indice_fx( hBstr, idx - start_idx, nBits ); - push_next_indice_fx( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ + push_next_indice( hBstr, idx - start_idx, nBits ); + push_next_indice( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ nbits_start = 3; } ELSE { - push_next_indice_fx( hBstr, 4 + st->hTcxCfg->coder_type, 3 ); + push_next_indice( hBstr, 4 + st->hTcxCfg->coder_type, 3 ); } } } @@ -667,7 +667,7 @@ void enc_prm_fx( tmp = TCX_20_CORE; move16(); } - push_next_indice_fx( hBstr, tmp, 1 ); + push_next_indice( hBstr, tmp, 1 ); } /* write TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */ @@ -696,7 +696,7 @@ void enc_prm_fx( overlap_code = 0; move16(); } - push_next_indice_fx( hBstr, overlap_code, nbits_tcx ); + push_next_indice( hBstr, overlap_code, nbits_tcx ); } IF( st->hPlcExt->enableGplc ) @@ -719,7 +719,7 @@ void enc_prm_fx( IF( EQ_16( core, ACELP_CORE ) ) { - push_next_indice_fx( hBstr, st->glr_idx[0], G_LPC_RECOVERY_BITS ); + push_next_indice( hBstr, st->glr_idx[0], G_LPC_RECOVERY_BITS ); } } @@ -789,7 +789,7 @@ void enc_prm_fx( IF( n != 0 ) { - push_next_indice_fx( hBstr, st->bpf_gain_param, n ); + push_next_indice( hBstr, st->bpf_gain_param, n ); } /* Mean energy (2 or 3 bits) */ @@ -797,7 +797,7 @@ void enc_prm_fx( IF( n != 0 ) { - push_next_indice_fx( hBstr, prm[j++], n ); + push_next_indice( hBstr, prm[j++], n ); } /* Subframe parameters */ @@ -810,14 +810,14 @@ void enc_prm_fx( IF( n != 0 ) { - push_next_indice_fx( hBstr, prm[j++], n ); + push_next_indice( hBstr, prm[j++], n ); } /* Adaptive codebook filtering (1 bit) */ IF( EQ_16( st->acelp_cfg.ltf_mode, 2 ) ) { - push_next_indice_fx( hBstr, prm[j++], 1 ); + push_next_indice( hBstr, prm[j++], 1 ); } /*Innovative codebook*/ @@ -839,12 +839,12 @@ void enc_prm_fx( FOR( ix = 0; ix < wordcnt; ix++ ) { - push_next_indice_fx( hBstr, prm[j++], 16 ); + push_next_indice( hBstr, prm[j++], 16 ); } IF( bitcnt ) { - push_next_indice_fx( hBstr, prm[j++], bitcnt ); + push_next_indice( hBstr, prm[j++], bitcnt ); } j = add( j_old, 8 ); /* Q0 */ @@ -852,7 +852,7 @@ void enc_prm_fx( /* Gains (5b, 6b or 7b / subfr) */ n = ACELP_GAINS_BITS[st->acelp_cfg.gains_mode[sfr]]; - push_next_indice_fx( hBstr, prm[j++], n ); + push_next_indice( hBstr, prm[j++], n ); } /*end of for(sfr)*/ } /*end of mode[0]==0*/ @@ -866,14 +866,14 @@ void enc_prm_fx( move16(); IF( st->enablePlcWaveadjust ) { - push_next_indice_fx( hBstr, st->Tonal_SideInfo, 1 ); + push_next_indice( hBstr, st->Tonal_SideInfo, 1 ); } /* TCX Gain = 7 bits */ - push_next_indice_fx( hBstr, prm[j++], 7 ); + push_next_indice( hBstr, prm[j++], 7 ); /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ - push_next_indice_fx( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); + push_next_indice( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); /* LTP data */ test(); @@ -881,13 +881,13 @@ void enc_prm_fx( { IF( prm[j] ) { - push_next_indice_fx( hBstr, 1, 1 ); - push_next_indice_fx( hBstr, prm[j + 1], 9 ); - push_next_indice_fx( hBstr, prm[j + 2], 2 ); + push_next_indice( hBstr, 1, 1 ); + push_next_indice( hBstr, prm[j + 1], 9 ); + push_next_indice( hBstr, prm[j + 2], 2 ); } ELSE { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } } j = add( j, 3 ); @@ -932,7 +932,7 @@ void enc_prm_fx( test(); IF( st->hTcxCfg->ctx_hm && NE_16( last_core, ACELP_CORE ) ) { - push_next_indice_fx( hBstr, prm[j], 1 ); + push_next_indice( hBstr, prm[j], 1 ); IF( prm[j] ) { @@ -1015,14 +1015,14 @@ void enc_prm_fx( test(); IF( st->enablePlcWaveadjust && k ) { - push_next_indice_fx( hBstr, st->Tonal_SideInfo, 1 ); + push_next_indice( hBstr, st->Tonal_SideInfo, 1 ); } /* TCX Gain = 7 bits */ - push_next_indice_fx( hBstr, prm[j++], 7 ); + push_next_indice( hBstr, prm[j++], 7 ); /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ - push_next_indice_fx( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); + push_next_indice( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); /* LTP data */ test(); @@ -1031,13 +1031,13 @@ void enc_prm_fx( { IF( prm[j] ) { - push_next_indice_fx( hBstr, 1, 1 ); - push_next_indice_fx( hBstr, prm[j + 1], 9 ); - push_next_indice_fx( hBstr, prm[j + 2], 2 ); + push_next_indice( hBstr, 1, 1 ); + push_next_indice( hBstr, prm[j + 1], 9 ); + push_next_indice( hBstr, prm[j + 2], 2 ); } ELSE { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } } j = add( j, 3 ); @@ -1079,7 +1079,7 @@ void enc_prm_fx( test(); IF( st->hTcxCfg->ctx_hm && !( last_core == ACELP_CORE && k == 0 ) ) { - push_next_indice_fx( hBstr, prm[j], 1 ); + push_next_indice( hBstr, prm[j], 1 ); IF( prm[j] ) { diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index c86b7e061..396e97c6f 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -419,7 +419,7 @@ ivas_error evs_enc_fx( FOR( i = 0; i < padBits; i++ ) { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } } @@ -678,19 +678,19 @@ static void writeFrameHeader_loc( Encoder_State *st ) IF( EQ_16( st->cng_type, FD_CNG ) ) { /* write SID/CNG type flag */ - push_next_indice_fx( hBstr, 1, 1 ); + push_next_indice( hBstr, 1, 1 ); /* write bandwidth mode */ - push_next_indice_fx( hBstr, st->bwidth, 2 ); + push_next_indice( hBstr, st->bwidth, 2 ); /* write L_frame */ IF( EQ_16( st->L_frame, L_FRAME ) ) { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } ELSE { - push_next_indice_fx( hBstr, 1, 1 ); + push_next_indice( hBstr, 1, 1 ); } } } @@ -698,7 +698,7 @@ static void writeFrameHeader_loc( Encoder_State *st ) { IF( st->rf_mode == 0 ) { - push_next_indice_fx( hBstr, sub( st->bwidth, FrameSizeConfig[st->frame_size_index].bandwidth_min ), FrameSizeConfig[st->frame_size_index].bandwidth_bits ); + push_next_indice( hBstr, sub( st->bwidth, FrameSizeConfig[st->frame_size_index].bandwidth_min ), FrameSizeConfig[st->frame_size_index].bandwidth_bits ); } } @@ -706,7 +706,7 @@ static void writeFrameHeader_loc( Encoder_State *st ) test(); IF( FrameSizeConfig[st->frame_size_index].reserved_bits && st->rf_mode == 0 ) { - push_next_indice_fx( hBstr, 0, FrameSizeConfig[st->frame_size_index].reserved_bits ); + push_next_indice( hBstr, 0, FrameSizeConfig[st->frame_size_index].reserved_bits ); } } diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 2eb13646c..d182e4a44 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1211,9 +1211,9 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru { FOR( i = 0; i < stages_37bits; i++ ) { - push_next_indice_fx( hBstr, indices[i], bits_37bits[i] ); + push_next_indice( hBstr, indices[i], bits_37bits[i] ); } - push_next_indice_fx( hBstr, index, 7 ); + push_next_indice( hBstr, index, 7 ); } ELSE { diff --git a/lib_enc/guided_plc_enc_fx.c b/lib_enc/guided_plc_enc_fx.c index 60a3f8f50..81e50d099 100644 --- a/lib_enc/guided_plc_enc_fx.c +++ b/lib_enc/guided_plc_enc_fx.c @@ -215,7 +215,7 @@ void enc_prm_side_Info_fx( IF( GT_16( hPlc_Ext->nBits, 1 ) ) { - push_next_indice_fx( st->hBstr, 1, 1 ); + push_next_indice( st->hBstr, 1, 1 ); diff_pitch = sub( hPlc_Ext->T0, hPlc_Ext->T0_4th ); test(); @@ -225,11 +225,11 @@ void enc_prm_side_Info_fx( move16(); } - push_next_indice_fx( st->hBstr, add( diff_pitch, search_range ), bits_per_subfr ); + push_next_indice( st->hBstr, add( diff_pitch, search_range ), bits_per_subfr ); } ELSE { - push_next_indice_fx( st->hBstr, 0, 1 ); + push_next_indice( st->hBstr, 0, 1 ); } return; diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index cc4840876..f5c13df57 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1513,13 +1513,13 @@ Word16 IGFEncWriteConcatenatedBitstream_fx( tmp = shr( hPrivateData->igfBitstreamBits, 3 ); FOR( i = 0; i < tmp; i++ ) { - push_next_indice_fx( hBstr, pBitstream[i], 8 ); + push_next_indice( hBstr, pBitstream[i], 8 ); } bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 ); IF( bitsLeft > 0 ) { - push_next_indice_fx( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); + push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); } return hInstance->infoTotalBitsWritten; diff --git a/lib_enc/igf_scf_enc_fx.c b/lib_enc/igf_scf_enc_fx.c index 8659d53a1..ed52349dc 100644 --- a/lib_enc/igf_scf_enc_fx.c +++ b/lib_enc/igf_scf_enc_fx.c @@ -358,7 +358,7 @@ Word16 IGFSCFEncoderEncode_fx( { FOR( i = 0; i < hPublicData->ptrBitIndex; ++i ) { - push_next_indice_fx( hBstr, ptr[i], 1 ); + push_next_indice( hBstr, ptr[i], 1 ); } } diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index aa2255c68..8f6a21d03 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -834,7 +834,7 @@ Word16 enc_lsf_tcxlpc_fx( move16(); FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i ) { - push_next_indice_fx( hBstr, **indices, lsf_numbits[i] ); + push_next_indice( hBstr, **indices, lsf_numbits[i] ); ++*indices; } @@ -843,7 +843,7 @@ Word16 enc_lsf_tcxlpc_fx( NumBits = add( NumBits, TCXLPC_IND_NUMBITS ); FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i ) { - push_next_indice_fx( hBstr, **indices, lsf_ind_numbits[i] ); + push_next_indice( hBstr, **indices, lsf_ind_numbits[i] ); ++*indices; } } @@ -909,7 +909,7 @@ Word16 lsf_msvq_ma_encprm_fx( FOR( i = 0; i < no_indices; i++ ) { - push_next_indice_fx( hBstr, *param_lpc, bits_param_lpc[i] ); + push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] ); param_lpc++; nbits_lpc = add( nbits_lpc, bits_param_lpc[i] ); } @@ -919,7 +919,7 @@ Word16 lsf_msvq_ma_encprm_fx( IF( ( core == ACELP_CORE ) && acelp_midLpc ) { - push_next_indice_fx( hBstr, *param_lpc, bits_midlpc ); + push_next_indice( hBstr, *param_lpc, bits_midlpc ); nbits_lpc = add( nbits_lpc, bits_midlpc ); } } @@ -981,7 +981,7 @@ Word16 lsf_bctcvq_encprm_fx( FOR( i = 0; i < no_indices; i++ ) { - push_next_indice_fx( hBstr, *param_lpc, bits_param_lpc[i] ); + push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] ); param_lpc++; nbits_lpc = add( nbits_lpc, bits_param_lpc[i] ); } diff --git a/lib_enc/qlpc_avq_fx.c b/lib_enc/qlpc_avq_fx.c index 13e0a3cf7..288612e43 100644 --- a/lib_enc/qlpc_avq_fx.c +++ b/lib_enc/qlpc_avq_fx.c @@ -143,12 +143,12 @@ static Word16 unary_code( FOR( ; ind > 0; ind-- ) { - push_next_indice_fx( hBstr, 1, 1 ); + push_next_indice( hBstr, 1, 1 ); nb_bits = add( nb_bits, 1 ); // Q0 } /* Stop bit */ - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); return ( nb_bits ); } @@ -195,7 +195,7 @@ static Word16 unpack4bits( IF( nbits == 0 ) { - push_next_indice_fx( hBstr, 0, 0 ); + push_next_indice( hBstr, 0, 0 ); i = 1; move16(); } @@ -206,10 +206,10 @@ static Word16 unpack4bits( FOR( ; nbits > 4; nbits -= 4 ) { - push_next_indice_fx( hBstr, prm[i], 4 ); + push_next_indice( hBstr, prm[i], 4 ); i = add( i, 1 ); } - push_next_indice_fx( hBstr, prm[i], nbits ); + push_next_indice( hBstr, prm[i], nbits ); i = add( i, 1 ); } @@ -330,7 +330,7 @@ Word16 encode_lpc_avq_fx( { nb = 1; move16(); - push_next_indice_fx( hBstr, q_type, nb ); + push_next_indice( hBstr, q_type, nb ); } nb_bits = add( nb_bits, nb ); // Q0 @@ -342,7 +342,7 @@ Word16 encode_lpc_avq_fx( IF( ( ( q_type == 0 ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) || ( ( q_type == 0 ) && ( GE_16( st1, 0 ) ) && EQ_16( element_mode, IVAS_CPE_MDCT ) ) ) { /* Absolute quantizer with 1st stage stochastic codebook */ - push_next_indice_fx( hBstr, st1, bits_for_abs_quant ); + push_next_indice( hBstr, st1, bits_for_abs_quant ); nb_bits = add( nb_bits, bits_for_abs_quant ); // Q0 } @@ -350,7 +350,7 @@ Word16 encode_lpc_avq_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && EQ_16( stereo_mode, 3 ) && st1 < 0 ) { - push_next_indice_fx( hBstr, add( st1, 2 ), 1 ); + push_next_indice( hBstr, add( st1, 2 ), 1 ); nb_bits = add( nb_bits, 1 ); // Q0 } @@ -368,7 +368,7 @@ Word16 encode_lpc_avq_fx( move16(); i = 3; } - push_next_indice_fx( hBstr, i, 2 ); + push_next_indice( hBstr, i, 2 ); i = sub( qn2, 2 ); @@ -377,7 +377,7 @@ Word16 encode_lpc_avq_fx( move16(); i = 3; } - push_next_indice_fx( hBstr, i, 2 ); + push_next_indice( hBstr, i, 2 ); /* Unary code for abs and rel LPC0/LPC2 */ /* Q5 = 0, Q6=10, Q0=110, Q7=1110, ... */ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 1a14e7acb..316a5b549 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7579,10 +7579,10 @@ void tbe_write_bitstream_fx( IF( ( st_fx->rf_mode || EQ_32( st_fx->total_brate, ACELP_9k60 ) ) && ( EQ_16( st_fx->bwidth, WB ) ) ) { /* WB LSF */ - push_next_indice_fx( hBstr, hBWE_TD->lsf_WB, NUM_BITS_LBR_WB_LSF ); + push_next_indice( hBstr, hBWE_TD->lsf_WB, NUM_BITS_LBR_WB_LSF ); /* WB frame */ - push_next_indice_fx( hBstr, hBWE_TD->gFrame_WB, NUM_BITS_SHB_FrameGain_LBR_WB ); + push_next_indice( hBstr, hBWE_TD->gFrame_WB, NUM_BITS_SHB_FrameGain_LBR_WB ); } ELSE IF( ( GE_32( st_fx->total_brate, ACELP_9k60 ) ) && ( LE_32( st_fx->total_brate, ACELP_32k ) ) && ( ( EQ_16( st_fx->bwidth, SWB ) ) || ( EQ_16( st_fx->bwidth, FB ) ) ) ) @@ -7592,53 +7592,53 @@ void tbe_write_bitstream_fx( test(); IF( ( EQ_16( st_fx->rf_mode, 1 ) ) || EQ_32( st_fx->total_brate, ACELP_9k60 ) ) { - push_next_indice_fx( hBstr, hBWE_TD->lsf_idx[0], 8 ); + push_next_indice( hBstr, hBWE_TD->lsf_idx[0], 8 ); } ELSE { FOR( i = 0; i < NUM_Q_LSF; i++ ) { - push_next_indice_fx( hBstr, hBWE_TD->lsf_idx[i], lsf_q_num_bits[i] ); + push_next_indice( hBstr, hBWE_TD->lsf_idx[i], lsf_q_num_bits[i] ); } /* LSF mirror points */ - push_next_indice_fx( hBstr, hBWE_TD->m_idx, MIRROR_POINT_BITS ); + push_next_indice( hBstr, hBWE_TD->m_idx, MIRROR_POINT_BITS ); /* LSF grid points */ - push_next_indice_fx( hBstr, hBWE_TD->grid_idx, NUM_LSF_GRID_BITS ); + push_next_indice( hBstr, hBWE_TD->grid_idx, NUM_LSF_GRID_BITS ); } /* Gain shape */ - push_next_indice_fx( hBstr, hBWE_TD->idxSubGains, NUM_BITS_SHB_SUBGAINS ); + push_next_indice( hBstr, hBWE_TD->idxSubGains, NUM_BITS_SHB_SUBGAINS ); /* frame gain */ - push_next_indice_fx( hBstr, hBWE_TD->idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); + push_next_indice( hBstr, hBWE_TD->idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); IF( GE_32( st_fx->total_brate, ACELP_24k40 ) ) { /* sub frame energy*/ - push_next_indice_fx( hBstr, hBWE_TD->idx_shb_fr_gain, NUM_BITS_SHB_ENER_SF ); + push_next_indice( hBstr, hBWE_TD->idx_shb_fr_gain, NUM_BITS_SHB_ENER_SF ); /* gain shapes residual */ FOR( i = 0; i < NB_SUBFR16k; i++ ) { - push_next_indice_fx( hBstr, hBWE_TD->idx_res_gs[i], NUM_BITS_SHB_RES_GS ); + push_next_indice( hBstr, hBWE_TD->idx_res_gs[i], NUM_BITS_SHB_RES_GS ); } /* voicing factor */ - push_next_indice_fx( hBstr, hBWE_TD->idx_mixFac, NUM_BITS_SHB_VF ); + push_next_indice( hBstr, hBWE_TD->idx_mixFac, NUM_BITS_SHB_VF ); } IF( EQ_16( st_fx->tec_tfa, 1 ) ) { - push_next_indice_fx( hBstr, st_fx->tec_flag, BITS_TEC ); - push_next_indice_fx( hBstr, st_fx->tfa_flag, BITS_TFA ); + push_next_indice( hBstr, st_fx->tec_flag, BITS_TEC ); + push_next_indice( hBstr, st_fx->tfa_flag, BITS_TFA ); } } IF( EQ_16( st_fx->bwidth, FB ) ) { - push_next_indice_fx( hBstr, hBWE_TD->idxGain, 4 ); + push_next_indice( hBstr, hBWE_TD->idxGain, 4 ); } } -- GitLab From 9591d921755e6f02cc087afadbf0b16082dbec60 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 15:03:51 -0400 Subject: [PATCH 0705/1221] replace other EVS bitstream related stuff --- lib_com/bitstream_fx.c | 9 ++++++--- lib_enc/ACcontextMapping_enc_fx.c | 6 +++--- lib_enc/enc_prm_fx.c | 2 +- lib_enc/igf_enc.c | 4 ++-- lib_enc/igf_enc_fx.c | 4 ++-- lib_enc/lib_enc.c | 2 ++ lib_enc/tcx_utils_enc_fx.c | 26 +++++++++++++++++++++----- 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 8cb968bf1..d3aab2616 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -314,11 +314,10 @@ void push_next_indice_fx( return; } -#endif /*-------------------------------------------------------------------* - * push_next_bits_fx() + * push_next_bits() * Push a bit buffer into the buffer at the next position *-------------------------------------------------------------------*/ @@ -368,6 +367,7 @@ void push_next_bits_fx( hBstr->nb_bits_tot = add( hBstr->nb_bits_tot, nb_bits ); move16(); } +#endif /*-------------------------------------------------------------------* * get_next_indice_fx( ) @@ -565,6 +565,7 @@ void reset_indices_dec_fx( * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ +#if 0 void write_indices_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ @@ -663,12 +664,13 @@ void write_indices_fx( return; } +#endif /*-------------------------------------------------------------------* * write_indices_buf_fx() * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ - +#if 0 void write_indices_buf_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ @@ -772,6 +774,7 @@ void write_indices_buf_fx( return; } +#endif /*-------------------------------------------------------------------* * indices_to_serial() * diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 4e02b1f11..43bd30fd4 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -346,10 +346,10 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( push_next_indice( hBstr, value, nbbits_ntuples ); /* Push arithmetic coded bits */ - push_next_bits_fx( hBstr, &ptr[nbbits_ntuples], sub( bp, nbbits_ntuples ) ); + push_next_bits( hBstr, (UWord16 *) &ptr[nbbits_ntuples], sub( bp, nbbits_ntuples ) ); /* Push sign bits */ - push_next_bits_fx( hBstr, signs, nbbits_signs ); + push_next_bits( hBstr, (UWord16 *) signs, nbbits_signs ); bp = add( bp, nbbits_signs ); /* Q0 */ /*write residual Quantization bits*/ @@ -372,7 +372,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( assert( bp + k <= nbbits ); /* Push the rest of the buffer */ - push_next_bits_fx( hBstr, &ptr[bp], sub( nbbits, bp ) ); + push_next_bits( hBstr, (UWord16 *) &ptr[bp], sub( nbbits, bp ) ); return /*(bp+nbbits_lsbs)*/; /*return only for debug plot*/ } diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index 6c052e596..1d619e6c5 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -965,7 +965,7 @@ void enc_prm_fx( IF( hTcxEnc->tcx_lpc_shaped_ari != 0 ) { - push_next_bits_fx( hBstr, &prm[++j], nbits_tcx ); + push_next_bits( hBstr, ( UWord16 * ) &prm[++j], nbits_tcx ); j = add( j, nbits_tcx ); /* Q0 */ } ELSE diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 2680bd9f6..d0c9fa329 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2429,7 +2429,7 @@ void IGFEncSetMode_ivas_fx( * * IGF bitstream concatenation for TCX10 modes *-------------------------------------------------------------------*/ - +#if 0 /* Float code */ void IGFEncConcatenateBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ const Word16 bsBits, /* i : number of IGF bits written to list of indices */ @@ -2487,7 +2487,7 @@ move16(); return; } - +#endif /*-------------------------------------------------------------------* * IGFEncResetTCX10BitCounter_ivas_fx() diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index f5c13df57..a8a64422f 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1449,7 +1449,7 @@ hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); return; } - +#if 0 /* old bitstream */ /**********************************************************************/ /* IGF bitsream concatenation for TCX10 modes **************************************************************************/ @@ -1475,7 +1475,7 @@ void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /** move16(); return; } - +#endif /**********************************************************************/ /* IGF reset bitsream bit counter for TCX10 modes **************************************************************************/ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 877fc2045..b17ba61df 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1892,6 +1892,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } /* write indices into bitstream buffer */ +#if 0 IF( hEncoderConfig->element_mode_init == EVS_MONO ) { test(); @@ -1905,6 +1906,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } } ELSE +#endif { write_indices_ivas_fx( st_ivas, outputBitStream, numOutBits ); } diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 7d268b92a..fd6293124 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3650,7 +3650,7 @@ Word16 tcx_res_Q_spec_ivas_fx( return bits; } - +#if 1 //TV void ProcessIGF_fx( IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */ Encoder_State *st, /**< in: Encoder state */ @@ -3667,8 +3667,9 @@ void ProcessIGF_fx( Word16 igfGridIdx; Word16 isIndepFlag; Word16 bsBits; - Word16 bsStart; + Word16 bsStart, pBsStart; BSTR_ENC_HANDLE hBstr = st->hBstr; + IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc; isIndepFlag = 1; @@ -3721,6 +3722,8 @@ void ProcessIGF_fx( Word16 Q_A; Word16 predictionGain = 0; Word16 *flatteningTrigger = &( st->hIGFEnc->flatteningTrigger ); + + move32(); move16(); move16(); @@ -3750,6 +3753,7 @@ void ProcessIGF_fx( { IGFEncWriteBitstream_fx( hInstance, NULL, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } +#if 0 ELSE { IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); @@ -3760,8 +3764,20 @@ void ProcessIGF_fx( { IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot, hBstr->ind_list ); } -} +#else + ELSE + { + pBsStart = hBstr->nb_ind_tot; + move16(); + + IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); + bsBits = sub( hBstr->nb_ind_tot, pBsStart ); + IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr ); + } +#endif +} + #endif void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) { Word16 i, length, att; @@ -3877,7 +3893,7 @@ void ProcessIGF_ivas_fx( IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); bsBits = sub( hBstr->nb_ind_tot, pBsStart ); - IGFEncConcatenateBitstream( hIGFEnc, bsBits, hBstr ); + IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr ); } return; @@ -3981,7 +3997,7 @@ void ProcessStereoIGF_fx( IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); bsBits = sub( hBstr->nb_ind_tot, pBsStart ); - IGFEncConcatenateBitstream( hIGFEnc[ch], bsBits, hBstr ); + IGFEncConcatenateBitstream_ivas_fx( hIGFEnc[ch], bsBits, hBstr ); } } return; -- GitLab From bb876b28b8dbda2b645171bb99f8c5877501f058 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 15:06:06 -0400 Subject: [PATCH 0706/1221] fix clang --- lib_com/bitstream_fx.c | 2 +- lib_enc/enc_prm_fx.c | 4 ++-- lib_enc/tcx_utils_enc_fx.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index d3aab2616..f0e564a8a 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -664,7 +664,7 @@ void write_indices_fx( return; } -#endif +#endif /*-------------------------------------------------------------------* * write_indices_buf_fx() * diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index 1d619e6c5..6d6a2d575 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -583,7 +583,7 @@ void enc_prm_fx( } push_next_indice( hBstr, idx - start_idx, nBits ); push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ - nbits_start = 3; /* Q0 */ + nbits_start = 3; /* Q0 */ } ELSE { @@ -965,7 +965,7 @@ void enc_prm_fx( IF( hTcxEnc->tcx_lpc_shaped_ari != 0 ) { - push_next_bits( hBstr, ( UWord16 * ) &prm[++j], nbits_tcx ); + push_next_bits( hBstr, (UWord16 *) &prm[++j], nbits_tcx ); j = add( j, nbits_tcx ); /* Q0 */ } ELSE diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index fd6293124..06de6a2fa 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3650,7 +3650,7 @@ Word16 tcx_res_Q_spec_ivas_fx( return bits; } -#if 1 //TV +#if 1 // TV void ProcessIGF_fx( IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */ Encoder_State *st, /**< in: Encoder state */ @@ -3777,7 +3777,7 @@ void ProcessIGF_fx( } #endif } - #endif +#endif void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) { Word16 i, length, att; -- GitLab From 2aa5710dacbe699f30781227bfbf45088225bf6d Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 15:13:41 -0400 Subject: [PATCH 0707/1221] fix clang --- lib_enc/tcx_utils_enc_fx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 06de6a2fa..ec1db2cf3 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3667,7 +3667,11 @@ void ProcessIGF_fx( Word16 igfGridIdx; Word16 isIndepFlag; Word16 bsBits; +#if 0 Word16 bsStart, pBsStart; +#else + Word16 pBsStart; +#endif BSTR_ENC_HANDLE hBstr = st->hBstr; IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc; @@ -3744,8 +3748,9 @@ void ProcessIGF_fx( } } +#if 0 bsStart = hBstr->next_ind_fx; - +#endif move16(); hInstance->infoTotalBitsPerFrameWritten = 0; move16(); -- GitLab From 8f109c520aa15d566107d3273893c11c30b52a1d Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 26 Mar 2025 09:06:17 -0400 Subject: [PATCH 0708/1221] work on encoder config duplication --- lib_enc/ivas_init_enc_fx.c | 46 ++++++++++++++++++-------------------- lib_enc/lib_enc.c | 10 ++++++--- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 57858b03e..19996e2e4 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -463,7 +463,7 @@ void ivas_initialize_handles_enc_fx( * * Initialize IVAS encoder state structure *-------------------------------------------------------------------*/ - +#if 0 ivas_error ivas_init_encoder( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -1073,6 +1073,7 @@ ivas_error ivas_init_encoder( } return error; } +#endif ivas_error ivas_init_encoder_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -1100,10 +1101,10 @@ ivas_error ivas_init_encoder_fx( hEncoderConfig->last_ivas_total_brate = ivas_total_brate; /* Q0 */ move32(); - IF( NE_16( ivas_format, MONO_FORMAT ) ) + if ( NE_16( ivas_format, MONO_FORMAT ) ) { /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = extract_l( L_max( hEncoderConfig->max_bwidth, WB ) ); /* Q0 */ + hEncoderConfig->max_bwidth = s_max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ move16(); } st_ivas->ism_mode = ISM_MODE_NONE; @@ -1142,7 +1143,10 @@ ivas_error ivas_init_encoder_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point input audio buffer!\n" ) ); } + set32_fx( st_ivas->p_data_fx[n], 0, extract_l( Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); } + st_ivas->q_data_fx = Q11; + move16(); FOR( ; n < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { st_ivas->p_data_fx[n] = NULL; @@ -1196,7 +1200,7 @@ ivas_error ivas_init_encoder_fx( /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ - test(); + IF( EQ_32( ivas_format, MONO_FORMAT ) ) { st_ivas->nSCE = 1; /* in mono, there is always only one SCE */ @@ -1209,19 +1213,9 @@ ivas_error ivas_init_encoder_fx( move16(); test(); - IF( st_ivas->hEncoderConfig->element_mode_init == EVS_MONO ) + IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { - IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - ELSE - { - IF( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } /* prepare stereo downmix for EVS */ @@ -1342,7 +1336,7 @@ ivas_error ivas_init_encoder_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { - IF( hEncoderConfig->Opt_DTX_ON ) + if ( hEncoderConfig->Opt_DTX_ON ) { st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 1; move16(); @@ -1350,7 +1344,7 @@ ivas_error ivas_init_encoder_fx( } } - IF( st_ivas->nCPE > 1 ) + IF( GT_16( st_ivas->nCPE, 1 ) ) { IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { @@ -1358,7 +1352,7 @@ ivas_error ivas_init_encoder_fx( } } } - ELSE IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) ) + ELSE IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { Word32 ism_total_brate; Word16 k; @@ -1428,12 +1422,12 @@ ivas_error ivas_init_encoder_fx( ELSE IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) ) { st_ivas->ism_mode = ISM_MODE_NONE; - move32(); + move16(); IF( GE_32( ivas_total_brate, IVAS_256k ) ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; - move32(); + move16(); } IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) @@ -1523,7 +1517,7 @@ ivas_error ivas_init_encoder_fx( return error; } - IF( NE_32( st_ivas->mc_mode, MC_MODE_MCT ) ) + IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) ) { st_ivas->nSCE = 0; move16(); @@ -1596,7 +1590,9 @@ ivas_error ivas_init_encoder_fx( FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nCPE + st_ivas->nSCE ) ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nCPE, st_ivas->nSCE ), &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, res_dec ) ) != IVAS_ERR_OK ) { return error; } @@ -1658,7 +1654,9 @@ ivas_error ivas_init_encoder_fx( *-----------------------------------------------------------------*/ /* set number of input channels used for analysis/coding */ - n = getNumChanAnalysis_fx( st_ivas ); + n = getNumChanAnalysis_fx( st_ivas ); /* Q0 */ + move16(); + IF( n > 0 ) { IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL ) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index b17ba61df..52734b4bd 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -70,7 +70,7 @@ struct IVAS_ENC * Local functions *---------------------------------------------------------------------*/ -static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +//static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error setBandwidth_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_BANDWIDTH maxBandwidth ); static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); @@ -609,6 +609,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( return error; } +#if 0 ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const Word32 inputFs, /* i : input sampling frequency */ @@ -649,11 +650,12 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( hIvasEnc->maxBandwidthUser = max_bwidth_user; - error = configureEncoder_fx( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() ); + error = configureEncoder( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() ); return error; } +#endif /*---------------------------------------------------------------------* * IVAS_ENC_ConfigureForSBAObjects() * @@ -1188,7 +1190,7 @@ static ivas_error configureEncoder( * Finalize initialization *-----------------------------------------------------------------*/ - IF( ( error = ivas_init_encoder( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_init_encoder_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1211,6 +1213,7 @@ static ivas_error configureEncoder( return error; } +#if 0 static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, @@ -1543,6 +1546,7 @@ static ivas_error configureEncoder_fx( return error; } +#endif /*---------------------------------------------------------------------* * IVAS_ENC_GetDelay() * -- GitLab From 1597e6dd757408df3772eacb2b4266524045a8d1 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 26 Mar 2025 13:46:47 -0400 Subject: [PATCH 0709/1221] Addition of compiler switch, code compiles and run, but not BE --- lib_com/bitstream_fx.c | 7 +++--- lib_com/options.h | 2 ++ lib_enc/igf_enc.c | 2 +- lib_enc/igf_enc_fx.c | 2 +- lib_enc/init_enc_fx.c | 48 ++++++++++++++++++++++++++++---------- lib_enc/ivas_init_enc_fx.c | 7 +++--- lib_enc/ivas_sce_enc_fx.c | 27 +++++++++++++++++---- lib_enc/lib_enc.c | 6 ++--- lib_enc/tcx_utils_enc_fx.c | 6 ++--- 9 files changed, 76 insertions(+), 31 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index f0e564a8a..f29dc6aee 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -244,7 +244,7 @@ Word16 rate2EVSmode( * * Push a new indice into the buffer *-------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_PUSH_BIT void push_indice_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ Word16 id, /* i : ID of the indice */ @@ -565,8 +565,7 @@ void reset_indices_dec_fx( * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ -#if 0 - +#ifndef HARM_PUSH_BIT void write_indices_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ @@ -670,7 +669,7 @@ void write_indices_fx( * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_PUSH_BIT void write_indices_buf_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ diff --git a/lib_com/options.h b/lib_com/options.h index 2133b86ac..183edaa71 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -75,4 +75,6 @@ /* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +#define HARM_PUSH_BIT +#define HARM_ENC_INIT #endif diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index d0c9fa329..c8e8974c2 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2429,7 +2429,7 @@ void IGFEncSetMode_ivas_fx( * * IGF bitstream concatenation for TCX10 modes *-------------------------------------------------------------------*/ -#if 0 /* Float code */ +#ifndef HARM_PUSH_BIT /* Float code */ void IGFEncConcatenateBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ const Word16 bsBits, /* i : number of IGF bits written to list of indices */ diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index a8a64422f..96f8d0202 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1449,7 +1449,7 @@ hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); return; } -#if 0 /* old bitstream */ +#ifndef HARM_PUSH_BIT /* old bitstream */ /**********************************************************************/ /* IGF bitsream concatenation for TCX10 modes **************************************************************************/ diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index ea944dd75..4913e410d 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -20,6 +20,7 @@ * * Initialization of state variables *-----------------------------------------------------------------------*/ +#if 1 ivas_error init_encoder_fx( Encoder_State *st_fx /* i/o: Encoder static variables structure */ ) @@ -946,6 +947,7 @@ ivas_error init_encoder_fx( move32(); return error; } +#endif /*-----------------------------------------------------------------------* * LPDmem_enc_init_fx() * @@ -1498,14 +1500,7 @@ ivas_error init_encoder_ivas_fx( IF( st->element_mode == EVS_MONO ) { /* This is done to as in EVS T_CldfbVadState structure is present in Encoder State */ - /* - if ( ( st->hVAD_CLDFB = (VAD_CLDFB_HANDLE) malloc( sizeof( T_CldfbVadState ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB VAD\n" ) ); - } - */ st->hVAD_CLDFB = &st->vad_st; - vad_init_fx( st->hVAD_CLDFB ); } ELSE @@ -1670,9 +1665,23 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + IF( EQ_16( st->element_mode, EVS_MONO ) ) { - return error; + /* open analysis for input SR */ + st->input_frame_fx = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); + + if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, CLDFB_getNumChannels( st->input_Fs ), st->input_frame_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + { + return error; + } } } ELSE @@ -1784,11 +1793,20 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + IF( st->element_mode == EVS_MONO ) { - return error; + if ( ( error = openCldfb( &st->cldfbSynTd, CLDFB_SYNTHESIS, CLDFB_getNumChannels( 16000 ), L_FRAME16k ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + { + return error; + } } - InitSWBencBuffer_ivas_fx( st ); ResetSHBbuffer_Enc_fx( st ); } @@ -2144,7 +2162,13 @@ ivas_error init_encoder_ivas_fx( } ELSE { +#ifndef HARM_ENC_INIT InitTransientDetection_ivas_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); +#else + InitTransientDetection_fx( extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ), + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), + &st->transientDetection ); +#endif } /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 19996e2e4..7c72d4780 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -269,7 +269,7 @@ Word16 getNumChanAnalysis_fx( return n; } - +#ifndef HARM_ENC_INIT /*-------------------------------------------------------------------* * copy_encoder_config_ivas_fx() * @@ -321,6 +321,7 @@ void copy_encoder_config_ivas_fx( return; } +#endif /*-------------------------------------------------------------------* * copy_encoder_config_fx() * @@ -463,7 +464,7 @@ void ivas_initialize_handles_enc_fx( * * Initialize IVAS encoder state structure *-------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_ENC_INIT ivas_error ivas_init_encoder( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -1213,7 +1214,7 @@ ivas_error ivas_init_encoder_fx( move16(); test(); - IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index f1631ba4f..3f80cce2b 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -466,12 +466,31 @@ ivas_error create_sce_enc_fx( st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; move32(); move32(); - + st->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; + st->input_Fs = st_ivas->hEncoderConfig->input_Fs; + st->input_frame_fx = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); +#if 0 + IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) + //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) + //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) { return error; } - hSCE->hCoreCoder[0] = st; + //IF( NE_32( ( error = init_encoder_fx( st) ), IVAS_ERR_OK ) ) + //{ + // return error; + //} + + //st->hBstr->ind_list = ind_list; + // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; + //reset_indices_enc_fx( st->hBstr, MAX_NUM_INDICES ); +#endif + hSCE->hCoreCoder[0] = st; st_ivas->hSCE[sce_id] = hSCE; @@ -483,7 +502,7 @@ ivas_error create_sce_enc_fx( * * Create, allocate and initialize EVS encoder SCE handle *-------------------------------------------------------------------------*/ - +#if 0 ivas_error create_evs_sce_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 sce_id, /* i : SCE # identifier */ @@ -614,7 +633,7 @@ ivas_error create_evs_sce_enc_fx( return error; } - +#endif /*------------------------------------------------------------------------- * destroy_sce_enc_fx() * diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 52734b4bd..fdf410df5 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -609,7 +609,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( return error; } -#if 0 +#ifndef HARM_ENC_INIT ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const Word32 inputFs, /* i : input sampling frequency */ @@ -1213,7 +1213,7 @@ static ivas_error configureEncoder( return error; } -#if 0 +#ifndef HARM_ENC_INIT static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, @@ -1896,7 +1896,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } /* write indices into bitstream buffer */ -#if 0 +#ifndef HARM_PUSH_BIT IF( hEncoderConfig->element_mode_init == EVS_MONO ) { test(); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index ec1db2cf3..5bea901bb 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3667,7 +3667,7 @@ void ProcessIGF_fx( Word16 igfGridIdx; Word16 isIndepFlag; Word16 bsBits; -#if 0 +#ifndef HARM_PUSH_BIT Word16 bsStart, pBsStart; #else Word16 pBsStart; @@ -3748,7 +3748,7 @@ void ProcessIGF_fx( } } -#if 0 +#ifndef HARM_PUSH_BIT bsStart = hBstr->next_ind_fx; #endif move16(); @@ -3758,7 +3758,7 @@ void ProcessIGF_fx( { IGFEncWriteBitstream_fx( hInstance, NULL, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } -#if 0 +#ifndef HARM_PUSH_BIT ELSE { IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); -- GitLab From c100d602b808183aea6cca0f0ccdf47db47b89e2 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 26 Mar 2025 14:08:20 -0400 Subject: [PATCH 0710/1221] fix BE issue, still crashed mid-file --- lib_com/options.h | 1 + lib_enc/ivas_init_enc_fx.c | 10 ++++++++-- lib_enc/ivas_sce_enc_fx.c | 41 +++++++++++++++++++++----------------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 183edaa71..4653bb460 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -77,4 +77,5 @@ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #define HARM_PUSH_BIT #define HARM_ENC_INIT +//#define HARM_SCE_INIT #endif diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 7c72d4780..04b99f039 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -1212,13 +1212,19 @@ ivas_error ivas_init_encoder_fx( move16(); sce_id = 0; move16(); - +#ifndef HARM_SCE_INIT + test(); + IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else test(); IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { return error; } - +#endif /* prepare stereo downmix for EVS */ IF( EQ_16( hEncoderConfig->stereo_dmx_evs, 1 ) ) { diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 3f80cce2b..2e1aed092 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -469,27 +469,11 @@ ivas_error create_sce_enc_fx( st->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; st->input_Fs = st_ivas->hEncoderConfig->input_Fs; st->input_frame_fx = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); -#if 0 - IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) - //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) - { - return error; - } -#else + IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) - //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) { return error; } - //IF( NE_32( ( error = init_encoder_fx( st) ), IVAS_ERR_OK ) ) - //{ - // return error; - //} - - //st->hBstr->ind_list = ind_list; - // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; - //reset_indices_enc_fx( st->hBstr, MAX_NUM_INDICES ); -#endif hSCE->hCoreCoder[0] = st; st_ivas->hSCE[sce_id] = hSCE; @@ -502,7 +486,7 @@ ivas_error create_sce_enc_fx( * * Create, allocate and initialize EVS encoder SCE handle *-------------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_SCE_INIT ivas_error create_evs_sce_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 sce_id, /* i : SCE # identifier */ @@ -624,9 +608,30 @@ ivas_error create_evs_sce_enc_fx( { return error; } +#ifdef HARM_PUSH_BIT + /*-----------------------------------------------------------------* + * Bitstream + *-----------------------------------------------------------------*/ + IF( ( st_fx->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); + } + + /* set pointer to the buffer of indices */ + st_fx->hBstr->ind_list = st_ivas->ind_list; + st_fx->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + st_fx->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; + st_fx->hBstr->nb_ind_tot = 0; + move16(); + st_fx->hBstr->nb_bits_tot = 0; + move16(); + st_fx->hBstr->st_ivas = st_ivas; +#else st_fx->hBstr->ind_list = ind_list; // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); +#endif + hSCE->hCoreCoder[0] = st_fx; st_ivas->hSCE[sce_id] = hSCE; -- GitLab From 448c79f670d8581070ed5ecadd5615a1b373c0b8 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 09:43:27 -0400 Subject: [PATCH 0711/1221] fix during switching --- lib_com/bitstream_fx.c | 3 ++- lib_enc/acelp_core_switch_enc_fx.c | 18 +++++++++++++++++- lib_enc/stat_enc.h | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index f29dc6aee..07a6a632f 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -530,11 +530,12 @@ void reset_indices_enc_fx( move16(); hBstr->nb_bits_tot = 0; move16(); +#ifndef HARM_PUSH_BIT hBstr->next_ind_fx = 0; move16(); hBstr->last_ind_fx = -1; move16(); - +#endif FOR( i = 0; i < max_num_indices; i++ ) { hBstr->ind_list[i].nb_bits = -1; diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 9b0ed8b58..8226748f7 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -62,7 +62,10 @@ void acelp_core_switch_enc_fx( Word16 Aq[2 * ( M + 1 )]; LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ BSTR_ENC_HANDLE hBstr = st_fx->hBstr; - +#ifdef HARM_PUSH_BIT + UWord16 value; + Word16 nb_bits; +#endif hLPDmem = st_fx->hLPDmem; /* initializations */ @@ -153,6 +156,18 @@ void acelp_core_switch_enc_fx( encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); +#ifdef HARM_PUSH_BIT + i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); +#ifdef DEBUGGING + assert( i >= 0 && "Internal error in ACELP core switching - unable to find ACELP subframe indices!" ); +#endif + while ( hBstr->ind_list[i].id == TAG_ACELP_SUBFR_LOOP_START ) + { + push_indice( hBstr, IND_CORE_SWITCHING_CELP_SUBFRAME, hBstr->ind_list[i].value, hBstr->ind_list[i].nb_bits ); + i++; + } + delete_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START ); +#else /*----------------------------------------------------------------* * bit-stream: modify the layer of sub frame CELP *----------------------------------------------------------------*/ @@ -165,6 +180,7 @@ void acelp_core_switch_enc_fx( hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits = -1; /* Q0 */ move16(); } +#endif /*----------------------------------------------------------------* * BWE encoding *----------------------------------------------------------------*/ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 64ab13ea2..5305a8bdc 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -92,9 +92,10 @@ typedef struct bitstream_enc_data_structure void *st_ivas; /* IVAS encoder structure */ // Word16 nb_bits_tot_fx; /* total number of bits already written */ // Indice *ind_list_fx; /* list of indices */ +#ifndef HARM_PUSH_BIT Word16 next_ind_fx; /* pointer to the next empty slot in the list of indices */ Word16 last_ind_fx; /* last written indice */ - +#endif } BSTR_ENC_DATA, *BSTR_ENC_HANDLE; /*----------------------------------------------------------------------------------* -- GitLab From a69f82222c1b56b8b3cf1f3fc53b445c3f467c59 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 09:50:15 -0400 Subject: [PATCH 0712/1221] fix when erasing indices --- lib_enc/cng_enc_fx.c | 4 ++++ lib_enc/eval_pit_contr_fx.c | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 221454970..d6cb59b17 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2460,8 +2460,12 @@ static void shb_CNG_encod_fx( push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice( hBstr, IND_SID_BW, 1, 1 ); +#ifdef HARM_PUSH_BIT + delete_indice( hBstr, IND_CNG_ENV1 ); +#else hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; +#endif move16(); move16(); diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index df629f295..5e1c8dfe3 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -378,6 +378,16 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit move16(); set16_fx( pitch_buf, shl( L_SUBFR, 6 ), NB_SUBFR16k ); + +#ifdef HARM_PUSH_BIT + /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ + for ( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) + { + delete_indice( hBstr, i ); + } + + delete_indice( hBstr, IND_ES_PRED ); +#else /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ FOR( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) { @@ -396,6 +406,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit hBstr->ind_list[IND_ES_PRED].nb_bits = -1; move16(); } +#endif } IF( LT_32( st_fx->core_brate, CFREQ_BITRATE ) ) { -- GitLab From a2b10d391aaf9aedf613c199ffaa2293ac8ffda4 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 09:54:11 -0400 Subject: [PATCH 0713/1221] fix clang --- lib_enc/cng_enc_fx.c | 2 +- lib_enc/igf_enc_fx.c | 2 +- lib_enc/init_enc_fx.c | 2 +- lib_enc/ivas_sce_enc_fx.c | 2 +- lib_enc/lib_enc.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index d6cb59b17..b031ca528 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2460,7 +2460,7 @@ static void shb_CNG_encod_fx( push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice( hBstr, IND_SID_BW, 1, 1 ); -#ifdef HARM_PUSH_BIT +#ifdef HARM_PUSH_BIT delete_indice( hBstr, IND_CNG_ENV1 ); #else hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 96f8d0202..f508b313f 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1449,7 +1449,7 @@ hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); return; } -#ifndef HARM_PUSH_BIT /* old bitstream */ +#ifndef HARM_PUSH_BIT /* old bitstream */ /**********************************************************************/ /* IGF bitsream concatenation for TCX10 modes **************************************************************************/ diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 4913e410d..60e6019aa 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1675,7 +1675,7 @@ ivas_error init_encoder_ivas_fx( return error; } } - ELSE + ELSE { IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 2e1aed092..41127a98e 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -474,7 +474,7 @@ ivas_error create_sce_enc_fx( { return error; } - hSCE->hCoreCoder[0] = st; + hSCE->hCoreCoder[0] = st; st_ivas->hSCE[sce_id] = hSCE; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index fdf410df5..dd01386d8 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -70,7 +70,7 @@ struct IVAS_ENC * Local functions *---------------------------------------------------------------------*/ -//static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +// static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error setBandwidth_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_BANDWIDTH maxBandwidth ); static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); -- GitLab From 3f70046df9d1c9ae2fc6c373d60b5165a865593a Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 11:34:05 -0400 Subject: [PATCH 0714/1221] fix reset indice for dtx case --- lib_enc/dtx_fx.c | 4 ++++ lib_enc/enc_ppp_fx.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 9a66572ab..6d8a29795 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -838,7 +838,11 @@ void dtx_fx( /* reset the bitstream (IVAS format signalling was already written) */ IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { +#ifdef HARM_PUSH_BIT + reset_indices_enc_fx( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); +#else reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); +#endif } } diff --git a/lib_enc/enc_ppp_fx.c b/lib_enc/enc_ppp_fx.c index c2aeaa7ca..9d1ffad60 100644 --- a/lib_enc/enc_ppp_fx.c +++ b/lib_enc/enc_ppp_fx.c @@ -189,8 +189,11 @@ ivas_error encod_ppp_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ +#ifdef HARM_PUSH_BIT + reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); +#else reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); - +#endif /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); } @@ -373,8 +376,11 @@ ivas_error encod_ppp_ivas_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ +#ifdef HARM_PUSH_BIT + reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); +#else reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); - +#endif /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); } -- GitLab From 16b3fe618f72cd1b7df54b0c3384092df6d62c85 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 12:52:49 -0400 Subject: [PATCH 0715/1221] Fix bitrate switching --- lib_enc/lib_enc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index dd01386d8..063f39dea 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1817,6 +1817,16 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( /* set pointers to the new buffers of indices in each element */ FOR( n = 0; n < st_ivas->nSCE; n++ ) { +#ifdef HARM_PUSH_BIT + st_ivas->hSCE[n]->hCoreCoder[0]->hBstr->ind_list = st_ivas->ind_list; + st_ivas->hSCE[n]->hCoreCoder[0]->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + + if ( st_ivas->hSCE[n]->hMetaData != NULL ) + { + st_ivas->hSCE[n]->hMetaData->ind_list = st_ivas->ind_list_metadata; + st_ivas->hSCE[n]->hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; + } +#else test(); IF( !( hIvasEnc->hCoreCoder == NULL && EQ_32( hEncoderConfig->ivas_format, MONO_FORMAT ) ) ) { @@ -1832,6 +1842,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( st_ivas->hSCE[n]->hMetaData->ind_list = st_ivas->ind_list_metadata; st_ivas->hSCE[n]->hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; } +#endif } FOR( n = 0; n < st_ivas->nCPE; n++ ) -- GitLab From 37e3c531bcec2722e8832f6719877a575f1e5020 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 13:48:10 +0530 Subject: [PATCH 0716/1221] Scaling fix in find target and usan error fix --- lib_com/ivas_spar_com_fx.c | 2 +- lib_enc/find_tar_fx.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 5a0d342e9..317ea0249 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -7190,7 +7190,7 @@ void ivas_dirac_dec_get_response_fx_29( if ( GT_16( index_elevation, 90 ) ) { - e_fac = L_add( 0x80000000, 0 ); + e_fac = MIN_32; } diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index 4e15bc828..16ec45c78 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -203,6 +203,7 @@ void find_targets_ivas_fx( temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */ move16(); } + Scale_sig( temp, M, 1 ); // scaling to make belong function output alligned //Qnew syn_filt_fx( 0, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); -- GitLab From ff1ecd8743402a7cb90cffda09c2dc9c9bab382f Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 15:05:26 +0530 Subject: [PATCH 0717/1221] Q mismatch fix in stereo_icBWE_enc_ivas_fx stack --- lib_com/deemph.c | 11 ++--- lib_com/prot_fx.h | 1 - lib_dec/ivas_stereo_icbwe_dec_fx.c | 2 +- lib_enc/ivas_stereo_ica_enc_fx.c | 8 ++-- lib_enc/ivas_stereo_icbwe_enc_fx.c | 64 +++++++++++++++++++----------- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/lib_com/deemph.c b/lib_com/deemph.c index c03a050bc..9bc20cb6f 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -41,26 +41,23 @@ void deemph_fx_32( - Word16 shift, /*scaled output*/ Word32 *signal, /* i/o: signal Qx*/ const Word16 mu, /* i : deemphasis factor Q15*/ const Word16 L, /* i : vector size */ - Word32 *mem /* i/o: memory (y[-1]) Qx+shift*/ + Word32 *mem /* i/o: memory (y[-1]) Qx*/ ) { Word16 i; - signal[0] = L_add( signal[0], Mpy_32_16_1( ( *mem ), mu ) ); /*Qx*/ + signal[0] = Madd_32_16( signal[0], *mem, mu ); // Qx move32(); FOR( i = 1; i < L; i++ ) { - signal[i] = L_add( signal[i], Mpy_32_16_1( signal[i - 1], mu ) ); /*Qx*/ - signal[i] = L_shl( signal[i], shift ); /*Qx+shift*/ - move32(); + signal[i] = Madd_32_16( signal[i], signal[i - 1], mu ); // Qx move32(); } - *mem = signal[L - 1]; /*Qx+shift*/ + *mem = signal[L - 1]; // Qx move32(); return; diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 851b461bf..ffd1d6032 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1651,7 +1651,6 @@ void deemph_fx( void E_UTIL_deemph2( Word16 shift, Word16 *x, const Word16 mu, const Word16 L, Word16 *mem ); void deemph_fx_32( - Word16 shift, /* i : scaled output */ Word32 *signal, /* i/o: signal */ const Word16 mu, /* i : deemphasis factor */ const Word16 L, /* i : vector size */ diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c9f7cac92..c7bc98566 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -611,7 +611,7 @@ void stereo_icBWE_dec_fx( Q_syn_shb = tmp; move16(); - deemph_fx_32( 0, shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); + deemph_fx_32( shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); hStereoICBWE->prev_Q_memshbspec = Q_syn_shb; move16(); Copy32( shb_synth_nonref_fx + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD ); /* Q_syn_shb */ diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 78ea50d7e..a8a088f20 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -408,8 +408,8 @@ static void deEmphResample_fx( /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */ - deemph_fx_32( 0, buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] ); - deemph_fx_32( 0, buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] ); + deemph_fx_32( buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] ); + deemph_fx_32( buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] ); FOR( i = 0; i < ( input_frame / dsFac1 ); i++ ) { @@ -420,8 +420,8 @@ static void deEmphResample_fx( } /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */ - deemph_fx_32( 0, tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] ); - deemph_fx_32( 0, tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] ); + deemph_fx_32( tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] ); + deemph_fx_32( tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] ); FOR( i = 0; i < ( input_frame / dsFactor ); i++ ) { diff --git a/lib_enc/ivas_stereo_icbwe_enc_fx.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c index 02d20543b..eba30f762 100644 --- a/lib_enc/ivas_stereo_icbwe_enc_fx.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -102,14 +102,15 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( const Word32 *shb_frame_target_fx, /* i : target shb Q31-shb_frame_target_e*/ Word16 shb_frame_target_e, Word32 *shb_synth_nonref_fx, /* o : non-ref shb synth Q31-shb_synth_nonref_e*/ - Word16 shb_synth_nonref_e, + Word16 *shb_synth_nonref_e, Word32 *specMapping_fx, /* i/o: current frame's mapping Qx*/ - Word32 *memShbSpecMapping_fx, /* i/o: current frame's mapping Qx*/ - Word32 *memShbSpecXcorr_fx, /* i/o: ic bwe spec mapping scorr memory Q31-memShbSpecXcorr_e*/ + Word32 *memShbSpecMapping_fx, /* i/o: current frame's mapping Q31-memShbSpecMapping_e*/ + Word16 *memShbSpecMapping_e, + Word32 *memShbSpecXcorr_fx, /* i/o: ic bwe spec mapping scorr memory Q31-memShbSpecXcorr_e*/ Word16 *memShbSpecXcorr_e ) { Word16 idx; - + Word16 max_exp; Word16 Txx1_fx = 0, Txx2_fx = 0, Txx3_fx = 0, T_desired_fx = 0; Word16 Txx1_e = 0, Txx2_e = 0, Txx3_e = 0, T_desired_e = 0; Word16 T_nonref_target_fx, temp_fx; @@ -136,10 +137,10 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( temp11_fx = dotp_fixed_ivas_fx( shb_frame_target_fx, shb_frame_target_e, shb_frame_target_fx + 1, shb_frame_target_e, L_FRAME16k - 1, &temp11_exp ); /* Q31-temp1_exp */ /* Calculate rxx(1)/rxx(0) of the non ref synth */ - temp0_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, L_FRAME16k - 3, &temp0_exp ); /* Q31-temp0_exp */ - temp1_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 1, shb_synth_nonref_e, L_FRAME16k - 3, &temp1_exp ); /* Q31-temp1_exp */ - temp2_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 2, shb_synth_nonref_e, L_FRAME16k - 3, &temp2_exp ); /* Q31-temp2_exp */ - temp3_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 3, shb_synth_nonref_e, L_FRAME16k - 3, &temp3_exp ); /* Q31-temp3_exp */ + temp0_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx, *shb_synth_nonref_e, L_FRAME16k - 3, &temp0_exp ); /* Q31-temp0_exp */ + temp1_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx + 1, *shb_synth_nonref_e, L_FRAME16k - 3, &temp1_exp ); /* Q31-temp1_exp */ + temp2_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx + 2, *shb_synth_nonref_e, L_FRAME16k - 3, &temp2_exp ); /* Q31-temp2_exp */ + temp3_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, *shb_synth_nonref_e, shb_synth_nonref_fx + 3, *shb_synth_nonref_e, L_FRAME16k - 3, &temp3_exp ); /* Q31-temp3_exp */ exp = s_max( *memShbSpecXcorr_e, s_max( s_max( s_max( temp00_exp, temp11_exp ), s_max( temp0_exp, temp1_exp ) ), s_max( temp2_exp, temp3_exp ) ) ); @@ -291,8 +292,19 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( *specMapping_fx = L_deposit_h( specMapping16 ); move32(); + max_exp = s_max( sub( *memShbSpecMapping_e, norm_l( *memShbSpecMapping_fx ) ), *shb_synth_nonref_e ); + + *memShbSpecMapping_fx = L_shl( *memShbSpecMapping_fx, sub( *memShbSpecMapping_e, max_exp ) ); // max_exp + move32(); + *memShbSpecMapping_e = max_exp; + move16(); + + scale_sig32( shb_synth_nonref_fx, L_FRAME16k, sub( *shb_synth_nonref_e, max_exp ) ); // max_exp + *shb_synth_nonref_e = max_exp; + move16(); + /* IC-BWE spec mapping */ - deemph_fx_32( 0, shb_synth_nonref_fx, extract_h( *specMapping_fx ), L_FRAME16k, memShbSpecMapping_fx ); + deemph_fx_32( shb_synth_nonref_fx, specMapping16, L_FRAME16k, memShbSpecMapping_fx ); // shb_synth_nonref_e return idx; } @@ -429,7 +441,7 @@ static void icbwe_dft_stereo_param_ivas_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i : */ Encoder_State *st, /* i/o: */ Word32 *shb_synth_nonref_fx, /* i/o: Q31-shb_synth_nonref_e*/ - Word16 shb_synth_nonref_e /* i/o: */ + Word16 *shb_synth_nonref_e /* i/o: */ ) { Word16 slopeILD_fx; @@ -439,7 +451,7 @@ static void icbwe_dft_stereo_param_ivas_fx( Word32 *nrg_L_fx, *nrg_R_fx, *nrg_DMX_fx; Word32 sum_nrg_L_fx, sum_nrg_R_fx, sum_nrg_DMX_fx; const Word32 spec_table_fx[4] = { -1288490189, -858993459, -429496730, 0 }; // Q31 - const Word16 slope_table_fx16[4] = { -17788, -10577, -4822, 0 }; // Q13 + const Word16 slope_table_fx16[4] = { -278, -165, -75, 0 }; // Q7 BSTR_ENC_HANDLE hBstr = st->hBstr; normFac_fx = 1342177280; /* 1000 * (10/((14400+10400)/2 - (6400+10400)/2)) */ // Q29 @@ -505,6 +517,7 @@ static void icbwe_dft_stereo_param_ivas_fx( IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) { /* Spec Mapping Estimate */ + Word16 max_exp; Word16 tmp1, exp1; Word32 L_tmp, L_tmp1; L_tmp = Mpy_32_32( hStereoICBWE->mem_nrg_L_fx[1], hStereoICBWE->mem_nrg_R_fx[0] ); // hStereoICBWE->mem_nrg_L_fx_e[1] + hStereoICBWE->mem_nrg_R_fx_e[1] @@ -527,10 +540,20 @@ static void icbwe_dft_stereo_param_ivas_fx( } hStereoICBWE->prevSpecMapping_fx = spec_table_fx[spIndx]; // q31 - /* ic bwe spec mapping application */ - deemph_fx_32( 0, shb_synth_nonref_fx, extract_l( L_shr( hStereoICBWE->prevSpecMapping_fx, 16 ) ), L_FRAME16k, &hStereoICBWE->memShbSpecMapping_fx ); // shb_synth_nonref_e - hStereoICBWE->memShbSpecMapping_e = shb_synth_nonref_e; + + max_exp = s_max( *shb_synth_nonref_e, sub( hStereoICBWE->memShbSpecMapping_e, norm_l( hStereoICBWE->memShbSpecMapping_fx ) ) ); + + hStereoICBWE->memShbSpecMapping_fx = L_shl( hStereoICBWE->memShbSpecMapping_fx, sub( hStereoICBWE->memShbSpecMapping_e, max_exp ) ); // max_exp + move32(); + hStereoICBWE->memShbSpecMapping_e = max_exp; + move16(); + + scale_sig32( shb_synth_nonref_fx, L_FRAME16k, sub( *shb_synth_nonref_e, max_exp ) ); + *shb_synth_nonref_e = max_exp; move16(); + + /* ic bwe spec mapping application */ + deemph_fx_32( shb_synth_nonref_fx, extract_h( hStereoICBWE->prevSpecMapping_fx ), L_FRAME16k, &hStereoICBWE->memShbSpecMapping_fx ); // shb_synth_nonref_e } ELSE { @@ -572,7 +595,7 @@ static void icbwe_dft_stereo_param_ivas_fx( move32(); move16(); - gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); /* Q0 */ + gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); /* Q0 */ hStereoICBWE->gDes_pastFrame_fx = L_deposit_h( gDes_fx ); /* Q31-exp */ hStereoICBWE->gDes_pastFrame_e = exp; @@ -800,7 +823,7 @@ void stereo_icBWE_enc_ivas_fx( move16(); } - icbwe_dft_stereo_param_ivas_fx( hStereoICBWE, hStereoDft, st, shb_synth_nonref_fx, shb_synth_nonref_e ); + icbwe_dft_stereo_param_ivas_fx( hStereoICBWE, hStereoDft, st, shb_synth_nonref_fx, &shb_synth_nonref_e ); } ELSE { @@ -1020,14 +1043,7 @@ void stereo_icBWE_enc_ivas_fx( IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) { /* IC BWE spectral mapping */ - Word32 max_abs_val; - maximum_abs_32_fx( shb_synth_nonref_fx, L_FRAME16k, &max_abs_val ); - IF( max_abs_val > 0 ) - { - scale_sig32( shb_synth_nonref_fx, L_FRAME16k, -1 ); - shb_synth_nonref_e = sub( shb_synth_nonref_e, -1 ); - } - spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); /* Q0 */ + spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_e ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); /* Q0 */ } ELSE { -- GitLab From eb76c9cb525514513b14b663f4a9f7bce45ab6b8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 16:33:13 +0530 Subject: [PATCH 0718/1221] Crash fix when Debugging mode was enabled --- lib_enc/ivas_core_pre_proc_front_fx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 0eb6d1887..ec752e71a 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -242,8 +242,16 @@ ivas_error pre_proc_front_ivas_fx( move16(); #ifdef DEBUG_MODE_INFO - in_buff_temp = hSCE->hCoreCoder[n]->input32_fx; - in_q_temp = hSCE->hCoreCoder[n]->q_inp32; + IF( hSCE != NULL ) + { + in_buff_temp = hSCE->hCoreCoder[n]->input32_fx; + in_q_temp = hSCE->hCoreCoder[n]->q_inp32; + } + ELSE + { + in_buff_temp = hCPE->hCoreCoder[n]->input32_fx; + in_q_temp = hCPE->hCoreCoder[n]->q_inp32; + } #endif -- GitLab From 7e5738514934f1352dbda55ef54544ff955754b8 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 26 Mar 2025 14:54:23 +0100 Subject: [PATCH 0719/1221] minimal code cleanup in ivas_smc_gmm_fx(). There were two unncessary IF clauses which could be replaced with L_max. --- lib_enc/speech_music_classif_fx.c | 49 ++++++++++++------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 63c0d5d54..189e6a8e2 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -856,16 +856,8 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { /*mx = PS_norm[i] > st->past_PS[i] ? PS_norm[i] : st->past_PS[i];*/ - IF( GT_32( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ) - { - mx = PS_norm[i]; - move16(); /*Q25 */ - } - ELSE - { - mx = hSpMusClas->past_PS_fx[i - LOWEST_FBIN]; - move16(); /*Q25 */ - } + mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + move16(); /*Q25 */ /*ps_sta += mx / (dPS[i] + 1e-5f);*/ IF( !dPS[i] ) @@ -1611,7 +1603,7 @@ Word16 ivas_smc_gmm_fx( Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; Word64 wprob_fx; Word32 fvm_fx[N_PCA_COEF]; - Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; + Word32 sum_PS_fx, ps_diff_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; Word16 dlp_mean2var_fx; @@ -1989,32 +1981,29 @@ Word16 ivas_smc_gmm_fx( move32(); /* [14] ps_sta (spectral stationarity) */ - ps_sta_fx = 0; - move32(); - Word16 ps_sta_exp = 0; - move16(); - FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - IF( GT_32( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ) + Word32 ps_sta_fx = 0; + move32(); + Word16 ps_sta_exp = 0; + move16(); + Word32 avoid_divide_by_zero; + avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31 + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - temp32 = BASOP_Util_Divide3232_Scale_cadence( PS_norm_fx[i], ( L_add( dPS_fx[i], L_shr( 21475, sub( 31, Qfact_PS_past ) ) ) ), &temp_exp ); // 31-temp_exp + Word32 tmp_max; + tmp_max = L_max(PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + + temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp move32(); ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); move32(); } - ELSE - { - // ps_sta += hSpMusClas->past_PS[i - LOWEST_FBIN] / ( dPS[i] + 1e-5f ); - temp32 = BASOP_Util_Divide3232_Scale_cadence( hSpMusClas->past_PS_fx[i - LOWEST_FBIN], ( L_add( dPS_fx[i], L_shr( 21475, sub( 31, Qfact_PS_past ) ) ) ), &temp_exp ); // 31-temp_exp - ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); - } + temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); + temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); + move32(); + MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); } - // temp32_log = L_add( BASOP_Util_Log2( L_add( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); - temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); - temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ - *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); - move32(); - MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); /* save ps_diff and ps_sta features for XTALK and UNCLR classifier */ IF( hStereoClassif != NULL ) -- GitLab From a4a0941a200ae798dd1e99b5e7ccf75e8645a244 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 26 Mar 2025 15:24:44 +0100 Subject: [PATCH 0720/1221] applied the clang patch. --- lib_enc/speech_music_classif_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 189e6a8e2..c293ceb3d 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1991,7 +1991,7 @@ Word16 ivas_smc_gmm_fx( FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { Word32 tmp_max; - tmp_max = L_max(PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp move32(); -- GitLab From dbb240ebb931eafa0778e3479c5e21f0edf0b833 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 28 Mar 2025 13:45:15 +0100 Subject: [PATCH 0721/1221] remove unnecessary moves16(), move32(), keep closer to original code --- lib_enc/speech_music_classif_fx.c | 40 ++++++++++++++----------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index c293ceb3d..3f6449a0c 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -856,8 +856,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { /*mx = PS_norm[i] > st->past_PS[i] ? PS_norm[i] : st->past_PS[i];*/ - mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); - move16(); /*Q25 */ + mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); /*Q25 */ /*ps_sta += mx / (dPS[i] + 1e-5f);*/ IF( !dPS[i] ) @@ -1981,29 +1980,26 @@ Word16 ivas_smc_gmm_fx( move32(); /* [14] ps_sta (spectral stationarity) */ + Word32 ps_sta_fx = 0; + move32(); + Word16 ps_sta_exp = 0; + move16(); + Word32 avoid_divide_by_zero; + avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31 + + FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - Word32 ps_sta_fx = 0; - move32(); - Word16 ps_sta_exp = 0; - move16(); - Word32 avoid_divide_by_zero; - avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31 - FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) - { - Word32 tmp_max; - tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); + Word32 tmp_max; + tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); - temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp - move32(); - ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); - move32(); - } - temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); - temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ - *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); - move32(); - MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); + temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp + ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } + temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); + temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ + *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); + move32(); + MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); /* save ps_diff and ps_sta features for XTALK and UNCLR classifier */ IF( hStereoClassif != NULL ) -- GitLab From 0d9fa201f91dc6977e4cec82201eeb6a5a86c854 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 15:05:24 +0530 Subject: [PATCH 0722/1221] Fix for 3GPP issue 1396: Stereo Encoder: BWE artefact at 48 kbps LTV Link #1396 --- lib_enc/ext_sig_ana_fx.c | 2 + lib_enc/ivas_mdct_core_enc_fx.c | 70 ++++++++++++++------------ lib_enc/ivas_stereo_mdct_core_enc_fx.c | 15 +++--- lib_enc/stat_enc.h | 1 + 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 087d892e3..53c8d080b 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1385,6 +1385,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); } } + st->hTcxEnc->spectrum_length = L_subframe; + move16(); } diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index f7da231a3..29ae0518c 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1251,6 +1251,8 @@ void ivas_mdct_core_whitening_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; + st->hTcxEnc->spectrum_length = st->hTcxEnc->L_frameTCX; + move16(); IF( GE_16( add( imult1616( hCPE->cpe_id, CPE_CHANNELS ), ch ), nChannels ) ) { CONTINUE; @@ -1266,6 +1268,8 @@ void ivas_mdct_core_whitening_enc_fx( core_signal_analysis_high_bitrate_ivas_fx( new_samples_fx[ch] + L_INP_MEM, T_op[ch], NULL, NULL, st, tnsSize[ch], tnsBits[ch], param_core[ch], <pBits[ch], windowedSignal_fx[ch], st->L_frame, st->hTcxEnc->L_frameTCX, hCPE->last_element_mode, 0, mdst_spectrum_fx[ch], mdst_spectrum_e[ch], &Q_new, &q_windowedSignal[ch] ); + st->hTcxEnc->spectrum_length = s_max( st->hTcxEnc->spectrum_length, st->hTcxEnc->L_frameTCX ); + move16(); /* BWD in MDCT domain */ IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { @@ -1373,16 +1377,16 @@ void ivas_mdct_core_whitening_enc_fx( q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); - q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); - q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com const Word16 switchKernel = /* these 4 transform types can be applied: 0 = MDCT-IV, 1 = MDST-II, 2 = MDCT-II, 3 = MDST-IV */ kernel_switch_detect_fx( hTcxEnc0->spectrum_fx[n], hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[0][n], mdst_spectrum_fx[1][n], q_com, nSampCore / nSubframes, @@ -1470,11 +1474,11 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( mdst_spectrum_e[0][n], hTcxEnc0->spectrum_e[n] ); q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com speech = NULL; if ( NE_16( n, 1 ) ) @@ -1491,11 +1495,11 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( mdst_spectrum_e[1][n], hTcxEnc1->spectrum_e[n] ); q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com speech = NULL; if ( NE_16( n, 1 ) ) @@ -1532,7 +1536,7 @@ void ivas_mdct_core_whitening_enc_fx( move16(); /* length = max(nSampCore / (2 * NB_DIV), L_subframeTCX / (2 * NB_DIV), NB_DIV = 2 */ length = shr( s_max( nSampCore, L_subframeTCX ), 2 ); - len_sbfr = shr( hTcxEnc0->L_frameTCX, shift ); + len_sbfr = shr( hTcxEnc0->spectrum_length, shift ); assert( hTcxEnc0->L_frameTCX == hTcxEnc1->L_frameTCX ); exp_max = s_max( hTcxEnc0->spectrum_e[n], hTcxEnc1->spectrum_e[n] ); exp_max = s_max( exp_max, mdst_spectrum_e[0][n] ); @@ -1624,22 +1628,22 @@ void ivas_mdct_core_whitening_enc_fx( { Word16 length; length = shr( s_max( nSampCore, L_subframeTCX ), shift ); // max(/* nSampCore/nSubframes, L_subframeTCX/nSubframes) */ - Word16 offset2 = sub( shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, length ); + Word16 offset2 = sub( shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, length ); exp_max = s_max( hTcxEnc0->spectrum_e[n], hTcxEnc1->spectrum_e[n] ); exp_max = s_max( exp_max, mdst_spectrum_e[0][n] ); exp_max = s_max( exp_max, mdst_spectrum_e[1][n] ); - exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); q_com = sub( s_min( Q31, add( sub( Q31, exp_max ), exp_com ) ), 6 ); exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e Word16 q_com_orig = q_com; move16(); @@ -1724,12 +1728,12 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( mdst_spectrum_e[ch][n], hTcxEncCh->spectrum_e[n] ); q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEncCh->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com + Scale_sig32( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEncCh->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com speech = hTcxEncCh->speech_TCX; if ( n != 0 ) @@ -1769,7 +1773,7 @@ void ivas_mdct_core_whitening_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { q_min = s_max( q_min, hTcxEnc->spectrum_e[n] ); - q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); } } q_min = sub( Q31, q_min ); @@ -1791,7 +1795,7 @@ void ivas_mdct_core_whitening_enc_fx( } FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( Q31, q_com ); move16(); } @@ -1825,8 +1829,8 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( q_min, hTcxEnc->spectrum_e[n] ); q_min = s_max( q_min, mdst_spectrum_e[ch][n] ); - q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); - q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); } } q_min = sub( Q31, q_min ); @@ -1849,8 +1853,8 @@ void ivas_mdct_core_whitening_enc_fx( } FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( Q31, q_com ); move16(); mdst_spectrum_e[ch][n] = sub( Q31, q_com ); @@ -2137,7 +2141,7 @@ void ivas_mdct_core_whitening_enc_fx( { q_min = s_max( q_min, hTcxEnc->spectrum_e[n] ); - q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); } } q_min = sub( Q31, q_min ); @@ -2161,7 +2165,7 @@ void ivas_mdct_core_whitening_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( 31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( 31, hTcxEnc->spectrum_e[n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( 31, q_com ); move16(); } diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 3becb30d9..b32e8a561 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -363,11 +363,11 @@ void stereo_mdct_core_enc_fx( move16(); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - length = sts[ch]->hTcxEnc->L_frameTCX; + length = sts[ch]->hTcxEnc->spectrum_length; move16(); - if ( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + length = shr( length, 1 ); } hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[0], length ) ); @@ -384,15 +384,12 @@ void stereo_mdct_core_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - Word16 n_sb = NB_DIV; + length = sts[ch]->hTcxEnc->spectrum_length; move16(); - if ( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - n_sb = 1; - move16(); + length = shr( length, 1 ); } - length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */ - FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) { Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[k], length, sub( q_spec, sub( Q31, sts[ch]->hTcxEnc->spectrum_e[k] ) ) ); /* q_spec */ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 5305a8bdc..3977c4054 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1211,6 +1211,7 @@ typedef struct tcx_enc_structure Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ Word16 spectrum_long_e; /* MDCT output for a long block. Points to spectrum */ Word16 q_spectrum_long_fx; + Word16 spectrum_length; } TCX_ENC_DATA, *TCX_ENC_HANDLE; typedef struct TransientDetection -- GitLab From 7acfb9dbb809362d8822d6de601b99f4f60820ef Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 11 Feb 2025 14:53:41 +0100 Subject: [PATCH 0723/1221] improve high complexity of param_mc_prm_est: MC/7-1-4/128kBit reduced by 166 WMOPS --- lib_com/options.h | 17 +++++-- lib_enc/ivas_mc_param_enc_fx.c | 83 ++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index a25ba565e..e35eca130 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,9 +68,18 @@ #endif /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ -//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ -#define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ -#define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ -#define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ #define FIX_1379_MASA_ANGLE_ROUND +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS /* FhG: Defines 1.0f-weight variables, uses Madd operation instead of L_add_sat */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS /* FhG: Splits single loop with IF-statements into two low-complex loops */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_HQ_CONSTANTS /* FhG: IMPROVE PRECISION: Uses 1/6 and 1/20 in full-precise Q31 constants instead of Q15 */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL /* FhG: Uses unique shift amount in each loop iteration */ +#define FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS /* FhG ivas_spar_com.c: Zeroes very small negative coeffs via L_shr_r (was L_shr) */ +#define FIX_ISSUE_1237 /* VA: replacement of Copy_Scale_sig_16_32_DEPREC() that are doing 16 bits left shift by Copy_Scale_sig_16_32_no_sat() */ +#define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ +#define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ +#define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ +#define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ +#define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ +#define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ #endif diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 039bbdf98..37ae4ef91 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -720,9 +720,16 @@ static void ivas_param_mc_param_est_enc_fx( } } +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + Word16 gb = find_guarded_bits_fx( l_ts ); + Word16 add20gb = add( 20, gb ); +#endif + FOR( ts = start_ts; ts < num_time_slots; ts++ ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST Word16 gb = find_guarded_bits_fx( l_ts ); +#endif ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb ); ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans ); @@ -807,10 +814,25 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); +#else + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e); + a_e = sub(add20gb, a_e); + b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); + b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); + b_e = sub( add20gb, b_e ); + c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); + c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); + c_e = sub( add20gb, c_e ); + d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); + d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); + d_e = sub( add20gb, d_e ); +#endif /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); @@ -841,6 +863,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST dmx_real_fx[ch_idx1] = 0; move32(); dmx_real_e[ch_idx1] = 0; @@ -860,13 +883,49 @@ static void ivas_param_mc_param_est_enc_fx( move32(); p_dmx_fac_fx++; } +#else + Word32 real_fx = L_add(0, 0); + Word16 real_e = 0; + move16(); + Word32 imag_fx = L_add( 0, 0 ); + Word16 imag_e = 0; + move16(); + + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e ); + L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add( 20, gb ), &imag_e ); + p_dmx_fac_fx++; + } + dmx_real_fx[ch_idx1] = real_fx; + move32(); + dmx_real_e[ch_idx1] = real_e; + move16(); + dmx_imag_fx[ch_idx1] = imag_fx; + move32(); + dmx_imag_e[ch_idx1] = imag_e; + move16(); +#endif } /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + a_fx = dmx_real_fx[ch_idx1]; + move32(); + a_e = dmx_real_e[ch_idx1]; + move16(); + b_fx = dmx_imag_fx[ch_idx1]; + move32(); + b_e = dmx_imag_e[ch_idx1]; + move16(); +#endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -888,6 +947,12 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); +#else + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, dmx_real_fx[ch_idx2] ), add( a_e, dmx_real_e[ch_idx2] ), Mpy_32_32( b_fx, dmx_imag_fx[ch_idx2] ), add( b_e, dmx_imag_e[ch_idx2] ), &tmp_e ); + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, + &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); +#endif move32(); } } @@ -895,12 +960,30 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); + a_e = sub( add20gb, a_e ); + b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); + b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); + b_e = sub( add20gb, b_e ); +#endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); +#else + + c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); + c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); + c_e = sub( add20gb, c_e ); + d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); + d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); + d_e = sub( add20gb, d_e ); +#endif /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); -- GitLab From 26732f809b1397fe77800cf545d195caf95f3b92 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 11 Feb 2025 15:26:46 +0100 Subject: [PATCH 0724/1221] fix clang-fomat-issues --- lib_enc/ivas_mc_param_enc_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 37ae4ef91..788273b94 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -820,9 +820,9 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); #else - a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]); - a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e); - a_e = sub(add20gb, a_e); + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); + a_e = sub( add20gb, a_e ); b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); b_e = sub( add20gb, b_e ); @@ -884,7 +884,7 @@ static void ivas_param_mc_param_est_enc_fx( p_dmx_fac_fx++; } #else - Word32 real_fx = L_add(0, 0); + Word32 real_fx = L_add( 0, 0 ); Word16 real_e = 0; move16(); Word32 imag_fx = L_add( 0, 0 ); -- GitLab From 0a4281e6c2204efcd9d764477c2fb69f99a85b4e Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 13 Feb 2025 22:07:15 +0100 Subject: [PATCH 0725/1221] completed tuning of MC param: no more BE now --- lib_com/options.h | 3 +- lib_enc/ivas_mc_param_enc_fx.c | 59 ++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 11 deletions(-) mode change 100644 => 100755 lib_enc/ivas_mc_param_enc_fx.c diff --git a/lib_com/options.h b/lib_com/options.h index e35eca130..bfff1b66a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,5 +81,6 @@ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #endif diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c old mode 100644 new mode 100755 index 788273b94..d150b1473 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -812,6 +812,24 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST + a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); + a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); + a_e = sub( add20gb, a_e ); + if ( a_fx == 0 ) + { + a_e = 0; + move16(); + } + b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); + b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); + b_e = sub( add20gb, b_e ); + if ( b_fx == 0 ) + { + b_e = 0; + move16(); + } +#endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { #ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST @@ -820,20 +838,23 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); #else - a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); - a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); - a_e = sub( add20gb, a_e ); - b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); - b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); - b_e = sub( add20gb, b_e ); c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); c_e = sub( add20gb, c_e ); + if ( c_fx == 0 ) + { + c_e = 0; + move16(); + } d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); d_e = sub( add20gb, d_e ); + if ( d_fx == 0 ) + { + d_e = 0; + move16(); + } #endif - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], @@ -896,7 +917,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e ); L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); - imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add( 20, gb ), &imag_e ); + imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add20gb, &imag_e ); p_dmx_fac_fx++; } dmx_real_fx[ch_idx1] = real_fx; @@ -964,9 +985,19 @@ static void ivas_param_mc_param_est_enc_fx( a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); a_e = sub( add20gb, a_e ); + if ( a_fx == 0 ) + { + a_e = 0; + move16(); + } b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] ); b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e ); b_e = sub( add20gb, b_e ); + if ( b_fx == 0 ) + { + b_e = 0; + move16(); + } #endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { @@ -976,15 +1007,23 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); #else - c_e = norm_l( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band] ); c_fx = L_shl( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], c_e ); c_e = sub( add20gb, c_e ); + if ( c_fx == 0 ) + { + c_e = 0; + move16(); + } d_e = norm_l( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band] ); d_fx = L_shl( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], d_e ); d_e = sub( add20gb, d_e ); + if ( d_fx == 0 ) + { + d_e = 0; + move16(); + } #endif - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, -- GitLab From a54e71469275581829e4f24cc5229f075e308393 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 10:23:33 +0100 Subject: [PATCH 0726/1221] version now with 2 macros for NONBE and BE code parts --- lib_enc/ivas_mc_param_enc_fx.c | 44 ++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index d150b1473..c1a8e5877 100755 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -720,14 +720,14 @@ static void ivas_param_mc_param_est_enc_fx( } } -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#if defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE ) || defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE ) Word16 gb = find_guarded_bits_fx( l_ts ); Word16 add20gb = add( 20, gb ); #endif FOR( ts = start_ts; ts < num_time_slots; ts++ ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#if !defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE ) && !defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE ) Word16 gb = find_guarded_bits_fx( l_ts ); #endif ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb ); @@ -738,6 +738,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( i = 0; i < nchan_input; i++ ) { pcm_in_fx[i] += l_ts; + move32(); } /* Computing the downmix */ FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ ) @@ -755,6 +756,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE dmx_real_fx[ch_idx1] = 0; move32(); dmx_real_e[ch_idx1] = 0; @@ -773,6 +775,28 @@ static void ivas_param_mc_param_est_enc_fx( move32(); p_dmx_fac_fx++; } +#else + Word32 real_fx = L_add(0,0); + Word16 real_e = add(0, 0); + Word32 imag_fx = L_add( 0, 0 ); + Word16 imag_e = add( 0, 0 ); + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e ); + L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add20gb, &imag_e ); + p_dmx_fac_fx++; + } + dmx_real_fx[ch_idx1] = real_fx; + dmx_real_e[ch_idx1] = real_e; + dmx_imag_fx[ch_idx1] = imag_fx; + dmx_imag_e[ch_idx1] = imag_e; + move32(); + move16(); + move32(); + move16(); +#endif } /* Cx for transport channels */ @@ -812,7 +836,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); a_e = sub( add20gb, a_e ); @@ -832,7 +856,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); @@ -884,7 +908,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE dmx_real_fx[ch_idx1] = 0; move32(); dmx_real_e[ch_idx1] = 0; @@ -934,7 +958,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -946,7 +970,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -981,7 +1005,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { -#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] ); a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e ); a_e = sub( add20gb, a_e ); @@ -1001,7 +1025,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { -#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST +#ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); @@ -1028,7 +1052,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); - move32(); +pri move32(); } } } -- GitLab From 10a3bd68e413c0a5632f78c975bbee1bd1ca2553 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 10:25:46 +0100 Subject: [PATCH 0727/1221] fix stupid typo --- lib_enc/ivas_mc_param_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index c1a8e5877..1e681d030 100755 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1052,7 +1052,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); -pri move32(); + move32(); } } } -- GitLab From 6116f7b9779c57d13914f1454bd8c7d8c7f19d83 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 10:28:27 +0100 Subject: [PATCH 0728/1221] fix clang-format-issues --- lib_enc/ivas_mc_param_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100755 => 100644 lib_enc/ivas_mc_param_enc_fx.c diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c old mode 100755 new mode 100644 index 1e681d030..92cd33e2f --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -776,8 +776,8 @@ static void ivas_param_mc_param_est_enc_fx( p_dmx_fac_fx++; } #else - Word32 real_fx = L_add(0,0); - Word16 real_e = add(0, 0); + Word32 real_fx = L_add( 0, 0 ); + Word16 real_e = add( 0, 0 ); Word32 imag_fx = L_add( 0, 0 ); Word16 imag_e = add( 0, 0 ); FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) -- GitLab From 05442c393d4e0db6bc2c220fcfbf1ecf2c40cacb Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 11:32:40 +0100 Subject: [PATCH 0729/1221] deactivated temporarily the NONBE part of this MR to check the pipeline results --- lib_com/options.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index bfff1b66a..c83adeb3a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,6 +81,11 @@ #define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ #define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ #define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ -#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +// #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +/* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ +//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ +#define FIX_ISSUE_1247 #endif -- GitLab From fc387514c9302e926028e13f5bdd8c150f8fc743 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 20 Feb 2025 14:57:16 +0100 Subject: [PATCH 0730/1221] reactivated NONBE modifications to see pipeline effects --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index c83adeb3a..6b0cbedc8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,7 +84,7 @@ // #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ /* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ -//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ #define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ #define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ #define FIX_ISSUE_1247 -- GitLab From a580e8872979581d899534faa09f43d79d8b76dc Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 13:55:52 -0400 Subject: [PATCH 0731/1221] replace EVS push_indice_fx with push_indice (from IVAS) --- lib_com/bitstream_fx.c | 6 +-- lib_com/gs_gains_fx.c | 28 ++++++------- lib_com/hq_tools_fx.c | 4 +- lib_com/pvq_com_fx.c | 2 +- lib_enc/FEC_enc_fx.c | 6 +-- lib_enc/acelp_core_enc_fx.c | 4 +- lib_enc/acelp_core_switch_enc_fx.c | 8 ++-- lib_enc/amr_wb_enc_fx.c | 2 +- lib_enc/avq_cod_fx.c | 20 +++++----- lib_enc/cng_enc_fx.c | 24 +++++------ lib_enc/cod2t32_fx.c | 6 +-- lib_enc/cod4t64_fx.c | 30 +++++++------- lib_enc/decision_matrix_enc_fx.c | 64 +++++++++++++++--------------- lib_enc/enc_amr_wb_fx.c | 4 +- lib_enc/enc_gen_voic_fx.c | 6 +-- lib_enc/enc_higher_acelp_fx.c | 4 +- lib_enc/enc_pit_exc_fx.c | 6 +-- lib_enc/enc_tran_fx.c | 62 ++++++++++++++--------------- lib_enc/enc_uv_fx.c | 2 +- lib_enc/eval_pit_contr_fx.c | 6 +-- lib_enc/fd_cng_enc_fx.c | 12 +++--- lib_enc/gain_enc_fx.c | 20 +++++----- lib_enc/gaus_enc_fx.c | 6 +-- lib_enc/gs_enc_fx.c | 20 +++++----- lib_enc/hq_classifier_enc_fx.c | 8 ++-- lib_enc/hq_core_enc_fx.c | 8 ++-- lib_enc/hq_env_enc_fx.c | 24 +++++------ lib_enc/hq_hr_enc_fx.c | 4 +- lib_enc/hq_lr_enc_fx.c | 62 ++++++++++++++--------------- lib_enc/hvq_enc_fx.c | 2 +- lib_enc/isf_enc_amr_wb_fx.c | 34 ++++++++-------- lib_enc/lsf_enc_fx.c | 18 ++++----- lib_enc/nelp_enc_fx.c | 8 ++-- lib_enc/peak_vq_enc_fx.c | 36 ++++++++--------- lib_enc/pit_enc_fx.c | 8 ++-- lib_enc/ppp_enc_fx.c | 8 ++-- lib_enc/range_enc_fx.c | 8 ++-- lib_enc/stat_noise_uv_enc_fx.c | 2 +- lib_enc/swb_bwe_enc_fx.c | 46 ++++++++++----------- lib_enc/swb_bwe_enc_hr_fx.c | 22 +++++----- lib_enc/swb_bwe_enc_lr_fx.c | 6 +-- lib_enc/swb_tbe_enc_fx.c | 28 ++++++------- lib_enc/tcq_core_enc_fx.c | 4 +- lib_enc/transition_enc_fx.c | 36 ++++++++--------- lib_enc/voiced_enc_fx.c | 2 +- 45 files changed, 363 insertions(+), 363 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index e144c2cc9..667958264 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -240,11 +240,11 @@ Word16 rate2EVSmode( } /*-------------------------------------------------------------------* - * push_indice_fx( ) + * push_indice( ) * * Push a new indice into the buffer *-------------------------------------------------------------------*/ - +#if 0 void push_indice_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ Word16 id, /* i : ID of the indice */ @@ -288,7 +288,7 @@ void push_indice_fx( return; } - +#endif /*-------------------------------------------------------------------* * push_next_indice_fx() * * Push a new indice into the buffer at the next position diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index 35236b603..ecfe9aae0 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -1028,7 +1028,7 @@ Word16 gsc_gainQ_fx( /*Q12*/ mean_4g[0] = round_fx( L_tmp ); move16(); idx_g = vquant_fx( mean_4g, Gain_meanNB_fx, mean_4g, Gain_mean_dicNB_fx, 1, 64 ); - push_indice_fx( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); + push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); FOR( i = 0; i < Mbands_gn; i++ ) { @@ -1040,21 +1040,21 @@ Word16 gsc_gainQ_fx( /*Q12*/ move16(); set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 ); idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); IF( LT_32( core_brate, ACELP_9k60 ) ) { idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); } ELSE { idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 7 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 ); } /*add end */ test(); @@ -1122,7 +1122,7 @@ Word16 gsc_gainQ_fx( /*Q12*/ move16(); idx_g = vquant_fx( mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64 ); - push_indice_fx( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); + push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); FOR( i = 0; i < Mbands_gn; i++ ) { @@ -1148,11 +1148,11 @@ Word16 gsc_gainQ_fx( /*Q12*/ move16(); idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 ); /* Update to quantized vector */ @@ -1185,13 +1185,13 @@ Word16 gsc_gainQ_fx( /*Q12*/ ELSE { idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 ); - push_indice_fx( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); } } diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index cf3ce202e..0e00b9428 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -2036,7 +2036,7 @@ Word16 calc_nor_delta_hf_fx( /* updating norm & storing delta norm */ add_bits_denv = 2; move16(); - push_indice_fx( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 ); + push_indice( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 ); FOR( i = num_env_bands; i < nb_sfm; ++i ) { IF( Rsubband[i] != 0 ) @@ -2052,7 +2052,7 @@ Word16 calc_nor_delta_hf_fx( delta = min_delta; /*Q0*/ move16(); } - push_indice_fx( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta ); + push_indice( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta ); ynrm[i] = add( ynrm[i], delta ); /*Q0*/ move16(); add_bits_denv = add( add_bits_denv, bitsforDelta ); diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index 479bc04d9..9cf1226d8 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -622,7 +622,7 @@ void fine_gain_quant_fx( gain_db = round_fx_sat( L_shl_o( L_tmp, 17, &Overflow ) ); idx = squant_fx( gain_db, &gain_dbq, finegain_fx[gbits - 1], gain_cb_size[gbits - 1] ); - push_indice_fx( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); + push_indice( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); L_tmp = L_mult0( gain_dbq, 21771 ); /* 21771=0.05*log2(10) */ /* 14+17=31 */ L_tmp = L_shr( L_tmp, 15 ); /* Q16 */ diff --git a/lib_enc/FEC_enc_fx.c b/lib_enc/FEC_enc_fx.c index 87243e8d2..69b14eb9b 100644 --- a/lib_enc/FEC_enc_fx.c +++ b/lib_enc/FEC_enc_fx.c @@ -94,7 +94,7 @@ void FEC_encode_fx( index = 3; move16(); } - push_indice_fx( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); + push_indice( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); } /*-----------------------------------------------------------------* @@ -117,7 +117,7 @@ void FEC_encode_fx( tmpS = s_min( tmpS, 31 ); tmpS = s_max( tmpS, 0 ); - push_indice_fx( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); + push_indice( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); } /*-----------------------------------------------------------------* * Encode last glottal pulse position (8 bits) @@ -157,7 +157,7 @@ void FEC_encode_fx( maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) Q0*/ } - push_indice_fx( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); + push_indice( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); } maxi = 0; move16(); diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index f9f941dbd..795f03403 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -472,7 +472,7 @@ ivas_error acelp_core_enc_fx( IF( nb_bits > 0 ) { Es_pred_enc_fx( &Es_pred_fx, &indice, st_fx->L_frame, res_fx, st_fx->voicing_fx, nb_bits, 0, Q_new ); - push_indice_fx( st_fx->hBstr, IND_ES_PRED, indice, nb_bits ); + push_indice( st_fx->hBstr, IND_ES_PRED, indice, nb_bits ); } @@ -619,7 +619,7 @@ ivas_error acelp_core_enc_fx( WHILE( nBits > 0 ) { i = s_min( nBits, 16 ); // Q0 - push_indice_fx( st_fx->hBstr, IND_UNUSED, 0, i ); + push_indice( st_fx->hBstr, IND_UNUSED, 0, i ); nBits = sub( nBits, i ); // Q0 } } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index f9058b9b9..9b0ed8b58 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -441,7 +441,7 @@ static void encod_gen_voic_core_switch_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*-----------------------------------------------------------------* @@ -489,7 +489,7 @@ static void encod_gen_voic_core_switch_fx( /* write reserved bits */ IF( unbits ) { - push_indice_fx( hBstr, IND_UNUSED, 0, unbits ); + push_indice( hBstr, IND_UNUSED, 0, unbits ); } /*-----------------------------------------------------------------* @@ -838,7 +838,7 @@ static void bwe_switch_enc_fx( } } - push_indice_fx( hBstr, IND_CORE_SWITCHING_AUDIO_DELAY, d1m_fx, AUDIODELAYBITS ); + push_indice( hBstr, IND_CORE_SWITCHING_AUDIO_DELAY, d1m_fx, AUDIODELAYBITS ); tmp = add( i_mult2( d1m_fx, delta_fx ), fdelay_fx ); /* Q0 */ ptmp = &hb_synth_tmp_fx[tmp]; /* Q0 */ @@ -867,7 +867,7 @@ static void bwe_switch_enc_fx( L_tmp1 = L_shl( L_tmp1, sub( q_tmp2, 24 ) ); gain_fx = round_fx_o( Isqrt( L_tmp1 ), &Overflow ); /*Q12 */ ind1_fx = usquant_fx( gain_fx, &gain_fx, shr( MINVALUEOFFIRSTGAIN_FX, 1 ), shr( DELTAOFFIRSTGAIN_FX, 4 ), ( 1 << NOOFGAINBITS1 ) ); /* Q0 */ - push_indice_fx( hBstr, IND_CORE_SWITCHING_AUDIO_GAIN, ind1_fx, NOOFGAINBITS1 ); + push_indice( hBstr, IND_CORE_SWITCHING_AUDIO_GAIN, ind1_fx, NOOFGAINBITS1 ); return; } diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index b1b2257e2..6f46e5c12 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -548,7 +548,7 @@ void amr_wb_enc_fx( * Write VAD information into the bitstream in AMR-WB IO mode *--------------------------------------------------------------------------------------*/ - push_indice_fx( st->hBstr, IND_VAD_FLAG, st->vad_flag, 1 ); + push_indice( st->hBstr, IND_VAD_FLAG, st->vad_flag, 1 ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 962b715cd..b3a49c59e 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -384,20 +384,20 @@ void AVQ_encmux_fx( /* write the unary code */ FOR( ; j > 16; j -= 16 ) { - push_indice_fx( hBstr, nq_ind, 65535, 16 ); + push_indice( hBstr, nq_ind, 65535, 16 ); bits = sub( bits, 16 ); } IF( j > 0 ) { - push_indice_fx( hBstr, nq_ind, extract_l( L_sub( L_shl( 1L, j ), 1L ) ), j ); + push_indice( hBstr, nq_ind, extract_l( L_sub( L_shl( 1L, j ), 1L ) ), j ); bits = sub( bits, j ); } } IF( !overflow ) { /* write the stop bit */ - push_indice_fx( hBstr, nq_ind, 0, 1 ); + push_indice( hBstr, nq_ind, 0, 1 ); bits = sub( bits, 1 ); } @@ -506,13 +506,13 @@ void AVQ_encmux_fx( IF( j > 0 ) { /* write the unary code */ - push_indice_fx( hBstr, nq_ind, sub( shl( 1, j ), 1 ), j ); + push_indice( hBstr, nq_ind, sub( shl( 1, j ), 1 ), j ); } IF( nq[i] != 0 ) { /* write the stop bit */ - push_indice_fx( hBstr, nq_ind, 0, 1 ); + push_indice( hBstr, nq_ind, 0, 1 ); } /*Compute AVQ code book number from unused Bits */ @@ -1099,32 +1099,32 @@ static void wrte_cv( ELSE IF( LT_16( nq, 5 ) ) /* Q2, Q3, Q4 */ { nq4 = shl( nq, 2 ); - push_indice_fx( hBstr, i_ind, I, nq4 ); + push_indice( hBstr, i_ind, I, nq4 ); bits = sub( bits, nq4 ); } ELSE IF( EQ_16( s_and( nq, 1 ), 0 ) ) /* Q4 + Voronoi extensions r=1,2,3,... */ { - push_indice_fx( hBstr, i_ind, I, 4 * 4 ); + push_indice( hBstr, i_ind, I, 4 * 4 ); bits = sub( bits, 4 * 4 ); /*pos = (int16_t)(nq / 2 - 2);*/ /* Voronoi order determination */ pos = sub( shr( nq, 1 ), 2 ); FOR( j = 0; j < 8; j++ ) { - push_indice_fx( hBstr, kv_ind, kv[j], pos ); + push_indice( hBstr, kv_ind, kv[j], pos ); } bits = sub( bits, shl( pos, 3 ) ); } ELSE /* Q3 + Voronoi extensions r=1,2,3,... */ { - push_indice_fx( hBstr, i_ind, I, 4 * 3 ); + push_indice( hBstr, i_ind, I, 4 * 3 ); bits = sub( bits, 4 * 3 ); /*pos = (int16_t)(nq / 2 - 1);*/ /* Voronoi order determination */ pos = sub( shr( nq, 1 ), 1 ); FOR( j = 0; j < 8; j++ ) { - push_indice_fx( hBstr, kv_ind, kv[j], pos ); + push_indice( hBstr, kv_ind, kv[j], pos ); } bits = sub( bits, shl( pos, 3 ) ); diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index e2b29ba59..221454970 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -975,7 +975,7 @@ void CNG_enc_fx( hTdCngEnc->old_enr_index = enr_index; move16(); - push_indice_fx( hBstr, IND_ENERGY, enr_index, num_bits ); + push_indice( hBstr, IND_ENERGY, enr_index, num_bits ); if ( enr_index == 0 ) { enr_index = -5; @@ -1063,7 +1063,7 @@ void CNG_enc_fx( move16(); } } - push_indice_fx( hBstr, IND_CNG_ENV1, min1_idx, 6 ); + push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 ); /* get quantized res_env_details */ FOR( i = 0; i < NUM_ENV_CNG; i++ ) { @@ -1122,28 +1122,28 @@ void CNG_enc_fx( /* dithering bit for AMR-WB IO mode is always set to 0 */ IF( EQ_32( st_fx->core_brate, SID_1k75 ) ) { - push_indice_fx( hBstr, IND_DITHERING, 0, 1 ); + push_indice( hBstr, IND_DITHERING, 0, 1 ); } IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 1, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 ); } ELSE { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 0, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 ); } - push_indice_fx( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, 7 ), 3 ); + push_indice( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, 7 ), 3 ); hTdCngEnc->num_ho = m; move16(); - push_indice_fx( hBstr, IND_SID_TYPE, 0, 1 ); + push_indice( hBstr, IND_SID_TYPE, 0, 1 ); test(); IF( LT_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - push_indice_fx( hBstr, IND_SID_BW, 0, 1 ); + push_indice( hBstr, IND_SID_BW, 0, 1 ); *sid_bw = 0; move16(); } @@ -2458,8 +2458,8 @@ static void shb_CNG_encod_fx( idx_ener_fx = s_max( idx_ener_fx, 0 ); } - push_indice_fx( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); - push_indice_fx( hBstr, IND_SID_BW, 1, 1 ); + push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); + push_indice( hBstr, IND_SID_BW, 1, 1 ); hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; move16(); @@ -2470,7 +2470,7 @@ static void shb_CNG_encod_fx( } else { - push_indice_fx( hBstr, IND_UNUSED, 0, 2 ); + push_indice( hBstr, IND_UNUSED, 0, 2 ); } hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); hTdCngEnc->ho_sid_bw = L_or( hTdCngEnc->ho_sid_bw, 0x1L ); @@ -2482,7 +2482,7 @@ static void shb_CNG_encod_fx( IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - push_indice_fx( hBstr, IND_SID_BW, 0, 1 ); + push_indice( hBstr, IND_SID_BW, 0, 1 ); } } diff --git a/lib_enc/cod2t32_fx.c b/lib_enc/cod2t32_fx.c index a948a4656..dc967e656 100644 --- a/lib_enc/cod2t32_fx.c +++ b/lib_enc/cod2t32_fx.c @@ -292,7 +292,7 @@ void acelp_2t32_fx( } { /* write index to array of indices */ - push_indice_fx( hBstr, IND_ALG_CDBK_2T32, index, 12 ); + push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 ); } return; } @@ -636,11 +636,11 @@ void acelp_1t64_fx( } IF( EQ_16( L_subfr, L_SUBFR ) ) { - push_indice_fx( hBstr, IND_ALG_CDBK_1T64, index, 7 ); + push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 ); } ELSE /* L_subfr == 2*L_SUBFR */ { - push_indice_fx( hBstr, IND_ALG_CDBK_1T64, index, 8 ); + push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 ); } return; diff --git a/lib_enc/cod4t64_fx.c b/lib_enc/cod4t64_fx.c index 99b794b42..457a129b8 100644 --- a/lib_enc/cod4t64_fx.c +++ b/lib_enc/cod4t64_fx.c @@ -330,11 +330,11 @@ Word16 acelp_4t64_fx( bitcnt = s_and( nbbits, 15 ); FOR( i = 0; i < wordcnt; i++ ) { - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], 16 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], 16 ); } IF( bitcnt ) { - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], bitcnt ); + push_indice( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], bitcnt ); } } ELSE @@ -347,7 +347,7 @@ Word16 acelp_4t64_fx( { k = i_mult2( track, NPMAXPT ); index = quant_1p_N1_fx( ind[k], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 5 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 5 ); } } ELSE IF( EQ_16( nbbits, 36 ) ) @@ -357,7 +357,7 @@ Word16 acelp_4t64_fx( k = i_mult2( track, NPMAXPT ); /* k = track * NPMAXPT;*/ index = quant_2p_2N1_fx( ind[k], ind[k + 1], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 9 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 9 ); } } ELSE IF( EQ_16( nbbits, 44 ) ) /* AMR-WB pulse indexing */ @@ -366,14 +366,14 @@ Word16 acelp_4t64_fx( { k = i_mult2( track, NPMAXPT ); index = quant_3p_3N1_fx( ind[k], ind[k + 1], ind[k + 2], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 13 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 13 ); } FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) { k = i_mult2( track, NPMAXPT ); index = quant_2p_2N1_fx( ind[k], ind[k + 1], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 9 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 9 ); } } ELSE IF( EQ_16( nbbits, 52 ) ) /* AMR-WB pulse indexing */ @@ -382,7 +382,7 @@ Word16 acelp_4t64_fx( { k = i_mult2( track, NPMAXPT ); index = quant_3p_3N1_fx( ind[k], ind[k + 1], ind[k + 2], 4 ); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64, index, 13 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 13 ); } } ELSE IF( EQ_16( nbbits, 64 ) ) /* AMR-WB pulse indexing */ @@ -393,7 +393,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 14 ) & 3 ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); } FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) @@ -402,7 +402,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_index & 0x3FFF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); } } ELSE IF( EQ_16( nbbits, 72 ) ) @@ -413,7 +413,7 @@ Word16 acelp_4t64_fx( L_index = quant_5p_5N_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 10 ) & 0x03FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 10 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 10 ); } FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) @@ -422,7 +422,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 14 ) & 3 ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); } FOR( track = 0; track < ( NB_TRACK_FCB_4T - 2 ); track++ ) @@ -431,7 +431,7 @@ Word16 acelp_4t64_fx( L_index = quant_5p_5N_fx( &ind[k], 4 ); index = extract_l( L_index & 0x03FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 10 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 10 ); } FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) @@ -440,7 +440,7 @@ Word16 acelp_4t64_fx( L_index = quant_4p_4N_fx( &ind[k], 4 ); index = extract_l( L_index & 0x3FFF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); } } ELSE IF( EQ_16( nbbits, 88 ) ) @@ -451,7 +451,7 @@ Word16 acelp_4t64_fx( L_index = quant_6p_6N_2_fx( &ind[k], 4 ); index = extract_l( L_shr( L_index, 11 ) & 0x07FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_1, index, 11 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 11 ); } FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) @@ -460,7 +460,7 @@ Word16 acelp_4t64_fx( L_index = quant_6p_6N_2_fx( &ind[k], 4 ); index = extract_l( L_index & 0x07FF ); logic16(); - push_indice_fx( hBstr, IND_ALG_CDBK_4T64_2, index, 11 ); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 11 ); } } } diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index c95bc9d5b..63a13aa1a 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -449,14 +449,14 @@ Word16 signalling_mode1_tcx20_enc_fx( num_bits = add( num_bits, nBits ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_ACELP_SIGNALLING, sub( idx, start_idx ), nBits ); + push_indice( hBstr, IND_ACELP_SIGNALLING, sub( idx, start_idx ), nBits ); } /* HQ/TCX core switching flag */ num_bits = add( num_bits, 1 ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_MDCT_CORE, 1, 1 ); + push_indice( hBstr, IND_MDCT_CORE, 1, 1 ); } } ELSE @@ -467,7 +467,7 @@ Word16 signalling_mode1_tcx20_enc_fx( num_bits = add( num_bits, 1 ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_CORE, 1, 1 ); + push_indice( hBstr, IND_CORE, 1, 1 ); } } @@ -475,7 +475,7 @@ Word16 signalling_mode1_tcx20_enc_fx( num_bits = add( num_bits, 1 ); IF( push != 0 ) { - push_indice_fx( hBstr, IND_MDCT_CORE, 1, 1 ); + push_indice( hBstr, IND_MDCT_CORE, 1, 1 ); } num_bits = add( num_bits, 2 ); @@ -484,19 +484,19 @@ Word16 signalling_mode1_tcx20_enc_fx( /* write band-width (needed for different I/O sampling rate support) */ IF( EQ_16( st->bwidth, NB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 0, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 0, 2 ); } ELSE IF( EQ_16( st->bwidth, WB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 1, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 1, 2 ); } ELSE IF( EQ_16( st->bwidth, SWB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 2, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 2, 2 ); } ELSE /* st->bwidth == FB */ { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 3, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 3, 2 ); } } } @@ -534,21 +534,21 @@ void signalling_enc_fx( test(); IF( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); /* write ACELP L_frame info */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 0, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 0, 1 ); } ELSE { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 1, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 1, 1 ); } } ELSE { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); } return; @@ -574,7 +574,7 @@ void signalling_enc_fx( IF( EQ_16( ppp_mode, 1 ) || EQ_16( nelp_mode, 1 ) ) { /* 1 bit to distinguish between 2.8kbps PPP/NELP frame and SID frame */ - push_indice_fx( hBstr, IND_CORE, 0, 1 ); + push_indice( hBstr, IND_CORE, 0, 1 ); /* SC-VBR: 0 - PPP_NB, 1 - PPP_WB, 2 - NELP_NB, 3 - NELP_WB */ test(); test(); @@ -586,19 +586,19 @@ void signalling_enc_fx( test(); IF( EQ_16( st_fx->coder_type, VOICED ) && EQ_16( st_fx->bwidth, NB ) && EQ_16( ppp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 0, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 0, 2 ); } ELSE IF( EQ_16( st_fx->coder_type, VOICED ) && NE_16( st_fx->bwidth, NB ) && EQ_16( ppp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 1, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 1, 2 ); } ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) && EQ_16( st_fx->bwidth, NB ) && EQ_16( nelp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 2, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 2, 2 ); } ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) && NE_16( st_fx->bwidth, NB ) && EQ_16( nelp_mode, 1 ) ) { - push_indice_fx( hBstr, IND_PPP_NELP_MODE, 3, 2 ); + push_indice( hBstr, IND_PPP_NELP_MODE, 3, 2 ); } } ELSE IF( NE_32( st_fx->core_brate, SID_2k40 ) && ( st_fx->core_brate != FRAME_NO_DATA ) ) @@ -606,7 +606,7 @@ void signalling_enc_fx( /* write the ACELP/HQ core selection bit */ IF( GE_32( st_fx->total_brate, ACELP_24k40 ) ) { - push_indice_fx( hBstr, IND_CORE, 0, 1 ); + push_indice( hBstr, IND_CORE, 0, 1 ); } /* find the section in the ACELP signalling table corresponding to bitrate */ @@ -652,7 +652,7 @@ void signalling_enc_fx( idx++; } - push_indice_fx( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); + push_indice( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); } /* write extension layer flag to distinguish between TBE (0) and BWE (1) */ @@ -664,11 +664,11 @@ void signalling_enc_fx( test(); IF( EQ_16( st_fx->extl, WB_TBE ) || EQ_16( st_fx->extl, SWB_TBE ) || EQ_16( st_fx->extl, FB_TBE ) ) { - push_indice_fx( hBstr, IND_BWE_FLAG, 0, 1 ); + push_indice( hBstr, IND_BWE_FLAG, 0, 1 ); } ELSE IF( EQ_16( st_fx->extl, WB_BWE ) || EQ_16( st_fx->extl, SWB_BWE ) || EQ_16( st_fx->extl, FB_BWE ) ) { - push_indice_fx( hBstr, IND_BWE_FLAG, 1, 1 ); + push_indice( hBstr, IND_BWE_FLAG, 1, 1 ); } } } @@ -678,24 +678,24 @@ void signalling_enc_fx( test(); IF( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 1, 1 ); /* write ACELP L_frame info */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 0, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 0, 1 ); } ELSE { - push_indice_fx( hBstr, IND_LAST_L_FRAME, 1, 1 ); + push_indice( hBstr, IND_LAST_L_FRAME, 1, 1 ); } } ELSE { - push_indice_fx( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); + push_indice( hBstr, IND_HQ_SWITCHING_FLG, 0, 1 ); } /* HQ/TCX core switching flag */ - push_indice_fx( hBstr, IND_MDCT_CORE, 0, 1 ); + push_indice( hBstr, IND_MDCT_CORE, 0, 1 ); /* Use ACELP signaling for LR MDCT */ IF( LE_32( st_fx->total_brate, ACELP_16k40 ) ) @@ -719,7 +719,7 @@ void signalling_enc_fx( idx++; } - push_indice_fx( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); + push_indice( hBstr, IND_ACELP_SIGNALLING, idx - start_idx, nBits ); } ELSE { @@ -727,25 +727,25 @@ void signalling_enc_fx( IF( LE_32( st_fx->core_brate, ACELP_64k ) ) { /* write ACELP/HQ core indication flag */ - push_indice_fx( hBstr, IND_CORE, 1, 1 ); + push_indice( hBstr, IND_CORE, 1, 1 ); } /* write band-width (needed for different I/O sampling rate support) */ IF( EQ_16( st_fx->bwidth, NB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 0, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 0, 2 ); } ELSE IF( EQ_16( st_fx->bwidth, WB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 1, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 1, 2 ); } ELSE IF( EQ_16( st_fx->bwidth, SWB ) ) { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 2, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 2, 2 ); } ELSE /* st_fx->bwidth == FB */ { - push_indice_fx( hBstr, IND_HQ_BWIDTH, 3, 2 ); + push_indice( hBstr, IND_HQ_BWIDTH, 3, 2 ); } } } diff --git a/lib_enc/enc_amr_wb_fx.c b/lib_enc/enc_amr_wb_fx.c index 08a20bbb9..4c5268017 100644 --- a/lib_enc/enc_amr_wb_fx.c +++ b/lib_enc/enc_amr_wb_fx.c @@ -170,7 +170,7 @@ void encod_amr_wb_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*-----------------------------------------------------------------* @@ -243,7 +243,7 @@ void encod_amr_wb_fx( hVAD->hangover_cnt, &hAmrwb_IO->gain_alpha_fx, &hf_gain_fx[i_subfr / L_SUBFR], add( Q_new, 1 ), st->Q_syn ); } - push_indice_fx( hBstr, IND_HF_GAIN_MODIFICATION, hf_gain_fx[i_subfr / L_SUBFR], 4 ); + push_indice( hBstr, IND_HF_GAIN_MODIFICATION, hf_gain_fx[i_subfr / L_SUBFR], 4 ); } p_Aw += ( M + 1 ); diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 62f740fb2..00c7d28d7 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -179,7 +179,7 @@ void encod_gen_voic_fx( move16(); } - push_indice_fx( hBstr, IND_HARM_FLAG_ACELP, harm_flag_acelp, 1 ); + push_indice( hBstr, IND_HARM_FLAG_ACELP, harm_flag_acelp, 1 ); } /*------------------------------------------------------------------* @@ -239,7 +239,7 @@ void encod_gen_voic_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit_fx;*/ @@ -387,7 +387,7 @@ void encod_gen_voic_fx( WHILE( unbits_PI_fx > 0 ) { i = s_min( unbits_PI_fx, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); unbits_PI_fx -= i; } IF( st_fx->Opt_SC_VBR ) diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index 64a11be5b..bf248bb5a 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -242,7 +242,7 @@ void transf_cdbk_enc_fx( Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/ *gain_preQ = round_fx( Ltmp ); /* Q2*/ } - push_indice_fx( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS ); + push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS ); /*--------------------------------------------------------------* * Encode and multiplex subvectors into bit-stream @@ -276,7 +276,7 @@ void transf_cdbk_enc_fx( WHILE( *unbits > 0 ) { i = s_min( *unbits, 16 ); - push_indice_fx( st_fx->hBstr, IND_UNUSED, 0, i ); + push_indice( st_fx->hBstr, IND_UNUSED, 0, i ); *unbits -= i; } } diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 957e41516..3cb2cc066 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -291,7 +291,7 @@ void enc_pit_exc_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit;*/ @@ -312,12 +312,12 @@ void enc_pit_exc_fx( IF( GE_32( st_fx->core_brate, MIN_RATE_FCB ) ) { pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 32 ); /* Q0 */ - push_indice_fx( hBstr, IND_PIT_IDX, pit_idx, 5 ); + push_indice( hBstr, IND_PIT_IDX, pit_idx, 5 ); } ELSE { pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 16 ); /* Q0 */ - push_indice_fx( hBstr, IND_PIT_IDX, pit_idx, 4 ); + push_indice( hBstr, IND_PIT_IDX, pit_idx, 4 ); } } else if ( use_fcb == 2 ) diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 4cda393d5..d6935dd0c 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -327,7 +327,7 @@ Word16 encod_tran_fx( WHILE( unbits_PI > 0 ) { i = s_min( unbits_PI, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); unbits_PI -= i; } @@ -336,72 +336,72 @@ Word16 encod_tran_fx( { IF( EQ_16( tc_subfr, TC_0_0 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, TC_0_64 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, TC_0_128 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); } ELSE IF( EQ_16( tc_subfr, TC_0_192 ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); } } ELSE /* L_frame == L_FRAME16k */ { IF( tc_subfr == 0 ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 2 ); } ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 2 ); } ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 2, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 2, 2 ); } ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 3, 2 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 3, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); } ELSE IF( EQ_16( tc_subfr, 4 * L_SUBFR ) ) { - push_indice_fx( hBstr, IND_TC_SUBFR, 3, 2 ); - push_indice_fx( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 3, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); } } diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 8a77b9e2b..a8612725b 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -153,7 +153,7 @@ void encod_unvoiced_fx( #ifdef DEBUGGING assert( st_fx->acelp_cfg.gains_mode[i_subfr_idx] == 7 && "Error: UC two-stage, only 5+2 gain Q is supported" ); #endif - push_indice_fx( st_fx->hBstr, IND_GAIN, index, st_fx->acelp_cfg.gains_mode[i_subfr_idx] ); + push_indice( st_fx->hBstr, IND_GAIN, index, st_fx->acelp_cfg.gains_mode[i_subfr_idx] ); gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index aef5fd637..df629f295 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -409,17 +409,17 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit IF( EQ_16( st_fx->coder_type, INACTIVE ) ) { - push_indice_fx( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 1 ); + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 1 ); } } ELSE { - push_indice_fx( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 3 ); + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 3 ); } } ELSE { - push_indice_fx( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 4 ); + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 4 ); } return last_pit_bin; diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index e51e2b682..2eb13646c 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1217,21 +1217,21 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru } ELSE { - push_indice_fx( hBstr, IND_SID_TYPE, 1, 1 ); - push_indice_fx( hBstr, IND_ACELP_16KHZ, corest->bwidth, 2 ); + push_indice( hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, corest->bwidth, 2 ); IF( EQ_16( corest->L_frame, L_FRAME16k ) ) { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 1, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 ); } ELSE { - push_indice_fx( hBstr, IND_ACELP_16KHZ, 0, 1 ); + push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 ); } FOR( i = 0; i < stages_37bits; i++ ) { - push_indice_fx( hBstr, IND_LSF, indices[i], bits_37bits[i] ); + push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); } - push_indice_fx( hBstr, IND_ENERGY, index, 7 ); + push_indice( hBstr, IND_ENERGY, index, 7 ); } /* Interpolate the bin/band-wise levels from the partition levels */ diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 0321cd763..0ccb31ccf 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -428,7 +428,7 @@ void gain_enc_mless_fx( tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */ index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) ); move16(); - push_indice_fx( hBstr, IND_GAIN_PIT, index, nBits ); + push_indice( hBstr, IND_GAIN_PIT, index, nBits ); /* gain_code Q */ /**gain_code /= gcode0;*/ @@ -441,7 +441,7 @@ void gain_enc_mless_fx( } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg ); - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits2 ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits2 ); L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/ } @@ -508,7 +508,7 @@ void gain_enc_mless_fx( * search for the best quantizer *-----------------------------------------------------------------*/ index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0 - push_indice_fx( hBstr, IND_GAIN, index, nBits ); + push_indice( hBstr, IND_GAIN, index, nBits ); } /* *norm_gain_code = *gain_code / *gain_inov; */ @@ -1108,7 +1108,7 @@ void gain_enc_SQ_fx( tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */ index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0 - push_indice_fx( hBstr, IND_GAIN_PIT, index, nBits_pitch ); + push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch ); /* gain_code Q */ /* *gain_code /= gcode0; */ @@ -1121,7 +1121,7 @@ void gain_enc_SQ_fx( } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg ); - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits_code ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits_code ); L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); move32(); /*Q16*/ @@ -1601,7 +1601,7 @@ void gain_enc_tc_fx( *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ move32(); - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } ELSE { @@ -1632,7 +1632,7 @@ void gain_enc_tc_fx( L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); move32(); /* Q14 -> Q16 */ - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } ELSE /* nBits == 3 */ { @@ -1642,7 +1642,7 @@ void gain_enc_tc_fx( L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); move32(); /* Q14 -> Q16 */ - push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } } @@ -2438,7 +2438,7 @@ void gain_enc_lbr_fx( *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); { - push_indice_fx( hBstr, IND_GAIN, index, nBits ); + push_indice( hBstr, IND_GAIN, index, nBits ); } return; } @@ -3223,7 +3223,7 @@ void gain_enc_amr_wb_fx( *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); - push_indice_fx( hBstr, IND_GAIN, index, nBits ); + push_indice( hBstr, IND_GAIN, index, nBits ); return; } diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index edddc6a88..081cf7ef0 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -96,7 +96,7 @@ Word16 gaus_encode_fx( move16(); /* low bound = -30; stepSize = 1.71875; inv_stepSize = 0.5818181 */ idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); /* Q0 */ - push_indice_fx( st_fx->hBstr, IND_GAIN, idx, nb_bits ); + push_indice( st_fx->hBstr, IND_GAIN, idx, nb_bits ); /*----------------------------------------------------------------* * Total excitation for Unvoiced coders @@ -638,8 +638,8 @@ void gauss2v_fx( idx = cod_2pos_fx( i, j, sign1, sign2, nvec ); /* Q0 */ move16(); - push_indice_fx( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); - push_indice_fx( hBstr, IND_TILT_FACTOR, index_delta, 3 ); + push_indice( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); + push_indice( hBstr, IND_TILT_FACTOR, index_delta, 3 ); /*----------------------------------------------------------------* * Find quantized gain diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 1642d1253..1a3d2cb56 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -82,16 +82,16 @@ void encod_audio_fx( test(); IF( ( st_fx->element_mode > EVS_MONO ) && st_fx->idchan == 0 ) { - push_indice_fx( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); + push_indice( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); } #endif IF( attack_flag > 0 ) { - push_indice_fx( hBstr, IND_GSC_ATTACK, 1, 1 ); + push_indice( hBstr, IND_GSC_ATTACK, 1, 1 ); } ELSE { - push_indice_fx( hBstr, IND_GSC_ATTACK, 0, 1 ); + push_indice( hBstr, IND_GSC_ATTACK, 0, 1 ); } @@ -105,7 +105,7 @@ void encod_audio_fx( IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( NE_16( st_fx->coder_type, INACTIVE ) && ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && GE_32( st_fx->total_brate, ACELP_13k20 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && GT_32( st_fx->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) && GE_16( st_fx->bwidth, SWB ) && !st_fx->flag_ACELP16k ) ) ) ) { - push_indice_fx( hBstr, IND_GSC_SWB_SPEECH, st_fx->GSC_noisy_speech, 1 ); + push_indice( hBstr, IND_GSC_SWB_SPEECH, st_fx->GSC_noisy_speech, 1 ); } /*---------------------------------------------------------------* * Find and encode the number of subframes @@ -185,12 +185,12 @@ void encod_audio_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { - push_indice_fx( hBstr, IND_HF_NOISE, nb_subfr_flag, 2 ); + push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 2 ); } ELSE IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) { /* nb_subfr_flag can only have the value 0 or 1 */ - push_indice_fx( hBstr, IND_HF_NOISE, nb_subfr_flag, 1 ); + push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 1 ); } } test(); @@ -227,7 +227,7 @@ void encod_audio_fx( move16(); } Es_pred_enc_fx( &Es_pred, &indice, st_fx->L_frame, res, st_fx->voicing_fx, nb_bits, 0, Q_new ); - push_indice_fx( hBstr, IND_ES_PRED, indice, nb_bits ); + push_indice( hBstr, IND_ES_PRED, indice, nb_bits ); } enc_pit_exc_fx( st_fx, speech, Aw, Aq, Es_pred, res, synth, exc, &T0_tmp, @@ -290,7 +290,7 @@ void encod_audio_fx( { hGSCEnc->noise_lev = s_max( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ); move16(); - push_indice_fx( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ), 2 ); + push_indice( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ), 2 ); } ELSE IF( st_fx->GSC_noisy_speech ) { @@ -300,7 +300,7 @@ void encod_audio_fx( } ELSE { - push_indice_fx( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP0 ), 3 ); + push_indice( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP0 ), 3 ); } /*---------------------------------------------------------------* @@ -931,7 +931,7 @@ void gsc_enc_fx( WHILE( bit > 0 ) { i = s_min( bit, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); bit = sub( bit, i ); } /* Reorder Q bands */ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 2b53082f7..300e31e8e 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -258,16 +258,16 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits { IF( GE_16( *hqswb_clas, HQ_GEN_SWB ) ) { - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas - 5, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas - 5, bits ); } ELSE { - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); } } ELSE { - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); } test(); @@ -343,7 +343,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits move16(); } /* write signalling info to the bitstream */ - push_indice_fx( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); + push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) ) { diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index ff19cfebc..66430cb8e 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -229,12 +229,12 @@ void hq_core_enc_fx( { IF( Voicing_flag > 0 ) { - push_indice_fx( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); + push_indice( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); num_bits = sub( num_bits, 1 ); } ELSE { - push_indice_fx( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); + push_indice( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); num_bits = sub( num_bits, 1 ); } } @@ -278,13 +278,13 @@ void hq_core_enc_fx( WHILE( num_bits >= 16 ) { - push_indice_fx( hBstr, IND_UNUSED, 0, 16 ); + push_indice( hBstr, IND_UNUSED, 0, 16 ); num_bits = sub( num_bits, 16 ); } IF( num_bits != 0 ) { - push_indice_fx( hBstr, IND_UNUSED, 0, num_bits ); + push_indice( hBstr, IND_UNUSED, 0, num_bits ); } #ifdef ADD_IVAS_HQ_CODE if ( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) diff --git a/lib_enc/hq_env_enc_fx.c b/lib_enc/hq_env_enc_fx.c index 5d47710ed..f033bd685 100644 --- a/lib_enc/hq_env_enc_fx.c +++ b/lib_enc/hq_env_enc_fx.c @@ -295,13 +295,13 @@ Word16 encode_envelope_indices_fx( /* o : Number of b test(); IF( EQ_16( flag_HQ2, LOW_RATE_HQ_CORE_TRAN ) || EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_HMODE, *LCmode, BITS_DE_HMODE ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, difidx[0], BITS_DE_FCOMP ); + push_indice( hBstr, IND_HQ2_DENG_HMODE, *LCmode, BITS_DE_HMODE ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, difidx[0], BITS_DE_FCOMP ); } ELSE { - push_indice_fx( hBstr, IND_LC_MODE, *LCmode, 2 ); - push_indice_fx( hBstr, IND_YNRM, difidx[0], NORM0_BITS ); + push_indice( hBstr, IND_LC_MODE, *LCmode, 2 ); + push_indice( hBstr, IND_YNRM, difidx[0], NORM0_BITS ); } test(); @@ -331,7 +331,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b m = lshr( m, 1 ); /* Q0 */ } - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); } } ELSE @@ -370,7 +370,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b move16(); } } - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); prevj = j; move16(); } @@ -419,11 +419,11 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( EQ_16( flag_HQ2, LOW_RATE_HQ_CORE ) ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, m, r ); } ELSE { - push_indice_fx( hBstr, IND_YNRM, m, r ); + push_indice( hBstr, IND_YNRM, m, r ); } prevj = j; @@ -515,11 +515,11 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( flag_HQ2 == 0 ) { - push_indice_fx( hBstr, IND_YNRM, v, r ); + push_indice( hBstr, IND_YNRM, v, r ); } ELSE { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); } } } @@ -536,14 +536,14 @@ Word16 encode_envelope_indices_fx( /* o : Number of b r = huffsizn[j]; /* Q0 */ move16(); - push_indice_fx( hBstr, IND_YNRM, m, r ); + push_indice( hBstr, IND_YNRM, m, r ); } } ELSE { FOR( i = 1; i < num_sfm; i++ ) { - push_indice_fx( hBstr, IND_YNRM, difidx[i], NORMI_BITS ); + push_indice( hBstr, IND_YNRM, difidx[i], NORMI_BITS ); } } } diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index 1cd516b43..705db9ecd 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -236,12 +236,12 @@ void hq_hr_enc_fx( IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) { nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); /* Q0 */ - push_indice_fx( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); + push_indice( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); } ELSE { nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); /* Q0 */ - push_indice_fx( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); + push_indice( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); } } /* updates */ diff --git a/lib_enc/hq_lr_enc_fx.c b/lib_enc/hq_lr_enc_fx.c index 9aca0f646..af2780682 100644 --- a/lib_enc/hq_lr_enc_fx.c +++ b/lib_enc/hq_lr_enc_fx.c @@ -115,7 +115,7 @@ static void spt_shorten_domain_set_fx( move16(); } } - push_indice_fx( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); + push_indice( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); *bit_budget = sub( *bit_budget, 1 ); /* Q0 */ move16(); } @@ -313,7 +313,7 @@ void hq_lr_enc_fx( } /* write the classification information into the bitstream */ - push_indice_fx( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas_fx, 2 ); + push_indice( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas_fx, 2 ); ( *num_bits_fx ) = sub( *num_bits_fx, 2 ); move16(); IF( EQ_16( hqswb_clas_fx, HQ_NORMAL ) ) @@ -325,7 +325,7 @@ void hq_lr_enc_fx( ELSE { /* write the transient bit into the bitstream */ - push_indice_fx( st_fx->hBstr, IND_HQ2_SWB_CLAS, is_transient_fx, 1 ); + push_indice( st_fx->hBstr, IND_HQ2_SWB_CLAS, is_transient_fx, 1 ); /* subtract one bit for the transient flag */ ( *num_bits_fx ) = sub( ( *num_bits_fx ), 1 ); @@ -741,7 +741,7 @@ void hq_lr_enc_fx( /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ FOR( i = 0; i < 2; i++ ) { - push_indice_fx( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); + push_indice( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); } } ELSE IF( is_transient_fx == 0 && EQ_16( inner_frame_fx, L_FRAME16k ) ) @@ -970,7 +970,7 @@ void hq_lr_enc_fx( /* encode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ FOR( i = 0; i < 2; i++ ) { - push_indice_fx( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); + push_indice( st_fx->hBstr, IND_HQ2_LAST_BA_MAX_BAND, hHQ_core->last_bitalloc_max_band[i], 1 ); } } ELSE IF( EQ_16( st_fx->bwidth, SWB ) && EQ_16( hqswb_clas_fx, HQ_HARMONIC ) && ( EQ_32( L_bwe_br, HQ_16k40 ) || EQ_32( L_bwe_br, HQ_13k20 ) ) ) @@ -2213,7 +2213,7 @@ static Word16 small_symbol_enc_fx( /* o : bits /* Encoding LSB bit packing */ FOR( i = 0; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB[i], BITS_DE_LSB ); } } @@ -2526,74 +2526,74 @@ static Word16 large_symbol_enc_fx( /* o : bits /* Encoding MSB bits */ IF( *hLCmode0 == 0 ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE, 0, BITS_DE_8SMODE ); bits = BITS_DE_8SMODE; move16(); IF( cnt_outlyer0 == 0 ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 0, BITS_DE_8SMODE_N0 ); bits = add( bits, BITS_DE_8SMODE_N0 ); IF( EQ_16( cnt_outlyer, 1 ) ) { /* 01 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } ELSE { /* 00 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ } FOR( i = 0; i < pos_outlyer; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = ( pos_outlyer + 1 ); i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); bits = add( bits, BITS_DE_8SMODE_N0 ); IF( EQ_16( cnt_outlyer, 1 ) ) { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); + push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); } ELSE { - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); bits = add( bits, BITS_ABS_ENG ); /* Q0 */ } FOR( i = 1; i < pos_outlyer; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = pos_outlyer + 1; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } @@ -2601,12 +2601,12 @@ static Word16 large_symbol_enc_fx( /* o : bits ELSE { bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); /* Q0 */ - push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); - push_indice_fx( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); + push_indice( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); + push_indice( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); FOR( i = 0; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); bits = add( bits, hessize[tdifidx1[i] + 4] ); /* Q0 */ } @@ -2614,7 +2614,7 @@ static Word16 large_symbol_enc_fx( /* o : bits { FOR( i = 0; i < BANDS; ++i ) { - push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); + push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); } /*bits += BANDS * lsbdepth1; */ bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); /* Q0 */ @@ -3115,7 +3115,7 @@ static Word16 band_energy_quant_fx( { deng_cmode = 0; move16(); - push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 1 ); deng_bits = add( ebits, BITS_DE_CMODE ); /* Q0 */ } @@ -3124,7 +3124,7 @@ static Word16 band_energy_quant_fx( /* setting energy difference coding mode and storing it */ deng_cmode = 1; move16(); - push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); + push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); deng_bits = add( hbits, BITS_DE_CMODE ); /* Q0 */ @@ -3479,7 +3479,7 @@ static Word16 p2a_threshold_quant_fx( move16(); } - push_indice_fx( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); + push_indice( hBstr, IND_HQ2_P2A_FLAGS, p2a_flags_fx[k], 1 ); j = add( j, 1 ); } @@ -3768,7 +3768,7 @@ static void mdct_spectrum_fine_gain_enc_fx( move16(); } - push_indice_fx( st_fx->hBstr, IND_HQ2_SUBBAND_GAIN, imin_fx, gqbits ); + push_indice( st_fx->hBstr, IND_HQ2_SUBBAND_GAIN, imin_fx, gqbits ); } return; diff --git a/lib_enc/hvq_enc_fx.c b/lib_enc/hvq_enc_fx.c index b06a1734d..a0acd0bfd 100644 --- a/lib_enc/hvq_enc_fx.c +++ b/lib_enc/hvq_enc_fx.c @@ -335,7 +335,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits q_noise_level[i] = 0; move16(); } - push_indice_fx( st_fx->hBstr, IND_HVQ_BWE_NL, q_noise_level_idx[i], 2 ); + push_indice( st_fx->hBstr, IND_HVQ_BWE_NL, q_noise_level_idx[i], 2 ); bits_used = add( bits_used, 2 ); noise_level[i] = q_noise_level[i]; /* in Q15 */ diff --git a/lib_enc/isf_enc_amr_wb_fx.c b/lib_enc/isf_enc_amr_wb_fx.c index 4851ed155..d58998565 100644 --- a/lib_enc/isf_enc_amr_wb_fx.c +++ b/lib_enc/isf_enc_amr_wb_fx.c @@ -173,11 +173,11 @@ static void qisf_ns_28b_fx( indice[4] = add( sub_VQ_fx( &isf[12], dico5_ns_28b_fx + 4, 4, DICO5_NS_28b - 1, &tmp ), 1 ); /* First vector has a problem -> do not allow */ move16(); /* write indices to array */ - push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 6 ); - push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 6 ); - push_indice_fx( hBstr, IND_ISF_0_2, indice[2], 6 ); - push_indice_fx( hBstr, IND_ISF_0_3, indice[3], 5 ); - push_indice_fx( hBstr, IND_ISF_0_4, indice[4], 5 ); + push_indice( hBstr, IND_ISF_0_0, indice[0], 6 ); + push_indice( hBstr, IND_ISF_0_1, indice[1], 6 ); + push_indice( hBstr, IND_ISF_0_2, indice[2], 6 ); + push_indice( hBstr, IND_ISF_0_3, indice[3], 5 ); + push_indice( hBstr, IND_ISF_0_4, indice[4], 5 ); /* decoding the ISFs */ disf_ns_28b_fx( indice, isf ); @@ -305,11 +305,11 @@ static void qisf_2s_36b_fx( indice[0] = Indirect_dico1[indice[0]]; move16(); /* Make interoperable with G722.2 */ - push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 8 ); - push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 8 ); - push_indice_fx( hBstr, IND_ISF_1_0, indice[2], 7 ); - push_indice_fx( hBstr, IND_ISF_1_1, indice[3], 7 ); - push_indice_fx( hBstr, IND_ISF_1_2, indice[4], 6 ); + push_indice( hBstr, IND_ISF_0_0, indice[0], 8 ); + push_indice( hBstr, IND_ISF_0_1, indice[1], 8 ); + push_indice( hBstr, IND_ISF_1_0, indice[2], 7 ); + push_indice( hBstr, IND_ISF_1_1, indice[3], 7 ); + push_indice( hBstr, IND_ISF_1_2, indice[4], 6 ); return; } @@ -442,13 +442,13 @@ static void qisf_2s_46b_fx( indice[0] = Indirect_dico1[indice[0]]; move16(); /* Make interoperable with G722.2 */ - push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 8 ); - push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 8 ); - push_indice_fx( hBstr, IND_ISF_1_0, indice[2], 6 ); - push_indice_fx( hBstr, IND_ISF_1_1, indice[3], 7 ); - push_indice_fx( hBstr, IND_ISF_1_2, indice[4], 7 ); - push_indice_fx( hBstr, IND_ISF_1_3, indice[5], 5 ); - push_indice_fx( hBstr, IND_ISF_1_4, indice[6], 5 ); + push_indice( hBstr, IND_ISF_0_0, indice[0], 8 ); + push_indice( hBstr, IND_ISF_0_1, indice[1], 8 ); + push_indice( hBstr, IND_ISF_1_0, indice[2], 6 ); + push_indice( hBstr, IND_ISF_1_1, indice[3], 7 ); + push_indice( hBstr, IND_ISF_1_2, indice[4], 7 ); + push_indice( hBstr, IND_ISF_1_3, indice[5], 5 ); + push_indice( hBstr, IND_ISF_1_4, indice[6], 5 ); return; } diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index e6d08c49d..8fe425d74 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -647,11 +647,11 @@ static void lsfq_CNG_fx( Vr_add( qlsf, &CNG_SN1_fx[idx_cv * M], qlsf, M ); /* write the VQ index to the bitstream */ - push_indice_fx( hBstr, IND_ISF_0_0, idx_cv, 4 ); + push_indice( hBstr, IND_ISF_0_0, idx_cv, 4 ); /* write the LVQ index to the bitstream */ - push_indice_fx( hBstr, IND_ISF_0_1, idx_lvq[0], LEN_INDICE ); - push_indice_fx( hBstr, IND_ISF_0_1, idx_lvq[1], LSF_BITS_CNG - 4 - LEN_INDICE ); + push_indice( hBstr, IND_ISF_0_1, idx_lvq[0], LEN_INDICE ); + push_indice( hBstr, IND_ISF_0_1, idx_lvq[1], LSF_BITS_CNG - 4 - LEN_INDICE ); return; } @@ -1117,13 +1117,13 @@ void lsf_end_enc_fx( IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) ) { /* VOICED =2 and GENERIC=3, so "coder_type-2" means VOICED =0 and GENERIC=1*/ - push_indice_fx( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); + push_indice( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); } /* write predictor selection bit */ IF( EQ_16( predmode, 2 ) ) { - push_indice_fx( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); + push_indice( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); } test(); @@ -1134,7 +1134,7 @@ void lsf_end_enc_fx( Bit_alloc1 = &BC_TCVQ_BIT_ALLOC_40B[1]; FOR( i = 0; i < ( M / 2 ) + 3; i++ ) { - push_indice_fx( hBstr, IND_LSF, TCQIdx[i], Bit_alloc1[i] ); + push_indice( hBstr, IND_LSF, TCQIdx[i], Bit_alloc1[i] ); } } ELSE @@ -1175,7 +1175,7 @@ void lsf_end_enc_fx( move16(); cumleft -= num_bits; move16(); - push_indice_fx( hBstr, IND_LSF, indice[i], num_bits ); + push_indice( hBstr, IND_LSF, indice[i], num_bits ); } WHILE( cumleft > 0 ) @@ -1195,7 +1195,7 @@ void lsf_end_enc_fx( } cumleft = sub( cumleft, num_bits ); - push_indice_fx( hBstr, IND_LSF, indice[i], num_bits ); + push_indice( hBstr, IND_LSF, indice[i], num_bits ); i = add( i, 1 ); } } @@ -3636,7 +3636,7 @@ static void lsf_mid_enc_fx( /* convert LSFs back to LSPs */ lsf2lsp_fx( qlsf, lsp, M, int_fs ); - push_indice_fx( hBstr, IND_MID_FRAME_LSF_INDEX, idx, nb_bits ); + push_indice( hBstr, IND_MID_FRAME_LSF_INDEX, idx, nb_bits ); return; } diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index a7588283a..391191175 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -698,9 +698,9 @@ void nelp_encoder_fx( } ELSE { - push_indice_fx( hBstr, IND_IG1, iG1_fx, 5 ); - push_indice_fx( hBstr, IND_IG2A, iG2_fx[0], 6 ); - push_indice_fx( hBstr, IND_IG2B, iG2_fx[1], 6 ); + push_indice( hBstr, IND_IG1, iG1_fx, 5 ); + push_indice( hBstr, IND_IG2A, iG2_fx[0], 6 ); + push_indice( hBstr, IND_IG2B, iG2_fx[1], 6 ); } test(); @@ -1019,7 +1019,7 @@ void nelp_encoder_fx( } ELSE { - push_indice_fx( hBstr, IND_NELP_FID, fid, 2 ); + push_indice( hBstr, IND_NELP_FID, fid, 2 ); } } diff --git a/lib_enc/peak_vq_enc_fx.c b/lib_enc/peak_vq_enc_fx.c index aa4763aa6..dffab4900 100644 --- a/lib_enc/peak_vq_enc_fx.c +++ b/lib_enc/peak_vq_enc_fx.c @@ -559,13 +559,13 @@ Word16 peak_vq_enc_fx( move32(); nf_gains[i] = L_shr( acc, 1 + 2 ); /* nf_gains in Q12. dicn_fx is in Q14. Need extra shift +2. */ move32(); - push_indice_fx( hBstr, IND_HVQ_NF_GAIN, indx, 5 ); + push_indice( hBstr, IND_HVQ_NF_GAIN, indx, 5 ); bits = add( bits, 5 ); } /* Signal number of peaks */ i = sub( max_peaks, vq_peaks ); - push_indice_fx( hBstr, IND_NUM_PEAKS, i, 5 ); + push_indice( hBstr, IND_NUM_PEAKS, i, 5 ); bits = add( bits, 5 ); /* Identify position of first peak and arrange peak gains by position */ @@ -677,8 +677,8 @@ Word16 peak_vq_enc_fx( move16(); } - push_indice_fx( hBstr, IND_FLAGN, FlagN, 1 ); - push_indice_fx( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS ); + push_indice( hBstr, IND_FLAGN, FlagN, 1 ); + push_indice( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS ); IF( FlagN ) { @@ -692,7 +692,7 @@ Word16 peak_vq_enc_fx( r = pgain_huffsizn[j]; move16(); - push_indice_fx( hBstr, IND_PG_IDX, m, r ); + push_indice( hBstr, IND_PG_IDX, m, r ); } } ELSE @@ -700,7 +700,7 @@ Word16 peak_vq_enc_fx( pPgainDifIdx = &pgain_difidx[1]; FOR( i = 0; i < vqPeaksMinus1; i++ ) { - push_indice_fx( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS ); + push_indice( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS ); } } @@ -727,13 +727,13 @@ Word16 peak_vq_enc_fx( num_overlap_bins = sub( 5, sub( vq_peak_idx[i + 1], vq_peak_idx[i] ) ); indx = sub( vq_peak_idx[i], 2 ); quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, num_overlap_bins, core_brate, vq_peaks ); - push_indice_fx( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); + push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); } indx = sub( vq_peak_idx[i], 2 ); quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, 0, core_brate, vq_peaks ); - push_indice_fx( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); + push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); /* Quantize peak positions and sign with HVQ */ @@ -826,7 +826,7 @@ Word16 peak_vq_enc_fx( move16(); } - push_indice_fx( hBstr, IND_HVQ_PVQ_GAIN, pvq_norm[k], HVQ_PVQ_GAIN_BITS ); + push_indice( hBstr, IND_HVQ_PVQ_GAIN, pvq_norm[k], HVQ_PVQ_GAIN_BITS ); pvq_bits = add( pvq_bits, HVQ_PVQ_GAIN_BITS ); pvq_norm[k] = add( pvq_norm[k], 8 ); @@ -1148,7 +1148,7 @@ static void quant_peaks_fx( { *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 0 ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 0, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 ); } ELSE IF( EQ_16( cb_class, 1 ) ) { @@ -1157,7 +1157,7 @@ static void quant_peaks_fx( move16(); *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 0, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 ); } ELSE IF( EQ_16( cb_class, 2 ) ) { @@ -1166,13 +1166,13 @@ static void quant_peaks_fx( move16(); *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 1, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 ); } ELSE { *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 1 ); move16(); - push_indice_fx( hBstr, IND_HVQ_PEAKS, 1, 1 ); + push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 ); } FOR( i = 0; i < 4; i++ ) @@ -1458,23 +1458,23 @@ static Word16 hvq_code_pos_fx( test(); IF( GT_16( delta_bits, sparse_bits ) || delta_bits < 0 ) { - push_indice_fx( hBstr, IND_POS_IDX, HVQ_CP_SPARSE, 1 ); + push_indice( hBstr, IND_POS_IDX, HVQ_CP_SPARSE, 1 ); FOR( i = 0; i < sparse_bits; i++ ) { - push_indice_fx( hBstr, IND_POS_IDX, sparse_result[i], 1 ); + push_indice( hBstr, IND_POS_IDX, sparse_result[i], 1 ); } bits = add( add( bits, sparse_bits ), 1 ); } ELSE { - push_indice_fx( hBstr, IND_POS_IDX, HVQ_CP_DELTA, 1 ); + push_indice( hBstr, IND_POS_IDX, HVQ_CP_DELTA, 1 ); FOR( i = 0; i < num_peaks; i++ ) { j = delta[i]; move16(); - push_indice_fx( hBstr, IND_POS_IDX, hvq_cp_huff_val[j], hvq_cp_huff_len[j] ); + push_indice( hBstr, IND_POS_IDX, hvq_cp_huff_val[j], hvq_cp_huff_len[j] ); } bits = add( add( bits, delta_bits ), 1 ); } @@ -1489,7 +1489,7 @@ static Word16 hvq_code_pos_fx( tmp = 0; move16(); } - push_indice_fx( hBstr, IND_POS_IDX, tmp, 1 ); + push_indice( hBstr, IND_POS_IDX, tmp, 1 ); } bits = add( bits, num_peaks ); diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index b19fb7e56..8eea1b3d5 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -1787,7 +1787,7 @@ void pit_Q_enc_fx( } { - push_indice_fx( hBstr, IND_PITCH, pitch_index, nBits ); + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); } return; @@ -1919,7 +1919,7 @@ void pit16k_Q_enc_fx( } } - push_indice_fx( hBstr, IND_PITCH, pitch_index, nBits ); + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); } ELSE IF( EQ_16( nBits, 9 ) ) /* absolute encoding with 9 bits */ { @@ -1949,14 +1949,14 @@ void pit16k_Q_enc_fx( } } - push_indice_fx( hBstr, IND_PITCH, pitch_index, 9 ); + push_indice( hBstr, IND_PITCH, pitch_index, 9 ); } ELSE /* nBits == 6 */ /* relative encoding with 6 bits */ { /*pitch_index = (T0 - *T0_min) * 4 + T0_frac;*/ pitch_index = add( shl( sub( T0, *T0_min ), 2 ), T0_frac ); - push_indice_fx( hBstr, IND_PITCH, pitch_index, nBits ); + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); } limit_T0_fx( L_FRAME16k, 8, L_SUBFR, limit_flag, T0, T0_frac, T0_min, T0_max ); diff --git a/lib_enc/ppp_enc_fx.c b/lib_enc/ppp_enc_fx.c index 9afb27065..ac3d5836a 100644 --- a/lib_enc/ppp_enc_fx.c +++ b/lib_enc/ppp_enc_fx.c @@ -171,9 +171,9 @@ ivas_error ppp_quarter_encoder_fx( CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx = (Word16) find_remd( Ltempn, 20971, &Ltempd ); move16(); - push_indice_fx( hBstr, IND_AMP0, AMP_IDX_fx[0], 6 ); - push_indice_fx( hBstr, IND_AMP1, AMP_IDX_fx[1], 6 ); - push_indice_fx( hBstr, IND_POWER, POWER_IDX_FX, 6 ); + push_indice( hBstr, IND_AMP0, AMP_IDX_fx[0], 6 ); + push_indice( hBstr, IND_AMP1, AMP_IDX_fx[1], 6 ); + push_indice( hBstr, IND_POWER, POWER_IDX_FX, 6 ); /*Phase copying is done through copy_phase instead of car2pol and pol2car */ copy_phase_fx( TARGETCW_FX, *CURRCW_Q_FX, TARGETCW_FX ); @@ -199,7 +199,7 @@ ivas_error ppp_quarter_encoder_fx( /*DTFS_phaseShift( CURRCW_Q,(float)(PI2*tmp/CURRCW_Q->lag) ); */ Q2phaseShift_fx( CURRCW_Q_FX, tmp_fx, CURRCW_Q_FX->lag_fx, S_fx, C_fx ); - push_indice_fx( hBstr, IND_GLOBAL_ALIGNMENT, shr( add( tmp_fx, 12 ), 2 ), 3 ); + push_indice( hBstr, IND_GLOBAL_ALIGNMENT, shr( add( tmp_fx, 12 ), 2 ), 3 ); free( PREVDTFS_FX ); return error; diff --git a/lib_enc/range_enc_fx.c b/lib_enc/range_enc_fx.c index 689b313d8..767b2ecb5 100644 --- a/lib_enc/range_enc_fx.c +++ b/lib_enc/range_enc_fx.c @@ -423,14 +423,14 @@ void rc_enc_bits_fx( IF( GT_16( bits, 16 ) ) { - push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_lshr( value, 16 ) ), sub( bits, 16 ) ); + push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_lshr( value, 16 ) ), sub( bits, 16 ) ); hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 - push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_and( value, 0x0000ffff ) ), 16 ); + push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_and( value, 0x0000ffff ) ), 16 ); hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 } ELSE { - push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( value ), bits ); + push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( value ), bits ); hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 } } @@ -516,7 +516,7 @@ static void rc_enc_write_fx( Word16 bits /* i : Number of bits Q0*/ ) { - push_indice_fx( hBstr, IND_RC_START, byte, bits ); + push_indice( hBstr, IND_RC_START, byte, bits ); return; } diff --git a/lib_enc/stat_noise_uv_enc_fx.c b/lib_enc/stat_noise_uv_enc_fx.c index 0a20db8ed..1445559a1 100644 --- a/lib_enc/stat_noise_uv_enc_fx.c +++ b/lib_enc/stat_noise_uv_enc_fx.c @@ -94,7 +94,7 @@ void stat_noise_uv_enc_fx( noisiness = s_max( noisiness, 0 ); noisiness = s_min( noisiness, 31 ); - push_indice_fx( st_fx->hBstr, IND_NOISINESS, noisiness, 5 ); + push_indice( st_fx->hBstr, IND_NOISINESS, noisiness, 5 ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 26c8382ca..1ebef7404 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -186,7 +186,7 @@ void wb_bwe_enc_fx( Q_synth = sub( add( sub( new_input_fx_exp, 16 ), scl ), 1 ); mode = WB_BWE_encoding_fx( coder_type, yorig_fx, WB_fenv_fx, st_fx, Q_synth, Q_synth ); - push_indice_fx( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); + push_indice( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); } hBWE_FD->prev_mode = mode; @@ -820,7 +820,7 @@ void swb_bwe_enc_fx( /* write FB BWE frame gain to the bitstream */ IF( EQ_16( st_fx->extl, FB_BWE ) ) { - push_indice_fx( st_fx->hBstr, IND_FB_SLOPE, idxGain, NUM_BITS_FB_FRAMEGAIN ); + push_indice( st_fx->hBstr, IND_FB_SLOPE, idxGain, NUM_BITS_FB_FRAMEGAIN ); } return; @@ -2476,7 +2476,7 @@ Word16 WB_BWE_encoding_fx( /* o : classification of wb index = WB_BWE_fenv_q_fx( WB_fenv_fx, F_2_5_fx, 32, 2 ); - push_indice_fx( st_fx->hBstr, IND_WB_FENV, index, 5 ); + push_indice( st_fx->hBstr, IND_WB_FENV, index, 5 ); return ( mode ); } @@ -2665,7 +2665,7 @@ static Word16 SWB_BWE_encoding_fx( { mode = IsTransient; move16(); - push_indice_fx( hBstr, IND_SWB_CLASS, mode, 2 ); + push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); /* Energy for the different bands and global energies */ global_gain_fx = L_deposit_l( 0 ); @@ -2924,13 +2924,13 @@ static Word16 SWB_BWE_encoding_fx( index = shr( add( SWB_tenv_tmp_fx[n_band], 1024 ), 11 ); } - push_indice_fx( hBstr, IND_SWB_TENV, index, 4 ); + push_indice( hBstr, IND_SWB_TENV, index, 4 ); } MSVQ_Interpol_Tran_fx( SWB_fenv_fx, indice ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[0], 7 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[1], 6 ); + push_indice( hBstr, IND_SWB_FENV, indice[0], 7 ); + push_indice( hBstr, IND_SWB_FENV, indice[1], 6 ); } ELSE { @@ -2955,7 +2955,7 @@ static Word16 SWB_BWE_encoding_fx( global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ mode = FD_BWE_class_fx( yos_fx, global_gain_fx, tilt_nb_fx, Q_synth, Q_shb, st_fx ); - push_indice_fx( hBstr, IND_SWB_CLASS, mode, 2 ); + push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); energy_control_fx( st_fx, ACELP_CORE, mode, -1, yos_fx, st_offset, energy_factor_fx, Q_synth_lf ); @@ -2990,11 +2990,11 @@ static Word16 SWB_BWE_encoding_fx( /* Energy VQ */ msvq_interpol_fx( SWB_fenv_fx, w_env_fx, indice ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[0], 5 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[1], 7 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[2], 6 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[3], 5 ); - push_indice_fx( hBstr, IND_SWB_FENV, indice[4], 6 ); + push_indice( hBstr, IND_SWB_FENV, indice[0], 5 ); + push_indice( hBstr, IND_SWB_FENV, indice[1], 7 ); + push_indice( hBstr, IND_SWB_FENV, indice[2], 6 ); + push_indice( hBstr, IND_SWB_FENV, indice[3], 5 ); + push_indice( hBstr, IND_SWB_FENV, indice[4], 6 ); } hBWE_FD->prev_mode = mode; move16(); @@ -3939,7 +3939,7 @@ void hq_generic_encoding_fx( IF( EQ_16( hHQ_core->hq_generic_speech_class, 1 ) ) { - push_indice_fx( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 1, 1 ); + push_indice( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 1, 1 ); *hq_generic_exc_clas = HQ_GENERIC_SP_EXC; move16(); } @@ -3947,8 +3947,8 @@ void hq_generic_encoding_fx( { *hq_generic_exc_clas = decision_hq_generic_class_fx_32( coefs_fx, hq_generic_offset ); move16(); - push_indice_fx( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 0, 1 ); - push_indice_fx( hBstr, IND_HQ_SWB_EXC_CLAS, *hq_generic_exc_clas, 1 ); + push_indice( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 0, 1 ); + push_indice( hBstr, IND_HQ_SWB_EXC_CLAS, *hq_generic_exc_clas, 1 ); } FOR( n_band = 0; n_band < nenv; n_band++ ) @@ -4069,23 +4069,23 @@ void hq_generic_encoding_fx( move16(); } - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[0], 5 ); - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[1], 7 ); - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[2], 6 ); - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[3], 5 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[0], 5 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[1], 7 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[2], 6 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[3], 5 ); IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) { - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[4], 6 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[4], 6 ); } ELSE { - push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[4], 5 ); + push_indice( hBstr, IND_SWB_FENV_HQ, indice[4], 5 ); } IF( EQ_16( st_fx->bwidth, FB ) ) { - push_indice_fx( hBstr, IND_FB_FENV_HQ, indice[5], 5 ); + push_indice( hBstr, IND_FB_FENV_HQ, indice[5], 5 ); } FOR( n_band = 0; n_band < nenv; n_band++ ) diff --git a/lib_enc/swb_bwe_enc_hr_fx.c b/lib_enc/swb_bwe_enc_hr_fx.c index fd4a9f125..8b5a17353 100644 --- a/lib_enc/swb_bwe_enc_hr_fx.c +++ b/lib_enc/swb_bwe_enc_hr_fx.c @@ -189,7 +189,7 @@ void swb_bwe_enc_hr_fx( st_fx->EnergyLT_fx_exp = exp1; move16(); - push_indice_fx( hBstr, IND_HR_IS_TRANSIENT, is_transient, 1 ); + push_indice( hBstr, IND_HR_IS_TRANSIENT, is_transient, 1 ); /*---------------------------------------------------------------------* * OLA and MDCT @@ -309,7 +309,7 @@ void swb_bwe_enc_hr_fx( ind1 = gain_quant_fx( &L_gain_fx, &gain1_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp1 ); - push_indice_fx( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalization with global gain */ @@ -353,7 +353,7 @@ void swb_bwe_enc_hr_fx( { ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx, NUM_ENVLOPE_CODE_HR_TR ); - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR ); + push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR ); nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR ); ind2 = ind1; move16(); @@ -369,7 +369,7 @@ void swb_bwe_enc_hr_fx( ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx + ( NUM_ENVLOPE_CODE_HR_TR2 * 2 ), NUM_ENVLOPE_CODE_HR_TR2 ); } - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR - 1 ); + push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR - 1 ); nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR - 1 ); } @@ -439,7 +439,7 @@ void swb_bwe_enc_hr_fx( L_en_noncoded_fx = L_deposit_h( en_band_fx[N_BANDS_TRANS_BWE_HR - 1] ); /* to Put in Q16+9 */ } - push_indice_fx( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR ); } ELSE @@ -507,7 +507,7 @@ void swb_bwe_enc_hr_fx( L_gain_fx = L_shr( L_tmp, sub( 31 - 16, exp2 ) ); /* 31: 'L_tmp' is already in Q31 */ ind1 = gain_quant_fx( &L_gain_fx, &gain1_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp1 ); - push_indice_fx( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalization with global gain */ @@ -547,8 +547,8 @@ void swb_bwe_enc_hr_fx( ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code1_fx, NUM_ENVLOPE_CODE_HR1 ); ind2 = en_band_quant_fx( en_band_fx + 2, swb_hr_env_code2_fx, NUM_ENVLOPE_CODE_HR2 ); - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR1 ); - push_indice_fx( hBstr, IND_HR_ENVELOPE, ind2, NBITS_ENVELOPE_BWE_HR2 ); + push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR1 ); + push_indice( hBstr, IND_HR_ENVELOPE, ind2, NBITS_ENVELOPE_BWE_HR2 ); nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR1 + NBITS_ENVELOPE_BWE_HR2 ); @@ -673,7 +673,7 @@ void swb_bwe_enc_hr_fx( L_en_noncoded_fx = L_mult0( min_env_fx, 16384 ); } - push_indice_fx( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR ); } ELSE @@ -758,7 +758,7 @@ void swb_bwe_enc_hr_fx( /* Put in Q16 */ L_gain_fx = L_shr( L_temp, sub( 31 - 16, temp2 ) ); /* 31: 'L_temp' is already in Q31 */ ind1 = gain_quant_fx( &L_gain_fx, &gain2_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp2 ); - push_indice_fx( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); + push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR ); nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalize with global gain */ @@ -784,7 +784,7 @@ void swb_bwe_enc_hr_fx( WHILE( nBits > 0 ) { i = s_min( nBits, 16 ); - push_indice_fx( hBstr, IND_UNUSED, 0, i ); + push_indice( hBstr, IND_UNUSED, 0, i ); nBits = sub( nBits, i ); } return; diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index 1a397c514..938cdd971 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -806,7 +806,7 @@ static void gethar_noisegn_fx( } } - push_indice_fx( hBstr, IND_NOISEG, imin_fx, 2 ); + push_indice( hBstr, IND_NOISEG, imin_fx, 2 ); /*g=(float) pow (10.0f,gain_table[imin]);*/ L_temp = L_mult( gain_table_SWB_BWE_fx[imin_fx], 27213 ); /* Q14+Q13+1=Q28 log(10)/log(2)=3.3219 27213.23(Q13) */ @@ -909,7 +909,7 @@ static void EncodeSWBSubbands_fx( /* Write the indices into the bitstream */ FOR( k = 0; k < nBands_search_fx; k++ ) { - push_indice_fx( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_mode0_Har[k] ); + push_indice( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_mode0_Har[k] ); } IF( flag_dis == 0 ) @@ -974,7 +974,7 @@ static void EncodeSWBSubbands_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_modeNormal[k] ); + push_indice( st_fx->hBstr, IND_LAGINDICES, lagIndices_fx[k], bits_lagIndices_modeNormal[k] ); } } diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index c5d5e651e..1a14e7acb 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -866,7 +866,7 @@ void wb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_LBR_WB_LSF ); + push_indice( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_LBR_WB_LSF ); } Copy( lbr_wb_bwe_lsfvq_cbook_2bit_fx + i * LPC_SHB_ORDER_LBR_WB, lsp_wb, LPC_SHB_ORDER_LBR_WB ); @@ -928,7 +928,7 @@ void wb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_WB_LSF ); + push_indice( st_fx->hBstr, IND_SHB_LSF, i, NUM_BITS_WB_LSF ); } Copy( wb_bwe_lsfvq_cbook_8bit_fx + i * LPC_SHB_ORDER_WB, lsp_wb, LPC_SHB_ORDER_WB ); @@ -1162,7 +1162,7 @@ void wb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_UV_FLAG, uv_flag, 1 ); + push_indice( st_fx->hBstr, IND_UV_FLAG, uv_flag, 1 ); /* Quantization of the subframe gain parameter */ QuantizeSHBsubgains_fx( st_fx, GainShape, st_fx->extl ); @@ -2482,7 +2482,7 @@ void swb_tbe_enc_fx( } ELSE { - push_indice_fx( st_fx->hBstr, IND_SHB_VF, vf_ind_fx, NUM_BITS_SHB_VF ); + push_indice( st_fx->hBstr, IND_SHB_VF, vf_ind_fx, NUM_BITS_SHB_VF ); } } @@ -5330,7 +5330,7 @@ static void QuantizeSHBsubgains_fx( idxSubGain = closest_centroid_lc_fx( subgains + NUM_SHB_SUBFR / 4, HBCB_SubGain5bit_fx, 1 << NUM_BITS_SHB_SUBGAINS ); Copy( HBCB_SubGain5bit_fx + idxSubGain * NUM_SHB_SUBFR / 4, subgains, NUM_SHB_SUBFR / 4 ); - push_indice_fx( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); + push_indice( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) { @@ -5401,7 +5401,7 @@ static void QuantizeSHBsubgains_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); + push_indice( hBstr, IND_SHB_SUBGAIN, idxSubGain, NUM_BITS_SHB_SUBGAINS ); } } @@ -5596,7 +5596,7 @@ static void Quant_shb_ener_sf_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( st_fx->hBstr, IND_SHB_ENER_SF, idxSubEner_fx, NUM_BITS_SHB_ENER_SF ); + push_indice( st_fx->hBstr, IND_SHB_ENER_SF, idxSubEner_fx, NUM_BITS_SHB_ENER_SF ); } return; } @@ -5683,7 +5683,7 @@ static void Quant_shb_res_gshape_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( st_fx->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); + push_indice( st_fx->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); } } } @@ -5787,7 +5787,7 @@ static void QuantizeSHBframegain_fx( 1 << NUM_BITS_SHB_FrameGain, &idxFrameGain, &Q_GainFrame, SHBCB_FrameGain64_fx ); - push_indice_fx( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FrameGain ); + push_indice( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FrameGain ); *rf_gainFrame_ind = idxFrameGain; move16(); /* Q18 */ } @@ -5852,7 +5852,7 @@ static void QuantizeSHBframegain_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); + push_indice( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); } *rf_gainFrame_ind = idxFrameGain; move16(); @@ -7176,7 +7176,7 @@ static void Quant_BWE_LSF_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_LSF, lsf_idx[i], lsf_q_num_bits[i] ); + push_indice( hBstr, IND_SHB_LSF, lsf_idx[i], lsf_q_num_bits[i] ); } } @@ -7186,7 +7186,7 @@ static void Quant_BWE_LSF_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_MIRROR, m_idx, MIRROR_POINT_BITS ); + push_indice( hBstr, IND_SHB_MIRROR, m_idx, MIRROR_POINT_BITS ); } grid_idx = Find_LSF_grid_fx( lsf, lsf_q, m ); @@ -7194,7 +7194,7 @@ static void Quant_BWE_LSF_fx( hBWE_TD->grid_idx = grid_idx; IF( NE_16( st_fx->codec_mode, MODE2 ) ) { - push_indice_fx( hBstr, IND_SHB_GRID, grid_idx, NUM_LSF_GRID_BITS ); + push_indice( hBstr, IND_SHB_GRID, grid_idx, NUM_LSF_GRID_BITS ); } FOR( i = 0; i < LPC_SHB_ORDER; i++ ) @@ -7407,7 +7407,7 @@ void fb_tbe_enc_fx( } ELSE { - push_indice_fx( st->hBstr, IND_FB_SLOPE, idxGain, 4 ); + push_indice( st->hBstr, IND_FB_SLOPE, idxGain, 4 ); } return; diff --git a/lib_enc/tcq_core_enc_fx.c b/lib_enc/tcq_core_enc_fx.c index 82088be50..d5841094f 100644 --- a/lib_enc/tcq_core_enc_fx.c +++ b/lib_enc/tcq_core_enc_fx.c @@ -449,11 +449,11 @@ ivas_error tcq_core_LR_enc_fx( j = sub( bit_budget, shl( nb_bytes, 3 ) ); FOR( i = 0; i < nb_bytes; i++ ) { - push_indice_fx( hBstr, IND_HQ2_SUBBAND_TCQ, pbs_fx->buf[i], 8 ); + push_indice( hBstr, IND_HQ2_SUBBAND_TCQ, pbs_fx->buf[i], 8 ); } IF( j > 0 ) { - push_indice_fx( hBstr, IND_HQ2_SUBBAND_TCQ, shr( pbs_fx->buf[nb_bytes], ( 8 - j ) ), j ); + push_indice( hBstr, IND_HQ2_SUBBAND_TCQ, shr( pbs_fx->buf[nb_bytes], ( 8 - j ) ), j ); } /* Clear decoding buffer */ set32_fx( coefs_quant_fx, 0, sfm_end[BANDS - 1] + 1 ); diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 7fe813d12..253cc9717 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -389,7 +389,7 @@ void transition_enc_fx( /* 7bit ENCODER */ /* index = (*T0-pit_start)*2 + *T0_frac/2;*/ index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -438,7 +438,7 @@ void transition_enc_fx( limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max for delta search */ index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -502,7 +502,7 @@ void transition_enc_fx( *T0_frac = 0; move16(); } - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -526,7 +526,7 @@ void transition_enc_fx( *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); move16(); index = delta_pit_enc_fx( 2, *T0, *T0_frac, *T0_min ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); @@ -607,7 +607,7 @@ void transition_enc_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } } @@ -768,7 +768,7 @@ void transition_enc_fx( /*index = (*T0)*2 + ((*T0_frac)>>1) - (PIT16k_FR2_TC0_2SUBFR*2) + ((PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4);*/ index = add( sub( add( shl( *T0, 1 ), shr( *T0_frac, 1 ) ), ( PIT16k_FR2_TC0_2SUBFR * 2 ) ), ( PIT16k_FR2_TC0_2SUBFR - PIT16k_MIN ) * 4 ); } - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } ELSE IF( EQ_16( nBits, 6 ) ) { @@ -777,7 +777,7 @@ void transition_enc_fx( move16(); index = delta_pit_enc_fx( 4, *T0, *T0_frac, *T0_min ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } IF( EQ_16( nBits, 6 ) ) { @@ -804,7 +804,7 @@ void transition_enc_fx( move16(); set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ - push_indice_fx( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ + push_indice( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ Copy( xn_fx, xn2_fx, L_SUBFR ); /* target vector for codebook search */ set16_fx( y1_fx, 0, L_SUBFR ); /* set filtered adaptive excitation to 0 */ @@ -839,7 +839,7 @@ void transition_enc_fx( IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { - push_indice_fx( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } *Jopt_flag = 1; @@ -1886,7 +1886,7 @@ static void tc_enc_fx( /* write pitch index */ IF( ( GE_16( *T0, L_SUBFR ) ) && ( NE_16( *tc_subfr, 3 * L_SUBFR ) ) ) { - push_indice_fx( hBstr, IND_PITCH, 0, nBits ); + push_indice( hBstr, IND_PITCH, 0, nBits ); } ELSE IF( EQ_16( *tc_subfr, 3 * L_SUBFR ) ) { @@ -1898,7 +1898,7 @@ static void tc_enc_fx( { index = abs_pit_enc_fx( 2, 0, *T0, *T0_frac ); } - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); limit_T0_fx( L_FRAME, 8, 0, 0, *T0, 0, T0_min, T0_max ); } @@ -1907,12 +1907,12 @@ static void tc_enc_fx( IF( EQ_16( nBits, 6 ) ) { index = delta_pit_enc_fx( 2, *T0, *T0_frac, PIT_MIN - 1 ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } ELSE { index = delta_pit_enc_fx( 0, *T0, *T0_frac, PIT_MIN - 1 ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } } } @@ -1926,13 +1926,13 @@ static void tc_enc_fx( ELSE IF( EQ_16( nBits, 6 ) ) { index = add( shl( sub( *T0, PIT16k_MIN ), 1 ), shr( *T0_frac, 1 ) ); - push_indice_fx( hBstr, IND_PITCH, index, nBits ); + push_indice( hBstr, IND_PITCH, index, nBits ); } } - push_indice_fx( hBstr, IND_TC_IMP_SHAPE, imp_shape, 3 ); - push_indice_fx( hBstr, IND_TC_IMP_POS, imp_pos, 6 ); - push_indice_fx( hBstr, IND_TC_IMP_SIGN, pitch_sign_fx, 1 ); - push_indice_fx( hBstr, IND_TC_IMP_GAIN, pitch_index, 3 ); + push_indice( hBstr, IND_TC_IMP_SHAPE, imp_shape, 3 ); + push_indice( hBstr, IND_TC_IMP_POS, imp_pos, 6 ); + push_indice( hBstr, IND_TC_IMP_SIGN, pitch_sign_fx, 1 ); + push_indice( hBstr, IND_TC_IMP_GAIN, pitch_index, 3 ); *position = add( imp_pos, i_subfr ); move16(); diff --git a/lib_enc/voiced_enc_fx.c b/lib_enc/voiced_enc_fx.c index b0dba61de..8081b2909 100644 --- a/lib_enc/voiced_enc_fx.c +++ b/lib_enc/voiced_enc_fx.c @@ -1156,7 +1156,7 @@ ivas_error ppp_voiced_encoder_fx( { Q_delta_lag = add( delta_lag_E, 11 ); /* to make it positive always */ - push_indice_fx( hBstr, IND_DELTALAG, Q_delta_lag, 5 ); + push_indice( hBstr, IND_DELTALAG, Q_delta_lag, 5 ); } WIsyn_fx( *dtfs_temp_fx, CURRP_Q_E_FX, lpc2_fx, &( hSC_VBR->ph_offset_E_fx ), out_fx, L_FRAME, 0, S_fx, C_fx, -- GitLab From dd98b3e4fa57b4bc8b07e175610df09427ba1916 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 14:01:42 -0400 Subject: [PATCH 0732/1221] fix clang --- lib_enc/transition_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 253cc9717..6718552c5 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -803,7 +803,7 @@ void transition_enc_fx( *Jopt_flag = 0; move16(); - set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ + set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ push_indice( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ Copy( xn_fx, xn2_fx, L_SUBFR ); /* target vector for codebook search */ -- GitLab From 7fa6d1bb0c0fe89cb8226b89a80803ed9f59d4b5 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 14:05:40 -0400 Subject: [PATCH 0733/1221] replace EVS push_next_indice_fx byt IVAS one --- lib_com/bitstream_fx.c | 4 +- lib_com/igf_base_fx.c | 2 +- lib_com/parameter_bitmaping_fx.c | 2 +- lib_enc/ACcontextMapping_enc_fx.c | 2 +- lib_enc/ari_hm_enc_fx.c | 4 +- lib_enc/decision_matrix_enc_fx.c | 4 +- lib_enc/enc_prm_fx.c | 130 +++++++++++++++--------------- lib_enc/evs_enc_fx.c | 14 ++-- lib_enc/fd_cng_enc_fx.c | 4 +- lib_enc/guided_plc_enc_fx.c | 6 +- lib_enc/igf_enc_fx.c | 4 +- lib_enc/igf_scf_enc_fx.c | 2 +- lib_enc/lsf_msvq_ma_enc_fx.c | 10 +-- lib_enc/qlpc_avq_fx.c | 20 ++--- lib_enc/swb_tbe_enc_fx.c | 28 +++---- 15 files changed, 118 insertions(+), 118 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 667958264..8cb968bf1 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -288,9 +288,8 @@ void push_indice_fx( return; } -#endif /*-------------------------------------------------------------------* - * push_next_indice_fx() * + * push_next_indice() * * Push a new indice into the buffer at the next position *-------------------------------------------------------------------*/ @@ -315,6 +314,7 @@ void push_next_indice_fx( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_com/igf_base_fx.c b/lib_com/igf_base_fx.c index fbccdb519..44cf27c5f 100644 --- a/lib_com/igf_base_fx.c +++ b/lib_com/igf_base_fx.c @@ -1242,7 +1242,7 @@ void IGFCommonFuncsWriteSerialBit( IF( hBstr ) { - push_next_indice_fx( hBstr, bit, 1 ); + push_next_indice( hBstr, bit, 1 ); } *pBitOffset = add( *pBitOffset, 1 ); move16(); diff --git a/lib_com/parameter_bitmaping_fx.c b/lib_com/parameter_bitmaping_fx.c index 0846c618b..923872090 100644 --- a/lib_com/parameter_bitmaping_fx.c +++ b/lib_com/parameter_bitmaping_fx.c @@ -21,7 +21,7 @@ static Word16 PutIntoBitstream_fx( value = *( *pStream )++; codedValue = EncodeValue( value, index ); - push_next_indice_fx( hBstr, codedValue, nBits ); + push_next_indice( hBstr, codedValue, nBits ); return value; } diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index c52fddf97..4e02b1f11 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -343,7 +343,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( /* Push number of encoded tuples */ value = sub( shr( lastnz, 1 ), 1 ); /* Q0 */ - push_next_indice_fx( hBstr, value, nbbits_ntuples ); + push_next_indice( hBstr, value, nbbits_ntuples ); /* Push arithmetic coded bits */ push_next_bits_fx( hBstr, &ptr[nbbits_ntuples], sub( bp, nbbits_ntuples ) ); diff --git a/lib_enc/ari_hm_enc_fx.c b/lib_enc/ari_hm_enc_fx.c index 76d48ccf4..343f1890f 100644 --- a/lib_enc/ari_hm_enc_fx.c +++ b/lib_enc/ari_hm_enc_fx.c @@ -42,12 +42,12 @@ Word16 EncodeIndex_fx( NumRatioBitsBwLtpIndx = NumRatioBits[Bandwidth][LtpPitchIndex]; move16(); - push_next_indice_fx( hBst, s_and( PeriodicityIndex, 0xff ), NumRatioBitsBwLtpIndx ); + push_next_indice( hBst, s_and( PeriodicityIndex, 0xff ), NumRatioBitsBwLtpIndx ); return NumRatioBitsBwLtpIndx; } ELSE { - push_next_indice_fx( hBst, PeriodicityIndex, 8 ); + push_next_indice( hBst, PeriodicityIndex, 8 ); return 8; } } diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index 63a13aa1a..bc5feeb6b 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -527,8 +527,8 @@ void signalling_enc_fx( assert( !st_fx->tcxonly ); assert( st_fx->core == HQ_CORE ); - push_next_indice_fx( hBstr, 1, 1 ); /* TCX */ - push_next_indice_fx( hBstr, 1, 1 ); /* HQ_CORE */ + push_next_indice( hBstr, 1, 1 ); /* TCX */ + push_next_indice( hBstr, 1, 1 ); /* HQ_CORE */ /* write ACELP->HQ core switching flag */ test(); diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index ecd4e2f01..6c052e596 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -33,7 +33,7 @@ static void enc_prm_hm( } /* Flag */ - push_next_indice_fx( hBstr, prm_hm[0], 1 ); + push_next_indice( hBstr, prm_hm[0], 1 ); IF( prm_hm[0] ) { @@ -50,7 +50,7 @@ static void enc_prm_hm( IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) ) { /* Gain index */ - push_next_indice_fx( hBstr, prm_hm[2], kTcxHmNumGainBits ); + push_next_indice( hBstr, prm_hm[2], kTcxHmNumGainBits ); } } } @@ -152,7 +152,7 @@ void enc_prm_rf_ivas_fx( index = 3; move16(); } - push_next_indice_fx( hBstr, index, 2 ); + push_next_indice( hBstr, index, 2 ); IF( EQ_16( rf_frame_type, RF_TCXFD ) ) { @@ -296,9 +296,9 @@ void enc_prm_rf_fx( /* LSF indices */ IF( EQ_16( rf_frame_type, RF_TCXFD ) ) { - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][0], lsf_numbits[0] ); /* VQ 1 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][1], lsf_numbits[1] ); /* VQ 2 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][2], lsf_numbits[2] ); /* VQ 3 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][0], lsf_numbits[0] ); /* VQ 1 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][1], lsf_numbits[1] ); /* VQ 2 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][2], lsf_numbits[2] ); /* VQ 3 */ } /* classification */ @@ -324,12 +324,12 @@ void enc_prm_rf_fx( index = 3; move16(); } - push_next_indice_fx( hBstr, index, 2 ); + push_next_indice( hBstr, index, 2 ); IF( EQ_16( rf_frame_type, RF_TCXFD ) ) { /* TCX global gain = 7 bits */ - push_next_indice_fx( hBstr, hRF->rf_gain_tcx[fec_offset], 7 ); + push_next_indice( hBstr, hRF->rf_gain_tcx[fec_offset], 7 ); /*window info 1 bit for long overlap 2 if minimum or half overlap*/ @@ -345,35 +345,35 @@ void enc_prm_rf_fx( test(); IF( ( EQ_16( rf_frame_type, RF_TCXTD1 ) || EQ_16( rf_frame_type, RF_TCXTD2 ) ) && hTcxEnc->tcxltp != 0 ) { - push_next_indice_fx( hBstr, hRF->rf_tcxltp_param[fec_offset], 9 ); + push_next_indice( hBstr, hRF->rf_tcxltp_param[fec_offset], 9 ); } } } ELSE IF( EQ_16( rf_frame_type, 7 ) ) /* NELP bitstream writing */ { /* LSF indices */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ /* NELP gain indices */ - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_iG1[fec_offset], 5 ); - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][0], 6 ); - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][1], 6 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_iG1[fec_offset], 5 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][0], 6 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_iG2[fec_offset][1], 6 ); /* NELP filter selection index */ - push_next_indice_fx( hBstr, hRF->rf_indx_nelp_fid[fec_offset], 2 ); + push_next_indice( hBstr, hRF->rf_indx_nelp_fid[fec_offset], 2 ); /* tbe gainFr */ - push_next_indice_fx( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 5 ); + push_next_indice( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 5 ); } ELSE IF( GE_16( rf_frame_type, 4 ) ) /* rf_frame_type ALL_PRED: 4, NO_PRED: 5, GEN_PRED: 6 */ { /* LSF indices */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ - push_next_indice_fx( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][0], 8 ); /* VQ 1 */ + push_next_indice( hBstr, hRF->rf_indx_lsf[fec_offset][1], 8 ); /* VQ 2 */ /* ES pred */ - push_next_indice_fx( hBstr, hRF->rf_indx_EsPred[fec_offset], 3 ); + push_next_indice( hBstr, hRF->rf_indx_EsPred[fec_offset], 3 ); ltp_mode = ACELP_LTP_MODE[1][1][rf_frame_type]; /* Q0 */ ltf_mode = ACELP_LTF_MODE[1][1][rf_frame_type]; /* Q0 */ @@ -386,13 +386,13 @@ void enc_prm_rf_fx( n = ACELP_LTP_BITS_SFR[ltp_mode][sfr]; IF( n != 0 ) { - push_next_indice_fx( hBstr, hRF->rf_indx_pitch[fec_offset][sfr], n ); + push_next_indice( hBstr, hRF->rf_indx_pitch[fec_offset][sfr], n ); } /* Adaptive codebook filtering (1 bit) */ IF( EQ_16( ltf_mode, 2 ) ) { - push_next_indice_fx( hBstr, hRF->rf_indx_ltfMode[fec_offset][sfr], 1 ); + push_next_indice( hBstr, hRF->rf_indx_ltfMode[fec_offset][sfr], 1 ); } /*Innovative codebook*/ @@ -403,7 +403,7 @@ void enc_prm_rf_fx( ( EQ_16( rf_frame_type, RF_GENPRED ) && ( sfr == 0 || EQ_16( sfr, 2 ) ) ) ) { - push_next_indice_fx( hBstr, hRF->rf_indx_fcb[fec_offset][sfr], 7 ); + push_next_indice( hBstr, hRF->rf_indx_fcb[fec_offset][sfr], 7 ); } /* Gains (5b, 6b or 7b / subfr) */ @@ -411,11 +411,11 @@ void enc_prm_rf_fx( IF( sfr == 0 || EQ_16( sfr, 2 ) ) { n = ACELP_GAINS_BITS[gains_mode]; - push_next_indice_fx( hBstr, hRF->rf_indx_gain[fec_offset][sfr], n ); + push_next_indice( hBstr, hRF->rf_indx_gain[fec_offset][sfr], n ); } } /* tbe gainFr */ - push_next_indice_fx( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 2 ); + push_next_indice( hBstr, hRF->rf_indx_tbeGainFr[fec_offset], 2 ); } /***************/ @@ -429,15 +429,15 @@ void enc_prm_rf_fx( test(); IF( EQ_16( fec_offset, 2 ) ) { - push_next_indice_fx( hBstr, 0, 2 ); + push_next_indice( hBstr, 0, 2 ); } ELSE IF( EQ_16( fec_offset, 3 ) || EQ_16( fec_offset, 5 ) || EQ_16( fec_offset, 7 ) ) { - push_next_indice_fx( hBstr, ( fec_offset - 1 ) / 2, 2 ); + push_next_indice( hBstr, ( fec_offset - 1 ) / 2, 2 ); } /* write RF frame type last in the bitstream */ - push_next_indice_fx( hBstr, rf_frame_type, 3 ); + push_next_indice( hBstr, rf_frame_type, 3 ); } @@ -533,7 +533,7 @@ void enc_prm_fx( IF( st->tcxonly ) { - push_next_indice_fx( hBstr, core == TCX_10_CORE, 1 ); + push_next_indice( hBstr, core == TCX_10_CORE, 1 ); { index = 3; move16(); @@ -553,7 +553,7 @@ void enc_prm_fx( index = 2; move16(); } - push_next_indice_fx( hBstr, index, 2 ); + push_next_indice( hBstr, index, 2 ); } } ELSE @@ -581,13 +581,13 @@ void enc_prm_fx( { idx = add( idx, 1 ); /* Q0 */ } - push_next_indice_fx( hBstr, idx - start_idx, nBits ); - push_next_indice_fx( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ + push_next_indice( hBstr, idx - start_idx, nBits ); + push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ nbits_start = 3; /* Q0 */ } ELSE { - push_next_indice_fx( hBstr, coder_type, 3 ); + push_next_indice( hBstr, coder_type, 3 ); } } ELSE @@ -595,15 +595,15 @@ void enc_prm_fx( IF( EQ_16( st->mdct_sw, MODE1 ) ) { /* 2 bits instead of 3 as TCX is already signaled */ - push_next_indice_fx( hBstr, st->hTcxCfg->coder_type, 2 ); + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); } ELSE { IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) { - push_next_indice_fx( hBstr, 1, 1 ); /* TCX */ - push_next_indice_fx( hBstr, 0, 1 ); /* not HQ_CORE */ - push_next_indice_fx( hBstr, st->hTcxCfg->coder_type, 2 ); + push_next_indice( hBstr, 1, 1 ); /* TCX */ + push_next_indice( hBstr, 0, 1 ); /* not HQ_CORE */ + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); } ELSE { @@ -641,13 +641,13 @@ void enc_prm_fx( { idx = add( idx, 1 ); } - push_next_indice_fx( hBstr, idx - start_idx, nBits ); - push_next_indice_fx( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ + push_next_indice( hBstr, idx - start_idx, nBits ); + push_next_indice( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ nbits_start = 3; } ELSE { - push_next_indice_fx( hBstr, 4 + st->hTcxCfg->coder_type, 3 ); + push_next_indice( hBstr, 4 + st->hTcxCfg->coder_type, 3 ); } } } @@ -667,7 +667,7 @@ void enc_prm_fx( tmp = TCX_20_CORE; move16(); } - push_next_indice_fx( hBstr, tmp, 1 ); + push_next_indice( hBstr, tmp, 1 ); } /* write TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */ @@ -696,7 +696,7 @@ void enc_prm_fx( overlap_code = 0; move16(); } - push_next_indice_fx( hBstr, overlap_code, nbits_tcx ); + push_next_indice( hBstr, overlap_code, nbits_tcx ); } IF( st->hPlcExt->enableGplc ) @@ -719,7 +719,7 @@ void enc_prm_fx( IF( EQ_16( core, ACELP_CORE ) ) { - push_next_indice_fx( hBstr, st->glr_idx[0], G_LPC_RECOVERY_BITS ); + push_next_indice( hBstr, st->glr_idx[0], G_LPC_RECOVERY_BITS ); } } @@ -789,7 +789,7 @@ void enc_prm_fx( IF( n != 0 ) { - push_next_indice_fx( hBstr, st->bpf_gain_param, n ); + push_next_indice( hBstr, st->bpf_gain_param, n ); } /* Mean energy (2 or 3 bits) */ @@ -797,7 +797,7 @@ void enc_prm_fx( IF( n != 0 ) { - push_next_indice_fx( hBstr, prm[j++], n ); + push_next_indice( hBstr, prm[j++], n ); } /* Subframe parameters */ @@ -810,14 +810,14 @@ void enc_prm_fx( IF( n != 0 ) { - push_next_indice_fx( hBstr, prm[j++], n ); + push_next_indice( hBstr, prm[j++], n ); } /* Adaptive codebook filtering (1 bit) */ IF( EQ_16( st->acelp_cfg.ltf_mode, 2 ) ) { - push_next_indice_fx( hBstr, prm[j++], 1 ); + push_next_indice( hBstr, prm[j++], 1 ); } /*Innovative codebook*/ @@ -839,12 +839,12 @@ void enc_prm_fx( FOR( ix = 0; ix < wordcnt; ix++ ) { - push_next_indice_fx( hBstr, prm[j++], 16 ); + push_next_indice( hBstr, prm[j++], 16 ); } IF( bitcnt ) { - push_next_indice_fx( hBstr, prm[j++], bitcnt ); + push_next_indice( hBstr, prm[j++], bitcnt ); } j = add( j_old, 8 ); /* Q0 */ @@ -852,7 +852,7 @@ void enc_prm_fx( /* Gains (5b, 6b or 7b / subfr) */ n = ACELP_GAINS_BITS[st->acelp_cfg.gains_mode[sfr]]; - push_next_indice_fx( hBstr, prm[j++], n ); + push_next_indice( hBstr, prm[j++], n ); } /*end of for(sfr)*/ } /*end of mode[0]==0*/ @@ -866,14 +866,14 @@ void enc_prm_fx( move16(); IF( st->enablePlcWaveadjust ) { - push_next_indice_fx( hBstr, st->Tonal_SideInfo, 1 ); + push_next_indice( hBstr, st->Tonal_SideInfo, 1 ); } /* TCX Gain = 7 bits */ - push_next_indice_fx( hBstr, prm[j++], 7 ); + push_next_indice( hBstr, prm[j++], 7 ); /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ - push_next_indice_fx( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); + push_next_indice( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); /* LTP data */ test(); @@ -881,13 +881,13 @@ void enc_prm_fx( { IF( prm[j] ) { - push_next_indice_fx( hBstr, 1, 1 ); - push_next_indice_fx( hBstr, prm[j + 1], 9 ); - push_next_indice_fx( hBstr, prm[j + 2], 2 ); + push_next_indice( hBstr, 1, 1 ); + push_next_indice( hBstr, prm[j + 1], 9 ); + push_next_indice( hBstr, prm[j + 2], 2 ); } ELSE { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } } j = add( j, 3 ); @@ -932,7 +932,7 @@ void enc_prm_fx( test(); IF( st->hTcxCfg->ctx_hm && NE_16( last_core, ACELP_CORE ) ) { - push_next_indice_fx( hBstr, prm[j], 1 ); + push_next_indice( hBstr, prm[j], 1 ); IF( prm[j] ) { @@ -1015,14 +1015,14 @@ void enc_prm_fx( test(); IF( st->enablePlcWaveadjust && k ) { - push_next_indice_fx( hBstr, st->Tonal_SideInfo, 1 ); + push_next_indice( hBstr, st->Tonal_SideInfo, 1 ); } /* TCX Gain = 7 bits */ - push_next_indice_fx( hBstr, prm[j++], 7 ); + push_next_indice( hBstr, prm[j++], 7 ); /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ - push_next_indice_fx( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); + push_next_indice( hBstr, prm[j++], NBITS_NOISE_FILL_LEVEL ); /* LTP data */ test(); @@ -1031,13 +1031,13 @@ void enc_prm_fx( { IF( prm[j] ) { - push_next_indice_fx( hBstr, 1, 1 ); - push_next_indice_fx( hBstr, prm[j + 1], 9 ); - push_next_indice_fx( hBstr, prm[j + 2], 2 ); + push_next_indice( hBstr, 1, 1 ); + push_next_indice( hBstr, prm[j + 1], 9 ); + push_next_indice( hBstr, prm[j + 2], 2 ); } ELSE { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } } j = add( j, 3 ); @@ -1079,7 +1079,7 @@ void enc_prm_fx( test(); IF( st->hTcxCfg->ctx_hm && !( last_core == ACELP_CORE && k == 0 ) ) { - push_next_indice_fx( hBstr, prm[j], 1 ); + push_next_indice( hBstr, prm[j], 1 ); IF( prm[j] ) { diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index c86b7e061..396e97c6f 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -419,7 +419,7 @@ ivas_error evs_enc_fx( FOR( i = 0; i < padBits; i++ ) { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } } @@ -678,19 +678,19 @@ static void writeFrameHeader_loc( Encoder_State *st ) IF( EQ_16( st->cng_type, FD_CNG ) ) { /* write SID/CNG type flag */ - push_next_indice_fx( hBstr, 1, 1 ); + push_next_indice( hBstr, 1, 1 ); /* write bandwidth mode */ - push_next_indice_fx( hBstr, st->bwidth, 2 ); + push_next_indice( hBstr, st->bwidth, 2 ); /* write L_frame */ IF( EQ_16( st->L_frame, L_FRAME ) ) { - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); } ELSE { - push_next_indice_fx( hBstr, 1, 1 ); + push_next_indice( hBstr, 1, 1 ); } } } @@ -698,7 +698,7 @@ static void writeFrameHeader_loc( Encoder_State *st ) { IF( st->rf_mode == 0 ) { - push_next_indice_fx( hBstr, sub( st->bwidth, FrameSizeConfig[st->frame_size_index].bandwidth_min ), FrameSizeConfig[st->frame_size_index].bandwidth_bits ); + push_next_indice( hBstr, sub( st->bwidth, FrameSizeConfig[st->frame_size_index].bandwidth_min ), FrameSizeConfig[st->frame_size_index].bandwidth_bits ); } } @@ -706,7 +706,7 @@ static void writeFrameHeader_loc( Encoder_State *st ) test(); IF( FrameSizeConfig[st->frame_size_index].reserved_bits && st->rf_mode == 0 ) { - push_next_indice_fx( hBstr, 0, FrameSizeConfig[st->frame_size_index].reserved_bits ); + push_next_indice( hBstr, 0, FrameSizeConfig[st->frame_size_index].reserved_bits ); } } diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 2eb13646c..d182e4a44 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1211,9 +1211,9 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru { FOR( i = 0; i < stages_37bits; i++ ) { - push_next_indice_fx( hBstr, indices[i], bits_37bits[i] ); + push_next_indice( hBstr, indices[i], bits_37bits[i] ); } - push_next_indice_fx( hBstr, index, 7 ); + push_next_indice( hBstr, index, 7 ); } ELSE { diff --git a/lib_enc/guided_plc_enc_fx.c b/lib_enc/guided_plc_enc_fx.c index 60a3f8f50..81e50d099 100644 --- a/lib_enc/guided_plc_enc_fx.c +++ b/lib_enc/guided_plc_enc_fx.c @@ -215,7 +215,7 @@ void enc_prm_side_Info_fx( IF( GT_16( hPlc_Ext->nBits, 1 ) ) { - push_next_indice_fx( st->hBstr, 1, 1 ); + push_next_indice( st->hBstr, 1, 1 ); diff_pitch = sub( hPlc_Ext->T0, hPlc_Ext->T0_4th ); test(); @@ -225,11 +225,11 @@ void enc_prm_side_Info_fx( move16(); } - push_next_indice_fx( st->hBstr, add( diff_pitch, search_range ), bits_per_subfr ); + push_next_indice( st->hBstr, add( diff_pitch, search_range ), bits_per_subfr ); } ELSE { - push_next_indice_fx( st->hBstr, 0, 1 ); + push_next_indice( st->hBstr, 0, 1 ); } return; diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index cc4840876..f5c13df57 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1513,13 +1513,13 @@ Word16 IGFEncWriteConcatenatedBitstream_fx( tmp = shr( hPrivateData->igfBitstreamBits, 3 ); FOR( i = 0; i < tmp; i++ ) { - push_next_indice_fx( hBstr, pBitstream[i], 8 ); + push_next_indice( hBstr, pBitstream[i], 8 ); } bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 ); IF( bitsLeft > 0 ) { - push_next_indice_fx( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); + push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft ); } return hInstance->infoTotalBitsWritten; diff --git a/lib_enc/igf_scf_enc_fx.c b/lib_enc/igf_scf_enc_fx.c index 8659d53a1..ed52349dc 100644 --- a/lib_enc/igf_scf_enc_fx.c +++ b/lib_enc/igf_scf_enc_fx.c @@ -358,7 +358,7 @@ Word16 IGFSCFEncoderEncode_fx( { FOR( i = 0; i < hPublicData->ptrBitIndex; ++i ) { - push_next_indice_fx( hBstr, ptr[i], 1 ); + push_next_indice( hBstr, ptr[i], 1 ); } } diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index aa2255c68..8f6a21d03 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -834,7 +834,7 @@ Word16 enc_lsf_tcxlpc_fx( move16(); FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i ) { - push_next_indice_fx( hBstr, **indices, lsf_numbits[i] ); + push_next_indice( hBstr, **indices, lsf_numbits[i] ); ++*indices; } @@ -843,7 +843,7 @@ Word16 enc_lsf_tcxlpc_fx( NumBits = add( NumBits, TCXLPC_IND_NUMBITS ); FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i ) { - push_next_indice_fx( hBstr, **indices, lsf_ind_numbits[i] ); + push_next_indice( hBstr, **indices, lsf_ind_numbits[i] ); ++*indices; } } @@ -909,7 +909,7 @@ Word16 lsf_msvq_ma_encprm_fx( FOR( i = 0; i < no_indices; i++ ) { - push_next_indice_fx( hBstr, *param_lpc, bits_param_lpc[i] ); + push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] ); param_lpc++; nbits_lpc = add( nbits_lpc, bits_param_lpc[i] ); } @@ -919,7 +919,7 @@ Word16 lsf_msvq_ma_encprm_fx( IF( ( core == ACELP_CORE ) && acelp_midLpc ) { - push_next_indice_fx( hBstr, *param_lpc, bits_midlpc ); + push_next_indice( hBstr, *param_lpc, bits_midlpc ); nbits_lpc = add( nbits_lpc, bits_midlpc ); } } @@ -981,7 +981,7 @@ Word16 lsf_bctcvq_encprm_fx( FOR( i = 0; i < no_indices; i++ ) { - push_next_indice_fx( hBstr, *param_lpc, bits_param_lpc[i] ); + push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] ); param_lpc++; nbits_lpc = add( nbits_lpc, bits_param_lpc[i] ); } diff --git a/lib_enc/qlpc_avq_fx.c b/lib_enc/qlpc_avq_fx.c index 13e0a3cf7..288612e43 100644 --- a/lib_enc/qlpc_avq_fx.c +++ b/lib_enc/qlpc_avq_fx.c @@ -143,12 +143,12 @@ static Word16 unary_code( FOR( ; ind > 0; ind-- ) { - push_next_indice_fx( hBstr, 1, 1 ); + push_next_indice( hBstr, 1, 1 ); nb_bits = add( nb_bits, 1 ); // Q0 } /* Stop bit */ - push_next_indice_fx( hBstr, 0, 1 ); + push_next_indice( hBstr, 0, 1 ); return ( nb_bits ); } @@ -195,7 +195,7 @@ static Word16 unpack4bits( IF( nbits == 0 ) { - push_next_indice_fx( hBstr, 0, 0 ); + push_next_indice( hBstr, 0, 0 ); i = 1; move16(); } @@ -206,10 +206,10 @@ static Word16 unpack4bits( FOR( ; nbits > 4; nbits -= 4 ) { - push_next_indice_fx( hBstr, prm[i], 4 ); + push_next_indice( hBstr, prm[i], 4 ); i = add( i, 1 ); } - push_next_indice_fx( hBstr, prm[i], nbits ); + push_next_indice( hBstr, prm[i], nbits ); i = add( i, 1 ); } @@ -330,7 +330,7 @@ Word16 encode_lpc_avq_fx( { nb = 1; move16(); - push_next_indice_fx( hBstr, q_type, nb ); + push_next_indice( hBstr, q_type, nb ); } nb_bits = add( nb_bits, nb ); // Q0 @@ -342,7 +342,7 @@ Word16 encode_lpc_avq_fx( IF( ( ( q_type == 0 ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) || ( ( q_type == 0 ) && ( GE_16( st1, 0 ) ) && EQ_16( element_mode, IVAS_CPE_MDCT ) ) ) { /* Absolute quantizer with 1st stage stochastic codebook */ - push_next_indice_fx( hBstr, st1, bits_for_abs_quant ); + push_next_indice( hBstr, st1, bits_for_abs_quant ); nb_bits = add( nb_bits, bits_for_abs_quant ); // Q0 } @@ -350,7 +350,7 @@ Word16 encode_lpc_avq_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && EQ_16( stereo_mode, 3 ) && st1 < 0 ) { - push_next_indice_fx( hBstr, add( st1, 2 ), 1 ); + push_next_indice( hBstr, add( st1, 2 ), 1 ); nb_bits = add( nb_bits, 1 ); // Q0 } @@ -368,7 +368,7 @@ Word16 encode_lpc_avq_fx( move16(); i = 3; } - push_next_indice_fx( hBstr, i, 2 ); + push_next_indice( hBstr, i, 2 ); i = sub( qn2, 2 ); @@ -377,7 +377,7 @@ Word16 encode_lpc_avq_fx( move16(); i = 3; } - push_next_indice_fx( hBstr, i, 2 ); + push_next_indice( hBstr, i, 2 ); /* Unary code for abs and rel LPC0/LPC2 */ /* Q5 = 0, Q6=10, Q0=110, Q7=1110, ... */ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 1a14e7acb..316a5b549 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7579,10 +7579,10 @@ void tbe_write_bitstream_fx( IF( ( st_fx->rf_mode || EQ_32( st_fx->total_brate, ACELP_9k60 ) ) && ( EQ_16( st_fx->bwidth, WB ) ) ) { /* WB LSF */ - push_next_indice_fx( hBstr, hBWE_TD->lsf_WB, NUM_BITS_LBR_WB_LSF ); + push_next_indice( hBstr, hBWE_TD->lsf_WB, NUM_BITS_LBR_WB_LSF ); /* WB frame */ - push_next_indice_fx( hBstr, hBWE_TD->gFrame_WB, NUM_BITS_SHB_FrameGain_LBR_WB ); + push_next_indice( hBstr, hBWE_TD->gFrame_WB, NUM_BITS_SHB_FrameGain_LBR_WB ); } ELSE IF( ( GE_32( st_fx->total_brate, ACELP_9k60 ) ) && ( LE_32( st_fx->total_brate, ACELP_32k ) ) && ( ( EQ_16( st_fx->bwidth, SWB ) ) || ( EQ_16( st_fx->bwidth, FB ) ) ) ) @@ -7592,53 +7592,53 @@ void tbe_write_bitstream_fx( test(); IF( ( EQ_16( st_fx->rf_mode, 1 ) ) || EQ_32( st_fx->total_brate, ACELP_9k60 ) ) { - push_next_indice_fx( hBstr, hBWE_TD->lsf_idx[0], 8 ); + push_next_indice( hBstr, hBWE_TD->lsf_idx[0], 8 ); } ELSE { FOR( i = 0; i < NUM_Q_LSF; i++ ) { - push_next_indice_fx( hBstr, hBWE_TD->lsf_idx[i], lsf_q_num_bits[i] ); + push_next_indice( hBstr, hBWE_TD->lsf_idx[i], lsf_q_num_bits[i] ); } /* LSF mirror points */ - push_next_indice_fx( hBstr, hBWE_TD->m_idx, MIRROR_POINT_BITS ); + push_next_indice( hBstr, hBWE_TD->m_idx, MIRROR_POINT_BITS ); /* LSF grid points */ - push_next_indice_fx( hBstr, hBWE_TD->grid_idx, NUM_LSF_GRID_BITS ); + push_next_indice( hBstr, hBWE_TD->grid_idx, NUM_LSF_GRID_BITS ); } /* Gain shape */ - push_next_indice_fx( hBstr, hBWE_TD->idxSubGains, NUM_BITS_SHB_SUBGAINS ); + push_next_indice( hBstr, hBWE_TD->idxSubGains, NUM_BITS_SHB_SUBGAINS ); /* frame gain */ - push_next_indice_fx( hBstr, hBWE_TD->idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); + push_next_indice( hBstr, hBWE_TD->idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); IF( GE_32( st_fx->total_brate, ACELP_24k40 ) ) { /* sub frame energy*/ - push_next_indice_fx( hBstr, hBWE_TD->idx_shb_fr_gain, NUM_BITS_SHB_ENER_SF ); + push_next_indice( hBstr, hBWE_TD->idx_shb_fr_gain, NUM_BITS_SHB_ENER_SF ); /* gain shapes residual */ FOR( i = 0; i < NB_SUBFR16k; i++ ) { - push_next_indice_fx( hBstr, hBWE_TD->idx_res_gs[i], NUM_BITS_SHB_RES_GS ); + push_next_indice( hBstr, hBWE_TD->idx_res_gs[i], NUM_BITS_SHB_RES_GS ); } /* voicing factor */ - push_next_indice_fx( hBstr, hBWE_TD->idx_mixFac, NUM_BITS_SHB_VF ); + push_next_indice( hBstr, hBWE_TD->idx_mixFac, NUM_BITS_SHB_VF ); } IF( EQ_16( st_fx->tec_tfa, 1 ) ) { - push_next_indice_fx( hBstr, st_fx->tec_flag, BITS_TEC ); - push_next_indice_fx( hBstr, st_fx->tfa_flag, BITS_TFA ); + push_next_indice( hBstr, st_fx->tec_flag, BITS_TEC ); + push_next_indice( hBstr, st_fx->tfa_flag, BITS_TFA ); } } IF( EQ_16( st_fx->bwidth, FB ) ) { - push_next_indice_fx( hBstr, hBWE_TD->idxGain, 4 ); + push_next_indice( hBstr, hBWE_TD->idxGain, 4 ); } } -- GitLab From 469705796bbf1af9839f5b0042e670c2dbd6eaff Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 15:03:51 -0400 Subject: [PATCH 0734/1221] replace other EVS bitstream related stuff --- lib_com/bitstream_fx.c | 9 ++++++--- lib_enc/ACcontextMapping_enc_fx.c | 6 +++--- lib_enc/enc_prm_fx.c | 2 +- lib_enc/igf_enc.c | 4 ++-- lib_enc/igf_enc_fx.c | 4 ++-- lib_enc/lib_enc.c | 2 ++ lib_enc/tcx_utils_enc_fx.c | 26 +++++++++++++++++++++----- 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 8cb968bf1..d3aab2616 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -314,11 +314,10 @@ void push_next_indice_fx( return; } -#endif /*-------------------------------------------------------------------* - * push_next_bits_fx() + * push_next_bits() * Push a bit buffer into the buffer at the next position *-------------------------------------------------------------------*/ @@ -368,6 +367,7 @@ void push_next_bits_fx( hBstr->nb_bits_tot = add( hBstr->nb_bits_tot, nb_bits ); move16(); } +#endif /*-------------------------------------------------------------------* * get_next_indice_fx( ) @@ -565,6 +565,7 @@ void reset_indices_dec_fx( * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ +#if 0 void write_indices_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ @@ -663,12 +664,13 @@ void write_indices_fx( return; } +#endif /*-------------------------------------------------------------------* * write_indices_buf_fx() * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ - +#if 0 void write_indices_buf_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ @@ -772,6 +774,7 @@ void write_indices_buf_fx( return; } +#endif /*-------------------------------------------------------------------* * indices_to_serial() * diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 4e02b1f11..43bd30fd4 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -346,10 +346,10 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( push_next_indice( hBstr, value, nbbits_ntuples ); /* Push arithmetic coded bits */ - push_next_bits_fx( hBstr, &ptr[nbbits_ntuples], sub( bp, nbbits_ntuples ) ); + push_next_bits( hBstr, (UWord16 *) &ptr[nbbits_ntuples], sub( bp, nbbits_ntuples ) ); /* Push sign bits */ - push_next_bits_fx( hBstr, signs, nbbits_signs ); + push_next_bits( hBstr, (UWord16 *) signs, nbbits_signs ); bp = add( bp, nbbits_signs ); /* Q0 */ /*write residual Quantization bits*/ @@ -372,7 +372,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( assert( bp + k <= nbbits ); /* Push the rest of the buffer */ - push_next_bits_fx( hBstr, &ptr[bp], sub( nbbits, bp ) ); + push_next_bits( hBstr, (UWord16 *) &ptr[bp], sub( nbbits, bp ) ); return /*(bp+nbbits_lsbs)*/; /*return only for debug plot*/ } diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index 6c052e596..1d619e6c5 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -965,7 +965,7 @@ void enc_prm_fx( IF( hTcxEnc->tcx_lpc_shaped_ari != 0 ) { - push_next_bits_fx( hBstr, &prm[++j], nbits_tcx ); + push_next_bits( hBstr, ( UWord16 * ) &prm[++j], nbits_tcx ); j = add( j, nbits_tcx ); /* Q0 */ } ELSE diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 2680bd9f6..d0c9fa329 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2429,7 +2429,7 @@ void IGFEncSetMode_ivas_fx( * * IGF bitstream concatenation for TCX10 modes *-------------------------------------------------------------------*/ - +#if 0 /* Float code */ void IGFEncConcatenateBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ const Word16 bsBits, /* i : number of IGF bits written to list of indices */ @@ -2487,7 +2487,7 @@ move16(); return; } - +#endif /*-------------------------------------------------------------------* * IGFEncResetTCX10BitCounter_ivas_fx() diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index f5c13df57..a8a64422f 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1449,7 +1449,7 @@ hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); return; } - +#if 0 /* old bitstream */ /**********************************************************************/ /* IGF bitsream concatenation for TCX10 modes **************************************************************************/ @@ -1475,7 +1475,7 @@ void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /** move16(); return; } - +#endif /**********************************************************************/ /* IGF reset bitsream bit counter for TCX10 modes **************************************************************************/ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 877fc2045..b17ba61df 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1892,6 +1892,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } /* write indices into bitstream buffer */ +#if 0 IF( hEncoderConfig->element_mode_init == EVS_MONO ) { test(); @@ -1905,6 +1906,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } } ELSE +#endif { write_indices_ivas_fx( st_ivas, outputBitStream, numOutBits ); } diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 7d268b92a..fd6293124 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3650,7 +3650,7 @@ Word16 tcx_res_Q_spec_ivas_fx( return bits; } - +#if 1 //TV void ProcessIGF_fx( IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */ Encoder_State *st, /**< in: Encoder state */ @@ -3667,8 +3667,9 @@ void ProcessIGF_fx( Word16 igfGridIdx; Word16 isIndepFlag; Word16 bsBits; - Word16 bsStart; + Word16 bsStart, pBsStart; BSTR_ENC_HANDLE hBstr = st->hBstr; + IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc; isIndepFlag = 1; @@ -3721,6 +3722,8 @@ void ProcessIGF_fx( Word16 Q_A; Word16 predictionGain = 0; Word16 *flatteningTrigger = &( st->hIGFEnc->flatteningTrigger ); + + move32(); move16(); move16(); @@ -3750,6 +3753,7 @@ void ProcessIGF_fx( { IGFEncWriteBitstream_fx( hInstance, NULL, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } +#if 0 ELSE { IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); @@ -3760,8 +3764,20 @@ void ProcessIGF_fx( { IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot, hBstr->ind_list ); } -} +#else + ELSE + { + pBsStart = hBstr->nb_ind_tot; + move16(); + + IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); + bsBits = sub( hBstr->nb_ind_tot, pBsStart ); + IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr ); + } +#endif +} + #endif void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) { Word16 i, length, att; @@ -3877,7 +3893,7 @@ void ProcessIGF_ivas_fx( IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); bsBits = sub( hBstr->nb_ind_tot, pBsStart ); - IGFEncConcatenateBitstream( hIGFEnc, bsBits, hBstr ); + IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr ); } return; @@ -3981,7 +3997,7 @@ void ProcessStereoIGF_fx( IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); bsBits = sub( hBstr->nb_ind_tot, pBsStart ); - IGFEncConcatenateBitstream( hIGFEnc[ch], bsBits, hBstr ); + IGFEncConcatenateBitstream_ivas_fx( hIGFEnc[ch], bsBits, hBstr ); } } return; -- GitLab From 9a216fbc8ecfdb3dc23206dbaf79e82cfa70819c Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 15:06:06 -0400 Subject: [PATCH 0735/1221] fix clang --- lib_com/bitstream_fx.c | 2 +- lib_enc/enc_prm_fx.c | 4 ++-- lib_enc/tcx_utils_enc_fx.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index d3aab2616..f0e564a8a 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -664,7 +664,7 @@ void write_indices_fx( return; } -#endif +#endif /*-------------------------------------------------------------------* * write_indices_buf_fx() * diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index 1d619e6c5..6d6a2d575 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -583,7 +583,7 @@ void enc_prm_fx( } push_next_indice( hBstr, idx - start_idx, nBits ); push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ - nbits_start = 3; /* Q0 */ + nbits_start = 3; /* Q0 */ } ELSE { @@ -965,7 +965,7 @@ void enc_prm_fx( IF( hTcxEnc->tcx_lpc_shaped_ari != 0 ) { - push_next_bits( hBstr, ( UWord16 * ) &prm[++j], nbits_tcx ); + push_next_bits( hBstr, (UWord16 *) &prm[++j], nbits_tcx ); j = add( j, nbits_tcx ); /* Q0 */ } ELSE diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index fd6293124..06de6a2fa 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3650,7 +3650,7 @@ Word16 tcx_res_Q_spec_ivas_fx( return bits; } -#if 1 //TV +#if 1 // TV void ProcessIGF_fx( IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */ Encoder_State *st, /**< in: Encoder state */ @@ -3777,7 +3777,7 @@ void ProcessIGF_fx( } #endif } - #endif +#endif void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) { Word16 i, length, att; -- GitLab From 112e0cd6b0455ab87b74ddc78ada386a7d5b8f2d Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Tue, 25 Mar 2025 15:13:41 -0400 Subject: [PATCH 0736/1221] fix clang --- lib_enc/tcx_utils_enc_fx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 06de6a2fa..ec1db2cf3 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3667,7 +3667,11 @@ void ProcessIGF_fx( Word16 igfGridIdx; Word16 isIndepFlag; Word16 bsBits; +#if 0 Word16 bsStart, pBsStart; +#else + Word16 pBsStart; +#endif BSTR_ENC_HANDLE hBstr = st->hBstr; IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc; @@ -3744,8 +3748,9 @@ void ProcessIGF_fx( } } +#if 0 bsStart = hBstr->next_ind_fx; - +#endif move16(); hInstance->infoTotalBitsPerFrameWritten = 0; move16(); -- GitLab From 95ea2c5fb0bd8883ade9207dc5d36262b91f8f2f Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 26 Mar 2025 09:06:17 -0400 Subject: [PATCH 0737/1221] work on encoder config duplication --- lib_enc/ivas_init_enc_fx.c | 46 ++++++++++++++++++-------------------- lib_enc/lib_enc.c | 10 ++++++--- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 57858b03e..19996e2e4 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -463,7 +463,7 @@ void ivas_initialize_handles_enc_fx( * * Initialize IVAS encoder state structure *-------------------------------------------------------------------*/ - +#if 0 ivas_error ivas_init_encoder( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -1073,6 +1073,7 @@ ivas_error ivas_init_encoder( } return error; } +#endif ivas_error ivas_init_encoder_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -1100,10 +1101,10 @@ ivas_error ivas_init_encoder_fx( hEncoderConfig->last_ivas_total_brate = ivas_total_brate; /* Q0 */ move32(); - IF( NE_16( ivas_format, MONO_FORMAT ) ) + if ( NE_16( ivas_format, MONO_FORMAT ) ) { /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = extract_l( L_max( hEncoderConfig->max_bwidth, WB ) ); /* Q0 */ + hEncoderConfig->max_bwidth = s_max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ move16(); } st_ivas->ism_mode = ISM_MODE_NONE; @@ -1142,7 +1143,10 @@ ivas_error ivas_init_encoder_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point input audio buffer!\n" ) ); } + set32_fx( st_ivas->p_data_fx[n], 0, extract_l( Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); } + st_ivas->q_data_fx = Q11; + move16(); FOR( ; n < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { st_ivas->p_data_fx[n] = NULL; @@ -1196,7 +1200,7 @@ ivas_error ivas_init_encoder_fx( /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ - test(); + IF( EQ_32( ivas_format, MONO_FORMAT ) ) { st_ivas->nSCE = 1; /* in mono, there is always only one SCE */ @@ -1209,19 +1213,9 @@ ivas_error ivas_init_encoder_fx( move16(); test(); - IF( st_ivas->hEncoderConfig->element_mode_init == EVS_MONO ) + IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { - IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - ELSE - { - IF( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } /* prepare stereo downmix for EVS */ @@ -1342,7 +1336,7 @@ ivas_error ivas_init_encoder_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { - IF( hEncoderConfig->Opt_DTX_ON ) + if ( hEncoderConfig->Opt_DTX_ON ) { st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 1; move16(); @@ -1350,7 +1344,7 @@ ivas_error ivas_init_encoder_fx( } } - IF( st_ivas->nCPE > 1 ) + IF( GT_16( st_ivas->nCPE, 1 ) ) { IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { @@ -1358,7 +1352,7 @@ ivas_error ivas_init_encoder_fx( } } } - ELSE IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) ) + ELSE IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { Word32 ism_total_brate; Word16 k; @@ -1428,12 +1422,12 @@ ivas_error ivas_init_encoder_fx( ELSE IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) ) { st_ivas->ism_mode = ISM_MODE_NONE; - move32(); + move16(); IF( GE_32( ivas_total_brate, IVAS_256k ) ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; - move32(); + move16(); } IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) @@ -1523,7 +1517,7 @@ ivas_error ivas_init_encoder_fx( return error; } - IF( NE_32( st_ivas->mc_mode, MC_MODE_MCT ) ) + IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) ) { st_ivas->nSCE = 0; move16(); @@ -1596,7 +1590,9 @@ ivas_error ivas_init_encoder_fx( FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nCPE + st_ivas->nSCE ) ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nCPE, st_ivas->nSCE ), &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, res_dec ) ) != IVAS_ERR_OK ) { return error; } @@ -1658,7 +1654,9 @@ ivas_error ivas_init_encoder_fx( *-----------------------------------------------------------------*/ /* set number of input channels used for analysis/coding */ - n = getNumChanAnalysis_fx( st_ivas ); + n = getNumChanAnalysis_fx( st_ivas ); /* Q0 */ + move16(); + IF( n > 0 ) { IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL ) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index b17ba61df..52734b4bd 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -70,7 +70,7 @@ struct IVAS_ENC * Local functions *---------------------------------------------------------------------*/ -static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +//static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error setBandwidth_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_BANDWIDTH maxBandwidth ); static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); @@ -609,6 +609,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( return error; } +#if 0 ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const Word32 inputFs, /* i : input sampling frequency */ @@ -649,11 +650,12 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( hIvasEnc->maxBandwidthUser = max_bwidth_user; - error = configureEncoder_fx( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() ); + error = configureEncoder( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() ); return error; } +#endif /*---------------------------------------------------------------------* * IVAS_ENC_ConfigureForSBAObjects() * @@ -1188,7 +1190,7 @@ static ivas_error configureEncoder( * Finalize initialization *-----------------------------------------------------------------*/ - IF( ( error = ivas_init_encoder( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_init_encoder_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1211,6 +1213,7 @@ static ivas_error configureEncoder( return error; } +#if 0 static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, @@ -1543,6 +1546,7 @@ static ivas_error configureEncoder_fx( return error; } +#endif /*---------------------------------------------------------------------* * IVAS_ENC_GetDelay() * -- GitLab From a36f22ff48b932db898fa0f775876c998330e831 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 15:08:19 +0530 Subject: [PATCH 0738/1221] Fix for 3GPP issue 1444: OMASA float decoder crashes with BASOP created bitstream Link #1444 --- lib_enc/ivas_masa_enc_fx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 080a62a9d..2f060f681 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -3979,9 +3979,7 @@ static void quantize_ratio_ism_vector_ivas_fx( FOR( i = 0; i < no_ism_loc; i++ ) { - idx[i] = mult( ratio_ism_loc[i], max_sum_idx ); // exponent : ratio_ism_e + 15 - move16(); - idx[i] = shl( idx[i], sub( add( ratio_ism_e, 15 ), 15 ) ); // Q0 + idx[i] = extract_l( L_shr( L_mult0( ratio_ism_loc[i], max_sum_idx ), sub( 15, ratio_ism_e ) ) ); // Q0 move16(); part_idx_sum = add( part_idx_sum, idx[i] ); -- GitLab From e8635700ca462990bef565bfc8529611f790732c Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 26 Mar 2025 13:46:47 -0400 Subject: [PATCH 0739/1221] Addition of compiler switch, code compiles and run, but not BE --- lib_com/bitstream_fx.c | 7 +++--- lib_enc/igf_enc.c | 2 +- lib_enc/igf_enc_fx.c | 2 +- lib_enc/init_enc_fx.c | 48 ++++++++++++++++++++++++++++---------- lib_enc/ivas_init_enc_fx.c | 7 +++--- lib_enc/ivas_sce_enc_fx.c | 27 +++++++++++++++++---- lib_enc/lib_enc.c | 6 ++--- lib_enc/tcx_utils_enc_fx.c | 6 ++--- 8 files changed, 74 insertions(+), 31 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index f0e564a8a..f29dc6aee 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -244,7 +244,7 @@ Word16 rate2EVSmode( * * Push a new indice into the buffer *-------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_PUSH_BIT void push_indice_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ Word16 id, /* i : ID of the indice */ @@ -565,8 +565,7 @@ void reset_indices_dec_fx( * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ -#if 0 - +#ifndef HARM_PUSH_BIT void write_indices_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ @@ -670,7 +669,7 @@ void write_indices_fx( * * Write the buffer of indices to a file *-------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_PUSH_BIT void write_indices_buf_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index d0c9fa329..c8e8974c2 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2429,7 +2429,7 @@ void IGFEncSetMode_ivas_fx( * * IGF bitstream concatenation for TCX10 modes *-------------------------------------------------------------------*/ -#if 0 /* Float code */ +#ifndef HARM_PUSH_BIT /* Float code */ void IGFEncConcatenateBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ const Word16 bsBits, /* i : number of IGF bits written to list of indices */ diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index a8a64422f..96f8d0202 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1449,7 +1449,7 @@ hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); return; } -#if 0 /* old bitstream */ +#ifndef HARM_PUSH_BIT /* old bitstream */ /**********************************************************************/ /* IGF bitsream concatenation for TCX10 modes **************************************************************************/ diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index ea944dd75..4913e410d 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -20,6 +20,7 @@ * * Initialization of state variables *-----------------------------------------------------------------------*/ +#if 1 ivas_error init_encoder_fx( Encoder_State *st_fx /* i/o: Encoder static variables structure */ ) @@ -946,6 +947,7 @@ ivas_error init_encoder_fx( move32(); return error; } +#endif /*-----------------------------------------------------------------------* * LPDmem_enc_init_fx() * @@ -1498,14 +1500,7 @@ ivas_error init_encoder_ivas_fx( IF( st->element_mode == EVS_MONO ) { /* This is done to as in EVS T_CldfbVadState structure is present in Encoder State */ - /* - if ( ( st->hVAD_CLDFB = (VAD_CLDFB_HANDLE) malloc( sizeof( T_CldfbVadState ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB VAD\n" ) ); - } - */ st->hVAD_CLDFB = &st->vad_st; - vad_init_fx( st->hVAD_CLDFB ); } ELSE @@ -1670,9 +1665,23 @@ ivas_error init_encoder_ivas_fx( test(); IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) { - IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + IF( EQ_16( st->element_mode, EVS_MONO ) ) { - return error; + /* open analysis for input SR */ + st->input_frame_fx = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); + + if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, CLDFB_getNumChannels( st->input_Fs ), st->input_frame_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + { + return error; + } } } ELSE @@ -1784,11 +1793,20 @@ ivas_error init_encoder_ivas_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + IF( st->element_mode == EVS_MONO ) { - return error; + if ( ( error = openCldfb( &st->cldfbSynTd, CLDFB_SYNTHESIS, CLDFB_getNumChannels( 16000 ), L_FRAME16k ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + { + return error; + } } - InitSWBencBuffer_ivas_fx( st ); ResetSHBbuffer_Enc_fx( st ); } @@ -2144,7 +2162,13 @@ ivas_error init_encoder_ivas_fx( } ELSE { +#ifndef HARM_ENC_INIT InitTransientDetection_ivas_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); +#else + InitTransientDetection_fx( extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ), + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), + &st->transientDetection ); +#endif } /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 19996e2e4..7c72d4780 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -269,7 +269,7 @@ Word16 getNumChanAnalysis_fx( return n; } - +#ifndef HARM_ENC_INIT /*-------------------------------------------------------------------* * copy_encoder_config_ivas_fx() * @@ -321,6 +321,7 @@ void copy_encoder_config_ivas_fx( return; } +#endif /*-------------------------------------------------------------------* * copy_encoder_config_fx() * @@ -463,7 +464,7 @@ void ivas_initialize_handles_enc_fx( * * Initialize IVAS encoder state structure *-------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_ENC_INIT ivas_error ivas_init_encoder( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -1213,7 +1214,7 @@ ivas_error ivas_init_encoder_fx( move16(); test(); - IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index f1631ba4f..3f80cce2b 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -466,12 +466,31 @@ ivas_error create_sce_enc_fx( st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; move32(); move32(); - + st->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; + st->input_Fs = st_ivas->hEncoderConfig->input_Fs; + st->input_frame_fx = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); +#if 0 + IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) + //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) + //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) { return error; } - hSCE->hCoreCoder[0] = st; + //IF( NE_32( ( error = init_encoder_fx( st) ), IVAS_ERR_OK ) ) + //{ + // return error; + //} + + //st->hBstr->ind_list = ind_list; + // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; + //reset_indices_enc_fx( st->hBstr, MAX_NUM_INDICES ); +#endif + hSCE->hCoreCoder[0] = st; st_ivas->hSCE[sce_id] = hSCE; @@ -483,7 +502,7 @@ ivas_error create_sce_enc_fx( * * Create, allocate and initialize EVS encoder SCE handle *-------------------------------------------------------------------------*/ - +#if 0 ivas_error create_evs_sce_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 sce_id, /* i : SCE # identifier */ @@ -614,7 +633,7 @@ ivas_error create_evs_sce_enc_fx( return error; } - +#endif /*------------------------------------------------------------------------- * destroy_sce_enc_fx() * diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 52734b4bd..fdf410df5 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -609,7 +609,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( return error; } -#if 0 +#ifndef HARM_ENC_INIT ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const Word32 inputFs, /* i : input sampling frequency */ @@ -1213,7 +1213,7 @@ static ivas_error configureEncoder( return error; } -#if 0 +#ifndef HARM_ENC_INIT static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, @@ -1896,7 +1896,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } /* write indices into bitstream buffer */ -#if 0 +#ifndef HARM_PUSH_BIT IF( hEncoderConfig->element_mode_init == EVS_MONO ) { test(); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index ec1db2cf3..5bea901bb 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3667,7 +3667,7 @@ void ProcessIGF_fx( Word16 igfGridIdx; Word16 isIndepFlag; Word16 bsBits; -#if 0 +#ifndef HARM_PUSH_BIT Word16 bsStart, pBsStart; #else Word16 pBsStart; @@ -3748,7 +3748,7 @@ void ProcessIGF_fx( } } -#if 0 +#ifndef HARM_PUSH_BIT bsStart = hBstr->next_ind_fx; #endif move16(); @@ -3758,7 +3758,7 @@ void ProcessIGF_fx( { IGFEncWriteBitstream_fx( hInstance, NULL, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } -#if 0 +#ifndef HARM_PUSH_BIT ELSE { IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); -- GitLab From a5992c0d0657a48d492bd8258ccd44a56fb15add Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 26 Mar 2025 14:08:20 -0400 Subject: [PATCH 0740/1221] fix BE issue, still crashed mid-file --- lib_enc/ivas_init_enc_fx.c | 10 ++++++++-- lib_enc/ivas_sce_enc_fx.c | 41 +++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/lib_enc/ivas_init_enc_fx.c b/lib_enc/ivas_init_enc_fx.c index 7c72d4780..04b99f039 100644 --- a/lib_enc/ivas_init_enc_fx.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -1212,13 +1212,19 @@ ivas_error ivas_init_encoder_fx( move16(); sce_id = 0; move16(); - +#ifndef HARM_SCE_INIT + test(); + IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else test(); IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { return error; } - +#endif /* prepare stereo downmix for EVS */ IF( EQ_16( hEncoderConfig->stereo_dmx_evs, 1 ) ) { diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 3f80cce2b..2e1aed092 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -469,27 +469,11 @@ ivas_error create_sce_enc_fx( st->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; st->input_Fs = st_ivas->hEncoderConfig->input_Fs; st->input_frame_fx = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); -#if 0 - IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) - //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) - { - return error; - } -#else + IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) - //IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) { return error; } - //IF( NE_32( ( error = init_encoder_fx( st) ), IVAS_ERR_OK ) ) - //{ - // return error; - //} - - //st->hBstr->ind_list = ind_list; - // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; - //reset_indices_enc_fx( st->hBstr, MAX_NUM_INDICES ); -#endif hSCE->hCoreCoder[0] = st; st_ivas->hSCE[sce_id] = hSCE; @@ -502,7 +486,7 @@ ivas_error create_sce_enc_fx( * * Create, allocate and initialize EVS encoder SCE handle *-------------------------------------------------------------------------*/ -#if 0 +#ifndef HARM_SCE_INIT ivas_error create_evs_sce_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 sce_id, /* i : SCE # identifier */ @@ -624,9 +608,30 @@ ivas_error create_evs_sce_enc_fx( { return error; } +#ifdef HARM_PUSH_BIT + /*-----------------------------------------------------------------* + * Bitstream + *-----------------------------------------------------------------*/ + IF( ( st_fx->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); + } + + /* set pointer to the buffer of indices */ + st_fx->hBstr->ind_list = st_ivas->ind_list; + st_fx->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + st_fx->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; + st_fx->hBstr->nb_ind_tot = 0; + move16(); + st_fx->hBstr->nb_bits_tot = 0; + move16(); + st_fx->hBstr->st_ivas = st_ivas; +#else st_fx->hBstr->ind_list = ind_list; // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); +#endif + hSCE->hCoreCoder[0] = st_fx; st_ivas->hSCE[sce_id] = hSCE; -- GitLab From 3891a5187d17cdd2e3b49eddf983989ea42a73b9 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 09:43:27 -0400 Subject: [PATCH 0741/1221] fix during switching --- lib_com/bitstream_fx.c | 3 ++- lib_enc/acelp_core_switch_enc_fx.c | 18 +++++++++++++++++- lib_enc/stat_enc.h | 3 ++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index f29dc6aee..07a6a632f 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -530,11 +530,12 @@ void reset_indices_enc_fx( move16(); hBstr->nb_bits_tot = 0; move16(); +#ifndef HARM_PUSH_BIT hBstr->next_ind_fx = 0; move16(); hBstr->last_ind_fx = -1; move16(); - +#endif FOR( i = 0; i < max_num_indices; i++ ) { hBstr->ind_list[i].nb_bits = -1; diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 9b0ed8b58..8226748f7 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -62,7 +62,10 @@ void acelp_core_switch_enc_fx( Word16 Aq[2 * ( M + 1 )]; LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ BSTR_ENC_HANDLE hBstr = st_fx->hBstr; - +#ifdef HARM_PUSH_BIT + UWord16 value; + Word16 nb_bits; +#endif hLPDmem = st_fx->hLPDmem; /* initializations */ @@ -153,6 +156,18 @@ void acelp_core_switch_enc_fx( encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); +#ifdef HARM_PUSH_BIT + i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); +#ifdef DEBUGGING + assert( i >= 0 && "Internal error in ACELP core switching - unable to find ACELP subframe indices!" ); +#endif + while ( hBstr->ind_list[i].id == TAG_ACELP_SUBFR_LOOP_START ) + { + push_indice( hBstr, IND_CORE_SWITCHING_CELP_SUBFRAME, hBstr->ind_list[i].value, hBstr->ind_list[i].nb_bits ); + i++; + } + delete_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START ); +#else /*----------------------------------------------------------------* * bit-stream: modify the layer of sub frame CELP *----------------------------------------------------------------*/ @@ -165,6 +180,7 @@ void acelp_core_switch_enc_fx( hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits = -1; /* Q0 */ move16(); } +#endif /*----------------------------------------------------------------* * BWE encoding *----------------------------------------------------------------*/ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 64ab13ea2..5305a8bdc 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -92,9 +92,10 @@ typedef struct bitstream_enc_data_structure void *st_ivas; /* IVAS encoder structure */ // Word16 nb_bits_tot_fx; /* total number of bits already written */ // Indice *ind_list_fx; /* list of indices */ +#ifndef HARM_PUSH_BIT Word16 next_ind_fx; /* pointer to the next empty slot in the list of indices */ Word16 last_ind_fx; /* last written indice */ - +#endif } BSTR_ENC_DATA, *BSTR_ENC_HANDLE; /*----------------------------------------------------------------------------------* -- GitLab From 6b9dde261138ff69f80e1932e3156250ccdd672d Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 09:50:15 -0400 Subject: [PATCH 0742/1221] fix when erasing indices --- lib_enc/cng_enc_fx.c | 4 ++++ lib_enc/eval_pit_contr_fx.c | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 221454970..d6cb59b17 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2460,8 +2460,12 @@ static void shb_CNG_encod_fx( push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice( hBstr, IND_SID_BW, 1, 1 ); +#ifdef HARM_PUSH_BIT + delete_indice( hBstr, IND_CNG_ENV1 ); +#else hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; +#endif move16(); move16(); diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index df629f295..5e1c8dfe3 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -378,6 +378,16 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit move16(); set16_fx( pitch_buf, shl( L_SUBFR, 6 ), NB_SUBFR16k ); + +#ifdef HARM_PUSH_BIT + /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ + for ( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) + { + delete_indice( hBstr, i ); + } + + delete_indice( hBstr, IND_ES_PRED ); +#else /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ FOR( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) { @@ -396,6 +406,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit hBstr->ind_list[IND_ES_PRED].nb_bits = -1; move16(); } +#endif } IF( LT_32( st_fx->core_brate, CFREQ_BITRATE ) ) { -- GitLab From c0db989af3499a2dc4741b2059c6e6b6449524af Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 09:54:11 -0400 Subject: [PATCH 0743/1221] fix clang --- lib_enc/cng_enc_fx.c | 2 +- lib_enc/igf_enc_fx.c | 2 +- lib_enc/init_enc_fx.c | 2 +- lib_enc/ivas_sce_enc_fx.c | 2 +- lib_enc/lib_enc.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index d6cb59b17..b031ca528 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2460,7 +2460,7 @@ static void shb_CNG_encod_fx( push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice( hBstr, IND_SID_BW, 1, 1 ); -#ifdef HARM_PUSH_BIT +#ifdef HARM_PUSH_BIT delete_indice( hBstr, IND_CNG_ENV1 ); #else hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 96f8d0202..f508b313f 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1449,7 +1449,7 @@ hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); return; } -#ifndef HARM_PUSH_BIT /* old bitstream */ +#ifndef HARM_PUSH_BIT /* old bitstream */ /**********************************************************************/ /* IGF bitsream concatenation for TCX10 modes **************************************************************************/ diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 4913e410d..60e6019aa 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1675,7 +1675,7 @@ ivas_error init_encoder_ivas_fx( return error; } } - ELSE + ELSE { IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 2e1aed092..41127a98e 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -474,7 +474,7 @@ ivas_error create_sce_enc_fx( { return error; } - hSCE->hCoreCoder[0] = st; + hSCE->hCoreCoder[0] = st; st_ivas->hSCE[sce_id] = hSCE; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index fdf410df5..dd01386d8 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -70,7 +70,7 @@ struct IVAS_ENC * Local functions *---------------------------------------------------------------------*/ -//static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +// static ivas_error configureEncoder_fx( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error setBandwidth_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_BANDWIDTH maxBandwidth ); static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); -- GitLab From b0162e358ff26d71df3c137718ba8b22ac3b023a Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 11:34:05 -0400 Subject: [PATCH 0744/1221] fix reset indice for dtx case --- lib_enc/dtx_fx.c | 4 ++++ lib_enc/enc_ppp_fx.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index 9a66572ab..6d8a29795 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -838,7 +838,11 @@ void dtx_fx( /* reset the bitstream (IVAS format signalling was already written) */ IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { +#ifdef HARM_PUSH_BIT + reset_indices_enc_fx( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); +#else reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); +#endif } } diff --git a/lib_enc/enc_ppp_fx.c b/lib_enc/enc_ppp_fx.c index c2aeaa7ca..9d1ffad60 100644 --- a/lib_enc/enc_ppp_fx.c +++ b/lib_enc/enc_ppp_fx.c @@ -189,8 +189,11 @@ ivas_error encod_ppp_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ +#ifdef HARM_PUSH_BIT + reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); +#else reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); - +#endif /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); } @@ -373,8 +376,11 @@ ivas_error encod_ppp_ivas_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ +#ifdef HARM_PUSH_BIT + reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); +#else reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); - +#endif /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); } -- GitLab From faf1f546c95d0ea2d6dc16419b8e87dac5d92e57 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 27 Mar 2025 12:52:49 -0400 Subject: [PATCH 0745/1221] Fix bitrate switching --- lib_enc/lib_enc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index dd01386d8..063f39dea 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1817,6 +1817,16 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( /* set pointers to the new buffers of indices in each element */ FOR( n = 0; n < st_ivas->nSCE; n++ ) { +#ifdef HARM_PUSH_BIT + st_ivas->hSCE[n]->hCoreCoder[0]->hBstr->ind_list = st_ivas->ind_list; + st_ivas->hSCE[n]->hCoreCoder[0]->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + + if ( st_ivas->hSCE[n]->hMetaData != NULL ) + { + st_ivas->hSCE[n]->hMetaData->ind_list = st_ivas->ind_list_metadata; + st_ivas->hSCE[n]->hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; + } +#else test(); IF( !( hIvasEnc->hCoreCoder == NULL && EQ_32( hEncoderConfig->ivas_format, MONO_FORMAT ) ) ) { @@ -1832,6 +1842,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( st_ivas->hSCE[n]->hMetaData->ind_list = st_ivas->ind_list_metadata; st_ivas->hSCE[n]->hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; } +#endif } FOR( n = 0; n < st_ivas->nCPE; n++ ) -- GitLab From 7f70a132985455dcf07605cb195ace3a99637457 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 31 Mar 2025 11:41:23 +0200 Subject: [PATCH 0746/1221] Activate FIX_1379_MASA_ANGLE_ROUND (merge conflict resolution) --- lib_com/options.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_com/options.h b/lib_com/options.h index 4653bb460..59a6b3508 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,6 +68,7 @@ #endif /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ +#define FIX_1379_MASA_ANGLE_ROUND //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ -- GitLab From 74f18249e5b2aeafe6b8496089ab0e3534fd952d Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 31 Mar 2025 13:42:54 +0200 Subject: [PATCH 0747/1221] Reactivate FIX_1378_ACELP_OUT_OF_BOUNDS after merge from main --- lib_com/options.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 4653bb460..2b88deb5d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -67,6 +67,8 @@ #define BASOP_NOGLOB_DECLARE_LOCAL #endif +#define FIX_1378_ACELP_OUT_OF_BOUNDS + /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ -- GitLab From ed31c72d4671eb32825893b731f876f6e4ba7286 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 31 Mar 2025 15:42:03 +0200 Subject: [PATCH 0748/1221] Remove change of L_shl_sat/L_shl which is not supposed to be part of the merge request. --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 4c91b0c7b..2a2841966 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -930,7 +930,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( { L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); } - g0 = extract_h( L_shl_sat( L_g0, 14 ) ); + g0 = extract_h( L_shl( L_g0, 14 ) ); /* Scale signal i of 1/A(gamma1) */ IF( GT_16( g0, 1024 ) ) -- GitLab From 418c31c56a80dd8781186d904b896f49ad22d61e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 21:13:07 +0530 Subject: [PATCH 0749/1221] Fix for 3GPP issue 1448: Complexity measurement crashes: StereoDmxEVS Link #1448 --- lib_com/tools_fx.c | 4 ++-- lib_com/wi_fx.c | 8 ++++---- lib_enc/core_enc_updt_fx.c | 4 ++-- lib_enc/fd_cng_enc_fx.c | 2 +- lib_enc/gaus_enc_fx.c | 2 +- lib_enc/ppp_enc_fx.c | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5219d076c..9e5547c7d 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -3579,8 +3579,8 @@ Word16 erb_diff_search_fx( Word16 *prev_erb, const Word16 *curr_erb, Word16 *dif } ELSE { - dh = sub( dif_erb[i + offset], cb_fx[j * cb_dim + i] ); /* Q13 */ - Ltemp1 = L_mult( dh, dh ); /* Q27 */ + dh = sub_sat( dif_erb[i + offset], cb_fx[j * cb_dim + i] ); /* Q13 */ + Ltemp1 = L_mult_sat( dh, dh ); /* Q27 */ dh = extract_h( Ltemp1 ); dl = extract_l( Ltemp1 ); diff --git a/lib_com/wi_fx.c b/lib_com/wi_fx.c index 7df4cb3f0..85d9df472 100644 --- a/lib_com/wi_fx.c +++ b/lib_com/wi_fx.c @@ -2901,11 +2901,11 @@ void quant_target_fx( DTFS_STRUCTURE *X_fx, const Word16 *curr_lpc, Word16 *w, W Ltemp1 = log10_fx( Ltemp1 ); /* subtract 10log10(2)*(2Q-13), Q23 */ - Ltemp1 = L_sub( Ltemp1, Ltemp3 ); + Ltemp1 = L_sub_sat( Ltemp1, Ltemp3 ); Ltemp1 = L_max( 0, Ltemp1 ); Ltemp2 = getSpEngyFromResAmp_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, curr_lpc, sin_tab, cos_tab ); Ltemp2 = log10_fx( Ltemp2 ); /* Ltemp1=10log10(eng_hb), Q23, need to adjust for Q factor of energy (2Q-13) */ - Ltemp2 = L_sub( Ltemp2, Ltemp3 ); /* Ltemp2 in Q23 */ + Ltemp2 = L_sub_sat( Ltemp2, Ltemp3 ); /* Ltemp2 in Q23 */ Ltemp2 = L_max( 0, Ltemp2 ); @@ -2929,10 +2929,10 @@ void quant_target_fx( DTFS_STRUCTURE *X_fx, const Word16 *curr_lpc, Word16 *w, W tmp = round_fx( Ltemp ); /* tmp in Q(22-n) */ Ltemp1 = Mult_32_16( Ltemp1, tmp ); /* Q(30-n) */ n = sub( 8, exp ); - w[0] = round_fx( L_shl( Ltemp1, n ) ); /* w[0] in Q15 */ + w[0] = round_fx_sat( L_shl_sat( Ltemp1, n ) ); /* w[0] in Q15 */ move16(); Ltemp2 = Mult_32_16( Ltemp2, tmp ); - w[1] = round_fx( L_shl( Ltemp2, n ) ); /* w[1] in Q15 */ + w[1] = round_fx_sat( L_shl_sat( Ltemp2, n ) ); /* w[1] in Q15 */ move16(); logLag = log10_fx( X_fx->lag_fx ); /* logLag=10*log10(lag), Q23 */ diff --git a/lib_enc/core_enc_updt_fx.c b/lib_enc/core_enc_updt_fx.c index 305c2a92f..ce2681e75 100644 --- a/lib_enc/core_enc_updt_fx.c +++ b/lib_enc/core_enc_updt_fx.c @@ -171,8 +171,8 @@ void core_encode_update_cng_fx( tmp = sub( st->wspeech_enc[-1], shl( hLPDmem->mem_w0, shift ) ); E_UTIL_deemph2( negate( shift ), wsyn, st->preemph_fac, st->L_frame, &tmp ); - hLPDmem->mem_w0 = sub( st->wspeech_enc[st->L_frame - 1], tmp ); - hLPDmem->mem_w0 = shr( hLPDmem->mem_w0, shift ); + hLPDmem->mem_w0 = sub_sat( st->wspeech_enc[st->L_frame - 1], tmp ); + hLPDmem->mem_w0 = shr_sat( hLPDmem->mem_w0, shift ); move16(); move16(); /* Update LPC-related memories */ diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index d182e4a44..fbf5247c3 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -2066,7 +2066,7 @@ Word16 cng_energy_fx( L_tmp = L_mult0( tmp16, tmp16 ); pt_res++; tmp16 = shl( *pt_res, scale ); - L_tmp = L_mac0( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */ + L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */ pt_res++; L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */ } diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index 081cf7ef0..2aa9a5dff 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -90,7 +90,7 @@ Word16 gaus_encode_fx( exp_code = sub( exp_code, 18 + 6 ); /* exp: -18 (code in Q9), -6 (L_subfr = 64) */ Ltmp = Isqrt_lc( Ltmp, &exp_code ); - *gain_inov = extract_h( L_shl( Ltmp, sub( exp_code, 3 ) ) ); /* g_code_inov in Q12 */ + *gain_inov = extract_h( L_shl_sat( Ltmp, sub( exp_code, 3 ) ) ); /* g_code_inov in Q12 */ nb_bits = st_fx->acelp_cfg.gains_mode[tmp_idx]; /* Q0 */ move16(); diff --git a/lib_enc/ppp_enc_fx.c b/lib_enc/ppp_enc_fx.c index ac3d5836a..d6dc8b6d6 100644 --- a/lib_enc/ppp_enc_fx.c +++ b/lib_enc/ppp_enc_fx.c @@ -830,7 +830,7 @@ static void LPCPowSpect_fx( Lacc = L_add( Lacc, L_shr( L_mult( dh, dh ), 1 ) ); /* Lacc=Re^2+Im^2, Q22 */ exp = norm_l( Lacc ); - tmp = round_fx( L_shl( Lacc, exp ) ); + tmp = round_fx_sat( L_shl( Lacc, exp ) ); exp = sub( sub( 30, exp ), 22 ); /* tmp may potentially become negative, when Lacc is a very large value */ -- GitLab From 5bd27bba7b3a3e6a7027c20ba92f18a07b157c79 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 21:22:15 +0530 Subject: [PATCH 0750/1221] Clang formatting changes --- lib_com/wi_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/wi_fx.c b/lib_com/wi_fx.c index 85d9df472..591645017 100644 --- a/lib_com/wi_fx.c +++ b/lib_com/wi_fx.c @@ -2904,7 +2904,7 @@ void quant_target_fx( DTFS_STRUCTURE *X_fx, const Word16 *curr_lpc, Word16 *w, W Ltemp1 = L_sub_sat( Ltemp1, Ltemp3 ); Ltemp1 = L_max( 0, Ltemp1 ); Ltemp2 = getSpEngyFromResAmp_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, curr_lpc, sin_tab, cos_tab ); - Ltemp2 = log10_fx( Ltemp2 ); /* Ltemp1=10log10(eng_hb), Q23, need to adjust for Q factor of energy (2Q-13) */ + Ltemp2 = log10_fx( Ltemp2 ); /* Ltemp1=10log10(eng_hb), Q23, need to adjust for Q factor of energy (2Q-13) */ Ltemp2 = L_sub_sat( Ltemp2, Ltemp3 ); /* Ltemp2 in Q23 */ Ltemp2 = L_max( 0, Ltemp2 ); -- GitLab From 731ee44c7b9420febc977a032b4258304a977d49 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 11:29:12 +0200 Subject: [PATCH 0751/1221] introduce FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 --- lib_com/prot_fx.h | 8 +++++++- lib_dec/swb_tbe_dec_fx.c | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 19560b368..f74c3071d 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,7 +60,7 @@ #define TCX_IMDCT_HEADROOM 1 // *** Currently checking be-nes of all-inactive (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50048 -- DONE GREEN! -// *** Currently checking be speedups ( only modified version of FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) +// *** Currently checking be speedups ( only modified version of FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50073 // --> next test: check nonbe speedups // //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 @@ -73,6 +73,12 @@ // NUmbers none: 88,183 +//----------------------------------------------------------------------- +//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE - pipes TBD +// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) + + + /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 2b42e5b0d..3bc2868a2 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -6997,13 +6997,16 @@ void ivas_swb_tbe_dec_fx( move32(); } - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART K" ); + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" ); + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" ); /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth_fx32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" ); /* resample SHB synthesis (if needed) and scale down */ synth_scale_fx = 32767; move16(); /* 1.0 in Q15 */ @@ -7027,14 +7030,25 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); + +#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 + Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 +#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { +#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } +#else + Word16 idx; + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ + L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ +#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); @@ -7097,7 +7111,9 @@ void ivas_swb_tbe_dec_fx( Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" ); /* Update previous frame parameters for FEC */ Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); IF( EQ_16( st->codec_mode, MODE1 ) ) @@ -7134,8 +7150,9 @@ void ivas_swb_tbe_dec_fx( move16(); hBWE_TD->prev_Qx = Q_bwe_exc; move16(); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" );*/ - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART K" );*/ + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" );*/ return; } -- GitLab From a4e12092354a192740be4e4c76947ddb52088384 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 11:33:21 +0200 Subject: [PATCH 0752/1221] deactivate all speedups --- lib_com/prot_fx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index f74c3071d..5ab70a690 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -66,7 +66,7 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS // Numbers ALL: 83,45 // Numbers beOnly: 86,156 -- GitLab From a92a989cb0e0e181be2d633a81635b25ce9d3895 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 11:38:34 +0200 Subject: [PATCH 0753/1221] apply clang format patch --- lib_com/prot_fx.h | 1 - lib_com/swb_tbe_com_fx.c | 90 ++++++++++++++++++++-------------------- lib_dec/swb_tbe_dec_fx.c | 2 +- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 4b9832a24..2be66fe1f 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -78,7 +78,6 @@ // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) - /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d58825e59..12ab2c9b0 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6869,65 +6869,65 @@ void elliptic_bpf_48k_generic_fx( IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //0 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; FOR( ; i < L_FRAME48k / 3; ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat(L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX); //3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); //4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); //5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); //6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); //7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); //8 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; } diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 3bc2868a2..e73e541d0 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7032,7 +7032,7 @@ void ivas_swb_tbe_dec_fx( move16(); #ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 - Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 + Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 #endif FOR( i = 0; i < L_FRAME16k; i++ ) -- GitLab From 8b8c300aefb6b52b7cad8b390cbffcdecc0184ff Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 11:53:55 +0200 Subject: [PATCH 0754/1221] fixed and activated FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig to test BEnes --- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 2be66fe1f..652afe49c 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -66,7 +66,7 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS // Numbers ALL: 83,45 // Numbers beOnly: 86,156 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 12ab2c9b0..43250e441 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6843,7 +6843,7 @@ void elliptic_bpf_48k_generic_fx( } } ELSE -#else +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { FOR( i = 4; i < L_FRAME48k; i++ ) { @@ -6862,7 +6862,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ + #else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); @@ -6933,7 +6933,7 @@ void elliptic_bpf_48k_generic_fx( } } ELSE -#else +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { FOR( i = 4; i < L_FRAME48k; i++ ) { @@ -6949,7 +6949,6 @@ void elliptic_bpf_48k_generic_fx( move32(); } } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #endif -- GitLab From 38702cd5c3fc81cc7fac45ade3c955ea0991b992 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 12:24:28 +0200 Subject: [PATCH 0755/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 43250e441..95428c21d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6863,7 +6863,7 @@ void elliptic_bpf_48k_generic_fx( } } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) @@ -6952,7 +6952,7 @@ void elliptic_bpf_48k_generic_fx( #endif - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; -- GitLab From 6eb0cd70d55fb5bc62b92530660ad4e5eabdd73a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 12:58:08 +0200 Subject: [PATCH 0756/1221] fixed and activated FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 95428c21d..5fe3c6feb 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6800,7 +6800,7 @@ void elliptic_bpf_48k_generic_fx( move32(); i++; - FOR( ; i < L_FRAME48k / 3; ) + FOR( ; i < L_FRAME48k; ) { // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 @@ -6893,7 +6893,7 @@ void elliptic_bpf_48k_generic_fx( move32(); i++; - FOR( ; i < L_FRAME48k / 3; ) + FOR( ; i < L_FRAME48k; ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From f05199c15fed0855831d2f7bc55578dca010df22 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 13:37:01 +0200 Subject: [PATCH 0757/1221] add intended version of FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - should be BE --- lib_com/prot_fx.h | 8 ++++---- lib_com/swb_tbe_com_fx.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 652afe49c..929872cf1 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -66,11 +66,11 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 2 WMOPS +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 1 WMOPS -// Numbers ALL: 83,45 -// Numbers beOnly: 86,156 -// NUmbers none: 88,183 +// Numbers ALL: +// Numbers beOnly: 87,344 +// NUmbers none: 88,236 //----------------------------------------------------------------------- diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5fe3c6feb..d3c098b03 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6870,37 +6870,37 @@ void elliptic_bpf_48k_generic_fx( { i = 4; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; FOR( ; i < L_FRAME48k; ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6908,25 +6908,25 @@ void elliptic_bpf_48k_generic_fx( i++; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; -- GitLab From 1053f32f15c322af2dc07f3782f8d878103cfe8a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 13:39:40 +0200 Subject: [PATCH 0758/1221] minor: comments --- lib_com/prot_fx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 929872cf1..055515fca 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -63,12 +63,12 @@ // *** Currently checking be speedups ( only modified version of FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50073 // --> next test: check nonbe speedups // -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 1 WMOPS -// Numbers ALL: +// Numbers ALL: 84,189 // Numbers beOnly: 87,344 // NUmbers none: 88,236 -- GitLab From 88f73bf5943924910ebd93ef5167089d23b8818a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 13:41:34 +0200 Subject: [PATCH 0759/1221] apply clang format patch --- lib_com/swb_tbe_com_fx.c | 76 ++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d3c098b03..a4ded2bb5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6869,64 +6869,64 @@ void elliptic_bpf_48k_generic_fx( IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; FOR( ; i < L_FRAME48k; ) { - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; -- GitLab From e506102c2e7be503b61e528cc605c01136aa36a7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 15:25:03 +0200 Subject: [PATCH 0760/1221] activate FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 to test BEnes --- lib_com/prot_fx.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 055515fca..0344456e9 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -59,14 +59,12 @@ #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 -// *** Currently checking be-nes of all-inactive (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50048 -- DONE GREEN! -// *** Currently checking be speedups ( only modified version of FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig) for be-nes (should not fail!) https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50073 -// --> next test: check nonbe speedups + // -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // 1 WMOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // \ +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // > 3.1 WOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // / +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // .9 WMOPS -- all pipes green , BE // Numbers ALL: 84,189 // Numbers beOnly: 87,344 @@ -74,7 +72,7 @@ //----------------------------------------------------------------------- -//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE - pipes TBD +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE - pipes TBD // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) -- GitLab From 16c3fe08f2569ece6fae744dce05e8638ba39830 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 15:29:54 +0200 Subject: [PATCH 0761/1221] apply clang format patch --- lib_com/prot_fx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 0344456e9..31d67098b 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -62,7 +62,7 @@ // //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // \ -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // > 3.1 WOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // > 3.1 WOPS //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // / #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // .9 WMOPS -- all pipes green , BE -- GitLab From c864af93164520a9907db2134ce307152a179aae Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 15:47:57 +0200 Subject: [PATCH 0762/1221] fix multi line comment warning --- lib_com/prot_fx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 31d67098b..62d1168ce 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,10 +60,10 @@ #define TCX_IMDCT_HEADROOM 1 -// -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // \ -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // > 3.1 WOPS -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // / + +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // | > 3.1 WOPS +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // | #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // .9 WMOPS -- all pipes green , BE // Numbers ALL: 84,189 -- GitLab From c2b954488d33fa1b43967bb06b5a4eed6ec04b08 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 15:52:31 +0200 Subject: [PATCH 0763/1221] apply clang format patch --- lib_com/prot_fx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 62d1168ce..af393e5c6 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,7 +60,6 @@ #define TCX_IMDCT_HEADROOM 1 - //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // | //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // | > 3.1 WOPS //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // | -- GitLab From 0c377506f3a16129badb751787766eedc1a35ba3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 16:31:38 +0200 Subject: [PATCH 0764/1221] FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1, 2, 3 activation --- lib_com/prot_fx.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index af393e5c6..ea2c0c9e8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,18 +60,18 @@ #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // | > 3.1 WOPS -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // be // .9 WMOPS -- all pipes green , BE - +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // | > 3.1 WOPS +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // BE // .9 WMOPS -- all pipes green +// ^^^^^^^^ // Numbers ALL: 84,189 // Numbers beOnly: 87,344 // NUmbers none: 88,236 //----------------------------------------------------------------------- -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE - pipes TBD +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE, all pipes green! // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) -- GitLab From c87aa384050f075c0e270c011c081a0b8a25f737 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 1 Apr 2025 16:39:49 +0200 Subject: [PATCH 0765/1221] apply clang format patch --- lib_com/prot_fx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index ea2c0c9e8..883ef5492 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,11 +60,11 @@ #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 //nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 //nonbe // | > 3.1 WOPS -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 //nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WOPS +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // BE // .9 WMOPS -- all pipes green -// ^^^^^^^^ +// ^^^^^^^^ // Numbers ALL: 84,189 // Numbers beOnly: 87,344 // NUmbers none: 88,236 -- GitLab From 6f6165506aab955a2072277cd41e566794c17ec0 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 2 Apr 2025 01:15:47 +0200 Subject: [PATCH 0766/1221] simplify initial patch --- lib_enc/ext_sig_ana_fx.c | 2 -- lib_enc/ivas_mdct_core_enc_fx.c | 7 +++---- lib_enc/stat_enc.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 53c8d080b..087d892e3 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1385,8 +1385,6 @@ void core_signal_analysis_high_bitrate_ivas_fx( ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); } } - st->hTcxEnc->spectrum_length = L_subframe; - move16(); } diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 29ae0518c..e27ec8c11 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1251,8 +1251,9 @@ void ivas_mdct_core_whitening_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; - st->hTcxEnc->spectrum_length = st->hTcxEnc->L_frameTCX; - move16(); + init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); + st->hTcxEnc->spectrum_length = L_subframeTCX; + IF( GE_16( add( imult1616( hCPE->cpe_id, CPE_CHANNELS ), ch ), nChannels ) ) { CONTINUE; @@ -1268,8 +1269,6 @@ void ivas_mdct_core_whitening_enc_fx( core_signal_analysis_high_bitrate_ivas_fx( new_samples_fx[ch] + L_INP_MEM, T_op[ch], NULL, NULL, st, tnsSize[ch], tnsBits[ch], param_core[ch], <pBits[ch], windowedSignal_fx[ch], st->L_frame, st->hTcxEnc->L_frameTCX, hCPE->last_element_mode, 0, mdst_spectrum_fx[ch], mdst_spectrum_e[ch], &Q_new, &q_windowedSignal[ch] ); - st->hTcxEnc->spectrum_length = s_max( st->hTcxEnc->spectrum_length, st->hTcxEnc->L_frameTCX ); - move16(); /* BWD in MDCT domain */ IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 3977c4054..c6176709b 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1211,7 +1211,7 @@ typedef struct tcx_enc_structure Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ Word16 spectrum_long_e; /* MDCT output for a long block. Points to spectrum */ Word16 q_spectrum_long_fx; - Word16 spectrum_length; + Word16 spectrum_length; /* corresponds to L_frameTCX, used for scaling of MDCT/MDST buffers */ } TCX_ENC_DATA, *TCX_ENC_HANDLE; typedef struct TransientDetection -- GitLab From a6ea0a059f1d0a5989279f34aaaeb78416092985 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 28 Feb 2025 18:45:21 +0100 Subject: [PATCH 0767/1221] rewritten all cov_smooth loops with better precision - with optional debug output --- lib_com/ivas_cov_smooth_fx.c | 139 ++++++++++++++++++++++++++--------- 1 file changed, 106 insertions(+), 33 deletions(-) mode change 100644 => 100755 lib_com/ivas_cov_smooth_fx.c diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c old mode 100644 new mode 100755 index 3a93ed1f5..e0f759f5f --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -42,6 +42,13 @@ *-----------------------------------------------------------------------------------------*/ #define BAND_SMOOTH_REST_START_IDX ( 2 ) +#define ONEeN20_Q97 0x5E728433 // 1e-20 in Q97 1.584.563.251 + +//#define DEBUG_ivas_compute_smooth_cov_fx +#ifdef DEBUG_ivas_compute_smooth_cov_fx +#include +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_calculate_update_factor_fx() @@ -87,8 +94,14 @@ static void ivas_calculate_smoothning_factor_fx( move16(); tmp = BASOP_Util_Divide3232_Scale( update_factor, L_shl( L_deposit_l( min_pool_size ), Q22 ), &exp_diff ); // Q(31 - exp_diff) - *Smoothing_factor = L_shl_sat( L_deposit_l( tmp ), add( Q16, exp_diff ) ); // Q31 + *Smoothing_factor = L_shl_sat( L_deposit_h( tmp ), exp_diff ); // Q31 move32(); +#ifdef DEBUG_ivas_compute_smooth_cov_fx + printf( "Smoothing_factor %g update_factor %g min_pool_size %d j=%d\n", + (double) *Smoothing_factor * pow (2.0, -31), + (double) update_factor + pow (2.0, -22.0), min_pool_size, j ); +#endif + IF( NE_32( smooth_mode, COV_SMOOTH_MC ) ) { @@ -264,19 +277,17 @@ void ivas_spar_covar_smooth_enc_close_fx( return; } - /*-----------------------------------------------------------------------------------------* * Function ivas_compute_smooth_cov_fx() * * Compute smooth covariance real/imag. *-----------------------------------------------------------------------------------------*/ - static void ivas_compute_smooth_cov_fx( ivas_cov_smooth_state_t *hCovState, ivas_filterbank_t *pFb, Word32 *pCov_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], // i/o: Q(q_cov[i][j]) Word32 *pPrior_cov_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], // i: hCovState->q_cov_real_per_band[i][j][k] - const Word32 fac, + const Word32 fac, // i: ONEeN20_Q97 (1e-20 in Q97) const Word16 start_band, const Word16 end_band, const Word16 num_ch, @@ -285,10 +296,15 @@ static void ivas_compute_smooth_cov_fx( { Word16 i, j, k; Word16 prev_idx = hCovState->prior_bank_idx; - Word32 factor = 0, L_tmp, L_tmp1; + Word32 factor = 0, L_tmp0, L_tmp1; + + const Word16 q_fac = 97; + const Word16 fac_e = sub(Q31, q_fac); + + Word16 cov_buf_e; + Word16 sm_b; Word16 non_sm_b_idx; - Word16 q_tmp[IVAS_MAX_NUM_BANDS]; sm_b = BAND_SMOOTH_REST_START_IDX; move16(); @@ -296,7 +312,9 @@ static void ivas_compute_smooth_cov_fx( move32(); assert( end_band <= pFb->filterbank_num_bands ); - +#ifdef DEBUG_ivas_compute_smooth_cov_fx + printf( "\n" ); +#endif test(); IF( EQ_16( prev_idx, -1 ) || EQ_16( transient_det[1], 1 ) ) { @@ -309,11 +327,28 @@ static void ivas_compute_smooth_cov_fx( } FOR( i = 0; i < num_ch; i++ ) { +#ifdef DEBUG_ivas_compute_smooth_cov_fx + Word16 cov_buf_e = sub( Q31, q_cov[i][i] ); +#endif FOR( k = start_band; k < end_band; k++ ) { - L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ); // (Q31, Q31) -> Q31 - pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( hCovState->q_cov_real_per_band[i][i][k], Q31 ) ) ); // hCovState->q_cov_real_per_band[i][j][k] + /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */ +#ifdef DEBUG_ivas_compute_smooth_cov_fx + Word32 L_buf = pCov_buf[i][i][k]; /* debug !! */ +#endif + pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); + hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); + move16(); +#ifdef DEBUG_ivas_compute_smooth_cov_fx + printf( "A: pCov_buf[%d][%d][%d] %g (0x%08X 0x%04X) fac %g sm-factor %g buf %g\n", i, i, k, + (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), + pCov_buf[i][i][k], + hCovState->q_cov_real_per_band[i][i][k] & 0xFFFF, + (double) fac * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] *pow (2.0, -31.0), + (double) L_buf * pow(2.0, (double) -q_cov[i][i])); +#endif } } } @@ -326,38 +361,63 @@ static void ivas_compute_smooth_cov_fx( { IF( EQ_16( i, j ) ) { - factor = fac; // Q31 + factor = fac; // Q97 move32(); } ELSE { - factor = 0; + factor = 0; // Q97 move32(); } - set16_fx( q_tmp, q_cov[i][j], sub( end_band, start_band ) ); FOR( k = start_band; k < non_sm_b_idx; k++ ) { - L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // (Q31, q_cov[i][j]) -> q_cov[i][j] - L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // (Q31, hCovState->q_cov_real_per_band[i][j][k]) -> hCovState->q_cov_real_per_band[i][j][k] - pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &q_tmp[k] ); // Q(31 - q_tmp[k]) + /* ref: pCov_buf[i][j][k] = pPrior_cov_buf[i][j][k] + ( hCovState->pSmoothing_factor[k] * ( pCov_buf[i][j][k] - pPrior_cov_buf[i][j][k] + factor ) ); */ + /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + + pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) + + factor * hCovState->pSmoothing_factor[k] ); */ +#ifdef DEBUG_ivas_compute_smooth_cov_fx + Word32 L_buf = pCov_buf[i][j][k]; +#endif + L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // q_tmp0: q_cov[i][j] // (Q31, q_cov[i][j]) -> q_cov[i][j] + L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k] + L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e ); + pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp0, cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), fac_e, &cov_buf_e ); move32(); - q_tmp[k] = sub( Q31, q_tmp[k] ); // Q of pConv_buf[i][j][k] is now q_tmp[k] + hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); - L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_tmp[k], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_tmp[k] - pCov_buf[i][j][k] = L_add( pCov_buf[i][j][k], L_tmp ); // q_tmp[k] - move32(); + +#ifdef DEBUG_ivas_compute_smooth_cov_fx + printf( "B1: pCov_buf[%d][%d][%d] %g fac %g sm-factor %g prior %g buf %g (q=%d)\n", i, j, k, + (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), + (double) factor * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), + (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); +#endif + } - Copy( q_tmp, hCovState->q_cov_real_per_band[i][j], sub( end_band, start_band ) ); // Q of pCov_buf[i][j][k] is hCovState->q_cov_real_per_band[i][j][j] } } FOR( i = 0; i < num_ch; i++ ) { FOR( k = non_sm_b_idx; k < end_band; k++ ) { - L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ); // (Q31, Q31) -> Q31 - pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( hCovState->q_cov_real_per_band[i][i][k], Q31 ) ) ); // hCovState->q_cov_real_per_band[i][j][j] + /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */ +#ifdef DEBUG_ivas_compute_smooth_cov_fx + Word32 L_buf = pCov_buf[i][i][k]; +#endif + pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e , &cov_buf_e); move32(); + hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][i][k] + move16(); +#ifdef DEBUG_ivas_compute_smooth_cov_fx + printf( "B2: pCov_buf[%d][%d][%d] %g fac %g sm-factor %g buf %g (q=%d)\n", i, i, k, + (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), + (double) fac * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ), q_cov[i][i]); +#endif } } } @@ -369,28 +429,41 @@ static void ivas_compute_smooth_cov_fx( { IF( EQ_16( i, j ) ) { - factor = fac; // Q31 + factor = fac; // Q97 move32(); } ELSE { - factor = 0; + factor = 0; // Q97 move32(); } FOR( k = start_band; k < end_band; k++ ) { - L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // (Q31, q_cov[i][j]) -> q_cov[i][j] - L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // (Q31, hCovState->q_cov_real_per_band[i][j][k]) -> hCovState->q_cov_real_per_band[i][j][k] - pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &q_tmp[k] ); // Q(31 - q_tmp[k]) + /* ref: pCov_buf[i][j][k] = pPrior_cov_buf[i][j][k] + ( hCovState->pSmoothing_factor[k] * ( pCov_buf[i][j][k] - pPrior_cov_buf[i][j][k] + factor ) ); */ + /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + + pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) + + factor * hCovState->pSmoothing_factor[k] ); */ +#ifdef DEBUG_ivas_compute_smooth_cov_fx + Word32 L_buf = pCov_buf[i][j][k]; /* debug !! */ +#endif + L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // q_tmp0: q_cov[i][j] // (Q31, q_cov[i][j]) -> q_cov[i][j] + L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k] + L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e ); + pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp0, cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), fac_e, &cov_buf_e ); move32(); - q_tmp[k] = sub( Q31, q_tmp[k] ); // Q of pConv_buf[i][j][k] is now q_tmp[k] + hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); - L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_tmp[k], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_tmp[k] - pCov_buf[i][j][k] = L_add( pCov_buf[i][j][k], L_tmp ); // q_tmp[k] - move32(); +#ifdef DEBUG_ivas_compute_smooth_cov_fx + printf( "C: pCov_buf[%d][%d][%d] %g factor %g sm-factor %g prior %g buf %g (q=%d)\n", i, j, k, + (double) pCov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_cov_real_per_band[i][j][k]), + (double) factor * pow(2.0, (double) -q_fac), + (double) hCovState->pSmoothing_factor_fx[k] * pow(2.0, -Q31), + (double) pPrior_cov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); +#endif + } - Copy( q_tmp, hCovState->q_cov_real_per_band[i][j], sub( end_band, start_band ) ); // Q of pCov_buf[i][j][k] is hCovState->q_cov_real_per_band[i][j][j] } } } @@ -418,7 +491,7 @@ void ivas_cov_smooth_process_fx( Word16 i, j, k; Word16 num_bands = sub( end_band, start_band ); - ivas_compute_smooth_cov_fx( hCovState, pFb, cov_real, hCovState->pPrior_cov_real_fx, 0, start_band, end_band, num_ch, transient_det, q_cov ); + ivas_compute_smooth_cov_fx( hCovState, pFb, cov_real, hCovState->pPrior_cov_real_fx, ONEeN20_Q97, start_band, end_band, num_ch, transient_det, q_cov ); FOR( i = 0; i < num_ch; i++ ) { -- GitLab From 8629f3b47ec26c6ce64ea82e440ccc421a462291 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 10 Mar 2025 18:06:58 +0100 Subject: [PATCH 0768/1221] fixed issue with wrong q for prior variables - debug prints inactive --- lib_com/ivas_cov_smooth_fx.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index e0f759f5f..513f84ea0 100755 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -97,9 +97,9 @@ static void ivas_calculate_smoothning_factor_fx( *Smoothing_factor = L_shl_sat( L_deposit_h( tmp ), exp_diff ); // Q31 move32(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "Smoothing_factor %g update_factor %g min_pool_size %d j=%d\n", + printf( "Smoothing_factor %e update_factor %e min_pool_size %d j=%d\n", (double) *Smoothing_factor * pow (2.0, -31), - (double) update_factor + pow (2.0, -22.0), min_pool_size, j ); + (double) update_factor * pow (2.0, -22.0), min_pool_size, j ); #endif @@ -341,7 +341,7 @@ static void ivas_compute_smooth_cov_fx( hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "A: pCov_buf[%d][%d][%d] %g (0x%08X 0x%04X) fac %g sm-factor %g buf %g\n", i, i, k, + printf( "A: pCov_buf[%d][%d][%d] %e (0x%08X 0x%04X) fac %e sm-factor %e buf %e\n", i, i, k, (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), pCov_buf[i][i][k], hCovState->q_cov_real_per_band[i][i][k] & 0xFFFF, @@ -388,7 +388,7 @@ static void ivas_compute_smooth_cov_fx( move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "B1: pCov_buf[%d][%d][%d] %g fac %g sm-factor %g prior %g buf %g (q=%d)\n", i, j, k, + printf( "B1: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), (double) factor * pow( 2.0, (double) -q_fac ), (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), @@ -397,6 +397,11 @@ static void ivas_compute_smooth_cov_fx( #endif } + FOR( ; k < end_band; k++ ) + { + hCovState->q_cov_real_per_band[i][j][k] = q_cov[i][j]; + move16(); + } } } FOR( i = 0; i < num_ch; i++ ) @@ -412,7 +417,7 @@ static void ivas_compute_smooth_cov_fx( hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][i][k] move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "B2: pCov_buf[%d][%d][%d] %g fac %g sm-factor %g buf %g (q=%d)\n", i, i, k, + printf( "B2: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e buf %e (q=%d)\n", i, i, k, (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), (double) fac * pow( 2.0, (double) -q_fac ), (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), @@ -455,7 +460,7 @@ static void ivas_compute_smooth_cov_fx( hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "C: pCov_buf[%d][%d][%d] %g factor %g sm-factor %g prior %g buf %g (q=%d)\n", i, j, k, + printf( "C: pCov_buf[%d][%d][%d] %e factor %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, (double) pCov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_cov_real_per_band[i][j][k]), (double) factor * pow(2.0, (double) -q_fac), (double) hCovState->pSmoothing_factor_fx[k] * pow(2.0, -Q31), -- GitLab From ea5245e56e431269bb54c131dfcb6430683de21e Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 10 Mar 2025 18:32:18 +0100 Subject: [PATCH 0769/1221] fixed clang-format-issue --- lib_com/ivas_cov_smooth_fx.c | 76 ++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 39 deletions(-) mode change 100755 => 100644 lib_com/ivas_cov_smooth_fx.c diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c old mode 100755 new mode 100644 index 513f84ea0..150dc3bfc --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -42,7 +42,7 @@ *-----------------------------------------------------------------------------------------*/ #define BAND_SMOOTH_REST_START_IDX ( 2 ) -#define ONEeN20_Q97 0x5E728433 // 1e-20 in Q97 1.584.563.251 +#define ONEeN20_Q97 0x5E728433 // 1e-20 in Q97 1.584.563.251 //#define DEBUG_ivas_compute_smooth_cov_fx #ifdef DEBUG_ivas_compute_smooth_cov_fx @@ -94,12 +94,12 @@ static void ivas_calculate_smoothning_factor_fx( move16(); tmp = BASOP_Util_Divide3232_Scale( update_factor, L_shl( L_deposit_l( min_pool_size ), Q22 ), &exp_diff ); // Q(31 - exp_diff) - *Smoothing_factor = L_shl_sat( L_deposit_h( tmp ), exp_diff ); // Q31 + *Smoothing_factor = L_shl_sat( L_deposit_h( tmp ), exp_diff ); // Q31 move32(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "Smoothing_factor %e update_factor %e min_pool_size %d j=%d\n", - (double) *Smoothing_factor * pow (2.0, -31), - (double) update_factor * pow (2.0, -22.0), min_pool_size, j ); + printf( "Smoothing_factor %e update_factor %e min_pool_size %d j=%d\n", + (double) *Smoothing_factor * pow( 2.0, -31 ), + (double) update_factor * pow( 2.0, -22.0 ), min_pool_size, j ); #endif @@ -299,7 +299,7 @@ static void ivas_compute_smooth_cov_fx( Word32 factor = 0, L_tmp0, L_tmp1; const Word16 q_fac = 97; - const Word16 fac_e = sub(Q31, q_fac); + const Word16 fac_e = sub( Q31, q_fac ); Word16 cov_buf_e; @@ -334,20 +334,20 @@ static void ivas_compute_smooth_cov_fx( { /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */ #ifdef DEBUG_ivas_compute_smooth_cov_fx - Word32 L_buf = pCov_buf[i][i][k]; /* debug !! */ + Word32 L_buf = pCov_buf[i][i][k]; /* debug !! */ #endif pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "A: pCov_buf[%d][%d][%d] %e (0x%08X 0x%04X) fac %e sm-factor %e buf %e\n", i, i, k, - (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), - pCov_buf[i][i][k], - hCovState->q_cov_real_per_band[i][i][k] & 0xFFFF, - (double) fac * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] *pow (2.0, -31.0), - (double) L_buf * pow(2.0, (double) -q_cov[i][i])); + printf( "A: pCov_buf[%d][%d][%d] %e (0x%08X 0x%04X) fac %e sm-factor %e buf %e\n", i, i, k, + (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), + pCov_buf[i][i][k], + hCovState->q_cov_real_per_band[i][i][k] & 0xFFFF, + (double) fac * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -31.0 ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ) ); #endif } } @@ -366,14 +366,14 @@ static void ivas_compute_smooth_cov_fx( } ELSE { - factor = 0; // Q97 + factor = 0; // Q97 move32(); } FOR( k = start_band; k < non_sm_b_idx; k++ ) { /* ref: pCov_buf[i][j][k] = pPrior_cov_buf[i][j][k] + ( hCovState->pSmoothing_factor[k] * ( pCov_buf[i][j][k] - pPrior_cov_buf[i][j][k] + factor ) ); */ - /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + + /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) + factor * hCovState->pSmoothing_factor[k] ); */ #ifdef DEBUG_ivas_compute_smooth_cov_fx @@ -388,14 +388,13 @@ static void ivas_compute_smooth_cov_fx( move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "B1: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, - (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), - (double) factor * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), - (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); + printf( "B1: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, + (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), + (double) factor * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), + (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); #endif - } FOR( ; k < end_band; k++ ) { @@ -412,16 +411,16 @@ static void ivas_compute_smooth_cov_fx( #ifdef DEBUG_ivas_compute_smooth_cov_fx Word32 L_buf = pCov_buf[i][i][k]; #endif - pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e , &cov_buf_e); + pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][i][k] move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "B2: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e buf %e (q=%d)\n", i, i, k, - (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), - (double) fac * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ), q_cov[i][i]); + printf( "B2: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e buf %e (q=%d)\n", i, i, k, + (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), + (double) fac * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ), q_cov[i][i] ); #endif } } @@ -439,20 +438,20 @@ static void ivas_compute_smooth_cov_fx( } ELSE { - factor = 0; // Q97 + factor = 0; // Q97 move32(); } FOR( k = start_band; k < end_band; k++ ) { /* ref: pCov_buf[i][j][k] = pPrior_cov_buf[i][j][k] + ( hCovState->pSmoothing_factor[k] * ( pCov_buf[i][j][k] - pPrior_cov_buf[i][j][k] + factor ) ); */ - /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + + /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) + factor * hCovState->pSmoothing_factor[k] ); */ #ifdef DEBUG_ivas_compute_smooth_cov_fx Word32 L_buf = pCov_buf[i][j][k]; /* debug !! */ #endif - L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // q_tmp0: q_cov[i][j] // (Q31, q_cov[i][j]) -> q_cov[i][j] + L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // q_tmp0: q_cov[i][j] // (Q31, q_cov[i][j]) -> q_cov[i][j] L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k] L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e ); pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp0, cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), fac_e, &cov_buf_e ); @@ -460,14 +459,13 @@ static void ivas_compute_smooth_cov_fx( hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); #ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "C: pCov_buf[%d][%d][%d] %e factor %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, - (double) pCov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_cov_real_per_band[i][j][k]), - (double) factor * pow(2.0, (double) -q_fac), - (double) hCovState->pSmoothing_factor_fx[k] * pow(2.0, -Q31), - (double) pPrior_cov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); + printf( "C: pCov_buf[%d][%d][%d] %e factor %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, + (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), + (double) factor * pow( 2.0, (double) -q_fac ), + (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), + (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), + (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); #endif - } } } -- GitLab From 73859be2519bd242ff115fbcf4c385103d6c1e74 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 25 Mar 2025 22:16:40 +0100 Subject: [PATCH 0770/1221] corrected use of exponents of cov_buf matrices --- lib_com/ivas_cov_smooth_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index 150dc3bfc..1b9cb5c99 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -328,7 +328,7 @@ static void ivas_compute_smooth_cov_fx( FOR( i = 0; i < num_ch; i++ ) { #ifdef DEBUG_ivas_compute_smooth_cov_fx - Word16 cov_buf_e = sub( Q31, q_cov[i][i] ); + cov_buf_e = sub( Q31, q_cov[i][i] ); #endif FOR( k = start_band; k < end_band; k++ ) { @@ -336,7 +336,7 @@ static void ivas_compute_smooth_cov_fx( #ifdef DEBUG_ivas_compute_smooth_cov_fx Word32 L_buf = pCov_buf[i][i][k]; /* debug !! */ #endif - pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); + pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub(Q31, q_cov[i][i]), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); move16(); -- GitLab From 5be8b9cff93c419462f8d16cabf1824a8cd095e7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 25 Mar 2025 23:58:59 +0100 Subject: [PATCH 0771/1221] fix clang-format issue --- lib_com/ivas_cov_smooth_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index 1b9cb5c99..d7cabd0db 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -336,7 +336,7 @@ static void ivas_compute_smooth_cov_fx( #ifdef DEBUG_ivas_compute_smooth_cov_fx Word32 L_buf = pCov_buf[i][i][k]; /* debug !! */ #endif - pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub(Q31, q_cov[i][i]), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); + pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); move16(); -- GitLab From 47ecefacad3c2aa92dfca1499986d11df69b0e55 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 31 Mar 2025 20:52:36 +0200 Subject: [PATCH 0772/1221] remove debug code --- lib_com/ivas_cov_smooth_fx.c | 60 ------------------------------------ 1 file changed, 60 deletions(-) diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index d7cabd0db..a50f5d2d2 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -44,11 +44,6 @@ #define BAND_SMOOTH_REST_START_IDX ( 2 ) #define ONEeN20_Q97 0x5E728433 // 1e-20 in Q97 1.584.563.251 -//#define DEBUG_ivas_compute_smooth_cov_fx -#ifdef DEBUG_ivas_compute_smooth_cov_fx -#include -#endif - /*-----------------------------------------------------------------------------------------* * Function ivas_calculate_update_factor_fx() @@ -96,11 +91,6 @@ static void ivas_calculate_smoothning_factor_fx( tmp = BASOP_Util_Divide3232_Scale( update_factor, L_shl( L_deposit_l( min_pool_size ), Q22 ), &exp_diff ); // Q(31 - exp_diff) *Smoothing_factor = L_shl_sat( L_deposit_h( tmp ), exp_diff ); // Q31 move32(); -#ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "Smoothing_factor %e update_factor %e min_pool_size %d j=%d\n", - (double) *Smoothing_factor * pow( 2.0, -31 ), - (double) update_factor * pow( 2.0, -22.0 ), min_pool_size, j ); -#endif IF( NE_32( smooth_mode, COV_SMOOTH_MC ) ) @@ -312,9 +302,6 @@ static void ivas_compute_smooth_cov_fx( move32(); assert( end_band <= pFb->filterbank_num_bands ); -#ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "\n" ); -#endif test(); IF( EQ_16( prev_idx, -1 ) || EQ_16( transient_det[1], 1 ) ) { @@ -327,28 +314,13 @@ static void ivas_compute_smooth_cov_fx( } FOR( i = 0; i < num_ch; i++ ) { -#ifdef DEBUG_ivas_compute_smooth_cov_fx - cov_buf_e = sub( Q31, q_cov[i][i] ); -#endif FOR( k = start_band; k < end_band; k++ ) { /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */ -#ifdef DEBUG_ivas_compute_smooth_cov_fx - Word32 L_buf = pCov_buf[i][i][k]; /* debug !! */ -#endif pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); move16(); -#ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "A: pCov_buf[%d][%d][%d] %e (0x%08X 0x%04X) fac %e sm-factor %e buf %e\n", i, i, k, - (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), - pCov_buf[i][i][k], - hCovState->q_cov_real_per_band[i][i][k] & 0xFFFF, - (double) fac * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -31.0 ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ) ); -#endif } } } @@ -376,9 +348,6 @@ static void ivas_compute_smooth_cov_fx( /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) + factor * hCovState->pSmoothing_factor[k] ); */ -#ifdef DEBUG_ivas_compute_smooth_cov_fx - Word32 L_buf = pCov_buf[i][j][k]; -#endif L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // q_tmp0: q_cov[i][j] // (Q31, q_cov[i][j]) -> q_cov[i][j] L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k] L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e ); @@ -387,14 +356,6 @@ static void ivas_compute_smooth_cov_fx( hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); -#ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "B1: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, - (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), - (double) factor * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), - (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); -#endif } FOR( ; k < end_band; k++ ) { @@ -408,20 +369,10 @@ static void ivas_compute_smooth_cov_fx( FOR( k = non_sm_b_idx; k < end_band; k++ ) { /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */ -#ifdef DEBUG_ivas_compute_smooth_cov_fx - Word32 L_buf = pCov_buf[i][i][k]; -#endif pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e ); move32(); hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][i][k] move16(); -#ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "B2: pCov_buf[%d][%d][%d] %e fac %e sm-factor %e buf %e (q=%d)\n", i, i, k, - (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), - (double) fac * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ), q_cov[i][i] ); -#endif } } } @@ -448,9 +399,6 @@ static void ivas_compute_smooth_cov_fx( /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) + factor * hCovState->pSmoothing_factor[k] ); */ -#ifdef DEBUG_ivas_compute_smooth_cov_fx - Word32 L_buf = pCov_buf[i][j][k]; /* debug !! */ -#endif L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // q_tmp0: q_cov[i][j] // (Q31, q_cov[i][j]) -> q_cov[i][j] L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k] L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e ); @@ -458,14 +406,6 @@ static void ivas_compute_smooth_cov_fx( move32(); hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); -#ifdef DEBUG_ivas_compute_smooth_cov_fx - printf( "C: pCov_buf[%d][%d][%d] %e factor %e sm-factor %e prior %e buf %e (q=%d)\n", i, j, k, - (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ), - (double) factor * pow( 2.0, (double) -q_fac ), - (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ), - (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ), - (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] ); -#endif } } } -- GitLab From b9604e9df6c79950b6267cac69f14f066b79b740 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 31 Mar 2025 21:04:12 +0200 Subject: [PATCH 0773/1221] formatting --- lib_com/ivas_cov_smooth_fx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/ivas_cov_smooth_fx.c b/lib_com/ivas_cov_smooth_fx.c index a50f5d2d2..9a8de3c1f 100644 --- a/lib_com/ivas_cov_smooth_fx.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -355,7 +355,6 @@ static void ivas_compute_smooth_cov_fx( move32(); hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k] move16(); - } FOR( ; k < end_band; k++ ) { -- GitLab From cb180abb1baf83ada5a1a82e23e582573432c2f9 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 2 Apr 2025 12:35:33 +0530 Subject: [PATCH 0774/1221] Fix for 3GPP issue 1452: Decoder crash for FOA at 96kbps JBM decoding to FOA in TonalMDCTConceal_InsertNoise_ivas_fx() Link #1452 --- lib_dec/tonalMDCTconcealment_fx.c | 154 +++++++++++++++--------------- 1 file changed, 75 insertions(+), 79 deletions(-) diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index e74df3a96..bc7e1d536 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -1383,12 +1383,15 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( Word16 rnd; Word16 tmp, g, tilt, exp_last, exp_noise, tiltFactor, crossfadeGain, e_crossfadeGain; - Word32 L_tmp, L_tmp2, nrgNoiseInLastFrame, nrgWhiteNoise; + Word32 L_tmp, L_tmp1, L_tmp2, nrgNoiseInLastFrame, nrgWhiteNoise; Word16 inv_exp, inv_samples, exp; Word32 last_block_nrg_correct; Word16 last_block_nrg_correct_e; Word32 max_concealment_value; Word16 max_spectral_value; + Word64 sum1, sum2; + Word16 num16, den16, exp1, exp2; + Word16 shift1, shift2; crossfadeGain = crossfadeGain_const; move16(); @@ -1851,28 +1854,36 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( } } ELSE{ - IF( !tonalConcealmentActive ){ - ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) ); - fac = shr( -32768, ld ); - + IF( tonalConcealmentActive == 0 ){ + sum1 = 0; + sum2 = 0; + move64(); + move64(); FOR( i = 0; i < crossOverFreq; i++ ) { - Word16 x = hTonalMDCTConc->lastBlockData.spectralData[i]; - Word32 y; - rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); /* Q0 */ - y = L_mult( tilt, rnd ); /* 15Q16 */ + Word16 x; + /*x = hTonalMDCTConc->lastBlockData.spectralData[i]; + nrgNoiseInLastFrame += x * x;*/ + sum1 = W_mac0_16_16( sum1, hTonalMDCTConc->lastBlockData.spectralData[i], hTonalMDCTConc->lastBlockData.spectralData[i] ); // Q: 2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp) - nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - x_exp - ld) + Q(15 - x_exp) - 15 = Q(31 - x_exp * 2 - ld) - x = round_fx( y ); /* 15Q16 -> 15Q0 */ - nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - (15 - 0) - ld) + Q(0) - 15 = Q(1 - ld) + /* rnd = own_random(&rnd); */ + rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); /* Q0 */ - mdctSpectrum[i] = y; /* 15Q16 */ + /* mdctSpectrum[i] = tilt * rnd; */ + mdctSpectrum[i] = L_mult( tilt, rnd ); // Q16 move32(); + /* tilt *= tiltFactor; */ tilt = mult_r( tilt, tiltFactor ); /* Q15 */ + + /* nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i]; */ + x = round_fx( mdctSpectrum[i] ); // Q0 + sum2 = W_mac0_16_16( sum2, x, x ); // Q0 } + *mdctSpectrum_exp = 15; + move16(); - IF( nrgNoiseInLastFrame == 0 ) + IF( sum1 /* nrgNoiseInLastFrame */ == 0 ) { set32_fx( mdctSpectrum, 0, crossOverFreq ); *mdctSpectrum_exp = SPEC_EXP_DEC; @@ -1880,85 +1891,70 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( } ELSE { - exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ); - exp_noise = add( ld, 30 ); - - IF( nrgWhiteNoise > 0 ) + IF( g == 0 ) { - ld = norm_l( nrgNoiseInLastFrame ); - nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31- exp_last + ld - exp_last = sub( exp_last, ld ); - ld = norm_l( nrgWhiteNoise ); - nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31 - exp_noise + ld - exp_noise = sub( exp_noise, ld ); - - exp = sub( exp_last, exp_noise ); - - IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) ) - { - nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31-exp -1 - exp = add( exp, 1 ); - } - tmp = div_l( nrgNoiseInLastFrame, round_fx( nrgWhiteNoise ) ); // Q15 - tmp = Sqrt16( tmp, &exp ); - g = mult_r( g, tmp ); // exponent of g = exp - - L_tmp = L_deposit_h( 0 ); - ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 ); - exp = sub( ld, exp ); - - IF( exp > 0 ) - { - g = shr( g, exp ); // Q15 - exp - *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp; - move16(); - } - ELSE - { - crossfadeGain = shl( crossfadeGain, exp ); // Q15-e_crossfadeGain+ exp - e_crossfadeGain = sub( e_crossfadeGain, exp ); - *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ); - move16(); - } - /*make a headroom for mdct_shaping*/ - exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC ); - /* assert(exp < 0);*/ - IF( exp < 0 ) - { - *mdctSpectrum_exp = SPEC_EXP_DEC; - move16(); - } - ELSE + *mdctSpectrum_exp = add( add( hTonalMDCTConc->lastBlockData.spectralData_exp, e_crossfadeGain ), 31 - SPEC_EXP_DEC ); + move16(); + FOR( i = 0; i < crossOverFreq; i++ ) { - exp = 0; - move16(); + /* mdctSpectrum[i] = g * mdctSpectrum[i] + crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */ + L_tmp = L_mult( crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData[i] ); // exp: hTonalMDCTConc->lastBlockData.spectralData_exp+e_crossfadeGain + if ( mdctSpectrum[i] <= 0 ) + { + /* mdctSpectrum[i] = g * mdctSpectrum[i] - crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */ + L_tmp = L_negate( L_tmp ); // exp: hTonalMDCTConc->lastBlockData.spectralData_exp+e_crossfadeGain + } + /* headroom for mdct_shaping */ + mdctSpectrum[i] = L_shr( L_tmp, 31 - SPEC_EXP_DEC ); // *mdctSpectrum_exp + move32(); } } - FOR( i = 0; i < crossOverFreq; i++ ) + ELSE { - Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[i]; // Q15 - spectralData_exp - move16(); - Word32 const y = mdctSpectrum[i]; // Q31-mdctSpectrum_exp - move32(); - - IF( g > 0 ) + IF( sum2 /* nrgWhiteNoise */ > 0 ) { - L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp + exp1 = sub( W_norm( sum1 ), 1 ); + num16 = extract_h( W_extract_h( W_shl( sum1, exp1 ) ) ); // nrgNoiseInLastFrame -> Q: 2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)+exp1-48 + exp2 = W_norm( sum2 ); + den16 = extract_h( W_extract_h( W_shl( sum2, exp2 ) ) ); // nrgWhiteNoise -> Q: exp2-48 + + /* sqrt( nrgNoiseInLastFrame / nrgWhiteNoise ) */ + tmp = div_s( num16, den16 ); // Q: 15+(2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)+exp1-48)-(exp2-48) + exp = sub( sub( shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ), 30 ), sub( exp1, exp2 ) ); // exp of tmp + tmp = Sqrt16( tmp, &exp ); + g = mult_r( g, tmp ); // exponent of g = exp } - L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp - IF( GT_32( y, 0 ) ) + exp1 = add( *mdctSpectrum_exp, exp ); + exp2 = add( hTonalMDCTConc->lastBlockData.spectralData_exp, e_crossfadeGain ); + exp = add( s_max( exp1, exp2 ), 1 ); + shift1 = sub( exp1, exp ); + shift2 = sub( exp2, exp ); + + FOR( i = 0; i < crossOverFreq; i++ ) { - L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + L_tmp1 = L_shl( Mpy_32_16_1( mdctSpectrum[i], g ), shift1 ); // g * mdctSpectrum[i] + L_tmp2 = L_shl( L_mult( crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData[i] ), shift2 ); // exp + + /* mdctSpectrum[i] = g * mdctSpectrum[i] - crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */ + L_tmp = L_sub( L_tmp1, L_tmp2 ); // exp + if ( mdctSpectrum[i] > 0 ) + { + /* mdctSpectrum[i] = g * mdctSpectrum[i] + crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */ + L_tmp = L_add( L_tmp1, L_tmp2 ); // exp + } + mdctSpectrum[i] = L_shr( L_tmp, 31 - SPEC_EXP_DEC ); // exp+31-SPEC_EXP_DEC + move32(); } - mdctSpectrum[i] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp - move32(); + /* headroom for mdct_shaping */ + *mdctSpectrum_exp = add( exp, 31 - SPEC_EXP_DEC ); + move16(); } } - exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) ); + exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, *mdctSpectrum_exp ); FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ ) { - mdctSpectrum[i] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), exp ); // Q15 - spectralData_exp + exp + mdctSpectrum[i] = L_shl( L_deposit_h( hTonalMDCTConc->lastBlockData.spectralData[i] ), exp ); // mdctSpectrum_exp move32(); } } -- GitLab From 9770a293ee45b6d074f2c194c0c500424cf03908 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 2 Apr 2025 12:37:21 +0530 Subject: [PATCH 0775/1221] Fix for 3GPP issue 1453: [regression] Encoder abort (divide by zero) for MC 5.1+2 encoding in ivas_param_mc_quantize_ilds_fx() Link #1453 --- lib_enc/ivas_mc_param_enc_fx.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 92cd33e2f..54fe249cd 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1422,8 +1422,21 @@ static void ivas_param_mc_quantize_ilds_fx( dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e ); } /*ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) )*/ - tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, EPSILON_FX, 0, &tot_ener_e ); - dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, EPSILON_FX, 0, &dmx_ener_e ); + IF( tot_ener_fx == 0 ) + { + tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63 + tot_ener_e = -32; + move32(); + move16(); + } + IF( dmx_ener_fx == 0 ) + { + dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63 + dmx_ener_e = -32; + move32(); + move16(); + } + L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) ); tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e ); ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e ); // Q25 -- GitLab From ce3ba2950404e5a188c61232a411a48350ed86ed Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 2 Apr 2025 12:40:42 +0530 Subject: [PATCH 0776/1221] Fix for 3GPP issue 1445: Deviations with MCT between BASOP and float for LTV 5.1 coded with 128kbps - 1 Link #1445 --- lib_enc/amr_wb_enc_fx.c | 2 +- lib_enc/bw_detect_fx.c | 12 +++++++++--- lib_enc/ivas_core_pre_proc_front_fx.c | 2 +- lib_enc/ivas_mdct_core_enc_fx.c | 9 +++++---- lib_enc/pre_proc_fx.c | 2 +- lib_enc/prot_fx_enc.h | 14 +++++++------- 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index 6f46e5c12..1580a7818 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -372,7 +372,7 @@ void amr_wb_enc_fx( * WB, SWB and FB bandwidth detector *----------------------------------------------------------------*/ - bw_detect_fx( st, st->input_fx, NULL, NULL, NULL, MONO_FORMAT, 0 ); + bw_detect_fx( st, st->input_fx, NULL, NULL, NULL, MONO_FORMAT, 0, 0 ); /* in AMR_WB IO, limit the maximum band-width to WB */ if ( GT_16( st->bwidth, WB ) ) diff --git a/lib_enc/bw_detect_fx.c b/lib_enc/bw_detect_fx.c index 2e9b2c5db..8a150d514 100644 --- a/lib_enc/bw_detect_fx.c +++ b/lib_enc/bw_detect_fx.c @@ -41,12 +41,12 @@ void bw_detect_fx( Encoder_State *st, /* i/o: Encoder State */ const Word16 signal_in[], /* i : input signal */ - Word16 *spectrum, /* i : MDCT spectrum */ + Word16 *spectrum, /* i : MDCT spectrum Q_spec */ const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 mct_on /* i : flag MCT mode */ -) + const Word16 mct_on, /* i : flag MCT mode */ + const Word16 Q_spec ) { Word16 Q_dct; Word16 i, j, k, bw_max, bin_width, n_bins; @@ -312,6 +312,11 @@ void bw_detect_fx( bin_width = i_mult( bin_width, l_frame / BWD_TOTAL_WIDTH ); Copy( spectrum, spect, l_frame ); + if ( st->element_mode != EVS_MONO ) + { + Q_dct = Q_spec; + move16(); + } } /*---------------------------------------------------------------------* * compute energy per spectral bins @@ -903,6 +908,7 @@ void bw_detect_fx( return; } + /*-------------------------------------------------------------------* * set_bw_fx() * diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 34d90a165..bb065ae20 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -870,7 +870,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 input_fx_tmp[480]; Copy_Scale_sig( st->input_fx, input_fx_tmp, shr( input_frame, 1 ), negate( st->q_inp ) ); /*scaling from Q_inp_const to q0*/ - bw_detect_fx( st, input_fx_tmp, NULL, enerBuffer_fx, sf_energySum, ivas_format, 0 ); + bw_detect_fx( st, input_fx_tmp, NULL, enerBuffer_fx, sf_energySum, ivas_format, 0, 0 ); } IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index e27ec8c11..7c3daebda 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1283,16 +1283,17 @@ void ivas_mdct_core_whitening_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { Word16 spect_fx[L_FRAME48k]; - Word16 q_spectrum, l_frame; + Word16 q_spectrum, lshift, l_frame; /*l_frame = (int16_t)(st->input_Fs / FRAMES_PER_SEC); 1 / FRAMES_PER_SEC = 0.2f */ l_frame = extract_l( Mpy_32_32( st->input_Fs, 42949673 /* 0.2f in Q31 */ ) ); if ( EQ_16( st->core, TCX_10_CORE ) ) { l_frame = shr( l_frame, 1 ); } - q_spectrum = L_norm_arr( st->hTcxEnc->spectrum_fx[n], l_frame ); - Copy_Scale_sig32_16( st->hTcxEnc->spectrum_fx[n], spect_fx, l_frame, q_spectrum ); - bw_detect_fx( st, NULL, spect_fx, NULL, NULL, MC_FORMAT /*just cannot be ISM_FORMAT*/, mct_on ); + lshift = L_norm_arr( st->hTcxEnc->spectrum_fx[n], l_frame ); + Copy_Scale_sig32_16( st->hTcxEnc->spectrum_fx[n], spect_fx, l_frame, lshift ); + q_spectrum = sub( add( sub( Q31, st->hTcxEnc->spectrum_e[n] ), lshift ), 16 ); + bw_detect_fx( st, NULL, spect_fx, NULL, NULL, MC_FORMAT /*just cannot be ISM_FORMAT*/, mct_on, q_spectrum ); test(); if ( EQ_16( nSubframes, NB_DIV ) && n == 0 ) diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index efecb33ed..cbb2cf421 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -298,7 +298,7 @@ void pre_proc_fx( move16(); } - bw_detect_fx( st, signal_in, NULL, enerBuffer, sf_energySum, MONO_FORMAT, 0 ); + bw_detect_fx( st, signal_in, NULL, enerBuffer, sf_energySum, MONO_FORMAT, 0, 0 ); /*----------------------------------------------------------------* * Noise energy down-ward update and total noise energy estimation diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 3f7f17fe7..e54d3025e 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -138,13 +138,13 @@ void AVQ_encmux_ivas_fx( void bw_detect_fx( Encoder_State *st, /* i/o: Encoder State */ - const Word16 signal_in[], /* i : i signal */ - Word16 *spectrum, /* i : MDCT spectrum */ - const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ - const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 mct_on /* i : flag MCT mode */ -); + const Word16 signal_in[], /* i : input signal */ + Word16 *spectrum, /* i : MDCT spectrum Q_spec */ + const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ + const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 mct_on, /* i : flag MCT mode */ + const Word16 Q_spec ); void core_switching_post_enc_fx( /*done */ Encoder_State *st_fx, /* i/o: encoder state structure */ -- GitLab From 4786581cd17e23de3cbc31b85596d6a52c32af13 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 09:38:38 +0200 Subject: [PATCH 0777/1221] deactivated all speedups but FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat in tools_fx.c - is it be? --- lib_com/prot_fx.h | 10 +++++----- lib_com/tools_fx.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 883ef5492..01970f37b 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,10 +60,10 @@ #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WOPS -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // BE // .9 WMOPS -- all pipes green +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // BE // .9 WMOPS -- all pipes green // ^^^^^^^^ // Numbers ALL: 84,189 // Numbers beOnly: 87,344 @@ -71,7 +71,7 @@ //----------------------------------------------------------------------- -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE, all pipes green! +//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE, all pipes green! // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5219d076c..ddacd9d09 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -760,6 +760,7 @@ void Copy_Scale_sig_16_32_DEPREC( } } +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat void Copy_Scale_sig_16_32_no_sat( const Word16 x[], /* i : signal to scale input Qx */ Word32 y[], /* o : scaled signal output Qx */ @@ -794,6 +795,41 @@ void Copy_Scale_sig_16_32_no_sat( } return; } +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat +//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); + + IF( L_tmp >= 0x7FFF ) + { + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* saturation can occur here */ +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + Word32 tmp32 = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + if ( tmp32 != y[i] ) + assert( 0 ); +#endif + } + return; + } + + //ELSE + { + Word16 tmp = extract_l( L_tmp ); + FOR( i = 0; i < lg; i++ ) + { + y[i] = L_mult(x[i], L_tmp); + move32(); /* saturation can occur here */ +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + Word32 tmp32 = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + if ( tmp32 != y[i] ) + assert( 0 ); +#endif + } + } +#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { @@ -801,6 +837,7 @@ void Copy_Scale_sig_16_32_no_sat( y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* saturation can occur here */ } +#endif } void Copy_Scale_sig_32_16( -- GitLab From 11d2a43def1639f505ac3b3b640b6e8caefb76a7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 09:40:54 +0200 Subject: [PATCH 0778/1221] applied clang format patch --- lib_com/tools_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index ddacd9d09..d0dddd4d1 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -796,7 +796,7 @@ void Copy_Scale_sig_16_32_no_sat( return; } #ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat -//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + //#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); IF( L_tmp >= 0x7FFF ) @@ -814,13 +814,13 @@ void Copy_Scale_sig_16_32_no_sat( } return; } - - //ELSE + + // ELSE { Word16 tmp = extract_l( L_tmp ); FOR( i = 0; i < lg; i++ ) { - y[i] = L_mult(x[i], L_tmp); + y[i] = L_mult( x[i], L_tmp ); move32(); /* saturation can occur here */ #ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST Word32 tmp32 = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); -- GitLab From 484696efae01af32ad89bebaebbbd0c3335cc763 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 09:46:35 +0200 Subject: [PATCH 0779/1221] fix warning unused variable --- lib_com/tools_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index d0dddd4d1..0ca7f54ad 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -817,7 +817,7 @@ void Copy_Scale_sig_16_32_no_sat( // ELSE { - Word16 tmp = extract_l( L_tmp ); + //Word16 tmp = extract_l( L_tmp ); FOR( i = 0; i < lg; i++ ) { y[i] = L_mult( x[i], L_tmp ); -- GitLab From 8408cc86cc6af04795636103c1ee0f4abe6bfca7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 09:47:08 +0200 Subject: [PATCH 0780/1221] fix clang format pipeline warning --- lib_com/tools_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 0ca7f54ad..957c8a42a 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -817,7 +817,7 @@ void Copy_Scale_sig_16_32_no_sat( // ELSE { - //Word16 tmp = extract_l( L_tmp ); + // Word16 tmp = extract_l( L_tmp ); FOR( i = 0; i < lg; i++ ) { y[i] = L_mult( x[i], L_tmp ); -- GitLab From c64a0a025d136cf681e95c615f766cd84387f499 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 11:18:01 +0200 Subject: [PATCH 0781/1221] activate only be speedups - is really be? --- lib_com/options.h | 9 ++++++++- lib_com/prot_fx.h | 9 +-------- lib_com/tools_fx.c | 13 ------------- lib_dec/ivas_stereo_icbwe_dec_fx.c | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 4653bb460..910f8094e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +//#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -78,4 +78,11 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT + +// new speedups - pipe running +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ + #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 01970f37b..bffb85ba8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -61,17 +61,10 @@ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig // BE // .9 WMOPS -- all pipes green -// ^^^^^^^^ -// Numbers ALL: 84,189 -// Numbers beOnly: 87,344 -// NUmbers none: 88,236 - //----------------------------------------------------------------------- -//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 // .8 WMOPS BE, all pipes green! // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 957c8a42a..d5ec36928 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -760,7 +760,6 @@ void Copy_Scale_sig_16_32_DEPREC( } } -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat void Copy_Scale_sig_16_32_no_sat( const Word16 x[], /* i : signal to scale input Qx */ Word32 y[], /* o : scaled signal output Qx */ @@ -796,7 +795,6 @@ void Copy_Scale_sig_16_32_no_sat( return; } #ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat - //#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); IF( L_tmp >= 0x7FFF ) @@ -806,15 +804,9 @@ void Copy_Scale_sig_16_32_no_sat( // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* saturation can occur here */ -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - Word32 tmp32 = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - if ( tmp32 != y[i] ) - assert( 0 ); -#endif } return; } - // ELSE { // Word16 tmp = extract_l( L_tmp ); @@ -822,11 +814,6 @@ void Copy_Scale_sig_16_32_no_sat( { y[i] = L_mult( x[i], L_tmp ); move32(); /* saturation can occur here */ -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - Word32 tmp32 = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - if ( tmp32 != y[i] ) - assert( 0 ); -#endif } } #else diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c7bc98566..4acfcf6d9 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,8 +904,22 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); +#endif FOR( i = 0; i < winLen_fx; i++ ) { +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ + L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ + tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ + move32(); + if ( LE_16( alpha_fx, winSlope_fx_ ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ + } +#else L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ @@ -915,6 +929,7 @@ void stereo_icBWE_dec_fx( { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } +#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) -- GitLab From 06cf345ccfca15132baf2627711176985a9ae4d9 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 2 Apr 2025 15:19:07 +0530 Subject: [PATCH 0782/1221] ASAN error fix for encoder --- lib_enc/ivas_sce_enc_fx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 41127a98e..a578a3cfa 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -612,10 +612,6 @@ ivas_error create_evs_sce_enc_fx( /*-----------------------------------------------------------------* * Bitstream *-----------------------------------------------------------------*/ - IF( ( st_fx->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); - } /* set pointer to the buffer of indices */ st_fx->hBstr->ind_list = st_ivas->ind_list; -- GitLab From 550e40e73f33098653222bfa5365edb218b01024 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 2 Apr 2025 15:21:55 +0530 Subject: [PATCH 0783/1221] Fix for 3GPP issue 1387: Stereo Encoder 32 kbps: Rattling artifcats in 16 kHz LTVs Link #1387 --- lib_enc/ivas_core_pre_proc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index ca53a227a..781d290ac 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -827,8 +827,8 @@ ivas_error ivas_compute_core_buffers_fx( /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); move16(); - Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx - sub( lMemRecalc, add( delay, L_FILT16k ) ), delay ); /* Q(-1) */ - Copy( signal_in_fx - lMemRecalc, new_inp_16k_fx - add( lMemRecalc, L_FILT16k ), add( input_frame, lMemRecalc ) ); /* st->q_inp */ + Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx - add( lMemRecalc, sub( delay, L_FILT16k ) ), delay ); /* Q(-1) */ + Copy( signal_in_fx - lMemRecalc, new_inp_16k_fx - sub( lMemRecalc, L_FILT16k ), add( input_frame, lMemRecalc ) ); /* st->q_inp */ Copy( signal_in_fx + sub( sub( input_frame, lMemRecalc ), shl( delay, 1 ) ), st->mem_decim16k_fx, shl( delay, 1 ) ); /* st->q_inp */ } ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) -- GitLab From cd84bf62258688461fd1130d3847f254b694ef13 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 12:34:57 +0200 Subject: [PATCH 0784/1221] fix precission in FIX_1439_SPEEDUP_elliptic_bpf_48k_generic STAGE1-3, activate, check again BEness --- lib_com/prot_fx.h | 6 +++--- lib_com/swb_tbe_com_fx.c | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index bffb85ba8..d64744426 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,9 +60,9 @@ #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a4ded2bb5..66daa4835 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6783,7 +6783,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6796,7 +6797,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6811,7 +6813,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6824,7 +6827,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6837,7 +6841,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; } @@ -6858,7 +6863,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } } @@ -7021,7 +7027,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7128,7 +7135,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -- GitLab From 50e83868d65d789c4c2fdc12161e3fcf8ce811bb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 12:37:28 +0200 Subject: [PATCH 0785/1221] clang format patch --- lib_com/prot_fx.h | 6 +++--- lib_com/swb_tbe_com_fx.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d64744426..709c7350a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,9 +60,9 @@ #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 66daa4835..9b78b6a0a 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6783,7 +6783,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6797,7 +6797,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6813,7 +6813,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6827,7 +6827,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6841,7 +6841,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6863,7 +6863,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } @@ -7027,7 +7027,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + // L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); @@ -7135,7 +7135,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + // L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); -- GitLab From f6035b9357c963cbf78e463f3bb825caab75aaa5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 13:45:10 +0200 Subject: [PATCH 0786/1221] fix FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 --- lib_com/prot_fx.h | 6 +++--- lib_dec/swb_tbe_dec_fx.c | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 709c7350a..fc10b7d3d 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,9 +60,9 @@ #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50610 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index e73e541d0..dd49465b1 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7047,7 +7047,6 @@ void ivas_swb_tbe_dec_fx( #else Word16 idx; idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ - L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ #endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ -- GitLab From 1d9afdc3dde8edc997ee137879e2f195961dd31a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 13:54:56 +0200 Subject: [PATCH 0787/1221] clang patch --- lib_dec/swb_tbe_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index dd49465b1..36a499f7d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7046,7 +7046,7 @@ void ivas_swb_tbe_dec_fx( } #else Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ #endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ -- GitLab From 5ad8f6474e933567260b3fe5ae3c6a5dc9652dcf Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:21:19 +0200 Subject: [PATCH 0788/1221] only cleaned upo- moved macros to options.h --- lib_com/options.h | 11 ++++++++++- lib_com/prot_fx.h | 8 -------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 910f8094e..d9a11b6a0 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -79,10 +79,19 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT -// new speedups - pipe running +//------------------------------------------------------------------------------------------------ +// new speedups - pipe running - 2.4 WMOPS (88.236 clean, 85.828 BE macros) #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.2 WMOPS, pipe https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50610 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | + + +// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) + + #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index fc10b7d3d..ffd1d6032 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,14 +60,6 @@ #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50610 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | - -//----------------------------------------------------------------------- -// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) - - /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ -- GitLab From 14ffa173ca0e1cba1519aca563184cb00ecefeb3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:23:40 +0200 Subject: [PATCH 0789/1221] Revert "only cleaned upo- moved macros to options.h" This reverts commit 5ad8f6474e933567260b3fe5ae3c6a5dc9652dcf. --- lib_com/options.h | 11 +---------- lib_com/prot_fx.h | 8 ++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index d9a11b6a0..910f8094e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -79,19 +79,10 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT -//------------------------------------------------------------------------------------------------ -// new speedups - pipe running - 2.4 WMOPS (88.236 clean, 85.828 BE macros) +// new speedups - pipe running #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.2 WMOPS, pipe https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50610 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | - - -// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) - - #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index ffd1d6032..fc10b7d3d 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,6 +60,14 @@ #define TCX_IMDCT_HEADROOM 1 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50610 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | + +//----------------------------------------------------------------------- +// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) + + /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ -- GitLab From 6adb90e0d7b137350d2c4617abaf2349032772ec Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:23:57 +0200 Subject: [PATCH 0790/1221] Revert "clang patch" This reverts commit 1d9afdc3dde8edc997ee137879e2f195961dd31a. --- lib_dec/swb_tbe_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 36a499f7d..dd49465b1 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7046,7 +7046,7 @@ void ivas_swb_tbe_dec_fx( } #else Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ #endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ -- GitLab From 267c42789813eb8a5d84a16d6ea6d7a3d51e5bd4 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:24:11 +0200 Subject: [PATCH 0791/1221] Revert "fix FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0" This reverts commit f6035b9357c963cbf78e463f3bb825caab75aaa5. --- lib_com/prot_fx.h | 6 +++--- lib_dec/swb_tbe_dec_fx.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index fc10b7d3d..709c7350a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,9 +60,9 @@ #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50610 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index dd49465b1..e73e541d0 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7047,6 +7047,7 @@ void ivas_swb_tbe_dec_fx( #else Word16 idx; idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ + L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ #endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ -- GitLab From 04de54be85ffb795b72aa44249c5516443a956da Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:24:33 +0200 Subject: [PATCH 0792/1221] Revert "clang format patch" This reverts commit 50e83868d65d789c4c2fdc12161e3fcf8ce811bb. --- lib_com/prot_fx.h | 6 +++--- lib_com/swb_tbe_com_fx.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 709c7350a..d64744426 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,9 +60,9 @@ #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 9b78b6a0a..66daa4835 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6783,7 +6783,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6797,7 +6797,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6813,7 +6813,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6827,7 +6827,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6841,7 +6841,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6863,7 +6863,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - // L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } @@ -7027,7 +7027,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - // L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); @@ -7135,7 +7135,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - // L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); -- GitLab From 05d9348d8fcbd9b587438233c3f3e60dbfba99b8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:24:59 +0200 Subject: [PATCH 0793/1221] Revert "fix precission in FIX_1439_SPEEDUP_elliptic_bpf_48k_generic STAGE1-3, activate, check again BEness" This reverts commit cd84bf62258688461fd1130d3847f254b694ef13. --- lib_com/prot_fx.h | 6 +++--- lib_com/swb_tbe_com_fx.c | 24 ++++++++---------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d64744426..bffb85ba8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,9 +60,9 @@ #define TCX_IMDCT_HEADROOM 1 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 66daa4835..a4ded2bb5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6783,8 +6783,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6797,8 +6796,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6813,8 +6811,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6827,8 +6824,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6841,8 +6837,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); i++; } @@ -6863,8 +6858,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ move32(); } } @@ -7027,8 +7021,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7135,8 +7128,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -- GitLab From 95e62c63d66b42e391dda75f12c033344f1a7591 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:47:22 +0200 Subject: [PATCH 0794/1221] deactivate all speedups --- lib_com/options.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 910f8094e..6616402cc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,9 +80,9 @@ //#define HARM_SCE_INIT // new speedups - pipe running -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ #endif -- GitLab From 3703d5c6f8b76d2d02a8b420ab92db65625ca5fc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 16:04:34 +0200 Subject: [PATCH 0795/1221] add FIX_1439_SPEEDUP_synthesise_fb_high_band_fx macro --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 6616402cc..e791e2835 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,5 +84,5 @@ //#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ //#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ - +//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // 0.4 WMOPS - BE? #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a4ded2bb5..7ad52ba6f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7298,6 +7298,47 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ + Word32 L_tmp32; + Word16 tmp16; + + if ( L_tmp < 0 ) + { + L_tmp32 = L_negate( L_tmp ); + } + if ( L_tmp < 0 ) + { + L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); + } + if ( L_tmp < 0 ) + { + tmp16 = extract_h( L_tmp32); + } + if ( L_tmp < 0 ) + { + tmp16 = negate( tmp16 ); + } + + if ( L_tmp == 0 ) + { + tmp16 = 0; + move16(); + } + + if ( L_tmp > 0 ) + { + L_tmp32 = L_shl_sat( L_tmp, tmp3 ); + } + if ( L_tmp > 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + + output[i] = tmp16; + move16(); + +#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7309,6 +7350,7 @@ void synthesise_fb_high_band_fx( output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); } +#endif } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; -- GitLab From 1b9bff76c733f36e9f19b12c87c1788c19446dc7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 13:45:10 +0200 Subject: [PATCH 0796/1221] fix FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 --- lib_dec/swb_tbe_dec_fx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index e73e541d0..dd49465b1 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7047,7 +7047,6 @@ void ivas_swb_tbe_dec_fx( #else Word16 idx; idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ - L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ #endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ -- GitLab From 2d8375baf11bf77e84261b65de13258a8e238d5a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 16:08:25 +0200 Subject: [PATCH 0797/1221] move all speedup macros to options.h --- lib_com/options.h | 9 ++++++++- lib_com/prot_fx.h | 8 -------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e791e2835..1efda0251 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -79,10 +79,17 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT -// new speedups - pipe running +// new speedups //#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ //#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ //#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ //#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // 0.4 WMOPS - BE? + +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | + +//----------------------------------------------------------------------- +// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index bffb85ba8..ffd1d6032 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -60,14 +60,6 @@ #define TCX_IMDCT_HEADROOM 1 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | - -//----------------------------------------------------------------------- -// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) - - /*----------------------------------------------------------------------------------* * Prototypes of global macros *----------------------------------------------------------------------------------*/ -- GitLab From babf4e8b6709a7ce79c7e7e0bc95914b46879676 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 16:10:09 +0200 Subject: [PATCH 0798/1221] apply clang patch --- lib_com/swb_tbe_com_fx.c | 4 ++-- lib_dec/swb_tbe_dec_fx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7ad52ba6f..500e2fd02 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7302,7 +7302,7 @@ void synthesise_fb_high_band_fx( L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ Word32 L_tmp32; Word16 tmp16; - + if ( L_tmp < 0 ) { L_tmp32 = L_negate( L_tmp ); @@ -7313,7 +7313,7 @@ void synthesise_fb_high_band_fx( } if ( L_tmp < 0 ) { - tmp16 = extract_h( L_tmp32); + tmp16 = extract_h( L_tmp32 ); } if ( L_tmp < 0 ) { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index dd49465b1..36a499f7d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7046,7 +7046,7 @@ void ivas_swb_tbe_dec_fx( } #else Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ #endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ -- GitLab From b677480fe59ceaf1b9345a10cafe36f50e122418 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:13:59 +0000 Subject: [PATCH 0799/1221] --- revert ALL changes --- --- lib_com/options.h | 16 +- lib_com/swb_tbe_com_fx.c | 278 +---------------------------- lib_com/tools_fx.c | 24 --- lib_dec/ivas_core_dec_fx.c | 62 ++----- lib_dec/ivas_jbm_dec_fx.c | 20 +-- lib_dec/ivas_stereo_icbwe_dec_fx.c | 15 -- lib_dec/swb_tbe_dec_fx.c | 25 +-- 7 files changed, 21 insertions(+), 419 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1efda0251..4653bb460 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -//#define WMOPS /* Activate complexity and memory counters */ +/*#define WMOPS*/ /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -78,18 +78,4 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT - -// new speedups -//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // 0.4 WMOPS - BE? - -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | - -//----------------------------------------------------------------------- -// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 500e2fd02..25c6c32bf 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -18,7 +18,6 @@ #define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ - /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6693,6 +6692,7 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ + void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6704,9 +6704,8 @@ void elliptic_bpf_48k_generic_fx( { Word16 i, j; Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; - Word32 L_output[L_FRAME48k]; FOR( i = 0; i < 4; i++ ) { @@ -6722,7 +6721,6 @@ void elliptic_bpf_48k_generic_fx( move32(); } - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6765,176 +6763,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) - { - Word64 W_tmpX; - Word64 W_tmpY; - i = 4; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - FOR( ; i < L_FRAME48k; ) - { - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //4 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //5 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); // 3 - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //4 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //5 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //4 - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //5 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //7 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - { - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - move32(); - } - } - -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) - { - i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - FOR( ; i < L_FRAME48k; ) - { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - { FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6948,9 +6776,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } - } -#endif - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -7005,28 +6830,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 - - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7041,7 +6844,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ + Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -7110,29 +6913,7 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -7150,7 +6931,6 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -#endif memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7218,13 +6998,12 @@ void synthesise_fb_high_band_fx( { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; + Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; - Word16 tmp[L_FRAME48k]; - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7240,7 +7019,6 @@ void synthesise_fb_high_band_fx( } exp_tmp = sub( Q_fb_exc, 2 ); - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" ); IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ @@ -7251,11 +7029,8 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ - - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); temp1 = sum2_fx_mod( tmp, L_FRAME48k ); + L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ exp = norm_l( L_tmp ); tmp3 = extract_h( L_shl( L_tmp, exp ) ); @@ -7298,47 +7073,6 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx - L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32; - Word16 tmp16; - - if ( L_tmp < 0 ) - { - L_tmp32 = L_negate( L_tmp ); - } - if ( L_tmp < 0 ) - { - L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); - } - if ( L_tmp < 0 ) - { - tmp16 = extract_h( L_tmp32 ); - } - if ( L_tmp < 0 ) - { - tmp16 = negate( tmp16 ); - } - - if ( L_tmp == 0 ) - { - tmp16 = 0; - move16(); - } - - if ( L_tmp > 0 ) - { - L_tmp32 = L_shl_sat( L_tmp, tmp3 ); - } - if ( L_tmp > 0 ) - { - tmp16 = extract_h( L_tmp32 ); - } - - output[i] = tmp16; - move16(); - -#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7350,9 +7084,7 @@ void synthesise_fb_high_band_fx( output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); } -#endif } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; } diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index d5ec36928..15bba151e 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,37 +794,13 @@ void Copy_Scale_sig_16_32_no_sat( } return; } -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - - IF( L_tmp >= 0x7FFF ) - { FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* saturation can occur here */ } - return; - } - // ELSE - { - // Word16 tmp = extract_l( L_tmp ); - FOR( i = 0; i < lg; i++ ) - { - y[i] = L_mult( x[i], L_tmp ); - move32(); /* saturation can occur here */ - } - } -#else - L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - FOR( i = 0; i < lg; i++ ) - { - // y[i] = L_mult0(x[i], L_tmp); - y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ - } -#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index db6dad33f..03f0e4b40 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -116,12 +116,12 @@ ivas_error ivas_core_dec_fx( error = IVAS_ERR_OK; move32(); - push_wmops( "ivas_core_dec (ICD)" ); + push_wmops( "ivas_core_dec" ); /*------------------------------------------------------------------* * General initialization *-----------------------------------------------------------------*/ - push_wmops( "ICD init" ); + use_cldfb_for_dft = 0; move16(); tdm_LRTD_flag = -1; @@ -370,9 +370,7 @@ ivas_error ivas_core_dec_fx( { save_hb_synth_32_fx = NULL; } - pop_wmops(); /*push_wmops( "ICD init" );*/ - push_wmops( "ICD SID, sanity" ); /*------------------------------------------------------------------* * Decode SID for MDCT-Stereo DTX mode *-----------------------------------------------------------------*/ @@ -400,9 +398,7 @@ ivas_error ivas_core_dec_fx( { ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } - pop_wmops(); /*push_wmops( "ICD SID, sanity" );*/ - push_wmops( "ICD Coredec" ); /*------------------------------------------------------------------* * Core Decoding *-----------------------------------------------------------------*/ @@ -487,7 +483,6 @@ ivas_error ivas_core_dec_fx( IF( st->core == ACELP_CORE ) { - push_wmops( "ICD ACELP" ); /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; @@ -560,7 +555,6 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) - pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 @@ -569,7 +563,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - push_wmops( "ICD TCX" ); Word16 Qsyn_temp; IVAS_FORMAT ivas_format; @@ -624,12 +617,10 @@ ivas_error ivas_core_dec_fx( } st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); move16(); - pop_wmops(); /*push_wmops( "ICD TCX" );*/ } IF( EQ_16( st->core, HQ_CORE ) ) { - push_wmops( "ICD HQ decoding" ); /* HQ core decoder */ Word16 Q_output; @@ -643,7 +634,6 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -660,8 +650,8 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 } - } /* n_channels loop */ - pop_wmops(); /*push_wmops( "ICD Coredec" );*/ + } /* n_channels loop */ + /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Decoding @@ -669,7 +659,6 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { - push_wmops( "ICD jTCX Coredec" ); /* active-frame decoding */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) { @@ -798,7 +787,6 @@ ivas_error ivas_core_dec_fx( } } } - pop_wmops(); /*push_wmops( "ICD jTCX Coredec" );*/ } /*---------------------------------------------------------------------* @@ -808,7 +796,6 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { - push_wmops( "ICD Stereo CNG Updates" ); /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; Word32 c_PS_LT_fx; @@ -824,14 +811,12 @@ ivas_error ivas_core_dec_fx( stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); - pop_wmops(); /*push_wmops( "ICD Stereo CNG Updates" );*/ } /*---------------------------------------------------------------------* * Postprocessing, BWEs and updates *---------------------------------------------------------------------*/ - push_wmops( "ICD Postproc, BWE, updates (ICD PP)" ); FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; @@ -842,7 +827,6 @@ ivas_error ivas_core_dec_fx( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ - push_wmops( "ICD PP TDBWE ACELPTCX trans" ); /*core_switching_post_dec*/ Q_synth = sub( 15, e_sig[0] ); @@ -916,12 +900,11 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } - pop_wmops(); /*push_wmops( "ICD PP TDBWE ACELPTCX trans" );*/ /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ - push_wmops( "ICD PP ACELP/MDCT switch" ); + /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ test(); test(); @@ -956,12 +939,11 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } - pop_wmops(); /*push_wmops( "ICD PP ACELP/MDCT switch" );*/ /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - push_wmops( "ICD PP BWswitch preproc" ); + ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); IF( st->hHQ_core == NULL ) @@ -1008,13 +990,12 @@ ivas_error ivas_core_dec_fx( hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } - pop_wmops(); /*push_wmops( "ICD PP BWswitch preproc" );*/ /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding *---------------------------------------------------------------------*/ - push_wmops( "ICD PP TBE/BWE" ); + Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; Word16 Q_syn_hb, sf; @@ -1042,9 +1023,8 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, WB_TBE ) ) { /* WB TBE decoder */ - push_wmops( "ICD PP TBE/BWE wb_tbe_dec" ); + ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_tbe_dec" );*/ } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) { @@ -1052,10 +1032,8 @@ ivas_error ivas_core_dec_fx( } ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) { - push_wmops( "ICD PP TBE/BWE wb_bwe_dec" ); /* WB BWE decoder */ Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_bwe_dec" );*/ } /* Memories Re-Scaling */ @@ -1099,10 +1077,8 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { - push_wmops( "ICD PP TBE/BWE swb_tbe_dec" ); /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec" );*/ Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx @@ -1117,22 +1093,18 @@ ivas_error ivas_core_dec_fx( /* FB TBE decoder */ IF( EQ_16( st->extl, FB_TBE ) ) { - push_wmops( "ICD PP TBE/BWE fb_tbe_dec" ); fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE fb_tbe_dec" );*/ } } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ - push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ + Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE" );*/ /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) @@ -1171,7 +1143,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) { - push_wmops( "ICD PP SWB CNG" ); /* SHB CNG decoder */ Word16 synth_fxl[960]; /* Q-2 */ Word16 q; @@ -1193,7 +1164,6 @@ ivas_error ivas_core_dec_fx( Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); - pop_wmops(); /* push_wmops( "ICD PP SWB CNG" );*/ } /*-------------------------------------------------------------------* @@ -1203,7 +1173,6 @@ ivas_error ivas_core_dec_fx( test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { - push_wmops( "ICD PP IC-BWE" ); Word16 q; q = 11; move16(); @@ -1225,12 +1194,10 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } - pop_wmops(); /*push_wmops( "ICD PP IC-BWE" );*/ } IF( EQ_16( st->element_mode, EVS_MONO ) ) { - push_wmops( "ICD PP BFI" ); /*----------------------------------------------------------------* * BFI waveform adjustment *----------------------------------------------------------------*/ @@ -1258,7 +1225,6 @@ ivas_error ivas_core_dec_fx( st->hPlcInfo->Pitch_fx = 0; move16(); } - pop_wmops(); /*push_wmops( "ICD PP BFI" );*/ } /*----------------------------------------------------------------* @@ -1271,7 +1237,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) { - push_wmops( "ICD PP Sync BWE" ); /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ IF( EQ_16( st->L_frame, L_FRAME ) ) { @@ -1425,7 +1390,6 @@ ivas_error ivas_core_dec_fx( st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } - pop_wmops(); /*push_wmops( "ICD PP Sync BWE" );*/ } test(); @@ -1441,7 +1405,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - push_wmops( "ICD PP TCXLTP" ); + IF( st->hHQ_core != NULL ) { Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 @@ -1498,7 +1462,6 @@ ivas_error ivas_core_dec_fx( } Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TCXLTP" );*/ /*--------------------------------------------------------* * Common updates @@ -1507,7 +1470,6 @@ ivas_error ivas_core_dec_fx( Word16 exp_max; Word32 output_fx_loc[L_FRAME48k]; - push_wmops( "ICD PP commonupdates" ); exp_max = 0; move16(); @@ -1562,8 +1524,6 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD PP commonupdates" );*/ - } /* n_channels loop */ FOR( n = 0; n < n_channels; n++ ) @@ -1582,7 +1542,7 @@ ivas_error ivas_core_dec_fx( move16(); } } - pop_wmops(); /*push_wmops( "ICD Postproc, BWE, updates (ICD PP)" );*/ + pop_wmops(); return error; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 4745bc5f0..93e8bb4eb 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -96,13 +96,12 @@ ivas_error ivas_jbm_dec_tc_fx( CPE_DEC_HANDLE hCPE; SCE_DEC_HANDLE hSCE; - push_wmops( "ivas_jbm_dec_tc (JBM)" ); + push_wmops( "ivas_jbm_dec_tc" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ - push_wmops( "JBM init" ); output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; @@ -135,7 +134,7 @@ ivas_error ivas_jbm_dec_tc_fx( } Word16 ch; - pop_wmops(); /*push_wmops( "JBM init" );*/ + /*----------------------------------------------------------------* * Decoding + pre-rendering @@ -153,7 +152,6 @@ ivas_error ivas_jbm_dec_tc_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { - push_wmops( "JBM STEREO" ); st_ivas->hCPE[0]->element_brate = ivas_total_brate; move32(); Word16 q_output = 11; @@ -194,11 +192,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } - pop_wmops(); /*push_wmops( "JBM STEREO" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { - push_wmops( "JBM ISM" ); /* Metadata decoding and configuration */ test(); IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) @@ -283,11 +279,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops(); /*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { - push_wmops( "JBM SBA/MASA" ); set16_fx( nb_bits_metadata, 0, MAX_SCE ); @@ -694,11 +688,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops(); /*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { - push_wmops( "JBM MASA_ISM" ); Word16 nchan_ism, nchan_transport_ism; Word16 dirac_bs_md_write_idx; @@ -829,11 +821,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 } } - pop_wmops(); /*push_wmops( "JBM MASA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { - push_wmops( "JBM SBA_ISM" ); Word16 nchan_ism, sba_ch_idx; set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -1102,11 +1092,10 @@ ivas_error ivas_jbm_dec_tc_fx( v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); } } - pop_wmops(); /*push_wmops( "JBM SBA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - push_wmops( "JBM MC" ); + // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; IF( st_ivas->nSCE > 0 ) { @@ -1479,7 +1468,6 @@ ivas_error ivas_jbm_dec_tc_fx( ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); } } - pop_wmops(); /*push_wmops( "JBM MC" );*/ } /*----------------------------------------------------------------* @@ -1488,9 +1476,7 @@ ivas_error ivas_jbm_dec_tc_fx( IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) { - push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); - pop_wmops(); /*push_wmops( "JBM syn_out" );*/ } ELSE { diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 4acfcf6d9..c7bc98566 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,22 +904,8 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); -#endif FOR( i = 0; i < winLen_fx; i++ ) { -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ - L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ - tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ - move32(); - if ( LE_16( alpha_fx, winSlope_fx_ ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ - } -#else L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ @@ -929,7 +915,6 @@ void stereo_icBWE_dec_fx( { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } -#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 36a499f7d..1b51a29fb 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4713,9 +4713,7 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - push_wmops( "synthesise_fb_high_band" ); synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); - pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) @@ -5519,7 +5517,6 @@ void ivas_swb_tbe_dec_fx( hBWE_TD = st->hBWE_TD; - /* initializations */ GainFrame_fx = 0; move32(); @@ -6330,7 +6327,6 @@ void ivas_swb_tbe_dec_fx( } } ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ - /* WB/SWB bandwidth switching */ IF( st->bws_cnt > 0 ) { @@ -6648,6 +6644,7 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); + /* Gain shape smoothing after quantization */ test(); IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) @@ -6997,16 +6994,11 @@ void ivas_swb_tbe_dec_fx( move32(); } - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" ); - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" ); - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth_fx32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" ); /* resample SHB synthesis (if needed) and scale down */ synth_scale_fx = 32767; move16(); /* 1.0 in Q15 */ @@ -7030,24 +7022,14 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); - -#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 - Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 -#endif - FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } -#else - Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ -#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); @@ -7110,9 +7092,7 @@ void ivas_swb_tbe_dec_fx( Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" ); /* Update previous frame parameters for FEC */ Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); IF( EQ_16( st->codec_mode, MODE1 ) ) @@ -7149,9 +7129,6 @@ void ivas_swb_tbe_dec_fx( move16(); hBWE_TD->prev_Qx = Q_bwe_exc; move16(); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" );*/ - - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" );*/ return; } -- GitLab From c1ec7869b0f26b14b17860ff4cc0649b3b3461d3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 14:15:20 +0000 Subject: [PATCH 0800/1221] --- revert MORE chenges--- --- lib_com/swb_tbe_com_fx.c | 26 +++++++++++++------------- lib_com/tools_fx.c | 12 ++++++------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 25c6c32bf..2a2841966 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6763,19 +6763,19 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 15bba151e..5219d076c 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -795,12 +795,12 @@ void Copy_Scale_sig_16_32_no_sat( return; } L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - FOR( i = 0; i < lg; i++ ) - { - // y[i] = L_mult0(x[i], L_tmp); - y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ - } + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* saturation can occur here */ + } } void Copy_Scale_sig_32_16( -- GitLab From 1eb52db50774f77743f15e2f5a9c9cd60c16db24 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 09:43:46 +0200 Subject: [PATCH 0801/1221] Revert "--- revert MORE chenges---" This reverts commit c1ec7869b0f26b14b17860ff4cc0649b3b3461d3. --- lib_com/swb_tbe_com_fx.c | 26 +++++++++++++------------- lib_com/tools_fx.c | 12 ++++++------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..25c6c32bf 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6763,19 +6763,19 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5219d076c..15bba151e 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -795,12 +795,12 @@ void Copy_Scale_sig_16_32_no_sat( return; } L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - FOR( i = 0; i < lg; i++ ) - { - // y[i] = L_mult0(x[i], L_tmp); - y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ - } + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* saturation can occur here */ + } } void Copy_Scale_sig_32_16( -- GitLab From fbca4d3889480434d04fc303b144b31d9985c98f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 09:44:08 +0200 Subject: [PATCH 0802/1221] Revert " --- revert ALL changes ---" This reverts commit b677480fe59ceaf1b9345a10cafe36f50e122418. --- lib_com/options.h | 16 +- lib_com/swb_tbe_com_fx.c | 278 ++++++++++++++++++++++++++++- lib_com/tools_fx.c | 24 +++ lib_dec/ivas_core_dec_fx.c | 62 +++++-- lib_dec/ivas_jbm_dec_fx.c | 20 ++- lib_dec/ivas_stereo_icbwe_dec_fx.c | 15 ++ lib_dec/swb_tbe_dec_fx.c | 25 ++- 7 files changed, 419 insertions(+), 21 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 4653bb460..1efda0251 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +//#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -78,4 +78,18 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT + +// new speedups +//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // 0.4 WMOPS - BE? + +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | + +//----------------------------------------------------------------------- +// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 25c6c32bf..500e2fd02 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -18,6 +18,7 @@ #define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ + /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6692,7 +6693,6 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ - void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -6704,8 +6704,9 @@ void elliptic_bpf_48k_generic_fx( { Word16 i, j; Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; + Word32 L_output[L_FRAME48k]; FOR( i = 0; i < 4; i++ ) { @@ -6721,6 +6722,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6763,6 +6765,176 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + { + Word64 W_tmpX; + Word64 W_tmpY; + i = 4; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + FOR( ; i < L_FRAME48k; ) + { + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //4 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //5 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); // 3 + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //4 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //5 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //4 + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //5 + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); // 6 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //7 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } + } + ELSE +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ + { + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + move32(); + } + } + +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + { + i = 4; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + FOR( ; i < L_FRAME48k; ) + { + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } + } + ELSE +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ + { FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6776,6 +6948,9 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } + } +#endif + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6830,6 +7005,28 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6844,7 +7041,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -6913,7 +7110,29 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -6931,6 +7150,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } +#endif memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -6998,12 +7218,13 @@ void synthesise_fb_high_band_fx( { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; - Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; + Word16 tmp[L_FRAME48k]; + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7019,6 +7240,7 @@ void synthesise_fb_high_band_fx( } exp_tmp = sub( Q_fb_exc, 2 ); + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" ); IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ @@ -7029,8 +7251,11 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } - temp1 = sum2_fx_mod( tmp, L_FRAME48k ); + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); + temp1 = sum2_fx_mod( tmp, L_FRAME48k ); L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ exp = norm_l( L_tmp ); tmp3 = extract_h( L_shl( L_tmp, exp ) ); @@ -7073,6 +7298,47 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ + Word32 L_tmp32; + Word16 tmp16; + + if ( L_tmp < 0 ) + { + L_tmp32 = L_negate( L_tmp ); + } + if ( L_tmp < 0 ) + { + L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); + } + if ( L_tmp < 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + if ( L_tmp < 0 ) + { + tmp16 = negate( tmp16 ); + } + + if ( L_tmp == 0 ) + { + tmp16 = 0; + move16(); + } + + if ( L_tmp > 0 ) + { + L_tmp32 = L_shl_sat( L_tmp, tmp3 ); + } + if ( L_tmp > 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + + output[i] = tmp16; + move16(); + +#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7084,7 +7350,9 @@ void synthesise_fb_high_band_fx( output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); } +#endif } + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; } diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 15bba151e..d5ec36928 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,13 +794,37 @@ void Copy_Scale_sig_16_32_no_sat( } return; } +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); + + IF( L_tmp >= 0x7FFF ) + { FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* saturation can occur here */ } + return; + } + // ELSE + { + // Word16 tmp = extract_l( L_tmp ); + FOR( i = 0; i < lg; i++ ) + { + y[i] = L_mult( x[i], L_tmp ); + move32(); /* saturation can occur here */ + } + } +#else + L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* saturation can occur here */ + } +#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 03f0e4b40..db6dad33f 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -116,12 +116,12 @@ ivas_error ivas_core_dec_fx( error = IVAS_ERR_OK; move32(); - push_wmops( "ivas_core_dec" ); + push_wmops( "ivas_core_dec (ICD)" ); /*------------------------------------------------------------------* * General initialization *-----------------------------------------------------------------*/ - + push_wmops( "ICD init" ); use_cldfb_for_dft = 0; move16(); tdm_LRTD_flag = -1; @@ -370,7 +370,9 @@ ivas_error ivas_core_dec_fx( { save_hb_synth_32_fx = NULL; } + pop_wmops(); /*push_wmops( "ICD init" );*/ + push_wmops( "ICD SID, sanity" ); /*------------------------------------------------------------------* * Decode SID for MDCT-Stereo DTX mode *-----------------------------------------------------------------*/ @@ -398,7 +400,9 @@ ivas_error ivas_core_dec_fx( { ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } + pop_wmops(); /*push_wmops( "ICD SID, sanity" );*/ + push_wmops( "ICD Coredec" ); /*------------------------------------------------------------------* * Core Decoding *-----------------------------------------------------------------*/ @@ -483,6 +487,7 @@ ivas_error ivas_core_dec_fx( IF( st->core == ACELP_CORE ) { + push_wmops( "ICD ACELP" ); /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; @@ -555,6 +560,7 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) + pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 @@ -563,6 +569,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { + push_wmops( "ICD TCX" ); Word16 Qsyn_temp; IVAS_FORMAT ivas_format; @@ -617,10 +624,12 @@ ivas_error ivas_core_dec_fx( } st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); move16(); + pop_wmops(); /*push_wmops( "ICD TCX" );*/ } IF( EQ_16( st->core, HQ_CORE ) ) { + push_wmops( "ICD HQ decoding" ); /* HQ core decoder */ Word16 Q_output; @@ -634,6 +643,7 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 + pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -650,8 +660,8 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 } - } /* n_channels loop */ - + } /* n_channels loop */ + pop_wmops(); /*push_wmops( "ICD Coredec" );*/ /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Decoding @@ -659,6 +669,7 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { + push_wmops( "ICD jTCX Coredec" ); /* active-frame decoding */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) { @@ -787,6 +798,7 @@ ivas_error ivas_core_dec_fx( } } } + pop_wmops(); /*push_wmops( "ICD jTCX Coredec" );*/ } /*---------------------------------------------------------------------* @@ -796,6 +808,7 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { + push_wmops( "ICD Stereo CNG Updates" ); /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; Word32 c_PS_LT_fx; @@ -811,12 +824,14 @@ ivas_error ivas_core_dec_fx( stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); + pop_wmops(); /*push_wmops( "ICD Stereo CNG Updates" );*/ } /*---------------------------------------------------------------------* * Postprocessing, BWEs and updates *---------------------------------------------------------------------*/ + push_wmops( "ICD Postproc, BWE, updates (ICD PP)" ); FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; @@ -827,6 +842,7 @@ ivas_error ivas_core_dec_fx( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ + push_wmops( "ICD PP TDBWE ACELPTCX trans" ); /*core_switching_post_dec*/ Q_synth = sub( 15, e_sig[0] ); @@ -900,11 +916,12 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } + pop_wmops(); /*push_wmops( "ICD PP TDBWE ACELPTCX trans" );*/ /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP ACELP/MDCT switch" ); /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ test(); test(); @@ -939,11 +956,12 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } + pop_wmops(); /*push_wmops( "ICD PP ACELP/MDCT switch" );*/ /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP BWswitch preproc" ); ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); IF( st->hHQ_core == NULL ) @@ -990,12 +1008,13 @@ ivas_error ivas_core_dec_fx( hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } + pop_wmops(); /*push_wmops( "ICD PP BWswitch preproc" );*/ /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding *---------------------------------------------------------------------*/ - + push_wmops( "ICD PP TBE/BWE" ); Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; Word16 Q_syn_hb, sf; @@ -1023,8 +1042,9 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, WB_TBE ) ) { /* WB TBE decoder */ - + push_wmops( "ICD PP TBE/BWE wb_tbe_dec" ); ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_tbe_dec" );*/ } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) { @@ -1032,8 +1052,10 @@ ivas_error ivas_core_dec_fx( } ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) { + push_wmops( "ICD PP TBE/BWE wb_bwe_dec" ); /* WB BWE decoder */ Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_bwe_dec" );*/ } /* Memories Re-Scaling */ @@ -1077,8 +1099,10 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { + push_wmops( "ICD PP TBE/BWE swb_tbe_dec" ); /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec" );*/ Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx @@ -1093,18 +1117,22 @@ ivas_error ivas_core_dec_fx( /* FB TBE decoder */ IF( EQ_16( st->extl, FB_TBE ) ) { + push_wmops( "ICD PP TBE/BWE fb_tbe_dec" ); fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE fb_tbe_dec" );*/ } } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ + push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE" );*/ /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) @@ -1143,6 +1171,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) { + push_wmops( "ICD PP SWB CNG" ); /* SHB CNG decoder */ Word16 synth_fxl[960]; /* Q-2 */ Word16 q; @@ -1164,6 +1193,7 @@ ivas_error ivas_core_dec_fx( Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); + pop_wmops(); /* push_wmops( "ICD PP SWB CNG" );*/ } /*-------------------------------------------------------------------* @@ -1173,6 +1203,7 @@ ivas_error ivas_core_dec_fx( test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { + push_wmops( "ICD PP IC-BWE" ); Word16 q; q = 11; move16(); @@ -1194,10 +1225,12 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } + pop_wmops(); /*push_wmops( "ICD PP IC-BWE" );*/ } IF( EQ_16( st->element_mode, EVS_MONO ) ) { + push_wmops( "ICD PP BFI" ); /*----------------------------------------------------------------* * BFI waveform adjustment *----------------------------------------------------------------*/ @@ -1225,6 +1258,7 @@ ivas_error ivas_core_dec_fx( st->hPlcInfo->Pitch_fx = 0; move16(); } + pop_wmops(); /*push_wmops( "ICD PP BFI" );*/ } /*----------------------------------------------------------------* @@ -1237,6 +1271,7 @@ ivas_error ivas_core_dec_fx( test(); IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) { + push_wmops( "ICD PP Sync BWE" ); /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ IF( EQ_16( st->L_frame, L_FRAME ) ) { @@ -1390,6 +1425,7 @@ ivas_error ivas_core_dec_fx( st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } + pop_wmops(); /*push_wmops( "ICD PP Sync BWE" );*/ } test(); @@ -1405,7 +1441,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - + push_wmops( "ICD PP TCXLTP" ); IF( st->hHQ_core != NULL ) { Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 @@ -1462,6 +1498,7 @@ ivas_error ivas_core_dec_fx( } Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); + pop_wmops(); /*push_wmops( "ICD PP TCXLTP" );*/ /*--------------------------------------------------------* * Common updates @@ -1470,6 +1507,7 @@ ivas_error ivas_core_dec_fx( Word16 exp_max; Word32 output_fx_loc[L_FRAME48k]; + push_wmops( "ICD PP commonupdates" ); exp_max = 0; move16(); @@ -1524,6 +1562,8 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 + pop_wmops(); /*push_wmops( "ICD PP commonupdates" );*/ + } /* n_channels loop */ FOR( n = 0; n < n_channels; n++ ) @@ -1542,7 +1582,7 @@ ivas_error ivas_core_dec_fx( move16(); } } - + pop_wmops(); /*push_wmops( "ICD Postproc, BWE, updates (ICD PP)" );*/ pop_wmops(); return error; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 93e8bb4eb..4745bc5f0 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -96,12 +96,13 @@ ivas_error ivas_jbm_dec_tc_fx( CPE_DEC_HANDLE hCPE; SCE_DEC_HANDLE hSCE; - push_wmops( "ivas_jbm_dec_tc" ); + push_wmops( "ivas_jbm_dec_tc (JBM)" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ + push_wmops( "JBM init" ); output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; @@ -134,7 +135,7 @@ ivas_error ivas_jbm_dec_tc_fx( } Word16 ch; - + pop_wmops(); /*push_wmops( "JBM init" );*/ /*----------------------------------------------------------------* * Decoding + pre-rendering @@ -152,6 +153,7 @@ ivas_error ivas_jbm_dec_tc_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { + push_wmops( "JBM STEREO" ); st_ivas->hCPE[0]->element_brate = ivas_total_brate; move32(); Word16 q_output = 11; @@ -192,9 +194,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } + pop_wmops(); /*push_wmops( "JBM STEREO" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { + push_wmops( "JBM ISM" ); /* Metadata decoding and configuration */ test(); IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) @@ -279,9 +283,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } + pop_wmops(); /*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { + push_wmops( "JBM SBA/MASA" ); set16_fx( nb_bits_metadata, 0, MAX_SCE ); @@ -688,9 +694,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } + pop_wmops(); /*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { + push_wmops( "JBM MASA_ISM" ); Word16 nchan_ism, nchan_transport_ism; Word16 dirac_bs_md_write_idx; @@ -821,9 +829,11 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 } } + pop_wmops(); /*push_wmops( "JBM MASA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { + push_wmops( "JBM SBA_ISM" ); Word16 nchan_ism, sba_ch_idx; set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -1092,10 +1102,11 @@ ivas_error ivas_jbm_dec_tc_fx( v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); } } + pop_wmops(); /*push_wmops( "JBM SBA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - + push_wmops( "JBM MC" ); // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; IF( st_ivas->nSCE > 0 ) { @@ -1468,6 +1479,7 @@ ivas_error ivas_jbm_dec_tc_fx( ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); } } + pop_wmops(); /*push_wmops( "JBM MC" );*/ } /*----------------------------------------------------------------* @@ -1476,7 +1488,9 @@ ivas_error ivas_jbm_dec_tc_fx( IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) { + push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); + pop_wmops(); /*push_wmops( "JBM syn_out" );*/ } ELSE { diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c7bc98566..4acfcf6d9 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,8 +904,22 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); +#endif FOR( i = 0; i < winLen_fx; i++ ) { +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ + L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ + tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ + move32(); + if ( LE_16( alpha_fx, winSlope_fx_ ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ + } +#else L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ @@ -915,6 +929,7 @@ void stereo_icBWE_dec_fx( { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } +#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1b51a29fb..36a499f7d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4713,7 +4713,9 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ + push_wmops( "synthesise_fb_high_band" ); synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) @@ -5517,6 +5519,7 @@ void ivas_swb_tbe_dec_fx( hBWE_TD = st->hBWE_TD; + /* initializations */ GainFrame_fx = 0; move32(); @@ -6327,6 +6330,7 @@ void ivas_swb_tbe_dec_fx( } } ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ + /* WB/SWB bandwidth switching */ IF( st->bws_cnt > 0 ) { @@ -6644,7 +6648,6 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); - /* Gain shape smoothing after quantization */ test(); IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) @@ -6994,11 +6997,16 @@ void ivas_swb_tbe_dec_fx( move32(); } + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" ); + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" ); + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth_fx32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" ); /* resample SHB synthesis (if needed) and scale down */ synth_scale_fx = 32767; move16(); /* 1.0 in Q15 */ @@ -7022,14 +7030,24 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); + +#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 + Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 +#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { +#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } +#else + Word16 idx; + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ +#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); @@ -7092,7 +7110,9 @@ void ivas_swb_tbe_dec_fx( Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); } + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" );*/ + push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" ); /* Update previous frame parameters for FEC */ Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); IF( EQ_16( st->codec_mode, MODE1 ) ) @@ -7129,6 +7149,9 @@ void ivas_swb_tbe_dec_fx( move16(); hBWE_TD->prev_Qx = Q_bwe_exc; move16(); + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" );*/ + + pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" );*/ return; } -- GitLab From 7a6eb577a26e04425f2a6c66e9ffd76532f39b01 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 09:41:08 +0200 Subject: [PATCH 0803/1221] Revert "correct instrumentation (should be BE)" This reverts commit 32c9de3dcce4d724aafddc804b12b21cee389d5f. -- GitLab From 56152c372114fb80bec10df6f3f3c3795ad76702 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 09:52:14 +0200 Subject: [PATCH 0804/1221] correct instrumentation --- lib_com/options.h | 21 +++++++++++---------- lib_com/tools_fx.c | 6 +++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1efda0251..a95d04541 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -//#define WMOPS /* Activate complexity and memory counters */ +#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -80,15 +80,16 @@ //#define HARM_SCE_INIT // new speedups -//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // 0.4 WMOPS - BE? - -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | > 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | < TODO: check border cases +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS according pipe +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | + +//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? +// +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index d5ec36928..b04f3b84e 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -809,11 +809,11 @@ void Copy_Scale_sig_16_32_no_sat( } // ELSE { - // Word16 tmp = extract_l( L_tmp ); + Word16 tmp = extract_l( L_tmp ); FOR( i = 0; i < lg; i++ ) { - y[i] = L_mult( x[i], L_tmp ); - move32(); /* saturation can occur here */ + y[i] = L_mult( x[i], tmp ); + move32(); } } #else -- GitLab From 82c2d8ee7a0bef0bfb878a72cfcb59a9027dd6d0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 09:52:47 +0200 Subject: [PATCH 0805/1221] activated all BE changes, including new FIX_1439_SPEEDUP_synthesise_fb_high_band_fx for BE testing --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index a95d04541..54f4ea2d9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,8 +85,8 @@ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? -// +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? + //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | -- GitLab From 96bdfba5324b038e4d353f21a9945fe2d5b1f320 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 11:11:34 +0200 Subject: [PATCH 0806/1221] cleanup FIX_1439_SPEEDUP_stereo_icBWE_dec_fx --- lib_dec/ivas_stereo_icbwe_dec_fx.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 4acfcf6d9..772eb2d7d 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -909,22 +909,17 @@ void stereo_icBWE_dec_fx( #endif FOR( i = 0; i < winLen_fx; i++ ) { -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx if ( LE_16( alpha_fx, winSlope_fx_ ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } #else - L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ - L_tmp = L_mac0( L_tmp, sub( 32767 /* 1.0 in Q15*/, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); /* Q29 */ - tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ - move32(); IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ -- GitLab From 687d77c114b050a49db63ff0846dc226cc83d1cd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 12:28:46 +0200 Subject: [PATCH 0807/1221] creating FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST --- lib_com/tools_fx.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index b04f3b84e..d004a14ee 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -759,14 +759,26 @@ void Copy_Scale_sig_16_32_DEPREC( move32(); /* saturation can occur here */ } } +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST +void Copy_Scale_sig_16_32_no_sat( + Word16 x[], /* i : signal to scale input Qx */ + Word32 y[], /* o : scaled signal output Qx */ + Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ + ) +#else void Copy_Scale_sig_16_32_no_sat( const Word16 x[], /* i : signal to scale input Qx */ Word32 y[], /* o : scaled signal output Qx */ const Word16 lg, /* i : size of x[] Q0 */ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ ) +#endif { + Word16 i; Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -795,27 +807,50 @@ void Copy_Scale_sig_16_32_no_sat( return; } #ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + lg = 1; + for (int i_exp = 0; i_exp < 35; i_exp++) + { + for ( short i_x = 0x8000; i_x < 0x7FFF; i_x ++) + { + L_tmp = L_shl_o( 1, i_exp - 1, &Overflow ); + +#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); +#endif IF( L_tmp >= 0x7FFF ) { FOR( i = 0; i < lg; i++ ) { +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + x[i] = i_x; +#endif // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* saturation can occur here */ } - return; } - // ELSE + ELSE { Word16 tmp = extract_l( L_tmp ); FOR( i = 0; i < lg; i++ ) { +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + x[i] = i_x; +#endif y[i] = L_mult( x[i], tmp ); move32(); } } +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST + int test = W_extract_l( W_mult_32_16( L_tmp, x[0] ) ); + + if ( test != y[0] ) + assert( 0 ); + } //i_x + } //i_exp +#endif #else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) -- GitLab From 244f515f8d7f88be03f30a8031c23c213bc7a414 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 12:29:16 +0200 Subject: [PATCH 0808/1221] Revert "creating FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST" This reverts commit 687d77c114b050a49db63ff0846dc226cc83d1cd. --- lib_com/tools_fx.c | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index d004a14ee..b04f3b84e 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -759,26 +759,14 @@ void Copy_Scale_sig_16_32_DEPREC( move32(); /* saturation can occur here */ } } -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST -void Copy_Scale_sig_16_32_no_sat( - Word16 x[], /* i : signal to scale input Qx */ - Word32 y[], /* o : scaled signal output Qx */ - Word16 lg, /* i : size of x[] Q0 */ - const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ - ) -#else void Copy_Scale_sig_16_32_no_sat( const Word16 x[], /* i : signal to scale input Qx */ Word32 y[], /* o : scaled signal output Qx */ const Word16 lg, /* i : size of x[] Q0 */ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ ) -#endif { - Word16 i; Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -807,50 +795,27 @@ void Copy_Scale_sig_16_32_no_sat( return; } #ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - lg = 1; - for (int i_exp = 0; i_exp < 35; i_exp++) - { - for ( short i_x = 0x8000; i_x < 0x7FFF; i_x ++) - { - L_tmp = L_shl_o( 1, i_exp - 1, &Overflow ); - -#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); -#endif IF( L_tmp >= 0x7FFF ) { FOR( i = 0; i < lg; i++ ) { -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - x[i] = i_x; -#endif // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* saturation can occur here */ } + return; } - ELSE + // ELSE { Word16 tmp = extract_l( L_tmp ); FOR( i = 0; i < lg; i++ ) { -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - x[i] = i_x; -#endif y[i] = L_mult( x[i], tmp ); move32(); } } -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat_TEST - int test = W_extract_l( W_mult_32_16( L_tmp, x[0] ) ); - - if ( test != y[0] ) - assert( 0 ); - } //i_x - } //i_exp -#endif #else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) -- GitLab From 775e4bc484c06a8a73fd35d4b8a7b3c4fce352a1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 12:30:20 +0200 Subject: [PATCH 0809/1221] minor: comment --- lib_com/tools_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index b04f3b84e..756b5be80 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -803,7 +803,7 @@ void Copy_Scale_sig_16_32_no_sat( { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ + move32(); /* Overflow can occur here */ } return; } @@ -822,7 +822,7 @@ void Copy_Scale_sig_16_32_no_sat( { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ + move32(); /* Overflow can occur here */ } #endif } -- GitLab From fa36afd7a872d440be20679e693a204d88930bf8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 14:17:43 +0200 Subject: [PATCH 0810/1221] add FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST --- lib_com/swb_tbe_com_fx.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 500e2fd02..3cf8e88e9 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7295,14 +7295,24 @@ void synthesise_fb_high_band_fx( *prev_fbbwe_ratio = shr( ratio, 1 ); move16(); } +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx Word32 L_tmp32; Word16 tmp16; - +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST + Word32 L_tmp_a[5] = { 0x80000000, 0xC0000000, 0, 0x40000000, 0x7FFFFFFF}; + Word16 tmp3_a[15] = { -35, -32, -31, -15, -3, -1, 0, 1, 3, 15, 31, 32, 35 }; + for (int i_lta = 0; i_lta < 5; i_lta++) + for ( int i_t3a = 0; i_t3a < 13; i_t3a++ ) + { + L_tmp = L_tmp_a[i_lta]; + tmp3 = tmp3_a[i_t3a]; +#endif + if ( L_tmp < 0 ) { L_tmp32 = L_negate( L_tmp ); @@ -7334,12 +7344,29 @@ void synthesise_fb_high_band_fx( { tmp16 = extract_h( L_tmp32 ); } - +#ifndef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST output[i] = tmp16; move16(); +#else + IF( L_tmp < 0 ) + { + output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ + move16(); + } + ELSE + { + output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ + move16(); + } + if ( output[i] != tmp16 ) + assert( 0 ); +#endif + +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST + } +#endif #else - L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ -- GitLab From ba2977a632ae81faa3fcacda2316a4644c052776 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 3 Apr 2025 14:17:56 +0200 Subject: [PATCH 0811/1221] Revert "add FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST" This reverts commit fa36afd7a872d440be20679e693a204d88930bf8. --- lib_com/swb_tbe_com_fx.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 3cf8e88e9..500e2fd02 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7295,24 +7295,14 @@ void synthesise_fb_high_band_fx( *prev_fbbwe_ratio = shr( ratio, 1 ); move16(); } -#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { - L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ #ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ Word32 L_tmp32; Word16 tmp16; -#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST - Word32 L_tmp_a[5] = { 0x80000000, 0xC0000000, 0, 0x40000000, 0x7FFFFFFF}; - Word16 tmp3_a[15] = { -35, -32, -31, -15, -3, -1, 0, 1, 3, 15, 31, 32, 35 }; - for (int i_lta = 0; i_lta < 5; i_lta++) - for ( int i_t3a = 0; i_t3a < 13; i_t3a++ ) - { - L_tmp = L_tmp_a[i_lta]; - tmp3 = tmp3_a[i_t3a]; -#endif - + if ( L_tmp < 0 ) { L_tmp32 = L_negate( L_tmp ); @@ -7344,29 +7334,12 @@ void synthesise_fb_high_band_fx( { tmp16 = extract_h( L_tmp32 ); } -#ifndef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST + output[i] = tmp16; move16(); -#else - IF( L_tmp < 0 ) - { - output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ - move16(); - } - ELSE - { - output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ - move16(); - } - if ( output[i] != tmp16 ) - assert( 0 ); -#endif - -#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx_TEST - } -#endif #else + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ -- GitLab From 5d6fc20e9d26d7e8c70212cfad104a7fed363d83 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 2 Apr 2025 12:34:57 +0200 Subject: [PATCH 0812/1221] fix precission in FIX_1439_SPEEDUP_elliptic_bpf_48k_generic STAGE1-3, activate, check again BEness --- lib_com/swb_tbe_com_fx.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 500e2fd02..5128e42e3 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6783,7 +6783,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6796,7 +6797,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6811,7 +6813,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6824,7 +6827,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; @@ -6837,7 +6841,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; } @@ -6858,7 +6863,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } } @@ -7021,7 +7027,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7128,7 +7135,8 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -- GitLab From 8ae4cf5c285cd81d4e6ae1f22cb927d710c33ccf Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 15:05:24 +0530 Subject: [PATCH 0813/1221] Fix for 3GPP issue 1396: Stereo Encoder: BWE artefact at 48 kbps LTV Link #1396 --- lib_enc/ext_sig_ana_fx.c | 2 + lib_enc/ivas_mdct_core_enc_fx.c | 70 ++++++++++++++------------ lib_enc/ivas_stereo_mdct_core_enc_fx.c | 15 +++--- lib_enc/stat_enc.h | 1 + 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 087d892e3..53c8d080b 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1385,6 +1385,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); } } + st->hTcxEnc->spectrum_length = L_subframe; + move16(); } diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index f7da231a3..29ae0518c 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1251,6 +1251,8 @@ void ivas_mdct_core_whitening_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; + st->hTcxEnc->spectrum_length = st->hTcxEnc->L_frameTCX; + move16(); IF( GE_16( add( imult1616( hCPE->cpe_id, CPE_CHANNELS ), ch ), nChannels ) ) { CONTINUE; @@ -1266,6 +1268,8 @@ void ivas_mdct_core_whitening_enc_fx( core_signal_analysis_high_bitrate_ivas_fx( new_samples_fx[ch] + L_INP_MEM, T_op[ch], NULL, NULL, st, tnsSize[ch], tnsBits[ch], param_core[ch], <pBits[ch], windowedSignal_fx[ch], st->L_frame, st->hTcxEnc->L_frameTCX, hCPE->last_element_mode, 0, mdst_spectrum_fx[ch], mdst_spectrum_e[ch], &Q_new, &q_windowedSignal[ch] ); + st->hTcxEnc->spectrum_length = s_max( st->hTcxEnc->spectrum_length, st->hTcxEnc->L_frameTCX ); + move16(); /* BWD in MDCT domain */ IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { @@ -1373,16 +1377,16 @@ void ivas_mdct_core_whitening_enc_fx( q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); - q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); - q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com const Word16 switchKernel = /* these 4 transform types can be applied: 0 = MDCT-IV, 1 = MDST-II, 2 = MDCT-II, 3 = MDST-IV */ kernel_switch_detect_fx( hTcxEnc0->spectrum_fx[n], hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[0][n], mdst_spectrum_fx[1][n], q_com, nSampCore / nSubframes, @@ -1470,11 +1474,11 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( mdst_spectrum_e[0][n], hTcxEnc0->spectrum_e[n] ); q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com speech = NULL; if ( NE_16( n, 1 ) ) @@ -1491,11 +1495,11 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( mdst_spectrum_e[1][n], hTcxEnc1->spectrum_e[n] ); q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com speech = NULL; if ( NE_16( n, 1 ) ) @@ -1532,7 +1536,7 @@ void ivas_mdct_core_whitening_enc_fx( move16(); /* length = max(nSampCore / (2 * NB_DIV), L_subframeTCX / (2 * NB_DIV), NB_DIV = 2 */ length = shr( s_max( nSampCore, L_subframeTCX ), 2 ); - len_sbfr = shr( hTcxEnc0->L_frameTCX, shift ); + len_sbfr = shr( hTcxEnc0->spectrum_length, shift ); assert( hTcxEnc0->L_frameTCX == hTcxEnc1->L_frameTCX ); exp_max = s_max( hTcxEnc0->spectrum_e[n], hTcxEnc1->spectrum_e[n] ); exp_max = s_max( exp_max, mdst_spectrum_e[0][n] ); @@ -1624,22 +1628,22 @@ void ivas_mdct_core_whitening_enc_fx( { Word16 length; length = shr( s_max( nSampCore, L_subframeTCX ), shift ); // max(/* nSampCore/nSubframes, L_subframeTCX/nSubframes) */ - Word16 offset2 = sub( shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, length ); + Word16 offset2 = sub( shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, length ); exp_max = s_max( hTcxEnc0->spectrum_e[n], hTcxEnc1->spectrum_e[n] ); exp_max = s_max( exp_max, mdst_spectrum_e[0][n] ); exp_max = s_max( exp_max, mdst_spectrum_e[1][n] ); - exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); q_com = sub( s_min( Q31, add( sub( Q31, exp_max ), exp_com ) ), 6 ); exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->spectrum_length, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->spectrum_length, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e Word16 q_com_orig = q_com; move16(); @@ -1724,12 +1728,12 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( mdst_spectrum_e[ch][n], hTcxEncCh->spectrum_e[n] ); q_min = sub( Q31, q_min ); - q_com = s_min( L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ), L_norm_arr( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEncCh->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com + Scale_sig32( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEncCh->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->spectrum_length, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com speech = hTcxEncCh->speech_TCX; if ( n != 0 ) @@ -1769,7 +1773,7 @@ void ivas_mdct_core_whitening_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { q_min = s_max( q_min, hTcxEnc->spectrum_e[n] ); - q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); } } q_min = sub( Q31, q_min ); @@ -1791,7 +1795,7 @@ void ivas_mdct_core_whitening_enc_fx( } FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( Q31, q_com ); move16(); } @@ -1825,8 +1829,8 @@ void ivas_mdct_core_whitening_enc_fx( q_min = s_max( q_min, hTcxEnc->spectrum_e[n] ); q_min = s_max( q_min, mdst_spectrum_e[ch][n] ); - q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); - q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( mdst_spectrum_fx[ch][n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); } } q_min = sub( Q31, q_min ); @@ -1849,8 +1853,8 @@ void ivas_mdct_core_whitening_enc_fx( } FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com - Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( Q31, q_com ); move16(); mdst_spectrum_e[ch][n] = sub( Q31, q_com ); @@ -2137,7 +2141,7 @@ void ivas_mdct_core_whitening_enc_fx( { q_min = s_max( q_min, hTcxEnc->spectrum_e[n] ); - q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); + q_com = s_min( q_com, L_norm_arr( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/ ) ); } } q_min = sub( Q31, q_min ); @@ -2161,7 +2165,7 @@ void ivas_mdct_core_whitening_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( 31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->spectrum_length, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( 31, hTcxEnc->spectrum_e[n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( 31, q_com ); move16(); } diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 3becb30d9..b32e8a561 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -363,11 +363,11 @@ void stereo_mdct_core_enc_fx( move16(); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - length = sts[ch]->hTcxEnc->L_frameTCX; + length = sts[ch]->hTcxEnc->spectrum_length; move16(); - if ( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + length = shr( length, 1 ); } hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[0], length ) ); @@ -384,15 +384,12 @@ void stereo_mdct_core_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - Word16 n_sb = NB_DIV; + length = sts[ch]->hTcxEnc->spectrum_length; move16(); - if ( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - n_sb = 1; - move16(); + length = shr( length, 1 ); } - length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */ - FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) { Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[k], length, sub( q_spec, sub( Q31, sts[ch]->hTcxEnc->spectrum_e[k] ) ) ); /* q_spec */ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 5305a8bdc..3977c4054 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1211,6 +1211,7 @@ typedef struct tcx_enc_structure Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ Word16 spectrum_long_e; /* MDCT output for a long block. Points to spectrum */ Word16 q_spectrum_long_fx; + Word16 spectrum_length; } TCX_ENC_DATA, *TCX_ENC_HANDLE; typedef struct TransientDetection -- GitLab From a516ef9925aa0f334727cf8a04617858cb5243b3 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 2 Apr 2025 01:15:47 +0200 Subject: [PATCH 0814/1221] simplify initial patch --- lib_enc/ext_sig_ana_fx.c | 2 -- lib_enc/ivas_mdct_core_enc_fx.c | 7 +++---- lib_enc/stat_enc.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 53c8d080b..087d892e3 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1385,8 +1385,6 @@ void core_signal_analysis_high_bitrate_ivas_fx( ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); } } - st->hTcxEnc->spectrum_length = L_subframe; - move16(); } diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 29ae0518c..e27ec8c11 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1251,8 +1251,9 @@ void ivas_mdct_core_whitening_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; - st->hTcxEnc->spectrum_length = st->hTcxEnc->L_frameTCX; - move16(); + init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); + st->hTcxEnc->spectrum_length = L_subframeTCX; + IF( GE_16( add( imult1616( hCPE->cpe_id, CPE_CHANNELS ), ch ), nChannels ) ) { CONTINUE; @@ -1268,8 +1269,6 @@ void ivas_mdct_core_whitening_enc_fx( core_signal_analysis_high_bitrate_ivas_fx( new_samples_fx[ch] + L_INP_MEM, T_op[ch], NULL, NULL, st, tnsSize[ch], tnsBits[ch], param_core[ch], <pBits[ch], windowedSignal_fx[ch], st->L_frame, st->hTcxEnc->L_frameTCX, hCPE->last_element_mode, 0, mdst_spectrum_fx[ch], mdst_spectrum_e[ch], &Q_new, &q_windowedSignal[ch] ); - st->hTcxEnc->spectrum_length = s_max( st->hTcxEnc->spectrum_length, st->hTcxEnc->L_frameTCX ); - move16(); /* BWD in MDCT domain */ IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 3977c4054..c6176709b 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1211,7 +1211,7 @@ typedef struct tcx_enc_structure Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ Word16 spectrum_long_e; /* MDCT output for a long block. Points to spectrum */ Word16 q_spectrum_long_fx; - Word16 spectrum_length; + Word16 spectrum_length; /* corresponds to L_frameTCX, used for scaling of MDCT/MDST buffers */ } TCX_ENC_DATA, *TCX_ENC_HANDLE; typedef struct TransientDetection -- GitLab From 739f19588bfee76c0e2d318b83da92ed3f4e325b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 12:43:47 +0530 Subject: [PATCH 0815/1221] Fix for 3GPP issue 1407: BASOP encoder: Distortion Stereo DTX 24.4 kbps, high MLD Link #1407 --- lib_enc/ivas_cpe_enc_fx.c | 53 ++++++++++++++--------------- lib_enc/ivas_stereo_dft_enc_fx.c | 17 +++------ lib_enc/ivas_stereo_dft_td_itd_fx.c | 36 ++++++++++++++------ 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 4e7706baf..be0afc1a4 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -127,6 +127,7 @@ ivas_error ivas_cpe_enc_fx( Word16 e_old_wsp[CPE_CHANNELS], q_old_wsp; move16(); // Q_new move16(); // Q_new + Word16 q_com; error = IVAS_ERR_OK; move32(); @@ -649,35 +650,31 @@ ivas_error ivas_cpe_enc_fx( hCPE->hStereoDft->Spd_R_smooth_fx_e = sub( hCPE->hStereoDft->Spd_R_smooth_fx_e, temp ); move16(); - shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Copy_Scale_sig_32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, sub( add( sts[1]->q_inp, shift ), sts[1]->q_inp32 ) ); /* sts[1]->q_inp + shift */ - sts[1]->q_inp = add( sts[1]->q_inp, shift ); - move16(); - Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( s_min( sts[1]->q_old_inp, sts[1]->q_inp ), sts[1]->q_old_inp ) ); /* min( sts[1]->q_old_inp, sts[1]->q_inp) */ - sts[1]->q_inp = s_min( sts[1]->q_inp, sts[1]->q_old_inp ); - move16(); - sts[1]->q_old_inp = sts[1]->q_inp; - move16(); - shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[0]->q_old_inp + shift */ - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Copy_Scale_sig_32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, sub( add( sts[0]->q_inp, shift ), sts[0]->q_inp32 ) ); /* sts[0]->q_inp + shift */ - sts[0]->q_inp = add( sts[0]->q_inp, shift ); - move16(); - Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( s_min( sts[0]->q_old_inp, sts[0]->q_inp ), sts[0]->q_old_inp ) ); /* min( sts[1]->q_old_inp, sts[1]->q_inp) */ - sts[0]->q_inp = s_min( sts[0]->q_inp, sts[0]->q_old_inp ); - move16(); - sts[0]->q_old_inp = sts[0]->q_inp; - move16(); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + q_com = sub( add( L_norm_arr( sts[n]->input32_fx, input_frame ), sts[n]->q_inp32 ), 16 ); + q_com = s_min( q_com, add( norm_arr( sts[n]->old_input_signal_fx, input_frame ), sts[n]->q_old_inp ) ); + q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hCPE->hStereoDft->dft_ovl ), hCPE->q_input_mem[n] ) ); + + if ( EQ_16( q_com, Q15 ) ) + { + q_com = 0; + move16(); + } + + Copy_Scale_sig_32_16( sts[n]->input32_fx, sts[n]->input_fx, input_frame, sub( q_com, sts[n]->q_inp32 ) ); + sts[n]->q_inp = q_com; + move16(); + + scale_sig( sts[n]->old_input_signal_fx, input_frame, sub( q_com, sts[n]->q_old_inp ) ); + sts[n]->q_old_inp = q_com; + move16(); + + scale_sig( hCPE->input_mem_fx[n], hCPE->hStereoDft->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) ); + hCPE->q_input_mem[n] = q_com; + move16(); + } stereo_dft_hybrid_ITD_flag_fx( hCPE->hStereoDft->hConfig, input_Fs, hCPE->hStereoDft->hItd->hybrid_itd_max ); diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index cebbc2619..01318af28 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -1064,23 +1064,14 @@ void stereo_dft_enc_analyze_fx( Word16 q_shift, guarded_bits; guarded_bits = find_guarded_bits_fx( NFFT ); - q_shift = sub( getScaleFactor32( pDFT_L, NFFT ), guarded_bits ); - q_shift = s_min( q_shift, sub( getScaleFactor32( pDFT_R, NFFT ), guarded_bits ) ); - FOR( Word16 j = 0; j < NFFT; j++ ) - { - pDFT_L[j] = L_shl( pDFT_L[j], q_shift ); - move32(); - } + q_shift = sub( L_norm_arr( pDFT_L, NFFT ), guarded_bits ); + scale_sig32( pDFT_L, NFFT, q_shift ); DFT_e[0] = sub( DFT_e[0], q_shift ); move16(); - FOR( Word16 j = 0; j < NFFT; j++ ) - { - pDFT_R[j] = L_shl( pDFT_R[j], q_shift ); - move32(); - } - + q_shift = sub( L_norm_arr( pDFT_R, NFFT ), guarded_bits ); + scale_sig32( pDFT_R, NFFT, q_shift ); DFT_e[1] = sub( DFT_e[1], q_shift ); move16(); diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index df4fe3edd..569a5690a 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -380,15 +380,6 @@ void stereo_td_itd_fx( move16(); set16_fx( shift_input, 0, input_frame ); - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - - Scale_sig( &input_mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); // Q(sts[n]->q_inp) - // Scale_sig(&sts[n]->old_input_signal_fx, 1965, sts[n]->q_inp - sts[n]->q_old_inp); - // sts[n]->q_old_inp = sts[n]->q_inp; - q_input_mem[n] = sts[n]->q_inp; - move16(); - } IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { FOR( n = 0; n < CPE_CHANNELS; n++ ) @@ -540,7 +531,7 @@ void stereo_td_itd_mdct_stereo_fx( const Word16 input_frame /* i : frame length */ ) { - Word16 i; + Word16 i, n, q_com; Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC]; Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC]; Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC]; @@ -584,6 +575,31 @@ void stereo_td_itd_mdct_stereo_fx( /*call ITD function*/ stereo_dft_enc_compute_itd_fx( hCPE, DFT_fx[0], DFT_tmp_e[0], DFT_fx[1], DFT_tmp_e[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_e, bin_nrgR_fx, bin_nrgR_e ); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + q_com = add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ); + q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ), hCPE->hCoreCoder[n]->q_old_inp ) ); + q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl ), hCPE->q_input_mem[n] ) ); + + if ( EQ_16( q_com, Q15 ) ) + { + q_com = 0; + move16(); + } + + scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_inp ) ); + hCPE->hCoreCoder[n]->q_inp = q_com; + move16(); + + scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_old_inp ) ); + hCPE->hCoreCoder[n]->q_old_inp = q_com; + move16(); + + scale_sig( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) ); + hCPE->q_input_mem[n] = q_com; + move16(); + } + /* Time Domain ITD compensation using extrapolation */ stereo_td_itd_fx( hStereoMdct->hItd, NULL, NULL, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem_fx, hCPE->q_input_mem ); } -- GitLab From 6e176c0e7eb7c2d86c5341a3d10bd27fd3ad4eb5 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 3 Apr 2025 16:38:47 +0200 Subject: [PATCH 0816/1221] Remover inactive FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK switch and code --- lib_dec/ivas_dirac_dec_fx.c | 51 ------------------------------------- 1 file changed, 51 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index ec1dbd290..c2ef3b92e 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2789,48 +2789,6 @@ void ivas_dirac_dec_render_sf_fx( q_input ); } q_input = add( Q11, q_input ); -#endif -#ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK - Word16 cldfb_last_band = 0; - move16(); - { - Word32 sr; - Word16 el; - FOR( el = 0; el < st_ivas->nSCE; el++ ) - { - test(); - test(); - IF( st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) - { - cldfb_last_band = s_max( cldfb_last_band, st_ivas->hSCE[el]->hCoreCoder[0]->hIGFDec->infoIGFStopFreq ); - sr = st_ivas->hSCE[el]->hCoreCoder[0]->output_Fs; - } - } - FOR( el = 0; el < st_ivas->nCPE; el++ ) - { - test(); - test(); - IF( st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->isIGFActive ) - { - cldfb_last_band = s_max( cldfb_last_band, st_ivas->hCPE[el]->hCoreCoder[0]->hIGFDec->infoIGFStopFreq ); - sr = st_ivas->hCPE[el]->hCoreCoder[0]->output_Fs; - } - test(); - test(); - IF( st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec != NULL && st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->isIGFActive ) - { - cldfb_last_band = s_max( cldfb_last_band, st_ivas->hCPE[el]->hCoreCoder[1]->hIGFDec->infoIGFStopFreq ); - } - } - IF( EQ_16( cldfb_last_band, 0 ) ) - { - cldfb_last_band = hSpatParamRendCom->num_freq_bands; - } - ELSE - { - cldfb_last_band = mult_r( div_s( shr( cldfb_last_band, 2 ), extract_l( L_shr( sr, 3 ) ) ), hSpatParamRendCom->num_freq_bands ); - } - } #endif FOR( ch = 0; ch < nchan_transport; ch++ ) { @@ -2850,15 +2808,6 @@ void ivas_dirac_dec_render_sf_fx( Cldfb_ImagBuffer_fx[ch][0], hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch], &q_temp_cldfb ); -#endif -#ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB_MASK - FOR( i = cldfb_last_band; i < hSpatParamRendCom->num_freq_bands; i++ ) - { - Cldfb_RealBuffer_fx[ch][0][i] = 0; - Cldfb_ImagBuffer_fx[ch][0][i] = 0; - move32(); - move32(); - } #endif } q_cldfb = q_temp_cldfb; -- GitLab From a5fab6fc610c7b8d489498cce3cf8d3e50d2ae41 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 4 Apr 2025 09:03:05 +0530 Subject: [PATCH 0817/1221] Precision improvements in mdct core enc --- lib_com/ivas_spar_com_fx.c | 181 ++++++++++--------------- lib_enc/ext_sig_ana_fx.c | 105 ++++++++------ lib_enc/ivas_mdct_core_enc_fx.c | 53 ++++---- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 14 +- lib_enc/prot_fx_enc.h | 3 +- lib_enc/tcx_utils_enc_fx.c | 6 +- 6 files changed, 176 insertions(+), 186 deletions(-) diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 317ea0249..0da6b90c2 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -51,24 +51,16 @@ * Local constants *------------------------------------------------------------------------------------------*/ -#define IVAS_FLT_EPS ( 1e-10F ) -#define IVAS_FIX_EPS ( 1 ) -#define IVAS_DBL_EPS ( (double) 1e-20 ) +#define IVAS_FIX_EPS ( 1 ) +#define IVAS_FIX_EPS_Q40 ( 110 ) -#define IVAS_REMIX_MULT_FAC ( 0.5f ) -#define IVAS_ACTIVEW_DM_F ( 1.0f ) #define IVAS_ACTIVEW_DM_F_Q30 ( ONE_IN_Q30 ) /*1 Q30*/ -#define IVAS_ACTIVEW_DM_F_DTX ( 0.25f ) -#define IVAS_ACTIVEW_DM_F_DTX_Q30 ( 268435456 ) /*0.25 Q30*/ -#define IVAS_ACTIVEW_DM_F_VLBR ( 0.25f ) -#define IVAS_ACTIVEW_DM_F_VLBR_Q30 ( 268435456 ) /*0.25 Q30*/ -#define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH ( 3.0f ) +#define IVAS_ACTIVEW_DM_F_DTX_Q30 ( 268435456 ) /*0.25 Q30*/ +#define IVAS_ACTIVEW_DM_F_VLBR_Q30 ( 268435456 ) /*0.25 Q30*/ #define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29 ( 1610612736 ) /*3 Q29*/ -#define IVAS_P_NORM_SCALING ( 1.0f ) #define IVAS_P_NORM_SCALING_FX ( ONE_IN_Q31 ) // 1 Q31 -#define IVAS_P_NORM_SCALING_DTX ( 0.75f ) #define IVAS_P_NORM_SCALING_DTX_FX ( 1610612736 ) // 0.75 Q31 #define IVAS_MAT_DIM_3 ( 3 ) @@ -1626,8 +1618,18 @@ static void ivas_get_Wscaling_factor_enc_fx( ivas_calc_post_pred_per_band_enc_fx( cov_real, q_cov_real, mixer_mat, q_mixer_mat, num_ch, b, postpred_cov_re, &q_postpred_cov_re ); } - Gw_sq = BASOP_Util_Divide3232_Scale( cov_real[0][0][b], L_max( postpred_cov_re[0][0], IVAS_FIX_EPS ), &tmp_exp ); // 15-(tmp_exp-(q_cov_real[0][0][b]- q_postpred_cov_re)) - q_Gw_sq = add( sub( 15, tmp_exp ), sub( q_cov_real[0][0][b], q_postpred_cov_re ) ); + tmp = L_shl_sat( IVAS_FIX_EPS_Q40, sub( q_postpred_cov_re, 40 ) ); + + IF( LE_32( postpred_cov_re[0][0], tmp ) ) + { + Gw_sq = Mpy_32_32( cov_real[0][0][b], 1250000000 ); /*1/1e-10 = 1250000000 Q(-4)*/ + q_Gw_sq = add( q_cov_real[0][0][b], -4 - 31 ); + } + ELSE + { + Gw_sq = BASOP_Util_Divide3232_Scale( cov_real[0][0][b], postpred_cov_re[0][0], &tmp_exp ); // 15-(tmp_exp-(q_cov_real[0][0][b]- q_postpred_cov_re)) + q_Gw_sq = add( sub( 15, tmp_exp ), sub( q_cov_real[0][0][b], q_postpred_cov_re ) ); + } shift = MAX16B; move16(); @@ -1992,12 +1994,15 @@ static void ivas_calc_post_pred_per_band_enc_fx( Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_postpred_cov_re*/ Word16 *q_postpred_cov_re ) { - Word16 i, j, k, guard_bits, tmp, q_temp_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], q_tmp_re, q_W_tmp; + Word16 i, j, k; Word32 dmx_mat_conj[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word32 temp_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - Word32 max_val; - Word64 tmp_re, W_tmp; - Word16 q_postpred_cov_re_per_value[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 temp_mat_e[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 q_postpred_cov_re_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 min_val; + Word32 tmp_re; + Word16 tmp_q; + Word16 tmp_e; FOR( i = 0; i < num_ch; i++ ) { @@ -2014,135 +2019,71 @@ static void ivas_calc_post_pred_per_band_enc_fx( set32_fx( postpred_cov_re[i], 0, num_ch ); } - max_val = 1; - move32(); + min_val = MAX16B; + move16(); /* num_ch x num_ch mult */ FOR( i = 0; i < num_ch; i++ ) { FOR( j = 0; j < num_ch; j++ ) { - tmp_re = 0; - move64(); - q_tmp_re = 31; + temp_mat[i][j] = 0; + move32(); + temp_mat_e[i][j] = 0; move16(); FOR( k = 0; k < num_ch; k++ ) { - W_tmp = W_shr( W_mult0_32_32( cov_real[i][k][band_idx], dmx_mat_conj[k][j] ), q_mixer_mat ); /*q_cov_real[i][k][band_idx]*/ - IF( LT_16( q_cov_real[i][k][band_idx], q_tmp_re ) ) - { - tmp_re = W_add( W_shr( tmp_re, sub( q_tmp_re, q_cov_real[i][k][band_idx] ) ), W_tmp ); /*q_cov_real[i][k][band_idx]*/ - q_tmp_re = q_cov_real[i][k][band_idx]; - move16(); - } - ELSE + tmp_re = Mpy_32_32( cov_real[i][k][band_idx], dmx_mat_conj[k][j] ); + tmp_e = sub( 62, add( q_cov_real[i][k][band_idx], q_mixer_mat ) ); + IF( tmp_re ) { - tmp_re = W_add( tmp_re, W_shr( W_tmp, sub( q_cov_real[i][k][band_idx], q_tmp_re ) ) ); /*q_tmp_re*/ + temp_mat[i][j] = BASOP_Util_Add_Mant32Exp( temp_mat[i][j], temp_mat_e[i][j], tmp_re, tmp_e, &temp_mat_e[i][j] ); + move32(); } } - IF( tmp_re == 0 ) - { - q_temp_mat[i][j] = 31; - move16(); - temp_mat[i][j] = 0; - move32(); - } - ELSE - { - q_temp_mat[i][j] = q_tmp_re; - move16(); - q_tmp_re = W_norm( tmp_re ); - temp_mat[i][j] = W_extract_h( W_shl( tmp_re, q_tmp_re ) ); /*q_temp_mat[i][j]+ q_tmp_re -32*/ - move32(); - q_temp_mat[i][j] = sub( add( q_temp_mat[i][j], q_tmp_re ), 32 ); - move16(); - } - max_val = L_max( max_val, L_abs( temp_mat[i][j] ) ); } } - guard_bits = find_guarded_bits_fx( num_ch ); - - tmp = norm_l( max_val ); - IF( LT_16( tmp, guard_bits ) ) - { - guard_bits = sub( guard_bits, tmp ); - } - ELSE - { - guard_bits = 0; - move16(); - } - - *q_postpred_cov_re = 31; - move16(); /* num_ch x num_ch mult */ FOR( i = 0; i < num_ch; i++ ) { FOR( j = i; j < num_ch; j++ ) { - tmp_re = 0; - move64(); - q_tmp_re = 31; + q_postpred_cov_re_buf[i][j] = *q_postpred_cov_re; move16(); FOR( k = 0; k < num_ch; k++ ) { - W_tmp = W_shr( W_mult0_32_32( mixer_mat[i][k][band_idx], temp_mat[k][j] ), guard_bits ); // q_temp_mat[k][j]+ q_mixer_mat-guard_bits - q_W_tmp = sub( add( q_temp_mat[k][j], q_mixer_mat ), guard_bits ); - IF( LT_16( q_W_tmp, q_tmp_re ) ) + tmp_re = Mpy_32_32( mixer_mat[i][k][band_idx], temp_mat[k][j] ); + tmp_q = sub( q_mixer_mat, temp_mat_e[k][j] ); + IF( tmp_re ) { - tmp_re = W_add( W_shr( tmp_re, sub( q_tmp_re, q_W_tmp ) ), W_tmp ); // q_W_tmp - q_tmp_re = q_W_tmp; + tmp_e = sub( 31, q_postpred_cov_re_buf[i][j] ); + postpred_cov_re[i][j] = BASOP_Util_Add_Mant32Exp( postpred_cov_re[i][j], tmp_e, tmp_re, sub( Q31, tmp_q ), &tmp_e ); + move32(); + q_postpred_cov_re_buf[i][j] = sub( 31, tmp_e ); move16(); } - ELSE - { - tmp_re = W_add( tmp_re, W_shr( W_tmp, sub( q_W_tmp, q_tmp_re ) ) ); // q_tmp_re - } } - - if ( LT_64( W_abs( tmp_re ), L_shl( IVAS_FIX_EPS, guard_bits ) ) ) + IF( postpred_cov_re[i][j] ) { - tmp_re = 0; - move64(); - } - - q_postpred_cov_re_per_value[i][j] = q_tmp_re; - move16(); - IF( tmp_re == 0 ) - { - postpred_cov_re[i][j] = W_extract_l( tmp_re ); /* q_tmp_re*/ - move32(); - } - ELSE - { - q_tmp_re = W_norm( tmp_re ); - postpred_cov_re[i][j] = W_extract_h( W_shl( tmp_re, q_tmp_re ) ); /* q_tmp_re+ q_postpred_cov_re_per_value[i][j] -32*/ - move32(); - q_postpred_cov_re_per_value[i][j] = sub( add( q_tmp_re, q_postpred_cov_re_per_value[i][j] ), 32 ); - move16(); + min_val = s_min( min_val, q_postpred_cov_re_buf[i][j] ); } - *q_postpred_cov_re = s_min( *q_postpred_cov_re, q_postpred_cov_re_per_value[i][j] ); - move16(); } } + /*Changing Q of postpred_cov_re to min_val*/ FOR( i = 0; i < num_ch; i++ ) { FOR( j = i; j < num_ch; j++ ) { - IF( postpred_cov_re[i][j] >= 0 ) - { - postpred_cov_re[i][j] = L_shr( postpred_cov_re[i][j], sub( q_postpred_cov_re_per_value[i][j], *q_postpred_cov_re ) ); //*q_postpred_cov_re - move32(); - } - ELSE + IF( postpred_cov_re[i][j] ) { - postpred_cov_re[i][j] = L_negate( L_shr( L_negate( postpred_cov_re[i][j] ), sub( q_postpred_cov_re_per_value[i][j], *q_postpred_cov_re ) ) ); //*q_postpred_cov_re + postpred_cov_re[i][j] = L_shl( postpred_cov_re[i][j], sub( min_val, q_postpred_cov_re_buf[i][j] ) ); move32(); } } } + FOR( i = 0; i < num_ch; i++ ) { FOR( j = 0; j < i; j++ ) @@ -2152,6 +2093,14 @@ static void ivas_calc_post_pred_per_band_enc_fx( } } + if ( EQ_16( min_val, MAX16B ) ) + { + min_val = Q31; + move16(); + } + *q_postpred_cov_re = min_val; + move16(); + return; } @@ -2687,7 +2636,8 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( trace = W_add( trace, W_deposit32_l( L_abs( cov_uu_re[i - num_dmx][i - num_dmx] ) ) ); // q_cov_uu_re } - factor = L_max( IVAS_FIX_EPS, postpred_cov_re[0][0] ); // q_postpred_cov_re + factor = postpred_cov_re[0][0]; // q_postpred_cov_re + move32(); q_factor = q_postpred_cov_re; move16(); IF( trace != 0 ) @@ -2708,10 +2658,20 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( factor = L_max( factor, tmp ); // q_factor } + tmp = L_shl_sat( IVAS_FIX_EPS_Q40, sub( q_factor, 40 ) ); + Word16 factor_exp = 0; move16(); - factor = BASOP_Util_Divide3232_Scale( 1, factor, &factor_exp ); // q=15-(factor_exp+31-(31-q_factor)) - factor_exp = add( factor_exp, q_factor ); + IF( LE_32( factor, tmp ) ) + { + factor = 1250000000; + factor_exp = Q31 - ( -4 ); + } + ELSE + { + factor = BASOP_Util_Divide3232_Scale( 1, factor, &factor_exp ); // q=15-(factor_exp+31-(31-q_factor)) + factor_exp = add( factor_exp, q_factor ); + } /* normalise Hermitian (except for rounding) cov_uu */ FOR( i = num_dmx; i < num_ch; i++ ) @@ -3311,6 +3271,9 @@ void ivas_calc_c_p_coeffs_enc_fx( Word16 i, j, q_postpred_cov_re; Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + q_postpred_cov_re = 0; + move16(); + FOR( i = 0; i < IVAS_SPAR_MAX_CH; i++ ) { set_zero_fx( postpred_cov_re[i], IVAS_SPAR_MAX_CH ); diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 087d892e3..6414a81b6 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -675,6 +675,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word16 alw_voicing[2], alw_voicing_wc = -1; Word16 disable_ltp = 0; Word16 tmp, *tmpP16; + Word16 q_mdstWin = st->q_inp, q_tcx20Win = st->q_inp; Word32 *tmpP32; Word16 Q_exp; Word32 L_tmpbuf[N_MAX + L_MDCT_OVLP_MAX]; @@ -684,12 +685,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); move16(); move16(); + move16(); + move16(); (void) vad_hover_flag; Word16 Q_win_temp[2]; Word16 *speech_ltp_fx = NULL; Word16 *wspeech_fx = NULL; Word16 *speech_fx = NULL; - Word16 q_out_wtda = 0; + Word16 q_out_wtda = st->q_inp; move16(); Word16 win_len[2]; move16(); @@ -961,7 +964,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( move32(); windowed_samples[frameno * L_FRAME_MAX + 1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0 move32(); - Copy_Scale_sig_16_32_DEPREC( tcx20Win, windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), 0 ); + Copy_Scale_sig_16_32_DEPREC( tcx20Win, windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), negate( q_tcx20Win ) ); *q_win = s_min( *q_win, sub( L_norm_arr( windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ) ), 1 ) ); move16(); Q_win_temp[frameno] = *q_win; @@ -983,7 +986,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outter left folding */ FOR( i = 0; i < folding_offset; i++ ) { - tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // Q0 + tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win move16(); } @@ -996,18 +999,18 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } } @@ -1016,7 +1019,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) { - tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // Q0 + tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win move16(); } @@ -1027,6 +1030,12 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmpP16 = tcx20Win; tmpP32 = hTcxEnc->spectrum_fx[frameno]; assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); + Word16 len[2], exp[2]; + hTcxEnc->spectrum_e[frameno] = 16; + exp[0] = exp[1] = hTcxEnc->spectrum_e[frameno]; + move16(); + move16(); + move16(); FOR( i = 0; i < 2; i++ ) { test(); @@ -1037,17 +1046,17 @@ void core_signal_analysis_high_bitrate_ivas_fx( mac_r( 2 << 16, -( 3 << 8 ), shl( i, 7 ) ), /* equivalent to: sub(i, 1) == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP */ &left_overlap, &right_overlap, tmpP16, &L_subframe, tcx5Win, st->element_mode != IVAS_CPE_MDCT, 1 ); - hTcxEnc->spectrum_e[frameno] = 16; - move16(); TCX_MDCT( tcx5Win, tmpP32, - &hTcxEnc->spectrum_e[frameno], + &exp[i], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); tmpP16 += tcx5SizeFB; tmpP32 += tcx5SizeFB; + len[i] = L_subframe; + move16(); /* high-band gain control in case of BWS */ IF( st->bwidth_sw_cnt > 0 ) @@ -1064,6 +1073,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_subframe - L_FRAME16k / ( 2 * nSubframes ) ); } } + hTcxEnc->spectrum_e[frameno] = s_max( exp[0], exp[1] ); + move16(); + + FOR( i = 0; i < 2; i++ ) + { + Scale_sig32( hTcxEnc->spectrum_fx[frameno] + i * L_subframe, len[i], sub( exp[i], hTcxEnc->spectrum_e[frameno] ) ); + } + + hTcxEnc->spectrum_e[frameno] = sub( hTcxEnc->spectrum_e[frameno], q_tcx20Win ); + move16(); } ELSE /* transform_type[frameno] != TCX_5 */ { @@ -1105,23 +1124,25 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } } TCX_MDCT( tcx20Win, hTcxEnc->spectrum_fx[frameno], &hTcxEnc->spectrum_e[frameno], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); + hTcxEnc->spectrum_e[frameno] = sub( hTcxEnc->spectrum_e[frameno], q_tcx20Win ); + move16(); } /* high-band gain control in case of BWS */ @@ -1147,23 +1168,27 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) && ( ( LT_32( st->total_brate, HQ_96k ) ) || st->igf ) ) { pMdstWin = tcx20Win; + Word16 q_pmdstWin = q_tcx20Win; + move16(); test(); if ( ( ( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) ) { pMdstWin = mdstWin; + q_pmdstWin = q_mdstWin; + move16(); } /* Compute noise-measure flags for spectrum filling and quantization */ AnalyzePowerSpectrum_ivas_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ), L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno], - pMdstWin, powerSpec, powerSpec_e ); + pMdstWin, q_pmdstWin, powerSpec, powerSpec_e ); } } } IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Word16 q_mdstWin, scale; + Word16 scale; L_subframe = idiv1616( L_frameTCX, nSubframes ); /* Q0 */ test(); @@ -1173,8 +1198,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( scale = sub( norm_arr( mdstWin, L_frameTCX ), 1 ); scale = s_min( 1, scale ); // restricting the Q to zero or less scale_sig( mdstWin, L_frameTCX, scale ); - q_mdstWin = add( -1, scale ); - move16(); + q_mdstWin = add( add( st->q_inp, -1 ), scale ); } ELSE { @@ -1185,8 +1209,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( scale = sub( norm_arr( mdstWin, sig_len ), 1 ); scale = s_min( 0, scale ); // restricting the Q to zero or less scale_sig( mdstWin, sig_len, scale ); - q_mdstWin = scale; - move16(); + q_mdstWin = add( scale, st->q_inp ); } IF( EQ_16( transform_type[frameno], TCX_5 ) ) @@ -1205,17 +1228,17 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } @@ -1292,17 +1315,17 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 7c3daebda..d0a91a098 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -370,15 +370,16 @@ static void kernel_switch_trafo_fx( static void kernel_switch_update_transforms_fx( - Word32 *sigR, /* i/o: MDCT samples of the given channel (*q_sig) */ - Word32 *sigI, /* i/o: MDST samples of the given channel (*q_sig) */ - Word16 *q_sig, /* i/o: Common Q of MDCT and MDST samples of the given channel */ - const Word16 tcxTransType, /* i : TCX transform type, cf also above */ - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration handle, pointer */ - const Word16 bwidthSwCnt, /* i : bandwidth switching counter in st */ - const UWord16 kernelType, /* i : TCX transform kernel type (0 - 3) */ - Word16 *tcxTimeSignal, /* i : hTcxEnc->new_speech_TCX buf in st */ - const Word16 *speech_TCX, /* i : hTcxEnc->speech_TCX buffer in st */ + Word32 *sigR, /* i/o: MDCT samples of the given channel (*q_sig) */ + Word32 *sigI, /* i/o: MDST samples of the given channel (*q_sig) */ + Word16 *q_sig, /* i/o: Common Q of MDCT and MDST samples of the given channel */ + const Word16 tcxTransType, /* i : TCX transform type, cf also above */ + TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration handle, pointer */ + const Word16 bwidthSwCnt, /* i : bandwidth switching counter in st */ + const UWord16 kernelType, /* i : TCX transform kernel type (0 - 3) */ + Word16 *tcxTimeSignal, /* i : hTcxEnc->new_speech_TCX buf in st */ + const Word16 *speech_TCX, /* i : hTcxEnc->speech_TCX buffer in st */ + const Word16 q_speech, Word32 *windowedTimeSignal, /* i/o: windowed input and scratch buffer (*q_windowedTimeSignal) */ Word16 *q_windowedTimeSignal, /* i/o: Q of windowed input and scratch buffer */ const Word16 L_subframe /* i : transform length (number of bins) */ @@ -429,9 +430,9 @@ static void kernel_switch_update_transforms_fx( Word32 factor; n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), sub( -Q1, q_speech ) ); // q_speech -> Q-1 wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), sub( q_speech, -Q1 ) ); // Q-1 -> q_speech Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); @@ -469,17 +470,17 @@ static void kernel_switch_update_transforms_fx( { FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -488,17 +489,17 @@ static void kernel_switch_update_transforms_fx( { FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -1486,7 +1487,7 @@ void ivas_mdct_core_whitening_enc_fx( speech = hTcxEnc0->speech_TCX; } kernel_switch_update_transforms_fx( hTcxEnc0->spectrum_fx[n], mdst_spectrum_fx[0][n], &q_com, hTcxEnc0->transform_type[n], sts[0]->hTcxCfg, sts[0]->bwidth_sw_cnt, hTcxEnc0->kernel_type[n], - hTcxEnc0->new_speech_TCX, speech, windowedSignal_fx[0] + i_mult( n, L_FRAME48k ), &q_windowedSignal[0], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); + hTcxEnc0->new_speech_TCX, speech, sts[0]->q_inp, windowedSignal_fx[0] + i_mult( n, L_FRAME48k ), &q_windowedSignal[0], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); mdst_spectrum_e[0][n] = sub( Q31, q_com ); hTcxEnc0->spectrum_e[n] = sub( Q31, q_com ); move16(); @@ -1507,7 +1508,7 @@ void ivas_mdct_core_whitening_enc_fx( speech = hTcxEnc1->speech_TCX; } kernel_switch_update_transforms_fx( hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[1][n], &q_com, hTcxEnc1->transform_type[n], sts[1]->hTcxCfg, sts[1]->bwidth_sw_cnt, hTcxEnc1->kernel_type[n], - hTcxEnc1->new_speech_TCX, speech, windowedSignal_fx[1] + i_mult( n, L_FRAME48k ), &q_windowedSignal[1], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); + hTcxEnc1->new_speech_TCX, speech, sts[1]->q_inp, windowedSignal_fx[1] + i_mult( n, L_FRAME48k ), &q_windowedSignal[1], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); mdst_spectrum_e[1][n] = sub( Q31, q_com ); hTcxEnc1->spectrum_e[n] = sub( Q31, q_com ); move16(); @@ -1741,7 +1742,7 @@ void ivas_mdct_core_whitening_enc_fx( speech = NULL; } kernel_switch_update_transforms_fx( hTcxEncCh->spectrum_fx[n], mdst_spectrum_fx[ch][n], &q_com, hTcxEncCh->transform_type[n], sts[ch]->hTcxCfg, sts[ch]->bwidth_sw_cnt, hTcxEncCh->kernel_type[n], - hTcxEncCh->new_speech_TCX, speech, windowedSignal_fx[ch] + i_mult( n, L_FRAME48k ), &q_windowedSignal[ch], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); + hTcxEncCh->new_speech_TCX, speech, sts[ch]->q_inp, windowedSignal_fx[ch] + i_mult( n, L_FRAME48k ), &q_windowedSignal[ch], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); mdst_spectrum_e[ch][n] = sub( Q31, q_com ); move16(); hTcxEncCh->spectrum_e[n] = sub( Q31, q_com ); diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index b32e8a561..2e365be47 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -250,7 +250,10 @@ void stereo_mdct_core_enc_fx( hCPE->hStereoMdct->stbParamsTCX20.nBandsStereoCore = hCPE->hStereoMdct->stbParamsTCX20.sfbCnt; move16(); } - + Word16 len = extract_l( Mpy_32_32( sts[0]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + Word16 q_com = s_min( s_min( add( sts[0]->q_inp, getScaleFactor16( sts[0]->input_fx, add( len, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ), add( sts[0]->q_old_inp, getScaleFactor16( sts[0]->old_input_signal_fx, len ) ) ), + s_min( add( sts[1]->q_inp, getScaleFactor16( sts[1]->input_fx, add( len, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ), add( sts[1]->q_old_inp, getScaleFactor16( sts[1]->old_input_signal_fx, len ) ) ) ); + q_com = s_min( 0, q_com ); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch]; @@ -272,11 +275,11 @@ void stereo_mdct_core_enc_fx( sts[ch]->hTcxEnc->tns_ms_flag[1] = 0; move16(); - Scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( sts[ch]->q_inp ) ); /* Q0 */ - Scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), negate( sts[ch]->q_old_inp ) ); /* Q0 */ - sts[ch]->q_old_inp = 0; + Scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sub( q_com, sts[ch]->q_inp ) ); /* Q0 */ + Scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), sub( q_com, sts[ch]->q_old_inp ) ); /* Q0 */ + sts[ch]->q_old_inp = q_com; move16(); - sts[ch]->q_inp = 0; + sts[ch]->q_inp = q_com; move16(); } @@ -765,7 +768,6 @@ void stereo_mdct_core_enc_fx( * Split available bits between channels *---------------------------------------------------------------*/ - Word16 q_com; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { Word16 n_sb = NB_DIV; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index e54d3025e..64402bf3c 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1278,7 +1278,8 @@ void AnalyzePowerSpectrum_ivas_fx( Word32 const mdctSpectrum[], /* i : MDCT spectrum */ Word16 mdctSpectrum_e, Word16 const signal[], /* i : windowed signal corresponding to mdctSpectrum */ - Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ + const Word16 q_signal, + Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ Word16 powerSpec_e[] ); void AdaptLowFreqEmph_fx( Word32 x[], diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 5bea901bb..ad1720665 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -330,7 +330,8 @@ void AnalyzePowerSpectrum_ivas_fx( Word32 const mdctSpectrum[], /* input: MDCT spectrum */ Word16 mdctSpectrum_e, Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */ - Word32 powerSpec[], /* output: Power spectrum. Can point to signal */ + const Word16 q_signal, + Word32 powerSpec[], /* output: Power spectrum. Can point to signal */ Word16 powerSpec_e[] ) { Word16 i, iStart, iEnd, lowpassLine; @@ -342,8 +343,7 @@ void AnalyzePowerSpectrum_ivas_fx( lowpassLine = L_frameTCX; move16(); - Word16 temp_powerSpec_e = 16; - move16(); + Word16 temp_powerSpec_e = sub( 16, q_signal ); TCX_MDST( signal, powerSpec, &temp_powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); shift = L_norm_arr( powerSpec, N_MAX + L_MDCT_OVLP_MAX ); -- GitLab From 32bba36dea4533cbf1bd6f01fd786a4fa434a203 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 09:02:46 +0200 Subject: [PATCH 0818/1221] add FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat --- lib_com/options.h | 4 ++++ lib_com/tools_fx.c | 26 +++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 2b88deb5d..8962098b9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,4 +80,8 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT +// +// new speedups +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | + #endif diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5219d076c..756b5be80 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,13 +794,37 @@ void Copy_Scale_sig_16_32_no_sat( } return; } +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat + L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); + + IF( L_tmp >= 0x7FFF ) + { + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* Overflow can occur here */ + } + return; + } + // ELSE + { + Word16 tmp = extract_l( L_tmp ); + FOR( i = 0; i < lg; i++ ) + { + y[i] = L_mult( x[i], tmp ); + move32(); + } + } +#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ + move32(); /* Overflow can occur here */ } +#endif } void Copy_Scale_sig_32_16( -- GitLab From e430720c9c5a2246b69a245e3f349e2f2f2f49cf Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 09:05:27 +0200 Subject: [PATCH 0819/1221] add FIX_1439_SPEEDUP_stereo_icBWE_dec_fx --- lib_com/options.h | 1 + lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 8962098b9..787f0338a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -83,5 +83,6 @@ // // new speedups #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | #endif diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c7bc98566..772eb2d7d 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,6 +904,9 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); +#endif FOR( i = 0; i < winLen_fx; i++ ) { L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ @@ -911,10 +914,17 @@ void stereo_icBWE_dec_fx( tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + if ( LE_16( alpha_fx, winSlope_fx_ ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ + } +#else IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } +#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) -- GitLab From 932c3f55d6d41abac3f13a470e6a1f8906516228 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 09:08:32 +0200 Subject: [PATCH 0820/1221] add FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx --- lib_com/options.h | 1 + lib_dec/swb_tbe_dec_fx.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 787f0338a..3a96cb998 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,5 +84,6 @@ // new speedups #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | #endif diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1b51a29fb..00be6455d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7022,14 +7022,24 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); + +#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx + Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 +#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { +#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } +#else + Word16 idx; + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ +#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); -- GitLab From f1e32ecf14d70eafaf0f4d86c4b57ec75f62cffb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 09:13:38 +0200 Subject: [PATCH 0821/1221] add FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig --- lib_com/options.h | 1 + lib_com/swb_tbe_com_fx.c | 93 +++++++++++++++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 3a96cb998..3e8725112 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,5 +85,6 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..062c131ee 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6763,18 +6763,91 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + { + i = 4; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; + + FOR( ; i < L_FRAME48k; ) + { + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } + } + ELSE +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ + { + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } } memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; -- GitLab From 866a91131bef01ce1db3654162fcee71cdfd925a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 09:18:27 +0200 Subject: [PATCH 0822/1221] add FIX_1439_SPEEDUP_synthesise_fb_high_band_fx --- lib_com/options.h | 4 +++- lib_com/swb_tbe_com_fx.c | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 3e8725112..571b5edd3 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -83,8 +83,10 @@ // // new speedups #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? + #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 062c131ee..af52c2564 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7146,6 +7146,50 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ + Word32 L_tmp32; + Word16 tmp16; + + // if (L_tmp < 0) + if ( L_tmp < 0 ) + { + L_tmp32 = L_negate( L_tmp ); + } + if ( L_tmp < 0 ) + { + L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); + } + if ( L_tmp < 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + if ( L_tmp < 0 ) + { + tmp16 = negate( tmp16 ); + } + + // if (L_tmp == 0) + if ( L_tmp == 0 ) + { + tmp16 = 0; + move16(); + } + + // if (L_tmp > 0) + if ( L_tmp > 0 ) + { + L_tmp32 = L_shl_sat( L_tmp, tmp3 ); + } + if ( L_tmp > 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + + output[i] = tmp16; + move16(); + +#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7157,6 +7201,7 @@ void synthesise_fb_high_band_fx( output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); } +#endif } return; } -- GitLab From 00053a90002504d72c527fa12c852af44830bf42 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 09:20:44 +0200 Subject: [PATCH 0823/1221] deactivate all speedups --- lib_com/options.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 571b5edd3..13f7c7f18 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,11 +82,11 @@ //#define HARM_SCE_INIT // // new speedups -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS +//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? +//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? #endif -- GitLab From 40ea7cb4e2dba433511e5fe47bb4130e997c6bbb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 4 Apr 2025 10:03:20 +0200 Subject: [PATCH 0824/1221] activated all speedups (BE) --- lib_com/options.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 13f7c7f18..571b5edd3 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,11 +82,11 @@ //#define HARM_SCE_INIT // // new speedups -//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS -//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? #endif -- GitLab From 9b493845537e40879b42d81dabddb076d3bbd0e0 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 6 Apr 2025 21:00:00 +0200 Subject: [PATCH 0825/1221] add BASOP_Util_Divide3232_Scale_newton() --- lib_com/basop_util.c | 408 +++++++++++++++++++++++++++++++++++++++++++ lib_com/basop_util.h | 7 + lib_com/options.h | 2 + 3 files changed, 417 insertions(+) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index b7ee35ab3..ec15e9769 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1062,6 +1062,414 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) return z; } +#ifdef DIV32_OPT_NEWTON +Word32 div_w_newton( Word32 num, Word32 den ); +/* +Table of 256 precalculated estimates to be used by the "div_w_newton" +function using the Newton/Raphson method. +Note: The first table value (for denominator near 0x40000000) is not fully +accurate and should not be used. +*/ +Word32 div_w_newton_lookup[256] = { + /* Precalculated rounded results for 0x40000000 / b with b in [0x40000000 ... 0x7FFFFFFF] */ + 0x7FFFFFFF, // 1.000000000000000 i=0 0.5 / 0.5+0/512 (b=0x40000000) + 0x7F807F80, // 0.996108949416342 i=1 0.5 / 0.5+1/512 (b=0x40400000) + 0x7F01FC07, // 0.992248062015504 i=2 0.5 / 0.5+2/512 (b=0x40800000) + 0x7E8472A8, // 0.988416988416988 i=3 0.5 / 0.5+3/512 (b=0x40C00000) + 0x7E07E07E, // 0.984615384615385 i=4 0.5 / 0.5+4/512 (b=0x41000000) + 0x7D8C42B2, // 0.980842911877395 i=5 0.5 / 0.5+5/512 (b=0x41400000) + 0x7D119679, // 0.977099236641221 i=6 0.5 / 0.5+6/512 (b=0x41800000) + 0x7C97D910, // 0.973384030418251 i=7 0.5 / 0.5+7/512 (b=0x41C00000) + 0x7C1F07C1, // 0.969696969696970 i=8 0.5 / 0.5+8/512 (b=0x42000000) + 0x7BA71FE1, // 0.966037735849057 i=9 0.5 / 0.5+9/512 (b=0x42400000) + 0x7B301ECC, // 0.962406015037594 i=10 0.5 / 0.5+10/512 (b=0x42800000) + 0x7ABA01EA, // 0.958801498127341 i=11 0.5 / 0.5+11/512 (b=0x42C00000) + 0x7A44C6AF, // 0.955223880597015 i=12 0.5 / 0.5+12/512 (b=0x43000000) + 0x79D06A96, // 0.951672862453532 i=13 0.5 / 0.5+13/512 (b=0x43400000) + 0x795CEB24, // 0.948148148148148 i=14 0.5 / 0.5+14/512 (b=0x43800000) + 0x78EA45E7, // 0.944649446494465 i=15 0.5 / 0.5+15/512 (b=0x43C00000) + 0x78787878, // 0.941176470588235 i=16 0.5 / 0.5+16/512 (b=0x44000000) + 0x78078078, // 0.937728937728938 i=17 0.5 / 0.5+17/512 (b=0x44400000) + 0x77975B8F, // 0.934306569343066 i=18 0.5 / 0.5+18/512 (b=0x44800000) + 0x77280772, // 0.930909090909091 i=19 0.5 / 0.5+19/512 (b=0x44C00000) + 0x76B981DA, // 0.927536231884058 i=20 0.5 / 0.5+20/512 (b=0x45000000) + 0x764BC88C, // 0.924187725631769 i=21 0.5 / 0.5+21/512 (b=0x45400000) + 0x75DED952, // 0.920863309352518 i=22 0.5 / 0.5+22/512 (b=0x45800000) + 0x7572B201, // 0.917562724014337 i=23 0.5 / 0.5+23/512 (b=0x45C00000) + 0x75075075, // 0.914285714285714 i=24 0.5 / 0.5+24/512 (b=0x46000000) + 0x749CB28F, // 0.911032028469751 i=25 0.5 / 0.5+25/512 (b=0x46400000) + 0x7432D63D, // 0.907801418439716 i=26 0.5 / 0.5+26/512 (b=0x46800000) + 0x73C9B971, // 0.904593639575972 i=27 0.5 / 0.5+27/512 (b=0x46C00000) + 0x73615A24, // 0.901408450704225 i=28 0.5 / 0.5+28/512 (b=0x47000000) + 0x72F9B658, // 0.898245614035088 i=29 0.5 / 0.5+29/512 (b=0x47400000) + 0x7292CC15, // 0.895104895104895 i=30 0.5 / 0.5+30/512 (b=0x47800000) + 0x722C996B, // 0.891986062717770 i=31 0.5 / 0.5+31/512 (b=0x47C00000) + 0x71C71C71, // 0.888888888888889 i=32 0.5 / 0.5+32/512 (b=0x48000000) + 0x71625344, // 0.885813148788927 i=33 0.5 / 0.5+33/512 (b=0x48400000) + 0x70FE3C07, // 0.882758620689655 i=34 0.5 / 0.5+34/512 (b=0x48800000) + 0x709AD4E4, // 0.879725085910653 i=35 0.5 / 0.5+35/512 (b=0x48C00000) + 0x70381C0E, // 0.876712328767123 i=36 0.5 / 0.5+36/512 (b=0x49000000) + 0x6FD60FBA, // 0.873720136518771 i=37 0.5 / 0.5+37/512 (b=0x49400000) + 0x6F74AE26, // 0.870748299319728 i=38 0.5 / 0.5+38/512 (b=0x49800000) + 0x6F13F596, // 0.867796610169492 i=39 0.5 / 0.5+39/512 (b=0x49C00000) + 0x6EB3E453, // 0.864864864864865 i=40 0.5 / 0.5+40/512 (b=0x4A000000) + 0x6E5478AC, // 0.861952861952862 i=41 0.5 / 0.5+41/512 (b=0x4A400000) + 0x6DF5B0F7, // 0.859060402684564 i=42 0.5 / 0.5+42/512 (b=0x4A800000) + 0x6D978B8E, // 0.856187290969900 i=43 0.5 / 0.5+43/512 (b=0x4AC00000) + 0x6D3A06D3, // 0.853333333333333 i=44 0.5 / 0.5+44/512 (b=0x4B000000) + 0x6CDD212B, // 0.850498338870432 i=45 0.5 / 0.5+45/512 (b=0x4B400000) + 0x6C80D901, // 0.847682119205298 i=46 0.5 / 0.5+46/512 (b=0x4B800000) + 0x6C252CC7, // 0.844884488448845 i=47 0.5 / 0.5+47/512 (b=0x4BC00000) + 0x6BCA1AF2, // 0.842105263157895 i=48 0.5 / 0.5+48/512 (b=0x4C000000) + 0x6B6FA1FE, // 0.839344262295082 i=49 0.5 / 0.5+49/512 (b=0x4C400000) + 0x6B15C06B, // 0.836601307189543 i=50 0.5 / 0.5+50/512 (b=0x4C800000) + 0x6ABC74BE, // 0.833876221498371 i=51 0.5 / 0.5+51/512 (b=0x4CC00000) + 0x6A63BD81, // 0.831168831168831 i=52 0.5 / 0.5+52/512 (b=0x4D000000) + 0x6A0B9944, // 0.828478964401295 i=53 0.5 / 0.5+53/512 (b=0x4D400000) + 0x69B4069B, // 0.825806451612903 i=54 0.5 / 0.5+54/512 (b=0x4D800000) + 0x695D041D, // 0.823151125401929 i=55 0.5 / 0.5+55/512 (b=0x4DC00000) + 0x69069069, // 0.820512820512820 i=56 0.5 / 0.5+56/512 (b=0x4E000000) + 0x68B0AA1F, // 0.817891373801917 i=57 0.5 / 0.5+57/512 (b=0x4E400000) + 0x685B4FE5, // 0.815286624203822 i=58 0.5 / 0.5+58/512 (b=0x4E800000) + 0x68068068, // 0.812698412698413 i=59 0.5 / 0.5+59/512 (b=0x4EC00000) + 0x67B23A54, // 0.810126582278481 i=60 0.5 / 0.5+60/512 (b=0x4F000000) + 0x675E7C5D, // 0.807570977917981 i=61 0.5 / 0.5+61/512 (b=0x4F400000) + 0x670B453B, // 0.805031446540881 i=62 0.5 / 0.5+62/512 (b=0x4F800000) + 0x66B893A9, // 0.802507836990596 i=63 0.5 / 0.5+63/512 (b=0x4FC00000) + 0x66666666, // 0.800000000000000 i=64 0.5 / 0.5+64/512 (b=0x50000000) + 0x6614BC36, // 0.797507788161994 i=65 0.5 / 0.5+65/512 (b=0x50400000) + 0x65C393E0, // 0.795031055900621 i=66 0.5 / 0.5+66/512 (b=0x50800000) + 0x6572EC2F, // 0.792569659442725 i=67 0.5 / 0.5+67/512 (b=0x50C00000) + 0x6522C3F3, // 0.790123456790123 i=68 0.5 / 0.5+68/512 (b=0x51000000) + 0x64D319FE, // 0.787692307692308 i=69 0.5 / 0.5+69/512 (b=0x51400000) + 0x6483ED27, // 0.785276073619632 i=70 0.5 / 0.5+70/512 (b=0x51800000) + 0x64353C48, // 0.782874617737003 i=71 0.5 / 0.5+71/512 (b=0x51C00000) + 0x63E7063E, // 0.780487804878049 i=72 0.5 / 0.5+72/512 (b=0x52000000) + 0x639949EB, // 0.778115501519757 i=73 0.5 / 0.5+73/512 (b=0x52400000) + 0x634C0634, // 0.775757575757576 i=74 0.5 / 0.5+74/512 (b=0x52800000) + 0x62FF3A01, // 0.773413897280967 i=75 0.5 / 0.5+75/512 (b=0x52C00000) + 0x62B2E43D, // 0.771084337349398 i=76 0.5 / 0.5+76/512 (b=0x53000000) + 0x626703D8, // 0.768768768768769 i=77 0.5 / 0.5+77/512 (b=0x53400000) + 0x621B97C2, // 0.766467065868264 i=78 0.5 / 0.5+78/512 (b=0x53800000) + 0x61D09EF3, // 0.764179104477612 i=79 0.5 / 0.5+79/512 (b=0x53C00000) + 0x61861861, // 0.761904761904762 i=80 0.5 / 0.5+80/512 (b=0x54000000) + 0x613C0309, // 0.759643916913947 i=81 0.5 / 0.5+81/512 (b=0x54400000) + 0x60F25DEA, // 0.757396449704142 i=82 0.5 / 0.5+82/512 (b=0x54800000) + 0x60A92806, // 0.755162241887906 i=83 0.5 / 0.5+83/512 (b=0x54C00000) + 0x60606060, // 0.752941176470588 i=84 0.5 / 0.5+84/512 (b=0x55000000) + 0x60180601, // 0.750733137829912 i=85 0.5 / 0.5+85/512 (b=0x55400000) + 0x5FD017F4, // 0.748538011695906 i=86 0.5 / 0.5+86/512 (b=0x55800000) + 0x5F889545, // 0.746355685131195 i=87 0.5 / 0.5+87/512 (b=0x55C00000) + 0x5F417D05, // 0.744186046511628 i=88 0.5 / 0.5+88/512 (b=0x56000000) + 0x5EFACE48, // 0.742028985507246 i=89 0.5 / 0.5+89/512 (b=0x56400000) + 0x5EB48823, // 0.739884393063584 i=90 0.5 / 0.5+90/512 (b=0x56800000) + 0x5E6EA9AE, // 0.737752161383285 i=91 0.5 / 0.5+91/512 (b=0x56C00000) + 0x5E293205, // 0.735632183908046 i=92 0.5 / 0.5+92/512 (b=0x57000000) + 0x5DE42046, // 0.733524355300860 i=93 0.5 / 0.5+93/512 (b=0x57400000) + 0x5D9F7390, // 0.731428571428571 i=94 0.5 / 0.5+94/512 (b=0x57800000) + 0x5D5B2B08, // 0.729344729344729 i=95 0.5 / 0.5+95/512 (b=0x57C00000) + 0x5D1745D1, // 0.727272727272727 i=96 0.5 / 0.5+96/512 (b=0x58000000) + 0x5CD3C315, // 0.725212464589235 i=97 0.5 / 0.5+97/512 (b=0x58400000) + 0x5C90A1FD, // 0.723163841807910 i=98 0.5 / 0.5+98/512 (b=0x58800000) + 0x5C4DE1B6, // 0.721126760563380 i=99 0.5 / 0.5+99/512 (b=0x58C00000) + 0x5C0B8170, // 0.719101123595506 i=100 0.5 / 0.5+100/512 (b=0x59000000) + 0x5BC9805B, // 0.717086834733894 i=101 0.5 / 0.5+101/512 (b=0x59400000) + 0x5B87DDAD, // 0.715083798882682 i=102 0.5 / 0.5+102/512 (b=0x59800000) + 0x5B46989A, // 0.713091922005571 i=103 0.5 / 0.5+103/512 (b=0x59C00000) + 0x5B05B05B, // 0.711111111111111 i=104 0.5 / 0.5+104/512 (b=0x5A000000) + 0x5AC5242A, // 0.709141274238227 i=105 0.5 / 0.5+105/512 (b=0x5A400000) + 0x5A84F345, // 0.707182320441989 i=106 0.5 / 0.5+106/512 (b=0x5A800000) + 0x5A451CEA, // 0.705234159779614 i=107 0.5 / 0.5+107/512 (b=0x5AC00000) + 0x5A05A05A, // 0.703296703296703 i=108 0.5 / 0.5+108/512 (b=0x5B000000) + 0x59C67CD8, // 0.701369863013699 i=109 0.5 / 0.5+109/512 (b=0x5B400000) + 0x5987B1A9, // 0.699453551912568 i=110 0.5 / 0.5+110/512 (b=0x5B800000) + 0x59493E14, // 0.697547683923706 i=111 0.5 / 0.5+111/512 (b=0x5BC00000) + 0x590B2164, // 0.695652173913043 i=112 0.5 / 0.5+112/512 (b=0x5C000000) + 0x58CD5AE2, // 0.693766937669377 i=113 0.5 / 0.5+113/512 (b=0x5C400000) + 0x588FE9DC, // 0.691891891891892 i=114 0.5 / 0.5+114/512 (b=0x5C800000) + 0x5852CDA0, // 0.690026954177898 i=115 0.5 / 0.5+115/512 (b=0x5CC00000) + 0x58160581, // 0.688172043010753 i=116 0.5 / 0.5+116/512 (b=0x5D000000) + 0x57D990D0, // 0.686327077747989 i=117 0.5 / 0.5+117/512 (b=0x5D400000) + 0x579D6EE3, // 0.684491978609626 i=118 0.5 / 0.5+118/512 (b=0x5D800000) + 0x57619F0F, // 0.682666666666667 i=119 0.5 / 0.5+119/512 (b=0x5DC00000) + 0x572620AE, // 0.680851063829787 i=120 0.5 / 0.5+120/512 (b=0x5E000000) + 0x56EAF319, // 0.679045092838196 i=121 0.5 / 0.5+121/512 (b=0x5E400000) + 0x56B015AC, // 0.677248677248677 i=122 0.5 / 0.5+122/512 (b=0x5E800000) + 0x567587C4, // 0.675461741424802 i=123 0.5 / 0.5+123/512 (b=0x5EC00000) + 0x563B48C2, // 0.673684210526316 i=124 0.5 / 0.5+124/512 (b=0x5F000000) + 0x56015805, // 0.671916010498688 i=125 0.5 / 0.5+125/512 (b=0x5F400000) + 0x55C7B4F1, // 0.670157068062827 i=126 0.5 / 0.5+126/512 (b=0x5F800000) + 0x558E5EE9, // 0.668407310704961 i=127 0.5 / 0.5+127/512 (b=0x5FC00000) + 0x55555555, // 0.666666666666667 i=128 0.5 / 0.5+128/512 (b=0x60000000) + 0x551C979A, // 0.664935064935065 i=129 0.5 / 0.5+129/512 (b=0x60400000) + 0x54E42523, // 0.663212435233161 i=130 0.5 / 0.5+130/512 (b=0x60800000) + 0x54ABFD5A, // 0.661498708010336 i=131 0.5 / 0.5+131/512 (b=0x60C00000) + 0x54741FAB, // 0.659793814432990 i=132 0.5 / 0.5+132/512 (b=0x61000000) + 0x543C8B84, // 0.658097686375321 i=133 0.5 / 0.5+133/512 (b=0x61400000) + 0x54054054, // 0.656410256410256 i=134 0.5 / 0.5+134/512 (b=0x61800000) + 0x53CE3D8B, // 0.654731457800512 i=135 0.5 / 0.5+135/512 (b=0x61C00000) + 0x5397829C, // 0.653061224489796 i=136 0.5 / 0.5+136/512 (b=0x62000000) + 0x53610EFB, // 0.651399491094148 i=137 0.5 / 0.5+137/512 (b=0x62400000) + 0x532AE21C, // 0.649746192893401 i=138 0.5 / 0.5+138/512 (b=0x62800000) + 0x52F4FB76, // 0.648101265822785 i=139 0.5 / 0.5+139/512 (b=0x62C00000) + 0x52BF5A81, // 0.646464646464647 i=140 0.5 / 0.5+140/512 (b=0x63000000) + 0x5289FEB5, // 0.644836272040302 i=141 0.5 / 0.5+141/512 (b=0x63400000) + 0x5254E78E, // 0.643216080402010 i=142 0.5 / 0.5+142/512 (b=0x63800000) + 0x52201488, // 0.641604010025063 i=143 0.5 / 0.5+143/512 (b=0x63C00000) + 0x51EB851E, // 0.640000000000000 i=144 0.5 / 0.5+144/512 (b=0x64000000) + 0x51B738D1, // 0.638403990024938 i=145 0.5 / 0.5+145/512 (b=0x64400000) + 0x51832F1F, // 0.636815920398010 i=146 0.5 / 0.5+146/512 (b=0x64800000) + 0x514F678B, // 0.635235732009926 i=147 0.5 / 0.5+147/512 (b=0x64C00000) + 0x511BE195, // 0.633663366336634 i=148 0.5 / 0.5+148/512 (b=0x65000000) + 0x50E89CC2, // 0.632098765432099 i=149 0.5 / 0.5+149/512 (b=0x65400000) + 0x50B59897, // 0.630541871921182 i=150 0.5 / 0.5+150/512 (b=0x65800000) + 0x5082D499, // 0.628992628992629 i=151 0.5 / 0.5+151/512 (b=0x65C00000) + 0x50505050, // 0.627450980392157 i=152 0.5 / 0.5+152/512 (b=0x66000000) + 0x501E0B44, // 0.625916870415648 i=153 0.5 / 0.5+153/512 (b=0x66400000) + 0x4FEC04FE, // 0.624390243902439 i=154 0.5 / 0.5+154/512 (b=0x66800000) + 0x4FBA3D0A, // 0.622871046228710 i=155 0.5 / 0.5+155/512 (b=0x66C00000) + 0x4F88B2F3, // 0.621359223300971 i=156 0.5 / 0.5+156/512 (b=0x67000000) + 0x4F576646, // 0.619854721549637 i=157 0.5 / 0.5+157/512 (b=0x67400000) + 0x4F265691, // 0.618357487922705 i=158 0.5 / 0.5+158/512 (b=0x67800000) + 0x4EF58364, // 0.616867469879518 i=159 0.5 / 0.5+159/512 (b=0x67C00000) + 0x4EC4EC4E, // 0.615384615384615 i=160 0.5 / 0.5+160/512 (b=0x68000000) + 0x4E9490E1, // 0.613908872901679 i=161 0.5 / 0.5+161/512 (b=0x68400000) + 0x4E6470B0, // 0.612440191387560 i=162 0.5 / 0.5+162/512 (b=0x68800000) + 0x4E348B4D, // 0.610978520286396 i=163 0.5 / 0.5+163/512 (b=0x68C00000) + 0x4E04E04E, // 0.609523809523810 i=164 0.5 / 0.5+164/512 (b=0x69000000) + 0x4DD56F47, // 0.608076009501188 i=165 0.5 / 0.5+165/512 (b=0x69400000) + 0x4DA637CF, // 0.606635071090047 i=166 0.5 / 0.5+166/512 (b=0x69800000) + 0x4D77397E, // 0.605200945626478 i=167 0.5 / 0.5+167/512 (b=0x69C00000) + 0x4D4873EC, // 0.603773584905660 i=168 0.5 / 0.5+168/512 (b=0x6A000000) + 0x4D19E6B3, // 0.602352941176471 i=169 0.5 / 0.5+169/512 (b=0x6A400000) + 0x4CEB916D, // 0.600938967136150 i=170 0.5 / 0.5+170/512 (b=0x6A800000) + 0x4CBD73B5, // 0.599531615925059 i=171 0.5 / 0.5+171/512 (b=0x6AC00000) + 0x4C8F8D28, // 0.598130841121495 i=172 0.5 / 0.5+172/512 (b=0x6B000000) + 0x4C61DD63, // 0.596736596736597 i=173 0.5 / 0.5+173/512 (b=0x6B400000) + 0x4C346404, // 0.595348837209302 i=174 0.5 / 0.5+174/512 (b=0x6B800000) + 0x4C0720AB, // 0.593967517401392 i=175 0.5 / 0.5+175/512 (b=0x6BC00000) + 0x4BDA12F6, // 0.592592592592593 i=176 0.5 / 0.5+176/512 (b=0x6C000000) + 0x4BAD3A87, // 0.591224018475751 i=177 0.5 / 0.5+177/512 (b=0x6C400000) + 0x4B809701, // 0.589861751152074 i=178 0.5 / 0.5+178/512 (b=0x6C800000) + 0x4B542804, // 0.588505747126437 i=179 0.5 / 0.5+179/512 (b=0x6CC00000) + 0x4B27ED36, // 0.587155963302752 i=180 0.5 / 0.5+180/512 (b=0x6D000000) + 0x4AFBE639, // 0.585812356979405 i=181 0.5 / 0.5+181/512 (b=0x6D400000) + 0x4AD012B4, // 0.584474885844749 i=182 0.5 / 0.5+182/512 (b=0x6D800000) + 0x4AA4724B, // 0.583143507972665 i=183 0.5 / 0.5+183/512 (b=0x6DC00000) + 0x4A7904A7, // 0.581818181818182 i=184 0.5 / 0.5+184/512 (b=0x6E000000) + 0x4A4DC96E, // 0.580498866213152 i=185 0.5 / 0.5+185/512 (b=0x6E400000) + 0x4A22C04A, // 0.579185520361991 i=186 0.5 / 0.5+186/512 (b=0x6E800000) + 0x49F7E8E2, // 0.577878103837472 i=187 0.5 / 0.5+187/512 (b=0x6EC00000) + 0x49CD42E2, // 0.576576576576577 i=188 0.5 / 0.5+188/512 (b=0x6F000000) + 0x49A2CDF3, // 0.575280898876405 i=189 0.5 / 0.5+189/512 (b=0x6F400000) + 0x497889C2, // 0.573991031390135 i=190 0.5 / 0.5+190/512 (b=0x6F800000) + 0x494E75FA, // 0.572706935123042 i=191 0.5 / 0.5+191/512 (b=0x6FC00000) + 0x49249249, // 0.571428571428571 i=192 0.5 / 0.5+192/512 (b=0x70000000) + 0x48FADE5C, // 0.570155902004454 i=193 0.5 / 0.5+193/512 (b=0x70400000) + 0x48D159E2, // 0.568888888888889 i=194 0.5 / 0.5+194/512 (b=0x70800000) + 0x48A8048A, // 0.567627494456763 i=195 0.5 / 0.5+195/512 (b=0x70C00000) + 0x487EDE04, // 0.566371681415929 i=196 0.5 / 0.5+196/512 (b=0x71000000) + 0x4855E601, // 0.565121412803532 i=197 0.5 / 0.5+197/512 (b=0x71400000) + 0x482D1C31, // 0.563876651982379 i=198 0.5 / 0.5+198/512 (b=0x71800000) + 0x48048048, // 0.562637362637363 i=199 0.5 / 0.5+199/512 (b=0x71C00000) + 0x47DC11F7, // 0.561403508771930 i=200 0.5 / 0.5+200/512 (b=0x72000000) + 0x47B3D0F1, // 0.560175054704595 i=201 0.5 / 0.5+201/512 (b=0x72400000) + 0x478BBCEC, // 0.558951965065502 i=202 0.5 / 0.5+202/512 (b=0x72800000) + 0x4763D59C, // 0.557734204793028 i=203 0.5 / 0.5+203/512 (b=0x72C00000) + 0x473C1AB6, // 0.556521739130435 i=204 0.5 / 0.5+204/512 (b=0x73000000) + 0x47148BF0, // 0.555314533622560 i=205 0.5 / 0.5+205/512 (b=0x73400000) + 0x46ED2901, // 0.554112554112554 i=206 0.5 / 0.5+206/512 (b=0x73800000) + 0x46C5F19F, // 0.552915766738661 i=207 0.5 / 0.5+207/512 (b=0x73C00000) + 0x469EE584, // 0.551724137931034 i=208 0.5 / 0.5+208/512 (b=0x74000000) + 0x46780467, // 0.550537634408602 i=209 0.5 / 0.5+209/512 (b=0x74400000) + 0x46514E02, // 0.549356223175966 i=210 0.5 / 0.5+210/512 (b=0x74800000) + 0x462AC20E, // 0.548179871520343 i=211 0.5 / 0.5+211/512 (b=0x74C00000) + 0x46046046, // 0.547008547008547 i=212 0.5 / 0.5+212/512 (b=0x75000000) + 0x45DE2864, // 0.545842217484009 i=213 0.5 / 0.5+213/512 (b=0x75400000) + 0x45B81A25, // 0.544680851063830 i=214 0.5 / 0.5+214/512 (b=0x75800000) + 0x45923543, // 0.543524416135881 i=215 0.5 / 0.5+215/512 (b=0x75C00000) + 0x456C797D, // 0.542372881355932 i=216 0.5 / 0.5+216/512 (b=0x76000000) + 0x4546E68F, // 0.541226215644820 i=217 0.5 / 0.5+217/512 (b=0x76400000) + 0x45217C38, // 0.540084388185654 i=218 0.5 / 0.5+218/512 (b=0x76800000) + 0x44FC3A34, // 0.538947368421053 i=219 0.5 / 0.5+219/512 (b=0x76C00000) + 0x44D72044, // 0.537815126050420 i=220 0.5 / 0.5+220/512 (b=0x77000000) + 0x44B22E27, // 0.536687631027254 i=221 0.5 / 0.5+221/512 (b=0x77400000) + 0x448D639D, // 0.535564853556485 i=222 0.5 / 0.5+222/512 (b=0x77800000) + 0x4468C066, // 0.534446764091858 i=223 0.5 / 0.5+223/512 (b=0x77C00000) + 0x44444444, // 0.533333333333333 i=224 0.5 / 0.5+224/512 (b=0x78000000) + 0x441FEEF8, // 0.532224532224532 i=225 0.5 / 0.5+225/512 (b=0x78400000) + 0x43FBC043, // 0.531120331950207 i=226 0.5 / 0.5+226/512 (b=0x78800000) + 0x43D7B7EA, // 0.530020703933747 i=227 0.5 / 0.5+227/512 (b=0x78C00000) + 0x43B3D5AF, // 0.528925619834711 i=228 0.5 / 0.5+228/512 (b=0x79000000) + 0x43901956, // 0.527835051546392 i=229 0.5 / 0.5+229/512 (b=0x79400000) + 0x436C82A2, // 0.526748971193416 i=230 0.5 / 0.5+230/512 (b=0x79800000) + 0x43491158, // 0.525667351129363 i=231 0.5 / 0.5+231/512 (b=0x79C00000) + 0x4325C53E, // 0.524590163934426 i=232 0.5 / 0.5+232/512 (b=0x7A000000) + 0x43029E1A, // 0.523517382413088 i=233 0.5 / 0.5+233/512 (b=0x7A400000) + 0x42DF9BB0, // 0.522448979591837 i=234 0.5 / 0.5+234/512 (b=0x7A800000) + 0x42BCBDC8, // 0.521384928716904 i=235 0.5 / 0.5+235/512 (b=0x7AC00000) + 0x429A0429, // 0.520325203252033 i=236 0.5 / 0.5+236/512 (b=0x7B000000) + 0x42776E9A, // 0.519269776876268 i=237 0.5 / 0.5+237/512 (b=0x7B400000) + 0x4254FCE4, // 0.518218623481781 i=238 0.5 / 0.5+238/512 (b=0x7B800000) + 0x4232AECD, // 0.517171717171717 i=239 0.5 / 0.5+239/512 (b=0x7BC00000) + 0x42108421, // 0.516129032258065 i=240 0.5 / 0.5+240/512 (b=0x7C000000) + 0x41EE7CA6, // 0.515090543259557 i=241 0.5 / 0.5+241/512 (b=0x7C400000) + 0x41CC9829, // 0.514056224899598 i=242 0.5 / 0.5+242/512 (b=0x7C800000) + 0x41AAD671, // 0.513026052104208 i=243 0.5 / 0.5+243/512 (b=0x7CC00000) + 0x4189374B, // 0.512000000000000 i=244 0.5 / 0.5+244/512 (b=0x7D000000) + 0x4167BA81, // 0.510978043912176 i=245 0.5 / 0.5+245/512 (b=0x7D400000) + 0x41465FDF, // 0.509960159362550 i=246 0.5 / 0.5+246/512 (b=0x7D800000) + 0x41252730, // 0.508946322067594 i=247 0.5 / 0.5+247/512 (b=0x7DC00000) + 0x41041041, // 0.507936507936508 i=248 0.5 / 0.5+248/512 (b=0x7E000000) + 0x40E31ADE, // 0.506930693069307 i=249 0.5 / 0.5+249/512 (b=0x7E400000) + 0x40C246D4, // 0.505928853754941 i=250 0.5 / 0.5+250/512 (b=0x7E800000) + 0x40A193F1, // 0.504930966469428 i=251 0.5 / 0.5+251/512 (b=0x7EC00000) + 0x40810204, // 0.503937007874016 i=252 0.5 / 0.5+252/512 (b=0x7F000000) + 0x406090D9, // 0.502946954813359 i=253 0.5 / 0.5+253/512 (b=0x7F400000) + 0x40404040, // 0.501960784313725 i=254 0.5 / 0.5+254/512 (b=0x7F800000) + 0x40201008 // 0.500978473581213 i=255 0.5 / 0.5+255/512 (b=0x7FC00000) +}; + + +/* + * Fractional multiplication of signed a and b, both in Q31. The result is doubled. + * Note: in this test, saturation is not needed. + * BASOP weights: 3 + */ + +static Word32 L_dmult( Word32 L_var1, Word32 L_var2 ) +{ + Word64 L64_var1 = W_mult0_32_32( L_var1, L_var2 ); + L64_var1 = W_shr( L64_var1, 30 ); + return W_extract_l( L64_var1 ); +} + +/* + * 32 by 32 bit division, following the Newton / Raphson method. + * Usage of this low-level procedure by the caller: + * 1. Numerator can use the full range of signed 32-bit datatypes: 0x80000000...0x7FFFFFFF + * Note: Since is not normalized here, but it is multplied to the reciprocal of the + * denominator, the caller should use a normalized and handle any exponent outside. + * 2. Denominator must be normalized into range 0x40000001 to 0x7FFFFFFF (all positive) + * Note: In case of den=0x40000000, the caller is not allowed to call the division routine, + since the result is known. + * Note: num / 0x40000000 equals to num with exp += 1. + * 3. The result is in range 0x40000000 to 0x7FFFFFFF, finally multiplied by . + * BASOP weights: 24 (incl. L_dmult) + */ + +Word32 div_w_newton( Word32 num, Word32 den ) +{ + Word32 x0, x1, x2, x3, diff, result; + + x0 = div_w_newton_lookup[sub( extract_l( L_shr( den, 22 ) ), 256 )]; + move32(); + + diff = L_sub( 0x40000000, Mpy_32_32( den, x0 ) ); + + x1 = L_add( x0, L_dmult( x0, diff ) ); + diff = L_sub( 0x40000000, Mpy_32_32( den, x1 ) ); + + x2 = L_add( x1, L_dmult( x1, diff ) ); + diff = L_sub( 0x40000000, Mpy_32_32( den, x2 ) ); + + x3 = L_add( x2, L_dmult( x2, diff ) ); + + result = Mpy_32_32( num, x3 ); + + return result; +} + +/* + * 32 / 32 division + * Usage of this global procedure by the caller: + * 1. Numerator can use the full range of signed 32-bit datatypes: 0x80000000...0x7FFFFFFF + * Note: Since is not normalized here, but it is multplied to the reciprocal of the + * denominator, the caller should use a normalized and handle any exponent outside. + * 2. Denominator can use the full range of signed 32-bit datatypes: 0x80000000...0x7FFFFFFF + * except den=0x00000000. In case of 0x80000000, it becomes internally negated to 0x7FFFFFFF. + * 3. The result is 0x00000000 (*s=0)for equals 0x00000000. + * The result is rather left aligned, with up to 1 bit headroom. + * 4. The result exponent is stored in s[0] + * BASOP weights: 41 (incl. div_w_newton) + */ + +Word32 BASOP_Util_Divide3232_Scale_newton( Word32 x, Word32 y, Word16 *s ) +{ + Word32 z; + Word16 sx; + Word16 sy; + Word32 sign; + + assert( y != (Word32) 0 ); + + /* Early exit, if numerator is zero */ + IF( x == (Word32) 0 ) + { + *s = 0; + return ( (Word32) 0 ); + } + +#if 0 + sign = L_xor( x, y ); /* check (sign < 0) for result negation */ + + if ( x < 0 ) + { + x = L_negate( x ); + } +#else + IF( EQ_32( y, 0x80000000 ) ) + { + /* Division by -1.0: same as negation of numerator */ + /* Return normalized negated numerator */ + sx = norm_l( x ); + x = L_shl( x, sx ); + *s = negate( sx ); + return L_negate( x ); + } + sign = y; + move32(); +#endif + if ( y < 0 ) + { + y = L_negate( y ); + } + + /* Normalize numerator */ + sx = norm_l( x ); + x = L_shl( x, sx ); + + /* Normalize denominator */ + sy = norm_l( y ); + y = L_shl( y, sy ); + + /* Store exponent: + 1 for div_w_newton computing 0.5*num/den */ + *s = sub( add( sy, 1 ), sx ); + move16(); + + /* Special treatment for den=0x40000000 */ + /* Result is known: z=2*num */ + IF( EQ_32( y, 0x40000000 ) ) + { + if ( sign < 0 ) + { + x = L_negate( x ); + } + return x; + } + + /* Invoke division applying Newton/Raphson-Algorithm */ + z = div_w_newton( x, y ); + + if ( sign < 0 ) + { + z = L_negate( z ); + } + + return z; +} +#endif /* DIV32_OPT_NEWTON */ + Word16 BASOP_Util_Divide3232_Scale( Word32 x, Word32 y, Word16 *s ) { Word16 z; diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index a6db7dc8d..b1d4b5fc1 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -333,6 +333,13 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, /*!< i : Numerator*/ Word16 *s ); /*!< o : Additional scalefactor difference*/ +#ifdef DIV32_OPT_NEWTON +Word32 BASOP_Util_Divide3232_Scale_newton( Word32 x, /*!< i : Numerator*/ + Word32 y, /*!< i : Denominator*/ + Word16 *s ); /*!< o : Additional scalefactor difference*/ +#endif + + /************************************************************************/ /*! \brief Binary logarithm with 7 iterations diff --git a/lib_com/options.h b/lib_com/options.h index 2b88deb5d..90cd057d0 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,4 +80,6 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT +#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ + #endif -- GitLab From 75452c1c01d23b783455cd1b959ab27256e43fc8 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 6 Apr 2025 21:07:27 +0200 Subject: [PATCH 0826/1221] Force 32by32 div Newton variant --- lib_com/basop_util.c | 5 +++++ lib_com/options.h | 1 + 2 files changed, 6 insertions(+) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index ec15e9769..32f5cc55f 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1013,6 +1013,10 @@ Word32 div_w( Word32 L_num, Word32 L_den ) Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { Word32 z; +#ifdef FORCE_DIV32_OPT_NEWTON + z = BASOP_Util_Divide3232_Scale_newton( x, y, s ); + return z; +#else Word16 sx; Word16 sy; Word32 sign; @@ -1060,6 +1064,7 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) } return z; +#endif } #ifdef DIV32_OPT_NEWTON diff --git a/lib_com/options.h b/lib_com/options.h index 90cd057d0..e1e4f53a7 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,5 +81,6 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ +#define FORCE_DIV32_OPT_NEWTON /* FhG: replace BASOP_Util_Divide3232_Scale_cadence() by BASOP_Util_Divide3232_Scale_newton() */ #endif -- GitLab From b88e235579de88acb9f94840c8ec32be4d4aee86 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 7 Apr 2025 09:59:52 +0530 Subject: [PATCH 0827/1221] Scaling fix in encode gen voice, enc gen audio, core-enc, acelp_fast_fx bug fixes, fine_gain_quant bug fix --- lib_com/ivas_prot_fx.h | 7 +- lib_com/prot_fx.h | 9 +- lib_com/pvq_com_fx.c | 67 --------- lib_enc/cod4t64_fast.c | 166 +++++++++++++++++------ lib_enc/enc_gen_voic_fx.c | 77 +++++++---- lib_enc/enc_pit_exc_fx.c | 13 +- lib_enc/ext_sig_ana_fx.c | 34 ++--- lib_enc/find_tar_fx.c | 135 +++++++++++++++++- lib_enc/gs_enc_fx.c | 8 +- lib_enc/inov_enc_fx.c | 14 +- lib_enc/ivas_core_enc_fx.c | 12 -- lib_enc/ivas_corecoder_enc_reconfig_fx.c | 8 +- lib_enc/ivas_mdct_core_enc_fx.c | 9 +- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 6 +- lib_enc/ivas_tcx_core_enc_fx.c | 9 +- lib_enc/prot_fx_enc.h | 15 ++ lib_enc/pvq_core_enc_fx.c | 6 +- 17 files changed, 366 insertions(+), 229 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 1bc3c6c5b..036d546bc 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2998,11 +2998,12 @@ void acelp_fast_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 cdk_index, /* i : codebook index */ const Word16 dn_orig[L_SUBFR], - /* i : corr. between target and h[]. */ // Q_new + 1 + /* i : corr. between target and h[]. */ // Q_dn Word16 Q_dn, const Word16 cn[L_SUBFR], - /* i : residual after long term prediction */ // Q_new + 1 - const Word16 H[L_SUBFR], + /* i : residual after long term prediction */ // q_cn + const Word16 q_cn, + const Word16 H[L_SUBFR], /* i : impulse response of weighted synthesis filter */ // e(norm_s(H[0])+1) Word16 code[L_SUBFR], /* o : algebraic (fixed) codebook excitation */ Word16 y[], /* o : filtered fixed codebook excitation */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index ffd1d6032..1452d8e2e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -5077,14 +5077,7 @@ void fine_gain_quant_fx( Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains Q12 */ const Word16 *gopt /* i : Optimal gains Q12 */ ); -void fine_gain_quant_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *ord, /* i : Indices for energy order Q0 */ - const Word16 num_sfm, /* i : Number of bands Q0 */ - const Word16 *gain_bits, /* i : Gain adjustment bits per sub band Q0 */ - Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains i:Q12 / o:Q11 */ - const Word16 *gopt /* i : Optimal gains Q12 */ -); + void get_max_pulses_fx( const Word16 *band_start, /* i : Sub band start indices */ const Word16 *band_end, /* i : Sub band end indices */ diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index 9cf1226d8..a6c0bc462 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -509,73 +509,6 @@ void apply_gain_fx( * * Fine gain quantization *--------------------------------------------------------------------------*/ -void fine_gain_quant_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *ord, /* i : Indices for energy order Q0 */ - const Word16 num_sfm, /* i : Number of bands Q0 */ - const Word16 *gain_bits, /* i : Gain adjustment bits per sub band Q0 */ - Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains i:Q12 / o:Q11 */ - const Word16 *gopt /* i : Optimal gains Q12 */ -) -{ - Word16 band; - Word16 gbits; - Word16 idx; - Word16 gain_db, gain_dbq; - Word16 err; - - Word16 tmp1, tmp2, exp1, exp2; - Word32 L_tmp; - UWord16 lsb; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - FOR( band = 0; band < num_sfm; band++ ) - { - gbits = gain_bits[ord[band]]; /* Q0 */ - move16(); - test(); - IF( fg_pred[band] != 0 && gbits > 0 ) - { - exp1 = norm_s( gopt[band] ); - exp1 = sub( exp1, 1 ); - tmp1 = shl( gopt[band], exp1 ); - exp2 = norm_s( fg_pred[band] ); - tmp2 = shl( fg_pred[band], exp2 ); /* Q12 + exp2 */ - exp1 = add( 15, sub( exp1, exp2 ) ); - err = div_s( tmp1, tmp2 ); /* Q15 */ - tmp1 = norm_s( err ); - exp2 = Log2_norm_lc( L_deposit_h( shl( err, tmp1 ) ) ); - tmp1 = sub( 14, tmp1 ); - tmp1 = sub( tmp1, exp1 ); - L_tmp = L_Comp( tmp1, exp2 ); - Mpy_32_16_ss( L_tmp, 24660, &L_tmp, &lsb ); /* 24660 = 20*log10(2) in Q12 */ /*16+12-15=13 */ - gain_db = round_fx_sat( L_shl_o( L_tmp, 17, &Overflow ) ); /* Q14 */ - - idx = squant_fx( gain_db, &gain_dbq, finegain_fx[gbits - 1], gain_cb_size[gbits - 1] ); /* Q0 */ - push_indice( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); - - L_tmp = L_mult0( gain_dbq, 21771 ); /* 21771=0.05*log2(10) */ /* 14+17=31 */ - L_tmp = L_shr( L_tmp, 15 ); /* Q16 */ - tmp1 = L_Extract_lc( L_tmp, &exp1 ); - tmp1 = abs_s( tmp1 ); - tmp1 = extract_l( Pow2( 14, tmp1 ) ); - exp1 = sub( 14, exp1 ); - - L_tmp = L_mult0( fg_pred[band], tmp1 ); /*12+exp1 */ - fg_pred[band] = round_fx( L_shl( L_tmp, sub( 15, exp1 ) ) ); /*12+exp1+16-exp1-16=12 - 1-> Q11*/ - move16(); - } - ELSE - { - fg_pred[band] = shr( fg_pred[band], 1 ); // Q12 -> Q11 To align all the fg_pred indices in same Q. - } - } - - return; -} void fine_gain_quant_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 *ord, /* i : Indices for energy order Q0 */ diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index 0e4c02744..e24f3b678 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -123,10 +123,11 @@ void acelp_fast_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 cdk_index, /* i : codebook index */ const Word16 dn_orig[L_SUBFR], - /* i : corr. between target and h[]. */ // Q_new + 1 + /* i : corr. between target and h[]. */ // Q_dn Word16 Q_dn, const Word16 cn[L_SUBFR], - /* i : residual after long term prediction */ // Q_new + 1 + /* i : residual after long term prediction */ // q_cn + const Word16 q_cn, const Word16 H[L_SUBFR], /* i : impulse response of weighted synthesis filter */ // e(norm_s(H[0])+1) Word16 code[L_SUBFR], @@ -161,7 +162,9 @@ void acelp_fast_fx( Word64 s64; Word16 flag = 0; move16(); - + Word32 temp1, temp2, temp3, temp4, temp5, temp6; + Word16 q_temp1, q_temp2; + Word16 scale_temp1, scale_temp2; /*-----------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ @@ -294,16 +297,23 @@ void acelp_fast_fx( exp = sub( Q31, shl( Q_dn, 1 ) ); + s64 = 0; + move64(); + FOR( i = 0; i < L_subfr; i++ ) + { + s64 = W_mac_16_16( s64, dn_orig[i], dn_orig[i] ); // 2 * Q_dn + 1 + } dndn_fx = 21474836 /*0.01f in Q31 */; move32(); dndn_e = 0; move16(); - FOR( i = 0; i < L_subfr; i++ ) + IF( s64 ) { - dndn_fx = BASOP_Util_Add_Mant32Exp( dndn_fx, dndn_e, L_mult0( dn_orig[i], dn_orig[i] ), exp, &dndn_e ); // Q(dndn_e) + Word16 new_exp1 = W_norm( s64 ); + dndn_fx = W_extract_h( W_shl( s64, new_exp1 ) ); // 2 * Q_dyn + exp1 - 31 + dndn_e = sub( 31, sub( add( add( shl( Q_dn, 1 ), 1 ), new_exp1 ), 32 ) ); } - exp1 = sub( Q31, shl( sub( Q_dn, 1 ), 1 ) ); cncn_fx = 214748365 /* 0.1f in Q31 */; move32(); @@ -312,31 +322,42 @@ void acelp_fast_fx( FOR( q = 0; q < nb_tracks; q++ ) { + s64 = 0; + move64(); + FOR( i = 0; i < L_subfr; i += nb_tracks ) + { + s64 = W_mac_16_16( s64, cn[i + q], cn[i + q] ); // 2 * q_cn + 1 + } + cncn_track[q] = 214748365 /* 0.1f in Q31 */; move32(); cncn_track_e[q] = 0; move16(); - - FOR( i = 0; i < L_subfr; i += nb_tracks ) + IF( s64 ) { - Word32 L_tmp = L_mult0( cn[i + q], cn[i + q] ); - shift = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, shift ); - cncn_track[q] = BASOP_Util_Add_Mant32Exp( cncn_track[q], cncn_track_e[q], L_tmp, sub( exp1, shift ), &cncn_track_e[q] ); // Q(cncn_track_e[q]) - move32(); + Word16 new_exp1 = W_norm( s64 ); + cncn_track[q] = W_extract_h( W_shl( s64, new_exp1 ) ); // 2 * Q_dyn + exp1 - 31 + cncn_track_e[q] = sub( 31, sub( add( add( shl( q_cn, 1 ), 1 ), new_exp1 ), 32 ) ); } cncn_fx = BASOP_Util_Add_Mant32Exp( cncn_fx, cncn_e, cncn_track[q], cncn_track_e[q], &cncn_e ); // Q(cncn_e) } - Word16 tmp; + Word16 tmp = 0; + move16(); s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_fx, &tmp ); tmp = add( tmp, sub( dndn_e, cncn_e ) ); s_coef_fx = Sqrt16( s_coef_fx, &tmp ); // Q(15 - tmp) - + q_temp1 = add( add( sub( Q15, tmp ), q_cn ), Q1 ); + scale_temp1 = sub( q_temp1, Q_dn ); FOR( i = 0; i < L_subfr; i++ ) { - bn_orig_fx[i] = L_mac0( L_shr( L_mult( s_coef_fx, cn[i] ), sub( 15, tmp ) ), beta1_fx, dn_orig[i] ); // Q_dn + temp1 = L_mult( s_coef_fx, cn[i] ); // Q(15 - tmp)+q_cn+1 + temp2 = L_mult( beta1_fx, dn_orig[i] ); // 1+Q_dn+1 + /* bn_orig_fx[i] is being used in Q_dn */ + temp2 = L_shr( temp2, 1 ); + temp1 = L_shr( temp1, scale_temp1 ); + bn_orig_fx[i] = L_add( temp1, temp2 ); // Q_dn move32(); IF( bn_orig_fx[i] >= 0 ) @@ -576,12 +597,12 @@ void acelp_fast_fx( } ELSE { - Gn = i_mult( s[0], shr( dn_orig[m[0]], 1 ) ); // Q_dn - 1 - Gd = alp[0]; // Q6 + Gn = i_mult( s[0], dn_orig[m[0]] ); // Q_dn + Gd = alp[0]; // Q6 move16(); - G = Gn; // Q_dn - 1 + G = Gn; // Q_dn move16(); - G = i_mult( G, s[0] ); // Q_dn - 1 + G = i_mult( G, s[0] ); // Q_dn track = track_order[q * nb_tracks + 1]; // Q0 move16(); @@ -596,14 +617,17 @@ void acelp_fast_fx( move64(); FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_mult0( Gd, dn_orig[i] ), G, *alp_pos0 ), 6 ); // Q_dn + temp1 = L_mult0( Gd, dn_orig[i] ); + temp2 = L_mult0( G, *alp_pos0 ); + temp3 = L_sub( temp1, temp2 ); + dn[i] = L_shr( temp3, 6 ); move32(); alp_pos0 += nb_tracks; s64 = W_mac_32_32( s64, dn[i], dn[i] ); // 2 * Q_dn + 1 } exp1 = W_norm( s64 ); dndn_fx = W_extract_h( W_shl( s64, exp1 ) ); // 2 * Q_dyn + exp1 - 31 - dndn_e = sub( 31, sub( add( shl( Q_dn, 1 ), exp ), 31 ) ); + dndn_e = sub( 31, sub( add( add( shl( Q_dn, 1 ), 1 ), exp1 ), 32 ) ); IF( dndn_fx == 0 ) { @@ -612,17 +636,28 @@ void acelp_fast_fx( dndn_e = 0; move16(); } + exp1 = 0; + move16(); s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_track[track], &exp1 ); exp1 = add( exp1, sub( dndn_e, cncn_track_e[track] ) ); s_coef_fx = Sqrt16( s_coef_fx, &exp1 ); - exp1 = sub( exp1, shift ); max_val_fx = EPSILLON_FX; move16(); m[1] = track; // Q0 move16(); + q_temp1 = add( add( sub( Q15, exp1 ), q_cn ), 1 ); + q_temp2 = add( Q_dn, Q2 ); + scale_temp1 = sub( q_temp1, Q_dn ); + scale_temp2 = sub( q_temp2, Q_dn ); FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_add( L_shr( L_mult( s_coef_fx, cn[i] ), sub( 15, exp1 ) ), L_shr( imult3216( dn[i], beta2_fx ), 2 ) ); // Q_dn + temp1 = L_mult( s_coef_fx, cn[i] ); // Q(15 - tmp)+q_cn+1 + temp2 = imult3216( dn[i], beta2_fx ); // Q_dn + 2 + + /* bn_orig_fx[i] is being used in Q_dn */ + temp2 = L_shr( temp2, scale_temp2 ); + temp1 = L_shr( temp1, scale_temp1 ); + dn[i] = L_add( temp1, temp2 ); // Q_dn move32(); temp_fx = imult3216( dn[i], sign_fx[i] ); // Q_dn @@ -645,14 +680,14 @@ void acelp_fast_fx( IF( GE_16( nb_pulse, 3 ) ) { - Gn = add( Gn, i_mult( s[1], shr( dn_orig[m[1]], 1 ) ) ); // Q_dn -1 + Gn = add( Gn, i_mult( s[1], dn_orig[m[1]] ) ); // Q_dn Gd32 = Gd; move16(); Gd32 = L_add( Gd32, L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[1] ), alp[m[0] - m[1]] ) ) ); // Q6 - G = Gn; // Q_dn - 1 + G = Gn; // Q_dn move16(); - G1 = i_mult( G, s[1] ); // Q_dn-1 - G = i_mult( G, s[0] ); // Q_dn-1 + G1 = i_mult( G, s[1] ); // Q_dn + G = i_mult( G, s[0] ); // Q_dn track = track_order[q * nb_tracks + 2]; // Q0 move16(); @@ -661,7 +696,12 @@ void acelp_fast_fx( FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_msu0( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), 6 ); // Q_dn + temp1 = imult3216( Gd32, dn_orig[i] ); + temp2 = L_mult0( G, *alp_pos0 ); + temp3 = L_mult0( G1, *alp_pos1 ); + temp4 = L_sub( temp1, temp2 ); + temp4 = L_sub( temp4, temp3 ); + dn[i] = L_shr( temp4, 6 ); move32(); alp_pos0 += nb_tracks; alp_pos1 += nb_tracks; @@ -677,15 +717,19 @@ void acelp_fast_fx( IF( GE_16( nb_pulse, 4 ) ) { - Gn = add( Gn, i_mult( s[2], shr( dn_orig[m[2]], 1 ) ) ); // Q_dn-1 + Gn = add( Gn, i_mult( s[2], dn_orig[m[2]] ) ); // Q_dn Gd32 = Gd; move16(); - Gd32 = L_add( Gd32, L_add( L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] ) ), L_mult0( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] ) ) ); // Q6 - G = Gn; // Q_dn-1 + temp1 = alp[0]; + move32(); + temp2 = L_mult0( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] ); + temp3 = L_mult0( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] ); + Gd32 = L_add( Gd32, L_add( L_add( temp1, temp2 ), temp3 ) ); // Q6 + G = Gn; // Q_dn move16(); - G1 = i_mult( G, s[1] ); // Q_dn-1 - G2 = i_mult( G, s[2] ); // Q_dn-1 - G = i_mult( G, s[0] ); // Q_dn-1 + G1 = i_mult( G, s[1] ); // Q_dn + G2 = i_mult( G, s[2] ); // Q_dn + G = i_mult( G, s[0] ); // Q_dn track = track_order[q * nb_tracks + 3]; move16(); @@ -695,7 +739,15 @@ void acelp_fast_fx( FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_msu( L_msu( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), 6 ); // Q_dn + + temp1 = imult3216( Gd32, dn_orig[i] ); + temp2 = L_mult0( G, *alp_pos0 ); + temp3 = L_mult0( G1, *alp_pos1 ); + temp4 = L_mult0( G2, *alp_pos2 ); + temp5 = L_sub( temp1, temp2 ); + temp5 = L_sub( temp5, temp3 ); + temp5 = L_sub( temp5, temp4 ); + dn[i] = L_shr( temp5, 6 ); move32(); alp_pos0 += nb_tracks; alp_pos1 += nb_tracks; @@ -717,16 +769,22 @@ void acelp_fast_fx( IF( GE_16( nb_pulse, 5 ) ) { - Gn = add( Gn, i_mult( s[3], shr( dn_orig[m[3]], 1 ) ) ); // Q_dn-1 + Gn = add( Gn, i_mult( s[3], dn_orig[m[3]] ) ); // Q_dn Gd32 = Gd; move16(); - Gd32 = L_add( Gd32, L_add( L_add( L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] ) ), L_mult0( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] ) ), L_mult0( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] ) ) ); // Q6 + temp1 = alp[0]; + move32(); + temp2 = L_mult0( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] ); + temp3 = L_mult0( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] ); + temp4 = L_mult0( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] ); + + Gd32 = L_add( Gd32, L_add( L_add( L_add( temp1, temp2 ), temp3 ), temp4 ) ); // Q6 G = Gn; - move16(); // Q_dn-1 - G1 = i_mult( G, s[1] ); // Q_dn-1 - G2 = i_mult( G, s[2] ); // Q_dn-1 - G3 = i_mult( G, s[3] ); // Q_dn-1 - G = i_mult( G, s[0] ); // Q_dn-1 + move16(); // Q_dn + G1 = i_mult( G, s[1] ); // Q_dn + G2 = i_mult( G, s[2] ); // Q_dn + G3 = i_mult( G, s[3] ); // Q_dn + G = i_mult( G, s[0] ); // Q_dn IF( EQ_16( cdk_index, 6 ) ) { @@ -740,7 +798,16 @@ void acelp_fast_fx( FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_msu( L_msu( L_msu( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), G3, *alp_pos3 ), 6 ); // Q_dn + temp1 = imult3216( Gd32, dn_orig[i] ); + temp2 = L_mult0( G, *alp_pos0 ); + temp3 = L_mult0( G1, *alp_pos1 ); + temp4 = L_mult0( G2, *alp_pos2 ); + temp5 = L_mult0( G3, *alp_pos3 ); + temp6 = L_sub( temp1, temp2 ); + temp6 = L_sub( temp6, temp3 ); + temp6 = L_sub( temp6, temp4 ); + temp6 = L_sub( temp6, temp5 ); + dn[i] = L_shr( temp6, 6 ); move32(); alp_pos0 += nb_tracks; alp_pos1 += nb_tracks; @@ -760,7 +827,16 @@ void acelp_fast_fx( FOR( i = 0; i < L_subfr; i++ ) { - dn[i] = L_shr( L_msu( L_msu( L_msu( L_msu( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), G3, *alp_pos3 ), 6 ); /*Q_dn*/ + temp1 = imult3216( Gd32, dn_orig[i] ); + temp2 = L_mult0( G, *alp_pos0 ); + temp3 = L_mult0( G1, *alp_pos1 ); + temp4 = L_mult0( G2, *alp_pos2 ); + temp5 = L_mult0( G3, *alp_pos3 ); + temp6 = L_sub( temp1, temp2 ); + temp6 = L_sub( temp6, temp3 ); + temp6 = L_sub( temp6, temp4 ); + temp6 = L_sub( temp6, temp5 ); + dn[i] = L_shr( temp6, 6 ); move16(); alp_pos0++; alp_pos1++; diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 00c7d28d7..22af9097d 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -403,14 +403,14 @@ void encod_gen_voic_fx( void encod_gen_voic_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 speech_fx[], /* i : input speech Qnew -1 */ const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ const Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *syn_fx, /* i/o: core synthesis Q_new*/ - Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ - Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new - 1*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q_new*/ Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ Word16 *voice_factors_fx, /* o : voicing factors Q15*/ Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q0*/ @@ -550,12 +550,12 @@ void encod_gen_voic_ivas_fx( Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); /*Q_new*/ - find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, - res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); + find_targets_ivas_new_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, + res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); q_h1 = sub( 14, norm_s( h1_fx[0] ) ); Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ - + Scale_sig( h1_fx, L_SUBFR, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14*/ /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn_fx, L_SUBFR, shift ); @@ -587,7 +587,7 @@ void encod_gen_voic_ivas_fx( /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ - Scale_sig( h1_fx, L_SUBFR, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14*/ + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, st_fx->coder_type, i_subfr_fx, exc_fx, h1_fx, xn_fx, y1_fx, xn2_fx, L_SUBFR, L_frame, g_corr_fx, clip_gain_fx, &gain_pit_fx, &lp_flag ); @@ -646,7 +646,7 @@ void encod_gen_voic_ivas_fx( gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); Lgcode = L_shl_o( gain_code_fx, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx_o( Lgcode, &Overflow ); /* Q0 */ + gcode16 = round_fx_o( Lgcode, &Overflow ); hLPDmem->tilt_code = est_tilt_ivas_fx( &exc_fx[i_subfr_fx], gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, Q_new, L_SUBFR, 0 ); /* Q15 */ move16(); @@ -666,14 +666,30 @@ void encod_gen_voic_ivas_fx( * Update memory of the weighting filter *-----------------------------------------------------------------*/ + + /*At this point + xn has to be in Qnew + yn has to be in Qnew + y2_fx has to be in Q9 + gcode16 in Q_new + gain_pit_fx in Q14 + */ + Scale_sig( xn_fx, L_SUBFR, 1 ); + Scale_sig( y1_fx, L_SUBFR, 1 ); /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ - Ltmp = L_mult0( gcode16, y2_fx[L_SUBFR - 1] ); /* Q9 */ - Ltmp = L_shl( Ltmp, add( 5, shift ) ); // Q_new+14+shift + Ltmp = L_mult0( gcode16, y2_fx[L_SUBFR - 1] ); + Ltmp = L_shl( Ltmp, add( 5, shift ) ); Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn_fx[L_SUBFR - 1], 16384 /*Q14*/ ); // Q_new-1+15+shift - Ltmp = L_msu( Ltmp, y1_fx[L_SUBFR - 1], gain_pit_fx /*Q14*/ ); // Q_new-1+15+shift - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); // Q_new+15 - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ + Word32 Ltmp2 = L_mult0( xn_fx[L_SUBFR - 1], 16384 ); + Ltmp = L_add( Ltmp, Ltmp2 ); + Word32 Ltmp3 = L_mult0( y1_fx[L_SUBFR - 1], gain_pit_fx ); + Ltmp = L_sub( Ltmp, Ltmp3 ); + + /*Ltmp is in Q14 + Qnew here + We need memWo in Qnew -1 */ + + Ltmp = L_shl( Ltmp, sub( 1, shift ) ); // Q14 + Qnew + 1 + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ move16(); IF( gain_preQ_fx != 0 ) { @@ -682,20 +698,20 @@ void encod_gen_voic_ivas_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* Contribution from AVQ layer */ - Ltmp1 = L_mult_o( gain_preQ_fx, code_preQ_fx[i], &Overflow ); /* Q2 + Q6 -> Q9*/ - Ltmp1 = L_shl_o( Ltmp1, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ + Ltmp1 = L_mult_o( gain_preQ_fx, code_preQ_fx[i], &Overflow ); + Ltmp1 = L_shl_o( Ltmp1, tmp1_fx, &Overflow ); /* Compute exc2 */ - Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); /* Q0 */ - exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); /* Q0 */ + Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); + exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); move16(); /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code_fx[i] ); /* Q10 */ - Ltmp = L_shl( Ltmp, 5 ); /* Q15 */ - Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); /* Q15 */ - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16*/ - exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); /* Q0 */ + Ltmp = L_mult( gcode16, code_fx[i] ); /*Qnew + 9 + 1 */ + Ltmp = L_shl( Ltmp, 5 ); /*Qnew + 9+ 1+5 */ + Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); /*Qnew + 14 + 1*/ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /*Qnew + 14 + 1 +1 */ /* saturation can occur here Q16*/ + exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); move16(); } } @@ -708,11 +724,12 @@ void encod_gen_voic_ivas_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code_fx[i] ); /* Q10 */ - Ltmp = L_shl_o( Ltmp, 5, &Overflow ); /* Q15 */ - Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); /* Q15 */ - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16*/ - exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); /* Q0 */ + /*gcode16 in Qnew*/ + Ltmp = L_mult( gcode16, code_fx[i] ); /*Qnew + 9 + 1 */ + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); /*Qnew + 9+ 1+5 */ + Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); /*Qnew + 14 + 1*/ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /*Qnew + 14 + 1 +1 */ + exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); } } /*-----------------------------------------------------------------* @@ -729,7 +746,7 @@ void encod_gen_voic_ivas_fx( * Update A(z) filters *-----------------------------------------------------------------*/ - Syn_filt_s( 1, p_Aq_fx, M, &exc_fx[i_subfr_fx], &syn_fx[i_subfr_fx], L_SUBFR, hLPDmem->mem_syn, 1 ); + syn_filt_fx( 1, p_Aq_fx, M, &exc_fx[i_subfr_fx], &syn_fx[i_subfr_fx], L_SUBFR, hLPDmem->mem_syn, 1 ); p_Aw_fx += ( M + 1 ); p_Aq_fx += ( M + 1 ); diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 3cb2cc066..47338f743 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -549,6 +549,7 @@ void enc_pit_exc_ivas_fx( Word16 xn[PIT_EXC_L_SUBFR]; /* Target vector for pitch search */ Word16 xn2[PIT_EXC_L_SUBFR]; /* Target vector for codebook search */ Word16 h1[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 cn[PIT_EXC_L_SUBFR]; Word16 y1[PIT_EXC_L_SUBFR]; /* Filtered adaptive excitation */ Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */ Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */ @@ -561,7 +562,6 @@ void enc_pit_exc_ivas_fx( Word16 g_corr[10]; /* ACELP correlation values + gain pitch */ Word16 clip_gain, i; /* LSF clip gain and LP flag */ const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */ - Word16 cn1[PIT_EXC_L_SUBFR], *cn; /* (Used only when L_subfr == L_SUBFR) Target vector in residual domain */ Word16 *pt_pitch; /* pointer to floating pitch */ Word16 L_subfr; Word16 cum_gpit, gpit_tmp; @@ -599,7 +599,7 @@ void enc_pit_exc_ivas_fx( move16(); Pitch_CT = GENERIC; move16(); - set16_fx( cn1, 0, PIT_EXC_L_SUBFR ); + set16_fx( cn, 0, PIT_EXC_L_SUBFR ); test(); test(); IF( st_fx->GSC_IVAS_mode > 0 && ( st_fx->GSC_noisy_speech || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) @@ -709,13 +709,6 @@ void enc_pit_exc_ivas_fx( /*------------------------------------------------------------------* * ACELP subframe loop *------------------------------------------------------------------*/ - cn = NULL; - test(); - if ( EQ_16( L_subfr, L_SUBFR ) || EQ_16( L_subfr, L_SUBFR * 2 ) ) - { - cn = cn1; - move16(); - } p_Aw = Aw; p_Aq = Aq; @@ -733,7 +726,7 @@ void enc_pit_exc_ivas_fx( Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); /* Q_new */ /* condition on target (compared to float) has been put outside the loop */ - find_targets_ivas_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, + find_targets_ivas_new_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 6414a81b6..58c1f9641 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -696,6 +696,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); Word16 win_len[2]; move16(); + Word16 shift; set32_fx( buf_powerSPec, 0, N_MAX + L_MDCT_OVLP_MAX ); set16_fx( buf_powerSPec_exp, 0, N_MAX + L_MDCT_OVLP_MAX ); @@ -986,7 +987,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outter left folding */ FOR( i = 0; i < folding_offset; i++ ) { - tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win + tcx20Win[folding_offset + i] = sub( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win move16(); } @@ -1001,16 +1002,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } } @@ -1019,7 +1018,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) { - tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win + tcx20Win[L_subframe + folding_offset - 1 - i] = add( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win move16(); } @@ -1031,7 +1030,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmpP32 = hTcxEnc->spectrum_fx[frameno]; assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); Word16 len[2], exp[2]; - hTcxEnc->spectrum_e[frameno] = 16; + hTcxEnc->spectrum_e[frameno] = sub( 16, q_tcx20Win ); exp[0] = exp[1] = hTcxEnc->spectrum_e[frameno]; move16(); move16(); @@ -1078,11 +1077,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( FOR( i = 0; i < 2; i++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[frameno] + i * L_subframe, len[i], sub( exp[i], hTcxEnc->spectrum_e[frameno] ) ); + scale_sig32( hTcxEnc->spectrum_fx[frameno] + i * L_subframe, len[i], sub( exp[i], hTcxEnc->spectrum_e[frameno] ) ); } - - hTcxEnc->spectrum_e[frameno] = sub( hTcxEnc->spectrum_e[frameno], q_tcx20Win ); - move16(); } ELSE /* transform_type[frameno] != TCX_5 */ { @@ -1126,16 +1122,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + q_tcx20Win - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } } @@ -1225,12 +1219,13 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( frameno == 0 && overlap_mode[0] == FULL_OVERLAP && GT_16( sub( L_subframe, left_overlap ), minWindowLen ) ) { tmp = shr( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); + shift = sub( q_mdstWin, add( Q16, st->q_inp ) ); Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp - L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin + L_tmp = L_shl( L_tmp, shift ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } @@ -1238,7 +1233,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp - L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin + L_tmp = L_shl( L_tmp, shift ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } @@ -1313,11 +1308,12 @@ void core_signal_analysis_high_bitrate_ivas_fx( { tmp = shr( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); Word32 L_tmp; + shift = sub( q_mdstWin, add( Q16, st->q_inp ) ); FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp - L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin + L_tmp = L_shl( L_tmp, shift ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } @@ -1325,7 +1321,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp - L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin + L_tmp = L_shl( L_tmp, shift ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index 16ec45c78..ddcb3ff9b 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -3,7 +3,7 @@ ====================================================================================*/ #include #include "options.h" /* Compilation switches */ -//#include "prot_fx.h" /* Function prototypes */ +// #include "prot_fx.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "cnst.h" /* Common constants */ @@ -293,3 +293,136 @@ void find_targets_ivas_fx( return; } + +void find_targets_ivas_new_fx( + const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ + const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ + const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ + const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ + Word16 tilt_fac, /* i : tilt factor Q15*/ + Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ + Word16 *cn, /* o : target vector in residual domain Q_new*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ +) +{ + Word16 i; + Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */ + Word16 scale, scaleq, j, d, s, s2, tmp; + Word16 Aqs[M + 1]; + Word32 h1_32[6 * L_SUBFR]; + Word16 sf; + Word64 Ltmp64; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + /*------------------------------------------------------------------------* + * Find the target vector for excitation search: + * + * |------| res[n] + * speech[n]---| A(z) |-------- + * |------| | |--------| error[n] |------| + * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target + * exc |--------| |------| + * + * Instead of subtracting the zero-input response of filters from + * the weighted input speech, the above configuration is used to + * compute the target vector. + *-----------------------------------------------------------------------*/ + FOR( i = 0; i < M; i++ ) + { + temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */ + move16(); + } + + syn_filt_fx( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); + + Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new - 1 */ + + deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new - 1 */ + + + /*-----------------------------------------------------------------* + * Find target in residual domain (cn[]) for innovation search + *--------------------------------------------------------------*/ + IF( cn != NULL ) + { + /* first half: xn[] --> cn[] */ + temp[0] = 0; + move16(); + preemph_copy_fx( xn, cn, tilt_fac, L_SUBFR / 2, temp ); + syn_filt_s_lc_fx( 1, Ap, cn, temp, L_SUBFR / 2 ); /* Q-1 -> Q-2 */ + Residu3_lc_fx( p_Aq, M, temp, cn, L_SUBFR / 2, 1 ); /* Q-2 -> Q-1 */ + Scale_sig( cn, L_SUBFR / 2, 1 ); + + /* second half: res[] --> cn[] (approximated and faster) */ + Copy( &res[i_subfr + ( L_SUBFR / 2 )], cn + ( L_SUBFR / 2 ), L_SUBFR / 2 ); + } + + /*---------------------------------------------------------------* + * Compute impulse response, h1[], of weighted synthesis filter * + *---------------------------------------------------------------*/ + + scale = norm_s( Ap[0] ); + scaleq = norm_s( p_Aq[0] ); + d = sub( scaleq, scale ); + IF( d >= 0 ) + { + Copy( p_Aq, Aqs, M + 1 ); /* Q12 */ + s = add( scaleq, 1 ); + s2 = shr( 16384, d ); + } + ELSE + { + Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */ + s = add( scale, 1 ); + s2 = 16384; + move16(); + } + + set32_fx( h1_32, 0, L_subfr ); + Overflow = 0; + move16(); + FOR( i = 0; i < M; i++ ) + { + Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ + FOR( j = 1; j <= i; j++ ) + { + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ + } + h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); + } + + Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ + FOR( j = 1; j <= M; j++ ) + { + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ + } + h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); + + FOR( i = M + 1; i < L_subfr; i++ ) + { + Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_o( h1_32[i - 1], s, &Overflow ) ) ); /* Q27 */ + FOR( j = 2; j <= M; j++ ) + { + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ + } + h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); + } + + sf = sub( L_norm_arr( h1_32, L_subfr ), 1 ); + Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf + + tmp = 0; + move16(); + Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1 + + return; +} \ No newline at end of file diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 1a3d2cb56..2bfb87a2e 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -439,8 +439,8 @@ void encod_audio_ivas_fx( move16(); T0_frac_tmp = 0; move16(); - Copy( hLPDmem->mem_syn, hGSCEnc->mem_syn_tmp_fx, M ); - hGSCEnc->mem_w0_tmp_fx = hLPDmem->mem_w0; + Copy_Scale_sig( hLPDmem->mem_syn, hGSCEnc->mem_syn_tmp_fx, M, sub( sub( Q_new, 1 ), hLPDmem->q_mem_syn ) ); + Copy_Scale_sig( &hLPDmem->mem_w0, &hGSCEnc->mem_w0_tmp_fx, 1, sub( sub( Q_new, 1 ), hLPDmem->q_mem_syn ) ); move16(); Es_pred = 0; move16(); @@ -763,8 +763,8 @@ void encod_audio_ivas_fx( /*--------------------------------------------------------------------------------------* * Updates *--------------------------------------------------------------------------------------*/ - - hLPDmem->mem_w0 = hGSCEnc->mem_w0_tmp_fx; /*_DIFF_FLOAT_FIX_ The way it is written in the original fix point is that at this point mem_w0 falls back to its original value (before enc_pit_exc, seems not the case in float */ + Copy_Scale_sig(&hGSCEnc->mem_w0_tmp_fx, &hLPDmem->mem_w0, 1, sub(hLPDmem->q_mem_syn , sub(Q_new , 1))); + /*_DIFF_FLOAT_FIX_ The way it is written in the original fix point is that at this point mem_w0 falls back to its original value (before enc_pit_exc, seems not the case in float */ move16(); Copy( exc_wo_nf, exc, st_fx->L_frame ); /* Q_new */ diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index e47b14559..a1fdae804 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -420,19 +420,16 @@ Word16 inov_encode_ivas_fx( { acelpautoc = 1; move16(); - + Word16 q_h1 = sub(14, norm_s(h2[0])); + Scale_sig(h2, L_SUBFR, sub(11, q_h1)); /* set h2[] in Q11*/ cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_SUBFR ); /* h2: Q11, Rw: (Rw_e)Q */ - // Word16 Rw_e = E_ACELP_hh_corr( h2, Rw, L_SUBFR, 3 ); corr_hh_ivas_fx( h2, Rw, &Rw_q, L_subfr ); // Q(Rw) = Q11-2 - E_ACELP_conv_ivas_fx( xn2, h2, cn ); // Qcn = Qxn2 /* dn_e -> Rw_e*Q_xn */ - // Scale_sig(Rw, L_SUBFR, sub(5, Rw_e)); //Q9 j = E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); Qdn = add( add( Qxn, Rw_q ), add( j, 1 ) ); - // Scale_sig(Rw, L_subfr, -3); //Q9->Q6 } ELSE { @@ -441,7 +438,8 @@ Word16 inov_encode_ivas_fx( updt_tar_fx( cn, cn, &exc[i_subfr], gain_pit, L_subfr ); /* scaling of cn[] to limit dynamic at 12 bits */ Scale_sig( cn, L_subfr, shift ); - + Word16 q_h1 = sub(14, norm_s(h2[0])); + Scale_sig(h2, L_SUBFR, sub(11, q_h1)); /* set h2[] in Q11*/ cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); corr_xh_ivas_fx( xn2, Qxn, dn, &Qdn, h2, L_subfr ); // Q(dn) = Q_new+1 } @@ -609,7 +607,7 @@ Word16 inov_encode_ivas_fx( } ELSE { - acelp_fast_fx( hBstr, nBits, dn, Qdn, cn, h2, code, y2, L_subfr ); + acelp_fast_fx( hBstr, nBits, dn, Qdn, cn,Q_new, h2, code, y2, L_subfr ); } } ELSE IF( ( EQ_16( st_fx->idchan, 1 ) && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 7 ) ) || ( st_fx->idchan == 0 && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 3 ) ) ) @@ -620,7 +618,7 @@ Word16 inov_encode_ivas_fx( } ELSE { - acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn, h2, code, y2, L_SUBFR ); + acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn,Q_new, h2, code, y2, L_SUBFR ); } } ELSE diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 1e7a13d45..3c62a0d18 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -444,13 +444,6 @@ ivas_error ivas_core_enc_fx( st->hTcxEnc->exp_buf_speech_ltp = st->exp_buf_speech_enc; move16(); } - - Scale_sig( st->input_fx, input_frame, negate( st->q_inp ) ); // Q0 - Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); // Q0 - st->q_old_inp = 0; - move16(); - st->q_inp = 0; - move16(); } Word16 Q_spec_old[2], L_spec; Q_spec_old[0] = hCPE->hCoreCoder[0]->hTcxEnc->spectrum_long_e; @@ -623,11 +616,6 @@ ivas_error ivas_core_enc_fx( { st = sts[n]; - Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); // Q0 - Scale_sig( st->input_fx, add( input_frame, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( st->q_inp ) ); // Q0 - st->q_old_inp = st->q_inp = 0; - move16(); - move16(); IF( st->hBWE_FD != NULL ) { Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( negate( 1 ), st->Q_old_wtda ) ); // Q(-1) diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index a1f2196fb..2e09c42ed 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -221,12 +221,12 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( k = 0; k < nSCE_old; k++ ) { - shift = getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame ); + shift = sub( getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame ), Q1 ); Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp + shift */ st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp, shift ); move16(); q_com_sce = s_min( q_com_sce, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ); - shift = getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ); + shift = sub( getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ), Q1 ); Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_inp + shift */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_inp, shift ); move16(); @@ -241,12 +241,12 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - shift = getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame ); + shift = sub( getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame ), Q1 ); Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp + shift */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp, shift ); move16(); q_com_cpe = s_min( q_com_cpe, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ); - shift = getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ); + shift = sub( getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ), Q1 ); Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp + shift */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp, shift ); move16(); diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index d0a91a098..e744c7f47 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -466,13 +466,14 @@ static void kernel_switch_update_transforms_fx( { Word16 tmp = shr( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); Word32 L_tmp; + Word16 shift = sub( *q_windowedTimeSignal, add( Q16, q_speech ) ); IF( GE_32( kernelType, MDCT_II ) ) { FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_speech, Q15) -> Q16 + q_speech - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal + L_tmp = L_shl( L_tmp, shift ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -480,7 +481,7 @@ static void kernel_switch_update_transforms_fx( { L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_speech, Q15) -> Q16 + q_speech - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal + L_tmp = L_shl( L_tmp, shift ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -491,7 +492,7 @@ static void kernel_switch_update_transforms_fx( { L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_speech, Q15) -> Q16 + q_speech - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal + L_tmp = L_shl( L_tmp, shift ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -499,7 +500,7 @@ static void kernel_switch_update_transforms_fx( { L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_speech, Q15) -> Q16 + q_speech - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal + L_tmp = L_shl( L_tmp, shift ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 2e365be47..1346d634b 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -253,7 +253,7 @@ void stereo_mdct_core_enc_fx( Word16 len = extract_l( Mpy_32_32( sts[0]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); Word16 q_com = s_min( s_min( add( sts[0]->q_inp, getScaleFactor16( sts[0]->input_fx, add( len, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ), add( sts[0]->q_old_inp, getScaleFactor16( sts[0]->old_input_signal_fx, len ) ) ), s_min( add( sts[1]->q_inp, getScaleFactor16( sts[1]->input_fx, add( len, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ), add( sts[1]->q_old_inp, getScaleFactor16( sts[1]->old_input_signal_fx, len ) ) ) ); - q_com = s_min( 0, q_com ); + q_com = sub( q_com, Q1 ); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch]; @@ -275,8 +275,8 @@ void stereo_mdct_core_enc_fx( sts[ch]->hTcxEnc->tns_ms_flag[1] = 0; move16(); - Scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sub( q_com, sts[ch]->q_inp ) ); /* Q0 */ - Scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), sub( q_com, sts[ch]->q_old_inp ) ); /* Q0 */ + scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sub( q_com, sts[ch]->q_inp ) ); /* q_com */ + scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), sub( q_com, sts[ch]->q_old_inp ) ); /* q_com */ sts[ch]->q_old_inp = q_com; move16(); sts[ch]->q_inp = q_com; diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 8dbd4731c..fd84d2f21 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -205,7 +205,7 @@ void stereo_tcx_core_enc( /*HM*/ Word16 indexBuffer[2 * ( ( N_MAX / 2 ) + 1 )]; - Word16 s, input_frame; + Word16 s; CONTEXT_HM_CONFIG hm_cfg[2]; @@ -377,13 +377,6 @@ void stereo_tcx_core_enc( Q_new = 0; move16(); - input_frame = idiv1616U( extract_l( L_shr( st->input_Fs, 1 ) ), FRAMES_PER_SEC / 2 ); - Scale_sig( st->input_fx, add( input_frame, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( st->q_inp ) ); - Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); - st->q_old_inp = 0; - move16(); - st->q_inp = 0; - move16(); core_signal_analysis_high_bitrate_ivas_fx( p_new_samples, T_op, lsp_new_fx, lsp_mid_fx, st, tnsSize, tnsBits, param_core, <pBits, NULL, st->L_frame, hTcxEnc->L_frameTCX, last_element_mode, vad_hover_flag, NULL, NULL, &Q_new, NULL ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 64402bf3c..a14f134ee 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2321,6 +2321,21 @@ void find_targets_ivas_fx( Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ); +void find_targets_ivas_new_fx( + const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ + const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ + const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ + const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ + Word16 tilt_fac, /* i : tilt factor Q15*/ + Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ + Word16 *cn, /* o : target vector in residual domain Q_new*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ +); + void E_ACELP_adaptive_codebook( Word16 *exc, /* i : pointer to the excitation frame Q_new */ Word16 T0, /* i : integer pitch lag Q0 */ diff --git a/lib_enc/pvq_core_enc_fx.c b/lib_enc/pvq_core_enc_fx.c index 214522126..fc6994139 100644 --- a/lib_enc/pvq_core_enc_fx.c +++ b/lib_enc/pvq_core_enc_fx.c @@ -550,13 +550,13 @@ Word16 pvq_core_enc_ivas_fx( get_max_pulses_fx( sfm_start, sfm_end, ord, npulses, nb_sfm, pulse_vector, maxpulse ); /* Fine gain prediction */ - ivas_fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, + fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, coefs_quant, pulse_vector, fg_pred, core ); - fine_gain_quant_ivas_fx( hBstr, ord, nb_sfm, gain_bits_array, fg_pred, gopt ); + fine_gain_quant_fx( hBstr, ord, nb_sfm, gain_bits_array, fg_pred, gopt ); apply_gain_fx( ord, sfm_start, sfm_end, nb_sfm, fg_pred, coefs_quant ); - *Q_coefs = 11; + *Q_coefs = 12; move16(); return add( pvq_bits, gain_bits_tot ); } -- GitLab From f05dc3869e93813322efa50e91cfb1d16aa8b137 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 7 Apr 2025 10:04:43 +0530 Subject: [PATCH 0828/1221] Clang formatting changes --- lib_com/ivas_prot_fx.h | 4 ++-- lib_enc/enc_pit_exc_fx.c | 28 ++++++++++++++-------------- lib_enc/find_tar_fx.c | 2 +- lib_enc/gs_enc_fx.c | 2 +- lib_enc/inov_enc_fx.c | 14 +++++++------- lib_enc/prot_fx_enc.h | 24 ++++++++++++------------ lib_enc/pvq_core_enc_fx.c | 2 +- 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 036d546bc..8da9cd9ac 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3002,8 +3002,8 @@ void acelp_fast_fx( Word16 Q_dn, const Word16 cn[L_SUBFR], /* i : residual after long term prediction */ // q_cn - const Word16 q_cn, - const Word16 H[L_SUBFR], + const Word16 q_cn, + const Word16 H[L_SUBFR], /* i : impulse response of weighted synthesis filter */ // e(norm_s(H[0])+1) Word16 code[L_SUBFR], /* o : algebraic (fixed) codebook excitation */ Word16 y[], /* o : filtered fixed codebook excitation */ diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 47338f743..9180d73b8 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -550,19 +550,19 @@ void enc_pit_exc_ivas_fx( Word16 xn2[PIT_EXC_L_SUBFR]; /* Target vector for codebook search */ Word16 h1[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector */ Word16 cn[PIT_EXC_L_SUBFR]; - Word16 y1[PIT_EXC_L_SUBFR]; /* Filtered adaptive excitation */ - Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */ - Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */ - Word16 voice_fac; /* Voicing factor */ - Word32 gain_code; /* Gain of code */ - Word16 gain_inov; /* inovation gain */ - Word16 gain_pit; /* Pitch gain */ - Word16 pit_idx, i_subfr; /* tmp variables */ - Word16 T0_min, T0_max; /* pitch variables */ - Word16 g_corr[10]; /* ACELP correlation values + gain pitch */ - Word16 clip_gain, i; /* LSF clip gain and LP flag */ - const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */ - Word16 *pt_pitch; /* pointer to floating pitch */ + Word16 y1[PIT_EXC_L_SUBFR]; /* Filtered adaptive excitation */ + Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */ + Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */ + Word16 voice_fac; /* Voicing factor */ + Word32 gain_code; /* Gain of code */ + Word16 gain_inov; /* inovation gain */ + Word16 gain_pit; /* Pitch gain */ + Word16 pit_idx, i_subfr; /* tmp variables */ + Word16 T0_min, T0_max; /* pitch variables */ + Word16 g_corr[10]; /* ACELP correlation values + gain pitch */ + Word16 clip_gain, i; /* LSF clip gain and LP flag */ + const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */ + Word16 *pt_pitch; /* pointer to floating pitch */ Word16 L_subfr; Word16 cum_gpit, gpit_tmp; Word32 Local_BR, Pitch_BR; @@ -727,7 +727,7 @@ void enc_pit_exc_ivas_fx( /* condition on target (compared to float) has been put outside the loop */ find_targets_ivas_new_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, - res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); + res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2, L_subfr, sub( 11, q_h1 ) ); /*Q11*/ diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index ddcb3ff9b..4f24ec39f 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -425,4 +425,4 @@ void find_targets_ivas_new_fx( Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1 return; -} \ No newline at end of file +} diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 2bfb87a2e..77470c255 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -763,7 +763,7 @@ void encod_audio_ivas_fx( /*--------------------------------------------------------------------------------------* * Updates *--------------------------------------------------------------------------------------*/ - Copy_Scale_sig(&hGSCEnc->mem_w0_tmp_fx, &hLPDmem->mem_w0, 1, sub(hLPDmem->q_mem_syn , sub(Q_new , 1))); + Copy_Scale_sig( &hGSCEnc->mem_w0_tmp_fx, &hLPDmem->mem_w0, 1, sub( hLPDmem->q_mem_syn, sub( Q_new, 1 ) ) ); /*_DIFF_FLOAT_FIX_ The way it is written in the original fix point is that at this point mem_w0 falls back to its original value (before enc_pit_exc, seems not the case in float */ move16(); Copy( exc_wo_nf, exc, st_fx->L_frame ); /* Q_new */ diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index a1fdae804..fe22ee398 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -420,12 +420,12 @@ Word16 inov_encode_ivas_fx( { acelpautoc = 1; move16(); - Word16 q_h1 = sub(14, norm_s(h2[0])); - Scale_sig(h2, L_SUBFR, sub(11, q_h1)); /* set h2[] in Q11*/ + Word16 q_h1 = sub( 14, norm_s( h2[0] ) ); + Scale_sig( h2, L_SUBFR, sub( 11, q_h1 ) ); /* set h2[] in Q11*/ cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_SUBFR ); /* h2: Q11, Rw: (Rw_e)Q */ corr_hh_ivas_fx( h2, Rw, &Rw_q, L_subfr ); // Q(Rw) = Q11-2 - E_ACELP_conv_ivas_fx( xn2, h2, cn ); // Qcn = Qxn2 + E_ACELP_conv_ivas_fx( xn2, h2, cn ); // Qcn = Qxn2 /* dn_e -> Rw_e*Q_xn */ j = E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); @@ -438,8 +438,8 @@ Word16 inov_encode_ivas_fx( updt_tar_fx( cn, cn, &exc[i_subfr], gain_pit, L_subfr ); /* scaling of cn[] to limit dynamic at 12 bits */ Scale_sig( cn, L_subfr, shift ); - Word16 q_h1 = sub(14, norm_s(h2[0])); - Scale_sig(h2, L_SUBFR, sub(11, q_h1)); /* set h2[] in Q11*/ + Word16 q_h1 = sub( 14, norm_s( h2[0] ) ); + Scale_sig( h2, L_SUBFR, sub( 11, q_h1 ) ); /* set h2[] in Q11*/ cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); corr_xh_ivas_fx( xn2, Qxn, dn, &Qdn, h2, L_subfr ); // Q(dn) = Q_new+1 } @@ -607,7 +607,7 @@ Word16 inov_encode_ivas_fx( } ELSE { - acelp_fast_fx( hBstr, nBits, dn, Qdn, cn,Q_new, h2, code, y2, L_subfr ); + acelp_fast_fx( hBstr, nBits, dn, Qdn, cn, Q_new, h2, code, y2, L_subfr ); } } ELSE IF( ( EQ_16( st_fx->idchan, 1 ) && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 7 ) ) || ( st_fx->idchan == 0 && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 3 ) ) ) @@ -618,7 +618,7 @@ Word16 inov_encode_ivas_fx( } ELSE { - acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn,Q_new, h2, code, y2, L_SUBFR ); + acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn, Q_new, h2, code, y2, L_SUBFR ); } } ELSE diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index a14f134ee..95bcb70d2 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2322,18 +2322,18 @@ void find_targets_ivas_fx( ); void find_targets_ivas_new_fx( - const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ - const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index Q0*/ - Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ - const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ - const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ - const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15*/ - Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ - Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ + const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ + const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ + const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ + const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ + Word16 tilt_fac, /* i : tilt factor Q15*/ + Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ + Word16 *cn, /* o : target vector in residual domain Q_new*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ); void E_ACELP_adaptive_codebook( diff --git a/lib_enc/pvq_core_enc_fx.c b/lib_enc/pvq_core_enc_fx.c index fc6994139..356f2beaf 100644 --- a/lib_enc/pvq_core_enc_fx.c +++ b/lib_enc/pvq_core_enc_fx.c @@ -551,7 +551,7 @@ Word16 pvq_core_enc_ivas_fx( /* Fine gain prediction */ fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, - coefs_quant, pulse_vector, fg_pred, core ); + coefs_quant, pulse_vector, fg_pred, core ); fine_gain_quant_fx( hBstr, ord, nb_sfm, gain_bits_array, fg_pred, gopt ); -- GitLab From 44cd194eb3ae5b774cdf0eff230d8a00ea2581ff Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 4 Apr 2025 09:03:05 +0530 Subject: [PATCH 0829/1221] Precision improvements in mdct core enc --- lib_com/ivas_spar_com_fx.c | 181 ++++++++++--------------- lib_enc/ext_sig_ana_fx.c | 105 ++++++++------ lib_enc/ivas_mdct_core_enc_fx.c | 53 ++++---- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 14 +- lib_enc/prot_fx_enc.h | 3 +- lib_enc/tcx_utils_enc_fx.c | 6 +- 6 files changed, 176 insertions(+), 186 deletions(-) diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 317ea0249..0da6b90c2 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -51,24 +51,16 @@ * Local constants *------------------------------------------------------------------------------------------*/ -#define IVAS_FLT_EPS ( 1e-10F ) -#define IVAS_FIX_EPS ( 1 ) -#define IVAS_DBL_EPS ( (double) 1e-20 ) +#define IVAS_FIX_EPS ( 1 ) +#define IVAS_FIX_EPS_Q40 ( 110 ) -#define IVAS_REMIX_MULT_FAC ( 0.5f ) -#define IVAS_ACTIVEW_DM_F ( 1.0f ) #define IVAS_ACTIVEW_DM_F_Q30 ( ONE_IN_Q30 ) /*1 Q30*/ -#define IVAS_ACTIVEW_DM_F_DTX ( 0.25f ) -#define IVAS_ACTIVEW_DM_F_DTX_Q30 ( 268435456 ) /*0.25 Q30*/ -#define IVAS_ACTIVEW_DM_F_VLBR ( 0.25f ) -#define IVAS_ACTIVEW_DM_F_VLBR_Q30 ( 268435456 ) /*0.25 Q30*/ -#define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH ( 3.0f ) +#define IVAS_ACTIVEW_DM_F_DTX_Q30 ( 268435456 ) /*0.25 Q30*/ +#define IVAS_ACTIVEW_DM_F_VLBR_Q30 ( 268435456 ) /*0.25 Q30*/ #define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29 ( 1610612736 ) /*3 Q29*/ -#define IVAS_P_NORM_SCALING ( 1.0f ) #define IVAS_P_NORM_SCALING_FX ( ONE_IN_Q31 ) // 1 Q31 -#define IVAS_P_NORM_SCALING_DTX ( 0.75f ) #define IVAS_P_NORM_SCALING_DTX_FX ( 1610612736 ) // 0.75 Q31 #define IVAS_MAT_DIM_3 ( 3 ) @@ -1626,8 +1618,18 @@ static void ivas_get_Wscaling_factor_enc_fx( ivas_calc_post_pred_per_band_enc_fx( cov_real, q_cov_real, mixer_mat, q_mixer_mat, num_ch, b, postpred_cov_re, &q_postpred_cov_re ); } - Gw_sq = BASOP_Util_Divide3232_Scale( cov_real[0][0][b], L_max( postpred_cov_re[0][0], IVAS_FIX_EPS ), &tmp_exp ); // 15-(tmp_exp-(q_cov_real[0][0][b]- q_postpred_cov_re)) - q_Gw_sq = add( sub( 15, tmp_exp ), sub( q_cov_real[0][0][b], q_postpred_cov_re ) ); + tmp = L_shl_sat( IVAS_FIX_EPS_Q40, sub( q_postpred_cov_re, 40 ) ); + + IF( LE_32( postpred_cov_re[0][0], tmp ) ) + { + Gw_sq = Mpy_32_32( cov_real[0][0][b], 1250000000 ); /*1/1e-10 = 1250000000 Q(-4)*/ + q_Gw_sq = add( q_cov_real[0][0][b], -4 - 31 ); + } + ELSE + { + Gw_sq = BASOP_Util_Divide3232_Scale( cov_real[0][0][b], postpred_cov_re[0][0], &tmp_exp ); // 15-(tmp_exp-(q_cov_real[0][0][b]- q_postpred_cov_re)) + q_Gw_sq = add( sub( 15, tmp_exp ), sub( q_cov_real[0][0][b], q_postpred_cov_re ) ); + } shift = MAX16B; move16(); @@ -1992,12 +1994,15 @@ static void ivas_calc_post_pred_per_band_enc_fx( Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_postpred_cov_re*/ Word16 *q_postpred_cov_re ) { - Word16 i, j, k, guard_bits, tmp, q_temp_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], q_tmp_re, q_W_tmp; + Word16 i, j, k; Word32 dmx_mat_conj[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word32 temp_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - Word32 max_val; - Word64 tmp_re, W_tmp; - Word16 q_postpred_cov_re_per_value[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 temp_mat_e[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 q_postpred_cov_re_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 min_val; + Word32 tmp_re; + Word16 tmp_q; + Word16 tmp_e; FOR( i = 0; i < num_ch; i++ ) { @@ -2014,135 +2019,71 @@ static void ivas_calc_post_pred_per_band_enc_fx( set32_fx( postpred_cov_re[i], 0, num_ch ); } - max_val = 1; - move32(); + min_val = MAX16B; + move16(); /* num_ch x num_ch mult */ FOR( i = 0; i < num_ch; i++ ) { FOR( j = 0; j < num_ch; j++ ) { - tmp_re = 0; - move64(); - q_tmp_re = 31; + temp_mat[i][j] = 0; + move32(); + temp_mat_e[i][j] = 0; move16(); FOR( k = 0; k < num_ch; k++ ) { - W_tmp = W_shr( W_mult0_32_32( cov_real[i][k][band_idx], dmx_mat_conj[k][j] ), q_mixer_mat ); /*q_cov_real[i][k][band_idx]*/ - IF( LT_16( q_cov_real[i][k][band_idx], q_tmp_re ) ) - { - tmp_re = W_add( W_shr( tmp_re, sub( q_tmp_re, q_cov_real[i][k][band_idx] ) ), W_tmp ); /*q_cov_real[i][k][band_idx]*/ - q_tmp_re = q_cov_real[i][k][band_idx]; - move16(); - } - ELSE + tmp_re = Mpy_32_32( cov_real[i][k][band_idx], dmx_mat_conj[k][j] ); + tmp_e = sub( 62, add( q_cov_real[i][k][band_idx], q_mixer_mat ) ); + IF( tmp_re ) { - tmp_re = W_add( tmp_re, W_shr( W_tmp, sub( q_cov_real[i][k][band_idx], q_tmp_re ) ) ); /*q_tmp_re*/ + temp_mat[i][j] = BASOP_Util_Add_Mant32Exp( temp_mat[i][j], temp_mat_e[i][j], tmp_re, tmp_e, &temp_mat_e[i][j] ); + move32(); } } - IF( tmp_re == 0 ) - { - q_temp_mat[i][j] = 31; - move16(); - temp_mat[i][j] = 0; - move32(); - } - ELSE - { - q_temp_mat[i][j] = q_tmp_re; - move16(); - q_tmp_re = W_norm( tmp_re ); - temp_mat[i][j] = W_extract_h( W_shl( tmp_re, q_tmp_re ) ); /*q_temp_mat[i][j]+ q_tmp_re -32*/ - move32(); - q_temp_mat[i][j] = sub( add( q_temp_mat[i][j], q_tmp_re ), 32 ); - move16(); - } - max_val = L_max( max_val, L_abs( temp_mat[i][j] ) ); } } - guard_bits = find_guarded_bits_fx( num_ch ); - - tmp = norm_l( max_val ); - IF( LT_16( tmp, guard_bits ) ) - { - guard_bits = sub( guard_bits, tmp ); - } - ELSE - { - guard_bits = 0; - move16(); - } - - *q_postpred_cov_re = 31; - move16(); /* num_ch x num_ch mult */ FOR( i = 0; i < num_ch; i++ ) { FOR( j = i; j < num_ch; j++ ) { - tmp_re = 0; - move64(); - q_tmp_re = 31; + q_postpred_cov_re_buf[i][j] = *q_postpred_cov_re; move16(); FOR( k = 0; k < num_ch; k++ ) { - W_tmp = W_shr( W_mult0_32_32( mixer_mat[i][k][band_idx], temp_mat[k][j] ), guard_bits ); // q_temp_mat[k][j]+ q_mixer_mat-guard_bits - q_W_tmp = sub( add( q_temp_mat[k][j], q_mixer_mat ), guard_bits ); - IF( LT_16( q_W_tmp, q_tmp_re ) ) + tmp_re = Mpy_32_32( mixer_mat[i][k][band_idx], temp_mat[k][j] ); + tmp_q = sub( q_mixer_mat, temp_mat_e[k][j] ); + IF( tmp_re ) { - tmp_re = W_add( W_shr( tmp_re, sub( q_tmp_re, q_W_tmp ) ), W_tmp ); // q_W_tmp - q_tmp_re = q_W_tmp; + tmp_e = sub( 31, q_postpred_cov_re_buf[i][j] ); + postpred_cov_re[i][j] = BASOP_Util_Add_Mant32Exp( postpred_cov_re[i][j], tmp_e, tmp_re, sub( Q31, tmp_q ), &tmp_e ); + move32(); + q_postpred_cov_re_buf[i][j] = sub( 31, tmp_e ); move16(); } - ELSE - { - tmp_re = W_add( tmp_re, W_shr( W_tmp, sub( q_W_tmp, q_tmp_re ) ) ); // q_tmp_re - } } - - if ( LT_64( W_abs( tmp_re ), L_shl( IVAS_FIX_EPS, guard_bits ) ) ) + IF( postpred_cov_re[i][j] ) { - tmp_re = 0; - move64(); - } - - q_postpred_cov_re_per_value[i][j] = q_tmp_re; - move16(); - IF( tmp_re == 0 ) - { - postpred_cov_re[i][j] = W_extract_l( tmp_re ); /* q_tmp_re*/ - move32(); - } - ELSE - { - q_tmp_re = W_norm( tmp_re ); - postpred_cov_re[i][j] = W_extract_h( W_shl( tmp_re, q_tmp_re ) ); /* q_tmp_re+ q_postpred_cov_re_per_value[i][j] -32*/ - move32(); - q_postpred_cov_re_per_value[i][j] = sub( add( q_tmp_re, q_postpred_cov_re_per_value[i][j] ), 32 ); - move16(); + min_val = s_min( min_val, q_postpred_cov_re_buf[i][j] ); } - *q_postpred_cov_re = s_min( *q_postpred_cov_re, q_postpred_cov_re_per_value[i][j] ); - move16(); } } + /*Changing Q of postpred_cov_re to min_val*/ FOR( i = 0; i < num_ch; i++ ) { FOR( j = i; j < num_ch; j++ ) { - IF( postpred_cov_re[i][j] >= 0 ) - { - postpred_cov_re[i][j] = L_shr( postpred_cov_re[i][j], sub( q_postpred_cov_re_per_value[i][j], *q_postpred_cov_re ) ); //*q_postpred_cov_re - move32(); - } - ELSE + IF( postpred_cov_re[i][j] ) { - postpred_cov_re[i][j] = L_negate( L_shr( L_negate( postpred_cov_re[i][j] ), sub( q_postpred_cov_re_per_value[i][j], *q_postpred_cov_re ) ) ); //*q_postpred_cov_re + postpred_cov_re[i][j] = L_shl( postpred_cov_re[i][j], sub( min_val, q_postpred_cov_re_buf[i][j] ) ); move32(); } } } + FOR( i = 0; i < num_ch; i++ ) { FOR( j = 0; j < i; j++ ) @@ -2152,6 +2093,14 @@ static void ivas_calc_post_pred_per_band_enc_fx( } } + if ( EQ_16( min_val, MAX16B ) ) + { + min_val = Q31; + move16(); + } + *q_postpred_cov_re = min_val; + move16(); + return; } @@ -2687,7 +2636,8 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( trace = W_add( trace, W_deposit32_l( L_abs( cov_uu_re[i - num_dmx][i - num_dmx] ) ) ); // q_cov_uu_re } - factor = L_max( IVAS_FIX_EPS, postpred_cov_re[0][0] ); // q_postpred_cov_re + factor = postpred_cov_re[0][0]; // q_postpred_cov_re + move32(); q_factor = q_postpred_cov_re; move16(); IF( trace != 0 ) @@ -2708,10 +2658,20 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( factor = L_max( factor, tmp ); // q_factor } + tmp = L_shl_sat( IVAS_FIX_EPS_Q40, sub( q_factor, 40 ) ); + Word16 factor_exp = 0; move16(); - factor = BASOP_Util_Divide3232_Scale( 1, factor, &factor_exp ); // q=15-(factor_exp+31-(31-q_factor)) - factor_exp = add( factor_exp, q_factor ); + IF( LE_32( factor, tmp ) ) + { + factor = 1250000000; + factor_exp = Q31 - ( -4 ); + } + ELSE + { + factor = BASOP_Util_Divide3232_Scale( 1, factor, &factor_exp ); // q=15-(factor_exp+31-(31-q_factor)) + factor_exp = add( factor_exp, q_factor ); + } /* normalise Hermitian (except for rounding) cov_uu */ FOR( i = num_dmx; i < num_ch; i++ ) @@ -3311,6 +3271,9 @@ void ivas_calc_c_p_coeffs_enc_fx( Word16 i, j, q_postpred_cov_re; Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + q_postpred_cov_re = 0; + move16(); + FOR( i = 0; i < IVAS_SPAR_MAX_CH; i++ ) { set_zero_fx( postpred_cov_re[i], IVAS_SPAR_MAX_CH ); diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 087d892e3..6414a81b6 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -675,6 +675,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word16 alw_voicing[2], alw_voicing_wc = -1; Word16 disable_ltp = 0; Word16 tmp, *tmpP16; + Word16 q_mdstWin = st->q_inp, q_tcx20Win = st->q_inp; Word32 *tmpP32; Word16 Q_exp; Word32 L_tmpbuf[N_MAX + L_MDCT_OVLP_MAX]; @@ -684,12 +685,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); move16(); move16(); + move16(); + move16(); (void) vad_hover_flag; Word16 Q_win_temp[2]; Word16 *speech_ltp_fx = NULL; Word16 *wspeech_fx = NULL; Word16 *speech_fx = NULL; - Word16 q_out_wtda = 0; + Word16 q_out_wtda = st->q_inp; move16(); Word16 win_len[2]; move16(); @@ -961,7 +964,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( move32(); windowed_samples[frameno * L_FRAME_MAX + 1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0 move32(); - Copy_Scale_sig_16_32_DEPREC( tcx20Win, windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), 0 ); + Copy_Scale_sig_16_32_DEPREC( tcx20Win, windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), negate( q_tcx20Win ) ); *q_win = s_min( *q_win, sub( L_norm_arr( windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ) ), 1 ) ); move16(); Q_win_temp[frameno] = *q_win; @@ -983,7 +986,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outter left folding */ FOR( i = 0; i < folding_offset; i++ ) { - tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // Q0 + tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win move16(); } @@ -996,18 +999,18 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } } @@ -1016,7 +1019,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) { - tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // Q0 + tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win move16(); } @@ -1027,6 +1030,12 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmpP16 = tcx20Win; tmpP32 = hTcxEnc->spectrum_fx[frameno]; assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); + Word16 len[2], exp[2]; + hTcxEnc->spectrum_e[frameno] = 16; + exp[0] = exp[1] = hTcxEnc->spectrum_e[frameno]; + move16(); + move16(); + move16(); FOR( i = 0; i < 2; i++ ) { test(); @@ -1037,17 +1046,17 @@ void core_signal_analysis_high_bitrate_ivas_fx( mac_r( 2 << 16, -( 3 << 8 ), shl( i, 7 ) ), /* equivalent to: sub(i, 1) == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP */ &left_overlap, &right_overlap, tmpP16, &L_subframe, tcx5Win, st->element_mode != IVAS_CPE_MDCT, 1 ); - hTcxEnc->spectrum_e[frameno] = 16; - move16(); TCX_MDCT( tcx5Win, tmpP32, - &hTcxEnc->spectrum_e[frameno], + &exp[i], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); tmpP16 += tcx5SizeFB; tmpP32 += tcx5SizeFB; + len[i] = L_subframe; + move16(); /* high-band gain control in case of BWS */ IF( st->bwidth_sw_cnt > 0 ) @@ -1064,6 +1073,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_subframe - L_FRAME16k / ( 2 * nSubframes ) ); } } + hTcxEnc->spectrum_e[frameno] = s_max( exp[0], exp[1] ); + move16(); + + FOR( i = 0; i < 2; i++ ) + { + Scale_sig32( hTcxEnc->spectrum_fx[frameno] + i * L_subframe, len[i], sub( exp[i], hTcxEnc->spectrum_e[frameno] ) ); + } + + hTcxEnc->spectrum_e[frameno] = sub( hTcxEnc->spectrum_e[frameno], q_tcx20Win ); + move16(); } ELSE /* transform_type[frameno] != TCX_5 */ { @@ -1105,23 +1124,25 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win + L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // q_tcx20Win move32(); } } TCX_MDCT( tcx20Win, hTcxEnc->spectrum_fx[frameno], &hTcxEnc->spectrum_e[frameno], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); + hTcxEnc->spectrum_e[frameno] = sub( hTcxEnc->spectrum_e[frameno], q_tcx20Win ); + move16(); } /* high-band gain control in case of BWS */ @@ -1147,23 +1168,27 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) && ( ( LT_32( st->total_brate, HQ_96k ) ) || st->igf ) ) { pMdstWin = tcx20Win; + Word16 q_pmdstWin = q_tcx20Win; + move16(); test(); if ( ( ( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) ) { pMdstWin = mdstWin; + q_pmdstWin = q_mdstWin; + move16(); } /* Compute noise-measure flags for spectrum filling and quantization */ AnalyzePowerSpectrum_ivas_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ), L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno], - pMdstWin, powerSpec, powerSpec_e ); + pMdstWin, q_pmdstWin, powerSpec, powerSpec_e ); } } } IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Word16 q_mdstWin, scale; + Word16 scale; L_subframe = idiv1616( L_frameTCX, nSubframes ); /* Q0 */ test(); @@ -1173,8 +1198,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( scale = sub( norm_arr( mdstWin, L_frameTCX ), 1 ); scale = s_min( 1, scale ); // restricting the Q to zero or less scale_sig( mdstWin, L_frameTCX, scale ); - q_mdstWin = add( -1, scale ); - move16(); + q_mdstWin = add( add( st->q_inp, -1 ), scale ); } ELSE { @@ -1185,8 +1209,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( scale = sub( norm_arr( mdstWin, sig_len ), 1 ); scale = s_min( 0, scale ); // restricting the Q to zero or less scale_sig( mdstWin, sig_len, scale ); - q_mdstWin = scale; - move16(); + q_mdstWin = add( scale, st->q_inp ); } IF( EQ_16( transform_type[frameno], TCX_5 ) ) @@ -1205,17 +1228,17 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } @@ -1292,17 +1315,17 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word32 L_tmp; FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp + L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp + L_tmp = L_shl( L_tmp, sub( q_mdstWin, add( Q16, st->q_inp ) ) ); // q_mdstWin mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index 7c3daebda..d0a91a098 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -370,15 +370,16 @@ static void kernel_switch_trafo_fx( static void kernel_switch_update_transforms_fx( - Word32 *sigR, /* i/o: MDCT samples of the given channel (*q_sig) */ - Word32 *sigI, /* i/o: MDST samples of the given channel (*q_sig) */ - Word16 *q_sig, /* i/o: Common Q of MDCT and MDST samples of the given channel */ - const Word16 tcxTransType, /* i : TCX transform type, cf also above */ - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration handle, pointer */ - const Word16 bwidthSwCnt, /* i : bandwidth switching counter in st */ - const UWord16 kernelType, /* i : TCX transform kernel type (0 - 3) */ - Word16 *tcxTimeSignal, /* i : hTcxEnc->new_speech_TCX buf in st */ - const Word16 *speech_TCX, /* i : hTcxEnc->speech_TCX buffer in st */ + Word32 *sigR, /* i/o: MDCT samples of the given channel (*q_sig) */ + Word32 *sigI, /* i/o: MDST samples of the given channel (*q_sig) */ + Word16 *q_sig, /* i/o: Common Q of MDCT and MDST samples of the given channel */ + const Word16 tcxTransType, /* i : TCX transform type, cf also above */ + TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration handle, pointer */ + const Word16 bwidthSwCnt, /* i : bandwidth switching counter in st */ + const UWord16 kernelType, /* i : TCX transform kernel type (0 - 3) */ + Word16 *tcxTimeSignal, /* i : hTcxEnc->new_speech_TCX buf in st */ + const Word16 *speech_TCX, /* i : hTcxEnc->speech_TCX buffer in st */ + const Word16 q_speech, Word32 *windowedTimeSignal, /* i/o: windowed input and scratch buffer (*q_windowedTimeSignal) */ Word16 *q_windowedTimeSignal, /* i/o: Q of windowed input and scratch buffer */ const Word16 L_subframe /* i : transform length (number of bins) */ @@ -429,9 +430,9 @@ static void kernel_switch_update_transforms_fx( Word32 factor; n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), -Q1 ); // Q0 -> Q-1 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), sub( -Q1, q_speech ) ); // q_speech -> Q-1 wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 - Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 + Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), sub( q_speech, -Q1 ) ); // Q-1 -> q_speech Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); @@ -469,17 +470,17 @@ static void kernel_switch_update_transforms_fx( { FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -488,17 +489,17 @@ static void kernel_switch_update_transforms_fx( { FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { - L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 - L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (q_speech, Q15) -> Q16 + q_speech + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_speech, Q15) -> Q16 + q_speech + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, add( Q16, q_speech ) ) ); // *q_windowedTimeSignal windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal move32(); } @@ -1486,7 +1487,7 @@ void ivas_mdct_core_whitening_enc_fx( speech = hTcxEnc0->speech_TCX; } kernel_switch_update_transforms_fx( hTcxEnc0->spectrum_fx[n], mdst_spectrum_fx[0][n], &q_com, hTcxEnc0->transform_type[n], sts[0]->hTcxCfg, sts[0]->bwidth_sw_cnt, hTcxEnc0->kernel_type[n], - hTcxEnc0->new_speech_TCX, speech, windowedSignal_fx[0] + i_mult( n, L_FRAME48k ), &q_windowedSignal[0], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); + hTcxEnc0->new_speech_TCX, speech, sts[0]->q_inp, windowedSignal_fx[0] + i_mult( n, L_FRAME48k ), &q_windowedSignal[0], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); mdst_spectrum_e[0][n] = sub( Q31, q_com ); hTcxEnc0->spectrum_e[n] = sub( Q31, q_com ); move16(); @@ -1507,7 +1508,7 @@ void ivas_mdct_core_whitening_enc_fx( speech = hTcxEnc1->speech_TCX; } kernel_switch_update_transforms_fx( hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[1][n], &q_com, hTcxEnc1->transform_type[n], sts[1]->hTcxCfg, sts[1]->bwidth_sw_cnt, hTcxEnc1->kernel_type[n], - hTcxEnc1->new_speech_TCX, speech, windowedSignal_fx[1] + i_mult( n, L_FRAME48k ), &q_windowedSignal[1], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); + hTcxEnc1->new_speech_TCX, speech, sts[1]->q_inp, windowedSignal_fx[1] + i_mult( n, L_FRAME48k ), &q_windowedSignal[1], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); mdst_spectrum_e[1][n] = sub( Q31, q_com ); hTcxEnc1->spectrum_e[n] = sub( Q31, q_com ); move16(); @@ -1741,7 +1742,7 @@ void ivas_mdct_core_whitening_enc_fx( speech = NULL; } kernel_switch_update_transforms_fx( hTcxEncCh->spectrum_fx[n], mdst_spectrum_fx[ch][n], &q_com, hTcxEncCh->transform_type[n], sts[ch]->hTcxCfg, sts[ch]->bwidth_sw_cnt, hTcxEncCh->kernel_type[n], - hTcxEncCh->new_speech_TCX, speech, windowedSignal_fx[ch] + i_mult( n, L_FRAME48k ), &q_windowedSignal[ch], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); + hTcxEncCh->new_speech_TCX, speech, sts[ch]->q_inp, windowedSignal_fx[ch] + i_mult( n, L_FRAME48k ), &q_windowedSignal[ch], shr( L_subframeTCX, shift ) /*L_subframeTCX / nSubframes*/ ); mdst_spectrum_e[ch][n] = sub( Q31, q_com ); move16(); hTcxEncCh->spectrum_e[n] = sub( Q31, q_com ); diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index b32e8a561..2e365be47 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -250,7 +250,10 @@ void stereo_mdct_core_enc_fx( hCPE->hStereoMdct->stbParamsTCX20.nBandsStereoCore = hCPE->hStereoMdct->stbParamsTCX20.sfbCnt; move16(); } - + Word16 len = extract_l( Mpy_32_32( sts[0]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + Word16 q_com = s_min( s_min( add( sts[0]->q_inp, getScaleFactor16( sts[0]->input_fx, add( len, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ), add( sts[0]->q_old_inp, getScaleFactor16( sts[0]->old_input_signal_fx, len ) ) ), + s_min( add( sts[1]->q_inp, getScaleFactor16( sts[1]->input_fx, add( len, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ), add( sts[1]->q_old_inp, getScaleFactor16( sts[1]->old_input_signal_fx, len ) ) ) ); + q_com = s_min( 0, q_com ); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch]; @@ -272,11 +275,11 @@ void stereo_mdct_core_enc_fx( sts[ch]->hTcxEnc->tns_ms_flag[1] = 0; move16(); - Scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( sts[ch]->q_inp ) ); /* Q0 */ - Scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), negate( sts[ch]->q_old_inp ) ); /* Q0 */ - sts[ch]->q_old_inp = 0; + Scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sub( q_com, sts[ch]->q_inp ) ); /* Q0 */ + Scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), sub( q_com, sts[ch]->q_old_inp ) ); /* Q0 */ + sts[ch]->q_old_inp = q_com; move16(); - sts[ch]->q_inp = 0; + sts[ch]->q_inp = q_com; move16(); } @@ -765,7 +768,6 @@ void stereo_mdct_core_enc_fx( * Split available bits between channels *---------------------------------------------------------------*/ - Word16 q_com; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { Word16 n_sb = NB_DIV; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index e54d3025e..64402bf3c 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1278,7 +1278,8 @@ void AnalyzePowerSpectrum_ivas_fx( Word32 const mdctSpectrum[], /* i : MDCT spectrum */ Word16 mdctSpectrum_e, Word16 const signal[], /* i : windowed signal corresponding to mdctSpectrum */ - Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ + const Word16 q_signal, + Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ Word16 powerSpec_e[] ); void AdaptLowFreqEmph_fx( Word32 x[], diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 5bea901bb..ad1720665 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -330,7 +330,8 @@ void AnalyzePowerSpectrum_ivas_fx( Word32 const mdctSpectrum[], /* input: MDCT spectrum */ Word16 mdctSpectrum_e, Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */ - Word32 powerSpec[], /* output: Power spectrum. Can point to signal */ + const Word16 q_signal, + Word32 powerSpec[], /* output: Power spectrum. Can point to signal */ Word16 powerSpec_e[] ) { Word16 i, iStart, iEnd, lowpassLine; @@ -342,8 +343,7 @@ void AnalyzePowerSpectrum_ivas_fx( lowpassLine = L_frameTCX; move16(); - Word16 temp_powerSpec_e = 16; - move16(); + Word16 temp_powerSpec_e = sub( 16, q_signal ); TCX_MDST( signal, powerSpec, &temp_powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); shift = L_norm_arr( powerSpec, N_MAX + L_MDCT_OVLP_MAX ); -- GitLab From 40dd464d457399bc0bfe0aa9f3f448dc253fe782 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 12 Mar 2025 10:45:04 +0100 Subject: [PATCH 0830/1221] Fix issue 1378 (invalid read access) --- diff | 1068 ++++++++++++++++++++++++++++++++++++++++ lib_com/options.h | 3 + lib_dec/dec_acelp_fx.c | 12 + 3 files changed, 1083 insertions(+) create mode 100644 diff diff --git a/diff b/diff new file mode 100644 index 000000000..e782cdaf8 --- /dev/null +++ b/diff @@ -0,0 +1,1068 @@ +diff --git a/Makefile b/Makefile +index 9d18cbde..8087038a 100644 +--- a/Makefile ++++ b/Makefile +@@ -26,10 +26,17 @@ LIB_LIBREND ?= libivasrend.a + LIB_LIBUTIL ?= libivasutil.a + + # Default tool settings +-CC ?= gcc ++#CC ?= gcc ++CC ?= clang + RM ?= rm -f + AR ?= ar + ++#CFLAGS += -fsanitize=address,undefined,integer,nullability ++#LDFLAGS += -fsanitize=address,undefined,integer,nullability ++#CFLAGS += -fsanitize=address,undefined,nullability ++#LDFLAGS += -fsanitize=address,undefined,nullability ++ ++ + # Detect system + UNAME_S := $(shell uname -s) + +diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c +index 48c00ed9..12bfee13 100644 +--- a/lib_dec/ivas_dirac_dec_fx.c ++++ b/lib_dec/ivas_dirac_dec_fx.c +@@ -3678,6 +3678,7 @@ void ivas_dirac_dec_render_sf_fx( + exp = L_norm_arr( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + scale_sig32( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // q_reference_power_smooth[0] + exp + q_reference_power_smooth[0] = add( q_reference_power_smooth[0], exp ); ++#if 0 + IF( LT_16( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // q_reference_power_smooth[0] +@@ -3696,10 +3697,11 @@ void ivas_dirac_dec_render_sf_fx( + q_reference_power_smooth[0] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0]; + move16(); + } +- ++#endif + exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), exp ); // q_reference_power_smooth + exp + q_reference_power_smooth[1] = add( q_reference_power_smooth[1], exp ); ++#if 0 + IF( LT_16( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // q_reference_power_smooth +@@ -3718,6 +3720,7 @@ void ivas_dirac_dec_render_sf_fx( + q_reference_power_smooth[1] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1]; + move16(); + } ++#endif + #else + exp = L_norm_arr( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands ); + scale_sig32( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, exp ); // q_reference_power_smooth + exp +@@ -3782,6 +3785,7 @@ void ivas_dirac_dec_render_sf_fx( + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); + move16(); ++#if 0 + IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) + { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) +@@ -3800,6 +3804,7 @@ void ivas_dirac_dec_render_sf_fx( + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; + move16(); + } ++#endif + exp = 31; + move16(); + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) +@@ -3812,6 +3817,7 @@ void ivas_dirac_dec_render_sf_fx( + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); + move16(); ++#if 0 + IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ) + { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) +@@ -3830,6 +3836,7 @@ void ivas_dirac_dec_render_sf_fx( + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; + move16(); + } ++#endif + #else + exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) +diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +index 77826b96..1cc6cd4d 100644 +--- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c ++++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +@@ -2173,13 +2173,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( + reference_power_smooth[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth + prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ), + h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth +- +-#ifdef FIX_867_CLDFB_NRG_SCALE +- assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] ); +- assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] ); +-#else ++#ifndef FIX_867_CLDFB_NRG_SCALE + assert( *q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q ); +-#endif + weightedDirectionSmoothness = + L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), + Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth +@@ -2187,6 +2182,23 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( + + exp = 0; + move16(); ++#else ++ Word16 s1, s2, qidx; ++ qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); ++ ++ s1 = s_max( 0, sub( q_reference_power_smooth[qidx], h_dirac_output_synthesis_state->reference_power_smooth_prev_q[qidx] ) ); ++ s2 = s_max( 0, sub( h_dirac_output_synthesis_state->reference_power_smooth_prev_q[qidx], q_reference_power_smooth[qidx] ) ); ++ currWeight = L_shr( currWeight, s1 ); ++ prevWeight = L_shr( prevWeight, s2 ); ++ weightedDirectionSmoothness = ++ L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), ++ Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth ++ sumWeight = L_add( currWeight, prevWeight ); // q_reference_power_smooth ++ ++ exp = s_min( q_reference_power_smooth[qidx], h_dirac_output_synthesis_state->reference_power_smooth_prev_q[qidx] ); ++ move16(); ++#endif ++ + #if 1 + tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ + smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 +@@ -2222,6 +2234,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( + p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; + set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) ); + ++#ifndef FIX_867_CLDFB_NRG_SCALE + FOR( k = 0; k < num_protos_dir; k++ ) + { + FOR( l = 0; l < num_freq_bands; l++ ) +@@ -2234,27 +2247,76 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( + *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth + move32(); + ++ assert(h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q); ++ + IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) + { + p_power_smooth_prev++; +- L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ ++ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ + exp_arr[k * num_freq_bands + l] = exp; + move16(); + +- *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/ ++ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ + move32(); + } + ELSE + { +- L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ ++ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ + exp_arr[k * num_freq_bands + l] = exp; + move16(); + +- *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/ ++ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ + move32(); + } + } + } ++#else ++ Word16 shift_prev0, shift_curr0, shift_prev1, shift_curr1; ++ shift_prev0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0], h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); ++ shift_curr0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); ++ shift_prev1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1], h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); ++ shift_curr1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); ++ ++ FOR( k = 0; k < num_protos_dir; k++ ) ++ { ++ FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) ++ { ++ g1 = alpha[l]; // Q31 ++ move32(); ++ g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 ++ *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev0 ) ) ); //(Q31, proto_power_smooth_q) -> proto_power_smooth_q ++ move32(); ++ *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), ++ L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr0 ) ); //(Q31, proto_power_smooth_q) -> min(proto_power_smooth_q, proto_power_smooth_prev_q) ++ move32(); ++ ++ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ ++ exp_arr[k * num_freq_bands + l] = exp; ++ move16(); ++ ++ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ ++ move32(); ++ } ++ FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) ++ { ++ g1 = alpha[l]; // Q31 ++ move32(); ++ g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 ++ *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev1 ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth ++ move32(); ++ *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), ++ L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr1 ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth ++ move32(); ++ ++ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ ++ exp_arr[k * num_freq_bands + l] = exp; ++ move16(); ++ ++ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ ++ move32(); ++ } ++ } ++#endif + + // Move proto_power_smooth_fx to common Q-factor + +@@ -2297,14 +2359,23 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( + p_power_smooth++; + } + } ++ ++ // Update the Q-factor ++#if 0 + q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); + q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); + +- // Update the Q-factor + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = h_dirac_output_synthesis_state->proto_power_smooth_q[0]; + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = h_dirac_output_synthesis_state->proto_power_smooth_q[1]; +- move16(); +- move16(); ++ move16(); move16(); ++#else ++ h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ); ++ h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ); ++ move16(); move16(); ++ ++ q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); ++ q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); ++#endif + h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp; + h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2; + move16(); +diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c +index 18c9269d..d1071b39 100644 +--- a/lib_rend/ivas_dirac_rend_fx.c ++++ b/lib_rend/ivas_dirac_rend_fx.c +@@ -1774,15 +1774,32 @@ void protoSignalComputation2_fx( + Word32 a_fx, b_fx, a2_fx, b2_fx; + Word16 interpolatorSpaced_fx, interpolatorDmx_fx; + Word32 tempSpaced_fx, tempDmx_fx; ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 q_shift, min_q_shift[2], exp, q_temp[2], temp_q_shift, q_temp2; ++#else + Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; ++#endif + Word32 temp; + Word64 W_tmp1, W_tmp2; + Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; + Word16 q_reference_power_64fx; ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 head_room, q_Left_Right_power[2]; ++#else + Word16 head_room, q_Left_Right_power; ++#endif ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ const Word16 num_proto = 3; ++#endif + /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ min_q_shift[0] = Q31; ++ min_q_shift[1] = Q31; ++ move16(); move16(); ++#else + min_q_shift = Q31; + move16(); ++#endif + temp_q_shift = Q31; + move16(); + q_sum_total_ratio = Q31; +@@ -1797,18 +1814,35 @@ void protoSignalComputation2_fx( + /* Calculate the max shift possible for the buffers RealBuffer_fx and ImagBuffer_fx */ + FOR( l = 0; l < 2; l++ ) + { ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ) ); ++ min_q_shift[0] = s_min( min_q_shift[0], q_shift ); ++ q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), L_norm_arr( ImagBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); ++ min_q_shift[1] = s_min( min_q_shift[1], q_shift ); ++#else + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], num_freq_bands ), L_norm_arr( ImagBuffer_fx[l][0], num_freq_bands ) ); + min_q_shift = s_min( min_q_shift, q_shift ); ++#endif + + #ifdef MSAN_FIX + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ); + #else + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ), L_norm_arr( ImagBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ) ); + #endif // MSAN_FIX ++#ifdef FIX_867_CLDFB_NRG_SCALE ++#if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) ++#error MASA_SUM_FREQ_RANGE_BINS if greater than CLDFB_NO_CHANNELS_HALF, this does not work ++#endif ++#endif + temp_q_shift = s_min( temp_q_shift, q_shift ); + } + ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits ++ min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits ++#else + min_q_shift = sub( min_q_shift, 2 ); // guard bits ++#endif + temp_q_shift = sub( temp_q_shift, 2 ); // guard bits + + /* Upscaling of the buffer proto_power_smooth_fx */ +@@ -1868,16 +1902,29 @@ void protoSignalComputation2_fx( + { + p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f + ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); ++ q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); ++ move16(); ++#else + q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + move16(); +- ++#endif + FOR( l = 0; l < num_freq_bands; l++ ) + { ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); ++ ++ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++#else + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +- ++#endif + Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift + Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift + +@@ -1894,14 +1941,13 @@ void protoSignalComputation2_fx( + temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 + + #ifdef FIX_867_CLDFB_NRG_SCALE +- Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -1910,7 +1956,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -1925,13 +1971,13 @@ void protoSignalComputation2_fx( + temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 + + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -1940,7 +1986,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -1954,13 +2000,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -1969,7 +2015,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2042,20 +2088,29 @@ void protoSignalComputation2_fx( + interpolatorSpaced_fx = sub( MAX16B, interpolatorDmx_fx ); /* Q15 */ + } + } +- ++#ifndef FIX_867_CLDFB_NRG_SCALE + min_q_shift = sub( min_q_shift, idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); + + q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); ++#endif + q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); +- + head_room = 63; + move16(); + FOR( l = 0; l < num_freq_bands; l++ ) + { ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); ++ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++#else ++ + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift ++#endif + + W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); + W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); +@@ -2063,15 +2118,28 @@ void protoSignalComputation2_fx( + head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); + } + head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); ++ ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ q_Left_Right_power[0] = add( shl( add( q_cldfb, min_q_shift[0] ), 1 ), sub( head_room, 32 ) ); ++ q_Left_Right_power[1] = add( shl( add( q_cldfb, min_q_shift[1] ), 1 ), sub( head_room, 32 ) ); ++#else + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); ++#endif + + FOR( l = 0; l < num_freq_bands; l++ ) + { ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); ++ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift ++#else + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +- ++#endif + /* Compute sum signal */ + Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift + Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift +@@ -2091,6 +2159,7 @@ void protoSignalComputation2_fx( + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power + // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); ++ assert(0 /* Fix 2 scale regions for total_bb_power_fx, left_hi_power_fx, right_hi_power_fx and total_hi_power_fx */ ); + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power + + IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) +@@ -2103,9 +2172,14 @@ void protoSignalComputation2_fx( + + IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) + { ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ assert( qidx == 0 ); ++ re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[qidx] ) ); // q_cldfb+temp_q_shift ++ im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[qidx] ) ); // q_cldfb+temp_q_shift ++#else + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift + im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift +- ++#endif + sum_power_fx = Madd_32_32( Mpy_32_32( re_aux, re_aux ), im_aux, im_aux ); // 2*(q_cldfb+temp_q_shift)-31 + temp = Mpy_32_32( a_fx, sum_power_fx ); // 2*(q_cldfb+temp_q_shift)-31 + +@@ -2121,6 +2195,18 @@ void protoSignalComputation2_fx( + } + + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ IF( LT_16( q_temp[qidx], stereo_type_detect->q_total_power ) ) ++ { ++ stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); // q_temp ++ move32(); ++ } ++ ELSE ++ { ++ stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power ++ move32(); ++ } ++#else + IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) + { + stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp +@@ -2131,7 +2217,7 @@ void protoSignalComputation2_fx( + stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power + move32(); + } +- ++#endif + test(); + IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) + { +@@ -2147,7 +2233,11 @@ void protoSignalComputation2_fx( + { + sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) + move32(); ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); ++#else + q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); ++#endif + sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 + move32(); + } +@@ -2159,6 +2249,22 @@ void protoSignalComputation2_fx( + ImagSubtract_fx = L_sub( im1, im2 ); // q_cldfb+min_q_shift + + temp = Madd_32_32( Mpy_32_32( RealSubtract_fx, RealSubtract_fx ), ImagSubtract_fx, ImagSubtract_fx ); // 2*(q_cldfb+min_q_shift)-31 ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ assert( qidx == 0 ); ++ IF( LT_16( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) ++ { ++ stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp[qidx] ) ), temp ); // q_temp ++ move32(); ++ stereo_type_detect->q_subtract_power_y = q_temp[qidx]; ++ move16(); ++ } ++ ELSE ++ { ++ stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y ++ move32(); ++ } ++ ++#else + IF( LT_16( q_temp, stereo_type_detect->q_subtract_power_y ) ) + { + stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp ) ), temp ); // q_temp +@@ -2171,12 +2277,10 @@ void protoSignalComputation2_fx( + stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp, stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y + move32(); + } ++#endif + } + + /* Compute protos (and their power) for direct sound rendering */ +-#ifdef FIX_867_CLDFB_NRG_SCALE +- Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); +-#endif + + /* W prototype */ + IF( stereo_type_detect->interpolator > 0 ) +@@ -2188,13 +2292,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift) -31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2203,7 +2307,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2222,13 +2326,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_16( Mpy_32_16_1( tempSpaced_fx, interpolatorSpaced_fx ), tempDmx_fx, interpolatorDmx_fx ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2237,7 +2341,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2258,13 +2362,13 @@ void protoSignalComputation2_fx( + Imag_aux_fx = L_shr( Imag_aux_fx, 1 ); // q_cldfb+min_q_shift + temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2273,7 +2377,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2289,13 +2393,13 @@ void protoSignalComputation2_fx( + { + temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2304,7 +2408,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2321,13 +2425,13 @@ void protoSignalComputation2_fx( + { + temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2336,7 +2440,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2376,13 +2480,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2391,7 +2495,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2418,13 +2522,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2433,7 +2537,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2459,13 +2563,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2474,7 +2578,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2499,8 +2603,12 @@ void protoSignalComputation2_fx( + + stereo_type_detect->q_sum_power = s_min( stereo_type_detect->q_sum_power, q_temp2 ); + move16(); ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ assert(0); ++#else + stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp ); + move16(); ++#endif + q_sum_total_ratio = Q15; + move16(); + +@@ -2517,6 +2625,22 @@ void protoSignalComputation2_fx( + } + + temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); ++ assert( 0 /* qidx has no valid value ? */ ); ++ IF( LT_16( q_Left_Right_power[qidx], stereo_type_detect->q_left_bb_power ) ) ++ { ++ stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power[qidx] ) ) ); // q_Left_Right_power ++ move32(); ++ stereo_type_detect->q_left_bb_power = q_Left_Right_power[qidx]; ++ move16(); ++ } ++ ELSE ++ { ++ stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power[qidx], stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power ++ move32(); ++ } ++#else + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ) + { + stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power +@@ -2529,8 +2653,24 @@ void protoSignalComputation2_fx( + stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power + move32(); + } ++#endif + + temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ assert( 0 /* qidx has no valid value ? */ ); ++ IF( LT_16( q_Left_Right_power[qidx], stereo_type_detect->q_right_bb_power ) ) ++ { ++ stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power[qidx] ) ) ); // q_Left_Right_power ++ move32(); ++ stereo_type_detect->q_right_bb_power = q_Left_Right_power[qidx]; ++ move16(); ++ } ++ ELSE ++ { ++ stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power[qidx], stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power ++ move32(); ++ } ++#else + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ) + { + stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power +@@ -2543,8 +2683,23 @@ void protoSignalComputation2_fx( + stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power + move32(); + } ++#endif + + temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ IF( LT_16( q_Left_Right_power[qidx], stereo_type_detect->q_total_bb_power ) ) ++ { ++ stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power[qidx] ) ) ); // q_Left_Right_power ++ move32(); ++ stereo_type_detect->q_total_bb_power = q_Left_Right_power[qidx]; ++ move16(); ++ } ++ ELSE ++ { ++ stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power[qidx], stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power ++ move32(); ++ } ++#else + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ) + { + stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power +@@ -2557,6 +2712,7 @@ void protoSignalComputation2_fx( + stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power + move32(); + } ++#endif + + IF( LT_16( stereo_type_detect->q_left_bb_power, stereo_type_detect->q_right_bb_power ) ) + { +@@ -2583,6 +2739,9 @@ void protoSignalComputation2_fx( + // 20480 = 10 in Q11 + lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 + ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ assert(0); ++#else + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + move32(); + stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); +@@ -2593,6 +2752,7 @@ void protoSignalComputation2_fx( + move16(); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + move32(); ++#endif + stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); + move16(); + +@@ -2637,19 +2797,33 @@ void protoSignalComputation2_fx( + move32(); + + ivas_masa_stereotype_detection_fx( stereo_type_detect ); ++ + } + ELSE + { + p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * num_freq_bands * 4 ); // q_proto_direct_buffer_f + ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); ++ q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); ++#else + q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); ++#endif + + FOR( l = 0; l < num_freq_bands; l++ ) + { ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); ++ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift ++ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift ++ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift ++ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift ++#else + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift ++#endif + + Real_aux_fx = L_add( re1, re2 ); // q_cldfb+ min_q_shift + Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+ min_q_shift +@@ -2659,14 +2833,13 @@ void protoSignalComputation2_fx( + move64(); + + #ifdef FIX_867_CLDFB_NRG_SCALE +- Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp ++ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp + #else + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp + #endif +@@ -2675,7 +2848,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2694,13 +2867,13 @@ void protoSignalComputation2_fx( + + temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // q_temp + #ifdef FIX_867_CLDFB_NRG_SCALE +- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) ++ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) + #else + IF( LT_16( q_temp, *q_proto_power_smooth ) ) + #endif + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp + #endif +@@ -2709,7 +2882,7 @@ void protoSignalComputation2_fx( + ELSE + { + #ifdef FIX_867_CLDFB_NRG_SCALE +- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth ++ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + #else + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth + #endif +@@ -2730,9 +2903,11 @@ void protoSignalComputation2_fx( + proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+ min_q_shift + move32(); + } ++ + } +- q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); + #ifdef FIX_867_CLDFB_NRG_SCALE ++ q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[0] ), 1 ); ++ + Word16 norm_shift = 63; + move16(); + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) +@@ -2749,6 +2924,8 @@ void protoSignalComputation2_fx( + } + q_reference_power[0] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); + move16(); ++ ++ q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[1] ), 1 ); + norm_shift = 63; + move16(); + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) +@@ -2766,6 +2943,7 @@ void protoSignalComputation2_fx( + q_reference_power[1] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); + move16(); + #else ++ q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); + Word16 norm_shift = 63; + move16(); + FOR( l = 0; l < num_freq_bands; l++ ) +@@ -2784,13 +2962,48 @@ void protoSignalComputation2_fx( + move16(); + #endif + ++#ifdef FIX_867_CLDFB_NRG_SCALE ++ IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) ++ { ++ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) ++ { ++ Scale_sig32(proto_frame_f_fx + l*2, CLDFB_NO_CHANNELS_HALF*2, sub( min_q_shift[1], min_q_shift[0] ) ); ++ } ++ *q_proto_frame_f = add( q_cldfb, min_q_shift[1] ); ++ move16(); ++ } ELSE { ++ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) ++ { ++ Scale_sig32(proto_frame_f_fx + (l + CLDFB_NO_CHANNELS_HALF)*2, 2*s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( min_q_shift[0], min_q_shift[1] ) ); ++ } ++ *q_proto_frame_f = add( q_cldfb, min_q_shift[0] ); ++ move16(); ++ } ++ IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) ++ { ++ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) ++ { ++ Scale_sig32(proto_direct_buffer_f_fx + l*2, CLDFB_NO_CHANNELS_HALF*2, sub( min_q_shift[1], min_q_shift[0] ) ); ++ } ++ *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); ++ move16(); ++ } ELSE { ++ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) ++ { ++ Scale_sig32(proto_direct_buffer_f_fx + (l + CLDFB_NO_CHANNELS_HALF)*2, 2*s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( min_q_shift[0], min_q_shift[1] ) ); ++ } ++ *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); ++ move16(); ++ } ++#else + *q_proto_frame_f = add( q_cldfb, min_q_shift ); + move16(); + *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift ); + move16(); ++#endif + #ifdef FIX_867_CLDFB_NRG_SCALE +- q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp ); +- q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp ); ++ q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp[0] ); ++ q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp[1] ); + move16(); + move16(); + #else diff --git a/lib_com/options.h b/lib_com/options.h index aff979023..37660ea47 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -69,6 +69,9 @@ #define FIX_867_CLDFB_NRG_SCALE + +#define FIX_1378_ACELP_OUT_OF_BOUNDS + /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ diff --git a/lib_dec/dec_acelp_fx.c b/lib_dec/dec_acelp_fx.c index 07750469f..51cbef624 100644 --- a/lib_dec/dec_acelp_fx.c +++ b/lib_dec/dec_acelp_fx.c @@ -169,6 +169,7 @@ void D_ACELP_indexing_fx( pulses = pulsestrack[0]; move16(); +#ifndef FIX_1378_ACELP_OUT_OF_BOUNDS /* safety check in case of bit errors */ IF( GE_64( s, pulsestostates[16][pulses - 1] ) ) { @@ -177,9 +178,20 @@ void D_ACELP_indexing_fx( move16(); return; } +#endif IF( pulses ) { +#ifdef FIX_1378_ACELP_OUT_OF_BOUNDS + /* safety check in case of bit errors */ + IF( GE_64( s, pulsestostates[16][pulses - 1] ) ) + { + set16_fx( code, 0, L_SUBFR ); + *BER_detect = 1; + move16(); + return; + } +#endif D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 ); } ELSE -- GitLab From 1276285c20e4dee68009ddc9e3e38776549e7b9b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 28 Mar 2025 16:35:27 +0530 Subject: [PATCH 0831/1221] Fix for 3GPP issue 1018: ParamISM: Ext-Output: Difference in high-band Link #1018 --- lib_com/swb_tbe_com_fx.c | 125 ++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2a2841966..238b478c5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -12,11 +12,12 @@ #include "ivas_prot_fx.h" #include "options_warnings.h" -#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ -#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 // Q31 -#define POW_EXC16k_WHTND_FX 178125000 // Q-6 -#define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ -#define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ +#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ +#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 // Q31 +#define POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49 1667313793 // Q49 +#define POW_EXC16k_WHTND_FX 178125000 // Q-6 +#define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ +#define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ /*-----------------------------------------------------------------* * Local function prototypes @@ -3958,7 +3959,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; Word32 pow1, pow22; Word16 scale, temp1, temp2, temp3; - + Word16 Q_White_exc16k; Word16 excTmp2[L_FRAME16k]; Word16 *White_exc16k; Word16 excNoisyEnv[L_FRAME16k]; @@ -3989,12 +3990,13 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word32 White_exc16k_32[L_FRAME16k]; Word16 White_exc16k_tmp[L_FRAME16k]; Word16 Q_temp; - Word16 prev_Q_bwe_exc_fb; - Word16 chk1, chk2; + Word16 prev_Q_bwe_exc_fb, Q_exc16kWhtnd; + Word16 chk1; + Word32 chk2; chk1 = 0; chk2 = 0; move16(); - move16(); + move32(); #if 1 // def ADD_IVAS_TBE_CODE Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; @@ -4262,7 +4264,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( } /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49; move32(); move32(); pow22 = POW_EXC16k_WHTND_FX; @@ -4271,21 +4273,23 @@ void GenShapedSHBExcitation_ivas_dec_fx( // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); Word16 pow1_exp = sub( Q31, Q_pow1 ); Word32 temp_pow = Sqrt32( pow1, &pow1_exp ); - temp_pow = L_shl( Mpy_32_32( temp_pow, pow22_inv ), pow1_exp ); + temp_pow = Mpy_32_32( temp_pow, pow22_inv ); /*Word16 out_exp; Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); temp_pow1 = L_shl(temp_pow1, out_exp);*/ // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); L_tmp = 0; move32(); + shift = getScaleFactor16( White_exc16k, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); move32(); - White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], sub( *Q_bwe_exc, NOISE_QADJ ) ) ); // Q_bwe_exc - NOISE_QADJ + White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], shift ) ); // Q_White_exc16k move16(); L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); } + Q_White_exc16k = add( shift, sub( 49 - 31, pow1_exp ) ); Q_temp = norm_l( L_tmp ); IF( L_tmp == 0 ) { @@ -4323,22 +4327,24 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* calculate pow22 */ /* pow22=0.00001f */ tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - pow22 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Word64 sum = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { - /* White_exc16k[k] *= excNoisyEnv[k]; */ - White_exc16k[k] = mult_r( excNoisyEnv[k], shl( White_exc16k[k], 1 ) ); // Q_excTmp2 + 5 + 1 - 15 ==> Q_excTmp2 - 9 - move16(); - chk2 = s_or( chk2, White_exc16k[k] ); + + White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 + chk2 = L_or( chk2, White_exc16k_32[k] ); /* i: excNoisyEnv in (Q_excTmp2) */ /* i: White_exc16k in Q6 */ - /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + /* o: White_exc16k in (Q_White_exc16k) */ /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2-NOISE_QADJ)*/ + sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ + move16(); } - /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ - Q_pow22 = shl( sub( Q_excTmp2, NOISE_QADJ ), 1 ); - Scale_sig( White_exc16k, L_FRAME16k, sub( *Q_bwe_exc, Q_excTmp2 ) ); + Q_pow22 = W_norm( sum ); + pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); + Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); } #if 1 // def ADD_IVAS_TBE_CODE @@ -4625,7 +4631,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( move16(); } } -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) { @@ -4638,29 +4643,42 @@ void GenShapedSHBExcitation_ivas_dec_fx( temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); Word16 temp_fac = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 + shift = sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ); // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); FOR( k = 0; k < L_FRAME16k; k++ ) { - mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); + mixExc16k[k] = mult_r( shl_sat( White_exc16k[k], shift ), temp_fac ); move16(); } } -#endif tmp = sub( Q_temp, 3 ); FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_FB[k] = White_exc16k[k]; /* Q_bwe_exc-NOISE_QADJ */ + White_exc16k_FB[k] = White_exc16k[k]; /* Q_White_exc16k */ } prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; move16(); - *Q_bwe_exc_fb = sub( *Q_bwe_exc, NOISE_QADJ ); + *Q_bwe_exc_fb = Q_White_exc16k; move16(); + *tbe_demph = shl_sat( *tbe_demph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ - /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ + *tbe_demph = shl_sat( *tbe_demph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); -#if 1 // def ADD_IVAS_TBE_CODE + Q_exc16kWhtnd = getScaleFactor16( exc16kWhtnd, L_FRAME16k ); + Q_exc16kWhtnd = add( Q_exc16kWhtnd, *Q_bwe_exc ); + + shift = getScaleFactor16( White_exc16k, L_FRAME16k ); + + shift = s_min( Q_exc16kWhtnd, add( shift, Q_White_exc16k ) ); + scale_sig( exc16kWhtnd, L_FRAME16k, sub( shift, *Q_bwe_exc ) ); + scale_sig( White_exc16k, L_FRAME16k, sub( shift, Q_White_exc16k ) ); + + Q_exc16kWhtnd = Q_White_exc16k = shift; + move16(); + move16(); + *tbe_premph = shl_sat( *tbe_premph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); + move16(); test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { @@ -4693,11 +4711,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* mixing of LB and gaussian excitation in the first half of the frame */ FOR( k = 0; k < L_FRAME16k / 2; k++ ) { - // exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(fact, mult(shl(White_exc16k[k], *Q_bwe_exc), scale)), mult_r(sub(32767, fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( fact, mult_r( White_exc16k[k], scale ) ), NOISE_QADJ ), - L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + exc16kWhtnd[k] = mac_r( L_mult( fact, mult_r( White_exc16k[k], scale ) ), + sub( 32767, fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd move16(); fact = add_sat( fact, step ); scale = add_sat( scale, step_scale ); @@ -4706,11 +4721,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* mixing of LB and gaussian excitation in the second half of the frame */ FOR( ; k < L_FRAME16k; k++ ) { - // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(new_fact, shl(White_exc16k[k], *Q_bwe_exc)), mult_r(sub(32767, new_fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( new_fact, White_exc16k[k] ), NOISE_QADJ ), - mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + exc16kWhtnd[k] = mac_r( L_mult( new_fact, White_exc16k[k] ), + sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd move16(); } } @@ -4718,14 +4730,9 @@ void GenShapedSHBExcitation_ivas_dec_fx( PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); } ELSE -#endif { -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) -#else - IF( EQ_16( coder_type, UNVOICED ) ) -#endif { L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); test(); @@ -4737,16 +4744,12 @@ void GenShapedSHBExcitation_ivas_dec_fx( scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ FOR( k = 0; k < L_FRAME16k; k++ ) { - /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); - /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx_sat( L_shl_sat( L_tmp, NOISE_QADJ ) ); + exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); move16(); - /* exc16kWhtnd: Q_bwe_exc */ } PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - /* i/o: exc16kWhtnd (Q_bwe_exc) */ - /* i/o: tbe_premph (Q_bwe_exc) */ + /* i/o: exc16kWhtnd (Q_exc16kWhtnd) */ + /* i/o: tbe_premph (Q_exc16kWhtnd) */ } ELSE { @@ -4809,11 +4812,10 @@ void GenShapedSHBExcitation_ivas_dec_fx( FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ + L_tmp = L_mult( temp2, White_exc16k[k + j] ); exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); move16(); - /* Q_bwe_exc */ + /* Q_exc16kWhtnd */ } k = add( k, lSubFr ); @@ -4827,19 +4829,18 @@ void GenShapedSHBExcitation_ivas_dec_fx( temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ temp = div_s( temp, temp2 ); /* Q15 */ temp = mult_r( PREEMPH_FAC, temp ); - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); - /* exc16kWhtnd: Q_bwe_exc; - tbe_premph: Q_bwe_exc*/ + /* exc16kWhtnd: Q_exc16kWhtnd; + tbe_premph: Q_exc16kWhtnd*/ } } } + *tbe_premph = shl_sat( *tbe_premph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + move16(); + Scale_sig( White_exc16k, L_FRAME16k, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); -#if 1 // def ADD_IVAS_TBE_CODE IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( LT_32( bitrate, ACELP_24k40 ) ) -#endif { Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); /* i: exc16kWhtnd in Q_bwe_exc */ -- GitLab From 6d8e151543207ae117f5624b4bd4ef201b003884 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 7 Apr 2025 13:06:15 +0200 Subject: [PATCH 0832/1221] fix PYTEST_ADDOPTS string --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f7db000f7..fcaa06d57 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -404,7 +404,7 @@ stages: - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM\ and stereo and at""; fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM and stereo and at\""; fi - *build-and-create-float-ref-outputs -- GitLab From 5f5ee69577d1095ccf087de5ff12ea933b19466f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 28 Mar 2025 11:41:17 +0100 Subject: [PATCH 0833/1221] adapt CI config to new versions of scripts --- .gitlab-ci.yml | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fcaa06d57..37bd9c601 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -375,6 +375,7 @@ stages: MERGED_CSV_ARTIFACT_NAME: "$CI_JOB_NAME--merged_csv--$CI_JOB_ID.csv" PAGES_HTML_ARTIFACT_NAME: "$CI_JOB_NAME-index.html" SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" + SUMMARY_HTML_ARTIFACT_SPLIT: "summary_split_$CI_JOB_NAME.html" IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" IMAGES_ARTIFACT_SPLIT: "images_split_$CI_JOB_NAME" script: @@ -400,10 +401,9 @@ stages: - comp_args="--mld --ssnr --odg" - - summary_args="MLD DIFF SSNR ODG" - - REPORT_ARG="" + - MEASURES_FOR_REPORT="MLD MAX_ABS_DIFF MIN_SSNR MIN_ODG" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi + - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; MEASURES_FOR_REPORT="$MEASURES_FOR_REPORT DELTA_ODG"; fi - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM and stereo and at\""; fi - *build-and-create-float-ref-outputs @@ -421,30 +421,20 @@ stages: - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true ### create histograms - - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME $REPORT_ARG - # if split comparison is done, we need to create two pages, one for the "whole file" values and one for the "split" values + - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME --split-csv-file $CSV_ARTIFACT_SPLIT + + # first for "whole" files comparison + - python3 scripts/create_histograms.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT + - if [ "$SPLIT_COMPARISON" = "true" ]; then - # use -v flag ("inverse") to also have the header in the output file - - grep -v "_whole" $CSV_ARTIFACT_NAME > $CSV_ARTIFACT_SPLIT - - cp $CSV_ARTIFACT_NAME tmp.csv - - grep -v "_split" tmp.csv > $CSV_ARTIFACT_NAME - - mkdir $IMAGES_ARTIFACT_SPLIT - - for MEASURE in $summary_args;do - - python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT/summary_"$MEASURE".csv $IMAGES_ARTIFACT_SPLIT/summary_"$MEASURE".png --measure $MEASURE - - done - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_SPLIT --measures $summary_args + - python3 scripts/create_histograms.py $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT --measures $MEASURES_FOR_REPORT + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_SPLIT $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_SPLIT --measures $MEASURES_FOR_REPORT - else # touch files to suppress warning for missing artifacts - touch $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT - fi - # this part creates the "whole file" histograms - - mkdir $IMAGES_ARTIFACT_NAME - - for MEASURE in $summary_args;do - - python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; - - done - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_NAME --measures $summary_args - - if [ $USE_LTV -eq 1 ] && [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then - id_previous=$(python3 ci/get_id_of_last_job_occurence.py $CI_DEFAULT_BRANCH $CI_JOB_NAME $CI_PROJECT_ID) - echo "Job ID from variables - $CI_JOB_ID, Job ID from script - $id_previous" @@ -486,6 +476,7 @@ stages: - $CSV_ARTIFACT_SPLIT - $MERGED_CSV_ARTIFACT_NAME - $SUMMARY_HTML_ARTIFACT_NAME + - $SUMMARY_HTML_ARTIFACT_SPLIT - $IMAGES_ARTIFACT_NAME - $IMAGES_ARTIFACT_SPLIT expose_as: "pytest compare results" -- GitLab From 4b93dfab26d87fc7c321d3734a141fededc753a1 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 28 Mar 2025 14:37:12 +0100 Subject: [PATCH 0834/1221] remove format filter again to run whole test suite --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 37bd9c601..6b70851fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -404,7 +404,7 @@ stages: - MEASURES_FOR_REPORT="MLD MAX_ABS_DIFF MIN_SSNR MIN_ODG" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; MEASURES_FOR_REPORT="$MEASURES_FOR_REPORT DELTA_ODG"; fi - - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; export PYTEST_ADDOPTS="-k \"not JBM and stereo and at\""; fi + - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; fi - *build-and-create-float-ref-outputs -- GitLab From de5e4c1b921998e6239c0e8fedd53db59f733ef0 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 1 Apr 2025 14:11:58 +0200 Subject: [PATCH 0835/1221] add --write-out-histograms flag --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b70851fb..75618d54e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -424,11 +424,11 @@ stages: - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME --split-csv-file $CSV_ARTIFACT_SPLIT # first for "whole" files comparison - - python3 scripts/create_histograms.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT + - python3 scripts/create_histograms.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT --write-out-histograms - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT - if [ "$SPLIT_COMPARISON" = "true" ]; then - - python3 scripts/create_histograms.py $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT --measures $MEASURES_FOR_REPORT + - python3 scripts/create_histograms.py $CSV_ARTIFACT_SPLIT $IMAGES_ARTIFACT_SPLIT --measures $MEASURES_FOR_REPORT --write-out-histograms - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_SPLIT $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_SPLIT --measures $MEASURES_FOR_REPORT - else # touch files to suppress warning for missing artifacts -- GitLab From 9140ad05bc5806e66a042ed176a39be6be5cf725 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 7 Apr 2025 12:13:38 +0200 Subject: [PATCH 0836/1221] adapt other uses of parse_xml_report.py to new version --- .gitlab-ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 75618d54e..4eb08fe7a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,6 +52,7 @@ variables: FLOAT_REF_COMMIT_FILE: "float-ref-git-sha" CUT_COMMIT_FILE: "CuT-git-sha" MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha" + MEASURES_FOR_REPORT: "MLD MAX_ABS_DIFF MIN_SSNR MIN_ODG" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -401,7 +402,8 @@ stages: - comp_args="--mld --ssnr --odg" - - MEASURES_FOR_REPORT="MLD MAX_ABS_DIFF MIN_SSNR MIN_ODG" + - INV_LEVEL_SCALING=$(awk "BEGIN {print 1.0 / $LEVEL_SCALING}") + - comp_args="--mld --ssnr --odg --scalefac $INV_LEVEL_SCALING" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; MEASURES_FOR_REPORT="$MEASURES_FOR_REPORT DELTA_ODG"; fi - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; fi @@ -667,9 +669,9 @@ stages: # Store branch outputs for comparison - mv tests/dut tests/dut_branch - # create the summary based on the branch - - for MEASURE in MLD DIFF SSNR ODG;do python3 scripts/create_histogram_summary.py $CSV_BRANCH $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME + # create the summary based on the branch only + - python3 scripts/create_histograms.py $CSV_BRANCH $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT ### run main now - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -- GitLab From dae405dff2d126ba3527028002c3ba0aac5e5985 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 7 Apr 2025 17:57:40 +0530 Subject: [PATCH 0837/1221] Fix for LTV crashes --- lib_com/ivas_spar_com_fx.c | 10 ++++++---- lib_enc/ext_sig_ana_fx.c | 12 ++++++------ lib_enc/pvq_core_enc_fx.c | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 0da6b90c2..8aaeb7f63 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -2658,14 +2658,16 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( factor = L_max( factor, tmp ); // q_factor } - tmp = L_shl_sat( IVAS_FIX_EPS_Q40, sub( q_factor, 40 ) ); + tmp = L_shl_sat( 189 /* 1e-20 in Q74 */, sub( q_factor, 74 ) ); Word16 factor_exp = 0; move16(); IF( LE_32( factor, tmp ) ) { - factor = 1250000000; - factor_exp = Q31 - ( -4 ); + factor = 22204; // (1 / 1e-20) in Q(-52) + factor_exp = Q15 - ( -52 ); + move32(); + move16(); } ELSE { @@ -2688,7 +2690,7 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( { q_tmp = W_norm( W_tmp ); } - cov_uu_re[i - num_dmx][j - num_dmx] = W_extract_h( W_shl( W_mult0_32_32( cov_uu_re[i - num_dmx][j - num_dmx], factor ), q_tmp ) ); /*q_cov_uu_re+15-factor_exp+q_tmp-32*/ + cov_uu_re[i - num_dmx][j - num_dmx] = W_extract_h( W_shl( W_tmp, q_tmp ) ); /*q_cov_uu_re+15-factor_exp+q_tmp-32*/ move32(); q_cov_uu_re_per_value[i - num_dmx][j - num_dmx] = sub( add( add( q_cov_uu_re, sub( 15, factor_exp ) ), q_tmp ), 32 ); move16(); diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 58c1f9641..200e7e8ed 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -987,7 +987,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outter left folding */ FOR( i = 0; i < folding_offset; i++ ) { - tcx20Win[folding_offset + i] = sub( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win + tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win move16(); } @@ -1002,14 +1002,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } } @@ -1018,7 +1018,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) { - tcx20Win[L_subframe + folding_offset - 1 - i] = add( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win + tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win move16(); } @@ -1122,14 +1122,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + q_tcx20Win - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win move32(); } } diff --git a/lib_enc/pvq_core_enc_fx.c b/lib_enc/pvq_core_enc_fx.c index 356f2beaf..e2d5fb264 100644 --- a/lib_enc/pvq_core_enc_fx.c +++ b/lib_enc/pvq_core_enc_fx.c @@ -550,8 +550,8 @@ Word16 pvq_core_enc_ivas_fx( get_max_pulses_fx( sfm_start, sfm_end, ord, npulses, nb_sfm, pulse_vector, maxpulse ); /* Fine gain prediction */ - fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, - coefs_quant, pulse_vector, fg_pred, core ); + ivas_fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, + coefs_quant, pulse_vector, fg_pred, core ); fine_gain_quant_fx( hBstr, ord, nb_sfm, gain_bits_array, fg_pred, gopt ); -- GitLab From fc7b3bc84d82d9419b007699399f8a79e9bbd11c Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 7 Apr 2025 20:24:42 +0200 Subject: [PATCH 0838/1221] Improve precision of proto power. Reduces hight frequency noise for MASA_1dir_2TC_at_96_kbps_48kHz_in_48kHz_out_MONO test case. --- diff | 1068 ----------------- lib_com/options.h | 2 +- lib_dec/ivas_dirac_dec_fx.c | 27 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 61 +- lib_rend/ivas_dirac_rend_fx.c | 293 ++++- 5 files changed, 306 insertions(+), 1145 deletions(-) delete mode 100644 diff diff --git a/diff b/diff deleted file mode 100644 index e782cdaf8..000000000 --- a/diff +++ /dev/null @@ -1,1068 +0,0 @@ -diff --git a/Makefile b/Makefile -index 9d18cbde..8087038a 100644 ---- a/Makefile -+++ b/Makefile -@@ -26,10 +26,17 @@ LIB_LIBREND ?= libivasrend.a - LIB_LIBUTIL ?= libivasutil.a - - # Default tool settings --CC ?= gcc -+#CC ?= gcc -+CC ?= clang - RM ?= rm -f - AR ?= ar - -+#CFLAGS += -fsanitize=address,undefined,integer,nullability -+#LDFLAGS += -fsanitize=address,undefined,integer,nullability -+#CFLAGS += -fsanitize=address,undefined,nullability -+#LDFLAGS += -fsanitize=address,undefined,nullability -+ -+ - # Detect system - UNAME_S := $(shell uname -s) - -diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c -index 48c00ed9..12bfee13 100644 ---- a/lib_dec/ivas_dirac_dec_fx.c -+++ b/lib_dec/ivas_dirac_dec_fx.c -@@ -3678,6 +3678,7 @@ void ivas_dirac_dec_render_sf_fx( - exp = L_norm_arr( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - scale_sig32( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // q_reference_power_smooth[0] + exp - q_reference_power_smooth[0] = add( q_reference_power_smooth[0], exp ); -+#if 0 - IF( LT_16( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ) - { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // q_reference_power_smooth[0] -@@ -3696,10 +3697,11 @@ void ivas_dirac_dec_render_sf_fx( - q_reference_power_smooth[0] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0]; - move16(); - } -- -+#endif - exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), exp ); // q_reference_power_smooth + exp - q_reference_power_smooth[1] = add( q_reference_power_smooth[1], exp ); -+#if 0 - IF( LT_16( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ) - { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // q_reference_power_smooth -@@ -3718,6 +3720,7 @@ void ivas_dirac_dec_render_sf_fx( - q_reference_power_smooth[1] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1]; - move16(); - } -+#endif - #else - exp = L_norm_arr( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands ); - scale_sig32( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, exp ); // q_reference_power_smooth + exp -@@ -3782,6 +3785,7 @@ void ivas_dirac_dec_render_sf_fx( - } - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); - move16(); -+#if 0 - IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) - { - FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) -@@ -3800,6 +3804,7 @@ void ivas_dirac_dec_render_sf_fx( - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; - move16(); - } -+#endif - exp = 31; - move16(); - FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) -@@ -3812,6 +3817,7 @@ void ivas_dirac_dec_render_sf_fx( - } - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); - move16(); -+#if 0 - IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ) - { - FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) -@@ -3830,6 +3836,7 @@ void ivas_dirac_dec_render_sf_fx( - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; - move16(); - } -+#endif - #else - exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) -diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c -index 77826b96..1cc6cd4d 100644 ---- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c -+++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c -@@ -2173,13 +2173,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( - reference_power_smooth[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth - prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ), - h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth -- --#ifdef FIX_867_CLDFB_NRG_SCALE -- assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] ); -- assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] ); --#else -+#ifndef FIX_867_CLDFB_NRG_SCALE - assert( *q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q ); --#endif - weightedDirectionSmoothness = - L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), - Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth -@@ -2187,6 +2182,23 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( - - exp = 0; - move16(); -+#else -+ Word16 s1, s2, qidx; -+ qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -+ -+ s1 = s_max( 0, sub( q_reference_power_smooth[qidx], h_dirac_output_synthesis_state->reference_power_smooth_prev_q[qidx] ) ); -+ s2 = s_max( 0, sub( h_dirac_output_synthesis_state->reference_power_smooth_prev_q[qidx], q_reference_power_smooth[qidx] ) ); -+ currWeight = L_shr( currWeight, s1 ); -+ prevWeight = L_shr( prevWeight, s2 ); -+ weightedDirectionSmoothness = -+ L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), -+ Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth -+ sumWeight = L_add( currWeight, prevWeight ); // q_reference_power_smooth -+ -+ exp = s_min( q_reference_power_smooth[qidx], h_dirac_output_synthesis_state->reference_power_smooth_prev_q[qidx] ); -+ move16(); -+#endif -+ - #if 1 - tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ - smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 -@@ -2222,6 +2234,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( - p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; - set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) ); - -+#ifndef FIX_867_CLDFB_NRG_SCALE - FOR( k = 0; k < num_protos_dir; k++ ) - { - FOR( l = 0; l < num_freq_bands; l++ ) -@@ -2234,27 +2247,76 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( - *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth - move32(); - -+ assert(h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q); -+ - IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) - { - p_power_smooth_prev++; -- L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ -+ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ - exp_arr[k * num_freq_bands + l] = exp; - move16(); - -- *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/ -+ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ - move32(); - } - ELSE - { -- L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ -+ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ - exp_arr[k * num_freq_bands + l] = exp; - move16(); - -- *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/ -+ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ - move32(); - } - } - } -+#else -+ Word16 shift_prev0, shift_curr0, shift_prev1, shift_curr1; -+ shift_prev0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0], h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); -+ shift_curr0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); -+ shift_prev1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1], h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); -+ shift_curr1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); -+ -+ FOR( k = 0; k < num_protos_dir; k++ ) -+ { -+ FOR( l = 0; l < CLDFB_NO_CHANNELS_HALF; l++ ) -+ { -+ g1 = alpha[l]; // Q31 -+ move32(); -+ g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 -+ *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev0 ) ) ); //(Q31, proto_power_smooth_q) -> proto_power_smooth_q -+ move32(); -+ *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), -+ L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr0 ) ); //(Q31, proto_power_smooth_q) -> min(proto_power_smooth_q, proto_power_smooth_prev_q) -+ move32(); -+ -+ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ -+ exp_arr[k * num_freq_bands + l] = exp; -+ move16(); -+ -+ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ -+ move32(); -+ } -+ FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) -+ { -+ g1 = alpha[l]; // Q31 -+ move32(); -+ g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 -+ *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev1 ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth -+ move32(); -+ *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), -+ L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr1 ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth -+ move32(); -+ -+ L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ -+ exp_arr[k * num_freq_bands + l] = exp; -+ move16(); -+ -+ *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ -+ move32(); -+ } -+ } -+#endif - - // Move proto_power_smooth_fx to common Q-factor - -@@ -2297,14 +2359,23 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( - p_power_smooth++; - } - } -+ -+ // Update the Q-factor -+#if 0 - q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); - q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); - -- // Update the Q-factor - h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = h_dirac_output_synthesis_state->proto_power_smooth_q[0]; - h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = h_dirac_output_synthesis_state->proto_power_smooth_q[1]; -- move16(); -- move16(); -+ move16(); move16(); -+#else -+ h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ); -+ h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ); -+ move16(); move16(); -+ -+ q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); -+ q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); -+#endif - h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp; - h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2; - move16(); -diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c -index 18c9269d..d1071b39 100644 ---- a/lib_rend/ivas_dirac_rend_fx.c -+++ b/lib_rend/ivas_dirac_rend_fx.c -@@ -1774,15 +1774,32 @@ void protoSignalComputation2_fx( - Word32 a_fx, b_fx, a2_fx, b2_fx; - Word16 interpolatorSpaced_fx, interpolatorDmx_fx; - Word32 tempSpaced_fx, tempDmx_fx; -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 q_shift, min_q_shift[2], exp, q_temp[2], temp_q_shift, q_temp2; -+#else - Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; -+#endif - Word32 temp; - Word64 W_tmp1, W_tmp2; - Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; - Word16 q_reference_power_64fx; -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 head_room, q_Left_Right_power[2]; -+#else - Word16 head_room, q_Left_Right_power; -+#endif -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ const Word16 num_proto = 3; -+#endif - /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ min_q_shift[0] = Q31; -+ min_q_shift[1] = Q31; -+ move16(); move16(); -+#else - min_q_shift = Q31; - move16(); -+#endif - temp_q_shift = Q31; - move16(); - q_sum_total_ratio = Q31; -@@ -1797,18 +1814,35 @@ void protoSignalComputation2_fx( - /* Calculate the max shift possible for the buffers RealBuffer_fx and ImagBuffer_fx */ - FOR( l = 0; l < 2; l++ ) - { -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ) ); -+ min_q_shift[0] = s_min( min_q_shift[0], q_shift ); -+ q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), L_norm_arr( ImagBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); -+ min_q_shift[1] = s_min( min_q_shift[1], q_shift ); -+#else - q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], num_freq_bands ), L_norm_arr( ImagBuffer_fx[l][0], num_freq_bands ) ); - min_q_shift = s_min( min_q_shift, q_shift ); -+#endif - - #ifdef MSAN_FIX - q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ); - #else - q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ), L_norm_arr( ImagBuffer_fx[l][0], MASA_SUM_FREQ_RANGE_BINS ) ); - #endif // MSAN_FIX -+#ifdef FIX_867_CLDFB_NRG_SCALE -+#if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) -+#error MASA_SUM_FREQ_RANGE_BINS if greater than CLDFB_NO_CHANNELS_HALF, this does not work -+#endif -+#endif - temp_q_shift = s_min( temp_q_shift, q_shift ); - } - -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits -+ min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits -+#else - min_q_shift = sub( min_q_shift, 2 ); // guard bits -+#endif - temp_q_shift = sub( temp_q_shift, 2 ); // guard bits - - /* Upscaling of the buffer proto_power_smooth_fx */ -@@ -1868,16 +1902,29 @@ void protoSignalComputation2_fx( - { - p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f - -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); -+ q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); -+ move16(); -+#else - q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); - move16(); -- -+#endif - FOR( l = 0; l < num_freq_bands; l++ ) - { -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -+ -+ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+#else - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift -- -+#endif - Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift - Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift - -@@ -1894,14 +1941,13 @@ void protoSignalComputation2_fx( - temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 - - #ifdef FIX_867_CLDFB_NRG_SCALE -- Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -1910,7 +1956,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -1925,13 +1971,13 @@ void protoSignalComputation2_fx( - temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 - - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -1940,7 +1986,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -1954,13 +2000,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -1969,7 +2015,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2042,20 +2088,29 @@ void protoSignalComputation2_fx( - interpolatorSpaced_fx = sub( MAX16B, interpolatorDmx_fx ); /* Q15 */ - } - } -- -+#ifndef FIX_867_CLDFB_NRG_SCALE - min_q_shift = sub( min_q_shift, idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); - - q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); -+#endif - q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); -- - head_room = 63; - move16(); - FOR( l = 0; l < num_freq_bands; l++ ) - { -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -+ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+#else -+ - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift -+#endif - - W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); - W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); -@@ -2063,15 +2118,28 @@ void protoSignalComputation2_fx( - head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); - } - head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); -+ -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ q_Left_Right_power[0] = add( shl( add( q_cldfb, min_q_shift[0] ), 1 ), sub( head_room, 32 ) ); -+ q_Left_Right_power[1] = add( shl( add( q_cldfb, min_q_shift[1] ), 1 ), sub( head_room, 32 ) ); -+#else - q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); -+#endif - - FOR( l = 0; l < num_freq_bands; l++ ) - { -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -+ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift -+#else - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift -- -+#endif - /* Compute sum signal */ - Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift - Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift -@@ -2091,6 +2159,7 @@ void protoSignalComputation2_fx( - left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power - right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power - // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); -+ assert(0 /* Fix 2 scale regions for total_bb_power_fx, left_hi_power_fx, right_hi_power_fx and total_hi_power_fx */ ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power - - IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) -@@ -2103,9 +2172,14 @@ void protoSignalComputation2_fx( - - IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) - { -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ assert( qidx == 0 ); -+ re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[qidx] ) ); // q_cldfb+temp_q_shift -+ im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[qidx] ) ); // q_cldfb+temp_q_shift -+#else - re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift - im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift -- -+#endif - sum_power_fx = Madd_32_32( Mpy_32_32( re_aux, re_aux ), im_aux, im_aux ); // 2*(q_cldfb+temp_q_shift)-31 - temp = Mpy_32_32( a_fx, sum_power_fx ); // 2*(q_cldfb+temp_q_shift)-31 - -@@ -2121,6 +2195,18 @@ void protoSignalComputation2_fx( - } - - temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ IF( LT_16( q_temp[qidx], stereo_type_detect->q_total_power ) ) -+ { -+ stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); // q_temp -+ move32(); -+ } -+ ELSE -+ { -+ stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power -+ move32(); -+ } -+#else - IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) - { - stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp -@@ -2131,7 +2217,7 @@ void protoSignalComputation2_fx( - stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power - move32(); - } -- -+#endif - test(); - IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) - { -@@ -2147,7 +2233,11 @@ void protoSignalComputation2_fx( - { - sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) - move32(); -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); -+#else - q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); -+#endif - sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 - move32(); - } -@@ -2159,6 +2249,22 @@ void protoSignalComputation2_fx( - ImagSubtract_fx = L_sub( im1, im2 ); // q_cldfb+min_q_shift - - temp = Madd_32_32( Mpy_32_32( RealSubtract_fx, RealSubtract_fx ), ImagSubtract_fx, ImagSubtract_fx ); // 2*(q_cldfb+min_q_shift)-31 -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ assert( qidx == 0 ); -+ IF( LT_16( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) -+ { -+ stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp[qidx] ) ), temp ); // q_temp -+ move32(); -+ stereo_type_detect->q_subtract_power_y = q_temp[qidx]; -+ move16(); -+ } -+ ELSE -+ { -+ stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y -+ move32(); -+ } -+ -+#else - IF( LT_16( q_temp, stereo_type_detect->q_subtract_power_y ) ) - { - stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp ) ), temp ); // q_temp -@@ -2171,12 +2277,10 @@ void protoSignalComputation2_fx( - stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp, stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y - move32(); - } -+#endif - } - - /* Compute protos (and their power) for direct sound rendering */ --#ifdef FIX_867_CLDFB_NRG_SCALE -- Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); --#endif - - /* W prototype */ - IF( stereo_type_detect->interpolator > 0 ) -@@ -2188,13 +2292,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift) -31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2203,7 +2307,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2222,13 +2326,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_16( Mpy_32_16_1( tempSpaced_fx, interpolatorSpaced_fx ), tempDmx_fx, interpolatorDmx_fx ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2237,7 +2341,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2258,13 +2362,13 @@ void protoSignalComputation2_fx( - Imag_aux_fx = L_shr( Imag_aux_fx, 1 ); // q_cldfb+min_q_shift - temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2273,7 +2377,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2289,13 +2393,13 @@ void protoSignalComputation2_fx( - { - temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2304,7 +2408,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2321,13 +2425,13 @@ void protoSignalComputation2_fx( - { - temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2336,7 +2440,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2376,13 +2480,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2391,7 +2495,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2418,13 +2522,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2433,7 +2537,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2459,13 +2563,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2474,7 +2578,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2499,8 +2603,12 @@ void protoSignalComputation2_fx( - - stereo_type_detect->q_sum_power = s_min( stereo_type_detect->q_sum_power, q_temp2 ); - move16(); -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ assert(0); -+#else - stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp ); - move16(); -+#endif - q_sum_total_ratio = Q15; - move16(); - -@@ -2517,6 +2625,22 @@ void protoSignalComputation2_fx( - } - - temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -+ assert( 0 /* qidx has no valid value ? */ ); -+ IF( LT_16( q_Left_Right_power[qidx], stereo_type_detect->q_left_bb_power ) ) -+ { -+ stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power[qidx] ) ) ); // q_Left_Right_power -+ move32(); -+ stereo_type_detect->q_left_bb_power = q_Left_Right_power[qidx]; -+ move16(); -+ } -+ ELSE -+ { -+ stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power[qidx], stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power -+ move32(); -+ } -+#else - IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ) - { - stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power -@@ -2529,8 +2653,24 @@ void protoSignalComputation2_fx( - stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power - move32(); - } -+#endif - - temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ assert( 0 /* qidx has no valid value ? */ ); -+ IF( LT_16( q_Left_Right_power[qidx], stereo_type_detect->q_right_bb_power ) ) -+ { -+ stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power[qidx] ) ) ); // q_Left_Right_power -+ move32(); -+ stereo_type_detect->q_right_bb_power = q_Left_Right_power[qidx]; -+ move16(); -+ } -+ ELSE -+ { -+ stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power[qidx], stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power -+ move32(); -+ } -+#else - IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ) - { - stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power -@@ -2543,8 +2683,23 @@ void protoSignalComputation2_fx( - stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power - move32(); - } -+#endif - - temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ IF( LT_16( q_Left_Right_power[qidx], stereo_type_detect->q_total_bb_power ) ) -+ { -+ stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power[qidx] ) ) ); // q_Left_Right_power -+ move32(); -+ stereo_type_detect->q_total_bb_power = q_Left_Right_power[qidx]; -+ move16(); -+ } -+ ELSE -+ { -+ stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power[qidx], stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power -+ move32(); -+ } -+#else - IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ) - { - stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power -@@ -2557,6 +2712,7 @@ void protoSignalComputation2_fx( - stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power - move32(); - } -+#endif - - IF( LT_16( stereo_type_detect->q_left_bb_power, stereo_type_detect->q_right_bb_power ) ) - { -@@ -2583,6 +2739,9 @@ void protoSignalComputation2_fx( - // 20480 = 10 in Q11 - lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 - -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ assert(0); -+#else - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); - move32(); - stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); -@@ -2593,6 +2752,7 @@ void protoSignalComputation2_fx( - move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); - move32(); -+#endif - stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); - move16(); - -@@ -2637,19 +2797,33 @@ void protoSignalComputation2_fx( - move32(); - - ivas_masa_stereotype_detection_fx( stereo_type_detect ); -+ - } - ELSE - { - p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * num_freq_bands * 4 ); // q_proto_direct_buffer_f - -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); -+ q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); -+#else - q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); -+#endif - - FOR( l = 0; l < num_freq_bands; l++ ) - { -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -+ re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift -+ re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift -+ im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift -+ im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift -+#else - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift -+#endif - - Real_aux_fx = L_add( re1, re2 ); // q_cldfb+ min_q_shift - Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+ min_q_shift -@@ -2659,14 +2833,13 @@ void protoSignalComputation2_fx( - move64(); - - #ifdef FIX_867_CLDFB_NRG_SCALE -- Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp -+ proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp - #else - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp - #endif -@@ -2675,7 +2848,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2694,13 +2867,13 @@ void protoSignalComputation2_fx( - - temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // q_temp - #ifdef FIX_867_CLDFB_NRG_SCALE -- IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) -+ IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) - #else - IF( LT_16( q_temp, *q_proto_power_smooth ) ) - #endif - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp - #endif -@@ -2709,7 +2882,7 @@ void protoSignalComputation2_fx( - ELSE - { - #ifdef FIX_867_CLDFB_NRG_SCALE -- proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth -+ proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth - #else - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth - #endif -@@ -2730,9 +2903,11 @@ void protoSignalComputation2_fx( - proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+ min_q_shift - move32(); - } -+ - } -- q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); - #ifdef FIX_867_CLDFB_NRG_SCALE -+ q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[0] ), 1 ); -+ - Word16 norm_shift = 63; - move16(); - FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) -@@ -2749,6 +2924,8 @@ void protoSignalComputation2_fx( - } - q_reference_power[0] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); - move16(); -+ -+ q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[1] ), 1 ); - norm_shift = 63; - move16(); - FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) -@@ -2766,6 +2943,7 @@ void protoSignalComputation2_fx( - q_reference_power[1] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); - move16(); - #else -+ q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); - Word16 norm_shift = 63; - move16(); - FOR( l = 0; l < num_freq_bands; l++ ) -@@ -2784,13 +2962,48 @@ void protoSignalComputation2_fx( - move16(); - #endif - -+#ifdef FIX_867_CLDFB_NRG_SCALE -+ IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) -+ { -+ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) -+ { -+ Scale_sig32(proto_frame_f_fx + l*2, CLDFB_NO_CHANNELS_HALF*2, sub( min_q_shift[1], min_q_shift[0] ) ); -+ } -+ *q_proto_frame_f = add( q_cldfb, min_q_shift[1] ); -+ move16(); -+ } ELSE { -+ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) -+ { -+ Scale_sig32(proto_frame_f_fx + (l + CLDFB_NO_CHANNELS_HALF)*2, 2*s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( min_q_shift[0], min_q_shift[1] ) ); -+ } -+ *q_proto_frame_f = add( q_cldfb, min_q_shift[0] ); -+ move16(); -+ } -+ IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) -+ { -+ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) -+ { -+ Scale_sig32(proto_direct_buffer_f_fx + l*2, CLDFB_NO_CHANNELS_HALF*2, sub( min_q_shift[1], min_q_shift[0] ) ); -+ } -+ *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); -+ move16(); -+ } ELSE { -+ FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) -+ { -+ Scale_sig32(proto_direct_buffer_f_fx + (l + CLDFB_NO_CHANNELS_HALF)*2, 2*s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( min_q_shift[0], min_q_shift[1] ) ); -+ } -+ *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); -+ move16(); -+ } -+#else - *q_proto_frame_f = add( q_cldfb, min_q_shift ); - move16(); - *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift ); - move16(); -+#endif - #ifdef FIX_867_CLDFB_NRG_SCALE -- q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp ); -- q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp ); -+ q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp[0] ); -+ q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp[1] ); - move16(); - move16(); - #else diff --git a/lib_com/options.h b/lib_com/options.h index 37660ea47..f9c99b0f9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,7 +68,7 @@ #endif #define FIX_867_CLDFB_NRG_SCALE - +#define FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE #define FIX_1378_ACELP_OUT_OF_BOUNDS diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index c2ef3b92e..d186de136 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3727,6 +3727,20 @@ void ivas_dirac_dec_render_sf_fx( } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); move16(); + exp = 31; + move16(); + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + exp = s_min( exp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + } + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); + move16(); + +#ifndef FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) @@ -3745,18 +3759,6 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; move16(); } - exp = 31; - move16(); - FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) - { - exp = s_min( exp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); - } - FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) - { - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) - } - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); - move16(); IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ) { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) @@ -3775,6 +3777,7 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; move16(); } +#endif #else exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 8b94a7cf7..93533c702 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2247,6 +2247,53 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) ); +#ifdef FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE + Word16 shift_prev0, shift_curr0, shift_prev1, shift_curr1; + shift_prev0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0], h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); + shift_curr0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); + shift_prev1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1], h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); + shift_curr1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); + + FOR( k = 0; k < num_protos_dir; k++ ) + { + FOR( l = 0; l < s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ); l++ ) + { + g1 = alpha[l]; // Q31 + move32(); + g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev0 ) ) ); //(Q31, proto_power_smooth_q) -> proto_power_smooth_q + move32(); + *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), + L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr0 ) ); //(Q31, proto_power_smooth_q) -> min(proto_power_smooth_q, proto_power_smooth_prev_q) + move32(); + + L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ + exp_arr[k * num_freq_bands + l] = exp; + move16(); + + *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ + move32(); + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + g1 = alpha[l]; // Q31 + move32(); + g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev1 ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth + move32(); + *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), + L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr1 ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth + move32(); + + L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ + exp_arr[k * num_freq_bands + l] = exp; + move16(); + + *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ + move32(); + } + } +#else FOR( k = 0; k < num_protos_dir; k++ ) { FOR( l = 0; l < num_freq_bands; l++ ) @@ -2286,6 +2333,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( } } } +#endif // Move proto_power_smooth_fx to common Q-factor @@ -2328,14 +2376,15 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( p_power_smooth++; } } - q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); - q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); // Update the Q-factor - h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = h_dirac_output_synthesis_state->proto_power_smooth_q[0]; - h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = h_dirac_output_synthesis_state->proto_power_smooth_q[1]; - move16(); - move16(); + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ); + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ); + move16(); move16(); + + q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); + q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); + h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp; h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2; move16(); diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 573ece7cb..1ded63197 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1762,15 +1762,28 @@ void protoSignalComputation2_fx( Word32 a_fx, b_fx, a2_fx, b2_fx; Word16 interpolatorSpaced_fx, interpolatorDmx_fx; Word32 tempSpaced_fx, tempDmx_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_shift, min_q_shift[2], exp, q_temp[2], temp_q_shift, q_temp2; +#else Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; +#endif Word32 temp; Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; Word16 head_room, q_Left_Right_power; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 num_proto = 3; +#endif /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ +#ifdef FIX_867_CLDFB_NRG_SCALE + min_q_shift[0] = Q31; + min_q_shift[1] = Q31; + move16(); move16(); +#else min_q_shift = Q31; move16(); +#endif temp_q_shift = Q31; move16(); q_sum_total_ratio = Q31; @@ -1785,31 +1798,47 @@ void protoSignalComputation2_fx( /* Calculate the max shift possible for the buffers RealBuffer_fx and ImagBuffer_fx */ FOR( l = 0; l < 2; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ) ); + min_q_shift[0] = s_min( min_q_shift[0], q_shift ); + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), L_norm_arr( ImagBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + min_q_shift[1] = s_min( min_q_shift[1], q_shift ); +#if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) +#error MASA_SUM_FREQ_RANGE_BINS if greater than CLDFB_NO_CHANNELS_HALF, this does not work +#endif +#else q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], num_freq_bands ), L_norm_arr( ImagBuffer_fx[l][0], num_freq_bands ) ); min_q_shift = s_min( min_q_shift, q_shift ); - +#endif q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ); temp_q_shift = s_min( temp_q_shift, q_shift ); } +#ifdef FIX_867_CLDFB_NRG_SCALE + min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits + min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits +#else min_q_shift = sub( min_q_shift, 2 ); // guard bits +#endif temp_q_shift = sub( temp_q_shift, 2 ); // guard bits /* Upscaling of the buffer proto_power_smooth_fx */ #ifdef FIX_867_CLDFB_NRG_SCALE IF( isloudspeaker ) { - q_shift = getScaleFactor32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + num_proto = 3; + q_shift = L_norm_arr( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } ELSE { - q_shift = getScaleFactor32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + num_proto = 2; + q_shift = L_norm_arr( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } @@ -1817,17 +1846,17 @@ void protoSignalComputation2_fx( move16(); IF( isloudspeaker ) { - q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + q_shift = L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } ELSE { - q_shift = getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); - q_shift = s_min( q_shift, getScaleFactor32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + q_shift = L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 } @@ -1852,15 +1881,29 @@ void protoSignalComputation2_fx( { p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f +#ifdef FIX_867_CLDFB_NRG_SCALE + q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); + q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); +#else q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#endif Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift @@ -1878,14 +1921,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -1894,7 +1936,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -1909,13 +1951,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -1924,7 +1966,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -1938,13 +1980,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -1953,7 +1995,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2027,19 +2069,32 @@ void protoSignalComputation2_fx( } } +#ifdef FIX_867_CLDFB_NRG_SCALE + q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); + q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); +#else min_q_shift = sub( min_q_shift, idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); +#endif q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); head_room = 63; move16(); FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#endif W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); @@ -2047,14 +2102,30 @@ void protoSignalComputation2_fx( head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); } head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); + +#ifdef FIX_867_CLDFB_NRG_SCALE +#if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) +#error MASA_SUM_FREQ_RANGE_BINS must be less than CLDFB_NO_CHANNELS_HALF +#endif + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift[0] ), 1 ), sub( head_room, 32 ) ); +#else q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#endif /* Compute sum signal */ Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift @@ -2064,6 +2135,7 @@ void protoSignalComputation2_fx( // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift) Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) ); // q_Left_Right_power + // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift) Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) ); // q_Left_Right_power @@ -2087,8 +2159,13 @@ void protoSignalComputation2_fx( IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[0]) ); // q_cldfb+temp_q_shift + im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift +#else re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift +#endif sum_power_fx = Madd_32_32( Mpy_32_32( re_aux, re_aux ), im_aux, im_aux ); // 2*(q_cldfb+temp_q_shift)-31 temp = Mpy_32_32( a_fx, sum_power_fx ); // 2*(q_cldfb+temp_q_shift)-31 @@ -2105,6 +2182,18 @@ void protoSignalComputation2_fx( } temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], stereo_type_detect->q_total_power ) ) + { + stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); // q_temp + move32(); + } + ELSE + { + stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power + move32(); + } +#else IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) { stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp @@ -2115,6 +2204,7 @@ void protoSignalComputation2_fx( stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power move32(); } +#endif test(); IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) @@ -2131,7 +2221,11 @@ void protoSignalComputation2_fx( { sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); +#ifdef FIX_867_CLDFB_NRG_SCALE + q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); +#else q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); +#endif sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 move32(); } @@ -2143,6 +2237,21 @@ void protoSignalComputation2_fx( ImagSubtract_fx = L_sub( im1, im2 ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( RealSubtract_fx, RealSubtract_fx ), ImagSubtract_fx, ImagSubtract_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) + { + stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp[qidx] ) ), temp ); // q_temp + move32(); + stereo_type_detect->q_subtract_power_y = q_temp[qidx]; + move16(); + } + ELSE + { + stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y + move32(); + } + +#else IF( LT_16( q_temp, stereo_type_detect->q_subtract_power_y ) ) { stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp ) ), temp ); // q_temp @@ -2155,12 +2264,10 @@ void protoSignalComputation2_fx( stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp, stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y move32(); } +#endif } /* Compute protos (and their power) for direct sound rendering */ -#ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); -#endif /* W prototype */ IF( stereo_type_detect->interpolator > 0 ) @@ -2172,13 +2279,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift) -31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2187,7 +2294,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2206,13 +2313,13 @@ void protoSignalComputation2_fx( temp = Madd_32_16( Mpy_32_16_1( tempSpaced_fx, interpolatorSpaced_fx ), tempDmx_fx, interpolatorDmx_fx ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2221,7 +2328,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2242,13 +2349,13 @@ void protoSignalComputation2_fx( Imag_aux_fx = L_shr( Imag_aux_fx, 1 ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2257,7 +2364,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2273,13 +2380,13 @@ void protoSignalComputation2_fx( { temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2288,7 +2395,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2305,13 +2412,13 @@ void protoSignalComputation2_fx( { temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2320,7 +2427,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2360,13 +2467,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2375,7 +2482,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2402,13 +2509,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2417,7 +2524,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2443,13 +2550,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2458,7 +2565,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2483,8 +2590,13 @@ void protoSignalComputation2_fx( stereo_type_detect->q_sum_power = s_min( stereo_type_detect->q_sum_power, q_temp2 ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp[0] ); + move16(); +#else stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp ); move16(); +#endif q_sum_total_ratio = Q15; move16(); @@ -2567,6 +2679,18 @@ void protoSignalComputation2_fx( // 20480 = 10 in Q11 lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 +#ifdef FIX_867_CLDFB_NRG_SCALE + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp[0] ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + move32(); + stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); + move16(); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp[0] ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + move32(); + stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); + move16(); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp[0] ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + move32(); +#else stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); @@ -2577,6 +2701,7 @@ void protoSignalComputation2_fx( move16(); stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); +#endif stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); move16(); @@ -2626,14 +2751,27 @@ void protoSignalComputation2_fx( { p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * num_freq_bands * 4 ); // q_proto_direct_buffer_f +#ifdef FIX_867_CLDFB_NRG_SCALE + q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); + q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); +#else q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift +#endif Real_aux_fx = L_add( re1, re2 ); // q_cldfb+ min_q_shift Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+ min_q_shift @@ -2643,14 +2781,13 @@ void protoSignalComputation2_fx( move64(); #ifdef FIX_867_CLDFB_NRG_SCALE - Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp #else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp #endif @@ -2659,7 +2796,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2678,13 +2815,13 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // q_temp #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp, q_proto_power_smooth[qidx] ) ) + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) #else IF( LT_16( q_temp, *q_proto_power_smooth ) ) #endif { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp ) ), temp ); // q_temp + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp #else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp #endif @@ -2693,7 +2830,7 @@ void protoSignalComputation2_fx( ELSE { #ifdef FIX_867_CLDFB_NRG_SCALE - proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth #else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth #endif @@ -2714,9 +2851,11 @@ void protoSignalComputation2_fx( proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+ min_q_shift move32(); } + } - q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); #ifdef FIX_867_CLDFB_NRG_SCALE + q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[0] ), 1 ); + Word16 norm_shift = 63; move16(); FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) @@ -2733,6 +2872,8 @@ void protoSignalComputation2_fx( } q_reference_power[0] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); move16(); + + q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[1] ), 1 ); norm_shift = 63; move16(); FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) @@ -2750,6 +2891,7 @@ void protoSignalComputation2_fx( q_reference_power[1] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); move16(); #else + q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); Word16 norm_shift = 63; move16(); FOR( l = 0; l < num_freq_bands; l++ ) @@ -2768,13 +2910,48 @@ void protoSignalComputation2_fx( move16(); #endif +#ifdef FIX_867_CLDFB_NRG_SCALE + IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) + { + FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + { + Scale_sig32(proto_frame_f_fx + shl( l, 1) , shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); + } + *q_proto_frame_f = add( q_cldfb, min_q_shift[1] ); + move16(); + } ELSE { + FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + { + Scale_sig32(proto_frame_f_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); + } + *q_proto_frame_f = add( q_cldfb, min_q_shift[0] ); + move16(); + } + IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) + { + FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + { + Scale_sig32(p_proto_buffer_fx + shl( l, 1) , shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); + } + *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[1] ); + move16(); + } ELSE { + FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + { + Scale_sig32(p_proto_buffer_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); + } + *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); + move16(); + } +#else *q_proto_frame_f = add( q_cldfb, min_q_shift ); move16(); *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift ); move16(); +#endif #ifdef FIX_867_CLDFB_NRG_SCALE - q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp ); - q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp ); + q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp[0] ); + q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp[1] ); move16(); move16(); #else -- GitLab From aab8df2e95447dbae770bf63769b44cce59cca36 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 7 Apr 2025 20:29:52 +0200 Subject: [PATCH 0839/1221] clang format and deactivate FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE. --- lib_com/options.h | 2 +- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 19 +++---- lib_rend/ivas_dirac_rend_fx.c | 50 ++++++++++--------- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index f9c99b0f9..e5c7467a0 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,7 +68,7 @@ #endif #define FIX_867_CLDFB_NRG_SCALE -#define FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE +//#define FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE #define FIX_1378_ACELP_OUT_OF_BOUNDS diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 93533c702..44ddf8609 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2249,10 +2249,10 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( #ifdef FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE Word16 shift_prev0, shift_curr0, shift_prev1, shift_curr1; - shift_prev0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0], h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); - shift_curr0 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); - shift_prev1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1], h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); - shift_curr1 = s_max( 0 , sub( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); + shift_prev0 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0], h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); + shift_curr0 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); + shift_prev1 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1], h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); + shift_curr1 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); FOR( k = 0; k < num_protos_dir; k++ ) { @@ -2260,7 +2260,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( { g1 = alpha[l]; // Q31 move32(); - g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev0 ) ) ); //(Q31, proto_power_smooth_q) -> proto_power_smooth_q move32(); *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), @@ -2278,10 +2278,10 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( { g1 = alpha[l]; // Q31 move32(); - g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev1 ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth move32(); - *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), + *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr1 ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth move32(); @@ -2379,8 +2379,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( // Update the Q-factor h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ); - h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ); - move16(); move16(); + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ); + move16(); + move16(); q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 1ded63197..3b32d30d1 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1779,7 +1779,8 @@ void protoSignalComputation2_fx( #ifdef FIX_867_CLDFB_NRG_SCALE min_q_shift[0] = Q31; min_q_shift[1] = Q31; - move16(); move16(); + move16(); + move16(); #else min_q_shift = Q31; move16(); @@ -1815,10 +1816,10 @@ void protoSignalComputation2_fx( } #ifdef FIX_867_CLDFB_NRG_SCALE - min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits - min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits + min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits + min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits #else - min_q_shift = sub( min_q_shift, 2 ); // guard bits + min_q_shift = sub( min_q_shift, 2 ); // guard bits #endif temp_q_shift = sub( temp_q_shift, 2 ); // guard bits @@ -2105,7 +2106,7 @@ void protoSignalComputation2_fx( #ifdef FIX_867_CLDFB_NRG_SCALE #if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) -#error MASA_SUM_FREQ_RANGE_BINS must be less than CLDFB_NO_CHANNELS_HALF +#error MASA_SUM_FREQ_RANGE_BINS must be less than CLDFB_NO_CHANNELS_HALF #endif q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift[0] ), 1 ), sub( head_room, 32 ) ); #else @@ -2121,10 +2122,10 @@ void protoSignalComputation2_fx( re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift #else - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift #endif /* Compute sum signal */ @@ -2160,7 +2161,7 @@ void protoSignalComputation2_fx( IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) { #ifdef FIX_867_CLDFB_NRG_SCALE - re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[0]) ); // q_cldfb+temp_q_shift + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift #else re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift @@ -2851,7 +2852,6 @@ void protoSignalComputation2_fx( proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+ min_q_shift move32(); } - } #ifdef FIX_867_CLDFB_NRG_SCALE q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[0] ), 1 ); @@ -2911,34 +2911,38 @@ void protoSignalComputation2_fx( #endif #ifdef FIX_867_CLDFB_NRG_SCALE - IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) + IF( GT_16( min_q_shift[0], min_q_shift[1] ) ) { - FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) { - Scale_sig32(proto_frame_f_fx + shl( l, 1) , shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); + Scale_sig32( proto_frame_f_fx + shl( l, 1 ), shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); } *q_proto_frame_f = add( q_cldfb, min_q_shift[1] ); move16(); - } ELSE { - FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + } + ELSE + { + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) { - Scale_sig32(proto_frame_f_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); + Scale_sig32( proto_frame_f_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); } *q_proto_frame_f = add( q_cldfb, min_q_shift[0] ); move16(); } - IF ( GT_16( min_q_shift[0], min_q_shift[1] ) ) + IF( GT_16( min_q_shift[0], min_q_shift[1] ) ) { - FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) { - Scale_sig32(p_proto_buffer_fx + shl( l, 1) , shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); + Scale_sig32( p_proto_buffer_fx + shl( l, 1 ), shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); } *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[1] ); move16(); - } ELSE { - FOR ( l = 0; l < i_mult(num_proto, num_freq_bands); l += num_freq_bands ) + } + ELSE + { + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) { - Scale_sig32(p_proto_buffer_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); + Scale_sig32( p_proto_buffer_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); } *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); move16(); -- GitLab From 876c438b3570702e13864c1873b3f5526880c731 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 07:26:02 +0200 Subject: [PATCH 0840/1221] rename FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 to FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx - deactivate BE macros, they are already in another branch --- lib_com/options.h | 21 ++++++++++----------- lib_dec/swb_tbe_dec_fx.c | 4 ++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 54f4ea2d9..3a2a1035f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -79,17 +79,16 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT -// new speedups -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | < TODO: check border cases -#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS according pipe -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | - -#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? - -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | +// new speedups - BE ones already in another branch +//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS +//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? Need for a manual test as long as be tests dont work + +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | //----------------------------------------------------------------------- // OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 36a499f7d..bb0d6f2e0 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7031,13 +7031,13 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); -#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 +#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 #endif FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx_0 +#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) -- GitLab From ee0587a7120d5c204d0c58968a1ee13b4fedb586 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 07:41:52 +0200 Subject: [PATCH 0841/1221] added FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic version 1 --- lib_com/options.h | 1 + lib_com/swb_tbe_com_fx.c | 13 +++++++++++++ lib_enc/swb_tbe_enc_fx.c | 12 +++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 571b5edd3..58899a74b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,6 +86,7 @@ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index af52c2564..00c33406d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6703,14 +6703,22 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic_ + Word16 memory_fx0[4][4], memory_fx[4], Q_temp, Q_temp2; +#else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; +#endif Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; FOR( i = 0; i < 4; i++ ) { memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic_ + memory_fx[i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); +#else memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); +#endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); @@ -7070,7 +7078,12 @@ void synthesise_fb_high_band_fx( Word16 Qout ) { Word16 i, j; +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; + Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; +#else Word16 excitation_in_interp3[L_FRAME48k]; +#endif Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 316a5b549..ef499ad6a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,13 +7299,18 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; - Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_buffer[L_FRAME48k + 4]; + Word16 *input_fhb = &input_fhb_buffer[0] + 4; +#else + Word16 input_fhb[L_FRAME48k]; +#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -7422,7 +7427,12 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; + Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; +#else Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; +#endif Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word64 fb_exc_energy; -- GitLab From 3f24f37600668fd12c833eec819aa9ca208d4a2a Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 8 Apr 2025 08:11:19 +0200 Subject: [PATCH 0842/1221] Correct calculation of total_bb_power_fx --- lib_rend/ivas_dirac_rend_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 3b32d30d1..02a26a74e 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2071,6 +2071,10 @@ void protoSignalComputation2_fx( } #ifdef FIX_867_CLDFB_NRG_SCALE + /* Make both shift the same because of total_bb_power_fx */ + min_q_shift[0] = s_min( min_q_shift[0], min_q_shift[1] ); + min_q_shift[1] = min_q_shift[0]; + move16(); q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); #else -- GitLab From feeb6bd7c714e7abcb84cdc35273ad3026a2aad5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 09:35:09 +0200 Subject: [PATCH 0843/1221] remap memory_fx and memory2_fx - more changes TBD - check BEnes --- lib_com/swb_tbe_com_fx.c | 43 ++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a9fd95434..86765d156 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6704,20 +6704,27 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic_ - Word16 memory_fx0[4][4], memory_fx[4], Q_temp, Q_temp2; +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 memory_fx0, Q_temp, Q_temp2; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; + + Word32 *L_tmp = &L_tmp_buffer[4]; + Word32 *L_tmp2 = &L_tmp2_buffer[4]; + Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; + Word16 *memory_fx = &input_fx[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; -#endif Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; +#endif Word32 memory2_fx_2[4], memory2_fx_3[4]; FOR( i = 0; i < 4; i++ ) { - memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic_ - memory_fx[i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + memory_fx0 = extract_l( memory_fx2[0][i] ); + memory_fx[i] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); #else + memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); #endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); @@ -6730,20 +6737,34 @@ void elliptic_bpf_48k_generic_fx( move32(); } +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( memory_fx[0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6752,8 +6773,13 @@ void elliptic_bpf_48k_generic_fx( L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6762,7 +6788,12 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 48a64bc5d6b5c35c1ec4d2686d7a1bc264a442ff Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 11:06:24 +0200 Subject: [PATCH 0844/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 86765d156..bef75e4bf 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6743,11 +6743,11 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6761,10 +6761,10 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6777,8 +6777,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6792,7 +6792,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #else - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 78aa1b4bb67c5ee28aba0f7c65c2741f6a023b96 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 11:12:41 +0200 Subject: [PATCH 0845/1221] remapping of memory2_fx_2 and memory2_fx_3 --- lib_com/swb_tbe_com_fx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bef75e4bf..eda963d23 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6706,17 +6706,21 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; Word16 *memory_fx = &input_fx[-4]; + Word32 *memory2_fx_2 = &L_tmp2[-4]; + Word32 *L_output = &L_output_buffer[0]; + Word32 *memory2_fx_3 = &L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; -#endif Word32 memory2_fx_2[4], memory2_fx_3[4]; +#endif + FOR( i = 0; i < 4; i++ ) { -- GitLab From 95d1adb8639be170b79c9be0f281b81c3d0c2a27 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 12:54:40 +0200 Subject: [PATCH 0846/1221] delete memory2_fx, memory_fx, memory2_fx_2, memory2_fx_3 --- lib_com/swb_tbe_com_fx.c | 241 ++++++++++++++++++++++++++++++++------- 1 file changed, 201 insertions(+), 40 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index eda963d23..e6ee1d5c3 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6695,7 +6695,11 @@ void wb_tbe_extras_reset_synth_fx( *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6710,11 +6714,11 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; - Word16 *memory_fx = &input_fx[-4]; - Word32 *memory2_fx_2 = &L_tmp2[-4]; + //Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; + //Word16 *memory_fx = &input_fx[-4]; + //Word32 *memory2_fx_2 = &L_tmp2[-4]; Word32 *L_output = &L_output_buffer[0]; - Word32 *memory2_fx_3 = &L_output[-4]; + //Word32 *memory2_fx_3 = &L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6726,14 +6730,17 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); - memory_fx[i] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); -#endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); +#endif move32(); move32(); move32(); @@ -6742,71 +6749,103 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif + + #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -#endif - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif + #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); @@ -6903,6 +6942,18 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + move32(); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6913,6 +6964,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); +#endif + + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); +#else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6924,6 +6991,20 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); +#endif + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); +#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6935,6 +7016,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); +#endif + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6947,6 +7044,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#endif + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6977,12 +7076,31 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); +#else + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); +#endif move32(); move32(); } +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + move32(); + L_tmpMax = L_abs( L_output[0] ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -6994,7 +7112,21 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7006,7 +7138,21 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7018,7 +7164,21 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7030,6 +7190,7 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#endif FOR( i = 4; i < L_FRAME48k; i++ ) { -- GitLab From 997c2e89ac3bba53c78862977722e94a950ed2b4 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 12:56:32 +0200 Subject: [PATCH 0847/1221] fix error conflicting types --- lib_com/prot_fx.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1452d8e2e..13b6fe2d8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,11 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : i signal Q_input_fx */ +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else + const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ -- GitLab From 9bc5392af628dd9716f787c74554dc9e7820521e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 13:14:17 +0200 Subject: [PATCH 0848/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 197 +++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 99 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e6ee1d5c3..10177bca7 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,11 +6714,11 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - //Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; - //Word16 *memory_fx = &input_fx[-4]; - //Word32 *memory2_fx_2 = &L_tmp2[-4]; + // Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; + // Word16 *memory_fx = &input_fx[-4]; + // Word32 *memory2_fx_2 = &L_tmp2[-4]; Word32 *L_output = &L_output_buffer[0]; - //Word32 *memory2_fx_3 = &L_output[-4]; + // Word32 *memory2_fx_3 = &L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6733,7 +6733,7 @@ void elliptic_bpf_48k_generic_fx( input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); @@ -6749,22 +6749,22 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6773,23 +6773,23 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6797,51 +6797,50 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #endif - #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #endif @@ -6943,15 +6942,15 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6969,15 +6968,15 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); #else L_tmpMax = L_abs( L_tmp2[0] ); @@ -6995,14 +6994,14 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); #else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); @@ -7020,15 +7019,15 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #else @@ -7079,11 +7078,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + move32(); #else - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); #endif move32(); move32(); @@ -7117,13 +7116,13 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); #else -- GitLab From f4efc581ee3386141a7b4ba83ab4430138d76fba Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 13:40:44 +0200 Subject: [PATCH 0849/1221] Revert "clang format patch" This reverts commit 9bc5392af628dd9716f787c74554dc9e7820521e. --- lib_com/swb_tbe_com_fx.c | 197 ++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 98 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 10177bca7..e6ee1d5c3 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,11 +6714,11 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - // Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; - // Word16 *memory_fx = &input_fx[-4]; - // Word32 *memory2_fx_2 = &L_tmp2[-4]; + //Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; + //Word16 *memory_fx = &input_fx[-4]; + //Word32 *memory2_fx_2 = &L_tmp2[-4]; Word32 *L_output = &L_output_buffer[0]; - // Word32 *memory2_fx_3 = &L_output[-4]; + //Word32 *memory2_fx_3 = &L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6733,7 +6733,7 @@ void elliptic_bpf_48k_generic_fx( input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? + //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); @@ -6749,22 +6749,22 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6773,23 +6773,23 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6797,50 +6797,51 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #endif + #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #endif @@ -6942,15 +6943,15 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6968,15 +6969,15 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); #else L_tmpMax = L_abs( L_tmp2[0] ); @@ -6994,14 +6995,14 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); #else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); @@ -7019,15 +7020,15 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #else @@ -7078,11 +7079,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + move32(); #else - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); #endif move32(); move32(); @@ -7116,13 +7117,13 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); #else -- GitLab From 9781a471204e1ebcf521ab1b74300f72b806eca5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 13:40:54 +0200 Subject: [PATCH 0850/1221] Revert "fix error conflicting types" This reverts commit 997c2e89ac3bba53c78862977722e94a950ed2b4. --- lib_com/prot_fx.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 13b6fe2d8..1452d8e2e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,11 +3258,7 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif + const Word16 input_fx[], /* i : i signal Q_input_fx */ Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ -- GitLab From 5a6b1cccab516d7f7b2b8b0cf7526e57119273bf Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 13:41:11 +0200 Subject: [PATCH 0851/1221] Revert "delete memory2_fx, memory_fx, memory2_fx_2, memory2_fx_3" This reverts commit 95d1adb8639be170b79c9be0f281b81c3d0c2a27. --- lib_com/swb_tbe_com_fx.c | 241 +++++++-------------------------------- 1 file changed, 40 insertions(+), 201 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e6ee1d5c3..eda963d23 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6695,11 +6695,7 @@ void wb_tbe_extras_reset_synth_fx( *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6714,11 +6710,11 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - //Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; - //Word16 *memory_fx = &input_fx[-4]; - //Word32 *memory2_fx_2 = &L_tmp2[-4]; + Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; + Word16 *memory_fx = &input_fx[-4]; + Word32 *memory2_fx_2 = &L_tmp2[-4]; Word32 *L_output = &L_output_buffer[0]; - //Word32 *memory2_fx_3 = &L_output[-4]; + Word32 *memory2_fx_3 = &L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6730,17 +6726,14 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); - input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? + memory_fx[i] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); +#endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); -#endif move32(); move32(); move32(); @@ -6749,103 +6742,71 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif - - #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif - #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); @@ -6942,18 +6903,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6964,22 +6913,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); -#endif - - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); -#else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6991,20 +6924,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#endif - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); -#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7016,22 +6935,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#endif - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7044,8 +6947,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#endif - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7076,31 +6977,12 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); -#else - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); -#endif + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); move32(); move32(); } -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7112,21 +6994,7 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7138,21 +7006,7 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7164,21 +7018,7 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7190,7 +7030,6 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#endif FOR( i = 4; i < L_FRAME48k; i++ ) { -- GitLab From 425a67b9280368e30cd32f97f725814e26fe8776 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 13:41:29 +0200 Subject: [PATCH 0852/1221] Revert "remapping of memory2_fx_2 and memory2_fx_3" This reverts commit 78aa1b4bb67c5ee28aba0f7c65c2741f6a023b96. --- lib_com/swb_tbe_com_fx.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index eda963d23..bef75e4bf 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6706,21 +6706,17 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; Word16 *memory_fx = &input_fx[-4]; - Word32 *memory2_fx_2 = &L_tmp2[-4]; - Word32 *L_output = &L_output_buffer[0]; - Word32 *memory2_fx_3 = &L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; - Word32 memory2_fx_2[4], memory2_fx_3[4]; #endif - + Word32 memory2_fx_2[4], memory2_fx_3[4]; FOR( i = 0; i < 4; i++ ) { -- GitLab From 205dcb45d5f71f507499708379d056e7069e7b27 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 12:56:32 +0200 Subject: [PATCH 0853/1221] fix error conflicting types --- lib_com/prot_fx.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1452d8e2e..13b6fe2d8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,11 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : i signal Q_input_fx */ +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else + const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ -- GitLab From fc8d9864050fa076cccdba719213097ba40cb59c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 13:47:52 +0200 Subject: [PATCH 0854/1221] follow-up : fix conflicting types --- lib_com/swb_tbe_com_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bef75e4bf..d75cae8fc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6695,7 +6695,11 @@ void wb_tbe_extras_reset_synth_fx( *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ -- GitLab From ff5630499370c5ab37bdcad83a4ae000a19d5d80 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:02:40 +0200 Subject: [PATCH 0855/1221] fix segfault --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d75cae8fc..5fc7588fd 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6733,7 +6733,7 @@ void elliptic_bpf_48k_generic_fx( #endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); -- GitLab From c52dbd20ab98074c0e5f1b470334f4ee918cfadc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:07:02 +0200 Subject: [PATCH 0856/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5fc7588fd..5e3eb007f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6733,7 +6733,7 @@ void elliptic_bpf_48k_generic_fx( #endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); -- GitLab From 91bc9889207580a123c2e561e2a4a6e8e8e6824c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 12:54:40 +0200 Subject: [PATCH 0857/1221] delete memory2_fx, memory_fx, memory2_fx_2, memory2_fx_3 --- lib_com/swb_tbe_com_fx.c | 235 ++++++++++++++++++++++++++++++++------- 1 file changed, 195 insertions(+), 40 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5e3eb007f..e620290c4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6710,12 +6710,11 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; - Word16 *memory_fx = &input_fx[-4]; + Word32 *L_output = &L_output_buffer[0]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6726,14 +6725,16 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); - memory_fx[i] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); -#endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? +#endif move32(); move32(); move32(); @@ -6742,71 +6743,103 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif + + #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -#endif - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif + #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); @@ -6903,6 +6936,18 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + move32(); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6913,6 +6958,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); +#endif + + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); +#else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6924,6 +6985,20 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); +#endif + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); +#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6935,6 +7010,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); +#endif + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6947,6 +7038,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#endif + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6977,12 +7070,31 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); +#else + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); +#endif move32(); move32(); } +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + move32(); + L_tmpMax = L_abs( L_output[0] ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -6994,7 +7106,21 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7006,7 +7132,21 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7018,7 +7158,21 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7030,6 +7184,7 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#endif FOR( i = 4; i < L_FRAME48k; i++ ) { -- GitLab From f1d1be180b1b22ef1c677427589c3b4c307c3a05 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:37:18 +0200 Subject: [PATCH 0858/1221] reintegrate loops, cleaning tbd --- lib_com/swb_tbe_com_fx.c | 268 ++++++++++++++++++++------------------- 1 file changed, 140 insertions(+), 128 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e620290c4..eb8626354 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6743,16 +6743,16 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + //L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6767,16 +6767,16 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + //L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6791,16 +6791,16 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + //L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6817,16 +6817,16 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + //L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6841,7 +6841,7 @@ void elliptic_bpf_48k_generic_fx( #endif -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig +#if defiend( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { @@ -6912,7 +6912,11 @@ void elliptic_bpf_48k_generic_fx( ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + FOR( i = 0; i < L_FRAME48k; i++ ) +#else FOR( i = 4; i < L_FRAME48k; i++ ) +#endif { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6937,16 +6941,16 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); + //L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + //L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + //move32(); #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6962,17 +6966,17 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); + //L_tmpMax = L_abs( L_tmp2[0] ); + //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //move32(); #else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6988,16 +6992,16 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //move32(); #else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7013,18 +7017,18 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7040,7 +7044,11 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + FOR( i = 0; i < L_FRAME48k; i++ ) +#else FOR( i = 4; i < L_FRAME48k; i++ ) +#endif { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7083,17 +7091,17 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); + //L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //move32(); + //L_tmpMax = L_abs( L_output[0] ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7109,17 +7117,17 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7135,17 +7143,17 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + //L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7161,17 +7169,17 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7186,7 +7194,11 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); #endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + FOR( i = 0; i < L_FRAME48k; i++ ) +#else FOR( i = 4; i < L_FRAME48k; i++ ) +#endif { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From 7cf8b43a129509dafe5057e33dbea7dbb2d9b720 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:41:07 +0200 Subject: [PATCH 0859/1221] clean up reintegratd loops - tbd: make upsempledsig macro work again --- lib_com/swb_tbe_com_fx.c | 111 ++------------------------------------- 1 file changed, 3 insertions(+), 108 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index eb8626354..5702ef0f2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6742,18 +6742,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); -#else +#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6764,20 +6753,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); -#else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6788,20 +6764,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); -#else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6812,22 +6775,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif - - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); -#else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6940,18 +6888,8 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - //L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - //move32(); -#else + +#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6962,22 +6900,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); -#endif - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpMax = L_abs( L_tmp2[0] ); - //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //move32(); -#else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6989,20 +6912,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - //L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //move32(); -#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7014,22 +6924,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -- GitLab From 0aa63c3ff3ea9d0fbbf507050019fd5e9ce048ab Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:46:16 +0200 Subject: [PATCH 0860/1221] make upsempledsig macro work again - tbd: cleanup --- lib_com/swb_tbe_com_fx.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5702ef0f2..7ddd76842 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6866,6 +6866,18 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 4; i < L_FRAME48k; i++ ) #endif { +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); +#else L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6876,6 +6888,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif } } -- GitLab From efe4596efd93a8668e536d65c9f8f746ffbd8908 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:50:41 +0200 Subject: [PATCH 0861/1221] more reintegrating loops and cleaning up - also fix - TBD: make upsampled work again - select only for correct filters --- lib_com/swb_tbe_com_fx.c | 56 +--------------------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7ddd76842..bdc947c7e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6998,19 +6998,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //move32(); - //L_tmpMax = L_abs( L_output[0] ); -#else +#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7022,21 +7010,7 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7048,21 +7022,7 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - //L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7074,21 +7034,7 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 3ad6e7e543ea7a6bfffbcb8032eb067b24c40c7f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:54:27 +0200 Subject: [PATCH 0862/1221] make upsampled work again - select only for correct filters --- lib_com/swb_tbe_com_fx.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bdc947c7e..3544cab74 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6859,6 +6859,10 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ + +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic FOR( i = 0; i < L_FRAME48k; i++ ) @@ -6866,18 +6870,27 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 4; i < L_FRAME48k; i++ ) #endif { -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + } + } + ELSE +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ + { +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + FOR( i = 0; i < L_FRAME48k; i++ ) #else + FOR( i = 4; i < L_FRAME48k; i++ ) +#endif + { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6888,10 +6901,11 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif } } + + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; -- GitLab From 707c22919241ee73a0313d49b041e560a7a97919 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 15:57:38 +0200 Subject: [PATCH 0863/1221] clang format patch and fix preproc cmd --- lib_com/swb_tbe_com_fx.c | 69 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 3544cab74..bf425c066 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6733,7 +6733,7 @@ void elliptic_bpf_48k_generic_fx( memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); // useless? #endif move32(); move32(); @@ -6743,53 +6743,53 @@ void elliptic_bpf_48k_generic_fx( } #ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #endif -#if defiend( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) +#if defined( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { @@ -6859,9 +6859,9 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - + #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); + test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic @@ -6905,7 +6905,6 @@ void elliptic_bpf_48k_generic_fx( } - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; @@ -7003,11 +7002,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + move32(); #else - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); #endif move32(); move32(); -- GitLab From 97c8d64e0605051e876f31e6babc3dc5fcd21d06 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 16:11:13 +0200 Subject: [PATCH 0864/1221] fix unused variable error --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bf425c066..4d22dda27 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6718,8 +6718,8 @@ void elliptic_bpf_48k_generic_fx( #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; -#endif Word32 memory2_fx_2[4], memory2_fx_3[4]; +#endif FOR( i = 0; i < 4; i++ ) { -- GitLab From 7c29e0fcda0a77f713dd7814cce8c1464bc0cf8d Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 8 Apr 2025 16:24:21 +0200 Subject: [PATCH 0865/1221] replace non-intuitive condition by intuitive one --- lib_com/prot_fx.h | 4 ++++ lib_com/swb_tbe_com_fx.c | 32 +++++++++++++++++++++----------- lib_enc/swb_tbe_enc_fx.c | 18 +++++++++++++++--- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 13b6fe2d8..c1ff2895b 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3268,6 +3268,10 @@ void elliptic_bpf_48k_generic_fx( Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ Word16 memory_fx_Q[], const Word16 full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + , + const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ +#endif ); void synthesise_fb_high_band_fx( diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 4d22dda27..259680930 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,15 +6696,19 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fx[], /* i : input signal Q_input_fx*/ + Word16 input_fx[], /* i : input signal Q_input_fx*/ #else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ + const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal memory_fx_Q */ - Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ + Word16 output_fx[], /* o : output signal memory_fx_Q */ + Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ Word16 memory_fx_Q[], - const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ + const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + , + const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ +#endif ) { Word16 i, j; @@ -6790,8 +6794,7 @@ void elliptic_bpf_48k_generic_fx( #if defined( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + IF( isUpsampledBy3 ) { i = 4; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ @@ -6861,8 +6864,7 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) + IF( isUpsampledBy3 ) { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic FOR( i = 0; i < L_FRAME48k; i++ ) @@ -7178,12 +7180,20 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + , 1 +#endif + ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + ,1 +#endif + ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index ef499ad6a..707b0b5f8 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,7 +7330,11 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + ,0 +#endif + ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7459,11 +7463,19 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + ,0 +#endif + ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + ,0 +#endif + ); } test(); -- GitLab From b9db88a72c7431e0c15373b1edf9bcb619fb422f Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 8 Apr 2025 16:48:44 +0200 Subject: [PATCH 0866/1221] Fix missing guard bits. Fixes regression for MASA_2dir_2TC_at_128_kbps_48kHz_in_48kHz_out_FOA. --- lib_rend/ivas_dirac_rend_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 02a26a74e..d64cffa26 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2075,6 +2075,8 @@ void protoSignalComputation2_fx( min_q_shift[0] = s_min( min_q_shift[0], min_q_shift[1] ); min_q_shift[1] = min_q_shift[0]; move16(); + min_q_shift[0] = sub( min_q_shift[0], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); + min_q_shift[1] = sub( min_q_shift[1], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); #else -- GitLab From 8cf8d354f628490634ab12caad66a9773113c381 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 8 Apr 2025 18:12:01 +0200 Subject: [PATCH 0867/1221] Improve proto power accuracy also for stereo_type_detect not NULL case. --- lib_rend/ivas_dirac_rend_fx.c | 42 ++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index d64cffa26..576964c29 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2071,14 +2071,15 @@ void protoSignalComputation2_fx( } #ifdef FIX_867_CLDFB_NRG_SCALE - /* Make both shift the same because of total_bb_power_fx */ - min_q_shift[0] = s_min( min_q_shift[0], min_q_shift[1] ); - min_q_shift[1] = min_q_shift[0]; - move16(); + Word16 total_shift[2], q_temp_total; + /* total_shift shift required to get common Q */ + total_shift[0] = s_max( 0, sub( min_q_shift[0], min_q_shift[1] ) ); + total_shift[1] = s_max( 0, sub( min_q_shift[1], min_q_shift[0] ) ); min_q_shift[0] = sub( min_q_shift[0], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); min_q_shift[1] = sub( min_q_shift[1], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); + q_temp_total = s_min( q_temp[0], q_temp[1] ); #else min_q_shift = sub( min_q_shift, idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); @@ -2151,17 +2152,30 @@ void protoSignalComputation2_fx( reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift) move64(); +#ifdef FIX_867_CLDFB_NRG_SCALE + Left_power_fx = L_shr( Left_power_fx, total_shift[qidx] ); + Right_power_fx = L_shr( Right_power_fx, total_shift[qidx] ); + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power + // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power +#else left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power +#endif IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); +#ifdef FIX_867_CLDFB_NRG_SCALE + total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power +#else total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power +#endif } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) @@ -2188,19 +2202,20 @@ void protoSignalComputation2_fx( move32(); } - temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 #ifdef FIX_867_CLDFB_NRG_SCALE - IF( LT_16( q_temp[qidx], stereo_type_detect->q_total_power ) ) + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], add( 31, total_shift[qidx] ) ) ) ); // 2*(q_cldfb+min_q_shift) -31 + IF( LT_16( q_temp_total, stereo_type_detect->q_total_power ) ) { - stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); // q_temp + stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp_total ) ) ); // q_temp move32(); } ELSE { - stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power + stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp_total, stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power move32(); } #else + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) { stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp @@ -2229,7 +2244,7 @@ void protoSignalComputation2_fx( sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); #ifdef FIX_867_CLDFB_NRG_SCALE - q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp[qidx] ) ) ); + q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp_total ) ) ); #else q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); #endif @@ -2245,6 +2260,7 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( RealSubtract_fx, RealSubtract_fx ), ImagSubtract_fx, ImagSubtract_fx ); // 2*(q_cldfb+min_q_shift)-31 #ifdef FIX_867_CLDFB_NRG_SCALE + assert( qidx == 0 ); IF( LT_16( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) { stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp[qidx] ) ), temp ); // q_temp @@ -2598,7 +2614,7 @@ void protoSignalComputation2_fx( stereo_type_detect->q_sum_power = s_min( stereo_type_detect->q_sum_power, q_temp2 ); move16(); #ifdef FIX_867_CLDFB_NRG_SCALE - stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp[0] ); + stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp_total ); move16(); #else stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp ); @@ -2687,15 +2703,15 @@ void protoSignalComputation2_fx( lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 #ifdef FIX_867_CLDFB_NRG_SCALE - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp[0] ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); move16(); - stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp[0] ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); move32(); stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp[0] ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); #else stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); -- GitLab From 8e1cdae974b4ff286afb05306be9ddc597458a02 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Tue, 8 Apr 2025 18:14:57 +0200 Subject: [PATCH 0868/1221] format fix --- lib_rend/ivas_dirac_rend_fx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 576964c29..7b4ec0a35 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2129,10 +2129,10 @@ void protoSignalComputation2_fx( re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift #else - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift #endif /* Compute sum signal */ @@ -2163,14 +2163,14 @@ void protoSignalComputation2_fx( left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power #endif IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power - // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); + // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); #ifdef FIX_867_CLDFB_NRG_SCALE total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power #else @@ -2184,8 +2184,8 @@ void protoSignalComputation2_fx( re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift #else - re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift - im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift + im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift #endif sum_power_fx = Madd_32_32( Mpy_32_32( re_aux, re_aux ), im_aux, im_aux ); // 2*(q_cldfb+temp_q_shift)-31 @@ -2215,7 +2215,7 @@ void protoSignalComputation2_fx( move32(); } #else - temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) { stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp -- GitLab From 8a2459dce972e7f3ec89ad21d591c390084ac6e6 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 8 Apr 2025 22:02:03 +0530 Subject: [PATCH 0869/1221] Fix for 3GPP issue 1459: Complexity measurement crashes: ISM+ encoder --- lib_enc/ivas_core_pre_proc_front_fx.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index bb065ae20..405d08301 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1226,9 +1226,6 @@ ivas_error pre_proc_front_ivas_fx( st->mem_wsp_q = *Q_new; move16(); move16(); - scale_sig( old_wsp_fx, L_WSP_MEM, sub( *Q_new, *q_old_wsp ) ); - *q_old_wsp = *Q_new; - move16(); ivas_find_wsp_fx( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); @@ -1244,18 +1241,6 @@ ivas_error pre_proc_front_ivas_fx( Word16 shift1 = norm_arr( old_wsp_fx, L_WSP_MEM ); Word16 shift2 = norm_arr( wsp_fx, L_WSP - L_WSP_MEM ); - maximum_abs_16_fx( old_wsp_fx, L_WSP_MEM, &shift ); - if ( !shift ) - { - shift1 = Q15; - move16(); - } - maximum_abs_16_fx( wsp_fx, L_WSP - L_WSP_MEM, &shift ); - if ( !shift ) - { - shift2 = Q15; - move16(); - } shift = s_min( add( *q_old_wsp, shift1 ), add( Q_wsp, shift2 ) ); shift = s_min( shift, add( norm_arr( st->mem_decim2_fx, 3 ), st->Q_old_wsp2 ) ); shift = s_min( shift, add( norm_arr( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ), st->Q_old_wsp2 ) ); -- GitLab From 88431b0f147cfb4bfbad137be2793a3377861d09 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 8 Apr 2025 22:09:30 +0530 Subject: [PATCH 0870/1221] ASAN fix for decoder --- lib_dec/ivas_jbm_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 93e8bb4eb..8c5a9e9af 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -2548,8 +2548,8 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( Word16 n_slots_still_available; Word16 n_samples_to_render; DECODER_TC_BUFFER_HANDLE hTcBuffer; - Word32 output_fx[MAX_CICP_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - Word32 *p_output_fx[MAX_CICP_CHANNELS]; + Word32 output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; Word16 nchan_in, nchan_out; IF( !st_ivas->hDecoderConfig->Opt_tsm ) { -- GitLab From de9181e67e6964e6247aae01f2ebfa50e06325ee Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 07:33:51 +0200 Subject: [PATCH 0871/1221] fic FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig/FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic, deactivate both --- lib_com/options.h | 4 +-- lib_com/swb_tbe_com_fx.c | 78 +++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 58899a74b..27d728add 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,8 +85,8 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ +//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +//#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 259680930..2099087e2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6862,51 +6862,63 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - IF( isUpsampledBy3 ) { +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + IF( isUpsampledBy3 ) + { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) + { + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } #else - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } #endif - { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); } - } - ELSE + ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - { + { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) #else - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) #endif - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } } } - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; -- GitLab From 94f1b674fd648b93a0914289537ac5c4df79e9ec Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 07:37:44 +0200 Subject: [PATCH 0872/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 34 ++++++++++++++++++---------------- lib_enc/swb_tbe_enc_fx.c | 21 ++++++++++++--------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2099087e2..63cda170f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,18 +6696,18 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fx[], /* i : input signal Q_input_fx*/ + Word16 input_fx[], /* i : input signal Q_input_fx*/ #else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ + const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal memory_fx_Q */ - Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ + Word16 output_fx[], /* o : output signal memory_fx_Q */ + Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ Word16 memory_fx_Q[], - const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ + const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig , - const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ + const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ #endif ) { @@ -6883,14 +6883,14 @@ void elliptic_bpf_48k_generic_fx( #else FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } @@ -7194,17 +7194,19 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , 1 -#endif + , + 1 +#endif ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,1 -#endif + , + 1 +#endif ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 707b0b5f8..4b0f5af57 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,10 +7330,11 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,0 -#endif + , + 0 +#endif ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; @@ -7463,18 +7464,20 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,0 -#endif + , + 0 +#endif ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,0 -#endif + , + 0 +#endif ); } -- GitLab From 279792cf491d2139bcef0105d5edf8b0bb4d4531 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 9 Apr 2025 08:11:24 +0200 Subject: [PATCH 0873/1221] Correct total_shift missing factor 2 for total/bb/hi energy scale region compensations. --- lib_rend/ivas_dirac_rend_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 7b4ec0a35..f67f3761b 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2072,9 +2072,9 @@ void protoSignalComputation2_fx( #ifdef FIX_867_CLDFB_NRG_SCALE Word16 total_shift[2], q_temp_total; - /* total_shift shift required to get common Q */ - total_shift[0] = s_max( 0, sub( min_q_shift[0], min_q_shift[1] ) ); - total_shift[1] = s_max( 0, sub( min_q_shift[1], min_q_shift[0] ) ); + /* total_shift shift required to get common Q of sum power values */ + total_shift[0] = shl( s_max( 0, sub( min_q_shift[0], min_q_shift[1] ) ), 1 ); + total_shift[1] = shl( s_max( 0, sub( min_q_shift[1], min_q_shift[0] ) ), 1 ); min_q_shift[0] = sub( min_q_shift[0], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); min_q_shift[1] = sub( min_q_shift[1], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); -- GitLab From a28eea915544f8fe15aff0a3be34ab2128933c57 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 08:35:28 +0200 Subject: [PATCH 0874/1221] activate FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 27d728add..8f0573deb 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,7 +86,7 @@ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ +#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? -- GitLab From 563f5f5b326993e31557ddde5091dcfb24083f34 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:09:56 +0200 Subject: [PATCH 0875/1221] Revert "activate FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic" This reverts commit a28eea915544f8fe15aff0a3be34ab2128933c57. --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 8f0573deb..27d728add 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,7 +86,7 @@ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | //#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ +//#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? -- GitLab From 9a9bad211d9169230953123b80d8fa9b054228b5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:05 +0200 Subject: [PATCH 0876/1221] Revert "clang format patch" This reverts commit 94f1b674fd648b93a0914289537ac5c4df79e9ec. --- lib_com/swb_tbe_com_fx.c | 34 ++++++++++++++++------------------ lib_enc/swb_tbe_enc_fx.c | 21 +++++++++------------ 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 63cda170f..2099087e2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,18 +6696,18 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fx[], /* i : input signal Q_input_fx*/ + Word16 input_fx[], /* i : input signal Q_input_fx*/ #else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ + const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal memory_fx_Q */ - Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ + Word16 output_fx[], /* o : output signal memory_fx_Q */ + Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ Word16 memory_fx_Q[], - const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ + const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig , - const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ + const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ #endif ) { @@ -6883,14 +6883,14 @@ void elliptic_bpf_48k_generic_fx( #else FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } @@ -7194,19 +7194,17 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - 1 -#endif + , 1 +#endif ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - 1 -#endif + ,1 +#endif ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 4b0f5af57..707b0b5f8 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,11 +7330,10 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - 0 -#endif + ,0 +#endif ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; @@ -7464,20 +7463,18 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - 0 -#endif + ,0 +#endif ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - 0 -#endif + ,0 +#endif ); } -- GitLab From bddbb00d9d9c3361c1a2ee4fc0c7736c7e5ad6bb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:14 +0200 Subject: [PATCH 0877/1221] Revert "fic FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig/FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic, deactivate both" This reverts commit de9181e67e6964e6247aae01f2ebfa50e06325ee. --- lib_com/options.h | 4 +-- lib_com/swb_tbe_com_fx.c | 78 +++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 47 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 27d728add..58899a74b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,8 +85,8 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | +#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2099087e2..259680930 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6862,63 +6862,51 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - { + #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - IF( isUpsampledBy3 ) - { + IF( isUpsampledBy3 ) + { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) - { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + FOR( i = 0; i < L_FRAME48k; i++ ) #else - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + FOR( i = 4; i < L_FRAME48k; i++ ) #endif + { + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); } - ELSE + } + ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - { + { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) #else - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) #endif - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); } } + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; -- GitLab From e19417766ac4ba1fcd699d141d6a9466c040fbd9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:21 +0200 Subject: [PATCH 0878/1221] Revert "replace non-intuitive condition by intuitive one" This reverts commit 7c29e0fcda0a77f713dd7814cce8c1464bc0cf8d. --- lib_com/prot_fx.h | 4 ---- lib_com/swb_tbe_com_fx.c | 32 +++++++++++--------------------- lib_enc/swb_tbe_enc_fx.c | 18 +++--------------- 3 files changed, 14 insertions(+), 40 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c1ff2895b..13b6fe2d8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3268,10 +3268,6 @@ void elliptic_bpf_48k_generic_fx( Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ Word16 memory_fx_Q[], const Word16 full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ -#endif ); void synthesise_fb_high_band_fx( diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 259680930..4d22dda27 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,19 +6696,15 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fx[], /* i : input signal Q_input_fx*/ + Word16 input_fx[], /* i : input signal Q_input_fx*/ #else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ + const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal memory_fx_Q */ - Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ + Word16 output_fx[], /* o : output signal memory_fx_Q */ + Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ Word16 memory_fx_Q[], - const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , - const int isUpsampledBy3 /* i : input signal is upsampled by factor 3 by inserting zeros */ -#endif + const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) { Word16 i, j; @@ -6794,7 +6790,8 @@ void elliptic_bpf_48k_generic_fx( #if defined( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) - IF( isUpsampledBy3 ) + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { i = 4; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ @@ -6864,7 +6861,8 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - IF( isUpsampledBy3 ) + test(); + IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic FOR( i = 0; i < L_FRAME48k; i++ ) @@ -7180,20 +7178,12 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - , 1 -#endif - ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,1 -#endif - ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 707b0b5f8..ef499ad6a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,11 +7330,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,0 -#endif - ); + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7463,19 +7459,11 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,0 -#endif - ); + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - ,0 -#endif - ); + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From 2c9293c346144dca73a6c31682d4b026970ea1c3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:29 +0200 Subject: [PATCH 0879/1221] Revert "fix unused variable error" This reverts commit 97c8d64e0605051e876f31e6babc3dc5fcd21d06. --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 4d22dda27..bf425c066 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6718,8 +6718,8 @@ void elliptic_bpf_48k_generic_fx( #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; - Word32 memory2_fx_2[4], memory2_fx_3[4]; #endif + Word32 memory2_fx_2[4], memory2_fx_3[4]; FOR( i = 0; i < 4; i++ ) { -- GitLab From adaae746412c624118fa7efa0b74fdc4a7991388 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:35 +0200 Subject: [PATCH 0880/1221] Revert "clang format patch and fix preproc cmd" This reverts commit 707c22919241ee73a0313d49b041e560a7a97919. --- lib_com/swb_tbe_com_fx.c | 69 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bf425c066..3544cab74 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6733,7 +6733,7 @@ void elliptic_bpf_48k_generic_fx( memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); // useless? + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? #endif move32(); move32(); @@ -6743,53 +6743,53 @@ void elliptic_bpf_48k_generic_fx( } #ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #endif -#if defined( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) +#if defiend( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { @@ -6859,9 +6859,9 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - + #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); + test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic @@ -6905,6 +6905,7 @@ void elliptic_bpf_48k_generic_fx( } + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; @@ -7002,11 +7003,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + move32(); #else - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); #endif move32(); move32(); -- GitLab From da263e0a8b21315afa6d995f8e1d4522f91ee82f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:45 +0200 Subject: [PATCH 0881/1221] Revert "make upsampled work again - select only for correct filters" This reverts commit 3ad6e7e543ea7a6bfffbcb8032eb067b24c40c7f. --- lib_com/swb_tbe_com_fx.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 3544cab74..bdc947c7e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6859,10 +6859,6 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic FOR( i = 0; i < L_FRAME48k; i++ ) @@ -6870,27 +6866,18 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 4; i < L_FRAME48k; i++ ) #endif { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ - { -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) #else - FOR( i = 4; i < L_FRAME48k; i++ ) -#endif - { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6901,11 +6888,10 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif } } - - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; -- GitLab From fe148b9c1ce20f1456aa5b13b82c30c557ad4ac3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:51 +0200 Subject: [PATCH 0882/1221] Revert "more reintegrating loops and cleaning up - also fix - TBD: make upsampled work again - select only for correct filters" This reverts commit efe4596efd93a8668e536d65c9f8f746ffbd8908. --- lib_com/swb_tbe_com_fx.c | 56 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bdc947c7e..7ddd76842 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6998,7 +6998,19 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } -#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + //move32(); + //L_tmpMax = L_abs( L_output[0] ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7010,7 +7022,21 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7022,7 +7048,21 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + //L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7034,7 +7074,21 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 6593f4f1f1cc2f0adec85ce2ef15418d4294af91 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:10:57 +0200 Subject: [PATCH 0883/1221] Revert "make upsempledsig macro work again - tbd: cleanup" This reverts commit 0aa63c3ff3ea9d0fbbf507050019fd5e9ce048ab. --- lib_com/swb_tbe_com_fx.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7ddd76842..5702ef0f2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6866,18 +6866,6 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 4; i < L_FRAME48k; i++ ) #endif { -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#else L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6888,7 +6876,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif } } -- GitLab From ee542585bb8b2d205f2892f4081e60bc5deae1ec Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:11:03 +0200 Subject: [PATCH 0884/1221] Revert "clean up reintegratd loops - tbd: make upsempledsig macro work again" This reverts commit 7cf8b43a129509dafe5057e33dbea7dbb2d9b720. --- lib_com/swb_tbe_com_fx.c | 111 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5702ef0f2..eb8626354 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6742,7 +6742,18 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); +#else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6753,7 +6764,20 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); +#else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6764,7 +6788,20 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); +#else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6775,7 +6812,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif + + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //move32(); +#else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6888,8 +6940,18 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - -#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + //L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + //move32(); +#else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6900,7 +6962,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); +#endif + +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpMax = L_abs( L_tmp2[0] ); + //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //move32(); +#else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6912,7 +6989,20 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //move32(); +#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6924,7 +7014,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); +#endif +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + //L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + //move32(); + //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -- GitLab From 6c53bd6ea8f8fb08246f081402a687defd0f07e1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:11:10 +0200 Subject: [PATCH 0885/1221] Revert "reintegrate loops, cleaning tbd" This reverts commit f1d1be180b1b22ef1c677427589c3b4c307c3a05. --- lib_com/swb_tbe_com_fx.c | 268 +++++++++++++++++++-------------------- 1 file changed, 128 insertions(+), 140 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index eb8626354..e620290c4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6743,16 +6743,16 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6767,16 +6767,16 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6791,16 +6791,16 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6817,16 +6817,16 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //move32(); + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6841,7 +6841,7 @@ void elliptic_bpf_48k_generic_fx( #endif -#if defiend( FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig ) && !defined( FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic ) +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) { @@ -6912,11 +6912,7 @@ void elliptic_bpf_48k_generic_fx( ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) -#else FOR( i = 4; i < L_FRAME48k; i++ ) -#endif { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6941,16 +6937,16 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - //L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - //move32(); + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + move32(); #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6966,17 +6962,17 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpMax = L_abs( L_tmp2[0] ); - //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //move32(); + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); #else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6992,16 +6988,16 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - //L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); #else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7017,18 +7013,18 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - //L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - //L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7044,11 +7040,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); #endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) -#else FOR( i = 4; i < L_FRAME48k; i++ ) -#endif { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7091,17 +7083,17 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - //move32(); - //L_tmpMax = L_abs( L_output[0] ); + L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + move32(); + L_tmpMax = L_abs( L_output[0] ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7117,17 +7109,17 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7143,17 +7135,17 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - //L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7169,17 +7161,17 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - //L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - //move32(); - //L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7194,11 +7186,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); #endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < L_FRAME48k; i++ ) -#else FOR( i = 4; i < L_FRAME48k; i++ ) -#endif { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From 5f3aadb59778bf164c5684ef69b66cc9a8617f40 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:11:17 +0200 Subject: [PATCH 0886/1221] Revert "delete memory2_fx, memory_fx, memory2_fx_2, memory2_fx_3" This reverts commit 91bc9889207580a123c2e561e2a4a6e8e8e6824c. --- lib_com/swb_tbe_com_fx.c | 235 +++++++-------------------------------- 1 file changed, 40 insertions(+), 195 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e620290c4..5e3eb007f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6710,11 +6710,12 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *L_output = &L_output_buffer[0]; + Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; + Word16 *memory_fx = &input_fx[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6725,16 +6726,14 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); - input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + memory_fx[i] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); +#endif memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //useless? -#endif + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -6743,103 +6742,71 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif - - #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif - #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig test(); @@ -6936,18 +6903,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6958,22 +6913,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); -#endif - - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); -#else L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6985,20 +6924,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#endif - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); -#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7010,22 +6935,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#endif - -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#else L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7038,8 +6947,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#endif - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7070,31 +6977,12 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); -#else - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); -#endif + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); move32(); move32(); } -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7106,21 +6994,7 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7132,21 +7006,7 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7158,21 +7018,7 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); -#endif -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7184,7 +7030,6 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#endif FOR( i = 4; i < L_FRAME48k; i++ ) { -- GitLab From 8ea93bb69f1479cfcca377cf931dd8ce0611732f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:17:05 +0200 Subject: [PATCH 0887/1221] replace memory2_fx[1] by L_tmp[-4] --- lib_com/swb_tbe_com_fx.c | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5e3eb007f..d84be8fcc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6731,7 +6731,7 @@ void elliptic_bpf_48k_generic_fx( memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); #endif - memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); @@ -6753,10 +6753,10 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); @@ -6772,9 +6772,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic @@ -6789,8 +6789,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic @@ -6805,7 +6805,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig @@ -6903,10 +6903,10 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ @@ -6914,9 +6914,9 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ @@ -6925,8 +6925,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6936,7 +6936,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -- GitLab From 4bd709768e353df914f49fc625cc68c86dcb786f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:21:47 +0200 Subject: [PATCH 0888/1221] delete memory2_fx[] --- lib_com/swb_tbe_com_fx.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d84be8fcc..fa3293f31 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,7 +6714,6 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *memory2_fx[3] = { NULL, &L_tmp[-4], &L_tmp2[-4] }; Word16 *memory_fx = &input_fx[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; @@ -6732,7 +6731,7 @@ void elliptic_bpf_48k_generic_fx( memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); #endif L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); @@ -6908,10 +6907,10 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); L_tmpMax = L_abs( L_tmp2[0] ); L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6920,9 +6919,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); L_tmpX = L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6932,8 +6931,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6944,7 +6943,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); FOR( i = 4; i < L_FRAME48k; i++ ) -- GitLab From 2e44a40ee0c3a13df76efa757ca09779d2aa69c8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:27:49 +0200 Subject: [PATCH 0889/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 128 +++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index fa3293f31..c14877c2a 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6750,12 +6750,12 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); @@ -6767,13 +6767,13 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic @@ -6783,13 +6783,13 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #endif - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic @@ -6797,14 +6797,14 @@ void elliptic_bpf_48k_generic_fx( #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #endif - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig @@ -6902,48 +6902,48 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); FOR( i = 4; i < L_FRAME48k; i++ ) -- GitLab From 8bf813ae7b6bfbe7df581c6287a621220c80d125 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:28:39 +0200 Subject: [PATCH 0890/1221] replace memory_fx by input_fx[-4] and delete memory_fx --- lib_com/swb_tbe_com_fx.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c14877c2a..a0b00380e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,7 +6714,6 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word16 *memory_fx = &input_fx[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6725,7 +6724,7 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); - memory_fx[i] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); @@ -6741,10 +6740,10 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6760,9 +6759,9 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6777,8 +6776,8 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6793,7 +6792,7 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ #endif -- GitLab From 1523048c6db4c83b0b7ff43691cd0c652d435683 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:35:45 +0200 Subject: [PATCH 0891/1221] replace memory2_fx_2 with Ltmp2[-4] and delete memory2_fx_2 --- lib_com/swb_tbe_com_fx.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a0b00380e..901739af8 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6711,14 +6711,15 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; + Word32 memory2_fx_3[4]; Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; -#endif Word32 memory2_fx_2[4], memory2_fx_3[4]; +#endif FOR( i = 0; i < 4; i++ ) { @@ -6975,16 +6976,16 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); } - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ @@ -6993,9 +6994,9 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_abs( L_output[0] ); - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ @@ -7005,8 +7006,8 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ @@ -7017,7 +7018,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 832ee83e0b76a8a82d70a81551aaffbe1b2e351b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:39:16 +0200 Subject: [PATCH 0892/1221] repoint memory2_fx_3 to L_output[4] which points to L_output_buffer[0] which has a size of (L_FRAME48k + 4) elements --- lib_com/swb_tbe_com_fx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 901739af8..ea4e398b7 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6710,11 +6710,12 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output[L_FRAME48k], L_tmpX, L_tmpMax; - Word32 memory2_fx_3[4]; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; + Word32 *L_output = L_output_buffer[4]; + Word32 *memory2_fx_3 = L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; -- GitLab From e5909c8a6fa50dc7d6d6f04469503c850254cc4c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:44:04 +0200 Subject: [PATCH 0893/1221] replace memory2_fx_3 with L_output[-4] and delete memory2_fx_3 --- lib_com/swb_tbe_com_fx.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index ea4e398b7..2ff20d7b7 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6715,7 +6715,6 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; Word32 *L_output = L_output_buffer[4]; - Word32 *memory2_fx_3 = L_output[-4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; @@ -6978,7 +6977,7 @@ void elliptic_bpf_48k_generic_fx( FOR( j = 0; j < 4; j++ ) { L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -6988,10 +6987,10 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); @@ -7001,9 +7000,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); @@ -7014,8 +7013,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); @@ -7027,7 +7026,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -- GitLab From 67f9f2ccdf00dace12278242afd5e61097186f41 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 09:48:03 +0200 Subject: [PATCH 0894/1221] follow-up to 832ee83 : fix type error --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2ff20d7b7..79fa2c5d9 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,7 +6714,7 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *L_output = L_output_buffer[4]; + Word32 *L_output = &L_output_buffer[4]; #else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; -- GitLab From bdf812bdbfdb1398ba7606f7baab4ffa4a23dcba Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 10:06:07 +0200 Subject: [PATCH 0895/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 79fa2c5d9..c0c624e55 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6741,7 +6741,7 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6760,7 +6760,7 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else @@ -6777,7 +6777,7 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ #else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From a3807f9bd7cce0e96af354c38fbb45b36e2fb370 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 10:53:01 +0200 Subject: [PATCH 0896/1221] reintegrate loops - Upsampled-SPEEDUP not working --- Workspace_msvc/decoder.vcxproj | 344 +++++++------- Workspace_msvc/encoder.vcxproj | 354 +++++++-------- Workspace_msvc/lib_com.vcxproj | 680 ++++++++++++++-------------- Workspace_msvc/lib_debug.vcxproj | 240 +++++----- Workspace_msvc/lib_dec.vcxproj | 710 ++++++++++++++--------------- Workspace_msvc/lib_enc.vcxproj | 742 +++++++++++++++---------------- Workspace_msvc/lib_rend.vcxproj | 414 ++++++++--------- Workspace_msvc/lib_util.vcxproj | 312 ++++++------- Workspace_msvc/renderer.vcxproj | 358 +++++++-------- lib_com/swb_tbe_com_fx.c | 41 +- 10 files changed, 2092 insertions(+), 2103 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index ca0d96f44..c3a5a71d8 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,173 +1,173 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 9578e488d..75b13f9bd 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 7a2aa8a7f..337fc98e2 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 929dd72a8..b6a8a7dd3 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 2d06d29aa..60a24021f 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 86dcef905..7fe2ad96c 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index e47858ae3..10abdb438 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 86730b859..1cfb3e588 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 70a130e31..ecd8b04aa 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c0c624e55..bfef8a445 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6709,6 +6709,7 @@ void elliptic_bpf_48k_generic_fx( { Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#define elliptic_bpf_48k_generic_loopstart 0 Word16 memory_fx0, Q_temp, Q_temp2; Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; @@ -6716,6 +6717,7 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp2 = &L_tmp2_buffer[4]; Word32 *L_output = &L_output_buffer[4]; #else +#define elliptic_bpf_48k_generic_loopstart 4 Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; @@ -6740,34 +6742,22 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#else +#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#else + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6776,13 +6766,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6792,11 +6777,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -#else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6877,8 +6858,9 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ { - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6902,6 +6884,8 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); + +#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6946,7 +6930,9 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ + + FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6982,6 +6968,8 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } + +#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7029,8 +7017,9 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From 38f6813f2722952f262bb9179c27787e002745e5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 10:58:52 +0200 Subject: [PATCH 0897/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bfef8a445..1c8ba8ee5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6743,10 +6743,10 @@ void elliptic_bpf_48k_generic_fx( } #ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6755,9 +6755,9 @@ void elliptic_bpf_48k_generic_fx( move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6766,8 +6766,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6777,7 +6777,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 362d92bc1499a8181ddf5d93c0c1a862e9f73576 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:12:16 +0200 Subject: [PATCH 0898/1221] fix warning non-initialized L_tmpMax --- lib_com/swb_tbe_com_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1c8ba8ee5..e6919b0b6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6930,6 +6930,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#else + L_tmpMax = L_add( 0, 0 ); #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) @@ -7017,6 +7019,8 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#else + L_tmpMax = L_add( 0, 0 ); #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) -- GitLab From 373da4cf73ac8a6dc77b3097e82dbdd501624036 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:13:28 +0200 Subject: [PATCH 0899/1221] fix warning non-initialized L_tmp32, tmp16 --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e6919b0b6..bdaf47b69 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7189,8 +7189,8 @@ void synthesise_fb_high_band_fx( { #ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32; - Word16 tmp16; + Word32 L_tmp32 = L_add( 0, 0 ); + Word16 tmp16 = add( 0, 0 ); // if (L_tmp < 0) if ( L_tmp < 0 ) -- GitLab From 8c30014c3929668569850190b796ad6bd9e4a2f4 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:21:54 +0200 Subject: [PATCH 0900/1221] Revert "fix warning non-initialized L_tmp32, tmp16" This reverts commit 373da4cf73ac8a6dc77b3097e82dbdd501624036. --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bdaf47b69..e6919b0b6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7189,8 +7189,8 @@ void synthesise_fb_high_band_fx( { #ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32 = L_add( 0, 0 ); - Word16 tmp16 = add( 0, 0 ); + Word32 L_tmp32; + Word16 tmp16; // if (L_tmp < 0) if ( L_tmp < 0 ) -- GitLab From ac596390b751a3ede6bd9eb71875050d04c0bec3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:22:05 +0200 Subject: [PATCH 0901/1221] Revert "fix warning non-initialized L_tmpMax" This reverts commit 362d92bc1499a8181ddf5d93c0c1a862e9f73576. --- lib_com/swb_tbe_com_fx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e6919b0b6..1c8ba8ee5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6930,8 +6930,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#else - L_tmpMax = L_add( 0, 0 ); #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) @@ -7019,8 +7017,6 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#else - L_tmpMax = L_add( 0, 0 ); #endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) -- GitLab From e9394af140f4b0709742f3bb7c4ff12952d9722f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:22:29 +0200 Subject: [PATCH 0902/1221] Revert "clang format patch" This reverts commit 38f6813f2722952f262bb9179c27787e002745e5. --- lib_com/swb_tbe_com_fx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1c8ba8ee5..bfef8a445 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6743,10 +6743,10 @@ void elliptic_bpf_48k_generic_fx( } #ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6755,9 +6755,9 @@ void elliptic_bpf_48k_generic_fx( move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6766,8 +6766,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6777,7 +6777,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 884dbfd4231fd621ea073923ad827800d6045b5f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:22:45 +0200 Subject: [PATCH 0903/1221] Revert "reintegrate loops - Upsampled-SPEEDUP not working" This reverts commit a3807f9bd7cce0e96af354c38fbb45b36e2fb370. --- Workspace_msvc/decoder.vcxproj | 344 +++++++------- Workspace_msvc/encoder.vcxproj | 354 +++++++-------- Workspace_msvc/lib_com.vcxproj | 680 ++++++++++++++-------------- Workspace_msvc/lib_debug.vcxproj | 240 +++++----- Workspace_msvc/lib_dec.vcxproj | 710 ++++++++++++++--------------- Workspace_msvc/lib_enc.vcxproj | 742 +++++++++++++++---------------- Workspace_msvc/lib_rend.vcxproj | 414 ++++++++--------- Workspace_msvc/lib_util.vcxproj | 312 ++++++------- Workspace_msvc/renderer.vcxproj | 358 +++++++-------- lib_com/swb_tbe_com_fx.c | 41 +- 10 files changed, 2103 insertions(+), 2092 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index c3a5a71d8..ca0d96f44 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,173 +1,173 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 75b13f9bd..9578e488d 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 337fc98e2..7a2aa8a7f 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0 - - - - StaticLibrary - v143 - false - MultiByte - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index b6a8a7dd3..929dd72a8 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0 - - - - StaticLibrary - v143 - MultiByte - - - StaticLibrary - v143 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 60a24021f..2d06d29aa 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0 - - - StaticLibrary - v143 - false - MultiByte - - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 7fe2ad96c..86dcef905 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0 - - - - StaticLibrary - v143 - false - MultiByte - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 10abdb438..e47858ae3 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0 - - - StaticLibrary - v143 - false - MultiByte - - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 1cfb3e588..86730b859 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0 - - - - StaticLibrary - v143 - MultiByte - - - StaticLibrary - v143 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index ecd8b04aa..70a130e31 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bfef8a445..c0c624e55 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6709,7 +6709,6 @@ void elliptic_bpf_48k_generic_fx( { Word16 i, j; #ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic -#define elliptic_bpf_48k_generic_loopstart 0 Word16 memory_fx0, Q_temp, Q_temp2; Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; @@ -6717,7 +6716,6 @@ void elliptic_bpf_48k_generic_fx( Word32 *L_tmp2 = &L_tmp2_buffer[4]; Word32 *L_output = &L_output_buffer[4]; #else -#define elliptic_bpf_48k_generic_loopstart 4 Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; @@ -6742,22 +6740,34 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6766,8 +6776,13 @@ void elliptic_bpf_48k_generic_fx( L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6777,7 +6792,11 @@ void elliptic_bpf_48k_generic_fx( L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +#else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6858,9 +6877,8 @@ void elliptic_bpf_48k_generic_fx( } ELSE #endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ { - FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6884,8 +6902,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - -#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6930,9 +6946,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - - FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6968,8 +6982,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } - -#ifndef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7017,9 +7029,8 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - FOR( i = elliptic_bpf_48k_generic_loopstart; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From b013d8b3c6d3e8e9760349c69c189787429458c7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:47:17 +0200 Subject: [PATCH 0904/1221] change macros FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig and FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic to FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - unrolls still active, loops starting at 4. no speedup functionality yet --- lib_com/options.h | 5 +- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 250 +++++++++++++++++++++++---------------- lib_enc/swb_tbe_enc_fx.c | 4 +- 4 files changed, 157 insertions(+), 104 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 58899a74b..42ea9fce4 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,8 +85,9 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | - TBDeleted, code integrated in FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic +#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity *//*- TBDeleted, code integrated in FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 13b6fe2d8..8eb1a5c80 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,7 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 input_fx[], /* i : input signal Q_input_fx*/ #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c0c624e55..fd1a043e1 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6695,7 +6695,7 @@ void wb_tbe_extras_reset_synth_fx( *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 input_fx[], /* i : input signal Q_input_fx*/ #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -6708,7 +6708,7 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; @@ -6723,7 +6723,7 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 0; i < 4; i++ ) { -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); #else @@ -6740,49 +6740,75 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#else - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#else - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif /*FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); #else - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#endif + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6792,11 +6818,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -#else L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -#endif L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6806,77 +6828,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) - { - i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - FOR( ; i < L_FRAME48k; ) - { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { FOR( i = 4; i < L_FRAME48k; i++ ) { @@ -6902,6 +6855,8 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6946,6 +6901,52 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#else + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + move32(); + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#endif FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6982,6 +6983,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7029,6 +7031,56 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#else + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + move32(); + L_tmpMax = L_abs( L_output[0] ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + +#endif FOR( i = 4; i < L_FRAME48k; i++ ) { @@ -7113,7 +7165,7 @@ void synthesise_fb_high_band_fx( Word16 Qout ) { Word16 i, j; -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; #else diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index ef499ad6a..2d1e6b226 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7305,7 +7305,7 @@ void fb_tbe_enc_fx( Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 input_fhb_buffer[L_FRAME48k + 4]; Word16 *input_fhb = &input_fhb_buffer[0] + 4; #else @@ -7427,7 +7427,7 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; -#ifdef FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; #else -- GitLab From 9d02d6b3d7218ceb6a41f4444ccd4baafa21db32 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 11:48:56 +0200 Subject: [PATCH 0905/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index fd1a043e1..eb294ce4f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6741,40 +6741,40 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6818,7 +6818,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From ada8a986cf568a58e7fca4741e5394ee40b4fbd8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:02:27 +0200 Subject: [PATCH 0906/1221] integrate loops into speedup if and else branch --- lib_com/swb_tbe_com_fx.c | 103 +++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index eb294ce4f..2d8a94fb1 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6784,6 +6784,20 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6828,23 +6842,22 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif + + FOR( i = 4; i < L_FRAME48k; i++ ) { - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); } +#endif memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6901,6 +6914,21 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6946,21 +6974,22 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#endif + FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } +#endif + Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); @@ -7031,6 +7060,24 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7080,8 +7127,6 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#endif - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -7099,6 +7144,10 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } + +#endif + + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; -- GitLab From bbeea3d01908ccfa716a64677c4206cbf882af19 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:05:56 +0200 Subject: [PATCH 0907/1221] integrate loops into speedup if and else branch part 2 --- lib_com/swb_tbe_com_fx.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2d8a94fb1..045207844 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6741,6 +6741,8 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + int i = 0; + L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6751,6 +6753,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6762,6 +6765,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6773,6 +6777,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6784,8 +6789,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( ; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6870,6 +6876,8 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + int i = 0; + L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6880,7 +6888,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); + i++; L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6891,7 +6901,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + i++; L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6902,7 +6914,9 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + i++; L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6913,9 +6927,10 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); + i++; L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR( ; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7013,6 +7028,8 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + int i = 0; + L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7024,6 +7041,7 @@ void elliptic_bpf_48k_generic_fx( L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); L_tmpMax = L_abs( L_output[0] ); + i++; L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7036,6 +7054,7 @@ void elliptic_bpf_48k_generic_fx( L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + i++; L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ @@ -7048,6 +7067,7 @@ void elliptic_bpf_48k_generic_fx( L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + i++; L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7060,8 +7080,9 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + i++; - FOR( i = 4; i < L_FRAME48k; i++ ) + FOR(; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From ead5a949b11851cd312909773f9abff92f8f898c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:06:55 +0200 Subject: [PATCH 0908/1221] integrate loops into speedup if and else branch part 3 --- lib_com/swb_tbe_com_fx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 045207844..e89e25de8 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6697,6 +6697,7 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 input_fx[], /* i : input signal Q_input_fx*/ + int i; #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif @@ -6741,7 +6742,7 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - int i = 0; + i = 0; L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6876,7 +6877,7 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - int i = 0; + i = 0; L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7028,7 +7029,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - int i = 0; + i = 0; L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 95b2b85957ae2f96d722868458cc72b346513104 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:09:40 +0200 Subject: [PATCH 0909/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e89e25de8..808ac1495 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6701,7 +6701,7 @@ void elliptic_bpf_48k_generic_fx( #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif - Word16 *Q_input_fx, + Word16 * Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ Word16 memory_fx_Q[], @@ -7083,7 +7083,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); i++; - FOR(; i < L_FRAME48k; i++ ) + FOR( ; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From 60ccd1121e766b75c22d0e9e1c128b004a57c6de Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:10:25 +0200 Subject: [PATCH 0910/1221] fix build error --- lib_com/swb_tbe_com_fx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 808ac1495..2e3937c1b 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6697,7 +6697,6 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 input_fx[], /* i : input signal Q_input_fx*/ - int i; #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif -- GitLab From 146e7cd9e69115433cf667bdc2c0163285f29529 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:12:39 +0200 Subject: [PATCH 0911/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2e3937c1b..7f81060ef 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6700,7 +6700,7 @@ void elliptic_bpf_48k_generic_fx( #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ #endif - Word16 * Q_input_fx, + Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ Word16 memory_fx_Q[], -- GitLab From 3482733adc3f46e3b7b32130490d00a0982198ff Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:23:21 +0200 Subject: [PATCH 0912/1221] replace unrolled loop bodies by rolled ones - slight change: subs and adds alternate and saturate now --- lib_com/swb_tbe_com_fx.c | 232 +++++++++++++++++++-------------------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7f81060ef..466f11af5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6743,51 +6743,51 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic i = 0; - L_tmpX = L_shr( L_mult( input_fx[0 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[1 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[2 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[3 - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; @@ -6878,57 +6878,57 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic i = 0; - L_tmpX = L_shr( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); i++; - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); i++; - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); i++; - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); i++; - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); FOR( ; i < L_FRAME48k; i++ ) { @@ -7030,56 +7030,56 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic i = 0; - L_tmpX = L_shr( Mult_32_16( L_tmp2[0 - 4], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); - L_tmpMax = L_abs( L_output[0] ); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); i++; - L_tmpX = L_shr( Mult_32_16( L_tmp2[1 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); i++; - L_tmpX = L_shr( Mult_32_16( L_tmp2[2 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); i++; - L_tmpX = L_shr( Mult_32_16( L_tmp2[3 - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[3 - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); i++; FOR( ; i < L_FRAME48k; i++ ) -- GitLab From 58dc59bcc05d5d79a7b1a602e732b6055c5aab15 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:37:16 +0200 Subject: [PATCH 0913/1221] clang format patch --- lib_com/swb_tbe_com_fx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 466f11af5..5369972c5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7069,13 +7069,13 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); i++; - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); -- GitLab From 5813c00d8007d85875a08d8c372fef55afee6e8a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 12:39:26 +0200 Subject: [PATCH 0914/1221] fix warning uninitialized --- lib_com/swb_tbe_com_fx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5369972c5..b2223a174 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6710,7 +6710,8 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX, L_tmpMax; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; + Word32 L_tmpMax = L_add( 0, 0 ); Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; -- GitLab From 834a5383d1f5697814384c1d6212179afbc01ba5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 13:22:04 +0200 Subject: [PATCH 0915/1221] delete unnecessary unrolls --- lib_com/options.h | 16 ++-- lib_com/swb_tbe_com_fx.c | 164 +-------------------------------------- 2 files changed, 9 insertions(+), 171 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 42ea9fce4..6063c208a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,15 +80,11 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT -// -// new speedups -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | - TBDeleted, code integrated in FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic -#define FIX_1439_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity *//*- TBDeleted, code integrated in FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity */ - -#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares another speedup patch*/ + +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b2223a174..386b7285f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6742,57 +6742,7 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - i = 0; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - FOR( ; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6877,61 +6827,7 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - i = 0; - - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - i++; - - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - i++; - - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - i++; - - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - i++; - - FOR( ; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7029,61 +6925,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - i = 0; - - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - i++; - - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - i++; - - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - i++; - - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - i++; - - FOR( ; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ -- GitLab From 3ad19ded3976182c9c04b30e15b8d0dcd89236d1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 13:47:25 +0200 Subject: [PATCH 0916/1221] introduced STAGE2, but still not functional and inactive - implemented speedup for STAGE0 and activated --- lib_com/options.h | 5 +- lib_com/prot_fx.h | 4 ++ lib_com/swb_tbe_com_fx.c | 127 +++++++++++++++++++++++++++++++++++---- lib_enc/swb_tbe_enc_fx.c | 25 +++++++- 4 files changed, 145 insertions(+), 16 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 6063c208a..6b7dcd93d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -83,8 +83,9 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares another speedup patch*/ - #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / + #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 8eb1a5c80..702cdea12 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,11 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS; +#endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 386b7285f..76ae12e85 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6695,7 +6695,11 @@ void wb_tbe_extras_reset_synth_fx( *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS; +#endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ #else const Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -6742,19 +6746,57 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } +#else + IF( !IsUpsampled3 ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } + } + ELSE + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } + } +#endif #else L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6827,6 +6869,26 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + // L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#else FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6841,6 +6903,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } +#endif #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6925,6 +6988,30 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( 0 = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + // L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -6942,6 +7029,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } +#endif #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7108,12 +7196,29 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx + + ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx + ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 2d1e6b226..484b81742 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,7 +7330,14 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7459,11 +7466,23 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , 1 // IsUpsampled3 + , 1 // isIVAS +#endif + ); } test(); -- GitLab From e9ed6057fb87635180b9ba5248a63565f3cb9b12 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 13:51:31 +0200 Subject: [PATCH 0917/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 19 +++++++++---------- lib_enc/swb_tbe_enc_fx.c | 18 ++++++++++-------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 76ae12e85..34f6367ff 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6784,14 +6784,14 @@ void elliptic_bpf_48k_generic_fx( { FOR( i = 0; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } @@ -7217,8 +7217,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 #endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx - ); + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 484b81742..adcf85c54 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7466,22 +7466,24 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( + elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1 // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 + 0, // IsUpsampled3 #endif - input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , 1 // IsUpsampled3 - , 1 // isIVAS -#endif + , + 1 // IsUpsampled3 + , + 1 // isIVAS +#endif ); } -- GitLab From 3c7264633c174dea95b44d7ffa2c5f0b63234240 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 13:54:19 +0200 Subject: [PATCH 0918/1221] fix build error --- lib_enc/swb_tbe_enc_fx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index adcf85c54..be0dd84e5 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7477,14 +7477,14 @@ void fb_tbe_enc_ivas_fx( } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx + elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - 1 // IsUpsampled3 - , - 1 // isIVAS + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 #endif - ); + input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From 02fef875c959af3e8a45981a0c3b49526a26bbf9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 14:48:19 +0200 Subject: [PATCH 0919/1221] unrolled BEspeedup by 3 --- lib_com/swb_tbe_com_fx.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 34f6367ff..16ffc719e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6782,7 +6782,7 @@ void elliptic_bpf_48k_generic_fx( } ELSE { - FOR( i = 0; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k;) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6794,6 +6794,31 @@ void elliptic_bpf_48k_generic_fx( // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + i++; + + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; } } #endif -- GitLab From 1a17fbc2bf8327b882a47fbf3a1825e008c32c51 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 9 Apr 2025 14:50:36 +0200 Subject: [PATCH 0920/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 16ffc719e..16c35701e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6782,7 +6782,7 @@ void elliptic_bpf_48k_generic_fx( } ELSE { - FOR( i = 0; i < L_FRAME48k;) + FOR( i = 0; i < L_FRAME48k; ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6796,24 +6796,24 @@ void elliptic_bpf_48k_generic_fx( move32(); i++; - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -- GitLab From 7436e9696b190bd4af140cd645d42a2c9a033993 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 9 Apr 2025 16:40:06 +0200 Subject: [PATCH 0921/1221] adjust to new scripts in compare-to-input test --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d7de529a5..5950fa19b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -836,8 +836,8 @@ stages: # create summary - mkdir $IMAGES_ARTIFACT_NAME - - for MEASURE in MLD DIFF SSNR ODG;do python3 scripts/create_histogram_summary.py report-diff.csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE --diff; done - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME + - python3 scripts/create_histograms.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT --write-out-histograms --no-bins + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME --measures $MEASURES_FOR_REPORT - exit 0 -- GitLab From f2927e211fa53161b7e9876803c484efddd52577 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 9 Apr 2025 16:56:05 +0200 Subject: [PATCH 0922/1221] fix histogram command --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5950fa19b..b4a1405cd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -836,7 +836,7 @@ stages: # create summary - mkdir $IMAGES_ARTIFACT_NAME - - python3 scripts/create_histograms.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT --write-out-histograms --no-bins + - python3 scripts/create_histograms.py report-diff.csv $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT --write-out-histograms --no-bins - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME --measures $MEASURES_FOR_REPORT - exit 0 -- GitLab From 4e6d3527c28936f542a435eb303c22c52f0d4e2d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 9 Apr 2025 18:20:46 +0200 Subject: [PATCH 0923/1221] fix command again --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b4a1405cd..46e941af8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -837,7 +837,7 @@ stages: # create summary - mkdir $IMAGES_ARTIFACT_NAME - python3 scripts/create_histograms.py report-diff.csv $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT --write-out-histograms --no-bins - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME --measures $MEASURES_FOR_REPORT + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT - exit 0 -- GitLab From 8846449ac87119876446cc3e50c2df97201a1f4a Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 9 Apr 2025 20:40:32 +0200 Subject: [PATCH 0924/1221] [cleanup] remove FIX_867_CLDFB_NRG_SCALE_CLDFB --- lib_dec/ivas_dirac_dec_fx.c | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index d186de136..f6de75cfb 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2771,28 +2771,8 @@ void ivas_dirac_dec_render_sf_fx( { /* CLDFB Analysis*/ offset = i_mult( hSpatParamRendCom->num_freq_bands, index_slot ); -#ifdef FIX_867_CLDFB_NRG_SCALE_CLDFB - Word16 q_input; - Word32 sigTemp[MAX_TRANSPORT_CHANNELS][CLDFB_NO_CHANNELS_MAX]; - q_input = 4; - move16(); - FOR( ch = 0; ch < nchan_transport; ch++ ) - { - q_input = s_min( q_input, L_norm_arr( &st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], - hSpatParamRendCom->num_freq_bands ) ); - } FOR( ch = 0; ch < nchan_transport; ch++ ) { - Copy_Scale_sig32( &st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], - sigTemp[ch], - hSpatParamRendCom->num_freq_bands, - q_input ); - } - q_input = add( Q11, q_input ); -#endif - FOR( ch = 0; ch < nchan_transport; ch++ ) - { -#ifndef FIX_867_CLDFB_NRG_SCALE_CLDFB q_temp_cldfb = Q11; move16(); cldfbAnalysis_ts_fx_fixed_q( &st_ivas->hTcBuffer->tc_fx[hDirACRend->sba_map_tc[ch]][offset], @@ -2800,15 +2780,6 @@ void ivas_dirac_dec_render_sf_fx( Cldfb_ImagBuffer_fx[ch][0], hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch], &q_temp_cldfb ); -#else - q_temp_cldfb = q_input; - move16(); - cldfbAnalysis_ts_fx_var_q( sigTemp[ch], - Cldfb_RealBuffer_fx[ch][0], - Cldfb_ImagBuffer_fx[ch][0], - hSpatParamRendCom->num_freq_bands, - st_ivas->cldfbAnaDec[ch], &q_temp_cldfb ); -#endif } q_cldfb = q_temp_cldfb; move16(); -- GitLab From bb132b7c7db0ad2a5f0e380a68f9dc16671fc053 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 9 Apr 2025 20:44:06 +0200 Subject: [PATCH 0925/1221] [cleanup] remove code in #if 0 ... #endif --- lib_dec/ivas_dirac_dec_fx.c | 55 ------------------------------------- lib_rend/lib_rend.c | 18 ------------ 2 files changed, 73 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index f6de75cfb..38ad4ce04 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3283,60 +3283,6 @@ void ivas_dirac_dec_render_sf_fx( IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { #ifdef FIX_867_CLDFB_NRG_SCALE -#if 0 - IF( LT_16( q_reference_power_smooth[0], DirAC_mem.reference_power_q[0] ) ) - { - Word32 temp; - FOR( i = 0; i < s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) - { - temp = L_shl( reference_power_fx[i], sub( q_reference_power_smooth[0], DirAC_mem.reference_power_q[0] ) ); - reference_power_fx[i] = L_max(temp, L_min(reference_power_fx[i], 1)); - move32(); - } - DirAC_mem.reference_power_q[0] = q_reference_power_smooth[0]; - move16(); - } - ELSE - { - Word32 temp; - FOR( i = 0; i < s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) - { - temp = L_shl( reference_power_smooth_fx[i], sub( DirAC_mem.reference_power_q[0], q_reference_power_smooth[0] ) ); - reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); - move32(); - } - q_reference_power_smooth[0] = DirAC_mem.reference_power_q[0]; - move16(); - } - - IF( LT_16( q_reference_power_smooth[1], DirAC_mem.reference_power_q[1] ) ) - { - Word32 temp; - FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) - { - temp = L_shl( reference_power_fx[i], sub( q_reference_power_smooth[1], DirAC_mem.reference_power_q[1] ) ); - reference_power_fx[i] = L_max(temp, L_min(reference_power_fx[i], 1)); - move32(); - } - DirAC_mem.reference_power_q[1] = q_reference_power_smooth[1]; - move16(); - } - ELSE - { - Word32 temp; - FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) - { - temp = L_shl( reference_power_smooth_fx[i], sub( DirAC_mem.reference_power_q[1], q_reference_power_smooth[1] ) ); - reference_power_smooth_fx[i] = L_max(temp, L_min(reference_power_smooth_fx[i], 1)); - move32(); - } - q_reference_power_smooth[1] = DirAC_mem.reference_power_q[1]; - move16(); - } - v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); - q_reference_power_smooth[0] = sub( q_reference_power_smooth[0], 1 ); - q_reference_power_smooth[1] = sub( q_reference_power_smooth[1], 1 ); -#else v_add_fixed_me( reference_power_fx, sub( 31, DirAC_mem.reference_power_q[0] ), reference_power_smooth_fx, sub( 31, q_reference_power_smooth[0] ), reference_power_smooth_fx, &temp_q, @@ -3347,7 +3293,6 @@ void ivas_dirac_dec_render_sf_fx( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, &temp_q, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ); q_reference_power_smooth[1] = sub( 31, temp_q ); -#endif #else IF( LT_16( q_reference_power_smooth, DirAC_mem.reference_power_q ) ) { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a25037153..7e526ca77 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8444,14 +8444,6 @@ static void intermidiate_ext_dirac_render( IF( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx ) { #ifdef FIX_867_CLDFB_NRG_SCALE -#if 0 - /* Possible improvement: normalize both scale regions individually. */ - tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); - move16(); move16(); -#else tmp = 0; move16(); FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) @@ -8476,7 +8468,6 @@ static void intermidiate_ext_dirac_render( } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); move16(); -#endif #else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ @@ -8484,14 +8475,6 @@ static void intermidiate_ext_dirac_render( move16(); #endif #ifdef FIX_867_CLDFB_NRG_SCALE -#if 0 - /* Possible improvement: normalize both scale regions individually. */ - tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); - hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); - move16(); -#else tmp = 0; FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) { @@ -8513,7 +8496,6 @@ static void intermidiate_ext_dirac_render( } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); move16(); -#endif #else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ -- GitLab From 8f88f93b45658e8f6c07f0034b4b3030c69b93d1 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 9 Apr 2025 20:46:52 +0200 Subject: [PATCH 0926/1221] [cleanup] remove inactive code in FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE --- lib_com/options.h | 1 - lib_dec/ivas_dirac_dec_fx.c | 2 - lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 48 ------------------- 3 files changed, 51 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e5c7467a0..91ee90e2b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,7 +68,6 @@ #endif #define FIX_867_CLDFB_NRG_SCALE -//#define FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE #define FIX_1378_ACELP_OUT_OF_BOUNDS diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 38ad4ce04..bbd4641b1 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3656,7 +3656,6 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); move16(); -#ifndef FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) { FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) @@ -3693,7 +3692,6 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; move16(); } -#endif #else exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 44ddf8609..7b446a80e 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2247,53 +2247,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) ); -#ifdef FIX_867_CLDFB_NRG_SCALE_PROTO_NORESCALE - Word16 shift_prev0, shift_curr0, shift_prev1, shift_curr1; - shift_prev0 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0], h_dirac_output_synthesis_state->proto_power_smooth_q[0] ) ); - shift_curr0 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); - shift_prev1 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1], h_dirac_output_synthesis_state->proto_power_smooth_q[1] ) ); - shift_curr1 = s_max( 0, sub( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); - - FOR( k = 0; k < num_protos_dir; k++ ) - { - FOR( l = 0; l < s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ); l++ ) - { - g1 = alpha[l]; // Q31 - move32(); - g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 - *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev0 ) ) ); //(Q31, proto_power_smooth_q) -> proto_power_smooth_q - move32(); - *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), - L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr0 ) ); //(Q31, proto_power_smooth_q) -> min(proto_power_smooth_q, proto_power_smooth_prev_q) - move32(); - - L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ - exp_arr[k * num_freq_bands + l] = exp; - move16(); - - *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-min(proto_power_smooth_q, proto_power_smooth_prev_q)))*/ - move32(); - } - FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) - { - g1 = alpha[l]; // Q31 - move32(); - g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 - *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, L_shr( *p_power_smooth_prev, shift_prev1 ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth - move32(); - *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), - L_shr( Mpy_32_32( g1, ( *p_power_smooth ) ), shift_curr1 ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth - move32(); - - L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ - exp_arr[k * num_freq_bands + l] = exp; - move16(); - - *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-h_dirac_output_synthesis_state->proto_power_smooth_prev_q))*/ - move32(); - } - } -#else FOR( k = 0; k < num_protos_dir; k++ ) { FOR( l = 0; l < num_freq_bands; l++ ) @@ -2333,7 +2286,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( } } } -#endif // Move proto_power_smooth_fx to common Q-factor -- GitLab From f5a6d8c16ceade57b154badb6b9998a5d70e11d3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 08:50:45 +0200 Subject: [PATCH 0927/1221] fix error in unrolled upsampled3 functionality --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 16c35701e..f3ce08a93 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6810,7 +6810,7 @@ void elliptic_bpf_48k_generic_fx( // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 6dcde3530c81a763aa2f3204ecaf6df5a61de6fe Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 08:59:36 +0200 Subject: [PATCH 0928/1221] apply clang format patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index f3ce08a93..b0047802d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6810,7 +6810,7 @@ void elliptic_bpf_48k_generic_fx( // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 74d86e358fa5dbc771e10ab63d8c9a0bc6d23e65 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 09:18:05 +0200 Subject: [PATCH 0929/1221] deactivate upsampled3 --- lib_com/swb_tbe_com_fx.c | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b0047802d..215f2a84f 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6716,6 +6716,10 @@ void elliptic_bpf_48k_generic_fx( Word16 memory_fx0, Q_temp, Q_temp2; Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; Word32 L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + Word64 W_tmpX; + Word64 W_tmpY; +#endif Word32 *L_tmp = &L_tmp_buffer[4]; Word32 *L_tmp2 = &L_tmp2_buffer[4]; @@ -6746,28 +6750,24 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - } -#else - IF( !IsUpsampled3 ) + IF( 1 /* !IsUpsampled3*/ ) { FOR( i = 0; i < L_FRAME48k; i++ ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6778,6 +6778,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } } ELSE @@ -6806,7 +6807,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - i++; + i++; // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6821,8 +6822,7 @@ void elliptic_bpf_48k_generic_fx( i++; } } -#endif -#else +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6881,7 +6881,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } -#endif +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; -- GitLab From 61bcd699753813516bbe7124b2598c0429c7643b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 09:20:11 +0200 Subject: [PATCH 0930/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 215f2a84f..de843d9ed 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6755,7 +6755,7 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 0; i < L_FRAME48k; i++ ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); @@ -6767,7 +6767,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6807,7 +6807,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - i++; + i++; // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6822,7 +6822,7 @@ void elliptic_bpf_48k_generic_fx( i++; } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 169b2dcb971e696a01b785c9e5b65b17afb507e3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 09:22:46 +0200 Subject: [PATCH 0931/1221] fix unused variable error --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index de843d9ed..a1866d831 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6750,7 +6750,7 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - IF( 1 /* !IsUpsampled3*/ ) + IF( 1 || !IsUpsampled3 ) { FOR( i = 0; i < L_FRAME48k; i++ ) { -- GitLab From 21a7f761078722c6c18d4d43ed07f3890571ca53 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 09:57:25 +0200 Subject: [PATCH 0932/1221] fix and activate upsampled3 --- lib_com/swb_tbe_com_fx.c | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a1866d831..8d5cdfcda 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6750,7 +6750,7 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - IF( 1 || !IsUpsampled3 ) + IF( !IsUpsampled3 ) { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6785,38 +6785,38 @@ void elliptic_bpf_48k_generic_fx( { FOR( i = 0; i < L_FRAME48k; ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; -- GitLab From cdc6a0c27c0465e84f8d02475938a77f407d92c5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 10:25:12 +0200 Subject: [PATCH 0933/1221] move stage2 code into loops --- lib_com/swb_tbe_com_fx.c | 115 ++++++++++++++++++++++++--------------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8d5cdfcda..a71251ba4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6785,41 +6785,82 @@ void elliptic_bpf_48k_generic_fx( { FOR( i = 0; i < L_FRAME48k; ) { - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; +#else + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - //L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - //L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } } #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ @@ -6894,11 +6935,9 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { - Word64 W_tmpX; - Word64 W_tmpY; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); @@ -6908,14 +6947,10 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - // L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } -#else - FOR( i = 0; i < L_FRAME48k; i++ ) - { +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ @@ -6927,8 +6962,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } -#endif #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7013,32 +7048,22 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( 0 = 4; i < L_FRAME48k; i++ ) + FOR( i = 0; i < L_FRAME48k; i++ ) { - Word64 W_tmpX; - Word64 W_tmpY; - +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - // L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#else - FOR( i = 0; i < L_FRAME48k; i++ ) - { +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ @@ -7053,8 +7078,8 @@ void elliptic_bpf_48k_generic_fx( L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } -#endif #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 4b91e6417af3003e1d4010668693331211a89fc3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 10:33:37 +0200 Subject: [PATCH 0934/1221] Delete unused code within upsampled3-section --- lib_com/swb_tbe_com_fx.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a71251ba4..520aa67ea 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6786,12 +6786,9 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 0; i < L_FRAME48k; ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); @@ -6800,37 +6797,27 @@ void elliptic_bpf_48k_generic_fx( i++; W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; #else - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6838,25 +6825,18 @@ void elliptic_bpf_48k_generic_fx( i++; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; -- GitLab From 171201666215606eb2f1f75d7725bdd6745d7ab3 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 10:42:10 +0200 Subject: [PATCH 0935/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 520aa67ea..7b1fe9cd2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6815,28 +6815,28 @@ void elliptic_bpf_48k_generic_fx( move32(); i++; #else - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; -- GitLab From 57b563d4c0df7df61d76f4411f6d22b17c76e8aa Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 11:19:11 +0200 Subject: [PATCH 0936/1221] place a FOR loop identifier in every preproc branch --- lib_com/swb_tbe_com_fx.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7b1fe9cd2..7baa27b75 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6752,9 +6752,9 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic IF( !IsUpsampled3 ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); @@ -6767,7 +6767,10 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6778,14 +6781,14 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } ELSE { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); @@ -6814,7 +6817,10 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); i++; + } #else + FOR( i = 0; i < L_FRAME48k; ) + { L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6840,8 +6846,8 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); i++; -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6915,9 +6921,9 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); @@ -6930,7 +6936,10 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ @@ -6942,8 +6951,9 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + #else L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7028,9 +7038,9 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); @@ -7043,7 +7053,10 @@ void elliptic_bpf_48k_generic_fx( L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ @@ -7058,8 +7071,8 @@ void elliptic_bpf_48k_generic_fx( L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ #else L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 0d7b5ddcc64a15b6a1a769f3eb84f7be68d4720a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 31 Mar 2025 21:08:44 +0530 Subject: [PATCH 0937/1221] Fix for 3GPP issue 1449: Complexity measurement crashes: OMASA encoder Link #1449 --- lib_enc/ivas_masa_enc_fx.c | 56 ++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 2f060f681..2b9ffef15 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -2297,7 +2297,9 @@ static void reduce_metadata_further_fx( UWord8 computeCoherence; Word32 onset_filter; Word16 onset_filter_e, exp; - Word32 bandEnergy; + Word64 bandEnergy; + Word32 bandEnergy32; + Word16 bandEnergy_exp, shift; UWord8 mergeOverFreqBands; Word32 meanRatio; Word16 tmp, tmp2; @@ -2437,13 +2439,16 @@ static void reduce_metadata_further_fx( move32(); bandEnergy = 0; - move32(); + move64(); FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { - bandEnergy = L_add( bandEnergy, energy[sf][band] ); + bandEnergy = W_mac_32_32( bandEnergy, energy[sf][band], 1 ); } + shift = W_norm( bandEnergy ); + bandEnergy32 = W_extract_h( W_shl( bandEnergy, shift ) ); + bandEnergy_exp = sub( 63, add( add( hMasa->data.q_energy, 1 ), shift ) ); - IF( BASOP_Util_Cmp_Mant32Exp( Mpy_32_32( L_shr( bandEnergy, 2 ), bandRatio ), sub( 31 + 1, hMasa->data.q_energy ), threshold, exp ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( Mpy_32_32( L_shr( bandEnergy32, 2 ), bandRatio ), add( 1, bandEnergy_exp ), threshold, exp ) > 0 ) { selectedBand = band; move16(); @@ -4640,7 +4645,9 @@ static void ivas_encode_masaism_metadata_fx( UWord8 numCodingBands; UWord8 numSf; Word16 brange[2]; - Word32 eneBand; + Word64 eneBand; + Word32 eneBand32; + Word16 eneBand_exp, shift; Word16 bin; Word16 obj; Word16 bits_ism[MAX_NUM_OBJECTS]; @@ -4689,11 +4696,14 @@ static void ivas_encode_masaism_metadata_fx( eneBand = 0; move16(); move16(); - move32(); + move64(); FOR( bin = brange[0]; bin < brange[1]; bin++ ) { - eneBand = L_add( eneBand, hMasa->data.energy_fx[sf][bin] ); // hMasa->data.q_energy + eneBand = W_mac_32_32( eneBand, hMasa->data.energy_fx[sf][bin], 1 ); // hMasa->data.q_energy + 1 } + shift = W_norm( eneBand ); + eneBand32 = W_extract_h( W_shl( eneBand, shift ) ); + eneBand_exp = sub( 63, add( add( hMasa->data.q_energy, 1 ), shift ) ); energy_ism = 0; energy_ism_e = 0; @@ -4727,12 +4737,12 @@ static void ivas_encode_masaism_metadata_fx( hOmasaData->energy_ratio_ism_fx[sf][0][obj] = L_shl( hOmasaData->energy_ratio_ism_fx[sf][0][obj], sub( L_tmp_e, 1 ) ); // Q30 move32(); } - L_tmp = BASOP_Util_Add_Mant32Exp( eneBand, sub( 31, hMasa->data.q_energy ), energy_ism, energy_ism_e, &L_tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( eneBand32, eneBand_exp, energy_ism, energy_ism_e, &L_tmp_e ); IF( L_tmp != 0 ) { - hOmasaData->masa_to_total_energy_ratio_fx[sf][0] = BASOP_Util_Divide3232_Scale_cadence( eneBand, L_tmp, &tmp ); + hOmasaData->masa_to_total_energy_ratio_fx[sf][0] = BASOP_Util_Divide3232_Scale_cadence( eneBand32, L_tmp, &tmp ); move32(); - tmp = add( tmp, sub( sub( 31, hMasa->data.q_energy ), L_tmp_e ) ); + tmp = add( tmp, sub( eneBand_exp, L_tmp_e ) ); /* Scaling to Q30 */ hOmasaData->masa_to_total_energy_ratio_fx[sf][0] = L_shl( hOmasaData->masa_to_total_energy_ratio_fx[sf][0], sub( tmp, 1 ) ); // Q30 move32(); @@ -4794,21 +4804,24 @@ static void ivas_encode_masaism_metadata_fx( move16(); eneBand = 0; - move32(); + move64(); FOR( sf = 0; sf < omasa_nblocks; sf++ ) { FOR( bin = brange[0]; bin < brange[1]; bin++ ) { - eneBand = L_add( eneBand, hMasa->data.energy_fx[sf][bin] ); // hMasa->data.q_energy + eneBand = W_mac_32_32( eneBand, hMasa->data.energy_fx[sf][bin], 1 ); // hMasa->data.q_energy + 1 } } + shift = W_norm( eneBand ); + eneBand32 = W_extract_h( W_shl( eneBand, shift ) ); + eneBand_exp = sub( 63, add( add( hMasa->data.q_energy, 1 ), shift ) ); - L_tmp = BASOP_Util_Add_Mant32Exp( eneBand, sub( 31, hMasa->data.q_energy ), energy_ism, energy_ism_e, &L_tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( eneBand32, eneBand_exp, energy_ism, energy_ism_e, &L_tmp_e ); IF( L_tmp != 0 ) { - hOmasaData->masa_to_total_energy_ratio_fx[0][band] = BASOP_Util_Divide3232_Scale_cadence( eneBand, L_tmp, &tmp ); + hOmasaData->masa_to_total_energy_ratio_fx[0][band] = BASOP_Util_Divide3232_Scale_cadence( eneBand32, L_tmp, &tmp ); move32(); - tmp = add( tmp, sub( sub( 31, hMasa->data.q_energy ), L_tmp_e ) ); + tmp = add( tmp, sub( eneBand_exp, L_tmp_e ) ); /* Scaling to Q30 */ hOmasaData->masa_to_total_energy_ratio_fx[0][band] = L_shl( hOmasaData->masa_to_total_energy_ratio_fx[0][band], sub( tmp, 1 ) ); // Q30 move32(); @@ -4851,18 +4864,21 @@ static void ivas_encode_masaism_metadata_fx( move16(); eneBand = 0; - move32(); + move64(); FOR( bin = brange[0]; bin < brange[1]; bin++ ) { - eneBand = L_add( eneBand, hMasa->data.energy_fx[sf][bin] ); // hMasa->data.q_energy + eneBand = W_mac_32_32( eneBand, hMasa->data.energy_fx[sf][bin], 1 ); // hMasa->data.q_energy + 1 } + shift = W_norm( eneBand ); + eneBand32 = W_extract_h( W_shl( eneBand, shift ) ); + eneBand_exp = sub( 63, add( add( hMasa->data.q_energy, 1 ), shift ) ); - L_tmp = BASOP_Util_Add_Mant32Exp( eneBand, sub( 31, hMasa->data.q_energy ), hOmasaData->energy_ism_fx[sf][band], hOmasaData->energy_ism_fx_e[sf][band], &L_tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( eneBand32, eneBand_exp, hOmasaData->energy_ism_fx[sf][band], hOmasaData->energy_ism_fx_e[sf][band], &L_tmp_e ); IF( L_tmp != 0 ) { - hOmasaData->masa_to_total_energy_ratio_fx[sf][band] = BASOP_Util_Divide3232_Scale_cadence( eneBand, L_tmp, &tmp ); + hOmasaData->masa_to_total_energy_ratio_fx[sf][band] = BASOP_Util_Divide3232_Scale_cadence( eneBand32, L_tmp, &tmp ); move32(); - tmp = add( tmp, sub( sub( 31, hMasa->data.q_energy ), L_tmp_e ) ); + tmp = add( tmp, sub( eneBand_exp, L_tmp_e ) ); /* Scaling to Q30 */ hOmasaData->masa_to_total_energy_ratio_fx[sf][band] = L_shl( hOmasaData->masa_to_total_energy_ratio_fx[sf][band], sub( tmp, 1 ) ); // Q30 move32(); -- GitLab From d41a00b7701d562e031629d9f028e37add6d356e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 11:59:52 +0200 Subject: [PATCH 0938/1221] deactivate STAGE2 and func1 - implement func1 --- lib_com/options.h | 1 + lib_com/swb_tbe_com_fx.c | 133 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 6b7dcd93d..35d09abf5 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -87,5 +87,6 @@ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 7baa27b75..bff330286 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6687,6 +6687,112 @@ void wb_tbe_extras_reset_synth_fx( return; } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 L_tmpMax ) +{ + Word32 L_tmpX; + Word16 i; + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } +#else + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } +#endif + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -6715,7 +6821,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; - Word32 L_tmpMax = L_add( 0, 0 ); + Word32 L_tmpMax; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word64 W_tmpX; Word64 W_tmpY; @@ -6750,6 +6856,10 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -6783,7 +6893,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } + } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -6848,7 +6958,9 @@ void elliptic_bpf_48k_generic_fx( i++; } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } + } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6921,6 +7033,10 @@ void elliptic_bpf_48k_generic_fx( move32(); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6953,8 +7069,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - -#else +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7038,6 +7154,10 @@ void elliptic_bpf_48k_generic_fx( move32(); } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); +#else #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7073,7 +7193,8 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ -#else +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 60212ef02f092f66dd92147fb54af52b90f920e2 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 12:09:07 +0200 Subject: [PATCH 0939/1221] implement maxabs in func1, STAGE2 and func1 still inactive --- lib_com/swb_tbe_com_fx.c | 72 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index bff330286..2974ccac1 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6688,10 +6688,13 @@ void wb_tbe_extras_reset_synth_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 L_tmpMax ) +inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) { Word32 L_tmpX; Word16 i; + Word32 L_tmpMax2 = *L_tmpMax; + Word32 L_tmpAbs; + move32(); IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -6708,6 +6711,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } } #else FOR( i = 0; i < L_FRAME48k; i++ ) @@ -6722,6 +6733,15 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } #endif } /*IsUpsampled3*/ @@ -6738,6 +6758,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } i++; W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); @@ -6748,6 +6776,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } i++; W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); @@ -6757,6 +6793,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } i++; } #else @@ -6769,6 +6813,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } i++; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6778,6 +6830,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } i++; L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6786,10 +6846,20 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } i++; } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -- GitLab From 090be8f36fd988d1aebf50bcf1c3ee50569139e0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 12:11:20 +0200 Subject: [PATCH 0940/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 239 +++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 120 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2974ccac1..f1492b0b4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6723,14 +6723,14 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t #else FOR( i = 0; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); if ( L_tmpMax > 0 ) @@ -6741,125 +6741,124 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } - } #endif - } /*IsUpsampled3*/ - ELSE - { /*IsUpsampled3*/ + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } + i++; + } #else - FOR( i = 0; i < L_FRAME48k; ) + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ - *L_tmpMax = L_tmpMax2; - move32(); + } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ @@ -6948,7 +6947,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7140,7 +7139,7 @@ void elliptic_bpf_48k_generic_fx( } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7264,7 +7263,7 @@ void elliptic_bpf_48k_generic_fx( } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 3ef8c26d6355b9709fac7a0609dcdf15a28c1afb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 10 Apr 2025 16:20:22 +0530 Subject: [PATCH 0941/1221] Fix for decoder crash --- lib_dec/igf_dec_fx.c | 100 +++++++++++++------------------------------ 1 file changed, 30 insertions(+), 70 deletions(-) diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 60e649a08..0010b9466 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -123,8 +123,8 @@ return noise; } static Word16 ivas_IGF_replaceTCXNoise_1_fx( /**< out: Q0 | number of noise bands */ - const Word32 *in, /**< in: Q31 | MDCT spectrum */ - Word16 s_l, /**< in: Q0 | noise headroom */ + const Word32 *in, /**< in: in_exp | MDCT spectrum */ + Word16 in_exp, /**< in: Q0 | noise headroom */ const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */ const Word16 start, /**< in: Q0 | start MDCT subband index */ const Word16 stop, /**< in: Q0 | stop MDCT subband index */ @@ -132,41 +132,44 @@ static Word16 ivas_IGF_replaceTCXNoise_1_fx( /**< out: Q Word16 *totalNoiseNrg_exp ) { Word16 sb; - Word16 tmp16; + Word16 tmp16, shift; Word16 noise; + Word32 tmp32; Word64 nE; - tmp16 = 0; + shift = 2; move16(); noise = 0; move16(); - s_l = sub( s_l, 5 ); nE = 0; move64(); + *totalNoiseNrg = 0; + move32(); + *totalNoiseNrg_exp = 0; + move16(); + FOR( sb = start; sb < stop; sb++ ) { IF( TCXNoise[sb] ) { - tmp16 = extract_h( L_shl( in[sb], s_l ) ); // Q31 + s_l - } - IF( TCXNoise[sb] ) - { - nE = W_mac_16_16( nE, tmp16, tmp16 ); // Q31 + s_l - } - IF( TCXNoise[sb] ) - { - noise = add( noise, 1 ); // Q0 + tmp32 = L_shr( in[sb], shift ); + nE = W_mac_32_32( nE, tmp32, tmp32 ); // 62 - (in_exp + shift + in_exp + shift + 1) + noise = add( noise, 1 ); } } - tmp16 = W_norm( nE ); - nE = W_shl( nE, tmp16 ); - *totalNoiseNrg = W_extract_h( nE ); - move32(); - *totalNoiseNrg_exp = sub( tmp16, 32 ); - move16(); + IF( nE ) + { + tmp16 = W_norm( nE ); + nE = W_shl( nE, tmp16 ); + *totalNoiseNrg = W_extract_h( nE ); + move32(); + *totalNoiseNrg_exp = sub( add( shl( shift, 1 ), shl( in_exp, 1 ) ), tmp16 ); + move16(); + } + return noise; } @@ -3533,14 +3536,8 @@ void IGFDecApplyMono_ivas( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in specMed_e = igf_spec_e[i]; move16(); - /*14 seems to be precise enough*/ - hPrivateData->headroom_TCX_noise_white = IGF_getScaleFactor32Cond( - hInstance->infoTCXNoise_ptr, - igf_spec + hGrid->minSrcSubband, - sub( hGrid->startLine, hGrid->minSrcSubband ) ); - move16(); hPrivateData->n_noise_bands = ivas_IGF_replaceTCXNoise_1_fx( igf_spec, - hPrivateData->headroom_TCX_noise_white, + igf_spec_e[i], hInstance->infoTCXNoise_ptr, hGrid->minSrcSubband, hGrid->startLine, @@ -3548,9 +3545,6 @@ void IGFDecApplyMono_ivas( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in &hPrivateData->totalNoiseNrg_exp ); move16(); - hPrivateData->totalNoiseNrg_exp = sub( shl( sub( igf_spec_e[i], sub( hPrivateData->headroom_TCX_noise_white, 5 ) ), 1 ), hPrivateData->totalNoiseNrg_exp ); - move16(); - BREAK; } } @@ -3560,22 +3554,15 @@ void IGFDecApplyMono_ivas( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in { IF( EQ_16( hPrivateData->currWhiteningLevel[i], IGF_WHITENING_OFF ) ) { - hPrivateData->headroom_TCX_noise = IGF_getScaleFactor32Cond( - hInstance->infoTCXNoise_ptr, - hPrivateData->pSpecFlat + hGrid->minSrcSubband, - sub( hGrid->startLine, hGrid->minSrcSubband ) ); - move16(); hPrivateData->n_noise_bands_off = ivas_IGF_replaceTCXNoise_1_fx( hPrivateData->pSpecFlat, - hPrivateData->headroom_TCX_noise, + hPrivateData->pSpecFlat_exp, hInstance->infoTCXNoise_ptr, hGrid->minSrcSubband, hGrid->startLine, &hPrivateData->totalNoiseNrg_off, &hPrivateData->totalNoiseNrg_off_exp ); move16(); - hPrivateData->totalNoiseNrg_off_exp = sub( shl( sub( hPrivateData->pSpecFlat_exp, sub( hPrivateData->headroom_TCX_noise, 5 ) ), 1 ), hPrivateData->totalNoiseNrg_off_exp ); - move16(); BREAK; } } @@ -3760,12 +3747,9 @@ void IGFDecApplyStereo( move16(); } - hPrivateDataL->headroom_TCX_noise_white = IGF_getScaleFactor32Cond( hIGFDecL->infoTCXNoise_ptr + hGrid->minSrcSubband, - igf_specL_fx + hGrid->minSrcSubband, - sub( hGrid->startLine, hGrid->minSrcSubband ) ); - move16(); + hPrivateDataL->n_noise_bands = ivas_IGF_replaceTCXNoise_1_fx( igf_specL_fx, - hPrivateDataL->headroom_TCX_noise_white, + specMedL_e, hIGFDecL->infoTCXNoise_ptr, hGrid->minSrcSubband, hGrid->startLine, @@ -3773,9 +3757,6 @@ void IGFDecApplyStereo( &hPrivateDataL->totalNoiseNrg_exp ); move16(); - hPrivateDataL->totalNoiseNrg_exp = sub( shl( sub( specMedL_e, sub( hPrivateDataL->headroom_TCX_noise_white, 5 ) ), 1 ), hPrivateDataL->totalNoiseNrg_exp ); - move16(); - IF( !bfi ) { s_l = getScaleFactor32( hPrivateDataR->pSpecFlat + hGrid->minSrcSubband - whiteningLevel, @@ -3796,21 +3777,14 @@ void IGFDecApplyStereo( move16(); } - hPrivateDataR->headroom_TCX_noise_white = IGF_getScaleFactor32Cond( hIGFDecR->infoTCXNoise_ptr, - igf_specR_fx + hGrid->minSrcSubband, - sub( hGrid->startLine, hGrid->minSrcSubband ) ); - move16(); hPrivateDataR->n_noise_bands = ivas_IGF_replaceTCXNoise_1_fx( igf_specR_fx, - hPrivateDataR->headroom_TCX_noise_white, + specMedR_e, hIGFDecR->infoTCXNoise_ptr, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataR->totalNoiseNrg, &hPrivateDataR->totalNoiseNrg_exp ); move16(); - hPrivateDataR->totalNoiseNrg_exp = sub( shl( sub( specMedR_e, sub( hPrivateDataR->headroom_TCX_noise_white, 5 ) ), 1 ), hPrivateDataR->totalNoiseNrg_exp ); - move16(); - BREAK; } } @@ -3820,37 +3794,23 @@ void IGFDecApplyStereo( test(); IF( EQ_16( hPrivateDataL->currWhiteningLevel[i], IGF_WHITENING_OFF ) || EQ_16( hPrivateDataR->currWhiteningLevel[i], IGF_WHITENING_OFF ) ) { - hPrivateDataL->headroom_TCX_noise_white = IGF_getScaleFactor32Cond( hIGFDecL->infoTCXNoise_ptr + hGrid->minSrcSubband, - hPrivateDataL->pSpecFlat + hGrid->minSrcSubband, - sub( hGrid->startLine, hGrid->minSrcSubband ) ); hPrivateDataL->n_noise_bands_off = ivas_IGF_replaceTCXNoise_1_fx( hPrivateDataL->pSpecFlat, - hPrivateDataL->headroom_TCX_noise_white, + hPrivateDataL->pSpecFlat_exp, hIGFDecL->infoTCXNoise_ptr, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataL->totalNoiseNrg_off, &hPrivateDataL->totalNoiseNrg_off_exp ); - hPrivateDataL->totalNoiseNrg_off_exp = sub( shl( sub( hPrivateDataL->pSpecFlat_exp, sub( hPrivateDataL->headroom_TCX_noise_white, 5 ) ), 1 ), hPrivateDataL->totalNoiseNrg_off_exp ); - move16(); - move16(); move16(); - hPrivateDataR->headroom_TCX_noise_white = IGF_getScaleFactor32Cond( hIGFDecR->infoTCXNoise_ptr, - hPrivateDataR->pSpecFlat + hGrid->minSrcSubband, - sub( hGrid->startLine, hGrid->minSrcSubband ) ); hPrivateDataR->n_noise_bands_off = ivas_IGF_replaceTCXNoise_1_fx( hPrivateDataR->pSpecFlat, - hPrivateDataR->headroom_TCX_noise_white, + hPrivateDataR->pSpecFlat_exp, hIGFDecR->infoTCXNoise_ptr, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataR->totalNoiseNrg_off, &hPrivateDataR->totalNoiseNrg_off_exp ); - hPrivateDataR->totalNoiseNrg_off_exp = sub( shl( sub( hPrivateDataR->pSpecFlat_exp, sub( hPrivateDataR->headroom_TCX_noise_white, 5 ) ), 1 ), hPrivateDataR->totalNoiseNrg_off_exp ); - move16(); - move16(); move16(); - - BREAK; } } -- GitLab From 2294ff5ff00a5425cf0136481de99a58b042d265 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:00:38 +0200 Subject: [PATCH 0942/1221] swb_tbe_com: coments general: use ISAVAS information to switch STAGE2 on and off --- lib_com/prot_fx.h | 6 +++++- lib_com/swb_tbe_com_fx.c | 20 ++++++++++++-------- lib_dec/swb_tbe_dec_fx.c | 12 ++++++++++-- lib_enc/swb_tbe_enc_fx.c | 6 +++--- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 702cdea12..a230a83c7 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3285,7 +3285,11 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ); + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , Word16 isIVAS +#endif +); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index f1492b0b4..8977dae08 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6926,9 +6926,9 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -7103,9 +7103,9 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7226,7 +7226,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7396,7 +7396,11 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ) + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , Word16 isIVAS +#endif +) { Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -7431,7 +7435,7 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 @@ -7445,7 +7449,7 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 00be6455d..4f8c04eb6 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,7 +4644,11 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + ,0 /*isIVAS*/ +#endif + ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4713,7 +4717,11 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , Word16 1 /*isIVAS*/ +#endif + ); test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index be0dd84e5..3fe74d1a0 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,7 @@ void fb_tbe_enc_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 0 // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7468,7 +7468,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1 // isIVAS - is this corret? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7479,7 +7479,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1 // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -- GitLab From 7d06c195a51eb028b63585b0de04bbb01dea6a16 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:08:17 +0200 Subject: [PATCH 0943/1221] activate func1 --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 35d09abf5..37a941590 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -87,6 +87,6 @@ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 1e85b77367047724ac26f7b5f70fdaa06e399ba9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:21:23 +0200 Subject: [PATCH 0944/1221] remove all BE changes --- lib_com/options.h | 7 +- lib_com/swb_tbe_com_fx.c | 195 ----------------------------- lib_com/tools_fx.c | 24 ---- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 -- lib_dec/swb_tbe_dec_fx.c | 5 - 5 files changed, 1 insertion(+), 240 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index bb95f74df..99c6e8eb6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,12 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT -// new speedups - BE ones already in another branch -//#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | 2.4 WMOPS -//#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig /*FhG: reduces WMOPS - bit-exact*/ // | -//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx // | 0.4 WMOPS - BE? Need for a manual test as long as be tests dont work + #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | #define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 9e85b4175..3fec692dc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6767,89 +6767,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); #ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) - { - Word64 W_tmpX; - Word64 W_tmpY; - i = 4; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - FOR( ; i < L_FRAME48k; ) - { - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //2 - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); // 3 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //4 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //5 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); // 3 - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //4 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); //5 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //7 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - // W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); //4 - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); //5 - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); // 6 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); //7 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - // W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); //8 - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { FOR( i = 4; i < L_FRAME48k; i++ ) { @@ -6871,76 +6788,6 @@ void elliptic_bpf_48k_generic_fx( } #else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig - test(); - IF( full_band_bpf_fx == full_band_bpf_3_fx || full_band_bpf_fx == full_band_bpf_1_fx ) - { - i = 4; - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 0 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 1 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - FOR( ; i < L_FRAME48k; ) - { - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 2 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 3 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - // L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); // 4 /*Q_input_fx + 13 + 1 - 3*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); // 5 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); // 6 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); // 7 /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - // L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); // 8 /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_upsampledsig*/ { FOR( i = 4; i < L_FRAME48k; i++ ) { @@ -7307,47 +7154,6 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx - L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32; - Word16 tmp16; - - if ( L_tmp < 0 ) - { - L_tmp32 = L_negate( L_tmp ); - } - if ( L_tmp < 0 ) - { - L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); - } - if ( L_tmp < 0 ) - { - tmp16 = extract_h( L_tmp32 ); - } - if ( L_tmp < 0 ) - { - tmp16 = negate( tmp16 ); - } - - if ( L_tmp == 0 ) - { - tmp16 = 0; - move16(); - } - - if ( L_tmp > 0 ) - { - L_tmp32 = L_shl_sat( L_tmp, tmp3 ); - } - if ( L_tmp > 0 ) - { - tmp16 = extract_h( L_tmp32 ); - } - - output[i] = tmp16; - move16(); - -#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7359,7 +7165,6 @@ void synthesise_fb_high_band_fx( output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); } -#endif } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 756b5be80..8316452ba 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,29 +794,6 @@ void Copy_Scale_sig_16_32_no_sat( } return; } -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat - L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - - IF( L_tmp >= 0x7FFF ) - { - FOR( i = 0; i < lg; i++ ) - { - // y[i] = L_mult0(x[i], L_tmp); - y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* Overflow can occur here */ - } - return; - } - // ELSE - { - Word16 tmp = extract_l( L_tmp ); - FOR( i = 0; i < lg; i++ ) - { - y[i] = L_mult( x[i], tmp ); - move32(); - } - } -#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { @@ -824,7 +801,6 @@ void Copy_Scale_sig_16_32_no_sat( y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); move32(); /* Overflow can occur here */ } -#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 772eb2d7d..c7bc98566 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,9 +904,6 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); -#endif FOR( i = 0; i < winLen_fx; i++ ) { L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ @@ -914,17 +911,10 @@ void stereo_icBWE_dec_fx( tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - if ( LE_16( alpha_fx, winSlope_fx_ ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ - } -#else IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } -#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index bb0d6f2e0..8da680bf8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7037,17 +7037,12 @@ void ivas_swb_tbe_dec_fx( FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } -#else - Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ -#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); -- GitLab From 88c2dd4595710a177de9832a967949c96d654c69 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:30:40 +0200 Subject: [PATCH 0945/1221] add changes from BE branch concerning elliptic_bpf_48k - deactivated STAGE2 and func1 --- lib_com/options.h | 11 +- lib_com/prot_fx.h | 18 +- lib_com/swb_tbe_com_fx.c | 588 +++++++++++++++++++++++++++++++-------- lib_dec/swb_tbe_dec_fx.c | 15 +- lib_enc/swb_tbe_enc_fx.c | 39 ++- 5 files changed, 534 insertions(+), 137 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 99c6e8eb6..efd9f65cf 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,13 +80,8 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - - -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | - -//----------------------------------------------------------------------- -// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1452d8e2e..9435087b4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,15 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : i signal Q_input_fx */ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS; +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else + const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ @@ -3277,8 +3285,12 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ); - + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 isIVAS +#endif +); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ #ifdef ADD_IVAS_TBE_CODE diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 3fec692dc..b83aa0413 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6688,14 +6688,198 @@ void wb_tbe_extras_reset_synth_fx( return; } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +{ + Word32 L_tmpX; + Word16 i; + Word32 L_tmpMax2 = *L_tmpMax; + Word32 L_tmpAbs; + move32(); + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#else + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#endif + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ + void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS; +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6704,18 +6888,36 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 memory_fx0, Q_temp, Q_temp2; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; + Word32 L_tmpMax; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + Word64 W_tmpX; + Word64 W_tmpY; +#endif + + Word32 *L_tmp = &L_tmp_buffer[4]; + Word32 *L_tmp2 = &L_tmp2_buffer[4]; + Word32 *L_output = &L_output_buffer[4]; +#else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; - Word32 L_output[L_FRAME48k]; +#endif FOR( i = 0; i < 4; i++ ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + memory_fx0 = extract_l( memory_fx2[0][i] ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); +#else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); +#endif + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -6723,55 +6925,17 @@ void elliptic_bpf_48k_generic_fx( move32(); } - - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + IF( !IsUpsampled3 ) { - FOR( i = 4; i < L_FRAME48k; i++ ) +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) { - Word64 W_tmpX; - Word64 W_tmpY; + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); @@ -6781,15 +6945,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } - } - -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ - { - FOR( i = 4; i < L_FRAME48k; i++ ) +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6802,9 +6962,135 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } - } -#endif +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ + ELSE + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6815,6 +7101,46 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6860,43 +7186,22 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 4; i < L_FRAME48k; i++ ) { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } +#endif + -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -6912,12 +7217,54 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -6965,30 +7312,7 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -7006,7 +7330,10 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } + #endif + + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7070,7 +7397,12 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ) + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 isIVAS +#endif +) { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; @@ -7100,12 +7432,28 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx + + ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 8da680bf8..b8ebb033e 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,7 +4644,12 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + 0 /*isIVAS*/ +#endif + ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4714,7 +4719,13 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ push_wmops( "synthesise_fb_high_band" ); - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + /* FB TBE synthesis */ + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 1 /*isIVAS*/ +#endif + ); pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 316a5b549..3fe74d1a0 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,13 +7299,18 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; - Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_buffer[L_FRAME48k + 4]; + Word16 *input_fhb = &input_fhb_buffer[0] + 4; +#else + Word16 input_fhb[L_FRAME48k]; +#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -7325,7 +7330,14 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 0 // isIVAS - is this correct? +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7422,7 +7434,12 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; + Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; +#else Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; +#endif Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word64 fb_exc_energy; @@ -7449,11 +7466,25 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS - is this corret? +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS - is this correct? +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From 006443f447927c1029638f3cc55e932fcff8fec8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:33:04 +0200 Subject: [PATCH 0946/1221] clang patch --- lib_com/prot_fx.h | 3 ++- lib_com/swb_tbe_com_fx.c | 9 +++++---- lib_dec/swb_tbe_dec_fx.c | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index a230a83c7..bab4533cb 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3287,7 +3287,8 @@ void synthesise_fb_high_band_fx( Word16 bpf_memory_Q[], Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , Word16 isIVAS + , + Word16 isIVAS #endif ); diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8977dae08..accee64bc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7103,7 +7103,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -7396,9 +7396,10 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , Word16 isIVAS + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 isIVAS #endif ) { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 4f8c04eb6..5c0f43639 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,10 +4644,11 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - ,0 /*isIVAS*/ -#endif + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + 0 /*isIVAS*/ +#endif ); /* add the fb_synth component to the hb_synth component */ @@ -4717,10 +4718,11 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , Word16 1 /*isIVAS*/ -#endif + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 1 /*isIVAS*/ +#endif ); test(); -- GitLab From 771fc273d21d96517467e04592381eb8f7d3001c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:08:30 +0200 Subject: [PATCH 0947/1221] fix type error --- Workspace_msvc/decoder.vcxproj | 344 +++++++------- Workspace_msvc/encoder.vcxproj | 354 +++++++-------- Workspace_msvc/lib_com.vcxproj | 680 ++++++++++++++-------------- Workspace_msvc/lib_debug.vcxproj | 240 +++++----- Workspace_msvc/lib_dec.vcxproj | 710 ++++++++++++++--------------- Workspace_msvc/lib_enc.vcxproj | 742 +++++++++++++++---------------- Workspace_msvc/lib_rend.vcxproj | 414 ++++++++--------- Workspace_msvc/lib_util.vcxproj | 312 ++++++------- Workspace_msvc/renderer.vcxproj | 358 +++++++-------- lib_com/swb_tbe_com_fx.c | 2 +- 10 files changed, 2078 insertions(+), 2078 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index ca0d96f44..c3a5a71d8 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,173 +1,173 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 9578e488d..75b13f9bd 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 7a2aa8a7f..337fc98e2 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 929dd72a8..b6a8a7dd3 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 2d06d29aa..60a24021f 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 86dcef905..7fe2ad96c 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index e47858ae3..10abdb438 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 86730b859..1cfb3e588 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 70a130e31..ecd8b04aa 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index accee64bc..624bafa78 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6688,7 +6688,7 @@ void wb_tbe_extras_reset_synth_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) { Word32 L_tmpX; Word16 i; -- GitLab From 0aecdf09691c911aa34cab9db235b5f0bdc1cc21 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:09:50 +0200 Subject: [PATCH 0948/1221] fix type error --- lib_com/swb_tbe_com_fx.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 624bafa78..67240e540 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6711,11 +6711,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6733,11 +6733,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6757,11 +6757,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6775,11 +6775,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6792,11 +6792,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6812,11 +6812,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6829,11 +6829,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6845,11 +6845,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } -- GitLab From b95a18c496b24a03377039ac466a9bd2bdc44f15 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Thu, 10 Apr 2025 14:13:22 +0200 Subject: [PATCH 0949/1221] remove FORCE_DIV32_OPT_NEWTON --- lib_com/basop_util.c | 5 ----- lib_com/options.h | 1 - 2 files changed, 6 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 32f5cc55f..ec15e9769 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1013,10 +1013,6 @@ Word32 div_w( Word32 L_num, Word32 L_den ) Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) { Word32 z; -#ifdef FORCE_DIV32_OPT_NEWTON - z = BASOP_Util_Divide3232_Scale_newton( x, y, s ); - return z; -#else Word16 sx; Word16 sy; Word32 sign; @@ -1064,7 +1060,6 @@ Word32 BASOP_Util_Divide3232_Scale_cadence( Word32 x, Word32 y, Word16 *s ) } return z; -#endif } #ifdef DIV32_OPT_NEWTON diff --git a/lib_com/options.h b/lib_com/options.h index e1e4f53a7..90cd057d0 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,6 +81,5 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ -#define FORCE_DIV32_OPT_NEWTON /* FhG: replace BASOP_Util_Divide3232_Scale_cadence() by BASOP_Util_Divide3232_Scale_newton() */ #endif -- GitLab From 1c6062c62decac67f36200ac02de64d361b94ecb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:15:33 +0200 Subject: [PATCH 0950/1221] deactivate func1, activate STAGE2 --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 37a941590..dc144cd1a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,7 +86,7 @@ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From ce94cf8dd649ca3ff7f2520340de30de222ab5ee Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:47:01 +0200 Subject: [PATCH 0951/1221] fix build errors --- lib_com/options.h | 2 +- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 303 +++++++++++++++++++++------------------ lib_dec/swb_tbe_dec_fx.c | 2 +- lib_enc/swb_tbe_enc_fx.c | 6 +- 5 files changed, 169 insertions(+), 146 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index dc144cd1a..8651c0671 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,7 +86,7 @@ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index bab4533cb..292c82206 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3259,7 +3259,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; + int isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 67240e540..e14fda2a2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6871,7 +6871,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; + int isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6889,8 +6889,9 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; Word32 L_tmpMax; + Word32 L_tmpX; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word64 W_tmpX; Word64 W_tmpY; @@ -6932,101 +6933,111 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) + IF( isIVAS ) { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } } -#else - FOR( i = 0; i < L_FRAME48k; ) + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ @@ -7107,37 +7118,43 @@ void elliptic_bpf_48k_generic_fx( elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7228,40 +7245,46 @@ void elliptic_bpf_48k_generic_fx( elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ @@ -7436,7 +7459,7 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS + isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 @@ -7450,7 +7473,7 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS + isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 5c0f43639..2994c2878 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4721,7 +4721,7 @@ void fb_tbe_dec_ivas_fx( synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , - Word16 1 /*isIVAS*/ + 1 /*isIVAS*/ #endif ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 3fe74d1a0..f42bd262a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,7 @@ void fb_tbe_enc_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 0 // isIVAS - is this correct? + 0, // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7468,7 +7468,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS - is this corret? + 1, // isIVAS - is this corret? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7479,7 +7479,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS - is this correct? + 1, // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -- GitLab From bc0565c1160cf97a4d23b9137fc608955e6bd890 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:15:33 +0200 Subject: [PATCH 0952/1221] deactivate func1, activate STAGE2 --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index efd9f65cf..01900a847 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,7 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 7fd231f4e0784a996a9b24484030cc875f3219a1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:57:27 +0200 Subject: [PATCH 0953/1221] fix build errors --- lib_com/swb_tbe_com_fx.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b83aa0413..5c2c74e2e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6712,11 +6712,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6734,11 +6734,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6758,11 +6758,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6776,11 +6776,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6793,11 +6793,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6813,11 +6813,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6830,11 +6830,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6846,18 +6846,18 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( L_tmpMax > 0 ) + if ( *L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } i++; } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; move32(); } -- GitLab From 523e8caa7d6c10b1ba758de621e9f5ca6e9619b4 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:47:01 +0200 Subject: [PATCH 0954/1221] fix build errors --- lib_com/options.h | 2 +- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 303 +++++++++++++++++++++------------------ lib_dec/swb_tbe_dec_fx.c | 2 +- lib_enc/swb_tbe_enc_fx.c | 6 +- 5 files changed, 169 insertions(+), 146 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 01900a847..1325dacfa 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,7 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9435087b4..359320af7 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3259,7 +3259,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; + int isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5c2c74e2e..828f4b5af 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6872,7 +6872,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; + int isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6890,8 +6890,9 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; Word32 L_tmpMax; + Word32 L_tmpX; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word64 W_tmpX; Word64 W_tmpY; @@ -6933,101 +6934,111 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) + IF( isIVAS ) { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } } -#else - FOR( i = 0; i < L_FRAME48k; ) + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ @@ -7108,37 +7119,43 @@ void elliptic_bpf_48k_generic_fx( elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7229,40 +7246,46 @@ void elliptic_bpf_48k_generic_fx( elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ @@ -7434,7 +7457,7 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS + isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 @@ -7448,7 +7471,7 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS + isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index b8ebb033e..636702daa 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4723,7 +4723,7 @@ void fb_tbe_dec_ivas_fx( synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , - Word16 1 /*isIVAS*/ + 1 /*isIVAS*/ #endif ); pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 3fe74d1a0..f42bd262a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,7 @@ void fb_tbe_enc_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 0 // isIVAS - is this correct? + 0, // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7468,7 +7468,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS - is this corret? + 1, // isIVAS - is this corret? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7479,7 +7479,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS - is this correct? + 1, // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -- GitLab From cbe487105f4baa613fc699d2caebb95e8f6e0c25 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:58:58 +0200 Subject: [PATCH 0955/1221] deactivate STAGE2 and func1 --- Workspace_msvc/decoder.vcxproj | 344 +++++++------- Workspace_msvc/encoder.vcxproj | 354 +++++++-------- Workspace_msvc/lib_com.vcxproj | 680 ++++++++++++++-------------- Workspace_msvc/lib_debug.vcxproj | 240 +++++----- Workspace_msvc/lib_dec.vcxproj | 710 ++++++++++++++--------------- Workspace_msvc/lib_enc.vcxproj | 742 +++++++++++++++---------------- Workspace_msvc/lib_rend.vcxproj | 414 ++++++++--------- Workspace_msvc/lib_util.vcxproj | 312 ++++++------- Workspace_msvc/renderer.vcxproj | 358 +++++++-------- lib_com/options.h | 2 +- 10 files changed, 2078 insertions(+), 2078 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index ca0d96f44..c3a5a71d8 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,173 +1,173 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 9578e488d..75b13f9bd 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 7a2aa8a7f..337fc98e2 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 929dd72a8..b6a8a7dd3 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 2d06d29aa..60a24021f 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 86dcef905..7fe2ad96c 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index e47858ae3..10abdb438 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 86730b859..1cfb3e588 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 70a130e31..ecd8b04aa 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/options.h b/lib_com/options.h index 1325dacfa..71dd19d71 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,7 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 423e399a8be328d6e320b9e66d41a10f5c835126 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:03:50 +0200 Subject: [PATCH 0956/1221] delete func1 --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 187 --------------------------------------- 2 files changed, 1 insertion(+), 188 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 71dd19d71..6d02885cc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,6 +82,6 @@ //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 828f4b5af..8416a2e7d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6688,181 +6688,6 @@ void wb_tbe_extras_reset_synth_fx( return; } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) -{ - Word32 L_tmpX; - Word16 i; - Word32 L_tmpMax2 = *L_tmpMax; - Word32 L_tmpAbs; - move32(); - IF( !IsUpsampled3 ) - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#else - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#endif - } /*IsUpsampled3*/ - ELSE - { /*IsUpsampled3*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ - *L_tmpMax = L_tmpMax2; - move32(); -} -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -6928,9 +6753,6 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -7040,7 +6862,6 @@ void elliptic_bpf_48k_generic_fx( } } } /*IsUpsampled3*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7115,9 +6936,6 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 IF( isIVAS ) { @@ -7156,7 +6974,6 @@ void elliptic_bpf_48k_generic_fx( } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7242,9 +7059,6 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 IF( isIVAS ) { @@ -7286,7 +7100,6 @@ void elliptic_bpf_48k_generic_fx( } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From bedb83f789423aa88f0016787ee00cf7fb751b4c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:08:59 +0200 Subject: [PATCH 0957/1221] delete all non-BE changes --- lib_com/options.h | 4 - lib_com/prot_fx.h | 8 - lib_com/swb_tbe_com_fx.c | 444 +-------------------------------------- lib_dec/swb_tbe_dec_fx.c | 14 +- lib_enc/swb_tbe_enc_fx.c | 37 +--- 5 files changed, 7 insertions(+), 500 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 8651c0671..a3a65fe55 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,8 +85,4 @@ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 292c82206..93da4d66a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,15 +3258,7 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 IsUpsampled3, - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e14fda2a2..2b86715a4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6687,181 +6687,6 @@ void wb_tbe_extras_reset_synth_fx( return; } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) -{ - Word32 L_tmpX; - Word16 i; - Word32 L_tmpMax2 = *L_tmpMax; - Word32 L_tmpAbs; - move32(); - IF( !IsUpsampled3 ) - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#else - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#endif - } /*IsUpsampled3*/ - ELSE - { /*IsUpsampled3*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ - *L_tmpMax = L_tmpMax2; - move32(); -} -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -6870,15 +6695,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 IsUpsampled3, - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6887,34 +6704,14 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; - Word32 L_tmpMax; - Word32 L_tmpX; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - Word64 W_tmpX; - Word64 W_tmpY; -#endif - - Word32 *L_tmp = &L_tmp_buffer[4]; - Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *L_output = &L_output_buffer[4]; -#else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; -#endif FOR( i = 0; i < 4; i++ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - memory_fx0 = extract_l( memory_fx2[0][i] ); - input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); -#else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); -#endif L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); @@ -6925,123 +6722,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - IF( !IsUpsampled3 ) - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } - } - } /*IsUpsampled3*/ - ELSE - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - } /*IsUpsampled3*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7100,7 +6781,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -7112,51 +6792,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7215,8 +6851,6 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } -#endif - Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); @@ -7239,54 +6873,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - } - -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7353,8 +6940,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -#endif - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; @@ -7420,19 +7005,10 @@ void synthesise_fb_high_band_fx( Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif ) { Word16 i, j; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; - Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; -#else Word16 excitation_in_interp3[L_FRAME48k]; -#endif Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; @@ -7457,28 +7033,12 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 1, // IsUpsampled3 -#endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx - - ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 1, // IsUpsampled3 -#endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 2994c2878..ebe7a847a 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,12 +4644,7 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - 0 /*isIVAS*/ -#endif - ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4718,12 +4713,7 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - 1 /*isIVAS*/ -#endif - ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index f42bd262a..272d9a4b9 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7305,12 +7305,7 @@ void fb_tbe_enc_fx( Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fhb_buffer[L_FRAME48k + 4]; - Word16 *input_fhb = &input_fhb_buffer[0] + 4; -#else Word16 input_fhb[L_FRAME48k]; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -7330,14 +7325,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 0, // isIVAS - is this correct? -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 -#endif - input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7434,12 +7422,7 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; - Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; -#else Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; -#endif Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word64 fb_exc_energy; @@ -7466,25 +7449,11 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS - is this corret? -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 -#endif - input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS - is this correct? -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 -#endif - input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From a3746c8f8e832ece31b48ec7b47bfa8216a0bb34 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:21:13 +0200 Subject: [PATCH 0958/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 7 +++---- lib_dec/swb_tbe_dec_fx.c | 4 ++-- lib_enc/swb_tbe_enc_fx.c | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2b86715a4..c9361cbe6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7004,8 +7004,7 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -) + Word16 Qout ) { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; @@ -7033,12 +7032,12 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index ebe7a847a..00be6455d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,7 +4644,7 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4713,7 +4713,7 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 272d9a4b9..a72a7ced1 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7325,7 +7325,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7449,11 +7449,11 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From 3ea49c9a6976c614a9d5606562ff79ef3c16eaae Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:22:15 +0200 Subject: [PATCH 0959/1221] clang patch --- lib_com/options.h | 1 - lib_com/swb_tbe_com_fx.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 6d02885cc..942f5cfd6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,6 +82,5 @@ //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8416a2e7d..1d7a9a5b7 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6974,7 +6974,7 @@ void elliptic_bpf_48k_generic_fx( } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7100,7 +7100,7 @@ void elliptic_bpf_48k_generic_fx( } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From d44257b3667886b4ac0daab94cdf1a1d0ada1a38 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:28:41 +0200 Subject: [PATCH 0960/1221] fix memory --- lib_com/swb_tbe_com_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c9361cbe6..14a40e7b9 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6712,9 +6712,9 @@ void elliptic_bpf_48k_generic_fx( { memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //is this change be? move32(); move32(); move32(); -- GitLab From 21eae1a712187057531458a0a2a2ba5f763a8c15 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:30:43 +0000 Subject: [PATCH 0961/1221] revert all changes in elliptic_bpf_48k_generic_fx , but 1 --- lib_com/swb_tbe_com_fx.c | 105 ++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 14a40e7b9..5ce4d8ad7 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6722,52 +6722,48 @@ void elliptic_bpf_48k_generic_fx( move32(); } - - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6791,8 +6787,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6837,19 +6831,19 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } Q_temp = norm_l( L_tmpMax ); @@ -6867,13 +6861,12 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); } - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -6939,8 +6932,6 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; -- GitLab From 5a9847e0933fbb07c5c052125a70865ff4aaff34 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:35:20 +0000 Subject: [PATCH 0962/1221] revert vcxproj changes --- Workspace_msvc/decoder.vcxproj | 6 +++--- Workspace_msvc/encoder.vcxproj | 6 +++--- Workspace_msvc/lib_com.vcxproj | 6 +++--- Workspace_msvc/lib_debug.vcxproj | 6 +++--- Workspace_msvc/lib_dec.vcxproj | 6 +++--- Workspace_msvc/lib_enc.vcxproj | 6 +++--- Workspace_msvc/lib_rend.vcxproj | 6 +++--- Workspace_msvc/lib_util.vcxproj | 6 +++--- Workspace_msvc/renderer.vcxproj | 6 +++--- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index c3a5a71d8..9c5f8787a 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -14,18 +14,18 @@ decoder {E3DCBC31-7FC9-D127-E000-529F8460D5FD} decoder - 10.0 + 10.0.17763.0 Application - v143 + v141 false MultiByte Application - v143 + v141 false MultiByte diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 75b13f9bd..5ec7a2c01 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -14,18 +14,18 @@ encoder {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} encoder - 10.0 + 10.0.17763.0 Application - v143 + v141 false MultiByte Application - v143 + v141 false MultiByte diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 337fc98e2..5cbb9a2bb 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -13,18 +13,18 @@ {39EC200D-7795-4FF8-B214-B24EDA5526AE} common - 10.0 + 10.0.17763.0 StaticLibrary - v143 + v141 false MultiByte StaticLibrary - v143 + v141 false MultiByte diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index b6a8a7dd3..157e32f9d 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -13,17 +13,17 @@ {54509728-928B-44D9-A118-A6F92F08B34F} debug - 10.0 + 10.0.17763.0 StaticLibrary - v143 + v141 MultiByte StaticLibrary - v143 + v141 MultiByte true diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 60a24021f..bddcb0dbf 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -14,18 +14,18 @@ lib_dec {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} evs_dec - 10.0 + 10.0.17763.0 StaticLibrary - v143 + v141 false MultiByte StaticLibrary - v143 + v141 false MultiByte diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 7fe2ad96c..95298d456 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -14,18 +14,18 @@ lib_enc {824DA4CF-06F0-45C9-929A-8792F0E19C3E} evs_enc - 10.0 + 10.0.17763.0 StaticLibrary - v143 + v141 false MultiByte StaticLibrary - v143 + v141 false MultiByte diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 10abdb438..0810f2a85 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -14,18 +14,18 @@ lib_rend {718DE063-A18B-BB72-9150-62B892E6FFA6} evs_dec - 10.0 + 10.0.17763.0 StaticLibrary - v143 + v141 false MultiByte StaticLibrary - v143 + v141 false MultiByte diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 1cfb3e588..ebb82c6c0 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -13,17 +13,17 @@ {2FA8F384-0775-F3B7-F8C3-85209222FC70} utility - 10.0 + 10.0.17763.0 StaticLibrary - v143 + v141 MultiByte StaticLibrary - v143 + v141 MultiByte true diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index ecd8b04aa..fc00b0348 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -14,18 +14,18 @@ renderer {12B4C8A5-1E06-4E30-B443-D1F916F52B47} renderer - 10.0 + 10.0.17763.0 Application - v143 + v141 false MultiByte Application - v143 + v141 false MultiByte -- GitLab From cf0b0aa0d7cc200915fdc1e36102efcf4d09ab7c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:50:09 +0200 Subject: [PATCH 0963/1221] revert vcxproj changes --- Workspace_msvc/decoder.vcxproj | 344 +++++++------- Workspace_msvc/encoder.vcxproj | 354 +++++++-------- Workspace_msvc/lib_com.vcxproj | 680 ++++++++++++++-------------- Workspace_msvc/lib_debug.vcxproj | 240 +++++----- Workspace_msvc/lib_dec.vcxproj | 710 ++++++++++++++--------------- Workspace_msvc/lib_enc.vcxproj | 742 +++++++++++++++---------------- Workspace_msvc/lib_rend.vcxproj | 414 ++++++++--------- Workspace_msvc/lib_util.vcxproj | 312 ++++++------- Workspace_msvc/renderer.vcxproj | 358 +++++++-------- 9 files changed, 2077 insertions(+), 2077 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index 9c5f8787a..ca0d96f44 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,173 +1,173 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 5ec7a2c01..9578e488d 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 5cbb9a2bb..7a2aa8a7f 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 157e32f9d..929dd72a8 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index bddcb0dbf..2d06d29aa 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 95298d456..86dcef905 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 0810f2a85..e47858ae3 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index ebb82c6c0..86730b859 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index fc00b0348..70a130e31 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file -- GitLab From 2633f5751459385a6a8dddc59f3abdd7f56aef72 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:52:32 +0000 Subject: [PATCH 0964/1221] revert unnecesary changes --- lib_enc/swb_tbe_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index a72a7ced1..316a5b549 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,13 +7299,13 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; + Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; - Word16 input_fhb[L_FRAME48k]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); -- GitLab From 673d0f595183ffb52564f3530d34e220c98f55ba Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 15:54:34 +0200 Subject: [PATCH 0965/1221] revert vcxproj changes --- Workspace_msvc/decoder.vcxproj | 344 +++++++------- Workspace_msvc/encoder.vcxproj | 354 +++++++-------- Workspace_msvc/lib_com.vcxproj | 680 ++++++++++++++-------------- Workspace_msvc/lib_debug.vcxproj | 240 +++++----- Workspace_msvc/lib_dec.vcxproj | 710 ++++++++++++++--------------- Workspace_msvc/lib_enc.vcxproj | 742 +++++++++++++++---------------- Workspace_msvc/lib_rend.vcxproj | 414 ++++++++--------- Workspace_msvc/lib_util.vcxproj | 312 ++++++------- Workspace_msvc/renderer.vcxproj | 358 +++++++-------- 9 files changed, 2077 insertions(+), 2077 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index c3a5a71d8..ca0d96f44 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,173 +1,173 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 75b13f9bd..9578e488d 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 337fc98e2..7a2aa8a7f 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0 - - - - StaticLibrary - v143 - false - MultiByte - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index b6a8a7dd3..929dd72a8 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0 - - - - StaticLibrary - v143 - MultiByte - - - StaticLibrary - v143 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 60a24021f..2d06d29aa 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0 - - - StaticLibrary - v143 - false - MultiByte - - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 7fe2ad96c..86dcef905 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0 - - - - StaticLibrary - v143 - false - MultiByte - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 10abdb438..e47858ae3 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0 - - - StaticLibrary - v143 - false - MultiByte - - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 1cfb3e588..86730b859 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0 - - - - StaticLibrary - v143 - MultiByte - - - StaticLibrary - v143 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index ecd8b04aa..70a130e31 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file -- GitLab From 15dda6ba60e7042909660554a9213876d87901e1 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:05:55 +0200 Subject: [PATCH 0966/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5ce4d8ad7..d3dc614aa 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,7 +6714,7 @@ void elliptic_bpf_48k_generic_fx( memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - //memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //is this change be? + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //is this change be? move32(); move32(); move32(); -- GitLab From 5bae86227e83790d932c36f68db42e4d5f8787a2 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:18 +0200 Subject: [PATCH 0967/1221] Revert "clang patch" This reverts commit 3ea49c9a6976c614a9d5606562ff79ef3c16eaae. --- lib_com/options.h | 1 + lib_com/swb_tbe_com_fx.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 942f5cfd6..6d02885cc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,5 +82,6 @@ //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1d7a9a5b7..8416a2e7d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6974,7 +6974,7 @@ void elliptic_bpf_48k_generic_fx( } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7100,7 +7100,7 @@ void elliptic_bpf_48k_generic_fx( } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 28ac4dc13474fc61114879e9e095ab1c6b1c2821 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:20 +0200 Subject: [PATCH 0968/1221] Revert "delete func1" This reverts commit 423e399a8be328d6e320b9e66d41a10f5c835126. --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 187 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 6d02885cc..71dd19d71 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,6 +82,6 @@ //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8416a2e7d..828f4b5af 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6688,6 +6688,181 @@ void wb_tbe_extras_reset_synth_fx( return; } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +{ + Word32 L_tmpX; + Word16 i; + Word32 L_tmpMax2 = *L_tmpMax; + Word32 L_tmpAbs; + move32(); + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#else + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#endif + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -6753,6 +6928,9 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -6862,6 +7040,7 @@ void elliptic_bpf_48k_generic_fx( } } } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6936,6 +7115,9 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 IF( isIVAS ) { @@ -6974,6 +7156,7 @@ void elliptic_bpf_48k_generic_fx( } } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7059,6 +7242,9 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 IF( isIVAS ) { @@ -7100,6 +7286,7 @@ void elliptic_bpf_48k_generic_fx( } } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From f1e9bdaefabbe3f66377b64c6453f5acfa87a423 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:22 +0200 Subject: [PATCH 0969/1221] Revert "deactivate STAGE2 and func1" This reverts commit cbe487105f4baa613fc699d2caebb95e8f6e0c25. --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 71dd19d71..1325dacfa 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,7 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 5f65ef0682f03fc3693cff73f42998bf757b99d7 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:24 +0200 Subject: [PATCH 0970/1221] Revert "fix build errors" This reverts commit 523e8caa7d6c10b1ba758de621e9f5ca6e9619b4. --- lib_com/options.h | 2 +- lib_com/prot_fx.h | 2 +- lib_com/swb_tbe_com_fx.c | 303 ++++++++++++++++++--------------------- lib_dec/swb_tbe_dec_fx.c | 2 +- lib_enc/swb_tbe_enc_fx.c | 6 +- 5 files changed, 146 insertions(+), 169 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1325dacfa..01900a847 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,7 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 359320af7..9435087b4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3259,7 +3259,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, + int isIVAS; #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 828f4b5af..5c2c74e2e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6872,7 +6872,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, + int isIVAS; #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6890,9 +6890,8 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; Word32 L_tmpMax; - Word32 L_tmpX; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word64 W_tmpX; Word64 W_tmpY; @@ -6934,111 +6933,101 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - } + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) + FOR( i = 0; i < L_FRAME48k; ) { - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else + FOR( i = 0; i < L_FRAME48k; ) { - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ @@ -7119,43 +7108,37 @@ void elliptic_bpf_48k_generic_fx( elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7246,46 +7229,40 @@ void elliptic_bpf_48k_generic_fx( elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - ELSE -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ @@ -7457,7 +7434,7 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, + isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 @@ -7471,7 +7448,7 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, + isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 636702daa..b8ebb033e 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4723,7 +4723,7 @@ void fb_tbe_dec_ivas_fx( synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , - 1 /*isIVAS*/ + Word16 1 /*isIVAS*/ #endif ); pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index f42bd262a..3fe74d1a0 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,7 @@ void fb_tbe_enc_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 0, // isIVAS - is this correct? + 0 // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7468,7 +7468,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS - is this corret? + 1 // isIVAS - is this corret? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7479,7 +7479,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS - is this correct? + 1 // isIVAS - is this correct? #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -- GitLab From f0779e9616693f311140b10bb9967f13f8d2fa58 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:25 +0200 Subject: [PATCH 0971/1221] Revert "fix build errors" This reverts commit 7fd231f4e0784a996a9b24484030cc875f3219a1. --- lib_com/swb_tbe_com_fx.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5c2c74e2e..b83aa0413 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6712,11 +6712,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6734,11 +6734,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6758,11 +6758,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6776,11 +6776,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6793,11 +6793,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6813,11 +6813,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6830,11 +6830,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } @@ -6846,18 +6846,18 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } i++; } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; move32(); } -- GitLab From 4dffc7c6f5fa863979d7c224fdb8ce8cfc08d186 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:28 +0200 Subject: [PATCH 0972/1221] Revert "deactivate func1, activate STAGE2" This reverts commit bc0565c1160cf97a4d23b9137fc608955e6bd890. --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 01900a847..efd9f65cf 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,7 +81,7 @@ #define HARM_ENC_INIT //#define HARM_SCE_INIT #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 903b7f4ff344e567ac72e0ddfa17bb490b0360b2 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:09:30 +0200 Subject: [PATCH 0973/1221] Revert "add changes from BE branch concerning elliptic_bpf_48k - deactivated STAGE2 and func1" This reverts commit 88c2dd4595710a177de9832a967949c96d654c69. --- lib_com/options.h | 11 +- lib_com/prot_fx.h | 18 +- lib_com/swb_tbe_com_fx.c | 588 ++++++++------------------------------- lib_dec/swb_tbe_dec_fx.c | 15 +- lib_enc/swb_tbe_enc_fx.c | 39 +-- 5 files changed, 137 insertions(+), 534 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index efd9f65cf..99c6e8eb6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,8 +80,13 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + + +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 +#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | + +//----------------------------------------------------------------------- +// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9435087b4..1452d8e2e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,15 +3258,7 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 IsUpsampled3, - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif + const Word16 input_fx[], /* i : i signal Q_input_fx */ Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ @@ -3285,12 +3277,8 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif -); + Word16 Qout ); + void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ #ifdef ADD_IVAS_TBE_CODE diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index b83aa0413..3fec692dc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6688,198 +6688,14 @@ void wb_tbe_extras_reset_synth_fx( return; } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) -{ - Word32 L_tmpX; - Word16 i; - Word32 L_tmpMax2 = *L_tmpMax; - Word32 L_tmpAbs; - move32(); - IF( !IsUpsampled3 ) - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#else - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#endif - } /*IsUpsampled3*/ - ELSE - { /*IsUpsampled3*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ - *L_tmpMax = L_tmpMax2; - move32(); -} -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ - void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 IsUpsampled3, - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6888,36 +6704,18 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; - Word32 L_tmpMax; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - Word64 W_tmpX; - Word64 W_tmpY; -#endif - - Word32 *L_tmp = &L_tmp_buffer[4]; - Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *L_output = &L_output_buffer[4]; -#else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; -#endif + Word32 L_output[L_FRAME48k]; FOR( i = 0; i < 4; i++ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - memory_fx0 = extract_l( memory_fx2[0][i] ); - input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); -#else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); -#endif - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -6925,17 +6723,55 @@ void elliptic_bpf_48k_generic_fx( move32(); } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - IF( !IsUpsampled3 ) + + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + FOR( i = 4; i < L_FRAME48k; i++ ) { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + Word64 W_tmpX; + Word64 W_tmpY; W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); @@ -6945,11 +6781,15 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + } + +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ + { + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6962,135 +6802,9 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ - ELSE - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } -#else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#endif + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -7101,46 +6815,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7186,22 +6860,43 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + Word64 W_tmpX; + Word64 W_tmpY; + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } -#endif - +#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -7217,54 +6912,12 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7312,7 +6965,30 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 + FOR( i = 4; i < L_FRAME48k; i++ ) + { + Word64 W_tmpX; + Word64 W_tmpY; + + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -7330,10 +7006,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - #endif - - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7397,12 +7070,7 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif -) + Word16 Qout ) { Word16 i, j; Word16 excitation_in_interp3[L_FRAME48k]; @@ -7432,28 +7100,12 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 1, // IsUpsampled3 -#endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx - - ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 1, // IsUpsampled3 -#endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index b8ebb033e..8da680bf8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,12 +4644,7 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - 0 /*isIVAS*/ -#endif - ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4719,13 +4714,7 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ push_wmops( "synthesise_fb_high_band" ); - /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 1 /*isIVAS*/ -#endif - ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 3fe74d1a0..316a5b549 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,18 +7299,13 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; + Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fhb_buffer[L_FRAME48k + 4]; - Word16 *input_fhb = &input_fhb_buffer[0] + 4; -#else - Word16 input_fhb[L_FRAME48k]; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -7330,14 +7325,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 0 // isIVAS - is this correct? -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 -#endif - input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7434,12 +7422,7 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; - Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; -#else Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; -#endif Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word64 fb_exc_energy; @@ -7466,25 +7449,11 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS - is this corret? -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 -#endif - input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS - is this correct? -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 0, // IsUpsampled3 -#endif - input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From d041f1fd191ded0cbb84e62a70067289b0be815f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:18:58 +0200 Subject: [PATCH 0974/1221] reapply all nonbe hanges from be branch - inactive --- lib_com/options.h | 12 +- lib_com/prot_fx.h | 37 ++- lib_com/swb_tbe_com_fx.c | 654 ++++++++++++++++++++++++++++++--------- lib_dec/swb_tbe_dec_fx.c | 14 +- lib_enc/swb_tbe_enc_fx.c | 39 ++- 5 files changed, 589 insertions(+), 167 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 99c6e8eb6..85318d23a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,13 +80,7 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT - - - -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 // nonbe // | -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 // nonbe // | 3.1 WMOPS, pipe testing https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/pipelines/50562 -#define FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 // nonbe // | - -//----------------------------------------------------------------------- -// OPT_STEREO_32KBPS_V1 switch is inactive - why? (3.2 WMOPS) +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1452d8e2e..028822857 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,15 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : i signal Q_input_fx */ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else + const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ @@ -3267,17 +3275,22 @@ void elliptic_bpf_48k_generic_fx( ); void synthesise_fb_high_band_fx( - const Word16 excitation_in[], /* i : full band excitation */ - Word16 Q_fb_exc, - Word16 output[], /* o : high band speech - 14.0 to 20 kHz */ - const Word32 fb_exc_energy, /* i : full band excitation energy */ - const Word16 ratio, /* i : energy ratio */ - const Word16 L_frame, /* i : ACELP frame length */ - const Word16 bfi, /* i : fec flag */ - Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ - Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ - Word16 bpf_memory_Q[], - Word16 Qout ); + const Word16 excitation_in[], /* i : full band excitation */ + Word16 Q_fb_exc, + Word16 output[], /* o : high band speech - 14.0 to 20 kHz */ + const Word32 fb_exc_energy, /* i : full band excitation energy */ + const Word16 ratio, /* i : energy ratio */ + const Word16 L_frame, /* i : ACELP frame length */ + const Word16 bfi, /* i : fec flag */ + Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ + Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ + Word16 bpf_memory_Q[], + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 isIVAS +#endif + ); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 3fec692dc..6648a1351 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6687,6 +6687,180 @@ void wb_tbe_extras_reset_synth_fx( return; } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +{ + Word32 L_tmpX; + Word16 i; + Word32 L_tmpMax2 = *L_tmpMax; + Word32 L_tmpAbs; + move32(); + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#else + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#endif + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() @@ -6694,8 +6868,17 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ + void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6704,18 +6887,37 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 memory_fx0, Q_temp, Q_temp2; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; + Word32 L_tmpMax; + Word32 L_tmpX; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + Word64 W_tmpX; + Word64 W_tmpY; +#endif + + Word32 *L_tmp = &L_tmp_buffer[4]; + Word32 *L_tmp2 = &L_tmp2_buffer[4]; + Word32 *L_output = &L_output_buffer[4]; +#else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; - Word32 L_output[L_FRAME48k]; +#endif FOR( i = 0; i < 4; i++ ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + memory_fx0 = extract_l( memory_fx2[0][i] ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); +#else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); +#endif + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -6723,88 +6925,182 @@ void elliptic_bpf_48k_generic_fx( move32(); } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } + } + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } + } + } /*IsUpsampled3*/ + ELSE + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } + } + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } + } + } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1 - { - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - //L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - } - } -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE1*/ + + FOR( i = 4; i < L_FRAME48k; i++ ) { - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); } -#endif - +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6815,6 +7111,52 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + } + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + } + +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6860,43 +7202,22 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 4; i < L_FRAME48k; i++ ) { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - //L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } +#endif + -#else /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } -#endif /*FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE2*/ Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -6912,12 +7233,60 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } + } + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } + } + +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -6965,30 +7334,7 @@ void elliptic_bpf_48k_generic_fx( L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -#ifdef FIX_1439_SPEEDUP_elliptic_bpf_48k_generic_STAGE3 - FOR( i = 4; i < L_FRAME48k; i++ ) - { - Word64 W_tmpX; - Word64 W_tmpY; - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - //L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 + 16 ), W_shl( W_tmpY, 2 - 16 ) ) ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#else FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -7006,7 +7352,10 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } + #endif + + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7044,6 +7393,7 @@ void elliptic_bpf_48k_generic_fx( return; } + /*-------------------------------------------------------------------* * synthesise_fb_high_band() * @@ -7070,17 +7420,26 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ) + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 isIVAS +#endif +) { Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; + Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; +#else Word16 excitation_in_interp3[L_FRAME48k]; +#endif + Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; - Word16 tmp[L_FRAME48k]; - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" ); /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7096,16 +7455,31 @@ void synthesise_fb_high_band_fx( } exp_tmp = sub( Q_fb_exc, 2 ); - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" ); IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx + + ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 8da680bf8..dfa12a5bd 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,7 +4644,12 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + 0 /*isIVAS*/ +#endif + ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4714,7 +4719,12 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ push_wmops( "synthesise_fb_high_band" ); - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + 1 /*isIVAS*/ +#endif + ); pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ test(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 316a5b549..f42bd262a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,13 +7299,18 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; - Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_buffer[L_FRAME48k + 4]; + Word16 *input_fhb = &input_fhb_buffer[0] + 4; +#else + Word16 input_fhb[L_FRAME48k]; +#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -7325,7 +7330,14 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 0, // isIVAS - is this correct? +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7422,7 +7434,12 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; + Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; +#else Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; +#endif Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word64 fb_exc_energy; @@ -7449,11 +7466,25 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1, // isIVAS - is this corret? +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1, // isIVAS - is this correct? +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From 28bd30c2e59d2c59b75fbc23c426648c92307c3e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:43:15 +0200 Subject: [PATCH 0975/1221] clang patch --- lib_com/prot_fx.h | 28 ++++++++++++++-------------- lib_com/swb_tbe_com_fx.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 028822857..292c82206 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3275,22 +3275,22 @@ void elliptic_bpf_48k_generic_fx( ); void synthesise_fb_high_band_fx( - const Word16 excitation_in[], /* i : full band excitation */ - Word16 Q_fb_exc, - Word16 output[], /* o : high band speech - 14.0 to 20 kHz */ - const Word32 fb_exc_energy, /* i : full band excitation energy */ - const Word16 ratio, /* i : energy ratio */ - const Word16 L_frame, /* i : ACELP frame length */ - const Word16 bfi, /* i : fec flag */ - Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ - Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ - Word16 bpf_memory_Q[], - Word16 Qout + const Word16 excitation_in[], /* i : full band excitation */ + Word16 Q_fb_exc, + Word16 output[], /* o : high band speech - 14.0 to 20 kHz */ + const Word32 fb_exc_energy, /* i : full band excitation energy */ + const Word16 ratio, /* i : energy ratio */ + const Word16 L_frame, /* i : ACELP frame length */ + const Word16 bfi, /* i : fec flag */ + Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ + Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ + Word16 bpf_memory_Q[], + Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS + , + Word16 isIVAS #endif - ); +); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6648a1351..8be5c88bb 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6856,7 +6856,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_t i++; } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; move32(); } -- GitLab From a2ecf205c2505903656e4ee7c61787e6008660aa Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:45:12 +0200 Subject: [PATCH 0976/1221] activate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 85318d23a..1b46169e1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,7 +80,7 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 6c8cfde86b1871323d017b7ba38ccb317c7902d2 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 14:51:28 +0000 Subject: [PATCH 0977/1221] revert some unwanted changes --- lib_com/swb_tbe_com_fx.c | 110 +++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8be5c88bb..06df9ec49 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -19,7 +19,6 @@ #define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ #define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ - /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ @@ -6911,13 +6910,16 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); + memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); #endif - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -7042,51 +7044,48 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7201,19 +7200,19 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } #endif @@ -7233,8 +7232,8 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -7393,7 +7392,6 @@ void elliptic_bpf_48k_generic_fx( return; } - /*-------------------------------------------------------------------* * synthesise_fb_high_band() * -- GitLab From 05632ea436e66f0b43a6031372be9c6f6a168d37 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 16:53:59 +0200 Subject: [PATCH 0978/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 06df9ec49..d017914dc 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6912,7 +6912,7 @@ void elliptic_bpf_48k_generic_fx( input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); #else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); -- GitLab From fc16917f1c0dd1df6bfc204e00021fd8b5266851 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 10 Apr 2025 12:18:55 -0400 Subject: [PATCH 0979/1221] possible fix to 1421 --- lib_com/options.h | 3 +++ lib_enc/enc_gen_voic_fx.c | 22 +++++++++++++++++++++- lib_enc/enc_tran_fx.c | 29 +++++++++++++++++++++++++++-- lib_enc/transition_enc_fx.c | 12 ++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 2b88deb5d..45cc3dc42 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -80,4 +80,7 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT + +#define TEST_HR + #endif diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 22af9097d..e694b60c2 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -518,7 +518,12 @@ void encod_gen_voic_ivas_fx( set16_fx( code_preQ_fx, 0, L_SUBFR ); shift_wsp = add( Q_new, shift ); - +#ifdef TEST_HR + if ( LT_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) ) + { + shift_wsp = sub( shift_wsp, 1 ); + } +#endif /* set and write harmonicity flag */ harm_flag_acelp = 0; move16(); @@ -621,18 +626,33 @@ void encod_gen_voic_ivas_fx( IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { +#ifdef TEST_HR + gain_enc_lbr_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->coder_type, i_subfr_fx, xn_fx, y1_fx, shift_wsp, y2_fx, code_fx, + &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, gc_mem, gp_mem, clip_gain_fx, L_SUBFR ); +#else gain_enc_lbr_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->coder_type, i_subfr_fx, xn_fx, y1_fx, sub( shift_wsp, 1 ), y2_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, gc_mem, gp_mem, clip_gain_fx, L_SUBFR ); +#endif } ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) { +#ifdef TEST_HR + gain_enc_SQ_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr_fx, xn_fx, y1_fx, y2_fx, code_fx, Es_pred_fx, + &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, clip_gain_fx, shift_wsp ); +#else gain_enc_SQ_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr_fx, xn_fx, y1_fx, y2_fx, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, clip_gain_fx, sub( shift_wsp, 1 ) ); +#endif } ELSE { +#ifdef TEST_HR + gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame, i_subfr_fx, -1, xn_fx, y1_fx, shift_wsp, y2_fx, code_fx, Es_pred_fx, + &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, clip_gain_fx ); +#else gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame, i_subfr_fx, -1, xn_fx, y1_fx, sub( shift_wsp, 1 ), y2_fx, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, clip_gain_fx ); +#endif } IF( st_fx->Opt_SC_VBR ) { diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index d6935dd0c..8e4f13116 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -520,7 +520,12 @@ Word16 encod_tran_ivas_fx( move16(); set16_fx( code_preQ, 0, L_SUBFR ); shift_wsp = add( Q_new, shift ); - +#ifdef TEST_HR + if ( LT_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) ) + { + shift_wsp = sub( shift_wsp, 1 ); + } +#endif /*----------------------------------------------------------------* * ACELP subframe loop *----------------------------------------------------------------*/ @@ -540,8 +545,11 @@ Word16 encod_tran_ivas_fx( q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ +#ifdef TEST_HR + Scale_sig( h1, L_SUBFR, sub( 14, q_h1 ) ); +#else Scale_sig( h1, L_SUBFR, sub( 13, q_h1 ) ); - +#endif /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn, L_SUBFR, shift ); @@ -559,7 +567,9 @@ Word16 encod_tran_ivas_fx( IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) ) { +#ifndef TEST_HR Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ +#endif transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr, cn, exc_fx, p_Aq, Aw_fx, h1, xn, xn2, y1, y2, Es_pred_fx, &gain_pit, gain_code, g_corr, clip_gain, &gain_preQ, code_preQ, unbits, Q_new, shift ); } @@ -587,22 +597,37 @@ Word16 encod_tran_ivas_fx( IF( Jopt_flag == 0 ) { /* SQ gain_code */ +#ifdef TEST_HR + gain_enc_tc_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y2, code, Es_pred_fx, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, shift_wsp ); +#else gain_enc_tc_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y2, code, Es_pred_fx, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, sub( shift_wsp, 1 ) ); +#endif } ELSE { IF( GT_32( st_fx->core_brate, ACELP_32k ) ) { /* SQ gain_pit and gain_code */ +#ifdef TEST_HR + gain_enc_SQ_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y1, y2, code, Es_pred_fx, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain, shift_wsp ); +#else gain_enc_SQ_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y1, y2, code, Es_pred_fx, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain, sub( shift_wsp, 1 ) ); +#endif } ELSE { /* VQ gain_pit and gain_code */ +#ifdef TEST_HR + gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame_fx, i_subfr, tc_subfr, xn, y1, shift_wsp, y2, code, Es_pred_fx, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain ); +#else gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame_fx, i_subfr, tc_subfr, xn, y1, sub( shift_wsp, 1 ), y2, code, Es_pred_fx, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain ); +#endif } } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 6718552c5..99e8b44fa 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -1423,7 +1423,11 @@ void transition_enc_ivas_fx( *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, ( Q_new + shift - 1 ) ); move16(); +#ifdef TEST_HR + Copy( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 )); +#else Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); +#endif lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx_q15, xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); @@ -1660,7 +1664,11 @@ void transition_enc_ivas_fx( *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, Q_new ); move16(); +#ifdef TEST_HR + Copy( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ) ); +#else Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); +#endif lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx_q15, xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) @@ -2082,7 +2090,11 @@ static void tc_enc_ivas_fx( /*--------------------------------------------------------------* * compute glottal-shape codebook excitation *--------------------------------------------------------------*/ +#ifdef TEST_HR + Copy( h1, h1_fx, L_SUBFR + ( M + 1 ) ); +#else Copy_Scale_sig( h1, h1_fx, L_SUBFR + ( M + 1 ), 1 ); +#endif /* create filtered glottal codebook contribution */ conv_fx( &exc_fx[i_subfr], h1_fx, yy1_fx, L_SUBFR ); -- GitLab From b98f74c7404d96d9ae934b4746d723fe1aec7803 Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Thu, 10 Apr 2025 12:24:43 -0400 Subject: [PATCH 0980/1221] fix clang --- lib_enc/transition_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 99e8b44fa..9f630da66 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -1424,7 +1424,7 @@ void transition_enc_ivas_fx( move16(); #ifdef TEST_HR - Copy( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 )); + Copy( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ) ); #else Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); #endif -- GitLab From c25105a8f3c6d710462a10a80ab5aa563b5a00a4 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 7 Apr 2025 11:46:08 +0200 Subject: [PATCH 0981/1221] replacingthe basop_util_add_mant2exp() for cy_sum and cy_sum_imag in ivas_param_mc_param_est_enc_fx(). --- lib_enc/ivas_mc_param_enc_fx.c | 99 ++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 54fe249cd..67037e0ad 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -30,6 +30,7 @@ *******************************************************************************************************/ +#define MERGE_REQUEST_1462 #include #include #include "options.h" @@ -59,7 +60,7 @@ static void ivas_param_mc_range_encoder_fx( const Word16 *seq_in, const Word16 n #define ATTACKTHRESHOLD_E 4 -static void ivas_param_mc_quantize_ilds_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 freq_idx, const Word16 nchan_input, const Word16 nchan_transport, Word16 *ILD_idx_out, Word16 ILD_q[PARAM_MC_SZ_ILD_MAP] ); +static void ivas_param_mc_quantize_ilds_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_e[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 freq_idx, const Word16 nchan_input, const Word16 nchan_transport, Word16 *ILD_idx_out, Word16 ILD_q[PARAM_MC_SZ_ILD_MAP] ); static void ivas_param_mc_parameter_quantizer_fx( const Word32 *x, const Word16 *x_e, const Word16 L, const Word16 sz_quantizer, const Word16 *quantizer_fx, const Word16 Q_quant, Word16 *quant_idx, Word16 *y ); @@ -655,8 +656,13 @@ static void ivas_param_mc_param_est_enc_fx( Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ +#ifdef MERGE_REQUEST_1462 + Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; +#else Word32 Cy_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; Word16 Cy_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; +#endif Word32 Cx_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; Word16 Cx_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; Word32 real_part_fx, imag_part_fx; @@ -685,13 +691,26 @@ static void ivas_param_mc_param_est_enc_fx( move16(); band_step = 1; move16(); +#ifdef MERGE_REQUEST_1462 + FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) + { + set64_fx( Cy_sum_real_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); + } + } +#endif FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC; cur_param_band++ ) { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) { - set32_fx( Cy_sum_imag_fx[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); - set16_fx( Cy_sum_imag_e[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); +#ifdef MERGE_REQUEST_1462 + set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); +#else + set32_fx( Cy_sum_fx[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); + set16_fx( Cy_sum_e[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); +#endif } FOR( ch_idx1 = 0; ch_idx1 < PARAM_MC_MAX_TRANSPORT_CHANS; ch_idx1++ ) @@ -832,7 +851,33 @@ static void ivas_param_mc_param_est_enc_fx( move32(); } } - +#ifdef MERGE_REQUEST_1462 + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]; + b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band]; + move32(); + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) + { + Word16 norm; + c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band]; + d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band]; + move32(); +// Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc) + Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], + W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); + move64(); + Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], + W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) ); + move64(); + + // convert the 64 bit fixpoint back into the 48 bit float format + norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); + Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = sub( sub( 62, gb ), norm ); + } + } +#else /* Cy for input channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { @@ -890,6 +935,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); } } +#endif } } @@ -1023,6 +1069,28 @@ static void ivas_param_mc_param_est_enc_fx( move16(); } #endif +#ifdef MERGE_REQUEST_1462 + a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]; + b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band]; + move32(); + move32(); + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) + { + Word16 norm; + c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band]; + d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band]; + move32(); + move32(); +// Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc) + Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], + W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); + move64(); + // convert the 64 bit fixpoint back into the 48 bit float format + norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); + Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = sub( sub( 62, gb ), norm ); + } +#else FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { #ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE @@ -1054,6 +1122,7 @@ static void ivas_param_mc_param_est_enc_fx( &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); move32(); } +#endif } } } @@ -1075,6 +1144,12 @@ static void ivas_param_mc_param_est_enc_fx( move32(); Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move16(); +#ifdef MERGE_REQUEST_1462 + Cy_sum_imag_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move64(); + Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move64(); +#else Cy_sum_imag_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move32(); Cy_sum_imag_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; @@ -1083,6 +1158,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); Cy_sum_imag_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move16(); +#endif } } @@ -1208,10 +1284,16 @@ static void ivas_param_mc_param_est_enc_fx( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); move32(); +#ifdef MERGE_REQUEST_1462 + Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); + move64(); + +#else Cy_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2], &Cy_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] ); move32(); +#endif } } } @@ -1284,15 +1366,22 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ ) { + Word16 norm; real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2]; move32(); real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2]; move16(); +#ifdef MERGE_REQUEST_1462 + // convert the 64 bit fixpoint back into the 48 bit float format + norm = W_norm( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); + imag_part_fx = W_extract_h( W_shl( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); + imag_part_e = sub( (62-gb ), norm ); +#else imag_part_fx = Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2]; move32(); imag_part_e = Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2]; move16(); - +#endif real_part_fx = Mpy_32_32( real_part_fx, real_part_fx ); imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx ); -- GitLab From 3f8794eb82a9c036fd20dd7451c00fd2166ccc5d Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 7 Apr 2025 11:52:36 +0200 Subject: [PATCH 0982/1221] applied the clang patch. --- lib_enc/ivas_mc_param_enc_fx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 67037e0ad..ef1e93405 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -30,7 +30,7 @@ *******************************************************************************************************/ -#define MERGE_REQUEST_1462 +#define MERGE_REQUEST_1462 #include #include #include "options.h" @@ -691,7 +691,7 @@ static void ivas_param_mc_param_est_enc_fx( move16(); band_step = 1; move16(); -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1462 FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ ) { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) @@ -705,7 +705,7 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) { -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1462 set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); #else set32_fx( Cy_sum_fx[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); @@ -863,12 +863,12 @@ static void ivas_param_mc_param_est_enc_fx( c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band]; d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band]; move32(); -// Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc) - Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], - W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); + // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc) + Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], + W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); move64(); - Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], - W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) ); + Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], + W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) ); move64(); // convert the 64 bit fixpoint back into the 48 bit float format @@ -1081,9 +1081,9 @@ static void ivas_param_mc_param_est_enc_fx( d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band]; move32(); move32(); -// Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc) - Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], - W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); + // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc) + Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], + W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); move64(); // convert the 64 bit fixpoint back into the 48 bit float format norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); @@ -1375,7 +1375,7 @@ static void ivas_param_mc_param_est_enc_fx( // convert the 64 bit fixpoint back into the 48 bit float format norm = W_norm( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); imag_part_fx = W_extract_h( W_shl( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); - imag_part_e = sub( (62-gb ), norm ); + imag_part_e = sub( sub( 62, gb ), norm ); #else imag_part_fx = Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2]; move32(); -- GitLab From f3f44d9fad0a858398c13400e72915b21f9ba559 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 9 Apr 2025 09:51:06 +0200 Subject: [PATCH 0983/1221] made the define name a bit more clearer --- lib_enc/ivas_mc_param_enc_fx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index ef1e93405..6ac7c3428 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -30,7 +30,7 @@ *******************************************************************************************************/ -#define MERGE_REQUEST_1462 +#define MERGE_REQUEST_1378_TO_ISSUE_1462 #include #include #include "options.h" @@ -656,7 +656,7 @@ static void ivas_param_mc_param_est_enc_fx( Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; #else @@ -691,7 +691,7 @@ static void ivas_param_mc_param_est_enc_fx( move16(); band_step = 1; move16(); -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ ) { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) @@ -705,7 +705,7 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) { -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); #else set32_fx( Cy_sum_fx[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); @@ -851,7 +851,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); } } -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]; @@ -1069,7 +1069,7 @@ static void ivas_param_mc_param_est_enc_fx( move16(); } #endif -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]; b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band]; move32(); @@ -1144,7 +1144,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move16(); -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 Cy_sum_imag_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move64(); Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; @@ -1284,7 +1284,7 @@ static void ivas_param_mc_param_est_enc_fx( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); move32(); -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); move64(); @@ -1371,7 +1371,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2]; move16(); -#ifdef MERGE_REQUEST_1462 +#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 // convert the 64 bit fixpoint back into the 48 bit float format norm = W_norm( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); imag_part_fx = W_extract_h( W_shl( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); -- GitLab From 740f4864ad452d7ddab3eed1e00868aaef140e27 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 9 Apr 2025 12:20:36 +0200 Subject: [PATCH 0984/1221] Properly named the define in the options.h file. --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index eb0054c53..e8a44d873 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -78,10 +78,10 @@ #define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ /* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ #define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version */ +//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version. Obsoleted by MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ - +#define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ #endif -- GitLab From e586b634bcd9608e2a73c7fb5dadb4938f4c4c59 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Thu, 10 Apr 2025 11:26:04 +0200 Subject: [PATCH 0985/1221] Updated the macro names in the ivas_mc_param_enc_fx.c file. --- lib_enc/ivas_mc_param_enc_fx.c | 76 ++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 6ac7c3428..d0316be0f 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -30,7 +30,6 @@ *******************************************************************************************************/ -#define MERGE_REQUEST_1378_TO_ISSUE_1462 #include #include #include "options.h" @@ -656,7 +655,7 @@ static void ivas_param_mc_param_est_enc_fx( Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; #else @@ -691,7 +690,7 @@ static void ivas_param_mc_param_est_enc_fx( move16(); band_step = 1; move16(); -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ ) { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) @@ -705,7 +704,7 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) { -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); #else set32_fx( Cy_sum_fx[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); @@ -851,7 +850,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); } } -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]; @@ -1069,7 +1068,7 @@ static void ivas_param_mc_param_est_enc_fx( move16(); } #endif -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band]; b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band]; move32(); @@ -1144,7 +1143,11 @@ static void ivas_param_mc_param_est_enc_fx( move32(); Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move16(); -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move64(); + Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move64(); Cy_sum_imag_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move64(); Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; @@ -1166,6 +1169,12 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move64(); + Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move64(); +#endif Cy_sum_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move32(); Cy_sum_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; @@ -1210,10 +1219,18 @@ static void ivas_param_mc_param_est_enc_fx( /* get ICLDs */ FOR( k = 0; k < nchan_input; ++k ) { +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + Word16 norm; + // convert the 64 bit fixpoint back into the 48 bit float format + norm = W_norm( Cy_sum_real_64[cur_param_band][k][k] ); + Nrg_fx[k] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][k][k], norm ) ); + Nrg_e[k] = sub( sub( 62, gb ), norm ); +#else Nrg_fx[k] = Cy_sum_fx[cur_param_band][k][k]; move32(); Nrg_e[k] = Cy_sum_e[cur_param_band][k][k]; move16(); +#endif } FOR( k = 0; k < num_ilds_to_code; ++k ) { @@ -1280,15 +1297,17 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { - Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], - Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], - &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); - move32(); -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); + move64(); Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); move64(); #else + Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], + &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); Cy_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2], &Cy_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] ); @@ -1317,10 +1336,14 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); +#else Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); move32(); +#endif } } } @@ -1329,7 +1352,24 @@ static void ivas_param_mc_param_est_enc_fx( band_step = 2; move16(); } - +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + { + // convert the 64 bit fixpoint back into the 48 bit float format + FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < MAX_CICP_CHANNELS; ch_idx2++ ) + { + Word16 norm; + norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); + Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = sub( sub( 62, gb ), norm ); + } + } + } + } +#endif /* map complex covariances to real values */ FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += band_step ) @@ -1366,12 +1406,8 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ ) { +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word16 norm; - real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2]; - move32(); - real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2]; - move16(); -#ifdef MERGE_REQUEST_1378_TO_ISSUE_1462 // convert the 64 bit fixpoint back into the 48 bit float format norm = W_norm( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); imag_part_fx = W_extract_h( W_shl( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); @@ -1382,6 +1418,10 @@ static void ivas_param_mc_param_est_enc_fx( imag_part_e = Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2]; move16(); #endif + real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2]; + move32(); + real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2]; + move16(); real_part_fx = Mpy_32_32( real_part_fx, real_part_fx ); imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx ); -- GitLab From 2b8875ee9b592244e1e3be965d13c40707d9cd56 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Thu, 10 Apr 2025 16:33:10 +0530 Subject: [PATCH 0986/1221] Fix for 3GPP issue 1447: BASOP encoder: W channel sounds dull and distorted in OSBA at 48 kbps with the LTV --- lib_enc/analy_sp_fx.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index bd4ad12ba..4f96ea2d4 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -494,9 +494,9 @@ void ivas_analy_sp_fx( } ELSE { - Word16 scale = 0; + Word16 scale = 0, shift; move16(); - + shift = s_min( norm_arr( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT ), norm_arr( speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT ) ); FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) { /* set pointer to the beginning of the signal for spectral analysis */ @@ -507,27 +507,26 @@ void ivas_analy_sp_fx( /* set the pointer for second analysis window */ pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; } - /* Clear 1st value of 1st part, copy 1st value of 2nd part */ pt_fft[0] = 0; move16(); - pt_fft[L_FFT / 2] = pt[L_FFT / 2]; // Q_new - preemph_bits + pt_fft[L_FFT / 2] = shl( pt[L_FFT / 2], shift ); // (Q_new + shift) - preemph_bits move16(); FOR( i = 1; i < L_FFT / 2; i++ ) { /* 1st windowed part */ - pt_fft[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); // Q_new - preemph_bits + pt_fft[i] = mult_r( shl( pt[i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits move16(); /* 2nd windowed part */ - pt_fft[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); // Q_new - preemph_bits + pt_fft[L_FFT - i] = mult_r( shl( pt[L_FFT - i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits move16(); } /* compute the spectrum */ fft_rel_16_32fx( pt_fft, &scale, i_subfr, L_FFT, LOG2_L_FFT ); - *q_fft_buff = add( Q_new, scale ); // resultant q for fft_buff + *q_fft_buff = add( add( Q_new, shift ), scale ); // resultant q for fft_buff move16(); IF( EQ_16( i_subfr, 1 ) ) { -- GitLab From ce7f9468512dfe09e52deb093205900072031755 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 4 Apr 2025 11:52:59 +0530 Subject: [PATCH 0987/1221] Fix for 3GPP issue 1410: Major Difference for Stereo input at noisy segments 13.2 kbps DTX 32kHz SWB - 2 Link #1410 --- lib_enc/fd_cng_enc_fx.c | 12 ++-- lib_enc/ivas_core_pre_proc_front_fx.c | 51 ++------------- lib_enc/ivas_front_vad_fx.c | 18 ++---- lib_enc/nois_est_fx.c | 93 +++++++++++++++++++++------ lib_enc/prot_fx_enc.h | 3 + 5 files changed, 95 insertions(+), 82 deletions(-) diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index d182e4a44..c773212db 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -2317,8 +2317,10 @@ void perform_noise_estimation_enc_ivas_fx( move32(); periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) ); move16(); - max_exp = s_max( max_exp, periodog_exp[i] ); - + if ( *ptr_per_fx ) + { + max_exp = s_max( max_exp, periodog_exp[i] ); + } ptr_per_fx++; i++; } @@ -2350,8 +2352,8 @@ void perform_noise_estimation_enc_ivas_fx( &hFdCngEnc->msPeriodog_fx_exp_cldfb ); ///* find common exponent for fft part and cldfb part of msperiodog */ - s1 = getScaleFactor32( msPeriodog_fx, nFFTpart ); - s2 = getScaleFactor32( &msPeriodog_fx[nFFTpart], nCLDFBpart ); + s1 = L_norm_arr( msPeriodog_fx, nFFTpart ); + s2 = L_norm_arr( &msPeriodog_fx[nFFTpart], nCLDFBpart ); s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) ); s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft ); @@ -2370,7 +2372,7 @@ void perform_noise_estimation_enc_ivas_fx( FOR( i = 0; i < nCLDFBpart; i++ ) { - msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s_min( 31, s2 ) ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ + msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s2 ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ move32(); } } diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 405d08301..b2fdcf821 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -775,14 +775,9 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - Word16 scale = add( L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ), st->hNoiseEst->q_bckr ); - scale = s_min( scale, add( L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ), st->hNoiseEst->q_enrO ) ); + Word16 scale = add( L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ), st->hNoiseEst->q_enrO ); scale = s_min( scale, fr_bands_fx_q ); - scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); - st->hNoiseEst->q_bckr = scale; - move16(); - scale_sig32( st->hNoiseEst->enrO_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_enrO ) ); st->hNoiseEst->q_enrO = scale; move16(); @@ -917,44 +912,14 @@ ivas_error pre_proc_front_ivas_fx( * Correlation correction as a function of total noise level *----------------------------------------------------------------*/ - noise_est_down_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, + noise_est_down_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, &st->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_fx, &st->hNoiseEst->Etot_v_h2_fx ); - q_tmpN = fr_bands_fx_q; - q_tmpE = fr_bands_fx_q; - move16(); - move16(); test(); IF( lr_vad_enabled && st->idchan == 0 ) { - scale = add( L_norm_arr( hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, NB_BANDS ), hCPE->hFrontVad[0]->hNoiseEst->q_bckr ); - scale = s_min( scale, add( L_norm_arr( hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, NB_BANDS ), hCPE->hFrontVad[1]->hNoiseEst->q_bckr ) ); - scale = s_min( scale, add( L_norm_arr( fr_bands_LR_fx[0], 2 * NB_BANDS ), fr_bands_LR_fx_q[0] ) ); - scale = s_min( scale, add( L_norm_arr( fr_bands_LR_fx[1], 2 * NB_BANDS ), fr_bands_LR_fx_q[1] ) ); - - scale_sig32( fr_bands_LR_fx[0], 2 * NB_BANDS, sub( scale, fr_bands_LR_fx_q[0] ) ); - fr_bands_LR_fx_q[0] = scale; - move16(); - scale_sig32( fr_bands_LR_fx[1], 2 * NB_BANDS, sub( scale, fr_bands_LR_fx_q[1] ) ); - fr_bands_LR_fx_q[1] = scale; - move16(); - - scale_sig32( hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[0]->hNoiseEst->q_bckr ) ); - hCPE->hFrontVad[0]->hNoiseEst->q_bckr = scale; - move16(); - scale_sig32( hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[1]->hNoiseEst->q_bckr ) ); - hCPE->hFrontVad[1]->hNoiseEst->q_bckr = scale; - move16(); - - noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, tmpN_LR_fx[0], tmpE_LR_fx[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, Etot_LR_fx[0], &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx ); - noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, tmpN_LR_fx[1], tmpE_LR_fx[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, Etot_LR_fx[1], &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx ); - - q_tmpN_LR[0] = q_tmpE_LR[0] = scale; - move16(); - move16(); - q_tmpN_LR[1] = q_tmpE_LR[1] = scale; - move16(); - move16(); + noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[0]->hNoiseEst->q_bckr, tmpN_LR_fx[0], &q_tmpN_LR[0], tmpE_LR_fx[0], &q_tmpE_LR[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, Etot_LR_fx[0], &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx ); + noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[1]->hNoiseEst->q_bckr, tmpN_LR_fx[1], &q_tmpN_LR[1], tmpE_LR_fx[1], &q_tmpE_LR[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, Etot_LR_fx[1], &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx ); corr_shiftL_fx = correlation_shift_fx( hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx ); // Q15 corr_shiftR_fx = correlation_shift_fx( hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx ); // Q15 @@ -1310,14 +1275,6 @@ ivas_error pre_proc_front_ivas_fx( /*------------------------------------------------------------------* * Update estimated noise energy and voicing cut-off frequency *-----------------------------------------------------------------*/ - { - // TODO: this scalings to be checked - scale = s_min( Q30, add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ) ); - scale = s_min( scale, sub( add( fr_bands_fx_q, L_norm_arr( fr_bands_fx, 2 * NB_BANDS ) ), 4 ) ); - scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); - scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); - st->hNoiseEst->q_bckr = fr_bands_fx_q = scale; - } scale = s_min( Q31, s_min( add( q_tmpN, L_norm_arr( tmpN_fx, NB_BANDS ) ), add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ) ) ); scale = sub( scale, 1 ); // guard bits diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index 25a936566..b21a66952 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -609,14 +609,8 @@ ivas_error front_vad_spar_fx( Q_inp_12k8 = hFrontVad->q_buffer_12k8; move16(); - scale = s_min( add( q_fr_bands[0], L_norm_arr( fr_bands_fx[0], 2 * NB_BANDS ) ), add( hFrontVad->hNoiseEst->q_bckr, L_norm_arr( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS ) ) ); - scale_sig32( fr_bands_fx[0], 40, sub( scale, q_fr_bands[0] ) ); // scale - scale_sig32( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); // scale - hFrontVad->hNoiseEst->q_bckr = q_fr_bands[0] = scale; - move16(); - move16(); - - noise_est_down_ivas_fx( fr_bands_fx[0], q_fr_bands[0], hFrontVad->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, + Word16 q_tmpN, q_tmpE; + noise_est_down_ivas_fx( fr_bands_fx[0], q_fr_bands[0], hFrontVad->hNoiseEst->bckr_fx, &hFrontVad->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ @@ -727,18 +721,18 @@ ivas_error front_vad_spar_fx( Scale_sig32( epsP_fx, M + 1, scale ); // Q_esp scale = add( hFrontVad->hNoiseEst->ave_enr_q, s_min( L_norm_arr( hFrontVad->hNoiseEst->ave_enr_fx, NB_BANDS ), L_norm_arr( hFrontVad->hNoiseEst->ave_enr2_fx, NB_BANDS ) ) ); - scale = s_min( scale, add( hFrontVad->hNoiseEst->q_bckr, L_norm_arr( tmpE_fx, NB_BANDS ) ) ); + scale = s_min( scale, add( q_tmpE, L_norm_arr( tmpE_fx, NB_BANDS ) ) ); scale = sub( s_min( scale, Q31 ), 1 ); scale_sig32( hFrontVad->hNoiseEst->ave_enr_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->ave_enr_q ) ); scale_sig32( hFrontVad->hNoiseEst->ave_enr2_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->ave_enr_q ) ); - scale_sig32( tmpE_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); + scale_sig32( tmpE_fx, NB_BANDS, sub( scale, q_tmpE ) ); hFrontVad->hNoiseEst->ave_enr_q = scale; move16(); - scale = add( hFrontVad->hNoiseEst->q_bckr, s_min( L_norm_arr( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS ), L_norm_arr( tmpN_fx, NB_BANDS ) ) ); + scale = s_min( add( hFrontVad->hNoiseEst->q_bckr, L_norm_arr( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS ) ), add( q_tmpN, L_norm_arr( tmpN_fx, NB_BANDS ) ) ); scale = sub( s_min( Q31, scale ), 1 ); // guard bits scale_sig32( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); - scale_sig32( tmpN_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); + scale_sig32( tmpN_fx, NB_BANDS, sub( scale, q_tmpN ) ); hFrontVad->hNoiseEst->q_bckr = scale; move16(); diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index e59ef07d9..c8f698da9 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -740,14 +740,17 @@ void noise_est_down_ivas_fx( const Word32 fr_bands[], /* i : per band input energy (contains 2 vectors) q_fr_bands */ const Word16 q_fr_bands, /* i : Q of fr_bands */ Word32 bckr[], /* i/o: per band background noise energy estimate q_fr_bands */ - Word32 tmpN[], /* o : temporary noise update q_fr_bands */ - Word32 enr[], /* o : averaged energy over both subframes */ - const Word16 min_band, /* i : minimum critical band */ - const Word16 max_band, /* i : maximum critical band */ - Word16 *totalNoise, /* o : noise estimate over all critical bands */ - Word16 Etot, /* i : Energy of current frame */ - Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ - Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ + Word16 *q_bckr, + Word32 tmpN[], /* o : temporary noise update q_fr_bands */ + Word16 *q_tmpN, + Word32 enr[], /* o : averaged energy over both subframes */ + Word16 *q_enr, + const Word16 min_band, /* i : minimum critical band */ + const Word16 max_band, /* i : maximum critical band */ + Word16 *totalNoise, /* o : noise estimate over all critical bands */ + Word16 Etot, /* i : Energy of current frame */ + Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ ) { @@ -755,13 +758,17 @@ void noise_est_down_ivas_fx( const Word32 *pt1, *pt2; Word16 i; Word16 e_Noise, f_Noise; - Word32 e_min; Word32 totalNoise_temp; Word32 L_Etot, L_Etot_last, L_Etot_v_h2, L_Etot_v; Word64 sum; Word16 q_sum; + Word32 enr32[NB_BANDS], bckr32[NB_BANDS], tmpN32[NB_BANDS]; + Word16 enr_q[NB_BANDS], bckr_q[NB_BANDS], tmpN_q[NB_BANDS]; + Word16 shift, shift1, shift2, shift3; + Word64 tmpN64, tmp, enr64; - e_min = L_shl( E_MIN_FXQ31, sub( q_fr_bands, Q31 ) ); // q_fr_bands + Copy32( bckr, bckr32, NB_BANDS ); + set16_fx( bckr_q, *q_bckr, NB_BANDS ); L_Etot = L_shl( Etot, 16 ); /*Q24 for later AR1 computations*/ L_Etot_last = L_shl( *Etot_last, 16 ); @@ -778,7 +785,7 @@ void noise_est_down_ivas_fx( { sum = W_mac_32_16( sum, bckr[i], 1 ); // q_fr_bands+1 } - q_sum = add( q_fr_bands, 1 ); + q_sum = add( *q_bckr, 1 ); IF( sum == 0 ) { sum = W_mult0_32_32( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ); // Q31 @@ -808,8 +815,12 @@ void noise_est_down_ivas_fx( FOR( i = 0; i < NB_BANDS; i++ ) { /* enr[i] = 0.5f * ( *pt1++ + *pt2++ ); */ - enr[i] = W_extract_h( W_mac_32_32( W_mult_32_32( *pt1, ONE_IN_Q30 ), *pt2, ONE_IN_Q30 ) ); // q_fr_bands+30+1-32+1 = q_fr_bands + enr64 = W_mac_32_32( W_mult_32_32( *pt1, ONE_IN_Q29 ), *pt2, ONE_IN_Q29 ); // q_fr_bands + 1 + Q29 + 1 (0.5 handle here) + shift = W_norm( enr64 ); + enr32[i] = W_extract_h( W_shl( enr64, shift ) ); move32(); + enr_q[i] = sub( add( q_fr_bands, shift ), 1 ); + move16(); pt1++; pt2++; } @@ -817,20 +828,66 @@ void noise_est_down_ivas_fx( /*-----------------------------------------------------------------* * Background noise energy update *-----------------------------------------------------------------*/ - FOR( i = 0; i < NB_BANDS; i++ ) { /* tmpN[i] = (1-ALPHA) * bckr[i] + ALPHA * enr[i]; */ /* handle div by zero in find_tilt_fx */ - tmpN[i] = L_max( Madd_32_16( Mpy_32_16_1( bckr[i], ALPHAM1_FX ), enr[i], ALPHA_FX ), e_min ); // q_fr_bands - move32(); - /* if( tmpN[i] < bckr[i] ) { bckr[i] = tmpN[i]; }*/ - /* Defend to increase noise estimate: keep as it is or decrease */ - bckr[i] = L_max( L_min( bckr[i], tmpN[i] ), e_min ); // q_fr_bands + tmpN64 = W_mult_32_16( bckr32[i], ALPHAM1_FX ); + tmp = W_mult_32_16( enr32[i], ALPHA_FX ); + + shift = s_min( bckr_q[i], enr_q[i] ); + tmpN64 = W_add( W_shl( tmpN64, sub( shift, bckr_q[i] ) ), W_shl( tmp, sub( shift, enr_q[i] ) ) ); // shift + q16 + shift1 = W_norm( tmpN64 ); + tmpN32[i] = W_extract_h( W_shl( tmpN64, shift1 ) ); // shift + q16 + shift1 - 32 move32(); + tmpN_q[i] = sub( add( add( Q16, shift ), shift1 ), 32 ); + move16(); + + IF( GT_32( E_MIN_FXQ31, L_shl_sat( tmpN32[i], sub( 31, tmpN_q[i] ) ) ) ) + { + tmpN32[i] = E_MIN_FXQ31; + tmpN_q[i] = 31; + move32(); + move16(); + } + + IF( GT_32( bckr32[i], L_shl_sat( tmpN32[i], sub( bckr_q[i], tmpN_q[i] ) ) ) ) + { + bckr32[i] = tmpN32[i]; /* Defend to increase noise estimate: keep as it is or decrease */ + bckr_q[i] = tmpN_q[i]; + move32(); + move16(); + } } + /* Scaling to common Q*/ + shift1 = bckr_q[0], shift2 = enr_q[0], shift3 = tmpN_q[0]; + move16(); + move16(); + move16(); + + FOR( i = 1; i < NB_BANDS; i++ ) + { + shift1 = s_min( shift1, bckr_q[i] ); + shift2 = s_min( shift2, enr_q[i] ); + shift3 = s_min( shift3, tmpN_q[i] ); + } + FOR( i = 0; i < NB_BANDS; i++ ) + { + bckr[i] = L_shl( bckr32[i], sub( shift1, bckr_q[i] ) ); + enr[i] = L_shl( enr32[i], sub( shift2, enr_q[i] ) ); + tmpN[i] = L_shl( tmpN32[i], sub( shift3, tmpN_q[i] ) ); + move32(); + move32(); + move32(); + } + *q_bckr = shift1; + *q_enr = shift2; + *q_tmpN = shift3; + move16(); + move16(); + move16(); /*------------------------------------------------------------------* * Energy variation update *------------------------------------------------------------------*/ diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 95bcb70d2..1319d2862 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -355,8 +355,11 @@ void noise_est_down_ivas_fx( const Word32 fr_bands[], /* i : per band i energy (contains 2 vectors) */ const Word16 q_fr_bands, /* i : Q of fr_bands */ Word32 bckr[], /* i/o: per band background noise energy estimate */ + Word16 *q_bckr, Word32 tmpN[], /* o : temporary noise update */ + Word16 *q_tmpN, Word32 enr[], /* o : averaged energy over both subframes */ + Word16 *q_enr, const Word16 min_band, /* i : minimum critical band */ const Word16 max_band, /* i : maximum critical band */ Word16 *totalNoise, /* o : noise estimate over all critical bands */ -- GitLab From 5ab1f5c22a35df4fed0295535be6cec0844a4151 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 4 Apr 2025 11:58:57 +0530 Subject: [PATCH 0988/1221] Clang formatting changes --- lib_enc/ivas_core_pre_proc_front_fx.c | 2 +- lib_enc/prot_fx_enc.h | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index b2fdcf821..0d6a5901a 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -775,7 +775,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - Word16 scale = add( L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ), st->hNoiseEst->q_enrO ); + Word16 scale = add( L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ), st->hNoiseEst->q_enrO ); scale = s_min( scale, fr_bands_fx_q ); scale_sig32( st->hNoiseEst->enrO_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_enrO ) ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 1319d2862..51e9849c7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -356,16 +356,16 @@ void noise_est_down_ivas_fx( const Word16 q_fr_bands, /* i : Q of fr_bands */ Word32 bckr[], /* i/o: per band background noise energy estimate */ Word16 *q_bckr, - Word32 tmpN[], /* o : temporary noise update */ + Word32 tmpN[], /* o : temporary noise update */ Word16 *q_tmpN, - Word32 enr[], /* o : averaged energy over both subframes */ + Word32 enr[], /* o : averaged energy over both subframes */ Word16 *q_enr, - const Word16 min_band, /* i : minimum critical band */ - const Word16 max_band, /* i : maximum critical band */ - Word16 *totalNoise, /* o : noise estimate over all critical bands */ - Word16 Etot, /* i : Energy of current frame */ - Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ - Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ + const Word16 min_band, /* i : minimum critical band */ + const Word16 max_band, /* i : maximum critical band */ + Word16 *totalNoise, /* o : noise estimate over all critical bands */ + Word16 Etot, /* i : Energy of current frame */ + Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ ); void noise_est_fx( -- GitLab From 70678f13d9dcd5fec96c87f605769ec7bca4d707 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 08:00:09 +0200 Subject: [PATCH 0989/1221] fix memory error in FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic --- lib_com/swb_tbe_com_fx.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d017914dc..8a4a44c7b 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7230,15 +7230,17 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); move32(); move32(); } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); @@ -7286,6 +7288,15 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + FOR( j = 0; j < 4; j++ ) + { + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + } + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From 5fe189beaf3e0537bfcb840690ae8048d2bad78a Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 08:16:01 +0200 Subject: [PATCH 0990/1221] fix conflict --- lib_com/options.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e2d92e670..796c29dda 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -82,12 +82,9 @@ #define HARM_PUSH_BIT #define HARM_ENC_INIT //#define HARM_SCE_INIT -<<<<<<< HEAD +#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ +#define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -======= -#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ -#define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ ->>>>>>> main #endif -- GitLab From 83e6adf7d674df3ed1eb016605ec5e954359919b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 08:44:39 +0200 Subject: [PATCH 0991/1221] deactivate all speedups --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 796c29dda..d9dc70338 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,7 +84,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8a4a44c7b..72857d1fb 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6687,13 +6687,40 @@ void wb_tbe_extras_reset_synth_fx( return; } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word16 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +static inline Word64 wmac_1616( Word64 x1, Word16 x2, Word16 x3 ) +{ + return W_mac_16_16( x1, x2, x3 ); +} + +static inline Word64 wmac_3216( Word64 x1, Word32 x2, Word16 x3 ) +{ + return W_mac_32_16( x1, x2, x3 ); +} + +static inline Word64 wmsu_3216( Word64 x1, Word32 x2, Word16 x3 ) +{ + return W_msu_32_16( x1, x2, x3 ); +} + +inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *input32_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) { Word32 L_tmpX; Word16 i; Word32 L_tmpMax2 = *L_tmpMax; Word32 L_tmpAbs; move32(); + + if(input16_fx > 0) + { + Word64 ( *wmac )( Word64, Word16, Word16 ); + Word64 ( *wmsu )( Word64, Word32, Word16 ); + } + if( input32_fx > 0 ) + { + Word64 ( *wmac )( Word64, Word32, Word16 ); + Word64 ( *wmsu )( Word64, Word32, Word16 ); + } + IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -- GitLab From 4cf3a55949a04cde9957911a047e48481a0c27ff Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 08:46:31 +0200 Subject: [PATCH 0992/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 72857d1fb..916bd3588 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6710,12 +6710,12 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i Word32 L_tmpAbs; move32(); - if(input16_fx > 0) + if ( input16_fx > 0 ) { Word64 ( *wmac )( Word64, Word16, Word16 ); Word64 ( *wmsu )( Word64, Word32, Word16 ); } - if( input32_fx > 0 ) + if ( input32_fx > 0 ) { Word64 ( *wmac )( Word64, Word32, Word16 ); Word64 ( *wmsu )( Word64, Word32, Word16 ); -- GitLab From cfeceee1088b315b9949acfee3392c0d75e1bc76 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 09:21:58 +0200 Subject: [PATCH 0993/1221] synched FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic with be branch, changed func1 --- lib_com/swb_tbe_com_fx.c | 127 ++++++++++++--------------------------- 1 file changed, 37 insertions(+), 90 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 916bd3588..4dc678913 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6697,9 +6697,14 @@ static inline Word64 wmac_3216( Word64 x1, Word32 x2, Word16 x3 ) return W_mac_32_16( x1, x2, x3 ); } -static inline Word64 wmsu_3216( Word64 x1, Word32 x2, Word16 x3 ) +static inline Word64 finalSat16( Word64 W_tmpx, Word64 W_tmpy ) { - return W_msu_32_16( x1, x2, x3 ); + return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +} + +static inline Word64 finalSat32( Word64 W_tmpx, Word64 W_tmpy ) +{ + return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); } inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *input32_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) @@ -6713,12 +6718,16 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i if ( input16_fx > 0 ) { Word64 ( *wmac )( Word64, Word16, Word16 ); - Word64 ( *wmsu )( Word64, Word32, Word16 ); + Word64 ( *finalSat )( Word64, Word64 ); + wmac = wmac_1616; + finalSat = finalSat16; } if ( input32_fx > 0 ) { Word64 ( *wmac )( Word64, Word32, Word16 ); - Word64 ( *wmsu )( Word64, Word32, Word16 ); + Word64 ( *finalSat )( Word64, Word64 ); + wmac = wmac_3216; + finalSat = finalSat32; } IF( !IsUpsampled3 ) @@ -6726,16 +6735,16 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ move32(); if ( *L_tmpMax > 0 ) { @@ -6747,27 +6756,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i } } #else - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } + assert( 0 ); /*kein bock*/ #endif } /*IsUpsampled3*/ ELSE @@ -6829,58 +6818,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i i++; } #else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } + assert( 0 ); /*kein bock*/ #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; @@ -6932,32 +6870,41 @@ void elliptic_bpf_48k_generic_fx( Word32 memory2_fx_2[4], memory2_fx_3[4]; #endif - FOR( i = 0; i < 4; i++ ) - { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + { + FOR( i = 0; i < 4; i++ ) memory_fx0 = extract_l( memory_fx2[0][i] ); input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); + } #else + FOR( i = 0; i < 4; i++ ) + { memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); -#endif move32(); move32(); move32(); move32(); move32(); } + } +#endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); + elliptic_bpf_48k_generic_func1( input_fx, 0, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ IF( !IsUpsampled3 ) { @@ -7141,7 +7088,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); + elliptic_bpf_48k_generic_func1( 0, L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 IF( isIVAS ) @@ -7270,7 +7217,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); + elliptic_bpf_48k_generic_func1( 0, L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 IF( isIVAS ) @@ -7323,7 +7270,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } - + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From c72ae0ff80b67d3ba36abea7b14bd60bf43fbf8b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 09:26:02 +0200 Subject: [PATCH 0994/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 360 +++++++++++++++++++-------------------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 4dc678913..24d05a27c 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6872,7 +6872,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic { - FOR( i = 0; i < 4; i++ ) + FOR( i = 0; i < 4; i++ ) memory_fx0 = extract_l( memory_fx2[0][i] ); input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); @@ -6898,7 +6898,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } - } +} #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -7018,61 +7018,61 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +move32(); + +L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +move32(); + +L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +move32(); +L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +move32(); +FOR( i = 4; i < L_FRAME48k; i++ ) +{ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } +} #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; @@ -7130,64 +7130,64 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ +L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ +L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ +move32(); +L_tmpMax = L_abs( L_tmp2[0] ); +L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +move32(); +L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); +L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +move32(); +L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); +L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ +L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ +move32(); +L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); +FOR( i = 4; i < L_FRAME48k; i++ ) +{ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); +} #endif @@ -7262,80 +7262,80 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - FOR( j = 0; j < 4; j++ ) - { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - } - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ +FOR( j = 0; j < 4; j++ ) +{ + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); +} - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ +L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ +L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ +move32(); +L_tmpMax = L_abs( L_output[0] ); + +L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ +L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ +L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ +move32(); +L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + +L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ +L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ +L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +move32(); +L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + +L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ +move32(); +L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + +FOR( i = 4; i < L_FRAME48k; i++ ) +{ + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); +} #endif -- GitLab From 3c2f24ba4a8f61246524a6b1f8c02edcdd3eedf2 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 09:38:47 +0200 Subject: [PATCH 0995/1221] fix error - deactivate all speedups --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index d9dc70338..fac5b1dfc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,7 +84,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +////#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 24d05a27c..9405f0aaf 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6871,8 +6871,8 @@ void elliptic_bpf_48k_generic_fx( #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + FOR( i = 0; i < 4; i++ ) { - FOR( i = 0; i < 4; i++ ) memory_fx0 = extract_l( memory_fx2[0][i] ); input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); @@ -6898,7 +6898,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } -} #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic -- GitLab From fa009ccaa2ae8c3bd9c7a3f9bde78511f84ccb8e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 09:42:03 +0200 Subject: [PATCH 0996/1221] clang patch --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 356 +++++++++++++++++++-------------------- 2 files changed, 179 insertions(+), 179 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index fac5b1dfc..d9dc70338 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,7 +84,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -////#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 9405f0aaf..1e8ded1ca 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7017,61 +7017,61 @@ void elliptic_bpf_48k_generic_fx( #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ -L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -move32(); - -L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -move32(); - -L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -move32(); -L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ -move32(); -FOR( i = 4; i < L_FRAME48k; i++ ) -{ - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -} + + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; @@ -7129,64 +7129,64 @@ FOR( i = 4; i < L_FRAME48k; i++ ) #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ -L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ -L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ -move32(); -L_tmpMax = L_abs( L_tmp2[0] ); -L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -move32(); -L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); -L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -move32(); -L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); -L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ -L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ -move32(); -L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -FOR( i = 4; i < L_FRAME48k; i++ ) -{ - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); -} + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } #endif @@ -7261,80 +7261,80 @@ FOR( i = 4; i < L_FRAME48k; i++ ) #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ -FOR( j = 0; j < 4; j++ ) -{ - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + FOR( j = 0; j < 4; j++ ) + { + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + } + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ move32(); + L_tmpMax = L_abs( L_output[0] ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); -} + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); -L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ -L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ -L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ -move32(); -L_tmpMax = L_abs( L_output[0] ); - -L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ -L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ -L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ -move32(); -L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); - -L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ -L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ -L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -move32(); -L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); - -L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ -move32(); -L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); - -FOR( i = 4; i < L_FRAME48k; i++ ) -{ - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); -} + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } #endif -- GitLab From 89cdfaf59e5cb05b12fd5ec649a3abccd8b11674 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 09:50:56 +0200 Subject: [PATCH 0997/1221] some more work on func1 --- lib_com/swb_tbe_com_fx.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1e8ded1ca..8044e9367 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6686,7 +6686,7 @@ void wb_tbe_extras_reset_synth_fx( return; } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +#if defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 ) && defined (FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1) static inline Word64 wmac_1616( Word64 x1, Word16 x2, Word16 x3 ) { return W_mac_16_16( x1, x2, x3 ); @@ -6719,6 +6719,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i { Word64 ( *wmac )( Word64, Word16, Word16 ); Word64 ( *finalSat )( Word64, Word64 ); + Word16 *input_fx = input16_fx; wmac = wmac_1616; finalSat = finalSat16; } @@ -6726,13 +6727,13 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i { Word64 ( *wmac )( Word64, Word32, Word16 ); Word64 ( *finalSat )( Word64, Word64 ); + Word32 *input_fx = input32_fx; wmac = wmac_3216; finalSat = finalSat32; } IF( !IsUpsampled3 ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); @@ -6755,22 +6756,18 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } } -#else - assert( 0 ); /*kein bock*/ -#endif } /*IsUpsampled3*/ ELSE { /*IsUpsampled3*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; ) { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpX = wmac( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ move32(); if ( *L_tmpMax > 0 ) { @@ -6782,13 +6779,13 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i } i++; - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ move32(); if ( *L_tmpMax > 0 ) { @@ -6801,11 +6798,11 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i i++; W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpX = wmac( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ move32(); if ( *L_tmpMax > 0 ) { @@ -6817,9 +6814,6 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i } i++; } -#else - assert( 0 ); /*kein bock*/ -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; move32(); -- GitLab From db082f377b3ccd6b196d1cf00e1ca12f554b09de Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 10:07:27 +0200 Subject: [PATCH 0998/1221] clang patch --- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index d9dc70338..796c29dda 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,7 +84,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 8044e9367..1008b9554 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7043,6 +7043,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From eeb01697dd5a4a88011c6a4ae198d372b401a475 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 10:10:00 +0200 Subject: [PATCH 0999/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1008b9554..6a97ae0c5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6686,7 +6686,7 @@ void wb_tbe_extras_reset_synth_fx( return; } -#if defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 ) && defined (FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1) +#if defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 ) && defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 ) static inline Word64 wmac_1616( Word64 x1, Word16 x2, Word16 x3 ) { return W_mac_16_16( x1, x2, x3 ); @@ -6814,7 +6814,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i } i++; } - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; move32(); } -- GitLab From 840a1e90837b3748ea00b38206c339f108f62fb2 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 11 Apr 2025 10:33:10 +0200 Subject: [PATCH 1000/1221] lib_rend: replace BASOP_Util_Divide3232_Scale_cadence() by BASOP_Util_Divide3232_Scale_newton() --- .../ivas_dirac_dec_binaural_functions_fx.c | 44 +++++++++---------- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 20 ++++----- lib_rend/ivas_dirac_rend_fx.c | 10 ++--- lib_rend/ivas_orient_trk_fx.c | 14 +++--- lib_rend/ivas_reverb_filter_design_fx.c | 22 +++++----- lib_rend/ivas_rotation_fx.c | 2 +- lib_rend/ivas_shoebox_fx.c | 8 ++-- lib_rend/lib_rend.c | 4 +- 8 files changed, 62 insertions(+), 62 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index ce602160f..59ba8062e 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1655,7 +1655,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); /* Formulate average diffuseness over frame */ - frameMeanDiffuseness = BASOP_Util_Divide3232_Scale_cadence( frameMeanDiffuseness, L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &exp ); // exp = exp + 31 - q_meanEnePerCh - exp1 + frameMeanDiffuseness = BASOP_Util_Divide3232_Scale_newton( frameMeanDiffuseness, L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &exp ); // exp = exp + 31 - q_meanEnePerCh - exp1 exp = sub( exp, sub( sub( 31, q_meanEnePerCh ), exp1 ) ); hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 move32(); @@ -1687,7 +1687,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move16(); den = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEnePrev_fx[0][bin], hDiracDecBin->ChEnePrev_e[0][bin], hDiracDecBin->ChEnePrev_fx[1][bin], hDiracDecBin->ChEnePrev_e[1][bin], &den_e ); den = L_max( 1, den ); - IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp ); + IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_newton( num, den, &exp ); exp = add( sub( num_e, den_e ), add( 5, exp ) ); IF( L_shr_sat( IIReneLimiter_fx, sub( 31, exp ) ) > 0 ) { @@ -3310,7 +3310,7 @@ static void eig2x2_fx( tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); #if 1 - tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); + tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3386,7 +3386,7 @@ static void eig2x2_fx( tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); #if 1 - tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); + tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); @@ -3731,11 +3731,11 @@ static void chol2x2_fx( // 4611686 = 1e-12 in Q62 IF( outRe[0][0] == 0 ) { - outRe[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); + outRe[1][0] = BASOP_Util_Divide3232_Scale_newton( c_re, 4611686, &exp ); move32(); q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) ); - outIm[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_im, 4611686, &exp ); + outIm[1][0] = BASOP_Util_Divide3232_Scale_newton( c_im, 4611686, &exp ); move32(); q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); } @@ -3792,7 +3792,7 @@ static void chol2x2_fx( } ELSE { - temp = BASOP_Util_Divide3232_Scale_cadence( temp, e1, &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( temp, e1, &exp ); q_tmp = add( sub( 31, exp ), sub( q_tmp, q_e ) ); } if ( temp == 0 ) @@ -3837,7 +3837,7 @@ static void chol2x2_fx( // 4611686 = Q62 IF( outRe[1][1] == 0 ) { - // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); + // outRe[0][1] = BASOP_Util_Divide3232_Scale_newton( c_re, 4611686, &exp ); Word32 tmp1 = 1953125005; /* 1/4611686 Q62 */ exp = 9; @@ -3845,7 +3845,7 @@ static void chol2x2_fx( move32(); q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) ); - // outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, 4611686, &exp ); + // outIm[0][1] = BASOP_Util_Divide3232_Scale_newton( -c_im, 4611686, &exp ); outIm[0][1] = Mpy_32_32( tmp1, -c_im ); move32(); q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); @@ -3853,13 +3853,13 @@ static void chol2x2_fx( ELSE { { - // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); - Word32 tmp1 = BASOP_Util_Divide3232_Scale_cadence( 0x7FFFFFFF, outRe[1][1], &exp ); + // outRe[0][1] = BASOP_Util_Divide3232_Scale_newton( c_re, outRe[1][1], &exp ); + Word32 tmp1 = BASOP_Util_Divide3232_Scale_newton( 0x7FFFFFFF, outRe[1][1], &exp ); outRe[0][1] = Mpy_32_32( tmp1, c_re ); move32(); q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); - // outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, outRe[1][1], &exp ); + // outIm[0][1] = BASOP_Util_Divide3232_Scale_newton( -c_im, outRe[1][1], &exp ); outIm[0][1] = Mpy_32_32( tmp1, -c_im ); move32(); q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); @@ -3882,12 +3882,12 @@ static void chol2x2_fx( // 4611686 = 1e-12 in Q62 IF( e2 == 0 ) { - temp = BASOP_Util_Divide3232_Scale_cadence( temp, 4611686, &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( temp, 4611686, &exp ); q_tmp = add( sub( 31, exp ), sub( q_tmp, 62 ) ); } ELSE { - temp = BASOP_Util_Divide3232_Scale_cadence( temp, e2, &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( temp, e2, &exp ); q_tmp = add( sub( 31, exp ), sub( q_tmp, q_e ) ); } if ( temp == 0 ) @@ -4035,7 +4035,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxEne_fx, &exp ); + maxEneDiv_fx = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, maxEne_fx, &exp ); q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) ); } exp = norm_l( maxEneDiv_fx ); @@ -4100,7 +4100,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, 4611686, &exp ); // 4611686 = Q62 + temp = BASOP_Util_Divide3232_Scale_newton( E_out1, 4611686, &exp ); // 4611686 = Q62 exp = sub( exp, sub( q_eout, 62 ) ); Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp } @@ -4109,7 +4109,7 @@ static void formulate2x2MixingMatrix_fx( { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp } @@ -4127,7 +4127,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 + temp = BASOP_Util_Divide3232_Scale_newton( E_out2, 4611686, &exp1 ); // 4611686 = Q62 exp1 = sub( exp1, sub( q_eout, 62 ) ); Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 } @@ -4136,7 +4136,7 @@ static void formulate2x2MixingMatrix_fx( { temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); + temp = BASOP_Util_Divide3232_Scale_newton( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 } @@ -4195,7 +4195,7 @@ static void formulate2x2MixingMatrix_fx( } ELSE { - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, D_fx[0], &exp ); exp = sub( exp, sub( Q30, q_D ) ); } div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp @@ -4328,7 +4328,7 @@ static void formulate2x2MixingMatrix_fx( Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, temp, &exp ); Pre_shift = norm_l( Pre_fx[chA][chB] ); Pim_shift = norm_l( Pim_fx[chA][chB] ); Pre_fx[chA][chB] = Mpy_32_32( L_shl( Pre_fx[chA][chB], Pre_shift ), temp ); @@ -4372,7 +4372,7 @@ static void formulate2x2MixingMatrix_fx( { Word16 Pre_shift, Pim_shift; temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); + temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, temp, &exp ); q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); Pre_shift = norm_l( Pre_fx[0][chB] ); diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 7b446a80e..0cdbe3a10 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2097,9 +2097,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move16(); exp1 = 0; move16(); - tmp32 = BASOP_Util_Divide3232_Scale_cadence( L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ), - ( L_add( Sqrt32( h_dirac_output_synthesis_state->direct_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp) - &exp1 ); + tmp32 = BASOP_Util_Divide3232_Scale_newton( L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ), + ( L_add( Sqrt32( h_dirac_output_synthesis_state->direct_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp) + &exp1 ); target_power_y = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp)) q_target_power_y = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) ); q_target_power_y = sub( q_target_power_y, 1 ); @@ -2108,9 +2108,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move16(); exp1 = 0; move16(); - tmp32 = BASOP_Util_Divide3232_Scale_cadence( L_shl( p_cy_auto_diff_smooth[num_freq_bands], sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ), - ( L_add( Sqrt32( h_dirac_output_synthesis_state->diffuse_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp) - &exp1 ); + tmp32 = BASOP_Util_Divide3232_Scale_newton( L_shl( p_cy_auto_diff_smooth[num_freq_bands], sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ), + ( L_add( Sqrt32( h_dirac_output_synthesis_state->diffuse_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp) + &exp1 ); target_power_y1 = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp)) q_target_power_y1 = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) ); q_target_power_y1 = sub( q_target_power_y1, 1 ); @@ -2268,7 +2268,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) { p_power_smooth_prev++; - L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ + L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ exp_arr[k * num_freq_bands + l] = exp; move16(); @@ -2277,7 +2277,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( } ELSE { - L_tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ + L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/ exp_arr[k * num_freq_bands + l] = exp; move16(); @@ -2495,7 +2495,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( exp = 0; move16(); - L_tmp = BASOP_Util_Divide3232_Scale_cadence( *( p_cy_auto_diff_smooth_prev++ ), ( *( p_power_diff_smooth_prev++ ) ), &exp ); // (Q31 - exp) + (q_a - q_b) + L_tmp = BASOP_Util_Divide3232_Scale_newton( *( p_cy_auto_diff_smooth_prev++ ), ( *( p_power_diff_smooth_prev++ ) ), &exp ); // (Q31 - exp) + (q_a - q_b) exp = sub( Q31, add( sub( Q31, exp ), sub( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state->proto_power_diff_smooth_q ) ) ); *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); // (31 - exp) @@ -3982,7 +3982,7 @@ void ivas_lfe_synth_with_filters_fx( } ELSE { - lfeGain_fx = extract_h( BASOP_Util_Divide3232_Scale_cadence( hMasaLfeSynth->targetEneLfeSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->transportEneSmooth_fx ), &lfeGain_fx_exp ) ); /*Q(31-(lfeGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneLfeSmooth_q))-16*/ + lfeGain_fx = extract_h( BASOP_Util_Divide3232_Scale_newton( hMasaLfeSynth->targetEneLfeSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->transportEneSmooth_fx ), &lfeGain_fx_exp ) ); /*Q(31-(lfeGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneLfeSmooth_q))-16*/ lfeGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneLfeSmooth_q ), lfeGain_fx_exp ); lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp ); // Q15-lfeGain_fx_exp lfeGain_fx = shl_r( lfeGain_fx, lfeGain_fx_exp ); // Q15 diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index f67f3761b..9de710b36 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -2691,8 +2691,8 @@ void protoSignalComputation2_fx( q_lr_bb_power = stereo_type_detect->q_right_bb_power; move16(); } - q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ - temp = BASOP_Util_Divide3232_Scale_cadence( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power)) + q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ + temp = BASOP_Util_Divide3232_Scale_newton( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power)) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_bb_power, stereo_type_detect->q_total_bb_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 IF( NE_32( temp, MIN_32 ) ) @@ -2740,8 +2740,8 @@ void protoSignalComputation2_fx( move32(); q_lr_hi_power = stereo_type_detect->q_right_hi_power; } - q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ - temp = BASOP_Util_Divide3232_Scale_cadence( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power) + q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ + temp = BASOP_Util_Divide3232_Scale_newton( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_hi_power, stereo_type_detect->q_total_hi_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 IF( NE_32( temp, MIN_32 ) ) @@ -3419,7 +3419,7 @@ void computeDirectionAngles_fx( } ELSE { - temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, intensityNorm, &exp ); // Q=31-(exp-(30-q_intensityNorm)) + temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, intensityNorm, &exp ); // Q=31-(exp-(30-q_intensityNorm)) exp = sub( exp, sub( Q30, q_intensityNorm ) ); temp = Sqrt32( temp, &exp ); // Q=31-exp q_temp = sub( 31, exp ); diff --git a/lib_rend/ivas_orient_trk_fx.c b/lib_rend/ivas_orient_trk_fx.c index a25a8db53..6ed7cf3b1 100644 --- a/lib_rend/ivas_orient_trk_fx.c +++ b/lib_rend/ivas_orient_trk_fx.c @@ -140,22 +140,22 @@ static void QuaternionDivision_fx( { Word16 scale_e, result_e = 0, w_q, x_q, y_q, z_q, result_q; - r->w_fx = BASOP_Util_Divide3232_Scale_cadence( ( q.w_fx ), d, &scale_e ); + r->w_fx = BASOP_Util_Divide3232_Scale_newton( ( q.w_fx ), d, &scale_e ); move32(); result_e = add( scale_e, sub( sub( Q31, q.q_fact ), den_e ) ); // e+e1-e2// w_q = sub( Q31, result_e ); - r->x_fx = BASOP_Util_Divide3232_Scale_cadence( ( q.x_fx ), d, &scale_e ); + r->x_fx = BASOP_Util_Divide3232_Scale_newton( ( q.x_fx ), d, &scale_e ); move32(); result_e = add( scale_e, sub( sub( Q31, q.q_fact ), den_e ) ); x_q = sub( Q31, result_e ); - r->y_fx = BASOP_Util_Divide3232_Scale_cadence( ( q.y_fx ), d, &scale_e ); + r->y_fx = BASOP_Util_Divide3232_Scale_newton( ( q.y_fx ), d, &scale_e ); move32(); result_e = add( scale_e, sub( sub( Q31, q.q_fact ), den_e ) ); y_q = sub( Q31, result_e ); - r->z_fx = BASOP_Util_Divide3232_Scale_cadence( ( q.z_fx ), d, &scale_e ); + r->z_fx = BASOP_Util_Divide3232_Scale_newton( ( q.z_fx ), d, &scale_e ); move32(); result_e = add( scale_e, sub( sub( Q31, q.q_fact ), den_e ) ); z_q = sub( Q31, result_e ); @@ -505,15 +505,15 @@ static IVAS_VECTOR3 VectorNormalize_fx( move16(); length_fx = VectorLength_fx( p, &q_len ); - result_fx.x_fx = BASOP_Util_Divide3232_Scale_cadence( p.x_fx, length_fx, &scale ); + result_fx.x_fx = BASOP_Util_Divide3232_Scale_newton( p.x_fx, length_fx, &scale ); move32(); x_qfact = sub( Q31, add( scale, sub( q_len, p.q_fact ) ) ); // e+(e1-e2)// - result_fx.y_fx = BASOP_Util_Divide3232_Scale_cadence( p.y_fx, length_fx, &scale ); + result_fx.y_fx = BASOP_Util_Divide3232_Scale_newton( p.y_fx, length_fx, &scale ); move32(); y_qfact = sub( Q31, add( scale, sub( q_len, p.q_fact ) ) ); - result_fx.z_fx = BASOP_Util_Divide3232_Scale_cadence( p.z_fx, length_fx, &scale ); + result_fx.z_fx = BASOP_Util_Divide3232_Scale_newton( p.z_fx, length_fx, &scale ); move32(); z_qfact = sub( Q31, add( scale, sub( q_len, p.q_fact ) ) ); diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 62c97f88f..c70e8d667 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -411,7 +411,7 @@ static void response_step_limit_fx( IF( X[i] ) { - desiredChange = BASOP_Util_Divide3232_Scale_cadence( X[i], X[i - 1], &div_e ); + desiredChange = BASOP_Util_Divide3232_Scale_newton( X[i], X[i - 1], &div_e ); desiredChange_q = sub( 31, ( div_e ) ); } @@ -459,7 +459,7 @@ static void response_step_limit_fx( IF( X[i] ) { - desiredChange = BASOP_Util_Divide3232_Scale_cadence( X[i], X[i + 1], &div_e ); + desiredChange = BASOP_Util_Divide3232_Scale_newton( X[i], X[i + 1], &div_e ); desiredChange_q = sub( 31, ( div_e ) ); } IF( GT_16( desiredChange_q, 30 ) ) @@ -742,9 +742,9 @@ void ivas_reverb_calc_color_levels_fx( move16(); cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28 - H_filter = BASOP_Util_Divide3232_Scale_cadence( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); + H_filter = BASOP_Util_Divide3232_Scale_newton( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); H_filter = Sqrt32( H_filter, &temp ); - T60_est = BASOP_Util_Divide3232_Scale_cadence( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ), &temp ); // conversion of log2 to log10. + T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ), &temp ); // conversion of log2 to log10. t60[freq_idx] = BASOP_Util_Add_Mant32Exp( T60_est, temp, t60[freq_idx], t60_e[freq_idx], &result_e ); move16(); t60_e[freq_idx] = result_e; @@ -775,14 +775,14 @@ void ivas_reverb_calc_color_levels_fx( { Word16 temp, temp1, temp2, temp3 = 0, temp4, temp5; move16(); - Word32 var1 = BASOP_Util_Divide3232_Scale_cadence( (Word32) i_mult( -6, minDelay ), L_shr( Mpy_32_32( t60[freq_idx], L_shl( output_Fs, 11 ) ), sub( 11, t60_e[freq_idx] ) ), &temp ); + Word32 var1 = BASOP_Util_Divide3232_Scale_newton( (Word32) i_mult( -6, minDelay ), L_shr( Mpy_32_32( t60[freq_idx], L_shl( output_Fs, 11 ) ), sub( 11, t60_e[freq_idx] ) ), &temp ); var1 = Mpy_32_32( var1, LOG2_10_Q29 ); // e = temp + (31 - 29) Word32 A0_square_est = BASOP_util_Pow2( var1, add( temp, 31 - 29 ), &temp ); Word16 alpha_e; - Word32 alpha = BASOP_Util_Divide3232_Scale_cadence( -log__0_001, t60[freq_idx], &alpha_e ); // alpha_e = 1 + alpha_e + (3 - t60_e[257]) + Word32 alpha = BASOP_Util_Divide3232_Scale_newton( -log__0_001, t60[freq_idx], &alpha_e ); // alpha_e = 1 + alpha_e + (3 - t60_e[257]) - Word32 div11 = BASOP_Util_Divide3232_Scale_cadence( A0_square_est, alpha, &temp1 ); // e = temp1 + (temp - alpha_e) - Word32 div2 = BASOP_Util_Divide3232_Scale_cadence( L_shl( output_Fs, 11 ), L_shr( L_add( Mpy_32_16_1( 1884631649, shl( minDelayDiff, 3 ) ), 14037339 ), 8 ), &temp2 ); // e = temp2, 26.7741 in Q19, 0.8776 in Q31 + Word32 div11 = BASOP_Util_Divide3232_Scale_newton( A0_square_est, alpha, &temp1 ); // e = temp1 + (temp - alpha_e) + Word32 div2 = BASOP_Util_Divide3232_Scale_newton( L_shl( output_Fs, 11 ), L_shr( L_add( Mpy_32_16_1( 1884631649, shl( minDelayDiff, 3 ) ), 14037339 ), 8 ), &temp2 ); // e = temp2, 26.7741 in Q19, 0.8776 in Q31 const Word32 revPredNormEnergy = Mpy_32_32( div2, div11 ); // q = (15 - temp2) + (15 - temp1) - 15 + 1 // L_max @@ -794,7 +794,7 @@ void ivas_reverb_calc_color_levels_fx( L_tmp = W_extract_h( W_shl( W_tmp1, W_shift ) ); temp4 = sub( 3, W_shift ); div2 = Sqrt32( L_tmp, &temp4 ); - pTarget_color_L[freq_idx] = BASOP_Util_Divide3232_Scale_cadence( div2, div1, &temp5 ); + pTarget_color_L[freq_idx] = BASOP_Util_Divide3232_Scale_newton( div2, div1, &temp5 ); move32(); temp5 = add( temp5, sub( temp4, temp3 ) ); pTarget_color_L_e[freq_idx] = temp5; @@ -807,7 +807,7 @@ void ivas_reverb_calc_color_levels_fx( L_tmp = W_extract_h( W_shl( W_tmp2, W_shift ) ); temp4 = sub( 3, W_shift ); div2 = Sqrt32( L_tmp, &temp4 ); - pTarget_color_R[freq_idx] = BASOP_Util_Divide3232_Scale_cadence( div2, div1, &temp5 ); + pTarget_color_R[freq_idx] = BASOP_Util_Divide3232_Scale_newton( div2, div1, &temp5 ); move32(); temp5 = add( temp5, sub( temp4, temp3 ) ); pTarget_color_R_e[freq_idx] = temp5; @@ -825,7 +825,7 @@ void ivas_reverb_calc_color_levels_fx( Word32 div1; Word16 temp = 0; move16(); - div1 = BASOP_Util_Divide3232_Scale_cadence( L_mult0( 1000, sub( freq_count, 1 ) ), L_shr( output_Fs, 1 ), &temp ); + div1 = BASOP_Util_Divide3232_Scale_newton( L_mult0( 1000, sub( freq_count, 1 ) ), L_shr( output_Fs, 1 ), &temp ); div1 = BASOP_Util_Add_Mant32Exp( div1, temp, ONE_IN_Q30, 1, &temp ); idx_pivot = extract_l( L_shr( div1, sub( 31, temp ) ) ); /* Perform step limiting */ diff --git a/lib_rend/ivas_rotation_fx.c b/lib_rend/ivas_rotation_fx.c index e6f8f2653..1633f42d0 100644 --- a/lib_rend/ivas_rotation_fx.c +++ b/lib_rend/ivas_rotation_fx.c @@ -1974,7 +1974,7 @@ static void external_target_interpolation_fx( move16(); Word32 tmp; /* Calculate the interpolation increment and coefficient */ - tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, L_shl( L_deposit_l( hExtOrientationData->numFramesToTargetOrientation[i] ), 2 ), &tmp_e ); + tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, L_shl( L_deposit_l( hExtOrientationData->numFramesToTargetOrientation[i] ), 2 ), &tmp_e ); hCombinedOrientationData->interpolationIncrement_fx = L_shl( tmp, sub( tmp_e, 31 ) ); /* Q30 */ move32(); hCombinedOrientationData->interpolationCoefficient_fx = hCombinedOrientationData->interpolationIncrement_fx; diff --git a/lib_rend/ivas_shoebox_fx.c b/lib_rend/ivas_shoebox_fx.c index 1a4496085..0156e70b5 100644 --- a/lib_rend/ivas_shoebox_fx.c +++ b/lib_rend/ivas_shoebox_fx.c @@ -387,7 +387,7 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( { q = Q22; move16(); - t = (Word32) BASOP_Util_Divide3232_Scale_cadence( *scale, absxk, &q ); + t = (Word32) BASOP_Util_Divide3232_Scale_newton( *scale, absxk, &q ); out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 @@ -397,7 +397,7 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( } ELSE { - t = (Word32) BASOP_Util_Divide3232_Scale_cadence( absxk, *scale, &q ); + t = (Word32) BASOP_Util_Divide3232_Scale_newton( absxk, *scale, &q ); t = W_extract_h( W_shl( W_mult_32_32( t, t ), sub( shl( q, 1 ), 9 ) ) ); // Q31 + Q31 + Q1 - 9 - 32 = Q22 out_tmp = L_add( out_tmp, t ); // Q22 move32(); @@ -407,7 +407,7 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( IF( GE_32( absxk, *scale ) ) { - t = (Word32) BASOP_Util_Divide3232_Scale_cadence( *scale, absxk, &q ); + t = (Word32) BASOP_Util_Divide3232_Scale_newton( *scale, absxk, &q ); out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 @@ -417,7 +417,7 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( } ELSE { - t = (Word32) BASOP_Util_Divide3232_Scale_cadence( absxk, *scale, &q ); + t = (Word32) BASOP_Util_Divide3232_Scale_newton( absxk, *scale, &q ); t = W_extract_h( W_shl( W_mult_32_32( t, t ), sub( shl( q, 1 ), 9 ) ) ); // Q31 + Q31 + Q1 - 9 - 32 = Q22 out_tmp = L_add( out_tmp, t ); // Q22 } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 7e526ca77..859768784 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -6836,7 +6836,7 @@ static void renderMasaToMasa( move32(); FOR( dir = 0; dir < numDirs; dir++ ) { - tmp = BASOP_Util_Divide3232_Scale_cadence( inMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum_fx, &tmp_e ); + tmp = BASOP_Util_Divide3232_Scale_newton( inMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum_fx, &tmp_e ); inMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( tmp, sub( tmp_e, 1 ) ); /* Q30 */ move32(); } @@ -6844,7 +6844,7 @@ static void renderMasaToMasa( move16(); tmp = 0; move32(); - tmp = BASOP_Util_Divide3232_Scale_cadence( inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum_fx, &tmp_e ); + tmp = BASOP_Util_Divide3232_Scale_newton( inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum_fx, &tmp_e ); inMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( tmp, sub( tmp_e, 1 ) ); /* Q30 */ move32(); } -- GitLab From e1d19cecb18720009dcb45d33196ba192b69fe09 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 11:30:57 +0200 Subject: [PATCH 1001/1221] checkin state of BE branch in commit 090be8f3 --- lib_com/options.h | 14 + lib_com/prot_fx.h | 10 +- lib_com/swb_tbe_com_fx.c | 573 ++++++++++++++++++++++++++--- lib_com/tools_fx.c | 26 +- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 + lib_dec/swb_tbe_dec_fx.c | 10 + lib_enc/swb_tbe_enc_fx.c | 39 +- 7 files changed, 623 insertions(+), 59 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e8a44d873..c76765742 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -72,6 +72,11 @@ #define FIX_1378_ACELP_OUT_OF_BOUNDS /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ + +#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ +#define MERGE_REQ + + //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ @@ -84,4 +89,13 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ + +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1452d8e2e..702cdea12 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,15 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : i signal Q_input_fx */ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS; +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else + const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 238b478c5..f1492b0b4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6687,6 +6687,181 @@ void wb_tbe_extras_reset_synth_fx( return; } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +{ + Word32 L_tmpX; + Word16 i; + Word32 L_tmpMax2 = *L_tmpMax; + Word32 L_tmpAbs; + move32(); + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#else + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#endif + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -6695,7 +6870,15 @@ void wb_tbe_extras_reset_synth_fx( *-------------------------------------------------------------------*/ void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS; +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal memory_fx_Q */ Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ @@ -6704,17 +6887,36 @@ void elliptic_bpf_48k_generic_fx( ) { Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 memory_fx0, Q_temp, Q_temp2; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; + Word32 L_tmpMax; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + Word64 W_tmpX; + Word64 W_tmpY; +#endif + + Word32 *L_tmp = &L_tmp_buffer[4]; + Word32 *L_tmp2 = &L_tmp2_buffer[4]; + Word32 *L_output = &L_output_buffer[4]; +#else Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; Word32 memory2_fx_2[4], memory2_fx_3[4]; +#endif FOR( i = 0; i < 4; i++ ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + memory_fx0 = extract_l( memory_fx2[0][i] ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); +#else memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); +#endif + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); move32(); move32(); move32(); @@ -6722,48 +6924,158 @@ void elliptic_bpf_48k_generic_fx( move32(); } - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ + ELSE + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); + + FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6777,6 +7089,7 @@ void elliptic_bpf_48k_generic_fx( L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; @@ -6787,6 +7100,46 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -6831,20 +7184,22 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } +#endif + Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); @@ -6861,12 +7216,54 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); move32(); + } +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); +#else +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -6932,6 +7329,10 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } + +#endif + + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -6998,7 +7399,12 @@ void synthesise_fb_high_band_fx( Word16 Qout ) { Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; + Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; +#else Word16 excitation_in_interp3[L_FRAME48k]; +#endif Word16 tmp[L_FRAME48k]; Word32 temp1; Word32 ratio2; @@ -7023,12 +7429,28 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx + + ); } ELSE { /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); @@ -7074,6 +7496,50 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { +#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ + Word32 L_tmp32; + Word16 tmp16; + + // if (L_tmp < 0) + if ( L_tmp < 0 ) + { + L_tmp32 = L_negate( L_tmp ); + } + if ( L_tmp < 0 ) + { + L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); + } + if ( L_tmp < 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + if ( L_tmp < 0 ) + { + tmp16 = negate( tmp16 ); + } + + // if (L_tmp == 0) + if ( L_tmp == 0 ) + { + tmp16 = 0; + move16(); + } + + // if (L_tmp > 0) + if ( L_tmp > 0 ) + { + L_tmp32 = L_shl_sat( L_tmp, tmp3 ); + } + if ( L_tmp > 0 ) + { + tmp16 = extract_h( L_tmp32 ); + } + + output[i] = tmp16; + move16(); + +#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7085,6 +7551,7 @@ void synthesise_fb_high_band_fx( output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); } +#endif } return; } diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5219d076c..756b5be80 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,13 +794,37 @@ void Copy_Scale_sig_16_32_no_sat( } return; } +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat + L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); + + IF( L_tmp >= 0x7FFF ) + { + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* Overflow can occur here */ + } + return; + } + // ELSE + { + Word16 tmp = extract_l( L_tmp ); + FOR( i = 0; i < lg; i++ ) + { + y[i] = L_mult( x[i], tmp ); + move32(); + } + } +#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ + move32(); /* Overflow can occur here */ } +#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c7bc98566..772eb2d7d 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,6 +904,9 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); +#endif FOR( i = 0; i < winLen_fx; i++ ) { L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ @@ -911,10 +914,17 @@ void stereo_icBWE_dec_fx( tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + if ( LE_16( alpha_fx, winSlope_fx_ ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ + } +#else IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } +#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 1b51a29fb..00be6455d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7022,14 +7022,24 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); + +#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx + Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 +#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { +#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } +#else + Word16 idx; + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ +#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 316a5b549..be0dd84e5 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,13 +7299,18 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; - Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_buffer[L_FRAME48k + 4]; + Word16 *input_fhb = &input_fhb_buffer[0] + 4; +#else + Word16 input_fhb[L_FRAME48k]; +#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); @@ -7325,7 +7330,14 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); - elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7422,7 +7434,12 @@ void fb_tbe_enc_ivas_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_new_buffer[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) + 4]; + Word16 *input_fhb_new = &input_fhb_new_buffer[0] + 4; +#else Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; +#endif Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; Word64 fb_exc_energy; @@ -7449,11 +7466,25 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } ELSE { - elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + 1 // isIVAS +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 0, // IsUpsampled3 +#endif + input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); } test(); -- GitLab From 8aa08f4f18d666485c9ed7a36b05a31478b70634 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Fri, 11 Apr 2025 09:45:17 +0000 Subject: [PATCH 1002/1221] last cleanups --- lib_com/prot_fx.h | 9 ++------- lib_com/swb_tbe_com_fx.c | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 93da4d66a..1452d8e2e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3258,7 +3258,7 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : input signal Q_input_fx*/ + const Word16 input_fx[], /* i : i signal Q_input_fx */ Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ @@ -3277,12 +3277,7 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif -); + Word16 Qout ); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d3dc614aa..ca0c39b17 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6714,7 +6714,6 @@ void elliptic_bpf_48k_generic_fx( memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); //is this change be? move32(); move32(); move32(); -- GitLab From a23e871dc20d37f820e832a9a5ac786bbca7ddca Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 16:58:15 +0530 Subject: [PATCH 1003/1221] Fix for 3GPP issue 1466: Large deviations observed with the extrapolation of shifted channel by TD-ITD compensation in stereo Link #1466, #1463 --- lib_enc/ivas_cpe_enc_fx.c | 3 +++ lib_enc/ivas_stereo_dft_td_itd_fx.c | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index be0afc1a4..1bb31810d 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -785,6 +785,9 @@ ivas_error ivas_cpe_enc_fx( } stereo_td_itd_mdct_stereo_fx( hCPE, vad_flag_dtx, vad_hover_flag, input_frame ); + + Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx - input_frame, sts[0]->input32_fx - input_frame, shl( input_frame, 1 ), sub( sts[0]->q_inp32, sts[0]->q_inp ) ); + Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx - input_frame, sts[1]->input32_fx - input_frame, shl( input_frame, 1 ), sub( sts[1]->q_inp32, sts[1]->q_inp ) ); } /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index 569a5690a..c457faa4f 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -575,9 +575,12 @@ void stereo_td_itd_mdct_stereo_fx( /*call ITD function*/ stereo_dft_enc_compute_itd_fx( hCPE, DFT_fx[0], DFT_tmp_e[0], DFT_fx[1], DFT_tmp_e[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_e, bin_nrgR_fx, bin_nrgR_e ); + q_com = MAX_16; + move16(); + FOR( n = 0; n < CPE_CHANNELS; n++ ) { - q_com = add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ); + q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ) ); q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ), hCPE->hCoreCoder[n]->q_old_inp ) ); q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl ), hCPE->q_input_mem[n] ) ); @@ -586,7 +589,10 @@ void stereo_td_itd_mdct_stereo_fx( q_com = 0; move16(); } + } + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_inp ) ); hCPE->hCoreCoder[n]->q_inp = q_com; move16(); -- GitLab From e0d2ebe1640492ea5322ee5f68f5685380db2d73 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 17:00:53 +0530 Subject: [PATCH 1004/1221] Fix for 3GPP issue 1458: Crash with new testcase in pytest suite - ISM with DTX, bitrate switching + JBM to BINAURAL_ROOM_IR Link #1458 --- lib_dec/ivas_jbm_dec_fx.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 8c5a9e9af..74af57bd5 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -2550,7 +2550,7 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( DECODER_TC_BUFFER_HANDLE hTcBuffer; Word32 output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; - Word16 nchan_in, nchan_out; + Word16 nchan_in, nchan_out, gd_bits, n_chan_inp, i, shift; IF( !st_ivas->hDecoderConfig->Opt_tsm ) { return IVAS_ERR_OK; @@ -2637,17 +2637,44 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ set16_fx( st_ivas->hIsmRendererData->interpolator_fx, 32767, hTcBuffer->n_samples_granularity ); // 32767=1.0f in Q15 - ivas_ism_render_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ); + ivas_ism_render_sf_fx( st_ivas, p_output_fx, hTcBuffer->n_samples_granularity ); st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor; *st_ivas->hCrendWrapper->p_io_qfactor = 11; move16(); + + shift = MAX_16; + move16(); + n_chan_inp = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ); + + FOR( i = 0; i < n_chan_inp; i++ ) + { + shift = s_min( shift, L_norm_arr( p_output_fx[i], hTcBuffer->n_samples_granularity ) ); + } + + gd_bits = sub( find_guarded_bits_fx( imult1616( hTcBuffer->subframe_nbslots[0], hTcBuffer->n_samples_granularity ) ), shift ); + + *st_ivas->hCrendWrapper->p_io_qfactor = sub( *st_ivas->hCrendWrapper->p_io_qfactor, gd_bits ); + move16(); + + FOR( i = 0; i < n_chan_inp; i++ ) + { + scale_sig32( p_output_fx[i], hTcBuffer->n_samples_granularity, sub( *st_ivas->hCrendWrapper->p_io_qfactor, Q11 ) ); // Q(*st_ivas->hCrendWrapper->p_io_qfactor) + } + IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) ) { return error; } + + FOR( i = 0; i < n_chan_inp; i++ ) + { + scale_sig32( p_output_fx[i], hTcBuffer->n_samples_granularity, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q(11) + } + *st_ivas->hCrendWrapper->p_io_qfactor = Q11; + move16(); } } ELSE -- GitLab From 2d7c39d471ad5d01b4bc893e8176e60ae38345ce Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Thu, 10 Apr 2025 16:39:51 +0530 Subject: [PATCH 1005/1221] Updates in stereo_mdct_core_enc_fx for precision improvement --- lib_com/fft_fx.c | 143 ----------------- lib_com/prot_fx.h | 7 + lib_com/tools_fx.c | 164 +++++++++++++++++++ lib_enc/ivas_stereo_mdct_core_enc_fx.c | 210 +++++++++++++++++-------- lib_enc/prot_fx_enc.h | 8 + lib_enc/tcx_utils_enc_fx.c | 111 +++++++++++++ 6 files changed, 438 insertions(+), 205 deletions(-) diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 31b11a9ea..5ee509879 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -7555,146 +7555,3 @@ void rfft_fx( return; } - -Word16 find_guarded_bits_fx( Word32 n ) -{ - // return n <= 1 ? 0 : n <= 2 ? 1 - // : n <= 4 ? 2 - // : n <= 8 ? 3 - // : n <= 16 ? 4 - // : n <= 32 ? 5 - // : n <= 64 ? 6 - // : n <= 128 ? 7 - // : n <= 256 ? 8 - // : n <= 512 ? 9 - // : n <= 1024 ? 10 - // : n <= 2048 ? 11 - // : n <= 4096 ? 12 - // : n <= 8192 ? 13 - // : n <= 16384 ? 14 - // : 15; - /*Word16 val = 0; - move32(); - test(); - WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) ) - { - val = add( val, 1 ); - }*/ - IF( LE_32( n, 1 ) ) - { - return 0; - } - ELSE - { - - return sub( 31, norm_l( L_sub( n, 1 ) ) ); - } -} - -Word16 L_norm_arr( const Word32 *arr, Word16 size ) -{ - Word16 q = 31; - move16(); - FOR( Word16 i = 0; i < size; i++ ) - { - Word16 q_tst; - - q_tst = norm_l( arr[i] ); - if ( arr[i] != 0 ) - { - q = s_min( q, q_tst ); - } - } - - return q; -} - -Word16 norm_arr( Word16 *arr, Word16 size ) -{ - Word16 q = 15; - Word16 exp = 0; - move16(); - move16(); - FOR( Word16 i = 0; i < size; i++ ) - { - if ( arr[i] != 0 ) - { - exp = norm_s( arr[i] ); - } - if ( arr[i] != 0 ) - { - q = s_min( q, exp ); - } - } - return q; -} - -Word16 W_norm_arr( Word64 *arr, Word16 size ) -{ - Word16 q = 63; - Word16 exp = 0; - move16(); - move16(); - FOR( Word16 i = 0; i < size; i++ ) - { - if ( arr[i] != 0 ) - { - exp = W_norm( arr[i] ); - } - if ( arr[i] != 0 ) - { - q = s_min( q, exp ); - } - } - return q; -} - -Word16 get_min_scalefactor( Word32 x, Word32 y ) -{ - Word16 scf_y; - Word16 scf = Q31; - move16(); - - test(); - if ( x == 0 && y == 0 ) - { - scf = 0; - move16(); - } - - if ( x != 0 ) - { - scf = norm_l( x ); - } - - scf_y = norm_l( y ); - if ( y != 0 ) - { - scf = s_min( scf_y, scf ); - } - - return scf; -} - - -Flag is_zero_arr( Word32 *arr, Word16 size ) -{ - FOR( Word16 i = 0; i < size; i++ ) - IF( arr[i] != 0 ) - { - return 0; - } - - return 1; -} - -Flag is_zero_arr16( Word16 *arr, Word16 size ) -{ - FOR( Word16 i = 0; i < size; i++ ) - IF( arr[i] != 0 ) - { - return 0; - } - - return 1; -} diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1452d8e2e..e60b8ac92 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1444,6 +1444,13 @@ void scale_sig32( const Word16 lg, /* i : size of x[] Q0 */ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx xx exp */ ); + +void Scale_sig64( + Word64 x[], /* i/o: signal to scale Qx */ + Word16 len, /* i : size of x[] Q0 */ + Word16 exp /* i : exponent: x = round(x << exp) Qx exp */ +); + void scale_sig32_r( Word32 x[], /* i/o: signal to scale Qx */ const Word16 lg, /* i : size of x[] Q0 */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 9e5547c7d..5f0e172bf 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -4526,3 +4526,167 @@ void v_add_fixed_me( return; } + +Word16 find_guarded_bits_fx( Word32 n ) +{ + // return n <= 1 ? 0 : n <= 2 ? 1 + // : n <= 4 ? 2 + // : n <= 8 ? 3 + // : n <= 16 ? 4 + // : n <= 32 ? 5 + // : n <= 64 ? 6 + // : n <= 128 ? 7 + // : n <= 256 ? 8 + // : n <= 512 ? 9 + // : n <= 1024 ? 10 + // : n <= 2048 ? 11 + // : n <= 4096 ? 12 + // : n <= 8192 ? 13 + // : n <= 16384 ? 14 + // : 15; + /*Word16 val = 0; + move32(); + test(); + WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) ) + { + val = add( val, 1 ); + }*/ + IF( LE_32( n, 1 ) ) + { + return 0; + } + ELSE + { + + return sub( 31, norm_l( L_sub( n, 1 ) ) ); + } +} + +Word16 L_norm_arr( const Word32 *arr, Word16 size ) +{ + Word16 q = 31; + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + Word16 q_tst; + + q_tst = norm_l( arr[i] ); + if ( arr[i] != 0 ) + { + q = s_min( q, q_tst ); + } + } + + return q; +} + +Word16 norm_arr( Word16 *arr, Word16 size ) +{ + Word16 q = 15; + Word16 exp = 0; + move16(); + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + if ( arr[i] != 0 ) + { + exp = norm_s( arr[i] ); + } + if ( arr[i] != 0 ) + { + q = s_min( q, exp ); + } + } + return q; +} + +Word16 W_norm_arr( Word64 *arr, Word16 size ) +{ + Word16 q = 63; + Word16 exp = 0; + move16(); + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + if ( arr[i] != 0 ) + { + exp = W_norm( arr[i] ); + } + if ( arr[i] != 0 ) + { + q = s_min( q, exp ); + } + } + return q; +} + +Word16 get_min_scalefactor( Word32 x, Word32 y ) +{ + Word16 scf_y; + Word16 scf = Q31; + move16(); + + test(); + if ( x == 0 && y == 0 ) + { + scf = 0; + move16(); + } + + if ( x != 0 ) + { + scf = norm_l( x ); + } + + scf_y = norm_l( y ); + if ( y != 0 ) + { + scf = s_min( scf_y, scf ); + } + + return scf; +} + + +Flag is_zero_arr( Word32 *arr, Word16 size ) +{ + FOR( Word16 i = 0; i < size; i++ ) + IF( arr[i] != 0 ) + { + return 0; + } + + return 1; +} + +Flag is_zero_arr16( Word16 *arr, Word16 size ) +{ + FOR( Word16 i = 0; i < size; i++ ) + IF( arr[i] != 0 ) + { + return 0; + } + + return 1; +} + +void Scale_sig64( + Word64 x[], /* i/o: signal to scale Qx */ + Word16 len, /* i : size of x[] Q0 */ + Word16 exp /* i : exponent: x = round(x << exp) Qx exp */ +) +{ + Word16 i; + assert( exp <= 63 && exp >= -63 ); + IF( exp == 0 ) + { + return; + } + + FOR( i = 0; i < len; i++ ) + { + /* saturation can occur here */ + x[i] = W_shl( x[i], exp ); + move64(); + } +} diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 1346d634b..91b8726f0 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -135,10 +135,8 @@ void stereo_mdct_core_enc_fx( { Word32 orig_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */ Word32 *orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; /* Pointers to MDCT output for a short block (L/R) */ - Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; - Word32 powerSpec_fx_tmp[CPE_CHANNELS][N_MAX]; /* This 32 bit buffer is created to preserve the precision for original separate Q calculation of powerSpec_fx buffer ( Related to 3gpp issue #1192 ) */ - Word32 *p_powerSpec_fx[CPE_CHANNELS]; - Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX]; + Word64 powerSpec64[CPE_CHANNELS][N_MAX]; + Word16 exp_powerSpec64[CPE_CHANNELS][NB_DIV]; Word32 powerSpecMsInv_long_fx[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */ Word32 *powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; Word32 quantized_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ @@ -153,7 +151,7 @@ void stereo_mdct_core_enc_fx( Word32 *p_mdst_spectrum_long_fx[CPE_CHANNELS]; Word32 mdst_spectrum_long_fx[CPE_CHANNELS][N_MAX]; Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; - Word16 q_powSpec[MCT_MAX_CHANNELS], q_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s; + Word16 q_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s; Word16 tmp_q_powSpec[N_MAX], tmp_q_powSpecInv[N_MAX], *tmp_q_psi[2]; Word64 W_tmp; Encoder_State *st, **sts; @@ -184,12 +182,11 @@ void stereo_mdct_core_enc_fx( p_orig_spectrum_long_fx[ch] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][0] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][1] = orig_spectrum_long_fx[ch] + N_TCX10_MAX; - set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX ); + set16_fx( exp_powerSpec64[ch], 0, NB_DIV ); } set16_fx( tmp_q_powSpecInv, 63, N_MAX ); set16_fx( tmp_q_powSpec, 63, N_MAX ); - set16_fx( q_powSpec, 31, MCT_MAX_CHANNELS ); set16_fx( q_powSpecMsInv, 31, MCT_MAX_CHANNELS ); tmp_q_psi[0] = tmp_q_powSpecInv; @@ -264,11 +261,10 @@ void stereo_mdct_core_enc_fx( inv_spectrum_fx[ch][1] = quantized_spectrum_fx[ch][1]; mdst_spectrum_fx[ch][0] = mdst_spectrum_long_fx[ch]; mdst_spectrum_fx[ch][1] = mdst_spectrum_long_fx[ch] + N_TCX10_MAX; + set64_fx( powerSpec64[ch], 0, N_MAX ); set32_fx( powerSpecMsInv_long_fx[ch], 0, N_MAX ); set32_fx( quantized_spectrum_long_fx[ch], 0, N_MAX ); set32_fx( mdst_spectrum_long_fx[ch], 0, N_MAX ); - set32_fx( powerSpec_fx[ch], 0, N_MAX ); - set32_fx( powerSpec_fx_tmp[ch], 0, N_MAX ); set32_fx( powerSpecMsInv_long_fx[ch], 0, N_MAX ); sts[ch]->hTcxEnc->tns_ms_flag[0] = 0; move16(); @@ -383,7 +379,7 @@ void stereo_mdct_core_enc_fx( } } - q_spec = sub( add( hdrm_min, q_spec ), 2 ); /* 2 guard bits to avoid over-flows (1 for stereo_coder_tcx_fx and other for power spectrum calculation )*/ + q_spec = sub( add( hdrm_min, q_spec ), 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -407,7 +403,8 @@ void stereo_mdct_core_enc_fx( /*--------------------------------------------------------------* * Power spectrum calculation *---------------------------------------------------------------*/ - Word16 length; + Word16 length, exp, shift1, shift2, norm; + Word32 mdct, mdst; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -437,17 +434,13 @@ void stereo_mdct_core_enc_fx( IF( sts[ch]->hTcxEnc->tns_ms_flag[n] ) { + exp = add( s_max( mdst_spectrum_e[ch][n], sts[ch]->hTcxEnc->spectrum_e[n] ), 1 ); + shift1 = sub( mdst_spectrum_e[ch][n], exp ); + shift2 = sub( sts[ch]->hTcxEnc->spectrum_e[n], exp ); + /* power spectrum: MDCT^2 + MDST^2 */ FOR( i = 0; i < L_subframeTCX; i++ ) { - W_tmp = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 - move32(); - move16(); - W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */ tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ @@ -455,7 +448,14 @@ void stereo_mdct_core_enc_fx( tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); + + mdst = L_shl( mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp + mdct = L_shl( sts[ch]->hTcxEnc->spectrum_fx[n][i], shift2 ); // exp: exp + powerSpec64[ch][i + n * L_subframeTCX] = W_mac_32_32( W_mult_32_32( mdct, mdct ), mdst, mdst ); // exp: 2*exp + move64(); } + exp_powerSpec64[ch][n] = shl( exp, 1 ); + move16(); } ELSE { @@ -493,53 +493,31 @@ void stereo_mdct_core_enc_fx( } /* power spectrum: MDCT^2 + MDST^2 */ - W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][0], sts[ch]->hTcxEnc->spectrum_fx[n][0] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpec_fx[ch][n * L_subframeTCX] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_powSpec[n * L_subframeTCX] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 - move32(); - move16(); + mdct = L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][0], 1 ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + powerSpec64[ch][n * L_subframeTCX] = W_mult_32_32( mdct, mdct ); // exp: 2(sts[ch]->hTcxEnc->spectrum_e[n]+1) + move64(); FOR( i = 1; i < L_subframeTCX - 1; i++ ) { - Word32 mdst_fx = L_sub( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], sts[ch]->hTcxEnc->spectrum_fx[n][i - 1] ); /* An MDST estimate q_spec*/ - - W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 - move32(); - move16(); + mdct = L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i], 1 ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + mdst = L_sub( L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], 1 ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i - 1], 1 ) ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + powerSpec64[ch][i + n * L_subframeTCX] = W_mac_32_32( W_mult_32_32( mdct, mdct ), mdst, mdst ); // exp: 2(sts[ch]->hTcxEnc->spectrum_e[n]+1) + move64(); } - W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpec_fx[ch][( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_powSpec[( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 - move32(); + mdct = L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], 1 ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + powerSpec64[ch][L_subframeTCX - 1 + n * L_subframeTCX] = W_mult_32_32( mdct, mdct ); // exp: 2(sts[ch]->hTcxEnc->spectrum_e[n]+1) + move64(); + + exp_powerSpec64[ch][n] = shl( add( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), 1 ); move16(); } } /* Aligning the Q-factors */ { - q_powSpec[ch] = Q31; q_powSpecMsInv[ch] = Q31; move16(); - move16(); - FOR( i = 0; i < N_MAX; i++ ) - { - IF( powerSpec_fx[ch][i] != 0 ) - { - q_powSpec[ch] = s_min( q_powSpec[ch], tmp_q_powSpec[i] ); - move16(); - exp_powerSpec[ch][i] = sub( Q31, tmp_q_powSpec[i] ); - move16(); - } - } FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) @@ -551,16 +529,11 @@ void stereo_mdct_core_enc_fx( } } } - FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpecMsInv[ch] ) ); - /* Here precision is preserved for powerSpec_fx buffer by storing the fixed Q copy of same buffer in powerSpec_fx_tmp buffer */ - /* powerSpec_fx implementation has separate Q for each index, powerSpec_fx_tmp has all indices in same Q beyond this point */ - powerSpec_fx_tmp[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i + ( n * L_subframeTCX )], q_powSpec[ch] ) ); /* q_powSpec */ - move32(); move32(); } } @@ -596,8 +569,9 @@ void stereo_mdct_core_enc_fx( * and quantization (0: tonal, 1: noise-like). * * Detect low pass if present. * *-----------------------------------------------------------*/ - ComputeSpectrumNoiseMeasure_fx( powerSpec_fx_tmp[ch], L_subframeTCX, i_mult( st->hTcxEnc->nmStartLine, idiv1616( L_subframeTCX, st->hTcxEnc->L_frameTCX ) ), - NE_32( imult3216( st->last_sr_core, st->L_frame ), imult3216( st->sr_core, st->L_frame_past ) ) || NE_16( st->last_core, TCX_20_CORE ), st->hTcxEnc->memQuantZeros, L_subframeTCX ); + ComputeSpectrumNoiseMeasure_ivas_fx( powerSpec64[ch], L_subframeTCX, i_mult( st->hTcxEnc->nmStartLine, idiv1616( L_subframeTCX, st->hTcxEnc->L_frameTCX ) ), + NE_32( imult3216( st->last_sr_core, st->L_frame ), imult3216( st->sr_core, st->L_frame_past ) ) || NE_16( st->last_core, TCX_20_CORE ), + st->hTcxEnc->memQuantZeros, L_subframeTCX ); } st->hTcxEnc->measuredBwRatio = ONE_IN_Q14; /* No bandwidth limit for the noise filling Q14*/ @@ -630,8 +604,48 @@ void stereo_mdct_core_enc_fx( IF( ( NE_16( hStereoMdct->mdct_stereo_mode[n], hStereoMdct->IGFStereoMode[n] ) || EQ_16( hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) && !hStereoMdct->isSBAStereoMode ) { IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; - p_powerSpec_fx[0] = powerSpec_fx_tmp[0]; - p_powerSpec_fx[1] = powerSpec_fx_tmp[1]; + Word32 powerSpec_fx[CPE_CHANNELS][N_MAX], *p_powerSpec_fx[CPE_CHANNELS]; + Word16 q_powSpec[CPE_CHANNELS]; + p_powerSpec_fx[0] = powerSpec_fx[0]; + p_powerSpec_fx[1] = powerSpec_fx[1]; + { + /* Copy powerSpec values from 64 bit buffer to 32 bit buffer */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + Word16 n1, nsub = 1; + length = sts[ch]->hTcxEnc->L_frameTCX; + move16(); + move16(); + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + nsub = NB_DIV; + move16(); + } + IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) ) + { + length = add( length, shr( length, 2 ) ); + } + exp = sub( exp_powerSpec64[ch][0], W_norm_arr( powerSpec64[ch], length ) ); + IF( EQ_16( nsub, 2 ) ) + { + exp = s_max( exp, sub( exp_powerSpec64[ch][1], W_norm_arr( powerSpec64[ch] + length, length ) ) ); + } + FOR( n1 = 0; n1 < nsub; n1++ ) + { + shift1 = sub( sub( exp_powerSpec64[ch][n1], exp ), 32 ); + FOR( i = 0; i < length; i++ ) + { + /* This doesn't result in saturation */ + powerSpec_fx[ch][i + n1 * length] = W_shl_sat_l( powerSpec64[ch][i + n1 * length], shift1 ); // exp: exp + move32(); + } + } + set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) ); + q_powSpec[ch] = sub( 31, exp ); // exp: exp + move16(); + } + } hIGFEnc[0] = sts[0]->hIGFEnc; hIGFEnc[1] = sts[1]->hIGFEnc; @@ -677,6 +691,42 @@ void stereo_mdct_core_enc_fx( } ELSE { + Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; // each value has a different exponent + Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX]; + { + /* Copy powerSpec values from 64 bit buffer to 32 bit buffer */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + Word16 n1, nsub; + nsub = 1; + length = sts[ch]->hTcxEnc->L_frameTCX; + move16(); + move16(); + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + nsub = NB_DIV; + move16(); + } + IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) ) + { + length = add( length, shr( length, 2 ) ); + } + FOR( n1 = 0; n1 < nsub; n1++ ) + { + FOR( i = 0; i < length; i++ ) + { + norm = W_norm( powerSpec64[ch][i + n1 * length] ); + powerSpec_fx[ch][i + n1 * length] = W_extract_h( W_shl( powerSpec64[ch][i + n1 * length], norm ) ); // exp = exp_powerSpec64[ch][n1]-norm + exp_powerSpec[ch][i + n1 * length] = sub( exp_powerSpec64[ch][n1], norm ); + move32(); + move16(); + } + } + set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) ); + set16_fx( exp_powerSpec[ch] + length, 0, sub( N_MAX + L_MDCT_OVLP_MAX, length ) ); + } + } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; @@ -703,6 +753,42 @@ void stereo_mdct_core_enc_fx( } ELSE { + Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; // each value has a different exponent + Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX]; + { + /* Copy powerSpec values from 64 bit buffer to 32 bit buffer */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + Word16 n1, nsub; + nsub = 1; + length = sts[ch]->hTcxEnc->L_frameTCX; + move16(); + move16(); + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + nsub = NB_DIV; + move16(); + } + IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) ) + { + length = add( length, shr( length, 2 ) ); + } + FOR( n1 = 0; n1 < nsub; n1++ ) + { + FOR( i = 0; i < length; i++ ) + { + norm = W_norm( powerSpec64[ch][i + n1 * length] ); + powerSpec_fx[ch][i + n1 * length] = W_extract_h( W_shl( powerSpec64[ch][i + n1 * length], norm ) ); // exp = exp_powerSpec64[ch][n1]-norm + exp_powerSpec[ch][i + n1 * length] = sub( exp_powerSpec64[ch][n1], norm ); + move32(); + move16(); + } + } + set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) ); + set16_fx( exp_powerSpec[ch] + length, 0, sub( N_MAX + L_MDCT_OVLP_MAX, length ) ); + } + } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { st = sts[ch]; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 51e9849c7..d6532b207 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1498,6 +1498,14 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, Word8 *noiseFlags, Word16 lowpassLine ); +void ComputeSpectrumNoiseMeasure_ivas_fx( Word64 *powerSpec, /* Qx */ + Word16 L_frame, /* Q0 */ + Word16 startLine, /* Q0 */ + Word8 resetMemory, /* Q0 */ + Word8 *noiseFlags, /* Q0 */ + Word16 lowpassLine /* Q0 */ +); + void lpc_quantization_fx( Encoder_State *st, const Word16 lsp[], /* Q15 */ diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index ad1720665..46f83c094 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -172,6 +172,117 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, } } +void ComputeSpectrumNoiseMeasure_ivas_fx( Word64 *powerSpec, /* Qx */ + Word16 L_frame, /* Q0 */ + Word16 startLine, /* Q0 */ + Word8 resetMemory, /* Q0 */ + Word8 *noiseFlags, /* Q0 */ + Word16 lowpassLine /* Q0 */ +) +{ + Word16 i, lastTone, j, exp; + Word32 c; + Word64 s, temp; + + IF( resetMemory != 0 ) + { + FOR( i = 0; i < lowpassLine; i++ ) + { + noiseFlags[i] = 0; + move16(); + } + } + + FOR( i = lowpassLine; i < L_frame; i++ ) + { + noiseFlags[i] = 1; + move16(); + } + + test(); + IF( powerSpec != NULL && LT_16( add( startLine, 6 ), L_frame ) ) + { + lastTone = 0; + move16(); + + /* noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */ + i = sub( startLine, 1 ); + /* s = powerSpec[i - 7] + powerSpec[i - 6] + powerSpec[i - 5] + + powerSpec[i - 4] + powerSpec[i - 3] + powerSpec[i - 2] + + powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1] + + powerSpec[i + 2] + powerSpec[i + 3] + powerSpec[i + 4] + + powerSpec[i + 5] + powerSpec[i + 6] + powerSpec[i + 7]; */ + + s = powerSpec[i - 7]; // Qx + move64(); + FOR( j = -6; j < 8; j++ ) + { + s = W_add( s, powerSpec[i + j] ); // Qx + } + + FOR( i = i + 1; i < lowpassLine - 7; i++ ) + { + /* c = powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1]; */ + temp = W_add( W_add( powerSpec[i - 1], powerSpec[i] ), powerSpec[i + 1] ); + exp = W_norm( temp ); + c = W_extract_h( W_shl( temp, exp ) ); // Qx+exp-32 + + /* s += powerSpec[i + 7] - powerSpec[i - 8]; */ + s = W_sub( s, powerSpec[i - 8] ); // Qx + s = W_add( s, powerSpec[i + 7] ); // Qx + + /* ( 1.75f - 0.5f * noiseFlags[i] ) * c */ + temp = W_mult_32_32( c, L_msu0( 28672 /* 1.75 in Q14*/, 8192 /* 0.5 in Q14 */, noiseFlags[i] ) ); // Qx+exp-32+14+1 = Qx+exp-17 + + IF( GE_64( W_shl( s, sub( exp, Q17 ) ), temp ) /* s >= ( 1.75f - 0.5f * noiseFlags[i] ) * c */ ) // Qx+exp-17 + { + noiseFlags[i] = 1; + move16(); + } + ELSE + { + noiseFlags[i] = 0; + lastTone = i; + move16(); + move16(); + } + } + + /* lower L_frame*startRatio lines are tonal (0), upper 7 lines are processed separately */ + FOR( ; i < lowpassLine - 1; i++ ) + { + /* c = powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1]; */ + temp = W_add( W_add( powerSpec[i - 1], powerSpec[i] ), powerSpec[i + 1] ); + exp = W_norm( temp ); + c = W_extract_h( W_shl( temp, exp ) ); // Qx+exp-32 + + /* ( 1.75f - 0.5f * noiseFlags[i] ) * c */ + temp = W_mult_32_32( c, L_msu0( 28672 /* 1.75 in Q14*/, 8192 /* 0.5 in Q14 */, noiseFlags[i] ) ); // Qx+exp-32+14+1 = Qx+exp-17 + + IF( GE_64( W_shl( s, sub( exp, Q17 ) ), temp ) /* s >= ( 1.75f - 0.5f * noiseFlags[i] ) * c */ ) // Qx+exp-17 + { + noiseFlags[i] = 1; + move16(); + } + ELSE + { + noiseFlags[i] = 0; + lastTone = i; + move16(); + move16(); + } + } + noiseFlags[i] = 1; /* uppermost line is defined as noise-like (1) */ + move16(); + + if ( lastTone > 0 ) /* spread uppermost tonal line one line upward */ + { + noiseFlags[lastTone + 1] = 0; + move16(); + } + } +} + static void detectLowpassFac( const Word32 *powerSpec, Word16 powerSpec_e, Word16 L_frame, Word8 rectWin, Word16 *pLpFac, Word16 lowpassLine ) { Word16 i, tmp; -- GitLab From 27e6f62214ad81b3fb1faef009456681844bc57e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 18:10:32 +0530 Subject: [PATCH 1006/1221] Removed scalings before ProcessStereoIGF_fx in stereo_mdct_core_enc_fx and decoder MSAN fix --- lib_com/prot_fx.h | 6 +++ lib_dec/ivas_osba_dec_fx.c | 5 ++ lib_enc/igf_enc.c | 11 +++-- lib_enc/ivas_mct_enc_mct_fx.c | 12 +++-- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 68 ++++++++------------------ lib_enc/tcx_utils_enc_fx.c | 6 ++- 6 files changed, 51 insertions(+), 57 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index e60b8ac92..4257b7e79 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -10859,8 +10859,11 @@ void ProcessStereoIGF_fx( Word16 q_pITFMDCTSpectrum_1, Word16 q_pITFMDCTSpectrum_2, Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ + Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ const Word32 element_brate, /* i : element bitrate */ @@ -10873,8 +10876,11 @@ void IGFEncApplyStereo_fx( const Word16 igfGridIdx, /* i : IGF grid index */ Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ + Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i : exp of inverse spectrum */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ const Word32 element_brate, /* i : element bitrate */ diff --git a/lib_dec/ivas_osba_dec_fx.c b/lib_dec/ivas_osba_dec_fx.c index 80413b21a..d12bf12e9 100644 --- a/lib_dec/ivas_osba_dec_fx.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -138,6 +138,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( Word32 *p_sepobj_fx[BINAURAL_CHANNELS]; Word16 channel_offset; + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + set32_fx( output_separated_objects_fx[i], 0, L_FRAME48k ); + } + FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) { p_sepobj_fx[n] = &output_separated_objects_fx[n][0]; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index c8e8974c2..bfb4a7423 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -2626,8 +2626,11 @@ void IGFEncApplyStereo_fx( const Word16 igfGridIdx, /* i : IGF grid index */ Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ + Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i : exp of inverse spectrum */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ const Word32 element_brate, /* i : element bitrate */ @@ -2691,7 +2694,9 @@ void IGFEncApplyStereo_fx( last_core_acelp = extract_l( EQ_16( sts[ch]->last_core, ACELP_CORE ) ); IGF_UpdateInfo( hIGFEnc[ch], igfGridIdx ); - IGF_CalculateStereoEnvelope_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], sts[ch]->hTcxEnc->spectrum_e[frameno], inv_spectrum_fx[ch][frameno], sts[ch]->hTcxEnc->spectrum_e[frameno], pPowerSpectrumParameter_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], pPowerSpectrumParameterMsInv_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx, coreMsMask, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp ); + IGF_CalculateStereoEnvelope_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], sts[ch]->hTcxEnc->spectrum_e[frameno], inv_spectrum_fx[ch][frameno], + exp_inv_spectrum_fx[ch], pPowerSpectrumParameter_fx[ch], exp_pPowerSpectrum_fx[ch], pPowerSpectrumParameterMsInv_fx[ch], + exp_pPowerSpectrumMsInv_fx[ch], igfGridIdx, coreMsMask, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp ); IF( EQ_16( sts[ch]->core, TCX_20_CORE ) ) { @@ -2702,11 +2707,11 @@ void IGFEncApplyStereo_fx( pPowerSpectrumParameter_fx[ch] = NULL; } - set16_fx( exp_pPowerSpectrum, sts[ch]->hTcxEnc->spectrum_e[frameno], L_FRAME48k ); + set16_fx( exp_pPowerSpectrum, exp_pPowerSpectrum_fx[ch], L_FRAME48k ); IGF_Whitening_ivas_fx( hIGFEnc[ch], pPowerSpectrumParameter_fx[ch], &exp_pPowerSpectrum[0], igfGridIdx, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, ( sts[0]->hTcxEnc->fUseTns[frameno] || sts[1]->hTcxEnc->fUseTns[frameno] ), sp_aud_decision0, element_brate, sts[ch]->element_mode ); - IGF_ErodeSpectrum_ivas_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx, mct_on ); + IGF_ErodeSpectrum_ivas_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], exp_pPowerSpectrum_fx[ch], igfGridIdx, mct_on ); } return; } diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 78bf976d1..66bdb1235 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -1072,7 +1072,7 @@ void mctStereoIGF_enc_fx( IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ) || EQ_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) { - + Word16 exp_powerSpec_tmp[CPE_CHANNELS]; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { s = s_min( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[n] ) ); @@ -1095,10 +1095,12 @@ void mctStereoIGF_enc_fx( move16(); move16(); } - - ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, - p_orig_spectrum_fx, q_origSpec, q_origSpec, - p_powerSpec_fx, p_powerSpecMsInv_fx, p_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); + exp_powerSpec_tmp[0] = p_st[0]->hTcxEnc->spectrum_e[0]; + exp_powerSpec_tmp[1] = p_st[1]->hTcxEnc->spectrum_e[0]; + move16(); + move16(); + ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum_fx, q_origSpec, q_origSpec, p_powerSpec_fx, exp_powerSpec_tmp, + p_powerSpecMsInv_fx, exp_powerSpec_tmp, p_inv_spectrum_fx, exp_powerSpec_tmp, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); } ELSE { diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 91b8726f0..46134a270 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -143,6 +143,7 @@ void stereo_mdct_core_enc_fx( Word32 *quantized_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV]; + Word16 exp_inv_spectrum[CPE_CHANNELS]; Word16 i, ch, nSubframes, L_subframeTCX; Word16 n, nAvailBits; Word16 tnsSize[CPE_CHANNELS][NB_DIV]; /* number of tns parameters put into prm */ @@ -151,8 +152,8 @@ void stereo_mdct_core_enc_fx( Word32 *p_mdst_spectrum_long_fx[CPE_CHANNELS]; Word32 mdst_spectrum_long_fx[CPE_CHANNELS][N_MAX]; Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; - Word16 q_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s; - Word16 tmp_q_powSpec[N_MAX], tmp_q_powSpecInv[N_MAX], *tmp_q_psi[2]; + Word16 exp_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s; + Word16 tmp_q_powSpecInv[N_MAX], *tmp_q_psi[2]; Word64 W_tmp; Encoder_State *st, **sts; STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct; @@ -186,8 +187,6 @@ void stereo_mdct_core_enc_fx( } set16_fx( tmp_q_powSpecInv, 63, N_MAX ); - set16_fx( tmp_q_powSpec, 63, N_MAX ); - set16_fx( q_powSpecMsInv, 31, MCT_MAX_CHANNELS ); tmp_q_psi[0] = tmp_q_powSpecInv; tmp_q_psi[1] = &tmp_q_powSpecInv[N_TCX10_MAX]; @@ -398,6 +397,9 @@ void stereo_mdct_core_enc_fx( } } stereo_coder_tcx_fx( hStereoMdct, sts, ms_mask, mdst_spectrum_fx, inv_spectrum_fx, inv_mdst_spectrum_fx, 0, q_spec ); + exp_inv_spectrum[0] = exp_inv_spectrum[1] = sub( Q31, q_spec ); + move16(); + move16(); } /*--------------------------------------------------------------* @@ -516,16 +518,15 @@ void stereo_mdct_core_enc_fx( /* Aligning the Q-factors */ { - q_powSpecMsInv[ch] = Q31; + Word16 q_temp = Q31; move16(); FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { - IF( powerSpecMsInv_fx[ch][n][i] != 0 ) + if ( powerSpecMsInv_fx[ch][n][i] != 0 ) { - q_powSpecMsInv[ch] = s_min( q_powSpecMsInv[ch], tmp_q_psi[n][i] ); - move16(); + q_temp = s_min( q_temp, tmp_q_psi[n][i] ); } } } @@ -533,10 +534,12 @@ void stereo_mdct_core_enc_fx( { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpecMsInv[ch] ) ); + powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_temp ) ); move32(); } } + exp_powSpecMsInv[ch] = sub( Q31, q_temp ); + move16(); } } @@ -605,7 +608,7 @@ void stereo_mdct_core_enc_fx( { IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; Word32 powerSpec_fx[CPE_CHANNELS][N_MAX], *p_powerSpec_fx[CPE_CHANNELS]; - Word16 q_powSpec[CPE_CHANNELS]; + Word16 exp_powSpec[CPE_CHANNELS]; p_powerSpec_fx[0] = powerSpec_fx[0]; p_powerSpec_fx[1] = powerSpec_fx[1]; { @@ -642,52 +645,21 @@ void stereo_mdct_core_enc_fx( } } set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) ); - q_powSpec[ch] = sub( 31, exp ); // exp: exp + exp_powSpec[ch] = exp; // exp: exp move16(); } } + hIGFEnc[0] = sts[0]->hIGFEnc; hIGFEnc[1] = sts[1]->hIGFEnc; - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - q_spec = sub( Q31, sts[ch]->hTcxEnc->spectrum_e[n] ); - Word16 q_comm = s_min( sub( Q31, sts[ch]->hTcxEnc->spectrum_e[n] ), s_min( q_powSpec[ch], q_powSpecMsInv[ch] ) ); - Word16 n_sb = NB_DIV; - move16(); - if ( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - n_sb = 1; - move16(); - } - length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */ - IF( NE_16( q_spec, q_comm ) ) - { - Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], length, sub( q_comm, q_spec ) ); /* q_powSpec */ - Scale_sig32( inv_spectrum_fx[ch][n], length, sub( q_comm, q_spec ) ); /* q_powSpec */ - sts[ch]->hTcxEnc->spectrum_e[n] = sub( Q31, q_comm ); - move16(); - } - IF( NE_16( q_powSpec[ch], q_comm ) ) - { - Scale_sig32( &p_powerSpec_fx[ch][0], L_subframeTCX, sub( q_comm, q_powSpec[ch] ) ); /* q_spec */ - q_powSpec[ch] = q_comm; - move16(); - } - IF( NE_16( q_powSpecMsInv[ch], q_comm ) ) - { - Scale_sig32( powerSpecMsInv_fx[ch][0], L_subframeTCX, sub( q_comm, q_powSpecMsInv[ch] ) ); /* q_spec */ - q_powSpecMsInv[ch] = q_comm; - move16(); - } - } hIGFEnc[0]->spec_be_igf_e = p_orig_spectrum_e[0]; - move16(); hIGFEnc[1]->spec_be_igf_e = p_orig_spectrum_e[1]; move16(); - ProcessStereoIGF_fx( hStereoMdct, sts, ms_mask, - orig_spectrum_fx, sub( Q31, p_orig_spectrum_e[0] ), sub( Q31, p_orig_spectrum_e[1] ), - p_powerSpec_fx, powerSpecMsInv_fx, inv_spectrum_fx, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); + move16(); + + ProcessStereoIGF_fx( hStereoMdct, sts, ms_mask, orig_spectrum_fx, sub( Q31, p_orig_spectrum_e[0] ), sub( Q31, p_orig_spectrum_e[1] ), + p_powerSpec_fx, exp_powSpec, powerSpecMsInv_fx, exp_powSpecMsInv, inv_spectrum_fx, exp_inv_spectrum, + n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); } ELSE { diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 46f83c094..2abe538e4 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -4029,8 +4029,11 @@ void ProcessStereoIGF_fx( Word16 q_pITFMDCTSpectrum_1, Word16 q_pITFMDCTSpectrum_2, Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ + Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ const Word32 element_brate, /* i : element bitrate */ @@ -4074,7 +4077,8 @@ void ProcessStereoIGF_fx( IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno], sub( Q31, q_pITFMDCTSpectrum_2 ) ); - IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, inv_spectrum_fx, frameno, sp_aud_decision0, element_brate, mct_on ); + IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, exp_pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, exp_pPowerSpectrumMsInv_fx, + inv_spectrum_fx, exp_inv_spectrum_fx, frameno, sp_aud_decision0, element_brate, mct_on ); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -- GitLab From e021386806c1746fb7bfb9b9ab0e8aaf02ca0ee8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 19:17:12 +0530 Subject: [PATCH 1007/1221] Precision improvements in SQ_gain_estimate_stereo_fx --- lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 65 ++++++++++++++---------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index a61b2b010..9a1198e20 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -836,52 +836,67 @@ void convertToMS_fx( /*! r: SQ gain */ static Word32 SQ_gain_estimate_stereo_fx( // e_res - Word32 xL_fx[], /* i : L vector to quantize Q31-e_xL*/ - Word16 e_xL, - Word32 xR_fx[], /* i : R vector to quantize Q31-e_xR*/ - Word16 e_xR, + const Word32 xL_fx[], /* i : L vector to quantize Q31-e_xL*/ + const Word16 e_xL, + const Word32 xR_fx[], /* i : R vector to quantize Q31-e_xR*/ + const Word16 e_xR, const Word16 nbitsSQ, /* i : number of bits targeted Q0*/ const Word16 lg, /* i : vector size (2048 max) Q0*/ Word16 *e_res ) { - Word16 i, q, iter, e_ener, e_tmp; + Word16 i, q, iter, e_ener, e_xL_2, e_xR_2, s; Word32 ener_fx, tmp_32, target_fx, fac_fx, offset_fx; - Word32 en_fx[N_MAX / 2]; // Q(26) + Word32 en_fx[N_MAX / 2]; // Q25 Word16 lg2, lg_4, lg2_4; + Word64 W_tmp, _0_01; lg_4 = shr( lg, 2 ); /* Q0 */ lg2_4 = shl( lg_4, 1 ); /* Q0 */ lg2 = shl( lg2_4, 2 ); /* Q0 */ i = 0; move16(); + e_xL_2 = shl( e_xL, 1 ); + e_xR_2 = shl( e_xR, 1 ); + _0_01 = W_shr( 21474836 /* 0.01 in Q31 */, sub( e_xL_2, 32 ) ); // 0.01 in 2*(Q of specL/R) + 1 - set32_fx( en_fx, 21474836 /* 0.01 in Q31 */, idiv1616( N_MAX, 2 ) ); + set32_fx( en_fx, 335544 /* 0.01 in Q25 */, ( N_MAX / 2 ) ); /* energy of quadruples with 9dB offset */ /* ignore that we may take no all lines into account, max. 3 lines at the upper end of the spectrum can be missed (if lg is not a multiple of 4, happens also in SQGain()*/ FOR( q = 0; q < lg_4; q++ ) { - ener_fx = BASOP_Util_Add_Mant32Exp( 21474836 /*0.01 in Q15*/, 0, Mpy_32_32( xL_fx[i], xL_fx[i] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 1], xL_fx[i + 1] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 2], xL_fx[i + 2] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 3], xL_fx[i + 3] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ - en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ + W_tmp = W_mac_32_32( _0_01, xL_fx[i], xL_fx[i] ); // 2 * e_xL + W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 1], xL_fx[i + 1] ); // 2 * e_xL + W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 2], xL_fx[i + 2] ); // 2 * e_xL + W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 3], xL_fx[i + 3] ); // 2 * e_xL + + s = W_norm( W_tmp ); + ener_fx = W_extract_h( W_shl( W_tmp, s ) ); + e_ener = sub( e_xL_2, s ); + + en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ move32(); - en_fx[q] = Mpy_32_16_1( L_add( e_ener * ONE_IN_Q25, en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) + en_fx[q] = Mpy_32_16_1( L_add( L_shl( e_ener, Q25 ), en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) move32(); i = add( i, 4 ); } i = 0; + move16(); FOR( ; q < lg2_4; q++ ) { - ener_fx = BASOP_Util_Add_Mant32Exp( 21474836 /*0.01 Q15*/, 0, Mpy_32_32( xR_fx[i], xR_fx[i] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 1], xR_fx[i + 1] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 2], xR_fx[i + 2] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 3], xR_fx[i + 3] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ - en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ + W_tmp = W_mac_32_32( _0_01, xR_fx[i], xR_fx[i] ); // 2 * e_xR + W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 1], xR_fx[i + 1] ); // 2 * e_xR + W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 2], xR_fx[i + 2] ); // 2 * e_xR + W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 3], xR_fx[i + 3] ); // 2 * e_xR + + s = W_norm( W_tmp ); + ener_fx = W_extract_h( W_shl( W_tmp, s ) ); + e_ener = sub( e_xR_2, s ); + + en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ move32(); - en_fx[q] = Mpy_32_16_1( L_add( e_ener * ONE_IN_Q25, en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) + en_fx[q] = Mpy_32_16_1( L_add( L_shl( e_ener, Q25 ), en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) move32(); i = add( i, 4 ); } @@ -898,24 +913,20 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res { fac_fx = L_shr( fac_fx, 1 ); /* Q25 */ offset_fx = L_sub( offset_fx, fac_fx ); /* Q25 */ - ener_fx = 0; - move32(); - e_ener = 0; - move16(); + W_tmp = 0; + move64(); FOR( i = 0; i < lg2_4; i++ ) { tmp_32 = L_sub( en_fx[i], offset_fx ); /* Q25 */ - e_tmp = 6; - move16(); /* avoid SV with 1 bin of amp < 0.5f */ IF( GT_32( tmp_32, 10066329 /*0.3 Q25*/ ) ) { - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, tmp_32, e_tmp, &e_ener ); /* Q31-e_ener */ + W_tmp = W_add( W_tmp, W_deposit32_l( tmp_32 ) ); /* Q25 */ /* if ener is above target -> break and increase offset */ - IF( L_shl_sat( ener_fx, sub( e_ener, Q13 ) ) > target_fx ) + IF( GT_64( W_tmp, W_shl( W_deposit32_l( target_fx ), 7 ) ) ) { offset_fx = L_add( offset_fx, fac_fx ); /* Q25 */ BREAK; -- GitLab From 5feaf0b4d57d671ffa92ff849db93bc4f683e081 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 19:26:25 +0530 Subject: [PATCH 1008/1221] Fix for 3GPP issue 1465: Decoder crash for low bitrate OSBA in ivas_spar_dec_upmixer_sf_fx() Link #1465 --- lib_com/cldfb.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 720ee37a0..6a9581498 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -901,7 +901,7 @@ void cldfbAnalysis_ts_fx_fixed_q( const Word16 *ptr_pf_fx; Word16 ptr_pf_sf; Word32 *timeBuffer_fx, buffer_fx[( CLDFB_NO_CHANNELS_MAX * CLDFB_NO_COL_MAX ) + ( 9 * CLDFB_NO_CHANNELS_MAX )]; - Word16 offset, frameSize; + Word16 offset, frameSize, gb, hr, shift; offset = sub( h_cldfb->p_filter_length, h_cldfb->no_channels ); frameSize = i_mult( h_cldfb->no_channels, h_cldfb->no_col ); @@ -1071,18 +1071,42 @@ void cldfbAnalysis_ts_fx_fixed_q( *q_cldfb = sub( *q_cldfb, 2 ); move16(); + gb = find_guarded_bits_fx( M1 ); + hr = L_norm_arr( iBuffer_fx, M1 ); + + IF( LT_16( hr, gb ) ) + { + scale_sig32( iBuffer_fx, M1, sub( hr, gb ) ); + } + /* FFT of DCT IV */ fft_cldfb_fx( iBuffer_fx, M2 ); /* post modulation of DCT IV */ - FOR( k = 0; k < M2; k++ ) + IF( LT_16( hr, gb ) ) { - /* do it inplace */ - /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ - imagBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ); // q - 5 - imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = Madd_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ); // q - 5 - move32(); - move32(); + shift = sub( gb, hr ); + FOR( k = 0; k < M2; k++ ) + { + /* do it inplace */ + /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + imagBuffer_fx[2 * k] = L_shl( Msub_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ), shift ); // q - 5 + imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = L_shl( Madd_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ), shift ); // q - 5 + move32(); + move32(); + } + } + ELSE + { + FOR( k = 0; k < M2; k++ ) + { + /* do it inplace */ + /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + imagBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ); // q - 5 + imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = Madd_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ); // q - 5 + move32(); + move32(); + } } IF( EQ_32( h_cldfb->prototype, CLDFB_PROTOTYPE_5_00MS ) ) -- GitLab From 7ab90bd2823d95a91cdd30a511e73b5ec1cf86c4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 21:19:26 +0530 Subject: [PATCH 1009/1221] Fix for 3GPP issue 1480: BASOP assert in MDCT-Stereo Stereo pre-processing with music signal Link #1480 --- lib_enc/ivas_mdct_core_enc_fx.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index e744c7f47..52a88064a 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -815,6 +815,7 @@ static UWord16 enc_ste_pre_mdct( Word16 mdst_exp1[2 * 960], mdst_exp2[2 * 960]; Word16 x1, x2, x3, x4, ans, tmp; Word32 maxSqrValue_fx; + Word64 sumL_64fx, sumR_64fx; IF( LT_16( nSamplesMax, 512 ) ) { @@ -885,7 +886,9 @@ static UWord16 enc_ste_pre_mdct( { return 0; } - + sumL_64fx = 0, sumR_64fx = 0; + move64(); + move64(); FOR( s = fadeInOff; s < nSampProc; s++ ) { Word32 absMagnL_fx, absMagnR_fx; @@ -898,8 +901,8 @@ static UWord16 enc_ste_pre_mdct( absMagnR_fx = Sqrt32( L_add( Mpy_32_32( sigR1_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI1_fx[s], sigI1_fx[s] ) ), &absMagnR_e ); corr_fx = L_add( corr_fx, L_add( Mpy_32_32( sigR0_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI0_fx[s], sigI1_fx[s] ) ) ); // q_com*2 - 31 - sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 - sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 + sumL_64fx = W_add( sumL_64fx, W_add( sigR0_fx[s], sigI0_fx[s] ) ); // q_com + sumR_64fx = W_add( sumR_64fx, W_add( sigR1_fx[s], sigI1_fx[s] ) ); // q_com sumMagnL_fx = BASOP_Util_Add_Mant32Exp( sumMagnL_fx, sumMagnL_e, absMagnL_fx, absMagnL_e, &sumMagnL_e ); sumMagnR_fx = BASOP_Util_Add_Mant32Exp( sumMagnR_fx, sumMagnR_e, absMagnR_fx, absMagnR_e, &sumMagnR_e ); sumPrdLR_fx = BASOP_Util_Add_Mant32Exp( sumPrdLR_fx, sumPrdLR_e, Mpy_32_32( absMagnL_fx, absMagnR_fx ), add( absMagnL_e, absMagnR_e ), &sumPrdLR_e ); @@ -911,7 +914,14 @@ static UWord16 enc_ste_pre_mdct( temp1 = L_shl( preproLen, x1 ); corr_fx = Mpy_32_32( corr_fx, temp1 ); x1 = sub( 62, add( shl( *q_com, 1 ), x1 ) ); - corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( sub( *q_com, 1 ), 1 ) ), &x1 ); + + x2 = W_norm( sumL_64fx ); + sumL_fx = W_extract_h( W_shl( sumL_64fx, x2 ) ); + + x3 = W_norm( sumR_64fx ); + sumR_fx = W_extract_h( W_shl( sumR_64fx, x3 ) ); + + corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, add( sub( add( *q_com, x2 ), 32 ), sub( add( *q_com, x3 ), 32 ) ) ), &x1 ); IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( corr_fx, x1, -maxSqrValue_fx, 52 ), -1 ) ) { -- GitLab From c946016412f3d3e53707309e5635f10c5a714d50 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 13 Apr 2025 21:12:19 +0200 Subject: [PATCH 1010/1221] replace BASOP_Util_Divide3232_Scale_cadence() by BASOP_Util_Divide3232_Scale_newton() --- lib_dec/ivas_dirac_dec_fx.c | 2 +- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 12 ++++++------ lib_dec/ivas_lfe_plc_fx.c | 4 ++-- lib_dec/ivas_mct_dec_fx.c | 6 +++--- lib_dec/ivas_stereo_cng_dec.c | 6 +++--- lib_dec/ivas_stereo_dft_dec.c | 2 +- lib_dec/ivas_stereo_mdct_stereo_dec_fx.c | 4 ++-- lib_dec/ivas_stereo_switching_dec_fx.c | 2 +- lib_dec/ivas_svd_dec_fx.c | 18 +++++++++--------- lib_dec/jbm_jb4sb.c | 2 +- 10 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index bbd4641b1..064185e47 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2614,7 +2614,7 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i] = L_add( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i], surCohEner_fx ); // Q29 move32(); - surCohRatio_fx[i] = BASOP_Util_Divide3232_Scale_cadence( surCohEner_fx, ( L_add( EPSILLON_FX, L_add( dirEne_fx, surCohEner_fx ) ) ), &temp_q ); + surCohRatio_fx[i] = BASOP_Util_Divide3232_Scale_newton( surCohEner_fx, ( L_add( EPSILLON_FX, L_add( dirEne_fx, surCohEner_fx ) ) ), &temp_q ); move32(); surCohRatio_fx[i] = L_shl( surCohRatio_fx[i], sub( temp_q, 16 ) ); // Q15 move32(); diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index 114083fad..6d367538d 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -1751,7 +1751,7 @@ Word16 computeMixingMatricesISM_fx( IF( svd_s_buffer_fx[i] ) { Word32 reg_fac; - reg_fac = BASOP_Util_Divide3232_Scale_cadence( MAX_32, svd_s_buffer_fx[i], &temp_e[i] ); + reg_fac = BASOP_Util_Divide3232_Scale_newton( MAX_32, svd_s_buffer_fx[i], &temp_e[i] ); Kx_reg_inv_fx[i] = reg_fac; move32(); temp_e[i] = sub( temp_e[i], svd_s_buffer_fx_e ); @@ -1760,7 +1760,7 @@ Word16 computeMixingMatricesISM_fx( ELSE { Word32 reg_fac; - reg_fac = BASOP_Util_Divide3232_Scale_cadence( MAX_32, EPSILON_FX_M, &temp_e[i] ); + reg_fac = BASOP_Util_Divide3232_Scale_newton( MAX_32, EPSILON_FX_M, &temp_e[i] ); Kx_reg_inv_fx[i] = reg_fac; move32(); temp_e[i] = sub( temp_e[i], EPSILON_FX_E ); @@ -1837,7 +1837,7 @@ Word16 computeMixingMatricesISM_fx( { IF( Cy_hat_diag_fx[i] ) { - G_hat_fx[i] = BASOP_Util_Divide3232_Scale_cadence( Cy_diag_fx[i], Cy_hat_diag_fx[i], &temp_e[i] ); + G_hat_fx[i] = BASOP_Util_Divide3232_Scale_newton( Cy_diag_fx[i], Cy_hat_diag_fx[i], &temp_e[i] ); move32(); temp_e[i] = add( temp_e[i], sub( Cy_diag_e, Cy_hat_diag_e ) ); move16(); @@ -1846,7 +1846,7 @@ Word16 computeMixingMatricesISM_fx( } ELSE { - G_hat_fx[i] = BASOP_Util_Divide3232_Scale_cadence( Cy_diag_fx[i], EPSILON_FX_M, &temp_e[i] ); + G_hat_fx[i] = BASOP_Util_Divide3232_Scale_newton( Cy_diag_fx[i], EPSILON_FX_M, &temp_e[i] ); move32(); temp_e[i] = add( temp_e[i], sub( Cy_diag_e, EPSILON_FX_E ) ); move16(); @@ -1949,7 +1949,7 @@ Word16 computeMixingMatricesISM_fx( { IF( Cy_tilde_p_fx[i + ( i * lengthCy )] ) { - adj_fx[i] = BASOP_Util_Divide3232_Scale_cadence( Cy_diag_fx[i], Cy_tilde_p_fx[i + ( i * lengthCy )], &temp_e[i] ); + adj_fx[i] = BASOP_Util_Divide3232_Scale_newton( Cy_diag_fx[i], Cy_tilde_p_fx[i + ( i * lengthCy )], &temp_e[i] ); move32(); temp_e[i] = add( temp_e[i], sub( Cy_diag_e, mat_mult_buffer2_e ) ); move16(); @@ -1958,7 +1958,7 @@ Word16 computeMixingMatricesISM_fx( } ELSE { - adj_fx[i] = BASOP_Util_Divide3232_Scale_cadence( Cy_diag_fx[i], EPSILON_FX_M, &temp_e[i] ); + adj_fx[i] = BASOP_Util_Divide3232_Scale_newton( Cy_diag_fx[i], EPSILON_FX_M, &temp_e[i] ); move32(); temp_e[i] = add( temp_e[i], sub( Cy_diag_e, EPSILON_FX_E ) ); move16(); diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index d98603d2a..a480ce7be 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -225,7 +225,7 @@ static Word16 lfeplc_lev_dur_fx( a_out_q_fx[0] = 30; move16(); - rc_fx[0] = BASOP_Util_Divide3232_Scale_cadence( -r_fx[1], r_fx[0], &temp_q2 ); + rc_fx[0] = BASOP_Util_Divide3232_Scale_newton( -r_fx[1], r_fx[0], &temp_q2 ); move32(); rc_q_fx[0] = add( sub( r_q_fx[1], r_q_fx[0] ), sub( 31, temp_q2 ) ); move16(); @@ -387,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate( s ), err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_newton( L_negate( s ), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 7e1597749..32403b11a 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -1330,7 +1330,7 @@ static ivas_error ivas_mc_dec_reconfig_fx( new_brate_SCE = 0; move32(); Word16 temp_e; - Word32 L_temp = BASOP_Util_Divide3232_Scale_cadence( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &temp_e ); + Word32 L_temp = BASOP_Util_Divide3232_Scale_newton( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &temp_e ); L_temp = L_shr( L_temp, sub( 31, temp_e ) ); new_brate_CPE = L_shl( L_temp, 1 ) /*CPE_CHANNELS*/; } @@ -1339,7 +1339,7 @@ static ivas_error ivas_mc_dec_reconfig_fx( new_brate_SCE = 0; move32(); Word16 temp_e; - Word32 L_temp = BASOP_Util_Divide3232_Scale_cadence( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &temp_e ); + Word32 L_temp = BASOP_Util_Divide3232_Scale_newton( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &temp_e ); L_temp = L_shr( L_temp, sub( 31, temp_e ) ); new_brate_CPE = L_shl( L_temp, 1 ) /*CPE_CHANNELS*/; } @@ -1348,7 +1348,7 @@ static ivas_error ivas_mc_dec_reconfig_fx( new_brate_SCE = 0; /* ivas_total_brate / st_ivas->nchan_transport;*/ move32(); Word16 temp_e; - Word32 L_temp = BASOP_Util_Divide3232_Scale_cadence( ivas_total_brate, st_ivas->nchan_transport, &temp_e ); + Word32 L_temp = BASOP_Util_Divide3232_Scale_newton( ivas_total_brate, st_ivas->nchan_transport, &temp_e ); L_temp = L_shr( L_temp, sub( 31, temp_e ) ); new_brate_CPE = L_shl( L_temp, 1 ) /*CPE_CHANNELS*/; } diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 478f96dc1..6b8a8f949 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -316,7 +316,7 @@ static void stereo_dft_generate_comfort_noise_fx( // lp_ener_fx will be in Q6 at this point. // So applying appropriate left shift on the denominator. - factor = L_shr( BASOP_Util_Divide3232_Scale_cadence( st->lp_ener_fx, L_shl( st->L_frame, Q6 ), &q_div ), 1 ); /* fixed factor in the loop below */ /* q_div */ + factor = L_shr( BASOP_Util_Divide3232_Scale_newton( st->lp_ener_fx, L_shl( st->L_frame, Q6 ), &q_div ), 1 ); /* fixed factor in the loop below */ /* q_div */ factor = Sqrt32( factor, &q_div ); q_div = add( q_div, 1 ); @@ -399,7 +399,7 @@ static void stereo_dft_generate_comfort_noise_fx( assert( ftmp > 0 ); q_div = 0; move16(); - ftmp = BASOP_Util_Divide3232_Scale_cadence( L_shl( 1, q_tmp ), ftmp, &q_div ); /* q_div */ + ftmp = BASOP_Util_Divide3232_Scale_newton( L_shl( 1, q_tmp ), ftmp, &q_div ); /* q_div */ /* in float: both a = "div"=(1/(x^2+y^2) and sqrt(a) is used and summed up in the same loop. @@ -672,7 +672,7 @@ static void stereo_dft_generate_comfort_noise_fx( move16(); FOR( k = 0; k < ( hFdCngCom->nFFTpart - 2 ); k++ ) { - factor = BASOP_Util_Divide3232_Scale_cadence( L_add( hFdCngCom->sidNoiseEstLp[k], DELTA_FX ), L_add( st->hFdCngDec->partNoiseShape[k], DELTA_FX ), &q_div ); /* q_div */ + factor = BASOP_Util_Divide3232_Scale_newton( L_add( hFdCngCom->sidNoiseEstLp[k], DELTA_FX ), L_add( st->hFdCngDec->partNoiseShape[k], DELTA_FX ), &q_div ); /* q_div */ q_div = add( q_div, sub( hFdCngCom->sidNoiseEstExp, st->hFdCngDec->partNoiseShape_exp ) ); IF( q_div < 0 ) { diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index f0fd1978b..92ae9159c 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -281,7 +281,7 @@ void stereo_dft_dec_analyze_fx( move16(); NFFT = NS2SA_FX2( inputFs, STEREO_DFT32MS_N_NS ); Word16 qfac_fx; - fac_fx = BASOP_Util_Divide3232_Scale_cadence( hStereoDft->NFFT, NFFT, &qfac_fx ); /* qfac_fx */ + fac_fx = BASOP_Util_Divide3232_Scale_newton( hStereoDft->NFFT, NFFT, &qfac_fx ); /* qfac_fx */ qfac_fx = sub( 31, qfac_fx ); ovl2 = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL2_NS ); move16(); diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 5248839f5..8842a6792 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -433,7 +433,7 @@ void stereo_decoder_tcx_fx( IF( !mct_on ) { - tmp_32 = BASOP_Util_Divide3232_Scale_cadence( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e ); + tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e ); tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26 nrgRatio = L_sub( tmp_32, ONE_IN_Q26 ); // Q26 @@ -488,7 +488,7 @@ void stereo_decoder_tcx_fx( } ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) ) { - inv_nrgRatio = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q26, nrgRatio, &tmp_e ); + inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e ); shift = sub( 5, tmp_e ); v_multc_fixed( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */ Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) ); /* Qx */ diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index 1a6ea257b..bcf714352 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -2361,7 +2361,7 @@ static Word32 ncross_corr_self_fx( Word16 q_cc = W_norm( c_c_fx ); Word32 num = W_extract_h( W_shl( c_c_fx, q_cc ) ); // Q(23 + q_cc - 32) -> e(40 - q_cc) Word16 quo_e; - num = BASOP_Util_Divide3232_Scale_cadence( num, energy, &quo_e ); + num = BASOP_Util_Divide3232_Scale_newton( num, energy, &quo_e ); quo_e = add( sub( sub( 40, q_cc ), q_prod ), quo_e ); c_c_fx_return = L_shl_sat( num, quo_e ); // Q31 } diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 8a9224ffa..014597972 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -628,7 +628,7 @@ static void ApplyQRTransform_fx( L_temp1 = BASOP_Util_Add_Mant32Exp( r, r_e, r, r_e, &L_temp1_e ); /* exp(L_temp1_e) */ L_temp1 = maxWithSign_fx( Mpy_32_32( L_temp1, x_split ) ); /* exp(L_temp1_e + x_split_e) */ L_temp1_e = add( L_temp1_e, x_split_e ); - d = BASOP_Util_Divide3232_Scale_cadence( d, L_temp1, &temp_exp ); /* temp_exp + d_e - L_temp1_e */ + d = BASOP_Util_Divide3232_Scale_newton( d, L_temp1, &temp_exp ); /* temp_exp + d_e - L_temp1_e */ d_e = add( temp_exp, sub( d_e, L_temp1_e ) ); g = GivensRotation_fx( MAX_32, 0, d, d_e, &g_e ); @@ -646,7 +646,7 @@ static void ApplyQRTransform_fx( L_temp1_e = g_e; move16(); L_temp2 = maxWithSign_fx( BASOP_Util_Add_Mant32Exp( d, d_e, L_temp1, L_temp1_e, &L_temp2_e ) ); /* exp(L_temp2_e) */ - mu = BASOP_Util_Divide3232_Scale_cadence( x_split, L_temp2, &mu_e ); /* exp(mu_e + (x-plit_e - L_temp2_e)) */ + mu = BASOP_Util_Divide3232_Scale_newton( x_split, L_temp2, &mu_e ); /* exp(mu_e + (x-plit_e - L_temp2_e)) */ mu_e = add( mu_e, sub( x_split_e, L_temp2_e ) ); mu = BASOP_Util_Add_Mant32Exp( mu, mu_e, L_negate( r ), r_e, &mu_e ); /* exp(mu_e) */ @@ -654,7 +654,7 @@ static void ApplyQRTransform_fx( L_temp1 = BASOP_Util_Add_Mant32Exp( x_ii, x_ii_e, x_kk, x_kk_e, &L_temp1_e ); /* exp(L_temp1_e) */ L_temp2 = BASOP_Util_Add_Mant32Exp( x_ii, x_ii_e, L_negate( x_kk ), x_kk_e, &L_temp2_e ); /* exp(L_temp2_e) */ d = BASOP_Util_Add_Mant32Exp( Mpy_32_32( L_temp1, L_temp2 ), add( L_temp1_e, L_temp2_e ), Mpy_32_32( r, mu ), add( r_e, mu_e ), &d_e ); /* exp(d_e) */ - d = BASOP_Util_Divide3232_Scale_cadence( d, maxWithSign_fx( x_ii ), &temp_exp ); /* exp(temp_exp + (d_e - x_ii_e) */ + d = BASOP_Util_Divide3232_Scale_newton( d, maxWithSign_fx( x_ii ), &temp_exp ); /* exp(temp_exp + (d_e - x_ii_e) */ d_e = add( temp_exp, sub( d_e, x_ii_e ) ); /*QR transformation*/ @@ -917,7 +917,7 @@ static void biDiagonalReductionLeft_fx( { Word16 invVal_e; Word32 invVal; - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); + invVal = BASOP_Util_Divide3232_Scale_newton( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); norm_x = 0; move32(); norm_x_e = 0; @@ -954,7 +954,7 @@ static void biDiagonalReductionLeft_fx( singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ move32(); - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); + invVal = BASOP_Util_Divide3232_Scale_newton( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { @@ -1046,7 +1046,7 @@ static void biDiagonalReductionRight_fx( Word16 invVal_e, temp_e; Word32 invVal; - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); + invVal = BASOP_Util_Divide3232_Scale_newton( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /*nChannelsC */ { temp_e = norm_l( singularVectors[currChannel][jCh] ); @@ -1082,7 +1082,7 @@ static void biDiagonalReductionRight_fx( singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* exp(sing_exp) */ move32(); - invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); + invVal = BASOP_Util_Divide3232_Scale_newton( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { @@ -1162,10 +1162,10 @@ static void singularVectorsAccumulationLeft_fx( IF( t_ii ) /*if (fabsf(t_ii) > EPSILON *fabsf(t_ii)) {*/ { - t_ii = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( t_ii ), &temp_exp ); + t_ii = BASOP_Util_Divide3232_Scale_newton( MAXVAL_WORD32, maxWithSign_fx( t_ii ), &temp_exp ); t_ii_e = sub( temp_exp, t_ii_e ); Word16 tempe; - Word32 temp = BASOP_Util_Divide3232_Scale_cadence( t_ii, maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &tempe ); + Word32 temp = BASOP_Util_Divide3232_Scale_newton( t_ii, maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &tempe ); tempe = add( tempe, sub( t_ii_e, singularVectors_Left_e[nCh][nCh] ) ); // fprintf( fp, "%e\n", me2f( t_ii, t_ii_e ) ); FOR( iCh = nCh + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index 002b4bc10..d1f782b55 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -911,7 +911,7 @@ static void JB4_adaptActivePlayout( ELSE { Word16 exp; - Word32 temp = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_sub( dropRateMax, dropRateMin ) ), W_extract_l( dropGapMax ), &exp ); + Word32 temp = BASOP_Util_Divide3232_Scale_newton( W_extract_l( W_sub( dropRateMax, dropRateMin ) ), W_extract_l( dropGapMax ), &exp ); /* limit gap to [gapMin,gapMax] and calculate current drop rate from gap */ Word64 temp2 = W_mult0_32_32( W_extract_l( JB4_MIN( gap, dropGapMax ) ), temp ); Word64 temp3 = W_shr( temp2, sub( 31, exp ) ); -- GitLab From 87cd131a980ed945d2cf71621fc9bfa7ab6a2029 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Sun, 13 Apr 2025 21:15:21 +0200 Subject: [PATCH 1011/1221] fix formatting --- lib_dec/ivas_svd_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_svd_dec_fx.c b/lib_dec/ivas_svd_dec_fx.c index 014597972..4b0522884 100644 --- a/lib_dec/ivas_svd_dec_fx.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -646,7 +646,7 @@ static void ApplyQRTransform_fx( L_temp1_e = g_e; move16(); L_temp2 = maxWithSign_fx( BASOP_Util_Add_Mant32Exp( d, d_e, L_temp1, L_temp1_e, &L_temp2_e ) ); /* exp(L_temp2_e) */ - mu = BASOP_Util_Divide3232_Scale_newton( x_split, L_temp2, &mu_e ); /* exp(mu_e + (x-plit_e - L_temp2_e)) */ + mu = BASOP_Util_Divide3232_Scale_newton( x_split, L_temp2, &mu_e ); /* exp(mu_e + (x-plit_e - L_temp2_e)) */ mu_e = add( mu_e, sub( x_split_e, L_temp2_e ) ); mu = BASOP_Util_Add_Mant32Exp( mu, mu_e, L_negate( r ), r_e, &mu_e ); /* exp(mu_e) */ @@ -654,7 +654,7 @@ static void ApplyQRTransform_fx( L_temp1 = BASOP_Util_Add_Mant32Exp( x_ii, x_ii_e, x_kk, x_kk_e, &L_temp1_e ); /* exp(L_temp1_e) */ L_temp2 = BASOP_Util_Add_Mant32Exp( x_ii, x_ii_e, L_negate( x_kk ), x_kk_e, &L_temp2_e ); /* exp(L_temp2_e) */ d = BASOP_Util_Add_Mant32Exp( Mpy_32_32( L_temp1, L_temp2 ), add( L_temp1_e, L_temp2_e ), Mpy_32_32( r, mu ), add( r_e, mu_e ), &d_e ); /* exp(d_e) */ - d = BASOP_Util_Divide3232_Scale_newton( d, maxWithSign_fx( x_ii ), &temp_exp ); /* exp(temp_exp + (d_e - x_ii_e) */ + d = BASOP_Util_Divide3232_Scale_newton( d, maxWithSign_fx( x_ii ), &temp_exp ); /* exp(temp_exp + (d_e - x_ii_e) */ d_e = add( temp_exp, sub( d_e, x_ii_e ) ); /*QR transformation*/ -- GitLab From 198464b72b08fa9dc2a61cb660ca7c590159c723 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 14 Apr 2025 17:15:12 +0200 Subject: [PATCH 1012/1221] hardcode output of BASOP_Util_Divide3232_Scale_cadence() for fad_r calculation --- lib_enc/ivas_stereo_dmx_evs_fx.c | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 625ff8ee9..0afb69279 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2419,7 +2419,34 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_g = hStereoDmxEVS->hPHA->fad_g_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); +#if 1 + SWITCH( fad_len ) + { + case STEREO_DMX_EVS_FAD_LEN_16: + fad_r = 13338408; + move32(); + tmp_e = -6; + move16(); + BREAK; + case STEREO_DMX_EVS_FAD_LEN_32: + fad_r = 856317467; + move32(); + tmp_e = -7; + move16(); + BREAK; + case STEREO_DMX_EVS_FAD_LEN_48: + fad_r = 571471740; + move32(); + tmp_e = -7; + move16(); + BREAK; + default: + fad_r = BASOP_Util_Divide3232_Scale_newton( 1, add( fad_len, 1 ), &tmp_e ); + BREAK; + } +#else fad_r = BASOP_Util_Divide3232_Scale_cadence( 1, add( fad_len, 1 ), &tmp_e ); +#endif fad_r = L_shl_r( fad_r, tmp_e ); fad_len2 = shr( fad_len, 1 ); FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len2; ( n++, m-- ) ) @@ -2537,7 +2564,34 @@ ivas_error stereo_dmx_evs_init_encoder_fx( move16(); fad_g = hStereoDmxEVS->hPHA->fad_g_prc_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); +#if 1 + SWITCH( fad_len ) + { + case STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 16: + fad_r = 856317467; + move32(); + tmp_e = -7; + move16(); + BREAK; + case STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 32: + fad_r = 857653375; + move32(); + tmp_e = -8; + move16(); + BREAK; + case STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 48: + fad_r = 572066403; + move32(); + tmp_e = -8; + move16(); + BREAK; + default: + fad_r = BASOP_Util_Divide3232_Scale_cadence( 1, add( fad_len, 1 ), &tmp_e ); + BREAK; + } +#else fad_r = BASOP_Util_Divide3232_Scale_cadence( 1, add( fad_len, 1 ), &tmp_e ); +#endif fad_r = L_shl_r( fad_r, tmp_e ); fad_len2 = shr( fad_len, 1 ); FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len2; ( n++, m-- ) ) -- GitLab From eba16468ee36235c6df9c87e5f69ed7a6427ebb0 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 14 Apr 2025 17:23:10 +0200 Subject: [PATCH 1013/1221] fix wrong value, use correct division --- lib_enc/ivas_stereo_dmx_evs_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 0afb69279..042a2e541 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2423,7 +2423,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( SWITCH( fad_len ) { case STEREO_DMX_EVS_FAD_LEN_16: - fad_r = 13338408; + fad_r = 853658096; move32(); tmp_e = -6; move16(); @@ -2586,7 +2586,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( move16(); BREAK; default: - fad_r = BASOP_Util_Divide3232_Scale_cadence( 1, add( fad_len, 1 ), &tmp_e ); + fad_r = BASOP_Util_Divide3232_Scale_newton( 1, add( fad_len, 1 ), &tmp_e ); BREAK; } #else -- GitLab From 94b8dca70e8b364f4dc6e75852111d1876ff84f3 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 14 Apr 2025 11:53:43 +0200 Subject: [PATCH 1014/1221] supress output from all make cmds in non-biuld tests if build test is fine, we don't need this info here and all the printouts from make reall clutter the job log --- .gitlab-ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a3fa4217b..412f11044 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -171,7 +171,7 @@ stages: - git pull origin $FLOAT_REF_BRANCH - *activate-debug-mode-info-if-set - make clean - - make -j + - make -j >> /dev/null - mv ./IVAS_cod ./$REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_dec ./$REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_rend ./IVAS_rend_ref @@ -187,7 +187,7 @@ stages: - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - *activate-debug-mode-info-if-set - make clean - - make -j + - make -j >> /dev/null - mv ./IVAS_cod ./$MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_dec ./$MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_rend ./IVAS_rend_merge_target @@ -202,7 +202,7 @@ stages: ### build dut binaries - *activate-debug-mode-info-if-set - make clean - - make -j + - make -j >> /dev/null .build-and-create-float-ref-outputs: &build-and-create-float-ref-outputs - *build-float-ref-and-dut-binaries @@ -509,7 +509,7 @@ stages: - *build-float-ref-binaries - *build-merge-target-binaries - make clean - - make -j + - make -j >> /dev/null - *check-up-to-date-in-comparison-jobs - exit_code_target=0 @@ -660,7 +660,7 @@ stages: - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - make clean - - make -j + - make -j >> /dev/null # need to restore cache again - *overwrite-pytest-cache-with-artifact - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN $comp_args --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true @@ -759,7 +759,7 @@ stages: - make_args="$make_args IGNORELIST=1" - fi - make clean - - make -j $make_args + - make -j $make_args >> /dev/null - testcase_timeout_arg="--testcase_timeout $TESTCASE_TIMEOUT_LTV_SANITIZERS" # disable per-testcase timeout for msan to evaluate what is going on that it takes so long - if [[ $CLANG_NUM = 1 ]]; then @@ -1536,7 +1536,7 @@ coverage-test-on-main-scheduled: - *copy-ltv-files-to-testv-dir - *build-float-ref-binaries # Build DuT binaries with GCOV - - make clean + - make clean >> /dev/null - make GCOV=1 -j - cp IVAS_rend IVAS_rend_ref # Copy to ensure instrumented renderer is run in the first pytest call @@ -1594,7 +1594,7 @@ be-2-evs-26444: - *print-common-info - *update-scripts-repo - sed -i".bak" "s/\(#define EVS_FLOAT\)/\/\/\1/" lib_com/options.h - - make -j + - make -j >> /dev/null # copy over to never change the testvector dir - cp -r $EVS_BE_TEST_DIR_BASOP ./evs_be_test @@ -1658,7 +1658,7 @@ voip-be-on-merge-request: script: - *print-common-info - make clean - - make -j + - make -j >> /dev/null - python3 -m pytest tests/test_be_for_jbm_neutral_dly_profile.py -- GitLab From 279ddadeaa7cb7c303ee1330e0027430dcba809d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 14 Apr 2025 15:56:57 +0200 Subject: [PATCH 1015/1221] make the commit number files textfiles so one can view them in gitlab ui --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 412f11044..d3f7ba999 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,9 +48,9 @@ variables: FAILED_TESTCASES_LIST: "failed-testcases.txt" ERRORS_TESTCASES_LIST: "errors-testcases.txt" PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" - FLOAT_REF_COMMIT_FILE: "float-ref-git-sha" - CUT_COMMIT_FILE: "CuT-git-sha" - MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha" + FLOAT_REF_COMMIT_FILE: "float-ref-git-sha.txt" + CUT_COMMIT_FILE: "CuT-git-sha.txt" + MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha.txt" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' -- GitLab From 6ec556d214525169cfb3831444b80f3671384839 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Mon, 14 Apr 2025 22:35:36 +0530 Subject: [PATCH 1016/1221] Fix for 3GPP issue 1478: Encoder crash (assert) in ISM1, GSC encoder --- lib_com/gs_preech_fx.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index 3b3eaa777..48ec22a22 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -177,9 +177,10 @@ void pre_echo_att_ivas_fx( move16(); Word16 ratio_fx; Word16 attack_pos_fx, i; - Word32 L_tmp, L_tmp1; - Word16 tmp, n1, n2, exp, frac1, frac2; + Word32 L_tmp; + Word16 tmp, tmp_e; Word32 etmp1_fx; + Word16 etmp_e; Word16 att_len; test(); @@ -220,32 +221,19 @@ void pre_echo_att_ivas_fx( IF( GT_32( etmp_fx, *Last_frame_ener_fx ) && attack_pos_fx > 0 ) { /* Find the average energy before the attack */ - L_tmp = sum32_fx( finc_fx, attack_pos_fx ); /*Q1 */ - L_tmp1 = L_shr( L_mult( attack_pos_fx, attack_pos_fx ), 1 ); /*Q0 */ - tmp = round_fx( Isqrt( L_tmp1 ) ); /*Q15 */ - L_tmp = L_shr( L_tmp, 2 ); /*Q1 ; ATT_SEG_LEN=4 */ - etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ - - etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ - /* Find the correction factor and apply it before the attack */ - /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ - /* = isqrt(etmp/(*Last_frame_ener)) */ - etmp_fx = L_max( etmp_fx, 1 ); - *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); - move32(); - n1 = norm_l( etmp_fx ); - n2 = norm_l( *Last_frame_ener_fx ); - - n1 = sub( n1, 1 ); - exp = sub( n1, n2 ); - - frac1 = round_fx( L_shl( etmp_fx, n1 ) ); - frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); - L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ - L_tmp = L_shr( L_tmp, exp ); /* add exponent */ + etmp_fx = sum32_fx( finc_fx, attack_pos_fx ); + etmp_e = sub( 31, add( shl( Q_new, 1 ), 1 ) ); + etmp_fx = L_add( etmp_fx, L_shr( 21474836 /*0.01 in Q31*/, etmp_e ) ); /* etmp = etmp + 0.01; (exp = etmp_e) */ + etmp_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( etmp_fx, L_mult0( attack_pos_fx, ATT_SEG_LEN ), &tmp_e ) ); + tmp_e = add( tmp_e, sub( etmp_e, 31 ) ); + etmp_e = tmp_e; + move16(); - L_tmp = Isqrt( L_tmp ); - ratio_fx = round_fx( L_shl( L_tmp, 9 ) ); + /* Find the correction factor and apply it before the attack */ + tmp = BASOP_Util_Divide3232_Scale( *Last_frame_ener_fx, etmp_fx, &tmp_e ); /* numerator Q = 2 * Q_new + 1; denominator Q = 31 - tmp_e */ + tmp_e = add( tmp_e, sub( sub( 31, etmp_e ), add( shl( Q_new, 1 ), 1 ) ) ); /* tmp_e = tmp_e + (31 - tmp_e) - (2 * Q_new + 1) */ + tmp = Sqrt16( tmp, &tmp_e ); + ratio_fx = shr( tmp, sub( 2, tmp_e ) ); /* Q13 */ /* Pre-echo atttenuation should never increase the energy */ ratio_fx = s_min( ratio_fx, 8192 /* 1 in Q13 */ ); /* Q13 */ -- GitLab From 83a63d925cfc8a4c15e2321740580238f1249c01 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Mon, 14 Apr 2025 22:38:47 +0530 Subject: [PATCH 1017/1221] Fix for 3GPP issue 1455: ParamMC Encoder: Missing energy for BASOP in 10kHz region --- lib_enc/ivas_mc_param_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index d0316be0f..22eacdb32 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -2222,7 +2222,7 @@ static void ivas_param_mc_dec2bin_fx( /* convert value to bitstream, MSB first */ FOR( idx = 0; idx < N; idx++ ) { - bits[idx] = (UWord16) s_and( shr( val, sub( N, sub( 1, idx ) ) ), 1 ); + bits[idx] = (UWord16) s_and( shr( val, sub( sub( N, 1 ), idx ) ), 1 ); move16(); } -- GitLab From 2434c3f7e07b1fec6fb1d1ad8869102bb742728d Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 14 Apr 2025 21:53:22 +0200 Subject: [PATCH 1018/1221] lib_com: replace BASOP_Util_Divide3232_Scale_cadence by BASOP_Util_Divide3232_Scale_newton --- lib_com/ivas_dirac_com_fx.c | 2 +- lib_com/ivas_qspherical_com_fx.c | 6 +++--- lib_com/ivas_spar_com_fx.c | 4 ++-- lib_com/ivas_transient_det_fx.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_com/ivas_dirac_com_fx.c b/lib_com/ivas_dirac_com_fx.c index b16b94f1d..4279065b0 100644 --- a/lib_com/ivas_dirac_com_fx.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -1034,7 +1034,7 @@ void computeDiffuseness_fixed( exp1 = sub( 31, q_intensity_slow ); tmp = Sqrt32( p_tmp[i], &exp1 ); - tmp = BASOP_Util_Divide3232_Scale_cadence( tmp, L_add( energy_slow[i], EPSILLON_FX ), &exp2 ); + tmp = BASOP_Util_Divide3232_Scale_newton( tmp, L_add( energy_slow[i], EPSILLON_FX ), &exp2 ); q_tmp = add( sub( 31, exp2 ), sub( sub( 31, exp1 ), q_ene ) ); IF( LT_16( q_tmp, Q30 ) ) diff --git a/lib_com/ivas_qspherical_com_fx.c b/lib_com/ivas_qspherical_com_fx.c index 6661026a8..844c3ecde 100644 --- a/lib_com/ivas_qspherical_com_fx.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -314,9 +314,9 @@ Word16 quantize_phi_enc_fx( Word32 temp_res; Word16 temp_e; - delta_phi_fx = BASOP_Util_Divide3232_Scale_cadence( 360, n, &temp_e ); + delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( 360, n, &temp_e ); delta_phi_fx = L_shl( delta_phi_fx, sub( temp_e, 9 ) ); - inv_delta_phi_fx = BASOP_Util_Divide3232_Scale_cadence( n, 360, &temp_e ); + inv_delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( n, 360, &temp_e ); IF( EQ_16( n, 1 ) ) { @@ -661,7 +661,7 @@ Word16 quantize_phi_chan_compand_fx( /* quantize companded value */ // delta_phi = 360.0f / (float) n; - delta_phi = BASOP_Util_Divide3232_Scale_cadence( 360, n, &tmp_e ); + delta_phi = BASOP_Util_Divide3232_Scale_newton( 360, n, &tmp_e ); delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); // Q22 // id_phi = (int16_t) round_f( ( phi / (float) delta_phi ) ); id_phi = BASOP_Util_Divide3232_Scale( phi, delta_phi, &tmp_e ); // Q15 diff --git a/lib_com/ivas_spar_com_fx.c b/lib_com/ivas_spar_com_fx.c index 8aaeb7f63..c2ad11e26 100644 --- a/lib_com/ivas_spar_com_fx.c +++ b/lib_com/ivas_spar_com_fx.c @@ -985,7 +985,7 @@ static void ivas_get_pred_coeffs_enc_fx( move32(); dm_g_q[b] = Q29; move16(); - DM_F[b] = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); // Q=(31-(s_dm_f+2+num_f_e-den_f_e)) + DM_F[b] = BASOP_Util_Divide3232_Scale_newton( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); // Q=(31-(s_dm_f+2+num_f_e-den_f_e)) move32(); DM_F_q[b] = sub( 31, add( s_dm_f, sub( add( 2, num_f_e ), den_f_e ) ) ); move16(); @@ -1514,7 +1514,7 @@ static void ivas_get_pred_coeffs_fx( den_f = L_max( den_f, 1 ); // Q=31-den_f_e dm_g[b] = activew_quad_thresh; // Q29 move32(); - DM_F[b] = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); // s_dm_f+2+num_f_e-den_f_e + DM_F[b] = BASOP_Util_Divide3232_Scale_newton( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); // s_dm_f+2+num_f_e-den_f_e move32(); s_dm_f = add( s_dm_f, sub( add( 2, num_f_e ), den_f_e ) ); /*Resultant exp for DM_F s_dm_f +( 2 + num_f_e ) - den_f_e*/ div_shift = sub( s_dm_f, 1 ); diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index 3b9a8cfd7..fb8679ebc 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -353,7 +353,7 @@ static Word32 ivas_calc_duck_gain_fx( test(); IF( ( env_1 != 0 ) && ( env_2 != 0 ) ) { - L_tmp = BASOP_Util_Divide3232_Scale_cadence( env_1, env_2, &tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( env_1, env_2, &tmp_e ); L_tmp = L_shl( L_tmp, add( sub( env1_e, env2_e ), tmp_e ) ); duck_gain_out = Mpy_32_32( duck_mult_fac, L_tmp ); /*Q29*/ -- GitLab From faeaeb84596e0e13cb1a3037b228104730cda03c Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 14 Apr 2025 22:04:05 +0200 Subject: [PATCH 1019/1221] lib_enc: replace BASOP_Util_Divide3232_Scale_cadence() by BASOP_Util_Divide3232_Scale_newton() with exception of ivas_stereo_dmx_evs_fx.c --- lib_enc/find_tilt_fx.c | 2 +- lib_enc/hq_classifier_enc_fx.c | 2 +- lib_enc/ivas_enc_cov_handler_fx.c | 2 +- lib_enc/ivas_masa_enc_fx.c | 24 ++++---- lib_enc/ivas_mdct_core_enc_fx.c | 10 +-- lib_enc/ivas_qmetadata_enc_fx.c | 12 ++-- lib_enc/ivas_stereo_classifier_fx.c | 14 ++--- lib_enc/ivas_stereo_cng_enc_fx.c | 12 ++-- lib_enc/ivas_stereo_dft_enc_fx.c | 78 ++++++++++++------------ lib_enc/ivas_stereo_dft_enc_itd_fx.c | 50 +++++++-------- lib_enc/ivas_stereo_eclvq_enc_fx.c | 20 +++--- lib_enc/ivas_stereo_ica_enc_fx.c | 10 +-- lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 4 +- lib_enc/ivas_stereo_td_analysis_fx.c | 6 +- lib_enc/ivas_tcx_core_enc_fx.c | 2 +- lib_enc/speech_music_classif_fx.c | 4 +- lib_enc/tcx_utils_enc_fx.c | 2 +- lib_enc/transient_detection_fx.c | 6 +- 18 files changed, 130 insertions(+), 130 deletions(-) diff --git a/lib_enc/find_tilt_fx.c b/lib_enc/find_tilt_fx.c index ed8ff425e..dc78719d2 100644 --- a/lib_enc/find_tilt_fx.c +++ b/lib_enc/find_tilt_fx.c @@ -329,7 +329,7 @@ void find_tilt_ivas_fx( { hp_bckr = L_deposit_l( 1 ); } - Ltmp = BASOP_Util_Divide3232_Scale_cadence( lp_bckr, hp_bckr, &e_tmp ); + Ltmp = BASOP_Util_Divide3232_Scale_newton( lp_bckr, hp_bckr, &e_tmp ); Ltmp = Mpy_32_16_r( Ltmp, 3277 /* 0.1f in Q15 */ ); Ltmp = L_shr_sat( Ltmp, sub( 15, e_tmp ) ); *bckr_tilt_lt = L_add_sat( Mpy_32_16_r( *bckr_tilt_lt, 29491 /* 0.9f in Q15 */ ), Ltmp ); // Q16 diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 300e31e8e..d82eebfb5 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -143,7 +143,7 @@ static Word16 hf_spectrum_sparseness_fx( Word16 l_shift = W_norm( inv_rms_fx ); inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms - inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_cadence( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */ + inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_newton( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */ inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) ); // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB ); inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); /* Q31-inv_rms32_e */ diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index c05d59b90..138e1467d 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -271,7 +271,7 @@ static Word16 ivas_spar_get_activeW_flag_fx( } ELSE { - L_tmp = BASOP_Util_Divide3232_Scale_cadence( hCovEnc->bb_var_lt_fx[0], side_ch_var, &exp_diff ); // (Q31 - exp_diff) + L_tmp = BASOP_Util_Divide3232_Scale_newton( hCovEnc->bb_var_lt_fx[0], side_ch_var, &exp_diff ); // (Q31 - exp_diff) en_ratio = L_shl_sat( L_tmp, exp_diff ); // Q31 IF( LT_32( en_ratio, Mpy_32_32( IVAS_SPAR_DYN_ACTIVEW_THRESH_FX, IVAS_SPAR_DYN_ACTIVEW_THRESH_FX ) ) ) // LHS Q31 :: RHS Q31 { diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 2b9ffef15..5c5de97ab 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -1477,7 +1477,7 @@ static void combine_freqbands_and_subframes_fx( move16(); hMeta->directional_meta[i].energy_ratio_fx[j][k] = - BASOP_Util_Divide3232_Scale_cadence( vecLen, L_add( energySum, EPSILON_FX ), &exp_diff ); /*exp_diff+vecLen_e-energySum_e*/ + BASOP_Util_Divide3232_Scale_newton( vecLen, L_add( energySum, EPSILON_FX ), &exp_diff ); /*exp_diff+vecLen_e-energySum_e*/ move32(); exp_diff = add( exp_diff, sub( vecLen_e, energySum_e ) ); hMeta->directional_meta[i].energy_ratio_fx[j][k] = @@ -1585,7 +1585,7 @@ static void combine_freqbands_and_subframes_fx( { energyRatioSum = BASOP_Util_Add_Mant32Exp( energyRatioSum, energyRatioSum_e, Mpy_32_32( energy[j][k], hMeta->directional_meta[i].energy_ratio_fx[j][k] ), add( energy_e[j][k], 1 ), &energyRatioSum_e ); // 31-energyRatioSum_e } - energyRatioTemp = BASOP_Util_Divide3232_Scale_cadence( energyRatioSum, L_add( energySum, EPSILON_FX ), &exp_diff ); + energyRatioTemp = BASOP_Util_Divide3232_Scale_newton( energyRatioSum, L_add( energySum, EPSILON_FX ), &exp_diff ); exp_diff = add( exp_diff, sub( energyRatioSum_e, energySum_e ) ); energyRatioTemp = L_shl( energyRatioTemp, sub( exp_diff, 1 ) ); // Q30 @@ -2264,13 +2264,13 @@ static void compensate_energy_ratios_fx( FOR( dir = 0; dir < numDirs; dir++ ) { hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = - BASOP_Util_Divide3232_Scale_cadence( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum, &exp_diff ); + BASOP_Util_Divide3232_Scale_newton( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum, &exp_diff ); move32(); hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], sub( exp_diff, Q1 ) ); // Q30 move32(); } hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = - BASOP_Util_Divide3232_Scale_cadence( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum, &exp_diff ); + BASOP_Util_Divide3232_Scale_newton( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum, &exp_diff ); move32(); hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], sub( exp_diff, Q1 ) ); // Q30 move32(); @@ -2406,7 +2406,7 @@ static void reduce_metadata_further_fx( IF( hMasa->data.onset_detector_1_fx != 0 ) { - onset_filter = L_max( BASOP_Util_Divide3232_Scale_cadence( hMasa->data.onset_detector_2_fx, hMasa->data.onset_detector_1_fx, &onset_filter_e ), 0 ); + onset_filter = L_max( BASOP_Util_Divide3232_Scale_newton( hMasa->data.onset_detector_2_fx, hMasa->data.onset_detector_1_fx, &onset_filter_e ), 0 ); IF( BASOP_Util_Cmp_Mant32Exp( onset_filter, onset_filter_e, ONE_IN_Q31, 0 ) > 0 ) { @@ -2433,7 +2433,7 @@ static void reduce_metadata_further_fx( Word32 bandRatio; // threshold = totalEnergySum / ( MAX_PARAM_SPATIAL_SUBFRAMES * LOWBITRATE_NUM_BANDS ) * 0.5f; /* Average energy multiplied with energy ratio of 0.5f */ - threshold = BASOP_Util_Divide3232_Scale_cadence( totalEnergySum, ( MAX_PARAM_SPATIAL_SUBFRAMES * LOWBITRATE_NUM_BANDS ) * 2, &exp ); /* Average energy multiplied with energy ratio of 0.5f */ + threshold = BASOP_Util_Divide3232_Scale_newton( totalEnergySum, ( MAX_PARAM_SPATIAL_SUBFRAMES * LOWBITRATE_NUM_BANDS ) * 2, &exp ); /* Average energy multiplied with energy ratio of 0.5f */ exp = add( exp, sub( sub( 31, add( hMasa->data.q_energy, tmp2 ) ), 31 ) ); bandRatio = hqmetadata->q_direction[0].band_data[band].energy_ratio_fx[0]; // Q30 move32(); @@ -2468,7 +2468,7 @@ static void reduce_metadata_further_fx( } IF( totalEnergySum != 0 ) { - meanRatio = BASOP_Util_Divide3232_Scale_cadence( meanRatio, totalEnergySum, &exp ); + meanRatio = BASOP_Util_Divide3232_Scale_newton( meanRatio, totalEnergySum, &exp ); exp = add( add( exp, 1 ), tmp2 ); // 31 - (hMasa->data.q_energy - 1) - 31 - hMasa->data.q_energy - tmp2 => 1 + tmp2 } ELSE @@ -4730,7 +4730,7 @@ static void ivas_encode_masaism_metadata_fx( FOR( obj = 0; obj < nchan_ism; obj++ ) { - hOmasaData->energy_ratio_ism_fx[sf][0][obj] = BASOP_Util_Divide3232_Scale_cadence( energy_ism_ind[obj], energy_ism, &L_tmp_e ); + hOmasaData->energy_ratio_ism_fx[sf][0][obj] = BASOP_Util_Divide3232_Scale_newton( energy_ism_ind[obj], energy_ism, &L_tmp_e ); move32(); L_tmp_e = add( L_tmp_e, sub( energy_ism_ind_e[obj], energy_ism_e ) ); /* Scaling to Q30 */ @@ -4740,7 +4740,7 @@ static void ivas_encode_masaism_metadata_fx( L_tmp = BASOP_Util_Add_Mant32Exp( eneBand32, eneBand_exp, energy_ism, energy_ism_e, &L_tmp_e ); IF( L_tmp != 0 ) { - hOmasaData->masa_to_total_energy_ratio_fx[sf][0] = BASOP_Util_Divide3232_Scale_cadence( eneBand32, L_tmp, &tmp ); + hOmasaData->masa_to_total_energy_ratio_fx[sf][0] = BASOP_Util_Divide3232_Scale_newton( eneBand32, L_tmp, &tmp ); move32(); tmp = add( tmp, sub( eneBand_exp, L_tmp_e ) ); /* Scaling to Q30 */ @@ -4791,7 +4791,7 @@ static void ivas_encode_masaism_metadata_fx( { FOR( obj = 0; obj < nchan_ism; obj++ ) { - hOmasaData->energy_ratio_ism_fx[0][band][obj] = BASOP_Util_Divide3232_Scale_cadence( energy_ism_ind[obj], energy_ism, &L_tmp_e ); + hOmasaData->energy_ratio_ism_fx[0][band][obj] = BASOP_Util_Divide3232_Scale_newton( energy_ism_ind[obj], energy_ism, &L_tmp_e ); move32(); L_tmp_e = add( L_tmp_e, sub( energy_ism_ind_e[obj], energy_ism_e ) ); /* Scaling to Q30 */ @@ -4819,7 +4819,7 @@ static void ivas_encode_masaism_metadata_fx( L_tmp = BASOP_Util_Add_Mant32Exp( eneBand32, eneBand_exp, energy_ism, energy_ism_e, &L_tmp_e ); IF( L_tmp != 0 ) { - hOmasaData->masa_to_total_energy_ratio_fx[0][band] = BASOP_Util_Divide3232_Scale_cadence( eneBand32, L_tmp, &tmp ); + hOmasaData->masa_to_total_energy_ratio_fx[0][band] = BASOP_Util_Divide3232_Scale_newton( eneBand32, L_tmp, &tmp ); move32(); tmp = add( tmp, sub( eneBand_exp, L_tmp_e ) ); /* Scaling to Q30 */ @@ -4876,7 +4876,7 @@ static void ivas_encode_masaism_metadata_fx( L_tmp = BASOP_Util_Add_Mant32Exp( eneBand32, eneBand_exp, hOmasaData->energy_ism_fx[sf][band], hOmasaData->energy_ism_fx_e[sf][band], &L_tmp_e ); IF( L_tmp != 0 ) { - hOmasaData->masa_to_total_energy_ratio_fx[sf][band] = BASOP_Util_Divide3232_Scale_cadence( eneBand32, L_tmp, &tmp ); + hOmasaData->masa_to_total_energy_ratio_fx[sf][band] = BASOP_Util_Divide3232_Scale_newton( eneBand32, L_tmp, &tmp ); move32(); tmp = add( tmp, sub( eneBand_exp, L_tmp_e ) ); /* Scaling to Q30 */ diff --git a/lib_enc/ivas_mdct_core_enc_fx.c b/lib_enc/ivas_mdct_core_enc_fx.c index e744c7f47..401e1360d 100644 --- a/lib_enc/ivas_mdct_core_enc_fx.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -233,7 +233,7 @@ static Word16 kernel_switch_detect_fx( L_tmp1 = Sqrt32( L_tmp1, &exp_tmp1 ); L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, L_tmp1, exp_tmp1, &exp_tmp ); L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, ONE_IN_Q30, 1, &exp_tmp ); - cov00 = BASOP_Util_Divide3232_Scale_cadence( cov00, L_tmp, &exp_tmp1 ); + cov00 = BASOP_Util_Divide3232_Scale_newton( cov00, L_tmp, &exp_tmp1 ); exp_tmp = add( exp_tmp1, sub( sub( Q31, q_com ), exp_tmp ) ); /* Added saturation to handle overflows when value is very close to 1.f */ cov00 = L_shl_sat( cov00, exp_tmp ); // Q31 @@ -247,7 +247,7 @@ static Word16 kernel_switch_detect_fx( L_tmp1 = Sqrt32( L_tmp1, &exp_tmp1 ); L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, L_tmp1, exp_tmp1, &exp_tmp ); L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, ONE_IN_Q30, 1, &exp_tmp ); - cov90 = BASOP_Util_Divide3232_Scale_cadence( cov90, L_tmp, &exp_tmp1 ); + cov90 = BASOP_Util_Divide3232_Scale_newton( cov90, L_tmp, &exp_tmp1 ); exp_tmp = add( exp_tmp1, sub( sub( Q31, q_com ), exp_tmp ) ); /* Added saturation to handle overflows when value is very close to 1.f */ cov90 = L_shl_sat( cov90, exp_tmp ); // Q31 @@ -735,7 +735,7 @@ static void applyStereoPreProcessingCplx( d_q = sub( 31, d_q ); deno = L_max( L_shl_sat( 1, d_q ), d_fx ); - sq_imp = BASOP_Util_Divide3232_Scale_cadence( n_fx, deno, &exp ); + sq_imp = BASOP_Util_Divide3232_Scale_newton( n_fx, deno, &exp ); exp = add( exp, sub( d_q, n_q ) ); d_fx = Sqrt32( sq_imp, &exp ); *mdctSample1_fx = Mpy_32_32( dmxR1_fx, d_fx ); @@ -764,7 +764,7 @@ static void applyStereoPreProcessingCplx( d_q = sub( 31, d_q ); deno = L_max( L_shl_sat( 1, d_q ), d_fx ); - sq_imp = BASOP_Util_Divide3232_Scale_cadence( n_fx, deno, &exp ); + sq_imp = BASOP_Util_Divide3232_Scale_newton( n_fx, deno, &exp ); exp = add( exp, sub( d_q, n_q ) ); d_fx = Sqrt32( sq_imp, &exp ); *mdctSample2_fx = Mpy_32_32( dmxR2_fx, d_fx ); @@ -956,7 +956,7 @@ static UWord16 enc_ste_pre_mdct( ELSE { Word16 exp1; - corr_fx = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_32( corr_fx, corr_fx ), Mpy_32_32( sumL_fx, sumR_fx ), &exp1 ); + corr_fx = BASOP_Util_Divide3232_Scale_newton( Mpy_32_32( corr_fx, corr_fx ), Mpy_32_32( sumL_fx, sumR_fx ), &exp1 ); corr_e = add( exp1, sub( shl( corr_e, 1 ), add( sumL_e, sumR_e ) ) ); } test(); diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 10380f422..79a4adee7 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -1332,12 +1332,12 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( ratioSum = L_add( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] ); IF( GT_32( ratioSum, ONE_IN_Q30 /*1.0f*/ ) ) { - hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_cadence( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], ratioSum, &div_e ); + hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], ratioSum, &div_e ); hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k], sub( div_e, 1 ) ); move32(); move32(); - hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_cadence( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], ratioSum, &div_e ); + hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], ratioSum, &div_e ); hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], sub( div_e, 1 ) ); move32(); move32(); @@ -1385,12 +1385,12 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( IF( GT_32( ratioSum, ONE_IN_Q30 /*1.0f*/ ) ) { - hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_cadence( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], ratioSum, &div_e ); + hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], ratioSum, &div_e ); hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], sub( div_e, 1 ) ); move32(); move32(); - hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_cadence( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], ratioSum, &div_e ); + hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = BASOP_Util_Divide3232_Scale_newton( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], ratioSum, &div_e ); hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = L_shl( hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k], sub( div_e, 1 ) ); move32(); move32(); @@ -6619,7 +6619,7 @@ void ivas_omasa_encode_masa_to_total_fx( { j = imult1616( k, len_stream ); /* quantize with fixed common step */ - L_tmp = BASOP_Util_Divide3232_Scale_cadence( dct_data[j], step, &tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( dct_data[j], step, &tmp_e ); tmp_e = add( tmp_e, Q6 ); q_idx[j] = rint_new_fx( L_shr( L_tmp, sub( 15, tmp_e ) ) /* Q16 */ ); // Q0 move16(); @@ -6642,7 +6642,7 @@ void ivas_omasa_encode_masa_to_total_fx( { FOR( i = 1; i < len_stream; i++ ) { - L_tmp = BASOP_Util_Divide3232_Scale_cadence( dct_data[j + i], step, &tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( dct_data[j + i], step, &tmp_e ); tmp_e = add( tmp_e, Q6 ); q_idx[j + i] = rint_new_fx( L_shr( L_tmp, sub( 15, tmp_e ) ) ); move16(); diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 3e69a0ca6..3a040517a 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -890,7 +890,7 @@ void unclr_classifier_td_fx( move16(); /* mean & std removal */ - fvn = BASOP_Util_Divide3232_Scale_cadence( L_sub( hStereoClassif->unclr_fv_fx[ind], unclr_mean_td[i] ), unclr_scale_td[i], &exp ); + fvn = BASOP_Util_Divide3232_Scale_newton( L_sub( hStereoClassif->unclr_fv_fx[ind], unclr_mean_td[i] ), unclr_scale_td[i], &exp ); fvn = Mpy_32_32( fvn, unclr_coef_td[i] ); // Q = 31-exp+15-31 = 15-exp exp = add( exp, 16 ); // exp = 31-(15-exp) = 16+exp @@ -1016,7 +1016,7 @@ void unclr_classifier_dft_fx( /* mean & std removal */ // fvn[i] = (hStereoClassif->unclr_fv[ind] - unclr_mean_dft[i]) / unclr_scale_dft[i]; - fvn[i] = BASOP_Util_Divide3232_Scale_cadence( L_sub( hStereoClassif->unclr_fv_fx[ind], unclr_mean_dft_Q15[i] ), unclr_scale_dft_Q15[i], &fvn_e[i] ); + fvn[i] = BASOP_Util_Divide3232_Scale_newton( L_sub( hStereoClassif->unclr_fv_fx[ind], unclr_mean_dft_Q15[i] ), unclr_scale_dft_Q15[i], &fvn_e[i] ); move32(); /* LR */ @@ -1157,7 +1157,7 @@ void xtalk_classifier_td_fx( move16(); /* mean & std removal */ - fvn = BASOP_Util_Divide3232_Scale_cadence( L_sub( hStereoClassif->xtalk_fv_fx[ind], xtalk_mean_td[i] ), xtalk_scale_td[i], &exp ); + fvn = BASOP_Util_Divide3232_Scale_newton( L_sub( hStereoClassif->xtalk_fv_fx[ind], xtalk_mean_td[i] ), xtalk_scale_td[i], &exp ); fvn = Mpy_32_32( fvn, xtalk_coef_td[i] ); // Q = 31-exp+15-31 = 15-exp exp = add( exp, 16 ); // exp = 31-(15-exp) = 16+exp @@ -1372,7 +1372,7 @@ void xtalk_classifier_dft_fx( // ratio_m1_m2 = fabsf( m1 * m2 ) / fabsf( m1 + m2 + 1.0f ); Word16 exp; - ratio_m1_m2 = BASOP_Util_Divide3232_Scale_cadence( L_abs( Mpy_32_32( m1, m2 ) ), L_abs( L_add( L_add( L_shr( m1, 2 ), L_shr( m2, 2 ) ), ONE_IN_Q29 ) ), &exp ); + ratio_m1_m2 = BASOP_Util_Divide3232_Scale_newton( L_abs( Mpy_32_32( m1, m2 ) ), L_abs( L_add( L_add( L_shr( m1, 2 ), L_shr( m2, 2 ) ), ONE_IN_Q29 ) ), &exp ); exp = sub( exp, 2 ); // m2_m2 = hItd->prev_m2 * m2; m2_m2 = Mpy_32_32( hItd->prev_m2_fx, m2 ); @@ -1406,7 +1406,7 @@ void xtalk_classifier_dft_fx( /* mean & std removal */ // fvn[i] = ( hStereoClassif->xtalk_fv[ind] - xtalk_mean_dft[i] ) / xtalk_scale_dft[i]; - fvn[i] = BASOP_Util_Divide3232_Scale_cadence( L_sub( hStereoClassif->xtalk_fv_fx[ind], xtalk_mean_dft_q15[i] ), xtalk_scale_dft_q15[i], &exp ); // Q15 + fvn[i] = BASOP_Util_Divide3232_Scale_newton( L_sub( hStereoClassif->xtalk_fv_fx[ind], xtalk_mean_dft_q15[i] ), xtalk_scale_dft_q15[i], &exp ); // Q15 move32(); fvn[i] = L_shl_sat( fvn[i], sub( exp, 2 ) ); // Q29 move32(); @@ -1755,7 +1755,7 @@ static Word32 redge_detect_fx( { // edge_slope = ( inp_max - inp_min ) / i; L_temp = BASOP_Util_Add_Mant32Exp( inp_max, 0, L_negate( inp_min ), 0, &L_temp_e ); - edge_slope = BASOP_Util_Divide3232_Scale_cadence( L_temp, i, &edge_slope_e ); + edge_slope = BASOP_Util_Divide3232_Scale_newton( L_temp, i, &edge_slope_e ); edge_slope_e = add( edge_slope_e, sub( L_temp_e, 31 ) ); edge[i] = err0; move32(); @@ -1788,7 +1788,7 @@ static Word32 redge_detect_fx( } // edge[i] /= i + 1; - edge[i] = BASOP_Util_Divide3232_Scale_cadence( edge[i], add( i, 1 ), &L_temp_e ); + edge[i] = BASOP_Util_Divide3232_Scale_newton( edge[i], add( i, 1 ), &L_temp_e ); move32(); edge_e[i] = add( L_temp_e, sub( edge_e[i], 31 ) ); move16(); diff --git a/lib_enc/ivas_stereo_cng_enc_fx.c b/lib_enc/ivas_stereo_cng_enc_fx.c index aa7c2d0aa..b73a57f46 100644 --- a/lib_enc/ivas_stereo_cng_enc_fx.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -101,7 +101,7 @@ void stereo_dft_enc_sid_calc_coh_fx( L_tmp1_e = sub( add( hStereoDft->Spd_L_smooth_fx_e, hStereoDft->Spd_R_smooth_fx_e ), W_tmp_q ); L_tmp2 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k], hStereoDft->xspec_smooth_fx[2 * k] ), shl( hStereoDft->xspec_smooth_fx_e[2 * k], 1 ), Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k + 1], hStereoDft->xspec_smooth_fx[2 * k + 1] ), shl( hStereoDft->xspec_smooth_fx_e[2 * k + 1], 1 ), &L_tmp2_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); - L_tmp3 = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp3_e ); + L_tmp3 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp3_e ); L_tmp3_e = add( L_tmp3_e, sub( L_tmp1_e, L_tmp2_e ) ); L_tmp3 = Mpy_32_32( prev_cohBand[b], L_tmp3 ); xspec_scale = Sqrt32( L_tmp3, &L_tmp3_e ); @@ -137,7 +137,7 @@ void stereo_dft_enc_sid_calc_coh_fx( L_tmp2 = W_extract_h( W_shl( W_tmp, W_tmp_q ) ); L_tmp2_e = sub( add( hStereoDft->Spd_L_smooth_fx_e, hStereoDft->Spd_R_smooth_fx_e ), W_tmp_q ); L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); - L_tmp3 = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp3_e ); + L_tmp3 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp3_e ); L_tmp3_e = add( L_tmp3_e, sub( L_tmp1_e, L_tmp2_e ) ); L_tmp3 = Mpy_32_32( coh_weight, L_tmp3 ); L_tmp3_e = add( coh_weight_e, L_tmp3_e ); @@ -150,7 +150,7 @@ void stereo_dft_enc_sid_calc_coh_fx( IF( coh_weight_sum > 0 ) { // cohBand[b] = cohBand[b] / coh_weight_sum; - cohBand[b] = BASOP_Util_Divide3232_Scale_cadence( cohBand[b], coh_weight_sum, &L_tmp1_e ); + cohBand[b] = BASOP_Util_Divide3232_Scale_newton( cohBand[b], coh_weight_sum, &L_tmp1_e ); move32(); cohBand_e[b] = add( L_tmp1_e, sub( cohBand_e[b], coh_weight_sum_e ) ); move16(); @@ -510,7 +510,7 @@ void stereo_dft_cng_side_gain_fx( hStereoCng->prev_sg_average_fx[b] = hStereoCng->sg_average_fx[b]; move32(); // hStereoCng->sg_average[b] = hStereoCng->sg_average[b] / (float) hStereoCng->sg_average_counter; - hStereoCng->sg_average_fx[b] = BASOP_Util_Divide3232_Scale_cadence( hStereoCng->sg_average_fx[b], hStereoCng->sg_average_counter, &tmp_e ); + hStereoCng->sg_average_fx[b] = BASOP_Util_Divide3232_Scale_newton( hStereoCng->sg_average_fx[b], hStereoCng->sg_average_counter, &tmp_e ); move32(); tmp_e = sub( tmp_e, 31 - 5 ); hStereoCng->sg_average_fx[b] = L_shl_r( hStereoCng->sg_average_fx[b], sub( tmp_e, 5 ) ); // Q31 @@ -535,7 +535,7 @@ void stereo_dft_cng_side_gain_fx( tmp = hStereoCng->sg_average_fx[b]; move32(); // hStereoCng->sg_average[b] = ( hStereoCng->sg_average[b] + prev_weight * hStereoCng->prev_sg_average[b] ) / ( (float) hStereoCng->sg_average_counter + prev_weight * (float) hStereoCng->prev_sg_average_counter ); - hStereoCng->sg_average_fx[b] = BASOP_Util_Divide3232_Scale_cadence( L_add( hStereoCng->sg_average_fx[b], Mpy_32_16_1( hStereoCng->prev_sg_average_fx[b], prev_weight ) ), L_add( L_shl( hStereoCng->sg_average_counter, Q15 ), L_mult0( prev_weight, hStereoCng->prev_sg_average_counter ) ), &tmp_e ); + hStereoCng->sg_average_fx[b] = BASOP_Util_Divide3232_Scale_newton( L_add( hStereoCng->sg_average_fx[b], Mpy_32_16_1( hStereoCng->prev_sg_average_fx[b], prev_weight ) ), L_add( L_shl( hStereoCng->sg_average_counter, Q15 ), L_mult0( prev_weight, hStereoCng->prev_sg_average_counter ) ), &tmp_e ); move32(); tmp_e = sub( tmp_e, 16 - 5 ); hStereoCng->sg_average_fx[b] = L_shl_r( hStereoCng->sg_average_fx[b], sub( tmp_e, 5 ) ); // Q26 @@ -571,7 +571,7 @@ void stereo_dft_cng_side_gain_fx( W_tmp_q = W_norm( W_tmp ); hStereoDft->sidSideGain_fx[b] = W_extract_h( W_shl( W_tmp, W_tmp_q ) ); move32(); - hStereoDft->sidSideGain_fx[b] = BASOP_Util_Divide3232_Scale_cadence( hStereoDft->sidSideGain_fx[b], sgSum, &tmp_e ); + hStereoDft->sidSideGain_fx[b] = BASOP_Util_Divide3232_Scale_newton( hStereoDft->sidSideGain_fx[b], sgSum, &tmp_e ); move32(); tmp_e = sub( tmp_e, W_tmp_q ); hStereoDft->sidSideGain_fx[b] = L_shl_sat( hStereoDft->sidSideGain_fx[b], tmp_e ); // Q31: saturation is fine since stereo_dft_quantize_res_gains_fx limits value to 1.0 diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 01318af28..6406158b4 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -880,7 +880,7 @@ void stereo_dft_enc_update_fx( // hStereoDft->res_cod_line_max = (int16_t) ( 0.5f + ( hStereoDft->band_limits[hStereoDft->res_cod_band_max] - 1 ) * 2.f * hStereoDft->N / (float) ( hStereoDft->NFFT ) ); Word32 tmp = L_shl( L_mult0( sub( hStereoDft->band_limits[hStereoDft->res_cod_band_max], 1 ), hStereoDft->N ), 1 ); Word16 exp; - tmp = BASOP_Util_Divide3232_Scale_cadence( tmp, hStereoDft->NFFT, &exp ); + tmp = BASOP_Util_Divide3232_Scale_newton( tmp, hStereoDft->NFFT, &exp ); hStereoDft->res_cod_line_max = extract_l( L_shr( tmp, sub( 31, exp ) ) ); move16(); // hStereoDft->res_cod_line_max = 8 * (hStereoDft->res_cod_line_max / 8); @@ -1226,7 +1226,7 @@ Word32 stereo_dft_enc_synthesize_fx( zp = STEREO_DFT_ZP_12k8_ENC; move16(); // fac = (float) ( NFFT ) / (float) ( hStereoDft->NFFT ); - fac_fx = BASOP_Util_Divide3232_Scale_cadence( NFFT, hStereoDft->NFFT, &temp_exp ); + fac_fx = BASOP_Util_Divide3232_Scale_newton( NFFT, hStereoDft->NFFT, &temp_exp ); fac_fx = L_shl( fac_fx, temp_exp ); ovl = STEREO_DFT_OVL_12k8; move16(); @@ -1250,7 +1250,7 @@ Word32 stereo_dft_enc_synthesize_fx( zp = STEREO_DFT_ZP_16k_ENC; move16(); // fac = (float) ( NFFT ) / (float) ( hStereoDft->NFFT ); - fac_fx = BASOP_Util_Divide3232_Scale_cadence( NFFT, hStereoDft->NFFT, &temp_exp ); + fac_fx = BASOP_Util_Divide3232_Scale_newton( NFFT, hStereoDft->NFFT, &temp_exp ); fac_fx = L_shl( fac_fx, temp_exp ); ovl = STEREO_DFT_OVL_16k; move16(); @@ -1283,7 +1283,7 @@ Word32 stereo_dft_enc_synthesize_fx( zp = STEREO_DFT_ZP_32k_ENC; move16(); // fac = (float) ( NFFT ) / (float) ( hStereoDft->NFFT ); - fac_fx = BASOP_Util_Divide3232_Scale_cadence( NFFT, hStereoDft->NFFT, &temp_exp ); + fac_fx = BASOP_Util_Divide3232_Scale_newton( NFFT, hStereoDft->NFFT, &temp_exp ); fac_fx = L_shl( fac_fx, temp_exp ); ovl = STEREO_DFT_OVL_32k; move16(); @@ -1307,7 +1307,7 @@ Word32 stereo_dft_enc_synthesize_fx( zp = STEREO_DFT_ZP_8k_ENC; move16(); // fac = (float) ( NFFT ) / (float) ( hStereoDft->NFFT ); - fac_fx = BASOP_Util_Divide3232_Scale_cadence( NFFT, hStereoDft->NFFT, &temp_exp ); + fac_fx = BASOP_Util_Divide3232_Scale_newton( NFFT, hStereoDft->NFFT, &temp_exp ); fac_fx = L_shl( fac_fx, temp_exp ); ovl = STEREO_DFT_OVL_8k; move16(); @@ -1511,7 +1511,7 @@ Word32 stereo_dft_enc_synthesize_fx( move32(); // output[offset + N + i] = ( tmp[zp + N + i] - ifft_deviation ) / win_ana[ovl - 1 - i] + ifft_deviation; Word16 L_temp_e; - Word32 L_temp = BASOP_Util_Divide3232_Scale_cadence( L_sub_sat( tmp_fx[zp + N + i], ifft_deviation ), L_deposit_h( win_ana_fx[ovl - 1 - i] ), &L_temp_e ); + Word32 L_temp = BASOP_Util_Divide3232_Scale_newton( L_sub_sat( tmp_fx[zp + N + i], ifft_deviation ), L_deposit_h( win_ana_fx[ovl - 1 - i] ), &L_temp_e ); L_temp = L_shl_sat( L_temp, L_temp_e ); output_fx[offset + N + i] = L_add_sat( L_temp, ifft_deviation ); // Q15 move32(); @@ -1733,7 +1733,7 @@ void stereo_dft_enc_process_fx( } // if ( fabsf( hStereoDft->hItd->deltaItd[k_offset] * 32000.f / input_Fs ) > 80.0f ) - tmp_32fx = L_abs( BASOP_Util_Divide3232_Scale_cadence( hStereoDft->hItd->deltaItd_fx[k_offset], input_Fs, &tmp_e ) ); + tmp_32fx = L_abs( BASOP_Util_Divide3232_Scale_newton( hStereoDft->hItd->deltaItd_fx[k_offset], input_Fs, &tmp_e ) ); tmp_e = add( tmp_e, 15 - 31 ); IF( BASOP_Util_Cmp_Mant32Exp( tmp_32fx, tmp_e, 5368709 /* 80.0f / 32000.f in Q31 */, 0 ) > 0 ) { @@ -2026,13 +2026,13 @@ void stereo_dft_enc_process_fx( // wR = sqrtf( 0.5f * ( comb_nrgL + comb_nrgR ) + frac_dot_prod ) / sum_abs; L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, sub( L_tmp1_e, 1 ), frac_dot_prod, frac_dot_prod_e, &L_tmp1_e ); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); - wR = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_abs, &wR_e ); + wR = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_abs, &wR_e ); wR_e = add( wR_e, sub( L_tmp1_e, sum_abs_e ) ); // wL = wR + sqrtf( 2.f ) * ( 1.f - ( sqrtf( Sr + Si ) / sum_abs ) ); L_tmp1 = BASOP_Util_Add_Mant32Exp( Sr, Sr_e, Si, Si_e, &L_tmp1_e ); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); - L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_abs, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_abs, &L_tmp2_e ); L_tmp2_e = add( L_tmp2_e, sub( L_tmp1_e, sum_abs_e ) ); L_tmp2 = L_shl_sat( L_tmp2, L_tmp2_e ); // Q31 saturation expected L_tmp1 = L_sub( MAX_32, L_tmp2 ); // Q31 @@ -2111,13 +2111,13 @@ void stereo_dft_enc_process_fx( // wR = sqrtf( 0.5f * ( comb_nrgL + comb_nrgR ) + frac_dot_prod ) / sum_abs; L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, sub( L_tmp1_e, 1 ), frac_dot_prod, frac_dot_prod_e, &L_tmp1_e ); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); - wR = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_abs, &wR_e ); + wR = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_abs, &wR_e ); wR_e = add( wR_e, sub( L_tmp1_e, sum_abs_e ) ); // wL = wR + sqrtf( 2.f ) * ( 1.f - ( sqrtf( Sr + Si ) / sum_abs ) ); L_tmp1 = BASOP_Util_Add_Mant32Exp( Sr, Sr_e, Si, Si_e, &L_tmp1_e ); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); - L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_abs, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_abs, &L_tmp2_e ); L_tmp2_e = add( L_tmp2_e, sub( L_tmp1_e, sum_abs_e ) ); L_tmp2 = L_shl_sat( L_tmp2, L_tmp2_e ); // Q31 saturation expected L_tmp1 = L_sub( MAX_32, L_tmp2 ); // Q31 @@ -2191,7 +2191,7 @@ void stereo_dft_enc_process_fx( // wR = sqrtf( 0.5f * ( sum_nrg_L2 + sum_nrg_R2 ) + dot_prod_nrg_ratio[b] ) / sum_abs; L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp3, sub( L_tmp3_e, 1 ), dot_prod_nrg_ratio_fx[b], dot_prod_nrg_ratio_fx_e[b], &L_tmp1_e ); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); - wR = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_abs, &wR_e ); + wR = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_abs, &wR_e ); wR_e = add( wR_e, sub( L_tmp1_e, sum_abs_e ) ); // wL = wR + sqrtf( 2.f ) * ( 1.f - sqrtf( sum_nrg_Mid ) / sum_abs ); @@ -2200,7 +2200,7 @@ void stereo_dft_enc_process_fx( L_tmp1_e = sum_nrg_Mid_e; move16(); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); - L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_abs, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_abs, &L_tmp2_e ); L_tmp2_e = add( L_tmp2_e, sub( L_tmp1_e, sum_abs_e ) ); L_tmp2 = L_shl_sat( L_tmp2, L_tmp2_e ); // Q31 saturation expected L_tmp1 = L_sub( MAX_32, L_tmp2 ); // Q31 @@ -2478,7 +2478,7 @@ static void stereo_dft_enc_get_res_cod_mode_flag_fx( L_tmp1 = L_sub( MAX_32, g ); // Q31 L_tmp2 = BASOP_Util_Add_Mant32Exp( hStereoDft->res_cod_NRG_S_fx[b], hStereoDft->res_cod_NRG_S_fx_e[b], Mpy_32_32( Mpy_32_32( L_tmp1, L_tmp1 ), hStereoDft->res_cod_NRG_M_fx[b] ), hStereoDft->res_cod_NRG_M_fx_e[b], &L_tmp2_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, MAX_32, 0, &L_tmp2_e ); - L_tmp1 = BASOP_Util_Divide3232_Scale_cadence( hStereoDft->res_cod_NRG_S_fx[b], L_tmp2, &L_tmp1_e ); + L_tmp1 = BASOP_Util_Divide3232_Scale_newton( hStereoDft->res_cod_NRG_S_fx[b], L_tmp2, &L_tmp1_e ); L_tmp1_e = add( L_tmp1_e, sub( hStereoDft->res_cod_NRG_S_fx_e[b], L_tmp2_e ) ); L_tmp1 = L_shl( L_tmp1, L_tmp1_e ); // Q31 *res_dmx_ratio = L_max( L_tmp1, *res_dmx_ratio ); @@ -2494,7 +2494,7 @@ static void stereo_dft_enc_get_res_cod_mode_flag_fx( /*Calculate the energy ratio of the inter-frame */ //*frame_nrg_ratio = dmx_res_all / hStereoDft->dmx_res_all_prev; - *frame_nrg_ratio = BASOP_Util_Divide3232_Scale_cadence( dmx_res_all, hStereoDft->dmx_res_all_prev_fx, &L_tmp1_e ); + *frame_nrg_ratio = BASOP_Util_Divide3232_Scale_newton( dmx_res_all, hStereoDft->dmx_res_all_prev_fx, &L_tmp1_e ); move32(); L_tmp1_e = add( L_tmp1_e, sub( dmx_res_all_e, hStereoDft->dmx_res_all_prev_fx_e ) ); *frame_nrg_ratio = L_shr_r_sat( *frame_nrg_ratio, sub( 3, L_tmp1_e ) ); // Q28 @@ -2741,7 +2741,7 @@ void stereo_dft_enc_res_fx( L_tmp2_e = hStereoDft->res_cod_NRG_M_fx_e[b]; L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, hStereoDft->res_cod_NRG_S_fx[b], hStereoDft->res_cod_NRG_S_fx_e[b], &L_tmp2_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, MAX_32, 0, &L_tmp2_e ); - in_phase_ratio = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &in_phase_ratio_e ); + in_phase_ratio = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &in_phase_ratio_e ); in_phase_ratio_e = add( in_phase_ratio_e, sub( hStereoDft->res_cod_NRG_M_fx_e[b], L_tmp2_e ) ); in_phase_ratio = L_shl_sat( in_phase_ratio, in_phase_ratio_e ); // Q31 : bound from 0.0 to 1.0 in_phase_ratio = L_max( 0, in_phase_ratio ); @@ -3512,7 +3512,7 @@ static void stereo_dft_enc_compute_prm_fx( W_shift = W_norm( W_tmp ); L_tmp2 = W_extract_h( W_shl( W_tmp, W_shift ) ); L_tmp2_e = sub( add( sub_nrg_DMX2_e, 31 ), W_shift ); - L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); L_tmp = L_shl( L_tmp, L_tmp_e ); // Q31hStereoDft->gainIPD_sm_fx = L_add( L_shr( hStereoDft->gainIPD_sm_fx, 1 ), L_ gain_IPD = L_add_sat( gain_IPD, L_tmp ); // Q31: saturation expected @@ -3597,7 +3597,7 @@ static void stereo_dft_enc_compute_prm_fx( // dot_prod_nrg_ratio[b2] = sum_past_dot_prod_abs2 / ( sum_past_nrgL2 + sum_past_nrgR2 + EPSILON ); L_tmp2 = BASOP_Util_Add_Mant32Exp( sum_past_nrgL2, sum_past_nrgL2_e, sum_past_nrgR2, sum_past_nrgR2_e, &L_tmp2_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); - dot_prod_nrg_ratio_fx[b2] = BASOP_Util_Divide3232_Scale_cadence( sum_past_dot_prod_abs2, L_tmp2, &L_tmp_e ); + dot_prod_nrg_ratio_fx[b2] = BASOP_Util_Divide3232_Scale_newton( sum_past_dot_prod_abs2, L_tmp2, &L_tmp_e ); move32(); L_tmp_e = add( L_tmp_e, sub( sum_past_dot_prod_abs2_e, L_tmp2_e ) ); dot_prod_nrg_ratio_fx[b2] = L_shl( dot_prod_nrg_ratio_fx[b2], L_tmp_e ); // Q31 @@ -3624,7 +3624,7 @@ static void stereo_dft_enc_compute_prm_fx( // dot_prod_nrg_ratio[b2] /= ( sum_nrg_L2 + sum_nrg_R2 + EPSILON ); L_tmp2 = BASOP_Util_Add_Mant32Exp( sum_nrg_L2, sum_nrg_L2_e, sum_nrg_R2, sum_nrg_R2_e, &L_tmp2_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); - dot_prod_nrg_ratio_fx[b2] = BASOP_Util_Divide3232_Scale_cadence( dot_prod_nrg_ratio_fx[b2], L_tmp2, &L_tmp_e ); + dot_prod_nrg_ratio_fx[b2] = BASOP_Util_Divide3232_Scale_newton( dot_prod_nrg_ratio_fx[b2], L_tmp2, &L_tmp_e ); move32(); L_tmp_e = add( L_tmp_e, sub( dot_prod_nrg_ratio_fx_e[b2], L_tmp2_e ) ); dot_prod_nrg_ratio_fx[b2] = L_shl( dot_prod_nrg_ratio_fx[b2], L_tmp_e ); // Q31 @@ -3691,7 +3691,7 @@ static void stereo_dft_enc_compute_prm_fx( } // c = sqrtf( sum_past_nrgL / sum_past_nrgR ); - c = BASOP_Util_Divide3232_Scale_cadence( sum_past_nrgL, sum_past_nrgR, &c_e ); + c = BASOP_Util_Divide3232_Scale_newton( sum_past_nrgL, sum_past_nrgR, &c_e ); c_e = add( c_e, sub( sum_past_nrgL_e, sum_past_nrgR_e ) ); c = Sqrt32( c, &c_e ); // sum_past_nrg_dmx = sum_past_nrgL + sum_past_nrgR + 2 * sum_past_dot_prod_abs; @@ -3718,7 +3718,7 @@ static void stereo_dft_enc_compute_prm_fx( { // g = ( sum_past_nrgL - sum_past_nrgR ) / ( sum_past_nrg_dmx ); L_tmp1 = BASOP_Util_Add_Mant32Exp( sum_past_nrgL, sum_past_nrgL_e, L_negate( sum_past_nrgR ), sum_past_nrgR_e, &L_tmp1_e ); - L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_past_nrg_dmx, &L_tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( L_tmp1, sum_past_nrg_dmx, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, sum_past_nrg_dmx_e ) ); g = L_shl_sat( L_tmp, L_tmp_e ); // Q31 saturation expected pSideGain[b] = g; @@ -3731,7 +3731,7 @@ static void stereo_dft_enc_compute_prm_fx( // pSideGain[b] = ( c - 1 ) / ( c + 1 ); L_tmp1 = BASOP_Util_Add_Mant32Exp( c, c_e, MIN_32, 0, &L_tmp1_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( c, c_e, MAX_32, 0, &L_tmp2_e ); - L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); pSideGain[b] = L_shl_sat( L_tmp, L_tmp_e ); // Q31 saturation expected move32(); @@ -3774,7 +3774,7 @@ static void stereo_dft_enc_compute_prm_fx( // pPredGain[b] = sqrtf( pPredGain[b] / ( reg + sum_past_nrg_dmx ) ); L_tmp2 = BASOP_Util_Add_Mant32Exp( reg, reg_e, sum_past_nrg_dmx, sum_past_nrg_dmx_e, &L_tmp2_e ); - L_tmp1 = BASOP_Util_Divide3232_Scale_cadence( L_tmp, L_tmp2, &L_tmp1_e ); + L_tmp1 = BASOP_Util_Divide3232_Scale_newton( L_tmp, L_tmp2, &L_tmp1_e ); L_tmp1_e = add( L_tmp1_e, sub( L_tmp_e, L_tmp2_e ) ); L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); pPredGain[b] = L_shl( L_tmp1, L_tmp1_e ); // Q31 @@ -3913,14 +3913,14 @@ static void stereo_dft_enc_compute_prm_fx( } // c = sqrtf( sum_energy_L / sum_energy_R ); - c = BASOP_Util_Divide3232_Scale_cadence( sum_energy_L, sum_energy_R, &c_e ); + c = BASOP_Util_Divide3232_Scale_newton( sum_energy_L, sum_energy_R, &c_e ); c_e = add( c_e, sub( sum_energy_L_e, sum_energy_R_e ) ); c = Sqrt32( c, &c_e ); // g = fabsf( ( c - 1 ) / ( c + 1 ) ); L_tmp1 = BASOP_Util_Add_Mant32Exp( c, c_e, MIN_32, 0, &L_tmp1_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( c, c_e, MAX_32, 0, &L_tmp2_e ); - g = L_abs( BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ) ); + g = L_abs( BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp_e ) ); L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); g = L_shl_sat( g, L_tmp_e ); // Q31 saturation expected IF( GT_32( g, 1717986918 /*0.8f in Q31*/ ) ) @@ -4326,7 +4326,7 @@ static Word32 stereo_dft_calc_mean_ipd_change_fx( ipd_mean_change = L_add( ipd_mean_change, ipd_change[b] ); } // ipd_mean_change /= gipd_band_max; - ipd_mean_change = BASOP_Util_Divide3232_Scale_cadence( ipd_mean_change, gipd_band_max, &ipd_mean_change_e ); + ipd_mean_change = BASOP_Util_Divide3232_Scale_newton( ipd_mean_change, gipd_band_max, &ipd_mean_change_e ); ipd_mean_change_e = add( ipd_mean_change_e, 18 - 31 ); ipd_mean_change = L_shr( ipd_mean_change, sub( 18, ipd_mean_change_e ) ); // Q13 @@ -4510,13 +4510,13 @@ static void stereo_dft_enc_get_reverb_flag_fx( FOR( b = 0; b <= s_min( hStereoDft->nbands, 6 ); b++ ) /* choose the subbands used for stereo filling */ { // norm_dmx = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_DMX[b]); - norm_dmx = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_DMX[b], &norm_dmx_e ); + norm_dmx = BASOP_Util_Divide3232_Scale_newton( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_DMX[b], &norm_dmx_e ); norm_dmx_e = add( norm_dmx_e, sub( 31, sub_nrg_DMX_e[b] ) ); // norm_l = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_L[b]); - norm_l = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_L[b], &norm_l_e ); + norm_l = BASOP_Util_Divide3232_Scale_newton( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_L[b], &norm_l_e ); norm_l_e = add( norm_l_e, sub( 31, sub_nrg_L_e[b] ) ); // norm_r = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_R[b]); - norm_r = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_R[b], &norm_r_e ); + norm_r = BASOP_Util_Divide3232_Scale_newton( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_R[b], &norm_r_e ); norm_r_e = add( norm_r_e, sub( 31, sub_nrg_R_e[b] ) ); FOR( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) /* normalization on each subbands */ @@ -4562,13 +4562,13 @@ static void stereo_dft_enc_get_reverb_flag_fx( FOR( ; b < s_min( hStereoDft->nbands, 10 ); b++ ) /* choose the subbands used for stereo filling */ { // norm_dmx = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_DMX[b]); - norm_dmx = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_DMX[b], &norm_dmx_e ); + norm_dmx = BASOP_Util_Divide3232_Scale_newton( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_DMX[b], &norm_dmx_e ); norm_dmx_e = add( norm_dmx_e, sub( 31, sub_nrg_DMX_e[b] ) ); // norm_l = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_L[b]); - norm_l = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_L[b], &norm_l_e ); + norm_l = BASOP_Util_Divide3232_Scale_newton( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_L[b], &norm_l_e ); norm_l_e = add( norm_l_e, sub( 31, sub_nrg_L_e[b] ) ); // norm_r = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_R[b]); - norm_r = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_R[b], &norm_r_e ); + norm_r = BASOP_Util_Divide3232_Scale_newton( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_R[b], &norm_r_e ); norm_r_e = add( norm_r_e, sub( 31, sub_nrg_R_e[b] ) ); FOR( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) /* normalization on each subbands */ @@ -4614,7 +4614,7 @@ static void stereo_dft_enc_get_reverb_flag_fx( FOR( b = 0; b < hStereoDft->nbands; b++ ) /* choose the subbands used for stereo filling */ { // sub_nrg_DMX[b] /= (hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]); - sub_nrg_DMX[b] = BASOP_Util_Divide3232_Scale_cadence( sub_nrg_DMX[b], sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), &L_tmp_e ); + sub_nrg_DMX[b] = BASOP_Util_Divide3232_Scale_newton( sub_nrg_DMX[b], sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), &L_tmp_e ); move32(); sub_nrg_DMX_e[b] = add( L_tmp_e, sub( sub_nrg_DMX_e[b], 31 ) ); move16(); @@ -4735,12 +4735,12 @@ static void stereo_dft_enc_get_reverb_flag_fx( // fac = ((diff_l_l > diff_r_l) ? diff_r_l / diff_l_l : diff_l_l / diff_r_l); IF( BASOP_Util_Cmp_Mant32Exp( diff_l_l, diff_l_l_e, diff_r_l, diff_r_l_e ) > 0 ) { - fac = BASOP_Util_Divide3232_Scale_cadence( diff_r_l, diff_l_l, &L_tmp_e ); + fac = BASOP_Util_Divide3232_Scale_newton( diff_r_l, diff_l_l, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( diff_r_l_e, diff_l_l_e ) ); } ELSE { - fac = BASOP_Util_Divide3232_Scale_cadence( diff_l_l, diff_r_l, &L_tmp_e ); + fac = BASOP_Util_Divide3232_Scale_newton( diff_l_l, diff_r_l, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( diff_l_l_e, diff_r_l_e ) ); } fac = L_shl_sat( fac, L_tmp_e ); // Q31 @@ -4792,7 +4792,7 @@ static Word32 stereo_dft_gain_offset_fx( * function @ 32kHz from which the values are interpolated: */ k0 = shr( tau, 3 ); // alpha = s_and(tau, 7) / 8.f; - alpha = BASOP_Util_Divide3232_Scale_cadence( s_and( tau, 7 ), 8, &alpha_e ); + alpha = BASOP_Util_Divide3232_Scale_newton( s_and( tau, 7 ), 8, &alpha_e ); alpha = L_shl( alpha, alpha_e ); // Q31 // wnt = (1 - alpha) * Wn_table[k0] + alpha * Wn_table[k0 + 1]; wnt = L_add( Mpy_32_32( L_sub( MAX_32, alpha ), Wn_table_fx[k0] ), Mpy_32_32( alpha, Wn_table_fx[k0 + 1] ) ); // Q31 @@ -4803,12 +4803,12 @@ static Word32 stereo_dft_gain_offset_fx( L_tmp1 = BASOP_Util_Add_Mant32Exp( MAX_32, 0, c, c_e, &L_tmp1_e ); L_tmp1 = Mpy_32_32( L_tmp1, L_tmp1 ); L_tmp1_e = shl( L_tmp1_e, 1 ); - L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( L_tmp, L_tmp1, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Divide3232_Scale_newton( L_tmp, L_tmp1, &L_tmp2_e ); L_tmp2_e = add( add( L_tmp2_e, sub( L_tmp_e, L_tmp1_e ) ), 3 /*multiply by 8*/ ); L_tmp2 = Mpy_32_32( L_tmp2, L_sub( MAX_32, wnt ) ); L_tmp1 = BASOP_Util_Add_Mant32Exp( MAX_32, 0, L_tmp, L_tmp_e, &L_tmp1_e ); L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, L_tmp1_e, Mpy_32_32( c, wnt ), add( c_e, 1 ), &L_tmp1_e ); - L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp2, L_tmp1, &L_tmp_e ); + L_tmp = BASOP_Util_Divide3232_Scale_newton( L_tmp2, L_tmp1, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( L_tmp2_e, L_tmp1_e ) ); L_tmp = Sqrt32( L_tmp, &L_tmp_e ); go = L_shl( L_tmp, L_tmp_e ); @@ -4838,7 +4838,7 @@ static void stereo_dft_enc_calculate_nrg_for_icbwe_fx( Word32 tmp; // bandResDft = ( (float) input_Fs ) / hStereoDft->NFFT; - bandResDft = BASOP_Util_Divide3232_Scale_cadence( input_Fs, hStereoDft->NFFT, &bandResDft_e ); + bandResDft = BASOP_Util_Divide3232_Scale_newton( input_Fs, hStereoDft->NFFT, &bandResDft_e ); // shbBins[0] = (int16_t) ( 6400 / bandResDft ); shbBins[0] = BASOP_Util_Divide3232_Scale( 6400, bandResDft, &tmp_e ); move16(); diff --git a/lib_enc/ivas_stereo_dft_enc_itd_fx.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c index b7429e2e7..1beacd19a 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -232,7 +232,7 @@ static Word32 itd_vad_ms_snr_calc_fx( move32(); } // E_band[i] = E_band[i] / ( itd_vad_band_tbl[i + 1] - itd_vad_band_tbl[i] ); - E_band[i] = BASOP_Util_Divide3232_Scale_cadence( E_band[i], L_sub( itd_vad_band_tbl[i + 1], itd_vad_band_tbl[i] ), &exp ); + E_band[i] = BASOP_Util_Divide3232_Scale_newton( E_band[i], L_sub( itd_vad_band_tbl[i + 1], itd_vad_band_tbl[i] ), &exp ); move32(); E_band_e[i] = add( exp, sub( E_band_e[i], 31 ) ); move16(); @@ -245,7 +245,7 @@ static Word32 itd_vad_ms_snr_calc_fx( FOR( i = 0; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) { // snr[i] = E_band[i] / E_band_n[i]; - snr[i] = BASOP_Util_Divide3232_Scale_cadence( E_band[i], E_band_n[i], &snr_e[i] ); + snr[i] = BASOP_Util_Divide3232_Scale_newton( E_band[i], E_band_n[i], &snr_e[i] ); move32(); snr_e[i] = add( snr_e[i], sub( E_band_e[i], E_band_n_exp[i] ) ); move16(); @@ -327,7 +327,7 @@ static void itd_vad_background_update_fx( L_temp = L_shl( *vad_frm_cnt, q_temp ); L_temp_e = sub( 31, q_temp ); L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( E_band_n_exp[i], L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); - E_band_n[i] = BASOP_Util_Divide3232_Scale_cadence( L_temp, L_add( *vad_frm_cnt, 1 ), &E_band_n_e_tmp ); + E_band_n[i] = BASOP_Util_Divide3232_Scale_newton( L_temp, L_add( *vad_frm_cnt, 1 ), &E_band_n_e_tmp ); move32(); E_band_n_exp[i] = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); move16(); @@ -536,7 +536,7 @@ static Word32 calc_mean_E_ratio_fx( L_temp1 = BASOP_Util_Add_Mant32Exp( acorr, acorr_e, fi[b], fi_e[b], &L_temp1_e ); L_temp2 = BASOP_Util_Add_Mant32Exp( acorr, acorr_e, L_negate( fi[b] ), fi_e[b], &L_temp2_e ); L_temp2 = BASOP_Util_Add_Mant32Exp( L_temp2, L_temp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_temp2_e ); - Er[b] = BASOP_Util_Divide3232_Scale_cadence( L_temp1, L_temp2, &Er_e[b] ); + Er[b] = BASOP_Util_Divide3232_Scale_newton( L_temp1, L_temp2, &Er_e[b] ); move32(); Er_e[b] = add( Er_e[b], sub( L_temp1_e, L_temp2_e ) ); move16(); @@ -585,7 +585,7 @@ static Word32 calc_mean_E_ratio_fx( L_temp1 = BASOP_Util_Add_Mant32Exp( acorr, acorr_e, total_fi, total_fi_e, &L_temp1_e ); L_temp2 = BASOP_Util_Add_Mant32Exp( acorr, acorr_e, L_negate( total_fi ), total_fi_e, &L_temp2_e ); L_temp2 = BASOP_Util_Add_Mant32Exp( L_temp2, L_temp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_temp2_e ); - *total_mEr = BASOP_Util_Divide3232_Scale_cadence( L_temp1, L_temp2, total_mEr_e ); + *total_mEr = BASOP_Util_Divide3232_Scale_newton( L_temp1, L_temp2, total_mEr_e ); move32(); *total_mEr_e = add( *total_mEr_e, sub( L_temp1_e, L_temp2_e ) ); move16(); @@ -1302,14 +1302,14 @@ void stereo_dft_enc_compute_itd_fx( // g_ILD = sqrtf( sum_nrg_L / ( sum_nrg_R + 1.0f ) ); L_temp = BASOP_Util_Add_Mant32Exp( sum_nrg_R, sum_nrg_R_e, MAX_32, 0, &L_temp_e ); - g_ILD = BASOP_Util_Divide3232_Scale_cadence( sum_nrg_L, L_temp, &g_ILD_e ); + g_ILD = BASOP_Util_Divide3232_Scale_newton( sum_nrg_L, L_temp, &g_ILD_e ); g_ILD_e = add( g_ILD_e, sub( sum_nrg_L_e, L_temp_e ) ); g_ILD = Sqrt32( g_ILD, &g_ILD_e ); // g_ILD = fabsf( ( g_ILD - 1 ) / ( g_ILD + 1 ) ); L_temp = BASOP_Util_Add_Mant32Exp( g_ILD, g_ILD_e, MIN_32, 0, &L_temp_e ); L_temp2 = BASOP_Util_Add_Mant32Exp( g_ILD, g_ILD_e, MAX_32, 0, &L_temp2_e ); - g_ILD = L_abs( BASOP_Util_Divide3232_Scale_cadence( L_temp, L_temp2, &g_ILD_e ) ); + g_ILD = L_abs( BASOP_Util_Divide3232_Scale_newton( L_temp, L_temp2, &g_ILD_e ) ); g_ILD_e = add( g_ILD_e, sub( L_temp_e, L_temp2_e ) ); g_ILD = L_shl_sat( g_ILD, g_ILD_e ); // Q31 @@ -1339,7 +1339,7 @@ void stereo_dft_enc_compute_itd_fx( // g_IPD = ( sum_nrg_L + sum_nrg_R + 2 * grand_dot_prod_real ) / grand_nrg_DMX; L_temp = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, sum_nrg_R, sum_nrg_R_e, &L_temp_e ); L_temp = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, grand_dot_prod_real, add( grand_dot_prod_real_e, 1 ), &L_temp_e ); - g_IPD = BASOP_Util_Divide3232_Scale_cadence( L_temp, grand_nrg_DMX, &g_IPD_e ); + g_IPD = BASOP_Util_Divide3232_Scale_newton( L_temp, grand_nrg_DMX, &g_IPD_e ); g_IPD_e = add( g_IPD_e, sub( L_temp_e, grand_nrg_DMX_e ) ); // if ( g_IPD >= 1.0f ) IF( BASOP_Util_Cmp_Mant32Exp( g_IPD, g_IPD_e, ONE_IN_Q29 - ONE_IN_Q14 /*Adjusting threshold for precision loss*/, 2 ) >= 0 ) @@ -1366,7 +1366,7 @@ void stereo_dft_enc_compute_itd_fx( // angle_rot = fabsf( atanf( 2.0f * ( grand_dot_prod_real ) / ( sum_nrg_L - sum_nrg_R + 1.0f ) ) ); L_temp = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, L_negate( sum_nrg_R ), sum_nrg_R_e, &L_temp_e ); L_temp = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, MAX_32, 0, &L_temp_e ); - L_temp2 = BASOP_Util_Divide3232_Scale_cadence( grand_dot_prod_real, L_temp, &L_temp2_e ); + L_temp2 = BASOP_Util_Divide3232_Scale_newton( grand_dot_prod_real, L_temp, &L_temp2_e ); L_temp2_e = add( L_temp2_e, sub( add( grand_dot_prod_real_e, 1 ), L_temp_e ) ); angle_rot = L_abs( BASOP_util_atan( L_shr_r_sat( L_temp2, ( sub( 6, L_temp2_e ) ) ) ) ); // Q14 // angle_rot = L_abs( BASOP_util_atan2( grand_dot_prod_real, L_temp, sub( add( grand_dot_prod_real_e, 1 ), L_temp_e ) ) ); // Q13 @@ -1378,7 +1378,7 @@ void stereo_dft_enc_compute_itd_fx( // g_side = fabsf( sum_nrg_L - sum_nrg_R ) / ( grand_nrg_DMX ); L_temp = L_abs( BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, L_negate( sum_nrg_R ), sum_nrg_R_e, &L_temp_e ) ); - g_side = BASOP_Util_Divide3232_Scale_cadence( L_temp, grand_nrg_DMX, &g_side_e ); + g_side = BASOP_Util_Divide3232_Scale_newton( L_temp, grand_nrg_DMX, &g_side_e ); g_side_e = add( g_side_e, sub( L_temp_e, grand_nrg_DMX_e ) ); g_side = L_shl_sat( g_side, g_side_e ); // Q31 g_side_e = 0; @@ -1443,7 +1443,7 @@ void stereo_dft_enc_compute_itd_fx( ELSE { // sfm_L = expf( log_prod_L / ( NFFT_mid ) ) / ( sum_abs_L / ( NFFT_mid ) ); - L_temp = BASOP_Util_Divide3232_Scale_cadence( log_prod_L, NFFT_mid, &L_temp_e ); + L_temp = BASOP_Util_Divide3232_Scale_newton( log_prod_L, NFFT_mid, &L_temp_e ); L_temp_e = add( L_temp_e, sub( log_prod_L_e, 31 ) ); L_temp = BASOP_Util_fPow( 1459366444 /*2.718 in Q29*/, 2, L_temp, L_temp_e, &L_temp_e ); q_temp = norm_l( NFFT_mid ); @@ -1451,7 +1451,7 @@ void stereo_dft_enc_compute_itd_fx( L_temp2_e = sub( 31, q_temp ); L_temp = Mpy_32_32( L_temp, L_temp2 ); L_temp_e = add( L_temp_e, L_temp2_e ); - sfm_L = BASOP_Util_Divide3232_Scale_cadence( L_temp, sum_abs_L, &sfm_L_e ); + sfm_L = BASOP_Util_Divide3232_Scale_newton( L_temp, sum_abs_L, &sfm_L_e ); sfm_L_e = add( sfm_L_e, sub( L_temp_e, sum_abs_L_e ) ); sfm_L = L_shl_sat( sfm_L, sfm_L_e ); // Q31 - should be rechecked for -10dB tests } @@ -1467,7 +1467,7 @@ void stereo_dft_enc_compute_itd_fx( ELSE { // sfm_R = expf( log_prod_R / ( NFFT_mid ) ) / ( sum_abs_R / ( NFFT_mid ) ); - L_temp = BASOP_Util_Divide3232_Scale_cadence( log_prod_R, NFFT_mid, &L_temp_e ); + L_temp = BASOP_Util_Divide3232_Scale_newton( log_prod_R, NFFT_mid, &L_temp_e ); L_temp_e = add( L_temp_e, sub( log_prod_R_e, 31 ) ); L_temp = BASOP_Util_fPow( 1459366444 /*2.718 in Q29*/, 2, L_temp, L_temp_e, &L_temp_e ); q_temp = norm_l( NFFT_mid ); @@ -1475,7 +1475,7 @@ void stereo_dft_enc_compute_itd_fx( L_temp2_e = sub( 31, q_temp ); L_temp = Mpy_32_32( L_temp, L_temp2 ); L_temp_e = add( L_temp_e, L_temp2_e ); - sfm_R = BASOP_Util_Divide3232_Scale_cadence( L_temp, sum_abs_R, &sfm_L_e ); + sfm_R = BASOP_Util_Divide3232_Scale_newton( L_temp, sum_abs_R, &sfm_L_e ); sfm_R_e = add( sfm_L_e, sub( L_temp_e, sum_abs_R_e ) ); // sfm_R = L_shl_r( sfm_R, sfm_R_e ); // Q31 sfm_R = L_shl_sat( sfm_R, sfm_R_e ); // Q31 @@ -1663,7 +1663,7 @@ void stereo_dft_enc_compute_itd_fx( } // cng_xcorr_filt = max( min( CORR_FILT, 10.0f * CORR_FILT / ( hStereoDft->expectedNumUpdates + hStereoDft->currentNumUpdates ) ), sfm_L ); - cng_xcorr_filt = BASOP_Util_Divide3232_Scale_cadence( 8 /*10.0f * CORR_FILT*/, add( hStereoDft->expectedNumUpdates, hStereoDft->currentNumUpdates ), &cng_xcorr_filt_e ); + cng_xcorr_filt = BASOP_Util_Divide3232_Scale_newton( 8 /*10.0f * CORR_FILT*/, add( hStereoDft->expectedNumUpdates, hStereoDft->currentNumUpdates ), &cng_xcorr_filt_e ); cng_xcorr_filt = L_shl_sat( cng_xcorr_filt, cng_xcorr_filt_e ); // Q31 cng_xcorr_filt = L_max( L_min( CORR_FILT_Q31, cng_xcorr_filt ), sfm_L ); // Q31 @@ -1724,7 +1724,7 @@ void stereo_dft_enc_compute_itd_fx( // cng_xcorr_filt = max( min( CORR_FILT, 10.0f * CORR_FILT / ( hStereoDft->expectedNumUpdates + hStereoDft->currentNumUpdates ) ), sfm_L ); IF( add( hStereoDft->expectedNumUpdates, hStereoDft->currentNumUpdates ) != 0 ) { - cng_xcorr_filt = BASOP_Util_Divide3232_Scale_cadence( 8 /*10.0f * CORR_FILT*/, add( hStereoDft->expectedNumUpdates, hStereoDft->currentNumUpdates ), &cng_xcorr_filt_e ); + cng_xcorr_filt = BASOP_Util_Divide3232_Scale_newton( 8 /*10.0f * CORR_FILT*/, add( hStereoDft->expectedNumUpdates, hStereoDft->currentNumUpdates ), &cng_xcorr_filt_e ); cng_xcorr_filt = L_shl_sat( cng_xcorr_filt, cng_xcorr_filt_e ); // Q31 cng_xcorr_filt = L_max( L_min( CORR_FILT_Q31, cng_xcorr_filt ), sfm_L ); // Q31 } @@ -1917,7 +1917,7 @@ void stereo_dft_enc_compute_itd_fx( } // tmpf1 = (float) ( NFFT / 2 + 1 ) / tmpf3; - tmpf1 = BASOP_Util_Divide3232_Scale_cadence( add( shr( NFFT, 1 ), 1 ), tmpf3, &tmpf1_e ); + tmpf1 = BASOP_Util_Divide3232_Scale_newton( add( shr( NFFT, 1 ), 1 ), tmpf3, &tmpf1_e ); tmpf1_e = add( tmpf1_e, sub( 31, tmpf3_e ) ); FOR( i = 0; i < NFFT; i++ ) { @@ -1995,7 +1995,7 @@ void stereo_dft_enc_compute_itd_fx( L_temp = L_abs( BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, L_negate( sum_nrg_R ), sum_nrg_R_e, &L_temp_e ) ); L_temp2 = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, sum_nrg_R, sum_nrg_R_e, &L_temp2_e ); L_temp2 = BASOP_Util_Add_Mant32Exp( L_temp2, L_temp2_e, 1407374883, -16, &L_temp2_e ); - es_em = BASOP_Util_Divide3232_Scale_cadence( L_temp, L_temp2, &es_em_e ); + es_em = BASOP_Util_Divide3232_Scale_newton( L_temp, L_temp2, &es_em_e ); es_em_e = add( es_em_e, sub( L_temp_e, L_temp2_e ) ); hStereoClassif->unclr_fv_fx[E_es_em] = L_shr_r( es_em, sub( 16, es_em_e ) ); // Q15 @@ -2027,7 +2027,7 @@ void stereo_dft_enc_compute_itd_fx( move16(); } L_temp2 = BASOP_Util_Add_Mant32Exp( L_temp2, L_temp2_e, 1407374883, -16, &L_temp2_e ); - d_prodL_prodR = BASOP_Util_Divide3232_Scale_cadence( L_temp, L_temp2, &d_prodL_prodR_e ); + d_prodL_prodR = BASOP_Util_Divide3232_Scale_newton( L_temp, L_temp2, &d_prodL_prodR_e ); d_prodL_prodR_e = add( d_prodL_prodR_e, sub( L_temp_e, L_temp2_e ) ); d_prodL_prodR = BASOP_Util_Add_Mant32Exp( d_prodL_prodR, d_prodL_prodR_e, MAX_32, 0, &d_prodL_prodR_e ); d_prodL_prodR = BASOP_Util_Loge( d_prodL_prodR, d_prodL_prodR_e ); // Q25 @@ -2046,7 +2046,7 @@ void stereo_dft_enc_compute_itd_fx( // xcorr_abs[i] = logf( xcorr_abs[i] / ( sum_nrg_L + sum_nrg_R + 1e-5f ) + 1e-5f ); L_temp = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, sum_nrg_R, sum_nrg_R_e, &L_temp_e ); L_temp = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, 1407374883, -16, &L_temp_e ); - L_temp2 = BASOP_Util_Divide3232_Scale_cadence( xcorr_abs[i], L_temp, &L_temp2_e ); + L_temp2 = BASOP_Util_Divide3232_Scale_newton( xcorr_abs[i], L_temp, &L_temp2_e ); L_temp2_e = add( L_temp2_e, sub( xcorr_abs_e[i], L_temp_e ) ); L_temp2 = BASOP_Util_Add_Mant32Exp( L_temp2, L_temp2_e, 1407374883, -16, &L_temp2_e ); xcorr_abs[i] = BASOP_Util_Loge( L_temp2, L_temp2_e ); @@ -2112,12 +2112,12 @@ void stereo_dft_enc_compute_itd_fx( move16(); // hStereoClassif->ave_ener_L = sum_nrg_L / ( NFFT_mid * NFFT_mid ); - hStereoClassif->ave_ener_L_fx = BASOP_Util_Divide3232_Scale_cadence( sum_nrg_L, L_mult0( NFFT_mid, NFFT_mid ), &hStereoClassif->ave_ener_L_fx_e ); + hStereoClassif->ave_ener_L_fx = BASOP_Util_Divide3232_Scale_newton( sum_nrg_L, L_mult0( NFFT_mid, NFFT_mid ), &hStereoClassif->ave_ener_L_fx_e ); move32(); hStereoClassif->ave_ener_L_fx_e = add( hStereoClassif->ave_ener_L_fx_e, sub( sum_nrg_L_e, 31 ) ); move16(); // hStereoClassif->ave_ener_R = sum_nrg_R / ( NFFT_mid * NFFT_mid ); - hStereoClassif->ave_ener_R_fx = BASOP_Util_Divide3232_Scale_cadence( sum_nrg_R, L_mult0( NFFT_mid, NFFT_mid ), &hStereoClassif->ave_ener_R_fx_e ); + hStereoClassif->ave_ener_R_fx = BASOP_Util_Divide3232_Scale_newton( sum_nrg_R, L_mult0( NFFT_mid, NFFT_mid ), &hStereoClassif->ave_ener_R_fx_e ); move32(); hStereoClassif->ave_ener_R_fx_e = add( hStereoClassif->ave_ener_R_fx_e, sub( sum_nrg_R_e, 31 ) ); move16(); @@ -2145,7 +2145,7 @@ void stereo_dft_enc_compute_itd_fx( { // thres *= 1.0f + 1.f * min( 1.f, max( 0.f, ( -1.0f * sfm_L + 0.5f ) / ( 0.5f - 0.2f ) ) ); L_temp = BASOP_Util_Add_Mant32Exp( L_negate( sfm_L ), 0, ONE_IN_Q30, 0, &L_temp_e ); - L_temp2 = BASOP_Util_Divide3232_Scale_cadence( L_temp, 644245094, &L_temp2_e ); + L_temp2 = BASOP_Util_Divide3232_Scale_newton( L_temp, 644245094, &L_temp2_e ); L_temp2_e = add( L_temp2_e, L_temp_e - 0 ); L_temp2 = L_shl_sat( L_temp2, sub( L_temp2_e, 1 ) ); // Q30 L_temp2_e = 1; @@ -2363,7 +2363,7 @@ void stereo_dft_enc_compute_itd_fx( L_temp = Mpy_32_32( den_cor_cur, den_cor_prev ); L_temp_e = add( den_cor_cur_e, den_cor_prev_e ); L_temp = Sqrt32( L_temp, &L_temp_e ); - cor_lb[i] = BASOP_Util_Divide3232_Scale_cadence( num_cor, L_temp, &cor_lb_e[i] ); + cor_lb[i] = BASOP_Util_Divide3232_Scale_newton( num_cor, L_temp, &cor_lb_e[i] ); move32(); cor_lb_e[i] = add( cor_lb_e[i], sub( num_cor_e, L_temp_e ) ); move16(); @@ -2375,7 +2375,7 @@ void stereo_dft_enc_compute_itd_fx( // par_L[i] = xcorr_max / ( sum_nrg_L_tmp + FLT_MIN ); IF( xcorr_max ) { - par_L[i] = BASOP_Util_Divide3232_Scale_cadence( xcorr_max, sum_nrg_L_tmp, &par_L_e[i] ); + par_L[i] = BASOP_Util_Divide3232_Scale_newton( xcorr_max, sum_nrg_L_tmp, &par_L_e[i] ); move32(); par_L_e[i] = add( par_L_e[i], sub( xcorr_max_e, sum_nrg_L_tmp_e ) ); move16(); diff --git a/lib_enc/ivas_stereo_eclvq_enc_fx.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c index 3abc07811..dc2cf18a0 100644 --- a/lib_enc/ivas_stereo_eclvq_enc_fx.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -89,7 +89,7 @@ void ECSQ_quantize_vector_fx( } ELSE { - inv_global_gain = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q15, global_gain, &inv_global_gain_e ); + inv_global_gain = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q15, global_gain, &inv_global_gain_e ); inv_global_gain = L_shl( inv_global_gain, inv_global_gain_e ); // Q31 FOR( i = 0; i < N; ++i ) { @@ -140,7 +140,7 @@ Word32 ECSQ_compute_optimal_gain_fx( // Q15 IF( sum_sq_output != 0 ) { // optimal_global_gain = sum_input_output / sum_sq_output; - optimal_global_gain = BASOP_Util_Divide3232_Scale_cadence( sum_input_output, sum_sq_output, &optimal_global_gain_e ); // 31 - ( sum_input_output_e - 31 + optimal_global_gain_e ) = 62 - ( sum_input_output_e + optimal_global_gain_e ) + optimal_global_gain = BASOP_Util_Divide3232_Scale_newton( sum_input_output, sum_sq_output, &optimal_global_gain_e ); // 31 - ( sum_input_output_e - 31 + optimal_global_gain_e ) = 62 - ( sum_input_output_e + optimal_global_gain_e ) optimal_global_gain = L_shr( optimal_global_gain, sub( sub( 62, add( sum_input_output_e, optimal_global_gain_e ) ), 15 ) ); // Q15 } @@ -427,7 +427,7 @@ static Word16 get_best_param_fx( IF( LE_16( sub( count, count0 ), ECSQ_NONZERO_MAX ) && EQ_32( sum_abs, L_shl( sub( count, count0 ), 10 ) ) ) { //*avg_abs_sum = ( sum_abs + 0.25f * count0 ) / count; - *avg_abs_sum = BASOP_Util_Divide3232_Scale_cadence( L_add( sum_abs, L_shl( count0, 8 ) ), L_shl( count, 10 ), &L_tmp_e ); + *avg_abs_sum = BASOP_Util_Divide3232_Scale_newton( L_add( sum_abs, L_shl( count0, 8 ) ), L_shl( count, 10 ), &L_tmp_e ); move32(); *avg_abs_sum = L_shr_r( *avg_abs_sum, sub( 21, L_tmp_e ) ); // Q10 move32(); @@ -438,7 +438,7 @@ static Word16 get_best_param_fx( } //*avg_abs_sum = ( sum_abs + 0.25f * count0 ) / count; - *avg_abs_sum = BASOP_Util_Divide3232_Scale_cadence( L_add( sum_abs, L_shl( count0, 8 ) ), L_shl( count, 10 ), &L_tmp_e ); + *avg_abs_sum = BASOP_Util_Divide3232_Scale_newton( L_add( sum_abs, L_shl( count0, 8 ) ), L_shl( count, 10 ), &L_tmp_e ); move32(); *avg_abs_sum = L_shr_r( *avg_abs_sum, sub( 21, L_tmp_e ) ); // Q10 move32(); @@ -478,7 +478,7 @@ static Word32 get_est_size_fx( // Q10 // if ( param < 0 ) //{ // //two_to_param = 1.0f / two_to_param; - // two_to_param = BASOP_Util_Divide3232_Scale_cadence( 1, two_to_param,&two_to_param_e); + // two_to_param = BASOP_Util_Divide3232_Scale_newton( 1, two_to_param,&two_to_param_e); // } IF( NE_16( param, ECSQ_ALL_ZERO_PARAM ) ) /* not all values are zeros */ @@ -508,7 +508,7 @@ static Word32 get_est_size_fx( // Q10 nonzero = sub( N, N0 ); // required_avg_abs_sum = ( nonzero + 0.25f * N0 ) / N; /* the vector must have nonzero +-1 and N0 zeros */ - required_avg_abs_sum = BASOP_Util_Divide3232_Scale_cadence( L_add( L_shl( nonzero, 10 ), L_shl( N0, 8 ) ), L_shl( N, 10 ), &required_avg_abs_sum_e ); /* the vector must have nonzero +-1 and N0 zeros */ + required_avg_abs_sum = BASOP_Util_Divide3232_Scale_newton( L_add( L_shl( nonzero, 10 ), L_shl( N0, 8 ) ), L_shl( N, 10 ), &required_avg_abs_sum_e ); /* the vector must have nonzero +-1 and N0 zeros */ required_avg_abs_sum = L_shr_r( required_avg_abs_sum, sub( 21, required_avg_abs_sum_e ) ); // Q10 test(); @@ -847,18 +847,18 @@ Word32 ECSQ_encode_target_SNR_fx( /* target_ratio is the target ratio between the sum squared values of input and sum squared values of quantization error */ // target_ratio = powf( 10.0f, target_SNR / 10.0f ); - L_tmp1 = BASOP_Util_Divide3232_Scale_cadence( target_SNR, 10, &L_tmp1_e ); + L_tmp1 = BASOP_Util_Divide3232_Scale_newton( target_SNR, 10, &L_tmp1_e ); L_tmp1_e = add( L_tmp1_e, 6 - 31 ); target_ratio = BASOP_Util_fPow( 10 << 27, 4, L_tmp1, L_tmp1_e, &target_ratio_e ); // target_sum_squared_error = sum_squared / target_ratio; - target_sum_squared_error = BASOP_Util_Divide3232_Scale_cadence( sum_squared, target_ratio, &target_sum_squared_error_e ); + target_sum_squared_error = BASOP_Util_Divide3232_Scale_newton( sum_squared, target_ratio, &target_sum_squared_error_e ); target_sum_squared_error_e = add( target_sum_squared_error_e, sub( sum_squared_e, target_ratio_e ) ); /* the mean of squared quantization error for uniform scalar quantization is 1 / 12, approximately 0.0833 */ /* when including global_gain, the relationship is target_sum_squared_error ~ (0.0833 * N) * global_gain ^ 2 */ /* the representable range for global_gain is from 1 (global_gain_index 0) to 29145 (global_gain_index 126) inclusive */ // global_gain = sqrtf( target_sum_squared_error / ( 0.0833f * (float) N ) ); - global_gain = BASOP_Util_Divide3232_Scale_cadence( target_sum_squared_error, L_mult0( 5459 /*0.0833f in Q16*/, N ), &global_gain_e ); + global_gain = BASOP_Util_Divide3232_Scale_newton( target_sum_squared_error, L_mult0( 5459 /*0.0833f in Q16*/, N ), &global_gain_e ); global_gain_e = add( global_gain_e, sub( target_sum_squared_error_e, 15 ) ); global_gain = Sqrt32( global_gain, &global_gain_e ); global_gain = L_shr( global_gain, sub( 16, global_gain_e ) ); // Q15 @@ -885,7 +885,7 @@ Word32 ECSQ_encode_target_SNR_fx( adjust_size = L_sub( test_size, max_bits_fixpt ); /* assume doubling the quantization step size will reduce the entropy with (up to) one bit */ // adjust_global_gain_index = (int16_t) ceil( adjust_size / ( 1024.0f * N * log_base2( global_gain_step ) ) ); - adjust_global_gain_index = BASOP_Util_Divide3232_Scale_cadence( adjust_size, N, &tmp_e ); + adjust_global_gain_index = BASOP_Util_Divide3232_Scale_newton( adjust_size, N, &tmp_e ); adjust_global_gain_index = Mpy_32_32( adjust_global_gain_index, 17816838 /*/ ( 1024.0f * log_base2( global_gain_step ) )*/ ); IF( NE_32( adjust_global_gain_index, L_shl( L_shr( adjust_global_gain_index, sub( 31, tmp_e ) ), sub( 31, tmp_e ) ) ) ) { diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index a8a088f20..61057fbca 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -150,7 +150,7 @@ static void tcaTargetCh_LA_fx( deno_exp = 0; move16(); } - gAdj = BASOP_Util_Divide3232_Scale_cadence( tempF2, deno, &gAdj_exp ); /* Q31-gAdj_exp */ + gAdj = BASOP_Util_Divide3232_Scale_newton( tempF2, deno, &gAdj_exp ); /* Q31-gAdj_exp */ gAdj_exp = add( gAdj_exp, sub( tempF2_exp, deno_exp ) ); } @@ -923,7 +923,7 @@ static void corrStatsEst_fx( IF( tempF_fx != 0 ) { temp32 = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, L_negate( Mpy_32_32( X_hat_fx, Y_hat_fx ) ), add( X_hat_exp, Y_hat_exp ), &exp ); /* Q31-exp */ - beta_reg_fx = BASOP_Util_Divide3232_Scale_cadence( temp32, tempF_fx, &beta_reg_exp ); /* Q31-beta_reg_exp */ + beta_reg_fx = BASOP_Util_Divide3232_Scale_newton( temp32, tempF_fx, &beta_reg_exp ); /* Q31-beta_reg_exp */ if ( beta_reg_fx ) { beta_reg_exp = add( beta_reg_exp, sub( exp, tempF_exp ) ); @@ -2345,9 +2345,9 @@ static void unclr_calc_corr_features_fx( move32(); } - ic_Lm = BASOP_Util_Divide3232_Scale_cadence( corrL, ener, &exp1 ); /* Q31-exp1 */ + ic_Lm = BASOP_Util_Divide3232_Scale_newton( corrL, ener, &exp1 ); /* Q31-exp1 */ exp1 = add( exp1, sub( corrL_exp, ener_exp ) ); - ic_Rm = BASOP_Util_Divide3232_Scale_cadence( corrR, ener, &exp2 ); /* Q31-exp2 */ + ic_Rm = BASOP_Util_Divide3232_Scale_newton( corrR, ener, &exp2 ); /* Q31-exp2 */ exp2 = add( exp2, sub( corrR_exp, ener_exp ) ); m_corrL_corrR = L_sub( L_max( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ), L_min( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ) ); // s_max(exp1, exp2) @@ -2405,7 +2405,7 @@ static void unclr_calc_corr_features_fx( } ELSE { - *corrEst_ncorr = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp ); /* Q31-corrEst_ncorr_exp */ + *corrEst_ncorr = BASOP_Util_Divide3232_Scale_newton( num, den, &exp ); /* Q31-corrEst_ncorr_exp */ *corrEst_ncorr_exp = add( exp, sub( num_exp, den_exp ) ); move32(); move16(); diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index 9a1198e20..b1eae7862 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -382,14 +382,14 @@ void stereo_coder_tcx_fx( Word16 fTemp_e, tmp_e; Word32 fTemp_fx = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1], &fTemp_e ); /* Q31-fTemp_e */ fTemp_e = sub( fTemp_e, 1 ); - nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[0], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[0] */ + nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_newton( fTemp_fx, nrgRatio_fx[0], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[0] */ move32(); nrgRatio_e[0] = add( tmp_e, sub( fTemp_e, nrgRatio_e[0] ) ); move16(); nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ move32(); - nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[1], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[1] */ + nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_newton( fTemp_fx, nrgRatio_fx[1], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[1] */ move32(); nrgRatio_e[1] = add( tmp_e, sub( fTemp_e, nrgRatio_e[1] ) ); move16(); diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 6ffd05c0c..6a107e91f 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -2013,7 +2013,7 @@ static void Get_corr_n_fx( } ELSE { - *ic_Lm = BASOP_Util_Divide3232_Scale_cadence( corrL, ener, &exp_diff ); // (Q31 - exp_diff) + *ic_Lm = BASOP_Util_Divide3232_Scale_newton( corrL, ener, &exp_diff ); // (Q31 - exp_diff) move32(); IF( *ic_Lm == 0 ) { @@ -2025,7 +2025,7 @@ static void Get_corr_n_fx( *q_ic_Lm = sub( Q31, exp_diff ); move16(); } - *ic_Rm = BASOP_Util_Divide3232_Scale_cadence( corrR, ener, &exp_diff ); // (Q31 - exp_diff) + *ic_Rm = BASOP_Util_Divide3232_Scale_newton( corrR, ener, &exp_diff ); // (Q31 - exp_diff) move16(); IF( *ic_Rm == 0 ) { @@ -2041,7 +2041,7 @@ static void Get_corr_n_fx( /* *es_em = 10 * ( log10f( sqrtf( ener_side / len ) ) - log10f( sqrtf( ener / len ) ) ); is simplified to *es_em = 10 * ( log10f( sqrtf( ener_side / ener ) ) ); */ - L_tmp = BASOP_Util_Divide3232_Scale_cadence( ener_side, ener, &exp_diff ); // (Q31 - exp_diff) + L_tmp = BASOP_Util_Divide3232_Scale_newton( ener_side, ener, &exp_diff ); // (Q31 - exp_diff) L_tmp = Sqrt32( L_tmp, &exp_diff ); /* (Q31 - exp_diff) */ L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */ *es_em = Mpy_32_32( Mpy_32_32( L_add( L_tmp, L_shl( exp_diff, Q25 ) ), LOG10_2_Q31 ), TEN_IN_Q27 ); // (Q25, Q27) -> Q21 diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index fd84d2f21..5f2e9a8e0 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -1086,7 +1086,7 @@ Word16 ivas_acelp_tcx20_switching_fx( nrg_s = BASOP_Util_Add_Mant32Exp( nrg_s, e_num, Mpy_32_32( y_fx[i], y_fx[i] ), shl( e_x, 1 ), &e_num ); /* Q31-e_num */ nrg_n = BASOP_Util_Add_Mant32Exp( nrg_n, e_den, Mpy_32_32( x_fx[i], x_fx[i] ), shl( temp_ene_e, 1 ), &e_den ); /* Q31-e_den */ } - res_cod_SNR_M[iter] = BASOP_Util_Divide3232_Scale_cadence( nrg_s, nrg_n, &temp_e ); /* Q31-res_cod_SNR_M_e[iter] */ + res_cod_SNR_M[iter] = BASOP_Util_Divide3232_Scale_newton( nrg_s, nrg_n, &temp_e ); /* Q31-res_cod_SNR_M_e[iter] */ move32(); res_cod_SNR_M_e[iter] = add( temp_e, sub( e_num, e_den ) ); move16(); diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 3f6449a0c..ecccc8011 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1961,7 +1961,7 @@ Word16 ivas_smc_gmm_fx( FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - temp32 = BASOP_Util_Divide3232_Scale_cadence( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp + temp32 = BASOP_Util_Divide3232_Scale_newton( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp PS_norm_fx[i] = L_shl( temp32, sub( Qfact_PS_past, add( sub( 31, temp_exp ), sub( Qfact_PS, sub( 31, sum_PS_e ) ) ) ) ); // Qfact_PS_past move32(); dPS_fx[i] = L_abs( L_sub( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ); @@ -1992,7 +1992,7 @@ Word16 ivas_smc_gmm_fx( Word32 tmp_max; tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); - temp32 = BASOP_Util_Divide3232_Scale_cadence( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp + temp32 = BASOP_Util_Divide3232_Scale_newton( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 2abe538e4..228e522bf 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2786,7 +2786,7 @@ void tcx_noise_factor_ivas_fx( /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { - tmp4 = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); + tmp4 = BASOP_Util_Divide3232_Scale_newton( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); s = add( add( exp_sqErrorNrg, -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; tmp4 = L_shl_o( tmp4, s, &Overflow ); diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 60d661db4..2ade624b6 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -458,7 +458,7 @@ Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const } /* exponent = AVG_FLAT_E */ - i = BASOP_Util_Divide3232_Scale_cadence( sumTempFlatness, nTotBlocks, &exp ); + i = BASOP_Util_Divide3232_Scale_newton( sumTempFlatness, nTotBlocks, &exp ); exp = add( exp, sub( sumTempFlatness_exp, 31 ) ); i = L_shl_sat( i, sub( exp, 10 ) ); // Can be saturated, since it is used for comparision againt 3.25/20.0f, Q21 return i; @@ -1569,12 +1569,12 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp IF( GT_32( w0, w1 ) ) { - pSubblockNrgChange[w] = BASOP_Util_Divide3232_Scale_cadence( w0, w1, &k ); + pSubblockNrgChange[w] = BASOP_Util_Divide3232_Scale_newton( w0, w1, &k ); pSubblockNrgChange_exp[w] = k; } ELSE { - pSubblockNrgChange[w] = BASOP_Util_Divide3232_Scale_cadence( w1, w0, &k ); + pSubblockNrgChange[w] = BASOP_Util_Divide3232_Scale_newton( w1, w0, &k ); pSubblockNrgChange_exp[w] = k; } move32(); -- GitLab From ae29b091c06820aec13831523e343bce6ea25781 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 14 Apr 2025 23:22:47 +0200 Subject: [PATCH 1020/1221] formatting --- lib_enc/hq_classifier_enc_fx.c | 4 ++-- lib_enc/ivas_enc_cov_handler_fx.c | 2 +- lib_enc/ivas_stereo_eclvq_enc_fx.c | 4 ++-- lib_enc/ivas_stereo_ica_enc_fx.c | 2 +- lib_enc/ivas_stereo_td_analysis_fx.c | 2 +- lib_enc/speech_music_classif_fx.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index d82eebfb5..558ae89a7 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -141,8 +141,8 @@ static Word16 hf_spectrum_sparseness_fx( } } Word16 l_shift = W_norm( inv_rms_fx ); - inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 - Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms + inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 + Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_newton( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */ inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) ); // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB ); diff --git a/lib_enc/ivas_enc_cov_handler_fx.c b/lib_enc/ivas_enc_cov_handler_fx.c index 138e1467d..59c38aa5d 100644 --- a/lib_enc/ivas_enc_cov_handler_fx.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -271,7 +271,7 @@ static Word16 ivas_spar_get_activeW_flag_fx( } ELSE { - L_tmp = BASOP_Util_Divide3232_Scale_newton( hCovEnc->bb_var_lt_fx[0], side_ch_var, &exp_diff ); // (Q31 - exp_diff) + L_tmp = BASOP_Util_Divide3232_Scale_newton( hCovEnc->bb_var_lt_fx[0], side_ch_var, &exp_diff ); // (Q31 - exp_diff) en_ratio = L_shl_sat( L_tmp, exp_diff ); // Q31 IF( LT_32( en_ratio, Mpy_32_32( IVAS_SPAR_DYN_ACTIVEW_THRESH_FX, IVAS_SPAR_DYN_ACTIVEW_THRESH_FX ) ) ) // LHS Q31 :: RHS Q31 { diff --git a/lib_enc/ivas_stereo_eclvq_enc_fx.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c index dc2cf18a0..a09daffe0 100644 --- a/lib_enc/ivas_stereo_eclvq_enc_fx.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -140,7 +140,7 @@ Word32 ECSQ_compute_optimal_gain_fx( // Q15 IF( sum_sq_output != 0 ) { // optimal_global_gain = sum_input_output / sum_sq_output; - optimal_global_gain = BASOP_Util_Divide3232_Scale_newton( sum_input_output, sum_sq_output, &optimal_global_gain_e ); // 31 - ( sum_input_output_e - 31 + optimal_global_gain_e ) = 62 - ( sum_input_output_e + optimal_global_gain_e ) + optimal_global_gain = BASOP_Util_Divide3232_Scale_newton( sum_input_output, sum_sq_output, &optimal_global_gain_e ); // 31 - ( sum_input_output_e - 31 + optimal_global_gain_e ) = 62 - ( sum_input_output_e + optimal_global_gain_e ) optimal_global_gain = L_shr( optimal_global_gain, sub( sub( 62, add( sum_input_output_e, optimal_global_gain_e ) ), 15 ) ); // Q15 } @@ -509,7 +509,7 @@ static Word32 get_est_size_fx( // Q10 // required_avg_abs_sum = ( nonzero + 0.25f * N0 ) / N; /* the vector must have nonzero +-1 and N0 zeros */ required_avg_abs_sum = BASOP_Util_Divide3232_Scale_newton( L_add( L_shl( nonzero, 10 ), L_shl( N0, 8 ) ), L_shl( N, 10 ), &required_avg_abs_sum_e ); /* the vector must have nonzero +-1 and N0 zeros */ - required_avg_abs_sum = L_shr_r( required_avg_abs_sum, sub( 21, required_avg_abs_sum_e ) ); // Q10 + required_avg_abs_sum = L_shr_r( required_avg_abs_sum, sub( 21, required_avg_abs_sum_e ) ); // Q10 test(); IF( EQ_32( avg_abs_sum, required_avg_abs_sum ) && LE_16( nonzero, ECSQ_NONZERO_MAX ) ) diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 61057fbca..6057ace6b 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -923,7 +923,7 @@ static void corrStatsEst_fx( IF( tempF_fx != 0 ) { temp32 = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, L_negate( Mpy_32_32( X_hat_fx, Y_hat_fx ) ), add( X_hat_exp, Y_hat_exp ), &exp ); /* Q31-exp */ - beta_reg_fx = BASOP_Util_Divide3232_Scale_newton( temp32, tempF_fx, &beta_reg_exp ); /* Q31-beta_reg_exp */ + beta_reg_fx = BASOP_Util_Divide3232_Scale_newton( temp32, tempF_fx, &beta_reg_exp ); /* Q31-beta_reg_exp */ if ( beta_reg_fx ) { beta_reg_exp = add( beta_reg_exp, sub( exp, tempF_exp ) ); diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 6a107e91f..1856370f6 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -2041,7 +2041,7 @@ static void Get_corr_n_fx( /* *es_em = 10 * ( log10f( sqrtf( ener_side / len ) ) - log10f( sqrtf( ener / len ) ) ); is simplified to *es_em = 10 * ( log10f( sqrtf( ener_side / ener ) ) ); */ - L_tmp = BASOP_Util_Divide3232_Scale_newton( ener_side, ener, &exp_diff ); // (Q31 - exp_diff) + L_tmp = BASOP_Util_Divide3232_Scale_newton( ener_side, ener, &exp_diff ); // (Q31 - exp_diff) L_tmp = Sqrt32( L_tmp, &exp_diff ); /* (Q31 - exp_diff) */ L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */ *es_em = Mpy_32_32( Mpy_32_32( L_add( L_tmp, L_shl( exp_diff, Q25 ) ), LOG10_2_Q31 ), TEN_IN_Q27 ); // (Q25, Q27) -> Q21 diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index ecccc8011..3852d6dc4 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1961,7 +1961,7 @@ Word16 ivas_smc_gmm_fx( FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - temp32 = BASOP_Util_Divide3232_Scale_newton( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp + temp32 = BASOP_Util_Divide3232_Scale_newton( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp PS_norm_fx[i] = L_shl( temp32, sub( Qfact_PS_past, add( sub( 31, temp_exp ), sub( Qfact_PS, sub( 31, sum_PS_e ) ) ) ) ); // Qfact_PS_past move32(); dPS_fx[i] = L_abs( L_sub( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ); -- GitLab From 8fa203f853f0539e0ecb66f7b58e9f56bac85de5 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Thu, 10 Apr 2025 13:00:38 +0200 Subject: [PATCH 1021/1221] switch on STAGE2 --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 48df856c7..b51ccda4b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -90,6 +90,6 @@ #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From eca9c911fa0623cdabe25df442ab43c3c93fa13d Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 07:42:32 +0200 Subject: [PATCH 1022/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 436213825..95d31cba3 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7029,14 +7029,14 @@ void elliptic_bpf_48k_generic_fx( L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7325,7 +7325,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -8042,7 +8042,7 @@ void prep_tbe_exc_fx( void prep_tbe_exc_ivas_fx( const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE +#if 1 // def ADD_IVAS_TBE_CODE const Word16 L_subfr, #endif const Word16 i_subfr_fx, /* i : subframe index */ @@ -8059,7 +8059,7 @@ void prep_tbe_exc_ivas_fx( Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE +#if 1 // def ADD_IVAS_TBE_CODE , /* i : core bitrate */ const Word16 element_mode, /* i : element mode */ const Word16 idchan, /* i : channel ID */ -- GitLab From 132d8b831cb0e12e433df95bc50ce3ef25659063 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 11 Apr 2025 20:57:11 +0530 Subject: [PATCH 1023/1221] Fix for 3GPP issue 1472: Precision issue with power spectrum causes different behavior with silent channels in MCT Link #1472 --- lib_com/ivas_sns_com_fx.c | 13 ++++++++++--- lib_enc/ivas_core_enc_fx.c | 27 ++++++++++++++++++++++++++- lib_enc/ivas_core_pre_proc_front_fx.c | 13 ------------- lib_enc/ivas_core_pre_proc_fx.c | 12 +++++++----- lib_enc/ivas_cpe_enc_fx.c | 2 +- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index fa64b0092..f1e44be78 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -200,9 +200,16 @@ void sns_compute_scf_fx( /* mean = sum / FDNS_NPTS; -Q6 is for division with FDNS_NPTS and -Q1 is to reduce Q by one */ - mean = W_shl_sat_l( sum, -Q7 ); // q_out - nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // q_out - nf = L_max( nf, L_shl( 256, sub( q_out, 40 ) ) /* powf( 2.0f, -32.0f ) in Q40 */ ); // q_out + mean = W_shl_sat_l( sum, -Q7 ); // q_out + nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // q_out + + IF( LE_32( nf, L_shl_sat( 256, sub( q_out, 40 ) ) ) ) /* powf( 2.0f, -32.0f ) in Q40 */ + { + nf = 256; + move32(); + q_out = 40; + move16(); + } FOR( i = 0; i < FDNS_NPTS; i++ ) { diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 3c62a0d18..066d105d5 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -419,7 +419,6 @@ ivas_error ivas_core_enc_fx( } } - /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Encoding *---------------------------------------------------------------------*/ @@ -532,6 +531,12 @@ ivas_error ivas_core_enc_fx( st->hTcxEnc->exp_buf_speech_ltp = st->exp_buf_speech_enc; move16(); } + Scale_sig( st->input_fx, input_frame, sub( -1, st->q_inp ) ); + Scale_sig( st->input_fx - input_frame, input_frame, sub( -1, st->q_old_inp ) ); + st->q_inp = -1; + move16(); + st->q_old_inp = -1; + move16(); } Word16 Q_spec_old[2], L_spec; @@ -612,6 +617,8 @@ ivas_error ivas_core_enc_fx( * Postprocessing, BWEs and Updates *---------------------------------------------------------------------*/ + Word16 tmp_input_fx[L_FRAME48k], tmp_old_input_fx[L_FRAME48k], q_inp[2]; + FOR( n = 0; n < n_CoreChannels; n++ ) { st = sts[n]; @@ -626,6 +633,17 @@ ivas_error ivas_core_enc_fx( move16(); } + Copy( st->input_fx - input_frame, tmp_old_input_fx, input_frame ); + Copy( st->input_fx, tmp_input_fx, input_frame ); + q_inp[0] = st->q_old_inp; + q_inp[1] = st->q_inp; + + Scale_sig( st->input_fx - input_frame, 2 * input_frame, sub( -1, st->q_inp ) ); + st->q_inp = -1; + move16(); + st->q_old_inp = -1; + move16(); + /*---------------------------------------------------------------------* * Postprocessing for ACELP/HQ core switching *---------------------------------------------------------------------*/ @@ -787,6 +805,13 @@ ivas_error ivas_core_enc_fx( } } + Copy( tmp_old_input_fx, st->input_fx - input_frame, input_frame ); + Copy( tmp_input_fx, st->input_fx, input_frame ); + st->q_old_inp = q_inp[0]; + move16(); + st->q_inp = q_inp[1]; + move16(); + /*---------------------------------------------------------------------* * Channel-aware mode - write signaling information into the bitstream *---------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 0d6a5901a..bac22a5b7 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1575,12 +1575,6 @@ ivas_error pre_proc_front_ivas_fx( move16(); IF( flag_16k_smc ) { - Scale_sig( st->input_fx - input_frame, input_frame_full, sub( -1, st->q_inp ) ); /* Q(-1) */ - st->q_inp = -1; - move16(); - st->q_old_inp = -1; - move16(); - Word16 Q_old_inp_16k = -1; move16(); @@ -1718,13 +1712,6 @@ ivas_error pre_proc_front_ivas_fx( st->exp_old_inp_12k8 = sub( Q15, add( *Q_new, shift ) ); move16(); - Scale_sig( st->input_fx - input_frame, input_frame_full, sub( -1, st->q_inp ) ); - st->q_inp = -1; - move16(); - st->q_old_inp = -1; - move16(); - - // Scale_sig( old_inp_12k8_fx, L_INP_12k8, negate( add( *Q_new, 1 ) ) ); *Q_new = sub( *Q_new, Q_inp_const ); // ivas_core_enc will assume inp signal (12k8 and 16k) in Q_new - 1 move16(); diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 781d290ac..b2ec13983 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -565,9 +565,6 @@ ivas_error pre_proc_ivas_fx( Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); /* Q15 - Q_old_inp_16k */ st->exp_buf_speech_enc_pe = sub( Q15, Q_old_inp_16k ); move16(); - Scale_sig( st->input_fx, input_frame, sub( -1, st->q_inp ) ); - st->q_inp = -1; - move16(); Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k move16(); @@ -713,7 +710,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 *inp_16k_fx, *new_inp_16k_fx; Word16 delay, element_mode; Word16 temp1F_icatdmResampBuf_fx[L_FILT_MAX]; /* temp buffers for ICA TDM resamplers */ - Word16 mem_decim16k_dummy_fx[2 * L_FILT_MAX]; + Word16 mem_decim16k_dummy_fx[2 * L_FILT_MAX], input_buf_fx[L_FRAME48k * 2]; Word16 *signal_in_fx; Word16 lMemRecalc, lMemRecalc_16k, L_frame_tmp, L_look; Word32 input_Fs; @@ -733,7 +730,12 @@ ivas_error ivas_compute_core_buffers_fx( set16_fx( new_inp_resamp16k_fx, 0, L_FRAME16k ); set16_fx( epsP_h, 0, M + 1 ); set16_fx( epsP_l, 0, M + 1 ); - signal_in_fx = st->input_fx; /* st->q_inp */ + set16_fx( input_buf_fx, 0, L_FRAME48k * 2 ); + + Copy_Scale_sig( st->input_fx - input_frame, input_buf_fx, input_frame, sub( -1, st->q_old_inp ) ); + Copy_Scale_sig( st->input_fx, input_buf_fx + input_frame, input_frame, sub( -1, st->q_inp ) ); + + signal_in_fx = &input_buf_fx[input_frame]; /* st->q_inp */ input_Fs = st->input_Fs; /* Q0 */ move32(); diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 1bb31810d..b5ed69560 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -430,7 +430,7 @@ ivas_error ivas_cpe_enc_fx( stereo_tca_enc_fx( hCPE, input_frame ); - shift = s_min( 0, sub( add( L_norm_arr( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sts[0]->q_inp32 ), 16 ) ); + shift = sub( add( L_norm_arr( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sts[0]->q_inp32 ), 16 ); shift = s_min( shift, sub( add( L_norm_arr( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sts[1]->q_inp32 ), 16 ) ); Copy_Scale_sig32_16( sts[0]->input_buff32_fx, sts[0]->input_buff_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( add( Q16, shift ), sts[0]->q_inp32 ) ); // shift Copy_Scale_sig32_16( sts[1]->input_buff32_fx, sts[1]->input_buff_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( add( Q16, shift ), sts[1]->q_inp32 ) ); // shift -- GitLab From 4fcbe7002858a6c2efdcb22ce037452b1e0d93bb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 08:41:15 +0200 Subject: [PATCH 1024/1221] Revert "clang patch" This reverts commit eca9c911fa0623cdabe25df442ab43c3c93fa13d. --- lib_com/swb_tbe_com_fx.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 95d31cba3..436213825 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7029,14 +7029,14 @@ void elliptic_bpf_48k_generic_fx( L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7325,7 +7325,7 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ FOR( i = 0; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ @@ -8042,7 +8042,7 @@ void prep_tbe_exc_fx( void prep_tbe_exc_ivas_fx( const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE +#if 1 // def ADD_IVAS_TBE_CODE const Word16 L_subfr, #endif const Word16 i_subfr_fx, /* i : subframe index */ @@ -8059,7 +8059,7 @@ void prep_tbe_exc_ivas_fx( Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE +#if 1 // def ADD_IVAS_TBE_CODE , /* i : core bitrate */ const Word16 element_mode, /* i : element mode */ const Word16 idchan, /* i : channel ID */ -- GitLab From 9f6be5f43f56398387993bf25399145a4a69a050 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 08:41:51 +0200 Subject: [PATCH 1025/1221] Revert "switch on STAGE2" This reverts commit 8fa203f853f0539e0ecb66f7b58e9f56bac85de5. --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index b51ccda4b..48df856c7 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -90,6 +90,6 @@ #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif -- GitLab From 9ff3085f6c46bf4909f0925b1112fcf20f7c16a0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 08:57:51 +0200 Subject: [PATCH 1026/1221] trying to revert ugly stuff and bring swb_tbe_com_fx.c back to state like e1d19cec --- lib_com/swb_tbe_com_fx.c | 553 ++++++++++++++++----------------------- 1 file changed, 232 insertions(+), 321 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 436213825..f1492b0b4 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6686,135 +6686,177 @@ void wb_tbe_extras_reset_synth_fx( return; } -#if defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 ) && defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 ) -static inline Word64 wmac_1616( Word64 x1, Word16 x2, Word16 x3 ) -{ - return W_mac_16_16( x1, x2, x3 ); -} - -static inline Word64 wmac_3216( Word64 x1, Word32 x2, Word16 x3 ) -{ - return W_mac_32_16( x1, x2, x3 ); -} - -static inline Word64 finalSat16( Word64 W_tmpx, Word64 W_tmpy ) -{ - return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -} -static inline Word64 finalSat32( Word64 W_tmpx, Word64 W_tmpy ) -{ - return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); -} - -inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *input32_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 +inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) { Word32 L_tmpX; Word16 i; Word32 L_tmpMax2 = *L_tmpMax; Word32 L_tmpAbs; move32(); - - if ( input16_fx > 0 ) - { - Word64 ( *wmac )( Word64, Word16, Word16 ); - Word64 ( *finalSat )( Word64, Word64 ); - Word16 *input_fx = input16_fx; - wmac = wmac_1616; - finalSat = finalSat16; - } - if ( input32_fx > 0 ) - { - Word64 ( *wmac )( Word64, Word32, Word16 ); - Word64 ( *finalSat )( Word64, Word64 ); - Word32 *input_fx = input32_fx; - wmac = wmac_3216; - finalSat = finalSat32; - } - IF( !IsUpsampled3 ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { - W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } } +#else + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } +#endif } /*IsUpsampled3*/ ELSE { /*IsUpsampled3*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; ) { - W_tmpX = wmac( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } i++; - W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } i++; W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = wmac( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ move32(); - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpAbs = L_abs( L_tmp[i] ); } - if ( *L_tmpMax > 0 ) + if ( L_tmpMax > 0 ) { L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); } i++; } - } /*IsUpsampled3*/ +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + if ( L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ *L_tmpMax = L_tmpMax2; move32(); } @@ -6829,7 +6871,7 @@ inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *i void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, + int isIVAS; #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6847,9 +6889,8 @@ void elliptic_bpf_48k_generic_fx( Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4], L_tmpX; Word32 L_tmpMax; - Word32 L_tmpX; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word64 W_tmpX; Word64 W_tmpY; @@ -6864,21 +6905,6 @@ void elliptic_bpf_48k_generic_fx( Word32 memory2_fx_2[4], memory2_fx_3[4]; #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < 4; i++ ) - { - memory_fx0 = extract_l( memory_fx2[0][i] ); - input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - move32(); - move32(); - } -#else FOR( i = 0; i < 4; i++ ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -6896,138 +6922,92 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - move32(); - move32(); } -#endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( input_fx, 0, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - } + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; ) { - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - } /*IsUpsampled3*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } +#else + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -7038,26 +7018,28 @@ void elliptic_bpf_48k_generic_fx( move32(); i++; - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7121,47 +7103,41 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( 0, L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } - +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7238,64 +7214,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - FOR( j = 0; j < 4; j++ ) - { - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - } - - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( 0, L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - } - -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ FOR( j = 0; j < 4; j++ ) { L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); @@ -7343,7 +7261,9 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7476,12 +7396,7 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif -) + Word16 Qout ) { Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -7516,7 +7431,7 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, + 1 // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 @@ -7530,18 +7445,15 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, + 1 // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 #endif excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ - - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); temp1 = sum2_fx_mod( tmp, L_FRAME48k ); + L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ exp = norm_l( L_tmp ); tmp3 = extract_h( L_shl( L_tmp, exp ) ); @@ -7641,7 +7553,6 @@ void synthesise_fb_high_band_fx( } #endif } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ return; } -- GitLab From 9703b0235de80170320a73d212765280ec29c07c Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 09:25:53 +0200 Subject: [PATCH 1027/1221] bring back to state e1d19cec --- lib_com/options.h | 10 ++++-- lib_com/prot_fx.h | 9 ++---- lib_dec/ivas_core_dec_fx.c | 62 +++++++------------------------------- lib_dec/ivas_jbm_dec_fx.c | 20 ++---------- lib_dec/swb_tbe_dec_fx.c | 29 ++---------------- lib_enc/swb_tbe_enc_fx.c | 6 ++-- 6 files changed, 30 insertions(+), 106 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 48df856c7..c76765742 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -#define WMOPS /* Activate complexity and memory counters */ +/*#define WMOPS*/ /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -89,7 +89,13 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ +#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ +#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ + #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 92dd8311b..59c9e2f8c 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3266,7 +3266,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, + int isIVAS; #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -3292,12 +3292,7 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif -); + Word16 Qout ); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index db6dad33f..03f0e4b40 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -116,12 +116,12 @@ ivas_error ivas_core_dec_fx( error = IVAS_ERR_OK; move32(); - push_wmops( "ivas_core_dec (ICD)" ); + push_wmops( "ivas_core_dec" ); /*------------------------------------------------------------------* * General initialization *-----------------------------------------------------------------*/ - push_wmops( "ICD init" ); + use_cldfb_for_dft = 0; move16(); tdm_LRTD_flag = -1; @@ -370,9 +370,7 @@ ivas_error ivas_core_dec_fx( { save_hb_synth_32_fx = NULL; } - pop_wmops(); /*push_wmops( "ICD init" );*/ - push_wmops( "ICD SID, sanity" ); /*------------------------------------------------------------------* * Decode SID for MDCT-Stereo DTX mode *-----------------------------------------------------------------*/ @@ -400,9 +398,7 @@ ivas_error ivas_core_dec_fx( { ivas_combined_format_brate_sanity_fx( element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); } - pop_wmops(); /*push_wmops( "ICD SID, sanity" );*/ - push_wmops( "ICD Coredec" ); /*------------------------------------------------------------------* * Core Decoding *-----------------------------------------------------------------*/ @@ -487,7 +483,6 @@ ivas_error ivas_core_dec_fx( IF( st->core == ACELP_CORE ) { - push_wmops( "ICD ACELP" ); /* ACELP core decoder */ Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; @@ -560,7 +555,6 @@ ivas_error ivas_core_dec_fx( } Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) - pop_wmops(); /*push_wmops( "ICD ACELP" );*/ } Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 @@ -569,7 +563,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - push_wmops( "ICD TCX" ); Word16 Qsyn_temp; IVAS_FORMAT ivas_format; @@ -624,12 +617,10 @@ ivas_error ivas_core_dec_fx( } st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); move16(); - pop_wmops(); /*push_wmops( "ICD TCX" );*/ } IF( EQ_16( st->core, HQ_CORE ) ) { - push_wmops( "ICD HQ decoding" ); /* HQ core decoder */ Word16 Q_output; @@ -643,7 +634,6 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD HQ decoding" );*/ } /*---------------------------------------------------------------------* @@ -660,8 +650,8 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 } - } /* n_channels loop */ - pop_wmops(); /*push_wmops( "ICD Coredec" );*/ + } /* n_channels loop */ + /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Decoding @@ -669,7 +659,6 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { - push_wmops( "ICD jTCX Coredec" ); /* active-frame decoding */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) { @@ -798,7 +787,6 @@ ivas_error ivas_core_dec_fx( } } } - pop_wmops(); /*push_wmops( "ICD jTCX Coredec" );*/ } /*---------------------------------------------------------------------* @@ -808,7 +796,6 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hStereoCng != NULL ) { - push_wmops( "ICD Stereo CNG Updates" ); /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ Word16 Q_c_PS_LT, Q_output; Word32 c_PS_LT_fx; @@ -824,14 +811,12 @@ ivas_error ivas_core_dec_fx( stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); - pop_wmops(); /*push_wmops( "ICD Stereo CNG Updates" );*/ } /*---------------------------------------------------------------------* * Postprocessing, BWEs and updates *---------------------------------------------------------------------*/ - push_wmops( "ICD Postproc, BWE, updates (ICD PP)" ); FOR( n = 0; n < n_channels; n++ ) { st = sts[n]; @@ -842,7 +827,6 @@ ivas_error ivas_core_dec_fx( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ - push_wmops( "ICD PP TDBWE ACELPTCX trans" ); /*core_switching_post_dec*/ Q_synth = sub( 15, e_sig[0] ); @@ -916,12 +900,11 @@ ivas_error ivas_core_dec_fx( Copy_Scale_sig_16_32_no_sat( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, hBWE_TD->prev_Qx ) ); // Q11 Copy( hBWE_TD->mem_resamp_HB_fx, hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } - pop_wmops(); /*push_wmops( "ICD PP TDBWE ACELPTCX trans" );*/ /*---------------------------------------------------------------------* * Postprocessing for ACELP/MDCT core switching *---------------------------------------------------------------------*/ - push_wmops( "ICD PP ACELP/MDCT switch" ); + /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ test(); test(); @@ -956,12 +939,11 @@ ivas_error ivas_core_dec_fx( { Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); } - pop_wmops(); /*push_wmops( "ICD PP ACELP/MDCT switch" );*/ /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - push_wmops( "ICD PP BWswitch preproc" ); + ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); IF( st->hHQ_core == NULL ) @@ -1008,13 +990,12 @@ ivas_error ivas_core_dec_fx( hBWE_FD->prev_flag = hBWE_FD->prev_flag; move16(); } - pop_wmops(); /*push_wmops( "ICD PP BWswitch preproc" );*/ /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding *---------------------------------------------------------------------*/ - push_wmops( "ICD PP TBE/BWE" ); + Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; Word16 Q_syn_hb, sf; @@ -1042,9 +1023,8 @@ ivas_error ivas_core_dec_fx( IF( EQ_16( st->extl, WB_TBE ) ) { /* WB TBE decoder */ - push_wmops( "ICD PP TBE/BWE wb_tbe_dec" ); + ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_tbe_dec" );*/ } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) { @@ -1052,10 +1032,8 @@ ivas_error ivas_core_dec_fx( } ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) { - push_wmops( "ICD PP TBE/BWE wb_bwe_dec" ); /* WB BWE decoder */ Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE wb_bwe_dec" );*/ } /* Memories Re-Scaling */ @@ -1099,10 +1077,8 @@ ivas_error ivas_core_dec_fx( test(); IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) { - push_wmops( "ICD PP TBE/BWE swb_tbe_dec" ); /* SWB TBE decoder */ ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec" );*/ Copy_Scale_sig_16_32_no_sat( hBWE_TD->syn_overlap_fx, hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, hBWE_TD->prev_Q_bwe_syn2 ) ); // Q11 Copy_Scale_sig_32_16( hBWE_TD->old_tbe_synth_fx_32, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( hBWE_TD->prev_Qx, Q11 ) ); // prev_Qx @@ -1117,22 +1093,18 @@ ivas_error ivas_core_dec_fx( /* FB TBE decoder */ IF( EQ_16( st->extl, FB_TBE ) ) { - push_wmops( "ICD PP TBE/BWE fb_tbe_dec" ); fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE fb_tbe_dec" );*/ } } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ - push_wmops( "ICD PP TBE/BWE swb_bwe_dec" ); Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_bwe_dec" );*/ + Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); // Q11 Copy_Scale_sig_32_16( hBWE_FD->L_old_wtda_swb_fx32, hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); // old_wtda_swb_fx_exp } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE" );*/ /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) @@ -1171,7 +1143,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) { - push_wmops( "ICD PP SWB CNG" ); /* SHB CNG decoder */ Word16 synth_fxl[960]; /* Q-2 */ Word16 q; @@ -1193,7 +1164,6 @@ ivas_error ivas_core_dec_fx( Scale_sig( hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, hBWE_TD->prev_Q_bwe_syn ) ) ); // Q0 Copy_Scale_sig_16_32_no_sat( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, negate( sub( hBWE_TD->prev_Q_bwe_syn2, Q11 ) ) ); - pop_wmops(); /* push_wmops( "ICD PP SWB CNG" );*/ } /*-------------------------------------------------------------------* @@ -1203,7 +1173,6 @@ ivas_error ivas_core_dec_fx( test(); IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) { - push_wmops( "ICD PP IC-BWE" ); Word16 q; q = 11; move16(); @@ -1225,12 +1194,10 @@ ivas_error ivas_core_dec_fx( Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); // Q11 Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); // Q11 } - pop_wmops(); /*push_wmops( "ICD PP IC-BWE" );*/ } IF( EQ_16( st->element_mode, EVS_MONO ) ) { - push_wmops( "ICD PP BFI" ); /*----------------------------------------------------------------* * BFI waveform adjustment *----------------------------------------------------------------*/ @@ -1258,7 +1225,6 @@ ivas_error ivas_core_dec_fx( st->hPlcInfo->Pitch_fx = 0; move16(); } - pop_wmops(); /*push_wmops( "ICD PP BFI" );*/ } /*----------------------------------------------------------------* @@ -1271,7 +1237,6 @@ ivas_error ivas_core_dec_fx( test(); IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) { - push_wmops( "ICD PP Sync BWE" ); /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ IF( EQ_16( st->L_frame, L_FRAME ) ) { @@ -1425,7 +1390,6 @@ ivas_error ivas_core_dec_fx( st->hTdCngDec->last_shb_ener_fx_32 = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ move32(); } - pop_wmops(); /*push_wmops( "ICD PP Sync BWE" );*/ } test(); @@ -1441,7 +1405,7 @@ ivas_error ivas_core_dec_fx( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - push_wmops( "ICD PP TCXLTP" ); + IF( st->hHQ_core != NULL ) { Copy_Scale_sig_16_32_no_sat( st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, st->hHQ_core->Q_old_wtda_LB ) ); // Q11 @@ -1498,7 +1462,6 @@ ivas_error ivas_core_dec_fx( } Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); - pop_wmops(); /*push_wmops( "ICD PP TCXLTP" );*/ /*--------------------------------------------------------* * Common updates @@ -1507,7 +1470,6 @@ ivas_error ivas_core_dec_fx( Word16 exp_max; Word32 output_fx_loc[L_FRAME48k]; - push_wmops( "ICD PP commonupdates" ); exp_max = 0; move16(); @@ -1562,8 +1524,6 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); // Q0 - pop_wmops(); /*push_wmops( "ICD PP commonupdates" );*/ - } /* n_channels loop */ FOR( n = 0; n < n_channels; n++ ) @@ -1582,7 +1542,7 @@ ivas_error ivas_core_dec_fx( move16(); } } - pop_wmops(); /*push_wmops( "ICD Postproc, BWE, updates (ICD PP)" );*/ + pop_wmops(); return error; } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 90385dfb5..8c5a9e9af 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -96,13 +96,12 @@ ivas_error ivas_jbm_dec_tc_fx( CPE_DEC_HANDLE hCPE; SCE_DEC_HANDLE hSCE; - push_wmops( "ivas_jbm_dec_tc (JBM)" ); + push_wmops( "ivas_jbm_dec_tc" ); /*----------------------------------------------------------------* * Initialization of local vars after struct has been set *----------------------------------------------------------------*/ - push_wmops( "JBM init" ); output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; @@ -135,7 +134,7 @@ ivas_error ivas_jbm_dec_tc_fx( } Word16 ch; - pop_wmops(); /*push_wmops( "JBM init" );*/ + /*----------------------------------------------------------------* * Decoding + pre-rendering @@ -153,7 +152,6 @@ ivas_error ivas_jbm_dec_tc_fx( } ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { - push_wmops( "JBM STEREO" ); st_ivas->hCPE[0]->element_brate = ivas_total_brate; move32(); Word16 q_output = 11; @@ -194,11 +192,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11 } } - pop_wmops(); /*push_wmops( "JBM STEREO" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { - push_wmops( "JBM ISM" ); /* Metadata decoding and configuration */ test(); IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) @@ -283,11 +279,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops(); /*push_wmops( "JBM ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) { - push_wmops( "JBM SBA/MASA" ); set16_fx( nb_bits_metadata, 0, MAX_SCE ); @@ -694,11 +688,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q } } - pop_wmops(); /*push_wmops( "JBM SBA/MASA" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { - push_wmops( "JBM MASA_ISM" ); Word16 nchan_ism, nchan_transport_ism; Word16 dirac_bs_md_write_idx; @@ -829,11 +821,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11 } } - pop_wmops(); /*push_wmops( "JBM MASA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) { - push_wmops( "JBM SBA_ISM" ); Word16 nchan_ism, sba_ch_idx; set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -1102,11 +1092,10 @@ ivas_error ivas_jbm_dec_tc_fx( v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame ); } } - pop_wmops(); /*push_wmops( "JBM SBA_ISM" );*/ } ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) { - push_wmops( "JBM MC" ); + // st = (st_ivas->nSCE > 0) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; IF( st_ivas->nSCE > 0 ) { @@ -1479,7 +1468,6 @@ ivas_error ivas_jbm_dec_tc_fx( ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame ); } } - pop_wmops(); /*push_wmops( "JBM MC" );*/ } /*----------------------------------------------------------------* @@ -1488,9 +1476,7 @@ ivas_error ivas_jbm_dec_tc_fx( IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) ) { - push_wmops( "JBM syn_out" ); ivas_syn_output_f_fx( p_output_fx, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data_fx ); - pop_wmops(); /*push_wmops( "JBM syn_out" );*/ } ELSE { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index dd1690fd4..00be6455d 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,12 +4644,7 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - 0 /*isIVAS*/ -#endif - ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4718,14 +4713,7 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - push_wmops( "synthesise_fb_high_band" ); - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - 1 /*isIVAS*/ -#endif - ); - pop_wmops(); /*push_wmops( "synthesise_fb_high_band" );*/ + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) @@ -5529,7 +5517,6 @@ void ivas_swb_tbe_dec_fx( hBWE_TD = st->hBWE_TD; - /* initializations */ GainFrame_fx = 0; move32(); @@ -6340,7 +6327,6 @@ void ivas_swb_tbe_dec_fx( } } ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ - /* WB/SWB bandwidth switching */ IF( st->bws_cnt > 0 ) { @@ -6658,6 +6644,7 @@ void ivas_swb_tbe_dec_fx( hBWE_TD->prev_Q_bwe_syn = Q_bwe_exc; move16(); + /* Gain shape smoothing after quantization */ test(); IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) @@ -7007,16 +6994,11 @@ void ivas_swb_tbe_dec_fx( move32(); } - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" ); - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" ); - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth_fx32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.1" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" ); /* resample SHB synthesis (if needed) and scale down */ synth_scale_fx = 32767; move16(); /* 1.0 in Q15 */ @@ -7120,9 +7102,7 @@ void ivas_swb_tbe_dec_fx( Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); } - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.2" );*/ - push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" ); /* Update previous frame parameters for FEC */ Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); IF( EQ_16( st->codec_mode, MODE1 ) ) @@ -7159,9 +7139,6 @@ void ivas_swb_tbe_dec_fx( move16(); hBWE_TD->prev_Qx = Q_bwe_exc; move16(); - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A.3" );*/ - - pop_wmops(); /*push_wmops( "ICD PP TBE/BWE swb_tbe_dec PART A" );*/ return; } diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index f42bd262a..be0dd84e5 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,7 @@ void fb_tbe_enc_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 0, // isIVAS - is this correct? + 1 // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7468,7 +7468,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS - is this corret? + 1 // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7479,7 +7479,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS - is this correct? + 1 // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -- GitLab From 6513a57e88afb8d5a95ec27739fa484ad1a8af47 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 10:34:10 +0200 Subject: [PATCH 1028/1221] Some bugs in STGE2 code, introduce FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS introduce FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW and deactivate it to test old elliptic_bpf_48k_generic function --- lib_com/options.h | 5 +- lib_com/prot_fx.h | 8 +- lib_com/swb_tbe_com_fx.c | 293 ++++++++++++++++++++++++++++++++++++++- lib_dec/swb_tbe_dec_fx.c | 16 ++- lib_enc/swb_tbe_enc_fx.c | 10 +- 5 files changed, 319 insertions(+), 13 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index c76765742..3ec71d78b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -95,7 +95,10 @@ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS* / +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ + +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 59c9e2f8c..018e3ef93 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3266,7 +3266,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; + Word16 isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -3292,7 +3292,11 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ); + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , Word16 isIVAS +#endif +); void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index f1492b0b4..1e806bd6a 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6868,10 +6868,10 @@ inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_t * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ - +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS; + Word16 isIVAS, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -7370,6 +7370,285 @@ void elliptic_bpf_48k_generic_fx( return; } + +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW*/ +void elliptic_bpf_48k_generic_fx( + const Word16 input_fx[], /* i : input signal Q_input_fx*/ + Word16 *Q_input_fx, + Word16 output_fx[], /* o : output signal memory_fx_Q */ + Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ + Word16 memory_fx_Q[], + const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ +) +{ + Word16 i, j; + Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 memory2_fx_2[4], memory2_fx_3[4]; + + FOR( i = 0; i < 4; i++ ) + { + memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); + memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); + memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); + } + + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } + + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; + memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; + memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; + memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; + move32(); + move32(); + move32(); + move32(); + move32(); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + move32(); + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + + Q_temp = norm_l( L_tmpMax ); + Q_temp = sub( Q_temp, 4 ); + Scale_sig32( L_tmp2, 960, Q_temp ); + + memory_fx2[1][0] = L_tmp[L_FRAME48k - 4]; + memory_fx2[1][1] = L_tmp[L_FRAME48k - 3]; + memory_fx2[1][2] = L_tmp[L_FRAME48k - 2]; + memory_fx2[1][3] = L_tmp[L_FRAME48k - 1]; + move32(); + move32(); + move32(); + move32(); + move32(); + FOR( j = 0; j < 4; j++ ) + { + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + } + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + move32(); + L_tmpMax = L_abs( L_output[0] ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; + memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; + memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; + memory_fx2[2][3] = L_tmp2[L_FRAME48k - 1]; + memory_fx2[3][0] = L_output[L_FRAME48k - 4]; + memory_fx2[3][1] = L_output[L_FRAME48k - 3]; + memory_fx2[3][2] = L_output[L_FRAME48k - 2]; + memory_fx2[3][3] = L_output[L_FRAME48k - 1]; + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + memory_fx_Q[0] = *Q_input_fx; + memory_fx_Q[1] = add( *Q_input_fx, 11 ); + memory_fx_Q[2] = add( add( *Q_input_fx, 6 ), Q_temp ); + memory_fx_Q[3] = add( add( *Q_input_fx, 1 ), Q_temp ); + move16(); + move16(); + move16(); + move16(); + Q_temp2 = norm_l( L_tmpMax ); + Scale_sig32( L_output, 960, Q_temp2 ); + FOR( i = 0; i < 960; i++ ) + { + output_fx[i] = extract_h( L_output[i] ); + move16(); + } + *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); + move16(); /* BASOP_NOGLOB */ + + return; +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW*/ + /*-------------------------------------------------------------------* * synthesise_fb_high_band() * @@ -7396,7 +7675,11 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout ) + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , Word16 isIVAS +#endif +) { Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -7431,7 +7714,7 @@ void synthesise_fb_high_band_fx( /* for 16kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1, // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 @@ -7445,7 +7728,7 @@ void synthesise_fb_high_band_fx( /* for 12.8kHz ACELP core */ elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1, // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 00be6455d..c31008f5f 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,7 +4644,15 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS + , 1 +#else + , 0 +#endif +#endif + ); /* add the fb_synth component to the hb_synth component */ /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ @@ -4713,7 +4721,11 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp ); + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , 1 +#endif + ); test(); IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->idchan == 0 ) ) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index be0dd84e5..30be6bedc 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7332,7 +7332,11 @@ void fb_tbe_enc_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS + 1, // isIVAS +#else + 0, // isIVAS +#endif #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7468,7 +7472,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1, // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 @@ -7479,7 +7483,7 @@ void fb_tbe_enc_ivas_fx( { elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1 // isIVAS + 1, // isIVAS #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -- GitLab From a92d246a5f8be1868eb1bf99fd1264670041c5d8 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 10:34:50 +0200 Subject: [PATCH 1029/1221] deactivate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW to test old bpf --- .vs/IVAS_BASOP/v17/.wsuo | Bin 0 -> 29696 bytes .vs/IVAS_BASOP/v17/DocumentLayout.json | 59 + .vs/VSWorkspaceState.json | 7 + IVAS_cod.exe | Bin 0 -> 6157824 bytes Workspace_msvc/decoder.vcxproj | 344 +- Workspace_msvc/encoder.vcxproj | 354 +- Workspace_msvc/lib_com.vcxproj | 680 +- Workspace_msvc/lib_debug.vcxproj | 240 +- Workspace_msvc/lib_dec.vcxproj | 710 +- Workspace_msvc/lib_enc.vcxproj | 742 +-- Workspace_msvc/lib_rend.vcxproj | 414 +- Workspace_msvc/lib_util.vcxproj | 312 +- Workspace_msvc/renderer.vcxproj | 358 +- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c.bak | 8216 ++++++++++++++++++++++++ 15 files changed, 10360 insertions(+), 2078 deletions(-) create mode 100644 .vs/IVAS_BASOP/v17/.wsuo create mode 100644 .vs/IVAS_BASOP/v17/DocumentLayout.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 IVAS_cod.exe create mode 100644 lib_com/swb_tbe_com_fx.c.bak diff --git a/.vs/IVAS_BASOP/v17/.wsuo b/.vs/IVAS_BASOP/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..b5ba4cc2e3848c523ea1f3f0f636f280abb28b55 GIT binary patch literal 29696 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 M1Dfdoh($ literal 0 HcmV?d00001 diff --git a/.vs/IVAS_BASOP/v17/DocumentLayout.json b/.vs/IVAS_BASOP/v17/DocumentLayout.json new file mode 100644 index 000000000..f96d16342 --- /dev/null +++ b/.vs/IVAS_BASOP/v17/DocumentLayout.json @@ -0,0 +1,59 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\work\\IVAS\\src\\IVAS_BASOP\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": -1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" + }, + { + "$type": "Bookmark", + "Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:130:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:132:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:131:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:129:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}" + }, + { + "$type": "Bookmark", + "Name": "ST:134:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:133:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}" + }, + { + "$type": "Bookmark", + "Name": "ST:128:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 000000000..f874ddaef --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\Workspace_msvc.sln", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/IVAS_cod.exe b/IVAS_cod.exe new file mode 100644 index 0000000000000000000000000000000000000000..aa3ccb696899271daeb2cd4ae2c93d36f6022116 GIT binary patch literal 6157824 zcmeZ`n!v!!z`(%5z`*eTKLf)K1_*F~Q20qk1_nO)U3?5%IL|8XVDvew7?P1$tWZ#t zpI(%htB{X2XFEIVzDbC=xbHuhEPO)J6zf%O5{^yhmmjC7C1J?h`S=ivW^TzG}os0}Y z^iL-bgWt|UnaLR-v!T{uPywzC3_gs^3~iGC(qWPh7?>Hk8Tqss6ap9+MEJnM2R3Ul zFbFU(Fc<_dFfcek*h~xzY+zXg%@7a=2}}kCP`EaN6@v7EG=pid2vipXgG+NXgAJUA zn{hxtnjr+YGy{WvG{{v56$Swe1&jzTI!mu4wW5T9fq`8v0OBB!UqOigNudG*LxNsW zN@7VO14BSGH^lET+zbpVpfErvbYNg`(1R#rVA;;Zz%U`2fuW3vfuSK9p$HOc2T%k? zIRhR7q1|r+yInatUH>%J{sE=YdKoB#zom?kfuXtf4+DS8AqED9ml;e93?MlL28McF zD1*O6n2CX*+xJi7OGW_(hECr<&9#4&_}gtjqM?8Ot4zHhlNL1F>pAtUVys z3=nG*h;;?TS^;9c0kP(RSSpieGrXJvVwr$gT_9Enh}8gMl}w(^@Vaux3=mbcV*`lF z-f;v(rR=x>qGETv0a0N)1g6Ypcd5>x?|0h*$mxJV-KfISRm-YAR_3%uu9N@ zVT+&x!#+U=h7*Dg43`8Q814u}f9;3ee1pd$n^ z*G$NP!2!w+5OiQj5p-b46Lesx5OiQ@5_DiVbLPyM(C#@9}4K^=;Z45VCnQ?>2~1gbm9QJF9xI*?1%)2BQhb5NCCAbz~UJU%}02w-@KSP zOA8!1AU}fq-}okniGd+3ym#-EzyJU5oDE7lAi2-07dqUY!(e>0)AbMkepim>AFQ=1 z84u>oX2@cC@r6qVGJ(t$$`-6Xf=nt^Y7cABn z_`C|G*a^x3xje+Xd2^c?hJav-QN^|Nk5J zf=Cud28Lp$*K99rr)e=v=@V7RAizb0%js}cSH-!G^cID~znZOd*JN3ce|NnztoChoC*#UOM39uu2kANKk zBH@nMF%{&9sUWdqEutW;485%&D&R#f)DbcuNA!Zk0$;qm33Wt?M1}%L9BSJ|n0P6F zx2wQ$2NO^XzC6Lez>uK=QU=w&3Z|??B0~ct4%I#hCJxgMa`nqjkaiuAGN|@!n6eUy z3=@zzRC_Q?yp#uGI}-x~!)xCR3y>P9UVWIF5{V2OkT_JYI7}R-7nH_c3qqn*0350v zES+8!p!jb-#FW+<`s1a6AOk~&1IQ3)++4Z=4VF@gv~J%YY0U>2L20HtRN$DC2jfcy zka`y+^^0KY`CIQYFfbtN0oemjXSKGyy;uJJ{~ws)Gk-P%NDAa2o(X|3CYXVeDo^Wy zdY3d^C3o%GhcHdWV&4ijyc#cHtz)~WhfQu_7ynhXv=7PsoPZ` ztuw&xbqGX?xkdrPNU0ZxsA1?16-es_Tani3WcOOT8|tEf`QXg6ogJEa;!MFVdT~t% zoOuF;7#Lo%3otNb%m8^Dny^=1hX)kcNuDTve|epsfgxiBlKM)Rdj8gOP)!6%7u~)B zX`PM%$X?~&@A`v(zb{AgOBU;c{Jpk}3=A2dB#snfuzax{Y$9sDH~`KUAQGeroH-Xv z0_O{m7<#@4^@L>3H6V9FQ`g07Fn{rMhYB2b0yn2$n`CSNse$IFwMc4w1&%w0fIRbB z0OCf0ZeN~mk%^rFF=^edKhl~HFs607{(!~)7PQ!(WC9NB<{yluK_LBz1mg^eK88{S z+}jRJ^%@^2;>lZEd`2sNL;3MdZ5a2fpZbqeJ@@37#K2kfV=@M-JV^AdDQ@% zz7rTT4uFyZoow9eKufB*mI-#-;ZHUDC);o;v87Ha;%T&I@t2I4e9nA3I` zft~ikKmeRdSMxJ4yf)z9-wW3Lld*&cZW2?eM25tI*$i2XFD|oy?Fx8N1=0OdALN;i z1&G4=;uTn+NF!%va9ZF2l}0cB@GvlBOhD2y53WT5oYMptk>ls(8IbxpNb2)o>iJs@ zK`mfV65;_BR>;~wA%~O^M8FkP=nrr$kbQyyRC)%-)dR1Q+ef$Fa21B_5k zCrcMNXJ*0#KsDQok1pUe&%f&a4;j3uCOVS2Hf85%B0hLBLb#Rm@6P(B8R-l?FX zCMe^<0#L!_`U4W5K`*X@mGZP6sN+G7R%o)VSIc+;F*_b+HXB$2$BR0M**|$17+%{# zl(W>SWk@Up7efXx<<|`$PVt8*KLt|G2g(55Ub`UOcu0WTIpbxA^W zP2pu=Fg}ph>G}m!r22k=7U*C2_lJJzb`{{??;&D+k-v8d1E~H-Y8TYzWYjDK`4`?M zc(MHwG-Z^?WVE2k&4$U93i9vw{Q^oYE?p9!s`IrdG$uiU-K9L;ENz`GT_}~yYn6;1 zh%ZcFzPPOq@p~{YI2z9JFfhEd{r~^}%X%&bhKvIXXTuv9iZGk`TZ{h( zP!kcgWbuY35O8{MbVj6y5<^&Ap8)$05!bK5?g7O$A97s3)`L_`|NsC0pK%7_hXO`u zQW6L2;ds%{1NH+K4+8@vvKeZ5j<@dk`~N?<*yMt+L1ERr7bMD1%5%JR%U@74m4N|N z^?}$RrQN;)T~k4vjz9@WJr?l7=ng1SSUSPg8l({H?A`G9|NrK_Ad;~}1j1k{5r;6C zOQc?_fa1pql%*J6+ki_*5m3&4Z2%525l~iqt&+j92%H`lFhKp|t_O*e{oG*xSaCBj zy!^nyz>uM{2oW8VE`ZzvZrg#nZD7NBSiz+tqBVgM9sIo~!HEx%(EJ<`QBtasVFGc7 z1k4@#bs_FBhqz-C7b1%mECMB2M6{WJoeYXLlq?Dhr#0Yk0+Ea*+|7GI45kvk*Ahs< zV*vI6BzROZN+3?@{SWdaOTY^gs8iN(frCVy3zUn%Eo_eFS1i`2YUMzQzuQ*;+^%lw zbo4A&qfRD{U8&Qc$x%gaBz2&iDgqk#d+n2P2doZZwLOwLu+_q#HnB>^ z3rN^8`~!J{CE&$!ZAjS3bAlsd76)o+@LDB9XE8WMpZg2dQ3}=ZmIJIKgM)$Lr5qar zLq@`4P&z_5RmTCGA_HD*J`2(c4*FJj)x{1@-l&y6Ke!FY3TnemWI!a)9I(NNu$l~Z z0Y(CamJ{^~83hn0OT(OeNDJagD-H&R39ro|3R&s}(CP)bj3p3_kN$uh%o6aT6RMFB ztWhrG0!020Ogw0F`R5wZK_S16%^hWw0y($B`DyT^BVW9`*#e%lKqkr!TlB3;hD^9DL#5@A{?N zSAc(iposM${$9`!42tt>b24&W9S6W}!& zIB$b0PEbw8)7R-UK?1qa@>(v#2IBs#-ykbk0$vD0-QUT^z%b#Z^M6na52=X{Dj`4) zgSVP}khAk^xr`Wyc~UU*4r)Nc!xC&>0W$+bMg!Ojh}2qV3r(%8Fu(A(Zh@y(Q1=Si z&4|FlNUc3!gAsB46l^y}TtgBeL%l-A1c+mEe?dJj0@lFsqKB10YCQtcXaduCTOH!d zV6aBHj1Lfb5t#gLsJt;q9^nIUYWoSA&F=It#cITg1%3V0rW2h%lm5tT7oKAZ^gD z`oH5KJ2+Yol!}5o1R1D`^+8o7s6W9oAuwYC#96DqgS4;&ya)n2i|55DCUD@oGBGf` z-2DcWiNRjvXnw(DeW5lOxkcG;0nUDq9)=LaaCr81c`XS_uCP8t@fWZ?-M#{yjt^TG>e28M1|fzAL9 zlps>cxB@Z%z&EfH0$!v;&A-nG_G%PpXf9NMf18s*>w(gcZeM}sN*+c~9+-iYML=vw z76G$B(xCB5kPxWp3Sxt@2>-UJAZE}DCMS?5Sil}O=?)cWtm1HxXJ7!wOml?^Lmdye zB?2CGd+h*G&|rs9zz9mvWK8R6hv!Eny z#S9IIQK>Mac%VkLK#XGAz!=nhHlSCuLCb;Rg?)<_Lqt@3T(|EZ$XRDS2185i%#NMFgzyRu?g8DgYv>X^patj!WK}2Fv zdRcr)etc;`L240rSRFKe4920|Z!$taZe)CM5Ry&;USueNy_+!wBEAwP9sm_z0}-DH z6SshhAAyKh!o(Gz;vXR5i7;^vsJO>+@JNIwO#Fi)#NHJUaYLB+4XF4Jh&VJo2fR1{ z6^~c}Hir?Weg#x~0Yv=eXJ|A|fQoah1gpOY6R&`ZXF$Yv!o(Ax;wK>D3t{3OP;rA* zU~@WQ;s#Lh1rYHF-02TiL5q}61?|_OMtOc8M5++^%6|aGaZ-j|QK*iTU#Am|99iZY5 zAmWWMaSf>W8;E!&Ok4me{sST&2owJy5Ako#I#v6Jg>UP;mo@xF<~fgB&CrW-an0NtH`~gIKBTPI3DsHeHY|c!WxC2x?0V3WA6W4%> zZ-9tr!o&rj;tD&!<^;mTf5<@mTLBTbgo!_Ziobw}E5gK2K*b|=g3aNCiEn_4uYibu zdKZ@dl{4#xAfq2VvqFQ1Kp!_)3^~095<{M0_Gl+yW}ju^VhoB}`la zD&7DQPlSncK*bM0#64l+AEY7SV6X>ljv-9^22{KPA}$FNKL8a!01;<|iLZc)YwQJ^ z^YSe;940`;8zABrVd51~@f{HHoiOnPsQ3$r_(GVt2SnWZ&5L(6S`4v=!4)Z#0MAzo z>;UmPT|acXe(7}m(dqgJ)FQE9;BN)ZS%M~vyF&$nGT!W+4VnrLc;OBN5G499N-bS*Ly$%NrKI<7(vZB0g!<&ChLRSni*gA z&SvNh{Sx#-XfMdyptdeww<`~5D2IXJWh1B|{R5-~G;95S4@?PncPP(s(7FhQ*NGW_ zK=Q6%0$!X)lK15~&IoEqy>`rC*ax*@J(4`g3Q*(ZwPFUxK5+A?@D0dxmVg%$Qs8)f zG2#3F|3(L13%=$>aXzdGRATJF@WQ4V)C6iiB4GXI#e`}|n+Mdut1)(9`11e%e^A?| z!`K1Ru7Ru%2t4izUJr2G^$)nQ$=U7tr}+RQWYG&#t#-FBM_?9X7E5<1Ptc1R@VK%7 zXqJg(1LJF5aIl6$=KEeB%ZPwDecNlO(_`f&(U+N`~QDuod^R1I1M1r(I0dD&3L@E=Kufy3?CR6j<=S8SPURm2AmZG zXNAC70dSTFoMi)NslZtpaF!07WdLW%Kv})69RV+v-TVK)`3TDkISU4cUf+&DP|)yi z2c@u{`yd$}NSB56fo+1M`tT2Q8e!bkqo8k-M(i6 zGfF_lF}+}g8Mg*v+zXX2|Nl>TX(t4VK9I3N-C)fDFHZjfMKA{>f)%?%&je+xftYdd z1=PD45Hnsf2r)3gw3$Gr3&D0i0I6quF%hQT0;2wSD+@G@b%*ZhociM*$TJ5R_*+10 zrZWD3J#!%7MHILf%hA~iO4rSMK_u8S2Ldw~rh$`=1_9cGdq*d&gZ zXBa>s2U6SFsUKeHvOa~`EewfTQs7!c<4n*ebGpOI@KxJ$*d>}HnVKPln8Rd)&kPOp{ zgD{y4h|G%zA3?$Xiysv1H#(<2`S<^Sx9gqG))yd#?}JY8Af43$|i9$O_*lff;8&${1gm!<5|vW#uD0 zuLJq_gRO79RN~gW7i2$pYD{6>|Nnoc&jwG8f!GW)Kx2H6^()=IAd$cfjv3&fdh!$+ zAl+ai1;7z#0ynml4eSr)3?GnkrWadb%45LFIbK}(01AtDe4r7ODV?n{>;C`m?gf#} zFBv-_jJ+T(JAeC0&@jtX5a++j)B+y|2L5fXGXnUx`OXP!e#6s!rMndrlATQ5y&#W( zR*8XK3|=U9B(NKtaf0}_x$X$)?geGt!0ylqLEYf$BH+avaD}9UUI_PsO5?y6eBil! zmVk^Jh&SFnf%|Mt*1#8|o= zY^eecOEqDZUVvE23A1#AAjFd%AWIVUNzF(A^7)%fJ^Guv<43ly-t%Tmny0vjk*> zK&;#J2e zgc^15kYtT%bne zjenr}g@K{B6~qeYh8kk64mJehCW!w#r%J2?EeimV3?+PxdqE7&00xE<>(|!ZVC~kf z6H0WtK`q0nAk)CfD8m9`|I7!_z;XcFFY@vRCj-N4{nxtP(0p>^0;tMm3CL)GXvlzR z;0J5qdAXbuGBGjr%)kHtds{&yJPf_T^PsrGuoh-?55#C*n9*B!Az|nPGWtMTXX^ow z(Y+utuzM;fJcC{|s38XhxCrZP6#)kYhy(`(m;qV>@BZ4Ie?M41X!X>;|NpH|l^B9r zcTiDKl>~BlP{s_1Q=0BWgGCeU6p@z)IiSG;wkhDn!Sm2y`2x`p2-ENbv>xOL&&vrM zpoZ%eh7zZ4-z$MH93fN9ovon8e)C=s393#(jZcQz;FQ1*GhrLVgco|RK(&+y*qkZM zB@)fGQ`k#{K+RxKn_FNVB!#@@;@|H&r?VBrPwValQ=Pp#{{8=N44N$hHr=J4pq6uUP3r=Nl2}lCxjUqHLC}k3rl62z>1^d$2bvIZZRqX=u{wKN zLEV$)y&w)lsSZD^rJZ2|@qphwXqbKF21nnE+?OB^w6ilXysY^D|9@}q2GHtbSY=cX znL&l5WsDw(AUNf)1Y}e|4F7l+YWNI@;V%u?L5niLMqYdv_~PMuuzY7LsB6?ab;-Z~ z|KZi_Q^>3$x=qjoz8pN$%@U9?2Vzq@%qBgkO~=?kHD2h&)=MRo{QFx$Mz=fkR?L_FUr8$I5Pe~#J9u5;~?U%B{C%D zfSXZsVKOcd8PL=dL+d5}mVQ=H$pf-2fPXtUhy%N)f_xR!-3rQm0WTgYV)Yd?NJGF; z%Mt)C=v+XSF}*N=S$3Th;;VdCPz1JuY-v4E%KB0Y%Mqm@fs(KBrEYNar*(>WyuJ+WTJg6`08Jc28(&jF-L0S( zli!1KF9*CIaV9V$1>($3@X~mefENZ}XY#x}!NR}*tCFD2wx^I8HPk4D7ntGTxoDPv zj2RFU&0!|q1Lfo+JTJ>wKr6;T9U2DymgykJO$GI}f_fnpes?cOD)2@9TaX)h__tkX zy;Q2$?Rp>}V-Li{r{IYF>x}? zM9}(^<|8~WFENAM2yXQAx9kDAu@}_N4eXu@5(|1EWC@CYjDj6%d-ur zZFW%H^Smqu8UKc-`%E{uC(tR_4ep0@I^;C@_1SPcY zmZ_k!FW`liAr^l-ff8T$lwOdMpcm%mASEmTuq^Hlb7BF+iRv&Xo?`KE?#$p}7Z)6{`4l{v4QjYUY&Z&Dyw4KwA_r^(&r252 z^!7hc7amga@V9IO^=W%SwNT&-H!HA%Q4Kc)jf=p%&;qmI2*iREm<8Nm3j|&+2DMwE z#$5*|4VKPU9ZZsiDd0snq^yM&{U!X}y`b_w z@I^61ycgOJW&saau<&nl{oQ&1)R+Q|^MV%pg4Q;G*x&)oRuBs^p&#Pq!0;k31vHus zo6!G|qQ%g71Tj}+i4ru{9q8l0 z019#t+ug^30aTZQ*w#J{44@DLu?>A37(ku`vDJJW7(j&zXa%LTj{^g!Lk|+?^KoDR zRT&`m4{rwsP)8BOe&_AL04kDclruo$ zDc%kYpmGbempj7Sfg!Uv*Eh8!5xgrpuQb;wv!s|IDYGQFq$o8pmm#k-H#jl3ASbmr zC^az!otv7M?2?+3Sm~JuRm4z`oanwRXE zhb#b50?`|kSdz++oamgNmzJ5%kd&C0Ql6Pol7V2k6(#1TI_H<>m82Fil;oEr<~U`R z6oGVQ7UzOoms(WJkegVX2w^j1B|$|Q5=&Du^P!>{PQ~FxnII!FJj)V`UGtI|5{uFq z(k5hEI54zYI55n&aA4SJ;lN;G<-l;l%7MYc+JRxMwF85ijRV6}8wZ94TL%UfTL*^F z?l(IGB<8_qp+I~NRDQRsNInke5DUD2d>WNJDrH9mh>G1&0;0lp%m7jTJGOu*j~zEal;e&sAj)b7&*9k& zud(bOmjQ`m>>t+viL&l6IXs&IvVZ)6zXL;vzXQW7e+Pyy{tgWP{2drL0vs5G0vs4* z0vs5w2RJaOL1}{k2L`JE2L_h_2L`_Y2Zo3M2Zp2o2Zl5L4h$0m92n*YI55QdJ1{H@ za9~&);J~mYz=2_RfCIy!00)MX0S*io0vs5+0vs4}pyrhYI50Fo*%SO77?$`uFs$=; zVA$dBz;MW);QsOES`LO%t{nmb3=A(N7#SF{WL}(`4{qgj`*L(Lg7$J-ffO(pFfhFQ z4r<@Ia&#l@H1B3Q=D-2k#N91;%!v~;li$s8%uxumL%f?Q;Dr)om^$MN0|Ud0Qi#Fe zVvVC)u-o-VCsT9n4~9~q43P0JSivKtEH6PF&n%l4ZZPFvx_v>)nYw+ybaFJ;eqku( zhiJG09wKLXozxx5(aqG&(dqlAJM<68UMt9OYPav7z!!Y)L9Jkx?$AHSog%<36xTn; z9TLDS-#^D2-+)*kpN0N8-t+>>0qw2)lh)~&@j_k-v}FvkE1fw8sT2bjwO|5V-eTXM zk0pHb=20(v4?+A1313l&!8pTrDR?*-9=^}!g5A*xTCI#dd`lo2u!Qd|@J=5VaQLo! zOHuglmq3K?;wW6*P{cKm6fNo!jK+qzVZdaZF&;pAW#o)z#3gERae;^AbE<|E_37lRe zz-uEqU0-y%zCm3j!x8Y}7i1W()Ab7|y@R~=IVjzFPa*B1dVjKP!EKf2F! z3v>#02e5Pof=_F3&_~Rubs03o+-|njr_~Lt?KST2o(7->}4h~T91gcZO@dyfD z-#^`g$DIT~i)~)iih-sK{&aJI2jbE?1I1os!GzMfLlx3G19@IVpovJmaD$8RZwpmP z>kL!@hX?;QR~6987|!FaFF@(%HT!W_aH-H-`+}jA^SCR>9Sk7RCm`u=UyiQOC!j5e zt{h#yA{`z=y`gV{UfcwCm52>lYw(nt0x0LY{%Ae|YA4PJM}#cl^l}O^a@gsL6qv@a zz?2Dmv8op>FhNy1EHL@^`zmz$zG$v}!B}G5T>FBlgz0q}|MpOspe&{r3_DCf(a;SF z@U%`R9&pM7Cp&OJGm0`Wy!aym+RtLkzui?PAdB(E+3k3>oD*SScySV}g=+^pC}u(D zL3D%al}_J3V0*!q@NW;~33_n>Zdh8UV;Z=4Kkgs^+G7TBQn#y2TBnoLiwcmb#ULUN zWOT3Zo4^+#;CbsG-B&OVBLQVx5!B?p4ZI>x0g|vK!w|s_THnoyAw~q3tzZ?P!zo2gE`^2 zg8*pv)Qi8MB{Jaj0gH^+LJSNOz)^4!JS$9W6c~eB01C}VM6BPum=*$y0&x1r9sXw_ zBZVl5e;=YAfD{+U9R)yLdTZLc<}|ab_P@)KnmD50WU6rr;Uj% z228;18F(=O3WSNlus{H}G#~^xJn+^ZyC6e?C_w^R{Rplb%1`>!oJHTvk=!m^|F2KO>;*kJI z5j!}WzxM2gRjJ^lu?;+lj5TRsseB~BZ4r3bfI91?LC~-v93HD6LzgJw0dCDgnhNmn z0PXmFp)0_^unUw}An_{pLPh{ov4YCT?$8&_uh<|V#ar&%?fQa$TgQu72ZsMDy%%B~ z7{HB81yCFEwRtzFnF;DdF}&99_Wg6*Q2`V@piMe|jyoxUYOdG95H%pXUbF9D6<}a^ zodU{ufeJw{p05NYHc-|~>vZIKF@qme7C@UM;P5L0Pb3o?emB6&?@+?eG!PPg6Qp7t z7}R1N7>r^a80=yl7`$Q~7{X#57#LVVfRUAnm6?^51(NnaWN7!B7aE}0tK|SUyEvLH z7)n`RHpB89|28L3y)6VyZ2>QSKLIxpUt2>(nk^Vg$b_6-Nx#Z(c+PfQDs2P6cDU=>xiAw%e71 zf13wK>&a5C9n7Fg3DjYJ;l#(l@WPglfgy_->Nx)GfdWAEJ#%0LP4 zCFneWEV01P`~t2zpZNt@R9@KFnS%;Xx_*Ef zz~*B{M$o$KviX4ft+QxG#bSjsiT~yFtO;372382kvWeaPr#u1+)&Wl&5tzIf@&4o-l+Kfqy-2bYY(eU!-${{0?2))&DGd%u8#)<=M^^<=3eI5feV zU#E0{qAlnJpA{$(u)N*{?o<_k_hYfV@Ze@(c;O5p>_CJiHz?cv;NKsp*LtbMDr15% zC{TWY^C!$brFt2l&5PZkKf0Yb0$v=0`L|T88?>=DkgxSp33oSWi>8M`>&epc7f(Q^ zmw-(Q{Q>H=Pl4$uG0I}>hI+RiE+~ssA!WU22Q3r=t+?c~VFaD22I{f@Nb7Xedy&fp zn)iqFdJJB~gVceJzvEJdIJL8=wAUR>m4V0iI{6O?#<@b7oh zYduh^1okVWTq$aVMLbWp>yv;NM%G}zft!S&6TmvX^twT#!W?PcfjnuQ0S2I~<-p1K zq7r0o35dw&1o^QO#BAXN9cLyFj=AnYj-VIDO;F=Yq45Ap63!U`@nH9WqM#A(0G)2% zAIBL%QsCA;q%O~~s9Oo}nVvO!8gIXZ#O0#uekni(-KHgbTR@`r!FQ%v>=w!jyT5Ivo)4?t~W*9VfSKXii*Nc1QH z9d860Nq`D<`%I_+w{@})F?9Pd3Umi5fI43u5uhcxp?{hWMey%;{Q$DnrLkfssG*X5 zlA+s$L!jG3p)-&N$&}_w9)=PVf zk!~jikjn!jIs;fhv3no_rmhF7F7!>e&qR^#K!r{xp4UrZ?wisGGNrjnfT6?$Rjk`d z0Bm9c%)|s#6T1TiI-Pi48vg(P{{+uoW;=X z`y>!tVYod2Ri8ZI{QaX_urq+=#b#Cph6!1WAR$l-qNEP0kG};pBGDcC1SG@J>1FVu zla+x1W`jh)3oW<}p;?TO>W6(5xZq0bbQJ(OWWSS0>jBVk#tm?5mHoKu4N$X-f1B?O z(9%+YAjqKB4^X)QN)a8P)=J=uiQvW6A`lbQS`UzxIvmBp!1BO`=`Kl;2!WY2>8GvxFG{NvH&s+mIt25=YS0FeRPEw0d2`Z zD0K63@S67yvR?vX-a=x`lfh!15_Fi72Q*A603N0k0S{Ah1iUx{cCi4&2762!K<*7g z1VA?js5$co+-g8>5zk@(EzRTsO$UJI3qZvPxOWU{fq}CHM^F~S3%LuR_JqL9ot(A| z4BvkSfUA$}Pye#mvp_?%-5wl)FIH^=C&qvmA3=+Fj&P)PPjQo&IhBEb`=NjrwadYh z-M&0&os2K$gKCgaP!Ak5$jZaNT`=f{G_xtB(g3TdWde;L$3eW8;DQ+;p#Dk)$RbdG zg{`@k2XqQB$P1vuc0d^v)a-}0Iwimjq;8JxP@c4IN1n7!rWdkc^R3^!U~z#o8^QC# zX!J!kx)5Zs^-@Mr43^50iTEOjJ(D*i}OUS>?71VWNKkoVm z)LR7Qyr-y}D^L-L4$U zt~{WD2iHHKSwy7Z1&ud$yK*3m1ovNYjekLM>ziKJFW`~-7w;j(39J_e%5pD3Q>Bn2 z4mmmlL|){8s;6}D*-O4(T2Gc*gL3g3NZq7R4y|KKR6*_1H;{HI7hIGd+z1Dqp!kCI z|Ns9Jx_#g9?+@eywXCc!lt^^@zDes2{gT!h2->WB4AeBe_wWDz3C0H?ks6Zc!0;l* z0g?tm16&&%AW;cQ9x-{4{jH#spONRlke6ES1YdlD6hPqcz?J^Mz41=pH{GFcK)tgU zFY5mN|No*AM3npkEzI`iX+2pY32D=V)PVXhUNHZaDtCvzfHcfYtRani-xr`d@WuBs zSimTQx*9LQT@5DC%Hm7it}j4s@fTnI{{L@$;H3*_d&qu}HT*5=j0_CWu``ewy%!h$ z{{P?W`vW|0^x`nMkI2#K`k}e@19&Lq!%H?s28I`>{(`odz2M*OVFap;e+0egD1};I zDhnEQ+U{Whk`M`ckq?vLZvh=!333bQq~cBwqZcWE|Nnnc4=LtmtII~jn7w)TS6@Pp2^eUaAb zrT1bDNC1{%Itm;ZUTE1tQVb~b*V#c*Oxgrcnwd}lDYrmrW=;V(&A6o|d*-ENCMTBU zLk@ZYrxyk2`2B-USL{<#kck=@-M)bP zR}6HHPV31!KJa?IA1~hh26?$G19VOgsQd=ice~)KRY2{r&>ulBz8675xiS$I_307rWtl`N89_V8@n$^uCzz`~UwJ-M>KzJ@iNGrP6rN zkis9x2$V}P%t}vCTM<;J3Ix2+gNqtN-0b@YoZzp)#gQB+2(sig*A6z&0ER4RUV{ZJJ8464D zLF?OI?D+Zre+I)BM#vJ2z!x{*)@y*`k^?eTV+0o!$^b>ti;X|QRo=@^P^nS^Hsb{| zWW7eviz#r`8d*%B=H7M>p1>FH3Sb_Cnvn}N!xdzP0oaT?tdQ~9fENKsW-xdAf~KE% zf?ljbH$xL@255%&#hV}h|7Qp|Fu?qB2d*0Aj!>vy(%_;{cRc+8@ylM&Vv-dgGeDyg zpu$8j=*0}UYE@8j;NS=QMF}p-4+)Qj5Hnuayhw)|02+b~co7a)s+z?D_sGM1SYSX6 zNPrq(&A-hRv<+V=gW(rwfCW4vy%=Ifw=YLpr=!Y?C*MIO0YB(4c8;{p0F@V)K?2|= z;7&_$%K=iUfzF@OjOhnO0eJq7CkR}Lfpg)6AK=Dtzzg;hP)6Te5ChcwD1jORF5fWE z+c@qDT6O~oWZ2Re&=fPcZ^RMwV(E8KcygdDGVtI8uZxfXjf8;?oI@IU(s&{A{r`Xd zZLX572TGKXBy>RaA!z7L>&2&U|Np;u`wisnFp#%@q;&@9yto4r{r(M93h;0Dl?r?j zod*k5wX78W?V(aZFC^eX!l10w?JJem>7n&vA=oUg9iWS1UakghCIbg2$XtyVEg(tI zKvJkcr{IgWZ~y;i@PO7hxPk_3Ubw-d&c8eK$8jdmNi5)!7F<0#nt(=hTz{l>dzhqk zdYQd&2RYIRMCg9|{~yx9}X`~qrNL(0`Rxlr%$xA-t4`r!fr zFD@Zuj6fsNzCS<{7cy7CQ#&(S50n~01`17DFO`TuQt1D$pjcsfxsRQJ;WaenzlMsf z0u2N+fre1QC8-O-bWp1S+|dFBUT1(Z1p~-r7P!e1(anH_$St@q)Qq2BAfd1Wbp9*@sK|m?_7Gj+1*pP)HU@^5XFwGa zGsH51fEOxo#af^Yy)6*5pyfxvi#6cm5Kt4oKS+NMNIwh2!vaAso@7IVp@j8iAxMf9 z9`q++Qv5BTZtx4qFaQ5%F+ptR33#yzCS8&RYDNFx2M6F0xM&D+0OrD-DFPmfgGS+t zrJxfZUTZ>zXCdLV32uTAbXXab@5EkIft0>H%fP^p#SU?VK)?%Cm|}<M*kv7lsF zIt7#rIl6uSbT)#88meTrYC}AgI;_!0rk3hK(k1oAu0at9%6wn zK4ihdNFCy*&<{Z`X2WbQK}~U&KY>aH%`6VM8yn%;g+X(qV0VB9q+YB5D=h})Tqp24 zt{2ljfm+wF#M|)+?AGQ(YM|LDP#Zq%38>A$!M`80Hw2oDHhqF5qe2#Nwsif$zuiM3 z@C7&ARw1NJ!}G!zWa$gvPyheF@Bk6cpJ1&%U!Fijc$RoVnhT(_bOhjDHGwoZTzLXs z{Dzw^4+#{I_GfTGt{qIE=F=Tei2#~5;^}nacyavW|Nqc292w9UjskcLM+G*9!|@s9 z69JUMdNwok9ve^tq|+-hb|3%$hxC>pS@0d)RB+1!G^VK+@M1>>%q}5t zlN9Ep2cR<}K&?98KWW{8S!taCIWNw90QGKuG*<{PlyL5JIXs)8^<=4dMimR_tm(tE z88QwWp3U&$nlNb1JkN`LAO8P;vGW6p&#GXym2yLTCeeDJL<`bD2hAIC1if&FJ5wkF z6x=VCeE@|Z%gartta_gmVvSqV&s+yW-otB z4@d@4R_sWJ`CloE2^XgL>FGw2TqB=-fHw!K*2AV|% zl^+5@FG66VB|;hepyd^p!TT{;UQPnF%%;8n|Nq5A5Yh7<9KQVfJuF&JmSlrYeFDXj zK)?$jm&a4Zvk+vz zK)?%sm;#vn=iWi$6?8HJctL9JTF^i`3(S7jZr3lbi(x(x2zbE@GoeHoGNW-3ymHD% z05KC1%F*q@DA4J|@|p{LaTTcA1h;s>4FhCz&1QJfBmmA+psw~0a97*$?f?H1kXuax za0668(_~EG(ju+X1JqoCw4q+`g4`eh()d~sl(RWN9p6Bc7hm6i#)H7~yJD>;>oh?P zET(`LdZ$6v3=98$&=n)la#;$zNtfj%Gb01T>%#8PA4uhR-#t(vgj$ZjdIO2$%b=$J z+BdLL+4To_G&v>}mVVVBl_hwF@x|5@m@q$lF7rhK$dRDc9MI&%09T}h(nbK)FU?2b zZ3J*4iU0=&tYl+*1IuM%ttU%ymaz92v2JtR+yMlU0CNH*vcqbvon7vpI;vIl=rPN-`1o5CM zHC}Xscu`j5T@@_v-)uouHLL5R5U-L6eyf->AHJ4&p&oTD-Uk zI@7`W&5MKDh-d!w*AAuKlD%YFP2)+=;|NPpn?k{AH(ar z=)=XJ@nX<;GUPr^(D4@al8v>0K#UUS=Gs5Z<+k0vfBviV{%Lk#cx?#km+_=^3cS{X zCTE_sPOjIA(Do!~M&-50F3?;=w<}l~`wq};im#cB4}dJ**X+P>qS=ArYO@2wqh|R2 z5~%&4n?Fl9nrr_smhik52Ng45!$qLM4K|#82ZI9x1I#?A|C`_7UoQ???GD-80q((q zrzJCDj)2c&;GGQ}nBQ^&R7&uG%Ow8&fuK&6R`VN8x-ko? zsUECJ;I(nL>yOX;S`450<5)i!PGI=VA9Vn%S&&5~V*y0dVwff`h$dLuULfejj(AvM z;{>YP_j^dRo-C2dI0Dg_1=A=9*2wW%B7@~9*zo}{neWFzj^}uJ7d+qfqq$0esni)_ zlvwjmmJ+E91Beben2w_m9j_%aQXn!cFqzd5nU@opzzc_9^Ufl0H&(vLcn%s*s)ctF zcfjQ=Kx09mhB8m!i=a4|uaqF|ES`XjDGDj?Am^}v`~>d4w!#gshZru`dY}Zf!2ZM0*^mYHEUfdO^W&h!GBN=f49CEMCJi(B z&@oV;2|#SNXuVV-k>LVS@?!?ndGo6bxf#6VZ!b&>e+y`}P`B@o=1K*IQrV0J5dFC@{UT8PpdKTr&Z|;jES1VQ z15xD;Q}ymB$WI)v)4N@NG*>7vl}cs&fGAOcDLD;Q;sUXYxl}4c<2X2E7-33QK$R#$ zEMh5@$cTU_xi=jeGObW0d7yb&P=pHvzW5je^FB1fr2;ZKAo`ZU^!bAI@w_(6Vh060 zcVB7xHBx&$}T9?}wnbQ!hb!Wxi9 zVMYMN_#l|^KM#TY$OD;I0G%W8auIkP9;jEq2U;2XA>c)86g-?kSMX#pgCYo=`mA9x zCGL>)A{7Wp5>lBbK#i2o{8|UGm+KH`oSp&=q9U*}L|((f;{`lC-au3?gsJoZs{~#0 z$kTeML>XeOUhBzHi422N;GipmDU}5)<$z5GM07hayogkWOb39r`m9xkwEMvGSqa^c z`2f(|Ku$M!J_|kv>R6BozPNyh`DMi9F=W0z5OnVY|9)Q{>w`61Y2cPn=%3f1n;dz- zCoXSCo`nXrM-b}kiBjL~%3R`A70 z=DQp~ci@5Ue$m;{z{J1+nznwexbpxri0S*~wb(8QGxSRa=nnB0$>9C)EH7sN`~M%h zEVVFu!*;8hL)5;s179f!S-;5fBJtn<|KLG9(0V%GKgV4dL5mU?UPOY# zL2;UWhym0r`U6_OC-A}uGB*yo5)|C@`vGnGfo~;l{>4ONMud`jcbF$`!nbUpd&0Ve}PsPyZ!+!2?1T8$Irm86|;@wJTuBWCb{xsJ+f_tX%;b z7%%aK?6VNup$odKtg}f5WaU!OwDao-kbQzXqL3tdz!LTli7iMH#b60Fhy))vtwD^6 z0!#2hQWY=6vET)aKS0rpdN&$q0b@1T2vA%fZ)suxooEE=h^YMe|33@79958iKiJ@a z7Y#k2*&ooLEvTaM{n6Rd#Q}2skKdqv)}L-B&}=lQLq5er1SEa|Bo5jw3cCCS)X8WG zlmLnE08Qk+ECAiq2#PGwI>bMqL171JPzRMK1C(?4!KvV02rLx{f?avMNr9h%fum#s z!|McSQUE2E?bwxNO<;I!2~7_mWfQO~1DPfS39fs;K~(|E%cr2JsQsYBb*KtI1H--3Y^<*h!F__`jUa*d zsm)BFCc~d@rsEADf$y6f8DB$!`FImZAfWsj!;9s=Q1Zf!VDwM`?SNtMpMe?*8*wW` z4uvkP$~ppPz_Z2;a5IJF<$chCXi)qeZxn!~3!Y!#xIXR#9+t|OpwGbYLLvd0UlxG8 z>bs!RgQdB40X)NWLX86*uLw#Vq2PpwxEvIeYMOsC)fR&WeVkZ8+~X}BF;bv12fQM? z8!i|k4iU^sK&Z{U2)eqww?!aDmVqJQ#p{KjM8uJm0E&k|7Erp*JONfQg)2phfg$L{ zNr(#Y0f&&mbkMl@WO%TI?=%4CGv7Ba_&_u2pj8(v(2~6a6c8`I{{ROWEW`RbXsTVn-_~fxs`V2iln!pECH7Ab=)Vgp+Q%`__^)6y?Duz{MU z{M%jM1iTQfgBKNnENPuhe4u=P;5%sa=1;c=%P!Dfm$Xj77i-}{#~r~b>cwi12sp@( zJAg(`7+%Z-iGbak)(ti&t<&|zi(+I^kO$H_U7x&&1x*ug_k9tVVO$JLJFG(dpoB3= z43scHwMlm%3wXpK`ve1cJRq&Jg$tzSh5Yyb{~;*?6ibbPu)vdtr?wZn&dPu)@F^Z3 zD_^_=P07Blhr}!>75T#Sl!`)P0c4N`Ot2&rWKaYm;9M4kiBmCw8TIgN^kA zyJI?N7TEPqcL57%#SUm?vMWsGg&hpsAeAj)V3oNb2S8GK@{M$jtTl<~~e6gDew4#us)AbBU4`@?MWDQ6aM_Q-r z15lw28dUXt()<#1`}~L3D3>gzb%U18zW`k;4q7%3YB@ZxK2;k5GRgHvzzch*?b}ZT zf)2WWVSfW`GAM_4hhFGp>3XsEE4VfPqucjFw@70U=%lUs7aYwnWgno*rh%r5U$=mY z7Y~->jVa(J0|Ud0y05T|c)TG4CYT8l1g95}^P6%&Srath3<;*@Lp+_KCo({j0^P1B z0y2IWPGEQ;CJas+U{SCeAZi;AonZ!*7|TTv(hxT^9t7P58~CDjE=Yz0+_m}=^g<32 zO=+F3H^6cHCEx`&T<8k4VgofzSp8sWOX9fe0Z>s6ZbGGXhTeHG6LfXJ>pZ0T?Yb|z zYVfFNTBq-w7ujId4$x{2)G%6!q8e1NgHwB2r|X>;wqVuJjQasPfBhXa>;n$4#zQ{b zpfq#@?D{(aFLbYgqav--^$o5z1pj{D8`cMFeLO!tpW@%| zdZRlOqKL;Yt&_*;MLBq~_)oVJ%khQ+1xS_fq6j1i_Qmn05}05tNDy48f@+?L6`-_W z2^Qn&be+>!I|tTq12am38*Asl8g6sI4L9}I#f`Odzzw&6*BOvxv10+Ge5?Ugey>6E zwy&e1GNATAT4xhj<|0_e5h?>}M8IUWgJsmAGN6V7OlB@v2HJQF0MEOEw&8XMvZQr` zO$C>7<)8^@uvZ%o)hK`>3?!>DbuG^fK*W<(|bW} zhh=)ND`1mBu?@}5Cq6>b0!pSAu7@duW%`AnDd5*FpiJxvZZe==TMg=>m_c$QDCr$< znb@EYO$zBBVHFKX24p}>UK4bxH6KZ_ ze)D3A2&7{Snq8=v<-oAxKjdt^mRaC?{o+%>y7EsS^fY2 zYv&!1B-aY&neK!nvtBSy9oof&sFd6RNoZh|kml}t$h7nebNI4ZV(6X1`{W@gW_^EviuOnELF~{UPz^o-Oo1=>kaQe; z#L(L#3egezqmyOgiw*BVO(oE2`25?!t^|!^i3Glo@PHM6CEzu{FxeOSC6F|;{X}3E z1H>7J7X%SCL+x zroa~)AUdJNHfZs&AKWD(I~>4;Kx@P5|Nmb+dk5+U7eR|`(8^^Mgvwo@CGcsTQ^6|t zfK_^AfZ_tOdij?-%y%L?LBn)uoxNa{lfWwFz`KWGy6fKk{||{e6UfXrC~ddafSiyF zQVxp4-a8Nf|9>r%);$%(fNWO-Gx_(of<&5sF!A@!VFevoKV>y&qK1Lth1t9R|G|2D zKt@S`jk=W9IrRqAs8$dIvOx~a3GnX++mLw(6q4`=0Bh&p4-O*! z^%r`1CU*8#tOlhDu*~t6sR=L#Yz0l}^6v*5e(^zPtH^550r?=3tC;CE+ly3QErtok zC%dPDgwi^DM14RG%?IfM1p&750cx@J1^!+x(6GXO-yhvmLDqM(bb+oKLgKv;V}~?? zT4h%M|KB-PVKwM>5fBMFM0@rB|3NRdu!2>jb+$@?e6Sr%1$6hKDC!3nt2~{^#(+Mz@|(E85Wc!_ae0roF3CUTTMU`kbvmzaRqrZkbnDBkZ4dh zSXTfv@cFk-@dZf-L4&Qkrxg^OfiGr00GTDizaJdRosdv|5e%AqetG>L=)ixFX#rX1 zGphITd4S47P&WyjHu$&qIDraE&~7tuuM3=*x~Fu2iq@bP_7IaHuJ3KtSpENhKzA?5 zE1=W(K`EjeVq3tAE#R|zcsg5cK>pd@3$hZXh<|%aD9GgjFY*dNPUYa=egfo4kax2bzV_}(E_UR#ru086F}4IU^jtPb+&YY0{g{c@KpkHK~4_kK*UAw z6c11Y1!XZpqn&>{G?l!#m^n@Nb72@?suL%K=nhboVrY91-}! z7wW=Lj&3g&XfE%B)U+=cK`!iV1r-^D(j@=(sUT%R-L0S^C*Z}myCA2Ebb`4r=luTv zA3PtN)(I|Fz=anmH9-q65EJU7<{zy5y`Xa)dm$+bnuw7i&iIzjOkf z9lae~>4NfM^C6C)9iVdc-~(9Q7Km2Yfs}PSf%d?ImV)<&^Ml8s$I$6JA)jK%2vQNM&^q?1IGN59Y2c!bhut2Nw zgIt$fx4fdoR!uM9vMpO?7aYzxCWPC z1$W9@H=O+cAKU`zow@*=B3=4Htr8CY?X4gU0lmFGw?OrSE<_mASpnCmpsWBcnW2?0 zr~>ET4=yO0e=_m+UISevg{AWC>|F!4aVp52LA|Xf(y9fZW5w zzr7Wt0}?MR&=v!#QvUs}BK-To0ib=bdn(ADUY4eS7nhhJCP1Wmr}TpC?3}s>><-Wo z$h{zDAVf#di^UM-kkTDmvUImh1dZ@@w(d9ys{TPF1Ahx>pCzbq;tTEspblX3?*|9C z^+EpL>!7`!-~t8I3jl{8sNevHAcz4CK@byKJn-)a2aolsS`TRP(%lQP6EqS58aIS0 z1Njo<^lp$Z|4aktih%B3P)Qc};tZtXhLmKlr(`j9PX$Q?y$CJ^D}+d7)KoS_!3w{f zP$R%SqAB2r4|>r8F$W~p*#Z`OvG56~NZ|Va|NrYWkaw_+oAU3U3Q9lLr)r(Sc7UAS z4UT(|Ctmo$t#bX*-O~z5W0EkdLVt9&Oa+O(FaufjdJ%eLfW}}uTepBC14J_LxBP|e zqQx2+z9Q6%36O;#Pk_9HEhdVlf&&;H6HbtJ10=waW8x&Ftq+j^hY~C%^r1$8LcM!R zFC=IF0+)dtAhFICu-FUn$Do+t1;s=%?wAM_!4(b1r$C$v@=AA4E6AR}7n5N2fTIB< z_G0}bP&Z=fOO8LFWo)3CIcWL@kG?_bM!B?ZL>5Tv2Dg~gnn7c5U?#}f@I=Ai+XOz6 z!u3aYFQ^291t;7MdJu3-xPtmx$54jw%R)nWYGL5KIOOaqw@ zsf2v3pq(TB7VueA;DxYGED)mtU+~$$rTal^qT$k@0ieJa`>mnUCA#n?(Dn|{AW-0o z#i<}$I6&pP7fV`aBS`dx9LUM9ML~j2ETA$6toQ{xNEpKeL73Z0#2^}w2BV%n0M&os z@)l_{>O4sFxq9mcr+{M z#jO;GN5Gb)bvA)L5(={EwJ5|AP?7~Jeqjd^1})}5F~P$U7EEFg4aXZnt^y5xypRFu zfO!w(7_cZCNc4rkga7|uaDxaC{{`a%&^mek?Y*G>Xy6Man5q1&prgC9_`us8z>~oo z{M&s5WCCBvL!1s;q7L32bnpRqdteBoNKgg?gM#0SzKLMJ1%L-IvrmAcmw&qpmrTG; z&}2b2Xz?^hw~v5G;0u+jAeE4&6@UM1P!RKB=z6g(8Ker_Yy*$CW*L-d^#+h$23Se<35Mo9T%dxJq0|WyZeX__e8|wehXW$61rbL| zF5B*b*8hNNXHahz5`~lQ{r^7!G&c$o?rs9bNWhD?7SO2TZvmZ~4r!!x_RauxSdlVW zVE0r|E(=0d{~y$q04JTa?unoQ%Ct^!-SI*bWI0%(@gR6K5nNV)5>4n2{{7(g38H*? zEtdw`2Ge{HG#&6GtsC6OOly9{2puf|6>-o)3se<=mYab}mu_$isGDa(AcO~YFwca* z7i;<p6Tpn;&}cR^(kqI7{4|J_r;g&0d$z>89dHfTQ{Y#K<|E(>ZJsILza z1r0<+-UXFIuK)l4f2qd^x+M!#)^@gnq#+Rp4cu;U$rSivr#U=~|AE2`9Ik2I9gr{s zw>MsVy#p)0SiwOC_8zFf04?M&+im*Z)OA{`VW&~OF~RzQLbnUbpdbU+^5AwWv`2&p_ZLnOZ2=(bx*@&?MF4ju)HLJ>P`d*Q zvMk89d+=e*;P?rAAsJ=P(0oJya;U_ozugTDO1T-dU{pN-5 ze@*Z~^%J-m7#I$$hn$rGT8pxEg98I-n2te?fnn_i2L@2p(!kEZuw;V+1E}HHAi%&d zdxHZ5$TOhMPu~Uy22i|#*o_+;7(m@gkU13_92h{u9-tK}86b03|Njq~TnyXbzyKO^ z0IBia;J^UtqJh{hAT{wNxdle?sSG|KhGBdvLvd+R8t7h;_|&}AqV!5k5r(u1klOfE zhLqfj_=1eYc<@arU`~EAl#^JJ7@wP(%aEIz8(&bATE+lU6Q5SWkepuxISl|jUi{+5 zEwuIZOrRwp9NmJ=RtzPeBmY6i0R+96=%5WcTnPUj#s9LOG6uybd~@a_?VF_*EsK<o<_k#9I?L5KE zfO&N~sITa%5b(k-0i0MsEfeUdDCoFs3u9=8DNzM4-cIYB`U13{>B3FuV)wMp)+Zo= z{Wn4F8wFTjAFOEg&HvzQ52u1v%mt|cm4U8bK&w@Jzd#oyeE}UI!oS~D!TLh23+MQ_P&4$SWs5sgREEqY3OX}{Qz=T z9++Gf|BI;*P2i&_m|h&e@&A9;fBx;RpboDD+?E6tP_I+~I%GkIzTI9Izh)^ za&(4104H0WfEVqM*Z|F9cKdQP9t5pI>hyil9m)fl;q9C{<Wpjq9{)(M9o zEg8^3-rg|1tpSH2qM182|pFuXW<4HOZ{u*m_P zz!&T&icE}+8D1;_E3(Ug%nN|5c%+YP(yW=13@_@ziX@M_9sqL-uEAyl)UJcqErD+w z{Qv)d{fncJhEAvJ5m;uMa2Rx+$TetY>jCi$uKoWHZXIA&Fq6Z5N$R5wM&R(#(9I!gj92oz0&}i14 ztDunJNb78EI1IHD+-_9pX5m6=HA-~z2n4>+ZwF`XfEU|-LCb*)pwV=YlR&xuFlpRP@tW>^8Y_1 zUibUz1isLM1sZ=#8w>P=p0rNvoqN|eGqn$0`~fc3Ei>O`?m0&E`#R0`bkaa90|i9pN>c)<-}bh@7Do(gg))cX*t&q0DG0L4CtS2shY zAl_F2d*2^oR=|sG@!(+VbUo4S3tIbfA?QUjRDHMWnE>$h!bMPl7o8BrAlG%aOa&*e zWtTw35lG>Mz!#oSh25big1TL=1iY|-3cR=v(+Tc$gA(D3oJ*jA#?T+2b?a{eUhsy4 z9g^1B+JY#jdO_^K7YDVVS&F~qGidJsEcU@lVF}<&3)lce0sw37hNgjaP+9){P+>^e zxI^3(@M2vYST}Mqm?|~mkXd4e%J5+|6it%PzqTPUkU{^LgF4=a)9zPqR2uoh16k6LAe^97C;RQNGasr z1U3qh2z`IRQlJi03X%;WVQ&!wQT{?7!az=bpfe93rO+pcr2#1RK@#3|s1(T6-M)}i zR}3*L;Ki+Iu<6LD4&)q2lA88K0139sQybrP3 z1F93A(m?h>ys8V8f_NX2#!f=a3V2}vVIZfmzYSo=2f)+V8>qkwW{6^t>tG2?;T%!| zI}B9_Phgv%0xu$AIuWJNv$H6rP zo=~A70|^3cs4P5WAX(-J#L$2jyCDovB5*ws(CvF6@Wl_v;@kkxnoMwo@*FDg;$H;V zDNvVow)BE)BZ)JhM$MU^Zr2L|FLp!KLMpZ^K`&N81zrR~Y(i)T7c{p|g9@7EpsfIq z<_RQIL0p*!)e8}Wc&G~E25?k@8Y$3P9ujD_a1Ee50LgPVVHz$#TQ#6G-0cbpJRZ0P zP)>wIw**YX8EA_M+4|eH;2;Qqh(VlL4%2V~v}6<5NLT<~ zKZO*4RZxZS0L+96ybyp`1Jwx*y}76U|DUi6H0FxEiP-#;i@*0gc$Df0xaGpXAKV1z z2Q9G#x4oGU!J4v+5PLdZ?_}J}16||}9xVdJaNvur@8J#L7nW+WfV zczn-0xW~I)?*zP<19dlK9s{K2g(PSO6Er^AG8N?RfEOJwJ)oxDouC&PD0)C@UOYVk zitz(M-L6LhURZ>I!vf?tHK^ZEmokEu%^v*03>y7o1FywB0&Xw!?{5Wlr@#wpdqJHN z=8N5~0^p*_6cU_Z-+;$SLAFA2$`o*>4SHb|3bqxJkb7D|3c#jzL)w@DFBU=-ys&r# z8qnkDY(26ZwEF49a?s=}h-BdJ*~!4bP|w@E7bL~N-?j=op9JoDWnZj-bv!^x18!{A zTWE-$2z>EwCD;w10e*1k+EqgMNTIv?IA{n1-090cq|xpBgnzq;BRDB{LmmA>0%qcc zpcivsCW6w(*rlzYPGa^64M>Z_3pIoeyn(v(K)?$Z zn7Pn6odPo#T&aQ6fgrL=E3mpW4`$+ppckK3K>WHL>QX0|iQxG@P;|W5e+)EBd=x3& zieOC*2{02c1ig5&4D4Tcp=ts%5s?};9>GYrDOl4j2h7|90WW%B=0el$ol=NBNG^>$ zg5**gtS;U566*I0K`*ReCW4aXoxm4eFcT3jWe2+yw0Q^`Q;4+nA{wF`GR*)hYL*3n zT@?UT4o(N)l=eagt{iLzD7FJ%um?hvznFIy8p)thzs{)}z>y3hkxC|z6ue}DmLurC zgcy6_1;UphOTkva<6{YQDe-==FG1>GD1t{%pd|=;Oh8;;2Q%?NzzZgriO`q`f|&>| zK|tzXoIeDLVbCSR{QIFUMNc^(n*(2{!OXo7^kUT#RG0pOEN6h0cp&vJ$`65J80^x_ z6W|069_E1;cOc7yUR-<*_5Oi?7ojjip^jY&GZf)iC6HsgL!ot8i9gsCpu#B?bi(g; z-#4H!@E<`hs-&R92qi|)IRWtcGdHk$&`L6p882KQ76yPTM0L1fph6C_F0{S?x;)7D z$8ksl6gRwRw+3gGNC_tEyhNK`Q0s>y#cn0@)w=cn} z^%f*30$xm94DrJL&^NGl58px15OB9E5C3+Kz!w`_!3sdf^>;G8cys{NoZ;c$&(V6a zmJfE)&5P3q{{No<-96X~I?3S0&IAAd?=k|f9-kTl8X#N&QUaRvXpK1xS-RZ|VnC)o zz)b%AQ$ZrlznJ)YLF)tf_k)#o`|>pJX#`Iymn1^fWF7)-cI@`$>7BwDBMvHcVM;rv zG=f%Fb%*lsZwK$A19g%>#&(DDbhmVYH9SnvEQOpOa%4Td?2Ff|TvH5lgn^@iGI0~!x)1(Be&#)m;` z^A1ARO$BsM1sMQZjeYq4|9}^(pu#T>Li7e?#7FM+?(PM-B(Qrbhzfeq3RTn%_C!E; zFUT)}FY=(mFIu5`U&O#fiX~v#N)j}UF%=Y`K`-7qf!&wZ*$U!!LmZf4Y;0WI-3xMT z;0tM(0ZBK&WoHn~y%1HcAh!p+_*wuqC*Xw*Ox25`>mc<4ovkmx73!Pipf&IyGO&9p zNGPbg737xysLx(7!E|;{1$ib2>a`cIz~*oS1-wuIvjl5dY;p(DC$BZyfsnAG976lrRGLxA%hl8Ti5#ye@+WGzkYP>$by{Jvao412M>S z2VA-rBpjHL208^+$_3(8P%3v~3CNf^b7tj>uaL!80WWyGz_OstIgTtZ^!EP$pHX1T zWe!#R;;k4o7Wi90tq9O^44&?Zp#6tIFD8mZrgy41sbR zXb)n*3j;@(U1^<-AfXrQ_J9g7A!uPS0W3BPB$mb4?aRZzekY4gC#E=^QXeDr?!_{CuE2HWr7WHecEWbu$mhSzC62+-w4q+zOHextReZIeizXt^*hO$6KcESr0W~ z!Y4xz!m6_3|Nj@?cY?0f067;l#s*s7 z0v@nRYd!>81_TmI105vXd;qjF_y=@A2)tfdj}uhPgN9{))3d&v()q1i-i+}r6 z5HqN|6{J3(yBAcl1-`g;3S=S=a@hy1PJ3HIL0$%Ls0N!7_+qCmIQ4@%2cVJ}beFN2 z9aQK<;EP!ZX*63Hu7GR-&p3cn%yy{R(4^Bnr56-6K`(BA2Vg*ptU<~;Tfo9EChY+E z1Qc}O@oPxXfSE7KA>M@r9e9)rA`fQ12#3kP=)DMX0=}R-4ZcE&_@JA85@aHdpaZ2o zXhC5D+NlFJ8xeG%ToUwRE_f&g zDd<4LFT%HD2|92Bd?5o45O}HshZiL1AgS&TBshWsUIc+z_=0Z2c~DS*g6_$3(D-*R zhzjgRO`6#!K#EYptGgGJ7-7}yi<{>_DmXe@Pk^hsR*)&+K=joJd~wDa9)d3nAndfx z);S=R`_WoPkk*qm*x6tYg5;4}MUb&;X_)+rg<$8SdJr|6tcSP^w44X*!Kompp+{BM zagg&-J%}0vKhA{f8(^nx4}_(BJ!7?gxT5g5?j z3!(yFG(i==_z4~u66tJ}S@Hir%sR+sJpS#ipyCO%U2p}c$$1W0X<9efX=$BPzksTz zqAj4Ud>|%VxjdxD)7feOYT<4Ns{^&AKu!yIvC#tTT8KYDDqunQ;yHN5HAldUdyt7+ zSkmhSnGOnYQ0N7{D1aGoAfUS!WB@EcUo3+eFc)S3D1e~B1RBrohR(y(LKQ*-1(MUi zneIgrRO$sMq?y#&dH}R2XDTT4AR|)HH3^nbg(${DrU&GpQZGy)EtJmIJ>Y}`Y9<6` zF?3G_aiNAmlK&gXGVp+Iux*f0FzCF^MX1z^7xv(Q10^G{LC^;83j^>dkqD$?(%TAZ zZUkg8boYWRfef-iYOxpXP?Nf+g1m%ce-2dYg)qd$0sPw`2Em%yr@_N9BAwvIHzd5k zB^MI&Mfn+UhJuy<;F1d>4`#jyhsnR_Jq=Qcn#WNy=V@?N2r9%tDUp9axYEN@bhu0RP7WJEv~c2w@(FW3hHhJH9`Yk+yxJl zh;)LvFPD4+mwKS008}1L1(jMsFHXWt1!Y4}krmiI6+{KSkcV`Gz~xaZs8kGiF$bpj zL?E<;>;{*N0WUr!fgKm{A`@mOxI6;KcOYzECA_%=k_&iYhpaTM8>}|16I@KZc(fi= znt@7;pl)!{7Vx4U(#wLCM__fJ;soThpcjfJUjA7pA7Qke5^ zZv~kS3Sdw`1ipA+3^f20yrA+Z09K-l!3^Mq82}0((8$Mr@J?V0&@4+Y$THA0G^j<< z-3sbrfaX@f=fAvYfiy(|UYt$@TLNo&bhm<+3W681gB$1wjV~5JmA=>xshFWn$nIW{ z7SOu(^Xov1tUyiyEi(gK+Y7c9e)J75%-RsBS+J3wUeKCE(40410H*PUCRFJQ2bi_s z7Jc_rkQUGa_=t6&Q7gDckT8l#Fo75MVe6OLpd}u7modbhAU~k!f(g7>3DXq-)%9XK zq!NV0doLu`peZVg5n6S;__Podup&@Jkh-cHTyq7y*am5oK;-zhLlRE+R8SlvLJsZ# z4VVMu;WN-+H-lGof&w6XEvPvLaR=0TSlocudV-?;#Un`774QN&pA1t04tY@Q39be8 zam``kkc0qEM4+X(pVxren9w8v4pDIH0wi@~4QSZ+ z;2kN@u_EX&%ZnhWdq6qA7hLbWI1f_{O7NgT7x+MuDpc`{ISWAMiFCF~fEyQImV>N= zH!eVB4JiMBi`o|p3_xnZ8^)pKPj@epOX~!eti50|pt~2OKk&tC z$bJO4abPXoV8a7m*gLk-e$0gv)< zyzp2Jx`z;?vI#Vj67XU=D|A?bza;>4uL)=oJ$Q2w&+!%k&?qQqTwy0@T=n2XhVD?F z-WKpta^OXw5RuLn@SY#oV(H^8ye*qSy>8;8YCCzb{U~RQmq7_^`93w`24F|1V5I!vqeiKuH*MgfO&Yn#J;>Mh}`sPC!~T zEmJ{#)PM{I28N0k>!E9+KrKAbaTK5~8Kia7(+cW%1-|H=57G|VmQ^1OatY|X0+71E zES4AYFvCI1Zo%_EU|kTygW!fExd>zvyq|0UF?>erfx0wsE&+vP;ER*GAUi=-IfxGm zC+HvwcxANrO7I|x>krTf$_?;{2Z)4^c>F#A8u2*UJryJhA33Z!A^1$&Hu-_OM z7#d#uTLCr<9Fo0Pz=nZHxMAzShF$7z1&M-&Pe49@u>+**rPROw|1-|=fUc+R1x0P( ziv^HW3L048-`)yxe83AIMrhJ3NrnzZ;n)TZGQ#>`tu4sE&3hn&Ms>O%2VZ<}yrmVC z9vB!L7+!dT2Sh+FJ`Ra{P}+WB3Ubox6`)X@3R=+)x`LY(bQV}ZZ!bt|;ET( zEKX1@3Y|Yd$^hMv3;vl!soK&3cX+j59DBBy9T2j_yv+93Pp z5#J|S`OQO0^ZP#J{Jex^Z;6yA_%_43Y`7G)hc+sbG$h? z*ubTM!;6DPU>>Aj3)%|@ZXUikwG>qEL5p!nGm;&$?-Qaji<5slSY_agcrCCApa_ID zA!Rm!(h+z!Hn_9`CB_%+OCb%K&>x8A*o#Y$J_gh=CXg9th!vo{jNk_S3tNz5U=J|UMzjg$odTs77LbEL&V*=uu|pH;Oi-H|WJu79(v4te2E2%YY$*T* z6xhAs()IchP|^o2m)brR5(TAy{Xn;fgRVLRUD*q2XMswj?jCSP4Sd0h@Qeb(i|>$n zAL7JaoRFzQP>8=^e05Rc%0IMKvUx;Fme=a`iZkY;lN5G47C!zj15eV`RI81_G zywHI92h^be`6uwj(hX4m^g!0mL(J)fnDc^t2_*bcoE!w{X@J6Cf#Jm#NF5Jx1&Wh* zEyi&2cSs8sq8Q0x{+JHqfjA8A9&manUktiUuyHY{`U2gv*5e8qvjx>Kd)1*{gV!*i z>MIaZ!+Zz@OM(ZSkwz4KL90|i6;aTOb2C6Hz?*zyK~V~?^B*Bb602wuy(hJrD zF?uT8Xe9T59Ni7AKwlI?j0Rs#1gXBJf=c|L7hDi?(>lR50H^?m);Qqmt7j2XjdKB9 zQIao>K?86I^}SgM>k@y7;Jb>KU+MAQEoa`-33E z4s`c|MAJH3c)``z&xN4oEa-4&X!Ql2@d$eH5Rytk{W<>ay&%s7zUci0P3I-ah}jb! z)Y$>>mRV2YtQrF2M_~PaQ{IlSo3UxntLf-mBtqG{T z)(i3jC|@)-+&j)5aU6quzM=R=&l!aAfsQed+k7M)g%t<1^V(FZ-J~FU|?W) zeHvUsf;vs$<5EBj%&9H#1db?po*vT8aph^=GXYeOG4QwiU}RtbmHF6OCy=R3(7`#@ zhiXB$0sH`oY@gx?I>Hv#p96agv=E^QWMVf@N8k&AKv3@EfOfdR3QBppr%VGW0Cnpc z=7Tz96OXs*z^2ji=0mH<7l;1;e-QwZC(2Q2y{#Y}0iens+<68CK6tAo_#EnPk%@Sm zxf0?`&{z)0kf3g`djehvg3rki=>&6Mf{r!p?FA`78e9Q!;p!hw0(lpz9;&o^D#&j^ zFI*u#8Hib+$i{Z!9cW$3esIdRzF3zcyQ1So&|CcBK{{NrF1fvxF%0jYaHPQLi4vt=sS)?lcu;BE$JK~&(218C~zfLx~yvh(#+Q0Tep z1a$j~1onar2zs&c1t>rSvbexI5_@|=#s6_u(AS8sIxY z;FYf}kR?x`Rm`0&y(>V6L>-)i-*?@i9MGfpn-4I8wgAoptz+Eo`vbJ_>P^s#hYH|W z1s%}Ezuol*Xb1C~z!%brFwqa70O*EzA9VI_AjmzwcLKXZ?*zU0;s;g++E@&8kKr6} z(W(OqOYIBYJz#HxJR$+o7z*{sZn(w|FpWQEgHnR+e^8?U)RF;5?3#z5g&DSxz8Gjk za=-7J?kT-X9)eC&RD%k?=!Mkqphg43hZpe>vq5V?-*or1fHq&1@gRrof^@2}ZLmayFerF^K#Nup!P_Jc4k5JQ z-2)f>0QTya?v|+_cY=Ko@M5knSW`Dx()UaElwMFc1idhYbWOnF;QFPzrxg?qfiL8s z!Y^7Ol|I;%4==(YrZ9g9d%=V7CL{m;&=08A>G>jC_W^F*F^DdRbsyl?t%nM~5JR!< z1!Q3q$hx_Z7C7kqYDlQgnFR~gFQC(qK%vSx3o?9iBj`mPTo#lVz+wJ+CMYpX0(EW= zebtZwWl_)}L6<X^<+>)b%#CxcO=rF5-)1iz#f9ifeQKAAoK9_QNYLA zb$~9>u)fIOyB-{e@a>QLWWmNk;t-y3e!xXPfVV$`&v|*lzg>he=!FkBQ?Y=GN`6pU zcoF>x)`IcPSnK{!3cLxwWh%(80Wa1;dQt%yK|AD9L3s)0p{Y=b7i(0(E`Z8`JalRX zsMhk%fP@Y>F@OvUe31y%0}Y+fFWs&Wz$23$P>C1uFvCK>bo)L46~eV3!@vjYfC^q; zh$q0M!HY#7(H-s!N+2M+f?j-uEPH}E-1S4Z?*s7Y&>g76i_a=Bhkxh}eE@Q}Ajq!Q zaEF7E709r_7b~E8U=IHPb9g^g;>9wUVWA+4Kn_1L9h6M;|NZ|DIW>Ucivz=p{ky=Y z2E;)Q5^>xOIyL~b`QQ4@3zprGV*|t(7#KLdI52=}m=<;hhLv9(7(k^t=3?SEm*b~1xFn|hW5WC~61B1$8$XU+KUmX}glXjqe=XGBl7g2cVQIxv76 zuKWxPc3&MBK<#eO{(dWvnXCW*2eHjS_OAN>AJpbH0J&`igslYw3FICqTN0#q zIYeCGs{`Z+6O^+|z=xW|r!thd=77l}Fqy+p;#vebT>*4@3Fw4{)V$Q7_*90}yi}j~ zREEsrl=z~=l2nKYx8O$ufc+ z_5c41t*M~=SOq(tK_T!(1~xt5OqSL;6|Cpm6p$Xb3{VV0oMnQp2XyW}^pyTyu%1I; zJsI3em^omDbtg z3f3nMa_Y{1Qiyp5&5Ct9Br%Hl5ZAwuhUo`&`%&x%c`NY6Z^#q{XvpY= zKFoa3@iLG=cu@^A|3c7<`;)--r**apK+`gq5%7Wyq6jL%zr7bE4;tqK1!T|*bBHvk zlFDKPwNyb_V37pW;TM8l920}G4+Qk~LflmhS(d}UeJaQ-&{!eJtbiA%sLVHLJy&!7aAY8 zkAYg%JV<^7nHBUR7^d_<0K{D&KkkEh{6f%+N1{l61Ra7I_@W(gig6 z^tOTy9fAc4G@*eydXSXY9V!4yhXF5I!6{4wG?-HWE@8SuK?m9L1iYx`1sygk5by#L z-Yno-f*D^tnehLAH@L)t)MpodIWW9V!QozU;yP1P@QM<+kpWTk)Zm< zxWLzl~_MIUH@dU@NWm@L|sTMfewTMb(KKj_rep>yy|rQ0Pd(_xmXy~!?354e2@*Zv^SYYf zVEX^K>lg6A)8D@T|G{A)6YxS2k{}^rArT1nge}Yy1i}J#QYXkq;H6C9@aTuG3F;1& z2zrqOsp6pF0iNJ^aStK}4ILhE=tRLZ`F;US+5G_>iv*e>bb^Y%SP7kG+8_F-+gAY8 z7&Gtt|9`^EBA33;V`F3H7kRy)%M-t(rKPdGNa_VuU%nEZz6Tm> z4}eYxDiLX{JpejVs6@K4_5i5vE>U`|2i1Gr6|C*G+;P_*GiT0ZJns4hWaMkU!7|G!`Zn+=MUp3UG9b_$pP-2`~uqr+V61yd>Il?P(XL+i=b}T zCjl?yz;aM`yzT{A>iYq*ugMoQJOT2zg!P5m)NbD|plefuUhu%(i102XT{l7It-&D- z?g_g>?9YOVzbFJ-1_}n4_4Ah?1;guRch!cGGn=HM#= z8U{KMlqLT{1EvSGV^by&QZyWfRFwhUp+|yVxIvc{b-RjycCJAxGl6c7z!y4DnHS06 zgAzo#Lj^jSUZ{1!k8|r`bYys;wiaBGH6L-Xe)FPoEhMjk?~I+o=*VyZdNG*d3|^I;9?T>UrRcD)1eU5>OSP5<%Ur z2F(YU0=j*5nh&xBc87uvujdJP5rm@77gXSD1a-Tr1a$j?>=g)lVE|Fl4R(D1!eu(( z!^bwk7D-+C@c(}nGq`^N?!+5FMk1Ja!4aR<*}CTg^qe;EKm|k^JTU?0>vW4Sf?7Ku zRRP_-AkzY&_wNa$b+&>69h7#bf*3(BdLBaiL;NjW;KNYC+Op)kdqFV}h;W4l*cD)F zzz3+QbhB^;ys!lyry$bV3bLjbe3VdNmVEbAkmexpUc}(1d;P0mE?@R?r1>3@`S! zfok4XP)tBvizP5M&;nBhoP0Ke=lEeU0X~@`C`-N@oRI>+9Z&GeB&3)C^L4<{SO(J! z3jE$)P)LGS-a;Y-6aoP+oWUFIc|Zlxi*RtE437zjW&GPA!NT4ij%wGEA%A5dO-Oe+Cu^rIWInL1vL!>x_xCpCA9?P2x)Ms2FkJE z1Osy>TpLfoi!PXv;37pJ2-;-E0- z51l*$FTz?7OG>~NL!1#J`T?Zbq6J>scd$D$ys%gfF6|-Rmfg!i-4;*@ZvEy(-Ev6L zpEiM&fq`KHyCcJg|NsAkuIc;;(g-TU`573VvO6+>k`$;Pa*y4S0Tj0&_EmOA@K_y) zeTE%YSHv4ZD~)(VD1)IqH8VY1-z(jr9F2#-=Y)n{INoaW4>ID`ycfh`0dKXtv_6aaiQt|{}-p5KuyvfhU<$Bdcp1hB`|@27mJ-?_8tJ+3%W_U)3*a`FKD2$ zGqmMJe-mhgD~rFk)#pEG{QUevP>SN=-|u?|9Lb<05X#Zb)79z2x&6G$jd}9RasTLAQB=_w0e%qM&vrbp8o6J7Ueq zzyK@Hx?M!KfSUPtKVf}Hu)dZdfKrD#M&Mg4B>}2;;kPv9GAlPLu8vg%(aT!FMYXBAR zi~m7qrA^lk}yp$J*O1v0eLrFRK5{@(EK_i_E9eGz0TQUtb6dGWFS|Nj?nK*aNUBoBhT z*82zKWzaU;4-h?oH)Cf9>{dZ5{z z?cmv+z!!}v&>Yk10-9>%0NwWUAGBF~zv~-oa?$f#i)SU(;X`~?epnU-zC_yjw-vFn6 z$owS^4a~?I`k)$Kv_hI70WWkAt_DQ}|Mn2yCqXa1F+tqF-}g;gr;G0s%(y{u2>*W2 zDObL4`1gnS{?I;zkrTurwsp2@{0D9F2azDZz3FzDIwj!6PiQ5)-}gI zzYwVdrQ~b>KvUWxp#1fw+qVPUJ$@+IDJ8VApq`6vIM-? z4%4Cl($Wed1G;-b`U787!)y-)*#H`y=&S{GgwYvKO=@(+1`suvss%A==V9TS0vO?NdSWK`)+w`*bXwts)?MTS2)8)b<5AGq8Iq z$eAElgR}&6_kz>}zE}u8(?O)ORRE-ADkz@?b+>{}Qw!+s1&IZ|$b-AW0W`S39qxUw z`7iD>fE)?VCj8qW2E3?-h^2M5f(-0!1(jhSmwLQiKlw1fr;rFHg*f^2wURt;W7 z=lZ7G_X_`h5y#d`{4L6$sTfd6bpljCfl8`9pvw}cg1DgGAwRSn0=b-jyG!VgfEWM& z8-q^h2S@p0@CpS`1nWS87DNSQ%#sAnUqRxyvy}%FGp!(VK|u&IIk0;wNHFL{F*x0` z1Y|K}G=MfVTn1mLBhuN*0Wxks$f+%${MHQ?2zXHpSvmlbf00`C|No1GDo}0)sqgFs zt;>1gUj+#xe$a)Bpz5E0doRfHz!yvZfm{w+BM)jX@o%3BqJp|xLE4~Mc8V`3s32M0 zr*%us;-Cnx^xy&&rXUtGEbE?hxNX4iuj!t4)yV|<|7 z_X6nJXpnUv&J`G^+qLC5%LG^*2|C^6qyr=hT5Sq491#Z~H-W+rhPeO1A!1r#@HAR*X-NSgfHr-B57UQDGzBtXL`{M#pjmSlik z4y~In{Q)I8@LK8@W#APJh|JOo$}9np%#sC3n$XMwNw56dq1h0eg92W-v4aXK7Eoqk zU|>jiu`Cz)d7Vp=CSfxoZ=xzw^8Je&YZ@d4f7jDjm&o(ErU2ny8| zkWkeFyA75uL4tuVtS-PpRT>mMpkxS7lgC}Ag45D#6-0m|Vj2|W;3i17>lN@N>GR9} z|9>&73{=xT{t7)vX#%J;0yURfKnzg%Q~_du%BLJq11cM&Ck;d-f{2(h(9jAoOx&&10wSuezg)i8MYpkH~ zWr2??pc(;cKKrn4349?BGhzYAh^Zilf?UDCz@PwYO!IH=VFg)^SbGcVOT2gr-t{HY z**XWLvlryEz$^w(!J+``RiWwxb$!5gu7>HH0V@r60h~1x0TPSZ^;V*aEw!f&u_Cn04?01FE&4ZZ%l%7P#I7h+dFq1G}e!+z-*4 zeS!fsnBXB@0oNM?*4qm5Za{Z0$On)SxPy<-+zjj3ys&}mjR3_ysKN50qvZep7tJ7| z4n$Ofh!PNyU-BPv!2`(ZP*7)r3sii9PKX1K5P^bbzl-RJ)&nKgU;&UdFm)vvFd_c^ zA-pGAFO`IY6AUc2!Tn8mG#oh#%LU@F2m{Rxfyy-&rnFAR*P<}fKuf7zFQj$zaHMr| zy#y_~Lude1#*D3(N*uw-1r&l%tHI@GD=3-*UYtAwvq}nVCU~@$2UHVuiwLH53cUOQ z8WI2vGJu>4uHX@7f?{;P59^86lO+x>i$G`d97yYQ1$XIDr(2qTG1Xdu=bED%zaukio>7mFBbj<>E{3qy)=Sc@!~)Ms5b?56J*)IA1OzM7ds|{$KM){fX2D3-@M?M z0vUA^Wnf@nk#=PG@&EsS&}c`mj3dJnD7#a}k>LcC-5}%0umw6US1senums93m2qU4 z0%hmRI5L0|0LYwd8Ak?C?+BD-Qe_+&K-E4-JXXe$0n}&*iHFNLGJyI@Aa;O^BLk@C z0b+ZC+yEUJag=dn0CfvM;+7!yK*bGZ92r2hFi2ce#*qP3%!1fTGL8(O;u^%3mT_bN z6`>%uh>Rlxs7M5{d1V|KK*0}UGsrkH1jZMaCdC&Q7L~-OGL$728AB-03b?YwBG6r4 zWr;-wpapBW1%{?j8l`CK9SB+gS5O?E$^c>|2gavW zFeHLWFaf&PD?UFhjUhR&gdwveB|bSZF9m6lTWI&2*u$WKN+>3R584p{+Tg}xeXxcr ztvi$>tuyq`YmT&TSDv&^*FXH*UH^1Hg&7*!{ifTM1I7cdPY68j`UhlNw<|}$3!lrN zu4sWeEZx2w#~VQ+paybxC`WUZ0z*k0Cx3MyS$I zj^j-r5wKEMj^-Uah7hH`9NiN^?4TE6P^GRM#~VN*V5J}j$bin>ggOAk4tSvrRSI$d zNCd1jl%si<0$3?;H^>Yy8+6J#$P5NEh;^V~1+fEOJii3-EXWLy2;2-7s8Wz8KJ+7uHavAP0a%z)C?5;D9Oxg(8R@^g;lt6yyMq2v{k|0WMIbpb!AD171A6hzJ3Y z2v{k|0Ul7Lpb!AD17GZdDg`+JBm!0nazF-DDaZjJcF>D{s8WyvKq6qJAP4NRL4*K^ z9q=LrsuUCgAQ7-qkOOj{rh*&*Vh6skgenC&03-rd3UYuAG|7P+0AdHd;Dag!IRGRA zRtj>!79!hRb(18t~MkOK&m2Mkc9AO{dA53Zg?gaCo^U=>s;$N>b( zgL2<0b1%3r5uaUj&P!PWYKPUPj_-|mqS_~OG0aBP7VSRjesLWsVogPpn#S_#I{ zEy%y!Nh;vQ4u}d+6o49&kTkNn9iB!&jYk*;ufOCu?)n8JaNP9=gaWrOA??E#QeVM$ zRd<3e;Q7(~im5a7M|15D7XEfE&?R!NKmMz<@@P6TfL6u&@&vw+-V2K}LGV}?IE1c! z0aXr;Sxo%fU3mgteBT38!v~r@^!@WX|DakSi;d< z`-P=M__fkb&_V{VW+#xs*M_^;7#JA9It{@B3Oh{B&Sq#mP$Hgj6y%18v$Gj8PMn?1 z@M2>+*bT42Yb8T@f?gQFy&<>*avi4YpBJw`gS^VW6SUA9Y|kyQfWj_;b5O5={E%UB zZZ<>4igU9WUPM8R&0^-??)wLHXkn;8(2J$^poNJ7%}02w-@N$I3W>Uv>W&P;8jcLs z8jcK8G#nY!H5?hh@rSuy85(zSpa1`d1=o)k0iVIk3z%O#e+Euiplx!XYy!$XouKad z2XOR$Xs-Rh#^1gc9K9d@tF*q+c7*Kp{_}ztb6`}yhr|BQfm2FNwU z-GV_c*x>=A0ve}7)A`~=EQexUUS zkht;v^I|GkbLbb)Vu~LDFRnd>dEm!ORggk>Xy>3RT#Kae52P*Cyc3k28A{c5K{SQ_ zd0`IL1X^_t-U3*G(Dd497w8ULus;Pqf#xdsx4V7`co7Ow0-6cp2Ybf_B9PYU`s3wf zP`W`0khEQ}1h2LO;wRTXFAjc02@ocP39pTIaD!8&>z^01KSFHv{Sx@%{u8jbK?MS2 z&)+$S0La$Y3Ofr<&t_;nSt6d%0CK>D)3X^e7(kilM+!LMf};XFti;h=!&SjhVhT0{ zn(V+i2sFIs%h4UeSOHfY!X?n{q!92z*cO~3UwgxcW?VU%_Xu==8nY#4;JuUl+e7~Z zWkGgZLG0;n;Q}duYjF_}>Gn_vd~wVMY#3xMxMVXVc~9ujbYz&R>B#U`(~&_<%aP%w zrXz#DmLtOsEk}5d8@wJ!ff2mE^Z{r+kOye+4^(P>UX8TA)O8QYT`%%JfbMAE=;rA3 zJd24{{R2xlmEdTf3LI`yTA$#K(m`aTGJ5dxm(_u!wYFpXdGdAsV>C805LA~LC_0Uh;acgc)+;=JOcxoC-wzj z_3hHd67Yhl7Q8s>Wz7Ho|96723nV~8USz%lmB64wN4`L}hJ4}Q@B5|sr%0_JcsH*r z$8nblpaCz2*SA17o`ILpJA;!XXtXY^(=q0S$~*8_9sho(nCug5fiF~GetH8Ma17<> zZUr$qog$j|f*5e`_`Cxp2$q)-g80tI;NagM7-M~?Ru;4~1~jk|%F*o<(R}KET4x9c z%Zuf2K|VMEX&(rJCZoGKz-CDcOhE0$vmx zg2uxOkehuux~GB|oq-9>dqE7in`gX*xOs^H0|PkLu^bHrT9~unBgOh6$jzZYvJZiq zb%6=ZC;z8)`Y^G)`1}U!=GR=^p&ZAZ5()M$AU@IrGNG!gT+Yz9@|pjAzfxGH(E z_YG(z5qM9PW7&)KZ=m-`ce`?=bq1upmADAWEWni@gy1)1{|HPdzx$aFhKN9;b&lYxt@=K0n`k968ItkZgd)G*dFA>k{7>U|Njp@ zsSV<#vKOyjLnmP%zDj#>^EKoW?$8%6&bBGn)z2utBjGG?V($ z9AqzZH)vPI3z(z%TmFNi7<8rsr~u*#cyT5JlnX#9qO%cH=DetW{r`V2_~u}cm!YfR zr%v!y!jv_D5OD?nvmEovA$TV3+B2^Jppp_8&FRo=tT!F zEX)z6W$-aDyxx(;1WL0VAcq9LFoZd~L>9ahpYa_tXlMe(tA>2gW&{8JK#kT*C9>V1 zLCx)gEEp=;`4|{pD)BNfWU+LE%HzwMp)px1mc0pjlq5~6$JSOHMykng8dTk z!lDKw$%5ih4_*d_*9M?YM(6=Z|HCou#r~Jzrgh*8wYiuc7UP9%6%GZ*kLw#~S@s4r ziwr)qEZ6c@G;8n`89ASVm*?|0H@Jy4$f zZ(g8lf-a?XhQ0u$F4q@O*T3N3@B0Gc`ZAE~7eie?A+R@e4yx;oAg%``sW|~JzF300 zl^~Bmb57F?%$)Ox8=9uE)LWprFr#kQ1N{3vG+IxVsPgXzZI$Ba?wJ6p$-otZ%R~{V zS3I&_D1rR(dgn_!(E2S#kejzVl?A+5y&e`cvfaKMfiJrEV@7r~Hv_}VGA;%NP&FO; zBe!?FZf<@P^Jgf?;L?I z4jW@;>Bn5qB-8RD<@x{rFY2HF|33k|*Qh1n#i4ajHOznG62?fhFB76F}-f@e3_wlsGXHDiaq2!|R4_ zc+T$Q$IRLHI2jngF>`SyW~MsG$-n?AE;zcuEwq3ad(fgYCIXbIQ1fmNCj&!9!*0<1 zqaBd&3WIng;Dsz)yBIj5fSb)}olase9zO-uhawPB&}LN3^5bbBo1(q1}#Sw_%K7e0HgvmXvDwW zNhSc)ntHMGI3z)XCbpb1pnhZF0c8`^0@DPdH}C~}IY<&U(8WQ1W&jn)(3pC(7Mgzf zTi$_64aRO?(4bUW(2EsopfV-OAdiDCZQ=-g@rVsG{TyP4W)OU(Qf*WgLvJr=xlmv) zc$GM6xio7RxKzzzf-Hj%co7Lb2$6p~csnLX(2M7jF(cBQoq^$XH>fEB8r>-ie37&o z=4wdw=(HO%5QNwn7+zin`xdOT8{}iDpcmJ!AsY6xZa~>5K(#YJxRBZgk%v@VW#D{E z*vFtL;lSRhpjl#6AFtR6_c2H^;6*y*BzI6|g%-wNCt>3)63AY|wmq z@(V~WYV1q0F)+L|VP#;*VguLhPho+@-y+8fN|T^XoCmrC6@p$!orWYgUyja3P#^0> z1W14H18!_uJSfSLd|gDe0Q?cLCk!a9UCO5n9`kVaj}3(-fQ zp_6V`P`S+$_~IEP%E7WuWiP%zgss5LWw z4WUB2Y9Uvlu?QN;yA$}rWCtwFr-G*EgI;`wtkw_U-|qSX?hm6;n@vYmCU~# zyk(dp;DyZu%s`yO%)sz^8n_NwyB#wGYneec0ce{y2P-H5174IXVg_J1GXulRA|^=Z zfukEb(k;6Z9z?f6O?gmjSMnZ6H(L4!Elvh?e864~eF5Dw@`8WA>kE*-_6L?(AF55x zV(100{toEv1ucVz762un^ufP9uq^1s+DoX(>MnRgnMn6kkaAEr3YwNo`!R!IDiZ_4 z>n6~!0tcj2*{}@i_!3!g;7r(t88`_{3=A);K?C#5;IbQ(G6G(xt$^y}Z;1yDD}qm@ zJJ5Vc3{=oGA4m&$@#MQDs2>F08U<>#2fov*pT@Fa+d_S2*uYB zuhs5`E_vP_`UYfnz>7o%kTX#8rz0Z+!|Pq(L2tY-!c%&$6 z>cxz*M+^)MuUCS5D4(B#IHxKd0t>o(LHtghrslmM216-7WGF}gV$*B+EH=MJS;~f!es=^%|89+roNZij6vc3w$c5`%O02NjswymQh z11LX&*rtw-44}OmAhwR9BLgU@g4jxqjtrm#0AfoxIx-}I&+bYtNQJVBlT#UrQj6o$ ziV~B-jFeOeO?!dVoYdUZypni`lS*<67(m0ZP#oI*CJ;QPgk_;o^Dh?Ah#crt5su?7 zji8;K46kp2(-l}X>d`LEKiO(U_(6x5xN;nCnE>vWfRf~Ov?PgDD+{vL1)$^$*V?!N z$^{KvHG#?=5Ffk@2)vdXR7`^=b$5V-K^#z%8$7%W;<$1gZ#V#x0Vz8H*-C5Vq$Dh3X5@O%*V`8?3j z3~Uzi%M0h5ur>=gz!1|8@_tz!zo< z!R2`XNG-@%p9vL#FCP8^bs#{CNI_@N9Cw)jiO|L1(hh71>Pa)rKiFz*pojD{@96?Z zC}@ZQoF2NTG=c}_5#~g0~3xhoVdOc{}SXBW-NfEfzXL<-Or$BQdxNHO! zPu2%(HDS(%mMs!%!NnBRitfOI<1C<|REF34L4NZn2z>Ev4Oj&zg*br=KX9*x6_k(y zUPOk2iYCwyT=PzFT7s@O1F-{M?1pLuMLI|XlPy!El@#_jm6Pmk0$vyCey(>g2l%w$wC@}}Uxa$UvU63O{ z2|D0~&ufT)FGu4+P__tsu`3H4ub{}bVki*@hg9H;l-2MU0d=lHbC1mx5ey~#;3_5} z=!G*>fh$LIMFLDbA?SrRL>ycufom_+D-fE0iPVBNm;HdGd=`chW&Zt;n#gAYOW=z) ztHAa`#o+S@JHQR1^AJhMtgTZ9qyhqGOE>{4525QfvqWB;gJ|e<{nK3g2VM_yTm$>~ zwRbltEAVs&CUgd{bi492A4ur-{nP2l1G*aHP)fJ!pUwb|ZqNZsJe`38pf%;&JyHU@ zL;nQ5*m?rgYyn4)@1IT%;{%XI0PE7x-4xpW=0(KS|Non7Il!ad9L*LCrA)8ILBS{( z^y2SIuy;YFAt>Q8SigCZm9EKvvL2Oxzbojb=M=CO(1Af-9GxCIFFsuXHR*XkeSmI{ zoU~3au@~pTLZIauzC7IlES-TSFV293TsgWqK)0%QJ8FRY7t29{pg{%DlGtu9v$Rf+ zycd(MK<3uEnYw*>(z*lG(mDfEUeth;BJ`W2bvos|NCye}@_>39-A-9)osJ?eLcl^C z-GUG!`O-Q)B3{^o1i_sgu!(wUofG5C7#LotgTxVr8l-hLC4j{FLE;E^8Krf0q=3Y~ zUj}&<;;*#s0I{^rK$aJeF8}{O!TQY$t2DImLIfUU{T?Ac(t6=~V%7`8)pH*NO}vAa zfFLRfEbECuQD4fwLqLFm;dK^x8Xnv$V|)<+=|^_E@_;5ogFrlA4$y%?fgCSDTe87X z>noDh>A~{?w3!#wh;)_cbP{+W22(5387T4sv^@)=Rw1p^L*fOf9b*bUVt~$crk`T&aUb~XT&FotIKS3vwm;`mZg3dnzA0!1j_mBg0Ak=CPP=PD)@;Ru-2?{^( z(77wh)G7b|P#(|?*S*XP3@@Vo{{R0X6l6bWHIGKX3r)CXvY^gIcc@4=OBZw;o#O@f zU(j@bA84$A5#rvTGhpu3%3|dQUkdyTE+n4C#=jkO@$F@p5PypxGx!qeFWs&p-8>Wc zL7QYiCnR+I`wu@M0mKHyF#mqnFKOMqATDToF(@csbp8QPsDtOB!3Jy>40=(5Fn$xL zlgcp(iQAz%r3@d@T!{#H;|4{8L=nr;sp(5^{n9DrIX zF9Kmk+_(rbizVR2dYBQV?imbBpa61(+R4A&$py55^$R3*@Nf6v34D=o2&50ZW9Y>a zFdID2|H5M$G~h}MK?w@FjBJW8C=0yU{RGc6kwBH#iJwAmGGS}xc$m?!!7dpI>dWMp7ysATnQKKakF^<*h%lPA>I(4|0u zGB3_D$%z%oZK!+F4enLD2%{4u) zV8>kmi-ML4q57a^zc`^Ox|Nk#0 z{rvwQmj9-~_2+|%5K#VWh6}}jvLvXWDS!)kLPOCNTv+&if%YA~fIJ3Tc4vK|RwRot zixD&wFBACUx&&z1g23x5AQ4bULMG_NVTc$g0`Ztqf*gt*pz{Yn<#o^t(Vw6u5@INfiF(ORe|^~K_@M|DF5;Q|BIp@;9>(@ z#JWv^rlC?{P+)+HSYwz_iBAT@FYr({Xz3ddJd8|1Yie8#0zmWCGJ!8Hi-W^}e}AY! z>!lJ2kR-Uu3CLmvof!3EGejPgAVR^Rictg$fQsPBpnQHEv{n~dbgrI^a2jX{p+?|~ z88D%eWN3tdb0JG(T6a$gu8UYL9br9lSJ@%#HhX0(KYbhaKS$pyzd7uZkt#lU_B1sN#)7{J|Sn8lO@8rpZ2 z33#y!s)z{`)u1i#AQuK@@pXeF=Rzc33xQJ(8`#uNh}g?!NOlKD(A7!MP$-GZVgmUH zlpH_?1%f6JWP)CVKs14+_V>7gq*_mw>Vu8t0-YxK!U&=QbjyS57m#+4UjwuFz>=a6 zNw7N@v)I6HV}yvk3v!m1!mes4_LTa$Ao&gsEr*2SGg~EhN1iM{j(z-pE(mH)V zys!f~?nT5`NXmf}VUYS*1QxQOPy+?SQqbX!dJvVM6tBg50uD*!WdrWg4X3^ zNq|Fny$CqHy!ieFWC5&<=il!n0oumQ1x{?f1|ZY_fmS#&Ff@pDhqi$0GZVOj6}o*} zx&v8)KzlrOU#vL-u4B4=TRI(CUi5*M_=0LSu@|3@fh1T0U}10$<2Gff{=fX`QZTzyq3JdR;=F zfG!={?t2EZ-xa*zQleXg5j@@tS~MBLB>*06@Ahrs-yX;WGOPIjXwF|I@Wp(2Q2DL! zGJ}bM;l-uT|Np-@3nET{*7ZVTd`>^q8;BV1gbTrAybLY`kMU%fP)R6c{V1BZTzdkb z;qt=65#cR|41~HHAn(J}aRj|kfU7(4S{sx;x_x!hxvUZL%9>!60WVG+2kQ)Y@$e{! z!O`j311c$dLwwhO8+E-tu6sbu`xBtBIRl!LbqMSZZQFU5iSHzXMAuWcsl#t1Jzif#=qV51IR9LT)qg}0rnoqZ{48^;FD3#e*iaiL1_fk z2nIPFQd4z%v2=P^yx0#qC=}7Ihq6Q_bUSi%I@!Ef0G5UqH2Wbep02d+0G_nYK$jQ! zAoE{N{{<2#PXb@8?1qIX__CVpL#*&-B*@$souDPdARVD! zK<5};33ySCti$(9_C;1`d#)w)5U2wj4$=X>!7Pivw-;nc;EP}m&_E@~C!poKAU940 zEqr~U4N}X$zZE3f{DYCduNIu6dO?!>`=|JVbhlnAl?FF>K!O1;B({NrD6JE`hW7O( zkQ7*b;ETUoVN#$Ks{H%GD^~gUw}gU?IRG)H7bF+>;v$OL*O$O<0!>}Lm=0P2%)cKz zp~b(y#}%Zx`6nYp_f(LQpcj+jx&sm;p($BHcV)X`PNTFC;;>gTfm{YtReEE?7Jvn-Pu0422h0K`Vg4 zHi3dH=*815uy6tKK@#8q4|pL1(GERM>}4@1`gVXczqA5%(V?B`woa(k{4F`4=-Cb$ zePHZu1szZn@FK$>lI}qB&3GCeu*M#&+J`hhL?)zlGp2PqF}+ZH3#zptnGAHk5a@i1 zXizvn6!J{q-yY}?^g;^a6_h}8c=6=T|No#q6RO&OZ@^7>G_^axOO3@qty73wKrtWa z@L~Z-9AqK9z}W8O6!2o@W^mY{7~=Gz7-S(E!VLcHflfg$da+pO^uirv@JmoS>75D+ zvLNuW_u%Y4M++Qw-J;-;rB{rdU`981R{muSXbB*6l!Unh9tGK;@`JJ4SBHQ5#ATqZ zW#Hyy5F4oR!-K2o2RMpc`xXcH_+9MQ$Y+!3lYrZ-w!?j4rKQJKo;vmwYi`U z7Why(kaF)GBjW!LEM2_$BE2n3ry#WuKr!i$LxI+X!MnZ3Hp-_k-Qp?W)7S--E^aVr?2I z^1!YDDF?e0GMfx$LajyC6%xQ^eX3R~iy7hS-VnzE{{0XQaF;PbUAF3F8R$ecl)C2G zMsSh<-AE6S699DxK?k!1zTko!ISg&GgIx!jgni-k3N~Q|&LbF|UIEai2+$E^pxo&z z5cr}IVhMD&&X<4}3~kUPP@>Jh9kyBk+)W625du{VuB0Hf-^G`p6@)gBT2CRZdn#xg zHLX*`@x}I+pq)dIgW+H%y*RW1<|nXoCxdjq3<2HopbhJQ)wjYNAh8gfUSBXS2GP*u zx)yYIclAriumETbz#pc*R21VJx24}%>#BjANTIA^kePAv!Zp+FgmA5=8)Z*K*iwH5H9 z4t%a6_<+J*$Wco#c6)&{9RGf>5>SU|=J%gLpb<*YL20x8fzHj{z8-7?NHVRn#TO*_ zqWJ|V%)qV#&EE&~_JWRX3VgwB1vU>fwFjO^dXe=4e?0Sm;u&;|5&!mHkiWpKRFK_Z zPeV!>(3l{o2LSQSeo&iJcmpUfL_kY(K;r~0kR|}=a2UoH-$9FYnO^+=|Kjg+@Sp>z zOTE1X+*c2HVc86eH5+i!vIu;!4KAd~zke#o6|I+Q@|94`ScGT^2agGx`|FYsRY3t6~S1Skc7Hg9slg8Biu7{5Cfk)$C+;|2_f}mhK z(**TAf6FRZ;Ro{Xi_IXt;N02s4|R4LnZDkZ#RT)JJmgGM&@R6hn<1(oxfvR8{~Mu>D-qn80-Bf)wMpybdLaRF z+6yBjU$DV^0U4qP<*ms^7pESBiwy9j$-H`Kg5+-jExdcN4y0fu zh*$z5=7W?nfZ9Cp^6Eu4LJMfd1DsdE!8rwdf^N`@RWJo5vKbjppm8Vg9hRU%H1I_) zOtRD}goM3BDl}q%-KnW4NR$q=rNHBeYB6RPf@&BXBp+ z7d*TSnnn?s(A@%FpbeUr+y#<-9Sv%~gYwnvI%p6;vKpw)>VOG>&%yix>Jfl4SL?}A z&?XQp6Eo1#D6rs#FUW9^`@lgGD$&i;1)0IQ#L(>{D9}9xoM}4)4PF>O`u{&80d%n; zcrNG!LwBe|Hwzbd*=zPihHe)Dfo>0%z!%+c$EbrM0^}W@3EhD_{M(tJ6C{wzgD3FC zhZW#S{FitB{{N4)feBd%=acTp@S?;Wybun0mF72h&`LPaG^+KR7dzb{ll~JxhvSE& zL(UKbExtXI;mB|WdOq0B3`d4NQ1+S(M}{>}_S_6dh8a+HZ-yg74|GjjYX)Q;9B4gV zc?M+d8;G5q0a@<`GCw)PkpWbEf!F~VjtrooK@i(2197&PUWOwBsCy>Iz`&rC;m81L zUW3$#W;il{DrgX!Bg2s)DYK+F9=g(uAvYyHB{MB8J}oCPogp!)I6gPAq$o2PbU;`R z=+v%w&?2;){BrObx!lx}#FWI6M2PCV(wv-lRH4k`-1yAg0)~?OlEfUyDmDhFO;BE0 zBG_04kbUtW`-&1%GE0jQ{DRDq$O(?B1^v8=O_dz=gIhqfY zfm#^N2TMTXJD{6uIJ%+R@g6M$H9!Pj@`D!Vav+TBf*U8C23mvxGA-;rsEm5bz`y`r z=maw&9@7+y|X+3ewf-RrccB zJy4;m06IIBBdyc1!9h zA*#T|w$zIs;N`fWbvqp0EnOh(J0a7D9x^ZPfaO9#E9km=CV=EXjti7~aTqLtY}yV^ z2GGeBP6{uUgXNG71oa|4lwS0KC6G z7q(zIWCOv@(|Vx-mOwTQyuLrJ(@EzA2Urf-K(O;X$)nC10iF<1iGWyc+TKojaOIpGKRqYi} z1>o~{K&O#GGF(1Pyu<@MQN{qe=O&8*3L!ZjWDFB%A&HR`DByHDUB7@DnO}llB*Jxb zbi00exf-P zfu?=JdutnZf=)Wz0TTYant#8m0%(>>ft7(_Cn)CAI(@&q;04|D3K}Z@67-^QA-Jsy z8dmIf)qu~by#g)71(%hef*ibC7JWUvfb}W(d^)I8)cz9`42b!3P`jrXA_hu9q2P6m z7_0I@rpSR?v_HCiRrt4yI0k`cGBpBTm_ziwKGo|xC$KkkMNqHnjR4R(C(xGSURTg< zwx9ux2Vx*=Wk9F+fX=8{SOSZ@0#LscbUmnCDNG17{m+oa*9~&ojUOO=0?^4*zHU&P z>kD<_8Q)nM7&3mGo6V3>aeg+#i=T4f<6roOw%4 z2sm0Czk{RYC1^w$f3o54-2-YgFhaI)K$6Z2qhe@W^S8_dh5dflAKkt(-6D;hp&k6& zT|w9QzTkre4QOxT4e%Y2kV#VC37{Rp;F;TB;BF;&l9YeD?-o$#UY`f@DtKW~x9g1n z(8kvc@Z@6XgrIKMj&2Xo{%5$h6W|*{__w>B3CNNF`z-w%*k}CPL$`o@d;%u!4-p6N z%03YE;z1$Q2PM%UA=d)|FV4<|+6Np_L1&dt z1im;55$J{*z3nP^j0&RF;l*;0R`4oinQop5&=ai!onG{Vl)VI9c+l;t0iNdrFBpIE zd=A)`pqo@d=hU|zsB;GG68C)*_@W2278o>P1v-cpe4I~)A3JDNNh9Eez*lIn`u+j6 zF5d*bn1?Xv^;YO~o(5z(uNfk>6Evs>>i_uaq;;|gzW4)L#S7`T{3v#0c(KO{+;3?- z0xDCj-@M?lh7`D_9a$2`5D4qX#@$E9GH4JXuzXmZc zb-OC0bqc)rclrPSEH2PV;Gn7h7w7Y#3AB_0vdFqr5InU9o*(6Uu>rKgxZ70$x&-hn zXlGq0q$9cAS0eBQ!)#bIf61zX#Jnw72(rxXVII`<5(7~0w)JG4XjVN$*|Ax0ov(#K zf}lDw5g`asUn&nSHvYU&zx@9{xC{cf$R$C}dT9?TFerdf_s{tx@UH=5UcrX*@sz0F7OOVO6-(f;u zUJHZwL;MMPu>+wFd|DUygsT@#U`K#1f&BwA5OfAvKV0DtkdW(_fGoxrQ4n?DLBD+v z1)yRcw2V67MJz-B}fl_|@Xx_)bTr7i%tpQw%8D zotOe%oV^I@dvL&H`#{FL<~P0sTJ_!;!1SUPBmgo^fq%PTP!{MQ!+;kSAHn&$+gAa+ zmZwA(yt}Jo&|>kRObH&u*T+E6$bv6N@fOzG|)<>&d?7pL@z?; z)Ze_|0x?f^hpK>vM*m&_JJ*$mf4c`;;EQ)T&`<&;@KAx)OQo<-PyvO)`3vBIpHPw3 zOQnj?-~mf)y8v2n4?5yWCJi(Ov<##Wl5JQ(CB96+3uZ_-fm&N||Gub$*~i}kI^aL8 z+x1IYr|S!2nDgQ;fKnZ3qhyUJ_&~!ifiJ2qfP)ld&}-!^P{-iQ_gg_Pk|DyNB0B5; zi?3h6u>w-`!V+wVuK@VU0TytE0&m)WQ7|2>2%NIEfZ32N5s?iIg%TlfpAHgxY%eaH z2PXm*a3bJu1>MGilJP#gSa%+g@!q^x08$Uhcr4)5`N9v$7A2T1s2T6Wi_G(gjQ8e6 z^m$MaAZ5G{0WZ?0fgKK7p9af#EC>%nGv0@w7xoBsu#ER1@C7H>5ul9s0i5pN1icW0 zD|`bIf@Hjh5J7P8xWd>MK+*Xj;Kh@va3_Gh#t+(N`{Ep2^bI)Uy$N`6I};X|kc{^s z@I?p2FtGDM%cR}}y_ky72+w%nlofLhDa;WWk1gm$5=09ua*WS`Q!+T?u?4&cIR{Q9 zFj-NMF|XknkL?8uNC1|@O2t8^IjDfHW(KW%;|O}O^({Cjb-Sv73-c22Ql-!jupBxK zA`QxdzHdNvFI=VuA_KCwJ5(aAQ}D&Cv!Ib6(2-6uX`LP{FS^eD|39Jmh=lc<7we57 zl`E*n0>$9^3UmAkR#SmG>b^f-xSa(ZVFg+V*eUSB^6dZrFG9|Oz3(dkDo0+Z!2%tW zk6lGt55Oxb8Bnfg2RQ+}KMAyi7j%t!>J(UXe(83V0sEQ1wFKOZ1SP#vd2nO>&x^BX z5NY$ri~VOn{aatSvKmhQ{jOg?H(zjqGRF6toxUGH*%ow?opA;<9iS%nKQF3KjLbQM zmfZgYyr`HAa~!;$5&Z}gLaJv15b9vb{ZHTvDY)0*^^7`PAyPf_2_gti?qM)CIJy4` zc=2@-%)URc1ra+d)Y zF{Rd^k`fZ5B@i9mz5*a+Zl}Sq9V!4CrGAld8k*L@a#|oGUh{$K7y(clMhe6S86*Qr z8qg}{>MKb4_LYHEF>J^c$u@{ID1C?i0Ofdi^cQb&!FD4OH@e1E)fIt5NCf4W@- zK#gorqZG7y6L}v;325uppKf0PwCNiD{Y@`S85mj*ltRwC{qf@KNl@QF2~_xj+5yi} zVX?>$J4yD(i;EyNFJ7Pg|Nq4^5b^LN$N?Z{@^nMj*OW+sI+~zCFA@IjJOP0(=E4m! zgN$HdaVyv=WTmcuz%74pnZ)Dtf)%V(3}od_&_X(x_}dep9Gwiha_tC*^_v&G z`e-pq#C;m*`{zKB0KH#>sQq${Z$KMY!+ZCd{Qv)dr!lteX2-#|>4Jyzs{jB04_Q2M z0J?YrH2>WhdZ*j z7q?u&_Pw6AiyJg$4nFBITUj(PUsQ?3FA^XIf}4;Gpuhy5wFn8@UY-eoFXS~KLA4olocV*G7x!TyQDOq# z^6vi&vBHUMJ0G?D@@-3WZKcp<3J2c^d^;9eg%1~A4LzksGo&VvS-lR-P@;y`

CPgsO63`y@fEPtFAWJ~UBY@5;Y`s(`2Aav(?@hz5lK|jHVeKzj|9sIz+-vVlNfQ}-35cGl_ zW)*)+HYnCyK}W=eK)spar;=ZS$&p#qzl7Wkqv z78?%f*c$4LPQ?qKnLuRe^!)%;dK$JL$dyNyWZj7 z?x7I~$won-QUp9aAD9NeaIrUp_e2n6h?t{$BFIiq%7X>a0y#W(MuP10fflT7uplY1 z0+|LnY!h7g^n&XwkUs)nY&rzWha%X0z%2?+U!bF_t>9)!Ku1J5VA*@qbTxBIZ7Wg~d3pcW15cYwEOV0Ti52m`}Q&>>?m+sXo8 z)WK~_&w`xbkH}prQ$Jk0z84+Skbu_+q~|C`fP=O+SPg7+!a0K}bVFrem`N9kgS?r*s@!}B7Z~QHv z*`Uj$T|f=2o!|{|-Jy5Dw_||vCFq_Eo`4q*TEP`MsG0I21@5>MaLj`e-+m9N?kV8r zO;AQt6a&KxdvMo|B>+wGMfh=WO#zMWJN)|trMg?dmv)0Q4ulI1$QN_uz*RaVA%}oc zEBL%#WIKDIc7kg@Q0@tQp~eqNH;}CU>JKCC;=EZ1biOI*M1m6mFDA%??E>}TdqJC9 zU#$NE8aBJbzu!r!y9a#tb7wE;_;m1c38#>>&Q{QR;TIiWK%nF&!2-{4M)H zW48b6L46|dD&H5;pp9@KE3mc6x_u#m;mg6l-!qN*qV=I#Gq6`tD%uV;kUPQCJ^b6j zrUtw)`2wnILEBA0OSN7v%aZ5c4mru-#m{hPI^u6x0a~HL&c7XUs^Sa&7I1{7b%G7a z5`mlc>@%`yB)C=?W;Qr(!OatB?7R>%fvkMr39|(jr!Op;!Oj4!Jn3`{d0`2cCRJ}F460Z}A19t159ffTo( zWCALtx+g-;)oFbLN+dd<)i>Q9A!(hx;D}uh+Fb{3y?uGH7_>!>1)RpfmcD3;fCg(x zG`J)>2)dINo;~@uPX!qf)ZGelYyh+X(A$Dk0A(?BLkK!-8G3Y{$Z7nd8skp?OZz$p|K&fq>9IFLbSUr7bNka__MTF^cBpwfkZ z`&1AGsgVvoVCcmtyOA4Ec4)5e1+}pQUzo#O1$X^!(7EWKlWEerJ*2=Z2|j~%rGeaw zrELL9dHVxPS}*bU&445_ew20zL>r``(p1tNz{9_vDfkZJ^LZJK^SOQ86 zJ`+mdm5mRhKzE=5td--+(e2Yw0$GK6fT0^C=?I#7%09@(?8E|Z{rYlrPZ8_@o%0VK zAvwv=9l|Bj?WNG^2s%fKf4@^&^ADy{Rk(V1YZ=m2o@xUsve`hMeJudKY_b(B@&&xj zYmk+rcJ-)POHe(g^5=#WnbB zPjI;mIVBl11&yVB;UES|i_kU=A}wZy!ZH#p^}po-&7g7wyqL!dsxVoyAa@vHuK+t3elAxNR0(3GL zD9FKiq6uSXlh*Ad1?9i^4%*NLF15daM)A=1#DmXtwLVyD2=M`U2!aJ+IygIn zMlj$#yKp^7(Y*y_2x21WHVx2ak6<70w}NJfK%<&>(mDg=UKGCtEwcvYG*FTJ!XyY9 z$R(t813(RAP@)3YC&+!6;2oeK#L?DS!v#t}chb6hL2;PY=^^*xF?dg!45+&R3oO?! zFV4OJcQW|*2bO_ybI$~D2P9CSGxP=|=YrNHb9A?0T+0JK3Ki4>&tQObcfm*fseq3_ z;^5y7=^R4S?ZJl(@P;?IB7o;H$N_=i1Oq*nF7SocHc;JbgT0Y@8FW~C=#8LWSoaPz z4ATqk(}N3q>+N{LWeO()=nOn?e-pfV8rF7t;qn2LH<4S~O#!eNBcrA5x)!OTL+?ZL zfzD`0YiWzXZKFy{JJbOb3OHKYeH>^lZFYZ{SBY(Dx4PnKY3p$?FuY_1oyX1wZfQrr z{Knt%9<(+DG{~Tm3Nipk2lOpSRVWAOK7iH(b)b{-L0xE20`-|t(jCat84Bt*yK;ce z$p-bNTe`r>)ZR2Hj2z+Vv3dVmr+L z{4Jo83Y2NV)nlCw)FAM=@-AE`mso(?yAMFsr-MSL6U%E|%qj}0W(2jxyPLquJrz1V zSU}E(a6MQc^y0T4Ebe^K#)}XIaNvup z&Y<9imKKPr=N()#tm-KO9i;Bb2JW4@a&$v4R-6V?$KS#Xn*0C_(!z}g_uzwGd|C^# zLIC8A{T?N)C+l>eJ^_yngfOCB5e70F92!9ioq;T`b&&%av$R1AYXsMc1v1(JE6Jg8 zz}yY(c*0c%y%5?Dig=N3*Bh{vP2gexW7uhx6UZOXphC~O!K@4nFSS6&z$4#BS?&vs z1O67!8I-7HHE0YLHTlfU`S9F$BWQ1a037| z6b@UxoLE0@KF9f{!_XU)O6u?ajutPDX6kedUE7p`k9SR+xLFvf;SA{whrCnhO zx^4rP72pI7at!}|F6)D}CRzVMLsA@&0koYm3=9mQ#dDz9fghPCK^G)7aCnf>UufQhlncChLUeDK7^Imp!~oQ@Z$ecP;f&#Z|J6jPH0C?Nj?G<;QRue zWbF=AfR`ztt_TOT{2{L^0%}a(03VTp>Fk3K8DQ>)+X$_9p#C^+fhU84b~Zxq?0_Wj zlAsrC9kF~sldlXtnfSkt>^y2&yJmCfE>AfyO8r)mx4znZ%q@R56y)eh(Jr2lJ z(rcA&-#d^IS6>$6c64^2HOM%UbYEc4RZ#xeiMB@nGnDE z4es-{J3!Y~clv^l_vLQ^-5dexQT$2k6adY<|4Hlgs(H}~J~IJ4TGW^XI!?9%bmJ5o zC=UNLAF2y_ae^B(KE?yuzVs)pv#|>_y#^YL$r1poX*|>eIz-~dLR4j-MeHwh!HxMp z$D2T-9pL$E?f>AV!=RO#puQAp$=v*ltrm2u;SZ?mdYnLKQNMT&nvs2dsoV7r;;{1< zk3f6+SwZdpKaB^Ef!kv8P#1tyrgcsLm9{Td{{!_%{(wsDZl|QQ&c<7y!>gu(r+d3Y z|D<(x-2n-Jj=Y3<@E%B@7^DJf&;yV_637v_iqYmDocz6V;Qg|`KcGPz;vw=v7j&+` ze%~M9HPPL!f6_WbJeXdHLq)SMvUR)u>Fp5!ooNj#AVK3}B8)FS{{^kKaQy+ko$*g^ z3l~TYc-;EnLk6%Kju+=~s=4?Os$>mR2|PeWKz^BqF4_PRZ9o^D1QN}Higx?{>7CNJ zgo%Lxy!kEr1o*B-7OoebU2%1#i?}|u#kHG$i>V=2k7m#QOx+ojyY+5^X(GwuG8er2;{sr|zLH8-I;DHo8 zpiB?m&$EOJe4lL0*Z==_t^@@zNai#0eX^}7U;l&dUSxRj`ZuWAq0tS=*}Wh=$6K#_ zgUEt{Yw82&k$hy0`wl?6vR!QgUZ}!F zRY1iCL$@zzn}A)=ix>x3rDf6G3J%N$SWyMK1*9A7fyRTNVkq#%em1ZdjW0ozrgcsL z6>{CaB7xnZu+xn-0$-f?0`i~$IBdZ|s{ZT${})cbKoJM(V@kB1tSbSnaSk;IdNCXB zfJFZ7t~Q`+biwzENd&z(U=Ma%z>D@gP%wa3%|ohmsUXmiJ>9-0pi?A3K?fQC1)bkF z737KD7A{ae59sX$*&q1gTQD0#^AQEm+1cRX;%-+F$Q%VYr-E8|t|n>SJOXK*y$pXq zOD)qnr#3)Sh3gw|Qu*+jn}2`khvq{LX`P`T`1iYh;NRa1vKn+A-wSF*CefbD##AdK{6myz#>x|LEA6VI>9o%t$RSHsPy(O z_zS)*N8<1Q|3TmlBpo^C3=DzYU@rt^Idr?41aw0tWxB!MZa!24N@E{DLopw^LoIq; zyg(OCNd&%Vy$1>a1ODxy4nbLrFT}Dy0m=bt?q@ml_JZsSe38fjj$Mcvhu&6@y#X)0 zA)=t@@-+y2vBwS^C#?rc5<$VydZ|Vlxog6$~;bvb1M zUYN0hER#v=Y(4P}Ty1=q+5E_!`Ov{1plfpZ_lG#DfY!FBb+>}@dRnJz&x^^R15`n& zX@8(x>m~k{d!UImQ0oUd5kZRCUQkl#74hhtI^`=U4Qudk?_jb9#RNF7Ggvb)1b{Qt z#D7){pc@@Q3jSEZ75uV-EBFCY0QCbj+#&n@=Ai8N>-9Yo*bD9>C_v-Vq?g4jptl#~ z08m*1@;9jKB@_7K)FhDK19pK9KuPPIS^+A^3^VDD5= z+6v;|-U`Yp0a*_GpfxR!UWx)V&_F>6O13LN#oio{@16vKlJ<)PCQzac0PjKP-wwKK z&dvsw`gFl3J|o8!q{;-xRa*B{kO$H_MLb@t1|6CDaye*R2|U0h2Rf}A)OH6IPoX`a zYM~W$v_2@4_s0GI|9=;Q188=2svo#nnAX`E1!@k03wn?b17GZ9geG3_nW7)MT}^sH z>(~}Sgm*cBcZG*O0h#PN2fSY>t!imD{xue+amy}=)r|mFH2x2I7+&GHM#>0phZT70W2LlC4mCi zA+UEUsKN?@Mjt5QZkzZGk}f&^{Qn=&+Y9z*?^ICv1B*~-V(o^^^nyoZK*Ph3jLE;f zsSC8nl7G8z4=Db?`yA(hY8ThEuaw$@JTH}FRnqv(mKJ%nPf4%C@ls#f~B+dz_%)14B?R*y4cR zUXZPUSq{D6R#i|hxTOUvhkC(FEP{GndtikC|Msb%Y!Axspo$k%cD(^-b{8*|fL>@r z$vwNNYfhG_H;5~Ejgj{D2>jF?ldG_)Df3OT_ zFb~|M>ueDP%bfWL+QsSX07`~7&><-Scn#8c2$W8PdR-d=y1@p5l=XlvECkiK-~k&ydK!{Eqng$Eux@&7XZ_-s2XI507M70b7arIy@wSX z>)lg9DI@4b49q1NAeVrf$)Iu@UPM0LQpr@ zKLIbEgRO=+7UI2Lh?{#MR%9{4oT&{lF5tzYDv-J0RV2va25LnFy+|zwN%BCNlWCof zH7|re{QnO%lONQUg-G#l53C7#kzRqOI*T#O;e}x`NEEb>X$rXP26v`VPib%d$;97# z7&IIP(!c=G0BRQVZ+D#%@FG7EW&(Jy5w-8lzu$EVXg5Lur0etpbO;+L^#^rB^1_Rc zkmbUV2!RG1|Msb%1~ok7WNSb+poSdit|Cz8WWLbtYr?->BoGquumIdu3DN?MXK09E zgz`~Hj0C)}0juT!nVHtv5(;Wsy*Tj>+~)ZKIy4>u#9}$`AoBtYFRtrw~YF zBAg8p40w?SF&Ux+5JHfFDb~68d-w(_eK~3IH zmcSPRpo3apmi+twA698jdGQA{)%+3^rr_QH|8{U2J21-uyfz!OgwiKK50qVgD7QV+DB0x4M<4}m%|kg)FU1qBqW=7SW1tf2Z7lvhCg#lY^Vpgtr>wF;=- zY6yI>=_;rUaCp%Lns|1AS4i6Npy&eUZE$(<;*}A!LMjFC+XQt1jvGUT_*=l22ZLrQ zz!f$tXru_#3fk}cp?8Y!n{VJ26Uc3_hI|&|il5$*5(FPW zJe~kh48s~8&?-5L@kIedV|OcPkw)_YrA{yd(nDxIsMHDWDx`IT3w_ASeJ~TW1s&96 z0GH;SQyM4OFff36macCCUc8M3`!=o9^-Ws0Z%V{$g2S2SRg zBg2crKN<`XQSp$G#xH*~7#fd&I`-CYUTpuP!2r4fiC>-pbk0=7CP#)R(Ea1{wm|lk zgT@r6Z*gQe0~PPyg4ko;vIVinykZMtk9px1#2)j^Es(RZK;|TDab#$KniICgkpa}@ z2aR9)Y=MklN-!`mxNdP|05wfP{Vu01jtroD17h25aby6sdq8ZfEshMJ;tRw!-{Qys zDxN`XlP!)6py~j`Hr(RK0P53#&VbPX+4b}Pe~`HH7Don9^nwPKKN%bOh;KKPfCuZiwC+DZ6#+QKa0w%Zg2dvI_;ipkL^Lxmzl@={ zGS7%1wIUfz#OI~v6fjg8F;p5dROB%v=Yb7j$S`C`k5A4oDuU<(n^2aYnVcG*mY56? zE66Ni2r-BUUzHhR5MPv94C3Y{R=|aF6Dz<%nRy7I%shq=1Ju!Dvc``CyInbyU3ofP z|A6j$dx|pL3>uH#vB8sp;l<)#8sIyz0=E7CzcWXOfdPER0O}wWs9z5rTRPC$Ds%P! z|ISv0tN;I}b+)Qp1r5S-bWhYUV_@iV+kU2T|@Q^FkYBKgg!0AX`wstn~uOOQIk(5FK4hY#10`uz&<0 zniyYv|NH-c76^ilPXlddF$e(7%Ds>m2NmfuV3#;Ly|@5UW&>$jefpQho&~4tvyN%`L~CPfa;_# z0WUU3fNce>j|BHSMd0T2iUbC|Q27kD0VL?56WARp0MQ1X9`BwAa!1gM3+q7@i%1q| z)hYjW54*q@@8DK>!`v3|Lh>6IL-P@i4A4qe(55C(0t|d{_!GneQ0n6W4F$Y-c*h2` z5E_&cCJLA_Fa*6g4-x5Y-LVbaj|4?kVDHpB+rZTvC}jk6_kxml^Ffus-l;Dj;(s8D zS&o56y9};^6$iWrn{eYJSn$I~u;8DMU_q5nU_l>H_0!ur;}cl$2t@D$L~zMxuwcnH zu*!%pVC^Yiz=8!|z=EL63hLd0Mmlp}+tCe-Qv8ynp}ypAis`F#Z(GAte$S z4CRdA)gXZeK`)wM;-zK~^`J7tAn=72EROkG_A!8Jc5sKxDJ;L~9K^36oiyUd4jd|t_3@;Y^`u~5IW(?TbX`K^5gOM+Ke*OQSC6ED9 z+1m>W{J`F+pui8xVtsMpH7FoNUUdBW|33pXEel%9vb_U5BJrXaW_gJw$U*y^%32SU z$YlwD?@YB~1rJ(qG#;A80!mnFAHj+5wbc%=F}|Qf3zJ?5fZTJq6y_eV8$osPPOflp zaHVy2f!+85bYB9Gyh_PXTFBWS;1G7{Nw#YIp;6*P?v_vOEzyTbZ zprM%;rf}bjfVcFfb+&?yw*@)%wFYQb547AoEa-(d+yo&MmBJvE;Ox!6Jy0a*g)&SX zf6EL|Ji2lOywK+WrD7J)`h?zI(5O>j?^IAi2la~sUIa$7gXSS%cG(2IxUT{A1Aj|5 z188goT-buz$e=772sQ^?qzCna>$ia3-V<-Ynd!)Na1Oh19WrbP&bIv9r((^wpbQ(- z+X~9C0jO!FyA_mE1G>S3@St@fK`(g3L5>UnZLb53ciIHLu!1?V#2RJ;|Mpf;u>o=@ zC=?<27}Vvu_y82K;NnmF0>szV%$y9(M%e$Ta_CECJn>8ua2lKUlmM670RbF!w-%5!9pz=sSm#twGpTtm zh-560hA@~)EFcVK{+9U+3=A(Hfwp?Hf<|V+8QSNCJ;)`Y9LJpk;y~A|Ie^BZUxN0Y zg3q!9=SfGO7m{#Q4r~kzFQmSK_HP@5OMz|=gTNP+FejA=flifo3fKmkn*0nJ2Y#)A zQZ(L&s}z8!{J_P)@Zuy`rN<8N_GqZfmVyTU!7k$f9n!z-E38n47P3>(O#(zMHlfg#|9o+>o-OZ31+0cZs6g(ZgiZYP(37fQ&&paGPr9H7S8>o1`5 z4L}={K*Qr5;3RO8zvU~asz5~ZQ5C2~{4Jn`wvfc(%K@rIpZ&pwE~xzi$#ftUAV2bN4-5k(S#aE))dICCctAroFA5<#(mGokwt)uq zz*ImtxDm_`I-e_xIg1&z`HX{qdqYsDU~LG#`O&OBetCUQoPQAFLGx9oY$SLC}jS3&DfwuP?li z`uzWYMuQzRKj;L$_^AwyyAp#eCUDq;Dt}`on5a~5?~Iq=QXJIi0!2l@i_l%5HXsk^ zZbVQ$ zERLWTa-1BXd05cqZBS`068ItqZY-n-+`|e|!SdP=bTlSNjZfeU54aj>i1Qr+dV4`` z1tqYc7m~)H5}oIT;wNy&g@3S7ZW@{{IIhPH5A)8&sP%t^|dN!fO|Z$)MD)6ZB#>++-bC zi@6olVh(sQ@j1AB%>Xs4K$lE`j1GKJ4H11&4C*K4frv~Hkpd#(K|~bjmM>7_gnzq} zPrwUrMQA*g#$<6rDjc7n7p8DgH&BAz56`#Bpreuz`IZ-^j=#kdB*O|fK^Y;V4_c)0 z_{0DI;N^ATQ_@vozT$7;VPar_15jYXE7abp z3m^@Bo2%gVHz=_n>Mu~JfI=F4IT1LVPga7eR~;nZx+_4#phT5_dn?GafZkq^X`lqq z-3030fQ$%y;g=55DgaC7A^|UWU|RWGoIy1gBRBvif{M?e7w_ev=JL0I*G_|m7a>U% zx~2t+VR@sM%Qj9-JDx z!P-H^?L?3XFJeIZs6eA@t>7?vk>d?7HF~FlauX=SK!ypyE)BE;3mgF#_wi>zDNqDl znKT}<0VnUqLm&oN5y)OpICM`0IhlWZ6UfGZ7bhWZer<)~zRQq(Na*g{^A6Gc1sVJT zv|nigcsH;j6F6(W1RqPz2}*X`J$wRRtdfHUVyRdbC=WxD?G%`3NjS*2kfzLwcb-t+ zg3eijgaE{s4xmeGUV)PbDC-6GP6ahA(Yj|~S7-}@a=Xgwq%1DD6Vzdrm5OEYLW&5V zfER)=(GoNM?Y*Fp2uQ;atgQpo<^vC-qIT86c0Bh3wVOp=oCobl0#%D1X`sX8GC+fQ z;C}LpR#~X0OQd>RK~4?m?FFS|P=XA4vHbzajgVstcK-my84Le*ND%OEp9<=Rg5oRS z#r&HfIndq-Ur;G46Z9e$ZZ4#?4~}X_kr%3j&?Xl!)VX-5W72Lq&j>1js>Q2QQq zsmL7bx{{IhhzwBv822hS@U}s?91DSLE|9=B628O?<92r0bDQI5z{V7KV zP-zI#`{I-%1E?cuqX!$N(zQKx*1f zIWm9>X%M^ilp_OZ6a=KE{FEaDXw(EGUVO@t0n`lvovWU4%8>zlgF}3NQD!@x_&S@rFj(7V(B= z*i=>Ck9_>BBA(80E#t2J_p3*vJ# zQy4%r$d9Q7#Q_W;B0dK~WiU9FGdMD&=A{-fxR&IXFr*d5Cne^k6f=Na0kRZiU1nYZ zf^U>Gkq2q)!2AIJpG9m;|>W0JQKJG|B`v z-s%PDkOa`4M-UfOpYd;p+7pj%kMSiWOBlhHfS2~1OzZUh16p1k`Uf)675WEs^jY%{ z-r8!2!$G5OpzXbXvQO~vZ=Wb(J&hsg#eH#@rvpIdcKiNG>+Aq~VCi$v6l>_8>_a>t zUv^IbX-Mmw2y)_!4zQ#v$S6>O+}$W;J&hr)vk4RuFS0>*f4ydX3EDT;e1ygN&5M-} zAq5&J%t7-DupHarwMegA-47vMhIJPD|SAgvcj3_-&$2qsrj2`%|OG6G-7z`c+N zx(K{G^iR->imBkf0j$*>76=wif`}pp<~))DU)&XgT37{owG*zQ~itzpY8$dKv?)!?(W)6p+~`KoS!bz!HZbksBBm z^x~=`I0f-FjI;;2S6tI(D_&$Rq2DoniZ4;HOr!ll%DlrAsHWDisoI=sjLZ9oFWZikIIxXqT7f0YV@nL1_~_jM@US*ZR$iJ@+&ikZ070I8QK; ze?O?r1-fayhARz}qdG(Xyyi#)pP>vo7Txs^Xfhd`eZct#re66V=*&&fxt6H%1m^c( z`EN&PD0qN2t+R0*XyI-kc&EmtG?49}qmKVT?zVIN!@uA6PxDWfTF8lv3@5p-Ray|=O1@Ghs*?mmL9h5xB_-p_eAg{n+#T;P81t2a+ zF?hbRHwVN8DfR%#wq}61yr5eyn-4N}f*HHO?L_bZSkjBvfB*mA2_D1;H5|LZgZS6~ z{{Ii&`UNU$I~{Fa9Qz9{20$sy!=Tg4<;7OGKw7s)R2pbM;v!_Bn6yr>uowM*|NjTw z0tDI_nbsNL@S+Z+#+M_lJFp_HbLx_}|Npun2IzcV#DKJbZV?4l0G$(jtQZ(x zcz~Q(0LkNNon2laF_XWDeo~tOD1QF_|NlY{G@}R_YUSVVWEb$FUl5u*OT}O_Nn$}S zDq*4}qDZY|up#$AJ0)P18fYl)#Tm#6e&GIrUC@hMxL(lVIv@{#l2_o1)LWpQ1P7>} zIkn;D|Nk$hfb>CciUAjJ$E(0oWG=*5KVVEw(VAO3<=f|f*dgBNl(z65or zJ9}CF{QuuOb;0}p|2wCyc>Di<252{LZ!5?ikh8ldz5uN?eBl8xCj)c=NN?+gw~(Qi z#)CmRpfNoyh-~lFhMypFrhNbZzq=Jg>Pj$zQsa#8FoSy+eE$zxfzHw0^u_=*Jo+Bu zl^4@Nb7)$z;M@(Kei4HQV`v6g98{)z1isLNi`#Zj1*L0nHf{y8KsmV=#DZmJsDhxN zZm0scfERO5fU|U#4Y+%j{Sh*&3@Si%0$wa|2Ul_dFVcU5DjSZp?jGo@^2MMR#Wr9` z(CL=^`&&UV3z}SJJ{SP%f;E9AmO-m2zg&C>=7WYjv=0Wn;Dz{*f4eW_MoQRN2v6XP zPglXQlhz$7fa_u#a1O9ORVxkNMGMN&Aag+@k33El{I@3j#Mfx;sER0$-F)1Wzr)k}h~kUJ$hFLk2{MgC+?<6P*0p1MPxdtl)!Y3;vc> zj0_Cm)CH={VN-(<2>CA1m<=LBp+C5|Y&;0s`V}CcRLCH~}15y;DJXF$kgp8o$IkP-1`8pDfIaM50nC};$u@en9DK=l+f48=Ua;R1Fm zsLi*1B4`pf=*2xAcuayeA-|CO0UCP-ZBqsfr9o$UJ7J1S_;wi^gVu0Nopb5`|JP<2 zphZ*25g(7F61oZ>tdeI(S{g`SD~Jb?D^{h+OQ;ER7c zK&1fx_Fj;-z!w{xz&VT`w6z^Htwx`4SEp;GZt)ZT4#$_3#dL2h8X)o`a5)7m4CZOOyG+eZfJ;=D1cgJkZEsGu%93a z8I(d_Tm#K~K}KUc9)Q-AfYWUER8SEMik5B<9gqXS`4ChoLUZBy*`R2WfkYFi3jSfh zz`zO$JI13aufE#32vT%mLuK- zt&y4tQuyL7XgUnkmbd}(b@xa zf7G*N1uTKG^P9;JpZ!-GWo#(s)1qN z?w$&&#UVOD>+)|;1v$n6v=#t#?g=QQp^{~wFg^18|No#D+wSs!CfULHrQ?$+BpUd) zH+?XLM^9k)R8XT6o;1MT0_{Br?47#cCU_F&%uVosaK!UioMgpO@@fK&y(=wJgI8vq(R zz61(h_Rrw?QLK(k9ADwofPX$Q_y{I+>hX`na4d`xnP@M2@_XrDop#%xl z)&nK-SzNHP1niC%(}h5tVUEt$6`*=bCW{kN{ICXqN|zUv$g+^&-#-!LO^B-Qo(UjR zKn~;I-vky1ms;IZ8a+TI)r*;7U>60vm|zQLbha+J^#6bJUJ%JpDv-taqTC)N!2*%! zZJlxnl(&09@`2q`L2e3qAp%}h&y&^(t`k95$%7PS@xSOc0O{ob4ZHAf2UoN~FW4dG z1-!5WGdMb17hL-PKjSRuSUfN@;6(^zp?5%raWSNsJn@Yw14GaY8>sk;U<l+h|>c{0%Vws z1KL9ZH%JX&LE)wcDq=y01P0kMFa-8O>X6>n2vA`P4x#{%csIC17W5(qTvw~?04ugN`Ww!{>z6?=K`;4%dm*(FOc46y*Qi0}^|I<2qLGFEV4m7U?N&?%Rav+6B zU|107SgzJ5(E6_NAjs#SZ1ENvONamfB@a+GY&--?6`+y>lr}-;G#*4GB2d}^B~AFG zYvVysLJ52ks0#{v$Q{oY!RvWJBL`CiL9%I`6F{lsh3?z`|G~SRAS=y4>y%rVK(pX! zosFQB^nwSpdxR0x=LSV6sD=c&0qz$5?cn4Ha%Iqq3*fkr0Vh6>vOrLmTm_UsyTMHo zP>BaBhCynf)jp)aVf_OtmLN?d{_PV%r8Bg>1lp&}0xF52rR*1my=EW3tA5g&nx`HwwL?m!(-vH`gQ%!QPxFK+jP+x#y!zxw|_;~E=u*^f)$3nQ4R zrILsV1zDINf6Fn@D&}6$C?RM8&z1lGgFqgF)buZ0wcugUJM{o0g@DRIMDYhI1%tX< zK?NS7(Bgm=l>skWj)JDZA$@>A7EmhS-|mqT*gJIts0GvA3L1`NRbd3TKEZD229HoS z9+Hp+x2M7KFJwSvSucp)c<_WII3gnI(E zY!2L_f02%mfLW`-2cPnU6wD|xNIPe2Kf*^iqKEMK6#Ci|X zmH{n3hlz6pbc0>qe2^y)T;PM!4rn3XOBOqZ<|7&1y&wbm_XjeyUMhu-1cHUqIvtr_ zTmemHflIz7GvrUjgdi2lckzfaKc`AQ$vb1xEnbwilbMK-MT^G4!_HxD9S` zJpieJj7WeYB;dt4?CcJLt!GkAOg5+dL#uy-oR3&`gUu2jDadY9fG&@}L(p*Mr7>1e*7Pk}*RGcnJoGnbz4@!vR{4`V6%C z5z@ux-wv)O1G;-b!=8b?Q$ZuSLA|Y@s6|VMy{!z7!O;$~Fc5A%s1X9ou;9fmUEm>0 z6L1EG!A-d0fJ3;?x4 zKnVquY``TIXjS9tJ)oHb1z2wo)^7sO8T{V@lH-AHEPDx^zJV;;ae3p&@S^Sz^0FO< z!=Pn5pxG+xH!lt!g3M>}%QJx15BR)sWB>&=Xx$F$2S)}_uqCiCF#LS)$NdT01Z%p*ahz$89?0u z(0ZZF_l^vpRuPDu^xlyH6dj;7LQ(G>89-$Nh#ds7>*@dhAhy?gM+Q(Nf$Vh$`Tg<# z{~*6OgZ%ga!nOzb@g9V2_1=*I6qlfVp$6|A89-$y11kfA+IvR^(6|Z6J<=e%ZbID8 z3kq8(oB6#X1E>!TQuFzpBLk=m0h#mSog)LNg$WXW^v;n1H2MT$-+AZA0O~1$!s^C5 zM}`QfIhWo!GJu+mAT=l7IWmA+k|6ehca998Q74f4ZSNczK#f?C_}X`n^+*gX3=B)& zIWmB2Zw3a2dG8zFiZfH< zlgb$i<5Tm>7}C;8;*(0#(in;h;?r{S^NSe3>wv)fOY`#c;)_cXBS3403gS~T%ixQK zK+A|yD+-{?hceRQ(?Ppn(<&Hp@{<#D!W>=VJzV319bFhQ5{q&nYjqNHa`MaLlR+k? z7BCd&6~z~q=Ei5FGNhE|=2n8-fV8{_ye$^Am9@AskHN8!A+xvu?EcK+H1L8Y5FfUv zCmz0@$ImIgxB#?{DBi=LAvq^CF%OBKm!DZ&iNr5UL|HC`wic)u;@{-_qWIjz0+3S~ z0)iPzatmBRgdamrTD&Xjf}!$a$U-5|k}Ko|L{K(p-4GG;_sG-z;Q4t1^Y7iR90)Ct z^%$(6{e%H8-aiI4VL%f{jR!${4g+7@g^GlNMn1tKUfiC1pk0X8Z(aoMLtSbBoE=Joy`7_nNC2wlCK1 z1=Iik|53J|eFPm`0KQBSG?hI8G+6%P?!W*4cY?)0v)Nt_FV29rueyRZZ*+t9mzlgc z4caLSoo{X|0SyhV1StXSEdiY^|Nq4-5Er4th^b~ZTLy*~6(A#E`*(d_WP-Rb zcly1E`iJb!M$kmf3pbDvm%zT70G?nl1qnd+&n~lJV0ZyKaRIsv%dzH#7)TnTKA_+Q z2Z#qz>{a&S7h>kyvFODc5D%hqLKDbww?UKTpd1UC&UmHI!0_TYXxbg@rL^veAd$4r z32#6W>p=76;ElTc+g$}9Eo;!hMI4~bAmG-o6HCC06A_?&gz#;N`rJhdL3!vtK>xE7yh347| z45dODpjzui9B6UC5tf%-Dv&`j&}|$%-5wF0UM$_AJk5t9K((=lLT4Zkm>UD*f|l=h zJ1Kz1P&i(k`~x12hVng_UhIGibo=sjdI-Gc0`EQorA^Shq$>w2Xy!2hGV`dt1Kf6i zPDw_AhPNORLU0LCW~c&<|3D;uZindrjah+4#vtMkA>z=n@UC5;2+;k5NLx{?3=A)1 z{`~*H3v|B_B(cPR#6Yt;;F(WQtGEX=Df(jTHn1JwrdI-ZF4TBE=)4}#)?!xB*a|2v z8xJBzVBn)HprM$67gIw)V=IvM8@SI49m{$V12GsjT^MjO>Q+z>{KdAP|Nm!zTieiapw{=W zY^#m5CI&QN@S^MI|NpxLKsJDjSF}yef2@+_B5H!LI>Ke0xR0ODuFsETGmrXnEYH?+8;lK+*mXG}FzP#qnZ>1iX6(9(ig!!~h3_11imDfsEnFO2{gBv0of+(2LD5_JtrwlI8*pi@eZ*m zLLd_&Kql~KRb+q$Vqa9jG#&_ekq2X+fLyH7ct`{^J^kX@MzG6Zq4o@v^Myd`iol8f z1-QEk+P2@>bO4mIzJEiMntMP3&%PlqG@GywBz6gOavNwtW#hpkpi&!LRze~v9O7uC z1&2>SIu?LTL6p7EKw>>0tDsT!0whrV?f?HBpkY$T9G?-$!|5PJkk|^Sdl3oZLA8Kd zJ}*2#0?^oP0!5uUNC2XKLIlWAHPCtkP;G^|YP$4K7GoCciz8y-sF-2>p;iX8{&5$B z0JyK5);Yxkv>xKcW6;jk*N0&dQ3Q(H^PrpmK!;?zaMJ5IXW9bBNYf?3sb0S z(BJ}+usu}x3&;}CS`e@UE4-k>pyeY7)fFL7VbJJ91}J5Lb9Z+W$R7bOKCJ_X-cIl} zd!W{D*Bww)oCa-21@%n9xwab|MvVtSRs_DthiHLS_DqHh3@>Jb)c1gH!2q9ZF%jgV z#zP>xgI?G})kD)V2S|N3NIiyQQXwkQ9b@pBpcgwKYQUpHP)~s(A@IclR0&Xcf}$bdMLR?SmN(c885m$i4GYK* z%Rl}9|6&nn`zlBe$j9Jm)*UFZ62lJ-{yhc^3|YDv2SB^peTAU@xDW&puz?9203AOK zTG9tHCFlhU#0f|x$0<5L0 z068b{#g{eUfJ16QoB)}1_9M9304E}lLpmElD;YC1WBS4Oy#(q6y^w;;Ne8@GC<3wz zbi?%r&=lBy4;D~EeJQ9$2QQ$UxzmV&f#Lg4kYQaQTYF6!v!KWK{DLgBgif@W%YjVd z2zXKV5tIQz$M?9ykMH4vM(h3)y&`?xt{j~cpjoWjQD^2(&?&m#e`X$-ufo7EbLWCK zMuzV{1Hd<$ym%-8Hg!ffEL3}0oWSt}nn-%>1o0Hur2#Ko?Z9fmO2JNLX#y(+Sp_;D z2vlNpfC8jf1axvx=LC=$FZ)4$1r=MMBmi0m0_qolvlp1-%5l5_luW@KkTOtu1am+I z8z>EeIUr@AbO+{ulz}omm;+J<%IaVaNEs-DgE=5&pll81fRusU2I9QX{_y|*3pEg- z_yM#B##Ny8K#4i*>{;YtSCg<4qtjkQ0$= z1JEe(i^%tgh6!lz#0!u2Acy-3w4MYz9JI6x)UEvZ7}?>V$^Sr>pcl8{qTKLQSn3NY z{Yzc5JYLND0CoKlP$c>u>FfY4p>M7|0(ZRz)b$}^&|)8?AmGJAeVFS(p$!rPxqg=j zDAK{XZwn~L%m(et1uYQ@WNE!rstRiNsTe_Xz5<8=Dk4CPfENbo0-(<8Yu;{uU*+z%tN0 zKhz%}b3p!p)e1hKF_Ko04rnvL42Ir*ZsjX zf>g!5xcvs6`T`Qb_W|x?&;7ZT0jO`m z3%1(c{QnPYHalj#D2G^kya}`r2NYH>Qb9VPW`g^zA#eWwe~}L&vOok#{zbwYP(A>q zj#6maPHR0`ssqoTC7{#+%LkVqKvPFa2qYhXwm^Gk1-zK`7Me8nfC^&QJ)KP~W}u|8 z2c9%EK(0N)@-jpiwARB{0<`T~1k|kxcyV?uXflik8r2|;Am>AJ7k`T}=mZ&1xdhs> z0+IkHY|zLbm;)-8M9e@;aH(*-0d$%khznK*+Kd9`fRusut$;Zo(?Gjcz#LFE0c}zN zb3n>K!;D}KNEv9q3YY^@W&^VaqzrW09#{sX479f%%mFFOK~@IZnFW>sDcfQLVuCa7 z@x~1>4#>0;bBGM0+;U`jvE&tU@)dY7<<qW^c&~~05FFyz} zFuZ7g_5c5iCJ<2zA}T;c@hf;_DCZG zV6xeubpgH#fiDigg(5PR$TBdz=zk4O3Om3_VMk{ZDB_xHcfgZ^EXW&2SYCPxfX)_RG*1+=dV++^e54qD6l{w~yyC21KGK&#fFwKuyNxb_Zs z!N&t)fCiw`Ivp!O8D+au1!!msv>4;Xf-cbT0Qg!8a3c~nNL^6{5*O%n{n1?egQ0|@ z+x5pw4*>>-*9PGAa1cvSbR0Vc8t4{5(IE!X0j=p^sSK2`EUXwnlOqf-8ejbX5AH}o zN;ezOwxrk>|NpzMcA{`3F;U;KIw9`57^54j*GEsqS) zfxIuGV76}nS1lVlJ3u+Nxpo8G_7~3~Rf`D7c2IQ(QV{SW@B~;GT6TcMK(@c=0$JJ$ z-hvA*+CWJhR`J>0fktqt7a^4J+BTH=ubnxcOp1atHXa5%2$>;RQ>&9y7wj$ZH#9AGcc z@Pg}~?k13efEP1kz*RIf96@3rN560ay9N}5{H^yuJ6%CzxsZJF{T4L9_*+1CN@W}X zH4!E~hX&dbP)2rL(%A$mTAOQ^!0lIn+V2ChADjt6O&VM90t)crrWbMTpqv89L7+Vc zjR!#`a^MTIa*#M`4r1eFV0f(u%0Xbg;1xZMhd}CsUbG#@%sHo{r_js09XJ{ zH48c?f@+ZF+6C|ckbeq^0B?v>x;sD$0$=R-4t4~rfpZDe>{|lbFAI$lkSdT%kdkaE z-14+6P;tb+9n@Bhhl>XA?*}!^OFc4NKnr5NJ%u`L4%lgPIwykav*y}4aHoOx=Yn$h z25xX&+T8(C5cp#69wp?dzaAqJv>r&{P%oFS3#Pf?Gp=-rY(>E|K9~V3>wm0ivbN|EdVKkG<&>MUQBxY|No1%AYuiGSPU`~ zRH${tf%aIREP)+`20F|t>;^1u;2SN&f?hblL`x+yCV&P;K;1)wz!x6yU=xAG0k}?8 zc>MqWgx6BwAmd2u1|M*e)(JkpJGIoH5^EhB8PXU`erLzgtMrp2{0ylXY)Z{~)3=Ggj22uht?So6TL{wKc+ds3YzI_NfVf~~2Oq(dy@-DJ|No0HWOHGw!a=*FTLce)%mVf3L7Kr! zd7(GEwQzx?UT}l-vpoc@TLm4U1sRkAsck$oiy!2hRkN}9W|jy8!;1?KkbD#P;$RWD zy9W1Az>E73k&G*#g8-Z!LBqBOoXmPUCxY6O&9y!7umzb1%Cmpi85mwmfeS5=LqM?z zZUKYTgE^oUhC!$6mltsl{{MfG2_jNJL_COy0uiAgA^=2qKL8Dhfj9Mmij+H7pwV6u z3OdP>ryF!IkwDOkBQWt&3DA*yaPc)T@eBr9l;R%`fE4)=-t87f)bD zm4IYHrO9h6=vk5~0WXfB$bt@feJul7`U^671zeW>xa$|tS-!7jkSdl;xNF$DeN{Sr zzr0v}@BjZ7o9_Mpk93fkGfY*f7`W*OsR8C*f;rk4R4gDLT<8=L(CzyLH0J~f*iEM3 zC3BE&FKBQ1YaUqX2jaa@0$FMcA}m0J@jXzn0B&0&H%|7zE%XPa8Q7Vj$mN|`MuI#8 z!;7N((Dd8^O7X58olT%FQFCnvJUuhq0~c>Eby(r05=aRs31=CB8{18w)e8YHu0sYL z!6RrLpw$X(cVTTz(6EwOMh2+TV}x1Q0?t4!ofARbuIAbnxP|?9Ar|fi-Qmm&&Ojg~ zAPZpw7E++fN&GITw*l@bu*!f>xjH%>oXKITR6wde-a*RVoxX3HYu_-GXrgo^_CXdJ z2fR4?-v~4;((U^ut&{P^_B;RogG$ijO$JsV%NZD6Y`KHz;F*A0@{>WPgX&Nnn39Qi zpc~!61t(~PFYv`#YjEyL>vVm=zdiIt5O`1;NxpX$*xg_`NCE*3J_o)?{R46jXqiG< zXA?;1g))lipuxnz7x_3%hsf(=m<}4w4t&9mY&uBj#nIc4U9evuxeZFD z;IFX9)ub+C-3zK`*5Lfx-;b zRR%R$L1Lg3l(7I5LjP|=vs?qn>7fms6G3AQ&9x2i9MF3Uk^?{+j(c721Y{Y3RDy=# z4}(wO;YsUsy~4j8B*Xv0;TJfOfOhlnZx6i^^kV&QumDI6ICDUH2a@MtK9U8O*N=$Jpq zhUgdbCxdevSP(RU=mgqn^`a9ZiZsmv-s-&R24W!zXiL_Mg&+Z_6F_^nUQ7T9K%D@d zlCHl2Dsg^57U1p>cVc+)cN$~?ZsQTq6qxm!7e3P=%WgqCN)L!TG2DUPgK|dPiJ>Gl zw*a(;54if&+LKcV!y|ABVWzmU3y zNSEM%=L88r(Bi zAPO`O2b$5(108S+p3&cb4O)Ia0TuDSPhd0pPvGUJ?^RII#PU)>4mzX)nyDKmGy0&z zdB9n-8?sH}#f3gdI)+MsI!T~bN6?Gy5Q(fPaDma?0h)&le6bKo6x167O;rZG=!S^G z)(e0P0j(DZdT|IMu>-tb0JH?85xibt_GNIc?glT40Jr!+Q;`{K*%_dhxio?J0WXXp z+CkM9$TE;1WO5l?VnJHR{3l>F6X?w9ZU-HdDP)kAUK2;`Q^;Sy4K|K|7uJ_SF^)Qg zeEbWz9^?m2A^U-+kU`V8ua!ZL0Zk$!%~OLd5pjeo8jN$i@R=pM7qXz!x4kmb#% zL0s^ZSvTk?FOL_yF8=@Dj9AS)8^lGdX70I&xth7+BD^YxtY%IJ2|%l6@M`9;i{Mt_ zht>n723aC6o?n9IYw&dtp$|F(6`E@wz%w<-JW#*dTZ)0%bryLLd_0HW7~&Xv?E3 z2P=;TXul&!0OJ;N`rQ7eH6GfOC4|A<%N(pcl`&!2SYFHiK642E0gZhOFiVxdpVG7u1c! zv)}%hCa6&=@Z#TjaOQ=M{Udi&TaLi8B6J!c_#!k;?tshMJFsbhJMd_EcpjAVSYB?C zfR?qOA^(6EUK_x|&|xf)7^pCZ217v2i>UMe|7W4D7G{Td54>9p>TmFVu@~<;!TyFd z{LDb(^HS##sSCV}m=h!bOvDzQ!5Vak68S!(F0JNb7UIKg#BmmU{UIKg+Bmk{L z!ApR*fCQjgz$<|=MdLWk;oC9sB2c3`w8kK512wBUU z1@RNoN*wT7UgvZF|HD_dftCXYzWC4q_C2g<2BkLeX)-UaLnNTV;#l^A?Ho8>k2k>= z0<(Y|19csEA@Jj~|Nrj-F9Zg!WdJV(K7SUG9Kj2L_kjeUy1?7x*PaEpp+N`MHy#2V zFBbG-6^iAJ;4$YmkUp5#L9O%Bv*1z&Y0SA8NeQUe_#)^m+8SfU!>}ZXvBp>pt}%Xf2GW^_BzkOXj58oUf|eSfCBC3JQ0N+C@4cX@4jyc4j13_A z@T@WJ`wr5KYmM=Tc5wV+Ut@e3E(wZvv^B=t;F6#M0DX<|42Uc=c{GC87(Y3U$Ti?K z#+N|?(DV#mL3{`#0F8SeQ1aaf5`ac3cxG(D>Hq&<>;@6rPJ_yC-!H8vQD(;S4?trO zWoAqhCJLJw`*8+ZwA=s}EjM5@V>jSMOWSF18S*j`dTkeUW~|;3+sqiWXqlh^>PG%K z1x$ixuSc@c^sruV`TL(JfXE{2%V3rP$ymlv!UVrDNsf)0KK z%>{#83=Z?O&OnnFw~&Rw&bE7T3`5M~#U>0fs~7W-#g03Iu99bXG4lkdAcCv}09gg9 z?shPMQZBeo2d^4SJ%LDs-$1L^Lr(nvkG}B8;l%&{FQP$2*a=W&02(9%uY-8L2Nubo z6+p0g=!~@CrTTty9X7+4`5?Ko!k1@* zR+b?z&u%ylNqWIBCxR3NyjYnAE(KuO2DF3?R@8x3ufd7~@WQpX$Nv9+@d89VJ_d;; z(5fJiIUsL=Cz;`Ev@RY)G#kK++BSd$VA&f~tIY=qK(jY^QCr`!|NnO&7OR05wN)KM zUMVyIyr?bh7|KF7@S?V$W00%@-f;iAJ$OIV=-bVx4X8{^3Z9E9tXA$_~eFM1I z-330_8Qd%Z@3XJ~83Gz01NUsY!22vzKsG@OQt&Xwc_h*R}`flt)~O&I63!Isy7hG#&AfRZ6B^@5iYS|0&7<@h1C zv%Szh^8fz?Xj=EGdLaX{2)aGhG2;dAk^lc+Xn+W15FrO5BteA85l|R_vS}%f?6DCv&S!wnr@I@G02)fct^(Zuij)0Tg5!gyI#G>2Hhan-< z23l(YUNnPsrI}A1EQCM_4ZhOM_3;1yFB}fT{REow0tGW@mDtbi2#-LIqGbtqu^A=` zTSU}!1nNXkD(VhB09!d^#nhVf8N8pP}$Qn85EI&vLDbgJ4UUVJ;#SqSO z$hklpazg(gZKVkWZ^#J(X?uMhR$PHMVrYz0-dfenrmNx7rwoC z`Hc&D!Y_E$&WjwF)&l|Hqdj0Neq69<-3?j?0ZPcAC2ycGdC_+eQG|lmyXArept%&h zUnmA704+kn`-Qv@{{O!NG&l~LQ0i<1?-w!$DT3+(?-x=#2yNBD_Y0|jL_l`K_X`Of z1m%B_FlZGD_>M7X?g!2Lcw~T=*3}+@CW1Ynv7pdBu%&f~#j)H6A?frUCv@QrXc=AL ziQJ4g)VVNeYXp2jML&T-1Z%!jYI1WjNfuee-&0AhX}VyOp63D`97zz)c@ z(1j!C4?0mL-WloLn^$TZOL)U78=u&u@X|loAif5~)0x z1slM@u>rP33bEGj&whw=&vQV71GM-l@Ws?i$m@_mVjwGF1z8xVC0?{2Ud;sLy-3*) z%Ddn)IR(i@ws05uK~}BZIRN!Ce5oI35g77PzbvSWY#}ZRc=7T+=;Uf9b!5tM~> z=8gR|csw)Ug&)`ns55W3?t>-46KnVGg4r`5r`>^1Akzl506Qmuw)KD)p}?1XUD}H> zw*X${wr?*qpMjQ&fok9vdqAqt)`88~ix@TlFBWUx3)&yG7Zk(b4hm?U61a$G33{Qu z37Y2kTh!p|l)mkQ#_|$y^K?lkctH{J+QgQ<;IMre4mvRn)I0^Pq+tawI06k(gLvS< z&+L;7oh@A81xIjI;Ppl*st!JcsRG{-1}+r4!K;>7L5qX}UbL3OqM>^t$ZXL3L=$+C z(CR(lAb|)6y_n+%StJDNSAZ2>O6!~mR@ekm2onx`u^6HdvUZ3K=HCUN)Zx0I6MRcZ zGtyGTDSIIPO-HP?02vQTP%k|8{Qv*Lc@MZt0BiiSY=j1D3G#x&cN<`$paq9tz*~C2 z3l3ZNLIWJ@? z4Q;)E7w5Ge0IvcBCxx(}7XfhBfmQ*6tM9PD7gjJ)*eXEq>ZpJhPH-P)fomfE?clY0 zK`(Buhk4RAcU3Qa=#bPcfpII2??Nv{Iy-6 zDjQl2ffftCI06y@FWLgtL)~Dj(mE%ApbzBFQHV0bMI&fXv;pcs1bdFTKC6Oh&?EnWu;H8XHw1NH}KoC|!~ zE+|<#8Gzd6keL}(L6FlyyQ87k%^*%F1}{dM3NpPLG=KtH;Sl(ul^I+;f{bYbwKe#+ zcYs!8z*;1rA{DwmVl`MLXi^?Dzu^1hMbys!|6io;gryr$h_@anQH3nZ@Z|vC2f+pp z8{XrtKfsGJl))}={Q-3|tQQ3!9#lPe05KjU08#JA@*;3MIL<)}jJrKp(mK7^Uf4l| zjyrMu|NsC03wtE>1uqo0gG#_G2k@K>=#bZ-7v~BgJ_hXwcjbVb5c^^$L=e6^hv&uf zZQyKr+yOL%%<$p`nEN6=uK7rY^_v$vOOa-+q30Wc(r~~F`$$lG8Pu|XHG_4bBA_u@ zP+ALmq0In_E6}}Rg{9cfH)?*vaoqI>Xxk}Lk@zn7++j{3eM{R zFYXBa``>&-pwsma^!%f4*FViiIIQ2i5JGk)$TTn}=e#G_eN5H|>xsF)3H|)1<~KaY zUB7^ANA(u}epk>f9^E006`i4fj=O#VmqXeA|NqYtdBL(B?7>dgKh3p&;Dd|v{)2J~ z%gb%dpeEIyv~FLXv`&r}>YyW^LjQET3UoTLywC*keE)QZ{^@pN>2&0HApuGo${=$= zdlI?@yFqJDg;&GMw@7Gp5m*xRLiQ>sS8;&$k@Ii&sD0C0-1iWbF z1~~+@3Ko?0zXZNGvI?e-quce%OHoh>%hetF=eQFO$XgjLpyaN<4eBZIMk3guL?{1& z%wl=@5VURqqz*I-|0CeV!#Ns|i%xzVchmu00R6%rbd*%+kK;}TS)gs^4xn?K4s`qe zNb7V=d7%X2UFvrIk=8i@T#E^U1WtB`{z&WW0@q>;pp&FPtu(Nf#uQM^20HHvynq_4 zF(Bdv_`E03>2VN^pkWE{c~8*YZ9mdF8$sg}FE&F@Z30>M1vEklx~~Z|?(ie6(<|r2 z6p%F3ZFw)+Ks<=s0@PkqfR2yy<>(d!+1c&Im)7YK@gf-{7|PMj1ae$=fJRzpVA=~m zkf19^HwVZu-HtkGolRiN%|PM^6SUGg!Q&?{lhHjp^N9HX?(Ca~|{ zflh8hm}8LE*#QozYanr`Io$%Cfd((GfJ6``n51<&<-AxA5=3Y>OY8K=doc?n2-Ta` z9iW!h8JO~-6(k7N-tEZI>7?_b2_yu$W2Dqu2|dKmY$jDgfUf z;7w}Qu!Rgx;H1g|3a(DaiWkZty`evXUhKL9PEMV!UqI>TOTY`w6|khq+U@$~b!|7u zBn43W1bXll2l(KtAKlP{uQ-|y#dNzuxS)WC9(2X=;=pfE0sI5X_h5Rl9xeb{*x?}n zUaOydh@l&l`+jtWFbcr(c<7(bkj9E`*DuXSc&y*NC@X*!p-Ahkz&C_tp8(ArcDrza ziZoExFR^=(0kX#T4?ko_vvhMU4?~G)H|XL*zek|bkL9>4=x$qZljcw03(b4Tg5W#a zc!FLebAW>dd=6&$CU8E4tp0kH4|5Bshzjj~gR8uPl~5-^=P-%9NP-xGRzm&x1-9m; zJ81i%E3AY9l||sf2^=!8a;X4xmr^x|C<76VAafxl6l8gPz*1PmAs10q7to5RpG#oM zP>QHWY#^5)6;X=IVCuj{)KW(9>Ik$Vs%IlOXrMb6VMUZ0)K`U|Ss=!4NGmGvg+DvU z3Z56B^PpZF`uYF=i@iVp|IcCvHS3u8w|fW#zKDT4E*84|sR^`LE8vAQOrq2Xv?qXr zfBQs`M9>Q@xP)XDD`>!Edk07&@P!~uqC^NhI|C{`Is;f{y5&K zU<)dD85mwjf!rnf6O?q}r3+tLXCU~jH*op}=SP%Gb`7#RHQ>eFi=e=UWin7SImQvW#;saxw)aRWJtKC-}mGf#JpFTn&cs-n|mX|Nq}<#fRlO zLGZ$?w9eKEpeq5sf=+2Vnbz660yI7Q9CQbpDELmlLyVnZ#_?8{VF{W z>Zt+8q1X9=GAoz|&abUL$01!`PzBrB>H(VlnF~5}=>sDJ!%omavDp_HdRs(6*DM9R zF#ZH;igEC72kj@{A1ZP15mPtBgbvW58rr7cOp0Xl^w@P*o0P_%G> z#xVG|yNU$72>lKUXO6VaRtu0LdO=R%-#!tf8g$4yNHE}q15DQm&<=J9&~>pA2OltX zgH?A=1Y3I{=tXBOs4v3y7XbEi_f(J@yPH6^2E4eM2ht3_<>Q6t8Mx%hfmUtynjHWC|FuwB z_f!xAa>o~#$-lo9B+~ptpf)7SW+&*{YKZYmUVu^^SYPHv(27OoLjf=Rz+udhWwQgU z@B~Be6y7;EK?=d9WS#&kycqOC6{7HUUq%5l1H&%RE#ldS7rr2Dz^iO$>ZtCBl5jy0-c+|Np^J07M}t2I|Q;AvN#|~v>UvcAn3)b%OD9J$mrNbhRznz9pC@| zfARP;>|8Ez_5im}_J98W|HUoHZA{I(KwF0ypj+}?IhuFu0TsCXt!qImx3_{+ZUCLm z#0(0*i6CbOy~v*r^-hUo2E#8<6CTvG6AXHx29qe20PRxa=!O>gd@%76Q^;{VkkSTp z+QH^;;9L^$!U~+~Ssudzw1pPu3bUo8+(3Nc6O(1tdWxE5|(mE%CReT2Bne?(1 zvQGr+_!0|2DlK1*;N1dX*$M}rq0pFqP? zX`NFYKt-$;=&&hQ5a9qKtU;$efwp>gb94s^1ikn@7Z&Cz(EV-DFn|D;lUBujquq@xV#W(+X+KjXD`?x3qStys*u(>Rp9sk|1Szahe^RxPKhWurGUbnf4`GUXR89J$ly8-ra?&yysZc% z4Ql;?25&)Z{{0?qoxL(pr63xtG?b%x7f2eU6f`&qV)O40bn2W6svuu;9d8BEAf@2F z1KHq`1XLG7s_||?C>_WGs?EW5Spfg`UXYVO*QS8%0o5xYLqOsn{|9EtgYH?0I1ajb zL%z4QT+=*2AfSO|!G z%JKjI19pOr+=lQAzHtFY zU-%AEkKjK5@q2qg5g3Rb%e_-Ujf)_(!Wo$lD%By!`a^`}>pucEAG9hOqMzkA$UJa$ z0oD(yE`oM|+b&=}sOc5r$R z%Hn^q_Xs$9!@@hQvqe+}loe9nftFNsgOvxoD4zw(v)mA&m$GaO46tE}GEmy&-|kTo z_(Be19JuyRg0N?_9;nNIVG6pNDFHMk2`;_6K{ua&oC!6xlm}9EHCMPWlsZF-#^a9Q z$_`Wvg~|lIFuehGX8^1KU#SMblBx%!tH`F3^oi?A?$&_QD6|NdA^bkV7j#g)yiD5cI+TA$JT? zZg+Pa05K*mQ3ajAm)6;IfS-Zkg#_rBC~%x!1YHl;-6H_Hb)fm68+drR39O|9q=kR` zM34qhcs3sZp99l)5TrB^bSn$E6JK3c(ctQaRr622@~zV+qn21l=a%Jp&p`CDO1ERRG=1 z3k{z+H$k0So);mYBctGT1T1tp0$*6e^p~nZsu}+6PGQj2AOH5in4lLwr$KGtZ#f4F zJ#Z_JAGXyP>=OR%P7$EJgy6)(za3m-2E9$<6 zH$7B4=)NGRB_0uhSw=8-fvdlO7bn33864mZhP@zDplzAPL!iltpckALpoAg=$xB%b zkQ@>4B4|3)8zrzz@&mMI()#uP|1Zp5|Nox>4p^`gK#B6jCz!WUlD|#rQ(z59l%%8Hkh9I-Q(er$X0FLYpYnQ(?}4D&pVoRM2{$gwOaSOp}+> zYXi77;D7)hhYqh%vlw4&{SC1O?A)|YN2eFTpaZ19#q=Qt{_Q=ipppt2FhMV#Re*wo zBTE2Qd+~3d!V4-$f?h-)07nvN1QT2r?*!Mx;Hm*s69>HTiUY+M53C5<0UG0mmqT}7 zg6^gP*XN*m4xCd#cjJI-nciMd0hCxlZ1)f+22f)RRBBs;#6hh!CI$v$ zklsuG|AVT0Wstv4|Njqa4v2vKbsBQ_3Li)fl>I;0i2>Az0h#$Z*ogs@3qb5w!A=aI z`~hO$4R&GxWgt+a?P9PK1E>iH5aTUjn-xB|fbpz7T#{N_<)c1L*#cw4B8B_>>axwI}hQt4IRd8pw_chN9HO90bp`B)=ryCkUh^xwNRrEhn)gFSWQB#4k$CaRt$3`I*U?dFdeU zr&TZ%WR@gnK-oFP1@XC=DIi54W?pJJi0KF+LCn;G;s8jXKv@i_d8tKk+v7pE!=Q+O z2!V3>H4PA^+TuYmrmCo;3-8=zn!7EmV=>`KSMx( zf#Jm-$PC=;u&ja?3A4dt#h|f&M$j<36-X6$Z^$&LDuZ6vHvzq%iA&J^8bL4e)`9l8 z34m(QH{bzM@JMmMi)p*S;>HIc#n^!`Cx#cF!a>DY^AQQ_H!s{GAO%<21W;Z%5$443 zH#gi6JdBrzAc(KQ%2aJ{5@r-zFd0{U(bWdN~OXs680;LUTLV za_cuQ?uTQ{$b!aKr^qodyeN(UkFVxD{QrOFQg&?PtDvGPt+RCj=zyWCpb00?%urgl z6BFoCUy$GdBtf>c&ej`9*{W5#Q`shXMti#g@3!RNMP?& zkp7?-{<}eyDQMKU;~{tu5TrHWg+(Mt7`!xsfBRIBRL~0-h*Q%#TS0vO?O+Px0+?wN z!DFyINOA&!FZOH$dl9Oy7h)RddS;LZdV7C-0N))9an6B-ASVj&ZwIG=fZpB}55ck^ zML{n<`GZ`=!@s{3-2^08oH{0sy2Q6fmFw0f~bG zBQK9-MvdoM^T@P#qlV<0~N z_NgEWl$1n3Z8DIqz})nMT7wd7FN$`8gh75O0r>^H883X`stO>gK&}D>8Yr3rUifxG zGX;OkKX79Y?p~05&yF7U;@E#SZb^~d?Qw}Oldcwq%I4xIf!>VsaSLDZ#nwu1Ql+rbpVnCTr* zSC_cM5-?27i)x5g&~PFwTzkRc8SvslHrQ2Z-C$3qb@qZB^}-7@J@!%(w3iDW$&l3l z;(t5T9{!e}kkA3?03|Vyvw~jm!|Vc0DD;A&A@D`^Pw-3&)Qg}{fhF`80TBB!oP1(4 zG*rML05T@%g$m3Vu+d;^Uj#tZLGv0S*+E?!2y<R0;HxzK*+6Rp1t67DN~{yZi`YO=r4$coTR#W{ zwXH$5gY}yiivuB56u&&^as-B)SSJQhUI4X0&&N73fbu7ZeK6LE0puRgR zt=a%qin=au&L*%VDEom{1^?)FvI%%`+#8&X0p?`w9!Ik8XZo!}zhZchhPabgp95m4y`lHu{ivu=te4Isq zqiPldHray@8IH4XbXCn_0AI5NUXSskH-wP`JlA~j!EqL*GgY$~c7i(o*`N`!AH6;T z9MHim=Ho1k_h7OIA2M`fSo;KK?ZF2O-M$Ee4?bWx&cdWt4K*1}@5P75SvWkZp>8_( zh@smR-P)k)Sqz}LLfOti!hJY7;*FmCd|B1jCA7enV#KONn^b6SC7d80z`+i94 zWbt~T_64-rZ~1G;(RM#NnT!v_L0X1NP~5BGX=bO*$+_#YAzlJ<$v&? zB}d?k3s8wr4v4Vzn-{je$e9(=|7d<=65d;TW+yM=xSWL!x92bzAMJGg16r8w`T(42 z(mH)FfI=x$fPXtnsLTDC3;{3Jt_O!tTBqxo7mA=cI~mZ#891QtfCKstG@$SB?{~e! zzu)(a^+EpLSD?ybe<)~m&z*}8(z<&tfI>U1)Az=UJD>jl?+tws^y0BUXb^@4a`qU@ z3l(ngx>e9oV_?%CfK7h@HT?nqe%A;5+kG!sAFQqB-yV7cG&lc%f4}b)=7Zg#BK+Gy zSHm|pLTjrMY5x7b5BT?oUSU4f?JAPi9eN|JQ^ey%0%#%)ba3v$2cR{Wpd=4+bvI8_ zApibQkR4Z;FLe8g@b4E14C-}#5zr0F?zh1COyFhie~8OLS?~obSdio8uYaJ{^4Wl1 z(S&3th8J<(NX7p{Z_xTY6YDoGmU}}I3BNq(G!=#nkkbGE|AR7ENwO0|Vllk?0qTD> zz5yMa8Q#114(M`8Pi(OU&Z(eDf6&Us&X3T|plO}G0U&{jkC6Gl&^Iq~KmPv@F2F!1 z2EK>~sbpnfU`Xrqeexm@G`$uo0_lOc{&?XC;`@rEbql6-hJJZr1e&e`Cl7Fz^8Jto zIX3G9=ynwT{jM*pFYx#N;bmY*>-H5$>+DqkS^XDuXGr*gG=AY$5fGmj>XfM-Al`kD z>~_}=Y27@op!Aj2*((4NKmGyY;Hf+y-p&u86H58Fw}RvXUTCd_Cc##Y|DYwtX`Q_+ zAZ3%lhJ}7e>t+dMsG7x)*4fGc60d@4_k98ypZ&8MtQ*uEd658N&j`q3;osg1QXKdq zXFpgz;6*Z|j!5fl{qhfV5GQC-=KufyK`*)>2b!jJw!ZoI|NjeVkXsL=b+*0$@p!?G z@cjU(j}9@Ub@!Zrr1jnpAo;hTt4Ov_1^EQjyamzFmOVHM4?bXK2Gy3|oIyno4=CmL z{`m)82?1h2(*INtlYe_FnA+b93I|X&TMn)jz>=Uc4J-{>uj0$oEi$olN^1ltII6)e zfXnrOMFU?<*$MJD%gmsF?x~>luR-152n%>|+77h3MW7SR?F7s5ZwEW-;zR!JV9P*D zaa?)2eL7e=d#1*KED-}+0+(z7iw3;VM_AGevLvv3DkxP1y-34m3D}MN`@u<~SHuzO zUt|v@fb3fJ4m1P}Rt%EsX$6S}zBml-#bWW$FI!w5;@=OBm|hkys1HGdv!OiQE=??* zExjoq%WT1xfxQosoB|dNdJ%@OtQF+3fbL$9#{ysUVp{gn@E^#*p#ni!S}*Rd00ldE z{csjT#(imLh8M3)LGI%T3g|`+Bc*y!aR$15M>4G&oG8;eTfr%R253(0ytrM(@fBRIBL{K-X zkGvtyLro75mHgXVL76__1v}gz5Wg2<0b06pwg$Tm)QJJ*jKCL8??FMq1J0RY;LavX zXRFMAP*{Q86OhIKV%>6(8t}3w{_Rsih6lZv1rs|EkR|Y<2f~B;p}QAkK;VmQpFsMc z=4DC3yp|>ZA_k&z;~lSA{I(;UKF6U&ww1`Id)& z|AkI)_`p(F7XJ&TWgsb7;_L0z`2YVuC>+3vDog&wqorVZP!|jq*%VBmp-E&ukZ zAT2>z@-MbSl)@qv668=Pc2DUAm1{vSE?okf2hp4*4<6)#CGHoh5EH-woC#q=O>5o@ zidTl(9MCN%Q2#N)_1Qwyg7jrEzIeX@Y()Sp($7PxqJS62HbNv`+yy5m@KDl=jZ46S z&_Xh;(BEUAOCij&;`b|2RTfiLDm6sL8zf)u`R z02%l4{$EfQoC?aMpehR_6Y!!GZUob7IZ((!lKBf>unC|@2c?gfE)cz-s`cO_CXjZJ zaKMXe6)+dDzT619trHXupb9kb#cH_85g>D?f<%M5L2EWQegjvEAW`2Bf!(1ZK`-V( zg!s3+J^>XZV0#`ifqV+GC+LM9G}yrU3n7YM+k#B!1(^#mBoZRdza6|xS%iOkAXCr_ zm&M=!2W{5tbhLP3`r`lp2`?R385l^+Hj_b3Usz4;K=$jY!o;MixnUqH2L#y5Aj_P^x`R46DVJTOoF6_MyTPT zZy@1U_!S&}FI~a=T}0Bl1DVn~r-GJoya)r`*#c@AbAT3Sfhsx|sAh0O4Wi!=qMv`e z?+;MG@o#rx3V0y{wip!QKA`rn?*h3QeK>Euf|OFH)XC zV#@bL;0q0?`u!mFt{(zk94~_^F4g1T4zV7T#-@T=-$5@{E`S<;AmD{B!r0fK`Wn=^ z5Nv+MnASP<$3I9ruNA~dYkmPLia|{N?Y&@X|5S(n|NmQ`ssUBwAd&17Y~7(E-A*jc zr~apPhH$XF=zj`ICVRkroL-P>&}OHqr=X?mB5B>Npr}skbYgmu{`CKU*it-jLpT1aey3WA%Up`Z&Kdwniwz!GscOJG`O>jO~ay?z3UJaC~En8otK<}WyK z(mGo~y_*+j!Lp$rps|kJS%fs8*MROx0jDNV5P+*L5Cd9uftZN!0woOVQ=krFE2#7W zl@MSB`=^5JVm`&c-Nko7z>COYXzZ0JA@o92q;-RJLh_R#$ZG!Wy&!LZDl&*!V0SZL z;NR{Ox&V|df?jZfSE}>8O#J`<|I6e5{{MgZjDdmSU~G99$WiIIQ1>x+OF3!w@@Mf>*94?!;);HrzeT}Al!b2PtX zOzQ-v9#BAmQ&<`zvGH#QCpFM8i1k5Gssby>KE&4TE7Bdv(tPrNTBi>a%L_};)hDm_ zcZ0fypxt6lOfS?PgI4Z?deUFgIt5>dgH*hH@evfW$R7MZ7wkb;Aqu+RWCCPxw4um} z;e~?@Qt$Y%4QOx_)YG+o^P*zX`QX0La;mZ4ga<#klNM*C6b_P@W56DzOY17#u4;FOpFl^;<9Dy&~@?i!Cfy%znAE41N*B_8l&-DlYe$Z~FH~jmVnh!8q zpQzQ&VgU*9Zx`|HDVxO*^ui1_tO-_^*6HG9@`C9vsIu7cI-}e51#5#4Xz?lNgkDgA z?+Z3R^ao_LA@m3Te$aN}H~jkrn-4KsAF4G4neY0eyBDN^e?O>i&Jqf;Dd5E!NRt?3 zeK*J}Ae&}@rgLAf%VNm*|Nnn|2G{k)4Bf4u%o^~5S0CI93<`LWtOsHV1O>eC)CI9P z0$xm*1BxF|#SO~k&ZLOG7^{=7fuI+5P{;YcN$YeJcp?7_ z6pj3#0~p?3KofMg@0;d>B7rYLAyfNsL%<`MK`+k1f)#GaA5eMV`i6g7 z2e{-p$=`Aibczk=Bz|nEB^J^x33#FM3o{}OW`LsxGOhKw98#!)hls%A`QW*mH{IZ# zTBnZyOY>e(Ckeh+{u6kHmE~oY00Tn?F8l97n)?ASmVi}rpiHZ6fP_9MAt77nBft{) z;s|8k9jC!9FoV6Z7#t2U7~(N0n8!f9J+M9CsiQaD;Njj*7cQ3Oy&x&L$0Wffvb>zg z5A_&iDeFhb3?5{V;ROrK{?k980gH6`$n|O9fCY^LK!<4=x_#ethcL1Py?DI?)K2E; zc71c)K>}1EzT60EqcL5&%0y{B(X7eLv=0gX6fYuy=dTF?-q2`}V{Jo%xpC8hj19kgfq?ba| zBB*l;txUSXV^5t^8ZU4$Ff{K4$-rYQ9Xw~t^71|}XtWDF&L03RwYyuoKpFyG6mJKI zJ5>01OBd+gYEbyUu>1zV)j?sVyrY2FJGhI?Qcbe>j@mjTZdB}=U@ zDA@N4f&W+#WlqJ==H~7+%kN3F`2G z#|Xgnx9<<=49ySz{h>dae=+m-f>zUJ3B0&o4D}1BTLiKSl$yaKJe?tp8qIq_!f-oo zeFbF*mX|?1kUbNw;OSQ1FHpn3faXV=f3ej1fU1c792Xx3z9@&84;nlKSq_?#1=$fY zQKP#TB-qK*)VvqOfLl`xwdOT91H6tcz{&e%F{l#>%5Yf|u}`+^$*R5g?YALZH(eA?;aEk^#jCWH*k;#Gn^TH-o&x@vk z+~-upzy1U`Mpa<;g8C$2&w&`76ImERr3Z)&w@?#m;X=@MCf7G*Eg&jjG&&x4yYjL)P2zDFbV-L zj;6rM?{cIL#{WLJO}(x=0y4ft&0u&Tr2#P#G~@~ChulC`))J7x5j}(9#bB6*7eP?1}0_(2F4e*ph?-6lAt}5kdq*~ofHCIm}7NKA+j|)0y1Pk z*7QKEL2|Sgva*(d3=5F5REV;j?4XPWYS%+tv+o1A^#^m!`VXLzw;Ocm0~2Jq0?0Kh zld*-(<6hLT2?1I2PYvv8B-iXgR@M@bQ2Ll4zXd61o;@(NM2&jgJ^?T2)Dec$l! zp9tzDYaa>#WsdzFAWm;c?+$QYfphl+y-0=F$4^LS3#!hJpcmQ@ozNac2PhE-zIfIR z_BuFSH-Us+l)MA2s{<7e5GB2k!BbGSdGVtfw5*N?;t^1~Z@pCN0dnwmh+0@1{zX5; zSWp8LqpXwT>&P`j^p z3Zn;Tm~+4DkK-&&pf2r;V{iZe&*0w1zyNNJg!Hxqy>JFk33CLzI0a5K;Kj5r@)LnC_QRB42zqfCk_>i&+yQCu_V#c=+!6YtlV#!yr?;T9 zeWAv>{^<5;Z3%p_7qW~w;Drm!*b6}~G9bpz2zVg}Y1o1dz4)*@^bMMs@7}=u1v4=l zX5uHXgCG~~xjlmV>p%e10lq)FLFwp)4NN)2{g7Y~hbcc1_~JDr&LH7?iW$=lS#SRT z-vRP9cv0J%-WIMO;L!K|ah#ATlZyDvWI_I=Ykg%KhNj(Bie^XzLRt9^fTPXQ0&2EA~F zS$ziVJ&3mz9)hd`&&9o1G6lruK=n4nbcof(pgG!?X`nG8(8|OYT@ytF7#KPxFoS9V zx7VPdR&Xu`rR&Cnpp}w=y`ejTUhGx`7a+KrOQ3ACADnHhFY@;mF)}b52hR&IFfc?N zZw1X6FfcGI1GnyRG=uhoGpzLq{$71(Jb+^w+<@_E-4Xa==LE3VI$J@_(F_I#2Hozd zAZE}D{#aN|AOjMQ>IN$bc+rlmK{ii9pP8cwzAJ|9{9a z6VS1y^^iphX`QVGpx)6*?7bfT{kw~pA{M)C3n4o3;KLTC^KuQa683$?uw0KE@ z9J3QNH~M-f=J^(Zl4Lbiz1vVc5Y7Wila$?x=|Nnnbp}^Gb#Lxm| zf9-N&08P1p#GiIKF(^Ry`P}PrVgN120d;h*bU87kCB-MFrTe6%LRkzs#qo(%nYpDU z8S$xQsd*rNYEEidVo7E`m;;prt;z$hcSbvJ@x}G$XbU`9U-E%Y90aY$xXt6O5c)JJ(ctC2(G|-R%Xy;Bh6F+RQsZ<L@IQfm%gvkFoU&TcLpGTl5A z0$&(GoQ5HJoMi&2D1E&J>{YOts3Xsy<+|qJumgD&occnVG`d;30$$up0ecri@;FNu z)XW2EovvUrQG3JS0O#N5SY&;n7Q^fku-Q%6%`SnNy#`{&{?I?&E)z=vUId}3Kkm|0 z0&)c0aos*mGJ!9&p~^s$7oadY?$RLxRt6L34(ZScdcgu!20CN~bT8>~mx&r6WiK;9 zr!*4bD`S|wKf1d>J-}{}#-JDLk|E&*HT6e#BS;Ds1K>m21-rq$xquf{$d>kwW zvLEc}Zg96N=tVqK3COtPji7!MSP94{0WX}OlD-_rL93S-Ag7G3QGn!Rr1jAl=a)iH zCVf%x1k{2CA3xI>`sYO=oC`W2!1YhSi~4YA-N4^671S{S9lZ-2r|!tL?@|KQ>xtuyq+3ya79{~vRG&hSG2F{oMK zssh@lCIOy|2D?$C1k`>O03Y%M)^+hwx2s4uk3b-pmwkvCG~+A67z8exKusNyZV|?y z7Z1QE`wDD5(?7s=ObC3TDG6?oygmfF^aM7; z#@_-uVHY$r+zsx6q;-b=c#;1I?0$)W-d>BB|Nol|F3doH8O`v`Xc(EF`ybW?x z^9x3T?wSZO@%4WG?V&25Doz0sZt!CSPW%L)$P)lMkf?X+jX(eY2lcil{QLhupxaj@ zusc)$lx_lEcyfS(R|ik=#oxOZ-0cDl8VdBbco~Q=FhB=1Il5cAc7Wz5vlw4|XahHC zkYpBsWL{_-1Bvs1_K>`=fwtrKhyLjH73gf4s2~FBb%g%tb`{{?-V*>a8X9gKApQw1 z1_osQ1`z*6S{=wl@Rqd~Tu?T64pAVj6XLuVpCA1H|Ki>QP={U%)L6h#>F4nU}zh z4B-H6fB4en`@F-4$>T-KebA~Lp5`hY2L2Y%QRZ2K8UH~ip>=nFqXvAwKEx5AWC(Hu zXkWsMH?UPrlj}k1SayM}JH^l)%F`{xzrXZHw-1*{ugFJGfON2MWeGq`HHDiR`XT#J zLT?W%=x_y)^SW6k2E3RCGu0MiDyWjpzR1??%flR~12yW!#e4t%zc_Oblp>@+P1%p2 zz6tog047kzc@y~JzCX0=<8Se01Z@NWwGy#UR&((0cVYr{B0wuXz*z@R!uid>zyR?m zr~}T^EeLX7=1Fk4`Y;KAh7*swOa$$xW_V$Jk6;`ecWDC8)V$!o_y0d6QGvEK@pN;5 zf;sa5*jyJuaH2Zy(qRFr)LuNk`~N=yHym>j^k8_g>Mp3(;%TnXVJLCHFumJHP^4Gn zASiJkV_{-=QF9lR-h6+6Lfe&xIRG5m$5^-+UL@TGh4f2MNbiNL7*_xlQZk^hmH@4? zQvofFol^x$1{{zf4^W}R5%gk5D5yY^0G)*jYw3ZOHib%{74W^Spi(yAMTan?X!R91 z)+h+tg!1Cq9W>8^3u?}^P9CNgr_klVb8w)gLQF5#-2tcSV@_O*FBaVa-PHrCH(pG? z^Z);gO?N;iKkfGg%|^Tcttg%cs6c`k$o|tw?!0^Yka?Si*y9N znC1u5#@p@6bIgH@;RQ3uS?tzzGBGB~+ zy-S|||Nmm^?f?HLycPo2r)iy2!D0(RVz~O@{QFx$imWfx7T`(!Z>$g2dV_K)B+o*M zqtGv)JevU?`tWT8M}I&T!;3?=K`jvuSP1lpZg>t#TA^P+gF~tyx4fSFvJ|}d5geRg zhX?jf1t|;aZ3UGF0WWMHGBGqC5$I@L4br@=7euw5EaB}Aor=!`rN8YWe+b@f24 zAnP|Ty2T*PBz}1Y&|q`R3?~Lq5#GSazz{yui2+m>fY{D6oftsD0b-lXbYcKSH;An` z6LM}0h|M|Ei2;`4l96V}=t$N@iMGX>n?NNq&4ueo10Zd=aR(2ihWA zoLZ1rlvt9Q;+&C~mzSCooSB}Nn8Q$9T2z!@nwOH9m+qXOky@0Rmz)Y#UQm>pn1Uh% zIx{4_G6-fMwD%aF8xL7|2GRxZUZRLX)^qJRV8+Ps!dMK_9&|YQ@BhvXzF69WprqCM z;Pk)$FU)U3Coy~9e1I$>oeE+=`io#D|Nd5xNb?WwTDJ_)c|834!D=%v9$;nw9kP4l z7-$i#+$>N@z=2i8gt;IUe`bPJyq*KvGv%uh_#zr|$QNjNCusORlq0PhG)H{r!~g#; z=HCF_iNU`eq|O+wE&#M4OCn3YcWT53(1xl^0g#bASrS=ty{!{IfNTka3Ni9;_tgn} zvAq2&Gfa(D48k-9$tH5?;hG}|QU>zLJewn}+r=p(t+NH9h97JzXd93OEYv^@Xh49N z{QFx$6ewHl7qmXa-`fdV{RtX4%Ra%tzaQ)b&=7zRhYU<9&&1;_pa5ogao`HHS91S77qUH#AxX4VSK{Kz!3Oi z7fjbwkTsygK_O*x<_WMxQ+Od3wSt_MeL}2v3fBo{28N&)PTU~dKxc@6^np%4gcadn zeJ!F8ePB;!Uli+Y0bj2W@PZ4X?p6}{l)j29Wwx?4m+Nhhtd^#d$~Kn!RI zftdXJr-CSOqC5D2fq#DwD@X@u>R_n^1H-QW^`O1OQ_q0PA_%+n#L0jE)4F{P(mH$h zoc#Cy#q3M}|G$_9A|_t?{~t7z!qM#{0zUbk3AB3yR2zU+=7Z?K-l?F>9n{+z1FCF# zdqG7A==h*+Cy{^`7dt^imtaVPFAmkAze?;4}*wXLscQ6_h5Rf-(kFP;y-W7v7*G zfL2hNfeK2nnrG+#|DOPs&4%O?kSJ(dB`lwSGAA@Gftb*80cZWix*Ho3v~Lz3zhR=UxR8JY*kjThzDqQ9w<=omqYyf!4~pw z=W!xfLPA3Y)LVg;@!1y*AeAblwghJZ{_QM*pj}&Fr(vmdLE2xKf^RPqfg6(m+BH8# z5K=dTQ(h-a*UNXH&hi!LumpUhv9$wK5rAqvkoQ1g2DTTo>VW40{@zfKmP=`!;0gky z1?+3gU?c#;KWp9sv7e{l`Q zyMTxVq*f3#&_M%0&~gY~Zh%qlZ# zkS#A-p~k$3DFVAQ08#hzZ-@E~A=KS70W^jg_@eJ7NVNz|#+ReBWgOKfa4VuO3-)(F`*d~Df@uNCHS|uf@}@g33e5@Qvh-`1|O;$CDa36 z%!me62?C(4W1!>Tkh}(RINEI^%o{_Pm1f!#s0X^;TEv=VIEF3?~ANddePRP7=M@WF?m zdpbZq3IZ?u03RI00bh0lu985h6g{9IzRGF^ou7@GP#|H1!&gvaK;;a2{DFKH@InG& z;!AzdkdQA2|F(&cMMx#iDCy$j!`>;pU{}Am)&+`j4oqo~6M|lBhe*FH1}&gK_Bp}` zu*X4DF))9_dP3bITtPd)$q;2ZO{uYh*_|c1VEVrlu^Ki zEVRl4i9tgRz4^4g7nD&TY3<^p-WE|%fCPY7*nk!oarCx87cGI!!&MXoy;#x=jYXu4 z2M!%@2x9mMTApD`6(C;)z6gPs2W~#0B>3zT%&=$!o0@%sxjPi*OjxhKn?(RQuY&?T z;Kf7mWFdOCX724_1-TKD8NqXF1fme+z@QhCA*PWY?2zn(6ztiDKyCnqI~F(K2`G@S z0$*r1K?5GCP=JIH$XAdIi4sQ8JcBJNAwIj=2sRO%eNa*;sK;1rE0SYLek z1JcBUrOf0={Qn=4z99F7fSeWh;s{JVlCvSX9%McwAmAk+1iWMf`G{cD1~h=e6kExN!&lHej=N<1R}VH38nsAi z5S;Zv?hJTwsufxmqDzA;4S2B{i!>w!gS0~;4xWoZ-o#rF`Yr|sHCi%b?rjkT+XgO& zvM(}sgDXgoX*iMrB;x)r0-HvKh|9hRas$Xmkg^cP4S0eXlqUmTOs@k6Gg@W<<#Ld( zu!IqwqyX`mE5t-_#Pv>n5dZ%_s4oucMg?Rs^!9@DRPR(!83LN)Za!cV@Zym>xciaC zz`wm0)HMs-1sWj*NA!ePP!k&I~BwP`4Q9^ z3&>*0V#s3S-`)#yQD7EmWD7LT0dG}p zIGA2+`VLAoJg?_K`XG=F_KQCdCxX`!BtY5wr-IxDn&Rtp39NhZ@&ITR2Ha+lT=NS? z{{7&<;$MFdWPcZEu@C4#V*dT$!6SG_0u*vVFU%lz^KWkj1v{u)|0Nb2Gzc$%783S1wY2UjtRM%abx!dG(J#*K|Nno& z>#dNfRd6ftB!BC7a03=4z`#xdEk%N~AWkwc`!xLtMC2Gy!VY-B{|y{PkO%?~mj%9v zh6dF33qddT$6yJxL!fz5*Ztt6g%n7j{VIXIQxC)-Wf4%6^6v{Q;@^Gz z;GH*tFZjTDMFy76pwlnCy`Z2DgwD_Owt~zI=~OIr#T;fW{1SSis}hAi3@qaC`0S{>P=<%3K*kqJ(O^43DIXjUkP-$|G{M}-GBKdL z7i4nai<50gy}vP7k2*2~g5^VbXwW=-}VZ698L91xhpsMMwkL;N_3Sr$E+=Kny$u zDsjMSOF6oI_+;kC2SB~)Oq;kE(cvx|>#%~XIrwikQ>AH-u9 zAHv2putnP8-QXO_zpVp2>v)pCMIE%`A3WCv9>xI84?+`8FKEPTdoL*RK!a%DsE6hU z{{6jpbHJNca9{+WO*}$l89Xe9l)6DPmry%Fjkp)@j)QcIfRhNQ_1zA(adwX0#Q=;%xhOMNBS_|!Vf&9V0y(JW+4V0BZ{O&2epb6KY7sU{(p}D!U1uXoc zcNeHU4T8E68Wo^gtc4fiGH{vFJq27?bc%GqRT%V6;e~`K*s-A6p2z8h-LC)tUuc5N ze3|?E|Noa-&p|8c(>lRZN}wVNtQcC`f}96+4rn@dKX^IPY|!1a3=RMPr*-zO0ks}( z?}XLZPoRUptsn-}3=orle=mpv)!4TD`=^4~P-lW_fslzBFiS+5__woofrfcOCI`OQ zuoE^d0OG%13LYv1F@s)|hJhjqbgUML4=!av=7PKcwhUUzg2bR!HveL-t>NDfb{uq= z6kKRDA!RIZvghAE6=Y`6i$sVW(BWvPQQ$(!m809I18IT}ymt6e64*&l-*&e2o&Ysy z&g=k9&ZR*HrNHK9$-iKSn4H$xy5b~g(hNMInSCOG8FbtgI4*iwCW2B3$hPc@3Cy7q z(3I2*I(v8fRFJly-d2ze0WVf|f?MG)?LaG^LBqJ9hy#TL*d%Cm4ibZ!0cw#!CNEz} zGcbU|4%Pqw4>~}@4kQL`c_R&C#4>@_twGdvf=AN9Hi1Ugp*De-&;eO~*t7|MFX+?; zsA<`U#Cm&JJ65`trfWiv5 zW}V&^0npqcR5P?E4pxsgrwH)@;C){PX(z6dcgx;FUtWBXr103QJ1sur~#FEoZCQ2SR6Ds z4Vj4rhY&AB6}Wj0)!i-9)H$VBlctIw0PJIEAZ{3P$1gCXR;RR_*>zsN6Bp10AvXHLz3W(i}SqSSzboaD^oEG@P9vs>NpmQ%?99DxZq4R+C zE+NV~dqHNsIJ^ZEB9In#cS|V9ytK|%kZmt!Z2A8`ts9o7z`khR0tyf3|Ns9VZ@qB( zAL!oX`WFpbpr!Q@kVlh1N=VGTp!50pxA%gq0M%O{&jr1(gt?r*I#q(?r#P;931XxovlkiLT5IEDlGN1Zm=b3pbOFe{eQ6ytPrLb ztZ*?%A!wD~>3{$ExA(Y$0t8gqgA4{$k|2J-i{1cGdIpvAb58#I-`fi!13_iQRFEOv zEmJ`e0g5M(wr)t`3wrUq7OX4a#l8qAL$wRc=xm(=nluG1de{SUt=wkN_Qc*^5GSyE zDo7F($sof}5;@p1o~FPTd%^QQpz~aVUNAy>ADyjdz+Pwt83GD5up9aJgM$dAtOJ<> zDG}Hp-U79?U##*6J1wmfY(Un3(1hsefB%EJ!RCSt1VwjX_f$|i2zqfEd>^3zs8)JW zuL6r1)$U%9D>{2Yie7|o0>#Tzkb}}Xr-HP??azYK*r4W_ijtR_B+u#lnKuWI{Hva!V0d)Eo*pwHJo50mM zR67Gh0t>Vr2G?*Ru-XX}%-58m9^-GBAOzZiIpg#{(CTm97d0E9c>okgFXA?WG8Llw zlzNkMm6K2T4yWBfS1i6cl3gof!$L< z?f{h!AZxLg4|6AjOahe;ol_z102>3!#UOWpJOS1WYAC>(Kp=-fiiP*yAl=~OyI)L( zu%YhA66gk-7xbb#9IU3Z6=ZyGYstxf|3SV3naYn;Pl5Po(E=}3`SMXkx4Rc47zhi@edSQOg43W?S>U(=T@wMy z7ffqG!+hY70;N!p?}J{*%E418WR)=K!)R} zkV+x$1XW0|`salpL=0Lny#$?kMXjAPGR9}NEg;uP@`q!WgtU2HXJIud%O%M@i zibe4+$TwjBYJzviWAQI2Y*G9R(gMk8tq^yj_*W4k2K8^20JH*rAqi=|!-Er)wGb(S zTLwKvfaGzfh~4gBFTqp9hSUH42O@_MNIN{6L0S>;6u}2s#2xVBDWuU5@WQ7NY#gWv z0Qn9jguo_&ws)|D&jJ92&q1hzn}5L44Ic6~qVC zIiQwT0HjG4_(F0!NHwIFFjoqiT1wO*$*Z$90#w*6T>+}u!No&bXRixLsA&bLC9MiE zv~wz0SshpzIP}vxTfxerLCW~IgY^V;UOSuu9}WTvOihR3lul5@H*u4&dM33bHHUg)2lXtrN@# zM;S;WuzM=VNKll4YLEbE_3$DMd{{ap%A_P=QKs763Q`TJNnU(f297e2F=?IPKz(t3 z+5i6&dZ&VfAdMrC!(e&&g(0M60a_{sN{8@(&jcTV0%^N|%ty~c(4-Fc@QV}9;NS!` zSNOL>0`o-*L=4G;5NAM~3~GOXJQ&zL6%>gpt~33r@$Ay;OqV%8Ec{_)XV%W^5Dx;z@;XvDC6Hg73ArlEV&mq9Ke=>(t8%; zi!Nw3f*F|wX{H3cI0#ODECKx6!Ql|p-3khzfESYByFx^u_4j^oA=`Qq6d>RpGOVKw z%byT+;4UM`K`(wS0`1G(4pEyW_reRsH8$yBx4{d0ADE{~M7pPfyX4^DesKh3%4;>y zLT*rs$dY@(1T*IZ=-#a_X<&08v60pdwhb1O6(GHMVzL74aSn)HL`*t@wZURi{>4Ol zuocjlY=&3}kIBy>(AX$Z<45R;MbYCA(F3ulc`qp8Fw_ei2d4$_#-Do&K|Ov({_WsY z7w|$3ru_sw*`0>8&>?0VZ+!#l*fYFXybwBy2i~#Q3Ni>B2cRxGo^CsQh`H9acPdCL zs4NH30o}bIvq7yKkP+|(33T)kUTFOWAIL4z33kcr=~;~3U{=5jA;_F7L;_lCc25PF z3Gel+2TwLZN^VfO3R*Y^P4%F@OTY^`J7|!D3o>v4^u$U7_3_5BB5(s+1AOzDba2%`;yk%Gl zq^@}{NC`M`gBhST1&knxmpd6i<5A$G4-$Mc4>UvzS92H41qCKJKb)Hfnj8ZSH-ge2 zC>eu?q43PG)VlWef|4(&vH;OR(BueBw(v#(Y}5+cb$nq0KK&ax8AFol3-3g5v_O(E zblwd-)ug}=-AM+{zMz4Ag?XS`D>(SKO$1NTUgB@5W@KPMnn?xise}&Gf#wik$sL|B zLH-VWkqNCMb|L0=AsWH+QQ+1#Y=V_JR0V1tXo~bj{wk1LMIaNjrx=)hRiJJJxvpvM z|NlsC0d38M>P2-6C@x@`|HWNs@r>jah(=7eK(~TIr(MAPi2LAUACRYmL7PR9-1Ke^ zXk-mMY1-T43f`%T2oz9gfLha_2_I0rfuupBM<9N8Pb*}kuf zPvq!=1qCFqK><<-wj8|t0kWkZ;yB2R@KjJRbc%Gm@CF(6^8Mrg|6guDhCT)Vj2UuN z6*x3N$rJ1q=-e&Hov_dd<=}_R|88MsU;wxLK(g@3>o7iOPJ&zu-rE`j9YaD^1zyJn zS?~s#y9QeZj`%ciuZ{;6@x4=!XSZi`vUI&@nGFhQu-`yo37SF=LP`xtQ{CV>{ufIu zKuHPK4FNmng#$z^trP4#{_VXWVNfei9U=iLq3}2|Fdl3qc1MET_+S<&)|4R%z-t;H z{sf0EY;WvtkRnhBLVOQP2O_-i5ab3OrwQ32J2e2ba}dIAbvgO(|BIYi|Np;8p9Sj2 zf%u^64IIXhgcE=xW3hpcErEwGB4f<}B_xemC}9gur$}K7$-H3aLc-R=92^j!-~zSp zKvDhTi5XZ7)GLLI?1EjFCGg@jL;|E37PbiM!DF{S!6V@uC{71QG$>4aW`Y(cf`S1( z>mUU)B;kXD8Em3B_{bg}n2EhT;7#7pJO=i%=}f#{hLjOVUJgb0f`5A}$TKFz+R*_~0r&dE8KC6k2vKl|f!S3B znj4R^fJVm|UKGsu{~spX+rtXc4h{uaV)FwT@ly2vRD$OgA*X;q!vQ1@N)6DO6Q&P50}hUW zg`ChVS7HWVnUKKj3Nsrfb}4~56tn;hVqQll%cd9Kr-5R|0%0I{uXKnGn|zj-m^k~%~8)7ZnH`n2SZ6T^=W z|Nn!|?3n$~i2<|(golBFVbVh<2G9aTkeaTCP7I);0BtA+sd0Mf!~oi33}Wko^!7pQl78sK09y47vX}Fr69Z_? zFNpp5ffEC088C=__kj}wXyK*;BLl<3N^px6hUKN9u8i2+oggVu-oJaA$FMJPzz^nnutC})DiD|J z_njC(^Ff~&7#OzScVYm|CxiUH`o0qbXbM`4fq`MceJ2J`TMV=>eA0a<22i&U#O}E7 z!~h!31hH%HJ28OTy&!hheJ2LcpaqB>eBX%yG}U6!7(fH4Aol%xP7I*_1&Dq9o)ZJ8O%7t8 zzvsjNs?tF0{r8+0K;;pLz4M+E1E@F#vA5iFVkl0IPi06>Es9Tt9rKcxT3j5T8=nfk z2+Rmd8$xL~RZ+lDl$sWwiv6sYREDC|y!@iv#GK43(9te=@o9<4CHY11$@v-acqP*+ z7>Y|$i&FEQ!758qa|?WmUGq|l(kp{fb0B7=GUQ+ifmAx@XTTf`(GF7=Tnh3Kj2DkE z0Cc`gVp6fQe^^d&d@2K+nO4C77Gp>%O3X`7Wypn4IDD0onFb09e6nd349SqAa7v)Q z0r>?K_E<#IDo`Q=J!;Y_7|K$MN-~oZbK*f(mlmgjBdshI9L8w6kwuGAlR@XS#v{Zs z^GZ_liZe?p!Kb;#7o{fVfWibJ3=?t7PjoFy&5QTUO-y$xO-oBH0;z+E2BjwEpon6s zi$_&c5bvCkmxHDZDu}8Qi#o6ns;YwI-1y8qhQj!=lro0=(vtYpiUNj|%%b?R__PX8 zT7@1%RFGc|ar&7v;PYvD!j8Ls0i7>--1P^9`U9f)_q&QT|6nW;;@|Hp()^RDgp+@N zs7UiK=2Ffb1s7*Cv>qrG&p5%xz>u-v;%tTtiA%E?Uf8VD1>Ks)zdux>`4?ELt3>k; zuvTA*=AX=^oVx@r&t_=7R4Sfv5~S7P@@$5T9hYY_ykLZC-R=uMu1qB8MLiR&Mq+*W zn*(~W7HE^B0RMK-@spqo4BpZN;lJ2F0lcCDbcPssYdvV$RHy*|b{4Jx@aBBbjzS3c z#T1BA(BJ}i4L^8ymH_{D9)Z9Y6%e_!PS-D>B~YM?W4|&&UBch;4s-*rYHu6T?hCX7(mC_xblF`a|PAw zFOET$EbjzK9el{Z?8^f(t&?Tq4zS1r24;w2u-=Q0m_vE^_m}?ZW&zi}mHq$!zbNSk zRl(j_%>1C>d*KSV)FR`VCw5B%kt_wBR0J~A_YbHEp$;2r z06-^`g7Y`(Dcbz|eK|l)dsmQFM*i)g5hW- ziyN?4K>Zh_{BHu52KyT&E25W8{M$pn1iiSf0alJHqf{W7hFY3{+=h}-z68AJf*FQ2 zk?26o0>?T^B4O_S|Nq6muK)jE{Olq!w}1^nEBSN`z+MS>p$uVQ2EmJ&U7#pC3(84M zkRVV00}t|TID>qXI@n}fK^_drxtR805Aqb4X$JzpS`gt1PI;_IrXi$22^U+Ci^B}V z8ss}6sTdquC_z4<^Z)-B-5{c^^Z$RGl}ROJkrCLLsEG+P<$?3%L3sTFE@NiufddY# zAJs2l{U>166UgIWMewW!5_u7Yq#Z5;%7hm?K)a06So z16nJCEL4G;?gcg#eA%HuTDR|yv`!v@7or{i|ATFXvd2q z5e5giOyG+~go5L)Z@}aAa_x}SrJ-kDFoRqHHWthA_@LuyLG7M7ptce2vQxzRU~PGC z=#e1MEr{JRRL46N6qW_{ zkY@hvu4h2En1GI{KEl7>^$7EYpl;tQfiE0jIzjic9!cvAJ@dl14V2OfK`j~3?K~i_ zf~sP*AJ7QmZ|MZLQb6rI-!FkL{zAe4RQ`i)w5kOZWnQ2t>jhnY0zLp7a(X9!>otN2jK6misDTL@;{ff| zbNvH$jUdQ184Z<9Q7=wy1D`Jt6!1b|E11>k`r(CX3*yL5xEH{hx_v(czG#C~-`KtW zvl;mqLu3oVdcBbJg7-!Gf`d&&4Aj!z+YIuo5y-RPL%l&)wMzuNX!{CJpP-Expn*qU za5Q2xM?hJsbQk0d9c(9OgU-6PK2_@rI;ondSe^}O4q*2xAIQ0{XM=AUJns4eTt@tA z0?p}N0v&=3x^@Kheh*MT5R}lmLGgyWzaV0Lp*F48_XzZg-B5ubO!vM>1h3iy7Yv~n zfWr5&r$5N0?6qcDr5)c%cr{`Qmlc%Sg~B64x7N z&YaL<9eN|^#X-nIicZ%n;2qDP3wHuDOpJ|-Uo3~oT<8Yf3jw-g2ejp! ze|rar8Q2{Pn)U@3N>>73>;f;g6X_1+=xhR+@#1D9Xt?=BK)3IWz!xzvqppB<+ckmi z@Ckre;sleq0N%t7y0<3~R8Vhk0x`h_A^-MJkO!{>ya*zqz6a<<3CI%A<=~*( zd^%m9yhsKK_;RFmPXyielhzr!;e|uv|Np(NM*^}KL2LLYg6s}@v04pWBn2S+{NhC_ zNQft`({&As1337%PXu{5=tY?lg20G%d>i_@$FE_)7*7tmNVtDam7i4I?`ACKJn-^ZYAx(<337|6b$Y&>pBme*Z z2Q^!Tzd-Iy0ZCb9n&q9YU--BC-U;ju{Sfp*2PXC*t=shvXk-ag$oZmNl?xgt1G#cF_%uo1 zADFIu^WsV^*p)vpUHRh0j#`i_-vqqqhosE3PS+dVzApk_)Wi8#__v4N0Ns@s@M0D$ zoxb7U?t3M$JM=}+i#C|pi(c0=prh}vfC|GqK`&yZK>h}2R8Ug^)DF~=h6-H>deMiF z23ZL9@h-?h=K%igt~WqNJqUau4pVjkw2X7Rt4zR)CorKCfiFB@Y*4BECZHSCkSc+i z@?v!-$U2cu*C(I^pM6NI+gGA@3UpJb>kr6Uh0rrW-L6l-89Mu-ShuT0Z;t?E+i2(y z@B#@?qRzgk!wlN^>-qycgcAfY7;Ne(9cEt%P~rz=mdqMZF^33-2SG2wBtecq2?k|^ zqhGWmq#?oZCFsRw$g-e-7ggXUA!r#LBs}f}zF>!`M})@}n9zy97Zxx!EId90zDR)? zHyeCX1V(s(>RV8qhdVqVDp11%5>lXf8<6M0-7jm1`Op9Z2eu$Yf$tAci^IDb)Z(xN z4S@84Zm8)#8_+9y;ky&Vi-+65#X|ED3+p#8OtwQx1yIZ4#&;)%Gtm70f!ii=Fez|9RtA(-U{k@)Rsa8kC*UtW0MBvy{((&+YgYaLKLOnN%Ra=A*6qXk z0{gvpFxT+!58-_Q+9bCeG!_9qm<-lO{sG!}=lbQvwaWkhVP`=yhk`D40j1$i-w!YL zRDy26_y9YikD1vQbUg`3U%(3k$RcfUhJqdf$qXsqetU-C@U%75WKbyr_B3<|1e)t*pwcfsLu%mw@Pt1| zjSRTm4%#hw10sbi1M#tc1t{&CfM%QX{(=q%0;T;kznmCeJlzaR`^`sWtlzw_+yY7Z z6F_PI3P|?<|No%6@xd=A*jyMWy@PRR_nXEy4?veq^zKyv9hO~zsMQua+@8Z=e6-W` z&+*nB|NetEY%;t!UH<=nmP8f>1&If| z2!J&jPJoW2XX)x}-2yu@VGqnq5Cdu^h{?ad6+-!nfXoE#2ISvA6(rQ#5(;)2|9-H8 zx=?4b`h=I$=wRKPps@n$_g@9CFSh|DB~Swy5@S=qDKO~8Oi0ZL+O`1F+T8=b z{WI{zMeuwPWECtZIm6P|_8wPI9D275s|17FynJ8F9? z$PCa150L7>7twGFLHzEiV3YZ`w}N;9S^O`$A@ZQ%nJmT^wveJD;Drh#5IVsbw|Or} z7elQOQa)xb0S);Tf^IwoWzsDE7mhHK4g_Q|zW6Ky_GmzNFGz3Ti^b2NUHTHJDd5Gm zdy7G)Xv0krc(GaltPeD{57W8=Vid$J&@|cYDglx1o+eV)svwWAO>d!P@V&^ z-58u1Krsqhn_hF--ozK@Bot&xWY_ldxa4AAj%vmqmC0WXXo?c~nZ1kefkpvfMApci|Kz%$Gp zt?~c=|9|nm5Hh^#DiHAEFeKj6I$J^3@^AMQ2m}pQf-h7IUjZrR|HFk}v>XEq;pr#} zfSN_1v8>~*pmkpi3=Fj|`U?L;&gTbRXY!(;5Y|}+--YJ-1(M-izkqIFxf~1=;Yzpb)gTCiF{M=Txxy0wD8WF9S78 z)4F>>LTQ~nt_2{UvlfC{WME~-U8aK0lB<33vEcvz2`@ooS^V3;;nRAc#1ho&=mmvH z;ERoXkf7dwA*dT1sNZh{yogy0?t=#fyhvIIW_7lLO7z#xS&T?p%b;38huq!b1sgLX zpt~0oGv99pz7U5SB8zMYs6@muCI$)`$8NAyGlM`~ogYx+0$;qE4R%LRzzc>&AeKN- zz>8xGKr9YWBfHaO>Vy|;Ag{h&jz9Kl-Lk~8#4;Ed6kyl9PY8NpBMNqXz>C9>PC~$o zQxaeie(+6aQ+z?e+wIE(Y9%em2Ne#BAopN3Fgr86uv?9krw^_Mh|-1kEJ@j1f20eCo*pLfZk{dp5)=+ z-|xW#65j71pnU=~92O$L(#z5X$~sTL!{A*3FM1)mU(50D_k95Bk%3lnbcgaVvvh$+ zv$HQUbh?P%0G$`w?aILlxsQ`$8Q4m&An3|j$eo&tz$YT|fJH&0iaWSKx3=6t5_RQZ z1zidd@S+?d2=Xy(hJn9jIx7PM*ts5jpmfQ<{#4)&(5geoit;@V5l06xUkrjd73Rop zUk>IFMwXx#dlrM;1`ahRKCra*2^{9ZZFBv>zy3roPZwwg<^e=h05pRmG657`FEXHJ zf=&<#ox1BCvZvr@dAhia=HRc^$L*csUR|_8>}_pMG2(w0ZOa~KqJd7U3Wk}dvOL*ErHww z8j*$wzi`V272mF4r)FLRyR1ia%VCgU=#lPHj_#H=kakcZBn?*TdjP7eMHJ!zU(f*i zf$mZc{{7p)POatWo-!TmRLH8N$627-;K@Hw4GHqmcCe3vUPyC*1G?LnBdxO$r1Qnf zERf$h`1dz~xUC0j<-r5g{M#pjA}8p@OLjCJFS9_Vvhi;R&9zoTWYaobPk@VKa8-!7 zr4cm$(fo^rzc(2)z_8u*2PlNTfZ~3;i&t8}3m-@=5AMrnUt~z@bP;{?LOcu97)4c^ z5%59*N$tUhAho=2UcAmk8!dQ~)`>0EfNcPubs56@1~gib0_uH3|WsAOU6C?L7e?TS1xl3#hp3nE)!T0$=0D50h~!*Q zi5d993*EUO;TI_xpyXE$KBO%a+0kHcxq|OH#^!q@X{@&00iVEt6gXhpzNLd~YXJ?a z{Q&J&0S^L!cf82#fldyB*1ep76~mo9tSz8=5~L2|b&xu60S6ksxd>(*e8A8-1)&ZS z(NjR$K!XvWl^ut`gVe!nV}{s!@DW324_F=EjA9PTDEnQ% zfD+}(Q^Wt6_W@hMJau_;30b)Q3 z(y1UO=y*a4p}P&89sxg z3sCxjx(r+ffKnEuB><5DI~`mM+|ma-E8xXOE(ilD$%B0W<#)r%gO}g~gOHLuxIAD^ z1ts~rps_SX5V7Geq!fp(E8%YeE#C*1{DI($&-u4|@C3e)VFFtUD$HOZ4ojxpp&ZOE zTr8lQtRH~tSWqFoKZr;B6oetbdv>|rnqLXg1^1g(|aaw=`RzudfbTg%Od+?-n_Fm8e-GBHG+OwZ}Lkm)Pwt^VY zQV7HZ9gMF9DuqP&!R<_Nk#z^A7{q`o1~EZr@q-l$)P`jVfUhqAnQ`zDS8t1`OeCm8 z?**wl_>hhHV8Dxrnc%dKqLQ<>MO4HPNhK>t<-HkTm9KkVOLDpv<;sITgc@ttNL}f3?q1hLOdRs)#=zvs$9h!ZS4Rofqt95MXcox}oOnEy2dt<2`%f1>dr zBLhQ2C97xi$$yRzC25^rVlP<#{{IhdGkK(eh9^Oh1X|=E642YbX8-^Hf!(13LEWvO zs1A7X(u9Gb`G^Fl=-VHd);SfFWSYSVhp9vy!eB1pgD_Z1SYMt5tw3YW`rq5SK?`*C zZs&Axpo0A0+j~F@K!F?hLh&Eim!Ojpwf_Il z5&*ZK`S-ViWZ~TtkZ*!sESm>%0(idkMb;mfwli9wW^pfw0#(K$pmA@AW>9I>JB3$e zCFn8%tR}MT0GTL|#m&FH6=Xobi$lM$n!A7M3N3J0clS&HZR_OU4^A7PGjz26|G)S^ z`$D(RM3L@^CFTqakSKtr?#zo|SG0(NToLd>_#ZF$va+?V zP;3N;6V$Nn9$tYjD$#88dhz`yXkcpjYa!zU-3XsP1c`!tvE3;RH2x0CB#?B{+X~9N z0lmGT%pTY~6;zM}^|pdao`7y&fk237f?k{l2doOza)?hvz%9+R&Z*$ivKC~=YoQ&W zskyYyR+J=V7oZj*KbpgTfO_sfvQG&0PT>W40LoSAox%(92$*~D0cURyE678jj>!*1ks1IA znZOrW(xBo%<7EK}L9aZLUImp1k z0J0HWu;5DPWfvcSiYUVCq?geBmzCR7A+-!VwG+gAWQfVXQB*mkgM zLFM|EH=q(S1R@HqTtIpu9a_`^1SF2F0O{?8nDO8zxX5_v_#d>#9#mZi^|tza`Tsuv zT6^?P1tk@DK!Zj*nvaO^Z|?=E4eXr?QXACm$`kM+)Y}xa4Gxk9AjvPS+bJNe(=q79 z&Ts$!ck_Z;3C%AVJHZS{Gc!ffnc+qBRB$sBGHr8jDyWqSYJXV2d9iRRq?I`Vv~Vg% z(wPC|7|@i?Tq$P;P+|e)im6i03?OHK8lqiN&I}-zf#zYFq?{Q*z66z#Wm3)zpqOOP zWnjpXa%KP(mEjY#2-=$HToGRk-ku6&fVQ4i!h|3U(2mZ;lEnCw+=}?L3PUr76a){#PJ@Ui zWtPMjI8#c%)F+-(0qiY+m+)uXpsqn^_v%LQ`8w^!Oddu zdKeqfdi*0h`4Ll3$6Zf=)V|pJ<^TVTFDwiUFPb5ybh^H2u6@H$DwM%sz`*dL7UYy8 zEH5)yz=ONp9NmEmouN-&O#K3>6FJhl1NqWALm#{-hKY0sa&(4XK=9ML19{RqL+`u@ zgsTt)Erk#I^8f!1(0F>c@0+yFM$pXC3q6pM&?iCNu4e*X2rdTsk^?+4=a}|F2rLI# znDwG{30N+z)Aa=?%Y)iAp+}l)k1&-uH`g9vF5zgdJ;GAL^g08)eg|Si*^Bd^LE8tq zT{+S^14>>T{0v%b%h4?e?)as3I*Gkl_Zd`?7=s(c;EsS-*^5~qO$Q)Gl)UHxX$s}& zW&-!-(mFlFUQ~iK@ox`(k$p&}+xJcP1c$s?44r`-Sqz}%m{|;<8^?U_1ZJ`Ig7!-N zmIJw5rqlHVNd82?i>i~*k_r^vCtm&owZ0fYt4%=5c)MNS1iU!$*A~=tfN1eO5%|I# zRm*8628Qm?H_eB5zySwZF8YFH0mvGjERpWeH~ib3`~qGaIu5f(I!mumw&tOpTHL^pP(hR>z~(0K#dJ-+YCT1-S6bre1OsVM6F>K6KGKy zNNjtH7s!r)7w1?Zz4iT|CAx1wSA2oQUrhf9N){WtUEid2`#wnP^ayy-@)0z=0CLWQ zv`(j>7bPIR@0;d>Jb^EEfWw|8BLOt@1}f~bKmE&M&*A_jhZoV1R&T%yrcdC8Q(AYA zo5aki4E)wU$}DFaAN4 zf^(=N%ZvUG|Nm!+WPuV}K%1sIK{!NUcH^52zY+{R6(Z`%P~P z*AoT?hJY815UsCIgUYecH=Pqf{nKvO6OhX1io7$!i+g?G$|tV*h>i7|7Y6;13J28K zx+Cw*@C7=K@j~92AuTCBIW3(5G~eF*Mh8^hUD?SE3OrD$`g!$n*BjvS?(BPLxdkrA zKD>bQq2<_{7poB}I6&nZf-eXv#O6SyJ3x-@^!))^q6%Isojebe;ozlJ3P@e(ouF>l z4*@T(&j-taw>p6*q0%}-uQbt$P|8@_* zz!!~&kqeN}AB~4VnIi~NfVgyl(*d{ufoTXp(!k%1&;Tw#grOQh1qe)oJdy@(Bn{vK zl z81%vz#D~Pei}E?3ux9}mAdq42kC5CS`XK0q)Gx3@16~|_3(fs4(A<9_@WtDAU`bHD z_~PLkXaNH5vB1lq2LUgxLz=Y#FX~`MAeBL@;6^-oF%P^7%Jm6kufY>g@99O*iy3dg zmVlN7y|@Eop9p*bJs%ikIjA}e%Hn;o7a|Sb#^}iM!tV{N0QmtcK&sop(c0~LBR;PA zh>rD}7oOdaY!1q~ko>Fwp1bdKeSmdI??Q0X6*17ozduk6RL6Jw1h}MuR^;D!4ao&g z0%_eGX`Q}rUK~Rb@nA~p^nLMSGfapFqUgzsg-9Y`MGs!|frTXa_cL|-f_BuTbq9r{ zb&5E4yGnp`H6LW`4wXpj=BUG>HFtJ=xb=N8{7Ji=ATTpuAp8==nqg4 z{U_iB8zeD;i|Adi!O`3uD#5>>t2UaIi` z`Ox(TbZFcw=!GIAZGe-})mIQt`huP13-V+jhI<4+mb_j9>eBCb^5Ng_`(ftypRJcl zG(jeZet>L&^6&|K(GK0W0$QH)`XxBAg38|4>Y%2W>j$V4e1cxY!4w_{cyS1!u-jK6 zup7KG)%69ar~3w!@IQd!<_kz~^T7yEOB~YP5(sz!Iwq_6hzgRf2OwSG?1HST0HKQ~ z;05R&Opq>chYQ~GYCfW1{pN*R2P_MOcE1Tc?g~Es1X3uy;Ccy4O1L+*@>n0N1#gQ8 z{S%bM_`(|EEl?=)Z};U1e4zys0B;iG2zW8`6*z>ziOu&VI37R?)4P2I(mGiJU(9*| zN?OyJkFZ$3d9k(~<}h&XJOj#~J9I=C7+yGcK-Sw_dHw(YPHt8#1JeAUjT-#heMJIa zq`}7UTz`Nrq7~rZ?5|)FcQS6tNI9 zwmXRgyzqgGegL;7kATu5#(D`E&|+cG{f3~H;?z5@|Nnon`8g<94}j+FU-N0Cred9io0ET__zB62n2SA z^6+nW;tF`-zXw`l^0#aN?`-u2EoD*QUw;a;;)3}EsEg6f;+59vdfOY;A^;k|NsAj52R?j>jzNs`T|On2ZCNiJ%@(Lfq)nPo3{k4 z-~azF_kt$`c=-1_d4P@zaR;q30j0hZpkM+OO0FlsBU>l<_xqk`{>jMSs{&fLIQbc< z&;@C;X*~c6AYag`ZvO2qUZB}A9{%ltTtP4NcEbY*6soWkq7e9^1@011=?#u1P|5<2 z_$P(1;D$vaVN)Dj;=r6xPgZ3)Spg}hU&|EXPl!n|E`{eci z{~&d5g0cianmj;53Ig3u9H0dCBd~WWD1`*Qc+LdY4DJQ+Z})u?_=5E*xLio(E!ya0Z%{;TJS!2*C&YF z#*^0VdjhiJ9GpKu`R#}Gg<9`!uzCFZUC%II==N3V6$u3Slz+R27-;121ZZJ5#Ix7I zBf>mLp?N0Y#iz&MxJv7EJ@a}l|90Oqf!(1R{M(rVUfh7lbo+u_^%9g?K{ET9pxu6z zv`!wUZdVO>jjjQz(I-C!r4iQ~{QG^MSRbsdCPGWXWBi`HVSS<25R_{mW_5?Eq;>cB zg5n750`%Y$1R3{w`|C1@a^sUA4cMIe;t_s(pJ25Yl&-MaI}>Ew>+O(kS%t1M!wdID zNVg0!D0s3FG$;tF1gzh@=xKyh5TLQP23=={C(wObJbI9MXHZ}Er>-*tD4~JI>E7!) zGk_uy#D1;o%m8u)XsqxKNbl?a|3T~%y5Ke2@rV&L@DXd^wc7|WhT_yh5ROkt%_&J_ z07)e0mBfP&iG!#|5rQrn1@D(JVPOExrJniy|Nl;2(55L+<%Yaew72yMI9I)!A_y94 z1Jx|OH-1BALZ^Zlpyn0mzQf<3MA8ZpflMgZrhrd~>2?(XPb`3nq2Hj2gM%M*@pA7} zkg-88!l!|Z6#*B2y}cl@z!$=^Kw>PQg$Xapw?gw-iNFrf04O+vF}`$TW?*<(4IUf@ z=?Qw_4>pGdRDAyibpt^c7(!hMb}l57ftgU3fJWVa|NnpR2Qz4O_doFR5wQHhhs@of z3cV~|ovjzZo&t+@P2v6Y`~Uxrsn{>)<0~ty~bTtSDNq zK7`tOBJf2glGcllkSx7$AM9Qh6rHn?bowLd%s$23Jr(L+t`}1wTA5M2ngG*!A?Sq& zL@U^<2OlyaX^nztWkS)ailp`CedJJLMRKq_L@OhTgI_&Bcy%5`D>#(0Pq87{`s5zS zuPAmFq9|rZQoQ{hXzk4PzyJSdv4bw92d8x>h;sh@Ct6SPw}6J0L6TGN{Qmzx=!Ggo zvZM7pIB|ee{J{sz-M$LFB95KlaO2+(7VYX`1t*zaPzrhB3$p20>-FFN|1-Si@0to? zG#p~=05kZvfhG92^@2>bK3E%?1@<~f5h#IVvA@W@2lqTmpj^EV7k|-t4;-HS+rWmx zgER2Og}b1ZY!|55>~015BdwF^#cq%wq-+Z@a%OmuT>~!LAVu4|8c@*&Djuxgyx3R+ zDcZpM@M4Ud89>aD)S#) zvVfLtbO$n}b%wrpaqkW&6@bf?7n3%^3K3DzfLkCBsB-Rfee+`H9Z;}2YR$#DmCTb?<2JAGQ0ywJY`Do#Vc9DKwI*`*5J zNdmi=wg$BE^%wCH02$=|sRI{#k;CV3Ym3EG|a$9dbpyD22X=?=7f3|%1HPR)^b2T39{+ZT;_j&+ zp9j6z2JYvIbhd)Huje-J1-XEsR1p$v>?#ZlJ0AQ8-5K5ra^Z{ZxBmZsvFO(S{}Y<` zf^>jYf*2r`J0U8;7QE;MsjL90>;-R$4C)435zyTWvLWz=E_jC^54bjP1b5_EI$JM* zR>5uu@2ms`3dCF6Awl<|`xZ1O9|(A%4`HWug4ObG2X6=j-LwkYS@yyZvR$;ZRp38p z8zzVZADsc39|I5LLu4`-7z`M?dqL8HFMQWSqm93%2sDDoz#zcTJryJu^x`0-`hmDF zi>n*#PWX9r5MdOAOI3u$;DYQd=m`^i^tKvnq^Pgv_x;fw(z_(+g_{Q`0z}{zrQHBkFae;GZosJ>JQg2#10`!Z zfz%Mpj5as0WJd9|&{!ouGfn}Y4?&mAs0p(Ql%rnH?FHw#fGp6p4cmJ``43(~K<@K{ zI;yu7lu=;nK#|BLWzkVpovxZ!Vo3dyMs4Bb;fYJy(0 zuZG4qf6GaT+ylmLu>OD-)(E+^5IF^g?p~0-z!&!+tp`XB%Ho3MFu40c-pOEKaA1HL zwhp2Jl*1u;36jIrA>Imj(Fe)c0WVr13Lz$EfO9ycNO1(w74x1**G==pHaqWKMEf+PT%OkV7{19k>#3IP|^ojnsk z>EwmhmH+==xLyH`CV@88d9)rVaRj$P0)4>4oS@TR*r1*PrB$gF(8N(91xs--^HzWs zI^4Pp>K%gu7hKt5RQlk+jb#GeA_Uq#4lb&eU52(PKzpZObbw6&wIVjajwJvwpnX6P zlYf6Jg!28;4Q`k5@AvUiu|8N^5313-TR}~=UY`jr{QIYZ)TMQ^1g3Sig4%~Kv@e71 z4guK%+Q1GHg4OoDAP%&`2djnE`BOm>&}tv7u^YVaKIp}M@a=dao#5T~FGK%>(gJvc zPj{dM|8^FqfNtSmz!%=& zjp>jYJ|5hwffp>0f{1@RWXCze=luJ90$4zc2|?9J(2JRuz{Z1%CR+#_UeG|wCRj$b zR{&Kj9MGh+5aMW1^Rcs~7t}s}@$VwYi=kh3a4|42fReQes7$#576rGaWU>z#bcb^E zwlIO_putY+0c!uHbF)pcCMZyMB1V%)s!X>iqxzJ0VvB`M!A(1J({IZLk;RBA}vtFX$3;&;fGW zePsf(_+PZ2hbFQMpsvJ^ZeI!h?IMmrFaF;JiL(T}C<8Z)SwLG;K<7zbI_;PfM zGzPsm2ENx$1hhKJ^+mvoa&Ya$(&_pl3$*1QbiN>XUg|*r=y<6Y65xg<@kRbQ zP<8~ZrBQ&M9_#hO8>|WG1UN@$h8N#*KuI#L`G^W={x=tr3c>yCBaY4tpbiHpja+bq zj03_CZ#x5?e`Cuq0uf3B&zZV@croQHsK0m?+}noshSfl4qJT3jN^iJp5iA5*U(Nw7n+xUW2F*N! zr;uN~@IDI)&d?WWouO}D*qw#;&qV@Wd|C+8Ck*bN3&8s4l4n6F5H#fiuCPMCKq?wY zR~a-53YyGf1@Dprb(Ps5=fQ)!%H1MOol|;2{(kZJ3@9#KzZ`tP%Ipd{Sm{ezw}?kt z=Tz`f3tP{C4nF}gK~w$veZO==v<1D8z6wfn904yrLAo`at~(%c=?YHJplRNN@M&I1 zm!7|OIjHvmIstP(l8Zn`Oa;Dp4V~mbl7Soq<^*;iNIkT(4?c?xvV0EgNKjrtIR6K@ zCVatj2JAdgfT zLqAxbsx<=*G8}xs20icVI7Y&UTK{@uArXV3#F5wBq|3U-UpXSy{-oWviQMeLk4v4EeA9j^(LqnGU(C^wk_}l z$4}4zr~+i7Zoexi&Ai}Wf3Q1LrkBMjpx5_6;ESm#;1UngD)4c4W_VGY4l077$Mbwk z2ek@7#j5q27dz9TAq&x;~`F-T>%y8iU|No%#J8ro#sozq`|yYgampe z4^jhKJYAAo5TBb^0Il@F^*x^R|Bk!<;K-ZB03JTUUZH~z_&f_rJiZ*@wajn8ioq!j zV`NSSG}ba3Jl*X3r91Qo|9%!P$lfJpUr@UH)5|ik6SPM8#c|L=8ip4>$3cZTs6Frj zv@*f<17srG^#iCNhn!Aa>)Gx4rkkVF_X&7WFH2|W8|Yz_AD}iss#@6b*xjKoK#RgB zeFqgEJl(!8IvHO)JqF5t^Iv*`=9=XaHLqBx0a0R@` z17DK@xi$RLENFdM>XpR^GAZ;0?Ch0)-Jx&5>iYoUtb-VrmO<(*ug0Xp{`G|z|n-|O}=ur)haM1oym0U)K7n4&U>vir- z`uBgQXEc`eI>%iPfU*ioBFJD603CMbs}T5N5oGCbz>Af~K?x6ZmhGKgpzXkEouM~g zq=4K7TP;>1+#Sl1*6jpZ>9XU6=Mhla3S+AnIC04fFrULStF1Z)geJGl6JH-e4}2W47f?TML&V$ZdBs6Aj?uo}W#>jm0j z394=(8&Tg(0T~hc2D%G1I1Xe44@8ac2gnvw1F#z3H_-j3_hZ3oUN3xUhQDP4noy_$ z4HAJC7eQ7a?Rl~B5U4Kq-2)mD0-c`2)6v;86;!5!1TqhScJTN1u;v^_K0pE_)!8#u zrX8f!^+)Cju&OD%DecI|{eX7Abxvu$()R!V%RG?FK#kc4pePG{0By{I>OWAmxx@Nk zZ91qw%!D{H;Z8s=xUB+OJ_jo4PTU6XhX5xaaN8pE2h@}wAe;F2`+|mA- z8{&&zkw%bg=M->1;PuJZjr{w4?*zX1l?)0r(4;vFC^WZE1yMm+A}=-`1f^@xh1m>K z{{2tucHIFwt{LQN-v`hMng{&*LqRUT0jdV3@iQ>+Z|?O8iVMuA+QvyKCnn7)+GcT$RfaCrHtN{eh%Pme_pjKt43-6g1ks#~9ve_3I(z;zl z&w%Oya5$n&bb)PvHiyoDtUksL+SkI-?Zna9Dlz3B_@p^saOMep1C8)E{QF%&xm^R) z2U-Q%U(Arj@FM*LIOaNA|4jb(AJpuA@pL~}B(1ac3rxrfrsxe!H7wn z{NC{I4+X`j1}HnR!S20!0g8jr7tk1g!N1@21^<3uaE#xD^m^ZPw@d}Ov9q-WWaW>& zAm@UdGQ}6<&a}>{B_Qz&U~$(s-94=!*LLaqJ z?FDtWd7zOG5&}gS$l9P6R(ruo71X2c?gg0=*gX~G(4ZF^APaQ^__w!$>;$D7kiP<7 zu*0-~PBH{JGoZT{6cT|iYN1+QYyltL4w?Z56>|GSKV%;gf}ArAsXX}i`@ZNE@c>Q# zfSuLd3req`xkGF!!5vmmXFvOd3go17NHxX3KlBAS)w@Eh12t;1FRFl#N%wt|eUgXy zBFG|8A31mrXj3c5E|8rt|A2xZ@P+vvXb>Rz2NVQ>FV=$RkU0Wglt3CC0sPy+Aqp}B z6czz5e(#3r1)c5-3cjFjaH zJH+q${~s+)zwrlcOy&p*=xzlW08hAAVB#;hz$}3v&^ck)T5%vdyL~RO1a^yD2zqhH z4`d!_eCxx(hupnAypR@O>6?Sk*qP7q?=OAP$?~x?I!%f z54H;A7+A&w1zyk#cbNE#wGiV$j&c2P@Bw#k4=bdp7y9PlBX&>>y1wWRImi;!&2li{ zg+D|!D7GPvfvCmen9!Y|A`5FP71e(+z99dB8YOoo|N9SGtTh=_gY5SOdv^-dyRL5z zK453Q07}H&E~i)mx_M3ozEE@nY2^tDc(L3E#Nq%|_6HwvF^7VJ>kVkU36?wgw@(Eb zAH=`C71W#w$g+F!c?UdSy?72~?*}=UlQ|SL!tmzcLsm%c1`Ykb+yP3w-XKEs$N&E? zXMF$vA6$%ofEME)K&1!&e%~vgiaVT*KpR7B2Pk-4aknwPZvX#(0y%Ar>!4FBK_j$8 zwlNmM+8E3Sz~Rx^dIQ>4n0jIIzyB|Cw*QB;I37b96P>LmK=Pmywhw^heLxNcw_L$Z zi_j;~@OZ+%A9N!HsO8Gv3vOCW1=Ypiqse`rV9VJ-FBUw3IssHv_qKxU2h|CnrUhte zz?6UgK@kWR?(PLSGw{V)@WmV=5Lb6&wE~iDeZPRqD_c}6KwiLN1z5Pd7v$5x7hW(c zKwO9w&4*Yz!FEBL7Orm~?&<7l1y$QG+_!4&MCd1 zYWsyGSQNAuw-;nFs5JtrTVH(K3Mw_7K}`!BT{Zswp&Fp3+hXuKS8ziBWPc~PvV3uH zE6f!wp&;wiI$J?i%8Qv`ao;!H5c@m9wegF|U{R1OdR#%)r*-y%Dz6vWAXk9fj@V05 zumfbl=beKpKhQMZ3(#CB$P7?)feZ?gmPdvxGD&GkqOoOVgY#F2D~10{g8b^h}l;L)CdF3 zIfHApUY0fC zr~xm*#9wfLS;W?Wx74_ z|I+URXuJ$`nk#7aX6pg|9${t%2G{@-xceK5QYnE4GADxe2ZJ_yO$BXtB9IPqz)1sC z19LI^3V^pKHi0YyO$>lC(HqzuFYy~e0S;<7a596pUh?ms2v+!r72HMy515L0yikX$ zlET_6pxt6})S3K6w1sNQE~23^?3zaM;}2B@atae8rW1IS{KI@ll> z#FrqmK&6&8zXB@VjfsddE_jrIoD1?F0q1U6j~;>qoZAf6 z0181+93lrd8zin_ap(nB2nq;LOA6T;;P#a38)zH~!PP-pY@oPiLyl|MB||^gft(78 z3Qow9;5VS@rc+>(q45UVp7rA3I#7V#0_B;Fpgn%zlL&%%z z9c_^LmLPY$76*-Rffl8M)}OZ)fFu+^5}?L2$mH!VUNWG~xBS}!#e!a_!p!4uDFKZW zfZA6jlmCJ5o#_QJAR`K3Cjb7aAQ8wqYWM^wO3~E{QUGl-gY_U<&95Cn1sJI8`!fmD z;GPPiKvU7s=07OyKy3i!q*MI+!G<9^0jsP)27pRH1Bg-l`@vRpw)EG> zd=>EG0{A>^kxnr8r6qV23mnv-@nk0n{_Q*-f!$LScrkA^NFxWRnfJm8!cOZ1JBEMzRFEmKA;K3fkhKQTrEkk1u1BP#8c=>=SPjbf zpsBK{8@eVifbJ3krR(k~y&!35h(ngYfsbH;Y6my;k8B3JB;bX111zUXg0|Izi-3R^ zOILxV(>lTYmp!05_RsJC|3NoQ_kv1^z!#V5U>b#Xf#y0vM-X%dc)W;O_5c3_aQO$? zL&D$E3fdbEQUKb(@|qizznc#-rFHsZ8GJSe!*y~#eo2I{c7z5p%G05wan42cmM=mNVQtD*ecd7Qw*XU(q| zvk$32_G`S!zKA>;BoDrG1Jrx|0CpMHfikU?kXQwqBZO__3EW2Ck8>Cc*$=%_cp(E* zXpM7__iQN=4p|8!zz>o$$gvb{h$ryvd zDxgsW25=;UDpFV@2VO;k`bqFHBGAY~^9x4E=nbU!hBj@$T^0D~%|she!3}OmH@{?r z4B$YNV;R7ivK$gikZDGg<_vDjA56v$aVI@4$I4M$UMbC)vJcA>{Kw}Pzp=c=-YyWd2_$CbzSW?H{1>Lh06qHK; z|NnpalZceL1T@PbLO(SB65;O!jZlCm2*GIqb%v(-mjHk7cThqAnE*}* zsKqW=!9{2)AehfOEkHg3wXhz5TUfmy3S4v&3bPk}h9Iq=w$&AL5Q_s;9v^%N>V|byaOo>ZA-gi2}u6^uHfovA1vd6!xE!(15b5oCvg2T7pb7)mOhxBZ6_CPpV1;1wdZ+M0raVA3 z2ejgZHtl3UN{bhPhSNc=2{u-NP=7+_~OSRBuR)>R|UbVBOxuYUPuG1dn#yLH0Z@i z$o2(@9H|O{8LQvRXv=h?0!3Kj4NqEt+5L8b1gGyU9P-?*4NC7vH z1(-lJnClzR*;t@)aMb()>zaTzIzdt}s8;vJm3Z% zB)37dVl6+U^*~xdS!SULh{XYk0{-p2ATvO%R#5f`%CdXGxDXo52LfJvT>xgMb+&@y z2jWJwT;}?so2Rj}7Ze{a$`*hE5mXg}`m~_gC(vS7@O(sCw}@9-=TuNkzOY{a+PDeQ z5zr0R82IAMS+GUWGy_R2&=l}u156H_X25X)KG|?8$W1{n9zxs*nK%V0fk=XE3VLw_ zSrTMp;ERR)$Y}<(xjpqJ)ES^8gv-0&^aa}1(LNvKT~J>iG_C__b+9sn%XdVY33w4O zACzYPgWAqlK*T{%1NwiKe1?NO1H&!`CI$x3r7W%@J3*T)vM(|-AA-(kF!OI`5eV4H zz{0=)x@IL*UmpjieGdw!8K1E?nj+V?V}$e97ueFwRDVv#cg zs6Pjaw(cTl22i&Tq`sjDWlxJA@)i})=9RPxhRobV(7u(T)WjUny^|c<^ z7=ki-%4RXVXfXq=g5!A|c+B-b!)uN%*Z(Yx9j^cRxB31DjlMyQfgGHx2NC4q-{0cZ zAjH4`;c}#Pv$%qc0-c%*GWZ4P8lDNSw}LLt%sBj2g8_7lnn2)-tYzS$HQ>cV@DdJ= zfEPO;^?ASx`{iJ%4%dG#p8Wm)f5I`>|BSCWyF&kijtB|;&%e#}Kd5oFZ6YYpnh!Br zAF2&W#Ijw6kKTN5apL6*MAfm@;jZeAaJ z!~|Q%1{%;TkLw1v z#KBuDd|!a)7Vo?`{OAAw7yCfOP7v|r4`eXLl_TKAid?A2`CA;A7#K1bzA%DM4}WnV z=2-p~blg6u){Z}*-Tr=J<(49~xUU>ca|G(GwL?HCK4%a`R zL&!jz&K#ebgU*=mbiL9GIX3Y`U^nE@;TPa5<6jtnui6vobp7&r=5f~#V7qxhcEc~- z0gdUStgZ&x-h7A&#Q`UO<8Z)%CkO}J0i9?Dcfg&1Zr=}qFV=&%Fo|@!et10%v^=u) zQmq32c2}tEMM#^o)Aa*1h!cMQ|34v%5qyO25=j4`)Aa*rR1CCkbkcNiVomFGy~Dpf zlp`pM>BW9XOA~ZTTCeK~kPGevf;K|bzet5>4*(q({NluXuukx0_Aj`>+uwQk_n+tl z9p@2x2XwaDi+~r+5aU6KjDI`mPCF%t0H_7Yzuol$BuHhCfQ{;O1sxUg0_q=Va5KXE z^9Agm7cVA&F6Q9h?)oAC;;0J{1rU>%bD)W)gnt)gbT0JAi#Vu`ACLw?Mx`^u3olb} zg8*_Q^ITI%0-gXm$h`n04L$E`Wu-I29VmNtr8C0`D0@n!GXv<(*7#J|oy)n2#fb=B zW^ryj+Wx*BHF^vTFCLq!gU;w`x%mJ8&iUL}maD%2-S+`1dR;XFUR=$B`leJoi-mu? zuSVdDLogx!mS-HG_ErPvz>}$49{&ITqU zpx)LC5C8uUc(HRQs4U>%-`)!n4$NZcoeH`|E9gan0Z4)el3Bs6{2$Q4$RD8Px1cLy z9{&Fi8jA-Vb_kl*@dfWH!PwCUKAv(e0|P@A8$=^$)3!)AS^~OzK~&(2ghOC&f)-YR5AgsQ0-DwR z(LJRX_zksP$SkIJh%=y`vanFdoL&?17BqS0Btq__2xnR zm)~KXBk)3P^i5#kfVDnV>j7Gs4LUIgWEQ9o0@54wqJ9e4fuI&W|9)SDv&11G01|^a z>&SOd%XTiPuG-$TM4W*E)X@i-68OS01DX~}g7~+C;~TPjssp4f@P!o2k_(`jXHb-a zrkNTK_J}hu1ir}e2FEF=F70jwnU~fHHvWY(*g{`WeYAZd$Rv<%kb;00CniIk4JstT zUWBI|S*UTKI}E|P(mKH|dhz8Os0=;;+IoT~<TRIIw3k=^nq-BJpq(rTQ`6*LM})EHaQNCGOTOs z9Y6;cJcR6->zM#@1ZceG2dHHO<-T~F4hwa`G|;)%om0UU@PI6My#h2j(A^=X4%(&P zyXN8l|HoRFKm7ln;aKZ35cT5e*Z==tJOB~5ze48kw>3$qGcdFsC@}#ybU+-2v~IAW zX`NFcMu7A(zE}y;wgg1X{|ZX04b0%XEBLpA?E|GQkV}GIJWPYSkiR7sG|vE>hA&75L)ST)39~;Na?RnF`9?0WU5KhTA4EFA+?QFPO_IH!_yGm)RFIOO7oQ+Yr~ue!z<&$fD+e7bhVVd1q_RLr`)7r8JPU zLqTg)#MB|TEKg|!WvZYTx=>Gm4io|9H(!o!nA9cknLIo*AoV~7sME{8y%%Ddz>6<^ zV248n&_Km~zzat3=>Z%8FJ3^FNO!hofQ;+~IU}%pDu@&GLMH{9DN200TS3V`pc@=o zfiE5Ig0JUB!34yBw_mK{Pa%Z=zPQVL8@Qnom z{GdY``1gYi2OXf!GXb=Pr}2=JJm}Dl{jDIUfKG=8HHrU$?<^2_UBSN%T(Gqs0M$Xh zGJ)NpI-p936{INu+m(YAW?#}kMgU(P<2d}x}Io1RclXxKk;(~6W zx^Kn=IzAQD&7BHT*a7YXzxV;V$D-SnqpJhdt?KA)1KAGhFoU=(FK)j7|Nq66_n?ND zs|2Kl1`eei2@DJjpdCqIhxWE`vG6c31ndNj&SYO?=xzl$zqd!Ag_nULa2Ep`cyz5B z?6ux0j4hzsOLl-oPcU>tOmN|1*$FoDB13PB00T3~G_VS|X`ox+F^ytmUiY3EU`9I0wEE zg4py@8+7_!C`VT-DB3!}J>wT@pnFH)gBep>K@kc{BcL&ij$Tk3{sr^9|Nme716_I% z3L3`f>HziWJGwwAraP49SQAJo!;8Cb|Nnn+1EdNZodKXruwLx=#t6C|vpbZhs}*E) z2RNO9Qx(YQj)@?>FBXBc&IMn*VFT&|fVu_y;-ER8M3aBJuLP(Ms{-n8fmRlYfX;32 zMvA+G2B5eD4WodwD(I#%$RWPlL&2KBy#<-T-l-oR{{Ih7059%YgS04sau=w};SaaY zyF1hXd}{>g&N%3j-?jV*<(7tH{@XZaNYwn@j!q|z7mwfk z|Nr9N8_>lj+kF*4E(e{!DFSM*t8|Bo^s;mX^!9>W68NHm8I;XLAbmECc4vkc)6~Iz zHpro-k{X~fTu`UV`pt_w>W~f`XydLyyE6mG1kfG8-`brSK&=D`1_p*l?T~wdL1VAy z+npIe)g@?r^FX^Z1E^L8vA484Gk|JF5PNaEGXtm|0(BVJ%C7|KZyi{b#R4_NGC_gbJDKRev zd{9t&Wqc|Fh7f3o6Lc3_erXBxJ|H~j0f3sU9G$)|z?GCA~5^DCx7LT{q+%ARXnPazLIl#@>2!VbdUqBJq}Ky- zZP1IXXsGW>Y_k|an=O$rBgp*i9%&%Yb~ANz1itY32lAUvr|XmE+9%)}?w-8lVrF1? z9hJoj>AZnV4R|2}H`Ni{RIufNppfI>M=|@uUre*tf$v5G9UNEEdY~=@bi@ zAT1>D8A{DBm<~Pw`)Yq+Nq5TxkiP@6m_QwB-!CA?2fdi=B*@TwL3ix6&(RD!mwx-0l5sk=CY*qQk@UHPzdGdcHydkmjNyU0^J@8 z{M!SWg77N|e8JEP8vo*W9RR;!9MoK71Z~xYYYpKN>2^{8Z!adOD&WPs7O;ukz8rxs zF3tV>zxfEui>eo(^BZ3L|Bo7BlOtitK)c(Qqj@Ljnq!7i`R-7Tpcn4o%LrId!cLTt zf#J1t7ArV~bbul~@P$0w46W`^j^c#{fvO+4Z&8ZO3bQ?XWjnF+2$-)ZwB8DVIaL-!#AB zIPUrbG(-%WcliDc?Se?wmzQ8m2*5+Qp?{#;ivB>#3yy9<{{3CY)EF4757tV99RfPL zqIXKi3D6Y43paPrwsMx&N5SO;*a+W0(6OsOkg|uFzc(CY2aX|%=3gwe)gZruc9nr_ z{n6bsv4oR>0etAiw`ABAmEGv_$5|R7vB=R4zK;*o4d`y^XaH#iwa<4$wSw+k1i2YW z{y577kk*$4pvAB_I;YJ)6l$G8`9Kg95(gi!_x3RLaDqljLLo;)MMKR8U9EwqCys%J!qyi#%>2FjpuKzoFFF&! zaRW+R-JxGPTe?8e2+j!L4lC*jXP|T*pOx?;1fr=Ev}w;3bP&vs?$9sYkR;F@`lM5& z1604ku2J3g7!rJGpe6AVpkxMWo+Iht=?Hw0xESo@*F9MRFTN%~-4yz#+xJUn%S2Ez z0*yjpJEE)kCrfQ&mcfey5KWz~pkpZ@c@T7v8(43*?}JXBrsmoQ@F-P+y6F<=!chrO z*oUI)VQC6@(Jcvb70>Igm!P8>@rGwRXh|5Je3+V*@InUW#ygF$3l}6y zf<`s(fP?N1+?mynAVH@Mb|xt34nAP-_Wja3g%P636>_ee@*m@=B8z=g;kaPpe~>Kp{Vh=*u>eL9N`Y&m2MrxRig=w6&JX`PLrvEmo3 zpwT3Vq7`5lrl2YUje)&*@BnmQPPglqw9W~TfuS$Q8bJdr3@?s8`2YXKfd~KpXG{P! zBS57GsAhS=3t6Wf@Is^kRJ(x=<#~h4C!iH_p#3tS!)^FM_X$C6QvC%POa_(u;3J1v z0<#!1{@cTS%MZG_jt`;;t^5Vw*|NmcH1`+4(g9dbsLFN4=NVtfA z%B=18Av;t;zjT6Y({9%nkfS93Ng+y3Q0WO?Z_xZkBfPiv#!k=~vEYLA^J-kVoqxY8 z4`{vyRJ%fQENJKj-okJZ5aT7ko{^8%=0g?lC>m-6+v{ysI0d&ojH%xH}KWtq7 z!;540Kr@pJy`gu4pmVLDi<~%uUf6<92@-*}bY29!hzWq&g{-|Dq#az5f(OB1)YpL}_da1V6$0QkO4$AT9@_x}HXQF{;MxzG=-mr6m$U;Y3sEs_B*h%>(T z|Njoq#34+*63CL*^`I;FK=&Ry!~9Vy3~E-pehGMC023+!k5+&ONxEHS(mF*vUOWL^ z%kkPVi-~``@0Y+AtjJ13e}JdhyM1Lq>oQ;L1S=H-`3HKRG(>zMNE{>z?q`F}H~0V= z4D134zZ3$U^4WbhpjXspnlrhvp~J5Zb-xLMLOK|g<0@g3RLY)VFX?9%fH>pEdZXV zTsgXZ1S+}%S%R_{vshk8SAjY;A_4FgJfwfn?ZFcGg1-rzP9X7jiUHKF>)`^ocpV*H zYyw^2@j4LPO7DjDEbsY2Q$wjl7Bk2J(Dv#vn0N`(Yk6dwTENB~cK|JOVt5e`GSd3Z zi{;|5>&3zM|DDihV0hsy0Xa|1;==#`J3nEYpao^J);Ayi|KAD9>}j37KW_j3zl#Af z4ZGn3;=m}7KU%mzEdbCJT%ElaK;ws@;B^q$;op7;GQQgkl|uLf zGp(db8Bo%blKKC|IEdf>u9=mGn1`U7wgf269(NGCWt}JPttqU&v z|DOR-4K}4a6g2JyuE9>jR0qLT&$;mb|1NNA?+`<`FGuebMo?=H>e=HgO`wxV`M39i zlm))1J_oi0R59^y2U`^I!W_KVm<1HzFRUv-@*H6EKo?7a%oBu|2X;y)OBet4sUWk0 zUi^odbs*qHa|=ix3%J#J@nLr;M{f@oL>oAWI$0+2Z*K)@3wZGZyiOHt9sl;JAioB^ zcmfkU5b$D0Imjpuuu<6;LHV$E3YrsMe7W)e|BLq^;uVN^3c4KQW!XRQ(SR0dol|`- zfX*WZiGs7$mkW>-(Fg4utKomm!#WN9-RDU;qFAg%F6~1ra|$ zcV2u35$~>n+Bdtv_v1_j6>^}dAW$r1pGaT^UEXRt9h`Ofw?kw>t#)vLfDWAx<>_tV zYG4GlY_IWxltBhCvO$NgwTObEG_AAs3AE_w1u>ur1;pgvKNUoQ(*yVnwjNfH4p4G& z5@ul71u3$pf{N@H9w1kO!UmkvL4^Z2=Ri$^6b|4_!N1?t1k`-`2iYZKk=EG@PPgpW zK-)k;OpyOT8o&|S2rBYHlgDd5{QnP{?E=YUUIdq2Eux^p2}2N6puq$|b8?^y@Arc} z$-n*rcy_L%S7c()i>23W7@ChrfQme@qccx{O`XCEG9c)Mn+PbpI6y5}(A7z|L8auS ztDuetXdw&8(;%H-Kf%jVkb44O@W6C}SC4>H2E3SoqVwfl&=MF>{s4Ig6k1?&p!owN z1}(|>_xFOL-1=axE417OW!vr0<&3C8x70w3Q{oH31qoCNv^h8fR4l9j-No^GdT(n4 zsOI3`4mLKhcPdCS=!F(!DI@>>R#3ef@ZuM^VgZ%P37}lRy%$7*Cfq@u33~Cn0BlEE zXDf(Le5}`k7T|!i1Y!mqD9{662r7d1AMk)Kp1J-1e-KC+YTSTAIOxSI1+cQ${rua( zP5_w;N;-ir1mI2s@j-bI9I~Jw1{;K}wgTrHP=%!iK0E}h4qU{6rVK%=a#|cgi$l{o zTSOm#f@428X+xKGGJvZ6?j8?N=%;n|fK|M(y8QqD3sdlwAeYiQr(S_(uvQQQ>H-iG zbW1HbbwcXPMWEsj)WFO>!I0KHg%@O5TIbX|Fx?;qR5yspzrPnm!Q8>WAL2aFHv3@E ze!l&^AUja<3RDYdcQ5~buxsFn9u%;kn;${#DxRjm7vXcjaSYn-3^oS2xxl|4>?qKw zZcs14Z2?6ik}WR;pvJs-UIsR=v(@DSWOAYv6hQ$m?DN6mpn5pV?#049FfXmM)dn2W z;L32H?m^Fa|1_~HT^SUtGklhz4#Jl?bmNjd$X zeRbOjItlDVen|2~iLrneC*nc&3J~E=u)CqbgI4f0LkxN816m2VeJZFd3EBZFR1ZF2 z=o1*I(XP=a`AZYQYsMuL~1#z3`k( zFT5cpzBB@dJ5ox!_^7u<6y(kTaKjSPMr{GNQNb-3Pyq+pMFfhYY;fNOXbypvlHl-$H4Q*s3VLxHG8qd#QJEh#+cBdAIH)BLcP8F+p0OGl;z(Z3 zKEd2Og%=d$kYonh(gnJw2w(hx92oFI3St_GVGc>>7!ClXA1n^Q6H1^^4|=h+4I1hw zKwg5RB9s8a6ORyYB|}UEr*rg9Imnf;G!5#Mw{w9CG+0v&tQuStWuE}$U62dF zP4ny%49pjUUPMAvLwkszCQ87Ir>Bt{d;I%*K~1N?7xy?p1|!-=;P!7&7UPSj>EOBx z+F%5?m|iqO#L_xjL45x0Q$bWvZ>!5?P-_<63IjPOsJ9j52hjXq<3Uh+Bk)DA3}|Xo z0yH)T?%V~v5X``^Bg^iEG{hE=>tDn}*lC@uB9|b`yugeA@G7Q@4|}KZ%3S*YKM1@~ z3Q{bC_<_5?3wjQLifJ$((VGCP1m`}Gqag|pK4R!?5e4xf=0eI2F#iSL8PNQUMsF`@ zSO?T*1l9AP7CfjS3!cvb_cP!{*bh*{zPA??1cAL%K|uhTA7=%HK){QMa-a}U0BsZE z;NL$HG_u?HNS=YAp_0|B`P2iapcnFK;1B_C;%NlQgBSlbfmom$!$8A7Yfk?E|6)1l z>I_g{i%<#F{DZmH2i8D_Cdq@3*dfIYWO`xh3HZp=0S0E5iGM(C4^TOgeK7$RE-%>r zgOWeb>uLPkdqGhVm?i(>P%7B5{QJQsfZf~@$R*Ce@Pgwcs8IoKiGun+APbsbFhZOE z;EOsqdRv;na}@mhu>|0Y>EJ~apoRuG+_U6ggkrPI3uM{s6QI7<63`eEXdWFj#{o%p zJfPW*-l-cvGW^@YLuyb7ZUzR>9ChO%PzVIQc=-Sn$ui)kKd7$_D$&6`WN3#EB*woV z(#3Vq)F3T? z)X?b>MKT=JnA>n1JctphcJU(AECFF-OW zq`(4YO85v!Q(*U0kcB}nHbT}X!$*RlZCGsM5#S5KU}YYPI>=B6)Ke3|lk<@K_e5X? zD$GZv9NkmIAj-FbgOI1IlVu~gVnZK@f%qGoCb~tMdRe?ceKe5213~_t3QD9wFOrg= z{yq@!Vi}Bm0=bNV_#0|WM^HC7paWj)ge*ORjF96Whe7xoJcfaD2nf9LcOm#HKM{nF zAjTPh74TrA}LzfbPqvhg5lt_exH!Knnp2j=u1@`k= z@R1A%qJKm7my3!}rJvAm1mgDBsCCelDdD9{m7a2h96d>&>*>{0_wkG!~W z2(+#Ov;*Y^beNzQ#DJOuV)E~w3Zj~SG1u1f?{5XMVc9v91G+i^UixZ+2T5>XKX$Wp@PlT6`L|C6IV$Ky)gf@xX-4w_M$qwKAO8P;nGBks1&w%t z8~~~=z^;OJ06=0;w}Dq-G=W5u?gqjE% z5CD%Of*0sOW3F4I37kxxWI=R5Eb46O1^c(}ASjMvKwT-wKza6|1ZL39>fi|K73ly) zILKV^_^S*w=z3Wuf(kg0Q$Q8{%~*)h+b;z5wt|cec(H9FxP=d%WdyfFK#2w%5FiFL zAV5r*2YosCVMF7!=FmbW`-B0ruL{&oQ0>bS2=$clrEXUZ@HFY(1ONZO*a5m=T)2DA?kl-NOe1LVeTNU9Ea@c}%C0l9st#1J}@ z$luZhy1f!IIs-QYo?mt$Y~pC z6%20qiSeGfiRn(IX=$lNAblW_pwz@1gotxSUJjZfun?-Ml+2>|GLQj9scG@46$PNX zb5n~_^O95J3-Ze$W`h^Jgm%Aad;{uAg!k_K^5y^korjsQ?41UUYeO6EX`Q|=K-(ok zMS@<`M}hN3TBqxiH1NWVR)rt`|G)6q^Z)+~=RMFlb);cXg+Hj1<^46_DjdB-9`OS) z*AMEDXF!yJ2k--aKqfL3Gm1`XkZa^(O8cc zWFoVN)#C@a;R4bMo7w{P#JZ;hLMAe&fK|LG+x`Fli^AQ|>eUszD;xE$KhRVRWWL|} zVr?}4_D~5>)c`U#^8{${8GIKW7ihm9=;Doo4_QFhi}hE7{SQ_Ro~nbW2Q9|zox;oU z734P8FTFg60$-?ng7hHU`L~C@fEf+0b$9|_xWmnP5d=2}ZOZTQN3a2~xs0^#7EzGr z(>k#&`-g=E|9(gifqH9AtcYno2~adAf^G!?)jQb2gMYuP1ZZjxRC}a>SK{=7(}vD2 zkf%bwfO{nqKoffW+b4of$peiFfK&v$SQ!RRRiF+K_zELej_w|qO3-o`&^cCLz!f=o zLa@7O4(Mj=7mwJ$^FW~B1<&e&mx!iygRM>L>;T#EV%<(qXBT7*njt~_+g+c4_R4&L zk41n|A*u){`GQ6G_lJV+WB37{Llo%dfy^OpyaJy?bo~PFC4!6zdcpbw6#B3UL{RVr zzL>ZZ+%QV(Yz6T_(_5im;Qe5bU4bvoeTQlT&mMx51-ytt(e|<#be0Pv|Mp&xY~YKW zP;lTu4FzSHP;hF+xC2$f`c$nK|8}t50U*nL5ncyb9`Ir!DH3T{v(i{mhZ7of8_6_`Oo0ij>O2@kQ}05tFeT5n(j&Ze$k zz^NCp*Z?xm*1`*tesO90|Nk$}g09a1tICEqe*FMCC=YBExEt8R z3Q`41<5QRz7{Fl$K8(*5<-S13<(vGy+2Dym*Ec9J3_3OrGRhzN1|El?AOhJ08mxbz z{1TkkK{vyIZX^JWviG)#fCYW8OczHgzE>8p)a1lfa-lA3uXy)w*L9@|9|IH zhOdzMv#Fpk4tnuF7#!xH_D`1mi$n-7t+UnO2k2G-kmA7ZsUV#}FHD|;jRf^MzJS_0 ztv|l}{~yrZi=v4C0Z0)KvTfb1AQb`Ky&z)(U(`MWso>~rH37xY_NgFKKxqJEW5A31 zL16blT>veKL7NU;d3t-Gb8?|yzz2SA?*(ZI?4AlT2vNQnK*~)}2@1;C{M$iSQ0)g7 z{*b~CTta{biavvH;{)~cK!qr5Vh?=ZGXMUmAhFCt;DWV>6;iN*EC$_Y^9Fj26UhF6 z?p~1npq4E@9mvkWS-gXm&vvs+2zU{R; zRQ~<{|D_9vIP&NJ|CeFEK}pd;}hp#|>g@PGmxlr~?OM1rFdGzbO`8C;bb zB)v}vco94Uq=5%iioZyY2eDaT@o)+p0--#;JH6&N=AJ@IvJ+xR(Rjak~61sFTCP&A?#&=0(<9NGB%^G#|{c zojGREX858)P?U4LJ`Jur!J1L`s6Zl( zzZZ01bCwwRKncjQd6{mW383}CFX|zUfq)lmkcbO-Aq!6Dpk@Cb;95W{)MdIw8bMoZ zUiiSYT!v=&7q7s12BhUpukRDk3iLOi)b%0Yg+UakbppAl7rYe)<182vP~9HL$iVO- z1#+Fo5B}{gp-%!{i28z37YqOX6Rjuf)gaDRfL=oi$-bX`5Gwflo`bfIfOZUFZ_EgQ zioV0(fg;dRNGfUFB93XDp?6;F1zm~(I>8IFfxr)JC`VeS>kZKM5^&|=%F)f!(Je9& z)FS-T?W+L22NrVH^!CsjK`%5QSpl>Y^auZTA6IZ7+zEOi02O~B4r%KIywC%$Nd=8b zg6_HnN2M7cS6RNyOuN18y_go7eQp_c`82knov z?vT(Y;NhHipc^kW_WSsB{)Ap7O1Pgf@C3ndC-~X3@?s2GdzK= zQU7wpnISzfGp`uBDm@gme^3Uz&7srvNvA9N72n{h1DyD(JSlj_ z4RlMr59^B;_Uk}JUg#fKQw!X+3JGLN>kMIi@j`Lk|Nr0#MbNyfuLLL&K)2Jq5Q9k_ ze82!6Z}a^FyAI{|+W-H-6OTIYLN?%qZaFB`as<4X0_ntnj-vpb z=J5rx_62k#D>y-b%nEq%A3V9m5%3}ns`|y*K!|?u3@!L9SMY8ya4T>lL=Nov>{ASo zdo}-nD$M6=KutJT&?yBUAj@VBK4Ji0+XvnJG!16aUugCQACS@Q`USE`>EJ^KW+Z22 zz*L`ys(xVxu^KYL3swz|E^xzE3L*z~F+vLDtN;vWf#OU6bZ72gFez#RxaGL8QQLg3ExMw0AWqo4o>6NLug=q;SHS;l<=< zpbP}rT>JbPO8(IR$wTvx$q8pz&43s`;b39_ojv#C@BjZhLBrMH?DTo{LWkRP7>tj0 zy8hW=&j8vp(+X1YLKEZ$aH0MJ)Q-bA&KrEXTNQZKUMT2>3JK;5kRHuJ(8{8;ZjnGx z{`vCa;VMw>0$+A3!F&*$0U-<4)4E+8nbJC4M8CY)3swUX{QLjEbIMVcfB*l#SP#021DxZ*{U7vG-C6j1?=dhifO9i=Sz-w9m$c4M@I{5F zcOb(Y!@u7}^b2StW+Aw2hIM=(N%ILP5rA6BkPZ{%CaWi))+XpcXh`=8k^-K95*p~( zWJu>6ykyT6to_BB+u&L|oqrAY*;1wh%Oq?fRm-2OMmH-BZA! z81#bwGRP880rCRPl2FJc9hmM~a}%TmyiX3ae)TVCD@Vmj*uVfNy}T@k&X(Y~+d{_r zU~LX)kt`@ZgKwxncb3N`kR8~ZwQmI|34v}UMhmW`;J^g!#eUK4D+0 zd1^SieK|UP|GZ}F4&~_#{nL%C45Aovek(}5vMUd0XCS7M(C#kfnuPp;)`FPZi4HB zZV!%5-#0JbfOufle4t^G7k5CzM*%OEs(|+sce=g+ZKQ^6O9q`^+>BRG*62u4HaUJ?4 ztuv7CMJ9;v`r^0)=sawOZr>Nj9aTU(GrB`x9Cy+Hvp}+-#gq_P(EI=cSXKZoYXV|{ z=e|Mf7F}N)cM-6F3xP+7UL1Gf0ttNcBj5$-j^5@Ypks=m79I+CvD^t_;dapUDk!DD==Pc5 z68IuN6;#l0yygeBz$V- ztPBiz6Nox!BU_6t1H+3#MQA{SkE(&?8EdF>U$ZcPPqcmlS}GOv!lWEzFAtK74++B@ zDAFDJ1eSdaUPOUT6@D!XIw0}|cz>KHq|?&v`=ry+;Dt3vx;ymA@g@aZP}njsypZ?} zI>iB${Q^N}>vV@c;NR|~70~VbfPZ_S4yd#C2efi4usifg(2LXZ|Nb{0Q9uNMlqk#{ z-~ccNo#5d6q1(o2#?&gB=6IixuEgfI%C$L50GT zPM--PFAsn+dFTWF{Z1OK2TF=xO!@WyKPW4_;NKp|6Z9e!=J`^wEGEbiM?8Tq>|vrM z4jCsvM<687zyc383%GWdj0Vt}zUy+(U^@d2wlkehI?c6b;K4TI zCnVTBKt}^Wtm<~s33%ZU4m!e!19W^7)M57oVGeW1m?OZz@S+xG@(ECa^*zz)VbENA z0&cP$)Z}-J44?wL+sPo{MVE^xC_<1TKLT#5N5&6OG^@i*JpwlMNT-KNbL|nhsV~4s z2D7}J0Wp<-yAxjks9XzF33_qoBPe({UVw&eL3^q}hh^~uzW6EtbvS>EA9(!&Xku`? zQ(3@^+XxvGP*%PHD)5)dLIdmo$lTBaoq-z7wFlr1NQXK=9BdRQk3pm91!$NB77w7U zPe=+?#Xu~(8wupw=Un-o%0jU8zU_vGGphUsJzdbN5 z=!Fqnl=Haj9?;JD*X+k#K_>w+fI`VbBdt4hPg>{1YakDZf~+wB5!zt8U~YQxh94Rb zC7u}!zd*4f5cFa?+-MU}y#}hWj=_;`x9gqPpyQrF7Z!B8 zzUXY}0&OSncD)lH*L=jq`pt_qHzCb7P%{ODL%ZMX2w4N#|9wl1AuPOi@0#HM|96UN zW0_<&KG50fvL95{W-;{k8f*uRIO<*nR}`@Ag&Lqa9?ft6|7V1NqJp8fb<0*zi}@In zIw+ICM0+E)fHZG_h`#vo_5c4DpTGY9f4sFM?my&u%P*i~gGCu6<}oxMV(bJnK!-U% zrWHYc>J0tS?fRqnfJi53M2VwYuybln9Oyb45SiBP!I#$A+X4~*3qx98tqmZ7UXY6J zK#tC-9UyKin9I@GTLI#Q{^)jM>1@r3L(GJCyMF2B0UfMRWCrRaPR)q>|Nn&x$jzYh zf?rsHSgs(#0Yq4XrhJ${`@VmafxOOr1sp=4QmnV7Fm!c)=|hlcpvCDgZbyS{0q;8i1v<9jbZ|@ZB&5sx0d$HF zOBZ=lY==ERfdS3QAyUolX%iTtEN+ z|H1%7XoCo~&)@@1nsc(ETO@lp=tD$t>};FYkTH54G{G4k(sl{xr; zsk`fl0Rw~fiNF_%H$f=~+?9nbEe89Yi+_8^2?Nl6)Os^;3j)+js3rn! z%$O5`o+0?RPXy@#%_f2*171vo=>{E}9x8)$+})RM7B2q%zA^_NGIdV?JLh81i%a0C zNgl98pxyr=pd!H+W(K&KC<9qD4DLaI@?iHwkmjInSAl>R#Sx%*7C>|{Knl{jr-Iy) z)(Ljni}@d+<8G*`pvJrqxB(83w9eKUAs~fd3Nj*y8kF5l2Mj=m$$};@&>i#Qmmb(5 z{M#Ygv(TIb3#J!ErqIAW5b#0_!iGBw6k&pColU0<7#Lo>`~W%~PK1HK2z+4!VT02TD1=aAmLGIb zGAR4DPJx!Ty&wj30WgTkzke!-YW~H<-`fM4Qvt0Oo&Zw}Vn7vxnEd;vf+*0rqH&bqeDOzLFTi1dstb@L8`&#L5KTJ z1it8psD9n@GU)&R|1S#OVUz*;1It=3)v0&8ay0LNly%bl`+GsvY+yI2?|t`(Fyye+ zA8DPAJRl+P5sb%tL0g5ur@Qs`g#7>i;_KW0u;%HRU;M{^CM1p|M}1W>bsr5kjyg%eM}i+ya+))jwC86yJ&_)4C% z&fba;$V5HFs!Grq!=PBfyc8XDnI==M7o_a{(H+ug!N0xf0yF4#iv6Gq)4`?o_6|_C z4SbRK7F<|DO3zl19RV+VA!2ErVE*fccx$BnC^Zs4)Lj1UQ$c10y)ZO{CNpR*gjFRx z6S^mYQgP4=`Sajl!RFlUU{43Wcw+!H=_532Lhy20*-l}!F` zK#2t8@gLnTT^4EGU_;Y7J3vA5QsY19bQ7>+(>kYuqg4)c-Z8$Ql>|8f8ZAApdvgE( zfAQ)yXjb~t3#K=ST{_*qkO(e`%tA!&Ll$V{mN?@H)><`4wF-7Ih?&+s;Sw{bAveVr zY+n`FzN3gFT*7m_bw}|3|KKJ)7laM!$@lhx(jsU#0w{$B^|pevgN9f^UIq8;L8k!~ zfJ)5XR!}+(=|4|Nnz}TO&gL{}1Txt;qumsuY6-Qy_u{#bCiDphg?` z1bhDNy&zWvA|>+P5JrojZg7J&0CW=WkH8l`yFvZkm`-rZIg6otDyRh=^x`QzY`D9@ zQZE-fF))D3FVO0(&>zh;Tow%A;B@`Lzuki;@Wmu%L~w$J*TKsWTt7gXg03GxLD&3~ z2^5^6&}&kEbh|WKq;>a%f&wC~vjY^YFSJ3&6~8`;a5cDGcKwmo?ZK1Q>BRz;0F{j3 zx&w5xNVgMDTBjq+i;pk=|9|o3<^TWS(Y3Tr-#0Jry##eP;MsXU6U>R)(CxCmZ(i(r z2~8((LqY9X@Of@8=Dh^nUG54RgGvJ}8Uhtepau)5-4@W@+Y$HwKct*$eF_Rj5lApL z?*#=SLkTSCG8~~nhf(xH=Nf+my}0rm)X(L?Zh*QY0|PitQR}qsjx*q9m&OH9wgc70 z0pNDXR1gIk7DBK1VH(U&gEW9n-Thl4_ylZ9cfXM1&H=B5jZ@C-HBe3bH8Zg)Pi1Xq^WRR(MA5 zo(PF)b%@%=y;Hj8@dk3n|l3`{c`wVV%cN55G0WW+ZW`SJ~Pkw3L;Lu6y1m~(3 zJD)&P1l%$-@6C9E#b->03=9ET{4Z{6K>Y;jwSmnIdT|^kb|4^wft7&))%xyHQdw*-=Ba}{3ruv&B8SvuteXx~a_rQA)NLFeiSqU-`7A9aT|2+bQ33y@1 zkH8lngdyX*0uc9s4$Fh)NRZ+HaA1J#fv1G-iC~w#a08bs;N|NtcBz5=2+Dph{z2Gj zo#2uw3t}+H72r^VbxpwrgOe+g??46zym$-FS>Q#QFA^b!fl~jAr7$)q^+JmL7m47L zeqp5{c0cfMhbYbxcp(Hc;zH1iFc|v)c3*;m8WR5SSncirxiIiWwLG|!2DT2vXZ+j2 z9uLS8c(GU&5iHMP>3C%8@lha}vcY29ESLyH%A|g-v{Mi(p4I*Gi91fLlU>h*!TyWPG&(z*kA(mDfJ zUf6@&_ImS+aM01h;PZujK`ajt;S6#tOE;`{VFGg&f6ICBG|`W4Ck~L)Kr=Ki%znVU zQVP=nY4r02y!iDECKriX`0;}WA4;4-Ta`FK#&oxWhVTPkynxwNs-BU+iBWw8dIY^N zg(=~0aR52T^+$7s0z)a!@m7xzNaA?S2Tqm>-AtWeG4Q1rM?n2R{+6?#NwFl*DZ%Xg z+oys%6)%)w&Mb)scO}6G_?HBOoeVEUSV2<=kdg&nhBqDr2?k~rb{M5jC5iPc)<@dvKM4z z;ER5!kq)TE64XUtL3sTPwFjInSps2>@`ad?#SDwK7t&v$(Z%0#oB=eS^`qNKg@1ns zXk}XK$S&6s{B(4;kJq9x!3k1n`$33xHt7s`-Q1~FK`0S5{sScM7lCQLJ^Y+wm| zaURm02zU_&(|lJ6tQqWdP;G#$`Lz|%AqS3nmY^(#7dh9#p$?k5g!YrIzQ8?L&%(g) zBI@@4|1Uys{|8NX3{Nip$Sj_pP|80VhUYE(E%zo17C2# zC1k)U`~hgGWw!_DFi{iG*xs+3pz$7lP{}kEEbtN}fGCK-zF_I}GC+h0OTY^i$fApY z7q1n-F%BzedAia%8$n40Y!}GA{M$WPKs{FlP{$u+K>)-c@O)q3i`(8H{Tu-=7C{Z# zej(_^F5kmuww#V*vo?$kb{*${s*-}C-85d2=YMC3q~1`EC<4! zX`PKA8Dz6yk}O@_9tMFg?4WHEkYS*#KC#ou;KfeRnY>G`gI0}d{{^=|KnGKUGZRa| zi_;&WzT04kqAcO8L}2?KxY1_lNO(Bc8mk@r(ULqw1q!~z;3;@|GX13J(ERM>;~ z;Mw>09H7x{g%{x<8-uQcW^VbnLq@+}2!DXuQz`~pM*yuQ{=SEbmMDSN)j$TOUOb13 z@*Hp7f;999VuPw2u;Vq-x_dzaX`LP5H3bJj$M}L8C_liCd$AB^3V#cz)Aj-+4_dDP zZ5TAcq)V*8iBbWv2)IS?Q9k%?UIlQ80LjPRnVPJ2n$0}K^Arqv=E}M2#19s`5+6QNTON@5`B?>6;v4F9{l9*4F|345df!1 zSmFis%`h8#kQtC5VmSG9?YdPU~!40tz(bxdiAa0r(bCSOXR|8t@-x z+=;*!mnFa+0QJWBw}Xudcya#8%6OfiPw1tca zTZ|(7fYysa z=lEgcN7uK3qKOCLYJ>%#=y(whw*VTNaNo>@nSB9LRw(dqp9l(JXdeqSW#kg{q8!=$ zA8FlFK@Lmn3~}^%@#hk#oSFbDrxdy;R^)>Qi=7;h#;3cT6uLPAUnG=)hDAWLXw8Rw zK=w5saDfb^bb~Ld`vJaa4q`tfi+2n1Z+GH?MtbvhZKYxRhLl(-53FaAn_T*v_) zV(py@nq3L%Z3WGlfczNv;@t+2{Q@uLIT;wTm?2#Vo`4taub>H)zhy5odVc^me)+-? zoHAKJ85C?jxDg3&|H8V;yElW=3f$44Vn6`Yc!3PY>0E@i!{7~c_<-s|a9V-Xe%o=5 zyhkIM4=;#8^IPCq#usNUfKEsNEgA~yZ3V3-f+c_-pymyzb_#g$Lm5;piGXImOF-*T zesl+_@b7N|x4;jSiludf7b2x~_UeGzUsV?n?JuxECP;vPJ9uSM0RMKdD$uMKXw4F& zpaXjz?l@?^#Ts1T#G?}QLUbc2-ek~Y7VIa?0ccQ>8t}qV1e#PpBa^W3f~P3xBt2GJ zUpxcP4-25W6V_7)YXNl*z)=Sq1bcBw7-}7~m_StqEsMY&fJZGXO_U>92TI6bgTZM6 z)P8|9>Y!bg97nJ%0WXZf838dJ25P>5mVlt@a0q;11=GO@(E%#)QJulR9oz^Fc(Gpy zY&f#F!NZ#%Gha+P_y7NkUJ%i7?*D)A{fwZVAw!8fr~};rV)JhgR13mk_GWx$o1Odr ze*!qbkn#(UA#9;M=%|MV78V8u(6Q`uU`y+e5)eo!tT~d_-H5F8#jUgd|G&6;7F0}n zure@!nxxPc&4y?2Y^}%2!0_V2S#WEwxk7`XBn6!EG@5sv0gYpngud8(7Cd+Y8;>Y~ z=`FE>lw+Vi4g>gf!YLf!*3hLA1=OI}!4K-WbT)xoLoOf(y@&(Z==-C&QiFlNB_FiP z8Pqh=Xx;&~mA@qhR@%V*n$``T2T1Ge)c|F_zh|IB^T_EDG~fry%^(#4FSyRaDs>Pa z9JlZ^2Ajp=-`)z640v((3|_^kCT~Ddj41QqZh_U0?cg#AHnNL#CKEEa6$eoWN}{l# z*B4%JTR_ur2wRX+3S_QB5vCcG-@yZ_K`(gGG~=9fd9n#qEQ3eDVPniMF2D~3hS&@- z6CPF*`N6p*trHw};DCik6RfP@-#!%-ut6`jKop}^4oCq7@_*2azI7m1@Svs}(2^0* zlm-8GaGVFe$bgvz9Z^NK8aChQ1ThOWSHUV1xLGpT%z~#6*us!+YZ2~(m!L=uC5Rs{ z@PPva)sGm_vjnpKT4xieF@;MXC~2bl6`>C#_u>-hWZ<(P z;sl5|3_2qioSLw-1Jt@e)eU621MUu3*nwRD4gEZ64-P05I^L=h^8bGWXcLO^2~aab12u}fn>x%G z7y>fDDgsY{%dSqa9#D&?_f0T#oz{ck|NmcHJpTXxi!;YT2W4k5bhm;QZ@}8fpoKRA zkcBrgpyf2E4u#g;kS1~9i<^@`jYJhxm%#cdS^O_fa)Z4Cnm~h0ploji8~P#vA%UhD zeW~p?$b<;0Dp>siir^P4ptFs)_ks)twXML8f8h_a-~iefG5`LlAeE3Mmc5{Bbwj|p z5L6`J2nNj|P6bh*^ALA)fnA^0*?J}T|Nkr-m+ln1ebN-ekw>`V3xp(Wt?D-fUSH5V}ndV zi-2#D zfTwl$LKJ|TC@&I^K(bl}gAoHm_f$}R3(A7;F7KVf`y&{1I6Y|hFXY^77Elh{0a}d@ z;cI*W9f1LA_$maxNbU#cx~vZwpw<1m9xyY2j-%-9VFfMh58MUT1wPUqw2VLSg~}0- z4+OfWf(nozXl{RT?=HNg0$rn$0a_vpt^-~iVMhcGXiove1uM>hTnJvaeS!fz%D@Hb zH#EKkZQ~4l!MhM-4bQF;(Ave$sh|P}YAC40&4(EZZjpc_gI+{K#L_xj!G)3y=%`@O zdBGE2JA%dzyTPRwa=8Rj7S!7c(jBl9>@@J@9XCLCJAoUi3PCU2`XGVB0Ny^a1GH@d z;sMakiJ%=|UEn<(pnVcSFWMQviR;DvLnv+91-Id$qY9eT0<}dIFx$2KE$pCGviy)^ z9YFyP*%JZ|cyPLg*DT!=Ux3$DOaspkgC;E*G92U?V5M&sBg}M^)BrIKlo}xM3b}y* zlo~+2^zJ}~pckRN5D$NZI06(y@S3r^31n%&PO!_sx3|3b1X_hI2rg6wz-b?@7*?o) z8|CW{{{Ih6U^_tx46;WCl)!?($r9o)us>fMJ_w3=0dNVQ1z8yhHx$;d^Irf`!voGn z@cI-sC<<a7yd!JrVr>|7%W=y;DI<@SG)h92~U#bpz5EG>8ovg9Z(~_fGKz?Enjc&a{H2 z7X?9kVEMQAf|S9RSb}l_|Mpgp!Ju0tw)cWo#Rm3H1+9t=>TLxrhXt=A038hsS`-`9 z+X`9~8_?SeS`-`DI~BAjHmJ81v?vxd1OXa)fQ;LW-1u^_AXb%-s%~8-ktiax>ppXX(p+*oW%6fZT zK^wxr)}yStM->6B+6RmDwuFj+d5~3<3;|N3Jk1FhEwv@^9}2 zg;QV_|BE;#NU6O)^g~)_OXvOp@THsFcZM5RA9p|U#~#DP-4TsJyZd$d)4jX z64*O+0%)xgxX})tf$Me>fKR}^_{zu+x)1Wj-QA!`H~2vBJeaZkEuhJ~Ztzx5e(>IM z{+4+l4?vSd7XOP!{|!K^d_Yao-l^b-f~;ZS3j~d(zj)lo16rr^qIx%aGl_q{M^@{} zQn4)1fr+3I*Ps_}Fi(QKVHc?T(HbbEkKl!HzSszJPiYo`Qk9v*a! z`HNS({{MgR6hu4#5w}6aH4t%e7pTPl0bU6MYIJb~zPJYukJc{GWG8rE3}|yUG;-!$ zhDJka9?}wy2$*Pz7XNnec2~6cfsf|L!Bm#&fr<=pDxAQ-JunPhnm`s3@o#sE33y=w zQweE(fQpdTlO<9}+c_Rxg1Uvj2E5RP zj8cLt7jS#83q1Y*!W4XIra)R}>k&|Q2{c~}8l(kHK7-6gbuJ64_J}}`RiV&1BmV6Z zK~@F5I3x%zIl%QB*i-W{Nz;NK2W_u||IXiz{V(VJ4~|Nlca-a}ViNW((E#0^wUKpo-=H{75bzHJ1& z20;5T$PXOY<5-U$dRhs%%ECC)^9|_uMK{o58d1>3c~I4htIU4_b3myCJWfF=7+mJ_ zgL8Kl6DTG@>l9v0I}Z)Fk`ho(gXe?{)JznHnXg%FK{;)E=m(@M(e2~{ib80?0@*FJ z#nb|nw86O^l(r_Obvik{(Ax$Y$d_D%)0(?I41 zyf~}|nj`~lQdI~9Pd#KGV&LE2!wPD2fvR@!6dPz$FSu2>9Xw?g*gF+8djU28bQ|_| z$f7QIa-Ba1lonKwtDO={Xy*c+mAX3^%s?}|6Kgma7=p4GvOsHO`S*M9Kyr&oz>6Ej zAg4)yhQP4xUI!htW__?W;l+b3|NpdSSH@RA_O$?f@r6)JzSkm|sM~!nQ;UH7dKEz)e4tto~v) zKlossK* z0Xj7j><@I8x&*wK2n&=FM{t&c_wXRAC&6N%q7$6Wplc#C0z{x|8o@L2e(S-j17F*M zjfZ!ep^CwR@TMDd0VU{IBhUnVw_wl+--!p3?M;GSxE6v8 zmq56bqq~I*bPNaROtD^2)V?s<^#A`0Ul8E|BAh{l9f+_55hfr)f7Ac}pvEP%)$`#L zH0DdiK!0WPJ~$uaSpVy@rH?(1mLpP17}4l}5g!xHe~aVKcZi6aQQ zdJ;6Y#1io0EKKx8FqkC}6!3zx1FSOOMZkAZ3!5dav-JRI_}Fj*B=(`c`g8)DukOG^ zOJe!AyMk7i^nx@8zA*j*G7L1}4dR2As8l&H)LI}W*Bt_1@Pk+Xas<4%_6?+%1vK8v zza4CQz>7tnL1HiiK!t1X9?%$wP+Ip?5CeLv6Nt&bzZFC^|6r=M&Jq9*Sn}@&tIoU# z8kOp85d{q*fx06gb(t4IgH63HqTs&pi%js)yuj<_{M#XJN5nIz(GMQ#gbaxZd$4eNyf4xL9mDh5HOq*9J6L_d3v0+xte|eti+XTplm*;A zbYcm3k^dVUWN@276}BK~iDek*oMVt7t_lG!e)@xw2xO0tEz|_mq7Qt|loBq(IM@CE z|3U;r@Pi1hb^re(6$ht}L6Zr8O9N=ssnqcg7N@p6zC1;NW1Qdpdm$Y375t2;z6_kL-UaeNK-kBp}QBf%{uUf zB`k*F8?L`YS5km_vEU;spRES1SOFdQ1l>l?_u}wsNHT$zhD(k>lR}9Qs9Ng<9pD5y z{c_Ff|Nkc-^)hQ<>iAoDA)P76;tkM2+~9&5v3TPx==_b7X`R^GVBiykK>HiOvk%}_ zFsPX@0lH!W6ql%bu3kLug2ytb=>=+%gU?;AG#L7Ue|rmf>r}vt74INv5Za>#uNenVLe_)M z6Mm@xI#st5)Qv-QAVLpAgOk5yHK;R=dAtyGx(!}7fV?jNUvB`uIr0`ej9Ax4l~39G_j$Gy0N@A&3<30lL1v`?XR3n&KhE$5vK z_8Ydfwy-#2>4GkAd!YpJ6C$o*EYML-jmUn{fcXWcf@cEy6g{%>poxOO7tP@NvUy&H z{73G`Lyx`4$znwK95mc!!M~j;;Klhj;D|*8?2qmcL5s9bCh+Nuh??X_w+ojA|8|bR z7kgKL=UyR(feN=D-9B6vpp$=#SN#9~A`f)@FRmgEbozqR-y0L^HE)W27AVF1m2 zgV^`fTo^!8yC5}Z)La-qv%Mhp9yJ$+{L+$mL$mDo)V!4V%)Ashzqll^s01Nmlx=~k z1SEi}2H6CJOj1!|Noss?X;DE=X)!}#d`?=tD??#?S`ql-MUV*iw#C%E)S~pv)Z%!b zAcnM}{JfI*P_@aq`CcPoP20vBN@OH7Fe`8+NAU>@kzK{XRVsHeDJAx#OQgd8EG{`F;IxVdP z=&;b^ zu75xjXs)Ck?%pur>-@H`3Fc+^Wzntw6X zYC<)4hct?GhW==-{lQQo+zmQH_28#J|C^7n9CrnsY0L2X5U8b4sQ~guC>l~UZRUj(5om2u|ygLT*s4oZnOmvRsDh-edSB~Zb8UZiA@m zJMJ<8ascu%(6QVv{u~ASxcLZ&^_v&@&5&vrln9_0NBRJrdjBVjy*u;||8^&VfETPg z;q6HS(1tEwp6)=F&d?t(cozKs|3Vx@2!RM*5W%qkG*AG#v2%L|Xd89li(@W1}0M?p21Mg$k6Tk2Q;#_6=q+lDQN5NAO7tgQh_h(VT$=%R)NMn7``wv zbcg=wW(s)G0@J|X(hrsboy7}sr9)7+D-UQG`o+c9;MP{aixV(oN)*7WD!}^)JC>+I z?k1dgh@XMsh01(T->ninf%1T6i$O!hFAi9N28sk;D`qifF=R2qo3XAu-97>$;B`WCAxa?0??VGd@&lDm z^teBQwEG}5K=(o1*vW-_9|UM5nju33bV&D&L*P8s=?X5LUI~F`1dmBedvRV8up4|s~m4Ew*!0ymHK`+`M9jQ*&JKdl=2d0BV0(7O?7hE+N=;B4| zgS8&Lp-(`g9bZ86SAPOu^y-0Q0Bo%wsB>KCX}!4&8` za*YoR3@ZEmZq;>Yb;Rl@`{`>#`ECr49XjjL=RdF2URG-zaOkf`(U@PK)1-mUY4eS7n91s z146Io_JTbCS`rl0?aILl%F3Wp7qp&A0+hBugW$d*fxT0I@PpUW3Ix0;;|86ds=~kD zSEKc0i4yZvj@}k7a1`)w?*%CV%>{$(2ztS|9F(_3Uj7DMo#D!n*6k~i*4e=TD$&b+ z{{KG#l4tLjxG=nURtd?okb9Fdsz5^*pj2)B=7n|@Bm?uygO-XhJTY-$00lS02L=Wv zQx^tM)PVBy9}^db!1(;q5{8t-l0*;#)a-}eUs(XEUncAXHMOBvnH_h10xAbz`~}@4 z?8*UZet|9>>SpS6eenWxKSQ_g1IYaSi+~p=Hb5(9{+8Dqpqqm@x+j8$$~r^ufKtBe zg%`^}#`r=HE$Iw>^J3`_&@zb^%%H0c0$!-Y3@8x=HFO(6jWjmUnK*SnK&>9(?of{7 zO&~$An=(Oypd0GDJ<>pu_~J1nA1tZr2C=+dX6g zyF*_Dy+}U^O2nZ1o6zNnVzJr!Vadd;v!b$6P0u}8iUK{}3$8Z}W#lJl;1C%AM1ia{62MwN5IZ(QV%r$ho zz6p5IzaA>X-vV0r4BD9EdnNFN$4yXT1n=?(3AtVgcwq_?IuZEdCgMzUkkdfdM@R*| z5QeBo>vTN;ZY1(=_s9r*@%ILjQQ#IZNc1^E^hGz!v;*J)cF+cIsel(pAu7_q_h0!Q z0F@nof?oVz19z_=Xt3LrquZmP({~Rjew+$Gkpn8+4?bWDc;T`OT#9$P&H(v2bVg@j zL38a4_zfGN`zt^cYl#Z@PKy|b45lFe{dxU>~=n?+?t_Q3y)T;CEhwwq3btvdA z-P6s}*9jg1J<{#E=Qs;!AtA%-gIEptV|}4EFiYaa)}2u2OaYk&szsa%x6iT;Xwu3Ck-*BGjtEQPYVqy-#_4njwHmOPS*(_cezgJbSh}Bod9># ztFI78O@`f61P-duBai|U985<*^`!MdP*6emAnQEAK_xP+Q>2l9zw421-#y1!8bNUc z2`UT&4p<+oRR)E7x9gs6(3YUU9pEs73czwt04-813wR+5kq2G0+v!;L!Vct=mzP2F+HBx^ zRJ#!HC~Xq0USxDqW@0ND*G>G`+&eh7SV?Go5%&<%kvr$TkZj~?3zH=`EpI$sX( zF(6U_FXltEfx0~}lCOY`0QFQL^-Njdi+YGWsDkcvDtocu11M}b(z-p$(mH*=yqEyu zhjOHKJEehae$fEp!%c^{%m!ivNWM382`F9hZ}&)pRO1Zbliheg>*Qa2c>uDWrPFl| z|90OcpuGS=5S?f*SxL0WVB0g8TdJ4D)hW&c(Db@#T<@vXV3P3u^KOlEIF#GZZzW4$@ zJB8=turDf)+;?h8I@3;9LOds_e~GV`x5-WBukub1o!1 zK<_B;afIXt(A?z=M;FK)<&Z83C=0+bIDhbj9e4c#5<;Cf0A&QwtwItImw<{PkWi>Z z&dOD9W=xVxpMwR?k%wL0Puyve_;6!baE@?hHzh~{EID+ z!am@IHADo|!ULOCDgbK!vP^uD1iEM9Wf-W^(FNVo%Lv|j_#zr&Kji-1xaK1~)^A?0 z=Rm?9avv={#y3g5AJ^KIrykTF>m=enUCjG(9m0ES4}jM?LA$Tu8nn~*$8lHCdLf1v zpyO^qjcafd71XEM@5|GAvQ#z8!0S@Kk!EPRPcBv%gbO;qx({~>z}mF z0EZX*K|OWQ@;Z*r&tuVzxJUO&w^_5l5%*nHSNp>#6U& zZ~$4z2&r8&0$(sLfK^6<;6`v-XXu?5GN6Ih*J)WyaAmjVBb0G6fX>Vbz4PMhUr?LH z9<)gZbY@^i;ET;j%D7?5&ViLl7#}DV$tup+adS39hQY1b3@^TUfgQ=eJ@f%+F;+K6 z;ET=GpmG^h13dxl*34ptN}dULkx>bf5=rZHy}`fT_W@{yaZtDGpMV$lr9f9j@^reM z09`5xYG>-QF@XBuFI@hDTAsdl0=q-Or<_~?h3XSfo$w+k zi>24~L%@rTUqQ`jnNHUepu0>?1imnU2M|ZM>xq}`paw8#c7}g{hYt?}L-s|n#zQB9 zXEAiUe&`Gk;ot5HS~CA3sN3~IK)3IoW>6D7_6o>M0f?EQCxTwwfd>=VOklk0-pQ&(=FHxy8Ewbi7Nxc3#mWgka`mMBH#yjBCb31Pg7`egC9&Iy$}B`wO(G6H*?yyjTz7odk!km)nblzd+#&%GKbl z24BIw3Q$Y(PxAqbfEP@GpxA)MrSFNr7Zc~g+yV|%P}4jEe9`e4vV;0w-Q z|Np;W0Xfzeq!qN77St$#^hH2pN1$U|v_QF(f4h?o_+lWAK!_;;FKU*9X3P~JDH7z1 z)9?^w?RGu!TJ^O^cj%wvPBx&ChHlqC#~r}4zaR@j|8!2=0}2$^6OiV@3Qre?7u>1f z=0fuk2kSR4;!+_M6{O9)!PAA|1N08~J)SNMX-VII`Ir;(A;muEzp8#P`SC!6ghzKWHp z`G7#c3;l1PBn5F)bCm(e!4NkY1ihHN44jC-H6b*k^6w87X}wgc0TydM$P@U&uM1SZ zut43D0M&vzt8ywC5+|Vc7j(Rs2WxZexa${Cq`z1R8UY2lqto{f=o;SrP9?1e>L5qK zg7?30bo&TYfU7LfW)>etfll8auNC0}z8u|C7(wgaz|+Z~<(?s2prsct5HdTp)Ot8+iJ-Q3gDH z4C)*H;olx869lS6L0fAAU!*~#UZ+5Ikbo+YfEN#Ez>G5jXG8w&fpSQCj39cln84jl z(EbL6fETh5!PnB*Y+-;%B0ORbcQ91_{y?ebSBycRQduJ4#RX}wgZa1n3V`w_(&BTT zZWb<3LD@YKl;MJ2h$Vm$ia@997m(I30WU=1CUbPVet8MHh`!tR5C8r^xzev7OCv>}hfwXtU6X8h~H2=3Gj*;QT=0wQ+U(CXP|97qo$2$MV(GB)U zXRphae~=+f&un<9MsjmVc0|g?EC+7ejfvoj5vMBewqg|6&D5 zz?TPfg>VdrKLf;X1)J%?0-Z!?HQDm-|BF1(?Ys=Vy)!oa`ybdlb;*W*|AVrOy1~W- zyl7Yg8gCZq?gfblz6d-5>N|kus7ki}gPab}zuhS#06gB=3_gw^VC%pCpam9!pyU2P zoPZanH-KUcv`r;s>%af}`+GrDcPI~NJC^l{I`NG2ObiSe3b$u7WX!ldo8g7DBczC$ z3U;p(OE*VacOY9@=hQVD{{4Tk7c^W5nyUg$z4ZEke7EW|=&VLoaFcOr&DMYaUkjym zw}Kdu;R7&}e}6AXgnvKS80%BDX8hY*LEZpO-GOAfLnS~{cW`wgz7N1HGYRle^tMP) zNbtN~);l$0>%adX-+?tFmUu{X^9TfXLmkZ%@M23HsALm>m{r^9Ke}6A1#+rW`)QM-j z2L;&+P>?0una%Lxg*_z55K+v(-$|hL0DtRxP=69M)d}(Ct3E>GF{{7E91X}OY+rxSQ zl!{PZcwfeV?m@Yf)(LhR z$hlz0;fqEUs0T7nfEE>lPVE6FGO)hRDXm99$zextZ_Czypp&RVWrDgPfyB{xaFr`~ zXYf=|LqE5xP^W?R z&LHf6VZ9HOi@=i)pgw#r$ojw+TVbLXKvT@1*y`>9J1Ou*RUW96<$2w*3v$ZN)E-bg zfbP4U02+h>dllp`unQqWQD7$jey~&d_qT#_4rt8i8F!L^tRdGF>bhZ@ve&yVE*bK^k9v0`*c^ zVESKhL#{hW>uj~y0`el53V1Ok4&(w*Vb-zX-+yon+iZc99aBLJXbgjx{QFx$R5K`# zw1O5h5s{(z_xFNB{a|e}|8{VU!OINffa?l)F*^qwy|7?_2U$001fB<$UOhl(bAW@e zWg;ls1iVOw=zCcS8a>HPRr zP&!uthXTkFP;vrCIW!bNVzAT<_gFQ|V=r#(1tn?dLDP@~4NZLAuF&!`8|q0&P`p@% z&_Q&XDT0{sG7;=yaH2-?ASf9l0xR%^38do;8chcK1mq=fy2VqP@b@kR=Mb4Acvn>ICcVoB|GOXk7E}p9(gsr5BWeFmu%Q zR#5bTMigWMUr6l&g(e5o0?;u+pwi>TVemL8XnN;mkwa^a8ykjd^>=sB2GW(hl)ZGfIIs;x@ z6#`YKpjJcz$mNLi4$AVNxf7Xy7ZZ0t0&e?>z!z5`?6l6-mJR>@@A_X48h4u7u;JhT z9T0YF4X6~&d;S0ai%gJ(q^12zSn&eQ72Q4H=nj0*8wDy>z)L6ix3_}q3wUAq8dg4m z`25>Zb4Uv~Zw9;whUo;K%?EN_(2M`CU^+qkm&uTn4`PE-KFGAd7q{VRDnJDpNwsGH zXxHq9fB!+If$Je?#CAjKgMb(R(xLgb7i2i7d;uwg7s@@Yp!6L0;yOgx>mL5?Q$gVk zDu6&50$%*x296VGJirP${_Rsi(Fj?IEC4bV6!RcmAmc%<0hxkUY=P_MP=TOsaB~>a zy8x~733{<37BqEi&IpyF`%Udh{?ad7esYW1?dMhj|4!Y@u1Tfc7fJ6fqI<1U=sw>x?Px<(mGqg+Mc`sEl>s3EILs8r-B&J0vN>P z-`@(MdO;ej57t_s8whn_=1I_mGP4hp0RMilA;(=Nf(Hy<^n)yUz2v1lBq4zU8MONq z)NBLYPzr6?f*c;u+Y4%YqD2AdBx*=YYAUD|AJh%*ra_k>fd>k}{TFbz>_re4C{|3+ zV@0|f79g-#S;+x9J_KA}f|3HrRiL{7w*LDc@M5k%C_nM^_J(Zv_a9MZfd+hqPJ=2f zj^3#tDR|m}w)J|!r4Xz_;AlK}1k~DtR<2Cl9S4xOpq=4Q!8M=^a%HsNL!k9!DbMj% zP>&5%K)vRIut9?i-BUrLol^@o{QLi!zq=JgHy>c^1T#=gVX^E5$<{`6gH?mJv4RS8 zXlbvr1)M=Zv&66-NjF%1_Y`n79rU6q1)K*VcBFOt%A|GnxPnZ0vEdnL5WNZND^OR7 ze}A9=XwcA%g@FOox@_G7%H1!*JD_3C-!cI-(!0GEBn}HsCjRXmek=?OfiL0_>aKzY zuC`AFwbc>*`YF7ivOQ=AsJ)*JKED&xKg<<>SB?{+r>RgN>!| z?+2UN-2yfW)cQw^yGV44Fb2KwLN%X|@e=PV2inHNEB=xq@NIUwML7)%ee zV*+hFzBsoD>HyGW7+9`%3fMe&%HZEW(T9bB0oG7C>kanFi&D@Hx&=@F|Az)H$X-ww zwVo^u0R`+-PyhzK_}2yv*b+O?u69U|GK&G~X1LFKSV7?i+O-bKV$d##2TS0Kypy0b zEb}@wi?JKhcSJ(^Kv4nd4nTT zp|0Y91_)}W?!{IwaJcY8HN%qXi`Z}LEdz$7 zKyXi=E8xW=Pq3H3!|-XH;HD6$Ed_2ZLW^Bcg9cW^qxA1stPk<`f-dERh8k#C1*XtT zB&}P-F|BiI%EEvDU+_Ez&4z&80v~FC=4_Y-Xh)BKKUfD^z~{t(Tq%GN@L$$Ly?g@H z4Tm}ulv}$Y4KR?8p%y@g4iGI_kV8O@1BXOczzYtD9WVcbrWe8fY_2q5DACP=_oCq4 zW5gJT0eDUKiyX+z(rf1zPLE(qYNvwQY(Xy=TVa_)4U}bCq2oc#Fi`=>Y94{W7wX`{ zrFlTA!0p1I7fWHP_**PM(=^~-JO6$UJvm0?3RPGai6W z11bZp1OvxrH#p~kW*kq5H68@bICl1WfQJ9_K?=bRuK*2{fX2;03}~YV#N^-K3!$ch z#@av)9?%j_*rZol;0v2ZSaj<1BU}p7(+$bypo3gMqk_;>{vz8Al%RQDo1-fSJBfe4 zh$FNt=HEXRY)lKdDi3&J1kw01{6BOb14tIy=>ajJ>OsrvbYSHZXbCOY1Km?Sz`cJK zFQ~I#Om>I3V;eLJbEI{H3)!^JiJ*f1MezOq{}+OXTwgFQ2GNiYFFP8E2sukP?YTBiBhCX?bco$R-@PG!@T%WuM2Jv7k34B2d_c=iO zDrF);Q@WtF1TXlv`@R4*bwNu|!PCWoFXUk6^0$EY$APwdFr{_-zJSdq|GV@5{|m{x zppA(fpvAr5dBC6->}k<@wzWG4@(+tRVjm4Tu4WQou&9>|!v z4oE@D9q)hbN#pP2Vrs7Y&#X@$dKj zk$q98w@363XhFvQ&@Y{!!3ozNnJ2)?r|?>w11Wd?l6}H}`66gZS@sE?-WFZ~(5i&} zzF#^;IzX}F#M14-k=8Ak)*1TdHBVZ%>l;X+=lTY;|F8KcPpvO#wNv&Xo!%Z+m{p)- zYrAaJ&t&Df9FNnhc+eX=a8#D&M^0Ju|)JqDL2+EQN`KlYDIPgWa6Sy1$ zEsq45?E^C#lrO*vdqJ$up4Js$vq2oV+4@kk)iKNlDGq!g4>9|t4roXfw7v^;h9ziy zJt$G^Zvro3fmJDxoWKfd;DPGUZo$Swpb_?o}Pg2X_5Ij9nl{Q)oTpeO-} zft0*n@FMx<|No!{N~l55i}EUHe&ufgP0)eX8o3$-yqJIxUJG8N*X?V+f^js zh4W8vJiU+xn*)`3u@|PL#2$1yE69{pa3LL#eZB@@FN698ps)>m@oOoxZ2($kA`At2TwO(JB16hn^KT}zZaAB!P*kgW-HvfKbe1aC)-UZF!fVvMHAXjH!1qFudo8v95I%ocaK>dq!(7n0Pjv?;Cg}=9! zk%8fOE5jLRE5qO_XmM6r=Ts4p!9rL6|K9;>o@IkaNgM5UwrOO5G!%Nl zT7vK^2Tg#1N_0?#HiZ{t9*75ufo_o|(B$GcAkL1Ecq8R7J`fc4`RbIAjl@Ly<8xDARg3S{_QMY z0a@}dQeb*c1ipxXu|X>(TS0*l@Z!q?u$gI{V192eDC|L_eIOdNS@%tM4>rJUWMmh;yaehTjpDYE!E2tR= z$*15d9zNg-atU;_HH)!#DyWTLxTKmonIpyDg=g;hH!f*ru-@b8DVPWfAUK_l~^ zRV^&wnNZN}8v^{>JwWRMO+bwYP?-_P(s&3|yMXNk)g7Sf1=L&s-`gPpad>yA2t=Nv z8>AkTeuH{jLCp-Xg9ACbnOH%Bu+~O*C}^7-4`_(_|3^^Q9$LFVDiUb_uMpJ#vq9N=SwOD9pA(N5<}(}#)Cv)su&<#kOHtum^jF2 zkUEeAhz;%Tf%YE9BJLIJdpjxu7A3p!Zd-_ zb0XB&6Qdq|KS1Lf9cBiG@ZP;w{`~*H6SPqWx+`Fz!|gc?#z#9{|71yIF~9f-E{wp7 zAbNXm{QLhu@Ws3Rpqh*WEPV+keIY1|p|=&Z_&(r8uNg=IPnJY)?~T789eW@;z$Yev zlq~=?kY1!Alv#k4O+{1209IxXQ3h&5_x|_;8CIDJVnAw6Fq40OD@cTYyRQhS@>BxP zAAk;6*bWvCc%cP#=l&Djp*+1TU7f8@z<;j7 zD~JKL4#ec&-wL681*{L&mhtbO3gY&*go0fRI>X@4|No#$>hml}!MPp0Vg{tByBB0J zq?Uvjvc1O@qzyDe3RciE6%-l)FU-Lg?}1LS010=t^n!$6ECg*f0Pms%4~cz&21qN2 z0qGrrnf&{EK_bmRnfZJ9K@GnBQ$c)aIDvZf;O$kNtuH|L`+#QjK$Z~nD}V1^aL*TN zn5zK)`V0K~dqH}cFZNCe1;syT;uRDb-M%vX+eI9MvgBX9nF$RB@C*k?b@x<|#h~^8 z)TR9ULk0NPpMr)g^9la#J-#5*K*0iWIjUvdQ>KDaW6%o$@MV3VV1g)v8Uv0I=2M+5 z;6(c(>kp_lmizzz|I72BU0OR~s}n$)K;8xi7j&QwB*qU3u;yRP{Jn*s00gb}etYLYfw*~ADNI-%YneuN3hfdIoZ4gB>dV5?!KI!ZQ-=zd<(}6+&WGOfSKw}Lg z1`SG3Sb$pUpq0YV0O{@phnGkrD0D$e5dtsH9fgE0Bpx6k3);9=2HF=O586Zpwx=6x zKP*ZjXFxP3Y$qfh>LEQ{mQwGuo zibAlHTc(1FgMb&Y?4ZgN6lEY`P!#?B|Nq7DU!W*@4vL*zaH|QVxD%XCK*KR$_q><{ zQUuPMpdP-?2jxxv-Uv|K?FTFBZ3zWA2Q;w&QV0nsP!fD`=K?q| zI$PiT`TxJS7v%FmP`H7$b;B~G+kCL9fbL$9vcMN@;Jvbt(~f3=`@1X<6JSn2%Gn?b zL6fRr2fVm54Qvv)owa=`$hx2x6%a94z;6fp7jD-o@LD7ei22=9K@JFl?4fjkxC$Zz zwHY*g3|7-A()c3(=l}m;rQKlf1-$UfhIMq5n)iZCVyG48-w!PbC62RzE-hksVF5Z_ z<+V7%#N#ZD;7yzIAc>dF|Nj36ul4J8RY~gWs0|R>{ig8^Xe>3ncdx+z|NnP_Hg;gtr#tMy zLz%7*UYz+3T}R>j0yM4{`T~-ELtpUk2km?Fl>t>^OF@;`ez2GX^99h+Ck)vKL8l|8 zb&CY1b%wBhdC~G6+%0?oIs}OMAov(2&~+HT9BJJyj!bEtE}~z+`vLg(`@ZN76@f)< zEL5BEN#jeMJx4|U|Nq}P<*3B}|NmbEp-R<&q(Y81ys!ef7;?PX35K-p5Z*7K(P)t4 zU7tV-FxMyi`+c9l+`zxzMf8jH3I5)h3=9lA4}k6+y~w~E3K|-C(#_KpxC<Xn>}aID!IRn5lwT0zm=%`$J!J zw_F8zAfUVFD#$;9FF3&JK&HRwY&i=O>zr~Hq~t~3H&8+21R3kZ&*p~Hn^tseUo_+ z6fj6(2kLQU9s&y@LJ!o_%RB)VM1&ux!v@oi2*EzEe?TGlMH%cfXb7Ts`lK3I3fgFDgiGvV8SI;p!xuJPO6Op zM=4tR0E?mcI6NI>k3j2z5_OOyC@Vq}Q}+~b+Uo29JH8W?AGE*@?E_Uzu3)eGzJN3y zd_mp@VDlG8d}AH3c{z`R)S z&QOr+x>1~7BMUMVBQ#q<=c9n~28!bQ;7AAUrhd`wD*`$V&lj{g;dM7?fFbk&X2xBH>&3qddBVd4isLn?w0Ubn9SXmiSE&@KQ-Es)dT!tf$k52+TorU$A8 zK*gl>n-??nAho~*W(Ed^k_H!sFVH<~`x;yrKxqV2zOQOWAM6Wy41T^<;0P3@YhJyt_eRj|yzrYuso}h(f65XMoli**x z1|2a1HVT|~bGfUAy!4;lEkhwy$0dJ*3Tj>{PVFH8+U{WKOxTAT`UY0!&8(BUiK zZ89MKOMg%)xxE#{4gjr$0QImy9UCc#A)w~pi+M2ifq)mAdclT+jC}D8#=ZdR1H6Fn z(mKIGoYoDYI$Ocvy!!+G3K1MYs^Cq};0lq<01El=|NjgB51>lZ_l5B#;{%|Aywl}u z%Zn&vK}bE(*>Y9}R3+Mj+y)NA?28O(-7cbE(mGwAfT}*HOOv;YwuX_E`~>kwHcCO-T@o2U;|@Tm?A=R3(9Gu)r7EV0Ey{4J6h% z1?*Z(`vgF4L#<5VweX8(usI<6GV$8CTLI)6EcU%neEX?NNB^QUg$33cB|Y9M0LKwL&1LBld!l zG3cPiH?ZmxRAho1A6To;7b#$;f`Z3O0u%t?=G-J0PTp_mvc845o2zrqNu@zKXbwYjd!UJUR>pd?5KnJscs$z|x z7hB>$RU}920sfZF;JHKo?VxFrxd`Do(7jwZs$&)FgS9pM+oys`SZRiX++VZ024JeRuKpVF}C)R)qVT=k}1vIh02GZz4wo)EqWm;z|2e>fo1yP_> zgd9J=M4|Eaq5-@=64h~dMdy0Qss6gwb5>?QO4hG1H+e|M4 zUj6^S3sTZdH2`V0e+8OxRt8Ud!4zqO6oFPDftK2X6iI;;fwzQ%&uRl56Lvr*;Kk!r zpc)i(CJSf*iWBJ4RgUI^K7lW)RzoB}TjRl(;r33=S@r*a(2I>w9iSyXV553leOCSd zAMnBhq65_Sz&4xL{6nBtF#}wsfY+UXt`g~O5mgBQ>E(gweSIo}gAsJ^<{xj+sH+>q zDu~$BEAAlcjgZA!*EoZ8%OQ*PPH_b3-GwYRHOCgD_uERapCIP7hFF92PJ*bz7B9W|Nqw=ps~=fy(?hPn zYI4wNaNRDBb!nX~q86YiHh%%O?+UC73qCxx#{+c#Sz2cgM2+wZ& z1okVa-L^jze7vd;2S>Na#Gn^>P=)X$1WvjaAAmdz+Vbtf#L>;u5%|IlqAmk8vXaHn zJC(%}6pI^tK!;617Lb9Lr1<`TwqkyOVyXETb8S)<4`@vpD2lRAB=k<<)v*HUbW;F% zQUKJfb;Yta3bdwC4WtvH4`d_%e$X-}3FeDIFG}S=2JpN-`nr>Uf9MtC1E4tQbO{uB zu^Y5W037hyhZxejdssm+lGcf>76Hc}I8>(af>ePPIm-xv7RPfmSFkYfx3q&6-h$fN zVBcXZxB;a{PyX$pHlUWg3aEbh(H+t|A?U?+V{j49zunaa)THl*t{4FwcLQ1m$G_kA z2YhR2H$?60`Jj^mKr2GP*&lj{5%^4>-d0e`4Cw6zCF8)}&>Ky~JiZlBf(fiE~9P5}Gl#qSoVGRXO~_?&*h z2<*+*?V!Z!!Gi2?WLM6d4RWOb0ar?b;+lWI?}P4;)(O3!?T5ZUI$e4vygvVO8K@-y zYKY+WV=4c3*9YJjfah^gNdOjs*60uT*IxiHwe9EyCH>1%;1qXYf_f#{nJ z(f6|W|NsAK-L49tjpCq6#retq{}Z5VD0=@`{Qv*L5WJ8tRHyY)2|p;Mw}M5bLF&4F zEdoJ3Ku}Es77pn4)c{T8-T}ug2WS-)s1cHR0$eyx;RO}Wpcs1rFX(jgAT0n;jRxvH zUv2=!8waSn)H@aAhoIh8a1em5NjaDj_`(U?9W&{jdS^9~&feZXt3juqZx2PXy0;Z% zKtOLV$NwC)ZNH?7n6$%`hCA-EE0^H1j5dVWwKL6hkdQ1RH(1R8UI ztSY(0z#P)?2NXv?vQHSmyz?SQ0+!6~fD={bMNpHe+m)lYM_>-57y6|66=U`x3FZ^9 zQj7USAT(@Wx-M*jW2clg&I1UaH>4i5tZWc!0FTJm`DP8@7IDD}C5 zGY@JB&A;FEj`f9FZ%}JJ^CCE@LD~VJ5{iGjhzF>*T~!ATJkXGA^GndNig&=1YoR}w zPk{rp#cKf%1H%hv@UDWnumtLj(2lE(y?(!XXBPhts-w7}Gj? ze}MG-hON=Zwy+jF2?^SV0*)te&Efh5T1$Tc9V!Su|E38P@t_goMW815cHcXJpy~)z zdw?p*DHB1F2CgU1gDX^Uo&im@S%9jh*AJkBXssYGfI|-Zv6P^Yvj+tfmMHxKj!)2C zd;Hs30zqp>Kz<8+(FZpi#DBf=rOp5U|6hVm%Y)g^zr7VC74Twn4LI1-I>CHgt)k{1 z&{#NP`#=88mbg+ts58p45Qk1wE< z3CSLyQ0Qjq0G})Jt{vSXdf{6Q@!)pQ^fc(`RgUf^Q2qqBqCT`iB=?8@042mukOZh#CvgwrV{kLE7i3Uc zC&b_vZ$Yc_UlxITixB6+5=d|F15;4*I$IR%X#VYRX^;T{y}dV#K+--C>E5ZJ-c3+% zD@Zf|s<(G42dF9ld!z%DL=ZJl2gq%plE3i~D0+fkh};8Z3uyUYlHJ=2YP1LTLfZ4a zt)QlUKyNRo7ZBJB=^*sBg8B}Kf*#~$&>6_ko=r+%#)UIyc=)$Z1=V0dSgM>r2GAaO z3uu+ok_2mv-2gStLvKJ+`3?U4t~VfN@AqN>jeeSdPRy0#-wyHei(QqFP=`dxjqWME zU|+uog2YB=>jfiF@PiHM4RQ1Vjau&qm89VE5K{Gm?BL(d;}rNp24>oYpl+~EP^ta` z-sk|;%KZC%Z-8c@UNkHN+Z+JW4a$exL8e1F-64%KK`-Wk*Xn^5``zdc<>++jl6k>> z2jZIE9#>Fr4pel#$UFpgOAjlk8Nk0k^ai9<+3$&cQS!3}y(t zRfKLv2$C5WA7XKbFvtiyNF(Qj(f|K19^L%^e+Ssz;Pthjjugmuol|p+{{Qc6%`p1^ zzq=Pqfu95!j4tswir zN+DqYQR;i6vo!@|Rc`{ws;OWSEYb}T*$R^F7P-J3a*n0M9_&;|Lk^-J*(x!JRp1I^ zJJ`B_7ezNgB@F1u3y}5T7y>s7A-Y{}bWV){+1?5o0P5}qlVFiJVAq2K zAEMp&Mt8^wmY{By69F$~a)SK{POjUhf-DPq@%09><@``LfgJ(akc(+d5M&c)P{4~D z9AE=GTaSR!IRpRpUXY=IFC0q2sT%4_P|60i1VAm;z!xeAxfdr&pz6SbbX*Xbw9eK8 zprI~sj9p~tZ4rfZfqk!JUz7lkS={Iq@c=DP1t|;Y?gd#M2=+ImxeQSrdIi=LffO3x zk$~)rpsO}uLk5tf*#us`!VA7|M+BkD_X?ENopBws#}^WEc%xaL5fm^y zK>;tevV&M0kRSp(5|XqajwHfQIFy5n5AdJ`c)G;*3aH)T!UP&Kz0nPAbXbCK>JtGs z(+@sk0FP~ya&)8mY05P;KV5v#+rtWpb>x&A!vOLK$V-pdKrCc0fzun&KEkdV;USb! z7;w1?^-m`Fb~A{7EEHPI~dD5So@x1a?mamHVI`5o)&t zWI3ozevtrKZvzE)!*5yuJdeAHhBY z)o;*x0b8vC=|F?lF@VOM@<7^LZ-6WYSpix>1=9~|6M*W%pci~F`+RS}>c{FUpw{Kv zAOHWq-18P>2B<^N-|7jfD?u{=;JVWH26W&Hbax)eFQ6?ckV`Z;*+GMazBi7y^nyYd zG+g{b9b_iR6&D|MPAxI||G#-Jh?D>yil@Z`Iu!3fcP~gNt+Ry}6iF|hfR@)Yf^!bO z?ENAJ68>qOtvkTY8s8heQ+z=tfJzFG5Vk=>P;5i@R3LJ`E4K1s?OafVaDYPn26zuQ zEH#1lX|Dn`I8TGm^#?~;XUkNOmtRLp!N)NnscB-j zNF(Ij4&3Fy$2nl*!O0C2{h&|*d!%~`IBJ4k@Wb2=j()J)LHh@?AmNTD!@hW$4>lX_ zbk`fbJ+2@NKwSe+utOY&D^G*VCQx3+8t4{qhx_6P^f2)HL6ks0d=ZpbU2in+X$5(N zq0|Eu%gCv4;YIK{i=j6_sjvW?3PB_!6)xd~rb3VqJQc>lw7|<1P+J!kd=Hj`0|8_Y ztn9G82x<9+B1#x9XZXzD9VP|_ya}$ebpxpB^Zf#-*9Hnkl)|dJ7bF|_!ecAQUdZan z7;smV1)>p@HsHk^;k+{;7i11>H~?f_&QA?@cm90@RA=o(ghD(2EC? z!TJ$C!d7`|U-p;9* zS_QHerA44{M&m$UJHET1`)&baV2#UM@xl&jg6kcSyO&H40umDSH!?4Q_n(&XFo*ELoGtMJv^TzY z>H;Isko|tpeGWaYQ$W+Ipw>fo%T&;SOTdfg#UQ`41Y|KncFVbgFT)Y(Y+Yjn%2885 zBSHN8L!sW_-`*1nGXpBr-2*l$@Wos-lm3Elvk~cRT>&y_D##>ILjptxboYV;K@}X> zdEH>!0$!X#*3!Heq=uo?JBvSyvAY-Kp1>C;z?qkWfB%J`7k9uGau5m#ix;0yf!bj^ z85kIPr*?pXBa5*c?5cnlKk`A|=LmqAZvoz+11Ttcz){5l2@3x0tzeh)Z|?;;Iq=22 zbg)in4-I5&zzZvgSXyT*h!0vL+6!U?z9@u9fE2_0Do3pAO~J0$`1}9=%f$~NyJiWF zvP=ezV=;n~UUyF`sC^pvg3ktCcY=1$^iHh-g#@w^aJqmspY_4V>Oca*8JyxkTS4JN zO$$y!nh2mO64VxkRIaWZ{M$hd@fVG0$bkd0Dd2@HL@ced6~yP?-V34vvlw55KqNqc z19pxt2V{inO%cQpP*#PGaA}?d6^^1%Wyf6_LFWWAybuBjgPgwu)JBHR=lZ;OeF8L3 z&cnami3wcTfIE0yGSJbX-aN4JU>Rt(2bWO2A%Ye`FXl6Vi!bnqH+V|l_X@O7yaFn~ zAZL#-SzoMG>kj2ywF=7F&m|1a_fx-ICi?7U(6*Ci*Kxf~qc40X3|Nno` zUdiX{To@+&{|`Rb=I%Nd2GER~gC+yR$#pIaph-9od+RzE2GHCuXs_h_buJ8`>0l7M zbDawVXi^Nc$Dw?k3j=664m7utw$6nCG;ReF4_fEK02=QE&B57#)USf&-LP`Ut#Z(i%d0GcBQtz=oV)`bBy(8*xKz%X;I z3j=6W5_F1c>sl8EP+_dV!oX0u)`bC7)PdN!Yh4&X1r>;$u-1hERQP~SF9`zKW&8g> zNZf6$3j=6K86<8AGT-X|f6!_J)3q)PpzZ>QEwk2z0W`P`+SAFp)`bBy01lcXc(ulb z0W_`+VqaS0!T_q%L2AydabW=Ea}fL38W#po-UqSwuW?}jWoZz5+Zq=JP#OlYH>`o| z^+;t%ttf~GZ3<;b1)bMp2%(@GM?vTF6oO6!N=q$@Ps=ZgPt8j$O0NXVqKLz{g)k(Q zrhybg6vh{4=B4MP#uqZAWEQ0+mt^MW#h0Zfmw-&FC;-_9k^pTmi7!q~E{;#FC_r$a zn^h4qAXh?oX%!5qIjL}VVpS%bjlS3!WF)#+S_MOH5qPz8QEFa(QEp;RW>q5CacPNQ z$AN8v=)^6bR>6QnJ06`-Pr-KJLIVR7K8S6(P(iR#v`|Z{K-yUY-cMVIE&x7f$vGz_ zEh*kJH!!tPGnVi(Fua)J1U{Oj)AdVp?HBj~HS>;uh9OyA&SC{!i2EWRrszhu z>z8id8=V}@wKw333!#d0Ss561fy+$SFKL|{wvt%5RKxeAFIFFD< zb@?17kl_gk>2B9AtUAmfBWEKC`hICVcm`}zD?}7jnYe!GYyzFD3p$;LBk+aw0nqva zj!xG%&9!eBKzC%ldC3hrF*EcF^wwB#bppQB&i4@F~3+PJbZr?Bb z+d~{vf?mwo1FoPz*U5Ey;RPp%i`!6U{@x9s6|w>^ z5*(mu<_gq~?$9fpA&nf(wO8PYBIXbz1w}AJFM7r@?GIXB6`f`9LI7so1(125Ip6Nk zFWoLp9NnQ8IzcxzUw|9S3N@CInSlYiFzXMp2GAlg!=K=&e?8$P=+tiT4E>WAItTy% z?{$3=(CzynFoPi~iRlGoe`UhMF*O$f6*2X766ABcoz4? zlLMe@N?hJ=59J1)2eEt~~<}j2{OeVf+O)BMA;;)a7BI z6o8m_p9YFRgBSB*=AS?gaL6=ycjyUln4f@KGZAV{FUZ$Cpridj_pyK`mA`aD^?-tX z*LQFrfT9j`3js?Y=)kPdKd|X@P{sxY3TR?J`-B8&@tg%j$4ig@|Np;y0BX{}gCY9_ z5BQGkueQ*TI07=)^++dp7906ivCsPJVP!k$KD}9VFb%P7Z1)wr` z0!VB3KF~Fy9NnQ`IwyjP0nl2u4lqLy%mm%Elh!Si))}btA|9mH^$n!S_hpL`&Nl>;iUAgeIJX&t>( zV&?Ca0Hst=#~PecQ5OM$N&{o$^av^dKnd%hH8>6M?+*ptul1wb_e*!kM2_PupnFpo zUPCsRVKEO8)z%klL0t;CZpg};W}7C45_4n=krJ~nrkxO7Fl#4*G=iKmr4f`ZgI-9( zbh!TM_Wg3a1uP6Y!wlqZP_^kZfg|w6S1Y(*x?R5ERX@bfgfZTG_jtCr~;{I z03~0LG2Omjnk^Yh#6kIhDd5E#s1n~V$3fA|0IETl0$xmo33EV%A@?Hv{|-qIppCsy z4BkIBgMon|EWCFwXfO3nHAFK3abO0@T6WOV=hl-Yg1eyCN$z-YZ8s>r^Mi9jTBqxd z7e_$?{M&s^KZM&OH<3!v<60X?OLqxB?zp8*d819->-T&MGZE>>b;O6zp}@xpyKcx+|6 zuSVdD+dA+rswsGs26PR(K+p?g@WOH)NS{j!bR5}hP`L&=WltmM#ZrVW@I8L6Jh1cW zLyv%#d$=BfmfuJC_xm1!x(a+C{Xx*;P*Bo708;0B09qp-;NKs5Uu4RZ(wXvfWg<1S6$bOau~ z05^nqKodW%M=}q9#&Vcl1VIBi2adaRfZ93?FZ6f)|NlY@M5yipjb`|O3SiLT^e@4; zw1X^3>-Jzt>+}VCI`jy1jmr`K{jNtq2LK83@8<$7aRD_5z?B==)2;`gfpdU=zwd$O zpN#yy1LsHYo&W#8a03yJJ3)So1^Lkcynrbblm>YMx_t!#U$BVrF*G0H>2%%GT)PKc z;_Z2PkCTDn%;mY5bhSx zrDXj3eNRAAS9b`L0C-QrnQosZ38GYS1im=c4jMlNZDc8v@r1+j-z6h?JK&2FD zB|myXJpoCm-7Xvg;I#s0x$}r0$$9C z0qcOxX>_`XUV&>p_>iGHg!e_zi|J6U;PU9;1BPxN)+>Q85+Pc_A#?B%1B%v*4@0|)Ixg^l6->eZAdpGWsS4jMfiK=c1VD~QNn<-f#ZC4}21E+$#YkaT z)o=u6$$=vXG^q@Zwdyudaudj6?hU;X)a!aB;Kj~qAQ7HU*BKypft>Lj?u-eLh5j=F zUOeswyS3AG26!oI%L}8eka5nbpe@)hR6sn?E~^sIRx`1!pmAvsGcfCXM)f{E4@B^F z9RwL9(%A}H^W5v(64*Tz#0u(moe}UN7JU2<4`}=mT%`1Z&EVf2Iw9!A#XyioSZK8b zz9@hQq;k$?YGkeQ%WjG*h`K=WCkiLfJ?NJobr0NEwPzrXZI z<~LAmF&BYmbPja8bd+?uOyhu7#I8pmCx$Y6L1ZCq47i>Ga0{WkXJQKj14E}zn*@rV z5ls$AmWAy^=HDK|71GTz^+MJR2Ivs?s&G&`gv^kD+8Cg8h~%~sK>Gyj7WGS{$yynd$Jhl``rr=0`E-{3;%;6nyb zLkr^UL(n$mC9Fn)=hDt}yD&<0x=fdVWTcA>;8@!Mvh3gk22d*tRy{!!KywZ@?H!n`Sf^?hM7#J8_Kx(0LCA*HeFkFGM*B^0VSOe`}FFpd9 zLjjH9&pqP8&;k{oa>RuJR6l^kdycp;q@?EM=Yq~|DguqN!%u>Q49f?Xf}|45(m|&^ zf<|&dL%L}d;6s_9eK!yV9^d6S?)n47Iqv!gLj3^s6ki0a18*wo1`i)}`u+j+d^mz$ zyj%_HpmTJ({s3+9`w{ShLlIUGvUa=vcpV2?y*?3iur{`_k3VUhE`oJ0o~-@5NAuzvHR4b+>URTJC6 zZD~;KfhO6vgIlR@JYjAEO{w1re6jmA$fGQ2ovt^)%eJ#YCqc=8#_x`^fQG^uUhD*! z2^xzA6=9(=paBHvXu^wmYySTS4>VtV$m}Zv8ZkJ|0=hJa;YAB*%W(LCG=5>%GyD+x z2$bIQq8zm0uLwlsuKE9e0@y3iV4P9S}O-JxHCpa+96Lr%T=0XnGT z#oN1}N*Z(=MDQ&TOQ6$rOK0c~&}c09+$?aAfQoBWQ$WS4E9gWEkkvsimcvcqg_*LZ zGjv0@E7UEZ&;wP1U^}~gzXXEKzW9h4bnUS#*ytC@a5GNcgt}x&XXpz4?V&eqLmAqn5!fBNB&gdJwE1;U z;0r#O?4Hih125G<2i1Yj`$_8zz49Umv{S+L47clr5>>cmwzol+!P=l#0$bgD+mwoybN*!Xo<2tL=QNHXJ2Gs1|@#qKcE90m#zdYcMiQ0 z1b0j`To)%q7dSV8(+4;=fpp~~bU_2i7q06vI955px+N06`&er>hJ&mA$3K}DHnzp;ZMMIMe~su>o+e}J%N;D zX%j#La48^p=y^{Cr(94Ek2nJ!Z*6=7+ISz{TidWx0a4_E`~P>qeU%&F((TG|*E67E z94v7HEOF#T?u!5aUu1xYWDpStA|gRV3do&cec;`Jt{yN+}^IRY?0$Pbv1gF@@$BKyTrr~-I$UjokV0-dg)oQGyEs7!>I+XvN# zW-h2egP5BORRA~F2ie@0YT!En4g_|G?g@I)cpa2)Kv{JI|8{UW0hP$O0FnS@sCU;u zERIgs2VfQ8{_qOWc&bRy3npiuq!0jisSff7Ba z79}x8K`V^FArIO>p9wuB5D}+B{$R&J;uNxj7*uN^$Lf1Oh!R+t{NfzAxPVqd7-l2l zbsJP8I9`#>M#Su7s1mr@MaX8q1fS3Q3e+a`-4WOwx+UnvB5=%uqIV7dcGool-7tyH zbD&5CMK3=@NvG=*unJIg`NE=C*%9m)P@KK^4r8APd=U*{r**m>K@4Ra3F>xz67a$v zd>te7WFg}$`3!?n@TE4Oy5~W_3k4+UI(}G8-gxn2F{ljGWny4>A-e>0T0c}DxZZdW z_~Hfl5<&s~{TEs<)hok|bv+W$?fWF~#YrS-{=R3R&M;_ve8Gzai~s-c^<5B{(NKKI zqZ@Q$ARqWZAkbXwj4U1g?XD*RUUWM^{Rz64H*`VJ3oVF1TBqv*aM3vBMZ{uIr#^$h z0puCq1)w>e89^_CAl9aJx=sKEoa=;u7w1J_4PDvet`|Tl^@Ysh|NnQ&gSWN$PIxHy#*9B>vu2WvTTlD|`gbW8Keg;qt`$8YG=DO3h2YkTb zl%N;A_E6V?w@#gh@lFJ0F=VB@Sbqiw0!O`j3aon{dg@J+L#o|SvknIlb09`P& z-E~U93rB?R?$Dl~7meT>B?LgjM_`XPyod+sVdUTL+Yj}aZ|=JB;`%~Rlb;{FP%f?0_0Ef9Ac2>qKS4E%@153@C4As&;L3}& zAPLaXyRJ7{50vmjhgE#9yqE%#;NKs5rS(#YNfv*%s|^2kj=&eOLNH&+W-)e$%79L2 zc%cFD4EQQm#urf_ov+0}>q%QLmGFUPS7ks4HadaCv-n|}F2haY1iSM!%WEcB2hik_ z3&V@1JK##a@d&7Pwtn;C(j8d64l1i`F1axLfY$4Ams}VYK>KtdmmqVgDVb&QsTj3A zxW0!SZ4c_&faY5X@o9ZtKHPlegV@jC?{?)-cID}G{nL$nGC$b)Aoru6x8MB6BfPhE z$4((oxeikGdG&GEE8qqOAE-Wa<>>A>0UC4ywW>I}nYuj$I(=`vcmyg8LA!XnIXZn` zym$;6651Zh1G*JDfsug$EdK(0n+<3K{fo<>JFwXJx4Yg5c)>0ROBI%&YnM3qw@-wu z6?!KClTZMS3UYw2uHXrJ;bsF)!ri`q(mEYkUNV4&PT0VW_7}V1TC}oQz`MRWKxPHL zSOk|4+yy$#x!d(mT4w;u%fq0x6Kwq3eQyN5sDrC9&tih?@ds%Rc##U1kOTFm1-qRT z0=j))1itWj1@3%zhyF?HbYgj32|95FD?TBjGw zi{+qUd^U)EFBm|pioWv0JgyG5kAJ(9R6w`yAMiO`FTPtLd;diS=%D>9hThOKLA|aI z;L1QD_9EcLEl49c-~}W2Oe2vjHt<}=M36;6FM8k>X=X9>x}FK>^?d-^m(Rc5DGhvI z-HX5%Ghim{mj#t~BH+A_rCAE{z<#GP>l3w!pjIkq`l6+)19b0*?}JVcmKPU5C)p`NVK{FA9x1ALZ)D@S(^c$FFde$aBEi6X}v6l_7skAdMuEy#%1hhMjV(g`#) ze*OV>fo8NGDA5IZZGT`HXzr?K0%&9uJO~InY1%~)Y7Qv(zc2-v0}ffpwSg}JUtEHP z1b<6Cs7?b7@Z$3%13-fxqQ80|P^bW=ua5S^$GiYbt~+ zkq&tA!y1%4Sh_*uWKBh83=A*aeuH}UKlrzIM3{ju5BtHt-6<>}%c$G;2mkhoAT>cR z1R;Zt0o|@Yz~{idP$&RJw*bVP9X1RMFaG_)Vh-rQg&+Le1H(X*UC3T?0__-p*Z|TU z)b09%b&Cxsd9x{iE}N6-biD#vTLxMLcje_VCI*I=TS4apbb^WoMtEw!X$kTUsA2U6 zTu*{S+xH7}T=@$qm4FVg1f7X^4HR*pxz!^tfob9;J9JOyM9?Z`(0n)SvO_tj9k*FOO-Ch34quoCEYy#g6o*mBE-;lFZe<|X0G`s6Mye=c=mzS4xPSlG7f;2 zi!y+6LFOUQ4uRet)(6x7{RhpWXC4Aw$IE;o@Wsz_px!JGT(R$$%!^>fEut^H!7bV! znHRx|4+Xq915upC1X|??%9tN|ryLXlAEf2_qnD>C@I@4|3Q&Ij(AzWN2YA)5Jwyt{ zJrFCv#|`l_FffB=aK3cAe(0TYVFnX;O#4SCPZKC9!W{+i0q8VIh@(J~-Ju_PdrqAI z>j?b;y`#0;_f2<5qX=l#28ij>D3aFg6_wWM5dsQ;Zr3;6J`+HDc7K4FArnN>x*cQE zI-SB^n1B8M{{`rL{BGYj{QCt#2K4d-bccR`T@kd528%VlVh$-f<(&w{$aArX+p(%lQnhoHXkk8alw zpem&sT>J;UsFZ^gn|}ZQ|9?3Nqms z9uY0i6i{yIozj~y{ojAkurT=2IuXzingFPI^5x=#?w;0;>Hq$NLhj4ON8K$`!M5;k z_x%E@mx5k!ef{^p`G`U%xb$q^3ob)JS3!dqFFA!77+yE-fDACSMu5s*2)j1~RPf#V z`2YWln;$_t%D{O^m63s=p_0|3`NThm)&r%|Sxnu&&;)ZBa!)~8XRF8bfB#>rXEA0m zb-R9mw7ix7!wqCUqA zG-~6)6!^lB8K%b&R3d`%F05S-c1E|$M3L?ekb3aN(NhCJAvgzgg#Bw1kdr{AFGn|| zc?@-Ow@;Hu_e78u@W4TRA1r7mw;Kj}Jp!x=M(2xtb zE&>JBhu)ShP#pmcD)1>R{M%bW3IbkeKrDvLTTBHdq@WjH-h-NrAVWa>m*${$F$cI^ z%)h-ABoy$%5uz=v6U+y-5`Dp01GSmNzrPohz(A`yL8ohj+MQshz7|UB1}6i^!~&QJ zbsf0EJq0Snm>|A{Rk{58!CD~^2kM&yzQ|#MMKaUtbr98PVbW|fk)fmt(hU31JEaj4 z3=sQ3N1pL-hkChC2OR#O5m0CdLqiTZ2EfDp+aH5M7<5g{mu_D)Gt;`kSrL44pFilV z{+FO@IbJ>m)k&cr(z?NcmDbrLz|6q#LJy>Xh>+6m|E4~ie0 zg#hajaZp$9^chfGffBLHq$N2C83kLD-A1_cNqV+%t3AsuWbYMQQRSpk$Mgx?b zL6rv181HUEOJ-BlF~hF`CUznanxR152`rw2)RK({K{+b$#ZK@%BIsmGPznX*5p$?P z;JzzIcMr4{2PcGXpNY^a6EYQek|C|Lh3kMg1H%i0m!L`dsW4MMszIDcgeeCfB20M& zI*fih+?3TsnUdDo1j>Lf)`B#H(;=3co_~L!UF#)Cy$vqJ0$%h&4%LK~0H7!cdht>f z>~3h$1Zp6)T0nDXFNgsdC;~HaC!hTuHqAf5IaCKJhl1FU96A+bQg%* z06;Zoo&@J?k)~dju7DRy?|^bPX!7(6sH@m=3SuGHJ-s3w{QJQ{lGfb|ifnM*X#5;B z33wCKu4o43*$~hu>RwReovl>2JCvh&7ii?0u>^EeK=Td|o266~G+sFowB&$)zmr90 zD`@NiRFHvaP$v*14LX8V22^~41VM*)fSU6`-L0TrU;wQ3+wIE13TpO)1OmIkBMLz; z7P^UnhI>E}i0#mRq!#WSRt5%8tqt}bs5%A*ERGiLDppW88x&7isw)2dPT-Q+kU&mO z>*h%71Q)k2emwFD4%a z#VBN@4>U*OXl+CC^+g8$?JWYJd>!yYUD*Is45oFqnt{w3BkIKin8X2s?TP*1w9z}I z0}^>+P>XSuY>=o<>juXUtSnsk7?dL&L1R4RhM6AB#o$^RR6G)LIYyX8U&Iw=7Zsr4 zbRgixQ5YLEix2L(1!aKBqZeyn5(L8xW-~t|?7F9bBMn@dU56})fyWzoFdk<{!%RBr zFh`IU44_3(Q#e3LC+I~8%n9Hq0+nZ=k`vTmJS7heh6_P2_QBZT1|ulE12Zmw)>SNp zNq}zC#+%>415uzAQ?OuQ0yzL23>VHrq5@a`?FKh8(z?MJEUgpVq_;Xk_cKn zpI?-j9$#FLnp{#;nj4>!pO+32%}psT!4w58VSr=s`g9xg^HV@wQSjtO=z|wh_x?ks zH@XEoL+`whzW4us#udc7qSDXL)&s1vEc;_y7MFKS9J7 z5b^%*|NmK_H4YB~UMPQnR*NO}pkZUg8V4@8gc@kZ9=^sQNg76Dq0g_T}K;9+(l-?RqER#k12WW|@N=7X)$~2V|ja z8(g0Qc#xfcJ9Lyi7cQX=8d?J#03j9F9r}kKG;;qUUkb(82X{afSRZKM2(%dELC_05 zxOQ96=q3mMcIaXZQMiN(*xYUpg~0C6J3%l0oPeySfUN9z(F-#2wH+uBLF>uxy@PtW zL>n|~h%oOcTtWzWamNc^kbcPa+}_X+pou#004r$i(Vd_d`yoy4fEUmHfHDwhX$0tW zGN|7R;bwxCMu2xKegKU|^KTDK3j#&eoq!j$FcX$QOaNzU@Qs_HPay5l&?n&gpg|YL z1eRGJs&xbxWf-IJp+A~`G1V$T)xt+TU4MXvJdZbm2HQX_?AIq>F98MrekT^xv1Q_y zK3IVco@omsx0?W%5 za53)s1EdN%CC>Ds?G~u!0Ub^92Q;Ms3S|$b7X@I^&>zqlaM0LHAj^xWTmS!Ofal34 z{DfKyIt~S9V7KduPVhW%b1mX1lyA2nmV?f00hj-vjc{1!ZTR<31WkOjUMkT6*CIG4 zZn`_b6Fdh6K%4E^kGq2Q-!OpE-4P;Ze8BmFf4c{0lKcZ`W(9fyRd*;j3}DkL-7Ju4 z6%W`X`44Ei11laJFi_7BRvIcY>1StA_!JCCb|3EzpIs@bn z$e*Bb?pDx}BgoPZ-#^VY9Xt#r1(47LZ3GDE;DId;Fa~)Uv_11rx64ExScqzV2PYd8 z9ml~*29yI)v;@5P^9`aHG~Ef_`Qy?AStJk-S}F$;4SI0{s>YS$ILHK0&1(JTh0_*D zK*FmgFasPu*w1e{?)n9!{YB?>NCgEhN;`djyr=*Pfc)Fd0h+=Bt;kade4)ezD$_VX z_kJ{iy6-OnLCRb?`1gC1w4SU}fVXErM=3H^z*BPwmq2IepVx|T0jx_oI$i%{F~j=% z3IU*rtv}s?3PCTpb3u((fft{zL0rkvEeJX+q?@BVkR|9v?ki{kUMkh?`U6y&c0-r? z1;b=Yw848IyL~wVU+6J_QYJ^I>le^ow=Y32bm6L4yIsG$W(J*EbA-qG&5JLaAfX8k zznZY{-r5%MdRXYHh~uuH`zRS+_(EKj)(u*D=lkb{E{G4>2;o!$N?9*tL404(%7(JE z&d@I}c&~w$B7@=_9NK{|YFjPq}I;t6=6BnnQj z;DaU|%U&G53YrxJFPBsZd@&UqIV|7{uAI_dECXxi-|xy3@WKmW189K;=z6uCpdlBA z5~1!;j>bbEcF+r#l)wL*kAN09fSWM5 zs}C=^I2k}2=Rm0hoLm|YfwrXty-1P;&3kfy{L0ZC2r=;jcrju|05}%FvEA*&0gAQ8 zgP;YWfiHS{!Ips?c7OqNNSgI^kYbR-SV2Wzz>6p!(Dr_oms4377_wMEhCpN75aura z7SKXD&_Z91v`)v87c;Ivk0XYJZP|K;4D&HVdAd4gVSf=g+3yK)4)Z~|YW&VmT%iEsrR z-L4;AE@H``@+-yw>avLXu{BXEX}dk3sS%Xsf?j;_1^Jxg#hOcqm}Y?64_buVj3rm-fzv)HrddJ374YJ&CpfrX zq=JkA-D<}Z_+sZ%Xh@Z4AXbjNP<{dv6#_>9DDMTn@cjvH7`#x0>IWr+O1OTIznXV| zvK=UMf}#z?4t%jZ0Tco(FBgF#f*IsJa0wjn!VadDzoiW<$G_i~C-6l$LU=K(?t+!& z%?HFl8Ls(YTHuTOCLrJNfO8wje?c$Sx`0HG;)n-k6eP3DvV!9%@WqpJpzwq$4E+%F z;xXL6;CTN6I)V_CtY;U2-Hu4syHFLLW`QS=2jKJyH4~IT`caiG0GSCY5a9^~RMG^# z_#pvGSfH8-sStuh`(JO6GdW&ty?}^zPPnPKqTL*vjUkbzi1ss)-ND+c4 z0tX%_a)VwJdcSk5h!2xUr|*?4P>KVu-+r+UrnN-0+xH5j8v$yyy>JCN@U?Jv z=#}H(6&|2$_`(1r*zJ0yc}IykX!fFYC1|zr0?>Gt>pO5Wr_;5g8+6osN9RP4lIGeD zct3dad2nF9Tn(E2X6Sak(%k`45}0KJ8BY52FN-~k10?RD6ZpbZ5?nb3yodp7<4EhC z;wCY3Dg*!aLjf;1_`s5&0og3ZETitwE8R{y0WUtv!G&L3<$aR|gsi!$ZGk)b-#Lh*zkxb7u2&H2qpyJ1M}xElf)16s z0`4`w;CBYMZMs9Rq;-PVKfQQ+_WyryV(9k0lGf>H_u>xdym@d8z#`TQ9tU>4zIOt9 z!Rtji__uqMff{T4+nq{4`MX;Xaxz-?L{MG8zpZH&7ieT>uOTRZOS}{SB?(4QDuY&@ zUmidcMM=w6{;DfLQlLj&ss$i{A_ZjQhgU*3XRha#XP zcqZt@whXX}PS-o&%W%Pc>uzYp(gnB4A7&Ff#HP>{LA|b9z`F!MV-0CRFV=B^%>hl; zgWL-8(~B;+O`sjvK5&~}+ry080XoH=0d&$&uj?F8V1RqrpiBvBJihRR8{j%8-~~6_ z0C1iH4H|U2z5pFO_Xo7f>kDYn7r0>=_~O7Zeum~FGLWJSROY?E4+}KbZr2Z>*5e1r z7*-0KE5nPx72s}8T=S6{>o+eJuYfct`Q;fvEsq?K3TQuvm)(`&4wU_$&6NSRcK17* zE5iY(_&YXNhAmL`Gd5R-6;SqFHdlr@Q1(?eSMb@~pkm_;n=3<6YH@s8QDQQfk&+6b z@e6K$7rulWa0tt?0f=m>`F ziw59ZqXbj}UkEJ*>wA3;bOt9!TIYlmP{HK`IvC#=;@hrEpkX|#Q~&?J2t5U^U$(mn z1ia|H14|WJ84NF&L8rn6zDT(X6BOMATCV|aicSC<@Dp^9eDe_&>o+gzmO&B;IHLoT2gnRa$K%V3D<}W|&jJMis0tJae4zrj&o~RT6R5ihl&J$=@W92T z!8r=N5eU3k@x@0rP+)`hMSKAbeT4pb5f5@1u0b5o_!8)fjvt_a1D!xrD$vc+*2&TZ z+D+;EC-B8WxOsnGA9`VY^8f!AdLUPVodeqC75JhK7F7H#Q$fRgj7V*pB$!;O1WGgC z3npHY3hq*Z`dOgW{K#uj!MkC;SYN2s)cY+oX zhrS5Pa4}+FcyWdaEC@Pd2YeO%i`{}C0hWL)PS7DOFV^sbxEuj57DE~dovt4;DrSRh z{}A-z{B>v|E)mHPILW{OI*{eXD@fVj>G}a|KsPw!fQ$SW?;}8lv4E<7{_VbR0yF;C zGcdfE32_1_&%Dru1P(|AxY&6U_~I8cNE2kOz8qBPe%~Kyoi4s7Ug-XX4h2B>BZZ(2 zRPpb3Dr-H!-{;H%T6EkC3Yx$SP||v#0x>DAvo!}aYq=d9Y(W_e3JeS{R={io&r$#2 z-yY(7A}E6)fq~&gFGA|YL`I0i;Eq}F2UJyp4;*2KE}jSBQII|Y25NgMc7dD`ciQxPIUOR`n%$_eIy!wnyx;-3kw1&Qdn(Afpe!-a%x3_sy&UkuM-S|&fESy2Aq@Wg z5ZAvD;)DovgIY?W)4*9FDB#8KUJwg(dV%2-5DPR|0!jyHxd-eJk&d7jry&(RT)IaT zlz%|;u%N4`bASK;587@5RvwDv?hw$fM@)CiLfZKOFQz~iI|sao2B%Y&fES;jQvCaS zK~Ws|A`oITXdg?^i;$^c#|8zwu!4J_U@}+?lyX5Q3xTpfB8P**sT;JvhYMoNF0k|? zhF(+;toen-1K?R&umQe2-69jgcfVhTgjP^MckhIU|NjSePX(1)K`*4i;sTwmAa3VW zkQ{i!45-?|jBQX{C*q201<-Mc{D@=+&X2Rf-UXe=8CxKYtm<#<7v;*X` zZ15$&kf?F}0`|BdJ2(M=J)V7vp%+r}fno}DHqU18rbI|Z4LYF^?9EQs4=-l@{Qp0T zA5=(zG7{);qz?fvMB%R3-3_uEV&j4x)$b!ebjpf4!#_3Ass6~5qt4;o*oa941{UEzpu1)li2 z4Jpxa#8>TiPG~tBJ0$c(TIUo;P&N7D zD`?;0%a$LI1_k!zgsuXhIn7=M1_lhrLvjQ-WHFN{j{E~w4LatwhZT~bL%)EINbBzH zfMkDABPQsD4me{71O>cMg0MQlt((rNAXP8JL2Vk;1nb=oP79z4yc?`2s2i*!;DsSv z<_7sG{z}jb z8;EZ}?E+Bt=HEUQI3H^(BH1fa=5a1)PzdoRcU&}hhypcmGV(}!n(m)gG2g|s&U zFcT~IY`qtVZ-TQw==u$C+JvPz%-jt*U(gvG9v~;aY=JpZ9^ynu zU?SI;U?(|QWbwbyf_NJ=divtrH+T?$6A+$S3lb2Jcm%l?QbA*uXD_Vau6@u9 z3kWfYYr!5wNg`iBjlPPHpnyO(8sw`MXyXuC_umJ59~2O+aHDs3f-HfgK9pntZV$+Q zgarh6Bmz_!q;-Qcb6RHys7LtX^#@RAhNBzYl}hUd7j0>s9iSfJi}N2q4hu!zgUi#+ z!Uc&akUt>q3wXiS4<1_rcl^Nf=AaWrTzR^A1R%kL@JqmpTYX@)-Qb0C&9D`7ka5Nv zQmzayUQPy&Gj{v_F+TeuX9{Sk9H<9v{pN-K6i7FoU!DPUHtho`SMV7Dpb`5NX;+35 z|Ns97jYWn@yE5#6vfZU!89>zyXhXY=v?~KB>Oks^rCk|7B@c+LA??bLl3Nj61;^kLZqJ0A{;L|#NpS)0c4{Ld0F9ctJT3(Pn7p|ZYt{jiC|jCeUe@pz9ldbhdy~8>l$~Il`{D zhZUqBoJz6}K{ovV==zuhS$;6>_Z zSQtD240*=5JlDwcLcM9E8!2(R+GnSY@!{~3o6A3W!fENZlAcX>8 z2Z3V&byNd%jvmNC{2&K``nmf-ClE|M(<{;l>hg7lw4MQL1s6i7n^bMVQPc~X0|XBX zJP3U8`4cz1IV|aKHw&KR|ZgUg4j#sA!P?h%@lc822gJa#BPyyWdM1Up@M;-Kpr$l zk(OGNnwOj!Uyxs(S`?q3l*LdGk8yu8`7oDzeI$b|>x_;?&{n6?A2YTq~3&q#}|7U<^lwT~r2%YEy->C;X{3h@< zXp({DWd(S0j|05+qcil$iX3 z1ijdK6gCRR(e3)+r6#Dt1zi#cJ`J%u^i9wU_FvYZ8Aym0&^p{UR4t$r?-BNN`@RW$ z@udWm|2cMXgXa5P-+)dcd*Sfv|NjiG>x&t>LB}jEg3PxBywC*a1kk~$FTj;Jc;y@F zG1=XrZ$L+PG#_BJK2e(v8sO*OFXDTmau&nEM@*n)Y2ChW(mF#NWnSC?@A(UT5d^tN zkbgUmD@a-3i_MVsC@8Tmo1t$y!Gp5ht`8v9-T_5dh8LfDK#8^ah=TQ-7jC_f)CoCb_k^M=!x!kB z*cC-rPAOJFacP~9z~Ti-f$Va{8hu=~5ig{kBQ-qu z_k;DdUMf+78wheP|9*<Mv|Q9(Vl#vI2Ct75LnJxWm)BU4Nu?Hi2U4_2f9nx%V|) zkdzEcTOb_T{ig8^XbL~PcdyR>|NnQIB2H06T)&pZ0xEiXL1&oGZU^NX(9yIU%|Dq- zWcl}pay0*9DG|wX%vf=MHbaKOgV_u(LbJiksd3ex-M#|+`vY055ApXpvw^ldg7%~c zq;-cl%A|FISD=6C_676h(mF#QytwxC|Nj>kpMvTyuu9NnqHIA~EH88+$Mb`Z692A3SQWenMa}}g1@C7@PK`v(}bcURr@*)^y#LHixBjG`9 zeo*df5rt|K1#8;{5(nk&9#)WeVD}VOka*CG6Z=8Mw?ONG5+zV1wx)p6At*_wb@qaG z^t`zK7<4`tXuIKS1!#7f3Q`1C4OX!gq+$a|1$cL9S|_%hO8onM!O;OK1NrxZO+fb= zs9lUM_Tt1onETYyy20AgI;VoHg=8?WdtVrXT%ZSX!D|ox{a|-@Lqa#G8xq*ywjH|I zi)^^zf@$5LX(X`L7f&96sx2!>e0=G473lSu-~vj{y(|;KUd+D8kk;J`3Wc;z9?)e2 z*c5^Gy>~;L+9|^EqW{tV|1Y{8fwEC6$o=RkgnvKSFX+NA#A`sUNrBE*(7kn?Q%%65 zejqk?D~MgH0BWT6hWPFPwez7!Hf|qiEtgyD?xfW0$!X0&-#Fx-CrQV;rjt} zia*Rs{_U+G69ZnDJ%g4b;O(d&X9c}bf{B4=`JnnibE7;?fiJ#7W*I>JgIj!|1$hn~HngYE(0bu1Ik2L>a zuM^K$4qDpR@NhOm#*c@y8D4x%0Xz34KWGc)yr2L7gNuc3SAn$737}@hizWB}|DOP@ zwegh&8^NhF^hf7ZQ0>><3MPBOWXRD8+#zSD@V9h;RxyGLuM?mP{-y+VyYNm3c#&8E zj`g%oaHN9DC9pf>=!Bpb5``dxKuK?2 zIf%s(081#~MdaBR8M<9WLFKXNguoZC!H1lJ6c<7jzlhKVjaKr^nAz#t(iz$Tw*{8k zPCN!h1^B8AP(=p4&utS-^gzIiWiU2qJx51Sw`)tlizbLg5Hnx2+yiw&GScio>vKB- zyF*)oUToM2D;J%z7&2x#f+pNM0=hw`fv3Wy)IkgT1o*c%fubegg%5c9AqS{-?`#AK zz4!&%DEL|()OkTDQ^inr8LW);rSU)5RTw3@t_&}H8bPh}c*x+?`9@HW64aWpe)D2d zBc!DR*~eL<3mJnFV_;yop$l2Z2D<&?kgh8ODF1=Ro%ZOuGJt9%koX#1aNiNyYs|?{ zPRwCQ1)pyB8ux=-vb?Cg1J0g*KylO!I+HiV(d0!4 zir^Pe-^%8NJ!rS$OS}KD82O>+%J5=WJt#(+k4RX*dBN8Jivv(~&Yuu^tG%{>S=Y4Obd?onYvn*BoixuArqZfB3f}pCTUG4GKNbt|DI^ z9OsXtuNP{313LO6ymxN}s9mCjt$hrRNN@uXW7J;4`a-P=xNrb1ALxRO#&x?0fCr{L z3SMyj2Q|KqfJ-p&CY~SvKx2moa4tLp8R-BqQigv&i&yIb&`C`o*MUMAbifIS4O$`% z8m9v_arw80ehGTP@Ep{%t>1IK3GDtM7d%`DE&<5=g-wiK(KyH1# zi+{VTL_iitukVJy7nW;5sSynn1vd>o7t7)>)usgiPSA?k^Z%!X=^^4ZA_RX9R*?tcD4e7G*JmmaqoAxB+*s zXhwqtBLn!t-)6WvFVH!Ep&~&qHXx~EC}(8o2CepthO1M`U;rHrv)y-2;ESUhp+Qgz zJ!A64VbDSxP=(!kpu`=X%D`j(;O;P};qAjH06IQkI}_qkTWkt~Ubx*gg)Ag+{Q_En z>kpcv^gRF`hwXK33F!5m5ZD`fBdFK)325j~B=E)5U{GkwfJOyEKfEvpxdl%G69E-& zy5O4E_XlYCt4dm@h{p?tKmY${FfcTLj(7ag9jed`Dy$4Zh24*CSA}k#3E(Yxs~}B~ zfER{uK-C&czzYs|xPgX$et>Iz@cl_VPA}H{2HlteF%+~(SD{;^vD?W6R35^u;0SyX z3N!T1Yp9`{VIf>12I>?*7tMn%WeR)|4l)!}m4f<&Qg=W)Kq>nJNC>pAgdIf)d{BW3 z|8^FyfEQ;sK;x}Mhkv{86VROJhoBeNZ^Mm%O+J4Jd~pyV`f@v{Uu6O6Aa;hnd2t=I zkOq{v-UPgO4OjIBWWBFM;ENmUVU~#TZx1~H$`o$`UK~Ow#M57uXnx6PeXv%7e|zW| zsK!o&#@A;-Y1&sL@I?vS4q=eBpi#v{ggXB1pekp(?}xw_-f)Gmlq&fPT)cJrYJjfE z;07;H3jG4QiqjLcLlJ+u7YZtYz;h)i<r^56wLn8RYi*G;v|9|ljw0MVq zyXyz=f&fr4o&~>F8@xh>5kAZo!X*H@;o*gy5vctr@NyC;AVCM(f$JoUX%7kOgSG0Q zR1IlEAo~qk3k7DpC<0mk`XFfUHR#*|P{;(n(7g#xso+Ys2_*Ew`v>xHA80xf?4@i_ zqg6nlyMqOMzG@&FXdZ!odk08Q;EQQ%p#fJC54Rk&6b;o!O(4B+(?Ifq5FY4aXD)&6 zE|7d$cYsG)XCNDNJ7y!uf*0Gq|NsAD<9ARx!+I1lc+Iwi^{HA_(6kCTFdLBr^SF}> zsQP?S2QuRIVbDH<{a~jpbfU@~5A#*FBq{?au+5Z7z z|FCdn*Z`fQePaRH^8pgSV*zO^gZ6w}v2X?7B?@Anv2X>=vl@ZgZzZ_}h9EkpAU-cY zvp6+AH?abRpH{(;=agAe9ABKA8lRa0$uH|!L_*7V{B?TG;IJ(~!cr3&hGJrM9Btq>e`ppwZ~An--_YFJo{gK8VlW(!dC zz32xW5dN|pv^A9lbm+#5z!x=8ogjYbji47Y5I(pv!*UZY|9;4-tX5cty8s%w3%vlH z_`JZs-}OTC56)U`&}He_7d4neIY2^S-boE+&?y_G7rH~5SUN>EzJQ!pegJfrJJ_#j zoj$GyUcCAOYL17V>2(POo!SIBW9JNJ&h4If1a#ca3oj+m7A(*h#2JW%&^*K0$-?zw z?H5ot?nT-YP&Q`a-w(R7d+Li9)4)r1KqW8O{k|8VBaavO_lI6+{>51fYGa@2^>GE= zAHc!Cy$KZ5pz;)I1;|gJHJKm-`M0}-g0Dw7(;d?LBIv~_@Y&{|6MoKgy7azyp#`$* z^(>ImUYJVIO3VYGLCZ7QCqSVBEfhGrc^E;}{~2^M%h1fc23}ng|L_0*-q0W770p{lIpj}lRS@+Ye5E+J^!_@dxn+DD=S7yWbvw!kYtRE+kI)_xoM|EenzbIsEl<{{5j_ zK-&2C`?wy^z8C}woa{py%&r`e$h*kd%_0!+Vm-Ps5ZRO9sJ-+FG-7B98k++h5a7Bc ztrHwgFIIj6-GvA)vb(^^eg;S-xQI&Y#CE+iBvIEUfj5Zo@1F?L1c?ENKSBI%m#Htn z2>=vzH^5QX?bG@q@I^E@Y6SSVUkG|}e>p7QiGcSK`JPGZ>;UP0AqsNB>o!QiW@GEh z@S?d8T(CjshFObL8Jdp-SigC3x)4&V@yj!S${iPw+W-ImgXVfy+d|4UP{AEe7B^@MHvfL#H{GFMx|=|SMK@1J z;0r78*bivBb_4(R&<&udeADgw1yY=Vmxg=X1*hIl*9Bm&YzWK}c~No^EC!C|9}sq0 zr|SwxO$mzP-Vom-pqvQ0lXgL1H|XZP2FQ#_074Nc@qq3I zfc7Xu6JMvx)Eh58fmYPKRDkZeam7Bn9a*h@EV;Du*f*>3R?NW04_Rqyoh}N|Nn~+5Md88 zgHSB=LHa#!x&2XZS(;R6fDj7lK|)gRs*&U6=H_ z?f~^kmjrf)&H?-J1?L~ICXguT>dOm3FU-NWbcl4iUU(S>TId4LZT$N~e2;*F2~-dt zVZNBw8QRecx)PBQB-riK3aS5~tv?X=#cIgv+kh8M*C5uscnR5;(COOH8#*PZ+qD6F z74eHEa4upAc(D?E& z{IpKjDg66gr?eiZHRs>%I|WofegNgD?L7e?a{^yvLUryB1zm2H)(JI#(VPE}jcZ`- zJNX$H7_`BgTW7ul8w|?ISqxx*f{tRF;s`P==tcEEL-1u&`@z?OrFFJ=fyBYLIzsXa z2mf}6SilQ^s7a`5UueAf|Nn(Dc!iPYAJ|x-fwL>ai@t1dp${3o70dy(W*vP+y@8A?)f z3*u85lJhg-QyD6f^NWf=6+nC{Ln2l-$|d*U_9w3Mjlf$PUqrtC|36~`r~p5|7QB+9 z)AdJl?GN~-{gu#lJ)jvEP%q_2T4y6@3i5@(Yfy}UC+R1EN~#zCU;Y2zeDXhd(6tNP zk$DR`>l<96fLEcR-Xhlgi=|c)w5kO(>;rCb{0MxpI}KdvyuJi#>HbLToB(R7y;urb zL&O4Fgz}^DASeO@UpPS&f)+8j{^)E1d7#_%4`hF4SQaGo>2rT%w=0LWD^Cqaw=YMh z@1NIf-Jv|4pbH28bU%eGf`Qh(APO{oOXB^Ijc-nHGJy7aT73Kee`gUBmZhI4dp*JH zCqM;!XXp=5(6>JM4!@(d*W(-FxKA6(Czyp@P#w@1{#&#sUX(}^|pfa27u~suopn3#+U3v z2E9G3Abo-S+oytD532mXWS;;T2l54yabMIyZdC#A_~74;VrVz$NSGGzRf|0Q+e1Zy zK;xERH^_5=H1R;!&7v*{G;jyy|8(U1p8?AMptu6%|8z(S1g!_OaCc<@IiG=pfnkHY zD+96m=po|1SdMFK{=vfE+YIWdfChaYfcu~ipncE>{QF%WH2+|# zP3-o4aquBi;0q0yJ)rL06VT;eJ{Le&a6RaDz0k=rvAOmF-14=cQ`V2Lyab)1!@u44 z1t{I1=m1?HWAPeP-YcvJ3!5HaAoJ1_F^UIaz{`< z*a_7AXs$iOQNr}v7~GWscT&8{UbOuNZG?hoD0xu<(a_BVR+HB0A@(8_Gy)55e}O~8 z^+{Uu0md}YMb-O#pEUpEs5JvEbcCEv`2l>FL~}Q2%^gRl>lM)W%9Vf@ljgu0grHMi zUcO{zV0gV1R6@Q1Wigg4jx4rbP%gdo5wutmboV1vVLaE4n5yyg2;} zG>Fa2zyN9E!;X=86Y%2WB~W~G1iY~L4T@2YwC*1088R1xUK}|NmgL|60X&1Z1C(B~ ze?ZQl0j0@M5(d_^MY02+7r0W|F}%_o>YcDufqseS0;5A6?G&~C;rh$)~|+<7ol zw!%#5ftqqL=!GN1lo{F|!0S*7LHE_XnA!Y@nfcJcA4~z@<|gQ%IMDcQ^AQfPB1az3 zyzP%5&_Ti7z8{(oDg?e*c^(vC0+5gny%O|7V>U`i*E2CNfXh5^)cHPvjx{{t-yiw} zRHgYs@`_+k79;4Wqc@Evl@ zt~~gW-RCm&pSxQf)sU&Gg44^V1jdC9@Z!0>v-OApXWSdJGeFmv{R0t0mQnd_cTmo69N+c-Bsb)JJ2EMPCA z9u(UQx;J(v#LE|!K)t*JWF{y&K|$%$;nMB816;1`U?}C!U;v%!911b|bs2an0_@+= z8)?ml7}GjKZ}9JTy#Xq)9I^~v)WFQ#f@UU2Q8&-T?$9lrB8|^C3Zr=}`9iVEx8+PO63SU=-7u<>9Dk!e`h>!J~7qN+uYG(pyCUt|aEBwyw zJ-(>xd_ipy5C+!=0?_$=#G3CHPrjk80cL&qAC&GvE7SOGTUqCCVyF;2xnr*rmO6tIw3`;*5bh3&I zIFo_a6M>eucKb{;0ry8(8k=nFO3~40^F+5jdV-FUK$gEIkt< z{n8gS6y*v!A9_FdUSyMi7j+ORxOXxuFg)THG}16{ZcN#5Y2Uz>lh)Y^g5K9(68P}-M=h0&j0 zpF^O^8M5Ee7Gn16Gq2Zzbz@Bx9JS&I-Jl}^p0|MNK9<*4K#hH-<_ZOd5^+#X2VIcf zd_W=K#o>#fQX4X%j@49_S}nM#%{5Ib3?&j-&=XbnyZ-6*X;KM%VV49dk~v-<1X~pF zqHh5>5W9Ujj)O83L-P><>o+fc#6mI|JpW*}rx2rQ;At7qVb423UBR?Y-&f#uq-mX@ zZ+38k=gVB*?F6+F(>i@`fX~uS>kPfMg9{>cXD2t9;d>7}q@30ndSVB}9M@AYU1wmr z&VidLX`QY+c0x?{-L(s1PUxN;5OZAjy?FKM|Nj?HLBs!M63f5pz+ujOF*popixk8JYr1+Ed0HoNpi3PEM*4&eqRC5>SE}QO7IRQ z7f|U5x;qAXR0XKL_Je=FOXv&8LOhu8iz`RL?TvsJ(Wk%+@NA$jM{mf*5O6Ci`y>PZ z{?aeqB3zv;n_jSe0-q$ZA2bZ+<9Y*BY=9>qz-JeLrqDp+B`;8gUoaj6n;h`s$4M{) zGIPt(>vJju92o~6L9E~r>}1*aVlimb<$mz7GQB<*ASyujtANT57VwNN|9&6e6JSTx z@^tg`cZ*B_O`2qb2TdPId6sNYVx04R8UZ5;_(k5ds;b05x<4LlAo( zIYS_06d-Yi5LbrejKsXC)S`Sa!@slyOdA!0DZ^q0@P0)DQAUOr&C!tkiWgq}`@hr2 z6-%cTnloB0-u(Ly%^bZ}Z~py<=8vg1Z~pyD2(KVFzc6saha4kTl+^ z15yJ?=Dm7v{(%RJrgDH3fbwoyXDb&-0jOb`*4fJgG6XVTJ(Uln1~fRI*4ZimQUl3h zy+R;05KE_ufYd-NZ50El0R>1}XRicE4J5Zsl>(`OI!5NrzyB}lL4&GQAfgmR6o80q z5RnEV5I8+*ZxK+2v#Lke`8&Dzs{XMRrAm-l> zHs|6aa60Sg^qG2xe|xAvP!`_{^Ieb(u^l|f3A!``rqpHXjer*&kU2;2?%gcD7o0HF zphE~;MFRLCF1h%yJEZqc(2FRD>X(+#k#VrIK|TVz7t*)}GocOw4=dO*f`%1B-uwga z-9vW)!iG?eZqRjI&&oj+h(K?z#~aX1w4hEt)VCKObo;d4351#r@+?QU&jgmh7n>nk zUfh2B|39QFbclg}e-A6j&eoHq(7p*o3}kBSNzfv;JFotMZvcPIb-WeC2Bkcx*}W}O z6F>_zy1IJMG;9B-9WMk#KvI}WC1-$K^kZQ{X6g==0a#WLpY>4 zYTcmWlz9TQYq56HXjl`LtUtqh<70+fGhK$=1M2gHEp9}ts&e=CRr=O13s zl*jg7kRH$|ShtfxH|PLP(5798!Tj5ML6!yfP6fFos2A+qfL>qla65Qqiwd}T0^XDr zsL&0%*MkW(Xa&+0)a!Z!bP6ZdO*Pgb{>cUbsmVxzke!-0_Rgu$wRDP%2EAt@F5e(JK7ha!jK{g92QV_ z9(=^q-O>y4koF;{4>}=ysJr?1gQMr*1Ey|>542A}Wneza2Kk7DlBYH)CLB!~e` zk{~Ak{#FnLPLhk5LAz4GN-sVHH%CAVBzt-x*@YDpDE#}Uf|Or;1g>a7r?^a+3eGW8 zctOz%7CrcYp||(KhyVXOd%$|YCV@^@Xg%@p|NqVwQIJZ=0ezqf5_C<|6kd?wApe3* z2i@;I<>SBqfncp*M}SQVd{LMH%4`B)-C#+`o+^-upgI7o`(gK#-kgvB{v+<_fH*Gb zg)u}oafyeCzqbH1_;3Jpmzw37j{(dqJGep4OPR|Nb}c1##d*E?1vJ21PD#F)(B?WywR6 zb$82Dkm7(BM_Is&XtG#d{GJRo8PpJiIdv+C(>bMA18g#g12?%EYH}IeWQb#WT0x2f zUt~i}ewp_VG~G89R3?I&1S*@r*&(g7^}?Hf|3SMgA-J~{)B=OWH|V1HH~;dkRL2g!QD&I;_E3JSBJUaI?{xy|DHM%D|Nr++1u;PvMuAlXyjZy%oHPTvdqGwOzIX{fqz80b)|@w>%m#KYH0^W? z?$BXiU^w`Ip|^+W2_pk!!78|?2li_>k0Aec5l7G^z((uA#)9_J^6v*1#Gu%A=~C(D z*abG@5kqf_Ajk}`kFqZ^AlwgLOr0hF;@vu^8K6o8;_eq+FtGyxFU~>OX`QVgKY?RT z<2AHrqwxCQ{}-~LU7He*|Nrl81xW-zH@>}K-3T(61vL8(nlpnMtq(B{?BwmeAm0bR z&;~D`0iC!7G7ws4fFlo7W4Lm3hfFYma1Sta^KkL+2d9E=7RGL#37x%1K%u?@v?Fu- zRFHX~vzI`0zzgLKAQy0Sw#vNz_rJRr6j_1YQ$d`d7v|8_6s-q9tuRnl*a9*q;1Ot( zBZ!HXqe+OBIcvezLcItIHBgxWqJv%-Amm=Cz}P1OyQhMj5%i*P2S_VR0JNF~C)`Gr zZl;}}*aV+WB!E9Q6_CvYg-p>;T5=70!;qjd==0Q?_< zk}rsflzd-p0Xd5!pt~1jM&JvrFCacB`L3ZP`4+DM83R7Ki+_7BB+$1{1>60C9U=F^ z8^Q)12nUKRP?K2%mIOIKNpKcu3+L1a;QR}6QR{({Ah4JIyn?3G53m0He^CrlmiGXZ zQbGKH-d>P=VDD6rAwj*ZAVWb5#X&9rMH$Gbpcl3;L9Uc|Ezo@8e_CfNNbL(v&~{N! zs_q4G17Ae02C3ml>uh}isyw$(1?7aG7fRr6Ckr%hW?wX54wZoBK+wv?$Dn%|w@(FG z8}#DaPLL5OY88;wZU?D_w5A}1E2t2L=7hBFR#3(P?`G`>s{@w>*%u{xTSP&HFw~s1 z?x`T>fj5ezgEn`*Tn*a$S@{bzQ<&D-`UDhOpwN8)3N6?B|Np;m04XD`5@X@-1uxII zl-3Du<$$V{R#0;V+RXwn`S*jHMEv`wf{W`@wYkuiHKJnS-w)Qrzn#Yk6bB$T1-*C) z*~03N{hr%PIw90 zR`>E4Xfh~NCaoKsVA497x_wpBx~GDyO6wGS!3(-+k^^+pBoAm0E@*t@MPvt(w#fci}!z0%pP44_UDh|Q7h$^dG0f=c~AS*{GA_9%$`Cd-up z)FK4c3lFng88qJh`wwDY%5r4@^^HJ!4`#VCfO@8Xf|z5o^tIWdIE`fqGn}S*{GA;Uy3|HOrL&GyYs2JH>@$#P`?rTYX11_s+KR|ZfH1+n!(>R~sQ%Wl0 zK_UzgE|`fd4pIr?gCs!g0+^W~pQIMSg+THMA*j750;nq7g5o_vF7wSy0h!?z1U{@Q z9?FHB)&-IP%{75AX#E)Uevxih4(Q#uB^=GQe;7;bUsr&xDq!Sjp1|;e`R4!s-Jv|k zomhNYCNRACas#xmN8mWa2N3TWi03PC+>ynkZ34rK>o-62Ri!cB_n8h5p*C>>!liF&`xL2Kv>|5Hb~>K`2k~hs0jaluI^9)&^Z*{t|DpO z9H5?3cc@5OC)ewp5PQ=R_JZfLb;5gVuYhOHz!Te_SA#~_dVOC6c83ZCz1aB=)cE27 zwIEzY0$yY-1{d_8&F7$^5yu@U{Jo%souK*Y){~{6Gr<3Vhs7s=4r(y~O&o!ip8Wys z#0qKr180L~n|DE)Cjl=MA&gGfA1~6bgK7`gF99F}LEQ$HE+`YUyD#8H8$@Zqi?^%5 zj_Y*&@iHAW9qlW_zh4lv2vY*o;OGWb1WceRzS~y@v>B1_I;d|6THOH-V$?&+nt$@} z_s#~7e1!gKy;N!mo;e3^0qYF?@!}EaDn?hCfNo!jK+xK5*Ejszc>*BJ7u`G)0$&(_ z15V&|C|>`bf;c(gg&~B|>H4D^+1NV>V{d?sy$N0*Ch*b+z7M}4&z0eYkpsBwZ$6@9 z{pLlh10-cl0F_4_AZh5l)#5xzxeqD_7v#Azq@*#Vq!~cgx`C1)c)tT^=}36*UQh+P z(+RQY4QY~A9z31Y%JCnuQt}VztXl^D?V$=mFRqnBtI!h7Ua+Eo-d>P%1A9aF1oeXA z5p;JrICX*U<7z%4@j3{nLYctsP>G-yO-!K0g%Z83Ad3QedqqGyBzr?!z~=S(?g6cG zhpa_>5e`0>PzJJl1+*xw^%8#zC?>N&Yn*tpPZ)HEa`d`zmB4zM%!dLXeYO(}y&=4N zf?jO3gp3j}@^5!l2zbE;_fG`K2wxuP#Xda(Ca^v)_$O znLJPe3l$;IVqMU-G?3$7bX@uWe*$QUr>{cbi`j5RI^CffL7=UH;Olg<7(ihMx`Gqo z{D2p>;PrYEuXVe9H3GXsRUj)kvlx4QTR>C6JlTf~x_vo%r!a!t8T5h=q8wxw$Xohw zyW~;4jX3@=vMg3}>nCRNuC z)C2*gC+jyaKG;GMC1_eurVw(b9w>btEp%nr^Z);U0|o|$U4@W6hamQbLRSV*ssXVV z6uL5iVjRStSm??CN_il?4TY`@pacP87ZgJ3UC{DQm(;@2#5_nH2d+Y40!WgedIDJv z#0NJgNAvrog~uyi-*7W0kkjR`UO;G`w9fU*ftkjET(n3!jDMPzR>)Ok-x7Q zw3LgHAGCEFa%hA#L@8)M;Kl!WFl|4wm_hUC-Jv3&`9W}U2Gv5KQ6NxB7Y4o&PXKh1 zSr+4q9rHojz*nw-H-^7BUIj0fK68hz37Pu7)TFm*P?&AOdy}nNZ zLAHSo1`_E8na;5SY+eBW_D~*ZRlxyXloJoWVnd|U^$z$Jc>!?Oo2AqB4!B~v@loD5l7m8Nkj2PE^!~)d*w}K=o=)Kr;N)Y>n_m;RaT!HSN*ir(? zLuH9YM&JfwSz;0FY-M=;0NSAz7T&uTbinscGeoLHR1n8qUp%-v1G4NB>*@?1{@y?) z(BLQNkOqNn&=I^Wp$A%LF=T!KErDk)eX&yov=n|XXu$vTQgDQRco7G=taAHQkZ910 z`?J9Q2PHeuX?UOz)IQk!gOR@vWCkelhrR)2xeoy^QXon}1AH$u=D@Ul0i}%4FWoIu zBmP5{?el<&%^$FIT?f9*MIf!S6;uvoF}}D9)(TD9V8MVFFY{n=4NBc#K(|JLQ}-9} zaR95&fubxHn#Nl}#}>SpehxHn2Vz1}`UjW;UdS#5IgJIB&`@1c0>1r5q_Y)tU{Uu} z5E=AB9^6%Cfe3<%1n}`}FD$^ugHCFL82<)t{JtePj2DF&4?YPCd^T3livy5+*9kr( zi+?-V@PKacVOgNj4v_nUy1@<#co71=bqN$wphS_y_+m3SZGuNs`L|C62?o8`p9>2q z@IHJ{e07H+rT8D+p)%bqt)RH*Wa)aX3@UO!XCZdGN_2{JfOeUImo2%XOp(1JBji6KsDr`kSIv|xk+ z22hBD*gwj#doXh50i47hxc1t0uMJ|DDK8?@D!ht%_stPj=`b$${V z`*o~cdFqMX--CYsQuCXf@ZQ=fJEai?%W>B&#>U3RFYf&VRj(V)o;kzw;u7d2qT{Zh zQ7nenoZYSunh!8`x;_A{lC$)Ez~5`c#K3Ue6?Cf|!;590Ie1Vr|H_MQuo0lk3mIPY zgM>i~$WFW{0Si9?55H7^gh2~;_q>ROSaJs>{+hEp^bY7W_)yR~Y!OS>JN&(%W9qVf zA0#mQa&(8@0gX*Tcsx+vi<-mWq}b{Dp%-+nC2!V58+rnK z5X6T7Gy|+527pQg&|z&af?j08G`;9`-4l?-fU1FiyYHUB?$9SeFC1a&o`BDF?{!@P zG6b|Q=}piJ6YybvJm6|x15zqHAl>}t>!LC6tIst^ItuF_uLIpE7% zp9HvbzJmQCz`y@O>!mvBZr4AZu3uhU`1AjN zTDR|tv`*hCFE)eDAbKs?9r~j)^vjE_U@6x*pxu)%W`LwXGo~9reFV@J%`X8j7Q;+D z(R#9uWdq}D_Ln>U{{L@u08%Jisdi;}ao-4BC^R3*v3~Qy$QV)#q)h-Vce_)Ks55hG zAnX4?c|V{A(v}6W-D)8Bs)E@1HHb4dBx+n4iZj#mGSf1X6Z4W&eNz*QON&yC;#08+ z8-lJx$V^KMF3klgC@m^-&d&(R56Le{%n8ZNO)Yl8Aqmj{EmvR^xPSM6iGcxBe=Gd` z|9>awv}kCzA5njIyK;1O@Ch(5bohSm4&~@-5&*GXKY@=3NaNo&QBVMMX4j#B7q8P{ zWjfn2*N=>^S&q4WWObh_%bf)DSl3>bKv3hq zd*TvRu)ZJQt#@1vpyg8gUB7^*5kR9GO%QqCAK4cZm_gS#d;txy^KWkjSrE_-c1Pfg zMDSfXBA_ZU`&2^j6yBV_pivUYMPyq*XJmqI=>V-T@qN=90y^wV@!kzEGM7Q2ziI5&^<_?@Js0JVT8B>b_*5A6@f2&A+CT;Vq>~u z&IE)jK#TP{U3j0owuY%c4skW8v_9SnO5GsGHtz+oSc;imv%NU0t;#UL_&|3rNGJ`Y z`9;@{|NmcM+4ST_Mcea8CMvy{=1L7vo>CwHt5r6;x z2QPXQjo?>z>C8F zAnQdsTT}jmW(9rz{{J7)-3#Ibc25O4Dd>gWb&wKBsU8IBlXSKwfRe>_h{O1|hu#T# zvAiFo3^tbuGAQtcGeiv3)CH;EKNTe0dZ|{2e|sy48PMGeGAQtc7Pw)@0WlYpr@<;; z7=unc>IPc|nwA7<0qym-ff&ob{X$R{;|o2=BvHVNtJA?QfEdyXv4DSjFIZRiRFFkM zS&TbCDF@tgke9D9f#3Fyt+SN}biU%r|7o4QE}&xt4ME$3V?abWhzJ4^z90g$H}!?{ zH_(#$H2!T*&4Y4cFT|3IK`*@FvMsAYvXI3v2Olu-Z}(w+0$GIy%AJs$697AF znt!{C=#v0gY0wRoeUS^Z_e9`}kBKnnhk~3x73BP&?pBcV2^ph?WXvkKF?`_E1PaTS z$3ad7c?40UG{MyIx2y!oGQw9GBRm2s?0Q&1K@Os zp&uIq1L(*!SDs!U0noWjpc)5K3h?g-E6qFrO8woXZ+czW1o-!t{>c88zBMWF#2BdI@6f~}1`1ga8W#&nkIX-+ab9#FWA*w(dKAJ$gDq27P z|No-l^Z);l9NgLJ@E6p!0%ypy&R!c(`c4F?@%jA!f7bsjMx53|@+PEi;om+Lq%)`+ zY+S$#eelT~0^k~Ab381xz`N8T3SaPcgEJQ>U3d3_+z|L;*EERGesE}Jo&tL(^i8i1 z7w8o9AK8}@dV2&RwuXYP^Liaju-xE>nso_mR_UAG5HWbrOfiC(Rr;lyr317VCJVG_ z2NswY!8-8OWEl($3=S{8PJ%ibT!(l2zUiGJ2&qya)idZkq!$98KvPZ}{M(v@1Q-}v z5Ae72fKC+zS%IE540?MQ8$g!`?+^WgJAoMVwirNEm4ccifoYvQpkuWm?G>KhDU2<= zkXjAYvCcke07_jwd=tQeARQu3X`Ld4FET#<|NkNxw9f{bs=7np^tN!p+z)DtKzzv$ z@nvVL38?1{YK$SW>*ZKj{F)-t3a)lYFUWvSo~9RnKY&I{@2hTNHSa);N}euP22g7S#AfMoWdJ1+5c^A~D?>_VQEGBYd~tGOPHGY8V6oKP z0#N4;bS@33HwQV5%r~_tJrz8O4dH|PazUVD5q%wl9YI4x5OJuwR0aqaO<5{@W&+Z~ zgUnA5d4CZ9epd>r@%TJXKf;9>L3i=ag!kP{9ecTnc{ zLQB0+&}jCL?ot8J05?n53$?eP3G)RnLDw=tFQ$2{42cVfv*9Gz{W0OawM%x2Bai=p zdZ`RA&bSQfsQ%r1l=yc(Jk2RBmlZT8?>pqo2k?F#EUtgvxt_z z0Sy~%0d)&r%mxW;0}&fR#2OF*lFwr22Tg*!kdB0wTl_6^K}UXq53VQyUEkn2?fdHCOYdk0;z`y_=D0<<#7G#$Q_}(qoAFLp?5G5eRASI25 zK#D>7171i#6!-dG4(tuRAJpsm8l*Pxg+K<#5P|N{A6>4mJDNa49NoS@xi_>2-XNk3bi5K1=&0NuY5dzfIKU$ij7{K}0kvITTn&SUO^FEqHs8ywCrfy` zLw_6t52G->=IVC+ajXF}q{8^(H|V~y*WOudkmNT9uF(RPazHT^@S+(mA>Zx$<5(le zbqsJb8DDIE`Tzfmbs)pC*ttIkGrk_HGe_(Q-N;JV&LEAy8xcjsV?v_CgfI5&$~~w6`cr0zLAk1j7O_7iyRY!Z46?prWD(QIK<>qGAY9&|Cpj zR2(4+cFu%n|Np<}1`%x_qVd`P{}a&M0p;?8Mgc*G5dIBC_#Ys1%b*Scnaxu{SxqE+Gfys{sNt@J3v`~2k5+hn7cW;U3a_`W@lh{?Fsb( z#3-l_(vWgcH|P=xZ)BrfcLcofg2xQls1s}q47jVZFZ|mf*S>*ny$4li*(YQ`$B{BY z?4AS)J@8K3FHb>n)(Y5xGCWMq@Z(7z*=0tbTf1ZDRhQ#@VqE_0&1a1A=`4?g@Xq))c+y^B==Gt zG)M%F3Q%Rxda0E2xa$&FLAL~ypt@bZbonmn@Zfr(_5{?k1J%Y~0$ycKhzv~)M ze|i(>l*W@FX>bzV^BQz8%O1#z?9e^@`(5{dR&J+dF=okUENEi{1@0d3(ykx9Jp!Pn z1ISeV?Jj};KrP-q*%uSKT|rWywggD3+hyXPfEN+3K_L$r*0|#bb$kgQXf!Ky%?l}z z^{<&;w?Z6MB7+<)vQ;3h;7I%Q5L6j~&U4O^0L@<<2UlWed|~Ek!lOD%;>FWSus%@0 zPXtFJSBE3pi}fHQUWU-Z;9aFoN}hwzxx!r9i&dvY0l5_HGJ-)@V5KyM3MIxfDw;}Acn!DZHJA24+LFp2PQp9slM&A`v=Y@JOM9K!3-8q&gcSr2|NXt*4YGd%8T-Qpqk%x z2W0B^!c13&7f(dMqX^AMVyxf1Fc*dNRr%#XV}lGgX1X%G{{R0!sPLDW<;rj$%I2Qs z%5WLV{xj2+A+y*qxui5PC!{>zC9?>09xdc*>VTru;?%qnhOGR|ywsH7(xkMa#N5EwAO>h%d0J;Lh{?ZyDu`0N zOd#{X1v^J?j{vA(4}1|m15_+=WJ!R|M+UnMWyUw?#Wy~X0v?z%(z+pbr*%#R-Dw2c z`qK(xKs^Ft^6&2jQSe!b{Vk#(*IJ+8?+syrw4lI24$=z_bVwxyWl=-+u8H0=uxbWoO^(wHCwnwxI|wMhc_xA%e+1-{r^432itL>$yS z6vd!ZgF(B_K~V?FB`sYbQ@T6mFo3fBGi77Qq0nIWfF{{`CV=GAy1`CJ>zoL(?1lbq z(8MIjK1`!PE&(Mt&{kEDC7FjlfY$f*up0dN{~tpTbe0-Skbgfor9wlHfBiwoFjOx~ zQ^1S4AFV)VLcTl>U9!`w0!>I$K@4aZf|&gKTR~Lw4+;L>d*FqKV5Q*r0F~sRD-?RX z?toKB532wuAtl}dg)7(~a72R&BwvoS?kR!yz{;jTlv&*Z?I8ed$_04~6o24|gys&A z7&II4?{^ge4WLGWtl!=X%9D^;D$uc4+aZ<)zTkF)m99Gc`=MzMWi0~OAF!QZXK#X< ztv#=u_>m0+PkXh9f_xG1LJDr6EG$2ybx#G^p4K^q7o_GzImi^SAG1#|fD$uEG_4by zr$HV9XI^Mx2IX`9{oq^=4m^-u`yqCL67x&&ehF|0WL^ZvaEmA?hM`(Oa|h7mmw5s# zJ%tw{4Ys43rwJD8@bm#n3efTew7!aeKdRvnX|Q`hhQIjD3QDRRK>;rknLsRoAkYS7 zP$ow&kwEDIeu44}Ww1U0Xn~V?5?p%qKufQ!Ahn$=A3H-nvb@LyZQyzN47?Tu96_0f zAc|QbMIAWBboSo)@&AA4R8SG#-3lhbBHa*?tsvQMmV?|b*H}v2VU}J5o6{l+F$bJL zyF*T}1a-5V2zc>`8RQ+vCd}pk)(ZdBQ z!J$s=WSRJ4&9(pkv##^Q+`8RYA~1{T1=|^TVfex;56V6e@WKwpJ^@<0&;aE@v*9W5 zu8|%taK8W&7@$o>FD$Qt8t$h-C(_LXt<1)-Z3g(@XAV%&`{GV6!nO+#Hu%`%#uy<6 zh8ORy{{KG#(h5mg06 z7mHjOK$!}}zP`wn0aVd|TDun(xiWxqHi&(4kt+iznSmNKyB4`JfC_EU{Kb|(t47=uN%}CUm_5OlheBxV793Z7fH?#U(%o4s$@q z&tEve#7mq(jgnCC)he!UAO)Z68_@b=&{+O{rxNQEpuu_2%_*cyb9|XO~ zD*?xDr|W~)M3O1ZFmWO9p7Xk)hZ34ERn(aAVyg4YFkOpC2fjh=AH! z*zSY}son2UVtuhTAJj4leFL(?XF>(M1?|Hq02*lxdZD`b_y6W2pxsVyK-D~G0>Sl0 zrxR!m%^Oe%xpY-Pz0>W}1=W9vq1#7LpgVx2Gtl5g$>sn5U*ul~rR*~3+I80#uX)nC zeP2Mz1Ygkck1rrDDzm=G-|GVEtuS?iF41B?2@VGS{k|_imi2Ujx=5XlEHC6PgT^dC zfw@ z93qS2XplwSJ`+Vc9SvS2f?V^m^#A|=(Az&BK%$lt(y|J8;Q;rJB+TnAV6TJg-Ly^* zp4a01`$Lf|21i_4XCTjuFBd^UJr}fF-Sq)ziUyikK`{&(x)*?MbNdq58~Oz_%hTNf z>fwW88*@_UNx+LQ;6qz9AZ5vdWv&b_ggC%u31l}&DhH(W0Iz9ZvCNg>3v~a-?PZYt zfuJ(t$}-5^aUk}YW#IeY;&by;z+0M=ia-?j{L1DxE};EMdv*#UChW2}Unp^d(lTgV z>kjxZ3fDKsUBMSpj|B*7eU?q?ogSa7kllXDWX&il<8#xUaW?R z@VB^w8czFtRa#G$xHZ@EFqAlCF@bN;dy!@f)mEYlPA+d=EV=OiKj?%zUyZ;Q9&lNH zXcs;7&5LHxZkcXZj(``Dp`d9WP}WdsJ;~qF#K^#q!N9}7@Zy6f_*f(8rr}Z{$Whi_ z7eRF{%gZn!2FQ&-;JI?tC9TarnfQAxK{YC9(fJopzH$8mEl0k9PG)Teokk9-ML}JV z&>xwHKnod|T|v{PU%-n#LAQ$i$UFfO2GwgWpv5k}P^lNL(K)PWQDB%{DN2_6!hXE1AbFLRRca#K=MH^y78C-TD9W9%D{lj6ocL= zTp;G=yv5e)*u2pAmGI`&?cO2Uyi^Rf3(4o4KCk5yr=_-gHsGR5>XdCfV#aF zy{=aRK;aBp$79g#3hE<*>i@tOi#LEqbwL+kTnT~{@(4Ng%zOP2;lUBy8ap5>H@92056Sz>|bqxwnU(7N+FIo1F;M= zb_iKlfzo$?EX#TkUIca#SOIFg3A};|s~u_Gp&!79u|$D3+_-|a&%6x#|Ns9>1JL5; z?XDj{_ci%JY)5L*$beM4g9s-OVS5%d`~GKWS;i4mxn_O*bVCZG*B+LecYyN6of3rVQapn!2wd-3WN zXg4%Vx2sOTi*>N5E^*C*+y(*~>T@;e<`LlE9_R*f?9Hv{jy;|P_72RkGe9Q3+zz_- zlNs#VaG0_DEuh=k5TlAF-7H-E`#n5B^#JI6pe#nv;sb%87o|`;7`tJvPKMe6b+ySU zP{Ia1|NJ)x!B7bc1&5a=^8R^6+nW zQVV$TEfK{-$4`P93!rNnvY2oga(D|YRA7c|L^Y)8BisWBvj*!LB=s+80Q7?k|~CEWmN57PJp~53~Cy)g5zj2%n|%8e?b)~s9?lW zNb~P^H2@8&RDpV=;G4Hix>>qlaR{0OfXCs+&5#g5#Nqq|NU%cVu;2tz95zE$BjT_S zsu~)HPGHrbGPE0%ASWOaqz8spGgPhYV9$c4M6;N%8NiNVz}I+)OQCijI}VCFG_5ZZ zOknYr1&%k+b@F>Q!8{F1imOnKsso%BwsaRXw65}>TnzsXIY@yI`uecV($wh zLpSL7hwpHQxPtBv2bBg>jA3pw0u>OxE|Ahd7H$VDUvWe2fX2z4W1s;p2T&yPZ+Ddl zc=0+891@_K0DOML?Ts)G!b~^`Q2{P!ozz~;0-5mQ$T4u)=qeNNA`BLcF8a>Fo4Suo^C<@?Ji7A0WU&~ zVBswUwgObHY=9W|S^%6nKu5dGgNT3@GC>RD9;gLSH^v?X6~=7f7MLPD3az?*6~OTa zZa=T|1vRO7K$ko5Z}&YD2rnTVpk_e>NDyS!3u};*S;39{3oti=>s3(H?1PDv2!L)G z>kj1zdhyE^WIV?UCXmJyP=|AS2dI(^e6hg*>PN&wywP80M@8M+s6GMnOc7!q6iI z5=qc7lsxkP|AZILN8kzY2He~@(71$7;EQ8$5g-2Tp$?!1rA0uuuMKFY-4Qj=X#OD> z_b`+Txt(i!s6kM-s|mP}h5Ixj1mshV*Y?ncat7RVP@4oYo3|5m$Q9&}Mh89y2G}&( zaTZW}`M`_P!{9cFLZ|DK7nz6u|9{bP80>sdvqKVYoEB(7fKJd0cDRTH|8`e{07&xC z33~DFCnzL%I$fVYTIisWkX5i)E2)Mq_j?lfVk%tFIEy7q0OA#afETuAybR4p1Ug+G zfU@d?z!zuW3OTx6AH2NC!ocv_FpD{h8?J>5UCT^VE%QKH^g)>vlrRJWUQ|kf?BGGz zk%6iqmxY1hMavUQM`c+vhH6bu~Q zz9Qh`KAf1+IvHOu9s2+Og)YcgR!};9aY!GW96`$#euDSsg{pv#t$7Q&ZVa&-^K>_8 zHzufw+2ML>CphC@WB?tl#F5r5BAC`0dIY?66SRD;!}l;qu@gs!>mg8q(H+Q=))~6z zMdv|Ke1eF25K#ppN?bwd~s|4|Nk#o4}h8` zpdJG9+Q@tzXz-U5LZv_!fmT^Sxggs>+!w9dFqQ7$Ztzt`u$7>ZxNTrJwH_$d1v?cK z<&2=NixUUK4$urYDCvO4?t(z>@C6Yb`$2^RtXz$<02#%B;`+4i5J6C41NUT6M?T;M zZ75H-5dVG_ChHTmRaqPvAF^gJpqK$VGbQuD6i|QAM^J$I1iWeK!)O7X>2`S04{0j| zyfCW=cg7)RpJD)A=qv=*nBr z9{%mVGN3;D8*r`#H^tvtg31N~P(E@!-2q1{@BjZ7%pl_5UQquJM0^1e@ArbI5+Q?j z5xZO&Uc`P;VTg!|k83{SV*TdD`Y$RBpgU6e*;KiFTP}Kk$C4Iub9aKGfgHM42E!qHin}56SlfW13kduf&*X_Lj|33?69cWg0uAR9OWUL?Zotbp73fPXt^+G07}PEdIAZ+CqV@ZvCdeIm#m zpuh%g7=x9pFHlQXP`L-WOKxIk>k-g?SBu@Cqwae_`atKzfcz2kA~+rF42VIX0m|MU z(K~-YGwh*XvM(htp8}cD$uhAUYzAn#-H*(RV0A4}bs9LCe?Ni%VKD=44?UaSL02}{6>P?!O}FkknGp7{oH5^CtYxU=*B{}`Ro%6y;FE0v56iu(UGvA`2snmz~L*%TfQGUS-Ox6hll?~ z$cYCZK=}p9aELs*;r}Ag4Bzn?o8gdP2QP*wLM>Ebl=&!PfRp;e|LIlAu6GRe*=` zSs|hj^Iqt~bTWW-!c2#`3lwCaS`$3T&kGTSnD^pq4b;v*??9V5x~GEZpcj6So=QL# zQ+F%K%zzg*P?7Flkm~|p%n1i;40tga!su-M@$UbB*p*{nKwI%Fw}Z9{w}RN9g$N)a zweA1^A8&o~?mzf)rx)tm|Nn2^3)09?BGcRZ=H37Qpd$<3{r?~IVs!`Df=;k%gzHy) z0Ef+o?p}~7psk^gwt+-I;SAa;_y8ONp&!z^TS3NwC*n731LXrfP!?bXWdXd!duuKQOeQ zI(iSwbf7*dc=iitrmIbZL_M+>VaH>G925BBwJ$ilKw|`0LJM^JV`UUX#r{xej)R0H zILE!1vlTR+()2PCG^q=!+rVRLsIynFx@``4ObxVUrWJG*8>n`E5d+c>_5;|T*eg!Z zj-@O?@UB(x4qogv2Ka_c`1V&U9jI1XbUfJR>_s2;2fnZlHrVz$>~#-+^1&+={RkkveE_&-X|76tME37Y||O3Bm|I zkP(ovH;(R}383vWsMgwo*R6t1_kvq{Yct4NkAMIF?*d&&p4K@v1JnrGycyh^NaKf0 zK!AE}pjG7WK?7yIQ$g3^f$o|BDGlfaJ1FqQ11(U?T?CvDa3+IVaZtMk)HP^f1TETT zc;N|h!0U^+v_Tqqpq_{IiCTG3?F_m@599#QG)N2h>>b7zEMP+pgHsaN?$965D(DBu zK3ElWk^{719ehh9|2EjUJ^Za}IiPc|;6#Yp!QkH(`VQ1G>*Qcy$oh}SBakxK6}(dw zlF2~(lcD7+I4!>LKLUzm&`8!3&?Ig4MNqnd=<@}q8|rtVe{9q?isxP=C~!vbVt;0v)Jki$4STW=s0z863x?VgRGC6^#( zKzA=lHtjkZZP21xW^F$z{pESnmmz0q;;;3}b^X^Z=;@wR1qtn%*g}sskKU zFRZ`^kbwf_0Vv9+9spVE3bq!+49Mt60S!=r+Nu8FqiR4`ZR~glZM$y)sTSV|8Xb-T zDQgAE1iUcy2D_xQbq&bh9Q@mRL1qQM*y{ln=La1ZBmd$*gqPOY3Ni*%y0$I=nRk2x z==?+wGZ1P!s16S;G`kNuZ6fpsxQ@cA3hAUL zNG5v)SuWGr+VT#E8k#JpE!K%;1K1|NnPS1(8AB zU|RxST=j$ctOk@cKwZcZP|~Pd2f9E8#0<(hpHaP!&m)VmyA|a7fEP^Qvx-DITXSGq zQb1a~!CFAfpl+~KKzA?5(7+c5!Moo<=`RA5Ubat#m3^_+Pw-@h*VVAIO@37q1?J(;wErM~KsIfK)&gD`WRm5FPYF7gq2DfWovDLAqA<=p>gjD-W3lDdmB)eX5`;K71S^Yda=g^ z9I~L0=ilB7Ht9tKL@ced6~qS}QUh*@Dh7j;vUIjufTC|dSQ0#CuMH|9L4rXqWCKBJ zIKV*w$`7EPH~7#FP{$E|vYPJ?Q0E4;b_ZYc=Qs;!K?lQ&pR51>fAMAY|Ns2Z90%I* z0k;8Py9l)3!{J3Iq_xx8ssV~RhVEWa)CG1=1#yF3WJ6>FUKp(bH&;7b6+oGLKd9Sb z02-)h;es3h1I=sQtsw0IFPsa&KJ9Fkc@NE|Apat}203wo^M7|Q$mqZq95AgCuwfbl zSgfjmVwD5rVdmBU|9AI-R0MWU1=$hw!T?q&$h-qpY9LJkh-}#l@=xH4Z1BZ-BAu-g zAVpI_1_pJ5IRV|hAdP`9EV@8W2PFm(P)u&03Nk4ui}A&JCy)f}+%u5Yz!%;Sv9!)s z5TAcL#6tsuPtFLEG@6Vf`teE#jdAmPA_|Md(EFE*?KhbXu)0a_gVqPGVcmY|cZ zSpr|kuL3pIqQC$D|5Ez<|NoG2J)3i`3@=(AfXDS9r_FLaRAFd50vffme)Hn=1Nayp zsH$-}=gI);Sc6JBjti~~pnfoj&3wU?0n}{;vHzWSWdOBOKwa@~=Uo{Tl5c!1nX544_IBBwlykl>t=ufy67%yE1^v zL6CUCc~=Hd`37RApLb;d6-OX;(s@?~P)-D~BS3C`_aA)kO3-;%22iAc#C^`Yf{&xF z0+W?svMjMEK8c|$vB(t0g)_kSu2_JDOL7a$K|`ZvFdjrvNp68LSOly;GcP4GIknh7 z%_p%aJ+-)mAv3oizo-OsIw$xfmWqP-;?mr()MTI3JkaXsGzJ7Wt%9Knbk=5C1w$p2 zu7J{2AkCE^q5?#~)v>H8OIjFBFWPB2| zS-Z0fEan3e1GU6lu`J02o$;~11EkLSVy$x)18DKg7tn5J&@x@$Ki#1}dRxHziUMAU zFoN#w73p;S0GinQ5cuM=2-JBc9Nn%TUN$o`Fua}*JHPkYGSGa<^8f!|`~k7PgNRSd zATx4bx>3-{&V-yc}gdI`QP+!emeI})Z8yeu4a>>p&avLjp^v@G101G)nD zg(ghA#2L58Irt$9vlYNAhQSwWR)Cfjce}m`co7b%@;hDMygmv#_ZPG%8nQ;c8?<;Y zPyjSTjdEAPW?+ zjR!$Hn*uXH8^~WsLL@-vI5atkfO_?yRP^I`gA0@ci*OGS28I{eOaK3Wkp?0Hmx7km zf|f)4U{w$Soe^Sx17ZaWC=P!#9yAaEZ5F$E9V`kq-vVmn3zemyF-g!~;Lb)Hkh#oD zL0ja19BYyRo%0Sp5CwD!3`4i?kK>J?V`4xP1266_`TzgL4G{5o3247wH|UH76%_`C zpck9K7v6GYNr29TX;A^WXFgmAbUert@L4n6a50cp7gdnfa;O-4H#Bd!2|*Jdf6F`2 zw$vm13=A(m%0lzri{{!F@Vw`}6q5HIfu=J-11R8pfPQlfORWNA_h9IsY|v4%FM6ji zg6D%@a6>}p_30g;Bc?#h={p<2n@~S3{{Meh3TV2^^+j6e1khgF7xxx}rZPa|SYTUF z4+;WpT{q2=;NS222ef23^hMB%dGVmt3DAv;u7AKcg}mr(0iQ4%@WSDmA!wfT^)_%; zf6)ov1N)j6bgW4OXoD^&DS(#JhyLiC2&x;pT|YD*kpS&~y#=Y0Amvve^gg8*1&jax zZ?5HF0OeSYW($T=)|c=RE-dZ^87;`aA6$-DAFP!IwBkkfHo5by|Die+ReuT z-8<2|6YQuGWw63-@Oi0$FSKRAu>ux5j^b>=pci~lNmmZg0g|B64HoM+FDh=roqq;2 zKlTQ6n2+!+74R9zBB17tHMR*d@EjOuLbapU8Z^QZxCoSDVP_$?T7txE7lCKRd_gNz z5oaP_=YuAv68>YYR`37+XM7>D2vnBxLbxn1SV7!wUyjaRP=yPcC2Rt%RPJas2ATSN z;s5_Hgh1B$a`11P2%bK>R3Zyn`?9SAJbiW&WU>+1?@$84N7!ahAF`tDA$1u0ksmqO+wh3XwU=> z=!9d)PzTatX^;fCfe4XFfGneiY}A5`Z12Qs7+4Q%p$ev^7YX3|2}Iy3Ko{KzLX3qB zcCKFlYJY*QD}N~rx;I(~eEce?`3pKQ<020J{)p?hMf4+wU1yURX1M2D>sL%lyHE zblB$&%^>Tl1756k2374G0WY>#ff%59!xvcuO@gj*08MLwM?asZfHZRiyoiGtmkKxT z33QALwECh2x|FFh|vbf6h|Axg3eY@^RpXFg3f(^68Itq+)0LBpyB!=;6*e{ z;6&gHc}u9f!p?xpvCdXd|DY4xJ%Dx+y1_yLFRq*ds{pmj!SUG(%Ez#t1WeKT!yrXG zK>;sJA<99ck8Wlu!}(bZ*VgocAXMv4*+<7*4flAfh9#IeQ6c}h`&j2#-nbye?_~PSS z(DAFF5QB!51GrO*6juLX0w)4rFhj<$0$ymH26>VLPgt!u308qWteOvj6oJBu6QUd? ztZsm(M?o$|%+$UJn2QotfiQoAw^w~Z*)oqDR+=z%7lK}#H9-z5ey9v`SRDY*=z(lT z4y&Vc;9&(m7y>d+ejj{#EI7bkJcf+k1-#&bL_JFQfIGDT(C+7pjuRlSgLct^5)uD) z@PdP&Zd66d2SJKJ;q&r1h{XXKwuet2UjWb5qD~*bFqi`gABcG`3=w{X6olA{$Sms@ zoG^7K0$;2(hKA1t&=uP6p*-a9u>em>qKD7Y*`SiI9<&QM7(}Q;k9xqqBm!KQfo6pz zc%bDVxPU{g8u+*Mf+`eHIrs*2Qa`Be11{ju7e-74)s~=g@BlYx@ZR+UZ0!wbQBrq{ zBk1I}w9Xb$2T)b_XBKG0-1h@`(;s-Wgd?rH$D>IIbfQBKM9qy^pxH!?PmtNfrBC0?{ zDTpWl5z!zb3`7Ki2pngftL4gKv&m*ch!T=kKW(I z3i2>$r{r`-28Ld+(?G*nKj8b)A;kiCUx-^AM=t-rK_pFS8CMfQOFX zfajUF_k#Qh8uIxBno{*x2ud^}ovolC>uu%v1iIP?k!D&%A$bZkeQW@}Uf>OQloe9G zgDslE3(4>xw}96}xV{0cbKu`T6=YaYH#iCcUff>*wFnd=y}h8Ig*q2f(6Pc3=OF`# zbHPRFKu6$uf{%176IU0c!BW_T7U5 zI_O0kOzc3w3oZjtAb?7bA0NT%UO-Af>s~~h7DK;Bz|CF z%D=r8qycUosLJV{3JTbu7t3K9KwMbZfKGh)`2T<4i<|mj<3MvJ-L0Si3V2Zl(*WXT zF+eSb8J7WG+5?)=dC?6{BXF19I|44+I$J+{1RY-Rv3jsT+Q@NSUPLFKb2L^))j6R9rWs0R%v@W4ALut8<& zY?$bQfGnmLZ^1PPII>?D!eqc@Z!v_I1{r4U1rN4@(kI9bFP=dbH$kifU3c~V|9?;l z0$CF9!UCcd5~H9Y(jZto-2-1m2a1U&;9U_f0yDA-rWd_92ARSSc(E4TE`!!JpaJD> zNGlO?_&LhLsTT*Qg8CxhRb&uT8epcR!%P9SLBOVfyB)nD$V1nlj1Oudf^O?Bn+l3} zP^1NQw}K)Kbm<5vv2{-crHr5#U%|B@YNWM-qB@|v7ZmU4EwQ6m)T2f+Ggt+INWQld z7Rf0GKr9YO3lk}l&*)%_;sblM{*y8haSnGHd){cM#!=;h?QxO z@%6OMsXCwj|9@dR1vFv}8lesVT{HnIPXb>gKq~Tp?x`RHf?foafZWCdDgJOp186`O z77gzwg9;RAaksq{WK+P4SK1&`z^;d-v=?mbZITJV)H zppp_kaRFT|szV&P{{b`^=>~G>wpLIN6f|X6&dk6-e)R~tTCH~~ zs8+^b#>1A0L)->mZ;3Q}NT51+5f53@6u`f|6=YpNcQ2^%5cq-}d|9AKXDf*N(&Im9 zk`NTPL7>?|P}~N*XfXl@5nRiWLJ*$^9LSI>3LwscXH`vT48T5717Um5dAw$6NQnnpL1i)D}>aDRAQd|1WGN{{KG#+<41A#E{kv zY2<*fKm;AN_y)SB;|=I~MsSKa_>h5r{}f(uQ|J(XFX+De-d2!t(3Lue_#1X&Q+Jr(4Kpck6pRSF`VU@w99Fhfgo zM9y6Xsk8%NTAt;D;sKO%!483xo>K%N4)F!Wr`HRk382VrHjA z7&KC0aSiJdpn38GI0Rlih4f}%im*ChWB>pE6F_m?da2YI+KcaYKWMxcWYkMV(3JpRKmY&#@+62j1v=VkTQ6vY3ba2K zbk_{1jZI)MWD0073CCav|F%|eU*Q7i#sE-r6g3(_i&4L1A4uqJVTE|2^aK3H04&|h z{h;obL2nN)#9O5w(z>A+S}gDT|Nq6LK2Vpa60|SF7qn%48+fb@R9tz2#%pklckyon z5B`CAJxVN~d;khW&_L;npg!ml7f{f>Faenko*n>qozU0+fky$YFVqJ2_JWjyTFD?E zAjJVVo+0rIT6F~RFm&JrT2#QAtr_6E^F%sZL2h|HiGSNvaKU?tzoiE?tAggyLFw?t zvflsyUrg+U4JLz~h@*E`Thlugqz6{^_D+F@C$unurk-wS5@dwr0TfBl+9!znL&57{ zUwntmnq%a|`QWQGU^y`pRL(*QK15EG(FJD~cutJT0r5d|yK}&;ZFnIHa&zE|vnn8I z)Iu~9A_mWI(DHNpRFDZlFS;O$D$+VzL43kds11oE1N7nuv=kL&0yr0`_J9Uuci~>% z1|L&A4vw-lu+kOOGhG5IT|amK|Nr7%Hz>+Lxd$9&I8qgV?{o$RhTdL~zQ8QdUS4cz z>qVk6G;F}*GqAHkAn}N@eE`w~fwTo6(Tx$KO9Q}WfnpSFYxh);4}xBt1>XoG(%A~) zzVyNtqh63ENdQcXRW`^dp3c@8s1XV__r)J2kSuD1&VYzPBNWuyfkf$x^AHJ0PY7gO zz>6A4+Z$p!I6A-~i7WA&gUV0HX)Mqbjy+_0L8gONCHr)NB6{6Rsek|fzuf;D)UP=k z&?~C&&XwWCf&<`5e(334N(Vu+{Gho9>o+f+9)L_qOaPskqw&s_0o1Vvg?rI^R|Zhu z8^kVn@5%t`9)s9yZD0I`kUyE1^X5Qwe%-jx9q`XIK*dshZf zUIv-Z``(oSRJMXT_bl&S89|Ph|j4vZpds#iue<#-}n= z#HTV;F;p^CfX`8d9zO<}?`eKh6W&|fvQr*$JP~3S6wdq(KCH1;3Y6JFc>pxc&ePH9 zGqvMIWCtk9&w=Z{AK>NVKcG8bPYYDzE7IXonPisfu3*N7u49!P4S`U=SfnDV?wWHJZLt3{l z_}b|g``Z8if3dP1Im+$_; zv%p7Jh8J`9g0lc*or}Ug6^7;`HP&xlJlhLN{%I3HhG=|rW$5_-|37FAipfV;hO)$* zQs{BGkoXe`3x}?lKv^zP^0xo~Un~L%w;-wA{n;F3&(X@Agi(uV44HEp$@bXZ(^rU zy9HA{QiQr+x%a=Z~6cK#VZi;6hvHT0i|Hjw6+XrhbL2W4TlIr zNn{3SlL^Q~ERIK7qxJ>d!g}!<()tFe&%P)FI!cxkv{SS@L{Oxc=MyN?bg&4%NNoW% z7M($bI=E#22-;5qs)xZD9`&3k$i-N-h4`bp)~7p^r@2app~MmDV9;%>29T@OAdM){ zS`ZPBpcfu+Cw|Gk$ky%4!yKpsDp@*MxL%xT24(I!FUvvmnV|FiLqCD1c(1&NCFd{# z?ob339H2-5`Ms2*Yl;|XS${_eBlnAZu;Ir++sS=7y1+YJI|7tnM1X`}G&O^Umq2?8 zK7xi5UVMVt$lr1lv}z%g1L-2W&7f94s7VdZMyTr+Kv(vH+SC0E3=H66C#@6PwZP3k zS!%Pug)F$nMxSjB{cL>-bTbtqIe`4t?ZP3_%X0y2Ea+I>{h=u7zB@!rq*vq@=sLwN z7RC-1qZc(zpzvJqy76V`|Ns9%8*N3b-@I_!2`Qhz_p>*?v0#Rr$9>|@|NlEd$L@ej zBjoeAkGZ~JIOh72;h5`VhGVXe7+$C}{r~?$9z;li2+=0+?u<^?AE1&5bYVvz2RPo& zNPLcf4jwY`JIt^~Ns$iB#M%tiDCT|-xywmp(!rS<=^M}t@(#UZOV(R z#{d5_KzGc541;CCAK*Qr`$E5icduCwhS)o@*=zTcXE zO7Qm@ppnU8e+>nz|dX#1AN)%zS8fI%Rcv&euH#)5nHK{b;I@r>w!|PW3FEqUz`KU9&>%jc+B-Xa}c!N1M*JNRlZ&}kn(f?n7Mf|djcbhthQrzqF&;DXFk44TruzsLib z^LiWqw$O*ozZgr|Kv@}dqxmDo7r}LqEV<3~5m?vfSI{It^dFo4Us27OU^*a>c#t7(D}E>NV2+XVU2|J2X1|2_gX@^X?FJI+?+=2>r18Ao5MYJ{8e<)^L0k159 znej3RR8A>?!Uc3Z&WC{BUXX&o-l-tFf?jaef+iRRI$R%v0v49OCcl8i3rBY-&oL&3 z*KFOcJfI@}WHqRs5a~8Kz&Y7^=19$Md2n$ zr3OCpbq+`|^vu@}e_Rn?NNq&4ueo10Zd=cn| zO3-3vP^T@wG%qDSIX?q(uLVdnC9^0jF()$x)(HdO=cod%FFRfDbhbsA_zZ#=i|(HEt9Fhir%IYf!BFVrfZ$lf_HePIhq940RhJI4K;492*N-B-!oy zrng5RfDg1TA@m1q14c&`=m=`a((9Tkydy5IudOfCT7a6=u$m6mQU372k>|dWc_aA8&KgG-n+Nt|Ns9xl|jQ4pwSZK<}5hry?7B{ z{{KHX?{&NgDF@||C*YCq2#_!+jXZc^3vwP4fJnAtrq^sQ_N`Q5m|%Redn!mM zt>K%0SAXCNC$4~S@?VHKx4eF z4RektFuag1gA4(+g6=MU@wXH-Y19j12X==xfCk+`9^~H+@gR)f4GD&z7jMCr#R<%4 zJx~YA|KJO7Te`qOqQEr-w^<^^u={> zs%8mzu?|w3gF2g?F1;sSA=B%ft}8%8!l4U-UhLL!8{ZXyFV;iW z&vm-4c(JAA|Njj6*4K>Pp(}!3Ytw3)ADG7MN4iyBcWqOebY4HTSNPsfBL3Rftte6Js_<{yYvkyVe1WxPpVV&^e zV=<`E18tw*-UQkr5%8k_0n}L~#u*de*06&rNRIA_AWMT@OoDWT0$%(S2Ky4Un!FJt z^kQ$Y@Zvzx|NmJW84N6-1KZF1|KAHbgqjbW7D~mz4i9+I!wX_S zmV|ED1KR%}0-J|U>vZ9r@S?it|9{AhZ=eG)d0}4RZ*c?FggAzLKqZ@D79Xfp9`HgE z;v>)m_K)t6-V;GDzC&6rpcD_zM(QA6yxs-&B>27@7tslwt)Sw!8C(dn@V7UEhERGz zLjP5IcW}5tj+TG%;!Yu?xNz-waj_5-tyN&>r*-kRF95eky#-|zaO^+25g_~^+jmW&f&GZ=b9Hw0xd^n&h@HoOB0UJ0<37au}GR~DoX zJc!fsLa-2&zQGG3L7njJA-ofUz{ev>#DLcF@PKlyZ%g2dogAPj<4EgtZF#{9)&mYW z&~VOnAJz$hFDmXrvju<4Oweu}0S9Q=;C~M;(E!TE%wWqvV*+4}-Jv`|FIGoGEMw;1 z?%ERY!Utg)Bo%-TN@a(cQ)0uvKeVIuQk@C^cGr#osMq)rPLG9{#=qUS19Wm+OVEqo z>~Pnob-T7e_Iw&}xG}t#xC~Tb$3w=#MV5nF=Aeq$`pt{$%OKS^zdQrz!chwjH--<; z`g<#f8^ekJ|Nn#HWd(;D!v-jO35OfQ0;rma9BvE~{{R0Ex(B9&!;K*)Ej1)R1k_r0 z%}XsxuLRGuctUnKGUR0Dr6v~nxVa{lr4}Wor-Eiq3dEW0=6^25!=W@2B&Cj)(04jfY*r)_?$)pP=nKo#4I>c(}HUqXRTf&(qD+ z<-ye9`-y*hs6r5EJn=KAZTBK6AJh#3Edaal=l}l~kMltDpLw7p1G@O~Gq|@|cN-qT zk658gmB9@U)Mh_ygmEXRmIimmL zr-DTI_q!@sU#N}i?FDHDw_`wS+rb{|odUjWfqy^P5b$anP_34ID1o^Z)Q#fb4>k$Z zQv@wC`t$!kXvGld#))#4=zGpy_T%l(mJ?+pl{QF(cfUN_sz#lX95X@UpbUS3 zf4lF6K)A&Fi69Bkn$A+ljeMQ1H^3^uH46XsCeWox0WUgOKp_cUWb>j1#=a1gW&dIy zgqPOodgXYl%HRK>nF0n-Q?2z2C>`|Y{Qv)=DhHGfKx5S>!2Ub|_2&ux{jMkY_xnm% zAFTD{-yeG7c*|4)s1YD3P%@?MaYOT4#^w6Oc6;AZvs{*1Vn% zvK;HVY~V!3-@6Rdx9SDC4o5J+`N~>tP#YOE$}ts`ZhKp}KqRdA=tg znZ_4n7AV*xKtolGpw<~A%XCi#xd+skJ<;9M3JS!)7tY|#{-B-|^bo#oh{Ziz4xnS_ zK;>QbB?j>Jm=mBb;o~e&OBv!n{{6lu__t5-1%+B#JQ7iyn#s^x32AbYOxB-5C^GSwI7OodNGeIE*@h|^&*DC=p zwlhN9zx@PgT{_6zpclaqv9!)s5FZpmU`D`;E{FuEOvYCfb&GHXy^sU9uE57rfv(Vm z7FmLbqyur0dL}5@XyP*tR`$d4@!IR@*flpFQ#Yw|No*1WE1{G49fSuCyuxDf|4xA2v9L_@loeg zP{r507eqqxec5bKzCY023ld7}Y~cl^%oheAYotNeyq*uvec-Cf6@9gU3TRBl3zS>n zsrv_L%o3I;K?x2t@&O*R1SQ(+iwVr&%mSXp16`T8eJaRbphfzB|Njqo;SOG|2+Q|) zi#Gn=)1c94&`MwM9uruqVg#jZkogB6urOZ$Ww>sUE>I2zPfmj)8ssK$_Lu=#HQfoW zX(0|YfM+Qb*Jm-lxcyHLw1NSeGeHLTLNhX21qljk{_QQHpr8b`txt4M0mnnoiwy9+ ze4y^mR6021k0S_Abzx0?^U;U>8F-VS~H{xj@t5MGsgb zXh;-1&;c&bLa|f<{Jo%^v%Qd9)eSCCQ5{tb-s8`+6Xah|Jq)!FTta|G>JC0+K@<>T zY2YjhjxlvN?c>Wljj36SC)V0%w6KuggU za48D2_aG=NyICd#yvXGQmjuMQvLF={sBgdn;-O!_ZE4V27FW<6r~!~xLiuJ+T99p$N{Q5u* z3U~|TWew;A=upr-Zg&D+G)@3XVrhnCbb=&6&5(EfAQlJqW(eaSa5RAm&KF;QL)qYF zh&eQ23IVkAws$J1pbqK==du8>;{V|7 zyF8FYehL=%J>aSvlsiH7=IUfnQiIv*dnNG2N`%|^w?hkkSBMx=ZO{v{E$~GRL;{?| zzP7ivP(7dqaql4pL|Fq?bvwDPYIpF>^7F->{c`Xb3-dAl{iP?mdAd4zHoVXU+4_3IOGi-2beS1?Y9Tn~qtye@ zwMFYeYCxk7;F=9>!RLOkLqLtIEns(nE+s>%3Yu-27)rGu1#kkq00vdYpu_-~3vhTb zD-jg9d0+!vzkqWtsJsIA8=!kLA^nCg;9Q94H$ZZ=kLZgR?uq~Zzi>)K%GIGDL&554 z&~KR01+76%s0Ba);RGfpd(T#XemWEVC zkOtnh?{J^+Z-yNLd=1*H=O$K;;y+78$5K2W|Fz;m8bf33%@rXs!d?;^;*! zT>Roe8Cn%v*8$|%?qu_Tqf(|Nk#e#ln1!rx;OUX8`wev351L zxqb$fAx~iwr{EC8-ssswWaF^eri-CQ7nGbJTa^(-JG7jE7oCkZU7#V1I`Iq#VFreb z1CM7jWEeb|&G15~R10)E4bC|8{Q{3Ia8qUyI2nT$s($I6a`phYmEwCMt&_#;#qt)#$9rzc25oUqzN(FUKz#~g9u0(@3_xOVR3NhMMgMUAd6X@b&&!Hg*>2Kfg`7gzy!1mQ*CXGoy|a&HgRz2E^a&<+NWHdjzEKr9Q@0QWv# znZ$E+UNb7{!>nZ_i`hZ5&0$*%A4h^>weo*fS ztmDO-C{WaaPHTY=AtF*$Zx5pb2YBxO%fUx1%%=iDo2NiM9)8fh-k?ej8t?%xrhtzX z7kK#}Gyrov3Uqr4Ska5s$Dp?Ix72`_e?e}LodR(vcwAsR=+anWnCtjkLO|=cAkz+0 zK^gLeJIIlsxWSjbBoPq~syZ+$WN_b!2Vu=)a9%?SSXYU(ZXc(AX`SF&0?B)@N*k1H zdV9d>mVbY#L|V6qKw4)=;XhCj-rI8&6m^I?8C)%-b&4>)=!pFP|3x#1r~?rzBOw#3 ztp`d~`1gbDYCTyh364cju@m${{Ua_sQUgdeRZ>r#-4 zcxdi_eFWxrcd&2383)u!Mk#K<7j*SbH2{?`{M%iB1n_V3{S2BhkO=B+1;taqi$_7A zl1AmVD?cdxflkZ|{Q+7m0&Pe`jt>J}3)kBVG6tmiM-cxu*UzBSVk824r-FF3?mC&+CKy`@vNZXqOzQ4+3sKgIlI(V=mB^I4D-3 z(SzxDP^ttsEF|DTRswYa$myV=*0k;rkAG>M;G_ytj+ThQs;5AUDo}c7VNC0EDf)-x zc33Ypts9&U(?A1aGs6D=e=!+E^o4;+7x22#Lq9-`C|?~=IBEp-y6y=`1H}nw`6noW zgDZ4M6vA%u0*}YAf(jr=h`;#o!+@drhytka!acCc-^&HMA_lZd{{;VbAJ;vBFMb?^ zCK>(~Z$<`&7aC#z|7ToZ3@+GCbi0al^GxUt3;ATsQ;La#Zz>A4+?V{i-0zubB z_Bw!D&M!eHe1UHX1WkukKm@Z`dqX>ddR?ak^!hFc>x z>V00E4f+57#fcD5tb*?N&0_6!?Fi`gof6m^x*(|6bq!cA)WZF)@Ze+ti-Sx8g%wBO zi>r=EP7FQ4zuhHt4=9$mfUh}xQDzSg7SK=)#9uHLOJlbeN2f;s%*i~U4Y=T72RWXl z)5+(B7RZUJU?<)JW&du_{xAm>H-;AtUEm2p=vqCdZqSS%Xll*+&5NU5kQu=Vd<+Z> z9w5d4|NjTg#J`kj)K-G<53UqETMb!_@Uy)02<;3iGNUWWAKSD$t{3y^@`6d&W+E^OFMdkS=LZwjvis0qCvI!XXO@*6a}2p!*R0ZYHI3Iv^h5ePb>$pYjr z&{f-Jf#?S${RiJQX7d04|JOok-Mt_NWYP%Cz+^McoBkPPsXg7 zGbKUG_a=f4m<@VS23ZLOUi1SJc_Hc#&QfXJO&%hklfGJgK-)Op`+-(AbMSAU2%6Xh zozC<38QA$CuXOwN1VR=^fwTl<$-j62lRN>E=msBV8}Q;(IB3{HfPepq)|0h1pk+#~ zJ)K}V{_S9&gA~K(j(s3zfYu##Hi8U(QRVml|BF;V&~Cs`4*u<62ZA~+AQuL{u-OI8 zl8{T~`L|C6i3fofHgGyN?%w*#a{@$0|x~-3_4+TMZ{!`<@26=WfJ zR=ykJc!bq2UiyL)RzSwAnKL6_WWx-51j)1rGZ=lrX`*=-D8Lv>3bGh_!D|--5N3e` z4dk-G7tG*;0eAvlL_v)2bZyCE$N()nj|%chvE3hpe9L4s8i~kpwY$M(Y9o z-esT*TetakH@{>=9;$xD2pZ@Dl|iis_nRGdrh(^V8MVF9Od8wC9ShH0#x5@?*&nTXo?=^ zgA{?vpUg54i=(qO0ZBDD?ZI<(*&}GEod|r91!IFpcGp07X`QVxVBO$=3h3?y#Q z93%?5D!>Gy4ixU)y`b<3%wp=E3bHZig~WTX=>ae1^Mi^Sj(`_o;Hx9R%W^>*u0flz zKfF-%0wpWfmmmIu>c#+A-6#bT2Bkn;n;z@HlHfW8W7A`|^{LuO^!kmbDG+k==^+Nt zo=!nfRAin6?G)|~VG;n%I=cSo_Gz*ReDMylkRhOZD#$rOFZR6z`=qlK#C_fWG8eQy zy0(X*#J?9BFrY#gs(2#!Fd`m^Vpv)QjS@i8^b5v^V8cM=-ixmfz-(wje64sKYy&9o z?Er1Vhl;=8^90?0>H)5ZAf`ZFmc@v2wJPWY;mk{5AGvS{Fdsrrz5y?8fR7h}=5c;V z^NR7sB9O7Kc_Cbe7n4!BEg&xcwyB_|7-;k3Vs-`w=p5yQ7wsTPJU!@c(D11zJLotV z&>$nIwRgN#1scJ}TR~fWAYwdFu@|Zy|Np;G01?t4LJVvHzQ&s}69YrW7gR!axGh=3cx0?H%cnGcjajvhB( zkmCk4l-?cEVG;DA0b*ch>l4sUJ}?QYNI`}MzDNe2^$K2?%fG!9noCH^cP4068NRtQX`W(5ajML8opOL8|@E zR#1}Y23rAI?*l6CUxdNrK#8P#D#!@X8G!#mi#4oZa-d`b3cT!#h`?s)0JZ;ME!FxW zP{{{tsUG<9o=5HG@E%1#8n_~OEkq`*v-JmPH5ix#9g+ACba3Ye=pF~K zt^C`kf|Nj8lA!i)V3yL0zX;P_e1x$>~WeE_>9TTlSJlQsJkL#GQL2gn#mhJYAj1T#jG6k{Y_ zcsYaidxmy_CP4(47#L6r5AYEV{4JoS(ec(B{~!xAUwn50O>yBa9&5|NM<~EO;tINt ze!uINZXZFBUXg>K`Z0}v8xIp`Fz>~!S72YKb++CC%@J(}Q=svmAIKR^q$B7>0AvY6 zKsVSW0WTJS%R!D#F!v>BZGJDTk^<$CAeg!nilAZz6#SsR0BCFg+JS*(!xv_^z-|C# z9RBT7L2a|37ng2=#h_JTMngULdOVN`0WaJjjq$WjaQmKrJH*;7_7`s7#ox`2lUELx#QTI>Q1Ok`hT03B=5=lK8sgdHFO?6+fs_BG_=ulQ=c;1;0;JJ{Up z6VM0-ZD)s`TGH*pCeq9D1AOWN4_60|!3#E!J6_KNufKUY`v<7q&(qBWKH4Cy(*v}% z=2#Qxj&a5pcN{?X9Xo&q_&{qOz-|Ng$1%2=@%I*jwuvC$$c|_>Fo$pmfRY8o?I#() zC#viRH7K(GGr-SN32EX09jJnmLPMW8E4-^()4C8UtlgkwIx8??6ZK4^puIbI-+ zPcg=m!`&gShx%*>*!2e(m|XgA=5fou4 z@dLN7!HEcU4G!qU5yM?zFN0gs%#J#s1{SC}oqdw6yOf974-y6<0v#fTFC4)(?0U)i zA1!XcIWDbJgyV%ANC{*Mh>4XO!;8KWdy0fJDGstd6^$0I5Fi zdIUs)l=Omnp&(ULLA|{foi_jfzi0sw^&p}OM3jPv0uYf6BGN!aAc*h*5$+(u2}Ia} z2n!Hl3?lSwV8H-RURcT~(4vbB?rosC9@jsakc&S;Ilu=rfZN%S+t0zP`Cm9dR$>Rd zIDQQj(4fmcKH$}hxaR|6z<&l%#l#Wtq77~U=p?E@S@AC?wc!b`J2l zE&IWfcZl8WU}Y~hLQLy)y#nj_8!(50N>#{?gcppLL9PTX$J)~yx&bu7vnQb2_X=o& z?M={&Wbm2$r*>)HctMxcZPsK@~A|8WJa;R444 z|900N$b!vvFwHl5p__fPPZ%)!f==Or98ZNKF5pM2><1kP#1aU#H-R~n2Q<3W4Z8Mw z5@h9Y0RQ&ThM;cO3jr@2V77tQZ~tjMS(?^671W9W&CmV7v>3eT+!b`2&jemj`owLO zI@~IVdEKsO0$yAKFI*GpbUpKu33OT(xNv_VV+opOg(Qb10WWkff};Y|5b6$n64dSb zAmGJK=(dLKCjv7}cX(UAI02sE1T8%K13N2#qZe|J@{jCGkPAq@fY!F2w*Z~G4a&^{ zpw_DIlE4=+Fbgh#4F|{e4~ThSHK7}VURc1?8~`UVkV9TvfvS1I4fDo{G{{gEbf~De z7gSgTc87xYcS2TCce)^$?*dV@x%)f&6 zO#Ff7I$sXxN$fwePbTzE0pHdIs&qhW{oa_vcECx1cfi#wfsa3f&Q9+36#-53!jF*S z=!KkD3C`jdL208Gv_D{fC{`74yIjA3l)b3W1f^|I!GJB`K_^&44sZ+o0$L*U!omFi z{|TU(b8z6#2z+t>Jd*$KK>S|~o^Iv{;NK1%^aE`bU1kTeNTk#CO0Vyp!0ym1K`$0V zx)&fJNRWaiG;RdGkiHH!GXSh84!qSCl(BGy9pumn-!C&jfw$fal=ysmKt<4=pcfm? zfsKL`L6GQt;R6waMsgNE|8{Vt5cI+rA^}#s-xp?`E4~6!0NTn&C`XT3nCn1}6EXvB z4+14B(6Qp6%|Hg%!0rp^_Pr4Jq8Qvc#1|LfbA0wg<6?^`$g7|dX}fPj;ESVY!A5~n z9W05yNQ8(%y~@8G5(1zK8g`}zQtAPn)(5cwy5Z~v6Er|TY3UT`#46DJ8t_~RN*oaN zPzNc49JJr{59pYmo#6dUAg>03#%XT^y>NvV_~4SG13WtfidAqC1e)oC9jy&YXkIU_ zn}9qQ+5;N$0To~YFP@%(`VYLL31o86i$;hT+<%Z{1Q}6*9xIMgu)UZ7nZl~{Jm|EDOA)9wgbEz{R9Je@D()Q_b2ltILt~pdVN5rHc3O>h>rK6K&6Gk-xTXK(7 zr-Lm#05i-5bc7?sFz8`l`%Aw-4j%*C3OQ*Wl%5#{c7ShdJHY@dKET&>gJ(3c`Ou)Z z#}JY#O20r)bu4@#Y5f2H3lR{(4qt6M7;+N9$Wiee`Fsp=q}~xZDE55 zf{cS6Ahyd0)HzH9&Dbvg`v3pSy04IPxv}*~z{jzhn4gI-Ru5)u=nv46 z?obZI@ipKIwayS67oge$l)GEFAV($neu1pyW_S^62ny_Dpuk@64|W_4i@O`ci_Phf zu1(_+Q18L|%?qXsNQWkE0w)6l1CKjo-3q9Ga@HNPj~&E5>h8v{1iDsbue%$=3@Cf6 zyBk9fl)b{;jiCX`p6>3(04f4NdOO_Rz%zazc7wYc1E?4Pu`57oQgaK8;!_z)QgaIo z;~_^3gHEafUE>Slf)5!+5`Y{t43({d(v?uU0!o*qCdcQb=EbKXI!&S7Z(#Rf9&`N< zKK<`M==8t;{M&s0H~(bf?^On+CJFv+q5omUtN^%@-sUQjeIkMRVi2+vqy*mP$^(&l zp_>R^h?j*^KPV3}GBAJ^0{%xSKKQr!@?>93fR-KsFCHhrP4fK@ZFsl}fSdcdkGTJlTg}joH8#{YhXqy*vRL zbp?45wLVz3&G98>*z{k=Dz0iYL z017^EXm^JS^g94RzDO7p-(k=TP>;F( z14sBjP=x>E-{$+T`6oxM4F9&!fBf5A|AFS>N;$ej#5zP6Ux?^|h9fS6#%X*xx&k>m z0yto7&W-?17@MmjfD6Xv?g-$9v3WWIcwlVajsRX5o3A5)@5K(?|NmcX1`+E(#7Ypc z1VqdS5wmpv|DS*@ZL)x!`acMC1_vm$g4RU@z0m#(DtQE6Uyg%>gLMi@IDpS{<2dg6 z0~99EZ~&dd?7`9D`yUh_$6Wt19CQ7{@Inb>xh#l~01?8vpiw@7H2!T);GO!Q;`Kkc zc)d9jTD+FAS*+5E}F6zQ4kjd zym$z%7gz#b?3jTX0U2QX6+rfb&vo5~J)~fj88k5P*bi>@LY2L^bsAdTCBp2tK(qga z7TEuwqg~E|j$>? zfn4xf5xo1{^)INm`a<~-*x4Pfe_wcjWM9tx3+tKv11Do9n1X*V)WHe@|AJB(B)Ni) zeB$303Q2>Vpe1s~TL1rNK)ojdzQ+z!G=W<;NFL$=%YbgULy>tg^%U4O0WV}=Uidr> z)eDO?K?M$q7ZMJFHG#a)3X**p2b$j97W$|4QVE;Uf!8drnKm#sAK|cm^TIU&n(M*& zT?Bf5Bl_vLQw;uDjQrbN-v)I1{s{yf&H5+k#ggCPVkeD%+W~NJPninyjvP1^Lf`U(?(Cg= z0P2PJFAiydJjnE#>Gk|97SP)5_uxUvXt+i`u>J2|%mgbeKIZz4@daoea>6m!w@g@E z6$rM-^)1N$ES48d5UcpNfjaYl0)3Bp+77^zpZVj)w(%-t`^G)i2@@QlKkAj=Mq*wVVzz>ySFA0RFU{AofcxP-}=8w89?Z;x%w{q@k`o=K6;D#Z$Ha|6e>% z1C;}yk>Bo6guD6sj)Bg0LUnuUPgt}-+#U)umcL~ND7PI|gJstD;AmSq3FiEoEEdr1 z3H;k8g1i8dM5HDCec;pv8UuK78Lq<%>d+SsYM=@DFZ|oU{%yTfD%b4_isBB4Nf(2% zm|pa#fgHvG3L2qq*DqZi;Gpq+^MV=VIZ*N6?fNI+#nSI!WuU+deb)hY3P`o@n+~vs z?$9sYt{*y^uJAK3yf~@)|No04AY#Aj|Nj%3kAO}rpArMfu;Bcf5fKll zAKg6@Ks8I?izJw)m-|6>gI9vQ;Du{?0M+FBzuWgmcSvJG&RSW6eknt&I-AxoSBUNpfpod|q!O$0Rl1k!ZlnCoYT*PLCUpTR!;4BAiw zUOlbN%fOIf!^FSdtacf<){izOgpK8TnFBBp|f3Cf^M1B+>vF7Rmn3#lWZ=;8=? zu@GDbu>`#EK)4!I-hc{sSX3WiU| z%wT%%_QL}R)D;KmL5c2e-xGl^Dq!0Fp9I;-67XUfOj}9Nao0Bt3JeS{CM$ssG<^Y@ z6ME6E1lpM#`XsG0bWd8h>w~mT*BxoyzIW0(eUGGdhu%o*3_b87Na_Fo7rr3E14KA0 zfeNR`te`V$z)|7*qkBpt$iG40nS;-e=0L!UDwrb_VUFN$c>^xNP(t=h;EMw=E$%Qa z@A}~0g#{5TWI?GrusifZ(2Gu(HUXHn?Fen4L1IuSA&2aVfES@KJ$Ft(gQyv%2NFb} zLbE^-5=5ZjN>Ky_k?(`FPTxIg-Qb|wk=E^cBdyc*2sEe;ywF$t|Nn&+h)@L)3W}g0 zIsiJJ5maP=9h(DL?G*6h^KP)k;IdU5ye1fw9ru9qFgO;SU@A|-R9*;r@m3I)ad$ve zg626SU@GUsRGtWY@fm#jF38Ly5S5^T`*)Ca6#*|wVJZ&t^uC0ecozR-j; zn*v^Jfax}e>An#3q8qMz3;%Z4JD{0>BcSo-EkQ3H>;!ocvJU?Wgbm&UwcU3MNW~M# z#M6tN5Gin>DSHE~1*8l*iyXS*#SMAT*_JCnMuRnO33|Z_ZN!5*6%H@j!No2|z>7G@ zM$Jyw4Os&G+g(=#yx6lHY#_*R{{5j_g1TKd1iVN$1cf5#+Sx7qAjiCLI|fq4(&_pF z8UnCX21?J6{HqMJW7QLoT8@AhhPyxv@QmJzR`5z#P-ufpyaDpw0g(5$1iZMl1EdVx z=X-Gu!UlPde|zW_kctN&Z|w+tu^A!-8nJ#M4jJHx1gv-gg#@Gkl!V!{0J7RT;DtIk1|c!YOyGjJKt(&_pJB|Y#=fTRU+nECS{E2IKmsDfh;k`^k# zOHrXA;ClxYVX(At4i*n50$&`0ut8pfrG+P;(Ap9BVmU+#oEEqtGX)@Jh_rA_1|uze z1{Y+o5GaMTX98aMKz2<)LjaT(R&9ZX0CHLg1z!_~oEF{$yjZXYtg_Sf%}dbcLU2%k z=Vq3})~4!#qY4u7L2z$F3o%g9R0~td0#kV+@I?f8MJp(PjvRLdFJ*wPQF!rB8nhl- z8ajZzW5@q`(B>G|123+EBrZsU%42Z#b=(zFbDaf=pOF6lf5MAL(xBQJ)OdxoB@VU2 z>y9hT3=G|_Zvwh~Uj)85)d3gZ!_2?{ZZ3calCd@~I(-*_RbVtIn86JoaN`8LKXL1xpF#5)$N0CE{)fyS;M3jhx&Snd%K`EPGl=*n_5VNi_7-aUrPFl*SQ&VL{R?#H z@iSt$6I6tQEzSn55&F^#nks=f4K`H*avylAgrGUyp$j@iI$k78{r~?W4n#ys{r?Z~ z_X&pXP$b(yBMsmQ(rv!~)4D}G(mF$DfEA**-awOU5QVN#@1A7nF8uKG;ab? zPzo~1DXmkakf2Fv-M%x@I(eL4?2rVF2ZD%olK=lh!U43P2|0qHqq*Rg3r`cyScc6P zZ3~5Z8MLeqIjUh-!+^q*XJRMM2C#J)sRhX#Xrv2++{XtZI3;mJI&7dA)Y4AtW(iE| zbe)4WxSk;9W+(74HTX%9%-E{MFdSs>kgfh)+yrgB0}Q-{};g^ z!cPJ;qyuS7g`VjYX#|I#?~m@#6P+QA2`}tGiY$>8UFn203gHSbbWUjmwcTC_fzi}dGSIVbpEY4NG9}1T4(5uv~JfuX`QYQUYrBToD>H&tJ*-P zMQnrAPOeuvS-L=J9@O!1z0m2>mGELSNa;Fpkb9wu&UChPfod_h!V{g4PST5ZklH4& zg}z79I(_e?b%*Xr10A{_3zCTd%YYqu1M0{JFPuR#c3`LM|MdU=%L^Z2(?J4>ZVWG$ z_(GIn7biqPH3R>4kojvG;i0jOm4V^K8qxp%!6!C!yGjJS;A@7;mPqq&2Q4kx z4&Hho5b(mp1>8hbNu^V8$eraz!xTM_vH!9;(zga4Jc-y7s9$u0k4Dt zZSe01dhr3)L@fum$2bCB^nud{=!~Er-Jt^DV`{oZz>)T&+gE^pyNDyG%{3$7g)79= zv`*IOj+>q**|be0P39{Nb7c8kk;wC zr1|83&?W0H_6q<1|6&J-*end%MYTV42LFE7DWE_TVP;@}DEshY8b}fxHCX1n`S*u5 zfR^dL1`W+If@YFoVe>){>g4^PA`TLM-olWhsa#KhmQwo8d0_>z-4t#CwtZ_*3qXSd z{NO$k#614(EM5UGv>*Y{3Eu134cTD%Vk)@l1=_^~x|xH2JNSZ*pl-0509gAl;6)!; zFGv}vr~t(rOlcPXi-W76Aq!d@2tHar@P#Zy1E^&Qz5^9B!46G5LH9w*K|#I-beui^ zcHcFirt6xZ7aGV0LCT3MK`$0Tx?rI6z`xyh4oK~Zpcg!FQ|7$<0^0K73XbR{An5}^ zFXn>N8MvK{r0M!Su+=Z*g}`YORG^rqb%XAe_kEMr9r`1!6Ld$r>xr~Z*8^$YzH`z# zeV4pAB>4aTi@hLX2Z-1#2)f_{bouj-ZdU>R?K}a2FZQnlnG0G-2TI0ioh*SbdO*rv z{sbK|wowpLNQQn0dNH*YmhtUCi#uIEz>|PB%naWTuq@;O(#Xia-E~I53m%9xDC4}G z3mPP-0K3w~>)(ro0-${3It66Pizx!2N)vR*4?k#u z6zFia7Y@HnKu6Ke;NR~%#rj~0c*YZc&`lDLXES6JJf6+)qCo?EV9{$y@VNw_qfbKx z(z-zgvT(g{1{wGwR{&ZtgI8U?kgI_OV>thQSCQryjL7>ez?*}AfYyhCssif^b@Jfk zw?7mVW8I|!Y27}4|I$Er^*-YVjhmkY)g8tMU;%UyB=~Xzc<3mLIg9Z{0o2pmF9f}~ zvK$hi+Ybc5PKN^T^5zi;d?CRKD!V}obFZXzhw`L#hOT+h!vFt2%v;R90)bf!84M1f ziHXoPpd#@~zzZkv)+JDWSOHoV2kJWI!z{TF1k>9cD!{*;g)892V~8Bwa&W8)zK{Vq z8oB~L(~aRpk1M2I0J#N$&keK!9#q|1zj<-d71BtU0J;OgCew}K3ABwcJ=2Zh3Y0xL z6LKE{Xq`uIrW?Z+sCZi@9INa`KbGEsXe7hLp_W5+m^8BOn%d5eIm@ zTmU-1^`X=COQ-9PPS-zKOyJ_-1#dMhLgnB-1D$`%BLLdx{lbp#|NjXu`5-I6c)CF{ zJ^_EyI(>ia0v*&3%C|41`2PQYAqrB+zu%Ro`2}-Yrz?DsJUB^!7s58b zLKAM~7myH0p%`4~&+8>1LEkTdF9P9$U--AXerY};VEyLBA7@CUg4%W<3|c<{T{Zx2 zB)~)BAZX`2I3)P@y9!uesI3DnVgm)leipCR1NEk$62un~GQ|+vz@sGY;IzjATBz3T z%L6XwmhgabkSXY3Be1Y52c$@}foZ!C^kTsha9Bd@0crDkkqgrHG7Gc~8oUa`7R~vP z`=}+L>E%VIE6S88;#zTV>gn};16fnS4mOVm>|t;PjJh!ZlrF3<)XMX32W7+*Z~?L1 zB^1a95Fl7x|08{sg5th)EX$pzCFLAo&h_fy5W+1rlFC z%dbIQfaaHs)(2~Kvly~Kar*^yxYUJ!7f#DT@yY`-jDI_*4nDXLY&s}dUhjA*0NV2E zDg(K`o#Vw7PEa_xet;x`nmjj#7mf~~L=X>21xFk}sldeg&5JGvNGeF104gI}@*sD? zfy%|Dd2S3BplM=Go*M(`PPlkb!azNHsVFrKTr`5RD5C8X#(zmFE9t(vIaW<)X&Re0HqAjVXmPIz;Op^nDl~{ za$kikXLy+e-f#>$@ynn9wExQvDar)xK~bgyy8p)x5@r1I44^o(04asWQ)Gb~!wo1q zpn!0kf%7-o`Ydpc#9q*fSYN0OfCbSXSP+$$Kx3}N2wWyXOVD1P3xO|A{{YWagDN2K z$(i8O47))c?Z8jqfO$OwvV?>Q>M3wCf)k+fAGUrjt=m-qxiSQ2Y*-b*)BJ)FTqy2` zY$5|4{Zh&SY9cX#n@ES*Kn46U=qk0TwvZ5nq*n!K`HcOtQMAJD1vu+Ic~Qjn|No0z zHc&PT6$k>|CD!fB11Z11?}8+U{jMUd2TH`i$p)OpL8@M8LP~dV0Rl=7ptSEg51Jkh z1iY|>u}=i{hJFB>{NgJ(6d|R?gV#K1-JuVlrN#sP{jLxA_xlPozXUbrMYK;@AFPdl zlpU@QK%LAFfiKt=L(2}(*)Ogy0$#Mv1=|O@_bZDLRLuB30Cj6V1iiSu2&xp+3-Wyu z_#z6f^vUb??ogSuZr2xSolM=n3Xpj{!50~<|Np;8W`$oY`=ZE=;l*WZP|}4IHsLm) zl&fI<=7p>cB-|%}>YNWnkbA2@WzC-=q_hf;een5f&2MVLduv;Ef(`-!M-=kSlWEWGDkfKCPp2et0DyYd9QIIski z3_#=d3%~~6cwq;&0>@f%{%xTG)~9MspxFzw@*>}0;b^f1FAwVym-kBO0%vPKtl&N0$=>fhXq6k z|NhV$t(WS2K&_x|SDAnp>)wI0C@8z~Zx3AnzI{soS_AO}fvf-z9Bl`eUJ~H2z7h07 z1IcCX{QF&Rv>vFl=ilzTAP}^OQvkGPh95LK(;dnI>N|W0==N0z><*O)da)0@EJp@p z5NI~!{w%l`UvjWBFuc%XhBP94RRUiug1cJ<)cOY9)z%Le5(JlFH(s1&0yVhLz^;FR zMd>!C|NmcX1j&KbVQXV;12ro7dy%VzAKjq}-JqsIJKUbcUf-TT=$^n9P=Km{swEy! z4fLbiR|3>1fDDjufS51(zyT!#>!DrXas2nU17+-%~!zsV67Htt9!SrLZi(D zP+O`->P0^zG|Ub z?+%p!)%_4A2Z;H?3)~El0jHqe&=sJd{s3CT4Qd4DnSj$P$dQoB9#71I7Q8{T8fdf% z60>VzE-NX+5wpFnD?ly--J}Y3&TdGO<=^f*1LXD#K`%6CAVsNb4=7a}349?87d-+V zAx1Z6voYA|pu^8Vqam>9{*w)hZa#2y?|AX+|G)neUduoaKk(g=)(sx?zwqMW|9}5q z+yTk*Z--1IUkH4$2d-ZY9HCp%x?L}T5(IQ$e$R_lAZ<%Q!~(Eha2degw-tC=b*6;g>Ie+fiHw|U?EWl4M14C9F|1jaZm`soT)|}oPavq@@In#l4p$ja z64?VvJu0B%_6$b*qOCI)zegI7vfZAWt zhTwPuIji{)=zKYFxTEe%gVa3yy(bajj;MWRWkJK8zhw!yU*yUY0P-_5?}63_g3C50 zm}gy8pp71IX66BRpkA1K1G$+8T9bf}^Hl+Fu=V8$eBnM78t4~-URcA}Ag??Ke6jlj zNTUG%_E2cC@In%%0u(La{110So&ngiFQq{-bPeQMaP7n22Re)z6vg1(qcTA+u097V z1POtf-(^$44glo~aFGB%FU(b;8#E#|EfXFFpo>D`>2D{f>5_esfjLwn2y*7c2?l1+ zRLa*4_+noDE67hgpiIQS-4`w9tsrgz)v_=2U~Fj2uX_*D2wJLh1Jbbzsc~a?kzoXC zYC$`8uZ=)$ts3h$FE$!M+gj`l3=AOP)HQ^tfGR-rA(P^ZGt=`j zk-CoHR$plMo7lr(7K9*z51J_B;NS1dV|}omD-CqaWoPK0*BoixuArH^KcJzi?x!$A zL%ZK}yK=yI(Dr2vX#MMwo#KcND{Q?)Ex1?B(aq86`=mScNjFoc>zfy#4dmUvPr3tH zfn8 z(F@R-ATJm|$0+^=9T)ZubO4&~6aMXiG7u|58$s!b17uLAW5$bXAo%ttFS!d1QR+D_~IF4)eLBHA84U42mf}bjDQyk2o*@8 zTnNz@>)`tS@NW-20&>HjfEO02a5o4tLc%k!pfmJ9w=2hShXT+FOwbVA!G}zNFKUZa z8Jdrw~rGpd+~< z$8>Xadlqz;9_SXC2AZ+o4>|_?z;PDP>AeiE4}v>i=oh~Iu|8NEm?iPzT_MytD?p}! zqQRq}+jT`J%f#l|6>wKofVWJsysTwmV8~(vo!k#Phn=I_si2#uBk+Z!Hn?nhJ-s{h zK+ub9h>^!#K~wPzFG07;@o#rM0;)3p1irYN3=gV%pc|n>L8f%N9su2|?FbF3&_4$s zF$KK{f*924x&-7d-zA+M1x|;L|%gYzc&`YPlLFI~m_2(b!Q=p&%-*kEc z6y`zTpkiqQtti+J^2dSWET9`(ph1OUz!B?HwaSoiJ^=3BbQOTZ3@QW*=c8cH=RxG4 zp3nLZa(M^nj+y3zCZMi%^Pw`(2vGBZ640Tq%?Hy0K|2qi$?qY!u?=2G*d6*N=*7Yy z&}cPiCcPVMMyKx`Sh7qDco7T>$r3(r(+a$1)l2L(5BM(KZr>+qosMEJVt<3qe+3c6 zAR-S$Wc~(ilmJ<4X?;pm1IRs7qT0$%({geK@xW&Z8HXF!qM-2^JL__u=s>n=>1zXfzk z6et0LWkCfrx;FekajajrRx@`v0M1}`)&ap{}jx>KXgy_AsPPtzB@86 zg3br)_T9h?Ia6Z`sF~~I1nN~2P!jWk_2>WpFBpD;`ff8`X8!;G|D`#o<_Ue!%>-Ik z-Yt;U8L0E({*V9vL9xuizuzOR+x5-N?>{d-0G$BMzuybW2Oa0~0aT8D0j0$spzsTN z(eA;=(0oJ&7IUoKt}k9Qce}obk83^>WBukuyB4ISa0Xf*a)gDW@7M&Nm=`G5dZ|R2 zf4i$d0BEzSApdqJIS>n6e}D!!U&z*i>M4P4UmmC!Pd7)mV9*Ow8&KZk0ME8Kro9jY zd4#z;l!t%2Q(C}_PD zbLU0S02pYhr<;YTo2R4G_s1?!de1(@3{nb;eikOM$i+we`%C|H*K%}=h<8Jl^MMs! zWCopX0IIk}1iO8IfX;qz{{H{}i#iZd33A8F>i_@$gTf26+bvuZIlK^!2}t-6;*;85 z*|FjpX#atx3PX7B-U!YA|97r3WnjP<2{S&>*?Q&5|Not>H?I8upRoc|do%R*zPSiG zI?^-<)GFkGiB7dS4?2QW9wK_Yb&4kRBt>0N69jbj<_l#IOYZ;w{|gx;<}oxMU|bBM zkGGbgPPEX0$%K23#$1zUT?`_0UhRjBm{Kc=`LlEAb9ArcZViqA<)zfAO`5* z?G>8;|Gy{)wV8@QL@uO318Vm;Nu_nR?g2?hfX{L41+fFO7<;GA(FA!u31Tj!L6(-* z*;@lrs{`6v&J0R2O`sLC0WYHCplP#26Gykb)ZU;t)tZxNP|VE?Yi8llKSEUDfY{lfBSV5-Oj81f(d!)q&ExN7;s71i1X{7d(H+uQ z(HZ&!oQJYOi&KAeyKo6~f=+M&E#}%EDsu1jK*Km9 z2OltX`+n)32)6A)(2M!z-~(5|MuHBt)C47EDVRp^Shh$2TnEUA51?`hG-m3u668<; z&<4BiUXYDxonW`V@c#4vKWMWN5CBYP^G!+R1 z?W=1#V8FnDWb2DeC$Lrg+gm~QfKDt1=?i?J2r&n=6SA}E6sS3R{x@{|7_@`1(~;%H zzTcocbSbS9oL@jUU4U~8Bqe~E&@9vZQ=m3K%Ldeo&pgDy&%n^z!+K`|Xt6Fo14B0C z@^P>knTJ5DrkFwN<-sAq0n+6AA@d?wQ;X=8kpKU8g4p0J2Q@wOB3RR*fET?GO)rc8 zgH~;UoypjI>OUwLI|FRGeZL%cbomdinK(c-)0edF0KT-&zz9%K`hH344vb3c3}|Nk$JgNQ>QVlRl;0U|boh;^Wb1LzzvaCkuixx^fF zT*Y=*XiS4bKj=kiI~Qn@JBuNU17ukTNKxR6{e2)&9&k|)I+eDC_lwQ{|1Tnb{r?Zn zuMlsDym0^Z|9_TuhGtAZ6KJzwAWP5-mQ8w~wLJkZy1~f{yyEJ``WCPtI2am>%orG6 z@ctq)!XR!q1lq9Q?ZPC$zkfoL83Tj$soI(>CeZL?=807d;H(TPpLc-R;H(TSGP6$z z@^2UM3VLyOGROrG*C;|<0~#2}5`?4#kiOm?R*)IHKy2ickbOw7m&Y;i#Vz4oxyIR5{?3&aL%4t(Jy2Ufq6p8>R&ptr#B|Nj?aKf&`GA9`Ct zK~)TFX$$iq(A5y&8Xi>Wae(@vSqxdsSqxAp4=%W7a_L}H`?l)k7hgT0PD9%7@UOyas#M;{;+H>~*|D6g93=H5D8-OS9f5TwIG-${z`y>PS%DJte5y8FS zwp9stH(2w_N8Ahy;8p|weh-b-lO@{FJgz%)pox&qXv z?w$x*Kp6C5$_h|VPN26H)ba}G?FF@=K%I-mLkk!f7=n6RLFR)rfc5il2e-UH{BFT+ zCJ^0xumYsMy9s1oz>6dEK<25Wb+&@qbo~2!LFTreEKvh5I|naC^hg6~Xg*W{a!z*# zNMGQKIcq@r1hPP9K6gW#Xgfk+O*BpLbmWT(AT=zYuxr`@D#f}xKo%x>TLyi5mcLlTn2Ip)TEgv(Gitov~I6R0KyHQ_;hgx5l8-Qd0fq$>_)^6v+? zXh3OUzekDn#ac~-NVm^~3Q%p+4K^^~g=#A}dv$`juQ$II2KD6xyO|&YFVaAkb@zfS z@9dobYUhW10uS0W?*b32m8gQkwFAWNp14F6wBD@g06!?>v?hR5i-Gh*FT(;0u!01- zLpfmjWzqCE9y-L&z|c802Glj;I^GJRK?9eFrZz{n3s(g^+Fb+$__uqM1$KjVfcoz; zpy&bF1&ZEoCjRXnD&S%Ubj1`XTmvYI>Rxa_1-z);iYKlU*%=tJ*dZb5BoOc-AP^eC zC5Di&4D6l?3e2DvW{{={+&jJ;-BScRKtte84liDQ03G`Y$xhv%@g-2=gD1KdUY|fi z29RMka3=&KWI!DfcmW{=YJ)o|1b~kF^p!Mw>-7Z}fovuIN9tT~VBOuV}`vs(>^-`TmH@I)z?V->;71YV@ zc2eNqFOYqRjoA@&j7WE&LZ=f8s3*1GqoDO{6yWWF3P(Q$_-StPe z2S?zG@BUEFl`3?He&OHm6b5Q4^Y0Ig33_oGCdc2h95f;f?xjVTfsa-A!oS@qA|T7C z+ZWUy12t%aUcBxF=bQkLBfvv!zczr{e*&P}l|WrLaBCc-A8f^T@SMjN{_P$Sfmuc% z%eOay%n5k07-|lvlI#VIQh+*3jfb|_FfatYc=nzfJOBj_X7nQE7YhT!i!1N`|IbL^ z1noQh((U0A_~Nl2%#WPip|kkolk* zuhY@#Mfy8XCFluq-hQWo)&nJi#wWquFfXSU-e5Uh6r&7~j5@s;#V8q&a!_QVH7@wK zvw#M{z68GbWdK?*#qmPu-T(hDc;A5<%CM@%lz%_CdIQaSt1v-kGQjmI|MsRe3=9mQ zPUVNd7dL#MUgdB32ij8uI^Ow1Z_89fE8!vo*uEEX72wDMbpbL!O?i;RG7o{8gT0sy zc}6i%M1qboNRp=zdrJONgN(u4(z^iJ^wHC(~EGEaaS ztG!crK@C?_5m0j#ECOw$LQM_@HBG_h9DK;yJB1h2AO$N!G(%x3L5)wa%Iu3Sy)B}k zCMTGS($GW|0d=XsBE3_3LCr_7$-O!2^Emq^Z*0s+Oo86N4vC6Cp%De1<7Ok!FdeC4{3xdJ;Bf& z!X*H59Z1-v5n2JCWaxI`5a{-D>GbdbwU@wcRQ~;7cY^pXT~LJ=8M;9=HMH#a>4G}! z5<|C-pg>ypgbD*tn_(h|dhzJx|Nk%Ef`}V0L5t8px5+@pQeQyEQX%O8GLNq?$Bp5| z0wJV%d}U$KRu|CFul1W3&x9ZY&S?|W7#J8d=D0C{(pUpO1H+v8ZVaFl*dWco&^zCa z0hB&LbN21?-55YkK@hucz8eE54TExh*?cz!P$vl_o;Tl(0hG=`L&cf%-55aKEf70- zz8eE5j|ea_FhtLHV*q6zkov&+ZVaH_9cT%J+k7_$P>ut!t>?QjfHEUUjSk2?XCU_t zE6jIe0A*eV8wLg;klRB3{|B*IKyC|xsQEF^jRDlBbr5D?cstLH0o3CKb&MX*b7KG% z9UwQ~oae>>>KcPOm1pOC#)=D9I|3N(;-)jT%_&_Dxd_&;l&8w04&V-R3qh@0oe02)64sR@|p#sC_g z0JT?K=D9I|1};Euvz+I~02<2(U}9h}oae@HMDzcDkhtPJHwI8=0mPP==f(i)K!D8Q zp6A8@YI=g~`aRc;0W|UfVt<(H#!wiaRurF6vA0h5s>YL@kOcenYkdhGGyi^rX%bvN=?i`@DfW(5|gtbK>>16Mt&K{!Jr_@ zDK3c51qD+D1BjWIS`IQewV*fvy}0NCEjmjTLB%9^^bNug40>_J6)MT!atu`Zg0`A@q@{KGet6;e6mq&CyeIJ@ z9A;7pA9!E^v@)gBEA6!a#JEt7v~EY9v`(kA7rY=>`*Ngp2bQIEhQ4_5_X*frY26+r z;QhsKLHtk-_@s(g$%|W0Kyx-Ak zmCvA&gBPctfdWLQ)AdJl?GNy*^N*L`L3Tp`n;Of$d#40y5U47h~^niK^M zP;>C__e|?%07-#2&G2sr?c4xe-2qyB{31^qIx&i5_$&qnh8M0NXEK4hp4-7O7Wl&0 z85*D^x}X&>p}W>b>MLam{VE1U4OjxfAQ-vXi+R^fB_b9FPvaT>48=* zyM76HaTP8k4e^u{2Pm!^4}v@RFOJoNOy=lz{Q;>id=|MeyeQ;BsxH3pfF}41tlzxY z#RID=KvPs9iy(U;LFH(|A~%NAoYdUZyb?$e1G;-1v2_QOoI(2`2+d!j%OlNa))2G) z3Q0Xt>$L*AT{)~>d1^qtyH4Lfui3goc{)S?bi4jREb9Wh9Ylcki}3FUB?(_1?t`G+ zA{gtxV6EU?#?Xubx_OD^KXl;m;6sL8X=+(EE&Dm87wNgLlq#qf_dTE48RtF-3UIl2dY2@u7Dpp9qaq&g*(Vx(7r5$c`{)0z}mrQ zG0K3wn8o;FcQeT40-dfeVD7@QAh!9ZL#-~zK*-{K8Sq#yGP@hJiKYN<)a!lVqmuY* zKxTuM)_nk%Hegj+WgtP0fEN>OtwC$mK)W8nHyUNhz3|Hd%YjB5`1gl$v|g$MjohmA z`Y>}6yZ8v63U+0J6oIFBLECZzUR2t`qS64o=NlZT$Z^sE zSAY~Jn?X~X2(#0`eRCdx7qfpOG6~GijKW$5h8Ka5G}Y<)#pSQJ^wm4QRqJ1Jp_e4{X19V*?9JGq9cDqn^;sV#jV)0?4c^Bd8mg zyL}b-w~H_az2JbG8Sx_K*Z=<+X=V%zP}4#Cv>>V;S;K5L$lx-ED#$(o_wtK_a0N)w z_y)WtNk5Ab!&awsaJWJ}3~~*)5Zn#Y04j4KHPxFHZVWGuvw~}?<|ClZi&AXJ_0yLX zko}6F_AtXrHwOQ*)S|SU{Bl^e1TGIT_uGSg2Ocei947#F1vpJY_%FVsfnAr@>H1|S zsO|%|eB^(Es$xirN=Ep02V|<#^}~yQKR_dHKR_hd#57QS1KMr(2imj!16n5p8Y;0q zSZfQ}<|x3w-6!B5XawL7{J4rTxa~jqw}*ZKWy~J|FF@8w3-6B_PrG}iI&1# zYYmQQa3+BU4!EdLgQUGq*B{`uAsPMP!L=WOFKoeK#M9~eEJp^1YG!M7#A}z zym$?X8nD(-fgtda>fqz|nc!NxL1B;#wgME|e=I7G85@5f*xMB_sx)ObG#fk7dRKa7o0=^gG-=GU3K(#VxvmgIw$b-KREk_2tm4t#MK+-Bhj0IL@R7xEmS^C&@;BUsC#evla;v2M`K zeTP#)Tu}V}cmdjvkpa4N032$dx)2&@>ykij4{Ux~x9^X%P96cUjo?*Q5Gx^7;kQ1py`UAy>e$iB#=LpjLYj=R>N! z3b^f{T@|e-OFdsa{S2Bedx3O}3kTT084TAKGrVwzXb5;Q4_sDp1iVN^vJPAuf~*sK zoel0f$ppQ4nh5qFs6h$d$oJxkDJ)>!UsNDl2G08&kb)6x*)8Zq!wW;0Wk0~F6XG|7 zWylpJXtJI$=*4{#m?hyaj6Y*klu%VW;i~k}DoRKoy_f-4!1vK+aJ~fg6QfBfbOgWCIna zUtX`kRwF`NM&KIJ5RzsBUc3M|V|k#7=R@F&<#1zuKtrAZbO;joBrFle7aAYIr84Mv znYn)t_h zgJwKm^FyauTz|Y+1`+_9finnySmSL`sKD*}0`6LXi{TgRz?%4c3zxUMvQg2d=2W8-ILH zKr8AKpq)(3znJ)Yt3h*<3@^OE6$?wJ>m0D^BcR30zDJ;{kMQpgJ<|M(wKjzxv`Hz8 zF^iRdJLru4l2~wl33#CmPRQV~g%{^zz=EKR{Ni&In4Q+?3fr>*KJE{?e*?_!_MH>> zB03+Wj;GUg&g=H(+BpoRyjhGdwt=exkef10z#}Ykf?jL_FXZItbnR%a?O@<+})*@`4AX<7EzLRXX_Yy80JZ zkTyxD>lV-$6Hi(vEV6Wy*Yy*v|O#U%fB z9!ALEP4*!M{_Q@jUjkoPR)Ino+~|3s8x3ZIwh)5O(*kXUYv~nf1lJq~A29H5=V5|q zKlq4&f4ht5mw*?)D#2R7ZOC`b3N75a7BCS*K#cR;+E7v)lu3KJ$a!7`67I+|xf4?9W zpT77Dj(bp|$l?OWdkwf52omUZT@wI~K2J4Je1Zzq1>i$3vgBT{{Q%9If>eRhMDq)| zv`*JGFA9ExtJXEm2l)fRhS`H#JshyrAe}Cv6JA9B{{J81D9{DZ9NnQUy)0ee;_l!> z2LA0L96>KKkR9dP5%A(U#GFpoj$Yq25Tm!KB00)+K|q$=i^A^+NBOR4ekqsM>AQx1 zf9RU#L;OMAAamA(8%7ZK9DK;o>B2kV#c9wW0(hGM*0jRJ-}{9Dx&siLwOx-uR-?Nf z;ot9jr1>W+fA2Z)#_G@$-7Zrn1iX-fUnqfVHI9H6D6DWwcyB-KYl%PftAb)TKym$#_KuXYFNWg(h z(2b#B1<(@oNcKf8=FkTI{jLZ2xAQoG`c!*BCyCt%co6{}UIK;d4*u=FJ3xWDBdFVT zPQZ(KwICxv+3_Xlcnommaw71BxfV3%@wb2~F#heK2ZA6D16|HM6XJ$|7XdJbod|sK zB@AQ|q!5unc9`pt>=Rtf;A30)_lF+f-wwH*d=KdOp&LOj_CUreK{u-KZ+G1R8tvQ> z*d012=mitPZF@nxd|W{XQ_Kl`@kL$tKJIp7SOeWp|8}<vc7WE`rFHh+0og6}71V?5 zo(j^)zrE=XXr0)Lt!l7DZU~-942%J-*5%*s5f=F3BwS9^_)>Q(NMBm#1dzTL=RixH zyM0B{x&_lZr-B0L#qKZv|G&8Q1=Q>W7o8vz!r>-FLG9fSwzv5QV~N{N(D4yzoxKl0 zj;s9ws`93S*cTrKfz~pCtYZZ&oDF!9@CGzh%L8h_fJDgt?tML#hIS0Myd<}L6BqaFvcYw|K$;jXG4m7iS8$7tc0a`Q(@}3lU7MXv0U|7(L z0GI>#TMmQTOI%qD5JQ>|umrp?f*6|x5(PW2`JhDL3mGI)uq&Dm=>)xCLlOl?Nb>=Q zfEOQLfgOfyLP+3?TS%f%6EcEc96=I=notw)VjV;jDTEn7A^iLkC~rXmEv>T=9O{=r zJ^UAM!NU=dh3a7eFY;7i0gvqO2$(2;%Ooby+UHhKN=fT%1?AZnT_7VEUIath?Vx7= z$+S*i@T3{)={>d}x6~T+_JXnksJ{6DE?arP<9Tp4xGbLruB!z=jrg6QN(O9Gz>D+# z;7S8(b6R&V#2vk$eEfn5JdiOJ#D>HQ|Nah;joKH3vbZ40w)v1l&N+qqk6=XPQ;VY<=nDh~pM_xoj z+VGvOGr$YoaQfQ_$>03jTS7q=fmY-F;NL#Q7sLtb2AzLB2i$uS=yaX&dOOJHy`aJ` z@WoX>n9o7{v~F--P3r{v_65gBP;v)54id-w`zM0@rhO;?;kk@}7Xpy{mxbhWXhO{h z?41gA15ZFk3CQO$AfNkz&&yJQn3~oNwl1v`Z1{^wA3(=pgKbUgYz39bFX}&lgTw>e zZDZ+lokDq#ObK|=32s0Nbh=J?y`6u5FUY2g57Roqj2AqhkrPCCfQt4PKi-4G1H``g zAg!|%#CY)-G+KbmJxP>71Qvom&-octyko3Wl*4ZioQnr68 z$j>{#ebYmrjRGLefiM1h!%`85&%b>tNO2IPG0hB)G|-M*kRbndut5PYVjxZP&Q?&x z*4qox7uY=�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 z475h%0Dp@jSPar;2Z;r}Uox}u^GlY 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

tTOAd;h)={4I6pDFST6O1o) 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

(A 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%0AstsC6c5O`M@- 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%0A1RA`R`UPm6BL8+!|M33| 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

%zj^Ua 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%0DW6W9O$e_`|%($0sJE-xnM!aa-8MFJH^pnEMr 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�$B>0Mgb+f7b{%B1wHesF(uvxP1b%SYPNk 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
)`2z>d-^eAqQSl2G#Mpdl%?NfV9rg6E9l7 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%0AT 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 z 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


TU(G__urbLG<*tf*sr2`v9b_cPhw3LEWw?;F~O8 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�!u-JUuS}y9JbS2JlhPKftSV1wq$K`3it0 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

-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 $TY|b>cLcn+1|GTt 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%0A_AIs1r@NMdQ+kC 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­vAdAm;|Wc&`Aq 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%0D*ba#$uwx+$29b0^lO||A6iU*BW;xKc4 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 z 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

Bs`L&0;j9dBl{{IzU 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ͱOh?UI(-oFaE^%s{~ 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 z�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%0D3%;#Jnbeb)pw~|Gm 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

16z2g6- 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 - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 9578e488d..75b13f9bd 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 7a2aa8a7f..337fc98e2 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 929dd72a8..b6a8a7dd3 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 2d06d29aa..60a24021f 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 86dcef905..7fe2ad96c 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0 + + + + StaticLibrary + v143 + false + MultiByte + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index e47858ae3..10abdb438 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0 + + + StaticLibrary + v143 + false + MultiByte + + + + StaticLibrary + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 86730b859..1cfb3e588 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0 + + + + StaticLibrary + v143 + MultiByte + + + StaticLibrary + v143 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 70a130e31..ecd8b04aa 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0 + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/options.h b/lib_com/options.h index 3ec71d78b..d235b80b9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -95,7 +95,7 @@ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ diff --git a/lib_com/swb_tbe_com_fx.c.bak b/lib_com/swb_tbe_com_fx.c.bak new file mode 100644 index 000000000..fb68537c8 --- /dev/null +++ b/lib_com/swb_tbe_com_fx.c.bak @@ -0,0 +1,8216 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" +#include "basop_util.h" +#include "ivas_prot_fx.h" +#include "options_warnings.h" + +#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ +#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 // Q31 +#define POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49 1667313793 // Q49 +#define POW_EXC16k_WHTND_FX 178125000 // Q-6 +#define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ +#define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ + +/*-----------------------------------------------------------------* + * Local function prototypes + *-----------------------------------------------------------------*/ + +static void create_random_vector_fx( Word16 output[], const Word16 length, Word16 seed[] ); +static void flip_spectrum_fx( const Word16 input[], Word16 output[], const Word16 length ); +static void Calc_st_filt_tbe( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero ); +static void Hilbert_transform_fx( Word32 tmp_R[], Word32 tmp_I[], Word32 *tmpi_R, Word32 *tmpi_I, const Word16 length, const Word16 HB_stage_id ); +static void Hilbert_transform_sp_fx( Word16 tmp_R[], Word16 tmp_I[], Word32 *tmpi_R, Word32 *tmpi_I, const Word16 length, const Word16 HB_stage_id ); +void Estimate_mix_factors_fx( const Word16 *shb_res, const Word16 Q_shb, const Word16 *exc16kWhtnd, const Word16 Q_bwe_exc, const Word16 *White_exc16k_frac, const Word16 Q_frac, const Word32 pow1, const Word16 Q_pow1, const Word32 pow22, const Word16 Q_pow22, Word16 *vf_modified, Word16 *vf_ind ); + +/*-------------------------------------------------------------------* + * swb_tbe_reset() + * + * Reset the SWB TBE encoder + *-------------------------------------------------------------------*/ + +void swb_tbe_reset_fx( + Word32 mem_csfilt[], + Word16 mem_genSHBexc_filt_down_shb[], + Word16 state_lpc_syn[], + Word16 syn_overlap[], + Word16 state_syn_shbexc[], + Word16 *tbe_demph, + Word16 *tbe_premph, + Word16 mem_stp_swb[], + Word16 *gain_prec_swb ) +{ + set32_fx( mem_csfilt, 0, 2 ); + set16_fx( mem_genSHBexc_filt_down_shb, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set16_fx( state_lpc_syn, 0, LPC_SHB_ORDER ); + + set16_fx( syn_overlap, 0, L_SHB_LAHEAD ); + set16_fx( state_syn_shbexc, 0, L_SHB_LAHEAD ); + + *tbe_demph = 0; + move16(); + *tbe_premph = 0; + move16(); + + set16_fx( mem_stp_swb, 0, LPC_SHB_ORDER ); + *gain_prec_swb = 16384; + move16(); /*Q14 = 1 */ + + return; +} + + +/*-------------------------------------------------------------------* + * swb_tbe_reset_synth() + * + * Reset the extra parameters needed for synthesis of the SWB TBE output + *-------------------------------------------------------------------*/ + +void swb_tbe_reset_synth_fx( + Word32 genSHBsynth_Hilbert_Mem[], + Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[], + Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[] ) +{ + + set32_fx( genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE ); + set16_fx( genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); + + if ( genSHBsynth_state_lsyn_filt_shb_local_fx_32 != NULL ) + { + set32_fx( genSHBsynth_state_lsyn_filt_shb_local_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * fb_tbe_reset_synth_fx() + * + * reset of FB TBE memories + *-------------------------------------------------------------------*/ + +void fb_tbe_reset_synth_fx( + Word32 fbbwe_hpf_mem_fx[][4], + Word16 fbbwe_hpf_mem_fx_Q[], + Word16 *prev_fbbwe_ratio_fx ) +{ + set32_fx( fbbwe_hpf_mem_fx[0], 0, 4 ); + set32_fx( fbbwe_hpf_mem_fx[1], 0, 4 ); + set32_fx( fbbwe_hpf_mem_fx[2], 0, 4 ); + set32_fx( fbbwe_hpf_mem_fx[3], 0, 4 ); + set16_fx( fbbwe_hpf_mem_fx_Q, 0, 4 ); + *prev_fbbwe_ratio_fx = 1; + move16(); /*should be set to 1.0f, scaling unknown */ + + return; +} + + +/*-------------------------------------------------------------------* + * tbe_celp_exc_offset() + * + * Compute tbe bwe celp excitation offset + *-------------------------------------------------------------------*/ + +Word16 tbe_celp_exc_offset( + const Word16 T0_fx, /* i : Integer pitch Q0 */ + const Word16 T0_frac_fx, /* i : Fractional part of the pitch Q1 */ + const Word16 L_frame /* i : frame lenght */ +) +{ + Word16 offset_fx, tmp_fx, tmp1_fx, tmp2_fx, tmp_fac; + tmp_fac = 320; + move16(); /*2.5 in Q7*/ + if ( EQ_16( L_frame, L_FRAME16k ) ) + { + tmp_fac = 256; + move16(); /*2.0 in Q7*/ + } + tmp_fx = extract_l( L_mult( T0_frac_fx, 32 ) ); /*Q8, 0.25 in Q7*/ + tmp_fx = add( 512, tmp_fx ); /*Q8; 2 in Q8*/ + tmp_fx = mult_r( tmp_fx, tmp_fac ); /*Q16->Q0; 2.5 in Q7 or 2.0 in Q7 */ + + tmp1_fx = sub( T0_fx, 2 ); /*Q0*/ + + tmp2_fx = shl( tmp1_fx, 1 ); /*Q0 */ + + IF( EQ_16( L_frame, L_FRAME ) ) + { + tmp2_fx = add( shl( tmp1_fx, 1 ), shr( tmp1_fx, 1 ) ); /*Q0; (5/2 = 2 + 1/2)*/ + } + + offset_fx = add( tmp_fx, tmp2_fx ); /*Q0*/ + + return offset_fx; +} + +/*-------------------------------------------------------------------* + * swb_tbe_celp_exc() + * + * Compute tbe bwe celp excitation + *-------------------------------------------------------------------*/ +void tbe_celp_exc( + const Word16 L_frame_fx, /* i : Frame lenght */ + const Word16 i_subfr_fx, /* i : sub frame */ + const Word16 T0_fx, /* i : Integer pitch Q0 */ + const Word16 T0_frac_fx, /* i : Fractional part of the pitch Q1 */ + Word16 *error_fx, /* i/o: Error Q5 */ + Word16 *bwe_exc_fx /* i/o: bandwitdh extension signal */ +) +{ + Word16 offset_fx, tmp_fx, i; + IF( EQ_16( L_frame_fx, L_FRAME ) ) + { + /*offset = T0 * HIBND_ACB_L_FAC + (int) ((float) T0_frac * 0.25f * HIBND_ACB_L_FAC + 2 * HIBND_ACB_L_FAC + 0.5f) - 2 * HIBND_ACB_L_FAC; + for (i=0; i 0 ) + { + tmp_fx = shr( *error_fx, 5 ); /*Q0*/ + } + ELSE + { + tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ + } + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC - offset_fx + tmp_fx]; // Qx + move16(); + } + tmp_fx = extract_l( L_mult( T0_frac_fx, 1 ) ); /*Q3; 0.25 in Q2*/ + tmp_fx = add( shl( T0_fx, 3 ), tmp_fx ); /*Q3*/ + tmp_fx = extract_l( L_mult( tmp_fx, 5 ) ); /*Q5, 2.5 in Q1*/ + tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*Q5*/ + *error_fx = add( *error_fx, tmp_fx ); /*Q5*/ + move16(); + } + ELSE + { + /* offset = T0*2.5 + (int) ((float) T0_frac * 0.25f*2.5 + 2*2.5 + 0.5f) - 2*2.5; - case above*/ + /* offset = T0*2 + (int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f) - 2*2; - case here*/ + + /*(int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f)*/ + offset_fx = tbe_celp_exc_offset( T0_fx, T0_frac_fx, L_frame_fx ); + IF( *error_fx > 0 ) + { + tmp_fx = shr( *error_fx, 5 ); /*Q0*/ + } + ELSE + { + tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ + } + + FOR( i = 0; i < L_SUBFR * 2; i++ ) + { + bwe_exc_fx[i + i_subfr_fx * 2] = bwe_exc_fx[i + i_subfr_fx * 2 - offset_fx + tmp_fx]; // Qx + move16(); + } + + /* error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac;*/ + tmp_fx = extract_l( L_mult( T0_frac_fx, 2 ) ); /*Q3; 0.5 in Q2*/ + tmp_fx = add( shl( T0_fx, 4 ), tmp_fx ); /* now tmp_fx = "T0_fx*2+ 0.5f*T0_frac_fx" in Q3*/ + tmp_fx = shl( tmp_fx, 2 ); /*now above tmp_fx in Q5*/ + tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*move offset_fx to Q5, tmp_fx in Q5, ans tmp_fx in Q5*/ + *error_fx = add( *error_fx, tmp_fx ); /*error_fx in Q5*/ + move16(); + } +} + +/*-------------------------------------------------------------------* + * swb_tbe_celp_exc_ivas() + * + * Compute tbe bwe celp excitation + *-------------------------------------------------------------------*/ +void tbe_celp_exc_ivas( + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 L_frame_fx, /* i : Frame lenght */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 i_subfr_fx, /* i : sub frame */ + const Word16 T0_fx, /* i : Integer pitch Q0 */ + const Word16 T0_frac_fx, /* i : Fractional part of the pitch Q1 */ + Word16 *error_fx, /* i/o: Error Q5 */ + Word16 *bwe_exc_fx, /* i/o: bandwitdh extension signal Qx */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +) +{ + Word16 offset_fx, tmp_fx, i; + + test(); + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) + { + return; + } + + IF( EQ_16( L_frame_fx, L_FRAME ) ) + { + /*offset = T0 * HIBND_ACB_L_FAC + (int) ((float) T0_frac * 0.25f * HIBND_ACB_L_FAC + 2 * HIBND_ACB_L_FAC + 0.5f) - 2 * HIBND_ACB_L_FAC; + for (i=0; i 0 ) + { + tmp_fx = shr( *error_fx, 5 ); /*Q0*/ + } + ELSE + { + tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ + } + + FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC - offset_fx + tmp_fx]; + move16(); + } + tmp_fx = extract_l( L_mult( T0_frac_fx, 1 ) ); /*Q3; 0.25 in Q2*/ + tmp_fx = add( shl( T0_fx, 3 ), tmp_fx ); /*Q3*/ + tmp_fx = extract_l( L_mult( tmp_fx, 5 ) ); /*Q5, 2.5 in Q1*/ + tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*Q5*/ + *error_fx = add( *error_fx, tmp_fx ); /*Q5*/ + move16(); + } + ELSE + { + /* offset = T0*2.5 + (int) ((float) T0_frac * 0.25f*2.5 + 2*2.5 + 0.5f) - 2*2.5; - case above*/ + /* offset = T0*2 + (int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f) - 2*2; - case here*/ + + /*(int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f)*/ + offset_fx = tbe_celp_exc_offset( T0_fx, T0_frac_fx, L_frame_fx ); + IF( *error_fx > 0 ) + { + tmp_fx = shr( *error_fx, 5 ); /*Q0*/ + } + ELSE + { + tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ + } + + FOR( i = 0; i < L_subfr * 2; i++ ) + { + bwe_exc_fx[i + i_subfr_fx * 2] = bwe_exc_fx[i + i_subfr_fx * 2 - offset_fx + tmp_fx]; + move16(); + } + + /* error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac;*/ + tmp_fx = extract_l( L_mult( T0_frac_fx, 2 ) ); /*Q3; 0.5 in Q2*/ + tmp_fx = add( shl( T0_fx, 4 ), tmp_fx ); /* now tmp_fx = "T0_fx*2+ 0.5f*T0_frac_fx" in Q3*/ + tmp_fx = shl( tmp_fx, 2 ); /*now above tmp_fx in Q5*/ + tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*move offset_fx to Q5, tmp_fx in Q5, ans tmp_fx in Q5*/ + *error_fx = add( *error_fx, tmp_fx ); /*error_fx in Q5*/ + move16(); + } +} + +/*===========================================================================*/ +/* FUNCTION : flip_and_downmix_generic_fx() */ +/*---------------------------------------------------------------------------*/ +/* PURPOSE :flips the spectrum and downmixes the signals, lpf if needed*/ +/*---------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS */ +/* _(Word16[]) input :input spectrum */ +/* _(Word16) length :length of spectra */ +/* _(Word16) ramp_flag :flag to indicate slow ramp need after switching */ +/* _(Word16[]) lpf_num :lpf numerator */ +/* _(Word16[]) lpf_den :lpf denominator */ +/*---------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _(Word16[])output : output spectrum */ +/*---------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _(Word32[9])mem1 : memory */ +/* _(Word32[8])mem2 : memory */ +/* _(Word32[8])mem3 : memory */ +/* _(Word16) dm_frequency_inHz :Downmix frequency in Hz */ +/* _(Word16*) phase_state :Phase state in case frequency isn't */ +/* multiple of 50 Hz */ +/*---------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*---------------------------------------------------------------------------*/ +void flip_and_downmix_generic_fx( + Word16 input[], /* i : input spectrum Qx*/ + Word16 output[], /* o : output spectrum Qx*/ + const Word16 length, /* i : length of spectra */ + Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx+16*/ + Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx+16*/ + Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx+16*/ + Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ +) +{ + Word16 i, j; + Word16 tmp_16[L_FRAME32k + HILBERT_ORDER1]; + Word32 tmpi_R[L_FRAME32k]; + Word32 tmpi_I[L_FRAME32k]; + Word32 tmpi2_R[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmpi2_I[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmp_R[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmp_I[L_FRAME32k + HILBERT_ORDER2]; + + /*Word16 s_tmp[L_FRAME32k];*/ + /*Word16 factor;*/ + Word16 period; + Word16 local_negsin_table17[17] = { 0, -11793, -22005, -29268, -32609, -31580, + -26319, -17530, -6393, 6393, 17530, 26319, + 31580, 32609, 29268, 22005, 11793 }; /* Q15 */ + Word16 local_cos_table17[17] = { 32767, 30571, 24279, 14732, 3212, -8739, + -19519, -27683, -32137, -32137, -27683, + -19519, -8739, 3212, 14732, 24279, 30571 }; /* Q15 */ + Word16 *local_negsin_table, *local_cos_table; + Word32 L_tmp; + + /* 1850 Hz downmix */ + period = 17; + move16(); + local_negsin_table = local_negsin_table17; + local_cos_table = local_cos_table17; + + + FOR( i = 0; i < length; i = i + 2 ) + { + input[i] = negate( input[i] ); + move16(); + } + + Copy( input, tmp_16 + HILBERT_ORDER1, length ); + + /*Copy32( mem1_ext, tmp_16, 5 ); */ + FOR( i = 0; i < HILBERT_ORDER1; i++ ) + { + tmp_16[i] = extract_h( mem1_ext[i] ); /* mem1_ext (Qx+16) tmp16 (Qx) */ + move16(); + } + + /* Hilber transform stage - 0 - single precision */ + Hilbert_transform_sp_fx( tmp_16, /* i: Real component of HB */ + tmp_16, /* i: Imag component of HB */ + tmpi_R, /* o: Real component of HB */ + tmpi_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 0 ); /* i: HB transform stage */ + + FOR( i = 0; i < HILBERT_ORDER1; i++ ) + { + mem1_ext[i] = L_deposit_h( tmp_16[i + length] ); /* mem1_ext (Qx+16) tmp16 (Qx) */ + move32(); + } + + Copy32( mem2_ext, tmpi2_R, HILBERT_ORDER2 ); + Copy32( mem3_ext, tmpi2_I, HILBERT_ORDER2 ); + + /* Hilber transform stage - 1 */ + Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ + tmpi_I, /* i: Imag component of HB */ + tmpi2_R, /* o: Real component of HB */ + tmpi2_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 1 ); /* i: HB transform stage */ + + Copy32( mem2_ext + HILBERT_ORDER2, tmp_R, HILBERT_ORDER2 ); + Copy32( mem3_ext + HILBERT_ORDER2, tmp_I, HILBERT_ORDER2 ); + + /* Hilber transform stage - 2 */ + Hilbert_transform_fx( tmpi2_R, /* i: Real component of HB */ + tmpi2_I, /* i: Imag component of HB */ + tmpi_R, /* o: Real component of HB */ + tmpi_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 2 ); /* i: HB transform stage */ + + Copy32( tmpi2_R + length, mem2_ext, HILBERT_ORDER2 ); + Copy32( tmpi2_I + length, mem3_ext, HILBERT_ORDER2 ); + + /* Hilber transform stage - 3 */ + Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ + tmpi_I, /* i: Imag component of HB */ + tmp_R, /* o: Real component of HB */ + tmp_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 3 ); /* i: HB transform stage */ + + Copy32( tmp_R + length, mem2_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); + Copy32( tmp_I + length, mem3_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); + + if ( GE_16( *phase_state, period ) ) + { + *phase_state = 0; + move16(); + } + + i = 0; + move16(); + j = *phase_state; + move16(); + + WHILE( i < length ) + { + WHILE( ( j < period ) && ( i < length ) ) + { + L_tmp = Mult_32_16( tmp_R[i + 4], local_cos_table[j] ); /*//Qx+16 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + 4], local_negsin_table[j] ); /*Qx+16 */ + output[i] = round_fx( L_tmp ); /*Qx */ + move16(); + i++; + j++; + } + + if ( GE_16( j, period ) ) + { + j = 0; + move16(); + } + } + + *phase_state = j; + move16(); + + return; +} + + +void flip_and_downmix_generic_fx32( + Word32 input[], /* i : input spectrum Qx*/ + Word32 output[], /* o : output spectrum Qx*/ + const Word16 length, /* i : length of spectra */ + Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ + Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ +) +{ + Word16 i, j; + Word32 tmp[L_FRAME32k + HILBERT_ORDER1]; + Word32 tmpi_R[L_FRAME32k]; + Word32 tmpi_I[L_FRAME32k]; + Word32 tmpi2_R[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmpi2_I[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmp_R[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmp_I[L_FRAME32k + HILBERT_ORDER2]; + + /*Word16 s_tmp[L_FRAME32k];*/ + /*Word16 factor;*/ + Word16 period; + Word16 local_negsin_table17[17] = { 0, -11793, -22005, -29268, -32609, -31580, + -26319, -17530, -6393, 6393, 17530, 26319, + 31580, 32609, 29268, 22005, 11793 }; /* Q15 */ + Word16 local_cos_table17[17] = { 32767, 30571, 24279, 14732, 3212, -8739, + -19519, -27683, -32137, -32137, -27683, + -19519, -8739, 3212, 14732, 24279, 30571 }; /* Q15 */ + Word16 *local_negsin_table, *local_cos_table; + Word32 L_tmp; + + /* 1850 Hz downmix */ + period = 17; + move16(); + local_negsin_table = local_negsin_table17; + local_cos_table = local_cos_table17; + + + FOR( i = 0; i < length; i = i + 2 ) + { + input[i] = L_negate( input[i] ); + move16(); + } + + Copy32( input, tmp + HILBERT_ORDER1, length ); + Copy32( mem1_ext, tmp, HILBERT_ORDER1 ); + + /* Hilber transform stage - 0 - single precision */ + Hilbert_transform_fx( tmp, /* i: Real component of HB */ + tmp, /* i: Imag component of HB */ + tmpi_R, /* o: Real component of HB */ + tmpi_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 0 ); /* i: HB transform stage */ + + + Copy32( mem2_ext, tmpi2_R, HILBERT_ORDER2 ); + Copy32( mem3_ext, tmpi2_I, HILBERT_ORDER2 ); + + /* Hilber transform stage - 1 */ + Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ + tmpi_I, /* i: Imag component of HB */ + tmpi2_R, /* o: Real component of HB */ + tmpi2_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 1 ); /* i: HB transform stage */ + Copy32( tmp + length, mem1_ext, HILBERT_ORDER1 ); + Copy32( mem2_ext + HILBERT_ORDER2, tmp_R, HILBERT_ORDER2 ); + Copy32( mem3_ext + HILBERT_ORDER2, tmp_I, HILBERT_ORDER2 ); + + /* Hilber transform stage - 2 */ + Hilbert_transform_fx( tmpi2_R, /* i: Real component of HB */ + tmpi2_I, /* i: Imag component of HB */ + tmpi_R, /* o: Real component of HB */ + tmpi_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 2 ); /* i: HB transform stage */ + + Copy32( tmpi2_R + length, mem2_ext, HILBERT_ORDER2 ); + Copy32( tmpi2_I + length, mem3_ext, HILBERT_ORDER2 ); + + /* Hilber transform stage - 3 */ + Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ + tmpi_I, /* i: Imag component of HB */ + tmp_R, /* o: Real component of HB */ + tmp_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 3 ); /* i: HB transform stage */ + + Copy32( tmp_R + length, mem2_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); + Copy32( tmp_I + length, mem3_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); + + if ( GE_16( *phase_state, period ) ) + { + *phase_state = 0; + move16(); + } + + i = 0; + move16(); + j = *phase_state; + move16(); + + WHILE( LT_16( i, length ) ) + { + WHILE( ( j < period ) && ( i < length ) ) + { + test(); + L_tmp = Mult_32_16( tmp_R[i + 4], local_cos_table[j] ); /*//Qx+16 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + 4], local_negsin_table[j] ); /*Qx+16 */ + output[i] = L_tmp; /*Qx */ + move32(); + i++; + j++; + } + + if ( GE_16( j, period ) ) + { + j = 0; + move16(); + } + } + + *phase_state = j; + move16(); + return; +} + +/*---------------------------------------------- + * Hilbert transform - Double precision + *------------------------------------------------*/ +static void Hilbert_transform_fx( + Word32 tmp_R[], /* i: Real component of HB */ + Word32 tmp_I[], /* i: Real component of HB */ + Word32 tmpi_R[], /* o: Real component of HB */ + Word32 tmpi_I[], /* o: Imag. component of HB */ + const Word16 length, /* i: input length */ + const Word16 HB_stage_id /* i: HB transform stage */ +) +{ + Word16 i, hb_filter_stage, offset; + Word32 L_tmp; + + hb_filter_stage = shl( HB_stage_id, 1 ); + offset = 0; + move16(); + if ( HB_stage_id == 0 ) + { + offset = 1; + move16(); + } + + test(); + test(); + IF( HB_stage_id == 0 || EQ_16( HB_stage_id, 2 ) ) + { + FOR( i = 0; i < length; i++ ) + { + L_tmp = Mult_32_16( tmp_R[i + 4], Hilbert_coeffs_fx[hb_filter_stage][0 + offset] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2 + offset] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_R[i], Hilbert_coeffs_fx[hb_filter_stage][4 + offset] ); /*Qx+15 */ + tmpi_R[i] = L_shl( L_tmp, 1 ); + move32(); /*Qx+16 */ + + L_tmp = Mult_32_16( tmp_I[i + 4 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][0] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + 2 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][2] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][4] ); /*Qx+15 */ + tmpi_I[i] = L_shl( L_tmp, 1 ); + move32(); /*Qx+16 */ + } + } + ELSE IF( EQ_16( HB_stage_id, 1 ) || EQ_16( HB_stage_id, 3 ) ) + { + FOR( i = 0; i < length; i++ ) + { + + L_tmp = Mult_32_16( tmpi_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmpi_R[i], Hilbert_coeffs_fx[hb_filter_stage][4] ); /*Qx+15 */ + tmpi_R[i + 4] = L_sub( tmp_R[i], L_shl( L_tmp, 1 ) ); + move32(); /*Qx+16 */ + + L_tmp = Mult_32_16( tmpi_I[i + 2], Hilbert_coeffs_fx[hb_filter_stage + 1][2] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmpi_I[i], Hilbert_coeffs_fx[hb_filter_stage + 1][4] ); /*Qx+15 */ + tmpi_I[i + 4] = L_sub( tmp_I[i], L_shl( L_tmp, 1 ) ); + move32(); /*Qx+16 */ + } + } +} + + +/*---------------------------------------------- + * Hilbert transform - Single precision Stage 0 + *------------------------------------------------*/ +static void Hilbert_transform_sp_fx( + Word16 tmp_R[], /* i: Real component of HB */ + Word16 tmp_I[], /* i: Real component of HB */ + Word32 tmpi_R[], /* o: Real component of HB */ + Word32 tmpi_I[], /* o: Imag. component of HB */ + const Word16 length, /* i: input length */ + const Word16 HB_stage_id /* i: HB transform stage */ +) +{ + Word16 i, hb_filter_stage, offset; + Word32 L_tmp; + + hb_filter_stage = shl( HB_stage_id, 1 ); + offset = 0; + move16(); + if ( HB_stage_id == 0 ) + { + offset = 1; + move16(); + } + + /* Hilbert single precision stage 0 */ + FOR( i = 0; i < length; i++ ) + { + L_tmp = L_mult( tmp_R[i + 4], Hilbert_coeffs_fx[hb_filter_stage][0 + offset] ); /*Qx */ + L_tmp = L_mac( L_tmp, tmp_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2 + offset] ); /*Qx */ + L_tmp = L_mac( L_tmp, tmp_R[i], Hilbert_coeffs_fx[hb_filter_stage][4 + offset] ); /*Qx */ + tmpi_R[i] = L_shl( L_tmp, 1 ); + move32(); /*Qx+16 */ + + L_tmp = L_mult( tmp_I[i + 4 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][0] ); /*Qx */ + L_tmp = L_mac( L_tmp, tmp_I[i + 2 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][2] ); /*Qx */ + L_tmp = L_mac( L_tmp, tmp_I[i + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][4] ); /*Qx */ + tmpi_I[i] = L_shl( L_tmp, 1 ); + move32(); /*Qx+16 */ + } + + return; +} + + +/*---------------------------------------------- + * flip_spectrum_fx + *----------------------------------------------*/ +void flip_spectrum_fx( + const Word16 input[], /* i : input spectrum */ + Word16 output[], /* o : output spectrum */ + const Word16 length /* i : vector length */ +) +{ + Word16 i; + + FOR( i = 0; i < length; i = i + 2 ) + { + output[i] = negate( input[i] ); + move16(); + output[i + 1] = input[i + 1]; + move16(); + } + + return; +} + + +/*---------------------------------------------------------------------------- + * calc_rc0_h + * + * computes 1st parcor from composed filter impulse response + *---------------------------------------------------------------------------*/ +void Calc_rc0_h( + Word16 *h, /* i : impulse response of composed filter */ + Word16 *rc0 /* o : 1st parcor */ +) +{ + Word32 L_acc; + Word16 *ptrs; + Word16 acf0, acf1; + Word16 temp, sh_acf; + Word16 i; + + /* computation of the autocorrelation function acf */ + L_acc = L_mult( h[0], h[0] ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + L_acc = L_mac( L_acc, h[i], h[i] ); + } + sh_acf = norm_l( L_acc ); + L_acc = L_shl( L_acc, sh_acf ); + acf0 = extract_h( L_acc ); + + ptrs = h; + + temp = *ptrs++; + move16(); + L_acc = L_mult( temp, *ptrs ); + FOR( i = 1; i < LONG_H_ST - 1; i++ ) + { + temp = *ptrs++; + move16(); + L_acc = L_mac( L_acc, temp, *ptrs ); + } + L_acc = L_shl( L_acc, sh_acf ); + acf1 = extract_h( L_acc ); + + /* Compute 1st parcor */ + IF( acf0 == 0 ) + { + *rc0 = 0; + move16(); + return; + } + + IF( LT_16( acf0, abs_s( acf1 ) ) ) + { + *rc0 = 0; + move16(); + return; + } + *rc0 = div_s( abs_s( acf1 ), acf0 ); + move16(); + IF( acf1 > 0 ) + { + *rc0 = negate( *rc0 ); + move16(); + } +} + +void Calc_rc0_h_ivas_enc_fx( + Word16 *h, /* i : impulse response of composed filter */ + Word16 *rc0 /* o : 1st parcor */ +) +{ + Word32 L_acc; + Word16 *ptrs; + Word16 acf0, acf1; + Word16 temp, sh_acf, tmp2; + Word16 i; + + /* computation of the autocorrelation function acf */ + L_acc = L_mult( h[0], h[0] ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + tmp2 = shr( h[i], 2 ); + L_acc = L_mac( L_acc, tmp2, tmp2 ); + } + sh_acf = norm_l( L_acc ); + L_acc = L_shl( L_acc, sh_acf ); + acf0 = extract_h( L_acc ); + + ptrs = h; + + temp = *ptrs++; + move16(); + L_acc = L_mult( temp, *ptrs ); + FOR( i = 1; i < LONG_H_ST - 1; i++ ) + { + temp = shr( *ptrs++, 2 ); + move16(); + L_acc = L_mac( L_acc, temp, shr( *ptrs, 2 ) ); + } + L_acc = L_shl( L_acc, sh_acf ); + acf1 = extract_h( L_acc ); + + /* Compute 1st parcor */ + IF( acf0 == 0 ) + { + *rc0 = 0; + move16(); + return; + } + + IF( LT_16( acf0, abs_s( acf1 ) ) ) + { + *rc0 = 0; + move16(); + return; + } + *rc0 = div_s( abs_s( acf1 ), acf0 ); + move16(); + IF( acf1 > 0 ) + { + *rc0 = negate( *rc0 ); + move16(); + } +} + +static void Calc_st_filt_tbe( + Word16 *apond2, /* i : coefficients of numerator */ + Word16 *apond1, /* i : coefficients of denominator */ + Word16 *parcor0, /* o : 1st parcor calcul. on composed filter */ + Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ + Word16 *mem_zero /* i : All zero memory */ +) +{ + Word32 L_g0; + + Word16 h[LONG_H_ST]; + + Word16 g0, temp; + Word16 i; + temp = sub( 2, norm_s( apond2[0] ) ); + /* compute i.r. of composed filter apond2 / apond1 */ + Syn_filt_s( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); + /* compute 1st parcor */ + Calc_rc0_h( h, parcor0 ); + + /* compute g0 */ + L_g0 = L_mult0( 1, abs_s( h[0] ) ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); + } + g0 = extract_h( L_shl( L_g0, 14 ) ); + + /* Scale signal i of 1/A(gamma1) */ + IF( GT_16( g0, 1024 ) ) + { + temp = div_s( 1024, g0 ); /* temp = 2**15 / gain0 */ + FOR( i = 0; i < L_SUBFR16k; i++ ) + { + sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); + move16(); + } + } +} + +static void Calc_st_filt_tbe_ivas_enc_fx( + Word16 *apond2, /* i : coefficients of numerator */ + Word16 *apond1, /* i : coefficients of denominator */ + Word16 *parcor0, /* o : 1st parcor calcul. on composed filter */ + Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ + Word16 *mem_zero /* i : All zero memory */ +) +{ + Word32 L_g0; + + Word16 h[LONG_H_ST]; + + Word16 g0, temp; + Word16 i; + temp = sub( 2, norm_s( apond2[0] ) ); + /* compute i.r. of composed filter apond2 / apond1 */ + syn_filt_fx( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); + /* compute 1st parcor */ + Calc_rc0_h_ivas_enc_fx( h, parcor0 ); + + /* compute g0 */ + L_g0 = L_mult0( 1, abs_s( h[0] ) ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); + } + g0 = extract_h( L_shl( L_g0, 14 ) ); + + /* Scale signal i of 1/A(gamma1) */ + IF( GT_16( g0, 1024 ) ) + { + temp = div_s( 1024, g0 ); /* temp = 2**15 / gain0 */ + FOR( i = 0; i < L_SUBFR16k; i++ ) + { + sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); + move16(); + } + } +} + +static void Calc_st_filt_tbe_ivas_dec_fx( + Word16 *apond2, /* i : coefficients of numerator */ + Word16 *apond1, /* i : coefficients of denominator */ + Word16 *parcor0, /* o : 1st parcor calcul. on composed filter */ + Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ + Word16 *mem_zero /* i : All zero memory */ +) +{ + Word32 L_g0; + + Word16 h[LONG_H_ST]; + + Word16 g0, temp; + Word16 i; + temp = sub( 2, norm_s( apond2[0] ) ); + /* compute i.r. of composed filter apond2 / apond1 */ + Syn_filt_s( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); + /* compute 1st parcor */ + Calc_rc0_h( h, parcor0 ); + + /* compute g0 */ + L_g0 = L_mult0( 1, abs_s( h[0] ) ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); + } + g0 = extract_h( L_shl( L_g0, 14 ) ); + + /* Scale signal i of 1/A(gamma1) */ + IF( GT_16( g0, 1024 ) ) + { + temp = div_s( 1024, g0 ); /* temp = 2**15 / gain0 */ + FOR( i = 0; i < L_SUBFR16k; i++ ) + { + sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); + move16(); + } + } +} + +static void filt_mu_fx( + const Word16 *sig_in, /* i : signal (beginning at sample -1) */ + Word16 *sig_out, /* o : output signal */ + const Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ + Word16 SubFrameLength /* i : the length of subframe */ +) +{ + Word16 n; + Word16 mu, ga, temp; + const Word16 *ptrs; + Word16 tmp, exp; + Flag Overflow = 0; + move32(); + + + IF( EQ_16( SubFrameLength, L_SUBFR ) ) + { + IF( parcor0 > 0 ) + { + mu = mult_r( parcor0, GAMMA3_PLUS_FX ); + } + ELSE + { + mu = mult_r( parcor0, GAMMA3_MINUS_FX ); + } + } + ELSE + { + IF( parcor0 > 0 ) + { + mu = mult_r( parcor0, GAMMA3_PLUS_WB_FX ); + } + ELSE + { + mu = mult_r( parcor0, GAMMA3_MINUS_WB_FX ); + } + } + + tmp = abs_s( mu ); + tmp = sub( 32767, tmp ); + exp = norm_s( tmp ); + tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*(14 - exp) */ + ga = shl_sat( tmp, exp ); /*Q14 */ + + + /* ga = (float) 1. / ((float) 1. - (float) fabs (mu)); */ + + ptrs = sig_in; /* points on sig_in(-1) */ + + FOR( n = 0; n < SubFrameLength; n++ ) + { + temp = mult_r( mu, ( *ptrs++ ) ); + temp = add_sat( temp, *ptrs ); /*Q12 */ + sig_out[n] = shl_o( mult_r( ga, temp ), 1, &Overflow ); + move16(); /*Q12 */ + } + + return; +} + +static void scale_st_swb( + const Word16 *sig_in_fx, /* i : postfilter i signal */ + Word16 *sig_out_fx, /* i/o: postfilter o signal */ + Word16 *gain_prec_fx, /* i/o: last value of gain for subframe */ + Word16 SubFrameLength ) +{ + Word16 i; + Word16 agc_fac1_para_fx; + Word16 agc_fac_para_fx; + Word32 L_acc, L_temp; + Word16 g0_fx, gain_fx; + Word16 scal_in, scal_out; + Word16 s_g_in, s_g_out, sh_g0, temp; + + + IF( EQ_16( SubFrameLength, L_SUBFR ) ) + { + agc_fac1_para_fx = AGC_FAC1_FX; + move16(); + agc_fac_para_fx = AGC_FAC_FX; + move16(); + } + ELSE /*IF( SubFrameLength == L_SUBFR16k ) */ + { + agc_fac1_para_fx = AGC_FAC1_WB_FX; + move16(); + agc_fac_para_fx = AGC_FAC_WB_FX; + move16(); + } + + /* compute input gain */ + L_acc = L_mult0( 1, abs_s( sig_in_fx[0] ) ); /*0 +Q_bwe_exc-1 */ + FOR( i = 1; i < SubFrameLength; i++ ) + { + L_acc = L_mac0( L_acc, 1, abs_s( sig_in_fx[i] ) ); /*Q_bwe_exc-1 */ + } + + g0_fx = 0; + move16(); + IF( L_acc != 0L ) + { + scal_in = norm_l( L_acc ); + L_acc = L_shl( L_acc, scal_in ); + s_g_in = extract_h( L_acc ); /* normalized */ + + /* Compute o gain */ + L_acc = L_mult0( 1, abs_s( sig_out_fx[0] ) ); + FOR( i = 1; i < SubFrameLength; i++ ) + { + L_acc = L_mac0( L_acc, 1, abs_s( sig_out_fx[i] ) ); + } + IF( L_acc == 0L ) + { + *gain_prec_fx = 0; + move16(); + + return; + } + + scal_out = norm_l( L_acc ); + L_acc = L_shl( L_acc, scal_out ); + s_g_out = extract_h( L_acc ); /* normalized */ + + + sh_g0 = add( scal_in, 1 ); + sh_g0 = sub( sh_g0, scal_out ); /* scal_in - scal_out + 1 */ + IF( LT_16( s_g_in, s_g_out ) ) + { + g0_fx = div_s( s_g_in, s_g_out ); /* s_g_in/s_g_out in Q15 */ + } + ELSE + { + temp = sub( s_g_in, s_g_out ); /* sufficient since normalized */ + g0_fx = shr( div_s( temp, s_g_out ), 1 ); + g0_fx = add( g0_fx, (Word16) 0x4000 ); /* s_g_in/s_g_out in Q14 */ + sh_g0 = sub( sh_g0, 1 ); + } + /* L_gain_in/L_gain_out in Q14 */ + /* overflows if L_gain_in > 2 * L_gain_out */ + g0_fx = shr_sat( g0_fx, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */ // Need to verify? + + g0_fx = mult_r( g0_fx, agc_fac1_para_fx ); /* L_gain_in/L_gain_out * AGC_FAC1_FX */ + } + /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */ + /* sig_out(n) = gain(n) sig_out(n) */ + gain_fx = *gain_prec_fx; + move16(); /*14 */ + FOR( i = 0; i < SubFrameLength; i++ ) + { + temp = mult_r( agc_fac_para_fx, gain_fx ); /*15 +14 -15 =14 */ + gain_fx = add( temp, g0_fx ); /* in Q14 */ + L_temp = L_mult( gain_fx, sig_out_fx[i] ); /*14 + Q_bwe_exc-1 +1 = 14 + Q_bwe_exc */ + L_temp = L_shl_sat( L_temp, 1 ); /*14 + Q_bwe_exc +1 */ + sig_out_fx[i] = round_fx_sat( L_temp ); /*Q_bwe_exc +15 -16 = Q_bwe_exc-1 */ + move16(); + } + *gain_prec_fx = gain_fx; + move16(); + + return; +} + +void PostShortTerm_fx( + Word16 *sig_in, /* i : input signal (pointer to current subframe */ + Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ + Word16 *sig_out, /* o : postfiltered output */ + Word16 *mem_stp, /* i/o: postfilter memory*/ + Word16 *ptr_mem_stp, /* i/o: pointer to postfilter memory*/ + Word16 *ptr_gain_prec, /* i/o: for gain adjustment*/ + Word16 *mem_zero, /* i/o: null memory to compute h_st*/ + const Word16 formant_fac_fx /* i : Strength of post-filter*/ +) +{ + Word16 apond1_fx[LPC_SHB_ORDER + 1]; /* denominator coeff.*/ + Word16 apond2_fx[LONG_H_ST]; /* numerator coeff. */ + Word16 sig_ltp_fx[L_SUBFR16k + 1]; /* residual signal */ + /*Word16 lpccoeff_fx[LPC_SHB_ORDER+1];//Q12 */ + Word16 g1_fx, g2_fx, parcor0_fx; /*Q15 */ + Word16 tmp; + + parcor0_fx = 0; + move16(); + set16_fx( apond1_fx, 0, LPC_SHB_ORDER + 1 ); + set16_fx( apond2_fx, 0, LONG_H_ST ); + set16_fx( sig_ltp_fx, 0, L_SUBFR16k + 1 ); + + /* Obtain post-filter weights */ + tmp = extract_h( L_mult( GAMMA_SHARP_FX, formant_fac_fx ) ); /*Q15 */ + g1_fx = add( GAMMA0_FX, tmp ); /*Q15 */ + g2_fx = sub( GAMMA0_FX, tmp ); /*Q15 */ + + /* Compute weighted LPC coefficients */ + weight_a_fx( lpccoeff, apond1_fx, g1_fx, LPC_SHB_ORDER ); + weight_a_fx( lpccoeff, apond2_fx, g2_fx, LPC_SHB_ORDER ); + /* o: apond1_fx, apond2_fx in Q12 */ + + /* Compute A(gamma2) residual */ + Residu3_10_fx( apond2_fx, sig_in, sig_ltp_fx + 1, L_SUBFR16k, 0 ); + /* o: sig_ltp_fx in Q_bwe_exc */ + + /* Save last output of 1/A(gamma1) */ + sig_ltp_fx[0] = *ptr_mem_stp; + move16(); + + /* Control short term pst filter gain and compute parcor0 */ + Calc_st_filt_tbe( apond2_fx, apond1_fx, &parcor0_fx, sig_ltp_fx + 1, mem_zero ); + /* o: parcor0 in Q15 */ + /* i/o: sig_ltp_fx in Q_bwe_exc */ + + /* 1/A(gamma1) filtering, mem_stp is updated */ + Syn_filt_s( 0, apond1_fx, LPC_SHB_ORDER, sig_ltp_fx + 1, sig_ltp_fx + 1, L_SUBFR16k, mem_stp, 1 ); + + /* (1 + mu z-1) tilt filtering */ + filt_mu_fx( sig_ltp_fx, sig_out, parcor0_fx, L_SUBFR16k ); + /* o: sig_out in Q_bwe_exc */ + + /* gain control */ + scale_st_swb( sig_in, sig_out, ptr_gain_prec, L_SUBFR16k ); + + return; +} + +void PostShortTerm_ivas_enc_fx( + Word16 *sig_in, /* i : input signal (pointer to current subframe */ + Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ + Word16 *sig_out, /* o : postfiltered output */ + Word16 *mem_stp, /* i/o: postfilter memory*/ + Word16 *ptr_mem_stp, /* i/o: pointer to postfilter memory*/ + Word16 *ptr_gain_prec, /* i/o: for gain adjustment*/ + Word16 *mem_zero, /* i/o: null memory to compute h_st*/ + const Word16 formant_fac_fx /* i : Strength of post-filter*/ +) +{ + Word16 apond1_fx[LPC_SHB_ORDER + 1]; /* denominator coeff.*/ + Word16 apond2_fx[LONG_H_ST]; /* numerator coeff. */ + Word16 sig_ltp_fx[L_SUBFR16k + 1]; /* residual signal */ + /*Word16 lpccoeff_fx[LPC_SHB_ORDER+1];//Q12 */ + Word16 g1_fx, g2_fx, parcor0_fx; /*Q15 */ + Word16 tmp; + + parcor0_fx = 0; + move16(); + set16_fx( apond1_fx, 0, LPC_SHB_ORDER + 1 ); + set16_fx( apond2_fx, 0, LONG_H_ST ); + set16_fx( sig_ltp_fx, 0, L_SUBFR16k + 1 ); + + /* Obtain post-filter weights */ + tmp = extract_h( L_mult( GAMMA_SHARP_FX, formant_fac_fx ) ); /*Q15 */ + g1_fx = add( GAMMA0_FX, tmp ); /*Q15 */ + g2_fx = sub( GAMMA0_FX, tmp ); /*Q15 */ + + /* Compute weighted LPC coefficients */ + weight_a_fx( lpccoeff, apond1_fx, g1_fx, LPC_SHB_ORDER ); + weight_a_fx( lpccoeff, apond2_fx, g2_fx, LPC_SHB_ORDER ); + /* o: apond1_fx, apond2_fx in Q12 */ + + /* Compute A(gamma2) residual */ + Residu3_10_fx( apond2_fx, sig_in, sig_ltp_fx + 1, L_SUBFR16k, 0 ); + /* o: sig_ltp_fx in Q_bwe_exc */ + + /* Save last output of 1/A(gamma1) */ + sig_ltp_fx[0] = *ptr_mem_stp; + move16(); + + /* Control short term pst filter gain and compute parcor0 */ + Calc_st_filt_tbe_ivas_enc_fx( apond2_fx, apond1_fx, &parcor0_fx, sig_ltp_fx + 1, mem_zero ); + /* o: parcor0 in Q15 */ + /* i/o: sig_ltp_fx in Q_bwe_exc */ + + /* 1/A(gamma1) filtering, mem_stp is updated */ + syn_filt_fx( 0, apond1_fx, LPC_SHB_ORDER, sig_ltp_fx + 1, sig_ltp_fx + 1, L_SUBFR16k, mem_stp, 1 ); + + /* (1 + mu z-1) tilt filtering */ + filt_mu_fx( sig_ltp_fx, sig_out, parcor0_fx, L_SUBFR16k ); + /* o: sig_out in Q_bwe_exc */ + + /* gain control */ + scale_st_swb( sig_in, sig_out, ptr_gain_prec, L_SUBFR16k ); + + return; +} + +void PostShortTerm_ivas_dec_fx( + Word16 *sig_in, /* i : input signal (pointer to current subframe */ + Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ + Word16 *sig_out, /* o : postfiltered output */ + Word16 *mem_stp, /* i/o: postfilter memory*/ + Word16 *ptr_mem_stp, /* i/o: pointer to postfilter memory*/ + Word16 *ptr_gain_prec, /* i/o: for gain adjustment*/ + Word16 *mem_zero, /* i/o: null memory to compute h_st*/ + const Word16 formant_fac_fx /* i : Strength of post-filter*/ +) +{ + Word16 apond1_fx[LPC_SHB_ORDER + 1]; /* denominator coeff.*/ + Word16 apond2_fx[LONG_H_ST]; /* numerator coeff. */ + Word16 sig_ltp_fx[L_SUBFR16k + 1]; /* residual signal */ + /*Word16 lpccoeff_fx[LPC_SHB_ORDER+1];//Q12 */ + Word16 g1_fx, g2_fx, parcor0_fx; /*Q15 */ + Word16 tmp; + + parcor0_fx = 0; + move16(); + set16_fx( apond1_fx, 0, LPC_SHB_ORDER + 1 ); + set16_fx( apond2_fx, 0, LONG_H_ST ); + set16_fx( sig_ltp_fx, 0, L_SUBFR16k + 1 ); + + /* Obtain post-filter weights */ + tmp = extract_h( L_mult( GAMMA_SHARP_FX, formant_fac_fx ) ); /*Q15 */ + g1_fx = add( GAMMA0_FX, tmp ); /*Q15 */ + g2_fx = sub( GAMMA0_FX, tmp ); /*Q15 */ + + /* Compute weighted LPC coefficients */ + weight_a_fx( lpccoeff, apond1_fx, g1_fx, LPC_SHB_ORDER ); + weight_a_fx( lpccoeff, apond2_fx, g2_fx, LPC_SHB_ORDER ); + /* o: apond1_fx, apond2_fx in Q12 */ + + /* Compute A(gamma2) residual */ + Residu3_10_fx( apond2_fx, sig_in, sig_ltp_fx + 1, L_SUBFR16k, 0 ); + /* o: sig_ltp_fx in Q_bwe_exc */ + + /* Save last output of 1/A(gamma1) */ + sig_ltp_fx[0] = *ptr_mem_stp; + move16(); + + /* Control short term pst filter gain and compute parcor0 */ + Calc_st_filt_tbe_ivas_dec_fx( apond2_fx, apond1_fx, &parcor0_fx, sig_ltp_fx + 1, mem_zero ); + /* o: parcor0 in Q15 */ + /* i/o: sig_ltp_fx in Q_bwe_exc */ + + /* 1/A(gamma1) filtering, mem_stp is updated */ + Syn_filt_s( 0, apond1_fx, LPC_SHB_ORDER, sig_ltp_fx + 1, sig_ltp_fx + 1, L_SUBFR16k, mem_stp, 1 ); + + /* (1 + mu z-1) tilt filtering */ + filt_mu_fx( sig_ltp_fx, sig_out, parcor0_fx, L_SUBFR16k ); + /* o: sig_out in Q_bwe_exc */ + + /* gain control */ + scale_st_swb( sig_in, sig_out, ptr_gain_prec, L_SUBFR16k ); + + return; +} + +void flip_spectrum_and_decimby4_fx( + const Word16 input[], /* i : input spectrum Q_inp */ + Word16 output[], /* o : output spectrum Q_inp */ + const Word16 length, /* i : vector length */ + Word16 mem1[], /* i/o : memory Q_inp */ + Word16 mem2[], /* i/o : memory Q_inp */ + const Word16 ramp_flag /*i: flag to trigger slow ramp-up of output following change of core (HQ to ACELP or 12k8 to 16k ACELP) */ +) +{ + Word16 i; + Word16 factor, tmp[L_FRAME16k / 2]; + Word16 tmp1, tmp2; + Word16 input_change[L_FRAME16k]; + + IF( ramp_flag ) + { + factor = div_s( 4, length ); /* Q15 */ + FOR( i = 0; i < length / 4; i += 2 ) + { + tmp1 = extract_l( L_mult0( i, factor ) ); /* Q15 */ + tmp2 = extract_l( L_mult0( add( i, 1 ), factor ) ); /*Q15 */ + input_change[i] = negate( mult_r( input[i], tmp1 ) ); + move16(); + input_change[i + 1] = mult_r( input[i + 1], tmp2 ); + move16(); + } + } + ELSE + { + i = 0; + move16(); + } + + FOR( ; i < length; i = i + 2 ) + { + input_change[i] = negate( input[i] ); + move16(); + input_change[i + 1] = input[i + 1]; + move16(); + } + + Decimate_allpass_steep_fx( input_change, mem1, length, tmp ); + Decimate_allpass_steep_fx( tmp, mem2, shr( length, 1 ), output ); + + return; +} + + +/*==========================================================================*/ +/* FUNCTION : void GenShapedWBExcitation_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Synthesize spectrally shaped highband excitation signal for the wideband */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 *lpc_shb i : lpc coefficients Q12 */ +/* _Word16 coder_type i : coding type */ +/* _Word16 *bwe_exc_extended i : bwidth extended exciatation Q_bwe_exc*/ +/* _Word16 Q_bwe_exc i : Q format */ +/* _Word16 voice_factors[] i : voicing factor Q15 */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 *excSHB o : synthesized shaped shb exctiation Q_bwe_exc*/ +/* _Word16 *exc4kWhtnd o : whitened synthesized shb excitation Q_bwe_exc*/ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _Word32 *mem_csfilt i/o : memory Q_bwe_exc+16*/ +/* _Word16 *mem_genSHBexc_filt_down1 i/o : memory Q_bwe_exc */ +/* _Word16 *mem_genSHBexc_filt_down2 i/o : memory Q_bwe_exc */ +/* _Word16 *mem_genSHBexc_filt_down3 i/o : memory Q_bwe_exc */ +/* _Word16 *state_lpc_syn i/o : memory Q_bwe_exc */ +/* _Word16 bwe_seed[] i/o : random number generator seed */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ + +void GenShapedWBExcitation_ivas_fx( + Word16 *excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q_bwe_exc*/ + Word32 *mem_csfilt, /* i/o : memory Q_bwe_exc+16*/ + Word16 *mem_genSHBexc_filt_down1, /* i/o : memory Q_bwe_exc*/ + Word16 *mem_genSHBexc_filt_down2, /* i/o : memory Q_bwe_exc*/ + Word16 *mem_genSHBexc_filt_down3, /* i/o : memory Q_bwe_exc*/ + Word16 *state_lpc_syn, /* i/o : memory Q_bwe_exc*/ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended exciatation Q_bwe_exc*/ + const Word16 Q_bwe_exc, + Word16 bwe_seed[], /* i/o : random number generator seed */ + const Word16 voice_factors[], /* i : voicing factor Q15*/ + const Word16 uv_flag, /* i : unvoiced flag */ + const Word16 igf_flag ) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER_WB]; + Word16 lpc_whtn[LPC_WHTN_ORDER_WB + 1]; + Word16 R_h[LPC_WHTN_ORDER_WB + 2], R_l[LPC_WHTN_ORDER_WB + 2]; + Word16 Q_R; + Word16 excTmp[L_FRAME16k]; + Word16 excTmp2[L_FRAME16k / 4]; + Word16 excTmp2_frac[L_FRAME16k / 4]; + Word16 exc4k[L_FRAME16k / 4]; + Word16 exc4k_frac[L_FRAME16k / 4]; + Word32 exc4k_32[L_FRAME16k / 4]; + Word32 pow1, pow22; + Word16 scale; + Word32 excNoisyEnv[L_FRAME16k / 4]; + Word16 csfilt_num2[1] = { 1638 }; /* Q15*/ + Word16 neg_csfilt_den2[2] = { -32768, 31457 }; /* Q15 */ + Word32 L_tmp, Ltemp1, Ltemp2; + Word16 temp1, temp2, exp; + Word32 Lmax; + Word16 max_val, n1, n2, sc; + Word32 LepsP[LPC_WHTN_ORDER_WB + 1]; + Word16 tmp_vfac; + Word16 avg_voice_fac; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + + /*0.25f*sum_f(voice_factors, NB_SUBFR)*/ + L_tmp = L_mult( voice_factors[0], 8192 /* 0.25 in Q15 */ ); + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mac( L_tmp, voice_factors[i], 8192 /* 0.25 in Q15 */ ); + } + avg_voice_fac = round_fx( L_tmp ); + + test(); + test(); + test(); + test(); + IF( igf_flag != 0 && ( EQ_16( coder_type, VOICED ) || GT_16( avg_voice_fac, 11469 /* 0.35 in Q15 */ ) ) ) /*Q15 -> 0.35f*/ + { + csfilt_num2[0] = 6554; + move16(); /*Q15 -> 0.2f*/ + neg_csfilt_den2[1] = 26214; + move16(); /*Q15 -> 0.8f*/ + } + ELSE IF( igf_flag != 0 && ( EQ_16( coder_type, UNVOICED ) || LT_16( avg_voice_fac, 6654 /* 0.2 in Q15*/ ) ) ) /*Q15 -> 0.2f*/ + { + csfilt_num2[0] = 328; + move16(); /*Q15 -> 0.01f*/ + neg_csfilt_den2[1] = 32440; + move16(); /*Q15 -> 0.99f*/ + } + set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER_WB ); + Decimate_allpass_steep_fx( bwe_exc_extended, mem_genSHBexc_filt_down1, L_FRAME32k, excTmp ); + flip_spectrum_and_decimby4_fx( excTmp, exc4k, L_FRAME16k, mem_genSHBexc_filt_down2, mem_genSHBexc_filt_down3, 0 ); + + IF( uv_flag ) + { + create_random_vector_fx( exc4kWhtnd, L_FRAME16k / 4, bwe_seed ); + IF( LT_16( Q_bwe_exc, 5 ) ) + { + + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4kWhtnd[i] = shl_r( exc4kWhtnd[i], sub( Q_bwe_exc, 5 ) ); /*Q(Q_bwe_exc)/Q5(if Q_bwe_exc > 5) */ + move16(); + } + } + } + ELSE + { + autocorr_fx( exc4k, LPC_WHTN_ORDER_WB + 1, R_h, R_l, &Q_R, + L_FRAME16k / 4, win_flatten_4k_fx, 0, 1 ); + + /* Ensure R[0] isn't zero when entering Levinson Durbin */ + R_l[0] = s_max( R_l[0], 1 ); + move16(); + FOR( i = 1; i <= LPC_WHTN_ORDER_WB; i++ ) + { + L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); + L_Extract( L_tmp, &R_h[i], &R_l[i] ); + } + + E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER_WB, NULL ); + + Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER_WB + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); + + fir_fx( exc4k, lpc_whtn, exc4kWhtnd, wht_fil_mem, L_FRAME16k / 4, + LPC_WHTN_ORDER_WB, 0, 3 ); + + /* Ensure pow1 is greater than zero when computing normalization */ + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excTmp2[i] = abs_s( exc4kWhtnd[i] ); + move16(); /* Q_bwe_exc */ + max_val = s_max( max_val, excTmp2[i] ); + move16(); + } + + IF( max_val == 0 ) + { + pow1 = 1; + move16(); + n1 = 0; + move16(); + } + ELSE + { + n1 = norm_s( max_val ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); // Q_bwe_exc + n1 + move16(); /* Q14 */ + } + n1 = sub( sub( 14, n1 ), Q_bwe_exc ); + pow1 = 1; + move32(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ + pow1 = L_add_o( pow1, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ + } + } + + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); + move32(); /* Q_bwe_exc+16 */ + *mem_csfilt = Mult_32_16( excNoisyEnv[i], neg_csfilt_den2[1] ); + move32(); /* Q_bwe_exc+16 */ + } + + create_random_vector_fx( exc4k, L_FRAME16k / 4, bwe_seed ); + + /* Ensure pow22 is greater than zero when computing normalization */ + Lmax = 0; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4k_32[i] = Mult_32_16( excNoisyEnv[i], exc4k[i] ); + move32(); /* Q_bwe_exc+6 */ + Lmax = L_max( Lmax, L_abs( exc4k_32[i] ) ); + } + + IF( Lmax == 0 ) + { + pow22 = 1; + move16(); + n2 = 0; + move16(); + set16_fx( exc4k_frac, 0, L_FRAME16k / 4 ); + } + ELSE + { + n2 = norm_l( Lmax ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ + move16(); + } + n2 = 30 - n2 - ( Q_bwe_exc + 6 ); + pow22 = 1; + move32(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ + pow22 = L_add_o( pow22, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ + } + } + + test(); + test(); + IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 /* 0.2 in Q15 */ ) ) ) + { + L_tmp = root_a_over_b_fx( pow1, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); + scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ + sc = sub( add( n2, Q_bwe_exc ), 14 ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ + move16(); + } + } + ELSE + { + sc = sub( add( n2, Q_bwe_exc ), 14 ); /* Q_bwe_exc+n2-14*/ + + k = 0; + FOR( i = 0; i < 4; i++ ) + { + test(); + IF( igf_flag != 0 && EQ_16( coder_type, VOICED ) ) + { + /*tmp_vfac = 2*voice_factors[i]; + tmp_vfac = min(1, tmp_vfac);*/ + tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); + } + ELSE + { + tmp_vfac = voice_factors[i]; + move16(); + } + + Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); + temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ + L_tmp = Mult_32_16( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ + Ltemp2 = root_a_over_b_fx( L_tmp, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); + temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ + FOR( j = 0; j < L_FRAME16k / 16; j++ ) + { + L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ + L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ + exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ + move16(); + k++; + } + } + } + } + + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); + + return; +} + +void GenShapedWBExcitation_fx( + Word16 *excSHB, /* o : synthesized shaped shb exctiation Q(Q_bwe_exc) */ + const Word16 *lpc_shb, /* i : lpc coefficients Q12 */ + Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q(Q_bwe_exc) */ + Word32 *mem_csfilt, /* i/o : memory Q(Q_bwe_exc+16) */ + Word16 *mem_genSHBexc_filt_down1, /* i/o : memory Q(Q_bwe_exc) */ + Word16 *mem_genSHBexc_filt_down2, /* i/o : memory Q(Q_bwe_exc) */ + Word16 *mem_genSHBexc_filt_down3, /* i/o : memory Q(Q_bwe_exc) */ + Word16 *state_lpc_syn, /* i/o : memory Q(Q_bwe_exc) */ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended exciatation Q(Q_bwe_exc) */ + const Word16 Q_bwe_exc, /* i : Q for memories */ + Word16 bwe_seed[], /* i/o : random number generator seed */ + const Word16 voice_factors[], /* i : voicing factor Q15 */ + const Word16 uv_flag, /* i : unvoiced flag */ + const Word16 igf_flag ) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER_WB]; + Word16 lpc_whtn[LPC_WHTN_ORDER_WB + 1]; + Word16 R_h[LPC_WHTN_ORDER_WB + 2], R_l[LPC_WHTN_ORDER_WB + 2]; + Word16 Q_R; + Word16 excTmp[L_FRAME16k]; + Word16 excTmp2[L_FRAME16k / 4]; + Word16 excTmp2_frac[L_FRAME16k / 4]; + Word16 exc4k[L_FRAME16k / 4]; + Word16 exc4k_frac[L_FRAME16k / 4]; + Word32 exc4k_32[L_FRAME16k / 4]; + Word32 pow1, pow22; + Word16 scale; + Word32 excNoisyEnv[L_FRAME16k / 4]; + Word16 csfilt_num2[1] = { 1638 }; /* Q15*/ + Word16 neg_csfilt_den2[2] = { -32768, 31457 }; /* Q15 */ + Word32 L_tmp, Ltemp1, Ltemp2; + Word16 temp1, temp2, exp; + Word32 Lmax; + Word16 max_val, n1, n2, sc; + Word32 LepsP[LPC_WHTN_ORDER_WB + 1]; + Word16 tmp_vfac; + Word16 avg_voice_fac; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + move16(); + move16(); + move16(); + + /*0.25f*sum_f(voice_factors, NB_SUBFR)*/ + L_tmp = L_mult( voice_factors[0], 8192 /*0.25 in Q15 */ ); + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mac( L_tmp, voice_factors[i], 8192 /*0.25 in Q15 */ ); + } + avg_voice_fac = round_fx( L_tmp ); + + test(); + test(); + test(); + test(); + IF( igf_flag != 0 && ( EQ_16( coder_type, VOICED ) || GT_16( avg_voice_fac, 11469 /* 0.35 in Q15 */ ) ) ) /*Q15 -> 0.35f*/ + { + csfilt_num2[0] = 6554; + move16(); /*Q15 -> 0.2f*/ + neg_csfilt_den2[1] = 26214; + move16(); /*Q15 -> 0.8f*/ + } + ELSE IF( igf_flag != 0 && ( EQ_16( coder_type, UNVOICED ) || LT_16( avg_voice_fac, 6654 /* 0.2 in Q15 */ ) ) ) /*Q15 -> 0.2f*/ + { + csfilt_num2[0] = 328; + move16(); /*Q15 -> 0.01f*/ + neg_csfilt_den2[1] = 32440; + move16(); /*Q15 -> 0.99f*/ + } + set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER_WB ); + Decimate_allpass_steep_fx( bwe_exc_extended, mem_genSHBexc_filt_down1, L_FRAME32k, excTmp ); + flip_spectrum_and_decimby4_fx( excTmp, exc4k, L_FRAME16k, mem_genSHBexc_filt_down2, mem_genSHBexc_filt_down3, 0 ); + + IF( uv_flag ) + { + create_random_vector_fx( exc4kWhtnd, L_FRAME16k / 4, bwe_seed ); + IF( LT_16( Q_bwe_exc, 5 ) ) + { + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4kWhtnd[i] = shl_r( exc4kWhtnd[i], sub( Q_bwe_exc, 5 ) ); /*Q(Q_bwe_exc)/Q5(if Q_bwe_exc > 5) */ + move16(); + } + } + } + ELSE + { + autocorr_fx( exc4k, LPC_WHTN_ORDER_WB + 1, R_h, R_l, &Q_R, + L_FRAME16k / 4, win_flatten_4k_fx, 0, 1 ); + + /* Ensure R[0] isn't zero when entering Levinson Durbin */ + R_l[0] = s_max( R_l[0], 1 ); + move16(); + FOR( i = 1; i <= LPC_WHTN_ORDER_WB; i++ ) + { + L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); + L_Extract( L_tmp, &R_h[i], &R_l[i] ); + } + + E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER_WB, NULL ); + + Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER_WB + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); + + fir_fx( exc4k, lpc_whtn, exc4kWhtnd, wht_fil_mem, L_FRAME16k / 4, + LPC_WHTN_ORDER_WB, 0, 3 ); + + /* Ensure pow1 is greater than zero when computing normalization */ + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excTmp2[i] = abs_s( exc4kWhtnd[i] ); + move16(); /* Q_bwe_exc */ + max_val = s_max( max_val, excTmp2[i] ); + move16(); + } + + IF( max_val == 0 ) + { + pow1 = 1; + move16(); + n1 = 0; + move16(); + } + ELSE + { + n1 = norm_s( max_val ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); + move16(); /* Q14 */ + } + n1 = sub( sub( 14, n1 ), Q_bwe_exc ); + pow1 = 1; + move32(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ + pow1 = L_add_o( pow1, L_shr( L_tmp, 7 ), &Overflow ); /* Q22 */ + } + } + + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); + move32(); /* Q_bwe_exc+16 */ + *mem_csfilt = Mpy_32_16_1( excNoisyEnv[i], neg_csfilt_den2[1] ); + move32(); /* Q_bwe_exc+16 */ + } + + create_random_vector_fx( exc4k, L_FRAME16k / 4, bwe_seed ); + + /* Ensure pow22 is greater than zero when computing normalization */ + Lmax = 0; + move32(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4k_32[i] = Mpy_32_16_1( excNoisyEnv[i], exc4k[i] ); + move32(); /* Q_bwe_exc+6 */ + Lmax = L_max( Lmax, L_abs( exc4k_32[i] ) ); + } + + IF( Lmax == 0 ) + { + pow22 = 1; + move16(); + n2 = 0; + move16(); + set16_fx( exc4k_frac, 0, L_FRAME16k / 4 ); + } + ELSE + { + n2 = norm_l( Lmax ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ + move16(); + } + n2 = sub( sub( 30, n2 ), add( Q_bwe_exc, 6 ) ); + pow22 = 1; + move32(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ + pow22 = L_add_o( pow22, L_shr( L_tmp, 7 ), &Overflow ); /* Q22 */ + } + } + + test(); + test(); + IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 /*0.2 in Q15 */ ) ) ) + { + L_tmp = root_a_over_b_fx( pow1, sub( 22, shl( n1, 1 ) ), pow22, sub( 22, shl( n2, 1 ) ), &exp ); + scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ + sc = sub( add( n2, Q_bwe_exc ), 14 ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ + move16(); + } + } + ELSE + { + sc = sub( add( n2, Q_bwe_exc ), 14 ); /* Q_bwe_exc+n2-14*/ + + k = 0; + move16(); + FOR( i = 0; i < 4; i++ ) + { + test(); + IF( igf_flag != 0 && EQ_16( coder_type, VOICED ) ) + { + /*tmp_vfac = 2*voice_factors[i]; + tmp_vfac = min(1, tmp_vfac);*/ + tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); + } + ELSE + { + tmp_vfac = voice_factors[i]; + move16(); + } + + Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); + temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ + L_tmp = Mpy_32_16_1( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ + Ltemp2 = root_a_over_b_fx( L_tmp, sub( 22, shl( n1, 1 ) ), pow22, sub( 22, shl( n2, 1 ) ), &exp ); + temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ + FOR( j = 0; j < L_FRAME16k / 16; j++ ) + { + L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ + L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ + exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ + move16(); + k = add( k, 1 ); + } + } + } + } + + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); + + + return; +} + +/*-------------------------------------------------------------------* + * GenWBSynth() + * + * Generate 16 KHz sampled highband component from synthesized highband + *-------------------------------------------------------------------*/ + +void GenWBSynth_fx( + const Word16 *input_synspeech, /* i : input synthesized speech Qx*/ + Word16 *shb_syn_speech_16k, /* o : output highband compnent Qx*/ + Word16 *state_lsyn_filt_shb1, /* i/o: memory Qx*/ + Word16 *state_lsyn_filt_shb2 /* i/o: memory Qx*/ +) +{ + Word16 speech_buf_16k1[L_FRAME16k], speech_buf_16k2[L_FRAME16k]; + Word16 i, maxm, nor; + Word16 input_synspeech_temp[L_FRAME16k / 4]; + + maxm = 0; + move16(); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + maxm = s_max( maxm, abs_s( input_synspeech[i] ) ); + } + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + maxm = s_max( maxm, abs_s( state_lsyn_filt_shb1[i] ) ); + } + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + maxm = s_max( maxm, abs_s( state_lsyn_filt_shb2[i] ) ); + } + + nor = s_max( sub( norm_s( maxm ), 3 ), 0 ); /* Headroom = 3 */ + IF( maxm == 0 ) + nor = 15; + move16(); + + Copy_Scale_sig( input_synspeech, input_synspeech_temp, L_FRAME16k / 4, nor ); + Scale_sig( state_lsyn_filt_shb1, 2 * ALLPASSSECTIONS_STEEP, nor ); + Scale_sig( state_lsyn_filt_shb2, 2 * ALLPASSSECTIONS_STEEP, nor ); + Interpolate_allpass_steep_fx( input_synspeech_temp, state_lsyn_filt_shb1, L_FRAME16k / 4, speech_buf_16k1 ); + Interpolate_allpass_steep_fx( speech_buf_16k1, state_lsyn_filt_shb2, L_FRAME16k / 2, speech_buf_16k2 ); + flip_spectrum_fx( speech_buf_16k2, shb_syn_speech_16k, L_FRAME16k ); + + Scale_sig( shb_syn_speech_16k, L_FRAME16k, negate( nor ) ); + Scale_sig( state_lsyn_filt_shb1, 2 * ALLPASSSECTIONS_STEEP, negate( nor ) ); + Scale_sig( state_lsyn_filt_shb2, 2 * ALLPASSSECTIONS_STEEP, negate( nor ) ); + + return; +} + + +void find_td_envelope_fx( + const Word16 inp[], /* i : input signal Qx */ + const Word16 len, /* i : length of the input signal */ + const Word16 len_h, /* i : length of the MA filter */ + Word16 mem_h[], /* i/o: memory of the MA filter, length len_h/2 Qx */ + Word16 out[] /* o : td envelope of the input signal Qx */ +) +{ + Word16 k, K; + Word16 buf_in[L_FRAME16k + MAX_LEN_MA_FILTER], *p_in, *p_out, *p_prev, w; + Word16 tmp1, tmp2; + + assert( len > 0 && len <= L_FRAME16k ); + + // len_h is 20 at all calling locations + K = 10; /* length of FIR filter memory = half of the total filter length */ + move16(); + w = 1639; /* 1 / 20 in Q15 */ /* MA filtering coefficient */ + move16(); + + /* copy filter memory to the input buffer */ + IF( mem_h != NULL ) + { + Copy( mem_h, buf_in, K ); + } + ELSE + { + /* no memory available, use the first len_h/2 samples as memory */ + p_in = buf_in; + FOR( k = 0; k < K; k++ ) + { + *p_in++ = mult_r( abs_s( inp[k] ), w ); /* Qx */ + move16(); + } + } + + /* take the absolute value of the input signal and copy it to the input buffer */ + /* multiply each value by 1 / filter length */ + p_in = &buf_in[K]; + FOR( k = 0; k < len; k++ ) + { + *p_in++ = mult_r( abs_s( inp[k] ), w ); /* Qx */ + move16(); + } + + /* update filter memory from the end of the input buffer */ + IF( mem_h != NULL ) + { + Copy( &buf_in[len], mem_h, K ); + } + + /* do MA filtering */ + out[0] = sum16_fx( buf_in, len_h ); + move16(); + p_out = &buf_in[0]; /* pointer to leaving sample */ + p_in = &buf_in[len_h]; /* pointer to entering sample*/ + FOR( k = 1; k < len - K; k++ ) + { + tmp1 = *p_out++; + move16(); + tmp2 = *p_in++; + move16(); + out[k] = add( sub( out[k - 1], tmp1 ), tmp2 ); /* Qx */ + move16(); + } + + /* use IIR filtering to extrapolate the last K samples */ + p_in = &buf_in[len - K]; + p_out = &out[len - K]; + p_prev = p_out - 1; + FOR( k = 0; k < K; k++ ) + { + tmp1 = *p_in++; + move16(); + tmp2 = *p_prev++; + move16(); + *p_out++ = add( mult_r( 1638 /* 0.05f in Q15 */, ( tmp1 ) ), mult_r( 31130 /* 0.95f in Q15 */, ( tmp2 ) ) ); + move16(); + } + + return; +} + + +/*======================================================================================*/ +/* FUNCTION : void GenShapedSHBExcitation_fx () */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Synthesize spectrally shaped highband excitation signal */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _(Word16) coder_type : coding type Q_bwe_exc */ +/* _(Word16) bwidth : input signal bwidth Q0 */ +/* _(Word16*) bwe_exc_extended :bwidth extended exciatation Q_bwe_exc */ +/* _(Word16[]) voice_factors :voicing factors Q15 */ +/* _(Word16*) lpc_shb :lpc coefficients Q12 */ +/* _(Word16*) Q_bwe_exc :Q Format of bwe_exc_extended */ +/* _(Word16) L_frame : Frame length - determines whether 12.8 or 16kHz core */ +/* _(Word16) last_L_frame : last L_frame */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _(Word16*)excSHB :synthesized shaped shb excitation Q_bwe_exc */ +/* _(Word16*)White_exc16k :white excitation for the Fullband extension Q_bwe_exc */ +/* _(Word16*)slope :slope +ve (high freq > low freq), -ve or neutral Q12 */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _(Word16*)mem_csfilt :memory */ +/* _(Word16*)mem_genSHBexc_filt_down_shb :memory */ +/* _(Word16*)state_lpc_syn :memory */ +/* _(Word16[]) bwe_seed :random number generator seed */ +/* _(Word16[]) lpf_14k_mem :memory */ +/* _(Word32[])Hilbert_Mem :memory */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*======================================================================================*/ +void GenShapedSHBExcitation_fx( + Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word32 *mem_csfilt, /* i/o: memory */ + Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ + Word16 *state_lpc_syn, /* i/o: memory */ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ + Word16 bwe_seed[], /* i/o: random number generator seed */ + Word16 voice_factors[], /* i : voicing factor*/ + const Word16 extl, /* i : extension layer */ + Word16 *tbe_demph, /* i/o: de-emphasis memory */ + Word16 *tbe_premph, /* i/o: pre-emphasis memory */ + Word16 *lpc_shb_sf, /* i: LP coefficients */ + const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ + Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ + Word16 *shb_res, + Word16 *vf_ind, + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + Word16 *Q_bwe_exc, + Word16 *Q_bwe_exc_fb, + const Word16 Q_shb, + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, + const Word16 prev_bfi +#ifdef ADD_IVAS_TBE_CODE + , /* i : previous frame was concealed */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ +#endif +) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER]; + Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; + Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ + Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ + Word16 Q_R; + Word32 LepsP[LPC_WHTN_ORDER + 1]; + Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; + Word32 pow1, pow22; + Word16 scale, temp1, temp2; + + Word16 excTmp2[L_FRAME16k]; + Word16 *White_exc16k; + Word16 excNoisyEnv[L_FRAME16k]; + Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ + move16(); + Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ + move16(); + move16(); + Word16 varEnvShape; + Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ + move16(); + Word16 exc16kWhtnd[L_FRAME16k]; + + Word32 L_tmp; + Word16 vf_tmp; + Word16 tmp, exp, tmp2; + Word16 voiceFacEst[NB_SUBFR16k]; + Word16 zero_mem[LPC_SHB_ORDER]; + Word32 syn_shb_ener_sf[4]; + Word16 tempSHB[80]; + Word16 Q_pow1, Q_pow22; + + Word32 L_tmp2, L_tmp3, L_tmp4; + Word16 temp; + + Word16 White_exc16k_FB_temp[L_FRAME16k]; + Word32 White_exc16k_32[L_FRAME16k]; + Word16 Q_temp; + Word16 prev_Q_bwe_exc_fb; + +#ifdef ADD_IVAS_TBE_CODE + Word32 tempD; + Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; + Word16 cbsize; + Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; + Word16 c0, c1, c2, c3, c4, c5, g1, g2, g, den; + Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; + Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; + Word16 flag_plosive; + Word16 delta; + Word16 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; + + mix_factor = 0.0f; +#endif + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); + set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); + + FOR( i = 0; i < L_FRAME32k; i = i + 2 ) + { + exc32k[i] = negate( bwe_exc_extended[i] ); + move16(); + exc32k[i + 1] = bwe_exc_extended[i + 1]; + move16(); + } + + /* Decimate by 2 */ + Decimate_allpass_steep_fx( exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k ); + /* i: exc32k in Q_bwe_exc */ + /* o: exc16k in Q_bwe_exc */ + + autocorr_fx( exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1 ); + /* Ensure R[0] isn't zero when entering Levinson Durbin */ + R_l[0] = s_max( R_l[0], 1 ); + move16(); + FOR( i = 1; i <= LPC_WHTN_ORDER; i++ ) + { + L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); + L_Extract( L_tmp, &R_h[i], &R_l[i] ); + } + E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL ); + Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); + fir_fx( exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3 ); + + /* i: exc16k in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc */ + +#ifdef ADD_IVAS_TBE_CODE + IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) +#else + IF( GE_32( bitrate, ACELP_24k40 ) ) +#endif + { + temp2 = 0; + move16(); + FOR( j = 0; j < 4; j++ ) + { + temp1 = shb_res_gshape[j]; + move16(); + FOR( i = 0; i < 80; i++ ) + { + exc16kWhtnd[temp2 + i] = round_fx( L_shl( L_mult( exc16kWhtnd[temp2 + i], temp1 ), 1 ) ); + move16(); + /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ + } + temp2 = add( temp2, 80 ); + } + } + + /* Estimate pow1 associated with Low band nonlinear extended excitation */ + /* pow1=0.00001f */ + tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); + pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ + excTmp2[k] = abs_s( exc16kWhtnd[k] ); + move16(); + + /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ + pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ + } + Q_pow1 = shl( *Q_bwe_exc, 1 ); + + test(); +#ifdef ADD_IVAS_TBE_CODE + IF( EQ_16( flag_ACELP16k, 0 ) ) +#else + IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) +#endif + { + /* varEnvShape = mean_fx(voice_factors, 4); */ + /* unroll the loop */ + L_tmp = L_mult( voice_factors[0], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors[1], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors[2], 8192 ); + varEnvShape = mac_r( L_tmp, voice_factors[3], 8192 ); /* varEnvShape in Q15 */ + } + ELSE /* 16k core */ + { + /* varEnvShape = mean_fx(voice_factors, 5); */ + /* unroll the loop */ + L_tmp = L_mult( voice_factors[0], 6554 ); + L_tmp = L_mac( L_tmp, voice_factors[1], 6554 ); + L_tmp = L_mac( L_tmp, voice_factors[2], 6554 ); + L_tmp = L_mac( L_tmp, voice_factors[3], 6554 ); + varEnvShape = mac_r( L_tmp, voice_factors[4], 6554 ); /* varEnvShape in Q15 */ + } + + IF( EQ_16( extl, FB_TBE ) ) + { + /*pow(varEnvShape,3) */ + tmp = mult_r( varEnvShape, varEnvShape ); + tmp = mult_r( tmp, varEnvShape ); + + /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ + fb_deemph_fac = sub( 22282 /*0.68f Q15*/, tmp ); + fb_deemph_fac = s_max( fb_deemph_fac, 15729 /*0.48f Q15*/ ); + } + + /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ + varEnvShape = msu_r( 1179773824l /*0.549375f Q31*/, 8172 /*0.249375f Q15*/, varEnvShape ); + + /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ + varEnvShape = s_max( varEnvShape, 9830 /*0.3f Q15*/ ); + varEnvShape = s_min( varEnvShape, 16368 /*0.4995f Q15*/ ); + varEnvShape = shl( varEnvShape, 1 ); + csfilt_num2[0] = sub( MAX_16, varEnvShape ); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + + test(); + test(); + test(); +#ifdef ADD_IVAS_TBE_CODE + IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) +#else + IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) +#endif + { + /* pre-init smoothing filter to avoid energy drop outs */ + L_tmp = L_mult( excTmp2[0], 1638 ); + FOR( i = 1; i < L_SUBFR16k / 4; i++ ) + { + L_tmp = L_mac( L_tmp, excTmp2[i], 1638 ); /*1638 = 1/20 in Q15*/ + } + /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ + + /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ + /* rather stick to the more conservative approach, to avoid potential clippings */ + test(); + IF( !( prev_bfi && EQ_16( extl, FB_TBE ) ) ) + { + /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ + varEnvShape = 26214 /*0.8f Q15*/; + move16(); + csfilt_num2[0] = sub( MAX_16, varEnvShape ); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + } + + *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); + move32(); + } +#ifdef ADD_IVAS_TBE_CODE + if ( MSFlag > 0 ) + { + varEnvShape = 0.995f; + csfilt_num2[0] = 1.0f - varEnvShape; + csfilt_den2[1] = -varEnvShape; + } + + White_exc16k = exc16k; + + /* Track the low band envelope */ + if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) + { + if ( extl_brate != SWB_TBE_1k10 && extl_brate != SWB_TBE_1k75 ) + { + mem_csfilt_left = 0.0f; + mem_csfilt_right = 0.0f; + for ( k = 0; k < L_FRAME16k; k++ ) + { + excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; + mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; + excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; + mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; + } + + alpha = 0.0f; + step = 1.0f / L_FRAME16k; + for ( k = 0; k < L_FRAME16k; k++ ) + { + excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + ( 1 - alpha ) * excNoisyEnvRight[k]; + alpha += step; + } + } + } + else +#endif + { + /* Track the low band envelope */ + L_tmp = *mem_csfilt; + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + excNoisyEnv[i] = mac_r( L_tmp, csfilt_num2[0], excTmp2[i] ); + move16(); + /* excNoisyEnv : Q_bwe_exc, + *mem_csfilt: Q_bwe_exc+16, excTmp2: Q_bwe_exc, csfilt_num2[0] Q15 */ + L_tmp = L_mult( excNoisyEnv[i], neg_csfilt_den2[1] ); /* Q_bwe_exc+16 */ + } + *mem_csfilt = L_tmp; + move32(); + } +#ifdef ADD_IVAS_TBE_CODE + if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) + { + /* generate gaussian (white) excitation */ + for ( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k[k] = (float) own_random( &bwe_seed[0] ); + } + + /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ + pow22 = POW_EXC16k_WHTND; + v_multc( White_exc16k, (float) sqrt( pow1 / pow22 ), White_exc16k, L_FRAME16k ); + } + else +#endif + { + /* create a random excitation - Reuse exc16k memory */ + White_exc16k = exc16k; + create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); + create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); + + L_tmp = L_deposit_l( 0 ); + tmp = add( *Q_bwe_exc, 1 ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + L_tmp4 = L_shl_sat( L_deposit_l( White_exc16k[k] ), tmp ); + if ( excNoisyEnv[k] != 0 ) + { + L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_bwe_exc) +5 +1*/ + } + White_exc16k_32[k] = L_tmp4; + move32(); + L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); + } + Q_temp = norm_l( L_tmp ); + if ( L_tmp == 0 ) + { + Q_temp = 31; + move16(); + } + /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ + /* White_exc16k in Q6 */ + + /* calculate pow22 */ + /* pow22=0.00001f */ + tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); + pow22 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc-NOISE_QADJ) */ + tmp = sub( NOISE_QFAC, 5 ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /* White_exc16k[k] *= excNoisyEnv[k]; */ + White_exc16k[k] = mult_r( excNoisyEnv[k], shl( White_exc16k[k], tmp ) ); + move16(); + /* i: excNoisyEnv in (Q_bwe_exc) */ + /* i: White_exc16k in Q6 */ + /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + /* pow22 += White_exc16k[k] * White_exc16k[k]; */ + pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ + } + /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ + Q_pow22 = shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ); + } + +#ifdef ADD_IVAS_TBE_CODE + flag_plosive = 0; + move16(); + test(); + test(); + test(); + IF(GE_32(extl_brate, SWB_TBE_2k8) || EQ_32(extl_brate, SWB_TBE_1k10) || EQ_32(extl_brate, SWB_TBE_1k75))) +#else + IF( GE_32( bitrate, ACELP_24k40 ) ) +#endif + { + IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ + { +#ifdef ADD_IVAS_TBE_CODE + if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) + { + /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ + find_td_envelope( White_exc16k, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); + find_td_envelope( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); + + for ( k = 0; k < L_FRAME4k; k++ ) + { + EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; + EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; + } + + /* calculate the optimal mix factor */ + c0 = c1 = c2 = c3 = c4 = c5 = 0.0f; + for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + + c0 += c0_part[i]; + c1 += c1_part[i]; + c2 += c2_part[i]; + c3 += c3_part[i]; + c4 += c4_part[i]; + c5 += c5_part[i]; + } + + den = 4.0f * c0 * c2 - c4 * c4; + g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; + g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; + + *Env_error = 0.0f; + flag_plosive = 0; + for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; + *Env_error += Env_error_part[i]; + + if ( Env_error_part[i] > THR_ENV_ERROR_PLOSIVE ) + { + /* envelope error is too high -> likely a plosive */ + flag_plosive = 1; + } + } + + if ( flag_plosive ) + { + /* plosive detected -> set the mixing factor to 0 */ + *vf_ind = 0; + mix_factor = 0.0f; + } + else + { + /* normalize gain */ + g = g2 / ( g1 + g2 ); + + /* quantization of the mixing factor */ + cbsize = 1 << NUM_BITS_SHB_VF; + delta = 1.0f / ( cbsize - 1 ); + if ( g > 1.0f ) + { + g = 1.0f; + } + else if ( g < delta ) + { + /* prevent low gains to be quantized to 0 as this is reserved for plosives */ + g = delta; + } + + *vf_ind = usquant( g, &mix_factor, 0.0f, 1.0f / ( cbsize - 1 ), cbsize ); + } + } + else +#endif + { + Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, + ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); + tmp = voiceFacEst[0]; + move16(); + tmp2 = MAX_16; + move16(); + if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) + { + tmp2 = 26214 /*0.8f Q15*/; + move16(); + } + } + } + ELSE /* decoder side */ + { +#ifdef ADD_IVAS_TBE_CODE + if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) + { + if ( *vf_ind == 0 ) + { + mix_factor = 0.0f; + flag_plosive = 1; + } + else + { + mix_factor = usdequant( *vf_ind, 0.0f, 1.0f / ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) ); + } + } + else +#endif + { + /* *vf_ind is an integer scale by 0.125f*/ + tmp = shl( *vf_ind, ( 15 - 3 ) ); + tmp2 = MAX_16; + move16(); + if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) + { + tmp2 = 26214 /*0.8f Q15*/; + move16(); + } + } + } +#ifdef ADD_IVAS_TBE_CODE + IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) +#endif + { + voice_factors[0] = mult_r( voice_factors[0], tmp2 ); + move16(); + voice_factors[1] = mult_r( voice_factors[1], tmp2 ); + move16(); + voice_factors[2] = mult_r( voice_factors[2], tmp2 ); + move16(); + voice_factors[3] = mult_r( voice_factors[3], tmp2 ); + move16(); + voice_factors[4] = mult_r( voice_factors[4], tmp2 ); + move16(); + } + } +#ifdef ADD_IVAS_TBE_CODE + if ( element_mode >= IVAS_CPE_DFT && nlExc16k != NULL ) + { + /* save buffers for IC-BWE */ + mvr2r( exc16kWhtnd, nlExc16k, L_FRAME16k ); + v_multc( White_exc16k, (float) sqrt( pow1 / pow22 ), mixExc16k, L_FRAME16k ); + } +#endif + + tmp = sub( Q_temp, 3 ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k_FB[k] = round_fx( L_shl( White_exc16k_32[k], tmp ) ); /* Q_bwe_exc +5 +1 +Q_temp -16 -3 */ + } + prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; + move16(); + *Q_bwe_exc_fb = sub( add( *Q_bwe_exc, Q_temp ), 13 ); + move16(); + deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); + /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ + /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ +#ifdef ADD_IVAS_TBE_CODE + if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) + { + if ( !flag_plosive ) /* use only LB excitation in case of plosives */ + { + /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ + old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); + new_scale = 1.0f; + step_scale = ( new_scale - old_scale ) / ( L_FRAME16k / 2 ); + scale = old_scale; + + /* interpolate between the old and the new value of the mixing factor */ + old_fact = *prev_mix_factor; + new_fact = mix_factor; + step = ( new_fact - old_fact ) / ( L_FRAME16k / 2 ); + fact = old_fact; + + /* mixing of LB and gaussian excitation in the first half of the frame */ + for ( k = 0; k < L_FRAME16k / 2; k++ ) + { + exc16kWhtnd[k] = (float) fact * ( White_exc16k[k] * scale ) + (float) ( 1 - fact ) * exc16kWhtnd[k]; + fact += step; + scale += step_scale; + } + + /* mixing of LB and gaussian excitation in the second half of the frame */ + for ( ; k < L_FRAME16k; k++ ) + { + exc16kWhtnd[k] = (float) new_fact * White_exc16k[k] + (float) ( 1 - new_fact ) * exc16kWhtnd[k]; + } + } + preemph( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + } + else +#endif + { +#ifdef ADD_IVAS_TBE_CODE + if ( coder_type == UNVOICED || MSFlag == 1 ) +#else + IF( EQ_16( coder_type, UNVOICED ) ) +#endif + { + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ + L_tmp = L_mult( White_exc16k[k], scale ); + /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ + exc16kWhtnd[k] = round_fx( L_shl( L_tmp, NOISE_QADJ ) ); + move16(); + /* exc16kWhtnd: Q_bwe_exc */ + } + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + /* i/o: exc16kWhtnd (Q_bwe_exc) */ + /* i/o: tbe_premph (Q_bwe_exc) */ + } + ELSE + { + Word16 nbSubFr, lSubFr; + Word16 tempQ15; + Word32 tempQ31; + /*nbSubFr = ( bitrate < ACELP_24k40 )? NB_SUBFR : NB_SUBFR16k;*/ + nbSubFr = NB_SUBFR16k; + lSubFr = ( L_FRAME16k / NB_SUBFR16k ); + IF( LT_32( bitrate, ACELP_24k40 ) ) + { + nbSubFr = NB_SUBFR; + move16(); + lSubFr = ( L_FRAME16k / NB_SUBFR ); + move16(); + } + k = 0; + FOR( i = 0; i < nbSubFr; i++ ) + { + test(); + IF( EQ_16( coder_type, VOICED ) && ( LT_32( bitrate, ACELP_24k40 ) ) ) + { + exp = 0; + move16(); + tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ + temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + exp = 0; + move16(); + tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ + temp = sub( MAX_16, temp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } + ELSE + { + /* Adjust noise mixing for formant sharpening filter */ + tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); + /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ + vf_tmp = sub( MAX_16, tempQ15 ); + vf_tmp = mult_r( voice_factors[i], vf_tmp ); + + exp = 0; + move16(); + tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ + temp = sub( MAX_16, vf_tmp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } + + FOR( j = 0; j < lSubFr; j++ ) + { + /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ + L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ + L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ + exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); + move16(); + /* Q_bwe_exc */ + } + k = add( k, lSubFr ); + + /* estimate the pre-emph factor */ + tempQ15 = sub( MAX_16, voice_factors[i] ); + exp = 0; + move16(); + temp = Sqrt16( tempQ15, &exp ); + temp = shl( temp, exp - 1 ); + + temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ + temp = div_s( temp, temp2 ); /* Q15 */ + temp = mult_r( PREEMPH_FAC, temp ); + + PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); + /* exc16kWhtnd: Q_bwe_exc; + tbe_premph: Q_bwe_exc*/ + } + } + } + +#ifdef ADD_IVAS_TBE_CODE + IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) +#else + IF( LT_32( bitrate, ACELP_24k40 ) ) +#endif + { + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: excSHB in Q_bwe_exc */ + } + ELSE + { + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); + + Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + + Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + + Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + + Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: tempSHB in Q_bwe_exc */ + /* o: syn_shb_ener_sf in (2*Q_bwe_exc+1) */ + IF( LE_32( bitrate, ACELP_32k ) ) + { + L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); + + /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ + tmp = shl( Q_shb, 1 ); + tmp2 = add( shl( *Q_bwe_exc, 1 ), 1 ); + L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ + + *Q_bwe_exc = sub( *Q_bwe_exc, exp ); + move16(); /* compensate for the exp shift */ + tmp2 = add( prev_Q_bwe_syn, n_mem2 ); + IF( GT_16( *Q_bwe_exc, tmp2 ) ) + { + L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); + *Q_bwe_exc = tmp2; + move16(); + } + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ + exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ + move16(); + } + } + /* i: L_tmp2 in (Q31-exp) */ + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ + + /* Rescale the past memories: LP synth and SHB look ahead buffers */ + tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + state_lpc_syn[i] = shl( state_lpc_syn[i], tmp ); + move16(); + } + FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) + { + excSHB[i] = shl( excSHB[i], tmp ); + move16(); + } + /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ + + Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in (Q_bwe_exc) */ + /* o: excSHB in (Q_bwe_exc) */ + } + + IF( EQ_16( extl, FB_TBE ) ) + { + tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); + Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); + Scale_sig( fb_tbe_demph, 1, tmp ); + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); + /* i: White_exc16k_FB in (14-n2) */ + /* o: White_exc16k_FB_temp in (14-n2) */ + + FOR( i = 0; i < 10; i++ ) + { + FOR( j = 0; j < 32; ++j ) + { + White_exc16k_FB_temp[i * 32 + j] = mult_r( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); + move16(); + } + } + + *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); + move16(); /**Q_bwe_exc_fb +35 +1 -16*/ + flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); + + deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); + } + ELSE + { + set16_fx( White_exc16k_FB, 0, L_FRAME16k ); + } + +#ifdef ADD_IVAS_TBE_CODE + *prev_pow_exc16kWhtnd = pow1; + *prev_mix_factor = mix_factor; +#endif + return; +} + +void GenShapedSHBExcitation_ivas_enc_fx( + Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc_fb */ + Word32 *mem_csfilt, /* i/o: memory */ + Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ + Word16 *state_lpc_syn, /* i/o: memory */ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ + Word16 bwe_seed[], /* i/o: random number generator seed */ + Word16 voice_factors[], /* i : voicing factor*/ + const Word16 extl, /* i : extension layer */ + Word16 *tbe_demph, /* i/o: de-emphasis memory */ + Word16 *tbe_premph, /* i/o: pre-emphasis memory */ + Word16 *lpc_shb_sf, /* i: LP coefficients */ + const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ + Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ + Word16 *shb_res, + Word16 *vf_ind, + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + Word16 *Q_bwe_exc, + Word16 *Q_bwe_exc_fb, + const Word16 Q_shb, + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, + const Word16 prev_bfi, + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 Q_EnvSHBres_4k, + Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ +) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER]; + Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; + Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ + Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ + Word16 Q_R; + Word32 LepsP[LPC_WHTN_ORDER + 1]; + Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; + Word32 pow1, pow22; + Word16 scale, temp1, temp2, temp3; + + Word16 excTmp2[L_FRAME16k]; + Word16 *White_exc16k; + Word16 Q_White_exc16k; + Word16 excNoisyEnv[L_FRAME16k]; + Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ + move16(); + Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ + move16(); + move16(); + Word16 varEnvShape; + Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ + Word16 exc16kWhtnd[L_FRAME16k]; + + Word32 L_tmp; + Word16 vf_tmp; + Word16 tmp, exp, tmp2 = 0; + move16(); + Word16 voiceFacEst[NB_SUBFR16k]; + Word16 zero_mem[LPC_SHB_ORDER]; + Word32 syn_shb_ener_sf[4]; + Word16 syn_shb_ener_sf_q[4]; + Word16 tempSHB[80]; + Word16 Q_pow1, Q_pow22; + + Word32 L_tmp2, L_tmp3, L_tmp4; + Word16 temp; + + Word16 White_exc16k_FB_temp[L_FRAME16k]; + Word32 White_exc16k_32[L_FRAME16k]; + Word16 White_exc16k_tmp[L_FRAME16k]; + Word16 prev_Q_bwe_exc_fb; + + Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; + Word16 cbsize; + Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; + Word32 c0, c1, c2, c3, c4, c5, den; + Word16 g1, g2, g, g1_e, g2_e, g_e, den_e, shift, tmp_e, tmp1_e; + Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; + Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; + Word16 flag_plosive; + Word16 delta; + Word32 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; + Word64 W_tmp; + + mix_factor = 0; /* Q15 */ + move16(); + + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); + set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); + FOR( i = 0; i < L_FRAME32k; i = i + 2 ) + { + exc32k[i] = negate( bwe_exc_extended[i] ); // Q_bwe_exc + move16(); + exc32k[i + 1] = bwe_exc_extended[i + 1]; // Q_bwe_exc + move16(); + } + + /* Decimate by 2 */ + Decimate_allpass_steep_fx( exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k ); // Q_bwe_exc + /* i: exc32k in Q_bwe_exc */ + /* o: exc16k in Q_bwe_exc */ + + autocorr_fx( exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1 ); // Q_R + /* Ensure R[0] isn't zero when entering Levinson Durbin */ + R_l[0] = s_max( R_l[0], 1 ); + move16(); + FOR( i = 1; i <= LPC_WHTN_ORDER; i++ ) + { + L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); + L_Extract( L_tmp, &R_h[i], &R_l[i] ); // Q_R + } + E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL ); + Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); // Q12 + fir_fx( exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3 ); // Q_bwe_exc + + /* i: exc16k in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc */ + + IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) + { + temp2 = 0; + move16(); + FOR( j = 0; j < 4; j++ ) + { + temp1 = shb_res_gshape[j]; + move16(); + FOR( i = 0; i < 80; i++ ) + { + exc16kWhtnd[temp2 + i] = round_fx( L_shl( L_mult( exc16kWhtnd[temp2 + i], temp1 ), 1 ) ); // Q_bwe_exc + move16(); + /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ + } + temp2 = add( temp2, 80 ); + } + } + + /* Estimate pow1 associated with Low band nonlinear extended excitation */ + /* pow1=0.00001f */ + tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); + W_tmp = W_shl( 21475 /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ + excTmp2[k] = abs_s( exc16kWhtnd[k] ); + move16(); + + /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ + W_tmp = W_mac_16_16( W_tmp, exc16kWhtnd[k], exc16kWhtnd[k] ); // 2*Q_bwe_exc+1 + } + exp = W_norm( W_tmp ); + pow1 = W_extract_h( W_shl( W_tmp, exp ) ); // 2*Q_bwe_exc+1+exp-32 = // tmp+exp + Q_pow1 = add( tmp, exp ); + + IF( flag_ACELP16k == 0 ) + { + /* varEnvShape = mean_fx(voice_factors, 4); */ + /* unroll the loop */ + L_tmp = L_mult( voice_factors[0], 8192 /*0.25 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[1], 8192 /*0.25 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[2], 8192 /*0.25 in Q15 */ ); + varEnvShape = mac_r( L_tmp, voice_factors[3], 8192 /*0.25 in Q15 */ ); /* varEnvShape in Q15 */ + } + ELSE /* 16k core */ + { + /* varEnvShape = mean_fx(voice_factors, 5); */ + /* unroll the loop */ + L_tmp = L_mult( voice_factors[0], 6554 /*0.2 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[1], 6554 /*0.2 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[2], 6554 /*0.2 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[3], 6554 /*0.2 in Q15 */ ); + varEnvShape = mac_r( L_tmp, voice_factors[4], 6554 /*0.2 in Q15 */ ); /* varEnvShape in Q15 */ + } + + IF( EQ_16( extl, FB_TBE ) ) + { + /*pow(varEnvShape,3) */ + tmp = mult_r( varEnvShape, varEnvShape ); + tmp = mult_r( tmp, varEnvShape ); + + /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ + fb_deemph_fac = sub( 22282 /*0.68f Q15*/, tmp ); + fb_deemph_fac = s_max( fb_deemph_fac, 15729 /*0.48f Q15*/ ); + } + + /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ + varEnvShape = msu_r( 1179773824l /*0.549375f Q31*/, 8172 /*0.249375f Q15*/, varEnvShape ); + + /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ + varEnvShape = s_max( varEnvShape, 9830 /*0.3f Q15*/ ); + varEnvShape = s_min( varEnvShape, 16368 /*0.4995f Q15*/ ); + varEnvShape = shl( varEnvShape, 1 ); + csfilt_num2[0] = sub( MAX_16, varEnvShape ); // Q15 + move16(); + neg_csfilt_den2[1] = varEnvShape; // Q15 + move16(); + + test(); + test(); + test(); + test(); + IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) + { + /* pre-init smoothing filter to avoid energy drop outs */ + L_tmp = L_mult( excTmp2[0], 1638 ); + FOR( i = 1; i < L_SUBFR16k / 4; i++ ) + { + L_tmp = L_mac( L_tmp, excTmp2[i], 1638 ); /*1638 = 1/20 in Q15*/ + } + /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ + + /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ + /* rather stick to the more conservative approach, to avoid potential clippings */ + test(); + IF( !( prev_bfi && EQ_16( extl, FB_TBE ) ) ) + { + /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ + varEnvShape = 26214 /*0.8f Q15*/; + move16(); + csfilt_num2[0] = sub( MAX_16, varEnvShape ); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + } + + *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); + move32(); + } + + IF( MSFlag > 0 ) + { + // varEnvShape = 0.995f; + varEnvShape = 32604; + move16(); + csfilt_num2[0] = 32768 - varEnvShape; + // csfilt_num2[0] = sub( 32767, varEnvShape ); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + } + + White_exc16k = exc16k; + Word16 Q_excTmp2 = add( getScaleFactor16( excTmp2, L_FRAME16k ), *Q_bwe_exc ); + IF( *mem_csfilt ) + { + Q_excTmp2 = s_min( Q_excTmp2, sub( add( norm_l( *mem_csfilt ), *Q_bwe_exc ), 1 ) ); + } + test(); + /* Track the low band envelope */ + IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + test(); + IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) + { + mem_csfilt_left = 0; + mem_csfilt_right = 0; + move16(); + move16(); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + // excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; + excNoisyEnvLeft[k] = add( mem_csfilt_left, mult_r( csfilt_num2[0], shl( excTmp2[k], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 + move16(); + // mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; + mem_csfilt_left = mult_r( neg_csfilt_den2[1], excNoisyEnvLeft[k] ); // Q_excTmp2 + // excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; + excNoisyEnvRight[L_FRAME16k - k - 1] = add( mem_csfilt_right, mult_r( csfilt_num2[0], shl( excTmp2[L_FRAME16k - k - 1], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 + move16(); + // mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; + mem_csfilt_right = mult_r( neg_csfilt_den2[1], excNoisyEnvRight[L_FRAME16k - k - 1] ); // Q_excTmp2 + } + + alpha = 0; + move16(); + // step = 1.0f / L_FRAME16k; + step = 102; // Q15 + move16(); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + // excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + (1 - alpha) * excNoisyEnvRight[k]; + excNoisyEnv[k] = add( mult_r( alpha, excNoisyEnvLeft[k] ), mult_r( sub( 32767, alpha ), excNoisyEnvRight[k] ) ); // Q_excTmp2 + move16(); + alpha = add( alpha, step ); + } + } + } + ELSE + { + /* Track the low band envelope */ + L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + excNoisyEnv[i] = mac_r( L_tmp, csfilt_num2[0], shl( excTmp2[i], sub( Q_excTmp2, *Q_bwe_exc ) ) ); + move16(); + /* Work-around to avoid 0s for very small value*/ + test(); + test(); + test(); + test(); + if ( excNoisyEnv[i] == 0 && ( L_tmp != 0 || ( csfilt_num2[0] != 0 && excTmp2[i] != 0 ) ) ) + { + excNoisyEnv[i] = 1; + move16(); + } + /* excNoisyEnv : Q_excTmp2, + *mem_csfilt: Q_excTmp2+16, excTmp2: Q_excTmp2, csfilt_num2[0] Q_excTmp2 */ + L_tmp = L_mult( excNoisyEnv[i], neg_csfilt_den2[1] ); /* Q_excTmp2 + 16 */ + } + *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); + move32(); + } + + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + /* generate gaussian (white) excitation */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k[k] = own_random( &bwe_seed[0] ); // Q0 + move16(); + } + + /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; // Q31 + move32(); + move32(); + pow22 = POW_EXC16k_WHTND_FX; + Q_pow22 = -6; + move16(); + // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); + Word16 pow1_exp = sub( Q31, Q_pow1 ); + Word32 temp_pow = Sqrt32( pow1, &pow1_exp ); + temp_pow = L_shl( Mpy_32_32( temp_pow, pow22_inv ), pow1_exp ); + /*Word16 out_exp; + Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); + temp_pow1 = L_shl(temp_pow1, out_exp);*/ + // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); + L_tmp = 0; + move32(); + Q_White_exc16k = add( getScaleFactor16( White_exc16k, L_FRAME16k ), norm_l( temp_pow ) ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); // Q31 + Q0 - Q15 = Q16 + move32(); + White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q16 + Q_White_exc16k - Q16 = Q_White_exc16k + move16(); + L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); + } + } + ELSE + { + /* create a random excitation - Reuse exc16k memory */ + create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 + create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); // Q5 + + L_tmp = L_deposit_l( 0 ); + tmp = add( *Q_bwe_exc, 1 ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_excTmp2) +5 +1*/ + White_exc16k_32[k] = L_tmp4; /* (Q_excTmp2) +5 +1*/ + move32(); + L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); + } + /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ + /* White_exc16k in Q6 */ + + /* calculate pow22 */ + /* pow22=0.00001f */ + tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); + W_tmp = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /* White_exc16k[k] *= excNoisyEnv[k]; */ + White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 + move16(); + /* i: excNoisyEnv in (Q_excTmp2) */ + /* i: White_exc16k in Q6 */ + /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + + /* pow22 += White_exc16k[k] * White_exc16k[k]; */ + W_tmp = W_mac0_16_16( W_tmp, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ + } + Q_pow22 = W_norm( W_tmp ); + pow22 = W_extract_h( W_shl( W_tmp, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); + Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); + } + + flag_plosive = 0; + move16(); + test(); + test(); + test(); + IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ + { +#ifndef ADD_IVAS_TBE_CODE // BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k_tmp[k] = shl( White_exc16k[k], sub( *Q_bwe_exc, Q_White_exc16k ) ); + move16(); + } + + /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ + find_td_envelope_fx( White_exc16k_tmp, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); /* Q_bwe_exc */ + find_td_envelope_fx( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); /* Q_bwe_exc */ + + FOR( k = 0; k < L_FRAME4k; k++ ) + { + EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; /* Q_bwe_exc */ + move16(); + EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; /* Q_bwe_exc */ + move16(); + } + + /* calculate the optimal mix factor */ + c0 = c1 = c2 = c3 = c4 = c5 = 0; /* Q0 */ + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + + temp1 = add( shl( *Q_bwe_exc, 1 ), 1 ); + temp2 = add( add( Q_EnvSHBres_4k, *Q_bwe_exc ), 1 ); + temp3 = add( shl( Q_EnvSHBres_4k, 1 ), 1 ); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + // c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c0_part[i] = L_shr( sum2_fx( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ + move32(); + // c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c1_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ + move32(); + // c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c2_part[i] = L_shr( sum2_fx( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ + move32(); + // c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c3_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ + move32(); + // c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c4_part[i] = L_shr( Dot_product( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), sub( temp1, 1 ) ); /* Q0 */ + move32(); + // c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c5_part[i] = L_shr( sum2_fx( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp3 ); /* Q0 */ + move32(); + + c0 = L_add( c0, c0_part[i] ); + c1 = L_add( c1, c1_part[i] ); + c2 = L_add( c2, c2_part[i] ); + c3 = L_add( c3, c3_part[i] ); + c4 = L_add( c4, c4_part[i] ); + c5 = L_add( c5, c5_part[i] ); + } + + // den = 4.0f * c0 * c2 - c4 * c4; + W_tmp = W_sub( W_shl( W_mult0_32_32( c0, c2 ), 2 ), W_mult0_32_32( c4, c4 ) ); + den_e = 63; + move16(); + shift = W_norm( W_tmp ); + den = W_extract_h( W_shl( W_tmp, shift ) ); + den_e = sub( den_e, shift ); + + IF( den == 0 ) + { + den = 1; + move32(); + den_e = 31; + move16(); + } + + // g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; + W_tmp = W_sub( W_mult0_32_32( c3, c4 ), W_shl( W_mult0_32_32( c1, c2 ), 1 ) ); + g1_e = 63; + move16(); + shift = W_norm( W_tmp ); + L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); + g1_e = sub( g1_e, shift ); + + g1 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); + g1_e = sub( add( tmp_e, g1_e ), den_e ); + + // g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; + W_tmp = W_sub( W_mult0_32_32( c1, c4 ), W_shl( W_mult0_32_32( c0, c3 ), 1 ) ); + g2_e = 63; + move16(); + shift = W_norm( W_tmp ); + L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); + g2_e = sub( g2_e, shift ); + + g2 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); + g2_e = sub( add( tmp_e, g2_e ), den_e ); + + // *Env_error = 0.0f; + *Env_error = 0; + move16(); + flag_plosive = 0; + move16(); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + // Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; + L_tmp = BASOP_Util_Add_Mant32Exp( c5_part[i], 31, Mpy_32_32( L_mult( g1, g1 ), c0_part[i] ), add( shl( g1_e, 1 ), 31 ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c1_part[i], g1 ), add( 31, g1_e ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g2, g2 ), c2_part[i] ), add( shl( g2_e, 1 ), 31 ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c3_part[i], g2 ), add( 31, g2_e ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g1, g2 ), c4_part[i] ), add( add( g1_e, g2_e ), 31 ), &tmp_e ); + + // Env_error_part[i] = L_shr( L_tmp, 31 - tmp_e ); // Check Exponent + Env_error_part[i] = extract_h( L_shr_sat( L_tmp, sub( Q15, tmp_e ) ) ); /* Q0 */ + move16(); + + // *Env_error += Env_error_part[i]; + *Env_error = add_sat( *Env_error, Env_error_part[i] ); /* Q0 */ + move16(); + + if ( GT_16( Env_error_part[i], THR_ENV_ERROR_PLOSIVE_FX ) ) // Check which Q + { + /* envelope error is too high -> likely a plosive */ + flag_plosive = 1; + move16(); + } + } + + IF( flag_plosive ) + { + /* plosive detected -> set the mixing factor to 0 */ + *vf_ind = 0; + move16(); + mix_factor = 0; + move16(); + } + ELSE + { + /* normalize gain */ + // g = g2 / ( g1 + g2 ); + tmp1_e = BASOP_Util_Add_MantExp( g1, g1_e, g2, g2_e, &tmp ); + IF( tmp == 0 ) + { + tmp = 1; + move16(); + tmp1_e = 15; + move16(); + } + g = BASOP_Util_Divide1616_Scale( g2, tmp, &tmp_e ); + g_e = sub( add( tmp_e, g2_e ), tmp1_e ); + + /* quantization of the mixing factor */ + cbsize = 1 << NUM_BITS_SHB_VF; + move16(); + // delta = 1.0f / ( cbsize - 1 ); + delta = 2341; /* Q14 */ + move16(); + // if ( g > 1.0f ) + IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), ONE_IN_Q31, 0 ) > 0 ) + { + // g = 1.0f; + g = MAX16B; /* Q15 */ + move16(); + g_e = 0; + move16(); + } + // else if ( g < shl( delta, ( 15 - g_e ) - 14 ) ) + ELSE IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), delta, 17 ) < 0 ) + { + /* prevent low gains to be quantized to 0 as this is reserved for plosives */ + // g = delta; + g = shl( delta, 1 ); /* Q15 */ + g_e = 0; + move16(); + } + + g = shl_sat( g, g_e ); /* Q15 */ + + *vf_ind = usquant_fx( g, &mix_factor, 0, delta, cbsize ); + move16(); + } + } + ELSE +#else + UNUSED_PARAM( Env_error_part ); + UNUSED_PARAM( Env_error ); + UNUSED_PARAM( EnvSHBres_4k ); + UNUSED_PARAM( c5_part ); + UNUSED_PARAM( c1 ); + UNUSED_PARAM( den ); + UNUSED_PARAM( c3_part ); + UNUSED_PARAM( c0 ); + UNUSED_PARAM( delta ); + UNUSED_PARAM( c3 ); + UNUSED_PARAM( c2_part ); + UNUSED_PARAM( c1_part ); + UNUSED_PARAM( EnvWhiteExc16k ); + UNUSED_PARAM( g2 ); + UNUSED_PARAM( c5 ); + UNUSED_PARAM( c4_part ); + UNUSED_PARAM( EnvWhiteExc16k_4k ); + UNUSED_PARAM( c2 ); + UNUSED_PARAM( g ); + UNUSED_PARAM( cbsize ); + UNUSED_PARAM( g1 ); + UNUSED_PARAM( EnvExc16kWhtnd ); + UNUSED_PARAM( c0_part ); + UNUSED_PARAM( EnvExc16kWhtnd_4k ); + UNUSED_PARAM( c4 ); +#endif + { + Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, + Q_White_exc16k, pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); + tmp = voiceFacEst[0]; + tmp2 = MAX_16; + move16(); + move16(); + if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) + { + tmp2 = 26214 /*0.8f Q15*/; + move16(); + } + } + } + ELSE /* decoder side */ + { + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + IF( *vf_ind == 0 ) + { + // mix_factor = 0.0f; + mix_factor = 0; + move16(); + flag_plosive = 1; + move16(); + } + ELSE + { + // mix_factor = usdequant(*vf_ind, 0.0f, 1.0f / ((1 << NUM_BITS_SHB_VF) - 1)); + mix_factor = usdequant_fx( *vf_ind, 0, 2341 ); + } + } + ELSE + { + /* *vf_ind is an integer scale by 0.125f*/ + tmp = shl( *vf_ind, ( 15 - 3 ) ); + tmp2 = MAX_16; + move16(); + IF( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) + { + tmp2 = 26214 /*0.8f Q15*/; + move16(); + } + } + } + + test(); + IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) + { + voice_factors[0] = mult_r( voice_factors[0], tmp2 ); + move16(); + voice_factors[1] = mult_r( voice_factors[1], tmp2 ); + move16(); + voice_factors[2] = mult_r( voice_factors[2], tmp2 ); + move16(); + voice_factors[3] = mult_r( voice_factors[3], tmp2 ); + move16(); + voice_factors[4] = mult_r( voice_factors[4], tmp2 ); + move16(); + } + } + + test(); + IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) + { + /* save buffers for IC-BWE */ + // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); + Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); // Q_bwe_exc + *nlExc16k_e = sub( 15, *Q_bwe_exc ); + move16(); + + // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + Word16 temp_fac = round_fx_sat( L_tmp ); // Q15-exp + + FOR( k = 0; k < L_FRAME16k; k++ ) + { + mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); // Q_White_exc16k+15-exp-15 = Q_White_exc16k-exp + move16(); + } + *mixExc16k_e = sub( 15, sub( Q_White_exc16k, exp ) ); + move16(); + } + + Copy( White_exc16k, White_exc16k_FB, L_FRAME16k ); // Q_White_exc16k + prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; + *Q_bwe_exc_fb = Q_White_exc16k; + move16(); + move16(); + + Word16 tbe_demph_fx = shl_sat( *tbe_demph, sub( Q_White_exc16k, *Q_bwe_exc ) ); // Q_White_exc16k + + deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, &tbe_demph_fx ); + /* i/o: White_exc16k (Q_White_exc16k) */ + /* i: tbe_demph_fx (Q_White_exc16k) */ + *tbe_demph = shr_sat( tbe_demph_fx, sub( Q_White_exc16k, *Q_bwe_exc ) ); + move16(); + + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + IF( !flag_plosive ) /* use only LB excitation in case of plosives */ + { + /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ + /* old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); */ + old_scale = round_fx_sat( root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ) ); // exp + old_scale = shl( old_scale, s_min( 0, exp ) ); // limit Q factor to 15 + exp = s_max( 0, exp ); + + // new_scale = 1.0f; + new_scale = shr( 32767, exp ); // exp + + // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); + step_scale = mult_r( sub( new_scale, old_scale ), 205 ); // exp + scale = old_scale; // exp + move16(); + + /* interpolate between the old and the new value of the mixing factor */ + old_fact = *prev_mix_factor; // Q15 + new_fact = mix_factor; // Q15 + move16(); + move16(); + + // step = (new_fact - old_fact) / (L_FRAME16k / 2); + step = mult_r( sub( new_fact, old_fact ), 205 ); // Q15 + fact = old_fact; // Q15 + move16(); + + shift = add( exp, sub( *Q_bwe_exc, Q_White_exc16k ) ); + + /* mixing of LB and gaussian excitation in the first half of the frame */ + FOR( k = 0; k < L_FRAME16k / 2; k++ ) + { + /* exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; */ + L_tmp = L_shl_sat( L_mult( fact, mult_r( White_exc16k[k], scale ) ), shift ); // Q_bwe_exc+16 + exc16kWhtnd[k] = mac_r_sat( L_tmp, sub( 32767, fact ), exc16kWhtnd[k] ); // Q_bwe_exc + move16(); + + fact = add_sat( fact, step ); // Q15 + scale = add_sat( scale, step_scale ); // exp + } + + shift = sub( *Q_bwe_exc, Q_White_exc16k ); + /* mixing of LB and gaussian excitation in the second half of the frame */ + FOR( ; k < L_FRAME16k; k++ ) + { + // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; + L_tmp = L_shl_sat( L_mult( new_fact, White_exc16k[k] ), shift ); // Q_bwe_exc+16 + exc16kWhtnd[k] = mac_r( L_tmp, sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_bwe_exc + move16(); + } + } + // preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc + } + ELSE + { + test(); + IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) + { + scale = 0; + move16(); + + test(); + IF( pow1 != 0 && pow22 != 0 ) + { + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ + } + + FOR( k = 0; k < L_FRAME16k; k++ ) + { + exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); // Q_White_exc16k + move16(); + } + + Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); // Q_bwe_exc + + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc + /* i/o: exc16kWhtnd (Q_bwe_exc) */ + /* i/o: tbe_premph (Q_bwe_exc) */ + } + ELSE + { + Word16 nbSubFr, lSubFr; + Word16 tempQ15; + Word32 tempQ31; + nbSubFr = NB_SUBFR16k; + lSubFr = ( L_FRAME16k / NB_SUBFR16k ); + move16(); + move16(); + IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) + { + nbSubFr = NB_SUBFR; + move16(); + lSubFr = ( L_FRAME16k / NB_SUBFR ); + move16(); + } + k = 0; + move16(); + FOR( i = 0; i < nbSubFr; i++ ) + { + test(); + IF( EQ_16( coder_type, VOICED ) && ( LT_32( extl_brate, SWB_TBE_2k8 ) ) ) + { + exp = 0; + move16(); + tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ + temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + exp = 0; + move16(); + tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ + temp = sub( MAX_16, temp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } + ELSE + { + /* Adjust noise mixing for formant sharpening filter */ + tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); + /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ + vf_tmp = sub( MAX_16, tempQ15 ); + vf_tmp = mult( voice_factors[i], vf_tmp ); + + exp = 0; + move16(); + tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ + temp = sub( MAX_16, vf_tmp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } + + shift = sub( *Q_bwe_exc, Q_White_exc16k ); + FOR( j = 0; j < lSubFr; j++ ) + { + /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ + L_tmp = L_shl_sat( L_mult( temp2, White_exc16k[k + j] ), shift ); // 16+(Q_bwe_exc) + exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); // Q_bwe_exc + move16(); + } + k = add( k, lSubFr ); + + /* estimate the pre-emph factor */ + tempQ15 = sub( MAX_16, voice_factors[i] ); + exp = 0; + move16(); + temp = Sqrt16( tempQ15, &exp ); + temp = shl( temp, sub( exp, 1 ) ); + + temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ + temp = div_s( temp, temp2 ); /* Q15 */ + temp = mult_r( PREEMPH_FAC, temp ); + + PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); // Q_bwe_exc + /* exc16kWhtnd: Q_bwe_exc; + tbe_premph: Q_bwe_exc*/ + } + } + } + + IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) + { + syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: excSHB in Q_bwe_exc */ + } + ELSE + { + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); + + syn_filt_fx( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[0] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + syn_filt_fx( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[1] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + syn_filt_fx( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[2] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + syn_filt_fx( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[3] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + tmp2 = s_min( s_min( syn_shb_ener_sf_q[0], syn_shb_ener_sf_q[1] ), s_min( syn_shb_ener_sf_q[3], syn_shb_ener_sf_q[2] ) ); + syn_shb_ener_sf[0] = L_shl( syn_shb_ener_sf[0], sub( tmp2, syn_shb_ener_sf_q[0] ) ); + move32(); + syn_shb_ener_sf[1] = L_shl( syn_shb_ener_sf[1], sub( tmp2, syn_shb_ener_sf_q[1] ) ); + move32(); + syn_shb_ener_sf[2] = L_shl( syn_shb_ener_sf[2], sub( tmp2, syn_shb_ener_sf_q[2] ) ); + move32(); + syn_shb_ener_sf[3] = L_shl( syn_shb_ener_sf[3], sub( tmp2, syn_shb_ener_sf_q[3] ) ); + move32(); + + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: tempSHB in Q_bwe_exc */ + /* o: syn_shb_ener_sf in tmp2 */ + IF( LE_32( bitrate, MAX_ACELP_BRATE ) ) + { + L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); + + /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ + tmp = shl( Q_shb, 1 ); + L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ + + *Q_bwe_exc = sub( *Q_bwe_exc, exp ); + move16(); /* compensate for the exp shift */ + tmp2 = add( prev_Q_bwe_syn, n_mem2 ); + IF( GT_16( *Q_bwe_exc, tmp2 ) ) + { + L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); + *Q_bwe_exc = tmp2; + move16(); + } + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ + exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ + move16(); + } + } + /* i: L_tmp2 in (Q31-exp) */ + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ + + /* Rescale the past memories: LP synth and SHB look ahead buffers */ + tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + state_lpc_syn[i] = shl_sat( state_lpc_syn[i], tmp ); + move16(); + } + FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) + { + excSHB[i] = shl_sat( excSHB[i], tmp ); + move16(); + } + /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ + + syn_filt_fx( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); + syn_filt_fx( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); + syn_filt_fx( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); + syn_filt_fx( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in (Q_bwe_exc) */ + /* o: excSHB in (Q_bwe_exc) */ + } + + IF( EQ_16( extl, FB_TBE ) ) + { + tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); + Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); + Scale_sig( fb_tbe_demph, 1, tmp ); + syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); + /* i: White_exc16k_FB in (Q_bwe_exc_fb) */ + /* o: White_exc16k_FB_temp in (Q_bwe_exc_fb) */ + + FOR( i = 0; i < 10; i++ ) + { + FOR( j = 0; j < 32; ++j ) + { + White_exc16k_FB_temp[i * 32 + j] = mult_r_sat( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); + move16(); + } + } + + *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); + move16(); /**Q_bwe_exc_fb +35 +1 -16*/ + flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); + + deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); + } + ELSE + { + set16_fx( White_exc16k_FB, 0, L_FRAME16k ); + } + + *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 + *prev_mix_factor = mix_factor; + move32(); + move16(); + + return; +} + +void GenShapedSHBExcitation_ivas_dec_fx( + Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ + const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word32 *mem_csfilt, /* i/o: memory */ + Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ + Word16 *state_lpc_syn, /* i/o: memory */ + const Word16 coder_type, /* i : coding type */ + const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ + Word16 bwe_seed[], /* i/o: random number generator seed */ + Word16 voice_factors[], /* i : voicing factor*/ + const Word16 extl, /* i : extension layer */ + Word16 *tbe_demph, /* i/o: de-emphasis memory */ + Word16 *tbe_premph, /* i/o: pre-emphasis memory */ + Word16 *lpc_shb_sf, /* i: LP coefficients */ + const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ + Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ + Word16 *shb_res, + Word16 *vf_ind, + const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ + Word16 fb_state_lpc_syn[], /* i/o: memory */ + Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ + Word16 *Q_bwe_exc, + Word16 *Q_bwe_exc_fb, + const Word16 Q_shb, + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, /* i : bitrate */ + const Word16 prev_bfi, /* i : previous frame was concealed */ + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling Q0 */ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling Q0 */ +) +{ + Word16 i, j, k; + Word16 wht_fil_mem[LPC_WHTN_ORDER]; + Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; + Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ + Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ + Word16 Q_R; + Word32 LepsP[LPC_WHTN_ORDER + 1]; + Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; + Word32 pow1, pow22; + Word16 scale, temp1, temp2, temp3; + Word16 Q_White_exc16k; + Word16 excTmp2[L_FRAME16k]; + Word16 *White_exc16k; + Word16 excNoisyEnv[L_FRAME16k]; + Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ + move16(); + Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ + move16(); + move16(); + Word16 varEnvShape; + Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ + Word16 exc16kWhtnd[L_FRAME16k]; + + Word32 L_tmp; + Word16 vf_tmp; + Word16 tmp, exp, tmp2 = 0; + move16(); + Word16 voiceFacEst[NB_SUBFR16k]; + Word16 zero_mem[LPC_SHB_ORDER]; + Word32 syn_shb_ener_sf[4]; + Word16 syn_shb_ener_sf_q[4]; + Word16 tempSHB[80]; + Word16 Q_pow1, Q_pow22; + + Word32 L_tmp2, L_tmp3, L_tmp4; + Word16 temp; + + Word16 White_exc16k_FB_temp[L_FRAME16k]; + Word32 White_exc16k_32[L_FRAME16k]; + Word16 White_exc16k_tmp[L_FRAME16k]; + Word16 Q_temp; + Word16 prev_Q_bwe_exc_fb, Q_exc16kWhtnd; + Word16 chk1; + Word32 chk2; + chk1 = 0; + chk2 = 0; + move16(); + move32(); + +#if 1 // def ADD_IVAS_TBE_CODE + Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; + Word16 cbsize; + Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; + Word32 c0, c1, c2, c3, c4, c5, den; + Word16 g1, g2, g, g1_e, g2_e, g_e, den_e, shift, tmp_e, tmp1_e; + Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; + Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; + Word16 flag_plosive; + Word16 delta; + Word32 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; + Word64 W_tmp; + + mix_factor = 0; /* Q15 */ + move16(); +#endif + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); + set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); + FOR( i = 0; i < L_FRAME32k; i = i + 2 ) + { + exc32k[i] = negate( bwe_exc_extended[i] ); // Q_bwe_exc + move16(); + exc32k[i + 1] = bwe_exc_extended[i + 1]; // Q_bwe_exc + move16(); + } + + /* Decimate by 2 */ + Decimate_allpass_steep_fx( exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k ); // Q_bwe_exc + /* i: exc32k in Q_bwe_exc */ + /* o: exc16k in Q_bwe_exc */ + + autocorr_fx( exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1 ); // Q_R + /* Ensure R[0] isn't zero when entering Levinson Durbin */ + R_l[0] = s_max( R_l[0], 1 ); + move16(); + FOR( i = 1; i <= LPC_WHTN_ORDER; i++ ) + { + L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); + L_Extract( L_tmp, &R_h[i], &R_l[i] ); // Q_R + } + E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL ); + Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); // Q12 + fir_fx( exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3 ); // Q_bwe_exc + + /* i: exc16k in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc */ + +#if 1 // def ADD_IVAS_TBE_CODE + IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) +#else + IF( GE_32( bitrate, ACELP_24k40 ) ) +#endif + { + temp2 = 0; + move16(); + FOR( j = 0; j < 4; j++ ) + { + temp1 = shb_res_gshape[j]; + move16(); + FOR( i = 0; i < 80; i++ ) + { + exc16kWhtnd[temp2 + i] = round_fx( L_shl( L_mult( exc16kWhtnd[temp2 + i], temp1 ), 1 ) ); // Q_bwe_exc + move16(); + /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ + } + temp2 = add( temp2, 80 ); + } + } + + /* Estimate pow1 associated with Low band nonlinear extended excitation */ + /* pow1=0.00001f */ + tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); + pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ + excTmp2[k] = abs_s( exc16kWhtnd[k] ); + move16(); + chk1 = s_or( chk1, exc16kWhtnd[k] ); + + /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ + pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ + } + Q_pow1 = shl( *Q_bwe_exc, 1 ); + + test(); +#if 1 // ADD_IVAS_TBE_CODE + IF( flag_ACELP16k == 0 ) +#else + IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) +#endif + { + /* varEnvShape = mean_fx(voice_factors, 4); */ + /* unroll the loop */ + L_tmp = L_mult( voice_factors[0], 8192 /*0.25 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[1], 8192 /*0.25 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[2], 8192 /*0.25 in Q15 */ ); + varEnvShape = mac_r( L_tmp, voice_factors[3], 8192 /*0.25 in Q15 */ ); /* varEnvShape in Q15 */ + } + ELSE /* 16k core */ + { + /* varEnvShape = mean_fx(voice_factors, 5); */ + /* unroll the loop */ + L_tmp = L_mult( voice_factors[0], 6554 /*0.2 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[1], 6554 /*0.2 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[2], 6554 /*0.2 in Q15 */ ); + L_tmp = L_mac( L_tmp, voice_factors[3], 6554 /*0.2 in Q15 */ ); + varEnvShape = mac_r( L_tmp, voice_factors[4], 6554 /*0.2 in Q15 */ ); /* varEnvShape in Q15 */ + } + + IF( EQ_16( extl, FB_TBE ) ) + { + /*pow(varEnvShape,3) */ + tmp = mult_r( varEnvShape, varEnvShape ); + tmp = mult_r( tmp, varEnvShape ); + + /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ + fb_deemph_fac = sub( 22282 /*0.68f Q15*/, tmp ); + fb_deemph_fac = s_max( fb_deemph_fac, 15729 /*0.48f Q15*/ ); + } + + /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ + varEnvShape = msu_r( 1179773824l /*0.549375f Q31*/, 8172 /*0.249375f Q15*/, varEnvShape ); + + /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ + varEnvShape = s_max( varEnvShape, 9830 /*0.3f Q15*/ ); + varEnvShape = s_min( varEnvShape, 16368 /*0.4995f Q15*/ ); + varEnvShape = shl( varEnvShape, 1 ); + csfilt_num2[0] = sub( MAX_16, varEnvShape ); // Q15 + move16(); + neg_csfilt_den2[1] = varEnvShape; // Q15 + move16(); + + test(); + test(); + test(); +#if 1 // def ADD_IVAS_TBE_CODE + test(); + IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) +#else + IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) +#endif + { + /* pre-init smoothing filter to avoid energy drop outs */ + L_tmp = L_mult( excTmp2[0], 1638 ); + FOR( i = 1; i < L_SUBFR16k / 4; i++ ) + { + L_tmp = L_mac( L_tmp, excTmp2[i], 1638 ); /*1638 = 1/20 in Q15*/ + } + /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ + + /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ + /* rather stick to the more conservative approach, to avoid potential clippings */ + test(); + IF( !( prev_bfi && EQ_16( extl, FB_TBE ) ) ) + { + /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ + varEnvShape = 26214 /*0.8f Q15*/; + move16(); + csfilt_num2[0] = sub( MAX_16, varEnvShape ); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + } + + *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); + move32(); + } +#if 1 // def ADD_IVAS_TBE_CODE + IF( MSFlag > 0 ) + { + // varEnvShape = 0.995f; + varEnvShape = 32604; + move16(); + csfilt_num2[0] = 32768 - varEnvShape; + // csfilt_num2[0] = sub( 32767, varEnvShape ); + move16(); + neg_csfilt_den2[1] = varEnvShape; + move16(); + } + + White_exc16k = exc16k; + move16(); + Word16 Q_excTmp2 = add( getScaleFactor16( excTmp2, L_FRAME16k ), *Q_bwe_exc ); + IF( *mem_csfilt ) + { + Q_excTmp2 = s_min( Q_excTmp2, sub( add( norm_l( *mem_csfilt ), *Q_bwe_exc ), 1 ) ); + } + test(); + /* Track the low band envelope */ + IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + test(); + IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) + { + mem_csfilt_left = 0; + mem_csfilt_right = 0; + move16(); + move16(); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + // excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; + excNoisyEnvLeft[k] = add( mem_csfilt_left, mult_r( csfilt_num2[0], shl( excTmp2[k], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 + move16(); + // mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; + mem_csfilt_left = mult_r( neg_csfilt_den2[1], excNoisyEnvLeft[k] ); // Q_excTmp2 + // excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; + excNoisyEnvRight[L_FRAME16k - k - 1] = add( mem_csfilt_right, mult_r( csfilt_num2[0], shl( excTmp2[L_FRAME16k - k - 1], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 + move16(); + // mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; + mem_csfilt_right = mult_r( neg_csfilt_den2[1], excNoisyEnvRight[L_FRAME16k - k - 1] ); // Q_excTmp2 + } + + alpha = 0; + move16(); + // step = 1.0f / L_FRAME16k; + step = 102; // Q15 + move16(); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + // excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + (1 - alpha) * excNoisyEnvRight[k]; + excNoisyEnv[k] = add( mult_r( alpha, excNoisyEnvLeft[k] ), mult_r( sub( 32767, alpha ), excNoisyEnvRight[k] ) ); // Q_excTmp2 + move16(); + alpha = add( alpha, step ); + } + } + } + ELSE +#endif + { + /* Track the low band envelope */ + L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + excNoisyEnv[i] = mac_r( L_tmp, csfilt_num2[0], shl( excTmp2[i], sub( Q_excTmp2, *Q_bwe_exc ) ) ); + move16(); + /* Work-around to avoid 0s for very small value*/ + test(); + test(); + test(); + test(); + if ( excNoisyEnv[i] == 0 && ( L_tmp != 0 || ( csfilt_num2[0] != 0 && excTmp2[i] != 0 ) ) ) + { + excNoisyEnv[i] = 1; + move16(); + } + /* excNoisyEnv : Q_excTmp2, + *mem_csfilt: Q_excTmp2+16, excTmp2: Q_excTmp2, csfilt_num2[0] Q_excTmp2 */ + L_tmp = L_mult( excNoisyEnv[i], neg_csfilt_den2[1] ); /* Q_excTmp2 + 16 */ + } + *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); + move32(); + } +#if 1 // def ADD_IVAS_TBE_CODE + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + /* generate gaussian (white) excitation */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k[k] = own_random( &bwe_seed[0] ); + move16(); + } + + /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49; + move32(); + move32(); + pow22 = POW_EXC16k_WHTND_FX; + Q_pow22 = -6; + move16(); + // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); + Word16 pow1_exp = sub( Q31, Q_pow1 ); + Word32 temp_pow = Sqrt32( pow1, &pow1_exp ); + temp_pow = Mpy_32_32( temp_pow, pow22_inv ); + /*Word16 out_exp; + Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); + temp_pow1 = L_shl(temp_pow1, out_exp);*/ + // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); + L_tmp = 0; + move32(); + shift = getScaleFactor16( White_exc16k, L_FRAME16k ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); + move32(); + White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], shift ) ); // Q_White_exc16k + move16(); + L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); + } + Q_White_exc16k = add( shift, sub( 49 - 31, pow1_exp ) ); + Q_temp = norm_l( L_tmp ); + IF( L_tmp == 0 ) + { + Q_temp = 31; + move16(); + } + } + ELSE +#endif + { + /* create a random excitation - Reuse exc16k memory */ + White_exc16k = exc16k; + move16(); + create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 + create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); // Q5 + + L_tmp = L_deposit_l( 0 ); + tmp = add( *Q_bwe_exc, 1 ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_excTmp2) +5 +1*/ + White_exc16k_32[k] = L_tmp4; /* (Q_excTmp2) +5 +1*/ + move32(); + L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); + } + Q_temp = norm_l( L_tmp ); + IF( L_tmp == 0 ) + { + Q_temp = 31; + move16(); + } + /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ + /* White_exc16k in Q6 */ + + /* calculate pow22 */ + /* pow22=0.00001f */ + tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); + Word64 sum = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + + White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 + chk2 = L_or( chk2, White_exc16k_32[k] ); + /* i: excNoisyEnv in (Q_excTmp2) */ + /* i: White_exc16k in Q6 */ + /* o: White_exc16k in (Q_White_exc16k) */ + /* pow22 += White_exc16k[k] * White_exc16k[k]; */ + sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ + move16(); + } + Q_pow22 = W_norm( sum ); + pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); + Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); + } + +#if 1 // def ADD_IVAS_TBE_CODE + flag_plosive = 0; + move16(); + test(); + test(); + test(); + IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) +#else + IF( GE_32( bitrate, ACELP_24k40 ) ) +#endif + { + IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ + { +#ifndef ADD_IVAS_TBE_CODE // BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k_tmp[k] = round_fx( L_shl( White_exc16k_32[k], *Q_bwe_exc ) ); + move16(); + } + + /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ + find_td_envelope_fx( White_exc16k_tmp, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); /* Q_bwe_exc */ + find_td_envelope_fx( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); /* Q_bwe_exc */ + + FOR( k = 0; k < L_FRAME4k; k++ ) + { + EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; /* Q_bwe_exc */ + move16(); + EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; /* Q_bwe_exc */ + move16(); + } + + /* calculate the optimal mix factor */ + c0 = c1 = c2 = c3 = c4 = c5 = 0; /* Q0 */ + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + + temp1 = add( shl( *Q_bwe_exc, 1 ), 1 ); + temp2 = add( add( Q_shb, *Q_bwe_exc ), 1 ); + temp3 = add( shl( Q_shb, 1 ), 1 ); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + // c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c0_part[i] = L_shr( sum2_fx( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ + move32(); + // c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c1_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ + move32(); + // c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c2_part[i] = L_shr( sum2_fx( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ + move32(); + // c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c3_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ + move32(); + // c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c4_part[i] = L_shr( Dot_product( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), sub( temp1, 1 ) ); /* Q0 */ + move32(); + // c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); + c5_part[i] = L_shr( sum2_fx( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp3 ); /* Q0 */ + move32(); + + c0 = L_add( c0, c0_part[i] ); + c1 = L_add( c1, c1_part[i] ); + c2 = L_add( c2, c2_part[i] ); + c3 = L_add( c3, c3_part[i] ); + c4 = L_add( c4, c4_part[i] ); + c5 = L_add( c5, c5_part[i] ); + } + + // den = 4.0f * c0 * c2 - c4 * c4; + W_tmp = W_sub( W_shl( W_mult0_32_32( c0, c2 ), 2 ), W_mult0_32_32( c4, c4 ) ); + den_e = 63; + move16(); + shift = W_norm( W_tmp ); + den = W_extract_h( W_shl( W_tmp, shift ) ); + den_e = sub( den_e, shift ); + + IF( den == 0 ) + { + den = 1; + move32(); + den_e = 31; + move16(); + } + + // g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; + W_tmp = W_sub( W_mult0_32_32( c3, c4 ), W_shl( W_mult0_32_32( c1, c2 ), 1 ) ); + g1_e = 63; + move16(); + shift = W_norm( W_tmp ); + L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); + g1_e = sub( g1_e, shift ); + + g1 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); + g1_e = sub( add( tmp_e, g1_e ), den_e ); + + // g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; + W_tmp = W_sub( W_mult0_32_32( c1, c4 ), W_shl( W_mult0_32_32( c0, c3 ), 1 ) ); + g2_e = 63; + move16(); + shift = W_norm( W_tmp ); + L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); + g2_e = sub( g2_e, shift ); + + g2 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); + g2_e = sub( add( tmp_e, g2_e ), den_e ); + + // *Env_error = 0.0f; + *Env_error = 0; + move16(); + flag_plosive = 0; + move16(); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + // Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; + L_tmp = BASOP_Util_Add_Mant32Exp( c5_part[i], 31, Mpy_32_32( L_mult( g1, g1 ), c0_part[i] ), add( shl( g1_e, 1 ), 31 ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c1_part[i], g1 ), add( 31, g1_e ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g2, g2 ), c2_part[i] ), add( shl( g2_e, 1 ), 31 ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c3_part[i], g2 ), add( 31, g2_e ), &tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g1, g2 ), c4_part[i] ), add( add( g1_e, g2_e ), 31 ), &tmp_e ); + + // Env_error_part[i] = L_shr( L_tmp, 31 - tmp_e ); // Check Exponent + Env_error_part[i] = extract_h( L_shr_sat( L_tmp, sub( Q15, tmp_e ) ) ); /* Q0 */ + move16(); + + // *Env_error += Env_error_part[i]; + *Env_error = add_sat( *Env_error, Env_error_part[i] ); /* Q0 */ + move16(); + + if ( GT_16( Env_error_part[i], THR_ENV_ERROR_PLOSIVE_FX ) ) // Check which Q + { + /* envelope error is too high -> likely a plosive */ + flag_plosive = 1; + move16(); + } + } + + IF( flag_plosive ) + { + /* plosive detected -> set the mixing factor to 0 */ + *vf_ind = 0; + move16(); + mix_factor = 0; + move16(); + } + ELSE + { + /* normalize gain */ + // g = g2 / ( g1 + g2 ); + tmp1_e = BASOP_Util_Add_MantExp( g1, g1_e, g2, g2_e, &tmp ); + IF( tmp == 0 ) + { + tmp = 1; + move16(); + tmp1_e = 15; + move16(); + } + g = BASOP_Util_Divide1616_Scale( g2, tmp, &tmp_e ); + g_e = sub( add( tmp_e, g2_e ), tmp1_e ); + + /* quantization of the mixing factor */ + cbsize = 1 << NUM_BITS_SHB_VF; + move16(); + // delta = 1.0f / ( cbsize - 1 ); + delta = 2341; /* Q14 */ + move16(); + // if ( g > 1.0f ) + IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), ONE_IN_Q31, 0 ) > 0 ) + { + // g = 1.0f; + g = MAX16B; /* Q15 */ + } + // else if ( g < shl( delta, ( 15 - g_e ) - 14 ) ) + ELSE IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), delta, 17 ) < 0 ) + { + /* prevent low gains to be quantized to 0 as this is reserved for plosives */ + // g = delta; + g = shl( delta, 1 ); /* Q15 */ + } + + *vf_ind = usquant_fx( g, &mix_factor, 0, delta, cbsize ); + move16(); + } + } + ELSE +#else + UNUSED_PARAM( Env_error_part ); + UNUSED_PARAM( Env_error ); + UNUSED_PARAM( EnvSHBres_4k ); + UNUSED_PARAM( c5_part ); + UNUSED_PARAM( c1 ); + UNUSED_PARAM( den ); + UNUSED_PARAM( c3_part ); + UNUSED_PARAM( c0 ); + UNUSED_PARAM( delta ); + UNUSED_PARAM( c3 ); + UNUSED_PARAM( c2_part ); + UNUSED_PARAM( c1_part ); + UNUSED_PARAM( EnvWhiteExc16k ); + UNUSED_PARAM( g2 ); + UNUSED_PARAM( c5 ); + UNUSED_PARAM( c4_part ); + UNUSED_PARAM( EnvWhiteExc16k_4k ); + UNUSED_PARAM( c2 ); + UNUSED_PARAM( g ); + UNUSED_PARAM( cbsize ); + UNUSED_PARAM( g1 ); + UNUSED_PARAM( EnvExc16kWhtnd ); + UNUSED_PARAM( c0_part ); + UNUSED_PARAM( EnvExc16kWhtnd_4k ); + UNUSED_PARAM( c4 ); +#endif + { + Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, + ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); + tmp = voiceFacEst[0]; + tmp2 = MAX_16; + move16(); + move16(); + if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) + { + tmp2 = 26214 /*0.8f Q15*/; + move16(); + } + } + } + ELSE /* decoder side */ + { + test(); +#if 1 // def ADD_IVAS_TBE_CODE + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + IF( *vf_ind == 0 ) + { + // mix_factor = 0.0f; + mix_factor = 0; + move16(); + flag_plosive = 1; + move16(); + } + ELSE + { + // mix_factor = usdequant(*vf_ind, 0.0f, 1.0f / ((1 << NUM_BITS_SHB_VF) - 1)); + mix_factor = usdequant_fx( *vf_ind, 0, 2341 ); + } + } + ELSE +#endif + { + /* *vf_ind is an integer scale by 0.125f*/ + tmp = shl( *vf_ind, ( 15 - 3 ) ); + tmp2 = MAX_16; + move16(); + IF( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) + { + tmp2 = 26214 /*0.8f Q15*/; + move16(); + } + } + } +#if 1 // def ADD_IVAS_TBE_CODE + test(); + IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) +#endif + { + voice_factors[0] = mult_r( voice_factors[0], tmp2 ); + move16(); + voice_factors[1] = mult_r( voice_factors[1], tmp2 ); + move16(); + voice_factors[2] = mult_r( voice_factors[2], tmp2 ); + move16(); + voice_factors[3] = mult_r( voice_factors[3], tmp2 ); + move16(); + voice_factors[4] = mult_r( voice_factors[4], tmp2 ); + move16(); + } + } + test(); + IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) + { + /* save buffers for IC-BWE */ + // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); + Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); + // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); + /*Word16 temp_fac = divide3232(L_shr(pow1, Q_pow1), pow22); + Word16 temp_fac_exp = 0; + temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + Word16 temp_fac = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 + shift = sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ); + // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + mixExc16k[k] = mult_r( shl_sat( White_exc16k[k], shift ), temp_fac ); + move16(); + } + } + + tmp = sub( Q_temp, 3 ); + FOR( k = 0; k < L_FRAME16k; k++ ) + { + White_exc16k_FB[k] = White_exc16k[k]; /* Q_White_exc16k */ + } + prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; + move16(); + *Q_bwe_exc_fb = Q_White_exc16k; + move16(); + *tbe_demph = shl_sat( *tbe_demph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); + deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); + *tbe_demph = shl_sat( *tbe_demph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + + Q_exc16kWhtnd = getScaleFactor16( exc16kWhtnd, L_FRAME16k ); + Q_exc16kWhtnd = add( Q_exc16kWhtnd, *Q_bwe_exc ); + + shift = getScaleFactor16( White_exc16k, L_FRAME16k ); + + shift = s_min( Q_exc16kWhtnd, add( shift, Q_White_exc16k ) ); + scale_sig( exc16kWhtnd, L_FRAME16k, sub( shift, *Q_bwe_exc ) ); + scale_sig( White_exc16k, L_FRAME16k, sub( shift, Q_White_exc16k ) ); + + Q_exc16kWhtnd = Q_White_exc16k = shift; + move16(); + move16(); + *tbe_premph = shl_sat( *tbe_premph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); + move16(); + test(); + IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) + { + IF( !flag_plosive ) /* use only LB excitation in case of plosives */ + { + /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ + // old_scale = (float)sqrt(*prev_pow_exc16kWhtnd / pow1); + // old_scale = divide3232(*prev_pow_exc16kWhtnd, pow1); // exp = Q15 - (Q_pow1) + // Word16 old_scale_exp = Q15 - (Q_pow1); + // old_scale = Sqrt16(old_scale, &old_scale_exp); + // old_scale = shl(old_scale, old_scale_exp); //Q15 + L_tmp = root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ); + old_scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 + // new_scale = 1.0f; + new_scale = 32767; + move16(); + // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); + step_scale = mult_r( sub( new_scale, old_scale ), 205 ); + scale = old_scale; + move16(); + /* interpolate between the old and the new value of the mixing factor */ + old_fact = *prev_mix_factor; + move16(); + new_fact = mix_factor; + move16(); + // step = (new_fact - old_fact) / (L_FRAME16k / 2); + step = mult_r( sub( new_fact, old_fact ), 205 ); + fact = old_fact; + move16(); + /* mixing of LB and gaussian excitation in the first half of the frame */ + FOR( k = 0; k < L_FRAME16k / 2; k++ ) + { + exc16kWhtnd[k] = mac_r( L_mult( fact, mult_r( White_exc16k[k], scale ) ), + sub( 32767, fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd + move16(); + fact = add_sat( fact, step ); + scale = add_sat( scale, step_scale ); + } + + /* mixing of LB and gaussian excitation in the second half of the frame */ + FOR( ; k < L_FRAME16k; k++ ) + { + exc16kWhtnd[k] = mac_r( L_mult( new_fact, White_exc16k[k] ), + sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd + move16(); + } + } + // preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + } + ELSE + { + test(); + IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) + { + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + test(); + if ( chk1 == 0 && chk2 == 0 ) + { + L_tmp = 0; + move32(); + } + scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); + move16(); + } + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + /* i/o: exc16kWhtnd (Q_exc16kWhtnd) */ + /* i/o: tbe_premph (Q_exc16kWhtnd) */ + } + ELSE + { + Word16 nbSubFr, lSubFr; + Word16 tempQ15; + Word32 tempQ31; + nbSubFr = NB_SUBFR16k; + lSubFr = ( L_FRAME16k / NB_SUBFR16k ); + move16(); + move16(); + IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) + { + nbSubFr = NB_SUBFR; + move16(); + lSubFr = ( L_FRAME16k / NB_SUBFR ); + move16(); + } + k = 0; + move16(); + FOR( i = 0; i < nbSubFr; i++ ) + { + test(); + IF( EQ_16( coder_type, VOICED ) && ( LT_32( extl_brate, SWB_TBE_2k8 ) ) ) + { + exp = 0; + move16(); + tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ + temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + exp = 0; + move16(); + tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ + temp = sub( MAX_16, temp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } + ELSE + { + /* Adjust noise mixing for formant sharpening filter */ + tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); + /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ + vf_tmp = sub( MAX_16, tempQ15 ); + vf_tmp = mult( voice_factors[i], vf_tmp ); + + exp = 0; + move16(); + tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ + temp = sub( MAX_16, vf_tmp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } + + FOR( j = 0; j < lSubFr; j++ ) + { + /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ + L_tmp = L_mult( temp2, White_exc16k[k + j] ); + exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); + move16(); + /* Q_exc16kWhtnd */ + } + k = add( k, lSubFr ); + + /* estimate the pre-emph factor */ + tempQ15 = sub( MAX_16, voice_factors[i] ); + exp = 0; + move16(); + temp = Sqrt16( tempQ15, &exp ); + temp = shl( temp, sub( exp, 1 ) ); + + temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ + temp = div_s( temp, temp2 ); /* Q15 */ + temp = mult_r( PREEMPH_FAC, temp ); + PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); + /* exc16kWhtnd: Q_exc16kWhtnd; + tbe_premph: Q_exc16kWhtnd*/ + } + } + } + *tbe_premph = shl_sat( *tbe_premph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + move16(); + Scale_sig( White_exc16k, L_FRAME16k, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); + Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); + + IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) + { + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: excSHB in Q_bwe_exc */ + } + ELSE + { + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); + + Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[0] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[1] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[2] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); + tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); + Scale_sig( tempSHB, 80, tmp ); + syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); + syn_shb_ener_sf_q[3] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); + move16(); + + tmp2 = s_min( s_min( syn_shb_ener_sf_q[0], syn_shb_ener_sf_q[1] ), s_min( syn_shb_ener_sf_q[3], syn_shb_ener_sf_q[2] ) ); + syn_shb_ener_sf[0] = L_shl( syn_shb_ener_sf[0], sub( tmp2, syn_shb_ener_sf_q[0] ) ); + move32(); + syn_shb_ener_sf[1] = L_shl( syn_shb_ener_sf[1], sub( tmp2, syn_shb_ener_sf_q[1] ) ); + move32(); + syn_shb_ener_sf[2] = L_shl( syn_shb_ener_sf[2], sub( tmp2, syn_shb_ener_sf_q[2] ) ); + move32(); + syn_shb_ener_sf[3] = L_shl( syn_shb_ener_sf[3], sub( tmp2, syn_shb_ener_sf_q[3] ) ); + move32(); + + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: tempSHB in Q_bwe_exc */ + /* o: syn_shb_ener_sf in tmp2 */ + IF( LE_32( bitrate, MAX_ACELP_BRATE ) ) + { + L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); + + /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ + tmp = shl( Q_shb, 1 ); + L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ + + *Q_bwe_exc = sub( *Q_bwe_exc, exp ); + move16(); /* compensate for the exp shift */ + tmp2 = add( prev_Q_bwe_syn, n_mem2 ); + IF( GT_16( *Q_bwe_exc, tmp2 ) ) + { + L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); + *Q_bwe_exc = tmp2; + move16(); + } + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ + exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ + move16(); + } + } + /* i: L_tmp2 in (Q31-exp) */ + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ + + /* Rescale the past memories: LP synth and SHB look ahead buffers */ + tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + state_lpc_syn[i] = shl_sat( state_lpc_syn[i], tmp ); + move16(); + } + FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) + { + excSHB[i] = shl_sat( excSHB[i], tmp ); + move16(); + } + /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ + + Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in (Q_bwe_exc) */ + /* o: excSHB in (Q_bwe_exc) */ + } + + IF( EQ_16( extl, FB_TBE ) ) + { + tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); + Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); + Scale_sig( fb_tbe_demph, 1, tmp ); + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); + /* i: White_exc16k_FB in (14-n2) */ + /* o: White_exc16k_FB_temp in (14-n2) */ + + FOR( i = 0; i < 10; i++ ) + { + FOR( j = 0; j < 32; ++j ) + { + White_exc16k_FB_temp[i * 32 + j] = mult_r_sat( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); + move16(); + } + } + + *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); + move16(); /**Q_bwe_exc_fb +35 +1 -16*/ + flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); + + deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); + } + ELSE + { + set16_fx( White_exc16k_FB, 0, L_FRAME16k ); + } + +#if 1 // def ADD_IVAS_TBE_CODE + *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 + *prev_mix_factor = mix_factor; +#endif + return; +} + +/*====================================================================================*/ +/* FUNCTION : void GenSHBSynth_fx() */ +/*------------------------------------------------------------------------------------*/ +/* PURPOSE :Generate 32 KHz sampled highband component from synthesized highband*/ +/*------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS */ +/* _(Word16*)input_synspeech :input synthesized speech */ +/* _(Word16) L_frame :ACELP frame length */ +/*------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _(Word16*)shb_syn_speech_32k : output highband component */ +/*------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _(Word16[]) allpass_mem : memory */ +/* _(Word32[]) Hilbert_Mem : memory */ +/*------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*------------------------------------------------------------------------------------*/ + +void GenSHBSynth_fx( + const Word16 *input_synspeech, /* i : input synthesized speech */ + Word16 *shb_syn_speech_32k, /* o : output highband component */ + Word32 Hilbert_Mem[], /* i/o: memory */ + Word16 allpass_mem[], /* i/o: memory */ + const Word16 L_frame, /* i : ACELP frame length */ + Word16 *syn_dm_phase ) +{ + Word16 i, speech_buf_32k[L_FRAME32k]; + Word16 maxm, nor, nor32, shift; + Word16 input_synspeech_temp[L_FRAME16k]; + Word32 maxm32; + + + maxm = 0; + move16(); + maxm32 = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + maxm = s_max( maxm, abs_s( input_synspeech[i] ) ); + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + maxm = s_max( maxm, abs_s( allpass_mem[i] ) ); + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); + nor = sub( norm_s( maxm ), 3 ); + nor32 = sub( norm_l( maxm32 ), 3 ); + if ( maxm == 0 ) + { + nor = 15; + move16(); + } + if ( maxm32 == 0 ) + { + nor32 = 31; + move16(); + } + shift = s_min( nor, nor32 ); + + Copy_Scale_sig( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); + Scale_sig( allpass_mem, 2 * ALLPASSSECTIONS_STEEP, shift ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); + Interpolate_allpass_steep_fx( input_synspeech_temp, allpass_mem, L_FRAME16k, speech_buf_32k ); + /*modify_Fs_fx( input_synspeech, L_FRAME16k, 16000, speech_buf_32k, 32000, allpass_mem, 0);*/ + IF( EQ_16( L_frame, L_FRAME ) ) + { + /* 12.8 k core flipping and downmixing */ + flip_and_downmix_generic_fx( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, + Hilbert_Mem, + Hilbert_Mem + HILBERT_ORDER1, + Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), + syn_dm_phase ); + } + ELSE + { + /* 16 k core flipping and no downmixing */ + FOR( i = 0; i < L_FRAME32k; i = i + 2 ) + { + shb_syn_speech_32k[i] = negate( speech_buf_32k[i] ); + move16(); + shb_syn_speech_32k[i + 1] = speech_buf_32k[i + 1]; + move16(); + } + } + + Scale_sig( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); + Scale_sig( allpass_mem, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); + + return; +} + + +/* IVAS 32-bit variant */ +void GenSHBSynth_fx32( + const Word32 *input_synspeech, /* i : input synthesized speech Qx*/ + Word32 *shb_syn_speech_32k, /* o : output highband component Qx*/ + Word32 Hilbert_Mem[], /* i/o: memory Qx*/ + Word32 state_lsyn_filt_shb_local[], /* i/o: memory Qx*/ + const Word16 L_frame, /* i : ACELP frame length */ + Word16 *syn_dm_phase ) +{ + Word32 speech_buf_32k[L_FRAME32k]; + Word16 i; + + Word16 shift = 0; + Word32 maxm32, input_synspeech_temp[L_FRAME16k]; + move16(); + + /* find the maximum value and derive the shift to improve precision of the Hilber filter */ + maxm32 = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + maxm32 = L_max( maxm32, L_abs( input_synspeech[i] ) ); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + maxm32 = L_max( maxm32, L_abs( state_lsyn_filt_shb_local[i] ) ); + } + + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); + } + + IF( maxm32 != 0 ) + { + shift = sub( norm_l( maxm32 ), 3 ); + + Copy_Scale_sig32( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); + } + ELSE + { + Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); + } + + Interpolate_allpass_steep_fx32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); + + IF( EQ_16( L_frame, L_FRAME ) ) + { + flip_and_downmix_generic_fx32( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, Hilbert_Mem, Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), syn_dm_phase ); + } + ELSE + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + // shb_syn_speech_32k[i] = ( ( i % 2 ) == 0 ) ? ( -speech_buf_32k[i] ) : ( speech_buf_32k[i] ); + IF( i % 2 == 0 ) + { + shb_syn_speech_32k[i] = L_negate( speech_buf_32k[i] ); // Qx + } + ELSE + { + shb_syn_speech_32k[i] = speech_buf_32k[i]; // Qx + } + move32(); + } + } + + IF( maxm32 != 0 ) + { + Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); + } + + return; +} + + +/*==============================================================================*/ +/* FUNCTION : void ScaleShapedSHB_fx() */ +/*------------------------------------------------------------------------------*/ +/* PURPOSE : */ +/*------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _(Word16) length : SHB overlap length */ +/* _(Word16*) subgain : subframe gain Q15 */ +/* _(Word32) frame_gain : frame gain Q18 */ +/* _(Word16*) win : window Q15 */ +/* _(Word16*) subwin : subframes window Q15 */ +/* _(Word16) Q_bwe_exc : Q format */ +/*------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _(Word16) Qx : Q factor of output */ +/*------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _(Word16*) synSHB : synthesized shb signal input Q_bwe_exc / output Qx */ +/* _(Word16*) overlap : buffer for overlap-add Q_bwe_exc /output Qx */ +/*------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*------------------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*==============================================================================*/ + +void ScaleShapedSHB_fx( + const Word16 length, /* i : SHB overlap length */ + Word16 *synSHB, /* i/o : synthesized shb signal Q(Q_bwe_exc)/Q(Qx) */ + Word16 *overlap, /* i/o : buffer for overlap-add Q(Q_bwe_exc)/Q(Qx) */ + const Word16 *subgain, /* i : subframe gain Q15 */ + const Word32 frame_gain, /* i : frame gain Q18 */ + const Word16 *win, /* i : window Q15 */ + const Word16 *subwin, /* i : subframes window Q15 */ + Word16 *Q_bwe_exc, + Word16 *Qx, /* o : newly computed Q factor for synSHB */ + Word16 n_mem3, + Word16 prev_Q_bwe_syn2 ) +{ + const Word16 *skip; + Word16 i, j, k, l_shb_lahead, l_frame, l_frame_tmp; + Word16 join_length, num_join; + Word32 mod_syn[L_FRAME16k + L_SHB_LAHEAD]; + Word16 sum_gain; + Word32 L_tmp; + Word16 tmpQ15; + Word16 Q_gFr_norm, gain_frame_Q16; + Word32 L_tmp2; + Word16 temp1, temp2; + + /* Init */ + set32_fx( mod_syn, 0, L_FRAME16k + L_SHB_LAHEAD ); + + /* apply gain for each subframe, and store noise output signal using overlap-add */ + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + /* WB Gain shape and gain frame application with overlap */ + skip = skip_bands_WB_TBE; + l_frame = L_FRAME16k / 4; + move16(); + l_shb_lahead = L_SHB_LAHEAD / 4; + move16(); + + sum_gain = 0; + move16(); + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain = mult_r( subwin[2 * k + 2], subgain[0] ); /* Q15 */ + mod_syn[skip[0] + k] = L_mult( sum_gain, synSHB[skip[0] + k] ); /* Q_bwe_exc + 16 */ + move32(); + mod_syn[skip[0] + k + length / 2] = L_mult( subgain[0], synSHB[skip[0] + k + length / 2] ); /* Q_bwe_exc + 16 */ + move32(); + } + FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) + { + FOR( k = 0; k < length; k++ ) + { + /* one bit headroom here, otherwise messes up the gain shape application */ + /* keep it as L_mult0 */ + L_tmp = L_mult0( subwin[k + 1], subgain[i] ); /* Q30 */ + sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i - 1] ) ); /* Q14 */ + mod_syn[skip[i] + k] = L_shl( L_mult( sum_gain, synSHB[skip[i] + k] ), 1 ); /* Q_bwe_exc + 16 */ + move32(); + } + } + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain = mult_r( subwin[length - 2 * k - 2], subgain[i - 1] ); /* Q15 */ + mod_syn[skip[i] + k] = L_mult( sum_gain, synSHB[skip[i] + k] ); /* Q_bwe_exc + 16 */ + move32(); + } + } + ELSE + { + /* SWB Gain shape and gain frame application with overlap */ + l_frame = L_FRAME16k; + move16(); + l_shb_lahead = L_SHB_LAHEAD; + move16(); + skip = skip_bands_SWB_TBE; + + num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; + move16(); + join_length = i_mult2( num_join, length ); + j = 0; + move16(); + FOR( k = 0; k < length; k++ ) + { + sum_gain = mult_r( subwin[k + 1], subgain[0] ); /* Q15 */ + mod_syn[j] = L_mult( synSHB[j], sum_gain ); + move32(); /* Q_bwe_exc + 16 */ + j = add( j, 1 ); + } + + FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) + { + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn[j] = L_mult( synSHB[j], subgain[i * num_join] ); + move32(); /* Q_bwe_exc + 16 */ + j = add( j, 1 ); + } + + FOR( k = 0; k < length; k++ ) + { + /* one bit headroom here, otherwise messes up the gain shape application */ + /* keep it as L_mult0 */ + L_tmp = L_mult0( subwin[k + 1], subgain[( i + 1 ) * num_join] ); /* Q30 */ + sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i * num_join] ) ); /*Q14 */ + mod_syn[j] = L_shl( L_mult( sum_gain, synSHB[j] ), 1 ); + move32(); /* Q_bwe_exc + 16 */ + j = add( j, 1 ); + } + } + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn[j] = L_mult( synSHB[j], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); + move32(); /* Q_bwe_exc + 16 */ + j = add( j, 1 ); + } + FOR( k = 0; k < length; k++ ) + { + sum_gain = mult_r( subwin[length - k - 1], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); /* Q15 */ + mod_syn[j] = L_mult( synSHB[j], sum_gain ); + move32(); /* Q_bwe_exc + 16 */ + j = add( j, 1 ); + } + } + + + Q_gFr_norm = norm_l( frame_gain ); + if ( frame_gain == 0 ) + { + Q_gFr_norm = 31; + move16(); + } + Q_gFr_norm = sub( Q_gFr_norm, 1 ); /* give some headroom */ + + gain_frame_Q16 = round_fx( L_shl( frame_gain, Q_gFr_norm ) ); /* Q = 18 + Q_gFr_norm - 16 + = (Q_gFr_norm + 2) */ + + *Q_bwe_exc = add( *Q_bwe_exc, Q_gFr_norm ); /* compensate for the exp shift */ + move16(); + *Q_bwe_exc = sub( *Q_bwe_exc, 13 ); /* Keep Q-fac at => (Q_bwe_exc + Q_gFr_norm - 13) */ + move16(); + + /* check for headroom of previous buff memories: overlap, Hilbert, and interp all-pass mem */ + tmpQ15 = add( prev_Q_bwe_syn2, n_mem3 ); + if ( GT_16( *Q_bwe_exc, tmpQ15 ) ) + { + *Q_bwe_exc = tmpQ15; + move16(); + } + + *Qx = *Q_bwe_exc; + move16(); + /* rescale the overlap memory */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + temp2 = 1; + move16(); + if ( overlap[i] < 0 ) + { + temp2 = -1; + move16(); + } + temp1 = abs_s( overlap[i] ); + temp1 = shl( temp1, sub( *Q_bwe_exc, prev_Q_bwe_syn2 ) ); + overlap[i] = i_mult( temp1, temp2 ); + move16(); /* Q_bwe_exc + Q_gFr_norm - 13 */ + } + + FOR( i = 0; i < l_shb_lahead; i++ ) + { + L_tmp = Mpy_32_16_1( mod_syn[i], gain_frame_Q16 ); /* Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15 */ + L_tmp2 = Mpy_32_16_1( L_tmp, win[i] ); /* (Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15) + 15 + (1-16) */ + synSHB[i] = mac_r( L_tmp2, overlap[i], MAX_16 ); + move16(); /* Q_bwe_exc + Q_gFr_norm - 13 */ + synSHB[i + l_shb_lahead] = round_fx( L_tmp ); /* Q_bwe_exc + Q_gFr_norm - 13 */ + move16(); + } + + FOR( ; i < l_frame; i++ ) + { + L_tmp = Mpy_32_16_1( mod_syn[i], gain_frame_Q16 ); /* Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15 */ + synSHB[i] = round_fx( L_tmp ); /* Q_bwe_exc + Q_gFr_norm - 13 */ + move16(); + } + + l_frame_tmp = add( l_frame, l_shb_lahead ); + FOR( ; i < l_frame_tmp; i++ ) + { + L_tmp = Mpy_32_16_1( mod_syn[i], gain_frame_Q16 ); /* Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15 */ + L_tmp = Mpy_32_16_1( L_tmp, win[l_frame + l_shb_lahead - 1 - i] ); /* (Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15) + 15 + (1-16) */ + overlap[i - l_frame] = round_fx( L_tmp ); /* Q_bwe_exc + Q_gFr_norm - 13 */ + move16(); + } + + return; +} + + +/* IVAS 32-bit variant */ +void ScaleShapedSHB_fx32( + const Word16 length, /* i : SHB overlap length */ + Word32 *synSHB_fx, /* i/o: synthesized shb signal Q_inp/Q_new */ + Word32 *overlap_fx, /* i/o: buffer for overlap-add Q_inp/Q_new */ + const Word16 *subgain_fx, /* i : subframe gain Q15 */ + const Word32 frame_gain_fx, /* i : frame gain Q18*/ + const Word16 *win_fx, /* i : window Q15 */ + const Word16 *subwin_fx, /* i : subframes window Q15 */ + Word16 *Q_inp, + Word16 *Q_new ) +{ + const Word16 *skip; + Word16 i, j, k, l_shb_lahead, l_frame; + Word16 join_length, num_join; + Word32 mod_syn_fx[L_FRAME16k + L_SHB_LAHEAD], L_tmp; + Word16 sum_gain_fx; + + /* initilaization */ + l_frame = L_FRAME16k; + l_shb_lahead = L_SHB_LAHEAD; + move16(); + move16(); + skip = skip_bands_SWB_TBE; + + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + skip = skip_bands_WB_TBE; + l_frame = L_FRAME16k / 4; + l_shb_lahead = L_SHB_LAHEAD / 4; + move16(); + move16(); + } + + /* apply gain for each subframe, and store noise output signal using overlap-add */ + set32_fx( mod_syn_fx, 0, l_frame + l_shb_lahead ); + + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + sum_gain_fx = 0; + move16(); + FOR( k = 0; k < shr( length, 1 ); k++ ) + { + sum_gain_fx = mult_r( subwin_fx[2 * k + 2], subgain_fx[0] ); + mod_syn_fx[skip[0] + k] = Mpy_32_16_1( synSHB_fx[skip[0] + k], sum_gain_fx ); + move32(); // Qx + mod_syn_fx[skip[0] + k + length / 2] = Mpy_32_16_1( synSHB_fx[skip[0] + k + length / 2], subgain_fx[0] ); // Qx + move32(); + } + FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) + { + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_fx[k + 1], subgain_fx[i] ); + sum_gain_fx = round_fx( L_mac0( L_tmp, subwin_fx[length - k - 1], subgain_fx[i - 1] ) ); + mod_syn_fx[skip[i] + k] = L_shl( Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ), 1 ); // Qx + move32(); + } + } + FOR( k = 0; k < shr( length, 1 ); k++ ) + { + sum_gain_fx = mult_r( subwin_fx[length - k * 2 - 2], subgain_fx[i - 1] ); + mod_syn_fx[skip[i] + k] = Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ); // Qx + move32(); + } + } + ELSE + { + num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; + join_length = i_mult( num_join, length ); + j = 0; + move16(); + move16(); + FOR( k = 0; k < length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[k + 1], subgain_fx[0] ) ); // Qx + move32(); + j = add( j, 1 ); + } + FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) + { + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[i * num_join] ); // Qx + move32(); + j = add( j, 1 ); + } + + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_fx[length - k - 1], subgain_fx[i * num_join] ); + mod_syn_fx[j] = L_shl( Mpy_32_16_1( synSHB_fx[j], round_fx( L_mac0( L_tmp, subwin_fx[k + 1], subgain_fx[( i + 1 ) * num_join] ) ) ), 1 ); // Qx + move32(); + j = add( j, 1 ); + } + } + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); // Qx + move32(); + j = add( j, 1 ); + } + FOR( k = 0; k < length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[length - k - 1], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ) ); // Qx + move32(); + j = add( j, 1 ); + } + } + + Word16 norm_shift = norm_l( frame_gain_fx ); + if ( frame_gain_fx == 0 ) + { + norm_shift = 31; + move16(); + } + + norm_shift = s_min( norm_shift, 14 ); + norm_shift = sub( norm_shift, 1 ); + + *Q_new = add( *Q_inp, sub( norm_shift, 13 ) ); // Q_new = Q_inp + min(norm_shift,14) - 14; + move16(); + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + overlap_fx[i] = L_shl( overlap_fx[i], sub( *Q_new, *Q_inp ) ); + move32(); + } + + FOR( i = 0; i < l_shb_lahead; i++ ) + { + synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[i] ) ); // Q_new + synSHB_fx[i] = L_add( synSHB_fx[i], overlap_fx[i] ); + synSHB_fx[i + l_shb_lahead] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new + move32(); + move32(); + move32(); + } + + FOR( ; i < l_frame; i++ ) + { + synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new + move32(); + } + + FOR( ; i < l_frame + l_shb_lahead; i++ ) + { + synSHB_fx[i] = L_shl( synSHB_fx[i], sub( *Q_new, *Q_inp ) ); + overlap_fx[i - l_frame] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[l_frame + l_shb_lahead - 1 - i] ) ); // Q_new + move32(); + move32(); + } + + *Q_inp = *Q_new; + move16(); + return; +} + + +/*-------------------------------------------------------------------* + * ScaleShapedWB() + * + * + *-------------------------------------------------------------------*/ + +void ScaleShapedWB_fx( + const Word16 length, /* i : SHB overlap length */ + Word16 *synSHB, /* i/o : synthesized shb signal Q_bwe_exc/Qx */ + Word16 *overlap, /* i/o : buffer for overlap-add Q_bwe_exc/Qx */ + const Word16 *subgain, /* i : subframe gain Q15*/ + const Word32 frame_gain, /* i : frame gain Q18 */ + const Word16 *win, /* i : window Q15*/ + const Word16 *subwin, /* i : subframes window Q15*/ + const Word16 Q_bwe_exc, + Word16 L_frame, /* i : Frame length - determines whether 12.8 or 16kHz core in-use */ + Word16 dynQ, /* i : indicate whether output is dynamic Q, or Q0 */ + Word16 *Qx, /* o : newly computed Q factor for synSHB */ + Word16 prev_Qx, /* i : prev_Qx for memory scaling */ + Word32 *Hilbert_Mem /* i : Hilbert memory used for computing Qx */ +) +{ + const Word16 *skip; + Word16 i, j, k, l_shb_lahead, l_frame, l_frame_tmp; + Word16 join_length, num_join; + Word32 mod_syn[L_FRAME16k + L_SHB_LAHEAD]; + Word16 sum_gain; + Word32 L_tmp; + Word16 max_val, abs_sig, sc1, sc2, shift, max_headroom, min_shift, max_shift, max_shift2; + /* Init */ + set32_fx( mod_syn, 0, L_FRAME16k + L_SHB_LAHEAD ); + + /* apply gain for each subframe, and store noise output signal using overlap-add */ + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + /* WB Gain shape and gain frame application with overlap */ + skip = skip_bands_WB_TBE; + move16(); + l_frame = L_FRAME16k / 4; + move16(); + l_shb_lahead = L_SHB_LAHEAD / 4; + move16(); + + sum_gain = 0; + move16(); + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain = mult_r( subwin[2 * k + 2], subgain[0] ); /* Q15 */ + mod_syn[skip[0] + k] = L_mult( sum_gain, synSHB[skip[0] + k] ); + move32(); /* Q_bwe_exc + 16 */ + mod_syn[skip[0] + k + length / 2] = L_mult( subgain[0], synSHB[skip[0] + k + length / 2] ); + move32(); /* Q_bwe_exc + 16 */ + } + FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) + { + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin[k + 1], subgain[i] ); /* Q30 */ + sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i - 1] ) ); /* Q14 */ + mod_syn[skip[i] + k] = L_shl( L_mult( sum_gain, synSHB[skip[i] + k] ), 1 ); + move32(); /* Q_bwe_exc + 16 */ + } + } + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain = mult_r( subwin[length - 2 * k - 2], subgain[i - 1] ); /* Q15 */ + mod_syn[skip[i] + k] = L_mult( sum_gain, synSHB[skip[i] + k] ); + move32(); /* Q_bwe_exc + 16 */ + } + } + ELSE + { + /* SWB Gain shape and gain frame application with overlap */ + l_frame = L_FRAME16k; + move16(); + l_shb_lahead = L_SHB_LAHEAD; + move16(); + skip = skip_bands_SWB_TBE; + move16(); + + num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; + move16(); + join_length = i_mult2( num_join, length ); + j = 0; /* ptr*/ + move16(); + FOR( k = 0; k < length; k++ ) + { + sum_gain = mult_r( subwin[k + 1], subgain[0] ); /* Q15 */ + mod_syn[j] = L_mult( synSHB[j], sum_gain ); + move32(); /* Q_bwe_exc + 16 */ + j++; + } + + FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) + { + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn[j] = L_mult( synSHB[j], subgain[i * num_join] ); + move32(); /* Q_bwe_exc + 16 */ + j++; + } + + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin[k + 1], subgain[i_mult2( ( i + 1 ), num_join )] ); /* Q30 */ + sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i * num_join] ) ); /*Q14 */ + mod_syn[j] = L_shl( L_mult( sum_gain, synSHB[j] ), 1 ); + move32(); /* Q_bwe_exc + 16 */ + j++; + } + } + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn[j] = L_mult( synSHB[j], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); + move32(); /* Q_bwe_exc + 16 */ + j++; + } + FOR( k = 0; k < length; k++ ) + { + sum_gain = mult_r( subwin[length - k - 1], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); /* Q15 */ + mod_syn[j] = L_mult( synSHB[j], sum_gain ); + move32(); /* Q_bwe_exc + 16 */ + j++; + } + } + + + max_val = 0; + move16(); + FOR( i = 0; i < l_frame + l_shb_lahead; i++ ) + { + abs_sig = abs_s( round_fx( mod_syn[i] ) ); + if ( GT_16( abs_sig, max_val ) ) + { + max_val = abs_sig; + move16(); + } + } + + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + abs_sig = abs_s( round_fx( Hilbert_Mem[i] ) ); + if ( GT_16( abs_sig, max_val ) ) + { + max_val = abs_sig; + move16(); + } + } + + sc1 = norm_s( max_val ); /* max_val headroom in mod_syn[] */ + sc2 = norm_s( round_fx( frame_gain ) ); /* headroom in GainFrame */ + + IF( dynQ == 0 ) + { + shift = sub( 13, Q_bwe_exc ); /* earlier = (10 - Q_bwe_exc) but we changed GainFrame Q21 to Q18 */ + *Qx = 0; + move16(); + } + ELSE IF( EQ_16( L_frame, L_FRAME ) ) /* 12.8k core */ + { + max_headroom = sub( add( sc1, sc2 ), 4 ); /* Max headroom after multiplying = sc1 + sc2 -3 (keep 3 bit extra headroom) */ + /* 12.8k core needs extra headroom than 16k core */ + /* otherwise Hilbert transform inside flip_and_downmix have saturation, causes ringing in output */ + + /* Qx = (Q_bwe_exc+3) + shift - 16 */ + /* make sure 14 > Qx > 2 */ + min_shift = sub( 2, sub( add( Q_bwe_exc, 3 ), 16 ) ); + max_shift = sub( 13, sub( add( Q_bwe_exc, 3 ), 16 ) ); + max_shift2 = s_min( max_shift, max_headroom ); /* avoid shifting more than the available max_val headroom to avoid overflow */ + + shift = s_min( min_shift, max_shift2 ); + *Qx = sub( add( add( Q_bwe_exc, 3 ), shift ), 16 ); + move16(); + } + ELSE /* 16k core */ + { + max_headroom = sub( add( sc1, sc2 ), 1 ); /* Max headroom after multiplying = sc1 + sc2 -1 (keep 1 bit extra headroom) */ + + /* Qx = (Q_bwe_exc+3) + shift - 16 */ + /* make sure 14 > Qx > 3 */ + min_shift = sub( 3, sub( add( Q_bwe_exc, 3 ), 16 ) ); + move16(); + max_shift = sub( 13, sub( add( Q_bwe_exc, 3 ), 16 ) ); + move16(); + max_shift2 = s_min( max_shift, max_headroom ); /* avoid shifting more than the available max_val headroom to avoid overflow */ + + shift = s_min( min_shift, max_shift2 ); + *Qx = sub( add( add( Q_bwe_exc, 3 ), shift ), 16 ); + move16(); + } + + /* bring memory st_fx->syn_overlap_fx[] = overlap[i] to new Q = Qx to prepare for addition */ + FOR( i = 0; i < l_shb_lahead; i++ ) + { + overlap[i] = shl( overlap[i], sub( *Qx, prev_Qx ) ); + move16(); + } + + FOR( i = 0; i < l_shb_lahead; i++ ) + { + /* mod_syn in (16+Q_bwe_exc), frame_gain in Q18 */ + L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ + synSHB[i] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, win[i] ), shift ) ); /* Qx */ + move16(); + synSHB[i] = add_sat( synSHB[i], overlap[i] ); + move16(); /* Qx */ + synSHB[i + l_shb_lahead] = round_fx_sat( L_shl_sat( L_tmp, shift ) ); /* Qx */ + move16(); + } + + FOR( ; i < l_frame; i++ ) + { + L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ + synSHB[i] = round_fx_sat( L_shl_sat( L_tmp, shift ) ); /* Qx; */ + move16(); + } + + l_frame_tmp = add( l_frame, l_shb_lahead ); + FOR( ; i < l_frame_tmp; i++ ) + { + L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* (Q_bwe_exc+3) */ + overlap[i - l_frame] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, win[l_frame + l_shb_lahead - 1 - i] ), shift ) ); /* Qx */ + move16(); + } + + return; +} + +/*-------------------------------------------------------------------* + * non_linearity() + * + * Apply a non linearity to the SHB excitation + * -------------------------------------------------------------------*/ + +static Word32 non_linearity_scaled_copy( + const Word16 input[], + Word16 j, + const Word16 length, + Word32 output[], + Word32 prev_scale, + const Word16 scale_step, + const Word16 en_abs ) +{ + Word16 i; + Word32 L_tmp; + + + IF( en_abs ) + { + FOR( i = 0; i < j; i++ ) + { + L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + output[i] = L_tmp; + move32(); + + L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ + prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ + } + FOR( ; i < length; i++ ) + { + L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + output[i] = L_tmp; + move32(); + } + } + ELSE + { + FOR( i = 0; i < j; i++ ) + { + L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + + if ( input[i] < 0 ) + { + L_tmp = L_negate( L_tmp ); + } + output[i] = L_tmp; + move32(); + + L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ + prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ + } + + FOR( ; i < length; i++ ) + { + L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + + if ( input[i] < 0 ) + { + L_tmp = L_negate( L_tmp ); + } + output[i] = L_tmp; + move32(); + } + } + return prev_scale; +} + + +/*-------------------------------------------------------------------* + * non_linearity() + * + * Apply a non linearity to the SHB excitation + * -------------------------------------------------------------------*/ + +static Word32 non_linearity_scaled_copy_ivas( + const Word16 input[], + Word16 j, + const Word16 length, + Word32 output[], + Word32 prev_scale, + const Word16 scale_step, + const Word16 en_abs ) +{ + Word16 i; + Word32 L_tmp; + + + IF( en_abs ) + { + FOR( i = 0; i < j; i++ ) + { + L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + + test(); + test(); + if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) + { + /* NOTE: this is done to avoid the product to become zero for small non-zero input */ + L_tmp = 1; + move16(); + } + + output[i] = L_tmp; + move32(); + + L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ + prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ + } + FOR( ; i < length; i++ ) + { + /* L_tmp = (input[i] * input[i]) * prev_scale;*/ + L_tmp = Mpy_32_16_1( Mpy_32_16_1( prev_scale, input[i] ), input[i] ); /* 2*Q_inp */ + + test(); + test(); + if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) + { + /* NOTE: this is done to avoid the product to become zero for small non-zero input */ + L_tmp = 1; + move16(); + } + output[i] = L_tmp; + move32(); + } + } + ELSE + { + FOR( i = 0; i < j; i++ ) + { + L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + + test(); + test(); + if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) + { + /* NOTE: this is done to avoid the product to become zero for small non-zero input */ + L_tmp = 1; + move16(); + } + + if ( input[i] < 0 ) + { + L_tmp = L_negate( L_tmp ); + } + output[i] = L_tmp; + move32(); + + L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ + prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ + } + + FOR( ; i < length; i++ ) + { + L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + test(); + test(); + if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) + { + /* NOTE: this is done to avoid the product to become zero for small non-zero input */ + L_tmp = 1; + move16(); + } + + if ( input[i] < 0 ) + { + L_tmp = L_negate( L_tmp ); + } + output[i] = L_tmp; + move32(); + } + } + return prev_scale; +} + + +/*==========================================================================*/ +/* FUNCTION : void non_linearity() */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Apply a non linearity to the SHB excitation */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* Word16 input[] i : input signal Q_inp */ +/* Word16 length i : input length */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* Word32 output[] o : output signal 2*Q_inp */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Word32 *prev_scale i/o: memory Q30 */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ + +void non_linearity_fx( + const Word16 input[], /* i : input signal Q_inp */ + Word32 output[], /* o : output signal 2*Q_inp */ + const Word16 length, /* i : input length */ + Word32 *pPrevScale, /* i/o: memory Q30 */ + Word16 Q_inp, + Word16 coder_type, /* i : Coder Type */ + Word16 *voice_factors, /* i : Voice Factors */ + const Word16 L_frame /* i : ACELP frame length */ + +) +{ + Word16 i, j; + Word16 max_val = 0; + move16(); + Word32 scale; + Word16 scale_step; + Word16 exp, tmp; + Word16 e_tmp, f_tmp; + Word16 frac; + Word32 L_tmp; + Word32 L_tmp1; + + Word16 en_abs = 0; + Word16 v_fac = 0; + move16(); + move16(); + Word16 ths; + Word16 nframes; + Word32 prev_scale; + Word16 length_half; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + nframes = 5; + move16(); + ths = 17817; + move16(); /* 0.87*5 in Q12 */ + } + ELSE + { + nframes = 4; + move16(); + ths = 15400; + move16(); /* 0.94*4 in Q12 */ + } + + + FOR( i = 0; i < nframes; i++ ) + { + v_fac = add( v_fac, shr( voice_factors[i], 3 ) ); /* Q12 */ + } + + test(); + if ( EQ_16( coder_type, VOICED ) && GT_16( v_fac, ths ) ) + { + en_abs = 1; + move16(); + } + + length_half = shr( length, 1 ); + prev_scale = *pPrevScale; + move32(); + + + /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ + + FOR( i = j = 0; i < length_half; i++ ) + { + tmp = abs_s( input[i] ); + if ( GT_16( tmp, max_val ) ) + { + j = i; + move16(); + } + max_val = s_max( max_val, tmp ); + } + + + IF( GT_16( max_val, shl( 1, Q_inp ) ) ) + { + exp = norm_s( max_val ); + tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ + scale = L_shl( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ) ); /* Q31 */ + } + ELSE + { + scale = 1438814044; + move32(); /* Q31; 0.67 in Q31 */ + } + + test(); + IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 32 ), scale ) ) + { + scale_step = 16384; + move16(); /* Q14 */ + prev_scale = L_shr( scale, 1 ); /* Q30 */ + } + ELSE + { + + /* Computing log2(scale) */ + IF( j == 0 ) + { + scale_step = 32767; + move16(); + } + ELSE + { + e_tmp = norm_l( scale ); + f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); + e_tmp = sub( -1, e_tmp ); + L_tmp = Mpy_32_16( e_tmp, f_tmp, MAX_16 ); /* Q16 */ + + /* Computing log2(prev_scale) */ + e_tmp = norm_l( prev_scale ); + f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); + e_tmp = negate( e_tmp ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, MAX_16 ); /* Q16 */ + + /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ + L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ + + /* Computing 1/j */ + exp = norm_s( j ); + tmp = div_s( shl( 1, sub( 14, exp ) ), j ); /* Q(29-exp) */ + + /* (log2(scale / prev_scale))/length */ + L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ + + frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ + + tmp = extract_l( Pow2( 14, frac ) ); + scale_step = shl_o( tmp, exp, &Overflow ); /* Q14 */ + } + } + + prev_scale = non_linearity_scaled_copy( input, j, length_half, output, prev_scale, scale_step, en_abs ); + + max_val = 0; + move16(); + j = shr( length, 1 ); + FOR( i = length_half; i < length; i++ ) + { + tmp = abs_s( input[i] ); + if ( GT_16( tmp, max_val ) ) + { + j = i; + move16(); + } + max_val = s_max( max_val, tmp ); + } + + IF( GT_16( max_val, shl( 1, Q_inp ) ) ) + { + exp = norm_s( max_val ); + tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ + scale = L_shl_o( L_mult( 21955 /* 0.67 in Q15 */, tmp ), add( exp, sub( Q_inp, 14 ) ), &Overflow ); /* Q31 */ + } + ELSE + { + scale = 1438814044; + move32(); /* Q31; 0.67 in Q31 */ + } + + test(); + IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 32 ), scale ) ) + { + scale_step = 16384; + move16(); /*Q14 */ + prev_scale = L_shr( scale, 1 ); /*Q30 */ + } + ELSE + { + /*scale_step = (float) exp(1.0f / (float) (j - length/2) * (float) log(scale / prev_scale)); */ + /* Computing log2(scale) */ + IF( EQ_16( j, length_half ) ) + { + scale_step = 32767; + move16(); /*Q14 */ + } + ELSE + { + e_tmp = norm_l( scale ); + f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); + e_tmp = sub( -e_tmp, 1 ); + L_tmp = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ + + /* Computing log2(prev_scale) */ + e_tmp = norm_l( prev_scale ); + f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); + e_tmp = negate( e_tmp ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ + + /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ + L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ + + /* Computing 1/(j - length/2) */ + + tmp = sub( j, length_half ); + exp = norm_s( tmp ); + + + tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* Q(29-exp) */ + + /* (log2(scale / prev_scale))/length */ + L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ + + frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ + + tmp = extract_l( Pow2( 14, frac ) ); + scale_step = shl_o( tmp, exp, &Overflow ); /*Q14 */ + } + } + + prev_scale = non_linearity_scaled_copy( input + length_half, sub( j, length_half ), sub( length, length_half ), output + length_half, prev_scale, scale_step, en_abs ); + + *pPrevScale = prev_scale; + move32(); + + /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ + + return; +} + + +/*==========================================================================*/ +/* FUNCTION : void non_linearity_ivas_fx() */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Apply a non linearity to the SHB excitation */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* Word16 input[] i : input signal Q_inp */ +/* Word16 length i : input length */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* Word32 output[] o : output signal 2*Q_inp */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Word32 *prev_scale i/o: memory Q30 */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ + +void non_linearity_ivas_fx( + const Word16 input[], /* i : input signal Q_inp */ + Word32 output[], /* o : output signal 2*Q_inp */ + const Word16 length, /* i : input length */ + Word32 *pPrevScale, /* i/o: memory Q30 */ + Word16 Q_inp, + Word16 coder_type, /* i : Coder Type */ + Word16 *voice_factors, /* i : Voice Factors */ + const Word16 L_frame /* i : ACELP frame length */ + +) +{ + Word16 i, j; + Word16 max_val = 0; + move16(); + Word32 scale; + Word16 scale_step; + Word16 exp, tmp; + Word16 e_tmp, f_tmp; + Word16 frac; + Word32 L_tmp; + Word32 L_tmp1; + + Word16 en_abs = 0; + Word16 v_fac = 0; + move16(); + move16(); + Word16 ths; + Word16 nframes; + Word32 prev_scale; + Word16 length_half; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + nframes = 5; + move16(); + ths = 17817; + move16(); /* 0.87*5 in Q12 */ + } + ELSE + { + nframes = 4; + move16(); + ths = 15400; + move16(); /* 0.94*4 in Q12 */ + } + + + FOR( i = 0; i < nframes; i++ ) + { + v_fac = add( v_fac, shr( voice_factors[i], 3 ) ); /* Q12 */ + } + + test(); + if ( EQ_16( coder_type, VOICED ) && GT_16( v_fac, ths ) ) + { + en_abs = 1; + move16(); + } + + length_half = shr( length, 1 ); + prev_scale = *pPrevScale; + move32(); + + + /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ + + FOR( i = j = 0; i < length_half; i++ ) + { + tmp = abs_s( input[i] ); + if ( GT_16( tmp, max_val ) ) + { + j = i; + move16(); + } + max_val = s_max( max_val, tmp ); + } + + + IF( GT_16( max_val, shl( 1, Q_inp ) ) ) + { + exp = norm_s( max_val ); + tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ + scale = L_shl( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ) ); /* Q31 */ + } + ELSE + { + scale = 1438814044; + move32(); /* Q31; 0.67 in Q31 */ + } + + test(); + IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 64 ) /*Q30 -> Q31*/, scale /*Q31*/ ) ) + { + scale_step = 16384; + move16(); /* Q14 */ + prev_scale = L_shr( scale, 1 ); /* Q30 */ + } + ELSE + { + + /* Computing log2(scale) */ + IF( j == 0 ) + { + scale_step = 32767; + move16(); + } + ELSE + { + e_tmp = norm_l( scale ); + f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); + e_tmp = sub( -1, e_tmp ); + L_tmp = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ + + /* Computing log2(prev_scale) */ + e_tmp = norm_l( prev_scale ); + f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); + e_tmp = negate( e_tmp ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ + + /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ + L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ + + /* Computing 1/j */ + exp = norm_s( j ); + tmp = div_s( shl( 1, sub( 14, exp ) ), j ); /* Q(29-exp) */ + + /* (log2(scale / prev_scale))/length */ + L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ + + frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ + + tmp = extract_l( Pow2( 14, frac ) ); + scale_step = shl_o( tmp, exp, &Overflow ); /* Q14 */ + } + } + + prev_scale = non_linearity_scaled_copy_ivas( input, j, length_half, output, prev_scale, scale_step, en_abs ); + + max_val = 0; + move16(); + j = shr( length, 1 ); + FOR( i = length_half; i < length; i++ ) + { + tmp = abs_s( input[i] ); + if ( GT_16( tmp, max_val ) ) + { + j = i; + move16(); + } + max_val = s_max( max_val, tmp ); + } + + IF( GT_16( max_val, shl( 1, Q_inp ) ) ) + { + exp = norm_s( max_val ); + tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ + scale = L_shl_o( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ), &Overflow ); /* Q31 */ + } + ELSE + { + scale = 1438814044; + move32(); /* Q31; 0.67 in Q31 */ + } + + test(); + IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 64 ), scale ) ) + { + scale_step = 16384; + move16(); /*Q14 */ + prev_scale = L_shr( scale, 1 ); /*Q30 */ + } + ELSE + { + /*scale_step = (float) exp(1.0f / (float) (j - length/2) * (float) log(scale / prev_scale)); */ + /* Computing log2(scale) */ + IF( EQ_16( j, length_half ) ) + { + scale_step = 32767; + move16(); /*Q14 */ + } + ELSE + { + e_tmp = norm_l( scale ); + f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); + e_tmp = sub( -e_tmp, 1 ); + L_tmp = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ + + /* Computing log2(prev_scale) */ + e_tmp = norm_l( prev_scale ); + f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); + e_tmp = negate( e_tmp ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ + + /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ + L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ + + /* Computing 1/(j - length/2) */ + + tmp = sub( j, length_half ); + exp = norm_s( tmp ); + + + tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* Q(29-exp) */ + + /* (log2(scale / prev_scale))/length */ + L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ + + frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ + + tmp = extract_l( Pow2( 14, frac ) ); + scale_step = shl_o( tmp, exp, &Overflow ); /*Q14 */ + } + } + + prev_scale = non_linearity_scaled_copy_ivas( input + length_half, sub( j, length_half ), sub( length, length_half ), output + length_half, prev_scale, scale_step, en_abs ); + + *pPrevScale = prev_scale; + move32(); + + /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ + + return; +} + + +/*-------------------------------------------------------------------* + * create_random_vector() + * + * creates random number vector + * Note: the abs(max_val) value coming out of create_random_vector should + * fit into the precision of Q6. + * -------------------------------------------------------------------*/ + +void create_random_vector_fx( + Word16 output[], /* o : output random vector Q5*/ + const Word16 length, /* i : length of random vector */ + Word16 seed[] /* i/o: start seed */ +) +{ + Word16 i, j, k; + Word16 scale1, scale2; + Word32 L_tmp; + + L_tmp = L_abs( Mult_32_16( 2144047674, Random( &seed[0] ) ) ); /*Q23 */ + j = extract_l( L_shr( L_tmp, 23 ) ); + j = s_and( j, 0xff ); + + L_tmp = L_abs( Mult_32_16( 2144047674, Random( &seed[1] ) ) ); /*Q23 */ + k = extract_l( L_shr( L_tmp, 23 ) ); + k = s_and( k, 0xff ); + + WHILE( EQ_16( k, j ) ) + { + L_tmp = L_abs( Mult_32_16( 2144047674, Random( &seed[1] ) ) ); /*Q23 */ + k = extract_l( L_shr( L_tmp, 23 ) ); + k = s_and( k, 0xff ); + } + + scale1 = 18021; + move16(); /* 200.00f * 0.35f/0.1243f; */ + if ( Random( &seed[0] ) < 0 ) + { + scale1 = -18021; + move16(); /*Q5 */ /* -200.00f * 0.35f/0.1243f; */ + } + + scale2 = 7208; + move16(); /* 80.00f * 0.35f/0.1243f; */ + if ( Random( &seed[1] ) < 0 ) + { + scale2 = -7208; + move16(); /*Q5 */ /* -80.00f * 0.35f/0.1243f; */ + } + + FOR( i = 0; i < length; i++ ) + { + j = s_and( j, 0xff ); + k = s_and( k, 0xff ); + output[i] = round_fx( L_add( L_mult( scale1, gaus_dico_swb_fx[j] ), L_mult( scale2, gaus_dico_swb_fx[k] ) ) ); /*Q5 */ + move16(); + j++; + k++; + } + + return; +} + + +/*======================================================================================*/ +/* FUNCTION : interp_code_5over2_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Used to interpolate the excitation from the core sample rate */ +/* of 12.8 kHz to 32 kHz. */ +/* Simple linear interpolator - No need FOR precision here. */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16[]) inp_code_fx : input vector (Q12) */ +/* _ (Word16) inp_length : length of input vector */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) interp_code_fx : output vector (Q12) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ + +void interp_code_5over2_fx( + const Word16 inp_code_fx[], /* i : input vector Qx*/ + Word16 interp_code_fx[], /* o : output vector Qx*/ + const Word16 inp_length /* i : length of input vector */ +) +{ + Word16 i, kk, kkp1, i_len2; + Word32 Ltemp; + Word16 factor_i_fx[5] = { 6554, 19661, 32767, 19661, 6554 }; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + Word16 factor_j_fx[5] = { 26214, 13107, 0, 13107, 26214 }; + move16(); + move16(); + move16(); + move16(); + move16(); + interp_code_fx[0] = inp_code_fx[0]; + move16(); /* Qx */ + + Ltemp = L_mult( inp_code_fx[0], factor_i_fx[3] ); /* Q(16+x) */ + Ltemp = L_mac( Ltemp, inp_code_fx[1], factor_j_fx[3] ); /* Q(16+x) */ + interp_code_fx[1] = round_fx( Ltemp ); /*Qx */ + move16(); + Ltemp = L_mult( inp_code_fx[0], factor_i_fx[4] ); /*Q(16+x) */ + Ltemp = L_mac( Ltemp, inp_code_fx[1], factor_j_fx[4] ); /*Q(16+x) */ + interp_code_fx[2] = round_fx( Ltemp ); /* Qx */ + move16(); + kk = 1; + move16(); + kkp1 = 2; + move16(); + i = 3; + move16(); + /*i_len2 = ( inp_length - 2 ) * HIBND_ACB_L_FAC; */ /*HIBND_ACB_L_FAC == 5/2 */ + i_len2 = sub( inp_length, 2 ); + i_len2 = shr( add( shl( i_len2, 2 ), i_len2 ), 1 ); /* rounding below during shr makes it non BE*/ + + FOR( ; i < i_len2; i += 5 ) + { + Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[0] ); /*Q(16+x) */ + Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_i_fx[0] ); /*Q(16+x) */ + interp_code_fx[i] = round_fx( Ltemp ); /*Qx */ + move16(); + Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[1] ); /*Q(16+x) */ + Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_i_fx[1] ); /*Q(16+x) */ + interp_code_fx[i + 1] = round_fx( Ltemp ); /*Qx */ + move16(); + Ltemp = L_mult( inp_code_fx[kkp1], factor_i_fx[2] ); /*Q(16+x) */ + interp_code_fx[i + 2] = round_fx( Ltemp ); /*Qx */ + move16(); + kk++; + kkp1++; + + Ltemp = L_mult( inp_code_fx[kk], factor_i_fx[3] ); /*Q(16+x) */ + Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_j_fx[3] ); /*Q(16+x) */ + interp_code_fx[i + 3] = round_fx( Ltemp ); /*Qx */ + move16(); + Ltemp = L_mult( inp_code_fx[kk], factor_i_fx[4] ); /*Q(16+x) */ + Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_j_fx[4] ); /*Q(16+x) */ + interp_code_fx[i + 4] = round_fx( Ltemp ); /*Qx */ + move16(); + kk++; + kkp1++; + } + + Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[0] ); /*Q(16+x) */ + interp_code_fx[i] = round_fx( Ltemp ); /*Qx */ + move16(); + Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[1] ); /*Q(16+x) */ + interp_code_fx[i + 1] = round_fx( Ltemp ); /*Qx */ + move16(); + return; +} + + +/*======================================================================================*/ +/* FUNCTION : interp_code_4over2_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Used to interpolate the excitation from the core sample rate */ +/* of 16 kHz to 32 kHz. */ +/* Simple linear interpolator - No need for precision here. */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16[]) inp_code_fx : input vector (Qx) */ +/* _ (Word16) inp_length : length of input vector */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) interp_code_fx : output vector (Qx) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ + +void interp_code_4over2_fx( + const Word16 inp_code_fx[], /* i : input vector Qx*/ + Word16 interp_code_fx[], /* o : output vector Qx*/ + const Word16 inp_length /* i : length of input vector */ +) +{ + Word16 i, j; + j = 0; + move16(); + FOR( i = 0; i < inp_length - 1; i++ ) + { + interp_code_fx[j] = inp_code_fx[i]; + move16(); /*Qx */ + interp_code_fx[j + 1] = add( shr( inp_code_fx[i], 1 ), shr( inp_code_fx[i + 1], 1 ) ); + move16(); + move16(); /*Qx */ + j = add( j, 2 ); + } + + interp_code_fx[j] = inp_code_fx[i]; + move16(); + interp_code_fx[j + 1] = shr( inp_code_fx[i], 1 ); + move16(); /*Qx */ + + return; +} + + +/*-------------------------------------------------------------------* + * wb_tbe_extras_reset_synth() + * + * Reset the extra parameters only required for WB TBE synthesis + *-------------------------------------------------------------------*/ + +void wb_tbe_extras_reset_synth_fx( + Word16 state_lsyn_filt_shb[], + Word16 state_lsyn_filt_dwn_shb[], + Word16 state_32and48k_WB_upsample[], + Word16 state_resamp_HB[] ) +{ + set16_fx( state_lsyn_filt_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); + set16_fx( state_lsyn_filt_dwn_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); + set16_fx( state_32and48k_WB_upsample, 0, 2 * ALLPASSSECTIONS_STEEP ); + set16_fx( state_resamp_HB, 0, INTERP_3_1_MEM_LEN ); + + return; +} +#if defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 ) && defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 ) +static inline Word64 wmac_1616( Word64 x1, Word16 x2, Word16 x3 ) +{ + return W_mac_16_16( x1, x2, x3 ); +} + +static inline Word64 wmac_3216( Word64 x1, Word32 x2, Word16 x3 ) +{ + return W_mac_32_16( x1, x2, x3 ); +} + +static inline Word64 finalSat16( Word64 W_tmpx, Word64 W_tmpy ) +{ + return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +} + +static inline Word64 finalSat32( Word64 W_tmpx, Word64 W_tmpy ) +{ + return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); +} + +inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *input32_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) +{ + Word32 L_tmpX; + Word16 i; + Word32 L_tmpMax2 = *L_tmpMax; + Word32 L_tmpAbs; + move32(); + + if ( input16_fx > 0 ) + { + Word64 ( *wmac )( Word64, Word16, Word16 ); + Word64 ( *finalSat )( Word64, Word64 ); + Word16 *input_fx = input16_fx; + wmac = wmac_1616; + finalSat = finalSat16; + } + if ( input32_fx > 0 ) + { + Word64 ( *wmac )( Word64, Word32, Word16 ); + Word64 ( *finalSat )( Word64, Word64 ); + Word32 *input_fx = input32_fx; + wmac = wmac_3216; + finalSat = finalSat32; + } + + IF( !IsUpsampled3 ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + } + } /*IsUpsampled3*/ + ELSE + { /*IsUpsampled3*/ + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = wmac( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = wmac( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ + move32(); + if ( *L_tmpMax > 0 ) + { + L_tmpAbs = L_abs( L_tmp[i] ); + } + if ( *L_tmpMax > 0 ) + { + L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); + } + i++; + } + } /*IsUpsampled3*/ + *L_tmpMax = L_tmpMax2; + move32(); +} +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + +/*-------------------------------------------------------------------* + * elliptic_bpf_48k_generic() + * + * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz + * Implemented as 3 fourth order sections cascaded. + *-------------------------------------------------------------------*/ + +void elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + int isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 IsUpsampled3, + Word16 input_fx[], /* i : input signal Q_input_fx*/ +#else + const Word16 input_fx[], /* i : input signal Q_input_fx*/ +#endif + Word16 *Q_input_fx, + Word16 output_fx[], /* o : output signal memory_fx_Q */ + Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ + Word16 memory_fx_Q[], + const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ +) +{ + Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 memory_fx0, Q_temp, Q_temp2; + Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; + Word32 L_tmpMax; + Word32 L_tmpX; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + Word64 W_tmpX; + Word64 W_tmpY; +#endif + + Word32 *L_tmp = &L_tmp_buffer[4]; + Word32 *L_tmp2 = &L_tmp2_buffer[4]; + Word32 *L_output = &L_output_buffer[4]; +#else + Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; + Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; + Word32 memory2_fx_2[4], memory2_fx_3[4]; +#endif + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + FOR( i = 0; i < 4; i++ ) + { + memory_fx0 = extract_l( memory_fx2[0][i] ); + input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); + L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); + } + +#else + FOR( i = 0; i < 4; i++ ) + { + memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); + memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); + memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); + } +#endif + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( input_fx, 0, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + IF( !IsUpsampled3 ) + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } + } + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } + } + } /*IsUpsampled3*/ + ELSE + { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } + } + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } + } + } /*IsUpsampled3*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ + +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + + memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; + memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; + memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; + memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; + move32(); + move32(); + move32(); + move32(); + move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 + elliptic_bpf_48k_generic_func1( 0, L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + } + ELSE +#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } + } + +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ + move32(); + L_tmpMax = L_abs( L_tmp2[0] ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } +#endif + + + Q_temp = norm_l( L_tmpMax ); + Q_temp = sub( Q_temp, 4 ); + Scale_sig32( L_tmp2, 960, Q_temp ); + + memory_fx2[1][0] = L_tmp[L_FRAME48k - 4]; + memory_fx2[1][1] = L_tmp[L_FRAME48k - 3]; + memory_fx2[1][2] = L_tmp[L_FRAME48k - 2]; + memory_fx2[1][3] = L_tmp[L_FRAME48k - 1]; + move32(); + move32(); + move32(); + move32(); + move32(); + +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + FOR( j = 0; j < 4; j++ ) + { + L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + } + + L_tmpMax = L_add( 0, 0 ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ + elliptic_bpf_48k_generic_func1( 0, L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } + } + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } + } + +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ + FOR( j = 0; j < 4; j++ ) + { + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + } + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ + move32(); + L_tmpMax = L_abs( L_output[0] ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ + L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); + + L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); + + FOR( i = 4; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } + +#endif + + + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; + memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; + memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; + memory_fx2[2][3] = L_tmp2[L_FRAME48k - 1]; + memory_fx2[3][0] = L_output[L_FRAME48k - 4]; + memory_fx2[3][1] = L_output[L_FRAME48k - 3]; + memory_fx2[3][2] = L_output[L_FRAME48k - 2]; + memory_fx2[3][3] = L_output[L_FRAME48k - 1]; + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + memory_fx_Q[0] = *Q_input_fx; + memory_fx_Q[1] = add( *Q_input_fx, 11 ); + memory_fx_Q[2] = add( add( *Q_input_fx, 6 ), Q_temp ); + memory_fx_Q[3] = add( add( *Q_input_fx, 1 ), Q_temp ); + move16(); + move16(); + move16(); + move16(); + Q_temp2 = norm_l( L_tmpMax ); + Scale_sig32( L_output, 960, Q_temp2 ); + FOR( i = 0; i < 960; i++ ) + { + output_fx[i] = extract_h( L_output[i] ); + move16(); + } + *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); + move16(); /* BASOP_NOGLOB */ + + return; +} +/*-------------------------------------------------------------------* + * synthesise_fb_high_band() + * + * Creates the highband output for full band - 14.0 to 20 kHz + * Using the energy shaped white excitation signal from the SWB BWE. + * The excitation signal input is sampled at 16kHz and so is upsampled + * to 48 kHz first. + * Uses a complementary split filter to code the two regions from + * 14kHz to 16kHz and 16 kHz to 20 kHz. + * One of 16 tilt filters is also applied afterwards to further + * refine the spectral shape of the fullband signal. + * The tilt is specified in dB per kHz. N.B. Only negative values are + * accomodated. + *-------------------------------------------------------------------*/ + +void synthesise_fb_high_band_fx( + const Word16 excitation_in[], /* i : full band excitation */ + Word16 Q_fb_exc, + Word16 output[], /* o : high band speech - 14.0 to 20 kHz */ + const Word32 fb_exc_energy, /* i : full band excitation energy */ + const Word16 ratio, /* i : energy ratio */ + const Word16 L_frame, /* i : ACELP frame length */ + const Word16 bfi, /* i : fec flag */ + Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ + Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ + Word16 bpf_memory_Q[], + Word16 Qout +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + , + Word16 isIVAS +#endif +) +{ + Word16 i, j; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; + Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; +#else + Word16 excitation_in_interp3[L_FRAME48k]; +#endif + Word16 tmp[L_FRAME48k]; + Word32 temp1; + Word32 ratio2; + Word32 L_tmp; + Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; + + /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ + j = 0; + /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ + FOR( i = 0; i < L_FRAME48k; i += 3 ) + { + excitation_in_interp3[i] = mult( excitation_in[j], 24576 ); /* Q(Q_fb_exc+13-15 = Q_fb_exc-2) */ + move16(); + excitation_in_interp3[i + 1] = 0; + move16(); + excitation_in_interp3[i + 2] = 0; + move16(); + j++; + } + exp_tmp = sub( Q_fb_exc, 2 ); + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + /* for 16kHz ACELP core */ + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx + + ); + } + ELSE + { + /* for 12.8kHz ACELP core */ + elliptic_bpf_48k_generic_fx( +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 + isIVAS, +#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + 1, // IsUpsampled3 +#endif + excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); + } + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ + + push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); + temp1 = sum2_fx_mod( tmp, L_FRAME48k ); + L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ + exp = norm_l( L_tmp ); + tmp3 = extract_h( L_shl( L_tmp, exp ) ); + tmp1 = sub( add( Q_fb_exc, Q_fb_exc ), 8 ); /* 1-9*/ + exp = sub( sub( 31, tmp1 ), exp ); + + exp2 = norm_l( temp1 ); + tmp2 = extract_h( L_shl( temp1, exp2 ) ); + exp2 = sub( sub( 31, sub( shl( exp_tmp, 1 ), 8 ) ), exp2 ); /* in Q15 (temp1 in Q9)*/ + + exp = sub( exp2, exp ); /* Denormalize and substract */ + IF( GT_16( tmp2, tmp3 ) ) + { + tmp2 = shr( tmp2, 1 ); + exp = add( exp, 1 ); + } + IF( 0 != tmp3 ) + { + tmp3 = div_s( tmp2, tmp3 ); + L_tmp = L_deposit_h( tmp3 ); + L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ + ratio2 = Mult_32_16( L_tmp, ratio ); /*Q(31-exp+0-15 = 16-exp)*/ + } + ELSE + { + ratio2 = 0; + } + + IF( !bfi ) + { + *prev_fbbwe_ratio = ratio; + move16(); + } + ELSE + { + /**prev_fbbwe_ratio = ratio*0.5f;*/ + *prev_fbbwe_ratio = shr( ratio, 1 ); + move16(); + } + tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ + IF( L_tmp < 0 ) + { + output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ + move16(); + } + ELSE + { + output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ + move16(); + } + } + pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ + return; +} + +/*-------------------------------------------------------------------* + * Estimate_mix_factors_fx() * + * * + * Estimate mix factors for SHB excitation generation * + *-------------------------------------------------------------------*/ +void Estimate_mix_factors_fx( + const Word16 *shb_res, /* i : SHB LP residual in Q = Q_shb */ + const Word16 Q_shb, + const Word16 *exc16kWhtnd, /* i : SHB transformed low band excitation Q_bwe_exc */ + const Word16 Q_bwe_exc, + const Word16 *White_exc16k_frac, /* i : Modulated envelope shaped white noise Q_frac */ + const Word16 Q_frac, + const Word32 pow1, /* i : SHB exc. power for normalization in Q_pow1 */ + const Word16 Q_pow1, + const Word32 pow22, /* i : White noise excitation for normalization in Q_pow22 */ + const Word16 Q_pow22, + Word16 *vf_modified, /* o : Estimated voice factors */ + Word16 *vf_ind /* o : voice factors VQ index */ +) +{ + Word16 shb_res_local[L_FRAME16k], WN_exc_local[L_FRAME16k]; + Word32 pow3, temp_p1_p2, temp_p1_p3; + Word16 temp_numer1[L_FRAME16k], temp_numer2[L_FRAME16k]; + Word16 i, length; + Word16 exp1, exp2, expa, expb, fraca, fracb, scale, num_flag, den_flag; + Word16 tmp, tmp1, sc1, sc2; + Word32 L_tmp1, L_tmp2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + Copy( shb_res, shb_res_local, L_FRAME16k ); + Copy( White_exc16k_frac, WN_exc_local, L_FRAME16k ); + /* WN_exc_local in (Q_frac) */ + + pow3 = Dot_product( shb_res_local, shb_res_local, L_FRAME16k ); /* (2*Q_shb+1) */ + + pow3 = L_add( pow3, L_shl( 21475l /*0.00001f in Q31*/, 2 * Q_shb + 1 - 31 ) ); /* (2*Q_shb+1) */ + if ( pow3 == 0 ) + { + pow3 = 1; + move32(); + } + + /* temp_p1_p2 = (float)sqrt(pow1/pow2); */ + temp_p1_p2 = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp1 ); /* temp_p1_p3 in (Q31+exp1) */ + + /* temp_p1_p3 = (float)sqrt(pow1/pow3); */ + temp_p1_p3 = root_a_over_b_fx( pow1, Q_pow1, pow3, ( 2 * Q_shb + 1 ), &exp2 ); /* temp_p1_p3 in (Q31+exp2) */ + + + sc1 = sub( Q_bwe_exc, sub( Q_frac, exp1 ) ); + sc2 = sub( Q_bwe_exc, sub( Q_shb, exp2 ) ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp1 = Mult_32_16( temp_p1_p2, WN_exc_local[i] ); /* (Q_frac - exp1) +16 */ + WN_exc_local[i] = round_fx( L_tmp1 ); + move16(); + L_tmp2 = Mult_32_16( temp_p1_p3, shb_res_local[i] ); /* (Q_shb - exp2) +16 */ + shb_res_local[i] = round_fx( L_tmp2 ); + move16(); + /* temp_numer1[i] = sub(shb_res_local[i], WN_exc_local[i]); */ + temp_numer1[i] = round_fx_sat( L_sub_sat( L_shl_sat( L_tmp2, sc2 ), L_shl_sat( L_tmp1, sc1 ) ) ); + move16(); + /* (Q_bwe_exc) */ + + /* temp_numer2[i] = sub(exc16kWhtnd[i], WN_exc_local[i]); */ + temp_numer2[i] = sub_sat( exc16kWhtnd[i], round_fx_sat( L_shl_sat( L_tmp1, sc1 ) ) ); + move16(); + /* (Q_bwe_exc) */ + } + + + length = L_FRAME16k; + move16(); + temp_p1_p2 = Dot_product( temp_numer1, temp_numer2, length ); /* 2*(Q_bwe_exc)+1 */ + temp_p1_p3 = Dot_product( temp_numer2, temp_numer2, length ); /* 2*(Q_bwe_exc)+1 */ + + /* vf_modified[i] = min( max_val( (temp_p1_p2 / temp_p1_p3), 0.1f), 0.99f); */ + /* tmp = (temp_p1_p2 / temp_p1_p3); */ + IF( temp_p1_p3 > 0 ) + { + expa = norm_l( temp_p1_p3 ); + fraca = extract_h( L_shl( temp_p1_p3, expa ) ); + expa = sub( 30, expa ); + + expb = norm_l( temp_p1_p2 ); + fracb = round_fx_o( L_shl_o( temp_p1_p2, expb, &Overflow ), &Overflow ); + expb = sub( 30, expb ); + + num_flag = 0; + move16(); + IF( fraca < 0 ) + { + num_flag = 1; + move16(); + fraca = negate( fraca ); + } + + den_flag = 0; + move16(); + IF( fracb < 0 ) + { + den_flag = 1; + move16(); + fracb = negate( fracb ); + } + + scale = shr( sub( fraca, fracb ), 15 ); + fracb = shl( fracb, scale ); + expb = sub( expb, scale ); + + tmp = div_s( fracb, fraca ); + exp1 = sub( expb, expa ); + tmp = shl_sat( tmp, exp1 ); + if ( NE_16( num_flag, den_flag ) ) + { + tmp = negate( tmp ); + } + } + ELSE + { + tmp = 0; + move16(); + } + + vf_modified[0] = s_min( s_max( tmp, 3277 /* 0.1f in Q15*/ ), 32440 /* 0.99f in Q15 */ ); + move16(); + + *vf_ind = usquant_fx( vf_modified[0], &tmp1, 4096 /* 0.125 in Q15 */, 2048 /* 0.125 in Q14 */, shl( 1, NUM_BITS_SHB_VF ) ); + move16(); + + vf_modified[0] = tmp1; + move16(); + vf_modified[1] = tmp1; + move16(); + vf_modified[2] = tmp1; + move16(); + vf_modified[3] = tmp1; + move16(); + vf_modified[4] = tmp1; + move16(); + + /* vf_modified in Q15 */ + + return; +} +#ifdef ADD_IVAS_TBE_CODE +/*-------------------------------------------------------------------* + * tbe_celp_exc() * + * * + * Prepare adaptive part of TBE excitation * + *-------------------------------------------------------------------*/ + +void tbe_celp_exc( + const int16_t element_mode, /* i : element mode */ + const int16_t idchan, /* i : channel ID */ + float *bwe_exc, /* i/o: BWE excitation */ + const int16_t L_frame, /* i : frame length */ + const int16_t L_subfr, /* i : subframe length */ + const int16_t i_subfr, /* i : subframe index */ + const int16_t T0, /* i : integer pitch lag */ + const int16_t T0_frac, /* i : fraction of lag */ + float *error, /* i/o: error */ + const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ +) +{ + int16_t i, offset; + + if ( element_mode == IVAS_CPE_TD && idchan == 1 && !tdm_LRTD_flag ) + { + return; + } + + if ( L_frame == L_FRAME ) + { + offset = tbe_celp_exc_offset( T0, T0_frac ); + + for ( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc[i + i_subfr * HIBND_ACB_L_FAC - offset + (int16_t) *error]; + } + *error += (float) offset - (float) T0 * HIBND_ACB_L_FAC - 0.25f * HIBND_ACB_L_FAC * (float) T0_frac; + } + else + { + offset = T0 * 2 + (int16_t) ( (float) T0_frac * 0.5f + 4 + 0.5f ) - 4; + for ( i = 0; i < L_subfr * 2; i++ ) + { + bwe_exc[i + i_subfr * 2] = bwe_exc[i + i_subfr * 2 - offset + (int16_t) *error]; + } + *error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac; + } + + return; +} +#endif +/*======================================================================================*/ +/* FUNCTION : prep_tbe_exc_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Prepare TBE excitation */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) L_frame_fx : length of the frame */ +/* _ (Word16) i_subfr_fx : subframe index */ +/* _ (Word16) gain_pit_fx : Pitch gain (14) */ +/* _ (Word32) gain_code_fx : algebraic codebook gain (Q(16+Q_exc)) */ +/* _ (Word16*[]) code_fx : algebraic excitation (Q9) */ +/* _ (Word16) voice_fac_fx : voicing factor (Q15) */ +/* _ (Word16) gain_preQ_fx : prequantizer excitation gain */ +/* _ (Word16[]) code_preQ_fx : prequantizer excitation */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*[]) voice_factors_fx : TBE voicing factor (Q15) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16[]) bwe_exc_fx : excitation for TBE (Q_exc) */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ + +void prep_tbe_exc_fx( + const Word16 L_frame_fx, /* i : length of the frame */ +#ifdef ADD_IVAS_TBE_CODE + const Word16 L_subfr, +#endif + const Word16 i_subfr_fx, /* i : subframe index */ + const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ + const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 voice_fac_fx, /* i : voicing factor Q15*/ + Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ + Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ + const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ + const Word16 code_preQ_fx[], /* i : prequantizer excitation */ + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + Word16 T0, /* i : integer pitch variables Q0 */ + Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + Word32 core_brate +#ifdef ADD_IVAS_TBE_CODE + , /* i : core bitrate */ + const int16_t element_mode, /* i : element mode */ + const int16_t idchan, /* i : channel ID */ + const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ +#endif +) +{ + Word16 i; + Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; + Word16 tmp_code_preInt_fx[L_SUBFR]; + Word16 gain_code16 = 0; + move16(); + Word16 tmp /*, tmp1, tmp2*/; + /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ + Word16 pitch; + + Word32 L_tmp, Ltemp1, Ltemp2; + Word32 tempQ31; + Word16 tempQ15; +#ifndef ADD_IVAS_TBE_CODE + Word16 L_subfr = L_SUBFR; + move16(); +#endif +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + /**voice_factors = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac; + = VF_0th_PARAM + voice_fac * (VF_1st_PARAM + VF_2nd_PARAM * voice_fac ) + *voice_factors = min( max_val(0.0f, *voice_factors), 1.0f); */ + tempQ31 = L_deposit_h( VF_1st_PARAM_FX ); + tempQ15 = mac_r( tempQ31, VF_2nd_PARAM_FX, voice_fac_fx ); + tempQ31 = L_deposit_h( VF_0th_PARAM_FX ); + *voice_factors_fx = mac_r( tempQ31, voice_fac_fx, tempQ15 ); + move16(); + tmp = MAX_16; + move16(); + + pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ + + test(); + test(); + IF( ( ( EQ_16( coder_type, VOICED ) ) || ( GT_16( pitch, 14784 /* 115.5 in Q7 */ ) ) ) && ( GT_32( core_brate, ACELP_8k00 ) ) ) + { + tmp = MAX_16; + move16(); + *voice_factors_fx = mult_r( *voice_factors_fx, tmp ); + move16(); + } + + *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); + move16(); +#ifdef ADD_IVAS_TBE_CODE + IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) + { + IF( flag_TD_BWE && i_subfr == 0 ) + { + set16_fx( bwe_exc, 0, L_FRAME32k ); + } + return; + } + +#endif + IF( EQ_16( L_frame_fx, L_FRAME ) ) + { + interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ + gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ + FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) + { + L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ + L_tmp = L_shl_sat( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ + L_tmp = L_mac_sat( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ + move16(); + } + } + ELSE + { + IF( gain_preQ_fx != 0 ) + { + FOR( i = 0; i < L_subfr; i++ ) + { + /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ + Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ + + Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ + Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, 4 ) /*Q_exc+16-13*/, &Overflow ); /*Q_exc+16 */ + + tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ + move16(); + } + } + ELSE + { + FOR( i = 0; i < L_subfr; i++ ) + { + /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ + Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ + tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ + move16(); + } + } + + interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ + FOR( i = 0; i < L_subfr * 2; i++ ) + { + L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * 2] ); /*Q14+Q_exc+1 */ + tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ + bwe_exc_fx[i + i_subfr_fx * 2] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ + move16(); + } + } + + return; +} + +/*======================================================================================*/ +/* FUNCTION : prep_tbe_exc_ivas_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Prepare TBE excitation */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) L_frame_fx : length of the frame */ +/* _ (Word16) i_subfr_fx : subframe index */ +/* _ (Word16) gain_pit_fx : Pitch gain (14) */ +/* _ (Word32) gain_code_fx : algebraic codebook gain (Q(16+Q_exc)) */ +/* _ (Word16*[]) code_fx : algebraic excitation (Q9) */ +/* _ (Word16) voice_fac_fx : voicing factor (Q15) */ +/* _ (Word16) gain_preQ_fx : prequantizer excitation gain */ +/* _ (Word16[]) code_preQ_fx : prequantizer excitation */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*[]) voice_factors_fx : TBE voicing factor (Q15) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16[]) bwe_exc_fx : excitation for TBE (Q_exc) */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ + +void prep_tbe_exc_ivas_fx( + const Word16 L_frame_fx, /* i : length of the frame */ +#if 1 // def ADD_IVAS_TBE_CODE + const Word16 L_subfr, +#endif + const Word16 i_subfr_fx, /* i : subframe index */ + const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ + const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 voice_fac_fx, /* i : voicing factor Q15*/ + Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ + Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ + const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ + const Word16 code_preQ_fx[], /* i : prequantizer excitation */ + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + Word16 T0, /* i : integer pitch variables Q0 */ + Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + Word32 core_brate +#if 1 // def ADD_IVAS_TBE_CODE + , /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +#endif +) +{ + Word16 i; + Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; + Word16 tmp_code_preInt_fx[L_SUBFR]; + Word16 gain_code16 = 0; + move16(); + Word16 tmp /*, tmp1, tmp2*/; + /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ + Word16 pitch; + + Word32 L_tmp, Ltemp1, Ltemp2; + Word32 tempQ31; + Word16 tempQ15; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + /**voice_factors = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac; + = VF_0th_PARAM + voice_fac * (VF_1st_PARAM + VF_2nd_PARAM * voice_fac ) + *voice_factors = min( max_val(0.0f, *voice_factors), 1.0f); */ + tempQ31 = L_deposit_h( VF_1st_PARAM_FX ); + tempQ15 = mac_r( tempQ31, VF_2nd_PARAM_FX, voice_fac_fx ); + tempQ31 = L_deposit_h( VF_0th_PARAM_FX ); + *voice_factors_fx = mac_r( tempQ31, voice_fac_fx, tempQ15 ); + move16(); + + tmp = MAX_16; + move16(); + + pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ + + test(); + test(); + IF( ( ( EQ_16( coder_type, VOICED ) ) || ( GT_16( pitch, 14784 ) ) ) && ( GT_32( core_brate, ACELP_8k00 ) ) ) + { + tmp = MAX_16; + move16(); + *voice_factors_fx = mult_r( *voice_factors_fx, tmp ); + move16(); + } + + *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); + move16(); +#if 1 // def ADD_IVAS_TBE_CODE + test(); + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) + { + test(); + IF( flag_TD_BWE && i_subfr_fx == 0 ) + { + set16_fx( bwe_exc_fx, 0, L_FRAME32k ); + } + return; + } + +#endif + IF( EQ_16( L_frame_fx, L_FRAME ) ) + { + interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ + gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ + FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) + { + L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ + L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ + L_tmp = L_mac_o( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC], &Overflow ); /*Q15+Q_exc */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ + move16(); + } + } + ELSE + { + Word16 shift = 4; + move16(); + IF( gain_preQ_fx != 0 ) + { + FOR( i = 0; i < L_subfr; i++ ) + { + /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ + Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ + + Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ + Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, shift ) /*Q_exc+ 2 + 6 (or) 10 - 13*/, &Overflow ); /*Q_exc+16 */ + + tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ + move16(); + } + } + ELSE + { + FOR( i = 0; i < L_subfr; i++ ) + { + /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ + Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ + tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ + move16(); + } + } + + interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ + FOR( i = 0; i < shl( L_subfr, 1 ); i++ ) + { + L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + shl( i_subfr_fx, 1 )] ); /*Q14+Q_exc+1 */ + tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ + bwe_exc_fx[i + shl( i_subfr_fx, 1 )] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ + move16(); + } + } + + return; +} + +/*=============================================================================*/ +/* FUNCTION : void swb_formant_fac_fx ( ) */ +/*------------------------------------------------------------------------------*/ +/* PURPOSE : * Find strength of adaptive formant postfilter using tilt */ +/* of the high band. The 2nd lpc coefficient is used as a tilt approximation. */ +/*------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* const Word16 lpc_shb2 : 2nd HB LPC coefficient Q12 */ +/*------------------------------------------------------------------------------*/ +/*INPUT/OUTPUT ARGUMENTS : */ +/* Word16 *tilt_mem Q12 */ +/* OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* formant_fac :Formant filter strength [0,1] Q15 */ +/*------------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==============================================================================*/ + +Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ + const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ + Word16 *tilt_mem /* i/o: Tilt smoothing memory (Q12) */ +) +{ + Word16 formant_fac; + Word16 tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /* Smoothen tilt value */ + /* tmp = 0.5f * (float)fabs(lpc_shb2) + 0.5f * *tilt_mem; */ + tmp = mult_r( 16384, abs_s( lpc_shb2 ) ); + tmp = add( tmp, mult_r( 16384, *tilt_mem ) ); /* Q12 */ + *tilt_mem = tmp; + move16(); /*Q12 */ + /* Map to PF strength */ + /* formant_fac = (tmp - SWB_TILT_LOW)*SWB_TILT_DELTA; */ + tmp = sub( tmp, SWB_TILT_LOW_FX ); /* Q12 */ + formant_fac = mult_r( tmp, SWB_TILT_DELTA_FX ); /* Q12 */ + + + IF( GT_16( formant_fac, 4096 /* 1 in Q12 */ ) ) + { + formant_fac = 4096; /* 1 in Q12 */ + move16(); + } + ELSE IF( formant_fac < 0 ) + { + formant_fac = 0; + move16(); + } + /* now formant_fac in Q12 */ + + /* formant_fac = 1.0f - 0.5f*formant_fac */ + tmp = mult_r( 16384, formant_fac ); /* 0.5 in Q15 */ + formant_fac = shl_o( sub( 4096 /* 1 in Q12 */, tmp ), 3, &Overflow ); + return formant_fac; /*Q15 */ +} + + +void wb_tbe_extras_reset_fx( + Word16 mem_genSHBexc_filt_down_wb2[], + Word16 mem_genSHBexc_filt_down_wb3[] ) +{ + set16_fx( mem_genSHBexc_filt_down_wb2, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); + set16_fx( mem_genSHBexc_filt_down_wb3, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); + + return; +} + +/*-------------------------------------------------------------------* + * get_tbe_bits() * + * * + * Determine TBE bit consumption per frame from bitrate * + *-------------------------------------------------------------------*/ + + +Word16 get_tbe_bits_fx( + const Word32 total_brate, /* o : TBE bit consumption per frame */ + const Word16 bwidth, /* i : overall bitrate */ + const Word16 rf_mode /* i : bandwidht mode */ +) +{ + Word16 i, bits = 0; + + IF( EQ_16( rf_mode, 1 ) ) + { + /* TBE bits for core, primary frame */ + test(); + test(); + IF( ( EQ_16( bwidth, WB ) ) && ( EQ_32( total_brate, ACELP_13k20 ) ) ) + { + /* Gain frame: 4, Gain shapes: 0, and LSFs: 2 */ + bits = NUM_BITS_SHB_FrameGain_LBR_WB + NUM_BITS_LBR_WB_LSF; + move16(); + } + ELSE IF( ( EQ_16( bwidth, SWB ) ) && ( EQ_32( total_brate, ACELP_13k20 ) ) ) + { + /* Gain frame: 5, Gain shapes: 5, and lowrate LSFs: 8 */ + bits = NUM_BITS_SHB_FRAMEGAIN + NUM_BITS_SHB_SUBGAINS + 8; + move16(); + } + } + ELSE + { + test(); + test(); + IF( ( EQ_16( bwidth, WB ) ) && ( EQ_32( total_brate, ACELP_9k60 ) ) ) + { + bits = NUM_BITS_LBR_WB_LSF + NUM_BITS_SHB_FrameGain_LBR_WB; + move16(); + } + ELSE IF( ( EQ_16( bwidth, SWB ) ) || ( EQ_16( bwidth, FB ) ) ) + { + test(); + IF( EQ_32( total_brate, ACELP_9k60 ) ) + { + bits = NUM_BITS_SHB_FRAMEGAIN + NUM_BITS_SHB_SUBGAINS + 8; + move16(); + } + ELSE IF( ( GE_32( total_brate, ACELP_13k20 ) ) && ( LE_32( total_brate, ACELP_32k ) ) ) + { + bits = NUM_BITS_SHB_SUBGAINS + NUM_BITS_SHB_FRAMEGAIN + NUM_LSF_GRID_BITS + MIRROR_POINT_BITS; + move16(); + + FOR( i = 0; i < NUM_Q_LSF; i++ ) + { + bits = add( bits, lsf_q_num_bits[i] ); + } + } + + if ( GE_32( total_brate, ACELP_24k40 ) ) + { + bits = add( bits, NUM_BITS_SHB_ENER_SF + NUM_BITS_SHB_VF + NUM_BITS_SHB_RES_GS * NB_SUBFR16k ); + } + + test(); + test(); + if ( EQ_16( bwidth, SWB ) && ( EQ_32( total_brate, ACELP_16k40 ) || EQ_32( total_brate, ACELP_24k40 ) ) ) + { + bits = add( bits, BITS_TEC + BITS_TFA ); + } + + if ( EQ_16( bwidth, FB ) ) + { + /* full band slope */ + bits = add( bits, 4 ); + } + } + } + + return bits; +} -- GitLab From e4e0064ef0d988798e8245771382c9311a6caf5e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 10:35:56 +0200 Subject: [PATCH 1030/1221] clang patch --- lib_com/prot_fx.h | 7 ++++--- lib_com/swb_tbe_com_fx.c | 7 ++++--- lib_dec/swb_tbe_dec_fx.c | 13 ++++++++----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 018e3ef93..a1e5d0cdb 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3292,10 +3292,11 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout + Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , Word16 isIVAS -#endif + , + Word16 isIVAS +#endif ); void prep_tbe_exc_fx( diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 1e806bd6a..c41aaf6d0 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7371,7 +7371,7 @@ void elliptic_bpf_48k_generic_fx( return; } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW*/ void elliptic_bpf_48k_generic_fx( const Word16 input_fx[], /* i : input signal Q_input_fx*/ Word16 *Q_input_fx, @@ -7675,9 +7675,10 @@ void synthesise_fb_high_band_fx( Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ Word16 bpf_memory_Q[], - Word16 Qout + Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , Word16 isIVAS + , + Word16 isIVAS #endif ) { diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index c31008f5f..e910e5457 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4644,12 +4644,14 @@ void fb_tbe_dec_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS - , 1 + , + 1 #else - , 0 + , + 0 #endif #endif ); @@ -4721,9 +4723,10 @@ void fb_tbe_dec_ivas_fx( fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* FB TBE synthesis */ - synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp + synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , 1 + , + 1 #endif ); -- GitLab From b6b5040636092a7de548d90ae804374190e3d779 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:08:02 +0200 Subject: [PATCH 1031/1221] fix FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW --- lib_com/prot_fx.h | 11 +++++++++++ lib_com/swb_tbe_com_fx.c | 8 ++++++++ lib_enc/swb_tbe_enc_fx.c | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index a1e5d0cdb..07ef34533 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3264,6 +3264,7 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word16 isIVAS, @@ -3280,6 +3281,16 @@ void elliptic_bpf_48k_generic_fx( Word16 memory_fx_Q[], const Word16 full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ); +#else +void elliptic_bpf_48k_generic_fx( + const Word16 input_fx[], /* i : i signal Q_input_fx */ + Word16 *Q_input_fx, + Word16 output_fx[], /* o : output signal */ + Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ + Word16 memory_fx_Q[], + const Word16 full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ +); +#endif void synthesise_fb_high_band_fx( const Word16 excitation_in[], /* i : full band excitation */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c41aaf6d0..e6d579269 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7713,6 +7713,7 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS @@ -7723,10 +7724,14 @@ void synthesise_fb_high_band_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); +#else + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); +#endif } ELSE { /* for 12.8kHz ACELP core */ +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS @@ -7735,6 +7740,9 @@ void synthesise_fb_high_band_fx( 1, // IsUpsampled3 #endif excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); +#else + elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); +#endif } temp1 = sum2_fx_mod( tmp, L_FRAME48k ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 30be6bedc..2987fb0cd 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,6 +7330,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS @@ -7342,6 +7343,9 @@ void fb_tbe_enc_fx( 0, // IsUpsampled3 #endif input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#else + elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#endif Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7470,6 +7474,7 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS @@ -7478,9 +7483,13 @@ void fb_tbe_enc_ivas_fx( 0, // IsUpsampled3 #endif input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#else + elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#endif } ELSE { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS @@ -7489,6 +7498,9 @@ void fb_tbe_enc_ivas_fx( 0, // IsUpsampled3 #endif input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#else + elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); +#endif } test(); -- GitLab From 5e7a155cd5eb3064a7187bfa9c6c092f4621d162 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:12:03 +0200 Subject: [PATCH 1032/1221] clang patch --- lib_enc/swb_tbe_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 2987fb0cd..648387bbf 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,7 +7330,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS -- GitLab From c9120743cda4609291d5d55a72d7538d5808c506 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:16:33 +0200 Subject: [PATCH 1033/1221] Revert "deactivate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW to test old bpf" This reverts commit a92d246a5f8be1868eb1bf99fd1264670041c5d8. --- .vs/IVAS_BASOP/v17/.wsuo | Bin 29696 -> 0 bytes .vs/IVAS_BASOP/v17/DocumentLayout.json | 59 - .vs/VSWorkspaceState.json | 7 - IVAS_cod.exe | Bin 6157824 -> 0 bytes Workspace_msvc/decoder.vcxproj | 344 +- Workspace_msvc/encoder.vcxproj | 354 +- Workspace_msvc/lib_com.vcxproj | 680 +- Workspace_msvc/lib_debug.vcxproj | 240 +- Workspace_msvc/lib_dec.vcxproj | 710 +- Workspace_msvc/lib_enc.vcxproj | 742 +-- Workspace_msvc/lib_rend.vcxproj | 414 +- Workspace_msvc/lib_util.vcxproj | 312 +- Workspace_msvc/renderer.vcxproj | 358 +- lib_com/options.h | 2 +- lib_com/swb_tbe_com_fx.c.bak | 8216 ------------------------ 15 files changed, 2078 insertions(+), 10360 deletions(-) delete mode 100644 .vs/IVAS_BASOP/v17/.wsuo delete mode 100644 .vs/IVAS_BASOP/v17/DocumentLayout.json delete mode 100644 .vs/VSWorkspaceState.json delete mode 100644 IVAS_cod.exe delete mode 100644 lib_com/swb_tbe_com_fx.c.bak diff --git a/.vs/IVAS_BASOP/v17/.wsuo b/.vs/IVAS_BASOP/v17/.wsuo deleted file mode 100644 index b5ba4cc2e3848c523ea1f3f0f636f280abb28b55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29696 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 M1Dfdoh($ diff --git a/.vs/IVAS_BASOP/v17/DocumentLayout.json b/.vs/IVAS_BASOP/v17/DocumentLayout.json deleted file mode 100644 index f96d16342..000000000 --- a/.vs/IVAS_BASOP/v17/DocumentLayout.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "Version": 1, - "WorkspaceRootPath": "C:\\work\\IVAS\\src\\IVAS_BASOP\\", - "Documents": [], - "DocumentGroupContainers": [ - { - "Orientation": 0, - "VerticalTabListWidth": 256, - "DocumentGroups": [ - { - "DockedWidth": 200, - "SelectedChildIndex": -1, - "Children": [ - { - "$type": "Bookmark", - "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" - }, - { - "$type": "Bookmark", - "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" - }, - { - "$type": "Bookmark", - "Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}" - }, - { - "$type": "Bookmark", - "Name": "ST:130:0:{1fc202d4-d401-403c-9834-5b218574bb67}" - }, - { - "$type": "Bookmark", - "Name": "ST:132:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" - }, - { - "$type": "Bookmark", - "Name": "ST:131:0:{1fc202d4-d401-403c-9834-5b218574bb67}" - }, - { - "$type": "Bookmark", - "Name": "ST:129:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}" - }, - { - "$type": "Bookmark", - "Name": "ST:134:0:{1fc202d4-d401-403c-9834-5b218574bb67}" - }, - { - "$type": "Bookmark", - "Name": "ST:133:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}" - }, - { - "$type": "Bookmark", - "Name": "ST:128:0:{13b12e3e-c1b4-4539-9371-4fe9a0d523fc}" - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index f874ddaef..000000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ExpandedNodes": [ - "" - ], - "SelectedNode": "\\Workspace_msvc.sln", - "PreviewInSolutionExplorer": false -} \ No newline at end of file diff --git a/IVAS_cod.exe b/IVAS_cod.exe deleted file mode 100644 index aa3ccb696899271daeb2cd4ae2c93d36f6022116..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6157824 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�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 z475h%0Dp@jSPar;2Z;r}Uox}u^GlY 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

tTOAd;h)={4I6pDFST6O1o) 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

(A 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%0AstsC6c5O`M@- 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%0A1RA`R`UPm6BL8+!|M33| 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

%zj^Ua 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%0DW6W9O$e_`|%($0sJE-xnM!aa-8MFJH^pnEMr z13JA^LFE<6U8ExtAQxbEk$Pr;y#g(W=Dnd(7YXFUpx#!68{jJzK|vG<3)reTs9hv* zPYD{Z|E7aogPi$hLxiB|_U~&@dtLkuO3+2*K!Xm_MS>;|CzvR#izM(G(nW%=3xITy zdRRei8nEEOM+`e4y`vUUkl>3xPz}}j8dOfgoA9r)p|hmAdMThT5?D(B|9*(<_9?!gpbL627u;uL z33#yt+IEL1=xhP^pkMrZ1?eJz$4QzG6$JIRg4`X@-3#(;U^i4eFQ~Uw0+Js=HF03? zR8Y+v1nD9{t3>BDkS-ED^&&}0Xi+J_WrFAl$i zc8m@L;OxVI)Afs!a-gh*+%ZD#!$51Ambc(K5Y#d11r-^ zrcvMveTbouXin<}2PL>;bnOKsgFv%FdL}g3OJbpe$Gs?Hul(D=gP5>lu(ubK_yS)v z><1Nr68ziYDLifpG@!scA_M}VroGta0-9Fffwnb7z^x#d+^vrwQ#imww4eban7ETJ zC`5Q5YYG!;;u&5f7$J4v9vgwWZ=j~9^_v&Vj3C{&vTU|Y(|5jd)=)dLHBl>U2^@#pkL_MPa=2egAzd6?<`fnEXi2j>yJ)-}n zU61I$sn#R^^{ z0IJMEeWb&6@eH7r0EoT5E}j9D-azbSb@2?Kj1OYZsEcO+WpNO@t1g}aR6Ky#jdhSd z9>~n9Iz+#&xGtUnlrj@I85q*);u%0G1jG)ni)R2;NT7bBcU?RKsHy_7?d#$hKurfw zUs0zno&i)wg3MQ`i--5!kh)r+ZWZWgb6DRA#D;aBKx}vq3exF;aY3CIPe10)z6@!8t)7_qwdOZG$6ddGI+w>?e?X`|APUs&>&OA0%=D)l z)c!lLwEEb5xHi0jylc8mIscHr&!-0GVs{Wc&VB);pz8uY! zE)4vwPZ_{R9r15(Vlsq;T=zs!fbwr|s^Mo~2zVj)4_v8%7VLn%k1PpU*k98J_vecT zU_V38I|QAg49Y}D2qX}#oM7u4L_Js)TpkUn|m;?$TNG$#7ZSew` z1diSPfl2V#=@khKdhy*EWV!%Y5ah(PZqSvF6G47>Vg2|2{|VsG=>R1UaBOaG0ws@t z7x}$l$AgkbmIKVr7m*NA$hbR4_rx#g=>;SJPA~5@K=$%LVhD5t8#LwoVMTT8pWdDT zkVxQ*y$~H)EZ_tS>M;LKgvLur8a#+Wv%yVy;1J}1#0YGsDoCb54BfsQjR$+cN#m3n zI1sZ0xo+g1XhCXp@cCC9I17RwAbYlB76h%` zu$TtV--D7-_e4-;MkFzg?k11`IAX;hR`YKU{R2|a-2o~hz)1&I5P$^0x%4%}`N&~_ zQV`tk0o#mH5Pa_fi=}~A6Tqwh<$Dw>KmuSZIv`dw*ZyEAsQ_C9&h_Rfv9uT-*7Dt< z9L-fO3?*WaVqw3BP2h_bm~@F5IEb8*Kw-cS&PqRE$rB_4^B_1ZKqVa)#CDLq+b4pu z5GX|Ww|9WDP~Zz4gjcd0K>D{kB?Y_?gNX8PKLPSlcM~YbAnfDl?f?mZv+f#INF;;& zrU_bF5zy`X16pc;i~~F8NADCzQ2q&eQ43N2qV(tg|1SzaMD|b6VeuUN`#sWHPr_0z zw8^g@4^4k1pp*-qyUz%E5g7*+EmZ-P3;R33#rMe)*DNNGjoY0>0$!NH)RdqnS7{Zn zgE5oqBZx%v5f1A&FH|)k$rZF8Wrv0Y1H+5M8sPEJ8_)m$-^s;>WjqvIda;12v)(7q z|NjS-+f580ZtDXO7qnhv3IhW}=hQnOt}913r0(klnFw{wEfxlbpkCK20o|aE(8D-+ zhUOyz;5j3R$C3hG#Kb~9Um}^&V8_6aCD7};Ca^d3O3;giQ^D$A3uOuPx~>W6^}Q1K zBG(Hf#`EIqchHDq-^c&|J42Ub3HG+;d<2ar^@7|I_~N-TI80!cbo(v=&(*#-4-wB2 z>}~}qM5KTvy*>f=0$;3$$RqS|bWe;h2iML^0$xmn$YwEulU`s_(2M>~aJ~VR%-|vf zl6;r+g6=hJRsy>LT)2dCKq~Ady&;Ydfp*64{%zz8vL=0{KEa_$OLUtKXKwx*M zKu{Lri-up)49!Orn)iZ&n4!c2$skrFgIYn-tZPIdH7LSOAaCt=N}8#C=;Duy542AN zzSs|O7y33P+gMB||qOyIBsWrn2g&?UVtUJn9ZctI@966glUR^!1J zOvsHINEp3PfvN&sSOltacY$UawJ!#}kcLh89SDFJ(0ot@=01o(Z-}Ex(2K{4knm>& ztNMq0o28gR*5)7ct z%wQX~e*p&!RHC~Vl;P95!Mf5q1G!$5e*w2)L^@mlJcmq``2Kj!4cffde8>T`{Q!z+vCde;{Si>ntO0Q>7EKQBIv~xZg6OKgH3Ecpae1c^=j~a z&5-oOzrAT06Q~ua0SN$5X$~It%02{{feA4Og#!yyz>BgLke5Lxp@WhyQX&S`1|Ww) zQ*du9$UUIJJDI>28{0sdSU@%7i={U}<%|euizO&TKw7|66GwLk#Fmi2e?c$$A!`aC zv6|M|2y!0ybUsLW;@{o@5(#|a4ju*LfOsRV6YPx_MxX!xf1&&N|NksdLy;9!Rzk`+ zO?gPlg)~5ZLCVlI0WSn0;xB%Jr>DT{0K4MM85ptzyInb00}R0VT_EtqOF6K9(5;#r zX`K^_3>X+*90ko?9RSThF}&aeCkz&dt2-OlfEMMkWidcp*LY|HGpMI>L>6Mm0f@4+ z&c+p>b1>4>7#JX)OY5Al2&9wY#m&Ihqdy1-!U|B;?D{e6T3+#X+bL2e{;HJoJMBlrUC9ML~^bR}R)m z44@o24M`BxlHSAs>SQ$_iGteFm%s*OK}4axZTtk98M*ckRLB{DdVf4YFEYa5rR)mO zrXSEATZmsdUaa}||Nkzq05~ymy#THEoB-bI0KN|`^bhnT5zw{Df0};?fOe3BuXp|f z3e0XE--7z-3~8M`0UV$nY%FM%)BaGfVvrTxBB2oZDUKQ-d0Vi&EBK0NP}p~~xI*Mx zygWeivj0E>*c~s$KpXhL&H^pZ_2PH|n!Vit768X7*Ne}fejj)-HrSo6D7Q~H{}kZw z1qDwQ6X@n=(0L>vYXV;AHiGgN2dJn+m2jztNbL6ojWwiows?X31JVv!5zGU2W#Ef< z4G>k^FMtj``2#xe0c39A3s#u+&_5t=ceVtAybIDE`UheAdYJYTpduSd;#eKTT!ii5 z(BS|3|Njdv5Wx!a?Mu*!C(TD#tlzv?DhtVTp!DBd%fZ0k!UQ@933T`t*nUTz7neZ& zzPq4RmY|ah1%h4(2E&uVHU44an4X5YYr8YC+~R^KTCo33~A`2x?5JFlb??t4P3$b1)%L;~P8?`(igts8kp< zwFjC7SOF6%k>3H%l%ObPd?EM;G~EwMWt{;$FPK4n+t>2OCt)u8^!xvRWaW=Q3puUd zyy%kQWB9m7t!B11LA`E8<5V)2@p4wqZ`^eIdT$I{Pp&V zocjMC)UIkg1gar|UR)N37K6R5FHVB`3ZQZdRJjJe*a4Bsa0DFy!q7XF+J=}2X;>dxuf}zO3;f6sDAK~>I}WDGN(b!v?i$jUYpbZ z|9AFETmidlDo8S@yA`CF71TZscwq_A4r&mCeA;*rbgd}V{Ki9|)^X4aQHYxER*;JB zUXbpz?unq*MOtS-&5L88)!=Lp+2#XvkeV?8Je+YG;*9R8V4Yxl)4DrARd-rvR~M-8 z?fm=yKbkbCu21XiS_6{KLX+<90JRu8yEcF%V?p^GRH{wAa|JR}*a~7m7gK_m{QG-B zRP#@^S|k4bU}gOK!HT+j!A{x=@ywJkP{SjwbBf~@kinpN_X)2zK)eL;aQ8$|)1q?% zcx~|$P-X*d0k{JiemwT)|No2*(CI4-y}d6$%kf_@i-MysV+$*E&%sAfq`nmai)Jx{ zyE_*j^!BiVYWcwKsh~91c&LXTRL3oc=mm{rwLZD>|No0LkZqs|!aJZsBm%?(t)oo% z`2YV4FOc0ESirWl&bbGQ`s)x|dV5u_f})=1>i_>QltCj}p&X#%p}S*(8ECC>SDzUJ z!wW8uk*1(>i4oL8+uq~`8a005><2BKN>o8hBYb%RUl_oJgkX(3un8wXCCLj=`2uOD zf`(v)K;54G9Wmw%46P^mTlaw0ID)#NO`sNI>wyxNECG<>?Gp)C>Vo!TR|}evXX!MM36^!Ez)F9}EG0Zm5d?zT<0(+-|Yzyjb1=$t=O&5?L2H6H`_47cy39>P$ zw-sb#K(B8{U~lLR@Tt7rzMwrKBA~u`z>7_>U>iZ9wtwOh8_)=Qi6cteeM8`jTwzH1 zLTS6-2zU_+6NebTA?SrOLnFhJO8ovkS! zL38F1brE27CEl>~p#=7FN0J!>185-)NNLcEqh(-YpjtsH_IH4mfVZA3v4un#$QVdk z2@C^ys@uaL@I_ys97FRF9#EH!e>>RLfEQJ$M)`8^?+2%@)=MRlpu_@I7L2Z}d*TKg z1_u89PHe3QN>sp|6tKW{CeXq(kTU~c$f0TiWhf`R)&nIXV6Q?P7Vx5?JgL;((E%0fZUX6H1vS(V zmNy;(wfllzn2LdnmVm9k2REKt1j}p~7+z$77HoskGt>Z(hJaq*8-Xtx1Q3ZGDv547 zs8Jg9A{?Ty8+4GAwj{_VmW+NTaHo%d`@|lQQ(qkRfF%&A7vB-%Q4G+MZVCt3F?YX# z=LH}k2dPCno4$aijliR+;2E0k4vx*w5Ae#lU1bTaSTm}{65a}1|OhDp1pls-B5b&bD2%PIdy&G_W1zIu)O3B?F z5PwVr`2!>X@hSiIUXVv1MO0Ir83RKA$Ocd?64*NxRC z`a%He-QHfX^a}w~uFh&%tFAjQu!y1yN`1d!>;AdcHJy0S6GXDu^pCr@| zFHS(r2bF@`JF-Bf0RMKd+d)CWzr6!g@&>+`1aTy&?0eA$VMB{g=(sR6@%(ayWh^B~ zNeU`?K?M$|7z%vhjjk0mCF&#-@Zu0$UmSQaA@D_k0GX{q2i#%!k z+nVI9r!jzH^2N#maOi=Qy?6^_gBINMLTv1Wh(R6uS|2veArYWN|9)e;vptl#? z7VVun;U0KNCb%&PDjT+eXY^644oD7ZiU8&GZg7tYv}FvOW;~KWS){uOG<6Zs+Y3!w zpiB+229mh~vlw1{h+$)BJ_0(Q)&#Va)c{m5c25M2Z-Pg_p#=aqc)>=&0}0xH0jUps z!4(ZM1r!U-yFkS&Lx};n`U0^boutl*pc0yYyDQWNkPOHr0WaQ(g9>3DkRM^?Ux^C1 zO~t>x1Jp8wH^pFiEXEC#i9|qCics5hV15S0@l;SP3T{Aw9gDDOiwMXj2~cUp(RdJ4 z_<>8p7kfCth3AVcAE48AuqJa0$jzV(v){?4^#FehXl(*iH>i;o*b6NTsv!n|9St4C zg%$^i5E;Zk-UM*VSqijl9n|=SPB?>0K2S*x3KDoLoPYa7PyrY8;&&>jP!WMOzN1(f z7BBsVBbL7GyA~_5|oD1x<$Cs zI;RSNI&~A@{r}(F3StI;jRK`Y_`CqfRM5vO4nytv{UKDexfjU*7wmWD$J=cNahEJgRLXqyN z;2{zxpMdUO(CA3x!3h$eX5v&Z=TL(LsHNBn;;=SwfF=>3s_Hlx7{D75__v1|1a(7H zfcgk#1`Eg>Xp^kB738>p-d>Og0$*rlD}YL!my1EIwgGk;qy@>k z1e7QtY3|}9?Lz^eOH*DnWr5uZ4qtH60L}QWwS%VQ5~C~uh-dltcYwTm@F7b#I7E9} zypBjfyx(|G3OoiA&I(SA5PAOnO(6AX(&(YoC0%{Gt zcn;pOt-`;3DyX9$)Y}T`=m+%nf@)Hb!Qc)oXqcdPDyVfA1YI7$za2D+;uQh98B+l| zcF_cCVF$dpY6A@@{+88Tpxm0p(Azr$G=%tK7Zcd;ka7-G6}0+7l1ul*4p7%NOQ5&) z$SLrMqDbJ2HznYF2~xcsVs>xu2aq|vQ$fZBLDjxUF#y#^0y{x>Pi9|afQ*IpP7%BS z8qfw!E@hu&Nb6+bdhz-t=p-}HXcK4{4ZK|$#K1PfCQzH-I~6ph8kEJF!H~kh&g@W2<_Ye3Bwa5wrzHLOj3AmGJ&s5oQ@4|EJ;&MDCT zIFOTG7K0|Kz|KDecRnM?`QV|ogAW*(F9c-?fU{4A#)9b#@NfW`5%hvt3lt3!;4wCk z>p(sOj}$_88Gyu~;LUJf^ttTQLXb_0@U(>hxfu7Ju!8EA;6fO?qVqJLr&D5pb$iS-C* z$`g`d10mz)jfakbrZ)MvyYd9Qc%=bK*fP){fQBtZd0IDTTBnbI2z1o~G}}PTNb8;i zGB~X>gpujRx2OOAzxep{|9^;;{QEgtPnJ~kZx4kv)WOpUf!$LYf&Bn+ZSz63z!yGWAA-hN zUrq(JJ3+}N8+azN^=#5Qdzij}l!`z7 z|34!w4RlmLSmnV-&|u=<-Xj1~5%|I-8IsqwUkG~fA{WetX5<%~puk~)*>>;&G#L5! zPhkY~)qu*5pclVQVa6(gb4~UMhF$fbrVe=OCarS{2gs2xM4o_(b6M zatzDChYaZIVqr#|2n5>(iUsgA9{+Yo?hATx$_Q#yi6FRgX91;e)rX*U5<;-}0gDNO z#2^-Qw}PhM(z-i92`#O&3zTGDe0+eImjulerge9Kl1N%-7bs!8xCD}hjkfaRPZBWWn@Z&=sY>H=i@!&TXXvq`wPUoaQTnvpzKy&e+ z^}m0(7(j=_P0$2Qu5NQu zJOgMh4wSC1Z-uO{%HU>TII}gL0W{WiK!|~1-`02r(C`;X&AP4e44@g*Bu)l~MO)(; zK+Ssr1_p-NTjLo(Eq)OO28JGx8?OBS4^m&hHJ$;~006nIY->CNs7(Nx6fW2r&j2c% zL27cg#xsD1szGWpK>n^QFt~v1J@x-T z$dC40;~7AWXAs+TYdiy}VGUwyfcynjBfB-80o1|(iHmHFX8^TIKx}qUn4E-|^J_~y z1E|RknnL)vC7uB^b^yAFP&sujg&Fcih-FgP+4r4}=QR;&4! zr52^-7Tq98^JL;;9tSX=_*l!En@gSf?&d7y=GASUPt zlBCi!5VI&PJ~uTt-q(?#qBxDAqPPIOcFqy3EvL8uVnbejd_iJSVs3m+K{5mA%nu}P zMs9p^S~^2!UP@|(Q)yaSY7s+mL27bIQE6^`PJUi`d@3rR0b&y9WE6%xuvs8OA%Y;5 zV|*clV|+P-V|-zJW?l*?h~SL)lH`i`LU5SCSOvM6DPW-jFqsx#$N*V?vqMCSf#F5* zPcG1Ti*K&}|G%>p+xa5Btpe9U3rRSxgW8zTeKeg@|6BzRJa%^o7&0()_Wro~|NrsU z4_BcJWB%R-H50HL`wcpKv-u}8fA4;9zbNzvxRU7!0JZTz7o1)D|Nq5?+yDP($?|WX z`sW&G?Sr8%tY8KYuD60j176&Y1Xm8A^XspHMjsTweI$@v;EVhenA{JL9BAD%s44|d z4=;wBCeOdU7bFiV^g#N8UM!D*=>zehi-AFxLtXp-AGE>)I!uHvjPoYf!aMyzd&m)AWi)rpq+Y<5eYlc z4)m-4|2G~2&C&&Rw}K*zH3QTb>h1-x8xN*|26(!`vDkPh1u_H%l3@k64PdGuBeGCc zpgIm_7IlJ(AKodtbc#|Nn*AP3QtHP^&GiyCaGhwBDun z3P?`s=Kud$3>h(oK8!Ek#eow_XDbWnLNE$uh|z&sT`CP8M+FA} zNGj-sBTTA9G>aiaBUXy>#XMy5Ab|i)Rv;zoB$hF}s76r|3fh@r*Lt8dfqy&Ld7wlL z@P}`yv#73Cu3o#QkYSG*J=l%cx z;ESYtL5c!jFhI-&Nx~fSA_uBr{|QJU?QR065zy|^gCE2}!|32?6OaKxFZPGQ90tm_ z;PCUXYdu-2$-jRp$ZxHeY9&FpP+kMs%h1~kazNmVneV~oygUrL=m$qp#lIh12w9)1 zwLyd<gU zgFSD3u+|-%YQPZ$5o>-4zV%r96#sUX4m3NaVzHwUY{xv%YBuZ#Cd0hoi{=HEiJ-9} zP~3vHKro-;-`?U2a&^E9J(xA%Yypvl`$-UN-wcqSFmAsB#fSB&+9)KOz^S776(h*k z+86k@`%GjC65qqc~F0W^{Y_I%)rLWKSoq7WBCYaLKO0dfT>`lW}hpis5GP-_gjOa@fogTk=8 z6=YpE&xF7izVLO-Ke~HCqMa-gU!1rC^5Lc|Hqf;BOHkD(76f)WXhI*9mq8mY__ud} zRyzdtPQCCRJhB9?I$oT41=@!q0NSwvK7*W(b-;_#DIg zu!}*x@GJ)Y{h?nVp6&&Cy5bEu!{JG&pmGItX9nofupRQ?^D~M+JaoH37i70bgEa=c$OETSm}_7~EiCPK zPX(D1^x_6s6%WiVxfUf7Zbd;I zdk~yN5vGERM^Lc=GBu#P7v$K$7uu+%P6Y)`5SEB&h8dfMW-NBcUID9uIu=xgL7WTE z@g;s>SAw=?zW4!QgYIm(_WysDBs{(Sj{zxS33$NmN|L z!PyO_16~}1sD}t=#Q$Yt=Xl~ zF8*FU(7JWT?x`SsK`*pmZUb?kNfe$RJZd z_xDZ&&16mmSq0jC@}s+_6%-zUFFIg80|i-z!hg`%D~K8N;+`V3wO1ko4Qg02IuZhk zDh^1R??y3{2Xv723uByycH%TNAGe_bU_IsY$zufuv|No5OggxX&VaOUGiKnyo1E{5ta~3>c3W*d zFfcGOWPp0H5bc344xI%T#Q`rmkqyt{ggLeek~RZgbj|@81WT0L!A*dG7saih$`pK^ zL&mxaP?7G$fDzb7fuicB#5#&;T2UD++A+qR|r+ zZjilV+e1}?UMRo>4g|dT0`42I1iX-jmETVsu8U;G6&5 zQz5ns%fZs7z;SRX2$Fmedm1!b2j+uH{Oh1aaFQ@H7_R^S|8g=$**z7cAm~MBDcIeetsrg|XO;u3LMnhr1iW}Y8Ki3wSh0}kgWpW z4+@IopciT$APpSg(*GAYv{>NI<3iEHlo65uPE6N9?Zkg2V0{5EzQWQd$R22f_V$8? zWdgG}U=CLR&r$INyqKN<)|S@U$^oii7+x%c*a-090i! z$O(ZjWb$`#`{p4G=Rx+rY2=|NmMKWHJAKusPkK z0^r2_Vh>FHiNF^PDC)Bu__t4e19BbssG}E;pepyD0C&_t`2jR00jeoM83eqq8Z>tC zLURx3z%`!E))%0_WPA|`j&zpJ)+Z3YCyf8#8fX_RsO^k3C-V35FoM=VfMN}2t^@Tl zK{*#amv;ApYzusm18#B(KrHW_3Nj0{-sCE%2h5Mq47%C-+W-IB2*2@f=kW;ao(l3q z(2Hk~MHK-r-hxvKPr!>5aMKV}T7p_j&=dx1=z+q7f4}P&<_nB%U^Wv$0Tc9MBe-cR(Af&&zPt_EVyk5U+P)3q2fUax0TkPRs=XeBp|68)aC-G>VOwJTtFs)`~pg1FO@+R40x;%x&Z7&xg;#{N`Vt2 zv~GXV53vAZ;BjzuBoUJS`33uN*gz0y*B>YY1ic8Bf|(%zQTfk%@z)o3kNy8Y0WvUz z$SWG?N+&07{rqARNGWJI5Z)Jq8l-*t(DxTpz_O5L63o93e8B#KI1lD#Zg-F%sMX5? zN`9ajTn13yc0Tt1|BE~jkqIJFKtw!zUTv& zwvdHAMlgM)3D=CCdhIWV;f%bK;faxiT$Y9_C z^=834vpD!+*0O^OMzFJA>=uKWqMgMCahn|2ZA@@egm!^ui_$u$f&=o`5zwJfDo6kS ze<2Sdq>h3@4P3H<#v(w05cnb$W-5P6D<}{kp#}-s7Zpy>Py;VIhiFKFX()-v0EHMv zPz8fCI>gQ9aK&hDu7gVm?E+Z|bF&-B&ERq#l$&3egSn7$o+qt46lKJ!`3Fm_F=(eX z=n7B~NGa+Di)Ziwo**-VUL-k!eF4quuXnr=h~G z3qM$f1tbHBgBOwzhk=GB__t351#i%cRD_0mkmUrR;p+}aOnV?C4}xZ{r-CLq__sIR z-~ui115bJIZ=ZOL3pA#>M+9nfiDU-ounAb<_JSE^NNG?O8))Qv`$UlGK`&mxb);u7 zfcD0p-3m^ev4=qI9nezIiJJ_-@)0j84}k}9`S*8#wVZ?DyBmVwHG6MoQ(11PdD6c7FX|3U^th=T|r5Wx!~I1XXPtqCl6_*+&ZGDIj( z&0}r1q7JS=5>%6ga-?-T*`;+l+Pn}s2%0*W$pA`Mkiw3C zJ0uwRx3_}QRKSZwJ8)ou(%FlpLQqeXxIs6B1=zf}Z~)vF0o5|lw4evmav&h%Up)iE zi?;{Boet1Ee`g~oy}X!x05mwL3|>P5nltMRuzAsb0Cb8Ccvhnetf&m6=*5Bqu!v27 zEVGb>q>~g7??5R(bmgm;%?mfM`T{idr3%REOCYNsz_xhVybuOy0Xd-CS0b$wTwcHU zzaKuKzu{6m!wdd9;0b-mCH0f;fadc-bB)$-UWDF(&gXN27K&VoX8;ZSe&AFSzy8IYeXu4q_*f0p<3ITK`-*@DB6vZ&B*PD+@e8}Yc(H3A zs6Gjm0Bw2s6Yyg7L(uYG4$w8k&=C!c5}SX&uY~o%+9J@YWc>TV11~?A4?>#2PT-a$ zD4s!myBE3O&IJ#sO$s`%3_7Ok`X%6nF}T;y)9LyI)N1Sw3XNz^+7H6U1biRu zX`QZTKv_g2t&{78%3f$&{m%=@y^v$@L3iB6@^aUurO9X&Uuzpeg8$5vkb~hxT)4D|%(>g=Hyr=;w2464$-uuoI z^rGq)STWcGpw&pB3jEtyxB|d7fySGm{1;4?pcnx6>|eNn*(_< z#Yf$)5blf97Eo;$f?n{$wH*Ol2MR9*a2fz}K_mAt+or&@od|q!1Iz~5b^z2X36%+Y z!O9CySKN#Y3@@(k`v3pM1rTu>L>vPV2SLOh5V0LZY})nze@3A#s6ql|Mq?hR2_;dW zlhJ%n1ilD>3%P@YLXQN!u!RemfP`ER1ia9K3n_x;20(`ul*5Jiz>_v-UWo1j)k1k0 znl>=|4s*loivabULH0d>3%P=XK=z%53mJigK=$o|3(12Hr~%o>4!4g7YTweGpz4+l z6cnd+{{R2tD2O-!B6fp_Z6IPJh*$$6mhb%kAIWJNa2uks1o*duoaPD_at8^4oMr?U zG64yJoF)$!f(JzoTnH8vTp*{t&dZo(2@8rHT!^3mEvGvX_~I&D$Tcf~e>=#&LvSG@ zkPyhe^>870Q2c=l!GdDe4#-|?=)EGpO~L68dOt($4$xf*u!~dfqsS$K8H&rpumOC=oq`(4kp z9w-$Cm7M~hvh&4uP~?Hm^93bu&?b5{n6FAf7sGP2o-7sK#SUs(y9%Ur3cT13((t+r zmK=U?!opKCBaICd%AhJm2`(xOJ(dXUx@xdqE0Eq$j-VHN;HuQ2?Qz#X0WY3$z)Tbb z?+NG*1v}Ipq<05sVi~l65_F9E!G{dJQ#h^|Ph;qI72w~`k;cCbv;i;l0TxvuCg`f} zU{Uo0!>k)vR8?S@b>+pvZU6tjm;)lFgNRAnK&?BFqdI-}G}rE7=Wl-mny?7n^Iv6Z z!o7F~{{5~G__uX@F`fpRfW5=Nt*OLh8UynQ{{5jhvJbI>Taek882Gof2uNT^9DIaB z;^HIh8nQ1jqexug-_|q(W-NjOx)gLjQ?CyP6F9|ky*RxUlsG`=F5q!5Ony*+U0}7`@KGleE3~_Y73|+^#bL+{T$5)C7|K587yoJ-hl$W9cBSo zNMTn(?HmU1#1}DV*TdD!wZnc z(F9OiS?3<&4u>F+(*KY(s4n;7L3g9Ymt^LY#3$#cq%!1Y<{|Me+>K{=jD)%G#53%^ z6VJePH=beV-FODj`C8EP0KrZNoyq*-`R4!sUkGgh6%oE7ttUZ6M5sjTrBY$&u3*L& zM>m5~!ER8GjtP89^b2J}aJdH3&%fVQp!GnB8t9H(-#>vbI1p0cL=5VMbPBv^1ex(V zh=0GYOzX)KHP94F=%1h$w+!G0?O+C#F_6>Fg2Ad)V5+ttsRD%$xW~o#LKmb8x{{13 z;6)xQtlSXJ;^p5Ca!fTsV|OS|TDR+;v`(fMUpM{#KLK)dT-JF=u!CBb;Pb`M&pSis z@0g23laXxv%>(gSMrW?y9JZ7sO_ z|9@wTXu@64X}BMr{QnQ0z(4qip|b}p2yL1$^iJV@arys$aAA~vf}wK??}5wz|AU)5 znTH~o7#MncSV0QF3vVFWK?+`If$r5-1rZ7$LK;MX&O@63Gq|(20JJV*FNkC*W_r!` zV*4pBh6$i+Y(PS3ol{stK7dw@=3IuP!REan7DQ4 zM0qS&`K9hwkPygZ53tFgPz1$l^Ii}OqSOei^knx`kPygZkW%m%n9T=JcRH;TeD()u zU*FUnm;e8Vtl9!I`S-ViM4Epv^Y`8W_4Cxg$1H-?^X~^M0XJZKJleo(S9(I%Tm~;? zg~)*}s|E=Kyoh6hr6;`?k3eUjG4k(+n6iC}FGxwyi{ExCExrPYgSRDudk3K7 z!P%K%#(2D#4Kn5jxP2X%6a;lCKj_X^&_O0IY#?Kc0WS_)fz1tg@e7=QS)lF)Ewchy z@RAJ_kA8ol{nu_^9?-By7Gw8RP-5fX?!*-EA_4At!51oj|NjT?jsRtXPA{A8RZe{=?Q$nbOPKj z0i9;R13l>gbXDGqSH~gZkUmnNP0))U4AAK1Z#l}s!0=+nZ&1z8lhzI1lT&gTy1e4Y zYf$m?1G>E82dJCg{F8~l_Yt@<4E@o1sT6elPAdo4$-Q7typVYhK7s1B1Zd+wNG7Pa z7398v7fcWtP=^aNp977BZ9M{@%}Sv2G=FrrOa;YL0BA8T5Bz))@QEHTOmv~4dm<22 zeDZ*|G{2BTh=R;K_=vr?MKs~V|Nr1oh=UK=d#CVbfDVxAg}AcY7iw+S^wMp~zb-HR!|z(pee_NFXz1_pR%2GB$dNL|1SClqxrCjb2ZeWm=GXLBatqCZQ;M@%aa6TLCD~tbm+NrwCdV+Ij#I7QG-nfiL1v z^gxmjOK*!Ps3HOn4S+8U0cp%U0osGrJH;1VM1Vv>QNSd+ggBr-r_zlbuEDd2@Hia4}5d%=zn1-TSd zuJ89s;$MFdeAYcE9d&^Y|L7HQ1iS0t1NPn?R#3J9XG2IX0%aR;;RMRWpi&T$_5xn~ z+6c-x0WT(fhebv`AJ~Q_@I4I&N>yK^e+P#>BnyL67%17Mbx#5%+qBM!po76)o&=qv z2^#eP9rrH7znuvb;PB&iL;`wy5jKNd3y}sH6x0oFl7IvPU(6N;tzy;7w(C{&+RRk?{koe&6gW3!Vad6HJcrj-hDD+hLw?nENP{1J0egUo=jPXxZ`fw3p;mq;6*x$ z#ETPO!Nm)#Y=ocbbm12?Ai>28hV(|5G)k7@Mll=gb4c;h@l6nN!Xd~FK`$Pwf;|9r z9H_M1-vQ34Cn3g7g(%yDq72rU?41H`Oa_7C5LAJJG9_fENcJHH{_Q>B24En#F%ODH za5m)MHiZ#X)dcNuVPIeYjog8o9=$GHBJiN@Z4m|K&;an_QBb;ov~$5BkCsc}RSExg z*r8LP%noV_fIPDue0&EFHx8&-o-P30s}P9Bla$y0pu*u9!s8g@eH8c1nRypy^Ci6 zr4-N}%kOXF89+e~IxXn^+js_0w1C)8-^Me5N_CL>yKmzeKp79jzWO$v0aV|BTK#9= z#xsC=L7;h|10cP3|NrM;U|`q|(tG#+e~|h$Z$W47|No!D$-uDSZ9D@g+n0wMyL|JTlr(0xOq=P2p^SnYrc# zyni|YG>O^mWRuqE`Ucd|2XCPceF1J9U3l>mbRzQ?5b^#Wv{RGT>HFcu!+)T$RsQXv zZ-QQ=!X3d6Zb^cs-(DO59i|U<(-%-vJoF2s%NY6vv=$1q+8H#L=gh^x@M0Or^o1Z| z4#-f%?Pb1SV4id4-|zdS^<=3vXl`zQ6ZkOM10}lPA^A6fFP^{^N`db92CqN^mD_3SutJM>CgXXu$1H$eyFgYxK$`yloET{pBIDDj3YIsn%Q zmr88Gk@X?q#af7dP&)`bm-s>l?rurgqMTKb173N8Uep(XW(h&pn67C(P!b2~!GNX% zyIH)_I$f8gbt87yfQEuXmx0_F@WK-6Z1jW;_w8#kcOy!EesCH zAAv7+$-%t%gMWYM2GH>vpj93(m_XkA`v=r$a{bbJfWLJbWbg=bfgJz-CeUuf)&rn@ zeJS9hV4>$Jy}0=q7KiEJ)*R^e1`)^BOP~vnKz`;4crmRI?9nVvs2BOSyLf@yQ-Lq4 zp;DlW6n=DrE<^AMV1d*N2@t8*0$GfpbF6p*Uid*oK!e@BKLTI8mxX)fwKiypPUx3z zR}IM0J7tJBLF-5$>lqIr6oX>R_e0=|{}3UN8qj)(?Hv`M%M@Q^Kq4`%)Ab2RW$1^X z7gu2_4}eZ-fixUp73&KNxcUb#_Wb_;|Hby-piuN((|VG>WhtaL`UP}K1bF$xe%BYE z(CvkVE~qx;-`)h;atWF|c@p?S0%94+e*W#DAA+)&UxY%0K%IB~?Vt(bBPiZ`5b)x$ z3@j`jfR=7d1RJ}*3AFRE^+2r>LTo!&3~JS1xUMI##1O**?KT|&=aL;SZvOiJ|HTz> z|B?ezdqYoe0C~>@G(~m%7s$V%FIq2^3WD-}>w!|vzTvoP!A2pck!cK&!`jnrl@UO02<|9dy$GXyIq}As7Dr zK8zx*Cu@a3YpFq{!3(o|aQZ?@DJl?=7dpTG{|B3501g3&DXw3#Pq^^!58)DNy;Lg> za&fn>N?NywV_IkEkryw2g34e0Ue_I7qLpwi$Uf9D$L0d1@fX-k9-N((p9lWXl7P#9x zRw;r`@?(1O9}+vD^!Z{lPS-mx!a*0;1wk&ZgN%vt@1F=hp7v6SIX^gomFR<< z;`=7>#j5wP>?y;)J@gKEbO@RaK{uDZ@G=KAhj?Bvfeiio1GGL3+%@HB-U;$11Aj{g zD5)Zy+_6RxbVz+k3IBd@l!GR~zO)`FNy%b_nhRYj!4vpmZZ0@tz+F(#tt>nNttU&Y zL2(8vDz=9>G6jK$_xQKF-U)bd`W@K00WUr&fx?vsR-N5=5%>c%5eO>UegwVvA_)s% zcu@9$W`n>>y}*^nrIHFz5V*bxc(EK}X6u2HRB)PJ@q+aSJjL?EYR(le-hT(J!2qqO z1XV4d>ahvbDR^-mbfh*T|90OMkiG37Syqq?IDvqdM}vd{Uda9a`M>#y2;>qhaBr6> z;KfY1Q?Gy=1d07?&CiinT^h=DH`eg&PM4qgHEE1u!S$}QmDTJw<<>o+g{Y=LypK>ZSd zU-1k_p!0f$zv3BoK-n6<;u-QnpnVDuBLH+{Nild;8+bjG0C*W&r|XAK*Dsx}KfpKT zaPY$}_T+B?pZUiKJNMcq;6>Oga6$!V{}($m!0G12LD1cB;7bd)JJkfdFoLLQJy602 zE_D99nD7}?u@uA1sR?+&2UAlDzhJZ`=*5qhVAERw!2Q4o808@Gbp%h#Qbh>_d!2-4)R9ggsk2Brx5q9t) zGxtT1%lCIYGi6{n_>c|81$pG)Lw4?qLEwrE=F|l+pCOzYi?HhTLU7{^+y~*`4)VtY zh$JWnfW{_XG^Bw;6WqE5opf3N;qL;)UAL6a29lTi|YCd_dDmUD;%(EI^M0`PhP^94KsunU3W6tw2^ z2OK7BAK`kn^%VGvs;-K~pKh#q%ir~`n z;On+g{rn;rCS4*9?vR5g^Iu`Sy7_1Pq-uOiZNMkb0+&|q@K`uz^c47iG{y~$EBK+Gy`TfFUSXj7# zSJPm--2t><2-aRazz0qO;MFyape7_}QbHu?g~#?cpb->^8Q@8hll(1jAWelg&A*sR zd5*V&&Xxmr+qfWX&~k53at2ETboYXs82DmcA~@ZEOR%)g(2f^#-~9joV#OQCc|0Qg z+dXOmUr558%?GXwI$o5&0i~rRP@x4?^YszbYv778RD>T~rQU~$mI%VS1syM}z?xM- zSs1Ep2V5CHc-3oKr*Fp#VURLVQVZ<}>ITPYz>EJ0VCTN<0Bx7q@B0RHe(gd?1qQMb zavt=HOqg-}Et#P53$%r-29`byKu5`dd9b|K1^1pbIDkNs0WVy5!C{})*$U#nKAhIw z3t~VvBZHaz`=^3Mx*^p|T4!qs=!jxQ{_SAtz!!`tMx=E^ly^?8_z&8B2kN7NmPkTw z5dobXCBnZQTwDZXadi8Fl1vzQW)r*~Q4#E#fETu422a2X6Bt7q!sv8u>Go{_9asZ$ z6x2-tFV@1sq6F+YsLRrMz{bHmcZ`4gRFK<2t1&>j`SgRC?=Rs5U6{rws86Rp*0Q1u(h>DliAS)O_nQ1#DE?#KB zY~gSD2}(eq!@)t}0xEAjK+PX;Ov1z1^C8Sf$YIRPjS|L(Ve#L5h%v1bYykg$aN0`i zhBSrJI(tEp@Ini841g+VD?O&$U-aIG+6ActMNqx=A`dPNt^?7f{bAB2g3vlpB&`!% z2fpS3)qWz-+7Bro*l;0x1C|Rq!3iV-G+PNNut4=%K$ZhIq9%gsyr3)&aFBY0f!9}{ zyCf7c92W2*2h89Jc##ZaL_rv!1RdG}OOntq3Vd+~?gemQg99??#WYT2SH3>Rza5+z zVR@Z@KRDBAp9+MPBwJ%(DTWbN7A}Ga!OFrruR%o=sD=TzGWLV(%H~5X@bp~-QU9Xq zIcR7CR2Y?tbcez`y1xTFl6SH$8eC>Rc;O5>eA^Fnp*REocF+R&Pj_Ka2^s2r6Zm31 zOsIq(96xEDp$}egJqHb=F!FB)ZA^it?r+gx=kxCmeFGW~22D(X5@!e0si0}`=3k5@ znwWwt^&;qkpfRtn>h1A<=OxL(6Xc#Y=AJ> z09jZ#oO!|Y46?(e6)gSb>Hq%|Al>urU>o7_aw`fPHr>7=kXy{4H_nNHCOES6@5p=H`C?LUCW3B|9f4u}m%m)#(o`T}n^-b%6QdiJoD^Pod4d#VX zBT)JWpM6{^3F`fe@Nb{^Mjy1(^3iRmH%s|IIbnZC8))6g$r5SslEv&p4A30c!vwy0 zO&R1Nkolm2m1Qu!C8}AB;7|rl9)qfj9s!W*Kv*I6HWKVv&^lF-w9ZD56)$c+0nd`$ zfrbcVqT~o0G>5oefux!ep5x$!RIo+@Xc83ENPxH%a(N6$O~n8I|6yuCY>*oM?U1Dp z{M%bWLIE$@o`APM@$Wy;da^_Y>bPFeqirj0K|>Ca4JN!`1|8@PavbOkHBg{$cd`lS_7wm%izh(68t|fa z4QOgw1T?wy@(yUVE+Z&{w}UMVdf^W&Hm7XUftwJAU7$dGPVg#d_y zKzB=m8uJ{Wp%l<2Gy%9DcGiHj$$+&<8=ou{&tPT-UC-P&haqD};~a(;KU%<BPP>8yTiVKhU8jLf({o8{SpKYyAIHeAn??)J{+8SKr;I~ zmVie1__s|2t;bL6giH#y9w@Qm2VX+{1Tt^c8utJH|Fmx3Kahry?;r528UJ>$INamm z5OcvLAC^Ov`1gk%0iB*!0y?W+`w_Uo&A-26g&F9sGgi4CJxriQ|7o3&gI`)N zfgIxcr`z`lWZZvh2-qP=*L-jH{Q^3d3?vQ@%5!004}yy^{_PXjfNmLh;duj=yg*~` zNJa*s840QedqINm0IP$T_oD0}C=@_Tsa+RvWv~ z9@bg{p88z^o%&tEzu$EU|9;;&)(2}XK{udxyFN+l<_Spa>3eZ8K4f9MR%81e%ffD%J9KrsXohsTf(#EdKs{_VaC0$-eEg!$?ZlAks}lO|}t z1~h3RMVk+%J>Zl85{KJ!Bn0f%mj!=8Ym*@5jKei>LI5A}2^xGhfbw5lzYh+x8K4QD z3RVUNa38VhK4=jdsPuwPBFlg#OGWs%cR(hH!M(nq7ts)l`1d0xRxdOsf~JRiL4xp< zrGibH2f8+9{_VXWLAbWJ!C-H__<9d?1{$ar%)cLe%xvpP*u*cWNdhX>0$x103ifa7 zfs$fqrsm(z;?;VfBoN$~hPEwcL5u{={emtje*zl!W`bK-1C?chdJr^-jc60aL1bSG zgL?{413e*v;O@bnpck+Hi-0O#(CBAcx2ptb5913pkn=$mHmCuU)(u_&mDcHc;05nJ zQ043UqV;5H4Y=|KDd67@KJXS)@}CHLF$-?q2~b%L+NTx{NkyRH5&rF=2ZCOd!POi< zZvB9pXqRf05Mt1yXZg3go(Om`0j}!=IP2_qQFj-*mU+#K;=AB-3);5XKM{0sLhGdx zSJ2vSP*bBfbO&glACyiZ(~!_+5NsM!_&uooA;Q1ibqA;l_!Icz;y-x6fJ&aw6QCj+ zYX0_#pgG2%7jqfF`2#dJ@uCs#yeTif-ueH(8$1evm|4^Z*HbS7UUXcB#k&mucHb%B zi}|3@2Xfkr9g>h4#SI`skXpRpdBaQmE%QJXDYVsU12c=ir5z*;nnL{39r^@3?E`B{ zhX;aFCA2)@-w&QejD}7chE553VFvN)jMf7+JjYvIkeV1EHmHdKH40|LcAo$yP}u>J z4tf#J3Z7~_=GxEr;x*`)Yf#z(?VIcS3lBnYu{jYkvk09M1$hlL?+2=vCW58|U#tV2 z;LQLkIk$V*1-{U~1PdrVaE<_F9gqg-+#w`AgOedhG~mVja?ny1k=MH5@CnJacBd`InboLA3U*^ zeJBOw@H3#vgFoG_;8F!Vn|1&tmp~oB_5nPh2FlN%2I2Gz&~V^yVPJzyNlZ-v^)lXp z&cSvS;fG<pII%f^#$|)B|5wfkT}GbZ6*)XzsgK}63@PyrPB zBl8ewfl{|GPp^n$XXq2qT(j$+7kMDr?Y?)Q#Uo_fN#t*M%%pYu-bm~8J@XG5xG0#zdLnpMmX5&`?cB`~x?b^_N1NEI?W|MpgpAY9vh zUo6@j(6ur1Z*K(&!nLh{XnV2Y#{d5>R^Nbl7_|OnK4_4t6_S8()+$}+p^<~PR&jyY zfumMYgUVvBRX8BBsI|&xAFy9RIUlr(Zpu$sp#K3Co~{xBF9PB5Z~{CC3-8B*mRtwC zFoH`T;NK6fVR(+W+8`B0AU3Ed0?i?{UIGoOf-dQR^@Tueu6e zT!?^8L0%z*=$V5mGEnw95%}UZT-S*g=RpT&odO-B1v)l-2RPBLK{g9qX&rzR<11Ac3o{1N<#>K~9FoF2rN}EuGMM3*0~h zpXLV}6`Jn_PE)9jqgZIYmh^=Xzt~Vev@!LVS!+(P40HqgDn7RG{w_|%j zq!X~NaR9Gx&hYsN3~Mz>6q%a3%teS{;1I z0J;*SVLAh-mKVrA!PXu6ptpq!6jBHUA{-E%3P?IHKE$sPBoEW~!VPTWiw_t7|9|oN zB53l8f4{FlcjyED?JZuQ%ku(WguuL8A_#8Fe|WL!B4|rD=q5GrN>qVv*9ZLDdjdep z17E1Zl$XkZR>_5;%Cf^`q2uUjouMCIB!SF(ZI{Ii+790B`+$G@6i1L@K`(9`hX!?t zAZ)fbp<6WW|$fLEu5e!IMAv>ED;ReZ^QyxvUDTxg+0WaEDn(KF_Y232Mqk% zd6*!c5r(P-jRy%pgL4uS_->gS0WZF~fW4Z<294<6mM+jG!{9W9V&xfxLU4%n_DldN z1dqXj&XCy7A_(#0VyHsUx@K5xgD#4KxTX~caMz?mWM9q%Wh53zM%sK78tMEk zO(0<$en!bU@(^=C;o~cieUYu(^+9is04TFyy7#j)Bm|g2VF^vUBH)_9ci z3H7WH(D@$x`(1g`__y&erFHtgf$f*y0ornM@Bu?_4-@F55dQt4AT=z4X`QYwc7o3w zdC0H}tmY9zZ;K%41Q7oHz92Os9BJ?-@oOHG4#xh_KcK}P)))AD<3NXm?e~3?eGwFh zf3OYlX+sv@><4+C3*vdukvgDGApdrjKuARWa)NjqbPmIdpcmCgpy6Di0m`Ya0@)|H zAcc$?c)KWQh*HD@lB4!Rw7xig7IZ%$h}a7{ZkrVnV}>x3O7%cjTYwU|989Rh8Ps8J zJx~IftN9c7f*CHQ0m+WphqxfcVglHspq24FPLR~&4z<_+EU0bm`UlyZ-G^cBx8~m; z`UEt53mN8e{lX6((%c^^05=*m8v=3&|8|(sZydp)@v;rHPXp9^hUFDR>O2Wi^5Wu| z|Nmc{IRhyfd<6nuIKZt2E#P1PmmzZ?ieHC-$_mf`zBEixsT%065s*F(xR5ZoG!O`S z@%0eQ7t)~8)K#GQ1tWNKXaKlQaD$i%GSim_5+=qFq4?$_8rE-KJnezhnV|hW&2K2K z|E`_>|Nq6q(}+q?73MzFO7Px6sI&Q7kSjrTglaM?!B7Wqw1CSa(kek|B%Pp2ZXyHj z+7l!Xs{|k0gKd2A`V{v159U)u{RcWM`z5aW52hS@{RfjpssBLcVXyxVKtma&{sSvV zuKz#+DD@x2NAUU&ZVJx&&kh^}uVY?3I|+*alaQniTB{Ta(~PJDonS&lR)S3s(_dZ& z?Ez+ow5|T_hx&|!O3(^o4ycd^)8eiaGr)BP_Db=Ez;RG@5&EU|QVCHt;{$6* zXh3Vm#J$kKC!%It3eoyvE$AHW6(C~qvH$Z8m&}+sQUyp*jfnT5<5@^kfSv{V$0td;<8r;?6Du|L7 zn?Q$QuRRJWGeFgxBHVsN^;ip0{5k_vm4T|qKf9rxMO2S3;X?50@fu91L_doOG_(xa z*{uH@+;0WVQ@mLG0?NJsX{!iBYy#N>t1=lNLeMI6Q!BK}1h3145up98(DSWcfbKDc ztdE9H=j%Y$r`oh0C{gV8G^7853v@0w>k-(bJ!tn2XnHH?#YDKf zNtP?!mHhsuBs)5zM0*#us|v$!D`~lsl4T>Zr9NPV+@y!ed z2GCu=poL&N)exg($6fz`24Ii7{s2?pi3zu$F-^@Umu{_WtUzM*@%U7vLGObF}_ z?Fs63?Fe`=54?+3pwqRZGqmURfvgYRzCD56p&daljueBVveWfX1_J|w1OI+klWt#u zZjr_y6n;qKpP&~fNccDFKUhy8dXc{lQSmo5lD-@ja-4R6kAN)&87c!l+WE!$cOU~nTV*!zZx7u7IV22J=E;D|ychZR zLGqx*b}RU|yRHZT-#GH(C0G|obO|iP7y~4lUcS+z2AxI2? zmZ4?IL%KWl2sIgs8;TfS=)D4)16d>w9#;jY+R#1F;G z9r~b~r7HlM@*sSdu0H`U{J^Ocl=8MfQgTqhi!SgP0vzC!0ZL*Yf?h0t2C){DoLqSV zvKU`Hg{+1O0Egg;-{2Xz&Q{PWcK-dLF0GeJCA-0ktsx59krjZ>zXB-?dQkuo=HKtT zr#sZ5lcnp09_Vxc&)@(5XPor`o$Kp*B;ZBWMrcCgZ}|*bGz*#w2N&U>qkOLfz7R!Nc$$HM;WhY7*TzGT5-#)#|9;T2Pv0}v z2kQ&?w}+kp%|c!Yc(ERC@(q5_oDz5;K?Z}(xBoA$d;nR>(|VxR5VR)YO*iONEodoY zkqs&fprs7Bdp;-dg)rQ#Io+Xezy%`YjD2X@=HKpn0W>dlCg?@PN3hu-51~n(2zp@+ zmpt(jbXF(G_MU)l-;Tf+AHZn>TxPuZavNj@C{b_V-wrN*patD&$acw~fER%f99!K(SU`)UNfNPw6Dp3_9_!zE?F@%DB#5($PP|Oi4F>jKLPMET_6i79=ctjp>!$_Bnq;qfqy%A z-VG|T5n@zOzzcJTl1|qz;G8W2a&SYyivT32Oo6b|I$ayOL+>;m(qLp@0Nt7ZJ{|*> zY~?{a{6Uo!cuh9wBvSC&ZAg^`X7cX`FV2QmT-wlz3oO>{`U0iydIXL*XsUX>C4->> zwB8QXRe&bDgUAZtfiN3z6d}9!%GU7a89{HylCFlXGc3SsK_K3f?&<0*bGO zz!%$Zg5v@d@z7%7#S+NEs(=@}*Fm#)iS%*TFQ8IxC**=(--Z|R-~a!A!38oMQmT{) zg3dYl67a(8JEX*M{nA|fg`rdgQiMnxX8|>Y8D2aG?WBLf2vSu0g@M22FL(yJ8+6#s z9&iZ?zIO420>oL6G#I)e2&~}r6R=wYUTgv<4p4$z0WsbJREEB&h8U36=?Yp7KLOMs z-qY=B0Sej|{V=^{aJ^Ibw}(yv#rKMU7Z)I1&a_U~75v+MML@Z8LeLAZ8(<5e6+r_? zbVJY!6NKoC3J4qI&R+1Evq11E#T$ZN@Ihq2diVRT2z;^j6UZ{KTfy!M8u&-1jZ)}@FQ^@A{pN*68Kh+ln(uvLk-)G4I>*au znZN+@8|eJ5KNbmydtFlFOL7Ysz^z(vdlpoMg!k4q>;#?Y1>W2Kc{OTd_QjGf|Np<3 z{{?h0OAEM7JNe81|De%#SCfDj)31R-3zX%1Kx_VdRRUj3Sq%#;!(Gr?;J^$2FQ7Gx z9ALl6bo$-_H?*JZfV6X6cf8R50_w>6Wq>qfF@mWV($~RegUcscbDu1^A9v}^|*7RS-)3RAbB2?$iOXC-w%N=<}iU9nE}uis0FA6+5r`NG5;>usBT}2PR18Tp#Auu z#-~Bhi*GBTp00f&>#N zm!mc|MIen$CP=tKN)LErvj(gSWFWk;>3IcYEl3F7*ffI(fy)VSV{<9oFvzxCa5K_% z5A>|yJ)k@aJ}Wqom4N{?%@?ZC?fL+m^Jhbvsi2nAeu${ggg=2VTA;!&UW1E1aPtwI zNInF-$beMhAVa%DbvjwPKylW3pwyIqyRS)L7UPR>NIN$Y z2zrrr2^J-1;7v*+kjs#ol!p)&9>CwE%tmTb#=uPmWxyMt+T%tLq)FKbZncA&lsce; zq`Q5;fUaf&Ww7Jm_7e}NJpx*WGAHoG(Tgw#BDE%~|Ns9F(uvfRs!!mQi%4lB5M=KAKfBFF&#?ch@O zMZgQWP2f^C;6*8uEAFJ6KD$pUIzz3{sL3T=>|L9J@g zAiz%^C-E|5mp z3%-^G?OcE;Tk;RO8x|}*4J6&|E7JVZq0{$CZ|IcHsi4KkpstxK_^eO#Yt)5mO}bk_ zN&>PJKzHQvZx6KzdXc{xR9pyjyFO_?pwQ|1q`McS1k|bnGhS~$?)nDY_ypZ20d@;$ zKgJ7*f1q-CN+;Mrm>!N!@Cp84RT`jS(@%e4^PyN>B*5RB1DX4Q7{d|xLID(5M>smc z3#_}R+WZGyA>IuxpIOp6TXjHVx!b{1KzA=lHt@w79Wv6R-?Dg&ycdO`6W2&y%vf*c7_2QoO|g&o8`u-%VNf$avBll&*DqYsonCn_gh48rYh@Tp__|$Xx_#et za=hRNiStghA!}}f)d>#j6uDvAW_7@*sc=YJfJK2IJ%pD=rb?`yx0t`sCfcj ztb#B=<>hKE&_Sjj0$*%{tU!i|fyYT7sluoF1=w?mb6 zgA-T4izjCw0S@MZRl~>hIQX}>aDmK(r?TUaUTs=us|0A~U@9oj^KWlrVPRkZRYV$r zFG5d(i~}Vsk^i6q0JQp>p@M)Z=VXv z=s{VGSsX98AYKDin=kTCfV~M$&qi}#jxYw5+1=penbz6FVZgxf;_J`<|FZ)7TK|3N1mcQ%5R9|N702~ono9c)m*3nvxOE;Ue)f_6Z5 zLl)HY@1F|d1-)Q_d7(rIv>Bcwt+UYwWN{7XaL|{ani!nU!LDgNP?M7-(AygVx+bMN zl%w$w$W1{nE+l{*)7uJ?fK1&^1UV<@#W7_RyTNe;I$Q!|ci@W-xX(qwQ43m(-8lhl zJ?MPS3C$<}gF>XU3uM@fSD-;N=s9uVeK;>}K+f;v-yay#dZ|Qp$1L!rJgq-K$z#ut z|NnRHhyzU?^?m>etOjX+t-PxkG_Kq^6|89bkN^L7cqD=pwSpD3ffRwp_Iw=zUz|J! zjid`f8KCj37Zu>P6Gvw&Xou{JD$o(4r68i<2WY_@XvM(x4$v6}fiL7{L*tac6?6?a z|9-H2kh}~!@jg_dn}sXjML0}ZNnv*{$k0IejR&BP5M$7bRJaO%{_S8l2J}KoN&fAj z3Xq8muz`ro_QDWcsPcdl*VUO&hm`PxYZTD_r56i8BXQsa&jYGpCVq#U?9}@L6i&_G z|Nq~W00|`UVcA8X!Mk1%(E++n0-WV?T2Gc5gLYtXfbNTUp+5_13x5mftOD36ZY)7B zL=iHEj0_Ar6u<_zf(@1g83#U@4itR}knsCt%D@nqF)NaRA%lUT;ogfDa8BXrbbY|T zA6$dCUMf{UR%#p!QyK|Z+8z2J=*6$&py&hDWCH*H|9@?atO+zLk#Y9Sna3|wP&FMz z(UideI-_KJE69L=7c;+s>xi^YFrR;WFGv{FQBw(ekvjt#0wqGQBnl2qQ}76;Kj`#M zm`_W!GZ;ib^AD|{CP=^wBZStSX>6dh*b9!9U!XxX*r_T%UcCMa9)sfF4=V5YTQ`AD z1^xc@|Nj@CK*U=R@d89V1`+o_#7z)!1w@<&5vRWX|IfdDD#+|0aPjzJ#$iwhaezuB zVN==Zw1+JtZhW&Phy9T1@oB9uUc z>=#gEwSpomAmdvE1H+5g2ceO5A`ol6W({s~LF%>pQ{jg#_65 zx2M6?fKE%rQT{wdr~<8c&48PP6w(u6YH)`1e7FkKkOtMGpaTTf!{s%hl`BVg2PCAY zz@<<_S`87>S`a;;qgX+D0$wD*_3*=vPy6v=HTWP*(Aq4goYn&+{KhA{r-Hi?on3s) z3=A*2KmGszVi|~7_z6**zW^0SFZ>bVd4h$3Aq#povjswUBS@Hqe>-SYIS?T{i-mz< zCn#rtm-#?$VFow4z%$|y{)@x|(3rgt^kONP4Jx!){zI>51BW!^#%XXv3^Z>I;l5A@ zs|IJ_7ujGoNGAj6xId7kpzH{`&Kr6ua`r{|70xf-?nl^Z2-o=sQ~@md`2YWlxgcT& zh?oo_`anb{h-d*3^&q0^Bj{dYU+BHp;FKi*nZ=zj8J@K6fs$XLFEkXunGdQc8=+_? ziXxD!p=#U_YNn#70eeLNGTy2LQ&dut0lGN^Jf5pN1?q&7_zch}9RK!KP=E%!I5G() z;RcoH1%+4Oi`8%mU8uxVP;dmjm;{#)0f#^6c-9xOph3TvC7|Vg;Bq|&bP7@`hzqVC zLt0Prw}yerNk~yY6;#v*y>N#a#ouBHDhZWffpW;LHOq%%F-a5sH?95+D2?c~A)l zRU?W}(}bc1eCIl}nE22KwXGyEgFzA;OrZQ0_<|j#yTrrz5~Ozl_T&6Fpeb?={_PV% zJ_p?t0J>1jjDaEW#T2*}QSh?YZYL8^k0$WN?91Twl+Cpk4E!y}K$nA7g3kOb0TKBi zA`3*Mf=mWiGT_tGJ3#q`8FDHz7tG{RP0$(!(Am!4VGb`91MT(#9ia_gRXY(>?X+Gh z^~p*BwOaRcbcb4i&JULfc)D0{{R0)EQpAB4X#K-L1`1BrwndbP6h)jIHo}T z{J4w*(LRK$f-0!c_{xd&D3sUu=2x|NjJV zLla!(a&-Gjbc+afP5=#-yjcDU+@=N%x`3M-FQ$P6LP0~OKhipzUg5RN?Vn^zQHT$~1()dr3HLNIuK+kz3iUh@R#x*|UU6Fc>MGV zZ2WZZ%m4qI_ksk$L)so7U2@WssS;MAAa*$Nuu>kbuZe&x^^`lQztI>HGWQ}G3lVWQrk)cixJ)*LeY z8JMNe9r^?`?gug=;Dy*U(8z*7x9^kYg9@F#Pawk|phZ&PL5|m3U<0dXUqFX-LE|ki z_P_Z5zt?w4CwTM~riY^wJd_Fc0cce5#mpC=fz^|sqtagUq;;b^3Nf$>F-9=x#qk&5 z9w20B3^oF0bOPjU7WlwwFKFm85H{@UatI{L5%5AAoLxZ5KtrEdjEKR~kB~kmXh8Et z=r*wOw9ZzL6ZyA;seo?qkZ`wP(2K8-UO>Q$J3BxMLB@ebPWiXDf=mS+rUBvxzR-n? zT|h_LdZ&UCLJ(+R6*BD0zr7b^e&CCzTS3M^@=zy?eE?(*WVEdG2uPkK;Dro$MhZNz z8u})v8*~uo$u3yQAeh$e`z5Wj7aaIbpmR67Ltg}ehsdTphXk4H8%PX;M^ZtfxGjgYbV zfEV#Tpke_u`iU|^c;X4@FgH-*0wrKjVhnuY!jCcnITaMTpu=%Nz6*H42J=D*{1kg| ztx*R$H1j1WBEhvL*fp&uYqGNhdcg-Mf|?Ahpux|87ni-kZb6KS@^1$ZmIk~y$%kS! z+Q4f!+~cC)NQR8!f^BC2+1`BWKcvM14vDvq|Nox=?acOqhALj%ehf|wpvu)LB;duJ zHdr{S?u3kk_JW2*UTk^%|Nkz?I4ES?d@;zR*UCE}-CYD4;S6|T1GA666*39~whld$z9@w$E2-k&?y3V?a%{909Q%-5 z4(=CgfX8*J;7a}Zw}agp1T7E1Nf?~Rz->&#B*Y6ha4`o-&aYZvApl9v;85E72vo*{ z4x$EKO8H{hBWN`Nnt6CJ}^N0q_7PXxolp&^`_85tOMK?XRdf=81r9)Y9Cm4kn~M@ZlcOPJD<1W*fYdlP7^ zGXQCocjf6I1IH|4>D|Nmdy1`*dl#6=Ks21FbO5r;s;UJ$VZL~I5T>mK|Ejg5lR z2y|?;W*yjOP(cZ;fB3hD%79uXpn^2u#hJq(dB`ApK@&7UP{u|T`2O1j%WjoZdQIY$geUm3Z(WZI-|Nj>%AVMBQNP!4Z5Fr2}xIqLP zh+qT}fA0PN|KdA{_yjuYayvNjK!-{XtO3Oh2dJ)rwtV=vyUKv-1W?=sz7PPn$sj|e zTN>bT#|Ij(0gY>eRfAgqXpwdtJlP30_(e5BBYcb%+|K})QQ#)Zi}FUe;ovb=^Z{*1 zq%|T`!N*v^CV_h_;Q8Gbx-c~*+1*n?Get;ossWl8eqjw);mN-rJU`ZY05qBn8e;|3 z*4}V==ol+vywm_L#RqC!zrjxGzuDH4SMkh=KT`*y>dTZxZj10 zD)8?Q%xS$;!f$+_yBFN8fDYxT-~Ippg%gOdy^H7?f;zhaFJ9Nf!|F0+jj|d7rGxgB;dtXm`45;n-yLBtjiu^vRMx&_)Ys(?7VtJ@bELwRNNMT)$Py-)s1*<_0>mY<8=x{42uw!5zg%7tv1N(C|)RXYxR%l?~f=j@LTcLq{ z5H6txuD_vO|IP{E;nwDx|Nn!_KJd6<>CONDCx8b`!SRBW0>Oe{$0LOTLJ;9=gc!0f zYgU3XAxFTA#o(O56YyddjG+kbhl09Hps~{zLZIVBc|imRh+qa0|89T=tql103xak- zAPu*+g0ghL3p`CE{NTYEvdHt>ZaOcFla3YndM!2y?m4YxvvwD(uR!WcT-3ThTk z1P!+ay;uyFlLv#G;(PD=EX55^(SuAs7x;YHk4NWaSU&I@Od`}X^CG#><=lJ?_;F_<6vqxldQ z=m`23%2z>cchGQmw=WNPv411DR^@=+LJi6Y{}+KH5tNlcBNM(KUc3dJhMCqK`Xj9~ z^bcsX4(WLO{h*7uL%&#`s!e51zJy*>Si&3&PD^B z_rNnD@C5^k13&}wbqEK%hPQ7%yhsPR;&l_~zLF<_FHV9BERIgs2Lv4^13G*R>fdhH z2LUhEUIF*7I$a;UK9jMajgbM|BV#`S_IIc21Mmu#8{qyLXq`9c{8G^In-2nCd|nGy z6Y$~|IHiMR-+%_@p9H;F0Z|X?v%KJe```-nKHVolFSf(<&V%cH!N1-04X9)HBJjnJ zjbNie2iNt6o(alg<=^gl10;7P@Wq~mU^(!ZO#+M!8YuLA5%}UicrX&Qo8S)U5LU=g z`I)=~h8Ium!AZ0Eh=ui=7ZwhX)CfBH^-5j>!x`v0=m&X7=?^me4LZ+^?Dfya2SJAi z@oz_4@7(ytgc&@Zeg?D#^DH72Bi17yZ~gHHvf}u7>lY{sluA0l=Z5y)_yby#cmXQ$ z0<`;i0(j23cj||~p!MLOJI5Y@F0(kolf?iY#sn49EutXVfEP1XfWxq}^$BSIJ*IpG zO#Z=N=!&cxpxyc(L1*wVzVHI4QkKrvD}8NF!;3TE{whmn>j|*gFZRIr zd;b3azXP;CF0He5#$V9&8@*tvvv&zd`xMZWe?MqZG|0pjkWeFNiR+2~X`QVNAZ`(8 zm2xl02c5kyU{>Gx`~N>^-)bv}0oiQ?X7cav1&K8N1g(ST?>z##Vr42w7kHo-#OMb5 zKA;$ zd~snpG+a~u{{P=QH3AeBy{#Y)sLuz|7}z}(#0`33swTtGd_raxcJ{?P$NJl zcDI5e0Lh8>ixEx~0MC^|oEQ#r&TFBaN74{ZbOwnbIT2)3;0s;ioj6GqyAz{eP6V0Q z+Y0h!KyNR|TY(vG0vQ;(r-CGcUIfAPgQSo=AqDqDa5p#&A<6wKf_cy=ivb=uFP<-j zh6*Uj@o%3BirSzorWf&Z!QyG1t)L|M64Y+A&?`Qr9( z@bz9VjKP@(BU|hNNjL8W1qlOx3&@4gSbfn1$r)*#tv!GL|L5P{3!(yHp*IC=97kvC z22fgR_4)h%e?V_9h!fa76+{JfgQWsq+)@F@6Ue;~BVK60JpwY4fBRGr1ykP(&ToOe zQ$ZOt=mpOX(6F&U^IlMbgS!yK33%}UTug&Hiy#9KE(FO2z4!!6N+8$t;&Y(|h6~%^ zAqp`W&4r+XA+UEUsK^LAO%b`jPC&9d&BrPpfch> zS|_+X0F@Eo5&^om9h8Fj_k$Bs^Dhqm-ieS2^8H}Nu$?{(kT?kF2HO?zB4IH&9YC#S zhL$nip#t45T?zp&E9juawympkh4p`Onyj&HveF)t?2FrnGL#O6XY#OG^7N+ z=+1)`Ir5;^7+4!zG7r+i=xhaP1v>@^L__JVq6;QGxD#I%9_kwmXX0bx! zx4Wm+;otxNfiL{P?MYC&16daIV%>bGmq1)(<)Cf-fiL9Y%0YGqy{LyN2XVW>9sunU z0H>EJy&x-sUPR}h1R*$U!0oq#836Ko_f(J%L6dx71A4$`2nD{7LNx%A;99`fyac@X zI}hq$kk*$!|A8w8P<0geq6l0GvOse&BmefPpxP+t#j0swEuhwR78@*YtIh%m^0XeP z69JE{q;*a$0X1fHL5sOxLw1>f1!O=1&3i#bEkj9pFD&PQ%8;Op51ybx1SA*mqFEN4 z4{Z~@n6MFC_q-O! zVt6qH92HP)&3i%iGt`N|@;B(#uNQ@&<;$-j`v<@R2_OORItm7m-vYltTdRNm{Qv*L z`OE+R8P4JJ7AZB$bjx%kS_vX+{r|8DM%>jg(cji7Z4l3`T|}kqKLl;`uzX@3ttf7 z0V13~gKnGxRZW2ztFu7C1gdv}UPwbM4|q`ovx&cT0%%4eEe(_yKpFyGd;>2@$jE~dqMFQ_~Iy3`o$ZlOAzXy#(+XU@WouHI)pUT7*I$DzNmvrL)SZV z1ibLcfQB!BD`@%}p$}>-IJ#fBLG>Y|K|v3XBz36t3qSm>`wwnlA$t;P3@FM2q3ti8 zfEVmgV_w`#hq?|i5&b!fI%0hlCm|Y0rS0A^|PrUVH^N z9zab!Q24wSgN5^56mjrS8_bkXkcFyPQ>ht}4Ukgs#bmfiAU}fg6UdVRFRD?*vlzR3 zLE?cgCPNyr0nk$P#p5)X*Ck+nbbxDp0!sKQ2+e8`8E~_{Ya%H9f!4KvRK4&9EopWG z5so0j21MXm|C|9y^Pu)ozzZgbe?g0&z-c}R<{h8pvN3GSZO7vSFD(t|Q>J$qlIZ3xBA_7vGW*?uJwq5O+hZ zTn<@Y5b)w3OdWqKXm%Z8AtVm#p$7ABZv~}gcpRof#b4Zm8iXE)ZcqjM+j~J8VTln` z2nM~-glc-B09Ey3I!q)F=AJsMZb))~xEop-z260mbTODZM7ad6g!h3?EqHMQv?BR3 zh&Tr#PQC$6aMgk??3D<3kqy`Cl+ggX#n+doJ5VR+#pfhgkZJL6Zw1x&psWOHvjo1F z{sug13BJau)R}*OE2t1`Jy2?q!2mMWS0eC53ru^d1jN`-o^B_dfEPM&>ty)%_ktYR zda^`t7w9}H@MIqk$i=VucYwAsfX01a{01#1h7<(gaX0?$6Bmep_9r{_gFO#vk7djR zulIKS5ddp}Jq8CRX!fWE+`SJ49Y4&&zuiM6@WuB8nBQ{vwj9eyDz{*r&gz+9 zp-%9K;EUSVpcbJo=!{|>{_RdG0WVg=w44a+o(ig+gI;*Rw19>VUwDB$@Nyw&Gq@|n zez2V{ieMTK1ayOa);)0v*kha!?GVAvMv&kOR?zC~P>7Y_v&LQ+!?a%r>TU%MNOpIu z5CN@RKQ#mF;O?m)!OkX-;EQ9R^~~U2G}IqkK?2}@a%V5tl}kYDqhG9h_5c5il^_Dd ze=#4#ngt@Jz5-28LCoae-n2*rw8Ovw7L26|prRjSAOH4=Ai1CyDlj?zmb;+7J!3aG z00UlVL!5`^=T?OBb>K72K#iCHkg1@7*uWQ|;IN!He8M5`ix&;1VLxwMw!`Y&`!5rkhOs?ykTk(MGZ*e zMKH)cFLFWFWq^p}7ytif2snUB8J=zrgTNP;U>ZvuAmX7CK`&zAg4&>?073a9Ebzti zSZK(Vie@zI25oDR2zrqOQ;OJH3%2+cc%3mg3evi#fgmqsq@8hkOVk?KyrB}I6b{s01^fp1j)&r6G3U`MJGtu6?89;NLr_d%8N|MW?+!z zLEUEqdPVoNCosHVRtL{;KsE!kse>lpK+_D?Z(ew+L#8_>@G>wk9BEHr0F9xuFflM3 z>quY#^~*qWZ#z2@7(g985PMBW0t0AJ55!*4k-z}z!hzNy&+bTI01eH7*nJ%d44|<) z5WBM@fdSNE1F3KANMHbs-hjmGI}#W`1D7E2%8mpEP=5f#F6>BP09D=~c4kKc11LLy z*a;m-^Dl{IMd|S#Mhp6gZ*YLj#~c97$AE5Yf*#?An2!N3@`lX4fLdY4!96U{ zNh-&|MIVH90yZCW;_3hYFAjrOfB*mADFPM;4{_~c1+%BhfJzA) zkPFN~gb|3)1rZt`LK(Ec`X%VVZAks-%F*qi6ZnD$?uN`=Y!Gumt%MyAd%^9MosdJZ z!Ts1>f)F*J2GI`CglrmQtPFJ17(-fTFW3z`p8Ws+Vl#+X2O?I2h$SFmK4^jQ>*`$# zTIMi-&+nfCIz8&a;Bg?{7Z&KdrMDWJU9-|7o35L4$G4;E5rS@eo;% zBO$UnfB*l7$buS8FRVcpnSlsH5TOGi)Io$2$a3gxejrQG3#BM%tdz(?=F(b0`6K{z z&%%po(x4^OJTF&+suCu!^ovbx;Bp>RS3?9ILTZ+@&Q?%D0*_08W_Lj2lHf@u=+HAr zjDJ6P?x^t>XnLyFgnv6&3uvqfBn#d?bHjjvp_`{8@I@D7HWaF*vt{ZR(45!m9iSWo zx*7~bgJ<_xLGJB@O!B=50j-?IGWRzJQf=d$`>TP;gJvv1liuL5)fZnuONbd?_<`Fz zES=zq5%B7K(2UHB>mXT%7Z)ahLWHHW^$cWW?*NQ{0BP=T4rJ~ROm+6I0HsmT`sWvu zK}(`RgU%fwq1H#RNCXXjy(j}OpFWuenfU{SC^-C}BfX$7n#criNy7R@3%A=7-lpmOPjFvyD6Lc1W-eBjaC7yrR)fFUM#_q2inKCpW# zWcuTAH^{RbkkQiKRu;$v4X7UiT8RNNGN>Cok{a;Bg9|)#2HGk9_y7OyDZL6x`9z!V!*!O#DF{9S3sYYoT3`i9d*=y+C5n;6OMUWNgq2J(yh} zcj9;SWKMjJ4()>a9%OEBFUa?Sy^vlQWD*cEb@{>O(%z{cPEa>kETFp=#0z|Jk^>xbAooIycp(n=2*^nO?O+RF>U*bxGGS0JIM)We z_&pmuD2qBF2+2w>&Vz?iK%+zub0Ee;XVPChge5MJGkSaRxKJI#g{ANig_w-yLQrWD z)Y}RwM*?0%LR|Rr`)}}sU{oI{GFUoWL4Ct4h8JEiKB&)_#qh!k#s^KngG)3}%L!bD zfEds+1jOXu4{llW?+1?xTOZ`_1?{8E%K$A$I5`G3u+f&11I>F;x&~RkF01lUlK`)Mj=VUnoy1~m8 z0$zy2bb?)43|ct?npOY>PT-5IAZQ?$)MYV)*PlaHdxBS&=fcVzP?Qc(8CL=D?w~*5Nm6LB z-wiPz7Tp(Gq2_@d02&d1mU}ObA?wOwgX((`&ka86y|WeSfPQd{LLHFB@S+}>4{lI^ zViJ^e!ASwypa6+M(-i-H@aQAxx=!$nHVxZ z=d?im1Zv>Fw#oqAgTlWb-1dXoiAcu}VDshBMJ@)&dSAMOj{DmW9z_DDi^k5W0idcL zwBDH?RUFi5crgjI>>9i!4cgZ%zO#9F(AzqNVfB zR*?P|A|TuO_k&xV=pOB!3UXl3i-2Zm*nqe%<01Y7HBMpv^8oqp)J@QpHQ*U!m^f&{ z{>3KHl4f%J2Qn4pKafor{@de^>_3PSaAJX#8=b8n{Vz;Fw)5`?cNj4J2XbK0i-IPo z|3F-@|FRffyzT%AvUIj4Kr+p37$4N@%VKzO8pe--$nS>nLtxXpp!A9-E}MTLPw#>h z!>3pCA>~FuH)L(qi}R3rtrNTm2|T?ERSucnb$}}e*&Xy^0ZciF+YR;rsL2i11DoEh z@q>jQcsT&1c!y0d$HNQ&`MrB8$cLcmU9bVL>0N771HeUnH*9)W4rTyID{Oif)VK(I zF&SJ}ut3Ww(DW{-Z4vb1bOk89!K-;e)4QOeCGdq?4M-4WdKWbG_rmWwXq!A_dKWBU z3leDF3#vH5)4M1QHOTZXNG{;TlK;}61!2EGV_SPX5Bz=|v%aGHlYlYe_F zsO=EY-3w~*2lhhR1HI5@@5agCmIQcucPlt5pxT=Ef_#BAy$hOod@%{MA{jcp3l?Yu z34lvI(4@hOqHECUUC@-li0MA*2E9lIPat!2wq5~Gnu5rH?p{zt1-@AB1B+CN z?x`T5pcgFQvLDox0nL(trlY_*Uc7-M*R)RXj6pYKKD>J>D8&T5h(|J~6(kh!Vh>zB zXmSKJaR$l@Qum1o4A`e7lf{2u>py^#u%?z8~1=Y1dFKi%|2fUaJvk7H-7o;KJ zg*a4EH?(DO9HtgDy$c%V08j6NO1*#=*5EcFPXM&sePIn#3!B~rt4GW_L4t=Bs;hS@ zOd1po0o}czSO|RaYyvoa2fW~gx&)yP6wCqLy`az!e6bIz4j~OS1{BhPFXls~UmSxh zFA8{(>je#8*z_*UdZ@7w*QG=CA&dnDJv@>;pwch$p~fQAL5+d9P64V8Aq_PK6oG*+ z7@^WHG@!=3`0ojI9b#+~ob<~tgLl6efo8-&i6Y=dDR`9yEVV;I4VJWb!cCEY7IH7d zAlVO^szIp~63+j?Ef!cVfX?iJ!Y=5AFw6#!W6@G+IFb#JQt-tVxJe*CB2wub6miff zImo=g7hCEN{gv+J>{~@zF;KohFZiIEUa&${y{LhSD8t=@JiQBQ$OgQ)4q3$n4@-5JTF~?^$m2nf zX+&s5uYf9lao!E;N6_>xsL=tN-UT&Tf?hPh)GddpgHP{*yc7T}tzSgc!r}%pB@dn6 z1qDdJ3u~AmMo?8RRzgK!6Wp-UUJ$APF(nTQl)x81!IdvZz>5N?#uwr+_mt>BHKX|N z1av9G3wfA2`1CHw-S9YE05zC@J7ld9tWxNJiof^|H3&Tp)1eCZw?h_sKs*es>Aawt zUN}Nkz1RU0>34;OH)whn6fXe~cS9>90hl^-m^wtc1g?bdp9Af*|9S5J{}*3C#Cs6& z3Pd~w5f9EGPxLmy4S`Mca)2j#x!~fUiC$3656V=a)=S`vb?49~dO^h@>O}8s7pNcL z6TOf@c4xS;pow0Pb5SRHl|gPtp6C?<2|$X3UeF*vY(DKpWFa^?L0V?W6TP5TOyG-O z;9vz!^n%udgXdO3hjoA_dik88jw^vp^n%V{PzikTH4khis04%c9w$|Ug&^x`UQ9U) zpXlX)O!OXtX#q|2g6ip@7x6GHpgE=&iDyAu*g*pmF#ExddC>{e2%6{x`3yGEs{qm7 z4fZZ{qF3fD=m0s0m5_;EFPL`FL@!u7bfWiR71+Vu;DssBiQchD2Gh+f*JteiC&Pdz!y2-RuyQX7i0@;qSp+j3o_9Q z3huxc4=cg`4}b(fH+ZHy;04@0pow0P;oym0kdB}i{4m48>qTG_<~JRozAKT37=@VV z1bJ&33}1)u2U08jM3glR;c=q-T@ zf+u=G*)S~d#Xoy!$RSVkR>G7bCVIgZe>@4=JPXb&Y2D!cB(RCz>nA~}9uzle-Mt{S zu!-J%API2(faG%MMDKQxFxa4O@Q@#LqIUsE7`)38GSS;`5>y6&=iwm}y-SuRFuaiB zM4ITG%L$t31dc#bUl1Ou}#Pp9u2@FwHzLk!HWpxXw!eZTN;7X;nW$G@E;@I?!xvIlK>W$Jc) z1G;y?^-Z_$m*#^^oxWdQu$}-VY|xN8=o;+pS>T)xo+QxD1hYYFh4}aTf)0u5W$^-E zcKV_DB~z#G2hcPbj=iEktWVWOcZ2SE0^QE}1$>72Z*X-2x#JCLdw1vukW{zt2Z)Pb z1ibhPR>cE4F^~~{U1zuJhvpYdovt5VgdGRv*I={&DbJ9%$PB1?Y~_ z9nZnD*sXs+<8{Bli|&0DK*yr-1ikQ1hsEy;Q1pYgUt2(gKO;`}#Ur50lU{%?>3tFO;vZb$1ODw`>pm3Rn9CtoBLJizc|*JN)}y zCAxiOdPN*NLvQqg_d0a8T7ZVl8D2z}g6sxuxA+IzRO$Nw`#FOA`+e_NAFQv)a^T+| z`USMr{)YCUfNtL#fiE}^`J5X%y_Zx4=7GTU!-+T)c}Rxyg%T}GeI|0 zGNyrU=>o0l`2rco2m9>{|9;me))(p%`L~0w{Ro8E0LuO^4q8Afs}k5bhhQ_kKxQJ8 z!8E=|f?Op7a~asB&4-ve!Hn1K{M%h$1Z1(i$W8%82nYZE6TMS>LC1wb6r^>xf=maU zCJA!*)8Ej8B+@#4KfJj98+wXwT4(5+7bky%swvkOpzziKh4+i=FqiVT++qM<__uv3 zNG9mT-(;|DP-7u`zW4Wn;PMIRfI6^GK;e%RDwlj=p@P*Xi_Ks@F-hwNAMgZq>I=zyI>C|hf)nJXm-(QrYM_(j-vofp=LE+|;ETIS;P?XdQ(k;bgt89= zyf_LG@Aef)>tuX!9CSMjBP@&mgoP=8OFlCLLl#RGONK!3G=?k(NPKUHm<>O{@J7Ik zX<;D0DWr9S6Mb4|FX&3D7X?56Lr&ZVPXOKkAL$G}+XTEL@&@FP_uY^b)!7QVZ3=cG z3IFyMQP7FEkR#8sFEYRdUUb9M%YaU^1sws9*4fMO53-GXDu@A{5e6|qON&88*$;=> zT>kxFW!<45i@iWe4Wt6b?d}EHANXPoc+QIl;vD|{U<3KLw}gUS12uww`xIXgKd8GE zF@WK`nC!q6HL4`Ne z5$Z)SO*{}yAS$RE97F*xEOS7z91tgV_k!#UeDMX`$pzWN0?`7Z;0|PiX#pwj1+QNT z>;*4Gf-Bh!nJxfTif|cFkOaJ#iI92W3uZ%ur+X?$LC}i|nBA^Fz_}O}mJ_m(9Lm3a zD%eS&GXVen{~z!oDIP2fIvNn{V&5O2RUBZSzHmd6YXu1hWZAu_MUm+31&Ig3+;QM9 zs3L?047`2-xiRp?6>z-;KA;wKFA3NM4v@fy1SJ3VUQpBoX34*hfLj6*0bMrs@Be>L zoPlfum69Ogz!wYSz#ahSt)~z+G@7AyLjxLgXe!76Sp1y?_d9t4UN}J9)a@$*%7jj! zD_&mnfezLd0UfPw1mZ*b4R9Dju>xH1#hhL*o%pI|~u@RU`t6(TEE{IPnichORZofCanZp2Xucd%4j8I3MhjAQy zEjhTAR{Hh-fAE30i2M&d5^Oglusd5pr(l4UfC~Zep=%H&-Mt{Gz!wJ-K;g}Uq!QdC z0JVi6#}0K*1t|=AF#}m)H`w5S7s=qp1L&BOGvJe?__zC>3CsZP8|V&|0oTul5SIkJ zh=Ax1c<~=B!qV+41B#%9U;aaiGw^9hJZarL0%@J#`?p`Tfv;Hs?*R>Z(Fx9MAe)we zc0T<7{~y#yToRbY_hMfR$P3_9n8o5kz*uz7f)cE9nk%yxVktOA6cKO^@E%{W5K^V8K=#Oq+2>ZpGXt1R-0=j+o1ittO zEu3BVK+eUn;NQ;^5ZE2MBk09rnADEfGqM=LP4OQAFKl7nI1%__A;c*7g~u-(z~u+X z`Ahgg7m4zNt}4#rdr<*V2+DX_j4yt{cn1Pr)PZ$?LU9fMcHcD+n>oRwHqb!K;^W`$ zx+LI*2}~DgG!7JgK`$Oc8tk2}J0PQot~#JA2v39ObvXjS8>+iQ_XNGz2^D!E0P#|{ zuTCf9i^-p06B3~Yplc2x^T9BEzB>Y6G{W@VfL6Yt2AxbVqCfrr-(0(cfxiWG?rXQ} zj(`^$;Ishsx9<{&FPtH+3wWUgPBkFe4dDC7mjq_r**n6;ol#+ zq4g4fFX#X`a1g%e0ZW2)gOgYW=qBqIZs61a3bzftQ!_yKJZ8!B?{{6&e1JXR1t(Yw z__Rv!MbzD{djei;0nbQr1ibJr0olwG@Zu9V)q#>%Z!gG*KyYBifU7c)$#Y((gPj1e z@d~`#y#cBmWMk-(=0og3FQ!L=%mmMwgB=Mr$q8oTP4J8nPp9jiUT^^eNqV2bl@P=t zO{gcJ@>!DL#2E;4=?R3=7jHoO2cLs)NcjyKIn@Eh9lIW^EoPVDAPl(Q zEt(Gs1imPO2!ig#1s{d)dL!V4T?8~>PXxYT`T!oAPwRBO09JD*=*9c@Fd@iw!QhLY zUwA^2IY?m!0|#hpN$7>37tD}U0V|p+K)zD}4aLApVIgo1gBI7YQg|&`7fZLV3aCW& zfB*mgi>&wm|7SD^f`UN>Tn^9Fh6ZS<7#YG@bvF%UURrnP8(f{-sUT(6r|Jtp{dLzbpi>ODXrBn| z4&4&;qLK^LOyTKtJ@Nu{-*dO?fq-t`BY`gt!W>>I#=kxEO%VTf*DnDtq+y~Z@}Tp= zjs(7#2`<$+I$aNdFB|9#{qTYf# zo4_yu%4XXOxf2_to^fvi1E>}Pjbs1VgW9e&0&PAr1Q867?MH_3hGtNv0f-42NQGkX z{vwd;!h84PY2SkOH-a0l8138JA)q*irhc#zT(qk+PC25=?fF^q3@vT z7Syzy25vF4bh_>UCmPVPd7z;`-#^fyu|J^ZAn2^diw~?X)XHZu^6&Tk1HO!i#Vep2 z)Hr&Q3JNBkPS+i;k3*V=pz{;ufU2#6(c(mBsjC6O4Bv@P!$q6iVxKUBkaUbWISr zS#}UI#0aVJK3t4mON-qzhOQtQ*`!1GiXS{DTxIpg4jSn4nf2v>kcS z9~x9AKtuBzg23&_oEorTzzb$@6BKmcG^B|DYThBWBSj#co3u_>)OKVKl8q4MARD3W zNPn1(-~%Q%Kw6}~AhYHHFD8PUpy=($)!>Q=l(6T##@>$Pgt@cw!8x&~^;p3*h@) zCcIVwHzPr}E`gewmwmwz%fJ0Z;EU-`VeLwIQxkMQ40w##6}hQ-50awMnwm2p(FnvY``L5Z2Uu0@^b8{|Q=CQ%?~Z<|s`~379BqQ*$9`!y&i@ z-0cf#YVKEnYA-=FHLF3Yzy&vQG3xu_MbZ;QQ!@;7!%Qf)rl!pkw5Fyu$UJhJntTl4 z2n97YnL$>rZ*tFkeiwbKJX*}X=?8G z1`80;)ZF?SY8bq!DGW0VoR?byUlhR&Lo_w#frlrdl`X8Pc@tb7gNiEDrshXTv#b-` zNCY=u!LH1be<2Pr8dNd7;D)imrPh+5Ecq8dyujW7OTU4zL51XthDWGvQG=HtPhe?_ zeuoVFb-EtNl801A@-G%c3<4PnssDUU0$<3%EWZ%+!U#!${EHG8??m8>3>f=D&5eR9yLfVaxma7~j&;wq$f^#!Z zz>7Cv5teRW1yH}L?;+^C2N1CYM9hEq|37H_k^|I9EdpKO!pOfJbecz)95kcATdtuR z;MS=vLIT`!g|to~P0@+6a82Nr>#RsnA5#Y0;@t{KnBZy`($s#D1XErT0qr1yo$>ks z^c;H79$WA({10iJJOVE+KR|2k_(H^Y!^A=DF3|KIM0m-A|NkdITCNGl6Bu5EJV$N0 zE_n`Vxq{lQ8OIUr)=S3`?bhSR5$)E)#}nY~)_unj?be;g5$)Cu$4PIuhIYRpH2)uX z-1QHrbql%{s@tP1t<(3cXijRvi%O8OppF=r{{nQT;)_&}SOSQM1`%N(A`sML z18rkB2<#5!33^coi%|Yn&^?)uMR8$)5U0fiyfB1W$=?dP_cMzTbm_?UK(U|~&!u6G z76Y9M0a`4?68PdGOtiELbkH?ujhtP;i`OvG5*^rPa=V}xSK*?_Cj6Iznpf&(}Sh;WF7eKrTtE2tp`d)!E5qB-s=XP@!S^=I;Nfn z)XC}&{gc)iSoXsD-~ay;nvbwpzj+bx6q2Sukp;t{-EXkPpD1XOR{*r4fCcO_P}Dty zxfT(1=iov}QMVH=h!l08bwv|i>;o;R*a;#)e9$Qh9?;0S0`n+;E9lx9jL4Y+GnBt| zE2OUqUQ{L)^uh}!QzC^FIVLbs{#MY652Oe}s7H<a}DuYDT(#O!KA|n5x z=g&Y=*VDk%D`P*OyxWxnVFhY>>FxmE>goIE1+M%E4S4X$Edej)NkGH1BoQ=f;>#2G zq8lbuss<7QEvKr03kidSTtxz2q{4(sG(fp>KlCQr5)RN(nAQWOLeQa7j*xR2J}p53WuP#Q~u8E(nc{pw)~oj6ix{_<-^h6T|?AfERmV29!!> zv4DKGed0TPP{uETNtB3#Mjij8bvA;pItHy=neZ}-5wwb;JM<6#_9l>Uz>5?oa2ulA z7q0RVD4X2{5ukHHUt9)lzhgw!A_%ua9p-y3Mv&baa0$L{*FXIGJH9b7Ftna50VzYW z@}d|lkj%S5R~=0J0#bIVL=)szlnnpbmUKo60#MgBCs$4n-5w{JK?now3hyp);R$z zd=Rwp%a`N0BgEQ6pmi~?l|k(ZxDwF%8&LJ~C#|y!l; zB0%A}zXN1u>&a3tkiGkx#EifpXah=K`vb#TFO?dCir4)fIjtv4pjYjH%AN@V%nS@K zxlAq$1e zQDJC2vIQjM%ahhUaULV+Y@pBwFSh>#-9EyT*4+US@_q4Q$xqNCpimL;immBCLBnyb z4+6S+YmcoOh}&jBpj>AE3{pC2?E`{Io)SOn4#-w^O( zjwhJk3F_8^7E#t9+Z_4=WX_U+EWQ_8VERsg?q@WE*?b}B#V)W8&;ZN|{_UML;0q;~&1<^BBX%1CUgWz%HEjSDm>UA2?q>nH_Qj{8 z;NDqUrz_l^7lAKyVD@b24&4y+qSqay2o!LjkbDAi%!|Mm-)+F=rggd=>7Lrd%)k)T z-P*y-zyLaIh<`gc9)n&?iUCCnPj@RwK|pseNCBu}%fGz|6szD>TA*nkE0{kn1a*T_ zh1GXZf)VL1i=glS|3mbF&IN2*!U#H&PZwFA@0P$9d!YJ4dD1$;YF2g}i1X!e=>6u5 zq!*<0MF>bQ8^|pT*@qbTxBIZ33Cx%d8e5w>0TiJxiXpq7v)I5R`UfAt)XYFq;}25< zzThTf8c3=aq&@J32}G(pR3HdTOu7mLyqJ`t%FuWORQH08sKTNMGytB9P=uO}FjGgV z09tx^5x~vB(0C++8C0scet6ON_5c4Y0sifwAA(+(@I%vGR7ZmS--BUq{Ij9?S9woSl3Iv-9j^64o;N+XdoW+#I!@nJL z=Ujy)I7Y#_&c+(bJ`j*G6Dhn{CV^r|pc~}r8&ce$QnuT50i?ry;aUR2i^tc&9qzd1 zBMH`TUYOp16zUT|^E)@LB{2Me-T|b39ns&Gx{kOTi2r&5!yc#_j_U~wJ|(HS1t|=U zz5(%`E)k#=O#%Mlu0ddqTLeQukZYJrh+A;H8)B;hto~?x6T`^B5EkCMcL`_-VmP7} zK`c-Q*C#(-y!#9q^ZNp-R5BPqSrpU>ng~kgK`)%(;VrvE3_Q2&`s2l3hz5no$qX+x zegq~$jiNh1RTyaN!iyHD#)!!b-M%`3-Ju#my{>lxdVOC6g3}hCD1x{k ztj2~+coFo%0Fq8ST^snfyY>XUNPww4 zfnw;3fNtN0z!yeVpb+5cbZvN{{s}xZKB4te4d{lhp4J03B9JviAcdWf^%I@04c(zF zLEWwm0WX$u!}1!a7Yb5z1Xl32bcc$hb-P{xO$@IG9SfcX8biAh_`=8xWFM$ryz=rC zXzl&fHQ-f+r5xz_{)P;wWC67+z{&6mcq;A+bSmx&|NhV`ps6_P3$+UT`+dRuwC)yP zkZEb1Euo{UNa?Ri!+E-JvQ$pvEn#rWb66AhRVh($t{s zNpShw!wPa^;ENrQRtO|LoMK4pY~ck-yl4QevjJ%VO$~w;?Jff^^X!Bu2dz0z>um8| z0a|UkKlDehi_pK$R!|mh24`f0Vy4$@FKjMwGE6W&**z5`k=EHG3N~5o!~g%Fl9~ZD zR{BEX11OolSm+Fj5SC8Y25@;fy&^OEG{7JpoU8a|90OgpaQxhD2wlf4MZvb_5+|h)c3)7 zCjwtMfpvfk`M|$Fw4?bD3#hU70g~8{f~Qb90$%KaX6sfJ&}iLM5E=C1Iyh;9Ec@_6 z8nm28(+0Fm2vn<_VTYx3?ToXa^EpA2^Vy&U-QZ$mEnJ!h9EdYs?0yH@VgX4c908C` zC4s%63xaxEL7^1zVwO56ZHRRHas>8H)d850*%A06_#LQ~ z&jB9VY+45@n$T4|Gy(-VC;+E`3Z&LcwaVbQfLH;t5@H3&MK7iVf?Ox?+8k8kwVtfg z=id(T49wyelOV={CeXkx%K}|+8T29=q7l?95&;i||AMGX>jZ792>k#nEn%x#e;a~b z1zp1$`xabMK~#ZCOV~1zD==l?aecG5ptW!u{QDtI)feAbLF@ZLNgYwFZGtXCY6UHI z>IN@(3Ie$bGC-dK&U7pRFRCF0TfmDVaCynm>Dtgc6?7Xkq$E7U4l)^S#zq~Iv%nR? z_RuLouqi!zNK+Y9k|JUs9LAv255QYjcp&}&wKYH`Ei~l76eL+_3xWb(p&PuA3$(Wv zGT-rHGdN+h1iUx}u_WNdL3nl0+Y54VV0UOk&dVgExkNntd-`gO|>Y6Pg00xJI@Cck(Bi;WY3FIKz+Cxx_5 z*E`^?N*_QC0M`%Ds^|mg@>0k)JpTTD44?xBT|a>8ofakr2GFXS51^{^3IhWJ==ReO zpy~-!^?|CV5B%GGTsZaW~!e6TW2Mxoeb-F%y(E<|Kx#j==|7o4R zPe5(T&?n7@SkgK}pMbXHHU9|U@4v?csv=&z1b0E8J1)VY`s0P`3-IvD6VQ6j7ZwnQ zKWRNss}9~v1&W-&7ZY`%3H}18V*C>DVu21=0JIShYz#P@Lq92@9PCjRP#KjK^nz0lq>3Zp#R5o|A>hS!un4$Go$wyw)3_D(c{Qf5Bg)+p+poUR5WP{ra z1*oOn;O%xnFBrg~$J5yg+Lij+6KX$HHPm1vTQ6#X+zf8Pb%R|L@ZucAgn$=Y!QOxx z)w~yEAVZx^TDR|$v`*g#FSb1eT|f#+E}(mLyL&+)7WkqMq90NqKo^C)c+mk`#`BU3 zeCVv}14yYW@GODh#rhNAQWsL_8l40cx}c)V`pt{4Cm@9`Xt07o;#mR%D7k^|VD@~L zzyL}zAhzqX1O|{BKz(eRXGn9=iAhEbiAjc_O+euFk)Zpf!h81?fV#se*vrF`e~|ld zv&8tfgZ5y%{DVb_(D7D~d;=_9#ABT1ii2m1J_z$D|&kaK#jiM&?BJi$`kNH5h4lBsy{$QV(1TO zR{a6WOU*w7Ye5$~|KQ&);_L8a3IjN&cKb?zH@&=YhBlS=gEnHe_<|a~FZe+&dA+T7 z>K0H>EK9H#+$sk3Y!m`}r-IxT^x`x#sM{j~?umhI_5A_uiTwa~Q}(+mSYN1h0`*S# z_lNlQv|cJT207>AgU(h^fHs4J71BAGe;C?10ZD*5Cm?%Ybb?moyk17Y26>1Lp+7(~ z6x}=?X`MZxpa6Q|1=fBNJU|ETt-X-=1B;s)_;5gXizrAnXkqsY36Kt4!N|YgSHb#V ztu4fJE}=(S50prN>`v>R;tMe%wB^NB@M+zkb!0!%x_w*HI(u9}axeCR#aF-V0@X{~ zLwP_^Clc_Y?KjLtB_Q)bM)`q@`p}jaT_7#|`&|{9Ux4;x!^8L`BW!!li7P>}NP z_i;VadJ^QE&>v~tEnxqHedGo*Z6 zMFhAV&m#C@3TSl=XrF*W(2F0xV4>rj#ht~O<&d!;crpWSBUd09dGH}acc@HSCkxjL zN3gp>K$#DeLl?nKb<4 zLl2a#_Bw$96fmInoAm1h22ef(?aUB=oxlLfa3FEP*9iC9Rvsbw}b92GE%Spi?K(x>-U! znm~NlH~jm3pR}H=bSOENF5sRVj83o*XatnaQ+SCn2ILwdQ6au zK)vuAK`#p7ie8I?+Zp_z8vn&E@TePDoj`Z!ji48n5U&J4hN-ocK`saNvOj>DzrG(p zP1Zl%uAnWT0f8@aRKd~#FPI^^I$dw{h8_q41wyy)gTNPez&$daPS*z@Vel%qZr3XT zFOI;(Z}j>e2+ZOF+bj?6yYj#SaRb!?FSjPf2!*clzu*KlCRScQt zg!loJMU&u)Kz{Ij0&3E{2zs#^((VAM;|HbU7g|u)b^Bfje9;TB0PK5m?XF_y#nA6yCcR)JETFi@kj<@E_W~26fpa0$zm3fny4Eumq?t zZu%d5%RT@0UI|d6_{CFMWNFYS!BiQLI$n@EaCChEwUB+$&$bZ(RbVH;tC`?tRYI%+ z#aI^0i`kHj+X-&IfK7t8$PU6=WX-=gYF&C;L5>EE1%OTk`q9gB3RH?fcbJ0?3;NM3 zau7To#uE_OJrz{z2fc^^7iB;O z3ZR+Aw9eKX(DuUZVATOxGA~r&;Q>1A2vjCQ18NRL0^~W^X8spHWMF{@QVg@~MIkur zuyleCZvh!G6=X>e_j7fcEuT|7`}mhN8AF))EIvLTr=0CcMWNF?Y*Bvjm4+dNyekDpaB{-=*@tx2LfIcLL>uTa6keF5@x-EX1iW|!Hijjwvo!*&0-~RP|5Ok+=*4gFz&;1`ye#kuPXRB= zAW1*1vlV0+|8|I;?x~KPZdgMG2aYR#3SHnympT2z(KWA`OmWaJ0IjA4Vo(eTu*LGH7ih zGi1N@YPe3&5kKHm3NFCV2MaiA-C+LY-yV7ebdLZ?1E}Q=x~hSLe>;m)z>B+(Xbgb1 zcQ`=Ooh`kfUdxM(KSA^ROM64_1VIN5Uc8&A1sbTrXR9j62>$(3A(pxRV7|}|+STCW zdnc`vC*Xw-*wAAy1wlijmq1sdg358%AJDX1VH>z+g$ylS-v;W&fodu1H!o&w zgH*F=6F}$Dl>C5<;R`S@Fr4_2zyPwzg@J+L(2oQLP*j1&^IfSh_)ry|pcm_5LM3K9QrSSuX2AElz4-q9|Nos3f!;l!g`Cg6 z|Np-WA~1CaNZ{&sPym_iNCz+Efap31(ghKK=-L3%1rdPgnh(+ib{aT|p^gkS|5B=z z1huVqf@*fq2npz1&KKDrJ+Ci;lJrzi;R({-x&q{e!0-S6zwr6~|9>y|a4}h$31)GEFN|1hV zn*bDdpvVMmvjJZq0XZMX_sxr)-$2WVKqK)l)`1KI%_e{*(!m)LqlF=1eW4aq27(S_ z3;hDQ>W6t_UnTej39TP1P@Pt11)~SAC&yP z=Ry7G{jNXKx_w-G(mH*gyx9L0WKrmogO8YdTS7s1%7I!tPkN{Lf}#>MQuL&^$JOEg z|No#$1*ELoRRDbKT&oj!p8=>_!N0#H6r`l}0DoUPXoYAugh zTkUsV{Q3eqHrH1Kv}OogMDlM3b$%8LgO!4`fy4jBB$&X7z!%q^LoI~dWuC>6#mv7w z^hwYQUx)>u7X6Dvh=w#!*KWV>lYz?xL}w};*Vh1#2d7k7lf-T)mO znAYw41w8uB0aEo6w50|V{<}L>ZzC0JU>LLq}5(M!eqL z?JAPi%>m9idq8WxE~Ryb-g&VRyyoiwXi^ANCn3xLSpq9ZYM4P2lDka6 zfC{&gPoVYeAfgLIw1S8R5K#?UbH)T7@qh9DDb#EHE%!lHItzHq+MB=^(?EwT9RW|p zyf}qWv!g7$&s5?*KM)rW4kfAD|=~|GR0$%vT^pq6yZ-*oV@bab? z%V4@nq9Cp6{k}hXr}%~OhG^G|Q z0^WLQ1he==;EQcAeWhxk>M`_9(2K{9p&l<4&H{}Zy$N`c08>>0+4!yS;vQ(l(`(k3 z$3R6N=*$|>$qua`x4_GnEY=qqTft3BP*L$>4?n`Y4si4M!AtJbI(_fF=mr@H8VmqA zq7UW>{+2jMr*l85=`V61=7Hv5`S*j93UYY~I_(ZL7wr3``K17;bODti&A$Zd46+0= zK-DVj=2p;Zq8AP6Aa@FY*T}vJdLalm`pxS-{QF(Mv>vDn;|I-_LKA%!e6f)atOZo`fTrVHFM)P7f%edY zn-8G1c7ZS6ra_zp8r*pk^r8--rPuWh=nP9xSRZ`I+&je=RK0*&p&$`Z=!2>lP|5(c zPe4g_&mYi1bo+ZD@>6_41tMteUBC+s1<(|g%*zZ=M$>)|sK&cd53_{ZViwcBMip&fQ@Iv-Q zKWOb2tVjcw5$NL&63s6dtuNFXgKB&J{g5nzi11QLP|Wm#3hclaOuW$GZ3XdPZvr2n z0X|si#dTOPwr&BJ(Y+AL_07zEpf>CGf7T~T#52|~GB9LpXr055A<{O7;RRDKKST2o zo)=v2{{Mf$3L+Rl#P7HN|G)SKB0hqMHz49Uhe4IWb90E0$B5KPYX4LC=DEP7E3G6P{` z9@I6xAj!ZN`Y<1rsDQMD-g)8s8l2fc(okc)5ym1ld!BNF-47{ye1E{3ilCMwq)P~j z=fD?pA-cgu_eO{wP@;m=jUONaX`QVbz}YDD2S!!|Nd&$)j-n8n5vPLWf?jyT5=iSB zupzw=3Tz}wc64I6Hz96{sKdBIp&U-~y+;)|33LQ$TA#<6iy$ z|041gr2RG(WOC4pQ+HvB$rM!AxxNW_p$->P0!2I63D9-C;6B!iZ!iDhbS3b`3YdKtf?n)_sDaoG^6PJyz=a@i zM84>PxHPR3T9|_7275sk@b3qQIPq2T=S+w9jF9QQQuWe^7{l zEe?3`@ir_L_`$IVDimMXfYyZ}C43u*^T7!pRFy+21T`el{b1u-4?vp7ATM(u%Ys%8 zfK`B+#GoL5aq~Io*bi`j^#^KC51g++^)RU50M)~w0V+^E4C?Ov0FBjx41m=1izUF7 zF#qT#4YjM?m5S zxDpva&1DdK2Uj9PahZQnN@@{_3Q^+xJ=P~mlGgdvRw`GO1tX9iFU5i+_184pT+04@>5qQ@`~V~ht)zXl6AEaO2{%R#jYq_51!1S@~;z{i7Lf!0KIV~ht)W&|q*RaoHg zf6)XJI1%{b*j1>7=;J}Q5DP%n%ZosW1~SKkfzFz#X8#7gyjCphhOBbp|fi z`SFbhS%AlbKqSP?8)k#te6o8gNQlJoAQ#YiO!gqc3PhNK2m=tI4I?1=}2*X})L>d`d^Z;56 z+<7q_bhr|(at}5#^bp6$P}GC}|6i1XhyoCi4IFAPDpWU=yZ z2agE`zL*I2j5J6TJcJnZLK@~=u%_4N`S*jB^Y2IM9iA!?&-egpj&O9$VaUkon8Wbm zNgbp)0v(A;g_+IY0$SD%uDn5x2z=pNNpO8m; zF2E#9iuqBZNgXZ`1wJ_z)I#iqbm0Pf!2?*JyH>y_bLsp8M>Qzhz6hv+4nKj$up!FR zI>F-wFTUPG+!&+q;`u$$nS_k@L46JIXckye;EQ~?y@mYyLls&t)n&f8eeeJO7uW7V zhM!zPYr()H$uBnlg<5Rn`r|qS6x+=Vg2e|`2 z{N(#45H$P*83fu688i>bVtui45wt)%5%|IuX6uEZ7YE_yA$8h#Kt_VbJV1`%hp9je zKcSlb;_V->FTgnkI<&GMGPKfqiN6mv{N(zj`Go*PjqjJ{pUA^cNX>M{P>?&p!%rZ~ zC&7&d4?lr>31Mix1U*PgJ>Z2XE4bJSc%cJMzTl!|386$KX_=N`3GwaI5$I^%DylcgJoaeRfBUgytIa82HzhqUf%|#`l+A+a!@1vN5G4f2&eUehO~)~7(jS)kjoAhsY4vVe!PpraSYzo20c=EH}xKw-lHi%D?5 z1lngp@gitA%M;{9h0Zw)87-Z27+x4xfxY;``u6|-FU&xMA&Afc5$Yg92}H<(2ni4& z3?leIo`-}q+DKN(Ie7e_jbue3WY9*k3J@|lN3vuf-Uc@i41R)x0JJ#dg$j&~K9a?a zka)5FEYwlNj%3L}G{eVdz@rJ!k*rNWz_x>02B4}6oSVTwwS$Fy=`q9|ip;xK>kw`hZ`LX2tsg{kLn5d>R>b4&{qE1+(% z@0}MKH^E65G%O10n1Tn3UR?eT^&Yt1gVuV@KcU$PS~>nhQ3T3PTS2uNY>172J2-a* zzG#D}n=x}Ics%u|^`{c?j5JUJ+yF{|5?yl`UTi7{CqVxFU<+Fhlpsw4wA}z@X~--c zIK2nFFoqb3HEP6Ra>#>>P9QT7^9sf{paXdz?*_g2avB;(B`ToUbiMOJ=mscMARd5> z3J4&K<=^gl2h;|76Zm4)H)ueC20B6!y?D^j8PZ7FizJ9{aLO%%=mDi%h|yai0`Q?T z*B^)x9LOj(ba<=>O(A$(to1;R9C+}Be|s-z6fN)tD=cw>$EIGJKxLtZYzNDN=OkX- zhB@m*;EVYX@w85`F8=-C@ge^GU^`I8-nu|hm(VqbA>#xn>b{qPqYe~st)P*f7uT+V zN^Nj%fsegCy7vG7i@VoQ#@_r+!9pEA_O|*YObEx=TNTKh(rdWJ-m>BPagDuMf($SL z8Gtc6* z1zKr+=M??1u6A3P6X z4QeNE1$ll4$ny$4a~NLiDF%BU)S`fvmR2WV34kBmO#%o<5jTipy$V2(pKfzrKYWahkDM2q9kHb7F37b5DjH5><T{xcmq28qvSPS3CP2CsuMxO zcA#-G>o+f6On?mAfyV4q`pip&LMI zTsJ`1zHQ*&@4KP-Cr7PrmH_|$P>_}ly*wA-`)mv$=>?>!)1|lJg&@eT*ZX=yF9h|1 z4s8j{0(Fl#dVO~U_CjtO>2-Y*&H8$`#Y&hosA&c2gmORxKphxRfP$86fj8HImTiOPEWC={`4qX9_trahpUI4iftSbuAdhK*w@_I4Y_$O)2VB?{iD){?; zf~MoZs8<-efq%P8=#GFF z-4`GZ+YT-ne}LBCq9}yK$Bw`klOVnZMOIp;OX!XlAJ2oLp$l~W9O#@jC#XUDeOGjc zg4QH?rFFZmfTpz-FAkpv`H&xUfX)kdh*4m-@IzLJu;AC-3bO0vd(iE>Vt-*<8lEU7 zGQ7Cm1J1{g(f7DsP&Ni-AL}N@Upa|Nnmw zTVE-Wq2d4k|Dbi3I!cKQpfh1Xi<2~z5*a)V%@`^SL4)ndpy77V&^j1{_rD2%$J3E- z>h5+`fUNlW^5WDvP+K6Br}a`P>r2pfW6j0X2mgK&cjV65i%>(0Dx%@ZvelCjORf zpgCXx@G0crW$d7HI9^PLmx6=1aGPZTd4xE^7V00CiMLi_`(@tCTQRV-28a4=ncYa8$qt-L38y( z@Bw%N;8WGU1imOjsD~UF4+@35FjEf%ya5GxU`?uD3%aP^zla94xQgzpah zlGZ8s;@BDRA=U!cZ(ekFK~g0+^?=vwHow7}e!9-!NI!x5G1AXJxb0Ze&wB8&f1o3( zVClyet^qy$6rVw)pXD%{aHOAbh`F%z^Wqge3=ruj7#30o0$v=4Dp`qUxY`$DCc@QgUc$o; zDgCsaf~Ozv4)pYcINTbt{+kdV>3nU{_G4KeB<_BD*#0eJ?B{VezENQY-;a6+G#z;o zTl?mC>w`a_f3&wt5nbwn~{JVU>i_1gby!ieP(mH+v z+I$T<_6Xb*z1S=UTAx(YaG1A8?+yR3x1t4WLK3y;ETVzVR=fy_)>Q( zXxl|vr$9G&{{{FObdbo4c94DG4i0F|DX5ahnDKf88ObVpQ4Ky`4b&p#;NKqN_z$$o z8N59dw6W_&FWf$N(4aJU!&itS6RM&NxFRK}le$5NE^u^%x1fOUKnFYP18CRM%Y1MU zxxRs#^#^1YjPoz(g*4nST~N^uYR_0a2d6oRFVi|1(aoI!G8bZVZ!ah?wGUqW0XbdZ z$&2d0pkad0H$hnpy{!SD<0oEJG=c*jwB{PLYOV=%X*R=)CU6IfrL*-9bU`qVW%y65 zPt}5)wjVME0J0C(B<=16=?#2w96Sid12O9LZtzm-EXEfTAY%idDhj4j7P6)~;Drh} zU$JzD8i4u|$3O>NgQ|A$d5=?gL6#tSV0#1H1E7^a5LrgZS;F0rzyewF;{Q`{z=4J_ zvKT-suR-g5K&pFtTtPt*_#zi#QtwodXeT(nKrP@_575B}prImA{n_gR;u(Q9T!9xd zXCGon>+WF%X#pMC07_pNy`3kZt};l4^&$RV&|(2d{D4kCgEXi>wH*Q$f;-vqw)-uFi!B>KT?V&xznOzUj50ViYMABd;`B{}~6 zf{?5e5cuNL6L4UpK@Q~swF;+#4rvK`5%~-z0lIJ*l<1&G;1q!S;E?w57PxNE*-rf1 z!B@G1`uHF-0$!*>90CgI7dOF5K^w9_a{Sw;g4`DLLJ4A8T4$>X$gSJK6lla9BpvwT zF<2L9qZfz|)5X6X>Xs0&ZiI9%$gQApdJqkA2S``I3t7lkHn2MwQA`AT7-Ta@F~|=A zFCIJwdmOB|1;z$-BEX>;@WKJ&DbNre=u~|M&`Lf~=>=N<4G&gn7Vu04sD^l94?bBN zylD!w*AbM&Ui=21eLWSFgg`cf5>~(qF^Fx@sC~Hyv>%e;1p}l%0?9V~`+eUuztq5) zz}{FNtkujg22V0VMgTz81;8?v3pi3?S#W>%R8Yyk|9{3=7Vxf0kl8^mytY9T zdWjC`mdX7bttU&AKxeEffNtHn^8<7ax<*>}RFG;=TkI5g@0M+b0~6?oXz+!R{M*5@ zK`-yADyg~Xw+aC}vviJciLS5ekWHI!DHz@_aFs*@>K%q}S6K7iBBQjptgZoV^ zovlAWn=Ke#=)?FQkjk^PZb*5S)*1TZ#oh0q#-rAh6I0$ z7c&DxFSv3C?fm)C9m)e3p6=rS=d zH17o|W8iNA6@FQa-BUqf5cJ{?xc?3r+D(AD9h~3zxA%hba3D-26Qn^J@Zu#n(m^Q< zbbuZI_Er!DDmXxN;EO0o6A-j>{NMlo-BUqs2zoIEVow_6Y^`o^5C*)cgNuSru;Sm| zs{zW-Fg+6>CI!4Ghuf$CDXKuK17IG{geePvD+BFJ=HCuE4vc?$D@a$si-VB1V_GMe z53`Ja`&5u=K`(^vLt_qn))tbtK)M58IK!nyK!p!K|MsaMM$n5@@K6Ks`M0-%C{S>K zL+=GQTpx%J(*-mBMGagU6ngyIdqKKEQ+BU*tjEwI9^&YY7FFm@lHffV1G2v~I8>(0Ho=XpgxQ$R)4avKU@ufKwtO zTSvh7pcJ0P@WKPe2PJXvm9ou;7}GjKKOp5KP&)-=9jLYU1GL=%#0i9@JTq|1NB~lB zAnC%F|CnHUK(2sA1^8$acu|6E5y)*pFV2DkUZArT#C>_@H}p1KV<@Jz>A0FV8dQZ zgIoEaeV48Vpo?$1MFc@L!6ndktBmR9pfcM4)J}Tw;4at>Xq#{oXyX*ai`(E_#nRdO z2GmSFkk;7>I{xj&6wtmc&`dT1DDK)mfzE>!=$y&{;#GY5|GyW!$FsAQ1tgFTvI^9) z^TjeU0;+gHhZEfcjcG7~>UxmZLD3cP!VczZ&|utDki|hSyl#VC33W(!E67Ta^D~T# z85p{!f-D5J)iTcVFfhERg?K68g$cO5%hTNpQl8ey_~PLrc7(sU1G;ejJLrIFhi=G5FPPUa zfy)}6)&uq2{QIYZJl1-t1ae(cT4yU*^L+5$t2F51z842>LSw@9MFscCL;}2~u-n%puy-mb=>)xa43XvE4t6?ZeKL!ABEySac_ITSgMoV5{^p4cAVV1#85n%c6B$6o6^QL>p2z?y zkwNNh%o7>>%TkNda`MX=lJkq=a}x^~f*CUNQsQ$n^NOLn(ZS)>>Zv%kOMEog@`xWkCq-|q%(-rA1R-|r{{2Ry95Uk*BTjp4;4NW;AoTwsA_GRf)h zgNl~G7uUgMG7rQkM1Ow)r2GKY{E%`k@P#fjxVIGW!UUZCVEz4TZ?IHEhyjb^1#l05 z>QPWW2+D%?_h&-_3uMU){%hcX19j+d^!IBaCSmXI2Y@cJ2h|~<&e{tn(55f)`um`r zVd(vR=2g&?#oq$DnhYWhE{`D{b#T``4XM9>2)s24wZE@-72!cfr2Z+W6U@JTDu@DA z$MEqh{_U+Gu>eR?LLLqH0tu>s7u?_)2GkS-`5L?v2h>MJG3JFCxY@t~4&*4v!QG%P z0lbqd26ii2C)e-_*s-uqF6h#{EQS}-VEb4gX$4f*lGVwDq`P=<+{4n{en^!U^x_BD zZ=l)-)HLGX4r%;DI=O!!AqcS^wUY}nGvEa`vYD`Cy9~v|7w)eRom`L=K`&C5Lt__f zC-?hHSSJ^x8q~>s3ffxr8oiSXk_~#{c^MpT;J~(pn~T!P1>J8y;l+WM$emoK6;LN2 zcXDN6f+Z-O+%%B&kWMbhPLPX&L3_JE#Sf^HEA#jN|G*akxzKEf(#ef_2yz|^q$!of z@WKnm2aPa*cmHRfU_j~Q{(ziMjlGkb4M`=Pt)LnnwzcBJizA?YP@o^PHyuuXz;)~x!|?|C>3LGWP_X&_+l=&WD|h6?u9?-&icKe_7l95 z3sQ#E$pwW$&XOa)z`jgI=tMcR<0-EN~D8yqF0W1r2w>T4^vnt05)@yqE+|W*{3u zqhb8e@wjeq6Eg5c3rtxyTp6g7$G;tNwlx2C@EPv`FYdrwzYtS;K`sIHCqZ@xz0kb? zjX7}h56N2~)qyYK;L@N@FL;O!#0YwE6dr0IKCDX(3%wU=aDAZSjeq-8kSb6|6ckzk zFQ&t#L45x0y&!3jqd?rC7ZqsI5U=oW?*&N*zIX}gBtpZwcPc2MfXoK@4ARL3SsM7l z5Mm6tlRNc1*q@*nhnu4auKqwJE693iCl|zg0oso>fqI?X8Bd{|T#(^`FFK*_Lhj_2 zJ_WZ~L7iNXB2Xt6l*eDhf_GzqI=Ri@l!(aI#V|f7g=aCmNQUu2NgTD43ko1mmk+#s z5Y*lSR~|^6Tu_b)dJza7nHPW*9KGNcC0G}}{3i?319Al{D!{Ebtesqt+k#%a00+DP zWFV7pC)YC*Ud(}ddZ5+?w3EC4EHqY$@8tf;02_v@llvC55euc0`}-W&4rnL$>|^j% zJ>S5&3OeF&96SULZhWr;ZRrB_d3iwH*aeS4)rvr8uLy`Y=`r{W_P_uCcTNTM2wpUT z>;lbZVB4JsT5b(G2k9JmXSweW&|nHEMFhdlzkduakT@W-1>ImPKqu-zdbQxrG`N!s z?$s`b_#xm$+%1r2c)F*8Tmub)A8&4Z#2+;e>j+SSDH=>PvL2WaoL8$4(n@ZvVO z^nrGJdqF;LJ&6bju;vw@{asn0HD;hFcyaO+D9}N*BedHK9RgK^2PCN5>k7Gj=MA!A zaJM(~MbL|F55bEG(mFvsXK=R{)EO>-h=R7}b~3&&dI%~)KurNqw--Db4!Q{Ng;pv! z#lyP2p>Kk^T}|L4NN*srDBa#au89mU4rd^Bd)+cY-Cj^P)cVZ}&P+(RcLJy%%i@OU z_qw|w`n|4hi436h3hMXTx+OAz${>(>6F2<*ULwv%rQ7^FH?H~j5?1j1d(W@`|98eR zGB9B2k5BjonSbZs?kW<{+p7XEdRsv{0(yHvRNxE0JkTl*kxth&-JvqwOx$4A-M%uNj4w9-0}c3t4dZV~ zV}!0?1h>yHCfh}QC4=-Z=fv)8Rs{|eW z&jVhT^r8%=60|p^B^2a1$bHwZC-%CY0F~AvfxS~f!Z07aP|g53U7*u-4d@6C&`G@u zkHhlG3DAwJFD8Ps0_Z5t7rm|z&kIH1^}T=p{|66uf)_Oiq;4K&05613?A?DFd;K|X=F92_M9y}l1XlQ~Ec2=YMSi{2biD2RYOfF6OLK$lR5 zt_XV32{-KxHZPn4tpWkf#iMy)6HFY{3$tOuXkKUrO`n7BzvkZ``lj^~f6s9S28Ij< z2hboJ=xiYH5!ZJ?TS}n^Uop;xRs{Slb0A}}pzg_wRqzmh13sM^vO&QF+(QEuf?L3c zL-TJ3o#OrPC@7#nqCa}4g3>Bv3l#r$&{eSu!IdoN_Lwagsr%}0P(94Q9dwcFOURsZ zTBqw4@N_8ucGoQdFF?D$nvZ~t-tro97u=Q?^Fdcx^Y0IpXuZVWatrL{Ue_zIlm&_r z(8-y9|NjqoF$H`Jnn=J4?-L*=g5vT6=>AyPq1Yb+UO0l!o&&k>3;%ZCJ)rnK0doJ9 zfEQ{Ie}M)%UYt4tG63X|E4`p|J-54l33w3-*$Dtz0t@a$T?u^g384;h04PXdMnhU! z+KcJnX)%s~7w2G8TTj95E|9A>@Nf6s0J3{a&o+f~lOd%!zdQrzo`fsji3|_^|Njq4P`*Bi3|F9RH=jg?6HvCjPa^p4Q;-^S zpF{>wz%?*2FqrrxGJx_ph;8VT$N-8^P?@jcgH+~M8ZuPmF{D-$#HVDIf$7RhFjY|j zp(^2HpP(gv;Pu>J*umv3&yWBAcmBmz-hx_DtsvBw)=7fzSzM7+9O~9n&ktz;Us8A9OTid3Lx&TACOC| zT17y-H6UU;coN@+f4^Ysr4q?3rfydoaLa@r<|_V{U?v8J7yY2)Oquw%gU%QGJPqm% z{uUKgo@6;3E(TG&1l5bWYrMNNRs^XEHQdm4G*+P6g$npciEa z!O;#)(HNSpqiF(}9Q48wt_j3{ap~*-|1Zvh&oFHTnF<=50Z9bD$bf4HNmhlt)t>l9&paqtV&go_WrO&UST zc3JcV+SJLu$PCt>eS*2$6|SG-MI(4ZT?abG*9s1TT=3+3FQ{m3Jy|Ny9clqNy_4xh zFi17%a#3(90Ns#a5|qgBq9+EaqT!DPRWzW|+xpFmOEHj&CT#)-0|SFiP$I(@Xnk@8 zq!G$K7nI0w!i zfg9g|d;q#Hfr$FY<}_Vus5jCm+&RXt2*nFr4SS>dTEQnFdEe6ebgZ&9= zaDz+XfERpy&`2%`K_q@q5faqf3My?7>A%i z8K~lUjg+Bqn%V0MzA#cF2$z|sL2LDnz{~`VmHz-8@4bC0s5A(A(bEI-0k}Se)O;`0 zc7X#PUZ3`Y><107Lo~IcX#%-6;Kj$CFijx-izd)%q_v>g`0e1fE=W5_BItz#Tsx>f zg|;OR!vstDKqb+BCQuy*u1`VjLvUrH05&XC12p_B(CsVIE8-Z`+X^b-174&AL+evt zNW&Kz94~xO#8qJN^1=ivz8_pr-(3^a3=px%n-;x`R}g*(VrKs=G;Vq17em zFl7 zwGQ;ifL?GA$bx47_fG}ar`acp;pMHx()TeJEsaT(yK*rC` zfX2^!vGwPUx88t`pCMQ;9)c&aT_pm#eMP`m8iH2By~w@|N;m?YU>*GXeN8}V;RC3% zvOkog`4>|u&+*m^zyALREzf<;1!056>U+T&K#fF@ET~?SfYxgu!!?3l2!W4bl>lFm z$oL}V_5c4b@X0aK-Dnq|?yJ|p&+OlCPAxk7* z{QCd@#qn35oum^HVFljz2n(j(R*-Q4FC1@yLyCXDFGurFaJYaX02VGFHaJ|Sf;UT{IgK~48g#uq#wr@vMPb^Nm&x?Obwx_xy5U$6y(h6M!z zUi2cH>-qySqBAEpk>Q1MAX34wED%&MfU=eKn-`gZkb(hx7w?kTLB|D z{|{ncj7?+!MKox9=0q&g_)J9}xJ3+W8Iv*|uZ(NFd;=qR{021jxHAXaezk5_j&2Wy zPVizha2xLhXh#ibFEM!25O}csMPeH)@>O>-B!F&H=>^@w{vz`K|Npx{i#gLer#=Ab z1Kkod;kELPv^0>SR#b0iK=yO)0_CB!&Z!|F%TI$=gF9p~WU*yQ@o#ta z2zYUF12`do2LpRILD`^fEUqpA-M$XsK_C9@tsqx{iX)J713~M2LREsY7(iPoUtC`R z+Wv2n#hm5P+X@#7#2&DbR zwA0`$#J}A)0aQ}PKtu!lKv@N}tvDtS=HXC}pcgmRLp^yQ;KiJcP&Q~qZm0{?p$4GF z1jxgnat7q#0FZ}$RY1ltW--2aHXrQa?ofxI-d2z=AfDSV0Xi0e2kdgt<*YA2nBmI}}|aTfmVp)x@)&LM;o85tN}+yfmscJt5w z{}~SQpi+w`;KgaUHM*ctu-22Ms-Ti6R43@gg(j$>B|rNSViL1T2KFr!OtK+RoHnW6-9YpG_& z0Z_u;9;y-af(IsAq6+St>IA&_3Da95v=id2UU0yC1dX1*`28DnK0Sy4@n5|8{r^8A z@7#l#Rw|lNrVkB)lQ6*&2WSX@oe2tobB)jtC>4g;E{((XVvy|_4xoyCd#Fgzi(r^K z{+89?xT=L(_X{D>0lGv8RKlfoLcE{{ah&wm(#$^%8%pB53y~a`D3Yk`q(}ul0?XCi#>ICFfP-zQtLr}MCNI~|aPOm#fY z6ookR067!n{Gcom(j3kXarny?km*^5(2Cs=*>t49$x`VK z4GHRY4FClfC|Ck}r-G_WaNK~#ykHe6bbIznJ8-bPR0Em53bY>vbo9vMI#?3(1Ro5- zza3H*Wa+?y0kp;fw7(l#8G|Y}Q00mi``%E~L6@Rtyt0LcOe?bKzDOZsLR!eYwS~An z3sfR`xkE!n9ocl`kZ~X_Wcs0|^MFk6@`aXnCu?zpj0b5UV+b{U9cW&fD+(Gi*>Ka{ z_(2D~@Nb6{M_Cc1h0JAe!%63LaE4YaG*|@SM%#gNQx;=Z1ZhsLgBS{KT)|pMz8--u zwk-o^BT&wIQMCff2Hz#>0xcB`K#395LIPz1Pzxyt)IxGq34k^Uk4yu%kodQ^f||;Z ze!-T^M1~jKu1NiYK37n`0Mz`pe)A&G71}QV4R-9wOk@C+I-n-b^~^*DP=W{TUAdB( z$PiS{kdg-$6^%!L749;PUS?Xsrmi#Lc(JewmJZ&xt0Oj#~m=E|{ zszBa?))0B1>c9aU$uIU)LOsdf63)oL02}-PE!lsu;S+qsh@sopfq%OQW6+D$TR=_% zZ@A6kd+~M&hzHt64{4P5f~deO?iW`e5}*_V>L)q`ytw29uBJfM7NoBMN?5T7WiJ$A zi42~w9Kgf){M&m$AqYxXprA!dSlLsc3ClMouorRy0rXr7P+#T69ez;#g4*ZcFa#AU zn0*dVe=qRGELD)K2y~|}xKakKR1SKvaWUAh&^5WBvj{*=0T-v`7tRm^ z`L~D0fVyq)-rwm(P+y)1e9@1H9scd8y+2TlfU-O&M$meHHzz@31f0kn0(&6^9JI2A zuOAQf33^c{2#OsEa8d>p9xrS`+xI*^fYzaM@b8}p?jT(%amr!_pO4_d68M6<9GYOk zeWOqg(D2ENZ)Gq+_|8SJaqqx`=s!UfKB(XTA4m1#Bup`)Zv<+>ZbAry`$mV}|NsAD z?|WF^2$Y}J!|m3Ec3{ALBTxrsODVzykVZ13+nxh*!HY7GS%n}1#D9?vVkLo$2KS9X zz4#Eg(V6`FT{T({K>9|Yj!-1bXh`1()DK~UxfR|w0=0lYz!XCIMj*X+;X*>NwmUdr zu7b9by|@n=GQR~PK>QaM-og4tpySF8!R>(djX)u=7A6Sl8-;2hci}dbKtll1Hv-xI zA0||SYI``yc4*%SRMMKmT*=?E4OA6_8_Xc{LO$Va$s z;Jy*4b?pZi0(TQY9ms6B5V)HF8OC^_x&WN&(>lR?NH+l-fq^f$P^4ah_F`p#`$nK> zvxPaZqyW|>28VCyTZp@SWddJB!fk{*;#n~?tRQ_Au%!Vn7R<-#h*lJ-m!K2xPy&M$ zY9A;ezl0kOwhz=HEQ1SyJq-@Ppce)xhC)0Ib&4p86sRf(`J^9ij1Y?L?Vzn~FDAbE z|Nlh~hyd}y8MXt|O#+R;hy=Z8f@_9$lR$~=EL;%UO#;Pw2TTysO$t>AdLarEf^?Ih zuFNlj1tYkd1dXuBdC0*Cs&7E8!WWk;z$GYXJ`XfLX2=F=?jZ^p{uUut1_p3RB=8S1 zC*I2gs$ExsM$(sp#`5=r5`2k1xZ>pB4hmO2$n61Xovk1}pzb#)iAlgkK?Y=L^6v*r zg9maTJ+7b^Ern30^S4X|pP~U*vLB)Zw4yPZg@NIP707;55Ml5dv_A_x6yh2a@PZNM zd;XS1Ai@2;AV+{t`DyWj^y?sFi7!AS)g1iW!NZS%FHXX&1~oQ9L1SZ(P8O(v4=tp- z!ABGYzOaLo&#ysq2&fAAx4Wi5Cm7L-cTnpuup6>@?*-2pc82C78ZY}mhe9!e69q@$ z3pcnE6tmd*_fG|d6IiY%0Oat%7e@=A!Bc7s>Tg44=eC1}G@1GLgX0AxydC1tfEUwX z%K2MB(`uj+bY}A-d*(w2f3Sgq9Ui8op!OB0?S-X73Tg}nz3>(QS4pouK+P6Jz~J;R zrfXnD{fMU=Da8@)?vH1zvCG-`@)| zy7eR|HBJRFLANA;ECFr!0qF|NN{6MUd!N9%z_|G(3Lfq_B$g!M)KUQka2bn+1BJX8Mt;7uQp zR<$F{#~^FK$HXn04R&$B3tvd1Kj1|PINHF?ZqV8Epw=D49?%+$5dQ5v9)T|kAQR&7 zi0B15hxuZ+ZwUCt=!c-I%wBr`|Ns9b^Z)<UaS=5LbGfMXt)SELIG-n!-pdvG5?AOoWWkM2IXcRxOQW> zcKGlH7R|QOAk8AL3qiShdmsxa-++gWpt)))sPI7^HUc%eL6i2Nfees&pvE*>Ay)|= zeK7!aRbazL$EJhBA3AKb0<@{^WgMs#2_H6E0(UO{a4j@|y1XB>ymN1Yl;9(?C187bTEY<_T1-J(bsB9Ae&69v^2|yW60@;G2_=4r| zH{d}NgO{Kgal~+v8Imo&9Q+s&pJhT?h_yj&=>oMj!NW?R5WA3#@C()ub096m6ri@K zfNTK|FM&cV3&|E&4*u;JA%;B6L_~<~0*~1kfOm6baKVO|Sm3t!VNYWbq=i@r#Fp35 zkl`j!a4pP&1(zGRG6q*~z5;>ZVJB$*haGVTJ+%Z!0{(6d>T(kH;-P&RyGE+C-W7gT#r1@%Qi2@cd3MVpxOZGrYhTR|f{kYOjCnnZ>dQ;d*?oy3hn z!%m=4BkMOWZW%#_ozf7UAn}fx zLugEiE2r7>+1PxpTrsN?8uORC;37zMP zE>E}pWjN-`o8O3lHs z2}l-$%zI%0vNMCh2sA9s(cRPmis2WwPzMnl z{+CLfK^5Ho4v&I(Hh_WPe28Py4rN$5gLCyqCvx7XhzX@!_ffDhIm0%eO83eqjfP`M_ff8Lvtod?uPXw78^kOeuO33&Cl0l&$(;*H9W#HBWCA=>je?z*> zzCT`DW;EDA%!kIlDBK)@7m~mK|A*#7-yg5}UU2?~4l{!eSMGM@Xx;%zZw&k`pn9_# z@&|mRblQRG2s-I?zw4ia4?ww~dm<ja0xYu1-K|3QHc%FLZzF`)Fm8?w0z+Ol}zlL&KC{)+>kDQu`bsD0DqX2rk|@M0%i zi9Tfh+Lr@d7$?FUTgr#xSkB|FZ$K-EUb7!}eFIv82eQ2zbooXT*aen9LDL~|F9Jc< z`9PclYP3xRSr_!e3vQit1~?Uh)>0V+zW4+a2QA12MISh94wQ(3(+bEAs1I*~_K&^z z4B8_G3PX>w){`Y-&@#zMEa1h<1elkFj88)J#eqU*Az0sT&<3+@AYvnEx|<2)we22Z zfiE_}wDGsh0L|Ee4|WaZ=mzDGZE&|qWCX;62ado&G!G_Tk^wSjzXwa}$4EGXP z>>Nl8mN8e@FfhE>^Bpus1X{WQb^2+Tw@?BStabuO_lvIYpq&Yjyj=n^V&?b%|6fc2 z5&dApkV=YmFvCg>pa!mwt|DN z1H@`QS)%gd>o>?2MGpS$&}zoG3!F0`?gUjc&9xsG_*?owJ0zZiR5O5V*zOb-@Zv=r zGy#-KL6=Vjh6TO21QX?NX#y1yptREgPGcuaHNkqpWp6+h^NZ!*;8jZ&*Nc-79%%3D zYf!_2A5us+zhDHZt%k^gs-Y~d7jq#zkXruzpjEIR(za5i5B%G~)&#tGgpfcM ze%%gsAV~d-|ItuWOS~Yh3xw_^*mbW((p?A%TaXt!!FIl|2kkL~q)QXf@;d)7|Np=6 z0uint!U05BfBFAE16+nc^T;fCAm)SCbHZX`GfcP?xoqQwiIzCwDp$IFKk)CL2nuTJ zL$%_dImSIjQ`bMBDif5=_B$n6p8z?`_fL1|hhr^V5Qi~? z9d@qyh=}!@7h$T9J{b5sNhI=W+ZUs1Xdl+5n^HF&l1$z>E3spzRK@Qoa}c??~=>#DHd< z%R#fw(4NQcP^de}?|Eo|%v1(#HiPskPp@_dK4$6yfT5n7|d_=y@nNf^%b9 zr|X{=<=|akr1m@Ur41!mb3h=kXjSPGZkv zKWHBMb=-^Vph@UUZ@^7RaDfBqd0c?I2({-?fn*(0n+&DF4DQ*)gUo+X`R4zBaOT12 zdE~<_fH%{@Jr8xTK1YzNY(TC;bUJKdI`~_9K{YaRr^6BMENG(|S|e-1#7knq&gcMj z1zJy*THva6n}33O8ld74($nz$15zpC@uL4VsHb)TDX)TzdQkxu7J?OeU@_2svI($) z6x@3V0?$T+dK%D%Od`xLC89`u7qD72kclr8UW2kJq#gma^k3+MX0^3IgeurDP)`GD zmSWg35V(7rdQ3FK;CSD>B4is=tOytGdSO5PbIR<1aq!a|PS}&D=#EjSZ^oe1uCyvPCV^@23%z+H_R&|EsGxy%plG}Z<|6FIo60ZQ7S4oEso6jJ{{ zYy>y-FO_P7oVUFLRMG}!F~6_@Z%yL>O+ICDy@-SGK&|K3S|Ek{!3vvSGJ@0!KxCn6 zjUYUbTF`9;-M$~vxV&F6%>IiK`&OpY=U<+KncVnDe%Pvh=m~Eg3hG*z`q@A zP2h`ighaP1Lb#zC8X^~hUQF?axgXNiKvHIjUAGgGZZ=4)fa18b5!AGQapgJahB$B+ z*b&s#c=G)J{}=Z`#4QkU6+~Qk4(n<_Gmk#ZYb8aX=2;-}}|QT>1L+%Xy%(4Y{{r3bPNALr{7gFX6UkL3LNoIsd}{e*M=!K;)s0GObc3$=ghTf?l z%R8s=-T@oxs=~kD*MNWh!QLsYAPKOtgAW)wr?7$)fV(Ey7a4k6*Sz`vzq3Vj&Kqcd z1uS^rHCS*1c=?vEO7E0jkTN7QK*~W*>Yd^XQi~)5*0UYF$FFy)$=m<`gI@Ftp}4d= zRHB=ODFPL-8>UO_nz+uooNWN6LcS2IowXj)q)b;B8@>W zxS{rSw}Na4=}|2gr5-WZPeNcY|FK)D3o0zzYU$kQ&gsnI)j`+ujSJ0?`!R zW(FzZ2?}_T$OU3?bhh@q`Tw6Esyd4mw1OJ6Wh)5gz5@X-(#oK2JrVd~6@;DE*}4Lj zv<^OE=xz}OMQ>;8mG_{loqc7}I(z4US_;{qd&c&MTC`p&5d&T230m}tTj{z7*z z*ane_K`$iLK;gy%PACT-F!1jOJHC4gD=2MtgF~~ErRzl#XxaplLmBw@gFVyT!V5~J zY2Ce`paWlu?E{*adC3CWVhl-4Q@4P6UZx;n@Uo>1(17U$F`&zqKurGqQz4YA2Iw5$ ztKcIu!HPgrfGk~|u3x%+zjXS30O#uLLk!)JY~R@nY8rwCK?gm790*G7Q@~lia|$mg z=fk|#4OR;+FJ3GJO}K#0-+M9r*Z=<$z(zpK1;>1E0#b4Sn*cEvED0$cz@ngIrNC-C zd%z{ai%5{UAt1sZ&0J7`cJ{_#Hy129g%?C2%mu0K>;cCFlKVh`-q{N(X~BZ1{sv1< z0Y?nN9FW@19#)Xti=Ci(ku4x%J&2eEBBp|f3816;K&Q4X0YzEUPf)^l1)Zca1C;QK zz_qGqQNSU12j1mJE$&lNmC8Je|zY?Q0X5 zB?MaD4cfd9x@1TOQsRa3fsV0CNb76`rA7Yjp(;VJu!2{1E#Tw~uJDkY2y$}3i&SoK zbQ50`*IGc!G?+EeVvv7-sRsZ0bKNcAHbz?alu(eb(>g^wUL=BMQeH2AIgbOfZX5ft z&jNTR{xSkT#gfzrPnG!oMG!uB}h;_bvxjDf_{a-M(MIw=iZg@$Uy`2&ii2 zgWaJz{M%Wa0$$h@z|;SW1I-ZjesE5LslC|QG8L4EUNnM^_uCJ4Nw@14@aZc2Fr{GY zm@jnqfR&=x(d_>~v4K+Azcl>+|9^Kcs7(;qJr&d@2zns^uF4VheJiNG4?t7&`Zvfd zP<>y>1gf_CX-za63)RNI3l15)xKe%XE@D9hxeU&Pslnl zK&34>%Y&{AL}}H46Zi`sM`-hkzvUZf!7vm5c8CXFC_!8awHlP}AeQrQ2e*a-Uj#xF zfV%51zGlO{)ZGgThrkz~Annlrn1TG;!3i?pg(OVhiNNlupn@Xk#WASb7i&wv=D@-d zVk189o{jr8uRpdbl)ArHQ!MF2E}^J1|*Jm5i> z0)riY@FA$>2{xn!+)#pqWhc*s7f(JwyM-8TNb3eiSX!rue*oy?v&42LrQqTubdkLZt(wBH) z{{h+;Jou0SJT(SxUV@uuY26|mX`Nt~y^sJ+(SQd*LCGANt--}Qw0#UM;USc(3aA}Xi~6=ObAk~W5t35CYLQ&_;xJsT zI;JZ@zE0}~w>?2+(TiiCNt&12|NZ|@T;&<60;)MrgGPx!X&X-ny|9M4gTG}OsHP>t zn;se9+yqM2m`(@B3MhadLGm0Tyuc}-dkT0&0n`Cwe20>FkwPe~8(a{8Z-_k&Iv4My z!2kdMUt0hC|NmtcXsrvVq5&P(2kEwSg6kJ>Zw%BU1aBe%F`%gp#Dq46KutzaYAa!4 zU;sNk`ywcZLsay*f^q@>eo%k%ME4YMf4P^XtF!gO`~Uxsx1Mm9AyyD3vR*(zR(s2)kZuJM|4gFx$?zvP{p(#+)`^jP^!qk-`Aq` zWQim{q&~<#Bmrsi_KGw@G{CwSkWO@9_f(LNgI-MdFADCffKIamUmW540}`a5>u5rM zK)Vmt7izu1-2t%O;9?Nc%K#0nFrVrM2VXZ&N8pPCkd_L(k>&e?`69&1PL_!;K7r;m zUeChl(R8K41A!kjvhd<0OyEEOKg1?T?cdAN#lIiiSL+q&0Br#Rb#=OXL4N5KX@t5K z+}YXw59~2e%cdJVAkxb-0n)1B-wy7zlvu12xS8yQhLiA%k9=5CC;PWT0gl|8`duc)^HPii3|NfRz^Akp6Yx zix-gKO6v|)N$Z4;e}JZOUb4Oa{~weIkPPgG^!S5beAWbe8(IVKZ+8WqlkEWSeDOnC z^q>Qw_}3roh751?f?DuVkW>fRThOs4k>P~}6L@byT(|EZ2Kd@TrQtl9%~KnLh} z6pXQI{{5~2s*JFqiGL2Q2TD2l_xlDk|Kz9>$tumbFkucuhQq`;3@@@D!8+GE%|BS` zKuZ@+Oq|1zVKQkB!wWx%WE$vBl+LMhK#TFU!IuZNg4q1~ePyf<){10RXB14D!;odj9QGLArvn zL|+_9gq8~6LI9+^J5+^#KZ{qui%dup8@5Dhw7LMHG^B20>BKr^nvui|WYsO#DII*t|=oCGM-l?GNJ3%jY z{{dMd0I40JA>F&?-~a!Rq8!WwRSe*ecGUsZj!Rh>7{L9;9iRyI0!`?En;oD~0adQ8 zAO^J04q}4(U|{W2LFRV5n(*%z39vp@TMp{4`~#gmVF23g35`$Y3*A0bH-Lw4L2|AJ z{QG$VK)t$u|Nk?e>UQbf04mnOCQUgD*=5vn7UY+J7x^DSWr_f3DB~Y!9s(@f2~qXp z5M);&_}*-&Lmaw6<$A?mXtQYv)cdU<2Gso^Cjb6k2nE$<0dYTnZx%CXA#p3%Eue$c zMI1rV4N@EM;&U80v4F}qu;0M}**yj9r0y25!#k($0Xehv04Nxh!8iOtRE4^9gW44( zAcui+zy_$prh*vI8~|eS?{9@rP;H=~@&a|!w=qDw>7bE)SB-8S0Z@2?)ONRmOa-@? z;kiZr#WaXxK`piyRxtJngdR{3@$Uoe^VNamfq)l_yTSeg#SGY7m#G^9Ui^bJLONS7 zfTFG!M1ooipkvFr!QKq$?gjZd@Wqk$;Hc_s1#vs4f`Z_sG$;>&nL*uP@qia^!7&ON zA_0|MpxtetnPzcv@ofOr#`z$f`=PN83futZUQkeUg2}A^{QIYZvOsq$D62uj6ea@7 zk)TN<{{2%|fZ~69ODM=lP|^kQyF)|3Ws5BM#yJ7->ez*bu-<_j++a|a1x+`A@?$4Y zz>B+}OZ51+gUtjrVZhe+f>c3z`>}8{JU}%l$madMU`12GE-DS_W@!Tj%92N*jTgNj zx4gTRWwLpu;f zEL@N#1!&R^eB3Z7NxqN=-@pgyV=Xp-`5u1UCfL%~pv&@Jrh_&IflY5d$N?$ux~GDS zZa&1)31)PIi?`+jERb^Ur5SX03^=x5ECrbY_6aC=f(t1S16w8!1>JV0$-li7luSVJ z1yTsQwi;Bb2ECa55L|+%b%NzzZvz*cASEC}!Q}+B-~@^B@1F{xTt%!e)TY1+lI>G` z!G^&sc_9`JNq^hHc@Ctd+cg1{d|s?chsZz->h?_lHHDu)097_AY29EqfKJ*w`r!Zn z2`{U`g`2NP^H1hl@r>V~?w!EoISd&!ljktJ*mMh4af>wn;HVSN_ydw(0FvjKGKb;C zB#1nyy%s7G1g?PO6+xL4bOS0VDnK&eleH6qUYII?Wng2|X`L;iQ$VGd?E~nc>EPj| zDZC&-h*vtnrNIlG2Z&0Ee}4}vSV3sQap)ug?*nLyQ6!+-HzDxFS#ZaP2VA!ue8d2^ z=jwf^J>U)%+!%1NnF7kXNA5$9cL$H5z#Vd&Wdf*reX$fK4esDU9N+Dm&^;AYWOa%( zzG%T=K`Y2~PzFlIVgf8Ux_u+kx>+1SuI&JYiaJa!l4HO*1eA?HYDEImI;XIL)&9N* z^%*n-L4w_`Auxx(xd-(Z)ZrlMosg|sJ+7b<=Ebgi&=3X>hO~%+RCN1>9A{|+`+PMP zX;cF$VJg7gmmaXQz!3l%%?b5LjO5b8hH?og1)NdC*Y3k}VSkNEeufV}~BarQ+vh`}t3 zplAk}@xlS-%pK@4c^4q`&vL!f3js7?nh zJAyWY`1iMjf^6*e4e18=(Lssq(j8EV4sLt#@9%L1$)|NsffnXdkARfSzw`fp*8gtT z6wq0n{LrcjQqb^k2P+BcZao7!y5U6&_?A9M#l)cvEt>gTKu5xKho*oI0ps7^3oJ~n)cAsuqWDyBA2v5LkD(wwH#4u80VGjURGOC@U!0nr3+l^)y2XYN#o*3vX?$)G zSUkBTz9g|IJ+%bH11%eaAW`l5fqy?}OHZf-XpEGN3Dm@Q{g8b^qC1qM*QG0@(-m}Yr3kd!*mDycb)cJf zK~o~2Yj=MJf#VM(1j^sO;Gr?p)kV!em}?8bCx?UYi+mv#4Auf_e}jk0LIt{Axy#hKg@ke(^@0Fl#*E0d#pj%kEpMWxzK&R`8&d@Wj5AyF1 z{g4K}E!8D-%L}_3px)e>!0yl!K`#uSfmDL_*1q81?)oC2+ZQS!aUUcBYOl|G3Sx0| zx;_D`$YKNs{q_*wEkQ3PAw2rxTOc?bK(c9_F1}k{T)hq|DMCN=x`b{4Ir0NPSW~y_ zlYkdDV?c^oK-aGEZx;kzCi9`&R|Y)qqX)hcP6T95cc=`gP?`fa2(&uX$8`%Rh}Q(Y z*l`^er)ys1Tn7c;Jy1^!G|UN3DZU>dO+0Wa`2fAN19bHN8qneRANaR}9QDEp>Sl18 zF7!jUs|>h7_ZsXv4p6v(F5+dG_(Bq7#p@N_p$ci;u4_Q8x$oDY1(`%(H)tu>ba7BH zL2nXu{Q}A74f_)rUf8||=X1!&*MavO49!PEtlzw7dk@Rwpn<`T{g8V)c^DWNR_sq? z*z*7Xe^B0Bus;zrTx4VtpURMtnVu1!l9`r}j-U;uaU3{>8p!*zNfbMsI9U<5PQY-|z z>H&V=17r<(fIjHp0RFy(@C~efAd!=$5*Z49kPY`vE&(sfRiG7QN%is8o=^Y(gHHE9 z-r50Wy*Li4d=G(cMh2Zv4>EdtU{cVF4azWW_7H6sEEyPHfT}6TQgpEGC+h?tlAwJ& zFKR)jT7VXaIk|L#&3};%5_x$QvneX$6n5qgv-SR?3sj0wkEr+kLYtGp=0Feo2x zkkn4lG3;rby)mG}g0;ZbPtExJ|Nm>{9nZnMR*=jKU63V8V1Ztc^b61(em@gn>`p}*AO`wPjc+sN>4J-bZ zxuE_UsD6bUYJIusVdq}*3SM?_ays$&k08YT5y#X#kFT~&)phpit zl3uAU=!nIsAg>0!V1nxvhh;KQwt8_3wAAtCDtH0}YrVwZ2buxP01b=tZwCifz>5P4 zP`{Ma!**YT6bHR{E)SDP12s|@(mGo~MuS&=fcJ)Ufexm9Q2;tkBO81>Ll#@ND+lWa z@JT0`&p;!XJXtJRoZY@0jR%i_4!d~~3>9U~;sc+C13Kq0=!GprwASDAqBUXb$xyTJu&yjR#jS zfsYX433^ev4|MRMLDoN5#P;^?c>n)@Ak^X)p5O^B0sif-KA>#$$`c#{pdl{M+})@D z|ATs4K~4;Kq5lFLbNt(Vec#;}_JXtqc85YPZ|VhS z_`qIpUI!g^#0om~4>Yt7@*Mc`Wd7|CkM#C}>I9HIpwb1TmVdiPQeYNC_f$~X1`=Qe zC7pooUQn$Q_`Hp>eTxHE z^nfGl#UoqL(O3$gR^n7pS_pcf01KG|paYp24<@iOFa-8a1^F{5ixuW>aGLI60Ea$D zx04G|olySy|Nq`rPze;!+gtM)asi;lXK+wEeE$C*swW9FJPmR> z=;X^^;3(Vk6|4wkX8=5GRY2-MNh<)foczU%7EpW00Cz>5wrgQFX)IIXi0q&Tg6D##enDp*jt9SS-=qu@KJQ3x(N zS`XA2f|FI&-xoXGLFRzBeBns3)Bl3fp#W&n;QRmoL8sM%4oid-($Es}3*4(7SqfQ< z83h@W8G2hmP6)`z0kI*${-Oum=afk6Yz3W24~oU9AO=#Xbj=5c%4@eQ0hl=uy%2N2 z-U@o*f@%&6|8}r}0a@v=I5fET<|KuIYE>@?8HZ@7_%5bJJ>k*w_^lOFQ~l;DxZU1e3%3d9MC0?pgh~#OE4tB7t{6jf`S7U z#h`_ukZ=SA2fR3eM;G|QG)N1A1zhHVD^XaYvNZ&U4YJb=vtng;`|lG+bWsI8Yue8KfYZ|?$7 z66gkRuLy!hEG((P>o-UN>Npd0n1lqRmP+dcC)5|9R^5cxqQ(ax^;BACBPeoSxPnf% z04*c|<>yQMEjpmM-Vd(ULC4�$B>0Mgb+f7b{%B1wHesF(uvxP1b%SYPNk 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
)`2z>d-^eAqQSl2G#Mpdl%?NfV9rg6E9l7 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%0AT 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 z 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


TU(G__urbLG<*tf*sr2`v9b_cPhw3LEWw?;F~O8 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�!u-JUuS}y9JbS2JlhPKftSV1wq$K`3it0 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

-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 $TY|b>cLcn+1|GTt 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%0A_AIs1r@NMdQ+kC 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­vAdAm;|Wc&`Aq zFRil`#D_*7M9quOU!YDc5!(T(DAGDx!Kval=(y?EhOf0iRU#-M2ELF0m!7bIhcqc) zJcgO=`r{?&;Cuf4VEwHJN;E*;1qV&wi(H5*{{2%yIilNF27Dl1IoJ+Qkh-ZLmj(5< zBK&kp9PB4>An8H1ZwH;%0A=s*1sesrRE@>!g$~Fl{{7$_-0dp^9*^MP?)oL*g%dy*Mck3nh@jp!tQ?1N^PqphI8aY!~=q30x5jr0P z$Xo}Q$-f_(rF}tX5tj1r2a9&QO7QOo9U4}m1#$)G7}H3IQT(VLNnQ!6j#wEP7+#w| z{R66PWYR#jx7$i+?G18azzcDR37{SpDDP{4wSo>Gc?mjkjeooE7f`kNA?U@q&#*|Y z0@)6BV8DwTaxf3W`~vnQq-_jlLLCojA=lc#iz#r3p%v+?RzTbamJ51O4L2O**4K+) zo4(e=@J|_34>;NaUbv&^d3og*?7aLJAA1;H+}wj)w?^*;)vcf!(fZ8`xxL7B>xYks zx|RP^4+AJofie`wryhn}P`#Q19T`iaKd(kCg-Qcg zEv{Q$99j+<$@UdV>-635V(aq%|DoNo&?TTM#B~{{BjUT_#q8z(|G$_9A|@^e4{&Ee z+UK3FU!W_AM9>Gg5wnKtz(p8nD$y6Tmg8p4RSc>u=fKVN zCSa~M$lPvU3CLt2s48|n0?OdvHlc{)i%B5!UzUPQ-wO_*9WUxZLf~)$J2&(QB>RMd zuB-()8N8UV2viAz3YiT-FV=m4`I7Zz6!;iEtX@%H2CB(?k08~KIndhCch3t>u&tok z&ja8?6>qI{2i3EdCb)Fa-xdV;*k;U-Ux+AOq^5Z=h#0yoBonov^$C zq!xS&;+CKn=O9uu0$!BBLqY-;hKUeK(Agg^CxE9wLwDdAjz19aLLZ_7b6~$XWjdnPJbsz`q@|qT~<6N8sk@!H1wBdfp{3#25en-y6CFG8R=O0QM(% ziw1wobWjHztn-ovC|p2Cb6)|c56F=J9EermV4eW(gR*qGp6CWmjwrtQ^1t~ANW&S( zsSmza0$=noE3T{=*3rYu(M_a zy!Z`i(t_p;&jh}>3uyrabb~753lL7H>z9{Le}hU8SOK;tty9GD#l?l7{($QqPy*i) z_~H}9$h1z^Enq)v2zqfJE(E%r3Z4!@+sk0*k$?)~?ob)Xo{)GUa8y9jt?v$O2alkr z*N3YI9R&+2z`^G5Z})u=_~O%RSh7^$-ygaIHmjA^J!PT;c!NRcju(6jL1jFs2G{{l zA>C6N;qvbmfXbsHQ0pGFE(BZk5dtda5iOBD3t#~SEBFmTq2UTH2DSvgI3orQcyRhD zfU?22E`wTrUN34v7QUYHVk*cO=yE}kz!za~zkv53fck{ZuVCIY1s$gGCE$f2q|Xrm zn$&n90%-yTbcZT{mZ6qHS`d)=UJZ~Xkj}ZvuO5aMGqxZ%Af&c}W_A*+-@JIR1=4x| zHGg$}^)M`f&g)qG!kpIuH48u(+x!l=b^|Yu$GXcRm>;~>UI03M;{;i}?aLAP;yw>7 zJ%9%!TQAjv4ygMB+Q|NlFWCV*soU%YrU4}3cI_D~McaMz1~ z7lL5hIRaj+fMwn%-M&u(UsQtIBcO8N3;*`eFG1kVZ&M(7Dd5HL=iuxJTBef450=m3 zd$COfoGNAnyvTv6I}E90J6#`u4rS*Fe4zv}7Myb0AnHL|!AqaRe1Dx)`bvo!w*BgN^(jaC8yr_jq zT?l%?xEVT^5dpK`9wG}GIm`gX7CPwS-`UHS+&HPh?;pcCCow7Pvk+jx0`UYvncs{!4v0^J;e zFLWW??ofeFrWY6HfKF@M?)oRb`G}77n-?24Lh=hVsevhQdJ_qQZU}qR>5AABh9_Hy zSYN0Whh~d3@TMvjuNR3R>t0{v-|j0C*d59PslC>$1`oo3;u6$6%@qPCBv7Xg+&l$` z2*zF_@L&h%24Rpk*FOO-o(aOVfyW&&)&q-JU*PZE1gaXrS(OL0N&_;|1ZKW?_6!<^ z{4MQpRRU?lAMok{OMwnm5P)p%&ENi2eWK#4J$j2uaC{X9D2x1Yh9V2-5Xp$t=*u9FFcLu=&0mU7`OwL>OQ6 zLbQS`=3rr92z+q{Qtg9o)M)~Vyr>3gbmidR-vKhG^<=I2F3>qF-L4#IofAMpFFYY; z_;Pel1Q{Omq62D%FGpu1NaTh2tpEQfL_>DGaIZ%R19198n~w*F0}seK-Jwty2fUd4 z6dJ`P?8XOPf)+V<`*JiM1i7Ho_Xp_Ur5~X4gSuhP0BvI0#v>5;;@4kLfyWW>Lhv7$ z(dqgJuKLAZerQ1bNb6(-UF^7@sr5juF{sFcduJ!4ob85tCu8RS|Ik4A0lF-~W9I+= z6F{4Qz|-|w>ySMd+WiK!K?rnsW2Y+*=%N<>KB(iSG~==Ib7gNC{ zBgj#mP9iVdXZ-&U@@gq3#!V!ye>z=xUZ{breJun^pWT51pk>_P5C{+eCF1>o0_N`<<>(F&u@01|H3X%4P}~Xzy*T*?&2kA8%TG-Q)xb+2scr5Wdr}+)8`+1JL z{s3R@(LNni34FEe z6qIPsFfuSeres3FX1RVygPiFJ+T{A7^<+(Ocj%9xOxG`<`Q(5X8>fT)8Svr-Kgcjp zGvh;dC}b1a)oGv-&Gkd;ff5o||Qz5umDL3iqa zYA%Lu*B8y;i-N3HAty0#dB%fvJ22>=M2>C`j=&e`!eAGIPs#=raZW4&FM?rWUqFSA zK;R1}n1BGNxB@lfegwSO3lRj}cLz1%PZlHCwb>ULKzDfW=Mf0(4ix|~xBCSA3+xX4 z6ZB#__((p``i-fOB-ITXfPDz5s{>wSKn(44{ejCQo&bnJ(DT~^UWg(aGy`H#r|TE+ z%^l$Of5?4UktCc2s?UO6Z2Aqh`z2^}1)>h*h&^z179f9f1it8ksDmg0bpubL84sGn z-3k-?@w)QGi^>20XMk=#0(WJz;3mdqFdP6?rayvS9K8o~jt98V;@|Ee5cndW6C8-J zYm^$`=73xl1he7`)a)ODFYI7qKVCDvHiE><3rl!z%VGo>{v+Up8bm1IMJ=RZ)9L!- z*dJF3AEk|R{kQ^pSk{N zJ^Tp9D@y0WZ#R zfg%vp(Rcx!ByoN6V&_C~v)K0qXyL;Xa8BR}2z+trHY^ElJpq*f+aU$(pTHM>FsFz@T>u`Zn86P=Cg6oU#DSfzKaf3$Vib6%@t?pK zEHIN!PlWgdY?2?uq)yi_$6eomsv=O^;SD&l-!#^~`Cre#z~7q%n)Bxa=dyLMoO>gS z4{X3(m;kghbR+OZ7tG8DSxnvF^{aPa0l^Bs4X)eu&cz4azBl;yPdV}D?i7Z`UuSq2 z7)r%6+8G%bGB&)N%aEb*YA(ZziEZF}WV?OufDUT7!N0%dB1pOIZf>yZ4v^}OS92LM z7+%k1c##ZM9eM|J_`?nU?LCJ;sso{!<_b9L@qh=Mz@^b=NLuN1{Q|dOJH!HT>i7}( zVj)b+4{$yU{SowHA4F5Y3sF9B6m)_XnL~ZE9palHPpp2{A4{{VJMRH{EWPmOf=HCt)i8#sv zHWO5*y@&*x5AMFcsAU6-L#jdW9w6Tk+Zha?Lr}JZI##)0wcryVUo=9@NCQn&><{H> zy;NEV?wP*e04oB|{Q$7?IWXmS zvRFXlAunb_WnVPGb$-bB&(FZn?RzKi1urC=0$#MhW#43Mi2x->(0sxUIS|YB4QTY@ zP2h|5kcM`^3penhPL6;Vd%@axI$iI83YR-UFJz!W0J`eZ;YA&|eC7b%xw;>88F8xz zc=z^oa47}y#0&6QWyj%s$QB5&(;h+cVE|;W6|(jdP?;C@5NCjF2Te#l0Sz?02zW7r z5gZMmp(wEN9k3vH4=w}1&H+t9^Mm$0yy&_LOR1n6pup2LUjkk%K{n$;&p5TU<9s@Jy0_1S9KTx-WO^AoN=RyVp zg8~EiF5cDGV9rqiRa2llm`^Z({R7&~0jkk21ish?F{RV>!b?@q)^aAW)(wyp33lU! zfEN>)LE1o}`~fu52by4y1IG?a09bh;#P)y}6)=6Ep+3-|Zsy=-4!A&gF&l3A3(zJ( zNDzZZ*&HF-0$y-*gEJd=wkPyO^C3pa(Qtw=M}mw6jfgWq1Ogyw;}ZwSd7#Ju)k>gH zeUT4d!U__~;svLHa}X=Q=?By}m$4jWBIDAk6?!O1l#D!U`PIECDYLLWJX+j~H0Lc@aDh zS9!JLjVc4fi^ucs{s-MDDRS%o|DDyGST1=t29<+PUPyKR|DSOHG@Z$?6LbHFn14>;X6 z9|B#E0NxGS{DY%b19ap==0%XpdRs(6&O$lH^}qd#%nnc@KMZc-fClhy0?cFlp{fr#=o5<5Of|0$W?(a z?*9Ut1`adj^RS?mXs$J2C=r70BWnd&{Nid0s4=zQ_Y2w_CCJwx^B~^q2RCs+j<^CAR}dOnm~4ke#wNT9Ef!25B}{gflL7}e87PRuBt(%AZG%+Y3@bw4@jtk zJpi`4M--MS(>g&16%3Vb06_BlAygN_V^mG)qdO#%A>9@ww|0cX<}4&Mm{nO!3&$mah1|NmtP z>{!(gFEkn0_=OFw6Wj!2Y4a8h*Mf;h~K{##r2SY?e^tpu4(+kP;UY{oC}^ZU`Y;=GM<4` z255x-2Y5q=i`TywMj+RK4mpL}1<5L|KhnB+oYFw2$nt~j08c2s>Gsv=beZ_)1vgX- zv@jJsg8L%#D=67P((8860R%g~fCNB;1TR1Z1!z?rc!=tSJya#=sPsB5e(-q~rTpOL zimy&5is!T5fD93@=GBUjk1*OHQDd6)?L02(=7@%WLK{Vo2)X?rX zu%rLLLkL*-f&BYH^OvAyzcpNG;KAO|Kd(8`Ku3~-4(;3S`ltIT%nRd=+b6alYkd`FoXG9j)U$d0dM;I`42i4r4jfd7p9;@_ys7EVP^?^c{vp{ zipa{p-Blytg*!}Dsc;q>|8`%4z!xSkp%SNEG4-G&D4}0o^n+G2gKqrd-|y;ZODA-VB}jJ$Ot?fd1Ef0x zbU6n9_E43e7kfX0lR9Wt>BYg1U^ckR;gQ9}za6Bv2d-Bwi!sC4n1SI%CQQ$TAh2;S zZXjvo-vLqsGULU;zaaO4&Q}C`!yxd5J=`!sgg0h^l)cUb2f0DO3u%~|QsFEXNLX>e zgh~Wnw|Nrmx-2hs>Y7+Fq0n(ENIUc+rAH0zKMHj+%Ab*5%1idIn*tUZKyne`a z&x=ccK>Z}8oeT-W4k_~-wB{(Yeqt(Qt5V|067tOKb5514_=Pt>z=nturJ_o{&s zHK?qF-m(O~BoMsD=0)KLaQuK;uaF|=2yC_go`4rApTLpbc1Y#wZK^aW@Jsn&*}q#W5D;Isf9 znR)RXq~Hj+fe*22+k3F<5KeaiTZN=$3qs3_8ITYUc;OGT8+2~84S4HB&TmknItbdE zygw9FAjpDekFo?Z8bEvUTzLXsSh9Zl-+V;iWey_)1GJFv)d_rY=rAmaWWeHaJzPjC zgTaV_Axj`*Gt87^1+XcvC15gO^L=>&UwA@fnn59eDjRAO^ga z(EXYj4xpIb4swYF+*-k1{ote+y5q&H57bYM9s8{&6hwgwZbE%Vuc+w@y zh#%~mcpg#|=5OQ1Vc0b;IMCwL$QPfD*%1IHUE znRbUB0MC9S3GjdgUi3qfO~4B_aEjpRbOp`i|A4J0%?K3*4YPg-e9;E(Tk(K82cRYR zpaaI8e}clZ6;hMxDEBhFnAi=jNg-PlMS4K1AVKF_-0FtZqLBTGCd$1GXa4{HufV{- z5TM-4umO7Kk&kjO=nf->oZ__j+|)$)F+ri-pd&arS`U;uXE4-)oFfqUq8uJ2oI5K1 zO=EZ+{#rGIAq6y7DiHJ{5=k}!By0JaeTM~zVUPg|+HTNhQxmu%_8s7g3v>b-52#Ap z0jl3#v+e-ZYoPg$Zj?nOSn6k3)eEb?o8O3FTdual0i0G`KkS4sd_TQd|NsC07pp)g z+JUw|f>ZE|*ZX0~O#(bZb?^ZLG?n?Vet1#)AGA~_l&3TF4|q5Zei4yFS|@mY80gef ziGvT=tS{6$L7J*Fn;+RTA3FGhjeon3>jzNJ{ztc~Krc@Kl*s{Nf~GZJG!(u2-+V*_ zv=Zom5@wT2n-ymy$m0qcUp<4_A(TgCZ!d{ z=cIxn5!@cZalSZoxyp{!TA&i$6>^9xmYEK4!Mzuh-@&WrIQX}>c!3tvK?>U!C*Obz zKghHY`0(fLJpq##7#Kj+4s_kY)wduuJYY58qm02B09*lq)~vj61^1~yr7-Bw=d{ii zuS=jar}@C;AoyTpka%|~M_PA_8^~;s5|A5Syaw;P_Wc8zBmph?DdmBz&4W1M1!(j4 zgqK=~bD>XnK*A23TEP2no8Od#_ty68lts)JA+`r~yK=B{FfuT7y8d_pI(r{9V=WMv z#Q=qj-Ju+fhd^!xEoWr?1j<#Q7XLvb(77zlhlC)<-HL#=^EDp~3IrdulYNMR+4Tn~ z^dtgbc<%wFH-{{N-q0x^Gnx++1-!V{0xn;UyY_&J?HA&pJps`2RU+`kjlCc(9IXdR zc#pgGfU?w!ub_&zJG3V#O8}Z`S$cg~rv!onm*dMvP=%4jkZ~eu8bcOnaYq1nrN+UB zEWIJTQ-Z)+vQIF8IsDr}hYUX14!V_329f}K)O#6T7`1~EU_7LF+1d^&UP`Rryr^!6 zgeNpDPEqe=nDYPsf6!fD3)FiVa*7L(w_}|FtyhGv2ZIIeA5f@*_T`cmssfmy`Ue!M zB7rZy?g9mo17x+rjW&oAK~WCQ4<_NgwP$wnVvlc;?hcm_28O_HPz$9=Ac%n>0DOM= zM3+zohM*U(e}TpiKq)y(px5;ZNUrgq8ECQL3x#HItnq`6d+c_FnFEU1D?u-kL6;F8 z5kM9PErJCZ@gn^bID$ZDP_~}rZ&?dFNgvB$WX(SXYR&ogho0#MjYmKVku%+(+lPAs zet}(a>lrAkfhG;lbo+vKO$WX>4yqhqZ^>fJ5_rM=93s8_LJ(+`hCslJ$Yo$>cl(NT zPXzfKR5OC>K2SL=!vtDzEPyQ8?aC3*?JE%YV#7zUvtL_c__!OiVyqB!Yc#r#IfB5& ze}7ayxdkbCg|&i`mx=Y87c#AoxC5=7`k>j%a0Oa-{m}%at+e?3oD}r* zg{%B$5QY?UFLwO={~uBlfqb!QHz=uqauffq1L7bhpsViV}Xu>GKw%N%LlzHdO=_rb@ALC#v6@&uerKwHCJ?}5}h6PqDX0m?>j49-s& z>wk8DR#SoY&b{#Y0S{}Dz!!GlYzYZ#h5%5Ag+6(q`Q!ip36S^zow_LnSL3v^fd{0< z_rVL+AOHWuV&~3_@8AFb2X){;t>N8I!43t_Vu0rFU)*{O765I0d#weFmj^EngYHs< zBmv($FSdRMhZ;{>XXuR=E51XAHC%55yr_nI{0q2x0&kvs(F!;8Lt3}%2hbXb7lmLm ze1Cw4Vp2e6;90T`K0$B|s1Duk`T#V52CC1%mEeoY?XY+UEg}B`YDl~g1sV5Rn}2)g z9nh%wA9y11fh*=q>vp{XcF2owpkeLpzHdM+3P>^mEm-=v4Q8$=v~q;S^NVc|9iRh+ z_q!qtpZ^FJbZ=f-fSW~-YU)Ygiz{%c7yR2pUw|A1UTnJ^yqa6=_$VhlS zmm%W;XhD@wB4qhhC`Vd16KD(oTteV1q4<0KL6_!U!g;7LcoPPsJMa4A-~-lfUyj}o zMwZUd2i;$KAxl2~fR>ViCiA;Jc>Z4m-M{kXg?Ihk|DCQ+x%D-A2e5r zFqBAxuN;7+Q4TP>`2gtZkWR+eGN7^3=2wiM+LI%#QxHWKG-BG#1lsfqK7W)EY&28r zffDX+-v|8r1v^9UyjJP{!Vg-|1l|PM9r~c#iRJ$V&_bdwFLu@4{m;MuM5pf^P`_(G z6Eo=IT^aCl{s+xfG7KdSph4Ky19cY7wNDsIIJ$kGbo$4E8+f@d1;vcBB z5CmFagRnp*;DtSCSoDa*%YFa;|9?3ZbjDrx*??Zr3kJOmFCN!|>$^C}DlgMINXi1A zL3qQUm*EYxU-rbHm!T{%r!*B>%Yn;V71(~9JDsi%I$fW1y1wXiMcJD}WcsMcV0b&1 zA*12#T!t5);?UB^3(&2H69}b}P9joC0%&MpKPjn1wHBO8UaSS3;)t146u}7qTT*$E z4QdI$h8)K5Cg_FCJ#bD2wO<6&I+?%;sQDmMcc@4w*9&`)TF~)j-5j9h2cU%1$<+WQ{LQfsVhv3OY4B6nFZ%15ICdP}A2PQ1kXpAUFZb1iW|;UZyMYvIUgB zqT%Vwz_^#;MRPSMeZ@5&QL%pW;#xH%d8L8VmxVDReYqH8NnZ-E^o1vJNkI!AA#mZt z11@~nK!s1Kc*a%+28N6U@8&XOD7>G`@M1;`TFN4nrhdX2z~E6tjP)4clIH@bE=5aI zFS=b{@bC8kt?3i$4t>#FCBgvOLh=OEcmxfRgYM2|04D+d{esM)PtrO=KY+Qg6ak7; z*AJjTh80~ex;+G7Mc0HXP@;STN+zh~%?ofjVFTJN(0ZWGq`CGDxSV*?>H7d0j}N+C zB|u#TP}G5v3}|QKi|#;~pcmcXGD75~2xza@>wn<;ixjNiyil%!L>auL1z~{mzX7N| zKw01j&hPl5zyMmVYfM+irfL1GahdzN+3ZQ9_JFr;01Cj#oi3T@^UYz^^>Va{9u5ROg zQ3JmV5?UmHPF=hOX2WU^{_UZ+AYuMu-%W591~r^PQSJKyG(_$3)vr_xe)MN8b{!ZdWd#V0_X%^F4uYhw6Ws~%%$LMw_xANFo3*p0VV-T zte_43S3vH#5b)yJcd!@0d-h9=z%|JWaH?VJ29@J4x_u>}HOdQ6V*C);9r~o(NhaV$ zEO_sd$jeGljt}_v|9^ZOWO><_a!7Ikrw;|__!pk+tC|IxQ{f4C@p}!dm5A1W5CARV z-T)e7-tc8ELx#cExePDPMSzpd3%2jz-GD?kBt(fwJD}C-FV=s9%$Xvmofj`we*6Fb z#gcEJRZcIOE3js1-xvJ*135rPJE12j*pb)|0$&uu*6_G~=nfSL0+kipIbaFkMYjhi z$OVF4Sh0b6ydt2U4* z4Bro+0tHmoqm~+ABO$HKu0wcUh<*X>=zG#&*9*!vZ@^7H@comZ&GF#Dkk8T>vz`sBA1?YNk&@>Ea zIjqN3aI}Jsg?Mr1Gbkm22b2VZUg$w&z_;HqzS!^?lo~?c1a-U0fV};JA1Vzx3yZ1S z^+R)o3`2JKdPc=H5p_$;JjeEQmGP2wp}co2eg>lg;-_U>Rt# zsr-nRY;HiM!O7-D)<1v z#j_6}J2|>J(z*rHI>9$Wc5{FmSsa~Qpxo^WE*k#?{txAWw3$r`!O`&pJd_AN7oi(; z9zd)rXzLjdsP7gBQuyWtH>w-3+n+|V{aXsK+J9FC-Tv+ZlrR9zk8OA5fX_jJ-GgJk z1u|pw;^ceKeT(m*Ymk0`HaeHccYo;x4MKp9OaYy43l0}hLqw+F?*9p|MZxEDf(Bk+ zWS@TfzxfDg@y?GI_3!`x?*<(=558KflL^djKE%}RD$ywb3Pi~Gs)Kzm!;9j4Xnz27 z3F@(Yh$kTZ0T26Lh9A)WW{5pTe*o?`Xndpd;o}$92Z>rA16Pk@Jf!gr=-Slq-n}LN z|Nq~qjBS)2d~S0V{|mbd;EVv;*#Mr<$iB!9+PA+Qv~T|sxaY^x*;?`c|NmW}HALBm z*t>f{yiOn1H7`JiEAVd*y%N+7RuS-G<882E;PvF$7uh>qL|b0)g68{nfGz_7jkJLW zvwlDav%qV@ntw6!_e_JVMFFkq_T>Oi{J$`TI1E&izwm@P1hikdyB9&Ec0pVNUT&X# zf&t>x&Jf-;FaCq(+P1r13CLoC1Z3cg9Eg^H7sU`qKmz&{L#GRG%Zu}%h!$sahcwv(R$~Mqhul+fo)oGyAY5nF!Qw}T-F*7hQ^f>i0Jo*3s zzW@UR!#1a0hBeT6icLnu0Hq!6PFQ{Gi))dD6N?TrF-+XGrT5eBlMUK7$3kZIvVNh0j7*^Ikj) zG^hreVhngumI0pfd3lEkaacPnm%!1=)9Kpq`cM{Iw{Jt>3w=m`3KA*1K+UtX&d@I}IzVe+Uh_j@>EI70hJKP((1JvdF63`3U@g)yd#e*+ZJHY0Jet?z>>;R4EgRe*j-_Gq1 z@iEvdhap}8l?$MCPzzoJfo)vf8@eFqMH{$P0oup}TD|cmt(ym$JbYig&;p&V%K{$6 zfAMb~EOl6d0t~cmefBAEaDhTKixDIUIua@k$>J)wf+sIQr_F&Ew!H{=@#!bL6%9(F z-Jx$lsd3LwP{ReXY)S!U$_Y@z`$fUF&k@ZwS`IE`j; zfEof|UmbvoFhY!Tgy@F26tZ=89mEDu{DN;Rg=AzOH&FeTfs~QIWq>j=DBD@Td9gDC zl94BX>WC1xUWNt*PGvRmAG8M5PZ^HUg-<4bZu zIXfFngX&5U2Db+=&+CHT`~WMJp_LZ{EDydYg?OaX^$sjsfZNZgCn14KK~3n?4nHV? zAhW@H*W$p51hl>K^`R`DZr3{jFSsFdhXF4(fvo_gksmu%z)NF%U%cRjP71bO;%@=v z_8qEV8P^vtK7;1m6d;>J{+91ZD)x%FB?}bij*UU>T6V zk*ox7NHhRDhNsi@!Rtv`JfK~LFXqB@wZL_OcDjL(mY z-@G^h8n8GF9?S53(<|cp;l^|Z(C*F+pt&q?xdV<&-#?&1=d@19+7-}PgY|`4w{G7n zppHKziNBi-4QTL;*qgLY-xn{kK&HHw>khpFuCA_t@~G>ZfESOBfx{HkGk(1Yw7U^{ zs@JVlNb&}yMsR)8{02w+6dG^r(D-EU4&?!_xZ&YT>*Qg2@$u__*s=fY;FEVmKpX#l zytw%lG#d-k42c1*fEPx`!R`S~%)$)>*A0w8FU;U>{Q_%T!Gi?6;2u0v*!+vJCJgMo zAE25XF=Ofu(GD{D#crrI`$IuzYJt~KdVoe%KzvsYNVWi-V)sG_q6t)7yq*f4J^lh& z1p_|$1f)_R@WtGtP)A<~dXWe*8J;&mr4);*+{{P>Q0b<#JWWg+lfB*jrWcD&ZcSL-9q3|CxX%1Rb;``+V==M#}>SWMDi0w0A z$yBem71a6+==J>&*c>vZJlcIALn4H-VY3@;**z*PhEa)(<< zpt=DRq}Fd<%uRwsFt~0g04au+`}=)*89+YmU}Rv}>C?*qay+R1Snbox0CF_wtmy?l zy$ofk$ws-Ec`5N}3^}QZDe=Xb>3Q*)c_|DT@wutF3`MEMr8y-Gpp*l_;QB%aI(~~~ zVh^!04Z8o}%Ztvx@M!t=q6V~`o8iS(aC4WX)AbFwvGL+X3P>EZn4Blz1;=z)bSZ-B zR{rgw-yn^Y7xTD55d&I>`obB!mRy>DyYDwpfb#^sNQAVkI$b}!Pyo+f)6CoiBT{m_Hq!Jpo zH+*{;Qu9iRDjA^Vl@4gW1LeR=L@*q81rO&PcfGS9u9xAs>w^zq>dA%#5bwo8%FT_KF9MsUZ@$Y50@&EsSP&)PS?_~g`QKPcd|PIHfEG)2^R#|2oy-vUVjD!Z)AbK%G3yZ)>o+fg zp_YRTMZ)0pj&WWGxX>2~coBC1TpWYyH1M&J;B!A;yZ|r3gPb4o2HdLv?_bQ~f1w9g z4_&3Q9aJ;k@Bj_saPaRx(Jj&oa$slZhZo79W-zEF`6A%O_x&(yUiA9@2<#1g5ClCh zF7O36*ee3Ppn(EcPyqZ0d@+3u$j_iPfS>_{)=MRVphIFF1iV`WZrzUvy z}7ZWT@!2(2w67=YIK?e_A(Tw=P`u(fSRfC z8Bhki1OmkeXl;opsPPZ(cHV+GE8xXNh+{x0F!05d)nK0nWHG+bgn0Tj%WEd%1J-X| zWX2+`*hWe};5o{8P)KnEyl8AINr=$_;P}vis0FQ7&&px~haD)az68Dyg2)7bob+NTO!FKV zqZwifNTVSrO?(M>Q2-GN==S{+_~J6yPaGh5Q0@Yq))WAdhm|S<)^A??je2N^qkzjTLwu@3!Et_8_d zUjkmVg3ad$cu@oKQ#VKrPbW*)i_@SLX|IoVgU+$y0kv5~8eeP&iM@pEG<%^1)(VR3 z#3m4?w|=9-yfYk6JCUY+Vl|btd2nT4zB!| z#qeSgI7}$;&xdZ2#vo8;1$h-z)w6U3yvPBE5=X#`WC#PpKdV6#hzwx=Y=9}j@K4)k z@Ogls=(!zElz%`qAy2@Iw>w}pA?O@F(DLZt%fL|&+PMKf+iNwL&jLMo?FZ=iGhdOw z7gxZ-904z+A&v@oAp~K7N_fzY;SWJC1R$psfEI38fNFTqi9&yNf-M9MX@Qa-s67fk zh^_^^LP8(_6h1GGgM*smwZ>~T@NHC}G}#UAD0~Tgu?waWR7A{$sDwo2gD@1YgA*t? zePTaflYhS}Xi00gNMmQ{pBK)bzynwNU3s7>@5RTZ(2xKvCFFq&(;s}uzzjNHjTO8S z3pDDuKNQsb1)rpH0H)yws0;+3Quh}cOyKzY0Oe#czIX~@f^LxM_T}hgnfT)HM{pE^ zW@{vn`~h}9W_yX@g)rDMq~c5fRGig<=M7(cTLN-AQgH^BOaM#rgI7&2*#?dW@B-ES zt{lxjSnI_zy1>)B-{vx8bbOo3@Zy3QczQQ00ixw#7qrCVZ&?NEbArkuP)qH_j}QO< zgGL2G0rLl@sDytPXq+6p(f;}e@H$;r(0RZDpr-Jfpcld5Mjhyuf;XV$IiSJ-be=0> zU>39s+xkMS1pjv5KOjAz1H=UaUTA|CRq(vN09sfNI=PgktJC$)i2CBmS*1-c|d0q%?|a7)19`U5)f1fIg;-|u<_bUgYJaKi{P!1rtmG%P@;jy(zJ z_I(iuJ{`^vyix*`E1v|sFa#$m4$uub;0?V3-L6kSB`zn(Rg4gWWDx<}?fN31+xH2? zprzoV0A$dMfEO>o0m#wm`Xa3xb*vq9*t+ivPzk-|9cW*y187nD{?H4pmrA@qz67;& ztYB_E0a_&mTGkWL?Rz8e#Uhv$p-+Ndw8E@-0$R4%?JLk7`UG^&dMwCTm=GxA-+AHn z4m5WSTbeG=?a~F_ss&DS96>L3gVU)1sEH3=Ixo;2`T%5-FvuiOL*`Dvi{lGH$p^Gc z=0V^KE{N5jM&JKMU~%Y)V2(kU#S^5yk%6th#4-Q?PEcQ7OnD2NKYr2q_Wyq{AC|EG zyeNAM%3%9l|A5+wXJHWwUS{+o=*5mr(AYf?@S+A1dZ45V?qn>o7YgVghYQo(lLH?1d2%)v7lS&T0N zA=ZE|dU%4xDicE14~C;}c*;CONGHK-T>ot;@L2su0R&1O(sfJUQ1^BifQrB|JT zFSfn@|9=AL{<8q&z5&QUaQV-Hy4(V^0=HBiQXztiQ}C7N904!tLB~HF5qQZ2Izs_6 znZptIV&+DWm5_s){%(M>4?wnbodx?1d{)Sd!d6&Jse=c14?bXE23NW$c1T0*0PO(> z1(87Dixpr)Kuvd0JM>S`i|zA3X@mom1^z(f0$wD886c1UKzBJfzi|YLGm}2_~UOm0?wwOx(U2PE_p5_%w9x6{2Bl~zZNpo z!T93yI}X_iE zYW#=<_J#@s^+GO1hpvr$aT6Q>pe0Hic+x>KIA{c3OMwCkG|&ah^BjRMzJph-3P2X{ zc=;kn060Bkzh4BDtod7JGB7aox`M_-zyrU~{exE_r7**qAV+{0PVZ4QFO72<&A5jSGU?Uy$-+4>)optlzx& z6`ywgn^@ZdNutAV|>@avPACzo(Ks6Vr*_W^yYyqeR z+3hP6_~O7vP&VTLpN<4c4<}N38D6~f1f>VaT3%Z(NOA!0%eauz3tmG4YDnKnf!9}{ zr5yV~Yd1Q%UaWlz3dR>|U@xg1rkab76S~JV?#L z74YKgDo{{>DDALLF;^-65k^Bt| z3@?5|g?$A&8DFe>0u2ML4rKfd6Fss;x_!xPZ@V36E?*B`A1 zN-97d?beee1zC(Qo=gXaN2lu_M18@*zn@2-^<*t?7SoF(aCuN?6I3cgW@OK-1bGa6 z^vjD6hTvisTm(;ns1JA{4UPs-W!}m7;@@LX)5Z(5GOP7csT0DOtuU=80$)_ZjJy!^ z!WUu;Bw`Od{{J7=rhD^Z5y&ji8gtOXoc$t>t(U+ND-F{D3ZFiZ8pv+l$L^4n1&LNT z8QT5kMa5%K;4&~Ybi49^E`_oH8v)vjXT-lhl%w@hi55f#RDBD88hO{IfkKNT;Ds$X zd^tdixENn3fNX>406S#@SQQIsB#rR}GeWXXG>hRyF|y>dN00<)=Z>BLLF2_?&;tUH zQe0X$3m2$Ze=+CL|Nk$RKl=Y4G(!TqM@j%ZR1Zslpw2kFkbd9>ZnuKBcYu41FF@y8 zH6P)5kp?m#lm~R-&x>1AL4JcYcx6D%xGyi3yWRZ{+N}d>?Ri522NENCk3cm(=t>Nc z6`*tgJ_8ec!H8hci^Sz1Ar9zjmd_6%)5M^;k8qGfAV-9ScE8C82<&CZ2uST^02N=L z@*H#!0BDpM>ON3uuHps>8IXEVv7Z5&oyAap4qlpnaYd*H75fmT>85(ThB1r5ZXbAx1@b^`4m49HX(|bcdfJ$x9#dp1+ zo$k}YWhZEbDrf{iAux;iMaU~qSqVDf=0mruLO0KZPTwal_CNUle?nR}=-l;JptT0z zH3FbDFfSNEi2+nVx1QwhSp*sg2haC|?&S&quaYQv0NSA<5d;b{e$ZUZ3np+q&(j_H zB&gd}0+j9xz+T`0otVb-BKQF)YC*^2S%N(PZfAiv#J}iR3iCVYLexL42TH`itxj+? z-0i9m@M76pu zr$884j4$p$nBAc=olGzG-~SJr*kj4=Wq7gP8B%kAIy%fQko*muKjq1Wv?V}wheS4L zO;TB6PJCi=GJGT)QUp-4K7rWvz1^-H)~-DD;2x6iAJ7gs(0MuC$j9VC90O^8!`C<9 zSpU%cMg>|Q;oR;DX~NfwWQk{N01a2ke4oqkLQw@gTm_CLNMmU}q?Zuz;@Em{jDimI z2AyL691`Q8GzDHZwH?j}UCI0-;DsAP0F)toe*|VQFfcN___rNo4rs*?Xc_>rfcrSQHBtwKw(CE#dz!&l0 z;sRV>gZ=j>=mlt<17!L68_@A}pw5^jT-A##4oEqx1{Zn)T2tA2sYE10H;#d!8?+t9 z6Fg-Lo+RB59x)Kf@OA~A9rYmSg)Wku>xpWE3rGn+cq%u4E!aHBp4%h`NCt%`bua_mzOo7Ltv#|6 zbV?sMVIyBh4jPMUJy0u>m6f6KeJ(@B6i`YIR|KbI$ml@ml^5oJ{{M#_=j?jng(mm_ zJYOEr(J^1aJ$-PJf1wER5$GTcaJ%)z0f>7+X&{UL1ruEQ2><@jBh9~fYDBV1GFE_W z75Ooj;l)D*u&v;#HTxoH84yQWr;F%=7dt@fbHSrB-~(zx&w#F=OY00h!@uA44CsPe z>w~qrpfhUtx4VQs04?1*16n5gAn3(8aFdaPf4}b;(4y5xFLFUfz1|JZ8E1lCgcq_i=p$8neC<^x`zU4Gg-L8La0< z;ES)|P6z0k<hWeMm-O zFGE3oc`>Le3GIH<_(p{nyk7mzr~m(VdNMOGV5H*Xtq(pymYcnp4L!%WRpayj|1WAm zypw62y(%DHK4`@+TZW7?=$4RB@aiy;fES(MQko;+1$4b|zzcRrJaxA6fF{4VGrpIC zH28`HzKDgXeF6!hfbOXvH9;?~fJoOuh@f&q1e%c_ zyaK7?ftr)CNf(srpn<>wY3xJgdRtjO|NjpPa*!FI`wbvLr3X%xECE^k-QeU9@PY?? z0f7j_N|=Mv=YcFjL^H&Wj6Y!@3n6j-VlpJzf@0!DI3)HvTSY+mff-a#O$9k1=*8aI zAd?_Vqb|+@v(q|TLq5aP2sps`w}TE^Vnp#CG!5}@hXn)F-fVF1lqKLr5coWNo`4rS z!M4L(+uQ5&`Tu{AmqA_!owE+|dcX@|h$@hKvludrg&7!L1b{1Wk+jZMm(TzIcTWW+ zil7%+Fog#|;RiPC#WG0yC#|y;#OL1*@g4tmu*QHF-)F*n1~RC(7nJM+;qeFdZa{_z zXdb5*6heV7u0huR27p5fq$lXbWJu_MnpphX;eG&F7xdygBoqT)#DTB45eaya3Mprx z(apaf95}59>Xkv&U@yqWFBXBeID_U=LC31e1iUaZ0q?4l(?N*b7jAfl@Na zGH8H-0|S&aK#>MA2o(MxCkDQlHUp#{lACV9*are$oP)7JEvTs=vw~h!fy*eE*`VpE z))-JZFbSOKKul2L0ISVne6a>RD+fuS8z8#?(mGpHKt&~}T5tgAi~#X2rFBlV0r9*( z|Njpj2}tW~)d2}ug0@NT_myZpSt0}-9+?W3PynrZ06V|{TH^MC7?8o-UKo;W*E{Fsu zWAbmG3i4&pi)GVbib4FB&p`A33=IDny1`Bjc%g=HUj?Xz$qX)=V6Lw?4Avd+A|K*X zXr-H`#=ropTDO8rIB3<%za5-HK*~mjuM=U;;sZ~G@dUhR1t(%~vgF?mP6&aB_A@xZVbxz2|BDk-!TyC7 z9iR{ke31eX16{rYjwEQ@`GN~Fm}6iS5!?zsc({Wi4Q2)CwjEHJ@FE_?(APm3EY*lK z!*mGj3P@nXJhT^*C_qlj5_};K(T@_cNOA0>AV@2}zJYUKG7U4oOgGyoi4X8s6>&c@Jku zdLugkIV6n`5-;2!T~(+j`L}~hQrsc=eG)jtK&j@1Hj*d$A>uGkw1bZ1z5N#C#!!*g zOLg4*`@spJ6;=;|!s^8=kOHK7P)iq559%TU859|_Dj67F>;u>R;B5C|5+rlO-P{W@ z4HVm;SPXhG8KM;G7H}yKs#{)YgRI*RE^u2K^j4!0Wvw@g(kQ*1=YtOeJ_vw1jUOl=o}%Q7iYoK`=QXaM*5J06`(aYQjrTb zFpK|1+(bk`E`qSTeHB2P8(ZG|{|_yTx?L6cw{rw$@xQ2tC;=6D85zF93@_@ytymsN z!w&36P!$8}JAiu%xT>AnO8)J=AjgA(3slYrp_QQ5z-KA}c_jGFLWdKD3Xx!4Kp_c&^k|4HmLoWlUF$Q8AHuN%p znztafRzoiX$cG@dT0<`bsNDi$D>n2pfSQ4zweJ!Qy$t?ksYPiy`Q;2Hxdlcbf&p}@ zd3-8E5<_Nja$-(ud@2K&X2?vPL?DYH%b~Y*!{7h^1A2Qwd#WHOMGN$XUI=>e@yWOU%|{f# zT4e%ydp-XD{}0;w5%eNm3!)ojs0i55-l-tjpciM8L3+UEg3dHpZ*K_&SrPEU3fd3`Z(VNj1qr^m_7a@Q ze}GhheFNHN%)fn#FUb0!7v+86R0I-C>udoFzF7PcG}YAv?q7fhN5KQ*wVL2emjzm+ z#uL~(6=YaYZ!5?d0a=Wo-JlAAFF4r0|8G7b(>oPxdT%Sp36L%r=)nCKp1;9i0Goye zkHMg?U=y&uP%8^^56Ewz34~IGZlAtCpp|1%V27QCB-DteUWOMLI^cu~-5>Kx2b5Al zQEvU_#abOmN}a&Uz`&5u1lbD=+8ukWsh0udE>LZ4}+nIR(k_sW27;X!loQPJC)!87TQ>rsqL8p!Deo8eIXeMfn^K&l43q4-&zyzoR51Npc?}fzEc2L&}v>J0Bq!SVF;wYpcAMk<)%wPeH zgooYsPtc3d=isstv@#Vm z5)K;nc7h9mN5VmS7WCml;E{09JfRF+2(19(ImJQ5DN(9|A076Tax4}Ak3(FTu% zgGR}fk>q?|w4Q{GgoAG2W=E0(uaOYR0FQ)&%zO7j58hW`PWhdul@R7^qAow!8%&N)I|i0bJTX z_X8az!h^GMd_W6jP-*kR@yY-H6J9rgS~#KLavtMg zOdjh~wPKJpHVVgC8o^Uk(qLVevKUYc-)>)pz!&~$Ab$zqDtHSr!P4XwybD1q0A522 z-V5!$3@_fRAs4)b>PQ8zi8>@vfXdw)?TB*Mt^-l-8h0SdU9}EGxhvO!D0f9V$SZfj zi4ig%iM~I(`He+*Z|#YleApTS;E{>!6NobqK*uZdaHVznuwHlpx?f}hbch05lz|TO z2Q9gPobUlU+8t7Tfi|ND1inaUhbDs1A8DN~p%-4ngH9uQy%TCDKWw!P_+ptCMiABD z>6(KNS<*UPcrU!r1)Y7QDFQl0J@mv2dGIu}t3d04Qo)^|A-S|p-xDu5!KQ-m;sR~v zu8M~C|4R6GoCWK2J@Mix=tv>ZSeGw2iC@jU?sjkUQ~l( zU>2zR2Rhm&_y7O@JH)_pu1CP}39<^b&xRSUS#Z~C@MQv_Z(i7eqlSOSSsqXfy1oI& z=Y-d>JLADd`2Khy12R4mW;`FrcuBCF>yZ}>|DpRZ1Oi_yiG=w?aF-Vkb4yYpq z+V24_0$;pP_y=A%_7a@3SUOz~q;`=BB}`vw1*^M$UlGs{&2xb+b(UpfQ7?({%&*{uuu4zGpzQcQ1lo)HcI> z`l8zvv}Srk;ES7Z$4YjGZs-g>@M8L3P!|$>O~8p4Re%5gpYXC0l=VPM)F21%Ol<|5 z)9Jb*gMopWfq%d23GkVapw%%y!TABSI(J3D3m!;S8}OnSW($7{C^dEa9teDK9$c}2 zT5FJ_Oh8V0@e0z+>U2HO>$@NjbO2F?P!%YJ9te2h#|7?a@NWlQF$_9y<;9;SutPv+ zQ)d0+2i;BZVkSa}AAHngtup_1@Rn$afEPUw(*wGFcLcu3?*?n`bY1gWu{%@()Rq99 zK)ECEMJTwL$Pw_u2d<>Kb`1l6-#ySO=LG)!p(psavxHtSpT-dIf+HLj+k!i7!HL)R z$_r=EuKL#spncaF0>+aWK)0^Do&a5l0n!xsVlg|oa>`-`A40(q^uh?@Z15n)HV8Wn zbn*Lk-z%WVyA$-HAPiH-1-o4}(z<<5fG-C)@Eg1>AXEpu zPOPaB>{)0sTmqSbJ^|iD(Cw=NK6s=bG@A`F8kF1@LDbLablm_hIKgL4p{7G?*A2A> z5Fhyd2z*fh(E)Cmeu1+0gVz&*3q?ba>92P~)Vp#7yl{Z30UhOb1j^nY`T;!Rz!La^ z@i#aX{(+RDF8#d>FY@HUrD*e!4C^;94$4EzPS6GTvv$6Ke z|NsB%%lM2h9d`vYJ41iGmTRv4@xNZ81|-eEz|c?(+TC&7^$Um%+Hw!tGy137m8X+u z!b?z@-FyVJf`6_YB#dCq1CW24-=MAE$L;W791aKF7u0-&qto?ABgj<@44`AAe}JYT zUJEqV{$ObM|G$Q#`ojd`rXG2!evp^jNS}zG*E{WS2N=VKCue~;7 z1qU2BM0sw?G`>CqTKM?p#X4Cu?}Gdb+b@ILd{FrST89a~ont?!47&=68H5F=Ar|13Js`Y6Pf=Q40_5M@3__lKHS} zH~)O*7jWg^*JqvZaRNgz-)DXS)&R-L4E*}897WQf`E@`Y@uT2koh9If4y0!UT6zXr zWdw1*I>H)c^C8U+S7OXhg_*wwTwa5!2v7|U-KKP08aaG0(lgv6pcKf!zyR9F{sX*` z9kgMP$1?OsZA`c8k8WQMa9)J@RHPexnGnLiEE9^1x_y6ihjM)8*8y#AJ`b)8SOQ*{ zL7WE~DF>gT{9-F)%?v0QUQdDq1ZcC49KxZ9@Wym6EMTbZUU`^%(;%^ga4#!%_vT5# z0~X<4SpL}ob7pfb2V*T;b1ldJdP(rH65GK&ZkB)-{~+N43I<3ZfL0GnA{z=`KZbGN z5+udxfm7W4Z%16JghBI>%|G}{xxnkhUK%knFkn;U%hUW*9;E31|N57_;A=X-yVJ5E ziuGCFFi&DA;{U`iz-sV(7Q-igLDvtjc|lwU822-O6zE7CU!Lzb!Ih!$C6KBYFN{K% z7`jiqm>tW+@QGi*_r)jvxD%iFBYZ#bYaD!WHHHavrCw*~pV#TQt$KiJ)dRRyNEY3A zaWWWekrC9Q8=v?i!4^FLS(F2}sJZqJLyZuqdH|huTVKWwI@+)PwRCgspa1njpn3sx zHF`ra`wmc*@S3^X^#}CYpBWN}SOtea=J_0;;BGxoYw?+13oS4{^9#EEd7%n%HiGMe`V6G&%Zv9xV4qb$b$$8F9|zX;;il^c&_1L$ zFaC-noCZ#DNaY28_yLeHpnT60@FKYq)O=y#-+!X{r+uABR!+u=pK}>9EPl;pc=7$m zqyNoEK;t4j0WYkO6w34Wtp`o#?FS`_IxTQaeddp3wRk=YbOkj}^GkWKgD*e$%&&Fg zGk@eku#K;^K%23@-)w#<5AOY5e)O4N>(FO@0Z@qn@;e{bo zi4;HRP!v!-;mQGNCmaXw$>Mm;3N{{6#vT?!3psG`A=h`P;ip`I8h&9J2B7d;02+4P z{v9d&ew8B>%Gbq#R(G{t0)-tkWuS*y+`-TMao`Yzh8;XDpatM5NcciRAEH(Syc!Bz zhCue;aomjka}%~3^?@j+7s2TldT~^(8~=V#jA$K%L>Dx!Iz#__;@9#89o=;Bh5RS} z2%e(}l9NGs-}lQW{wUus5O)Z=f|B8Dr`Hb1rohd312W@Hx9b~pGoFCVc=DMa3BvphDILN2q4^EZan~;(0n}~il=%M%k^YCNL-Id3A&Fy4G6}Eaa0OCp5IB(D zu_6NLQz6*n;6Qo?VWR|65_sqb5=h4&@{q()DF6wi|EdXw6Bz!h#(>EbFqvUE0Wz-# z3N8>PVmz|(%^U{E{BsKE0DN`Cu;lSp&{A(uC;7z|&`2MsQ=Wa|KlmIa@Hw!cNxxkX zw}DP#0oTo-$*tEsY2ChGAj=1Qzktp@0u`>H^=e_93=H7mi90V6|AWR0Lf?Sz#0&wA z9fA%8dK2&>0+J*^CW0rB-UPmIg$um^k9WKXdSL_?dIAyxZ5o?j01nc$&ej6(@K-O0 zf)2(6yFf=?_*<-)89*aoce;JA^oBSxK{gV+==MF+E8^H0dV+ty>x*vR6JX8}2rYQi(rUKP}#%3J#w=Fo zyX%sG7tS!Tcm-bQn;>wmxe@TKM$n5}aG@J7SAw?w zfX=wg09^$CBL6H{Cuo-X#bodRrSFGc5#IyW(-=BKCv>|`Uq^9Il-)~ERU1z162%RP`goEl!pfG;+j0J)d} zbgRS*E|7?C3-~6Osh}hLU;F@XQ0V|`=>=W#@#5Jp$fDcOJ1=g-&gFa)@Zx_-LH)@Oa#pXjSouNCx(k}vDNWrDMLwA6^upte61BLG& zP&pQQ161!b9|DzYpq2ut|6qNJzc-zkfdQI7x_x(m%7t#%J>W8EWdq0)ka7%G(Cq-p zbcgN%7d;jb1>L@TKoclcKf!BzUUa+e0f*8a&~;T8A9cI#&_2}Zx&xYrpn9QJy>NvX zk=E(D0J|fu)Po(-9l8TlB#D9T02SLiz+tlku4xOzihcKJDof^Od(AeSG298UkD+jR@r7?IZLIs@*A z4G>3wt$L9KQP3T_2judYABbXTyYCE8Wwj*eg&RaoTBqw2s3H6a$(waxuY>CmXmPpS zcMeGBf}j^XaGfyg`4N)y;W}ZV%D)|)A)uP)L)xgICJFy`$i*>`x}yyt@nRLkkZ#{C zpfH*P-hC7L0u-TJK*6#F8Z7+VAy>}uZ+D#$@WK^l065_{fXcWj0Wb6sqA!@C#)fVI z1&ix<gcu1v)yDf4}b?Sk8V6 z9$^99I(!A3SuS+DUT8kR)aiN#S}r_*mkSTT<-!Bdv>ZfteO0&X1#m&?yW+)yukaQM zxS|Ii;Iks=g+&d>**x987eFykg+o;mOw}2Xsu0K-`Zu~=FM#9e0;C3m)@?6yz|BKg z7`a2j1(Xh6tWE=225JS|0o7QbFw%fXgM9yz88lxFI{XGytGsvzI(HM+O2ye_;_p2P z3Zm`4;B$Wd1icWqf|k-HE|AqOSJJvg9Md{O*Swem+J&><71aFu(H(lFyYxz0H;Ws% zf^P&%f%^Sd(z;#OfW>k_4gh%rbbwO<+?`+eK?f#5PW)J93A0QaHZ%Ss=*5v#m^Xib zw1aL=F+^y8y&p-bCqn5<&}muVF`F#L7YiZXZ)ocn&rKJQrfj`F|Msb%1~h1S#UJoB z5ulltYH&*iw59e>cjy(cr)Gfm!MxrHnfG&8-OKQzjQQ^Wh^Y9u#v`Dvh4q^kN0}jg zmITIW=d0k6%GjeD)R(*Zmw z+zXbIHojCUp5Y5>+%5nO{W1KR%kaYN33veR#XQiCRFF5aFaBo^<>(BB?3d*Uc(Eh} z7GE!5A&q517Bog$UXkky(8l5yc926s!RJXh!K3vBD4~Oz z1p06xNEhfyzzZ3;&;w990VT7}WUx~}?QQ<;t~UZ+c$h;|7=Ozg(DtGIzBjr&@C9$?Ro-qE(QlgxI6SjC)0~)@FAhyu17#J zeR*J~cZVM7WP0HUmDvN5DS^lYbc3!R3Wpltd!Uo?g%m_t=pK-bzA$CJ3j$v($by=- zr<3W$XYgT~;Cq!`s3QUdbPguCCju(-xF?fE25Mz0>WwAfVfKPT-5JnP9I5yqE)S{jmhRaE3JF`S*u{3)L_er40n>jI;s&sOkT_UBs2~I{bxZ5?{Q?@^2>k+G;RCv#=L;y> ztPk?{x3GZrpn+Nz;2w!<59IzmaAzd6r5ijh0jWMaAotuslr_8vdH4VS3x5y+IuG=P z>pSRin>Suqy#uWZfh^rjldUwjo?K|3ushj zd*}^N+wM!ii^FjcrTb5S$`(**0`8H3j>_nOngZ%M?dSy^y|W>U32eoepcmOt$?XRM zUYv)UaquBicjyM~i=Cm6ZqJi|7fw)xAPcsD3#B#06iT4+nQqrD;6iB!sECk)RHNWR zX$!be+5swHiXrWa?$8~bOfQasw&j2a7j}RX_72eK!odej-M(A2Pjvcj=?(=M)$I$? z|KcP>XQ%5N6nm5)!ri`GIvHP-f(-->kZb`5z?SaN4d8Qzy1Y06SzH{zzumPXpc_;YZ-a`wm<0er zp)En(u2TYDG()xUZ};s9><*m}^r8?d^5O)fuI={S(8>5h8f3`!&>n~`U#J@X?Y=D# zUDi;M7fMj8eb;m{zIX~cS`#$9;<^SLnrryChc-Zhf(xpFf4gr7#6Leez)3scg+I(< zkP(ZZMu6i0(zoT`?|TK@>F(-u1-1LHbcb#Lr_>D)8A!4Pbq}s|hpqw3tbvZt_`ZPj z2(ARZh>QVS2X5`|jRvz}MW*kSz!z2!X>gGl^5_5mmkFS5!KCkq9>I+l-(Dhm1Xo_X z0PRo#Pg?SW^6Lu=eRw7Y-6+q$-}Oef?*(u|Khy1cruhJ#Bncir zPwaL*)6LQ8yX3{Rm!Px+s`I;jmju30hqOStL(g4EMy;I=AMjkBA1%yjx$W z_3iEjnFuM^zjT9*2X&&rj2CS$AZ0e_+Q=@5Q~38^0JW03eJ^x}Ol0Yt(wYHky5_zB zt+Ai|lAVcx0X(J#ZmhpZgS#UhJXj8P2kIhdP=nX{V69d6RERs6K;!NZM}aOT1-lM9 z@cskM(jTC6HD9lLISJILWdOARLE9EzeAI<`z806IwxCvXZ6w4R?0yHGd3f<5WL^1% zZl4a8&Yr1YuQojg*V$h#K0<^82PhnV|Ns9Y73`!5FaLwD3AxbedIr{N{_?^SBnO`7 z1@+-TbuYG!2>iW=!JRhOFQBgbkH8m6Ixz3pfx@BN^#b^mw-q3#K`wZ>&|P|=TVz_N zNF&Tep({W~Yu|YG|No22AmZG!|Nkd|Y9`R^!of&bGW!7QZG8xO@mm{ajW+*w*AF1e zzXZMzjex2B0@5D(A?QUDLOZCt23I;O9Io`GB64pPmrv_;`L}~RKHxnZ-Jxf|EzM-` zs5+=$_MkCgB`sLFYbT61MZeVR<$R7yYs*C2&k`R{pN+rw>$qq z^WvcX*^3>$44^1u;9y|*vZI%wBsI4HHmgL`d{O{(KjQ|_e#R+?`J{yox92bzAMJGg zbG-G)U+957t6(!rpgYYoW?6zxA^>$;7HPo(mhVLyQn*QE7io!kox(B#nm&>xUkSLiNPNb3#>`<1I-$#fCfMzCl^LQbb{OHK5z|SgFz0q zgh+#;>&4%{|Np;u@fUO-vP^d<2k7oQm9%c(7ipawu$$Fi1iaWD0{0^54tek$?H^uj z1kEEcfo_frc(GLj8ZP`T!mQ9R0Q(-J(9^I!SgQ`o!`-d|{GdxnUs!@`5EhVFXUo(F zAQz>9*1*3$nDrlYk~9ByUyZE)U)B`s3n*?w(eNF^bh-Uk1FefUU?0{Q*9Qodq;X2{}g? zto+U2|NjGDe1c4U1-#&dE7xd##R%#^YhQ%wdkJpQgBH$%9MIjl_X&_Z*n!})!hM`TYwMo`fNzsH_>iG{3NOfwK`(4!I#Y1y!6k6pmGnCTxP+Q z7(tXgm^O{!#TKX`z8ZlqB;YEbh9rPgOad9gzdux?8*Fv2Pr$#<-ZP-st@!;Pb}=Xe zv#UTSI8^xe`)YKD3iP^o{p)PK0!op+AQyuxsi~lI)FH-z>u8WfcP}U`A<}z5%E6|9 zr9l$>+j~KpKpWgavOzC`A!!&KqS+T2I$K0RA^PGE=(ID~h$1+}A~zR&L1hdi;aH#G z?-gJK^$tOP0A;rBUXU}vQv+Zhf+r%TLM&$rc<~4l_yI2>!TF5`lrSzn>}&xi+7~UL zIjyN6kAQoSt-C;80Q(qR`-3F9r-ICfNbdkkgZRxanL5E1cTWX51R}i+EDhp=r9q5t zuuCA)TfovFmw^ojG5EJn1z8C?)c|BR=(G%wA)xRAsSbLf40FC0IN%V@2hBXcIQkQ` zN##7~(o7^zYy#T@ay!@_5Chp6py~t?ZD47rGeDX^&H%{+ zUxb2Aego~T{Sfp*GXSgvG;5i~h*3b?R>CYGmQR4`z*9hkYFMADb?yaMYyr^P0$xnO z3ke?ZP!&(Wi)P3`KB&}!X7(2get;T-OCg#-ZHX7>{9zVlB34 z>N^hfGQ8k?hg_?7zXR3kpc>fv%?rPGkXk)$0%*_0fdhy$TR$G?WdJ2$Q1kEYfnEks ztp*y%d~yJ3JhsBvh#?DB^Mh8CfY;+-?pIWR-5>Ix(-q4VB8X}q+^7Z*pZFrJ4gswY zaTNfUUZ7lZ3F(Sw{_P!SZcb+aUC;UjG}FS-%`+kJMLD#jg|+3oeR;Y?7=vEy2N!A_ z;K&E%Q5VrCFT9bebN=lUL8b+PCr3cldkF87pck4@(?E^Fiw{7za)6G)V}>-#U}k|1 znPw4u@%JCJ=sEa^fq#1w$TUbH3%b zd9fasX&`-IxAj6zLv?XFs#)Mm)wo_H{(~M|b@2f#*uVh2z>DxTzqhV?aDsI&I}CAWI;Z@Tr4biKmCr{F8~lw-eO80JR#o zvxI_dgtWdxdLIP6cn)5x%Mk!+Q1Wz#H1Y(!FoHN7RBU&;^gelU2sG1&MgNna7t4|L z`?Nj?e9;Qg40b+fKmp>;deEYemvNxRFlZ^(#Ygd3Ru70NZ=< z0XQbWdxaqi4>5H6ih%QJ`c3c})S!SDYr!mmpnw;X?}5d@jss;TUlGuKV!fb704!#} z1qb?#eMkjIDih*vcv!N4ju?CidLiTuE=$2924!9lHfZdS1KfR50XM=pV3`@7{Bj`m z3B(7`DM$oY44^OZxXn;8sV*50REl|%hLkpV;ptc3f z^We4xdS8Hvzqbu{vJ8N_0wr0_4uo3n`vaUTwSR%T=U3g11=VMASQx+4o#CY zf8tM*mB>cH(_}EjAZSE^%m<}O-=DbBByxdv{Tev!1qHm2y$)i5(j)U75Q_t>43rip zzF-9V6tuk-bZs8gBW$2@s+6NUWZIuj5snvkK~*@UZVoun%kU!i8K`cKgLJq*Ji7xr zkjMJXi*3(f^)jfx9dV);d=Cc?0|P_K35@=B^BW29fw!HmFFIXOuE+par{IKv+~@>% zYz07zEti8X3kQ`H*%v{z6(V{e$qpRopuFbF(+w(WAAkdv2O5N+qV~-To*&T2z@FCM zfNEyYaRT6qp&p!I;08eJrIX)5x6Xk)3R+_X8r48ur`-IDskR8T2nn>=7UV{dnSZ)n zroI3bv7jqM!8z0k;yTb8rB0XLH!q4HD^LC)C)_{XA-!)P^VL4BF9Kh@gXw|o*n43E zatwHPH16d322weJ+5(Vv#c}XD6=)L{R7bjWvAp;MT4ezWTyS*@bN3HWD@CN+X95eP zMuJqnZvtKB`V>? zmMFxfkq}$k@FM0a2RCy4^TvifX2!|_sfEhxd2Bd$P7>-ghnRM1V}i+<8nI0`CwbJ zFS0_5>xZDV9WSl_!44^NIn&GVBIgmP0BAk}x?|(OBS@|XWd)xzkh|hQ=aWU8f#iA6 zP3WQBZ*~O8F)+MvethRY=uEH;5C8w)IfWg|8i?bqAUO{984SIx2Oj?a-`Tq3A#_9s zTqa-)o$!E`8gQ^8D#`9%kO}aE9(s z5pWsq0Z{-A4u(z_(HAeSz)n#GnTci%C}V*e0?;y)p*w{4MbL|h5Mu&f%m5FfaX{<= z>4&)K#REtk3bqH*gnscN=QFf?y7;IY93K4Jc?2NQm3@dA+TZ}&12V{m^+n(dO_)6f zPu2KY=VVf%mJwcXHt+# zNc6C9L7FAtNlkUv@>-6#ef2c5Q5{MOKy$|n=P9CNg$_U+T-M!!_0wr&zPDTi?`5;RtSop=y z4{$HBVS0%jWF`w2s00J;L8UxGqz9QYF9NjE! zptkWnx))!C%s}a0|*%wrg zOz8!e!Be+9{Qv*OwRivjXUu*Bb#V3xK4_wV`kNaTN_=i$s{&pug)Y9y;A3NerA{ue z2N;98TR~<9ym;seRa^m8{Ng-B1X3CZbh311%=LqIzp_v8qT0y=vvU?iQ@{&Ds4?In zDClYZwGc_Lkgq@|%S1>79^!_&9PFl2k!}_?P>j8Q3y(1#aQetT0rpy{NVkX>D9+Bk zg$DsI)Fd8|vr0v}dH6uNZtYuWv6+2{4{8N3$lGu$dJtCdfqc*l3JXwyTMW8#_GL1> zwmovWm*K^~TcFxD9@^e+xD6f(lVf18e)GclHl*_9mj|sTVmJd*{{R1fQ2onurI+Cb zl+Agim*E7I&32`i0TihWatsWAF84CzmzEgDCzYn9F@)tXgyk}Xl`??#M>fB42@CJ7 z-Lq2=G1GP2bq}awh6V})v#&s>?-B6i0=U%#x>M=^{7xyz(pvuBODqfw;6?~2KZDlN zBMN?4T?=acc0-zcFA`m#=^+C$lnALLK)DK3w+IBjaDXgif&@Ic@A~G2%^PUp1+KpK zAZkl^{RdGFZ4$ot;|#Tg8EOew8mt*oyWEB>NrDM?x`@7cas4%XB&yqY52Aems{KHP zD!e`e)%YbnWDBHxzw^TL6*S60RWNFFV5xua1ij#Z*}@OC1)7Y()g{Q5 z=a6+-V9OEp@57fE@xcTNR~Obhp!hiS5-mPJ&ItuIpzeT50?>J`;6#*thz)CmG=YqV zLo$61hyDneZ6}IPx3s_PzKuvufEPcgNGBi z0`@%sDtxwsR%W~eT@DEuDk`|u%kaYK3Z(98KH_5i=EamNkm?FFZ&Ps#(N|n_tC!&p zw0@d@tC!&nls)HGFH)@pnX3VjM6B09pU-K013FSaymv2Xjp$C$VZ`9!C*zom0+&7UP2Fb0)k7O_GTO^@5l62D}i5 z*o|w|Qu7ai+H{bW-4HW^x*J| zk%L7C4@k#i&=G*ITObh{aHp5yMd2lIghIytzFY#eML+>-{pQ8?OOVKg-hCBur{Q+X| zx2#|W-EjA#`4wwtC`cLHv$)Opy9ojCNNc- z4AE3=L{h~EQx#(gQN;=~s~btx3uXoe(ApG^pcf{>AaxvBaCON@>JETC%MtW~FAAiJ z1)<6oN!2Wvs)#a(DmIv%;z+7WV5%lLq&qJII=jhShF-TKFpiK z0KQaJ^D9WBLKb_sFZf#b7dwzNih?vcfNlu|Yvjms$S9aSg#mQ#!ix`IU>ZXOKnnz3 z)FWxU!^FUlr2)F^Jc}iZBa1650AeF3LbgLSa=<*~hNN*ZL?g(lELmJxTv;g@3l>A2 zS_jq01#>DdlEy5MMjNnGK{oPdRb)(933V#y96Qk2@*Lezr(Q8Y1dbs{qXXQj0vVu$ z4e=((wVY5(;jW#5q!)alAS7U!vN*CtG8TZYLW76x+0T$50^JA9|21zey$zYZS z*uhL$Tv;L+CqR0^o&}wOHW8|q3+848B)zquYi4Y~ZU)&amjSvR4dP#rn?s>`Ibk9E zL?7W_N043zaAE-IRRAyKg!mV9Y@#GwFEl-@K+?+!(hGC5K$b`bDEmTU7Ubr;pCJB) zyEz9*FKCwpKFvg9&AxgO$Q zkegGXdbwc<&0-i@SD+W2Itc*a!@28N6e z|K~Df_%O_4c=2i-crR7At3X<}?;p?&f*zoWmgXa%1KE1dLQ2XB|L^oNsNU^m@V?v2 zPr6ac!Fe+>v(W2 z175ufT8()G9*rMBYY9P{K{mpL-hhTtKucuj!G&IcSCI9FJ_zb{-4c++@Z$0X(4`BY znqQ=|_s*OD|C{%M$p0lm5C$WEOA9Ll!^`VDpz|}HyaA1(y9$7o(|&+lTJh-z_{^g$ zMrdz@0o)Jf3V0D|2~L`wt|zh>!HqD`z(1&u%oXs$7AAM3+xJLdcj$?r7qd*j%E2nZ zjbaW^XY$E6(2DgVpe<@$Hhn5@TO1|O#T2!K9mPEG=K4d_61PS zGh`x5(2Gczf<2(~c)NX11io;C__5RVMtA5Q&^aUlFBTg^U2p~DGSD_KaC2)5|8^eG zwuUP~FBBnbmcgqSK>L}%4YV!%+g+NN0=hx_Y8jvkUOb1H1=^(xTH^MAfBgmU2KbPP zOhMhCja*kC%V$7sJJ2DH4^S+-5%gjURQ?4w%&aqT*Z+W2$H=ZPg{ivI?Rz1x8?;e6 z2_gjY4LF=ZjWD^dpsPsF1ayNoMmWM0go5UAd^tK@CbGQv^92;opqmD61ia{nSOi*1 z4{CpcLmk@w11WQb8k7N17VyF!oGw5sO`)?#poN+cbC-Z8e_nzQVh(+Qy!aSA&I4Y2 z%)dYM4XAq~45}ZQAn^!_MbL7iDQ3{3w^%Lv2i+SBXgT!I-xN^`paFB9zx*~GW zV@OqpoP!)-LZBQ3%JC0iMJP)Xq)6HanPvz8MKmPSAQzjU`=g->UVPC7$4#dzD6e2G zL5rYDK{*PNpALdEAf&jy68Itzs^EnM%w1>T`F|?R_#54@{4WGkb*0<&0wfRrho}O% z_Tr;%P!vskvHLx!0KF0fO5`u@!4!a}Ktee>K?@^hf>gka(1ED{Ra_ud@I+h$QWkm! zQeCjZlpz&gP~*J7(>0&KB`bJaJoc*h4XEnnf|jfxi@?QWSHKG^NNxtFT}VCx$$+a~ zd6*P9T_9Nv9fkN0$-kYh;B*1<0Vu&CRlWCM3J_KAX&q?9A*x;tm=LJy#ZqLtbb%_^ zD}gWOLslk(k_WDW@Pfp(VREU|9{yl{u=;NS0y#d>gweI@XPB2?82 z4w!op=_M6r6(YSnf(aqg%Xx?pN_y#ji5P(cv}t7D=4A1tNzvp0|e6{Z?o?=nJ)D0JnZB)$!FyIw1( zks8qLD*)Qw@gWG@_xF7VZlr?rboSnO^Z$S2UJwb|Hdk+gVDq=UW?*1w2Fq!bct98q z{4H1Eq5&mFFGUy`7$AB;ox&1D2phCwo4;i>15B;~bfN|8%jXOX47<|OKo@I-u6e-< zntPlz^Z);}PS+JLzQ6wee*&)2G0@>w)(2~&`L~Cz0WF;ZZD|1&?TtY%`2C=f0gEn{ zt{1z(`)gfSfU1Acyk{s!H#jdn_C-?*3a37h#jkr`XMj5s*fZ`2>kGBoXc_YvIGuow zOM_SePA86F!}h+GHa<`)o-vJ+fgvM+VID)q8c;8C$pUaM5|nN_r-C{)&ET$$1LzD8 z5Em3`C8~{JL2!r}ymrm{1MAI;DS#ahn(}?^ne`JkK=5B4A#9ZO6V?}gfg}uZ%nFcW zHh>(%!#I!Og*e19pshIFu3tds8I`{J|9=8xY%u3TFT;z_eMn=2H}-+X20^_t>o+fE z?}PMs`Q;fvW4|RIdKn)4|NkE}@v-bfF9YZtM$j6E#UFYZKjC~2P7Vf! zEY_W%Sy52m2-LO^USL7V8d>8t}XoM|TJ#OHelpW55eN zn3@Njp--UZ9DK+OE^xV60=jv)0$*^!)LiHcy^_Vc3uI3AAs$dBg`4y2BGj$}ouNlS zjd@7p?Mpy6Xj{?=un7X4t_wOtmw?)ikO~WQ4cmvH7h0D=dIdUNCv=8Rfiy`D1a^l$ z2?Adc)&tYq&>7kSY9T_Z#3upWpv%nOL1n?`G<1T`Q|JbhL6D;x0$$9y4l683 z1$b*YXt($h$nJIxh$)azJPF!^a^v6s|D98K?|}EafQEWu=0SGXPY8NZf}{sDPt?MT ztOvXaz99g#nHszo-wjDMXipG|ViX6%Etm`rQUR!=m^)D{fJOtTA%+~~@fSdzMU8Us z)Fel@3oJUVVQL^z4vkJul;{+Psewc}#0?jDL4*B1u;lgmJk&05l)GLDfOPb}1a*V< zEnWqi0E=?pD}g8p!W`l^Xq1P7dhwvUa-IZsgKn>z3DXOXa&Q|JDM9>($|6TO_(YAs zZpi6JFIHX!xePVRU0VXW!N(gcfgBQG3NZ!jvx5(rP(v3r3BhBe5lK(>NmevH=usYw zqM8j&HTF244-QjUoU^0qfyOzczX6YioO2-0qDMI!N)GmbsX>WyE|e%&fvG`>az2zO zXMm}}8s(3`vbdt$1>!XvQN9eO7i*MrK=tB|@@?QU1b>t}LF|A=Ia-Fo5#@bIda_S) zqDBblI0Vp1Jl)XpIx4yFc@QowZvXpIo4(Euwzew~Jz z14$`RfAOQFrfV=Y;FN-%{da(Efu)pCP~Qa9fq~WsQV_pEQwn>L8@;~p8_QpflgOYgb}Sv6lzy%!vFvOJEwvUy6#2~#6pP4U|X{> zt8I{;pl+}M0q{VyMGAPr)pkFU4Vcw7RtsW~EXY2IR?0xVk5bu!oevqbMnurGlh8l| zwU~(3^#G;|DS~*B^Cj3W&;oemMuQei7bt?D$%PlW{(#!gifq!05~wb4_(CHHJs({- z0rmyhRxFh)*6^Ey6y$^}*>^}bWS_*SWU<IPZ!K8r1;^(5z3iq!7)gV@mNx}h_4OSkKmfNtLnfiF0~d4wY<-~}Hz zo8zqeu*Tmn6c?b?eb7+lMh**zTR}Ti5yj#QlVeB`2u=0eSVEN<*`ybBFkPS=1~r!- zxdw%r#ExvzixWqoc7b9L>Oz$I5^54^T`UB(3pobSo3VKilOg&sYbvbaX9bB9s2)N! zRS${{7&R4E8zN9_K&z=T>X!ch4-EuvjK+{G_#!Q6Bc&UB-!^DE5!$Qx4+#>e)6t?H z*mXNdx%{$u3?DyLQ2pz1VOBoG+ot z2`wjp9Sn_iehj-xVTOR61Pw!e47>bb%3ipj*oBrSz}A48U@fAczCl2Dk0_{b5C|3r z?e;_OGn5?!yBt#efNcjYctukM76+|pMvvJYFx^O{7*97gyFt5+(8OQ-IsmmBsWjt3 z43?vwdLS zfz1H5WeJ7rHi&<~>a$O>BEl7;ka^E;z}I2qzpd7K#!N>`3a-V{A2w$=paPvBy|7ipl&4^^n<; z8Jv9#FVvTUXG@^lx>ha)PnR%)w{_(#g-n-lGcYhL;Ot}g09_C7%+&{;HvtV{IB@kb zT!4z(a`iDBfU>Q)`WQAq*`{25;CrV*>W#Si7$!i)^||^$w0RBP{~kY&QM~;P-4PRV#H8l069Rh!kD4Lh@rxep~8Rx zwAK!SL%ZKJz5%Uq1?}|)8MspeF+Y>V0*z$U;g%CSK*@s#atn193pjzG58W?;sd>^F z`T}YWXhRj!0A3?Z$(7E~8(A!nw1C#FiG`^-(iwUJY7D3v2CYqkP5M~E)NJVt-2u9% zy*qSEP`B%gfNs!X&(b?Vjuq&1UD6r4qC0d)5Tx7o0z4)2q82I(UdZ1GzA>cR6|zJG zw8#s*l|q4gL^hB0zqS{ zFC-vJK>b7Tt>rwOt)PBJC;0N3Zt$7Jpu>Sz1c65EUSz?n13TCkVn(;?kAQB_X|6sH zSx8`=L~2W9F=l`gQ+FuTn8lDAY=Qz_%-jwN0iK`$h^C96RpRjRv=_g@vas-h+~?BW z3vyo|+^lejrO*(7-W>+bPOdA!(?TycBb$@4rxFwnpfj1L1ayOs@D79yG`{G9C=3dC z!2oe0a%f~RX0*)x{~vPvcL3yQ@xT|?A(zSo1-v-B4eFO}aNq@XgF`alg(<|)PNaCu zXt)SEuxv(Pcj%O$7gJzHbfb9j#UHSN0-fOKgPbBgC7>G`>M!m=JPr;x)OG;)ylEtr zCXhIWs$@bGBama(gSx>k3+VO*Ep}`PdclIE9<{~-?f1Y?9*X3UY~=D1Qc9Wd^)b9? zTmUJh8jpbTv-O)77ZyOuCN2gB1{=OU2GHH`pz`7zUmy6q7ZCe2UmwF2XjyZDuaDsf zlzo)14?NckQgeu}k6{T^d_P|w!xSic4__Zc3zWT+uMfP31f+f&UmpV~0fE?CK;jIQ zCJdFv43$OjGNNOK}g4X9*+7PHxh*ii;> zY+-63Wz&v8NZAK1EabtS7U*pK0-FDw`U5om3oikG1a^mh33^ctQ}YC@<^@O%G*5Sj zz6k1eeG>5EI@lJ0&Q{O_e&nP0fW)Jy@ZnE_H03M+I^K$ep(hN)=*tLXr# zX$9FB(A^8NKCl}c9zosUzzKNqc@rr11&~XS?p~1k!0xFa^+DaOpzsUm?ga&A;0tG% z`JkI4JEunc|Np;xD#*1#-K`*}2Xyy>!ZNUXDkxxsUI=f6nr{N00RWu=+}#RNAJE+k zQXkko6{J3>yA`B9;6*YlJXOHzH9+R~f_xg-Jr(5bpzc;sJOp(2f+8jGg)z+ipqvM- zTBd^32X(iC)CY9;g473gPX(zDdeID1?*ca817v^eW4&Clnkoth`UXc30?x`U4LEWt& z^#Ly!VJ-l9xD)Jq@CZ_OFDRe`yQhN83F>YI1xrA8FGyA33m-_Z2L-%11U_Pqr?XWA z>;Z}Y|Nn!B%phifje`Xys);W+;AXr7m;RuU+b>|#1Ug$;z@~A4g9CI)Pynnl1UC*~ z1@ns|8^E3gm-pGo^)PD1gjV)=C_S^^ZjLEYf64(RR$C8xmdsi3qK^x_7R zU8r>h9!<(fnzBzK_i?6zJQvgr_Gv(OFDNAjc25N*%b*u;*CTrirCp9kmpO`E$gT6K zplAu|2FFoAcP}Uv2X;>dCF!6SjYxK(R<8JTokr4y($$94gbt#83@^%O!fHZLO=A7# z#j%-?nlNpG1Oo$uhbW>hTq}mC3s;FD>cZt>h`Mlz7@{s*D2AvD=ZPWe!r5Yox^RXV zqAr{&hNufCiS;pnViZ&__KWo~fbtcH-6Ph=01AE(yHl)>0TetScAHoq11NEW*v(>n z44|Y5VmFBOF@W+0h+PYE|3An%5>+7gL)qmZ_e0qwAooMrg&_As*?A!ML)qCN_e0qk zAooLh5T@WxgfX}uVF>C<6q_>?n=urdG8CII6dN-X8!;3cG87vyRG2eVm@!nCqF3+W z`uq>{eqWFWcG@HAbHw^D=z1>D=pORieB2sPa^!)`w?Nkcpe-1&hA9E{lcC0-_YlNk zYCyeV=&~^MX{pbvp;m$Vyl`_+r%TR5)gVvDgRdu<0B!I$1in}ewo3rAObyiZ>~@_H z0AEtUyB1`NK&LBsApx{a2)QO0)Kvg2zj%=eGXb<90onwHt_1>h5Wp9h9EGU?Eo^}H zI?&b~EP^Nr3V1OCa&lQGa)%s!fzubT*I>@}g{)nGbd@#)zPJXF1(#cpscBGY&^d*d z=RauSDzxVToz>8USQixVLLRIQx#!U$3eo`@5C$0#_@Wl90%k3=O96H#xVzI0I!OK| zObs|ZAPxTRUQk~Z+=2nG&oYIn0WA)M^getc%dcQ7@LmW(lmrF5=ztubh8!NSeh0W` zcOc+JDnv<8z>DZrpcvx`Lev8wn}c2)28%;u64KXjg|6DrfN4e@%y=;YrUevfpw201 zc^GU`=tU7EzQAD&o}34T5HyHk%LhSSKya8q;~%UTGS!Kq8nyxrvQF*AbR?r86W91u zzk~!7*lfroG?Hp)CIk)3BKN_!t^kJ;ETe+;g35H{%sdgM29i_3!v^S!dU9cEP;x5j zM4~554N^`84L&2=r3zJpoKw-3p)7%1EA$(z5|#q7=g9DtAm2gb8n*TV(#3BGe6bT| z0yuq!f^INE%JI@Ly`V^kQgU>YFGgS$#mVmTLQa7 zHw3-VfylxlptFS+Ir3m*1Q1Ox>LJzz1-vL-4)P%^r-EV*lD9!a_8dc))Thbg9&f z-4G=~0WUT#gZcqFC;%-ZUPwZWgOs_DoC;fwTL;q&Z{&eJ^x_%VD1lB_P^5vnK%mvR zpzad5usH$oCOC{CYhpk_ge$8`K@tE|HE3oNMKxMheS=~)Xl@dpYC9CwpxH$v)!+;U z8ka*Wbiv|~SvXK(3|hGd(iQaL!%|QH!d7GbR$Mw$-+n*_@AJ*+5p zgU1=cvlb}AFJh6LgxvHc)tsqF=478lYN0|60?jI;*bH_Ms2zdk&=;qdAOZ=c2~V;~ zj3{nGnhJuN1e$%ubQ5Tl06lM-Be@BstxvK^xkx5~N&)!97t|!s1ROx0*E;f`Xn0 zIvxhw;egtdWr3*ykB7l_T(F@GQaxAzH3vK(2HA0eUeWG>sR0j&!R$iaO)&$e20S1J zvkP@VtOTZJNoVK^sJ}qT3b~OH08;}V5QCY+jpAkST47}OllY$I~xfCH)qT-ieg z{h`eow7$jt`H%nrw>cqWDsUsYP?kh(g{cJf?;xW=P$RPsp)6T^(G61x>it1RRiHf* zP<}&pW+F@_sBhRg71U3Mnh9FQfV`y69HtV~bL^Z7>Se>-iMn))7p4-_uj~Z(voYpG zUV_yKbhe6sN6sWbBWJEV0w7Hc=!l>zI0ywgTS2#}bWVlbzyuk2>vo0Cj4Xti^W`sS z&Fc@)9%_boYXEf<}-2f{t)#1?ddv?gjZJ@C6@4CyLil%@gUd?3#yUU5GMo$yf6f70reD6Mp$0V1dF4FC;0Lo&{!N6N4|uqM+!Hv z*Mhpi7YhY+_kuhX*gX~Gsh}5@F!dmAC)hiXc2z4VI0L$SL17!%4UQzxh}d6H7_vY# z1qHmQN_+ml`3OoF!rEB9pm+t1V1iuvA`qf5DBy+rTu|VEdil!Iq!Qv>X z0@B`^3UUc($O#;O9590*m+8QQ;Y9&VJIKMEU_ISvegJtKo(>#fu?ZRsfetvLIJp}o z6}^}MQx6(SgbX;Mh6-xhdGP=eMkvGH_}pUvGaod**$E!(>_(d`16^D?CGbVt98dtF zCJB@Yt!`iFywx3;N~DYiz8e=dIo1sw_GmS4gU@8&e49Rp;L0Jbh zA`VI-XsIk1qA4igg(vtBK$HZ78qjFjb>?hL&!VK@Zs>f&i+q?$(13gARM6-XAbabi)%Yb#|j>`y*g` zQDP91>A=YrmejjZlH-ehh^C-`7pxEuAQxP)OxFs^bfEEWaF)6QzDyeA(@Qg9K1C@E zURXg4MJ|dVnXVU<=>of_f?_%7#blU4sKM~!H`rKEK?g5^yV3jr%5?D3<}@szK$8}o z;2Do@6eoA1q@ownkaW`to`mQG&q$z#3ToPUkqt8+G-c2Uo^QbGp4~9@C1CegfNHB& z(5N%0(EtDce_%Iw<^ndf{(>9kU!;W53sMjA;eT+I0UA|@&w@n5)FWj;a19&O-3qF1 z(MQl%&j3XeXwD5$>$QSv)PN`{yBj=}71Z4dYRLq=xHBEd%1Zx3h$yShZ(7@S0(1n8&!Qv=c26DR^j(Y7OOg&PT#FvE)Vd@bv3(1lw838r1 zzW6f@?7yIZ7e(NsYf(ZHmL*ZEPEUx!pnwiSfYp0|)Z@#-H(&v40#ZgK|0%*Ags0DyJvHGH7DmV_1(`1I)M9?Y_kS19A=?2#apwq}f zM!Yx-(G(Q$Vkh|US)R^TKCs4NAQ5HH*zCLlW)Z$m{K5`a(}QC1Ox%4kGwf$ZuRiI8Lf)rB;O(mfRv z#h@$-3W@Gs&@6Ib_f$}U9P~na3dqeUxeOYZAWZ??y`V%Ah&omMq70%bDBwj7_z+sW zfeD(O1+~nSiWh+tzzNYjiMfjMas$YJ2X1epM8p@Sml#V?2nL}umny12X;>d)#O1hCV`!dEi6Hr0=j!arAr{{3WFDSA)0~$ zUR(xWUyU~`LF*epeGyQcyikVd1iKMs)CeOifA+(}5@Z6X!3Pe@M2HDQhovD>sAQi+ zTB?mVEUO_g26iXf5`Iv@32J3P0u$7-0WG2fyUle1$j#US6Ql{$)BpuS_f(K3(3%C1 z5ice{GzA5`Xak?5hc_@mOEm(zdqG{9z!%rRK?KX?NJEtvfw`s+XHzyx!|+JIhj#M*!^bHv(!c5}qq zfEIJa+JFXg#M*!wbHv(!3UkETfD&`W+JFLc#M*#tbHv(!G?4qDbNY!O_e0q+AooMr z;UM=z*+C%pL)pF{_e0qpAooMr&LH)iJL)jJ}_e0r6AooMrIw1E$*=iv7L)i)- z_e0szAooMrVj%bbg{)@~1i2r|<^j1M%H}ZdV@QrKVMvazGyxIDAi@Yl7&0WsR~do? zs|-P+RfZtpDnp340Z7&oL|A|ba}Z$$B1}O9SQl6mL=Q;JfFT)V8pte=Ng#6!4H%Lw z8Imm+lFb>C%@~qR8InyHl8qUXjTn**8IqCLR)ZEag2!*4K*w)oK;ySN5#zUr^$)$R zpq$#-S^!${2wK;1@F7$06kf34)Ev0h`1fBIIJd&4ZK0DMEGSD1Z^6_+rfp%yql~(4gQlq`6)bpv>%FKD^Ni)Aob@cbRhaVqd7 z6ihHRpd|x{eLA3}h!cWdJOR5z05X*c>5!pM+d4uF2nu*%4!(~RWttLW+IBL`K!|ma z8Cb}e>V}{fr4U(gpn#T>Z3QI+=q@qX5J)IQ&x@1bbM-(&0{c5bfdHGe1s#|KPC$so z-Et6Pp>xIHVeA0tv?zQwvkImLJZX!4V)q)@BIx8Vq*Dc*LWLb+^kOqa38?=EaUb#| zHmoBBJ^kVZ8$?M^z>7Z}P%ogZl}LdYhdgNuUC{C3B>1LHP!)sXp%;cQE#OFpyAQII z<%KXLwh$o<%2m)1##mmFhOQWt+u(}PrfeptWKwX!kbOuHB_j*M)Ic&R*c{NdJLH*!w{1|nAej`Lk9bPhyGP{4~x;JeK6XVQ0I zufeT@WH@*xy#SE~2OKB@@MTgJh;2auFQmY_V3`!8Zz?ErBhFr^1S^19ihb3@RhSx( zPf^!5z%#NTObw`nfn-u>mVvK<;)5s&3V6{1K3WeYG+>z&wgxH@q9iEbMR+SXRbZ@v z+7A|o#xG>h5xSP+g$hhFTE6aqX#qz%+iM`*lI zg{mQ(N2^;v4u{4eY)unv-QtT_m@GKDu;-OxQiSJG9f&MA>MlO)#+OAKA(jONyeMx1g#j#!UVPY%mP4q?uRG|3V5-#5$Xf9g-o&# z^YbkNcMzQv#9OdRWLP>>lDErv!BSP6&Ll4<-xFp4b;SO2O2Css)S;{s-(5ly)xq z@n(?_1A+ox_=B(aL`jmMS$ve^FIU41gjfeD*de=;HUzxrg~&nzuS{P_@kg(s+; zd%X@EHSisb%-v}1Tr-HV&@us~SqQHlC&AQ!3L?~O0$;%R4r~!LqeC(%yd4R;zTrU7 zi_;J#K>;ruA@0N1&Xt2G2?}^20@emN?ggt7>~>`7oaz8l)e4%sfCx7qF<{N<3 zgC+{QdqL_0yQhNGBSx!1>H}YFhpATps|QUpLO1kuw}OlSxd$>83UYAJ3wDTlXyhQx zfIzqAbhm;G0u66Nbb*{5^x`7K7f@X&^AR8yg8csf|9^D5q*3fbnfm~_GYGp~Pf_eb z+LaH9%x*{=3xHw|ytD@*j6IGSK&rsA;23d?l&U^}rfXY4Q;qmi)dP^KUeHu9hK(St z0o}bIa}X0xAQuL_m|g{qe^BsuP6elzUXc30?x`U4uyqaHy&(00FP_8Hg95&DDmcAN z1z8%@-3oF6VoeXoZ$U52Vd_DV-3i{x)eT;m70}%aQV*KA0u38?w}R9Myl9812Ssxy zcso{iFDMQJyQhMT0Ht?GRDv8F_~Lpc*!|#`2MyUEO}XHS!-drdUD+p*295Ei&DThF zp$y^TO`BU$>=H)aehrReNO}RSpX}_t0$PZMr%X5iisPwAK&rrn5B5@M14vct7LY1% z;e)*tS^!ejy9A^P-A0hsfbL$9IiM*A&=RZeR*(w=UZhumLk^{U=>@3|?4AlzkC-qA zsSkXy9i|>Ry?`tY>TU(O05pydT20bD738;|7wj78_BNhlS0Tbk0))mqS%GvLZtLE z0UUc%u*Du&6{OZ`0I8bV0#b!1y%c~{wU&TX;YlwEAXU97AXVt;1*8?!JcL9f$WcMv ztsoZ$yf7~Vhc{|^0jUq{o(i%TG&KoX(gji<_@W)A9yz^$ECn5p2vG>~PGI*`kl%t{ zTrY*1kDOjW>Oq5v5ch!82X(iC)Cas!hnY`gdMSsP4^A&A^PYIqiz7n$u5+w6?l`T8j@Wos|_IYkRJm37+ze8fy_ff zwk(9ig0?JxCW@@zybzCt%t-RfGl1qKe*_}-EQo|4_ACg7AoeWqg&_7UaEBoFEO3M% z_AIc5AoeUUg&_7U{0~O#S@;u-*t75}xQ_vpL_kwd--G)YK+z9ke+lkm07Wf`{V}+Y z0TgW@_PgLd2GBed==hO0AidBzy%!+8Q1%m$UMTwkNH3IqC%BIR)c66Jb0fHq0n|_d zv9AR8F@Ty#AohjeJ_b;82E;xS+{XZ_{6Opz!F>#%iVDO&65PiCsv<$`1HpX^py~|7 z-V@x%04n@I>>a^<44{Gv#NGn(J9J)g1IX`C_8O4;q3jhP_e0rBK<>VNu?rLs*@yUAmG9gJu)cXnTeu@8>^m!k62I!$Wl@CfR3!kbQ}6E7(*02 zpyN+5^<*CsLvh>RY-Im{4$4K+1I`y9TUtaxi5#?R9V81m#uTz05=H#Qdaw%wI$J>{ zR_9bu507LsUc<})m1v#dZV1>6$fikYb=p9PM6__!iNcZ(=UA1J0l z#st2&3s!;ZFtB%mx?4eh1FeIEv}iy<5cEP9;+#%!M-CG7-QZ3lqNfK+6>zuIVww*b zb_9PsJj)UCE&$W zh{B+N7u}gqKX;?_C|`UAiwksuH9*oGWH=IKAmN1%%%EAH7twKao3l`752s$Yg zWHu;&fQpa67q&1n5YY}PC-CKV4v40pfEWM3SKOhbU-%w3kgGt8gdrUgQ1%LV;g^mP zbf_f>)U%+|zd;T~1iA=BC&VM*%Z`wu5PLb12yq-}{yPn1Eo^=ebm0VgIk6S20wqpS zGYG0PU$8=)Lv%S2ifKOKazX*3DJbB@H1OS;DB+B~oXCYJ3<`LWoC@_bS~+nVEKabT zP=OhQ8VoObVA>H025&hL0|_W-yn)(JNb!cZoLGdS6LjtZicUP`LLkbF%A{w>Qe{mmTaZtdEtKbV6Q4%oT28Aj_Cvr;+)oiE-K*wjJc;LnBB(P^8 zfdRh03MmS)7Zer{#{~tv&;x5m6ck(-4T>JH3Y0iS%^_$7#T}S>MA+kPQ0Tzag9=PY z6O?d4@jVgj=b(TWx!`+EQNkH}LE!>X7!>fr3alA4O^Mo|SOgX)SWx`d1UD6f0#JkD zMKVk~BEjG-D2yR74vjZZF9Rvw@D>!6C^|uX02G~g3JQA^ouFO{u{v8J(FAoZsIP*g z6De(iTBD%M1(Jod_d)j`LRz<=j0+MEcwwFZjz8qo4&L(vG5#V(Duh}9I`jm^f){xZ zgMtEHq-cPn1-S!&H3NZKiU&IeVmJ62D+bW4II3Z!QWG6Qb*3sHy} zP_KciQGAi|JO(*ZK!c^|Db5vQ9!jL(Ywn981udkxk7PgINQs6-Kh))*e2t_N8Y!Ub zIzaw~hZ!_dKxfl~#1WCg8w>Io&PV~(eIO0+fP-29I*JD*4!7Wi3&bE$`KL-uq+EQ2 zQ57_TLs)h+;X2n^58e zU*Gl}Bo4uT%svUK7LbA#Z=9GQ>4daAk#s^M1=R8c`4=@(K+C()v-dNw&oCne;xKUY z6J!v2HUag4LE>-=UdTcMG$`POuo7mZU=Hy>M%zGUz|DRU32_X>Zt$h0NM6H;6zvG) zNCB-@K=)iH#5|Np!B=)gLLw1tKXj-Vktpy+%6y3L!8)@~f?5{HE{7eKgt}BQI~?qO zs2wB`lUiHDEPi=vEtG9&4MWMV8@P;Pd7aUl%ZY2e&} zMUOO!HFJ>kKm!kp9@M)SGm!K^?o7lM1mY<6n4stZS8!PDLAgio1p|s6a0!S-k1UEk zXF?HS0L^Du^q_9Mn1Q4R_dvTOiajYPdcdt1EcT!tEoFeB2V7NR=m9kjkmo17ng%U2?bU)g32XOs}(w6i@jg0 z0C8MUzzZ?3W<*Vi*~%{gt3ZiS)D9t9zxW7DJ(2xl5tw>X`o;Hyz;t6z?w1p#a&==g8kyhQeYb~`o-Qb?L_vAr6Dm6u1_F!15&)Qxoz;5#E9Jr~XhU zBeDx>284PRbD(`SL?_sTkjfh=^0Ai_Kg7X~1MUCu16hkGCqTFNp*9A6AjTudDc*8o z4op2F?D3ADy#c!br5qwWezqN=DJbBDF2pOy;f%eUV1XzM3V89$7wTuUf%YVbp@b&n zc8fs+4>cHGD8sZP5)9t)v(J!#g2o%D0fiKAc*_Y(NGgNsBxRueKZ>281{jK+cnS(v zB%P3E7?MtCH4f_TfHD`n4uhsy%z^grKAz&#z18K_N?>_eboAdooR>=(x1 zXhbR2q4t5UYz3)B&*Y%N29P-1>=*ekcOVig)Gwg^G)OJnKB(E41MRC}W+37nQc&O< zXfK0k0-gUO0!~iI2^epKVvjdQ&|w`X#2jdEg6M<6wBY z2`a)tDJSs78aGfd!@5bLs9wVutg3SbsfI-gwt@CL5c5zX1>a!R8b~C9gZAJ<7F7H3 zM#?9M@4-5=PfDTcghmSS1MN$|KEoL)pt=tw;Gh;@4z%Bf7!(xn;vz3Gk%DEQT>@eR z)MwJDKEsHUSI)?Bf@PrH6Ji|EQ6h;FuwtmzNWnMK-U5k4Xwb@_+K)FLvUm$8je}HzghW_Yw{Q}y6==vp#5gaa%42kM4bC|mjy>+PS?2F={ zHHF~KoIRo-Uj)A3gsDdI1-`6u6RcjK+ZXCGd}?)JzJU4|w=Wn#ON2nDsdl&Ug4`AG zqR9fJTKRMpS&VhWZ)F7x<#$ z5ZH9$qCyPj3j$FAso79{5e0J>7GDTq_(BJ!nn+*#0jno2E&|Yej4MH9Uj((eQGGGR z3L3gtd?AJ5i!_*OB7I>7^93}O;7fg7Ftr5Y0#c!Ye1XUp=Pa@K0-7&`G4jO%m}(?n z;B#34*w@6x#SxfVsE={S1*oYF@&zJaaKPM!B`%~f;^LMC)Xzx1z?UypflVhaU;Klq zB@h>oCD*9FaDurDi!Veld?5l;O{6cLfYlQh7ZxyI5R406j5JbX4h>x_zL3H2g&#~c zk-m_F`2y-Pe5tPprj}q_uwnROn;C9jh+_Dn1E!itUqpa?OWny_6+Cs_rdoJXZ0iY45#%Y z_6(==_c4?(6cw8=6crmY6crmW6crmXR4`OBRDmyL1E1&X!NR~07T&ve$M66DcM35w zFzf&w_4|1>;ymButspst*;5$c7jZG5To~433=Vfl-2q-D3py0Pa|-Vt@M*o^Rtl(# zhP+lI07(yIDi@m`W|WPTGDv#BQ?Zy@vJatdjeTi^>@?6aA51;y`!%;B>47Zs!PJv| z2z5JcBa$A-Od&Qss9Sw~QS^Xjsj%rm-G3^Hq6aj~gro-^&@G~%kOx(gAX&)L6UaIU zkT|Ht4iXP~aT;tItd9&@2l3+1|Nos+c;Ec_|DR;j{vw$MiBfdaK&Qd>u%fsD+&?|| z0MwgB5r3hNWEwcKDKRVw$uP)VJf>-&jcF)O06Pu5B^5>Z#Z*I3nu3HHBz;g|*a;-V zAPEQ4Fwj6EiW9&tgY19>iG$j7pa>0k@yh_=wCt0hBt?m7Iw)=fB{p=^K)Jd_6qH&( zi47!+oY+9(pu`3e4|)-Y;xuM9*`KN#I#bBU;{0^$21L;*ihU6b{jacp$Naw&_~25BvVmfSTvGhkZgcy z7;|?ID=0=lp$3u-dhr!p>~cVhcTgD$67QVC3sMFyB|r=0dRS2$4)zZuiGsvINfeX} z0$zmcfj!jOdI1#sQ?G!k9Z+QmSttThiyrwP7lFh6K(_=!Jp{@nNFK_lTM9F6D#&2a z{@dT+qu@YhgLaF941F;HZdw^6c!C06)PT)}6b#uXLHPyATyQ`^W?4Yt2J$3G7CFCw z#6g|}i3h#V(**|<)Rmz80&WCN;RQ`xk!)H5l4+16j&2%ctssgUz>x?}lqkY4gpmvb zXFdwda@RrjCMYs64FeT`C@ugy4059}iujA4+Q_DX(kdmUX`{Fe6rq@=fpRj68^CUZ z>}&#wgHk>yLIYmJBDoEcl_@c;AIUUG#erlRbe%LPxgj^YZfk-<2l?C+P_=>DPy>~l z$QRWvN74gvH8wq{i>r%~^nlX`HZ7>@eI1arK#C@8dQjIQ^C0Pgq-kt=P?w6|&_E6X zP~nVC59<2mB`A78NfetN)V0+GD0)Ci2T2b!_cC=8+fY*i`xI8PfXV_;K}c>xEd4V>6egkRLFB0>$4sVFdP6Ov(&Y=CJPs96N6U_jXbBpdX?M+@WxYBki>senua zZ3qB2vOujLNLvJabOy-tpf(IBp~2cPAQyqeK`sJ`2fcU&GXvBF>jbx_2shMBAt@#( z;Kk}UlsD9#LxM6W;Kf;RvBv?re+_Idq+p=Dq1LJl4k&QoK-O;})x^-E9<)LU6j`7k z14R}r$UyyGkT@vFK;l6!wj-Ga*~Efw8VL=xEEK~)J8vj3Y_1Z*pO773n1+E$KotK# zvoaG#ufiY2G|pK2wwBsvMP#3XRsmCD+EWzMK+E=!OoO)6 z(2g@RQUE!CP(uy%u(^No2tAMj2vpUeH||hx`Z$H82V6K~(}H?9+jJx?kfI5j9@Mk* zl9BX4ifwFqP){?{N74gn-(u5)df41=IYbaZYE^7{SQ${ik5~Y}?ff5^v8^CS@CpHw}7uTc_F$&346d1-SgD?z|4KNJ@HH%Q{ zofnJ2#XGecYOD|sQ8c3F2s49}hFTBA^FaYGm>yH!P_u)ZrUD6`pnw-zU~^%)50qcf zgBLW!(IN^8UcybQJCcaVf~+S-s)(UQJ@E}SJ}HE0*(X5@ztK%2p`msV$!Xaqg*sb! zDKPAd1hUIOi*zv!1C@ZFPy4OcT59YlO^y&GJ&+OzRB@xX)KK^L zDgOJn+7XdK$R!pD@B{l(*CjP}~MeZ0K$yrKOgH;x7lqy9;@3xxewEA*jj1{C~gC7u*7s5@up2eF%7gu2FWy(Ei$0Va!@r5k`H=uiw6`! z$gMSycqe2|9jXt~qX6jxRr?_Mz!!^<^g&7@kT|M7@Mb+!ZP`fLzy&p?E=bA)X+yZu z1W6mDsKV3-seM5D5U%{gjqn|$D96+XsTx4~5cVBG(g&%BvFQWF4ywK$6n&sZ95#KR z6o;xW1VtaHZpG9Gx_hEU6r>N~KN%!_7z6F_*kkEN*Y|`AIb1;dNHOipJ_Op(0O3iK_fk3$HK>NW_U3ZNW92!9ZFMLqUM4uf1nR)S1 zH>Q!G-OQ*)Hp7klc^TQ6=%e}|BS8rs)9awKA3$azysi&7b190Mpbhh&z=3AIT_7_- znE}(CpxvY(GZ7Jbn*-+cKom34#^k|ff-(xGJNYo8s2y(R-%H4T2OSB3?oQB&sF-Gg z_U3`yiSWBI+{~3IW}?q)fcy?xdxdGHAci~dv%~xziee^urx|1>DDz>4CuoBX$eoDr z?1r1kh+-!C_yx$!>_eR0nC=wDaHl!k%(WMh!xMer0b(W>7BfXL%zVrS^Lr$UnP^>n zXuNY{F;fh~%zn6;tSDxp54S+v$%DmAaSSu9;bv~Ufb4hlVG@X$yjaYX#4z(YE6ne) zC}yHp!4Na~u$U=@VdiAGnVcwQqPK=1X7Xb(QyRled$^ff&m;RCy%_^C6SQI*Gkt=# zn4qT5*DNr(+PGKx&%43-Mo*Cx%R1`C@HRM3yiB@TX8`+?03cYfJ_#f8L2X$pJJH{AQFiz7> zf_)A#4breeHw{b03~c~|dTXfh{Tu9Oh-u*V7A1!1L7Wy8@Zt-&I7aRSqMHkD`+@qK zpvDSF5_zNuBn~PwLE=F#!jasVeG=)uVrUqFe1)O|>RZrC0Tl5Uy+|g3c2dJH0R)>w zf|FcO3_`kt5Nr^r!p63^7u#S$6%#1YK_Vdgqy*wNL#RoD-Dt@P$#bYtX@Fu9wqyp% zu*8~{gk&17WCq$ri{b{b+aTv0fW#5i^AtveFL5L@;te|vF)S$HMK8GYr&2Qez<_Wg z=qwi0#6e1&szDqG?TaH_eGHCM5|Y_nBqwE`M7rY?Y!E3<5=Jpe5+j*mv{b-R2_6&z z#Uv;*f|_PQFHZgc^S}8BEWKh+WkehH7s)VOi43$o7{v)-mt~*e!YIG>kxavp$cQ&A z31V1KzzYpUwJ3uOOoL(=QCy^=n1nr%5pUXbB-3!EGSJ3nkQ?9$9h%BOrv-w<5pFyA z2jNQ`sf>8T{y+>13V3k{TxL)ym8n9Eg%&_a_gj-3r_m@Taihg43CT_lB4LtX_^5M$qb{x4K^+N1ZHPG z=@-J6IFcFhhE0VS78LLz8eFVVDVgp2iEtz6yae)V%r8hLpsW)ca>%mu|D zQ8a@{sWhv;AtE6Aq%4L>pgsGbC_|4*&_ReGaYR%apqPX`nGtVV5|U}Sl9?Qi3LSIE zZ^~DMFL5L@;te|vF$~oH2bXJ9N@gFvAl!&@*E_fjA|+1MAP$69zkFzMNm)Tea7H&jY`R^^AmFTv17yp@uk^*6qESTOd=tfm7y3Uj%E-k$!yI>WY5VXObP;@ z_3`3TAH$0qw{QQCh>DNv_Wfgg_C?g4+y5JnfR5C#e)B^1&h7u*Ph$^HU}Iol_;9I@ z0kl+zfsuj1^D^X24-nh^avuX|U0O+{XZ#?FX?f zF848%q~;bFf=PyAh7yKKh6?a;9%sPkd00Tt^Ed(8Sj~s+JdbWyg-+KG{QG?c`1gm3 z@b7n(;9q~i`c#Q{h9o-!Lk7p6xeOU8f95j0n6u|0XrDAlRr4?Al6e08t|HApSWCkA z_xp-8|Kup~g-CIgxIm=%OROPM0wqQeDUlLQh?HE30z^uoL_9+ZWX}wcJwHJ9n856D zm1zFK0y4~30%W{3|Nc;k=3iVO!$49zAj3dX0wBXcQX(bd8PXub4F1h!$e8eNF2jrG zyTOh&KAG0(`{OlFT6gG=wB|#MX`P`z`1ia1;NR~nVSTVR%J@=RXXqD@yz7^=<^zmr zovvT__xpYUIotYFtp!vqh%dpv{uJ{;&{8y!gWWC%S@`$+{@~wVD#E}19RL2(FU;q< zOFwjqoa=Ns$MSl^>pqYPom0>J{{O$b6+||_VC{r3_JX+5{O!U_3=G}9AP)bwi3Xqh z82+nF<@wylV0<90(-rJy-ydns2N^*=;NKq#a<_!_g<2Vi#i1hn>rZvNe(2>n5%_}B z^#A|nBP_4ayxhmgzyS6X*Z|ibP)~t8`~wt@)~7%QfCE5;fBnJk&=0*VhXP(iSi%gb z1sQ-p)MTKp5#e8dq1*REugJxq7tbAF2H1cMAl(bkykQ3XW+3PVxhzI#%piLrSqfwX z$LmuscYur_-4jZQAOl!lpLtzHMkIvP!gSk^5d&pApt?axv$GeJZ@Z_0$mUlZoe;)e z5SNF){huW0i~|sde_KZaIN|jAfD#TUG5>fG!~FmM1VjL3Uu0lD)b0DBJLDisP&doL zfETx4g9ULcc(Czyousifg(2KcXdj*05UQC9mPXVjXfT(v} z5zy_sB(OX5MNqfvlYkd*;p&rN>O;WlBOvO1X9RYKP6_IEy%EsudnNFNEnK}ZOuY+O zy~qFm|GPtH1a-Sk3F!8{5!fAiCFn&zM0IDY30RE<#7x(YfNtNG!0yl!LEWxL0$#iX zn*?(6{g;ryXjK8L*MO+^?Fj4+Z3*gjJrU6DdnE9MCB)RAfEVjw>P5inB_Qg-VH4C1 z4yb@`-yMP7p<9ApG{bGFgy{mEZ`V1M1LX2nPdOBOb zfbPzk3aT5sdqJ)W?4Am8Vo-N0C|m=&dqII5_(C40{s~z9i+}(BcTWYW59$VcDWJO- zq&~2FDoB0Mi+q^+BVhF>KcRdE>TU&jKA^i76mNmuQ$dj!^dcS{ zG6J2gSHS9TfYi5w!Y81+7oUFU%qC3<`L$7N!^E;ZAU9K{xM$jDbZAS};~Xf*o}K%?9vPW@jttT;|TH z9smCSM><=j7ZjL*-BUqkqery~+zcs**MkCHC~O3oCeYbh0uF=n=tH1_n?=4csh4Z^4LIpW^S8;$UC^mE^D@AH9bA`2^%P>veAZY}n8q`}4N^v|v0WX%o424&SAd`OZLkzw60Mz2c zZ7h1dd2JocTpyUZ@ER1^-0Ta?pr$kb`U}jb`1gmZXrJnK<>}_}2!u7lvQIFh)r{3} zqdz`|h6Ak51$o~02mktm{QE;?4nAT6HOBeZUt~T6Hu_MvFHg6KV-T!u)hp70QspYa z4W0or7*co=6NVnwTakFSLVhb_!#SiK%919s2) z3;g?iWwH;lLEL}%J)&;qtBdFW8C7|2)L|}L5k)RiU;p&TF>OmD}=TuNFn#I(Oy&d2V*JTUS z1*#6AZHHb^+aa)fDyZ!c)a|+>pxbv#;ETx+Jt%Dlu&Z#i1s;P<7U*mR)eW6fK@~-J zE2!-d(A^92QeZc@W(?{ESCauRjA7;@wH@%a1(?AZ8MW;I_H|HqD<}v8x>2e-MEHX$ zoX)AB+NT>|TR<7+ex$ZTFR1Mh*gX{#SV7&bpteImcQ2^z5cmQT{-Bt%1Q)pIZ3ley z|Mmx<^aIkn_CAP(-gamOwL1d3dqK^%!0xG_wnI=iI3WeR_zl-v2-Ay5wUD+0N+S)e zNo4~G_Mm_ln^u4eg-&q&jL~)gH$`9#H?(Ho4@gi21-!WT6y$u+aUV~>rlGbST0xa+ zKzA=FL<76QNg}8loIV0xYymqSse&WE?NEuT6}fino{FbVJ&3B0__hNFszy@U4!)>b ziElfIplT$g?GSkn6e&nSOMKg59=cYPw!_O)-~a!Ad6$a;G6;fwWJkjKRIM@pe(*>S zbo`*(=Mbn{c_`?`K5*jY01X0lwwyil7j!n|*$aRF|9`y|I%dw$+rtVH4}9@SAKYgL z_x5pH1seML(%o|uq^EnzQIJ^>%RysD$3P7=o@1RM$5>wP-wA2?;25wHu|CM(tHj8_ z0IK;>>SZp7o1tU#py6wfU7b^SL3Y8KQ@9d(Jjs=;37JAJXp|?ekn9$P)g%w8VfkxiG@b9k`;a~rq895AhzC85r|Nob_ zIT#qgV}D>@hkk*M{e1x$1{z?oK3Hp-1!|;#M4;nX-7XhFLlqYTU+lUCN}fDWU#LLR zfCeZHY|dgp@&`yJ@WmT;kUuzxOa&l4-BXT&OoKRvoKzsh#J~V{K4?%-B>MydTD#=u zO|S=$5(LQF&MCYgYrz@?km4NNl7g6mwMoSc8YV>K5Sb<5I1UPUF$u{U$V3N{HM^J~ z&G;{`xj`OnKEQ-DxGG_Niof?B1H>1|ZAZ}Ps|d~(DUMXvwHW3i28fF=V-CBgp|;^@ zOMYoS$Ov!8q6~UT!Y%B-0S;-Xg*uR=V(|C>|Cj8bp%Tp0vX7OR)B;QOpzuVb7Cfo` z63EJ@tf0cdSETu;2zY2*r1_UziFn38(9n3o|G5kqd;ZU5cyVS4cxXIJgnzrQNZtv!@V6XfBEQ^hyA28mSh-mPK0x|x!ymMA6C@t^Vi#nrm&hCg($hWVD99{O zLV}FBBj=vLhK5qAd`Gw08WzN90v|6j`ghaTyieF#)(g6t1`vDXun z0ayq`J}d)(^dKT1PX=HH75h&>2^ci)kFVGVli)?*}*D{jOj5m-V8xgU{4@FeuR ze?cR?pj#$VKK3!Zh}(-i^ZZ~hXyzF-`D^{=#p1n?nP+}^1{nqhhMbRm3{U?5{|}l! z=KS2pa0SX{``pKH1j=Uq+{ds5%4Yc7$FKy-{`;wqVG5M}>r)>?3zYr+Qy&AUQw}oo z%cnjD&}asT{qa*D1E|jjV!!*;#{lY(g4nM=^)Y}3m_h6ppZXX;-EI*3>8CyhP!}1* ze)Or20o0uZvG0HCV*qtALF_x9`WQexcM$vLr#=QypAE#m_Nk8n)I$fcFMsM|0F94> z*cU$aF@Q!^LF}_2_y2?V{S?UkQ1)?<`=RV3pZXX;?dAmx3=D@rZu|THKZt$cQy&AU z7y_~Pf$aSa5#RHvkD(F@i_IB|%@~SJ8H!C9ij5hHjTnjz8Hx=UO3WEb%os{c8A?nT zN{kswj2KD`8A=QoD$N-x%@`_887fT}DvcQ`jTkBo87d7J1g`cm1YYf9m~^#|;qui! z29axh4B^-M7^Yt9W4L^+kAeSs9|Hpi2O|d)2L}fSGYba?2P=pL#%vtyp4a;r!k+ap zM7-!@@O$0IVEnO(&_r8GxP_v z%@5jHi+qgs6qp+DG%CcLiw{5x1VR`=bEu2~FA8Bwu7KuH86ai!Mbzs|d|_(9!@m$? zKnr`3j~CK}sR57U!pvbsxfX>LrUpDD3o$4A1RKf~Ef3E^y#*dyg*8r5k0sg*Qv(_# zh0X1CyZ#91_Wct0Vm{aw0hBQ}=v-d6?~lOl&@VwRe#6v&aw~M44Sggu9Hs`8i#x$n zINj)@pPON7K)JhfDrlAkWB!vLrUsPjJHcZs7~`DTFg2jkpmQo{(xn@Hl=C>)*8-ib zNMmuKXd|1-Fmn)7S>3Im(VT$pUXb;Hs55FWieYAgN=V3Lpm0b;zt?H+YmXs2dzi0o}cz;j_T*sh~&TU%kk$@MCF!hL( z2OVz&4Ob$jNkK!u0o}bIRe>+gK%5;E@WN>dxNXr19<7B8SR>6V?Z`P~Zqa3JK&bfvCgM-6(_MFZz&l z9el_H8ct&2>kQ#zL7hlO8+wjF(uKTb2d}2Zr;r`UhHMpR6dEz(4H^xG&m`xf=tA1J z(Tz4wj-qQjiY}xTh23Z)>Y(xaK&XWFvXlF_MLA0|({~+2~LVx<;?JWL3h;|mwA4EHg^ADn(#r6l$&SL(9XlF6} zLA0~}{zkO3e*H$Yv%ddEw6nhaMzpg&{zkO3-u>=l0F|JiHrMOleGH&X3Sz(b-G{R+ zgsbgTVa`xt#!z9(P+`JQVa!lr#86?#P+`CTUf&36jDhYeOZfl)|4t2p_4$iqprp%# zw?01tQ-ixcUkFozr#`QRslij9N5a&A>T^UL3!U||J`QrMK&R`H&d?RGl`@F+M^IU$ znMT;U9r(=NPq6s{ovx5N95OQpUttstHNh3s3drblXJF`tS9OpH$QKq6B|!l%^!lM? zB2py)UtR=R8ug+JW*ykU@M;{|WXOTYVwP)Jj2R3YKx>+y#vJYgTNM=WV&_p%2*B>) z&c4Wi($bNJ7zhm?)FKtSTI)qQObs{$P^X)qZIKt3!L~rdIb%;HC>)>@s;Fh`Du_bR z`V)u~Q5MoLX0*)x{~vW;^TqdGm|xx=f%*lt7=IB8F|-pY9y1y){{P<%T@dzS3(N?# zB~UU@jo|1*G>D)v_YdN6aA>0zf$*hcP?aH&IEJc3sX0K?t+09t)>L|-f}|d`&cLd? z6v-jkCy~m1NU18q(9iH<;W}8U3d+ycZ(e*@2Psv#7#J9282aI5>Nt(<9{pi}^e;di*PZr=@(6K%B95Mh-yv}F=ycuC8M+19(?B~0UK^%lL1*X^s4?h0 z1a_F337w%+vS2*~Hk5qx_#o7(hR)CyxH-%yJ(m4YHLV5U^?sn1D`d^U1n4Y(L*R?q zV7ml5T|ab&eu1oAoB&;K*bwyMFHH78XXp{w62V@OanQ953j$t5!qi;o47~zd5;zs4 z2D;XALEww6Ff|W4L!UrPsVhOd6KMQ{6+@2sLQxIz1!%==cj$$n z7wt$!Lk>N|r}`!&pulEB4hcn44b6n0lb?|L;7j*`LkX5q!FoXjY$!*!3m0hOkSp*- zBTNk>r$UDWQFB-(2}3-&<#N^WFWGz2Ryl!VL25P zbCA3Z+H43iAmGJeunJf>K^7c$PX*@%xYOhzmUp^>Ljrqlu0}Qol2f7i2DCs5ocSUk zN`eAjoNL7h4_Hq1JrdX*dLZbYw+q694?UT{K;L(Zw8Pl7<%=|vt) zGjs(t)I%?>fsGRAbOl8kXrVeNUxS8kzy;h6h&RDu3^{uc6hyePDi7{7N2T86xELso zpWy(M{hGTU)C~jA3%%g(XIKCgf6Cp@FagSb#NE%(0A=6j?q>is)j<9FJKX&YpaK%a zzQx_o0Lo|xsrJFo3A!vf%O`x+@2*3BCzz7py`AZxCvLE+L)}^kNE37E~2tul7GelmrF5cwUE5&0$pg z&Jfi&s(n?6EI3d=C#G!$C4^4MSSNfW0n$`>Q37bhRp5F&8KNX8;Kj{ajL?8p`mRR; zz-{?$5G6qYFV<{9)gX6Rr+xELApXO4nw?&2w_mJ zf`%|g^IQy)eh`X5xecxut;&CiZZaqr;!O0X4lp&4ObX6iXmjeaFeNB?R0t)H{#*yO3MG&7q0EI}g{mQ( zN3}PAOoPTDWUmWSMam141xFY5iZm1KW@x&@$fMpcSy0Nwo<~z$>R?Tmi9LrthN%Jh z6GslUhp7P-FW7Ua3`7ZN{c#yaSfJ<7e25ZI|9>qg7BO?^S+F=Xc2RSv5lk~$4xI(l z0*-R@99jd3D|qR@Uh*%MmLqPBCRU}_-Q6YR?Di^3>&nL*VcXHV=yS3PS$E{8@SWZQcK zbd&sqz!!NiS#Vr|+si@SU_%ituS{5cU~TTsA@_En%jfaTBZ zi_G0;0!Y4p8{_|9@cj zRFL|h7sp}h9l+{AD~P&VL6!z|_kvsiIzZvy|NlYVtsuVzyby<}Hvp>#ttsv91*s40 zo(fVAIzR#99+3LL7wItd3Sjl16;RNl4!T=GMu6P&AL5?>|NjTQ*uEU>erU8KozD$j zYSP^bG6=TSvU@7X*+DNFA?XgP3u#aguU)56>_R&B7O!1XQS3rGDGMcz1wgUaD*}o= zaMWUtV+N3_sVpE>=y8mcsz8S&cea8~PU{9IChV!|0ca0Q?~}ivgE>H&k!%EM4e0I# znFBgb0}`Jg7Y4j=Uj`0ul=RXIQXkko6{H@tg%%Q@AoYPSro+^O0=^S`xJLI>kflN0 ztsobGj?;joFOc7YUOZn4H6Ik&o!~<*x?4f&1G;-b>Oos*A?^XG4|rh?GanSqo#3NL zpvP)-PX!qPO7EamTiv~&1RnUJ9b!H>=0QU?@KHs)aTtga^GM^Pc+<;lB)hUtA|1tt z*RE6)yO0j6MM*Cgz_E7)TkL@%vl~(-8~~}BdIY2jPkPw^Qq{TzqzX@ZSpZViy9A^P zJ%xg_26Xp=%mFPj1TTDV1-UTbh4>O^e1d|%6MTM1cP~hNVE0szdeC_wf5B&LfYb-R zNQbFMPA?!!gSuNmE(qxE1$ig1dn(9pK`*v1hMEtGY*=~$sSoJx1*r!uQG~b$q(0yU zJIs6{(@QwSd}w+>8au`thl(gMk95{2-t>}nR+GUDj7m5qPDFIT4OaRB; z6l}2vRs~5f4IouhTR^Jtq?ZDas@4*aDm>{W0i>!o1*8f+y@0fWW;XwV3v!U7g1TEl zE)00_d?7SGk<$xEePH)gkiDQKt&sErQXlxjd=XSVa(V$-3YxozChmJR^nIDmIivhBWqm9uzSD} zfAAsFT^@Mj@DRioP+cgE9#8`d)O3T?d7$PTsObi7D)B(v2G)gg#w=dDt|8f#eG=&q z_8{=7nht9H3@@5Gkf*#@Izdxjpot>uH!qHNK&HI-4ok+vHJCp6o+>D0-gEK!gEgK^dkVw3U||k+fu=1TAdA)RKJ& zb(p&rMGqGa@5rDy%@air=)OcudqB5yAqSf%iXI-U_JD3gMAq|gIwAF)}rVE-DilT2b?cJwzP{R_9bu507Ls zX2Z+?HN88*-4L)Dki{|}`#=kRK<)?v=VI`p8x-LeH^80}=mhsBI;VpAJ7A@di(5cy zLCeBGMnLAIEdnc&7734Q`kKBc+2ZawL=)1w4L_|*ylq%qE(S@l8g##qT zK!zQ`V+?`aQ$gK#&<-$2ID^te;ENwq!F~=3c##)}5zeq7NN~yt>TU&T33%ZOQ5Y2P z!Wyg@JW~LQ7Fdt+#bU6yKqpuOB;7&g3s43UUi^s#+ZYsp8VoN|VA??rh9sD7G(Uhm z4vWthCXg5hx2qsk11P|u@rFLw0n!N@DtS?bqLT?V#=B9x-Hno3UpOG?1XnF6R)TuS zu<%0D*ba#$uwx+$29b0^lO||A6iU*BW;xKc4 z>SPcXl3lt{2GXFOWyL7ajzDxmJaQ7WE)yvVv6mBq5XXV$zrmUjFDGOn3WEY(2!l0amJ`)raf0Q< zl}NCS80CZwOgkdM;4LS3AZY~}Z=m)QQoP|UCxTFPf|@rdI`L$82^5{6_7|}_;~>!l zb}gh8hNKf(Q1Er5WoBra1zlVQ%D9MvLSOBk~KX*-#IFt_}w|6z+i+vmrVmfpHSl z!bOTg>;=V(FtFo5>;HQ})*=cDE{uZ024XyNoTApGsO8y<9+-MW*yC+b+yT1)r63|) zP%MXN3JQ233-JnaIAbp;zJ$X3{Hh1)XVf9;7eNq12{kBI!wf1q?9D~Yo&Vx&T-1)xRqAcNo*ypRLOCFo#Okq~hF zB6k3=W*|_D9My~{h-09^2|9O-0W>Q)g%`AYFpIGpwK1;K1#&tf$6z+WyCCMF<`~fA z7Gg3CrF|F$NjOmZK^Yjye!K}`0mS!EouD=Xl1^xtfl62u|3XVVP%{rCj);^Xu+MNt z3O9Pu0JVUvyN4BI5F%1KAqE8nyr>T%CQ=|hQ;->me$3HMP%y)~NuX*J$!i#qGQ9(& z8Wt&_rH+vP6vA^~A?Be(3clw4QAi|$gBH@N<& z^g!|%Mw~FWBgYB2%MLOQ;k6`)aYRRn5hPhbtp~MokgUfWB^8j!2kQj)qmVR0V+7PN z067mHVBi>m^iEL3Uuc8?i0SSO_Ai5V%NmM198P$LDjyc<0nrh$Ei87W}nvoC_0pCE(aX&D;ppgu529B#pj zvk-%V0$v>U#f%ipAs)zR8^{c}*)KRDWY%K}L!e9RnmsiHK*{ZKvN>Jzkn1=1mh>p@*|_`C`1 zXRsb<>54^qbMA74cqzCsvyCjMp z5fnY(Rty$Uu1ypT;yn=I}9TNT|4z!m;>lgn9 z8;g=)@b-&OLjnpMZ;-kHDcUl% z+~EOp2O_P4-2rLEqNoLnV;g91fti6A4uOoH;mhs*5KTb=FI-)~$r3sJcHG@3u;W1cf2u&%BFYKOf%ZRO6)16vnn6&V`N9X{9OSuB zyye6kO!Ens6X_65K>;uBI)S}{9M0Is&$d7m1_iuWRSESoS~(#EF_cg_kqt8lH5gu8 z1{+I!Ik6ZLP|$b-jSwJZJ-p?_OB9`?479ID(FtmRq1cJ1g!u{y9I$I4%`haL(1HTg z-2r7T^bCqQ(7wC^6a^@W3T!f@rvowrwMmkF2s8`?5{H}p;xWt&w1NWCg$1dF7YIcZuTDX1C{D(Qv9t|@Cy`aE1(5?p26cq46#sMP%h4|ZHoz>Cr{khO?{0%M5t#bvMxlsHArA!r4KGQ>GV z7Zk;q<`XU`>>!$g0$yyf1AB#VLD3CS7!>fLu@vfOw1VO#SRADxi*4rK31$##FuYg= z(~d|mcpDT|kbr{58>p9ol=biy6bDdrg8Bd`I`L%pHWZyaB+U7rfrL2JwV=KVlAX}Z z1xlNsAqP3m z&PV~(eV|wb)qS8?gmm>GXC{Hf;aTxTH^d-N`DaN?q+l6nKT!Y*W!R{$G^)=q;$&7n zNHr{@U>Rut2{Df7C^-pp<0hOO88N93Zm+SMhU28fD&Thd;;m7poqUX2=*9e zlz=rrnkgU+@Qej^Fr<%yBL3nB#30c9$L5$(LflBZ3B(Mr9oZ*^P`!o`Cv17hae{56 zJq2PON~GW$X*Yo+E2#Z4sP^NHlqyK{Lv@Oy>V!rLsObp`Gk7wFhA}6`jDrr?XPA)! zF`k5x_GE}bK>;r!%`hVcvqpgow}Bi9&x0@K=YoP6mQf^7y@nAfg*hPAu#AFjr2Ra^ zJd{YmS9r~bL?XoRCxub%#~Ue6A-;#|lttAEA2kO}R)c1tLD2#li4S_QHXG~*WEVou zj?F&74_ZV9+6273w&{L7;HLm zaUl-#1=Pp5d;uLuLJ8eyn7fdD0WB6JKuf>C8?mRbg5o0Rg)U4rk}pse+@dX)_zPA~ zTwDaA`52ckz*QV-f|`~A4P0bTKogW8MuN(KsYdbyzC>aH^8_@J;8WWJQ%f)^KwUtP zFF?f^C~yN`Tu8^_3ushGVnoFvm}(?n;ERePu&;@WieoUfP#@!p3P{a{>I*KIyO84o z>I)$ZU))K9`k6>ytO1)&T()3<`GR0vfZE)szHouL3yUwLFnl2fQ%$5Vo`Ka97Z+A& zKE@RnkO~dt3q+w)mkJGCWM4q@g)m0G2!N?Z@&&%Mt^o4|G?m~}TLM!{FfKq%ZICYz z`C>;37GFS9lr%^u;-_>BPl_63iC__@W4=nn+(b zfqhL}Tug(hh58tGz5s8@Kxu&7O2F+4F$`a={0k+|K~=8c6THWjQrbOB?4ZoTKg1qePCK=>ywB7|M&LZdHDZ-ApiDIiJ%wfSwXi4 za`10=6$#+q?kf@aqPGDo0=mC=9|Pq6;;Anl{{R14D6P8{#7JvCz?jwvX7cav1&Q$Q z4+UR9-3h*B7cA2awxnC6F^GRZM8KB=#Cvh?2G}i7ot-VcKR*2b|3c#b|NkIUpo+CG z!1PZ<*Ppiyq@N|=#Z+{IK0N&Y|Hb)#|Nl>T8T9}E|CcI^q`CeJ*!8XwP^W1h?4Ak= zsBV^~0RHV@e?r5odlkqD95X;GRFFJ~%g1l7gOvxoXub_%@IcLnd0qA&$m`%B?rsHJ z$TJ}jDJ+;Tfb9VV1a`MU;sA7L97|Wg3%{)(OIQM4l)|j#LAMqhP|N;;0_r*Fpk_vJ zQs`|3i3jw8BP8$zTlUNU%|`@4*9wE(hBx}Bg3=Y}3i74kFa$?9)SDL{c8BtGx3q$y zxs#>qh2CF~cYP)J_k)eqJ_U{Piw{8RdV0Tn`2WAtr-|hSD_9{|5kiTtK=+iXAa{0( zG`@KJ2V@j-piF6f^AL2}l;;+3ARswGpwp#`<;BK7AWs{Ed)S~GUqjOS8D8YLBb5X1 z-9hC5D0^AId9leIRt_*TFfhcV_cMTe!NAYJ(3#%P0CEP1-Im_Z0E#yj1_p+P^nQkd zkn+qFhRj@sqEuM^ZGNK=wgZ%XLDvJgKIwFQ(dqgIbo#36mrmCopc_M71v*{-@bC8( z=?)d>W$Eg4{gK58xljDN< z(;YJLPtc1~n?O!x0U6D|KlBarsqWApptv{s4GMmLP+kX>H;@Z1{{+2|0vAF&#s|_m zUBSNb{gBptkTI>(_XEgM{{5~Z)))ADpMn#YuLwv?`&75I!Hcjf5S1_9g7XPar|TCintp&a&4OwIUtYi8^#jPO zPr5}W27xSh{QwFuk;b4G#ZYB0eqDx|{qY)z!4vRe$3_qX93s%LQ2PZAf3W7zFQ6C^ z`2`A{|KL-zK#B87W!-J05bza3G2&^3=9lAL6&D3}xw<}Mlz{_nY z;tDHa;`30%H8#V<+fc+m^h3p87a|PbF&QQpgAjC>1`~8g2x`oL2^t{;3ueLuWp_3( z&SPjjSt61Zm$3kJO|A&jJcbvXsz}%5?s0~MGDmhl!{@AihI?843@5Yt8Dz8j85lqp z{}O>AHv|(_2)aX+tSSp5siQID75W?aFhU0TfNI9l;7fG4t9CtN;`r zueBixX3SuCt*|qI2^_5A87&M93>gJX^B6LofI@b?GE&GUIYB}e82?S7L1N>cpW zU3mgt@Ku0Iw$=kBpp!6;Gj?`#aJ=~W4U{#Wfs6*FLjLWcJV7s>lp|ESavWzkd*%$! zi}PTWdq65dLBhY?mnZPWE+mzq9LJev&73LuVkubVB#=r_=788f0j?6Xp7uDSl9H0r zi)xU{*V!4Mu!LBhiKGl-N$U*#1FCOa|3I37;7aQc|Nc;ci@&T-@%JABl_IWR0{Hj) z3h?g_{R1keIY8y~i>K$n?&x%V19Bz*e$X}9kS5`2hzydJP!3Ra!Tc3mME(J_e?s4Y zipY;&{{IJ^oQkB>l?QBkJH!kW(|N!R&RmELl9o^&km*amz)a`qhL}G23n-O=juryd zy{-ZQ-M&15;2XDpCW0G7kj_I*em}ztb9+#^+gavXR40pcHrUnDL7@^(n$pU%)9FHZjd z|9=Aiepi9!7mR70uHYE({gc-G5>!WmLjO_+Pi&4x&?z??0{-SBo7X7@|Xb8jFy2QDg@R7?8&h7)yT!Jv}RL|xAwsC+xX@H^!`H70aiN=5FW^40YzgrG<$Xhys%phc2uY9ACQ!<0O(2$P@0|) z_(B;b^#ddoDgZjq8Pv$(hKYZHiSu-W#6Ls&C7rGxAmWh2cR(^XVKQ$JG7vrcVKOfu zGN7gC(4N{7nA8)Hl&b*fESFH8ZcrNPgh@RBN%;zZ1};N6z*2cIsXItg5M9AAsT&X} z&=8v|2iWNrFsUmbsZas%WpR-FD+`ml0FnYZ1AGTN$Qev9sWTucP}s3`L&NSlq}AN% zdIBT`G7!8u0Mtx71Cu%ek^&jX4(fV<4BQBlI?(NVC$Ky8PtXg#rO^1<)9rdEpxgIP z;EQgU&=$xAu|EP{yjTKNwWHhjMqqd7kDwQ+FjX5MHz$4xd~pb-Y7OKJ>n{N>>|v^w zK<;<@5cFaWOw|g=Dc2tYUr54KE$9wC6V&bcCg4RGOx2uj-!p;Tp>Kj-e1-{4fm~qw zBJf23OlU@T=!u|i*B1dV&ccKyKrT{w67)g~Ce#DDw&6+Oi{&t(7SL5I;G54_U_u?B ziyc505x!`I2{m-P&I#!D-4poY-eO2dwAO$Ng*idpu6qJrL_ig`=72=OH?r;sda((n z7Ifh$%fiHAmYBNA;Lnj1*?v#8X1`~||iTX|m1Re1Gq5x(B=mfoP*C_$uyCsks7E;{h_KZYih?-w@R8x+CC)Buvc)m>N(y2ESMo6tzJw zzAOaW0jgL*g%+q?G4X}|FVH!~ps)<;1}A}l7cmgSKK zd7%Q?r$EIxNZtLPpsRpE;T-_IsQm>G%)C$m(24?I9#A)RJ4hYungmcH3wZGaW}dGA zXb=M2q?iCw20N@Bq%81-E=(E7T2RpfvNi*(4ixzT-H^+UUra@)yZERZVyh!a8T3X& z$i2xg?kzwH6*j0kNw7LlTm*Huf)a4Ri)|2f-5;`;!S&Y**ELX$7rI?JI!z|Lc=F@_ z|L$Iprois0AWcCp1R-wd{*c8EZu`9ufN46>9m>&Z()D6JNK-2)wgS3)LCHVxg%7e# zp#niKZbRyi86d}*G`^?-X@MNL-Q5b(67XUrTnjtIaVsEN`1fA`_3=z5yl@9;>IJ1h z&{3cNL4z(&=0iQ;D*$o~OV|3Gs1_ zM?e*`^_v&hO(Avp8EAcd0$N{NfbKsxLe$sbF$s8k3p^$PZg27Lca;E*N$da(k%C5H zet=rVp+BIbFhBVByZ!(T=YU3G`oZHCp)#O0FaP=r{QG@D%pd&gPk>C}Uw?x6BB(WX z@gZoS10wpPm&dW&RRuO&)A8c^H*jlJ2BeUGJ!rHB#Qed(9;8)*fBi+~L!jn1XrRYe z1S0yQSH!E^R|Pa)!_wC2GLhxQBv9|;W$6F^|6l6-|NkF6dIa`c=pU%N|A5`N-&ex= zV6ABu6U<0g5&rcTx_wo8Lng8Wfs|Z)0P-CF`h(q}D!nXC0Wa9U|Nq~7gy;2UJcf#Z z0%MO7149-g$Y79fvrjPeiUfju3TmbpL2@?eL`Wkr_n}(1p9p;Mc{0RvAXhzyu;H${ z4#{_&t`A_YVta9UIaEEuRTE&w9SC@_1Y!h|t0ut=xr1;O+lwBUF$hvy_dLAZ+J#kXZp&mmm3 z8LAZ&R>vp7rC;oZu;H#+4Kwfp%vD@3mcxugxGDu^+<|}>6%Zqk!YU1B$QgvIxLzc{ zj6t|c7G}(ez!!#4V?bf03Sq-tB?>d}1k6=DF9c!6AzXD1q758Yk0wGqi3qC;kSk)*jcwU@>G%xwLBV5%EGv-9#i`h_PK(6YCu;H$%hZ%SP<|@7y)iC1_uCjm`cOc+} z55x$hu(E;~vIpTRz85AiV-T+T2-OOTK~@<1LePt!6TlvYyXxg!Fu&7v$ID;B(BeTO z0OUeY_GWx>6VjLjd6<8@t3tqw6EJ}jpgEpDK@ibR2+!ix=D)rWZvp{RkiE!(4qL@P#u}D=1veA#Au0%=dzQ5Wv6PRRc7jBodg#_(BO` z9>jryFaZ>2|Aw?6L1o~J`~6^Zz|K~N+abWeUBnUONs)jorWdCX>OnySDl?E+yZ$jAc(7m}EEC&f) zkY-4-I0UI&Kw2Q-yAdXU627w$qA%(pCWExRD2A~Q1iaV|Wg{F8p3TW(dJzlLjYt$y zNY2)SX}kcd6?LGFebGD(;_4S%v%!o`S8x>*ssX8^z;XE>QgMLdo_~9&LePtMFadA` z`~gLbLePsF2+u#42o+{C>vyp z0RMKL0FXCDg0fg%yob~c&|OaLXZ}!HAyB8jSPiKG16~+GiW6uf z#a9E;gcAwMVt%0xGac++g}@hLFadDz!^#l`gy@SWT~H4k2zYS=#y%1FLI&oN3*D}e z!~zPZP?4Z4wigE=H4!MFL4u&yEsz2bQjV~_5Jl(!ITcj=U4kkGWr=5< zV8?)aY>=e!1iW&BBjCkpNM#)G;t-@j>2$pVG69|)nP2RL)SsZZha{I3FadDz!%C4! z2+7T0wqShO$9^hlH>q)C=G$2BaMn zYs@dW5N1Nc_$Q<~0%bJ*?XIxI@facc;&=xnctG~-hOtiszW5JiBb?5^9b^gHi={B# z2Ou^4pTHMMPzQpNMj1pSyd)_DufyO7cySg|l?J>BffOm7u8_tqqCLX$!V_jTI87)7 zys&@?pp+#_2+1?ygcp+`Y_yVu zh`{w#P< zL6XWjm;gBFVM%2NLiEL)Hn^4-51?$2-RPm)g3tqUHYju*p-u&bZYWeMD6x1#*znNx zgsvO_xAs7qLGi`%!U$m^BzzTN0x03jjSzkDz7^`&3qda)!`KG`UZ_KC1Q)*$heINf z1qX@|kj)@xcR>|{oIMX}2q;59%8@zX)g2rGFFr#m(tsCLkOHOC72IJ$YLBqK z$cLE@cCkXxi#V77N=f2@5PhKowGm{y0*rkj=tT;I4Nop$*NOyWalPPz=|)sN$03Tr z3FdYSG)ztezBmtMBfN7Kyfg!pvf%|F>x&(bng~$K{c*jBN9X{#A5{Fwz?^y^=!F49BRpXkKppo&92VAmkPbwr>lu)KczcBP1uM*C za6(oHc=2UA+}r%yLt%ZIdkE1Nhnk@(E(E<`gWHVS+T(h$2B8CFB`7;)LKK5Tw-#o| ziNF_yP&UZlki?R|0c-_odxZ5x1j0;61>+7AKnY(%gy;)VsM(>1ikQuu;Ix9 z(jMV@@fA|Jfua!R>`f4*U}qm|0y_+xAt0s5k@aAafEUt`8b9F0B1mxpnnVIE#zM45 z*j`MBnGSZZLg0%wm;gBVVdY2xLi9xl)J9O1;{juz2z=24WrG3@l32j*6$#4Xd0_z4 zkEnFsLY0Hc5k?sMK){QyjbP^^dFb;xun2N{gzd#WNG${k14sdQ7AAn=@a+iE7qg)z zgB*Sz%0?7`kaC3QMJqxF$o-&l#0loS6M-+nU>f25nh>b-URXow|9}@pkWK`6bONb+ z!1h8DW;U!8k$?$+gCEu&VM2($c-8>+JSh5KXd&5+9>V8fLsf_n?uIG{h46fsF$V%( zOop;SeupHPiI9c0kPrs>8q!p#LYN5&<4l+UN*D(tL|>Rg%?5?BHjI5D@I^k9jYu4j zl7#1lC`>oP;g_I_K@NXb5B5L2BzXpzDF}FB3#st~UL1k6&O2QpLpO-_2>Xkjkm?gu zCqOEm6)*vC1i;FYNeIywWf1#7T3%$q*are$tb?*afd;8~K;ZnbQb(kqD{(171Wxij+>*Js=a{ z<0I@Z{9$H;6S6|!3pb54h`!)~+6PK10Z=x`ZuHRo0;wrLUISSQ%8(nO%0Xr5 z(OQJhcS6|k(A^1{Jb|?KK$=1E#r|Ru!bC{;PJ{`dB#UZ<=!xX^AXN+x)Uhv;Ar)!Bi&v0#d8g}+EGGC&yDLog z3`}-Q78B&E_b)*&w!>uC!DQEDF~R5GIbpIBV6q!PCSM5ZcKs0Wq8cV!1e09>G8sB6 ze-=_#2D}J?$u8-3JrmIF`zG*(BSdGX>l~1A&Au-JvgnUI@T6 z%mBIWNIAP_u*uMd;m29uot zGWkG2x9@|%7YkvsGhnhEAd~k5f!0F2_zbB|171|YWLrQ>0J=l(1ieUy=ca4zEdDm{Jjtzo#4yLAyfQY0$;Gh)Pg77 z!HWbo1iVOusRd0KcY_xRYzTUB8zu^x&+T^YfK2fpg^7Zf4up0Db-S(!cp(oH1x;;2 z7745fdI4>3KyK6R1}_p=5%{7RrWQ0437_S^3#s%vp-UZF0=q+(1ic7{sRd22!sq%o z!qh^RIxGkR$-K~psRd2?W-)d5g67);yF=#$y=Z`F2zbE`DOoyQK?xBY$N}BHa{^zy zhbedlX~TEAg3|F+P>2SBR#?2SgDE%)Qvk{akSX}?&>2B5*1{Alfhkx4T|lrVpxbv# z;EO+y>M`KOWXSA8XDeuq8lon24P>=O2F#Frm>L_$V(6ZwVf!(1if?l}5)Of?x zfTpc8zzY#vS3njkOn}*?4pRe~pzWRtnz|3_1}BMt7ugU+-5(%D2*ZnCkeUrt=&x*gvpo^%)>rU~~MS?_RKYbu=W@9>WAsLhUR< z^u@+9Sg7%U79%8qY?%s5xv=Z0U;KyEpded7p~n2851}2B)@oq_D4~{)5Pjhdu>~Az z;I#JZ8Yr!SQa1b&(CG+!K%vI`LJeU6B-BJ<0w|&OA5zJHJpJNvDcCpQ9sxM5O#;~i zE|&tJYk6SpACP}QX^rK@K7;{~P+JQVKnbV~ZFc@c^5 z4Jg!DUPK_YLqg3RCV&!Zh6vFYq7Ylap$1NCN3McG4U}^NyQhMR>!24OA&mo&Z$P2O z`r-qmmVq_^WrAMZhY6sB+DU}yi?t<)Py;Wii2>OITT%ncJAp4c5%z#WjrBzb!T?C9 zmBR#3LM;&?`oa}r4{U+Tw=1B9FQA+g)D2mn^kQ-i*d-v}fI^M!g%UzLB-8|90w|&O z8&WrbJpJN+G1v@nsDaa3AIKia%AoG4pb9bQg*L(-P^huJ*o80vlGawj1W-Z^I(`RE zYvnL|VC9+`$evbE-hr?E2}alh3N`i@K`6$`1ipZem!X83HcZ)tpcniQdthnpz-3UV zfpQLfxzO8cu#aJ(#{S|Bq#i?*YqwznD4_ltlzwtEC^pigjn4SUQdL+p1Jvr1Z@8o`pz#<>l(E0p$%dsXb04bU7#h&cox!p z04=29U}RuO>kj>s)*1TdMaTdD|G_5x33&0Q5bXH0PS-ClK<%IjY2ChG(mH*yuTbK# zK3HqQzaMn!3kPK8Y=7vRZdVBV#Q|5)8fuQ#10{TE-Jw6gcFBNT_j(Ix8Bn(`M_RXt zV_IkEix;e*ZC(3a-+)#qffk^ba-?;$xTSTnc)fT9-s0%{raP1)t=shlSnL`^>`!;7 zKw3A8S6Zj*j~9m^VsAjJgSuS>x=RJpx_SK4I(Y(KEC)-0Tqcm#?fU~PHW|Fv^UlBj z|KpmENLasl!6bk!La?ki59HtP%E7BKs!*vd-sA$r=9wUI_M1oeGiGT&b3;te!iW$(R ziq=c~Ek8j^%s^Y?e!S-9-|zdQ`5+4@HbHU5zaOk0v=HqgNY%--&R)>!))yS0I0En8 z1Qm?0L0fl049K1h@QOVC{ovL{^G}vqJ*ZJ272w^b{M$tWgZQ^Y*Wb;_ho&bm|MiwE zCjRYUTLNDM!jc+Tidg$pQ0zv*%Jz?GhX4&c@1Klr!%xE>39F&$zQD3kJU5B&mKR0ozi5%?nJFK8(p2gu&E zPM6RVFRa0~Eal%1ZfG~ZU;5-1_QFQm!ccl0yc8%4u*#R z|I<2KL3PcGfN>*$|puutQu2bqD`;$bwoV1!8aopgQqk&A%P8oEH)(A-*Sq zUhK_5b5RXw*X!$Da67kygCgL?6o^8&lX^iR6!=0HTuZW~b%NL8X7TcGp9*T{2E9mu zs|WR13CEN+|Mp&xN@$3IQ}70e86f9EQt*AyrcsAx|Nn&7`(6rwQUcBuzTmP2OBMQqe|rnKJPUXclLdA+$g=KG9&qKC2{wBpWY^J+ zrTq*qo^v4WI?Cd_{lD?Z9tH*m>o+fSIdA_5RYnt-7#J8HEbV7F@&EsS4F(2=KTG== zKm}a{0|Ud4rTq-W1*srxR0!RN1Z$IE+h3N&yaQw$WFHd$cF@kht(jnF?gWcpWa#z< zIaTn*z90YpXEE;riGmIv1vd-?0$;R4RKvxgswW^+gLfbCZ|4yRd=Z7D7`%2q4Ya8+ z1)(}s0ME(;((Za5uzIE zM^>2XTi@Y+1l@e=3st=sMKx$GKiJ)CkX3_r6+z4{MN!QTGrJC<8gfxPBuLyLs-foSZy|mMyH^k*4mFntX08;-Tvm8EfVS=;%su#k1?K)27t^5Oa3J8t zRG7IZ0$=Qeh(p5h6fY#3a=ke8_5c4Y)+|P-`-EZcgW4|yX(kHpLL^ z!>wPf1+zXL$@*l7DzNpS^Ay2_AJ>bVFaQ5%NkjIpOt1ts#5h2Q%}fOy*8(bM|Ge-5 zxoVd**j3mXRn0%;K(0dSvw-HeUwlphdl$`Bpm~pzkl+HRr?U`M(6|zf&1(J+{7F^A8=6^}e8XFnAp@G(99E2MR}qB_GIo&>YqlNc4ca z?>iu>z)_WbQ5cp|4u1Ooe*$DL?=mJxHFV|-s6P}2-KPxA84M72A7TJ)qy%;Rc=*yf zd6-@_e)|6(EOqb^16b+72cU|j8>B=;EUi<7@kQLH|Np^K7axFa2W{2j0V`l(OY3Ce zdSUzN|9`Md_C;8w#SGfz2{(h|g%r$;gAbU%N)J9{g1H20%J+|OQ&_>)fi5+5g;)f3 z3CD{oAE7SEKEVcdG^j2Jg(!jgXX8hxf3gp;gDnExo8k*m0=7u-MIX$fgAZY~CfvDT zQv_aQBTV6hngS})5uO%&;Q=!x`yveJY2Y;7V)B4wC4jnTzH@s@u68X^8-9wc%T-6N*iR0$`BUuf-M4<%aEW0M*!oC zV1z}yP>Vp>6Ko39M+OLs_@EXEfsUO4B?f2&@FFbY16!1RLKw|QuipRvKLJ+gf;T{c zHq(Q9JK)V-ph8y(s+S)!7y)r8*cAaUR)O@tKDi50ZelwSq4}qDtrFM|2OoiUeE)$t z66{sS7a0%}V8vjk3B16$3px!2QuO(PorbzMtNDjqtrFDdf{-B?h|{13^Fs}WmShG9 zgFy##?1YqF*bP>O8!Uvy;BD_f&EbG{Xe%Uh0?fh>kTU-@Pg*x>$^;#? z1RCwJV`g9gb#r{byx98>p7$6a<8h#4pzgd_3K~a&+4=@-)EnrjN}vI@H~jlupIBe0 z4eRwi1L`5d$Nc!WgXeF-vHgCpTd;0yU! zSeQKF-yiy=+m$D+nA;hV+9YD%786< z(Fj-dquW;otO|U-+4fKg@X$!NuMBvn%?l2ggG$8s_q%@C2^tdtjaPN@IKB7-8Ug{0 zM0EQqfK@{pA*B$rL8n!`&f(wh`(+nclPgDBr-;Xkjs=^a?bcUg6&#dIhvi)cQibR|d%Y{QG^cKw9Bm0WX5#nzdn` zyAt$*7cL6%+?9YAx1wMH^yD?u>v=Di!8{0Vl`4SyNRWNb2{6t4EmuG-KhOvexD>`X z??wc4+RX+~+5w+r!vh@$|M5ci_y7MdJV1o=@Bja^1o*eR{s?%%4l}r$P z1ieVqgGEFNBmv0q?-y}wy;K?s;_d_$8Qq~WX`obc4RT)C57a~w0QZ>yxKhCI(0^T+ z4NR|DUz+@fmK6sdv7p9mI?N^fEssGS2MzRqJ&sZSfR1A8-w*aU=%g7Q_~^aKumAsF z_=53#O+e6qIYh^=P-N z3^?JR`w7|z4N?q>H!slAJAuF#9+9vZ767Zp@ZWbGt&ooo>)ha2BuD1E5&;{Q(|4 zhWYNp4{W~6ia_;U_91>qGGGJ+r9i+7Nw^K5SOy)i2Tlzb`L_|Kj=$vy$ae%{8GPUs z_&gy*Ec^ZV|NliMXm~|{e>*6G=W4@3795SBq8M5_I>T%OMPuj>aDxg~OtOPL3Q`Oz zU%>md1cF{PhQmDyRt>rl0VR42;Ff_r3K|@SjG+na>}Pnf`0K6z5mE8YM{KO$y!iGN z(!NNW0Ln!YJNp^V{Qv(SbS9I^&VB~}vecrqocwaoP+4gAo5nXhj0_Cny?ej>`~QEZ zGoqD%n6CjBPY+)BfB*mgc1L$nLfEN?t&KCqnP+F(&lNWzLyYgT2!}L6P@fsumtGOS%xbqF%UJyy^ z^nC+9-z-aoe>>>BmtZYe$n)<|0XIKf-@I4{(){8CXhehsviNilOj)To_;3V;pcgA) zLi{ZYnHU(3yIugdg+SvoV1M3ukq$Bj(!u~0$)R5$L#Ux&K-CxjeqR;qgSA@V+7Ubw z7XYq3LBsMhjAt+efX=dc@dZ2}#M9||;q^Z7Sr6cn5Glrh4h#%0%pkpAh(6aN0WY?~_3h!`?z;z6LLUiwQ4i4vRR%U~ zPvDE25KBR>$&!6h4dH=o1c%-iP>A_{fmULmVD;Ez2!vYVqcIpVoSzo##h6KFW0$I2Nvc0nf zoW5Tqf(+gsdLSrE?!{GzUeNFXNJ;k;u#%t`weesxL1IvCAg94h1s#v{Vi%+>(CK>P zwR9H43+p714i=Cym=At{20LDE`}hC<%O0czdJ#4pa_7Y{kP18rRD^H>4F-=@fl?tx z0_}iHWih;%od|XxB7u5=#)?1*R0NSg!(hR20o3wCl86lg=?0zO3QeFs5buJL3sM3V zL+FPj(5YZ$P<@~TDgqW@N$Ye)PN4UYjfW)nJ%KMQAfnI&dMgm-gad>Us2n1JieOKm ze<2ws;6)3h?SVCcc7U@4B!QlRXh4o$$xona&J`(vf(`)%B^k5?ssML6mINvcSyj~O zdV+tu?}5N9xfhNQYR84OK}FXnv&Sse;b=HLXW328pS667jy5=Kdo z=^sH0K#qZqOXla_?4hxF$<~>uPMbIp85#;&>lx09A8K{801IjC3 zx_iLIRNxCCa2^27IDUZ@1n=L2q6?8y>a0PLiIz%!`N13vI{EkutSAC6D)s{xl^n3B zJr9l%&_TRkU@4*pG-UD;bSU&oqko{PHdFw-pe5z~|NkKWLv(<0Kh*yq^@RLy&&a@l z>VFMJ28I^~ATvP;2pkL_jAt-_g5gQf3v-AUW(2&jg=8y8tpF=jBb1@(r^Fc4Gj@Ft z@ZzZwOh_S%0oq?h@z)m6cnkQH-Yn1{)))T$ETN!)4|s74lIl>c2!&hW0j}e>^SFXk zgWM+&^y0ZMEQkd_rhyJihRVO_ftUvJEiBe7K~}%EL^tO{&Ds;kzg3MLWbc zP`(HE4_}yp3j)vp%$?@i3k-&X&zlbj=T?f6m5(YLEqzP6OG`DA56D8&G_7yF&Y)#!yY5aYN|n+=Q2)QEb+i#h}GyW&9}a zWq~LMHT4O&*A`~Yex88VlXW^^=Yt#%3)UAqJis9eN+z(N7X@3*^m;Y833lWKD~M0P zA~%>t&?8Nb1ij#cm<)0yB*5Ty9)Y+YVy8qJXyN6;7a;F00!1Y#o)K)TEUC;Ay) z6g&fWnIVVWetvfAf8!BQPuTj+i*3(f{b$fPNyLeM22ec?isi}^{S2TEFsLtGa000> z9aLPJl$4m45?^j?6rTn=4i_|E*!ac;(!bsV>R$)q>|b}hc>f$!1N#c3b^1Lv?*)-;#Z0f+UPwQ>^?!o#rS4XcP+DgQ>zNl3AU)v70^d)7 zdfP(t4}scP&}9dpPTYRb$WEOaj0;Mo;I4l5MF#%uE}~}wUii3y(?(jSYX?jfM3Xp7 zVOqCqM_Q+g=$RJ}o`E8;FN1-DfdM89H6|635MW0!ce;q~cySP<{CMkufB*l3Vy$^E zhz0SK+e4724s`c|gwi@)c+b3O2C3d903JCA1^dhO19XigsGR-K{8Iwtuh0*mQE^C8 zSA*P<09hRj9chF4tHc$rzYacRNb3&mNb3yYJ@bMCWcBO53(b|2O=fiHU9 z!N%+YC9i{z7{LB|`4lu^2lCRz2c4~;MAW<&L_)ll{Q%^(ligE6LTQ~oqGw*L0BeBE z&*8XIVv6;J+Gx}WP=#^fv3Btx|Mn2xGeIw=yMSEIMg37bo;RG2n0s~=o)Yk=fzY=3k4#0ilNhmcg2f9kUK$I zE?aF+dDE1hQ^L;EQ4jXcp&h zF=u69$Y40Y3{e4Ec;+IyBH%?JLWL+RsDbT!qxEE|I(XdZ#f#04q4nmI7b`$a&|;DY zFXlc5)#dFJ`in=9Sm<;0r-7!eJU*8vLrcLX~kt<&`dYPN;kkRSok4)zInGi5`-i!G4l z!%(02_5{9|1Th3uBZJO4elZE$z~BgYQ3=)#^2w7IzK=jY0nMj@=bH9G0yY4=v+vVkrj+2WIAO#2HW(I$V zZm>sOCj@kZ40#P%BMkLOXiw0KlMdj}05vDNeOm%woP?y*fEOFU+Cd(9@S^1*$RnXQ zK+Ty40WZEnLK|Y_4^bqKgx-K0!1f^EMFGs<6M-*|z%+p3P#x7Hpbnf1L~UB9>w^pi z1|G;=DiKV{!<^SO(M}d?5oxm4&kR2I10Tew?0$zNxgE{gEIB+1z!2oU_ z$U{#+xobk;3n{qhgO@WIAm>AZCcT@GO?I6CQvD+E#T>ZFFOY&N4el^K{_Ud9o}d?#;Nl?HJph?8A@D^FT=WSzt7ac!*a<1U zeOTwbICl?GHSAz802SdbqH|tszXvMi>OrO4esH0v2`v=o-Gdj3lkb7sRy=8)z7Jls zfi?JnG;9yO5%gjkI4^@zK60_x0Cx+>Kd@r)7g#O0J_Bb#v|{lzBzVDj5LPUvgGc;1 zpn1@>C*XyvEjYs9#iA>uaT@SK2OJ9^m%Mnva1WFR;l*Mh#AHaZSRw>Vbg0GR8yl#> z7lK|mz%+o0#l>(9;KBq{EFOTU1!WQN+z3z5i(Z(!4g_Sx^dBmHu?9Sk!O`j3kOf)v zb?_my7I=|}Pzx?;8sSR8l?b@Z%Y})xWO4Iv2Nk2UA(q06QEx~~F5ra`*tH;^KY77+ z_y7Ma9)9q`1aLuG3Www|P8c1eqh#>pLf~ z7u=QyUA_fcHIgNfCD8555%}T=R7L2Vpx#!H83CYE(tRI*Mp&iB>jU@(T}ul*B_AHp3Sv>h8ImYka~NpH$lBUP`}Lj&5IK^AiX_S1_lO~Ymm88 zHU*YA;CrzyJS1eZz)p{S5GK zU{YxsLt0{TNq!NiHy9M3l9`qk59t~PC6=Yf7ndf%xW%QpU@oZF2%e9y&^j#upZlG9(R>;K28OvhqMfgTLi8Xl(#!aoT?V(eGUSy$| z!VWV9+8+pb@d_-Da3QE11Rd?M3F0tNv-d?A7d*N*Fu@iRf+nu97KkCB;*fv8OX!K# z1K=%yUoJlE?A7@H|9|sd5UBtjIC*pd)Dgeb-3k%{4V;{KArEpts6;#7(hEA?gMmST z;RP2+@bwgMO*JLxMYky|yncWS&I#bs89X3?I?w_N7VCrcvYLJ6N?ad0Tfir1 zyokOE%3!BozJX+c3CR7Q4*u=F9iW6XA?SrO++UD159w3xh19vwgf0S7+Y|I+IwWd3 zTR|llI26GC$G8adhxLW}@+=9^Km{~O{RO8TmVg&5;C2%<-9pnucQ44iz!w?dDQu`5 zcr|NB&xBzU_tt zRKSac;4Orp64p73;e|0oA1D?(A*tboz!gyG75W1?HfxOGu?a5JAOr9}UV~QrsQ>%_ z|K&{3;#W|f2FEf+4Lig7LTv~r$?@+G@jcOc36x%4zkmjgK($HpUJwaMuSVxU>Gfpy zRFDv8;ONAQe9%UJ{{60Bj<zYP&rU~_w5LLp=<~aL~y$sTJTA7ythUC4bPB**)M?&l2!rGDI^Z`GaE@><4Ul7BV4@$RZ!$S)>kp z_bn)kl2Wu@rL)pk#CC~uuBhdI%7Q>6r;8s2;>Aitv-VGN( zMb(D1Zr2Z>P2(>nfcYA)6+s0^_Y`oE9MlbNN(H=723H##onS6_LcF^d)U*oho(gJf z1-+OAcPrCtafq%?aO3NR2gux)m7s|$(5M?Y95BjmP|MmBRJ5dZyM!(PFIQ%`0LuU1 zYkom%q^qCphIKp#YQuusiq>ylu$+Um zVL@x}I3D(c_sJ?SFfiCW>}Oc;|Nnmw+w5UK11L{AFfcIaJnUx(iZ4mcEdVu7GxJhX zD;O%{AvAa+0+hhAAEEh;0Q5f251p_poWTj;$BT2|lNUgN0A4WOoE~ z<>UU)KcE42&=k*$1>ho*BjANQIIV)J@Gqd*o6s*oFTUu3Bby(*AQRF9NCcg^u^n{X zCU`04Cta`#P)xsW0WHGrcKwmo$@IbsboLhH;#AP-QQl1Os{cIby3SAm{_RYlJS-9T z;y>Jo58%S$&x^mH1^u9X2dxMA`{skHJg@^e_#u-PVW1-iKnsCE%Z0oGUgSXxKz8MB z(5e~GRrDVMUd)F`gN`}LVg%nTAQ<$*3L*%;kdg6456D7r+u%>o3wekXX!jhf>HH_~ z1!!e-^AS*{;eom`9Ha?+wNdjC0qZv}zMqC92FU$RSq%K!TwMaP7_u0;eQg4}Lk)tu zT`dCmxA~fY>R$=a7!tT-;t0%Q=nho@g-5rqLST2OOi;J0LqNB$MqqcSKoD%SgV~n{ zbW4zu<=_9!M*=|QOQ=rJi(qiy66C59d=`SeCK2?)MF$*Ppz0UaSKtT&^>$VGw{rw` zhbjbhyUGM~`#J=6hiaf$4Q_EBe8j>W$`h2u^kTLJ*csMuUND}%1-&#Dnsz}HXusZZ z*FT^R65<$>TK40ve?Ti^yIuc)c9(+`LNQkLbtI~Op2yl%q+YOwquZCm+E<_$Td1Oh z4@iBDU_DfQ8ByvH=9d$t9$|hFLG>Kgt^%c?y@}SoA~?bc#r2bKbQ3{ zL!)^%Lk7dcEQXYYAiD#ak6Z{23kR=XH+21Bd^Dif^+U>HkW^>ti{q|O7#JKFprr!% zm{8E=+RaB;S`Uy5+RAisdF^h3Dz0LXZV z3w%GMbn=3fM#jfQ!@~_8U!93pW1pjbdOZVKF}N+8Pw_zJDO`*d6+#(JH_d zDy7iv`lI=P1UT}(fOT;*LZw*2tM#EafYMK=@1JhhKgSsoUd>{F3WKr|7{la!|Gc;e z4quMu2aF|rSv=s&W$hr92*?>vV-K+~oH^6*)1g?j;ip0|8~@TnmmeJNzF>Ty;i3HH zM~96M7+*SkCOE9yMMZ-9K&eExkBUgQi;95prSBiRZ*;q;@O=N+efhOx_lfQp6_M@` z6#`!nW?MSRvFDgxykMeNotDm-P3 ze#V!&kHtkF5&&(L0J}dJq!el$*g&v#E-D<~KXxB7zVtc(Y@I-Nhzd`)iwXytbtk^3 zsEADbo}wZEwTq{mqlnMiMTMh`L)%3~KsrQ4MB7D$Lpnr-=liYiH=1uTAX^Tp&jUMs z|12ypoWRiS`{)0K38*0)+6~&v81P~VC#adjg0goMhkbbbgLBT8l4dxr&J}MI3A&^M8`1;~aa4_F4 z{qp@IIGAO?!7Kp}W)WyG3qXU}zmy&3<+ylwhzEy*ohtxy5)Z;j0-caRmf${6D-5z2 zAtlinq9Ve5pi~+qQ9zQ!A>&K_m42^-yFm^{qzhCBgCa@-6j373hyo=FP(<;7BT7U% zL`6c|MTJK?L`A^A66WxDw8%Ph=FCgbZe~!xL-9*)1_pRyI&a=4@geO)Cl7#-DZ$#iq#aX!xm6 z!~)90{A({j-wt(PiI(i(r- zI~42U_8~0Pxgenq@)>ft&xE)?;HHSm>AN(cX zeF$PJNF@Y+W8H9j4ue7|d(y``j*0_^)A;KSTzpU@4NBGXidjGN>l`=?V$Uz;Klp&1 zf7c6nFt@(w>1Tc&-W9KAF?^MVMg`bFn0aDH9#u*lNcvdIQE}kt&$npWxs1LgL^{iGvT=8(!|KWj`ISqln6kb6Of z`6C+!3QJ)I28Ne;|NnzS1?)61f$6>~bob4?_yA<$yka(x^JaoA-d8M%<~mSO0C8O@ zOY5Zy4w$=8Qsdki-F;RV=?O|P@sc2 z9~_I-SN{Jm&rkw3e$A^{4E$>@h=OAQEN@@T4pMA<;4sX3;{zTjQ4F(R^ysg;14$qM zqDBWE*LZ;}c;E=N;L_plQ~bMLi5z?>()bAEqQ;lTEDQ{_lHYFz8{g(%dl>9OS&$2( z!TI}e^G}{)aYz7xO!{D7%n5O-@g-!(g5nSyF;JrU$PY-+gs8AIAK?ILMREj)`@xyN z88mzNQV|rn82&?vPTc;JJ_$1Gfn%`^$W=2*_8!7#51fkyTThnkd$IHX|Nqe9?C@i@ za+cNu;6MRq5_qbBxmWP$&%A?29#<+IVodt@kE05d^YRYzhp{%in#J&mKL$*hU;_~bLBk)bdH+G~YrRyVQOenR zvV!$9zt+LS-A9_i)o3S=N@s`)%Y7Y{n=&e&`2|>1x*s6Q(e8uI4;cB^Tx8@vaq$(V z($D-6Xk8Ah_W$9CK5&?S*F$;f1J;L1iLf8)8Ay9B>pysMe$$nQ|C^6+#2)^yT4FGP z;lFAHn5+Sl4PdebOm=|D9xyopOilrlGr;5=Fu4FsE&-D(z~mY*xdBXW0h2qxweJJ3?Ee3GQ z8rtjzHP_xKfYm?f_T}jGebOEJq}%mDH(Czx66LhZ0n@-;s-L5ZQGr@b-p#E8NEeAu142Z1bgbtK} zyOp5k7}%j4p#DDOh+we)CBXiF0rvl!?$9^<+nKt3U+`}iv_4eg4VHt1<(KZzA3@!& zUjklC1?@6H_L%RVPG69VLw|rg4jCy3c##KF268cyD^c=K^BWCRI|MpIKQz~VVBv31 z2X8n0@L#2M%Flj=ZeM8Vi^GgX4%R0aq5lDL7Hy|1va%N#p??yavNsr^zX+!6O}Fct zPS+RRzAr$j#r4U{tDpe}Sjbevl))?oh0LATZr!LM13HfdC1rq=J$Nk%R>lMhr8ko@WW)0?YaRqgb`v0W5A0Skkes1U2k-|-gvDA55@}+ z@z)Z@2VRSGy9xxrWz@iVga?#I_~jW&fA%vZ|LkW_`Pt8~<3~S(%#VIhRs%;OIQCeUhI%KW+5KBB9|R2~ zb2J~~2zn8UMHwSVnJZ880kDnD2YCWt=wVTIixq0A0K`&(0N8oDC~n&fQU&D!E-bpkO_D(35zm2 zkTPG6=7S2Iz8u{k^$MM#Jl(DW%`X%>T?Jk)`S<^Sw=V~?uK+}zIaB~5-|70Jx%P)V zfBP>M(4PDs|5bWT7$$%N_Z7s-7cv1aUi|ol>CYt~Wv)EU zFGRrpd?^z6;vyDhwIF4oJk75lf%`%r;KeE|%ECa(e0iE*@<1%*33}0tMVUTG8OTx& zh@~8XFJiDL;{YiGSqe!;FIWOzm|{`(5IocV@)k2Fgm{`?%0ldx4SKfP z_#zvNGI5Y;AWJzRmU0HXaKWPN0~6GztPo3CgI>sDQFaof3}h)I#8Sq<7sq~pefn}8 zND5?;9K<5IfETwRQYe|A9i$B8J1K}oQb8}aU{RI;QU)2tBa})BFlliE%W)U<`Pn3{&={+xJVSFLHyz|4%(D>8O;PAJfA?IH|!;Js^42*yJ86^MqGr0ciXDIyN&v5H^Kf|X#{S0#d`Wd|b z_cLt%-Oq6PPd~%=zx@o#|N9wwe)lsh`P0vE;cq{~pMU)fslWRfYX9^zto+;0aP?n5 zgWd0bhOj^V3{8Lg8P@$n)P}uy>!*}YluD%W zUq7jQf`9Kp=Hsm=`CTtGpZMQ=T;TPE;57d0HR!+dAO9~uO5?x&L-|*!2vpWVp!t9RNUZgL z$s7JX*O?E!-rHTvVSJ$Z=` z&zuSFzSI1Mqxs2)<|8bj-PtUiIVvpOZ<^mYKm)bbx7(S6e>+F($r8!#U=IH6O#Iuu zd8`kXaCZlDG#_H>4CZ)!7ovoJdoYjnsZx$^XHXRmZUKYF{kmQMy!-?jym<>+4zS&u zCyhVvAit*TgHQYgt`8VMtTZ^QJD8*K(SLphhQ?nX_!$`Z+dDx~>de6}08)5>UxRf6 zXwXE{^#Z?!>xDG_Qr83g5Y7P*=K;T_>j97qe;8ciLK^?|6P>=G`kSG|h<{J$k514g z#ShHR9G%V_-QFDh+XeZzJM&myC`wuZKebT&$=dDA@mdBV z)OxZMG#|tVRtpLf$by)svE7fO5n&BVuigJcyWiY(<+%9}GSvX)H^0%~-|ot%`lFtK z!S+Kv14C(Iw=d7ZhrF#POW8pEijqL%OFI}CI2bxZA9T7t0gX)5A9uY0>R^BxsiEKw zSm+P%9MzBR&_9i*z>0l8bb?Mn{LtcH2+{KWivkT+WfWYO;?Vat~~c{-hc4zh+`?|4)83U{A<~pt~@tgIS}HY zje@V)UqjB{g@hG6{J<+K4nAPu-|oW7p~}#}zyMbOcF#>#jyJO)V$HUH+~zSb@V86{ zEk}C8!M`p>g#|QApxOWm>;`!ThEo2UHY#b|EGlWu59-sJf7JJ;sBrMNrm-?Gyewmf z1q8_QGiT0#&2N4q(OfIQP{MiK^$Xbj?665((E1)wUy7krIpe^qSqvE!$`cu~7_t;I z9=w{xkj3;u=I(?4%||4fe=wFZo@uWAz)-6DBI3rw|Hm0XM})#vW>~zQ#Q-+p#jew! zaSoB2?_LIgb~}NVtY_E@GcdeJ?0Nzk0O@r7!@oV0ukjHm;WYjNk^HU8K-tDs;5cZ9 z{eMJM$F)PXfN}$4314&V52g~u=Gq_3B_^-EGeBm8=M~u?M&EViczK(F0d#Qys7?PT z=*8PkumK%f9iZc>uOK8=g6#JF6L{B^;|^=bq)7}Q`(;!>BsjrkiDz-V_)-os zNal4tC@;Lb^%9gET&i5*ie5~HZ!$6H4iz{K+9tx#?fNGGq=MDs^(=sC2w}^5&1(_aDrjSM~kw&BNgN`Nks#fB*jv zo_%vK=yH+Sw`x9vqGR|fen&=vGf(pAjXEJAoKpd z2!@ykF%8+E|D`?57Q@YxH~-$fdGo-{hj(OGyq?7{`~HJ@#U^)nPrRPR z@LC6=8swR~tQ*i&FMz5pW4pt9;Potqu<-7=pj#)MJLi`D|NsA6D=0`AOQrtwmU8s& z1x3%&r47|Qj3pesr2@URO-q;FjqU0Md#HCV$REK05CgiL`S|x82zasdJvb4^$K7@9 zdI`Gh2obN)=l~to+PzL) z8c+YPPwR~R2RisVmVOr-MM0|w z--z5ic~?f|Zios8XlcO<&}xh3BO-@;LsWQPymdF6J-U)AJG3=5BwMs-@Klu-r+=D9lV&3Z~|D!dAl5bZ!-E37_L@!<#2>J_YC7QjWVf?%ufhBI@wHgHeZ#Prep2KB@ZuKR*Mvi;6($ z5s<@Q@PPd0qQcXCK^5fKM$o2b23rubl#M$?g`;$1>&ems&2LJ&&jdEV5deizj0(r> zyM-Jtc;0{_ULf*rBFA0E<|8Gb%MZj}J^2r=H(xq~mV~&d@W3qO;0K=-bQiSFKm>Gd zX+6jlCAKfpK%tYP!hhf``*#-=@dgG4h7z&cx*PZ>Gqjv7VY>MMT&2GJ{O|w&o9|lA z^0#by`Q-o22QOE@eDWXUyO)bV{DUt*sqE&1mXrLgbN~JS5AykKT>*i~3=rpR0ck&Q z^UsZ&8^M{URQwL_lsB^&{vEt|;O3uuH$fSylOmcEg)l3~BsAq6ffq$d6C_0uR#oi!bP;@gF_Fkj5YOD~?` zA)Czy7*+o%kdU8lOu3HjlcN1S{nb+;|yv1 zA*vwPp<6A}+VBgcHc|)709hSj(mLTE$T?xEAb)(~kNA+rA9Cgszrf`*{^HB>Y5YeI zgM7&fu_fjq$marYXECV$2bHrRZ!v?trPI2AZ8pe%B49=ue}u`=4ScgfZaMmiKjy_J z{)k_n_yul!;*UJ|i9hn}C;rGgpZH@geBzIM`iWoQ*eCv&i=X%-zNhgE`Ka)u@gF_N z{E0v2@+bb7V`=W!#310ccFYxRWf5h=m{4u{i@yC2h;}`j_3Tj}08>#%w z;;ak|kamae2YUtv=0m#{I5041U(hYEVPN3C0Gg2lh3zH|kjrD9ed3R~lEyEj3b7;P zW*UD8NbFD=fB2_NIyxUd(pOHcP0_*>Wj11ftbU{?}F9!a;^{fmG z%qN;3)HgqDXgt{PpON7cf5d}N`~rtR@khum0H?0V>!0{zVC?^&_+t(;AArC#evKIq zZB4@kd@y;}8G8tHB=RRgmbBU(BEQBf$P;cnga7ypx~! zBSTbpKJiB$PvbBCsGG)LaMC4>U&Hpp8&G12c$LNZ~=`~}}Z)*VmdFL(`NeE!5A`52_D`HjFQ{)l6r_#=*d;*U6- z#xLxm!gALIH0>$?%1z+d7LvUHc6;54Py7NG)A&P9r|}nGR7m5mI|<4OAL{v=LGv}- z2b+H|@V9(nW?%pXT`wym1H<=QjfX%PCyl@Ovq>6%*yWv{nL$yOcN1iUNE-jI(`o$g zZ>RCUJDtY=`C=M>+2u6;>xa5eH9i8};RbD)HZNvmU;yVATTp)GZv~y$2}_GYAu2pO zL6)ZRgG>$Kg*dkOq6x%wAz1@(P$EnRo3xYhKQjaK2~bVJ!qEInpeSxv{XcF{ZjuG% zPFUITQti+G|7rX}HQ-_;1w_{U0%c~9_kVPs0GF5GQklQ02(%BT{T?Xm{bJy6zsktK z@G=foM5OVDAK3B18RYpR2be(_71^3k{Efom;4V-F10Dc5 zl*V8DK><{Tfy$mVexVQ*mQVa~r@*)7yi8|eU;t|X#d+%zP+RI9D8WDjFZ^U0f5@FQ z{xZ<;$jQcsplECS2_pGh_kvDk02RKC4?(@K=AR6ZIvMOAa0Hj85*xXoq=Oc*U=vD| zVI~|s$PDi6HUD5JVZX}?N(+bYvTD4Y#Q<_HIDI22;ct;=WMH@n_6nvPGeqtaf5ekd z`~pXIy<=uzco_@2B^4YxY5a8;()f!nfgWm_n|a?Ay!ZV+9d^= zuKK}HVgOPIZbl*UPPuduYx7Tra*^gY0;pxs%@>E8-^hT)AWIRiG#>&nIGPWE)*rGo zzvAc=QF*cI>7)O5T~q{`kH{Qu{=rbEVave4!oc5b!^FT4)_tM*L4D&vhX2eAjjuqh znC3?f;rl_A&ucYX2Bts%`TIUHBGf@uG#+aB$IK888h*tn^SeJaz5~?-Y5WwF{h#|?0`mn>C9wlkNu==~`N8}NR3V7aqC!aH&-F8h_czH2%-0K(z#@iU1Y+plTwGKm1!7f7z2X{?Cs-@yFZ*RSBQ?BTj%C zCTaXfzB9)|8w-a%@kbnP{>M=77YB0eC;rIupZFs{&5I8Z^Nt>XBsTCRH;~3bi@?AC z|9443QVM?y6KDz;Y&6 z8+H)vf|o5I6F>)iHUDHN5d|r>faF+KhqtpBUZ#RNjQm1i&L{rJ11~|d#cBKn4_(su zBcCDi64vHTlj8UP|7}5Q7>g7dPlDncG{6Zeadk1WKpMXgxKucLg&ERrYJ3GsyWm!s z@gZ=229+K7x7zxX0g`Ao7UuH-VrRc@Q!9_?z)-!@I5m zcVam}!!7X9H`&+Hps|`*0hlPLON?dg4Kzvub`Q9-kbQ!gf4d7Ww(+;StPftJj=z!G zUj$9@H^1SzE28p3=thK+GIC&X|Dg*Yorgd= zL2V6=ce5A{?*a{Fz4iySCqaro@yA^NwW%21&4OHM_u2%+{Q$N(^58De6%sG?LFL{- z#>R*L*%=rbe}c$jt2F-blb`tGPJ(Z7Xa?7bJ}Ls><@ty@5yWQ!Rfse1Au2>j+YRP; zL>uKIXndca0o-mcSpae9vfdOG252Tad-KWv7ocq2e1zvPIPZXRPDvm%@36kGya~$* z@;86M)9{*`PyX*>Wnf_F^$95D9(R2J+TMHI^^QFQ=st@Zpk@MS z9}^>pcYy(Xhrk&I77*_Q=rGOWu17#;PabzY&?md5F&QKx0@4Jst(1L7KS+QXvCIq}g1x?pfp6;#+&_%^3Ug%D|^?wIT>THIW!E0`VmR2K_c)c+`@q!m5zXl|4 zj3NKR_{5916K?(AaU^Xv!%JZd`6tFFUYrHVw}9k7uf}HnT9AAKNd7X0JjncBkbFSa zY=)PcvC8Lyi<^12{-1Cah;tn$1dc@B{M##rUw_TT!y z;{Zs%FoygIkpDsQZ_;Noy!^Zh-Txr@wIF!`kozuUmG1?~n}FmuW0lVZ$wz?XCu5cO z1<5Y~*P0wf=dA^!su{~-Aqkom?~<=^(*`oE(D6h6XO<@UVDuM3jr$pNK*tn$1d zd6w+i3@?qb%D?Ts^?%0$p^(hR{6KxxBl-~1F~NjtNdAz{1=e?=Vj>r z2bsSXB%cD3zl7R^M-WMb<0n%TLRbCe)-vQDej3E!o zpS&RX1EBaZ#*qI4D*wA~{ogSMBrl9r{wzp702IETm!kV0q<<|)o&zL*8LNCRNWKIl zzZpY*3Ml?T@<%}an~Whp!T7`rUy%F@kbE(QJShBiLGnBWp!|4P_yCd@#*hc)@3SEJm?BX9 zw;0|3Ao;Z*`38{uWej;x{Pcq4ML_bKvC8LyMZzu-U|5)X9LGmIX z`CzQ_ydZfCki0Qg`M2%2{_ltZ$qQr1gVOg|ko*Ub`#vv1_dm#eYeDiZC9@e`UdAfl z3zDA#lHUxG@AduoQo{TpsHt`asXga)#`wgG1d!qakm5Fo;xi~pK<=>xDft3Yk_=IT z)ZPQ-Cs~lZN$G5cm(Ez_|F+%wzoP~uuZ&gxE=Ya>NS+z1{9cfJ1W5kzLiF(XV|?Pp zT#)<`ko;k+^0gp&p0e2tFBfB#j|IsafaII8%G-kEUx3U{#*hc4cUh2pOa;jQ81gHO zPrUfsdh7oV36Q)phWriV6EE(9w`L|8C{_ki2 z$qQr1gTnJHNPY&${Lgd2L4dHoYX#^4uoEv043zEMBl5fV42i3Q>jj+UN3{uI^Je%QVnLi)K)0i)Juu zi)Qd>i)M&vi)P4ai)N^3i)LtPi)NVC7R|7%Et+9VTQq}FcQk`scQgZAcQnJVu4slg zUC|7;x}q5#v_&)gX^UnMX^&>mYL8~HX^&>`Xpd%yXpd$nXpd&-Xpd%C&>qcjqCJ}7 zN_#ZJqxNWq5AD$mzuKc2xH_U4Bs!uQ^g5y$>^hdOD&R z=5$0etm%kmIM5NzaG@ib;Za94!d)293^W28+&U2EWc|hLp}|hN8}B zhPuvZh6$a~3=2A=8MbsrGo0#-W_Z*Y&G4x+nt`J$nn9u~nn9&2n!%zgn!%$hnjxwy znjxhtnxUX8nxUpEnqgX3G{c6jXogc=(F_jV(comn$-vOS!NAbK$H36Q&j6YrXJEK+ zJPVA$3K$p|Hf+d(F&Q4L&th1xA&bF4E{DN^p_t*r#uA2xjm2>J16qX)4A)8+Hpu6| z#jr3I%$z9>I2qGlB^+)XNIh}SM)c=S1+ zA!ScK!}FGWhD_i5hS#F`40-qR8a^z`V<^tgYxruO$56qL*YN8^?kFA&gMml`(hRZ; z3Ji)2N({;jDh#R&>I@nTt({B^OX`^zERC2MYL7B7>}Y3Tn7oXcL6m`k;YhtOgAM}& zgPS)41DA>@!>1|+hR8Pz4CVTa3=`uR7$z=bU{GgZU|1i>#bCh5z_3Jzfr0ns|NoxH z|NZ}A{qMic4h9CT2nL2PC5#MQtPBiie*OR7y7%w@yT||kH)Jqk&|}bN&}PtK&}7hM zNHAkyNL&5)|0x#+hENF}hRrhs85$E984h%>`FTWzfx$1OyM!@yv%Fn~Q_(!^&RlQVxYB$>TpIHT+Az-J?I;O+HK46n@3GcYhQ zFf*_)urjbSa4>K~!$E~XgF%`>hCz-&9<;jEhk@a-00Tqc`jt!v0vQ-yonmIVD$Kxe z`vD^Zt2YBfX)rT`{sRVviUr3=G?53o?LqqxFbGWB_{(F0*PjXP`&bt!`F&+r+ZOcX zNgcC;!WOLq6Zl@vn844(&?D^G;C!UyiCp*JE2p0Pk(kKvPw&JwMjeecjLR18V|=jx zBV)^rnSXbbs{gH6c=PX{-+TTnS#zB6NX<#cPZ6IP1HQ%bu8<63W;m7Ou%I?vfZ?8e zx`S|{GQ*@7wGDrpbTf<|GdJWs7iOq3bH4C#25&=QXljDpI#~wg+qIy2j1`;$1QKG<7Y+$&|@Q=X(v`+`50fIr3f*cH>AY}l}>@kQi zFff2tHG$>@LEZ;t6(i7bz@RL{z`zi|z`zg%N*bWGPz?KC)HfKft7mu>R?m?Btgb;X zzK+56a4mziNNvOH;F^Y|P1Ou7i>ewtwp22F*-_C@vay_D?YuIElE%`8X;CE&SG9^6 z-hC=;n6$Z|Aul(-L0vJgA?kci!~BYDh7Q@RhB^B(7!qUB8-l;5Hazc7Vdzy$ZdkE9 zv0H=IEM?eT5k^!H)VedyKTU+l?H#Ol#7b-G(WZ?(9;+%4rL8ZULu7$lqQF@Ion!*-QJ zr1LA+c#qv)|9$lRy#j-Sy+RGb*&@$IwZ$05or{l8e4G@Way(T%y*A@`CVRF`PI_*8 z-n{(P1?vh|6wN5EFNrNREc;t_puDm|tMXE1VHHR9v}&1}nKit%m9=+kE$X`KuGLA@ z2h}&%uc<#<|E&IdJ!o+#1H%rki9+ASqh(YTI+W+DRcWf|EZ5^O^foRv?J#e%EVA~s zm9W3&(B`D+a?sV^{gQ{b*B)L7Rf#hA4#jg_lN5i`*D>JoE6@*d>%=9?GXDX1%yE!tk> zSNyQJu;gz^YbjS*PZ?)-W^3ufJdarv6*~pZfpx(>P}f6o|%39+WvL z->W2}+Ms?w^O5!|-P`&*4O@)uO<$XJT1Zy}nERw)-CqI2U*+=u+_6kfWhH!j^|mil~f?jk1lFjQJFEJa%SWM!ZSFpM-;n z%}Gwl|B|<-p$23s{dF2zy3JeK5k9^_kv*})nbJb4pN__yJh+18x$TXnkv_->{NZF zCahts>8%x`ou-qeo2i$mA8O!isB0u_{Kfd9$!gO^vk-G-i}w~gEbFWst(j~N*i_q^ z*uA!!Zy)Hu=(yf7+KJV9t#h!;cbA#2R&F=l%G`xK)_Ayh-u5i?V)dTxt>Lr7$IbVO zZ@k|tzheL2{!IZKfjxozL6d@ngC_+GhV+NkHvih=3Wlze)%H7K=%2$+MFK4STtw^qz zP_eh-WrawkLuFRwl*)aT&nx+>%&X$6TB}x9U99?6B~@)#omAagy}bHl_3LV$8l4)S zn(UgcniVxiYaZA9uaT}buMMirscoxWP`k7CV(rUXhC1;&-8$#Gh`QXm#=5C>E9!RF zovpi9_r8vyUZ7sSUa#J^-n%}cKDEB6zP7%zeoFnk`W5vX>vz>3sy|hKvHnK=z4|Bh zFYDjdf2{vn|D*nQ{acc?X}J8Q6L9?-1R(${{ZJxRx2_m%D>Jq!KY`n3i!hC2;I zjNTfx7)zS0HL*86ZyIOz+N{i+(W28r&~mz^wAFkoMe9Y@N;V5^#YhexdEAx|~0 zPOmp!e%|Z71$+v8F8JvC_WHi|_3&Hj$LJs9zujLbASd8xfLvf%;JHB6pqijdK^noe z!Iy&7LaIW}hA4yeU7q? zZjZhYEg6#(vnu9Oj8$x7?D1H>xRAJ+arfg?;xppc#D9o4NhnX)neZpUF0mo;U?NkJ zb5e8C;Uwl{r{u=u{mK85ZBi;zwx@haF-Xl#U77kMRUs`pZCcueG_G`)^t$xz=^xTH zG7>XpWL(JL$h6Na&0LfDC{rTKH>){oN7kDx#q7}R&g?ze@3WP1LUY=4cICXzk4wm_oLxiGJAX5rz& zcZK3bjzw8TQ;PN!JuTubHZ6`VZY^F@e7X2nu|kPkNlwY6lI9RLveC2xO{^bSb6UsM~pD%x3&R3yZ;Zu=S(NVFi;z-5A zivJZdl@^tum4%hPl`AWcR6eNuT`5*&P~}yXT2)syqiSQ-sjA0Sf2u^Pb*f#eW2#H4 zyQ>#f@2Eas{j~abwP1}}jZIBpO*U!Pu|UtdvQU*BHeS3k9WPW|HgmG$fEx7P2j zKUjaP{&f9?`YZJ}>+jY-tbbDfqW*RLyZVpypX=M+N^ z|7OM`N*9=%4|Fu)GvE6d`j|dc>Btq!7MAN;m!S!22<~F z2HVw<4MzW?8$8|O81~gCG@MRYIjw`+O^dT%Q|Wp{(09jlzy*mxY||6 z@Se54VP-}>!`4mp3|dd>8D9LUKV>V-u;gbl!zsb*4D&Qn7+cubnPh(MVS2;Y!W?ia zieMr8^pPxshBH4ZXWjr?Mplk`uuzkHihsn@K_|!(EeRe zfjdO_K+$%Q1M!Mt4wVzd71G!xA6#sbO2}ZAS#Z5W_Q81}c?RZ%3Jfa7N(Y{vP-gg_ zsOq5lPpyG}u7*RIoz?-NN7@YY+I1bS=;+Y*_8*&CvV8r=hss zuR&Efpdov4V1s}`FvHy)Aq}%_!x$v@g*PZ#MKUyQjA~$0iD77*7~8P#XB@+Xm;{Cs zI};ns1(O*zCZ#lRu1jqY`JBeE(lDc8PG%;<@mX073`esYlwRaCaIoYx^h)G6^r{v# zJk=^}DA6ctkdiBI*uh=Wp!cz)A>mvpgVEx$hPM3j1~=mhhKP3+4T~34HVArEHT1r! zYG7)rW{4B0Y3Q9=)6gJT+o0A`+fekjmLbfyuHoq7I)<$u>KJ5A>KQ)g)-xE+t8X}e zq`u+w!+HjVuk{V5{?$J@!pp$a<<3y@VkX1yXa5*tT8bGvu773R(A2_|Q7Om#=E))E z4B2Omlt$QO`msBw~Bu(w=B zfop>-gT-sP1_e!p1G6#}9U9gsF|7KieBh&nYJ*XeT7%nJbp{S8%>%(1S_fEmXfyoa z&~4y|);l1)PQT$BqhUi|n32QI)y54WjHU-{!_6E**P1(2Fk2pIjkI!zU2lEhE{pAf z=aF^?qSx6oNH94v{10(z_^`~G;oNtZh6;DLhKp0(8+JePXb{))YB*8u-LP@LPs3JL zKZb3d{tPp_0~j1n2R2OP2yQ5F4rw@89omq&F^s|QNjO8ONMu8bV^l*@b~Jil6%E2Ul?>(IDjU?Rs~DtzRW-O4S2N6eR?Q$2 zQq!Gyu z(!qKL*<1AutKQT%aQ&=ju=-!$bB~2V%UhCRagG_oGu0@DHJQx}&3zjgoF$$xFs+kf zv||Znbb2s}@d4izMvXKHrk4HjOcuXZGJW{*jp@PyH|B<$Gnf;4-ZCpJb75H_G>_%S z!JjM*i^5qImTqUAuv?OC!S!0U3$GuuIlT2|k2t@T-JxBPLxHoO3@*~B9dZNST*y`EPfMxSrO^9_6#jv4a@eA>>R zkYp>MAaq3F!B20&2SQf`7lg$NF&ua$*yx;|kNW$#NA`a2Yq7M|eh(37fD)wN_ z4Y7vQ9B~CcMu`Orr%5Pj9cJR+H}I7Uig^;f9}js4OOl(b|XbRLya*pMjeFzKJ{ z0?j#c2a2rZ8PadcJ1|!&I5 z#?0YtxH-c;CX0smYb_f7MOZShu~;!Mt+zVxHqzSR7>kWV`+A!OohVy|%`A2fBJ1rO z{37ieVwoKnY}Pt7JP&hhh-PqNn6lETp*P5x!TGl{!=}Y94cEL~8P(h`Z=-ZII#kb*Em>z81L!xKXo-spxhd7@o5hH`t~XH+UW`X5dsVVW_GvVVHfZq#@I!wBbolDFf$| z(uQl6Wer|^Wev#>%NP`l%NgpL%NwdMl{1JdR5bYKR4}M)uV9$OP{}aEqq4!Izmg&S zN+pA?L{&p;R8>RX>?($rx2hUGNK`kpg;qB#pHSTpa;lo4o2iDu%d&=HLS9Wn%%U2G z^;c>dT3Kru9+=cN>`AI+km|2(__4FLA?$H2g9&#XL%(4iLq=F#!=B2zhThqA4L5h! zF)X}Q*YNOr9m8zl`i8T*^$itn^$fFP>l;jp>lxhI>lx0@tZz8Es=mQyS3QI3iTZ}7 zEAvw&F)4%$LbN}lXFJoc=)k!J~WEqYN8G`GkzLg0K zs`@qHI_mMdoeYzbZiDNpDpeK616c`l>Qj}zd!t3yv6AekL!d&Sbdl!gs-9HXo?&WZ3S> z&v0cSzd+M3{ssGk1spop3V`ZThkZ$c2bA}L>(mEzWkL=4m%(+b!}&g81*^B*9o!ulEG*?T4>S6}5 zGARY=JK#Fm!E&Ya1AhS-P~Ci>>App99VE$JZ8YlG{46AhgMEi-gL zZ2*U^O5FylSCF>A$J2Ta-)!{3Z2}K@1BR&+3_xuIhMZzUhObY+Z3G6(6Gjc6ER8{J zg#$gZCJx#CCZINhgIlrb0lTN*w!;CZlV%QH*5;r#1Vf^{MMLgH3vgSaq15s~>vM3M z;z0drD~BRmYf#(5!A{Y}L1eNGsEyGutIXEH^98uA(NK2U?!YG-dr+IBVS~Iw!}|#i z;I@Zmv15bc6L1@Z;m}d1h72=jP+O!SO5CMkNxKWEO~P}aNEh*G`>N1N<6p?bvYn` zp>JIRxGi-)Be5aqD5Om#Tbsm?d;`+9TG^Z2u>3i=jl~c-E2V++Go-C0u{f2X_!qd% z#c+Ok8pFB2khWLWiu4ASzu-0)!=)t|3`{@3Z83&Vb21q=zRLu)$r`pz$YS{W0Ngff z;BLrnxO5KEM!TJr!yvl@+*V@{4a{XYH3!^gV_0mI$8fAB58QSu<+GrfWFfQP_}r2Hdt|_#9Zo@Mto)jmN+vR@~qkRt#$EH85N) zW@r#D0k!!U4)v8ZG@UL1wfz_zol6;P>%eWmhP+Ru4GXo)Ky5(=n>l3+i!OuPgbi~X z${7sHz-_~Z=KJLh4#E|nHe$oWii(CKtH5nVhBZ8u4eMteW#wvycJFFXo3bHpRyD(=1K_r0!x8S924{mBa2wO7yoTZG zOmJJX;q9H8hMK?NHYdY;o7x7WXh_>La#}6JyG^y=HmKOE+J==Zb>Oz>IrF-PxBy6- zw5qPzG2o^NE`Rm@A`(D zf5B~ChFAaVS1rwFym82nWk!H5`+`qgTn!%2c^JMP8BGL?9 z4`m&CRw*<@mtI^h%@Q^#bjNkU%|#qrVLpp3OIQh_f|wxOv&4fg#!2q2ZNn z151_zgUv&yhRgo04K-Wc8=eVzH5^ItVK}wcuVK}jfCd@G;D#Gsp$t;(-6 zlM5RrZ7gD#{h^p)lR_!OddD(`yx?+%Gocj?%RDL>?rB#wg#E8#_;RS4VP07cgRN9; z!>+Zp4XlQB3_MHf7!I)2HwZ`8H~g7Z&rp1(zMZ z8P+izVz|ceis2uFAfpPSIinY23}YT+1LGvd#f)1Rk1<|je9riTk%LKsNrTCP$%84J zDUGR=sfB4W(;}vgO#7M6GTml+$@HCxm06fsfmxT?n%RRnlsSnxpSha3gLw+`Lguy1 zJDHC%Uu3?^{F3<#XgZUDVbZJI2XD{IX3SW~{w4c0qa}AW!}B9@3_+XO8Q#8QWVlkx zz|gD6z>o}@xq{4NK}eQxu5h6R(%)5$42?iLkwKyk3^oiF3?>W)3_1)N3@Qu?3^EK7 z3?d8y3_J`RpuKGj4x6NN8CNrSGN>_#GVn5RGO#nSF|abQFfcPPF@UGb9Mbfi*a8?$ z8Mqm^7&sX?u&6jL{hVJ@Uk#jAx<`OLU?bDU-K zVO3x;V{Tyj#MlB>!DaMAEmCfgc!p3IpBDEfj$>@@tTHUd%ymp38Joc>J{mq%^OBn` z9xvq2r^>yK<1m{Gs}ze7b1l;cM$lQh3=U5WZ>u@WO%#t7^5IkFUdwR^L&ZJAYijm# zec};9o_q@2t2p+vIkJkg=rdO{y<=F1hC5*s7(Rqe0Ew}l zxYNp_b7c{8g3(cCh2=9?6qZY{q;zC6Ys9oOGca6WK5?g&xg&Whv&7UT%nV9@nPm>F zW`4l5lbOf=II}db07LVENeo|h&SFwH>C2Llrp8+K;19zV(O{+>4zHLCo^!LdoxH*r z(YAxBBUu#W4%QB_My4YQ8q5;K`790guB;Obzca2%_`bN z+?p9LZ1!Y&^ZEx&Uoi~B%_Q4Ka`%fu0Hz}ynJky*~7pYejr14fJVBVaRZ3Z60DI(MD1 z?)M}{gWc>*C+@T|t&u5WlF=7sG6~IK3Rr)JslnqvlSJSwrax~lGrcKRW$y8M#V|!; z4r9)&enyoi&P+W!e=`OAS-?0cCXI2*%3q8rs}?XB{EuW>lfc3><8C(7pVRM{B-FT> zk0`8QI#BzSso`cU^QC-$#&zx=8Q<})W6WT%XZjKRn5n>a7o(h57UQ~Yj~FvtDwz^O zoS2M4UoeW;yD@RZpJ0-yc?fnNOV~LkQ25>ua$;Qj%Ynh^{5D2V8c;ZSmSs=LY{myn zmQ0|uutRPu3n-j9y2_a)0;^aGY_nK3tb$l1^i#pp#Ol%7u9 zVP&54OqB`b?mwr)m_X*tD*wW0kv@m9XXkIm8H#yKOD1J81@y8rrF{2cy7O}#lS$|c zCI{0xCQ$r5S<1|;H{k(;QRof^w<%_f5w-i6&Ybze+>z|c_-|7&V@u#hu-#{3FEbqw z-^R43q?kE_(~;%G9aa{Qn>PHiVfk_T8jFJb7p5(dPZ{d6Y#6W1@&l(aH`P+cFoPn- zjH~WUd!`96TcpondQeydjt@|Jc=Nh~d4sA8a|XkHW`=xEmJ{CQOg4M1m=4tb1-rZ9 z=3OS6NzzOu*AFp*($#_5Ql>S(rZ8=Z)MZ+-C7tPu#ujk;SaEDJ(~GHxKyl8z@Y))N z8}V$6H5Z&21-NCwX**-$T*g~#x)@6)Yk<=xC_Tw6&tO`zB6fh?i%sN$g?< zh3`C@J&eB=xHGDF1vBor7{Qdo>BwxOlfwAN%7f9tRE%lCwKq&PX4y;y@$yU`S{E`g z985kJY|43|Rys_8= zbWR?aU(k4mG2w7D(}R8I7&Z7`GjgnPVLJ0}CD^Pr=X04DTsAR*;B+0O_nV?lZ9Npls=Q6GNwFexJZ1b`iViY79k9lur1eNWe@?cBk zQbtfYYa!*qbYR6DrYFs1Of^eQz~!HSt`KvLEC;we%(yDfY*UcN+|{Q8s!Jhp86VDc zC4W6UZbf7xnIgU}WZJMTiHV~zmFdTmnM@jWSC}H&4uIX$!h4_TNunTg@2Ic<^sxC|yHs54glhDEpiVsko%Ai!s z3@Te|WI34XvQ)rzw8al2ri!Y!Omh}>GxBWBW9-QhXX03MgsJ6Z4O2v$1=9njolI+f z*)W6Z8&F(<%mTGdK;_syl`zH|ixU_ddJMt!h{wZ8j9+f2Gcx${FuB~=z%*rL6%&t& z0h55)8gRXqVC2dyQT(3ihL97pPvkP@eFl|`pn4aS_CaP}$=3(9dzfTu5}8gM289Qx zuIFR6nKYZJg?Bqsjs0D4c?fD#fa;kmv)Gv5=({s4SY6AQF)^3%Osq5024->Q3oZ?e z?|A(f&q@Ad1nJXB4P^Qw!OWDST?S6uf266L9RE*i6yqDQ)?gqvM>8ly-UUY)% zY;e85ehQ=9$xv|l2eO~X-<@g7w|9&OR>UyX$bMh~mm6xcnbydBVglv4Thc9zE;5Ii zWls7sgTiZuVjlAamjq^xpD&nFBp)$pEZ}68(NAUmWA%e6U_B2rsO_`j*ko{92o$y; zeOqsvhxWesJye-BEfn~dJkj6_68n1WS(MDQCP9Qr;CK-@J*TWvV0v`? z062~9aL8g}P^x8;m@2}=qV3NFY6D!D_=M@h$zmp*D~mvF943b)+Zl3YG8x2vM>B%T z2~ZvUOtzo#jKFioA8h>0p!NvEW@Y9x?=<1%PD7v}xGfH9XMxInP?`!qpUH43KOU6F zm_colI@tuqE3?iq_IO2s@+XVPZ)@fgGrXBW<g%2p)SQjs1 z*u$E{2r4IUJZED0v>|{o%%F?W;Qvl0P@Dcp$|5ESwb|fy5U6YfwPQei0gp&E7La*6 zojP`w3eb8-H>!I1DY0NkE!_`Qo+Cd!9#(Ux>ZkD^8A%-}YRtra*9 zWR}lhZnzoC+>tB_ZU=$-BL`|(nGUDyV(|N{22R_cy337u0b|qD#f*DOioxx1P(K5d zf6v4QGi%gcVFtB*w!G?Q28A7{4`Y$;!j!bojIp9Bm(k&4G83qs#Iz@u(JU^CaRakD z6DY5N`V%+K$uoi4=pa9|1R65;c->;kV6X@Gr9gTA!qqy)eFlY$CD)ypZk*$1e)Fh} zan0HYMo>GyhwT89Moc`Di=70ML3uAz#8*XTkpDpa2T)(;2U|aL&+P)nLg}Xr3SV>> zL#7EbZBRYJWOjBl;}L}gjG#8!g3cREJ%9HyNlcvrt{Xt%xo6r0W{|%?aSRHNOAPlI zSt_&{H!x3U)Hsv|u4CO)=Q4`@u4cS4OAOrB*^!hEZo`1`Feu+ks7W((bZut>#W|=i zaOO-2OnY`5WwPTs&NwBtgYm*d7A67RCZ;Ee6PechvH|BaiNIe> zHD<=3uw??ZBfxoDNrZ9FV;06Y2OJr%%xVMG|IBVv+!%it`Z2oLMS$9w%pyHaOb$&! zObiqMF@efFP`e0J=7IbIO1Gdkd4SwL#u>Zkf&G7g?+(+e;-ie9e&z#R2BtICZA_qY z4AiFswUt2qA5d8g>ND&q`OLII)rDC|gq^YLuO!2f6eXq&Q`UmY6}CIlJWLJ0g_uF* z5vaWdOVgn82GouP(I5RArUSK2L48Asz$)ey$FdoJ8ul@yoUvtuim@={domtso6ZRG52*hR@;|IR z0=I(#t3YbN{U1;}NFs0+^P`uhjBG+a;4<;RiWug$*O80~Pdym-uo{8G1(a_L2WKjzvxs*A|uC|BaEOvl*DgomK9Aq znM7nSg8T&@lK{mjs2#&l5zPWB%NCry1nPq_u!NN{g4#O^uH`V#SyauKp|k|lS7ic~ zgDGdGGJ*Qrp#1UY^fge~1MZ7~^6&+h1Qt-6V@abC!>y6N!`Jk-;kmGmlZ=Lt1H9N4}J`fYa<%w6(lzFPsn7bTUF4oVqzJ?4TWk3 zf9pDiy0i5w7V4Da7sNb-2SI=+NFL za^P@+#DdO3nTEVw3J&W`R1cWn)NI(XK(Ap*v+)6!DvJY0YHS&7nw=Q-w7N6I)c7#C z#|JW;R10eeIvvF@*)^V_yf2x-W`24@MPYV>^8Y-BMNUNxXUs|)eqJkYV3DtC2S17s5@H1TeZrt7ySPy3<{eDUM|T5h6B=|FmkXiQ*3A~QUQh4fftLk95!Ck z1%=rGhcFX{vZdyruxpSDwrhB_#t{^T4c$>54f|JmgTk`GPdBJRJT?>*rVMqx(G15r z<3M4{z~GR=@cC;RD2y8z_;MIJbMnAp?R%_`L(DD%mPY0lxxOe-doFgrwuvLr}uV-dI< z#v0J_oz*~R2HT927VImcZ?XqGtmJ5jl;TV{yo>XJY&4fZ#&50*3ubc%9Jl5vxOJN+ z;AS=NgG17M2Ge%)IRr)XGkp8S-_S5i;J^nw zFCqz-CW$WaH57ZW^t>3utz2=2m)sH#msUzNOmUYyp!ZZ#VL_ABf#>ql2`qc18@@)$ zH0=B)qYyAzcENUixdrb}%PD+MmuEQ3tl&^EUxDF)l_G=mHAM!+LM4X}+{yuiVXw7TL-A#;hNoHD z4Z=)12Y%1cIWSjW*Wt%e-3G20y@tyl^%{cO^&Q$|3>@+{8aQye89IdBGGqwNGdjS` zWXzB>)%ZZ3hKYmbZj*)yzNQX~@0&U#7MeAjWHN8KHQD^YWEG2sFIy}Q{C2TqSaHSj zz|Ul>1MfarIkY!gA2`5o<1lBg4TFTXZG+JcTZT6-b`H)L?GBj7+B+P7VbAcX*r8$j zKL-Y}PDch_VJC(;bDSCusyZ{&u5)fUYv$6hX`c&&wwr5%=~>r?OTlj7-9!80-5I!_ zx;H$_^l0#Z=fU7s{`)aZs`YP3{q4`NyCR@r;@1F%7lnZg``!jN2xSH_JbfJ0U=kPHz;Gj&!6PuF zf$LNVgS%5G!{42u4BCca4HuV(F}#-zXK0=r-q6Dl(ZF3B(eUp>L_elzyzvdUE8-hA zKaOws;+w!QcY8v^T7|?0<<3L~hL4F2P7z5AFZU%id{#+jNa{*vFn*uhkQ$uQ@M~KN z!w1RK2Dh42hCg>x83gUq8d~P3HH7|8V`zy>Z{XjX-tb*2gTcBYqv7V242DYvnGGsE znGF}7WiniK$YL;>mBsM>m*g;*{>*7`@XckIzaY0E z;BziRh-+TM%4vBFfzR_AJk0YMCbs1_XkN`{5L7N;a4#reIJ2jKVLnG;!~Wnx2Hkmu z49}kzHoP?`YOt#;Vz_glh~Wr(F~c|C;)bHh#S9iViW}TyN*LzFmoV5aDq&E4Qo<0T zTH0_jwUnW4X=y{plTwC@N@Wc331tjMbITe$Z?~&pI8@%S^H(`T zno$KqNM=Pt%lwLlZ&xZBR&rJ{%(bm-xL8oh;I_E3;n$VQhIg!04N7KJ4O3F98eFGT zHJBc%YDj)x#c*D_nxVqIx*@KpnxSbnoRKpPZwWi^$cr8PtWo<)VR4v1_s#=EcGiwKj52)iazsUC&T+rM@BIPCY~Q z<9dcOFY6nE-q$nmf2nU^{87&UTBFnPx4uE}HVL1BL5BegXUG=~ajyL4F1KnXeKY z2B5G2g$XEZKw$(5D^Qq$!wwXNps)mmDJX11zk%DP@0QNC5R^w6+zJZ7c}DYUe#3;e zdhQzL922k1ZVqX%2V?+|e{}14@2V4e$$|6vi1S*?uRm6kJDh5!Qb;cyFVb1Yb zhMSSG49%}&8fMnSG|2MCfXX^>ndiDYilNIh3S1VZq(nCS{Sd*xRT}{=E1M>VH@uS# zZ@92LtU=Q-tl`hj&<1y>P;eRR5g5Y2a3i?EI4&4m1`A~dHSB#G$nd-{kYU2tfQDTa z0Su|X{Tn9K`ZL)72bbjy>WqF3$&J1Z%8b4ZnGHS+=KsAJdTYHwbwI@mpx@WjL1VXxL#~F&fyAlC z49rZ%2ZHmA4usq?bYOQgY{=bcz|byZZ~#;%U;e0ffHOvq;rmftP@UZXs=I}lbR3>! zX*U#J)&kY-2M#aRJkY_d39j>lZ>b-Ma8zedTA|jkhEMIluM$-TzS}AXo;j#AbSzV5 z_`t2qpirpPAbCykz+EfFhWz;o2hK7pBz#YoZ+L%Nj$ymL+yTGIvIjtIk*|?52blLt zH$0P15F zI-sS({3oWLc~8$T<_$YjSvnqHU}500VZEWVoOOk_5Sv9>Et^Np3$}vZVD^HU``85* zXmWg5Foom7?Ef4A6S6oR>aKDIq&jd3xUS|(kQL)*c-O#Pu1r%P_3n`GMZ1EOzaM>!Ba70er!K6d{ z!Q_wP4UeKE6cmm~IQZyFE=Zdu>5%_lvLQ7?%E9xZl!KI&w8D)=(g{u6G76F z$TV=d$}UJ*D|=w2sN8{@wQ>nxp2|7=^p$sbu~nYopsa#JbE`sw-dlwOhe8w^?Dr@h zSfZ@N@Tp6QLH(0bgL9-ZgZlyH1BU7<2blU)8g_kAVTg!UZMc0<)xkwW&0$iXn#0jA zY6tE_sWaR>pzg3!O~awKN8^CXCyj>n;hGJydo>T_Drp^9(5}U>?TyxfHG$d;t=qI2 z?4@-WZq@5Fgg((Zu+c-;;oTbD1};Ip2DVZ?hDSH_8s^yOH<&KaZ&=H0aDX}8fWhLF z0fU#WVT0ua!v?m`h721*jU3E&7&*+8GCpv<#`wUed&UP|IG8l-T4dso&SHAtU8?DU zfa9hNy&7f?i#yF4CciRci1jva_`lkmp_<2{;e3w8f!}8=8W?mf9q#s6HcWhD$sp@v zb)bH=Rl`m$YloAW)(6&~uy)8%w{iH_YQvEB#D-z9ldZ$n1-1uf|FdNXkFh)OY^Pm= zr?@>sV~Kr3_eJ}LOg#q%scwgcxz8OMK07-$NH1_~5dGuW@G#top?n+#0Gq-5ZJ)xi^^q zc5gTt?9rgP#)Bb@#k0Xb#FLvKh>L(j4xhQJ>|47WXl8?uPkvUip{? z{;U`V#Vs)nAOFTMG`hz&oSP8aaO-9)!&0TV2A%AT|0`t-tBG;xfNW4jB=+nwz*qxElFmG7~gXNP9hEByyh6!<*48F57 z8}?t%WOyN*)o|25t0A&Gt6|}>EQa}v*$sg<*$g|&vKg*!$YxmjDw{z|C5Is?HmAXF zS`Neeb2$vo?70nI_PGqK<+%*S>v9>UJk4dukjZO!7nH}K(V52}yg!d&n? zruh7ZZIkmEWKQHW82`y<_^n^SP?}u8uwYsNL(Rzo297@k4X%2H4aNzD4HqXCHYgk} zY>@v_*l zhOfRA4Vgt14V}{}8bWtfG@Q9x!SIful3}-UWrML>B|}(7WrK28CBvN6l@0sPR5tXy zt!!Z7t71^st7`b{Th)-2TgA}bQ^gRrx~k#S$ts4I&#M?VvQ~rEO*Ys$R5vikRx=b; zRx@->t!D7vSk18YOm)MF=hY1@Of?LzWNI3InAJ3_52#__&#GwK8?4Y4b08)odSZK%Fj z+raj;w!z{@ZG#YZ9m5paI)=Uabqu|ZbquV*bqp#gbq%jd>KGzg>lkvU)-h-i>lxS|)Hh6fQr~dqMSa7HH}wr#ALli0orPY_u!D+W4bTuR`gVHo8ZL8^3fzmoC%`@yj z1IYuRybzXA$pFe5yOk?Jd8Og>-3kU!-szlH!2rrjUwkVVKzR$4$L8Dv=Q&W`WAM)@ zX8`5Ja=CJF-V8cl*5I_ftl@qgB=3Uq@L}dMaGn<40M6qL;?boH@&=_0puBH-v!uaw zZAk-5V+jMOYyg!Jp}&e7&Yl669Sx@nAZ1Cja4|#r6L1*=Dr-PxPQzK1q6WDyg$?qD z3mGm=1eZ+=u6l)_vI<;gfyypW8TMPhpuy-*euMOhd_PL-k6jYXi%G8F$*c?z9+W;zSL1pgFGDsObpD~+Z z;W2R8%y7&<3shD!?7yDb;4?e3p+7FOp+hmV!TbrhY;V|=kLvzI9R;eZRQ4t^94Su()nVYejC)x^!>srOhG!B94DT++Gi>gP zXE1e+Zz%m8#{jAeb+h9dmMFzFfa=I|6Ji+}++!I&{e{$_pt=-Pr)pk}W&qW(PWI8@ zIu}&;g6iN>fhY#$Basag%Oe>MX+<_{z6+_d?>a>=huaw z!-SkLh6vd(P~8t|1Ay8B4YKz_7j+ko0QCq;a~ZJwv;-VG{(-VJ)YAZ;R0+embaCj+Rh6w2b+ps~iI;Y6?p zxGhz*$ejVywhH{<#_(;L8$+h88^h|yt_*uRT^r`=yE6D*bzwMD<xSc*)(+dbtR3oCTRF)1STRg` zW7z;|i!$h1Hh|iu=W;9#RP$IcFsv~LwOt)RZP>+~W)3|XW(WL_n>M^nHEl>|F$J}G z8(uh=9Qb(8_`tOqmQw9u7=>`p}nGGC_ z7w9|8wb5^QbVKg|Td5wX?S0_w8eN8s9=Z)7Pjnh?)$2Hb+UTv@v>iZg_N{NU8s@ia zIpip5f!g#A>%%o2KyCb*9u0;aY8nmK52!obj#76x{6+1+#6C3#XAL!mTL)De!lG3h zc6?Dez|g0{V5qLb;Bi2i!6j1JLH!fBkI?|?Yk>M32SXGY^xrBpG`A{%`XmpYZuJE4gah}8bmG%H^`(5Gl>5cQec@Zuzn?=@Ty)Qp;uHOL3K5M z!X^j)4JOz4CalZm3y@*tb7-2zy8zS&)IG?233TDBLSLTo#_`HKjX1_1fxsFGSTK?sX4I(^@Qa2YcIL$R>ILE}m z5Xa5H@Q;OoVI3<2Lmd+X!#ySjhAc(~2GAYUUJMKj-V6*3+ZY%a{1_M*R2Uc-^cWZz zxEL51K$DgXkO@o%&>~}f1_lPuAyS|-z_u_jFwA3MV8{dA3CPI6aG!~R;XD%qLk$xH zLoE{n!+#bAhInoUhHIdiPLLr(7;`c3FmQwS3cz*?fX-(F?Fe84?Q&yBg3mc28Qppj12E=85v&NGBUgY zvHKVp{`E63{F}$X@Xwurp~jzq;h!=C!#|K-VFre891INaI2jnqSQr?pSQr?-u`n=L zF)=VyF+tLe9U}w7ECvP!A81+uEk;LAC)^B>gU6H@7#Q3b7#Kj8!P_u0Fvu`6FxW9M zFo1451f|6~76yiYoD2;AI2ahdb1*Rc7iM6%FUY{KN1cJ8&Yyvy%$FCe#q z{Lsh1@S=}_;lC{-!^=JfhW8-0JR`$fTSkWWwu}sS1St<;UIsxh6abSTwg3YN@-y%= z@G!zyGtPHfEAh!V5tCg(Xj!vrj7sxX~B*E z*MF(HIy+h%$hlq zF)b~PjRj<+j5z}%1E@4(0Fx|W9%%0zGXom~sDuY8LdA>>EDW3sJg9LT9)%pWsi5{Wz{Wh zikdW4)_q^+AA_={pAw1nHC2xaJ|-ClhS_MS_VAQ^zHw{S;j`=b=gRfBw9aqn;n7eH zvoQ|*nDnTirYf->T|LAt5)7bAQ$fB%E(tin?uEn$3j?Se=U@QU{h+(`z*6881lrPw zEGGeOGZ7~bQ3WDF;R~|~Vhaz0O3wrai=GJ#Aw3fqN_r+R%$zxs5rmD5jhR6-2><{8 zpV8RZnDKSs4#wu!flMI&pa1_kkTJ-728KzDD$LthJlJlsXL0`K>fw>$Tg`7JctR*t z%P*c-btSPTOQ%6v*UH`X1p3!|{U(;P?Di%GK zpRB@ccG!yB7dxDDRCTU$IqNFpp6Rj0^S771PowXCzu*4Gff+%wgHMKh4V4Xdib#oU zikcI>Ip%om^|;6JuM<8beoT6o{37LU>iM)i>B};@Gjp@NvXygwJQf6sDD}iwf-;k^i5DmKtdTpLQdEP#XBg+fy6*;P#OTS zL1G{_NDRaViGkQ4F%TOh#=-!C3=HgG$iTqO06L>poSB2XZEUAaJZi2wtGvGF&JqYCCy zKShoUUL@!yjFyP4Ejgt*@DHt;3+gR9H7BDw4J1~1NuVk`LnCj!F@?J(*GFUWCI99-k zcM5kUryWNO#};-Lwlf@a|D^qm_}}+`+5fix_5Wx8-~a!_|C|5s{=f16+W))%PyGM> z?KXEWn;N$q=LHsLRxXx!=EF>7%+<^r7*iR~F`W8$Kx93868Ah-WiAW$J?u}}|Fd3X zEoQsNx|~&>)suA-%k$i=b`#Z)$#99^6}iQ8hs%qnoYR*rij|KwnJtiII_u28Xa42> z@BBaG|MdTl{y+JD?*GmIAOC;)|LOnh|8M_4{{N5lBd-(Bc798a=j{L3Kd{)aYP0Y# zD>Ln3c=A{8uOg_4=D<)lA%KB_A%VfxF_+<6PI<$wi?yKhcge*JAx$+5(k7J+%LU6A zR*4rgs5uujWK7IuU|`5**wT~1P-mLf(Doy_LH0^w!?t7b4bRWTG9)leG~ z!SHuoSVOH~D1&@+FoPg-P{V`?0SvFS{2NLx`Zi2%_F>rK;N9TM;ni^erbolaE$$6M zGu;?&wz@Vvta52MTkhQ8TI0mVQZ+3gI$lc z!}sG>4Qn~991Q&|4}{FHaCq~~yy2XsxxGwHSmJYBn5o&}=Yzq~YM(s?orurQr~N zL7l;|Lfv7hqIyHq88wFU6>0|>)zl75ysGN(tyPs_xw$ICoL4FiXXmLj7>B4d9OqIw z(0E9>A-Y=G!Ov8=A^3w5L+To(12vgS2d1biIV^vscwpT!MTTYRiU-;?6%Y8mQE>RS zUcsTVM4{obr2+#3gTjJe$K)0E_sKhWhRZWdRgh1Z_eyR-;#N6^+YNFD*nH&{Jd~7U z$apT>Fm0>sgUl9Lh5Ny>4?Zc&CM^0Q)9~u3Ou~ujG6|MhG7GG1Wg1Qj$Rs>|B7LBB zr?kSlK52!h6zPO^E9nKsg3=8!FQgb44oE$ao*~7su0Sebi>DNWt}^H>Xq@SfA@g$` zgTd=s2CL^a4LQ%N8`iz9VtDbnl7WGtlHmb=1w)Z?Il}_0vWC#mQij^%5(bv3#SPbX z7BM_}SlA%KTgVV=UC^*HC!gWfg1iR48@UYZLb(h_{c;#A`?4ECE@U-uiDotU#AGt? zEz4+d{FL5s%ORcN?8LMN-lwSy6Rc7hJSU|v=)Fm9F!4xk2waxLP|cRquskD?;p~|N zhDSyT40mV6Gi+mtXGkfCW4L!WmO;ihwn21X48viA7zWv;(G1ek(GA-sMKQeKj%rxZ z7TNHTDUxA#18BG+f?;Pvc*6sx@P_=hu!aQgFoty#LmL7mLmAu_g*3G4gfMXL2xhqG z63lS?gfqw z%Of2dVuT$TR-AQc=;&}@_~YyVItid*@*ew!EtU2TiRShUGrrm}gm1B9m|JXjAl=x` zVcTch18rMu9j=$!GAuW@W%%;b=D?mkHVh06HV%87Z5TeV+c?ZRW6iL0qIH9JxHUt7 ztaZcD$5sbct+HbHS7_C+&(ezFHKP?n(<#e_rpcBLuVXA3cB@%3eEeW>pnJE4Lsy%{ ze^6%yR4qgCSs!C#C=*O++SqE%k_0osgt2j&+APVl@P=iY8iT?tNn>G{$Yt4jDK7D8 z!cGDZ5fM3CDK{}cp)kHUt~53VhFOv?#Uw>C1ZVI)=N9KoV{_2C$fmZ0o8jq4W`=7k zSs1*Nco_~y3NT1#3o~e}XJ(mnT$rIc|JMKIyJQ#w=f!GNjFyW^g<##;`J! zg(3e4sK=(j$iR>Q>aH>H{^w_4dCADI^cFwE4sjNSkI#h|0vp&E9;=EmocH8p;N2v_ zaIBVxVS+TMx5vN`kvtQ$cYxu6YPP_gyz>9Y{{R0U!7us$9*-=e;=|DY=DQCt-2UnO z|Fz;e276`(hWMBA3}Rsh49M7H-g{1sRXW+M|{J?9{Ev9TM@{aDqI{Q4w@ zT-!;|Rq7bR)DYOS!IatIz>5bBQVZ1^R;d{=B)b|i_~aQl>=V{Kkk$BnftZ)b0Wn>z z0|_gI0#*uftGHV+HuR(@KbtK2zhV0;g#+v5-#7@h$X{6hj4ML&80#(b?~El1um3t& z=NmJ8ay-m%{Iep%7n64;eSExZ%PC%jR$Sa4G($@^z-@6~^(fp#YrT7tpqQcb!3+p%;RLgfc@a++B zC_5y4;=kIYCPJm&5l7A`a&|FE*II+PZ-A$3p=lrf)Y2 zCjMm5TJ^%B@)S!$+I9ATj!)bIUNhJilo>u>z_sJ6f_*Rd1@E5U0(Av^3aY2yGCaBE z(J=YQBF-g87z`d>;AU91eQQIDi&BH{HJ*k`OXVNzStYu_>+Gikvya?x2;C{o^p@+Y5z&{0|3`+&(x+hRWS5IsNa!Z|Q#xYj1vF$dy$qc**sR zp<}*jf~eWo6gI8D3}JKL>|uYwG~uZV&w=o@2M#n&;7ho1S-^o|<@;OzrZO(L!Np~; zy_&P3(>@}gJoW3UEk_v-e3r65@PD-igC_g^1evKH7aS9kXvlqd{=l4;TMY9q9x+&| z$6V0M!4hz4$-e_1XWmiB6aDZd{KTIN2l{^~^e-2b;91A2@HO?}tJgmn8rHqnX2{oa zI&dJ&lA+J`WWtG8JPSf~Id9xhWpbEvK!l<6x#k{=kAE5FHvM9V%{_kLSA~hfw+jyr z?65e*pz_|TB6dHU!?ob=41Egf6)Xkp67Em`6~y%N7|gx)d&5ed4}blg7)u{`dcD02jkHv%mjWYW@2!)y2i2P|U($d-?bO+b#e9Kilx;f4dbI z!(y9n|BY4u|94o%&Je2n?SFUspZ{W8IT<=HF*0oU`2W9788d@U{=@%ys?Yx$dUG+@ zt!HD1Nnv4_8N$TSYRbUisPyN*eFrl`!EQ!|cEFfimy`1k)t`TzeH{TLYjB>ntfRQUM6DdXS&UAuq& z=al*LUpDX0f2nQ%|1%3SF$5VgF{qgS|3AHwfnoie|Ns9#`tm>b>Er(zeVh!Y)dCED zhglfzDY7xx>M${sY5o0wr<;*s{g&VVMJE0IpB4A-|8xc^2Hi|?2Hik0hQK*e3_?u8 z3=^Y786GUU#cSf9_s8M9noxpN+m92cUa&f3<_m9mI_J*>hr>)i=G!naY*;GXvhyyZ zPu`V(36U=u1K5k06>hRic-fgTm`uOTe1^sO&yo{S%w>UF{x{sKmwB-E%}*94+5b0A zCNMoXKJjmcs_tKbc4KY_uW*qfJy%8nrvu*@I;zQN3GdQb816GG zJ@~-MYhdT|jiF!TPijy9|06tS|8ALcbVJ^{m&m8hu=I@KF zY=#83$3Fue#4;t^+5cMN(!yU27pn9Rd=uuGGtrUh&Cgj37ao6Ld2uS8#en_bj{s%0 z?*jV%KYwv9XUzC!$^1ZzgSBBAm)U`kDxN0A*Nh4$9fcM!3;h(Cbms4aPw~7r()<3s zxhv0f;>!`Hgc-AhJ{(;Acm2lh{|f8oFi&8YW(m-q%xA&a_UDMu`M+uTnT#LIgSql{ zr7|WITFA&+3jGggd-Zq8BYUPNi*7MKFrM_gapOJ)hu;yBdrJQ?K9`=z5Ycqz$CUL) zm>KWnFjVa1XIpb+4KqXU3tbk|KW2&b}n&8q+3VD{vN z1MhCNHCtGjD>lvkEpuVgpW|0M7$%5Z{2yU##OQEVfI~stT|ndD?Y{@&E*r#1UioJr zH0xhNgdL;W;f)MkCHwy$m@mct;nIJOjK6RH9Prls-SGF2XhUa`hJecZ{~3ymECJ(Qy_5eOxUDWbr(c`#x}GjWyMNXHg76irJ0+a|clfoY$BH@mYz_6! zTpM~TzA-HA(Yny-!nViz(H{#roxgTZXD~9)*u>CKV9v>rbB=k!r&(Ox{pbHXuuK(f z@cyKvuxi5}iS}Qt8{Yi>(%^mkhrz*>{~nyZ{Dq~O=TF0%Q{o32!@oCtVtuBtH~$mE z(KV_LT0DGl4YmIj_D1oQupRqbDx3A+K~7cV#wyvrocaC#=R_+qJ%|tx4VvZ4c;+hq zzjscX89&9`XI#LrM?&Z0fqyqnm@+FJc=^v_{w}7N2S$Gs1T|!@bl>_LDsJ#UEoTKo zNT27Q6X&8CTaJ`5F>t%c6&%)Q+ThRdbJomA#+o$>f4(f*_HTwv`JX8p)-y8*-Bu`w z+Q3-gW%=uBRK)*`v*-WYRlobcC-(h+gTyWW0%{e0F-+g6V0_2nzXsFPA3sVL{LK?s z%b3x_|GR-%>hFY>TBa#`pE4-4U1K}Yb4y3TZo}^b%+4J5{;)BGyr^NGA^hbp2V*4z z!)ZYlg%)>~2cQ3Z`XF|=@(7Gi9OFBHCF9rH&}REuFbN5TJ$gQwYQZu|UQ zpl&58;I@Y8{qbA|1Kz{`?#$$5e3@+b-_C9!qk_q9@eh0V|BGBy%#ag$>2HJc3r3S| z;tZvBdl(8Pr7<>K^O7$(;l^a(d*f3k)6xGg6khyUBis7_OQ0LW{Nox74$6US40A51 z7_4>U*syrV_lXx7|0_4&VF>gy`OnhP#FW6C#9AS?m#N}N25ZB?Nm@&uU;E2Y|DR`v z$aLm_z3-h zRLjo)3ON6J%v`w_JX<1PaplJU4{v4vMkr1A>(Tm=<;UWM>@)TsVs6lSF7`&! ziJ4)}(>D{YP5gWyW`(Z9Jr%J7&v$74V2)#Eh!OC~SoQo@L-XFR6W%@NI`D*zF|g?$ z!v?YY>?^XI7!!Vce$#O6l!}E`Ig5c~{rA1aFBlj$bnpoT_HZf$?iE}h@qi=Y${r!b zvSgIJkBu{9Dea#;q^);hQ@QO9}_UbxYNSHkk!D*@boGR!{)31|NlSo^M6F>@BdvU|NqzNFfwp@GBP}r z{`p_=!T9s%pzs+M~=qh4ih?xHWf36=B!`_vQ46-Z!{a<49 z>;Hji;tYvfe*Ztj{{O$<-T(i2TmJqJlKt~v_9Y|3@;iV2Uo-gqU%mbR|NY+>7`CL{ z_+PU?m|@b_|NrIrSr`;${{6QSVq}n5$HXwX`~Uw-IlW=Q1!{(t@rc?O2BH+TzdyBIGVVd8T*wBcVv?Ur8(^45Ygj=C_-ICPj{ zO@BLMK=flCGfNu=7b6uWlf!I(-B|e;H@xKMD_SxC|0FBNe-cMGvAFcT{coqVjFCam zO~69xz~2jPhkvio)nmKLmi|BFt5c!J!LN$9{>IEzr=Iuza7k` z3?9DK{}NtYWLmKJs_+%lV5V@#9)@N0o&S%_fB5%7wg;niKsv*Nl1V?bTSOTiYzdOf zcvAc?dq>Cr3Ef(ZlDVP`bEdxi^Ci~nuR!A+&a_Uye<$W^{5~-At5QI?`QIl_PyaaF zoWj7fUgh79#?^m!w9WimFy#;P1mm-e3>yDgErQAz9XgHG6^`(+>{)l8$-`Co?-H%I zO!as6{SR5y!rV~P^yNvyw?9%cs{a%sfBsNdB>$D6(^HjU{(O#0YjXZi$Y$m}X%)k; zMn>xIga94>9lr|y_K2GP7t8y}xL~)6U^Kh?{|R3-|E*f|gRy1)4+e*PWpSM=xBi7C z7BjwdyTPz&H^aXLUylBAc+ep#5+cI%W`Z=c%`wrxlV1J)w}(-UAwVRN<-tjH(Jh%d zOfhHtnR4Wd7;mr#{bX!g`hNmT)Gw7y=l?SNFctpLyYP?4I_W=#>MI!bUl;hVR&{r!-O9(zxSM6&s=A5;{St;_P-W3wk$6~@BVtB zb@z9}WkFS+dkhQ)GyXGGAG-8ktn(-0u@1A(12HC#_tC!vpLYMxXnn+*DP7O-q2(USfj||5 z37x(?yG-^m3UF`b^NKS3cVSES_Xh2o61Uc>{&VD#W9T~7_CMj>WWgs__!#D;PGfvA zm+Q|Jj=ld5^ga?zShJpihvneEkTp@v9j#G+zn5?O?{KzSl*fYmuiuBW46Wsr3^iWo zn7*Ig`~OEv&ff+9CrE!kbBWz@a?^Zq*ASjpeQ^W>jPn<&Hg zw@>~D++WS}X`%?@4bjbv4J%6id}s7v_~5;s&)~qn|KB!D|F?g}TLuPZ#{Ue4Cz%e2 zG6~qlonU-ZX2vA4Igas(oHz4}bS;Jn_A~x4T!|LhV(G_FQ0l&0B%F`?tzeP&t6?j)9t$!YTeEZkn?OCpd)_tl0tTDffa$o#6tYrSL8x!`Q zOXxPE^{QD6H)hZH@lAU!KRh!S82?opF#HpiVdUmp|Np@}Awd(}jf^t{KL7aeN|c#Vg8zT!!y<+m z-4;xHnE(7WNDKO^aN1L7*~`!W_-=&KL2?8_x}GSaOJqcfDrVbABVEPxr6?mlo~&m$6{e?;9^<{wO%_ zl-RH~o?+RWE&ncPZDv0FHRJz_d(MpY_y05Wtrlc>;BLxTd2SlRzZz*qgMIqH9KyDX zJ1mV5mXpk8bXc7z{DaT@SA*aAuM2W6O3t`->0is`CdLWxC$TadunR2Es`Vth`7Z5S-`STx}!4ex6Pab|8_8)Vkwb# z_*)Qb$gt+aa^{A$HVUFLasPLieE-eSJCp5#tMm5{f2aI@!NdBaVO1AP!>zs2RR!A_ zQnp(Dbt>s#1hpmYkI673OghE9AY$F`B|&fgC^*#1U)UV<^~lR5e_mX<`kP^03S)zW z;-4Q&>wX)YIms$=U*PYL7iXCc7(ILY;yii`45g-SMRNogJ{fW`{IYoeU*YVB|Ay25{qGU@_P-$T&wrgbeundt z*cc@BSQ#pAe*OPmhk>Da^PB(DHJ|?H`h5AXxb5x#kPpB9cj*88->c5faPNTxLwM4^ z|I3W|8GZ-;`Okgg&;N^|q73ivaWJg@_WFMg%b))bFETJ(c=Y4HQrX}Cd)ovVvOY31 zbiHL@@XGo8|IryH29}+|42>?V3_{O7{@2#{|6i(}iJ?j5_kRP6fB)w$;bCZ#U}E^s z&dBg9;>Z7W%NQ9Jsy_JtE9=XD>AP?KXK#A^|9kbX{|mIf{_lDA`@h*jQ3loUU;ov; zco;Zu{`~)m_t$@?gnR$%yCJdjZ>oYKP%1iz5dH=J4y+WQtpzc@0 zf;oR3YThd@IK1`i4enOf2&;J32OHkX-k5s+x5~SZ3=cMSG2QTN`Q4Bkto~+?FQdc6 zcia=Qng4v?UjMlv?(F*m?30vO#2Wr?P(R2eV0!U)ockTdBex>{?As^y-+{ly?8Kx^ ztPOD%UlJC1a3{2szZ96%`enhIwD&Xk!dMyD52=69(q>J_a(S^}-oNkPUibYwarx&D zkA|q1*XgVad>Z_kuX(={eg8Bhk^*(%Lch*Ru_@WOb%U}zcRFL=3($^{;iv-c^0fud;8#%;LirDQ;7_h ze3T?4Q+_rmS}9C(IQ8$rt&=|vZ1hq-@UEIgp*D(h!?7Ti19?n}35WN+SNOZ_TSTib zlS9R_ZwDOi=_Kq?``U444(kl5g})x0(SQD7C(oybZY@m*Fd~MR5<*yU} zdCn^f(||v}QjY%Lpmyz>!`5G~Z#d3lUvV#(DITzL9xf&X0A347Lj{;-FQ%dG2NtNW%KMx8^EB`bg2BWe(Go*@28bM$vz7v~T@;U`c~!k6%jR} z>TVnFFj|!fFf4dv@!KMuh4ISv9;O+Zy1yD8-7#bc5@EC2Fy~)JW!&G0c-cQb61@Kw z++6q7!2ccFflw!nbu()i7gQa1r#I32pF&9H9}D$wzYips|NZdAnRP<$@~;OH&Gl>M zUSTNkx%N}wy5aA=hnyJpum&*}u-P*vyj#fgAzS6sgUt&B7=FZid0ag8TY@u}rR4U$ zKNiB187p?g{@-QzmoXvZu%N?<*WU_mHGlM}!?bd%0r{n*3us{5_VZu(PqbF_uGg!0AN64u# z>rUim=yW~v|IY6zf8PAL{m(-o?w8AwXG{!lekgps{+dC=YW<;Uk(%lG`-wD%gr z1UY-A1KiTTUpO}Ya4#r9x z=dn3-^y>r^Z2X(j$@llG=#&3Jmzw`g`4{*1TeLNU1oLXvE1#ShPJG(>Q{(q?W`-99 zdQ+BOW3b|`X1v0;pUI2k8bimsnZLKChy5#fzWeLFhycbJUiAzgV(x!uIU(@>K+9IM zg!z8L43CAr9%wtIutDkZ_kw_?Ukgk^9(>gOP}TqWUxP`7PQbcMu7>TFtc!RZ{xeMZ z&$NR7$)7WqEB`Zmz3BAd?nMrV_?+)0cQTn2D%9UBI4bnZfh*wCjI+tC2bjO;{Mc8> z%3!MZ_EVfGgU0-p@{BIO zBba}DTh8Ke<=f8&-h*Em{?@TEEUOE8(E5ePp<)YHK+U@k4I=7-hl~~faa^DCH{i7` z`-CWsFAK7Mzd7({zeTHZN5bL9&joei(mwUu{v_OCV?D4g zjcdWjGTDZ=3;yYMpZxC?clX~9md+mxY-@}vHeLDc(AmMQFhAfkLuJd02@^PeIXsWo zE?BjdGhx0F*MW?%?;3X7f31nw!}Ld%i;-d92K@$+uS_R2`hRKU&0$%v!TbG>867_s z)G+=sS>pAlfm23_rBIGZVdJz93Z9<7@4BpINaE4?cfnfpqlJ9<-#HTtb_y&7T>+pD-(QZ2qE9GX2|z zSE>9zo@cUJlvw@#F*p9#g#;g-4K^Iy2RMbf8K!(lyrZIAx?5<8w3fE7X_|GE^#pc< z+>j(&4NvvE<$D$0s&Q$(P;}K@W1GoVpCO&~LF>ERze;f#OT`D~7wl`S&f2kXv}ft% zWNSs4t#;m}>E+Px`q+JicctN6j(NqhMWQ-e3^ZaNNZD#Im~k1KTecck^GfB%6|B#~l0rzasVjfBT*P|BEX#Fr-}i|Nju^ z?)q#0|MS@X|DVRlz~JW0z%Z$SfdQm8?!%w|4=4Zs?=tECf1`c>|Fb{;|KCZRfq}`G zfkE`wzyI8>|Nl4M`~Tm>lYs$bE=aAd#h3qmXBinno&W#O%VA*1%K864L5Y#!P}uMP zPnZ1v&vulF!8Dzb0ptddxgfPtt$+ScSiry#;r;*r%}@r0hw=;z#gqU47d2vJc#+D$ zU@@D40pwng8$jlQ)F!q4`+sHu1H*$I|NqbCXJGI;_W%Ek7zTz{rVI?MZV z{~tABU;u?LD9k|N0P-8iy&yM$%mt}^Q1R-2vF!iSL16|82aw+! z#2FYsZUC7JQY$j|&;N)&|Nl47gTxysEFUSobb3tmIX8rwt&i?;@ zP#lBe4HOrk@CAh#C>%h31GyLE29UWRwUv^;|I2Fq|F7!w|9{q>|Nkpz|NlR!nt@@@ zr2qdpqZt_9Z~y;)-`9WtSAG2d|I&m1|7&{~7(i;ZRDb@LxcvXW>aqX-zZo(xIA8w% zzmAK6A>!lz|0Qew{jcr%|36ae|9?Xl1_qG1Ahm1)fBv6JXJX(KVqln+&A^bo{Qv(# z83u;r1%Li;cl!VTp9Ld>m;(a?$PFNKL28?x{`!CO7XyQi90SAGI0l9!e+Gsn)&Kqn za5FH}=rA&z>}Fs9xfkRHkhvhW(bd2Ir=DbD$ea5AzpX9<1LO7o|5=?F7@`j|FoXv} z{04F_$PFNKL25r;`2ByP4FkhZ0S1PGhyVX~m@zVhegFSo!H9tY6b>N2f!qsn1IS#E zTG2=U{LP z-!<{y|40c222l8d!VDA+Aisg!3vvUFUSobb3tmkEq?wl ze*O;}$Dnuv#RVvQL16|82aw-D?ghC4WG+bUn%RH;7q|cWumAtwe;d%gF8BZcO;<25 zC`bJNe@cUap=tB~|JEV@|I2Ou|6gYH|NnD$GcbVE2AX{SpHRWTz!(1i|0hWXhRS#U z|3BAeUJkXnr;zy3eeVrKaB_22(xZy6XgcK-W+ z#*%^I)ug}w8BG`%#P2gQJeT=oC|3OfddYJLU=P&k16268XR z4IpztYR$v{{C~vGz;I~K|Nj$y{QuAFz`*dI9};GuZ~*xYtKR?rf7X%h31GyLE29UWRwd;$1 z|IbroU^pzsz_9DrzyCizL&6snW}t8Y`3>Y=kQ+eeg4A|eeEzRc`2YW5cXkFXX-Hgv z!WR@~pl|^B4dh;s8$jlQ)V|yG`@ecI1H-jG1_n^Pf#L!bzMwDzg#*ZMVE6v|2R0X^ zHnrlz|1;PBf#VnyZ=kpUg)b<~K;Z!L8_2yNH-O9qsSW1&``@Sz`y`97o^t1{_p>qSVjh$P5=L& zIU+=>I|G)DX7?SiD7$!3^Fo4_(as$X*klJ15fB!2mFfm;E`2T-~Gy}uSEC2tC zhyDNmsf&SO!vcukK<)*(0c0*n?f%Ta|GCaGFf4uZ|33#m1B2iq1_thj|Nkd#hJ*vi zZy@)A+yF8cq&CU#-~XIH|NlqvLiSTS^D;18W`%?qC>%h31GyLE29UWRwX2u?`9J&3 z|Njp^{Qu8%`QQJ*-;nSHg&8OuKz;+c7vu(zxgfPB*MI+S;bve^xWL3P-yaeepzsBS z87Le;egnA|w5JnfE=cXOp1=R+Ui|;RTabYP6mOuo0EI6o%s}A)@*Bv#AUA-_1*!cT z`Q!g12}m4+;tdoRpzsBS87Le;egnA|<>6pZWX$|MBnt{|}R5U8Mr6@|F4k9z;I~d z|NqbU7#P$g85mxl{r`Uh7X!mOBL)VL8$jlQ)ZW|w_y3L{Muxzw|Nr&V7#Jj27#O4; z{r`X3iGhJvnStRu3&g!3H-O9qsg2(E_rHY_BZK_$|KRpXpBn?iHITaZ|NpmHLj3lN zoq+-529UWRwO@1p{%=0R$T02C|Nk>V^)C|xLzyuH!{sxOZ~*xYJ zzrdOQ|1WbfFyy}f|KI%W|NkCrkT3&<1ITY6_p);^fXxM|{dD2q|Ba3R|NnXO|G$wM z14F}8Nce)n3=|F^zk%Efas$X*kXnQH|NcMHVPNPCW?)#q7!ntt@CAh#C>%h3Tg(J; z1IS#E+WYJN{@3{S|9_GZ0|O}DKyd*IUr?B>e*gbJ$ZsI`g4_Ty7o@gd`2T;YkN^LJ z;usWfptt~qFDT4F;Q;a*$h{ypfXoG{^ zv9E)Qy!m09h4zI`<<2=QmnuVZwisvki|3Cik z|Nq=S{{Qd(^Z&od|Ns9}|Nj5~mWhGE>F59d790NmU;5|&|M{E@46FGW7(i-UTL1q) z`SbsOi7)^EZ}{>5|6djc2BnYx|FQ!FnECSm|5Mfs3|ZC;3?TP{+yF8cq_%JFzyEeq7#RNk`2T+^KLdkZ z+5i7@4Hy{0O&J(|J2NnV{04F_$PFNKL2BQx`}f~`3IjtbF9XBNm;e7Oh%qo+QeQ1VB%+BXoZFuC>%h31GyLE29UWR zwSf}<|L3ax`ya-}z;Nc?|NrU23=E*~1%(+X96){pxfkRHkhvhWJ9}6E|GAEd;puT^ z2D9ql;J5&VFDT4F;Q;a*$h{ypfXoG{&CK}szu@=(|95H`7(np`iVINqg2D_G4j{jQ z+zWC8$Xt-xxRd|>|MmU<9~{SzA#ni;Ur?BV!U5zrkb6OH0GSI?8*KdNf9;L`|5KS5 z7*4(W|3CNN|Npm{7#NzE85rUi85m4|{Qv*)&j0`6|NsC0@azBoi!2NbAhnhq|Nobt z|NnpK@BjaI{rLYsikpGK``iEj;YJJ$Wq1GozkA{T|A#^h4F9+x=7Q9|TKn(+&4UaK zjFU?_-UV7U1Q;s%hpAhl)x|NhUiVPp_xVPN3p zVPLo_&%iM8;{X4zKL7vkznX#Js09N9$h{ypfXoG{ozU~=|JB2c3^B?K3{Ri^|DV12 z|9`Iy|NmRcGB9iqhxiTTUXU9==7QAbZ~pyX-iL`H?bZMP{EQ3?t6%>A-^s?n@JkjF z4j{jQ+zWC8$Xt-xhwuOVpRnrx|E$~p|3BAYU?}?j|35bmB+NkJ0P-8iy&yM$%mt~n z_5Jrhxaa?W)hYk~Yis@guW=g^zMwDzg#*ZMAoqgY05TV(_Sv*=|0`4&8F-&CG5kC6 z4;&Yu@CAh#C>%h31GyLE29UWRwLvYv{&$}J|9@pM0|O}DKyd*IUr?BV!U5zrkb6OH z0GSI?+jacs|NVO*aSVz#P+Wk*7ZhfoZ~*xYjenticklKc#|Njp^{{Nrp z@Bja0-~Rs>;$UFd@a6x1YefbIT?Yn+#LJL0L@XZ!EJ!CD4}VqFG? zDl-NK?oa>!pNL>!D1G$r|GJBe45C7e41Pik3?Mgv%mu0aqxkp#4Le2#wnPSoyM_!5 z`&k(nj)ndI|8L>{|F!EF7_Rd|+zWC8$Xt-xGj+fJ|C`3h@ar4{L(u2{|MQOg{Xg%_ zzyG#v3=B+P|NjU14dh;s8$jlQ)PCLg>%aR{CWdM6{{Qdh|M&lH-@pHFmoqT9h(W>u zHpLh|Ne8j%P_;L}?{{J`5U|;~n8z{Yj!WR@~pl|^B4dh;s z8$jlQ)G|+h{oi`WKX4p_;tdoRpzsBS87Le;egnA|oGB7xCF)#?mGcfqEGcbVM3vvUq8h z2?vnhK<)*(0c0*n?OwTm|G7CB7z}nZFr>X;VECfJz+mVb_H|^K|vz`C{Yi;=dU+4=Yd_iFb3I~wiK<)**VK)NL$tJpTUwzvb)y|FcCI7(7`R7(g3f{aG0pwsA2qfYjPA`~P1LG&b?> z|Nqoy|NkFnU|=x+{{MfzJp%)iGy_BH^Z)13=BL6{{Jug z|Ns9{2?ho;P6h_qm;e9YVr5`B@azBo%^&{%2f5+!JBZqbzJLEM_!t>9KmPw8vhV-@ z8?XNV_rCJ~|J~33|MPG#F!+4>{~zRDkQ+eeg48;x{rms zt^fZcco`T}nIL`xxfkRHkhvhWdz1hD7yQh?uvvtGL79(%p_iS3!SLJv|A|Zt44`lT z`3>Y=kQ+eeg4Le*_kYjh|NsBr{QrOHm;e7?b1^Vjg3jp?Wnch>1ITY6_k!F2G8d$_ z+vxxQLka)?Z+-p$|7LCmhH2W6@CAh#C>%h31GyLE29UWRwI!YZ{>ynVFo4Y8y#4=w zP+Wk*7ZhfoZ~*xYh=Bqf0>(sp~RVi0TgebxB!JOD9k|N0P-8yJZ^}& zAhk_b|Njqp`u{&DjzRGTiVINqg2D_G4j{jQ+zWC8$Xt+G8|VN3xo-deKa-n*;o$H8 z|7(8y|KG*Rz_94w|NlLV3=C&J|NqZa_W%DXCI*HLJPZss#26SrYE}CF|DW~s|NjI| z1_s_Q|Nmd%VqoxRW?Hq(pOaK4>^zi?GkhvhW$728f4|8W^P~~D^ z_|m|@z|GIVkZZue;OD@|(0=&e|Le944BcG}3?Mgv%mt~P{OHgB%Z!W+1>6h_Ic^LL zMV1T9@h`fSan1OJ`2?#)D$z#2&AwXf zu}LzJV(G74loxHl?EcchUp~<|$E?ocp|yt|Cre_@x4eD&=WK7g&gYpX|6lE_nxJlj z-Y@3d;=t^5?Z2jP?c|i0_0>(3O*dH0HR@(LT^XDgsV8c7)5cKqiuq6L6}HrZK?noG z2W18ZNm~Ynj%$!`0Qn8%UXU9==7QAv&-?rT$FUSobb3tnP_5S|%`2PPtD2_q#28s(%_=3U=6b>N2f!qsn1IS#E z+IxNf{@-8x|Nq}#|NpPyU|`rL#=vm%_y7Mnum1nvAk4s!@$dit0}ucIU&6r1u;$JG z|3_IE7(i+l75w|p?7_ewvh)A{9nb&&zu?5cu<6JD|C~t-43ldZ89voAFg(5R@4x0d zh`AuOkHUWc4^?7fu#RJ32yS3txa9l)|D%lz3>{Ax8A@ibFtjiK|6h|2;s%hpAhpf$ z-~ab-W@cd7&cGmdjDca*w*UWiCjI^YRE>$jJf4w3Lk;3ykQ+eeg4BM!@cF;^D`tlI z(-;}%t1vKJ-umyq!I7W;=hQPY^b0aDfcyq>FUSobb3tm~NqqjFc9ex-)06-IosKXt z#BcrnzdG{&|6~RR22ePF{04F_$PFNKL28|^eEIKb!NBm+g^}UF&A%h31GyLE29UWRwQNz`|4-Nc{olOs|9?=t zf#L!bzMwDzg#*ZMAoqgY05TV(mhtk<|BNk*kL2dw<3sQSx)0h8;wzDu4ZTbH{!}9-sk8^+j zw`VgjJP}}E0EGj{Zy@)A+yF8cq;{{}kN>k085peem>Jq?|NJ*_{{P?i*8l&YFaw1H z$ZsI`g4_Ty7o_%A`LF-t%1jK=2LJx&efspnM|NqsPf#H%U1A_oN14H=h|Nn0=GBBK$VPL3T^Z$R!xBve` zm>3v9YW;lv|9_+O|NlE>1_tK8|NpNtV_>KkVPJ6OVql0m_W%E`)&KwVh%qp{(pZ|}f7#W;w|NIxJXJGIZ`}_at-GBd+UotSrYcMc?-0)7BfdQoU z&$RFVV83RL@79#^& zI159qJp;qp21q!7{04F_$PFNKL24^izy4nt&A?FM&B&mZ$;80V$-v+Px>bh}5)L50 zf!qsn1IS#E+K^Sh{y)9<@Bhh#|Ng()_5c3?SxEST!VDA+Aisg!3vvUd7W^8WXKP+Wk*7ZhfoZ~*xY(6zk@d|Nq*l|Nk%LU|Nv%|CRj=3=?)TFvyrOFo669axcgYAag-#4HAC+7Y=1&h%skiP+r8y@M#SL!{kN( z|Et}FgagQLAoqgY05TV(cFFeN|KHvJ|Nq_`1_sx71_nqN zx63i``uqXM1t@$$VFn5Zkl#S=1-SuaE=X;D*xUbqHvajaxD*m^ptt~qFDT4F;Q;a* z$h{ypfXoG{oh9|=|H1kH{@>$ZU;xD%C@w(Z3kow(IDq^HaxcgYAag-#zxn_A|8c?p z|NH;_|DX5k|Nk$n3=GTJ85s7w|NlQlnt@@<=l}nGAO8QpUWI|7l81p|5(fhVNbR>d z|Nc+8^Z$SG)c^mti!d;((qdo$t$+9s&cI;k%)qcuh=IY!1hW1BWG+Z;xWnK7&wLpf zn3ggyR9P}GOga1i|I}6nhIMR=4Ad1t@$$VFn5Zkl#S= z1-SuaE=cYDrH}rLSpEACieu0^3{YHv!WR@~pl|^B4dh;s8$jlQ)Fx#8`~S3vfnnzo z1_pz<3=EvJ7#QTHFfjb-1)VC$2tS3E6?!Hq7X#=_Qa%RI`NP5tq732;k_<8oatw+L z$_#1@nhd%O1`H+)77R8Fjts60UJL;YVGJ=0Ner0`1>ln@nHWH4bb?MR1hGIgGXn&I z&MX9-XvxX|fuM75K_?h;FmQlRtL9_?ol^}urI?oibV9KJLqqdZ--a3~qXw3%nhn3T z!WM`g6l{29mp5TEJ4=Jlk7|ZnVf8#gGnrnhu4G_XmsWe=-3uNDLGj{-sutOX*6O4K zMkkCJ&YJr)h-vsAczNA`p-DS`!SPJt2enrO8Z4&eFjTi&GqhH?F!-3HJNRgdF>E<4 z(XjbiW<#60M?>WebA}t=Y8?Kgn8;{wGBdEu_HH=rlIM__tCe80TaaP;q)-NyT^R@X zI5iLab`@v%_${pAzjZdlM>G8dh9e>j{3in%LLZbgY*(-msC&ecuu7i0!Q;L&Lz8SZ z!#+X(1w3=49Gu=6G<;4@Wr!(AXSiNxT5)U#i^7tA2?otZuLeu^>V{H*PzI?=wF6!6 zwHThYMK&CIR>9!l=i?x`RAGUwBs;@_jm8bnqT(AWAC@*K|MEVN_DpF)n;cie9aa;D znUb*$!t<&c3MGRb%mQ_G)Y-8myh&tj=zFHqaB^L6L*v0phGVx98t%*6EcnPSp0}W#}Lky)}YAhcYxE)>_GKtxf|~%v$Jhl!T4asSIGnSei<@++v(ZR zVv@)pkW<0%W^Mrk(~C%k3kA*%|IKt0Tr9;+V#^o>M3VR!{)wv{(C@ctU^p4nu=`jB z!{W}m2BEjv3}$n}7?w0SI@r(GQTX~n{LjuZ=7zUIA_q<;YdXZ#+BFbQgfv95Iy2lvx-g!>cV9unI*+=BQ$@KAW&2|o)bxA~`0cZ1$j;Yh_~9TOP-?{O7Py@;!L(P% zq0>Rx;nqdthK-Ic3{xkBFmUWoY3Mpz!jR@%-QZuG-LUImG=q_zkAuq&8;8bt-2>Ii zau-f8^Dn5MDf1vYN9I7Zkc_f07C>en>po~{aPSv z{e$7N_&0%UmM<61Fn@Azl>D&Zocp^4!IRz`X!`w%;a=-Yh0Vq<9*DC)U+|3a*@NAx zPak|Le&Vp??PG-{lOHEEq&;rv?~qxr>5BA&v_h!`+36Aqvk!|h%$g=NA?FKU!mrO< z61D5t7Cf|LN{~DF_eE3S&jqYJUkfI4e`H9@e7hjU=2gO!8P64F_B~DT)qc`YQ2rQ% zL2R(tlo`)KYCvj1dO&(XW`N8BnF%r*WCzGDkewjAL2dxMWz!XDklR3E2MRM#Sb@R_ z6gHqR0fhx93_yMd`5EL_kRL&Q1NjT&PmsSs;Q$I3P&k3Y4HS-`a0P`kDBMBu0E!n- zJb~f}6gQwa0ma3KDZjZvVGjy(P*{V)7!C6cmOEA6#S{IvXStgl$D8l>Fm) zVP3@|aiaBiK{w;)1#b?$K2TQw>;eDo#~=)1gTz2`AT=PhAUz-5(CMB z)PU52^nmn&%mA4M!XP$C3?v6q15yjp1JVmJ17sG+PoS^^`4{9DP?&+j1LOx#Sb;E@ z?I`&HBnMIhQVZ4-Ed)-tVD`Re{2)1y8fxkXr9Du*gVF&gU4YUFC{2OV5hx9T(hexi zfYJ&mjeybyC|!Wk2`Jrw(h(?KfzlZ$-GMNO4HkQ7#{^cBoh|{=1JVmJ17sG+Opw_i zJ3w}U>;&5_cknOREwc}cg4_m58=!Ot@;fLEfzlZ$-oa_jQSt*QZGh4wC>?>)5Gbrb z=?0Y6KvwbTA-D4x|QzL2Qs1NRCeG zKz;;;56I1+umkxI6c(WH0r?FazLNhWL16|8A5a*8!#8-+8&KGS!v|D$zW5;l@;fLF zK=~RJrl9Zzg%K!zK;Z)ldr0k^^B78zcsj17Q#wBnFZLVGtW629g6|5E~>0k^^B78zcsj z17Q#wBnFZLVGtW629}fjCkgTs$RD6^0fimN&mez*(hw+Y!C?X_+r`Kx#m0L3%)XL1uu= z0$~svBnFZLsR5}4=>h2lnE^5jgh6bO7)TDJ2Ba3G2c#Ed2FNUse?Z{{3InivPcHfc z3OkS=LH-4WCn#({{sDy-C`>_q2ZaYHyg^|G_HX@68Bkb*!UPmvp!fiVB`7>V;SGud zP*{P(^U)D@P#A;43ltxqbOs7TPM94ZkT_eHpk4^Z3e+e%`eKY3^^<8WY`wy~w5sqa(a6f_R zSLZs$2l)n!e_gIKd@!HEP`4kJI$GZ+{aWiv2H`!FzEG-Y7mRbyayA;rMJCd|N4!pp#* z#-he##VEum$SA-#hryr0l|hX`h(Ut^bl(H0mjyblpPNCHL6bp&L7Bmsp_PGyQHaT! zQJu+;W1hf#f%lg0EWgQA@dYx?XFkWM$@q++gu#eGg@KoWgMpO+bR`25_&yhY24MyX z1`7sj24jXIhEfJ^hN%nzOg8MGJ0?Ikynrz1t_jGEFl^8pVL<&bkP9I91%Ucmpgtbx zHX$BxKZ~D%4}7x>=#C(SZgvKken{^PWCE!7#>N1Gpne+&b1;C+0u`SS{Ga(h<9~*F z273m127U&12GD&Mp!4oo8Mqn58T1+A8TK>OGyZ4#4?as4qKAP&iouE@ilK@@n!%bO znxUG3he3uxhrxyc~?46+RB48{x&4E_uW3`GoW46_+FGMr*~%+0Y>8}(*q*SdvuCrf zXaB-(#nH%dl0%R)igO9)drnKPR<4U&a@^V6JGj|+LUx~!d9|Qa=+w1Nn5EZsqIpqq;#ayq~}RrmFAMMmno82B6C%S zRn}NGLAG0Vo9umAHaQ)+K)DjRX>!};uE~9trey99#`OEV6 zXiR`X;4IH-uGL%&j7-doOw0^S%nXdo42(>;_@K1qA#qlvUAxF2 z)8vHtZmW3PWA?us*<9Yc?sm`f4S zvEO4K#hr*>nb4XTn`D^Gm~u8{YHDPfbo$No$r;|63|X79lCt@8cIG7JvgfVN^T~gm z-%+4axVJE*=v7f&u|Ubf68+M>rJiM%%VNqOmuFVIt0=7eTv<}}rK+gEg^P0rk zTeX38C+h6#H`o8K2jwzQ4h5ak+)&R^x4gQdVt$E5K|wYHD4+xwBp4JJG#CsREEpUZ zJQxBPSQt1Mco+m2L>MF(WEd0}R2VcEbl`(C4h${~9t=JV0SqAw5uk;MOa1=WZ}g9K zYqwwM@W?^eS=^)9f!l3enXdDWT&FPcfG{_8FLni8=T66F2OHbD4z(9PgRgP=u>9Cx zw{4$)OY7hL(Ru0KCzC~6-h#rG^XG#9yF7Um%5@cG>u=hE#aP1lc+Z|W^XF;e!e5tt zlYZ#^SNsT43&SAw#z!{F!1$nZxIuTYG(|NX%fi6PAiyBWpu%9t;J^^bkit;OFo9tu!x4suAZdoPXMF4!1VE>7Gq^J_ zG}tpRY;j^>FmYyJ*aE_b7#K_rpO9o=n54wOkY&igu*#f);gu}|gO@u4LzgcD16LFS zgH|j9!!3}Fny3}Ou83=Rz8 z3_=Vd45AEz47>~x4B8Bl42}%>415d{43Z2|4AKlT4EziN3_1)^3{DIM44_ds(0wz` z422A`3~~(e3%NM)#DFkA&+4K!+HiEhHQpjhBXXE48;t_;Bm-6h7yKJ44`pL9tJ^hIDpa$FSs_5 zU=U{zV~}FtVBlvkVJKygX9!}L%)rT@$iU4I%rJ$)l%b44hC!MkgkdU!5`!{>EQ20{ z0{EVkat2if6$W(%H3kiaP=;yXn9yd>VbEnT2ak)oF@!NhGbAviGE^|sGBh!?GfZcg z!?2KH8G{8wI721F31ShB$@>hWQLG49N_w3`-b188R5U7*;Y^ zGej}eFwACfV2EdEWLUu9%8 zFr8rr!%T)*3~>w-7>+W0XGmt4%5aL|4?_aOB!=S*KN%7kCNrF1_{EUIaGD{BVG6@Z zhTjbF3=AhBSt=&~Q&@ILBbdFc%!|84Tx9!rh!< z9#XhxGF(6kcMFCrhWQK^87vu`7`(x`sDz=Gp^aey!%But47(XFG2CW&!tj>CiXn$# zA;V<`JB9*=r3}{@oEb_PRx#XRaA&AwSjX^y!H1!aVKc*1h5&{phV2Y58A2J_8TK%| zV~AwvW;np`iNTs7mthgZ6$X2TLWX4wHyB(P${1EN+-2}!sA5>p@Q}fmp`Kw2!!w3J zhGvEx46hi%7&;jCGQ4MqV(4Kw$ncrLh9Qq(F~d~`2Zkbs-@MNfF z*ue0J!H=PVVJpLPh9HI(hMf$r8NwMl8TK)JV2EbuWjMs}g~65~pJ55ZH3mn9VulqA zw;0?QDj3!>+-LA&sA1U1@R-4$p^;%5!wZIBhE|4M3~v}B7`hntGkj!-Vd!Hx%YtWem$1Rxqq&SjCXWuz=w%gE(V0!%~Jv3^I%v42u}Gmo4m12^2xjPIIK{xi7{f4);W7g+V+cbZ!)XRq##n~w3|AQV z7(*HQ8O|`UF~%{>V7SV_<uqf#ECzJ7YYo*@FwA1O&LGHW#Zbbqk>NFi6GIKdPKM76?hK6# z`xt&O_%n1e9AjW$j9{3=aGrsaF_B?5!wm)@Mr(#rhD{7_7@Qeu8Fn#zVenvRV%X2{ zlOceii{Ur}BV#1PWQGe2T#QK!a~N(i2s7F+lrd~(c+23zP{**F;VXkDLo>qxhF=VU z4BZST7?>EN7^W~>WZ-5@W|+%xi$R3ZmZ6+s3&T4GSB83qJq+I%yck*-4l?{^2x91A zILW}w7|k%1;SvK6V+zAOhT9CHpsolw4S~v!T!!@wUl`0V($6-A?F>5@b~5Z@$Ya>R z@Rh-wv6x{i!!HIK#sY>-4Br_n84DRUGyGt%Vk}|!%}~U!h2bZIHDf-*Muu+;7SQxl z%J7F_H&N+l4}&~I8N**_`YC7l$6&^=7o2`782+QBpM6N_r;>qz5mbXh%54jVDu(?G zjEwdSjSR;aI2e5x`WP-Vh%!bp%w~ANpv0KQu!7+&gFd4rLp8$z1|~)~h7N|a4E&72 z3{x3yF~~3`Ff3wt&Y;O?$I!rVl!2Ymo1vHC5`ze11j8(b`wWVVsSL{*-Z1DfS~1ix z9Asc-bZ6*fIL9Es7{V}(;WmRTV+Y=GJ^VwrxKG0)urfL_G&7uF;9_)PXk$3dz{}{#(9Ljx zL5R_hVFJTd264tfhRF;!7^E1(7-lfsWsql#W|+(Hh(U!hj$r}AQwDX$WQL^-uNZU~ zGZO)M8T}b1 zGF)SjU<_iI!f=y8nlYSVCc`}j1;!YLc?^#kR2kzL7BW0z&|pkqSjO<0L6D;WUE`V-{lrgFIs$!x;uy#%#uFhLa3Zj2Y1M*T|s2c$uj5cZETop@~6} z5z=mGW>8`@W4H=Ve=Q8kjL7W93VR1ttBpF z4C@)bG88fRGZZrHW%$Ox%(#xhona?K0z(923WF14FoPeX4WlpPABKetF^rQLf*5!i zUofyRnlL6ZMl&vEc+OzN=)ky#fsb(#!$t-!#yCa>#!!Z-3?&Tv85S_SV_;$oU^Ha> z&k(`zfFYS7nDH6I6NbkO0*s#+J~G%dzGN_GOk?n3*uo&p=)`b{VFrUM;~IwV3||;n z8A}=FF)U+9V)SO1z>vdW!5GJ|i$R|;fZ-KGB*S5b0)`OAtqhTjwv29!B8=}DmNS$w zSTedXBs01*{$<$5uz`V}F@qtAVJ1U5LllD#12>~6;}3?13~Y?s7(y6kF}!B*XI#PH z&3J?%l<_CSA_il|DGafU?2L|#jEtWdo-(8`&SxlRaAw%eu$EyW!v_Xm1_MSPMk~fJ z#$1Mf41o+{jF}A43{i}BjN2K0F&t&^V2o#&&9IVzhw%}^8wL)P^xepCoxy;y4I_Qu zW4O=ofZ-v-BZel18w`ew?Tny!H)HH!Y+<;?V9eOb*vfF5!Gy7kv4g>!v5nylgDGP- zV>81|1|!A}X!`DCuwZ;lRQi6xAkWanUAQ!)8ZCW4LrUMh3^pj~ zyN}^HgDs;ygC|1_LkMFKgA3zShD65s41SDD8G;x$F)U{I$KcDbf`O57CPO%*CBqMf zcMSdve;AfAI5Pw=oMcF4;AZS+Si%s>_@5z|aW_K+qaC9kg9l?4V===EhEEKC8I%}B z80{FW80Im!FvK!!X0T_R!myHI7J~;vBcmsyFJlB_8bdI{1csLk&Wtq-pBWA?Br(2a zaA5e(aEjp~!!(8x27g8##`g@`jC&Z4FlaHxF&t)KVytG!W^7>0WpHIIW?aQk#2CVm z$Dq!*g~5yA62pFmECyx9vkdu+wTzXF=NOV1s~E}|Dj4b+7cgWpXb)-b9u$}q|@ zMlxPt;AQ;DkjL1>sKcnq$jn&FP{??cA(7z_gB;^!21!N<#_bFxjNuHk8KfDl8DbdS z8Fw)FFyu3MF`j0KWprgoVwk}&kzp@`6N3X|AmdtwG{)Zy#~9WzursnT)-il!ILHve z(85^C5YN!eSiq3ZD9`wXA)P^hQI~Nw!y<-P41$dH45f@)8B`cU8LAld7%LgF8FCn- z7*iNQ^~qHRM}|5^1;+CXg$(N%k{L7@%NPq7k2A0^?qmpH^k!Vhz{kkJ_>18KgEvDQ z<8%fahDZiS#yJc^j2Vn>jBX54jLR7&F(fbsGDI`9GIB9~1-EkcF)%QmVF+VvU?^kI zXUt%zX57Y5#8A$7f+2xHm2nNjHHKV9amFwPMaFo>XvS1VR>oc692mur!Z4Y^iBXs_ zlhK{QhtZaSlW{J?H-M*u5CNcOhh%wqSa5I)MwlmCTT+WcjP{VkFA)H|ogCj#6!x@Ge1`mcX z#=Q)NjJ1qCj2jts86PoBXH;Z-%TUO0ona?K1A{5!WX2K(2gV}|-i$?z%NW-&I52cD z1~aT=yv@+Yu!ms-V*$fz#%>02#>EU<7%wpFXS~JmhT$ngB7+)ZBjYoMWehxw8yR*p zK4e(Mn93l)*u_xKpu||p5Y2d;VIE^VLl46ThFOf=j29Ui8KfDb7&93@GHhiGV=!Sn zz<8P=l5rP9Hp3l;`HX&y_KaB!mW*W#)eN2t=NXnVUSnurEM?rrXva{@7|Q6)aFB5Y zgEQk2hEEI&7+n|*7>_deGfrXTXS8S7&)~|Kz_60xIfDeF1>d!xn}}hGd3xh8GNe3=s^z z3>^&3j7u4gF?2E3GHhU2!|26O&iIbuF@qC>AfpsxFM|=|9L6GsP=+Rk7{+o2WkwCg zCdQWxy^Q*dQyFC#_cAVLyvuNj;Vi=;#vBGA#!ZYj7{VC?8T%MMGdMENU_8ud#;C$r z!H~-!$+(@7k8v%d52HHcBF4)M){OTU+!&h~)-irzaA%BVT*zp{*v}BexP$Q(LmtBw zh9it$87dhTGsZFA2lX`>Js9UQ+A;<+)-hy&`kagrjPDsXGZr)WGM-~_V!X-lgkc5a zQATq{P^)1V;{%4PpdK${2;*ypZw##r6Bw2-dNSIf)L#=Beluh+Uc$(qY>e!T9E_Zd zT#S<#{xD=RUS^!mz{r@#c!O~Y!#{>>#;c4|8U8cmFkWMv!%)mPje&tNm+?B|WQM;C zS&Ubp`ExEq2_rXA`ICoH9y*#an}LaunURH&l`)^OfU%IVi18-lEyml7cNpg}ltT0G ze1h409PbK=bb$#u~<@41o+w7z98mjA0_(7$<}CuN`og#?_z^ zCB`!h;SAfr`S$`i|Hd&MWUyrHWSqgcm(i5*8N*^mO~#K5g$%bD_A)du*fP#%EMf3q zJi!pmSjV`DaT9|B!xY9~hOLbE8QK^QFzjJ0VA#&s%^=UXoZ$fD6^7G{_ZU7fyktmZ z&|~ane8sSeL47gVBqjneh|Da|R~{Nk%2cUIr`170~>f!dT9r&1k^b$M}|ECZjpyLPizF zlZ=}gA2M8HxX5shF^55laUbIyhIqzE#y*Dc44#Zj7|%1>G3tQxuOj1NMlr^nj3JEr zjO!S$GdMFoV(?>ZX4u8}gTbFMm2oYj3u8Y+6yp)bcMN$9HyAE3{$!|RSkIWo_?V%E z;V5GO<4Q(X#%O5%J;j*7_?clpV=+T0<0S?!#=8tJ7`8B8WVB~YXUu0f#`uKcCPNj& zZpIkK_YA+l`F8_jAfp>R|033fg66{zbB3^$nV_*$VeqIjXp9*#k_;O$R%B3OU|`Vr zG=ah3^8|(&UnVfj_%?yz#*YaM5x*xeSp1v75WzT+;Rnk^h8-LeK@~a<3~~o(78Nw- z$i~3J0Ge||V9)?R6L=zonSqsopMisQ9zz7{JO&A_i3~ruCNfCyOk}X&naEJUGm&8q z&qVM{D##*`H<590Nn&!gLSj*VXOYveXoX#N?v<;$nqFg|yPV6lUS0dP*Pcts*nK+&qQ!QB`V~AJeZ%Rkdj!EsHdRdnWj(z@*613LDqwvmYAcX zP?=wF;j-}%K(xPN=7=q#qY$ezeAYNhtC@hOI6H8JRk}^v`dh`?& z-13VQQY#X33vyDe6cl*5IFmCHixiR-Y!x&z71R_AD%{*Ot$DeeGZORCLBRtuDLFqS zRUtDE=B`SG^30qZ1yF1yrlqAOmw=s8SelrVSyBlKe~=zXY=BJ2FDS{(1x39A$Q)?+ zK+;=oYHof}B{=Tk$qN>KIr+(nIf!Hk3J!39C8eh27o{p>mVmV(r7W;U6my};IX*E5 zWEfaIvNfT3*?IZpc?v-sS3^+sma+2u0=)pMPRc)@fgHV%8T zz~Ib~!H~+3%#h8Xz~IVI#8AYL&rrmm#{im7QD6vV$YV%kNMgtVt1V&3XHZ~BVaQ}C zW+-6DVMt`CWKduTVhCYyW>8@8Wk_WxW+-MzWJqU7WdLU?1_lO*eYy-GSZ#D;NCfw) zN*Rj4HYhWwGNdplFz7NUFsL#VGcYi~{N$FIlbV;9n+oy+Ow2bwr8Fm1!4D)HRGOz7 zg7CCkVrEWhQL2KnYKnrcf@(1XBpl(PrI44JSfo%24KP^Qz`($us%I3Tz`y`ipIDTd z2rEQjp$?7XqSWHlB2bP_s)VE?c!thIDqFyL2SnH@FfeerB$gyvDcFGgz~u;zLvS|D zE6q(xEdm!YutW(n%nIZduHek7R4WArF2|IVqSWGID+PlJkQpEh@fXGJWKbQ2w-qwaAGiIFkvuY&|`36@L}))Ihi4h!I>e5A(X+7A%ww`!I!}ms>X#u zk0FI2harc7fgzEhfFYAXmm!y-m_e7JoFS7Tk3p9q8Jx>f8FazvJ{_E+N*Ib5Dj9Sc zau^I5bio*88^W9vhBByW#tcSCHZU**rKbBAq~>|2R=QS%gYsNzdSGd4QDss}7=|#gi%S_28FCnc8A=#R!KFezLku_s^cV~nViVD-)n z3=9EaQ&Jd88Il=F7+e@K8H&JefrTh~Sc4?7i3PYgf&3emn3I{3SdwZAQU@`Kfx*Qp zCNU59Cb_62rYyM#QaFNTQZr(TOH$%NX)Qi8FD+j$ zxu5`aF8IqV(#!!>Yejj9IWYyPMe!vWMX8A?@!;AIVjjqS2Sg__a4;}1oDrSK09q(@ z1!3=9ktp!5`|_zWn24wPO1 zrI(07{Idbd-vU*?1Iph6r4K;Gk3i`YQ2LD6LVE*`KY{XJ zK>2T={0~t67byJ$O8K^5da$%zaq z3=9lEpnL_Xi458d3=BR}5cL^S5O?)RO$7H3Hb_lm&;YqhY9fOc$UV{%8KfB)7*wPo z>DfejB7-34OeJYZ`h=y+5U6+tRDFvyB)n!wL)^1NdLn})0|Nt0JuJP!(i1GcVd(&t zo?zjBMS3EGC<6mSe0)-3acT<4i45`a$)J`nLwtNeVsUaJsJLc`k1sAs0kyZmYC#QG z2q!*1EwQ)+#x6@uF3B%~@IYoJ=fF7e@u`VPnIN&^^31f7ctfx`5VjE#+ZfC)C@C^C zVTg|}N-Zua%1kZ+=_}1k%*jm8OHE;biGm!fke6BxDn}GjQgc#EQWM9DaFM8M#{iB8ZEXeyU0ntST?Phl{DIPruALTx zKB&#Zz`y`%l-SrZFxY|2wPj$?0rmAX85rsq7#QLh7#M087#P&l7#M157#Or{85p!} z85neJ85s0!85mSS`s{2OY;0^9)NC0TYHS%8;%pfh63Ws_KwU0%1`s<5i46)lb%q2` z!JD53l4eK%wP3OA0x04WL0zJp)Dmp^AyKV>tUa?N zwFnfxVEs^egtZFD(hLbud5F`oo03qLSyWP*n4^%ASzM5ln4Fpm>Wbwi7J&ShnxOzS z0=s5V*do+mbw&b09-lK95|Z-^Dp7oj2&jb8loExa)RNMoyi8DZB)EDoBm{+oc!KPQ z#2q}gp>YZ2V>b|#o@CPPAgZeAw13tF5Bitz+QU_eqmQp91%MaLq^GB70M zCgvrkr=}1JJalzf0}$j#L>OX(5^{uN32U@4MW{|lsmx2v%}iE6boz=E((;QGK=BTf zODsvP$Sgrh^e`2Ow2#k0=;;rqV?chy2s7NOp>Yh&uaGtmEZf4$9|a{PP?ZHQj}(&g z;}gphGfNl{Wt5Gr9fLv$Xbiz6wK%ybv!Eou2$ZiBoDz#u6`XSti;EQyG75<$3K|T^ za*jnsiIwUM3{a&WnW;sIMadbJNSZ*#F(^3agN6u7QWgA@vOryYP-g*ZS3+W5eqLp6 zerd4+sEb)#keCcE8=S+y-7f|el?(U2GOsizr=X;WAty06DJ7ACp)5Z$1>_Da zeq^XsS74|G`Jt>NzX()rrB+mf)x!AI3=9d0DOsh(CHX}lHl&PzrWd4KmXVrMkP41+ zgr8v50H_VEkedqb9V3^1#OlFf4b%Y)up$@a=7OTkvcwWl51WCZpeVm2HMt};#Y%yp zpfo8bGZ~TwqDwML^Ri>DKYpR6qKBm6c{uW7#P4KP7DkT#TofUB?=4-nRy_R zfgvY9FCCNtO7n`r6*`Cw3R4K3lUS0OlZwm+nO$6xVr2!5i1-o(22?%+gH38qPG&)I zX0aUugAOQBFfcIaAPFku<)>C8rxt+nSaLxrLt<_LgAUY^_iKT26i< zNPS9vX;Mxq14B}NKC~^AnO9-~YLjHyW>~Nzo8d!NHiJTM zHbaQvY=#BfvKcKjp+*7H-vv1e#0L2p)b9ncLH%5qIH(T_Vml}1 zfyaN7lT(X}70N&(C!mqv)Z7Bl5O4u#)Ck-`01b$tjWHx;<|P(orWVIkSeO;1mc(S{ zCC7lqi1YIja~ND0tQcY#5*cC`;u*@pqdwW-Q4-J^d&n6Zpb^$0hD-*~=xGc?1%m~H z8F*9(G|mDVElOsHVaR7F0FT+`gU4gRnG@t_1_lNt24{vuhCGHmhJ1z+1_g#hhGd3h zuvx_n3g8i=9EMWx*eYo3Mu8!fAs1{GXyg{%RM7m+8>NX18p;zHQj{k`N1JeuU8ON( zG9)piG8BQwwh-f1pgs?waj#;AN`^d!WQGj*h?f!g91@VXvcYENF{Co&fXAXhVyX-| z;PGHoa~T+t!9E6!VW%*}Gh~3n0yJg@8r!yIuw_tS@MQ2~2xD+$@L}*|aAAmN@L+Ic z@B@$HxiZ8kjzlP02+}Z#-E_@Dn|Z3r4&(-q z7+5KIOvx>$*by|^4G{tD9b{l|%PDp%N(B$+!_>H^mVier!OB2+)Gent7$yeFzaTMB z*g$Tob5UkVW^!Uqa4L8n&9#D|#b`DI!`*C#fT!8;c>_pg2pMEPV>FxL!X1cwQeuh% zvRny6K7%fU9YZ`rI5-u7@)9JR@)%0NW4WLlSj3>fpvIuapum7o@4}GJ;0DgIh%}c5 z9vKCNAJ{WAO;@Q58Q>i|CE!>D?N0&ae~@b-@rX!8pfPCJ$a5;v2(oj2k!wX}NkCCP zsPJQ8uotkmhq*f!JYtQUBVnn%m>~u{l3N5G5eB6uP|kpv4;nEpVTcFoMo#shR0SI8 z28ADJw^0Vvq9leyaC(EKP6Gx7h8l(%@CG>}1_cHia9&2Jg2V!X50N)!FoUMic!qdr zu0*xbiouGZ0KC@;6gvp_f#$40118Dv{GrYe!(hOm4tIwZLp)OM0i8_=aymYHk{Muj zgF+`A>>^MJRRk`xAfWxY7S@` zp*W@#G?@UJTu3Y^05eNcGV^2N(=u~XA(IFN45i?CQ_$QAD2_pCK9wPnA(ugc0e9?y z&XxzI6~g%qRuh40j{;~)2h}y8QUH|iLG2At{S2D9MU()baD${IR5!&lBr%jSq%ov{ z>nBhe%SXz&pgF)|280jvpzR7!y#cEeh%F}wyE}~`nIVTEA6yzBTprJWEFKST?|@W+ zX08#rxCq`pLRSw8RZv<*sDPv+YPvfWJU<3%4;3*WT+RRvRZ!~-WFsVmA+zidK4?{O zDg($zpwt1XL+Fz}(!i}sPz{glR#5q!%a99g0i-d2=KKo4?Ep~Pgv<%zO2JxSeV|!G zm844_u4FM}gP z1cL&DJ_D#l56a`9)f}L89Uxa_GE_07LhC^d1|VGN4_tZVaHFLoq`Jg95mfU&2t%kP1!-3gG$cJa7(8W+(;sOh7GG1#nC! zf>&^W`Xr#09OVq4z75DmB?cV^1qS4JgtWJk!EH^GP=wh{*viwq15pw0de64YdctWRSGi?T5=F)}c) zu&{z4^uR<`23BTPP#+XDR|heHiGzuOnS+&ql>>ZyBLg!#_#6RtRtE6IF$3s43opR1<;Pf}pl5sP;-_NCEe(Kqtw-TD)ltdEj=a0t2Y* zfYcD6azldw-DKSD3{cIi3C?pG3?O}=JXpa{0xzRM?nwmKO&Sa!`#|IJ<%(dnxeW2(mMf?Q1gSSLZPa7{K~S(0 zn}0!}M|?j6v{o&jL5~5}%K){1;=!$NP_G5#9$0$`)LVeG%|Y#MPzybip@gBB!3N$Q zhqOe|TZRxbKxGD~_6C&;#S9=DK&4|Qxc`&J04X~P8A`z`UO@2;s!KsWp+-9oRA!ej zfYLz;QcVS_KM?hJ83U+C4l0R3rF$9!s7(S|=LafDiLH~%z^nd{%>cz4av2Q@Ly&7g zc3}47kX7QUDM8~E`3%VJ2CXzi*a-@4kgcHgS%~&3cGF-zb!2-{U1-OkzyNBYfa*vm zr1meQcaOWSK@ZzvhCGG>a6Jd|IVip%wK^#8B0?FIHgJbEEz^HIxL!x35m0VG&f}mu z8In^_Rf2LiC_Z62LHzPL{~Q&3!jFm2kwc`yn&5#$Opp--3`VeFzuC~iS`v??sAdD^csMkLjh;&JQ z>cACO1K|r$+<-8)_yP6b{TLL$tAFws(iuv?^DdBaRzz=I0X*-CuP2XKc>-ChL%n#X zUg`#oe2$LufL7>$MqtqUr>M0jq`U!*eSyX=eIPuVzCbG#hVD2b;kXCIGANyu zFjO*tRsw*=vGc%tgDV(7r5R|AC1|x4WbQ``JVOi`e*yJ6Ksg0GHCpI zu#fM8+>SZN1gXV9^JxVPpb;)mn1V`y5(ZHFAGCS|M1y(&sSKdqGyps=9@d6qHsG z^&HHmp*D^INz26h4pb_FFeopBVhxlxL3tFkZW=Tq4a&KQ`kT1&Y&0Grv-9*!rJy(j zVchYE+(v?wpTxF@(92X}>L*zKp?4U7{6A22(r9?1*YU*H5ug-FZ1@o_UxsG?4^sYu z+N+?JAE<5}ob!SZcY@ktp!xt?KMy2MxZOJ%kF+lxQF8(@{dLrO0u+;=J_#tcK`ZjG zuU`V?UgFz%p!7p*I}F|Z*vfZ^?Zn$pINc3I?L~fCfb_U9%Z!2W1*i=I!k~Bp#q(%; z613(Vvf>dDCfLjP!5LquRZC~#6Y*!$t!D+=TwK*dQU<%2Pk$&`<=rre$i_b z&>Sah<^r}C6p=DOB?+<)*jYb>b-`AlKvEI$>1gPMHz7DgVF*b_h29Cf#e8c+a06vNM4!&#R9P-l&};-`V0~A`H{484dx1(&I#@d4Tq0?JFE-7TOy4|2e#mLtLo6el1|Y&}6*|93EyK%mkGQM$n9 zSRwT~;T>K>dt8syoiyat5d$@+Myl^XbrA@IQUtF0h}e8El>7|xFEM2^DdoV>_CMq_ zK5S(nvGGq@IS6Yplb63BZF6!`J1FMqQ}z)XZiM^u16^m3A4iZn1#=DiK>G+(=7BIM zHBega5strsNbA&(vw`phD2_mwKJi4oR7u=wFjV`7W6e`RJb3(%I}a0Eo)ON!sHH0H;~dpKa`Q52{UlU7>F-BSZU$jc3dhw_ z2Bm6h&PNPHDkd*vNsG&Y@E0iVK$xEKH_&O8yto97DbT*ZN?dyZH3X?!uM#d-2O^zP zKh6fi7oeO5!uWEV1_SKYILP^!8lbz@H5tGso`KHCBK9;tNZ$i=J1;0rf$j?e-DV6q zvFWC7fup4(lEgE9OlRo7s zsbk&bl7CN;`gQhf)?k01;xXOU9?BEFH={eV&g%$1-t0E&0Q>->gNSb)NT8f6nH z>3-;k4|2+ZlnbDg0y_;Bk(OX(2XX0UIF$#G5W>C&7?z{RD``L`6I&a@Y(i}ZgG_*x z{D`<3n0!yY_6evhN8Wui)G7mrt@p^u|ARN2kW&-kvVfFwl0M}Dap?w;lgP`p4hw3P4Wy*|p_EpzhYu+2!D<-7WdgC~=5Q(xAfW>5 zO`*0xG4F&LsMJqxPXUzLiSI8Ar+9^=eA>19NUg0vF$lt-d zLFzeBm_Tkt2aN$HGk|VK2d%hDXDDUJ1>c1M5=mnKox2aJLqWMT9(;EjC?u(wzENFA zNgYRCXpm)`xKNHKo}JFh|xquZUBWJD2G7yi!deW{Rk)p|~qezR>f$$e74ncSz;&GtUFnMuGpZ*bXwJK@|LfVz2#U}CN zI)uyJfk?m9kHdlR1t`uynD|^s&3HpiMdXJlvFkWc?Hg+QCnz7e0Gaf#_P#{5k3MmTYA5~u2r6Yk7*x_i zYI4y02xvtg?CdSjdig4bRB)aI5!B0<1MPS6LYuTU>_Gbw6t^IZJARQ@22wYEVWkFn z;S5TR#MYoNo9L5gVYboJU!XVyVchXZyL>tj{v|JLNz0o9;V)1ef-vrQq+Na-=(30& zaXQd`1jQ`~gW?z4I1uP0OHe6G&Hlx;BaaTWA3=E)gh8njTX_rWw}W~#uoYj_j9*yFAupUq+qX6hunv%aRG}l2;7{IIz`7R={lpU(kyW`b^rMc3=9rTQ`rx8hN;Lb|8+Dy z_eAlX+_kTZ7(p5io=Z_*lzd8J$$Qo6i)Rbo-_Mq}do?$n86?N>B=6thvspZQ(v0LS z^_ZDlqf~!fDh%^FbodrK1A{=n-U<%qO{;386#E>`b$#YOccev~`*qFXDXMEdg+P`{ z-Mtku|IGfx$UCc7#~kNzVf~sew&!Bd`t83pd;1fnXo2lecuIVyU#|aP1Cbpbi4Lf>YCtt<+B$lYzY3j|JZ8PDc-)1 zSr{615C8shK`AIegMa(yPr~8CB2IT|V=b@El#Ki#V=;;0n#kt1o#jib68~)%%1Y#B zV0a=Z+natkOhJB%Rks=EY>v!=z57zj6kZ=un?3hMx@aD!=v?hjMuozG9{bKMdg>Zf zF9q_z?usejnGTdl_b|kM*id@x_DYeRHy_1*EuHt;=W)2X`eyJfyZv|KWR?5E zZ!!$jUAD}8=h(RI@F}KO$cR;V0K8SULDVvS0l(zuZ^t*?KNeDibgaUCntZ zf@j%jwZyRYW|^#mU)oE{UbyI-cVFN*kCo%39ow!2FHW3)9(v%{!%Z%X?>E#bs1&Of zU2Ochni`)CFhJCANl9z@+*Ea4tp9Vd{A}z_179LucuuuxAv4qq+3eY--zYxa-u>8rW^tz)cSrsI`4b-$dZ%#q`(E?vD*cHHbDPw1`5 z6XqVDwc@n5szlibUe1mc-%AAKt^NplJYCzD94YYp^z;{**VXKbo@{AbH6dEb(s)iO zdzJUZm+rddKl5ficid8T4Vk6dx;ic4 z%LLxbUtn;kI{q|i$BV3v8v;*foIPKl@k=ZeaXRm|V{w9=1x$`f$W!N9Qa<&~J6{Msk8 zpWn3pxiCMeJkX^3*o#Q*dlC0+&PV)rQxdHSUlCdQTrD`gTs(REv)A!le;;RBzA!dj zz`CM+r{OneetE^)&QUj}eU)ClNYXxog@J(~c*}2LfAMY3Cv)EU zr}NGiU3qQm)^B{%EQ%){@_c<}x_10jdkg+=n_Z>adePAv#tMgCoWJ95xDy$h|@Lpq0^RidM29}=Py2MpI4=^<$L)-?+Yg`r9b$w zVqLoR$+erqPULXUojaA`phvWA*FLW=W;cU;U)(M{swnf5v(eQn>&B|y!`gTtgN0v}oS6{Se<95ieHy}Cj~bA8|+%jvIGMGdrlxcQhDTHE~7*!8EQ zJi>Y2jwMfQiw}KrtC^8h($B9bd3)Wq#d@1W0#@~|wtVGeGHv?G`}Z0DUH*KjfvIwV zIRgU&*@rCr z|3thz<@eXig|=l2Uh0d~rulp^*88~Qb006iaOM=B;uZXA2@b-HHe4NrXB2gpn!i7J zt80tlZYM{dpVx9&yHD(3WPMcgc6!i}#KTFeZrp0W_sV!jV#bFlduN>y&boTAR~MXM z1cYChRUMnBDfWfS-t+VMWlPH!EALy<6usz-evyD_z02HvJA@Cd@H6r`xz>2zo?ZXe zlo=`d=oy_Aw%aoCUxC@pnBA?@MV$UhopJkd*W%fwcJ@s1i%e4gK5n&Jw|eK{{C6BO z`#{Ay1B1h=Lk^8M%YW$DUVm6PL;v|z&g8(NyOJx`yG3bTJ9mdk>)&0sbG<6U>T544 zZCVxtR^ zzh+m{$^stlOk!hTU`X7MF2%)o>A*wQ3)aO#x9#=jFMc$4Q{tmL$y$3@)TYe7T97zR z_3@#drQ9NlIejh_9~TBZ|9PjdKABy6zW%+rN+A0f1UmP|*@T&wKekwW+SY&G zrAD23-6nc>a{k zxQ9A@DIS&!rwTscH;J$j-!kQ!hx*=dwHm!!-K7gAG*}C7yRAFH<9u!%%M+EE0bo0s zm>3wCSs55uI2jmOco`U3g%}vwBp8_3_O5(^l)BzH1$NnK{-l77d?EzQZqEu+fBEek3?QWzK* zUNAE-2&gkKENEk7aB$*hXqYyGf#Km-R)$lvtU-5rxG-cglz~tAf$WS^U`S%9WKdwJ zVn_w=&4Jw7kp@18rw8%8mi6 zN(Re8&Y^**ft(!!>KPO<OwZO+YTqXQ*HR^<2^zav1U%Kzk}dege4x zw6YDv2JKNo*bGt&nwLQ}AJnJGWI(qS11Qc*89*^s z!2r462NVk_3<}`b2FZYKUdv-hXMo+{k_x@$2Q>|lxOXQr54v>+WPd1D`$2I9vbTgG zgF%6z80tF2?L*j8BK6ZDsAmWY1JDQzC=C=afOhb}(jg-QBO|D4U}RumL}4>R08|vr zA)3v=05TFxfXs!&6v!g5F(7M*&TqvGMGT<)mdF4)gA0<|Vi*v9g5*e;pOV3B}Ng09=Mb! zVgSj5<~H*gQW#PhG#E4)U^gHefb9Sg==lOOCP29m5ig*#$v`H<)-QnUuwfu)Tm)ez z$Oce|A?Cjja+rI#Q0;>Br9mc;Hb0NB0i+kf!|p#=&z-oj4}@tTvx)Z^%ocop8eH)O zTc?Kb@o}`$j(E?1k7wOqw7*{6Qr%s8tk?R9iq= zW02Yc6i&qZmpb7~ygv!smkn-9veLMYdHg`eg?H(A*mF^g7g_caX=k^ z!crBz>skDMqn`gzO9%3ONlr-wn>WJm*TE8x#P|@FS`h6e{C*pJ@d(QIp#Cq2hLrl` zwx2*{BdA{vG6`fNW`7QK_II$vGt9jp8dnHl#xrUeNvhumUpgQrwWF3Dh%`@GSPYhQ zKuib>|8xM#1)$suqH*O0TKVX2^%C&dLlOfh-)JzXfky<3z~fQn z;Fb?)EH96tgaLHMcM?M>LmERGxE%)S8|Q;tb)dSx2rO?3CX?agl+;O2sD2#ydJ=bd zB3iBFwL6Jz=PEF$F{puiYPk%M@f?_a*iC?`0=1=KBTJysAy^L&J)S^45!m=Fq9+9! zWx_pH3rbNSS4%uw3bhO)$IqY?L>+&_LZ1BiCC0}v zTgdS%q)&-G<&aXYfN}z?9K)R!L3swfe-Fw(pqdXfo}bD9TCJ7C02&i32A8@Z9U!wo zs&M5paz;;Jy)x`$bfD3OWbj_WRPY!+Xf#C;Jeq<&8;71wKyDrU;eacTV1~xv^B*X6 zfl7Q3jXm9h(hww-A#wz!&p^2xvm77z_yhTikpGB}Kg4V%1A`}nAA=hM=&l>cY!`^{ z$q>R22^9m4#8omdF!(VzGWantfZL~_odlkKZVZ`uX$+ozo*`hhd6^|(b&h@vd5L*6 zGdCFO6418=VVgSvCgIozZuT+7-har<8i2-z)X%Pd&ICQ@&GB7X@@*hY|Kv8~rQDUx@ z0s{j>0Jxu%4mLLz?0W_Vx6GVWkfa*}Bve3Q0&=`hW*%4^rmAi4@(o*@dkrNt!*NvR5{d5K9msVSf=$)EvF z0g%1-pfr~XUd;kpfdlFlD}ZZRP@fmH9s}lf$lN|CAAou~pcD#mn=XR_gBJs+%z*CON@Renhyj%ip!B520D=tQJjBHXqCvTdfx!lr5b_dpQx!_{vh(uG z^XwQHY%pR4v~~xQJ3x6Qn*p?YuACu{!470R7!$ib1NXWG(5b;C44^xSW1#IHNa*V^ zAXYChpsi0pjwR4IBdBKwawjOIBr(Y>TPMlM>!a9x)YRwL2X3pyAzaGN}(w#9=xKb9DIH=sAMAS zVo*3^3s>5?7qvuzwC_Q#$Y&tzTHN7_NC)WV!}10w6=z6{^+?#~pj?v+&S|jp4l0{L zJu6tv1@a%LmO+dvV5U~kc!Cy#0)qyF27?iU8G``>#0Q4pH9(+p3*=v9QxzCMqPTnn z3ImY6FrS0cA}H^m(ztyG(o3wHQO$&`{R7zrYL~#qJ`~_N5tO3nldcQE`*&cm0Ip0J zaHmt+W3sGCP8TuR5#=?K+-;O=?;=hV6jg) z{y}*Vcbx=s18!MdH5PW4;?8{_*J2M}NP7lUUs2PYknn|+IFMWm3E={GuEiB@^o(y< z-0L$aFc_1N20)=X5bnnoo}l!D><=@jKS1R?{`M3sSJ5NhHNZ1SpnQfL*4W%_!~m*k zKrSbgUa8l1RKz+ywP6KxI2+b&?&f#-8C^r%3Zjee? zyn$MFpmr0aPYLN~6Ca1z-HTcdqV~Bd>GNQ7E66XPmLRC#hv@Hs_E&&<#PJM>IhujV z7v$7-xXNc*qyubW3JNJuYNV$-VCfMwZVMXuAwCU)T#7v%(jvTI?u7NeNOLF1tqAV@$Zw%TP%D}(?qaor5@;^I*jl^o8e7poQ;~K+|1|H`qVF1kl7c(G_mY~WoKvjTB zYDj5;Z+;6hrv!>q(1;YaxgQ0F8ipDM&`2GucMDq?0NUk2egC2Q4Yc|Iv5y7jQ_x5q zWQ+(jP6Zkjvjfjsfm{R$eahSgvK6*ExP$>TP6aBf(vU(OqyphCP-_RYY9a}|wl{|X zG%pWI@%X|O;(l~9(!guw85n3a7eVP90%hR}N^OYrj41gLsTs6B0U-{{yPy$5Q0oa4 zvY@%FG^APsG**=lUiXm9kPRPaL)8JH;Eyf0aQol zfyegK89?(6kX2hnIOajz7(gQS4b-uec~VCb6IZbd6qaW^r;%N>X}J zL5W^+K>=vLHmJS<&3r+2zr-^*GXyb&FvK$iF$6G#FnBQdGx#%jGk{7RKZan25C%sE z9|j)=SZxklzXz+!aq9<_SiTJY3}Fne4Cr+hXci7Mb_y!{Kct!`5-asV=s5Oz#pa8D5Kx57d&{Ve=|f`oBe5qSu_q$2 zCn2#XBeAzIA$B;DcD3o6Ai^j1<9Utsp#f z)sT@Vkn2G6?6B6KF*uLH;uq8t0Qp7(yz+te@e7MXSQre1J3z6DD5;_CS}b?LBGqTb zC5c5Pr3EpGMd@Yn1&Kw)nR)5piVd?~f}D8(+P751kj_xX0Lq=9^)R5;HR#*{&^$k= z-HLn@F=$OCq}NJ}d7wTdWRwNJnV=K~s>$;h$SsFJtqYJ_5$hjdeuAxu2bEOmNG*8O zIuXRnV*rgPgM16BbrInLavkn=L`rILc1b?CEs>g67L%G+mRXda2U_A2pP83gl9`y3 zS(OM{K?IHk(#u;=OcXO@Gk|I~P<{iIkul)DRT%?}&IGTG%0s#@8suBZI0a}|ET{wk zVNQp^Ah7)OGD1!yjDh(OT;A%;acgWf$Pz-^_NkF?bK<%`A2GAKLptVo1a6!Z- zs80%MH^SsVaR-{i0rksa<2bPWC>r3J88o*KszE@jlr@;ssR}G#&t2 zT?4vT9@IC5lt-Ymgg|QqL3sxx3b7Bgjsdjm#f`zAA%MY^!4Djl5ceoCcrt)e8YE?c zdj2rIkX2lu+8mUQKrMODjtV^n1qRp(KhT;AkZmBBfyRVD>%Wr0tv!&>L1sZtWlCfK znFZQy4%q<(TGa*Wmw253u^Hqz zD}c7KLA?-cBZm;Zu<_V5@M$!lasnhyt8x@_21O!L2?|PYFgKJl6fmSS$eZ>qpQ1*wT#SAS_cEP1$1|J4zhInXS5@aBR z@66y2?p->9OA=&p(5h=t&O(TR`jUPOuHYUisKjG{n(4<7%HYf3$`Hih$>0o94iyh! z@C1v4g}~=sq326T-3c0d1Eo?>{|wag2jxl7$s?fB8&+o`=POWI1)6^Vl?F--I?!1@ z%F-pWnK2CI;PJ!~aK4Axgjx;~<2KxNI&^FxCqFqcCpD(LIJE@AgjV6;0E5JjFSv$L zV1S**0&)$gHcbcjJ3*xrZ1*3g3`7si97l!-u(_alJ5X7M>N^GoTLx>eJcz`u22?&H z#%sZf8DRYe)OLFg18C$X6`Wr|H8VLqBxEx%dq|K~>7W#l2QB$=xf$YD(A+Ypg#vRg zsBZ`w;VlNQ?*q+p!c@eg#5&0JpnWzO;GQ0;n?PX(DTg3-Ag3WjsROEoK%?K7?R!vb z3t}$922dZxngP})faDL5>7cn?kef{y%)#>vp!P1PB?(zW3yKSf`Ka*#>N7*y___>s z48;sp3_jqs+6bK>|B(|rgiXd4XQ|+H0c#~f%5snkKt2Se7?=zsUem$jdyrNDEZzwF zFCV-@9b|$Z1EgdD*+4BnVwz4(f8vU7%0@Mp9%&j>gM!+WpmrFd6eBjDgWLPs?tj77odaIIn9U&D$Vugt*ohkJpgIUN zet{UhLiRmsiviS1g48?6{sNt0P)C&*!xmqlJOnDGU~M}3gfC^bqJ}Uij#0xA7W?Sw z4!bJsDUUkw1}dpQt35#DU8uGr;u?FoMOg@e!i1c3PnoTl@dBF(L{0OsG6m#H{3<|U z1{xnhZO>7jpNNSUi2*~LqV(3K&L8$Yy*vXf%Xo8dg-X8H>d^Y4DFRbdiXH&P}}36 zJ}9Jqf|w056eQ2a7{C+^>6;KWVS3(` zP|gOK268!MJWrd!5S+WPsYX==awBYh2DYvXv@;j`Ot>M)Srpzw09s=YngIl@LP%u* zt@DD}k2=l`=~aNj1XUGiU9JZBOaxH911hya^$}$J4pQia~9}5{6>%PA|~uN1&1mG;anno$$OpNEPV51yHLHG`<3v*@V~uX;FaE z3g`r9kc&a{f1veSpn4BvcL4+FOec`KV(>a(^!0M+rwu^-4=TAqr8Hzt8RTzJ{fFvv zP-HnFos|eWfdjP40hA*^E6Iu(KqtE8Fo4F0H5foGE#g!wF@Wk&&>SdajuGT)23NQ-X3D$OWJkm7rM|$Xp62MiK2|h}+0F1>L>a?k&Nx z&LlrCwIUO`bP^Pl3>Q)g!E{3^gg(Gl#PEQE8jztI(jaCUKxu)rLI#7> zLI#J_LWU11g$xR*g;?jYKxq#$GNQl$TBQKF9|try1xmx9+)aEs#=Z^?R6l{n{6Tm7 zfMOWL&tXVoC;-owg4_-%&p_=3(E2xs9H@N=k^^B-&I9EOP|FT-PC4?rNKo2^&4FUe zv#2^jX$?|qLiB-7v4ZX3fTSJ5`4ziAVKeo`43*&4Cn#^mfO81QM9_FDXeJQ3i~_j@ zk?uix30Wm11VA(RpmivqbY8#!>IbGVfbu%1-3vVIOk-h=9PfP9G$^8LxFmCpt+cA244nH2!m!^E5Y}`Q0jj~y#gAY z1*I_1NntQic)TEqlCysES)RUxqidURDru>$nuDn0O_IQaEJ z)VLNET_z7ATY_7Q_6Snxc>d@_1%?UTTU$ zQGRJjW?pKsjsoZ?srbYkuyA})D%g`6n(!6So(#ndVc>PPpgTc47(jWZfFXbZ`D|Ye z@JTbEUPLx{<~5%ohXJ(K3KGXD&=FlwY6p!9fm#lrQ=CA%c8cJ)3}KfAtx^G{L{N$c ztr-HbLAO7E*5N?x1J#?5b_8}?L8TOE1sG_@EvViD<#*W5W>~ulpBiFZ0Lo*~xGcyo zF3wEKNma;5O)OAI&Mzt|EdVFt#1e)4B89xv#3FFafV4ozopRu_%b+#OppqQqTgaXx zh#Y8V6KI_gr0oZ~xeVlD(1174kt^QEI9NC>WsSB&19NiNZ=FP!59V4QMRUX)*w3OWQ0S^`2% z1h3sy$WMc$*QC<4wA3O!E&}Dupm8T8x*2f0Co!!gwTPO*1~D)-FNM@F137h2xRZea zOM1j!`oi)kc3EOdMp%CYR^lLX0H_3`N4X3NcTC$6B}_a6B>%zuicJPm?vi2(XonAE z2bU9r4}(90GlMt0Z-&hVNJ$#c;0NAS>I+_z7tesui(aPUE02-giLMWSS&XU^q!+ZK z1u}n&T*A6I`Z~J1y5Pxo`FRQ@`30an0&0Uo%PeT4grw3c5xHQ3lx(0j4X7kep`e_i zllwr4kAZ;!RBVG=vycWGsK{2xELKqUELBLVEJ-a^$jQ%3C+HiZ&0%n^OwLJF$jpO= zdroF?38Ho=&j20&T2Pdq3_6xHFCC^RKRFRpdB7uyfq}sT)P^Zb%*jjv?9-V+~KR^(MwxGmkzQEGOo2P5k-Fyw*z$mn{|vnT^Ya#0DoBD@CsgWa!?Qko0u4&)Z(q?Uj? zmoBi@8niu@lbV=atjGoLcfsNb)Ke;80FAMMVg%IU1hw@+BY6xAs-B=e9jE}w%u@hy zKm`rB16T~sq&|s7>8Zsf3VEfuNvTDko*w83XqYCj5{8iclEfTXA2BmOuh|9R)fU3DhP4^~hjzh@i$YsMQY>PX+e?LGx6g+iF31Gafu< z1IkmNo*Qy~f~*Qwh9JheQDs3pMPM_D;Do~fY41at#n8wG_j~j5OJM$j^nGEyT(r(F zqR;D+n46fM3TteG@}5F@MrLvb*f?;<7+geRcB8pKbtR~r0o{@f${C>EFS5HKJ4`_; zAiXDq?=iy+dz}mNE2w`@zCS^ACZtaT+ARg@Ntb}fcR+jWK_^*(ZWl+KpaF3!C>9wQ zm>5_XJQ5}`#4s>0urRPOgn-%lASZ$4QW7RHfOw#>WzeiWNEc|7tpt2;H>h-kv~OT# z1?ZG-(AXr%))EFAaQ_!H@@@xSc?~LsKq@Ms;|`#E#X+fy(s3wA2?T0^LPq^TYx+TA zptUhDJ2M$T;{?cKQppUUc?Zy3H)u8#)}954Le|n7F_pncU$;J9I6kYHe7U}a!n;ALQ7U}Iol0PVL19cKjE zgALm64WdC}AR07y29g8q6^F@z%mwKM(fm+51fb>#GB7X*K{3ca(0S<~wIKh4_>NF@ zp!FaiegFdl14vI0R6H0;hchrRfXoM-%MY>}G|vGtCzpYN0d($q0Rsbr3BxCaAxfq2{ze&7H`=0PaW6gYp+b-M@r^fdORCa;W%rsJqTV<*!5KBUu<2 zv=|r|B-j}kK;c8#xHU*OXq7f-$0X%PP%=V@gHA^P&9%Yw z65KnInOBlpl$V$jQ;=E|Uy@OjnwS!wl30=m-$Ig;I*FkmbrM5K>LiAW)JY6AsgoEQ zQYSIAq)uY!NS(wmA$1bNjMPaC3sNUBtVx~3up@O6!-3RE3};d&F5~|iq)%d4lRk-IPx>T=3+a;>?m*SQNT0;;C4CYDL&hWqfs9EEDjAa)Ofn`hcw|gs zh{>45kdiTpAtz%JLqo%VDL)JV{l7NV(?8Y zVsI=dV(?9@Wbi7@WAG}?VQ?%>X9!L$VDL{aVerc@V{l1L2B|LvU9sSnnp6a4Fff4h zCTD=o0V*iU1m!)i(me1yfmdk``0@nD()7~e5(bc2C8?mM0|Nud%>1O(B9OT-A&~iS zwxcftLx3*>gRifCN{W6Z*qoGq$E*%873D(e{-!Wlp{2m=G?446_-IDl`HWnc&f*C!yllmWCOG!c5&1L$-RWIn{4 zV(=Z-AcsKA1J%n2F^JiqaY;}s6r_rQ!3}H=f)B9|bWZ_7%nQ6*2Ba2rW)R5jpfzfs zyCp!aTnHaznite>AQ}|Ljtr&X9to(Q0xIA9!TVl7_m<={lrccg?n!1~V1Sqpy6*yV zlZ6}jY$DK^79e{-CPVB1%`b!F5PTLn=(H4&UQoDzqmlt)FGM}WZqPUfsJ8(MKhSw5 zpxG|iNH_xn#69`YGe2SO0?hML zMnvd?v@t;~IMCP)q~8GQNh8~DNRc_9bOPEt5Aqc#WROjU&H57dA1KFw`U0Rf7pQHR z0i6*^VF0a;LxeFgeg^4>t>A#U1{6mi*AR+d$jmaREeJXb6Q&y!OQ299><>ta0gXby z^ulZ=thWL@rwxjuR0fc4h^@K|xZMr12h>)Cq)pK5J}75{S`o0c3u-x(gG~du1B5}Q z;c^S8jR86*4-|SO43!MJ43O{u#cM9csavQq12Gr0YPSR<|Dd`IbW$KFMdmZ4GeB<9 z0QnZ=HV`J>97tG0d~l3@hu zM}Yb;Q1z~mt9v4XOF$Y^6H7{qQo-#EP~QS-mrr6b)V_fHg3MyycmO#7}l9`(tP?VaSS)A%v37IFkJ!HIQK>klUb_L!tQ{)ziL-#n}uD44}Rp z$R3z|p2cCH!CVxJU~)drzKI3!m;?3mA@Shj?CBDckD>)0uL#kQe2_Yjk74lvk}F9? zaTd5w3JO!-)Z*gA^i-$(3P&tr;ov@NP`)SZC>wBifcmUK`Js9618!0o7=*!X*n)uk zoXq4(_tX+-M1`alFdJ@DENcfmjz@l9-(BUYb~xm{*dT z3hrZq`q+>}{oi6i$fog5>04hR_fFn>~igo=VEJQ)45kkxa-8%+3Zw7f4BI-I1P>l*n6QEHsP>%x=MzEE@pz#sV zo;TPitvW*tg8_p&_$*1tm~<#Z2!k7gE(6$|P&Q~Ufe(W#LnwnE_&gAQ1{d)8laRB2 zsDDZjD9wT}W$^+^A+U4=${V281R_3QBf6l%1vF1p3_i&V6lb_jBVqubF$ zTIZnAQOHOl=!Qtp{1|BV7j`ZO%wEu%seJG_X)*(-WCx9nfm+R=6EPv{YCyRba_$ge zlR>6pU-JoD?}@qI2Dct$`&1be7>wX+x+gv7q*HF+&VPDfn(l(8wzGb*6~4AHx7D4?%ru&}v20(h$`02K7)u z{V7NqfaEmLDss?jT+qlr$OoX*f*xzsOOK#)dqHFM*(l{2s@o81KzRXlrY>j~AE-SH znxg@&Cxf^glmbC3GeKjOpgsU-jTLBi08~mq){!?jy^F3@0roH33)Z-GWXKq&*eET~Qb?Hd5qMIe=+)Ch_V(7Z@7Lp1oby>f(2{fZ;&j3124O1R;sxBz4 zL3XE^BHcg-3TbTd16lzg)0F*w=z$uUcyiWm?Dna=Rmghh#0Z`i` zm@!YP`$2w&lx!ehfMzE_YY-5%B`EiRX7|u*JbZdU;eZ-SAX`9nml8uL1L)=f&@OV& z3J*}-0~*VQonZ#?DJWNg+GL>60hKDCwkN2xh3yQ1l*XXZMo=jPq9L^ns3Zf8@PbYi z#MNd1g%5ShOVF-7(9R^#s4sH+2U#3aLZatIV*G);PXttof##4wttedvJ7{|cl*=LG za-fy7pglE7;59kP40_;muRtS+iQxUrpcMv5;8Y44vj_1K87knd5l{-P0pET?TYDg5 zKh%#0Q22x50Tk|tcmUahXmcxoOWiyMbp}ux0hM&19VMVV28tU{oev64(4MXguu9OG zddTL+GvqLU(kdvGf##lJ<##1`b(JCm2r@w91rp}u#S>`%CnOhv(gRr&or%Ir}WuS(CL17H?FKW63rF}z+&qD{5(2zbG=w2aE z{s7&Dl8n^C0hO}|aqM{&54ca9DIc-E^ z1qO5o+PMe8=rY*&9t;9_VG9E$MAgyAfPjn)#6e^enivp}iGer>(+^q^GNPlOp`o#< zxuvzOy`!_MyQjCWf5OB`lc!9bHhsp-S+nQNoi~5M!bOXhEM2yI#mZHy*Q{N)e#6F1 zo40J;wtdIWUAy<}-M9b1!9$0S96fgY#K}{q&zwDX{=&sem#&lpTB(l_Wj4tU%&tS{r8{Z18;F3XiLz*!(wM0yyiOn?E(fKtTy7NJUj z0l|i_7(q)ODLmf-xqSk=dl0oPjVubPaj4fG0=1_>EnM`L83TBR6(Iw%mD2eSZ2m-U z4T9Dx!+Z+r(}U(>AUz_`$TC8Pn(jdOAK4|yq9C7x_F{oXu|TWEFAjWnf@)ZoAwk-PCJxC?U^`KrBs1* z^{qi+3_3FbbcQ%+)i+`^1k^`?jckDS&g6qvV?jnAVBrB7=RhAz2904r&P)LHyD{gP zK=Dgiegf$Rjmp4oqX6vy2Ca<+^==V%BKM3zF$YRZ*j1wY4|1MM9{8+i&P*! z{gvX>k}{U@7%^zn0W|Jb2|i;3v1gxn^$_zh=g0`e5BRRV;>`5C z#2iR(5>nEE#x6iRFObJLuorKr?%&btLG#3*<5rv>OprxvILcu3rr!c@)3V^~1gh3HP&)}!Gl0f((ba>@!KD^7 z{{p(J2$ar1=Zk=13RDV$)@DQ60;oD+DHUWU2!nRzCNgA#&qV{}R?r+A!aR@(pqUhy zE=c+Y)yzo@$i9d98WKk!b3tKO3?9J;&6>kZ1dUokW}86rkW^j-Ed@b0K!I*wMGsk+ z*`T>TQ2fDW6Cieh&gcZCGLZj4Ev$U#NOm>@dixIM2L%RDjs?|kh#X0c`~+&NfzlPo zkDz&aNW3DKMWAp2)dirM6I2F(W|cs71jy~6uuuTsK%h-tU^hCKKMWf(0Nau{*dkJ zkaP#hdFcLtg)L~uH}0?m`PdD7!xL-{8Pp$CVsHfSlmYd=VDrSF`8!A{4Vrld^%gJQs1-Reh}-C zh;=I2GSiM7sNB*t_MK-3t;sC z=*&1!Oy@Dc(g-M)Krsm8<4^VQdH{TO3TQM5)N+ONd_dzZp!9{UWO8FbEyrLr7`U#0 zueViT0FA_DgLhDuGvqPYfxHGzZ!p(^)Pn>;qrIS>IBNdDUMhinh@4)jmu~zSu-^)g zD_z5Ufj^8vv4L4XfLx6&WYf?>7FI(LqaLY_AfoO;4tH|Ob&$WX#}KGw0-25oH*(Ae z`4~}iK+a8or4#bagVh`i45|#E_Pqv!Dnkmm?+YqnAYur2qozk}_$!7(lDZK`eynpd3!b-l@c*lG1{h z#G>@F`0~u0l;p&slw!!xJa}Xe67R5`6rk}S(2fdFJb-Q}1?|2EjedYyh56ufR1xE_ zxbBMwwJ;#2g4!^cCPBttAhUL)-X9Md#{sRT2F)XY#^oXRgIi9()^p7$}Q_ zF=!-$W<{zHh8|e0KSU}bTUR61877ZG{*_yA<7|;MYzfnP@Ls4XfR;+3uu%W za!W}(1FHK$^9#8Ag)2_b!nQcIBsH%L8Y7_bO~_c70(c}AbpI*nWG&EW257bbG-3(q zK^247A4B|zIo}0JyNEgjq84%jGpN@EI_(VPV^A3f+R+0s1(fnZJrP8Sf;z{8JN%IQ zouKvkAQM389^?v0ISb+;rv^}(2gyQ8A?)@OXP*`W=oA}Je+*Xs;>*b(cWA*+bp+`E zxdeAUfZst5+LM=GoR*oFmJf|8kn_Of9-uZc`U(b+uR;BF&>SUb%n7s~2(-5okzV{5 zJQy6oW0s(C(0H(El#Zi=#`i(>C}q3$O^=mD(>0F9}GR%C`Q0#%)28eYm#QQ5ZKM$Hf zQ0)S(?+4|sG6vB64~T`&MpDZ|&P6{@s1kN|$R7>tYUF`7r zF(PCj>y$uuaDi3{fp%np=FUJPPoSMyAQyx9ARmKT=%A5zkWWE-V?cK>foA4Fz5&gm zq1QN|Q8P%r6~j;lu8%=s26F)BNUkF)C2I4_Nopf73eoX_n>>*)K;MQmF^Boq<7P*CcQYG?amX!3K$)fW&TrvO)8Ib9PN)@M8e2 z?_ywB0~H6I>3Lw+B!(#PDQyf4C!lOk1_p);yCyL>GkAc{XnOz^_W+$ox*H*`vm2rp zq&@&D4w@6L*p0Aj%5H=^cR<-7_gsLoeHa)RK0w(Z_i*fisCQyuV9Y8z>v3USJ%&%nS? z0A+*RHUr9b0mUhl?FI^SDBBfuHtGS0nV_(;fwDnyod9KnP62FyvO#WJ0A+*xbp*-= zg~<~r8x$`b2O(yH`gtl)HYm(}plr}Nu{lsSs24Ti;3S4%hA;+@+cq3Tgy9~r8b1b* z+m1llAal+ju|alUIXDS?q9BO<V916 zK>h`_IYD(NXpJViSrA`=Mod6$08nceR0A`zep2oXZM7~u?Z z3#J-S7&4%RF3fDmX)@UKLBbSMA4nV&vq@mrLBb#1PEbD?*K44{#%H1LV55EC%X0EH_kUO_XgpcJ9NP{{ykpMh2^fm%11dP4O0xF##ZUTj983V{1OnFd9gH}C) z@&UT}pdK`+O$M6Lg6PJkA2dDzI!Of7YXXg)fKnW$I?$<>kiIZP4d{FqP^v>-9gWS8 zpne+Y#9)yAA_h!zL93WStEfP62Ri=;mpV}BLi!1yoDEvljA<66Yz38UpwNe{hd~Wb zP%Q!)M}g!LOfx`zbI_P3Xf-D`|A1l!q!(lZ#7&rHKx_onJlMk$B#+P!IR_a%?m&AZ zKxcSja|0;MLF161*)dqG+19Wy1?3Y^*#Sv^ zkdZ5p9B6b2aX}+Mpd1AnO9IV7fogwHT!VUpFts2)s4mn+s#!rbYB_^0*alGg zf~kd-|DbbVAgg0Q?gF_Sl%I>h=PN^MahMqB>~GM@MbMZ($Sd{+e<0T_pt>KFcR;2i#6k5es1$~U8nSs1U%~W1%3e@P1fBg28Z`i|^8}>^ zMBM}G(SpJY)OG;r2Kg|Z0hGHyHyJ?o_95g!E2kj23zBQ7J3a&|(?P59V6zj5Rt;$G z32{aW^7shq*eJ0kz~+rXbs=O#8#J$$!%zU7Cx)z_0*yF==7fD15O%}vMF)*bgVy#z zS}getX$%?+S_~l9fZ`k!s-SRAV*uR*1uDBB`BZ~}6gxnx#US%xpphq#ji3_^LG4A@ zhzV$IJ}5pwb5Ed?Wk4kkD37Ev;Bqr${Q_v*6*PN7nR%eGamY*yVw?bCK5^j+8rK4q zp#cn_o32v9>z$|>rs(Elh9_v{45%fS#$W+mcWw$j+X*HLDp!5Lt@v~Xka>`p1)Xc} z$^aUb$z=!tpKF%P;L1?JfIVGN7RsP_Cnr=WvlTO}Kq(hFRYCFyq`UyR5fbyTl!Z?< zdb)vyFR1vCM0*f9CE8;0YeP*-cQhN=b%w&P+J4!Q$&pb zsmnpGg4E(5S%MaulO6x6zd$8MwaF0AQ=#*_r?E}^1Apd~I<&7CE7|a+z zEYRthsSFkj=HSs%&|Dv+ZUD`MfO_yCU7-CzpcCjIz6PlQ)lZ=HC!pEs9OxN##S9u? zSO&fm8`M(JV$cNdd;q0(h#x_7Z$%6_;8GgYwk~D>-9!j#QPeRQFjRog=`&!kfYP8E z3uGs$@eZmFKqiA~PsIEfsAmFddw|+hpw?Rq14IO*IvMPH&>3MM`#^JbNerMnQb0Y5 zcm_}p4RSL8s8s~=H+|A6WcCRZXP{XU(0n^=za6p+Xg@J%e;BA&2686dtE0Y*N zcTWjinFKzkT;j?k1{To0QdcH{@5M5>G6{TMy~UMD;PcTPu1o@-Ldmg(0J|DNerqW|6iTNpvJ(!pmB8)_`GI=tCPUBwZ+v* z;5)Azu1;dm2Hp92brORP0|P_A)kzGx3=9krS0Q)1C0v~ZK0hGi>Ldnp(75r{N#HY{ zE3Qsruw-ChXt+8Fyz;u^>Ldnx1_p)+S0^zzFfcI8xH^deG`_gtDrh{Ffnmi}(0DBa z!-lJ%@pJ};9alkPlMD<8u7bwA85mAnox}hdx4&=|G_J|OaN{ayjFo}m!PQCNam^Q3 zL1U#13?HseVgQW=|F}Ad0kkHF;TmX6l!1Zc+9U>0iV(Oqi2=0fxkG6p10xFqgT%E- z3`{Hx3@X8w&%2$F)fe>?{lnA=f4`aIi2i zBwU-sz{$b@zT1hLg@GaG+9U=Z76yijYm*pwSr`~vu1#X#V_{&JaBUI;KMMoHoNJR9 z1XvgtR$QCJAjrbN09xxL#KHhx>mysGNSr`~*T%W|C$-=;}ysFCSr`}|T%W|C&%(g)=K3TCBNhgRAJ-=_n6NM~u-ur$V9LV4AaG+6 zgBc40gUpRd4CX8h3>r5kF<7uLFqqt!#9+z7z~FFW5`z^B1B1_vNetF33=9!BCNbEt zFfgRtn8aYu!oW~)V-kY{3j;&VjY$lSEDQ`CHzqMSvoJ7BxiN{sg@u7(&5cP6uAuO| zF^Rzq6n{4+F}SlZFkHAXiNTYFf#J@LNeo^r3=A)BOk(h6VPN=jV-kZ8r~tS*iNTMB zfr01dBnE#_dbl}>Apn#fZcbtd0;PwWlNiE4>EPxhhHy|ixH*X-3go_60|U>k zNer?a3=Ar_CNb!6FfbV0n#5qu!NA~gYZ8MU2LnUMtw{{d91IKzwZVPIGS(l5fmumPlBgn{7%NWTOF!wryn2?mBIAoUUq3?D%1B^Vg~fYeJc zFmT+N#9%GKz@Ttv5(A?Q1B1bxNerAa3=B4RCNXfyFfe%BnZzI^!@v*%QYXW}kONYu zz`#%gQm4Sc&;e4Xz`!sCB(K20umB{l!oaWrB(K82um>cs!oY9>B(K82a0Mi*}S3M391Spm_Y z79NBK-QEToH-@MKjfH^3L30Nn8Z<@&qVvEl4ait9h!2{TfzXhnBS5V!5Fa*H2f8N; z#0Rx?Aao&!VkidRqy}173z{tg(GdTF#^^u_G8sT4ULgOcg18KzJ?9_>X#FIJ&VlOB zVSv~R>J5R!LF2+8IsbGcq!D}5~%&4F-(v+XbcoYgGTotG{pU&Jx?HhE(64$keLindl?cx zps{<9JSdz&qi3Ldoj@uhr4tYvWIiaZfb0UP0i_p^e?jgqW+-IPWpD(W14=g_agbj? zBa6BWAq=27ZBQQo#0KdFr6G{LAibb;1ac>6-WN1J3%Z{U)W!kLWrExTny&_>Es&X@ zIbBft0);2Yd{7$GW$*#FT|ns!#0L2nl-59Ig6smNH(iD>@H{an&4JtrnpX#zaY1P=B;xXKsSB)g7@=-dQ7l*0i|t_y&%7X(l=<`HYm-2(m03> znv(~ma}XP3J}9k&!VTRoptKK*yCkstL1+Ge#*9H}62b=M2bg<6c>=+Pq%n{?L3slv zp34BbtqY2xgVrA8GH*GX!aa5p9azk30p`$g6RN_9al1dQg|=} z$k(9xUeH-xAX7jsQwH!#@hWhx0;OC~Ixc2_g*B*e2MRk-7(w!(Cqp1;y$S=!51_Ib zRK9}Z58{qg@SS+R44|7qK;+bEb_avq0V&6Pz-1A{ZipQayWPQVg4qo!6CmY@6Vx5K3|a7! z31){211L@*c7V=yfceh{yuJfshaXrC#17C(LReV|aR;am4vJq#j5vbW2Z;fgeV{e^ zu(aX{_ASKR0I(Y&ZubSp03_T%ZbvOYiox@-pwtLSr;zj*0*+gVdm&{7#9S9}nnE@U zH4Z@I8=%+$rB0X|{lT|`Ld^1lvO#$v4D4Qz{U9DB=3sgv!Ez8i&fqmn5c{2>_Cs)fQ~tUW<$O_oy0Jkfq{YN*(7jFNdP*=q4I1J1L%%i(AW;>Kv08c zkg)`tXOkFeL1P!sCNY5S_6CjlfX09lo`KetF))C}d_Y~moM(`+hKgsC7}^;a7(in{ zpu5sro`KeGF))C}fPE zSgt|FHqJbo#Lx}0A3COV=NV)S12mQd>e9V!MNepK}0sVXu!y1tPo=;*p z2^yn$K8axx0|SG~^GOW57#J7~o=;*p3RiP1o=;*p#lXO@ z<@qFrtss9qpTuwww9f4LB!(-XF{kH~7(jQWKY2chVJ&E^>G>pv`wR>Wf1Xcbn9RVy z!0}=d!voO0h%Y8F>;{b~y_m!RxNHN2PvUhf4OdjpNd^}Lt_ z&QqYVCOy!Y(u+w9pdJNiOb&Ff`;r%v7^W~VFl=}+iD4-N1H+ydlNi>4#?)R+0+%&c zUQA-x#=yYv;Kd|{J)p5O=vdX87n2w|K;Zx#)B5oOGG+uC;{)CQ&hip6_5>Q+(g(%& z%SqstIcSVd0(3|H%SjCDL1St!A!ARVF+tGTBPK5)V^tnkCoyP%^3zMu9ybOC&=?(P z?9S&Us4vFA02(_4-SZgn5;CR*8bbt)DW<%f#4r_<&t6Ufw+TRFilBQ0YhF$Q=kWsQ z*j&fUN#K@0Xspc;l>c5%0?(s?#>}ih`S9f=h9*#WLB}RRV`QMQxiv2*F?52$=_P2b zA!LjWbZf+h9j_)a)Pd3ibnJD?E67+OXv`IKpW=d7kTJtGuO>0f0F_U# zCNcDY(#xw!4D&(x;MF9C6`*th9jkruY7)5J1sbCTt&{xnY7)5228~79fb#R}Ner!^ z{QP*q!h7K>7OhB!(TJ@OnLo;WQ{7Ur%B<4hm1`Sn-P2lNe$^`Sb21hR2|M{dy9^ zAqED9Gp{Ex>}6nJc=CD@!!nTk>q!hVLFFuTY+2;ZB!*d_{P<=PLo6trT%E*V3|d3| zW)ipu3K~NNjon(jnZ(cq3K!^Dug9B73=Iqn44|=D(3o$?n@J3fp!kN4RVTce#1IF% zFXPQ522jrgG)4^?yRLXMi2=0d3pD0y%D}+T@@5i44JiE`gp6TNcr%G12^5Z3A!FQg z-b`Xh0LAasN#J|3SG<|TFb@sWfFv)0uCn#8?>te)@I2B*QXHiEU=p(>}+uQhOl$Meuc3?Yla|fP`e3c z4ro3W#x6v152(ii69@I?VQf%O55@-F)dFIJTHcTzBd9+EntcKVF+>DHf>s;iOGJ7@$0)b;`O&p@k~ zKx~j(L2D;r>?CkJLE3R3SHi@T!Epc)2i->v69=872V-Y}%QT1@$Z94Cy8xUHAZ$=? z6{a4vG7H9rq#=l!DsbFG+H0Vg2C0FBBPh*6#6kCz!o)#yj0iTU^#)M`T2}-U2hGnR z*r0HSs7VLcPY`wnI1fVDx!`&M!UnBrg6V~fFhRsYt85VB2zxBdXaof$4(caD z;tL`UT9*S82Z_Mgpmnw|b}qPW2paQ(rA5d%0VM5$#w2yYYehlhParqI#6fm}(lkgM z#0K^7Kx~lvK{sH7*r0R_T5$&&%S>SanFAV0gp6H*NRT+l?+|xF`s5&z0lK$63tYZH z##cbAG(daXLE|*p;PeR@tAMx%HpT$qfz*M*C>vbQL&j3F!F4iZ>?*hKum@7oIoT<9OP%1I3!(y%5F&iJ{KIvkTD++2^zxyjm3dh z_JY_TGa+#X8G8VcAaPJWgsB0U3CRzj)CLMWkok~tJP-*Q+X00gX!RkC4H~gPjGutk zP=m@YSf3t}`VsPwlnc5O6%(eKIJ;BKQzp5I$%;0AeD7k1P)g8Hnu=c~Iye_=OCh z6^fwI7D)dZlrD7{kjrmmapdwFA`V)8icLL4992Ci%|L7hS8MvH-jBi5hh4g_zc@b1HGB6<zYPTo&sUWswdDo3)uOZkTtg0R*Qkwv?PO1yTc`me4YxZHxDXfK;;W1;RIR_4cg}q zsvAKkJ%Gwq#5y6!njM%ps65PI0G+;vZBHx6zm&xr>RK8|*n#TQWQJUZ0<`!+mxZjU zDPq9yzIf>QiU?CduBJ2`QQZyUA#6Z|CTN`#x-7)qpwNe`;e?&_3>s5Mzq1-$FJvD! z`h5|g^D#i}BhYE3pgf%pT|)|6`vmeaW$^^cU$Arovkl=(P%9JU9}o@6MUdUkpI@Ks)7Ob|CL9N3{!82WUS! zvK^pS2WbC3Xhjrg-8ZPz0_g{ZTReCd5J)tQ0VWPQrxU@0AKx@SyE`zBC z-5UuCBLxO*w_t*1w?Hc!A#n&g!3(r@3e-LU)nd3-xq-q9RLX$X2ZGK70ku0obw~jN z==2a=x(vAU? zoqpnX1|QUP=Vj|KxM^gz4uK&RO#Fo5)eav12`XjB={ znUtV%7qVZ%5WFrBl%_$w3*4!i()tKJ9FrM9xe~N@06Biq!w}>qPlOeKsBNp1L!?s5jIo~^m7DFT7&ndfzlRoI}X|ZAU`AXF~bAo{$LFAgQ;phD12Pd!UwdD z0@SktrEyTn0xCm5t9ub=`ysm(mXbl`q!Re-Ur-$gDp5hJtU-IRKz9S@f$x+7?P>$< z9RrOMq%v4Dfa;HYhI9r)a9smha{<}cnS#>#0QEET89+G>xh)w~6GHY-WP(o+0*xtwMpGCVAoqKKPSOU&QzCdY0_0EhTaj?dLhe8U zjnslt6ZP|-F@q7fF9E8pl90-=WCoB7sLcmDpT&@&lmWyBg^31(IrK()>~03_gaP&G zAuG;7Aqi<2fOh}nfcJBO^g(<>ZU2Dm1oezSy`p3!-+=lDh1s73&laoEdrLgqp04^XKF3R!g5gWAoY8Vr&fKs{K{Cv z-F1+(3@VR6wG%`QEFC~ZA^8^OR!}_v>*+%52c;a4jp+=avr<9j3TS13FL-U3D+8z< z1T#+rGe4!1Ni)d><*A(*)vaUbnA9U{YA7ovB&c8|Eb^QhZAnW=o{!L;i z&ddWZd`!+S2Gb>p5Po7wBB+_l0HQ&u6Lduv=z1=YaB^xUIHJ;W^7BFIE-f($)a_x& z%})U@X3R+e-R#A{5T6W@h|j1j$S+}FNXyL!4S_PG6+z`I4H)7p4H@Dq^BCfD^3y@{ zIq`X^6(xyjC8;2TVUfWAyPNFCe+YOFTBZ-0t%0ckO)-Jk4FWEZJsqI!1)vE-+&K!Q zoEGH=D7Qe$k7A?}1eSl1b1&$0FVGk>Xzw1VW&pVebUqg(cf)ccm;l8Y zr2Ig%GGXH_2)TF$?C}XISwZD7wpt8Z`RT-fsM}#-ufTv_8WUT(Bbx@%11jA?<2C4h z1GP&)ttn7S#9kI7n+0+iYTSY5`ar#TP#+t+Um<<~rM_GSSn7tgqbciOf%04m`0Su0 zh8TuI22g()RF5O#3n2#DGYlCu1)V1Y@(0Kbpq>S2EDn1fA=qck$p@d?nUkEGSO7V7 z4|?JrYEKQ+n!^@0l%`vd{}FrjATbLWr^{zRAOA&{1*KYWaSpz@2~k6WZZN~{R#@6c z*Z|QF%Ab_SBf=jLUm%c#l~aVbqy*7LApTe#bLfi?y-UHHw5j@ErOmdirkw;*bXY6 zKz$R?d~XJLS1Ga_a+wY4^&!iFd;{7A3K{1Dod*x;?^8RzAt@7d&ITwaB4Qhs-e58y zpMdN}7YB)f&M5_j7o;T!%IBcbVn~lofdMqy3A)V%l*S~3m68Jo+LnBhj0kkR}G)}AnG91)5 zU;wRC0QL7lbtQ-fjqqX*1z0T)3MWwh1(gEGeSc8h1Dhj()kl<-qaYKJ#~VR83skzG z_tH`OwYm&;&=X!kE(Dc0AQ8~GMJYHpfbyRn11R@V))xku3MpTxWe=#Xg0wCm=7MGl zK=btE_y;tr3K=^B#TRIt9kluamL5PSH^ei5Qi2y>3uj2hszE#5^d6U@sRyEhf->4roRTdnyLyHBdT&_2MBdV(g|t z#v!n~72>af3l~!20FoO)A&JfBpiVESv`36a!1^zsl!HH~LyHjx$hq#Hv9Q22nx z+#xey=<-Hjc~CnNlHSqfA^Jh``1FHXybu>qR?Z;jHqbf-P$~oE7*MEy{12*UK`jT= z_71_i2HciT&d)7KEJ{UbO+(xaB4KxkgV-Pp85iJZfYBf^h6A@jOP3iyv;cVMpx+5b zgT@E`|NjpfM`!@k74rjxT`t>4Y!;F?d@m1LiVQXaVjhA73&M#H5c3&eG+YA8Fo0}g zVt~=GyVXC`gZ3gYFd*ok=cXSM=`?k)ZPZNRoXl|`w8b>5;iT$;OQzHAFlGI*|2|Wq zZvJX92h)w^cRp2p+Rx#rw?C&U3Ti*pI?$!;ARmFa4gde&S$=(IYg*w(UeLl^1_p-z z|9Kt0n>q8$ko-3FFI49PduGUB3`h?HXdCu{4Z*%r184b$$eE0|(0 z`*0#p#UD#s1_rx6y<4;Fr3&)qU6eMpWjGM|{l?k__6r#pI0Ln$Z5bGnkA45O*xvqY zJuD56 z%xxJGjy9-I-eUiGY0}v>NAztO8eYZ~vu?AWU%OEG{9$ohh6P@|<=NZqtMV2IyTZ5bR?l(rb}vNsJ+H!1jNX3Nm9JY?I{-S)@*%2eX`G;J9k zykt^)wa5PSX}u=Ri?3}M7UUe<;(83<+5qS$p@}FE8J|Xlb98ErWv1 z(b>5N>|K97eAnA(1PaeJcDx7e*L`R{?b;=0%W$DY)PBc7`z!w^f0X2Av}L&9&-yR$ zko|#j4F}FO|7;i@e33Eue#qW2S&H}gR|8vyfJ**?DTnP-ili#-U&`AuEZ7oUqItyL z#Cy+C&U2vf`1ecY)Dio@jAu^H3VOB-2Ao2rNk{E<#aC^9bKk(0f#I8!)Tg8N!ijde z((mnU85kyrE$TgHe_`gdKRQ$1+AuI^&npWw`MC{r$+3_D>)DuVPYA zv1K@L$zA^CNqYsAPdR+XrnU?Y%-u`!PTAK-Ywuk1+Sr!iL(tLf45#gjSEcx5ezCP> zDEL|PtmCwO(Siyk<^M*u3=Vp`9rPwhRJ)S4Yl2YhRpmeUEarf-OTrU68HVIr}G*^*&|JHMC_|z;s7v z);at3kBt+)zE-ehm@uU*LjJrx!vyhHuh+BNG8EjFZ7wzj>{wLX;x3y*1VI_L|!$tf1d_2l}5$d)K9!~yzYM1PP$}iCn zs1vnis1RJ1lyu2nNRmfSYJ-q1!wu&Hg)=VMSDMdTlWD1K%h14GcJS&Y`~4jJ`|iE6 zvSl#Xy?iszWqYF=+azaBvan^qR$e2O_uyh85L*62=?^b%flDeF{h$HDhtUV*A$%CU zVBbx!dKldh3*p1)0A>guMk}nm0ag#AAA~~qFk0jPb+9~)PFN4&!{{0D5I&5)zz^ZW z=!V1B!1`hIiYf>nMqe<5@L_bpo2y{;Fj`DPB4#J1g9)1u$jNTy&;ltS2=mJj&A4VTggYaSW3CzT?JQV7j6N_O!iUiTkq|zNejo+m z!{~&^XTbVl^oJ!7K8!BNh45iCgFb{0qZ_`T2J45>3g<(2^mYA&4Q9!J2`I!JYxMb0CaCm_dv|oWX%1oI!{|gh7-+kb##Wflu6)vKe|A z)-V_`6f+nzFflMP1TvH`faZ-w8F&~3!QmjlAj!bXzyn9JbAkjT)?u!zB(A&sGfVL5{(Lj*$=!%PM{hFFGrhItIm3`q$+!zqS83<(UN{f$2v5*a2loM8CHkiu}9A&FrM!%2qU4Dk#T8ICdhU@!rP zdn&^jhS?0l41~hnlwl5oJVP48S!lSYGn`{EW0(sL_Y8*fDB*6-Fb^r*GZ`)*g}Vhq z7Q=joiwu?wP7L1QTvWnP%h1NKfMF%WCWhS%ml$p{JYjgtV8xKbu#n+0gB?Qw!%~Lp z49*Ot467LKFt{^RGOS~Gz~IAB$FP~+-LA& zsA1U1@R-4$p^;%5!wZIBhE|4M3~v}B7`hntGkj!-Vd!Hx%ZK5hDQuCj2R4z816GjGG;O?W_Z9L#hAnJ zm?4W{3ByAMX~uMhg$(x?Bp4y_pUd!sVKq_lzlK4cA&=oHH2(7$o-vp)tOdt^0mE~& z_+N(<|Ah=MP~yLcVLii320MldhOG?m8N3-<84fZ0VX$NF+4B-qD8O||qFeWg}Vz|yA$Y{k-!myFyHG>mF4Z}``&kXJijSTx3elYkm zbb@x^Ge$6gPHy02Ok|kNaDzdJ(VC%@VH3j}24{v^hFuI_7(5u781^&#WC&pBVmQvg z$Qa2mnc)Hh7h@8`9EO_=!i+WyWel4c-ZHo_)G_R4_{!kP(9Cdv;TJ<7LpQ?-1}4TR zhA9je8Mqmf8RjzFVh~}pWhiIZ!tjp4m7$(t55qSGFNPL|gABhJf*5)jPBJhvMl(!h zxWvH2n8GlR;WmRPWFQ5aesUSsGkjq%!$?2d7`8L)VA#p9iy@C;1H)GabH-wZtqi{y zY#0j|HZgo>uw*P`*v#;Q!HThj;WtAO!xo004AzYK3>z7~F<3y;PbtG6hTTM^pFIrn z3}p;|q3Nfb;U9w;!(MRusbKhzmVWjjrJqU$21ZZ~3MscO7^)cdGcYpRGc+mJHPl2N;+b-55F;&NA>b1~W`$xWypDn82`z z;W>jQqa8y7!%+ryMsJ2*hD!`0j1dg8816GDGNv*tXL!S)$7sb+!*Gy+nbDo0li?hL z0AmQlG=|#@vW$rgiy2-pXfawd)G{1mU}1D%Xks|dz{%*$(8_R%frrt9p^M=>gCL_X zLqEe61~J9}2GEHSl8m7Y(;4nC$T3DS%wc%Qpv)M{FrVQGgBoKJ!xDy<4BCw83@aJl zF&HprF|1+u$Y9K9!%)X?n1Pkik)fI41OpeN3qu>jX$D?KPlj%W3k*Vxehd>Bt}=)- z1~N=$xWORB7{)Mz;Vy$bV>H8DhDQu4jByML7@jhyGbS@EWq8G)!d_{?C6 zlKv_gjx$IwrZJ+IU*{OkGhAS}$Z(0Fis1xbJ;PZBImR5u8irF0(u|pmwG5{j zWEis;8yMsn>ln^3$TDU#Rx_MrkYdb$roTo81;)!nrN1i-@(fK3ij0tULoPlkgG(-{I8O&R+cgcw~JTo{)!Ok+r72x81*Fk|#$6l8Q^$Yxm2@Rgy6!Jna! zVK2is24==}4DJj&84?&G7*iOW7=s!77;PAR8UHXWWQbv$%n-!D%lLwUh0%mDkujQa zF~f5PBSr_tJq&z|pc8Dk7~>cj7(*GRGL$gvXIQ}Sj)93WfYFfgKSKn=1BPUVV8&+* zPZ%CE2rzzP_{d<-_>#e#F^$2CVGDyWqZ7j+h8Ya5jB6OaGkjrSWh`Zw$FPhciP4*3 z0z(di1!Ek;E(U$Z0ESl#kqn0!3K&8dw=zUB+A_K^iZH%sSk6$!V9Dslkj&`L_?KZH z!v+R^#teoehM5fM450hLxEVzme=s~`U}N0I5W+Bv;WdLl;|d0E#v=@&j6WF`F&HyW zVTfg9XLMv_Wc z1><9)()SYvd4?_qOKAG;X0T#3V|WTq-#rZ0XzBYIQu^*?ut7=ReGJbTY#HqtJQ-pb zLKuS>To|V^Br?ut@MB!c5X88NVKKu$2499142+C38NwMY8GbOlWAJDA!>|l|e)~y= zR0eLweugCsp^X0-f*E%+R502x`Z0JgW-%5sykPjm@Rvb}QH0Ts!HQuXg9}3}!)6A1 z#wiRd8D=qfFf=lHGWs$`Fs3mCGfZH3$>7Xb!|<8m07DYvTLuS)?+m9HE;3AGC}Hqt z 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

Bs`L&0;j9dBl{{IzU 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ͱOh?UI(-oFaE^%s{~ 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 z�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%0D3%;#Jnbeb)pw~|Gm zbQaSySw+VC^B5Tf6Ak{`tX}wUm8{plj%{-Pczi_vdCgb(w`P^gzk-E%|0eLw{kLt` z>3=#)zyEu4P40i6i^G4GS<(ONMGF7(2Q~h;)bIUox@hYEuZw2?=M-J=|NZX8|67fg z|DW}8)qg|H_5Wi;xBOqRW#@m%@B9C6-FxhR`Gd3n3rw#5SM9&^Kj75k{}YeA`Y)UO z@qf>R@BcGx|NhsHV`7;5nvG%411^RRYd(gk-vSIQO2Q01n?x8|H;FRb)(~TmkQZZM zTOi7?ZifiN-ZEhZ&zFJ>-0}hplIna6ru;k%%bsvDoZQ6DVAR6O(3Z%|a6O2TVO!k) z|1-P){{MaN_y2iuzy3G#|NQ^z+xP#XlHdPxSAF}hFZ1pH2ZnF|bJf57H|zcO-&FVe z|4j@({?GdN^L!?TK2v4} z_0`M_`L;F;p5cF}#?_$Z+K$14FVp14Di0|Nr~f|NGy}^zZ+&%)kFD-u(IBHsR0zt&xBJ z2YCMZ-yHYn|Fx-q{`0^3^Isz5?|-c`fB%2-{P+LT(SQHHTKxZ?H1GfaGoSwdw=rd4 zXh>sVNa|!@*tL*>A#w`?!^@)#3}FflkEVq{>-VPsg!$jGpzgMlH8gMlHWK>g%729c%<2Sg@bJMeDP1BU%t?{qd? z{j1>Z#n({9DCe-WN&CR#K2wGpF4hMwS=t0R`BK0jTAIi(-zAhG#L|bM=DjP!ubYkx&dK%+mS1fdUh~;9XgS+3 z*t%FV#NW1LIQG_@VQYaY!D{s{r}H9?a%-H>wf-UZTbEGM7yv55AXZ@|JROB{|!|?{nz>V z@qdEqr~l%!KKpwH! zpa1tQ{{DYZ{_p>(6aW7UsWUSC>|kOz`G}c;LzR`G#DR_Bxe7Z&>rr-wwc;EM%fvVs zJ{)9c_#n^DU~A3Bps2#i@c#`n!@E^X47&>%8GJ(+7~UlO2cN6(U;5ww+h_m&zq;Y? z|E;_J{tvzT_rDR>zyIDw|Nbxa{P+Kn+rR&UYXANxKL7jw>V&`lpJ@O6FL3P7|6RF% z{>vEs`Ttb@&wo$HKmXNc|M`DG_wRqF&wu~3KK%E;^ZEb(%wHK87JX%8xOI(*;b1#6 zgY+L}1{EC^hBaa=44eKjGrV2O&G5ieh+)bjF$OtN2?moF!VDXpu`^V@{qX-u$?5+x z)sz39`RVeX;o0qf1s6j8NxWF|muLT@KQr{d{WfrV`OD$p{+~1a8-6gj8h{**W1eG;F*v`M@V{3>}E zetK{(Sjxa<@O~XfL{~if0zNsmjtieyKIA@OUb5*MlgmnNrdy`XjK@CxX5f>a%rMKz zm7z73k3li$)&KYZulz4taq7SP^W*=^Kb`y^+j#E(!`GMp^E2K2uPJ`_zwf2{|Eu&L z{;v*t_@Ax)!TfL{r`3fkN$^0dh%cL&GY}vCa?c5-0<%I4gXL7*Z=$af7ha)|4%9X z{m-7n!0^F?nL+X(D?|ETb_Rb_PKGpXE{5#oTnv|XaWO2b8JI*LeK>zvle!|3>w{{zv8i{QqIokN-XqKmMOg`SG9O`j7vw7ytafeAlo4PRxJ) zuS@>>zkmO~|E+)j|NqIx$guqkBf}0?CI-7ACI*1e;J-l{}=9C`(H41#sBHa z3;##S&-kCD(DVO?O6~tQKH2~G7=-_qJNp_5kC&pPy1o< znEU4e$>l!|E)D)`QKjV@&AW) z&Hty2i~cWZ-1GmF=ehr>$8Y}6`~Tqox8+a&@Bjbe|DsQ?{~us`|Nltar~jN)-~P9q z{q;Z9@Be?UGt3OT`8gO8zj8Cw$MG|iISDcRoh!nyzgCPv_^miY_CE=R@4F=#dJLo( zjz&u{)Y?cfB%F|B==d(dV6#u0!A(MpL5x|1A);N7L2MHr!?xMn42$A97;Y=DGHhdD zVh~dL|37%apa0t?{rZ2N<>!Ci-{1eY=6?S#<@f!6UhDV&R=>XgpVho)S^w+*m-WB?f0g+Cf92ud|F>@b^FQ?Q z-~aR7{{OE&$-s~j!o+a?G&92@QC0>yNj8Q*huIi*aI!NbK4)VnNn~Sq(aOqDl)=LA zU5S}t{{=<{$vy^#^5XyheW(8Wugvi8|D2tF|Eur&`+pkqzyD;M1v zk_-%5MGOo!QyCcERxvO{D>E>-P5uA>_q~7rO@;sc-{SH2ztglo|E~-F`M>?l@Bbo~ zfB(18{PVxy%%A^zHvawZc;esx;-CNjFVbOTVDn&N=rLhtIChVjLBNWIq1J(gVg46p zhUC(J{{_l^|G&NU$A9stZ~qU}fBC<{`t$#n(?9+9oc8JePW{jSmqvW~Kaug9whP*g=#!qhp7&myeGWJC7WSn;V1!Id8AJcSLrLQIg2yUf4%FUzpYW&uRYI53Q->0phYs5&-%ntX ze3-Ds?3n|{qjwp9r~N9po651^ERT4DiLB~@AT>jVz=xI$z7ci~t}J#A=k8iGEQ-@_ zcw4O0us%sRLv<1J1eOh79{hUpydmEAUc;K68wXyVxz@n8|3(APin|BC)IC|SnE%a$ z9IekC&yW3Bva9EhNT>9FlNJWXfc0@qJokN>kHkD+p0QA!Wx@?37Ka)E77N9*%qiw2 z%qOh)nR`r^F|Ba7XZj>_pYhJN4#qo=Y#BrJ|1$){ongq!U&1hvwT)qOaXv#BZ#+Y- zRxpEhycfgCLT85XYFmc>i{=ciqDBns#dH`JTvuhVDUfH_$}h>F{8)%#gCsA5{UvsW z9m>oMy9EFLkDKxP|Fxw*{#U4f`=7-6<-fPyr~kVrefa-X_x=Bx|8M^v5P18aJNM21 zyDD$~C%C@(|NGXP|A$|`{lBl^{r`lNkN>?lfBrA-{Oy0~w;%tPt^WOA+4%Y3wum5l3fBm;O{_FqNoZtVY9sm3J8y7sxz7CO zsXg|;J?6mwy?=K6m#kU;f5DnX|92Qq{2x?T`Jd-|iZF6fk% zV9*HWPH9a1v%qBGn*(q9?=n1Ia=}4b^*F=nzXuuitT=dJy4*2`;v44a~w}$O;{o+n4oo3(!uYs+yUoIg$KR|OCmn~{Z=XQFX_6+ zKb=Rl|11nP|BLH;`p@!$(Ep`JEdSg8iv0h6N%8*;N$vkv$WQzK{>g&>>yE7WAG~AT z|8Fxk|DVmfkeeD0YgfstVWM2BuIs3-{qT~1eD;|9Ezb*OIf3C^z z|ED;9`LCSy{{NpR#l*ldgM}gWJR1Y^DGr8rJzNZK;yetADZC8(v-ub} zRrne9H}f;dw(v9bDDpGRh~;DGu;XQ5yTHw`Q<00|iW>(5PY4^sqBs@?pDHGXlpPEV zscQfKZ#w(;|F2Dd{-3_~`~OkX-~W%F{PllT*RTK6@_+q5n*Zzn{N`W(6_)<`pL*ff z|32p5|F_uv{vY1_`~U09zyAvx|M@Sx_|JbG)xZB8cmDm~8T;@5RKEZJbC3W3|E7_F z!OEPG!T$jxLuVNigZ>vL2KyI(|8H3T?|;;i|Nld`Ffd4*V`P|qpNV1SEoKJC%`6P_ zlUW%AU$Qdnb7Nz;(8$IhxR{M0WfL2N`3^RQcRSb^-fUxIShbFg;n_?!hHW`)41Xor z82l!(GB_MzVQ5&w%;2ZV#PH3Bf#IOwzyAhxzyFIa{P91z=j;E85ug6Y%f0`v`Rnz6 zH`bT`d7_^EPvd>^U%}+j|Lb=i{GTHB;Qy9a_y7B+JoxX>`SAbh#K-@G-aq|+)8yrU zL+!W!RZo8WKjZti|KDf*`Tw<@i6Lkr2g8p#K86S-5eEK1Nrrt4atu-~N(`5C)EJ(! zX)`$eF<>xgw`A}LbYs{X9Lb>kx`bi=oY@S!q%JV{ycA)a6q>^r_x(C!$?^y$jfZcU zQqD|eW@zzY;RxYjRd{fQ^~RBAwt`A!c7=s=*cBA-u-|xgmi$i0E87eY+?=iHV5zU* z@cx`A!)<=J{oK*kev-!}UjQvv>T>h6ZH(Uu}b%=Ci`{19(Hesa%TSCra)*b() zSOreEvLx(z!#rV681tR-lT253doa~8UT1U)FJ-)SUYRj=`a_0|erp+IwOSce&C?nB zO9C0h8J!pk)XW*0i}V>%wrVoG5U4t(-ItLn*r zOR1;-eKeo_PnrMxziH9S|Ieqs{vZA4?f=hHKm1P#{QUo{%(wqvp8oh>H~aU0Kiz-- z`+6A|-fm!Gu#SjNku7FaQ3Z7x?FY z!Tmq~b1MG+za;+ezsb&j{~IFy|DUPOz%a9ffuV3W1H-i+3=A){7#Xwz85ut2Ffx2= zU}T7z$jIUt)RKiErk{nO z{|pPmr{^pT_iwT=l+R&dXwqR}i0fo#DBjA%uwpACL()VBhPi?N|1V_t_y5C+KmY%Q z{Qhss_v`=fJ3s#aJ^uawk}Kc-?_vA)-z)L!|H5Zq{uj*n^1rY0%l|JuU;am4`|`gx z>g)dva^LV~FD8Vo=WDWq5u< zfI(DBgrV3)oPpgyisAK98HR7~;G_wOy3Kja880%5rXotD9LFrn>$AzpeSlf7aVNeA$Ny(qW8FZVwBUr_15|9=rX|A!r1|G(k&!vB7%egBtFF8a@6>-&F#xy=7- z`|th}sGacd++5>-35Li2+F1MiEm1i7CuXAQ9}bblzc-|a{N`|+^ef|$(ytAjw|?GG zWBFCE`pYkmU)TR^E86{k%CiZ~0gMJ54WA=;8{X{@YB>E~+~NH+8HR-(3Jr6YD=}!M zDIW;(QEE7EBhO%NA(h|}C;UO{E!Tu)c8nLQ4}UwL{`a**X4yjrq21RTdi~EgoLF(< zzy*~f2kx*OYB-Z|=)hW^qX!t?bj+?M0q zu<{4bf^-1^1>p!GhLTgl4{l_MB-FczELfK*+%WNzpu@f2{0m~2@@|L|;QpW&$HB00 z9qXK(a?JnRk25$p?EUv;GT+}HF-Lw|^gR6aBRBci1P!NO6FLfiRlIxn>q1rIZv_+E zKMV;>e@kZW|7)h7_V3L8SN}Ht@cRE@+Jyi2+>ZR;mizMm>B~$ENA3zS6z!E}a1NJe z&<>Voc*7&h5V1g#VZ~!n2Fns5hOq7Y4F1n~8M4HA8UESxGW>VqV_^Hn&u~vwh~eE_ z5e8i?afV;BB^mNgNi(QUm1PKfEXN?dRG#7bMR|tl8S)I8d2$TAZ)F(TK1(qqPL^QM zeIUy4|D6!S%Pag0mzVJ{SXOW{=tQ$IB*Zf_Bu-*r`0(%V|H8Gu|4&-{^Z%PC-~Zn# z`u5+__v`=2qA&lq-~aso^Tf~p6Iwt2f3fxR{{s0h|NHlT`G2wd>;K@^Z~vby`Tl?N zlOO+M?0)^wF*ES&U}9MLijiTy5+g%G zG6O@@`v3pUIsX6ul=tty=99nw?KA%VU-tXY|4;M&{AUUN^Z&2JpZ~U>e*ZUr@cY02 zli&ZR{Qv!bw$Y#eCbfV5N8kJNpEcy~f0NsP|9{Q@_kSwy|NrOL{r@lP$H2hwjDaDh zkda~gYet5)KqiL31xyULuQ4$QePv?c`NPC;`7INJ$yp|b!nsTg97#+J(Q-@-9ak9{ zRJs@$jO-X0I6gBlWUORh=uTu{2$N=DXt?(O|LIBp|7!>Q|Nouu|Nk%N|NYOL^6x)q z+`s=%_5S@gGsmttfnOJroYypWM$^DRb(Zf+(94ihE@i4Z1+L)lCWy46e!B~45W zs~edZ4puNRbfz;gtoCJM*saCHVE&JhVdZf~hRtn^3?|l$3;|CW7-qCGFtE!qFi5Zc z|9`*v|NpW3|NUR@_V53}3xEIbPWb!(>d!y_<>&wTUlIK0f4JnI|Cc`f{-5{o_kW9L zzyB|0{PTaU@t^-^s{i~Kx%ub60cdaE*}wl)694`G!1Vur%ZC5|ebN~i3RM^x9z9`X za9qm7@GX&*{ z7ejq88-uJU6GPXdzyFh-{ro?}>)Zc#rl0?p9{ccr6Yu-~GdbV=7g_N3fBf{f|5GQu z{m;bp_P?Re>;EDZ&;MICJ^263m&a+sjm5drn>uo^nrx``)alR_ZdC^m(xGx zpTy z4$p*ed(MjRRjg{Oni+Ney!d0V?cetUx88kvF!%Y}hW(N+8}@8_;_&F*1BSTwcNxMT z+-A^xe9PgI!0iLeEABKz%HL0j{`ZJsBl8Od9iev{gqgnHuvqlxK-Nx{0A~)~1`BV| zh9@?%4cRkP7~V>2H$3YyI8d~~#KAYwyrHYsg5k|abBEJAOc^?E89LPE>NJ#2RZW=N zB)fpOK&0ULLar&|$qXOvGkt4NyY%|NA%#Z`Tdi(3EK0q2!2RB-19Pq&J)mEBs3C9P z0fy~|4>YvZ9%49i=O}~T@lyv@i(houHUGweUX6zd+e%(J+;;pTu*B;h!&(oH2W{U3 z4=fXuW^js8Zumb>%b{wO!GVSd(+1&QivxV-Rt=p2RtIj}vtV%jWZICm)X*VFMyJ8G zS+yaZSMGq~XVD4y1-u%58vH8;D75TL-G5o438Zz zGi<^9Q+9yjNAp{FW6MF?=fv$$n^h*YQb-TiFQ8(L>j*a@VR|XxH#?OgURI| z7$!b{uMqt3y@PV}2ZPz}A20Y%`?O$!$(IB}zHbX6_%@iD9~<73eK!po3vz{_B3#KU08$jz{3DJMg*1_#5bNo)+-?^qakU6>gT&t+sV zVPRm{QUCA%4e`JK^)LVa@38&X|F{!B|Igz5`G0TCkN^HkKmITN`ThS}h9CbkOn>~( zo&4kfO0l2+EqDF=f4kz>e?H&e|E&%G{68=M_kXnTzyAx_{{P?f<^TT=Hy9W+)-y76 z7BeyIQ(|U#v6Go$gBc5h$8;8kvRf<+)BdwCtYl+l@cF>PaAYqF!{-7Ph9DjmhG&zQ z8MHW<8Gh$8F;t#oWO${{$S|vcfnocd|Njjf{{Nr3?%#hA?SKExcl`a&67l!{eeS>i zCtmsU-*eNS{~MS5`Tu#VN-l$^H9(%KpFqXG{J2zr5z(|Cx{f z{g3wj|NqYR|NkWw85ktm85rI?XJFXw$jGp15+j4@O-6>p!b}W8j!X;+2}}&u1xyV5 zg-i?^lb9G5x-v1GlVW0+^q7%h$wEd3-f%_+VKznv#f=OM8=@E(^jH}f9&Y;o|9a~G z|MqJc8SJhxGA#JY$k58g#NaBz#84!}#PEQHiDB_;Mh3y-j0{JnGcrt#V`P{m!^j|i znSo(`GXujueFg@*oB#iRYyAKJxc2}5({B9xZ`<|ne~Z(<|02x){+FNq`=4p?-~abp z{{H`3{P+Kdg1`SwYySR!I2E!MH|z7?|14(z{@1ts`(JnW-~TxK|NpI5{Qv()lz}0v zje+6bHwFg&R7Qr_bBqj5222dT9ZU?ySC|;?3oXT|UT51Ib_XRP@1KbP(A z{}-$O{-2Zj@4tw_|NoKf3=BV>F)*l{Vq`eHnu%d<8#6;{C=0`TAyx*fU91dC+}IdC zZ)Rg?`p3rLuFTHxU7nqR{WBZG+1YFig;Hz`90jZlZSz{L1j?}*?2JqGYfHs-%G_AIu?mD6lseys5y%< z$bS@JFme`V2=*0ZXwl+l*#4V`f#C%ggPIg4!|wg;4F6f!8LkSkGwkKyVEFr!li~bR z9)>wv1Q>Sei86TpmSk8wRgR%0K#8H>Lxn-6P?;gET8?2ag9t-o6$68(>)ro%jhFr3 z6cPP@ALsvn3=5|I+oY)a@4?qCe>W8S{_QCI{>SCO?mrh+E&7vCxcQIErO$t4=A{4i z3m5oziTUln?yo=p|2l2JxS+d(Y0H(b%pWYXSv5A^WLqF>$Z_Fy0;j^B2(AEOPVNMr z6mAEmIBo{rcU%`V__;PD@8|fD$;ckSe}`p3eiT#x@$UZ-%FTZyo`wC~psnytf$P_& z3)>k!JeU*kHX(xbwZlP+mkzHPUnp3WJZI>h_xwS1*NX!;tzR`*Z+OFS_TGDkz#X4I zM5zBz*d*}x4Oa-$gkxve8~z6IIxN~FwBXP^@q}A_G6(dQC^)G7RBo7 z4rN969mE809{4@wa)Y1t`3ApVryB$mPB|28Jn7)J^Hjrg^Ro<}lrA#lq+Vk%d2pv; zf7X)*wJUEnh}uV>XL^!$Cn(d^>_ z(~jp23+nDMYz(>9u-yK9Luu~G1Fg(Q51f`g#K3*-z=163gAIO6ha1XEjvXk7Jl$Z^ zf3d;k^$mw6>xU0+xW7u6e)+S8`24>!ax>W-ls^ePc=}6{LDN%-VfAuNhl|hk4_tp_ z;&80W;(*3%D~A?KYlqHIs{_A(m^Vb3n=m-(>N8CFuW=ylmg0ir?&Lf-y6$%m7&bgR5Ig<;fyucy9rlD@anLNj(6H;u*@nE1GY+N`&oKOdakhc0 z@xp;zrz;Lu`EEKC9lWO$U|t8Vt{Z)E%t$t1$fbR!oQylU?xNUZUa6TcHV+ z?z{`MO4+~l&S%`9@b32m$F^@5th+uYWJ^uLlY$ zzizOe^) z|KBbN`G2{n;{UqDS^quGZT~N`_1yncd++^kIrj2@TGhw@8r|Riv-SM^f9v;FaJU;ir=e*S-M|KtDM8Q=f6xqSbh9Qgfz$Kmh)Urqb*f9t`Y|BFq3|F?hm z=l`lr|Nh5JXJA-R%fyfo%EC}Bz{bG1n4KYxnUf($i;F>Bn44k8E^Y<^1s;aG&O8jd z8axcK7q}TtJ8(0ctm9$`o50B+Q^Uca<;l+Q=^rZt_fi%H6=!CKlMfgff?63E)|mhQ z@AU8Q|I7FO{Exr)`#%HY@BgnofBg^M{quim*w6nHq<{YZ#rgBUio(zT`=fvUKf3eh z|Al71{=1y}_1~lB_kR|fKmRvz{QX~Z_wWA&TmStp?fL(|CzgR>j|wA${yj#9f;J|G z1}SEStJ9eo3jQ!N+;?MPa4BP9i0)!xsBLCpn3}}GpsvZnV0n|7A*hs@A)0}iVP-88 zL+1xZhD$Mw49dqC7~~BY7@Ro#urA0P*o-d6%Qtc;ut0d?j$A#;YcP10VgJg zhq6oz+ukxVaBXH}n4HhZV4=#$@cSwQ!{=rO217#zhF$mn|1X^Q|G$XG|Nm)^7#TMI zW@ISkWMWX^W@2b$U}Bj3l96HEF-C^`8H@~D;~5#2$TBj_y3D|!)y%*ksK>xybnXBD zrrQ7ixz+yvzjE>4|A$Tg{>xhb`yc-2?|;)1fB$PP`1?Pt_3!^%6@UM0RR8@yzvu6N zleK^Ux83>s|GMPA|3WGM{-4?T@4t`a|NoO3{{K&W`~SaBECa)dvkVMIHjE5UmohSV za4<1EN?>A0UdzO=>opUDtQ0eYxH&V!Bu8e3`xeX$dt{gyLf$elxU6Pkm>$l=aQHJL z!{SCph5}|rhRxLs3{G$V|5uCt|9{4bfB#=w{QF}`hWko?fLWHDe}+%X&it4 ze?Rm4f5D31|7Xql{l8P(Qac9D_udRP zvXKnSCL}RvGN&>;Jsrysd)td4;gJ@@gRH;*Z@xbCKk0nUfAu`w|9yY2|2t9C@NZd^ z_P>f1cmHP8&iVW2RnFfBn}Yv}u!sI-@Gbev@@(_p8V1pS|B9ynlUQQ;|9}0D|AMvW z8P2TV!N~A#4bu#UCCmpNO<`%^DP!$8X3MsrZ@V|(C#>pRS z1xqa1GWyI|V_tq@KG0ag)ZcKJVS)Rre;+Kq{#lUu>DL6Ok3Sd$nZ7f0nSQ_LILh=MYk;D@WeyaF!5oEg*eS=z4F{}<3s`K2Ib|CM2)$%lsb8Lt_b7@jly zkbdltc;|kDN$g#R*IREl?D%o3;hy1b2fg$=2i8x&cc6OrLx!V=pC*XRepRqd^}~Y* zr*AQrPyIO~F_rm)M+uk0T}#0S&$fv>MC_Gq@Ksc9@Y$vAP@1C6FojXiLAXkv;qYGl z1Gz`^9IX0u7%nMmGWbqYdGPR`oI-S+L_?^J;04b#&bn+p#vSpeejK<__+f!e>}1Jw$)4UKJ92fk#PF(^DYXt*V-bzrHLl0$!iy@98mo-KhRxW}p0l%#~sd z@2q+Eyl!G@ z?K#{ax$0;GH^)f_q5WqWjMiU1uy4by1L;#A9mvvrec_eKmyWpFzZ!hU**;9W#?O#d zB;jD2qTrBHrG9{`Q}=*#wh_ZSW;2H*JBtG^_$&{6EwVVEQD}BRK+?EjTa#YHhqD?E z?TShY+N-1(JZB1h*ssiG(AvPrVDtRPf-`*|6qwh%SYTK1kim-Mw!_z1R~?RdTs$yC z>zqSu;2DMuM^8I!Z9mhX*MF|z@ac;VO{&)%dTVbdd|mf2VQ2q~hQ}Y@3+!9+om;Hz zKS!%E`+@DN`4+5NFM8mzu#AJzMnwm^G&P3};#v&~8+9B?RP`8S^Yt8*C+IpbP0~IP z(5i93u2IF|z@Z4xP{`W@1hsU=Xrmef{@Xq~Vg8$T~3E#?JHQYb@ zK4D|g*9%)6em}b+$S5%30Gq%U4IYPDO+kj|i$xtC*GewfyilfL(LXtdh)#tDZX3k| zJz|Os+HwjBWwCM%4<1V=*d3Kf(3cc_koQXgTbSe&mZ1=`t~DY(Ju@0sDCnCOiUM2n^+TCk8&)yu$_BDfCt|LzDxm!Sbm`d zb`#+TnU{qb3f~GZsBaZkuwNw95alaapf;I5!K#T@;I9_9f%<$74yTW-SCmYcT{Ei~ zI+(8gRoEK-TVn^`&jk@2-wW3He{D#9`}so8^G^lS9X}Pg|M}Q(O7xS$?aogEUjjcL zn3(#-pnlia1|8S$6S#l=`0(MxFO$;ce@=z8|4TR>&5-j#g6YJq&CC^s%B&Fr@oWL% ziR>SCt8x@vS;-+F`j$iCzz2?mliN8I*12&QxGZKr&~SxK!txO-!-FdFRdcP-dvi~+X%lccxOyl

16z2g6- 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 - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 75b13f9bd..9578e488d 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 337fc98e2..7a2aa8a7f 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,341 +1,341 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0 - - - - StaticLibrary - v143 - false - MultiByte - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index b6a8a7dd3..929dd72a8 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,121 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0 - - - - StaticLibrary - v143 - MultiByte - - - StaticLibrary - v143 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;DBG_WAV_WRITER;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 60a24021f..2d06d29aa 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,356 +1,356 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0 - - - StaticLibrary - v143 - false - MultiByte - - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - false - - - false - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + false + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 7fe2ad96c..86dcef905 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,372 +1,372 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0 - - - - StaticLibrary - v143 - false - MultiByte - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 10abdb438..e47858ae3 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,208 +1,208 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0 - - - StaticLibrary - v143 - false - MultiByte - - - - StaticLibrary - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 1cfb3e588..86730b859 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0 - - - - StaticLibrary - v143 - MultiByte - - - StaticLibrary - v143 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index ecd8b04aa..70a130e31 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0 - - - - Application - v143 - false - MultiByte - - - Application - v143 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/options.h b/lib_com/options.h index d235b80b9..3ec71d78b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -95,7 +95,7 @@ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ diff --git a/lib_com/swb_tbe_com_fx.c.bak b/lib_com/swb_tbe_com_fx.c.bak deleted file mode 100644 index fb68537c8..000000000 --- a/lib_com/swb_tbe_com_fx.c.bak +++ /dev/null @@ -1,8216 +0,0 @@ -/*==================================================================================== - EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 - ====================================================================================*/ - - -#include -#include "options.h" -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" -#include "basop_util.h" -#include "ivas_prot_fx.h" -#include "options_warnings.h" - -#define POW_EXC16k_WHTND 1.14e11f /* power of random excitation, length 320 samples, uniform distribution */ -#define POW_EXC16k_WHTND_FX_INV_SQRT 6360 // Q31 -#define POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49 1667313793 // Q49 -#define POW_EXC16k_WHTND_FX 178125000 // Q-6 -#define THR_ENV_ERROR_PLOSIVE 200.0f /* threshold for envelope error used in plosive detection */ -#define THR_ENV_ERROR_PLOSIVE_FX 200 /* threshold for envelope error used in plosive detection Q0 */ - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - -static void create_random_vector_fx( Word16 output[], const Word16 length, Word16 seed[] ); -static void flip_spectrum_fx( const Word16 input[], Word16 output[], const Word16 length ); -static void Calc_st_filt_tbe( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero ); -static void Hilbert_transform_fx( Word32 tmp_R[], Word32 tmp_I[], Word32 *tmpi_R, Word32 *tmpi_I, const Word16 length, const Word16 HB_stage_id ); -static void Hilbert_transform_sp_fx( Word16 tmp_R[], Word16 tmp_I[], Word32 *tmpi_R, Word32 *tmpi_I, const Word16 length, const Word16 HB_stage_id ); -void Estimate_mix_factors_fx( const Word16 *shb_res, const Word16 Q_shb, const Word16 *exc16kWhtnd, const Word16 Q_bwe_exc, const Word16 *White_exc16k_frac, const Word16 Q_frac, const Word32 pow1, const Word16 Q_pow1, const Word32 pow22, const Word16 Q_pow22, Word16 *vf_modified, Word16 *vf_ind ); - -/*-------------------------------------------------------------------* - * swb_tbe_reset() - * - * Reset the SWB TBE encoder - *-------------------------------------------------------------------*/ - -void swb_tbe_reset_fx( - Word32 mem_csfilt[], - Word16 mem_genSHBexc_filt_down_shb[], - Word16 state_lpc_syn[], - Word16 syn_overlap[], - Word16 state_syn_shbexc[], - Word16 *tbe_demph, - Word16 *tbe_premph, - Word16 mem_stp_swb[], - Word16 *gain_prec_swb ) -{ - set32_fx( mem_csfilt, 0, 2 ); - set16_fx( mem_genSHBexc_filt_down_shb, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - set16_fx( state_lpc_syn, 0, LPC_SHB_ORDER ); - - set16_fx( syn_overlap, 0, L_SHB_LAHEAD ); - set16_fx( state_syn_shbexc, 0, L_SHB_LAHEAD ); - - *tbe_demph = 0; - move16(); - *tbe_premph = 0; - move16(); - - set16_fx( mem_stp_swb, 0, LPC_SHB_ORDER ); - *gain_prec_swb = 16384; - move16(); /*Q14 = 1 */ - - return; -} - - -/*-------------------------------------------------------------------* - * swb_tbe_reset_synth() - * - * Reset the extra parameters needed for synthesis of the SWB TBE output - *-------------------------------------------------------------------*/ - -void swb_tbe_reset_synth_fx( - Word32 genSHBsynth_Hilbert_Mem[], - Word16 genSHBsynth_state_lsyn_filt_shb_local_fx[], - Word32 genSHBsynth_state_lsyn_filt_shb_local_fx_32[] ) -{ - - set32_fx( genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE ); - set16_fx( genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); - - if ( genSHBsynth_state_lsyn_filt_shb_local_fx_32 != NULL ) - { - set32_fx( genSHBsynth_state_lsyn_filt_shb_local_fx_32, 0, 2 * ALLPASSSECTIONS_STEEP ); - } - - return; -} - - -/*-------------------------------------------------------------------* - * fb_tbe_reset_synth_fx() - * - * reset of FB TBE memories - *-------------------------------------------------------------------*/ - -void fb_tbe_reset_synth_fx( - Word32 fbbwe_hpf_mem_fx[][4], - Word16 fbbwe_hpf_mem_fx_Q[], - Word16 *prev_fbbwe_ratio_fx ) -{ - set32_fx( fbbwe_hpf_mem_fx[0], 0, 4 ); - set32_fx( fbbwe_hpf_mem_fx[1], 0, 4 ); - set32_fx( fbbwe_hpf_mem_fx[2], 0, 4 ); - set32_fx( fbbwe_hpf_mem_fx[3], 0, 4 ); - set16_fx( fbbwe_hpf_mem_fx_Q, 0, 4 ); - *prev_fbbwe_ratio_fx = 1; - move16(); /*should be set to 1.0f, scaling unknown */ - - return; -} - - -/*-------------------------------------------------------------------* - * tbe_celp_exc_offset() - * - * Compute tbe bwe celp excitation offset - *-------------------------------------------------------------------*/ - -Word16 tbe_celp_exc_offset( - const Word16 T0_fx, /* i : Integer pitch Q0 */ - const Word16 T0_frac_fx, /* i : Fractional part of the pitch Q1 */ - const Word16 L_frame /* i : frame lenght */ -) -{ - Word16 offset_fx, tmp_fx, tmp1_fx, tmp2_fx, tmp_fac; - tmp_fac = 320; - move16(); /*2.5 in Q7*/ - if ( EQ_16( L_frame, L_FRAME16k ) ) - { - tmp_fac = 256; - move16(); /*2.0 in Q7*/ - } - tmp_fx = extract_l( L_mult( T0_frac_fx, 32 ) ); /*Q8, 0.25 in Q7*/ - tmp_fx = add( 512, tmp_fx ); /*Q8; 2 in Q8*/ - tmp_fx = mult_r( tmp_fx, tmp_fac ); /*Q16->Q0; 2.5 in Q7 or 2.0 in Q7 */ - - tmp1_fx = sub( T0_fx, 2 ); /*Q0*/ - - tmp2_fx = shl( tmp1_fx, 1 ); /*Q0 */ - - IF( EQ_16( L_frame, L_FRAME ) ) - { - tmp2_fx = add( shl( tmp1_fx, 1 ), shr( tmp1_fx, 1 ) ); /*Q0; (5/2 = 2 + 1/2)*/ - } - - offset_fx = add( tmp_fx, tmp2_fx ); /*Q0*/ - - return offset_fx; -} - -/*-------------------------------------------------------------------* - * swb_tbe_celp_exc() - * - * Compute tbe bwe celp excitation - *-------------------------------------------------------------------*/ -void tbe_celp_exc( - const Word16 L_frame_fx, /* i : Frame lenght */ - const Word16 i_subfr_fx, /* i : sub frame */ - const Word16 T0_fx, /* i : Integer pitch Q0 */ - const Word16 T0_frac_fx, /* i : Fractional part of the pitch Q1 */ - Word16 *error_fx, /* i/o: Error Q5 */ - Word16 *bwe_exc_fx /* i/o: bandwitdh extension signal */ -) -{ - Word16 offset_fx, tmp_fx, i; - IF( EQ_16( L_frame_fx, L_FRAME ) ) - { - /*offset = T0 * HIBND_ACB_L_FAC + (int) ((float) T0_frac * 0.25f * HIBND_ACB_L_FAC + 2 * HIBND_ACB_L_FAC + 0.5f) - 2 * HIBND_ACB_L_FAC; - for (i=0; i 0 ) - { - tmp_fx = shr( *error_fx, 5 ); /*Q0*/ - } - ELSE - { - tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ - } - - FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) - { - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC - offset_fx + tmp_fx]; // Qx - move16(); - } - tmp_fx = extract_l( L_mult( T0_frac_fx, 1 ) ); /*Q3; 0.25 in Q2*/ - tmp_fx = add( shl( T0_fx, 3 ), tmp_fx ); /*Q3*/ - tmp_fx = extract_l( L_mult( tmp_fx, 5 ) ); /*Q5, 2.5 in Q1*/ - tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*Q5*/ - *error_fx = add( *error_fx, tmp_fx ); /*Q5*/ - move16(); - } - ELSE - { - /* offset = T0*2.5 + (int) ((float) T0_frac * 0.25f*2.5 + 2*2.5 + 0.5f) - 2*2.5; - case above*/ - /* offset = T0*2 + (int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f) - 2*2; - case here*/ - - /*(int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f)*/ - offset_fx = tbe_celp_exc_offset( T0_fx, T0_frac_fx, L_frame_fx ); - IF( *error_fx > 0 ) - { - tmp_fx = shr( *error_fx, 5 ); /*Q0*/ - } - ELSE - { - tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ - } - - FOR( i = 0; i < L_SUBFR * 2; i++ ) - { - bwe_exc_fx[i + i_subfr_fx * 2] = bwe_exc_fx[i + i_subfr_fx * 2 - offset_fx + tmp_fx]; // Qx - move16(); - } - - /* error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac;*/ - tmp_fx = extract_l( L_mult( T0_frac_fx, 2 ) ); /*Q3; 0.5 in Q2*/ - tmp_fx = add( shl( T0_fx, 4 ), tmp_fx ); /* now tmp_fx = "T0_fx*2+ 0.5f*T0_frac_fx" in Q3*/ - tmp_fx = shl( tmp_fx, 2 ); /*now above tmp_fx in Q5*/ - tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*move offset_fx to Q5, tmp_fx in Q5, ans tmp_fx in Q5*/ - *error_fx = add( *error_fx, tmp_fx ); /*error_fx in Q5*/ - move16(); - } -} - -/*-------------------------------------------------------------------* - * swb_tbe_celp_exc_ivas() - * - * Compute tbe bwe celp excitation - *-------------------------------------------------------------------*/ -void tbe_celp_exc_ivas( - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 L_frame_fx, /* i : Frame lenght */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 i_subfr_fx, /* i : sub frame */ - const Word16 T0_fx, /* i : Integer pitch Q0 */ - const Word16 T0_frac_fx, /* i : Fractional part of the pitch Q1 */ - Word16 *error_fx, /* i/o: Error Q5 */ - Word16 *bwe_exc_fx, /* i/o: bandwitdh extension signal Qx */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -) -{ - Word16 offset_fx, tmp_fx, i; - - test(); - test(); - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) - { - return; - } - - IF( EQ_16( L_frame_fx, L_FRAME ) ) - { - /*offset = T0 * HIBND_ACB_L_FAC + (int) ((float) T0_frac * 0.25f * HIBND_ACB_L_FAC + 2 * HIBND_ACB_L_FAC + 0.5f) - 2 * HIBND_ACB_L_FAC; - for (i=0; i 0 ) - { - tmp_fx = shr( *error_fx, 5 ); /*Q0*/ - } - ELSE - { - tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ - } - - FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) - { - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC - offset_fx + tmp_fx]; - move16(); - } - tmp_fx = extract_l( L_mult( T0_frac_fx, 1 ) ); /*Q3; 0.25 in Q2*/ - tmp_fx = add( shl( T0_fx, 3 ), tmp_fx ); /*Q3*/ - tmp_fx = extract_l( L_mult( tmp_fx, 5 ) ); /*Q5, 2.5 in Q1*/ - tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*Q5*/ - *error_fx = add( *error_fx, tmp_fx ); /*Q5*/ - move16(); - } - ELSE - { - /* offset = T0*2.5 + (int) ((float) T0_frac * 0.25f*2.5 + 2*2.5 + 0.5f) - 2*2.5; - case above*/ - /* offset = T0*2 + (int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f) - 2*2; - case here*/ - - /*(int) ((float) T0_frac * 0.25f*2 + 2*2 + 0.5f)*/ - offset_fx = tbe_celp_exc_offset( T0_fx, T0_frac_fx, L_frame_fx ); - IF( *error_fx > 0 ) - { - tmp_fx = shr( *error_fx, 5 ); /*Q0*/ - } - ELSE - { - tmp_fx = negate( shr( abs_s( *error_fx ), 5 ) ); /*Q0*/ - } - - FOR( i = 0; i < L_subfr * 2; i++ ) - { - bwe_exc_fx[i + i_subfr_fx * 2] = bwe_exc_fx[i + i_subfr_fx * 2 - offset_fx + tmp_fx]; - move16(); - } - - /* error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac;*/ - tmp_fx = extract_l( L_mult( T0_frac_fx, 2 ) ); /*Q3; 0.5 in Q2*/ - tmp_fx = add( shl( T0_fx, 4 ), tmp_fx ); /* now tmp_fx = "T0_fx*2+ 0.5f*T0_frac_fx" in Q3*/ - tmp_fx = shl( tmp_fx, 2 ); /*now above tmp_fx in Q5*/ - tmp_fx = sub( shl( offset_fx, 5 ), tmp_fx ); /*move offset_fx to Q5, tmp_fx in Q5, ans tmp_fx in Q5*/ - *error_fx = add( *error_fx, tmp_fx ); /*error_fx in Q5*/ - move16(); - } -} - -/*===========================================================================*/ -/* FUNCTION : flip_and_downmix_generic_fx() */ -/*---------------------------------------------------------------------------*/ -/* PURPOSE :flips the spectrum and downmixes the signals, lpf if needed*/ -/*---------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS */ -/* _(Word16[]) input :input spectrum */ -/* _(Word16) length :length of spectra */ -/* _(Word16) ramp_flag :flag to indicate slow ramp need after switching */ -/* _(Word16[]) lpf_num :lpf numerator */ -/* _(Word16[]) lpf_den :lpf denominator */ -/*---------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _(Word16[])output : output spectrum */ -/*---------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _(Word32[9])mem1 : memory */ -/* _(Word32[8])mem2 : memory */ -/* _(Word32[8])mem3 : memory */ -/* _(Word16) dm_frequency_inHz :Downmix frequency in Hz */ -/* _(Word16*) phase_state :Phase state in case frequency isn't */ -/* multiple of 50 Hz */ -/*---------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*---------------------------------------------------------------------------*/ -void flip_and_downmix_generic_fx( - Word16 input[], /* i : input spectrum Qx*/ - Word16 output[], /* o : output spectrum Qx*/ - const Word16 length, /* i : length of spectra */ - Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx+16*/ - Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx+16*/ - Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx+16*/ - Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -) -{ - Word16 i, j; - Word16 tmp_16[L_FRAME32k + HILBERT_ORDER1]; - Word32 tmpi_R[L_FRAME32k]; - Word32 tmpi_I[L_FRAME32k]; - Word32 tmpi2_R[L_FRAME32k + HILBERT_ORDER2]; - Word32 tmpi2_I[L_FRAME32k + HILBERT_ORDER2]; - Word32 tmp_R[L_FRAME32k + HILBERT_ORDER2]; - Word32 tmp_I[L_FRAME32k + HILBERT_ORDER2]; - - /*Word16 s_tmp[L_FRAME32k];*/ - /*Word16 factor;*/ - Word16 period; - Word16 local_negsin_table17[17] = { 0, -11793, -22005, -29268, -32609, -31580, - -26319, -17530, -6393, 6393, 17530, 26319, - 31580, 32609, 29268, 22005, 11793 }; /* Q15 */ - Word16 local_cos_table17[17] = { 32767, 30571, 24279, 14732, 3212, -8739, - -19519, -27683, -32137, -32137, -27683, - -19519, -8739, 3212, 14732, 24279, 30571 }; /* Q15 */ - Word16 *local_negsin_table, *local_cos_table; - Word32 L_tmp; - - /* 1850 Hz downmix */ - period = 17; - move16(); - local_negsin_table = local_negsin_table17; - local_cos_table = local_cos_table17; - - - FOR( i = 0; i < length; i = i + 2 ) - { - input[i] = negate( input[i] ); - move16(); - } - - Copy( input, tmp_16 + HILBERT_ORDER1, length ); - - /*Copy32( mem1_ext, tmp_16, 5 ); */ - FOR( i = 0; i < HILBERT_ORDER1; i++ ) - { - tmp_16[i] = extract_h( mem1_ext[i] ); /* mem1_ext (Qx+16) tmp16 (Qx) */ - move16(); - } - - /* Hilber transform stage - 0 - single precision */ - Hilbert_transform_sp_fx( tmp_16, /* i: Real component of HB */ - tmp_16, /* i: Imag component of HB */ - tmpi_R, /* o: Real component of HB */ - tmpi_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 0 ); /* i: HB transform stage */ - - FOR( i = 0; i < HILBERT_ORDER1; i++ ) - { - mem1_ext[i] = L_deposit_h( tmp_16[i + length] ); /* mem1_ext (Qx+16) tmp16 (Qx) */ - move32(); - } - - Copy32( mem2_ext, tmpi2_R, HILBERT_ORDER2 ); - Copy32( mem3_ext, tmpi2_I, HILBERT_ORDER2 ); - - /* Hilber transform stage - 1 */ - Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ - tmpi_I, /* i: Imag component of HB */ - tmpi2_R, /* o: Real component of HB */ - tmpi2_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 1 ); /* i: HB transform stage */ - - Copy32( mem2_ext + HILBERT_ORDER2, tmp_R, HILBERT_ORDER2 ); - Copy32( mem3_ext + HILBERT_ORDER2, tmp_I, HILBERT_ORDER2 ); - - /* Hilber transform stage - 2 */ - Hilbert_transform_fx( tmpi2_R, /* i: Real component of HB */ - tmpi2_I, /* i: Imag component of HB */ - tmpi_R, /* o: Real component of HB */ - tmpi_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 2 ); /* i: HB transform stage */ - - Copy32( tmpi2_R + length, mem2_ext, HILBERT_ORDER2 ); - Copy32( tmpi2_I + length, mem3_ext, HILBERT_ORDER2 ); - - /* Hilber transform stage - 3 */ - Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ - tmpi_I, /* i: Imag component of HB */ - tmp_R, /* o: Real component of HB */ - tmp_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 3 ); /* i: HB transform stage */ - - Copy32( tmp_R + length, mem2_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); - Copy32( tmp_I + length, mem3_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); - - if ( GE_16( *phase_state, period ) ) - { - *phase_state = 0; - move16(); - } - - i = 0; - move16(); - j = *phase_state; - move16(); - - WHILE( i < length ) - { - WHILE( ( j < period ) && ( i < length ) ) - { - L_tmp = Mult_32_16( tmp_R[i + 4], local_cos_table[j] ); /*//Qx+16 */ - L_tmp = Madd_32_16( L_tmp, tmp_I[i + 4], local_negsin_table[j] ); /*Qx+16 */ - output[i] = round_fx( L_tmp ); /*Qx */ - move16(); - i++; - j++; - } - - if ( GE_16( j, period ) ) - { - j = 0; - move16(); - } - } - - *phase_state = j; - move16(); - - return; -} - - -void flip_and_downmix_generic_fx32( - Word32 input[], /* i : input spectrum Qx*/ - Word32 output[], /* o : output spectrum Qx*/ - const Word16 length, /* i : length of spectra */ - Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ - Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -) -{ - Word16 i, j; - Word32 tmp[L_FRAME32k + HILBERT_ORDER1]; - Word32 tmpi_R[L_FRAME32k]; - Word32 tmpi_I[L_FRAME32k]; - Word32 tmpi2_R[L_FRAME32k + HILBERT_ORDER2]; - Word32 tmpi2_I[L_FRAME32k + HILBERT_ORDER2]; - Word32 tmp_R[L_FRAME32k + HILBERT_ORDER2]; - Word32 tmp_I[L_FRAME32k + HILBERT_ORDER2]; - - /*Word16 s_tmp[L_FRAME32k];*/ - /*Word16 factor;*/ - Word16 period; - Word16 local_negsin_table17[17] = { 0, -11793, -22005, -29268, -32609, -31580, - -26319, -17530, -6393, 6393, 17530, 26319, - 31580, 32609, 29268, 22005, 11793 }; /* Q15 */ - Word16 local_cos_table17[17] = { 32767, 30571, 24279, 14732, 3212, -8739, - -19519, -27683, -32137, -32137, -27683, - -19519, -8739, 3212, 14732, 24279, 30571 }; /* Q15 */ - Word16 *local_negsin_table, *local_cos_table; - Word32 L_tmp; - - /* 1850 Hz downmix */ - period = 17; - move16(); - local_negsin_table = local_negsin_table17; - local_cos_table = local_cos_table17; - - - FOR( i = 0; i < length; i = i + 2 ) - { - input[i] = L_negate( input[i] ); - move16(); - } - - Copy32( input, tmp + HILBERT_ORDER1, length ); - Copy32( mem1_ext, tmp, HILBERT_ORDER1 ); - - /* Hilber transform stage - 0 - single precision */ - Hilbert_transform_fx( tmp, /* i: Real component of HB */ - tmp, /* i: Imag component of HB */ - tmpi_R, /* o: Real component of HB */ - tmpi_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 0 ); /* i: HB transform stage */ - - - Copy32( mem2_ext, tmpi2_R, HILBERT_ORDER2 ); - Copy32( mem3_ext, tmpi2_I, HILBERT_ORDER2 ); - - /* Hilber transform stage - 1 */ - Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ - tmpi_I, /* i: Imag component of HB */ - tmpi2_R, /* o: Real component of HB */ - tmpi2_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 1 ); /* i: HB transform stage */ - Copy32( tmp + length, mem1_ext, HILBERT_ORDER1 ); - Copy32( mem2_ext + HILBERT_ORDER2, tmp_R, HILBERT_ORDER2 ); - Copy32( mem3_ext + HILBERT_ORDER2, tmp_I, HILBERT_ORDER2 ); - - /* Hilber transform stage - 2 */ - Hilbert_transform_fx( tmpi2_R, /* i: Real component of HB */ - tmpi2_I, /* i: Imag component of HB */ - tmpi_R, /* o: Real component of HB */ - tmpi_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 2 ); /* i: HB transform stage */ - - Copy32( tmpi2_R + length, mem2_ext, HILBERT_ORDER2 ); - Copy32( tmpi2_I + length, mem3_ext, HILBERT_ORDER2 ); - - /* Hilber transform stage - 3 */ - Hilbert_transform_fx( tmpi_R, /* i: Real component of HB */ - tmpi_I, /* i: Imag component of HB */ - tmp_R, /* o: Real component of HB */ - tmp_I, /* o: Imag. component of HB */ - length, /* i: length of the spectra */ - 3 ); /* i: HB transform stage */ - - Copy32( tmp_R + length, mem2_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); - Copy32( tmp_I + length, mem3_ext + HILBERT_ORDER2, HILBERT_ORDER2 ); - - if ( GE_16( *phase_state, period ) ) - { - *phase_state = 0; - move16(); - } - - i = 0; - move16(); - j = *phase_state; - move16(); - - WHILE( LT_16( i, length ) ) - { - WHILE( ( j < period ) && ( i < length ) ) - { - test(); - L_tmp = Mult_32_16( tmp_R[i + 4], local_cos_table[j] ); /*//Qx+16 */ - L_tmp = Madd_32_16( L_tmp, tmp_I[i + 4], local_negsin_table[j] ); /*Qx+16 */ - output[i] = L_tmp; /*Qx */ - move32(); - i++; - j++; - } - - if ( GE_16( j, period ) ) - { - j = 0; - move16(); - } - } - - *phase_state = j; - move16(); - return; -} - -/*---------------------------------------------- - * Hilbert transform - Double precision - *------------------------------------------------*/ -static void Hilbert_transform_fx( - Word32 tmp_R[], /* i: Real component of HB */ - Word32 tmp_I[], /* i: Real component of HB */ - Word32 tmpi_R[], /* o: Real component of HB */ - Word32 tmpi_I[], /* o: Imag. component of HB */ - const Word16 length, /* i: input length */ - const Word16 HB_stage_id /* i: HB transform stage */ -) -{ - Word16 i, hb_filter_stage, offset; - Word32 L_tmp; - - hb_filter_stage = shl( HB_stage_id, 1 ); - offset = 0; - move16(); - if ( HB_stage_id == 0 ) - { - offset = 1; - move16(); - } - - test(); - test(); - IF( HB_stage_id == 0 || EQ_16( HB_stage_id, 2 ) ) - { - FOR( i = 0; i < length; i++ ) - { - L_tmp = Mult_32_16( tmp_R[i + 4], Hilbert_coeffs_fx[hb_filter_stage][0 + offset] ); /*Qx+15 */ - L_tmp = Madd_32_16( L_tmp, tmp_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2 + offset] ); /*Qx+15 */ - L_tmp = Madd_32_16( L_tmp, tmp_R[i], Hilbert_coeffs_fx[hb_filter_stage][4 + offset] ); /*Qx+15 */ - tmpi_R[i] = L_shl( L_tmp, 1 ); - move32(); /*Qx+16 */ - - L_tmp = Mult_32_16( tmp_I[i + 4 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][0] ); /*Qx+15 */ - L_tmp = Madd_32_16( L_tmp, tmp_I[i + 2 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][2] ); /*Qx+15 */ - L_tmp = Madd_32_16( L_tmp, tmp_I[i + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][4] ); /*Qx+15 */ - tmpi_I[i] = L_shl( L_tmp, 1 ); - move32(); /*Qx+16 */ - } - } - ELSE IF( EQ_16( HB_stage_id, 1 ) || EQ_16( HB_stage_id, 3 ) ) - { - FOR( i = 0; i < length; i++ ) - { - - L_tmp = Mult_32_16( tmpi_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2] ); /*Qx+15 */ - L_tmp = Madd_32_16( L_tmp, tmpi_R[i], Hilbert_coeffs_fx[hb_filter_stage][4] ); /*Qx+15 */ - tmpi_R[i + 4] = L_sub( tmp_R[i], L_shl( L_tmp, 1 ) ); - move32(); /*Qx+16 */ - - L_tmp = Mult_32_16( tmpi_I[i + 2], Hilbert_coeffs_fx[hb_filter_stage + 1][2] ); /*Qx+15 */ - L_tmp = Madd_32_16( L_tmp, tmpi_I[i], Hilbert_coeffs_fx[hb_filter_stage + 1][4] ); /*Qx+15 */ - tmpi_I[i + 4] = L_sub( tmp_I[i], L_shl( L_tmp, 1 ) ); - move32(); /*Qx+16 */ - } - } -} - - -/*---------------------------------------------- - * Hilbert transform - Single precision Stage 0 - *------------------------------------------------*/ -static void Hilbert_transform_sp_fx( - Word16 tmp_R[], /* i: Real component of HB */ - Word16 tmp_I[], /* i: Real component of HB */ - Word32 tmpi_R[], /* o: Real component of HB */ - Word32 tmpi_I[], /* o: Imag. component of HB */ - const Word16 length, /* i: input length */ - const Word16 HB_stage_id /* i: HB transform stage */ -) -{ - Word16 i, hb_filter_stage, offset; - Word32 L_tmp; - - hb_filter_stage = shl( HB_stage_id, 1 ); - offset = 0; - move16(); - if ( HB_stage_id == 0 ) - { - offset = 1; - move16(); - } - - /* Hilbert single precision stage 0 */ - FOR( i = 0; i < length; i++ ) - { - L_tmp = L_mult( tmp_R[i + 4], Hilbert_coeffs_fx[hb_filter_stage][0 + offset] ); /*Qx */ - L_tmp = L_mac( L_tmp, tmp_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2 + offset] ); /*Qx */ - L_tmp = L_mac( L_tmp, tmp_R[i], Hilbert_coeffs_fx[hb_filter_stage][4 + offset] ); /*Qx */ - tmpi_R[i] = L_shl( L_tmp, 1 ); - move32(); /*Qx+16 */ - - L_tmp = L_mult( tmp_I[i + 4 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][0] ); /*Qx */ - L_tmp = L_mac( L_tmp, tmp_I[i + 2 + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][2] ); /*Qx */ - L_tmp = L_mac( L_tmp, tmp_I[i + offset], Hilbert_coeffs_fx[hb_filter_stage + 1][4] ); /*Qx */ - tmpi_I[i] = L_shl( L_tmp, 1 ); - move32(); /*Qx+16 */ - } - - return; -} - - -/*---------------------------------------------- - * flip_spectrum_fx - *----------------------------------------------*/ -void flip_spectrum_fx( - const Word16 input[], /* i : input spectrum */ - Word16 output[], /* o : output spectrum */ - const Word16 length /* i : vector length */ -) -{ - Word16 i; - - FOR( i = 0; i < length; i = i + 2 ) - { - output[i] = negate( input[i] ); - move16(); - output[i + 1] = input[i + 1]; - move16(); - } - - return; -} - - -/*---------------------------------------------------------------------------- - * calc_rc0_h - * - * computes 1st parcor from composed filter impulse response - *---------------------------------------------------------------------------*/ -void Calc_rc0_h( - Word16 *h, /* i : impulse response of composed filter */ - Word16 *rc0 /* o : 1st parcor */ -) -{ - Word32 L_acc; - Word16 *ptrs; - Word16 acf0, acf1; - Word16 temp, sh_acf; - Word16 i; - - /* computation of the autocorrelation function acf */ - L_acc = L_mult( h[0], h[0] ); - FOR( i = 1; i < LONG_H_ST; i++ ) - { - L_acc = L_mac( L_acc, h[i], h[i] ); - } - sh_acf = norm_l( L_acc ); - L_acc = L_shl( L_acc, sh_acf ); - acf0 = extract_h( L_acc ); - - ptrs = h; - - temp = *ptrs++; - move16(); - L_acc = L_mult( temp, *ptrs ); - FOR( i = 1; i < LONG_H_ST - 1; i++ ) - { - temp = *ptrs++; - move16(); - L_acc = L_mac( L_acc, temp, *ptrs ); - } - L_acc = L_shl( L_acc, sh_acf ); - acf1 = extract_h( L_acc ); - - /* Compute 1st parcor */ - IF( acf0 == 0 ) - { - *rc0 = 0; - move16(); - return; - } - - IF( LT_16( acf0, abs_s( acf1 ) ) ) - { - *rc0 = 0; - move16(); - return; - } - *rc0 = div_s( abs_s( acf1 ), acf0 ); - move16(); - IF( acf1 > 0 ) - { - *rc0 = negate( *rc0 ); - move16(); - } -} - -void Calc_rc0_h_ivas_enc_fx( - Word16 *h, /* i : impulse response of composed filter */ - Word16 *rc0 /* o : 1st parcor */ -) -{ - Word32 L_acc; - Word16 *ptrs; - Word16 acf0, acf1; - Word16 temp, sh_acf, tmp2; - Word16 i; - - /* computation of the autocorrelation function acf */ - L_acc = L_mult( h[0], h[0] ); - FOR( i = 1; i < LONG_H_ST; i++ ) - { - tmp2 = shr( h[i], 2 ); - L_acc = L_mac( L_acc, tmp2, tmp2 ); - } - sh_acf = norm_l( L_acc ); - L_acc = L_shl( L_acc, sh_acf ); - acf0 = extract_h( L_acc ); - - ptrs = h; - - temp = *ptrs++; - move16(); - L_acc = L_mult( temp, *ptrs ); - FOR( i = 1; i < LONG_H_ST - 1; i++ ) - { - temp = shr( *ptrs++, 2 ); - move16(); - L_acc = L_mac( L_acc, temp, shr( *ptrs, 2 ) ); - } - L_acc = L_shl( L_acc, sh_acf ); - acf1 = extract_h( L_acc ); - - /* Compute 1st parcor */ - IF( acf0 == 0 ) - { - *rc0 = 0; - move16(); - return; - } - - IF( LT_16( acf0, abs_s( acf1 ) ) ) - { - *rc0 = 0; - move16(); - return; - } - *rc0 = div_s( abs_s( acf1 ), acf0 ); - move16(); - IF( acf1 > 0 ) - { - *rc0 = negate( *rc0 ); - move16(); - } -} - -static void Calc_st_filt_tbe( - Word16 *apond2, /* i : coefficients of numerator */ - Word16 *apond1, /* i : coefficients of denominator */ - Word16 *parcor0, /* o : 1st parcor calcul. on composed filter */ - Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ - Word16 *mem_zero /* i : All zero memory */ -) -{ - Word32 L_g0; - - Word16 h[LONG_H_ST]; - - Word16 g0, temp; - Word16 i; - temp = sub( 2, norm_s( apond2[0] ) ); - /* compute i.r. of composed filter apond2 / apond1 */ - Syn_filt_s( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); - /* compute 1st parcor */ - Calc_rc0_h( h, parcor0 ); - - /* compute g0 */ - L_g0 = L_mult0( 1, abs_s( h[0] ) ); - FOR( i = 1; i < LONG_H_ST; i++ ) - { - L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); - } - g0 = extract_h( L_shl( L_g0, 14 ) ); - - /* Scale signal i of 1/A(gamma1) */ - IF( GT_16( g0, 1024 ) ) - { - temp = div_s( 1024, g0 ); /* temp = 2**15 / gain0 */ - FOR( i = 0; i < L_SUBFR16k; i++ ) - { - sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); - move16(); - } - } -} - -static void Calc_st_filt_tbe_ivas_enc_fx( - Word16 *apond2, /* i : coefficients of numerator */ - Word16 *apond1, /* i : coefficients of denominator */ - Word16 *parcor0, /* o : 1st parcor calcul. on composed filter */ - Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ - Word16 *mem_zero /* i : All zero memory */ -) -{ - Word32 L_g0; - - Word16 h[LONG_H_ST]; - - Word16 g0, temp; - Word16 i; - temp = sub( 2, norm_s( apond2[0] ) ); - /* compute i.r. of composed filter apond2 / apond1 */ - syn_filt_fx( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); - /* compute 1st parcor */ - Calc_rc0_h_ivas_enc_fx( h, parcor0 ); - - /* compute g0 */ - L_g0 = L_mult0( 1, abs_s( h[0] ) ); - FOR( i = 1; i < LONG_H_ST; i++ ) - { - L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); - } - g0 = extract_h( L_shl( L_g0, 14 ) ); - - /* Scale signal i of 1/A(gamma1) */ - IF( GT_16( g0, 1024 ) ) - { - temp = div_s( 1024, g0 ); /* temp = 2**15 / gain0 */ - FOR( i = 0; i < L_SUBFR16k; i++ ) - { - sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); - move16(); - } - } -} - -static void Calc_st_filt_tbe_ivas_dec_fx( - Word16 *apond2, /* i : coefficients of numerator */ - Word16 *apond1, /* i : coefficients of denominator */ - Word16 *parcor0, /* o : 1st parcor calcul. on composed filter */ - Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ - Word16 *mem_zero /* i : All zero memory */ -) -{ - Word32 L_g0; - - Word16 h[LONG_H_ST]; - - Word16 g0, temp; - Word16 i; - temp = sub( 2, norm_s( apond2[0] ) ); - /* compute i.r. of composed filter apond2 / apond1 */ - Syn_filt_s( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); - /* compute 1st parcor */ - Calc_rc0_h( h, parcor0 ); - - /* compute g0 */ - L_g0 = L_mult0( 1, abs_s( h[0] ) ); - FOR( i = 1; i < LONG_H_ST; i++ ) - { - L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); - } - g0 = extract_h( L_shl( L_g0, 14 ) ); - - /* Scale signal i of 1/A(gamma1) */ - IF( GT_16( g0, 1024 ) ) - { - temp = div_s( 1024, g0 ); /* temp = 2**15 / gain0 */ - FOR( i = 0; i < L_SUBFR16k; i++ ) - { - sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); - move16(); - } - } -} - -static void filt_mu_fx( - const Word16 *sig_in, /* i : signal (beginning at sample -1) */ - Word16 *sig_out, /* o : output signal */ - const Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ - Word16 SubFrameLength /* i : the length of subframe */ -) -{ - Word16 n; - Word16 mu, ga, temp; - const Word16 *ptrs; - Word16 tmp, exp; - Flag Overflow = 0; - move32(); - - - IF( EQ_16( SubFrameLength, L_SUBFR ) ) - { - IF( parcor0 > 0 ) - { - mu = mult_r( parcor0, GAMMA3_PLUS_FX ); - } - ELSE - { - mu = mult_r( parcor0, GAMMA3_MINUS_FX ); - } - } - ELSE - { - IF( parcor0 > 0 ) - { - mu = mult_r( parcor0, GAMMA3_PLUS_WB_FX ); - } - ELSE - { - mu = mult_r( parcor0, GAMMA3_MINUS_WB_FX ); - } - } - - tmp = abs_s( mu ); - tmp = sub( 32767, tmp ); - exp = norm_s( tmp ); - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*(14 - exp) */ - ga = shl_sat( tmp, exp ); /*Q14 */ - - - /* ga = (float) 1. / ((float) 1. - (float) fabs (mu)); */ - - ptrs = sig_in; /* points on sig_in(-1) */ - - FOR( n = 0; n < SubFrameLength; n++ ) - { - temp = mult_r( mu, ( *ptrs++ ) ); - temp = add_sat( temp, *ptrs ); /*Q12 */ - sig_out[n] = shl_o( mult_r( ga, temp ), 1, &Overflow ); - move16(); /*Q12 */ - } - - return; -} - -static void scale_st_swb( - const Word16 *sig_in_fx, /* i : postfilter i signal */ - Word16 *sig_out_fx, /* i/o: postfilter o signal */ - Word16 *gain_prec_fx, /* i/o: last value of gain for subframe */ - Word16 SubFrameLength ) -{ - Word16 i; - Word16 agc_fac1_para_fx; - Word16 agc_fac_para_fx; - Word32 L_acc, L_temp; - Word16 g0_fx, gain_fx; - Word16 scal_in, scal_out; - Word16 s_g_in, s_g_out, sh_g0, temp; - - - IF( EQ_16( SubFrameLength, L_SUBFR ) ) - { - agc_fac1_para_fx = AGC_FAC1_FX; - move16(); - agc_fac_para_fx = AGC_FAC_FX; - move16(); - } - ELSE /*IF( SubFrameLength == L_SUBFR16k ) */ - { - agc_fac1_para_fx = AGC_FAC1_WB_FX; - move16(); - agc_fac_para_fx = AGC_FAC_WB_FX; - move16(); - } - - /* compute input gain */ - L_acc = L_mult0( 1, abs_s( sig_in_fx[0] ) ); /*0 +Q_bwe_exc-1 */ - FOR( i = 1; i < SubFrameLength; i++ ) - { - L_acc = L_mac0( L_acc, 1, abs_s( sig_in_fx[i] ) ); /*Q_bwe_exc-1 */ - } - - g0_fx = 0; - move16(); - IF( L_acc != 0L ) - { - scal_in = norm_l( L_acc ); - L_acc = L_shl( L_acc, scal_in ); - s_g_in = extract_h( L_acc ); /* normalized */ - - /* Compute o gain */ - L_acc = L_mult0( 1, abs_s( sig_out_fx[0] ) ); - FOR( i = 1; i < SubFrameLength; i++ ) - { - L_acc = L_mac0( L_acc, 1, abs_s( sig_out_fx[i] ) ); - } - IF( L_acc == 0L ) - { - *gain_prec_fx = 0; - move16(); - - return; - } - - scal_out = norm_l( L_acc ); - L_acc = L_shl( L_acc, scal_out ); - s_g_out = extract_h( L_acc ); /* normalized */ - - - sh_g0 = add( scal_in, 1 ); - sh_g0 = sub( sh_g0, scal_out ); /* scal_in - scal_out + 1 */ - IF( LT_16( s_g_in, s_g_out ) ) - { - g0_fx = div_s( s_g_in, s_g_out ); /* s_g_in/s_g_out in Q15 */ - } - ELSE - { - temp = sub( s_g_in, s_g_out ); /* sufficient since normalized */ - g0_fx = shr( div_s( temp, s_g_out ), 1 ); - g0_fx = add( g0_fx, (Word16) 0x4000 ); /* s_g_in/s_g_out in Q14 */ - sh_g0 = sub( sh_g0, 1 ); - } - /* L_gain_in/L_gain_out in Q14 */ - /* overflows if L_gain_in > 2 * L_gain_out */ - g0_fx = shr_sat( g0_fx, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */ // Need to verify? - - g0_fx = mult_r( g0_fx, agc_fac1_para_fx ); /* L_gain_in/L_gain_out * AGC_FAC1_FX */ - } - /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */ - /* sig_out(n) = gain(n) sig_out(n) */ - gain_fx = *gain_prec_fx; - move16(); /*14 */ - FOR( i = 0; i < SubFrameLength; i++ ) - { - temp = mult_r( agc_fac_para_fx, gain_fx ); /*15 +14 -15 =14 */ - gain_fx = add( temp, g0_fx ); /* in Q14 */ - L_temp = L_mult( gain_fx, sig_out_fx[i] ); /*14 + Q_bwe_exc-1 +1 = 14 + Q_bwe_exc */ - L_temp = L_shl_sat( L_temp, 1 ); /*14 + Q_bwe_exc +1 */ - sig_out_fx[i] = round_fx_sat( L_temp ); /*Q_bwe_exc +15 -16 = Q_bwe_exc-1 */ - move16(); - } - *gain_prec_fx = gain_fx; - move16(); - - return; -} - -void PostShortTerm_fx( - Word16 *sig_in, /* i : input signal (pointer to current subframe */ - Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ - Word16 *sig_out, /* o : postfiltered output */ - Word16 *mem_stp, /* i/o: postfilter memory*/ - Word16 *ptr_mem_stp, /* i/o: pointer to postfilter memory*/ - Word16 *ptr_gain_prec, /* i/o: for gain adjustment*/ - Word16 *mem_zero, /* i/o: null memory to compute h_st*/ - const Word16 formant_fac_fx /* i : Strength of post-filter*/ -) -{ - Word16 apond1_fx[LPC_SHB_ORDER + 1]; /* denominator coeff.*/ - Word16 apond2_fx[LONG_H_ST]; /* numerator coeff. */ - Word16 sig_ltp_fx[L_SUBFR16k + 1]; /* residual signal */ - /*Word16 lpccoeff_fx[LPC_SHB_ORDER+1];//Q12 */ - Word16 g1_fx, g2_fx, parcor0_fx; /*Q15 */ - Word16 tmp; - - parcor0_fx = 0; - move16(); - set16_fx( apond1_fx, 0, LPC_SHB_ORDER + 1 ); - set16_fx( apond2_fx, 0, LONG_H_ST ); - set16_fx( sig_ltp_fx, 0, L_SUBFR16k + 1 ); - - /* Obtain post-filter weights */ - tmp = extract_h( L_mult( GAMMA_SHARP_FX, formant_fac_fx ) ); /*Q15 */ - g1_fx = add( GAMMA0_FX, tmp ); /*Q15 */ - g2_fx = sub( GAMMA0_FX, tmp ); /*Q15 */ - - /* Compute weighted LPC coefficients */ - weight_a_fx( lpccoeff, apond1_fx, g1_fx, LPC_SHB_ORDER ); - weight_a_fx( lpccoeff, apond2_fx, g2_fx, LPC_SHB_ORDER ); - /* o: apond1_fx, apond2_fx in Q12 */ - - /* Compute A(gamma2) residual */ - Residu3_10_fx( apond2_fx, sig_in, sig_ltp_fx + 1, L_SUBFR16k, 0 ); - /* o: sig_ltp_fx in Q_bwe_exc */ - - /* Save last output of 1/A(gamma1) */ - sig_ltp_fx[0] = *ptr_mem_stp; - move16(); - - /* Control short term pst filter gain and compute parcor0 */ - Calc_st_filt_tbe( apond2_fx, apond1_fx, &parcor0_fx, sig_ltp_fx + 1, mem_zero ); - /* o: parcor0 in Q15 */ - /* i/o: sig_ltp_fx in Q_bwe_exc */ - - /* 1/A(gamma1) filtering, mem_stp is updated */ - Syn_filt_s( 0, apond1_fx, LPC_SHB_ORDER, sig_ltp_fx + 1, sig_ltp_fx + 1, L_SUBFR16k, mem_stp, 1 ); - - /* (1 + mu z-1) tilt filtering */ - filt_mu_fx( sig_ltp_fx, sig_out, parcor0_fx, L_SUBFR16k ); - /* o: sig_out in Q_bwe_exc */ - - /* gain control */ - scale_st_swb( sig_in, sig_out, ptr_gain_prec, L_SUBFR16k ); - - return; -} - -void PostShortTerm_ivas_enc_fx( - Word16 *sig_in, /* i : input signal (pointer to current subframe */ - Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ - Word16 *sig_out, /* o : postfiltered output */ - Word16 *mem_stp, /* i/o: postfilter memory*/ - Word16 *ptr_mem_stp, /* i/o: pointer to postfilter memory*/ - Word16 *ptr_gain_prec, /* i/o: for gain adjustment*/ - Word16 *mem_zero, /* i/o: null memory to compute h_st*/ - const Word16 formant_fac_fx /* i : Strength of post-filter*/ -) -{ - Word16 apond1_fx[LPC_SHB_ORDER + 1]; /* denominator coeff.*/ - Word16 apond2_fx[LONG_H_ST]; /* numerator coeff. */ - Word16 sig_ltp_fx[L_SUBFR16k + 1]; /* residual signal */ - /*Word16 lpccoeff_fx[LPC_SHB_ORDER+1];//Q12 */ - Word16 g1_fx, g2_fx, parcor0_fx; /*Q15 */ - Word16 tmp; - - parcor0_fx = 0; - move16(); - set16_fx( apond1_fx, 0, LPC_SHB_ORDER + 1 ); - set16_fx( apond2_fx, 0, LONG_H_ST ); - set16_fx( sig_ltp_fx, 0, L_SUBFR16k + 1 ); - - /* Obtain post-filter weights */ - tmp = extract_h( L_mult( GAMMA_SHARP_FX, formant_fac_fx ) ); /*Q15 */ - g1_fx = add( GAMMA0_FX, tmp ); /*Q15 */ - g2_fx = sub( GAMMA0_FX, tmp ); /*Q15 */ - - /* Compute weighted LPC coefficients */ - weight_a_fx( lpccoeff, apond1_fx, g1_fx, LPC_SHB_ORDER ); - weight_a_fx( lpccoeff, apond2_fx, g2_fx, LPC_SHB_ORDER ); - /* o: apond1_fx, apond2_fx in Q12 */ - - /* Compute A(gamma2) residual */ - Residu3_10_fx( apond2_fx, sig_in, sig_ltp_fx + 1, L_SUBFR16k, 0 ); - /* o: sig_ltp_fx in Q_bwe_exc */ - - /* Save last output of 1/A(gamma1) */ - sig_ltp_fx[0] = *ptr_mem_stp; - move16(); - - /* Control short term pst filter gain and compute parcor0 */ - Calc_st_filt_tbe_ivas_enc_fx( apond2_fx, apond1_fx, &parcor0_fx, sig_ltp_fx + 1, mem_zero ); - /* o: parcor0 in Q15 */ - /* i/o: sig_ltp_fx in Q_bwe_exc */ - - /* 1/A(gamma1) filtering, mem_stp is updated */ - syn_filt_fx( 0, apond1_fx, LPC_SHB_ORDER, sig_ltp_fx + 1, sig_ltp_fx + 1, L_SUBFR16k, mem_stp, 1 ); - - /* (1 + mu z-1) tilt filtering */ - filt_mu_fx( sig_ltp_fx, sig_out, parcor0_fx, L_SUBFR16k ); - /* o: sig_out in Q_bwe_exc */ - - /* gain control */ - scale_st_swb( sig_in, sig_out, ptr_gain_prec, L_SUBFR16k ); - - return; -} - -void PostShortTerm_ivas_dec_fx( - Word16 *sig_in, /* i : input signal (pointer to current subframe */ - Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ - Word16 *sig_out, /* o : postfiltered output */ - Word16 *mem_stp, /* i/o: postfilter memory*/ - Word16 *ptr_mem_stp, /* i/o: pointer to postfilter memory*/ - Word16 *ptr_gain_prec, /* i/o: for gain adjustment*/ - Word16 *mem_zero, /* i/o: null memory to compute h_st*/ - const Word16 formant_fac_fx /* i : Strength of post-filter*/ -) -{ - Word16 apond1_fx[LPC_SHB_ORDER + 1]; /* denominator coeff.*/ - Word16 apond2_fx[LONG_H_ST]; /* numerator coeff. */ - Word16 sig_ltp_fx[L_SUBFR16k + 1]; /* residual signal */ - /*Word16 lpccoeff_fx[LPC_SHB_ORDER+1];//Q12 */ - Word16 g1_fx, g2_fx, parcor0_fx; /*Q15 */ - Word16 tmp; - - parcor0_fx = 0; - move16(); - set16_fx( apond1_fx, 0, LPC_SHB_ORDER + 1 ); - set16_fx( apond2_fx, 0, LONG_H_ST ); - set16_fx( sig_ltp_fx, 0, L_SUBFR16k + 1 ); - - /* Obtain post-filter weights */ - tmp = extract_h( L_mult( GAMMA_SHARP_FX, formant_fac_fx ) ); /*Q15 */ - g1_fx = add( GAMMA0_FX, tmp ); /*Q15 */ - g2_fx = sub( GAMMA0_FX, tmp ); /*Q15 */ - - /* Compute weighted LPC coefficients */ - weight_a_fx( lpccoeff, apond1_fx, g1_fx, LPC_SHB_ORDER ); - weight_a_fx( lpccoeff, apond2_fx, g2_fx, LPC_SHB_ORDER ); - /* o: apond1_fx, apond2_fx in Q12 */ - - /* Compute A(gamma2) residual */ - Residu3_10_fx( apond2_fx, sig_in, sig_ltp_fx + 1, L_SUBFR16k, 0 ); - /* o: sig_ltp_fx in Q_bwe_exc */ - - /* Save last output of 1/A(gamma1) */ - sig_ltp_fx[0] = *ptr_mem_stp; - move16(); - - /* Control short term pst filter gain and compute parcor0 */ - Calc_st_filt_tbe_ivas_dec_fx( apond2_fx, apond1_fx, &parcor0_fx, sig_ltp_fx + 1, mem_zero ); - /* o: parcor0 in Q15 */ - /* i/o: sig_ltp_fx in Q_bwe_exc */ - - /* 1/A(gamma1) filtering, mem_stp is updated */ - Syn_filt_s( 0, apond1_fx, LPC_SHB_ORDER, sig_ltp_fx + 1, sig_ltp_fx + 1, L_SUBFR16k, mem_stp, 1 ); - - /* (1 + mu z-1) tilt filtering */ - filt_mu_fx( sig_ltp_fx, sig_out, parcor0_fx, L_SUBFR16k ); - /* o: sig_out in Q_bwe_exc */ - - /* gain control */ - scale_st_swb( sig_in, sig_out, ptr_gain_prec, L_SUBFR16k ); - - return; -} - -void flip_spectrum_and_decimby4_fx( - const Word16 input[], /* i : input spectrum Q_inp */ - Word16 output[], /* o : output spectrum Q_inp */ - const Word16 length, /* i : vector length */ - Word16 mem1[], /* i/o : memory Q_inp */ - Word16 mem2[], /* i/o : memory Q_inp */ - const Word16 ramp_flag /*i: flag to trigger slow ramp-up of output following change of core (HQ to ACELP or 12k8 to 16k ACELP) */ -) -{ - Word16 i; - Word16 factor, tmp[L_FRAME16k / 2]; - Word16 tmp1, tmp2; - Word16 input_change[L_FRAME16k]; - - IF( ramp_flag ) - { - factor = div_s( 4, length ); /* Q15 */ - FOR( i = 0; i < length / 4; i += 2 ) - { - tmp1 = extract_l( L_mult0( i, factor ) ); /* Q15 */ - tmp2 = extract_l( L_mult0( add( i, 1 ), factor ) ); /*Q15 */ - input_change[i] = negate( mult_r( input[i], tmp1 ) ); - move16(); - input_change[i + 1] = mult_r( input[i + 1], tmp2 ); - move16(); - } - } - ELSE - { - i = 0; - move16(); - } - - FOR( ; i < length; i = i + 2 ) - { - input_change[i] = negate( input[i] ); - move16(); - input_change[i + 1] = input[i + 1]; - move16(); - } - - Decimate_allpass_steep_fx( input_change, mem1, length, tmp ); - Decimate_allpass_steep_fx( tmp, mem2, shr( length, 1 ), output ); - - return; -} - - -/*==========================================================================*/ -/* FUNCTION : void GenShapedWBExcitation_fx () */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : Synthesize spectrally shaped highband excitation signal for the wideband */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _Word16 *lpc_shb i : lpc coefficients Q12 */ -/* _Word16 coder_type i : coding type */ -/* _Word16 *bwe_exc_extended i : bwidth extended exciatation Q_bwe_exc*/ -/* _Word16 Q_bwe_exc i : Q format */ -/* _Word16 voice_factors[] i : voicing factor Q15 */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _Word16 *excSHB o : synthesized shaped shb exctiation Q_bwe_exc*/ -/* _Word16 *exc4kWhtnd o : whitened synthesized shb excitation Q_bwe_exc*/ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _Word32 *mem_csfilt i/o : memory Q_bwe_exc+16*/ -/* _Word16 *mem_genSHBexc_filt_down1 i/o : memory Q_bwe_exc */ -/* _Word16 *mem_genSHBexc_filt_down2 i/o : memory Q_bwe_exc */ -/* _Word16 *mem_genSHBexc_filt_down3 i/o : memory Q_bwe_exc */ -/* _Word16 *state_lpc_syn i/o : memory Q_bwe_exc */ -/* _Word16 bwe_seed[] i/o : random number generator seed */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* CALLED FROM : */ -/*==========================================================================*/ - -void GenShapedWBExcitation_ivas_fx( - Word16 *excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ - const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q_bwe_exc*/ - Word32 *mem_csfilt, /* i/o : memory Q_bwe_exc+16*/ - Word16 *mem_genSHBexc_filt_down1, /* i/o : memory Q_bwe_exc*/ - Word16 *mem_genSHBexc_filt_down2, /* i/o : memory Q_bwe_exc*/ - Word16 *mem_genSHBexc_filt_down3, /* i/o : memory Q_bwe_exc*/ - Word16 *state_lpc_syn, /* i/o : memory Q_bwe_exc*/ - const Word16 coder_type, /* i : coding type */ - const Word16 *bwe_exc_extended, /* i : bwidth extended exciatation Q_bwe_exc*/ - const Word16 Q_bwe_exc, - Word16 bwe_seed[], /* i/o : random number generator seed */ - const Word16 voice_factors[], /* i : voicing factor Q15*/ - const Word16 uv_flag, /* i : unvoiced flag */ - const Word16 igf_flag ) -{ - Word16 i, j, k; - Word16 wht_fil_mem[LPC_WHTN_ORDER_WB]; - Word16 lpc_whtn[LPC_WHTN_ORDER_WB + 1]; - Word16 R_h[LPC_WHTN_ORDER_WB + 2], R_l[LPC_WHTN_ORDER_WB + 2]; - Word16 Q_R; - Word16 excTmp[L_FRAME16k]; - Word16 excTmp2[L_FRAME16k / 4]; - Word16 excTmp2_frac[L_FRAME16k / 4]; - Word16 exc4k[L_FRAME16k / 4]; - Word16 exc4k_frac[L_FRAME16k / 4]; - Word32 exc4k_32[L_FRAME16k / 4]; - Word32 pow1, pow22; - Word16 scale; - Word32 excNoisyEnv[L_FRAME16k / 4]; - Word16 csfilt_num2[1] = { 1638 }; /* Q15*/ - Word16 neg_csfilt_den2[2] = { -32768, 31457 }; /* Q15 */ - Word32 L_tmp, Ltemp1, Ltemp2; - Word16 temp1, temp2, exp; - Word32 Lmax; - Word16 max_val, n1, n2, sc; - Word32 LepsP[LPC_WHTN_ORDER_WB + 1]; - Word16 tmp_vfac; - Word16 avg_voice_fac; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move16(); -#endif - - /*0.25f*sum_f(voice_factors, NB_SUBFR)*/ - L_tmp = L_mult( voice_factors[0], 8192 /* 0.25 in Q15 */ ); - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mac( L_tmp, voice_factors[i], 8192 /* 0.25 in Q15 */ ); - } - avg_voice_fac = round_fx( L_tmp ); - - test(); - test(); - test(); - test(); - IF( igf_flag != 0 && ( EQ_16( coder_type, VOICED ) || GT_16( avg_voice_fac, 11469 /* 0.35 in Q15 */ ) ) ) /*Q15 -> 0.35f*/ - { - csfilt_num2[0] = 6554; - move16(); /*Q15 -> 0.2f*/ - neg_csfilt_den2[1] = 26214; - move16(); /*Q15 -> 0.8f*/ - } - ELSE IF( igf_flag != 0 && ( EQ_16( coder_type, UNVOICED ) || LT_16( avg_voice_fac, 6654 /* 0.2 in Q15*/ ) ) ) /*Q15 -> 0.2f*/ - { - csfilt_num2[0] = 328; - move16(); /*Q15 -> 0.01f*/ - neg_csfilt_den2[1] = 32440; - move16(); /*Q15 -> 0.99f*/ - } - set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER_WB ); - Decimate_allpass_steep_fx( bwe_exc_extended, mem_genSHBexc_filt_down1, L_FRAME32k, excTmp ); - flip_spectrum_and_decimby4_fx( excTmp, exc4k, L_FRAME16k, mem_genSHBexc_filt_down2, mem_genSHBexc_filt_down3, 0 ); - - IF( uv_flag ) - { - create_random_vector_fx( exc4kWhtnd, L_FRAME16k / 4, bwe_seed ); - IF( LT_16( Q_bwe_exc, 5 ) ) - { - - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4kWhtnd[i] = shl_r( exc4kWhtnd[i], sub( Q_bwe_exc, 5 ) ); /*Q(Q_bwe_exc)/Q5(if Q_bwe_exc > 5) */ - move16(); - } - } - } - ELSE - { - autocorr_fx( exc4k, LPC_WHTN_ORDER_WB + 1, R_h, R_l, &Q_R, - L_FRAME16k / 4, win_flatten_4k_fx, 0, 1 ); - - /* Ensure R[0] isn't zero when entering Levinson Durbin */ - R_l[0] = s_max( R_l[0], 1 ); - move16(); - FOR( i = 1; i <= LPC_WHTN_ORDER_WB; i++ ) - { - L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); - L_Extract( L_tmp, &R_h[i], &R_l[i] ); - } - - E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER_WB, NULL ); - - Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER_WB + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); - - fir_fx( exc4k, lpc_whtn, exc4kWhtnd, wht_fil_mem, L_FRAME16k / 4, - LPC_WHTN_ORDER_WB, 0, 3 ); - - /* Ensure pow1 is greater than zero when computing normalization */ - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - excTmp2[i] = abs_s( exc4kWhtnd[i] ); - move16(); /* Q_bwe_exc */ - max_val = s_max( max_val, excTmp2[i] ); - move16(); - } - - IF( max_val == 0 ) - { - pow1 = 1; - move16(); - n1 = 0; - move16(); - } - ELSE - { - n1 = norm_s( max_val ); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); // Q_bwe_exc + n1 - move16(); /* Q14 */ - } - n1 = sub( sub( 14, n1 ), Q_bwe_exc ); - pow1 = 1; - move32(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ - pow1 = L_add_o( pow1, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ - } - } - - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); - move32(); /* Q_bwe_exc+16 */ - *mem_csfilt = Mult_32_16( excNoisyEnv[i], neg_csfilt_den2[1] ); - move32(); /* Q_bwe_exc+16 */ - } - - create_random_vector_fx( exc4k, L_FRAME16k / 4, bwe_seed ); - - /* Ensure pow22 is greater than zero when computing normalization */ - Lmax = 0; - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4k_32[i] = Mult_32_16( excNoisyEnv[i], exc4k[i] ); - move32(); /* Q_bwe_exc+6 */ - Lmax = L_max( Lmax, L_abs( exc4k_32[i] ) ); - } - - IF( Lmax == 0 ) - { - pow22 = 1; - move16(); - n2 = 0; - move16(); - set16_fx( exc4k_frac, 0, L_FRAME16k / 4 ); - } - ELSE - { - n2 = norm_l( Lmax ); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ - move16(); - } - n2 = 30 - n2 - ( Q_bwe_exc + 6 ); - pow22 = 1; - move32(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ - pow22 = L_add_o( pow22, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ - } - } - - test(); - test(); - IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 /* 0.2 in Q15 */ ) ) ) - { - L_tmp = root_a_over_b_fx( pow1, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); - scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ - sc = sub( add( n2, Q_bwe_exc ), 14 ); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ - move16(); - } - } - ELSE - { - sc = sub( add( n2, Q_bwe_exc ), 14 ); /* Q_bwe_exc+n2-14*/ - - k = 0; - FOR( i = 0; i < 4; i++ ) - { - test(); - IF( igf_flag != 0 && EQ_16( coder_type, VOICED ) ) - { - /*tmp_vfac = 2*voice_factors[i]; - tmp_vfac = min(1, tmp_vfac);*/ - tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); - } - ELSE - { - tmp_vfac = voice_factors[i]; - move16(); - } - - Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); - temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ - L_tmp = Mult_32_16( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ - Ltemp2 = root_a_over_b_fx( L_tmp, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); - temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ - FOR( j = 0; j < L_FRAME16k / 16; j++ ) - { - L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ - L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ - exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ - move16(); - k++; - } - } - } - } - - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); - - return; -} - -void GenShapedWBExcitation_fx( - Word16 *excSHB, /* o : synthesized shaped shb exctiation Q(Q_bwe_exc) */ - const Word16 *lpc_shb, /* i : lpc coefficients Q12 */ - Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q(Q_bwe_exc) */ - Word32 *mem_csfilt, /* i/o : memory Q(Q_bwe_exc+16) */ - Word16 *mem_genSHBexc_filt_down1, /* i/o : memory Q(Q_bwe_exc) */ - Word16 *mem_genSHBexc_filt_down2, /* i/o : memory Q(Q_bwe_exc) */ - Word16 *mem_genSHBexc_filt_down3, /* i/o : memory Q(Q_bwe_exc) */ - Word16 *state_lpc_syn, /* i/o : memory Q(Q_bwe_exc) */ - const Word16 coder_type, /* i : coding type */ - const Word16 *bwe_exc_extended, /* i : bwidth extended exciatation Q(Q_bwe_exc) */ - const Word16 Q_bwe_exc, /* i : Q for memories */ - Word16 bwe_seed[], /* i/o : random number generator seed */ - const Word16 voice_factors[], /* i : voicing factor Q15 */ - const Word16 uv_flag, /* i : unvoiced flag */ - const Word16 igf_flag ) -{ - Word16 i, j, k; - Word16 wht_fil_mem[LPC_WHTN_ORDER_WB]; - Word16 lpc_whtn[LPC_WHTN_ORDER_WB + 1]; - Word16 R_h[LPC_WHTN_ORDER_WB + 2], R_l[LPC_WHTN_ORDER_WB + 2]; - Word16 Q_R; - Word16 excTmp[L_FRAME16k]; - Word16 excTmp2[L_FRAME16k / 4]; - Word16 excTmp2_frac[L_FRAME16k / 4]; - Word16 exc4k[L_FRAME16k / 4]; - Word16 exc4k_frac[L_FRAME16k / 4]; - Word32 exc4k_32[L_FRAME16k / 4]; - Word32 pow1, pow22; - Word16 scale; - Word32 excNoisyEnv[L_FRAME16k / 4]; - Word16 csfilt_num2[1] = { 1638 }; /* Q15*/ - Word16 neg_csfilt_den2[2] = { -32768, 31457 }; /* Q15 */ - Word32 L_tmp, Ltemp1, Ltemp2; - Word16 temp1, temp2, exp; - Word32 Lmax; - Word16 max_val, n1, n2, sc; - Word32 LepsP[LPC_WHTN_ORDER_WB + 1]; - Word16 tmp_vfac; - Word16 avg_voice_fac; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - move16(); - move16(); - move16(); - - /*0.25f*sum_f(voice_factors, NB_SUBFR)*/ - L_tmp = L_mult( voice_factors[0], 8192 /*0.25 in Q15 */ ); - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mac( L_tmp, voice_factors[i], 8192 /*0.25 in Q15 */ ); - } - avg_voice_fac = round_fx( L_tmp ); - - test(); - test(); - test(); - test(); - IF( igf_flag != 0 && ( EQ_16( coder_type, VOICED ) || GT_16( avg_voice_fac, 11469 /* 0.35 in Q15 */ ) ) ) /*Q15 -> 0.35f*/ - { - csfilt_num2[0] = 6554; - move16(); /*Q15 -> 0.2f*/ - neg_csfilt_den2[1] = 26214; - move16(); /*Q15 -> 0.8f*/ - } - ELSE IF( igf_flag != 0 && ( EQ_16( coder_type, UNVOICED ) || LT_16( avg_voice_fac, 6654 /* 0.2 in Q15 */ ) ) ) /*Q15 -> 0.2f*/ - { - csfilt_num2[0] = 328; - move16(); /*Q15 -> 0.01f*/ - neg_csfilt_den2[1] = 32440; - move16(); /*Q15 -> 0.99f*/ - } - set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER_WB ); - Decimate_allpass_steep_fx( bwe_exc_extended, mem_genSHBexc_filt_down1, L_FRAME32k, excTmp ); - flip_spectrum_and_decimby4_fx( excTmp, exc4k, L_FRAME16k, mem_genSHBexc_filt_down2, mem_genSHBexc_filt_down3, 0 ); - - IF( uv_flag ) - { - create_random_vector_fx( exc4kWhtnd, L_FRAME16k / 4, bwe_seed ); - IF( LT_16( Q_bwe_exc, 5 ) ) - { - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4kWhtnd[i] = shl_r( exc4kWhtnd[i], sub( Q_bwe_exc, 5 ) ); /*Q(Q_bwe_exc)/Q5(if Q_bwe_exc > 5) */ - move16(); - } - } - } - ELSE - { - autocorr_fx( exc4k, LPC_WHTN_ORDER_WB + 1, R_h, R_l, &Q_R, - L_FRAME16k / 4, win_flatten_4k_fx, 0, 1 ); - - /* Ensure R[0] isn't zero when entering Levinson Durbin */ - R_l[0] = s_max( R_l[0], 1 ); - move16(); - FOR( i = 1; i <= LPC_WHTN_ORDER_WB; i++ ) - { - L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); - L_Extract( L_tmp, &R_h[i], &R_l[i] ); - } - - E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER_WB, NULL ); - - Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER_WB + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); - - fir_fx( exc4k, lpc_whtn, exc4kWhtnd, wht_fil_mem, L_FRAME16k / 4, - LPC_WHTN_ORDER_WB, 0, 3 ); - - /* Ensure pow1 is greater than zero when computing normalization */ - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - excTmp2[i] = abs_s( exc4kWhtnd[i] ); - move16(); /* Q_bwe_exc */ - max_val = s_max( max_val, excTmp2[i] ); - move16(); - } - - IF( max_val == 0 ) - { - pow1 = 1; - move16(); - n1 = 0; - move16(); - } - ELSE - { - n1 = norm_s( max_val ); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); - move16(); /* Q14 */ - } - n1 = sub( sub( 14, n1 ), Q_bwe_exc ); - pow1 = 1; - move32(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ - pow1 = L_add_o( pow1, L_shr( L_tmp, 7 ), &Overflow ); /* Q22 */ - } - } - - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); - move32(); /* Q_bwe_exc+16 */ - *mem_csfilt = Mpy_32_16_1( excNoisyEnv[i], neg_csfilt_den2[1] ); - move32(); /* Q_bwe_exc+16 */ - } - - create_random_vector_fx( exc4k, L_FRAME16k / 4, bwe_seed ); - - /* Ensure pow22 is greater than zero when computing normalization */ - Lmax = 0; - move32(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4k_32[i] = Mpy_32_16_1( excNoisyEnv[i], exc4k[i] ); - move32(); /* Q_bwe_exc+6 */ - Lmax = L_max( Lmax, L_abs( exc4k_32[i] ) ); - } - - IF( Lmax == 0 ) - { - pow22 = 1; - move16(); - n2 = 0; - move16(); - set16_fx( exc4k_frac, 0, L_FRAME16k / 4 ); - } - ELSE - { - n2 = norm_l( Lmax ); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ - move16(); - } - n2 = sub( sub( 30, n2 ), add( Q_bwe_exc, 6 ) ); - pow22 = 1; - move32(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ - pow22 = L_add_o( pow22, L_shr( L_tmp, 7 ), &Overflow ); /* Q22 */ - } - } - - test(); - test(); - IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 /*0.2 in Q15 */ ) ) ) - { - L_tmp = root_a_over_b_fx( pow1, sub( 22, shl( n1, 1 ) ), pow22, sub( 22, shl( n2, 1 ) ), &exp ); - scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ - sc = sub( add( n2, Q_bwe_exc ), 14 ); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ - move16(); - } - } - ELSE - { - sc = sub( add( n2, Q_bwe_exc ), 14 ); /* Q_bwe_exc+n2-14*/ - - k = 0; - move16(); - FOR( i = 0; i < 4; i++ ) - { - test(); - IF( igf_flag != 0 && EQ_16( coder_type, VOICED ) ) - { - /*tmp_vfac = 2*voice_factors[i]; - tmp_vfac = min(1, tmp_vfac);*/ - tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); - } - ELSE - { - tmp_vfac = voice_factors[i]; - move16(); - } - - Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); - temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ - L_tmp = Mpy_32_16_1( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ - Ltemp2 = root_a_over_b_fx( L_tmp, sub( 22, shl( n1, 1 ) ), pow22, sub( 22, shl( n2, 1 ) ), &exp ); - temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ - FOR( j = 0; j < L_FRAME16k / 16; j++ ) - { - L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ - L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ - exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ - move16(); - k = add( k, 1 ); - } - } - } - } - - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); - - - return; -} - -/*-------------------------------------------------------------------* - * GenWBSynth() - * - * Generate 16 KHz sampled highband component from synthesized highband - *-------------------------------------------------------------------*/ - -void GenWBSynth_fx( - const Word16 *input_synspeech, /* i : input synthesized speech Qx*/ - Word16 *shb_syn_speech_16k, /* o : output highband compnent Qx*/ - Word16 *state_lsyn_filt_shb1, /* i/o: memory Qx*/ - Word16 *state_lsyn_filt_shb2 /* i/o: memory Qx*/ -) -{ - Word16 speech_buf_16k1[L_FRAME16k], speech_buf_16k2[L_FRAME16k]; - Word16 i, maxm, nor; - Word16 input_synspeech_temp[L_FRAME16k / 4]; - - maxm = 0; - move16(); - FOR( i = 0; i < L_FRAME16k / 4; i++ ) - { - maxm = s_max( maxm, abs_s( input_synspeech[i] ) ); - } - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - maxm = s_max( maxm, abs_s( state_lsyn_filt_shb1[i] ) ); - } - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - maxm = s_max( maxm, abs_s( state_lsyn_filt_shb2[i] ) ); - } - - nor = s_max( sub( norm_s( maxm ), 3 ), 0 ); /* Headroom = 3 */ - IF( maxm == 0 ) - nor = 15; - move16(); - - Copy_Scale_sig( input_synspeech, input_synspeech_temp, L_FRAME16k / 4, nor ); - Scale_sig( state_lsyn_filt_shb1, 2 * ALLPASSSECTIONS_STEEP, nor ); - Scale_sig( state_lsyn_filt_shb2, 2 * ALLPASSSECTIONS_STEEP, nor ); - Interpolate_allpass_steep_fx( input_synspeech_temp, state_lsyn_filt_shb1, L_FRAME16k / 4, speech_buf_16k1 ); - Interpolate_allpass_steep_fx( speech_buf_16k1, state_lsyn_filt_shb2, L_FRAME16k / 2, speech_buf_16k2 ); - flip_spectrum_fx( speech_buf_16k2, shb_syn_speech_16k, L_FRAME16k ); - - Scale_sig( shb_syn_speech_16k, L_FRAME16k, negate( nor ) ); - Scale_sig( state_lsyn_filt_shb1, 2 * ALLPASSSECTIONS_STEEP, negate( nor ) ); - Scale_sig( state_lsyn_filt_shb2, 2 * ALLPASSSECTIONS_STEEP, negate( nor ) ); - - return; -} - - -void find_td_envelope_fx( - const Word16 inp[], /* i : input signal Qx */ - const Word16 len, /* i : length of the input signal */ - const Word16 len_h, /* i : length of the MA filter */ - Word16 mem_h[], /* i/o: memory of the MA filter, length len_h/2 Qx */ - Word16 out[] /* o : td envelope of the input signal Qx */ -) -{ - Word16 k, K; - Word16 buf_in[L_FRAME16k + MAX_LEN_MA_FILTER], *p_in, *p_out, *p_prev, w; - Word16 tmp1, tmp2; - - assert( len > 0 && len <= L_FRAME16k ); - - // len_h is 20 at all calling locations - K = 10; /* length of FIR filter memory = half of the total filter length */ - move16(); - w = 1639; /* 1 / 20 in Q15 */ /* MA filtering coefficient */ - move16(); - - /* copy filter memory to the input buffer */ - IF( mem_h != NULL ) - { - Copy( mem_h, buf_in, K ); - } - ELSE - { - /* no memory available, use the first len_h/2 samples as memory */ - p_in = buf_in; - FOR( k = 0; k < K; k++ ) - { - *p_in++ = mult_r( abs_s( inp[k] ), w ); /* Qx */ - move16(); - } - } - - /* take the absolute value of the input signal and copy it to the input buffer */ - /* multiply each value by 1 / filter length */ - p_in = &buf_in[K]; - FOR( k = 0; k < len; k++ ) - { - *p_in++ = mult_r( abs_s( inp[k] ), w ); /* Qx */ - move16(); - } - - /* update filter memory from the end of the input buffer */ - IF( mem_h != NULL ) - { - Copy( &buf_in[len], mem_h, K ); - } - - /* do MA filtering */ - out[0] = sum16_fx( buf_in, len_h ); - move16(); - p_out = &buf_in[0]; /* pointer to leaving sample */ - p_in = &buf_in[len_h]; /* pointer to entering sample*/ - FOR( k = 1; k < len - K; k++ ) - { - tmp1 = *p_out++; - move16(); - tmp2 = *p_in++; - move16(); - out[k] = add( sub( out[k - 1], tmp1 ), tmp2 ); /* Qx */ - move16(); - } - - /* use IIR filtering to extrapolate the last K samples */ - p_in = &buf_in[len - K]; - p_out = &out[len - K]; - p_prev = p_out - 1; - FOR( k = 0; k < K; k++ ) - { - tmp1 = *p_in++; - move16(); - tmp2 = *p_prev++; - move16(); - *p_out++ = add( mult_r( 1638 /* 0.05f in Q15 */, ( tmp1 ) ), mult_r( 31130 /* 0.95f in Q15 */, ( tmp2 ) ) ); - move16(); - } - - return; -} - - -/*======================================================================================*/ -/* FUNCTION : void GenShapedSHBExcitation_fx () */ -/*--------------------------------------------------------------------------------------*/ -/* PURPOSE : Synthesize spectrally shaped highband excitation signal */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _(Word16) coder_type : coding type Q_bwe_exc */ -/* _(Word16) bwidth : input signal bwidth Q0 */ -/* _(Word16*) bwe_exc_extended :bwidth extended exciatation Q_bwe_exc */ -/* _(Word16[]) voice_factors :voicing factors Q15 */ -/* _(Word16*) lpc_shb :lpc coefficients Q12 */ -/* _(Word16*) Q_bwe_exc :Q Format of bwe_exc_extended */ -/* _(Word16) L_frame : Frame length - determines whether 12.8 or 16kHz core */ -/* _(Word16) last_L_frame : last L_frame */ -/*--------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _(Word16*)excSHB :synthesized shaped shb excitation Q_bwe_exc */ -/* _(Word16*)White_exc16k :white excitation for the Fullband extension Q_bwe_exc */ -/* _(Word16*)slope :slope +ve (high freq > low freq), -ve or neutral Q12 */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _(Word16*)mem_csfilt :memory */ -/* _(Word16*)mem_genSHBexc_filt_down_shb :memory */ -/* _(Word16*)state_lpc_syn :memory */ -/* _(Word16[]) bwe_seed :random number generator seed */ -/* _(Word16[]) lpf_14k_mem :memory */ -/* _(Word32[])Hilbert_Mem :memory */ -/*--------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------------------*/ -/* CALLED FROM : RX */ -/*======================================================================================*/ -void GenShapedSHBExcitation_fx( - Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ - const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ - Word32 *mem_csfilt, /* i/o: memory */ - Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ - Word16 *state_lpc_syn, /* i/o: memory */ - const Word16 coder_type, /* i : coding type */ - const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ - Word16 bwe_seed[], /* i/o: random number generator seed */ - Word16 voice_factors[], /* i : voicing factor*/ - const Word16 extl, /* i : extension layer */ - Word16 *tbe_demph, /* i/o: de-emphasis memory */ - Word16 *tbe_premph, /* i/o: pre-emphasis memory */ - Word16 *lpc_shb_sf, /* i: LP coefficients */ - const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ - Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ - Word16 *shb_res, - Word16 *vf_ind, - const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ - Word16 fb_state_lpc_syn[], /* i/o: memory */ - Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ - Word16 *Q_bwe_exc, - Word16 *Q_bwe_exc_fb, - const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ - const Word32 bitrate, - const Word16 prev_bfi -#ifdef ADD_IVAS_TBE_CODE - , /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - Word16 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -#endif -) -{ - Word16 i, j, k; - Word16 wht_fil_mem[LPC_WHTN_ORDER]; - Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; - Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ - Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ - Word16 Q_R; - Word32 LepsP[LPC_WHTN_ORDER + 1]; - Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; - Word32 pow1, pow22; - Word16 scale, temp1, temp2; - - Word16 excTmp2[L_FRAME16k]; - Word16 *White_exc16k; - Word16 excNoisyEnv[L_FRAME16k]; - Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ - move16(); - Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ - move16(); - move16(); - Word16 varEnvShape; - Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ - move16(); - Word16 exc16kWhtnd[L_FRAME16k]; - - Word32 L_tmp; - Word16 vf_tmp; - Word16 tmp, exp, tmp2; - Word16 voiceFacEst[NB_SUBFR16k]; - Word16 zero_mem[LPC_SHB_ORDER]; - Word32 syn_shb_ener_sf[4]; - Word16 tempSHB[80]; - Word16 Q_pow1, Q_pow22; - - Word32 L_tmp2, L_tmp3, L_tmp4; - Word16 temp; - - Word16 White_exc16k_FB_temp[L_FRAME16k]; - Word32 White_exc16k_32[L_FRAME16k]; - Word16 Q_temp; - Word16 prev_Q_bwe_exc_fb; - -#ifdef ADD_IVAS_TBE_CODE - Word32 tempD; - Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; - Word16 cbsize; - Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; - Word16 c0, c1, c2, c3, c4, c5, g1, g2, g, den; - Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; - Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; - Word16 flag_plosive; - Word16 delta; - Word16 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; - - mix_factor = 0.0f; -#endif - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); - - FOR( i = 0; i < L_FRAME32k; i = i + 2 ) - { - exc32k[i] = negate( bwe_exc_extended[i] ); - move16(); - exc32k[i + 1] = bwe_exc_extended[i + 1]; - move16(); - } - - /* Decimate by 2 */ - Decimate_allpass_steep_fx( exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k ); - /* i: exc32k in Q_bwe_exc */ - /* o: exc16k in Q_bwe_exc */ - - autocorr_fx( exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1 ); - /* Ensure R[0] isn't zero when entering Levinson Durbin */ - R_l[0] = s_max( R_l[0], 1 ); - move16(); - FOR( i = 1; i <= LPC_WHTN_ORDER; i++ ) - { - L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); - L_Extract( L_tmp, &R_h[i], &R_l[i] ); - } - E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL ); - Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); - fir_fx( exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3 ); - - /* i: exc16k in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc */ - -#ifdef ADD_IVAS_TBE_CODE - IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif - { - temp2 = 0; - move16(); - FOR( j = 0; j < 4; j++ ) - { - temp1 = shb_res_gshape[j]; - move16(); - FOR( i = 0; i < 80; i++ ) - { - exc16kWhtnd[temp2 + i] = round_fx( L_shl( L_mult( exc16kWhtnd[temp2 + i], temp1 ), 1 ) ); - move16(); - /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ - } - temp2 = add( temp2, 80 ); - } - } - - /* Estimate pow1 associated with Low band nonlinear extended excitation */ - /* pow1=0.00001f */ - tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); - pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ - excTmp2[k] = abs_s( exc16kWhtnd[k] ); - move16(); - - /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ - pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ - } - Q_pow1 = shl( *Q_bwe_exc, 1 ); - - test(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( flag_ACELP16k, 0 ) ) -#else - IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) -#endif - { - /* varEnvShape = mean_fx(voice_factors, 4); */ - /* unroll the loop */ - L_tmp = L_mult( voice_factors[0], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors[1], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors[2], 8192 ); - varEnvShape = mac_r( L_tmp, voice_factors[3], 8192 ); /* varEnvShape in Q15 */ - } - ELSE /* 16k core */ - { - /* varEnvShape = mean_fx(voice_factors, 5); */ - /* unroll the loop */ - L_tmp = L_mult( voice_factors[0], 6554 ); - L_tmp = L_mac( L_tmp, voice_factors[1], 6554 ); - L_tmp = L_mac( L_tmp, voice_factors[2], 6554 ); - L_tmp = L_mac( L_tmp, voice_factors[3], 6554 ); - varEnvShape = mac_r( L_tmp, voice_factors[4], 6554 ); /* varEnvShape in Q15 */ - } - - IF( EQ_16( extl, FB_TBE ) ) - { - /*pow(varEnvShape,3) */ - tmp = mult_r( varEnvShape, varEnvShape ); - tmp = mult_r( tmp, varEnvShape ); - - /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ - fb_deemph_fac = sub( 22282 /*0.68f Q15*/, tmp ); - fb_deemph_fac = s_max( fb_deemph_fac, 15729 /*0.48f Q15*/ ); - } - - /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ - varEnvShape = msu_r( 1179773824l /*0.549375f Q31*/, 8172 /*0.249375f Q15*/, varEnvShape ); - - /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ - varEnvShape = s_max( varEnvShape, 9830 /*0.3f Q15*/ ); - varEnvShape = s_min( varEnvShape, 16368 /*0.4995f Q15*/ ); - varEnvShape = shl( varEnvShape, 1 ); - csfilt_num2[0] = sub( MAX_16, varEnvShape ); - move16(); - neg_csfilt_den2[1] = varEnvShape; - move16(); - - test(); - test(); - test(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#else - IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#endif - { - /* pre-init smoothing filter to avoid energy drop outs */ - L_tmp = L_mult( excTmp2[0], 1638 ); - FOR( i = 1; i < L_SUBFR16k / 4; i++ ) - { - L_tmp = L_mac( L_tmp, excTmp2[i], 1638 ); /*1638 = 1/20 in Q15*/ - } - /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ - - /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ - /* rather stick to the more conservative approach, to avoid potential clippings */ - test(); - IF( !( prev_bfi && EQ_16( extl, FB_TBE ) ) ) - { - /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ - varEnvShape = 26214 /*0.8f Q15*/; - move16(); - csfilt_num2[0] = sub( MAX_16, varEnvShape ); - move16(); - neg_csfilt_den2[1] = varEnvShape; - move16(); - } - - *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); - move32(); - } -#ifdef ADD_IVAS_TBE_CODE - if ( MSFlag > 0 ) - { - varEnvShape = 0.995f; - csfilt_num2[0] = 1.0f - varEnvShape; - csfilt_den2[1] = -varEnvShape; - } - - White_exc16k = exc16k; - - /* Track the low band envelope */ - if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) - { - if ( extl_brate != SWB_TBE_1k10 && extl_brate != SWB_TBE_1k75 ) - { - mem_csfilt_left = 0.0f; - mem_csfilt_right = 0.0f; - for ( k = 0; k < L_FRAME16k; k++ ) - { - excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; - mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; - excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; - mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; - } - - alpha = 0.0f; - step = 1.0f / L_FRAME16k; - for ( k = 0; k < L_FRAME16k; k++ ) - { - excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + ( 1 - alpha ) * excNoisyEnvRight[k]; - alpha += step; - } - } - } - else -#endif - { - /* Track the low band envelope */ - L_tmp = *mem_csfilt; - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - excNoisyEnv[i] = mac_r( L_tmp, csfilt_num2[0], excTmp2[i] ); - move16(); - /* excNoisyEnv : Q_bwe_exc, - *mem_csfilt: Q_bwe_exc+16, excTmp2: Q_bwe_exc, csfilt_num2[0] Q15 */ - L_tmp = L_mult( excNoisyEnv[i], neg_csfilt_den2[1] ); /* Q_bwe_exc+16 */ - } - *mem_csfilt = L_tmp; - move32(); - } -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - /* generate gaussian (white) excitation */ - for ( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k[k] = (float) own_random( &bwe_seed[0] ); - } - - /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - pow22 = POW_EXC16k_WHTND; - v_multc( White_exc16k, (float) sqrt( pow1 / pow22 ), White_exc16k, L_FRAME16k ); - } - else -#endif - { - /* create a random excitation - Reuse exc16k memory */ - White_exc16k = exc16k; - create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); - create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); - - L_tmp = L_deposit_l( 0 ); - tmp = add( *Q_bwe_exc, 1 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - L_tmp4 = L_shl_sat( L_deposit_l( White_exc16k[k] ), tmp ); - if ( excNoisyEnv[k] != 0 ) - { - L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_bwe_exc) +5 +1*/ - } - White_exc16k_32[k] = L_tmp4; - move32(); - L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); - } - Q_temp = norm_l( L_tmp ); - if ( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } - /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ - /* White_exc16k in Q6 */ - - /* calculate pow22 */ - /* pow22=0.00001f */ - tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - pow22 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc-NOISE_QADJ) */ - tmp = sub( NOISE_QFAC, 5 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /* White_exc16k[k] *= excNoisyEnv[k]; */ - White_exc16k[k] = mult_r( excNoisyEnv[k], shl( White_exc16k[k], tmp ) ); - move16(); - /* i: excNoisyEnv in (Q_bwe_exc) */ - /* i: White_exc16k in Q6 */ - /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ - /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ - } - /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ - Q_pow22 = shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ); - } - -#ifdef ADD_IVAS_TBE_CODE - flag_plosive = 0; - move16(); - test(); - test(); - test(); - IF(GE_32(extl_brate, SWB_TBE_2k8) || EQ_32(extl_brate, SWB_TBE_1k10) || EQ_32(extl_brate, SWB_TBE_1k75))) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif - { - IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ - { -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ - find_td_envelope( White_exc16k, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); - find_td_envelope( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); - - for ( k = 0; k < L_FRAME4k; k++ ) - { - EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; - EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; - } - - /* calculate the optimal mix factor */ - c0 = c1 = c2 = c3 = c4 = c5 = 0.0f; - for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - - c0 += c0_part[i]; - c1 += c1_part[i]; - c2 += c2_part[i]; - c3 += c3_part[i]; - c4 += c4_part[i]; - c5 += c5_part[i]; - } - - den = 4.0f * c0 * c2 - c4 * c4; - g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; - g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; - - *Env_error = 0.0f; - flag_plosive = 0; - for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; - *Env_error += Env_error_part[i]; - - if ( Env_error_part[i] > THR_ENV_ERROR_PLOSIVE ) - { - /* envelope error is too high -> likely a plosive */ - flag_plosive = 1; - } - } - - if ( flag_plosive ) - { - /* plosive detected -> set the mixing factor to 0 */ - *vf_ind = 0; - mix_factor = 0.0f; - } - else - { - /* normalize gain */ - g = g2 / ( g1 + g2 ); - - /* quantization of the mixing factor */ - cbsize = 1 << NUM_BITS_SHB_VF; - delta = 1.0f / ( cbsize - 1 ); - if ( g > 1.0f ) - { - g = 1.0f; - } - else if ( g < delta ) - { - /* prevent low gains to be quantized to 0 as this is reserved for plosives */ - g = delta; - } - - *vf_ind = usquant( g, &mix_factor, 0.0f, 1.0f / ( cbsize - 1 ), cbsize ); - } - } - else -#endif - { - Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, - ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); - tmp = voiceFacEst[0]; - move16(); - tmp2 = MAX_16; - move16(); - if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } - ELSE /* decoder side */ - { -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - if ( *vf_ind == 0 ) - { - mix_factor = 0.0f; - flag_plosive = 1; - } - else - { - mix_factor = usdequant( *vf_ind, 0.0f, 1.0f / ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) ); - } - } - else -#endif - { - /* *vf_ind is an integer scale by 0.125f*/ - tmp = shl( *vf_ind, ( 15 - 3 ) ); - tmp2 = MAX_16; - move16(); - if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } -#ifdef ADD_IVAS_TBE_CODE - IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) -#endif - { - voice_factors[0] = mult_r( voice_factors[0], tmp2 ); - move16(); - voice_factors[1] = mult_r( voice_factors[1], tmp2 ); - move16(); - voice_factors[2] = mult_r( voice_factors[2], tmp2 ); - move16(); - voice_factors[3] = mult_r( voice_factors[3], tmp2 ); - move16(); - voice_factors[4] = mult_r( voice_factors[4], tmp2 ); - move16(); - } - } -#ifdef ADD_IVAS_TBE_CODE - if ( element_mode >= IVAS_CPE_DFT && nlExc16k != NULL ) - { - /* save buffers for IC-BWE */ - mvr2r( exc16kWhtnd, nlExc16k, L_FRAME16k ); - v_multc( White_exc16k, (float) sqrt( pow1 / pow22 ), mixExc16k, L_FRAME16k ); - } -#endif - - tmp = sub( Q_temp, 3 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_FB[k] = round_fx( L_shl( White_exc16k_32[k], tmp ) ); /* Q_bwe_exc +5 +1 +Q_temp -16 -3 */ - } - prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; - move16(); - *Q_bwe_exc_fb = sub( add( *Q_bwe_exc, Q_temp ), 13 ); - move16(); - deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ - /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - if ( !flag_plosive ) /* use only LB excitation in case of plosives */ - { - /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ - old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); - new_scale = 1.0f; - step_scale = ( new_scale - old_scale ) / ( L_FRAME16k / 2 ); - scale = old_scale; - - /* interpolate between the old and the new value of the mixing factor */ - old_fact = *prev_mix_factor; - new_fact = mix_factor; - step = ( new_fact - old_fact ) / ( L_FRAME16k / 2 ); - fact = old_fact; - - /* mixing of LB and gaussian excitation in the first half of the frame */ - for ( k = 0; k < L_FRAME16k / 2; k++ ) - { - exc16kWhtnd[k] = (float) fact * ( White_exc16k[k] * scale ) + (float) ( 1 - fact ) * exc16kWhtnd[k]; - fact += step; - scale += step_scale; - } - - /* mixing of LB and gaussian excitation in the second half of the frame */ - for ( ; k < L_FRAME16k; k++ ) - { - exc16kWhtnd[k] = (float) new_fact * White_exc16k[k] + (float) ( 1 - new_fact ) * exc16kWhtnd[k]; - } - } - preemph( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - } - else -#endif - { -#ifdef ADD_IVAS_TBE_CODE - if ( coder_type == UNVOICED || MSFlag == 1 ) -#else - IF( EQ_16( coder_type, UNVOICED ) ) -#endif - { - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); - /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx( L_shl( L_tmp, NOISE_QADJ ) ); - move16(); - /* exc16kWhtnd: Q_bwe_exc */ - } - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - /* i/o: exc16kWhtnd (Q_bwe_exc) */ - /* i/o: tbe_premph (Q_bwe_exc) */ - } - ELSE - { - Word16 nbSubFr, lSubFr; - Word16 tempQ15; - Word32 tempQ31; - /*nbSubFr = ( bitrate < ACELP_24k40 )? NB_SUBFR : NB_SUBFR16k;*/ - nbSubFr = NB_SUBFR16k; - lSubFr = ( L_FRAME16k / NB_SUBFR16k ); - IF( LT_32( bitrate, ACELP_24k40 ) ) - { - nbSubFr = NB_SUBFR; - move16(); - lSubFr = ( L_FRAME16k / NB_SUBFR ); - move16(); - } - k = 0; - FOR( i = 0; i < nbSubFr; i++ ) - { - test(); - IF( EQ_16( coder_type, VOICED ) && ( LT_32( bitrate, ACELP_24k40 ) ) ) - { - exp = 0; - move16(); - tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ - temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - exp = 0; - move16(); - tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ - temp = sub( MAX_16, temp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - ELSE - { - /* Adjust noise mixing for formant sharpening filter */ - tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); - /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ - vf_tmp = sub( MAX_16, tempQ15 ); - vf_tmp = mult_r( voice_factors[i], vf_tmp ); - - exp = 0; - move16(); - tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ - temp = sub( MAX_16, vf_tmp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - - FOR( j = 0; j < lSubFr; j++ ) - { - /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); - move16(); - /* Q_bwe_exc */ - } - k = add( k, lSubFr ); - - /* estimate the pre-emph factor */ - tempQ15 = sub( MAX_16, voice_factors[i] ); - exp = 0; - move16(); - temp = Sqrt16( tempQ15, &exp ); - temp = shl( temp, exp - 1 ); - - temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ - temp = div_s( temp, temp2 ); /* Q15 */ - temp = mult_r( PREEMPH_FAC, temp ); - - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); - /* exc16kWhtnd: Q_bwe_exc; - tbe_premph: Q_bwe_exc*/ - } - } - } - -#ifdef ADD_IVAS_TBE_CODE - IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( LT_32( bitrate, ACELP_24k40 ) ) -#endif - { - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: excSHB in Q_bwe_exc */ - } - ELSE - { - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - - Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - - Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - - Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - - Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: tempSHB in Q_bwe_exc */ - /* o: syn_shb_ener_sf in (2*Q_bwe_exc+1) */ - IF( LE_32( bitrate, ACELP_32k ) ) - { - L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); - - /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ - tmp = shl( Q_shb, 1 ); - tmp2 = add( shl( *Q_bwe_exc, 1 ), 1 ); - L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ - - *Q_bwe_exc = sub( *Q_bwe_exc, exp ); - move16(); /* compensate for the exp shift */ - tmp2 = add( prev_Q_bwe_syn, n_mem2 ); - IF( GT_16( *Q_bwe_exc, tmp2 ) ) - { - L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); - *Q_bwe_exc = tmp2; - move16(); - } - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ - exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ - move16(); - } - } - /* i: L_tmp2 in (Q31-exp) */ - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ - - /* Rescale the past memories: LP synth and SHB look ahead buffers */ - tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - state_lpc_syn[i] = shl( state_lpc_syn[i], tmp ); - move16(); - } - FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) - { - excSHB[i] = shl( excSHB[i], tmp ); - move16(); - } - /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ - - Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in (Q_bwe_exc) */ - /* o: excSHB in (Q_bwe_exc) */ - } - - IF( EQ_16( extl, FB_TBE ) ) - { - tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); - Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); - Scale_sig( fb_tbe_demph, 1, tmp ); - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); - /* i: White_exc16k_FB in (14-n2) */ - /* o: White_exc16k_FB_temp in (14-n2) */ - - FOR( i = 0; i < 10; i++ ) - { - FOR( j = 0; j < 32; ++j ) - { - White_exc16k_FB_temp[i * 32 + j] = mult_r( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); - move16(); - } - } - - *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); - move16(); /**Q_bwe_exc_fb +35 +1 -16*/ - flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); - - deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); - } - ELSE - { - set16_fx( White_exc16k_FB, 0, L_FRAME16k ); - } - -#ifdef ADD_IVAS_TBE_CODE - *prev_pow_exc16kWhtnd = pow1; - *prev_mix_factor = mix_factor; -#endif - return; -} - -void GenShapedSHBExcitation_ivas_enc_fx( - Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ - const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc_fb */ - Word32 *mem_csfilt, /* i/o: memory */ - Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ - Word16 *state_lpc_syn, /* i/o: memory */ - const Word16 coder_type, /* i : coding type */ - const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ - Word16 bwe_seed[], /* i/o: random number generator seed */ - Word16 voice_factors[], /* i : voicing factor*/ - const Word16 extl, /* i : extension layer */ - Word16 *tbe_demph, /* i/o: de-emphasis memory */ - Word16 *tbe_premph, /* i/o: pre-emphasis memory */ - Word16 *lpc_shb_sf, /* i: LP coefficients */ - const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ - Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ - Word16 *shb_res, - Word16 *vf_ind, - const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ - Word16 fb_state_lpc_syn[], /* i/o: memory */ - Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ - Word16 *Q_bwe_exc, - Word16 *Q_bwe_exc_fb, - const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ - const Word32 bitrate, - const Word16 prev_bfi, - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - Word16 Q_EnvSHBres_4k, - Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -) -{ - Word16 i, j, k; - Word16 wht_fil_mem[LPC_WHTN_ORDER]; - Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; - Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ - Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ - Word16 Q_R; - Word32 LepsP[LPC_WHTN_ORDER + 1]; - Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; - Word32 pow1, pow22; - Word16 scale, temp1, temp2, temp3; - - Word16 excTmp2[L_FRAME16k]; - Word16 *White_exc16k; - Word16 Q_White_exc16k; - Word16 excNoisyEnv[L_FRAME16k]; - Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ - move16(); - Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ - move16(); - move16(); - Word16 varEnvShape; - Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ - Word16 exc16kWhtnd[L_FRAME16k]; - - Word32 L_tmp; - Word16 vf_tmp; - Word16 tmp, exp, tmp2 = 0; - move16(); - Word16 voiceFacEst[NB_SUBFR16k]; - Word16 zero_mem[LPC_SHB_ORDER]; - Word32 syn_shb_ener_sf[4]; - Word16 syn_shb_ener_sf_q[4]; - Word16 tempSHB[80]; - Word16 Q_pow1, Q_pow22; - - Word32 L_tmp2, L_tmp3, L_tmp4; - Word16 temp; - - Word16 White_exc16k_FB_temp[L_FRAME16k]; - Word32 White_exc16k_32[L_FRAME16k]; - Word16 White_exc16k_tmp[L_FRAME16k]; - Word16 prev_Q_bwe_exc_fb; - - Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; - Word16 cbsize; - Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; - Word32 c0, c1, c2, c3, c4, c5, den; - Word16 g1, g2, g, g1_e, g2_e, g_e, den_e, shift, tmp_e, tmp1_e; - Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; - Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; - Word16 flag_plosive; - Word16 delta; - Word32 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; - Word64 W_tmp; - - mix_factor = 0; /* Q15 */ - move16(); - - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); - FOR( i = 0; i < L_FRAME32k; i = i + 2 ) - { - exc32k[i] = negate( bwe_exc_extended[i] ); // Q_bwe_exc - move16(); - exc32k[i + 1] = bwe_exc_extended[i + 1]; // Q_bwe_exc - move16(); - } - - /* Decimate by 2 */ - Decimate_allpass_steep_fx( exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k ); // Q_bwe_exc - /* i: exc32k in Q_bwe_exc */ - /* o: exc16k in Q_bwe_exc */ - - autocorr_fx( exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1 ); // Q_R - /* Ensure R[0] isn't zero when entering Levinson Durbin */ - R_l[0] = s_max( R_l[0], 1 ); - move16(); - FOR( i = 1; i <= LPC_WHTN_ORDER; i++ ) - { - L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); - L_Extract( L_tmp, &R_h[i], &R_l[i] ); // Q_R - } - E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL ); - Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); // Q12 - fir_fx( exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3 ); // Q_bwe_exc - - /* i: exc16k in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc */ - - IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) - { - temp2 = 0; - move16(); - FOR( j = 0; j < 4; j++ ) - { - temp1 = shb_res_gshape[j]; - move16(); - FOR( i = 0; i < 80; i++ ) - { - exc16kWhtnd[temp2 + i] = round_fx( L_shl( L_mult( exc16kWhtnd[temp2 + i], temp1 ), 1 ) ); // Q_bwe_exc - move16(); - /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ - } - temp2 = add( temp2, 80 ); - } - } - - /* Estimate pow1 associated with Low band nonlinear extended excitation */ - /* pow1=0.00001f */ - tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); - W_tmp = W_shl( 21475 /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ - excTmp2[k] = abs_s( exc16kWhtnd[k] ); - move16(); - - /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ - W_tmp = W_mac_16_16( W_tmp, exc16kWhtnd[k], exc16kWhtnd[k] ); // 2*Q_bwe_exc+1 - } - exp = W_norm( W_tmp ); - pow1 = W_extract_h( W_shl( W_tmp, exp ) ); // 2*Q_bwe_exc+1+exp-32 = // tmp+exp - Q_pow1 = add( tmp, exp ); - - IF( flag_ACELP16k == 0 ) - { - /* varEnvShape = mean_fx(voice_factors, 4); */ - /* unroll the loop */ - L_tmp = L_mult( voice_factors[0], 8192 /*0.25 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[1], 8192 /*0.25 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[2], 8192 /*0.25 in Q15 */ ); - varEnvShape = mac_r( L_tmp, voice_factors[3], 8192 /*0.25 in Q15 */ ); /* varEnvShape in Q15 */ - } - ELSE /* 16k core */ - { - /* varEnvShape = mean_fx(voice_factors, 5); */ - /* unroll the loop */ - L_tmp = L_mult( voice_factors[0], 6554 /*0.2 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[1], 6554 /*0.2 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[2], 6554 /*0.2 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[3], 6554 /*0.2 in Q15 */ ); - varEnvShape = mac_r( L_tmp, voice_factors[4], 6554 /*0.2 in Q15 */ ); /* varEnvShape in Q15 */ - } - - IF( EQ_16( extl, FB_TBE ) ) - { - /*pow(varEnvShape,3) */ - tmp = mult_r( varEnvShape, varEnvShape ); - tmp = mult_r( tmp, varEnvShape ); - - /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ - fb_deemph_fac = sub( 22282 /*0.68f Q15*/, tmp ); - fb_deemph_fac = s_max( fb_deemph_fac, 15729 /*0.48f Q15*/ ); - } - - /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ - varEnvShape = msu_r( 1179773824l /*0.549375f Q31*/, 8172 /*0.249375f Q15*/, varEnvShape ); - - /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ - varEnvShape = s_max( varEnvShape, 9830 /*0.3f Q15*/ ); - varEnvShape = s_min( varEnvShape, 16368 /*0.4995f Q15*/ ); - varEnvShape = shl( varEnvShape, 1 ); - csfilt_num2[0] = sub( MAX_16, varEnvShape ); // Q15 - move16(); - neg_csfilt_den2[1] = varEnvShape; // Q15 - move16(); - - test(); - test(); - test(); - test(); - IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) - { - /* pre-init smoothing filter to avoid energy drop outs */ - L_tmp = L_mult( excTmp2[0], 1638 ); - FOR( i = 1; i < L_SUBFR16k / 4; i++ ) - { - L_tmp = L_mac( L_tmp, excTmp2[i], 1638 ); /*1638 = 1/20 in Q15*/ - } - /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ - - /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ - /* rather stick to the more conservative approach, to avoid potential clippings */ - test(); - IF( !( prev_bfi && EQ_16( extl, FB_TBE ) ) ) - { - /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ - varEnvShape = 26214 /*0.8f Q15*/; - move16(); - csfilt_num2[0] = sub( MAX_16, varEnvShape ); - move16(); - neg_csfilt_den2[1] = varEnvShape; - move16(); - } - - *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); - move32(); - } - - IF( MSFlag > 0 ) - { - // varEnvShape = 0.995f; - varEnvShape = 32604; - move16(); - csfilt_num2[0] = 32768 - varEnvShape; - // csfilt_num2[0] = sub( 32767, varEnvShape ); - move16(); - neg_csfilt_den2[1] = varEnvShape; - move16(); - } - - White_exc16k = exc16k; - Word16 Q_excTmp2 = add( getScaleFactor16( excTmp2, L_FRAME16k ), *Q_bwe_exc ); - IF( *mem_csfilt ) - { - Q_excTmp2 = s_min( Q_excTmp2, sub( add( norm_l( *mem_csfilt ), *Q_bwe_exc ), 1 ) ); - } - test(); - /* Track the low band envelope */ - IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) ) - { - test(); - IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) - { - mem_csfilt_left = 0; - mem_csfilt_right = 0; - move16(); - move16(); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - // excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; - excNoisyEnvLeft[k] = add( mem_csfilt_left, mult_r( csfilt_num2[0], shl( excTmp2[k], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 - move16(); - // mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; - mem_csfilt_left = mult_r( neg_csfilt_den2[1], excNoisyEnvLeft[k] ); // Q_excTmp2 - // excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; - excNoisyEnvRight[L_FRAME16k - k - 1] = add( mem_csfilt_right, mult_r( csfilt_num2[0], shl( excTmp2[L_FRAME16k - k - 1], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 - move16(); - // mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; - mem_csfilt_right = mult_r( neg_csfilt_den2[1], excNoisyEnvRight[L_FRAME16k - k - 1] ); // Q_excTmp2 - } - - alpha = 0; - move16(); - // step = 1.0f / L_FRAME16k; - step = 102; // Q15 - move16(); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - // excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + (1 - alpha) * excNoisyEnvRight[k]; - excNoisyEnv[k] = add( mult_r( alpha, excNoisyEnvLeft[k] ), mult_r( sub( 32767, alpha ), excNoisyEnvRight[k] ) ); // Q_excTmp2 - move16(); - alpha = add( alpha, step ); - } - } - } - ELSE - { - /* Track the low band envelope */ - L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - excNoisyEnv[i] = mac_r( L_tmp, csfilt_num2[0], shl( excTmp2[i], sub( Q_excTmp2, *Q_bwe_exc ) ) ); - move16(); - /* Work-around to avoid 0s for very small value*/ - test(); - test(); - test(); - test(); - if ( excNoisyEnv[i] == 0 && ( L_tmp != 0 || ( csfilt_num2[0] != 0 && excTmp2[i] != 0 ) ) ) - { - excNoisyEnv[i] = 1; - move16(); - } - /* excNoisyEnv : Q_excTmp2, - *mem_csfilt: Q_excTmp2+16, excTmp2: Q_excTmp2, csfilt_num2[0] Q_excTmp2 */ - L_tmp = L_mult( excNoisyEnv[i], neg_csfilt_den2[1] ); /* Q_excTmp2 + 16 */ - } - *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); - move32(); - } - - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - /* generate gaussian (white) excitation */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k[k] = own_random( &bwe_seed[0] ); // Q0 - move16(); - } - - /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; // Q31 - move32(); - move32(); - pow22 = POW_EXC16k_WHTND_FX; - Q_pow22 = -6; - move16(); - // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); - Word16 pow1_exp = sub( Q31, Q_pow1 ); - Word32 temp_pow = Sqrt32( pow1, &pow1_exp ); - temp_pow = L_shl( Mpy_32_32( temp_pow, pow22_inv ), pow1_exp ); - /*Word16 out_exp; - Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); - temp_pow1 = L_shl(temp_pow1, out_exp);*/ - // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); - L_tmp = 0; - move32(); - Q_White_exc16k = add( getScaleFactor16( White_exc16k, L_FRAME16k ), norm_l( temp_pow ) ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); // Q31 + Q0 - Q15 = Q16 - move32(); - White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q16 + Q_White_exc16k - Q16 = Q_White_exc16k - move16(); - L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); - } - } - ELSE - { - /* create a random excitation - Reuse exc16k memory */ - create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 - create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); // Q5 - - L_tmp = L_deposit_l( 0 ); - tmp = add( *Q_bwe_exc, 1 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_excTmp2) +5 +1*/ - White_exc16k_32[k] = L_tmp4; /* (Q_excTmp2) +5 +1*/ - move32(); - L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); - } - /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ - /* White_exc16k in Q6 */ - - /* calculate pow22 */ - /* pow22=0.00001f */ - tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - W_tmp = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ - Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /* White_exc16k[k] *= excNoisyEnv[k]; */ - White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 - move16(); - /* i: excNoisyEnv in (Q_excTmp2) */ - /* i: White_exc16k in Q6 */ - /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ - - /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - W_tmp = W_mac0_16_16( W_tmp, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ - } - Q_pow22 = W_norm( W_tmp ); - pow22 = W_extract_h( W_shl( W_tmp, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 - Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); - Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); - } - - flag_plosive = 0; - move16(); - test(); - test(); - test(); - IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ - { -#ifndef ADD_IVAS_TBE_CODE // BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_tmp[k] = shl( White_exc16k[k], sub( *Q_bwe_exc, Q_White_exc16k ) ); - move16(); - } - - /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ - find_td_envelope_fx( White_exc16k_tmp, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); /* Q_bwe_exc */ - find_td_envelope_fx( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); /* Q_bwe_exc */ - - FOR( k = 0; k < L_FRAME4k; k++ ) - { - EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; /* Q_bwe_exc */ - move16(); - EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; /* Q_bwe_exc */ - move16(); - } - - /* calculate the optimal mix factor */ - c0 = c1 = c2 = c3 = c4 = c5 = 0; /* Q0 */ - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - - temp1 = add( shl( *Q_bwe_exc, 1 ), 1 ); - temp2 = add( add( Q_EnvSHBres_4k, *Q_bwe_exc ), 1 ); - temp3 = add( shl( Q_EnvSHBres_4k, 1 ), 1 ); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - // c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c0_part[i] = L_shr( sum2_fx( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ - move32(); - // c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c1_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ - move32(); - // c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c2_part[i] = L_shr( sum2_fx( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ - move32(); - // c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c3_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ - move32(); - // c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c4_part[i] = L_shr( Dot_product( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), sub( temp1, 1 ) ); /* Q0 */ - move32(); - // c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c5_part[i] = L_shr( sum2_fx( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp3 ); /* Q0 */ - move32(); - - c0 = L_add( c0, c0_part[i] ); - c1 = L_add( c1, c1_part[i] ); - c2 = L_add( c2, c2_part[i] ); - c3 = L_add( c3, c3_part[i] ); - c4 = L_add( c4, c4_part[i] ); - c5 = L_add( c5, c5_part[i] ); - } - - // den = 4.0f * c0 * c2 - c4 * c4; - W_tmp = W_sub( W_shl( W_mult0_32_32( c0, c2 ), 2 ), W_mult0_32_32( c4, c4 ) ); - den_e = 63; - move16(); - shift = W_norm( W_tmp ); - den = W_extract_h( W_shl( W_tmp, shift ) ); - den_e = sub( den_e, shift ); - - IF( den == 0 ) - { - den = 1; - move32(); - den_e = 31; - move16(); - } - - // g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; - W_tmp = W_sub( W_mult0_32_32( c3, c4 ), W_shl( W_mult0_32_32( c1, c2 ), 1 ) ); - g1_e = 63; - move16(); - shift = W_norm( W_tmp ); - L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); - g1_e = sub( g1_e, shift ); - - g1 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); - g1_e = sub( add( tmp_e, g1_e ), den_e ); - - // g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; - W_tmp = W_sub( W_mult0_32_32( c1, c4 ), W_shl( W_mult0_32_32( c0, c3 ), 1 ) ); - g2_e = 63; - move16(); - shift = W_norm( W_tmp ); - L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); - g2_e = sub( g2_e, shift ); - - g2 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); - g2_e = sub( add( tmp_e, g2_e ), den_e ); - - // *Env_error = 0.0f; - *Env_error = 0; - move16(); - flag_plosive = 0; - move16(); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - // Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; - L_tmp = BASOP_Util_Add_Mant32Exp( c5_part[i], 31, Mpy_32_32( L_mult( g1, g1 ), c0_part[i] ), add( shl( g1_e, 1 ), 31 ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c1_part[i], g1 ), add( 31, g1_e ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g2, g2 ), c2_part[i] ), add( shl( g2_e, 1 ), 31 ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c3_part[i], g2 ), add( 31, g2_e ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g1, g2 ), c4_part[i] ), add( add( g1_e, g2_e ), 31 ), &tmp_e ); - - // Env_error_part[i] = L_shr( L_tmp, 31 - tmp_e ); // Check Exponent - Env_error_part[i] = extract_h( L_shr_sat( L_tmp, sub( Q15, tmp_e ) ) ); /* Q0 */ - move16(); - - // *Env_error += Env_error_part[i]; - *Env_error = add_sat( *Env_error, Env_error_part[i] ); /* Q0 */ - move16(); - - if ( GT_16( Env_error_part[i], THR_ENV_ERROR_PLOSIVE_FX ) ) // Check which Q - { - /* envelope error is too high -> likely a plosive */ - flag_plosive = 1; - move16(); - } - } - - IF( flag_plosive ) - { - /* plosive detected -> set the mixing factor to 0 */ - *vf_ind = 0; - move16(); - mix_factor = 0; - move16(); - } - ELSE - { - /* normalize gain */ - // g = g2 / ( g1 + g2 ); - tmp1_e = BASOP_Util_Add_MantExp( g1, g1_e, g2, g2_e, &tmp ); - IF( tmp == 0 ) - { - tmp = 1; - move16(); - tmp1_e = 15; - move16(); - } - g = BASOP_Util_Divide1616_Scale( g2, tmp, &tmp_e ); - g_e = sub( add( tmp_e, g2_e ), tmp1_e ); - - /* quantization of the mixing factor */ - cbsize = 1 << NUM_BITS_SHB_VF; - move16(); - // delta = 1.0f / ( cbsize - 1 ); - delta = 2341; /* Q14 */ - move16(); - // if ( g > 1.0f ) - IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), ONE_IN_Q31, 0 ) > 0 ) - { - // g = 1.0f; - g = MAX16B; /* Q15 */ - move16(); - g_e = 0; - move16(); - } - // else if ( g < shl( delta, ( 15 - g_e ) - 14 ) ) - ELSE IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), delta, 17 ) < 0 ) - { - /* prevent low gains to be quantized to 0 as this is reserved for plosives */ - // g = delta; - g = shl( delta, 1 ); /* Q15 */ - g_e = 0; - move16(); - } - - g = shl_sat( g, g_e ); /* Q15 */ - - *vf_ind = usquant_fx( g, &mix_factor, 0, delta, cbsize ); - move16(); - } - } - ELSE -#else - UNUSED_PARAM( Env_error_part ); - UNUSED_PARAM( Env_error ); - UNUSED_PARAM( EnvSHBres_4k ); - UNUSED_PARAM( c5_part ); - UNUSED_PARAM( c1 ); - UNUSED_PARAM( den ); - UNUSED_PARAM( c3_part ); - UNUSED_PARAM( c0 ); - UNUSED_PARAM( delta ); - UNUSED_PARAM( c3 ); - UNUSED_PARAM( c2_part ); - UNUSED_PARAM( c1_part ); - UNUSED_PARAM( EnvWhiteExc16k ); - UNUSED_PARAM( g2 ); - UNUSED_PARAM( c5 ); - UNUSED_PARAM( c4_part ); - UNUSED_PARAM( EnvWhiteExc16k_4k ); - UNUSED_PARAM( c2 ); - UNUSED_PARAM( g ); - UNUSED_PARAM( cbsize ); - UNUSED_PARAM( g1 ); - UNUSED_PARAM( EnvExc16kWhtnd ); - UNUSED_PARAM( c0_part ); - UNUSED_PARAM( EnvExc16kWhtnd_4k ); - UNUSED_PARAM( c4 ); -#endif - { - Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, - Q_White_exc16k, pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); - tmp = voiceFacEst[0]; - tmp2 = MAX_16; - move16(); - move16(); - if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } - ELSE /* decoder side */ - { - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - IF( *vf_ind == 0 ) - { - // mix_factor = 0.0f; - mix_factor = 0; - move16(); - flag_plosive = 1; - move16(); - } - ELSE - { - // mix_factor = usdequant(*vf_ind, 0.0f, 1.0f / ((1 << NUM_BITS_SHB_VF) - 1)); - mix_factor = usdequant_fx( *vf_ind, 0, 2341 ); - } - } - ELSE - { - /* *vf_ind is an integer scale by 0.125f*/ - tmp = shl( *vf_ind, ( 15 - 3 ) ); - tmp2 = MAX_16; - move16(); - IF( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } - - test(); - IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) - { - voice_factors[0] = mult_r( voice_factors[0], tmp2 ); - move16(); - voice_factors[1] = mult_r( voice_factors[1], tmp2 ); - move16(); - voice_factors[2] = mult_r( voice_factors[2], tmp2 ); - move16(); - voice_factors[3] = mult_r( voice_factors[3], tmp2 ); - move16(); - voice_factors[4] = mult_r( voice_factors[4], tmp2 ); - move16(); - } - } - - test(); - IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) - { - /* save buffers for IC-BWE */ - // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); - Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); // Q_bwe_exc - *nlExc16k_e = sub( 15, *Q_bwe_exc ); - move16(); - - // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - Word16 temp_fac = round_fx_sat( L_tmp ); // Q15-exp - - FOR( k = 0; k < L_FRAME16k; k++ ) - { - mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); // Q_White_exc16k+15-exp-15 = Q_White_exc16k-exp - move16(); - } - *mixExc16k_e = sub( 15, sub( Q_White_exc16k, exp ) ); - move16(); - } - - Copy( White_exc16k, White_exc16k_FB, L_FRAME16k ); // Q_White_exc16k - prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; - *Q_bwe_exc_fb = Q_White_exc16k; - move16(); - move16(); - - Word16 tbe_demph_fx = shl_sat( *tbe_demph, sub( Q_White_exc16k, *Q_bwe_exc ) ); // Q_White_exc16k - - deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, &tbe_demph_fx ); - /* i/o: White_exc16k (Q_White_exc16k) */ - /* i: tbe_demph_fx (Q_White_exc16k) */ - *tbe_demph = shr_sat( tbe_demph_fx, sub( Q_White_exc16k, *Q_bwe_exc ) ); - move16(); - - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - IF( !flag_plosive ) /* use only LB excitation in case of plosives */ - { - /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ - /* old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); */ - old_scale = round_fx_sat( root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ) ); // exp - old_scale = shl( old_scale, s_min( 0, exp ) ); // limit Q factor to 15 - exp = s_max( 0, exp ); - - // new_scale = 1.0f; - new_scale = shr( 32767, exp ); // exp - - // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); - step_scale = mult_r( sub( new_scale, old_scale ), 205 ); // exp - scale = old_scale; // exp - move16(); - - /* interpolate between the old and the new value of the mixing factor */ - old_fact = *prev_mix_factor; // Q15 - new_fact = mix_factor; // Q15 - move16(); - move16(); - - // step = (new_fact - old_fact) / (L_FRAME16k / 2); - step = mult_r( sub( new_fact, old_fact ), 205 ); // Q15 - fact = old_fact; // Q15 - move16(); - - shift = add( exp, sub( *Q_bwe_exc, Q_White_exc16k ) ); - - /* mixing of LB and gaussian excitation in the first half of the frame */ - FOR( k = 0; k < L_FRAME16k / 2; k++ ) - { - /* exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; */ - L_tmp = L_shl_sat( L_mult( fact, mult_r( White_exc16k[k], scale ) ), shift ); // Q_bwe_exc+16 - exc16kWhtnd[k] = mac_r_sat( L_tmp, sub( 32767, fact ), exc16kWhtnd[k] ); // Q_bwe_exc - move16(); - - fact = add_sat( fact, step ); // Q15 - scale = add_sat( scale, step_scale ); // exp - } - - shift = sub( *Q_bwe_exc, Q_White_exc16k ); - /* mixing of LB and gaussian excitation in the second half of the frame */ - FOR( ; k < L_FRAME16k; k++ ) - { - // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; - L_tmp = L_shl_sat( L_mult( new_fact, White_exc16k[k] ), shift ); // Q_bwe_exc+16 - exc16kWhtnd[k] = mac_r( L_tmp, sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_bwe_exc - move16(); - } - } - // preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc - } - ELSE - { - test(); - IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) - { - scale = 0; - move16(); - - test(); - IF( pow1 != 0 && pow22 != 0 ) - { - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ - } - - FOR( k = 0; k < L_FRAME16k; k++ ) - { - exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); // Q_White_exc16k - move16(); - } - - Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); // Q_bwe_exc - - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc - /* i/o: exc16kWhtnd (Q_bwe_exc) */ - /* i/o: tbe_premph (Q_bwe_exc) */ - } - ELSE - { - Word16 nbSubFr, lSubFr; - Word16 tempQ15; - Word32 tempQ31; - nbSubFr = NB_SUBFR16k; - lSubFr = ( L_FRAME16k / NB_SUBFR16k ); - move16(); - move16(); - IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) - { - nbSubFr = NB_SUBFR; - move16(); - lSubFr = ( L_FRAME16k / NB_SUBFR ); - move16(); - } - k = 0; - move16(); - FOR( i = 0; i < nbSubFr; i++ ) - { - test(); - IF( EQ_16( coder_type, VOICED ) && ( LT_32( extl_brate, SWB_TBE_2k8 ) ) ) - { - exp = 0; - move16(); - tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ - temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - exp = 0; - move16(); - tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ - temp = sub( MAX_16, temp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - ELSE - { - /* Adjust noise mixing for formant sharpening filter */ - tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); - /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ - vf_tmp = sub( MAX_16, tempQ15 ); - vf_tmp = mult( voice_factors[i], vf_tmp ); - - exp = 0; - move16(); - tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ - temp = sub( MAX_16, vf_tmp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - - shift = sub( *Q_bwe_exc, Q_White_exc16k ); - FOR( j = 0; j < lSubFr; j++ ) - { - /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_shl_sat( L_mult( temp2, White_exc16k[k + j] ), shift ); // 16+(Q_bwe_exc) - exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); // Q_bwe_exc - move16(); - } - k = add( k, lSubFr ); - - /* estimate the pre-emph factor */ - tempQ15 = sub( MAX_16, voice_factors[i] ); - exp = 0; - move16(); - temp = Sqrt16( tempQ15, &exp ); - temp = shl( temp, sub( exp, 1 ) ); - - temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ - temp = div_s( temp, temp2 ); /* Q15 */ - temp = mult_r( PREEMPH_FAC, temp ); - - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); // Q_bwe_exc - /* exc16kWhtnd: Q_bwe_exc; - tbe_premph: Q_bwe_exc*/ - } - } - } - - IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) - { - syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: excSHB in Q_bwe_exc */ - } - ELSE - { - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - - syn_filt_fx( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[0] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - syn_filt_fx( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[1] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - syn_filt_fx( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[2] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - syn_filt_fx( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[3] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - tmp2 = s_min( s_min( syn_shb_ener_sf_q[0], syn_shb_ener_sf_q[1] ), s_min( syn_shb_ener_sf_q[3], syn_shb_ener_sf_q[2] ) ); - syn_shb_ener_sf[0] = L_shl( syn_shb_ener_sf[0], sub( tmp2, syn_shb_ener_sf_q[0] ) ); - move32(); - syn_shb_ener_sf[1] = L_shl( syn_shb_ener_sf[1], sub( tmp2, syn_shb_ener_sf_q[1] ) ); - move32(); - syn_shb_ener_sf[2] = L_shl( syn_shb_ener_sf[2], sub( tmp2, syn_shb_ener_sf_q[2] ) ); - move32(); - syn_shb_ener_sf[3] = L_shl( syn_shb_ener_sf[3], sub( tmp2, syn_shb_ener_sf_q[3] ) ); - move32(); - - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: tempSHB in Q_bwe_exc */ - /* o: syn_shb_ener_sf in tmp2 */ - IF( LE_32( bitrate, MAX_ACELP_BRATE ) ) - { - L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); - - /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ - tmp = shl( Q_shb, 1 ); - L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ - - *Q_bwe_exc = sub( *Q_bwe_exc, exp ); - move16(); /* compensate for the exp shift */ - tmp2 = add( prev_Q_bwe_syn, n_mem2 ); - IF( GT_16( *Q_bwe_exc, tmp2 ) ) - { - L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); - *Q_bwe_exc = tmp2; - move16(); - } - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ - exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ - move16(); - } - } - /* i: L_tmp2 in (Q31-exp) */ - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ - - /* Rescale the past memories: LP synth and SHB look ahead buffers */ - tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - state_lpc_syn[i] = shl_sat( state_lpc_syn[i], tmp ); - move16(); - } - FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) - { - excSHB[i] = shl_sat( excSHB[i], tmp ); - move16(); - } - /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ - - syn_filt_fx( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); - syn_filt_fx( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); - syn_filt_fx( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); - syn_filt_fx( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in (Q_bwe_exc) */ - /* o: excSHB in (Q_bwe_exc) */ - } - - IF( EQ_16( extl, FB_TBE ) ) - { - tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); - Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); - Scale_sig( fb_tbe_demph, 1, tmp ); - syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); - /* i: White_exc16k_FB in (Q_bwe_exc_fb) */ - /* o: White_exc16k_FB_temp in (Q_bwe_exc_fb) */ - - FOR( i = 0; i < 10; i++ ) - { - FOR( j = 0; j < 32; ++j ) - { - White_exc16k_FB_temp[i * 32 + j] = mult_r_sat( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); - move16(); - } - } - - *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); - move16(); /**Q_bwe_exc_fb +35 +1 -16*/ - flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); - - deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); - } - ELSE - { - set16_fx( White_exc16k_FB, 0, L_FRAME16k ); - } - - *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 - *prev_mix_factor = mix_factor; - move32(); - move16(); - - return; -} - -void GenShapedSHBExcitation_ivas_dec_fx( - Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ - const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ - Word32 *mem_csfilt, /* i/o: memory */ - Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ - Word16 *state_lpc_syn, /* i/o: memory */ - const Word16 coder_type, /* i : coding type */ - const Word16 *bwe_exc_extended, /* i : bwidth extended excitation */ - Word16 bwe_seed[], /* i/o: random number generator seed */ - Word16 voice_factors[], /* i : voicing factor*/ - const Word16 extl, /* i : extension layer */ - Word16 *tbe_demph, /* i/o: de-emphasis memory */ - Word16 *tbe_premph, /* i/o: pre-emphasis memory */ - Word16 *lpc_shb_sf, /* i: LP coefficients */ - const Word32 shb_ener_sf_32, /* i: input shb ener, Q31 */ - Word16 *shb_res_gshape, /* i: input res gain shape, Q14 */ - Word16 *shb_res, - Word16 *vf_ind, - const Word16 formant_fac, /* i : Formant sharpening factor [0..1] */ - Word16 fb_state_lpc_syn[], /* i/o: memory */ - Word16 *fb_tbe_demph, /* i/o: fb de-emphasis memory */ - Word16 *Q_bwe_exc, - Word16 *Q_bwe_exc_fb, - const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ - const Word32 bitrate, /* i : bitrate */ - const Word16 prev_bfi, /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling Q0 */ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling Q0 */ -) -{ - Word16 i, j, k; - Word16 wht_fil_mem[LPC_WHTN_ORDER]; - Word16 lpc_whtn[LPC_WHTN_ORDER + 1]; - Word16 R_h[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech MSB */ - Word16 R_l[LPC_WHTN_ORDER + 2]; /* Autocorrelations of windowed speech LSB */ - Word16 Q_R; - Word32 LepsP[LPC_WHTN_ORDER + 1]; - Word16 exc32k[L_FRAME32k], exc16k[L_FRAME16k]; - Word32 pow1, pow22; - Word16 scale, temp1, temp2, temp3; - Word16 Q_White_exc16k; - Word16 excTmp2[L_FRAME16k]; - Word16 *White_exc16k; - Word16 excNoisyEnv[L_FRAME16k]; - Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ - move16(); - Word16 neg_csfilt_den2[2] = { -32767, 26214 }; /* {1.0f, -0.8f} */ - move16(); - move16(); - Word16 varEnvShape; - Word16 fb_deemph_fac = 15729; /*0.48f in Q15 */ - Word16 exc16kWhtnd[L_FRAME16k]; - - Word32 L_tmp; - Word16 vf_tmp; - Word16 tmp, exp, tmp2 = 0; - move16(); - Word16 voiceFacEst[NB_SUBFR16k]; - Word16 zero_mem[LPC_SHB_ORDER]; - Word32 syn_shb_ener_sf[4]; - Word16 syn_shb_ener_sf_q[4]; - Word16 tempSHB[80]; - Word16 Q_pow1, Q_pow22; - - Word32 L_tmp2, L_tmp3, L_tmp4; - Word16 temp; - - Word16 White_exc16k_FB_temp[L_FRAME16k]; - Word32 White_exc16k_32[L_FRAME16k]; - Word16 White_exc16k_tmp[L_FRAME16k]; - Word16 Q_temp; - Word16 prev_Q_bwe_exc_fb, Q_exc16kWhtnd; - Word16 chk1; - Word32 chk2; - chk1 = 0; - chk2 = 0; - move16(); - move32(); - -#if 1 // def ADD_IVAS_TBE_CODE - Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; - Word16 cbsize; - Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; - Word32 c0, c1, c2, c3, c4, c5, den; - Word16 g1, g2, g, g1_e, g2_e, g_e, den_e, shift, tmp_e, tmp1_e; - Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; - Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; - Word16 flag_plosive; - Word16 delta; - Word32 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; - Word64 W_tmp; - - mix_factor = 0; /* Q15 */ - move16(); -#endif - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); - FOR( i = 0; i < L_FRAME32k; i = i + 2 ) - { - exc32k[i] = negate( bwe_exc_extended[i] ); // Q_bwe_exc - move16(); - exc32k[i + 1] = bwe_exc_extended[i + 1]; // Q_bwe_exc - move16(); - } - - /* Decimate by 2 */ - Decimate_allpass_steep_fx( exc32k, mem_genSHBexc_filt_down_shb, 2 * L_FRAME16k, exc16k ); // Q_bwe_exc - /* i: exc32k in Q_bwe_exc */ - /* o: exc16k in Q_bwe_exc */ - - autocorr_fx( exc16k, LPC_WHTN_ORDER + 1, R_h, R_l, &Q_R, L_FRAME16k, win_flatten_fx, 0, 1 ); // Q_R - /* Ensure R[0] isn't zero when entering Levinson Durbin */ - R_l[0] = s_max( R_l[0], 1 ); - move16(); - FOR( i = 1; i <= LPC_WHTN_ORDER; i++ ) - { - L_tmp = Mpy_32( R_h[i], R_l[i], wac_h[i - 1], wac_l[i - 1] ); - L_Extract( L_tmp, &R_h[i], &R_l[i] ); // Q_R - } - E_LPC_lev_dur( R_h, R_l, lpc_whtn, LepsP, LPC_WHTN_ORDER, NULL ); - Copy_Scale_sig( lpc_whtn, lpc_whtn, LPC_WHTN_ORDER + 1, sub( norm_s( lpc_whtn[0] ), 2 ) ); // Q12 - fir_fx( exc16k, lpc_whtn, exc16kWhtnd, wht_fil_mem, L_FRAME16k, LPC_WHTN_ORDER, 0, 3 ); // Q_bwe_exc - - /* i: exc16k in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc */ - -#if 1 // def ADD_IVAS_TBE_CODE - IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif - { - temp2 = 0; - move16(); - FOR( j = 0; j < 4; j++ ) - { - temp1 = shb_res_gshape[j]; - move16(); - FOR( i = 0; i < 80; i++ ) - { - exc16kWhtnd[temp2 + i] = round_fx( L_shl( L_mult( exc16kWhtnd[temp2 + i], temp1 ), 1 ) ); // Q_bwe_exc - move16(); - /* exc16kWhtnd in Q_bwe_exc, shb_res_gshape in Q14 */ - } - temp2 = add( temp2, 80 ); - } - } - - /* Estimate pow1 associated with Low band nonlinear extended excitation */ - /* pow1=0.00001f */ - tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); - pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ - excTmp2[k] = abs_s( exc16kWhtnd[k] ); - move16(); - chk1 = s_or( chk1, exc16kWhtnd[k] ); - - /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ - pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ - } - Q_pow1 = shl( *Q_bwe_exc, 1 ); - - test(); -#if 1 // ADD_IVAS_TBE_CODE - IF( flag_ACELP16k == 0 ) -#else - IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) -#endif - { - /* varEnvShape = mean_fx(voice_factors, 4); */ - /* unroll the loop */ - L_tmp = L_mult( voice_factors[0], 8192 /*0.25 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[1], 8192 /*0.25 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[2], 8192 /*0.25 in Q15 */ ); - varEnvShape = mac_r( L_tmp, voice_factors[3], 8192 /*0.25 in Q15 */ ); /* varEnvShape in Q15 */ - } - ELSE /* 16k core */ - { - /* varEnvShape = mean_fx(voice_factors, 5); */ - /* unroll the loop */ - L_tmp = L_mult( voice_factors[0], 6554 /*0.2 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[1], 6554 /*0.2 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[2], 6554 /*0.2 in Q15 */ ); - L_tmp = L_mac( L_tmp, voice_factors[3], 6554 /*0.2 in Q15 */ ); - varEnvShape = mac_r( L_tmp, voice_factors[4], 6554 /*0.2 in Q15 */ ); /* varEnvShape in Q15 */ - } - - IF( EQ_16( extl, FB_TBE ) ) - { - /*pow(varEnvShape,3) */ - tmp = mult_r( varEnvShape, varEnvShape ); - tmp = mult_r( tmp, varEnvShape ); - - /* max_val((0.68f - (float)pow(varEnvShape, 3)), 0.48f); */ - fb_deemph_fac = sub( 22282 /*0.68f Q15*/, tmp ); - fb_deemph_fac = s_max( fb_deemph_fac, 15729 /*0.48f Q15*/ ); - } - - /*varEnvShape = 1.09875f - 0.49875f * varEnvShape; */ - varEnvShape = msu_r( 1179773824l /*0.549375f Q31*/, 8172 /*0.249375f Q15*/, varEnvShape ); - - /*varEnvShape = min( max_val(varEnvShape, 0.6f), 0.999f); */ - varEnvShape = s_max( varEnvShape, 9830 /*0.3f Q15*/ ); - varEnvShape = s_min( varEnvShape, 16368 /*0.4995f Q15*/ ); - varEnvShape = shl( varEnvShape, 1 ); - csfilt_num2[0] = sub( MAX_16, varEnvShape ); // Q15 - move16(); - neg_csfilt_den2[1] = varEnvShape; // Q15 - move16(); - - test(); - test(); - test(); -#if 1 // def ADD_IVAS_TBE_CODE - test(); - IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#else - IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#endif - { - /* pre-init smoothing filter to avoid energy drop outs */ - L_tmp = L_mult( excTmp2[0], 1638 ); - FOR( i = 1; i < L_SUBFR16k / 4; i++ ) - { - L_tmp = L_mac( L_tmp, excTmp2[i], 1638 ); /*1638 = 1/20 in Q15*/ - } - /*L_tmp = sum(excTmp2, L_SUBFR16k/4)*(1/20) where L_SUBFR16k/4 =20 */ - - /* don't apply for FB in case the FB start-frame was potentially lost - White_exc16k is very sensitive to enery mismatch between enc - dec */ - /* rather stick to the more conservative approach, to avoid potential clippings */ - test(); - IF( !( prev_bfi && EQ_16( extl, FB_TBE ) ) ) - { - /* use weak smoothing for 1st frame after switching to make filter recover more quickly */ - varEnvShape = 26214 /*0.8f Q15*/; - move16(); - csfilt_num2[0] = sub( MAX_16, varEnvShape ); - move16(); - neg_csfilt_den2[1] = varEnvShape; - move16(); - } - - *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); - move32(); - } -#if 1 // def ADD_IVAS_TBE_CODE - IF( MSFlag > 0 ) - { - // varEnvShape = 0.995f; - varEnvShape = 32604; - move16(); - csfilt_num2[0] = 32768 - varEnvShape; - // csfilt_num2[0] = sub( 32767, varEnvShape ); - move16(); - neg_csfilt_den2[1] = varEnvShape; - move16(); - } - - White_exc16k = exc16k; - move16(); - Word16 Q_excTmp2 = add( getScaleFactor16( excTmp2, L_FRAME16k ), *Q_bwe_exc ); - IF( *mem_csfilt ) - { - Q_excTmp2 = s_min( Q_excTmp2, sub( add( norm_l( *mem_csfilt ), *Q_bwe_exc ), 1 ) ); - } - test(); - /* Track the low band envelope */ - IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) ) - { - test(); - IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) - { - mem_csfilt_left = 0; - mem_csfilt_right = 0; - move16(); - move16(); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - // excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; - excNoisyEnvLeft[k] = add( mem_csfilt_left, mult_r( csfilt_num2[0], shl( excTmp2[k], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 - move16(); - // mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; - mem_csfilt_left = mult_r( neg_csfilt_den2[1], excNoisyEnvLeft[k] ); // Q_excTmp2 - // excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; - excNoisyEnvRight[L_FRAME16k - k - 1] = add( mem_csfilt_right, mult_r( csfilt_num2[0], shl( excTmp2[L_FRAME16k - k - 1], sub( Q_excTmp2, *Q_bwe_exc ) ) ) ); // Q_excTmp2 - move16(); - // mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; - mem_csfilt_right = mult_r( neg_csfilt_den2[1], excNoisyEnvRight[L_FRAME16k - k - 1] ); // Q_excTmp2 - } - - alpha = 0; - move16(); - // step = 1.0f / L_FRAME16k; - step = 102; // Q15 - move16(); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - // excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + (1 - alpha) * excNoisyEnvRight[k]; - excNoisyEnv[k] = add( mult_r( alpha, excNoisyEnvLeft[k] ), mult_r( sub( 32767, alpha ), excNoisyEnvRight[k] ) ); // Q_excTmp2 - move16(); - alpha = add( alpha, step ); - } - } - } - ELSE -#endif - { - /* Track the low band envelope */ - L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - excNoisyEnv[i] = mac_r( L_tmp, csfilt_num2[0], shl( excTmp2[i], sub( Q_excTmp2, *Q_bwe_exc ) ) ); - move16(); - /* Work-around to avoid 0s for very small value*/ - test(); - test(); - test(); - test(); - if ( excNoisyEnv[i] == 0 && ( L_tmp != 0 || ( csfilt_num2[0] != 0 && excTmp2[i] != 0 ) ) ) - { - excNoisyEnv[i] = 1; - move16(); - } - /* excNoisyEnv : Q_excTmp2, - *mem_csfilt: Q_excTmp2+16, excTmp2: Q_excTmp2, csfilt_num2[0] Q_excTmp2 */ - L_tmp = L_mult( excNoisyEnv[i], neg_csfilt_den2[1] ); /* Q_excTmp2 + 16 */ - } - *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); - move32(); - } -#if 1 // def ADD_IVAS_TBE_CODE - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - /* generate gaussian (white) excitation */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k[k] = own_random( &bwe_seed[0] ); - move16(); - } - - /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT_IN_Q49; - move32(); - move32(); - pow22 = POW_EXC16k_WHTND_FX; - Q_pow22 = -6; - move16(); - // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), White_exc16k, L_FRAME16k); - Word16 pow1_exp = sub( Q31, Q_pow1 ); - Word32 temp_pow = Sqrt32( pow1, &pow1_exp ); - temp_pow = Mpy_32_32( temp_pow, pow22_inv ); - /*Word16 out_exp; - Word32 temp_pow1 = root_a_over_b_fx(pow1, Q_pow1, pow22, Q_pow22, &out_exp); - temp_pow1 = L_shl(temp_pow1, out_exp);*/ - // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); - L_tmp = 0; - move32(); - shift = getScaleFactor16( White_exc16k, L_FRAME16k ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); - move32(); - White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], shift ) ); // Q_White_exc16k - move16(); - L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); - } - Q_White_exc16k = add( shift, sub( 49 - 31, pow1_exp ) ); - Q_temp = norm_l( L_tmp ); - IF( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } - } - ELSE -#endif - { - /* create a random excitation - Reuse exc16k memory */ - White_exc16k = exc16k; - move16(); - create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 - create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); // Q5 - - L_tmp = L_deposit_l( 0 ); - tmp = add( *Q_bwe_exc, 1 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_excTmp2) +5 +1*/ - White_exc16k_32[k] = L_tmp4; /* (Q_excTmp2) +5 +1*/ - move32(); - L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); - } - Q_temp = norm_l( L_tmp ); - IF( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } - /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ - /* White_exc16k in Q6 */ - - /* calculate pow22 */ - /* pow22=0.00001f */ - tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - Word64 sum = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ - Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - - White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 - chk2 = L_or( chk2, White_exc16k_32[k] ); - /* i: excNoisyEnv in (Q_excTmp2) */ - /* i: White_exc16k in Q6 */ - /* o: White_exc16k in (Q_White_exc16k) */ - /* pow22 += White_exc16k[k] * White_exc16k[k]; */ - sum = W_mac0_16_16( sum, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ - move16(); - } - Q_pow22 = W_norm( sum ); - pow22 = W_extract_h( W_shl( sum, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 - Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); - Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); - } - -#if 1 // def ADD_IVAS_TBE_CODE - flag_plosive = 0; - move16(); - test(); - test(); - test(); - IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif - { - IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ - { -#ifndef ADD_IVAS_TBE_CODE // BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_tmp[k] = round_fx( L_shl( White_exc16k_32[k], *Q_bwe_exc ) ); - move16(); - } - - /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ - find_td_envelope_fx( White_exc16k_tmp, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); /* Q_bwe_exc */ - find_td_envelope_fx( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); /* Q_bwe_exc */ - - FOR( k = 0; k < L_FRAME4k; k++ ) - { - EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; /* Q_bwe_exc */ - move16(); - EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; /* Q_bwe_exc */ - move16(); - } - - /* calculate the optimal mix factor */ - c0 = c1 = c2 = c3 = c4 = c5 = 0; /* Q0 */ - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - - temp1 = add( shl( *Q_bwe_exc, 1 ), 1 ); - temp2 = add( add( Q_shb, *Q_bwe_exc ), 1 ); - temp3 = add( shl( Q_shb, 1 ), 1 ); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - // c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c0_part[i] = L_shr( sum2_fx( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ - move32(); - // c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c1_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ - move32(); - // c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c2_part[i] = L_shr( sum2_fx( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp1 ); /* Q0 */ - move32(); - // c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c3_part[i] = L_shr( L_negate( Dot_product( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ) ), sub( temp2, 1 ) ); /* Q0 */ - move32(); - // c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c4_part[i] = L_shr( Dot_product( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), sub( temp1, 1 ) ); /* Q0 */ - move32(); - // c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c5_part[i] = L_shr( sum2_fx( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ), temp3 ); /* Q0 */ - move32(); - - c0 = L_add( c0, c0_part[i] ); - c1 = L_add( c1, c1_part[i] ); - c2 = L_add( c2, c2_part[i] ); - c3 = L_add( c3, c3_part[i] ); - c4 = L_add( c4, c4_part[i] ); - c5 = L_add( c5, c5_part[i] ); - } - - // den = 4.0f * c0 * c2 - c4 * c4; - W_tmp = W_sub( W_shl( W_mult0_32_32( c0, c2 ), 2 ), W_mult0_32_32( c4, c4 ) ); - den_e = 63; - move16(); - shift = W_norm( W_tmp ); - den = W_extract_h( W_shl( W_tmp, shift ) ); - den_e = sub( den_e, shift ); - - IF( den == 0 ) - { - den = 1; - move32(); - den_e = 31; - move16(); - } - - // g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; - W_tmp = W_sub( W_mult0_32_32( c3, c4 ), W_shl( W_mult0_32_32( c1, c2 ), 1 ) ); - g1_e = 63; - move16(); - shift = W_norm( W_tmp ); - L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); - g1_e = sub( g1_e, shift ); - - g1 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); - g1_e = sub( add( tmp_e, g1_e ), den_e ); - - // g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; - W_tmp = W_sub( W_mult0_32_32( c1, c4 ), W_shl( W_mult0_32_32( c0, c3 ), 1 ) ); - g2_e = 63; - move16(); - shift = W_norm( W_tmp ); - L_tmp = W_extract_h( W_shl( W_tmp, shift ) ); - g2_e = sub( g2_e, shift ); - - g2 = BASOP_Util_Divide3232_Scale( L_tmp, den, &tmp_e ); - g2_e = sub( add( tmp_e, g2_e ), den_e ); - - // *Env_error = 0.0f; - *Env_error = 0; - move16(); - flag_plosive = 0; - move16(); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - // Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; - L_tmp = BASOP_Util_Add_Mant32Exp( c5_part[i], 31, Mpy_32_32( L_mult( g1, g1 ), c0_part[i] ), add( shl( g1_e, 1 ), 31 ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c1_part[i], g1 ), add( 31, g1_e ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g2, g2 ), c2_part[i] ), add( shl( g2_e, 1 ), 31 ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_16_1( c3_part[i], g2 ), add( 31, g2_e ), &tmp_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, tmp_e, Mpy_32_32( L_mult( g1, g2 ), c4_part[i] ), add( add( g1_e, g2_e ), 31 ), &tmp_e ); - - // Env_error_part[i] = L_shr( L_tmp, 31 - tmp_e ); // Check Exponent - Env_error_part[i] = extract_h( L_shr_sat( L_tmp, sub( Q15, tmp_e ) ) ); /* Q0 */ - move16(); - - // *Env_error += Env_error_part[i]; - *Env_error = add_sat( *Env_error, Env_error_part[i] ); /* Q0 */ - move16(); - - if ( GT_16( Env_error_part[i], THR_ENV_ERROR_PLOSIVE_FX ) ) // Check which Q - { - /* envelope error is too high -> likely a plosive */ - flag_plosive = 1; - move16(); - } - } - - IF( flag_plosive ) - { - /* plosive detected -> set the mixing factor to 0 */ - *vf_ind = 0; - move16(); - mix_factor = 0; - move16(); - } - ELSE - { - /* normalize gain */ - // g = g2 / ( g1 + g2 ); - tmp1_e = BASOP_Util_Add_MantExp( g1, g1_e, g2, g2_e, &tmp ); - IF( tmp == 0 ) - { - tmp = 1; - move16(); - tmp1_e = 15; - move16(); - } - g = BASOP_Util_Divide1616_Scale( g2, tmp, &tmp_e ); - g_e = sub( add( tmp_e, g2_e ), tmp1_e ); - - /* quantization of the mixing factor */ - cbsize = 1 << NUM_BITS_SHB_VF; - move16(); - // delta = 1.0f / ( cbsize - 1 ); - delta = 2341; /* Q14 */ - move16(); - // if ( g > 1.0f ) - IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), ONE_IN_Q31, 0 ) > 0 ) - { - // g = 1.0f; - g = MAX16B; /* Q15 */ - } - // else if ( g < shl( delta, ( 15 - g_e ) - 14 ) ) - ELSE IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), delta, 17 ) < 0 ) - { - /* prevent low gains to be quantized to 0 as this is reserved for plosives */ - // g = delta; - g = shl( delta, 1 ); /* Q15 */ - } - - *vf_ind = usquant_fx( g, &mix_factor, 0, delta, cbsize ); - move16(); - } - } - ELSE -#else - UNUSED_PARAM( Env_error_part ); - UNUSED_PARAM( Env_error ); - UNUSED_PARAM( EnvSHBres_4k ); - UNUSED_PARAM( c5_part ); - UNUSED_PARAM( c1 ); - UNUSED_PARAM( den ); - UNUSED_PARAM( c3_part ); - UNUSED_PARAM( c0 ); - UNUSED_PARAM( delta ); - UNUSED_PARAM( c3 ); - UNUSED_PARAM( c2_part ); - UNUSED_PARAM( c1_part ); - UNUSED_PARAM( EnvWhiteExc16k ); - UNUSED_PARAM( g2 ); - UNUSED_PARAM( c5 ); - UNUSED_PARAM( c4_part ); - UNUSED_PARAM( EnvWhiteExc16k_4k ); - UNUSED_PARAM( c2 ); - UNUSED_PARAM( g ); - UNUSED_PARAM( cbsize ); - UNUSED_PARAM( g1 ); - UNUSED_PARAM( EnvExc16kWhtnd ); - UNUSED_PARAM( c0_part ); - UNUSED_PARAM( EnvExc16kWhtnd_4k ); - UNUSED_PARAM( c4 ); -#endif - { - Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, - ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); - tmp = voiceFacEst[0]; - tmp2 = MAX_16; - move16(); - move16(); - if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } - ELSE /* decoder side */ - { - test(); -#if 1 // def ADD_IVAS_TBE_CODE - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - IF( *vf_ind == 0 ) - { - // mix_factor = 0.0f; - mix_factor = 0; - move16(); - flag_plosive = 1; - move16(); - } - ELSE - { - // mix_factor = usdequant(*vf_ind, 0.0f, 1.0f / ((1 << NUM_BITS_SHB_VF) - 1)); - mix_factor = usdequant_fx( *vf_ind, 0, 2341 ); - } - } - ELSE -#endif - { - /* *vf_ind is an integer scale by 0.125f*/ - tmp = shl( *vf_ind, ( 15 - 3 ) ); - tmp2 = MAX_16; - move16(); - IF( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } -#if 1 // def ADD_IVAS_TBE_CODE - test(); - IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) -#endif - { - voice_factors[0] = mult_r( voice_factors[0], tmp2 ); - move16(); - voice_factors[1] = mult_r( voice_factors[1], tmp2 ); - move16(); - voice_factors[2] = mult_r( voice_factors[2], tmp2 ); - move16(); - voice_factors[3] = mult_r( voice_factors[3], tmp2 ); - move16(); - voice_factors[4] = mult_r( voice_factors[4], tmp2 ); - move16(); - } - } - test(); - IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) - { - /* save buffers for IC-BWE */ - // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); - Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); - // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); - /*Word16 temp_fac = divide3232(L_shr(pow1, Q_pow1), pow22); - Word16 temp_fac_exp = 0; - temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - Word16 temp_fac = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 - shift = sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ); - // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - mixExc16k[k] = mult_r( shl_sat( White_exc16k[k], shift ), temp_fac ); - move16(); - } - } - - tmp = sub( Q_temp, 3 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_FB[k] = White_exc16k[k]; /* Q_White_exc16k */ - } - prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; - move16(); - *Q_bwe_exc_fb = Q_White_exc16k; - move16(); - *tbe_demph = shl_sat( *tbe_demph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); - deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - *tbe_demph = shl_sat( *tbe_demph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); - - Q_exc16kWhtnd = getScaleFactor16( exc16kWhtnd, L_FRAME16k ); - Q_exc16kWhtnd = add( Q_exc16kWhtnd, *Q_bwe_exc ); - - shift = getScaleFactor16( White_exc16k, L_FRAME16k ); - - shift = s_min( Q_exc16kWhtnd, add( shift, Q_White_exc16k ) ); - scale_sig( exc16kWhtnd, L_FRAME16k, sub( shift, *Q_bwe_exc ) ); - scale_sig( White_exc16k, L_FRAME16k, sub( shift, Q_White_exc16k ) ); - - Q_exc16kWhtnd = Q_White_exc16k = shift; - move16(); - move16(); - *tbe_premph = shl_sat( *tbe_premph, sub( Q_White_exc16k, sub( *Q_bwe_exc, NOISE_QADJ ) ) ); - move16(); - test(); - IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) - { - IF( !flag_plosive ) /* use only LB excitation in case of plosives */ - { - /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ - // old_scale = (float)sqrt(*prev_pow_exc16kWhtnd / pow1); - // old_scale = divide3232(*prev_pow_exc16kWhtnd, pow1); // exp = Q15 - (Q_pow1) - // Word16 old_scale_exp = Q15 - (Q_pow1); - // old_scale = Sqrt16(old_scale, &old_scale_exp); - // old_scale = shl(old_scale, old_scale_exp); //Q15 - L_tmp = root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ); - old_scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 - // new_scale = 1.0f; - new_scale = 32767; - move16(); - // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); - step_scale = mult_r( sub( new_scale, old_scale ), 205 ); - scale = old_scale; - move16(); - /* interpolate between the old and the new value of the mixing factor */ - old_fact = *prev_mix_factor; - move16(); - new_fact = mix_factor; - move16(); - // step = (new_fact - old_fact) / (L_FRAME16k / 2); - step = mult_r( sub( new_fact, old_fact ), 205 ); - fact = old_fact; - move16(); - /* mixing of LB and gaussian excitation in the first half of the frame */ - FOR( k = 0; k < L_FRAME16k / 2; k++ ) - { - exc16kWhtnd[k] = mac_r( L_mult( fact, mult_r( White_exc16k[k], scale ) ), - sub( 32767, fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd - move16(); - fact = add_sat( fact, step ); - scale = add_sat( scale, step_scale ); - } - - /* mixing of LB and gaussian excitation in the second half of the frame */ - FOR( ; k < L_FRAME16k; k++ ) - { - exc16kWhtnd[k] = mac_r( L_mult( new_fact, White_exc16k[k] ), - sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_exc16kWhtnd - move16(); - } - } - // preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - } - ELSE - { - test(); - IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) - { - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - test(); - if ( chk1 == 0 && chk2 == 0 ) - { - L_tmp = 0; - move32(); - } - scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); - move16(); - } - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - /* i/o: exc16kWhtnd (Q_exc16kWhtnd) */ - /* i/o: tbe_premph (Q_exc16kWhtnd) */ - } - ELSE - { - Word16 nbSubFr, lSubFr; - Word16 tempQ15; - Word32 tempQ31; - nbSubFr = NB_SUBFR16k; - lSubFr = ( L_FRAME16k / NB_SUBFR16k ); - move16(); - move16(); - IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) - { - nbSubFr = NB_SUBFR; - move16(); - lSubFr = ( L_FRAME16k / NB_SUBFR ); - move16(); - } - k = 0; - move16(); - FOR( i = 0; i < nbSubFr; i++ ) - { - test(); - IF( EQ_16( coder_type, VOICED ) && ( LT_32( extl_brate, SWB_TBE_2k8 ) ) ) - { - exp = 0; - move16(); - tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ - temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - exp = 0; - move16(); - tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ - temp = sub( MAX_16, temp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - ELSE - { - /* Adjust noise mixing for formant sharpening filter */ - tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); - /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ - vf_tmp = sub( MAX_16, tempQ15 ); - vf_tmp = mult( voice_factors[i], vf_tmp ); - - exp = 0; - move16(); - tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ - temp = sub( MAX_16, vf_tmp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - - FOR( j = 0; j < lSubFr; j++ ) - { - /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); - exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); - move16(); - /* Q_exc16kWhtnd */ - } - k = add( k, lSubFr ); - - /* estimate the pre-emph factor */ - tempQ15 = sub( MAX_16, voice_factors[i] ); - exp = 0; - move16(); - temp = Sqrt16( tempQ15, &exp ); - temp = shl( temp, sub( exp, 1 ) ); - - temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ - temp = div_s( temp, temp2 ); /* Q15 */ - temp = mult_r( PREEMPH_FAC, temp ); - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); - /* exc16kWhtnd: Q_exc16kWhtnd; - tbe_premph: Q_exc16kWhtnd*/ - } - } - } - *tbe_premph = shl_sat( *tbe_premph, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); - move16(); - Scale_sig( White_exc16k, L_FRAME16k, sub( sub( *Q_bwe_exc, NOISE_QADJ ), Q_White_exc16k ) ); - Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); - - IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) - { - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: excSHB in Q_bwe_exc */ - } - ELSE - { - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - - Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[0] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[1] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[2] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); - tmp = sub( getScaleFactor16( tempSHB, 80 ), 2 ); - Scale_sig( tempSHB, 80, tmp ); - syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); - syn_shb_ener_sf_q[3] = add( shl( add( *Q_bwe_exc, tmp ), 1 ), 1 ); - move16(); - - tmp2 = s_min( s_min( syn_shb_ener_sf_q[0], syn_shb_ener_sf_q[1] ), s_min( syn_shb_ener_sf_q[3], syn_shb_ener_sf_q[2] ) ); - syn_shb_ener_sf[0] = L_shl( syn_shb_ener_sf[0], sub( tmp2, syn_shb_ener_sf_q[0] ) ); - move32(); - syn_shb_ener_sf[1] = L_shl( syn_shb_ener_sf[1], sub( tmp2, syn_shb_ener_sf_q[1] ) ); - move32(); - syn_shb_ener_sf[2] = L_shl( syn_shb_ener_sf[2], sub( tmp2, syn_shb_ener_sf_q[2] ) ); - move32(); - syn_shb_ener_sf[3] = L_shl( syn_shb_ener_sf[3], sub( tmp2, syn_shb_ener_sf_q[3] ) ); - move32(); - - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: tempSHB in Q_bwe_exc */ - /* o: syn_shb_ener_sf in tmp2 */ - IF( LE_32( bitrate, MAX_ACELP_BRATE ) ) - { - L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); - - /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ - tmp = shl( Q_shb, 1 ); - L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ - - *Q_bwe_exc = sub( *Q_bwe_exc, exp ); - move16(); /* compensate for the exp shift */ - tmp2 = add( prev_Q_bwe_syn, n_mem2 ); - IF( GT_16( *Q_bwe_exc, tmp2 ) ) - { - L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); - *Q_bwe_exc = tmp2; - move16(); - } - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ - exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ - move16(); - } - } - /* i: L_tmp2 in (Q31-exp) */ - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ - - /* Rescale the past memories: LP synth and SHB look ahead buffers */ - tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - state_lpc_syn[i] = shl_sat( state_lpc_syn[i], tmp ); - move16(); - } - FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) - { - excSHB[i] = shl_sat( excSHB[i], tmp ); - move16(); - } - /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ - - Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in (Q_bwe_exc) */ - /* o: excSHB in (Q_bwe_exc) */ - } - - IF( EQ_16( extl, FB_TBE ) ) - { - tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); - Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); - Scale_sig( fb_tbe_demph, 1, tmp ); - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); - /* i: White_exc16k_FB in (14-n2) */ - /* o: White_exc16k_FB_temp in (14-n2) */ - - FOR( i = 0; i < 10; i++ ) - { - FOR( j = 0; j < 32; ++j ) - { - White_exc16k_FB_temp[i * 32 + j] = mult_r_sat( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); - move16(); - } - } - - *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); - move16(); /**Q_bwe_exc_fb +35 +1 -16*/ - flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); - - deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); - } - ELSE - { - set16_fx( White_exc16k_FB, 0, L_FRAME16k ); - } - -#if 1 // def ADD_IVAS_TBE_CODE - *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 - *prev_mix_factor = mix_factor; -#endif - return; -} - -/*====================================================================================*/ -/* FUNCTION : void GenSHBSynth_fx() */ -/*------------------------------------------------------------------------------------*/ -/* PURPOSE :Generate 32 KHz sampled highband component from synthesized highband*/ -/*------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS */ -/* _(Word16*)input_synspeech :input synthesized speech */ -/* _(Word16) L_frame :ACELP frame length */ -/*------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _(Word16*)shb_syn_speech_32k : output highband component */ -/*------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _(Word16[]) allpass_mem : memory */ -/* _(Word32[]) Hilbert_Mem : memory */ -/*------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*------------------------------------------------------------------------------------*/ - -void GenSHBSynth_fx( - const Word16 *input_synspeech, /* i : input synthesized speech */ - Word16 *shb_syn_speech_32k, /* o : output highband component */ - Word32 Hilbert_Mem[], /* i/o: memory */ - Word16 allpass_mem[], /* i/o: memory */ - const Word16 L_frame, /* i : ACELP frame length */ - Word16 *syn_dm_phase ) -{ - Word16 i, speech_buf_32k[L_FRAME32k]; - Word16 maxm, nor, nor32, shift; - Word16 input_synspeech_temp[L_FRAME16k]; - Word32 maxm32; - - - maxm = 0; - move16(); - maxm32 = L_deposit_l( 0 ); - FOR( i = 0; i < L_FRAME16k; i++ ) - maxm = s_max( maxm, abs_s( input_synspeech[i] ) ); - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - maxm = s_max( maxm, abs_s( allpass_mem[i] ) ); - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); - nor = sub( norm_s( maxm ), 3 ); - nor32 = sub( norm_l( maxm32 ), 3 ); - if ( maxm == 0 ) - { - nor = 15; - move16(); - } - if ( maxm32 == 0 ) - { - nor32 = 31; - move16(); - } - shift = s_min( nor, nor32 ); - - Copy_Scale_sig( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); - Scale_sig( allpass_mem, 2 * ALLPASSSECTIONS_STEEP, shift ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); - Interpolate_allpass_steep_fx( input_synspeech_temp, allpass_mem, L_FRAME16k, speech_buf_32k ); - /*modify_Fs_fx( input_synspeech, L_FRAME16k, 16000, speech_buf_32k, 32000, allpass_mem, 0);*/ - IF( EQ_16( L_frame, L_FRAME ) ) - { - /* 12.8 k core flipping and downmixing */ - flip_and_downmix_generic_fx( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, - Hilbert_Mem, - Hilbert_Mem + HILBERT_ORDER1, - Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), - syn_dm_phase ); - } - ELSE - { - /* 16 k core flipping and no downmixing */ - FOR( i = 0; i < L_FRAME32k; i = i + 2 ) - { - shb_syn_speech_32k[i] = negate( speech_buf_32k[i] ); - move16(); - shb_syn_speech_32k[i + 1] = speech_buf_32k[i + 1]; - move16(); - } - } - - Scale_sig( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); - Scale_sig( allpass_mem, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); - - return; -} - - -/* IVAS 32-bit variant */ -void GenSHBSynth_fx32( - const Word32 *input_synspeech, /* i : input synthesized speech Qx*/ - Word32 *shb_syn_speech_32k, /* o : output highband component Qx*/ - Word32 Hilbert_Mem[], /* i/o: memory Qx*/ - Word32 state_lsyn_filt_shb_local[], /* i/o: memory Qx*/ - const Word16 L_frame, /* i : ACELP frame length */ - Word16 *syn_dm_phase ) -{ - Word32 speech_buf_32k[L_FRAME32k]; - Word16 i; - - Word16 shift = 0; - Word32 maxm32, input_synspeech_temp[L_FRAME16k]; - move16(); - - /* find the maximum value and derive the shift to improve precision of the Hilber filter */ - maxm32 = L_deposit_l( 0 ); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - maxm32 = L_max( maxm32, L_abs( input_synspeech[i] ) ); - } - - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - maxm32 = L_max( maxm32, L_abs( state_lsyn_filt_shb_local[i] ) ); - } - - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); - } - - IF( maxm32 != 0 ) - { - shift = sub( norm_l( maxm32 ), 3 ); - - Copy_Scale_sig32( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); - Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); - } - ELSE - { - Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); - } - - Interpolate_allpass_steep_fx32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); - - IF( EQ_16( L_frame, L_FRAME ) ) - { - flip_and_downmix_generic_fx32( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, Hilbert_Mem, Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), syn_dm_phase ); - } - ELSE - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - // shb_syn_speech_32k[i] = ( ( i % 2 ) == 0 ) ? ( -speech_buf_32k[i] ) : ( speech_buf_32k[i] ); - IF( i % 2 == 0 ) - { - shb_syn_speech_32k[i] = L_negate( speech_buf_32k[i] ); // Qx - } - ELSE - { - shb_syn_speech_32k[i] = speech_buf_32k[i]; // Qx - } - move32(); - } - } - - IF( maxm32 != 0 ) - { - Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); - Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); - Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); - } - - return; -} - - -/*==============================================================================*/ -/* FUNCTION : void ScaleShapedSHB_fx() */ -/*------------------------------------------------------------------------------*/ -/* PURPOSE : */ -/*------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _(Word16) length : SHB overlap length */ -/* _(Word16*) subgain : subframe gain Q15 */ -/* _(Word32) frame_gain : frame gain Q18 */ -/* _(Word16*) win : window Q15 */ -/* _(Word16*) subwin : subframes window Q15 */ -/* _(Word16) Q_bwe_exc : Q format */ -/*------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _(Word16) Qx : Q factor of output */ -/*------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _(Word16*) synSHB : synthesized shb signal input Q_bwe_exc / output Qx */ -/* _(Word16*) overlap : buffer for overlap-add Q_bwe_exc /output Qx */ -/*------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*------------------------------------------------------------------------------*/ -/* CALLED FROM : RX */ -/*==============================================================================*/ - -void ScaleShapedSHB_fx( - const Word16 length, /* i : SHB overlap length */ - Word16 *synSHB, /* i/o : synthesized shb signal Q(Q_bwe_exc)/Q(Qx) */ - Word16 *overlap, /* i/o : buffer for overlap-add Q(Q_bwe_exc)/Q(Qx) */ - const Word16 *subgain, /* i : subframe gain Q15 */ - const Word32 frame_gain, /* i : frame gain Q18 */ - const Word16 *win, /* i : window Q15 */ - const Word16 *subwin, /* i : subframes window Q15 */ - Word16 *Q_bwe_exc, - Word16 *Qx, /* o : newly computed Q factor for synSHB */ - Word16 n_mem3, - Word16 prev_Q_bwe_syn2 ) -{ - const Word16 *skip; - Word16 i, j, k, l_shb_lahead, l_frame, l_frame_tmp; - Word16 join_length, num_join; - Word32 mod_syn[L_FRAME16k + L_SHB_LAHEAD]; - Word16 sum_gain; - Word32 L_tmp; - Word16 tmpQ15; - Word16 Q_gFr_norm, gain_frame_Q16; - Word32 L_tmp2; - Word16 temp1, temp2; - - /* Init */ - set32_fx( mod_syn, 0, L_FRAME16k + L_SHB_LAHEAD ); - - /* apply gain for each subframe, and store noise output signal using overlap-add */ - IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) - { - /* WB Gain shape and gain frame application with overlap */ - skip = skip_bands_WB_TBE; - l_frame = L_FRAME16k / 4; - move16(); - l_shb_lahead = L_SHB_LAHEAD / 4; - move16(); - - sum_gain = 0; - move16(); - FOR( k = 0; k < length / 2; k++ ) - { - sum_gain = mult_r( subwin[2 * k + 2], subgain[0] ); /* Q15 */ - mod_syn[skip[0] + k] = L_mult( sum_gain, synSHB[skip[0] + k] ); /* Q_bwe_exc + 16 */ - move32(); - mod_syn[skip[0] + k + length / 2] = L_mult( subgain[0], synSHB[skip[0] + k + length / 2] ); /* Q_bwe_exc + 16 */ - move32(); - } - FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) - { - FOR( k = 0; k < length; k++ ) - { - /* one bit headroom here, otherwise messes up the gain shape application */ - /* keep it as L_mult0 */ - L_tmp = L_mult0( subwin[k + 1], subgain[i] ); /* Q30 */ - sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i - 1] ) ); /* Q14 */ - mod_syn[skip[i] + k] = L_shl( L_mult( sum_gain, synSHB[skip[i] + k] ), 1 ); /* Q_bwe_exc + 16 */ - move32(); - } - } - FOR( k = 0; k < length / 2; k++ ) - { - sum_gain = mult_r( subwin[length - 2 * k - 2], subgain[i - 1] ); /* Q15 */ - mod_syn[skip[i] + k] = L_mult( sum_gain, synSHB[skip[i] + k] ); /* Q_bwe_exc + 16 */ - move32(); - } - } - ELSE - { - /* SWB Gain shape and gain frame application with overlap */ - l_frame = L_FRAME16k; - move16(); - l_shb_lahead = L_SHB_LAHEAD; - move16(); - skip = skip_bands_SWB_TBE; - - num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; - move16(); - join_length = i_mult2( num_join, length ); - j = 0; - move16(); - FOR( k = 0; k < length; k++ ) - { - sum_gain = mult_r( subwin[k + 1], subgain[0] ); /* Q15 */ - mod_syn[j] = L_mult( synSHB[j], sum_gain ); - move32(); /* Q_bwe_exc + 16 */ - j = add( j, 1 ); - } - - FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) - { - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn[j] = L_mult( synSHB[j], subgain[i * num_join] ); - move32(); /* Q_bwe_exc + 16 */ - j = add( j, 1 ); - } - - FOR( k = 0; k < length; k++ ) - { - /* one bit headroom here, otherwise messes up the gain shape application */ - /* keep it as L_mult0 */ - L_tmp = L_mult0( subwin[k + 1], subgain[( i + 1 ) * num_join] ); /* Q30 */ - sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i * num_join] ) ); /*Q14 */ - mod_syn[j] = L_shl( L_mult( sum_gain, synSHB[j] ), 1 ); - move32(); /* Q_bwe_exc + 16 */ - j = add( j, 1 ); - } - } - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn[j] = L_mult( synSHB[j], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); - move32(); /* Q_bwe_exc + 16 */ - j = add( j, 1 ); - } - FOR( k = 0; k < length; k++ ) - { - sum_gain = mult_r( subwin[length - k - 1], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); /* Q15 */ - mod_syn[j] = L_mult( synSHB[j], sum_gain ); - move32(); /* Q_bwe_exc + 16 */ - j = add( j, 1 ); - } - } - - - Q_gFr_norm = norm_l( frame_gain ); - if ( frame_gain == 0 ) - { - Q_gFr_norm = 31; - move16(); - } - Q_gFr_norm = sub( Q_gFr_norm, 1 ); /* give some headroom */ - - gain_frame_Q16 = round_fx( L_shl( frame_gain, Q_gFr_norm ) ); /* Q = 18 + Q_gFr_norm - 16 - = (Q_gFr_norm + 2) */ - - *Q_bwe_exc = add( *Q_bwe_exc, Q_gFr_norm ); /* compensate for the exp shift */ - move16(); - *Q_bwe_exc = sub( *Q_bwe_exc, 13 ); /* Keep Q-fac at => (Q_bwe_exc + Q_gFr_norm - 13) */ - move16(); - - /* check for headroom of previous buff memories: overlap, Hilbert, and interp all-pass mem */ - tmpQ15 = add( prev_Q_bwe_syn2, n_mem3 ); - if ( GT_16( *Q_bwe_exc, tmpQ15 ) ) - { - *Q_bwe_exc = tmpQ15; - move16(); - } - - *Qx = *Q_bwe_exc; - move16(); - /* rescale the overlap memory */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - temp2 = 1; - move16(); - if ( overlap[i] < 0 ) - { - temp2 = -1; - move16(); - } - temp1 = abs_s( overlap[i] ); - temp1 = shl( temp1, sub( *Q_bwe_exc, prev_Q_bwe_syn2 ) ); - overlap[i] = i_mult( temp1, temp2 ); - move16(); /* Q_bwe_exc + Q_gFr_norm - 13 */ - } - - FOR( i = 0; i < l_shb_lahead; i++ ) - { - L_tmp = Mpy_32_16_1( mod_syn[i], gain_frame_Q16 ); /* Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15 */ - L_tmp2 = Mpy_32_16_1( L_tmp, win[i] ); /* (Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15) + 15 + (1-16) */ - synSHB[i] = mac_r( L_tmp2, overlap[i], MAX_16 ); - move16(); /* Q_bwe_exc + Q_gFr_norm - 13 */ - synSHB[i + l_shb_lahead] = round_fx( L_tmp ); /* Q_bwe_exc + Q_gFr_norm - 13 */ - move16(); - } - - FOR( ; i < l_frame; i++ ) - { - L_tmp = Mpy_32_16_1( mod_syn[i], gain_frame_Q16 ); /* Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15 */ - synSHB[i] = round_fx( L_tmp ); /* Q_bwe_exc + Q_gFr_norm - 13 */ - move16(); - } - - l_frame_tmp = add( l_frame, l_shb_lahead ); - FOR( ; i < l_frame_tmp; i++ ) - { - L_tmp = Mpy_32_16_1( mod_syn[i], gain_frame_Q16 ); /* Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15 */ - L_tmp = Mpy_32_16_1( L_tmp, win[l_frame + l_shb_lahead - 1 - i] ); /* (Q_bwe_exc + 16 + Q_gFr_norm + 2 - 15) + 15 + (1-16) */ - overlap[i - l_frame] = round_fx( L_tmp ); /* Q_bwe_exc + Q_gFr_norm - 13 */ - move16(); - } - - return; -} - - -/* IVAS 32-bit variant */ -void ScaleShapedSHB_fx32( - const Word16 length, /* i : SHB overlap length */ - Word32 *synSHB_fx, /* i/o: synthesized shb signal Q_inp/Q_new */ - Word32 *overlap_fx, /* i/o: buffer for overlap-add Q_inp/Q_new */ - const Word16 *subgain_fx, /* i : subframe gain Q15 */ - const Word32 frame_gain_fx, /* i : frame gain Q18*/ - const Word16 *win_fx, /* i : window Q15 */ - const Word16 *subwin_fx, /* i : subframes window Q15 */ - Word16 *Q_inp, - Word16 *Q_new ) -{ - const Word16 *skip; - Word16 i, j, k, l_shb_lahead, l_frame; - Word16 join_length, num_join; - Word32 mod_syn_fx[L_FRAME16k + L_SHB_LAHEAD], L_tmp; - Word16 sum_gain_fx; - - /* initilaization */ - l_frame = L_FRAME16k; - l_shb_lahead = L_SHB_LAHEAD; - move16(); - move16(); - skip = skip_bands_SWB_TBE; - - IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) - { - skip = skip_bands_WB_TBE; - l_frame = L_FRAME16k / 4; - l_shb_lahead = L_SHB_LAHEAD / 4; - move16(); - move16(); - } - - /* apply gain for each subframe, and store noise output signal using overlap-add */ - set32_fx( mod_syn_fx, 0, l_frame + l_shb_lahead ); - - IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) - { - sum_gain_fx = 0; - move16(); - FOR( k = 0; k < shr( length, 1 ); k++ ) - { - sum_gain_fx = mult_r( subwin_fx[2 * k + 2], subgain_fx[0] ); - mod_syn_fx[skip[0] + k] = Mpy_32_16_1( synSHB_fx[skip[0] + k], sum_gain_fx ); - move32(); // Qx - mod_syn_fx[skip[0] + k + length / 2] = Mpy_32_16_1( synSHB_fx[skip[0] + k + length / 2], subgain_fx[0] ); // Qx - move32(); - } - FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) - { - FOR( k = 0; k < length; k++ ) - { - L_tmp = L_mult0( subwin_fx[k + 1], subgain_fx[i] ); - sum_gain_fx = round_fx( L_mac0( L_tmp, subwin_fx[length - k - 1], subgain_fx[i - 1] ) ); - mod_syn_fx[skip[i] + k] = L_shl( Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ), 1 ); // Qx - move32(); - } - } - FOR( k = 0; k < shr( length, 1 ); k++ ) - { - sum_gain_fx = mult_r( subwin_fx[length - k * 2 - 2], subgain_fx[i - 1] ); - mod_syn_fx[skip[i] + k] = Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ); // Qx - move32(); - } - } - ELSE - { - num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; - join_length = i_mult( num_join, length ); - j = 0; - move16(); - move16(); - FOR( k = 0; k < length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[k + 1], subgain_fx[0] ) ); // Qx - move32(); - j = add( j, 1 ); - } - FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) - { - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[i * num_join] ); // Qx - move32(); - j = add( j, 1 ); - } - - FOR( k = 0; k < length; k++ ) - { - L_tmp = L_mult0( subwin_fx[length - k - 1], subgain_fx[i * num_join] ); - mod_syn_fx[j] = L_shl( Mpy_32_16_1( synSHB_fx[j], round_fx( L_mac0( L_tmp, subwin_fx[k + 1], subgain_fx[( i + 1 ) * num_join] ) ) ), 1 ); // Qx - move32(); - j = add( j, 1 ); - } - } - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); // Qx - move32(); - j = add( j, 1 ); - } - FOR( k = 0; k < length; k++ ) - { - mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[length - k - 1], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ) ); // Qx - move32(); - j = add( j, 1 ); - } - } - - Word16 norm_shift = norm_l( frame_gain_fx ); - if ( frame_gain_fx == 0 ) - { - norm_shift = 31; - move16(); - } - - norm_shift = s_min( norm_shift, 14 ); - norm_shift = sub( norm_shift, 1 ); - - *Q_new = add( *Q_inp, sub( norm_shift, 13 ) ); // Q_new = Q_inp + min(norm_shift,14) - 14; - move16(); - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - overlap_fx[i] = L_shl( overlap_fx[i], sub( *Q_new, *Q_inp ) ); - move32(); - } - - FOR( i = 0; i < l_shb_lahead; i++ ) - { - synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[i] ) ); // Q_new - synSHB_fx[i] = L_add( synSHB_fx[i], overlap_fx[i] ); - synSHB_fx[i + l_shb_lahead] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new - move32(); - move32(); - move32(); - } - - FOR( ; i < l_frame; i++ ) - { - synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Q_new - move32(); - } - - FOR( ; i < l_frame + l_shb_lahead; i++ ) - { - synSHB_fx[i] = L_shl( synSHB_fx[i], sub( *Q_new, *Q_inp ) ); - overlap_fx[i - l_frame] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[l_frame + l_shb_lahead - 1 - i] ) ); // Q_new - move32(); - move32(); - } - - *Q_inp = *Q_new; - move16(); - return; -} - - -/*-------------------------------------------------------------------* - * ScaleShapedWB() - * - * - *-------------------------------------------------------------------*/ - -void ScaleShapedWB_fx( - const Word16 length, /* i : SHB overlap length */ - Word16 *synSHB, /* i/o : synthesized shb signal Q_bwe_exc/Qx */ - Word16 *overlap, /* i/o : buffer for overlap-add Q_bwe_exc/Qx */ - const Word16 *subgain, /* i : subframe gain Q15*/ - const Word32 frame_gain, /* i : frame gain Q18 */ - const Word16 *win, /* i : window Q15*/ - const Word16 *subwin, /* i : subframes window Q15*/ - const Word16 Q_bwe_exc, - Word16 L_frame, /* i : Frame length - determines whether 12.8 or 16kHz core in-use */ - Word16 dynQ, /* i : indicate whether output is dynamic Q, or Q0 */ - Word16 *Qx, /* o : newly computed Q factor for synSHB */ - Word16 prev_Qx, /* i : prev_Qx for memory scaling */ - Word32 *Hilbert_Mem /* i : Hilbert memory used for computing Qx */ -) -{ - const Word16 *skip; - Word16 i, j, k, l_shb_lahead, l_frame, l_frame_tmp; - Word16 join_length, num_join; - Word32 mod_syn[L_FRAME16k + L_SHB_LAHEAD]; - Word16 sum_gain; - Word32 L_tmp; - Word16 max_val, abs_sig, sc1, sc2, shift, max_headroom, min_shift, max_shift, max_shift2; - /* Init */ - set32_fx( mod_syn, 0, L_FRAME16k + L_SHB_LAHEAD ); - - /* apply gain for each subframe, and store noise output signal using overlap-add */ - IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) - { - /* WB Gain shape and gain frame application with overlap */ - skip = skip_bands_WB_TBE; - move16(); - l_frame = L_FRAME16k / 4; - move16(); - l_shb_lahead = L_SHB_LAHEAD / 4; - move16(); - - sum_gain = 0; - move16(); - FOR( k = 0; k < length / 2; k++ ) - { - sum_gain = mult_r( subwin[2 * k + 2], subgain[0] ); /* Q15 */ - mod_syn[skip[0] + k] = L_mult( sum_gain, synSHB[skip[0] + k] ); - move32(); /* Q_bwe_exc + 16 */ - mod_syn[skip[0] + k + length / 2] = L_mult( subgain[0], synSHB[skip[0] + k + length / 2] ); - move32(); /* Q_bwe_exc + 16 */ - } - FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) - { - FOR( k = 0; k < length; k++ ) - { - L_tmp = L_mult0( subwin[k + 1], subgain[i] ); /* Q30 */ - sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i - 1] ) ); /* Q14 */ - mod_syn[skip[i] + k] = L_shl( L_mult( sum_gain, synSHB[skip[i] + k] ), 1 ); - move32(); /* Q_bwe_exc + 16 */ - } - } - FOR( k = 0; k < length / 2; k++ ) - { - sum_gain = mult_r( subwin[length - 2 * k - 2], subgain[i - 1] ); /* Q15 */ - mod_syn[skip[i] + k] = L_mult( sum_gain, synSHB[skip[i] + k] ); - move32(); /* Q_bwe_exc + 16 */ - } - } - ELSE - { - /* SWB Gain shape and gain frame application with overlap */ - l_frame = L_FRAME16k; - move16(); - l_shb_lahead = L_SHB_LAHEAD; - move16(); - skip = skip_bands_SWB_TBE; - move16(); - - num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; - move16(); - join_length = i_mult2( num_join, length ); - j = 0; /* ptr*/ - move16(); - FOR( k = 0; k < length; k++ ) - { - sum_gain = mult_r( subwin[k + 1], subgain[0] ); /* Q15 */ - mod_syn[j] = L_mult( synSHB[j], sum_gain ); - move32(); /* Q_bwe_exc + 16 */ - j++; - } - - FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) - { - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn[j] = L_mult( synSHB[j], subgain[i * num_join] ); - move32(); /* Q_bwe_exc + 16 */ - j++; - } - - FOR( k = 0; k < length; k++ ) - { - L_tmp = L_mult0( subwin[k + 1], subgain[i_mult2( ( i + 1 ), num_join )] ); /* Q30 */ - sum_gain = round_fx( L_mac0( L_tmp, subwin[length - k - 1], subgain[i * num_join] ) ); /*Q14 */ - mod_syn[j] = L_shl( L_mult( sum_gain, synSHB[j] ), 1 ); - move32(); /* Q_bwe_exc + 16 */ - j++; - } - } - FOR( k = 0; k < join_length - length; k++ ) - { - mod_syn[j] = L_mult( synSHB[j], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); - move32(); /* Q_bwe_exc + 16 */ - j++; - } - FOR( k = 0; k < length; k++ ) - { - sum_gain = mult_r( subwin[length - k - 1], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); /* Q15 */ - mod_syn[j] = L_mult( synSHB[j], sum_gain ); - move32(); /* Q_bwe_exc + 16 */ - j++; - } - } - - - max_val = 0; - move16(); - FOR( i = 0; i < l_frame + l_shb_lahead; i++ ) - { - abs_sig = abs_s( round_fx( mod_syn[i] ) ); - if ( GT_16( abs_sig, max_val ) ) - { - max_val = abs_sig; - move16(); - } - } - - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - abs_sig = abs_s( round_fx( Hilbert_Mem[i] ) ); - if ( GT_16( abs_sig, max_val ) ) - { - max_val = abs_sig; - move16(); - } - } - - sc1 = norm_s( max_val ); /* max_val headroom in mod_syn[] */ - sc2 = norm_s( round_fx( frame_gain ) ); /* headroom in GainFrame */ - - IF( dynQ == 0 ) - { - shift = sub( 13, Q_bwe_exc ); /* earlier = (10 - Q_bwe_exc) but we changed GainFrame Q21 to Q18 */ - *Qx = 0; - move16(); - } - ELSE IF( EQ_16( L_frame, L_FRAME ) ) /* 12.8k core */ - { - max_headroom = sub( add( sc1, sc2 ), 4 ); /* Max headroom after multiplying = sc1 + sc2 -3 (keep 3 bit extra headroom) */ - /* 12.8k core needs extra headroom than 16k core */ - /* otherwise Hilbert transform inside flip_and_downmix have saturation, causes ringing in output */ - - /* Qx = (Q_bwe_exc+3) + shift - 16 */ - /* make sure 14 > Qx > 2 */ - min_shift = sub( 2, sub( add( Q_bwe_exc, 3 ), 16 ) ); - max_shift = sub( 13, sub( add( Q_bwe_exc, 3 ), 16 ) ); - max_shift2 = s_min( max_shift, max_headroom ); /* avoid shifting more than the available max_val headroom to avoid overflow */ - - shift = s_min( min_shift, max_shift2 ); - *Qx = sub( add( add( Q_bwe_exc, 3 ), shift ), 16 ); - move16(); - } - ELSE /* 16k core */ - { - max_headroom = sub( add( sc1, sc2 ), 1 ); /* Max headroom after multiplying = sc1 + sc2 -1 (keep 1 bit extra headroom) */ - - /* Qx = (Q_bwe_exc+3) + shift - 16 */ - /* make sure 14 > Qx > 3 */ - min_shift = sub( 3, sub( add( Q_bwe_exc, 3 ), 16 ) ); - move16(); - max_shift = sub( 13, sub( add( Q_bwe_exc, 3 ), 16 ) ); - move16(); - max_shift2 = s_min( max_shift, max_headroom ); /* avoid shifting more than the available max_val headroom to avoid overflow */ - - shift = s_min( min_shift, max_shift2 ); - *Qx = sub( add( add( Q_bwe_exc, 3 ), shift ), 16 ); - move16(); - } - - /* bring memory st_fx->syn_overlap_fx[] = overlap[i] to new Q = Qx to prepare for addition */ - FOR( i = 0; i < l_shb_lahead; i++ ) - { - overlap[i] = shl( overlap[i], sub( *Qx, prev_Qx ) ); - move16(); - } - - FOR( i = 0; i < l_shb_lahead; i++ ) - { - /* mod_syn in (16+Q_bwe_exc), frame_gain in Q18 */ - L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ - synSHB[i] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, win[i] ), shift ) ); /* Qx */ - move16(); - synSHB[i] = add_sat( synSHB[i], overlap[i] ); - move16(); /* Qx */ - synSHB[i + l_shb_lahead] = round_fx_sat( L_shl_sat( L_tmp, shift ) ); /* Qx */ - move16(); - } - - FOR( ; i < l_frame; i++ ) - { - L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ - synSHB[i] = round_fx_sat( L_shl_sat( L_tmp, shift ) ); /* Qx; */ - move16(); - } - - l_frame_tmp = add( l_frame, l_shb_lahead ); - FOR( ; i < l_frame_tmp; i++ ) - { - L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* (Q_bwe_exc+3) */ - overlap[i - l_frame] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, win[l_frame + l_shb_lahead - 1 - i] ), shift ) ); /* Qx */ - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * non_linearity() - * - * Apply a non linearity to the SHB excitation - * -------------------------------------------------------------------*/ - -static Word32 non_linearity_scaled_copy( - const Word16 input[], - Word16 j, - const Word16 length, - Word32 output[], - Word32 prev_scale, - const Word16 scale_step, - const Word16 en_abs ) -{ - Word16 i; - Word32 L_tmp; - - - IF( en_abs ) - { - FOR( i = 0; i < j; i++ ) - { - L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - output[i] = L_tmp; - move32(); - - L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ - prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ - } - FOR( ; i < length; i++ ) - { - L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - output[i] = L_tmp; - move32(); - } - } - ELSE - { - FOR( i = 0; i < j; i++ ) - { - L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - - if ( input[i] < 0 ) - { - L_tmp = L_negate( L_tmp ); - } - output[i] = L_tmp; - move32(); - - L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ - prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ - } - - FOR( ; i < length; i++ ) - { - L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - - if ( input[i] < 0 ) - { - L_tmp = L_negate( L_tmp ); - } - output[i] = L_tmp; - move32(); - } - } - return prev_scale; -} - - -/*-------------------------------------------------------------------* - * non_linearity() - * - * Apply a non linearity to the SHB excitation - * -------------------------------------------------------------------*/ - -static Word32 non_linearity_scaled_copy_ivas( - const Word16 input[], - Word16 j, - const Word16 length, - Word32 output[], - Word32 prev_scale, - const Word16 scale_step, - const Word16 en_abs ) -{ - Word16 i; - Word32 L_tmp; - - - IF( en_abs ) - { - FOR( i = 0; i < j; i++ ) - { - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - - test(); - test(); - if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) - { - /* NOTE: this is done to avoid the product to become zero for small non-zero input */ - L_tmp = 1; - move16(); - } - - output[i] = L_tmp; - move32(); - - L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ - prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ - } - FOR( ; i < length; i++ ) - { - /* L_tmp = (input[i] * input[i]) * prev_scale;*/ - L_tmp = Mpy_32_16_1( Mpy_32_16_1( prev_scale, input[i] ), input[i] ); /* 2*Q_inp */ - - test(); - test(); - if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) - { - /* NOTE: this is done to avoid the product to become zero for small non-zero input */ - L_tmp = 1; - move16(); - } - output[i] = L_tmp; - move32(); - } - } - ELSE - { - FOR( i = 0; i < j; i++ ) - { - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - - test(); - test(); - if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) - { - /* NOTE: this is done to avoid the product to become zero for small non-zero input */ - L_tmp = 1; - move16(); - } - - if ( input[i] < 0 ) - { - L_tmp = L_negate( L_tmp ); - } - output[i] = L_tmp; - move32(); - - L_tmp = Mult_32_16( prev_scale, scale_step ); /* Q29 */ - prev_scale = L_shl( L_tmp, 1 ); /* Q30 */ - } - - FOR( ; i < length; i++ ) - { - L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ - test(); - test(); - if ( input[i] != 0 && prev_scale != 0 && L_tmp == 0 ) - { - /* NOTE: this is done to avoid the product to become zero for small non-zero input */ - L_tmp = 1; - move16(); - } - - if ( input[i] < 0 ) - { - L_tmp = L_negate( L_tmp ); - } - output[i] = L_tmp; - move32(); - } - } - return prev_scale; -} - - -/*==========================================================================*/ -/* FUNCTION : void non_linearity() */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : Apply a non linearity to the SHB excitation */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* Word16 input[] i : input signal Q_inp */ -/* Word16 length i : input length */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* Word32 output[] o : output signal 2*Q_inp */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Word32 *prev_scale i/o: memory Q30 */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* CALLED FROM : */ -/*==========================================================================*/ - -void non_linearity_fx( - const Word16 input[], /* i : input signal Q_inp */ - Word32 output[], /* o : output signal 2*Q_inp */ - const Word16 length, /* i : input length */ - Word32 *pPrevScale, /* i/o: memory Q30 */ - Word16 Q_inp, - Word16 coder_type, /* i : Coder Type */ - Word16 *voice_factors, /* i : Voice Factors */ - const Word16 L_frame /* i : ACELP frame length */ - -) -{ - Word16 i, j; - Word16 max_val = 0; - move16(); - Word32 scale; - Word16 scale_step; - Word16 exp, tmp; - Word16 e_tmp, f_tmp; - Word16 frac; - Word32 L_tmp; - Word32 L_tmp1; - - Word16 en_abs = 0; - Word16 v_fac = 0; - move16(); - move16(); - Word16 ths; - Word16 nframes; - Word32 prev_scale; - Word16 length_half; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - nframes = 5; - move16(); - ths = 17817; - move16(); /* 0.87*5 in Q12 */ - } - ELSE - { - nframes = 4; - move16(); - ths = 15400; - move16(); /* 0.94*4 in Q12 */ - } - - - FOR( i = 0; i < nframes; i++ ) - { - v_fac = add( v_fac, shr( voice_factors[i], 3 ) ); /* Q12 */ - } - - test(); - if ( EQ_16( coder_type, VOICED ) && GT_16( v_fac, ths ) ) - { - en_abs = 1; - move16(); - } - - length_half = shr( length, 1 ); - prev_scale = *pPrevScale; - move32(); - - - /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ - - FOR( i = j = 0; i < length_half; i++ ) - { - tmp = abs_s( input[i] ); - if ( GT_16( tmp, max_val ) ) - { - j = i; - move16(); - } - max_val = s_max( max_val, tmp ); - } - - - IF( GT_16( max_val, shl( 1, Q_inp ) ) ) - { - exp = norm_s( max_val ); - tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ - scale = L_shl( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ) ); /* Q31 */ - } - ELSE - { - scale = 1438814044; - move32(); /* Q31; 0.67 in Q31 */ - } - - test(); - IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 32 ), scale ) ) - { - scale_step = 16384; - move16(); /* Q14 */ - prev_scale = L_shr( scale, 1 ); /* Q30 */ - } - ELSE - { - - /* Computing log2(scale) */ - IF( j == 0 ) - { - scale_step = 32767; - move16(); - } - ELSE - { - e_tmp = norm_l( scale ); - f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); - e_tmp = sub( -1, e_tmp ); - L_tmp = Mpy_32_16( e_tmp, f_tmp, MAX_16 ); /* Q16 */ - - /* Computing log2(prev_scale) */ - e_tmp = norm_l( prev_scale ); - f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); - e_tmp = negate( e_tmp ); - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, MAX_16 ); /* Q16 */ - - /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ - L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ - - /* Computing 1/j */ - exp = norm_s( j ); - tmp = div_s( shl( 1, sub( 14, exp ) ), j ); /* Q(29-exp) */ - - /* (log2(scale / prev_scale))/length */ - L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ - - frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ - - tmp = extract_l( Pow2( 14, frac ) ); - scale_step = shl_o( tmp, exp, &Overflow ); /* Q14 */ - } - } - - prev_scale = non_linearity_scaled_copy( input, j, length_half, output, prev_scale, scale_step, en_abs ); - - max_val = 0; - move16(); - j = shr( length, 1 ); - FOR( i = length_half; i < length; i++ ) - { - tmp = abs_s( input[i] ); - if ( GT_16( tmp, max_val ) ) - { - j = i; - move16(); - } - max_val = s_max( max_val, tmp ); - } - - IF( GT_16( max_val, shl( 1, Q_inp ) ) ) - { - exp = norm_s( max_val ); - tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ - scale = L_shl_o( L_mult( 21955 /* 0.67 in Q15 */, tmp ), add( exp, sub( Q_inp, 14 ) ), &Overflow ); /* Q31 */ - } - ELSE - { - scale = 1438814044; - move32(); /* Q31; 0.67 in Q31 */ - } - - test(); - IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 32 ), scale ) ) - { - scale_step = 16384; - move16(); /*Q14 */ - prev_scale = L_shr( scale, 1 ); /*Q30 */ - } - ELSE - { - /*scale_step = (float) exp(1.0f / (float) (j - length/2) * (float) log(scale / prev_scale)); */ - /* Computing log2(scale) */ - IF( EQ_16( j, length_half ) ) - { - scale_step = 32767; - move16(); /*Q14 */ - } - ELSE - { - e_tmp = norm_l( scale ); - f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); - e_tmp = sub( -e_tmp, 1 ); - L_tmp = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ - - /* Computing log2(prev_scale) */ - e_tmp = norm_l( prev_scale ); - f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); - e_tmp = negate( e_tmp ); - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ - - /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ - L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ - - /* Computing 1/(j - length/2) */ - - tmp = sub( j, length_half ); - exp = norm_s( tmp ); - - - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* Q(29-exp) */ - - /* (log2(scale / prev_scale))/length */ - L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ - - frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ - - tmp = extract_l( Pow2( 14, frac ) ); - scale_step = shl_o( tmp, exp, &Overflow ); /*Q14 */ - } - } - - prev_scale = non_linearity_scaled_copy( input + length_half, sub( j, length_half ), sub( length, length_half ), output + length_half, prev_scale, scale_step, en_abs ); - - *pPrevScale = prev_scale; - move32(); - - /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ - - return; -} - - -/*==========================================================================*/ -/* FUNCTION : void non_linearity_ivas_fx() */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : Apply a non linearity to the SHB excitation */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* Word16 input[] i : input signal Q_inp */ -/* Word16 length i : input length */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* Word32 output[] o : output signal 2*Q_inp */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Word32 *prev_scale i/o: memory Q30 */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* CALLED FROM : */ -/*==========================================================================*/ - -void non_linearity_ivas_fx( - const Word16 input[], /* i : input signal Q_inp */ - Word32 output[], /* o : output signal 2*Q_inp */ - const Word16 length, /* i : input length */ - Word32 *pPrevScale, /* i/o: memory Q30 */ - Word16 Q_inp, - Word16 coder_type, /* i : Coder Type */ - Word16 *voice_factors, /* i : Voice Factors */ - const Word16 L_frame /* i : ACELP frame length */ - -) -{ - Word16 i, j; - Word16 max_val = 0; - move16(); - Word32 scale; - Word16 scale_step; - Word16 exp, tmp; - Word16 e_tmp, f_tmp; - Word16 frac; - Word32 L_tmp; - Word32 L_tmp1; - - Word16 en_abs = 0; - Word16 v_fac = 0; - move16(); - move16(); - Word16 ths; - Word16 nframes; - Word32 prev_scale; - Word16 length_half; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - nframes = 5; - move16(); - ths = 17817; - move16(); /* 0.87*5 in Q12 */ - } - ELSE - { - nframes = 4; - move16(); - ths = 15400; - move16(); /* 0.94*4 in Q12 */ - } - - - FOR( i = 0; i < nframes; i++ ) - { - v_fac = add( v_fac, shr( voice_factors[i], 3 ) ); /* Q12 */ - } - - test(); - if ( EQ_16( coder_type, VOICED ) && GT_16( v_fac, ths ) ) - { - en_abs = 1; - move16(); - } - - length_half = shr( length, 1 ); - prev_scale = *pPrevScale; - move32(); - - - /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ - - FOR( i = j = 0; i < length_half; i++ ) - { - tmp = abs_s( input[i] ); - if ( GT_16( tmp, max_val ) ) - { - j = i; - move16(); - } - max_val = s_max( max_val, tmp ); - } - - - IF( GT_16( max_val, shl( 1, Q_inp ) ) ) - { - exp = norm_s( max_val ); - tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ - scale = L_shl( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ) ); /* Q31 */ - } - ELSE - { - scale = 1438814044; - move32(); /* Q31; 0.67 in Q31 */ - } - - test(); - IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 64 ) /*Q30 -> Q31*/, scale /*Q31*/ ) ) - { - scale_step = 16384; - move16(); /* Q14 */ - prev_scale = L_shr( scale, 1 ); /* Q30 */ - } - ELSE - { - - /* Computing log2(scale) */ - IF( j == 0 ) - { - scale_step = 32767; - move16(); - } - ELSE - { - e_tmp = norm_l( scale ); - f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); - e_tmp = sub( -1, e_tmp ); - L_tmp = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ - - /* Computing log2(prev_scale) */ - e_tmp = norm_l( prev_scale ); - f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); - e_tmp = negate( e_tmp ); - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ - - /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ - L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ - - /* Computing 1/j */ - exp = norm_s( j ); - tmp = div_s( shl( 1, sub( 14, exp ) ), j ); /* Q(29-exp) */ - - /* (log2(scale / prev_scale))/length */ - L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ - - frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ - - tmp = extract_l( Pow2( 14, frac ) ); - scale_step = shl_o( tmp, exp, &Overflow ); /* Q14 */ - } - } - - prev_scale = non_linearity_scaled_copy_ivas( input, j, length_half, output, prev_scale, scale_step, en_abs ); - - max_val = 0; - move16(); - j = shr( length, 1 ); - FOR( i = length_half; i < length; i++ ) - { - tmp = abs_s( input[i] ); - if ( GT_16( tmp, max_val ) ) - { - j = i; - move16(); - } - max_val = s_max( max_val, tmp ); - } - - IF( GT_16( max_val, shl( 1, Q_inp ) ) ) - { - exp = norm_s( max_val ); - tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ - scale = L_shl_o( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ), &Overflow ); /* Q31 */ - } - ELSE - { - scale = 1438814044; - move32(); /* Q31; 0.67 in Q31 */ - } - - test(); - IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 64 ), scale ) ) - { - scale_step = 16384; - move16(); /*Q14 */ - prev_scale = L_shr( scale, 1 ); /*Q30 */ - } - ELSE - { - /*scale_step = (float) exp(1.0f / (float) (j - length/2) * (float) log(scale / prev_scale)); */ - /* Computing log2(scale) */ - IF( EQ_16( j, length_half ) ) - { - scale_step = 32767; - move16(); /*Q14 */ - } - ELSE - { - e_tmp = norm_l( scale ); - f_tmp = Log2_norm_lc( L_shl( scale, e_tmp ) ); - e_tmp = sub( -e_tmp, 1 ); - L_tmp = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ - - /* Computing log2(prev_scale) */ - e_tmp = norm_l( prev_scale ); - f_tmp = Log2_norm_lc( L_shl( prev_scale, e_tmp ) ); - e_tmp = negate( e_tmp ); - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 32767 ); /* Q16 */ - - /* log2(scale / prev_scale) = log2(scale) - log2(prev_scale) */ - L_tmp = L_sub( L_tmp, L_tmp1 ); /* Q16 */ - - /* Computing 1/(j - length/2) */ - - tmp = sub( j, length_half ); - exp = norm_s( tmp ); - - - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* Q(29-exp) */ - - /* (log2(scale / prev_scale))/length */ - L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ - - frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ - - tmp = extract_l( Pow2( 14, frac ) ); - scale_step = shl_o( tmp, exp, &Overflow ); /*Q14 */ - } - } - - prev_scale = non_linearity_scaled_copy_ivas( input + length_half, sub( j, length_half ), sub( length, length_half ), output + length_half, prev_scale, scale_step, en_abs ); - - *pPrevScale = prev_scale; - move32(); - - /* Delay Alignment in FX is done inside swb_tbe_enc_fx() */ - - return; -} - - -/*-------------------------------------------------------------------* - * create_random_vector() - * - * creates random number vector - * Note: the abs(max_val) value coming out of create_random_vector should - * fit into the precision of Q6. - * -------------------------------------------------------------------*/ - -void create_random_vector_fx( - Word16 output[], /* o : output random vector Q5*/ - const Word16 length, /* i : length of random vector */ - Word16 seed[] /* i/o: start seed */ -) -{ - Word16 i, j, k; - Word16 scale1, scale2; - Word32 L_tmp; - - L_tmp = L_abs( Mult_32_16( 2144047674, Random( &seed[0] ) ) ); /*Q23 */ - j = extract_l( L_shr( L_tmp, 23 ) ); - j = s_and( j, 0xff ); - - L_tmp = L_abs( Mult_32_16( 2144047674, Random( &seed[1] ) ) ); /*Q23 */ - k = extract_l( L_shr( L_tmp, 23 ) ); - k = s_and( k, 0xff ); - - WHILE( EQ_16( k, j ) ) - { - L_tmp = L_abs( Mult_32_16( 2144047674, Random( &seed[1] ) ) ); /*Q23 */ - k = extract_l( L_shr( L_tmp, 23 ) ); - k = s_and( k, 0xff ); - } - - scale1 = 18021; - move16(); /* 200.00f * 0.35f/0.1243f; */ - if ( Random( &seed[0] ) < 0 ) - { - scale1 = -18021; - move16(); /*Q5 */ /* -200.00f * 0.35f/0.1243f; */ - } - - scale2 = 7208; - move16(); /* 80.00f * 0.35f/0.1243f; */ - if ( Random( &seed[1] ) < 0 ) - { - scale2 = -7208; - move16(); /*Q5 */ /* -80.00f * 0.35f/0.1243f; */ - } - - FOR( i = 0; i < length; i++ ) - { - j = s_and( j, 0xff ); - k = s_and( k, 0xff ); - output[i] = round_fx( L_add( L_mult( scale1, gaus_dico_swb_fx[j] ), L_mult( scale2, gaus_dico_swb_fx[k] ) ) ); /*Q5 */ - move16(); - j++; - k++; - } - - return; -} - - -/*======================================================================================*/ -/* FUNCTION : interp_code_5over2_fx() */ -/*--------------------------------------------------------------------------------------*/ -/* PURPOSE : Used to interpolate the excitation from the core sample rate */ -/* of 12.8 kHz to 32 kHz. */ -/* Simple linear interpolator - No need FOR precision here. */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16[]) inp_code_fx : input vector (Q12) */ -/* _ (Word16) inp_length : length of input vector */ -/*--------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16[]) interp_code_fx : output vector (Q12) */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------------------*/ - -/* _ None */ -/*--------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*======================================================================================*/ - -void interp_code_5over2_fx( - const Word16 inp_code_fx[], /* i : input vector Qx*/ - Word16 interp_code_fx[], /* o : output vector Qx*/ - const Word16 inp_length /* i : length of input vector */ -) -{ - Word16 i, kk, kkp1, i_len2; - Word32 Ltemp; - Word16 factor_i_fx[5] = { 6554, 19661, 32767, 19661, 6554 }; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - Word16 factor_j_fx[5] = { 26214, 13107, 0, 13107, 26214 }; - move16(); - move16(); - move16(); - move16(); - move16(); - interp_code_fx[0] = inp_code_fx[0]; - move16(); /* Qx */ - - Ltemp = L_mult( inp_code_fx[0], factor_i_fx[3] ); /* Q(16+x) */ - Ltemp = L_mac( Ltemp, inp_code_fx[1], factor_j_fx[3] ); /* Q(16+x) */ - interp_code_fx[1] = round_fx( Ltemp ); /*Qx */ - move16(); - Ltemp = L_mult( inp_code_fx[0], factor_i_fx[4] ); /*Q(16+x) */ - Ltemp = L_mac( Ltemp, inp_code_fx[1], factor_j_fx[4] ); /*Q(16+x) */ - interp_code_fx[2] = round_fx( Ltemp ); /* Qx */ - move16(); - kk = 1; - move16(); - kkp1 = 2; - move16(); - i = 3; - move16(); - /*i_len2 = ( inp_length - 2 ) * HIBND_ACB_L_FAC; */ /*HIBND_ACB_L_FAC == 5/2 */ - i_len2 = sub( inp_length, 2 ); - i_len2 = shr( add( shl( i_len2, 2 ), i_len2 ), 1 ); /* rounding below during shr makes it non BE*/ - - FOR( ; i < i_len2; i += 5 ) - { - Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[0] ); /*Q(16+x) */ - Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_i_fx[0] ); /*Q(16+x) */ - interp_code_fx[i] = round_fx( Ltemp ); /*Qx */ - move16(); - Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[1] ); /*Q(16+x) */ - Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_i_fx[1] ); /*Q(16+x) */ - interp_code_fx[i + 1] = round_fx( Ltemp ); /*Qx */ - move16(); - Ltemp = L_mult( inp_code_fx[kkp1], factor_i_fx[2] ); /*Q(16+x) */ - interp_code_fx[i + 2] = round_fx( Ltemp ); /*Qx */ - move16(); - kk++; - kkp1++; - - Ltemp = L_mult( inp_code_fx[kk], factor_i_fx[3] ); /*Q(16+x) */ - Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_j_fx[3] ); /*Q(16+x) */ - interp_code_fx[i + 3] = round_fx( Ltemp ); /*Qx */ - move16(); - Ltemp = L_mult( inp_code_fx[kk], factor_i_fx[4] ); /*Q(16+x) */ - Ltemp = L_mac( Ltemp, inp_code_fx[kkp1], factor_j_fx[4] ); /*Q(16+x) */ - interp_code_fx[i + 4] = round_fx( Ltemp ); /*Qx */ - move16(); - kk++; - kkp1++; - } - - Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[0] ); /*Q(16+x) */ - interp_code_fx[i] = round_fx( Ltemp ); /*Qx */ - move16(); - Ltemp = L_mult( inp_code_fx[kk], factor_j_fx[1] ); /*Q(16+x) */ - interp_code_fx[i + 1] = round_fx( Ltemp ); /*Qx */ - move16(); - return; -} - - -/*======================================================================================*/ -/* FUNCTION : interp_code_4over2_fx() */ -/*--------------------------------------------------------------------------------------*/ -/* PURPOSE : Used to interpolate the excitation from the core sample rate */ -/* of 16 kHz to 32 kHz. */ -/* Simple linear interpolator - No need for precision here. */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16[]) inp_code_fx : input vector (Qx) */ -/* _ (Word16) inp_length : length of input vector */ -/*--------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16[]) interp_code_fx : output vector (Qx) */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------------------*/ - -/* _ None */ -/*--------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*======================================================================================*/ - -void interp_code_4over2_fx( - const Word16 inp_code_fx[], /* i : input vector Qx*/ - Word16 interp_code_fx[], /* o : output vector Qx*/ - const Word16 inp_length /* i : length of input vector */ -) -{ - Word16 i, j; - j = 0; - move16(); - FOR( i = 0; i < inp_length - 1; i++ ) - { - interp_code_fx[j] = inp_code_fx[i]; - move16(); /*Qx */ - interp_code_fx[j + 1] = add( shr( inp_code_fx[i], 1 ), shr( inp_code_fx[i + 1], 1 ) ); - move16(); - move16(); /*Qx */ - j = add( j, 2 ); - } - - interp_code_fx[j] = inp_code_fx[i]; - move16(); - interp_code_fx[j + 1] = shr( inp_code_fx[i], 1 ); - move16(); /*Qx */ - - return; -} - - -/*-------------------------------------------------------------------* - * wb_tbe_extras_reset_synth() - * - * Reset the extra parameters only required for WB TBE synthesis - *-------------------------------------------------------------------*/ - -void wb_tbe_extras_reset_synth_fx( - Word16 state_lsyn_filt_shb[], - Word16 state_lsyn_filt_dwn_shb[], - Word16 state_32and48k_WB_upsample[], - Word16 state_resamp_HB[] ) -{ - set16_fx( state_lsyn_filt_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); - set16_fx( state_lsyn_filt_dwn_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); - set16_fx( state_32and48k_WB_upsample, 0, 2 * ALLPASSSECTIONS_STEEP ); - set16_fx( state_resamp_HB, 0, INTERP_3_1_MEM_LEN ); - - return; -} -#if defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 ) && defined( FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 ) -static inline Word64 wmac_1616( Word64 x1, Word16 x2, Word16 x3 ) -{ - return W_mac_16_16( x1, x2, x3 ); -} - -static inline Word64 wmac_3216( Word64 x1, Word32 x2, Word16 x3 ) -{ - return W_mac_32_16( x1, x2, x3 ); -} - -static inline Word64 finalSat16( Word64 W_tmpx, Word64 W_tmpy ) -{ - return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -} - -static inline Word64 finalSat32( Word64 W_tmpx, Word64 W_tmpy ) -{ - return W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); -} - -inline static void elliptic_bpf_48k_generic_func1( Word16 *input16_fx, Word32 *input32_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) -{ - Word32 L_tmpX; - Word16 i; - Word32 L_tmpMax2 = *L_tmpMax; - Word32 L_tmpAbs; - move32(); - - if ( input16_fx > 0 ) - { - Word64 ( *wmac )( Word64, Word16, Word16 ); - Word64 ( *finalSat )( Word64, Word64 ); - Word16 *input_fx = input16_fx; - wmac = wmac_1616; - finalSat = finalSat16; - } - if ( input32_fx > 0 ) - { - Word64 ( *wmac )( Word64, Word32, Word16 ); - Word64 ( *finalSat )( Word64, Word64 ); - Word32 *input_fx = input32_fx; - wmac = wmac_3216; - finalSat = finalSat32; - } - - IF( !IsUpsampled3 ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } - } /*IsUpsampled3*/ - ELSE - { /*IsUpsampled3*/ - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = wmac( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = wmac( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpX = wmac( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = wmac( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = wmac( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = finalSat( W_tmpX, W_tmpY ); /*Q_input_fx + 11*/ - move32(); - if ( *L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( *L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } - } /*IsUpsampled3*/ - *L_tmpMax = L_tmpMax2; - move32(); -} -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - -/*-------------------------------------------------------------------* - * elliptic_bpf_48k_generic() - * - * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz - * Implemented as 3 fourth order sections cascaded. - *-------------------------------------------------------------------*/ - -void elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 IsUpsampled3, - Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif - Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal memory_fx_Q */ - Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ - Word16 memory_fx_Q[], - const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ -) -{ - Word16 i, j; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 memory_fx0, Q_temp, Q_temp2; - Word32 L_tmp_buffer[L_FRAME48k + 4], L_tmp2_buffer[L_FRAME48k + 4], L_output_buffer[L_FRAME48k + 4]; - Word32 L_tmpMax; - Word32 L_tmpX; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - Word64 W_tmpX; - Word64 W_tmpY; -#endif - - Word32 *L_tmp = &L_tmp_buffer[4]; - Word32 *L_tmp2 = &L_tmp2_buffer[4]; - Word32 *L_output = &L_output_buffer[4]; -#else - Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; - Word32 memory2_fx_2[4], memory2_fx_3[4]; -#endif - -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - FOR( i = 0; i < 4; i++ ) - { - memory_fx0 = extract_l( memory_fx2[0][i] ); - input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); - L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - move32(); - move32(); - } - -#else - FOR( i = 0; i < 4; i++ ) - { - memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); - memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - move32(); - move32(); - } -#endif - -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( input_fx, 0, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - IF( !IsUpsampled3 ) - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } - } - } /*IsUpsampled3*/ - ELSE - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - } - } - } /*IsUpsampled3*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; - memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; - memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; - memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; - move32(); - move32(); - move32(); - move32(); - move32(); - -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - elliptic_bpf_48k_generic_func1( 0, L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - } - ELSE -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - } - -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } -#endif - - - Q_temp = norm_l( L_tmpMax ); - Q_temp = sub( Q_temp, 4 ); - Scale_sig32( L_tmp2, 960, Q_temp ); - - memory_fx2[1][0] = L_tmp[L_FRAME48k - 4]; - memory_fx2[1][1] = L_tmp[L_FRAME48k - 3]; - memory_fx2[1][2] = L_tmp[L_FRAME48k - 2]; - memory_fx2[1][3] = L_tmp[L_FRAME48k - 1]; - move32(); - move32(); - move32(); - move32(); - move32(); - -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - FOR( j = 0; j < 4; j++ ) - { - L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - L_output[j - 4] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - } - - L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( 0, L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - IF( isIVAS ) - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - } - ELSE -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - { - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - } - -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - FOR( j = 0; j < 4; j++ ) - { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - } - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); - - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - -#endif - - - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; - memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; - memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; - memory_fx2[2][3] = L_tmp2[L_FRAME48k - 1]; - memory_fx2[3][0] = L_output[L_FRAME48k - 4]; - memory_fx2[3][1] = L_output[L_FRAME48k - 3]; - memory_fx2[3][2] = L_output[L_FRAME48k - 2]; - memory_fx2[3][3] = L_output[L_FRAME48k - 1]; - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - memory_fx_Q[0] = *Q_input_fx; - memory_fx_Q[1] = add( *Q_input_fx, 11 ); - memory_fx_Q[2] = add( add( *Q_input_fx, 6 ), Q_temp ); - memory_fx_Q[3] = add( add( *Q_input_fx, 1 ), Q_temp ); - move16(); - move16(); - move16(); - move16(); - Q_temp2 = norm_l( L_tmpMax ); - Scale_sig32( L_output, 960, Q_temp2 ); - FOR( i = 0; i < 960; i++ ) - { - output_fx[i] = extract_h( L_output[i] ); - move16(); - } - *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); - move16(); /* BASOP_NOGLOB */ - - return; -} -/*-------------------------------------------------------------------* - * synthesise_fb_high_band() - * - * Creates the highband output for full band - 14.0 to 20 kHz - * Using the energy shaped white excitation signal from the SWB BWE. - * The excitation signal input is sampled at 16kHz and so is upsampled - * to 48 kHz first. - * Uses a complementary split filter to code the two regions from - * 14kHz to 16kHz and 16 kHz to 20 kHz. - * One of 16 tilt filters is also applied afterwards to further - * refine the spectral shape of the fullband signal. - * The tilt is specified in dB per kHz. N.B. Only negative values are - * accomodated. - *-------------------------------------------------------------------*/ - -void synthesise_fb_high_band_fx( - const Word16 excitation_in[], /* i : full band excitation */ - Word16 Q_fb_exc, - Word16 output[], /* o : high band speech - 14.0 to 20 kHz */ - const Word32 fb_exc_energy, /* i : full band excitation energy */ - const Word16 ratio, /* i : energy ratio */ - const Word16 L_frame, /* i : ACELP frame length */ - const Word16 bfi, /* i : fec flag */ - Word16 *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ - Word32 bpf_memory[][4], /* i/o: memory for elliptic bpf 48k */ - Word16 bpf_memory_Q[], - Word16 Qout -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - , - Word16 isIVAS -#endif -) -{ - Word16 i, j; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 excitation_in_interp3_buffer[L_FRAME48k + 4]; - Word16 *excitation_in_interp3 = &excitation_in_interp3_buffer[0] + 4; -#else - Word16 excitation_in_interp3[L_FRAME48k]; -#endif - Word16 tmp[L_FRAME48k]; - Word32 temp1; - Word32 ratio2; - Word32 L_tmp; - Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; - - /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ - j = 0; - /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ - FOR( i = 0; i < L_FRAME48k; i += 3 ) - { - excitation_in_interp3[i] = mult( excitation_in[j], 24576 ); /* Q(Q_fb_exc+13-15 = Q_fb_exc-2) */ - move16(); - excitation_in_interp3[i + 1] = 0; - move16(); - excitation_in_interp3[i + 2] = 0; - move16(); - j++; - } - exp_tmp = sub( Q_fb_exc, 2 ); - - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - /* for 16kHz ACELP core */ - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 1, // IsUpsampled3 -#endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx - - ); - } - ELSE - { - /* for 12.8kHz ACELP core */ - elliptic_bpf_48k_generic_fx( -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - isIVAS, -#endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - 1, // IsUpsampled3 -#endif - excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); - } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A.1" );*/ - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART A" )*/ - - push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" ); - temp1 = sum2_fx_mod( tmp, L_FRAME48k ); - L_tmp = L_max( 1, fb_exc_energy ); /*Q(2*Q_fb_exc + 1)*/ - exp = norm_l( L_tmp ); - tmp3 = extract_h( L_shl( L_tmp, exp ) ); - tmp1 = sub( add( Q_fb_exc, Q_fb_exc ), 8 ); /* 1-9*/ - exp = sub( sub( 31, tmp1 ), exp ); - - exp2 = norm_l( temp1 ); - tmp2 = extract_h( L_shl( temp1, exp2 ) ); - exp2 = sub( sub( 31, sub( shl( exp_tmp, 1 ), 8 ) ), exp2 ); /* in Q15 (temp1 in Q9)*/ - - exp = sub( exp2, exp ); /* Denormalize and substract */ - IF( GT_16( tmp2, tmp3 ) ) - { - tmp2 = shr( tmp2, 1 ); - exp = add( exp, 1 ); - } - IF( 0 != tmp3 ) - { - tmp3 = div_s( tmp2, tmp3 ); - L_tmp = L_deposit_h( tmp3 ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ - ratio2 = Mult_32_16( L_tmp, ratio ); /*Q(31-exp+0-15 = 16-exp)*/ - } - ELSE - { - ratio2 = 0; - } - - IF( !bfi ) - { - *prev_fbbwe_ratio = ratio; - move16(); - } - ELSE - { - /**prev_fbbwe_ratio = ratio*0.5f;*/ - *prev_fbbwe_ratio = shr( ratio, 1 ); - move16(); - } - tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - IF( L_tmp < 0 ) - { - output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ - move16(); - } - ELSE - { - output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ - move16(); - } - } - pop_wmops(); /*push_wmops( "SYNTHESISE_FB_HIGH_BAND PART B" );*/ - return; -} - -/*-------------------------------------------------------------------* - * Estimate_mix_factors_fx() * - * * - * Estimate mix factors for SHB excitation generation * - *-------------------------------------------------------------------*/ -void Estimate_mix_factors_fx( - const Word16 *shb_res, /* i : SHB LP residual in Q = Q_shb */ - const Word16 Q_shb, - const Word16 *exc16kWhtnd, /* i : SHB transformed low band excitation Q_bwe_exc */ - const Word16 Q_bwe_exc, - const Word16 *White_exc16k_frac, /* i : Modulated envelope shaped white noise Q_frac */ - const Word16 Q_frac, - const Word32 pow1, /* i : SHB exc. power for normalization in Q_pow1 */ - const Word16 Q_pow1, - const Word32 pow22, /* i : White noise excitation for normalization in Q_pow22 */ - const Word16 Q_pow22, - Word16 *vf_modified, /* o : Estimated voice factors */ - Word16 *vf_ind /* o : voice factors VQ index */ -) -{ - Word16 shb_res_local[L_FRAME16k], WN_exc_local[L_FRAME16k]; - Word32 pow3, temp_p1_p2, temp_p1_p3; - Word16 temp_numer1[L_FRAME16k], temp_numer2[L_FRAME16k]; - Word16 i, length; - Word16 exp1, exp2, expa, expb, fraca, fracb, scale, num_flag, den_flag; - Word16 tmp, tmp1, sc1, sc2; - Word32 L_tmp1, L_tmp2; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - Copy( shb_res, shb_res_local, L_FRAME16k ); - Copy( White_exc16k_frac, WN_exc_local, L_FRAME16k ); - /* WN_exc_local in (Q_frac) */ - - pow3 = Dot_product( shb_res_local, shb_res_local, L_FRAME16k ); /* (2*Q_shb+1) */ - - pow3 = L_add( pow3, L_shl( 21475l /*0.00001f in Q31*/, 2 * Q_shb + 1 - 31 ) ); /* (2*Q_shb+1) */ - if ( pow3 == 0 ) - { - pow3 = 1; - move32(); - } - - /* temp_p1_p2 = (float)sqrt(pow1/pow2); */ - temp_p1_p2 = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp1 ); /* temp_p1_p3 in (Q31+exp1) */ - - /* temp_p1_p3 = (float)sqrt(pow1/pow3); */ - temp_p1_p3 = root_a_over_b_fx( pow1, Q_pow1, pow3, ( 2 * Q_shb + 1 ), &exp2 ); /* temp_p1_p3 in (Q31+exp2) */ - - - sc1 = sub( Q_bwe_exc, sub( Q_frac, exp1 ) ); - sc2 = sub( Q_bwe_exc, sub( Q_shb, exp2 ) ); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp1 = Mult_32_16( temp_p1_p2, WN_exc_local[i] ); /* (Q_frac - exp1) +16 */ - WN_exc_local[i] = round_fx( L_tmp1 ); - move16(); - L_tmp2 = Mult_32_16( temp_p1_p3, shb_res_local[i] ); /* (Q_shb - exp2) +16 */ - shb_res_local[i] = round_fx( L_tmp2 ); - move16(); - /* temp_numer1[i] = sub(shb_res_local[i], WN_exc_local[i]); */ - temp_numer1[i] = round_fx_sat( L_sub_sat( L_shl_sat( L_tmp2, sc2 ), L_shl_sat( L_tmp1, sc1 ) ) ); - move16(); - /* (Q_bwe_exc) */ - - /* temp_numer2[i] = sub(exc16kWhtnd[i], WN_exc_local[i]); */ - temp_numer2[i] = sub_sat( exc16kWhtnd[i], round_fx_sat( L_shl_sat( L_tmp1, sc1 ) ) ); - move16(); - /* (Q_bwe_exc) */ - } - - - length = L_FRAME16k; - move16(); - temp_p1_p2 = Dot_product( temp_numer1, temp_numer2, length ); /* 2*(Q_bwe_exc)+1 */ - temp_p1_p3 = Dot_product( temp_numer2, temp_numer2, length ); /* 2*(Q_bwe_exc)+1 */ - - /* vf_modified[i] = min( max_val( (temp_p1_p2 / temp_p1_p3), 0.1f), 0.99f); */ - /* tmp = (temp_p1_p2 / temp_p1_p3); */ - IF( temp_p1_p3 > 0 ) - { - expa = norm_l( temp_p1_p3 ); - fraca = extract_h( L_shl( temp_p1_p3, expa ) ); - expa = sub( 30, expa ); - - expb = norm_l( temp_p1_p2 ); - fracb = round_fx_o( L_shl_o( temp_p1_p2, expb, &Overflow ), &Overflow ); - expb = sub( 30, expb ); - - num_flag = 0; - move16(); - IF( fraca < 0 ) - { - num_flag = 1; - move16(); - fraca = negate( fraca ); - } - - den_flag = 0; - move16(); - IF( fracb < 0 ) - { - den_flag = 1; - move16(); - fracb = negate( fracb ); - } - - scale = shr( sub( fraca, fracb ), 15 ); - fracb = shl( fracb, scale ); - expb = sub( expb, scale ); - - tmp = div_s( fracb, fraca ); - exp1 = sub( expb, expa ); - tmp = shl_sat( tmp, exp1 ); - if ( NE_16( num_flag, den_flag ) ) - { - tmp = negate( tmp ); - } - } - ELSE - { - tmp = 0; - move16(); - } - - vf_modified[0] = s_min( s_max( tmp, 3277 /* 0.1f in Q15*/ ), 32440 /* 0.99f in Q15 */ ); - move16(); - - *vf_ind = usquant_fx( vf_modified[0], &tmp1, 4096 /* 0.125 in Q15 */, 2048 /* 0.125 in Q14 */, shl( 1, NUM_BITS_SHB_VF ) ); - move16(); - - vf_modified[0] = tmp1; - move16(); - vf_modified[1] = tmp1; - move16(); - vf_modified[2] = tmp1; - move16(); - vf_modified[3] = tmp1; - move16(); - vf_modified[4] = tmp1; - move16(); - - /* vf_modified in Q15 */ - - return; -} -#ifdef ADD_IVAS_TBE_CODE -/*-------------------------------------------------------------------* - * tbe_celp_exc() * - * * - * Prepare adaptive part of TBE excitation * - *-------------------------------------------------------------------*/ - -void tbe_celp_exc( - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - float *bwe_exc, /* i/o: BWE excitation */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - float *error, /* i/o: error */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -) -{ - int16_t i, offset; - - if ( element_mode == IVAS_CPE_TD && idchan == 1 && !tdm_LRTD_flag ) - { - return; - } - - if ( L_frame == L_FRAME ) - { - offset = tbe_celp_exc_offset( T0, T0_frac ); - - for ( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) - { - bwe_exc[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc[i + i_subfr * HIBND_ACB_L_FAC - offset + (int16_t) *error]; - } - *error += (float) offset - (float) T0 * HIBND_ACB_L_FAC - 0.25f * HIBND_ACB_L_FAC * (float) T0_frac; - } - else - { - offset = T0 * 2 + (int16_t) ( (float) T0_frac * 0.5f + 4 + 0.5f ) - 4; - for ( i = 0; i < L_subfr * 2; i++ ) - { - bwe_exc[i + i_subfr * 2] = bwe_exc[i + i_subfr * 2 - offset + (int16_t) *error]; - } - *error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac; - } - - return; -} -#endif -/*======================================================================================*/ -/* FUNCTION : prep_tbe_exc_fx() */ -/*--------------------------------------------------------------------------------------*/ -/* PURPOSE : Prepare TBE excitation */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16) L_frame_fx : length of the frame */ -/* _ (Word16) i_subfr_fx : subframe index */ -/* _ (Word16) gain_pit_fx : Pitch gain (14) */ -/* _ (Word32) gain_code_fx : algebraic codebook gain (Q(16+Q_exc)) */ -/* _ (Word16*[]) code_fx : algebraic excitation (Q9) */ -/* _ (Word16) voice_fac_fx : voicing factor (Q15) */ -/* _ (Word16) gain_preQ_fx : prequantizer excitation gain */ -/* _ (Word16[]) code_preQ_fx : prequantizer excitation */ -/*--------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16*[]) voice_factors_fx : TBE voicing factor (Q15) */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _ (Word16[]) bwe_exc_fx : excitation for TBE (Q_exc) */ -/*--------------------------------------------------------------------------------------*/ - -/* _ None */ -/*--------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*======================================================================================*/ - -void prep_tbe_exc_fx( - const Word16 L_frame_fx, /* i : length of the frame */ -#ifdef ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif - const Word16 i_subfr_fx, /* i : subframe index */ - const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ - const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ - const Word16 code_fx[], /* i : algebraic excitation Q9*/ - const Word16 voice_fac_fx, /* i : voicing factor Q15*/ - Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ - Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ - const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ - const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - Word16 T0, /* i : integer pitch variables Q0 */ - Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - Word32 core_brate -#ifdef ADD_IVAS_TBE_CODE - , /* i : core bitrate */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif -) -{ - Word16 i; - Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; - Word16 tmp_code_preInt_fx[L_SUBFR]; - Word16 gain_code16 = 0; - move16(); - Word16 tmp /*, tmp1, tmp2*/; - /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ - Word16 pitch; - - Word32 L_tmp, Ltemp1, Ltemp2; - Word32 tempQ31; - Word16 tempQ15; -#ifndef ADD_IVAS_TBE_CODE - Word16 L_subfr = L_SUBFR; - move16(); -#endif -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - /**voice_factors = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac; - = VF_0th_PARAM + voice_fac * (VF_1st_PARAM + VF_2nd_PARAM * voice_fac ) - *voice_factors = min( max_val(0.0f, *voice_factors), 1.0f); */ - tempQ31 = L_deposit_h( VF_1st_PARAM_FX ); - tempQ15 = mac_r( tempQ31, VF_2nd_PARAM_FX, voice_fac_fx ); - tempQ31 = L_deposit_h( VF_0th_PARAM_FX ); - *voice_factors_fx = mac_r( tempQ31, voice_fac_fx, tempQ15 ); - move16(); - tmp = MAX_16; - move16(); - - pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ - - test(); - test(); - IF( ( ( EQ_16( coder_type, VOICED ) ) || ( GT_16( pitch, 14784 /* 115.5 in Q7 */ ) ) ) && ( GT_32( core_brate, ACELP_8k00 ) ) ) - { - tmp = MAX_16; - move16(); - *voice_factors_fx = mult_r( *voice_factors_fx, tmp ); - move16(); - } - - *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); - move16(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) - { - IF( flag_TD_BWE && i_subfr == 0 ) - { - set16_fx( bwe_exc, 0, L_FRAME32k ); - } - return; - } - -#endif - IF( EQ_16( L_frame_fx, L_FRAME ) ) - { - interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ - gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ - FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) - { - L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ - L_tmp = L_shl_sat( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ - L_tmp = L_mac_sat( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ - move16(); - } - } - ELSE - { - IF( gain_preQ_fx != 0 ) - { - FOR( i = 0; i < L_subfr; i++ ) - { - /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ - - Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ - Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, 4 ) /*Q_exc+16-13*/, &Overflow ); /*Q_exc+16 */ - - tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ - move16(); - } - } - ELSE - { - FOR( i = 0; i < L_subfr; i++ ) - { - /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ - tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ - move16(); - } - } - - interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ - FOR( i = 0; i < L_subfr * 2; i++ ) - { - L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * 2] ); /*Q14+Q_exc+1 */ - tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ - bwe_exc_fx[i + i_subfr_fx * 2] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ - move16(); - } - } - - return; -} - -/*======================================================================================*/ -/* FUNCTION : prep_tbe_exc_ivas_fx() */ -/*--------------------------------------------------------------------------------------*/ -/* PURPOSE : Prepare TBE excitation */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16) L_frame_fx : length of the frame */ -/* _ (Word16) i_subfr_fx : subframe index */ -/* _ (Word16) gain_pit_fx : Pitch gain (14) */ -/* _ (Word32) gain_code_fx : algebraic codebook gain (Q(16+Q_exc)) */ -/* _ (Word16*[]) code_fx : algebraic excitation (Q9) */ -/* _ (Word16) voice_fac_fx : voicing factor (Q15) */ -/* _ (Word16) gain_preQ_fx : prequantizer excitation gain */ -/* _ (Word16[]) code_preQ_fx : prequantizer excitation */ -/*--------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16*[]) voice_factors_fx : TBE voicing factor (Q15) */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _ (Word16[]) bwe_exc_fx : excitation for TBE (Q_exc) */ -/*--------------------------------------------------------------------------------------*/ - -/* _ None */ -/*--------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*======================================================================================*/ - -void prep_tbe_exc_ivas_fx( - const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif - const Word16 i_subfr_fx, /* i : subframe index */ - const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ - const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ - const Word16 code_fx[], /* i : algebraic excitation Q9*/ - const Word16 voice_fac_fx, /* i : voicing factor Q15*/ - Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ - Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ - const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ - const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - Word16 T0, /* i : integer pitch variables Q0 */ - Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE - , /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif -) -{ - Word16 i; - Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; - Word16 tmp_code_preInt_fx[L_SUBFR]; - Word16 gain_code16 = 0; - move16(); - Word16 tmp /*, tmp1, tmp2*/; - /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ - Word16 pitch; - - Word32 L_tmp, Ltemp1, Ltemp2; - Word32 tempQ31; - Word16 tempQ15; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - /**voice_factors = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac; - = VF_0th_PARAM + voice_fac * (VF_1st_PARAM + VF_2nd_PARAM * voice_fac ) - *voice_factors = min( max_val(0.0f, *voice_factors), 1.0f); */ - tempQ31 = L_deposit_h( VF_1st_PARAM_FX ); - tempQ15 = mac_r( tempQ31, VF_2nd_PARAM_FX, voice_fac_fx ); - tempQ31 = L_deposit_h( VF_0th_PARAM_FX ); - *voice_factors_fx = mac_r( tempQ31, voice_fac_fx, tempQ15 ); - move16(); - - tmp = MAX_16; - move16(); - - pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ - - test(); - test(); - IF( ( ( EQ_16( coder_type, VOICED ) ) || ( GT_16( pitch, 14784 ) ) ) && ( GT_32( core_brate, ACELP_8k00 ) ) ) - { - tmp = MAX_16; - move16(); - *voice_factors_fx = mult_r( *voice_factors_fx, tmp ); - move16(); - } - - *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); - move16(); -#if 1 // def ADD_IVAS_TBE_CODE - test(); - test(); - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) - { - test(); - IF( flag_TD_BWE && i_subfr_fx == 0 ) - { - set16_fx( bwe_exc_fx, 0, L_FRAME32k ); - } - return; - } - -#endif - IF( EQ_16( L_frame_fx, L_FRAME ) ) - { - interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ - gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ - FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) - { - L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ - L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ - L_tmp = L_mac_o( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC], &Overflow ); /*Q15+Q_exc */ - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ - move16(); - } - } - ELSE - { - Word16 shift = 4; - move16(); - IF( gain_preQ_fx != 0 ) - { - FOR( i = 0; i < L_subfr; i++ ) - { - /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ - - Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ - Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, shift ) /*Q_exc+ 2 + 6 (or) 10 - 13*/, &Overflow ); /*Q_exc+16 */ - - tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ - move16(); - } - } - ELSE - { - FOR( i = 0; i < L_subfr; i++ ) - { - /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ - tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ - move16(); - } - } - - interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ - FOR( i = 0; i < shl( L_subfr, 1 ); i++ ) - { - L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + shl( i_subfr_fx, 1 )] ); /*Q14+Q_exc+1 */ - tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ - bwe_exc_fx[i + shl( i_subfr_fx, 1 )] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ - move16(); - } - } - - return; -} - -/*=============================================================================*/ -/* FUNCTION : void swb_formant_fac_fx ( ) */ -/*------------------------------------------------------------------------------*/ -/* PURPOSE : * Find strength of adaptive formant postfilter using tilt */ -/* of the high band. The 2nd lpc coefficient is used as a tilt approximation. */ -/*------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* const Word16 lpc_shb2 : 2nd HB LPC coefficient Q12 */ -/*------------------------------------------------------------------------------*/ -/*INPUT/OUTPUT ARGUMENTS : */ -/* Word16 *tilt_mem Q12 */ -/* OUTPUT ARGUMENTS : */ -/*------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* formant_fac :Formant filter strength [0,1] Q15 */ -/*------------------------------------------------------------------------------*/ -/* CALLED FROM : */ -/*==============================================================================*/ - -Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ - const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ - Word16 *tilt_mem /* i/o: Tilt smoothing memory (Q12) */ -) -{ - Word16 formant_fac; - Word16 tmp; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - /* Smoothen tilt value */ - /* tmp = 0.5f * (float)fabs(lpc_shb2) + 0.5f * *tilt_mem; */ - tmp = mult_r( 16384, abs_s( lpc_shb2 ) ); - tmp = add( tmp, mult_r( 16384, *tilt_mem ) ); /* Q12 */ - *tilt_mem = tmp; - move16(); /*Q12 */ - /* Map to PF strength */ - /* formant_fac = (tmp - SWB_TILT_LOW)*SWB_TILT_DELTA; */ - tmp = sub( tmp, SWB_TILT_LOW_FX ); /* Q12 */ - formant_fac = mult_r( tmp, SWB_TILT_DELTA_FX ); /* Q12 */ - - - IF( GT_16( formant_fac, 4096 /* 1 in Q12 */ ) ) - { - formant_fac = 4096; /* 1 in Q12 */ - move16(); - } - ELSE IF( formant_fac < 0 ) - { - formant_fac = 0; - move16(); - } - /* now formant_fac in Q12 */ - - /* formant_fac = 1.0f - 0.5f*formant_fac */ - tmp = mult_r( 16384, formant_fac ); /* 0.5 in Q15 */ - formant_fac = shl_o( sub( 4096 /* 1 in Q12 */, tmp ), 3, &Overflow ); - return formant_fac; /*Q15 */ -} - - -void wb_tbe_extras_reset_fx( - Word16 mem_genSHBexc_filt_down_wb2[], - Word16 mem_genSHBexc_filt_down_wb3[] ) -{ - set16_fx( mem_genSHBexc_filt_down_wb2, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - set16_fx( mem_genSHBexc_filt_down_wb3, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - - return; -} - -/*-------------------------------------------------------------------* - * get_tbe_bits() * - * * - * Determine TBE bit consumption per frame from bitrate * - *-------------------------------------------------------------------*/ - - -Word16 get_tbe_bits_fx( - const Word32 total_brate, /* o : TBE bit consumption per frame */ - const Word16 bwidth, /* i : overall bitrate */ - const Word16 rf_mode /* i : bandwidht mode */ -) -{ - Word16 i, bits = 0; - - IF( EQ_16( rf_mode, 1 ) ) - { - /* TBE bits for core, primary frame */ - test(); - test(); - IF( ( EQ_16( bwidth, WB ) ) && ( EQ_32( total_brate, ACELP_13k20 ) ) ) - { - /* Gain frame: 4, Gain shapes: 0, and LSFs: 2 */ - bits = NUM_BITS_SHB_FrameGain_LBR_WB + NUM_BITS_LBR_WB_LSF; - move16(); - } - ELSE IF( ( EQ_16( bwidth, SWB ) ) && ( EQ_32( total_brate, ACELP_13k20 ) ) ) - { - /* Gain frame: 5, Gain shapes: 5, and lowrate LSFs: 8 */ - bits = NUM_BITS_SHB_FRAMEGAIN + NUM_BITS_SHB_SUBGAINS + 8; - move16(); - } - } - ELSE - { - test(); - test(); - IF( ( EQ_16( bwidth, WB ) ) && ( EQ_32( total_brate, ACELP_9k60 ) ) ) - { - bits = NUM_BITS_LBR_WB_LSF + NUM_BITS_SHB_FrameGain_LBR_WB; - move16(); - } - ELSE IF( ( EQ_16( bwidth, SWB ) ) || ( EQ_16( bwidth, FB ) ) ) - { - test(); - IF( EQ_32( total_brate, ACELP_9k60 ) ) - { - bits = NUM_BITS_SHB_FRAMEGAIN + NUM_BITS_SHB_SUBGAINS + 8; - move16(); - } - ELSE IF( ( GE_32( total_brate, ACELP_13k20 ) ) && ( LE_32( total_brate, ACELP_32k ) ) ) - { - bits = NUM_BITS_SHB_SUBGAINS + NUM_BITS_SHB_FRAMEGAIN + NUM_LSF_GRID_BITS + MIRROR_POINT_BITS; - move16(); - - FOR( i = 0; i < NUM_Q_LSF; i++ ) - { - bits = add( bits, lsf_q_num_bits[i] ); - } - } - - if ( GE_32( total_brate, ACELP_24k40 ) ) - { - bits = add( bits, NUM_BITS_SHB_ENER_SF + NUM_BITS_SHB_VF + NUM_BITS_SHB_RES_GS * NB_SUBFR16k ); - } - - test(); - test(); - if ( EQ_16( bwidth, SWB ) && ( EQ_32( total_brate, ACELP_16k40 ) || EQ_32( total_brate, ACELP_24k40 ) ) ) - { - bits = add( bits, BITS_TEC + BITS_TFA ); - } - - if ( EQ_16( bwidth, FB ) ) - { - /* full band slope */ - bits = add( bits, 4 ); - } - } - } - - return bits; -} -- GitLab From 0f4c1288bb56e06eb5c67e125586e3aaa8d8cbcb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:18:17 +0200 Subject: [PATCH 1034/1221] deactivate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW to test old bpf --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 3ec71d78b..d235b80b9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -95,7 +95,7 @@ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ -- GitLab From c445baf9df47a0e5cfeb4adcd429b8f6ad3e63ac Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:42:26 +0200 Subject: [PATCH 1035/1221] deactivate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index d235b80b9..430b8f22c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -94,7 +94,7 @@ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -- GitLab From 3a53d1a355f2e308b3b9eeb9ed81cd5eaf4f7bd9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:50:50 +0200 Subject: [PATCH 1036/1221] fix conflict --- lib_com/options.h | 104 +--------------------------------------------- 1 file changed, 2 insertions(+), 102 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 550edc5dd..44033b962 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -1,4 +1,3 @@ -<<<<<<< HEAD /****************************************************************************************************** (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, @@ -73,11 +72,6 @@ #define FIX_1378_ACELP_OUT_OF_BOUNDS /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ - -#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ -#define MERGE_REQ - - //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ @@ -90,10 +84,8 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -#define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ + +#define TEST_HR //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ @@ -101,97 +93,5 @@ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 - -#endif -======= -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#ifndef OPTIONS_H -#define OPTIONS_H - -/* clang-format off */ - -/* ################### Start DEBUGGING switches ######################## */ - -/*#define DEBUGGING*/ /* Allows debugging message to be printed out during runtime */ -#ifdef DEBUGGING -#define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ -#define DEBUG_MODE_INFO_TWEAK /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */ -#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ -/*#define DEBUG_FORCE_DIR*/ /* Force modes/parameters by reading from external binary files */ -/*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ -#define SUPPORT_FORCE_TCX10_TCX20 /* VA: Enable -force tcx10|tcx20 command-line option */ -#endif - -#define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ - -/*#define WMOPS*/ /* Activate complexity and memory counters */ -#ifdef WMOPS -/*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ -/*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ -/*#define WMOPS_WC_FRAME_ANALYSIS*/ /* Output detailed complexity analysis for the worst-case frame */ -/*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ -#endif - -/* #################### End DEBUGGING switches ############################ */ - -#ifndef BASOP_NOGLOB_DEV_USE_GLOBALS -#define BASOP_NOGLOB_DECLARE_LOCAL #endif -#define FIX_867_CLDFB_NRG_SCALE - -#define FIX_1378_ACELP_OUT_OF_BOUNDS - -/* Note: each compile switch (FIX_1101_...) is independent from the other ones */ -//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ -#define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ -#define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ -#define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ -/* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ -//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version. Obsoleted by MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ -#define HARM_PUSH_BIT -#define HARM_ENC_INIT -//#define HARM_SCE_INIT -#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ -#define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ - -#define TEST_HR - -#endif ->>>>>>> main -- GitLab From ba3a2b47c50e49ca420a2cc663b771826a3b89dc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 11:56:28 +0200 Subject: [PATCH 1037/1221] delete func1 code --- lib_com/options.h | 1 - lib_com/swb_tbe_com_fx.c | 187 --------------------------------------- 2 files changed, 188 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 44033b962..11cb842d2 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -92,6 +92,5 @@ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e6d579269..41c06b920 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6687,181 +6687,6 @@ void wb_tbe_extras_reset_synth_fx( return; } -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 -inline static void elliptic_bpf_48k_generic_func1( Word32 *input_fx, Word32 *L_tmp, const Word16 full_band_bpf_fx[][5], Word16 IsUpsampled3, Word32 *L_tmpMax ) -{ - Word32 L_tmpX; - Word16 i; - Word32 L_tmpMax2 = *L_tmpMax; - Word32 L_tmpAbs; - move32(); - IF( !IsUpsampled3 ) - { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#else - FOR( i = 0; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - } -#endif - } /*IsUpsampled3*/ - ELSE - { /*IsUpsampled3*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - if ( L_tmpMax > 0 ) - { - L_tmpAbs = L_abs( L_tmp[i] ); - } - if ( L_tmpMax > 0 ) - { - L_tmpMax2 = L_max( L_tmpMax2, L_tmpAbs ); - } - i++; - } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ - *L_tmpMax = L_tmpMax2; - move32(); -} -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ - /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -6926,9 +6751,6 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( input_fx, L_tmp, &full_band_bpf_fx[0], IsUpsampled3, 0 ); -#else IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -7028,7 +6850,6 @@ void elliptic_bpf_48k_generic_fx( } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ } /*IsUpsampled3*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7103,9 +6924,6 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( L_tmp, L_tmp2, &full_band_bpf_fx[1], 0, &L_tmpMax ); -#else #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7138,7 +6956,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7224,9 +7041,6 @@ void elliptic_bpf_48k_generic_fx( } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1 /*use subfunc*/ - elliptic_bpf_48k_generic_func1( L_tmp2, L_output, &full_band_bpf_fx[2], 0, &L_tmpMax ); -#else #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7262,7 +7076,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_func1*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From f4f3bcaabe330cff75073d30cbff5880788c8565 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 12:17:00 +0200 Subject: [PATCH 1038/1221] change else path in FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic to old code, delete FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW and change to FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - deactivate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic --- lib_com/options.h | 1 - lib_com/prot_fx.h | 6 +- lib_com/swb_tbe_com_fx.c | 412 +++++++-------------------------------- lib_enc/swb_tbe_enc_fx.c | 12 +- 4 files changed, 77 insertions(+), 354 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 11cb842d2..e01818a87 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -88,7 +88,6 @@ #define TEST_HR //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW /*activates new, spaghetticode version of elliptic_bpf_48k_generic. if inactive, only old code with no opts is active*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 07ef34533..33ac952cc 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3264,17 +3264,13 @@ void interp_code_4over2_fx( void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_lsyn_filt_dwn_shb[], Word16 state_32and48k_WB_upsample[], Word16 state_resamp_HB[] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word16 isIVAS, #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ -#else - const Word16 input_fx[], /* i : input signal Q_input_fx*/ -#endif Word16 *Q_input_fx, Word16 output_fx[], /* o : output signal */ Word32 memory_fx[][4], /* i/o: 4 arrays of 4 for memory memory_fx_Q */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 41c06b920..010ca2e99 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6693,7 +6693,7 @@ void wb_tbe_extras_reset_synth_fx( * 18th-order elliptic bandpass filter at 14.0 to 20 kHz sampled at 48 kHz * Implemented as 3 fourth order sections cascaded. *-------------------------------------------------------------------*/ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW + void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 Word16 isIVAS, @@ -6735,10 +6735,6 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic memory_fx0 = extract_l( memory_fx2[0][i] ); input_fx[i - 4] = shl_sat( memory_fx0, sub( *Q_input_fx, memory_fx_Q[0] ) ); -#else - memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); - memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); -#endif L_tmp[i - 4] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); L_tmp2[i - 4] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); // memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); @@ -6747,6 +6743,19 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); +#else + memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); + memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); + memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); + memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); + memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); +#endif + } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -6852,51 +6861,48 @@ void elliptic_bpf_48k_generic_fx( } /*IsUpsampled3*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[3 - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); - - FOR( i = 4; i < L_FRAME48k; i++ ) { L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -7001,19 +7007,19 @@ void elliptic_bpf_48k_generic_fx( L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } #endif @@ -7031,6 +7037,7 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic FOR( j = 0; j < 4; j++ ) { L_tmp2[j - 4] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); @@ -7039,6 +7046,16 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); } +#else + FOR( j = 0; j < 4; j++ ) + { + memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); + memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); + move32(); + move32(); + move32(); + } +#endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -7183,285 +7200,6 @@ void elliptic_bpf_48k_generic_fx( return; } - -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW*/ -void elliptic_bpf_48k_generic_fx( - const Word16 input_fx[], /* i : input signal Q_input_fx*/ - Word16 *Q_input_fx, - Word16 output_fx[], /* o : output signal memory_fx_Q */ - Word32 memory_fx2[][4], /* i/o: 4 arrays of 4 for memory */ - Word16 memory_fx_Q[], - const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ -) -{ - Word16 i, j; - Word16 memory_fx0[4][4], memory_fx[4][4], Q_temp, Q_temp2; - Word32 L_tmp[L_FRAME48k], L_tmp2[L_FRAME48k], L_output[L_FRAME48k], L_tmpX, memory2_fx[4][4], L_tmpMax; - Word32 memory2_fx_2[4], memory2_fx_3[4]; - - FOR( i = 0; i < 4; i++ ) - { - memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); - memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl_sat( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - move32(); - move32(); - } - - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - } - - memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; - memory_fx2[0][1] = input_fx[L_FRAME48k - 3]; - memory_fx2[0][2] = input_fx[L_FRAME48k - 2]; - memory_fx2[0][3] = input_fx[L_FRAME48k - 1]; - move32(); - move32(); - move32(); - move32(); - move32(); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); - L_tmpMax = L_abs( L_tmp2[0] ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); - } - - Q_temp = norm_l( L_tmpMax ); - Q_temp = sub( Q_temp, 4 ); - Scale_sig32( L_tmp2, 960, Q_temp ); - - memory_fx2[1][0] = L_tmp[L_FRAME48k - 4]; - memory_fx2[1][1] = L_tmp[L_FRAME48k - 3]; - memory_fx2[1][2] = L_tmp[L_FRAME48k - 2]; - memory_fx2[1][3] = L_tmp[L_FRAME48k - 1]; - move32(); - move32(); - move32(); - move32(); - move32(); - FOR( j = 0; j < 4; j++ ) - { - memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); - move32(); - move32(); - move32(); - } - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); - - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; - memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; - memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; - memory_fx2[2][3] = L_tmp2[L_FRAME48k - 1]; - memory_fx2[3][0] = L_output[L_FRAME48k - 4]; - memory_fx2[3][1] = L_output[L_FRAME48k - 3]; - memory_fx2[3][2] = L_output[L_FRAME48k - 2]; - memory_fx2[3][3] = L_output[L_FRAME48k - 1]; - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - memory_fx_Q[0] = *Q_input_fx; - memory_fx_Q[1] = add( *Q_input_fx, 11 ); - memory_fx_Q[2] = add( add( *Q_input_fx, 6 ), Q_temp ); - memory_fx_Q[3] = add( add( *Q_input_fx, 1 ), Q_temp ); - move16(); - move16(); - move16(); - move16(); - Q_temp2 = norm_l( L_tmpMax ); - Scale_sig32( L_output, 960, Q_temp2 ); - FOR( i = 0; i < 960; i++ ) - { - output_fx[i] = extract_h( L_output[i] ); - move16(); - } - *Q_input_fx = sub( add( add( *Q_input_fx, Q_temp ), Q_temp2 ), 15 ); - move16(); /* BASOP_NOGLOB */ - - return; -} -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW*/ - /*-------------------------------------------------------------------* * synthesise_fb_high_band() * @@ -7526,14 +7264,12 @@ void synthesise_fb_high_band_fx( IF( EQ_16( L_frame, L_FRAME16k ) ) { /* for 16kHz ACELP core */ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 -#endif excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx ); @@ -7544,14 +7280,12 @@ void synthesise_fb_high_band_fx( ELSE { /* for 12.8kHz ACELP core */ -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 1, // IsUpsampled3 -#endif excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); #else elliptic_bpf_48k_generic_fx( excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 648387bbf..7ad3b2013 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7330,7 +7330,7 @@ void fb_tbe_enc_fx( Copy_Scale_sig( new_input, input_fhb, L_FRAME48k, exp_temp ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS @@ -7339,9 +7339,7 @@ void fb_tbe_enc_fx( 0, // isIVAS #endif #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -#endif input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else elliptic_bpf_48k_generic_fx( input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7474,14 +7472,12 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -#endif input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7489,14 +7485,12 @@ void fb_tbe_enc_ivas_fx( } ELSE { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_ACTIVATENEW +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 1, // isIVAS #endif -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic 0, // IsUpsampled3 -#endif input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else elliptic_bpf_48k_generic_fx( input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -- GitLab From 44d3497339a6203e470bfde23dc795b14f8f6705 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 12:22:42 +0200 Subject: [PATCH 1039/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 010ca2e99..537881fd1 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6755,7 +6755,6 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); #endif - } #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic @@ -6793,7 +6792,7 @@ void elliptic_bpf_48k_generic_fx( move32(); } #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 @@ -6858,7 +6857,7 @@ void elliptic_bpf_48k_generic_fx( i++; } #endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ -- GitLab From 69d2069538046b46e9fa43c536d3c4697230e206 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 12:43:21 +0200 Subject: [PATCH 1040/1221] activate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index e01818a87..ec61fece6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -87,7 +87,7 @@ #define TEST_HR -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ -- GitLab From 2700c956fbad0ad46d7e3f2fb5e471d2fd92f912 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 15 Apr 2025 12:36:27 +0530 Subject: [PATCH 1041/1221] Fixes for crashes observed on LTV pipeline --- lib_enc/igf_enc.c | 8 +-- lib_enc/igf_enc_fx.c | 97 +++++++++++++++++++++++++++++++ lib_enc/prot_fx_enc.h | 7 +++ lib_enc/speech_music_classif_fx.c | 19 +++++- 4 files changed, 125 insertions(+), 6 deletions(-) diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index bfb4a7423..9769d83b6 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1171,13 +1171,13 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); // tmp_tb = IGF_getSFM_ivas(pPowerSpectrum, swb_offset[sfb], swb_offset[sfb + 1]) / IGF_getCrest_ivas(pPowerSpectrum, swb_offset[sfb], swb_offset[sfb + 1]); - sfm = IGF_getSFM( &sfm_exp, pPowerSpectrum_fx, &pPowerSpectrum_e, swb_offset[sfb], swb_offset[sfb + 1] ); + sfm = IGF_getSFM_ivas_fx( &sfm_exp, pPowerSpectrum_fx, &pPowerSpectrum_e, swb_offset[sfb], swb_offset[sfb + 1] ); crest = IGF_getCrest( &crest_exp, pPowerSpectrum_fx, pPowerSpectrum_e, swb_offset[sfb], swb_offset[sfb + 1] ); tmp_tb_fx = BASOP_Util_Divide1616_Scale( sfm, crest, &tmp_e ); tmp_tb_e = add( tmp_e, sub( sfm_exp, crest_exp ) ); /*stores the resultant exponent for tmp_tb_fx*/ // tmp_sb = IGF_getSFM_ivas(tileSrcSpec, 0, strt_cpy - tmp) / IGF_getCrest_ivas(tileSrcSpec, 0, strt_cpy - tmp); - sfm = IGF_getSFM( &sfm_exp, tileSrcSpec_fx, &tileSrcSpec_e, 0, sub( strt_cpy, tmp ) ); + sfm = IGF_getSFM_ivas_fx( &sfm_exp, tileSrcSpec_fx, &tileSrcSpec_e, 0, sub( strt_cpy, tmp ) ); crest = IGF_getCrest( &crest_exp, tileSrcSpec_fx, tileSrcSpec_e, 0, sub( strt_cpy, tmp ) ); tmp_sb_fx = BASOP_Util_Divide1616_Scale( sfm, crest, &tmp_e ); tmp_sb_e = add( tmp_e, sub( sfm_exp, crest_exp ) ); /*stores the resultant exponent for tmp_sb_fx*/ @@ -1322,7 +1322,7 @@ static void IGF_CalculateStereoEnvelope_fx( { Word16 shift = shr( width, 1 ); // shiftedSFM = IGF_getSFM_ivas( pPowerSpectrum, swb_offset[sfb] - shift, swb_offset[sfb + 1] - shift ) / IGF_getCrest_ivas( pPowerSpectrum, swb_offset[sfb] - shift, swb_offset[sfb + 1] - shift ); - sfm = IGF_getSFM( &sfm_exp, pPowerSpectrum_fx, &pPowerSpectrum_e, sub( swb_offset[sfb], shift ), sub( swb_offset[sfb + 1], shift ) ); + sfm = IGF_getSFM_ivas_fx( &sfm_exp, pPowerSpectrum_fx, &pPowerSpectrum_e, sub( swb_offset[sfb], shift ), sub( swb_offset[sfb + 1], shift ) ); crest = IGF_getCrest( &crest_exp, pPowerSpectrum_fx, pPowerSpectrum_e, sub( swb_offset[sfb], shift ), sub( swb_offset[sfb + 1], shift ) ); shiftedSFM_fx = BASOP_Util_Divide1616_Scale( sfm, crest, &shiftedSFM_e ); } @@ -1331,7 +1331,7 @@ static void IGF_CalculateStereoEnvelope_fx( Word16 shift; shift = shr( width, 1 ); // shiftedSFM = IGF_getSFM_ivas( pPowerSpectrum, swb_offset[sfb] + shift, swb_offset[sfb + 1] + shift ) / IGF_getCrest_ivas( pPowerSpectrum, swb_offset[sfb] + shift, swb_offset[sfb + 1] + shift ); - sfm = IGF_getSFM( &sfm_exp, pPowerSpectrum_fx, &pPowerSpectrum_e, add( swb_offset[sfb], shift ), add( swb_offset[sfb + 1], shift ) ); + sfm = IGF_getSFM_ivas_fx( &sfm_exp, pPowerSpectrum_fx, &pPowerSpectrum_e, add( swb_offset[sfb], shift ), add( swb_offset[sfb + 1], shift ) ); crest = IGF_getCrest( &crest_exp, pPowerSpectrum_fx, pPowerSpectrum_e, add( swb_offset[sfb], shift ), add( swb_offset[sfb + 1], shift ) ); shiftedSFM_fx = BASOP_Util_Divide1616_Scale( sfm, crest, &shiftedSFM_e ); } diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index f508b313f..f78ad2025 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -895,6 +895,103 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value return SFM /*Q15*/; } +/************************************************************************* +calculates spectral flatness measurment +**************************************************************************/ +Word16 IGF_getSFM_ivas_fx( /**< out: Q15| SFM value */ + Word16 *SFM_exp, /**< out: | exponent of SFM Factor */ + const Word32 *energy, /**< in: Q31| energies */ + const Word16 *energy_exp, /**< in: | exponent of energies */ + const Word16 start, /**< in: Q0 | start subband index */ + const Word16 stop /**< in: Q0 | stop subband index */ +) +{ + Word16 n, i, s; + Word32 num; + Word32 denom; + Word16 denom_exp; + Word16 invDenom_exp, numf_exp; + Word16 numf; + Word32 SFM32; + Word16 invDenom, SFM; + + num = 0; + move32(); + denom = 65536; // 1.f in Q16 + denom_exp = 15; + *SFM_exp = 0; + move16(); + SFM = 32767 /*1.0f Q15*/; + move16(); + + FOR( i = start; i < stop; i++ ) + { + /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/ + + /* n = sub(sub(31,norm_l(tmp32)),1); */ /*<- ld */ + /* n = sub(n,31); */ /*<- -Qx */ + /* n = add(n,*energy_exp); */ /*<- +xExp */ + + n = sub( sub( *energy_exp, norm_l( energy[i] ) ), 1 ); /*<-- short form*/ + + if ( energy[i] == 0 ) /*special case: energy is zero*/ + { + n = 0; + move16(); + } + + n = s_max( 0, n ); + num = L_add( num, L_deposit_l( n ) ); /*Q0*/ + + denom = BASOP_Util_Add_Mant32Exp( energy[i], *energy_exp, denom, denom_exp, &denom_exp ); + } + + /* calculate SFM only if signal is present */ + IF( denom != 0 ) + { + /*numf = (float)num / (float)(stop - start);*/ + numf = BASOP_Util_Divide3216_Scale( num, /*Q0*/ + sub( stop, start ), /*Q0*/ + &s ); /*Q-1 s*/ + numf_exp = add( s, 16 ); /*-> numf Q15 numf_exp*/ + /*denom /= (float)(stop - start);*/ + /*return ((float)pow(2.0, numf + 0.5f) / denom);*/ + + /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/ + invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/, + denom /*Q31, denom_exp*/, + &s ); /*Q-16, s-denom_exp*/ + invDenom_exp = add( sub( s, denom_exp ), 31 ); /*invDenom: Q15, invDenom_exp*/ + + /*add .5f to numf*/ + SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/ + s = norm_l( SFM32 ); + SFM32 = L_shl( SFM32, s ); + s = sub( 16, s ); /*SFM32(numf) is Q31 now*/ + + /*do the pow2 and the mult*/ + SFM32 = BASOP_util_Pow2( SFM32, s, &s ); + SFM32 = Mpy_32_16_1( SFM32, invDenom ); + *SFM_exp = add( s, invDenom_exp ); + + /*Transform to Q15*/ + s = norm_l( SFM32 ); + SFM = round_fx_sat( L_shl_sat( SFM32, s ) ); + *SFM_exp = sub( *SFM_exp, s ); + move16(); + /**SFM_exp = s_min(*SFM_exp, 0);*/ + IF( *SFM_exp > 0 ) + { + *SFM_exp = 0; + move16(); + SFM = 32767 /*1.0f Q15*/; + move16(); + } + } + + return SFM /*Q15*/; +} + /**********************************************************************/ /* calculates the IGF whitening levels by SFM and crest **************************************************************************/ diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index d6532b207..c83f30ba7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -3066,6 +3066,13 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value const Word16 start, /**< in: Q0 | start subband index */ const Word16 stop /**< in: Q0 | stop subband index */ ); +Word16 IGF_getSFM_ivas_fx( /**< out: Q15| SFM value */ + Word16 *SFM_exp, /**< out: | exponent of SFM Factor */ + const Word32 *energy, /**< in: Q31| energies */ + const Word16 *energy_exp, /**< in: | exponent of energies */ + const Word16 start, /**< in: Q0 | start subband index */ + const Word16 stop /**< in: Q0 | stop subband index */ +); /* IGFEnc.c */ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< out: | exponent of highPassEner */ const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 3f6449a0c..4d8f59152 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1937,6 +1937,7 @@ Word16 ivas_smc_gmm_fx( /* calculation of differential normalized power spectrum */ sum_PS_fx = 0; move32(); + Word16 q_temp32; Word16 sum_PS_e = 0; move16(); Word64 sum = W_shl( 21475 /* 1e-5 in Q31 */, sub( Qfact_PS, 30 ) ); // Qfact_PS+1 @@ -1961,8 +1962,22 @@ Word16 ivas_smc_gmm_fx( FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - temp32 = BASOP_Util_Divide3232_Scale_cadence( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp - PS_norm_fx[i] = L_shl( temp32, sub( Qfact_PS_past, add( sub( 31, temp_exp ), sub( Qfact_PS, sub( 31, sum_PS_e ) ) ) ) ); // Qfact_PS_past + temp32 = BASOP_Util_Divide3232_Scale_cadence( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp + q_temp32 = add( sub( 31, temp_exp ), sub( Qfact_PS, sub( 31, sum_PS_e ) ) ); + test(); + if ( temp32 == 0 ) + { + q_temp32 = 31; + move16(); + } + IF( LT_16( q_temp32, 31 ) && EQ_32( temp32, L_shl( 1, q_temp32 ) ) ) + { + temp32 = ONE_IN_Q31; + move32(); + q_temp32 = Q31; + move16(); + } + PS_norm_fx[i] = L_shl( temp32, sub( Qfact_PS_past, q_temp32 ) ); // Qfact_PS_past move32(); dPS_fx[i] = L_abs( L_sub( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ); move32(); -- GitLab From 71be43e779165e5aabefcb3dece4e6e9dfdcf0fd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 12:51:19 +0200 Subject: [PATCH 1042/1221] fix STAGE2 --- lib_com/swb_tbe_com_fx.c | 304 +++++++++++++++++++++------------------ 1 file changed, 163 insertions(+), 141 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 537881fd1..6a6129957 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6762,102 +6762,113 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + /*duplicate this into unrolled loopsections in IsUpsampled3-path and dont forget to delete 0-set-input[1,2,4,5,7,8...]*/ + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + } /*IsUpsampled3*/ ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; ) - { - W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; - - W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); - W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); - L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ - move32(); - i++; + IF( isIVAS ) + { + FOR( i = 0; i < L_FRAME48k; ) + { + W_tmpX = W_mac_16_16( 0, input_fx[i - 3], full_band_bpf_fx[0][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpX = W_mac_16_16( 0, input_fx[i - 4], full_band_bpf_fx[0][4] ); + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + + W_tmpY = W_msu_32_16( 0, L_tmp[i - 1], full_band_bpf_fx[3][1] ); + W_tmpX = W_mac_16_16( 0, input_fx[i - 2], full_band_bpf_fx[0][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); + L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ + move32(); + i++; + } } -#else - FOR( i = 0; i < L_FRAME48k; ) - { - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; - - L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + { + FOR( i = 0; i < L_FRAME48k; ) + { + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), 0 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + + L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; - L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); - i++; + L_tmpX = L_sub_sat( 0, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ + move32(); + i++; + } } -#endif /*#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - } /*IsUpsampled3*/ + + } /*IsUpsampled3*/ #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ @@ -6930,38 +6941,43 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); - W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); - L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp[i - 4], full_band_bpf_fx[1][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 3], full_band_bpf_fx[1][3] ); + W_tmpY = W_msu_32_16( 0, L_tmp2[i - 1], full_band_bpf_fx[4][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 2], full_band_bpf_fx[1][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 2], full_band_bpf_fx[4][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i - 1], full_band_bpf_fx[1][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); + L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ @@ -7058,40 +7074,46 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - FOR( i = 0; i < L_FRAME48k; i++ ) + IF( isIVAS ) { - W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); - W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); - W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); - W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); - L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + W_tmpX = W_mac_32_16( 0, L_tmp2[i - 4], full_band_bpf_fx[2][4] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 3], full_band_bpf_fx[2][3] ); + W_tmpY = W_msu_32_16( 0, L_output[i - 1], full_band_bpf_fx[5][1] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 2], full_band_bpf_fx[2][2] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 2], full_band_bpf_fx[5][2] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i - 1], full_band_bpf_fx[2][1] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); + W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); + W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); + L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ - FOR( i = 0; i < L_FRAME48k; i++ ) + ELSE +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + FOR( i = 0; i < L_FRAME48k; i++ ) + { + L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ + L_output[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ + move32(); + L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); + } } -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ + #else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From ebe0992c04b634a2e448b8da929ee576c9ba9527 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 13:28:40 +0200 Subject: [PATCH 1043/1221] activate STAGE2 with isIVAS 1 in all cases --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index ec61fece6..490109b56 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -89,7 +89,7 @@ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif -- GitLab From 99e90164fe3cc9dbd7424070def89a464f3b2cee Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 13:33:08 +0200 Subject: [PATCH 1044/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6a6129957..f6eff2f35 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7114,7 +7114,7 @@ void elliptic_bpf_48k_generic_fx( } } -#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ +#else /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic*/ L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ -- GitLab From a43b1a9ccee810967ab7c13d3b8d73f228dd7f57 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 13:38:58 +0200 Subject: [PATCH 1045/1221] fix unused parameter --- lib_com/swb_tbe_com_fx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index f6eff2f35..30ce3b650 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7288,7 +7288,11 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS 1, // isIVAS +#else + isIVAS, +#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx @@ -7304,7 +7308,11 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS 1, // isIVAS +#else + isIVAS, +#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); -- GitLab From 1132ef4545af681636bba726ad467737e60c23fb Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 13:40:40 +0200 Subject: [PATCH 1046/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 30ce3b650..4f73165c2 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7291,7 +7291,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS 1, // isIVAS #else - isIVAS, + isIVAS, #endif #endif 1, // IsUpsampled3 @@ -7311,7 +7311,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS 1, // isIVAS #else - isIVAS, + isIVAS, #endif #endif 1, // IsUpsampled3 -- GitLab From f103c93f4ee7d261dff8f0771dc3792ba4374e9b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 13:44:01 +0200 Subject: [PATCH 1047/1221] fix unused parameter --- lib_com/swb_tbe_com_fx.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 4f73165c2..21bb4eaeb 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7267,6 +7267,10 @@ void synthesise_fb_high_band_fx( Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS + isIVAS = 1; +#endif + /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7288,11 +7292,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS - 1, // isIVAS -#else isIVAS, -#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx @@ -7308,11 +7308,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS - 1, // isIVAS -#else isIVAS, -#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); -- GitLab From c9506c850340f63ac3b8031fc8c6c5b61bc4620d Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 15 Apr 2025 17:07:03 +0530 Subject: [PATCH 1048/1221] Fix for a crash in LTV complexity measurement pipeline --- lib_dec/fd_cng_dec_fx.c | 49 ++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 4c42a7959..0309771ff 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1536,8 +1536,8 @@ Word16 ApplyFdCng_ivas_fx( Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) ); Word16 shift = s_max( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); - scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), shift ) ); - scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( sub( *cngNoiseLevel_exp, shift2 ), shift ) ); + scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( hFdCngDec->bandNoiseShape_exp, shift ) ); + scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( *cngNoiseLevel_exp, shift ) ); *cngNoiseLevel_exp = shift; move16(); @@ -1688,16 +1688,15 @@ Word16 ApplyFdCng_ivas_fx( move32(); } } - /* adapt scaling for rest of the buffer */ - s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); - FOR( ; j < FFTCLDFBLEN; j++ ) - { - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ - move32(); - } + Word16 shift1 = L_norm_arr( cngNoiseLevel, j ); + Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) ); + Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); - *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); + scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) ); + scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) ); + + *cngNoiseLevel_exp = shift; move16(); } } @@ -1761,18 +1760,15 @@ Word16 ApplyFdCng_ivas_fx( move32(); } } - /* adapt scaling for rest of the buffer */ - s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); - FOR( ; j < FFTCLDFBLEN; j++ ) - { - /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ - cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ - move32(); - } + Word16 shift1 = L_norm_arr( cngNoiseLevel, j ); + Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) ); + Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); + scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) ); + scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) ); - *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); + *cngNoiseLevel_exp = shift; move16(); } } @@ -2399,8 +2395,15 @@ void perform_noise_estimation_dec_ivas_fx( ELSE { Copy32( msPeriodog, msNoiseEst, npart ); - scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); - hFdCngDec->msNoiseEst_exp = hFdCngDec->msPeriodog_exp; + + Word16 shift1 = L_norm_arr( msNoiseEst, npart ); + Word16 shift2 = L_norm_arr( &msNoiseEst[npart], sub( NPART_SHAPING, npart ) ); + Word16 shift = s_max( sub( hFdCngDec->msPeriodog_exp, shift1 ), sub( hFdCngDec->msNoiseEst_exp, shift2 ) ); + + scale_sig32( msNoiseEst, npart, sub( hFdCngDec->msPeriodog_exp, shift ) ); + scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, shift ) ); + + hFdCngDec->msNoiseEst_exp = shift; move16(); } @@ -5071,8 +5074,8 @@ void FdCng_decodeSID_ivas_fx( Word16 shift2 = L_norm_arr( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ) ); Word16 shift = s_max( sub( hFdCngCom->sidNoiseEstExp, shift1 ), sub( hFdCngCom->cngNoiseLevelExp, shift2 ) ); - scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( sub( hFdCngCom->sidNoiseEstExp, shift1 ), shift ) ); - scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( sub( hFdCngCom->cngNoiseLevelExp, shift2 ), shift ) ); + scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( hFdCngCom->sidNoiseEstExp, shift ) ); + scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( hFdCngCom->cngNoiseLevelExp, shift ) ); hFdCngCom->cngNoiseLevelExp = shift; move16(); -- GitLab From c0b894982c8fbbaee1ba6ee3574c44c0e5f72054 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Tue, 15 Apr 2025 14:10:28 +0200 Subject: [PATCH 1049/1221] cleanup --- lib_com/options.h | 1 + lib_enc/ivas_stereo_dmx_evs_fx.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 5ed2aa912..43c3c3038 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,6 +84,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ +#define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ #define TEST_HR diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 042a2e541..6e04b91c7 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -2419,7 +2419,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_g = hStereoDmxEVS->hPHA->fad_g_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); -#if 1 +#ifdef FIX_1481_HARDCODE_DIV SWITCH( fad_len ) { case STEREO_DMX_EVS_FAD_LEN_16: @@ -2564,7 +2564,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( move16(); fad_g = hStereoDmxEVS->hPHA->fad_g_prc_fx; // fad_r = 1.0f / (float) ( fad_len + 1 ); -#if 1 +#ifdef FIX_1481_HARDCODE_DIV SWITCH( fad_len ) { case STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 16: -- GitLab From f47deccf0a64382b75f87d469c8584a495afe1fb Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 15 Apr 2025 17:46:50 +0530 Subject: [PATCH 1050/1221] Fix for 3GPP issue 1477: Encoder crash (assert) in ISM1, HQ core fine gain quantization --- lib_com/pvq_com_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index a6c0bc462..1adcdb7ae 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -564,8 +564,8 @@ void fine_gain_quant_fx( tmp1 = extract_l( Pow2( 14, tmp1 ) ); exp1 = sub( 14, exp1 ); - L_tmp = L_mult0( fg_pred[band], tmp1 ); /*12+exp1 */ - fg_pred[band] = round_fx( L_shl( L_tmp, sub( 16, exp1 ) ) ); /*12+exp1+16-exp1-16=12 */ + L_tmp = L_mult0( fg_pred[band], tmp1 ); /*12+exp1 */ + fg_pred[band] = round_fx_sat( L_shl_sat( L_tmp, sub( 16, exp1 ) ) ); /*12+exp1+16-exp1-16=12 */ move16(); } } -- GitLab From 627abb06732e9b163f0b271ea79a3898156d88cc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 14:54:49 +0200 Subject: [PATCH 1051/1221] use FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE --- lib_com/options.h | 3 ++- lib_com/prot_fx.h | 8 ++++++++ lib_com/swb_tbe_com_fx.c | 43 ++++++++++++++++++++++++++++++++++++---- lib_dec/swb_tbe_dec_fx.c | 16 +++++++++------ lib_enc/swb_tbe_enc_fx.c | 26 +++++++++++++++--------- 5 files changed, 76 insertions(+), 20 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 490109b56..e3ac4ccfb 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -90,6 +90,7 @@ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ + #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE /*according to comment of @vaclav in MR!1390*/ /*overrides STAGE2 settings*/ + //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 33ac952cc..05fc12bd9 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3267,7 +3267,11 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + const int16_t element_mode, +#else Word16 isIVAS, +#endif #endif Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -3302,8 +3306,12 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + int16_t element_mode +#else Word16 isIVAS #endif +#endif ); void prep_tbe_exc_fx( diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 21bb4eaeb..cf6161e57 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,8 +6696,12 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + int16_t element_mode, +#else Word16 isIVAS, #endif +#endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -6711,6 +6715,13 @@ void elliptic_bpf_48k_generic_fx( const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + element_mode = 1; +#else + isIVAS = 1; +#endif +#endif Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; @@ -6762,7 +6773,11 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + IF(element_mode) +#else IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6801,7 +6816,11 @@ void elliptic_bpf_48k_generic_fx( ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + IF(element_mode) +#else IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; ) { @@ -6941,7 +6960,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + IF(element_mode) +#else IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7074,7 +7097,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + IF(element_mode) +#else IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7250,8 +7277,12 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + int16_t element_mode +#else Word16 isIVAS #endif +#endif ) { Word16 i, j; @@ -7267,10 +7298,6 @@ void synthesise_fb_high_band_fx( Word32 L_tmp; Word16 tmp3, tmp1, tmp2, exp, exp2, exp_tmp; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS - isIVAS = 1; -#endif - /* Interpolate the white energy shaped gaussian excitation from 16 kHz to 48 kHz with zeros */ j = 0; /* white excitation from DC to 8 kHz resampled to produce DC to 24 kHz excitation. */ @@ -7292,7 +7319,11 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + element_mode , +#else isIVAS, +#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx @@ -7308,7 +7339,11 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + element_mode, +#else isIVAS, +#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index e910e5457..5ab562fe2 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4646,14 +4646,13 @@ void fb_tbe_dec_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS - , - 1 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + ,st->element_mode #else , 0 -#endif -#endif +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); /* add the fb_synth component to the hb_synth component */ @@ -4725,9 +4724,14 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + , + st->element_mode +#else , 1 -#endif +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); test(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 7ad3b2013..990a44d19 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7333,12 +7333,12 @@ void fb_tbe_enc_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS - 1, // isIVAS +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + st->element_mode, #else - 0, // isIVAS -#endif -#endif + 0, +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else @@ -7475,8 +7475,12 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS -#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + st->element_mode, +#else + 1, +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else @@ -7488,8 +7492,12 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - 1, // isIVAS -#endif +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + st->element_mode, +#else + 1, +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else -- GitLab From db0bbc7d9f233eef3ef4c0653aa009a9c13268cd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 15 Apr 2025 15:11:41 +0200 Subject: [PATCH 1052/1221] clang patch --- lib_com/options.h | 2 +- lib_com/prot_fx.h | 4 ++-- lib_com/swb_tbe_com_fx.c | 12 ++++++------ lib_dec/swb_tbe_dec_fx.c | 3 ++- lib_enc/swb_tbe_enc_fx.c | 12 ++++++------ 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e3ac4ccfb..daf2be13b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 05fc12bd9..1d2873dc4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3268,7 +3268,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - const int16_t element_mode, + const int16_t element_mode, #else Word16 isIVAS, #endif @@ -3307,7 +3307,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - int16_t element_mode + int16_t element_mode #else Word16 isIVAS #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index cf6161e57..10f508489 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6697,7 +6697,7 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - int16_t element_mode, + int16_t element_mode, #else Word16 isIVAS, #endif @@ -6774,7 +6774,7 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - IF(element_mode) + IF( element_mode ) #else IF( isIVAS ) #endif @@ -6817,7 +6817,7 @@ void elliptic_bpf_48k_generic_fx( { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - IF(element_mode) + IF( element_mode ) #else IF( isIVAS ) #endif @@ -6961,7 +6961,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - IF(element_mode) + IF( element_mode ) #else IF( isIVAS ) #endif @@ -7098,7 +7098,7 @@ void elliptic_bpf_48k_generic_fx( L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - IF(element_mode) + IF( element_mode ) #else IF( isIVAS ) #endif @@ -7320,7 +7320,7 @@ void synthesise_fb_high_band_fx( elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - element_mode , + element_mode, #else isIVAS, #endif diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 5ab562fe2..c02a6a182 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4647,7 +4647,8 @@ void fb_tbe_dec_fx( synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - ,st->element_mode + , + st->element_mode #else , 0 diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 990a44d19..29ef4427a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7337,8 +7337,8 @@ void fb_tbe_enc_fx( st->element_mode, #else 0, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else @@ -7479,8 +7479,8 @@ void fb_tbe_enc_ivas_fx( st->element_mode, #else 1, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else @@ -7496,8 +7496,8 @@ void fb_tbe_enc_ivas_fx( st->element_mode, #else 1, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); #else -- GitLab From c227804b934b0cb380dd4cd5ec60c20660266d43 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 15 Apr 2025 19:41:45 +0200 Subject: [PATCH 1053/1221] clang-format --- lib_dec/acelp_core_dec_ivas_fx.c | 11 +---------- lib_dec/fd_cng_dec_fx.c | 4 ++-- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 6cecf8323..ad8ca9b50 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -848,16 +848,7 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn -> Q(-1) IF( st->hBWE_FD != NULL ) { -#ifdef REMOVE_EVS_DUPLICATES - IF( EQ_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - this is likely a bug in IVAS - { - save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); - } - ELSE -#endif - { - save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); - } + save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); } } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index f881d252d..dbb13de12 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1241,7 +1241,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } @@ -1565,7 +1565,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } -- GitLab From f34b6383bddca55252f3f7671c9c19461b5f62b2 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Tue, 15 Apr 2025 20:41:00 +0200 Subject: [PATCH 1054/1221] convert remaining places in ivas_stereo_dmx_evs_fx.c --- lib_enc/ivas_stereo_dmx_evs_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 625ff8ee9..425685529 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -830,7 +830,7 @@ static void calc_poc_fx( // ICCr = (float) sqrt( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) ); L_tmp1 = BASOP_Util_Add_Mant32Exp( Mpy_32_32_r( Nr, Nr ), shl( Nr_e, 1 ), Mpy_32_32_r( Ni, Ni ), shl( Ni_e, 1 ), &L_tmp1_e ); L_tmp2 = BASOP_Util_Add_Mant32Exp( Mpy_32_32_r( eneL, eneR ), add( eneL_e, eneR_e ), EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); - ICCr = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ); + ICCr = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp_e ); L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); ICCr = Sqrt32( ICCr, &L_tmp_e ); // Saturation to handle values close to 1.0f @@ -1891,7 +1891,7 @@ void stereo_dmx_evs_enc_fx( } L_tmp1 = BASOP_Util_Add_Mant32Exp( hStereoDmxEVS->hPHA->trns_aux_energy_fx[k], hStereoDmxEVS->hPHA->trns_aux_energy_fx_e[k], EPSILON_FX_M, EPSILON_FX_E, &L_tmp1_e ); - L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( subframe_energy[m], L_tmp1, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Divide3232_Scale_newton( subframe_energy[m], L_tmp1, &L_tmp2_e ); L_tmp2_e = add( L_tmp2_e, sub( subframe_energy_e[m], L_tmp1_e ) ); // if ( subframe_energy[m] / ( hStereoDmxEVS->hPHA->trns_aux_energy[k] + EPSILON ) > hStereoDmxEVS->hPHA->crst_fctr ) if ( BASOP_Util_Cmp_Mant32Exp( L_tmp2, L_tmp2_e, hStereoDmxEVS->hPHA->crst_fctr_fx, 31 ) > 0 ) @@ -1919,7 +1919,7 @@ void stereo_dmx_evs_enc_fx( FOR( m = 1; m < STEREO_DMX_EVS_NB_SBFRM; m++ ) { L_tmp1 = BASOP_Util_Add_Mant32Exp( subframe_energy[m - 1], subframe_energy_e[m - 1], EPSILON_FX_M, EPSILON_FX_E, &L_tmp1_e ); - L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( subframe_energy[m], L_tmp1, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Divide3232_Scale_newton( subframe_energy[m], L_tmp1, &L_tmp2_e ); L_tmp2_e = add( L_tmp2_e, sub( subframe_energy_e[m], L_tmp1_e ) ); // if ( subframe_energy[m] / ( subframe_energy[m - 1] + EPSILON ) > STEREO_DMX_EVS_TRNS_DTC_INST ) if ( BASOP_Util_Cmp_Mant32Exp( L_tmp2, L_tmp2_e, STEREO_DMX_EVS_TRNS_DTC_INST_Q0, 31 ) > 0 ) -- GitLab From 2ccf2c7cf2dd04348a9f6cedac75caaeb6ba2aa0 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Wed, 16 Apr 2025 06:47:41 +0530 Subject: [PATCH 1055/1221] Fix for 3GPP issue 1470: Increased noise in 6-14 kHz range with ParamBin rendering of MASA to STEREO using BASOP decoder --- lib_dec/fd_cng_dec_fx.c | 6 +++--- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 0309771ff..55c491efe 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -5664,7 +5664,7 @@ void generate_masking_noise_dirac_ivas_fx( scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ q_scale = add( q_scale, q_shift ); scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 - q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); + q_scale = sub( add( q_scale, 2 * Q8 ), 31 + 3 ); ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); @@ -5675,8 +5675,8 @@ void generate_masking_noise_dirac_ivas_fx( q_shift = norm_l( scale_fx ); scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ q_scale = add( q_scale, q_shift ); - num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ - q_num = sub( add( q_scale, q_ptr_level ), 31 ); + num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ + q_num = sub( add( q_scale, q_ptr_level ), 31 - 1 ); // num = ( scale * *ptr_level ) * 0.5f exp = sub( 31, q_num ); num = Sqrt32( num, &exp ); /*Q31 - exp*/ /* Real part in CLDFB band */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index ce602160f..c7b420e38 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -758,6 +758,9 @@ static void ivas_dirac_dec_binaural_internal_fx( ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag, 0, &q_cldfb[1][slot] ); + scale_sig32( Cldfb_RealBuffer_in_fx[1][slot], CLDFB_NO_CHANNELS_MAX, negate( add( sub( q_cldfb[1][slot], q_input ), 5 ) ) ); + scale_sig32( Cldfb_ImagBuffer_in_fx[1][slot], CLDFB_NO_CHANNELS_MAX, negate( add( sub( q_cldfb[1][slot], q_input ), 5 ) ) ); + /* LB: Copy first channel + LB-CNG to first and second channels with same scaling (dual-mono)*/ FOR( b = 0; b < numCoreBands; b++ ) { -- GitLab From 1daee4188980cd56ac1bcfbb35ff009c8da527a0 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 07:36:04 +0200 Subject: [PATCH 1056/1221] test STAGE2_saturationmode2 --- lib_com/options.h | 7 ++++--- lib_com/swb_tbe_com_fx.c | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index daf2be13b..e07899557 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -87,10 +87,11 @@ #define TEST_HR -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ /*0.9 WMOPS*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ /*3.2 WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE /*according to comment of @vaclav in MR!1390*/ /*overrides STAGE2 settings*/ - //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ +// #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 10f508489..c5b2941d5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6791,7 +6791,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr(W_tmpX,3), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); } } @@ -6830,7 +6834,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); i++; @@ -6840,7 +6848,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); i++; @@ -6849,7 +6861,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); i++; } @@ -6977,7 +6993,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); +#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7114,7 +7134,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); +#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -- GitLab From 1de6bb47406cb7108ee6e67ac29762a7a50e5080 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 07:39:36 +0200 Subject: [PATCH 1057/1221] clang patch --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c5b2941d5..2900d54e9 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6792,7 +6792,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr(W_tmpX,3), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ #else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ #endif -- GitLab From b40fc402017aecf7982e099cba73fad32ad20e1b Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 16 Apr 2025 07:58:24 +0200 Subject: [PATCH 1058/1221] Reactivate FIX_1379_MASA_ANGLE_ROUND after merge with conflict resolution. --- lib_com/options.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 43c3c3038..ad220450b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -71,6 +71,8 @@ #define FIX_1378_ACELP_OUT_OF_BOUNDS +#define FIX_1379_MASA_ANGLE_ROUND + /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ //#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ -- GitLab From c00e57f2c7b4911f742516dcf13bd7cfc14861dd Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 08:36:13 +0200 Subject: [PATCH 1059/1221] delete FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS, FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2, made FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 permanent active. WMOPS for bitstream in issue 1439: general patch: .9 WMOPS - nonBE, no regressions, STAGE2 patch: 3.2 WMOPS - 1 small regression --- lib_com/options.h | 7 ++--- lib_com/prot_fx.h | 8 ----- lib_com/swb_tbe_com_fx.c | 63 ---------------------------------------- lib_dec/swb_tbe_dec_fx.c | 10 ------- lib_enc/swb_tbe_enc_fx.c | 12 -------- 5 files changed, 2 insertions(+), 98 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 3ce190efc..84aac4489 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -88,11 +88,8 @@ #define TEST_HR -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ /*0.9 WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: nonBE, 0 regressions - reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ /*3.2 WMOPS*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE /*according to comment of @vaclav in MR!1390*/ /*overrides STAGE2 settings*/ -// #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1d2873dc4..8d70b1092 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3267,11 +3267,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE const int16_t element_mode, -#else - Word16 isIVAS, -#endif #endif Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -3306,11 +3302,7 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode -#else - Word16 isIVAS -#endif #endif ); diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2900d54e9..a3b4bd5c6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,11 +6696,7 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode, -#else - Word16 isIVAS, -#endif #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6715,13 +6711,6 @@ void elliptic_bpf_48k_generic_fx( const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - element_mode = 1; -#else - isIVAS = 1; -#endif -#endif Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; @@ -6773,11 +6762,7 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6791,11 +6776,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); } } @@ -6820,11 +6801,7 @@ void elliptic_bpf_48k_generic_fx( ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; ) { @@ -6834,11 +6811,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); i++; @@ -6848,11 +6821,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); i++; @@ -6861,11 +6830,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); i++; } @@ -6976,11 +6941,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6993,11 +6954,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); -#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7117,11 +7074,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7134,11 +7087,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); -#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } @@ -7301,11 +7250,7 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode -#else - Word16 isIVAS -#endif #endif ) { @@ -7343,11 +7288,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE element_mode, -#else - isIVAS, -#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx @@ -7363,11 +7304,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE element_mode, -#else - isIVAS, -#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index c02a6a182..890e0e5c8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4646,13 +4646,8 @@ void fb_tbe_dec_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE , st->element_mode -#else - , - 0 -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); @@ -4725,13 +4720,8 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE , st->element_mode -#else - , - 1 -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 29ef4427a..4f10d3b02 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7333,11 +7333,7 @@ void fb_tbe_enc_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, -#else - 0, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7475,11 +7471,7 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, -#else - 1, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7492,11 +7484,7 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, -#else - 1, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -- GitLab From f33357542fca749ec15cc69f253b8254c1522040 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 07:32:47 +0000 Subject: [PATCH 1060/1221] delete some code from another ticket and some empty lines --- lib_com/options.h | 4 +--- lib_com/swb_tbe_com_fx.c | 3 --- lib_com/tools_fx.c | 26 +------------------------- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 ---------- lib_dec/swb_tbe_dec_fx.c | 10 ---------- 5 files changed, 2 insertions(+), 51 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 84aac4489..1ada99f53 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -#define WMOPS /* Activate complexity and memory counters */ +/*#define WMOPS*/ /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -87,9 +87,7 @@ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ #define TEST_HR - #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: nonBE, 0 regressions - reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ #endif - diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a3b4bd5c6..6ac3ee725 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7038,7 +7038,6 @@ void elliptic_bpf_48k_generic_fx( } #endif - Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -7180,10 +7179,8 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - #endif - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 6dc1c45f2..5f0e172bf 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,37 +794,13 @@ void Copy_Scale_sig_16_32_no_sat( } return; } -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat - L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - - IF( L_tmp >= 0x7FFF ) - { - FOR( i = 0; i < lg; i++ ) - { - // y[i] = L_mult0(x[i], L_tmp); - y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* Overflow can occur here */ - } - return; - } - // ELSE - { - Word16 tmp = extract_l( L_tmp ); - FOR( i = 0; i < lg; i++ ) - { - y[i] = L_mult( x[i], tmp ); - move32(); - } - } -#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* Overflow can occur here */ + move32(); /* saturation can occur here */ } -#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 772eb2d7d..c7bc98566 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,9 +904,6 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); -#endif FOR( i = 0; i < winLen_fx; i++ ) { L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ @@ -914,17 +911,10 @@ void stereo_icBWE_dec_fx( tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - if ( LE_16( alpha_fx, winSlope_fx_ ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ - } -#else IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } -#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 890e0e5c8..419d202fc 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7032,24 +7032,14 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); - -#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx - Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 -#endif - FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } -#else - Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ -#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); -- GitLab From 930e90a4fc862e5165ba4f81a77dce68b745449e Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 16 Apr 2025 10:10:41 +0200 Subject: [PATCH 1061/1221] fix in ApplyFdCng_ivas_fx() --- lib_dec/fd_cng_dec_fx.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index dbb13de12..5c649df9b 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1241,7 +1241,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } @@ -1565,7 +1565,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } @@ -1757,15 +1757,35 @@ Word16 ApplyFdCng_ivas_fx( } } - Word16 shift1 = L_norm_arr( cngNoiseLevel, j ); - Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) ); - Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); +#ifdef REMOVE_EVS_DUPLICATES + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + /* adapt scaling for rest of the buffer */ + s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); + FOR( ; k < hFdCngCom->npart; k++ ) + { + FOR( ; j <= hFdCngCom->part[k]; j++ ) + { + cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ + move32(); + } + } + *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); + move16(); + } + ELSE +#endif + { + Word16 shift1 = L_norm_arr( cngNoiseLevel, j ); + Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) ); + Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) ); - scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) ); - scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) ); + scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) ); + scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) ); - *cngNoiseLevel_exp = shift; - move16(); + *cngNoiseLevel_exp = shift; + move16(); + } } } ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) -- GitLab From 9d14ced3fbf85af53dec45d1e3f8c8c040f35d64 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 16 Apr 2025 10:24:15 +0200 Subject: [PATCH 1062/1221] clang-format --- lib_dec/fd_cng_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 2bab16e04..d0fd178f2 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1241,7 +1241,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } @@ -1565,7 +1565,7 @@ Word16 ApplyFdCng_ivas_fx( } ELSE #endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } -- GitLab From 298c2401ea8e092b9a7d3e62260632ac73f6efb6 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Wed, 16 Apr 2025 14:31:39 +0530 Subject: [PATCH 1063/1221] Fix for LTV Multichannel 5_1 at 13.2 kbps 48kHz stream crash --- lib_com/gs_preech_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index 48ec22a22..16d3ce0e5 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -233,7 +233,7 @@ void pre_echo_att_ivas_fx( tmp = BASOP_Util_Divide3232_Scale( *Last_frame_ener_fx, etmp_fx, &tmp_e ); /* numerator Q = 2 * Q_new + 1; denominator Q = 31 - tmp_e */ tmp_e = add( tmp_e, sub( sub( 31, etmp_e ), add( shl( Q_new, 1 ), 1 ) ) ); /* tmp_e = tmp_e + (31 - tmp_e) - (2 * Q_new + 1) */ tmp = Sqrt16( tmp, &tmp_e ); - ratio_fx = shr( tmp, sub( 2, tmp_e ) ); /* Q13 */ + ratio_fx = shr_sat( tmp, sub( 2, tmp_e ) ); /* Q13 */ /* Pre-echo atttenuation should never increase the energy */ ratio_fx = s_min( ratio_fx, 8192 /* 1 in Q13 */ ); /* Q13 */ -- GitLab From d44872b1cf0bdd372055b00ee2dfdc9808b701c6 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:43:56 +0200 Subject: [PATCH 1064/1221] activate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1ada99f53..53a30a4a6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -88,6 +88,6 @@ #define TEST_HR #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: nonBE, 0 regressions - reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ #endif -- GitLab From 11970ae85c46799186afabf2370f758200e40644 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:55:51 +0200 Subject: [PATCH 1065/1221] Revert "activate FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2" This reverts commit d44872b1cf0bdd372055b00ee2dfdc9808b701c6. --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 53a30a4a6..1ada99f53 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -88,6 +88,6 @@ #define TEST_HR #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: nonBE, 0 regressions - reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ +//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ #endif -- GitLab From 38e2cb22645320d0511938c78e30aa48445ed02e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:56:05 +0200 Subject: [PATCH 1066/1221] Revert "delete some code from another ticket and some empty lines" This reverts commit f33357542fca749ec15cc69f253b8254c1522040. --- lib_com/options.h | 4 +++- lib_com/swb_tbe_com_fx.c | 3 +++ lib_com/tools_fx.c | 26 +++++++++++++++++++++++++- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 ++++++++++ lib_dec/swb_tbe_dec_fx.c | 10 ++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1ada99f53..84aac4489 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -87,7 +87,9 @@ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ #define TEST_HR + #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: nonBE, 0 regressions - reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ #endif + diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6ac3ee725..a3b4bd5c6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7038,6 +7038,7 @@ void elliptic_bpf_48k_generic_fx( } #endif + Q_temp = norm_l( L_tmpMax ); Q_temp = sub( Q_temp, 4 ); Scale_sig32( L_tmp2, 960, Q_temp ); @@ -7179,8 +7180,10 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } + #endif + memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 5f0e172bf..6dc1c45f2 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,13 +794,37 @@ void Copy_Scale_sig_16_32_no_sat( } return; } +#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat + L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); + + IF( L_tmp >= 0x7FFF ) + { + FOR( i = 0; i < lg; i++ ) + { + // y[i] = L_mult0(x[i], L_tmp); + y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); + move32(); /* Overflow can occur here */ + } + return; + } + // ELSE + { + Word16 tmp = extract_l( L_tmp ); + FOR( i = 0; i < lg; i++ ) + { + y[i] = L_mult( x[i], tmp ); + move32(); + } + } +#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* saturation can occur here */ + move32(); /* Overflow can occur here */ } +#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index c7bc98566..772eb2d7d 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,6 +904,9 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); +#endif FOR( i = 0; i < winLen_fx; i++ ) { L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ @@ -911,10 +914,17 @@ void stereo_icBWE_dec_fx( tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); +#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx + if ( LE_16( alpha_fx, winSlope_fx_ ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ + } +#else IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } +#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 419d202fc..890e0e5c8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7032,14 +7032,24 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); + +#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx + Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 +#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { +#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } +#else + Word16 idx; + idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ +#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); -- GitLab From 7bddc36ae7b4d790941c362a9ce416d96bf26b5b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:56:17 +0200 Subject: [PATCH 1067/1221] Revert "delete FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS, FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2, made FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 permanent active. WMOPS for bitstream in issue 1439: general patch: .9 WMOPS - nonBE, no regressions, STAGE2 patch: 3.2 WMOPS - 1 small regression" This reverts commit c00e57f2c7b4911f742516dcf13bd7cfc14861dd. --- lib_com/options.h | 7 +++-- lib_com/prot_fx.h | 8 +++++ lib_com/swb_tbe_com_fx.c | 63 ++++++++++++++++++++++++++++++++++++++++ lib_dec/swb_tbe_dec_fx.c | 10 +++++++ lib_enc/swb_tbe_enc_fx.c | 12 ++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 84aac4489..3ce190efc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -88,8 +88,11 @@ #define TEST_HR -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: nonBE, 0 regressions - reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -//#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: nonBE, 1 regression (Pipeline #51485) - reduces 3.2 WMOPS with issue 1439 Bitstream*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ /*0.9 WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ /*3.2 WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE /*according to comment of @vaclav in MR!1390*/ /*overrides STAGE2 settings*/ +// #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 8d70b1092..1d2873dc4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3267,7 +3267,11 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE const int16_t element_mode, +#else + Word16 isIVAS, +#endif #endif Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -3302,7 +3306,11 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode +#else + Word16 isIVAS +#endif #endif ); diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a3b4bd5c6..2900d54e9 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,7 +6696,11 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode, +#else + Word16 isIVAS, +#endif #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6711,6 +6715,13 @@ void elliptic_bpf_48k_generic_fx( const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) { +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE + element_mode = 1; +#else + isIVAS = 1; +#endif +#endif Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; @@ -6762,7 +6773,11 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) +#else + IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6776,7 +6791,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); } } @@ -6801,7 +6820,11 @@ void elliptic_bpf_48k_generic_fx( ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) +#else + IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; ) { @@ -6811,7 +6834,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); i++; @@ -6821,7 +6848,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); i++; @@ -6830,7 +6861,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ +#endif move32(); i++; } @@ -6941,7 +6976,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) +#else + IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6954,7 +6993,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); +#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7074,7 +7117,11 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) +#else + IF( isIVAS ) +#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7087,7 +7134,11 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 + L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ +#else L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); +#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } @@ -7250,7 +7301,11 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode +#else + Word16 isIVAS +#endif #endif ) { @@ -7288,7 +7343,11 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE element_mode, +#else + isIVAS, +#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx @@ -7304,7 +7363,11 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE element_mode, +#else + isIVAS, +#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 890e0e5c8..c02a6a182 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4646,8 +4646,13 @@ void fb_tbe_dec_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE , st->element_mode +#else + , + 0 +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); @@ -4720,8 +4725,13 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE , st->element_mode +#else + , + 1 +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 4f10d3b02..29ef4427a 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7333,7 +7333,11 @@ void fb_tbe_enc_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, +#else + 0, +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7471,7 +7475,11 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, +#else + 1, +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7484,7 +7492,11 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, +#else + 1, +#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -- GitLab From 10b4e67f2ee9d6fa65326e2d6ca1320dc76fe348 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:56:33 +0200 Subject: [PATCH 1068/1221] Revert "clang patch" This reverts commit 1de6bb47406cb7108ee6e67ac29762a7a50e5080. --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2900d54e9..c5b2941d5 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6792,7 +6792,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ + L_tmp[i] = W_sat_l( W_add( W_shr(W_tmpX,3), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ #else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ #endif -- GitLab From 8e842aba751226f7f011f4171bc440c556a168ac Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:56:43 +0200 Subject: [PATCH 1069/1221] Revert "test STAGE2_saturationmode2" This reverts commit 1daee4188980cd56ac1bcfbb35ff009c8da527a0. --- lib_com/options.h | 7 +++---- lib_com/swb_tbe_com_fx.c | 24 ------------------------ 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 3ce190efc..4f564c9f4 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -88,11 +88,10 @@ #define TEST_HR -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ /*0.9 WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ /*3.2 WMOPS*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE /*according to comment of @vaclav in MR!1390*/ /*overrides STAGE2 settings*/ -// #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ + //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c5b2941d5..10f508489 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6791,11 +6791,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr(W_tmpX,3), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); } } @@ -6834,11 +6830,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpX = W_mac_16_16( W_tmpX, input_fx[i], full_band_bpf_fx[0][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); i++; @@ -6848,11 +6840,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpX = W_mac_16_16( W_tmpX, input_fx[i - 1], full_band_bpf_fx[0][1] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); i++; @@ -6861,11 +6849,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 2], full_band_bpf_fx[3][2] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 3], full_band_bpf_fx[3][3] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp[i - 4], full_band_bpf_fx[3][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 ) ), 3 ) ); /*Q_input_fx + 11*/ -#endif move32(); i++; } @@ -6993,11 +6977,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 3], full_band_bpf_fx[4][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp[i], full_band_bpf_fx[1][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_tmp2[i - 4], full_band_bpf_fx[4][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_tmp2[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_tmp2[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); -#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -7134,11 +7114,7 @@ void elliptic_bpf_48k_generic_fx( W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 3], full_band_bpf_fx[5][3] ); W_tmpX = W_mac_32_16( W_tmpX, L_tmp2[i], full_band_bpf_fx[2][0] ); W_tmpY = W_msu_32_16( W_tmpY, L_output[i - 4], full_band_bpf_fx[5][4] ); -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_saturationmode2 - L_output[i] = W_sat_l( W_add( W_shr( W_tmpX, 3 ), W_shl( W_tmpY, 2 - 16 ) ) ); /*Q_input_fx + 11*/ -#else L_output[i] = W_sat_l( W_shr( W_add( W_tmpX, W_shl( W_tmpY, 2 - 16 + 3 + 16 ) ), 3 + 16 ) ); -#endif move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -- GitLab From e47ccc1e1c7cad1050ab57bf9a62ccf218646434 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 13:10:36 +0200 Subject: [PATCH 1070/1221] make FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 permanent active, delete FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS --- lib_com/options.h | 2 -- lib_com/prot_fx.h | 8 -------- lib_com/swb_tbe_com_fx.c | 39 --------------------------------------- lib_dec/swb_tbe_dec_fx.c | 10 ---------- lib_enc/swb_tbe_enc_fx.c | 12 ------------ 5 files changed, 71 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 4f564c9f4..ed6303e70 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -91,7 +91,5 @@ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ - #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE /*according to comment of @vaclav in MR!1390*/ /*overrides STAGE2 settings*/ - //#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS /*Test stage2 macro with all isavas variable = 1 - evs BE test will fail at least*/ #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1d2873dc4..8d70b1092 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3267,11 +3267,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE const int16_t element_mode, -#else - Word16 isIVAS, -#endif #endif Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -3306,11 +3302,7 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode -#else - Word16 isIVAS -#endif #endif ); diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 10f508489..a3b4bd5c6 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6696,11 +6696,7 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode, -#else - Word16 isIVAS, -#endif #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -6715,13 +6711,6 @@ void elliptic_bpf_48k_generic_fx( const Word16 full_band_bpf_fx[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 Q13 */ ) { -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_TEST_ALLIVAS -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE - element_mode = 1; -#else - isIVAS = 1; -#endif -#endif Word16 i, j; #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 memory_fx0, Q_temp, Q_temp2; @@ -6773,11 +6762,7 @@ void elliptic_bpf_48k_generic_fx( IF( !IsUpsampled3 ) { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -6816,11 +6801,7 @@ void elliptic_bpf_48k_generic_fx( ELSE { #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; ) { @@ -6960,11 +6941,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7097,11 +7074,7 @@ void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic L_tmpMax = L_add( 0, 0 ); #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE IF( element_mode ) -#else - IF( isIVAS ) -#endif { FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -7277,11 +7250,7 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE int16_t element_mode -#else - Word16 isIVAS -#endif #endif ) { @@ -7319,11 +7288,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE element_mode, -#else - isIVAS, -#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_3_fx @@ -7339,11 +7304,7 @@ void synthesise_fb_high_band_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE element_mode, -#else - isIVAS, -#endif #endif 1, // IsUpsampled3 excitation_in_interp3, &exp_tmp, tmp, bpf_memory, bpf_memory_Q, full_band_bpf_1_fx ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index c02a6a182..890e0e5c8 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -4646,13 +4646,8 @@ void fb_tbe_dec_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE , st->element_mode -#else - , - 0 -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); @@ -4725,13 +4720,8 @@ void fb_tbe_dec_ivas_fx( /* FB TBE synthesis */ synthesise_fb_high_band_fx( fb_exc, Q_fb_exc, fb_synth, fb_exc_energy, ratio, st->L_frame, st->bfi, &( hBWE_TD->prev_fbbwe_ratio_fx ), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, hb_synth_exp #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE , st->element_mode -#else - , - 1 -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 29ef4427a..4f10d3b02 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7333,11 +7333,7 @@ void fb_tbe_enc_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, -#else - 0, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7475,11 +7471,7 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, -#else - 1, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); @@ -7492,11 +7484,7 @@ void fb_tbe_enc_ivas_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE st->element_mode, -#else - 1, -#endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2_USEELEMENTMODE*/ #endif /*FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2*/ 0, // IsUpsampled3 input_fhb_new + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -- GitLab From e6ccb58bf5362caf51e4fbea2fecef32c878cd5c Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 16 Apr 2025 13:47:40 +0200 Subject: [PATCH 1071/1221] Introduce end-of-line normalization --- .gitattributes | 24 ++++++ lib_com/options.h | 182 +++++++++++++++++++++++----------------------- 2 files changed, 115 insertions(+), 91 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..63eef4d68 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,24 @@ +# Default behavior. Converts all text files to use LF in repository. +* text=auto + +# List all known generic text files +*.c text +*.csv text +*.h text +*.json text +*.m text +*.md text +*.prm text +*.py text +*.txt text + +# Set Windows specific text files to always use CRLF in working tree. +*.bat text eol=crlf +*.cmd text eol=crlf +*.sln text eol=crlf +*.vcxproj text eol=crlf +*.vcxproj.filters text eol=crlf + +# Set Unix specific text files to always use LF (also covers Windows subsystem for Linux) in working tree +*.sh text eol=lf + diff --git a/lib_com/options.h b/lib_com/options.h index 43c3c3038..99d528769 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -1,91 +1,91 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#ifndef OPTIONS_H -#define OPTIONS_H - -/* clang-format off */ - -/* ################### Start DEBUGGING switches ######################## */ - -/*#define DEBUGGING*/ /* Allows debugging message to be printed out during runtime */ -#ifdef DEBUGGING -#define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ -#define DEBUG_MODE_INFO_TWEAK /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */ -#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ -/*#define DEBUG_FORCE_DIR*/ /* Force modes/parameters by reading from external binary files */ -/*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ -#define SUPPORT_FORCE_TCX10_TCX20 /* VA: Enable -force tcx10|tcx20 command-line option */ -#endif - -#define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ - -/*#define WMOPS*/ /* Activate complexity and memory counters */ -#ifdef WMOPS -/*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ -/*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ -/*#define WMOPS_WC_FRAME_ANALYSIS*/ /* Output detailed complexity analysis for the worst-case frame */ -/*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ -#endif - -/* #################### End DEBUGGING switches ############################ */ - -#ifndef BASOP_NOGLOB_DEV_USE_GLOBALS -#define BASOP_NOGLOB_DECLARE_LOCAL -#endif - -#define FIX_867_CLDFB_NRG_SCALE - -#define FIX_1378_ACELP_OUT_OF_BOUNDS - -/* Note: each compile switch (FIX_1101_...) is independent from the other ones */ -//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ -#define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ -#define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ -#define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ -/* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ -#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ -//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version. Obsoleted by MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ -#define HARM_PUSH_BIT -#define HARM_ENC_INIT -//#define HARM_SCE_INIT -#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ -#define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -#define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ - -#define TEST_HR - -#endif +/****************************************************************************************************** + + (C) 2022-2025 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. + +*******************************************************************************************************/ + +/*==================================================================================== + EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 + ====================================================================================*/ + +#ifndef OPTIONS_H +#define OPTIONS_H + +/* clang-format off */ + +/* ################### Start DEBUGGING switches ######################## */ + +/*#define DEBUGGING*/ /* Allows debugging message to be printed out during runtime */ +#ifdef DEBUGGING +#define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ +#define DEBUG_MODE_INFO_TWEAK /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */ +#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ +/*#define DEBUG_FORCE_DIR*/ /* Force modes/parameters by reading from external binary files */ +/*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ +#define SUPPORT_FORCE_TCX10_TCX20 /* VA: Enable -force tcx10|tcx20 command-line option */ +#endif + +#define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ + +/*#define WMOPS*/ /* Activate complexity and memory counters */ +#ifdef WMOPS +/*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ +/*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ +/*#define WMOPS_WC_FRAME_ANALYSIS*/ /* Output detailed complexity analysis for the worst-case frame */ +/*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ +#endif + +/* #################### End DEBUGGING switches ############################ */ + +#ifndef BASOP_NOGLOB_DEV_USE_GLOBALS +#define BASOP_NOGLOB_DECLARE_LOCAL +#endif + +#define FIX_867_CLDFB_NRG_SCALE + +#define FIX_1378_ACELP_OUT_OF_BOUNDS + +/* Note: each compile switch (FIX_1101_...) is independent from the other ones */ +//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +#define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ +#define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ +#define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ +/* Both following 2 macros (IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST*) are independent from each other, they refer to different code blocks */ +#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE /* FhG: reduces WMOPS of param_mc_prm_est, bit-exact to previous version */ +//#define IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE /* FhG: reduces WMOPS of param_mc_prm_est, not bit-exact to previous version. Obsoleted by MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ +#define HARM_PUSH_BIT +#define HARM_ENC_INIT +//#define HARM_SCE_INIT +#define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ +#define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ +#define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ + +#define TEST_HR + +#endif -- GitLab From 1a99d47966f7153faa277303e6244a6214efbe4e Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 11:52:28 +0000 Subject: [PATCH 1072/1221] revert some unnecessary changes --- lib_com/options.h | 3 +-- lib_com/swb_tbe_com_fx.c | 2 -- lib_com/tools_fx.c | 26 +------------------------- lib_dec/ivas_stereo_icbwe_dec_fx.c | 10 ---------- lib_dec/swb_tbe_dec_fx.c | 10 ---------- lib_enc/swb_tbe_enc_fx.c | 12 ++++++------ 6 files changed, 8 insertions(+), 55 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index ed6303e70..c04b0e292 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -53,7 +53,7 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -#define WMOPS /* Activate complexity and memory counters */ +/*#define WMOPS*/ /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ @@ -89,7 +89,6 @@ #define TEST_HR #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ - #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index a3b4bd5c6..98048380e 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7180,10 +7180,8 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } - #endif - memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 6dc1c45f2..5f0e172bf 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -794,37 +794,13 @@ void Copy_Scale_sig_16_32_no_sat( } return; } -#ifdef FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat - L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); - - IF( L_tmp >= 0x7FFF ) - { - FOR( i = 0; i < lg; i++ ) - { - // y[i] = L_mult0(x[i], L_tmp); - y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* Overflow can occur here */ - } - return; - } - // ELSE - { - Word16 tmp = extract_l( L_tmp ); - FOR( i = 0; i < lg; i++ ) - { - y[i] = L_mult( x[i], tmp ); - move32(); - } - } -#else L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) ); - move32(); /* Overflow can occur here */ + move32(); /* saturation can occur here */ } -#endif } void Copy_Scale_sig_32_16( diff --git a/lib_dec/ivas_stereo_icbwe_dec_fx.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c index 772eb2d7d..c7bc98566 100644 --- a/lib_dec/ivas_stereo_icbwe_dec_fx.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -904,9 +904,6 @@ void stereo_icBWE_dec_fx( winSlope_fx = div_s( 1, winLen_fx ); /* Q15 */ alpha_fx = winSlope_fx; /* Q15 */ move16(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - Word16 winSlope_fx_ = sub( 32767 /* 1.0 in Q15*/, winSlope_fx ); -#endif FOR( i = 0; i < winLen_fx; i++ ) { L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); /* Q29 */ @@ -914,17 +911,10 @@ void stereo_icBWE_dec_fx( tmp = shl( round_fx( L_tmp ), 1 ); /* Q14 */ synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); /* Qsyn - 1 */ move32(); -#ifdef FIX_1439_SPEEDUP_stereo_icBWE_dec_fx - if ( LE_16( alpha_fx, winSlope_fx_ ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ - } -#else IF( LE_16( alpha_fx, sub( 32767 /* 1.0 in Q15*/, winSlope_fx ) ) ) { alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } -#endif } FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 890e0e5c8..419d202fc 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7032,24 +7032,14 @@ void ivas_swb_tbe_dec_fx( tmp1 = 0; move16(); - -#ifdef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx - Word32 idx32 = L_shr_r( 0x00333333, 10 ); /*NUM_SHB_SUBFR/L_FRAME16k*/ // Q16 -#endif - FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifndef FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx Word16 idx = 0; move16(); IF( i != 0 ) { idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); } -#else - Word16 idx; - idx = extract_h( imult3216( idx32, i ) ); /*Q0*/ -#endif L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ move16(); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 4f10d3b02..3e1e606f9 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7299,18 +7299,18 @@ void fb_tbe_enc_fx( Word16 ratio; Word16 tmp_vec[L_FRAME48k]; Word16 idxGain; +#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic + Word16 input_fhb_buffer[L_FRAME48k + 4]; + Word16 *input_fhb = &input_fhb_buffer[0] + 4; +#else + Word16 input_fhb[L_FRAME48k]; +#endif Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; -#ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic - Word16 input_fhb_buffer[L_FRAME48k + 4]; - Word16 *input_fhb = &input_fhb_buffer[0] + 4; -#else - Word16 input_fhb[L_FRAME48k]; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move16(); -- GitLab From 939f40786b137a9ff68856fba1faa51ee2b13ddc Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Wed, 16 Apr 2025 14:36:00 +0200 Subject: [PATCH 1073/1221] clang patch --- lib_enc/swb_tbe_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 3e1e606f9..60094c9a0 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7304,7 +7304,7 @@ void fb_tbe_enc_fx( Word16 *input_fhb = &input_fhb_buffer[0] + 4; #else Word16 input_fhb[L_FRAME48k]; -#endif +#endif Word16 Sample_Delay_HP; Word32 fb_exc_energy, temp2; Word32 L_tmp; -- GitLab From 253a399c813055dfa394fe1a3b76857743726e61 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Thu, 17 Apr 2025 07:58:25 +0530 Subject: [PATCH 1074/1221] Fix for MSAN issue in ivas_dirac_dec_render_sf_fx and ivas_dirac_alloc_mem_fx --- lib_dec/ivas_dirac_dec_fx.c | 19 +++++++++++++++++++ lib_rend/ivas_dirac_rend_fx.c | 1 + 2 files changed, 20 insertions(+) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index dd48916cb..10b8059b9 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2185,6 +2185,25 @@ void ivas_dirac_dec_render_sf_fx( move16(); move16(); + + FOR( Word16 i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + set32_fx( Cldfb_RealBuffer_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( Cldfb_ImagBuffer_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + set32_fx( Cldfb_RealBuffer_Binaural_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( Cldfb_RealBuffer_Binaural_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + /* local copies of azi, ele, diffuseness */ Word16 azimuth[CLDFB_NO_CHANNELS_MAX]; Word16 elevation[CLDFB_NO_CHANNELS_MAX]; diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index f67f3761b..5a5f74ee8 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -986,6 +986,7 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirAC_mem->reference_power_len = imult1616( 5, num_freq_bands ); + set16_fx( hDirAC_mem->reference_power_q, Q31, 2 ); } IF( hDirACRend->proto_signal_decorr_on ) -- GitLab From 5a66ba75ce61877ba4e544057da2c4cdfe541678 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Thu, 17 Apr 2025 08:02:02 +0530 Subject: [PATCH 1075/1221] Updates for ivas_analy_sp_fx to improve precision --- lib_enc/analy_sp_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index 4f96ea2d4..57dbb369c 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -634,14 +634,14 @@ void ivas_analy_sp_fx( move32(); Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; // *q_Bin_E move32(); - + Word32 add_const = 21475; // 1e-5 in Q31 FOR( i = 0; i < L_FFT / 2; i++ ) { Bin_E_old[i] = Bin_E[i]; // *q_Bin_E move32(); /* PS[i] = ( Bin_E[i] + 1e-5f + Bin_E[i + L_FFT / 2] + 1e-5f ) / 2.0f; */ - PS[i] = W_extract_h( W_mac_32_32( W_mult_32_32( Bin_E[i], ONE_IN_Q30 ), Bin_E[i + L_FFT / 2], ONE_IN_Q30 ) ); // *q_Bin_E + PS[i] = W_extract_h( W_add( W_mac_32_32( W_mult_32_32( Bin_E[i], ONE_IN_Q30 ), Bin_E[i + L_FFT / 2], ONE_IN_Q30 ), W_shr( W_shl( add_const, 32 ), sub( 31, *q_Bin_E ) ) ) ); // *q_Bin_E move32(); /* Bin_E[i] = (float) ( 10.0f * log( PS[i] ) ); */ -- GitLab From 2d2d72145471d80f47eb7c3e44552b958c1d690c Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Wed, 16 Apr 2025 17:04:44 +0530 Subject: [PATCH 1076/1221] Fix for 3GPP issue 1491: [regression] Encoder crash for MCT-MC 5.1 at 32kHz/SWB in bw_detect_fx() --- lib_enc/bw_detect_fx.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/lib_enc/bw_detect_fx.c b/lib_enc/bw_detect_fx.c index 8a150d514..30382cfba 100644 --- a/lib_enc/bw_detect_fx.c +++ b/lib_enc/bw_detect_fx.c @@ -336,24 +336,33 @@ void bw_detect_fx( sum32 = L_mac0_o( sum32, *pt1, *pt1, &Overflow ); pt1++; } - - IF( LE_32( sum32, 1 ) ) + test(); + test(); + IF( st->element_mode != EVS_MONO && EQ_32( sum32, MAX_32 ) && GT_16( Q_dct, 41 ) /* Any Q-value greater than Q41 for MAX_32 will be less than 0.001*/ ) { - /*deal with zero spectrum*/ - spect_bin[i] = -1; + spect_bin[i] = -6144; /* log10f( 0.00100000005 ) in Q11 */ move16(); } ELSE { - /* spect_bin[i] = (float)log10(spect_bin[i]); - = log2(spect_bin[i])*log10(2); */ - e_tmp = norm_l( sum32 ); - L_tmp = L_shl( sum32, e_tmp ); - f_tmp = Log2_norm_lc( L_tmp ); - e_tmp = sub( sub( 30, e_tmp ), Q_dct ); - L_tmp = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - spect_bin[i] = round_fx( L_shl( L_tmp, 11 ) ); /* Q11 */ - move16(); + IF( LE_32( sum32, 1 ) ) + { + /*deal with zero spectrum*/ + spect_bin[i] = -1; + move16(); + } + ELSE + { + /* spect_bin[i] = (float)log10(spect_bin[i]); + = log2(spect_bin[i])*log10(2); */ + e_tmp = norm_l( sum32 ); + L_tmp = L_shl( sum32, e_tmp ); + f_tmp = Log2_norm_lc( L_tmp ); + e_tmp = sub( sub( 30, e_tmp ), Q_dct ); + L_tmp = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ + spect_bin[i] = round_fx( L_shl( L_tmp, 11 ) ); /* Q11 */ + move16(); + } } } } -- GitLab From 2afc0761a28c8f8ef01c0b0b9b30628a51d3975d Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 17 Apr 2025 15:49:28 +0200 Subject: [PATCH 1077/1221] accept REMOVE_EVS_DUPLICATES --- Workspace_msvc/lib_dec.vcxproj | 3 - Workspace_msvc/lib_dec.vcxproj.filters | 3 - lib_com/bits_alloc_fx.c | 1313 +------------------- lib_com/gs_inact_switching_fx.c | 134 +- lib_com/gs_noisefill_fx.c | 10 +- lib_com/ivas_prot_fx.h | 2 +- lib_com/lsf_tools_fx.c | 220 ++-- lib_com/options.h | 2 - lib_com/prot_fx.h | 602 +++------ lib_com/swb_tbe_com_fx.c | 235 +--- lib_dec/FEC_fx.c | 15 +- lib_dec/FEC_scale_syn_fx.c | 574 +-------- lib_dec/acelp_core_dec_fx.c | 1544 ------------------------ lib_dec/acelp_core_dec_ivas_fx.c | 107 +- lib_dec/acelp_core_switch_dec_fx.c | 12 +- lib_dec/amr_wb_dec_fx.c | 38 +- lib_dec/cng_dec_fx.c | 683 +---------- lib_dec/dec_LPD_fx.c | 4 - lib_dec/dec_ace_fx.c | 30 +- lib_dec/dec_amr_wb_fx.c | 6 +- lib_dec/dec_gen_voic_fx.c | 534 +------- lib_dec/dec_pit_exc_fx.c | 432 +------ lib_dec/dec_post_fx.c | 241 +--- lib_dec/dec_ppp_fx.c | 17 +- lib_dec/dec_tran_fx.c | 12 +- lib_dec/dec_uv_fx.c | 100 +- lib_dec/evs_dec_fx.c | 16 +- lib_dec/fd_cng_dec_fx.c | 593 +-------- lib_dec/gain_dec_fx.c | 390 +----- lib_dec/gs_dec_fx.c | 693 +---------- lib_dec/ivas_core_dec_fx.c | 2 +- lib_dec/ivas_dirac_dec_fx.c | 4 +- lib_dec/ivas_stereo_mdct_core_dec_fx.c | 4 +- lib_dec/ivas_tcx_core_dec_fx.c | 7 +- lib_dec/ivas_td_low_rate_dec_fx.c | 20 +- lib_dec/lsf_dec_fx.c | 276 +---- lib_dec/pit_dec_fx.c | 256 +--- lib_dec/post_dec_fx.c | 18 +- lib_enc/acelp_core_enc_fx.c | 40 +- lib_enc/acelp_core_switch_enc_fx.c | 37 +- lib_enc/analy_lp_fx.c | 150 +-- lib_enc/cod_ace_fx.c | 11 +- lib_enc/enc_gen_voic_fx.c | 23 +- lib_enc/enc_tran_fx.c | 15 +- lib_enc/ivas_core_pre_proc_front_fx.c | 7 +- lib_enc/ivas_core_pre_proc_fx.c | 13 +- lib_enc/ivas_front_vad_fx.c | 6 +- lib_enc/ivas_td_low_rate_enc_fx.c | 4 +- lib_enc/lsf_enc_fx.c | 7 +- lib_enc/pre_proc_fx.c | 14 +- lib_enc/prot_fx_enc.h | 104 +- lib_enc/transition_enc_fx.c | 41 +- 52 files changed, 659 insertions(+), 8965 deletions(-) delete mode 100644 lib_dec/acelp_core_dec_fx.c diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 2d06d29aa..2839a5812 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -139,9 +139,6 @@ false - - false - diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 8a4fc4605..ebf15bd4c 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -119,9 +119,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index e9abb7651..3bfcd0c20 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -434,174 +434,12 @@ static Word16 fcb_table( } /*-------------------------------------------------------------------* - * acelp_FCB_allocator() + * acelp_FCB_allocator_fx() * * Routine to allocate fixed innovation codebook bit-budget *--------------------------------------------------------------------*/ -#ifndef REMOVE_EVS_DUPLICATES -static ivas_error acelp_FCB_allocator( - Word16 *nBits, /* i/o: available bit-budget */ - Word16 fixed_cdk_index[], /* o : codebook index Q0 */ - Word16 nb_subfr, /* i : number of subframes */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 coder_type, /* i : coder type */ - const Word16 tc_subfr, /* i : TC subframe index */ - const Word16 fix_first /* i : flag to indicate whether the first subframe bit-budget was fixed */ -) -{ - Word16 cdbk, sfr, step; - Word16 nBits_tmp; - Word16 *p_fixed_cdk_index; - Word16 max_n; - ivas_error error; - // PMT("Not floating point computation, but fixed point operator are still missing ") - - error = IVAS_ERR_OK; - move32(); - - cdbk = coder_type; /* just to avoid warning when DEBUGGING is deactivated */ - move16(); - - p_fixed_cdk_index = fixed_cdk_index; - - /* TRANSITION coding: first subframe bit-budget was already fixed, glottal pulse not in the first subframe */ - test(); - IF( GE_16( tc_subfr, L_SUBFR ) && fix_first ) - { - Word16 i; - - FOR( i = 0; i < nb_subfr; i++ ) - { - *nBits = sub( *nBits, ACELP_FIXED_CDK_BITS( fixed_cdk_index[i] ) ); - move16(); - } - return error; - } - - /* TRANSITION coding: first subframe bit-budget was already fixed, glottal pulse in the first subframe */ - sfr = 0; - move16(); - IF( fix_first ) - { - *nBits = sub( *nBits, ACELP_FIXED_CDK_BITS( fixed_cdk_index[0] ) ); - move16(); - sfr = 1; - move16(); - p_fixed_cdk_index++; - nb_subfr = 3; - move16(); - } - - /* distribute the bit-budget equally between subframes */ - IF( GT_16( L_subfr, L_SUBFR ) ) /* access fast_FCB_bits_2sfr */ - { - max_n = 6; - move16(); - } - ELSE - { - max_n = ACELP_FIXED_CDK_NB; - move16(); - } - FOR( cdbk = 0; cdbk < max_n; cdbk++ ) - { - IF( GT_32( L_mult0( fcb_table( cdbk, L_subfr ), nb_subfr ), L_deposit_l( *nBits ) ) ) - { - BREAK; - } - } - cdbk = sub( cdbk, 1 ); - -#ifdef DEBUGGING - if ( cdbk < 0 && coder_type != TRANSITION ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too low bit-budget for fixed innovation codebook (frame = %d). Exiting! \n" ); - } - if ( ( L_subfr == L_SUBFR && cdbk >= ACELP_FIXED_CDK_NB ) || ( L_subfr == 2 * L_SUBFR && fcb_table( cdbk, L_subfr ) == 128 /*stop value*/ ) ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too high bit-budget for fixed innovation codebook (frame = %d). Exiting! \n" ); - } -#endif - - set16_fx( p_fixed_cdk_index, cdbk, nb_subfr ); - nBits_tmp = 0; - move16(); - IF( cdbk >= 0 ) - { - nBits_tmp = fcb_table( cdbk, L_subfr ); - } - ELSE - { - nBits_tmp = 0; - move16(); - } - *nBits = sub( *nBits, i_mult( nBits_tmp, nb_subfr ) ); - move16(); - - /* try to increase the FCB bit-budget of the first subframe(s) */ - IF( LT_16( cdbk, ACELP_FIXED_CDK_NB - 1 ) ) - { - step = sub( fcb_table( add( cdbk, 1 ), L_subfr ), nBits_tmp ); - WHILE( *nBits >= step ) - { - ( *p_fixed_cdk_index )++; - *nBits = sub( *nBits, step ); - move16(); - p_fixed_cdk_index++; - } - - /* try to increase the FCB of the first subframe in cases when the next step is lower than the current step */ - step = sub( fcb_table( add( fixed_cdk_index[sfr], 1 ), L_subfr ), fcb_table( fixed_cdk_index[sfr], L_subfr ) ); - test(); - IF( GE_16( *nBits, step ) && cdbk >= 0 ) - { - fixed_cdk_index[sfr] = add( fixed_cdk_index[sfr], 1 ); - move16(); - *nBits = sub( *nBits, step ); - move16(); - test(); - IF( GE_16( *nBits, step ) && EQ_16( fixed_cdk_index[sfr + 1], sub( fixed_cdk_index[sfr], 1 ) ) ) - { - sfr = add( sfr, 1 ); - fixed_cdk_index[sfr] = add( fixed_cdk_index[sfr], 1 ); - move16(); - *nBits = sub( *nBits, step ); - move16(); - } - } - } - /* TRANSITION coding: allocate highest FCBQ bit-budget to the subframe with the glottal-shape codebook */ - IF( GE_16( tc_subfr, L_SUBFR ) ) - { - Word16 tempr; - - SWAP( fixed_cdk_index[0], fixed_cdk_index[tc_subfr / L_SUBFR] ); - - /* TRANSITION coding: allocate second highest FCBQ bit-budget to the last subframe */ - IF( idiv1616( tc_subfr, L_SUBFR ) < sub( nb_subfr, 1 ) ) - { - SWAP( fixed_cdk_index[( tc_subfr - L_SUBFR ) / L_SUBFR], fixed_cdk_index[nb_subfr - 1] ); - } - } - - /* when subframe length > L_SUBFR, number of bits instead of codebook index is signalled */ - IF( GT_16( L_subfr, L_SUBFR ) ) - { - Word16 i, j; - FOR( i = 0; i < nb_subfr; i++ ) - { - j = fixed_cdk_index[i]; - move16(); - fixed_cdk_index[i] = fast_FCB_bits_2sfr[j]; - move16(); - } - } - - return error; -} -#endif -static ivas_error acelp_FCB_allocator_ivas( +static ivas_error acelp_FCB_allocator_fx( Word16 *nBits, /* i/o: available bit-budget */ Word16 fixed_cdk_index[], /* o : codebook index Q0 */ Word16 nb_subfr, /* i : number of subframes */ @@ -754,1141 +592,16 @@ static ivas_error acelp_FCB_allocator_ivas( return error; } + /*-------------------------------------------------------------------* - * config_acelp1() + * config_acelp1_fx() * * Configure ACELP bit allocation * - should be in range of <6700; 24350> for ACELP@12.8kHz * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz *--------------------------------------------------------------------*/ -#ifndef REMOVE_EVS_DUPLICATES -ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ - const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ -) -{ - Word16 i, bits, nb_subfr; - Word16 flag_hardcoded, coder_type_sw, fix_first; - Word32 core_brate; -#ifdef DEBUGGING - (void) active_cnt; -#endif - ivas_error error; - - error = IVAS_ERR_OK; - move32(); - // PMT("Not floating point computation, but fixed point operator are still missing ") - /*-----------------------------------------------------------------* - * Set the flag indicating two-stage Unvoiced (UC) frame - *-----------------------------------------------------------------*/ - - *uc_two_stage_flag = 0; - move16(); - IF( EQ_16( coder_type, UNVOICED ) ) - { - test(); - test(); - test(); - test(); - test(); - if ( GE_32( total_brate, MIN_UNVOICED_TWO_STAGE_BRATE ) && element_mode > EVS_MONO && ( idchan == 0 || ( ( GE_32( total_brate, 8500 ) || extl_brate == 0 ) && EQ_16( tdm_LRTD_flag, 1 ) ) ) ) - { - *uc_two_stage_flag = 1; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Set the number of subframes - *-----------------------------------------------------------------*/ - - IF( EQ_16( L_frame, L_FRAME ) ) - { - nb_subfr = NB_SUBFR; - move16(); - -#ifdef DEBUGGING - if ( ( ( core_brate_inp < 5900 && coder_type > UNVOICED ) && !( core_brate_inp < MIN_TC_BRATE && coder_type == TRANSITION ) ) && !( idchan > 0 && element_mode == IVAS_CPE_TD ) && !( element_mode == IVAS_SCE && tdm_low_rate_mode ) ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too low bitrate (%d bps) for ACELP@12k8 in frame %d. Exiting!\n", core_brate_inp ); - } - - if ( core_brate_inp > ACELP_12k8_HIGH_LIMIT && core == ACELP_CORE ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too high bitrate (%d bps) for ACELP@12k8 in frame %d. Exiting!\n", core_brate_inp ); - } -#endif - } - ELSE /* L_frame == L_FRAME16k */ - { - nb_subfr = NB_SUBFR16k; - move16(); - -#ifdef DEBUGGING - if ( core_brate_inp < ACELP_16k_LOW_LIMIT && core == ACELP_CORE ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too low bitrate (%d bps) for ACELP@16k in frame %d. Exiting!\n", core_brate_inp ); - } -#endif - } - - coder_type_sw = coder_type; - move16(); - IF( core != ACELP_CORE ) - { - /* used in acelp_core_switch_enc() */ - nb_subfr = 1; - move16(); - if ( EQ_16( L_frame, L_FRAME ) ) - { - coder_type_sw = TRANSITION; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Check if the core_brate is hard coded (to keep BE for mono core) or not - *-----------------------------------------------------------------*/ - - flag_hardcoded = 0; - move16(); - i = 0; - move16(); - - WHILE( i < SIZE_BRATE_INTERMED_TBL ) - { - IF( EQ_32( core_brate_inp, brate_intermed_tbl[i] ) ) - { - flag_hardcoded = 1; - move16(); - BREAK; - } - - IF( LT_32( core_brate_inp, brate_intermed_tbl[i] ) ) - { - flag_hardcoded = 0; - move16(); - BREAK; - } - - i = add( i, 1 ); - } - - test(); - test(); - test(); - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( coder_type, AUDIO ) && - LE_32( core_brate_inp, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ - { - i = sub( i, 1 ); - } - - core_brate = brate_intermed_tbl[i]; - move32(); - - if ( element_mode > EVS_MONO ) - { - flag_hardcoded = 0; /* use automatic and flexible ACELP bit-budget allocation */ - move16(); - } - - test(); - if ( ( core != ACELP_CORE ) && ( element_mode == EVS_MONO ) ) /* needed for mode1 core switching in EVS mono */ - { - flag_hardcoded = 1; - move16(); - } - - /*-----------------------------------------------------------------* - * ACELP bit allocation - *-----------------------------------------------------------------*/ - test(); - test(); - IF( !( EQ_16( coder_type, TRANSITION ) && NE_16( tc_subfr, -1 ) ) || EQ_16( enc_dec, DEC ) ) - { - /* Set the bit-budget */ - bits = extract_l( Mpy_32_32( core_brate_inp, ONE_BY_FRAMES_PER_SEC_Q31 ) ); // Q0 - - test(); - test(); - IF( EQ_16( coder_type, TRANSITION ) && EQ_16( enc_dec, DEC ) && EQ_16( tc_call, 1 ) ) - { - bits = add( bits, *nBits_es_Pred ); /* equalize for 4th signaling bit estimated at the encoder in TC_0_192 */ - } - - /* Subtract signalling bits */ - test(); - test(); - IF( EQ_16( enc_dec, DEC ) && EQ_16( idchan, 1 ) && element_mode > EVS_MONO ) - { - bits = sub( bits, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ); - - IF( EQ_16( tdm_LRTD_flag, 1 ) ) - { - bits = add( bits, STEREO_BITS_TCA ); - } - - /* subtract TBE/BWE flag */ - test(); - test(); - test(); - test(); - test(); - test(); - IF( extl_brate > 0 && ( EQ_16( extl, WB_TBE ) || EQ_16( extl, SWB_TBE ) || EQ_16( extl, FB_TBE ) || EQ_16( extl, WB_BWE ) || EQ_16( extl, SWB_BWE ) || EQ_16( extl, FB_BWE ) ) ) - { - bits = sub( bits, 1 ); - } - } - ELSE - { - /* Subtract signalling bits */ - bits = sub( bits, signalling_bits ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( extl_brate > 0 && ( EQ_16( extl, WB_TBE ) || EQ_16( extl, SWB_TBE ) || EQ_16( extl, FB_TBE ) || EQ_16( extl, WB_BWE ) || EQ_16( extl, SWB_BWE ) || EQ_16( extl, FB_BWE ) ) ) - { - /* extension layer signalling bit is counted in the extension layer bitbudget */ - bits = add( bits, 1 ); - } - - /*-----------------------------------------------------------------* - * LSF Q bit-budget - *-----------------------------------------------------------------*/ - test(); - test(); - test(); - IF( !tdm_lp_reuse_flag || idchan == 0 ) - { - /* LSF Q bit-budget */ - acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx( core_brate, coder_type )]; - move16(); - - IF( !flag_hardcoded ) - { - IF( EQ_16( L_frame, L_FRAME ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( element_mode, IVAS_SCE ) && tdm_low_rate_mode ) - { - acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx( core_brate, coder_type )]; - move16(); - } - ELSE IF( ( LT_32( total_brate, 7200 ) || coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( idchan, 1 ) ) - { - /* TD stereo, secondary channel: do nothing */ - acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx( core_brate, coder_type )]; - move16(); - } - ELSE IF( element_mode > EVS_MONO && EQ_16( coder_type, AUDIO ) && LT_32( brate_intermed_tbl[i], ACELP_9k60 ) ) - { - /* primary channel: do nothing */ - } - ELSE IF( element_mode > EVS_MONO && EQ_16( coder_type, AUDIO ) /*&& brate_intermed_tbl[i] >= ACELP_9k60*/ ) - { - acelp_cfg->lsf_bits = 42; - move16(); - } - ELSE IF( LE_32( total_brate, 9600 ) || EQ_16( coder_type, UNVOICED ) ) - { - acelp_cfg->lsf_bits = 31; - move16(); - } - ELSE IF( LE_32( total_brate, 20000 ) ) - { - acelp_cfg->lsf_bits = 36; - move16(); - } - ELSE - { - acelp_cfg->lsf_bits = 41; - move16(); - } - } - ELSE /* L_frame == L_FRAME16k */ - { - acelp_cfg->lsf_bits = 41; - move16(); - } - } - - bits = sub( bits, acelp_cfg->lsf_bits ); - - /* mid-LSF Q bit-budget */ - acelp_cfg->mid_lsf_bits = mid_LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx( core_brate, coder_type )]; - move16(); - - test(); - if ( element_mode > EVS_MONO && EQ_16( coder_type, AUDIO ) /*&& brate_intermed_tbl[i] < ACELP_9k60*/ ) - { - acelp_cfg->mid_lsf_bits = 5; - move16(); - /* primary channel: do nothing */ - } - - bits = sub( bits, acelp_cfg->mid_lsf_bits ); - } - ELSE IF( EQ_16( tdm_lp_reuse_flag, 1 ) && EQ_16( idchan, 1 ) && NE_16( active_cnt, 1 ) ) - { - bits = sub( bits, TDM_IC_LSF_PRED_BITS ); - } - /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || - ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ - ) - { - *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, -1, -1 )]; - move16(); - bits = sub( bits, *nBits_es_Pred ); - } - ELSE IF( *uc_two_stage_flag ) - { - *nBits_es_Pred = 4; - move16(); - bits = sub( bits, *nBits_es_Pred ); - } - } - ELSE - { - bits = *unbits; - move16(); - } - - test(); - IF( EQ_16( coder_type, TRANSITION ) && tc_call == 0 ) - { - *unbits = bits; - return error; - } - - /*-----------------------------------------------------------------* - * Low-rate mode - bits are allocated in tdm_low_rate_enc() - *-----------------------------------------------------------------*/ - test(); - IF( EQ_16( element_mode, IVAS_SCE ) && tdm_low_rate_mode ) - { - acelp_cfg->FEC_mode = 0; - acelp_cfg->ltf_mode = FULL_BAND; - *nBits_es_Pred = 0; - *unbits = 0; - acelp_cfg->ubits = 0; - move16(); - move16(); - move16(); - move16(); - move16(); - - return error; - } - - /*-----------------------------------------------------------------* - * Supplementary information for FEC - *-----------------------------------------------------------------*/ - - acelp_cfg->FEC_mode = 0; - move16(); - test(); - test(); - IF( GE_32( core_brate, ACELP_11k60 ) && ( idchan == 0 || element_mode == EVS_MONO ) ) - { - acelp_cfg->FEC_mode = 1; - move16(); - - test(); - test(); - IF( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) && NE_16( coder_type, VOICED ) ) - { - bits = sub( bits, FEC_BITS_CLS ); - } - - IF( NE_16( coder_type, TRANSITION ) ) - { - IF( GE_32( total_brate, ACELP_16k40 ) ) - { - acelp_cfg->FEC_mode = 2; - move16(); - test(); - IF( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) ) - { - bits = sub( bits, FEC_BITS_ENR ); - } - } - - IF( GE_32( total_brate, ACELP_32k ) ) - { - acelp_cfg->FEC_mode = 3; - move16(); - - test(); - IF( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) ) - { - bits = sub( bits, FEC_BITS_POS ); - } - } - } - } - - /*-----------------------------------------------------------------* - * LP filtering of the adaptive excitation - *-----------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - test(); - test(); - IF( idchan > 0 && element_mode > EVS_MONO ) - { - acelp_cfg->ltf_mode = FULL_BAND; - move16(); - } - ELSE IF( EQ_16( coder_type, UNVOICED ) ) - { - acelp_cfg->ltf_mode = FULL_BAND; - move16(); - } - ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) ) && LT_32( core_brate, ACELP_11k60 ) ) - { - acelp_cfg->ltf_mode = LOW_PASS; - move16(); - } - ELSE IF( GE_32( core_brate, ACELP_11k60 ) && ( NE_16( coder_type, AUDIO ) && !( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME ) ) ) ) - { - test(); - test(); - IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ - { - acelp_cfg->ltf_mode = FULL_BAND; - move16(); - } - ELSE - { - acelp_cfg->ltf_mode = NORMAL_OPERATION; - move16(); - IF( coder_type != TRANSITION ) - { - bits = sub( bits, nb_subfr ); - } - } - } - ELSE - { - acelp_cfg->ltf_mode = FULL_BAND; - move16(); - } - - /*-----------------------------------------------------------------* - * UC bit-budget - *-----------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( EQ_16( coder_type, UNVOICED ) && !( *uc_two_stage_flag ) ) || ( coder_type == INACTIVE && LE_32( core_brate, ACELP_9k60 ) ) ) && ( idchan == 0 || element_mode == EVS_MONO ) ) - { - bits = sub( bits, NBITS_NOISENESS ); /* noiseness */ - } - IF( EQ_16( coder_type, UNVOICED ) && !( *uc_two_stage_flag ) ) - { - bits = sub( bits, 3 * NB_SUBFR ); /* tilt factor */ - } - - /*-----------------------------------------------------------------* - * TC bit-budget - *-----------------------------------------------------------------*/ - - fix_first = 0; - move16(); - IF( EQ_16( coder_type, TRANSITION ) ) - { - if ( EQ_16( tc_call, 2 ) ) - { - fix_first = 1; - move16(); - } - - /* TC signalling */ - IF( EQ_16( L_frame, L_FRAME ) ) - { - IF( EQ_16( tc_subfr, TC_0_0 ) ) - { - IF( enc_dec == ENC ) - { - bits = sub( bits, 1 ); /* TC signalling */ - } - - IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) - { - bits = sub( bits, 3 ); /* LP filtering flag */ - } - } - ELSE IF( EQ_16( tc_subfr, TC_0_64 ) ) - { - IF( enc_dec == ENC ) - { - bits = sub( bits, 4 ); /* TC signalling */ - } - - IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) - { - bits = sub( bits, 3 ); /* LP filtering flag */ - } - } - ELSE IF( EQ_16( tc_subfr, TC_0_128 ) ) - { - IF( enc_dec == ENC ) - { - bits = sub( bits, 4 ); /* TC signalling */ - } - - IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) - { - bits = sub( bits, 2 ); /* LP filtering flag */ - } - } - ELSE IF( EQ_16( tc_subfr, TC_0_192 ) ) - { - IF( enc_dec == ENC ) - { - bits = sub( bits, 3 ); /* TC signalling */ - } - - IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) - { - bits = sub( bits, 1 ); /* LP filtering flag */ - } - } - ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) - { - IF( enc_dec == ENC ) - { - bits = sub( bits, 3 ); /* TC signalling */ - } - - IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) - { - bits = sub( bits, idiv1616( sub( L_FRAME - L_SUBFR, tc_subfr ), L_SUBFR ) ); /* LP filtering flag */ - } - } - ELSE - { - IF( enc_dec == ENC ) - { - bits = sub( bits, 4 ); /* TC signalling */ - } - - IF( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) - { - bits = sub( bits, idiv1616_1( sub( L_FRAME - L_SUBFR, tc_subfr ), L_SUBFR ) ); /* LP filtering flag */ - } - } - } - ELSE /* L_frame == L_FRAME16k */ - { - IF( enc_dec == ENC ) - { - IF( LE_16( tc_subfr, 2 * L_SUBFR ) ) - { - bits = sub( bits, 2 ); /* TC signalling */ - } - ELSE - { - bits = sub( bits, 3 ); /* TC signalling */ - } - } - - // bits -= ( L_FRAME16k - tc_subfr - L_SUBFR ) / L_SUBFR; /* LP filtering flag */ - bits = sub( bits, idiv1616_1( sub( L_FRAME16k - L_SUBFR, tc_subfr ), L_SUBFR ) ); /* LP filtering flag */ - } - - /* glottal-shape codebook bits */ - bits = sub( bits, 3 + 6 + 1 + 3 ); - } - - /*-----------------------------------------------------------------* - * pitch, innovation, gains bit-budget - *-----------------------------------------------------------------*/ - - acelp_cfg->fcb_mode = 0; - move16(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( tdm_low_rate_mode, 1 ) && ( coder_type != INACTIVE ) && NE_16( coder_type, UNVOICED ) ) /* GENERIC low rate mode for secondary channel */ - { - set16_fx( acelp_cfg->pitch_bits, 0, NB_SUBFR16k ); - set16_fx( acelp_cfg->gains_mode, 0, NB_SUBFR16k ); - - FOR( i = 0; i < 2; i++ ) - { - acelp_cfg->pitch_bits[i] = 0; - move16(); - IF( tdm_Pitch_reuse_flag == 0 ) - { - acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX_fx( ACELP_7k20, GENERIC, i_mult( 2 * L_SUBFR, i ), TC_SUBFR2IDX_fx( tc_subfr ) )]; - move16(); - bits = sub( bits, acelp_cfg->pitch_bits[i] ); - } - acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX_fx( ACELP_7k20, GENERIC, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_fx( tc_subfr ) )]; - move16(); - bits = sub( bits, acelp_cfg->gains_mode[i] ); - } - acelp_cfg->fcb_mode = 1; - move16(); - -#ifdef DEBUGGING - if ( bits >= 55 ) - { - printf( "too much bits -> %d, LPC = %d and pitch = %d\n", bits, tdm_lp_reuse_flag, tdm_Pitch_reuse_flag ); - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); - } - else -#endif - IF( GE_16( bits, 16 ) ) - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); - } - ELSE - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); - acelp_cfg->fixed_cdk_index[1] = -1; - move16(); - } - acelp_cfg->fixed_cdk_index[2] = -1; - move16(); - acelp_cfg->fixed_cdk_index[3] = -1; - move16(); - } - ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || /* @12.8kHz core except of GSC */ - ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || - EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ - ) - { - /* pitch Q & gain Q bit-budget - part 2*/ - FOR( i = 0; i < nb_subfr; i++ ) - { - IF( EQ_16( L_frame, L_FRAME ) ) - { - test(); - IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) && EQ_16( idchan, 1 ) ) - { - acelp_cfg->pitch_bits[i] = 0; - move16(); - } - ELSE - { - acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_fx( tc_subfr ) )]; - move16(); - } - acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type_sw, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_fx( tc_subfr ) )]; - move16(); - } - ELSE /* L_frame == L_FRAME16k */ - { - test(); - IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) && EQ_16( idchan, 1 ) ) - { - acelp_cfg->pitch_bits[i] = 0; - move16(); - } - ELSE - { - acelp_cfg->pitch_bits[i] = ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx( core_brate, coder_type, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_16KHZ_fx( tc_subfr ) )]; - move16(); - } - acelp_cfg->gains_mode[i] = gain_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx( core_brate, coder_type_sw, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_16KHZ_fx( tc_subfr ) )]; - move16(); - } - - bits = sub( bits, acelp_cfg->pitch_bits[i] ); - - test(); - IF( coder_type == INACTIVE && EQ_16( acelp_cfg->gains_mode[i], 6 ) /* VQ vs. SQ threshold @32 kbps */ ) - { - bits = sub( bits, 5 ); - } - ELSE - { - if ( EQ_16( *uc_two_stage_flag, 1 ) ) - { - acelp_cfg->gains_mode[i] = 7; - move16(); - } - - bits = sub( bits, acelp_cfg->gains_mode[i] ); - } - } - - /* algebraic codebook bit-budget */ - test(); - test(); - test(); - test(); - test(); - test(); - IF( flag_hardcoded /* EVS */ || - ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || - ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) - { - FOR( i = 0; i < nb_subfr; i++ ) - { - IF( EQ_16( L_frame, L_FRAME ) ) - { - acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_fx( tc_subfr ) )]; - move16(); - } - ELSE /* L_frame == L_FRAME16k */ - { - acelp_cfg->fixed_cdk_index[i] = FCB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx( core_brate, coder_type, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_16KHZ_fx( tc_subfr ) )]; - move16(); - } - bits = sub( bits, acelp_cfg->fixed_cdk_index[i] ); - } - } - ELSE IF( !( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) ) - { - test(); - IF( EQ_16( coder_type, UNVOICED ) && !( *uc_two_stage_flag ) ) - { - i = idiv1616( bits, NB_SUBFR ); - IF( s_and( i, 1 ) == 0 ) - { - i = sub( i, 1 ); /* must be odd */ - } - i = s_min( i, 13 ); -#ifdef DEBUG_MODE_TD - if ( i < 0 ) - IVAS_ERROR( IVAS_ERR_INTERNAL, "ERROR::: UC negative index should not happen at frame %d\n" ); -#endif - i = s_max( i, 0 ); /* If i == 0-> random noise generator will be used as FCB */ - set16_fx( acelp_cfg->fixed_cdk_index, i, NB_SUBFR ); - bits = sub( bits, i_mult( i, NB_SUBFR ) ); - } - ELSE - { - - acelp_cfg->fcb_mode = 1; - move16(); - test(); - test(); - IF( EQ_16( element_mode, IVAS_CPE_TD ) ) - { - IF( GE_16( bits, i_mult( ACELP_FIXED_CDK_BITS( 0 ), ( nb_subfr ) ) ) ) /* enough bits for all fcb */ - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); - } - ELSE IF( GE_16( bits, i_mult( ACELP_FIXED_CDK_BITS( 0 ), sub( nb_subfr, 1 ) ) ) ) - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr - 1, L_SUBFR, coder_type, tc_subfr, fix_first ); - acelp_cfg->fixed_cdk_index[3] = -1; - move16(); - } - ELSE IF( GE_16( bits, i_mult( ACELP_FIXED_CDK_BITS( 0 ), sub( nb_subfr, 2 ) ) ) ) - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 2 ), L_SUBFR, coder_type, tc_subfr, fix_first ); - acelp_cfg->fixed_cdk_index[2] = acelp_cfg->fixed_cdk_index[1]; - move16(); - acelp_cfg->fixed_cdk_index[1] = -1; - move16(); - acelp_cfg->fixed_cdk_index[3] = -1; - move16(); - } - ELSE IF( GE_16( bits, ACELP_FIXED_CDK_BITS( 0 ) ) ) - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 1, L_SUBFR, coder_type, tc_subfr, fix_first ); - acelp_cfg->fixed_cdk_index[1] = acelp_cfg->fixed_cdk_index[0]; - move16(); - acelp_cfg->fixed_cdk_index[0] = -1; - move16(); - acelp_cfg->fixed_cdk_index[2] = -1; - move16(); - acelp_cfg->fixed_cdk_index[3] = -1; - move16(); - } - ELSE /* No FCB */ - { -#ifdef DEBUGGING - IVAS_ERROR( IVAS_ERR_INTERNAL, "WARNING!!!, No bit allocated to FCB, check frame %d\n" ); -#endif - acelp_cfg->fixed_cdk_index[0] = -1; - move16(); - acelp_cfg->fixed_cdk_index[1] = -1; - move16(); - acelp_cfg->fixed_cdk_index[2] = -1; - move16(); - acelp_cfg->fixed_cdk_index[3] = -1; - move16(); - } - } - ELSE IF( NE_16( element_mode, IVAS_CPE_TD ) && GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) - { - bits = 100; /* 9 kbps for fcb */ - move16(); - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); - } - ELSE - { - acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); - } - } - } - - /* AVQ codebook */ - test(); - test(); - test(); - IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || - ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) - { - FOR( i = 0; i < nb_subfr; i++ ) - { - IF( flag_hardcoded ) - { - acelp_cfg->AVQ_cdk_bits[i] = AVQ_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx( core_brate, coder_type, i_mult( i, L_SUBFR ), TC_SUBFR2IDX_16KHZ_fx( tc_subfr ) )]; - move16(); - { - bits = sub( bits, acelp_cfg->AVQ_cdk_bits[i] ); - } - } - - bits = sub( bits, G_AVQ_BITS ); - } - - test(); - test(); - IF( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && LE_32( core_brate_inp, MAX_BRATE_AVQ_EXC_TD ) && EQ_16( coder_type, GENERIC ) ) - { - /* harm. flag ACELP AVQ */ - bits = sub( bits, 1 ); - } - - IF( !flag_hardcoded ) - { - Word16 bit_tmp; - - bit_tmp = idiv1616( bits, nb_subfr ); - set16_fx( acelp_cfg->AVQ_cdk_bits, bit_tmp, nb_subfr ); - bits = sub( bits, i_mult( bit_tmp, nb_subfr ) ); - - bit_tmp = bits % nb_subfr; - move16(); - acelp_cfg->AVQ_cdk_bits[0] = add( acelp_cfg->AVQ_cdk_bits[0], bit_tmp ); - move16(); - bits = sub( bits, bit_tmp ); - } - } - } - ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || - ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || - ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) - { - Word32 Local_BR, Pitch_BR; - Word16 Pitch_CT; - - /* as defined at the beginning of [enc,dec]_pit_exc() */ - test(); - test(); - IF( GSC_IVAS_mode > 0 && ( GSC_noisy_speech || GT_32( core_brate, GSC_H_RATE_STG ) ) ) - { - Local_BR = ACELP_8k00; - move32(); - Pitch_CT = GENERIC; - move16(); - Pitch_BR = ACELP_8k00; - move32(); - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - Local_BR = ACELP_14k80; - move32(); - test(); - if ( GSC_IVAS_mode > 0 && LT_32( core_brate, IVAS_24k4 ) ) - { - Local_BR = ACELP_9k60; - move32(); - } - Pitch_BR = core_brate; - move32(); - } - } - ELSE IF( GSC_noisy_speech ) - { - Local_BR = ACELP_7k20; - move32(); - Pitch_CT = GENERIC; - move16(); - Pitch_BR = ACELP_7k20; - move32(); - if ( EQ_16( L_frame, L_FRAME16k ) ) - { - Pitch_BR = core_brate; - move32(); - } - } - ELSE - { - Local_BR = ACELP_7k20; - move32(); - Pitch_CT = AUDIO; - move16(); - Pitch_BR = core_brate; - move32(); - - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - Local_BR = ACELP_13k20; - move32(); - Pitch_CT = GENERIC; - move16(); - } - } - - FOR( i = 0; i < nb_subfr; i++ ) - { - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - acelp_cfg->pitch_bits[i] = ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx( Pitch_BR, Pitch_CT, i_mult( i, L_SUBFR ), 0 )]; - move16(); - acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX_fx( Local_BR, LOCAL_CT, i_mult( i, L_SUBFR ), 0 )]; - move16(); - } - ELSE - { - acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX_fx( Pitch_BR, Pitch_CT, i_mult( i, L_SUBFR ), 0 )]; - move16(); - acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX_fx( Local_BR, LOCAL_CT, i_mult( i, L_SUBFR ), 0 )]; - move16(); - acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX_fx( ACELP_7k20, LOCAL_CT, i_mult( i, L_SUBFR ), 0 )]; - move16(); - } - } - } - - test(); - test(); - test(); - IF( EQ_16( coder_type, TRANSITION ) && ( EQ_16( tc_call, 1 ) && tc_subfr == 0 && EQ_16( L_frame, L_FRAME ) ) ) - { - return error; - } - - /*-----------------------------------------------------------------* - * unused bits handling - *-----------------------------------------------------------------*/ - - acelp_cfg->ubits = 0; /* these bits could be reused for something else */ - move16(); - - test(); - IF( flag_hardcoded && NE_32( core_brate, PPP_NELP_2k80 ) ) - { - test(); - test(); - /* unused bits */ - IF( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE && LE_32( core_brate, ACELP_24k40 ) ) ) - { - acelp_cfg->ubits = 0; - move16(); - } - ELSE IF( EQ_16( L_frame, L_FRAME ) ) - { - acelp_cfg->ubits = reserved_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, -1, TC_SUBFR2IDX_fx( tc_subfr ) )]; - move16(); - } - ELSE - { - acelp_cfg->ubits = 0; - move16(); - } - - bits = sub( bits, acelp_cfg->ubits ); - } - - /* sanity check */ - test(); - test(); - test(); - IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || EQ_16( nb_subfr, NB_SUBFR16k ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || - ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ - { - acelp_cfg->ubits = 0; - move16(); - } - ELSE IF( flag_hardcoded && core == ACELP_CORE && bits != 0 ) - { -#ifdef DEBUGGING - IVAS_ERROR( IVAS_ERR_INTERNAL, "ERROR: bit-budget incorrect (%d bits) in frame %d.\n", (Word32) bits ); -#endif - } - ELSE IF( bits > 0 && !( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) ) - { - test(); - test(); - test(); - test(); - IF( idchan > 0 && EQ_16( element_mode, IVAS_CPE_TD ) ) - { - IF( !tdm_lp_reuse_flag ) - { - acelp_cfg->lsf_bits = add( acelp_cfg->lsf_bits, bits ); /* increase LSF Q bits */ - move16(); - bits = 0; - move16(); - } - ELSE - { - Word16 nb_prm = 4; - move16(); - if ( EQ_16( tdm_low_rate_mode, 1 ) ) - { - nb_prm = 2; - move16(); - } - /* First add remaining bits on gains */ - bits = sub( bits, allocate_unused( core_brate, coder_type, bits, nb_prm, 0, GAINSPRM, acelp_cfg->gains_mode ) ); - - /* Then, Increase pitch bit budget */ - test(); - IF( tdm_Pitch_reuse_flag == 0 && bits > 0 ) - { - bits = sub( bits, allocate_unused( core_brate, coder_type, bits, nb_prm, 0, PITCHPRM, acelp_cfg->pitch_bits ) ); - } - - /* Increase mid-lsf bit budget */ - test(); - IF( tdm_lp_reuse_flag == 0 && bits > 0 ) - { - bits = sub( bits, allocate_unused( core_brate, coder_type, bits, 1, 0, MID_LSFSPRM, &acelp_cfg->mid_lsf_bits ) ); - bits = sub( bits, allocate_unused( core_brate, coder_type, bits, 1, 0, LSFPRM, &acelp_cfg->lsf_bits ) ); - } - } - -#ifdef DEBUGGING - if ( idchan > 0 && bits > 0 && ( coder_type > UNVOICED || tdm_low_rate_mode == 0 ) ) - { - IVAS_ERROR( IVAS_ERR_INTERNAL, "WARNING !! Unused bits in secondary channel at frame %d\n" ); - } -#endif - } - - ELSE IF( core == ACELP_CORE && GE_16( coder_type, UNVOICED ) && LE_16( coder_type, GENERIC ) && EQ_16( L_frame, L_FRAME ) ) - { - acelp_cfg->lsf_bits = add( acelp_cfg->lsf_bits, bits ); /* increase LSF Q bits */ - move16(); - - test(); - IF( GT_16( acelp_cfg->lsf_bits, 46 ) ) - { - acelp_cfg->ubits = sub( acelp_cfg->lsf_bits, 46 ); - move16(); - acelp_cfg->lsf_bits = 46; - move16(); - } - ELSE IF( GT_16( acelp_cfg->lsf_bits, 42 ) && EQ_16( L_frame, L_FRAME ) ) - { - acelp_cfg->ubits = sub( acelp_cfg->lsf_bits, 42 ); - move16(); - acelp_cfg->lsf_bits = 42; - move16(); - } - } - ELSE - { - acelp_cfg->ubits = bits; - move16(); - } - } - ELSE IF( bits < 0 && !( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) ) - { -#ifdef DEBUGGING - IVAS_ERROR( IVAS_ERR_INTERNAL, "ERROR: bit-budget incorrect (%d bits) in frame %d.\n", (Word32) bits ); -#endif - } - } - - return error; -} - -/*-------------------------------------------------------------------* - * config_acelp1_IVAS() - * - * Configure ACELP bit allocation - * - should be in range of <6700; 24350> for ACELP@12.8kHz - * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz - *--------------------------------------------------------------------*/ -#endif -ivas_error config_acelp1_IVAS( +ivas_error config_acelp1_fx( const Word16 enc_dec, /* i : encoder/decoder flag */ const Word32 total_brate, /* i : total bitrate */ const Word32 core_brate_inp, /* i : core bitrate */ @@ -2511,11 +1224,11 @@ ivas_error config_acelp1_IVAS( IF( GE_16( bits, 16 ) ) { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); } ELSE { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); acelp_cfg->fixed_cdk_index[1] = -1; move16(); } @@ -2634,17 +1347,17 @@ ivas_error config_acelp1_IVAS( { IF( GE_16( bits, imult1616( ACELP_FIXED_CDK_BITS( 0 ), nb_subfr ) ) ) /* enough bits for all fcb */ { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); } ELSE IF( GE_16( bits, imult1616( ACELP_FIXED_CDK_BITS( 0 ), sub( nb_subfr, 1 ) ) ) ) { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 1 ), L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 1 ), L_SUBFR, coder_type, tc_subfr, fix_first ); acelp_cfg->fixed_cdk_index[3] = -1; move16(); } ELSE IF( GE_32( bits, imult1616( ACELP_FIXED_CDK_BITS( 0 ), sub( nb_subfr, 2 ) ) ) ) { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 2 ), L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, sub( nb_subfr, 2 ), L_SUBFR, coder_type, tc_subfr, fix_first ); acelp_cfg->fixed_cdk_index[2] = acelp_cfg->fixed_cdk_index[1]; move16(); acelp_cfg->fixed_cdk_index[1] = -1; @@ -2654,7 +1367,7 @@ ivas_error config_acelp1_IVAS( } ELSE IF( GE_32( bits, ACELP_FIXED_CDK_BITS( 0 ) ) ) { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, 1, L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, 1, L_SUBFR, coder_type, tc_subfr, fix_first ); acelp_cfg->fixed_cdk_index[1] = acelp_cfg->fixed_cdk_index[0]; move16(); acelp_cfg->fixed_cdk_index[0] = -1; @@ -2680,11 +1393,11 @@ ivas_error config_acelp1_IVAS( { bits = 100; /* 9 kbps for fcb */ move16(); - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); } ELSE { - acelp_FCB_allocator_ivas( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); + acelp_FCB_allocator_fx( &bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first ); } } } diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 582fd3c8a..119811275 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -33,144 +33,24 @@ /*------------------------------------------------------------------------*/ /* OUTPUT ARGUMENTS : */ /*------------------------------------------------------------------------*/ - /*------------------------------------------------------------------------*/ /* RETURN ARGUMENTS : */ /* _ None */ /*========================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES -void Inac_swtch_ematch_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 core_brate, /* i : Core bit rate */ - const Word16 Q_exc /* i : input and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode /* i : Last codec mode */ -) -{ - Word16 Ener_per_bd[MBANDS_GN]; - Word16 ftmp; - Word16 *pt_exc; - Word16 j, i; - - Word16 exp, frac; - Word32 L_tmp; - - /*-------------------------------------------------------------------------- - * average energy per band - *--------------------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( coder_type, AUDIO ) && bfi == 0 ) - { - Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1 ); - - /* reset long-term energy per band */ - FOR( i = 0; i < MBANDS_GN; i++ ) - { - lt_ener_per_band[i] = Ener_per_bd[i]; - move16(); - } - } - ELSE IF( EQ_16( coder_type, VOICED ) || EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || ( last_core != ACELP_CORE ) || NE_16( last_codec_mode, MODE1 ) ) - { - /* Find spectrum and energy per band for GC and VC frames */ - edct_16fx( exc2, dct_exc_tmp, L_frame, 5, EVS_MONO ); - - Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1 ); - - /* reset long-term energy per band */ - FOR( i = 0; i < MBANDS_GN; i++ ) - { - lt_ener_per_band[i] = Ener_per_bd[i]; - move16(); - } - } - ELSE IF( ( coder_type == INACTIVE ) && LE_32( core_brate, ACELP_24k40 ) ) - { - /* Find spectrum and energy per band for inactive frames */ - edct_16fx( exc2, dct_exc_tmp, L_frame, 5, EVS_MONO ); - Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1 ); - - /* More agressive smoothing in the first 50 frames */ - pt_exc = dct_exc_tmp; - move16(); - FOR( i = 0; i < MBANDS_GN; i++ ) - { - /* Compute smoothing gain to apply with gain limitation */ - L_tmp = L_mult( ALPHA0_FX, lt_ener_per_band[i] ); /*Q(15+12+1)=Q(28) */ - L_tmp = L_mac( L_tmp, BETA0_FX, Ener_per_bd[i] ); /*Q28 */ - lt_ener_per_band[i] = round_fx( L_tmp ); /*Q12 */ - move16(); - - ftmp = sub( lt_ener_per_band[i], Ener_per_bd[i] ); /*Q12 */ - - /* ftmp = (float)pow(10, ftmp);= pow(2,3.321928*ftmp);*/ - - L_tmp = L_mult( 27213, ftmp ); /*Q(13+12+1)=Q26 ; 27213=3.321928 in Q13 */ - L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ - frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of ftmp */ - ftmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - - exp = sub( exp, 14 ); - IF( LT_16( i, 2 ) ) - { - FOR( j = 0; j < 8; j++ ) - { - L_tmp = L_mult( *pt_exc, ftmp ); /* Q_exc*Q0 -> Q(Q_exc+1) */ - L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ - *pt_exc = round_fx_sat( L_tmp ); - move16(); - pt_exc++; - } - } - ELSE - { - FOR( j = 0; j < 16; j++ ) - { - L_tmp = L_mult( *pt_exc, ftmp ); /* Q_exc*Q0 -> Q(Q_exc+1) */ - L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ - *pt_exc = round_fx_sat( L_tmp ); /*Q_exc*/ - move16(); - pt_exc++; - } - } - } - - /* Going back to time */ - edct_16fx( dct_exc_tmp, exc2, L_frame, 5, EVS_MONO ); - } - - return; -} -#endif -void Inac_switch_ematch_ivas_fx( +void Inac_switch_ematch_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ - const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ const Word16 L_frame, /* i : Frame lenght */ const Word16 Q_exc, /* i : input and output format of exc2 */ const Word16 bfi, /* i : frame lost indicator */ const Word16 last_core, /* i : Last core used */ const Word16 last_codec_mode, /* i : Last codec mode */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const Word16 element_mode /* i : element mode */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 element_mode /* i : element mode */ ) { Word16 Ener_per_bd[MBANDS_GN16k]; @@ -251,7 +131,6 @@ void Inac_switch_ematch_ivas_fx( exp = sub( exp, 14 ); IF( LT_16( i, 2 ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( element_mode, EVS_MONO ) ) { FOR( j = 0; j < 8; j++ ) @@ -264,7 +143,6 @@ void Inac_switch_ematch_ivas_fx( } } ELSE -#endif { FOR( j = 0; j < 8; j++ ) { @@ -278,7 +156,6 @@ void Inac_switch_ematch_ivas_fx( } ELSE { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( element_mode, EVS_MONO ) ) { FOR( j = 0; j < 16; j++ ) @@ -291,7 +168,6 @@ void Inac_switch_ematch_ivas_fx( } } ELSE -#endif { FOR( j = 0; j < 16; j++ ) { @@ -306,9 +182,7 @@ void Inac_switch_ematch_ivas_fx( } /* Going back to time */ -#ifdef REMOVE_EVS_DUPLICATES IF( GT_16( element_mode, EVS_MONO ) ) -#endif { Scale_sig( dct_exc_tmp, 240, 1 ); // Q_exc Scale_sig( exc2, 240, 1 ); // Q_exc diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index 61aa1333c..8488851ac 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -1332,8 +1332,6 @@ void highband_exc_dct_in_ivas_fx( } } - -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( element_mode, EVS_MONO ) ) { Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, *Q_exc ); @@ -1346,7 +1344,6 @@ void highband_exc_dct_in_ivas_fx( } ELSE { -#endif Word16 Q_tmp = *Q_exc; move16(); Word16 Q_old = *Q_exc; @@ -1373,9 +1370,7 @@ void highband_exc_dct_in_ivas_fx( { Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) ); } -#ifdef REMOVE_EVS_DUPLICATES } -#endif /*--------------------------------------------------------------------------------------* * add the correction layer to the LF bins, @@ -1416,12 +1411,9 @@ void highband_exc_dct_in_ivas_fx( Q_hb_exc = 0; move16(); envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, *Q_exc, &Q_hb_exc ); -#ifdef REMOVE_EVS_DUPLICATES + test(); IF( GT_16( *Q_exc, Q_hb_exc ) && GT_16( element_mode, EVS_MONO ) ) -#else - IF( GT_16( *Q_exc, Q_hb_exc ) ) -#endif { Scale_sig( exc_wo_nf, L_frame, sub( Q_hb_exc, *Q_exc ) ); *Q_exc = Q_hb_exc; diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 8da9cd9ac..34c5df3af 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3967,7 +3967,7 @@ ivas_error ivas_core_dec_fx( const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ); -void decod_gen_2sbfr_ivas_fx( +void decod_gen_2sbfr_fx( Decoder_State *st, /* i/o: decoder static memory */ const Word16 sharpFlag, /* i : formant sharpening flag `Q0*/ const Word16 *Aq, /* i : LP filter coefficient Q12*/ diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 5f0b3b57b..a7713b48c 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -2863,40 +2863,39 @@ Word16 qlsf_ARSN_tcvq_Dec_16k_fx( } /*======================================================================*/ -/* FUNCTION : lsf_syn_mem_backup_fx */ +/* FUNCTION : lsf_syn_mem_backup_fx */ /*----------------------------------------------------------------------*/ /* PURPOSE : back-up synthesis filter memory and LSF qunatizer memories */ /*----------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16*) lsp_new : LSP vector to quantize */ -/* _ (Word16*) lsf_new : quantized LSF vector */ -/* _ (Word16*) lsp_mid : mid-frame LSP vector */ -/* _ (Encoder_State) st_fx : Encoder state Structure */ -/*-----------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _None */ -/*-----------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16) clip_var : pitch clipping state var */ -/* _ (Word16*) mem_AR : quantizer memory for AR model */ -/* _ (Word16*) mem_MA : quantizer memory for MA model */ -/* _ (Word16*) lsp_new_bck : LSP vector to quantize- backup */ -/* _ (Word16*) lsf_new_bck : quantized LSF vector - backup */ -/* _ (Word16*) lsp_mid_bck : mid-frame LSP vector - backup */ +/* INPUT ARGUMENTS : */ +/* _ (Word16*) lsp_new : LSP vector to quantize */ +/* _ (Word16*) lsf_new : quantized LSF vector */ +/* _ (Word16*) lsp_mid : mid-frame LSP vector */ +/* _ (Encoder_State) st_fx : Encoder state Structure */ +/*----------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _None */ +/*----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16) clip_var : pitch clipping state var */ +/* _ (Word16*) mem_AR : quantizer memory for AR model */ +/* _ (Word16*) mem_MA : quantizer memory for MA model */ +/* _ (Word16*) lsp_new_bck : LSP vector to quantize- backup */ +/* _ (Word16*) lsf_new_bck : quantized LSF vector - backup */ +/* _ (Word16*) lsp_mid_bck : mid-frame LSP vector - backup */ /* _ (Word16) mCb1 :counter for stationary frame after a transition frame */ -/* _ (Word32*) Bin_E : FFT Bin energy 128 *2 sets */ -/* _ (Word32*) Bin_E_old : FFT Bin energy 128 *2 sets */ -/* _ (Word16*) mem_syn_bck : synthesis filter memory */ -/* _ (Word16) mem_w0_bck : memory of the weighting filter */ -/* _ (Word16) streaklimit : LSF quantizer */ -/* _ (Word16) pstreaklen : LSF quantizer */ -/*-----------------------------------------------------------------------*/ - -/* _ None */ -/*-----------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*=======================================================================*/ +/* _ (Word32*) Bin_E : FFT Bin energy 128 *2 sets */ +/* _ (Word32*) Bin_E_old : FFT Bin energy 128 *2 sets */ +/* _ (Word16*) mem_syn_bck : synthesis filter memory */ +/* _ (Word16) mem_w0_bck : memory of the weighting filter */ +/* _ (Word16) streaklimit : LSF quantizer */ +/* _ (Word16) pstreaklen : LSF quantizer */ +/*----------------------------------------------------------------------*/ +/* _ None */ +/*----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================*/ void lsf_syn_mem_backup_fx( Encoder_State *st_fx, /* o: state structure */ @@ -2904,23 +2903,22 @@ void lsf_syn_mem_backup_fx( Word32 *gc_threshold_fx, /* i: Q16 */ Word16 *clip_var_bck_fx, /* i: Q(2.56), Q14, Q7, Q0, Q14, Q14 */ Word16 *next_force_sf_bck_fx, /* i: */ - - Word16 *lsp_new, /* o: LSP vector to quantize Q15 */ - Word16 *lsf_new, /* i: quantized LSF vector Q15 */ - Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */ - Word16 *clip_var, /* i: pitch clipping state var Q(2.56) */ - Word16 *mem_AR, /* i: quantizer memory for AR model 2.56 */ - Word16 *mem_MA, /* i: quantizer memory for MA model 2.56 */ - Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */ - Word16 *lsf_new_bck, /* o: quantized LSF vector - backup Q15 */ - Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */ - Word16 *mCb1, /* o: counter for stationary frame after a transition frame */ - Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets q_bin */ - Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets q_bin */ - Word16 *mem_syn_bck, /* i: synthesis filter memory q */ - Word16 *mem_w0_bck, /* i: memory of the weighting filter q */ - Word16 *streaklimit, /* i:LSF quantizer Q15 */ - Word16 *pstreaklen /* i:LSF quantizer */ + Word16 *lsp_new, /* o: LSP vector to quantize Q15 */ + Word16 *lsf_new, /* i: quantized LSF vector Q15 */ + Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */ + Word16 *clip_var, /* i: pitch clipping state var Q(2.56) */ + Word16 *mem_AR, /* i: quantizer memory for AR model 2.56 */ + Word16 *mem_MA, /* i: quantizer memory for MA model 2.56 */ + Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */ + Word16 *lsf_new_bck, /* o: quantized LSF vector - backup Q15 */ + Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */ + Word16 *mCb1, /* o: counter for stationary frame after a transition frame */ + Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets q_bin */ + Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets q_bin */ + Word16 *mem_syn_bck, /* i: synthesis filter memory q */ + Word16 *mem_w0_bck, /* i: memory of the weighting filter q */ + Word16 *streaklimit, /* i:LSF quantizer Q15 */ + Word16 *pstreaklen /* i:LSF quantizer */ ) { Word16 i; @@ -2985,25 +2983,31 @@ void lsf_syn_mem_backup_fx( return; } + +/*-------------------------------------------------------------------* + * lsf_syn_mem_backup_fx() + * + * + *--------------------------------------------------------------------*/ + void lsf_syn_mem_backup_ivas_fx( Encoder_State *st_fx, /* i: state structure */ Word16 *btilt_code_fx, /* i: tilt code Q15 */ Word32 *gc_threshold_fx, /* i: Q16 */ Word16 *clip_var_bck_fx, /* o: Q(2.56), Q14, Q7, Q0, Q14, Q14 */ Word16 *next_force_sf_bck_fx, /* o: */ - - Word16 *lsp_new, /* i: LSP vector to quantize Q15 */ - Word16 *lsp_mid, /* i: mid-frame LSP vector Q15 */ - Word16 *clip_var, /* o: pitch clipping state var Q(2.56) */ - Word16 *mem_AR, /* o: quantizer memory for AR model Q(2.56) */ - Word16 *mem_MA, /* o: quantizer memory for AR model Q(2.56) */ - Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup Q15 */ - Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup Q15 */ - Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */ - Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */ - Word16 *mem_syn_bck, /* o: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */ - Word16 *mem_w0_bck, /* o: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */ - Word16 *streaklimit, /* Q15 */ + Word16 *lsp_new, /* i: LSP vector to quantize Q15 */ + Word16 *lsp_mid, /* i: mid-frame LSP vector Q15 */ + Word16 *clip_var, /* o: pitch clipping state var Q(2.56) */ + Word16 *mem_AR, /* o: quantizer memory for AR model Q(2.56) */ + Word16 *mem_MA, /* o: quantizer memory for AR model Q(2.56) */ + Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup Q15 */ + Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup Q15 */ + Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */ + Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */ + Word16 *mem_syn_bck, /* o: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */ + Word16 *mem_w0_bck, /* o: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */ + Word16 *streaklimit, /* Q15 */ Word16 *pstreaklen ) { Word16 i; @@ -3079,66 +3083,68 @@ void lsf_update_memory( move16(); mem_MA[i] = sub( sub( qlsf[i], lsf_means[narrowband][i] ), mult_r( MU_MA_FX, old_mem_MA[i] ) ); } + + return; } + /*======================================================================*/ -/* FUNCTION : lsf_syn_mem_restore_fx */ +/* FUNCTION : lsf_syn_mem_restore_fx */ /*----------------------------------------------------------------------*/ /* PURPOSE : restore synthesis filter memory and LSF quantizer memories*/ /*----------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16) clip_var : pitch clipping state var */ -/* _ (Word16*) mem_AR : quantizer memory for AR model */ -/* _ (Word16*) mem_MA : quantizer memory for MA model */ -/* _ (Word16*) lsp_new_bck : LSP vector to quantize- backup */ -/* _ (Word16*) lsf_new_bck : quantized LSF vector - backup */ -/* _ (Word16*) lsp_mid_bck : mid-frame LSP vector - backup */ +/* INPUT ARGUMENTS : */ +/* _ (Word16) clip_var : pitch clipping state var */ +/* _ (Word16*) mem_AR : quantizer memory for AR model */ +/* _ (Word16*) mem_MA : quantizer memory for MA model */ +/* _ (Word16*) lsp_new_bck : LSP vector to quantize- backup */ +/* _ (Word16*) lsf_new_bck : quantized LSF vector - backup */ +/* _ (Word16*) lsp_mid_bck : mid-frame LSP vector - backup */ /* _ (Word16) mCb1 :counter for stationary frame after a transition frame */ -/* _ (Word32*) Bin_E : FFT Bin energy 128 *2 sets */ -/* _ (Word32*) Bin_E_old : FFT Bin energy 128 *2 sets */ -/* _ (Word16*) mem_syn_bck : synthesis filter memory */ -/* _ (Word16) mem_w0_bck : memory of the weighting filter */ -/* _ (Word16) streaklimit : LSF quantizer */ -/* _ (Word16) pstreaklen : LSF quantizer */ -/*-----------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _None */ -/*-----------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16*) lsp_new : LSP vector to quantize */ -/* _ (Word16*) lsf_new : quantized LSF vector */ -/* _ (Word16*) lsp_mid : mid-frame LSP vector */ -/* _ (Encoder_State) st_fx : Encoder state Structure */ -/*-----------------------------------------------------------------------*/ - -/* _ None */ -/*-----------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*=======================================================================*/ +/* _ (Word32*) Bin_E : FFT Bin energy 128 *2 sets */ +/* _ (Word32*) Bin_E_old : FFT Bin energy 128 *2 sets */ +/* _ (Word16*) mem_syn_bck : synthesis filter memory */ +/* _ (Word16) mem_w0_bck : memory of the weighting filter */ +/* _ (Word16) streaklimit : LSF quantizer */ +/* _ (Word16) pstreaklen : LSF quantizer */ +/*----------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _None */ +/*----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) lsp_new : LSP vector to quantize */ +/* _ (Word16*) lsf_new : quantized LSF vector */ +/* _ (Word16*) lsp_mid : mid-frame LSP vector */ +/* _ (Encoder_State) st_fx : Encoder state Structure */ +/*----------------------------------------------------------------------*/ +/* _ None */ +/*----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================*/ + void lsf_syn_mem_restore_fx( Encoder_State *st_fx, /* o: state structure */ Word16 btilt_code_fx, /* i: Q15 */ Word32 gc_threshold_fx, /* i: Q16 */ Word16 *clip_var_bck_fx, /* i: Q(2.56), Q14, Q7, Q0, Q14, Q14 */ Word16 next_force_sf_bck_fx, /* i: */ - - Word16 *lsp_new, /* o: LSP vector to quantize Q15 */ - Word16 *lsf_new, /* o: quantized LSF vector Q15 */ - Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */ - Word16 clip_var, /* i: pitch clipping state var Q(2.56) */ - Word16 *mem_AR, /* i: quantizer memory for AR model Q15 */ - Word16 *mem_MA, /* i: quantizer memory for MA model Q15 */ - Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */ - Word16 *lsf_new_bck, /* i: quantized LSF vector - backup Q15 */ - Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */ - Word16 mCb1, /* i: counter for stationary frame after a transition frame */ - Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */ - Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */ - Word16 *mem_syn_bck, /* i: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */ - Word16 mem_w0_bck, /* i: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */ - Word16 streaklimit, /* i:LSF quantizer Q15 */ - Word16 pstreaklen /* i:LSF quantizer */ + Word16 *lsp_new, /* o: LSP vector to quantize Q15 */ + Word16 *lsf_new, /* o: quantized LSF vector Q15 */ + Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */ + Word16 clip_var, /* i: pitch clipping state var Q(2.56) */ + Word16 *mem_AR, /* i: quantizer memory for AR model Q15 */ + Word16 *mem_MA, /* i: quantizer memory for MA model Q15 */ + Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */ + Word16 *lsf_new_bck, /* i: quantized LSF vector - backup Q15 */ + Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */ + Word16 mCb1, /* i: counter for stationary frame after a transition frame */ + Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */ + Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */ + Word16 *mem_syn_bck, /* i: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */ + Word16 mem_w0_bck, /* i: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */ + Word16 streaklimit, /* i:LSF quantizer Q15 */ + Word16 pstreaklen /* i:LSF quantizer */ ) { Word16 i; diff --git a/lib_com/options.h b/lib_com/options.h index daa609ed4..86b786588 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -95,6 +95,4 @@ #define TEST_HR -#define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions, ACELP low-band decoder */ - #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index e4d9b3dab..07e9dbdb1 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3286,67 +3286,33 @@ void synthesise_fb_high_band_fx( Word16 bpf_memory_Q[], Word16 Qout ); -#ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( - const Word16 L_frame_fx, /* i : length of the frame */ -#ifdef ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif - const Word16 i_subfr_fx, /* i : subframe index */ - const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ - const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ - const Word16 code_fx[], /* i : algebraic excitation Q9*/ - const Word16 voice_fac_fx, /* i : voicing factor Q15*/ - Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ - Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ - const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ - const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - Word16 T0, /* i : integer pitch variables Q0 */ - Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - Word32 core_brate /* i :core bitrate */ -#ifdef ADD_IVAS_TBE_CODE - , - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif -); -#endif - -void prep_tbe_exc_ivas_fx( - const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif - const Word16 i_subfr_fx, /* i : subframe index */ - const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ - const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ - const Word16 code_fx[], /* i : algebraic excitation Q9*/ - const Word16 voice_fac_fx, /* i : voicing factor Q15*/ - Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ - Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ - const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ - const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - Word16 T0, /* i : integer pitch variables Q0 */ - Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE - , /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif -); - -Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ - const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ - Word16 *tilt_mem /* i/o: Tilt smoothing memory */ + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 i_subfr_fx, /* i : subframe index */ + const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ + const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 voice_fac_fx, /* i : voicing factor Q15*/ + Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ + Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ + const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ + const Word16 code_preQ_fx[], /* i : prequantizer excitation */ + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + Word16 T0, /* i : integer pitch variables Q0 */ + Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +); + +/*! r: Formant filter strength [0,1] */ +Word16 swb_formant_fac_fx( + const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ + Word16 *tilt_mem /* i/o: Tilt smoothing memory */ ); void wb_tbe_extras_reset_fx( @@ -4858,35 +4824,6 @@ Word16 BITS_ALLOC_config_acelp( const Word16 narrowband, const Word16 nb_subfr ); -#ifndef REMOVE_EVS_DUPLICATES -ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ - const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ - const Word16 tc_subfr, /* i : TC subfr ID */ - const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ - Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - Word16 *unbits, /* o : number of unused bits */ - const Word16 element_mode, /* i : element mode */ - Word16 *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const Word16 idchan, /* i : stereo channel ID */ - const Word16 active_cnt, /* i : Active frame counter */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ - const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ -); -#endif Word16 set_ACELP_flag( const Word16 element_mode, /* i : element mode */ const Word32 element_brate, /* i : element bitrate */ @@ -5833,35 +5770,19 @@ void tcx_ltp_post_fx32( Word32 *tcx_buf, /* sig_q */ Word16 sig_q ); -#ifndef REMOVE_EVS_DUPLICATES -// gs_inact_switching_fx.c -void Inac_swtch_ematch_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 core_brate, /* i : Core bit rate */ - const Word16 Q_exc, /* i : i and output format of exc2 */ - const Word16 bfi, /* i : frame lost indicator */ - const short last_core, /* i : Last core used */ - const short last_codec_mode /* i : Last codec mode */ -); -#endif - -void Inac_switch_ematch_ivas_fx( +void Inac_switch_ematch_fx( Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ - const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ const Word16 L_frame, /* i : Frame lenght */ const Word16 Q_exc, /* i : input and output format of exc2 */ const Word16 bfi, /* i : frame lost indicator */ const Word16 last_core, /* i : Last core used */ const Word16 last_codec_mode, /* i : Last codec mode */ - const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const Word16 element_mode /* i : element mode */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 element_mode /* i : element mode */ ); // igf_base_fx.c @@ -6094,32 +6015,16 @@ void td_bwe_dec_init_fx( const Word32 output_Fs /* i : output sampling rate */ ); -#ifndef REMOVE_EVS_DUPLICATES -// lsf_dec_fx.c void lsf_dec_fx( - Decoder_State *st_fx, /* i/o: State structure */ - const Word16 tc_subfr, /* i : TC subframe index Q0*/ - Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ - Word16 *LSF_Q_prediction, /* o : LSF prediction mode Q0*/ - Word16 *lsf_new, /* o : de-quantized LSF vector Q(x2.56)*/ - Word16 *lsp_new, /* o : de-quantized LSP vector Q15*/ - Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector Q15*/ - const Word16 tdm_low_rate_mode /* i : secondary channel low rate mode flag Q0*/ - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ -); -#endif -void lsf_dec_ivas_fx( - Decoder_State *st_fx, /* i/o: State structure */ - const Word16 tc_subfr, /* i : TC subframe index Q0*/ - Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ - Word16 *LSF_Q_prediction, /* o : LSF prediction mode Q0*/ - Word16 *lsf_new, /* o : de-quantized LSF vector Q(x2.56)*/ - Word16 *lsp_new, /* o : de-quantized LSP vector Q15*/ - Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector Q15*/ - const Word16 tdm_low_rate_mode /* i : secondary channel low rate mode flag Q0*/ - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ + Decoder_State *st_fx, /* i/o: State structure */ + const Word16 tc_subfr, /* i : TC subframe index Q0*/ + Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ + Word16 *LSF_Q_prediction, /* o : LSF prediction mode Q0*/ + Word16 *lsf_new, /* o : de-quantized LSF vector Q(x2.56)*/ + Word16 *lsp_new, /* o : de-quantized LSP vector Q15*/ + Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector Q15*/ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag Q0*/ + const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ ); /*! r: index of the maximum value in the input vector */ @@ -6264,21 +6169,9 @@ void lsf_mid_dec_fx( Word16 lsp_mid[] /* o : quantized LSPs Q15*/ ); -#ifndef REMOVE_EVS_DUPLICATES -// cng_dec_fx.c void CNG_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ - const Word16 last_element_mode, /* i : last element mode Q0 */ - Word16 Aq[], /* o : LP coefficients Q12 */ - Word16 *lsp_new, /* i/o: current frame LSPs Q15 */ - Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */ - Word16 *allow_cn_step, /* o : allow CN step Q0 */ - Word16 *sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0 */ - Word32 *q_env ); -#endif -void CNG_dec_ivas_fx( - Decoder_State *st_fx, /* i/o: State structure */ - const Word16 last_element_mode, /* i : last element mode Q0 */ + const Word16 last_element_mode, /* i : last element mode Q0 */ Word16 Aq[], /* o : LP coefficients Q12 */ Word16 *lsp_new, /* i/o: current frame LSPs Q15 */ Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */ @@ -6688,12 +6581,12 @@ void hf_synth_amr_wb_fx( // dec_post_fx void Init_post_filter_fx( PFSTAT_HANDLE hPFstat /* i : core decoder parameters */ -); /* (i) : core decoder parameters */ +); /* i : core decoder parameters */ void nb_post_filt_fx( const Word16 L_frame, /* i : frame length */ - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *psf_lp_noise, /* i : Long term noise Q8 */ const Word16 tmp_noise, /* i : noise energy Q0 */ Word16 *Synth, /* i : 12k8 synthesis Qsyn */ @@ -6704,27 +6597,15 @@ void nb_post_filt_fx( const Word16 disable_hpf /* i : flag to diabled HPF */ ); -#ifndef REMOVE_EVS_DUPLICATES void formant_post_filt_fx( - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ - Word16 *synth_in, /* i : 12k8 synthesis */ - Word16 *Aq, /* i : LP filter coefficient */ - Word16 *synth_out, /* i/o: i signal */ - Word16 L_frame, - Word32 lp_noise, /* (i) : background noise energy (15Q16) */ - Word32 rate, /* (i) : bit-rate */ - const Word16 off_flag /* i : off flag */ -); -#endif -void formant_post_filt_ivas_fx( - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *synth_in, /* i : 12k8 synthesis */ - Word16 *Aq, /* i : LP filter coefficient */ - Word16 *synth_out, /* i/o: i signal */ - Word16 L_frame, - Word32 lp_noise, /* (i) : background noise energy (15Q16) */ - Word32 rate, /* (i) : bit-rate */ - const Word16 off_flag /* i : off flag */ + Word16 *Aq, /* i : LP filter coefficient Q12 */ + Word16 *synth_out, /* i/o: input signal */ + const Word16 L_frame, /* i : frame length */ + const Word32 lp_noise, /* (i) : background noise energy (15Q16) */ + const Word32 brate, /* (i) : bit-rate */ + const Word16 off_flag /* i : off flag */ ); void Filt_mu_fx( Word16 *sig_in, /* i : signal (beginning at sample -1) */ @@ -6890,65 +6771,34 @@ void PulseResynchronization_fx( Word32 /*float*/ const pitchEnd /*i Q16*/ ); -#ifndef REMOVE_EVS_DUPLICATES -// gs_dec_fx.c void decod_audio_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ - const Word16 *Aq, /* i : LP filter coefficient Q12*/ - Word16 *pitch_buf, /* o : floating pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors Q15*/ - Word16 *exc, /* i/o: adapt. excitation exc Q_exc*/ - Word16 *exc2, /* i/o: adapt. excitation/total exc Q_exc*/ - Word16 *bwe_exc, /* o : excitation for SWB TBE Q_exc*/ - Word16 *lsf_new /* i : ISFs at the end of the frame Qx*/ - , - Word16 *gain_buf /*Q14*/ -); -#endif -void decod_audio_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ - const Word16 *Aq, /* i : LP filter coefficient Q12*/ - Word16 *pitch_buf, /* o : Word16 pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors Q15*/ - Word16 *exc, /* i/o: adapt. excitation exc Q_exc*/ - Word16 *exc2, /* i/o: adapt. excitation/total exc Q_exc*/ - Word16 *bwe_exc, /* o : excitation for SWB TBE Q_exc*/ - Word16 *lsf_new /* i : ISFs at the end of the frame Qx*/ - , - Word16 *gain_buf, /*Q14*/ + Decoder_State *st_fx, /* i/o: decoder static memory */ + Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ + const Word16 *Aq, /* i : LP filter coefficient Q12*/ + Word16 *pitch_buf, /* o : Word16 pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *exc, /* i/o: adapt. excitation exc Q_exc*/ + Word16 *exc2, /* i/o: adapt. excitation/total exc Q_exc*/ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_exc*/ + Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/ const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag Q0*/ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag Q0*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6*/ ); -#ifndef REMOVE_EVS_DUPLICATES void gsc_dec_fx( - Decoder_State *st_fx, /* i/o: State structure */ - Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ - const Word16 pit_band_idx, /* i : bin position of the cut-off frequency Q0*/ - const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral) Q0*/ - const Word16 bits_used, /* i : Number of bit used before frequency Q Q0*/ - const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ - const Word16 coder_type, /* i : coding type Q0*/ - Word16 *last_bin, /* i : last bin of bit allocation Q0*/ - const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ - Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ - Word16 Q_exc ); -#endif -void gsc_dec_ivas_fx( - Decoder_State *st_fx, /* i/o: State structure */ - Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ + Decoder_State *st_fx, /* i/o: State structure */ + Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ const Word16 pit_band_idx, /* i : bin position of the cut-off frequency ` Q0*/ const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral) Q0*/ const Word16 bits_used, /* i : Number of bit used before frequency Q Q0*/ const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ const Word16 coder_type, /* i : coding type Q0*/ Word16 *last_bin, /* i : last bin of bit allocation Q0*/ - const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ - Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ + const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ + Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ Word16 *Q_exc ); void GSC_dec_init( @@ -6959,18 +6809,15 @@ void GSC_dec_init_ivas_fx( GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ ); - -// gain_dec_fx.c - void Es_pred_dec_fx( - Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/ - const Word16 enr_idx, /* i : indice */ - const Word16 nb_bits, /* i : number of bits */ - const Word16 no_ltp /* i : no LTP flag */ + Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/ + const Word16 enr_idx, /* i : indice */ + const Word16 nb_bits, /* i : number of bits */ + const Word16 no_ltp /* i : no LTP flag */ ); void gain_dec_tc_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ + Decoder_State *st_fx, /* i/o: decoder state structure */ const Word16 *code_fx, /* i : algebraic code excitation */ const Word16 i_subfr_fx, /* i : subframe number */ const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ @@ -7005,7 +6852,6 @@ void gain_dec_mless_fx( Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excitation Q16*/ ); -#ifndef REMOVE_EVS_DUPLICATES void gain_dec_lbr_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ const Word16 coder_type, /* i : coding type */ @@ -7016,25 +6862,8 @@ void gain_dec_lbr_fx( Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ Word32 gc_mem[], /* i/o: gain_code from previous subframes */ - Word16 gp_mem[] /* i/o: gain_pitch from previous subframes */ - , - const Word16 L_subfr /* i : subfr lenght */ -); -#endif - -void gain_dec_lbr_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word16 coder_type, /* i : coding type */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *code_fx, /* i : algebraic excitation Q9 */ - Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/ - Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ - Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ - Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ - Word32 gc_mem[], /* i/o: gain_code from previous subframes */ - Word16 gp_mem[] /* i/o: gain_pitch from previous subframes */ - , - const Word16 L_subfr /* i : subfr lenght */ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ + const Word16 L_subfr /* i : subfr lenght */ ); void lp_gain_updt_fx( @@ -7055,13 +6884,14 @@ void lp_gain_updt_ivas_fx( const Word16 L_frame /* i : length of the frame */ ); -Word32 gain_dec_gaus_fx( /* o : quantized codebook gain Q16 */ - Word16 index, /* i : quantization index */ - const Word16 bits, /* i : number of bits to quantize */ - const Word16 lowBound, /* i : lower bound of quantizer (dB) */ - const Word16 topBound, /* i : upper bound of quantizer (dB) */ - const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */ - Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */ +/*! r: quantized codebook gain Q16 */ +Word32 gain_dec_gaus_fx( + Word16 index, /* i : quantization index */ + const Word16 bits, /* i : number of bits to quantize */ + const Word16 lowBound, /* i : lower bound of quantizer (dB) */ + const Word16 topBound, /* i : upper bound of quantizer (dB) */ + const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */ + Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */ ); void gain_dec_SQ_fx( @@ -7155,23 +6985,7 @@ void re8_PPV_fx( Word16 y[] /* o : point in RE8 (8-dimensional integer vector) Q0 */ ); -#ifndef REMOVE_EVS_DUPLICATES -// dec_pit_exc_fx.c void dec_pit_exc_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 coder_type, /* i : coding type */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *code_fx, /* o : innovation */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 nb_subfr_fx /* i : Number of subframe considered */ - , - Word16 *gain_buf /*Q14*/ -); -#endif -void dec_pit_exc_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* i : LP filter coefficient */ const Word16 coder_type, /* i : coding type */ @@ -7181,7 +6995,7 @@ void dec_pit_exc_ivas_fx( Word16 *exc_fx, /* i/o: adapt. excitation exc */ Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ const Word16 nb_subfr_fx, /* i : Number of subframe considered */ - Word16 *gain_buf, /*Q14*/ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ); @@ -7225,24 +7039,8 @@ void Mode2_delta_pit_dec( Word16 **pt_indice /* i/o: pointer to Vector of Q indexes */ ); -#ifndef REMOVE_EVS_DUPLICATES -Word16 pit_decode_fx( /* o : floating pitch value */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - Word16 *T0, /* o : close loop integer pitch */ - Word16 *T0_frac, /* o : close loop fractional part of the pitch */ - Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ - Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const Word16 L_subfr /* i : subframe length */ -); -#endif /* o : floating pitch value */ -Word16 pit_decode_ivas_fx( +Word16 pit_decode_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ const Word32 core_brate, /* i : core bitrate */ const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ @@ -7603,22 +7401,7 @@ void configureFdCngDec_fx( const Word16 Last_L_frame, const Word16 element_mode ); -#ifndef REMOVE_EVS_DUPLICATES -/* Apply the CLDFB-based CNG */ Word16 ApplyFdCng_fx( - Word16 *timeDomainInput, /* i : pointer to time domain i */ - Word16 Q, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - Word16 *powerSpectrum, -#endif - Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer */ - Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer */ - Word16 *cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */ - Decoder_State *st, - const Word16 concealWholeFrame, /* i : binary flag indicating frame loss */ - Word16 is_music ); -#endif -Word16 ApplyFdCng_ivas_fx( Word16 *timeDomainInput, /* i : pointer to time domain input */ Word16 Q, Word32 *powerSpectrum, @@ -8210,14 +7993,11 @@ void FEC_pitch_estim_fx( const Word32 old_pitch_buf[], /* i : buffer of old subframe pitch values 15Q16 */ Word16 *bfi_pitch, /* i/o: update of the estimated pitch for FEC */ Word16 *bfi_pitch_frame, /* o : frame length when pitch was updated */ - Word16 *upd_cnt /* i/o: update counter */ - , - const Word16 coder_type, /* i : coder_type */ - Word16 element_mode /* i : element mode */ + Word16 *upd_cnt, /* i/o: update counter */ + const Word16 coder_type, /* i : coder_type */ + Word16 element_mode /* i : element mode */ ); -#ifndef REMOVE_EVS_DUPLICATES -// FEC_scale_sync_fx.c void FEC_scale_syn_fx( const Word16 L_frame, /* i : length of the frame */ Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ @@ -8244,69 +8024,37 @@ void FEC_scale_syn_fx( Word16 *mem_syn, /* o: initial synthesis filter states */ Word16 Q_exc, Word16 Q_syn, + const Word16 element_mode, /* i : element mode */ const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ - const Word16 force_scaling /* i: force scaling */ -); -#endif -void FEC_scale_syn_ivas_fx( - const Word16 L_frame, /* i : length of the frame */ - Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ - Word16 clas, /* i/o: frame classification */ - const Word16 last_good, /* i: last good frame classification */ - Word16 *synth, /* i/o: synthesized speech at Fs = 12k8 Hz */ - const Word16 *pitch, /* i: pitch values for each subframe */ - Word32 L_enr_old, /* i: energy at the end of previous frame */ - Word32 L_enr_q, /* i: transmitted energy for current frame */ - const Word16 coder_type, /* i: coder type */ - const Word16 LSF_Q_prediction, /* i : LSF prediction mode */ - Word16 *scaling_flag, /* i/o: flag to indicate energy control of syn */ - Word32 *lp_ener_FEC_av, /* i/o: averaged voiced signal energy */ - Word32 *lp_ener_FEC_max, /* i/o: averaged voiced signal energy */ - const Word16 bfi, /* i: current frame BFI */ - const Word32 total_brate, /* i: total bitrate */ - const Word16 prev_bfi, /* i: previous frame BFI */ - const Word32 last_core_brate, /* i: previous frame core bitrate */ - Word16 *exc, /* i/o: excitation signal without enhancement */ - Word16 *exc2, /* i/o: excitation signal with enhancement */ - Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) */ - Word16 *old_enr_LP, /* i/o: LP filter E of last good voiced frame */ - const Word16 *mem_tmp, /* i: temp. initial synthesis filter states */ - Word16 *mem_syn, /* o: initial synthesis filter states */ - Word16 Q_exc, - Word16 Q_syn, -#ifdef REMOVE_EVS_DUPLICATES - const Word16 element_mode, /* i : element mode */ -#endif - const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ - const Word16 force_scaling /* i: force scaling */ + const Word16 force_scaling /* i : force scaling */ ); // LD_music_post_filter_fx.c void LD_music_post_filter_fx( - MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ - const Word16 dtc_in[], /* i : i synthesis Qdct */ - Word16 dtc_out[], /* o : output synthesis Qdct */ - const Word32 core_brate, /* i : core bitrate Q0 */ - Word16 *Old_ener_Q, /* i/o : Old energy scaling factor */ - const Word16 coder_type, /* i : Coder type : -1 in case of IO Q0 */ - const Word16 Last_coder_type, /* i : i scaling Q0 */ - const Word16 Qdct /* i : i scaling Q0 */ + MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ + const Word16 dtc_in[], /* i : i synthesis Qdct */ + Word16 dtc_out[], /* o : output synthesis Qdct */ + const Word32 core_brate, /* i : core bitrate Q0 */ + Word16 *Old_ener_Q, /* i/o: Old energy scaling factor */ + const Word16 coder_type, /* i : Coder type : -1 in case of IO Q0 */ + const Word16 Last_coder_type, /* i : i scaling Q0 */ + const Word16 Qdct /* i : i scaling Q0 */ ); void Prep_music_postP_fx( - Word16 exc_buffer_in[], /* i/o: excitation buffer Q_exc*/ - Word16 dct_buffer_out[], /* o : DCT output buffer (qdct)*/ - Word16 filt_lfE[], /* i/o: long term spectrum energy Q15 */ - const Word16 last_core, /* i : last core */ - const Word16 element_mode, /* i : element mode */ - const Word16 *pitch_buf, /* i : current frame pitch information Q6*/ - Word16 *LDm_enh_lp_gbin, /* o : smoothed suppression gain, per bin FFT Q15*/ - const Word16 Q_exc, /* i : excitation scaling */ - Word16 *qdct /* o : Scaling factor of dct coefficient */ + Word16 exc_buffer_in[], /* i/o: excitation buffer Q_exc*/ + Word16 dct_buffer_out[], /* o : DCT output buffer (qdct)*/ + Word16 filt_lfE[], /* i/o: long term spectrum energy Q15 */ + const Word16 last_core, /* i : last core */ + const Word16 element_mode, /* i : element mode */ + const Word16 *pitch_buf, /* i : current frame pitch information Q6*/ + Word16 *LDm_enh_lp_gbin, /* o : smoothed suppression gain, per bin FFT Q15*/ + const Word16 Q_exc, /* i : excitation scaling */ + Word16 *qdct /* o : Scaling factor of dct coefficient */ ); void Post_music_postP_fx( - Word16 dct_buffer_in[], /* i/o: excitation buffer */ + Word16 dct_buffer_in[], /* i/o: excitation buffer */ Word16 *exc2, /* i/o: Current excitation to be overwriten */ const Word16 *mem_tmp, /* i : previous frame synthesis memory */ Word16 *st_mem_syn2, /* i/o: current frame synthesis memory */ @@ -8316,15 +8064,14 @@ void Post_music_postP_fx( Word16 *prev_Q_syn, /* i : previsous frame synthesis scaling */ Word16 *Q_syn, /* i : Current frame synthesis scaling */ Word16 *mem_syn_clas_estim_fx, /* i : old 12k8 synthesis used for frame classification*/ - const Word16 IsIO, /* i: Flag to indicate IO mode */ - Word16 *mem_deemph, /* i/o: speech deemph filter memory */ - Word16 *st_pst_old_syn_fx, /* i/o: psfiler */ - Word16 *st_pst_mem_deemp_err_fx, /* i/o: psfiler */ + const Word16 IsIO, /* i : Flag to indicate IO mode */ + Word16 *mem_deemph, /* i/o: speech deemph filter memory */ + Word16 *st_pst_old_syn_fx, /* i/o: psfiler */ + Word16 *st_pst_mem_deemp_err_fx, /* i/o: psfiler */ Word16 *mem_agc, - PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */ - const Word16 *tmp_buffer /* tmp_buffer in Q-1 */ - , - Word16 *mem_tmp2 /* Temporary memory used with scale_syn */ + PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */ + const Word16 *tmp_buffer, /* tmp_buffer in Q-1 */ + Word16 *mem_tmp2 /* Temporary memory used with scale_syn */ ); void music_postfilt_init( @@ -8556,29 +8303,17 @@ Word16 FEC_enhACB_fx( const Word16 puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ const Word16 bfi_pitch /* i : Q6 pitch used for concealment */ ); -Word16 FEC_synchro_exc_fx( /* o : do_WI flag */ - const Word16 L_frame, /* i : length of the frame */ - Word16 *exc, /* i/o: exc vector to modify */ - const Word16 desire_puls_pos, /* i : Pulse position send by the encoder */ - const Word16 true_puls_pos, /* i : Present pulse location */ - const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ + +/*! r: do_WI flag */ +Word16 FEC_synchro_exc_fx( + const Word16 L_frame, /* i : length of the frame */ + Word16 *exc, /* i/o: exc vector to modify */ + const Word16 desire_puls_pos, /* i : Pulse position send by the encoder */ + const Word16 true_puls_pos, /* i : Present pulse location */ + const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ ); -#ifndef REMOVE_EVS_DUPLICATES -// dec_uv_fx.c void decod_unvoiced_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ - const Word16 coder_type, /* Q0 i : coding type */ - Word16 *tmp_noise_fx, /* Q5 o : long term temporary noise energy */ - Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* Q15 o : voicing factors */ - Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ - Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ - Word16 *gain_buf ); -#endif -void decod_unvoiced_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ @@ -8621,38 +8356,20 @@ void gaus_L2_dec( Word16 *seed_acelp /*i/o : random seed Q0 */ ); -#ifndef REMOVE_EVS_DUPLICATES -// dec_gen_voic_fx.c ivas_error decod_gen_voic_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 L_frame_fx, /* i : length of the frame */ - const Word16 sharpFlag_fx, /* i : formant sharpening flag */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 do_WI_fx, /* i : do interpolation after a FER */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - Word16 *unbits, /* number of unused bits */ - Word16 *gain_buf /*Q14*/ -); -#endif -ivas_error decod_gen_voic_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 sharpFlag_fx, /* i : formant sharpening flag */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 do_WI_fx, /* i : do interpolation after a FER */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - Word16 *unbits, /* number of unused bits */ - Word16 *gain_buf, + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag_fx, /* i : formant sharpening flag */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 do_WI_fx, /* i : do interpolation after a FER */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + Word16 *unbits, /* number of unused bits */ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ); @@ -9582,33 +9299,6 @@ void d_gain_pred_fx( Word16 **pt_indice /* i/o: pointer to the buffer of indices */ ); -#ifndef REMOVE_EVS_DUPLICATES -// acelp_core_dec_fx.c -ivas_error acelp_core_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 output[], /* o : synthesis @internal Fs */ - Word16 synth_out[], /* o : synthesis */ - Word16 save_hb_synth[], /* o : HB synthesis */ - Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis for SWB BWE */ - Word16 sharpFlag, - Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word16 *unbits, /* o : number of unused bits */ - Word16 *sid_bw /* o : 0-NB/WB, 1-SWB SID */ - , - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const Word16 tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ - const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const Word16 last_element_mode, /* i : last element mode */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel */ - const Word16 nchan_out, /* i : number of output channels */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const Word16 read_sid_info /* i : read SID info flag */ -); -#endif // evs_dec_fx.c ivas_error evs_dec_fx( Decoder_State *st_fx, /* i/o : Decoder state structure */ @@ -10678,7 +10368,7 @@ Word16 swb_bwe_dec_fx32( Word16 output_frame /* i : frame length */ ); -ivas_error acelp_core_dec_ivas_fx( +ivas_error acelp_core_dec_fx( Decoder_State *st, /* i/o: decoder state structure */ Word16 output_fx[], /* o : synthesis @internal Fs */ Word16 synth_fx16[], /* o : synthesis */ @@ -10975,6 +10665,7 @@ Word16 ari_decode_14bits_pow_ivas( Word16 *res, Tastat *s, UWord16 base ); + Word16 ari_decode_14bits_sign_ivas( Word16 *ptr, Word16 bp, @@ -10988,22 +10679,21 @@ void lsf_syn_mem_backup_ivas_fx( Word32 *gc_threshold_fx, /* i: Q16 */ Word16 *clip_var_bck_fx, /* o: Q(2.56), Q14, Q7, Q0, Q14, Q14 */ Word16 *next_force_sf_bck_fx, /* o: */ - - Word16 *lsp_new, /* i: LSP vector to quantize Q15 */ - Word16 *lsp_mid, /* i: mid-frame LSP vector Q15 */ - Word16 *clip_var, /* o: pitch clipping state var Q(2.56) */ - Word16 *mem_AR, /* o: quantizer memory for AR model Q(2.56) */ - Word16 *mem_MA, /* o: quantizer memory for AR model Q(2.56) */ - Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup Q15 */ - Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup Q15 */ - Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */ - Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */ - Word16 *mem_syn_bck, /* o: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */ - Word16 *mem_w0_bck, /* o: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */ - Word16 *streaklimit, /* Q15 */ + Word16 *lsp_new, /* i: LSP vector to quantize Q15 */ + Word16 *lsp_mid, /* i: mid-frame LSP vector Q15 */ + Word16 *clip_var, /* o: pitch clipping state var Q(2.56) */ + Word16 *mem_AR, /* o: quantizer memory for AR model Q(2.56) */ + Word16 *mem_MA, /* o: quantizer memory for AR model Q(2.56) */ + Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup Q15 */ + Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup Q15 */ + Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */ + Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */ + Word16 *mem_syn_bck, /* o: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */ + Word16 *mem_w0_bck, /* o: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */ + Word16 *streaklimit, /* Q15 */ Word16 *pstreaklen ); -ivas_error config_acelp1_IVAS( +ivas_error config_acelp1_fx( const Word16 enc_dec, /* i : encoder/decoder flag */ const Word32 total_brate, /* i : total bitrate */ const Word32 core_brate_inp, /* i : core bitrate */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 2c0da33f5..fd841b67b 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7359,33 +7359,27 @@ void tbe_celp_exc( /* _ None */ /*======================================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( - const Word16 L_frame_fx, /* i : length of the frame */ -#ifdef ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif - const Word16 i_subfr_fx, /* i : subframe index */ - const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ - const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ - const Word16 code_fx[], /* i : algebraic excitation Q9*/ - const Word16 voice_fac_fx, /* i : voicing factor Q15*/ - Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ - Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ - const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ - const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - Word16 T0, /* i : integer pitch variables Q0 */ - Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - Word32 core_brate -#ifdef ADD_IVAS_TBE_CODE - , /* i : core bitrate */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 i_subfr_fx, /* i : subframe index */ + const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ + const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 voice_fac_fx, /* i : voicing factor Q15*/ + Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ + Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ + const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ + const Word16 code_preQ_fx[], /* i : prequantizer excitation */ + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + Word16 T0, /* i : integer pitch variables Q0 */ + Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ ) { Word16 i; @@ -7396,176 +7390,6 @@ void prep_tbe_exc_fx( Word16 tmp /*, tmp1, tmp2*/; /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ Word16 pitch; - - Word32 L_tmp, Ltemp1, Ltemp2; - Word32 tempQ31; - Word16 tempQ15; -#ifndef ADD_IVAS_TBE_CODE - Word16 L_subfr = L_SUBFR; - move16(); -#endif -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - /**voice_factors = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac; - = VF_0th_PARAM + voice_fac * (VF_1st_PARAM + VF_2nd_PARAM * voice_fac ) - *voice_factors = min( max_val(0.0f, *voice_factors), 1.0f); */ - tempQ31 = L_deposit_h( VF_1st_PARAM_FX ); - tempQ15 = mac_r( tempQ31, VF_2nd_PARAM_FX, voice_fac_fx ); - tempQ31 = L_deposit_h( VF_0th_PARAM_FX ); - *voice_factors_fx = mac_r( tempQ31, voice_fac_fx, tempQ15 ); - move16(); - tmp = MAX_16; - move16(); - - pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ - - test(); - test(); - IF( ( ( EQ_16( coder_type, VOICED ) ) || ( GT_16( pitch, 14784 /* 115.5 in Q7 */ ) ) ) && ( GT_32( core_brate, ACELP_8k00 ) ) ) - { - tmp = MAX_16; - move16(); - *voice_factors_fx = mult_r( *voice_factors_fx, tmp ); - move16(); - } - - *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); - move16(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) - { - IF( flag_TD_BWE && i_subfr == 0 ) - { - set16_fx( bwe_exc, 0, L_FRAME32k ); - } - return; - } - -#endif - IF( EQ_16( L_frame_fx, L_FRAME ) ) - { - interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ - gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ - FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) - { - L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ - L_tmp = L_shl_sat( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ - L_tmp = L_mac_sat( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ - move16(); - } - } - ELSE - { - IF( gain_preQ_fx != 0 ) - { - FOR( i = 0; i < L_subfr; i++ ) - { - /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ - - Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ - Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, 4 ) /*Q_exc+16-13*/, &Overflow ); /*Q_exc+16 */ - - tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ - move16(); - } - } - ELSE - { - FOR( i = 0; i < L_subfr; i++ ) - { - /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ - tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ - move16(); - } - } - - interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ - FOR( i = 0; i < L_subfr * 2; i++ ) - { - L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * 2] ); /*Q14+Q_exc+1 */ - tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ - bwe_exc_fx[i + i_subfr_fx * 2] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ - move16(); - } - } - - return; -} - -/*======================================================================================*/ -/* FUNCTION : prep_tbe_exc_ivas_fx() */ -/*--------------------------------------------------------------------------------------*/ -/* PURPOSE : Prepare TBE excitation */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16) L_frame_fx : length of the frame */ -/* _ (Word16) i_subfr_fx : subframe index */ -/* _ (Word16) gain_pit_fx : Pitch gain (14) */ -/* _ (Word32) gain_code_fx : algebraic codebook gain (Q(16+Q_exc)) */ -/* _ (Word16*[]) code_fx : algebraic excitation (Q9) */ -/* _ (Word16) voice_fac_fx : voicing factor (Q15) */ -/* _ (Word16) gain_preQ_fx : prequantizer excitation gain */ -/* _ (Word16[]) code_preQ_fx : prequantizer excitation */ -/*--------------------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16*[]) voice_factors_fx : TBE voicing factor (Q15) */ -/*--------------------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _ (Word16[]) bwe_exc_fx : excitation for TBE (Q_exc) */ -/*--------------------------------------------------------------------------------------*/ - -/* _ None */ -/*--------------------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*======================================================================================*/ -#endif -void prep_tbe_exc_ivas_fx( - const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif - const Word16 i_subfr_fx, /* i : subframe index */ - const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ - const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ - const Word16 code_fx[], /* i : algebraic excitation Q9*/ - const Word16 voice_fac_fx, /* i : voicing factor Q15*/ - Word16 *voice_factors_fx, /* o : TBE voicing factor Q15*/ - Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ - const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ - const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - Word16 T0, /* i : integer pitch variables Q0 */ - Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE - , /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif -) -{ - Word16 i; - Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; - Word16 tmp_code_preInt_fx[L_SUBFR]; - Word16 gain_code16 = 0; - move16(); - Word16 tmp /*, tmp1, tmp2*/; - /*Word16 random_code[L_SUBFR * HIBND_ACB_L_FAC];*/ - Word16 pitch; - Word32 L_tmp, Ltemp1, Ltemp2; Word32 tempQ31; Word16 tempQ15; @@ -7600,7 +7424,7 @@ void prep_tbe_exc_ivas_fx( *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); move16(); -#if 1 // def ADD_IVAS_TBE_CODE + test(); test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) @@ -7613,7 +7437,6 @@ void prep_tbe_exc_ivas_fx( return; } -#endif IF( EQ_16( L_frame_fx, L_FRAME ) ) { interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ @@ -7672,6 +7495,7 @@ void prep_tbe_exc_ivas_fx( return; } + /*=============================================================================*/ /* FUNCTION : void swb_formant_fac_fx ( ) */ /*------------------------------------------------------------------------------*/ @@ -7691,9 +7515,10 @@ void prep_tbe_exc_ivas_fx( /* CALLED FROM : */ /*==============================================================================*/ -Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ - const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ - Word16 *tilt_mem /* i/o: Tilt smoothing memory (Q12) */ +/*! r: Formant filter strength [0,1] */ +Word16 swb_formant_fac_fx( + const Word16 lpc_shb2, /* Q12 i : 2nd HB LPC coefficient */ + Word16 *tilt_mem /* i/o: Tilt smoothing memory (Q12) */ ) { Word16 formant_fac; @@ -7713,7 +7538,6 @@ Word16 swb_formant_fac_fx( /* o : Formant filter strength tmp = sub( tmp, SWB_TILT_LOW_FX ); /* Q12 */ formant_fac = mult_r( tmp, SWB_TILT_DELTA_FX ); /* Q12 */ - IF( GT_16( formant_fac, 4096 /* 1 in Q12 */ ) ) { formant_fac = 4096; /* 1 in Q12 */ @@ -7733,6 +7557,12 @@ Word16 swb_formant_fac_fx( /* o : Formant filter strength } +/*-------------------------------------------------------------------* + * wb_tbe_extras_reset_fx() + * + * + *-------------------------------------------------------------------*/ + void wb_tbe_extras_reset_fx( Word16 mem_genSHBexc_filt_down_wb2[], Word16 mem_genSHBexc_filt_down_wb3[] ) @@ -7749,7 +7579,6 @@ void wb_tbe_extras_reset_fx( * Determine TBE bit consumption per frame from bitrate * *-------------------------------------------------------------------*/ - Word16 get_tbe_bits_fx( const Word32 total_brate, /* o : TBE bit consumption per frame */ const Word16 bwidth, /* i : overall bitrate */ diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index a23c9aa90..48d91a87a 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -510,19 +510,10 @@ void FEC_exc_estim_fx( move16(); /* st_fx->L_frame / L_SUBFR */ tmp = shr( st_fx->L_frame, 6 ); + /* Replication of the last spectrum, with a slight downscaling of its dynamic */ -#ifdef REMOVE_EVS_DUPLICATES - gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc ); -#else - IF( st_fx->element_mode == EVS_MONO ) - { - gsc_dec_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, st_fx->Q_exc ); - } - ELSE - { - gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc ); - } -#endif + gsc_dec_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc ); + *tmp_noise = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ move16(); /* Transform back to time domain */ diff --git a/lib_dec/FEC_scale_syn_fx.c b/lib_dec/FEC_scale_syn_fx.c index 714a60166..7f4586083 100644 --- a/lib_dec/FEC_scale_syn_fx.c +++ b/lib_dec/FEC_scale_syn_fx.c @@ -50,7 +50,6 @@ /* _ None */ /*========================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void FEC_scale_syn_fx( const Word16 L_frame, /* i : length of the frame */ Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ @@ -77,574 +76,7 @@ void FEC_scale_syn_fx( Word16 *mem_syn, /* o: initial synthesis filter states Q_syn*/ Word16 Q_exc, Word16 Q_syn, - const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ - const Word16 force_scaling /* i: force scaling */ -) -{ - Word16 i; - Word32 L_enr1, L_enr2; - Word16 gain1, gain2, enr_LP; - Word16 tmp, tmp2, exp, exp2; - Word16 tmp3; - Word32 L_tmp; - Word16 scaling; - Word32 ener_max, L_enr2_av, L_ener2_max; - Word16 h1[L_FRAME / 2], tilt, pitch_dist, mean_pitch; - Word16 k; - Word32 L_mean_pitch; - - enr_LP = 0; - move16(); - gain2 = 0; - move16(); - gain1 = 0; - move16(); - *update_flg = 0; - move16(); - L_enr_old = L_max( 1, L_enr_old ); /* to avoid division by zero (*L_enr_old is always >= 0) */ - scaling = 16384; - move16(); /* Q14*/ - - /*-----------------------------------------------------------------* - * Find the synthesis filter impulse response on voiced - *-----------------------------------------------------------------*/ - test(); - IF( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) - { - IF( EQ_16( L_frame, L_FRAME ) ) - { - enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR - 1 ) * ( M + 1 ), L_SUBFR ); - } - ELSE /* L_frame == L_FRAME16k */ - { - enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR16k - 1 ) * ( M + 1 ), L_SUBFR ); /*Q3*/ - } - } - - /*-----------------------------------------------------------------* - * Define when to scale the synthesis - *-----------------------------------------------------------------*/ - - IF( bfi ) - { - *scaling_flag = 1; - move16(); /* Always check synthesis on bad frames */ - } - ELSE IF( prev_bfi ) - { - test(); - IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) || ( EQ_16( LSF_Q_prediction, MOVING_AVERAGE ) ) ) - { - *scaling_flag = 2; - move16(); /* Decoded LSFs affected */ - } - ELSE IF( NE_16( coder_type, TRANSITION ) ) - { - *scaling_flag = 1; - move16(); /* SN, but not TC mode - LSF still affected by the interpolation */ - } - ELSE - { - *scaling_flag = 0; - move16(); /* LSF still possibly affected due to interpolation */ - } - scaling = 24576; /*1.5 Q14*/ - move16(); - } - ELSE - { - test(); - IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) && ( EQ_16( *scaling_flag, 2 ) ) ) - { - *scaling_flag = 2; - move16(); /* Continue with energy control till the end of AR prediction */ - } - ELSE IF( *scaling_flag > 0 ) - { - ( *scaling_flag ) = sub( *scaling_flag, 1 ); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */ - move16(); - } - scaling = 32767; /*2.0 Q14*/ - move16(); - } - - /*-----------------------------------------------------------------* - * Find the energy/gain at the end of the frame - *-----------------------------------------------------------------*/ - - frame_ener_fx( L_frame, clas, synth, pitch[( L_frame >> 6 ) - 1], &L_enr2 /*Q0*/, 1, Q_syn, 3, 0 ); - - - test(); - test(); - IF( bfi || ( EQ_32( total_brate, ACELP_7k20 ) ) || ( EQ_32( total_brate, ACELP_8k00 ) ) ) - { - /* previous frame erased and no TC frame */ - IF( *scaling_flag > 0 ) - { - /*enr2 += 0.01f;*/ - L_enr2 = L_max( L_enr2, 1 ); /* L_enr2 is in Q0 */ - - IF( bfi ) /* In all bad frames, limit the gain to 1 */ - { - /* gain2 = (float)sqrt( enr_old / enr2 );*/ - L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 ); - gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ - - /*if( gain2 > 1.0f )gain2 = 1.0f;*/ - gain2 = s_min( gain2, 16384 ); - - /* find the energy/gain at the beginning of the frame */ - frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 ); - - /*enr1 += 0.1f;*/ - L_enr1 = L_max( L_enr1, 1 ); /* L_enr2 is in Q0 */ - - /*gain1 = (float)sqrt( enr_old / enr1 );*/ - L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 ); - gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ - - /*if( gain1 > 1.0f )gain1 = 1.0f;*/ - gain1 = s_min( gain1, 16384 ); /*Q14*/ - } - ELSE /* good frame */ - { - IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */ - { - L_enr_q = L_enr2; /*Q0*/ - set16_fx( h1, 0, L_FRAME / 2 ); - h1[0] = 1024; /*1.0f in Q10*/ - move16(); - /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/ - E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M ); - - /*Compute tilt */ - /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ - /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ - /*tilt = rr1 / rr0;*/ - tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/ - pitch_dist = 0; - move16(); - L_mean_pitch = L_mult( pitch[0], 8192 /*1.0f in Q13*/ ); /*Q14*/ - FOR( k = 0; k < ( NB_SUBFR - 1 ); k++ ) - { - pitch_dist = add( pitch_dist, abs_s( sub( pitch[k + 1], pitch[k] ) ) ); /*Q0*/ - L_mean_pitch = L_mac( L_mean_pitch, pitch[k + 1], 8192 ); /*Q14*/ - } - /*pitch_dist /= (float)(NB_SUBFR-1); */ - pitch_dist = mult_r( shl( pitch_dist, 4 ), 10923 /*1/(float)(NB_SUBFR-1) in Q15*/ ); /*Q4*/ - /*mean_pitch /= (float)(NB_SUBFR);*/ - mean_pitch = extract_h( L_shl( L_mean_pitch, 4 ) ); /*Q4*/ - - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( GT_16( tilt, 22938 ) ) && /* HF resonnant filter */ - ( ( GT_16( pitch_dist, 8 << 4 ) ) || ( LT_16( mean_pitch, PIT_MIN << 4 ) ) ) && /* pitch unstable or very short */ - ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) ) - { - /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/ - L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ - } - ELSE - { - ener_max = *lp_ener_FEC_max; /*Q0*/ - move32(); - test(); - if ( EQ_16( clas, VOICED_TRANSITION ) || ( GE_16( clas, INACTIVE_CLAS ) ) ) - { - ener_max = *lp_ener_FEC_av; /*Q0*/ - move32(); - } - /*if( enr_old > ener_max )ener_max = enr_old;*/ - ener_max = L_max( ener_max, L_enr_old ); - - /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/ - L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/ - } - } - /*gain2 = (float)sqrt( enr_q / enr2 );*/ - L_enr_q = L_max( L_enr_q, 1 ); /* L_enr2 is in Q0 */ - L_tmp = Sqrt_Ratio32( L_enr_q, 0, L_enr2, 0, &exp2 ); - gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ - - /*-----------------------------------------------------------------* - * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s) - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) || - EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) && - prev_bfi ) - { - /* voiced -> unvoiced signal transition */ - /* CNG -> active signal transition */ - gain1 = gain2; /*Q14*/ - move16(); - } - ELSE - { - /* find the energy at the beginning of the frame */ - frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 ); - - /*enr1 += 0.1f;*/ - L_enr1 = L_max( L_enr1, 1 ); /* L_enr1 is in Q0 */ - - /*gain1 = (float)sqrt( enr_old / enr1 );*/ - L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 ); - gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ - - /*if( gain1 > 1.2f )gain1 = 1.2f;*/ - /* prevent clipping */ - gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ ); - - /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */ - test(); - test(); - if ( EQ_16( clas, ONSET ) && GT_16( gain1, gain2 ) && prev_bfi ) - { - gain1 = gain2; /*Q14*/ - move16(); - } - } - - L_enr2 = L_enr_q; /*Q0*/ - move32(); /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC */ - } - - /*------------------------------------------------------------------------------* - * Smooth the energy evolution by exponentially evolving from gain1 to gain2 - *------------------------------------------------------------------------------*/ - - /*gain2 *= ( 1.0f - AGC );*/ - L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) ); /*Q30*/ - FOR( i = 0; i < L_frame; i++ ) - { - /*gain1 = gain1 * AGC + gain2;*/ - gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */ - /*exc[i] *= gain1;*/ - exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 ); - move16(); - /*exc2[i] *= gain1;*/ - exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); - move16(); - } - /* smoothing is done in excitation domain, so redo synthesis */ - Copy( mem_tmp, mem_syn, M ); /* Q_syn */ - syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn ); - *update_flg = 1; - move16(); - } - } - ELSE - { - /* previous frame erased and no TC frame */ - test(); - IF( prev_bfi && NE_16( coder_type, TRANSITION ) ) - { - IF( L_enr_q == 0 ) - { - L_enr_q = L_max( 1, L_enr2 ); /* sets to 'L_enr2' in 1 clock */ - set16_fx( h1, 0, L_FRAME / 2 ); - h1[0] = 1024; /*1.0f in Q10*/ - move16(); - /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/ - E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M ); - /*Compute tilt */ - /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ - /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ - /*tilt = rr1 / rr0;*/ - tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( ( EQ_32( total_brate, ACELP_13k20 ) ) || ( EQ_32( total_brate, ACELP_12k85 ) ) || ( EQ_32( total_brate, ACELP_12k15 ) ) || ( EQ_32( total_brate, ACELP_11k60 ) ) || - ( EQ_32( total_brate, ACELP_9k60 ) ) ) && - ( GT_16( tilt, 22938 ) ) && /* HF resonnant filter */ - ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */ - { - /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/ - L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ - } - ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) - { - /* Voiced-voiced recovery */ - test(); - IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) - { - /* enr_q /= enr_LP */ - exp = norm_l( L_enr_q ); - tmp = extract_h( L_shl( L_enr_q, exp ) ); - - exp2 = norm_s( enr_LP ); - tmp2 = shl( enr_LP, exp2 ); - - exp = sub( exp2, exp ); - - tmp3 = sub( tmp, tmp2 ); - IF( tmp3 > 0 ) - { - tmp = shr( tmp, 1 ); - exp = add( exp, 1 ); - } - tmp = div_s( tmp, tmp2 ); - - /* L_enr_q *= 2 * *old_enr_LP */ - L_enr_q = L_shl( L_mult( tmp, shl( *old_enr_LP, 1 ) ), exp ); - } - - ELSE - { - test(); - IF( avoid_lpc_burst_on_recovery && GT_16( enr_LP, 160 /*20.0f in Q3*/ ) ) - { - exp = norm_s( enr_LP ); - tmp = shl( enr_LP, exp ); - - exp2 = 7; - move16(); - tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */ - move16(); - exp = sub( exp2, exp ); - - IF( GT_16( tmp, tmp2 ) ) - { - tmp = shr( tmp, 1 ); - exp = add( exp, 1 ); - } - tmp = div_s( tmp, tmp2 ); /* tmp*2^exp = enr_LP/20.0 */ - L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* L_tmp*2^exp = sqrt(20.0/enr_LP) */ - L_enr_q = L_shl( Mpy_32_32( L_enr_q, L_tmp ), exp ); - } - } - } - - test(); - test(); - test(); - test(); - IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) || force_scaling ) - { - - IF( GT_32( L_enr_q, L_enr_old ) ) /* Prevent energy to increase on voiced */ - { - L_enr_q = L_add( Mpy_32_16_1( L_enr_old, 32767 - SCLSYN_LAMBDA ), Mpy_32_16_1( L_enr_q, SCLSYN_LAMBDA ) ); /*Q0*/ - } - } - } - - L_enr_q = L_max( 1, L_enr_q ); - - /* gain2 = (float)sqrt( enr_q / enr2 );*/ - exp = norm_l( L_enr_q ); - tmp = extract_h( L_shl( L_enr_q, exp ) ); - - exp2 = norm_l( L_enr2 ); - tmp2 = extract_h( L_shl( L_enr2, exp2 ) ); - - exp2 = sub( exp, exp2 ); /* Denormalize and substract */ - - tmp3 = sub( tmp2, tmp ); - IF( tmp3 > 0 ) - { - tmp2 = shr( tmp2, 1 ); - exp2 = add( exp2, 1 ); - } - - tmp = div_s( tmp2, tmp ); - - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp2 ); - gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ - /*-----------------------------------------------------------------* - * Clipping of the smoothing gain at the frame end - *-----------------------------------------------------------------*/ - - gain2 = s_min( gain2, 19661 /*1.2f in Q14*/ ); /* Gain modification clipping */ - if ( LT_32( L_enr_q, 2 ) ) - { - gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /* Gain modification clipping */ - } - - /*-----------------------------------------------------------------* - * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s) - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( clas, SIN_ONSET ) ) /* slow increase */ - { - gain1 = shr( gain2, 1 ); /*0.5f * gain2*/ - } - /*------------------------------------------------------------* - * voiced->unvoiced transition recovery - *------------------------------------------------------------*/ - ELSE IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) || /* voiced->unvoiced transition recovery */ - EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) /* CNG -> active signal transition */ - { - gain1 = gain2; /*Q14*/ - move16(); - } - ELSE - { - /*--------------------------------------------------------* - * Find the energy at the beginning of the frame - *--------------------------------------------------------*/ - tmp = frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0 ); - - /*gain1 = (float)sqrt( enr_old / enr1 );*/ - exp = norm_l( L_enr_old ); - tmp = extract_h( L_shl( L_enr_old, exp ) ); - exp2 = norm_l( L_enr1 ); - tmp2 = extract_h( L_shl( L_enr1, exp2 ) ); - - exp2 = sub( exp, exp2 ); /* Denormalize and substract */ - - tmp3 = sub( tmp2, tmp ); - - IF( tmp3 > 0 ) - { - tmp2 = shr( tmp2, 1 ); - exp2 = add( exp2, 1 ); - } - - tmp = div_s( tmp2, tmp ); - - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp2 ); - gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ - /* exp2 is always <= 1 */ - - gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ ); - - test(); - test(); - if ( avoid_lpc_burst_on_recovery && ( GT_16( enr_LP, 160 ) ) && ( LE_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) ) - { - gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); - } - - /*--------------------------------------------------------* - * Prevent a catastrophy in case of offset followed by onset - *--------------------------------------------------------*/ - test(); - if ( ( EQ_16( clas, ONSET ) ) && ( GT_16( gain1, gain2 ) ) ) - { - gain1 = gain2; /*Q14*/ - move16(); - } - } - /*-----------------------------------------------------------------* - * Smooth the energy evolution by exponentially evolving from - * gain1 to gain2 - *-----------------------------------------------------------------*/ - - L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) ); - - FOR( i = 0; i < L_frame; i++ ) - { - gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */ - exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 ); - move16(); - exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 ); - move16(); - } - - Copy( mem_tmp, mem_syn, M ); /* Q_syn */ - syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn ); - *update_flg = 1; - move16(); - } - } - /*-----------------------------------------------------------------* - * Update low-pass filtered energy for voiced frames - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( !bfi && ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) ) - { - IF( EQ_16( clas, VOICED_TRANSITION ) ) - { - L_enr2_av = L_enr2; /*Q0*/ - move32(); - frame_ener_fx( L_frame, VOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_ener2_max /*Q0*/, 1, Q_syn, 3, 0 ); - } - ELSE - { - L_ener2_max = L_enr2; /*Q0*/ - move32(); - frame_ener_fx( L_frame, UNVOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_enr2_av /*Q0*/, 1, Q_syn, 3, 0 ); - } - - /**lp_ener_FEC_av = 0.2f * enr2_av + 0.8f * *lp_ener_FEC_av; move32();*/ - *lp_ener_FEC_av = Madd_32_16( Mult_32_16( *lp_ener_FEC_av, 31130 /*0.95f in Q15*/ ), L_enr2_av, 1638 /*0.05F Q15*/ ); /*Q0*/ - move32(); - /**lp_ener_FEC_max = 0.2f * enr2_max + 0.8f * *lp_ener_FEC_max; move32();*/ - *lp_ener_FEC_max = Madd_32_16( Mult_32_16( *lp_ener_FEC_max, 31130 /*0.95f in Q15*/ ), L_ener2_max, 1638 /*0.05F Q15*/ ); /*Q0*/ - move32(); - } - - /*-----------------------------------------------------------------* - * Update the LP filter energy for voiced frames - *-----------------------------------------------------------------*/ - test(); - if ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) - { - *old_enr_LP = enr_LP; /*Q3*/ - move16(); - } - - return; -} -#endif -void FEC_scale_syn_ivas_fx( - const Word16 L_frame, /* i : length of the frame */ - Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ - Word16 clas, /* i/o: frame classification */ - const Word16 last_good, /* i: last good frame classification */ - Word16 *synth, /* i/o: synthesized speech at Fs = 12k8 Hz Q_syn*/ - const Word16 *pitch, /* i: pitch values for each subframe Q0*/ - Word32 L_enr_old, /* i: energy at the end of previous frame */ - Word32 L_enr_q, /* i: transmitted energy for current frame */ - const Word16 coder_type, /* i: coder type */ - const Word16 LSF_Q_prediction, /* i : LSF prediction mode */ - Word16 *scaling_flag, /* i/o: flag to indicate energy control of syn */ - Word32 *lp_ener_FEC_av, /* i/o: averaged voiced signal energy Q0*/ - Word32 *lp_ener_FEC_max, /* i/o: averaged voiced signal energy Q0*/ - const Word16 bfi, /* i: current frame BFI */ - const Word32 total_brate, /* i: total bitrate */ - const Word16 prev_bfi, /* i: previous frame BFI */ - const Word32 last_core_brate, /* i: previous frame core bitrate */ - Word16 *exc, /* i/o: excitation signal without enhancement */ - Word16 *exc2, /* i/o: excitation signal with enhancement */ - Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) Q12*/ - Word16 *old_enr_LP, /* i/o: LP filter E of last good voiced frame Q3*/ - const Word16 *mem_tmp, /* i: temp. initial synthesis filter states Q_syn*/ - Word16 *mem_syn, /* o: initial synthesis filter states Q_syn*/ - Word16 Q_exc, - Word16 Q_syn, -#ifdef REMOVE_EVS_DUPLICATES - const Word16 element_mode, /* i : element mode */ -#endif + const Word16 element_mode, /* i : element mode */ const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ const Word16 force_scaling /* i: force scaling */ ) @@ -742,12 +174,8 @@ void FEC_scale_syn_ivas_fx( tmp = sub( 3, getScaleFactor16( synth, L_frame ) ); -#ifdef REMOVE_EVS_DUPLICATES test(); IF( tmp > 0 && GT_16( element_mode, EVS_MONO ) ) -#else - IF( tmp > 0 ) -#endif { Word16 synth_tmp[L_FRAME16k]; Copy_Scale_sig( synth, synth_tmp, L_frame, -tmp ); // Q_synth - tmp diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c deleted file mode 100644 index 0fbedff60..000000000 --- a/lib_dec/acelp_core_dec_fx.c +++ /dev/null @@ -1,1544 +0,0 @@ -/*==================================================================================== - EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" /* Compilation switches */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot_fx.h" -#include "ivas_cnst.h" /* Common constants */ -#include "cnst.h" /* Common constants */ - -#ifndef REMOVE_EVS_DUPLICATES -/*==========================================================================*/ -/* FUNCTION : void acelp_core_dec_fx () */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : ACELP core decoder */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ Word16 coder_type i : coder type */ - -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ Word16 *voice_factors o : voicing factors Q15 */ -/* _ Word16 old_syn_12k8_16k[] o : intermediate ACELP Q_syn2-1 */ -/* synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ -/* _ Word16 synth_out[] o : synthesis Q_syn2-1 */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* _ Decoder_State_fx *st_fx: */ -/* _ Word16 bwe_exc_extended[] i/o: bandwidth extended excitation Q0*/ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* CALLED FROM : RX */ -/*==========================================================================*/ - -ivas_error acelp_core_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 output[], /* o : synthesis @internal Fs */ - Word16 synth_out[], /* o : synthesis Q_syn2-1*/ - Word16 save_hb_synth[], /* o : HB synthesis */ - Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation Q0*/ - Word16 *voice_factors, /* o : voicing factors Q15 */ - Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis for SWB BWE Q_syn2-1*/ - Word16 sharpFlag, - Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ - Word16 *unbits, /* o : number of unused bits */ - Word16 *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const Word16 tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ - const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const Word16 last_element_mode, /* i : last element mode */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel */ - const Word16 nchan_out, /* i : number of output channels */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const Word16 read_sid_info /* i : read SID info flag */ -) -{ - Word16 old_exc_fx[L_EXC_DEC] = { 0 }, *exc_fx; /* excitation signal buffer (Q0) */ - Word16 syn_fx_tmp[L_FRAME_16k + L_SUBFR], *syn_fx; /* synthesis signal buffer */ - Word16 temp_buf[L_FRAME16k + L_SYN_MEM]; - Word16 output_frame; /* frame length at output sampling freq. */ - Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ - Word32 enr_q_fx; /* E information for FER protection */ - Word16 tmp_noise_fx; /* Long term temporary noise energy */ - Word16 i, int_fs; - Word16 tc_subfr_fx; - Word16 allow_cn_step_fx; - Word16 temp_buf_fx[L_FRAME16k + L_SYN_MEM]; - - Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )] = { 0 }; /*Q12*/ - Word16 Es_pred_fx; /*Q8*/ - Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )] = { 0 }; /* excitation buffer Q_exc*/ - Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ - Word16 *bwe_exc_fx; - Word16 lsf_new_fx[M]; /* LSFs at the end of the frame */ - Word16 lsp_new_fx[M]; /* LSPs at the end of the frame */ - Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ - Word16 FEC_pitch_fx; /*Q6*/ - Word16 last_pulse_pos; - Word16 T0_tmp; - Word16 do_WI_fx; - Word16 dct_buffer_fx[DCT_L_POST]; - Word16 exc_buffer_fx[DCT_L_POST]; - Word16 dct_exc_tmp[L_FRAME16k]; - Word16 qdct; - Word16 delta_mem_scale; - Word16 bpf_error_signal[L_FRAME16k]; - CLDFB_SCALE_FACTOR scaleFactor; - Word32 workBuffer[128 * 3]; - Word32 q_env[20]; - Word16 exc3_fx[L_FRAME16k]; - Word16 syn1_fx_tmp[L_FRAME16k + 2], *syn1_fx; - Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX]; - Word16 gain_buf[NB_SUBFR16k]; /*Q14*/ - Word16 syn_fx_tmp2[L_FRAME_16k]; - Word16 pitch_buf_tmp[NB_SUBFR16k]; - Word16 k; - Word16 update_flg; - Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - Word32 imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - Word16 LSF_Q_prediction; /* o : LSF prediction mode */ - Word16 avoid_lpc_burst_on_recovery; - Word16 uc_two_stage_flag, dec; - Word16 nb_bits, indice; - Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; - MUSIC_POSTFILT_HANDLE hMusicPF; - BPF_DEC_HANDLE hBPF; - TD_BWE_DEC_HANDLE hBWE_TD; - FD_BWE_DEC_HANDLE hBWE_FD; - TCX_DEC_HANDLE hTcxDec; - ivas_error error; - (void) ( tdm_lspQ_PCh ); - (void) ( tdm_lsfQ_PCh ); - (void) ( use_cldfb_for_dft ); - (void) ( last_element_mode ); - (void) ( last_element_brate ); - (void) ( flag_sec_CNA ); - (void) ( nchan_out ); - (void) ( save_hb_synth ); - (void) ( output ); - (void) ( read_sid_info ); - (void) hStereoCng; - hMusicPF = st_fx->hMusicPF; - hBPF = st_fx->hBPF; - hBWE_TD = st_fx->hBWE_TD; - hBWE_FD = st_fx->hBWE_FD; - hTcxDec = st_fx->hTcxDec; - error = IVAS_ERR_OK; - move32(); - // IF ( EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && EQ_16(nchan_out, 1) && EQ_16(st_fx->idchan, 1) && LE_32(last_element_brate, IVAS_SID_4k4) ) - test(); - test(); - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st_fx->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) - { - /* In MDCT-Stereo DTX with mono output, we can skip CNG for the second channel, except for the first inactive frame following an active period */ - return error; - } - - FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - set32_fx( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer[i] = realBufferTmp[i]; - move32(); - imagBuffer[i] = imagBufferTmp[i]; - move32(); - } - - /*----------------------------------------------------------------* - * Initialization - *----------------------------------------------------------------*/ - - LSF_Q_prediction = -1; - move16(); - set16_fx( syn_fx_tmp, 0, L_SUBFR ); - syn_fx = syn_fx_tmp + L_SUBFR; - syn1_fx_tmp[0] = 0; - move16(); - syn1_fx_tmp[1] = 0; - move16(); - syn1_fx = syn1_fx_tmp + 2; - /*output_frame = (Word16)(st_fx->output_Fs_fx / 50); move16();*/ - output_frame = st_fx->output_frame_fx; - move16(); - st_fx->bpf_off = 0; - move16(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st_fx->last_core, HQ_CORE ) || EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && LE_32( st_fx->last_core_brate, SID_2k40 ) ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && LE_32( st_fx->last_core_brate, SID_2k40 ) ) ) - { - /* in case of HQ->ACELP switching, do not apply BPF */ - st_fx->bpf_off = 1; - move16(); - /* in case of core switching, reset post-filter memories */ - if ( st_fx->hPFstat != NULL ) - { - st_fx->hPFstat->on = 0; - move16(); - } - - /* reset the GSC pre echo energy threshold in case of switching */ - if ( st_fx->hGSCDec != NULL ) - { - st_fx->hGSCDec->Last_frame_ener_fx = MAX_32; - move32(); - } - } - IF( st_fx->prev_bfi > 0 ) - { - /* reset the GSC pre echo energy threshold in case of FEC */ - if ( st_fx->hGSCDec != NULL ) - { - st_fx->hGSCDec->Last_frame_ener_fx = MAX_32; - move32(); - } - } - - st_fx->clas_dec = st_fx->last_good; - move16(); - enr_q_fx = 0; - move32(); - Es_pred_fx = 0; - move16(); - tmp_noise_fx = 0; - move16(); - Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); // Q_exc - exc_fx = old_exc_fx + L_EXC_MEM_DEC; - - IF( st_fx->hWIDec != NULL ) - { - Copy( st_fx->hWIDec->old_exc2_fx, old_exc2_fx, L_EXC_MEM ); - } - ELSE - { - set16_fx( old_exc2_fx, 0, L_EXC_MEM ); - } - exc2_fx = old_exc2_fx + L_EXC_MEM; - IF( st_fx->hBWE_TD != NULL ) - { - Copy( hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2 ); // Q_exc - bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; - } - ELSE - { - bwe_exc_fx = NULL; - } - - last_pulse_pos = 0; - move16(); - do_WI_fx = 0; - move16(); - st_fx->GSC_noisy_speech = 0; - move16(); - st_fx->relax_prev_lsf_interp = 0; - move16(); - - set16_fx( gain_buf, 0, NB_SUBFR16k ); - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - st_fx->gamma = GAMMA1; - move16(); - st_fx->preemph_fac = PREEMPH_FAC; - move16(); - int_fs = INT_FS_FX; - move16(); - } - ELSE - { - st_fx->gamma = GAMMA16k; - move16(); - st_fx->preemph_fac = PREEMPH_FAC_16k; - move16(); - int_fs = INT_FS_16k; - move16(); - } - - /* reset post-filter in case post-filtering was off in previous frame */ - IF( st_fx->hPFstat != NULL ) - { - if ( st_fx->hPFstat->on == 0 ) - { - st_fx->hPFstat->reset = 1; - move16(); - } - } - avoid_lpc_burst_on_recovery = 0; - move16(); - test(); - test(); - if ( st_fx->last_con_tcx && NE_16( st_fx->L_frameTCX_past, st_fx->L_frame ) && st_fx->last_core != 0 ) - { - avoid_lpc_burst_on_recovery = 1; - move16(); - } - /* TD stereo parameters */ - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && st_fx->idchan == 1 ) - { - tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; - tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; - tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; - move16(); - move16(); - move16(); - move16(); - } - ELSE - { - tdm_lp_reuse_flag = 0; - tdm_low_rate_mode = 0; - move16(); - move16(); - test(); - if ( EQ_16( st_fx->element_mode, IVAS_SCE ) && st_fx->low_rate_mode ) - { - tdm_low_rate_mode = 1; - move16(); - } - tdm_Pitch_reuse_flag = 0; - move16(); - } - /*----------------------------------------------------------------* - * Updates in case of internal sampling rate switching - *----------------------------------------------------------------*/ - test(); - test(); - IF( NE_16( st_fx->last_L_frame, st_fx->L_frame ) && ( st_fx->last_core == ACELP_CORE || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) - { - IF( st_fx->hPFstat->on != 0 ) - { - Word16 mem_syn_r_size_old, mem_syn_r_size_new; - - mem_syn_r_size_old = shr( st_fx->last_L_frame, 4 ); - mem_syn_r_size_new = shr( st_fx->L_frame, 4 ); - lerp( st_fx->hPFstat->mem_stp + L_SYN_MEM - mem_syn_r_size_old, st_fx->hPFstat->mem_stp + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); - lerp( st_fx->hPFstat->mem_pf_in + L_SYN_MEM - mem_syn_r_size_old, st_fx->hPFstat->mem_pf_in + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); - } - /* convert quantized LSP vector */ - st_fx->rate_switching_reset = lsp_convert_poly_fx( st_fx->lsp_old_fx, st_fx->L_frame, 0 ); - move16(); - /* convert old quantized LSF vector */ - lsp2lsf_fx( st_fx->lsp_old_fx, st_fx->lsf_old_fx, M, int_fs ); - - /* FEC - update adaptive LSF mean vector */ - Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi1_fx, M ); // Qlog2(2.56) - Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi0_fx, M ); // Qlog2(2.56) - Copy( st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, M ); // Qlog2(2.56) - - /* Reset LPC mem */ - IF( EQ_32( st_fx->sr_core, INT_FS_16k ) ) - { - Copy( GEWB2_Ave_fx, st_fx->mem_AR_fx, M ); // Qlog2(2.56) - } - ELSE - { - Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); // Qlog2(2.56) - } - set16_fx( st_fx->mem_MA_fx, 0, M ); - - dec = DEC; - move16(); - IF( NE_16( st_fx->element_mode, EVS_MONO ) ) - { - dec = DEC_IVAS; - move16(); - } - - /* update synthesis filter memories */ - synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); - - Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); // Q_exc - Copy_Scale_sig( st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/ - - Copy( st_fx->mem_syn2_fx, st_fx->mem_syn3_fx, M ); - } - - IF( NE_16( st_fx->last_L_frame, st_fx->L_frame ) ) - { - /* update buffer of old subframe pitch values */ - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - - IF( EQ_16( st_fx->last_L_frame, L_FRAME32k ) ) - { - /* (float)12800/(float)32000; */ - k = 13107; // Q15 - move16(); - } - ELSE IF( EQ_16( st_fx->last_L_frame, 512 ) ) - { - /* (float)12800/(float)25600; */ - k = 16384; // Q15 - move16(); - } - ELSE /* st->last_L_frame == L_FRAME16k */ - { - /* (float)12800/(float)16000; */ - k = 26214; // Q15 - move16(); - } - - FOR( i = NB_SUBFR16k - NB_SUBFR; i < NB_SUBFR16k; i++ ) - { - st_fx->old_pitch_buf_fx[i - 1] = Mpy_32_16_1( st_fx->old_pitch_buf_fx[i], k ); // Q(15+15+1-16) - move32(); - } - - FOR( i = 2 * NB_SUBFR16k - NB_SUBFR; i < 2 * NB_SUBFR16k; i++ ) - { - st_fx->old_pitch_buf_fx[i - 2] = Mpy_32_16_1( st_fx->old_pitch_buf_fx[i], k ); // Q15 - move32(); - } - } - ELSE - { - - IF( EQ_16( st_fx->last_L_frame, L_FRAME32k ) ) - { - /* (float)16000/(float)32000; */ - k = -16384; // -0.5 in Q15 - move16(); - } - ELSE IF( EQ_16( st_fx->last_L_frame, 512 ) ) - { - /* tmpF = (float)16000/(float)25600; */ - k = -12288; //-0.375 in Q15 - move16(); - } - ELSE /* st->last_L_frame == L_FRAME12k8 */ - { - /* tmpF = (float)16000/(float)12800; */ - k = 8192; //.25 in Q15 - move16(); - } - - FOR( i = 2 * NB_SUBFR - 1; i >= NB_SUBFR; i-- ) - { - st_fx->old_pitch_buf_fx[i + 2] = L_add( st_fx->old_pitch_buf_fx[i], Mpy_32_16_1( st_fx->old_pitch_buf_fx[i], k ) ); // Q15 - move32(); - } - st_fx->old_pitch_buf_fx[NB_SUBFR + 1] = st_fx->old_pitch_buf_fx[NB_SUBFR + 2]; - move32(); - - FOR( i = NB_SUBFR - 1; i >= 0; i-- ) - { - st_fx->old_pitch_buf_fx[i + 1] = L_add( st_fx->old_pitch_buf_fx[i], Mpy_32_16_1( st_fx->old_pitch_buf_fx[i], k ) ); // Q15 - move32(); - } - st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[1]; - move32(); - } - } - - IF( NE_16( st_fx->bfi_pitch_frame, st_fx->L_frame ) ) - { - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - - IF( EQ_16( st_fx->bfi_pitch_frame, L_FRAME32k ) ) - { - /* (float)12800/(float)32000; */ - k = 13107; // Q15 - move16(); - } - ELSE IF( EQ_16( st_fx->bfi_pitch_frame, 512 ) ) - { - /* (float)12800/(float)25600; */ - k = 16384; // Q15 - move16(); - } - ELSE /* st->bfi_pitch_frame == L_FRAME16k */ - { - /* (float)12800/(float)16000; */ - k = 26214; // Q15 - move16(); - } - st_fx->bfi_pitch_fx = mult_r( k, st_fx->bfi_pitch_fx ); - move16(); - st_fx->bfi_pitch_frame = L_FRAME; - move16(); - } - ELSE - { - - IF( EQ_16( st_fx->bfi_pitch_frame, L_FRAME32k ) ) - { - /* (float)16000/(float)32000; */ - k = -16384; //-0.5 in Q15 - move16(); - } - ELSE IF( EQ_16( st_fx->bfi_pitch_frame, 512 ) ) - { - /* tmpF = (float)16000/(float)25600; */ - k = -12288; // -0.375 in Q15 - move16(); - } - ELSE /* st->bfi_pitch_frame == L_FRAME12k8 */ - { - /* tmpF = (float)16000/(float)12800; */ - k = 8192; // .25 in Q15 - move16(); - } - st_fx->bfi_pitch_fx = add( st_fx->bfi_pitch_fx, mult_r( st_fx->bfi_pitch_fx, k ) ); - move16(); - st_fx->bfi_pitch_frame = L_FRAME16k; - move16(); - } - } - - test(); - test(); - if ( EQ_16( st_fx->last_bwidth, NB ) && NE_16( st_fx->bwidth, NB ) && st_fx->ini_frame != 0 ) - { - st_fx->rate_switching_reset = 1; - move16(); - } - - /*----------------------------------------------------------------------* - * GOOD frame - *----------------------------------------------------------------------*/ - - IF( !st_fx->bfi ) - { - - /*----------------------------------------------------------------* - * Decoding of TC subframe classification - *----------------------------------------------------------------*/ - - tc_subfr_fx = -1; - move16(); - IF( EQ_16( st_fx->coder_type, TRANSITION ) ) - { - tc_subfr_fx = tc_classif_fx( st_fx, st_fx->L_frame ); - } - - /*----------------------------------------------------------------* - * Decoding of GSC IVAS mode - *----------------------------------------------------------------*/ - st_fx->GSC_IVAS_mode = 0; - move16(); - test(); - test(); - test(); - test(); - IF( ( st_fx->element_mode > EVS_MONO ) && st_fx->idchan == 0 && !( ( st_fx->core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) && !tdm_low_rate_mode ) - { - test(); - test(); - IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) - { - st_fx->GSC_IVAS_mode = get_next_indice( st_fx, 2 ); - move16(); - } - } - - /*----------------------------------------------------------------* - * Decoding of inactive CNG frames - *----------------------------------------------------------------*/ - test(); - IF( st_fx->core_brate == FRAME_NO_DATA || EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - /* decode CNG parameters */ - IF( st_fx->cng_type == LP_CNG ) - { - - CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); - - /* comfort noise generation */ - CNG_exc_fx( st_fx->core_brate, st_fx->L_frame, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, - &st_fx->first_CNG, &( st_fx->hTdCngDec->cng_ener_seed ), bwe_exc_fx, allow_cn_step_fx, &st_fx->hTdCngDec->last_allow_cn_step, st_fx->prev_Q_exc, st_fx->Q_exc, st_fx->hTdCngDec->num_ho, - q_env, st_fx->hTdCngDec->lp_env_fx, st_fx->hTdCngDec->old_env_fx, st_fx->hTdCngDec->exc_mem_fx, st_fx->hTdCngDec->exc_mem1_fx, sid_bw, &st_fx->hTdCngDec->cng_ener_seed1, exc3_fx, st_fx->Opt_AMR_WB, st_fx->element_mode ); - - Copy( Aq_fx, st_fx->Aq_cng, M + 1 ); // Q12 - } - ELSE - { - test(); - IF( EQ_32( st_fx->core_brate, SID_2k40 ) && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - FdCng_decodeSID_fx( st_fx->hFdCngDec->hFdCngCom, st_fx ); - *sid_bw = 0; - move16(); - } - - generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); - - FdCng_exc( st_fx->hFdCngDec->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); - - Copy( exc2_fx, exc3_fx, st_fx->L_frame ); - } - - delta_mem_scale = 3; - move16(); - test(); - if ( LT_32( st_fx->lp_ener_fx, 40 ) && ( st_fx->cng_type == LP_CNG ) ) /* very low energy frames, less than 0.3125 */ - { - delta_mem_scale = 0; - move16(); - } - i = st_fx->Q_exc; - move16(); - Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, - st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE ); - Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, - &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); - Copy_Scale_sig( exc2_fx, exc2_fx, st_fx->L_frame, sub( st_fx->Q_exc, i ) ); // Q_exc - - /* update past excitation signals for LD music post-filter */ - IF( hMusicPF != NULL ) - { - Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); - Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); - /* Update music post processing values */ - /* Filter energies update */ - FOR( i = 0; i < DCT_L_POST; i++ ) - { - /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); - move16(); - } - } - /* synthesis at 12.8kHz sampling rate */ - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc3_fx, syn1_fx, st_fx->mem_syn3_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); - - /* reset the decoder */ - CNG_reset_dec_fx( st_fx, pitch_buf_fx, voice_factors ); - - /* update st_fx->mem_syn1 for ACELP core switching */ - Copy( st_fx->mem_syn3_fx, st_fx->mem_syn1_fx, M ); - - /* update old synthesis for classification */ - Copy( syn1_fx + st_fx->L_frame - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); - - - /* save and delay synthesis to be used by SWB BWE */ - Copy_Scale_sig( syn1_fx, temp_buf_fx, st_fx->L_frame, sub( -1, st_fx->Q_syn ) ); // Q_syn -> Q(-1) - IF( hBWE_FD != NULL ) - { - save_old_syn_fx( st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); - } - } - - /*----------------------------------------------------------------* - * Decoding of all other frames - *----------------------------------------------------------------*/ - - ELSE - { - /*-----------------------------------------------------------------* - * Configure ACELP bit allocation - *-----------------------------------------------------------------*/ - nb_bits = 0; - st_fx->acelp_cfg.FEC_mode = 0; - uc_two_stage_flag = 0; - move16(); - move16(); - move16(); - test(); - IF( !st_fx->nelp_mode_dec && !st_fx->ppp_mode_dec ) - { - Word16 tc_subfr_tmp; - - tc_subfr_tmp = tc_subfr_fx; - move16(); - if ( LT_16( tc_subfr_tmp, L_SUBFR ) ) - { - tc_subfr_tmp = 0; - move16(); - } - - if ( EQ_16( tc_subfr_fx, TC_0_192 ) ) - { - nb_bits = -1; - move16(); - } - - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); - - test(); - test(); - IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) - { - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, TRANSITION, -1, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); - } - } - - /*-----------------------------------------------------------------* - * After CNG period, use the most up-to-date LSPs - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( st_fx->hTdCngDec != NULL && ( st_fx->last_core_brate == FRAME_NO_DATA || EQ_32( st_fx->last_core_brate, SID_2k40 ) ) ) - { - Copy( st_fx->lspCNG_fx, st_fx->lsp_old_fx, M ); // Q15 - - lsp2lsf_fx( st_fx->lspCNG_fx, st_fx->lsf_old_fx, M, int_fs ); - } - - /*-----------------------------------------------------------------* - * Reset higher ACELP pre-quantizer in case of switching - *-----------------------------------------------------------------*/ - - IF( !st_fx->use_acelp_preq ) - { - st_fx->mem_preemp_preQ_fx = 0; - move16(); - st_fx->last_nq_preQ = 0; - move16(); - } - - st_fx->use_acelp_preq = 0; - move16(); - - /*-----------------------------------------------------------------* - * LSF de-quantization and interpolation - *-----------------------------------------------------------------*/ - - lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, - tdm_lsfQ_PCh ); - - /*-----------------------------------------------------------------* - * FEC - first good frame after lost frame(s) (possibility to correct the ACB) - *-----------------------------------------------------------------*/ - - IF( st_fx->acelp_cfg.FEC_mode > 0 ) - { - last_pulse_pos = 0; - move16(); - - /* decode the last glottal pulse position */ - T0_tmp = FEC_pos_dec_fx( st_fx, &last_pulse_pos, &enr_q_fx, nb_bits ); - - - test(); - test(); - IF( NE_16( st_fx->last_core, HQ_CORE ) || ( EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->last_con_tcx ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st_fx->clas_dec, SIN_ONSET ) && last_pulse_pos != 0 && EQ_16( st_fx->prev_bfi, 1 ) ) - { - st_fx->Q_exc = - FEC_SinOnset_fx( old_exc_fx + L_EXC_MEM_DEC - L_EXC_MEM, last_pulse_pos, T0_tmp, enr_q_fx, Aq_fx, st_fx->L_frame, st_fx->Q_exc ); - move16(); - } - ELSE IF( ( EQ_16( st_fx->coder_type, GENERIC ) || EQ_16( st_fx->coder_type, VOICED ) ) && last_pulse_pos != 0 && EQ_16( st_fx->old_bfi_cnt, 1 ) && EQ_16( output_frame, L_FRAME16k ) && st_fx->hWIDec != NULL ) - { - do_WI_fx = FEC_enhACB_fx( st_fx->L_frame, st_fx->last_L_frame, old_exc_fx + L_EXC_MEM_DEC - L_EXC_MEM, T0_tmp, last_pulse_pos, st_fx->bfi_pitch_fx ); - } - } - } - - /*------------------------------------------------------------* - * In case of first frame after an erasure and transition from voiced to unvoiced or inactive - * redo the LPC interpolation - *------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - test(); - test(); - IF( st_fx->stab_fac_fx == 0 && st_fx->old_bfi_cnt > 0 && NE_16( st_fx->clas_dec, VOICED_CLAS ) && NE_16( st_fx->clas_dec, ONSET ) && - st_fx->relax_prev_lsf_interp == 0 && !( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) ) - { - int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid_fx, lsp_new_fx, Aq_fx, M, 2 ); - } - - /*---------------------------------------------------------------* - * Decoding of the scaled predicted innovation energy - *---------------------------------------------------------------*/ - - IF( nb_bits > 0 ) - { - indice = get_next_indice( st_fx, nb_bits ); - Es_pred_dec_fx( &Es_pred_fx, indice, nb_bits, uc_two_stage_flag ); - } - - /*------------------------------------------------------------* - * Decode excitation according to coding type - *------------------------------------------------------------*/ - - test(); - test(); - IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) - { - /* SC-VBR - NELP frames */ - Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, negate( st_fx->Q_exc ) ); // Q0 - st_fx->Q_exc = 0; - move16(); - - decod_nelp_fx( st_fx, &tmp_noise_fx, pitch_buf_fx, exc_fx, exc2_fx, voice_factors, bwe_exc_fx, &st_fx->Q_exc, st_fx->bfi, gain_buf ); - Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32) 0, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, L_FRAME, st_fx->coder_type ); - } - ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) ) - { - /* UNVOICED frames */ - decod_unvoiced_fx( st_fx, Aq_fx, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); - } - ELSE IF( EQ_16( st_fx->ppp_mode_dec, 1 ) ) - { - Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, negate( st_fx->Q_exc ) ); // Q0 - st_fx->Q_exc = 0; - move16(); - /* SC-VBR - PPP frames */ - IF( NE_32( ( error = decod_ppp_fx( st_fx, Aq_fx, pitch_buf_fx, exc_fx, exc2_fx, st_fx->bfi, gain_buf, voice_factors, bwe_exc_fx ) ), IVAS_ERR_OK ) ) - { - return error; - } - - Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32) 0, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, L_FRAME, st_fx->coder_type ); - } - ELSE IF( EQ_16( st_fx->coder_type, TRANSITION ) ) - { - decod_tran_fx( st_fx, st_fx->L_frame, tc_subfr_fx, Aq_fx, Es_pred_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, sharpFlag, gain_buf ); - } - ELSE IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) ) ) - { - decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf ); - tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ - } - ELSE - { - IF( NE_32( ( error = decod_gen_voic_fx( st_fx, st_fx->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf /*, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf*/ ) ), IVAS_ERR_OK ) ) - { - return error; - } - - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ - } - } - - /* synthesis for ACELP core switching and SWB BWE */ - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc_fx, temp_buf_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); - /* save and delay synthesis to be used by SWB BWE */ - IF( hBWE_FD != NULL ) - { - save_old_syn_fx( st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); - } - - /*-----------------------------------------------------------------* - * Apply energy matching when switching to inactive frames - *-----------------------------------------------------------------*/ - - Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); - /*------------------------------------------------------------* - * Decode information and modify the excitation signal of stationary unvoiced frames - *------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - IF( !( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) && NE_16( st_fx->nelp_mode_dec, 1 ) && !( EQ_16( st_fx->element_mode, IVAS_SCE ) && tdm_low_rate_mode ) ) - { - stat_noise_uv_dec_fx( st_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, exc2_fx, uc_two_stage_flag ); - } - - /*------------------------------------------------------------* - * Save filter memory in case the synthesis is redone after scaling - * Synthesis at 12k8 Hz sampling rate - *------------------------------------------------------------*/ - - /* update past excitation signals for LD music post-filter */ - IF( hMusicPF != NULL ) - { - Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); - Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); - Copy( hMusicPF->dct_post_old_exc_fx, exc_buffer_fx, DCT_L_POST - OFFSET2 ); - } - test(); - test(); - test(); - test(); - IF( hMusicPF != NULL && ( ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) || ( GE_16( st_fx->GSC_IVAS_mode, 1 ) && EQ_16( st_fx->L_frame, L_FRAME ) ) ) ) - { - - Word16 last_coder_type = st_fx->last_coder_type; - move16(); - test(); - test(); - test(); - if ( ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) || ( GE_16( st_fx->GSC_IVAS_mode, 1 ) && st_fx->GSC_noisy_speech == 0 ) ) - { - last_coder_type = AUDIO; - move16(); - } - /* Extrapolation of the last future part, windowing and high resolution DCT transform */ - qdct = 0; - move16(); -#ifdef _DIFF_FLOAT_FIX_ /* FLoat point using last_core which fits with the inner part of the function */ - Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, hMusicPF->filt_lfE_fx, st_fx->last_core, st_fx->element_mode, pitch_buf_fx, - hMusicPF->LDm_enh_lp_gbin_fx, st_fx->Q_exc, &qdct ); -#else - Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, hMusicPF->filt_lfE_fx, st_fx->last_coder_type, st_fx->element_mode, pitch_buf_fx, - hMusicPF->LDm_enh_lp_gbin_fx, st_fx->Q_exc, &qdct ); -#endif - /* LD music post-filter */ - LD_music_post_filter_fx( hMusicPF, dct_buffer_fx, dct_buffer_fx, st_fx->core_brate, - &hMusicPF->Old_ener_Q, AUDIO, last_coder_type, qdct ); - - /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */ - Post_music_postP_fx( dct_buffer_fx, exc2_fx, st_fx->mem_syn2_fx, st_fx->mem_syn2_fx, Aq_fx, syn_fx, &st_fx->Q_exc, &st_fx->prev_Q_syn, - &st_fx->Q_syn, st_fx->mem_syn_clas_estim_fx, 0, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, - &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, temp_buf_fx, mem_tmp_fx ); - } - ELSE - { - /* Core synthesis at 12.8kHz or 16kHz */ - i = 1; - move16(); - if ( st_fx->coder_type == INACTIVE ) - { - i = 0; - move16(); - } - /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */ - k = 0; - move16(); - test(); - test(); - if ( ( st_fx->coder_type == INACTIVE ) && st_fx->flag_cna && GE_16( round_fx( L_shl( st_fx->lp_noise, 1 ) ), 15 << 7 ) ) - { - k = 1; - move16(); - } - - Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx, - hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, i, k, temp_buf_fx ); - Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); // Q_syn - - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); - IF( hMusicPF != NULL ) - { - FOR( i = 0; i < DCT_L_POST; i++ ) - { - /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); - move16(); - } - } - } - - /*------------------------------------------------------------* - * FEC - Estimate the classification information - *------------------------------------------------------------*/ - - FEC_clas_estim_fx( st_fx, st_fx->Opt_AMR_WB, st_fx->L_frame, &st_fx->clas_dec, st_fx->coder_type, pitch_buf_fx, - syn_fx, &st_fx->lp_ener_FER_fx, &st_fx->decision_hyst, - NULL, NULL, NULL, NULL, 0, NULL, st_fx->Q_syn, temp_buf_fx, - st_fx->mem_syn_clas_estim_fx, &st_fx->classifier_Q_mem_syn, - 0, 0, 0, st_fx->last_core_brate, st_fx->acelp_cfg.FEC_mode ); - /*------------------------------------------------------------* - * FEC - Estimate pitch - *------------------------------------------------------------*/ - - FEC_pitch_estim_fx( st_fx->Opt_AMR_WB, st_fx->last_core, st_fx->L_frame, st_fx->clas_dec, st_fx->last_good, pitch_buf_fx, st_fx->old_pitch_buf_fx, - &st_fx->bfi_pitch_fx, &st_fx->bfi_pitch_frame, &st_fx->upd_cnt, st_fx->coder_type, st_fx->element_mode ); - - /*------------------------------------------------------------* - * FEC - Smooth the speech energy evolution when recovering after a BAD frame - * (smoothing is performed in the excitation domain and signal is resynthesized after) - *------------------------------------------------------------*/ - - k = 0; - move16(); - FOR( i = 0; i < st_fx->L_frame; i += L_SUBFR ) - { - pitch_buf_tmp[k] = mult_r( pitch_buf_fx[k], 512 ); // Q0(6+9-15) , (512 = 1.0f in Q9) - move16(); - k = add( k, 1 ); - } - - FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, - &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, - exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); - - test(); - test(); - test(); - test(); - IF( ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && LE_32( st_fx->total_brate, ACELP_7k20 ) ) || ( EQ_32( st_fx->total_brate, ACELP_7k20 ) ) || ( EQ_32( st_fx->total_brate, ACELP_8k00 ) ) ) - { - frame_ener_fx( st_fx->L_frame, st_fx->clas_dec, syn_fx, pitch_buf_tmp[sub( shr( st_fx->L_frame, 6 ), 1 )], &st_fx->enr_old_fx, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); - } - } - - } /* End of GOOD FRAME */ - - /*----------------------------------------------------------------* - * BAD frame - *----------------------------------------------------------------*/ - ELSE - { - /* SC-VBR */ - if ( EQ_16( st_fx->last_nelp_mode_dec, 1 ) ) - { - st_fx->nelp_mode_dec = 1; - move16(); - } - - /* long burst frame erasures */ - test(); - test(); - if ( GT_16( st_fx->nbLostCmpt, 5 ) && GE_16( st_fx->clas_dec, VOICED_CLAS ) && LT_16( st_fx->clas_dec, INACTIVE_CLAS ) ) - { - st_fx->last_good = VOICED_TRANSITION; - move16(); - } - - /* LSF estimation and A(z) calculation */ - lsf_dec_bfi( MODE1, lsf_new_fx, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx, - st_fx->stab_fac_fx, st_fx->last_coder_type, st_fx->L_frame, st_fx->last_good, - st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth ); - - FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx ); - - IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) - { - /* SC-VBR */ - Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, negate( st_fx->Q_exc ) ); // Q0 - st_fx->Q_exc = 0; - move16(); - - decod_nelp_fx( st_fx, &tmp_noise_fx, pitch_buf_fx, exc_fx, exc2_fx, voice_factors, bwe_exc_fx, &st_fx->Q_exc, st_fx->bfi, gain_buf ); - FEC_pitch_fx = pitch_buf_fx[3]; - move16(); - - Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32) 0, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, L_FRAME, st_fx->coder_type ); - } - ELSE - { - /* calculation of excitation signal */ - - FEC_exc_estim_fx( st_fx, st_fx->L_frame, exc_fx, exc2_fx, dct_exc_tmp, pitch_buf_fx, voice_factors, &FEC_pitch_fx, bwe_exc_fx, lsf_new_fx, &st_fx->Q_exc, &tmp_noise_fx ); - - Rescale_exc( NULL, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, L_FRAME32k, (Word32) 0, - &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, st_fx->L_frame, st_fx->last_coder_type ); - - tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ - - /* SC-VBR */ - st_fx->prev_gain_pit_dec_fx = st_fx->lp_gainp_fx; - move16(); /*Q14*/ - } - - /* synthesis for ACELP core switching and SWB BWE */ - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc_fx, temp_buf_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); /*old_syn_12k8_16k directly in q-1*/ - - /* save and delay synthesis to be used by SWB BWE */ - IF( hBWE_FD != NULL ) - { - save_old_syn_fx( st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); - } - /* Apply energy matching when switching to inactive frames */ - Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); - - /* udate past excitation signals for LD music post-filter */ - IF( hMusicPF != NULL ) - { - Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); - Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); - /* Update music post processing values */ - /* Filter energies update */ - FOR( i = 0; i < DCT_L_POST; i++ ) - { - /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ - hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( ( 1228 << ( 16 ) ), 22938, hMusicPF->filt_lfE_fx[i] ) ); - move16(); - } - /* Update circular buffer, keep last energy difference unchanged */ - FOR( i = 1; i < MAX_LT; i++ ) - { - hMusicPF->LDm_lt_diff_etot_fx[i - 1] = hMusicPF->LDm_lt_diff_etot_fx[i]; - move16(); - } - } - /* synthesis at 12k8 Hz sampling rate */ - /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */ - k = 0; - move16(); - test(); - test(); - if ( ( st_fx->coder_type == INACTIVE ) && st_fx->flag_cna && GE_16( round_fx( L_shl( st_fx->lp_noise, 1 ) ), 15 << 7 ) ) - { - k = 1; - move16(); - } - - Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx, - hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 1, k, temp_buf_fx ); - - test(); - IF( ( EQ_32( st_fx->total_brate, ACELP_7k20 ) ) || ( EQ_32( st_fx->total_brate, ACELP_8k00 ) ) ) - { - Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); // Q_syn - } - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); - - /* update buffer for classifier */ - IF( st_fx->hWIDec != NULL ) - { - Copy( exc2_fx + st_fx->L_frame - L_EXC_MEM, st_fx->hWIDec->old_exc2_fx, L_EXC_MEM ); - Copy( syn_fx + st_fx->L_frame - L_EXC_MEM, st_fx->hWIDec->old_syn2_fx, L_EXC_MEM ); - } - st_fx->prev_Q_exc_fr = st_fx->Q_exc; - move16(); - st_fx->prev_Q_syn_fr = st_fx->Q_syn; - move16(); - - Copy( syn_fx + st_fx->L_frame - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); - - test(); - IF( ( EQ_32( st_fx->total_brate, ACELP_7k20 ) ) || ( EQ_32( st_fx->total_brate, ACELP_8k00 ) ) ) - { - k = 0; - move16(); - FOR( i = 0; i < st_fx->L_frame; i += L_SUBFR ) - { - pitch_buf_tmp[k] = mult_r( pitch_buf_fx[k], 512 ); // Q0(6+9-15) , (512 = 1.0f in Q9) - move16(); - k = add( k, 1 ); - } - - /*------------------------------------------------------------* - * FEC - Smooth the speech energy evolution when recovering after a BAD frame - * (smoothing is performed in the excitation domain and signal is resynthesized after) - *------------------------------------------------------------*/ - - FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type, LSF_Q_prediction, - &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, - exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); - } - - /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ - /* fer_energy( st_fx->L_frame, st_fx->last_good, syn_fx, FEC_pitch_fx, &st_fx->enr_old_fx, st_fx->L_frame ); */ - frame_ener_fx( st_fx->L_frame, st_fx->last_good, syn_fx, shr( add( FEC_pitch_fx, 32 ), 6 ), &st_fx->enr_old_fx, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); - - IF( st_fx->nelp_mode_dec != 1 ) - { - /* modify the excitation signal of stationary unvoiced frames */ - stat_noise_uv_mod_fx( st_fx->coder_type, 0, st_fx->lsp_old_fx, lsp_new_fx, lsp_new_fx, Aq_fx, exc2_fx, st_fx->Q_exc, 1, &st_fx->ge_sm_fx, - &st_fx->uv_count, &st_fx->act_count, st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, - &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); - } - - /* SC-VBR */ - st_fx->hSC_VBR->FadeScale_fx = mult( st_fx->hSC_VBR->FadeScale_fx, 24576 ); /*24576 in Q15*/ - move16(); - } - IF( hBWE_TD != NULL ) - { - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - Copy( Aq_fx + 2 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); // Q12 - } - ELSE - { - Copy( Aq_fx + 3 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); // Q12 - } - } - /*--------------------------------------------------------* - * Apply NB postfilter in case of 8kHz output - *--------------------------------------------------------*/ - test(); - IF( EQ_16( st_fx->last_bwidth, NB ) && st_fx->hPFstat != NULL ) - { - k = 0; - move16(); - FOR( i = 0; i < st_fx->L_frame; i += L_SUBFR ) - { - pitch_buf_tmp[k] = mult_r( pitch_buf_fx[k], 512 ); // Q0(6+9-15) , (512 = 1.0f in Q9) - move16(); - k = add( k, 1 ); - } - - IF( EQ_16( st_fx->bwidth, NB ) ) - { - st_fx->hPFstat->on = 1; - move16(); - nb_post_filt_fx( st_fx->L_frame, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, st_fx->coder_type, st_fx->BER_detect, 0 ); - } - ELSE - { - st_fx->hPFstat->on = 0; - move16(); - nb_post_filt_fx( st_fx->L_frame, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, AUDIO, st_fx->BER_detect, 0 ); - } - } - ELSE - { - st_fx->psf_lp_noise_fx = round_fx( L_shl( st_fx->lp_noise, 1 ) ); - move16(); - } - - /*------------------------------------------------------------------* - * Perform fixed deemphasis through 1/(1 - g*z^-1) - *-----------------------------------------------------------------*/ - - /* Update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( syn_fx + st_fx->L_frame - L_SYN_MEM, st_fx->mem_syn_r, L_SYN_MEM ); - deemph_fx( syn_fx, st_fx->preemph_fac, st_fx->L_frame, &( st_fx->mem_deemph_fx ) ); - unscale_AGC( syn_fx, st_fx->Q_syn, syn_fx_tmp2, st_fx->agc_mem_fx, st_fx->L_frame ); - Copy( syn_fx_tmp2, syn_fx, st_fx->L_frame ); - - /* Update MODE2 memories*/ - IF( hTcxDec != NULL ) - { - Copy_Scale_sig( syn_fx + shr( st_fx->L_frame, 1 ), hTcxDec->old_syn_Overl, shr( st_fx->L_frame, 1 ), sub( -1, st_fx->Q_syn ) ); /*Q-1*/ - } - Copy_Scale_sig( syn_fx + st_fx->L_frame - M - 1, st_fx->syn, M + 1, sub( 0, st_fx->Q_syn ) ); /*Q0*/ - - /*------------------------------------------------------------------* - * Formant post-filter - *-----------------------------------------------------------------*/ - - IF( st_fx->hPFstat != NULL ) - { - test(); - test(); - test(); - IF( GE_16( st_fx->last_bwidth, WB ) && ( GT_32( st_fx->core_brate, ACELP_24k40 ) || ( st_fx->element_mode > EVS_MONO ) ) && LE_32( st_fx->core_brate, ACELP_32k ) ) - { - Copy( syn_fx, temp_buf + L_SYN_MEM, L_FRAME16k ); - st_fx->hPFstat->on = 1; - move16(); - formant_post_filt_fx( st_fx->hPFstat, temp_buf + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME16k, st_fx->lp_noise, st_fx->total_brate, 0 ); - } - ELSE IF( GE_16( st_fx->last_bwidth, WB ) ) - { - IF( st_fx->hPFstat->on ) - { - Copy( st_fx->hPFstat->mem_pf_in + L_SYN_MEM - M, temp_buf, M ); - Copy( syn_fx, temp_buf + M, L_SUBFR ); - Residu3_fx( Aq_fx, temp_buf + M, temp_buf + M + L_SUBFR, L_SUBFR, 1 ); - E_UTIL_synthesis( 1, Aq_fx, temp_buf + M + L_SUBFR, temp_buf, L_SUBFR, st_fx->hPFstat->mem_stp + L_SYN_MEM - M, 0, M ); - scale_st_fx( syn_fx, temp_buf, &st_fx->hPFstat->gain_prec, L_SUBFR ); - Copy( temp_buf, syn_fx, L_SUBFR / 2 ); - blend_subfr2_fx( temp_buf + L_SUBFR / 2, syn_fx + L_SUBFR / 2, syn_fx + L_SUBFR / 2 ); - } - st_fx->hPFstat->on = 0; - move16(); - } - } - /*----------------------------------------------------------------* - * Comfort noise addition - *----------------------------------------------------------------*/ - - test(); - test(); - IF( ( st_fx->hFdCngDec != NULL || EQ_16( st_fx->idchan, 1 ) ) && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || st_fx->flag_cna || ( EQ_16( st_fx->cng_type, FD_CNG ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || ( ( st_fx->cng_type == LP_CNG ) && LE_32( st_fx->total_brate, SID_2k40 ) ) ) - { - /*VAD only for non inactive frame*/ - test(); - st_fx->VAD = st_fx->VAD && ( st_fx->coder_type != INACTIVE ); - move16(); - test(); - test(); - test(); - test(); - test(); - IF( st_fx->idchan == 0 && ( st_fx->flag_cna || ( EQ_16( st_fx->cng_type, FD_CNG ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || - ( EQ_16( st_fx->cng_type, LP_CNG ) && LE_32( st_fx->total_brate, SID_2k40 ) ) ) ) - { - /*Noisy speech detector*/ - noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD, syn_fx, st_fx->Q_syn ); - - st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440 /*0.99 Q15*/ ); - move16(); - IF( st_fx->hFdCngDec->hFdCngCom->flag_noisy_speech != 0 ) - { - st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = add( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 328 /*0.01 Q15*/ ); - move16(); - } - } - if ( st_fx->idchan == 0 ) - { - st_fx->lp_noise = st_fx->hFdCngDec->lp_noise; - move32(); - } - /*Noise estimate*/ - IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) /* && !st->cng_ism_flag IVAS_CODE */ ) - { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - PMT( "Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done" ) - ApplyFdCng_fx( syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else - ApplyFdCng_fx( syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) ); -#endif - } - /* CNA: Generate additional comfort noise to mask potential coding artefacts */ - } - - test(); - test(); - test(); - test(); - IF( st_fx->flag_cna && NE_16( st_fx->coder_type, AUDIO ) ) - { - generate_masking_noise_fx( syn_fx, st_fx->Q_syn, st_fx->hFdCngDec->hFdCngCom, st_fx->hFdCngDec->hFdCngCom->frameSize, 0 ); - } - ELSE IF( st_fx->flag_cna && EQ_16( st_fx->coder_type, AUDIO ) && st_fx->last_core == ACELP_CORE && NE_16( st_fx->last_coder_type, AUDIO ) ) - { - FOR( i = 0; i < st_fx->hFdCngDec->hFdCngCom->frameSize / 2; i++ ) - { - syn_fx[i] = add( syn_fx[i], shr_r( mult_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->hFdCngDec->hFdCngCom->frameSize / 4], st_fx->hFdCngDec->hFdCngCom->fftlenFac ), -st_fx->Q_syn ) ); - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( st_fx->flag_cna == 0 && EQ_16( st_fx->L_frame, L_FRAME16k ) && EQ_16( st_fx->last_flag_cna, 1 ) && ( ( st_fx->last_core == ACELP_CORE && NE_16( st_fx->last_coder_type, AUDIO ) ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) - { - FOR( i = 0; i < st_fx->L_frame / 2; i++ ) - { - syn_fx[i] = add( syn_fx[i], shr_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->L_frame / 4], negate( st_fx->Q_syn ) ) ); - move16(); - } - } - - test(); - IF( st_fx->flag_cna == 0 || EQ_16( st_fx->coder_type, AUDIO ) ) - { - set16_fx( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st_fx->hFdCngDec->hFdCngCom->fftlen ); - } - } - - /*----------------------------------------------------------------* - * Resample to the output sampling rate (8/16/32/48 kHz) - * Bass post-filter - *----------------------------------------------------------------*/ - - /* check if the CLDFB works on the right sample rate */ - IF( ( st_fx->cldfbAna->usb * st_fx->cldfbAna->no_col ) != st_fx->L_frame ) - { - /* resample to ACELP internal sampling rate */ - Word16 newCldfbBands = CLDFB_getNumChannels( L_mult0( st_fx->L_frame, FRAMES_PER_SEC ) ); - resampleCldfb( st_fx->cldfbAna, newCldfbBands, st_fx->L_frame, 0 ); - resampleCldfb( st_fx->cldfbBPF, newCldfbBands, st_fx->L_frame, 0 ); - - IF( st_fx->ini_frame > 0 ) - { - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ); - move16(); - } - } - - test(); - IF( !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->bpf_off ) ) - { - test(); - IF( NE_16( st_fx->L_frame, st_fx->last_L_frame ) && NE_16( st_fx->last_codec_mode, MODE2 ) ) - { - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - retro_interp5_4_fx( hBPF->pst_old_syn_fx ); - } - ELSE IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - retro_interp4_5_fx( syn_fx, hBPF->pst_old_syn_fx ); - } - } - - bass_psfilter_fx( st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, st_fx->L_frame, pitch_buf_fx, st_fx->bpf_off, - st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, st_fx->coder_type, st_fx->Q_syn, bpf_error_signal ); - } - test(); - IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) - { - /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); - - scaleFactor.hb_scale = scaleFactor.lb_scale; - move16(); - - /* analysis and add the BPF error signal */ - i = 0; - move16(); - if ( st_fx->bpf_off == 0 ) - { - i = CLDFB_NO_COL_MAX; - move16(); - } - addBassPostFilter_fx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate( st_fx->Q_syn ), - i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor ); - - /* set output mask for upsampling */ - IF( EQ_16( st_fx->bwidth, NB ) ) - { - /* set NB mask for upsampling */ - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, 10 ); - move16(); - } - ELSE IF( NE_16( st_fx->cldfbSyn->bandsToZero, sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ) ) ) - { - /* in case of BW switching, re-init to default */ - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ); - move16(); - } - - /*WB/SWB-FD_CNG*/ - scaleFactor.hb_scale = scaleFactor.lb_scale; - move16(); - - - test(); - IF( !st_fx->cng_sba_flag || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - test(); - test(); - test(); - IF( ( ( st_fx->core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) && ( EQ_16( st_fx->cng_type, FD_CNG ) ) && ( LT_16( st_fx->hFdCngDec->hFdCngCom->numCoreBands, st_fx->cldfbSyn->no_channels ) ) ) - { - generate_comfort_noise_dec_hf_fx( realBuffer, imagBuffer, &scaleFactor.hb_scale, st_fx ); - - st_fx->cldfbSyn->bandsToZero = 0; - move16(); - IF( LT_16( st_fx->hFdCngDec->hFdCngCom->regularStopBand, st_fx->cldfbSyn->no_channels ) ) - { - st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->hFdCngDec->hFdCngCom->regularStopBand ); - move16(); - } - st_fx->cldfbSyn->lsb = st_fx->cldfbAna->no_channels; - move16(); - } - } - /* synthesis of the combined signal */ - st_fx->Q_syn2 = st_fx->Q_syn; - move16(); - { - cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); - } - /* Bring CLDFB output to Q0 */ - Scale_sig( synth_out, output_frame, negate( st_fx->Q_syn2 ) ); - st_fx->Q_syn2 = 0; - move16(); - - /* save synthesis - needed in case of core switching */ - Copy( synth_out, st_fx->previoussynth_fx, output_frame ); - } - - /*-----------------------------------------------------------------* - * Bandwidth extension 6kHz-7kHz - *-----------------------------------------------------------------*/ - IF( st_fx->hBWE_zero != NULL ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st_fx->L_frame, L_FRAME ) && NE_16( st_fx->bwidth, NB ) && GE_16( output_frame, L_FRAME16k ) && - ( EQ_16( st_fx->extl, -1 ) || EQ_16( st_fx->extl, SWB_CNG ) || ( EQ_16( st_fx->extl, WB_BWE ) && st_fx->extl_brate == 0 && NE_16( st_fx->coder_type, AUDIO ) ) ) ) ) - { - hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, st_fx->Q_syn2 ); - } - ELSE - { - hf_synth_reset_fx( st_fx->hBWE_zero ); - } - } - - /*-----------------------------------------------------------------* - * Populate parameters for SWB TBE - *-----------------------------------------------------------------*/ - - /* Apply a non linearity to the SHB excitation */ - IF( hBWE_TD != NULL ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( !st_fx->bfi && ( st_fx->prev_bfi ) ) || ( ( EQ_16( st_fx->last_vbr_hw_BWE_disable_dec, 1 ) ) && ( st_fx->vbr_hw_BWE_disable_dec == 0 ) ) || ( ( EQ_16( st_fx->extl, SWB_TBE ) || EQ_16( st_fx->extl, WB_TBE ) || EQ_16( st_fx->extl, FB_TBE ) ) && NE_16( st_fx->last_extl, SWB_TBE ) && NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, FB_TBE ) ) || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && !st_fx->tdm_LRTD_flag ) ) - { - hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); - move32(); - set16_fx( hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); - } - - test(); - test(); - test(); - test(); - test(); - IF( !st_fx->ppp_mode_dec && ( st_fx->idchan == 0 || NE_16( st_fx->element_mode, IVAS_CPE_TD ) || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && st_fx->tdm_LRTD_flag ) ) ) - { - non_linearity_fx( bwe_exc_fx, bwe_exc_extended, L_FRAME32k, &hBWE_TD->bwe_non_lin_prev_scale_fx, st_fx->Q_exc, - st_fx->coder_type, voice_factors, st_fx->L_frame ); - } - - test(); - IF( ( st_fx->core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); - move32(); - } - } - /*----------------------------------------------------------------------* - * Updates - *----------------------------------------------------------------------*/ - - updt_dec_fx( st_fx, old_exc_fx, pitch_buf_fx, Es_pred_fx, Aq_fx, lsf_new_fx, lsp_new_fx, voice_factors, old_bwe_exc_fx, gain_buf ); - - test(); - test(); - IF( GT_32( st_fx->core_brate, SID_2k40 ) && st_fx->hTdCngDec != NULL && st_fx->hFdCngDec != NULL ) - { - /* update CNG parameters in active frames */ - cng_params_upd_fx( lsp_new_fx, exc_fx, st_fx->L_frame, &st_fx->hTdCngDec->ho_circ_ptr, st_fx->hTdCngDec->ho_ener_circ_fx, &st_fx->hTdCngDec->ho_circ_size, st_fx->hTdCngDec->ho_lsp_circ_fx, - st_fx->Q_exc, DEC, st_fx->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st_fx->last_active_brate ); - /* Set 16k LSP flag for CNG buffer */ - st_fx->hTdCngDec->ho_16k_lsp[st_fx->hTdCngDec->ho_circ_ptr] = 0; - move16(); - if ( NE_16( st_fx->L_frame, L_FRAME ) ) - { - st_fx->hTdCngDec->ho_16k_lsp[st_fx->hTdCngDec->ho_circ_ptr] = 1; - move16(); - } - } - - return IVAS_ERR_OK; -} -#endif diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index ad8ca9b50..2c72bba78 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -47,12 +47,12 @@ /*-------------------------------------------------------------------* - * acelp_core_dec_ivas_fx() + * acelp_core_dec_fx() * * ACELP core decoder *-------------------------------------------------------------------*/ -ivas_error acelp_core_dec_ivas_fx( +ivas_error acelp_core_dec_fx( Decoder_State *st, /* i/o: decoder state structure */ Word16 output_fx[], /* o : synthesis @internal Fs Q_syn*/ Word16 synth_fx16[], /* o : synthesis Q_syn2*/ @@ -81,14 +81,14 @@ ivas_error acelp_core_dec_ivas_fx( Word16 syn_tmp_fx[L_FRAME16k + L_SUBFR], *psyn_fx; /* synthesis signal buffer */ Word16 output_frame; /* frame length at output sampling freq. */ Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56) */ - Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ + Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */ Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(q) quantized for the 4 subframes */ Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ Word32 enr_q_fx; /* E information for FER protection */ Word16 tmp_noise_fx; /* Long term temporary noise energy */ - Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ + Word16 Es_pred_fx; /* predicted scaled innov. energy Q8 */ Word16 FEC_pitch_fx; /* FEC pitch */ Word16 old_bwe_exc_fx[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ Word16 *bwe_exc_fx; /* Excitation for SWB TBE */ @@ -181,6 +181,7 @@ ivas_error acelp_core_dec_ivas_fx( st->hFdCngDec->hFdCngCom->sidNoiseEstExp = common_e; move16(); } + FOR( i = 0; i < NPART; i++ ) { st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = Madd_32_32( Mpy_32_32( STEREO_DFT_FD_FILT_Q31, st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] ), @@ -188,14 +189,14 @@ ivas_error acelp_core_dec_ivas_fx( move32(); } - ApplyFdCng_ivas_fx( NULL, 0, NULL, 0, NULL, NULL, NULL, st, 0, 0 ); + ApplyFdCng_fx( NULL, 0, NULL, 0, NULL, NULL, NULL, st, 0, 0 ); } ELSE { configureFdCngDec_fx( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); /* decode CNG parameters */ - CNG_dec_ivas_fx( st, last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sid_bw, q_env_fx ); + CNG_dec_fx( st, last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sid_bw, q_env_fx ); /* comfort noise generation */ CNG_exc_fx( st->core_brate, st->L_frame, &st->hTdCngDec->Enew_fx, &st->hTdCngDec->cng_seed, NULL, NULL, &st->lp_ener_fx, st->last_core_brate, &st->first_CNG, &( st->hTdCngDec->cng_ener_seed ), NULL, allow_cn_step, &st->hTdCngDec->last_allow_cn_step, st->prev_Q_exc, st->Q_exc, st->hTdCngDec->num_ho, q_env_fx, st->hTdCngDec->lp_env_fx, st->hTdCngDec->old_env_fx, st->hTdCngDec->exc_mem_fx, st->hTdCngDec->exc_mem1_fx, sid_bw, &st->hTdCngDec->cng_ener_seed1, NULL, st->Opt_AMR_WB, st->element_mode ); @@ -636,7 +637,7 @@ ivas_error acelp_core_dec_ivas_fx( /* decode CNG parameters */ IF( st->cng_type == LP_CNG ) { - CNG_dec_ivas_fx( st, last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sid_bw, q_env_fx ); + CNG_dec_fx( st, last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sid_bw, q_env_fx ); Copy( Aq_fx, st->Aq_cng, add( M, 1 ) ); /* comfort noise generation */ @@ -657,13 +658,11 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { FdCng_decodeSID_fx( st->hFdCngDec->hFdCngCom, st ); } ELSE -#endif { Word16 old_NoiseEstExp = st->hFdCngDec->hFdCngCom->sidNoiseEstExp; move16(); @@ -689,7 +688,7 @@ ivas_error acelp_core_dec_ivas_fx( move32(); } - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); Word16 new_sidNoiseEstExp = 31 - Q4; move16(); @@ -704,7 +703,7 @@ ivas_error acelp_core_dec_ivas_fx( move16(); test(); - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( EQ_16( st->coder_type, AUDIO ) && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( EQ_16( st->coder_type, AUDIO ) && !st->GSC_noisy_speech ) ); IF( st->hFdCngDec->hFdCngCom->cngNoiseLevelExp < 0 ) { @@ -728,13 +727,11 @@ ivas_error acelp_core_dec_ivas_fx( } } -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { generate_comfort_noise_dec_fx( NULL, NULL, NULL, st, &( st->Q_exc ), 2, -1 ); } ELSE -#endif { generate_comfort_noise_dec_ivas_fx( NULL, NULL, NULL, st, &( st->Q_exc ), 1, nchan_out ); } @@ -758,7 +755,6 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( st->hMusicPF && st->hGSCDec ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { // VE: TBV: should 'st_fx->L_frame * HIBND_ACB_L_FAC' be corrected in EVS? @@ -766,7 +762,6 @@ ivas_error acelp_core_dec_ivas_fx( st->L_frame * HIBND_ACB_L_FAC, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); } ELSE -#endif { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, L_FRAME32k, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); @@ -794,7 +789,6 @@ ivas_error acelp_core_dec_ivas_fx( /* Update music post processing values */ /* Filter energies update */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { FOR( i = 0; i < DCT_L_POST; i++ ) @@ -804,7 +798,6 @@ ivas_error acelp_core_dec_ivas_fx( } } ELSE -#endif { FOR( i = 0; i < DCT_L_POST; i++ ) { @@ -822,15 +815,12 @@ ivas_error acelp_core_dec_ivas_fx( /* reset the decoder */ CNG_reset_dec_fx( st, pitch_buf_fx, voice_factors_fx ); - -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { /* update st_fx->mem_syn1 for ACELP core switching */ Copy( st->mem_syn3_fx, st->mem_syn1_fx, M ); } ELSE -#endif { st->Q_syn_cng = st->Q_syn; move16(); @@ -889,13 +879,13 @@ ivas_error acelp_core_dec_ivas_fx( move16(); } - config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, st->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_fx( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, st->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); test(); test(); IF( EQ_16( st->coder_type, TRANSITION ) && LT_16( tc_subfr, L_SUBFR ) && EQ_16( st->L_frame, L_FRAME ) ) { - config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, TRANSITION, -1, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_fx( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, TRANSITION, -1, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } } @@ -934,7 +924,7 @@ ivas_error acelp_core_dec_ivas_fx( IF( !tdm_lp_reuse_flag ) { - lsf_dec_ivas_fx( st, tc_subfr, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, tdm_lsfQ_PCh_fx ); + lsf_dec_fx( st, tc_subfr, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, tdm_lsfQ_PCh_fx ); } ELSE { @@ -1084,7 +1074,7 @@ ivas_error acelp_core_dec_ivas_fx( } ELSE /* GENERIC */ { - decod_gen_2sbfr_ivas_fx( st, sharpFlag, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, gain_buf_fx, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ); + decod_gen_2sbfr_fx( st, sharpFlag, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, gain_buf_fx, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ); IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) { @@ -1106,7 +1096,7 @@ ivas_error acelp_core_dec_ivas_fx( ELSE IF( EQ_16( st->coder_type, UNVOICED ) ) { /* UNVOICED frames */ - decod_unvoiced_ivas_fx( st, Aq_fx, Es_pred_fx, uc_two_stage_flag, st->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, gain_buf_fx ); + decod_unvoiced_fx( st, Aq_fx, Es_pred_fx, uc_two_stage_flag, st->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, gain_buf_fx ); tmp_noise_fx = shr_r( st->lp_gainc_fx, 3 ); /*Q0*/ } @@ -1131,15 +1121,15 @@ ivas_error acelp_core_dec_ivas_fx( ELSE IF( EQ_16( st->coder_type, AUDIO ) || ( ( st->coder_type == INACTIVE ) && st->inactive_coder_type_flag ) ) { /* AUDIO and INACTIVE frames (coded by GSC technology) */ - decod_audio_ivas_fx( st, dct_exc_tmp_fx, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf_fx, - tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ); + decod_audio_fx( st, dct_exc_tmp_fx, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf_fx, + tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ); tmp_noise_fx = shr_r( st->lp_gainc_fx, 3 ); /*Q0*/ } ELSE { /* GENERIC, VOICED and INACTIVE frames (coded by AVQ technology) */ - IF( NE_32( ( error = decod_gen_voic_ivas_fx( st, st->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf_fx, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = decod_gen_voic_fx( st, st->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf_fx, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ) ), IVAS_ERR_OK ) ) { return error; } @@ -1163,7 +1153,7 @@ ivas_error acelp_core_dec_ivas_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); + Inac_switch_ematch_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames @@ -1212,7 +1202,6 @@ ivas_error acelp_core_dec_ivas_fx( move16(); /* Extrapolation of the last future part, windowing and high resolution DCT transform */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { // VE: TBV: this is likely a bug in EVS - 'st->last_coder_type' should be replaced by 'st->core_brate' @@ -1220,7 +1209,6 @@ ivas_error acelp_core_dec_ivas_fx( st->hMusicPF->LDm_enh_lp_gbin_fx, st->Q_exc, &qdct ); } ELSE -#endif { Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, st->hMusicPF->filt_lfE_fx, st->last_core, st->element_mode, pitch_buf_fx, st->hMusicPF->LDm_enh_lp_gbin_fx, st->Q_exc, &qdct ); } @@ -1229,9 +1217,7 @@ ivas_error acelp_core_dec_ivas_fx( LD_music_post_filter_fx( st->hMusicPF, dct_buffer_fx, dct_buffer_fx, st->core_brate, &st->hMusicPF->Old_ener_Q, AUDIO, last_coder_type, qdct ); /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */ -#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBC whether needed in IVAS -#endif { Copy( st->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/ } @@ -1300,13 +1286,9 @@ ivas_error acelp_core_dec_ivas_fx( Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 - FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, - &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, -#ifdef REMOVE_EVS_DUPLICATES - exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, st->element_mode, avoid_lpc_burst_on_recovery, 0 ); -#else - exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, 0 ); -#endif + FEC_scale_syn_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, + &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, st->element_mode, avoid_lpc_burst_on_recovery, 0 ); test(); test(); @@ -1384,7 +1366,7 @@ ivas_error acelp_core_dec_ivas_fx( } /* Apply energy matching when switching to inactive frames */ - Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); + Inac_switch_ematch_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); /* update past excitation signals for LD music post-filter */ IF( st->hMusicPF != NULL ) @@ -1452,13 +1434,9 @@ ivas_error acelp_core_dec_ivas_fx( { Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 - FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, - &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, -#ifdef REMOVE_EVS_DUPLICATES - exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, st->element_mode, avoid_lpc_burst_on_recovery, 0 ); -#else - exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, 0 ); -#endif + FEC_scale_syn_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, + &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, st->element_mode, avoid_lpc_burst_on_recovery, 0 ); } /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ @@ -1544,7 +1522,7 @@ ivas_error acelp_core_dec_ivas_fx( Copy( psyn_fx, temp_buf_fx + L_SYN_MEM, L_FRAME16k ); set16_fx( st->hPFstat->mem_zero, 0, M ); - formant_post_filt_ivas_fx( st->hPFstat, temp_buf_fx + L_SYN_MEM, Aq_fx, psyn_fx, st->L_frame, st->lp_noise, st->total_brate, 0 ); + formant_post_filt_fx( st->hPFstat, temp_buf_fx + L_SYN_MEM, Aq_fx, psyn_fx, st->L_frame, st->lp_noise, st->total_brate, 0 ); } ELSE IF( st->hPFstat != NULL && GE_16( st->last_bwidth, WB ) ) { @@ -1612,7 +1590,7 @@ ivas_error acelp_core_dec_ivas_fx( IF( NE_16( st->element_mode, IVAS_CPE_TD ) && !st->cng_ism_flag ) { /* Noise estimate */ - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } IF( !st->cna_dirac_flag ) @@ -1652,13 +1630,11 @@ ivas_error acelp_core_dec_ivas_fx( } ELSE IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { generate_masking_noise_fx( psyn_fx, st->Q_syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0 ); } ELSE -#endif { IF( st->idchan == 0 ) { @@ -1666,10 +1642,13 @@ ivas_error acelp_core_dec_ivas_fx( { set16_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st->hFdCngDec->hFdCngCom->fftlen ); } + Word32 psyn_32_fx[L_FRAME16k]; Copy_Scale_sig_16_32_no_sat( psyn_fx, psyn_32_fx, st->hFdCngDec->hFdCngCom->frameSize, sub( Q6, st->Q_syn ) ); // Q6 Copy_Scale_sig_16_32_no_sat( st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->hFdCngDec->hFdCngCom->frameSize, 1 ), Q15 ); // Q15 + generate_masking_noise_ivas_fx( psyn_32_fx, &exp, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); + Copy_Scale_sig_32_16( psyn_32_fx, psyn_fx, st->hFdCngDec->hFdCngCom->frameSize, sub( st->Q_syn, exp ) ); // Q = st->Q_syn Copy_Scale_sig_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2, shl( st->hFdCngDec->hFdCngCom->frameSize, 1 ), -Q15 ); // Q0 } @@ -1713,7 +1692,7 @@ ivas_error acelp_core_dec_ivas_fx( /*Noise estimate*/ IF( ( st->idchan == 0 ) && ( EQ_16( nchan_out, 2 ) || ( st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) ) ) ) { - ApplyFdCng_ivas_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx( psyn_fx, st->Q_syn, NULL, 0, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } } } @@ -1730,7 +1709,6 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( ( st->flag_cna == 0 ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->last_flag_cna, 1 ) && ( ( st->last_core == ACELP_CORE && !( EQ_16( st->last_coder_type, AUDIO ) && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || EQ_16( st->last_core, AMR_WB_CORE ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { // VE: TBV - is it correct in EVS? in FLP, it is: @@ -1743,7 +1721,6 @@ ivas_error acelp_core_dec_ivas_fx( } } ELSE -#endif { FOR( i = 0; i < ( st->hFdCngDec->hFdCngCom->frameSize ) / 2; i++ ) { @@ -1775,7 +1752,6 @@ ivas_error acelp_core_dec_ivas_fx( * Bass post-filter *----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { CLDFB_SCALE_FACTOR scaleFactor; @@ -1880,7 +1856,6 @@ ivas_error acelp_core_dec_ivas_fx( Copy( synth_fx16, st->previoussynth_fx, output_frame ); } ELSE -#endif { /* check if the CLDFB works on the right sample rate */ IF( NE_16( imult1616( st->cldfbAna->no_channels, st->cldfbAna->no_col ), st->L_frame ) ) @@ -1896,9 +1871,7 @@ ivas_error acelp_core_dec_ivas_fx( } /* analyze pitch coherence for bass post-filter */ - Word32 pitch_buf_fx_q20[12]; - Scale_sig32( st->old_pitch_buf_fx, 2 * NB_SUBFR16k + 2, Q4 ); // Q(x+4) Word16 lim = shr( st->L_frame, 6 ); FOR( Word16 lp = 0; lp < lim; lp++ ) @@ -1961,7 +1934,9 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, 1 ); // Q12 st->cldfbAna->Q_cldfb_state = Q12; move16(); + cldfbAnalysis_ivas_fx( syn_32_fx, realBuffer_fx, imagBuffer_fx, -1, st->cldfbAna ); + Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, -1 ); // Q11 st->cldfbAna->Q_cldfb_state = Q11; move16(); @@ -1990,6 +1965,7 @@ ivas_error acelp_core_dec_ivas_fx( } addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx, tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, negate( ( sub( q_bpf_error_signal, Q10 ) ) ) ); // Q10 st->cldfbBPF->Q_cldfb_state = Q10; move16(); @@ -2186,6 +2162,7 @@ ivas_error acelp_core_dec_ivas_fx( Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, 1 ); // Q12 st->cldfbAna->Q_cldfb_state = Q12; move16(); + cldfbAnalysis_ivas_fx( syn_32_fx + sub( st->L_frame, nSamples ), realBuffer_fx, imagBuffer_fx, nSamples, st->cldfbAna ); Scale_sig32( st->cldfbAna->cldfb_state_fx, offset, -1 ); // Q11 @@ -2215,8 +2192,8 @@ ivas_error acelp_core_dec_ivas_fx( tmp = nSamples; move16(); } - addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx + sub( st->L_frame, nSamples ), tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + addBassPostFilter_ivas_fx( tmp_bpf_error_signal_fx + sub( st->L_frame, nSamples ), tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); Scale_sig32( st->cldfbBPF->cldfb_state_fx, cldfb_state_offset, negate( sub( q_bpf_error_signal, Q10 ) ) ); // Q10 st->cldfbBPF->Q_cldfb_state = Q10; @@ -2299,13 +2276,11 @@ ivas_error acelp_core_dec_ivas_fx( IF( ( EQ_16( st->L_frame, L_FRAME ) && ( st->bwidth != NB ) && GE_16( output_frame, L_FRAME16k ) && ( EQ_16( st->extl, -1 ) || EQ_16( st->extl, SWB_CNG ) || ( EQ_16( st->extl, WB_BWE ) && st->extl_brate == 0 && NE_16( st->coder_type, AUDIO ) ) ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2 ); } ELSE -#endif { Copy_Scale_sig_32_16( synth_fx, synth_fx16, output_frame, 0 ); // Q0 hf_synth_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc2_fx, psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2 ); @@ -2315,9 +2290,7 @@ ivas_error acelp_core_dec_ivas_fx( ELSE { hf_synth_reset_fx( st->hBWE_zero ); -#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( st->element_mode, EVS_MONO ) ) // VE: TBV: tmp hack - it is a bug in EVS but condition is here to keep EVS bit-exact for the moment -#endif { set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); } @@ -2356,13 +2329,11 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( !st->ppp_mode_dec && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { non_linearity_fx( bwe_exc_fx, bwe_exc_extended_fx, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); } ELSE -#endif { Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); @@ -2389,14 +2360,12 @@ ivas_error acelp_core_dec_ivas_fx( IF( GT_32( st->core_brate, SID_2k40 ) && st->hTdCngDec != NULL && st->hFdCngDec != NULL ) { /* update CNG parameters in active frames */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { cng_params_upd_fx( lsp_new_fx, exc_fx, st->L_frame, &st->hTdCngDec->ho_circ_ptr, st->hTdCngDec->ho_ener_circ_fx, &st->hTdCngDec->ho_circ_size, st->hTdCngDec->ho_lsp_circ_fx, st->Q_exc, DEC, st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate ); } ELSE -#endif { cng_params_upd_ivas_fx( lsp_new_fx, exc_fx, st->L_frame, &st->hTdCngDec->ho_circ_ptr, st->hTdCngDec->ho_ener_circ_fx, &st->hTdCngDec->ho_circ_size, st->hTdCngDec->ho_lsp_circ_fx, st->Q_exc, DEC, st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate, st->element_mode, @@ -2413,9 +2382,7 @@ ivas_error acelp_core_dec_ivas_fx( } } -#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( st->element_mode, EVS_MONO ) ) -#endif { IF( save_hb_synth_fx16 ) { diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 6d3d0b381..363db8202 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -128,11 +128,7 @@ ivas_error acelp_core_switch_dec_fx( * Excitation decoding *----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); -#else - config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); -#endif + config_acelp1_fx( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); @@ -920,11 +916,7 @@ static void decod_gen_voic_core_switch_fx( * Decode pitch lag *----------------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - pitch = pit_decode_ivas_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*Q6*/ -#else - pitch = pit_decode_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ -#endif + pitch = pit_decode_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*Q6*/ /*--------------------------------------------------------------* * Find the adaptive codebook vector. diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index c1c1e6143..96ae82dde 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -373,11 +373,7 @@ ivas_error amr_wb_dec_fx( IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_1k75 ) ) { /* decode CNG parameters */ -#ifdef REMOVE_EVS_DUPLICATES - CNG_dec_ivas_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); -#else CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); -#endif /* comfort noise generation */ CNG_exc_fx( st_fx->core_brate, L_FRAME, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, @@ -630,15 +626,9 @@ ivas_error amr_wb_dec_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES - FEC_scale_syn_ivas_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, - &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, - exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); -#else FEC_scale_syn_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, - exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); -#endif + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 ); frame_ener_fx( L_FRAME, st_fx->clas_dec, syn_fx, pitch_buf_tmp[3], &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 ); } @@ -717,17 +707,10 @@ ivas_error amr_wb_dec_fx( * (smoothing is performed in the excitation domain and signal is resynthesized after) *------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - FEC_scale_syn_ivas_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, - MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, - st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, - st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, 0, 0 ); -#else FEC_scale_syn_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, - st_fx->Q_exc, st_fx->Q_syn, 0, 0 ); -#endif + st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, 0, 0 ); /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ frame_ener_fx( L_FRAME, st_fx->last_good, syn_fx, shr( FEC_pitch_fx, 6 ), &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 ); @@ -785,11 +768,7 @@ ivas_error amr_wb_dec_fx( st_fx->hPFstat->on = 1; move16(); test(); -#ifdef REMOVE_EVS_DUPLICATES - formant_post_filt_ivas_fx( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl( st_fx->psf_lp_noise_fx, 15 ), st_fx->total_brate, sub( amr_io_class, AUDIO_CLAS ) == 0 ); -#else formant_post_filt_fx( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl( st_fx->psf_lp_noise_fx, 15 ), st_fx->total_brate, sub( amr_io_class, AUDIO_CLAS ) == 0 ); -#endif } /*----------------------------------------------------------------* @@ -813,16 +792,9 @@ ivas_error amr_wb_dec_fx( st_fx->VAD = 0; move16(); } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - PMT( "Fixed point not done here " ) - ApplyFdCng_fx( syn, NULL, NULL, NULL, st, 0, 0 ); -#else -#ifdef REMOVE_EVS_DUPLICATES - ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 ); -#else - ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, NULL, NULL, st_fx, 0, 0 ); -#endif -#endif + + ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 ); + st_fx->hFdCngDec->hFdCngCom->frame_type_previous = st_fx->m_frame_type; move16(); diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index ce6ad6568..fdb6488db 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -22,19 +22,19 @@ static void shb_CNG_decod_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word static void shb_CNG_decod_ivas_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word16 *shb_synth_fx, const Word16 sid_bw, const Word16 Qsyn ); /*-----------------------------------------------------------------* + * CNG_dec_fx() + * * Decode residual signal energy *-----------------------------------------------------------------*/ -#ifndef REMOVE_EVS_DUPLICATES void CNG_dec_fx( Decoder_State *st_fx, /* i/o: State structure */ - const Word16 last_element_mode, /* i : last element mode Q0 */ + const Word16 last_element_mode, /* i : last element mode Q0 */ Word16 Aq[], /* o : LP coefficients Q12 */ Word16 *lsp_new, /* i/o: current frame LSPs Q15 */ Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */ Word16 *allow_cn_step, /* o : allow CN step Q0 */ - Word16 *sid_bw /* i : 0-NB/WB, 1-SWB SID Q0 */ - , + Word16 *sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0 */ Word32 *q_env ) { Word16 istep; @@ -72,7 +72,6 @@ void CNG_dec_fx( Word16 exp_pow; Word16 tmp_loop; Word16 enr_new, Aq_tmp[M + 1]; - Word16 LSF_Q_prediction; /* o : LSF prediction mode - just temporary variable in CNG */ TD_CNG_DEC_HANDLE hTdCngDec; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -108,681 +107,9 @@ void CNG_dec_fx( } ELSE { - lsf_dec_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0, - NULL ); - /* check IF LSPs may trigger too much synthesis energy */ - - E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M ); - enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR ); - - IF( shr( enr_new, 14 ) > 0 ) - { - /* Use old LSP vector */ - Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */ - Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */ - } - } - } - ELSE - { - /* Use old LSP vector */ - Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */ - Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */ - } - - /* Initialize the CNG spectral envelope in case of the very first CNG frame */ - IF( st_fx->first_CNG == 0 ) - { - Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); /* Q15 */ - } - - /*-----------------------------------------------------------------* - * Decode residual signal energy - *-----------------------------------------------------------------*/ - - *allow_cn_step = 0; - move16(); - test(); - IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - istep = ISTEP_AMR_WB_SID_FX; /* Q15 */ - move16(); - if ( EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - istep = ISTEP_SID_FX; /* Q15 */ - move16(); - } - - /* initialize the energy quantization parameters */ - num_bits = 6; - move16(); - if ( st_fx->Opt_AMR_WB == 0 ) - { - num_bits = 7; - move16(); - } - - /* decode the energy index */ - L_enr_index = get_next_indice_fx( st_fx, num_bits ); - - IF( LE_32( st_fx->last_core_brate, SID_2k40 ) || EQ_16( st_fx->prev_bfi, 1 ) ) - { - tmp1 = add( hTdCngDec->old_enr_index, 20 ); - } - ELSE - { - tmp1 = add( hTdCngDec->old_enr_index, 40 ); - } - IF( GT_16( L_enr_index, tmp1 ) && hTdCngDec->old_enr_index >= 0 ) /* Likely bit error and not startup */ - { - L_enr_index = tmp1; - move16(); - L_enr_index = s_min( L_enr_index, 127 ); /* Q0 */ - IF( st_fx->Opt_AMR_WB ) - { - L_enr_index = s_min( L_enr_index, 63 ); /* Q0 */ - } - } - - test(); - test(); - test(); - IF( GT_32( st_fx->last_core_brate, SID_1k75 ) && - NE_16( st_fx->first_CNG, 0 ) && - GE_16( hTdCngDec->old_enr_index, 0 ) && - GT_16( L_enr_index, add( hTdCngDec->old_enr_index, 1 ) ) ) - { - *allow_cn_step = 1; - move16(); - } - - hTdCngDec->old_enr_index = L_enr_index; - move16(); - if ( !L_enr_index ) - { - L_enr_index = -5; - move16(); - } - /* st_fx->Enew = L_enr_index / step - 2.0f;*/ - L_ener = L_mult( L_enr_index, istep ); /* Q16 (0+15) */ - /* subtract by 2 not done to leave Energy in Q2 */ - - /* extract integral and fractional parts */ - ener_fra = L_Extract_lc( L_ener, &ener_int ); - ener_int = add( ener_int, 4 ); /* Q2 to Q6 */ - - /* find the new energy value */ - hTdCngDec->Enew_fx = Pow2( ener_int, ener_fra ); - move32(); - - IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - burst_ho_cnt = get_next_indice_fx( st_fx, 3 ); /* 3bit */ - - *sid_bw = get_next_indice_fx( st_fx, 1 ); - move16(); - IF( *sid_bw == 0 ) - { - env_idx[0] = get_next_indice_fx( st_fx, 6 ); - move16(); - - /* get quantized res_env_details */ - FOR( i = 0; i < NUM_ENV_CNG; i++ ) - { - q_env[i] = L_deposit_l( CNG_details_codebook_fx[env_idx[0]][i] ); - move32(); - } - } - } - /* Reset CNG history IF CNG frame length is changed */ - test(); - test(); - IF( EQ_16( st_fx->bwidth, WB ) && NE_16( st_fx->first_CNG, 0 ) && NE_16( st_fx->L_frame, st_fx->last_CNG_L_frame ) ) - { - hTdCngDec->ho_hist_size = 0; - move16(); - } - } - - /*---------------------------------------------------------------------* - * CNG spectral envelope update - * Find A(z) coefficients - *---------------------------------------------------------------------*/ - test(); - test(); - test(); - IF( LE_32( st_fx->last_core_brate, SID_2k40 ) ) - { - /* Reset hangover counter if not first SID period */ - if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) ) - { - hTdCngDec->num_ho = 0; - move16(); - } - /* Update LSPs IF last SID energy not outliers or insufficient number of hangover frames */ - test(); - IF( LT_16( hTdCngDec->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngDec->Enew_fx, 21845 /*1/1.5f, Q15*/ ), st_fx->lp_ener_fx ) ) - { - FOR( i = 0; i < M; i++ ) - { - /* AR low-pass filter */ - st_fx->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, st_fx->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] ); - move16(); /* Q15 (15+15+1-16) */ - } - } - } - ELSE - { - /* Update CNG_mode IF allowed */ - test(); - test(); - test(); - IF( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !st_fx->first_CNG || GE_16( hTdCngDec->act_cnt2, MIN_ACT_CNG_UPD ) ) ) - { - IF( GT_32( st_fx->last_active_brate, ACELP_16k40 ) ) - { - st_fx->CNG_mode = -1; - move16(); - } - ELSE - { - st_fx->CNG_mode = get_cng_mode( st_fx->last_active_brate ); - move16(); - } - } - - /* If first sid after active burst update LSF history from circ buffer */ - burst_ho_cnt = s_min( burst_ho_cnt, hTdCngDec->ho_circ_size ); /* MODE1_DTX_IN_CODEC_B_FIX Q0*/ - hTdCngDec->act_cnt = 0; - move16(); - s_ptr = add( sub( hTdCngDec->ho_circ_ptr, burst_ho_cnt ), 1 ); - IF( s_ptr < 0 ) - { - s_ptr = add( s_ptr, hTdCngDec->ho_circ_size ); - } - - FOR( ll = burst_ho_cnt; ll > 0; ll-- ) - { - hTdCngDec->ho_hist_ptr = add( hTdCngDec->ho_hist_ptr, 1 ); /* Q0 */ - move16(); - if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) ) - { - hTdCngDec->ho_hist_ptr = 0; - move16(); - } - - /* Conversion between 12.8k and 16k LSPs */ - test(); - test(); - test(); - IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngDec->ho_16k_lsp[s_ptr] == 0 ) || ( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngDec->ho_16k_lsp[s_ptr], 1 ) ) ) - { - /* Conversion from 16k LPSs to 12k8 */ - lsp_convert_poly_fx( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 ); - } - /* update the circular buffers */ - Copy( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr * M] ), M ); /* Qx */ - Copy32( &( hTdCngDec->ho_ener_circ_fx[s_ptr] ), &( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ), 1 ); /* Q6 */ - hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - move32(); - Copy32( &( hTdCngDec->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Qx */ - - hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 ); - move16(); - - if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) ) - { - hTdCngDec->ho_hist_size = HO_HIST_SIZE; - move16(); - } - - s_ptr = add( s_ptr, 1 ); - if ( EQ_16( s_ptr, hTdCngDec->ho_circ_size ) ) - { - s_ptr = 0; - move16(); - } - } - - IF( hTdCngDec->ho_hist_size > 0 ) /* can be -1 at init MODE1_DTX_IN_CODEC_B_FIX */ - { - /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/ - L_tmp1 = L_shr( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], 2 ); - L_tmp1 = L_sub( L_tmp1, st_fx->lp_ener_fx ); + lsf_dec_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0, NULL ); - test(); - test(); - IF( ( L_tmp1 > 0 && ( st_fx->first_CNG || st_fx->element_mode == EVS_MONO ) ) ) - { - *allow_cn_step = s_or( *allow_cn_step, 1 ); - move16(); - } - } - IF( EQ_16( last_element_mode, IVAS_CPE_TD ) ) - { - *allow_cn_step = 1; - move16(); - } - test(); - IF( EQ_16( *allow_cn_step, 0 ) && GT_16( hTdCngDec->ho_hist_size, 0 ) ) - { - /* Use average of energies below last energy */ - ptr = hTdCngDec->ho_hist_ptr; - move16(); - Copy( &( hTdCngDec->ho_lsp_hist_fx[ptr * M] ), tmp, M ); /* Qx */ - m1 = 0; - move16(); - IF( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x1 ) == 0 ) - { - Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG ); - m1 = 1; - move16(); - } - L_enr = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */ - - weights = W_DTX_HO_FX[0]; /* Q15 */ - move16(); - - m = 1; - move16(); - FOR( k = 1; k < hTdCngDec->ho_hist_size; k++ ) - { - ptr--; - if ( ptr < 0 ) - { - ptr = HO_HIST_SIZE - 1; - move16(); - } - - test(); - IF( LT_32( Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ) && - GT_32( hTdCngDec->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], BUF_L_NRG_FX ) ) ) - { - /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/ - L_tmp1 = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */ - L_enr = L_add( L_enr, L_tmp1 ); /* Q6 */ - - /*weights += W_DTX_HO[k];*/ - weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */ - - Copy( &hTdCngDec->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M ); /* Qx */ - IF( EQ_32( L_and( hTdCngDec->ho_sid_bw, L_shl( (Word32) 0x1, k ) ), 0 ) ) - { - Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG ); /* Qx */ - m1++; - } - m++; - } - } - - /*enr /= weights;*/ - exp = norm_s( weights ); - tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */ - L_tmp1 = Mult_32_16( L_enr, tmp1 ); /* Q(14-exp+6-15)->Q(5-exp) */ - L_enr = L_shl( L_tmp1, add( exp, 1 ) ); /* Q6 */ - - st_fx->lp_ener_fx = L_enr; /* Q6 */ - move32(); - set32_fx( max_val, 0, 2 ); - set16_fx( max_idx, 0, 2 ); - - FOR( i = 0; i < m; i++ ) - { - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX ); - ftmp_fx = 964; - move16(); /*X2.56 */ - tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/ - L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536*/ - } - ELSE - { - lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k_FX ); - ftmp_fx = 1205; - move16(); /*QX2.56*/ - tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/ - L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536*/ - } - - tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56*/ - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/ - FOR( j = 0; j < M - 1; j++ ) - { - tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56*/ - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/ - } - - C[i] = Mpy_32_16_1( L_tmp, 1928 ); /*QX6.5536*/ - move32(); - - IF( GT_32( C[i], max_val[0] ) ) - { - max_val[1] = max_val[0]; - move32(); - max_idx[1] = max_idx[0]; - move16(); - max_val[0] = C[i]; - move32(); - max_idx[0] = i; - move16(); - } - ELSE IF( GT_32( C[i], max_val[1] ) ) - { - max_val[1] = C[i]; - move32(); - max_idx[1] = i; - move16(); - } - } - - IF( EQ_16( m, 1 ) ) - { - Copy( tmp, lsp_tmp, M ); /* Qx */ - } - ELSE IF( LT_16( m, 4 ) ) - { - FOR( i = 0; i < M; i++ ) - { - L_tmp1 = 0; - move32(); - FOR( j = 0; j < m; j++ ) - { - L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) ); - } - - L_tmp1 = L_sub( L_tmp1, L_deposit_l( tmp[max_idx[0] * M + i] ) ); - tmpv = div_s( 1, sub( m, 1 ) ); /*Q15*/ - L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/ - lsp_tmp[i] = extract_l( L_tmp1 ); /*Q15*/ - move16(); - } - } - ELSE - { - FOR( i = 0; i < M; i++ ) - { - L_tmp1 = 0; - move32(); - FOR( j = 0; j < m; j++ ) - { - L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) ); - } - - L_tmp1 = L_sub( L_tmp1, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15*/ - tmpv = div_s( 1, sub( m, 2 ) ); /*Q15*/ - L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/ - lsp_tmp[i] = extract_l( L_tmp1 ); /*Q15*/ - move16(); - } - } - - dist = 0; - move16(); /*Q15*/ - max_dev = 0; - move16(); /*Q15*/ - FOR( i = 0; i < M; i++ ) - { - dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/ - dist = add_o( dist, dev, &Overflow ); /*Q15*/ - if ( GT_16( dev, max_dev ) ) - { - max_dev = dev; - move16(); - } - } - - test(); - IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) ) /* 0.4 and 0.1 in Q15 */ - { - FOR( i = 0; i < M; i++ ) - { - st_fx->lspCNG_fx[i] = lsp_tmp[i]; - move16(); /*Q15*/ - } - } - ELSE - { - FOR( i = 0; i < M; i++ ) - { - /* AR low-pass filter */ - st_fx->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */ - move16(); - } - } - IF( m1 > 0 ) - { - FOR( i = 0; i < NUM_ENV_CNG; i++ ) - { - L_tmp = L_deposit_l( 0 ); - FOR( j = 0; j < m1; j++ ) - { - /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/ - L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); - } - /* env[i] /= (float)m1; */ - /* env[i] = env[i] - 2*st_fx->lp_ener_fx; */ - IF( EQ_16( m1, 1 ) ) - { - L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */ - } - ELSE - { - tmp1 = div_s( 1, m1 ); - L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */ - L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */ - } - env[i] = L_tmp; /* Q6 */ - move32(); - } - - Copy32( env, hTdCngDec->lp_env_fx, NUM_ENV_CNG ); /* Q6 */ - } - } - ELSE - { - Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */ - } - } - - test(); - IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - /* Update hangover memory during CNG */ - test(); - IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) ) - { - /* update the pointer to circular buffer of old LSP vectors */ - hTdCngDec->ho_hist_ptr++; - move16(); - if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) ) - { - hTdCngDec->ho_hist_ptr = 0; - move16(); - } - - /* update the circular buffer of old LSP vectors with the new LSP vector */ - Copy( lsp_new, &( hTdCngDec->ho_lsp_hist_fx[( hTdCngDec->ho_hist_ptr ) * M] ), M ); /* Q15 */ - - /* update the hangover energy buffer */ - hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] = hTdCngDec->Enew_fx; /* Q6 */ - move32(); - test(); - IF( EQ_32( st_fx->core_brate, SID_2k40 ) && ( *sid_bw == 0 ) ) - { - /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/ - exp = norm_l( hTdCngDec->Enew_fx ); - L_tmp = L_shl( hTdCngDec->Enew_fx, exp ); /*Q(exp+6)*/ - L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/ - L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/ - exp = norm_l( L_tmp ); - fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); - exp = sub( sub( 30, exp ), 6 ); - L_tmp = L_Comp( exp, fra ); - enr1 = L_shr( L_tmp, 10 ); /* Q6 */ - - FOR( i = 0; i < NUM_ENV_CNG; i++ ) - { - /* get quantized envelope */ - /* env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/ - L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */ - L_tmp = L_shl( L_tmp, 10 ); /* 16 */ - temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx ); - - exp_pow = sub( 14, temp_hi_fx ); - L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */ - env[i] = L_shl( L_tmp, sub( 6, exp_pow ) ); /* Q6 */ - move32(); - L_tmp = L_add( hTdCngDec->Enew_fx, hTdCngDec->Enew_fx ); - env[i] = L_add( env[i], L_tmp ); /* Q6 */ - move32(); - } - hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */ - move32(); - Copy32( env, &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Q6 */ - } - ELSE IF( ( *sid_bw != 0 ) ) - { - hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */ - move32(); - hTdCngDec->ho_sid_bw = L_or( hTdCngDec->ho_sid_bw, 0x1L ); /* Q0 */ - move32(); - } - - hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 ); - move16(); - if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) ) - { - hTdCngDec->ho_hist_size = HO_HIST_SIZE; - move16(); - } - } - /* Update the frame length memory */ - st_fx->last_CNG_L_frame = st_fx->L_frame; - move16(); - - if ( NE_32( st_fx->core_brate, SID_1k75 ) ) - { - hTdCngDec->num_ho = m; - move16(); - } - } - - IF( st_fx->element_mode == EVS_MONO ) - { - st_fx->last_CNG_L_frame = st_fx->L_frame; - move16(); - - IF( NE_32( st_fx->core_brate, SID_1k75 ) ) - { - hTdCngDec->num_ho = m; - move16(); - } - } - IF( st_fx->Opt_AMR_WB ) - { - E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M ); - } - ELSE - { - E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M ); - } - - tmp_loop = shr( st_fx->L_frame, 6 ); - FOR( i = 1; i < tmp_loop; i++ ) /* L_frame/L_SUBFR */ - { - Copy( Aq, &Aq[i * ( M + 1 )], add( M, 1 ) ); /* Q12 */ - } - - return; -} -#endif -void CNG_dec_ivas_fx( - Decoder_State *st_fx, /* i/o: State structure */ - const Word16 last_element_mode, /* i : last element mode Q0 */ - Word16 Aq[], /* o : LP coefficients Q12 */ - Word16 *lsp_new, /* i/o: current frame LSPs Q15 */ - Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */ - Word16 *allow_cn_step, /* o : allow CN step Q0 */ - Word16 *sid_bw /* i : 0-NB/WB, 1-SWB SID Q0 */ - , - Word32 *q_env ) -{ - Word16 istep; - Word16 i, L_enr_index; - Word32 L_ener; - Word16 ener_fra, ener_int; - Word16 num_bits; - Word16 weights, ptr, j, k; - Word16 m1; - Word16 m = 0; - move16(); - Word16 tmp[HO_HIST_SIZE * M]; - Word16 burst_ho_cnt = 0; - move16(); - Word16 ll, s_ptr; - Word32 L_enr, L_tmp1; - Word16 tmp1, exp; - Word16 lsf_tmp[M]; - Word32 C[M]; - Word32 max_val[2]; - Word16 max_idx[2]; - Word16 ftmp_fx; - Word16 lsp_tmp[M]; - Word16 dev; - Word16 max_dev; - Word16 dist; - Word16 tmpv; - Word16 env_idx[2]; - Word32 enr1; - Word32 env[NUM_ENV_CNG]; - Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG]; - Word32 L_tmp; - Word16 fra; - Word16 temp_lo_fx, temp_hi_fx; - Word16 exp_pow; - Word16 tmp_loop; - Word16 enr_new, Aq_tmp[M + 1]; - - Word16 LSF_Q_prediction; /* o : LSF prediction mode - just temporary variable in CNG */ - TD_CNG_DEC_HANDLE hTdCngDec; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - hTdCngDec = st_fx->hTdCngDec; - - m = 0; - move16(); - /*-----------------------------------------------------------------* - * Decode CNG spectral envelope (only in SID frame) - *-----------------------------------------------------------------*/ - test(); - IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - /* de-quantize the LSF vector */ - IF( st_fx->Opt_AMR_WB != 0 ) - { - /* Flt function */ - isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new ); - /* check IF ISPs may trigger too much synthesis energy */ - - E_LPC_f_isp_a_conversion( lsp_new, Aq_tmp, M ); - enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR ); - - IF( ( shr( enr_new, 14 ) > 0 ) ) - { - /* Use old LSP vector */ - Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */ - Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */ - } - } - ELSE - { - lsf_dec_ivas_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0, - NULL ); /* check IF LSPs may trigger too much synthesis energy */ - E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M ); enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR ); diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index f53234ded..d95359665 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -556,11 +556,7 @@ void decoder_LPD_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES int_lsp4_ivas_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp ); -#else - int_lsp4_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp ); -#endif } ELSE { diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index 16f749156..9c366e3f3 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -532,35 +532,24 @@ void decoder_acelp_fx( move16(); IF( st->igf != 0 ) { -#ifdef REMOVE_EVS_DUPLICATES - prep_tbe_exc_ivas_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, - gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); -#else - prep_tbe_exc_fx( st->L_frame, -#ifdef ADD_IVAS_TBE_CODE - L_SUBFR, -#endif - i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, - gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate -#ifdef ADD_IVAS_TBE_CODE - , - st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 -#endif - ); -#endif + prep_tbe_exc_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, + gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); } /*---------------------------------------------------------* * Enhance the excitation * *---------------------------------------------------------*/ + E_UTIL_enhancer( st->voice_fac, stab_fac, st->past_gcode, gain_inov, &( st->gc_threshold_fx ), code, &exc2[i_subfr], gain_pit, &st->dm_fx.prev_gain_code, st->dm_fx.prev_gain_pit, &st->dm_fx.prev_state, st->coder_type, acelp_cfg.fixed_cdk_index[idx], L_SUBFR, st->L_frame, st->Q_exc ); } /* !RF_NELP frame partial copy */ + /*----------------------------------------------------------* * - compute the synthesis speech * *----------------------------------------------------------*/ + rescale_mem( &st->Q_exc, &prev_Q_syn, &st->Q_syn, mem_syn, syn, M, i_subfr ); E_UTIL_synthesis( sub( st->Q_exc, st->Q_syn ), p_A, &exc2[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M ); @@ -686,16 +675,11 @@ void decoder_acelp_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES - FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, syn, pBuf_scaleSyn, st->enr_old_fx, 0, - st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, - exc, exc2, A, &( st->old_enr_LP ), mem_back, mem_syn, st->Q_exc, st->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, force_scale_syn ); -#else FEC_scale_syn_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, syn, pBuf_scaleSyn, st->enr_old_fx, 0, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, - exc, exc2, A, &( st->old_enr_LP ), mem_back, mem_syn, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, force_scale_syn ); -#endif + exc, exc2, A, &( st->old_enr_LP ), mem_back, mem_syn, st->Q_exc, st->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, force_scale_syn ); } + /* update ACELP synthesis memory */ Copy( mem_syn, st->mem_syn2_fx, M ); Copy( syn + st->L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM ); diff --git a/lib_dec/dec_amr_wb_fx.c b/lib_dec/dec_amr_wb_fx.c index b03b6d69c..500fe34ba 100644 --- a/lib_dec/dec_amr_wb_fx.c +++ b/lib_dec/dec_amr_wb_fx.c @@ -71,11 +71,7 @@ void decod_amr_wb_fx( * Decode pitch lag *----------------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - *pt_pitch_fx = pit_decode_ivas_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); -#else - *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); -#endif + *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*--------------------------------------------------------------* * Find the adaptive codebook vector diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 7411d59f2..3e42d9535 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -18,8 +18,7 @@ /*----------------------------------------------------------------------*/ /* GLOBAL INPUT ARGUMENTS : */ /* _ (Struct) st_fx : decoder static memory */ -/* _ (Word16) L_frame : length of the frame */ - +/* _ (Word16) L_frame : length of the frame */ /* _ (Word16[]) Aq_fx : LP filter coefficient Q12 */ /* _ (Word16) Es_pred_fx : predicted scaled innov. energy Q8 */ /* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ @@ -29,503 +28,30 @@ /* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ /* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ /*----------------------------------------------------------------------*/ - - /*----------------------------------------------------------------------*/ /* RETURN ARGUMENTS : */ /* _ None */ /*======================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES ivas_error decod_gen_voic_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 sharpFlag_fx, /* i : formant sharpening flag */ - const Word16 *Aq_fx, /* i : LP filter coefficient Q12 */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8 */ - const Word16 do_WI_fx, /* i : do interpolation after a FER */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6 */ - Word16 *voice_factors_fx, /* o : voicing factors Q15 */ - Word16 *exc_fx, /* i/o: adapt. excitation exc Q_exc */ - Word16 *exc2_fx, /* i/o: adapt. excitation/total exc Q_exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_exc */ - Word16 *unbits, /* number of unused bits */ - Word16 *gain_buf /*Q14*/ -) -{ - - - Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ - Word16 gain_pit_fx = 0; /* pitch gain Q14 */ - move16(); - Word32 gain_code_fx = 0; /* gain/normalized gain of the algebraic excitation Q16 */ - move32(); - Word32 norm_gain_code_fx = 0; /* normalized gain of the algebraic excitation Q16 */ - move32(); - Word16 gain_inov_fx = 0; /* Innovation gain Q12 */ - move16(); - Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ - Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */ - Word16 voice_fac_fx; /* voicing factor Q15 */ - Word16 code_fx[L_SUBFR]; /* algebraic codevector Q12 */ - - const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ - Word16 *pt_pitch_fx; /* pointer to floating pitch Q6 */ - Word16 i_subfr_fx, i; /* tmp variables */ - Word16 error_fx = 0; - move16(); - Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ - move16(); - Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */ - Word32 norm_gain_preQ_fx; - Word16 pitch_limit_flag_fx; - - Word16 tmp1_fx, gain_code16; - Word32 L_tmp_GC; - Word32 L_tmp; - - Word16 harm_flag_acelp; - - Word16 shft_prev, ph_offset_fx; - Word32 prev_res_nrg; - Word32 prev_spch_nrg; - Word32 curr_res_nrg; - Word32 curr_spch_nrg; - Word16 rint_bfi_pitch, rint_pitch; - Word16 fraca, fracb, expa, expb, scale, exp1; - Word16 *p_exc; - Word16 mem_tmp_fx[M]; - Word16 syn_tmp_fx[L_FRAME16k]; - Word16 shft_curr; - Word16 *p_syn; - Word16 sp_enratio, Qsp_enratio; - Word16 enratio, Qenratio; - DTFS_STRUCTURE *PREVP, *CURRP; - Word16 S_fx[PIT_MAX * 4 + 1], C_fx[PIT_MAX * 4 + 1]; - Word16 dummy2[2]; - Word16 out_fx[L_FRAME16k]; - - Word16 pf_temp1[MAXLAG_WI]; /*may not need more than MAXLAG_WI/2+1 */ - Word16 pf_temp2[MAXLAG_WI]; - Word16 pf_temp[MAXLAG_WI]; - Word16 pf_n2[MAXLAG_WI]; - MUSIC_POSTFILT_HANDLE hMusicPF; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - hMusicPF = st_fx->hMusicPF; - - GSC_DEC_HANDLE hGSCDec; - hGSCDec = st_fx->hGSCDec; - ivas_error error; - - error = IVAS_ERR_OK; - move32(); - - T0_fx = PIT_MIN; - move16(); - T0_frac_fx = 0; - move16(); - - /* read harmonicity flag */ - harm_flag_acelp = 0; - move16(); - test(); - test(); - IF( ( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) ) && EQ_16( st_fx->coder_type, GENERIC ) ) - { - harm_flag_acelp = (Word16) get_next_indice( st_fx, 1 ); - } - - /*------------------------------------------------------------------* - * ACELP subframe loop - *------------------------------------------------------------------*/ - - p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ - pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ - norm_gain_preQ_fx = 0; - move32(); - gain_preQ_fx = 0; - move16(); - set16_fx( code_preQ_fx, 0, L_SUBFR ); - - FOR( i_subfr_fx = 0; i_subfr_fx < L_frame; i_subfr_fx += L_SUBFR ) - { - /*----------------------------------------------------------------------* - * Decode pitch lag - *----------------------------------------------------------------------*/ - - *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 0, L_frame, i_subfr_fx, st_fx->coder_type, &pitch_limit_flag_fx, - &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_SUBFR ); - move16(); /*Q6*/ - - /*--------------------------------------------------------------* - * Find the adaptive codebook vector - *--------------------------------------------------------------*/ - - pred_lt4( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); - - tbe_celp_exc( L_frame, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx ); - - /*--------------------------------------------------------------* - * LP filtering of the adaptive excitation - *--------------------------------------------------------------*/ - lp_filt_exc_dec_fx( st_fx, MODE1, i_subfr_fx, L_SUBFR, L_frame, st_fx->acelp_cfg.ltf_mode, exc_fx ); - /*-----------------------------------------------------------------* - * Transform-domain contribution decoding (active frames) - *-----------------------------------------------------------------*/ - - test(); - IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && ( st_fx->coder_type != INACTIVE ) ) - { - gain_code_fx = 0; - move16(); - transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); - } - - /*--------------------------------------------------------------* - * Innovation decoding - *--------------------------------------------------------------*/ - - inov_decode_fx( st_fx, st_fx->core_brate, 0, L_frame, sharpFlag_fx, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_SUBFR ); - - /*--------------------------------------------------------------* - * Gain decoding - * Estimate spectrum tilt and voicing - *--------------------------------------------------------------*/ - - IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) - { - gain_dec_lbr_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); - } - ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) - { - gain_dec_SQ_fx( st_fx, i_subfr_fx, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - } - ELSE - { - gain_dec_mless_fx( st_fx, L_frame, st_fx->coder_type, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - } - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, st_fx->Q_exc ); // Q15 - move16(); - - /*-----------------------------------------------------------------* - * Transform domain contribution decoding - *-----------------------------------------------------------------*/ - test(); - IF( GE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) && ( st_fx->coder_type == INACTIVE ) ) - { - transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); - } - - /* update LP filtered gains for the case of frame erasures */ - lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); - - /*----------------------------------------------------------------------* - * Find the total excitation - *----------------------------------------------------------------------*/ - - IF( EQ_16( L_frame, L_FRAME ) ) /* Rescaling for 12.8k core */ - { - Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[i_subfr_fx * HIBND_ACB_L_FAC], hGSCDec->last_exc_dct_in_fx, - L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, i_subfr_fx, st_fx->coder_type ); - } - ELSE /* Rescaling for 16k core */ - { - - L_tmp_GC = L_max( gain_code_fx, L_shl( gain_preQ_fx, 16 ) ); /* Chose the maximum of gain_code or the prequantizer excitation x4 to keep some room*/ - Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[i_subfr_fx * 2], hGSCDec->last_exc_dct_in_fx, - L_SUBFR, L_SUBFR * 2, L_tmp_GC, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, i_subfr_fx, st_fx->coder_type ); - } - - gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/ - - /*-----------------------------------------------------------------* - * Add the ACELP pre-quantizer contribution - *-----------------------------------------------------------------*/ - - IF( gain_preQ_fx != 0 ) - { - IF( st_fx->element_mode == EVS_MONO ) - { - tmp1_fx = add( 15 - Q_AVQ_OUT_DEC - 2, st_fx->Q_exc ); - } - ELSE - { - tmp1_fx = add( 15 - Q_AVQ_OUT - 2, st_fx->Q_exc ); - } - FOR( i = 0; i < L_SUBFR; i++ ) - { - Word32 Ltmp1; - /* Contribution from AVQ layer */ - Ltmp1 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q6 -> Q9*/ - Ltmp1 = L_shl_sat( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ - - /* Compute exc2 */ - L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); // Q_exc+Q14+1+1 - exc2_fx[i + i_subfr_fx] = round_fx_sat( L_add_sat( L_tmp, Ltmp1 ) ); // Q_exc - move16(); - /* gain_pit in Q14 */ - L_tmp = L_mult( gain_code16, code_fx[i] ); // Q_exc+Q9+1 - L_tmp = L_shl_sat( L_tmp, 5 ); // Q_exc+Q9+1+5 - L_tmp = L_mac_sat( L_tmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); // Q_exc+Q15 +1 - L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ - - exc_fx[i + i_subfr_fx] = round_fx_sat( L_add_sat( L_tmp, Ltmp1 ) ); // Q_exc - move16(); - } - } - ELSE - { - Acelp_dec_total_exc( exc_fx, exc2_fx, gain_code16, gain_pit_fx, i_subfr_fx, code_fx, L_SUBFR ); - } - - /*-----------------------------------------------------------------* - * Prepare TBE excitation - *-----------------------------------------------------------------*/ - - Word16 idx = 0; - move16(); - IF( i_subfr_fx != 0 ) - { - idx = idiv1616( i_subfr_fx, L_SUBFR ); - } - - prep_tbe_exc_fx( L_frame, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, - &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, - st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate ); - - - /*----------------------------------------------------------------* - * Excitation enhancements (update of total excitation signal) - *----------------------------------------------------------------*/ - - test(); - IF( GT_32( st_fx->core_brate, ACELP_32k ) || ( st_fx->coder_type == INACTIVE ) ) - { - Copy( exc_fx + i_subfr_fx, exc2_fx + i_subfr_fx, L_SUBFR ); - } - ELSE - { - enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, - norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); - } - - p_Aq_fx += ( M + 1 ); - pt_pitch_fx++; - gain_buf[idx] = gain_pit_fx; // Q14 - move16(); - } - - /* FEC fast recovery */ - - IF( do_WI_fx ) - { - /* shft_prev = L_EXC_MEM - rint_new_fx(st_fx->bfi_pitch_fx);*/ - L_tmp = L_shl( L_deposit_l( st_fx->bfi_pitch_fx ), 10 ); /*Q16*/ - rint_bfi_pitch = rint_new_fx( L_tmp ); /*Q0*/ - shft_prev = sub( L_EXC_MEM, rint_bfi_pitch ); /*Q0*/ - - p_exc = st_fx->hWIDec->old_exc2_fx + shft_prev; - p_syn = st_fx->hWIDec->old_syn2_fx + shft_prev; - move16(); - move16(); - - prev_res_nrg = L_deposit_l( 1 ); - prev_spch_nrg = L_deposit_l( 1 ); - FOR( i = 0; i < rint_bfi_pitch; i++ ) - { - prev_res_nrg = L_mac0_sat( prev_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->prev_Q_exc_fr */ - prev_spch_nrg = L_mac0_sat( prev_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->prev_Q_syn_fr */ - p_exc++; - p_syn++; - } - - Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); - - syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_tmp_fx, mem_tmp_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); - - L_tmp = L_shl( L_deposit_l( pitch_buf_fx[NB_SUBFR16k - 1] ), 10 ); /*Q16*/ - rint_pitch = rint_new_fx( L_tmp ); /*Q0*/ - shft_curr = sub( st_fx->L_frame, rint_pitch ); /*Q0*/ - - p_exc = exc2_fx + shft_curr; - p_syn = syn_tmp_fx + shft_curr; - - curr_res_nrg = L_deposit_l( 1 ); - curr_spch_nrg = L_deposit_l( 1 ); - FOR( i = 0; i < rint_pitch; i++ ) - { - curr_res_nrg = L_mac0_sat( curr_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->Q_exc */ - curr_spch_nrg = L_mac0_sat( curr_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->Q_syn */ - p_exc++; - p_syn++; - } - - /* enratio = (curr_res_nrg / prev_res_nrg); */ - IF( prev_res_nrg > 0 ) - { - expa = norm_l( prev_res_nrg ); - fraca = extract_h( L_shl( prev_res_nrg, expa ) ); /* 2*st_fx->prev_Q_exc_fr -16+expa +1*/ - expa = sub( 30, add( expa, ( shl( st_fx->prev_Q_exc_fr, 1 ) ) ) ); - - expb = norm_l( curr_res_nrg ); - fracb = round_fx_sat( L_shl_sat( curr_res_nrg, expb ) ); /* 2*st_fx->Q_exc +expb+1 -16*/ - expb = sub( 30, add( expb, shl( st_fx->Q_exc, 1 ) ) ); - - scale = shr( sub( fraca, fracb ), 15 ); - fracb = shl( fracb, scale ); // Q(15-expb)+scale - expb = sub( expb, scale ); - - enratio = div_s( fracb, fraca ); // Q(15-(expb-expa)) - exp1 = sub( expb, expa ); - Qenratio = sub( 15, exp1 ); - } - ELSE - { - enratio = 0; - move16(); - Qenratio = 0; - move16(); - } - - /* sp_enratio = curr_spch_nrg/prev_spch_nrg */ - IF( prev_spch_nrg > 0 ) - { - expa = norm_l( prev_spch_nrg ); - fraca = extract_h( L_shl( prev_spch_nrg, expa ) ); /* 2*st_fx->prev_Q_syn_fr +expa+1-16*/ - expa = sub( 30, add( expa, shl( st_fx->prev_Q_syn_fr, 1 ) ) ); - - expb = norm_l( curr_spch_nrg ); - fracb = round_fx_sat( L_shl_sat( curr_spch_nrg, expb ) ); /* 2*st_fx->Q_syn +expb-16 */ - expb = sub( 30, add( expb, shl( st_fx->Q_syn, 1 ) ) ); - - scale = shr( sub( fraca, fracb ), 15 ); - fracb = shl( fracb, scale ); // Q(15-expb) +scale - expb = sub( expb, scale ); - - sp_enratio = div_s( fracb, fraca ); // Q(15-(expb-expa)) - exp1 = sub( expb, expa ); - Qsp_enratio = sub( 15, exp1 ); - } - ELSE - { - sp_enratio = 0; - move16(); - Qsp_enratio = 0; - move16(); - } - - test(); - test(); - test(); - test(); - IF( GT_16( shl_ro( enratio, sub( 15, Qenratio ), &Overflow ), 8192 ) && /*compare with 0.25 in Q15*/ - LT_16( shl_ro( enratio, sub( 10, Qenratio ), &Overflow ), 15360 ) && /*compare with 15.0 in Q10*/ - GT_16( shl_ro( sp_enratio, sub( 15, Qsp_enratio ), &Overflow ), 4915 ) && /*compare with 0.15 in Q15*/ - LT_16( st_fx->bfi_pitch_fx, 9600 ) && /*Q6*/ - LT_16( pitch_buf_fx[NB_SUBFR16k - 1], 9600 ) ) /*Q6*/ - { - IF( NE_32( ( error = DTFS_new_fx( &PREVP ) ), IVAS_ERR_OK ) ) - { - return error; - } - - IF( NE_32( ( error = DTFS_new_fx( &CURRP ) ), IVAS_ERR_OK ) ) - { - return error; - } - - GetSinCosTab_fx( rint_bfi_pitch, S_fx, C_fx ); - DTFS_to_fs_fx( st_fx->hWIDec->old_exc2_fx + shft_prev, rint_bfi_pitch, PREVP, (Word16) st_fx->output_Fs, do_WI_fx, S_fx, C_fx ); - PREVP->Q = add( PREVP->Q, st_fx->prev_Q_exc_fr ); - move16(); - - GetSinCosTab_fx( rint_pitch, S_fx, C_fx ); - DTFS_to_fs_fx( exc2_fx + shft_curr, rint_pitch, CURRP, (Word16) st_fx->output_Fs, do_WI_fx, S_fx, C_fx ); - CURRP->Q = add( CURRP->Q, st_fx->Q_exc ); - move16(); - - ph_offset_fx = 0; - move16(); - IF( NE_32( ( error = WIsyn_fx( *PREVP, CURRP, dummy2, &( ph_offset_fx ), out_fx, (Word16) st_fx->L_frame, 1, S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 ) ), IVAS_ERR_OK ) ) - { - return error; - } - - - Copy_Scale_sig( out_fx, exc2_fx, st_fx->L_frame, st_fx->Q_exc ); // Q_exc - Copy_Scale_sig( out_fx, exc_fx, st_fx->L_frame, st_fx->Q_exc ); // Q_exc - - /* update bwe_exc for SWB-TBE */ - FOR( i_subfr_fx = 0; i_subfr_fx < L_frame; i_subfr_fx += L_SUBFR ) - { - interp_code_4over2_fx( exc_fx + i_subfr_fx, bwe_exc_fx + shl( i_subfr_fx, 1 ), L_SUBFR ); - } - - free( PREVP ); - free( CURRP ); - } - } - - /* SC-VBR */ - st_fx->prev_gain_pit_dec_fx = gain_pit_fx; - move16(); /*Q14*/ - st_fx->prev_tilt_code_dec_fx = st_fx->tilt_code_fx; - move16(); /*Q15*/ - - return error; -} - -/*======================================================================*/ -/* FUNCTION : decod_gen_voic_ivas_fx() */ -/*----------------------------------------------------------------------*/ -/* PURPOSE : Decode generic (GC), voiced (VC) and AMR-WB IO frames */ -/* */ -/*----------------------------------------------------------------------*/ -/* GLOBAL INPUT ARGUMENTS : */ -/* _ (Struct) st_fx : decoder static memory */ -/* _ (Word16) L_frame : length of the frame */ - -/* _ (Word16[]) Aq_fx : LP filter coefficient Q12 */ -/* _ (Word16) Es_pred_fx : predicted scaled innov. energy Q8 */ -/* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ -/* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ -/*----------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ -/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ -/*----------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*======================================================================*/ -#endif -ivas_error decod_gen_voic_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 sharpFlag_fx, /* i : formant sharpening flag */ - const Word16 *Aq_fx, /* i : LP filter coefficient Q12*/ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8 */ - const Word16 do_WI_fx, /* i : do interpolation after a FER */ - Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe Q6*/ - Word16 *voice_factors_fx, /* o : voicing factors Q15 */ - Word16 *exc_fx, /* i/o: adapt. excitation exc Q_exc */ - Word16 *exc2_fx, /* i/o: adapt. excitation/total exc Q_exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_exc */ - Word16 *unbits, /* number of unused bits */ - Word16 *gain_buf, - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag_fx, /* i : formant sharpening flag */ + const Word16 *Aq_fx, /* i : LP filter coefficient Q12 */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8 */ + const Word16 do_WI_fx, /* i : do interpolation after a FER */ + Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe Q6 */ + Word16 *voice_factors_fx, /* o : voicing factors Q15 */ + Word16 *exc_fx, /* i/o: adapt. excitation exc Q_exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc Q_exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_exc */ + Word16 *unbits, /* number of unused bits */ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14 */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ ) { - - - Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ + Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ Word16 gain_pit_fx; /* pitch gain Q14 */ Word32 gain_code_fx; /* gain/normalized gain of the algebraic excitation Q16 */ Word32 norm_gain_code_fx; /* normalized gain of the algebraic excitation Q16 */ @@ -536,7 +62,7 @@ ivas_error decod_gen_voic_ivas_fx( Word16 code_fx[L_SUBFR]; /* algebraic codevector Q12 */ const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ - Word16 *pt_pitch_fx; /* pointer to Word16 pitch Q6 */ + Word16 *pt_pitch_fx; /* pointer to Word16 pitch Q6 */ Word16 i_subfr_fx, i; /* tmp variables */ Word16 error_fx; Word16 gain_preQ_fx; /* Gain of prequantizer excitation */ @@ -633,10 +159,8 @@ ivas_error decod_gen_voic_ivas_fx( * Decode pitch lag *----------------------------------------------------------------------*/ - /**pt_pitch_fx = pit_decode_fx(st_fx, st_fx->core_brate, 0, L_frame, i_subfr_fx, st_fx->coder_type, &pitch_limit_flag_fx, - &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_SUBFR);*/ - *pt_pitch_fx = pit_decode_ivas_fx( st_fx, st_fx->core_brate, 0, L_frame, i_subfr_fx, st_fx->coder_type, &pitch_limit_flag_fx, - &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 0, L_frame, i_subfr_fx, st_fx->coder_type, &pitch_limit_flag_fx, + &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); move16(); /*Q6*/ /*--------------------------------------------------------------* @@ -677,7 +201,7 @@ ivas_error decod_gen_voic_ivas_fx( IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { - gain_dec_lbr_ivas_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); + gain_dec_lbr_fx( st_fx, st_fx->coder_type, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR ); } ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) { @@ -700,13 +224,11 @@ ivas_error decod_gen_voic_ivas_fx( } /* update LP filtered gains for the case of frame erasures */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); } ELSE -#endif { lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); } @@ -790,10 +312,6 @@ ivas_error decod_gen_voic_ivas_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ - /*prep_tbe_exc_fx(L_frame, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, - &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, - st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate);*/ - Word16 idx; idx = 0; move16(); @@ -802,10 +320,10 @@ ivas_error decod_gen_voic_ivas_fx( idx = idiv1616( i_subfr_fx, L_SUBFR ); } - prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, - &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, - st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, - st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, + st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); /*----------------------------------------------------------------* @@ -819,14 +337,12 @@ ivas_error decod_gen_voic_ivas_fx( } ELSE { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); } ELSE -#endif { enhancer_ivas_fx2( st_fx->core_brate, 0, st_fx->coder_type, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); diff --git a/lib_dec/dec_pit_exc_fx.c b/lib_dec/dec_pit_exc_fx.c index fe7d2daaf..a18029cdc 100644 --- a/lib_dec/dec_pit_exc_fx.c +++ b/lib_dec/dec_pit_exc_fx.c @@ -14,13 +14,13 @@ /*--------------------------------------------------------------------------*/ /* INPUT ARGUMENTS : */ /* _ (Word16*) Aq_fx : LP filter coefficient Q12 */ -/* _ (Word16) coder_type : coding type Q0 */ +/* _ (Word16) coder_type : coding type Q0 */ /* _ (Word16) nb_subfr_fx :Number of subframe considered */ /* _ (Word16) Es_pred_fx :predicted scaled innov. energy */ /*--------------------------------------------------------------------------*/ /* OUTPUT ARGUMENTS : */ /* _ (Word16*) pitch_buf_fx : floating pitch values for each subframe Q6 */ -/* _ (Word16*) code_fx : innovation Q12 */ +/* _ (Word16*) code_fx : innovation Q12 */ /*--------------------------------------------------------------------------*/ /* INPUT/OUTPUT ARGUMENTS : */ /* Decoder_State_fx *st_fx : decoder state structure */ @@ -30,438 +30,29 @@ /* _ None */ /*==========================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void dec_pit_exc_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 coder_type, /* i : coding type */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *code_fx, /* o : innovation */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 nb_subfr_fx /* i : Number of subframe considered */ - , - Word16 *gain_buf /*Q14*/ -) -{ - Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ - Word16 gain_pit_fx; /* pitch gain Q14 */ - Word32 gain_code_fx; /* gain/normalized gain of the algebraic excitation Q16 */ - Word32 norm_gain_code_fx; /* normalized gain of the algebraic excitation Q16 */ - Word16 gain_inov_fx; /* Innovation gain Q12 */ - Word16 voice_fac_fx; /* voicing factor Q15 */ - Word16 L_subfr_fx, pit_idx_fx; - const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ - Word16 *pt_pitch_fx; /* pointer to floating pitch Q6 */ - Word16 i_subfr_fx, i; /* tmp variables */ - Word32 Local_BR_fx, Pitch_BR_fx; - Word16 pitch_limit_flag, Pitch_CT_fx; - Word16 exc2_bidon[L_SUBFR]; - Word16 *pt_gain; /* Pointer to floating gain values for each subframe */ - - Word16 gain_code16, gain_pitx2; - Word32 L_tmp; - Word16 nbits; - GSC_DEC_HANDLE hGSCDec; - gain_pit_fx = 0; - move16(); - hGSCDec = st_fx->hGSCDec; - - MUSIC_POSTFILT_HANDLE hMusicPF; - hMusicPF = st_fx->hMusicPF; - - Word16 use_fcb; - Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ - Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */ -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move16(); -#endif - - use_fcb = 0; - move16(); - test(); - test(); - IF( ( st_fx->GSC_IVAS_mode > 0 ) && ( EQ_16( st_fx->GSC_noisy_speech, 1 ) || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) - { - Local_BR_fx = ACELP_8k00; - Pitch_CT_fx = GENERIC; - Pitch_BR_fx = ACELP_8k00; - move32(); - move32(); - move16(); - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Local_BR_fx = ACELP_14k80; - move32(); - if ( st_fx->GSC_IVAS_mode > 0 ) - { - Local_BR_fx = ACELP_9k60; - move32(); - } - Pitch_BR_fx = st_fx->core_brate; - move32(); - } - } - ELSE IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) ) - { - Local_BR_fx = ACELP_7k20; - move32(); - Pitch_CT_fx = GENERIC; - move16(); - Pitch_BR_fx = ACELP_7k20; - move32(); - if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Pitch_BR_fx = st_fx->core_brate; - move32(); - } - } - ELSE - { - Local_BR_fx = ACELP_7k20; - move32(); - Pitch_CT_fx = AUDIO; - move16(); - Pitch_BR_fx = st_fx->core_brate; - move32(); - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Pitch_BR_fx = ACELP_13k20; - move32(); - Pitch_CT_fx = GENERIC; - move16(); - } - } - L_subfr_fx = mult_r( st_fx->L_frame, div_s( 1, nb_subfr_fx ) ); /* TV2Opt : this could be less complex with 2 ifs*/ - - - gain_code_fx = 0; - move16(); - pitch_limit_flag = 1; - move16(); /* always extended pitch Q range */ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && ( ( EQ_16( st_fx->L_frame, L_FRAME ) && GE_32( st_fx->core_brate, ACELP_13k20 ) ) || ( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, GSC_H_RATE_STG ) ) || st_fx->GSC_IVAS_mode == 0 ) ) ) && EQ_16( L_subfr_fx, L_SUBFR ) ) ) - { - use_fcb = 1; - move16(); - } - ELSE IF( ( st_fx->GSC_IVAS_mode > 0 ) && EQ_16( L_subfr_fx, 2 * L_SUBFR ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) - { - use_fcb = 2; - st_fx->acelp_cfg.fcb_mode = 1; - move16(); - move16(); - set16_fx( st_fx->acelp_cfg.gains_mode, 6, 4 ); - set16_fx( st_fx->acelp_cfg.pitch_bits, 9, 4 ); - set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, 5 ); - } - /*------------------------------------------------------------------* - * ACELP subframe loop - *------------------------------------------------------------------*/ - p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ - pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ - pt_gain = gain_buf; /* pointer to the gain buffer */ - FOR( i_subfr_fx = 0; i_subfr_fx < st_fx->L_frame; i_subfr_fx += L_subfr_fx ) - { - /*----------------------------------------------------------------------* - * Decode pitch lag - *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx ); - move16(); - - /*--------------------------------------------------------------* - * Find the adaptive codebook vector. - *--------------------------------------------------------------*/ - - pred_lt4( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_subfr_fx + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); - - /*--------------------------------------------------------------* - * Innovation decoding - *--------------------------------------------------------------*/ - - IF( EQ_16( use_fcb, 1 ) ) - { - inov_decode_fx( st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx ); - /*--------------------------------------------------------------* - * Gain decoding - * Estimate spectrum tilt and voicing - *--------------------------------------------------------------*/ - - gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 ); - move16(); - } - ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */ - { - inov_decode_fx( st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx ); - /*--------------------------------------------------------------* - * Gain decoding - * Estimate spectrum tilt and voicing - *--------------------------------------------------------------*/ - - gain_dec_lbr_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); - - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 ); - move16(); - } - ELSE - { - nbits = 5; - move16(); - if ( LT_32( st_fx->core_brate, MIN_RATE_FCB ) ) - { - nbits = 4; - move16(); - } - - set16_fx( code_fx, 0, L_SUBFR ); - gain_code_fx = L_deposit_l( 0 ); - st_fx->tilt_code_fx = 0; - move16(); - pit_idx_fx = (Word16) get_next_indice( st_fx, nbits ); - move16(); - - gain_pit_fx = add( 9590, dic_gp_fx[pit_idx_fx] ); - move16(); /*Q14 0.5853 in Q14 9590*/ - - if ( st_fx->BER_detect ) /* Bitstream is corrupted, use the past pitch gain */ - { - gain_pit_fx = st_fx->lp_gainp_fx; - move16(); - } - gain_code_fx = L_mult0( s_max( sub( 32767, shl_o( gain_pit_fx, 1, &Overflow ) ), 16384 ), st_fx->lp_gainc_fx ); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ - } - - /*----------------------------------------------------------------------* - * Find the total excitation - *----------------------------------------------------------------------*/ - - Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[( i_subfr_fx * ( 2 * HIBND_ACB_L_FAC ) ) / 2], hGSCDec->last_exc_dct_in_fx, - L_subfr_fx, shr( imult1616( L_subfr_fx, 2 * HIBND_ACB_L_FAC ), 1 ), gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, i_subfr_fx, coder_type ); - - gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/ - - IF( use_fcb != 0 ) - { - Acelp_dec_total_exc( exc_fx, exc2_bidon - i_subfr_fx, gain_code16, gain_pit_fx, i_subfr_fx, code_fx, L_subfr_fx ); - } - ELSE - { - IF( norm_s( s_or( gain_pit_fx, 1 ) ) == 0 ) - { - FOR( i = 0; i < L_subfr_fx; i++ ) - { - L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/ - exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/ - move16(); - } - } - ELSE - { - gain_pitx2 = shl( gain_pit_fx, 1 ); /*Q15*/ - - FOR( i = 0; i < L_subfr_fx; i++ ) - { - L_tmp = L_mult( gain_pitx2, exc_fx[i + i_subfr_fx] ); /*Q16+Q_exc*/ - exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/ - move16(); - } - } - } - - IF( EQ_16( L_subfr_fx, L_FRAME16k ) ) - { - /* update gains for FEC - equivalent to lp_gain_updt() */ - st_fx->lp_gainp_fx = gain_pit_fx; - move16(); - st_fx->lp_gainc_fx = 0; - move32(); - - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - move16(); - move16(); - move16(); - move16(); - p_Aq_fx += 5 * ( M + 1 ); - } - ELSE IF( EQ_16( L_subfr_fx, L_FRAME16k / 2 ) ) - { - IF( i_subfr_fx == 0 ) - { - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - p_Aq_fx += 2 * ( M + 1 ); - move16(); - - /* update gains for FEC - equivalent to lp_gain_updt() */ - st_fx->lp_gainp_fx = extract_h( L_mult( 6554, gain_pit_fx ) ); /*Q14 (3/15 in Q15 9830)*/ - st_fx->lp_gainc_fx = 0; - move16(); - move16(); - } - ELSE - { - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - pt_pitch_fx++; - p_Aq_fx += 3 * ( M + 1 ); - move16(); - move16(); - - /* update gains for FEC - equivalent to lp_gain_updt() */ - st_fx->lp_gainp_fx = extract_h( L_mult( 26214, gain_pit_fx ) ); /*Q14 (12/15 in Q15 9830)*/ - st_fx->lp_gainc_fx = 0; - move16(); - move16(); - } - } - ELSE IF( EQ_16( L_subfr_fx, 128 ) ) /*2*L_SUBFR*/ - { - p_Aq_fx += 2 * ( M + 1 ); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - move16(); - pt_pitch_fx++; - *pt_gain = gain_pit_fx; - move16(); - pt_gain++; - *pt_gain = *( pt_gain - 1 ); - move16(); - pt_gain++; - IF( i_subfr_fx == 0 ) - { - /* update gains for FEC - equivalent to lp_gain_updt() */ - st_fx->lp_gainp_fx = extract_h( L_mult( 9830, gain_pit_fx ) ); /*Q14 (3/10 in Q15 9830)*/ - st_fx->lp_gainc_fx = 0; - move16(); - move16(); - } - ELSE - { - /* update gains for FEC - equivalent to lp_gain_updt() */ - st_fx->lp_gainp_fx = extract_h( L_mult( 22938, gain_pit_fx ) ); /*Q14 (7/10 in Q15 22938)*/ - st_fx->lp_gainc_fx = 0; - move16(); - move16(); - } - } - ELSE IF( EQ_16( L_subfr_fx, 256 ) ) /*4*L_SUBFR*/ - { - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - move16(); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - move16(); - pt_pitch_fx++; - *pt_pitch_fx = *( pt_pitch_fx - 1 ); - move16(); - pt_pitch_fx++; - *pt_gain = gain_pit_fx; - move16(); - pt_gain++; - *pt_gain = *( pt_gain - 1 ); - move16(); - pt_gain++; - *pt_gain = *( pt_gain - 1 ); - move16(); - pt_gain++; - *pt_gain = *( pt_gain - 1 ); - move16(); - pt_gain++; - p_Aq_fx += 4 * ( M + 1 ); - - /* update gains for FEC - equivalent to lp_gain_updt() */ - st_fx->lp_gainp_fx = gain_pit_fx; - move16(); - st_fx->lp_gainc_fx = 0; - move16(); - } - ELSE - { - p_Aq_fx += ( M + 1 ); - move16(); - pt_pitch_fx++; - move16(); - *pt_gain = gain_pit_fx; - move16(); - pt_gain++; - - lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, 0, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, st_fx->L_frame ); - } - } - - return; -} - -/*==========================================================================*/ -/* FUNCTION : void dec_pit_exc_ivas_fx() */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : Decode pitch only contribution */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16*) Aq_fx : LP filter coefficient Q12 */ -/* _ (Word16) coder_type : coding type Q0 */ -/* _ (Word16) nb_subfr_fx :Number of subframe considered */ -/* _ (Word16) Es_pred_fx :predicted scaled innov. energy */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16*) pitch_buf_fx : Word16 pitch values for each subframe Q6 */ -/* _ (Word16*) code_fx : innovation */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Decoder_State_fx *st_fx : decoder state structure */ -/* _ (Word16*) exc_fx : adapt. excitation exc */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*==========================================================================*/ -#endif -void dec_pit_exc_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* i : LP filter coefficient */ const Word16 coder_type, /* i : coding type */ const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */ + Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */ Word16 *code_fx, /* o : innovation */ Word16 *exc_fx, /* i/o: adapt. excitation exc */ Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ const Word16 nb_subfr_fx, /* i : Number of subframe considered */ - Word16 *gain_buf, /*Q14*/ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ) { - Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ - Word16 gain_pit_fx; /* pitch gain Q14 */ - Word32 gain_code_fx; /* gain/normalized gain of the algebraic excitation Q16 */ + Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ + Word16 gain_pit_fx; /* pitch gain Q14 */ + Word32 gain_code_fx; /* gain/normalized gain of the algebraic excitation Q16 */ Word32 norm_gain_code_fx; /* normalized gain of the algebraic excitation Q16 */ - Word16 gain_inov_fx; /* Innovation gain Q12 */ + Word16 gain_inov_fx; /* Innovation gain Q12 */ Word16 voice_fac_fx; /* voicing factor Q15 */ Word16 L_subfr_fx, pit_idx_fx; - const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ + const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ Word16 *pt_pitch_fx; /* pointer to Word16 pitch Q6 */ Word16 i_subfr_fx, i; /* tmp variables */ Word32 Local_BR_fx, Pitch_BR_fx; @@ -578,13 +169,14 @@ void dec_pit_exc_ivas_fx( p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ pt_gain = gain_buf; /* pointer to the gain buffer */ + FOR( i_subfr_fx = 0; i_subfr_fx < st_fx->L_frame; i_subfr_fx += L_subfr_fx ) { /*----------------------------------------------------------------------* * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_ivas_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); move16(); /*--------------------------------------------------------------* @@ -621,7 +213,7 @@ void dec_pit_exc_ivas_fx( * Estimate spectrum tilt and voicing *--------------------------------------------------------------*/ - gain_dec_lbr_ivas_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); + gain_dec_lbr_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 ); move16(); diff --git a/lib_dec/dec_post_fx.c b/lib_dec/dec_post_fx.c index 281281ed6..37d088a8f 100644 --- a/lib_dec/dec_post_fx.c +++ b/lib_dec/dec_post_fx.c @@ -33,10 +33,7 @@ static void calc_st_filt_local_fx( Word16 *apond2, Word16 *apond1, Word16 *parco static void modify_pst_param_fx( const Word16 lp_noise, Word16 *g1, Word16 *g2, const Word16 coder_type, Word16 *gain_factor ); -#ifndef REMOVE_EVS_DUPLICATES static void Dec_formant_postfilt_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); -#endif -static void Dec_formant_postfilt_ivas_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); static void calc_st_filt_ivas_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero, const Word16 extl ); @@ -82,7 +79,7 @@ void Init_post_filter_fx( *--------------------------------------------------------------------------*/ void nb_post_filt_fx( const Word16 L_frame, /* i : frame length */ - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *psf_lp_noise, /* i : Long term noise Q8 */ const Word16 tmp_noise, /* i : noise energy Q0 */ Word16 *Synth, /* i : 12k8 synthesis Qsyn */ @@ -257,22 +254,20 @@ static void Dec_postfilt_fx( * Main routine to perform formant post filtering *--------------------------------------------------------------------------*/ -#ifndef REMOVE_EVS_DUPLICATES void formant_post_filt_fx( - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ Word16 *synth_in, /* i : 12k8 synthesis */ - Word16 *Aq, /* i : LP filter coefficient Q12 */ + Word16 *Aq, /* i : LP filter coefficient Q12 */ Word16 *synth_out, /* i/o: input signal */ - Word16 L_frame, - Word32 lp_noise, /* (i) : background noise energy (15Q16) */ - Word32 brate, /* (i) : bit-rate */ - const Word16 off_flag /* i : off flag */ + const Word16 L_frame, /* i : frame length */ + const Word32 lp_noise, /* (i) : background noise energy (15Q16) */ + const Word32 brate, /* (i) : bit-rate */ + const Word16 off_flag /* i : off flag */ ) { Word16 i_subfr; Word16 *p_Aq; - Word16 post_G1, post_G2; // Q15 - + Word16 post_G1, post_G2; /*default parameter for noisy speech and high bit-rates*/ IF( EQ_16( L_frame, L_FRAME ) ) @@ -381,134 +376,13 @@ void formant_post_filt_fx( Dec_formant_postfilt_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 ); p_Aq += ( M + 1 ); } -} -#endif -void formant_post_filt_ivas_fx( - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ - Word16 *synth_in, /* i : 12k8 synthesis */ - Word16 *Aq, /* i : LP filter coefficient Q12 */ - Word16 *synth_out, /* i/o: input signal */ - Word16 L_frame, - Word32 lp_noise, /* (i) : background noise energy (15Q16) */ - Word32 brate, /* (i) : bit-rate */ - const Word16 off_flag /* i : off flag */ -) -{ - Word16 i_subfr; - Word16 *p_Aq; - Word16 post_G1, post_G2; - - - /*default parameter for noisy speech and high bit-rates*/ - IF( EQ_16( L_frame, L_FRAME ) ) - { - post_G2 = 22938 /*0.7f Q15*/; - move16(); - IF( LT_32( lp_noise, LP_NOISE_THRESH ) ) - { - /*Clean speech*/ - IF( LT_32( brate, ACELP_13k20 ) ) - { - /*Low rates*/ - - post_G1 = 26214 /*0.8f Q15*/; - move16(); - } - ELSE IF( LT_32( brate, ACELP_24k40 ) ) - { - /*Low rates*/ - - post_G1 = 24576 /*0.75f Q15*/; - move16(); - } - ELSE - { - post_G1 = 23593 /*0.72f Q15*/; - move16(); - } - } - ELSE /*Noisy speech*/ - { - post_G1 = 22938 /*0.7f Q15*/; - move16(); - if ( LT_32( brate, ACELP_15k85 ) ) - { - /*Low rates*/ - post_G1 = 24576 /*0.75f Q15*/; - move16(); - } - } - } - ELSE - { - post_G2 = 24904 /*0.76f Q15*/; - move16(); - test(); - IF( GE_32( lp_noise, LP_NOISE_THRESH ) ) - { - post_G1 = 24904 /*0.76f Q15*/; - } - ELSE IF( EQ_32( brate, ACELP_13k20 ) ) - { - post_G1 = 26870 /*0.82f Q15*/; - move16(); - } - ELSE IF( EQ_32( brate, ACELP_16k40 ) ) - { - post_G1 = 26214 /*0.80f Q15*/; - move16(); - } - ELSE IF( EQ_32( brate, ACELP_24k40 ) || EQ_32( brate, ACELP_32k ) ) - { - post_G1 = 25559 /*0.78f Q15*/; - move16(); - } - ELSE - { - post_G1 = 24904 /*0.76f Q15*/; - move16(); - } - } - /* Switch off post-filter */ - if ( off_flag != 0 ) - { - post_G1 = post_G2; - move16(); - } - - /* Reset post filter */ - IF( hPFstat->reset != 0 ) - { - post_G1 = MAX16B; - move16(); - post_G2 = MAX16B; - move16(); - hPFstat->reset = 0; - move16(); - Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); - Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM ); - hPFstat->gain_prec = 16384; // 1.Q14 - move16(); - Copy( synth_in, synth_out, L_frame ); - - return; - } + return; +} - /* input memory*/ - Copy( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM ); - Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); - move16(); - p_Aq = Aq; // Q12 - FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR ) - { - Dec_formant_postfilt_ivas_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 ); - p_Aq += ( M + 1 ); - } -} /*---------------------------------------------------------------------------- - * Dec_formant_postfilt_fx + * Dec_formant_postfilt_fx() * * Post - adaptive postfilter main function * Short term postfilter : @@ -522,93 +396,14 @@ void formant_post_filt_ivas_fx( * k1 = 1st parcor calculated on {hi} * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 *----------------------------------------------------------------------------*/ -#ifndef REMOVE_EVS_DUPLICATES -static void Dec_formant_postfilt_fx( - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ - Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q14*/ - Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */ - Word16 *sig_out, /* o : postfiltered output */ - Word16 gamma1, /* i : short term postfilt. den. weighting factor Q15*/ - Word16 gamma2 /* i : short term postfilt. num. weighting factor Q15*/ -) -{ - /* Local variables and arrays */ - Word16 apond1[M + 1]; /* s.t. denominator coeff. Q12*/ - Word16 apond2[LONG_H_ST]; // Q12 - Word16 res2[L_SUBFR]; // Q14 - Word16 resynth[L_SUBFR + 1]; // Qy - Word16 parcor0; // Q15 - Word16 i, max; - Word16 scale_down; - - /* Compute weighted LPC coefficients */ - weight_a_fx( coeff, apond1, gamma1, M ); - weight_a_fx( coeff, apond2, gamma2, M ); - set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) ); - max = abs_s( signal_ptr[0] ); // Q14 - FOR( i = 1; i < L_SUBFR; i++ ) - { - max = s_max( max, abs_s( signal_ptr[i] ) ); - } - scale_down = 0; - move16(); - if ( GT_16( max, 16384 /*1.Q14*/ ) ) - { - scale_down = 1; - move16(); - } - - /* Compute A(gamma2) residual */ - IF( !scale_down ) - { - Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 1 ); - } - ELSE - { - Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 0 ); - Scale_sig( hPFstat->mem_stp, L_SYN_MEM, -1 ); - } - - /* Controls short term pst filter gain and compute parcor0 */ - calc_st_filt_local_fx( apond2, apond1, &parcor0, res2, hPFstat->mem_zero ); - - /* 1/A(gamma1) filtering, mem_stp is updated */ - resynth[0] = *( hPFstat->mem_stp + sub( L_SYN_MEM, 1 ) ); - move16(); - - E_UTIL_synthesis( 1, apond1, res2, &( resynth[1] ), L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M ); - - IF( !scale_down ) - { - Copy( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM ); - } - ELSE - { - Copy_Scale_sig( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1 ); - } - - /* Tilt filtering */ - Filt_mu_fx( resynth, sig_out, parcor0, L_SUBFR ); - IF( scale_down ) - { - Scale_sig( sig_out, L_SUBFR, 1 ); - } - - /* Gain control */ - scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR ); - - - return; -} -#endif -static void Dec_formant_postfilt_ivas_fx( - PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ - Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q14*/ - Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */ - Word16 *sig_out, /* o : postfiltered output */ - Word16 gamma1, /* i : short term postfilt. den. weighting factor Q15*/ - Word16 gamma2 /* i : short term postfilt. num. weighting factor Q15*/ +static void Dec_formant_postfilt_fx( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q14*/ + Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */ + Word16 *sig_out, /* o : postfiltered output */ + Word16 gamma1, /* i : short term postfilt. den. weighting factor Q15*/ + Word16 gamma2 /* i : short term postfilt. num. weighting factor Q15*/ ) { /* Local variables and arrays */ diff --git a/lib_dec/dec_ppp_fx.c b/lib_dec/dec_ppp_fx.c index 4849e147a..4b3f4f554 100644 --- a/lib_dec/dec_ppp_fx.c +++ b/lib_dec/dec_ppp_fx.c @@ -6,6 +6,7 @@ #include #include "options.h" /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ + /*===================================================================*/ /* FUNCTION : void decod_ppp_fx () */ /*-------------------------------------------------------------------*/ @@ -45,20 +46,20 @@ /*-------------------------------------------------------------------*/ /* CALLED FROM : RX */ /*===================================================================*/ + ivas_error decod_ppp_fx( - Decoder_State *st_fx, /* i/o: state structure */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *pitch_buf_fx, /* i/o: fixed pitch values for each subframe */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 bfi, /* i : bad frame indicator */ - Word16 *gain_buf, + Decoder_State *st_fx, /* i/o: state structure */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + Word16 *pitch_buf_fx, /* i/o: fixed pitch values for each subframe */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 bfi, /* i : bad frame indicator */ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/ Word16 *voice_factors, /* o : voicing factors */ Word16 *bwe_exc_fx /* o : excitation for SWB TBE */ ) { Word16 k; - Word16 LPC_de_curr_fx[M + 1], p_Aq_curr_fx[M], p_Aq_old_fx[M + 1]; Word16 excQ_ppp_fx[L_FRAME], pitch_fx[NB_SUBFR], LPC_de_old_fx[M + 1]; ivas_error error; diff --git a/lib_dec/dec_tran_fx.c b/lib_dec/dec_tran_fx.c index c5b06724a..de3a1ff3f 100644 --- a/lib_dec/dec_tran_fx.c +++ b/lib_dec/dec_tran_fx.c @@ -254,16 +254,10 @@ void decod_tran_fx( tmp_idx_2 = idiv1616( i_subfr, L_SUBFR ); } -#ifdef REMOVE_EVS_DUPLICATES - prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, - &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, - st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, - st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); -#else - prep_tbe_exc_fx( L_frame_fx, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, - st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate ); -#endif + st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); /*----------------------------------------------------------------* * Excitation enhancements (update of total excitation signal) diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index fcc2600a3..f1ba21979 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -25,96 +25,7 @@ static void gain_dec_gacelp_uv_fx( * Decode unvoiced (UC) frames *-------------------------------------------------------------------*/ -#ifndef REMOVE_EVS_DUPLICATES void decod_unvoiced_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ - const Word16 coder_type, /* Q0 i : coding type */ - Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ - Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ - Word16 *voice_factors_fx, /* Q15 o : voicing factors */ - Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ - Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ - Word16 *gain_buf ) -{ - Word16 gain_pit_fx; /* Quantized pitch gain */ - Word32 gain_code_fx; /* Quantized algebraic codeebook gain */ - Word16 gain_inov_fx; /* inovation gain */ - Word32 norm_gain_code_fx; /* normalized algebraic codeebook gain */ - Word16 voice_fac_fx; /* Voicing factor */ - Word16 code_fx[L_SUBFR]; /* algebraic codevector */ - Word16 i_subfr_fx; - const Word16 *p_Aq_fx; - Word16 *pt_pitch_fx; - - gain_pit_fx = 0; - move16(); - - test(); - IF( EQ_16( st_fx->last_ppp_mode_dec, 1 ) || EQ_16( st_fx->last_nelp_mode_dec, 1 ) ) - { - /* SC_VBR - reset the decoder, to avoid memory not updated issue for this unrealistic case */ - CNG_reset_dec_fx( st_fx, pitch_buf_fx, voice_factors_fx ); - } - - p_Aq_fx = Aq_fx; - move16(); /*Q12*/ /* pointer to interpolated LPC parameters */ - pt_pitch_fx = pitch_buf_fx; - move16(); /* pointer to the pitch buffer */ - - FOR( i_subfr_fx = 0; i_subfr_fx < L_FRAME; i_subfr_fx += L_SUBFR ) - { - /*----------------------------------------------------------------* - * Unvoiced subframe processing - *----------------------------------------------------------------*/ - - gaus_dec_fx( st_fx, i_subfr_fx, code_fx, &norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, &gain_inov_fx, &st_fx->tilt_code_fx, - &voice_fac_fx, &gain_pit_fx, pt_pitch_fx, exc_fx, &gain_code_fx, exc2_fx, bwe_exc_fx, &( st_fx->Q_exc ), st_fx->Q_subfr ); - - *tmp_noise_fx = extract_h( norm_gain_code_fx ); /*Q16*/ - move16(); - - /*----------------------------------------------------------------* - * Excitation enhancements (update of total excitation signal) - *----------------------------------------------------------------*/ - - enhancer_fx( st_fx->core_brate, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, - norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); - - Word16 tmp_idx = 0; - move16(); - IF( i_subfr_fx != 0 ) - { - tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); - } - voice_factors_fx[tmp_idx] = 0; - move16(); - - interp_code_5over2_fx( &exc_fx[i_subfr_fx], &bwe_exc_fx[( ( i_subfr_fx * 2 * HIBND_ACB_L_FAC ) >> 1 )], L_SUBFR ); - - p_Aq_fx += ( M + 1 ); - pt_pitch_fx++; - st_fx->tilt_code_dec_fx[tmp_idx] = st_fx->tilt_code_fx; - move16(); - } - - /* SC-VBR */ - st_fx->prev_gain_pit_dec_fx = gain_pit_fx; - move16(); - - set16_fx( gain_buf, 0, NB_SUBFR ); - - return; -} - -/*-------------------------------------------------------------------* - * decod_unvoiced() - * - * Decode unvoiced (UC) frames - *-------------------------------------------------------------------*/ -#endif -void decod_unvoiced_ivas_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ @@ -208,13 +119,11 @@ void decod_unvoiced_ivas_fx( move16(); /* update LP filtered gains for the case of frame erasures */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_FRAME ); } ELSE -#endif { lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_FRAME ); } @@ -250,6 +159,7 @@ void decod_unvoiced_ivas_fx( } // Scale_sig(code_fx, L_SUBFR, 3); //Q12 } + *tmp_noise_fx = extract_h( norm_gain_code_fx ); /*Q16*/ move16(); @@ -257,14 +167,12 @@ void decod_unvoiced_ivas_fx( * Excitation enhancements (update of total excitation signal) *----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { enhancer_fx( st_fx->core_brate, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); } ELSE -#endif { enhancer_ivas_fx( MODE1, st_fx->core_brate, uc_two_stage_flag, 0, coder_type, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx /*Q9/Q12?*/, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc ); @@ -276,12 +184,6 @@ void decod_unvoiced_ivas_fx( IF( i_subfr_fx != 0 ) { tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); -#ifdef REMOVE_EVS_DUPLICATES - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) - { - tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); - } -#endif } voice_factors_fx[tmp_idx] = 0; move16(); diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 090409b4c..fdd442bf6 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -332,11 +332,7 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ -#ifdef REMOVE_EVS_DUPLICATES - IF( ( error = acelp_core_dec_ivas_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) -#else IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -957,15 +953,9 @@ ivas_error evs_dec_fx( } st_fx->lp_noise = hFdCngDec->lp_noise; /*Q9.23*/ move32(); -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); -#else -#ifdef REMOVE_EVS_DUPLICATES - ApplyFdCng_ivas_fx( output_sp, 0, NULL, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); -#else - ApplyFdCng_fx( output_sp, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); -#endif -#endif + + ApplyFdCng_fx( output_sp, 0, NULL, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); + /* Generate additional comfort noise to mask potential coding artefacts */ test(); IF( EQ_16( st_fx->m_frame_type, ACTIVE_FRAME ) && st_fx->flag_cna ) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index d0fd178f2..7aaaeb161 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -555,573 +555,9 @@ void deleteFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec ) error */ -#ifndef REMOVE_EVS_DUPLICATES Word16 ApplyFdCng_fx( Word16 *timeDomainInput, /* i : pointer to time domain input Q*/ Word16 Q, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - Word16 *powerSpectrum, -#endif - Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer cldfbBufferScale*/ - Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer cldfbBufferScale*/ - Word16 *cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */ - Decoder_State *st, - const Word16 concealWholeFrame, /* i : binary flag indicating frame loss Q0*/ - Word16 is_music /*Q0*/ ) -{ - Word16 j, k, nBins; - Word16 s, s1, s2, num, denom; - Word32 *cngNoiseLevel; - Word16 *cngNoiseLevel_exp; - Word32 L_tmp; - Word16 L_tmp_exp; - Word16 facTab[NPART]; - Word16 facTabExp[NPART]; - Word16 tmp_loop; - Word32 L_c; - Word16 lsp_cng[M]; - HANDLE_FD_CNG_DEC hFdCngDec; - HANDLE_FD_CNG_COM hFdCngCom; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - Flag Carry = 0; - move16(); - move16(); -#endif -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - int16_t L_frame, last_L_frame; - int32_t sr_core; - - PMT( "Fix point code missing for IVAS_CODE_CNG_FIX185_PLC_FADEOUT" ) - /* limit L_frame and core fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */ - L_frame = min( st->L_frame, L_FRAME16k ); - last_L_frame = min( st->last_L_frame, L_FRAME16k ); - sr_core = min( st->sr_core, INT_FS_16k ); -#endif - - hFdCngDec = st->hFdCngDec; - hFdCngCom = hFdCngDec->hFdCngCom; - - - if ( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) ) - { - hFdCngCom->inactive_frame_counter = 0; - move16(); - } - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - hFdCngDec->flag_dtx_mode = hFdCngDec->flag_dtx_mode || st->first_CNG; - test(); - move16(); - } - cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/ - move32(); - cngNoiseLevel_exp = &hFdCngCom->cngNoiseLevelExp; - move16(); - nBins = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); - - SWITCH( st->m_frame_type ) - { - case ACTIVE_FRAME: - - /************************** - * ACTIVE_FRAME at DECODER * - **************************/ - - hFdCngCom->inactive_frame_counter = 0; - move16(); - hFdCngCom->sid_frame_counter = 0; - move16(); - - /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ - /* set noise estimation inactive during concealment, no update with noise generated by concealment should be performed. */ - -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - if ( concealWholeFrame == 0 && - ( timeDomainInput == NULL || - ( *timeDomainInput( -FLT_MAX ) && - *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX && - *( timeDomainInput + hFdCngCom->frameSize - 1 ) > ( -FLT_MAX ) ) ) && - ( ( ( ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && hFdCngDec->flag_dtx_mode ) || !st->VAD ) && - !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) || - ( st->element_mode == IVAS_CPE_TD ) ) && - ( !st->BER_detect ) ) -#else - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( - ( concealWholeFrame == 0 ) && - ( LT_16( *timeDomainInput, MAXVAL_WORD16 ) ) && GT_16( *timeDomainInput, MINVAL_WORD16 ) && ( LT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MAXVAL_WORD16 ) ) && GT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MINVAL_WORD16 ) && ( ( ( hFdCngDec->flag_dtx_mode == 0 ) && ( st->VAD != 0 ) ) == 0 ) && ( ( ( st->cng_type == LP_CNG ) && ( hFdCngDec->flag_dtx_mode != 0 ) ) == 0 ) && ( is_music == 0 ) && ( st->BER_detect == 0 ) ) -#endif - { - /* Perform noise estimation at the decoder */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - perform_noise_estimation_dec_fx( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); -#else - perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); -#endif - - /* Update the shaping parameters */ - test(); - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); - } - hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; - move16(); - - - /* Update CNG levels */ - test(); - IF( hFdCngDec->flag_dtx_mode != 0 && EQ_16( st->cng_type, FD_CNG ) ) - { - /* This needs to be done only once per inactive phase */ - bandcombinepow( - hFdCngDec->bandNoiseShape, - hFdCngDec->bandNoiseShape_exp, - nBins, - hFdCngCom->part, - hFdCngCom->nFFTpart, - hFdCngCom->psize_inv, - hFdCngDec->partNoiseShape, - &hFdCngDec->partNoiseShape_exp ); - - - j = 0; - move16(); - s2 = -( WORD32_BITS - 1 ); - move16(); - FOR( k = 0; k < hFdCngCom->nFFTpart; k++ ) - { - assert( hFdCngDec->partNoiseShape[k] >= 0 ); - assert( hFdCngCom->sidNoiseEst[k] >= 0 ); - - /* add DELTA as it is done in FLC version, in order to avoid num > denom */ - facTab[k] = 0; - move16(); - IF( hFdCngDec->partNoiseShape[k] != 0 ) - { - s1 = norm_l( hFdCngCom->sidNoiseEst[k] ); - L_tmp = L_shl( hFdCngCom->sidNoiseEst[k], s1 ); /*Q31 - hFdCngCom->sidNoiseEstExp + s1*/ - L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp ); - L_tmp = L_shr( L_tmp, 1 ); - s = add( L_tmp_exp, 1 ); - num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/ - - s1 = norm_l( hFdCngDec->partNoiseShape[k] ); - L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - hFdCngDec->partNoiseShape_exp + s1*/ - L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp ); - s = sub( s, L_tmp_exp ); - denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/ - - facTab[k] = div_s( num, denom ); /*Q15 - s*/ - move16(); - facTabExp[k] = s; - move16(); - } - /* Set unique exponent, if mantissa is equal to zero */ - if ( facTab[k] == 0 ) - { - facTabExp[k] = -( WORD32_BITS - 1 ); - move16(); - } - s2 = s_max( s2, facTabExp[k] ); - } - - FOR( k = 0; k < hFdCngCom->nFFTpart; k++ ) - { - s = sub( facTabExp[k], s2 ); - s = s_max( s_min( s, WORD32_BITS - 1 ), -( WORD32_BITS - 1 ) ); - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/ - move32(); - } - } - - /* adapt scaling for rest of the buffer */ - IF( NE_16( s2, -( WORD32_BITS - 1 ) ) ) - { - s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); - FOR( ; k < hFdCngCom->npart; k++ ) - { - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ - move32(); - } - } - - *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); - move16(); - } - } - ELSE - { - /* This sets the new CNG levels until a SID update overwrites it */ - test(); - test(); - test(); - IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) ) || ( EQ_16( st->element_mode, IVAS_CPE_TD ) && !hFdCngDec->flag_dtx_mode && !st->VAD ) ) - { - Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, nBins ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/ - *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; - move16(); - } - } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL ) - { - st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); - } - else - { - st->hTcxDec->CngLevelBackgroundTrace_bfi = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); - } -#endif - /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ - tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); - L_tmp = L_deposit_h( 0 ); - L_c = L_deposit_h( 0 ); - FOR( j = 0; j < tmp_loop; j++ ) - { - - Carry = 0; - move16(); - L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/ - Overflow = 0; - move16(); - - IF( *( cngNoiseLevel + j ) < 0 ) - { - L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/ - } - IF( *( cngNoiseLevel + j ) >= 0 ) - { - L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ - } - } - L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ - L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 ); - - L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/ - - L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/ - L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ - L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ - - st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/ - st->cngTDLevel_e = L_tmp_exp; - move16(); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - IF( hFdCngCom->active_frame_counter > 0 ) - { - /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - perform_noise_estimation_dec_fx( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); -#else - perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); -#endif - } - } - test(); - test(); - L_tmp = 0; - FOR( j = hFdCngCom->startBand; j < hFdCngCom->stopFFTbin; j++ ) - { - L_tmp = L_add( L_tmp, L_shr( cngNoiseLevel[j], 16 ) ); - } - L_tmp_exp = add( *cngNoiseLevel_exp, 16 ); - test(); - test(); - IF( EQ_16( concealWholeFrame, 1 ) && EQ_16( st->nbLostCmpt, 1 ) && ( GT_32( L_shl_o( L_tmp, L_tmp_exp, &Overflow ), 21474836 ) /*0.01f Q31*/ ) ) - { - /* update isf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ -#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 ); - E_LPC_a_lsp_conversion( hFdCngCom->A_cng, lsp_cng, st->lspold_cng, M ); - Copy( lsp_cng, st->lspold_cng, M ); /*Q15*/ - - lsp2lsf_fx( lsp_cng, st->lsf_cng, M, st->sr_core ); -#else - if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) - { - float scf[SNS_NPTS]; - float scf_int[FDNS_NPTS]; - float whitenend_noise_shape[L_FRAME16k]; - int16_t inc, start_idx, stop_idx; - float *noiseLevelPtr; - - - inc = ( st->core > TCX_20 ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = L_frame / inc; - noiseLevelPtr = cngNoiseLevel; - - set_zero( whitenend_noise_shape, start_idx ); - for ( j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) - { - whitenend_noise_shape[j] = *noiseLevelPtr; - } - if ( st->core == TCX_20_CORE ) - { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX20; - } - else - { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX10; - } - - sns_compute_scf( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, L_frame, scf ); - sns_interpolate_scalefactors( scf_int, scf, ENC ); - sns_interpolate_scalefactors( st->hTonalMDCTConc->scaleFactorsBackground_flt, scf, DEC ); - sns_shape_spectrum( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, scf_int, L_frame ); - - mvr2r( whitenend_noise_shape + start_idx, cngNoiseLevel, stop_idx - start_idx ); - wmops_sub_end(); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); - a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); - } - -#endif - st->plcBackgroundNoiseUpdated = 1; - move16(); - } - BREAK; - - case SID_FRAME: - - hFdCngDec->flag_dtx_mode = 1; - move16(); - /* no break */ - - case ZERO_FRAME: - - test(); - IF( st != NULL && st->cng_type == LP_CNG ) - { - /* Perform noise estimation on inactive phase at the decoder */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - perform_noise_estimation_dec_fx( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); -#else - perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); -#endif - /* Update the shaping parameters */ - - test(); - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); - } - hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; - move16(); - /* This sets the new CNG levels until a SID update overwrites it */ - Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it Q31 - hFdCngDec->bandNoiseShape_exp*/ - *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; - move16(); -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); -#else - /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ - tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); - L_tmp = L_deposit_h( 0 ); - L_c = L_deposit_h( 0 ); - FOR( j = 0; j < tmp_loop; j++ ) - { - - Carry = 0; - move16(); - L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/ - Overflow = 0; - move16(); - - IF( *( cngNoiseLevel + j ) < 0 ) - { - L_c = L_msuNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ - } - IF( *( cngNoiseLevel + j ) >= 0 ) - { - L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ - } - } - L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ - L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 ); - - L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/ - - L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/ - L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ - L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ - - st->cngTDLevel = round_fx_o( Sqrt32( L_tmp, &L_tmp_exp ), &Overflow ); /*Q15 - L_tmp_exp*/ - move16(); - st->cngTDLevel_e = L_tmp_exp; - move16(); -#endif - BREAK; - } - hFdCngCom->inactive_frame_counter = add( hFdCngCom->inactive_frame_counter, 1 ); - move16(); - - /************************************* - * SID_FRAME or ZERO_FRAME at DECODER * - *************************************/ - - /* Detect first non-active frame */ - IF( EQ_16( hFdCngCom->inactive_frame_counter, 1 ) ) - { - /* Compute the fine spectral structure of the comfort noise shape using the decoder-side noise estimates */ - bandcombinepow( - hFdCngDec->bandNoiseShape, - hFdCngDec->bandNoiseShape_exp, - nBins, - hFdCngCom->part, - hFdCngCom->nFFTpart, - hFdCngCom->psize_inv, - hFdCngDec->partNoiseShape, - &hFdCngDec->partNoiseShape_exp ); - } - - IF( EQ_16( st->m_frame_type, SID_FRAME ) ) - { - IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) - { - /* At initialization, interpolate the bin/band-wise levels from the partition levels */ - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, - hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); - *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; - move16(); - } - ELSE - { - if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - } - - /* Interpolate the CLDFB band levels from the SID (partition) levels */ - IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) - { - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, - hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); - *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; - move16(); - } - - s2 = -( WORD32_BITS - 1 ); - move16(); - /* Shape the SID noise levels in each FFT bin */ - j = 0; - move16(); - FOR( k = 0; k < hFdCngCom->nFFTpart; k++ ) - { - assert( hFdCngDec->partNoiseShape[k] >= 0 ); - - /* add DELTA as it is done in FLC version, in order to avoid num > denom */ - facTab[k] = 0; - move16(); - IF( hFdCngDec->partNoiseShape[k] != 0 ) - { - s1 = norm_l( hFdCngCom->sidNoiseEst[k] ); - L_tmp = L_shl( hFdCngCom->sidNoiseEst[k], s1 ); /*Q31 - hFdCngCom->sidNoiseEstExp + s1*/ - L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 ); - L_tmp = BASOP_Util_Add_Mant32Exp( hFdCngCom->sidNoiseEst[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp ); - L_tmp = L_shr( L_tmp, 1 ); - s = add( L_tmp_exp, 1 ); - num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/ - - s1 = norm_l( hFdCngDec->partNoiseShape[k] ); - L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - hFdCngDec->partNoiseShape_exp + s1*/ - L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp ); - s = sub( s, L_tmp_exp ); - denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/ - - facTab[k] = div_s( num, denom ); /*Q15 - s*/ - move16(); - facTabExp[k] = s; - move16(); - } - /* Set unique exponent, if mantissa is equal to zero */ - if ( facTab[k] == 0 ) - { - facTabExp[k] = -( WORD32_BITS - 1 ); - move16(); - } - s2 = s_max( s2, facTabExp[k] ); - } - - FOR( k = 0; k < hFdCngCom->nFFTpart; k++ ) - { - s = sub( facTabExp[k], s2 ); - s = s_max( s_min( s, WORD32_BITS - 1 ), -( WORD32_BITS - 1 ) ); - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/ - move32(); - } - } - /* adapt scaling for rest of the buffer */ - s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) ); - FOR( ; k < hFdCngCom->npart; k++ ) - { - FOR( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ - move32(); - } - } - *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 ); - move16(); - } - } - - IF( EQ_16( st->codec_mode, MODE2 ) ) - { - /* Generate comfort noise during SID or zero frames */ - generate_comfort_noise_dec_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); - } - - BREAK; - - default: - return -1; - } - - - return 0; -} -#endif -Word16 ApplyFdCng_ivas_fx( - Word16 *timeDomainInput, /* i : pointer to time domain input Q*/ - Word16 Q, Word32 *powerSpectrum, /*Q_power_spectrum*/ Word16 Q_power_spectrum, Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer cldfbBufferScale*/ @@ -1221,27 +657,22 @@ Word16 ApplyFdCng_ivas_fx( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); } ELSE -#endif { perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); } /* Update the shaping parameters */ test(); -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } - ELSE -#endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + ELSE IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } @@ -1477,13 +908,11 @@ Word16 ApplyFdCng_ivas_fx( IF( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); } ELSE -#endif { perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); } @@ -1544,44 +973,37 @@ Word16 ApplyFdCng_ivas_fx( IF( st != NULL && EQ_16( st->cng_type, LP_CNG ) ) { /* Perform noise estimation on inactive phase at the decoder */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); } ELSE -#endif { perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); } /* Update the shaping parameters */ - test(); -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } - ELSE -#endif - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) + ELSE IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 ); } hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; move16(); + /* This sets the new CNG levels until a SID update overwrites it */ Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it */ /*Q31 - hFdCngDec->bandNoiseShape_exp*/ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; move16(); } ELSE -#endif { Word16 shift1 = L_norm_arr( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) ); @@ -1662,16 +1084,15 @@ Word16 ApplyFdCng_ivas_fx( IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); } ELSE -#endif { scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); } + *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); } @@ -1684,13 +1105,11 @@ Word16 ApplyFdCng_ivas_fx( /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); } ELSE -#endif { scalebands_fx( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); } @@ -1757,7 +1176,6 @@ Word16 ApplyFdCng_ivas_fx( } } -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { /* adapt scaling for rest of the buffer */ @@ -1774,7 +1192,6 @@ Word16 ApplyFdCng_ivas_fx( move16(); } ELSE -#endif { Word16 shift1 = L_norm_arr( cngNoiseLevel, j ); Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) ); @@ -1863,13 +1280,11 @@ Word16 ApplyFdCng_ivas_fx( IF( EQ_16( st->codec_mode, MODE2 ) ) { /* Generate comfort noise during SID or zero frames */ -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st->element_mode, EVS_MONO ) ) { generate_comfort_noise_dec_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); } ELSE -#endif { generate_comfort_noise_dec_ivas_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 ); } diff --git a/lib_dec/gain_dec_fx.c b/lib_dec/gain_dec_fx.c index 00eca187d..db325cd80 100644 --- a/lib_dec/gain_dec_fx.c +++ b/lib_dec/gain_dec_fx.c @@ -602,7 +602,6 @@ void gain_dec_mless_fx( /* _ None */ /*==================================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void gain_dec_lbr_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ const Word16 coder_type, /* i : coding type */ @@ -653,375 +652,6 @@ void gain_dec_lbr_fx( ctype = shl( sub( coder_type, 1 ), 1 ); - /*-----------------------------------------------------------------* - * calculate prediction of gcode - * search for the best codeword - *-----------------------------------------------------------------*/ - IF( i_subfr == 0 ) - { - b_fx = b_1sfr_fx; - move16(); - n_pred = 2; - move16(); - cdbk_fx = gp_gamma_1sfr_6b_fx; - SWITCH( nBits ) - { - case 8: - { - cdbk_fx = gp_gamma_1sfr_8b_fx; /* Q14/Q9*/ - BREAK; - } - case 7: - { - cdbk_fx = gp_gamma_1sfr_7b_fx; /* Q14/Q9*/ - BREAK; - } - case 6: - { - cdbk_fx = gp_gamma_1sfr_6b_fx; /* Q14/Q9*/ - BREAK; - } - } - - /* calculate predicted gain */ - aux_fx[0] = 4096; /*Q12*/ - move16(); - aux_fx[1] = shl( ctype, 12 ); /*Q12*/ - move16(); - - /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); - gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode)); - gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */ - - e_tmp = norm_l( L_tmp2 ); - f_tmp = Log2_norm_lc( L_shl( L_tmp2, e_tmp ) ); /*Q15*/ - e_tmp = sub( expg2, add( 1, e_tmp ) ); - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/ - - L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ - L_tmp = Mult_32_16( L_tmp, 160 ); /*Q13, 20 in Q3*/ - L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q13*/ - - gcode0_fx = round_fx( L_shl( L_tmp, 11 ) ); /* Q8 */ - - - /*-----------------------------------------------------------------* - * gcode0 = pow(10.0, gcode0/20) - * = pow(2, 3.321928*gcode0/20) - * = pow(2, 0.166096*gcode0) - *-----------------------------------------------------------------*/ - - L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */ - L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ - frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ - - gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp_gcode0 = sub( exp_gcode0, 14 ); - - /* retrieve the codebook index and calculate both gains */ - /*index = (Word16)get_indice( st_fx,"gain", i_subfr, ACELP_CORE);move16();*/ - index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/ - move16(); - - *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/ - move16(); - - L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ - move16(); - - gc_mem[0] = *gain_code_fx; /*Q16*/ - move32(); - gp_mem[0] = *gain_pit_fx; /*Q14*/ - move16(); - } - ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) ) - { - b_fx = b_2sfr_fx; /*Q12*/ - move16(); - n_pred = 4; - move16(); - - cdbk_fx = gp_gamma_1sfr_6b_fx; /*Q14/Q9 */ - SWITCH( nBits ) - { - case 7: - { - cdbk_fx = gp_gamma_2sfr_7b_fx; /* Q14/Q9*/ - BREAK; - } - case 6: - { - cdbk_fx = gp_gamma_2sfr_6b_fx; /* Q14/Q9*/ - BREAK; - } - } - - /* calculate predicted gain */ - aux_fx[0] = 4096; /*Q12*/ - move16(); - aux_fx[1] = shl( ctype, 12 ); /*Q12*/ - move16(); - - /*aux_fx[2] = (float)log10(gc_mem[0]); - = log2(gc_mem[0])*log10(2);*/ - e_tmp = norm_l( gc_mem[0] ); - f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/ - e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/ - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ - move16(); - - aux_fx[3] = shr( gp_mem[0], 2 ); /*Q12*/ - move16(); - - /*-----------------------------------------------------------------* - * gcode0 = pow(10.0, dotp(b, aux, n_pred) - * = pow(2, 3.321928*dotp(b, aux, n_pred) - *-----------------------------------------------------------------*/ - L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ - L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ - L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ - frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ - - gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp_gcode0 = sub( exp_gcode0, 14 ); - - /* retrieve the codebook index and calculate both gains */ - index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/ - move16(); - - *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/ - move16(); - - L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ - move16(); - - gc_mem[1] = *gain_code_fx; /*Q16*/ - move32(); - gp_mem[1] = *gain_pit_fx; /*Q14*/ - move16(); - } - ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) - { - b_fx = b_3sfr_fx; - move16(); - n_pred = 6; - move16(); - - cdbk_fx = gp_gamma_3sfr_6b_fx; /*Q14/Q9 */ - - if ( EQ_16( nBits, 7 ) ) - { - cdbk_fx = gp_gamma_3sfr_7b_fx; /*Q14*/ - // PMT("verify if gp_gamma_3sfr_7b_fx is correct") - } - - /* calculate predicted gain */ - aux_fx[0] = 4096; /*Q12*/ - move16(); - aux_fx[1] = shl( ctype, 12 ); /*Q12*/ - move16(); - - /*aux_fx[2] = (float)log10(gc_mem[0]); - = log2(gc_mem[0])*log10(2);*/ - e_tmp = norm_l( gc_mem[0] ); - f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/ - e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/ - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ - move16(); - - /*aux[3] = (float)log10(gc_mem[1]); - = log2(gc_mem[1])*log10(2);*/ - e_tmp = norm_l( gc_mem[1] ); - f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/ - e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/ - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ - move16(); - - aux_fx[4] = shr( gp_mem[0], 2 ); /*Q12*/ - move16(); - aux_fx[5] = shr( gp_mem[1], 2 ); /*Q12*/ - move16(); - - /*-----------------------------------------------------------------* - * gcode0 = pow(10.0, dotp(b, aux, n_pred) - * = pow(2, 3.321928*dotp(b, aux, n_pred) - *-----------------------------------------------------------------*/ - L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ - L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ - L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ - frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ - - gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp_gcode0 = sub( exp_gcode0, 14 ); - - /* retrieve the codebook index and calculate both gains */ - index = (Word16) get_next_indice_fx( st_fx, nBits ); - move16(); - - *gain_pit_fx = cdbk_fx[( index * 2 )]; /*Q14*/ - move16(); - - L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ - move32(); - gc_mem[2] = *gain_code_fx; /*Q16*/ - move32(); - gp_mem[2] = *gain_pit_fx; /*Q14*/ - move16(); - } - ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) ) - { - b_fx = b_4sfr_fx; /*Q12*/ - n_pred = 8; - move16(); - - - cdbk_fx = gp_gamma_4sfr_6b_fx; /*Q14*/ -#ifdef IVAS_GAIN_MOD - IF( EQ_16( nBits, 7 ) ) - { - cdbk_fx = gp_gamma_4sfr_7b_fx; - PMT( "verify if gp_gamma_4sfr_7b_fx is correct" ) - } -#endif - - /* calculate predicted gain */ - aux_fx[0] = 4096; /*Q12*/ - move16(); - aux_fx[1] = shl( ctype, 12 ); /*Q12*/ - move16(); - - /*aux[2] = (float)log10(gc_mem[0]); - = log2(gc_mem[0])*log10(2);*/ - e_tmp = norm_l( gc_mem[0] ); - f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/ - e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/ - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ - move16(); - - /*aux[3] = (float)log10(gc_mem[1]); - = log2(gc_mem[1])*log10(2);*/ - e_tmp = norm_l( gc_mem[1] ); - f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/ - e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/ - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ - move16(); - - /*aux[4] = (float)log10(gc_mem[2]); - = log2(gc_mem[2])*log10(2);*/ - e_tmp = norm_l( gc_mem[2] ); - f_tmp = Log2_norm_lc( L_shl( gc_mem[2], e_tmp ) ); /*Q15*/ - e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[2])=16*/ - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ - aux_fx[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ - move16(); - - aux_fx[5] = shr( gp_mem[0], 2 ); /*Q12*/ - move16(); - aux_fx[6] = shr( gp_mem[1], 2 ); /*Q12*/ - move16(); - aux_fx[7] = shr( gp_mem[2], 2 ); /*Q12*/ - move16(); - - /*-----------------------------------------------------------------* - * gcode0 = pow(10.0, dotp(b, aux, n_pred) - * = pow(2, 3.321928*dotp(b, aux, n_pred) - *-----------------------------------------------------------------*/ - L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/ - L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ - L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ - frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ - - gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp_gcode0 = sub( exp_gcode0, 14 ); - - /* retrieve the codebook index and calculate both gains */ - index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/ - move16(); - *gain_pit_fx = cdbk_fx[( index * 2 )]; /*Q14*/ - move16(); - - L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ - move32(); - } - - /* *norm_gain_code = *gain_code / *gain_inov; */ - expg = sub( norm_s( *gain_inov_fx ), 1 ); - expg = s_max( expg, 0 ); - - tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); /*Q15*/ - *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q16*/ - move32(); - - return; -} -#endif -void gain_dec_lbr_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word16 coder_type, /* i : coding type */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *code_fx, /* i : algebraic excitation Q9 */ - Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/ - Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ - Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ - Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ - Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ - Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ - const Word16 L_subfr /* i : subfr lenght */ -) -{ - Word16 index, nBits, n_pred, ctype; - Word16 gcode0_fx, aux_fx[10]; - Word32 L_tmp, L_tmp1, L_tmp2; - Word16 expg, expg2, e_tmp, exp_gcode0, f_tmp, frac, tmp_fx; - const Word16 *b_fx, *cdbk_fx = 0; - /* Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR; - *gain_inov = 1.0f / (float)sqrt(Ecode); */ - Word16 shift_L_subfr; - shift_L_subfr = 6; - move16(); // for *cdbk_fx - move16(); - if ( GT_16( L_subfr, L_SUBFR ) ) - { - shift_L_subfr = add( shift_L_subfr, 1 ); - } - L_tmp = Dot_product12( code_fx, code_fx, L_subfr, &expg ); /*Q31 - expg*/ - expg = sub( expg, add( 18, shift_L_subfr ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ - - expg2 = expg; - move16(); - L_tmp2 = L_tmp; /* sets to 'L_tmp' in 1 clock */ - move32(); - L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/ - - *gain_inov_fx = extract_h( L_shl_sat( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */ - move16(); - - /*-----------------------------------------------------------------* - * select the codebook, size and number of bits - * set the gains searching range - *-----------------------------------------------------------------*/ - nBits = st_fx->acelp_cfg.gains_mode[shr( i_subfr, shift_L_subfr )]; - move16(); - - ctype = shl( sub( coder_type, 1 ), 1 ); - /*-----------------------------------------------------------------* * calculate prediction of gcode * search for the best codeword @@ -1583,24 +1213,28 @@ void lp_gain_updt_ivas_fx( } /*-------------------------------------------------* - * Gain_dec_gaus_vbr + * gain_dec_gaus_fx() * * Decode gains of purely unvoiced sounds *-------------------------------------------------*/ -Word32 gain_dec_gaus_fx( /* o : quantized codebook gain Q16 */ - Word16 index, /* i : quantization index */ - const Word16 bits, /* i : number of bits to quantize */ - const Word16 lowBound, /* i : lower bound of quantizer (dB) */ - const Word16 topBound, /* i : upper bound of quantizer (dB) */ - const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */ - Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */ + +/*! r: quantized codebook gain Q16 */ +Word32 gain_dec_gaus_fx( + Word16 index, /* i : quantization index */ + const Word16 bits, /* i : number of bits to quantize */ + const Word16 lowBound, /* i : lower bound of quantizer (dB) */ + const Word16 topBound, /* i : upper bound of quantizer (dB) */ + const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */ + Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */ ) { Word16 stepSize, gain, expg, frac, expi, tmp_igi; Word32 L_tmp, L_enr_q, L_gain; Word16 stepSize_Exp; + stepSize_Exp = 14; move16(); + /*------------------------------------------------------------------------------------------* * Quantize linearly the log E *------------------------------------------------------------------------------------------*/ diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index cf0fabc76..70639810c 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -23,7 +23,7 @@ /* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ /*--------------------------------------------------------------------------*/ /* INPUT/OUTPUT ARGUMENTS : */ -/* Decoder_State *st_fx : decoder memory structure */ +/* Decoder_State *st_fx : decoder memory structure */ /* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ /* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ /*--------------------------------------------------------------------------*/ @@ -31,439 +31,17 @@ /* _ None */ /*==========================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void decod_audio_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ - const Word16 *Aq, /* i : LP filter coefficient Q12*/ - Word16 *pitch_buf, /* o : floating pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors Q15*/ - Word16 *exc, /* i/o: adapt. excitation exc Q_exc*/ - Word16 *exc2, /* i/o: adapt. excitation/total exc Q_exc*/ - Word16 *bwe_exc, /* o : excitation for SWB TBE Q_exc*/ - Word16 *lsf_new /* i : ISFs at the end of the frame Qx*/ - , - Word16 *gain_buf /*Q14*/ -) -{ - Word16 tmp_nb_bits_tot, pit_band_idx; - Word16 code[4 * L_SUBFR]; - Word16 Diff_len, nb_subfr, i; - Word16 nb_frame_flg; - Word16 Es_pred = 0; - Word16 Len, max_len; - Word16 gsc_attack_flag; - - Word16 low_pit; - Word16 last_bin; - Word16 nbits; - - Word16 exc_wo_nf[L_FRAME16k]; - GSC_DEC_HANDLE hGSCDec; - hGSCDec = st_fx->hGSCDec; - - - /*---------------------------------------------------------------* - * Initialization - *---------------------------------------------------------------*/ - move16(); // corresponding to initialization of Es_pred - Diff_len = 0; - move16(); - - /* decode GSC attack flag (used to reduce possible pre-echo) */ - gsc_attack_flag = (Word16) get_next_indice_fx( st_fx, 1 ); /* Q0 */ - move16(); - - /* decode GSC SWB speech flag */ - test(); - IF( st_fx->coder_type != INACTIVE && GE_32( st_fx->total_brate, ACELP_13k20 ) ) - { - st_fx->GSC_noisy_speech = (Word16) get_next_indice_fx( st_fx, 1 ); /* Q0 */ - move16(); - } - - /* safety check in case of bit errors */ - test(); - test(); - IF( st_fx->GSC_noisy_speech && LT_16( st_fx->bwidth, SWB ) && st_fx->GSC_IVAS_mode == 0 ) - { - st_fx->BER_detect = 1; /* Q0 */ - move16(); - st_fx->GSC_noisy_speech = 0; /* Q0 */ - move16(); - } - - /* set bit-allocation */ -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); -#endif - - /*---------------------------------------------------------------* - * Decode energy dynamics - *---------------------------------------------------------------*/ - - IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) ) - { - nb_subfr = NB_SUBFR; /* Q0 */ - move16(); - hGSCDec->cor_strong_limit = 0; - move16(); - hGSCDec->noise_lev = NOISE_LEVEL_SP3; /* Q0 */ - move16(); - } - ELSE - { - IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) - { - hGSCDec->noise_lev = add( (Word16) get_next_indice_fx( st_fx, 2 ), NOISE_LEVEL_SP2 ); /* Q0 */ - move16(); - } - ELSE - { - hGSCDec->noise_lev = add( (Word16) get_next_indice_fx( st_fx, 3 ), NOISE_LEVEL_SP0 ); /* Q0 */ - move16(); - } - - /*---------------------------------------------------------------* - * Decode number of subframes - *---------------------------------------------------------------*/ - - - hGSCDec->cor_strong_limit = 1; /* Q0 */ - move16(); - nb_subfr = SWNB_SUBFR; - move16(); - - IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) - { - nbits = 1; - move16(); - nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ - move16(); - - IF( s_and( nb_frame_flg, 0x1 ) == 0 ) - { - nb_subfr = 2 * SWNB_SUBFR; /* Q0 */ - move16(); - hGSCDec->cor_strong_limit = 0; - move16(); - } - } - } - - /*---------------------------------------------------------------* - * Decode the last band where the adaptive (pitch) contribution is significant - *---------------------------------------------------------------*/ - - IF( LT_32( st_fx->core_brate, CFREQ_BITRATE ) ) - { - nbits = 3; /* Q0 */ - move16(); - test(); - if ( LT_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->coder_type == INACTIVE ) - { - nbits = 1; /* Q0 */ - move16(); - } - } - ELSE - { - nbits = 4; /* Q0 */ - move16(); - } - test(); - IF( LT_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->coder_type != INACTIVE ) - { - pit_band_idx = 1; /* Q0 */ - move16(); - } - ELSE - { - pit_band_idx = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ - move16(); - } - - IF( pit_band_idx != 0 ) - { - IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) - { - pit_band_idx = 7 + BAND1k2; /* Q0 */ - move16(); /* At low rate, if pitch model is chosen, then for to be use on extented and constant frequency range */ - } - ELSE - { - pit_band_idx = add( pit_band_idx, BAND1k2 ); /* Q0 */ - } - - /* detect bit errors in the bitstream */ - IF( GT_16( pit_band_idx, 13 ) ) /* The maximum decodable index is 10 + BAND1k2 (3) = 13 */ - { - pit_band_idx = 13; /* Q0 */ - move16(); - st_fx->BER_detect = 1; /* Q0 */ - move16(); - } - Diff_len = mfreq_loc_div_25[pit_band_idx]; /* Q0 */ - move16(); - } - hGSCDec->Last_GSC_pit_band_idx = pit_band_idx; /* Q0 */ - move16(); - - - /*--------------------------------------------------------------------------------------* - * Decode adaptive (pitch) excitation contribution - * Reset unvaluable part of the adaptive (pitch) excitation contribution - *--------------------------------------------------------------------------------------*/ - IF( GT_16( pit_band_idx, BAND1k2 ) ) - { - /*---------------------------------------------------------------* - * Decode adaptive (pitch) excitation contribution - *---------------------------------------------------------------*/ - test(); - IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) && EQ_16( nb_subfr, NB_SUBFR ) ) - { - Word16 indice; - nbits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( st_fx->core_brate, GENERIC, -1, -1 )]; /* Q0 */ - move16(); - if ( st_fx->element_mode > EVS_MONO ) - { - nbits = 5; - move16(); - } - - indice = get_next_indice_fx( st_fx, nbits ); /* Q0 */ - - Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); - } - - dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf ); - - IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) - { - minimum_fx( pitch_buf, shr( st_fx->L_frame, 6 ), &low_pit ); - low_pit = shr( low_pit, 6 ); /*Q6 -> Q0 */ - - IF( LT_16( low_pit, 64 ) ) - { - pit_band_idx = 9 + BAND1k2; /* Q0 */ - move16(); - if ( st_fx->bwidth == NB ) - { - pit_band_idx = 7 + BAND1k2; /* Q0 */ - move16(); - } - } - ELSE IF( LT_16( low_pit, 128 ) ) - { - pit_band_idx = 5 + BAND1k2; /* Q0 */ - move16(); - } - ELSE - { - pit_band_idx = 3 + BAND1k2; /* Q0 */ - move16(); - } - - Diff_len = mfreq_loc_div_25[pit_band_idx]; /* Q0 */ - move16(); - hGSCDec->Last_GSC_pit_band_idx = pit_band_idx; /* Q0 */ - move16(); - } - - /*---------------------------------------------------------------* - * DCT transform - *---------------------------------------------------------------*/ - edct_16fx( exc, dct_epit, st_fx->L_frame, 7, st_fx->element_mode ); - - /*---------------------------------------------------------------* - * Reset unvaluable part of the adaptive (pitch) excitation contribution - *---------------------------------------------------------------*/ - - max_len = sub( st_fx->L_frame, Diff_len ); /* Q0 */ - - if ( st_fx->bwidth == NB ) - { - max_len = sub( 160, Diff_len ); /* Q0 */ - } - - Len = 80; - move16(); - if ( LT_16( max_len, 80 ) ) - { - Len = max_len; /* Q0 */ - move16(); - } - - test(); - IF( EQ_32( st_fx->core_brate, ACELP_8k00 ) && NE_16( st_fx->bwidth, NB ) ) - { - FOR( i = 0; i < max_len; i++ ) - { - dct_epit[i + Diff_len] = 0; - move16(); - } - } - ELSE - { - FOR( i = 0; i < Len; i++ ) - { - dct_epit[i + Diff_len] = mult_r( dct_epit[i + Diff_len], sm_table_fx[i] ); /* Qx */ - move16(); - } - - FOR( ; i < max_len; i++ ) - { - dct_epit[i + Diff_len] = 0; - move16(); - } - } - // PMT("in the rare case of 4 subfr, bfi_pitch_fx might be wrong") - st_fx->bfi_pitch_fx = mean_fx( pitch_buf, nb_subfr ); /* Q6 */ - move16(); - st_fx->bfi_pitch_frame = st_fx->L_frame; /* Q0 */ - move16(); - - Diff_len = add( Diff_len, 1 ); /* Q0 */ - st_fx->bpf_off = 0; - move16(); - } - ELSE - { - /* No adaptive (pitch) excitation contribution */ - st_fx->bpf_off = 1; /* Q0 */ - move16(); - set16_fx( dct_epit, 0, st_fx->L_frame ); - - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - set16_fx( pitch_buf, L_SUBFR16k * 64, NB_SUBFR16k ); - } - ELSE - { - set16_fx( pitch_buf, L_SUBFR * 64, NB_SUBFR ); - } - - set16_fx( gain_buf, 0, NB_SUBFR16k ); - - st_fx->bfi_pitch_fx = L_SUBFR * 64; - move16(); - st_fx->bfi_pitch_frame = st_fx->L_frame; /* Q0 */ - move16(); - st_fx->lp_gainp_fx = 0; - move16(); - st_fx->lp_gainc_fx = 0; - move16(); - st_fx->tilt_code_fx = 0; - move16(); - pit_band_idx = 0; - move16(); - Diff_len = 0; - move16(); - } - - /*--------------------------------------------------------------------------------------* - * GSC decoder - *--------------------------------------------------------------------------------------*/ - - /* find the current total number of bits used */ - - tmp_nb_bits_tot = st_fx->next_bit_pos; /* Q0 */ - move16(); - - if ( st_fx->extl_brate > 0 ) - { - /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ - tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ - } - - test(); - if ( st_fx->coder_type == INACTIVE && LE_32( st_fx->core_brate, ACELP_9k60 ) ) - { - tmp_nb_bits_tot = add( tmp_nb_bits_tot, 5 ); /* Q0 */ - } - - gsc_dec_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, st_fx->Q_exc ); - /*--------------------------------------------------------------------------------------* - * iDCT transform - *--------------------------------------------------------------------------------------*/ - - edct_16fx( dct_epit, exc, st_fx->L_frame, 7, st_fx->element_mode ); - edct_16fx( exc_wo_nf, exc_wo_nf, st_fx->L_frame, 7, st_fx->element_mode ); - /*----------------------------------------------------------------------* - * Remove potential pre-echo in case an onset has been detected - *----------------------------------------------------------------------*/ - - pre_echo_att_fx( &hGSCDec->Last_frame_ener_fx, exc, gsc_attack_flag, st_fx->Q_exc, st_fx->last_coder_type, st_fx->L_frame ); - - /*--------------------------------------------------------------------------------------* - * Update BWE excitation - *--------------------------------------------------------------------------------------*/ - - IF( st_fx->hBWE_TD != NULL ) - { - set16_fx( voice_factors, 0, NB_SUBFR16k ); - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - interp_code_4over2_fx( exc, bwe_exc, st_fx->L_frame ); - } - ELSE - { - interp_code_5over2_fx( exc, bwe_exc, L_FRAME ); - } - } - /*--------------------------------------------------------------------------------------* - * Updates - *--------------------------------------------------------------------------------------*/ - - Copy( exc, exc2, st_fx->L_frame ); /* Q_exc */ - Copy( exc_wo_nf, exc, st_fx->L_frame ); /* Q_exc */ - - /*--------------------------------------------------------------------------------------* - * Channel aware mode parameters - *--------------------------------------------------------------------------------------*/ - - set16_fx( st_fx->tilt_code_dec_fx, 0, NB_SUBFR16k ); - - return; -} - -/*=========================================================================*/ -/* FUNCTION : void decod_audio_ivas_fx(); */ -/*-------------------------------------------------------------------------*/ -/* PURPOSE : Decode audio (AC) frames */ -/*-------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16[]) Aq : LP filter coefficient Q12 */ -/* _ (Word16) coder_type : coding type Q0 */ -/* _(Word16) Q_exc :Q format of excitation */ -/*-------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16[]) pitch_buf_fx : Word16 pitch values for each subframe Q6*/ -/* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Decoder_State *st_fx : decoder memory structure */ -/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ -/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*==========================================================================*/ -#endif -void decod_audio_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ - const Word16 *Aq, /* i : LP filter coefficient Q12*/ - Word16 *pitch_buf, /* o : Word16 pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors Q15*/ - Word16 *exc, /* i/o: adapt. excitation exc Q_exc*/ - Word16 *exc2, /* i/o: adapt. excitation/total exc Q_exc*/ - Word16 *bwe_exc, /* o : excitation for SWB TBE Q_exc*/ - Word16 *lsf_new /* i : ISFs at the end of the frame Qx*/ - , - Word16 *gain_buf, /*Q14*/ + Decoder_State *st_fx, /* i/o: decoder static memory */ + Word16 dct_epit[], /* o : GSC excitation in DCT domain Qx*/ + const Word16 *Aq, /* i : LP filter coefficient Q12*/ + Word16 *pitch_buf, /* o : Word16 pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *exc, /* i/o: adapt. excitation exc Q_exc*/ + Word16 *exc2, /* i/o: adapt. excitation/total exc Q_exc*/ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_exc*/ + Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ + Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/ const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag Q0*/ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag Q0*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ @@ -525,7 +103,7 @@ void decod_audio_ivas_fx( } /* set bit-allocation */ - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); + config_acelp1_fx( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /*---------------------------------------------------------------* * Decode energy dynamics @@ -735,7 +313,7 @@ void decod_audio_ivas_fx( Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); } - dec_pit_exc_ivas_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) { @@ -894,7 +472,7 @@ void decod_audio_ivas_fx( Word16 Q_exc_old = st_fx->Q_exc; move16(); - gsc_dec_ivas_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, &st_fx->Q_exc ); + gsc_dec_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, &st_fx->Q_exc ); IF( NE_16( Q_exc_old, st_fx->Q_exc ) ) { @@ -976,250 +554,17 @@ void decod_audio_ivas_fx( /* _None */ /*==========================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void gsc_dec_fx( - Decoder_State *st_fx, /* i/o: State structure */ - Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ - const Word16 pit_band_idx, /* i : bin position of the cut-off frequency Q0*/ - const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral) Q0*/ - const Word16 bits_used, /* i : Number of bit used before frequency Q Q0*/ - const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ - const Word16 coder_type, /* i : coding type Q0*/ - Word16 *last_bin, /* i : last bin of bit allocation Q0*/ - const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ - Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ - Word16 Q_exc ) -{ - Word16 i, j, bit, nb_subbands, pvq_len; - Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; - Word16 bitallocation_exc[2]; - Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k]; - Word16 max_ener_band[MBANDS_GN_BITALLOC16k]; - Word16 exc_diffQ[L_FRAME16k]; - Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; - Word16 concat_out[L_FRAME16k]; - Word16 inpulses_fx[NB_SFM]; - Word16 imaxpulse_fx[NB_SFM]; - Word16 mean_gain; - Word16 Mbands_gn = 16; - Word16 Qexc_diffQ = Q_PVQ_OUT; - Word32 L_tmp; - Word16 Q_tmp; - Word16 seed_init; - GSC_DEC_HANDLE hGSCDec; - hGSCDec = st_fx->hGSCDec; - move16(); - move16(); - - move16(); // for Mbands_gn - move16(); // for Qexc_diffQ - set16_fx( inpulses_fx, 0, NB_SFM ); - set16_fx( imaxpulse_fx, 0, NB_SFM ); - - /*--------------------------------------------------------------------------------------* - * Initialization - *--------------------------------------------------------------------------------------*/ - bit = bits_used; - move16(); - - set16_fx( exc_diffQ, 0, st_fx->L_frame ); - - /*--------------------------------------------------------------------------------------* - * Gain decoding - *--------------------------------------------------------------------------------------*/ - - test(); - IF( st_fx->bfi || st_fx->BER_detect ) - { - /* copy old gain */ - Copy( hGSCDec->old_y_gain_fx, Ener_per_bd_iQ, Mbands_gn ); /* Q_old_gain */ - mean_gain = mult_r( st_fx->lp_gainc_fx, 3277 ); /*Q3*/ - FOR( i = 0; i < Mbands_gn; i++ ) - { - Ener_per_bd_iQ[i] = add( Ener_per_bd_iQ[i], shl( mean_gain, 9 ) ); /*Q12*/ - move16(); - } - - st_fx->lp_gainc_fx = mult_r( st_fx->lp_gainc_fx, 32112 ); /*Q3*/ - move16(); - } - ELSE - { - mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q12 */ - - st_fx->lp_gainc_fx = mult_r( 640, mean_gain ); /*10 in Q6 x Q12 -> lp_gainc in Q3 */ - move16(); - } - - *last_bin = 0; - move16(); - test(); - IF( EQ_32( st_fx->core_brate, ACELP_8k00 ) && st_fx->bwidth != NB ) - { - bitallocation_exc[0] = 0; - move16(); - bitallocation_exc[1] = 0; - move16(); - } - - set16_fx( bitallocation_band, 0, MBANDS_GN ); - - test(); - IF( ( EQ_16( st_fx->bfi, 1 ) ) || st_fx->BER_detect ) - { - /*--------------------------------------------------------------------------------------* - * Copy old spectrum - * reduce spectral dynamic - * save spectrum - *--------------------------------------------------------------------------------------*/ - - test(); - IF( EQ_16( st_fx->last_good, INACTIVE_CLAS ) || EQ_16( st_fx->Last_GSC_noisy_speech_flag, 1 ) ) - { - FOR( i = 0; i < st_fx->L_frame; i++ ) - { - L_tmp = L_shr( L_mult( Random( &hGSCDec->seed_tcx ), 26214 ), 5 ); /*Q10*/ - L_tmp = L_mac( L_tmp, hGSCDec->Last_GSC_spectrum_fx[i], 6554 ); /* Q10 */ - hGSCDec->Last_GSC_spectrum_fx[i] = round_fx( L_tmp ); /*Q10*/ - move16(); - } - } - - Copy( hGSCDec->Last_GSC_spectrum_fx, exc_diffQ, st_fx->L_frame ); /* Q10 */ - - FOR( i = 0; i < st_fx->L_frame; i++ ) - { - hGSCDec->Last_GSC_spectrum_fx[i] = mult_r( hGSCDec->Last_GSC_spectrum_fx[i], 24576 ); /*Q10*/ - move16(); - } - } - ELSE - { - /*--------------------------------------------------------------------------------------* - * PVQ decoder - *--------------------------------------------------------------------------------------*/ - - bands_and_bit_alloc_fx( hGSCDec->cor_strong_limit, hGSCDec->noise_lev, st_fx->core_brate, Diff_len, bit, &bit, Ener_per_bd_iQ, - max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech, - st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); - - { - pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); - Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ - } - seed_init = 0; - move16(); - - /* Reorder Q bands */ - FOR( j = 0; j < nb_subbands; j++ ) - { - Copy( concat_out + shl( j, 4 ), exc_diffQ + shl( max_ener_band[j], 4 ), 16 ); /* Q_PVQ_OUT */ - - *last_bin = s_max( *last_bin, max_ener_band[j] ); /* Q0 */ - move16(); - - bitallocation_band[max_ener_band[j]] = 1; /* Q0 */ - move16(); - - seed_init = add( seed_init, inpulses_fx[j] ); /* Q0 */ - } - test(); - IF( NE_16( st_fx->last_coder_type, AUDIO ) /* First audio frame */ - && NE_16( st_fx->last_coder_type, UNVOICED ) ) /* last_coder_type == INACTIVE is overwritten in update_dec to UNVOICED */ - { - FOR( j = 0; j < nb_subbands * 16; j++ ) - { - IF( concat_out[j] > 0 ) - { - seed_init = extract_l( L_shl( seed_init, 3 ) ); /* Q0 */ - } - if ( concat_out[j] < 0 ) - { - seed_init = add( seed_init, 3 ); /* Q0 */ - move16(); - } - } - - hGSCDec->seed_tcx = seed_init; /* Q0 */ - move16(); - } - test(); - IF( EQ_32( st_fx->core_brate, ACELP_8k00 ) && st_fx->bwidth != NB ) - { - if ( exc_diffQ[L_FRAME8k - 2] != 0 ) - { - bitallocation_exc[0] = 1; /* Q0 */ - move16(); - } - - if ( exc_diffQ[L_FRAME8k - 1] != 0 ) - { - bitallocation_exc[1] = 1; /* Q0 */ - move16(); - } - } - - Copy( exc_diffQ, hGSCDec->Last_GSC_spectrum_fx, st_fx->L_frame ); /* Q_PVQ_OUT */ - - /*--------------------------------------------------------------------------------------* - * Skip adaptive (pitch) contribution frequency band (no noise added over the time contribution) - * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal - * Gain is based on the inter-correlation gain between the pulses found and residual signal - *--------------------------------------------------------------------------------------*/ - - freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); - } - - /*--------------------------------------------------------------------------------------* - * Estimate noise level - *--------------------------------------------------------------------------------------*/ - - highband_exc_dct_in_fx( st_fx->core_brate, mfreq_bindiv_loc, *last_bin, Diff_len, hGSCDec->noise_lev, pit_band_idx, exc_diffQ, - &hGSCDec->seed_tcx, Ener_per_bd_iQ, nb_subfr, exc_dct_in, st_fx->last_coder_type, bitallocation_band, lsf_new, - hGSCDec->last_exc_dct_in_fx, &hGSCDec->last_ener_fx, hGSCDec->last_bitallocation_band, bitallocation_exc, st_fx->bfi, coder_type, - st_fx->bwidth, exc_wo_nf, Qexc_diffQ, Q_exc, st_fx->GSC_noisy_speech, hGSCDec->lt_ener_per_band_fx, st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); - - exc_dct_in[0] = 0; - move16(); - - return; -} - -/*==========================================================================*/ -/* FUNCTION : void gsc_dec_ivas_fx () */ -/*--------------------------------------------------------------------------*/ -/* PURPOSE : Generic audio signal decoder */ -/*--------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word16) pit_band_idx : bin position of the cut-off frequency Q0 */ -/* _ (Word16) Diff_len : Lenght of the difference signal Q0 */ -/* _ (Word16) coder_type : coding type Q0 */ -/* _ (Word16) bits_used : Number of bit used before frequency Q Q0 */ -/* _ (Word16) nb_subfr : Number of subframe considered Q0 */ -/* _ (Word16) Qexc : Q format of exc_dct_in */ -/*--------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ None */ -/*--------------------------------------------------------------------------*/ -/* INPUT/OUTPUT ARGUMENTS : */ -/* Decoder_State *st_fx:Decoder State Structure */ -/* _ (Word16[]) exc_dct_in : dctof pitch-only excitation / total excitation Qexc*/ -/*--------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _None */ -/*==========================================================================*/ -#endif -void gsc_dec_ivas_fx( - Decoder_State *st_fx, /* i/o: State structure */ - Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ + Decoder_State *st_fx, /* i/o: State structure */ + Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation Q_exc*/ const Word16 pit_band_idx, /* i : bin position of the cut-off frequency ` Q0*/ const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral) Q0*/ const Word16 bits_used, /* i : Number of bit used before frequency Q Q0*/ const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ const Word16 coder_type, /* i : coding type Q0*/ Word16 *last_bin, /* i : last bin of bit allocation Q0*/ - const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ - Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ + const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx*/ + Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill Q_exc*/ Word16 *Q_exc ) { Word16 i, j, bit, nb_subbands, pvq_len; @@ -1310,13 +655,11 @@ void gsc_dec_ivas_fx( i--; } -#ifdef REMOVE_EVS_DUPLICATES IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ } ELSE -#endif { mean_gain = gsc_gaindec_ivas_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ } diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 03f0e4b40..cfbc1581a 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -520,7 +520,7 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, add( M, 1 ), sub( norm_s( sub( st->hFdCngDec->hFdCngCom->A_cng[0], 1 ) ), 3 ) ); // Qx } - IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = acelp_core_dec_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 10b8059b9..9c319489e 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2186,7 +2186,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); - FOR( Word16 i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { FOR( Word16 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { @@ -2195,7 +2195,7 @@ void ivas_dirac_dec_render_sf_fx( } } - FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { FOR( Word16 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 890e5fc9e..89cb92a4d 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -1097,8 +1097,8 @@ static void run_min_stats_fx( { arr_tmp = power_spec; } - ApplyFdCng_ivas_fx( NULL, 0, arr_tmp, power_spec_q, NULL, NULL, NULL, st, st->bfi, 0 ); - /*=================================================*/ + + ApplyFdCng_fx( NULL, 0, arr_tmp, power_spec_q, NULL, NULL, NULL, st, st->bfi, 0 ); } /* restore VAD (see above) */ diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index aa5a379e8..0be01f7b8 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -875,11 +875,11 @@ void stereo_tcx_core_dec_fx( { Word16 buffer[L_FRAME16k]; lerp( signal_outFB_fx, buffer, st->L_frame, hTcxDec->L_frameTCX ); - ApplyFdCng_ivas_fx( buffer, 0 /* Q of buffer */, NULL, 0, NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_fx( buffer, 0 /* Q of buffer */, NULL, 0, NULL, NULL, NULL, st, st->bfi, 0 ); } ELSE { - ApplyFdCng_ivas_fx( signal_out_fx, 0, NULL, 0, NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_fx( signal_out_fx, 0, NULL, 0, NULL, NULL, NULL, st, st->bfi, 0 ); } } @@ -915,7 +915,7 @@ void stereo_tcx_core_dec_fx( test(); IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && st->idchan == 0 ) { - ApplyFdCng_ivas_fx( signal_out_fx, 0, NULL, 0, NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_fx( signal_out_fx, 0, NULL, 0, NULL, NULL, NULL, st, st->bfi, 0 ); } } @@ -923,6 +923,7 @@ void stereo_tcx_core_dec_fx( return; } + static void stereo_tcx_dec_mode_switch_reconf_ivas_fx( Decoder_State *st, /* i/o: decoder state structure */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index 3191a8b4a..8f09c1c7d 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -127,7 +127,7 @@ void tdm_low_rate_dec_fx( tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ } - gsc_dec_ivas_fx( st, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st->coder_type, &last_bin, lsf_new, exc_wo_nf_fx, &st->Q_exc ); + gsc_dec_fx( st, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st->coder_type, &last_bin, lsf_new, exc_wo_nf_fx, &st->Q_exc ); /*--------------------------------------------------------------------------------------* * iDCT transform @@ -193,14 +193,9 @@ void tdm_low_rate_dec_fx( * * Decode generic (GC), 2 subframes mode *---------------------------------------------------------------------*/ -/*---------------------------------------------------------------------* - * decod_gen_2sbfr_ivas_fx() - * - * Decode generic (GC), 2 subframes mode - *---------------------------------------------------------------------*/ -void decod_gen_2sbfr_ivas_fx( - Decoder_State *st, /* i/o: decoder static memory */ +void decod_gen_2sbfr_fx( + Decoder_State *st, /* i/o: decoder static memory */ const Word16 sharpFlag, /* i : formant sharpening flag `Q0*/ const Word16 *Aq, /* i : LP filter coefficient Q12*/ Word16 *pitch_buf, /* o : Word16 pitch values for each subframe Q6*/ @@ -263,7 +258,7 @@ void decod_gen_2sbfr_ivas_fx( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch = pit_decode_ivas_fx( st, st->core_brate, 0, L_frame, i_subfr, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, 2 * L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /* Q6 */ + *pt_pitch = pit_decode_fx( st, st->core_brate, 0, L_frame, i_subfr, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, 2 * L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /* Q6 */ test(); test(); @@ -295,7 +290,7 @@ void decod_gen_2sbfr_ivas_fx( * Estimate spectrum tilt and voicing *--------------------------------------------------------------*/ - gain_dec_lbr_ivas_fx( st, GENERIC, i_subfr, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, gc_mem, gp_mem, 2 * L_SUBFR ); + gain_dec_lbr_fx( st, GENERIC, i_subfr, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, gc_mem, gp_mem, 2 * L_SUBFR ); st->tilt_code_fx = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, st->Q_exc, 2 * L_SUBFR, 0 ); /* Q15 */ move16(); @@ -312,10 +307,12 @@ void decod_gen_2sbfr_ivas_fx( Word16 gain_code16 = round_fx( L_shl( gain_code, st->Q_exc ) ); /*Q_exc*/ Acelp_dec_total_exc( exc, exc2, gain_code16, gain_pit, i_subfr, code, 2 * L_SUBFR ); + /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ - prep_tbe_exc_ivas_fx( L_frame, 2 * L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR /*i_subfr / L_SUBFR*/], bwe_exc, 0, NULL, st->Q_exc, T0, T0_frac, GENERIC, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); + + prep_tbe_exc_fx( L_frame, 2 * L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR /*i_subfr / L_SUBFR*/], bwe_exc, 0, NULL, st->Q_exc, T0, T0_frac, GENERIC, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR /*i_subfr / L_SUBFR*/]; /* Q15 */ move16(); @@ -323,6 +320,7 @@ void decod_gen_2sbfr_ivas_fx( * Excitation enhancements (update of total excitation signal) * called twice because adapting it to double the subfr length would need lot of modifications *----------------------------------------------------------------*/ + enhancer_ivas_fx2( st->core_brate, 0, GENERIC, i_subfr, L_frame, voice_fac, st->stab_fac_fx, norm_gain_code, gain_inov, &st->gc_threshold_fx, code, exc2, gain_pit, &st->dm_fx, st->Q_exc ); enhancer_ivas_fx2( st->core_brate, 0, GENERIC, i_subfr, L_frame, voice_fac, st->stab_fac_fx, norm_gain_code, gain_inov, &st->gc_threshold_fx, code + L_SUBFR, exc2 + L_SUBFR, gain_pit, &st->dm_fx, st->Q_exc ); diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index 9b7f77c79..913543db8 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -8,9 +8,11 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" + /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ + static void dqlsf_CNG_fx( Decoder_State *st_fx, Word16 *lsf_q ); /*--------------------------------------------------------------------------------------* @@ -88,7 +90,6 @@ static void dqlsf_CNG_fx( /* _ (Word16*) lsp_new : LP filter coefficient Q15 */ /* _ (Word16*) lsp_mid : LP filter coefficient Q15 */ /*---------------------------------------------------------------------------*/ - /* _ (Word16[]) st_fx->lsf_adaptive_mean_fx : FEC - adaptive mean LSF */ /* vector for FEC Q(x2.56) */ /* _ (Word16[]) st_fx->mem_AR_fx : AR memory of LSF quantizer */ @@ -99,271 +100,16 @@ static void dqlsf_CNG_fx( /* _ None */ /*===========================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES void lsf_dec_fx( - Decoder_State *st_fx, /* i/o: State structure */ - const Word16 tc_subfr, /* i : TC subframe index Q0*/ - Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ - Word16 *LSF_Q_prediction, /* o : LSF prediction mode Q0*/ - Word16 *lsf_new, /* o : de-quantized LSF vector Q(x2.56)*/ - Word16 *lsp_new, /* o : de-quantized LSP vector Q15*/ - Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector Q15*/ - const Word16 tdm_low_rate_mode /* i : secondary channel low rate mode flag Q0*/ - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ -) -{ - Word16 i; - Word16 no_param_lpc; - Word16 param_lpc[NPRM_LPC_NEW]; - Word32 L_tmp; - Word16 nBits = 0; - move16(); - Word16 tmp_old[M + 1], tmp_new[M + 1]; - Word16 enr_old = 0, enr_new = 0; - move16(); - move16(); - Word16 lsf_diff, coder_type; - - /* initialize */ - coder_type = st_fx->coder_type; - if ( EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - coder_type = INACTIVE; /* Q0 */ - move16(); - } - test(); - if ( EQ_16( coder_type, AUDIO ) && st_fx->GSC_IVAS_mode > 0 ) - { - coder_type = GENERIC; /* Q0 */ - move16(); - } - no_param_lpc = 0; - nBits = 0; - move16(); - move16(); - - /* Find the number of bits for LSF quantization */ - IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - nBits = LSF_BITS_CNG; /* Q0 */ - move16(); - } - ELSE - { - test(); - IF( st_fx->nelp_mode_dec == 0 && st_fx->ppp_mode_dec == 0 ) - { - nBits = st_fx->acelp_cfg.lsf_bits; /* Q0 */ - move16(); - } - ELSE IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) - { - IF( EQ_16( coder_type, UNVOICED ) ) - { - nBits = 30; /* Q0 */ - move16(); - if ( st_fx->bwidth == NB ) - { - nBits = 32; /* Q0 */ - move16(); - } - } - } - ELSE IF( EQ_16( st_fx->ppp_mode_dec, 1 ) ) - { - nBits = 26; /* Q0 */ - move16(); - } - } - - /* LSF de-quantization */ - lsf_end_dec_fx( st_fx, 0, coder_type, st_fx->bwidth, nBits, lsf_new, param_lpc, LSF_Q_prediction, &no_param_lpc, - tdm_lsfQ_PCh ); - - /* convert quantized LSFs to LSPs */ - - lsf2lsp_fx( lsf_new, lsp_new, M, st_fx->sr_core ); - /* set seed_acelp used in UC mode */ - test(); - IF( EQ_16( coder_type, UNVOICED ) && GT_16( st_fx->element_mode, EVS_MONO ) ) - { - st_fx->seed_acelp = 0; - move16(); - FOR( i = no_param_lpc - 1; i >= 0; i-- ) - { - /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ - st_fx->seed_acelp = extract_l( L_add( imult3216( 31821L /* Q0 */, add( shr( ( st_fx->seed_acelp ), 1 ), param_lpc[i] ) ), 13849L /* Q0 */ ) ); /* Q0 */ - move16(); - } - } - IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) - { - /* return if SID frame (conversion to A(z) done in the calling function) */ - return; - } - - /*-------------------------------------------------------------------------------------* - * FEC - update adaptive LSF mean vector - *-------------------------------------------------------------------------------------*/ - - FOR( i = 0; i < M; i++ ) - { - L_tmp = L_mult( lsf_new[i], 10922 ); /*Q(x2.56+16)*/ - L_tmp = L_mac( L_tmp, st_fx->lsfoldbfi1_fx[i], 10922 ); /*Q(x2.56+16)*/ - L_tmp = L_mac( L_tmp, st_fx->lsfoldbfi0_fx[i], 10922 ); /*Q(x2.56+16)*/ - st_fx->lsf_adaptive_mean_fx[i] = round_fx( L_tmp ); /*Q(x2.56)*/ - move16(); - } - - test(); - test(); - IF( ( st_fx->prev_bfi && ( EQ_16( coder_type, TRANSITION ) ) && ( EQ_16( tc_subfr, sub( st_fx->L_frame, L_SUBFR ) ) ) ) ) - { - lsf_diff = 1205; - move16(); /*int_fs / (float)(2*(M+1)); = 470.588 -> 1205 in Q2.56 */ - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - lsf_diff = 964; - move16(); /*int_fs / (float)(2*(M+1)); = 376.47 -> 964 in Q2.56 */ - } - st_fx->lsf_old_fx[0] = lsf_diff; - move16(); - - FOR( i = 1; i < M; i++ ) - { - st_fx->lsf_old_fx[i] = add( st_fx->lsf_old_fx[i - 1], lsf_diff ); /* Q2.56 */ - move16(); - } - lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, st_fx->sr_core ); - } - /*-------------------------------------------------------------------------------------* - * Mid-frame LSF decoding - * LSP interpolation and conversion of LSPs to A(z) - *-------------------------------------------------------------------------------------*/ - IF( st_fx->rate_switching_reset ) - { - /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st_fx->lsp_old_fx, M ); /* Q15 */ - Copy( lsf_new, st_fx->lsf_old_fx, M ); /* Q2.56 */ - } - { - /* Mid-frame LSF decoding */ - lsf_mid_dec_fx( st_fx, lsp_new, coder_type, lsp_mid ); - } - test(); - test(); - IF( !( st_fx->prev_bfi && ( EQ_16( coder_type, TRANSITION ) ) && ( EQ_16( tc_subfr, sub( st_fx->L_frame, L_SUBFR ) ) ) ) ) - { - IF( st_fx->prev_bfi ) - { - /* check, if LSP interpolation can be relaxed */ - E_LPC_f_lsp_a_conversion( st_fx->lsp_old_fx, tmp_old, M ); - enr_old = Enr_1_Az_fx( tmp_old, 2 * L_SUBFR ); /* Q3 */ - - E_LPC_f_lsp_a_conversion( lsp_new, tmp_new, M ); - enr_new = Enr_1_Az_fx( tmp_new, 2 * L_SUBFR ); /* Q3 */ - - IF( LT_16( enr_new, mult_r( 9830 /*0.3 Q15*/, enr_old ) ) ) - { - /* OLD CODE : if( st->safety_net == 1), replaced with a decision similar to MODE2 */ - st_fx->relax_prev_lsf_interp = -1; - move16(); - test(); - test(); - test(); - test(); - if ( st_fx->clas_dec == UNVOICED_CLAS || EQ_16( st_fx->clas_dec, SIN_ONSET ) || st_fx->clas_dec == INACTIVE_CLAS || EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) ) - { - st_fx->relax_prev_lsf_interp = 1; - move16(); - } - } - } - } - test(); - IF( EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->core == ACELP_CORE ) - { - /* update old LSPs/LSFs in case of HQ->ACELP core switching */ - Copy( lsp_mid, st_fx->lsp_old_fx, M ); /* Q15 */ - lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, st_fx->sr_core ); /* Q15 */ - } - test(); - IF( EQ_16( tdm_low_rate_mode, 1 ) && GT_16( coder_type, UNVOICED ) ) - { - // PMT("To be verified") - IF( EQ_16( st_fx->active_cnt, 1 ) ) - { - Copy( lsp_mid, st_fx->lsp_old_fx, M ); /* Q15 */ - lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, st_fx->sr_core ); /* Q15 */ - Copy( lsp_new, lsp_mid, M ); /* Q15 */ - } - - /* LSP interpolation and conversion of LSPs to A(z) - two-subframe mode */ - int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, -2 ); - } - ELSE - { - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, st_fx->relax_prev_lsf_interp ); - } - /*------------------------------------------------------------------* - * Check LSF stability (distance between old LSFs and current LSFs) - *------------------------------------------------------------------*/ - - IF( st_fx->element_mode == EVS_MONO ) - { - st_fx->stab_fac_fx = lsf_stab_fx( lsf_new, st_fx->lsf_old_fx, 0, st_fx->L_frame ); /*Q15*/ - move16(); - } - ELSE - { - st_fx->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st_fx->lsf_old_fx, 0, st_fx->L_frame ); /* Q15 */ - move16(); - } - - return; -} - -/*===========================================================================*/ -/* FUNCTION : lsf_dec_ivas_fx() */ -/*---------------------------------------------------------------------------*/ -/* PURPOSE : LSF decoder */ -/*---------------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Struct) st_fx : decoder static memory */ -/* _ (Word16) L_frame : length of the frame */ -/* _ (Word16) coder_type : coding type */ -/* _ (Word16) bwidth : input signal bandwidth */ -/*---------------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16*) Aq : LP filter coefficient Q12 */ -/* _ (Word16*) lsf_new : LP filter coefficient Q(x2.56) */ -/* _ (Word16*) lsp_new : LP filter coefficient Q15 */ -/* _ (Word16*) lsp_mid : LP filter coefficient Q15 */ -/*---------------------------------------------------------------------------*/ - -/* _ (Word16[]) st_fx->lsf_adaptive_mean_fx : FEC - adaptive mean LSF */ -/* vector for FEC Q(x2.56) */ -/* _ (Word16[]) st_fx->mem_AR_fx : AR memory of LSF quantizer */ -/* (past quantized LSFs without mean) Q(x2.56) */ -/* _ (Word16) st_fx->stab_fac_fx : LSF stability factor Q15 */ -/*---------------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ None */ -/*===========================================================================*/ -#endif -void lsf_dec_ivas_fx( - Decoder_State *st_fx, /* i/o: State structure */ - const Word16 tc_subfr, /* i : TC subframe index Q0*/ - Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ - Word16 *LSF_Q_prediction, /* o : LSF prediction mode Q0*/ - Word16 *lsf_new, /* o : de-quantized LSF vector Q(x2.56)*/ - Word16 *lsp_new, /* o : de-quantized LSP vector Q15*/ - Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector Q15*/ - const Word16 tdm_low_rate_mode /* i : secondary channel low rate mode flag Q0*/ - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ + Decoder_State *st_fx, /* i/o: State structure */ + const Word16 tc_subfr, /* i : TC subframe index Q0*/ + Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ + Word16 *LSF_Q_prediction, /* o : LSF prediction mode Q0*/ + Word16 *lsf_new, /* o : de-quantized LSF vector Q(x2.56)*/ + Word16 *lsp_new, /* o : de-quantized LSP vector Q15*/ + Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector Q15*/ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag Q0*/ + const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel Qx*/ ) { Word16 i; diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c index e8cebedbd..38ec41cb2 100644 --- a/lib_dec/pit_dec_fx.c +++ b/lib_dec/pit_dec_fx.c @@ -319,246 +319,22 @@ void Mode2_delta_pit_dec( /* _ (Word16 ) pitch : close loop integer pitch Q6 */ /*=======================================================================*/ -#ifndef REMOVE_EVS_DUPLICATES -Word16 pit_decode_fx( /* o : floating pitch value */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - Word16 *T0, /* o : close loop integer pitch */ - Word16 *T0_frac, /* o : close loop fractional part of the pitch */ - Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ - Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const Word16 L_subfr /* i : subframe length */ -) -{ - Word16 pitch; /*Q2*/ - Word16 pitch_index, nBits, pit_flag; - - pitch_index = 0; - move16(); - - /*----------------------------------------------------------------* - * Set pit_flag = 0 for every subframe with absolute pitch search - *----------------------------------------------------------------*/ - pit_flag = i_subfr; - move16(); - - if ( EQ_16( i_subfr, PIT_DECODE_2XL_SUBFR ) ) - { - pit_flag = 0; - move16(); - } - - /*-------------------------------------------------------* - * Retrieve the pitch index - *-------------------------------------------------------*/ - IF( !Opt_AMR_WB ) - { - /*----------------------------------------------------------------* - * pitch Q: Set limit_flag to 0 for restrained limits, and 1 for extended limits - *----------------------------------------------------------------*/ - test(); - test(); - IF( i_subfr == 0 ) - { - *limit_flag = 1; - move16(); - - if ( EQ_16( coder_type, VOICED ) ) - { - *limit_flag = 2; - move16(); /* double-extended limits */ - } - test(); - if ( EQ_16( coder_type, GENERIC ) && EQ_32( core_brate, ACELP_7k20 ) ) - { - *limit_flag = 0; - move16(); - } - } - ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) && EQ_32( coder_type, GENERIC ) && LE_32( core_brate, ACELP_13k20 ) ) - { - if ( GT_16( *T0, shr( add( PIT_FR1_EXTEND_8b, PIT_MIN ), 1 ) ) ) - { - *limit_flag = 0; - move16(); - } - } - - /*-------------------------------------------------------* - * Retrieve the number of Q bits - *-------------------------------------------------------*/ - - nBits = 0; - move16(); - IF( NE_16( coder_type, AUDIO ) ) - { - /* find the number of bits */ - nBits = st_fx->acelp_cfg.pitch_bits[shr( i_subfr, 6 )]; - move16(); - pitch_index = (Word16) get_next_indice_fx( st_fx, nBits ); - } - - /*-------------------------------------------------------* - * Pitch decoding in AUDIO mode - * (both ACELP@12k8 and ACELP@16k cores) - *-------------------------------------------------------*/ - IF( EQ_16( coder_type, AUDIO ) ) - { - test(); - if ( EQ_16( L_subfr, L_FRAME / 2 ) && i_subfr != 0 ) - { - pit_flag = L_SUBFR; - move16(); - } - if ( pit_flag == 0 ) - { - nBits = 10; - move16(); - } - if ( pit_flag != 0 ) - { - nBits = 6; - move16(); - } - - pitch_index = (Word16) get_next_indice_fx( st_fx, nBits ); - - test(); - test(); - IF( EQ_16( L_subfr, L_FRAME / 2 ) && i_subfr != 0 && GE_16( pitch_index, 32 ) ) /* safety check in case of bit errors */ - { - pitch_index = shr( pitch_index, 1 ); - st_fx->BER_detect = 1; - move16(); - } - - pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - ELSE IF( EQ_16( coder_type, VOICED ) ) - { - /*-------------------------------------------------------* - * Pitch decoding in VOICED mode - * (ACELP@12k8 core only) - *-------------------------------------------------------*/ - if ( EQ_16( i_subfr, 2 * L_SUBFR ) ) - { - pit_flag = i_subfr; - move16(); - } - - pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - ELSE - { - /*-------------------------------------------------------* - * Pitch decoding in GENERIC mode - * (both ACELP@12k8 and ACELP@16k cores) - *-------------------------------------------------------*/ - IF( EQ_16( L_frame, L_FRAME ) ) - { - pit_Q_dec_fx( 0, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - ELSE - { - pit16k_Q_dec_fx( pitch_index, nBits, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - } - } - - /*-------------------------------------------------------* - * Pitch decoding in AMR-WB IO mode - *-------------------------------------------------------*/ - - ELSE - { - *limit_flag = 0; - move16(); - test(); - test(); - IF( i_subfr == 0 || ( EQ_16( i_subfr, 2 * L_SUBFR ) && EQ_32( core_brate, ACELP_8k85 ) ) ) - { - nBits = 8; - move16(); - } - ELSE - { - nBits = 5; - move16(); - } - IF( GT_32( core_brate, ACELP_8k85 ) ) - { - nBits = 6; - move16(); - test(); - if ( i_subfr == 0 || EQ_16( i_subfr, 2 * L_SUBFR ) ) - { - nBits = 9; - move16(); - } - } - - pitch_index = (Word16) get_next_indice_fx( st_fx, nBits ); - - pit_Q_dec_fx( 1, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - - /*-------------------------------------------------------* - * Compute floating pitch output - *-------------------------------------------------------*/ - - pitch = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); /* save subframe pitch values Q6 */ - - return pitch; -} - -/*======================================================================*/ -/* FUNCTION : pit_decode_ivas_fx() */ -/*-----------------------------------------------------------------------*/ -/* PURPOSE : calculate pitch value */ -/* */ -/*-----------------------------------------------------------------------*/ -/* INPUT ARGUMENTS : */ -/* _ (Word32) core_brate : Core bitrate Q0 */ -/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode Q0 */ -/* _ (Word16) L_frame : length of the frame Q0 */ -/* _ (Word16) i_subfr : length of the frame Q0 */ -/* _ (Word16) coder_type : coding type Q0 */ -/* _ (Word16) L_subfr : subframe length */ -/*-----------------------------------------------------------------------*/ -/* OUTPUT ARGUMENTS : */ -/* _ (Word16 *) T0 : close loop integer pitch */ -/* _ (Word16 *) T0_frac : close loop fractional part of the pitch */ -/* _ (Word16 ) pitch : pitch value Q6 */ -/*-----------------------------------------------------------------------*/ -/* INPUT OUTPUT ARGUMENTS */ -/* _ (Word16 *) T0_min : delta search min for sf 2 & 4 */ -/* _ (Word16 *) T0_max : delta search max for sf 2 & 4 */ -/*-----------------------------------------------------------------------*/ -/* RETURN ARGUMENTS : */ -/* _ (Word16 ) pitch : close loop integer pitch Q6 */ -/*=======================================================================*/ - -#endif -Word16 pit_decode_ivas_fx( /* o : floating pitch value */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - Word16 *T0, /* o : close loop integer pitch */ - Word16 *T0_frac, /* o : close loop fractional part of the pitch */ - Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ - Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ +/*! r: floating pitch value */ +Word16 pit_decode_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ ) { Word16 pitch; /*Q2*/ diff --git a/lib_dec/post_dec_fx.c b/lib_dec/post_dec_fx.c index b5d56d8fb..cbcb225bc 100644 --- a/lib_dec/post_dec_fx.c +++ b/lib_dec/post_dec_fx.c @@ -139,21 +139,13 @@ void post_decoder( { st->hPFstat->on = 1; move16(); -#ifdef REMOVE_EVS_DUPLICATES - formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); -#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); -#endif } ELSE { st->hPFstat->on = 0; move16(); -#ifdef REMOVE_EVS_DUPLICATES - formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); -#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); -#endif } } @@ -176,10 +168,10 @@ void post_decoder( /* Update synth2 memory */ Copy( synth_buf2 + L_frame, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX ); - return; } + void post_decoder_ivas_fx( Decoder_State *st, Word16 synth_buf[], // Q0 @@ -310,21 +302,13 @@ void post_decoder_ivas_fx( { st->hPFstat->on = 1; move16(); -#ifdef REMOVE_EVS_DUPLICATES - formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); -#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); -#endif } ELSE { st->hPFstat->on = 0; move16(); -#ifdef REMOVE_EVS_DUPLICATES - formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); -#else formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); -#endif } } diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 4c3f7152c..ceba860a1 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -394,14 +394,10 @@ ivas_error acelp_core_enc_fx( test(); IF( !nelp_mode && !ppp_mode ) { -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#endif - st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, - tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, - tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, + tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, + tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } /*-----------------------------------------------------------------* @@ -464,19 +460,16 @@ ivas_error acelp_core_enc_fx( { tc_classif_enc_fx( Q_new, st_fx->L_frame, &tc_subfr_fx, &position, attack_flag, st_fx->pitch[0], res_fx ); -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#endif - -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, - tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, + tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } /*---------------------------------------------------------------* * Calculation of prediction for scaled innovation energy * (for memory-less gain quantizer) *---------------------------------------------------------------*/ + IF( nb_bits > 0 ) { Es_pred_enc_fx( &Es_pred_fx, &indice, st_fx->L_frame, res_fx, st_fx->voicing_fx, nb_bits, 0, Q_new ); @@ -521,13 +514,9 @@ ivas_error acelp_core_enc_fx( lsp_mid_bck_fx, mCb1_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen_fx ); /* Configure ACELP bit allocation */ -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, -#endif - -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, - st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, + st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /* redo LSF quantization */ lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, Q_new ); @@ -1185,7 +1174,7 @@ ivas_error acelp_core_enc_ivas_fx( test(); IF( !nelp_mode && !ppp_mode ) { - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_fx( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } /*-----------------------------------------------------------------* @@ -1322,7 +1311,7 @@ ivas_error acelp_core_enc_ivas_fx( { tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_fx( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } /*---------------------------------------------------------------* @@ -1381,7 +1370,7 @@ ivas_error acelp_core_enc_ivas_fx( lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); /* Configure ACELP bit allocation */ - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_fx( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); /* redo LSF quantization */ lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL, Q_new ); @@ -1390,6 +1379,7 @@ ivas_error acelp_core_enc_ivas_fx( calc_residu_fx( st, inp, res_fx, Aq ); st->hTdCngEnc->burst_ho_cnt = 0; move16(); + /* VOICED frames in SC-VBR */ encod_gen_voic_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, 0, Q_new ); } diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 854f0ff67..52f5d4010 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -11,32 +11,17 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ + /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ -static void encod_gen_voic_core_switch_fx( Encoder_State *st_fx, - const Word16 L_frame_fx, - const Word16 inp_fx[], - const Word16 Aq_fx[], - const Word16 A_fx[], - const Word16 T_op[], - Word16 *exc_fx, - const Word32 core_bitrate_fx, - Word16 shift, - Word16 Q_new ); -static void encod_gen_voic_core_switch_ivas_fx( Encoder_State *st_fx, - const Word16 L_frame_fx, - const Word16 inp_fx[], - const Word16 Aq_fx[], - const Word16 A_fx[], - const Word16 T_op[], - Word16 *exc_fx, - const Word32 core_bitrate_fx, - Word16 shift, - Word16 Q_new ); +static void encod_gen_voic_core_switch_fx( Encoder_State *st_fx, const Word16 L_frame_fx, const Word16 inp_fx[], const Word16 Aq_fx[], const Word16 A_fx[], const Word16 T_op[], Word16 *exc_fx, const Word32 core_bitrate_fx, Word16 shift, Word16 Q_new ); + +static void encod_gen_voic_core_switch_ivas_fx( Encoder_State *st_fx, const Word16 L_frame_fx, const Word16 inp_fx[], const Word16 Aq_fx[], const Word16 A_fx[], const Word16 T_op[], Word16 *exc_fx, const Word32 core_bitrate_fx, Word16 shift, Word16 Q_new ); static void bwe_switch_enc_fx( Encoder_State *st_fx, const Word16 *new_speech ); + static void bwe_switch_enc_ivas_fx( Encoder_State *st_fx, const Word16 *new_speech ); static Word16 dotprod_satcont( const Word16 *x, const Word16 *y, Word16 qx, Word16 qy, Word16 *qo, Word16 len, Word16 delta ); @@ -151,12 +136,8 @@ void acelp_core_switch_enc_fx( * Excitation encoding *----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, -#else - config_acelp1( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, -#endif - GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); + config_acelp1_fx( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, + GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); @@ -279,8 +260,8 @@ void acelp_core_switch_enc_ivas_fx( * Excitation encoding *----------------------------------------------------------------*/ - config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, - GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); + config_acelp1_fx( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, + GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); encod_gen_voic_core_switch_ivas_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); diff --git a/lib_enc/analy_lp_fx.c b/lib_enc/analy_lp_fx.c index 78a02eeec..9b6ff2108 100644 --- a/lib_enc/analy_lp_fx.c +++ b/lib_enc/analy_lp_fx.c @@ -3,17 +3,16 @@ ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -#include "rom_enc.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_enc.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* - * analy_lp() + * analy_lp_fx() * * Perform LP analysis * @@ -23,26 +22,26 @@ * - find interpolated LSPs and convert back to A(z) for all subframes * - update LSPs for the next frame *-------------------------------------------------------------------*/ -void analy_lp_ivas_fx( - const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ - const Word16 L_frame, /* i :(q0) length of the frame */ - const Word16 L_look, /* i :(q0) look-ahead */ - Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ - Word16 A[], /* o :(q14) A(z) filter coefficients */ - Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 lsp_new[], /* o :(q15) current frame LSPs */ - Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ - Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ - const Word16 Top[2], /* i :(q0) open loop pitch lag */ - const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ - const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ -#ifdef REMOVE_EVS_DUPLICATES - const Word16 element_mode, /* i : element mode */ -#endif - const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ - Word16 Q_new, /*i: stores Q for speech*/ - Word16 *Q_r /*stores q for ener*/ ) + +void analy_lp_fx( + const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ + const Word16 L_frame, /* i :(q0) length of the frame */ + const Word16 L_look, /* i :(q0) look-ahead */ + Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ + Word16 A[], /* o :(q14) A(z) filter coefficients */ + Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 lsp_new[], /* o :(q15) current frame LSPs */ + Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ + Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ + const Word16 Top[2], /* i :(q0) open loop pitch lag */ + const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ + const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ + const Word16 element_mode, /* i : element mode */ + const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ + Word16 Q_new, /* i : stores Q for speech */ + Word16 *Q_r /*stores q for ener*/ +) { Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */ Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */ @@ -77,9 +76,7 @@ void analy_lp_ivas_fx( /* Autocorrelations */ autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 ); -#ifdef REMOVE_EVS_DUPLICATES IF( NE_16( element_mode, EVS_MONO ) ) -#endif { /*if ( r[0] < 100.0f && no_thr == 0 )*/ /*r[0] = 100.0f*/ @@ -132,101 +129,6 @@ void analy_lp_ivas_fx( return; } -#ifndef REMOVE_EVS_DUPLICATES -void analy_lp_fx( - const Word16 speech[], /* i : pointer to the speech frame Q_new*/ - const Word16 L_frame, /* i : length of the frame Q0*/ - const Word16 L_look, /* i : look-ahead Q0*/ - Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/ - Word16 A[], /* o : A(z) filter coefficients Q14*/ - Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/ - Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/ - Word16 lsp_new[], /* o : current frame LSPs Q15*/ - Word16 lsp_mid[], /* o : current mid-frame LSPs Q15*/ - Word16 lsp_old[], /* i/o: previous frame unquantized LSPs Q15*/ - const Word16 Top[2], /* i : open loop pitch lag Q0*/ - const Word16 Tnc[2], /* i : open loop pitch gain Q15*/ - const Word32 Core_sr, /* i : Internal core sampling rate Q0*/ - const Word16 sec_chan_low_rate, /* i : flag to signal second channel Q0*/ - Word16 Q_new, - Word16 *Q_r ) -{ - Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */ - Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */ - Word32 LepsP[M + 1]; - Word16 i, i_subfr, wind_length = 0; - Word16 *lsp; - const Word16 *wind = NULL; - const Word16 *pt; - Word16 half_frame; - - IF( EQ_16( L_frame, L_FRAME ) ) - { - wind_length = L_LP; - move16(); - wind = Assym_window_W16fx; /* Q15 */ - } - ELSE /* L_frame == L_FRAME16k */ - { - wind_length = L_LP_16k; - move16(); - wind = assym_window_16k_fx; /* Q15 */ - } - lsp = lsp_mid; /* Q15 */ - half_frame = shr( L_frame, 1 ); - - FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) - { - pt = speech + sub( add( half_frame, L_look ), wind_length ); - half_frame = shl( half_frame, 1 ); - - /* Autocorrelations */ - autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 ); - - /* Lag windowing */ - adapt_lag_wind( r_h, r_l, M, Top[i_subfr], Tnc[i_subfr], Core_sr ); - - /* Levinson-Durbin */ - E_LPC_lev_dur( r_h, r_l, A, LepsP, M, NULL ); - FOR( i = 0; i <= M; i++ ) - { - L_Extract( LepsP[i], &epsP_h[i], &epsP_l[i] ); - } - /*Q_r[... might not be needed from external...*/ - Q_r[1 - i_subfr] = add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ); - move16(); - - /* Conversion of A(z) to LSPs */ - E_LPC_a_lsp_conversion( A, lsp, lsp_old, M ); - - lsp = lsp_new; /* Q15 */ - } - IF( EQ_16( sec_chan_low_rate, 1 ) ) - { - /* LSP interpolation */ -#ifdef REMOVE_EVS_DUPLICATES - int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 ); -#else - int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 ); -#endif - } - ELSE - { - /* LSP interpolation */ -#ifdef REMOVE_EVS_DUPLICATES - int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); -#else - int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); -#endif - } - Copy( lsp_new, lsp_old, M ); /* Q15 */ - *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */ - move32(); - - return; -} -#endif - /*-------------------------------------------------------------------* * analy_lp_AMR_WB() * diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index b5c18d44b..e1914aeb5 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -366,14 +366,9 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * IF( st->igf != 0 ) { -#ifdef REMOVE_EVS_DUPLICATES - prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], - bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate, - st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); -#else - prep_tbe_exc_fx( L_frame, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], - bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate ); -#endif + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate, + st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); } /*---------------------------------------------------------* diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index a60828a94..87bba1fae 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -363,20 +363,15 @@ void encod_gen_voic_fx( exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); /* Q0 */ } } + /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, - &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, - T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, - st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); -#else - prep_tbe_exc_fx( L_frame, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, - T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate ); -#endif + T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. @@ -405,9 +400,11 @@ void encod_gen_voic_fx( hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); } + return; } + void encod_gen_voic_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 speech_fx[], /* i : input speech Qnew -1 */ @@ -763,10 +760,10 @@ void encod_gen_voic_ivas_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ - prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, - &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, - T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, - st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, + T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 394b22c30..eba991f57 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -308,13 +308,8 @@ Word16 encod_tran_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ -#ifdef REMOVE_EVS_DUPLICATES - prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], - bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); -#else - prep_tbe_exc_fx( L_frame_fx, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], - bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate ); -#endif + prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. @@ -717,9 +712,9 @@ Word16 encod_tran_ivas_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ - prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], - bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, - st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); + prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 67c4f256f..5f4a5dd60 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1150,12 +1150,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } -#ifdef REMOVE_EVS_DUPLICATES - analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, element_mode, i, *Q_new, Q_r ); -#else - analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, - INT_FS_12k8, i, *Q_new, Q_r ); -#endif + analy_lp_fx( inp_12k8_fx, L_FRAME, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, element_mode, i, *Q_new, Q_r ); FOR( Word16 idx = 0; idx < M + 1; idx++ ) { diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 6fe6b6720..4fcb9e1ec 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -1134,20 +1134,11 @@ ivas_error ivas_compute_core_buffers_fx( IF( Q_new ) { -#ifdef REMOVE_EVS_DUPLICATES - analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, sub( *Q_new, 1 ), Q_r ); -#else - analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, sub( *Q_new, 1 ), Q_r ); -#endif + analy_lp_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, sub( *Q_new, 1 ), Q_r ); } ELSE { -#ifdef REMOVE_EVS_DUPLICATES - analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, -1, Q_r ); - -#else - analy_lp_ivas_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, -1, Q_r ); -#endif + analy_lp_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, element_mode, 0, -1, Q_r ); } /*--------------------------------------------------------------* diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index f3cf05e63..9e2e1402e 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -637,11 +637,7 @@ ivas_error front_vad_spar_fx( hFrontVad->q_buffer_12k8 = Q_inp_12k8; move16(); -#ifdef REMOVE_EVS_DUPLICATES - analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, st->element_mode, 0, Q_inp_12k8, Q_r ); -#else - analy_lp_ivas_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, 0 /* <-- sec_chan_low_rate */, Q_inp_12k8, Q_r ); -#endif + analy_lp_fx( inp_12k8_fx, L_FRAME, L_LOOK_12k8, &res_energy_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing_fx, INT_FS_12k8, st->element_mode, 0, Q_inp_12k8, Q_r ); FOR( Word16 i = 0; i <= M; i++ ) { diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 77ddb35aa..d10527a24 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -365,11 +365,12 @@ void encod_gen_2sbfr( move16(); move16(); } + /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ - prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; /* Q15 */ move16(); @@ -378,6 +379,7 @@ void encod_gen_2sbfr( * Synthesize speech to update mem_syn_flt[]. * Update A(z) filters *-----------------------------------------------------------------*/ + Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); p_Aw += 2 * ( M + 1 ); p_Aq += 2 * ( M + 1 ); diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 8fe425d74..b26532b15 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -289,13 +289,16 @@ void lsf_enc_fx( { int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, 0 ); } + /*------------------------------------------------------------------* * Check LSF stability (distance between old LSFs and current LSFs) *------------------------------------------------------------------*/ + IF( NE_32( st_fx->core_brate, SID_2k40 ) ) { st_fx->stab_fac_fx = lsf_stab_fx( lsf_new, st_fx->lsf_old_fx, 0, st_fx->L_frame ); } + return; } @@ -1982,7 +1985,7 @@ static void first_VQstages( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ @@ -2172,7 +2175,7 @@ static void first_VQstages_ivas_fx( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index e8d4a0722..cc8b64ca4 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -213,7 +213,7 @@ void pre_proc_fx( /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ) ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ) ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* @@ -414,11 +414,7 @@ void pre_proc_fx( alw_voicing[1] = st->voicing_fx[2]; move16(); -#ifdef REMOVE_EVS_DUPLICATES - analy_lp_ivas_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, EVS_MONO, 0, *Q_new, Q_r ); -#else - analy_lp_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, -1 /*IVAS_CODE !! LowRateFlag*/, *Q_new, Q_r ); -#endif + analy_lp_fx( inp_12k8, L_FRAME, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lsp_old1_fx, alw_pitch_lag_12k8, alw_voicing, INT_FS_12k8, EVS_MONO, 0, *Q_new, Q_r ); lsp2lsf_fx( lsp_new, lsf_new, M, INT_FS_12k8 ); stab_fac = lsf_stab_fx( lsf_new, st->lsf_old1_fx, 0, L_FRAME ); @@ -1131,11 +1127,7 @@ void pre_proc_fx( Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); } -#ifdef REMOVE_EVS_DUPLICATES - analy_lp_ivas_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, EVS_MONO, 0, *Q_new, Q_r ); -#else - analy_lp_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, -1 /*IVAS_CODE !! LowRateFlag*/, *Q_new, Q_r ); -#endif + analy_lp_fx( inp_16k, L_FRAME16k, L_look, ener, A, epsP_h, epsP_l, lsp_new, lsp_mid, st->lspold_enc_fx, st->pitch, st->voicing_fx, 16000, EVS_MONO, 0, *Q_new, Q_r ); /*--------------------------------------------------------------* * Compute Weighted Input diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index d9389eb9c..9eb43c82b 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -41,9 +41,8 @@ #include "ivas_error_utils.h" #include "complex_basop.h" #include "ivas_stat_enc.h" -/*----------------------------------------------------------------------------------* - * Prototypes of RAM counting tool macros - *----------------------------------------------------------------------------------*/ + + ivas_error acelp_core_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 inp_fx[], /* i : input signal of the current frame Q_new*/ @@ -68,57 +67,37 @@ ivas_error acelp_core_enc_fx( ); -void analy_lp_ivas_fx( - const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ - const Word16 L_frame, /* i :(q0) length of the frame */ - const Word16 L_look, /* i :(q0) look-ahead */ - Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ - Word16 A[], /* o :(q14) A(z) filter coefficients */ - Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ - Word16 lsp_new[], /* o :(q15) current frame LSPs */ - Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ - Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ - const Word16 Top[2], /* i :(q0) open loop pitch lag */ - const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ - const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ -#ifdef REMOVE_EVS_DUPLICATES - const Word16 element_mode, /* i : element mode */ -#endif - const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ - Word16 Q_new, /*i: stores Q for speech*/ - Word16 *Q_r /*stores q for ener*/ ); - -#ifndef REMOVE_EVS_DUPLICATES void analy_lp_fx( - const Word16 speech[], /* i : pointer to the speech frame Q_new*/ - const Word16 L_frame, /* i : length of the frame Q0*/ - const Word16 L_look, /* i : look-ahead Q0*/ - Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/ - Word16 A[], /* o : A(z) filter coefficients Q14*/ - Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/ - Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/ - Word16 lsp_new[], /* o : current frame LSPs Q15*/ - Word16 lsp_mid[], /* o : current mid-frame LSPs Q15*/ - Word16 lsp_old[], /* i/o: previous frame unquantized LSPs Q15*/ - const Word16 Top[2], /* i : open loop pitch lag Q0*/ - const Word16 Tnc[2], /* i : open loop pitch gain Q15*/ - const Word32 Core_sr, /* i : Internal core sampling rate Q0*/ - const Word16 sec_chan_low_rate, /* i : flag to signal second channel Q0*/ - Word16 Q_new, - Word16 *Q_r ); -#endif - -void AVQ_cod_fx( /* o: comfort noise gain factor */ - const Word16 xri[], /* i: vector to quantize */ - Word16 xriq[], /* o: quantized normalized vector (assuming the bit budget is enough) */ - const Word16 NB_BITS, /* i: number of allocated bits */ - const Word16 Nsv, /* i: number of subvectors (lg=Nsv*8) */ - const Word16 Q_in_ref /* i: Scaling i */ + const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ + const Word16 L_frame, /* i :(q0) length of the frame */ + const Word16 L_look, /* i :(q0) look-ahead */ + Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */ + Word16 A[], /* o :(q14) A(z) filter coefficients */ + Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */ + Word16 lsp_new[], /* o :(q15) current frame LSPs */ + Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */ + Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */ + const Word16 Top[2], /* i :(q0) open loop pitch lag */ + const Word16 Tnc[2], /* i :(q15) open loop pitch gain */ + const Word32 Core_sr, /* i :(q0) Internal core sampling rate */ + const Word16 element_mode, /* i : element mode */ + const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */ + Word16 Q_new, /* i : stores Q for speech */ + Word16 *Q_r /*stores q for ener*/ +); + +/*1 r: comfort noise gain factor */ +void AVQ_cod_fx( + const Word16 xri[], /* i: vector to quantize */ + Word16 xriq[], /* o: quantized normalized vector (assuming the bit budget is enough) */ + const Word16 NB_BITS, /* i: number of allocated bits */ + const Word16 Nsv, /* i: number of subvectors (lg=Nsv*8) */ + const Word16 Q_in_ref /* i: Scaling i */ ); void AVQ_encmux_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ const Word16 extl, /* i : extension layer */ Word16 xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ @@ -130,7 +109,7 @@ void AVQ_encmux_fx( ); void AVQ_encmux_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ const Word16 extl, /* i : extension layer */ Word16 xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ @@ -151,15 +130,15 @@ void bw_detect_fx( const Word16 mct_on, /* i : flag MCT mode */ const Word16 Q_spec ); -void core_switching_post_enc_fx( /*done */ - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 inp12k8[], /* i : i signal @12.8 kHz Qinp*/ - const Word16 inp16k[], /* i : i signal @16 kHz Qinp*/ - const Word16 A[], /* i : unquant. LP filter coefs. (Q12) */ - Word16 Qshift, - Word16 Q_new, - const Word16 Qsp, /* i/o : Q from acelp synthsis */ - Word16 *Qmus /* i/o : Q from mdct synthsis / Q of output synthesis */ +void core_switching_post_enc_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 inp12k8[], /* i : i signal @12.8 kHz Qinp*/ + const Word16 inp16k[], /* i : i signal @16 kHz Qinp*/ + const Word16 A[], /* i : unquant. LP filter coefs. (Q12) */ + Word16 Qshift, + Word16 Q_new, + const Word16 Qsp, /* i/o : Q from acelp synthsis */ + Word16 *Qmus /* i/o : Q from mdct synthsis / Q of output synthesis */ ); void core_switching_pre_enc_fx( @@ -170,8 +149,9 @@ void core_switching_pre_enc_fx( const Word16 last_element_mode /* i : last_element_mode Q0*/ ); -Word16 correlation_shift_fx( /* o : noise dependent voicing correction Q15 */ - const Word16 totalNoise_fx /* i/o: noise estimate over all critical bands Q8 */ +/*! r: noise dependent voicing correction Q15 */ +Word16 correlation_shift_fx( + const Word16 totalNoise_fx /* i/o: noise estimate over all critical bands Q8 */ ); void dtx_fx( diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 5e50cac15..e0dd32927 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -212,13 +212,9 @@ void transition_enc_fx( IF( EQ_16( *tc_subfr, TC_0_0 ) ) { /* this is called only to compute unused bits */ -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#endif - L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, - st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, + st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, sub( shift_wsp, 1 ) ); @@ -328,13 +324,9 @@ void transition_enc_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#endif - st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, - unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, + unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* @@ -1042,14 +1034,9 @@ void transition_enc_ivas_fx( IF( EQ_16( *tc_subfr, TC_0_0 ) ) { /* this is called only to compute unused bits */ - -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#endif - L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, - st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, + st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } @@ -1160,13 +1147,9 @@ void transition_enc_ivas_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { -#ifdef REMOVE_EVS_DUPLICATES - config_acelp1_IVAS( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#else - config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, -#endif - st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, - unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); + config_acelp1_fx( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, + unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* -- GitLab From 1ecdfd6f7aecdf1da3655ac16fd8942d1f409f65 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 17 Apr 2025 15:52:49 +0200 Subject: [PATCH 1078/1221] rename file --- Workspace_msvc/lib_dec.vcxproj | 2 +- Workspace_msvc/lib_dec.vcxproj.filters | 6 +++--- ...celp_core_dec_ivas_fx.c => acelp_core_dec_fx.c} | 0 lib_dec/ivas_td_low_rate_dec_fx.c | 14 +++++++++++--- 4 files changed, 15 insertions(+), 7 deletions(-) rename lib_dec/{acelp_core_dec_ivas_fx.c => acelp_core_dec_fx.c} (100%) diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 2839a5812..12f77b346 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -139,7 +139,7 @@ false - + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index ebf15bd4c..25079058c 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -119,9 +119,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -515,6 +512,9 @@ decoder_ivas_c + + decoder_all_c + diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_fx.c similarity index 100% rename from lib_dec/acelp_core_dec_ivas_fx.c rename to lib_dec/acelp_core_dec_fx.c diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index 8f09c1c7d..6419f8517 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -40,6 +40,13 @@ #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" + +/*-------------------------------------------------------------------* + * tdm_low_rate_dec_fx() + * + * Low-bitrate decoder + *-------------------------------------------------------------------*/ + void tdm_low_rate_dec_fx( Decoder_State *st, /* i/o: decoder static memory */ Word16 dct_epit[], /* o : GSC excitation in DCT domain Q_exc*/ @@ -188,6 +195,7 @@ void tdm_low_rate_dec_fx( return; } + /*---------------------------------------------------------------------* * decod_gen_2sbfr() * @@ -217,12 +225,12 @@ void decod_gen_2sbfr_fx( move32(); Word16 gain_inov = 0; /* Innovation gain */ move16(); - Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ - Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */ + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */ Word16 voice_fac; /* voicing factor */ Word16 code[2 * L_SUBFR]; /* algebraic codevector */ const Word16 *p_Aq; /* Pointer to frame LP coefficient */ - Word16 *pt_pitch; /* pointer to Word16 pitch */ + Word16 *pt_pitch; /* pointer to Word16 pitch */ Word16 i_subfr; /* tmp variables */ Word16 L_frame; Word16 pitch_limit_flag; -- GitLab From 30d174cd2602b630f7ad4ea56061d8da79c6d5c5 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 17 Apr 2025 16:04:05 +0200 Subject: [PATCH 1079/1221] clang-format --- lib_enc/lsf_enc_fx.c | 4 ++-- lib_enc/pre_proc_fx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index b26532b15..23ed7d0c2 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -1985,7 +1985,7 @@ static void first_VQstages( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ @@ -2175,7 +2175,7 @@ static void first_VQstages_ivas_fx( dist[1] = dist_buf + maxC; move16(); - set16_fx( idx_buf, 0, (const Word16) ( 2 * stagesVQ * maxC ) ); + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); set16_fx( parents, 0, maxC ); /* Set up inital distance vector */ diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index cc8b64ca4..f7ebc8298 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -213,7 +213,7 @@ void pre_proc_fx( /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ) ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ) ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* -- GitLab From 03845cc8a08ec94c81328e1146630a7ed45e81eb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 21 Apr 2025 10:50:02 +0530 Subject: [PATCH 1080/1221] Removed the dependency of common exp for mdst_spectrum_fx and spectrum_fx, fb_tbe_enc exponent correction --- lib_com/ivas_prot_fx.h | 3 +- lib_enc/ivas_core_enc_fx.c | 2 +- lib_enc/ivas_mct_enc_mct_fx.c | 8 +- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 140 +++++++++++------------ lib_enc/ivas_stereo_mdct_stereo_enc_fx.c | 39 ++++--- lib_enc/prot_fx_enc.h | 5 +- lib_enc/swb_tbe_enc_fx.c | 7 +- 7 files changed, 103 insertions(+), 101 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 8da9cd9ac..17566e3cb 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2711,7 +2711,8 @@ void stereo_coder_tcx_fx( Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ - Word16 q_spec ); + Word16 exp_spec, + Word16 exp_mdst_spec ); // bw_detect_fx.c Word16 set_bw_mct_fx( diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index 066d105d5..f5d3c4d73 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -744,7 +744,7 @@ ivas_error ivas_core_enc_fx( IF( EQ_16( st->extl, FB_TBE ) ) { /* FB TBE encoder */ - fb_tbe_enc_ivas_fx( st, st->input_fx, fb_exc_fx, Q_fb_exc ); + fb_tbe_enc_ivas_fx( st, st->input_fx, fb_exc_fx, Q_fb_exc, st->q_inp ); } } } diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 66bdb1235..aed6aefa4 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -385,7 +385,7 @@ static void getBlockValues_fx( p_st[0] = sts[ch1]; p_st[1] = sts[ch2]; - stereo_coder_tcx_fx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum, p_inv_spectrum, p_inv_mdst_spectrum, 1, q_spec ); + stereo_coder_tcx_fx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum, p_inv_spectrum, p_inv_mdst_spectrum, 1, sub( 31, q_spec ), sub( 31, q_spec ) ); test(); test(); @@ -1073,6 +1073,7 @@ void mctStereoIGF_enc_fx( EQ_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) { Word16 exp_powerSpec_tmp[CPE_CHANNELS]; + Word16 exp_p_inv_spectrum[CPE_CHANNELS]; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { s = s_min( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[n] ) ); @@ -1097,10 +1098,13 @@ void mctStereoIGF_enc_fx( } exp_powerSpec_tmp[0] = p_st[0]->hTcxEnc->spectrum_e[0]; exp_powerSpec_tmp[1] = p_st[1]->hTcxEnc->spectrum_e[0]; + exp_p_inv_spectrum[0] = exp_p_inv_spectrum[1] = p_st[0]->hTcxEnc->spectrum_e[0]; + move16(); + move16(); move16(); move16(); ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum_fx, q_origSpec, q_origSpec, p_powerSpec_fx, exp_powerSpec_tmp, - p_powerSpecMsInv_fx, exp_powerSpec_tmp, p_inv_spectrum_fx, exp_powerSpec_tmp, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); + p_powerSpecMsInv_fx, exp_powerSpec_tmp, p_inv_spectrum_fx, exp_p_inv_spectrum, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); } ELSE { diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 46134a270..39e77050b 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -152,8 +152,8 @@ void stereo_mdct_core_enc_fx( Word32 *p_mdst_spectrum_long_fx[CPE_CHANNELS]; Word32 mdst_spectrum_long_fx[CPE_CHANNELS][N_MAX]; Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; - Word16 exp_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s; - Word16 tmp_q_powSpecInv[N_MAX], *tmp_q_psi[2]; + Word16 exp_powSpecMsInv[MCT_MAX_CHANNELS]; + Word16 tmp_q_powSpecInv[N_MAX], *exp_powSpecInv[2]; Word64 W_tmp; Encoder_State *st, **sts; STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct; @@ -188,8 +188,8 @@ void stereo_mdct_core_enc_fx( set16_fx( tmp_q_powSpecInv, 63, N_MAX ); - tmp_q_psi[0] = tmp_q_powSpecInv; - tmp_q_psi[1] = &tmp_q_powSpecInv[N_TCX10_MAX]; + exp_powSpecInv[0] = tmp_q_powSpecInv; + exp_powSpecInv[1] = &tmp_q_powSpecInv[N_TCX10_MAX]; sts = hCPE->hCoreCoder; hStereoMdct = hCPE->hStereoMdct; @@ -343,61 +343,59 @@ void stereo_mdct_core_enc_fx( IF( !hStereoMdct->isSBAStereoMode ) { /* Common q for mdst_spectrum and spectrum */ - Word16 k; - q_spec = 0; + Word16 exp1, exp2; Word16 length; - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) - { - q_spec = s_max( q_spec, sts[ch]->hTcxEnc->spectrum_e[k] ); - q_spec = s_max( q_spec, mdst_spectrum_e[ch][k] ); - } - } - q_spec = sub( Q31, q_spec ); /*find headroom to increase precision*/ - Word16 hdrm_min = MAX_16; + exp1 = MIN_16; + exp2 = MIN_16; + move16(); move16(); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { length = sts[ch]->hTcxEnc->spectrum_length; move16(); - IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + if ( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { length = shr( length, 1 ); } - hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[0], length ) ); - hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][0], length ) ); + exp1 = s_max( exp1, sub( sts[ch]->hTcxEnc->spectrum_e[0], L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[0], length ) ) ); + exp2 = s_max( exp2, sub( mdst_spectrum_e[ch][0], L_norm_arr( mdst_spectrum_fx[ch][0], length ) ) ); IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - hdrm_min = s_min( hdrm_min, L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[1], length ) ); - hdrm_min = s_min( hdrm_min, L_norm_arr( mdst_spectrum_fx[ch][1], length ) ); + exp1 = s_max( exp1, sub( sts[ch]->hTcxEnc->spectrum_e[1], L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[1], length ) ) ); + exp2 = s_max( exp2, sub( mdst_spectrum_e[ch][1], L_norm_arr( mdst_spectrum_fx[ch][1], length ) ) ); } } - q_spec = sub( add( hdrm_min, q_spec ), 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ + exp1 = add( exp1, 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ + exp2 = add( exp2, 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { length = sts[ch]->hTcxEnc->spectrum_length; move16(); - IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + if ( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { length = shr( length, 1 ); } - FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + + scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[0], length, sub( sts[ch]->hTcxEnc->spectrum_e[0], exp1 ) ); /* exp1 */ + sts[ch]->hTcxEnc->spectrum_e[0] = exp1; + scale_sig32( mdst_spectrum_fx[ch][0], length, sub( mdst_spectrum_e[ch][0], exp2 ) ); /* exp2 */ + mdst_spectrum_e[ch][0] = exp2; + IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[k], length, sub( q_spec, sub( Q31, sts[ch]->hTcxEnc->spectrum_e[k] ) ) ); /* q_spec */ - sts[ch]->hTcxEnc->spectrum_e[k] = sub( Q31, q_spec ); - Scale_sig32( mdst_spectrum_fx[ch][k], length, sub( q_spec, sub( Q31, mdst_spectrum_e[ch][k] ) ) ); /* q_spec */ - mdst_spectrum_e[ch][k] = sub( Q31, q_spec ); + scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[1], length, sub( sts[ch]->hTcxEnc->spectrum_e[1], exp1 ) ); /* exp1 */ + sts[ch]->hTcxEnc->spectrum_e[1] = exp1; + scale_sig32( mdst_spectrum_fx[ch][1], length, sub( mdst_spectrum_e[ch][1], exp2 ) ); /* exp2 */ + mdst_spectrum_e[ch][1] = exp2; } } - stereo_coder_tcx_fx( hStereoMdct, sts, ms_mask, mdst_spectrum_fx, inv_spectrum_fx, inv_mdst_spectrum_fx, 0, q_spec ); - exp_inv_spectrum[0] = exp_inv_spectrum[1] = sub( Q31, q_spec ); + stereo_coder_tcx_fx( hStereoMdct, sts, ms_mask, mdst_spectrum_fx, inv_spectrum_fx, inv_mdst_spectrum_fx, 0, sts[0]->hTcxEnc->spectrum_e[0], mdst_spectrum_e[0][0] ); + exp_inv_spectrum[0] = exp_inv_spectrum[1] = sts[0]->hTcxEnc->spectrum_e[0]; move16(); move16(); } @@ -406,10 +404,13 @@ void stereo_mdct_core_enc_fx( * Power spectrum calculation *---------------------------------------------------------------*/ Word16 length, exp, shift1, shift2, norm; - Word32 mdct, mdst; + Word32 mdct, mdst, imdct, imdst; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { + L_subframeTCX = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); /* Q0 */ + nSubframes = NB_DIV; + move16(); IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { nSubframes = 1; @@ -417,12 +418,6 @@ void stereo_mdct_core_enc_fx( move16(); move16(); } - ELSE - { - nSubframes = NB_DIV; - move16(); - L_subframeTCX = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); /* Q0 */ - } /* in MCT only relevant for bitrate switching from non-MCT bitrates */ IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) ) @@ -432,8 +427,6 @@ void stereo_mdct_core_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { - q_spec = sub( 31, sts[ch]->hTcxEnc->spectrum_e[n] ); - IF( sts[ch]->hTcxEnc->tns_ms_flag[n] ) { exp = add( s_max( mdst_spectrum_e[ch][n], sts[ch]->hTcxEnc->spectrum_e[n] ), 1 ); @@ -443,16 +436,18 @@ void stereo_mdct_core_enc_fx( /* power spectrum: MDCT^2 + MDST^2 */ FOR( i = 0; i < L_subframeTCX; i++ ) { - W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + mdst = L_shl( mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp + mdct = L_shl( sts[ch]->hTcxEnc->spectrum_fx[n][i], shift2 ); // exp: exp + imdst = L_shl( inv_mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp + imdct = L_shl( inv_spectrum_fx[ch][n][i], shift2 ); // exp: exp + + W_tmp = W_mac_32_32( W_mult_32_32( imdct, imdct ), imdst, imdst ); // exp: 2*exp + norm = W_norm( W_tmp ); + powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*exp-norm + exp_powSpecInv[n][i] = sub( shl( exp, 1 ), norm ); move32(); move16(); - mdst = L_shl( mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp - mdct = L_shl( sts[ch]->hTcxEnc->spectrum_fx[n][i], shift2 ); // exp: exp powerSpec64[ch][i + n * L_subframeTCX] = W_mac_32_32( W_mult_32_32( mdct, mdct ), mdst, mdst ); // exp: 2*exp move64(); } @@ -464,32 +459,28 @@ void stereo_mdct_core_enc_fx( IF( NE_16( hStereoMdct->mdct_stereo_mode[n], SMDCT_DUAL_MONO ) ) { /* power spectrum: MDCT^2 + MDST^2 */ - W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_psi[n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n] + norm = W_norm( W_tmp ); + powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n]-norm + exp_powSpecInv[n][0] = sub( shl( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), norm ); move32(); move16(); FOR( i = 1; i < L_subframeTCX - 1; i++ ) { - Word32 mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); /* An MDST estimate q_spec*/ - - W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + Word32 mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); // exp: sts[ch]->hTcxEnc->spectrum_e[n] + W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n] + norm = W_norm( W_tmp ); + powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n]-norm + exp_powSpecInv[n][i] = sub( shl( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), norm ); move32(); move16(); } - W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); /* 2*q_spec+1 */ - tmp_s = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ - powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ - tmp_q_psi[n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n] + norm = W_norm( W_tmp ); + powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n]-norm + exp_powSpecInv[n][L_subframeTCX - 1] = sub( shl( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), norm ); move32(); move16(); } @@ -517,30 +508,31 @@ void stereo_mdct_core_enc_fx( } /* Aligning the Q-factors */ + exp = MIN_16; + move16(); + FOR( n = 0; n < nSubframes; n++ ) { - Word16 q_temp = Q31; - move16(); - FOR( n = 0; n < nSubframes; n++ ) + FOR( i = 0; i < L_subframeTCX; i++ ) { - FOR( i = 0; i < L_subframeTCX; i++ ) + if ( powerSpecMsInv_fx[ch][n][i] != 0 ) { - if ( powerSpecMsInv_fx[ch][n][i] != 0 ) - { - q_temp = s_min( q_temp, tmp_q_psi[n][i] ); - } + exp = s_max( exp, exp_powSpecInv[n][i] ); } } + } + IF( NE_16( exp, MIN_16 ) ) + { FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_temp ) ); + powerSpecMsInv_fx[ch][n][i] = L_shl( powerSpecMsInv_fx[ch][n][i], sub( exp_powSpecInv[n][i], exp ) ); move32(); } } - exp_powSpecMsInv[ch] = sub( Q31, q_temp ); - move16(); } + exp_powSpecMsInv[ch] = exp; + move16(); } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index b1eae7862..2f1b7d6c8 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -190,7 +190,8 @@ void stereo_coder_tcx_fx( Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ - Word16 q_spec ) + Word16 exp_spec, + Word16 exp_mdct_spec ) { STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL; Word32 nrgRatio_fx[CPE_CHANNELS]; @@ -255,8 +256,8 @@ void stereo_coder_tcx_fx( tmp = Inv16( extract_h( nrgRatio_fx[k] ), &e_tmp ); /* Q15-e_tmp */ tmp = shl( tmp, e_tmp ); /* Q15 */ - v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* Q31-spectrum_e[k] */ - v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX ); /* q_spec */ + v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* exp: exp_spec */ + v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX ); /* exp: exp_mdct_spec */ } ELSE IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), -1 ) && LT_16( k, EQ_16( sts[0]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) { @@ -264,8 +265,8 @@ void stereo_coder_tcx_fx( L_frameTCX = idiv1616( L_frameTCX, ( sts[0]->core == TCX_20_CORE ) ? 1 : NB_DIV ); /* Q0 */ /* This operation is resulting in some high MLDs in fixed point. */ - v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* Q31-spectrum_e[k] */ - v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX ); /* q_spec */ + v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* exp: exp_spec */ + v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX ); /* exp: exp_mdct_spec */ } } } @@ -356,7 +357,7 @@ void stereo_coder_tcx_fx( move16(); const Word16 sfbWidth = sub( endLine, startLine ); - nrgRatio_e[0] = nrgRatio_e[1] = sub( Q31, q_spec ); + nrgRatio_e[0] = nrgRatio_e[1] = exp_spec; move16(); move16(); @@ -370,10 +371,12 @@ void stereo_coder_tcx_fx( { Word32 tmp_fx; Word16 tmp_e; - tmp_e = sub( Q31, q_spec ); + tmp_e = exp_mdct_spec; + move16(); tmp_fx = sum2_32_fx( &mdst_spectrum_fx[0][k][startLine], sfbWidth, &tmp_e ); /* Q31-tmp_e */ nrgRatio_fx[0] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], tmp_fx, tmp_e, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ - tmp_e = sub( Q31, q_spec ); + tmp_e = exp_mdct_spec; + move16(); tmp_fx = sum2_32_fx( &mdst_spectrum_fx[1][k][startLine], sfbWidth, &tmp_e ); /* Q31-tmp_e */ nrgRatio_fx[1] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[1], nrgRatio_e[1], tmp_fx, tmp_e, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */ } @@ -426,15 +429,15 @@ void stereo_coder_tcx_fx( move32(); - v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* q_spec+30-31 */ - v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth ); /* q_spec+30-31 */ - scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec - scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* exp: exp_spec+1 */ + v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth ); /* exp: exp_mdct_spec+1 */ + scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // exp: exp_spec + scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 ); // exp: exp_mdct_spec - v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* q_spec+30-31 */ - v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth ); /* q_spec+30-31 */ - scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec - scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* exp: exp_spec+1 */ + v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth ); /* exp: exp_mdct_spec+1 */ + scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // exp: exp_spec + scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 ); // exp: exp_mdct_spec } } } @@ -469,11 +472,11 @@ void stereo_coder_tcx_fx( nAvailBitsMS[k] = idiv1616( nAvailBitsMS[k], nSubframes ); /* Q0 */ move16(); - MsStereoDecision_fx( sfbConf, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], q_spec, &hStereoMdct->mdct_stereo_mode[k], &ms_mask[k][0], nAvailBitsMS[k] ); + MsStereoDecision_fx( sfbConf, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], sub( Q31, exp_spec ), &hStereoMdct->mdct_stereo_mode[k], &ms_mask[k][0], nAvailBitsMS[k] ); IF( sts[0]->igf ) { - IGFEncStereoEncoder_fx( sfbConf, sts[0]->hIGFEnc, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], q_spec, &ms_mask[k][0], + IGFEncStereoEncoder_fx( sfbConf, sts[0]->hIGFEnc, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], sub( Q31, exp_spec ), &ms_mask[k][0], &hStereoMdct->IGFStereoMode[k], hStereoMdct->mdct_stereo_mode[k], (Word16) EQ_16( sts[0]->core, TCX_20_CORE ), (Word16) EQ_16( sts[0]->last_core, ACELP_CORE ) ); } ELSE diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index d9389eb9c..73ec00cbd 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -216,9 +216,10 @@ void fb_tbe_enc_fx( void fb_tbe_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 new_input[], /* i : i speech at 48 kHz sample rate Q0*/ + const Word16 new_input[], /* i : i speech at 48 kHz sample rate Q_new_input*/ const Word16 fb_exc[], /* i : FB excitation from the SWB part Q_fb_exc*/ - Word16 Q_fb_exc ); + Word16 Q_fb_exc, + Word16 Q_new_input ); void fb_tbe_reset_enc_fx( Word32 elliptic_bpf_2_48k_mem_fx[][4], diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 316a5b549..633ede535 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -7415,9 +7415,10 @@ void fb_tbe_enc_fx( void fb_tbe_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 new_input[], /* i : input speech at 48 kHz sample rate Q0 */ + const Word16 new_input[], /* i : input speech at 48 kHz sample rate Q_new_input */ const Word16 fb_exc[], /* i : FB excitation from the SWB part Q_fb_exc */ - Word16 Q_fb_exc ) + Word16 Q_fb_exc, + Word16 Q_new_input ) { Word16 ratio; Word16 tmp_vec[L_FRAME48k]; @@ -7446,7 +7447,7 @@ void fb_tbe_enc_ivas_fx( } Copy_Scale_sig( new_input - NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_fhb_new, L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), exp_temp ); - + exp_temp = add( exp_temp, Q_new_input ); IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { elliptic_bpf_48k_generic_fx( input_fhb_new, &exp_temp, tmp_vec, hBWE_TD->elliptic_bpf_2_48k_mem_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, full_band_bpf_2_fx ); -- GitLab From 85fb64b8f0899b9ad53b9f293bb315ec8bf055a5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 21 Apr 2025 10:53:34 +0530 Subject: [PATCH 1081/1221] Clang formatting --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 39e77050b..aa762a77c 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -438,8 +438,8 @@ void stereo_mdct_core_enc_fx( { mdst = L_shl( mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp mdct = L_shl( sts[ch]->hTcxEnc->spectrum_fx[n][i], shift2 ); // exp: exp - imdst = L_shl( inv_mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp - imdct = L_shl( inv_spectrum_fx[ch][n][i], shift2 ); // exp: exp + imdst = L_shl( inv_mdst_spectrum_fx[ch][n][i], shift1 ); // exp: exp + imdct = L_shl( inv_spectrum_fx[ch][n][i], shift2 ); // exp: exp W_tmp = W_mac_32_32( W_mult_32_32( imdct, imdct ), imdst, imdst ); // exp: 2*exp norm = W_norm( W_tmp ); -- GitLab From 9d4b8adbad35b11b2440cbf1ad9aae2c7bf9f925 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 21 Apr 2025 12:04:36 +0530 Subject: [PATCH 1082/1221] Fix for 3GPP issue 1254: BASOP encoder OSBA 256 kbps: broken signal envelope Link #1254 --- lib_enc/ivas_mct_enc_mct_fx.c | 37 +++++++++-------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index aed6aefa4..1a820ac96 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -997,7 +997,7 @@ void mctStereoIGF_enc_fx( Word32 *p_powerSpec_fx[NB_DIV]; Word16 b, nSubframes, L_subframeTCX; - Word16 p_ch[2], n, ch, ch1, ch2, s = 31; + Word16 p_ch[2], n, ch, ch1, ch2; Word16 q_pSI_ch[2]; Word16 q_pS_ch[2]; Encoder_State *p_st[NB_DIV]; @@ -1072,39 +1072,20 @@ void mctStereoIGF_enc_fx( IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ) || EQ_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) { - Word16 exp_powerSpec_tmp[CPE_CHANNELS]; - Word16 exp_p_inv_spectrum[CPE_CHANNELS]; - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - s = s_min( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[n] ) ); - s = s_min( s, q_pS_ch[ch] ); - s = s_min( s, q_pSI_ch[ch] ); - } + Word16 exp_powerSpec_fx[CPE_CHANNELS], exp_powerSpecMsInv_fx[CPE_CHANNELS], exp_inv_spectrum_fx[CPE_CHANNELS]; + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - scale_sig32( p_st[ch]->hTcxEnc->spectrum_fx[0], N_MAX, sub( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[0] ) ) ); - scale_sig32( p_inv_spectrum_fx[ch][0], L_FRAME48k, sub( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[0] ) ) ); - p_st[ch]->hTcxEnc->spectrum_e[0] = sub( 31, s ); - p_st[ch]->hTcxEnc->spectrum_e[1] = sub( 31, s ); - move16(); + exp_powerSpec_fx[ch] = sub( Q31, q_pS_ch[ch] ); + exp_powerSpecMsInv_fx[ch] = sub( Q31, q_pSI_ch[ch] ); + exp_inv_spectrum_fx[ch] = p_st[ch]->hTcxEnc->spectrum_e[n]; move16(); - - scale_sig32( p_powerSpecMsInv_fx[ch][0], L_FRAME48k, sub( s, q_pSI_ch[ch] ) ); - scale_sig32( &p_powerSpec_fx[ch][0], sts[ch]->hTcxEnc->L_frameTCX, sub( s, q_pS_ch[ch] ) ); - q_powerSpec[ch1] = s; - q_powerSpec[ch2] = s; move16(); move16(); } - exp_powerSpec_tmp[0] = p_st[0]->hTcxEnc->spectrum_e[0]; - exp_powerSpec_tmp[1] = p_st[1]->hTcxEnc->spectrum_e[0]; - exp_p_inv_spectrum[0] = exp_p_inv_spectrum[1] = p_st[0]->hTcxEnc->spectrum_e[0]; - move16(); - move16(); - move16(); - move16(); - ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum_fx, q_origSpec, q_origSpec, p_powerSpec_fx, exp_powerSpec_tmp, - p_powerSpecMsInv_fx, exp_powerSpec_tmp, p_inv_spectrum_fx, exp_p_inv_spectrum, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); + + ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum_fx, q_origSpec, q_origSpec, p_powerSpec_fx, exp_powerSpec_fx, + p_powerSpecMsInv_fx, exp_powerSpecMsInv_fx, p_inv_spectrum_fx, exp_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); } ELSE { -- GitLab From 86a16ee117dcb1d7e236574cc9d6d13faaa91cc6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 21 Apr 2025 12:09:33 +0530 Subject: [PATCH 1083/1221] Fix for complexity measure crash - [ltv48_OMASA_2ISM_1TC_OMASA_ISM2_1TC_b16_4_wb_cbr_fer_ep_10pct_fer_g192.192] --- lib_enc/ivas_masa_enc_fx.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index 5c5de97ab..ceb5dec1d 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -2302,7 +2302,7 @@ static void reduce_metadata_further_fx( Word16 bandEnergy_exp, shift; UWord8 mergeOverFreqBands; Word32 meanRatio; - Word16 tmp, tmp2; + Word16 tmp, tmp2, q_totalEnergySum; numCodingBands = hMasa->config.numCodingBands; test(); @@ -2373,6 +2373,7 @@ static void reduce_metadata_further_fx( tmp2 = s_min( 32, tmp2 ); totalEnergySum = W_extract_h( W_shl( W_tmp, tmp2 ) ); tmp2 = sub( tmp2, 32 ); + q_totalEnergySum = add( hMasa->data.q_energy, tmp2 ); /* Determine onsets */ hMasa->data.onset_detector_1_fx = Mpy_32_32( hMasa->data.onset_detector_1_fx, LOWBITRATE_ONSET_ALPHA_Q31 ); @@ -2380,12 +2381,17 @@ static void reduce_metadata_further_fx( tmp = hMasa->data.q_onset_detector; move16(); - IF( BASOP_Util_Cmp_Mant32Exp( hMasa->data.onset_detector_1_fx, sub( 31, hMasa->data.q_onset_detector ), totalEnergySum, sub( 31, hMasa->data.q_energy ) ) < 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( hMasa->data.onset_detector_1_fx, sub( 31, hMasa->data.q_onset_detector ), totalEnergySum, sub( 31, q_totalEnergySum ) ) < 0 ) { hMasa->data.onset_detector_1_fx = totalEnergySum; // hMasa->data.q_energy hMasa->data.q_onset_detector = add( hMasa->data.q_energy, tmp2 ); move32(); move16(); + + shift = norm_l( hMasa->data.onset_detector_2_fx ); + hMasa->data.onset_detector_2_fx = L_shl( hMasa->data.onset_detector_2_fx, shift ); + move32(); + tmp = add( tmp, shift ); } IF( LT_16( tmp, hMasa->data.q_onset_detector ) ) { -- GitLab From ec8f88dc5e91646b110a2449cfe1303df024aae5 Mon Sep 17 00:00:00 2001 From: malenov Date: Tue, 15 Apr 2025 12:42:10 +0200 Subject: [PATCH 1084/1221] align the usage of IND_SHB_RES_GS with the float code --- lib_com/cnst.h | 4 ++++ lib_com/options.h | 1 + lib_enc/swb_tbe_enc_fx.c | 8 ++++++++ 3 files changed, 13 insertions(+) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 379dd7c85..ae84dbd2c 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -532,12 +532,16 @@ enum IND_STEREO_ICBWE_MSFLAG, IND_SHB_ENER_SF, IND_SHB_RES_GS, +#ifndef FIX_1486_IND_SHB_RES IND_SHB_RES_GS1, IND_SHB_RES_GS2, IND_SHB_RES_GS3, IND_SHB_RES_GS4, IND_SHB_RES_GS5, IND_SHB_VF, +#else + IND_SHB_VF = IND_SHB_RES_GS + 5, +#endif IND_SHB_LSF, IND_SHB_MIRROR = IND_SHB_LSF + 5, IND_SHB_GRID, diff --git a/lib_com/options.h b/lib_com/options.h index daa609ed4..3f158a8e8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -91,6 +91,7 @@ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ +#define FIX_1486_IND_SHB_RES /* VA: Fix for issue 1486: align the usage of IND_SHB_RES_GS indices with float code */ #define TEST_HR diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 633ede535..acfc5043c 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -5683,7 +5683,11 @@ static void Quant_shb_res_gshape_fx( move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { +#ifdef FIX_1486_IND_SHB_RES + push_indice( st_fx->hBstr, IND_SHB_RES_GS + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); +#else push_indice( st_fx->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); +#endif } } } @@ -5719,7 +5723,11 @@ static void Quant_shb_res_gshape_ivas_fx( } ELSE { +#ifdef FIX_1486_IND_SHB_RES + push_indice( st->hBstr, IND_SHB_RES_GS + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); +#else push_indice( st->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); +#endif } } } -- GitLab From 1c32f217ea08b6ddcbfc02d2d0c870ee8769de81 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 21 Apr 2025 16:38:00 +0530 Subject: [PATCH 1085/1221] Q-mismatch bug fix for ProcessIGF in mct path --- lib_dec/ivas_dirac_dec_fx.c | 4 ++-- lib_enc/ext_sig_ana_fx.c | 2 +- lib_enc/ivas_mct_core_enc_fx.c | 2 +- lib_enc/ivas_mct_enc_mct_fx.c | 4 ++-- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 4 ++-- lib_enc/prot_fx_enc.h | 3 ++- lib_enc/tcx_utils_enc_fx.c | 5 +++-- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 10b8059b9..9c319489e 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2186,7 +2186,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); - FOR( Word16 i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { FOR( Word16 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { @@ -2195,7 +2195,7 @@ void ivas_dirac_dec_render_sf_fx( } } - FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { FOR( Word16 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 200e7e8ed..eeeb294b4 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1401,7 +1401,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( st->igf ) { Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] ); - ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); + ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], &q_spectrum, hTcxEnc->spectrum_fx[frameno], q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); } } } diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 548a56717..0ab232dd9 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -646,7 +646,7 @@ void ivas_mct_core_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); - ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], &q_spectrum, orig_spectrum_fx[ch][n], q_origSpec, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); st->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index aed6aefa4..67f3b3d47 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -1122,7 +1122,7 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[p_ch[ch]], sub( Q31, q_powerSpec[p_ch[ch]] ), N_MAX + L_MDCT_OVLP_MAX ); - ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], &q_spectrum, orig_spectrum_fx[p_ch[ch]][n], q_origSpec, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); @@ -1163,7 +1163,7 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); set16_fx( exp_powerSpec[ch], sub( Q31, q_powerSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); - ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], &q_spectrum, orig_spectrum_fx[ch][n], q_origSpec, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index aa762a77c..c38494669 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -710,7 +710,7 @@ void stereo_mdct_core_enc_fx( q_spectrum = sub( Q31, st->hTcxEnc->spectrum_e[n] ); Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ - ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); + ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], &q_spectrum, orig_spectrum_fx[ch][n], q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); } } } @@ -787,7 +787,7 @@ void stereo_mdct_core_enc_fx( Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ - ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); + ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], &q_spectrum, orig_spectrum_fx[ch][n], q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); } } } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 73ec00cbd..120dd42b5 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1244,8 +1244,9 @@ void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ - const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ + const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ + const Word16 q_ITFMDCTSpectrum, /* i : Q of MDCT spectrum fir ITF */ Word32 *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate */ Word16 *q_powerSpec, /* i/o: Q of power spectrum */ const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 228e522bf..7d5f486cc 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3926,8 +3926,9 @@ void ProcessIGF_ivas_fx( Encoder_State *st, /* i : Encoder state */ Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ - const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ + const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ + const Word16 q_ITFMDCTSpectrum, /* i : Q of MDCT spectrum fir ITF */ Word32 *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate (*q_powerSpec) */ Word16 *exp_powerSpec, /* i/o: Q of power spectrum */ const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ @@ -3969,7 +3970,7 @@ void ProcessIGF_ivas_fx( } } - IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, *q_spectrum ) ); + IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, q_ITFMDCTSpectrum ) ); IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); -- GitLab From f325d96e34c46d7dc59d04289b830371fefed00f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 22 Apr 2025 10:37:39 +0200 Subject: [PATCH 1086/1221] Revert "[revert-me] use other branch for testing" This reverts commit ca78d64b8655295422fafd8100f4bd609b71a8c9. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c500107c1..01ac69a92 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "kiene/tmp-branch-for-ltv-split-testing" + BASOP_CI_BRANCH_PC_REPO: "ci/split-output-files-b4-comparison" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From 7c5a7682fe42f3b38974c1225ebb53924dea7478 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 22 Apr 2025 10:37:53 +0200 Subject: [PATCH 1087/1221] Revert "[revert-me] change branch for getting the scripts" This reverts commit e538224816eff3d9455bc28e81be5d5eb29c18d0. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 01ac69a92..275b91bfb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "ci/split-output-files-b4-comparison" + BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From e4c2db922a44e2bc9270262e4825c140f2c04126 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Tue, 22 Apr 2025 13:57:28 +0200 Subject: [PATCH 1088/1221] fix lineendings --- lib_com/options.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 99206fa9d..2f1e82de8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -90,8 +90,8 @@ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ -#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ +#define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ #define FIX_1486_IND_SHB_RES /* VA: Fix for issue 1486: align the usage of IND_SHB_RES_GS indices with float code */ -- GitLab From 32903074dd6dbee6e4737651a15a4873cec378b5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 22 Apr 2025 23:03:07 +0530 Subject: [PATCH 1089/1221] Fix for LTV encoder +10dB crash --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index c38494669..646f3e725 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -458,29 +458,35 @@ void stereo_mdct_core_enc_fx( { IF( NE_16( hStereoMdct->mdct_stereo_mode[n], SMDCT_DUAL_MONO ) ) { + exp = shl( add( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), 1 ); // 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) /* power spectrum: MDCT^2 + MDST^2 */ - W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n] + mdct = L_shr( inv_spectrum_fx[ch][n][0], 1 ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + W_tmp = W_mult_32_32( mdct, mdct ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) (exp) norm = W_norm( W_tmp ); - powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n]-norm - exp_powSpecInv[n][0] = sub( shl( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), norm ); + powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1)-norm (exp-norm) + exp_powSpecInv[n][0] = sub( exp, norm ); move32(); move16(); FOR( i = 1; i < L_subframeTCX - 1; i++ ) { - Word32 mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); // exp: sts[ch]->hTcxEnc->spectrum_e[n] - W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n] + /* float mdst = ( inv_spectrum[ch][n][i + 1] - inv_spectrum[ch][n][i - 1] ); + powerSpecMsInv[ch][n][i] = mdst * mdst + inv_spectrum[ch][n][i] * inv_spectrum[ch][n][i]; */ + mdst = L_sub( L_shr( inv_spectrum_fx[ch][n][i + 1], 1 ), L_shr( inv_spectrum_fx[ch][n][i - 1], 1 ) ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + mdct = L_shr( inv_spectrum_fx[ch][n][i], 1 ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + W_tmp = W_mac_32_32( W_mult_32_32( mdst, mdst ), mdct, mdct ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) (exp) norm = W_norm( W_tmp ); - powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n]-norm - exp_powSpecInv[n][i] = sub( shl( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), norm ); + powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1)-norm (exp-norm) + exp_powSpecInv[n][i] = sub( exp, norm ); move32(); move16(); } - W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n] + mdct = L_shr( inv_spectrum_fx[ch][n][L_subframeTCX - 1], 1 ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1 + W_tmp = W_mult_32_32( mdct, mdct ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) (exp) norm = W_norm( W_tmp ); - powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*sts[ch]->hTcxEnc->spectrum_e[n]-norm - exp_powSpecInv[n][L_subframeTCX - 1] = sub( shl( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), norm ); + powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1)-norm (exp-norm) + exp_powSpecInv[n][L_subframeTCX - 1] = sub( exp, norm ); move32(); move16(); } -- GitLab From c4169554ee53d088799b7fd4b8c56fd83fd05c36 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 23 Apr 2025 17:02:33 +0530 Subject: [PATCH 1090/1221] Fix for 3GPP issue 1505: [regression] Encoder crash for McMASA 7.1+4 16kHz input at 64kbps in convertToBwMS_fx() Link #1505 --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 646f3e725..1bd5c936b 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -371,7 +371,7 @@ void stereo_mdct_core_enc_fx( } exp1 = add( exp1, 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ - exp2 = add( exp2, 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ + exp2 = add( exp2, 2 ); /* 2 guard bit to avoid over-flows in stereo_coder_tcx_fx (ms_processing_fx) */ FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { -- GitLab From 6ed7ba270608ea31f61e5ed9ebc51d7eb24ada98 Mon Sep 17 00:00:00 2001 From: Anjaneyulu Sana Date: Tue, 15 Apr 2025 17:03:53 +0530 Subject: [PATCH 1091/1221] Fix for 3GPP issue 1479: Renderer crashes for MASA long test vector input --- lib_rend/ivas_dirac_rend_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 03831e407..030287b7f 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4166,7 +4166,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i] = L_add( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i], surCohEner_fx ); // q29 move32(); - surCohRatio_fx[i] = L_deposit_h( BASOP_Util_Divide3232_Scale( surCohEner_fx, L_add( L_add( 1, dirEne_fx ), surCohEner_fx ), &surCohRatio_exp[i] ) ); // 31-surCohRatio_exp + surCohRatio_fx[i] = BASOP_Util_Divide3232_Scale_cadence( surCohEner_fx, L_add( L_add( 1, dirEne_fx ), surCohEner_fx ), &surCohRatio_exp[i] ); // 31-surCohRatio_exp move32(); temp_exp = s_max( temp_exp, surCohRatio_exp[i] ); } @@ -4961,7 +4961,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hSpatParamRendCom->num_freq_bands ) ); } } - scale_factor = sub( scale_factor, 3 ); // guard bits + scale_factor = sub( scale_factor, find_guarded_bits_fx( hSpatParamRendCom->num_freq_bands ) ); // guard bits FOR( ch = 0; ch < hDirACRend->num_outputs_dir; ch++ ) { -- GitLab From f1e41eb33e60dbf624ddf474d5e25af517b88aa8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 23 Apr 2025 17:06:22 +0530 Subject: [PATCH 1092/1221] Replace BASOP_Util_Divide3232_Scale_cadence() with BASOP_Util_Divide3232_Scale_newton() --- lib_rend/ivas_dirac_rend_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 030287b7f..2f748289a 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4166,7 +4166,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i] = L_add( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i], surCohEner_fx ); // q29 move32(); - surCohRatio_fx[i] = BASOP_Util_Divide3232_Scale_cadence( surCohEner_fx, L_add( L_add( 1, dirEne_fx ), surCohEner_fx ), &surCohRatio_exp[i] ); // 31-surCohRatio_exp + surCohRatio_fx[i] = BASOP_Util_Divide3232_Scale_newton( surCohEner_fx, L_add( L_add( 1, dirEne_fx ), surCohEner_fx ), &surCohRatio_exp[i] ); // 31-surCohRatio_exp move32(); temp_exp = s_max( temp_exp, surCohRatio_exp[i] ); } -- GitLab From e550b83e38222f2720b5b49f8bf857cc02b66eca Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 14:46:13 +0200 Subject: [PATCH 1093/1221] remove some debug output and add silent/quiet flags --- .gitlab-ci.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 275b91bfb..5f8168e3a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1703,8 +1703,7 @@ voip-be-on-merge-request: # see below in the concrete complexity jobs - if [ "$JOB_ID_INJECT" != "" ]; then job_id=$JOB_ID_INJECT; fi - curl --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts.zip - - unzip artifacts.zip || true # this may fail on first run, when there are no artifacts there and the zip file is actually just "404"-html - - ls + - unzip -qq artifacts.zip || true # this may fail on first run, when there are no artifacts there and the zip file is actually just "404"-html - public_dir="$CI_JOB_NAME-public" # if is needed to catch case when no artifact is there (first run), similarly as above @@ -1727,15 +1726,14 @@ voip-be-on-merge-request: - fi - fi - - ls wmops - rm artifacts.zip - rm -rf $public_dir ### 1.5.part: get the corresponding measurement from ivas-float-update - job_id=$(python3 ci/get_id_of_last_job_occurence.py ivas-float-update $CI_JOB_NAME $CI_PROJECT_ID) - echo $job_id - - curl --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts_ref.zip - - unzip -j artifacts_ref.zip "*latest_WMOPS.csv" || true + - curl --silent --show-error --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts_ref.zip + - unzip -qq -j artifacts_ref.zip "*latest_WMOPS.csv" || true # add file to arguments only if the artifact could be retrieved to prevent error later. - if [ -f latest_WMOPS.csv ]; then GET_WMOPS_ARGS="$GET_WMOPS_ARGS latest_WMOPS.csv"; fi @@ -1748,8 +1746,6 @@ voip-be-on-merge-request: - mkdir $public_dir/logs # first move logs - log_files=$(cat $public_dir/graphs*.js | grep logFile | sed "s/.*\(wmops_newsletter_.*\.csv\).*/\1/g") - - echo $log_files - - ls wmops/logs - for f in $log_files; do [ -f wmops/logs/$f ] && mv wmops/logs/$f $public_dir/logs/$f; done # copy index page blueprint - cp ci/complexity_measurements/index_complexity.html ${public_dir}/index.html @@ -1757,7 +1753,6 @@ voip-be-on-merge-request: - sed -i "s/IVAS FORMAT/IVAS $in_format to $out_format/g" ${public_dir}/index.html # do separately here to avoid overwrite complaints by mv - mv -f ci/complexity_measurements/style.css ${public_dir}/ - - ls $public_dir .complexity-template: extends: @@ -1775,7 +1770,6 @@ voip-be-on-merge-request: - *complexity-measurements-setup # delete previous jobs logfiles if present (-f flag ensures return calue of 0 even in first run where this folder is not present) - rm -rf COMPLEXITY/logs - - which coan allow_failure: exit_codes: - 123 -- GitLab From bbfe0be3b8cd96fbde157aeff57c71c05ddc2624 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 17:01:03 +0200 Subject: [PATCH 1094/1221] fix artifact name to conform to new scripts --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 275b91bfb..382b3992d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -738,7 +738,7 @@ stages: - $MERGE_TARGET_COMMIT_FILE - regressions_crashes.csv - regressions_MLD.csv - - regressions_MAXIMUM_ABS_DIFF.csv + - regressions_MAX_ABS_DIFF.csv - regressions_MIN_SSNR.csv - regressions_MIN_ODG.csv - improvements_crashes.csv -- GitLab From 240e70d6c66c70962219efbd7f5695f004f54010 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 17:03:53 +0200 Subject: [PATCH 1095/1221] fix other occasions as well --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 382b3992d..0b7fe26eb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -622,7 +622,7 @@ stages: - *print-common-info # create empty files for all artifacts to suppress warnings in case of no regressions found or all is BE - - touch $XML_REPORT_BRANCH $XML_REPORT_MAIN $HTML_REPORT_BRANCH $HTML_REPORT_MAIN $CSV_BRANCH $CSV_MAIN $SUMMARY_HTML_ARTIFACT_NAME $FLOAT_REF_COMMIT_FILE $CUT_COMMIT_FILE $MERGE_TARGET_COMMIT_FILE regressions_crashes.csv regressions_MLD.csv regressions_MAXIMUM_ABS_DIFF.csv regressions_MIN_SSNR.csv regressions_MIN_ODG.csv improvements_crashes.csv improvements_MLD.csv improvements_MAXIMUM_ABS_DIFF.csv improvements_MIN_SSNR.csv improvements_MIN_ODG.csv + - touch $XML_REPORT_BRANCH $XML_REPORT_MAIN $HTML_REPORT_BRANCH $HTML_REPORT_MAIN $CSV_BRANCH $CSV_MAIN $SUMMARY_HTML_ARTIFACT_NAME $FLOAT_REF_COMMIT_FILE $CUT_COMMIT_FILE $MERGE_TARGET_COMMIT_FILE regressions_crashes.csv regressions_MLD.csv regressions_MAX_ABS_DIFF.csv regressions_MIN_SSNR.csv regressions_MIN_ODG.csv improvements_crashes.csv improvements_MLD.csv improvements_MAX_ABS_DIFF.csv improvements_MIN_SSNR.csv improvements_MIN_ODG.csv - mkdir $IMAGES_ARTIFACT_NAME - set -euxo pipefail @@ -743,7 +743,7 @@ stages: - regressions_MIN_ODG.csv - improvements_crashes.csv - improvements_MLD.csv - - improvements_MAXIMUM_ABS_DIFF.csv + - improvements_MAX_ABS_DIFF.csv - improvements_MIN_SSNR.csv - improvements_MIN_ODG.csv expose_as: "pytest compare results" -- GitLab From 1acdddb6af021c28246ffe812cb56f1724d2440a Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 17:11:14 +0200 Subject: [PATCH 1096/1221] add summary printout at end of complexity jobs --- .gitlab-ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5f8168e3a..644ed7355 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1754,6 +1754,16 @@ voip-be-on-merge-request: # do separately here to avoid overwrite complaints by mv - mv -f ci/complexity_measurements/style.css ${public_dir}/ +.complexity-measurements-report-summary: &complexity-measurements-report-summary + - *print-results-banner + - if [ $ret_val -eq 0 ]; then + - echo -e "No crashes occured.\nNo changes in complexity or memory usage (>1%) detected." + - elif [ $ret_val -eq 123 ]; then + - echo -e "Changes in complexity or memory usage (>1%) detected!!!\nNo crashes occured." + - else + - echo -e "Something went wrong in running the codec. Likely some modes were crashing." + - fi + .complexity-template: extends: - .test-job-linux @@ -1793,6 +1803,7 @@ complexity-stereo-in-stereo-out: - out_format=stereo - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-ism-in-binaural-out: @@ -1810,6 +1821,7 @@ complexity-ism-in-binaural-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-ism-in-binaural_room_ir-out: @@ -1827,6 +1839,7 @@ complexity-ism-in-binaural_room_ir-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-ism-in-ext-out: @@ -1844,6 +1857,7 @@ complexity-ism-in-ext-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-sba-hoa3-in-hoa3-out: @@ -1861,6 +1875,7 @@ complexity-sba-hoa3-in-hoa3-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-sba-hoa3-in-binaural-out: @@ -1878,6 +1893,7 @@ complexity-sba-hoa3-in-binaural-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-sba-hoa3-in-binaural_room_ir-out: @@ -1895,6 +1911,7 @@ complexity-sba-hoa3-in-binaural_room_ir-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-mc-in-7_1_4-out: @@ -1912,6 +1929,7 @@ complexity-mc-in-7_1_4-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-mc-in-binaural-out: @@ -1929,6 +1947,7 @@ complexity-mc-in-binaural-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-mc-in-binaural_room_ir-out: @@ -1946,6 +1965,7 @@ complexity-mc-in-binaural_room_ir-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-masa-in-ext-out: @@ -1963,6 +1983,7 @@ complexity-masa-in-ext-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-masa-in-binaural-out: @@ -1980,6 +2001,7 @@ complexity-masa-in-binaural-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-masa-in-hoa3-out: @@ -1997,6 +2019,7 @@ complexity-masa-in-hoa3-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val # complexity-omasa-in-ext-out: @@ -2014,6 +2037,7 @@ complexity-masa-in-hoa3-out: # - ret_val=0 # - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? # - *complexity-measurements-prepare-artifacts +# - *complexity-measurements-report-summary # - exit $ret_val complexity-omasa-in-binaural-out: @@ -2031,6 +2055,7 @@ complexity-omasa-in-binaural-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-omasa-in-hoa3-out: @@ -2048,6 +2073,7 @@ complexity-omasa-in-hoa3-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-StereoDmxEVS-stereo-in-mono-out: @@ -2065,6 +2091,7 @@ complexity-StereoDmxEVS-stereo-in-mono-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val # complexity-osba-in-ext-out: @@ -2080,6 +2107,7 @@ complexity-StereoDmxEVS-stereo-in-mono-out: # - ret_val=0 # - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? # - *complexity-measurements-prepare-artifacts +# - *complexity-measurements-report-summary # - exit $ret_val complexity-osba-in-binaural-out: @@ -2097,6 +2125,7 @@ complexity-osba-in-binaural-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val complexity-osba-in-binaural_room_ir-out: @@ -2114,6 +2143,7 @@ complexity-osba-in-binaural_room_ir-out: - ret_val=0 - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts + - *complexity-measurements-report-summary - exit $ret_val # job that sets up gitlab pages website -- GitLab From 1b059d6ef99d5f8155b0160e609fe56cc3c602f4 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 17:14:58 +0200 Subject: [PATCH 1097/1221] [revert-me] temporarily disable delay for testing --- .gitlab-ci.yml | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 644ed7355..ae4c41ec6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1811,8 +1811,6 @@ complexity-ism-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 1 hour variables: JOB_ID_INJECT: "" script: @@ -1829,8 +1827,6 @@ complexity-ism-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 2 hours variables: JOB_ID_INJECT: "" script: @@ -1847,8 +1843,6 @@ complexity-ism-in-ext-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 3 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1865,8 +1859,6 @@ complexity-sba-hoa3-in-hoa3-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 4 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1883,8 +1875,6 @@ complexity-sba-hoa3-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 5 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1901,8 +1891,6 @@ complexity-sba-hoa3-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 6 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1919,8 +1907,6 @@ complexity-mc-in-7_1_4-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 7 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1937,8 +1923,6 @@ complexity-mc-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 10 hours variables: JOB_ID_INJECT: "" script: @@ -1955,8 +1939,6 @@ complexity-mc-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 12 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1973,8 +1955,6 @@ complexity-masa-in-ext-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 15 hours variables: JOB_ID_INJECT: "" script: @@ -1991,8 +1971,6 @@ complexity-masa-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 16 hours variables: JOB_ID_INJECT: "" script: @@ -2009,8 +1987,6 @@ complexity-masa-in-hoa3-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 17 hours variables: JOB_ID_INJECT: "" script: @@ -2045,8 +2021,6 @@ complexity-omasa-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 18 hours variables: JOB_ID_INJECT: "" script: @@ -2063,8 +2037,6 @@ complexity-omasa-in-hoa3-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 20 hours variables: JOB_ID_INJECT: "" script: @@ -2081,8 +2053,6 @@ complexity-StereoDmxEVS-stereo-in-mono-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 22 hours variables: JOB_ID_INJECT: "" script: @@ -2099,8 +2069,6 @@ complexity-StereoDmxEVS-stereo-in-mono-out: # - .complexity-template # rules: # - if: $MEASURE_COMPLEXITY_LINUX -# when: delayed -# start_in: 17 hours # script: # - in_format=OSBA # - out_format=EXT @@ -2115,8 +2083,6 @@ complexity-osba-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 22 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -2133,8 +2099,6 @@ complexity-osba-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX - when: delayed - start_in: 25 hours variables: JOB_ID_INJECT: "" script: -- GitLab From f9354b9c882b9f2206bc78976073c3ed5b572413 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 17:20:38 +0200 Subject: [PATCH 1098/1221] [revert-me] change script branch for testing --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ae4c41ec6..f29544856 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" + BASOP_CI_BRANCH_PC_REPO: "kiene/tmp-branch-for-complexity-cleanup" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From 4200ee7afd5b315ea0fcbae54c382585e0ba3d40 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 17:29:49 +0200 Subject: [PATCH 1099/1221] silent flag for another curl call --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f29544856..49bff6ad4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1702,7 +1702,7 @@ voip-be-on-merge-request: # this is a testing/maintenance mechanism to force getting the log history from a specific job id # see below in the concrete complexity jobs - if [ "$JOB_ID_INJECT" != "" ]; then job_id=$JOB_ID_INJECT; fi - - curl --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts.zip + - curl --silent --show-error --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts.zip - unzip -qq artifacts.zip || true # this may fail on first run, when there are no artifacts there and the zip file is actually just "404"-html - public_dir="$CI_JOB_NAME-public" -- GitLab From e4ed9c4fc8ce3752a732321b22278150ebc8dea8 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 23 Apr 2025 18:39:57 +0200 Subject: [PATCH 1100/1221] [revert-me] add intentional crash + changed complexity --- lib_dec/ivas_jbm_dec_fx.c | 8 ++++---- lib_enc/ivas_enc_fx.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 74af57bd5..8d4b10dec 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -159,10 +159,10 @@ ivas_error ivas_jbm_dec_tc_fx( set32_fx( &p_output_fx[0][0], 0, L_FRAME48k ); set32_fx( &p_output_fx[1][0], 0, L_FRAME48k ); - IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } + // IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK ) + // { + // return error; + // } IF( NE_16( q_output, Q11 ) ) { diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index ff5f65b32..95f690c15 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -31,6 +31,7 @@ *******************************************************************************************************/ #include +#include #include #include "options.h" #include "cnst.h" @@ -187,6 +188,7 @@ ivas_error ivas_enc_fx( } ELSE IF( EQ_32( ivas_format, ISM_FORMAT ) ) { + assert( 0 ); /* select ISM format mode; reconfigure the ISM format encoder */ IF( ( error = ivas_ism_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { -- GitLab From fe603f822ce6da6933b81b3ba20f11f30fb616ba Mon Sep 17 00:00:00 2001 From: Stefan Doehla Date: Tue, 15 Apr 2025 07:59:10 +0000 Subject: [PATCH 1101/1221] [fix] L_mult -> L_mult_o in L_msuNs_co --- lib_com/basop32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 20dbe663e..65d449a32 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -1575,7 +1575,7 @@ Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *O { Word32 L_var_out; - L_var_out = L_mult( var1, var2 ); + L_var_out = L_mult_o( var1, var2, Overflow ); L_var_out = L_sub_co( L_var3, L_var_out, Carry, Overflow ); return ( L_var_out ); -- GitLab From f783eba95c52904c34d86e37a6f371f3f4461dcf Mon Sep 17 00:00:00 2001 From: Stefan Doehla Date: Tue, 22 Apr 2025 16:23:37 +0200 Subject: [PATCH 1102/1221] [fix] missing overflow handling as in legacy STL --- lib_com/basop32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 65d449a32..aec1573be 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -2044,6 +2044,8 @@ Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) Word32 L_test; Flag carry_int = 0; + /* TODO: unset overflow, but not done */ + /* unset_overflow( Overflow ); */ if ( get_carry( Carry ) ) { unset_carry( Carry ); @@ -2056,6 +2058,7 @@ Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) L_var_out = L_var1 - L_var2; if ( L_var1 > 0L ) { + set_overflow( Overflow ); unset_carry( Carry ); } } @@ -2067,18 +2070,22 @@ Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) if ( ( L_test < 0 ) && ( L_var1 > 0 ) && ( L_var2 < 0 ) ) { + set_overflow( Overflow ); carry_int = 0; } else if ( ( L_test > 0 ) && ( L_var1 < 0 ) && ( L_var2 > 0 ) ) { + set_overflow( Overflow ); carry_int = 1; } else if ( ( L_test > 0 ) && ( ( L_var1 ^ L_var2 ) > 0 ) ) { + unset_overflow( Overflow ); carry_int = 1; } if ( L_test == MIN_32 ) { + set_overflow( Overflow ); carry_int ? set_carry( Carry ) : unset_carry( Carry ); } else -- GitLab From 8ee4fc159676449962ebfa9426aa689a2c654b70 Mon Sep 17 00:00:00 2001 From: Stefan Doehla Date: Wed, 23 Apr 2025 21:47:58 +0200 Subject: [PATCH 1103/1221] remove unnecessary comment --- lib_com/basop32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index aec1573be..fbe08a11f 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -2038,14 +2038,13 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) return ( L_var_out ); } + Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) { Word32 L_var_out; Word32 L_test; Flag carry_int = 0; - /* TODO: unset overflow, but not done */ - /* unset_overflow( Overflow ); */ if ( get_carry( Carry ) ) { unset_carry( Carry ); -- GitLab From f2d5e62ed9989c2119241bec4cc1113211fb3cdf Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 23 Apr 2025 17:21:44 +0530 Subject: [PATCH 1104/1221] Fix for 3GPP issue 1499: Spike in BASOP encoded signal of MASA selection material Link #1499 --- lib_enc/analy_sp_fx.c | 10 ++--- lib_enc/find_uv_fx.c | 2 +- lib_enc/ivas_core_pre_proc_front_fx.c | 32 ++++++++-------- lib_enc/ivas_cpe_enc_fx.c | 4 +- lib_enc/ivas_front_vad_fx.c | 12 +++--- lib_enc/ivas_stereo_td_analysis_fx.c | 8 ++-- lib_enc/long_enr_fx.c | 4 +- lib_enc/nois_est_fx.c | 55 ++++++++++++++------------- lib_enc/prot_fx_enc.h | 6 +-- lib_enc/stat_enc.h | 6 ++- lib_enc/updt_enc_fx.c | 9 ++++- 11 files changed, 80 insertions(+), 68 deletions(-) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index 57dbb369c..49bb03f57 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -438,7 +438,7 @@ void ivas_analy_sp_fx( Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ Word32 *lf_E, /* o : per bin E for first... q_lf_E */ Word16 *q_lf_E, /* o : per bin E for first... Q0 */ - Word16 *Etot, /* o : total input energy Q8 */ + Word32 *Etot, /* o : total input energy Q24 */ const Word16 min_band, /* i : minimum critical band Q0 */ const Word16 max_band, /* i : maximum critical band Q0 */ Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ @@ -557,7 +557,7 @@ void ivas_analy_sp_fx( /* Average total log energy over both half-frames */ /* *Etot = 10.0f * (float)log10(0.5f * *Etot); */ - *Etot = -12800 /* 10.f * logf(0.00001f) in Q8 */; + *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/; move16(); IF( LEtot != 0 ) { @@ -566,7 +566,7 @@ void ivas_analy_sp_fx( LEtot = W_shl( LEtot, exp ); // q_fr_bands+2+exp Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 61, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+2+exp-32) */ ); // Q25 Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21 - *Etot = extract_h( L_shl( Ltmp, Q24 - Q21 ) ); // Q8 + *Etot = L_shl( Ltmp, Q24 - Q21 ); // Q24 move16(); } } @@ -599,7 +599,7 @@ void ivas_analy_sp_fx( } /* Average total log energy over both half-frames */ - *Etot = -12800 /* 10.f * logf(0.00001f) in Q8 */; + *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/; move16(); IF( LEtot != 0 ) { @@ -607,7 +607,7 @@ void ivas_analy_sp_fx( LEtot = W_shl( LEtot, exp ); // q_fr_bands+exp Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 62, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+1+exp-32) */ ); // Q25 Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21 - *Etot = extract_h( L_shl( Ltmp, Q24 - Q21 ) ); // Q8 + *Etot = L_shl( Ltmp, Q24 - Q21 ); // Q24 move16(); } } diff --git a/lib_enc/find_uv_fx.c b/lib_enc/find_uv_fx.c index 79dc78c6d..c4fe2e895 100644 --- a/lib_enc/find_uv_fx.c +++ b/lib_enc/find_uv_fx.c @@ -729,7 +729,7 @@ Word16 find_uv_ivas_fx( /* o : coding typ * Total frame energy difference (dE3) *-----------------------------------------------------------------*/ - dE3 = sub( Etot, hNoiseEst->Etot_last_fx ); /*Q8*/ + dE3 = sub( Etot, extract_h( hNoiseEst->Etot_last_32fx ) ); /*Q8*/ /*-----------------------------------------------------------------* * Energy decrease after spike (dE2) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 67c4f256f..b9a15cd35 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -205,7 +205,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 S_map_fx[L_FFT / 2]; Word16 cor_map_sum_LR_fx[CPE_CHANNELS]; /* speech/music clasif. parameter */ Word16 S_map_LR_fx[L_FFT / 2]; /* short-term correlation map */ - Word16 Etot_fx; /* total energy Q8 */ + Word32 Etot_fx; /* total energy Q8 */ Word32 tmpN_fx[NB_BANDS]; /* Temporary noise update */ Word32 tmpE_fx[NB_BANDS]; /* Temporary averaged energy of 2 sf. */ Word32 tmpN_LR_fx[CPE_CHANNELS][NB_BANDS]; /* Temporary noise update */ @@ -739,7 +739,7 @@ ivas_error pre_proc_front_ivas_fx( IF( hStereoClassif != NULL ) { - IF( GT_32( sub( st->lp_speech_fx, Etot_fx ), 25 << Q8 ) ) /*Q8*/ + IF( GT_32( sub( st->lp_speech_fx, extract_h( Etot_fx ) ), 25 << Q8 ) ) /*Q8*/ { hStereoClassif->silence_flag = 2; move16(); @@ -759,11 +759,11 @@ ivas_error pre_proc_front_ivas_fx( IF( hCPE != NULL ) { - noise_est_pre_32fx( L_deposit_h( Etot_fx ), st->ini_frame, st->hNoiseEst, st->idchan, element_mode, hCPE->last_element_mode ); + noise_est_pre_32fx( ( Etot_fx ), st->ini_frame, st->hNoiseEst, st->idchan, element_mode, hCPE->last_element_mode ); } ELSE { - noise_est_pre_32fx( L_deposit_h( Etot_fx ), st->ini_frame, st->hNoiseEst, st->idchan, element_mode, element_mode ); + noise_est_pre_32fx( ( Etot_fx ), st->ini_frame, st->hNoiseEst, st->idchan, element_mode, element_mode ); } test(); @@ -913,18 +913,18 @@ ivas_error pre_proc_front_ivas_fx( *----------------------------------------------------------------*/ noise_est_down_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, &st->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, - &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_fx, &st->hNoiseEst->Etot_v_h2_fx ); + &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_32fx, &st->hNoiseEst->Etot_v_h2_fx ); test(); IF( lr_vad_enabled && st->idchan == 0 ) { - noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[0]->hNoiseEst->q_bckr, tmpN_LR_fx[0], &q_tmpN_LR[0], tmpE_LR_fx[0], &q_tmpE_LR[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, Etot_LR_fx[0], &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx ); - noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[1]->hNoiseEst->q_bckr, tmpN_LR_fx[1], &q_tmpN_LR[1], tmpE_LR_fx[1], &q_tmpE_LR[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, Etot_LR_fx[1], &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx ); + noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[0]->hNoiseEst->q_bckr, tmpN_LR_fx[0], &q_tmpN_LR[0], tmpE_LR_fx[0], &q_tmpE_LR[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_LR_fx[0] ), &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_32fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx ); + noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[1]->hNoiseEst->q_bckr, tmpN_LR_fx[1], &q_tmpN_LR[1], tmpE_LR_fx[1], &q_tmpE_LR[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_LR_fx[1] ), &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_32fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx ); corr_shiftL_fx = correlation_shift_fx( hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx ); // Q15 corr_shiftR_fx = correlation_shift_fx( hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx ); // Q15 } - *relE_fx = sub( Etot_fx, st->lp_speech_fx ); // Q8 + *relE_fx = sub( extract_h( Etot_fx ), st->lp_speech_fx ); // Q8 move16(); corr_shift_fx = correlation_shift_fx( st->hNoiseEst->totalNoise_fx ); /* Q15 */ @@ -1307,8 +1307,8 @@ ivas_error pre_proc_front_ivas_fx( move16(); move16(); - noise_est_ivas_fx( st, old_pitch1, tmpN_fx, epsP_fx, Etot_fx, *relE_fx, corr_shift_fx, tmpE_fx, q_tmpE, fr_bands_fx, fr_bands_fx_q, cor_map_sum_fx, - &ncharX_fx, &sp_div_fx, &q_sp_div, &non_staX_fx, loc_harm, lf_E_fx, q_lf_E_fx, &st->hNoiseEst->harm_cor_cnt, st->hNoiseEst->Etot_l_lp_fx, + noise_est_ivas_fx( st, old_pitch1, tmpN_fx, epsP_fx, extract_h( Etot_fx ), *relE_fx, corr_shift_fx, tmpE_fx, q_tmpE, fr_bands_fx, fr_bands_fx_q, cor_map_sum_fx, + &ncharX_fx, &sp_div_fx, &q_sp_div, &non_staX_fx, loc_harm, lf_E_fx, q_lf_E_fx, &st->hNoiseEst->harm_cor_cnt, extract_h( st->hNoiseEst->Etot_l_lp_32fx ), st->hNoiseEst->Etot_v_h2_fx, &st->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_fx, hStereoClassif, NULL, st->ini_frame ); @@ -1352,14 +1352,14 @@ ivas_error pre_proc_front_ivas_fx( noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[0], epsP_fx, Etot_LR_fx[0], sub( Etot_LR_fx[0], hCPE->hFrontVad[0]->lp_speech_fx ), corr_shiftL_fx, tmpE_LR_fx[0], q_tmpE_LR[0], fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], &cor_map_sum_LR_fx[0], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[0], lf_E_LR_fx_q, &hCPE->hFrontVad[0]->hNoiseEst->harm_cor_cnt, - hCPE->hFrontVad[0]->hNoiseEst->Etot_l_lp_fx, hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[0]->hNoiseEst->bg_cnt, + extract_h( hCPE->hFrontVad[0]->hNoiseEst->Etot_l_lp_32fx ), hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[0]->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[0], hCPE->hFrontVad[0]->ini_frame ); /* Note: the index [0] in the last argument is intended, the ini_frame counter is only maintained in the zero-th channel's VAD handle */ noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[1], epsP_fx, Etot_LR_fx[1], sub( Etot_LR_fx[1], hCPE->hFrontVad[1]->lp_speech_fx ), corr_shiftR_fx, tmpE_LR_fx[1], q_tmpE_LR[1], fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], &cor_map_sum_LR_fx[1], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[1], lf_E_LR_fx_q, &hCPE->hFrontVad[1]->hNoiseEst->harm_cor_cnt, - hCPE->hFrontVad[1]->hNoiseEst->Etot_l_lp_fx, hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[1]->hNoiseEst->bg_cnt, + extract_h( hCPE->hFrontVad[1]->hNoiseEst->Etot_l_lp_32fx ), hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[1]->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[1], hCPE->hFrontVad[0]->ini_frame ); } @@ -1387,7 +1387,7 @@ ivas_error pre_proc_front_ivas_fx( find_tilt_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, st->hNoiseEst->q_bckr, ee_fx, st->pitch, st->voicing_fx, lf_E_fx, q_lf_E_fx, corr_shift_fx, st->input_bwidth, st->max_band, hp_E_fx, MODE1, &( st->bckr_tilt_lt ), st->Opt_SC_VBR ); - st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, Etot_fx, hp_E_fx, + st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, extract_h( Etot_fx ), hp_E_fx, &flag_spitch, last_core_orig, hStereoClassif, *Q_new /*q_inp_12k8*/, fr_bands_fx_q ); // Q0 Copy_Scale_sig_16_32_no_sat( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); @@ -1461,7 +1461,7 @@ ivas_error pre_proc_front_ivas_fx( scale_sig32( PS_fx, 128, shift ); Qfact_PS = add( Qfact_PS, shift ); - smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, Etot_fx, lsp_new_fx, *cor_map_sum_fx /*Q8*/, epsP_fx, PS_fx, non_staX_fx, *relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, *epsP_fx_q, hSpMusClas->past_PS_Q ); /* Q0 */ + smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, extract_h( Etot_fx ), lsp_new_fx, *cor_map_sum_fx /*Q8*/, epsP_fx, PS_fx, non_staX_fx, *relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, *epsP_fx_q, hSpMusClas->past_PS_Q ); /* Q0 */ #ifdef DEBUG_FORCE_DIR if ( st->force_dir[0] != '\0' ) @@ -1495,7 +1495,7 @@ ivas_error pre_proc_front_ivas_fx( * Update of old per-band energy spectrum *----------------------------------------------------------------*/ - ivas_long_enr_fx( st, Etot_fx, localVAD_HE_SAD, high_lpn_flag, NULL, 1, NULL, NULL ); + ivas_long_enr_fx( st, extract_h( Etot_fx ), localVAD_HE_SAD, high_lpn_flag, NULL, 1, NULL, NULL ); Copy32( fr_bands_fx + NB_BANDS, st->hNoiseEst->enrO_fx, NB_BANDS ); /* fr_bands_fx_q */ st->hNoiseEst->q_enrO = fr_bands_fx_q; @@ -1676,7 +1676,7 @@ ivas_error pre_proc_front_ivas_fx( st->q_Bin_E = add( *Q_new, Q_SCALE - 2 ); move16(); /* 2nd stage speech/music classification (ACELP/GSC/TCX core selection) */ - ivas_smc_mode_selection_fx( st, element_brate, smc_dec, *relE_fx, Etot_fx, attack_flag, inp_12k8_fx, *Q_new, S_map_fx, flag_spitch ); + ivas_smc_mode_selection_fx( st, element_brate, smc_dec, *relE_fx, extract_h( Etot_fx ), attack_flag, inp_12k8_fx, *Q_new, S_map_fx, flag_spitch ); } #ifdef DEBUG_FORCE_DIR diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index b5ed69560..a05493aa4 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -735,8 +735,8 @@ ivas_error ivas_cpe_enc_fx( move16(); } - Etot_last_fx[0] = sts[0]->hNoiseEst->Etot_last_fx; /* Q8 */ - Etot_last_fx[1] = sts[1]->hNoiseEst->Etot_last_fx; /* Q8 */ + Etot_last_fx[0] = extract_h( sts[0]->hNoiseEst->Etot_last_32fx ); /* Q8 */ + Etot_last_fx[1] = extract_h( sts[1]->hNoiseEst->Etot_last_32fx ); /* Q8 */ move16(); move16(); } diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index f3cf05e63..124ab2996 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -90,6 +90,7 @@ ivas_error front_vad_fx( ivas_error error; Word16 Q_new; Word16 Qband, mem_decim_size; + Word32 Etot_LR_32fx; error = IVAS_ERR_OK; push_wmops( "front_vad" ); move16(); @@ -248,7 +249,7 @@ ivas_error front_vad_fx( move16(); ivas_analy_sp_fx( IVAS_CPE_TD, hCPE, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2 - 3 * ( L_SUBFR / 2 ), Q_new, fr_bands_fx[n], - &q_fr_bands[n], lf_E_fx[n], &q_lf_E[n], &Etot_LR_fx[n], sts[0]->min_band, sts[0]->max_band, Bin_E_fx, &q_Bin_E, Bin_E_old_fx, + &q_fr_bands[n], lf_E_fx[n], &q_lf_E[n], &Etot_LR_32fx, sts[0]->min_band, sts[0]->max_band, Bin_E_fx, &q_Bin_E, Bin_E_old_fx, &q_Bin_E_old, PS_fx, q_PS_out, lgBin_E_fx, band_energies_fx, &q_band_energies, fft_buffLR_fx, &q_fft_buffLR ); if ( n == 0 ) { @@ -275,9 +276,10 @@ ivas_error front_vad_fx( /* add up energies for later calculating average of channel energies */ - Word32 Etot_fx = L_deposit_h( Etot_LR_fx[n] ); /* Q24 */ + noise_est_pre_32fx( Etot_LR_32fx, hFrontVads[0]->ini_frame, hFrontVad->hNoiseEst, 0, 0, 0 ); - noise_est_pre_32fx( Etot_fx, hFrontVads[0]->ini_frame, hFrontVad->hNoiseEst, 0, 0, 0 ); + Etot_LR_fx[n] = extract_h( Etot_LR_32fx ); + move16(); /* wb_vad */ Word16 scale = s_min( q_fr_bands[n], add( hFrontVads[n]->hNoiseEst->q_enrO, L_norm_arr( hFrontVads[n]->hNoiseEst->enrO_fx, NB_BANDS ) ) ); @@ -611,7 +613,7 @@ ivas_error front_vad_spar_fx( Word16 q_tmpN, q_tmpE; noise_est_down_ivas_fx( fr_bands_fx[0], q_fr_bands[0], hFrontVad->hNoiseEst->bckr_fx, &hFrontVad->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, - &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); + &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_32fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ @@ -753,7 +755,7 @@ ivas_error front_vad_spar_fx( noise_est_ivas_fx( st, old_pitch, tmpN_fx, epsP_fx, Etot_fx[0], sub( Etot_fx[0], hFrontVad->lp_speech_fx ), corr_shift_fx, tmpE_fx, hFrontVad->hNoiseEst->ave_enr_q, fr_bands_fx[0], q_fr_bands[0], &cor_map_sum_fx, NULL, &sp_div_fx, &Q_sp_div, &non_staX_fx, &loc_harm, - lf_E_fx[0], q_lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, hFrontVad->hNoiseEst->Etot_l_lp_fx, hFrontVad->hNoiseEst->Etot_v_h2_fx, + lf_E_fx[0], q_lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, extract_h( hFrontVad->hNoiseEst->Etot_l_lp_32fx ), hFrontVad->hNoiseEst->Etot_v_h2_fx, &hFrontVad->hNoiseEst->bg_cnt, st->lgBin_E_fx, &sp_floor, S_map_fx, NULL, hFrontVad, hFrontVad->ini_frame ); MVR2R_WORD16( st->pitch, st->pitch, 3 ); diff --git a/lib_enc/ivas_stereo_td_analysis_fx.c b/lib_enc/ivas_stereo_td_analysis_fx.c index 1856370f6..909d0c206 100644 --- a/lib_enc/ivas_stereo_td_analysis_fx.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -340,8 +340,8 @@ Word16 stereo_tdm_ener_analysis_fx( test(); IF( ( LE_32( hStereoTD->tdm_lt_rms_L_fx, rms_thd_fx ) && LE_32( hStereoTD->tdm_lt_rms_R_fx, L_shl( rms_thd_fx, 1 ) ) ) || ( LE_32( hStereoTD->tdm_lt_rms_R_fx, rms_thd_fx ) && LE_32( hStereoTD->tdm_lt_rms_L_fx, L_shl( rms_thd_fx, 1 ) ) ) || - ( sts[0]->hVAD->hangover_cnt != 0 && LT_16( sts[1]->hNoiseEst->Etot_last_fx, 3072 /*12 in Q8*/ ) ) || - ( sts[1]->hVAD->hangover_cnt != 0 && LT_16( sts[0]->hNoiseEst->Etot_last_fx, 3072 /*12 in Q8*/ ) ) || + ( sts[0]->hVAD->hangover_cnt != 0 && LT_32( sts[1]->hNoiseEst->Etot_last_32fx, 201326592 /*12 in Q24*/ ) ) || + ( sts[1]->hVAD->hangover_cnt != 0 && LT_32( sts[0]->hNoiseEst->Etot_last_32fx, 201326592 /*12 in Q24*/ ) ) || ( NE_16( sts[0]->hSpMusClas->past_dec[0], sts[1]->hSpMusClas->past_dec[0] ) ) ) { test(); @@ -873,8 +873,8 @@ static Word16 Get_dt_lt_ener_fx( move32(); *tdm_lt_rms_R = L_shl( Mpy_32_32( 1932735282 /* 0.9f in Q31 */, rms_R ), sub( Q16, q_rms_R ) ); // (Q31, q_rms_R) -> q_rms_R -> Q16 move32(); - L_tmp = Mpy_32_16_1( 1932735282 /* 0.9f in Q31 */, sts[0]->hNoiseEst->Etot_last_fx ); //(Q31, Q8) -> Q24 - sts[1]->hNoiseEst->Etot_last_fx = extract_h( L_tmp ); // (Q24 >> Q16) -> Q8 + L_tmp = Mpy_32_32( 1932735282 /* 0.9f in Q31 */, sts[0]->hNoiseEst->Etot_last_32fx ); //(Q31, Q24) -> Q24 + sts[1]->hNoiseEst->Etot_last_32fx = L_tmp; // (Q24 >> Q16) -> Q8 sts[1]->hVAD->hangover_cnt = 0; move16(); } diff --git a/lib_enc/long_enr_fx.c b/lib_enc/long_enr_fx.c index af57edd3b..60c40b3fe 100644 --- a/lib_enc/long_enr_fx.c +++ b/lib_enc/long_enr_fx.c @@ -94,7 +94,7 @@ void ivas_long_enr_fx( } FOR( n = 0; n < n_chan; n++ ) { - hFrontVad[n]->hNoiseEst->Etot_last_fx = Etot_LR[n]; /* Q8 */ + hFrontVad[n]->hNoiseEst->Etot_last_32fx = L_deposit_h( Etot_LR[n] ); /* Q24 */ move16(); } } @@ -141,7 +141,7 @@ void ivas_long_enr_fx( } } /* Update */ - st_fx->hNoiseEst->Etot_last_fx = Etot; /* Q8 */ + st_fx->hNoiseEst->Etot_last_32fx = L_deposit_h( Etot ); /* Q24 */ move16(); } diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index c8f698da9..d8131f10e 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -359,8 +359,8 @@ void noise_est_init_ivas_fx( hNoiseEst->Etot_lp_fx = 0; hNoiseEst->Etot_h_fx = 0; hNoiseEst->Etot_l_fx = 0; - hNoiseEst->Etot_l_lp_fx = 0; - hNoiseEst->Etot_last_fx = 0; + hNoiseEst->Etot_l_lp_32fx = 0; + hNoiseEst->Etot_last_32fx = 0; hNoiseEst->Etot_v_h2_fx = 0; hNoiseEst->sign_dyn_lp_fx = 0; move16(); @@ -368,8 +368,8 @@ void noise_est_init_ivas_fx( move16(); move16(); move16(); - move16(); - move16(); + move32(); + move32(); return; } @@ -510,10 +510,10 @@ void noise_est_pre_32fx( move32(); Etot_l_32fx = Etot; move32(); - hNoiseEst->Etot_l_lp_fx = extract_h( Etot ); // Q8 - move16(); - hNoiseEst->Etot_last_fx = extract_h( Etot ); // Q8 - move16(); + hNoiseEst->Etot_l_lp_32fx = Etot; // Q24 + move32(); + hNoiseEst->Etot_last_32fx = Etot; // Q24 + move32(); hNoiseEst->Etot_v_h2_fx = 0; move16(); Etot_lp_32fx = Etot; @@ -538,20 +538,20 @@ void noise_est_pre_32fx( ) { /* *Etot_l += min(2,(*Etot_last-*Etot_l)*0.1f); */ - tmp = Mpy_32_32( L_sub( L_deposit_h( hNoiseEst->Etot_last_fx ), Etot_l_32fx ), 214748365 ); /* 0.1f factor in Q31 */ - tmp = L_min( 33554432, tmp ); /* 2.0 in Q24 is 33554432 */ - Etot_l_32fx = L_add( Etot_l_32fx, tmp ); /* Q24 */ + tmp = Mpy_32_32( L_sub( ( hNoiseEst->Etot_last_32fx ), Etot_l_32fx ), 214748365 ); /* 0.1f factor in Q31 */ + tmp = L_min( 33554432, tmp ); /* 2.0 in Q24 is 33554432 */ + Etot_l_32fx = L_add( Etot_l_32fx, tmp ); /* Q24 */ } /* Avoids large steps in short active segments */ test(); - IF( ( GT_32( L_sub( L_deposit_h( hNoiseEst->Etot_last_fx ), Etot_l_32fx ), 503316480 ) ) /* 30.0f*Q24 */ + IF( ( GT_32( L_sub( hNoiseEst->Etot_last_32fx, Etot_l_32fx ), 503316480 ) ) /* 30.0f*Q24 */ && ( GT_16( hNoiseEst->harm_cor_cnt, HE_LT_CNT_PRE_SHORT_FX ) ) ) { /* *Etot_l += (*Etot_last-*Etot_l)*0.02f; */ - Etot_l_32fx = L_add( Etot_l_32fx, Mpy_32_32( L_sub( L_deposit_h( hNoiseEst->Etot_last_fx ), Etot_l_32fx ), 42949673 ) ); /* 0.02 in Q24*/ + Etot_l_32fx = L_add( Etot_l_32fx, Mpy_32_32( L_sub( hNoiseEst->Etot_last_32fx, Etot_l_32fx ), 42949673 ) ); /* 0.02 in Q24*/ } - ELSE IF( GT_32( L_sub( L_deposit_h( hNoiseEst->Etot_last_fx ), Etot_l_32fx ), 167772160 ) ) /* 10.0 in Q24*/ + ELSE IF( GT_32( L_sub( hNoiseEst->Etot_last_32fx, Etot_l_32fx ), 167772160 ) ) /* 10.0 in Q24*/ { Etot_l_32fx = L_add( Etot_l_32fx, 1342177 ); /* 0.08 in Q24*/ } @@ -560,10 +560,10 @@ void noise_est_pre_32fx( Etot_l_32fx = L_min( Etot_l_32fx, Etot ); // Q24 test(); - IF( LT_16( ini_frame_fx, 100 ) && LT_32( Etot_l_32fx, L_deposit_h( hNoiseEst->Etot_l_lp_fx ) ) ) + IF( LT_16( ini_frame_fx, 100 ) && LT_32( Etot_l_32fx, ( hNoiseEst->Etot_l_lp_32fx ) ) ) { /**Etot_l_lp = 0.1f * *Etot_l + (1.0f - 0.1) * *Etot_l_lp; */ - hNoiseEst->Etot_l_lp_fx = extract_h( L_add( Mpy_32_32( 214748364 /* 0.1f in Q31*/, Etot_l_32fx ), Mpy_32_32( 1932735283 /* 0.9f in Q31*/, L_deposit_h( hNoiseEst->Etot_l_lp_fx ) ) ) ); // Q8 + hNoiseEst->Etot_l_lp_32fx = W_round64_L( W_add( W_mult_32_32( 214748364 /* 0.1f in Q31*/, Etot_l_32fx ), W_mult_32_32( 1932735283 /* 0.9f in Q31*/, hNoiseEst->Etot_l_lp_32fx ) ) ); // Q8 move16(); } ELSE @@ -572,16 +572,16 @@ void noise_est_pre_32fx( test(); test(); test(); - IF( ( ( GT_16( hNoiseEst->harm_cor_cnt, HE_LT_CNT_FX ) ) && ( GT_32( L_sub_sat( L_deposit_h( hNoiseEst->Etot_last_fx ), Etot_l_32fx ), HE_LT_THR2_Q24 ) ) ) || ( ( sub( hNoiseEst->harm_cor_cnt, HE_LT_CNT_FX ) > 0 ) && ( LT_16( ini_frame_fx, HE_LT_CNT_INIT_FX ) ) ) || ( GT_32( L_sub_sat( L_deposit_h( hNoiseEst->Etot_l_lp_fx ), Etot_l_32fx ), HE_LT_THR2_Q24 ) ) ) + IF( ( ( GT_16( hNoiseEst->harm_cor_cnt, HE_LT_CNT_FX ) ) && ( GT_32( L_sub_sat( hNoiseEst->Etot_last_32fx, Etot_l_32fx ), HE_LT_THR2_Q24 ) ) ) || ( ( sub( hNoiseEst->harm_cor_cnt, HE_LT_CNT_FX ) > 0 ) && ( LT_16( ini_frame_fx, HE_LT_CNT_INIT_FX ) ) ) || ( GT_32( L_sub_sat( hNoiseEst->Etot_l_lp_32fx, Etot_l_32fx ), HE_LT_THR2_Q24 ) ) ) { /**Etot_l_lp = 0.03f * *Etot_l + (1.0f - 0.03f) * *Etot_l_lp; */ - hNoiseEst->Etot_l_lp_fx = extract_h( L_add( Mpy_32_32( 64424509 /* 0.03f in Q31*/, Etot_l_32fx ), Mpy_32_32( 2083059139 /* 0.97f in Q31*/, L_deposit_h( hNoiseEst->Etot_l_lp_fx ) ) ) ); // Q8 + hNoiseEst->Etot_l_lp_32fx = W_extract_h( W_add( W_mult_32_32( 64424509 /* 0.03f in Q31*/, Etot_l_32fx ), W_mult_32_32( 2083059139 /* 0.97f in Q31*/, hNoiseEst->Etot_l_lp_32fx ) ) ); // Q24 move16(); } ELSE { /* *Etot_l_lp = 0.02f * *Etot_l + (1.0f - 0.02f) * *Etot_l_lp; */ - hNoiseEst->Etot_l_lp_fx = extract_h( L_add( Mpy_32_32( 42949673 /* 0.02f in Q31*/, Etot_l_32fx ), Mpy_32_32( 2104533975 /* 0.98f in Q31*/, L_deposit_h( hNoiseEst->Etot_l_lp_fx ) ) ) ); // Q8 + hNoiseEst->Etot_l_lp_32fx = W_extract_h( W_add( W_mult_32_32( 42949673 /* 0.02f in Q31*/, Etot_l_32fx ), W_mult_32_32( 2104533975 /* 0.98f in Q31*/, hNoiseEst->Etot_l_lp_32fx ) ) ); // Q24 move16(); } } @@ -748,8 +748,8 @@ void noise_est_down_ivas_fx( const Word16 min_band, /* i : minimum critical band */ const Word16 max_band, /* i : maximum critical band */ Word16 *totalNoise, /* o : noise estimate over all critical bands */ - Word16 Etot, /* i : Energy of current frame */ - Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word32 Etot, /* i : Energy of current frame */ + Word32 *Etot_last, /* i/o: Energy of last frame Q8 */ Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ ) @@ -770,8 +770,9 @@ void noise_est_down_ivas_fx( Copy32( bckr, bckr32, NB_BANDS ); set16_fx( bckr_q, *q_bckr, NB_BANDS ); - L_Etot = L_shl( Etot, 16 ); /*Q24 for later AR1 computations*/ - L_Etot_last = L_shl( *Etot_last, 16 ); + L_Etot = Etot; /*Q24 for later AR1 computations*/ + move32(); + L_Etot_last = *Etot_last; L_Etot_v_h2 = L_shl( *Etot_v_h2, 16 ); /*-----------------------------------------------------------------* @@ -2989,7 +2990,7 @@ void noise_est_ivas_fx( move16(); /* st->lt_Ellp_dist = 0.03f* (Etot - st->Etot_l_lp) + 0.97f*st->lt_Ellp_dist;*/ - tmp = sub( Etot, hNoiseEst->Etot_l_lp_fx ); /* Q8 */ + tmp = sub( Etot, extract_h( hNoiseEst->Etot_l_lp_32fx ) ); /* Q8 */ hNoiseEst->lt_Ellp_dist_fx = mac_r( L_mult( tmp, 983 /* 0.03 in Q15*/ ), hNoiseEst->lt_Ellp_dist_fx, 31785 /* 0.97 in Q15*/ ); // Q8 move16(); @@ -3180,7 +3181,7 @@ void noise_est_ivas_fx( { tmp = shl( tmp, 1 ); /*1.5 + 1.5 Q13 */ } - Ltmp = L_deposit_h( hNoiseEst->Etot_l_lp_fx ); + Ltmp = hNoiseEst->Etot_l_lp_32fx; Etot_l_lp_thr = round_fx( L_add( Ltmp, L_shl( L_mult( tmp, Etot_v_h2 ), 2 ) ) ); /* Q13+Q8+1 +2 = Q24 -> Q8*/ /* enr_bgd = Etot < Etot_l_lp_thr; */ @@ -3365,8 +3366,8 @@ void noise_est_ivas_fx( move16(); test(); test(); - if ( ( GT_16( hNoiseEst->sign_dyn_lp_fx, 15 * 256 ) ) /* 15 in Q8 */ - && ( LT_16( sub( Etot, hNoiseEst->Etot_l_lp_fx ), shl( Etot_v_h2, 1 ) ) ) /* Q8 , Etot_v_h2 has limited dynmics can be upscaled*/ + if ( ( GT_16( hNoiseEst->sign_dyn_lp_fx, 15 * 256 ) ) /* 15 in Q8 */ + && ( LT_16( sub( Etot, extract_h( hNoiseEst->Etot_l_lp_32fx ) ), shl( Etot_v_h2, 1 ) ) ) /* Q8 , Etot_v_h2 has limited dynmics can be upscaled*/ && ( GT_16( *st_harm_cor_cnt, 20 ) ) ) { sd1_bgd = 1; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 120dd42b5..4237aa9c3 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -369,8 +369,8 @@ void noise_est_down_ivas_fx( const Word16 min_band, /* i : minimum critical band */ const Word16 max_band, /* i : maximum critical band */ Word16 *totalNoise, /* o : noise estimate over all critical bands */ - Word16 Etot, /* i : Energy of current frame */ - Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word32 Etot, /* i : Energy of current frame */ + Word32 *Etot_last, /* i/o: Energy of last frame Q8 */ Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ ); @@ -2230,7 +2230,7 @@ void ivas_analy_sp_fx( Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ Word32 *lf_E, /* o : per bin E for first... q_lf_E */ Word16 *q_lf_E, /* o : per bin E for first... Q0 */ - Word16 *Etot, /* o : total input energy Q8 */ + Word32 *Etot, /* o : total input energy Q24 */ const Word16 min_band, /* i : minimum critical band Q0 */ const Word16 max_band, /* i : maximum critical band Q0 */ Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index c6176709b..4fe5bb8a4 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -545,8 +545,10 @@ typedef struct noise_estimation_structure Word16 bg_cnt; /* Noise estimator - pause length counter */ Word16 Etot_l_fx; /* Q8 Noise estimator - Track energy from below */ Word16 Etot_h_fx; /* Q8 Noise estimator - Track energy from above */ - Word16 Etot_l_lp_fx; /* Q8 Noise estimator - Smoothed low energy */ - Word16 Etot_last_fx; /*Q8*/ + Word16 Etot_l_lp_fx; /* EVS- Q8 Noise estimator - Smoothed low energy */ + Word32 Etot_l_lp_32fx; /* IVAS-Q24 Noise estimator - Smoothed low energy */ + Word16 Etot_last_fx; /*EVS- Q8*/ + Word32 Etot_last_32fx; /* IVAS - Q24*/ Word16 Etot_lp_fx; /* Q8 Noise estimator - Filtered input energy */ Word16 lt_tn_track_fx; /* Q15 */ diff --git a/lib_enc/updt_enc_fx.c b/lib_enc/updt_enc_fx.c index fb2a6215b..1210bfd04 100644 --- a/lib_enc/updt_enc_fx.c +++ b/lib_enc/updt_enc_fx.c @@ -362,7 +362,14 @@ void updt_enc_common_fx( move16(); st->last_bwidth = st->bwidth; move16(); - st->hNoiseEst->Etot_last_fx = Etot; + IF( GT_16( st->element_mode, EVS_MONO ) ) + { + st->hNoiseEst->Etot_last_32fx = L_deposit_h( Etot ); + } + ELSE + { + st->hNoiseEst->Etot_last_fx = Etot; + } move16(); st->last_coder_type_raw = st->coder_type_raw; move16(); -- GitLab From 349ac68863f3031e5bae907dacb9057e43856504 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 23 Apr 2025 17:10:00 +0530 Subject: [PATCH 1105/1221] Fix for 3GPP issue 1487: Basop Encoder: Stereo DTX Front VAD Flag Mismatch Link #1487 --- lib_enc/nois_est_fx.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index c8f698da9..2e03f40a9 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -2253,6 +2253,7 @@ void noise_est_ivas_fx( Word16 tmp_enr, tmp_floor; /* constants in Q8 */ Word16 vad_bwidth_fx; /* vad ns control variabel for input bwidth from teh BWD */ /* for DTX operation */ + Word32 L_tmp; Word16 lim_Etot_fx; /* Q8 */ Word32 lim_Etot_sq_fx; /* Q16 */ @@ -3001,7 +3002,7 @@ void noise_est_ivas_fx( } */ IF( *st_harm_cor_cnt == 0 ) { - hNoiseEst->lt_haco_ev_fx = mac_r( 64424509 /* 0.03 in Q32*/, hNoiseEst->lt_haco_ev_fx, 31785 /* 0.97 in Q15*/ ); // Q15 + hNoiseEst->lt_haco_ev_fx = mac_r( 64424509 /* 0.03 in Q31*/, hNoiseEst->lt_haco_ev_fx, 31785 /* 0.97 in Q15*/ ); // Q15 move16(); } ELSE @@ -3558,14 +3559,14 @@ void noise_est_ivas_fx( } /*st->lt_aEn_zero = 0.2f * (st->aEn==0) + (1-0.2f) *st->lt_aEn_zero;*/ /* y(n+1)= alpha*tmp + (1-alpha)*y(n) */ - tmp = 0; - move16(); + L_tmp = 0; + move32(); if ( hNoiseEst->aEn == 0 ) { - tmp = 6554; // 0.2 in Q15 - move16(); + L_tmp = 429496730; // 0.2 in Q31 + move32(); } - hNoiseEst->lt_aEn_zero_fx = mac_r( tmp, hNoiseEst->lt_aEn_zero_fx, 26214 /* 0.8 in Q15*/ ); // Q15 + hNoiseEst->lt_aEn_zero_fx = mac_r( L_tmp, hNoiseEst->lt_aEn_zero_fx, 26214 /* 0.8 in Q15*/ ); // Q15 move16(); IF( st_fx->element_mode > EVS_MONO ) -- GitLab From 378ba3b0fea391be2efeffe706c7fae3c064f760 Mon Sep 17 00:00:00 2001 From: rtyag Date: Thu, 24 Apr 2025 11:26:14 +1000 Subject: [PATCH 1106/1221] increase instrumentation build timeout to 10 mins --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0b7fe26eb..73af86312 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1002,7 +1002,7 @@ build-codec-linux-instrumented-make: when: never extends: - .build-job-linux - timeout: "7 minutes" + timeout: "10 minutes" script: - *print-common-info - *update-scripts-repo -- GitLab From d380e91f41bac21f7b4a96e1b776fb8d53a75304 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 24 Apr 2025 12:35:36 +0530 Subject: [PATCH 1107/1221] Fix for 3GPP issue 1507: BASOP decoder asserts in ivas_hq_phase_ecu_fx with OMASA FER bitstream from BASOP encoder Link #1507 --- lib_dec/ivas_stereo_dft_plc_fx.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index 90d9c5823..3fed308b2 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -188,6 +188,8 @@ Word32 imax_pos_fx( Word32 posi, y1, y2, y3, y3_y1, y2i; Word32 ftmp_den1, ftmp_den2; Word16 q_div_2i, q_div_posi; + Word64 W_tmp; + Word16 shift1, shift2; /* Seek the extrema of the parabola P(x) defined by 3 consecutive points so that P([-1 0 1]) = [y1 y2 y3] */ y1 = y[0]; /* Qx */ move32(); @@ -195,9 +197,13 @@ Word32 imax_pos_fx( move32(); y3 = y[2]; /* Qx */ move32(); - y3_y1 = L_sub( y3, y1 ); /* Qx */ - ftmp_den1 = L_sub( L_add( y1, y3 ), L_shl( y2, 1 ) ); /* Qx */ - ftmp_den2 = L_shl( L_sub( L_sub( L_shl( y2, 1 ), y1 ), y3 ), 1 ); /* Qx */ + y3_y1 = L_sub( y3, y1 ); /* Qx */ + W_tmp = W_sub( W_add( y1, y3 ), W_shl( y2, 1 ) ); /* Qx */ + shift1 = W_norm( W_tmp ); + ftmp_den1 = W_extract_h( W_shl( W_tmp, shift1 ) ); /* Qx + shift1 - 32 */ + W_tmp = W_shl( W_sub( W_sub( W_shl( y2, 1 ), y1 ), y3 ), 1 ); /* Qx */ + shift2 = W_norm( W_tmp ); + ftmp_den2 = W_extract_h( W_shl( W_tmp, shift2 ) ); /* Qx + shift2 - 32 */ test(); IF( ( ftmp_den2 == 0 ) || ( ftmp_den1 == 0 ) ) @@ -206,6 +212,7 @@ Word32 imax_pos_fx( } y2i = Mpy_32_16_1( Mpy_32_16_1( y3_y1, BASOP_Util_Divide3232_Scale( y3_y1, ftmp_den1, &q_div_2i ) ), (Word16) ( 0xF000 ) ); /* q_div_2i */ + q_div_2i = sub( add( q_div_2i, shift1 ), 32 ); IF( q_div_2i < 0 ) { y2i = L_shl( y2i, q_div_2i ); @@ -219,6 +226,7 @@ Word32 imax_pos_fx( } /* their corresponding normalized locations */ posi = BASOP_Util_Divide3232_Scale( y3_y1, ( ftmp_den2 ), &q_div_posi ); /* q_div_posi */ + q_div_posi = sub( add( q_div_posi, shift2 ), 32 ); IF( ( q_div_posi != 0 ) ) { posi = L_shl( posi, q_div_posi ); -- GitLab From 4497161299ef1dede088c335652edca3d7d9aa8f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 24 Apr 2025 09:06:20 +0200 Subject: [PATCH 1108/1221] increase timeout for build jobs --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 73af86312..4e7d36f24 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -986,6 +986,7 @@ build-codec-linux-make: when: never extends: - .build-job-linux + timeout: "10 minutes" script: - *print-common-info - *activate-Werror-linux @@ -1019,7 +1020,7 @@ build-codec-linux-debugging-make: when: never extends: - .build-job-linux - timeout: "7 minutes" + timeout: "10 minutes" variables: BUILD_WITH_DEBUG_MODE_INFO: "true" script: @@ -1037,7 +1038,7 @@ build-codec-windows-msbuild: when: never extends: - .build-job-windows - timeout: "7 minutes" + timeout: "10 minutes" tags: - ivas-windows script: -- GitLab From 633745fa5271180e9f2687d2544bf5588f159fcd Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 24 Apr 2025 12:30:34 +0530 Subject: [PATCH 1109/1221] Changes to address 3GPP issue 1276 --- lib_enc/init_enc_fx.c | 9 ++++ lib_enc/ivas_core_pre_proc_front_fx.c | 70 ++++++++++++++------------ lib_enc/ivas_stereo_mdct_core_enc_fx.c | 2 +- lib_enc/stat_enc.h | 15 ++++-- 4 files changed, 58 insertions(+), 38 deletions(-) diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index e200d0f00..98d7fe957 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1184,6 +1184,8 @@ ivas_error init_encoder_ivas_fx( st->mem_preemph_fx = 0; move16(); + st->mem_preemph_fx_q_inp = 0; + move16(); st->mem_preemph16k_fx = 0; move16(); st->mem_preemph_enc = 0; @@ -1298,6 +1300,8 @@ ivas_error init_encoder_ivas_fx( /* stereo switching memories */ st->mem_preemph_DFT_fx = 0; move16(); + st->mem_preemph_DFT_fx_q_inp = 0; + move16(); set16_fx( st->inp_12k8_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_12k8, L_MEM_RECALC_12K8 ), L_FILT ) ); st->mem_preemph16k_DFT_fx = 0; move16(); @@ -1397,6 +1401,7 @@ ivas_error init_encoder_ivas_fx( st->q_Bin_E_old = Q31; move16(); set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); + set16_fx( st->mem_decim_fx_q_inp, 0, shl( L_FILT_MAX, 1 ) ); set16_fx( st->mem_decim16k_fx, 0, shl( L_FILT_MAX, 1 ) ); set16_fx( st->old_inp_12k8_fx, 0, L_INP_MEM ); set16_fx( st->old_inp_16k_fx, 0, L_INP_MEM ); @@ -1410,6 +1415,10 @@ ivas_error init_encoder_ivas_fx( set16_fx( st->input_buff_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); st->q_inp = Q15; move16(); + st->mem_preemph_q = Q15; + move16(); + st->mem_q = Q15; + move16(); st->q_old_inp = Q15; move16(); set32_fx( st->input_buff32_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index b9a15cd35..3d7d87bc2 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -499,15 +499,16 @@ ivas_error pre_proc_front_ivas_fx( * Change the sampling frequency to 12.8 kHz * (if not available from downsampled DMX) *----------------------------------------------------------------*/ - - Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( st->q_inp, Q_inp_const ) ); /* st->q_inp */ + Scale_sig( st->mem_decim_fx_q_inp, 2 * L_FILT_MAX, sub( st->q_inp, st->mem_q ) ); /* st->q_inp */ test(); + IF( EQ_16( element_mode, IVAS_SCE ) ) { - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_12k8_fx, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ - Scale_sig( new_inp_12k8_fx, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ - - Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_12k8_fx, INT_FS_12k8, st->mem_decim_fx_q_inp, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ + st->mem_q = st->q_inp; + move16(); + Copy( st->mem_decim_fx_q_inp, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* st->q_inp */ Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ @@ -521,13 +522,15 @@ ivas_error pre_proc_front_ivas_fx( Word16 length_inp = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS ); Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); /* st->q_inp */ - Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx_q_inp, 0, &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ } - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ - Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* st->q_inp */ - Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8, INT_FS_12k8, st->mem_decim_fx_q_inp, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* st->q_inp */ + st->mem_q = st->q_inp; + move16(); + Copy( st->mem_decim_fx_q_inp, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* st->q_inp */ + Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to st->q_inp*/ IF( lMemRecalc > 0 ) { @@ -541,10 +544,13 @@ ivas_error pre_proc_front_ivas_fx( ELSE /* DFT stereo */ { /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ + Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx_q_inp, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ + st->mem_q = st->q_inp; + move16(); scale_sig( old_inp_12k8_fx, L_INP_MEM - STEREO_DFT_OVL_12k8, sub( Q_inp_const, st->q_inp ) ); scale_sig( st->input_fx - input_frame, input_frame_full, sub( Q_inp_const, st->q_inp ) ); - Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ + Copy_Scale_sig( st->mem_decim_fx_q_inp, st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ + // Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ st->q_inp = Q_inp_const; move16(); st->q_old_inp = Q_inp_const; @@ -552,7 +558,7 @@ ivas_error pre_proc_front_ivas_fx( } IF( NE_16( Q_inp_const, st->q_inp ) ) { - Scale_sig( st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ + Copy_Scale_sig( st->mem_decim_fx_q_inp, st->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp_const, st->q_inp ) ); /* Q(-1) */ } Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( -1, sub( 15, st->exp_buf_speech_enc ) ) ); /* Q(-1) */ @@ -585,24 +591,23 @@ ivas_error pre_proc_front_ivas_fx( headroom = 2; move16(); - - st->mem_preemph_fx = shl_sat( st->mem_preemph_fx, sub( st->q_inp, -1 ) ); /*st->q_inp*/ + st->mem_preemph_fx_q_inp = shl_sat( st->mem_preemph_fx_q_inp, sub( st->q_inp, st->mem_preemph_q ) ); /*st->q_inp*/ move16(); - st->mem_preemph_DFT_fx = shl_sat( st->mem_preemph_DFT_fx, sub( st->q_inp, -1 ) ); /*st->q_inp*/ + st->mem_preemph_DFT_fx_q_inp = shl_sat( st->mem_preemph_DFT_fx_q_inp, sub( st->q_inp, st->mem_preemph_q ) ); /*st->q_inp*/ move16(); test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { Copy_Scale_sig( new_inp_12k8_fx - STEREO_DFT_OVL_12k8 + L_FRAME, st->inp_12k8_mem_stereo_sw_fx, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, sub( Q_inp_const, st->q_inp ) ); /* memory for TD/DFT stereo switching Q_inp_const*/ - st->mem_preemph_fx = st->mem_preemph_DFT_fx; /* st->q_inp */ + st->mem_preemph_fx_q_inp = st->mem_preemph_DFT_fx_q_inp; /* st->q_inp */ move16(); - st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* st->q_inp */ + st->mem_preemph_DFT_fx_q_inp = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* st->q_inp */ move16(); // PREEMPH_FX( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - PREEMPH_32FX( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, sig_out, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - dummy_fx = st->mem_preemph_fx; + PREEMPH_32FX( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, sig_out, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx_q_inp ); + dummy_fx = st->mem_preemph_fx_q_inp; move16(); // PREEMPH_FX( new_inp_12k8_fx - STEREO_DFT_OVL_12k8 + L_FRAME, PREEMPH_FAC, STEREO_DFT_OVL_12k8, &dummy_fx ); @@ -618,18 +623,18 @@ ivas_error pre_proc_front_ivas_fx( { IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { - st->mem_preemph_fx = st->mem_preemph_DFT_fx; /* st->q_inp */ + st->mem_preemph_fx_q_inp = st->mem_preemph_DFT_fx_q_inp; /* st->q_inp */ move16(); Copy_Scale_sig( st->inp_12k8_mem_stereo_sw_fx, new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, sub( st->q_inp, Q_inp_const ) ); /* st->q_inp */ // PREEMPH_FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx ); - PREEMPH_32FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), sig_out, PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx ); + PREEMPH_32FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), sig_out, PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx_q_inp ); preemp_start_idx = new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); move16(); preemp_len = STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT; move16(); } - st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* st->q_inp */ + st->mem_preemph_DFT_fx_q_inp = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* st->q_inp */ move16(); } @@ -640,15 +645,15 @@ ivas_error pre_proc_front_ivas_fx( Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); move16(); // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx ); - PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, sig_out, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx ); + PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, sig_out, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx_q_inp ); preemp_start_idx = new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8; preemp_len = length_12k8; move16(); } // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8, sig_out + preemp_len, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - dummy_fx = st->mem_preemph_fx; /* st->q_inp */ + PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8, sig_out + preemp_len, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx_q_inp ); + dummy_fx = st->mem_preemph_fx_q_inp; /* st->q_inp */ move16(); // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8 + L_FRAME, PREEMPH_FAC, lMemRecalc_12k8 + L_FILT, &dummy_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 + L_FRAME, sig_out + preemp_len + L_FRAME, PREEMPH_FAC, lMemRecalc_12k8 + L_FILT, &dummy_fx ); @@ -669,8 +674,8 @@ ivas_error pre_proc_front_ivas_fx( ELSE /* IVAS_SCE or IVAS_CPE_MDCT */ { // PREEMPH_FX( new_inp_12k8_fx, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - PREEMPH_32FX( new_inp_12k8_fx, sig_out, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - dummy_fx = st->mem_preemph_fx; + PREEMPH_32FX( new_inp_12k8_fx, sig_out, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx_q_inp ); + dummy_fx = st->mem_preemph_fx_q_inp; move16(); // PREEMPH_FX( new_inp_12k8_fx + L_FRAME, PREEMPH_FAC, L_FILT, &dummy_fx ); PREEMPH_32FX( new_inp_12k8_fx + L_FRAME, sig_out + L_FRAME, PREEMPH_FAC, L_FILT, &dummy_fx ); @@ -678,11 +683,12 @@ ivas_error pre_proc_front_ivas_fx( preemp_len = L_FRAME + L_FILT; move16(); } - st->mem_preemph_fx = shl_sat( st->mem_preemph_fx, sub( -1, st->q_inp ) ); /*Q(-1) saturation added as float value goes above 65536 for +10 dB test (ltv48_MC512.wav and ltv48_MC51.wav) */ + st->mem_preemph_fx = shl_sat( st->mem_preemph_fx_q_inp, sub( -1, st->q_inp ) ); /*Q(-1) saturation added as float value goes above 65536 for +10 dB test (ltv48_MC512.wav and ltv48_MC51.wav) */ move16(); - st->mem_preemph_DFT_fx = shl( st->mem_preemph_DFT_fx, sub( -1, st->q_inp ) ); /*Q(-1)*/ + st->mem_preemph_DFT_fx = shl( st->mem_preemph_DFT_fx_q_inp, sub( -1, st->q_inp ) ); /*Q(-1)*/ + move16(); + st->mem_preemph_q = st->q_inp; move16(); - maximum_abs_32_fx( sig_out, preemp_len, &max_32 ); inp_max = s_max( extract_h( max_32 ), 1 ); diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 1bd5c936b..8acbc3e87 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -370,7 +370,7 @@ void stereo_mdct_core_enc_fx( } } - exp1 = add( exp1, 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */ + exp1 = add( exp1, 2 ); /* 2 guard bit to avoid over-flows in stereo_coder_tcx_fx */ exp2 = add( exp2, 2 ); /* 2 guard bit to avoid over-flows in stereo_coder_tcx_fx (ms_processing_fx) */ FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 4fe5bb8a4..45ec01b31 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1361,7 +1361,10 @@ typedef struct enc_core_structure Word16 no_scales_fx[MAX_NO_MODES][2]; /* LSF LVQ structure Q0*/ Word16 no_scales_p_fx[MAX_NO_MODES_p][2]; /* LSF LVQ structure Q0*/ - Word16 mem_preemph_fx; /* preemphasis filter memory Q(-1) */ + Word16 mem_preemph_fx; /* preemphasis filter memory Q(-1) */ + Word16 mem_q; /* preemphasis filter memory Q(-1) */ + Word16 mem_preemph_q; /* preemphasis filter memory Q(-1) */ + Word16 mem_preemph_fx_q_inp; /* preemphasis filter memory Q(-1) */ Word16 old_wsp_fx[L_WSP_MEM]; /* old weighted signal vector */ Word16 exp_old_wsp; @@ -1460,10 +1463,11 @@ typedef struct enc_core_structure SIGNAL_BUFFERS_ENC_HANDLE hSignalBuf; Word32 *Bin_E_old_fx; /* per bin energy of old 2nd frames */ Word16 q_Bin_E_old; - Word16 *mem_decim_fx; /* decimation filter memory Q(-1) */ - Word16 *mem_decim16k_fx; /* ACELP@16kHz - decimation filter memory @16kHz Q(-1) */ - Word16 *old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ - Word16 *old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ + Word16 *mem_decim_fx; /* decimation filter memory Q(-1) */ + Word16 mem_decim_fx_q_inp[2 * L_FILT_MAX]; /* decimation filter memory Q(-1) */ + Word16 *mem_decim16k_fx; /* ACELP@16kHz - decimation filter memory @16kHz Q(-1) */ + Word16 *old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ + Word16 *old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ Word16 *buf_speech_enc_pe; // exp_buf_speech_enc_pe Word16 *buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ @@ -1773,6 +1777,7 @@ typedef struct enc_core_structure /* stereo switching memories */ Word16 mem_preemph_DFT_fx; /* Q(-1) */ + Word16 mem_preemph_DFT_fx_q_inp; /* Q(-1) */ Word16 inp_12k8_mem_stereo_sw_fx[STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT]; /* Q(-1) */ Word16 mem_preemph16k_DFT_fx; /* Q(-1) */ Word16 inp_16k_mem_stereo_sw_fx[STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k]; /* Q(-1) */ -- GitLab From 92fc63690bd364029401987607c5eced0644944c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 24 Apr 2025 11:00:24 +0200 Subject: [PATCH 1110/1221] Revert "[revert-me] add intentional crash + changed complexity" This reverts commit e4ed9c4fc8ce3752a732321b22278150ebc8dea8. --- lib_dec/ivas_jbm_dec_fx.c | 8 ++++---- lib_enc/ivas_enc_fx.c | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 8d4b10dec..74af57bd5 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -159,10 +159,10 @@ ivas_error ivas_jbm_dec_tc_fx( set32_fx( &p_output_fx[0][0], 0, L_FRAME48k ); set32_fx( &p_output_fx[1][0], 0, L_FRAME48k ); - // IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK ) - // { - // return error; - // } + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } IF( NE_16( q_output, Q11 ) ) { diff --git a/lib_enc/ivas_enc_fx.c b/lib_enc/ivas_enc_fx.c index 95f690c15..ff5f65b32 100644 --- a/lib_enc/ivas_enc_fx.c +++ b/lib_enc/ivas_enc_fx.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include -#include #include #include "options.h" #include "cnst.h" @@ -188,7 +187,6 @@ ivas_error ivas_enc_fx( } ELSE IF( EQ_32( ivas_format, ISM_FORMAT ) ) { - assert( 0 ); /* select ISM format mode; reconfigure the ISM format encoder */ IF( ( error = ivas_ism_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { -- GitLab From d22d0d30279d95de9b0d4d6863f2074b8b083451 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 24 Apr 2025 11:00:37 +0200 Subject: [PATCH 1111/1221] Revert "[revert-me] change script branch for testing" This reverts commit f9354b9c882b9f2206bc78976073c3ed5b572413. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f12628044..756432136 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,7 +29,7 @@ variables: MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "kiene/tmp-branch-for-complexity-cleanup" + BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 -- GitLab From 59e90cdd679f559b3431276b75258e0e1d4224e0 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 24 Apr 2025 11:00:46 +0200 Subject: [PATCH 1112/1221] Revert "[revert-me] temporarily disable delay for testing" This reverts commit 1b059d6ef99d5f8155b0160e609fe56cc3c602f4. --- .gitlab-ci.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 756432136..780a51995 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1812,6 +1812,8 @@ complexity-ism-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 1 hour variables: JOB_ID_INJECT: "" script: @@ -1828,6 +1830,8 @@ complexity-ism-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 2 hours variables: JOB_ID_INJECT: "" script: @@ -1844,6 +1848,8 @@ complexity-ism-in-ext-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 3 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1860,6 +1866,8 @@ complexity-sba-hoa3-in-hoa3-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 4 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1876,6 +1884,8 @@ complexity-sba-hoa3-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 5 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1892,6 +1902,8 @@ complexity-sba-hoa3-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 6 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1908,6 +1920,8 @@ complexity-mc-in-7_1_4-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 7 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1924,6 +1938,8 @@ complexity-mc-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 10 hours variables: JOB_ID_INJECT: "" script: @@ -1940,6 +1956,8 @@ complexity-mc-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 12 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -1956,6 +1974,8 @@ complexity-masa-in-ext-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 15 hours variables: JOB_ID_INJECT: "" script: @@ -1972,6 +1992,8 @@ complexity-masa-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 16 hours variables: JOB_ID_INJECT: "" script: @@ -1988,6 +2010,8 @@ complexity-masa-in-hoa3-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 17 hours variables: JOB_ID_INJECT: "" script: @@ -2022,6 +2046,8 @@ complexity-omasa-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 18 hours variables: JOB_ID_INJECT: "" script: @@ -2038,6 +2064,8 @@ complexity-omasa-in-hoa3-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 20 hours variables: JOB_ID_INJECT: "" script: @@ -2054,6 +2082,8 @@ complexity-StereoDmxEVS-stereo-in-mono-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 22 hours variables: JOB_ID_INJECT: "" script: @@ -2070,6 +2100,8 @@ complexity-StereoDmxEVS-stereo-in-mono-out: # - .complexity-template # rules: # - if: $MEASURE_COMPLEXITY_LINUX +# when: delayed +# start_in: 17 hours # script: # - in_format=OSBA # - out_format=EXT @@ -2084,6 +2116,8 @@ complexity-osba-in-binaural-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 22 hours 30 minutes variables: JOB_ID_INJECT: "" script: @@ -2100,6 +2134,8 @@ complexity-osba-in-binaural_room_ir-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + when: delayed + start_in: 25 hours variables: JOB_ID_INJECT: "" script: -- GitLab From 8cdaa39df0c7b287efe951b8e5b72a52c172be9b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 24 Apr 2025 14:42:03 +0530 Subject: [PATCH 1113/1221] optimizing vector add and subtract, hp20 optimizations --- lib_com/hp50_fx.c | 85 +++++-------------- lib_com/mslvq_com_fx.c | 35 ++++++-- lib_com/options.h | 3 +- lib_com/prot_fx.h | 18 ++++ lib_com/tools.c | 20 +++++ lib_com/tools_fx.c | 20 +++++ lib_dec/fd_cng_dec_fx.c | 4 + lib_dec/ivas_dirac_dec_fx.c | 4 + lib_dec/ivas_jbm_dec_fx.c | 4 + lib_dec/ivas_mc_param_dec_fx.c | 5 ++ lib_enc/ivas_qmetadata_enc_fx.c | 18 +++- lib_enc/ivas_sns_enc_fx.c | 4 + lib_enc/speech_music_classif_fx.c | 4 + lib_rend/ivas_dirac_ana_fx.c | 4 + lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 7 ++ lib_rend/ivas_dirac_rend_fx.c | 12 ++- lib_rend/ivas_efap_fx.c | 29 ++++++- lib_rend/ivas_omasa_ana_fx.c | 5 ++ lib_rend/ivas_reverb_fx.c | 30 +++++++ lib_rend/lib_rend.c | 8 ++ 20 files changed, 238 insertions(+), 81 deletions(-) diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index f5e7105cf..f1864d7a7 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -458,14 +458,8 @@ void hp20_fx_32( { Word16 i; Word32 a1_fx, a2_fx, b1_fx, b2_fx; -#ifdef OPT_STEREO_32KBPS_V1 - Word16 Qy1, Qy2, Qmin; - Word64 y0_fx64, y1_fx64, y2_fx64; - Word32 x0, x1, x2; -#else /* OPT_STEREO_32KBPS_V1 */ Word16 Qx0, Qx1, Qx2, Qy1, Qprev_y1, Qy2, Qprev_y2, Qmin; Word64 x0_fx64, x1_fx64, x2_fx64, y0_fx64, y1_fx64, y2_fx64, R1, R2, R3, R4, R5; -#endif /* OPT_STEREO_32KBPS_V1 */ IF( EQ_32( Fs, 8000 ) ) { @@ -516,64 +510,15 @@ void hp20_fx_32( move32(); move32(); -#ifdef OPT_STEREO_32KBPS_V1 - y1_fx64 = W_add( W_deposit32_l( mem_fx[0] ), W_deposit32_h( mem_fx[1] ) ); - y2_fx64 = W_add( W_deposit32_l( mem_fx[2] ), W_deposit32_h( mem_fx[3] ) ); - - x0 = mem_fx[4]; - move32(); - x1 = mem_fx[5]; - move32(); -#else /* OPT_STEREO_32KBPS_V1 */ Qprev_y1 = extract_l( mem_fx[4] ); Qprev_y2 = extract_l( mem_fx[5] ); y1_fx64 = W_deposit32_l( mem_fx[0] ); y2_fx64 = W_deposit32_l( mem_fx[1] ); x0_fx64 = W_deposit32_l( mem_fx[2] ); x1_fx64 = W_deposit32_l( mem_fx[3] ); -#endif /* OPT_STEREO_32KBPS_V1 */ FOR( i = 0; i < lg; i++ ) { -#ifdef OPT_STEREO_32KBPS_V1 - x2 = x1; - move32(); - x1 = x0; - move32(); - x0 = signal_fx[i]; - move32(); - - Qy1 = W_norm( y1_fx64 ); - if ( y1_fx64 == 0 ) - { - Qy1 = 62; - move16(); - } - - Qy2 = W_norm( y2_fx64 ); - if ( y2_fx64 == 0 ) - { - Qy2 = 62; - move16(); - } - - Qmin = s_min( Qy1, Qy2 ); - - Qmin = sub( Qmin, 34 ); - - y0_fx64 = W_mac_32_32( W_mult_32_32( W_shl_sat_l( y1_fx64, Qmin ), a1_fx ), W_shl_sat_l( y2_fx64, Qmin ), a2_fx ); // Qmin + Q29 + Q30 + 1 - - Word64 temp = W_mac_32_32( W_mac_32_32( W_mult_32_32( x2, b2_fx ), x1, b1_fx ), x0, b2_fx ); // Q30 - Word64 y0_fx = W_shr( y0_fx64, add( Qmin, Q30 ) ); // Q30 - y0_fx64 = W_add( temp, y0_fx ); // Q30 - signal_fx[i] = W_shl_sat_l( y0_fx64, -Q30 ); - move32(); - - y2_fx64 = y1_fx64; - move64(); - y1_fx64 = y0_fx64; - move64(); -#else /* OPT_STEREO_32KBPS_V1 */ x2_fx64 = x1_fx64; move64(); x1_fx64 = x0_fx64; @@ -587,7 +532,11 @@ void hp20_fx_32( move16(); } Qy1 = sub( Qy1, 34 ); +#ifdef OPT_STEREO_32KBPS_V1 + R1 = W_mult0_32_32( W_shl_sat_l( y1_fx64, Qy1 ), a1_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ R1 = W_mult0_32_32( W_extract_l( W_shl( y1_fx64, Qy1 ) ), a1_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ Qy1 = add( Qy1, Qprev_y1 ); Qy2 = W_norm( y2_fx64 ); @@ -597,7 +546,11 @@ void hp20_fx_32( move16(); } Qy2 = sub( Qy2, 34 ); +#ifdef OPT_STEREO_32KBPS_V1 + R2 = W_mult0_32_32( W_shl_sat_l( y2_fx64, Qy2 ), a2_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ R2 = W_mult0_32_32( W_extract_l( W_shl( y2_fx64, Qy2 ) ), a2_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ Qy2 = add( Qy2, Qprev_y2 ); Qx0 = W_norm( x0_fx64 ); @@ -607,7 +560,11 @@ void hp20_fx_32( move16(); } Qx0 = sub( Qx0, 34 ); +#ifdef OPT_STEREO_32KBPS_V1 + R3 = W_mult0_32_32( W_shl_sat_l( x0_fx64, Qx0 ), b2_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ R3 = W_mult0_32_32( W_extract_l( W_shl( x0_fx64, Qx0 ) ), b2_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ Qx1 = W_norm( x1_fx64 ); if ( x1_fx64 == 0 ) @@ -616,7 +573,11 @@ void hp20_fx_32( move16(); } Qx1 = sub( Qx1, 34 ); +#ifdef OPT_STEREO_32KBPS_V1 + R4 = W_mult0_32_32( W_shl_sat_l( x1_fx64, Qx1 ), b1_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ R4 = W_mult0_32_32( W_extract_l( W_shl( x1_fx64, Qx1 ) ), b1_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ Qx2 = W_norm( x2_fx64 ); if ( x2_fx64 == 0 ) @@ -625,7 +586,11 @@ void hp20_fx_32( move16(); } Qx2 = sub( Qx2, 34 ); +#ifdef OPT_STEREO_32KBPS_V1 + R5 = W_mult0_32_32( W_shl_sat_l( x2_fx64, Qx2 ), b2_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ R5 = W_mult0_32_32( W_extract_l( W_shl( x2_fx64, Qx2 ) ), b2_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ Qmin = s_min( Qy1, Qy2 ); @@ -655,17 +620,8 @@ void hp20_fx_32( move64(); move16(); move16(); -#endif /* OPT_STEREO_32KBPS_V1 */ } -#ifdef OPT_STEREO_32KBPS_V1 - mem_fx[0] = W_extract_l( y1_fx64 ); - mem_fx[1] = W_extract_h( y1_fx64 ); - mem_fx[2] = W_extract_l( y2_fx64 ); - mem_fx[3] = W_extract_h( y2_fx64 ); - mem_fx[4] = x0; - mem_fx[5] = x1; -#else /* OPT_STEREO_32KBPS_V1 */ Qy1 = W_norm( y1_fx64 ); test(); IF( y1_fx64 != 0 && LT_16( Qy1, 32 ) ) @@ -688,7 +644,6 @@ void hp20_fx_32( mem_fx[3] = W_extract_l( x1_fx64 ); mem_fx[4] = Qprev_y1; mem_fx[5] = Qprev_y2; -#endif /* OPT_STEREO_32KBPS_V1 */ move32(); move32(); diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index cf2ad8a8a..7fcf36bfc 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -128,21 +128,31 @@ void init_lvq_fx( FOR( i = 0; i < MAX_NO_MODES; i++ ) { #ifdef OPT_STEREO_32KBPS_V1 - FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; ( j++, k++ ) ) + FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ ) { - if ( ( no_lead_fx[i][j] <= 0 ) ) + if ( no_lead_fx[i][j] > 0 ) { - j = MAX_NO_SCALES; + k = add( k, 1 ); + } + if ( no_lead_fx[i][j] <= 0 ) + { + j = MAX_NO_SCALES - 1; + move16(); } } no_scales[i][0] = k; move16(); - FOR( k = 0; j < MAX_NO_SCALES << 1; ( j++, k++ ) ) + FOR( k = 0; j < MAX_NO_SCALES << 1; j++ ) { + if ( no_lead_fx[i][j] > 0 ) + { + k = add( k, 1 ); + } if ( no_lead_fx[i][j] <= 0 ) { j = MAX_NO_SCALES << 1; + move16(); } } no_scales[i][1] = k; @@ -172,23 +182,32 @@ void init_lvq_fx( FOR( i = 0; i < MAX_NO_MODES_p; i++ ) { #ifdef OPT_STEREO_32KBPS_V1 - FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; ( j++, k++ ) ) + FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ ) { - + if ( no_lead_p_fx[i][j] > 0 ) + { + k = add( k, 1 ); + } if ( ( no_lead_p_fx[i][j] <= 0 ) ) { - j = MAX_NO_SCALES; + j = MAX_NO_SCALES - 1; + move16(); } } no_scales_p[i][0] = k; move16(); - FOR( k = 0; j < MAX_NO_SCALES << 1; ( j++, k++ ) ) + FOR( k = 0; j < MAX_NO_SCALES << 1; j++ ) { + if ( no_lead_p_fx[i][j] > 0 ) + { + k = add( k, 1 ); + } if ( ( no_lead_p_fx[i][j] <= 0 ) ) { j = MAX_NO_SCALES << 1; + move16(); } } diff --git a/lib_com/options.h b/lib_com/options.h index 2f1e82de8..cbc77b6e7 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -74,7 +74,7 @@ #define FIX_1379_MASA_ANGLE_ROUND /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ -//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ #define OPT_AVOID_STATE_BUF_RESCALE /* Optimization made to avoid rescale of synth state buffer */ #define FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx /*FhG: WMOPS tuning, nonbe*/ #define FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot /*FhG: WMOPS tuning, nonbe*/ @@ -93,6 +93,7 @@ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ +#define VEC_ARITH_OPT_v1 #define FIX_1486_IND_SHB_RES /* VA: Fix for issue 1486: align the usage of IND_SHB_RES_GS indices with float code */ #define TEST_HR diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 41f68807e..86b5ec0b7 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6184,6 +6184,15 @@ void v_add_fixed( const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ ); +#ifdef VEC_ARITH_OPT_v1 +void v_add_fixed_no_hdrm( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */ + const Word16 N /* i : Vector length */ +); +#endif /* VEC_ARITH_OPT_v1 */ + void v_add_fixed_me( const Word32 x1[], /* i : Input vector 1 */ const Word16 x1_e, /* i : Exponent for input vector 1 */ @@ -6218,6 +6227,15 @@ void v_sub_fixed( const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ ); +#ifdef VEC_ARITH_OPT_v1 +void v_sub_fixed_no_hdrm( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N /* i : Vector length */ +); +#endif /* VEC_ARITH_OPT_v1 */ + /*! r: dot product of x[] and y[] */ Word32 dotp_fixed( const Word32 x[], /* i : vector x[] */ diff --git a/lib_com/tools.c b/lib_com/tools.c index b1a9f4d13..f7303c6f3 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -888,6 +888,26 @@ void v_sub_fixed( return; } +#ifdef VEC_ARITH_OPT_v1 +void v_sub_fixed_no_hdrm( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N /* i : Vector length */ +) +{ + Word16 i; + + FOR( i = 0; i < N; i++ ) + { + y[i] = L_sub( x1[i], x2[i] ); + move32(); + } + + return; +} +#endif /* VEC_ARITH_OPT_v1 */ + /*-------------------------------------------------------------------* * v_multc_fixed() * diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 6dc1c45f2..44a86b0eb 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -4524,6 +4524,26 @@ void v_add_fixed( return; } +#ifdef VEC_ARITH_OPT_v1 +void v_add_fixed_no_hdrm( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */ + const Word16 N /* i : Vector length */ +) +{ + Word16 i; + + FOR( i = 0; i < N; i++ ) + { + y[i] = L_add( x1[i], x2[i] ); + move32(); + } + + return; +} +#endif /* VEC_ARITH_OPT_v1 */ + void v_add_fixed_me( const Word32 x1[], /* i : Input vector 1 */ const Word16 x1_e, /* i : Exponent for input vector 1 */ diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index d0fd178f2..47a61a26e 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -5345,7 +5345,11 @@ void generate_masking_noise_ivas_fx( } ELSE { +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ +#endif /* VEC_ARITH_OPT_v1 */ } return; diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 9c319489e..37b0bf1ba 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -3100,7 +3100,11 @@ void ivas_dirac_dec_render_sf_fx( v_multc_fixed( onset_filter_fx, 536870912 /* 0.25f in Q31 */, onset_filter_fx, hSpatParamRendCom->num_freq_bands ); +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( onset_filter_fx, onset_filter_subframe_fx, onset_filter_subframe_fx, hSpatParamRendCom->num_freq_bands ); /* Q31 */ +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( onset_filter_fx, onset_filter_subframe_fx, onset_filter_subframe_fx, hSpatParamRendCom->num_freq_bands, 0 ); /* Q31 */ +#endif /* VEC_ARITH_OPT_v1 */ p_onset_filter_fx = onset_filter_subframe_fx; } ELSE diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 74af57bd5..3f67962dc 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -2137,7 +2137,11 @@ ivas_error ivas_jbm_dec_render_fx( /* add already rendered SBA part */ FOR( n = 0; n < nchan_out; n++ ) { +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( p_output_fx[n], p_tc_fx[n + st_ivas->nchan_ism], p_output_fx[n], *nSamplesRendered ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( p_output_fx[n], p_tc_fx[n + st_ivas->nchan_ism], p_output_fx[n], *nSamplesRendered, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } } ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 5f93c9676..e0671eea0 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -2084,8 +2084,13 @@ void ivas_param_mc_dec_render_fx( { IF( hLsSetup.index_lfe[idx_lfe] != ch ) { +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer_fx[ch][slot_idx], 1 ); + v_add_fixed_no_hdrm( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer_fx[ch][slot_idx], 1 ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer_fx[ch][slot_idx], 1, 0 ); v_add_fixed( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer_fx[ch][slot_idx], 1, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } } } diff --git a/lib_enc/ivas_qmetadata_enc_fx.c b/lib_enc/ivas_qmetadata_enc_fx.c index 79a4adee7..744d2c067 100644 --- a/lib_enc/ivas_qmetadata_enc_fx.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -1069,8 +1069,12 @@ void ivas_qmetadata_enc_sid_encode_fx( { /*compute the average direction */ ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[m], q_direction->band_data[b].elevation_fx[m], direction_vector_fx ); - scale_sig32( direction_vector_fx, 3, Q22 - Q30 ); // Q30 -> Q22 + scale_sig32( direction_vector_fx, 3, Q22 - Q30 ); // Q30 -> Q22 +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); // Q22 +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3, 0 ); // Q22 +#endif /* VEC_ARITH_OPT_v1 */ } ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, Q22, &avg_azimuth_fx[b], &avg_elevation_fx[b] ); @@ -2402,7 +2406,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( /*compute the average direction */ ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector ); scale_sig32( direction_vector, 3, -8 ); // Q30 -> Q22 +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( avg_direction_vector, direction_vector, avg_direction_vector, 3 ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( avg_direction_vector, direction_vector, avg_direction_vector, 3, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } } } @@ -2665,7 +2673,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( IF( LT_16( idx, 4 ) ) { +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( avg_direction_vector, direction_vector, avg_direction_vector, 3 ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( avg_direction_vector, direction_vector, avg_direction_vector, 3, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } } /* project the quantized average azimuth angle to the same grid as the current sample */ @@ -2696,7 +2708,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector ); scale_sig32( direction_vector, 3, -8 ); // Q30 -> Q22 +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( avg_direction_vector, direction_vector, avg_direction_vector, 3 ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( avg_direction_vector, direction_vector, avg_direction_vector, 3, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector, Q22, &avg_azimuth, &avg_elevation ); avg_azimuth_index_upd = quantize_phi_enc_fx( L_add( avg_azimuth, 180 << Q22 ), 0, &avg_azimuth, avg_azimuth_alphabet ); diff --git a/lib_enc/ivas_sns_enc_fx.c b/lib_enc/ivas_sns_enc_fx.c index b7de878a1..2eaefb483 100644 --- a/lib_enc/ivas_sns_enc_fx.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -672,7 +672,11 @@ Word16 quantize_sns_fx( Word32 ener_side_fx; Word16 ener_side_q; +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M ); +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ Word64 L64_sum; L64_sum = 1; diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index cbd8ea19f..cf6ba543b 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2181,7 +2181,11 @@ Word16 ivas_smc_gmm_fx( } /* PCA */ +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( FV_fx, pca_mean_fx, FV_fx, N_SMC_FEATURES ); +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( FV_fx, pca_mean_fx, FV_fx, N_SMC_FEATURES, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ v_mult_mat_fixed( FV_fx, FV_fx, pca_components_fx, N_SMC_FEATURES, N_PCA_COEF, 0 ); /*------------------------------------------------------------------* * Calculation of posterior probability diff --git a/lib_rend/ivas_dirac_ana_fx.c b/lib_rend/ivas_dirac_ana_fx.c index 8124c4967..c2430d008 100644 --- a/lib_rend/ivas_dirac_ana_fx.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -578,7 +578,11 @@ static void ivas_dirac_dmx_fx( v_add_fx( data_in_fx[0], data_in_fx[1], data_out_fx[0], input_frame ); v_multc_fixed( data_out_fx[0], ONE_IN_Q30, data_out_fx[0], input_frame ); // ONE_IN_Q30 = 0.5* ONE_IN_Q31 +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame ); +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ v_multc_fixed( data_out_fx[1], ONE_IN_Q30, data_out_fx[1], input_frame ); FOR( i = 0; i < nchan_transport; i++ ) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 0cdbe3a10..509eec6e2 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -1227,10 +1227,17 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { Scale_sig32( aux_buf, num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth, temp_q ) ); /*temp_q->(h_dirac_output_synthesis_state->q_cy_auto_diff_smooth)*/ } +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( aux_buf, + &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], + &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], + num_freq_bands_diff ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/ +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( aux_buf, &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/ +#endif /* VEC_ARITH_OPT_v1 */ } return; diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 2f748289a..2540426cc 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -4528,9 +4528,13 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_freq_domain_decorr_ap_params, hDirACRend->h_freq_domain_decorr_ap_state ); - v_multc_fixed( onset_filter_fx, 536870912 /* 0.25f in Q31 */, onset_filter_fx, hSpatParamRendCom->num_freq_bands ); /* Q31 */ + v_multc_fixed( onset_filter_fx, 536870912 /* 0.25f in Q31 */, onset_filter_fx, hSpatParamRendCom->num_freq_bands ); /* Q31 */ +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( onset_filter_fx, onset_filter_subframe_fx, onset_filter_subframe_fx, hSpatParamRendCom->num_freq_bands ); /* Q31 */ +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( onset_filter_fx, onset_filter_subframe_fx, onset_filter_subframe_fx, hSpatParamRendCom->num_freq_bands, 0 ); /* Q31 */ - p_onset_filter_fx = onset_filter_subframe_fx; /*q31*/ +#endif /* VEC_ARITH_OPT_v1 */ + p_onset_filter_fx = onset_filter_subframe_fx; /*q31*/ } ELSE { @@ -4627,7 +4631,11 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_smooth_q = DirAC_mem.reference_power_q; move16(); #endif +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( reference_power_fix, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands ); // DirAC_mem.reference_power_smooth_q +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( reference_power_fix, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 0 ); // DirAC_mem.reference_power_smooth_q +#endif /* VEC_ARITH_OPT_v1 */ } } /*Rescaling proto_direct_buffer_f*/ diff --git a/lib_rend/ivas_efap_fx.c b/lib_rend/ivas_efap_fx.c index 543decbdd..4fb88643b 100644 --- a/lib_rend/ivas_efap_fx.c +++ b/lib_rend/ivas_efap_fx.c @@ -1525,7 +1525,11 @@ static void get_poly_gains_fx( A[1] = elePoly[i - 1]; // q22 move32(); +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( P, A, P_minus_A, 2 ); /* Precalculate value of (P-A) q22*/ +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( P, A, P_minus_A, 2, 0 ); /* Precalculate value of (P-A) q22*/ +#endif /* VEC_ARITH_OPT_v1 */ FOR( j = i; j < numChan - 2 + i; ++j ) { @@ -1578,7 +1582,11 @@ static Word32 get_tri_gain_fx( tmpN[1] = L_sub( C[0], B[0] ); // q22 move32(); - v_sub_fixed( B, A, tmpSub1, 2, 0 ); // tmpSub1 q22 +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( B, A, tmpSub1, 2 ); // tmpSub1 q22 +#else /* VEC_ARITH_OPT_v1 */ + v_sub_fixed( B, A, tmpSub1, 2, 0 ); // tmpSub1 q22 +#endif /* VEC_ARITH_OPT_v1 */ tmpDot1 = dotp_fixed( tmpN, tmpSub1, 2 ); // Q13 @@ -2237,7 +2245,11 @@ static void sort_channels_vertex_fx( move32(); } +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( tmpV1, tmpV2, tmpV3, 3 ); // tmpV3 Q30 +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( tmpV1, tmpV2, tmpV3, 3, 0 ); // tmpV3 Q30 +#endif /* VEC_ARITH_OPT_v1 */ Word16 exp2 = 2; move16(); normV = ISqrt32( dotp_fixed( tmpV3, tmpV3, 3 ) /*q29*/, &exp2 ); // q=31-exp2 @@ -2419,7 +2431,11 @@ static Word16 in_poly_fx( /* Angles are in Q22 */ A[1] = poly.polyEle[0]; // q22 move32(); - v_sub_fixed( P, A, P_minus_A, 2, 0 ); /* Precalculate value of (P-A) q22*/ +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( P, A, P_minus_A, 2 ); /* Precalculate value of (P-A) q22*/ +#else /* VEC_ARITH_OPT_v1 */ + v_sub_fixed( P, A, P_minus_A, 2, 0 ); /* Precalculate value of (P-A) q22*/ +#endif /* VEC_ARITH_OPT_v1 */ FOR( n = 1; n < sub( numVertices, 1 ); ++n ) { @@ -2487,8 +2503,13 @@ static Word16 in_tri_fx( I'll just compute the determinant and if it's equal to 0, that means the two vectors are colinear */ - v_sub_fixed( B, A, tmpDot1, 2, 0 ); // tmpDot1 q22 - v_sub_fixed( C, A, tmpDot2, 2, 0 ); // tmpDot2 q22 +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( B, A, tmpDot1, 2 ); // tmpDot1 q22 + v_sub_fixed_no_hdrm( C, A, tmpDot2, 2 ); // tmpDot2 q22 +#else /* VEC_ARITH_OPT_v1 */ + v_sub_fixed( B, A, tmpDot1, 2, 0 ); // tmpDot1 q22 + v_sub_fixed( C, A, tmpDot2, 2, 0 ); // tmpDot2 q22 +#endif /* VEC_ARITH_OPT_v1 */ /* Verification of the non-colinearity : Q22 * Q22 = Q13 */ invFactor = L_sub( Mpy_32_32( tmpDot1[0], tmpDot2[1] ), Mpy_32_32( tmpDot1[1], tmpDot2[0] ) ); /*q22+q22-q31->q13*/ diff --git a/lib_rend/ivas_omasa_ana_fx.c b/lib_rend/ivas_omasa_ana_fx.c index ba632c6ba..7b7f64c84 100644 --- a/lib_rend/ivas_omasa_ana_fx.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -538,8 +538,13 @@ static void ivas_omasa_param_est_ana_fx( FOR( i = 1; i < nchan_ism; i++ ) { +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // Q: Chnl_RealBuffer_q + v_add_fixed_no_hdrm( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // Q: Chnl_ImagBuffer_q +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins, 0 ); // Q: Chnl_RealBuffer_q v_add_fixed( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins, 0 ); // Q: Chnl_ImagBuffer_q +#endif /* VEC_ARITH_OPT_v1 */ } /* Y */ diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 9b149940c..12b94b1a2 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -2177,13 +2177,23 @@ void ivas_binaural_reverb_processSubframe_fx( { IF( s_and( ch, 1 ) ) { +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( hReverb->preDelayBufferReal_fx[idx], inReal[ch][sample], hReverb->preDelayBufferReal_fx[idx], hReverb->numBins ); + v_add_fixed_no_hdrm( hReverb->preDelayBufferImag_fx[idx], inImag[ch][sample], hReverb->preDelayBufferImag_fx[idx], hReverb->numBins ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( hReverb->preDelayBufferReal_fx[idx], inReal[ch][sample], hReverb->preDelayBufferReal_fx[idx], hReverb->numBins, 0 ); v_add_fixed( hReverb->preDelayBufferImag_fx[idx], inImag[ch][sample], hReverb->preDelayBufferImag_fx[idx], hReverb->numBins, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } ELSE { +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( hReverb->preDelayBufferReal_fx[idx], inImag[ch][sample], hReverb->preDelayBufferReal_fx[idx], hReverb->numBins ); + v_add_fixed_no_hdrm( hReverb->preDelayBufferImag_fx[idx], inReal[ch][sample], hReverb->preDelayBufferImag_fx[idx], hReverb->numBins ); +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( hReverb->preDelayBufferReal_fx[idx], inImag[ch][sample], hReverb->preDelayBufferReal_fx[idx], hReverb->numBins, 0 ); v_add_fixed( hReverb->preDelayBufferImag_fx[idx], inReal[ch][sample], hReverb->preDelayBufferImag_fx[idx], hReverb->numBins, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } } idx = add( idx, 1 ) % hReverb->preDelayBufferLength; @@ -2213,20 +2223,40 @@ void ivas_binaural_reverb_processSubframe_fx( SWITCH( phaseShiftTypePr[tapIdx] ) { case 0: /* 0 degrees phase */ +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( hReverb->outputBufferReal_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots ); + v_add_fixed_no_hdrm( hReverb->outputBufferImag_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( hReverb->outputBufferReal_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); v_add_fixed( hReverb->outputBufferImag_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ BREAK; case 1: /* 90 degrees phase */ +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( hReverb->outputBufferReal_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots ); + v_add_fixed_no_hdrm( hReverb->outputBufferImag_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots ); +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( hReverb->outputBufferReal_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); v_add_fixed( hReverb->outputBufferImag_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ BREAK; case 2: /* 180 degrees phase */ +#ifdef VEC_ARITH_OPT_v1 + v_sub_fixed_no_hdrm( hReverb->outputBufferReal_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots ); + v_sub_fixed_no_hdrm( hReverb->outputBufferImag_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots ); +#else /* VEC_ARITH_OPT_v1 */ v_sub_fixed( hReverb->outputBufferReal_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); v_sub_fixed( hReverb->outputBufferImag_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ BREAK; default: /* 270 degrees phase */ +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( hReverb->outputBufferReal_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots ); + v_sub_fixed_no_hdrm( hReverb->outputBufferImag_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( hReverb->outputBufferReal_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); v_sub_fixed( hReverb->outputBufferImag_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ BREAK; } } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 859768784..ad84c92e9 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -5772,7 +5772,11 @@ static ivas_error renderLfeToBinaural_fx( { writePtr = getSmplPtr_fx( outAudio, ear_idx, 0 ); move32(); +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( writePtr, tmpLfeBuffer, writePtr, frame_size ); /* Q(out_q) */ +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( writePtr, tmpLfeBuffer, writePtr, frame_size, 0 ); /* Q(out_q) */ +#endif /* VEC_ARITH_OPT_v1 */ } pop_wmops(); @@ -6793,7 +6797,11 @@ static void renderMasaToMasa( ELSE IF( EQ_16( masaInput->base.inputBuffer.config.numChannels, 2 ) && EQ_16( outAudio.config.numChannels, 1 ) ) { // v_add( tmpBuffer[0], tmpBuffer[1], tmpBuffer[0], masaInput->base.inputBuffer.config.numSamplesPerChannel ); +#ifdef VEC_ARITH_OPT_v1 + v_add_fixed_no_hdrm( tmpBuffer_fx[0], tmpBuffer_fx[1], tmpBuffer_fx[0], masaInput->base.inputBuffer.config.numSamplesPerChannel ); +#else /* VEC_ARITH_OPT_v1 */ v_add_fixed( tmpBuffer_fx[0], tmpBuffer_fx[1], tmpBuffer_fx[0], masaInput->base.inputBuffer.config.numSamplesPerChannel, 0 ); +#endif /* VEC_ARITH_OPT_v1 */ } /* Copy metadata */ -- GitLab From 098a015dfa4609f6cf1ff76c1aef0586facacf0a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 24 Apr 2025 17:12:50 +0530 Subject: [PATCH 1114/1221] Fix for MSAN ASAN error in decoder, renderer crash fix and macro code cleanup --- lib_dec/ivas_core_dec_fx.c | 11 +---------- lib_dec/ivas_dirac_dec_fx.c | 21 +++++++++++++++++++-- lib_rend/lib_rend.c | 13 ++++++++----- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 03f0e4b40..320d9d4bc 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -266,11 +266,7 @@ ivas_error ivas_core_dec_fx( test(); test(); test(); -#ifdef NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID IF( !st->bfi && st->prev_bfi && GT_32( st->total_brate, SID_2k40 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) -#else - IF( !st->bfi && st->prev_bfi && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) -#endif { conceal_eof_gain32 = L_shr_sat( st->hTcxDec->conceal_eof_gain32, sub( 16, st->hTcxDec->conceal_eof_gain_e ) ); // e = 31 - Q , 16 - e => 16 - (31 - Q) => Q - 15, // shr(16 -e ) = shr(Q -15) => 15 - Q ==> Q15 @@ -604,7 +600,7 @@ ivas_error ivas_core_dec_fx( st->hHQ_core->Q_old_wtda_LB = st->hHQ_core->Q_old_wtda; move16(); - Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, Q11 ); // Q11 + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], output_frame, Q11 ); // Q11 IF( st->hTcxDec ) { @@ -771,13 +767,8 @@ ivas_error ivas_core_dec_fx( test(); test(); -#ifdef NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES /* On first good active frame after frameloss undo the whitening of the bg noise shape */ IF( GT_32( sts[0]->core_brate, SID_2k40 ) && sts[0]->bfi == 0 && EQ_16( sts[0]->prev_bfi, 1 ) ) -#else - IF( sts[0]->bfi == 0 && EQ_16( sts[0]->prev_bfi, 1 ) ) - /* On first good frame after frameloss undo the whitening of the bg noise shape */ -#endif { FOR( n = 0; n < n_channels; ++n ) { diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 37b0bf1ba..403e11f00 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -1446,10 +1446,27 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { - hSpatParamRendCom->azimuth[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); + /* Right shifting -1 -> -1, Hence this change is done */ + Word32 L_tmp = L_abs( q_direction->band_data[band].azimuth_fx[block] ); + hSpatParamRendCom->azimuth[meta_write_index][b] = extract_h( L_shr( L_tmp, 6 ) ); move16(); - hSpatParamRendCom->elevation[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); + + IF( q_direction->band_data[band].azimuth_fx[block] < 0 ) + { + hSpatParamRendCom->azimuth[meta_write_index][b] = negate( hSpatParamRendCom->azimuth[meta_write_index][b] ); + move16(); + } + + L_tmp = L_abs( q_direction->band_data[band].elevation_fx[block] ); + hSpatParamRendCom->elevation[meta_write_index][b] = extract_h( L_shr( L_tmp, 6 ) ); move16(); + + IF( q_direction->band_data[band].elevation_fx[block] < 0 ) + { + hSpatParamRendCom->elevation[meta_write_index][b] = negate( hSpatParamRendCom->elevation[meta_write_index][b] ); + move16(); + } + hSpatParamRendCom->energy_ratio1_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; move32(); hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( ONE_IN_Q30, q_direction->band_data[band].energy_ratio_fx[block] ); diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ad84c92e9..e39b9a61e 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8511,13 +8511,16 @@ static void intermidiate_ext_dirac_render( move16(); #endif } + IF( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx != NULL ) + { - tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q + tmp) */ - hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, tmp ); - move16(); + tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q + tmp) */ + hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, tmp ); + move16(); + } - IF( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx != 0 ) + IF( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx != NULL ) { tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q + tmp) */ -- GitLab From b755243c371c14f14304d427c4805c88c543be15 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 24 Apr 2025 15:53:29 +0200 Subject: [PATCH 1115/1221] only pass --split-csv-file if SPLIT_COMPARISON is given --- .gitlab-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 780a51995..894265e41 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -423,7 +423,11 @@ stages: - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true ### create histograms - - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME --split-csv-file $CSV_ARTIFACT_SPLIT + - if [ "$SPLIT_COMPARISON" = "true" ]; then + - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME --split-csv-file $CSV_ARTIFACT_SPLIT + - else + - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME + - fi # first for "whole" files comparison - python3 scripts/create_histograms.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME --measures $MEASURES_FOR_REPORT --write-out-histograms -- GitLab From 3eae44e31f3f549c179cfa4611e57e51507a38f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Mon, 10 Mar 2025 17:12:35 +0100 Subject: [PATCH 1116/1221] Use default variables from ivas-codec-ci Also extracts the project's own (override) variables into a separate file. --- .gitlab-ci.yml | 80 ++++------------------------------------ .gitlab-ci/variables.yml | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 72 deletions(-) create mode 100644 .gitlab-ci/variables.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 894265e41..7c29145b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,76 +1,12 @@ variables: - TESTV_DIR: "/usr/local/testv" - LTV_DIR: "/usr/local/ltv" - EVS_BE_TEST_DIR_BASOP: "/usr/local/be_2_evs_basop" - FLOAT_REF_BRANCH: "ivas-float-update" - BUILD_OUTPUT: "build_output.txt" - SCRIPTS_DIR: "/usr/local/scripts" - EXIT_CODE_NON_BE: 123 - EXIT_CODE_FAIL: 1 - LONG_TEST_SUITE: "tests/codec_be_on_mr_nonselection tests/renderer --param_file scripts/config/self_test_ltv.prm --use_ltv" - LONG_TEST_SUITE_NO_RENDERER: "tests/codec_be_on_mr_nonselection --param_file scripts/config/self_test_ltv.prm --use_ltv" - SHORT_TEST_SUITE: "tests/codec_be_on_mr_nonselection" - SHORT_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_basop_encoder.prm" - LONG_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_ltv_basop_encoder.prm" - TEST_SUITE: "" - # These path variables are used by the pytest calls. - # They can be overwritten in the job templates to e.g. only test encoder or decoder in the chain - DUT_ENCODER_PATH: "./IVAS_cod" - DUT_DECODER_PATH: "./IVAS_dec" - REF_ENCODER_PATH: "./IVAS_cod_ref" - REF_DECODER_PATH: "./IVAS_dec_ref" - MERGE_TARGET_ENCODER_PATH: "./IVAS_cod_merge_target" - MERGE_TARGET_DECODER_PATH: "./IVAS_dec_merge_target" - # These path variables are used for building the binaries - # They should never be overwritten! - REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_ref" - REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_ref" - MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_merge_target" - MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" - LEVEL_SCALING: "1.0" - IVAS_PIPELINE_NAME: '' - BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" - PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" - TESTCASE_TIMEOUT_STV: 900 - TESTCASE_TIMEOUT_LTV: 2400 - TESTCASE_TIMEOUT_LTV_SANITIZERS: 10800 - CI_REGRESSION_THRESH_MLD: "0.1" - CI_REGRESSION_THRESH_MAX_ABS_DIFF: "50" - CI_REGRESSION_THRESH_SSNR: "-1" - CI_REGRESSION_THRESH_ODG: "-0.05" - GIT_CLEAN_FLAGS: -ffdxq - INSTR_DIR: "scripts/c-code_instrument" - BUILD_WITH_DEBUG_MODE_INFO: "" - ENCODER_TEST: "" - DELTA_ODG: "" - COMPARE_DMX: "" - SPLIT_COMPARISON: "" - SKIP_REGRESSION_CHECK: "" - FAILED_TESTCASES_LIST: "failed-testcases.txt" - ERRORS_TESTCASES_LIST: "errors-testcases.txt" - PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" - MEASURES_FOR_REPORT: "MLD MAX_ABS_DIFF MIN_SSNR MIN_ODG" - FLOAT_REF_COMMIT_FILE: "float-ref-git-sha.txt" - CUT_COMMIT_FILE: "CuT-git-sha.txt" - MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha.txt" - MANUAL_PIPELINE_TYPE: - description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." - value: 'default' - options: - - 'default' - - 'pytest-compare' - - 'pytest-compare-enc-dmx' - - 'pytest-compare-long' - - 'pytest-compare-to-input' - - 'pytest-saturation-smoke-test' - - 'evs-26444' - - 'sanitizer' - - 'pytest-renderer' - - 'complexity' - - 'coverage' - - 'voip-be-test' - - 'peaq-enc-passthrough' - + # note: GitLab cannot reference the variable in the include ref:, we need to use a YAML anchor for this + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF mullerfa/ci-refactor + +include: + - local: .gitlab-ci/variables.yml + - project: ivas-codec-pc/ivas-codec-ci + ref: *IVAS_CODEC_CI_REF + file: main.yml default: interruptible: true # Make all jobs by default interruptible diff --git a/.gitlab-ci/variables.yml b/.gitlab-ci/variables.yml new file mode 100644 index 000000000..94bb71fb3 --- /dev/null +++ b/.gitlab-ci/variables.yml @@ -0,0 +1,65 @@ +variables: + EVS_BE_TEST_DIR_BASOP: "/usr/local/be_2_evs_basop" + FLOAT_REF_BRANCH: "ivas-float-update" + SCRIPTS_DIR: "/usr/local/scripts" + LONG_TEST_SUITE: "tests/codec_be_on_mr_nonselection tests/renderer --param_file scripts/config/self_test_ltv.prm --use_ltv" + LONG_TEST_SUITE_NO_RENDERER: "tests/codec_be_on_mr_nonselection --param_file scripts/config/self_test_ltv.prm --use_ltv" + SHORT_TEST_SUITE: "tests/codec_be_on_mr_nonselection" + SHORT_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_basop_encoder.prm" + LONG_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_ltv_basop_encoder.prm" + TEST_SUITE: "" + # These path variables are used by the pytest calls. + # They can be overwritten in the job templates to e.g. only test encoder or decoder in the chain + DUT_ENCODER_PATH: "./IVAS_cod" + DUT_DECODER_PATH: "./IVAS_dec" + REF_ENCODER_PATH: "./IVAS_cod_ref" + REF_DECODER_PATH: "./IVAS_dec_ref" + MERGE_TARGET_ENCODER_PATH: "./IVAS_cod_merge_target" + MERGE_TARGET_DECODER_PATH: "./IVAS_dec_merge_target" + # These path variables are used for building the binaries + # They should never be overwritten! + REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_ref" + REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_ref" + MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_merge_target" + MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" + LEVEL_SCALING: "1.0" + BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" + PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" + TESTCASE_TIMEOUT_STV: 900 + TESTCASE_TIMEOUT_LTV: 2400 + TESTCASE_TIMEOUT_LTV_SANITIZERS: 10800 + CI_REGRESSION_THRESH_MLD: "0.1" + CI_REGRESSION_THRESH_MAX_ABS_DIFF: "50" + CI_REGRESSION_THRESH_SSNR: "-1" + CI_REGRESSION_THRESH_ODG: "-0.05" + INSTR_DIR: "scripts/c-code_instrument" + BUILD_WITH_DEBUG_MODE_INFO: "" + ENCODER_TEST: "" + DELTA_ODG: "" + COMPARE_DMX: "" + SPLIT_COMPARISON: "" + SKIP_REGRESSION_CHECK: "" + FAILED_TESTCASES_LIST: "failed-testcases.txt" + ERRORS_TESTCASES_LIST: "errors-testcases.txt" + PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" + MEASURES_FOR_REPORT: "MLD MAX_ABS_DIFF MIN_SSNR MIN_ODG" + FLOAT_REF_COMMIT_FILE: "float-ref-git-sha.txt" + CUT_COMMIT_FILE: "CuT-git-sha.txt" + MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha.txt" + MANUAL_PIPELINE_TYPE: + description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." + value: 'default' + options: + - 'default' + - 'pytest-compare' + - 'pytest-compare-enc-dmx' + - 'pytest-compare-long' + - 'pytest-compare-to-input' + - 'pytest-saturation-smoke-test' + - 'evs-26444' + - 'sanitizer' + - 'pytest-renderer' + - 'complexity' + - 'coverage' + - 'voip-be-test' + - 'peaq-enc-passthrough' -- GitLab From f202e60605b0d31b123439a4b9ead9c21ae0261a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Wed, 26 Mar 2025 20:00:10 +0100 Subject: [PATCH 1117/1221] Use stages from ivas-codec-ci --- .gitlab-ci.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7c29145b0..c4162e0f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -64,16 +64,6 @@ workflow: variables: IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' - -stages: - - .pre - - prevalidate - - build - - check-be - - test - - postvalidate - - deploy - # --------------------------------------------------------------- # Generic script anchors # --------------------------------------------------------------- -- GitLab From f4344fb875f6e4a732396a228f3bd3bd48250f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Wed, 26 Mar 2025 20:32:18 +0100 Subject: [PATCH 1118/1221] Use snippets from ivas-codec-ci --- .gitlab-ci.yml | 257 ++++++++++++++++--------------------------------- 1 file changed, 81 insertions(+), 176 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c4162e0f7..2f3176df7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,13 +71,6 @@ workflow: # These can be used later on to do common tasks # Prints useful information for every job and should be used at the beginning of each job -.print-common-info: &print-common-info - - | - echo "Printing common information for build job." - echo "Current job is run on commit $CI_COMMIT_SHA" - echo "Commit time was $CI_COMMIT_TIMESTAMP" - date | xargs echo "System time is" - .print-common-info-windows: &print-common-info-windows - | echo "Printing common information for build job." @@ -85,107 +78,6 @@ workflow: echo "Commit time was $CI_COMMIT_TIMESTAMP" ("echo 'System time is'", "Get-Date -Format 'dddd dd/MM/yyyy HH:mm K'") | Invoke-Expression -.activate-debug-mode-info-if-set: &activate-debug-mode-info-if-set - - if [ "$BUILD_WITH_DEBUG_MODE_INFO" = "true" ]; then - - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUGGING\ *\)\*\//\1/g" lib_com/options.h - - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUG_MODE_INFO\ *\)\*\//\1/g" lib_com/options.h - - fi - -.build-float-ref-binaries: &build-float-ref-binaries - - git rev-parse HEAD > $CUT_COMMIT_FILE - - current_commit_sha=$(git rev-parse HEAD) - ### build reference binaries - - git checkout $FLOAT_REF_BRANCH - - git pull origin $FLOAT_REF_BRANCH - - *activate-debug-mode-info-if-set - - make clean - - make -j >> /dev/null - - mv ./IVAS_cod ./$REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY - - mv ./IVAS_dec ./$REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - - mv ./IVAS_rend ./IVAS_rend_ref - ### Return to current branch - - git restore . - - git rev-parse HEAD > $FLOAT_REF_COMMIT_FILE - - git checkout $current_commit_sha - -.build-merge-target-binaries: &build-merge-target-binaries - - current_commit_sha=$(git rev-parse HEAD) - ### build merge target binaries - - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - *activate-debug-mode-info-if-set - - make clean - - make -j >> /dev/null - - mv ./IVAS_cod ./$MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY - - mv ./IVAS_dec ./$MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - - mv ./IVAS_rend ./IVAS_rend_merge_target - ### Return to current branch - - git restore . - - git rev-parse HEAD > $MERGE_TARGET_COMMIT_FILE - - git checkout $current_commit_sha - -.build-float-ref-and-dut-binaries: &build-float-ref-and-dut-binaries -### build reference binaries - - *build-float-ref-binaries -### build dut binaries - - *activate-debug-mode-info-if-set - - make clean - - make -j >> /dev/null - -.build-and-create-float-ref-outputs: &build-and-create-float-ref-outputs - - *build-float-ref-and-dut-binaries - - ### prepare pytest - # create short test vectors - - python3 tests/create_short_testvectors.py - # create references - - exit_code=0 - - - enc_stats_arg="" - - if [ "$ENCODER_TEST" = "true" ]; then - - enc_stats_arg="--enc_stats" - - fi - - - enc_dmx_arg="" - - if [ "$COMPARE_DMX" = "true" ]; then - - enc_dmx_arg="--compare_enc_dmx" - - fi - - - python3 -m pytest $TEST_SUITE -v --update_ref 1 $enc_stats_arg $enc_dmx_arg --create_ref -n auto --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - -.update-scripts-repo: &update-scripts-repo - - cd $SCRIPTS_DIR - - sed -i '/fetch/d' .git/config # Remove all fetch lines to clean out dead links - - git remote set-branches --add origin $BASOP_CI_BRANCH_PC_REPO # Add currently used branch - - git fetch - - git restore . # Just as a precaution - - git checkout $BASOP_CI_BRANCH_PC_REPO - - git pull origin $BASOP_CI_BRANCH_PC_REPO - - cd - - - cp -r $SCRIPTS_DIR/ci . - - cp -r $SCRIPTS_DIR/scripts . - - cp -r $SCRIPTS_DIR/tests . - - cp $SCRIPTS_DIR/pytest.ini . - -.apply-testv-scaling: &apply-testv-scaling - - echo "Applying level scaling in scripts/testv using scale=$LEVEL_SCALING" - - tests/scale_pcm.py ./scripts/testv/ $LEVEL_SCALING - -.update-ltv-repo: &update-ltv-repo - - cd $LTV_DIR - - git pull - - cd - - -.get-commits-behind-count: &get-commits-behind-count - - echo $CI_COMMIT_SHA - - echo $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - commits_behind_count=$(git rev-list --count $CI_COMMIT_SHA..origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME) - -.copy-ltv-files-to-testv-dir: ©-ltv-files-to-testv-dir - - cp "$LTV_DIR"/*.wav scripts/testv/ - - cp "$LTV_DIR"/*.met scripts/testv/ - - cp "$LTV_DIR"/*.csv scripts/testv/ - .activate-Werror-linux: &activate-Werror-linux - sed -i.bak "s/^# \(CFLAGS += -Werror\)/\1/" Makefile @@ -261,22 +153,18 @@ workflow: # Job templates # --------------------------------------------------------------- -# templates to define stages and platforms -.test-job-linux: - tags: - - ivas-basop-linux - -.build-job-linux: - stage: build - timeout: "2 minutes" +# override for centrally defined job to make use of the basop runners +.job-linux: tags: - ivas-basop-linux -.build-job-windows: - stage: build - timeout: "4 minutes" - tags: - - ivas-windows +# custom variant of this template, we need to update the scripts repo before every build +.test-job-linux: + extends: + - .job-linux + script: + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh + - !reference [.job-linux, before_script] .print-results-banner: &print-results-banner - set +x @@ -307,11 +195,11 @@ workflow: IMAGES_ARTIFACT_SPLIT: "images_split_$CI_JOB_NAME" script: - set -euxo pipefail - - *print-common-info - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - if [ $USE_LTV -eq 1 ]; then - - *update-ltv-repo - - *copy-ltv-files-to-testv-dir + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh - testcase_timeout=$TESTCASE_TIMEOUT_LTV - else - testcase_timeout=$TESTCASE_TIMEOUT_STV @@ -319,12 +207,13 @@ workflow: - python3 ci/remove_unsupported_testcases.py $PRM_FILES - if [ $LEVEL_SCALING != "1.0" ]; then - - *apply-testv-scaling + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/apply-testv-scaling.sh - fi - if [ "$COMPARE_DMX" = "true" ] || [ "$ENCODER_TEST" = "true" ]; then - BUILD_WITH_DEBUG_MODE_INFO="true" - fi + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-and-create-float-ref-outputs.sh - INV_LEVEL_SCALING=$(awk "BEGIN {print 1.0 / $LEVEL_SCALING}") - comp_args="--mld --ssnr --odg --scalefac $INV_LEVEL_SCALING" @@ -417,8 +306,8 @@ workflow: - report-junit.xml .check-up-to-date-in-comparison-jobs: &check-up-to-date-in-comparison-jobs - - *get-commits-behind-count - | + commits_behind_count="$(bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/get-commits-behind-count.sh)" if [ $commits_behind_count -ne 0 ]; then set +x echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run. Checking bitexactness or testing for regressions now can result in meaningless results. Run\n\t git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." @@ -426,6 +315,8 @@ workflow: fi .check-be-to-target-anchor: &check-be-to-target-anchor + extends: + - .job-linux stage: check-be needs: ["build-codec-linux-make"] timeout: "300 minutes" @@ -434,16 +325,16 @@ workflow: HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" PYTEST_LOG_TARGET_BRANCH: "pytest-log-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME.txt" script: - - *print-common-info + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - set -euxo pipefail - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - python3 tests/create_short_testvectors.py - if [ $USE_LTV -eq 1 ]; then - - *update-ltv-repo - - *copy-ltv-files-to-testv-dir + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh - testcase_timeout=$TESTCASE_TIMEOUT_LTV - else - testcase_timeout=$TESTCASE_TIMEOUT_STV @@ -453,11 +344,11 @@ workflow: - python3 scripts/prepare_combined_format_inputs.py - if [ $LEVEL_SCALING != "1.0" ];then - - *apply-testv-scaling + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/apply-testv-scaling.sh - fi - - *build-float-ref-binaries - - *build-merge-target-binaries + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-binaries.sh float-ref + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-binaries.sh merge-target - make clean - make -j >> /dev/null - *check-up-to-date-in-comparison-jobs @@ -537,6 +428,8 @@ workflow: - fi .check-regressions-pytest-anchor: &check-regressions-pytest-anchor + extends: + - .job-linux stage: test timeout: "300 minutes" variables: @@ -549,7 +442,9 @@ workflow: IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" script: - - *print-common-info + - !reference [ .job-linux, before_script ] + + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh # create empty files for all artifacts to suppress warnings in case of no regressions found or all is BE - touch $XML_REPORT_BRANCH $XML_REPORT_MAIN $HTML_REPORT_BRANCH $HTML_REPORT_MAIN $CSV_BRANCH $CSV_MAIN $SUMMARY_HTML_ARTIFACT_NAME $FLOAT_REF_COMMIT_FILE $CUT_COMMIT_FILE $MERGE_TARGET_COMMIT_FILE regressions_crashes.csv regressions_MLD.csv regressions_MAX_ABS_DIFF.csv regressions_MIN_SSNR.csv regressions_MIN_ODG.csv improvements_crashes.csv improvements_MLD.csv improvements_MAX_ABS_DIFF.csv improvements_MIN_SSNR.csv improvements_MIN_ODG.csv @@ -570,8 +465,8 @@ workflow: - *update-scripts-repo - if [ $USE_LTV -eq 1 ]; then - - *update-ltv-repo - - *copy-ltv-files-to-testv-dir + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh - testcase_timeout=$TESTCASE_TIMEOUT_LTV - else - testcase_timeout=$TESTCASE_TIMEOUT_STV @@ -579,7 +474,7 @@ workflow: - python3 ci/remove_unsupported_testcases.py $PRM_FILES - if [ $LEVEL_SCALING != "1.0" ];then - - *apply-testv-scaling + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/apply-testv-scaling.sh - fi # check MR title for flag that allows regressions to be mergable @@ -591,7 +486,7 @@ workflow: ### run branch first # this per default builds the branch and the reference and creates the reference outputs - - *build-and-create-float-ref-outputs + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-and-create-float-ref-outputs.sh - *check-up-to-date-in-comparison-jobs # need to restore cache again - *overwrite-pytest-cache-with-artifact @@ -684,6 +579,8 @@ workflow: .ivas-pytest-sanitizers-anchor: &ivas-pytest-sanitizers-anchor + extends: + - .job-linux stage: test needs: ["build-codec-linux-make"] timeout: "600 minutes" @@ -695,12 +592,14 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'schedule' && $IVAS_PYTEST_MSAN - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "sanitizer" script: - - *print-common-info - - *update-scripts-repo - - *copy-ltv-files-to-testv-dir + - !reference [ .job-linux, before_script ] + + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh - python3 ci/remove_unsupported_testcases.py $PRM_FILES - - *build-float-ref-binaries + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-binaries.sh float-ref - set -euxo pipefail - make_args="CLANG=$CLANG_NUM" - if [[ $CLANG_NUM == 3 ]]; then @@ -728,6 +627,8 @@ workflow: - report-junit.xml .ivas-pytest-compare-to-input-anchor: &ivas-pytest-compare-to-input-anchor + extends: + - .job-linux stage: test needs: ["build-codec-linux-make"] timeout: "360 minutes" @@ -735,11 +636,13 @@ workflow: SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" script: - - *print-common-info - - *update-scripts-repo + - !reference [ .job-linux, before_script ] + + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - if [ $USE_LTV -eq 1 ]; then - - *update-ltv-repo - - *copy-ltv-files-to-testv-dir + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh - testcase_timeout=$TESTCASE_TIMEOUT_LTV - else - testcase_timeout=$TESTCASE_TIMEOUT_STV @@ -747,9 +650,9 @@ workflow: - python3 ci/remove_unsupported_testcases.py $PRM_FILES - if [ $LEVEL_SCALING != "1.0" ];then - - *apply-testv-scaling + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/apply-testv-scaling.sh - fi - - *build-float-ref-and-dut-binaries + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-float-ref-and-dut-binaries.sh - INV_LEVEL_SCALING=$(awk "BEGIN {print 1.0 / $LEVEL_SCALING}") - comp_args="--mld --ssnr --odg --scalefac $INV_LEVEL_SCALING" @@ -822,14 +725,15 @@ uninterruptible: branch-is-up-to-date-with-target-pre: extends: + - .job-linux - .rules-merge-request stage: prevalidate needs: [] tags: - ivas-basop-linux script: - - *get-commits-behind-count - | + commits_behind_count="$(bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/get-commits-behind-count.sh)" if [ $commits_behind_count -ne 0 ]; then echo -e "Your branch is $commits_behind_count commits behind the target branch, run\n\tgit pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." exit 1 @@ -837,13 +741,14 @@ branch-is-up-to-date-with-target-pre: branch-is-up-to-date-with-target-post: extends: + - .job-linux - .rules-merge-request stage: postvalidate tags: - ivas-basop-linux script: - - *get-commits-behind-count - | + commits_behind_count="$(bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/get-commits-behind-count.sh)" if [ $commits_behind_count -ne 0 ]; then echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run, run\n\tgit pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." exit 1 @@ -864,7 +769,7 @@ clang-format-check: needs: [] timeout: "5 minutes" script: - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh # Set up variables. This can't be done in the "variables" section because variables are not expanded properly there - PATCH_FILE_NAME="$ARTIFACT_BASE_NAME".patch - > @@ -918,7 +823,7 @@ build-codec-linux-make: - .build-job-linux timeout: "10 minutes" script: - - *print-common-info + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - *activate-Werror-linux - make -j @@ -935,8 +840,8 @@ build-codec-linux-instrumented-make: - .build-job-linux timeout: "10 minutes" script: - - *print-common-info - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - bash scripts/prepare_instrumentation.sh -m MEM_ONLY - make -j -C $INSTR_DIR @@ -954,8 +859,8 @@ build-codec-linux-debugging-make: variables: BUILD_WITH_DEBUG_MODE_INFO: "true" script: - - *print-common-info - - *activate-debug-mode-info-if-set + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/activate-debug-mode-info-if-set.sh - make -j build-codec-windows-msbuild: @@ -1444,14 +1349,14 @@ ivas-smoke-test-saturation: - USE_LTV=1 - LEVEL_SCALING=32768 - - *print-common-info - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - if [ $USE_LTV -eq 1 ]; then - - *update-ltv-repo - - *copy-ltv-files-to-testv-dir + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh - fi - if [ $LEVEL_SCALING != "1.0" ];then - - *apply-testv-scaling + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/apply-testv-scaling.sh - fi - cp -r scripts/testv/* $TESTV_DIR/ @@ -1487,11 +1392,11 @@ coverage-test-on-main-scheduled: stage: test timeout: 3 hours script: - - *print-common-info - - *update-scripts-repo - - *update-ltv-repo - - *copy-ltv-files-to-testv-dir - - *build-float-ref-binaries + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/copy-ltv-files-to-testv-dir.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-binaries.sh float-ref # Build DuT binaries with GCOV - make clean >> /dev/null - make GCOV=1 -j @@ -1548,8 +1453,8 @@ be-2-evs-26444: stage: test timeout: "120 minutes" # To be revisited script: - - *print-common-info - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - sed -i".bak" "s/\(#define EVS_FLOAT\)/\/\/\1/" lib_com/options.h - make -j >> /dev/null @@ -1613,7 +1518,7 @@ voip-be-on-merge-request: needs: ["build-codec-linux-make"] timeout: "10 minutes" script: - - *print-common-info + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - make clean - make -j >> /dev/null - python3 -m pytest tests/test_be_for_jbm_neutral_dly_profile.py @@ -1704,10 +1609,10 @@ voip-be-on-merge-request: GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: - - *print-common-info - - *update-scripts-repo - - *update-ltv-repo - - *build-float-ref-and-dut-binaries + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-float-ref-and-dut-binaries.sh - *complexity-measurements-setup # delete previous jobs logfiles if present (-f flag ensures return calue of 0 even in first run where this folder is not present) - rm -rf COMPLEXITY/logs @@ -2085,8 +1990,8 @@ pages: rules: - if: $UPDATE_PAGES script: - - *print-common-info - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - python3 ci/setup_pages.py - ls - ls -lh public -- GitLab From 8b86fdaebc520a6418208d4ddd20119b637cd82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Thu, 24 Apr 2025 17:54:06 +0200 Subject: [PATCH 1119/1221] Post-rebase fixes --- .gitlab-ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2f3176df7..90afc1508 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -164,7 +164,6 @@ workflow: - .job-linux script: - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - - !reference [.job-linux, before_script] .print-results-banner: &print-results-banner - set +x @@ -175,7 +174,7 @@ workflow: .test-job-linux-needs-testv-dir: extends: .test-job-linux before_script: - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - if [ ! -d "$TESTV_DIR" ]; then mkdir -p $TESTV_DIR; fi - cp -r scripts/testv/* $TESTV_DIR/ @@ -223,7 +222,7 @@ workflow: - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; MEASURES_FOR_REPORT="$MEASURES_FOR_REPORT DELTA_ODG"; fi - if [ "$SPLIT_COMPARISON" = "true" ]; then comp_args="${comp_args} --split-comparison"; fi - - *build-and-create-float-ref-outputs + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/build-and-create-float-ref-outputs.sh # DMX comparison only in manual job with no other metrics - if [ "$COMPARE_DMX" = "true" ]; then @@ -462,7 +461,7 @@ workflow: - exit 0 - fi - - *update-scripts-repo + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - if [ $USE_LTV -eq 1 ]; then - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh -- GitLab From c65468f22f7f7f634fce60979d8eca266d91fc18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Thu, 24 Apr 2025 19:25:22 +0200 Subject: [PATCH 1120/1221] Fix missing update hook --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 90afc1508..20c8510a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -162,8 +162,9 @@ workflow: .test-job-linux: extends: - .job-linux - script: - - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh + before_script: + - !reference [.job-linux, before_script] + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh .print-results-banner: &print-results-banner - set +x -- GitLab From 30a45771fdcc00dae848430c0b8fc53c736358ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Thu, 24 Apr 2025 20:53:47 +0200 Subject: [PATCH 1121/1221] Clean up and fix check-be-to-target/check-regressions-pytest jobs --- .gitlab-ci.yml | 224 ++++++++++++++++++------------------------------- 1 file changed, 80 insertions(+), 144 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 20c8510a8..ee0b8a104 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -314,9 +314,22 @@ workflow: exit 1 fi -.check-be-to-target-anchor: &check-be-to-target-anchor +.check-be-job: extends: - - .job-linux + - .test-job-linux + before_script: + - !reference [ .test-job-linux, before_script ] + - rm -rf tests/dut tests/ref + variables: + USE_LTV: 0 + DUT_ENCODER_PATH: ./IVAS_cod_ref + DUT_DECODER_PATH: ./IVAS_dec_ref + MERGE_TARGET_ENCODER_PATH: ./IVAS_cod_ref + MERGE_TARGET_DECODER_PATH: ./IVAS_dec_ref + +.check-be-to-target-job: + extends: + - .check-be-job stage: check-be needs: ["build-codec-linux-make"] timeout: "300 minutes" @@ -427,10 +440,13 @@ workflow: - unzip $PYTEST_CACHE_ARTIFACT - fi -.check-regressions-pytest-anchor: &check-regressions-pytest-anchor +.check-regressions-pytest-job: extends: - - .job-linux + - .check-be-job stage: test + needs: + - job: "check-be-to-target-short-enc-0db" + artifacts: true timeout: "300 minutes" variables: XML_REPORT_BRANCH: "report-junit-branch-$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" @@ -442,8 +458,6 @@ workflow: IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" script: - - !reference [ .job-linux, before_script ] - - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh # create empty files for all artifacts to suppress warnings in case of no regressions found or all is BE @@ -888,178 +902,100 @@ build-codec-windows-msbuild: ### jobs that check for bitexactness of fx encoder and decoder check-be-to-target-short-enc-0db: extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_DECODER_PATH=./IVAS_dec_ref - - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref - - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=1.0 - - rm -rf tests/dut tests/ref - <<: *check-be-to-target-anchor + - .check-be-to-target-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" + # -/-0dB + LEVEL_SCALING: "1.0" check-be-to-target-short-enc-+10db: extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_DECODER_PATH=./IVAS_dec_ref - - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref - - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=3.162 - - rm -rf tests/dut tests/ref - <<: *check-be-to-target-anchor + - .check-be-to-target-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" + # +10dB + LEVEL_SCALING: "3.162" check-be-to-target-short-enc--10db: extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_DECODER_PATH=./IVAS_dec_ref - - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref - - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=0.3162 - - rm -rf tests/dut tests/ref - <<: *check-be-to-target-anchor + - .check-be-to-target-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" + # -10dB + LEVEL_SCALING: "0.3162" check-be-to-target-short-dec-0db: extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_ENCODER_PATH=./IVAS_cod_ref - - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=1.0 - - rm -rf tests/dut tests/ref - <<: *check-be-to-target-anchor + - .check-be-to-target-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE" + # +/-0dB + LEVEL_SCALING: "1.0" check-be-to-target-short-dec-+10db: extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_ENCODER_PATH=./IVAS_cod_ref - - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=3.162 - - rm -rf tests/dut tests/ref - <<: *check-be-to-target-anchor + - .check-be-to-target-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE" + # +10dB + LEVEL_SCALING: "3.162" check-be-to-target-short-dec--10db: extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_ENCODER_PATH=./IVAS_cod_ref - - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=0.3162 - - rm -rf tests/dut tests/ref - <<: *check-be-to-target-anchor + - .check-be-to-target-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE" + # -10dB + LEVEL_SCALING: "0.3162" ### jobs that check for regressions on non-BE testcases check-regressions-short-enc-0db: - stage: test - needs: - - job: "check-be-to-target-short-enc-0db" - artifacts: true extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_DECODER_PATH=./IVAS_dec_ref - - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=1.0 - - rm -rf tests/dut tests/ref - <<: *check-regressions-pytest-anchor + - .check-regressions-pytest-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" + # +/-0dB + LEVEL_SCALING: "1.0" check-regressions-short-enc-+10db: - stage: test - needs: - - job: "check-be-to-target-short-enc-+10db" - artifacts: true extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_DECODER_PATH=./IVAS_dec_ref - - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=3.162 - - rm -rf tests/dut tests/ref - <<: *check-regressions-pytest-anchor + - .check-regressions-pytest-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" + # +10dB + LEVEL_SCALING: "3.162" check-regressions-short-enc--10db: - stage: test - needs: - - job: "check-be-to-target-short-enc--10db" - artifacts: true extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_DECODER_PATH=./IVAS_dec_ref - - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" - - LEVEL_SCALING=0.3162 - - rm -rf tests/dut tests/ref - <<: *check-regressions-pytest-anchor + - .check-regressions-pytest-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" + # -10dB + LEVEL_SCALING: "0.3162" check-regressions-short-dec-0db: - stage: test - needs: - - job: "check-be-to-target-short-dec-0db" - artifacts: true extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_ENCODER_PATH=./IVAS_cod_ref - - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=1.0 - - rm -rf tests/dut tests/ref - <<: *check-regressions-pytest-anchor + - .check-regressions-pytest-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE" + # +/-0dB + LEVEL_SCALING: "1" check-regressions-short-dec-+10db: - stage: test - needs: - - job: "check-be-to-target-short-dec-+10db" - artifacts: true extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_ENCODER_PATH=./IVAS_cod_ref - - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=3.162 - - rm -rf tests/dut tests/ref - <<: *check-regressions-pytest-anchor + - .check-regressions-pytest-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE" + # +10dB + LEVEL_SCALING: "3.162" check-regressions-short-dec--10db: - stage: test - needs: - - job: "check-be-to-target-short-dec--10db" - artifacts: true extends: - - .rules-pytest-to-main-short - - .test-job-linux - before_script: - - USE_LTV=0 - - DUT_ENCODER_PATH=./IVAS_cod_ref - - TEST_SUITE="$SHORT_TEST_SUITE" - - LEVEL_SCALING=0.3162 - - rm -rf tests/dut tests/ref - <<: *check-regressions-pytest-anchor + - .check-regressions-pytest-job + variables: + TEST_SUITE: "$SHORT_TEST_SUITE" + # -10dB + LEVEL_SCALING: "0.3162" # --------------------------------------------------------------- # Short test jobs for running from web interface or schedule -- GitLab From 409948139be266df763bc613d756a51fbfe85edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Thu, 24 Apr 2025 22:29:14 +0200 Subject: [PATCH 1122/1221] Pin latest commit on main --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ee0b8a104..a00af3162 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ variables: - # note: GitLab cannot reference the variable in the include ref:, we need to use a YAML anchor for this - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF mullerfa/ci-refactor + # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this + # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 4eb4c0dfbdc845280a9994b5f7540f69c737537b include: - local: .gitlab-ci/variables.yml -- GitLab From bbf760a19cbfbc975b508140b4e03d2c622f798b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 25 Apr 2025 11:57:02 +0530 Subject: [PATCH 1123/1221] Fix for 3GPP issue 1508: BASOP decoder asserts in ivas_wb_tbe_dec_fx with OMASA FER bitstream from BASOP encoder Link #1508 --- lib_com/swb_tbe_com_fx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5f391b271..5631dfa94 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -1645,7 +1645,12 @@ void GenShapedWBExcitation_ivas_fx( } } - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); + Scale_sig( state_lpc_syn, LPC_SHB_ORDER, -Q2 ); /* Q(Q_bwe_exc) -> Q(Q_bwe_exc - 2) */ + + Syn_filt_s( Q2, lpc_shb, LPC_SHB_ORDER_WB, exc4kWhtnd, excSHB, L_FRAME16k / 4, state_lpc_syn, 1 ); + + Scale_sig( state_lpc_syn, LPC_SHB_ORDER, Q2 ); /* Q(Q_bwe_exc - 2) -> Q(Q_bwe_exc) */ + Scale_sig( excSHB, L_FRAME16k / 4, Q2 ); /* Q(Q_bwe_exc - 2) -> Q(Q_bwe_exc) */ return; } -- GitLab From 8cbfea6c3aa81df3b8df6e8a0764dae0860be894 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 25 Apr 2025 12:28:57 +0530 Subject: [PATCH 1124/1221] Fix for LTV crash observed for test case: [ltv_basop_encoder-MASA 2TC at 192 kbps, 48kHz in, 48kHz out, EXT out] --- lib_enc/speech_music_classif_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index cf6ba543b..65000a7b3 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2006,8 +2006,8 @@ Word16 ivas_smc_gmm_fx( { Word32 tmp_max; tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); - - temp32 = BASOP_Util_Divide3232_Scale_newton( tmp_max, L_add( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp + /* Saturation doesn't have a significant impact here, as a value of 1e-5 in Q31 format is added to prevent division by zero */ + temp32 = BASOP_Util_Divide3232_Scale_newton( tmp_max, L_add_sat( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); -- GitLab From a6621c0de4709c34666afddbe0f4d6d80fec78a3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 25 Apr 2025 14:31:35 +0530 Subject: [PATCH 1125/1221] ASAN and MSAN error fix for decoder pipeline --- lib_dec/ivas_core_dec_fx.c | 2 +- lib_dec/ivas_dirac_dec_fx.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 320d9d4bc..38ec5b943 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1030,7 +1030,7 @@ ivas_error ivas_core_dec_fx( /* Memories Re-Scaling */ Copy_Scale_sig_16_32_no_sat( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 // Q_input can get value <= -5 - Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], synth_32_fx[n], output_frame, sub( Q11, Q_synth_fx ) ); // Q11 IF( hBWE_FD != NULL ) { diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index 403e11f00..7fecb7ca7 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -1511,10 +1511,25 @@ void ivas_qmetadata_to_dirac_fx( { FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { - hSpatParamRendCom->azimuth2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); + /* Right shifting -1 -> -1, Hence this change is done */ + Word32 L_tmp = L_abs( q_direction->band_data[band].azimuth_fx[block] ); + hSpatParamRendCom->azimuth2[meta_write_index][b] = extract_h( L_shr( L_tmp, 6 ) ); move16(); - hSpatParamRendCom->elevation2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); + IF( q_direction->band_data[band].azimuth_fx[block] < 0 ) + { + hSpatParamRendCom->azimuth2[meta_write_index][b] = negate( hSpatParamRendCom->azimuth2[meta_write_index][b] ); + move16(); + } + + L_tmp = L_abs( q_direction->band_data[band].elevation_fx[block] ); + hSpatParamRendCom->elevation2[meta_write_index][b] = extract_h( L_shr( L_tmp, 6 ) ); move16(); + IF( q_direction->band_data[band].elevation_fx[block] < 0 ) + { + hSpatParamRendCom->elevation2[meta_write_index][b] = negate( hSpatParamRendCom->elevation2[meta_write_index][b] ); + move16(); + } + hSpatParamRendCom->energy_ratio2_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; move32(); hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], q_direction->band_data[band].energy_ratio_fx[block] ); -- GitLab From 1917992dcf9d8c7c899debc82fc0b11a882044ed Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 25 Apr 2025 15:20:40 +0530 Subject: [PATCH 1126/1221] Fix for 3GPP issue 1509: BASOP decoder asserts in ivas_dirac_dec_binaural_determine_processing_matrices_fx with OMASA rate switching bitstream from BASOP encoder Link #1509 --- lib_dec/ivas_stereo_switching_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index bcf714352..677c91ef0 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -2351,7 +2351,7 @@ static Word32 ncross_corr_self_fx( q_prod = sub( 81, add( add( headroom_left_x, headroom_left_y ), q_prod ) ); energy = Sqrt32( energy, &q_prod ); - IF( LT_32( energy, L_shl_sat( 1, sub( 31, q_prod ) ) ) ) + IF( LE_32( energy, L_shl_sat( 1, sub( 31, q_prod ) ) ) ) { c_c_fx_return = W_shl_sat_l( c_c_fx, 31 - ( 2 * OUTPUT_Q + 1 ) ); // Q31 } -- GitLab From d80b5ea123605a6e959539370ccab5f1be076e88 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 25 Apr 2025 14:27:46 +0530 Subject: [PATCH 1127/1221] Fix for 3GPP issue 1516: BASOP encoder crash with OSBA with 4 objects Link #1516 --- lib_enc/bw_detect_fx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib_enc/bw_detect_fx.c b/lib_enc/bw_detect_fx.c index 30382cfba..050adbf01 100644 --- a/lib_enc/bw_detect_fx.c +++ b/lib_enc/bw_detect_fx.c @@ -48,7 +48,7 @@ void bw_detect_fx( const Word16 mct_on, /* i : flag MCT mode */ const Word16 Q_spec ) { - Word16 Q_dct; + Word16 Q_dct, E_spect_bin, tmp_1; Word16 i, j, k, bw_max, bin_width, n_bins; Word16 max_NB, max_WB, max_SWB, max_FB, mean_NB, mean_WB, mean_SWB, mean_FB; /* Q11*/ const Word16 *pt, *pt1; @@ -324,6 +324,7 @@ void bw_detect_fx( set16_fx( spect_bin, 1, n_bins ); Q_dct = shl( Q_dct, 1 ); + E_spect_bin = sub( Q31, Q_dct ); FOR( k = 0; k <= bw_max; k++ ) { @@ -336,9 +337,9 @@ void bw_detect_fx( sum32 = L_mac0_o( sum32, *pt1, *pt1, &Overflow ); pt1++; } + tmp_1 = BASOP_Util_Cmp_Mant32Exp( sum32, E_spect_bin, MAX_32, Q31 - 41 ); /* Any sum32 in Q_dct if it is less than MAX_32 in Q41 will be less than 0.001 */ test(); - test(); - IF( st->element_mode != EVS_MONO && EQ_32( sum32, MAX_32 ) && GT_16( Q_dct, 41 ) /* Any Q-value greater than Q41 for MAX_32 will be less than 0.001*/ ) + IF( st->element_mode != EVS_MONO && tmp_1 < 0 ) { spect_bin[i] = -6144; /* log10f( 0.00100000005 ) in Q11 */ move16(); -- GitLab From 0f3ed1d91bae5e3718922a7d92a2886f3169ea09 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Sun, 27 Apr 2025 09:46:59 +0200 Subject: [PATCH 1128/1221] Attempt to fix missing rules and missing fetch of ci scripts --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a00af3162..8fb379bf9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -195,6 +195,8 @@ workflow: IMAGES_ARTIFACT_NAME: "images_$CI_JOB_NAME" IMAGES_ARTIFACT_SPLIT: "images_split_$CI_JOB_NAME" script: + - !reference [ .job-linux, before_script ] + - set -euxo pipefail - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh @@ -318,6 +320,7 @@ workflow: .check-be-job: extends: - .test-job-linux + - .rules-pytest-to-main-short before_script: - !reference [ .test-job-linux, before_script ] - rm -rf tests/dut tests/ref -- GitLab From 5d486dc952b6a20ea856c3e144e3c7336e223393 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Sun, 27 Apr 2025 20:59:49 +0200 Subject: [PATCH 1129/1221] Add fix to pages job --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8fb379bf9..bebb7d024 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1930,6 +1930,8 @@ pages: rules: - if: $UPDATE_PAGES script: + - !reference [ .job-linux, before_script ] + - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - python3 ci/setup_pages.py -- GitLab From bd8637d94fda7573c15f0e07b714299f3bb4ac7e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 25 Apr 2025 14:55:08 +0530 Subject: [PATCH 1130/1221] Fix for 3GPP issue 1427: Basop Encoder Spectral Gaps in Stereo DTX 13.2 kbps Noisy Signal Link #1427 --- lib_enc/ivas_core_enc_fx.c | 19 ++++++------------- lib_enc/ivas_core_pre_proc_fx.c | 14 ++++++++++---- lib_enc/prot_fx_enc.h | 1 + lib_enc/stat_enc.h | 2 +- lib_enc/swb_bwe_enc_fx.c | 17 +++++++++-------- lib_enc/swb_pre_proc_fx.c | 15 ++++++++++++++- 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/lib_enc/ivas_core_enc_fx.c b/lib_enc/ivas_core_enc_fx.c index f5d3c4d73..6fcb8abd0 100644 --- a/lib_enc/ivas_core_enc_fx.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -675,12 +675,6 @@ ivas_error ivas_core_enc_fx( wb_bwe_enc_ivas_fx( st, new_inp_resamp16k_fx[n] ); } - IF( st->hBWE_FD != NULL ) - { - Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, Q1 ); // Q-1 -> Q0 - st->Q_old_wtda = add( st->Q_old_wtda, Q1 ); - move16(); - } /*---------------------------------------------------------------------* * SWB(FB) TBE encoding @@ -725,8 +719,6 @@ ivas_error ivas_core_enc_fx( Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, shift ); // st->Q_old_wtda } - Word16 q_new_swb_speech_buffer = getScaleFactor16( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX ); - Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // Q0->q_new_swb_speech_buffer /* SWB TBE encoder */ test(); @@ -750,11 +742,9 @@ ivas_error ivas_core_enc_fx( } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) ) { - Copy_Scale_sig_32_16( shb_speech_fx32, shb_speech_fx, L_FRAME16k, -Q16 ); // Q_shb_spch - 16 - Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, negate( q_new_swb_speech_buffer ) ); // q_new_swb_speech_buffer -> Q0 + Copy_Scale_sig_32_16( shb_speech_fx32, shb_speech_fx, L_FRAME16k, -Q16 ); // Q_shb_spch - 16 /* SWB(FB) BWE encoder */ - swb_bwe_enc_ivas_fx( st, last_element_mode, old_inp_12k8_fx[n], old_inp_16k_fx[n], old_syn_12k8_16k_fx[n], new_swb_speech_fx_16, shb_speech_fx, sub( Q_shb_spch, Q16 ), sub( Q_new[n], 1 ) ); - Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // Q0 -> q_new_swb_speech_buffer + swb_bwe_enc_ivas_fx( st, last_element_mode, old_inp_12k8_fx[n], old_inp_16k_fx[n], old_syn_12k8_16k_fx[n], new_swb_speech_fx_16, st->q_inp, shb_speech_fx, sub( Q_shb_spch, Q16 ), sub( Q_new[n], 1 ) ); } Scale_sig( old_syn_12k8_16k_fx[n], L_FRAME16k, sub( Q1, Q_new[n] ) ); // Q0 @@ -776,6 +766,9 @@ ivas_error ivas_core_enc_fx( * Inter-channel BWE encoding *-------------------------------------------------------------------*/ + Word16 q_new_swb_speech_buffer = getScaleFactor16( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX ); + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // st->q_inp+q_new_swb_speech_buffer + q_new_swb_speech_buffer = add( st->q_inp, q_new_swb_speech_buffer ); test(); test(); IF( n == 0 && GE_32( input_Fs, 32000 ) && hStereoICBWE != NULL ) @@ -784,7 +777,7 @@ ivas_error ivas_core_enc_fx( stereo_icBWE_preproc_fx( hCPE, input_frame, new_swb_speech_buffer_fx_16 /*tmp buffer*/, q_new_swb_speech_buffer ); q_new_swb_speech_buffer = add( q_new_swb_speech_buffer, 16 ); - Copy_Scale_sig_16_32_no_sat( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, L_FRAME48k + STEREO_DFT_OVL_MAX, Q16 ); // q_new_swb_speech_buffer - 16 - > q_new_swb_speech_buffer + Copy_Scale_sig_16_32_no_sat( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, L_FRAME48k + STEREO_DFT_OVL_MAX, Q16 ); // q_new_swb_speech_buffer+st->q_inp - 16 - > q_new_swb_speech_buffer+st->q_inp Copy_Scale_sig_16_32_no_sat( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 stereo_icBWE_enc_ivas_fx( hCPE, shb_speech_fx32, sub( Q31, Q_shb_spch ), new_swb_speech_buffer_fx, sub( Q31, q_new_swb_speech_buffer ), voice_factors_fx32[0] ); diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 6fe6b6720..48253aed6 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -886,8 +886,11 @@ ivas_error ivas_compute_core_buffers_fx( IF( EQ_16( st->bwidth, WB ) ) { - Copy_Scale_sig( new_inp_16k_fx - delay, st->hBWE_FD->old_input_wb_fx, delay, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ - Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - STEREO_DFT_OVL_16k + delay, sub( STEREO_DFT_OVL_16k, delay ) ); /* Check Q here once. Q should be Q_old_wtda */ + Copy_Scale_sig( new_inp_16k_fx - delay, st->hBWE_FD->old_input_wb_fx, delay, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ + scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( Q_old_inp_16k, st->Q_old_wtda ) ); // st->Q_old_wtda->Q_old_inp_16k + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - STEREO_DFT_OVL_16k + delay, sub( STEREO_DFT_OVL_16k, delay ) ); + st->Q_old_wtda = Q_old_inp_16k; + move16(); } } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) @@ -898,8 +901,11 @@ ivas_error ivas_compute_core_buffers_fx( test(); IF( EQ_16( st->bwidth, WB ) && st->hBWE_FD != NULL ) { - Copy_Scale_sig( new_inp_16k_fx + L_FILT16k - delay, st->hBWE_FD->old_input_wb_fx, delay, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ - Copy( new_inp_16k_fx - L_MEM_RECALC_16K, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - L_MEM_RECALC_16K - L_FILT16k + delay, sub( L_MEM_RECALC_16K + L_FILT16k, delay ) ); /* Check Q here once. Q should be Q_old_wtda */ + Copy_Scale_sig( new_inp_16k_fx + L_FILT16k - delay, st->hBWE_FD->old_input_wb_fx, delay, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ + scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( Q_old_inp_16k, st->Q_old_wtda ) ); // st->Q_old_wtda->Q_old_inp_16k + Copy( new_inp_16k_fx - L_MEM_RECALC_16K, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - L_MEM_RECALC_16K - L_FILT16k + delay, sub( L_MEM_RECALC_16K + L_FILT16k, delay ) ); + st->Q_old_wtda = Q_old_inp_16k; + move16(); } } ELSE IF( element_mode == IVAS_SCE ) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 4237aa9c3..11d6404b7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -639,6 +639,7 @@ void swb_bwe_enc_ivas_fx( Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ const Word16 *new_swb_speech_fx, /* i : original input signal at 32kHz */ + const Word16 Q_new_swb_speech, /* i : Q for new_swb_speech_fx */ Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz */ Word16 Q_shb_speech, Word16 Q_slb_speech ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 45ec01b31..4da0bff61 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1013,7 +1013,7 @@ typedef struct fd_bwe_enc_structure { Word16 new_input_hp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS )]; // Q_new_input_hp Word16 Q_new_input_hp; - Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS )]; // q0 + Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS )]; // st->q_inp Word16 old_input_wb_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; /* Q(-1) */ Word16 old_input_lp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS )]; // st->hBWE_FD->prev_Q_input_lp Word16 old_syn_12k8_16k_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; // st->Q_syn diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 1ebef7404..6b309c334 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -270,6 +270,7 @@ void swb_bwe_enc_ivas_fx( Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ const Word16 *new_swb_speech_fx, /* i : original input signal at 32kHz */ + const Word16 Q_new_swb_speech, /* i : Q for new_swb_speech_fx */ Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz */ Word16 Q_shb_speech, Word16 Q_slb_speech ) @@ -287,7 +288,7 @@ void swb_bwe_enc_ivas_fx( Word16 old_input_lp_fx[L_FRAME16k]; Word16 new_input_hp_fx[L_FRAME16k]; Word16 yorig_fx[L_FRAME48k]; - Word16 scl, new_input_fx_exp; + Word16 scl, new_input_fx_q; Word16 max; Word16 Sample_Delay_SWB_BWE; Word16 Sample_Delay_HP; @@ -412,7 +413,7 @@ void swb_bwe_enc_ivas_fx( * SWB BWE encoding * FB BWE encoding *---------------------------------------------------------------------*/ - new_input_fx_exp = 0; + new_input_fx_q = Q_new_swb_speech; move16(); test(); IF( ( EQ_16( st_fx->idchan, 1 ) ) && ( EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) @@ -424,12 +425,12 @@ void swb_bwe_enc_ivas_fx( } } /* MDCT of the core synthesis signal */ - wtda_fx( old_input_fx, &new_input_fx_exp, L_old_input_fx, hBWE_FD->L_old_wtda_swb_fx, + wtda_fx( old_input_fx, &new_input_fx_q, L_old_input_fx, hBWE_FD->L_old_wtda_swb_fx, &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ inner_frame ); /* DCT of the ACELP core synthesis */ - direct_transform_fx( L_old_input_fx, yorig_32, 0, inner_frame, &new_input_fx_exp, st_fx->element_mode ); + direct_transform_fx( L_old_input_fx, yorig_32, 0, inner_frame, &new_input_fx_q, st_fx->element_mode ); /* high-band gain control in case of BWS */ IF( st_fx->bwidth_sw_cnt > 0 ) @@ -438,7 +439,7 @@ void swb_bwe_enc_ivas_fx( } /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ - scl = sub( 16 + 8, new_input_fx_exp ); + scl = sub( 16 + 8, new_input_fx_q ); /* Possible to Upscale? */ IF( scl > 0 ) { @@ -449,7 +450,7 @@ void swb_bwe_enc_ivas_fx( scl = s_min( Q_synth, scl ); } Copy_Scale_sig32_16( yorig_32, yorig_fx, inner_frame, scl ); - Q_synth = add( sub( new_input_fx_exp, 16 ), scl ); + Q_synth = add( sub( new_input_fx_q, 16 ), scl ); max = 0; move16(); Q_synth_hf = 0; @@ -558,12 +559,12 @@ void swb_bwe_enc_ivas_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_exp, new_input_fx_exp ); + SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_q, new_input_fx_q ); } ELSE { SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, new_input_fx_exp, new_input_fx_exp ); + SWB_fenv_fx, tilt_nb_fx, 6, Q_slb_speech, Q_shb, new_input_fx_q, new_input_fx_q ); } diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index ba165cba4..30cfb4920 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -166,6 +166,8 @@ void wb_pre_proc_fx( Copy( hBWE_FD->old_input_wb_fx, old_input, Sample_Delay_WB_BWE ); Copy( new_inp_resamp16k + L_FRAME16k - Sample_Delay_WB_BWE, hBWE_FD->old_input_wb_fx, Sample_Delay_WB_BWE ); Copy( old_input, hBWE_FD->L_old_wtda_swb_fx, L_FRAME16k ); + st_fx->Q_old_wtda = -1; + move16(); } return; } @@ -778,7 +780,7 @@ void swb_pre_proc_fx( /*full implementation pending*/ void swb_pre_proc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - Word16 *new_swb_speech, /* o : original input signal at 32kHz - Q0 */ + Word16 *new_swb_speech, /* o : original input signal at 32kHz - st->q_inp */ Word32 *new_swb_speech_fx, /* o : original input signal at 32kHz - Q - q_reImBuffer */ Word16 *shb_speech, /* o : SHB target signal (6-14kHz) at 16kHz- Q(Q_shb_spch) */ Word16 *Q_shb_spch, @@ -846,6 +848,9 @@ void swb_pre_proc_ivas_fx( test(); test(); + scale_sig( hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( st->q_inp, st->Q_old_wtda ) ); // st->Q_old_wtda -> st->q_inp + st->Q_old_wtda = st->q_inp; + move16(); IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && GE_16( st->bwidth, SWB ) ) { Copy( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ) ); @@ -880,6 +885,8 @@ void swb_pre_proc_ivas_fx( IF( NE_16( st->extl, WB_BWE ) ) { Copy( old_input_fx, hBWE_FD->L_old_wtda_swb_fx, L_FRAME32k ); + st->Q_old_wtda = st->q_inp; + move16(); } } @@ -929,6 +936,10 @@ void swb_pre_proc_ivas_fx( test(); test(); + scale_sig( hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( st->q_inp, st->Q_old_wtda ) ); // st->Q_old_wtda -> st->q_inp + st->Q_old_wtda = st->q_inp; + move16(); + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && GE_16( st->bwidth, SWB ) ) { IF( EQ_16( st->bwidth, SWB ) ) @@ -1029,6 +1040,8 @@ void swb_pre_proc_ivas_fx( set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); Copy( new_swb_speech + inner_frame - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); Copy( old_input_fx, hBWE_FD->L_old_wtda_swb_fx, inner_frame ); + st->Q_old_wtda = st->q_inp; + move16(); } /* resample 48 kHz to 32kHz */ -- GitLab From 6e4399ee5756cb057a36cfd0e8a8b99367f53b03 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 28 Apr 2025 08:46:47 +0530 Subject: [PATCH 1131/1221] EVS bitexactness fix --- lib_enc/swb_pre_proc_fx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 30cfb4920..8991696e6 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -166,8 +166,6 @@ void wb_pre_proc_fx( Copy( hBWE_FD->old_input_wb_fx, old_input, Sample_Delay_WB_BWE ); Copy( new_inp_resamp16k + L_FRAME16k - Sample_Delay_WB_BWE, hBWE_FD->old_input_wb_fx, Sample_Delay_WB_BWE ); Copy( old_input, hBWE_FD->L_old_wtda_swb_fx, L_FRAME16k ); - st_fx->Q_old_wtda = -1; - move16(); } return; } -- GitLab From 88d341f8f88423ca0ab7073d99a5a78b47e23140 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 28 Apr 2025 08:50:42 +0530 Subject: [PATCH 1132/1221] Fix for renderer crashes in CI ltv test --- lib_rend/ivas_dirac_rend_fx.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 2540426cc..06b37ff5a 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -5007,10 +5007,20 @@ static void ivas_masa_ext_dirac_render_sf_fx( ELSE { /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + /* cldfb_state_fx should be in 1 less q-factor compared to cld buffers for cldfbSynthesis_ivas_fx function */ Word16 q_out = sub( q_cldfb, 1 ); - scale_sig32( hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_length, sub( q_out, hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state ) ); // q_out - hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state = q_out; - move16(); + Word16 max_shift = L_norm_arr( hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_length ); + IF( GT_16( max_shift, sub( q_out, hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state ) ) ) + { + scale_sig32( hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_length, sub( q_out, hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state ) ); // q_out + hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state = q_out; + move16(); + } + ELSE + { + scale_sig32( Cldfb_RealBuffer_fx[idx_in][i], hSpatParamRendCom->num_freq_bands, sub( hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state, q_out ) ); + scale_sig32( Cldfb_ImagBuffer_fx[idx_in][i], hSpatParamRendCom->num_freq_bands, sub( hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state, q_out ) ); + } FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) { RealBuffer_fx[i] = Cldfb_RealBuffer_fx[idx_in][i]; // q_cldfb -- GitLab From d0c0db1c0c943fa2a048363c792ca5a934e92b7d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 28 Apr 2025 17:23:12 +0530 Subject: [PATCH 1133/1221] Complexity measure crash fix for ltv48_STEREO_StereoDmxEvs_b07_16_dtx_wb_rs_fer_ep_10pct_fer_g192 --- lib_dec/igf_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 0010b9466..aa3f35b26 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -244,7 +244,7 @@ static void IGF_replaceTCXNoise_2( Word32 *in, /**< in g = getSqrtWord32( L_mult( divide3232( totalNoiseNrg, rE ), 8192 /*1.0f / 4.0f Q15*/ ) ); // ((Q15 + Q15 + Q1) / 2) -> Q15 - g = shl( g, 1 ); // Q16 + g = shl_sat( g, 1 ); // Q16 FOR( sb = start; sb < stop; sb++ ) { -- GitLab From 66f93c33e18041835fe487df49e96c09f6bfda20 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 28 Apr 2025 17:28:03 +0530 Subject: [PATCH 1134/1221] Clang formatting changes --- lib_dec/igf_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index aa3f35b26..511d8a977 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -244,7 +244,7 @@ static void IGF_replaceTCXNoise_2( Word32 *in, /**< in g = getSqrtWord32( L_mult( divide3232( totalNoiseNrg, rE ), 8192 /*1.0f / 4.0f Q15*/ ) ); // ((Q15 + Q15 + Q1) / 2) -> Q15 - g = shl_sat( g, 1 ); // Q16 + g = shl_sat( g, 1 ); // Q16 FOR( sb = start; sb < stop; sb++ ) { -- GitLab From 62465ef34e84a79f011e1cd7da55dea4e57fed0b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 28 Apr 2025 17:37:40 +0530 Subject: [PATCH 1135/1221] Fix for 3GPP issue 1524: BASOP decoder asserts in ivas_dirac_dec_binaural_determine_processing_matrices_fx with OMASA BASOP encoder bitstream using rate switching Link #1524 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 922a4ef12..412b8c226 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -2096,6 +2096,21 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); q_tmp2 = add( q_res, exp ); + + /*Limiting value to Q63*/ + IF( GT_16( q_tmp2, 63 ) ) + { + tmp2 = L_shl( tmp2, sub( 63, q_tmp2 ) ); + q_tmp2 = 63; + move16(); + IF( EQ_32( tmp2, -1 ) ) + { + tmp2 = 0; + move32(); + q_tmp2 = 31; + move16(); + } + } IF( LT_16( q_CrEne, q_tmp2 ) ) { realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); -- GitLab From 6ee710fdf94a104a3bfc33db55f2225c6feaead6 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 28 Apr 2025 15:13:02 +0200 Subject: [PATCH 1136/1221] fix bug in CI config wrt binary naming in BE and regression checks --- .gitlab-ci.yml | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bebb7d024..95edafd47 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -326,10 +326,6 @@ workflow: - rm -rf tests/dut tests/ref variables: USE_LTV: 0 - DUT_ENCODER_PATH: ./IVAS_cod_ref - DUT_DECODER_PATH: ./IVAS_dec_ref - MERGE_TARGET_ENCODER_PATH: ./IVAS_cod_ref - MERGE_TARGET_DECODER_PATH: ./IVAS_dec_ref .check-be-to-target-job: extends: @@ -911,6 +907,9 @@ check-be-to-target-short-enc-0db: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # -/-0dB LEVEL_SCALING: "1.0" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-be-to-target-short-enc-+10db: extends: @@ -919,6 +918,9 @@ check-be-to-target-short-enc-+10db: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # +10dB LEVEL_SCALING: "3.162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-be-to-target-short-enc--10db: extends: @@ -927,6 +929,9 @@ check-be-to-target-short-enc--10db: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # -10dB LEVEL_SCALING: "0.3162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-be-to-target-short-dec-0db: extends: @@ -935,6 +940,9 @@ check-be-to-target-short-dec-0db: TEST_SUITE: "$SHORT_TEST_SUITE" # +/-0dB LEVEL_SCALING: "1.0" + # overwrite encoder with float reference one + DUT_ENCODER_PATH: "$REF_ENCODER_PATH" + MERGE_TARGET_ENCODER_PATH: "$REF_ENCODER_PATH" check-be-to-target-short-dec-+10db: extends: @@ -943,6 +951,9 @@ check-be-to-target-short-dec-+10db: TEST_SUITE: "$SHORT_TEST_SUITE" # +10dB LEVEL_SCALING: "3.162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-be-to-target-short-dec--10db: extends: @@ -951,6 +962,9 @@ check-be-to-target-short-dec--10db: TEST_SUITE: "$SHORT_TEST_SUITE" # -10dB LEVEL_SCALING: "0.3162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" ### jobs that check for regressions on non-BE testcases check-regressions-short-enc-0db: @@ -960,6 +974,9 @@ check-regressions-short-enc-0db: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # +/-0dB LEVEL_SCALING: "1.0" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-regressions-short-enc-+10db: extends: @@ -968,6 +985,9 @@ check-regressions-short-enc-+10db: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # +10dB LEVEL_SCALING: "3.162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-regressions-short-enc--10db: extends: @@ -976,6 +996,9 @@ check-regressions-short-enc--10db: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # -10dB LEVEL_SCALING: "0.3162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-regressions-short-dec-0db: extends: @@ -984,6 +1007,9 @@ check-regressions-short-dec-0db: TEST_SUITE: "$SHORT_TEST_SUITE" # +/-0dB LEVEL_SCALING: "1" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-regressions-short-dec-+10db: extends: @@ -992,6 +1018,9 @@ check-regressions-short-dec-+10db: TEST_SUITE: "$SHORT_TEST_SUITE" # +10dB LEVEL_SCALING: "3.162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" check-regressions-short-dec--10db: extends: @@ -1000,6 +1029,9 @@ check-regressions-short-dec--10db: TEST_SUITE: "$SHORT_TEST_SUITE" # -10dB LEVEL_SCALING: "0.3162" + # overwrite decoder with float reference one + DUT_DECODER_PATH: "$REF_DECODER_PATH" + MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" # --------------------------------------------------------------- # Short test jobs for running from web interface or schedule -- GitLab From ba4e30212f18189f5e8698b86f75c7e73a1e7468 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 28 Apr 2025 15:22:14 +0200 Subject: [PATCH 1137/1221] fix binary name overwrite for decoder BE jobs --- .gitlab-ci.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95edafd47..0e9e06a56 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -951,9 +951,9 @@ check-be-to-target-short-dec-+10db: TEST_SUITE: "$SHORT_TEST_SUITE" # +10dB LEVEL_SCALING: "3.162" - # overwrite decoder with float reference one - DUT_DECODER_PATH: "$REF_DECODER_PATH" - MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" + # overwrite encoder with float reference one + DUT_ENCODER_PATH: "$REF_ENCODER_PATH" + MERGE_TARGET_ENCODER_PATH: "$REF_ENCODER_PATH" check-be-to-target-short-dec--10db: extends: @@ -962,9 +962,9 @@ check-be-to-target-short-dec--10db: TEST_SUITE: "$SHORT_TEST_SUITE" # -10dB LEVEL_SCALING: "0.3162" - # overwrite decoder with float reference one - DUT_DECODER_PATH: "$REF_DECODER_PATH" - MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" + # overwrite encoder with float reference one + DUT_ENCODER_PATH: "$REF_ENCODER_PATH" + MERGE_TARGET_ENCODER_PATH: "$REF_ENCODER_PATH" ### jobs that check for regressions on non-BE testcases check-regressions-short-enc-0db: @@ -1007,9 +1007,9 @@ check-regressions-short-dec-0db: TEST_SUITE: "$SHORT_TEST_SUITE" # +/-0dB LEVEL_SCALING: "1" - # overwrite decoder with float reference one - DUT_DECODER_PATH: "$REF_DECODER_PATH" - MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" + # overwrite encoder with float reference one + DUT_ENCODER_PATH: "$REF_ENCODER_PATH" + MERGE_TARGET_ENCODER_PATH: "$REF_ENCODER_PATH" check-regressions-short-dec-+10db: extends: @@ -1018,9 +1018,9 @@ check-regressions-short-dec-+10db: TEST_SUITE: "$SHORT_TEST_SUITE" # +10dB LEVEL_SCALING: "3.162" - # overwrite decoder with float reference one - DUT_DECODER_PATH: "$REF_DECODER_PATH" - MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" + # overwrite encoder with float reference one + DUT_ENCODER_PATH: "$REF_ENCODER_PATH" + MERGE_TARGET_ENCODER_PATH: "$REF_ENCODER_PATH" check-regressions-short-dec--10db: extends: @@ -1029,9 +1029,9 @@ check-regressions-short-dec--10db: TEST_SUITE: "$SHORT_TEST_SUITE" # -10dB LEVEL_SCALING: "0.3162" - # overwrite decoder with float reference one - DUT_DECODER_PATH: "$REF_DECODER_PATH" - MERGE_TARGET_DECODER_PATH: "$REF_DECODER_PATH" + # overwrite encoder with float reference one + DUT_ENCODER_PATH: "$REF_ENCODER_PATH" + MERGE_TARGET_ENCODER_PATH: "$REF_ENCODER_PATH" # --------------------------------------------------------------- # Short test jobs for running from web interface or schedule -- GitLab From 2ebe23b3ec8be37c4e9e3a9bb061dad62de88bb9 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 28 Apr 2025 15:38:58 +0200 Subject: [PATCH 1138/1221] fix job dependencies for regression check jobs --- .gitlab-ci.yml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0e9e06a56..364e522aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -444,9 +444,6 @@ workflow: extends: - .check-be-job stage: test - needs: - - job: "check-be-to-target-short-enc-0db" - artifacts: true timeout: "300 minutes" variables: XML_REPORT_BRANCH: "report-junit-branch-$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" @@ -970,6 +967,9 @@ check-be-to-target-short-dec--10db: check-regressions-short-enc-0db: extends: - .check-regressions-pytest-job + needs: + - job: "check-be-to-target-short-enc-0db" + artifacts: true variables: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # +/-0dB @@ -981,6 +981,9 @@ check-regressions-short-enc-0db: check-regressions-short-enc-+10db: extends: - .check-regressions-pytest-job + needs: + - job: "check-be-to-target-short-enc-+10db" + artifacts: true variables: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # +10dB @@ -992,6 +995,9 @@ check-regressions-short-enc-+10db: check-regressions-short-enc--10db: extends: - .check-regressions-pytest-job + needs: + - job: "check-be-to-target-short-enc--10db" + artifacts: true variables: TEST_SUITE: "$SHORT_TEST_SUITE_ENCODER" # -10dB @@ -1003,6 +1009,9 @@ check-regressions-short-enc--10db: check-regressions-short-dec-0db: extends: - .check-regressions-pytest-job + needs: + - job: "check-be-to-target-short-dec-0db" + artifacts: true variables: TEST_SUITE: "$SHORT_TEST_SUITE" # +/-0dB @@ -1014,6 +1023,9 @@ check-regressions-short-dec-0db: check-regressions-short-dec-+10db: extends: - .check-regressions-pytest-job + needs: + - job: "check-be-to-target-short-dec-+10db" + artifacts: true variables: TEST_SUITE: "$SHORT_TEST_SUITE" # +10dB @@ -1025,6 +1037,9 @@ check-regressions-short-dec-+10db: check-regressions-short-dec--10db: extends: - .check-regressions-pytest-job + needs: + - job: "check-be-to-target-short-dec--10db" + artifacts: true variables: TEST_SUITE: "$SHORT_TEST_SUITE" # -10dB -- GitLab From 6bc3038a7056b9761f6a9c11ac0b1a0c6b167c43 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 28 Apr 2025 19:24:51 +0530 Subject: [PATCH 1139/1221] Q related fixed for encoder transition and decoder msan fixes --- lib_dec/ivas_mct_dec_fx.c | 2 +- lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 2 ++ lib_enc/acelp_enc_util_fx.c | 12 ++++++------ lib_enc/enc_tran_fx.c | 3 ++- lib_enc/ivas_core_pre_proc_fx.c | 7 ++----- lib_enc/transition_enc_fx.c | 16 ++-------------- 6 files changed, 15 insertions(+), 27 deletions(-) diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 32403b11a..b34ce0c56 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -398,7 +398,7 @@ ivas_error ivas_mct_dec_fx( test(); IF( ( st_ivas->sba_dirac_stereo_flag != 0 ) && ( NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) || GE_16( cpe_id, sub( nCPE, 2 ) ) ) ) { - Copy_Scale_sig_16_32_no_sat( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( synth_fx[n], synth_fx_32[n], output_frame, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->old_out_fx32, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); ivas_post_proc_fx( NULL, hCPE, n, synth_fx_32[n], NULL, output_frame, 1, Q11 ); Copy_Scale_sig_32_16( synth_fx_32[n], synth_fx[n], output_frame, sub( sub( 15, e_sig[n] ), Q11 ) ); // Q0 diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index e82005965..8035af217 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -102,6 +102,8 @@ void stereo_dft_unify_dmx_fx( Word16 num_plocs; Word32 plocsi[STEREO_DFT_RES_N_PEAKS_MAX]; + set32_fx( DFT_PRED_RES, 0, STEREO_DFT32MS_N_32k ); + output_frame = extract_l( Mult_32_16( st0->output_Fs, INV_FRAME_PER_SEC_Q15 ) ); /* Q0 */ samp_ratio = BASOP_Util_Divide3232_Scale( st0->sr_core, st0->output_Fs, &q_samp_ratio ); samp_ratio = shr( samp_ratio, sub( Q15 - Q12, q_samp_ratio ) ); diff --git a/lib_enc/acelp_enc_util_fx.c b/lib_enc/acelp_enc_util_fx.c index 181583e91..7f57b55da 100644 --- a/lib_enc/acelp_enc_util_fx.c +++ b/lib_enc/acelp_enc_util_fx.c @@ -180,9 +180,9 @@ void E_ACELP_conv( } void E_ACELP_conv_ivas_fx( - const Word16 xn2[], /* i Qx*/ + const Word16 xn2[], /* i Qnew - 1*/ const Word16 h2[], /* i Q12*/ - Word16 cn2[] /* o Q0*/ + Word16 cn2[] /* o Qnew*/ ) { Word16 i, k; @@ -194,14 +194,14 @@ void E_ACELP_conv_ivas_fx( { /*cn2[k] = xn2[k]; */ Word64 L_tmp_64; - L_tmp_64 = W_deposit32_l( L_mult0( xn2[k], 0x800 ) ); /* 4Q11 */ + L_tmp_64 = W_deposit32_l( L_mult0( xn2[k], 0x800 ) ); /* Qnew -1 + 12 */ FOR( i = 0; i < k; i++ ) { /*cn2[k]-=cn2[i]*h2[k-i];*/ - L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*h2 4Q11*/ + L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*Qnew + 11*/ } - L_tmp = W_sat_l( L_tmp_64 ); /* 4Q11 */ - cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); /* Q0*/ + L_tmp = W_sat_l( L_tmp_64 ); /* Qnew + 11 */ + cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); /* Qnew*/ move16(); } } diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 394b22c30..f308e9e87 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -545,7 +545,7 @@ Word16 encod_tran_ivas_fx( Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ - find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, + find_targets_ivas_new_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); @@ -555,6 +555,7 @@ Word16 encod_tran_ivas_fx( #else Scale_sig( h1, L_SUBFR, sub( 13, q_h1 ) ); #endif + /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn, L_SUBFR, shift ); diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 6fe6b6720..5853e2739 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -1174,11 +1174,8 @@ ivas_error ivas_compute_core_buffers_fx( ELSE IF( GT_32( input_Fs, 8000 ) && EQ_32( sr_core, INT_FS_16k ) ) { Copy( &old_inp_16k_fx[L_frame_tmp], st->old_inp_16k_fx, L_INP_MEM ); - IF( Q_new ) - { - st->exp_old_inp_16k = sub( Q16, *Q_new ); //(*Q_new - 1) - move16(); - } + st->exp_old_inp_16k = sub(Q16, *Q_new); //(*Q_new - 1) + move16(); } ELSE IF( GT_32( input_Fs, 8000 ) ) { diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 5e50cac15..c724ffd6c 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -924,8 +924,6 @@ void transition_enc_ivas_fx( /* set limit_flag to 0 for restrained limits, and 1 for extended limits */ limit_flag = 0; move16(); - Word16 h1_fx_q15[L_SUBFR + ( M + 1 )]; - Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 0 ); pit_start = PIT_MIN; move16(); @@ -1443,12 +1441,7 @@ void transition_enc_ivas_fx( *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, ( Q_new + shift - 1 ) ); move16(); -#ifdef TEST_HR - Copy( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ) ); -#else - Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); -#endif - lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx_q15, + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) @@ -1684,12 +1677,7 @@ void transition_enc_ivas_fx( *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, Q_new ); move16(); -#ifdef TEST_HR - Copy( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ) ); -#else - Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); -#endif - lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx_q15, + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { -- GitLab From c5d45b9cdad87c45d937da2462ce0defad4d3d73 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 29 Apr 2025 08:11:58 +0530 Subject: [PATCH 1140/1221] Clang formatting changes --- lib_dec/ivas_stereo_dft_dec_dmx_fx.c | 2 +- lib_enc/enc_tran_fx.c | 2 +- lib_enc/ivas_core_pre_proc_fx.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c index 8035af217..cdb64e46c 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -103,7 +103,7 @@ void stereo_dft_unify_dmx_fx( Word32 plocsi[STEREO_DFT_RES_N_PEAKS_MAX]; set32_fx( DFT_PRED_RES, 0, STEREO_DFT32MS_N_32k ); - + output_frame = extract_l( Mult_32_16( st0->output_Fs, INV_FRAME_PER_SEC_Q15 ) ); /* Q0 */ samp_ratio = BASOP_Util_Divide3232_Scale( st0->sr_core, st0->output_Fs, &q_samp_ratio ); samp_ratio = shr( samp_ratio, sub( Q15 - Q12, q_samp_ratio ) ); diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index f308e9e87..865972819 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -546,7 +546,7 @@ Word16 encod_tran_ivas_fx( Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_ivas_new_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, - res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); + res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ diff --git a/lib_enc/ivas_core_pre_proc_fx.c b/lib_enc/ivas_core_pre_proc_fx.c index 5853e2739..e2c099cd2 100644 --- a/lib_enc/ivas_core_pre_proc_fx.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -1174,7 +1174,7 @@ ivas_error ivas_compute_core_buffers_fx( ELSE IF( GT_32( input_Fs, 8000 ) && EQ_32( sr_core, INT_FS_16k ) ) { Copy( &old_inp_16k_fx[L_frame_tmp], st->old_inp_16k_fx, L_INP_MEM ); - st->exp_old_inp_16k = sub(Q16, *Q_new); //(*Q_new - 1) + st->exp_old_inp_16k = sub( Q16, *Q_new ); //(*Q_new - 1) move16(); } ELSE IF( GT_32( input_Fs, 8000 ) ) -- GitLab From 34c9080325f97b34ea73c8d98f1cfafc30a26ba2 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 29 Apr 2025 08:01:15 +0200 Subject: [PATCH 1141/1221] add missing reference to common before_script section --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 364e522aa..71a5704aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1596,6 +1596,7 @@ voip-be-on-merge-request: GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: + - !reference [ .job-linux, before_script ] - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh -- GitLab From 1a9dfb950313aeaa5626608e2d32d53458ab7c7c Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 29 Apr 2025 08:22:37 +0200 Subject: [PATCH 1142/1221] update CI ref --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 364e522aa..59c8d2b72 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 4eb4c0dfbdc845280a9994b5f7540f69c737537b + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 7c6b6f261883e282ebe050e18d48c00ce623b8be include: - local: .gitlab-ci/variables.yml -- GitLab From 997852da13bcfddae4a4e4fb863cf455e03c4421 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 29 Apr 2025 08:50:20 +0200 Subject: [PATCH 1143/1221] update commit to point to CI repo main --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 59c8d2b72..4b7d05c7b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 7c6b6f261883e282ebe050e18d48c00ce623b8be + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF f5e61349c22ededcdfe1cc54e533dea477f2d003 include: - local: .gitlab-ci/variables.yml -- GitLab From ee28fb4d85ca4d1adfb0c01eb774bc8b9fda35f5 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 29 Apr 2025 08:01:15 +0200 Subject: [PATCH 1144/1221] add missing reference to common before_script section --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4b7d05c7b..1f5a98321 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1596,6 +1596,7 @@ voip-be-on-merge-request: GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: + - !reference [ .job-linux, before_script ] - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh -- GitLab From 8f5cd954654c320df786feb4638dc89aba703792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Tue, 29 Apr 2025 01:21:37 +0200 Subject: [PATCH 1145/1221] Inherit before_script from .test-job-linux --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1f5a98321..bb2259810 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1596,7 +1596,7 @@ voip-be-on-merge-request: GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: - - !reference [ .job-linux, before_script ] + - !reference [ .test-job-linux, before_script ] - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/update-ltv-repo.sh -- GitLab From 8ebc89d0a003b2287ebbb33aa941d8e8e6e5cfeb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 29 Apr 2025 14:54:13 +0530 Subject: [PATCH 1146/1221] Fix for 3GPP issue 1525: Second channel of BASOP decoder MASA format output to FOA has missing energy or wrong signal Link #1525 --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 509eec6e2..37b5f1e05 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2134,9 +2134,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move16(); } - subtract_power_y = masa_stereo_type_detect->subtract_power_y_fx; // q_subtract_power_y - move32(); - a = 858993; /* ( 0.0004f in Q31 ); Temporal smoothing coefficient */ move32(); b = L_sub( ONE_IN_Q31, a ); /* Temporal smoothing coefficient */ @@ -2152,24 +2149,42 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move32(); masa_stereo_type_detect->q_target_power_y_smooth = q_com; move16(); - masa_stereo_type_detect->subtract_power_y_smooth_fx = - L_add( Mpy_32_32( a, subtract_power_y ), - Mpy_32_32( b, masa_stereo_type_detect->subtract_power_y_smooth_fx ) ); //(Q31, q_subtract_power_y) -> q_subtract_power_y + + IF( NE_16( masa_stereo_type_detect->q_subtract_power_y, masa_stereo_type_detect->q_subtract_power_y_smooth ) ) + { + exp = s_min( add( masa_stereo_type_detect->q_subtract_power_y, norm_l( masa_stereo_type_detect->subtract_power_y_fx ) ), add( masa_stereo_type_detect->q_subtract_power_y_smooth, norm_l( masa_stereo_type_detect->subtract_power_y_smooth_fx ) ) ); + masa_stereo_type_detect->subtract_power_y_fx = L_shl( masa_stereo_type_detect->subtract_power_y_fx, sub( exp, masa_stereo_type_detect->q_subtract_power_y ) ); + move32(); + masa_stereo_type_detect->subtract_power_y_smooth_fx = L_shl( masa_stereo_type_detect->subtract_power_y_smooth_fx, sub( exp, masa_stereo_type_detect->q_subtract_power_y_smooth ) ); + move32(); + masa_stereo_type_detect->q_subtract_power_y = exp; + move16(); + masa_stereo_type_detect->q_subtract_power_y_smooth = exp; + move16(); + } + subtract_power_y = masa_stereo_type_detect->subtract_power_y_fx; // q_subtract_power_y move32(); + W_temp = W_add( W_mult0_32_32( a, subtract_power_y ), W_mult0_32_32( b, masa_stereo_type_detect->subtract_power_y_smooth_fx ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth + exp = W_norm( W_temp ); + masa_stereo_type_detect->subtract_power_y_smooth_fx = W_extract_h( W_shl( W_temp, exp ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth + exp - 32 + move32(); + masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 ); + move16(); + exp = 0; move16(); IF( masa_stereo_type_detect->target_power_y_smooth_fx != 0 ) { subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ), BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25 - exp = sub( masa_stereo_type_detect->q_subtract_power_y, q_com ); + exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, q_com ); L_tmp = Mpy_32_32( L_sub( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ); // Q25 } ELSE { subtract_target_ratio = BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ); // Q25 - exp = sub( 31, masa_stereo_type_detect->q_subtract_power_y ); + exp = sub( 31, masa_stereo_type_detect->q_subtract_power_y_smooth ); L_tmp = L_sub( Mpy_32_32( L_add( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ), -503316480 /* L_shl( -15, 25 ) */ /*log(EPSILON)*/ ); // Q25 } subtract_target_ratio_db = Mpy_32_32( 1342177280 /* 10.0f * in Q27*/, L_tmp ); // (Q27, (Q25, Q31)) -> (Q27, Q25) -> Q21 @@ -2178,6 +2193,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move32(); masa_stereo_type_detect->subtract_power_y_fx = 0; move32(); + masa_stereo_type_detect->q_subtract_power_y = Q31; + move16(); } /*-----------------------------------------------------------------* -- GitLab From 6b052e9535277432f63a9daf3cc2c7bc88a184e2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 29 Apr 2025 13:33:19 +0530 Subject: [PATCH 1147/1221] Fix for 3GPP issue 1417: Audible artifact at SBA 13.2 kbps, 48KHz Link #1417 --- lib_enc/sig_clas_fx.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/lib_enc/sig_clas_fx.c b/lib_enc/sig_clas_fx.c index cf5d31d22..ed34798fc 100644 --- a/lib_enc/sig_clas_fx.c +++ b/lib_enc/sig_clas_fx.c @@ -53,9 +53,10 @@ Word16 signal_clas_fx( /* o : classification for current { Word32 Ltmp; Word16 mean_voi2, een, corn, zcn, relEn, pcn, fmerit1; - Word16 i, clas, pc, zc, lo, lo2, hi, hi2, exp_ee, frac_ee; + Word16 i, clas, pc, zc, exp_ee; Word16 tmp16, tmpS; const Word16 *pt1; + Word64 tmp64; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -73,34 +74,34 @@ Word16 signal_clas_fx( /* o : classification for current mean_voi2 = mac_r( Ltmp, st->voicing_fx[2], 16384 ); /* average spectral tilt in dB */ - lo = L_Extract_lc( ee[0], &hi ); - lo2 = L_Extract_lc( ee[1], &hi2 ); - Ltmp = L_mult( lo, lo2 ); /* Q5*Q5->Q11 */ - - test(); - test(); - IF( LT_32( Ltmp, 2048 ) ) + tmp64 = W_mult0_32_32( ee[0], ee[1] ); + exp_ee = W_norm( tmp64 ); + Ltmp = W_extract_h( W_shl( tmp64, exp_ee ) ); // Q = Q6+Q6 + exp_ee - 32 + exp_ee = sub( 31, sub( add( Q12, exp_ee ), 32 ) ); + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( Ltmp, exp_ee, ONE_IN_Q31, 0 ), -1 ) ) { een = 0; move16(); } - ELSE IF( GT_32( Ltmp, THRES_EEN ) || hi > 0 || hi2 > 0 ) - { - een = 512; - move16(); - } ELSE { /* mean_ee2 = 0.5f * 20.0f * (float)log10( tmp ); */ /* een = K_EE_ENC * mean_ee2 + C_EE_ENC; */ - exp_ee = norm_l( Ltmp ); - frac_ee = Log2_norm_lc( L_shl( Ltmp, exp_ee ) ); - exp_ee = sub( 30 - 11, exp_ee ); - Ltmp = Mpy_32_16( exp_ee, frac_ee, LG10 ); /* Ltmp Q14 */ - een = round_fx( L_shl( Ltmp, 16 - 5 ) ); /* Q14 -> Q9 */ - een = mac_r( C_EE_FX, een, K_EE_FX ); - } + Ltmp = BASOP_Util_Log10( Ltmp, exp_ee ); // Q25 + Ltmp = Mpy_32_32( Ltmp, 671088640 /*20.f in Q25*/ ); // Q25 + Q25 -Q31 = Q19 * 0.5 = Q20 + een = extract_l( L_shl( Mpy_32_16_1( Ltmp, K_EE_FX ), Q9 - Q20 ) ); // Q9 + IF( GT_16( een, 512 ) ) + { + een = 512; + move16(); + } + ELSE IF( een < 0 ) + { + een = 0; + move16(); + } + } /* compute zero crossing rate */ pt1 = speech + sub( L_look, 1 ); tmpS = shr( *pt1, 15 ); /* sets 'tmpS to -1 if *pt1 < 0 */ -- GitLab From 9891182d9469eaa7433f31e765122c1663cdc7ca Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 29 Apr 2025 14:36:41 +0530 Subject: [PATCH 1148/1221] Fix for EVS Bitexactness issue --- lib_enc/ivas_core_pre_proc_front_fx.c | 2 +- lib_enc/prot_fx_enc.h | 9 + lib_enc/sig_clas_fx.c | 231 ++++++++++++++++++++++++++ 3 files changed, 241 insertions(+), 1 deletion(-) diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 3d7d87bc2..4a8c4edd2 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1425,7 +1425,7 @@ ivas_error pre_proc_front_ivas_fx( * TC frame selection *-----------------------------------------------------------------*/ - st->clas = signal_clas_fx( st, inp_12k8_fx, ee_fx, *relE_fx, L_look, tdm_SM_last_clas ); /* Q0 */ + st->clas = signal_clas_ivas_fx( st, inp_12k8_fx, ee_fx, *relE_fx, L_look, tdm_SM_last_clas ); /* Q0 */ move16(); select_TC_fx( MODE1, st->tc_cnt, &st->coder_type, st->localVAD ); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 4237aa9c3..2aa5df5c4 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -570,6 +570,15 @@ Word16 signal_clas_fx( /* o : classification for current Word16 *uc_clas /* o : temporary classification used in music/speech class*/ ); +Word16 signal_clas_ivas_fx( /* o : classification for current frames */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 *speech, /* i : pointer to speech signal for E computation */ + const Word32 *ee, /* i : lf/hf E ration for 2 half-frames */ + const Word16 relE, /* i : frame relative E to the long term average */ + const Word16 L_look, /* i : look-ahead */ + Word16 *uc_clas /* o : temporary classification used in music/speech class*/ +); + void speech_music_classif_fx( Encoder_State *st, /* i/o: state structure */ const Word16 *new_inp, /* i : new input signal */ diff --git a/lib_enc/sig_clas_fx.c b/lib_enc/sig_clas_fx.c index ed34798fc..beb97514a 100644 --- a/lib_enc/sig_clas_fx.c +++ b/lib_enc/sig_clas_fx.c @@ -50,6 +50,236 @@ Word16 signal_clas_fx( /* o : classification for current const Word16 L_look, /* i : look-ahead */ Word16 *clas_mod /* o : class flag for NOOP detection */ ) +{ + Word32 Ltmp; + Word16 mean_voi2, een, corn, zcn, relEn, pcn, fmerit1; + Word16 i, clas, pc, zc, lo, lo2, hi, hi2, exp_ee, frac_ee; + Word16 tmp16, tmpS; + const Word16 *pt1; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + /*----------------------------------------------------------------* + * Calculate average voicing + * Calculate average spectral tilt + * Calculate zero-crossing rate + * Calculate pitch stability + *----------------------------------------------------------------*/ + + /* average voicing on second half-frame and look-ahead */ + Ltmp = L_mult( st->voicing_fx[1], 16384 ); /* Q15*Q14->Q30 */ + mean_voi2 = mac_r( Ltmp, st->voicing_fx[2], 16384 ); + + /* average spectral tilt in dB */ + lo = L_Extract_lc( ee[0], &hi ); + lo2 = L_Extract_lc( ee[1], &hi2 ); + Ltmp = L_mult( lo, lo2 ); /* Q5*Q5->Q11 */ + + test(); + test(); + IF( LT_32( Ltmp, 2048 ) ) + { + een = 0; + move16(); + } + ELSE IF( GT_32( Ltmp, THRES_EEN ) || hi > 0 || hi2 > 0 ) + { + een = 512; + move16(); + } + ELSE + { + /* mean_ee2 = 0.5f * 20.0f * (float)log10( tmp ); */ + /* een = K_EE_ENC * mean_ee2 + C_EE_ENC; */ + exp_ee = norm_l( Ltmp ); + frac_ee = Log2_norm_lc( L_shl( Ltmp, exp_ee ) ); + exp_ee = sub( 30 - 11, exp_ee ); + Ltmp = Mpy_32_16( exp_ee, frac_ee, LG10 ); /* Ltmp Q14 */ + een = round_fx( L_shl( Ltmp, 16 - 5 ) ); /* Q14 -> Q9 */ + een = mac_r( C_EE_FX, een, K_EE_FX ); + } + /* compute zero crossing rate */ + pt1 = speech + sub( L_look, 1 ); + tmpS = shr( *pt1, 15 ); /* sets 'tmpS to -1 if *pt1 < 0 */ + Ltmp = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME; i++ ) + { + tmp16 = add( 1, tmpS ); + pt1++; + tmpS = shr( *pt1, 15 ); /* pt1 >=0 ---> 0 OTHERWISE -1 */ + Ltmp = L_msu0( Ltmp, tmpS, tmp16 ); + } + zc = extract_l( Ltmp ); + + /* compute pitch stability */ + pc = add( abs_s( sub( st->pitch[1], st->pitch[0] ) ), abs_s( sub( st->pitch[2], st->pitch[1] ) ) ); + st->tdm_pc = pc; + move16(); + /*-----------------------------------------------------------------* + * Transform parameters to the range <0:1> + * Compute the merit function + *-----------------------------------------------------------------*/ + + /* corn = K_COR * mean_voi2 + C_COR */ + Ltmp = L_mult( C_COR_FX, 32767 ); + corn = round_fx( L_shl( L_mac( Ltmp, mean_voi2, K_COR_FX ), -4 ) ); /*Q13+Q13*Q15 =>Q13->Q9*/ + /* Limit [0, 1] */ + corn = s_max( corn, 0 ); + corn = s_min( corn, 512 ); + + Ltmp = L_mult( C_ZC_FX, 4 ); /*Q13*Q2 -> Q16*/ + zcn = round_fx( L_shl( L_mac( Ltmp, zc, K_ZC_FX ), 16 - 7 ) ); /*Q0*Q15 + Q16*/ + /* Limit [0, 1] */ + zcn = s_max( zcn, 0 ); + zcn = s_min( zcn, 512 ); + + Ltmp = L_mult( C_RELE_FX, 256 ); /*Q15*Q8 ->Q24*/ + relEn = round_fx( L_shl( L_mac( Ltmp, relE, K_RELE_FX ), 1 ) ); /*relE in Q8 but relEn in Q9*/ + /* Limit [0.5, 1] */ + relEn = s_max( relEn, 256 ); + relEn = s_min( relEn, 512 ); + + Ltmp = L_mult( C_PC_FX, 2 ); /*Q14*Q1 -> Q16*/ + pcn = round_fx( L_shl( L_mac( Ltmp, pc, K_PC_FX ), 16 - 7 ) ); /*Q16 + Q0*Q15*/ + /* Limit [0, 1] */ + pcn = s_max( pcn, 0 ); + pcn = s_min( pcn, 512 ); + + Ltmp = L_mult( een, 10923 ); + Ltmp = L_mac( Ltmp, corn, 21845 ); + Ltmp = L_mac( Ltmp, zcn, 10923 ); + Ltmp = L_mac( Ltmp, relEn, 10923 ); + Ltmp = L_mac( Ltmp, pcn, 10923 ); + + fmerit1 = round_fx_o( L_shl_o( Ltmp, 16 - 10 - 1, &Overflow ), &Overflow ); /* fmerit1 ->Q15 */ + + /*-----------------------------------------------------------------* + * FEC classification + *-----------------------------------------------------------------*/ + + st->fmerit_dt = sub( st->prev_fmerit, fmerit1 ); /*Q15*/ + move16(); + st->prev_fmerit = fmerit1; + move16(); + + /* FEC classification */ + test(); + test(); + IF( st->localVAD == 0 || EQ_16( st->coder_type, UNVOICED ) || LT_16( relE, -1536 ) ) + { + clas = UNVOICED_CLAS; + *clas_mod = clas; + move16(); + move16(); + } + ELSE + { + SWITCH( st->last_clas ) + { + case VOICED_CLAS: + case ONSET: + case VOICED_TRANSITION: + + IF( LT_16( fmerit1, 16056 ) ) /*0.49f*/ + { + clas = UNVOICED_CLAS; + move16(); + } + ELSE IF( LT_16( fmerit1, 21626 ) ) /*0.66*/ + { + clas = VOICED_TRANSITION; + move16(); + } + ELSE + { + clas = VOICED_CLAS; + move16(); + } + IF( LT_16( fmerit1, 14745 /* 0.45f*/ ) ) + { + *clas_mod = UNVOICED_CLAS; + move16(); + } + ELSE IF( LT_16( fmerit1, 21626 /* 0.66f*/ ) ) + { + *clas_mod = VOICED_TRANSITION; + move16(); + } + ELSE + { + *clas_mod = VOICED_CLAS; + move16(); + } + BREAK; + + case UNVOICED_CLAS: + case UNVOICED_TRANSITION: + IF( GT_16( fmerit1, 20643 ) ) /*0.63*/ + { + clas = ONSET; + move16(); + } + ELSE IF( GT_16( fmerit1, 19169 ) ) /*0.585*/ + { + clas = UNVOICED_TRANSITION; + move16(); + } + ELSE + { + clas = UNVOICED_CLAS; + move16(); + } + *clas_mod = clas; + move16(); + + BREAK; + + default: + clas = UNVOICED_CLAS; + *clas_mod = clas; + move16(); + move16(); + BREAK; + } + } + /* Onset classification */ + + /* tc_cnt == -1: frame after TC frame in continuous block of GC/VC frames */ + /* tc_cnt == 0: UC frame */ + /* tc_cnt == 1: onset/transition frame, coded by GC coder type */ + /* tc_cnt == 2: frame after onset/transition frame, coded by TC coder type */ + + if ( clas == 0 ) + { + st->tc_cnt = 0; + move16(); + } + + test(); + IF( GE_16( clas, VOICED_TRANSITION ) && st->tc_cnt >= 0 ) + { + st->tc_cnt = add( st->tc_cnt, 1 ); + move16(); + } + + if ( GT_16( st->tc_cnt, 2 ) ) + { + st->tc_cnt = -1; + move16(); + } + return clas; +} + +Word16 signal_clas_ivas_fx( /* o : classification for current frames */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 *speech, /* i : pointer to speech signal for E computation in Qx */ + const Word32 *ee, /* i : lf/hf E ration for 2 half-frames in Q6 */ + const Word16 relE, /* i : frame relative E to the long term average in Q8 */ + const Word16 L_look, /* i : look-ahead */ + Word16 *clas_mod /* o : class flag for NOOP detection */ +) { Word32 Ltmp; Word16 mean_voi2, een, corn, zcn, relEn, pcn, fmerit1; @@ -273,6 +503,7 @@ Word16 signal_clas_fx( /* o : classification for current } return clas; } + /*-------------------------------------------------------------------* * select_TC_fx() * -- GitLab From fdd58b16039c3a097cbbc044684fcd88f2986254 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 29 Apr 2025 16:35:26 +0530 Subject: [PATCH 1149/1221] Fix for 3GPP issue 1461: Issue with VAD sensitivity in SBA DTX mode at 48 and 80 kbps Link #1461 --- lib_enc/vad_fx.c | 73 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index 1fdcb94fa..531265236 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -213,6 +213,29 @@ void wb_vad_init_ivas_fx( * * accumulate snr_sum with significance thresholds *-----------------------------------------------------------------*/ +static void sign_thr_snr_acc_ivas_fx( + Word32 *L_snr_sum, /* o: q_snr_sum */ + Word16 *q_snr_sum, + Word32 L_snr, /* i: q_snr */ + Word16 q_snr, + Word32 sign_thr, /* i: q_snr */ + Word32 min_snr /* i: q_snr */ +) +{ + /*if( snr >= sign_thr ) */ + Word32 L_tmp; + Word16 exp_snr_sum = sub( 31, *q_snr_sum ); + L_tmp = min_snr; + move32(); + IF( GE_32( L_snr, sign_thr ) ) + { + L_tmp = L_add( L_snr, 0 ); /* q_snr */ + } + *L_snr_sum = BASOP_Util_Add_Mant32Exp( *L_snr_sum, exp_snr_sum, L_tmp, sub( 31, q_snr ), &exp_snr_sum ); /* q_snr */ + *q_snr_sum = sub( 31, exp_snr_sum ); + move32(); + move32(); +} static void sign_thr_snr_acc_fx( Word32 *L_snr_sum, /* o: Q4 */ Word32 L_snr, /* i: Q4 */ @@ -2186,6 +2209,10 @@ Word16 wb_vad_ivas_fx( L_snr_sum = L_deposit_l( 0 ); L_snr_sum_HE_SAD = L_deposit_l( 0 ); + Word16 q_snr_sum = 0; + Word16 q_snr_sum_HE_SAD = 0; + move16(); + move16(); snr_sumt = 0; move16(); L_mssnr_hov = L_deposit_l( 0 ); @@ -2199,7 +2226,7 @@ Word16 wb_vad_ivas_fx( q_snr = 0; move16(); move16(); - q_shift = add( sub( q_fr_bands, hNoiseEst->q_bckr ), 15 - 4 ); + q_shift = add( sub( q_fr_bands, hNoiseEst->q_bckr ), 14 - 4 ); FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) { ftmp = L_add( *pt1++, 0 ); @@ -2207,12 +2234,12 @@ Word16 wb_vad_ivas_fx( ftmp2 = L_add( *pt3++, 0 ); /*fr_enr = ( 0.2f * st->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 );*/ - L_tmp = Mult_32_16( hNoiseEst->enrO_fx[i], 13107 ); /* L_tmp(high word) = Qenr0fx*Q16+1 -16 -> Qener0+1 */ - L_tmp1 = Madd_32_16( L_tmp, ftmp, 26214 ); /* 26214 = .4 in Q16 */ - L_tmp1 = Madd_32_16( L_tmp1, ftmp1, 26214 ); /* L_tmp1 re_used a bit later for final snr[i]*/ + L_tmp = Mult_32_16( hNoiseEst->enrO_fx[i], 6554 ); /* L_tmp(high word) = Qenr0fx*Q15+1 -16 -> Qener0 */ + L_tmp1 = Madd_32_16( L_tmp, ftmp, 13107 ); /* 13107 = .4 in Q15 */ + L_tmp1 = Madd_32_16( L_tmp1, ftmp1, 13107 ); /* L_tmp1 re_used a bit later for final snr[i]*/ - L_tmp2 = Madd_32_16( L_tmp, ftmp, 19661 ); /* 19661 = 0.3 in Q16 */ - L_tmp2 = Msub_32_16( L_tmp2, ftmp1, -32768 ); /* -32768= -0.5 in Q16 */ + L_tmp2 = Madd_32_16( L_tmp, ftmp, 9830 ); /* 9830 = 0.3 in Q15 */ + L_tmp2 = Msub_32_16( L_tmp2, ftmp1, -16384 ); /* -16384= -0.5 in Q15 */ IF( GT_32( ftmp, ftmp1 ) ) { @@ -2221,12 +2248,12 @@ Word16 wb_vad_ivas_fx( IF( ftmp2 != 0 ) { e_num = norm_l( L_tmp1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+1+e_num-16 + m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+e_num-16 e_noise = norm_l( ftmp2 ); m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - m_num = shr( m_num, 1 ); // q_fr_bands+e_num-16 + m_num = shr( m_num, 1 ); // q_fr_bands-1+e_num-16 shift_snr = add( sub( e_num, e_noise ), q_shift ); snr_tmp = div_s( m_num, m_noise_local ); // q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise @@ -2234,7 +2261,7 @@ Word16 wb_vad_ivas_fx( } ELSE { - L_snr = L_shr_o( L_tmp1, sub( Q3, q_fr_bands ), &Overflow ); // q_fr_bands+1 -> Q4 + L_snr = L_shl_o( L_tmp1, sub( Q4, q_fr_bands ), &Overflow ); // q_fr_bands -> Q4 } } ELSE @@ -2244,12 +2271,12 @@ Word16 wb_vad_ivas_fx( IF( ftmp2 != 0 ) { e_num = norm_l( L_tmp2 ); - m_num = extract_h( L_shl( L_tmp2, e_num ) ); // q_fr_bands+1+e_num-16 + m_num = extract_h( L_shl( L_tmp2, e_num ) ); // q_fr_bands+e_num-16 e_noise = norm_l( ftmp2 ); m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - m_num = shr( m_num, 1 ); // q_fr_bands+e_num-16 + m_num = shr( m_num, 1 ); // q_fr_bands-1+e_num-16 shift_snr = add( sub( e_num, e_noise ), q_shift ); snr_tmp = div_s( m_num, m_noise_local ); // q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise @@ -2257,7 +2284,7 @@ Word16 wb_vad_ivas_fx( } ELSE { - L_snr = L_shr_o( L_tmp2, sub( Q3, q_fr_bands ), &Overflow ); // q_fr_bands+1 -> Q4 + L_snr = L_shl_o( L_tmp2, sub( Q4, q_fr_bands ), &Overflow ); // q_fr_bands -> Q4 } } @@ -2350,25 +2377,31 @@ Word16 wb_vad_ivas_fx( IF( hNoiseEst->bckr_fx[i] != 0 ) { e_num = sub( norm_l( L_tmp1 ), 1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+1+e_num-16 + m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+e_num-16 e_noise = norm_l( hNoiseEst->bckr_fx[i] ); m_noise_local = extract_h( L_shl( hNoiseEst->bckr_fx[i], e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 L_snr_tmp = L_deposit_h( div_s( m_num, m_noise_local ) ); // 32+q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise - q_snr_tmp = add( 32, sub( add( q_fr_bands, e_num ), add( hNoiseEst->q_bckr, e_noise ) ) ); + q_snr_tmp = add( 31, sub( add( q_fr_bands, e_num ), add( hNoiseEst->q_bckr, e_noise ) ) ); } ELSE { - L_snr_tmp = Mpy_32_16_1( L_tmp1, 18286 /* 1/E_MIN in Q6 */ ); // q_fr_bands-8 - q_snr_tmp = sub( q_fr_bands, 8 ); + L_snr_tmp = Mpy_32_16_1( L_tmp1, 18286 /* 1/E_MIN in Q6 */ ); // q_fr_bands-9 + q_snr_tmp = sub( q_fr_bands, 9 ); } /* conditional snrsum, snr_sum = snr_sum + snr[i];*/ + IF( GT_16( q_snr_tmp, 28 ) ) // added to avoid overflow while scaling sign_thr_HE_SAD,min_snr_HE_SAD,sign_thr and min_snr while scaling to q_snr_tmp + { + L_snr_tmp = L_shl( L_snr_tmp, sub( 28, q_snr_tmp ) ); + q_snr_tmp = 28; + move16(); + } exp = sub( Q4, q_snr_tmp ); L_snr = L_shl_sat( L_snr_tmp, exp ); // Q4 - sign_thr_snr_acc_fx( &L_snr_sum_HE_SAD, L_snr, sign_thr_HE_SAD, min_snr_HE_SAD ); - sign_thr_snr_acc_fx( &L_snr_sum, L_snr, sign_thr, min_snr ); + sign_thr_snr_acc_ivas_fx( &L_snr_sum_HE_SAD, &q_snr_sum_HE_SAD, L_snr_tmp, q_snr_tmp, L_shl( sign_thr_HE_SAD, sub( q_snr_tmp, 4 ) ), L_shl( min_snr_HE_SAD, sub( q_snr_tmp, 4 ) ) ); + sign_thr_snr_acc_ivas_fx( &L_snr_sum, &q_snr_sum, L_snr_tmp, q_snr_tmp, L_shl( sign_thr, sub( q_snr_tmp, 4 ) ), L_shl( min_snr, sub( q_snr_tmp, 4 ) ) ); /* if( snr[i] < 1.0f ) { snr[i] = 1.0f;} */ IF( LT_32( L_snr, 16 /* 1.0 in Q4 */ ) ) @@ -2412,7 +2445,9 @@ Word16 wb_vad_ivas_fx( move16(); move16(); } - } /* end of band loop */ + } /* end of band loop */ + L_snr_sum = L_shl_o( L_snr_sum, sub( 4, q_snr_sum ), &Overflow ); // q_snr_sum->q4 + L_snr_sum_HE_SAD = L_shl_o( L_snr_sum_HE_SAD, sub( 4, q_snr_sum_HE_SAD ), &Overflow ); // q_snr_sum_HE_SAD->q4 L_snr_outlier = L_shl_sat( L_snr_outlier, sub( Q4, q_snr ) ); // q_snr -> Q4 snr_sumt = extract_h( L_shl( L_snr_sumt, Q4 ) ); // Q16 -> Q4 -- GitLab From 5785fc2be7ec1c0b9b3900ad02fe5e561311ba53 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 29 Apr 2025 13:20:37 +0200 Subject: [PATCH 1150/1221] made 1st parameter const - fix msvc warning fixed two more warnings 'uninitialized local variable' --- lib_com/swb_tbe_com_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5631dfa94..ae5fb0323 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6701,7 +6701,7 @@ void wb_tbe_extras_reset_synth_fx( void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - int16_t element_mode, + const int16_t element_mode, #endif #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic Word16 IsUpsampled3, @@ -7360,8 +7360,8 @@ void synthesise_fb_high_band_fx( { #ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32; - Word16 tmp16; + Word32 L_tmp32 = L_add(0,0); + Word16 tmp16 = add( 0, 0 ); // if (L_tmp < 0) if ( L_tmp < 0 ) -- GitLab From 5f81a24eba14c191d0af5d8b02c27a713948c07e Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Tue, 29 Apr 2025 15:16:40 +0200 Subject: [PATCH 1151/1221] fix formatting --- lib_com/swb_tbe_com_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index ae5fb0323..a3a18e32c 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7360,7 +7360,7 @@ void synthesise_fb_high_band_fx( { #ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32 = L_add(0,0); + Word32 L_tmp32 = L_add( 0, 0 ); Word16 tmp16 = add( 0, 0 ); // if (L_tmp < 0) -- GitLab From 20e7299b27635e3b3f7a8e55f2274a5f2f672450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Tue, 29 Apr 2025 16:44:20 +0200 Subject: [PATCH 1152/1221] Restore old base rules from BASOP branch Should re-introduce the expected behavior for BASOP builds. --- .gitlab-ci.yml | 1 + .gitlab-ci/rules-basis.yml | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .gitlab-ci/rules-basis.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bb2259810..e03f48d00 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ variables: include: - local: .gitlab-ci/variables.yml + - local: .gitlab-ci/rules-basis.yml - project: ivas-codec-pc/ivas-codec-ci ref: *IVAS_CODEC_CI_REF file: main.yml diff --git a/.gitlab-ci/rules-basis.yml b/.gitlab-ci/rules-basis.yml new file mode 100644 index 000000000..c650f574a --- /dev/null +++ b/.gitlab-ci/rules-basis.yml @@ -0,0 +1,53 @@ +# overwrites the default rules in the IVAS CI repository +# should be refactored and unified +.rules-basis: + rules: + # see https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + variables: + IVAS_PIPELINE_NAME: 'MR pipeline: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' + ### disabled for now because pipeline cd is redundant with MR pipeline with current workflow + # - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Pushes to main + # variables: + # IVAS_PIPELINE_NAME: 'Push pipeline: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'default' # for testing + variables: + IVAS_PIPELINE_NAME: 'Web run pipeline: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare' + variables: + IVAS_PIPELINE_NAME: 'Run comparison tools against float ref: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare-enc-dmx' + variables: + IVAS_PIPELINE_NAME: 'Run encoder dmx comparison against float ref: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare-long' + variables: + IVAS_PIPELINE_NAME: 'Run comparison tools against float ref (long test vectors): $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-compare-to-input' + variables: + IVAS_PIPELINE_NAME: 'Run comparison tools against input (pass-through only): $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-saturation-smoke-test' + variables: + IVAS_PIPELINE_NAME: 'Run saturation smoke-test: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'evs-26444' + variables: + IVAS_PIPELINE_NAME: 'EVS 26.444 test: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'sanitizer' + variables: + IVAS_PIPELINE_NAME: 'Short testvectors sanitizers' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'pytest-renderer' + variables: + IVAS_PIPELINE_NAME: 'Renderer test: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'complexity' + variables: + IVAS_PIPELINE_NAME: 'Complexity Measurement on $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'voip-be-test' + variables: + IVAS_PIPELINE_NAME: 'Voip BE test on $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'peaq-enc-passthrough' + variables: + IVAS_PIPELINE_NAME: 'PEAQ encoder pass-through test: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'schedule' # Scheduled in any branch + variables: + IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' -- GitLab From ded7d14aac5cfd179b1e1b80f64c0dc84dd5f346 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Tue, 29 Apr 2025 17:39:47 +0200 Subject: [PATCH 1153/1221] remove UTF-8 BOMs at beginning of files --- lib_dec/lib_dec_fx.c | 2 +- lib_enc/init_enc_fx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 77deb9e7d..421137631 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -1,4 +1,4 @@ -/****************************************************************************************************** +/****************************************************************************************************** (C) 2022-2025 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., diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 98d7fe957..cf79a4de3 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1,4 +1,4 @@ -/*==================================================================================== +/*==================================================================================== EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ -- GitLab From 8a5d21c9855023b9da4dfa0d80e1d4e12cfc002a Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 29 Apr 2025 19:39:31 +0200 Subject: [PATCH 1154/1221] Fix for ivas-pytest-compare-to-input-anchor --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e03f48d00..b93061941 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -639,8 +639,6 @@ workflow: - report-junit.xml .ivas-pytest-compare-to-input-anchor: &ivas-pytest-compare-to-input-anchor - extends: - - .job-linux stage: test needs: ["build-codec-linux-make"] timeout: "360 minutes" -- GitLab From 51e39130bb2fbda03cc3e8d145e17f7f028698b6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 30 Apr 2025 11:56:09 +0530 Subject: [PATCH 1155/1221] Fix for 3GPP issue 1415: Cleanup of pre-processor macros Link #1415 --- lib_com/basop_util.c | 10 - lib_com/bitstream_fx.c | 2 - lib_com/cldfb_evs.c | 7 - lib_com/core_com_config.c | 55 +- lib_com/hq_conf_fx.c | 4 - lib_com/interleave_spectrum.c | 12 - lib_com/prot_fx.h | 81 +-- lib_com/swb_tbe_com_fx.c | 422 +----------- lib_com/tcx_mdct_window.c | 39 -- lib_com/tns_base.c | 20 - lib_dec/FEC_HQ_phase_ecu_fx.c | 525 --------------- lib_dec/TonalComponentDetection_fx.c | 9 - lib_dec/acelp_core_dec_fx.c | 5 - lib_dec/amr_wb_dec_fx.c | 5 - lib_dec/core_dec_init_fx.c | 116 ---- lib_dec/core_dec_switch_fx.c | 22 - lib_dec/dec_LPD_fx.c | 8 - lib_dec/dec_ace_fx.c | 7 - lib_dec/dec_acelp_tcx_main_fx.c | 4 - lib_dec/dec_tcx_fx.c | 3 - lib_dec/er_dec_tcx_fx.c | 114 ---- lib_dec/evs_dec_fx.c | 4 - lib_dec/fd_cng_dec_fx.c | 155 +---- lib_dec/gs_dec_amr_wb_fx.c | 43 -- lib_dec/hq_classifier_dec_fx.c | 10 - lib_dec/hq_core_dec_fx.c | 111 ---- lib_dec/hq_hr_dec_fx.c | 1 - lib_dec/ivas_output_config_fx.c | 10 - lib_dec/tns_base_dec_fx.c | 53 +- lib_dec/tonalMDCTconcealment_fx.c | 456 ------------- lib_dec/updt_dec_fx.c | 35 - lib_enc/cng_enc_fx.c | 5 - lib_enc/cod_tcx_fx.c | 628 ------------------ lib_enc/core_enc_init_fx.c | 7 - lib_enc/core_enc_switch_fx.c | 11 - lib_enc/core_enc_updt_fx.c | 14 - lib_enc/enc_pit_exc_fx.c | 5 - lib_enc/evs_enc_fx.c | 22 - lib_enc/ext_sig_ana_fx.c | 152 ----- lib_enc/hq_classifier_enc_fx.c | 195 +----- lib_enc/hq_core_enc_fx.c | 117 ---- lib_enc/hq_hr_enc_fx.c | 14 - lib_enc/init_enc_fx.c | 15 +- lib_enc/ivas_omasa_enc_fx.c | 5 - lib_enc/lib_enc.c | 36 +- lib_enc/mdct_classifier_fx.c | 78 +-- lib_enc/tcx_utils_enc_fx.c | 4 +- lib_enc/transient_detection_fx.c | 75 --- lib_enc/updt_enc_fx.c | 31 - .../ivas_dirac_dec_binaural_functions_fx.c | 14 - 50 files changed, 20 insertions(+), 3756 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index ec15e9769..dc9013a42 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1409,15 +1409,6 @@ Word32 BASOP_Util_Divide3232_Scale_newton( Word32 x, Word32 y, Word16 *s ) *s = 0; return ( (Word32) 0 ); } - -#if 0 - sign = L_xor( x, y ); /* check (sign < 0) for result negation */ - - if ( x < 0 ) - { - x = L_negate( x ); - } -#else IF( EQ_32( y, 0x80000000 ) ) { /* Division by -1.0: same as negation of numerator */ @@ -1429,7 +1420,6 @@ Word32 BASOP_Util_Divide3232_Scale_newton( Word32 x, Word32 y, Word16 *s ) } sign = y; move32(); -#endif if ( y < 0 ) { y = L_negate( y ); diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 07a6a632f..4fcac20b6 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -52,7 +52,6 @@ int16_t FEC_seed = 12558; /* Seed for random FEC generator */ FILE *FEC_pattern = NULL; /* FEC pattern file (for simulation of FEC) */ -#ifndef IVAS_CODE float FEC_random = 0; /* FEC rate in percent (for simulation of FEC) */ /*-------------------------------------------------------------------* * file_read_FECpattern() @@ -109,7 +108,6 @@ static int16_t file_read_FECpattern( void ) return bfi; } #endif -#endif /*-------------------------------------------------------------------* * pack_bit() * diff --git a/lib_com/cldfb_evs.c b/lib_com/cldfb_evs.c index c28a534d6..51c9ee6f9 100644 --- a/lib_com/cldfb_evs.c +++ b/lib_com/cldfb_evs.c @@ -981,10 +981,6 @@ ivas_error openCldfb( const Word16 type, /*!< analysis or synthesis */ const Word16 maxCldfbBands, /*!< number of cldfb bands */ const Word16 frameSize /*!< FrameSize */ -#ifdef ADD_IVAS_CLDFB - , - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -#endif ) { HANDLE_CLDFB_FILTER_BANK hs; @@ -996,9 +992,6 @@ ivas_error openCldfb( } hs->type = type; -#ifdef ADD_IVAS_CLDFB - hs->prototype = prototype; -#endif move16(); IF( type == CLDFB_ANALYSIS ) diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index f0ee8efd8..f75f28a18 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -246,67 +246,18 @@ Word16 getTcxonly_ivas_fx( } Word16 getTcxonly( -#ifdef IVAS_CODE_SWITCHING - const Word16 element_mode, /* i : IVAS element mode */ -#endif const Word32 total_brate /* i : total bitrate */ -#ifdef IVAS_CODE_SWITCHING - , - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t is_ism_format /* i : flag indicating ISM format */ -#endif ) { Word16 tcxonly; tcxonly = 0; move16(); -#ifdef IVAS_CODE_SWITCHING - SWITCH( element_mode ) + if ( GT_32( total_brate, 32000 ) ) { - case EVS_MONO: -#endif - if ( GT_32( total_brate, 32000 ) ) - { - tcxonly = 1; - move16(); - } -#ifdef IVAS_CODE_SWITCHING - break; - case IVAS_SCE: - if ( is_ism_format ) - { - if ( total_brate > MAX_ACELP_BRATE_ISM ) - { - tcxonly = 1; - } - } - else - { - if ( total_brate > MAX_ACELP_BRATE ) - { - tcxonly = 1; - } - } - break; - - case IVAS_CPE_DFT: - case IVAS_CPE_TD: - if ( total_brate > MAX_ACELP_BRATE ) - { - tcxonly = 1; - } - break; - case IVAS_CPE_MDCT: - if ( total_brate >= ( MCT_flag ? IVAS_32k : IVAS_48k ) ) - { - tcxonly = 1; - } - break; -#endif -#ifdef IVAS_CODE_SWITCHING + tcxonly = 1; + move16(); } -#endif return tcxonly; /*Q0*/ } diff --git a/lib_com/hq_conf_fx.c b/lib_com/hq_conf_fx.c index 503975363..f6a01adfc 100644 --- a/lib_com/hq_conf_fx.c +++ b/lib_com/hq_conf_fx.c @@ -303,11 +303,7 @@ void hq_configure_evs_fx( *start_norm = 0; move16(); -#ifndef SOLVED_COMP_ENC_DEC IF( EQ_16( length, L_FRAME48k ) ) /*tbv SOLVED_COMP_ENC_DEC*/ -#else - IF( EQ_16( length, L_SPEC48k ) ) -#endif { IF( EQ_16( hqswb_clas, HQ_GEN_FB ) ) { diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum.c index 5c4c98e29..e8bb728ff 100644 --- a/lib_com/interleave_spectrum.c +++ b/lib_com/interleave_spectrum.c @@ -63,11 +63,7 @@ void interleave_spectrum_fx( /* Common inits */ p1 = coefs; /*Q12*/ p_out = coefs_out; -#ifdef SOLVED_COMP_ENC_DEC - IF( EQ_16( length, L_SPEC48k ) ) -#else IF( EQ_16( length, L_FRAME48k ) ) -#endif { bw = intl_bw_48; /*Q0*/ cnt = intl_cnt_48; /*Q0*/ @@ -337,20 +333,12 @@ void de_interleave_spectrum_fx( p1 = coefs_out; l_frame = length; move16(); -#ifdef SOLVED_COMP_ENC_DEC - IF( EQ_16( length, L_SPEC48k ) ) -#else IF( EQ_16( length, L_FRAME48k ) ) -#endif { bw = intl_bw_48; /*Q0*/ cnt = intl_cnt_48; /*Q0*/ grps = N_INTL_GRP_48; move16(); -#ifdef SOLVED_COMP_ENC_DEC - l_frame = L_FRAME48k; - move16(); -#endif p2 = coefs_out + sublen[2]; /* 240, length/4 */ p3 = coefs_out + sublen[4]; /* 480, 2*length/4 */ p4 = coefs_out + sublen[5]; /* 720, 3*length/4 */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 86b5ec0b7..fde3949fd 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3062,20 +3062,6 @@ void GenShapedSHBExcitation_fx( Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, const Word16 prev_bfi -#ifdef ADD_IVAS_TBE_CODE - , /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - Word16 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -#endif ); void GenShapedSHBExcitation_ivas_enc_fx( @@ -3152,7 +3138,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, const Word16 prev_bfi -#if 1 // def ADD_IVAS_TBE_CODE , /* i : previous frame was concealed */ const Word16 element_mode, /* i : element mode */ const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ @@ -3165,7 +3150,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -#endif ); void GenSHBSynth_fx( @@ -3309,9 +3293,6 @@ void synthesise_fb_high_band_fx( #ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ -#ifdef ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif const Word16 i_subfr_fx, /* i : subframe index */ const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ @@ -3326,21 +3307,12 @@ void prep_tbe_exc_fx( Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ Word32 core_brate /* i :core bitrate */ -#ifdef ADD_IVAS_TBE_CODE - , - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif ); #endif void prep_tbe_exc_ivas_fx( const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE const Word16 L_subfr, -#endif const Word16 i_subfr_fx, /* i : subframe index */ const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ @@ -3355,13 +3327,11 @@ void prep_tbe_exc_ivas_fx( Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE , /* i : core bitrate */ const Word16 element_mode, /* i : element mode */ const Word16 idchan, /* i : channel ID */ const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif ); Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ @@ -4180,15 +4150,7 @@ Word16 get_codec_mode( ); Word16 getTcxonly( -#ifdef IVAS_CODE_SWITCHING - const Word16 element_mode, /* i : IVAS element mode */ -#endif const Word32 total_brate /* i : total bitrate */ -#ifdef IVAS_CODE_SWITCHING - , - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t is_ism_format /* i : flag indicating ISM format */ -#endif ); Word16 getTcxonly_fx( @@ -6578,10 +6540,6 @@ void TonalMDCTConceal_SaveFreqSignal( const Word16 *scaleFactors, const Word16 *scaleFactors_exp, const Word16 gain_tcx_exp -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - , - const Word16 infoIGFStartLine -#endif ); void TonalMDCTConceal_SaveFreqSignal_ivas_fx( @@ -6650,9 +6608,6 @@ void TonalMDCTConceal_InsertNoise( Word16 *pSeed, /*IN/OUT*/ const Word16 tiltCompFactor, Word16 crossfadeGain, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - const Word16concealment_noise[L_FRAME48k], -#endif const Word16 crossOverFreq ); void TonalMDCTConceal_SaveTimeSignal( @@ -7646,9 +7601,6 @@ void configureFdCngDec_fx( Word16 ApplyFdCng_fx( Word16 *timeDomainInput, /* i : pointer to time domain i */ Word16 Q, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - Word16 *powerSpectrum, -#endif Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer */ Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer */ Word16 *cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */ @@ -7672,9 +7624,6 @@ Word16 ApplyFdCng_ivas_fx( void perform_noise_estimation_dec_fx( const Word16 *timeDomainInput, /* i: pointer to time domain i */ const Word16 Q, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - float *power_spectrum, -#endif HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ ); @@ -8389,10 +8338,6 @@ void improv_amr_wb_gs_fx( const Word16 Last_ener_fx, /* i : Last energy (Q8) Q0*/ const Word16 rate_switching_reset, /* i : rate switching reset flag Q0*/ const Word16 last_coder_type /* i : Last coder_type Q0*/ -#ifdef ADD_IVAS_GS_DEC_IMPR - , - const Word16 VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ -#endif ); // dec_amr_wb_fx.c @@ -8444,18 +8389,7 @@ ivas_error ppp_quarter_decoder_fx( void open_decoder_LPD_fx( Decoder_State *st, const Word32 total_brate, /* Q0 */ -#ifdef NEW_IVAS_OPEN_DEC - const Word32 last_total_brate, -#endif const Word16 bwidth /* Q0 */ -#ifdef NEW_IVAS_OPEN_DEC - , - const Word16 is_mct, /* i : MCT mode flag */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - const Word16 last_element_mode, -#endif - const Word16 is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ -#endif ); void open_decoder_LPD_ivas_fx( Decoder_State *st, /* i/o: decoder state structure */ @@ -9010,28 +8944,19 @@ void tcx_hm_modify_envelope( ); // tns_base_dec_fx.c -#ifdef IVAS_CODE -void -#else Word16 -#endif ReadTnsData( STnsConfig const *pTnsConfig, Decoder_State *st, Word16 *pnBits, Word16 *stream, Word16 *pnSize ); -#define IVAS_CODE -#ifdef IVAS_CODE + void -#else -Word16 -#endif ReadTnsData_ivas_fx( STnsConfig const *pTnsConfig, Decoder_State *st, Word16 *pnBits, Word16 *stream, Word16 *pnSize ); -#undef IVAS_CODE Word16 DecodeTnsData( STnsConfig const *pTnsConfig, Word16 const *stream, @@ -9454,10 +9379,6 @@ void con_tcx_fx( const Word16 coh, /* i : coherence of stereo signal */ Word16 *noise_seed, /* i/o: noise seed for stereo */ const Word16 only_left /* i : TD-PLC only in left channel */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - , - const float *A_cng /* i : CNG LP filter coefficients */ -#endif #endif ); diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 5631dfa94..d1883efde 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -2103,20 +2103,6 @@ void GenShapedSHBExcitation_fx( Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, const Word16 prev_bfi -#ifdef ADD_IVAS_TBE_CODE - , /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - Word16 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -#endif ) { Word16 i, j, k; @@ -2160,20 +2146,6 @@ void GenShapedSHBExcitation_fx( Word16 Q_temp; Word16 prev_Q_bwe_exc_fb; -#ifdef ADD_IVAS_TBE_CODE - Word32 tempD; - Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; - Word16 cbsize; - Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; - Word16 c0, c1, c2, c3, c4, c5, g1, g2, g, den; - Word16 EnvWhiteExc16k[L_FRAME16k], EnvExc16kWhtnd[L_FRAME16k]; - Word16 EnvWhiteExc16k_4k[L_FRAME4k] = { 0 }, EnvExc16kWhtnd_4k[L_FRAME4k] = { 0 }; - Word16 flag_plosive; - Word16 delta; - Word16 c0_part[NUM_SHB_SUBGAINS], c1_part[NUM_SHB_SUBGAINS], c2_part[NUM_SHB_SUBGAINS], c3_part[NUM_SHB_SUBGAINS], c4_part[NUM_SHB_SUBGAINS], c5_part[NUM_SHB_SUBGAINS]; - - mix_factor = 0.0f; -#endif set16_fx( zero_mem, 0, LPC_SHB_ORDER ); set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); @@ -2205,12 +2177,7 @@ void GenShapedSHBExcitation_fx( /* i: exc16k in Q_bwe_exc */ /* o: exc16kWhtnd in Q_bwe_exc */ - -#ifdef ADD_IVAS_TBE_CODE - IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) -#else IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { temp2 = 0; move16(); @@ -2244,11 +2211,7 @@ void GenShapedSHBExcitation_fx( Q_pow1 = shl( *Q_bwe_exc, 1 ); test(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( flag_ACELP16k, 0 ) ) -#else IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) -#endif { /* varEnvShape = mean_fx(voice_factors, 4); */ /* unroll the loop */ @@ -2294,11 +2257,7 @@ void GenShapedSHBExcitation_fx( test(); test(); test(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#else IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#endif { /* pre-init smoothing filter to avoid energy drop outs */ L_tmp = L_mult( excTmp2[0], 1638 ); @@ -2325,42 +2284,6 @@ void GenShapedSHBExcitation_fx( *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); move32(); } -#ifdef ADD_IVAS_TBE_CODE - if ( MSFlag > 0 ) - { - varEnvShape = 0.995f; - csfilt_num2[0] = 1.0f - varEnvShape; - csfilt_den2[1] = -varEnvShape; - } - - White_exc16k = exc16k; - - /* Track the low band envelope */ - if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) - { - if ( extl_brate != SWB_TBE_1k10 && extl_brate != SWB_TBE_1k75 ) - { - mem_csfilt_left = 0.0f; - mem_csfilt_right = 0.0f; - for ( k = 0; k < L_FRAME16k; k++ ) - { - excNoisyEnvLeft[k] = mem_csfilt_left + csfilt_num2[0] * excTmp2[k]; - mem_csfilt_left = -csfilt_den2[1] * excNoisyEnvLeft[k]; - excNoisyEnvRight[L_FRAME16k - k - 1] = mem_csfilt_right + csfilt_num2[0] * excTmp2[L_FRAME16k - k - 1]; - mem_csfilt_right = -csfilt_den2[1] * excNoisyEnvRight[L_FRAME16k - k - 1]; - } - - alpha = 0.0f; - step = 1.0f / L_FRAME16k; - for ( k = 0; k < L_FRAME16k; k++ ) - { - excNoisyEnv[k] = alpha * excNoisyEnvLeft[k] + ( 1 - alpha ) * excNoisyEnvRight[k]; - alpha += step; - } - } - } - else -#endif { /* Track the low band envelope */ L_tmp = *mem_csfilt; @@ -2376,21 +2299,6 @@ void GenShapedSHBExcitation_fx( *mem_csfilt = L_tmp; move32(); } -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - /* generate gaussian (white) excitation */ - for ( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k[k] = (float) own_random( &bwe_seed[0] ); - } - - /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - pow22 = POW_EXC16k_WHTND; - v_multc( White_exc16k, (float) sqrt( pow1 / pow22 ), White_exc16k, L_FRAME16k ); - } - else -#endif { /* create a random excitation - Reuse exc16k memory */ White_exc16k = exc16k; @@ -2439,98 +2347,10 @@ void GenShapedSHBExcitation_fx( Q_pow22 = shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ); } -#ifdef ADD_IVAS_TBE_CODE - flag_plosive = 0; - move16(); - test(); - test(); - test(); - IF(GE_32(extl_brate, SWB_TBE_2k8) || EQ_32(extl_brate, SWB_TBE_1k10) || EQ_32(extl_brate, SWB_TBE_1k75))) -#else IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ { -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - /* calculate TD envelopes of exc16kWhtnd and White_exc16k */ - find_td_envelope( White_exc16k, L_FRAME16k, 20, NULL, EnvWhiteExc16k ); - find_td_envelope( exc16kWhtnd, L_FRAME16k, 20, NULL, EnvExc16kWhtnd ); - - for ( k = 0; k < L_FRAME4k; k++ ) - { - EnvWhiteExc16k_4k[k] = EnvWhiteExc16k[4 * k]; - EnvExc16kWhtnd_4k[k] = EnvExc16kWhtnd[4 * k]; - } - - /* calculate the optimal mix factor */ - c0 = c1 = c2 = c3 = c4 = c5 = 0.0f; - for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c1_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c2_part[i] = sum2_f( &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c3_part[i] = -2.0f * dotp( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c4_part[i] = 2.0f * dotp( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], &EnvWhiteExc16k_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - c5_part[i] = sum2_f( &EnvSHBres_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); - - c0 += c0_part[i]; - c1 += c1_part[i]; - c2 += c2_part[i]; - c3 += c3_part[i]; - c4 += c4_part[i]; - c5 += c5_part[i]; - } - - den = 4.0f * c0 * c2 - c4 * c4; - g1 = ( c3 * c4 - 2 * c1 * c2 ) / den; - g2 = ( c1 * c4 - 2 * c0 * c3 ) / den; - - *Env_error = 0.0f; - flag_plosive = 0; - for ( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - Env_error_part[i] = c5_part[i] + g1 * g1 * c0_part[i] + g1 * c1_part[i] + g2 * g2 * c2_part[i] + g2 * c3_part[i] + g1 * g2 * c4_part[i]; - *Env_error += Env_error_part[i]; - - if ( Env_error_part[i] > THR_ENV_ERROR_PLOSIVE ) - { - /* envelope error is too high -> likely a plosive */ - flag_plosive = 1; - } - } - - if ( flag_plosive ) - { - /* plosive detected -> set the mixing factor to 0 */ - *vf_ind = 0; - mix_factor = 0.0f; - } - else - { - /* normalize gain */ - g = g2 / ( g1 + g2 ); - - /* quantization of the mixing factor */ - cbsize = 1 << NUM_BITS_SHB_VF; - delta = 1.0f / ( cbsize - 1 ); - if ( g > 1.0f ) - { - g = 1.0f; - } - else if ( g < delta ) - { - /* prevent low gains to be quantized to 0 as this is reserved for plosives */ - g = delta; - } - - *vf_ind = usquant( g, &mix_factor, 0.0f, 1.0f / ( cbsize - 1 ), cbsize ); - } - } - else -#endif { Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); @@ -2547,21 +2367,6 @@ void GenShapedSHBExcitation_fx( } ELSE /* decoder side */ { -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - if ( *vf_ind == 0 ) - { - mix_factor = 0.0f; - flag_plosive = 1; - } - else - { - mix_factor = usdequant( *vf_ind, 0.0f, 1.0f / ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) ); - } - } - else -#endif { /* *vf_ind is an integer scale by 0.125f*/ tmp = shl( *vf_ind, ( 15 - 3 ) ); @@ -2574,9 +2379,6 @@ void GenShapedSHBExcitation_fx( } } } -#ifdef ADD_IVAS_TBE_CODE - IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) -#endif { voice_factors[0] = mult_r( voice_factors[0], tmp2 ); move16(); @@ -2590,14 +2392,6 @@ void GenShapedSHBExcitation_fx( move16(); } } -#ifdef ADD_IVAS_TBE_CODE - if ( element_mode >= IVAS_CPE_DFT && nlExc16k != NULL ) - { - /* save buffers for IC-BWE */ - mvr2r( exc16kWhtnd, nlExc16k, L_FRAME16k ); - v_multc( White_exc16k, (float) sqrt( pow1 / pow22 ), mixExc16k, L_FRAME16k ); - } -#endif tmp = sub( Q_temp, 3 ); FOR( k = 0; k < L_FRAME16k; k++ ) @@ -2611,47 +2405,8 @@ void GenShapedSHBExcitation_fx( deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ -#ifdef ADD_IVAS_TBE_CODE - if ( extl_brate == SWB_TBE_1k10 || extl_brate == SWB_TBE_1k75 ) - { - if ( !flag_plosive ) /* use only LB excitation in case of plosives */ - { - /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ - old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); - new_scale = 1.0f; - step_scale = ( new_scale - old_scale ) / ( L_FRAME16k / 2 ); - scale = old_scale; - - /* interpolate between the old and the new value of the mixing factor */ - old_fact = *prev_mix_factor; - new_fact = mix_factor; - step = ( new_fact - old_fact ) / ( L_FRAME16k / 2 ); - fact = old_fact; - - /* mixing of LB and gaussian excitation in the first half of the frame */ - for ( k = 0; k < L_FRAME16k / 2; k++ ) - { - exc16kWhtnd[k] = (float) fact * ( White_exc16k[k] * scale ) + (float) ( 1 - fact ) * exc16kWhtnd[k]; - fact += step; - scale += step_scale; - } - - /* mixing of LB and gaussian excitation in the second half of the frame */ - for ( ; k < L_FRAME16k; k++ ) - { - exc16kWhtnd[k] = (float) new_fact * White_exc16k[k] + (float) ( 1 - new_fact ) * exc16kWhtnd[k]; - } - } - preemph( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - } - else -#endif { -#ifdef ADD_IVAS_TBE_CODE - if ( coder_type == UNVOICED || MSFlag == 1 ) -#else IF( EQ_16( coder_type, UNVOICED ) ) -#endif { L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ @@ -2753,11 +2508,7 @@ void GenShapedSHBExcitation_fx( } } -#ifdef ADD_IVAS_TBE_CODE - IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) -#else IF( LT_32( bitrate, ACELP_24k40 ) ) -#endif { Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); /* i: exc16kWhtnd in Q_bwe_exc */ @@ -2866,10 +2617,6 @@ void GenShapedSHBExcitation_fx( set16_fx( White_exc16k_FB, 0, L_FRAME16k ); } -#ifdef ADD_IVAS_TBE_CODE - *prev_pow_exc16kWhtnd = pow1; - *prev_mix_factor = mix_factor; -#endif return; } @@ -3288,7 +3035,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( { IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ { -#ifndef ADD_IVAS_TBE_CODE // BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { @@ -3474,33 +3220,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } ELSE -#else - UNUSED_PARAM( Env_error_part ); - UNUSED_PARAM( Env_error ); - UNUSED_PARAM( EnvSHBres_4k ); - UNUSED_PARAM( c5_part ); - UNUSED_PARAM( c1 ); - UNUSED_PARAM( den ); - UNUSED_PARAM( c3_part ); - UNUSED_PARAM( c0 ); - UNUSED_PARAM( delta ); - UNUSED_PARAM( c3 ); - UNUSED_PARAM( c2_part ); - UNUSED_PARAM( c1_part ); - UNUSED_PARAM( EnvWhiteExc16k ); - UNUSED_PARAM( g2 ); - UNUSED_PARAM( c5 ); - UNUSED_PARAM( c4_part ); - UNUSED_PARAM( EnvWhiteExc16k_4k ); - UNUSED_PARAM( c2 ); - UNUSED_PARAM( g ); - UNUSED_PARAM( cbsize ); - UNUSED_PARAM( g1 ); - UNUSED_PARAM( EnvExc16kWhtnd ); - UNUSED_PARAM( c0_part ); - UNUSED_PARAM( EnvExc16kWhtnd_4k ); - UNUSED_PARAM( c4 ); -#endif { Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, Q_White_exc16k, pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); @@ -4003,7 +3722,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( move16(); move32(); -#if 1 // def ADD_IVAS_TBE_CODE Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; Word16 cbsize; Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; @@ -4018,7 +3736,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( mix_factor = 0; /* Q15 */ move16(); -#endif + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); FOR( i = 0; i < L_FRAME32k; i = i + 2 ) @@ -4050,11 +3768,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* i: exc16k in Q_bwe_exc */ /* o: exc16kWhtnd in Q_bwe_exc */ -#if 1 // def ADD_IVAS_TBE_CODE IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { temp2 = 0; move16(); @@ -4089,11 +3803,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( Q_pow1 = shl( *Q_bwe_exc, 1 ); test(); -#if 1 // ADD_IVAS_TBE_CODE + IF( flag_ACELP16k == 0 ) -#else - IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) -#endif { /* varEnvShape = mean_fx(voice_factors, 4); */ /* unroll the loop */ @@ -4139,12 +3850,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( test(); test(); test(); -#if 1 // def ADD_IVAS_TBE_CODE - test(); + IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#else - IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#endif { /* pre-init smoothing filter to avoid energy drop outs */ L_tmp = L_mult( excTmp2[0], 1638 ); @@ -4171,7 +3878,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); move32(); } -#if 1 // def ADD_IVAS_TBE_CODE + IF( MSFlag > 0 ) { // varEnvShape = 0.995f; @@ -4231,7 +3938,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( } } ELSE -#endif + { /* Track the low band envelope */ L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); @@ -4257,7 +3964,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); move32(); } -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { @@ -4303,7 +4009,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( } } ELSE -#endif { /* create a random excitation - Reuse exc16k memory */ White_exc16k = exc16k; @@ -4352,20 +4057,15 @@ void GenShapedSHBExcitation_ivas_dec_fx( Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); } -#if 1 // def ADD_IVAS_TBE_CODE flag_plosive = 0; move16(); test(); test(); test(); IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ { -#ifndef ADD_IVAS_TBE_CODE // BELOW PART WILL NEED TO BE CONVERTED FOR ENCODER!! test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { @@ -4544,33 +4244,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( } } ELSE -#else - UNUSED_PARAM( Env_error_part ); - UNUSED_PARAM( Env_error ); - UNUSED_PARAM( EnvSHBres_4k ); - UNUSED_PARAM( c5_part ); - UNUSED_PARAM( c1 ); - UNUSED_PARAM( den ); - UNUSED_PARAM( c3_part ); - UNUSED_PARAM( c0 ); - UNUSED_PARAM( delta ); - UNUSED_PARAM( c3 ); - UNUSED_PARAM( c2_part ); - UNUSED_PARAM( c1_part ); - UNUSED_PARAM( EnvWhiteExc16k ); - UNUSED_PARAM( g2 ); - UNUSED_PARAM( c5 ); - UNUSED_PARAM( c4_part ); - UNUSED_PARAM( EnvWhiteExc16k_4k ); - UNUSED_PARAM( c2 ); - UNUSED_PARAM( g ); - UNUSED_PARAM( cbsize ); - UNUSED_PARAM( g1 ); - UNUSED_PARAM( EnvExc16kWhtnd ); - UNUSED_PARAM( c0_part ); - UNUSED_PARAM( EnvExc16kWhtnd_4k ); - UNUSED_PARAM( c4 ); -#endif { Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); @@ -4588,7 +4261,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( ELSE /* decoder side */ { test(); -#if 1 // def ADD_IVAS_TBE_CODE IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { IF( *vf_ind == 0 ) @@ -4606,7 +4278,6 @@ void GenShapedSHBExcitation_ivas_dec_fx( } } ELSE -#endif { /* *vf_ind is an integer scale by 0.125f*/ tmp = shl( *vf_ind, ( 15 - 3 ) ); @@ -4619,10 +4290,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( } } } -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) -#endif { voice_factors[0] = mult_r( voice_factors[0], tmp2 ); move16(); @@ -4979,10 +4648,8 @@ void GenShapedSHBExcitation_ivas_dec_fx( set16_fx( White_exc16k_FB, 0, L_FRAME16k ); } -#if 1 // def ADD_IVAS_TBE_CODE *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 *prev_mix_factor = mix_factor; -#endif return; } @@ -7566,56 +7233,7 @@ void Estimate_mix_factors_fx( return; } -#ifdef ADD_IVAS_TBE_CODE -/*-------------------------------------------------------------------* - * tbe_celp_exc() * - * * - * Prepare adaptive part of TBE excitation * - *-------------------------------------------------------------------*/ - -void tbe_celp_exc( - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - float *bwe_exc, /* i/o: BWE excitation */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - float *error, /* i/o: error */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -) -{ - int16_t i, offset; - - if ( element_mode == IVAS_CPE_TD && idchan == 1 && !tdm_LRTD_flag ) - { - return; - } - - if ( L_frame == L_FRAME ) - { - offset = tbe_celp_exc_offset( T0, T0_frac ); - - for ( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) - { - bwe_exc[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc[i + i_subfr * HIBND_ACB_L_FAC - offset + (int16_t) *error]; - } - *error += (float) offset - (float) T0 * HIBND_ACB_L_FAC - 0.25f * HIBND_ACB_L_FAC * (float) T0_frac; - } - else - { - offset = T0 * 2 + (int16_t) ( (float) T0_frac * 0.5f + 4 + 0.5f ) - 4; - for ( i = 0; i < L_subfr * 2; i++ ) - { - bwe_exc[i + i_subfr * 2] = bwe_exc[i + i_subfr * 2 - offset + (int16_t) *error]; - } - *error += (float) offset - (float) T0 * 2 - 0.5f * (float) T0_frac; - } - return; -} -#endif /*======================================================================================*/ /* FUNCTION : prep_tbe_exc_fx() */ /*--------------------------------------------------------------------------------------*/ @@ -7647,9 +7265,6 @@ void tbe_celp_exc( #ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( const Word16 L_frame_fx, /* i : length of the frame */ -#ifdef ADD_IVAS_TBE_CODE - const Word16 L_subfr, -#endif const Word16 i_subfr_fx, /* i : subframe index */ const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ @@ -7664,13 +7279,6 @@ void prep_tbe_exc_fx( Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ Word32 core_brate -#ifdef ADD_IVAS_TBE_CODE - , /* i : core bitrate */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif ) { Word16 i; @@ -7685,10 +7293,8 @@ void prep_tbe_exc_fx( Word32 L_tmp, Ltemp1, Ltemp2; Word32 tempQ31; Word16 tempQ15; -#ifndef ADD_IVAS_TBE_CODE Word16 L_subfr = L_SUBFR; move16(); -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -7719,17 +7325,6 @@ void prep_tbe_exc_fx( *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); move16(); -#ifdef ADD_IVAS_TBE_CODE - IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) - { - IF( flag_TD_BWE && i_subfr == 0 ) - { - set16_fx( bwe_exc, 0, L_FRAME32k ); - } - return; - } - -#endif IF( EQ_16( L_frame_fx, L_FRAME ) ) { interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ @@ -7816,9 +7411,7 @@ void prep_tbe_exc_fx( #endif void prep_tbe_exc_ivas_fx( const Word16 L_frame_fx, /* i : length of the frame */ -#if 1 // def ADD_IVAS_TBE_CODE const Word16 L_subfr, -#endif const Word16 i_subfr_fx, /* i : subframe index */ const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ @@ -7833,13 +7426,11 @@ void prep_tbe_exc_ivas_fx( Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ Word32 core_brate -#if 1 // def ADD_IVAS_TBE_CODE , /* i : core bitrate */ const Word16 element_mode, /* i : element mode */ const Word16 idchan, /* i : channel ID */ const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ -#endif ) { Word16 i; @@ -7885,7 +7476,7 @@ void prep_tbe_exc_ivas_fx( *voice_factors_fx = s_min( s_max( *voice_factors_fx, 0 ), MAX_16 ); move16(); -#if 1 // def ADD_IVAS_TBE_CODE + test(); test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( idchan, 1 ) && !tdm_LRTD_flag ) @@ -7898,7 +7489,6 @@ void prep_tbe_exc_ivas_fx( return; } -#endif IF( EQ_16( L_frame_fx, L_FRAME ) ) { interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index 44ce806f7..0316ec582 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -123,9 +123,6 @@ void mdct_window_sine( Word16 n /* Q0 */ ) { -#ifdef IVAS_CODE - if ( element_mode == EVS_MONO ) -#endif { const PWord16 *table; table = getSineWindowTable( n ); @@ -138,42 +135,6 @@ void mdct_window_sine( } // PMT("getSineWindowTable needs to be updated for IVAS") } -#ifdef IVAS_CODE - else - { - const float *window_table = 0; - Word16 buf_in_size = 0; - switch ( window_type ) - { - case FULL_OVERLAP: - window_table = tcx_mdct_window_48; - buf_in_size = 420; - break; - case HALF_OVERLAP: - window_table = tcx_mdct_window_half_48; - buf_in_size = 180; - break; - case TRANSITION_OVERLAP: - case MIN_OVERLAP: - window_table = tcx_mdct_window_trans_48; - buf_in_size = 60; - break; - - default: - assert( 0 && "Unsupported window type" ); - break; - } - - if ( Fs == 48000 ) - { - mvr2r( window_table, window, n ); - } - else - { - lerp( window_table, window, n, buf_in_size ); - } - } -#endif } diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 101bc1df8..82de45023 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -96,10 +96,8 @@ void InitTnsConfiguration( Word32 nSampleRate; Word16 s1; Word16 s2; -#ifndef ADD_IVAS_TNS (void) ( element_mode ); (void) ( is_mct ); -#endif nSampleRate = bwMode2fs[bwidth]; move32(); startLineFilter = &pTnsConfig->iFilterBorders[1]; @@ -138,21 +136,6 @@ void InitTnsConfiguration( ELSE IF( GT_32( nSampleRate, INT_FS_16k ) ) { -#ifdef ADD_IVAS_TNS - if ( ( element_mode > IVAS_SCE ) && ( total_brate >= ( is_mct ? IVAS_32k : IVAS_48k ) ) ) - { - pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz_Stereo ) / sizeof( tnsParameters32kHz_Stereo[0] ); - if ( nSampleRate == 100 * frameLength ) /* sub-frame length is <= 10 ms */ - { - pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped; - } - else - { - pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo; - } - } - else -#endif { move16(); @@ -212,9 +195,6 @@ void InitTnsConfiguration( move16(); pTnsConfig->iFilterBorders[0] = frameLength; } -#ifdef ADD_IVAS_TNS - pTnsConfig->allowTnsOnWhite = 0; -#endif return; /*TNS_NO_ERROR;*/ } diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index ef09c3de3..dedf9f859 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -65,25 +65,12 @@ static void windowing_ROM_optimized( const Word16 *, Word16 *, const Word16, con static void fft_spec2_fx( const Word16[], Word32[], const Word16 ); static void trans_ana_fx( const Word16 *, Word16 *, Word16 *, Word16 *, const Word16, const Word16, const Word16, const Word16, Word16 *, Word16 *, Word16 *, Word16 * ); static void peakfinder_fx( const Word16 *, const Word16, Word16 *, Word16 *, const Word16 -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 endpoints /* i : Flag to include endpoints in peak search */ -#endif ); static Word16 imax_fx( const Word16 *, const Word16 ); static void spec_ana_fx( const Word16 *prevsynth, Word16 *plocs, Word32 *plocsi, Word16 *num_plocs, Word16 *X_sav, const Word16 output_frame, const Word16 bwidth_fx, Word16 *Q -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 element_mode, - Word16 *noise_fac, - const Word16 pcorr -#endif ); static void subst_spec_fx( const Word16 *, const Word32 *, Word16 *, const Word16, Word16 *, const Word16 *, const Word16, const Word16 *, const Word16, Word16 *, const Word16 *, const Word16 *, Word16, const Word16 * ); static Word16 rand_phase_fx( const Word16 seed, Word16 *sin_F, Word16 *cos_F ); -#ifdef IVAS_FEC_ECU_TO_COMPLETE -static float imax2_jacobsen_mag( const float *y_re, const float *y_im ); -#endif /*------------------------------------------------------------------* * rand_phase() @@ -666,9 +653,6 @@ static void ivas_peakfinder_fx( move16(); } len0Minus2 = sub( len0, 2 ); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - PMT( "\nlen0Minus2 = sub(len0, 2) is it still correct if IVAS_FEC_ECU_TO_COMPLETE is activated\n" ) -#endif FOR( i = 0; i < len0Minus2; i++ ) { @@ -912,10 +896,6 @@ static void peakfinder_fx( Word16 *plocs, /* o : the indices of the identified peaks in x0 Q0 */ Word16 *cInd, /* o : number of identified peaks Q0 */ const Word16 sel /* i : The amount above surrounding data for a peak to be identified */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 endpoints /* i : Flag to include endpoints in peak search */ -#endif ) { const Word16 *pX0; @@ -951,11 +931,6 @@ static void peakfinder_fx( pInd = indarr; pDx01 = dx0; pDx0 = pDx01 + 1; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - len = 0; - move16(); - IF( endpoints ) -#endif { *pX++ = *pX0++; move16(); @@ -965,9 +940,6 @@ static void peakfinder_fx( move16(); } len0Minus2 = sub( len0, 2 ); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - PMT( "\nlen0Minus2 = sub(len0, 2) is it still correct if IVAS_FEC_ECU_TO_COMPLETE is activated\n" ) -#endif FOR( i = 0; i < len0Minus2; i++ ) { @@ -981,9 +953,6 @@ static void peakfinder_fx( } pX0++; } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( endpoints ) -#endif { *pInd = len0Minus1; move16(); @@ -994,13 +963,7 @@ static void peakfinder_fx( minimum_fx( x, len, &minMag ); pInd = indarr; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - test(); - test(); - IF( GT_16( len, 2 ) || ( !endpoints && ( len > 0 ) ) ) -#else IF( GT_16( len, 2 ) ) -#endif { /* Set initial parameters for loop */ tempMag = minMag; @@ -1011,9 +974,6 @@ static void peakfinder_fx( move16(); threshold = add( leftMin, sel ); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( len > 0 ) -#endif { /* Deal with first point a little differently since tacked it on Calculate the sign of the derivative since we took the first point @@ -1060,20 +1020,6 @@ static void peakfinder_fx( } pX--; /* After decrement, pX points to either x[-1] or x[0]. */ } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - PMTE() - ii = -1; /* First point is a peak */ - if ( len >= 2 ) - { - if ( x[1] >= x[0] ) - { - ii = 0; /* First point is a valley, skip it */ - } - } - } -#endif *cInd = 0; move16(); /*Loop through extrema which should be peaks and then valleys*/ @@ -1179,9 +1125,6 @@ static void peakfinder_fx( } ELSE /* This is a monotone function where an endpoint is the only peak */ { -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( endpoints ) -#endif { xInd = 1; move16(); @@ -1206,13 +1149,6 @@ static void peakfinder_fx( move16(); } } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { /* Input constant or all zeros -- no peaks found */ - *cInd = 0; - move16(); - } -#endif } } @@ -1709,12 +1645,6 @@ static void spec_ana_fx( const Word16 output_frame, /* i : Frame length Q0 */ const Word16 bwidth_fx, /* i : Encoded bandwidth index Q0 */ Word16 *Q /* o : Q value of the fft spectrum */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 element_mode, /* i : IVAS element mode */ - Word16 *noise_fac, /* o : for few peaks zeroing valleys decision making */ - const Word16 pcorr -#endif ) { Word16 Lprot, LprotLog2Minus1, hamm_len2, Lprot2, Lprot2_1, m, n; @@ -1782,52 +1712,18 @@ static void spec_ana_fx( IF( EQ_16( output_frame, L_FRAME48k ) ) { /* Apply hamming-rect window */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( EQ_16( element_mode, EVS_MONO ) ) -#endif { windowing( xfp, xfp, w_hamm_sana48k_2_fx, rectLength, hamm_len2 ); } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - PMTE() - // window_corr = w_hamm[0]; - // window_corr_step = w_hamm[0] / hamm_len2; - // for (i = 0; i < hamm_len2; i++) - //{ - // xfp[i] = prevsynth[i] * (w_hamm[i] - window_corr); - // xfp[Lprot - i - 1] = prevsynth[Lprot - i - 1] * (w_hamm[i] - window_corr); - // window_corr -= window_corr_step; - // } - } -#endif /* Spectrum */ fft3_fx( xfp, xfp, Lprot ); } ELSE { -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( EQ_16( element_mode, EVS_MONO ) ) -#endif { /* Apply hamming-rect window */ windowing_ROM_optimized( xfp, xfp, sinTblOffset, rectLength, hamm_len2 ); } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - PMTE() - // window_corr = w_hamm[0]; - // window_corr_step = w_hamm[0] / hamm_len2; - // for (i = 0; i < hamm_len2; i++) - //{ - // xfp[i] = prevsynth[i] * (w_hamm[i] - window_corr); - // xfp[Lprot - i - 1] = prevsynth[Lprot - i - 1] * (w_hamm[i] - window_corr); - // window_corr -= window_corr_step; - // } - } -#endif /* Spectrum */ r_fft_fx_lc( pFftTbl, Lprot, Lprot2, LprotLog2Minus1, xfp, xfp, 1 ); } @@ -1880,35 +1776,13 @@ static void spec_ana_fx( /* Find maximum and minimum. */ maximum_fx( xfp, Lprot2_1, &Xmax ); minimum_fx( xfp, Lprot2_1, &Xmin ); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( EQ_16( element_mode, EVS_MONO ) ) -#endif { sel = mult_r( sub( Xmax, Xmin ), CMPLMNT_PFIND_SENS_FX ); } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - sel = ( Xmax - Xmin ) * ( 1.0f - ST_PFIND_SENS ); - } -#endif peakfinder_fx( xfp, Lprot2_1, plocs, num_plocs, sel -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - endpoints -#endif ); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - /* Currently not the pitch correlation but some LF correlation */ - if ( element_mode != EVS_MONO && *num_plocs > 50 && pcorr < 0.6f ) - { - *num_plocs = 0; - } - - IF( EQ_16( element_mode, EVS_MONO ) ) -#endif { /* Refine peaks */ @@ -1955,105 +1829,6 @@ static void spec_ana_fx( move32(); /* in Q16. Append the fractional part to the integral part. */ } } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - Lprot2p1 = Lprot / 2 + 1; - - /* Refine peaks */ - pPlocsi = plocsi; - pPlocs = plocs; - n = *num_plocs; /* number of peaks to process */ - - /* Special case-- The very 1st peak if it is at 0 index position (DC) */ - /* With DELTA_CORR_F0_INT == 2 one needs to handle both *pPlocs==0 and *pPlocs==1 */ - if ( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */ - { - *pPlocsi++ = *pPlocs + imax_pos( &xfp[*pPlocs] ); - pPlocs++; - n = n - 1; - } - - if ( n > 0 && *pPlocs == 1 ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ - { - *pPlocsi++ = *pPlocs - 1 + imax_pos( &xfp[*pPlocs - 1] ); - currPlocs = *pPlocs++; - n = n - 1; - } - - /* All remaining peaks except the very last two possible integer positions */ - currPlocs = *pPlocs++; - endPlocs = Lprot2p1 - DELTA_CORR_F0_INT; /* last *pPlocs position for Jacobsen */ - - /* precompute number of turns based on endpoint integer location and make into a proper for loop */ - if ( n > 0 ) - { - nJacob = n; - if ( sub( endPlocs, plocs[sub( *num_plocs, 1 )] ) <= 0 ) - { - nJacob = sub( nJacob, 1 ); - } - - for ( k = 0; k < nJacob; k++ ) - { - *pPlocsi++ = currPlocs + imax2_jacobsen_mag( &( X_sav[currPlocs - 1] ), &( X_sav[Lprot - 1 - currPlocs] ) ); - currPlocs = *pPlocs++; - } - n = n - nJacob; - } - - /* At this point there should at most two plocs left to process */ - /* the position before fs/2 and fs/2 both use the same magnitude points */ - if ( n > 0 ) - { - /* [ . . . . . . . ] Lprot/2+1 positions */ - /* | | | */ - /* 0 (Lprot/2-2) (Lprot/2) */ - - if ( currPlocs == ( Lprot2p1 - DELTA_CORR_F0_INT ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ - { - *pPlocsi++ = currPlocs - 1 + imax_pos( &xfp[currPlocs - 1] ); - currPlocs = *pPlocs++; - n = n - 1; - } - - /* Here the only remaining point would be a fs/2 plocs */ - /* pXfp = xfp + sub(Lprot2,1); already set just a reminder where it - * whould point */ - if ( n > 0 ) /* fs/2 which makes special case . */ - { - *pPlocsi++ = currPlocs - 2 + imax_pos( &xfp[currPlocs - 2] ); - currPlocs = *pPlocs++; - n = n - 1; - } - } - - /* For few peaks decide noise floor attenuation */ - if ( *num_plocs < 3 && *num_plocs > 0 ) - { - sig = sum_f( xfp, Lprot2_1 ) + EPSILON; - - /*excluding peaks and neighboring bins*/ - for ( i = 0; i < *num_plocs; i++ ) - { - st_point = max( 0, plocs[i] - DELTA_CORR ); - end_point = min( Lprot2_1 - 1, plocs[i] + DELTA_CORR ); - set_f( &xfp[st_point], 0.0f, end_point - st_point + 1 ); - } - noise = sum_f( xfp, Lprot2_1 ) + EPSILON; - nsr = noise / sig; - - if ( nsr < 0.03f ) - { - *noise_fac = 0.5f; - } - else - { - *noise_fac = 1.0f; - } - } - } -#endif } /*-------------------------------------------------------------------* @@ -2474,12 +2249,6 @@ static void subst_spec_fx( const Word16 *beta, /* i : Magnitude modification factors for fade to average Q15 */ Word16 beta_mute, /* i : Factor for long-term mute Q15 */ const Word16 *Xavg /* i : Frequency group averages to fade to Q0 */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 element_mode, /* i : IVAS element mode */ - const Word16 ph_ecu_lookahead, /* i : Phase ECU lookahead */ - const Word16 noise_fac /* i : noise factor */ -#endif ) { Word16 Xph_short; @@ -2500,11 +2269,6 @@ static void subst_spec_fx( Word16 alpha_local; Word16 beta_local; Word16 expo; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - Word16 one_peak_flag_mask; - Word16 alpha_local; - Word16 beta_local; -#endif Word16 mag_chg_local; /*for peak attenuation in burst */ Lprot = 512; @@ -2560,21 +2324,6 @@ static void subst_spec_fx( move32(); } } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - one_peak_flag_mask = 1; /* all ones mask -> keep */ - IF( NE_16( element_mode, EVS_MONO ) ) - { - if ( ( *num_plocs > 0 ) && sub( *num_plocs, 3 ) < 0 ) - { - one_peak_flag_mask = noise_fac; /* all zeroes mask -> zero */ - } - if ( *num_plocs == 0 ) - { - X[0] = 0; /* reset DC if there are no peaks */ - X[shr( Lprot, 1 )] = 0; /* also reset fs/2 if there are no peaks */ - } - } -#endif lprotBy2Minus1 = sub( shr( Lprot, 1 ), 1 ); i = 1; move16(); @@ -2635,21 +2384,10 @@ static void subst_spec_fx( move16(); im = *pImX; move16(); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( EQ_16( element_mode, EVS_MONO ) ) -#endif { tmp = sub( mult_r( re, cos_F ), mult_r( im, sin_F ) ); im = add( mult_r( re, sin_F ), mult_r( im, cos_F ) ); } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - PMTE() - // tmp = one_peak_flag_mask * (X[i] * cos_F - X[im_ind] * sin_F); - // X[im_ind] = one_peak_flag_mask * (X[i] * sin_F + X[im_ind] * cos_F); - } -#endif IF( LT_16( alpha[k], 32766 ) ) { *seed = rand_phase_fx( *seed, &sin_F, &cos_F ); @@ -2766,21 +2504,10 @@ static void subst_spec_fx( move16(); im = *pImX; move16(); -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( EQ_16( element_mode, EVS_MONO ) ) -#endif { tmp = sub_sat( mult_r( re, cos_F ), mult_r( im, sin_F ) ); im = add_sat( mult_r( re, sin_F ), mult_r( im, cos_F ) ); } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - ELSE - { - PMTE() - // tmp = one_peak_flag_mask * (X[i] * cos_F - X[im_ind] * sin_F); - // X[im_ind] = one_peak_flag_mask * (X[i] * sin_F + X[im_ind] * cos_F); - } -#endif IF( LT_16( alpha[k], 32766 ) ) { alpha_local = mag_chg_local; @@ -3032,97 +2759,7 @@ static void rec_wtda_fx( Word16 *p_ecu; Word16 g; Word16 tbl_delta; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - float xsubst_[2 * L_FRAME48k]; - const float *w_hamm; - float *pX_start, *pX_end; - float tmp; - int16_t hamm_len2; - float *pNew; - const float *pOldW, *pNewW; - float xfwin[NS2SA( L_FRAME48k * FRAMES_PER_SEC, N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 )]; - const float *pOld; - int16_t copy_len; - int16_t ola_len; - - copy_len = NS2SA( output_frame * FRAMES_PER_SEC, ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* prototype fill on each side of xsubst to fill MDCT Frame */ - ola_len = NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */ - - if ( output_frame == L_FRAME48k ) - { - w_hamm = w_hamm_sana48k_2; - hamm_len2 = L_PROT_HAMM_LEN2_48k; - } - else if ( output_frame == L_FRAME32k ) - { - w_hamm = w_hamm_sana32k_2; - hamm_len2 = L_PROT_HAMM_LEN2_32k; - } - else - { - w_hamm = w_hamm_sana16k_2; - hamm_len2 = L_PROT_HAMM_LEN2_16k; - } - - if ( element_mode != EVS_MONO && *num_p > 0 && plocs[0] > 3 ) - { - /* Perform inverse windowing of hammrect */ - pX_start = X; - pX_end = X + Lprot - 1; - for ( i = 0; i < hamm_len2; i++ ) - { - tmp = 1.0f / *w_hamm; - *pX_start *= tmp; - *pX_end *= tmp; - pX_start++; - pX_end--; - w_hamm++; - } - } - - /* extract reconstructed frame with aldo window */ - timesh = NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ) - ( 2 * output_frame - Lprot ) / 2; - - set_f( xsubst_, 0.0f, 2 * output_frame - Lprot + timesh ); - mvr2r( X, xsubst_ + 2 * output_frame - Lprot + timesh, Lprot - timesh ); - - /* Copy and OLA look ahead zero part of MDCT window from decoded signal */ - if ( element_mode != EVS_MONO ) - { - mvr2r( old_dec, xsubst_ + NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ), copy_len ); /* also need to scale to Q0 ?? */ - pOld = old_dec + copy_len; - pNew = xsubst_ + copy_len + NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ); - sinq( EVS_PI / ( ola_len * 2 ), 0.0f, ola_len, xfwin ); - v_mult( xfwin, xfwin, xfwin, ola_len ); /* xfwin = sin^2 of 0..pi/4 */ - pOldW = xfwin + ola_len - 1; - pNewW = xfwin; - for ( i = 0; i < ola_len; i++ ) - { - *pNew = *pOld * *pOldW + *pNew * *pNewW; - pOld += 1; - pNew += 1; - pOldW -= 1; - pNewW += 1; - } - } - else - { - /* Smoothen onset of ECU frame */ - xf_len = (int16_t) ( (float) output_frame * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) - ( output_frame - Lprot / 2 ); - p_ecu = xsubst_ + 2 * output_frame - Lprot + timesh; - tbl_delta = 64.f / xf_len; /* 64 samples = 1/4 cycle in sincos_t */ - for ( i = 0; i < xf_len; i++, p_ecu++ ) - { - g = sincos_t[( (int16_t) ( i * tbl_delta ) )]; - g *= g; - *p_ecu = g * ( *p_ecu ); - } - } - - /* Apply TDA and windowing to ECU frame */ - wtda( xsubst_ + output_frame, ecu_rec, NULL, ALDO_WINDOW, ALDO_WINDOW, output_frame ); -#else // PMTE() xsubst_ = rec_buf + output_frame; Lprot2 = shr( Lprot, 1 ); @@ -3175,7 +2812,6 @@ static void rec_wtda_fx( out_ptr = rec_buf + sub( shl( output_frame, 1 ), timesh ); wtda_fx( out_ptr, &Qin, ecu_rec, NULL, 0, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ output_frame ); -#endif return; } @@ -3240,13 +2876,6 @@ static void rec_frame_fx( Word32 *ecu_rec, /* o : Reconstructed frame in tda domain */ const Word16 output_frame, /* i : Frame length */ const Word16 Q -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const float *old_dec, /* i : end of last decoded for OLA before tda and itda */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t *num_p, /* i : Number of peaks */ - const int16_t *plocs /* i : Peak locations */ -#endif ) { const Word16 *pFftTbl; @@ -4034,28 +3663,11 @@ static void fec_ecu_dft_fx( Word16 *Tf_abs, /*Qout */ Word16 *Nfft, Word16 *exp /*Qout = Qin+exp */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const int16_t element_mode /* i : IVAS element mode */ -#endif ) { Word32 L_tmp, Tmp, Tfr32[512], Tfi32[512], fac, *Pt1, *Pt2; Word16 i, tmp, tmp_short, N_LP, target[2 * L_FRAME48k], Tfr16[FEC_FFT_MAX_SIZE], *pt1, *pt2, *pt3; Word16 tmp_loop; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - int16_t alignment_point; - - Lon20 = (int16_t) 160 / 20; - if ( element_mode == EVS_MONO ) - { - alignment_point = 2 * 160 - 3 * Lon20; - } - else - { - alignment_point = 2 * 160; - } -#endif tmp = sub( 296, N ); Copy( &prevsynth_LP[tmp], target, N ); @@ -4588,11 +4200,6 @@ static void fec_noise_filling_fx( const Word16 N, const Word16 HqVoicing, Word16 *gapsynth_fx /*Qsynth */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const int16_t element_mode, /* i : IVAS element mode */ - const float *old_out -#endif ) { @@ -4607,22 +4214,6 @@ static void fec_noise_filling_fx( Word32 L_tmp; const Word16 *sinq_tab; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - - const float *p_mdct_ola; - int16_t alignment_point; - PMTE() - if ( element_mode == EVS_MONO ) - { - alignment_point = 2 * L - 3 * L / 20; - } - else - { - alignment_point = 2 * L; - } - mvr2r( prevsynth + alignment_point - N, noisevect, N ); -#endif - IF( EQ_16( L, L_FRAME32k ) ) { sinq_tab = sinq_32k; @@ -4693,18 +4284,6 @@ static void fec_noise_filling_fx( tmp_fx = div_s( 1, Rnd_N_noise ); /*Q15 */ tmp_fx = round_fx_sat( L_shl_sat( L_mult( tmp_fx, 25736 ), 2 ) ); /*Q15 */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - if ( element_mode == EVS_MONO ) - { - kk = 7 * L / 20; - p_mdct_ola = prevsynth + 37 * L / 20; - } - else - { - kk = NS2SA( L * FRAMES_PER_SEC, N_ZERO_MDCT_NS ); - p_mdct_ola = old_out + kk; - } -#endif sinq_fx( shr( tmp_fx, 1 ), shr( tmp_fx, 2 ), Rnd_N_noise, SS_fx ); @@ -4812,11 +4391,6 @@ static void fec_alg_fx( const Word16 decimatefactor, const Word16 HqVoicing, Word16 *gapsynth /*Qin */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 element_mode, /* i : IVAS element mode */ - const Word16 *old_out -#endif ) { Word16 Nfft; @@ -4829,19 +4403,11 @@ static void fec_alg_fx( Word16 n, Q; fec_ecu_dft_fx( prevsynth_LP, N, Tfr, Tfi, &sum_Tf_abs, Tf_abs, &Nfft, &exp -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - element_mode -#endif ); sinusoidal_synthesis_fx( Tfr, Tfi, Tf_abs, N, output_frame, decimatefactor, Nfft, sum_Tf_abs, synthesis, HqVoicing, exp ); fec_noise_filling_fx( prevsynth, synthesis, ni_seed_forfec, output_frame, i_mult2( N, decimatefactor ), HqVoicing, gapsynth -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - element_mode, old_out -#endif ); n = R1_48 - R2_48; @@ -5018,11 +4584,6 @@ static void hq_phase_ecu_fx( Word16 *beta_mute, /* o : Factor for long-term mute Q15 */ const Word16 bwidth_fx, /* i : Encoded bandwidth */ const Word16 output_frame /* i : frame length */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - const Word16 pcorr, - const Word16 element_mode /* i : IVAS element mode */ -#endif ) { Word16 lprot, offset; @@ -5030,22 +4591,6 @@ static void hq_phase_ecu_fx( Word16 seed; Word16 alpha[LGW_MAX], beta[LGW_MAX]; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - const float *old_dec; - float noise_fac; - int16_t ph_ecu_lookahead; - - noise_fac = 1.0f; - - if ( element_mode == EVS_MONO ) - { - ph_ecu_lookahead = NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); - } - else - { - ph_ecu_lookahead = 0; - } -#endif IF( EQ_16( output_frame, L_FRAME48k ) ) { lprot = L_PROT48k; /* 1536 = (2*output_frame)*1024/1280 */ @@ -5074,29 +4619,17 @@ static void hq_phase_ecu_fx( { test(); // PMT("verify condition compared to float") -#ifdef IVAS_FEC_ECU_TO_COMPLETE - IF( !( prev_bfi != 0 && *last_fec != 0 ) && EQ_16( element_mode == EVS_MONO ) ) -#else if ( !( prev_bfi != 0 && *last_fec != 0 ) ) -#endif { *time_offs = 0; move16(); } -#ifdef IVAS_FEC_ECU_TO_COMPLETE - offset = add( sub( sub( shl( output_frame, 1 ), lprot ), *time_offs ), ph_ecu_lookahead ); -#else offset = sub( sub( shl( output_frame, 1 ), lprot ), *time_offs ); -#endif trans_ana_fx( prevsynth + offset, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, *last_fec, alpha, beta, beta_mute, Xavg ); spec_ana_fx( prevsynth + offset, plocs, plocsi, num_p, X_sav, output_frame, bwidth_fx, Q_spec -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - element_mode, noise_fac, pcorr -#endif ); test(); @@ -5128,21 +4661,10 @@ static void hq_phase_ecu_fx( subst_spec_fx( plocs, plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame, &seed, alpha, beta, *beta_mute, Xavg -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - element_mode, ph_ecu_lookahead, noise_fac -#endif ); /* reconstructed frame in tda domain */ -#ifdef IVAS_FEC_ECU_TO_COMPLETE - old_dec = prevsynth + 2 * output_frame - NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ); -#endif rec_frame_fx( X, ecu_rec, output_frame, *Q_spec -#ifdef IVAS_FEC_ECU_TO_COMPLETE - , - old_dec, element_mode, num_p, plocs -#endif ); *last_fec = 0; @@ -5297,22 +4819,6 @@ void hq_ecu_fx( Word16 decimatefactor; Word16 corr; /*Q15 */ Word16 prevsynth_LP[2 * L_FRAME8k]; -#ifdef IVAS_FEC_ECU_TO_COMPLETE - HQ_DEC_HANDLE hHQ_core; - const float *fec_alg_input; - int16_t evs_mode_selection; - int16_t ivas_mode_selection; - - hHQ_core = st->hHQ_core; - if ( st->element_mode == EVS_MONO ) - { - fec_alg_input = prevsynth + NS2SA( output_frame * FRAMES_PER_SEC, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ); - } - else - { - fec_alg_input = prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); - } -#endif /* init (values ar changed after) */ decimatefactor = 4; move16(); @@ -5323,11 +4829,7 @@ void hq_ecu_fx( IF( !( LT_16( output_frame, L_FRAME16k ) ) ) { -#ifdef IVAS_FEC_ECU_TO_COMPLETE - fec_ecu_pitch_fx( fec_alg_input, prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); -#else fec_ecu_pitch_fx( prevsynth + NS2SA_FX2( L_mult0( output_frame, 50 ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); -#endif } ELSE { @@ -5350,32 +4852,6 @@ void hq_ecu_fx( test(); test(); test(); -#if defined IVAS_FEC_ECU_TO_COMPLETE - evs_mode_selection = ( st->total_brate >= 48000 && ( output_frame >= L_FRAME16k && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) && - ( ph_ecu_HqVoicing || ( ( ( hHQ_core->env_stab_plc > 0.5 ) && ( corr < 0.6 ) ) || ( hHQ_core->env_stab_plc < 0.5 && ( corr > 0.85 ) ) ) ) ) ) || - ( st->total_brate < 48000 && ( ( ph_ecu_HqVoicing || corr > 0.85 ) && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) ) ); - - ivas_mode_selection = ( N < PH_ECU_N_LIMIT ) || ( corr < PH_ECU_CORR_LIMIT ); - if ( ( ( st->element_mode == EVS_MONO ) && evs_mode_selection ) || - ( ( st->element_mode != EVS_MONO ) && evs_mode_selection && ivas_mode_selection ) ) - - { - fec_alg_fx( fec_alg_input, prevsynth_LP, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth, &hHQ_core->ni_seed_forfec, st->element_mode, st->hHQ_core->old_out ); - *last_fec = 1; - *ph_ecu_active = 0; - move16(); - *time_offs = output_frame; - move16(); - ; - } - else - { - hq_phase_ecu( prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ), ecu_rec, time_offs, X_sav, num_p, plocs, plocsi, env_stab, last_fec, prev_bfi, old_is_transient, mag_chg_1st, Xavg, beta_mute, st->bwidth, output_frame, corr, st->element_mode ); - - *last_fec = 0; - *ph_ecu_active = 1; - } -#else IF( ( GE_32( st_fx->total_brate, 48000 ) && ( GE_16( output_frame, L_FRAME16k ) && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) && ( NE_16( ph_ecu_HqVoicing, 0 ) || ( ( ( NE_16( st_fx->hHQ_core->env_stab_plc_fx, 0 ) ) && ( LT_16( corr, 19661 ) ) ) || ( !( NE_16( st_fx->hHQ_core->env_stab_plc_fx, 0 ) ) && ( GT_16( corr, 27853 ) ) ) ) ) ) ) || ( LT_32( st_fx->total_brate, 48000 ) && ( ( ph_ecu_HqVoicing || GT_16( corr, 27853 ) ) && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) ) ) ) @@ -5395,7 +4871,6 @@ void hq_ecu_fx( env_stab, last_fec, ph_ecu_active, prev_bfi, old_is_transient, mag_chg_1st, Xavg, beta_mute, st_fx->bwidth, output_frame ); } -#endif return; } diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index e820f1399..4b2cf0213 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -740,15 +740,6 @@ static void CorrectF0( Word16 tmp; -#ifdef IVAS_CODE - FOR( i = 0; i < MAX_PEAKS_FROM_PITCH - 1; i++ ) - { - diff[i] = 0; - sortedDiff[i] = 0; - move16)); - move16)); - } -#endif F0 = *pF0; /*Q10*/ test(); diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 0fbedff60..3570ce86d 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1287,12 +1287,7 @@ ivas_error acelp_core_dec_fx( /*Noise estimate*/ IF( NE_16( st_fx->element_mode, IVAS_CPE_TD ) /* && !st->cng_ism_flag IVAS_CODE */ ) { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - PMT( "Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done" ) - ApplyFdCng_fx( syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, ( EQ_16( st_fx->coder_type, AUDIO ) && st_fx->GSC_noisy_speech == 0 ) ); -#endif } /* CNA: Generate additional comfort noise to mask potential coding artefacts */ } diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index c1c1e6143..971af2b56 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -813,15 +813,10 @@ ivas_error amr_wb_dec_fx( st_fx->VAD = 0; move16(); } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - PMT( "Fixed point not done here " ) - ApplyFdCng_fx( syn, NULL, NULL, NULL, st, 0, 0 ); -#else #ifdef REMOVE_EVS_DUPLICATES ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 ); #else ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, NULL, NULL, st_fx, 0, 0 ); -#endif #endif st_fx->hFdCngDec->hFdCngCom->frame_type_previous = st_fx->m_frame_type; move16(); diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 967a93bfb..86d8e805a 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -20,18 +20,7 @@ void open_decoder_LPD_fx( Decoder_State *st, const Word32 total_brate, /* Q0 */ -#ifdef NEW_IVAS_OPEN_DEC - const Word32 last_total_brate, -#endif const Word16 bwidth /* Q0 */ -#ifdef NEW_IVAS_OPEN_DEC - , - const Word16 is_mct, /* i : MCT mode flag */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - const Word16 last_element_mode, -#endif - const Word16 is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ -#endif ) { Word16 i; @@ -50,10 +39,8 @@ void open_decoder_LPD_fx( hTcxLtpDec = st->hTcxLtpDec; hTcxDec = st->hTcxDec; -#ifndef NEW_IVAS_OPEN_DEC st->total_brate = total_brate; move32(); -#endif if ( NE_16( st->codec_mode, MODE1 ) ) /*already updated in MODE1*/ { @@ -70,40 +57,18 @@ void open_decoder_LPD_fx( /* initializing variables for frame lengths etc. right in the beginning */ st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); move16(); -#ifndef NEW_IVAS_OPEN_DEC hTcxDec->L_frameTCX = extract_l( Mult_32_16( st->output_Fs, 0x0290 ) ); move16(); -#endif IF( st->ini_frame == 0 ) { st->last_L_frame = st->L_frame_past = st->L_frame; move16(); move16(); -#ifndef NEW_IVAS_OPEN_DEC st->L_frameTCX_past = hTcxDec->L_frameTCX; -#endif move16(); } -#ifdef NEW_IVAS_OPEN_DEC - IF( st->hTcxDec != NULL ) - { - hTcxDec->L_frameTCX = extract_l( Mult_32_16( st->output_Fs, 0x0290 ) ); - IF( st->ini_frame == 0 ) - { - st->L_frameTCX_past = st->hTcxDec->L_frameTCX; - move16(); - } - } -#endif st->tcxonly = getTcxonly( -#ifdef IVAS_CODE_SWITCHING - st->element_mode, -#endif st->total_brate -#ifdef IVAS_CODE_SWITCHING - , - is_mct -#endif /*, st->is_ism_format Needed in the last version of float IVAS */ ); move16(); @@ -155,9 +120,6 @@ void open_decoder_LPD_fx( // st->pit_res_max = initPitchLagParameters(12800, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max); // hTcxDec->pit_max_TCX = (int16_t)(st->pit_max * st->output_Fs / 12800); // hTcxDec->pit_min_TCX = (int16_t)(st->pit_min * st->output_Fs / 12800); -#if 0 - PMT("Fixed point to be verified here") -#endif i = mult_r( hTcxDec->L_frameTCX, getInvFrameLen( L_FRAME ) ); /* Q6 */ hTcxDec->pit_max_TCX = extract_l( L_shr( L_mult( st->pit_max, i ), 7 ) ); /* Q0 */ move16(); @@ -243,7 +205,6 @@ void open_decoder_LPD_fx( } /*TCX config*/ -#ifndef NEW_IVAS_OPEN_DEC st->hTcxCfg->preemph_fac = st->preemph_fac; move16(); st->hTcxCfg->tcx_mdct_window_length_old = st->hTcxCfg->tcx_mdct_window_length; @@ -304,34 +265,6 @@ void open_decoder_LPD_fx( } resetTecDec_Fx( st->hTECDec ); - -#else - if ( st->hIGFDec != NULL ) - { - PMT( "To be done" ) - // IF (!is_init || st->element_mode != IVAS_CPE_MDCT) - //{ - // init_tcx_cfg(st->hTcxCfg, total_brate, st->sr_core, st->output_Fs, st->L_frame, st->bwidth, st->hTcxDec->L_frameTCX, st->fscale, encoderLookahead, encoderLookaheadFB, st->preemph_fac, st->tcxonly, st->rf_flag, st->igf, st->hIGFDec->infoIGFStopFreq, st->element_mode, st->ini_frame, MCT_flag); - // } - // else - //{ - // st->hTcxCfg->tcx_curr_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; - // st->hTcxCfg->last_aldo = 1; - // } - } - /*Constraint for adaptive BPF, otherwise parameter estimation and post-processing not time aligned*/ - IF( st->tcxonly == 0 ) - { - assert( 0 == ( st->hTcxCfg->lfacNext > 0 ? st->hTcxCfg->lfacNext : 0 ) ); - } - // IF (st->tecDec_fx != NULL) - { - resetTecDec_Fx( &( st->tecDec_fx ) ); - } - -#endif - - /* Initialize decoder delay */ @@ -447,7 +380,6 @@ void open_decoder_LPD_fx( move16(); /*PLC*/ -#ifndef NEW_IVAS_OPEN_DEC IF( st->prev_bfi != 0 ) { PWord16 const *w; @@ -498,10 +430,6 @@ void open_decoder_LPD_fx( hTcxDec->Q_syn_Overl_TDAC = hHQ_core->Q_old_wtda_LB; move16(); } -#else - PMT( "acelp_plc_mdct_transition is missing" ) - // acelp_plc_mdct_transition(st); -#endif } test(); @@ -545,9 +473,6 @@ void open_decoder_LPD_fx( set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ /* Q_syn_Overl_TDAC */ set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ /* Q_syn_Overl_TDACFB */ set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ /* Q_syn_Overl */ -#if 0 - PMT("to be moved to reset_tcx_overl_buf") -#endif } IF( st->hTcxCfg != NULL ) { @@ -575,15 +500,6 @@ void open_decoder_LPD_fx( cldfb_reset_memory( st->cldfbAna ); cldfb_reset_memory( st->cldfbBPF ); cldfb_reset_memory( st->cldfbSyn ); -#ifndef NEW_IVAS_OPEN_DEC -#if 0 - PMT("cldfbSynHB is missing ") -#endif - // IF (st->cldfbSynHB != NULL) - //{ - // cldfb_reset_memory(st->cldfbSynHB); - // } -#endif } ELSE IF( ( NE_16( st->L_frame, st->last_L_frame ) ) && ( LE_16( st->L_frame, L_FRAME16k ) ) && ( LE_16( st->last_L_frame, L_FRAME16k ) ) ) /* Rate switching between 12.8 and 16 kHz*/ { @@ -817,10 +733,6 @@ void open_decoder_LPD_fx( test(); IF( EQ_16( st->core, ACELP_CORE ) && EQ_16( st->last_core, HQ_CORE ) ) { - /*_DIFF_FLOAT_FIX_*/ -#if 0 - PMT("floating point is using L_frameTCX instead of output_frame, is it ok?") -#endif frame_ener_fx( st->output_frame_fx, UNVOICED_CLAS, st->previoussynth_fx, -1, &st->enr_old_fx, 1, 0, 0, 0 ); } } @@ -840,20 +752,6 @@ void open_decoder_LPD_fx( move16(); if ( st->hTcxDec != NULL ) { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - /* Todo: should be considered for other stereo modes as well */ - IF( is_init || MCT_flag || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) - { - PMT( "Fixed point to be done" ) - st->hTcxDec->CngLevelBackgroundTrace_bfi = PLC_MIN_CNG_LEV; - st->hTcxDec->NoiseLevelIndex_bfi = PLC_MIN_STAT_BUFF_SIZE - 1; - st->hTcxDec->CurrLevelIndex_bfi = 0; - st->hTcxDec->LastFrameLevel_bfi = PLC_MIN_CNG_LEV; - set_f( st->hTcxDec->NoiseLevelMemory_bfi, PLC_MIN_CNG_LEV, PLC_MIN_STAT_BUFF_SIZE ); - - st->hTcxDec->cummulative_damping_tcx = 1.0f; - } -#else hTcxDec->conCngLevelBackgroundTrace = PLC_MIN_CNG_LEV_Q21; /*Q21*/ move16(); hTcxDec->conNoiseLevelIndex = PLC_MIN_STAT_BUFF_SIZE - 1; /* Q0 */ @@ -871,7 +769,6 @@ void open_decoder_LPD_fx( hTcxDec->cummulative_damping_tcx = 32767 /*1.0f Q15*/; move16(); -#endif } st->cummulative_damping = 32767 /*1.0f Q15*/; move16(); @@ -891,10 +788,8 @@ void open_decoder_LPD_fx( st->old_fpitch = L_deposit_h( st->pit_min ); move32(); -#ifndef NEW_IVAS_OPEN_DEC st->old_fpitchFB = L_deposit_h( hTcxDec->pit_min_TCX ); move32(); -#endif st->rate_switching_init = 1; move16(); @@ -924,9 +819,6 @@ void open_decoder_LPD_fx( test(); IF( hTcxLtpDec != NULL && ( EQ_16( st->ini_frame, 0 ) || ( EQ_16( st->last_codec_mode, MODE1 ) && st->element_mode == EVS_MONO ) ) ) { -#if 0 - PMT("TO be verify, update seems to differ from float") -#endif hTcxLtpDec->tcxltp_pitch_int = st->pit_max; /* Q0 */ move16(); hTcxLtpDec->tcxltp_pitch_fr = 0; /* Q0 */ @@ -1059,12 +951,6 @@ void open_decoder_LPD_fx( move16(); st->second_last_core = -1; move16(); -#ifdef NEW_IVAS_OPEN_DEC - IF( st->hTcxCfg != NULL && st->element_mode != EVS_MONO ) - { - st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( is_init ? total_brate : st->bits_frame_nominal * FRAMES_PER_SEC, st->igf ); - } -#endif IF( hTcxDec != NULL ) { hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; /*15Q16*/ @@ -1105,10 +991,8 @@ void open_decoder_LPD_fx( hTcxDec->tcx_hm_LtpPitchLag = -1; move16(); } -#ifndef NEW_IVAS_OPEN_DEC st->hTcxCfg->na_scale = 32767 /*1.0f Q15*/; move16(); -#endif if ( hTcxLtpDec != NULL ) { hTcxLtpDec->tcxltp_gain = 0; /* Q15 */ diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index 63c35f876..8c68f39ce 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -13,18 +13,7 @@ void mode_switch_decoder_LPD_fx( Decoder_State *st, /* i/o: decoder state structure */ Word16 bwidth, /* i : audio bandwidth Q0*/ Word32 total_brate, /* i : total bitrate Q0*/ -#ifdef IVAS_CODE_SWITCHING - const Word32 last_total_brate, /* i : last frame total bitrate */ -#endif Word16 frame_size_index /* i : index determining the frame size Q0*/ -#ifdef IVAS_CODE_SWITCHING - , - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - , - const Word16 last_element_mode -#endif -#endif ) { Word16 fscale, switchWB; @@ -100,15 +89,7 @@ void mode_switch_decoder_LPD_fx( test(); IF( NE_16( fscale, st->fscale ) || ( switchWB != 0 ) || ( bSwitchFromAmrwbIO != 0 ) || EQ_16( st->last_codec_mode, MODE1 ) || st->force_lpd_reset ) { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - open_decoder_LPD_fx( st, total_brate, last_total_brate, bwidth, MCT_flag, last_element_mode, 0 ); -#else -#ifdef IVAS_CODE - open_decoder_LPD_fx( st, total_brate, last_total_brate, bwidth, is_mct, 0 ); -#else open_decoder_LPD_fx( st, total_brate, bwidth ); -#endif -#endif } ELSE { @@ -153,9 +134,6 @@ void mode_switch_decoder_LPD_fx( IF( ( st->hTcxCfg->fIsTNSAllowed != 0 ) && st->hIGFDec != NULL ) { InitTnsConfigs( bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFDec->infoIGFStopFreq, total_brate, st->element_mode, 0 /* 0 should be replaced with MCT_flag*/ ); -#ifdef IVAS_CODE - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); -#endif } } } diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index f53234ded..c04ee9dc5 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -574,11 +574,7 @@ void decoder_LPD_fx( IF( bfi != 0 && ( st->last_core != ACELP_CORE ) ) { /* PLC: [TCX: TD PLC] */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - con_tcx_fx( st, &synthFB[0], -1.f, NULL, 0, NULL ); -#else con_tcx_fx( st, &synthFB[0] ); -#endif lerp( synthFB, synth, st->L_frame, hTcxDec->L_frameTCX ); st->con_tcx = 1; move16(); @@ -778,11 +774,7 @@ void decoder_LPD_fx( { TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX ); } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - decoder_tcx_post_fx( st, synth, synthFB, Aq, bfi, 0 ); -#else decoder_tcx_post_fx( st, synth, synthFB, Aq, bfi ); -#endif IF( EQ_16( st->core, TCX_20_CORE ) ) { /* LPC Interpolation for BWE/post-processing */ diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index 16f749156..55d3ebbae 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -537,15 +537,8 @@ void decoder_acelp_fx( gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); #else prep_tbe_exc_fx( st->L_frame, -#ifdef ADD_IVAS_TBE_CODE - L_SUBFR, -#endif i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate -#ifdef ADD_IVAS_TBE_CODE - , - st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 -#endif ); #endif } diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c index 04a41ed46..21bf7cf12 100644 --- a/lib_dec/dec_acelp_tcx_main_fx.c +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -208,11 +208,7 @@ static void decode_frame_type_fx( Decoder_State *st ) move16(); /* Reconf Core */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - mode_switch_decoder_LPD_fx( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode ); -#else mode_switch_decoder_LPD_fx( st, st->bwidth, st->total_brate, frame_size_index ); -#endif /* Reconf CLDFB */ IF( NE_16( i_mult( st->cldfbAna->no_channels, st->cldfbAna->no_col ), st->L_frame ) ) { diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index af80ee1f5..883024002 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -893,9 +893,6 @@ void decoder_tcx_fx( TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, &x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - concealment_noise, -#endif infoIGFStartLine ); } } diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index e804d2009..1a8a8b30d 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -126,10 +126,6 @@ void con_tcx_fx( const Word16 coh, /* i : coherence of stereo signal Q14*/ Word16 *noise_seed, /* i/o: noise seed for stereo Q0*/ const Word16 only_left /* i : TD-PLC only in left channel Q0*/ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - , - const float *A_cng /* i : CNG LP filter coefficients Q14*/ -#endif #endif ) @@ -489,19 +485,7 @@ void con_tcx_fx( move16(); /* PLC: calculate damping factor */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/ -#endif IF( EQ_16( st->nbLostCmpt, 1 ) ) { st->cummulative_damping = 32767 /*1.f Q15*/; @@ -568,19 +552,7 @@ void con_tcx_fx( } set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/ /* PLC: calculate damping factor */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/ -#endif } /*-----------------------------------------------------------------* @@ -707,20 +679,9 @@ void con_tcx_fx( } /* PLC: [TCX: Fade-out] retrieve background level */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - if ( A_cng != NULL ) - { - gainSynthDeemph = getLevelSynDeemph_fx( &( tmp ), A_cng, L_frame / 4, st->preemph_fac, 1 ) / 4.f; - } - else - { - gainSynthDeemph = getLevelSynDeemph_fx( &( tmp ), A_local, L_frame / 4, st->preemph_fac, 1 ); - } -#else tmp16 = 32767; move16(); gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q5*/ -#endif IF( st->tcxonly != 0 ) { /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */ @@ -728,19 +689,6 @@ void con_tcx_fx( hTcxDec->conCngLevelBackgroundTrace_e, gainSynthDeemph, gainSynthDeemph_e, &gainCNG, &gainCNG_e ); -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - if ( st->element_mode == IVAS_CPE_MDCT && A_cng != NULL ) - { - if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) - { - gainCNG = 0.f; - } - else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) - { - gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; - } - } -#endif } ELSE { @@ -907,34 +855,6 @@ void con_tcx_fx( /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/ /*buf[0;M] Q0: mem_syn*/ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - if ( A_cng != NULL ) - { - float alpha_delayed; - - alpha_delayed = 1.0f; - if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE ) - { - alpha_delayed = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); - } - - if ( st->plcBackgroundNoiseUpdated && alpha_delayed != 1.0f ) - { - float lsp_local[M], lsp_fade[M], alpha_inv; - - alpha_inv = 1.0f - alpha_delayed; - - a2lsp_stab( A_local, lsp_local, lsp_local ); - - for ( i = 0; i < M; i++ ) - { - lsp_fade[i] = alpha_delayed * lsp_local[i] + alpha_inv * st->lspold_cng[i]; - } - - lsp2a_stab( lsp_fade, A_local, M ); - } - } -#endif E_UTIL_synthesis( sub( Q_exc, Q_syn ), A_local, @@ -1434,19 +1354,7 @@ void con_tcx_ivas_fx( move16(); /* PLC: calculate damping factor */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/ -#endif IF( EQ_16( st->nbLostCmpt, 1 ) ) { st->cummulative_damping = 32767 /*1.f Q15*/; @@ -1513,19 +1421,7 @@ void con_tcx_ivas_fx( } set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/ /* PLC: calculate damping factor */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/ -#endif } /*-----------------------------------------------------------------* @@ -1666,7 +1562,6 @@ void con_tcx_ivas_fx( } /* PLC: [TCX: Fade-out] retrieve background level */ -#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT tmp16 = 32767; move16(); IF( A_cng != NULL ) @@ -1677,11 +1572,6 @@ void con_tcx_ivas_fx( { gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q13*/ } -#else - tmp16 = 32767; - move16(); - gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); -#endif IF( st->tcxonly != 0 ) { /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */ @@ -1689,7 +1579,6 @@ void con_tcx_ivas_fx( hTcxDec->conCngLevelBackgroundTrace_e, gainSynthDeemph, gainSynthDeemph_e, &gainCNG, &gainCNG_e ); -#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT test(); IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && A_cng != NULL ) { @@ -1705,7 +1594,6 @@ void con_tcx_ivas_fx( gainCNG = extract_l( Mpy_32_32( gainCNG, L_tmp ) ); /*Q15-gainCNG_e*/ } } -#endif } ELSE { @@ -1882,7 +1770,6 @@ void con_tcx_ivas_fx( /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/ /*buf[0;M] Q0: mem_syn*/ -#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT IF( A_cng != NULL ) { Word16 alpha_delayed; @@ -1914,7 +1801,6 @@ void con_tcx_ivas_fx( E_LPC_f_lsp_a_conversion( lsp_fade, A_local, M ); } } -#endif E_UTIL_synthesis( sub( Q_exc, Q_syn ), diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 090409b4c..c0281c7e3 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -957,14 +957,10 @@ ivas_error evs_dec_fx( } st_fx->lp_noise = hFdCngDec->lp_noise; /*Q9.23*/ move32(); -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); -#else #ifdef REMOVE_EVS_DUPLICATES ApplyFdCng_ivas_fx( output_sp, 0, NULL, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); #else ApplyFdCng_fx( output_sp, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0 ); -#endif #endif /* Generate additional comfort noise to mask potential coding artefacts */ test(); diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 47a61a26e..893b49241 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -559,9 +559,6 @@ void deleteFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec ) Word16 ApplyFdCng_fx( Word16 *timeDomainInput, /* i : pointer to time domain input Q*/ Word16 Q, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - Word16 *powerSpectrum, -#endif Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer cldfbBufferScale*/ Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer cldfbBufferScale*/ Word16 *cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */ @@ -588,16 +585,6 @@ Word16 ApplyFdCng_fx( move16(); move16(); #endif -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - int16_t L_frame, last_L_frame; - int32_t sr_core; - - PMT( "Fix point code missing for IVAS_CODE_CNG_FIX185_PLC_FADEOUT" ) - /* limit L_frame and core fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */ - L_frame = min( st->L_frame, L_FRAME16k ); - last_L_frame = min( st->last_L_frame, L_FRAME16k ); - sr_core = min( st->sr_core, INT_FS_16k ); -#endif hFdCngDec = st->hFdCngDec; hFdCngCom = hFdCngDec->hFdCngCom; @@ -636,27 +623,6 @@ Word16 ApplyFdCng_fx( /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ /* set noise estimation inactive during concealment, no update with noise generated by concealment should be performed. */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - if ( concealWholeFrame == 0 && - ( timeDomainInput == NULL || - ( *timeDomainInput( -FLT_MAX ) && - *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX && - *( timeDomainInput + hFdCngCom->frameSize - 1 ) > ( -FLT_MAX ) ) ) && - ( ( ( ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && hFdCngDec->flag_dtx_mode ) || !st->VAD ) && - !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) || - ( st->element_mode == IVAS_CPE_TD ) ) && - ( !st->BER_detect ) ) -#else test(); test(); test(); @@ -671,14 +637,9 @@ Word16 ApplyFdCng_fx( IF( ( concealWholeFrame == 0 ) && ( LT_16( *timeDomainInput, MAXVAL_WORD16 ) ) && GT_16( *timeDomainInput, MINVAL_WORD16 ) && ( LT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MAXVAL_WORD16 ) ) && GT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MINVAL_WORD16 ) && ( ( ( hFdCngDec->flag_dtx_mode == 0 ) && ( st->VAD != 0 ) ) == 0 ) && ( ( ( st->cng_type == LP_CNG ) && ( hFdCngDec->flag_dtx_mode != 0 ) ) == 0 ) && ( is_music == 0 ) && ( st->BER_detect == 0 ) ) -#endif { /* Perform noise estimation at the decoder */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - perform_noise_estimation_dec_fx( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); -#else perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); -#endif /* Update the shaping parameters */ test(); @@ -790,16 +751,6 @@ Word16 ApplyFdCng_fx( move16(); } } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL ) - { - st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); - } - else - { - st->hTcxDec->CngLevelBackgroundTrace_bfi = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); - } -#endif /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); L_tmp = L_deposit_h( 0 ); @@ -840,11 +791,8 @@ Word16 ApplyFdCng_fx( IF( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - perform_noise_estimation_dec_fx( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); -#else perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); -#endif + } } test(); @@ -860,58 +808,11 @@ Word16 ApplyFdCng_fx( IF( EQ_16( concealWholeFrame, 1 ) && EQ_16( st->nbLostCmpt, 1 ) && ( GT_32( L_shl_o( L_tmp, L_tmp_exp, &Overflow ), 21474836 ) /*0.01f Q31*/ ) ) { /* update isf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ -#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 ); E_LPC_a_lsp_conversion( hFdCngCom->A_cng, lsp_cng, st->lspold_cng, M ); Copy( lsp_cng, st->lspold_cng, M ); /*Q15*/ lsp2lsf_fx( lsp_cng, st->lsf_cng, M, st->sr_core ); -#else - if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) - { - float scf[SNS_NPTS]; - float scf_int[FDNS_NPTS]; - float whitenend_noise_shape[L_FRAME16k]; - int16_t inc, start_idx, stop_idx; - float *noiseLevelPtr; - - - inc = ( st->core > TCX_20 ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = L_frame / inc; - noiseLevelPtr = cngNoiseLevel; - - set_zero( whitenend_noise_shape, start_idx ); - for ( j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) - { - whitenend_noise_shape[j] = *noiseLevelPtr; - } - if ( st->core == TCX_20_CORE ) - { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX20; - } - else - { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX10; - } - - sns_compute_scf( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, L_frame, scf ); - sns_interpolate_scalefactors( scf_int, scf, ENC ); - sns_interpolate_scalefactors( st->hTonalMDCTConc->scaleFactorsBackground_flt, scf, DEC ); - sns_shape_spectrum( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, scf_int, L_frame ); - - mvr2r( whitenend_noise_shape + start_idx, cngNoiseLevel, stop_idx - start_idx ); - wmops_sub_end(); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); - a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); - } - -#endif st->plcBackgroundNoiseUpdated = 1; move16(); } @@ -929,11 +830,7 @@ Word16 ApplyFdCng_fx( IF( st != NULL && st->cng_type == LP_CNG ) { /* Perform noise estimation on inactive phase at the decoder */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - perform_noise_estimation_dec_fx( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); -#else perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); -#endif /* Update the shaping parameters */ test(); @@ -947,9 +844,6 @@ Word16 ApplyFdCng_fx( Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it Q31 - hFdCngDec->bandNoiseShape_exp*/ *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; move16(); -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); -#else /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); L_tmp = L_deposit_h( 0 ); @@ -985,7 +879,6 @@ Word16 ApplyFdCng_fx( move16(); st->cngTDLevel_e = L_tmp_exp; move16(); -#endif BREAK; } hFdCngCom->inactive_frame_counter = add( hFdCngCom->inactive_frame_counter, 1 ); @@ -1903,9 +1796,6 @@ Word16 ApplyFdCng_ivas_fx( void perform_noise_estimation_dec_fx( const Word16 *timeDomainInput, /* i: pointer to time domain input Q*/ const Word16 Q, -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - float *power_spectrum, -#endif HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ ) { @@ -1936,53 +1826,11 @@ void perform_noise_estimation_dec_fx( move16(); /* Perform STFT analysis */ -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - IF( !( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL ) ) - { - /* Perform STFT analysis */ - AnalysisSTFT( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom ); - } -#else /* Perform STFT analysis */ AnalysisSTFT( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom ); -#endif fftBuffer_exp = add( fftBuffer_exp, WORD16_BITS - 1 ); { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) - { - /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */ - periodog = power_spectrum; - } - else - { - /* Compute the squared magnitude in each FFT bin */ - if ( startBand == 0 ) - { - ( *ptr_per ) = fftBuffer[0] * fftBuffer[0]; /* DC component */ - ptr_per++; - ptr_r = fftBuffer + 2; - } - else - { - ptr_r = fftBuffer + 2 * startBand; - } - - ptr_i = ptr_r + 1; - - for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ ) - { - ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i ); - ptr_r += 2; - ptr_i += 2; - } - /* Nyquist frequency is discarded */ - - /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ - v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand ); - } -#else assert( startBand != 0 ); len = sub( stopFFTbin, startBand ); @@ -2062,7 +1910,6 @@ void perform_noise_estimation_dec_fx( } hFdCngDec->hFdCngCom->periodog_exp = add( hFdCngDec->hFdCngCom->periodog_exp, sub( 2, s ) ); move16(); -#endif /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */ bandcombinepow( periodog, hFdCngDec->hFdCngCom->periodog_exp, sub( stopFFTbin, startBand ), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp ); diff --git a/lib_dec/gs_dec_amr_wb_fx.c b/lib_dec/gs_dec_amr_wb_fx.c index 65e9eaa87..331142a44 100644 --- a/lib_dec/gs_dec_amr_wb_fx.c +++ b/lib_dec/gs_dec_amr_wb_fx.c @@ -24,9 +24,6 @@ #define NORMALIZE_SPECS_Q_OUT 6 #define ENER_FX_Q_GUARD 1 -#ifdef ADD_IVAS_GS_DEC_IMPR -#define CONTR_LIMIT 3012 to be verified for fixed point /* Threshold to allow an increase in the contribution length */ -#endif /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -35,10 +32,6 @@ static void Ener_per_band_fx( const Word16 exc_diff_fx[], const Word16 exc_diff_ static void Apply_gain_fx( Word16 exc_diffQ_fx[], Word32 L_Ener_per_bd_iQ[], Word32 L_Ener_per_bd_yQ[], const Word16 Q_out ); static void normalize_spec_fx( Word16 fac_up_fx, Word16 fy_norm_fx[], const Word16 L_frame, const Word16 Q_out ); static void gs_dec_amr_wb_fx( const long core_brate, Word16 *seed_tcx, const Word16 dct_in_fx[], const Word16 Q_dct_in, Word16 dct_out_fx[], Word16 Q_dct_out, const Word16 pitch_fx[], const Word16 voice_fac, const Word16 clas, const Word16 coder_type -#ifdef ADD_IVAS_GS_DEC_IMPR - , - const Word16 VeryLowRateSTflag -#endif ); /*-------------------------------------------------------------------* @@ -223,10 +216,6 @@ static void gs_dec_amr_wb_fx( const Word16 voice_fac, /* i : gain pitch Q15*/ const Word16 clas, /* i : signal frame class Q0*/ const Word16 coder_type /* i : coder type Q0*/ -#ifdef ADD_IVAS_GS_DEC_IMPR - , - const Word16 VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ -#endif ) { Word16 i, mDiff_len; @@ -280,13 +269,7 @@ static void gs_dec_amr_wb_fx( temp = Invert16( temp, &exp ); /* Q15 */ L_temp = L_mult( temp, 12800 ); /* Q15 */ L_temp = L_shl( L_temp, sub( 3, exp ) ); /* *8.0f */ /* Q15 */ -#ifdef ADD_IVAS_GS_DEC_IMPR - test(); - test(); - IF( L_temp <= CONTR_LIMIT && ( VeryLowRateSTflag || GE_32( core_brate, ACELP_12k65 ) ) ) -#else if ( GE_32( core_brate, ACELP_12k65 ) ) -#endif { L_temp = L_shl( L_temp, 1 ); /* Q16 */ } @@ -311,16 +294,6 @@ static void gs_dec_amr_wb_fx( mDiff_len = s_max( round_fx( L_temp ), BIN_1k2 ); /* Q0 */ -#ifdef ADD_IVAS_GS_DEC_IMPR - IF( ( VeryLowRateSTflag && ( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, AUDIO_CLAS ) ) ) ) /* Do not apply normalization on VOICED signal in case of stereo */ - { - Copy( dct_in_fx, exc_diffQ, L_FRAME ); - - /* normalization of the spectrum and noise fill */ - normalize_spec_fx( 1 * 256, exc_diffQ + mDiff_len, sub( L_FRAME, mDiff_len ), NORMALIZE_SPECS_Q_OUT ); - } - ELSE -#endif { Copy( dct_in_fx, exc_diffQ_fx, mDiff_len ); /* Q_dct_in */ set16_fx( exc_diffQ_fx + mDiff_len, 0, sub( L_FRAME, mDiff_len ) ); @@ -387,10 +360,6 @@ void improv_amr_wb_gs_fx( const Word16 Last_ener_fx, /* i : Last energy (Q8) Q0*/ const Word16 rate_switching_reset, /* i : rate switching reset flag Q0*/ const Word16 last_coder_type /* i : Last coder_type Q0*/ -#ifdef ADD_IVAS_GS_DEC_IMPR - , - const Word16 VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ -#endif ) { Word16 i, exp_a, exp_b, exp_diff, j; @@ -413,18 +382,10 @@ void improv_amr_wb_gs_fx( test(); test(); test(); -#ifdef ADD_IVAS_GS_DEC_IMPR - IF( VeryLowRateSTflag || - ( ( locattack == 0 && LE_32( core_brate, ACELP_12k65 ) ) && - ( ( LT_32( core_brate, ACELP_8k85 ) && NE_16( clas, AUDIO_CLAS ) && - ( EQ_16( clas, UNVOICED_CLAS ) || EQ_16( clas, VOICED_TRANSITION ) ) ) || - EQ_16( coder_type, INACTIVE ) ) ) ) -#else IF( ( locattack == 0 && LE_32( core_brate, ACELP_12k65 ) ) && ( ( LT_32( core_brate, ACELP_8k85 ) && NE_16( clas, AUDIO_CLAS ) && ( ( clas == UNVOICED_CLAS ) || EQ_16( clas, VOICED_TRANSITION ) ) ) || ( EQ_16( coder_type, INACTIVE ) ) ) ) -#endif { /*------------------------------------------------------------* * two differents paths: @@ -495,10 +456,6 @@ void improv_amr_wb_gs_fx( *------------------------------------------------------------*/ edct_16fx( exc2_fx, dct_exc_in_fx, L_FRAME, 6, EVS_MONO ); gs_dec_amr_wb_fx( core_brate, seed_tcx, dct_exc_in_fx, Q_exc2, dct_exc_out_fx, Q_exc2, pitch_buf_fx, lt_voice_fac_fx, clas, coder_type -#ifdef ADD_IVAS_GS_DEC_IMPR - , - VeryLowRateSTflag -#endif ); edct_16fx( dct_exc_out_fx, exc2_fx, L_FRAME, 6, EVS_MONO ); diff --git a/lib_dec/hq_classifier_dec_fx.c b/lib_dec/hq_classifier_dec_fx.c index 5ff5dec58..c8dac0a0b 100644 --- a/lib_dec/hq_classifier_dec_fx.c +++ b/lib_dec/hq_classifier_dec_fx.c @@ -99,17 +99,11 @@ Word16 hq_classifier_dec_fx( /* o : Consumed bits max_brate = HQ_48k; /* Q0 */ move32(); } -#ifndef SOLVED_COMP_ENC_DEC test(); test(); test(); test(); IF( ( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_FRAME48k ) ) && LE_32( core_brate, max_brate ) ) -#else - /*_DIFF_FLOAT_FIX_ -> could this modification break the interoperability with EVS ?? */ - test(); - IF( ( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_SPEC48k ) ) && LE_32( core_brate, max_brate ) ) -#endif { *hqswb_clas = get_next_indice( st_fx, 2 ); /* Q0 */ move16(); @@ -147,11 +141,7 @@ Word16 hq_classifier_dec_fx( /* o : Consumed bits *hqswb_clas = HQ_GEN_SWB; /* Q0 */ move16(); } -#ifndef SOLVED_COMP_ENC_DEC ELSE IF( EQ_16( length, L_FRAME48k ) ) -#else - ELSE IF( EQ_16( length, L_SPEC48k ) ) -#endif { *hqswb_clas = HQ_GEN_FB; /* Q0 */ move16(); diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index 4d1ef6774..3c2cd5a80 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -78,22 +78,10 @@ void hq_core_dec_fx( /*num_bits = (short)(st->total_brate / 50); */ Mpy_32_16_ss( st_fx->total_brate, 5243, &L_tmp, &lsb ); /* 5243 is 1/50 in Q18. (0+18-15=3) */ num_bits = extract_l( L_shr( L_tmp, 3 ) ); /*Q0 */ - -#ifdef ADD_IVAS_HQ_CODE_L_SPEC - /* Set default spectrum length */ - L_spec = l_spec_tbl[st_fx->bwidth]; -#endif IF( !st_fx->bfi ) { IF( EQ_16( core_switching_flag, 1 ) ) { -#ifdef ADD_IVAS_HQ_CODE_L_SPEC - IF( NE_16( st_fx->element_mode, EVS_MONO ) ) - { - L_spec = l_spec_ext_tbl[st_fx->bwidth]; - } - ELSE -#endif { core_switching_hq_prepare_dec_fx( st_fx, &num_bits, output_frame ); @@ -105,12 +93,6 @@ void hq_core_dec_fx( } } } -#ifdef ADD_IVAS_HQ_CODE - IF( hq_recovery_flag ) - { - acelp_plc_mdct_transition( st ); - } -#endif /* subtract signalling bits */ num_bits = sub( num_bits, st_fx->next_bit_pos ); /* Q0 */ @@ -145,9 +127,7 @@ void hq_core_dec_fx( /* set inner frame (== coded bandwidth) length */ inner_frame = inner_frame_tbl[st_fx->bwidth]; /* Q0 */ move16(); -#ifndef ADD_IVAS_HQ_CODE_L_SPEC L_spec = inner_frame; /* Q0 */ -#endif move16(); IF( st_fx->bfi == 0 ) @@ -233,12 +213,6 @@ void hq_core_dec_fx( move16(); } -#ifdef ADD_IVAS_HQ_CODE - test(); - test(); - test(); - IF( EQ_16( st_fx->element_mode, EVS_MONO ) || ( !core_switching_flag && !hq_recovery_flag ) ) -#endif { /* scaling (coefficients are in nominal level) */ IF( NE_16( output_frame, NORM_MDCT_FACTOR ) ) @@ -322,59 +296,6 @@ void hq_core_dec_fx( * Overlap-add * Pre-echo reduction *--------------------------------------------------------------------------*/ -#ifdef ADD_IVAS_HQ_CODE - if ( st->element_mode > EVS_MONO && ( core_switching_flag || hq_recovery_flag ) ) - { - /* Initializations for TCX MDCT framework, to be used for switching frame */ - tcx_cfg = st->hTcxCfg; - L_frameTCX_glob = hTcxDec->L_frameTCX; - L_frame_glob = st->L_frame; - L_spec = hTcxDec->L_frameTCX; - st->fscale = sr2fscale( st->sr_core ); - fscaleFB = sr2fscale( st->output_Fs ); - encoderLookahead = ( L_LOOK_12k8 * st->fscale ) / FSCALE_DENOM; - encoderLookaheadFB = ( L_LOOK_12k8 * fscaleFB ) / FSCALE_DENOM; - mdctWindowLength = getMdctWindowLength( st->fscale ); - mdctWindowLengthFB = (int16_t) ( mdctWindowLength * st->output_Fs / st->sr_core ); - if ( core_switching_flag ) - { - tcx_cfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; - tcx_cfg->tcx_curr_overlap_mode = FULL_OVERLAP; - } - else - { - tcx_cfg->tcx_last_overlap_mode = ALDO_WINDOW; - tcx_cfg->tcx_curr_overlap_mode = ALDO_WINDOW; - st->last_core = HQ_CORE; /* Needed to decode non-transition frame */ - } - - init_tcx_window_cfg( tcx_cfg, st->sr_core, st->output_Fs, st->L_frame, hTcxDec->L_frameTCX, encoderLookahead, encoderLookaheadFB, mdctWindowLength, mdctWindowLengthFB, st->element_mode ); - - init_tcx_info( st, L_frame_glob, L_frameTCX_glob, 0, st->bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); - - overlap = tcx_cfg->tcx_mdct_window_length; - overlapFB = tcx_cfg->tcx_mdct_window_lengthFB; - index = tcx_cfg->tcx_last_overlap_mode; - - /* LB synthesis */ - IMDCT_fx( t_audio_q, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, wtda_audio, tcx_cfg->tcx_aldo_window_1_trunc, tcx_cfg->tcx_aldo_window_2, tcx_cfg->tcx_mdct_window_half, tcx_cfg->tcx_mdct_window_minimum, tcx_cfg->tcx_mdct_window_trans, tcx_cfg->tcx_mdct_window_half_length, tcx_cfg->tcx_mdct_window_min_length, index, - MDCT_IV, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, 0, st->bfi, hHQ_core->old_outLB, 0, st, 0, acelp_zir ); - - mvr2r( wtda_audio + ( overlap >> 1 ) - tcx_offset, output, L_frame_glob ); - - /* FB synthesis */ - IMDCT_fx( t_audio_q, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, wtda_audio, tcx_cfg->tcx_aldo_window_1_FB_trunc, tcx_cfg->tcx_aldo_window_2_FB, tcx_cfg->tcx_mdct_window_halfFB, tcx_cfg->tcx_mdct_window_minimumFB, tcx_cfg->tcx_mdct_window_transFB, tcx_cfg->tcx_mdct_window_half_lengthFB, tcx_cfg->tcx_mdct_window_min_lengthFB, index, - MDCT_IV, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, 0, st->bfi, hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); - - mvr2r( wtda_audio + ( overlapFB >> 1 ) - tcx_offsetFB, synth, L_frameTCX_glob ); - - if ( !core_switching_flag ) - { - st->last_core = ACELP_CORE; /* Restore last core */ - } - } - else -#endif { test(); IF( EQ_16( output_frame, L_FRAME8k ) || st_fx->bfi == 0 ) @@ -392,24 +313,6 @@ void hq_core_dec_fx( move16(); } } -#ifdef ADD_IVAS_HQ_CODE - if ( st->element_mode > EVS_MONO ) - { - if ( st->bfi ) - { - /* Rough resampling, but reduces energy loss in case of switch to ACELP in first good frame */ - lerp( t_audio_q, wtda_audio_LB, st->L_frame, inner_frame ); - v_multc( t_audio_q, 0.5f, wtda_audio_LB, st->L_frame ); - } - else - { - /* LB synthesis for potential switch to ACELP */ - ener_match = (float) sqrt( (float) st->L_frame / (float) output_frame ); - v_multc( t_audio_q, ener_match, t_audio_q, inner_frame ); - inverse_transform( t_audio_q, wtda_audio_LB, is_transient, st->L_frame, inner_frame, st->element_mode ); - } - } -#endif IF( EQ_16( output_frame, L_FRAME8k ) ) { test(); @@ -465,13 +368,6 @@ void hq_core_dec_fx( window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx ); } -#ifdef ADD_IVAS_HQ_CODE - if ( st->element_mode > EVS_MONO ) - { - /* LB synthesis for potential switch to ACELP */ - window_ola( wtda_audio_LB, output, hHQ_core->old_outLB, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, st->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth ); - } -#endif test(); test(); IF( ( st_fx->bfi == 0 && st_fx->prev_bfi == 0 ) || !( GE_16( output_frame, L_FRAME16k ) ) ) @@ -561,13 +457,6 @@ void hq_core_dec_fx( Copy( &st_fx->mem_pitch_gain[2], &st_fx->mem_pitch_gain[nbsubfr + 2], nbsubfr ); /* Q14 */ set16_fx( &st_fx->mem_pitch_gain[2], 0, nbsubfr ); } -#ifdef ADD_IVAS_HQ_CODE - /* Move LB excitation to old_exc memory in case of switch HQ->ACELP */ - if ( st->element_mode > EVS_MONO ) - { - mvr2r( output, st->old_exc + L_EXC_MEM_DEC - st->L_frame, st->L_frame ); - } -#endif return; } diff --git a/lib_dec/hq_hr_dec_fx.c b/lib_dec/hq_hr_dec_fx.c index 89864bc3b..6423015bc 100644 --- a/lib_dec/hq_hr_dec_fx.c +++ b/lib_dec/hq_hr_dec_fx.c @@ -46,7 +46,6 @@ void ivas_hq_pred_hb_bws_fx( } ELSE { - // EVS_FUNC_MODIFIED st_fx->prev_ener_shb_fx = 0; move16(); L_tmp = L_deposit_l( 0 ); diff --git a/lib_dec/ivas_output_config_fx.c b/lib_dec/ivas_output_config_fx.c index 3a0960960..17999496e 100644 --- a/lib_dec/ivas_output_config_fx.c +++ b/lib_dec/ivas_output_config_fx.c @@ -239,16 +239,6 @@ void ivas_renderer_select( move16(); } -#if 0 // def DEBUGGING /*temp disabling this as paramMC crashes with CREND*/ - IF ( st_ivas->hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) - { - *renderer_type = RENDERER_BINAURAL_MIXER_CONV; - } - ELSE IF ( st_ivas->hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) - { - *renderer_type = RENDERER_BINAURAL_FASTCONV; - } -#endif test(); IF( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { diff --git a/lib_dec/tns_base_dec_fx.c b/lib_dec/tns_base_dec_fx.c index 13f6ca461..def1ffefb 100644 --- a/lib_dec/tns_base_dec_fx.c +++ b/lib_dec/tns_base_dec_fx.c @@ -26,11 +26,8 @@ typedef Word32 ( *TLinearPredictionFilter )( Word16 order, Word16 const parCoeff * * *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE -void -#else + Word16 -#endif ReadTnsData( STnsConfig const *pTnsConfig, Decoder_State *st, @@ -47,20 +44,6 @@ ReadTnsData( IF( GT_16( pTnsConfig->nMaxFilters, 1 ) ) { -#ifdef IVAS_CODE - IF( pTnsConfig->allowTnsOnWhite ) - { - IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) - { - ReadFromBitstream( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, st, &stream, pnSize ); - } - ELSE - { - ReadFromBitstream( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, st, &stream, pnSize ); - } - } - ELSE -#endif { IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) @@ -81,19 +64,10 @@ ReadTnsData( move16(); *pnBits = sub( st->next_bit_pos, start_bit_pos ); - -#ifdef IVAS_CODE - return; -#else return TNS_NO_ERROR; -#endif } -#define IVAS_CODE -#ifdef IVAS_CODE + void -#else -Word16 -#endif ReadTnsData_ivas_fx( STnsConfig const *pTnsConfig, Decoder_State *st, @@ -109,7 +83,6 @@ ReadTnsData_ivas_fx( IF( GT_16( pTnsConfig->nMaxFilters, 1 ) ) { -#ifdef IVAS_CODE IF( pTnsConfig->allowTnsOnWhite ) { IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) @@ -122,7 +95,6 @@ ReadTnsData_ivas_fx( } } ELSE -#endif { IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) @@ -143,13 +115,9 @@ ReadTnsData_ivas_fx( move16(); *pnBits = sub( st->next_bit_pos, start_bit_pos ); -#ifdef IVAS_CODE return; -#else - return TNS_NO_ERROR; -#endif } -#undef IVAS_CODE + /*---------------------------------------------------------------------* * DecodeTnsData() * @@ -169,21 +137,6 @@ Word16 DecodeTnsData( IF( GT_16( pTnsConfig->nMaxFilters, 1 ) ) { - -#ifdef IVAS_CODE - IF( pTnsConfig->allowTnsOnWhite ) - { - IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) - { - SetParameters( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, pTnsData, &stream, pnSize ); - } - ELSE - { - SetParameters( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, pTnsData, &stream, pnSize ); - } - } - ELSE -#endif { IF( LT_16( pTnsConfig->iFilterBorders[0], 512 ) ) { diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index bc7e1d536..7465a7f65 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -103,18 +103,6 @@ ivas_error TonalMDCTConceal_Init( hTonalMDCTConc->nScaleFactors = nScaleFactors; move16(); -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - PMTE() - set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS ); - PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 ); - PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 ); - hTonalMDCTConc->psychParams = NULL; - hTonalMDCTConc->scf_fadeout = 1.0f; - hTonalMDCTConc->last_block_nrg = 0.0f; - hTonalMDCTConc->curr_noise_nrg = 0.0f; - hTonalMDCTConc->faded_signal_nrg = 0.0f; - -#endif /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when new time samples are stored in lastPcmOut */ move16(); @@ -198,9 +186,6 @@ ivas_error TonalMDCTConceal_Init_ivas_fx( hTonalMDCTConc->nScaleFactors = nScaleFactors; move16(); - //#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - // PMTE() - // To be uncommented when field of fixed type is added for scaleFactorsBackground set32_fx( hTonalMDCTConc->scaleFactorsBackground_fx, 0, FDNS_NPTS ); hTonalMDCTConc->scf_fadeout = 16384 /*1.000000 Q14*/; PsychoacousticParameters_Init_fx( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 ); @@ -243,10 +228,6 @@ void TonalMDCTConceal_SaveFreqSignal( const Word16 *scaleFactors, // Q31-scaleFactors_exp const Word16 *scaleFactors_exp, const Word16 gain_tcx_exp -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - , - const int16_t infoIGFStartLine -#endif ) { Word16 *temp; @@ -340,20 +321,6 @@ void TonalMDCTConceal_SaveFreqSignal( test(); IF( ( nNewSamples > 0 ) && ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) ) { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - int16_t i; - PMTE() - hTonalMDCTConc->last_block_nrg_flt = 0.0f; - for ( i = 0; i < infoIGFStartLine; i++ ) - { - hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i]; - hTonalMDCTConc->last_block_nrg_flt += mdctSpectrum[i] * mdctSpectrum[i]; - } - for ( ; i < nNewSamples; i++ ) - { - hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i]; - } -#else /* Store new data */ s = getScaleFactor32( mdctSpectrum, nNewSamples ); @@ -375,7 +342,6 @@ void TonalMDCTConceal_SaveFreqSignal( move16(); } hTonalMDCTConc->lastBlockData.spectralData_exp = sub( mdctSpectrum_exp, s ); -#endif move16(); hTonalMDCTConc->lastBlockData.gain_tcx_exp = gain_tcx_exp; @@ -2207,19 +2173,12 @@ void TonalMDCTConceal_InsertNoise( Word16 *pSeed, /*IN/OUT*/ const Word16 tiltCompFactor, // Q15 Word16 crossfadeGain, // Q15 -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - const Word16concealment_noise[L_FRAME48k], - const float cngLevelBackgroundTrace_bfi, -#endif const Word16 crossOverFreq ) { Word16 i, ld, fac; Word16 rnd, exp, exp_last, exp_noise, inv_samples, inv_exp; Word16 g, tiltFactor, tilt, tmp; Word32 nrgNoiseInLastFrame, nrgWhiteNoise, L_tmp, L_tmp2; -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - float last_block_nrg_correct; -#endif g = sub( 32767 /*1.0f Q15*/, crossfadeGain ); @@ -2230,16 +2189,6 @@ void TonalMDCTConceal_InsertNoise( rnd = *pSeed; move16(); } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - /* based on what is done in tcx_noise_filling() */ - /* always initialize these to avoid compiler warnings */ - tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); - tilt = 1.0f; - nrgNoiseInLastFrame = 0.0f; - nrgWhiteNoise = 0.0f; - hTonalMDCTConc->faded_signal_nrg_flt = 0.0f; - last_block_nrg_correct = 0.0f; -#endif IF( hTonalMDCTConc->lastBlockData.blockIsValid == 0 ) { /* may just become active if the very first frame is lost */ @@ -2247,199 +2196,8 @@ void TonalMDCTConceal_InsertNoise( *mdctSpectrum_exp = SPEC_EXP_DEC; move16(); } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - else if ( concealment_noise != NULL ) - { - if ( !tonalConcealmentActive ) - { - /* if fadeout has not started yet, only apply sign scrambling */ - if ( crossfadeGain == 1.0f ) - { - for ( i = 0; i < crossOverFreq; i++ ) - { - if ( concealment_noise[i] > 0 ) - { - mdctSpectrum[i] = hTonalMDCTConc->lastBlockData.spectralData[i]; - } - else - { - mdctSpectrum[i] = -hTonalMDCTConc->lastBlockData.spectralData[i]; - } - } - - for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) - { - mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; - } - } - /* actual fadeout is done in this case */ - else - { - g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg_flt ); - - for ( i = 0; i < crossOverFreq; i++ ) - { - x = hTonalMDCTConc->lastBlockData.spectralData[i]; - y = concealment_noise[i]; - - if ( y > 0 ) - { - mdctSpectrum[i] = g * y + crossfadeGain * x; - } - else - { - mdctSpectrum[i] = g * y - crossfadeGain * x; - } - - hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[i] * mdctSpectrum[i]; - } - for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) - { - mdctSpectrum[l] = 0.0f; - } - } - } - else - { - assert( hTonalMDCTConc->pTCI->numIndexes > 0 ); - - /* initialize bins of tonal components with zero: basically not - necessary, but currently the whole spectrum is rescaled in - mdct_noiseShaping() and then there would be a processing of - uninitialized values */ - for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) - { - for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) - { - mdctSpectrum[l] = 0; - if ( l < crossOverFreq ) - { - last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l]; - hTonalMDCTConc->curr_noise_nrg_flt -= concealment_noise[l] * concealment_noise[l]; - } - } - } - - /* if fadeout has not started yet, only apply sign scrambling */ - if ( crossfadeGain == 1.0f ) - { - for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) - { - if ( concealment_noise[l] > 0 ) - { - mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; - } - else - { - mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l]; - } - } - for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) - { - for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ ) - { - if ( concealment_noise[l] > 0 ) - { - mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; - } - else - { - mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l]; - } - } - } - - for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ ) - { - if ( concealment_noise[l] > 0 ) - { - mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; - } - else - { - mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l]; - } - } - - for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) - { - mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; - } - } - /* actual fadeout is done in this case */ - else - { - g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg_flt ); - - for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) - { - x = hTonalMDCTConc->lastBlockData.spectralData[l]; - y = concealment_noise[l]; - - if ( y > 0 ) - { - mdctSpectrum[l] = g * y + crossfadeGain * x; - } - else - { - mdctSpectrum[l] = g * y - crossfadeGain * x; - } - hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; - } - for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) - { - for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ ) - { - x = hTonalMDCTConc->lastBlockData.spectralData[l]; - y = concealment_noise[l]; - - if ( y > 0 ) - { - mdctSpectrum[l] = g * y + crossfadeGain * x; - } - else - { - mdctSpectrum[l] = g * y - crossfadeGain * x; - } - hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; - } - } - - for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ ) - { - x = hTonalMDCTConc->lastBlockData.spectralData[l]; - y = concealment_noise[l]; - - if ( y > 0 ) - { - mdctSpectrum[l] = g * y + crossfadeGain * x; - } - else - { - mdctSpectrum[l] = g * y - crossfadeGain * x; - } - hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; - } - - for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) - { - mdctSpectrum[l] = 0.0f; - } - } - } - - if ( hTonalMDCTConc->faded_signal_nrg_flt > 0.0f && hTonalMDCTConc->curr_noise_nrg_flt > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG ) - { - float nrg_corr_factor; - - nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg_flt - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg_flt ); - v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq ); - } - } -#endif ELSE { -#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT L_tmp = 805306368l /*0.375f Q31*/; move32(); inv_exp = 15; @@ -2456,7 +2214,6 @@ void TonalMDCTConceal_InsertNoise( nrgNoiseInLastFrame = L_deposit_h( 0 ); nrgWhiteNoise = L_deposit_h( 0 ); exp_last = exp_noise = 0; -#endif move16(); move16(); IF( !tonalConcealmentActive ) @@ -3576,216 +3333,3 @@ void TonalMdctConceal_whiten_noise_shape_ivas_fx( pop_wmops(); } - - -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT -void TonalMdctConceal_create_concealment_noise( - float concealment_noise[L_FRAME48k], - CPE_DEC_HANDLE hCPE, - const int16_t L_frameTCX, - const int16_t L_frame, - const int16_t idchan, - const int16_t subframe_idx, - const int16_t core, - const int16_t crossfade_gain, - const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) -{ - STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; - TonalMDCTConcealPtr hTonalMDCTConc; - Decoder_State *st; - HANDLE_FD_CNG_COM hFdCngCom; - int16_t *rnd_c, *rnd; - int16_t crossOverFreq, i, save_rnd_c, max_noise_line; - float c, c_inv; - float noise_shape_buffer[L_FRAME48k]; - int16_t inc, start_idx, stop_idx; - float *cngNoiseLevelPtr; - float last_scf; - - wmops_sub_start( "create_conc_noise" ); - - hStereoMdct = hCPE->hStereoMdct; - st = hCPE->hCoreCoder[idchan]; - hTonalMDCTConc = st->hTonalMDCTConc; - hFdCngCom = st->hFdCngDec->hFdCngCom; - rnd = &hStereoMdct->noise_seeds_channels[idchan]; - rnd_c = &hStereoMdct->noise_seed_common; - - /* determine start bin for IGF */ - if ( st->igf == 0 ) - { - if ( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - crossOverFreq = min( L_frameTCX, L_frame ); - } - else - { - crossOverFreq = L_frameTCX; - } - } - else - { - crossOverFreq = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); - } - - /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ - max_noise_line = crossOverFreq; - if ( st->tonal_mdct_plc_active ) - { - max_noise_line = max( max_noise_line, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 ); - } - - /* first lost frame is handled separately */ - if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) - { - *rnd = 1977 + idchan; - /* will be set twice when looping over two channels, but does not matter */ - *rnd_c = 1979; - } - - if ( crossfade_gain == 1.0f ) - { - /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ - for ( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); - concealment_noise[i] = *rnd; - } - - wmops_sub_end(); - - return; - } - - save_rnd_c = *rnd_c; - - c = sqrtf( hStereoMdct->lastCoh ); - c_inv = sqrtf( 1 - hStereoMdct->lastCoh ); - - /* pre-compute the noise shape for later weighting of the noise spectra */ - cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel_flt[0]; - inc = ( st->core > TCX_20_CORE ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = hFdCngCom->stopFFTbin / inc; - - for ( i = 0; i < start_idx; i++ ) - { - noise_shape_buffer[i] = 0.0f; - } - for ( ; i < stop_idx; i++, cngNoiseLevelPtr += inc ) - { - noise_shape_buffer[i] = sqrtf( *( cngNoiseLevelPtr ) ); - } - - last_scf = sqrtf( *( cngNoiseLevelPtr - inc ) ); - - for ( ; i < max_noise_line; i++ ) - { - noise_shape_buffer[i] = last_scf; - } - - /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg_flt = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; - if ( noise_gen_mode == EQUAL_CORES || ( ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1 ) ) ) - { - /* current channel is TCX20 -> generate noise for "full-length" spectrum */ - for ( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); - *rnd_c = own_random( rnd_c ); - - concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i]; - hTonalMDCTConc->curr_noise_nrg_flt += concealment_noise[i] * concealment_noise[i]; - } - } - else /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ - { - /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ - for ( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); - *rnd_c = own_random( rnd_c ); - - concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i]; - hTonalMDCTConc->curr_noise_nrg_flt += concealment_noise[i] * concealment_noise[i]; - - *rnd_c = own_random( rnd_c ); - } - } - if ( st->tonal_mdct_plc_active ) - { - for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) - { - concealment_noise[i] *= 0.0f; - } - } - /* restore common seed - - after finishing the first channel - - after a first subframe if the current channel is TCX10 */ - if ( ( idchan == 0 && ( core == TCX_20 || ( core == TCX_10 && subframe_idx == 1 ) ) ) || ( core == TCX_10 && subframe_idx == 0 ) ) - { - *rnd_c = save_rnd_c; - } - st->seed_tcx_plc = *rnd; - wmops_sub_end(); - - return; -} -void TonalMdctConceal_whiten_noise_shape( - Decoder_State *st, - const int16_t L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) -{ - int16_t inc, start_idx, stop_idx; - float *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; - HANDLE_FD_CNG_COM hFdCngCom; - float whitenend_noise_shape[L_FRAME16k]; - float scfs_int[FDNS_NPTS]; - const PsychoacousticParameters *psychParams; - - push_wmops( "apply_sns_on_noise_shape" ); - - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_flt[0]; - psychParams = st->hTonalMDCTConc->psychParams; - hFdCngCom = st->hFdCngDec->hFdCngCom; - - inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = L_frame / inc; - noiseLevelPtr = hFdCngCom->cngNoiseLevel_flt; - - set_zero( whitenend_noise_shape, start_idx ); - for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) - { - whitenend_noise_shape[j] = *noiseLevelPtr; - } - - if ( whitening_mode == ON_FIRST_LOST_FRAME ) - { - float scf[SNS_NPTS]; - - sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf ); - sns_interpolate_scalefactors( scfs_int, scf, ENC ); - sns_interpolate_scalefactors( scfs_bg, scf, DEC ); - scfs_for_shaping = &scfs_int[0]; - } - else /* whitening_mode == ON_FIRST_GOOD_FRAME */ - { - scfs_for_shaping = &scfs_bg[0]; - } - - if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f ) - { - sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame ); - mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx ); - } - else - { - set_zero( hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx ); - } - - pop_wmops(); -} -#endif diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 0e1b951bb..81046fb19 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -576,23 +576,6 @@ void updt_dec_common_fx( test(); test(); test(); -#ifdef IVAS_CODE - /* Store long-term estimates of stab_fac and log energy diff to estimate env_stab in case of core switch ACELP/TCX->HQ */ - if ( st->element_mode != EVS_MONO ) - { - output_frame = NS2SA( st->output_Fs, FRAME_SIZE_NS ); - log_energy = log2f( ( sum2_f( synth, output_frame ) / output_frame ) + 1.0f ); - log_energy_diff = fabsf( st->log_energy_old - log_energy ); - st->log_energy_old = log_energy; - st->log_energy_diff_lt = ENV_SMOOTH_FAC * log_energy_diff + ( 1.0f - ENV_SMOOTH_FAC ) * st->log_energy_diff_lt; - if ( st->core == HQ_CORE ) - { - st->stab_fac = min( 1, ( STAB_FAC_EST1 + ( STAB_FAC_EST2 * st->hHQ_core->mem_env_delta ) + ( STAB_FAC_EST3 * st->log_energy_diff_lt ) ) ); - st->stab_fac = max( 0, st->stab_fac ); - } - st->stab_fac_smooth_lt = ENV_SMOOTH_FAC * st->stab_fac + ( 1.0f - ENV_SMOOTH_FAC ) * st->stab_fac_smooth_lt; - } -#endif IF( ( ( LE_32( st_fx->core_brate, SID_2k40 ) ) && EQ_16( st_fx->cng_type, FD_CNG ) ) || ( st_fx->tcxonly && EQ_16( st_fx->codec_mode, MODE2 ) ) ) { @@ -964,23 +947,6 @@ void ivas_updt_dec_common_fx( test(); test(); test(); -#ifdef IVAS_CODE - /* Store long-term estimates of stab_fac and log energy diff to estimate env_stab in case of core switch ACELP/TCX->HQ */ - if ( st->element_mode != EVS_MONO ) - { - output_frame = NS2SA( st->output_Fs, FRAME_SIZE_NS ); - log_energy = log2f( ( sum2_f( synth, output_frame ) / output_frame ) + 1.0f ); - log_energy_diff = fabsf( st->log_energy_old - log_energy ); - st->log_energy_old = log_energy; - st->log_energy_diff_lt = ENV_SMOOTH_FAC * log_energy_diff + ( 1.0f - ENV_SMOOTH_FAC ) * st->log_energy_diff_lt; - if ( st->core == HQ_CORE ) - { - st->stab_fac = min( 1, ( STAB_FAC_EST1 + ( STAB_FAC_EST2 * st->hHQ_core->mem_env_delta ) + ( STAB_FAC_EST3 * st->log_energy_diff_lt ) ) ); - st->stab_fac = max( 0, st->stab_fac ); - } - st->stab_fac_smooth_lt = ENV_SMOOTH_FAC * st->stab_fac + ( 1.0f - ENV_SMOOTH_FAC ) * st->stab_fac_smooth_lt; - } -#else IF( st_fx->element_mode != EVS_MONO ) { Word16 q_div = sub( Q31, shl( Qpostd, 1 ) ); @@ -1003,7 +969,6 @@ void ivas_updt_dec_common_fx( st_fx->stab_fac_smooth_lt_fx = extract_h( L_add( L_mult( ENV_SMOOTH_FAC_FX, st_fx->stab_fac_fx ), L_mult( sub( MAX_16, ENV_SMOOTH_FAC_FX ), st_fx->stab_fac_smooth_lt_fx ) ) ); // Q15 } -#endif test(); test(); diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index b031ca528..9dea812a6 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -462,7 +462,6 @@ void CNG_enc_fx( IF( hTdCngEnc->burst_ho_cnt > 0 ) { /**allow_cn_step |= ( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] > 4 * hTdCngEnc->lp_ener_fx ); */ -#if 1 /*allow_cn_step |= (hDtxEnc->first_CNG || st->element_mode == EVS_MONO) && (hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] > lp_ener_thr_scale * hTdCngEnc->lp_ener);*/ /* (hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] > lp_ener_thr_scale * hTdCngEnc->lp_ener); */ L_tmp1 = L_shr( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr], 2 ); @@ -471,10 +470,6 @@ void CNG_enc_fx( L_tmp1 = L_add( L_tmp1, L_shr( hTdCngEnc->lp_ener_fx, 8 ) ); } L_tmp1 = L_sub( L_tmp1, hTdCngEnc->lp_ener_fx ); -#else - L_tmp1 = L_shr( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr], 2 ); - L_tmp1 = L_sub( L_tmp1, hTdCngEnc->lp_ener_fx ); -#endif test(); test(); IF( ( hDtxEnc->first_CNG > 0 || st_fx->element_mode == EVS_MONO ) && L_tmp1 > 0 ) diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 4bb44eae2..c40db6678 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -138,487 +138,7 @@ void HBAutocorrelation_fx( move32(); } } -#ifdef ADD_IVAS_TNS -/*-------------------------------------------------------------------* - * TNSAnalysisStereo() - * - * - *-------------------------------------------------------------------*/ - -#define SIMILAR_TNS_THRESHOLD ( 0.04f ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE ( 3.0f ) - -void TNSAnalysisStereo( - Encoder_State **sts, /* i : encoder state handle */ - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ - const int16_t bWhitenedDomain, /* i : whitened domain flag */ - int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -) -{ - int16_t ch, k, L_spec, L_frame, nSubframes, iFilter; - float *spectrum; - Encoder_State *st = NULL; - TCX_ENC_HANDLE hTcxEnc = NULL; - int16_t individual_decision[NB_DIV]; - float maxPredictionGain = 0.f, meanPredictionGain; - - individual_decision[0] = 0; - individual_decision[1] = 0; - L_spec = -1; - L_frame = -1; - - /* TNS filter analysis, loop over channels */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) - { - continue; - } - - hTcxEnc = st->hTcxEnc; - - nSubframes = ( hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - - for ( k = 0; k < nSubframes; k++ ) - { - /* reset tns on whitened domain flag */ - if ( !bWhitenedDomain ) - { - hTcxEnc->bTnsOnWhithenedSpectra[k] = 0; - hTcxEnc->fUseTns[k] = 0; - } - - if ( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - - spectrum = hTcxEnc->spectrum[k]; - L_frame = hTcxEnc->L_frameTCX; - st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; - L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; - - /*-----------------------------------------------------------* - * Temporal Noise Shaping analysis * - *-----------------------------------------------------------*/ - - if ( hTcxEnc->transform_type[k] == TCX_5 ) - { - /* rearrange LF sub-window lines prior to TNS analysis & filtering */ - tcx5TnsGrouping( L_frame >> 2, L_spec >> 1, spectrum ); - } - - /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */ - ResetTnsData( &hTcxEnc->tnsData[k] ); - if ( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 ) - { - break; - } - - CalculateTnsFilt( st->hTcxCfg->pCurrentTnsConfig, spectrum, &hTcxEnc->tnsData[k], NULL ); - } - } - } - - if ( !mct_on ) - { - /* TNS decision */ - /* if framing differs between channels, keep the filter decision per channel */ - if ( ( sts[0]->hTcxEnc->transform_type[0] != sts[1]->hTcxEnc->transform_type[0] && - sts[0]->hTcxEnc->transform_type[1] != sts[1]->hTcxEnc->transform_type[1] ) || - sts[0]->hTcxCfg->fIsTNSAllowed != sts[1]->hTcxCfg->fIsTNSAllowed ) - { - individual_decision[0] = individual_decision[1] = 1; - } - else if ( bWhitenedDomain ) - { - nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - for ( k = 0; k < nSubframes; k++ ) - { - if ( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] != sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) - { - individual_decision[k] = 1; - } - } - } - - /* framing equal, check for similar filters, if very similar (also indicator for and M signal), - * use at least the same decision, maybe use the same filter - */ - { - int16_t isTCX10; - isTCX10 = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 0 : 1; - - nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - - for ( k = 0; k < nSubframes; k++ ) - { - if ( sts[0]->hTcxCfg->fIsTNSAllowed && individual_decision[k] != 1 && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - float maxPredGain = -1.0f; - sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; - sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; - -#ifdef DEBUGGING - assert( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ); -#endif - for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter[2]; - struct TnsParameters const *pTnsParameters[2]; - pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - -#ifdef DEBUGGING - assert( pTnsParameters[0]->startLineFrequency == pTnsParameters[1]->startLineFrequency ); - assert( pTnsParameters[0]->nSubdivisions == pTnsParameters[1]->nSubdivisions ); -#endif - /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of - * both filters for the decision - */ - meanPredictionGain = ( pFilter[0]->predictionGain + pFilter[1]->predictionGain ) * 0.5f; - maxPredictionGain = max( maxPredictionGain, meanPredictionGain ); - - if ( ( pFilter[0]->predictionGain > pTnsParameters[0]->minPredictionGain ) && ( sts[0]->element_brate < IVAS_80k ) && - ( pFilter[1]->predictionGain > pTnsParameters[1]->minPredictionGain ) && ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - pFilter[0]->predictionGain = pFilter[1]->predictionGain = meanPredictionGain; /* more TNS filter sync at 48kbps */ - } - if ( ( fabs( pFilter[0]->predictionGain - pFilter[1]->predictionGain ) < SIMILAR_TNS_THRESHOLD * meanPredictionGain ) && - ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - float maxAvgSqrCoef = max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); - float meanLtpGain = ( sts[0]->hTcxEnc->tcxltp_gain + sts[1]->hTcxEnc->tcxltp_gain ) * 0.5f; - maxPredGain = max( maxPredGain, meanPredictionGain ); - if ( ( meanPredictionGain > pTnsParameters[0]->minPredictionGain ) || ( maxAvgSqrCoef > pTnsParameters[0]->minAvgSqrCoef ) ) - { - if ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || meanLtpGain < 0.6f ) - { - ++sts[0]->hTcxEnc->tnsData[k].nFilters; - pFilter[0]->filterType = TNS_FILTER_ON; - ++sts[1]->hTcxEnc->tnsData[k].nFilters; - pFilter[1]->filterType = TNS_FILTER_ON; - } - else - { - const float maxEnergyChange = ( GetTCXMaxenergyChange( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ) + GetTCXMaxenergyChange( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ) ) * 0.5f; - - if ( maxEnergyChange >= pTnsParameters[0]->minEnergyChange ) - { - ++sts[0]->hTcxEnc->tnsData[k].nFilters; - pFilter[0]->filterType = TNS_FILTER_ON; - ++sts[1]->hTcxEnc->tnsData[k].nFilters; - pFilter[1]->filterType = TNS_FILTER_ON; - } - else - { - pFilter[0]->filterType = TNS_FILTER_OFF; - pFilter[1]->filterType = TNS_FILTER_OFF; - } - } - } - else if ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - ++sts[0]->hTcxEnc->tnsData[k].nFilters; - ++sts[1]->hTcxEnc->tnsData[k].nFilters; - } - else if ( sts[0]->hTcxEnc->tnsData[k].nFilters != sts[1]->hTcxEnc->tnsData[k].nFilters ) /* sanity check */ - { - assert( 0 ); - } - else - { - pFilter[0]->filterType = TNS_FILTER_OFF; - pFilter[1]->filterType = TNS_FILTER_OFF; - } - if ( ( pFilter[0]->filterType == TNS_FILTER_ON ) && ( pFilter[1]->filterType == TNS_FILTER_ON ) && ( sts[0]->element_brate < IVAS_80k ) ) - { - int16_t tmpIntValue = 0; - int16_t tmpCoeff[TNS_MAX_FILTER_ORDER]; - int16_t i, maxOrder = max( pFilter[0]->order, pFilter[1]->order ); - - set_s( tmpCoeff, 0, TNS_MAX_FILTER_ORDER ); - for ( i = 0; i < maxOrder; i++ ) - { - tmpIntValue = (int16_t) max( tmpIntValue, abs( pFilter[0]->coefIndex[i] - pFilter[1]->coefIndex[i] ) ); - } - if ( tmpIntValue == 1 ) /* the TNS coefficients are sufficiently similar to equalize the two filters */ - { - for ( i = maxOrder - 1; i >= 0; i-- ) - { - tmpCoeff[i] = ( abs( pFilter[0]->coefIndex[i] ) < abs( pFilter[1]->coefIndex[i] ) ? pFilter[0]->coefIndex[i] : pFilter[1]->coefIndex[i] ); - if ( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) ) - { - maxOrder--; - } - else - { - tmpIntValue = 0; - } - } - /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */ - if ( maxOrder > 0 ) - { - for ( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- ) - { - pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i]; - } - - pFilter[0]->order = pFilter[1]->order = maxOrder; - } - } - } - } - else - { - individual_decision[k] = 1; - } - } - - if ( individual_decision[k] == 0 ) - { - sts[0]->hTcxEnc->fUseTns[k] = ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0; - sts[1]->hTcxEnc->fUseTns[k] = ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0; - } - else - { - sts[0]->hTcxEnc->tnsData[k].nFilters = 0; - sts[1]->hTcxEnc->tnsData[k].nFilters = 0; - sts[0]->hTcxEnc->fUseTns[k] = 0; - sts[1]->hTcxEnc->fUseTns[k] = 0; - for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - } - } - - if ( !bWhitenedDomain && individual_decision[k] == 0 && maxPredGain < TNS_GAIN_THRESHOLD_FOR_WHITE && sts[0]->hTcxEnc->transform_type[k] != TCX_5 ) - { - sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - sts[0]->hTcxEnc->tnsData[k].nFilters = 0; - sts[1]->hTcxEnc->tnsData[k].nFilters = 0; - sts[0]->hTcxEnc->fUseTns[k] = 0; - sts[1]->hTcxEnc->fUseTns[k] = 0; - for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter ); - ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); - } - } - maxPredictionGain = max( maxPredictionGain, maxPredGain ); - } - } - } - } - - /* individual decision for each channel */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) - { - continue; - } - - int16_t isTCX10; - isTCX10 = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 0 : 1; - - nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - - for ( k = 0; k < nSubframes; k++ ) - { - if ( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && - ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - float maxPredGain = -1.0f; - - sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; - - for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter; - const struct TnsParameters *pTnsParameters; - pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - maxPredGain = max( maxPredGain, pFilter->predictionGain ); - - if ( ( pFilter->predictionGain > pTnsParameters->minPredictionGain ) || ( pFilter->avgSqrCoef > pTnsParameters->minAvgSqrCoef ) ) - { - if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || sts[ch]->hTcxEnc->tcxltp_gain < 0.6f ) - { - ++sts[ch]->hTcxEnc->tnsData[k].nFilters; - pFilter->filterType = TNS_FILTER_ON; - } - else - { - const float maxEnergyChange = GetTCXMaxenergyChange( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); - - if ( maxEnergyChange >= pTnsParameters->minEnergyChange ) - { - ++sts[ch]->hTcxEnc->tnsData[k].nFilters; - pFilter->filterType = TNS_FILTER_ON; - } - else - { - pFilter->filterType = TNS_FILTER_OFF; - } - } - } - else if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - ++sts[ch]->hTcxEnc->tnsData[k].nFilters; - } - else - { - pFilter->filterType = TNS_FILTER_OFF; - } - } - - sts[ch]->hTcxEnc->fUseTns[k] = ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0; - - if ( !bWhitenedDomain && maxPredGain < TNS_GAIN_THRESHOLD_FOR_WHITE && sts[ch]->hTcxEnc->transform_type[k] != TCX_5 ) - { - sts[ch]->hTcxEnc->fUseTns[k] = 0; - sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - sts[ch]->hTcxEnc->tnsData[k].nFilters = 0; - for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); - sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - } - } - maxPredictionGain = max( maxPredictionGain, maxPredGain ); - } - } - } - - - /* we have the decision, set filter data accordingly */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) - { - continue; - } - - nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - - for ( k = 0; k < nSubframes; k++ ) - { - if ( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; - - for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter; - pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; - switch ( pFilter->filterType ) - { - case TNS_FILTER_OFF: - ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); - break; - case TNS_FILTER_ON_ZERO: - /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */ - ClearTnsFilterCoefficients( pFilter ); - pFilter->order = 1; - break; - } - } - } - } - } - - /* Apply filters, loop over channels */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) - { - continue; - } - - nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - - for ( k = 0; k < nSubframes; k++ ) - { - if ( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */ - sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] && - sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] ) - { - int16_t equalFilterData = ( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters && - sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] == sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] && - sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) - ? 1 - : 0; - if ( equalFilterData ) - { - for ( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) - { - const int16_t *pDataCh0 = (const int16_t *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter]; - const int16_t *pDataCh1 = (const int16_t *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter]; - int16_t i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */ - - while ( ( i >= 0 ) && ( pDataCh0[i] == pDataCh1[i] ) ) - { - i--; - } - if ( i >= 0 ) - { - equalFilterData = 0; - break; - } - } - if ( equalFilterData ) - { - st->hTcxEnc->tnsData[k].nFilters *= -1; /* signals common TNS */ - } - } - } - if ( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; - spectrum = st->hTcxEnc->spectrum[k]; - /* If TNS should be used then get the residual after applying it inplace in the spectrum */ - if ( st->hTcxEnc->fUseTns[k] ) - { - st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; - - ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum, 1 ); - } - - if ( st->hTcxEnc->transform_type[k] == TCX_5 ) - { - tcx5TnsUngrouping( L_frame >> 2, L_spec >> 1, st->hTcxEnc->spectrum[k], ENC ); - } - - st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k]; - - EncodeTnsData( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k ); - } - - if ( st->hTcxEnc->transform_type[k] == TCX_5 ) - { - tcx5SpectrumInterleaving( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum[k] ); - tcx5SpectrumInterleaving( st->hTcxCfg->tcx5SizeFB, mdst_spectrum[ch][k] ); - } - } - } - - return; -} - - -#endif void TNSAnalysis_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 L_frame, /* input: frame length */ @@ -1317,154 +837,6 @@ void ShapeSpectrum_ivas_fx( } } -#ifdef ADD_IVAS_TNS -/*-----------------------------------------------------------* - * EstimateStereoTCXNoiseLevel() - * - * Estimate and quantize stereo noise factors - *-----------------------------------------------------------*/ - -void EstimateStereoTCXNoiseLevel( - Encoder_State **sts, /* i : state handle */ - float *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum */ - float gain_tcx[][NB_DIV], /* i : global gain */ - int16_t L_frame[][NB_DIV], /* i : frame length */ - int16_t noiseFillingBorder[][NB_DIV], /* i : noise filling border */ - int16_t hm_active[][NB_DIV], /* i : flag indicating if the harmonic model is active */ - const int16_t ignore_chan[], /* i : flag indicating whether the channel should be ignored */ - float fac_ns[][NB_DIV], /* o : noise filling level */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - int16_t ch, n; - int16_t nSubframes, maxNfCalcBw, iStart, noiseTransWidth; - float smooth_gain; - float combined_q_spectrum[N_MAX]; - int16_t *fac_ns_q; - int32_t total_brate; - - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - Encoder_State *st = sts[ch]; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - - if ( ignore_chan[ch] ) - { - continue; - } - total_brate = ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? st->element_brate : st->total_brate; - - for ( n = 0; n < nSubframes; n++ ) - { - fac_ns_q = param_core[ch] + n * NPRM_DIV + 1; - maxNfCalcBw = min( noiseFillingBorder[ch][n], (int16_t) ( hTcxEnc->measuredBwRatio * (float) L_frame[ch][n] + 0.5f ) ); - if ( ( total_brate >= HQ_96k && ( st->element_mode <= IVAS_SCE || st->bwidth < SWB ) ) || total_brate > IVAS_192k ) - { - fac_ns[ch][n] = 0.0f; - *fac_ns_q = 0; - } - else - { - iStart = L_frame[ch][n] / ( ( total_brate >= ACELP_13k20 && !st->rf_mode ) ? 6 : 8 ); /* noise filling start bin*/ - - if ( n == 0 ) - { - mvr2r( hTcxEnc->ltpGainMemory, &hTcxEnc->ltpGainMemory[1], N_LTP_GAIN_MEMS - 1 ); - hTcxEnc->ltpGainMemory[0] = st->hTcxEnc->tcxltp_gain; - } - - smooth_gain = dotp( hTcxEnc->ltpGainMemory, nf_tw_smoothing_coeffs, N_LTP_GAIN_MEMS ); - - noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame[ch][n] == st->L_frame >> 1 ), smooth_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active[ch][n] ) ); - - mvr2r( q_spectrum[ch][n], combined_q_spectrum, L_frame[ch][n] ); - tcx_noise_factor( hTcxEnc->spectrum[n], combined_q_spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame[ch][n], gain_tcx[ch][n], hTcxEnc->noiseTiltFactor, &fac_ns[ch][n], fac_ns_q, st->element_mode ); - - /* hysteresis for very tonal passages (more stationary noise filling level) */ - if ( *fac_ns_q == 1 ) - { - hTcxEnc->noiseLevelMemory_cnt = (int16_t) min( INT16_MAX, 1 + abs( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */ - } - else - { - if ( ( *fac_ns_q == 2 ) && ( abs( hTcxEnc->noiseLevelMemory_cnt ) > 5 ) ) - { - *fac_ns_q = 1; /* reduce noise filling level by one step */ - fac_ns[ch][n] = 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL ); - - /* signal that noise level is changed by inverting sign of level memory */ - hTcxEnc->noiseLevelMemory_cnt = ( hTcxEnc->noiseLevelMemory_cnt < 0 ) ? 5 : -1 - hTcxEnc->noiseLevelMemory_cnt; - } - else - { - hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */ - } - } - } /* bitrate */ - } -#ifdef DEBUG_MODE_MDCT - dbgwrite( &smooth_gain, sizeof( float ), 1, 1, "./res/smooth_gain" ); - dbgwrite( &st->hTcxEnc->tcxltp_gain, sizeof( float ), 1, 1, "./res/tcxltp_gain" ); - dbgwrite( &noiseTransWidth, sizeof( int16_t ), 1, 1, "./res/noiseTrans" ); - dbgwrite( &fac_ns[ch][0], sizeof( float ), 2, 1, "./res/fac_ns" ); -#endif - } - - return; -} - - -/*-----------------------------------------------------------* - * DecideTonalSideInfo() - * - * - *-----------------------------------------------------------*/ - -static int16_t DecideTonalSideInfo( - const float spectrum[], - const int16_t L_frame_glob, - float SFM2 ) -{ - float SFM, K, K2; - int16_t Tonal_SideInfo; - - SFM = SFM_Cal( spectrum, min( 200, L_frame_glob ) ); - - if ( L_frame_glob <= 256 ) - { - K = 0.4f; - K2 = 0.1f; - } - else if ( L_frame_glob == 320 || L_frame_glob == 512 ) - { - K = 0.4f; - K2 = 0.1f; - } - else /*FrameSize_Core == 640*/ - { - K = 0.35f; - K2 = 0.04f; - } - - - Tonal_SideInfo = 0; - if ( SFM < K ) - { - Tonal_SideInfo = 1; - } - - if ( SFM2 < K2 ) - { - Tonal_SideInfo = 1; - } - - return Tonal_SideInfo; -} -#endif - /*-------------------------------------------------------------------* * GetTransWidth() * diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 05f838a3a..5c0e4911c 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -53,14 +53,7 @@ void init_coder_ace_plus_fx( /* Bitrate */ st->tcxonly = (Word8) getTcxonly( -#ifdef IVAS_CODE_SWITCHING - st->element_mode, -#endif st->total_brate -#ifdef IVAS_CODE_SWITCHING - , - MCT_flag, st->is_ism_format -#endif ); move16(); diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index 2f21f1015..fb5fd037a 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -49,11 +49,7 @@ void core_coder_mode_switch_fx( switchWB = 1; /*force init when coming from MODE1*/ } -#ifdef IVAS_CODE_SWITCHING - tcxonly_tmp = getTcxonly( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); -#else tcxonly_tmp = getTcxonly( st->total_brate ); -#endif if ( NE_16( tcxonly_tmp, st->tcxonly ) ) { @@ -71,11 +67,7 @@ void core_coder_mode_switch_fx( move32(); st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); assert( st->L_frame == st->sr_core / 50 ); -#ifdef IVAS_CODE_SWITCHING - st->tcxonly = getTcxonly( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); -#else st->tcxonly = (Word8) getTcxonly( st->total_brate ); -#endif /* st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale ) * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f ; */ /* st->bits_frame_nominal = extract_l(L_shr(Mpy_32_16_1( L_shl(st->bitrate,8), mult_r(div_s(st->fscale, shl(st->L_frame,4)), FL2WORD16(FSCALE_DENOM/12800.f))), 6)); */ tmp32 = L_shl( st->total_brate, 1 ); /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate */ @@ -118,9 +110,6 @@ void core_coder_mode_switch_fx( IF( st->hTcxCfg->fIsTNSAllowed != 0 ) { InitTnsConfigs( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); -#ifdef IVAS_CODE - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, EQ_16( st->element_mode, IVAS_CPE_MDCT ) ); -#endif } st->narrowBand = 0; diff --git a/lib_enc/core_enc_updt_fx.c b/lib_enc/core_enc_updt_fx.c index ce2681e75..dcf57738a 100644 --- a/lib_enc/core_enc_updt_fx.c +++ b/lib_enc/core_enc_updt_fx.c @@ -48,20 +48,6 @@ void core_encode_update_fx( Encoder_State *st ) if ( hTcxEnc != NULL ) { Copy( hTcxEnc->buf_speech_ltp + st->L_frame, hTcxEnc->buf_speech_ltp, n ); - -#ifdef IVAS_CODE - IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->hTcxEnc->kernel_switch_corr_past = 0.f; - st->hTcxEnc->kernel_type[0] = MDCT_IV; - st->hTcxEnc->kernel_symmetry_past = 0; - st->hTcxEnc->enc_ste_pre_corr_past = 0; - move16(); - move16(); - move16(); - move16(); - } -#endif } /* Update previous mode */ diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 9180d73b8..f16dd80cb 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -250,13 +250,8 @@ void enc_pit_exc_fx( *----------------------------------------------------------------*/ Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); /* Q_new */ /* condition on target (compared to float) has been put outside the loop */ -#if 1 // ndef BUG_FIX find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); -#else - find_targets_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hLPDmem->mem_w0, p_Aq, /*_DIFF_FLOAT_FIX_ --> Here I think mem_syn_tmp_fx should be used */ - res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); -#endif Copy_Scale_sig( h1, h2, L_subfr, -2 ); /* Q13 */ Scale_sig( h1, L_subfr, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index 396e97c6f..624ec20fc 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -169,18 +169,6 @@ ivas_error evs_enc_fx( { updt_IO_switch_enc_fx( st, input_frame ); set16_fx( hBWE_TD->old_speech_shb_fx, 0, L_LOOK_16k + L_SUBFR16k ); -#if defined IVAS_CODE - PMT( "find scaling factor for prev_enr_EnvSHBres, prev_pow_exc16kWhtnd and prev_mix_factor " ) - set16_fx( st->hBWE_TD->old_speech_shb, 0, L_LOOK_16k + L_SUBFR16k ); - set16_fx( st->hBWE_TD->mem_shb_res, 0, MAX_LEN_MA_FILTER ); - set16_fx( st->hBWE_TD->old_EnvSHBres, 0, L_FRAME4k ); - st->hBWE_TD->old_mean_EnvSHBres = 0; - st->hBWE_TD->prev_enr_EnvSHBres = 1.0f; - st->hBWE_TD->prev_shb_env_tilt = 0; - st->hBWE_TD->prev_pow_exc16kWhtnd = 1.0f; - st->hBWE_TD->prev_mix_factor = 1.0f; - st->hBWE_TD->prev_Env_error = 0; -#endif cldfb_reset_memory( st->cldfbAnaEnc ); cldfb_reset_memory( st->cldfbSynTd ); } @@ -466,16 +454,6 @@ ivas_error evs_enc_fx( { set16_fx( hBWE_TD->old_speech_shb_fx, 0, L_LOOK_16k + L_SUBFR16k ); set16_fx( shb_speech, 0, L_FRAME16k ); -#if defined IVAS_CODE - set_f( st->hBWE_TD->mem_shb_res, 0.0f, MAX_LEN_MA_FILTER ); - set_f( st->hBWE_TD->old_EnvSHBres, 0.0f, L_FRAME4k ); - st->hBWE_TD->old_mean_EnvSHBres = 0.0f; - st->hBWE_TD->prev_enr_EnvSHBres = 1.0f; - st->hBWE_TD->prev_shb_env_tilt = 0.0f; - st->hBWE_TD->prev_pow_exc16kWhtnd = 1.0f; - st->hBWE_TD->prev_mix_factor = 1.0f; - st->hBWE_TD->prev_Env_error = 0.0f; -#endif } /* SWB TBE encoder */ diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index eeeb294b4..49d757be3 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -70,24 +70,12 @@ void core_signal_analysis_high_bitrate_fx( Word32 *tmpP32; Word16 Q_exp; -#ifdef IVAS_CODE - int16_t disable_ltp = 0; -#endif TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; -#ifndef IVAS_CODE /* dummy */ (void) vad_hover_flag; (void) last_element_mode; -#endif -#ifdef IVAS_CODE - if ( NE_16( last_element_mode, st->element_mode ) ) - { - disable_ltp = 1; /* disable TCX-LTP in stereo switching to avoid discontinuities in synthesis */ - move16(); - } -#endif left_overlap = -1; move16(); right_overlap = -1; @@ -300,15 +288,6 @@ void core_signal_analysis_high_bitrate_fx( WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno], overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, tcx20Win, st->element_mode != IVAS_CPE_MDCT /* truncate_aldo */, 1 ); -#ifdef IVAS_CODE - if ( windowed_samples != NULL ) /* save windowed speech_TCX samples */ - { - assert( L_subframe + ( left_overlap + right_overlap ) / 2 < 2 * L_FRAME_MAX / nSubframes - L_FRAME_MAX / 8 ); - windowed_samples[frameno * L_FRAME_MAX + 0] = (float) overlap_mode[frameno]; - windowed_samples[frameno * L_FRAME_MAX + 1] = (float) overlap_mode[frameno + 1]; - mvr2r( tcx20Win, windowed_samples + frameno * L_FRAME_MAX + 2, L_subframe + ( left_overlap + right_overlap ) / 2 ); - } -#endif } IF( EQ_16( transform_type[frameno], TCX_5 ) ) @@ -321,15 +300,6 @@ void core_signal_analysis_high_bitrate_fx( tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // Q0 move16(); } -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_MDCT && frameno == 0 && overlap_mode[0] == FULL_OVERLAP && L_subframe - left_overlap > minWindowLen ) - { - for ( i = minWindowLen; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ - { - tcx20Win[left_overlap + i] -= hTcxEnc->speech_TCX[-1 - i] * st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] * st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i]; - } - } -#endif /* Outter right folding */ tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) @@ -365,13 +335,6 @@ void core_signal_analysis_high_bitrate_fx( tmpP16 += tcx5SizeFB; tmpP32 += tcx5SizeFB; -#ifdef IVAS_CODE - /* high-band gain control in case of BWS */ - if ( st->bwidth_sw_cnt > 0 ) - { - v_multc( hTcxEnc->spectrum[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ), (float) ( st->bwidth_sw_cnt ) / (float) BWS_TRAN_PERIOD, hTcxEnc->spectrum[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ), L_subframe - L_FRAME16k / ( 2 * nSubframes ) ); - } -#endif } } ELSE /* transform_type[frameno] != TCX_5 */ @@ -414,33 +377,12 @@ void core_signal_analysis_high_bitrate_fx( } ELSE { -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_MDCT && frameno == 0 && transform_type[0] == TCX_10 && overlap_mode[0] == FULL_OVERLAP && L_subframe - left_overlap > minWindowLen ) - { - for ( i = minWindowLen; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ - { - tcx20Win[left_overlap + i] -= hTcxEnc->speech_TCX[-1 - i] * st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] * st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i]; - } - } -#endif TCX_MDCT( tcx20Win, spectrum[frameno], &spectrum_e[frameno], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); } /* For TCX20 at bitrates up to 64 kbps we need the power spectrum */ /* high-band gain control in case of BWS */ -#ifdef IVAS_CODE - if ( st->bwidth_sw_cnt > 0 ) - { - v_multc( hTcxEnc->spectrum[frameno] + L_FRAME16k / nSubframes, (float) ( st->bwidth_sw_cnt ) / (float) BWS_TRAN_PERIOD, hTcxEnc->spectrum[frameno] + L_FRAME16k / nSubframes, L_subframe - L_FRAME16k / nSubframes ); - } - - if ( st->mct_chan_mode == MCT_CHAN_MODE_LFE ) - { - set_f( &hTcxEnc->spectrum[frameno][MCT_LFE_MAX_LINE], 0.f, L_subframe - MCT_LFE_MAX_LINE ); - st->hTcxCfg->tcx_coded_lines = MCT_LFE_MAX_LINE; - } -#endif IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { test(); @@ -461,94 +403,6 @@ void core_signal_analysis_high_bitrate_fx( pMdstWin, powerSpec, &powerSpec_e ); } } -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_MDCT ) - { - L_subframe = L_frameTCX / nSubframes; - - if ( transform_type[frameno] == TCX_20 && st->hTcxCfg->tcx_last_overlap_mode != TRANSITION_OVERLAP && st->mct_chan_mode != MCT_CHAN_MODE_LFE ) - { - wtda_ext( hTcxEnc->new_speech_TCX, mdstWin, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX, 3 ); - } - else - { - /* Windowing for the MDST */ - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 ); - } - - if ( transform_type[frameno] == TCX_5 ) - { - /* Outer left folding */ - for ( i = 0; i < left_overlap / 2; i++ ) - { - mdstWin[left_overlap / 2 + i] += mdstWin[left_overlap / 2 - 1 - i]; - } - - if ( frameno == 0 && overlap_mode[0] == FULL_OVERLAP && L_subframe - left_overlap > minWindowLen ) - { - for ( i = minWindowLen; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ - { - mdstWin[left_overlap + i] += hTcxEnc->speech_TCX[-1 - i] * st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] * st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i]; - } - } - - /* Outer right folding */ - for ( i = 0; i < right_overlap / 2; i++ ) - { - mdstWin[L_subframe + left_overlap / 2 - 1 - i] -= mdstWin[L_subframe + left_overlap / 2 + i]; - } - - /* 2xTCX5 */ - L_subframe = tcx5SizeFB; - folding_offset = left_overlap / 2; - - for ( i = 0; i < 2; i++ ) - { - assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); - WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 ); - - TCX_MDST( tcx5Win, mdst_spectrum[frameno] + i * tcx5SizeFB, left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); - /* high-band gain control in case of BWS */ - if ( st->bwidth_sw_cnt > 0 ) - { - v_multc( mdst_spectrum[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ), (float) ( st->bwidth_sw_cnt ) / (float) BWS_TRAN_PERIOD, mdst_spectrum[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ), L_subframe - L_FRAME16k / ( 2 * nSubframes ) ); - } - } - } - else /* transform_type[frameno] != TCX_5 */ - { - if ( transform_type[frameno] == TCX_20 && st->hTcxCfg->tcx_last_overlap_mode != TRANSITION_OVERLAP && st->mct_chan_mode != MCT_CHAN_MODE_LFE ) - { - edst( mdstWin, mdst_spectrum[frameno], L_subframe, st->element_mode ); - - v_multc( mdst_spectrum[frameno], (float) sqrt( (float) NORM_MDCT_FACTOR / L_subframe ), mdst_spectrum[frameno], L_subframe ); - } - else - { - if ( frameno == 0 && transform_type[0] == TCX_10 && overlap_mode[0] == FULL_OVERLAP && L_subframe - left_overlap > minWindowLen ) - { - for ( i = minWindowLen; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ - { - mdstWin[left_overlap + i] += hTcxEnc->speech_TCX[-1 - i] * st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] * st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i]; - } - } - - TCX_MDST( mdstWin, mdst_spectrum[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); - } - - /* high-band gain control in case of BWS */ - if ( st->bwidth_sw_cnt > 0 ) - { - v_multc( mdst_spectrum[frameno] + L_FRAME16k / nSubframes, (float) ( st->bwidth_sw_cnt ) / (float) BWS_TRAN_PERIOD, mdst_spectrum[frameno] + L_FRAME16k / nSubframes, L_subframe - L_FRAME16k / nSubframes ); - } - } - - if ( st->mct_chan_mode == MCT_CHAN_MODE_LFE ) - { - set_f( &mdst_spectrum[frameno][MCT_LFE_MAX_LINE], 0.f, L_subframe - MCT_LFE_MAX_LINE ); - } - } -#endif } IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) @@ -559,9 +413,6 @@ void core_signal_analysis_high_bitrate_fx( st->hTcxCfg->tcx_coded_lines, transform_type[frameno], ( frameno == 0 ) && ( st->last_core == ACELP_CORE ), spectrum[frameno], &hTcxEnc->tnsData[frameno], &hTcxEnc->fUseTns[frameno], NULL ); -#ifdef IVAS_CODE - IF( st->hTcxCfg->fIsTNSAllowed ) -#endif { EncodeTnsData_fx( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frameno], param_core + frameno * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, pTnsSize + frameno, pTnsBits + frameno ); @@ -583,9 +434,6 @@ void core_signal_analysis_high_bitrate_fx( * LPC analysis *---------------------------------------------------------------*/ -#ifdef IVAS_CODE - IF( st->tcxonly ) -#endif { HBAutocorrelation_fx( st->hTcxCfg, lpc_left_overlap_mode, lpc_right_overlap_mode, &st->speech_enc_pe[frameno * tcx10Size], shr( L_frame, sub( nSubframes, 1 ) ), r, M ); diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index 558ae89a7..aa2c319f1 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -194,7 +194,6 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits Word16 *hqswb_clas /* o : HQ class Q0 */ ) { -#ifndef SOLVED_COMP_ENC_DEC Word16 bits; HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; @@ -277,88 +276,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits *hqswb_clas = HQ_GEN_SWB; /* Q0 */ move16(); } -#else - Word16 bits; - HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; - Word32 max_brate; - Word16 harmonic_decision; - - - max_brate = HQ_32k; - move32(); - if ( st_fx->element_mode > EVS_MONO ) - { - max_brate = HQ_48k; - move32(); - } - - *hqswb_clas = HQ_NORMAL; - bits = 1; - move16(); - IF( EQ_16( is_transient, 1 ) ) - { - *hqswb_clas = HQ_TRANSIENT; - move16(); - } - - /* classification and limit bandwidth for bit allocation */ - test(); - IF( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_SPEC48k ) ) - { - IF( LE_32( st_fx->core_brate, max_brate ) ) - { - test(); - IF( !is_transient && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - /* Detect HQ_HARMONIC mode */ - *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); - -#if 0 - harmonic_decision = hf_spectrum_sparseness( st, coefs ); -#else - harmonic_decision = 0; - move16(); -#endif - test(); - IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && !harmonic_decision ) - { - *hqswb_clas = HQ_NORMAL; - move16(); - } - ELSE - { - /* Detect harmonic VQ mode HQ_HVQ */ - hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core, - nf_gains, &hHQ_core->hvq_hangover, pe_gains ); - } - } - bits = 2; - move16(); - } - } - ELSE IF( EQ_16( length, L_SPEC16k_EXT ) || EQ_16( length, L_SPEC48k_EXT ) ) - { - bits = 0; /* HQ_NORMAL only -- no signalling needed */ - move16(); - } - /* write signalling info to the bitstream */ - push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits ); - - IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) ) - { - IF( EQ_16( length, L_SPEC32k ) ) - { - *hqswb_clas = HQ_GEN_SWB; - move16(); - } - ELSE IF( EQ_16( length, L_SPEC48k ) ) - { - *hqswb_clas = HQ_GEN_FB; - move16(); - } - } -#endif return bits; } Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bits Q0 */ @@ -677,11 +595,8 @@ Word16 peak_avrg_ratio_fx( test(); test(); test(); -#ifndef SOLVED_COMP_ENC_DEC /*This affect BE even if it shouldn't*/ + IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && EQ_32( total_brate, HQ_24k40 ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) -#else - if ( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && LT_32( total_brate, HQ_BWE_CROSSOVER_BRATE ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) -#endif { hqswb_clas = HQ_HARMONIC; move16(); @@ -1177,11 +1092,7 @@ void hvq_classifier_fx( L_input_max = L_deposit_l( 0 ); set32_fx( L_thr, 0, L_FRAME16k ); -#ifndef SOLVED_COMP_ENC_DEC IF( EQ_32( L_core_brate, HQ_24k40 ) ) -#else - IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) ) -#endif { nsub = HVQ_NSUB_24k; move16(); @@ -1420,7 +1331,6 @@ void hvq_classifier_fx( num_peak_cands = add( num_peak_cands, 1 ); } } -#ifndef ADD_IVAS_HQ_CODE IF( EQ_32( L_core_brate, HQ_24k40 ) ) { peak_th = HVQ_MAX_PEAKS_24k_CLAS; @@ -1431,9 +1341,6 @@ void hvq_classifier_fx( peak_th = HVQ_MAX_PEAKS_32k; move16(); } -#else - peak_th = (int16_t) ( ( core_brate * HVQ_PEAKS_PER_DELTA_THR + HVQ_PEAKS_PER_DELTA_THR_OFFS ) / HVQ_PEAKS_BPS_DELTA ); -#endif /* Find peaks */ pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); i = 0; @@ -1555,7 +1462,6 @@ void hvq_classifier_fx( move16(); } -#ifndef ADD_IVAS_HQ_CODE IF( EQ_32( L_core_brate, HQ_24k40 ) ) { *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */ @@ -1566,9 +1472,6 @@ void hvq_classifier_fx( *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */ move16(); } -#else - *Npeaks = (int16_t) ( min( ( core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) ); -#endif } ELSE { @@ -1581,99 +1484,3 @@ void hvq_classifier_fx( return; } - -#ifdef ADD_IVAS_HQ_CODE -/*--------------------------------------------------------------------------* - * hf_spectrum_sparseness() - * - * Detection of sparse spectrum in high band for activation of harmonic - * modes HQ_HARMONIC and HQ_HVQ - *--------------------------------------------------------------------------*/ -/*! r: Harmonic decision for high band */ -static int16_t hf_spectrum_sparseness( - Encoder_State *st, /* i/o: encoder state structure */ - const float *coefs /* i : MDCT spectrum */ -) -{ - int16_t i; - float thr; - int16_t low_count; - float A[L_SPEC_HB]; - float Amax; - float movmean; - float inv_rms; - float crest; - float crest_mod; - const float *p_num; - float *crest_lp; - float *crest_mod_lp; - int16_t result; - - crest_lp = &st->hHQ_core->crest_lp; - crest_mod_lp = &st->hHQ_core->crest_mod_lp; - - result = TRUE; - if ( st->element_mode != EVS_MONO ) - { - for ( i = 0; i < L_SPEC_HB; i++ ) - { - A[i] = (float) fabsf( coefs[i + L_SPEC_HB] ); - } - low_count = 0; - inv_rms = 0.0f; - crest_mod = 0.0f; - maximum( A, L_SPEC_HB, &Amax ); - thr = Amax * PEAK_THRESHOLD; - movmean = 0.0f; /* avoid uninitialized warning */ - p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ - for ( i = 0; i < L_SPEC_HB; i++ ) - { - inv_rms += A[i] * A[i]; - if ( A[i] < thr ) - { - low_count += 1; - } - if ( i <= HALF_WIN_LENGTH ) - { - if ( i == 0 ) - { - movmean = sum_f( &A[0], i + HALF_WIN_LENGTH + 1 ) * ( *p_num ); - } - else - { - p_num++; - movmean = movmean + ( A[i + HALF_WIN_LENGTH] - movmean ) * ( *p_num ); - } - } - else - { - if ( L_SPEC_HB <= i + HALF_WIN_LENGTH ) - { - p_num--; - movmean = movmean + ( movmean - A[i - HALF_WIN_LENGTH - 1] ) * ( *p_num ); - } - else - { - movmean = movmean + ( A[i + HALF_WIN_LENGTH] - A[i - HALF_WIN_LENGTH - 1] ) * ( *p_num ); - } - } - if ( crest_mod < movmean ) - { - crest_mod = movmean; - } - } - inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB ); - crest = Amax * inv_rms; - crest_mod = crest_mod * inv_rms; - *crest_lp = HQ_CREST_FAC_SM * ( *crest_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * crest; - *crest_mod_lp = HQ_CREST_FAC_SM * ( *crest_mod_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * crest_mod; - - if ( ( ( *crest_lp ) > HQ_CREST_THRESHOLD ) && ( ( *crest_mod_lp ) > HQ_CREST_MOD_THRESHOLD ) && ( low_count > LOW_COUNT_THRESHOLD ) ) - { - result = FALSE; - } - } - - return result; -} -#endif diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index 66430cb8e..b5e1abbca 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -35,15 +35,6 @@ void hq_core_enc_fx( Word16 tmp; Word32 L_tmp; UWord16 lsb; -#ifdef ADD_IVAS_HQ_CODE_L_SPEC - Word16 L_spec; -#endif -#ifdef ADD_IVAS_HQ_CODE - Word16 left_overlap, right_overlap; - Word16 overlap, nz, tcx_offset, L_frame; - Word16 Aq_old[M + 1]; - Word16 output[L_FRAME16k]; -#endif Word16 two_frames_buffer[2 * L_FRAME48k]; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -87,37 +78,6 @@ void hq_core_enc_fx( is_transient = detect_transient_fx( audio, input_frame, 0, st_fx ); /* Q0 */ -#ifdef ADD_IVAS_HQ_CODE - test(); - test(); - test(); - IF( ( st_fx->element_mode > EVS_MONO ) && ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) - { - /*-------------------------------------------------------------------------- - * IVAS switching frame - *--------------------------------------------------------------------------*/ - - L_spec = input_frame; - left_overlap = -1; - right_overlap = -1; - move16(); - move16(); - move16(); - - WindowSignal( &( st_fx->tcx_cfg ), st_fx->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st_fx->hTcxEnc->speech_TCX, &L_spec, wtda_audio, 1, 1 ); - Q_audio = 16; - move16(); /*tbv inspired from core_enc_ol*/ - TCX_MDCT( wtda_audio, t_audio, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st_fx->element_mode ); - - inner_frame = inner_frame_tbl[st_fx->bwidth]; - L_spec = l_spec_ext_tbl[st_fx->bwidth]; - is_transient = 0; - move16(); - move16(); - move16(); - } - ELSE -#endif { /*-------------------------------------------------------------------------- * Windowing and time-domain aliasing @@ -144,10 +104,8 @@ void hq_core_enc_fx( move16(); } } -#ifndef ADD_IVAS_HQ_CODE /* subtract signalling bits */ num_bits = sub( num_bits, hBstr->nb_bits_tot ); /* Q0 */ -#endif direct_transform_fx( wtda_audio, t_audio, is_transient, input_frame, &Q_audio, st_fx->element_mode ); /* scale coefficients to their nominal level (8kHz) */ @@ -174,10 +132,6 @@ void hq_core_enc_fx( /* limit encoded band-width according to the command-line OR BWD limitation */ inner_frame = inner_frame_tbl[st_fx->bwidth]; /* Q0 */ move16(); -#ifdef ADD_IVAS_HQ_CODE_L_SPEC - L_spec = l_spec_tbl[st_fx->bwidth]; - move16(); -#endif IF( GT_16( input_frame, inner_frame ) ) { IF( EQ_16( is_transient, 1 ) ) @@ -193,31 +147,10 @@ void hq_core_enc_fx( set32_fx( t_audio + inner_frame, 0, sub( input_frame, inner_frame ) ); } } -#ifdef ADD_IVAS_HQ_CODE_L_SPEC - /* subtract signalling bits */ - num_bits = sub( num_bits, hBstr->nb_bits_tot_fx ); -#endif - /*-------------------------------------------------------------------------- * High-band gain control in case of BWS *--------------------------------------------------------------------------*/ -#ifdef ADD_IVAS_HQ_CODE - IF( st_fx->bwidth_sw_cnt > 0 ) - { - IF( is_transient ) - { - FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) - { - v_multc( t_audio + i * inner_frame / NUM_TIME_SWITCHING_BLOCKS + L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS, (float) ( st->bwidth_sw_cnt ) / (float) BWS_TRAN_PERIOD, t_audio + i * inner_frame / NUM_TIME_SWITCHING_BLOCKS + L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS, inner_frame / NUM_TIME_SWITCHING_BLOCKS - L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ); - } - } - ELSE - { - v_multc( t_audio + L_FRAME16k, (float) ( st->bwidth_sw_cnt ) / (float) BWS_TRAN_PERIOD, t_audio + L_FRAME16k, L_spec - L_FRAME16k ); - } - } -#endif /*-------------------------------------------------------------------------- * Classify whether to put extra bits for FER mitigation *--------------------------------------------------------------------------*/ @@ -263,12 +196,7 @@ void hq_core_enc_fx( t_audio[i] = L_shr( t_audio[i], sub( Q_audio, 12 ) ); /* Q12 */ move32(); } - -#ifdef ADD_IVAS_HQ_CODE_L_SPEC - hq_hr_enc_fx( st_fx, t_audio, L_spec, &num_bits, is_transient, vad_hover_flag ); -#else hq_hr_enc_fx( st_fx, t_audio, inner_frame, &num_bits, is_transient, vad_hover_flag ); -#endif Q_audio = 12; move16(); } @@ -286,51 +214,6 @@ void hq_core_enc_fx( { push_indice( hBstr, IND_UNUSED, 0, num_bits ); } -#ifdef ADD_IVAS_HQ_CODE - if ( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) - { - overlap = st->hTcxCfg->tcx_mdct_window_length; - nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS ); - L_frame = (int16_t) ( st->L_frame + st->hTcxCfg->tcx_offset - st->hTcxCfg->lfacNext ); - tcx_offset = st->hTcxCfg->lfacNext; - set_f( Aq_old, 0, M + 1 ); /* Dummy filter */ - Aq_old[0] = 1; - - /* Code taken from InternalTCXDecoder() */ - TCX_MDCT_Inverse( t_audio, wtda_audio, overlap, L_frame - overlap, overlap, st->element_mode ); - - /* Window current frame */ - tcx_windowing_synthesis_current_frame( wtda_audio, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); - - /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ - mvr2r( wtda_audio + L_frame - nz, st->hTcxEnc->old_out, nz + overlap ); - set_zero( st->hTcxEnc->old_out + nz + overlap, nz ); - - tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); - - for ( i = 0; i < nz; i++ ) - { - st->hTcxEnc->old_out[nz + overlap + i] = wtda_audio[L_frame - 1 - i] * st->hTcxCfg->tcx_aldo_window_1_trunc[-1 - i]; - } - mvr2r( wtda_audio + ( overlap >> 1 ) - tcx_offset, output, st->L_frame ); - } - else - { - ener_match = (float) sqrt( (float) L_FRAME16k / (float) NORM_MDCT_FACTOR ); - v_multc( t_audio, ener_match, t_audio, inner_frame ); - - inverse_transform( t_audio, wtda_audio, is_transient, L_FRAME16k, inner_frame, st->element_mode ); - - window_ola( wtda_audio, output, st->hTcxEnc->old_out, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); - } - - if ( st->element_mode > EVS_MONO ) - { - /* Store LB synthesis in case of switch to ACELP */ - mvr2r( output, st->hLPDmem->old_exc, L_FRAME16k ); - } -#endif - return; } diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index 705db9ecd..05654e775 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -249,20 +249,6 @@ void hq_hr_enc_fx( move16(); /* Prepare synthesis for LB generation in case of switch to ACELP */ -#ifdef ADD_IVAS_HQ_CODE - IF( NE_16( hqswb_clas, HQ_HVQ ) ) - { - apply_envelope_enc( t_audio_q, ynrm, num_sfm, sfm_start, sfm_end ); - } - - IF( is_transient ) - { - de_interleave_spectrum( t_audio_q, length ); - } - Copy32( t_audio_q, t_audio, length ); -#endif - - return; } diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 98d7fe957..e80ca0d59 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -20,7 +20,6 @@ * * Initialization of state variables *-----------------------------------------------------------------------*/ -#if 1 ivas_error init_encoder_fx( Encoder_State *st_fx /* i/o: Encoder static variables structure */ ) @@ -946,7 +945,7 @@ ivas_error init_encoder_fx( move32(); return error; } -#endif + /*-----------------------------------------------------------------------* * LPDmem_enc_init_fx() * @@ -1193,10 +1192,8 @@ ivas_error init_encoder_ivas_fx( st->exp_mem_preemph_enc = 0; move16(); -#if 1 // TODO: Float Initializations. To be removed later st->active_cnt = 0; move16(); -#endif st->pst_mem_deemp_err_fx = 0; move16(); @@ -1438,8 +1435,6 @@ ivas_error init_encoder_ivas_fx( st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC st->input_fx = st->input_buff_fx + frame_length; } -#if 1 // TODO: To be removed later -#endif } ELSE { @@ -1454,8 +1449,6 @@ ivas_error init_encoder_ivas_fx( st->buf_speech_enc = NULL; st->buf_wspeech_enc = NULL; st->input_buff_fx = NULL; -#if 1 -#endif } /*-----------------------------------------------------------------* @@ -1956,12 +1949,6 @@ ivas_error init_encoder_ivas_fx( st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; move16(); move16(); -#if 1 - // set_f( st->hTcxEnc->spectrum_long, 0, N_MAX ); - // st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; - // st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; - // set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); -#endif set16_fx( st->hTcxEnc->old_out_fx, 0, L_FRAME32k ); st->hTcxEnc->Q_old_out = 0; diff --git a/lib_enc/ivas_omasa_enc_fx.c b/lib_enc/ivas_omasa_enc_fx.c index f1187bc6c..b5b592582 100644 --- a/lib_enc/ivas_omasa_enc_fx.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -1112,11 +1112,6 @@ static void ivas_omasa_param_est_enc_fx( { q = q_data; move16(); -#if 0 - scale_sig32( hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, hOMasa->cldfbAnaEnc[i]->cldfb_state_length, sub( q, hOMasa->cldfbAnaEnc[i]->Q_cldfb_state ) ); - hOMasa->cldfbAnaEnc[i]->Q_cldfb_state = q; - move16(); -#endif cldfbAnalysis_ts_fx_var_q( &( data[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q ); /*q_data-5*/ norm_buff = s_min( norm_buff, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) ); norm_buff = s_min( norm_buff, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 063f39dea..f90b2d8ec 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -2650,41 +2650,7 @@ static ivas_error sanitizeBandwidth_fx( } } - IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) - { -#if 0 // IVAS_fmToDo: temporary disabled to keep EVS bit-exactness -> to be verified - if (max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < ACELP_16k40) - { - if (hEncoderConfig->ivas_total_brate < ACELP_9k60) - { - max_bwidth_tmp = WB; - } - else - { - max_bwidth_tmp = SWB; - } - } - - if (max_bwidth_tmp == SWB && hEncoderConfig->ivas_total_brate < ACELP_9k60) - { - max_bwidth_tmp = WB; - } - - /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ - if ((max_bwidth_tmp == NB || hEncoderConfig->input_Fs == 8000) && hEncoderConfig->ivas_total_brate > ACELP_24k40) - { - if (hEncoderConfig->input_Fs >= 16000) - { - max_bwidth_tmp = WB; - } - else - { - return IVAS_ERR_INVALID_BITRATE; - } - } -#endif - } - ELSE + IF( NE_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { Word32 quo = 0, rem; move32(); diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index a4e19e040..ea06878c1 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -117,88 +117,15 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision Word32 gain1_tmp = 0, gain2_tmp = 0; Word16 exp, exp1, exp2, exp3; Word32 L_tmp, L_tmp1; -#ifdef IVAS_CODE - Word16 gain2_start, gain3_start, gain4_start, H1_start, H2_start, H_length; - Word16 gain2_start_rs, gain3_start_rs; -#endif TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; #endif test(); -#ifdef IVAS_CODE - IF( EQ_32( st_fx->input_Fs, 32000 ) || EQ_32( st_fx->input_Fs, 48000 ) ) - { - gain2_start = GAIN2_START_SWB; - gain2_start_rs = GAIN2_START_SWB_RS; - gain3_start = GAIN3_START_SWB; - gain3_start_rs = GAIN3_START_SWB_RS; - gain4_start = GAIN4_START_SWB; - // gain4_start_rs = GAIN4_START_SWB_RS; - H1_start = H1_START_SWB; - H2_start = H2_START_SWB; - H_length = H_LENGTH_SWB; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } - ELSE IF( EQ_32( st_fx->input_Fs, 16000 ) ) - { - gain2_start = GAIN2_START_WB; - gain2_start_rs = GAIN2_START_SWB_RS; - gain3_start = GAIN3_START_WB; - gain2_start_rs = GAIN2_START_SWB_RS; - gain4_start = GAIN4_START_WB; - H1_start = H1_START_WB; - H2_start = H2_START_WB; - H_length = H_LENGTH_WB; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } - ELSE - { - assert( !"Unknown sampling frequency in MDCT_classifier" ); - H1_start = -1; /* to avoid compilation warning */ - H2_start = -1; /* to avoid compilation warning */ - H_length = -1; /* to avoid compilation warning */ - gain2_start = -1; /* to avoid compilation warning */ - gain3_start = -1; /* to avoid compilation warning */ - gain4_start = -1; /* to avoid compilation warning */ - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } -#endif -#ifdef IVAS_CODE - if ( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) ) -#endif { dft_mag_square_fx( fft_buff, magSq, 256 ); } -#ifdef IVAS_CODE - ELSE - { - float norm_val; - - norm_val = ( L_FFT * L_FFT ) / 4.f; - for ( k = 0; k < 128; k++ ) - { - X[k + 1] = st->Bin_E_old[k] * norm_val; - } - X[0] = X[1]; - } -#endif nf = L_add( magSq[0], 0 ); pe = L_add( magSq[0], 0 ); np = 0; @@ -295,10 +222,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision gain1 = L_deposit_l( 0 ); gain2 = L_deposit_l( 0 ); gain3 = L_deposit_l( 0 ); -#ifdef IVAS_CODE - PMT( "MDCT_classifier needs review for different sampling rate" ) -#endif - // IVAS_CODE to adapt + FOR( k = 0; k < 8; k++ ) { gain1 = L_add( gain1, L_shr( cldfbBuf_Ener[k], 3 ) ); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 7d5f486cc..acc52c2aa 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -3761,7 +3761,7 @@ Word16 tcx_res_Q_spec_ivas_fx( return bits; } -#if 1 // TV + void ProcessIGF_fx( IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */ Encoder_State *st, /**< in: Encoder state */ @@ -3893,7 +3893,7 @@ void ProcessIGF_fx( } #endif } -#endif + void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) { Word16 i, length, att; diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 2ade624b6..1ad69a330 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -638,16 +638,6 @@ void RunTransientDetection_fx( Word16 const *input, Word16 nSamplesAvailable, Tr /* Update the delay buffer. */ UpdateDelayBuffer( filteredInput, nSamplesAvailable, &pTransientDetection->delayBuffer ); -#ifdef IVAS_CODE - /* compute ramp up flag */ - pSubblockEnergies->ramp_up_flag = ( ( pSubblockEnergies->ramp_up_flag << 1 ) & 0x0003 ); - e0 = dotp( filteredInput + length / 2, filteredInput + length / 2, pSubblockEnergies->pDelayBuffer->nSubblockSize / 2 ) + 0.5f * MIN_BLOCK_ENERGY; - e1 = pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4] - e0; - if ( e1 > e0 ) - { - pSubblockEnergies->ramp_up_flag |= 0x0001; - } -#endif } @@ -1582,72 +1572,7 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp } } } -#ifdef IVAS_CODE -/*-------------------------------------------------------------------* - * set_transient_stereo() - * - * - *-------------------------------------------------------------------*/ - -void set_transient_stereo( - CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - float currFlatness[] /* i/o: current flatness */ -) -{ - int16_t n, attackIsPresent; - float currFlatnessMax; - Encoder_State **sts; - - sts = hCPE->hCoreCoder; - - /* for DFT/TD based stereo ,map avg. flatness to individual stereo channels (M/S or X/Y) */ - maximum( currFlatness, CPE_CHANNELS, &currFlatnessMax ); - attackIsPresent = 0; - - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - attackIsPresent = max( attackIsPresent, sts[n]->hTranDet->transientDetector.bIsAttackPresent ); - } - - set_f( currFlatness, currFlatnessMax, CPE_CHANNELS ); - - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - sts[n]->hTranDet->transientDetector.bIsAttackPresent = attackIsPresent; - } - - if ( hCPE->hStereoDft != NULL ) - { - if ( hCPE->hStereoDft->attackPresent ) - { - hCPE->hStereoDft->wasTransient = 1; - } - else if ( hCPE->hStereoDft->wasTransient ) - { - hCPE->hStereoDft->wasTransient = 0; - } - - hCPE->hStereoDft->attackPresent = attackIsPresent; - hCPE->hStereoDft->hItd->currFlatness = 0; - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - hCPE->hStereoDft->hItd->currFlatness = max( hCPE->hStereoDft->hItd->currFlatness, currFlatness[n] ); - } - } - - if ( hCPE->hStereoMdct != NULL ) - { - hCPE->hStereoMdct->hItd->currFlatness = 0; - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - hCPE->hStereoMdct->hItd->currFlatness = max( hCPE->hStereoMdct->hItd->currFlatness, currFlatness[n] ); - } - } - - return; -} -#endif /*-------------------------------------------------------------------* * transient_analysis() * diff --git a/lib_enc/updt_enc_fx.c b/lib_enc/updt_enc_fx.c index 1210bfd04..aed3bf812 100644 --- a/lib_enc/updt_enc_fx.c +++ b/lib_enc/updt_enc_fx.c @@ -204,20 +204,6 @@ void updt_IO_switch_enc_fx( set16_fx( hBWE_TD->old_speech_wb_fx, 0, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 16 ); set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); set16_fx( hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); -#ifdef IVAS_CODE - set16_fx( st->hBWE_TD->mem_shb_res, 0, MAX_LEN_MA_FILTER ); - set16_fx( st->hBWE_TD->old_EnvSHBres, 0, L_FRAME4k ); - st->hBWE_TD->old_mean_EnvSHBres = 0; - st->hBWE_TD->prev_enr_EnvSHBres = 32767; - st->hBWE_TD->prev_pow_exc16kWhtnd = 32767; - st->hBWE_TD->prev_mix_factor = 32767; - st->hBWE_TD->prev_Env_error = 0; - move16(); - move16(); - move16(); - move16(); - move16(); -#endif hBWE_TD->bwe_non_lin_prev_scale_fx = 0; move16(); set16_fx( hBWE_TD->decim_state1_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); @@ -251,23 +237,6 @@ void updt_IO_switch_enc_fx( st->use_acelp_preq = 0; move16(); -#ifdef IVAS_CODE - set16_fx( st->hSpMusClas->finc_prev, 0, ATT_NSEG ); - set16_fx( st->hSpMusClas->tod_lt_Bin_E, 0, TOD_NSPEC ); - set16_fx( st->hSpMusClas->tod_S_map_lt, 0, TOD_NSPEC ); - st->hSpMusClas->lt_finc = 0; - st->hSpMusClas->last_strong_attack = 0; - st->hSpMusClas->tod_thr_lt = TOD_THR_MASS; - st->hSpMusClas->tod_weight = 0; - st->hSpMusClas->tod_S_mass_prev = TOD_THR_MASS; - st->hSpMusClas->tod_S_mass_lt = TOD_THR_MASS; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); -#endif } ELSE /* switching to AMR-WB IO mode */ { diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 412b8c226..16fefa3bb 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3327,17 +3327,10 @@ static void eig2x2_fx( tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); -#if 1 tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); -#else - /* Note: This code part does not work yet, see pipeline issue for BASOP #1009 */ - /* although the same code works at other places: mantissa and q_format is fine */ - normVal_fx = ISqrt32( tmp3, &exp ); - q_tmp2 = sub( 31, exp ); -#endif IF( LT_16( q_tmp1, q_c ) ) { @@ -3403,17 +3396,10 @@ static void eig2x2_fx( tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); -#if 1 tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); -#else - /* Note: This code part does not work yet, see pipeline issue for BASOP #1009 */ - /* although the same code works at other places: mantissa and q_format is fine */ - normVal_fx = ISqrt32( tmp3, &exp_tmp3 ); - q_tmp2 = sub( 31, exp_tmp3 ); -#endif IF( LT_16( q_tmp1, q_c ) ) { -- GitLab From 6f1ac6e49513f6ba4d675f428489cd8fba35fdc2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 30 Apr 2025 12:01:49 +0530 Subject: [PATCH 1156/1221] Clang formatting changes --- lib_com/bitstream_fx.c | 2 +- lib_com/prot_fx.h | 35 ++- lib_com/swb_tbe_com_fx.c | 428 +++++++++++++++--------------- lib_dec/FEC_HQ_phase_ecu_fx.c | 27 +- lib_dec/core_dec_init_fx.c | 2 +- lib_dec/core_dec_switch_fx.c | 6 +- lib_dec/dec_ace_fx.c | 3 +- lib_dec/er_dec_tcx_fx.c | 10 +- lib_dec/fd_cng_dec_fx.c | 1 - lib_dec/gs_dec_amr_wb_fx.c | 6 +- lib_dec/tns_base_dec_fx.c | 3 +- lib_dec/tonalMDCTconcealment_fx.c | 3 +- lib_enc/core_enc_init_fx.c | 3 +- 13 files changed, 252 insertions(+), 277 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 4fcac20b6..2b66f92cd 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -52,7 +52,7 @@ int16_t FEC_seed = 12558; /* Seed for random FEC generator */ FILE *FEC_pattern = NULL; /* FEC pattern file (for simulation of FEC) */ -float FEC_random = 0; /* FEC rate in percent (for simulation of FEC) */ +float FEC_random = 0; /* FEC rate in percent (for simulation of FEC) */ /*-------------------------------------------------------------------* * file_read_FECpattern() * diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index fde3949fd..f422d5e50 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3061,8 +3061,7 @@ void GenShapedSHBExcitation_fx( Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, - const Word16 prev_bfi -); + const Word16 prev_bfi ); void GenShapedSHBExcitation_ivas_enc_fx( Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ @@ -3137,8 +3136,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, - const Word16 prev_bfi - , /* i : previous frame was concealed */ + const Word16 prev_bfi, /* i : previous frame was concealed */ const Word16 element_mode, /* i : element mode */ const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ @@ -3292,7 +3290,7 @@ void synthesise_fb_high_band_fx( #ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( - const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 L_frame_fx, /* i : length of the frame */ const Word16 i_subfr_fx, /* i : subframe index */ const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ @@ -3326,12 +3324,11 @@ void prep_tbe_exc_ivas_fx( Word16 T0, /* i : integer pitch variables Q0 */ Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ - Word32 core_brate - , /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ + Word32 core_brate, /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ ); Word16 swb_formant_fac_fx( /* o : Formant filter strength [0,1] */ @@ -6539,8 +6536,7 @@ void TonalMDCTConceal_SaveFreqSignal( Word16 nNewSamplesCore, const Word16 *scaleFactors, const Word16 *scaleFactors_exp, - const Word16 gain_tcx_exp -); + const Word16 gain_tcx_exp ); void TonalMDCTConceal_SaveFreqSignal_ivas_fx( TonalMDCTConcealPtr hTonalMDCTConc, @@ -8389,7 +8385,7 @@ ivas_error ppp_quarter_decoder_fx( void open_decoder_LPD_fx( Decoder_State *st, const Word32 total_brate, /* Q0 */ - const Word16 bwidth /* Q0 */ + const Word16 bwidth /* Q0 */ ); void open_decoder_LPD_ivas_fx( Decoder_State *st, /* i/o: decoder state structure */ @@ -8951,12 +8947,11 @@ ReadTnsData( STnsConfig const *pTnsConfig, Word16 *stream, Word16 *pnSize ); -void -ReadTnsData_ivas_fx( STnsConfig const *pTnsConfig, - Decoder_State *st, - Word16 *pnBits, - Word16 *stream, - Word16 *pnSize ); +void ReadTnsData_ivas_fx( STnsConfig const *pTnsConfig, + Decoder_State *st, + Word16 *pnBits, + Word16 *stream, + Word16 *pnSize ); Word16 DecodeTnsData( STnsConfig const *pTnsConfig, Word16 const *stream, diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index d1883efde..c4605393d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -2102,8 +2102,7 @@ void GenShapedSHBExcitation_fx( Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, - const Word16 prev_bfi -) + const Word16 prev_bfi ) { Word16 i, j, k; Word16 wht_fil_mem[LPC_WHTN_ORDER]; @@ -2366,258 +2365,257 @@ void GenShapedSHBExcitation_fx( } } ELSE /* decoder side */ - { { - /* *vf_ind is an integer scale by 0.125f*/ - tmp = shl( *vf_ind, ( 15 - 3 ) ); - tmp2 = MAX_16; - move16(); - if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) - { - tmp2 = 26214 /*0.8f Q15*/; - move16(); - } - } - } + { /* *vf_ind is an integer scale by 0.125f*/ + tmp = shl( *vf_ind, ( 15 - 3 ) ); + tmp2 = MAX_16; + move16(); + if ( LE_16( tmp, 22938 /*0.7f Q15*/ ) ) { - voice_factors[0] = mult_r( voice_factors[0], tmp2 ); - move16(); - voice_factors[1] = mult_r( voice_factors[1], tmp2 ); - move16(); - voice_factors[2] = mult_r( voice_factors[2], tmp2 ); - move16(); - voice_factors[3] = mult_r( voice_factors[3], tmp2 ); - move16(); - voice_factors[4] = mult_r( voice_factors[4], tmp2 ); + tmp2 = 26214 /*0.8f Q15*/; move16(); } } +} +{ + voice_factors[0] = mult_r( voice_factors[0], tmp2 ); + move16(); + voice_factors[1] = mult_r( voice_factors[1], tmp2 ); + move16(); + voice_factors[2] = mult_r( voice_factors[2], tmp2 ); + move16(); + voice_factors[3] = mult_r( voice_factors[3], tmp2 ); + move16(); + voice_factors[4] = mult_r( voice_factors[4], tmp2 ); + move16(); +} +} - tmp = sub( Q_temp, 3 ); - FOR( k = 0; k < L_FRAME16k; k++ ) +tmp = sub( Q_temp, 3 ); +FOR( k = 0; k < L_FRAME16k; k++ ) +{ + White_exc16k_FB[k] = round_fx( L_shl( White_exc16k_32[k], tmp ) ); /* Q_bwe_exc +5 +1 +Q_temp -16 -3 */ +} +prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; +move16(); +*Q_bwe_exc_fb = sub( add( *Q_bwe_exc, Q_temp ), 13 ); +move16(); +deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); +/* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ +/* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ +{ + IF( EQ_16( coder_type, UNVOICED ) ) { - White_exc16k_FB[k] = round_fx( L_shl( White_exc16k_32[k], tmp ) ); /* Q_bwe_exc +5 +1 +Q_temp -16 -3 */ + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ + FOR( k = 0; k < L_FRAME16k; k++ ) + { + /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ + L_tmp = L_mult( White_exc16k[k], scale ); + /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ + exc16kWhtnd[k] = round_fx( L_shl( L_tmp, NOISE_QADJ ) ); + move16(); + /* exc16kWhtnd: Q_bwe_exc */ + } + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + /* i/o: exc16kWhtnd (Q_bwe_exc) */ + /* i/o: tbe_premph (Q_bwe_exc) */ } - prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; - move16(); - *Q_bwe_exc_fb = sub( add( *Q_bwe_exc, Q_temp ), 13 ); - move16(); - deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ - /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ + ELSE { - IF( EQ_16( coder_type, UNVOICED ) ) + Word16 nbSubFr, lSubFr; + Word16 tempQ15; + Word32 tempQ31; + /*nbSubFr = ( bitrate < ACELP_24k40 )? NB_SUBFR : NB_SUBFR16k;*/ + nbSubFr = NB_SUBFR16k; + lSubFr = ( L_FRAME16k / NB_SUBFR16k ); + IF( LT_32( bitrate, ACELP_24k40 ) ) { - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ - FOR( k = 0; k < L_FRAME16k; k++ ) - { - /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); - /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx( L_shl( L_tmp, NOISE_QADJ ) ); - move16(); - /* exc16kWhtnd: Q_bwe_exc */ - } - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); - /* i/o: exc16kWhtnd (Q_bwe_exc) */ - /* i/o: tbe_premph (Q_bwe_exc) */ + nbSubFr = NB_SUBFR; + move16(); + lSubFr = ( L_FRAME16k / NB_SUBFR ); + move16(); } - ELSE + k = 0; + FOR( i = 0; i < nbSubFr; i++ ) { - Word16 nbSubFr, lSubFr; - Word16 tempQ15; - Word32 tempQ31; - /*nbSubFr = ( bitrate < ACELP_24k40 )? NB_SUBFR : NB_SUBFR16k;*/ - nbSubFr = NB_SUBFR16k; - lSubFr = ( L_FRAME16k / NB_SUBFR16k ); - IF( LT_32( bitrate, ACELP_24k40 ) ) + test(); + IF( EQ_16( coder_type, VOICED ) && ( LT_32( bitrate, ACELP_24k40 ) ) ) { - nbSubFr = NB_SUBFR; + exp = 0; move16(); - lSubFr = ( L_FRAME16k / NB_SUBFR ); + tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ + temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + exp = 0; move16(); + tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ + temp = sub( MAX_16, temp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ } - k = 0; - FOR( i = 0; i < nbSubFr; i++ ) + ELSE { - test(); - IF( EQ_16( coder_type, VOICED ) && ( LT_32( bitrate, ACELP_24k40 ) ) ) - { - exp = 0; - move16(); - tempQ15 = Sqrt16( voice_factors[i], &exp ); /* Q15 */ - temp = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - exp = 0; - move16(); - tempQ15 = Sqrt16( temp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b_fx( pow1 * (1.0f - temp), pow22 ); */ - temp = sub( MAX_16, temp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } - ELSE - { - /* Adjust noise mixing for formant sharpening filter */ - tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); - /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ - vf_tmp = sub( MAX_16, tempQ15 ); - vf_tmp = mult_r( voice_factors[i], vf_tmp ); - - exp = 0; - move16(); - tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ - temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ - - /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ - temp = sub( MAX_16, vf_tmp ); - tempQ31 = Mult_32_16( pow1, temp ); - L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); - temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ - } + /* Adjust noise mixing for formant sharpening filter */ + tempQ15 = mult_r( SWB_NOISE_MIX_FAC_FX, formant_fac ); + /* vf_tmp = voice_factors[i] * (1.0f - vf_tmp); */ + vf_tmp = sub( MAX_16, tempQ15 ); + vf_tmp = mult_r( voice_factors[i], vf_tmp ); - FOR( j = 0; j < lSubFr; j++ ) - { - /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); - move16(); - /* Q_bwe_exc */ - } - k = add( k, lSubFr ); - - /* estimate the pre-emph factor */ - tempQ15 = sub( MAX_16, voice_factors[i] ); exp = 0; move16(); - temp = Sqrt16( tempQ15, &exp ); - temp = shl( temp, exp - 1 ); - - temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ - temp = div_s( temp, temp2 ); /* Q15 */ - temp = mult_r( PREEMPH_FAC, temp ); + tempQ15 = Sqrt16( vf_tmp, &exp ); /* Q15 */ + temp1 = shl( tempQ15, exp ); /* Q15 exc16kWhtnd scale factor */ + + /*temp2 = root_a_over_b(pow1 * (1.0f - vf_tmp), pow22); */ + temp = sub( MAX_16, vf_tmp ); + tempQ31 = Mult_32_16( pow1, temp ); + L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); + temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ + } - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); - /* exc16kWhtnd: Q_bwe_exc; - tbe_premph: Q_bwe_exc*/ + FOR( j = 0; j < lSubFr; j++ ) + { + /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ + L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ + L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ + exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); + move16(); + /* Q_bwe_exc */ } + k = add( k, lSubFr ); + + /* estimate the pre-emph factor */ + tempQ15 = sub( MAX_16, voice_factors[i] ); + exp = 0; + move16(); + temp = Sqrt16( tempQ15, &exp ); + temp = shl( temp, exp - 1 ); + + temp2 = add( temp, shl( temp1, -1 ) ); /* shift right by 1 to avoid overflow */ + temp = div_s( temp, temp2 ); /* Q15 */ + temp = mult_r( PREEMPH_FAC, temp ); + + PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); + /* exc16kWhtnd: Q_bwe_exc; + tbe_premph: Q_bwe_exc*/ } } +} - IF( LT_32( bitrate, ACELP_24k40 ) ) - { - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: excSHB in Q_bwe_exc */ - } - ELSE - { - set16_fx( zero_mem, 0, LPC_SHB_ORDER ); +IF( LT_32( bitrate, ACELP_24k40 ) ) +{ + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: excSHB in Q_bwe_exc */ +} +ELSE +{ + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); - Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); + Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[0] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); - Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); + Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[1] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); - Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); + Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[2] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); - Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); - syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); - move32(); + Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, tempSHB, 80, zero_mem, 1 ); + syn_shb_ener_sf[3] = L_shr( sum2_fx( tempSHB, 80 ), 3 ); + move32(); - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: tempSHB in Q_bwe_exc */ - /* o: syn_shb_ener_sf in (2*Q_bwe_exc+1) */ - IF( LE_32( bitrate, ACELP_32k ) ) - { - L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: tempSHB in Q_bwe_exc */ + /* o: syn_shb_ener_sf in (2*Q_bwe_exc+1) */ + IF( LE_32( bitrate, ACELP_32k ) ) + { + L_tmp = sum32_fx( syn_shb_ener_sf, 4 ); - /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ - tmp = shl( Q_shb, 1 ); - tmp2 = add( shl( *Q_bwe_exc, 1 ), 1 ); - L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ + /* find root_a(tempSHB[0]) = root_a_over_b(shb_ener_sf[0]), L_tmp) */ + tmp = shl( Q_shb, 1 ); + tmp2 = add( shl( *Q_bwe_exc, 1 ), 1 ); + L_tmp2 = root_a_over_b_fx( shb_ener_sf_32, tmp, L_tmp, tmp2, &exp ); /* L_tmp2 in (Q31-exp) */ - *Q_bwe_exc = sub( *Q_bwe_exc, exp ); - move16(); /* compensate for the exp shift */ - tmp2 = add( prev_Q_bwe_syn, n_mem2 ); - IF( GT_16( *Q_bwe_exc, tmp2 ) ) - { - L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); - *Q_bwe_exc = tmp2; - move16(); - } - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ - exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ - move16(); - } - } - /* i: L_tmp2 in (Q31-exp) */ - /* i: exc16kWhtnd in Q_bwe_exc */ - /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ - - /* Rescale the past memories: LP synth and SHB look ahead buffers */ - tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + *Q_bwe_exc = sub( *Q_bwe_exc, exp ); + move16(); /* compensate for the exp shift */ + tmp2 = add( prev_Q_bwe_syn, n_mem2 ); + IF( GT_16( *Q_bwe_exc, tmp2 ) ) { - state_lpc_syn[i] = shl( state_lpc_syn[i], tmp ); + L_tmp2 = L_shl( L_tmp2, sub( tmp2, *Q_bwe_exc ) ); + *Q_bwe_exc = tmp2; move16(); } - FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) + FOR( i = 0; i < L_FRAME16k; i++ ) { - excSHB[i] = shl( excSHB[i], tmp ); + L_tmp3 = Mult_32_16( L_tmp2, exc16kWhtnd[i] ); /* *Q_bwe_exc + (31-exp) - 15 */ + exc16kWhtnd[i] = round_fx( L_tmp3 ); /* *Q_bwe_exc - exp */ move16(); } - /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ - - Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); - Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); - /* i: exc16kWhtnd in (Q_bwe_exc) */ - /* o: excSHB in (Q_bwe_exc) */ } + /* i: L_tmp2 in (Q31-exp) */ + /* i: exc16kWhtnd in Q_bwe_exc */ + /* o: exc16kWhtnd in Q_bwe_exc: (Q_bwe_exc-exp) */ - IF( EQ_16( extl, FB_TBE ) ) + /* Rescale the past memories: LP synth and SHB look ahead buffers */ + tmp = sub( *Q_bwe_exc, prev_Q_bwe_syn ); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { - tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); - Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); - Scale_sig( fb_tbe_demph, 1, tmp ); - Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); - /* i: White_exc16k_FB in (14-n2) */ - /* o: White_exc16k_FB_temp in (14-n2) */ + state_lpc_syn[i] = shl( state_lpc_syn[i], tmp ); + move16(); + } + FOR( i = -L_SHB_LAHEAD; i < 0; i++ ) + { + excSHB[i] = shl( excSHB[i], tmp ); + move16(); + } + /* Do mem_stp_swb_fx scaling before PostShortTerm_fx */ - FOR( i = 0; i < 10; i++ ) - { - FOR( j = 0; j < 32; ++j ) - { - White_exc16k_FB_temp[i * 32 + j] = mult_r( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); - move16(); - } - } + Syn_filt_s( 0, lpc_shb_sf, LPC_SHB_ORDER, exc16kWhtnd, excSHB, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 80, excSHB + 80, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + 2 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 160, excSHB + 160, 80, state_lpc_syn, 1 ); + Syn_filt_s( 0, lpc_shb_sf + 3 * ( LPC_SHB_ORDER + 1 ), LPC_SHB_ORDER, exc16kWhtnd + 240, excSHB + 240, 80, state_lpc_syn, 1 ); + /* i: exc16kWhtnd in (Q_bwe_exc) */ + /* o: excSHB in (Q_bwe_exc) */ +} - *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); - move16(); /**Q_bwe_exc_fb +35 +1 -16*/ - flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); +IF( EQ_16( extl, FB_TBE ) ) +{ + tmp = sub( add( *Q_bwe_exc_fb, 20 ), prev_Q_bwe_exc_fb ); + Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); + Scale_sig( fb_tbe_demph, 1, tmp ); + Syn_filt_s( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); + /* i: White_exc16k_FB in (14-n2) */ + /* o: White_exc16k_FB_temp in (14-n2) */ - deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); - } - ELSE + FOR( i = 0; i < 10; i++ ) { - set16_fx( White_exc16k_FB, 0, L_FRAME16k ); + FOR( j = 0; j < 32; ++j ) + { + White_exc16k_FB_temp[i * 32 + j] = mult_r( White_exc16k_FB_temp[i * 32 + j], cos_fb_exc_fx[j] ); + move16(); + } } - return; + *Q_bwe_exc_fb = add( *Q_bwe_exc_fb, 20 ); + move16(); /**Q_bwe_exc_fb +35 +1 -16*/ + flip_spectrum_fx( White_exc16k_FB_temp, White_exc16k_FB, L_FRAME16k ); + + deemph_fx( White_exc16k_FB, fb_deemph_fac, L_FRAME16k, fb_tbe_demph ); +} +ELSE +{ + set16_fx( White_exc16k_FB, 0, L_FRAME16k ); +} + +return; } void GenShapedSHBExcitation_ivas_enc_fx( @@ -7264,7 +7262,7 @@ void Estimate_mix_factors_fx( #ifndef REMOVE_EVS_DUPLICATES void prep_tbe_exc_fx( - const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 L_frame_fx, /* i : length of the frame */ const Word16 i_subfr_fx, /* i : subframe index */ const Word16 gain_pit_fx, /* i : Pitch gain Q14*/ const Word32 gain_code_fx, /* i : algebraic codebook gain 16+Q_exc*/ @@ -7278,8 +7276,7 @@ void prep_tbe_exc_fx( Word16 T0, /* i : integer pitch variables Q0 */ Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ - Word32 core_brate -) + Word32 core_brate ) { Word16 i; Word16 tmp_code_fx[2 * L_SUBFR * HIBND_ACB_L_FAC]; @@ -7425,12 +7422,11 @@ void prep_tbe_exc_ivas_fx( Word16 T0, /* i : integer pitch variables Q0 */ Word16 T0_frac, /* i : Fractional pitch variables Q0*/ const Word16 coder_type, /* i : coding type */ - Word32 core_brate - , /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ + Word32 core_brate, /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ ) { Word16 i; diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index dedf9f859..ad2f86073 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -64,11 +64,9 @@ static void windowing( const Word16 *, Word16 *, const Word16 *, const Word16, c static void windowing_ROM_optimized( const Word16 *, Word16 *, const Word16, const Word16, const Word16 ); static void fft_spec2_fx( const Word16[], Word32[], const Word16 ); static void trans_ana_fx( const Word16 *, Word16 *, Word16 *, Word16 *, const Word16, const Word16, const Word16, const Word16, Word16 *, Word16 *, Word16 *, Word16 * ); -static void peakfinder_fx( const Word16 *, const Word16, Word16 *, Word16 *, const Word16 -); +static void peakfinder_fx( const Word16 *, const Word16, Word16 *, Word16 *, const Word16 ); static Word16 imax_fx( const Word16 *, const Word16 ); -static void spec_ana_fx( const Word16 *prevsynth, Word16 *plocs, Word32 *plocsi, Word16 *num_plocs, Word16 *X_sav, const Word16 output_frame, const Word16 bwidth_fx, Word16 *Q -); +static void spec_ana_fx( const Word16 *prevsynth, Word16 *plocs, Word32 *plocsi, Word16 *num_plocs, Word16 *X_sav, const Word16 output_frame, const Word16 bwidth_fx, Word16 *Q ); static void subst_spec_fx( const Word16 *, const Word32 *, Word16 *, const Word16, Word16 *, const Word16 *, const Word16, const Word16 *, const Word16, Word16 *, const Word16 *, const Word16 *, Word16, const Word16 * ); static Word16 rand_phase_fx( const Word16 seed, Word16 *sin_F, Word16 *cos_F ); @@ -1779,8 +1777,7 @@ static void spec_ana_fx( { sel = mult_r( sub( Xmax, Xmin ), CMPLMNT_PFIND_SENS_FX ); } - peakfinder_fx( xfp, Lprot2_1, plocs, num_plocs, sel - ); + peakfinder_fx( xfp, Lprot2_1, plocs, num_plocs, sel ); { @@ -2875,8 +2872,7 @@ static void rec_frame_fx( Word16 *X, /* i : FFT spectrum */ Word32 *ecu_rec, /* o : Reconstructed frame in tda domain */ const Word16 output_frame, /* i : Frame length */ - const Word16 Q -) + const Word16 Q ) { const Word16 *pFftTbl; Word16 Lprot, lprotLog2Minus1; @@ -4402,13 +4398,11 @@ static void fec_alg_fx( Word16 exp; Word16 n, Q; - fec_ecu_dft_fx( prevsynth_LP, N, Tfr, Tfi, &sum_Tf_abs, Tf_abs, &Nfft, &exp - ); + fec_ecu_dft_fx( prevsynth_LP, N, Tfr, Tfi, &sum_Tf_abs, Tf_abs, &Nfft, &exp ); sinusoidal_synthesis_fx( Tfr, Tfi, Tf_abs, N, output_frame, decimatefactor, Nfft, sum_Tf_abs, synthesis, HqVoicing, exp ); - fec_noise_filling_fx( prevsynth, synthesis, ni_seed_forfec, output_frame, i_mult2( N, decimatefactor ), HqVoicing, gapsynth - ); + fec_noise_filling_fx( prevsynth, synthesis, ni_seed_forfec, output_frame, i_mult2( N, decimatefactor ), HqVoicing, gapsynth ); n = R1_48 - R2_48; move16(); @@ -4629,8 +4623,7 @@ static void hq_phase_ecu_fx( trans_ana_fx( prevsynth + offset, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, *last_fec, alpha, beta, beta_mute, Xavg ); - spec_ana_fx( prevsynth + offset, plocs, plocsi, num_p, X_sav, output_frame, bwidth_fx, Q_spec - ); + spec_ana_fx( prevsynth + offset, plocs, plocsi, num_p, X_sav, output_frame, bwidth_fx, Q_spec ); test(); IF( prev_bfi != 0 && *last_fec != 0 ) @@ -4660,12 +4653,10 @@ static void hq_phase_ecu_fx( } subst_spec_fx( plocs, plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame, &seed, - alpha, beta, *beta_mute, Xavg - ); + alpha, beta, *beta_mute, Xavg ); /* reconstructed frame in tda domain */ - rec_frame_fx( X, ecu_rec, output_frame, *Q_spec - ); + rec_frame_fx( X, ecu_rec, output_frame, *Q_spec ); *last_fec = 0; move16(); diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 86d8e805a..eb34e1bc1 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -20,7 +20,7 @@ void open_decoder_LPD_fx( Decoder_State *st, const Word32 total_brate, /* Q0 */ - const Word16 bwidth /* Q0 */ + const Word16 bwidth /* Q0 */ ) { Word16 i; diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index 8c68f39ce..94b6efb1b 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -10,9 +10,9 @@ #include "rom_com.h" void mode_switch_decoder_LPD_fx( - Decoder_State *st, /* i/o: decoder state structure */ - Word16 bwidth, /* i : audio bandwidth Q0*/ - Word32 total_brate, /* i : total bitrate Q0*/ + Decoder_State *st, /* i/o: decoder state structure */ + Word16 bwidth, /* i : audio bandwidth Q0*/ + Word32 total_brate, /* i : total bitrate Q0*/ Word16 frame_size_index /* i : index determining the frame size Q0*/ ) { diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index 55d3ebbae..ad89ca556 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -538,8 +538,7 @@ void decoder_acelp_fx( #else prep_tbe_exc_fx( st->L_frame, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, - gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate - ); + gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate ); #endif } diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 1a8a8b30d..161cefe76 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -550,8 +550,8 @@ void con_tcx_fx( { calcGainc2_fx( &exc[0], Q_exc, L_subfr, &( st->Mode2_lp_gainc ) ); } - set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/ - /* PLC: calculate damping factor */ + set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/ + /* PLC: calculate damping factor */ alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/ } @@ -681,7 +681,7 @@ void con_tcx_fx( /* PLC: [TCX: Fade-out] retrieve background level */ tmp16 = 32767; move16(); - gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q5*/ + gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q5*/ IF( st->tcxonly != 0 ) { /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */ @@ -1419,8 +1419,8 @@ void con_tcx_ivas_fx( { calcGainc2_fx( &exc[0], Q_exc, L_subfr, &( st->Mode2_lp_gainc ) ); } - set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/ - /* PLC: calculate damping factor */ + set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/ + /* PLC: calculate damping factor */ alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/ } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 893b49241..3fe93854e 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -792,7 +792,6 @@ Word16 ApplyFdCng_fx( { /* Perform noise estimation in active frames in the decoder for downward updates */ perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec ); - } } test(); diff --git a/lib_dec/gs_dec_amr_wb_fx.c b/lib_dec/gs_dec_amr_wb_fx.c index 331142a44..eea37431a 100644 --- a/lib_dec/gs_dec_amr_wb_fx.c +++ b/lib_dec/gs_dec_amr_wb_fx.c @@ -31,8 +31,7 @@ static void NoiseFill_fx( Word16 *exc_diffQ_fx, Word16 *seed_tcx, const Word16 M static void Ener_per_band_fx( const Word16 exc_diff_fx[], const Word16 exc_diff_exp, Word32 y_gain4_fx[] ); static void Apply_gain_fx( Word16 exc_diffQ_fx[], Word32 L_Ener_per_bd_iQ[], Word32 L_Ener_per_bd_yQ[], const Word16 Q_out ); static void normalize_spec_fx( Word16 fac_up_fx, Word16 fy_norm_fx[], const Word16 L_frame, const Word16 Q_out ); -static void gs_dec_amr_wb_fx( const long core_brate, Word16 *seed_tcx, const Word16 dct_in_fx[], const Word16 Q_dct_in, Word16 dct_out_fx[], Word16 Q_dct_out, const Word16 pitch_fx[], const Word16 voice_fac, const Word16 clas, const Word16 coder_type -); +static void gs_dec_amr_wb_fx( const long core_brate, Word16 *seed_tcx, const Word16 dct_in_fx[], const Word16 Q_dct_in, Word16 dct_out_fx[], Word16 Q_dct_out, const Word16 pitch_fx[], const Word16 voice_fac, const Word16 clas, const Word16 coder_type ); /*-------------------------------------------------------------------* * NoiseFill_fx() @@ -455,8 +454,7 @@ void improv_amr_wb_gs_fx( * Go back to time domain -> Overwrite exctiation *------------------------------------------------------------*/ edct_16fx( exc2_fx, dct_exc_in_fx, L_FRAME, 6, EVS_MONO ); - gs_dec_amr_wb_fx( core_brate, seed_tcx, dct_exc_in_fx, Q_exc2, dct_exc_out_fx, Q_exc2, pitch_buf_fx, lt_voice_fac_fx, clas, coder_type - ); + gs_dec_amr_wb_fx( core_brate, seed_tcx, dct_exc_in_fx, Q_exc2, dct_exc_out_fx, Q_exc2, pitch_buf_fx, lt_voice_fac_fx, clas, coder_type ); edct_16fx( dct_exc_out_fx, exc2_fx, L_FRAME, 6, EVS_MONO ); /*------------------------------------------------------------* diff --git a/lib_dec/tns_base_dec_fx.c b/lib_dec/tns_base_dec_fx.c index def1ffefb..a5df03490 100644 --- a/lib_dec/tns_base_dec_fx.c +++ b/lib_dec/tns_base_dec_fx.c @@ -67,8 +67,7 @@ ReadTnsData( return TNS_NO_ERROR; } -void -ReadTnsData_ivas_fx( +void ReadTnsData_ivas_fx( STnsConfig const *pTnsConfig, Decoder_State *st, Word16 *pnBits, /*Q0*/ diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 7465a7f65..b45b78ad1 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -227,8 +227,7 @@ void TonalMDCTConceal_SaveFreqSignal( Word16 nNewSamplesCore, // Q0 const Word16 *scaleFactors, // Q31-scaleFactors_exp const Word16 *scaleFactors_exp, - const Word16 gain_tcx_exp -) + const Word16 gain_tcx_exp ) { Word16 *temp; Word16 nOldSamples, tmp_exp, s, i, max_exp; diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index 5c0e4911c..2f7870ab6 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -53,8 +53,7 @@ void init_coder_ace_plus_fx( /* Bitrate */ st->tcxonly = (Word8) getTcxonly( - st->total_brate - ); + st->total_brate ); move16(); /* Core Sampling Rate */ -- GitLab From 6dcf203d59ad42b0e2c7b2e98df9c55167d8b0b8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 30 Apr 2025 14:52:40 +0530 Subject: [PATCH 1157/1221] Fix for 3GPP issue 1535: Assert in ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx of BASOP decoder for OMASA bitstream Link #1535 --- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 37b5f1e05..9212e3d23 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -2166,15 +2166,25 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move32(); W_temp = W_add( W_mult0_32_32( a, subtract_power_y ), W_mult0_32_32( b, masa_stereo_type_detect->subtract_power_y_smooth_fx ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth - exp = W_norm( W_temp ); - masa_stereo_type_detect->subtract_power_y_smooth_fx = W_extract_h( W_shl( W_temp, exp ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth + exp - 32 - move32(); - masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 ); - move16(); - + IF( W_temp ) + { + exp = W_norm( W_temp ); + masa_stereo_type_detect->subtract_power_y_smooth_fx = W_extract_h( W_shl( W_temp, exp ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth + exp - 32 + move32(); + masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 ); + move16(); + } + ELSE + { + masa_stereo_type_detect->subtract_power_y_smooth_fx = 0; // Q31 + move32(); + masa_stereo_type_detect->q_subtract_power_y_smooth = Q31; + move16(); + } exp = 0; move16(); - IF( masa_stereo_type_detect->target_power_y_smooth_fx != 0 ) + test(); + IF( masa_stereo_type_detect->target_power_y_smooth_fx && masa_stereo_type_detect->subtract_power_y_smooth_fx ) { subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ), BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25 -- GitLab From 528f8406425967c1634066eda5c83654d1feb415 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 12:57:09 +0200 Subject: [PATCH 1158/1221] update CI commit SHA --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b93061941..605eb30d2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF f5e61349c22ededcdfe1cc54e533dea477f2d003 + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF e0b6e4f4f5f9281794beca2a669fce9be8f8405e include: - local: .gitlab-ci/variables.yml -- GitLab From afce099d46d4481ffbc828cf44a6d42faeaf054e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 13:02:43 +0200 Subject: [PATCH 1159/1221] update sha again to test branch --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 605eb30d2..38aa72681 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF e0b6e4f4f5f9281794beca2a669fce9be8f8405e + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 725e23e7813092e0aab0d8be711356c374dd7663 include: - local: .gitlab-ci/variables.yml -- GitLab From 7d9c257e5781c5eb849bec81611627dbe1b6dfe1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 30 Apr 2025 14:35:09 +0530 Subject: [PATCH 1160/1221] Fix for 3GPP issue 1525: Second channel of BASOP decoder MASA format output to FOA has missing energy or wrong signal - 2 Link #1525 --- lib_rend/ivas_dirac_decorr_dec_fx.c | 75 +++++++++++++++-------------- lib_rend/ivas_rom_rend.h | 8 +-- lib_rend/ivas_rom_rend_fx.c | 9 ++-- lib_rend/ivas_stat_rend.h | 4 +- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 1afac99c4..4db9cd09a 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -63,8 +63,8 @@ * Local function prototypes *------------------------------------------------------------------------*/ -static void get_lattice_coeffs_fx( const Word16 band_index, const Word16 channel_index, Word16 *lattice_coeffs ); -static void lattice2allpass_fx( const Word16 filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); +static void get_lattice_coeffs_fx( const Word16 band_index, const Word16 channel_index, Word32 *lattice_coeffs ); +static void lattice2allpass_fx( const Word16 filter_length, const Word32 *lattice_coeffs_fx, Word32 *filter_coeffs_num_real_fx, Word32 *filter_coeffs_den_real_fx ); /*------------------------------------------------------------------------- * ivas_dirac_dec_decorr_open() @@ -90,7 +90,8 @@ ivas_error ivas_dirac_dec_decorr_open_fx( Word16 split_frequencies_bands[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = { 0, 0, 0, 23768 }; move16(); Word16 *split_freq_ptr; - Word16 cur_lattice_delta_phi_fx, lattice_coeffs_fx[2 * DIRAC_MAX_DECORR_FILTER_LEN]; + Word16 cur_lattice_delta_phi_fx; + Word32 lattice_coeffs_fx[2 * DIRAC_MAX_DECORR_FILTER_LEN]; ivas_error error; @@ -277,12 +278,12 @@ ivas_error ivas_dirac_dec_decorr_open_fx( freq_domain_decorr_ap_state->q_decorr_buffer = Q31; move16(); - IF( ( freq_domain_decorr_ap_params->filter_coeff_num_real_fx = (Word16 *) malloc( sizeof( Word16 ) * imult1616( add( ap_filter_length[split_band_index_start], 1 ), imult1616( freq_domain_decorr_ap_params->max_band_decorr, num_outputs_diff ) ) ) ) == NULL ) + IF( ( freq_domain_decorr_ap_params->filter_coeff_num_real_fx = (Word32 *) malloc( sizeof( Word32 ) * imult1616( add( ap_filter_length[split_band_index_start], 1 ), imult1616( freq_domain_decorr_ap_params->max_band_decorr, num_outputs_diff ) ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } - IF( ( freq_domain_decorr_ap_params->filter_coeff_den_real_fx = (Word16 *) malloc( sizeof( Word16 ) * imult1616( add( ap_filter_length[split_band_index_start], 1 ), imult1616( freq_domain_decorr_ap_params->max_band_decorr, num_outputs_diff ) ) ) ) == NULL ) + IF( ( freq_domain_decorr_ap_params->filter_coeff_den_real_fx = (Word32 *) malloc( sizeof( Word32 ) * imult1616( add( ap_filter_length[split_band_index_start], 1 ), imult1616( freq_domain_decorr_ap_params->max_band_decorr, num_outputs_diff ) ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD decorrelator\n" ) ); } @@ -414,7 +415,7 @@ void ivas_dirac_dec_decorr_process_fx( Word32 frame_ma_fx[2 * ( DIRAC_MAX_DECORR_FILTER_LEN + 1 )]; Word32 *p_frame_dec_fx, *decorr_buffer_fx; Word16 *phase_coeff_real_fx, *phase_coeff_imag_fx; - Word16 *filter_coeff_num_real_fx, *filter_coeff_den_real_fx; + Word32 *filter_coeff_num_real_fx, *filter_coeff_den_real_fx; Word32 *decorr_buffer_start_ptr_fx, *decorr_buffer_ptr_fx; Word32 input_real_fx, input_imag_fx, filter_frame_imag_fx, filter_frame_real_fx; Word16 q_aux_buffer, q_onset_dec, q_frame_f; @@ -666,8 +667,8 @@ void ivas_dirac_dec_decorr_process_fx( /* MA part of filter impulse response */ FOR( l = 0; l < filter_length; l++ ) { - frame_ma_fx[2 * l] = Mpy_32_16_1( input_real_fx, filter_coeff_num_real_fx[l] ); // Q_qux -3 = q_deorr - frame_ma_fx[2 * l + 1] = Mpy_32_16_1( input_imag_fx, filter_coeff_num_real_fx[l] ); // Q_qux - 3 = q_deorr + frame_ma_fx[2 * l] = Mpy_32_32( input_real_fx, filter_coeff_num_real_fx[l] ); // Q_qux -3 = q_deorr + frame_ma_fx[2 * l + 1] = Mpy_32_32( input_imag_fx, filter_coeff_num_real_fx[l] ); // Q_qux - 3 = q_deorr move32(); move32(); } @@ -691,12 +692,12 @@ void ivas_dirac_dec_decorr_process_fx( FOR( l = 1; l < filter_length; l++ ) { // q adjustment needed// - Word32 temp_1 = Mpy_32_16_1( filter_frame_real_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 + Word32 temp_1 = Mpy_32_32( filter_frame_real_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 temp_1 = L_shl( temp_1, 3 ); // q_decorr decorr_buffer_ptr_fx[0] = L_sub( L_add( decorr_buffer_ptr_fx[0], frame_ma_fx[2 * l] ), temp_1 ); // q_deocor move32(); - Word32 temp_2 = Mpy_32_16_1( filter_frame_imag_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 + Word32 temp_2 = Mpy_32_32( filter_frame_imag_fx, filter_coeff_den_real_fx[l] ); // q_decorr - 3 temp_2 = L_shl( temp_2, 3 ); // q_decorr decorr_buffer_ptr_fx[1] = L_sub( L_add( decorr_buffer_ptr_fx[1], frame_ma_fx[2 * l + 1] ), temp_2 ); // q_decorr move32(); @@ -1146,16 +1147,16 @@ void ivas_dirac_dec_decorr_close_fx( static void get_lattice_coeffs_fx( const Word16 band_index, // Q0 const Word16 channel_index, // Q0 - Word16 *lattice_coeffs ) // Q12 + Word32 *lattice_coeffs ) // Q31 { Word16 k; FOR( k = 0; k < ap_filter_length[band_index]; k++ ) { - Word16 cur_lattice_coeff = ap_lattice_coeffs_fx[band_index][add( imult1616( channel_index, ap_filter_length[band_index] ), k )]; // Q12 - lattice_coeffs[k] = cur_lattice_coeff; // Q12 - move16(); - move16(); + Word32 cur_lattice_coeff = ap_lattice_coeffs_fx[band_index][add( imult1616( channel_index, ap_filter_length[band_index] ), k )]; // Q31 + lattice_coeffs[k] = cur_lattice_coeff; // Q31 + move32(); + move32(); } return; @@ -1165,40 +1166,40 @@ static void get_lattice_coeffs_fx( /* convert lattice filter coeffs to all pass transfer function coeffs */ static void lattice2allpass_fx( const Word16 filter_length, // Q0 - const Word16 *lattice_coeffs_fx, // Q15 - Word16 *filter_coeffs_num_real_fx, // Q12 - Word16 *filter_coeffs_den_real_fx ) // Q12 + const Word32 *lattice_coeffs_fx, // Q31 + Word32 *filter_coeffs_num_real_fx, // Q28 + Word32 *filter_coeffs_den_real_fx ) // Q28 { Word16 i, p; - Word16 alpha_real_fx[2][DIRAC_MAX_DECORR_FILTER_LEN + 1]; - Word16 *alpha_real_p_old_fx = &alpha_real_fx[0][0]; - Word16 *alpha_real_p_fx = &alpha_real_fx[1][0]; - Word16 *tmp_fx; + Word32 alpha_real_fx[2][DIRAC_MAX_DECORR_FILTER_LEN + 1]; + Word32 *alpha_real_p_old_fx = &alpha_real_fx[0][0]; + Word32 *alpha_real_p_fx = &alpha_real_fx[1][0]; + Word32 *tmp_fx; FOR( i = 0; i < 2; i++ ) { - set16_fx( alpha_real_fx[i], 0, DIRAC_MAX_DECORR_FILTER_LEN + 1 ); + set32_fx( alpha_real_fx[i], 0, DIRAC_MAX_DECORR_FILTER_LEN + 1 ); } - alpha_real_p_fx[0] = ONE_IN_Q12; - move16(); - alpha_real_p_old_fx[0] = ONE_IN_Q12; - move16(); + alpha_real_p_fx[0] = ONE_IN_Q28; + move32(); + alpha_real_p_old_fx[0] = ONE_IN_Q28; + move32(); /* recursion */ - Word16 lattice_alpha = 0; - move16(); + Word32 lattice_alpha = 0; + move32(); FOR( p = 1; p < filter_length; p++ ) { - alpha_real_p_fx[p] = shr( lattice_coeffs_fx[( p - 1 )], 3 ); /* Q12 */ + alpha_real_p_fx[p] = L_shr( lattice_coeffs_fx[( p - 1 )], 3 ); /* Q28 */ move16(); FOR( i = 1; i < p; i++ ) { - lattice_alpha = mult( lattice_coeffs_fx[( p - 1 )], alpha_real_p_old_fx[sub( p, i )] ); /* Q12 */ - alpha_real_p_fx[i] = add( alpha_real_p_old_fx[i], lattice_alpha ); /* Q12 */ - move16(); + lattice_alpha = Mpy_32_32( lattice_coeffs_fx[( p - 1 )], alpha_real_p_old_fx[sub( p, i )] ); /* Q28 */ + alpha_real_p_fx[i] = L_add( alpha_real_p_old_fx[i], lattice_alpha ); /* Q28 */ + move32(); } /* switch pointers */ tmp_fx = alpha_real_p_old_fx; @@ -1208,10 +1209,10 @@ static void lattice2allpass_fx( FOR( i = 0; i < filter_length; i++ ) { - filter_coeffs_den_real_fx[i] = alpha_real_p_old_fx[i]; /* Q12 */ - move16(); - filter_coeffs_num_real_fx[i] = alpha_real_p_old_fx[sub( sub( filter_length, i ), 1 )]; /* Q12 */ - move16(); + filter_coeffs_den_real_fx[i] = alpha_real_p_old_fx[i]; /* Q28 */ + move32(); + filter_coeffs_num_real_fx[i] = alpha_real_p_old_fx[sub( sub( filter_length, i ), 1 )]; /* Q28 */ + move32(); } return; diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index e7d6c6293..f62440749 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -51,10 +51,10 @@ extern const Word16 diffuse_response_CICP16_fx[9]; /*Q-15*/ extern const Word16 ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS]; extern const Word16 ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS]; extern const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS * DIRAC_MAX_DECORR_FILTER_LEN]; /*Q-14*/ -extern const Word16 ap_lattice_coeffs_1_fx[DIRAC_DECORR_FILTER_LEN_1 * DIRAC_MAX_NUM_DECORR_FILTERS]; /*Q-15*/ -extern const Word16 ap_lattice_coeffs_2_fx[DIRAC_DECORR_FILTER_LEN_2 * DIRAC_MAX_NUM_DECORR_FILTERS]; /*Q-15*/ -extern const Word16 ap_lattice_coeffs_3_fx[DIRAC_DECORR_FILTER_LEN_3 * DIRAC_MAX_NUM_DECORR_FILTERS]; /*Q-15*/ -extern const Word16 *const ap_lattice_coeffs_fx[DIRAC_DECORR_NUM_SPLIT_BANDS]; +extern const Word32 ap_lattice_coeffs_1_fx[DIRAC_DECORR_FILTER_LEN_1 * DIRAC_MAX_NUM_DECORR_FILTERS]; /*Q-15*/ +extern const Word32 ap_lattice_coeffs_2_fx[DIRAC_DECORR_FILTER_LEN_2 * DIRAC_MAX_NUM_DECORR_FILTERS]; /*Q-15*/ +extern const Word32 ap_lattice_coeffs_3_fx[DIRAC_DECORR_FILTER_LEN_3 * DIRAC_MAX_NUM_DECORR_FILTERS]; /*Q-15*/ +extern const Word32 *const ap_lattice_coeffs_fx[DIRAC_DECORR_NUM_SPLIT_BANDS]; extern const Word16 ap_split_frequencies_fx[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]; /*Q-14*/ extern const Word16 sba_map_tc[11]; /*Q-0*/ diff --git a/lib_rend/ivas_rom_rend_fx.c b/lib_rend/ivas_rom_rend_fx.c index 2b46ff611..4f101582c 100644 --- a/lib_rend/ivas_rom_rend_fx.c +++ b/lib_rend/ivas_rom_rend_fx.c @@ -76,11 +76,10 @@ const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECO 29799 , 15800 , 24520 , 10977 , 25165 , 30177 , 16042 , 10060 , 30789 , 8397 , 19121 , 1339 , 29056 , 25160 , 12415 , 3611 , 25203 , 20991 , 4951 , 14580 , 13083 , 24188 , 27295 , 14997 , 22841 , 12403 , 5735 , 19656 , 21619 , 18488 , 10360 , 12954 , 7563 , 27744 , 25189 , 5677 , 7107 , 28747 , 9026 , 11251 , 12524 , 29372 , 24412 }; -const Word16 ap_lattice_coeffs_1_fx[330] /* Q15 */ = { 26061, 16472, 6699, 13650, 15061, 8862, -6617, 917, 2222, -1724, -1270, -1880, 671, 12048, -19454, 17487, 6635, -63, 6392, -6044, -7663, 7474, -10790, -11098, -2611, 1716, -310, 5859, 6253, -15691, 1442, 25837, 4375, -5690, 17871, 22329, 10907, 9656, 10658, 1560, 5157, 3810, 7175, -6201, -10400, -24696, 25309, -16625, 9076, -22700, 7612, -11624, -511, -7309, 10174, -1147, 2810, -16383, 7053, 6599, -16238, -9884, 6439, 10687, -19476, 10319, 21911, 2511, 1497, -4089, -6660, -9738, 4122, -5881, -6611, 5279, 12977, 8745, 11684, 15995, -1843, 4563, -9712, -3697, 1225, -12039, -7087, -9088, 12760, 3772, -7879, -8880, 13982, -362, 4974, 8306, 7397, 16341, -4468, 14516, -9994, -1025, -352, 5581, 16268, -4583, -7929, -3435, 9645, -2219, -16128, -15978, 1192, 3584, 12981, -11562, -6747, -2719, -15172, -10135, 848, -3029, -4100, -5115, -160, 5847, 2935, 1468, 7805, -10227, -12802, -5850, 14890, 12681, -12742, -6481, 1164, 14922, -1782, 12452, 9534, 1599, 2576, 7265, -7128, 3974, -12998, -7159, -4170, -8831, -11279, -15238, -13808, -852, 7259, 11861, -11411, 9666, 11998, 2315, -2819, 8261, 5113, -2057, 13401, 7944, -9888, -2167, 12735, -15146, -5206, 7562, -3053, 1542, 2405, -10977, 751, 11619, 2372, 638, 11039, -15746, 5579, 8508, -12896, -11422, -3570, 9137, 12631, 11870, -10444, 11872, 9467, 9542, -9110, -14722, -9453, -13565, -13280, -9671, -8031, 82, 9433, 11410, -5844, -6767, 11504, -15800, 699, -16128, 1593, 14853, 3576, 7621, -15524, 4603, 11551, -3231, 4822, -1828, 3530, -7570, 11708, 11404, 7615, -10642, 5324, 1888, -1990, -319, -7346, -9252, -2144, 2119, 9187, -9335, -15417, 638, -14493, 12360, 14659, -9519, 11322, 12130, -10260, 3918, 9830, 13336, -9106, 14648, 6383, 5167, -7320, -4822, 12421, -7089, 4520, -13014, 2421, -8949, -14517, -5515, 11346, 1230, 2142, 5370, -4014, 11975, -10365, 3842, -9872, 5558, -11025, 8844, -13767, -10855, 16335, -12878, -15144, -10587, 15432, -11778, 8661, 7104, 16167, 4963, -10539, 15217, -11654, 13775, 6039, -9900, 4474, -8285, 6353, 9790, 7825, -12658, -5963, -2533, 4090, -8630, 12766, 147, 11134, 13605, 12378, 13114, 11548, -124, -6046, 14199, -7784, 4839, 13343, 2215, -8169, -11600, 10516, 13959, 10144, -6215, -6863, 5209, -2684, 12675, 5851, -13341, 7280, -4885, }; -const Word16 ap_lattice_coeffs_2_fx[132] /* Q15 */ = { 20764, 22321, -1619, 9395, 4784, 4436, -13439, -6775, -21527, -3334, 14296, 11135, -4305, -25354, -9883, 10733, 10886, 6745, 23514, -18100, -4919, 1787, 7848, -21249, -23653, 6205, 2234, 203, 2523, 1267, 13874, -3560, 14157, -13586, 9104, 13712, 2549, -9275, -11698, 151, -14504, -12200, 13216, 7963, 10301, 14565, 11387, 16254, 3552, 15380, -5579, 10692, 5641, 14428, 1914, 11130, -6388, 16096, -9217, -1412, -15810, -10977, -11015, 6437, -5394, 14499, -4429, -11612, 14815, -10198, -11391, 16329, -9469, 12334, -5830, 6407, 10940, -5003, 1744, 15000, 14499, 7708, -11310, -9374, 5093, 13283, 7113, -3537, 350, 12090, -16330, -16246, -7060, -3075, 10494, -453, 16036, 15427, -2157, 11366, 893, 4918, 15860, -16298, 5531, -16182, -5686, 10966, 8658, -13914, -10319, 8293, 13021, -16107, -14867, -15183, -626, 11, 10336, 15477, 3117, 9285, -7375, -3924, -15626, 1229, 11041, 16204, -2051, 5821, 15200, 16032, }; -const Word16 ap_lattice_coeffs_3_fx[66] /* Q15 */ = { 621, -6953, 13851, -13128, -3502, -805, 4587, 9161, 1060, 20726, 18957, -24071, 563, 433, -908, -11578, -15799, -16097, 14975, 5410, 15391, -6412, 14421, -15642, 11802, -16074, 15880, -5694, 247, 9115, 14234, 1977, -6347, -1104, 16260, 96, -15756, -3589, -760, 10639, -9570, -11670, -12012, 12481, -9887, 3614, 12575, 9960, -16373, -11455, 10969, -662, -14092, -5069, -12161, 10947, 11367, -5465, -7506, 3865, 11183, 16071, 16176, -12049, 13976, -1499, }; - -const Word16 * const ap_lattice_coeffs_fx[DIRAC_DECORR_NUM_SPLIT_BANDS] = +const Word32 ap_lattice_coeffs_1_fx[330] /* Q31 */ = { 1707955968, 1079539968, 439065920, 894568704, 987086592, 580795520, -433671424, 60123100, 145623008, -113015624, -83277272, -123237648, 43980464, 789623296, -1274971776, 1146041216, 434865440, -4194035, 418933248, -396120544, -502225568, 489841024, -707151360, -727382784, -171154448, 112504520, -20332376, 383985120, 409832224, -1028380544, 94536528, 1693286528, 286751360, -372925568, 1171218304, 1463361920, 714828608, 632831232, 698492672, 102256728, 338016064, 249692224, 470255968, -406406976, -681613440, -1618517632, 1658684160, -1089598848, 594810048, -1487723008, 498864736, -761839168, -33543694, -479015552, 666806528, -75234944, 184217584, -1073737536, 462267328, 432535424, -1064187648, -647809920, 422002016, 700395328, -1276386944, 676287680, 1435960064, 164589584, 98163624, -267984480, -436523296, -638210688, 270166336, -385436800, -433269856, 346019744, 850510912, 573156928, 765762624, 1048283392, -120804544, 299101536, -636524864, -242330640, 80326624, -789039168, -464483520, -595626048, 836273088, 247207584, -516360288, -582000256, 916374208, -23749022, 326015936, 544365632, 484824512, 1070984448, -292867392, 951343872, -655019008, -67237712, -23117662, 365821696, 1066178368, -300379264, -519686752, -225163664, 632096768, -145444768, -1056995776, -1047134528, 78157664, 234919680, 850736384, -757728896, -442194816, -178238992, -994355776, -664208128, 55589760, -198547744, -268733952, -335258720, -10494753, 383196992, 192384464, 96265248, 511571392, -670272576, -838996096, -383418176, 975855232, 831101952, -835100544, -424765824, 76321568, 977938304, -116844584, 816118976, 624840448, 104805792, 168871664, 476183040, -467180768, 260466144, -851865984, -469186528, -273299520, -578761856, -739202496, -998661504, -904981824, -55901148, 475768544, 777374080, -747846144, 633471168, 786354816, 151747632, -184790960, 541442880, 335149184, -134861968, 878260672, 520681024, -648033280, -142077520, 834621696, -992624896, -341192192, 495630624, -200100384, 101094944, 157629600, -719445696, 49263276, 761521344, 155458496, 41817948, 723487232, -1031938880, 365645600, 557622016, -845198016, -748587008, -233994112, 598808640, 827833472, 777923776, -684486784, 778044032, 620485312, 625355840, -597041280, -964868672, -619576960, -889000256, -870330048, -633834112, -526369728, 5433133, 618239040, 747816064, -383012288, -443491872, 753940736, -1035527360, 45870252, -1057006464, 104457896, 973415680, 234419312, 499502560, -1017436928, 301725760, 757045952, -211754768, 316049472, -119823144, 231367744, -496124544, 767317376, 747390912, 499083776, -697476928, 348923136, 123795992, -130425272, -20920786, -481433632, -606352768, -140537776, 138935744, 602089984, -611830976, -1010393216, 41841572, -949849216, 810060928, 960749824, -623839680, 742015744, 795013504, -672420096, 256821872, 644275136, 874015104, -596832960, 960008960, 418381344, 338664608, -479752128, -316038720, 814053056, -464590912, 296281888, -852937536, 158709776, -586499264, -951414720, -361479488, 743596288, 80622976, 140417520, 351974720, -263116144, 784855872, -679294144, 251841856, -646998144, 364266912, -722555264, 579635904, -902286720, -711452736, 1070569984, -843980416, -992532608, -693845504, 1011415424, -771940928, 567612160, 465568000, 1059568448, 325320160, -690744576, 997319296, -763801920, 902804288, 395774784, -648814912, 293208832, -542989120, 416409952, 641614400, 512836288, -829568640, -390839872, -166056320, 268091856, -565634304, 836672512, 9667971, 729723520, 891643776, 811214080, 859468032, 756829056, -8177617, -396275168, 930607744, -510143328, 317148960, 874476800, 145204256, -535395584, -760230656, 689206976, 914828032, 664809408, -407354016, -449784000, 341379040, -175941184, 830706816, 383501920, -874332928, 477147232, -320183360}; +const Word32 ap_lattice_coeffs_2_fx[132] /* Q31 */ = { 1360843264, 1462880896, -106124344, 615715776, 313579872, 290773568, -880779712, -444026592, -1410828032, -218497872, 936944960, 729753600, -282142848, -1661606912, -647739072, 703431872, 713452032, 442076704, 1541038592, -1186205568, -322414592, 117158120, 514363136, -1392593792, -1550156800, 406684000, 146426176, 13348758, 165409920, 83060376, 909276800, -233341280, 927820288, -890434752, 596656832, 898691840, 167097856, -607873152, -766668864, 9951439, -950562176, -799540352, 866157440, 521887904, 675097984, 954584384, 746287104, 1065244224, 232804400, 1007990144, -365686400, 700745408, 369704352, 945610048, 125449552, 729442240, -418684160, 1054884800, -604078592, -92599496, -1036132928, -719417728, -721895936, 421913952, -353525216, 950242176, -290318304, -761035968, 970948224, -668342016, -746551232, 1070181312, -620620608, 808379392, -382088896, 419923232, 716984640, -327914304, 114310552, 983047168, 950209984, 505204128, -741223296, -614390784, 333800576, 870574848, 466160704, -231842336, 22973780, 792393536, -1070215680, -1064756736, -462737632, -201582144, 687787456, -29725468, 1050991360, 1011065344, -141377440, 744899776, 58581208, 322307232, 1039409984, -1068139008, 362486656, -1060515456, -372648544, 718711232, 567440320, -911931072, -676298432, 543498048, 853369216, -1055627776, -974371328, -995053760, -41077068, 738734, 677385088, 1014353152, 204309440, 608543168, -483372800, -257186944, -1024072704, 80584320, 723596736, 1061954304, -134438912, 381504768, 996200512, 1050733696}; +const Word32 ap_lattice_coeffs_3_fx[66] /* Q31 */ = { 1360843264, 1462880896, -106124344, 615715776, 313579872, 290773568, -880779712, -444026592, -1410828032, -218497872, 936944960, 729753600, -282142848, -1661606912, -647739072, 703431872, 713452032, 442076704, 1541038592, -1186205568, -322414592, 117158120, 514363136, -1392593792, -1550156800, 406684000, 146426176, 13348758, 165409920, 83060376, 909276800, -233341280, 927820288, -890434752, 596656832, 898691840, 167097856, -607873152, -766668864, 9951439, -950562176, -799540352, 866157440, 521887904, 675097984, 954584384, 746287104, 1065244224, 232804400, 1007990144, -365686400, 700745408, 369704352, 945610048, 125449552, 729442240, -418684160, 1054884800, -604078592, -92599496, -1036132928, -719417728, -721895936, 421913952, -353525216, 950242176}; +const Word32 * const ap_lattice_coeffs_fx[DIRAC_DECORR_NUM_SPLIT_BANDS] = { &ap_lattice_coeffs_1_fx[0], &ap_lattice_coeffs_2_fx[0], diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 0515e4038..17474bfe7 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -120,8 +120,8 @@ typedef struct dirac_decorr_params_structure Word16 *pre_delay; Word16 *filter_length; - Word16 *filter_coeff_num_real_fx; /* Q12 */ - Word16 *filter_coeff_den_real_fx; /* Q12 */ + Word32 *filter_coeff_num_real_fx; /* Q28 */ + Word32 *filter_coeff_den_real_fx; /* Q28 */ Word16 *phase_coeff_real_fx; /* Q14 */ Word16 *phase_coeff_imag_fx; /* Q14 */ Word16 *split_frequency_bands; -- GitLab From 1609478cc3e8fee37f8a9bf2d43f9da3fc9d0f36 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 30 Apr 2025 14:46:00 +0530 Subject: [PATCH 1161/1221] Clang formatting changes --- lib_rend/ivas_dirac_decorr_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_decorr_dec_fx.c b/lib_rend/ivas_dirac_decorr_dec_fx.c index 4db9cd09a..9b2bf02d7 100644 --- a/lib_rend/ivas_dirac_decorr_dec_fx.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -1154,7 +1154,7 @@ static void get_lattice_coeffs_fx( FOR( k = 0; k < ap_filter_length[band_index]; k++ ) { Word32 cur_lattice_coeff = ap_lattice_coeffs_fx[band_index][add( imult1616( channel_index, ap_filter_length[band_index] ), k )]; // Q31 - lattice_coeffs[k] = cur_lattice_coeff; // Q31 + lattice_coeffs[k] = cur_lattice_coeff; // Q31 move32(); move32(); } -- GitLab From 87f833e2f2c14ee78f51cd74fc6d5c9a0b6c649f Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 30 Apr 2025 13:15:53 +0200 Subject: [PATCH 1162/1221] update CI repo SHA for latest main commit --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 38aa72681..6d9128027 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: # note: GitLab cannot reference variables defined by users in the include ref:, we need to use a YAML anchor for this # see https://docs.gitlab.com/ci/yaml/includes/#use-variables-with-include for more information - IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 725e23e7813092e0aab0d8be711356c374dd7663 + IVAS_CODEC_CI_REF: &IVAS_CODEC_CI_REF 44cb5638949b874ce0f5c3bf4359f9db860d88bc include: - local: .gitlab-ci/variables.yml -- GitLab From bbc238ef5ff9e55a3daa76f3385e239e2b355294 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 30 Apr 2025 17:40:40 +0530 Subject: [PATCH 1163/1221] Fix for decoder msan error --- lib_dec/ivas_stereo_dft_dec_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 324f2b7f3..f1ccc1d7f 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -402,6 +402,8 @@ ivas_error stereo_dft_dec_create_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TCX-LTP handle\n" ) ); } set_zero_fx( hStereoDft_loc->hb_nrg_subr_fx, STEREO_DFT_NBDIV ); /*Setting hb_nrg_subr_fx to zero*/ + hStereoDft_loc->q_hb_nrg_subr = Q31; + move16(); hStereoDft_loc->hConfig->force_mono_transmission = 0; move16(); -- GitLab From 97117fd61051f35fe7546805a6a518eed474fb1d Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 5 May 2025 10:45:37 +0200 Subject: [PATCH 1164/1221] missing pop_wmops() added. --- lib_enc/ivas_cpe_enc_fx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index a05493aa4..d020b398a 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -329,6 +329,7 @@ ivas_error ivas_cpe_enc_fx( &q_band_energies_LR, NULL, NULL, NULL, Q_inp, Q_buffer, Q_add, &front_create_flag ) ), IVAS_ERR_OK ) ) { + pop_wmops(); return error; } @@ -362,6 +363,7 @@ ivas_error ivas_cpe_enc_fx( *----------------------------------------------------------------*/ IF( ( error = stereo_memory_enc_fx( hCPE, input_Fs, max_bwidth, ivas_format, st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) { + pop_wmops(); return error; } @@ -372,6 +374,7 @@ ivas_error ivas_cpe_enc_fx( IF( ( error = stereo_set_tdm_fx( hCPE, input_frame, sts[1]->q_inp32 ) ) != IVAS_ERR_OK ) { + pop_wmops(); return error; } @@ -917,6 +920,7 @@ ivas_error ivas_cpe_enc_fx( move16(); IF( error != IVAS_ERR_OK ) { + pop_wmops(); return error; } } @@ -991,6 +995,7 @@ ivas_error ivas_cpe_enc_fx( igf = getIgfPresent_fx( sts[n]->element_mode, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->rf_mode ); /* Q0 */ IF( ( error = IGF_Reconfig_fx( &sts[n]->hIGFEnc, igf, 0, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->element_mode, sts[n]->rf_mode ) ) != IVAS_ERR_OK ) { + pop_wmops(); return error; } } @@ -1019,6 +1024,7 @@ ivas_error ivas_cpe_enc_fx( { IF( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ) != IVAS_ERR_OK ) { + pop_wmops(); return error; } } @@ -1195,6 +1201,7 @@ ivas_error ivas_cpe_enc_fx( } IF( NE_32( ( error = ivas_core_enc_fx( NULL, hCPE, st_ivas->hMCT, n_CoreChannels, old_inp_12k8_16fx, old_inp_16k_16fx, Q_new, ener_fx, A_fx, Aw_fx, epsP_fx, epsP_fx_q, lsp_new_fx, lsp_mid_fx, vad_hover_flag, attack_flag, realBuffer_fx, imagBuffer_fx, q_re_im_buf, old_wsp_fx, e_old_wsp, loc_harm, cor_map_sum_fx, vad_flag_dtx, enerBuffer_fx, enerBuffer_fx_exp, fft_buff_fx, tdm_SM_or_LRTD_Pri, ivas_format, 0 ) ), IVAS_ERR_OK ) ) { + pop_wmops(); return error; } -- GitLab From fdfd1c02f905d22b41baf98e6d0109313920ad89 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 09:37:10 +0530 Subject: [PATCH 1165/1221] Fix for crash observed with complexity measurement pipeline for stereodownmix --- lib_com/phase_dispersion_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/phase_dispersion_fx.c b/lib_com/phase_dispersion_fx.c index 723d173bc..3103723be 100644 --- a/lib_com/phase_dispersion_fx.c +++ b/lib_com/phase_dispersion_fx.c @@ -114,12 +114,12 @@ void phase_dispersion( scale2 = getScaleFactor32( x32, L_subfr ); FOR( i = 0; i < L_subfr / 2 - 1; i++ ) { - code[i] = round_fx_sat( L_shl_sat( x32[2 * i + 0], scale2 ) ); + code[i] = round_fx_sat( L_shl_sat( x32[2 * i], scale2 ) ); code[L_subfr - 1 - i] = round_fx_sat( L_shl_sat( x32[2 * i + 3], scale2 ) ); } - code[L_subfr / 2 - 1] = round_fx( L_shl( x32[L_subfr - 2], scale2 ) ); - code[L_subfr / 2] = round_fx( L_shl( x32[1], scale2 ) ); + code[L_subfr / 2 - 1] = round_fx_sat( L_shl_sat( x32[L_subfr - 2], scale2 ) ); + code[L_subfr / 2] = round_fx_sat( L_shl_sat( x32[1], scale2 ) ); j = sub( j, scale2 ); -- GitLab From 4fcac19d00b8401c48753423cd399ccaeea01210 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 09:46:22 +0530 Subject: [PATCH 1166/1221] Bug fix for energy level drop Link #1084 --- lib_enc/ivas_front_vad_fx.c | 2 +- lib_enc/nois_est_fx.c | 4 ++-- lib_enc/prot_fx_enc.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index 124ab2996..fff68e5a2 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -613,7 +613,7 @@ ivas_error front_vad_spar_fx( Word16 q_tmpN, q_tmpE; noise_est_down_ivas_fx( fr_bands_fx[0], q_fr_bands[0], hFrontVad->hNoiseEst->bckr_fx, &hFrontVad->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, - &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_32fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); + &hFrontVad->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_fx[0] ) /*q8->q24*/, &hFrontVad->hNoiseEst->Etot_last_32fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index e8c72baa1..733576975 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -748,8 +748,8 @@ void noise_est_down_ivas_fx( const Word16 min_band, /* i : minimum critical band */ const Word16 max_band, /* i : maximum critical band */ Word16 *totalNoise, /* o : noise estimate over all critical bands */ - Word32 Etot, /* i : Energy of current frame */ - Word32 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word32 Etot, /* i : Energy of current frame Q24*/ + Word32 *Etot_last, /* i/o: Energy of last frame Q24 */ Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ ) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 54e203db1..2d7e708bb 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -369,8 +369,8 @@ void noise_est_down_ivas_fx( const Word16 min_band, /* i : minimum critical band */ const Word16 max_band, /* i : maximum critical band */ Word16 *totalNoise, /* o : noise estimate over all critical bands */ - Word32 Etot, /* i : Energy of current frame */ - Word32 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word32 Etot, /* i : Energy of current frame Q24*/ + Word32 *Etot_last, /* i/o: Energy of last frame Q24 */ Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ ); -- GitLab From 88c70599bf3fb7b39d338e5df8b2f56587642f7b Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 6 May 2025 09:21:34 +0200 Subject: [PATCH 1167/1221] Reserve ivas-pytest-compare_ref-long-dec* jobs to high-memory-capacity runners --- .gitlab-ci.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b93061941..279e90e46 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1270,7 +1270,10 @@ ivas-pytest-compare_ref-long-enc: ivas-pytest-compare_ref-long-dec: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux + tags: + - ivas-basop-linux + - high-memory-capacity before_script: - USE_LTV=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -1282,7 +1285,7 @@ ivas-pytest-compare_ref-long-dec: ivas-pytest-compare_ref-long-enc-lev-10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -1294,7 +1297,10 @@ ivas-pytest-compare_ref-long-enc-lev-10: ivas-pytest-compare_ref-long-dec-lev-10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux + tags: + - ivas-basop-linux + - high-memory-capacity before_script: - USE_LTV=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -1318,7 +1324,10 @@ ivas-pytest-compare_ref-long-enc-lev+10: ivas-pytest-compare_ref-long-dec-lev+10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux + tags: + - ivas-basop-linux + - high-memory-capacity before_script: - USE_LTV=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH -- GitLab From 65692897fffed98f744153d0dcba5aa755a8d1e9 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 13:57:38 +0530 Subject: [PATCH 1168/1221] Fix for 3GPP issue 1448: Complexity measurement crashes: StereoDmxEVS Link #1448 --- lib_dec/evs_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index c0281c7e3..9f08a281b 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -1151,7 +1151,7 @@ ivas_error evs_dec_fx( FOR( i = 0; i < tmps; i++ ) { - output_sp[i + delay_comp] = msu_r_sat( L_mult_sat( output_sp[i + delay_comp], alpha ), shr( hHQ_core->old_out_fx[i + nz], timeIn_e ), add( alpha, -32768 ) ); /*timeIn_e*/ + output_sp[i + delay_comp] = msu_r_sat( L_mult_sat( output_sp[i + delay_comp], alpha ), shr_sat( hHQ_core->old_out_fx[i + nz], timeIn_e ), add( alpha, -32768 ) ); /*timeIn_e*/ move16(); alpha = add( alpha, step ); } -- GitLab From 69e2488291842285710c67440681d342844781f8 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 17:31:17 +0530 Subject: [PATCH 1169/1221] Improvements related to input_fx and input32_fx buffers scalings --- lib_com/ivas_prot_fx.h | 2 +- lib_enc/init_enc_fx.c | 6 +- lib_enc/ivas_corecoder_enc_reconfig_fx.c | 76 +++++++--- lib_enc/ivas_cpe_enc_fx.c | 181 ++++++++++++----------- lib_enc/ivas_ism_enc_fx.c | 6 +- lib_enc/ivas_mct_enc_fx.c | 3 + lib_enc/ivas_sce_enc_fx.c | 6 +- lib_enc/ivas_stereo_dft_enc_fx.c | 12 +- lib_enc/ivas_stereo_dft_td_itd_fx.c | 38 +---- lib_enc/ivas_stereo_ica_enc_fx.c | 16 +- lib_enc/ivas_stereo_switching_enc_fx.c | 47 ++---- lib_enc/stat_enc.h | 2 + 12 files changed, 198 insertions(+), 197 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 17566e3cb..5816c60b5 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -4746,7 +4746,7 @@ ivas_error stereo_memory_enc_fx( void stereo_switching_enc_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - Word16 old_input_signal_pri[], /* i : old input signal of primary channel */ + Word32 old_input_signal_pri[], /* i : old input signal of primary channel */ const Word16 input_frame, /* i : input frame length */ const Word16 q_inp ); diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 1513cbe23..97cd57308 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1421,7 +1421,10 @@ ivas_error init_encoder_ivas_fx( set32_fx( st->input_buff32_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); st->q_inp32 = Q31; move16(); + st->q_old_inp32 = Q31; + move16(); st->old_input_signal_fx = st->input_buff_fx; + st->old_input_signal32_fx = st->input_buff32_fx; /* st->input_Fs / FRAMES_PER_SEC */ Word16 frame_length = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); @@ -1432,7 +1435,8 @@ ivas_error init_encoder_ivas_fx( } ELSE { - st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC + // st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC + st->input32_fx = st->input_buff32_fx + frame_length; st->input_fx = st->input_buff_fx + frame_length; } } diff --git a/lib_enc/ivas_corecoder_enc_reconfig_fx.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c index 2e09c42ed..a8698bacc 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig_fx.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -213,24 +213,37 @@ ivas_error ivas_corecoder_enc_reconfig_fx( move16(); } - Word16 q_com_sce = Q15; + Word16 q_com_sce = Q15, q_com_sce32 = Q31; + move16(); + move16(); + Word16 q_com_cpe = Q15, q_com_cpe32 = Q31; move16(); - Word16 q_com_cpe = Q15; move16(); IF( nSCE_old > 0 ) { FOR( k = 0; k < nSCE_old; k++ ) { shift = sub( getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame ), Q1 ); - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp + shift */ + scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp + shift */ st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp, shift ); move16(); q_com_sce = s_min( q_com_sce, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ); shift = sub( getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ), Q1 ); - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_inp + shift */ + scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_inp + shift */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_inp, shift ); move16(); q_com_sce = s_min( q_com_sce, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp ); + + shift = sub( getScaleFactor32( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal32_fx, input_frame ), Q1 ); + scale_sig32( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal32_fx, input_frame, shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp + shift */ + st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp32 = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp32, shift ); + move16(); + q_com_sce32 = s_min( q_com_sce32, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp32 ); + shift = sub( getScaleFactor32( st_ivas->hSCE[k]->hCoreCoder[0]->input32_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ), Q1 ); + scale_sig32( st_ivas->hSCE[k]->hCoreCoder[0]->input32_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_inp + shift */ + st_ivas->hSCE[k]->hCoreCoder[0]->q_inp32 = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_inp32, shift ); + move16(); + q_com_sce32 = s_min( q_com_sce32, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp32 ); } } @@ -242,15 +255,26 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { shift = sub( getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame ), Q1 ); - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp + shift */ + scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp + shift */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp, shift ); move16(); q_com_cpe = s_min( q_com_cpe, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ); shift = sub( getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ), Q1 ); - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp + shift */ + scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp + shift */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp, shift ); move16(); q_com_cpe = s_min( q_com_cpe, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp ); + + shift = sub( getScaleFactor32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal32_fx, input_frame ), Q1 ); + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal32_fx, input_frame, shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp + shift */ + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp32 = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp32, shift ); + move16(); + q_com_cpe32 = s_min( q_com_cpe32, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp32 ); + shift = sub( getScaleFactor32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input32_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ), Q1 ); + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input32_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp + shift */ + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32, shift ); + move16(); + q_com_cpe32 = s_min( q_com_cpe32, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 ); } } } @@ -259,14 +283,16 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( k = 0; k < nSCE_old; k++ ) { - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ) ); /* q_com */ + scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ) ); /* q_com */ st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp = q_com; move16(); - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp ) ); /* q_com */ + scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp ) ); /* q_com */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp = q_com; move16(); Copy_Scale_sig_16_32_DEPREC( st_ivas->hSCE[k]->hCoreCoder[0]->input_buff_fx, st_ivas->hSCE[k]->hCoreCoder[0]->input_buff32_fx, L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS ) + L_FRAME48k, Q6 ); /* Q6 + q_com */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp32 = add( Q6, q_com ); + st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp32 = add( Q6, q_com ); + move16(); move16(); } } @@ -277,14 +303,16 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ) ); /* q_com */ + scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ) ); /* q_com */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp = q_com; move16(); - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp ) ); /* q_com */ + scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp ) ); /* q_com */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp = q_com; move16(); Copy_Scale_sig_16_32_DEPREC( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff_fx, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS ) + L_FRAME48k, Q6 ); /* Q6 + q_com */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 = add( Q6, q_com ); + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp32 = add( Q6, q_com ); + move16(); move16(); } } @@ -301,7 +329,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { set32_fx( input_buff_fx[0], 0, len_inp_memory ); Copy32( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, input_buff_fx[0], len_inp_memory ); /* st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 */ - q_input_buff[0] = st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32; + q_input_buff[0] = st_ivas->hSCE[0]->hCoreCoder[0]->q_old_inp32; move16(); } @@ -311,7 +339,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( nCPE_old > 0 ) { Copy32( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, input_buff_fx[n + 1], len_inp_memory ); /* st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 */ - q_input_buff[n + 1] = st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32; + q_input_buff[n + 1] = st_ivas->hCPE[0]->hCoreCoder[n]->q_old_inp32; move16(); } } @@ -334,7 +362,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( GT_16( n_CoreCoder_existing, sce_id ) ) { Copy32( st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff32_fx, input_buff_fx[sce_id], len_inp_memory ); /* st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_inp32 */ - q_input_buff[sce_id] = st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_inp32; + q_input_buff[sce_id] = st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_old_inp32; move16(); } destroy_sce_enc_fx( st_ivas->hSCE[sce_id], ( EQ_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) && !st_ivas->hEncoderConfig->stereo_dmx_evs ) ); @@ -349,7 +377,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( n_CoreCoder_existing > cpe_id * CPE_CHANNELS + n ) { Copy32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, input_buff_fx[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n], len_inp_memory ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 */ - q_input_buff[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n] = st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32; + q_input_buff[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n] = st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp32; move16(); } } @@ -398,7 +426,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( GT_16( n_CoreCoder_existing, sce_id ) && NE_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { Copy32( input_buff_fx[sce_id], st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff32_fx, len_inp_memory ); /* q_input_buff[sce_id] */ - st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_inp32 = q_input_buff[sce_id]; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_old_inp32 = q_input_buff[sce_id]; move16(); } test(); @@ -475,7 +503,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( GT_16( n_CoreCoder_existing, add( i_mult( cpe_id, CPE_CHANNELS ), n ) ) ) { Copy32( input_buff_fx[n], st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, len_inp_memory ); /* q_input_buff */ - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 = q_input_buff[n]; + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp32 = q_input_buff[n]; move16(); } } @@ -560,7 +588,9 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( st_ivas->nSCE ) { Copy32( input_buff_fx[0], st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, len_inp_memory ); /* q_input_buff */ - st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 = q_input_buff[0]; + // st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 = q_input_buff[0]; + st_ivas->hSCE[0]->hCoreCoder[0]->q_old_inp32 = q_input_buff[0]; + move16(); move16(); } @@ -569,7 +599,9 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { Copy32( input_buff_fx[n + 1], st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, len_inp_memory ); /* q_input_buff */ - st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 = q_input_buff[n + 1]; + // st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 = q_input_buff[n + 1]; + st_ivas->hCPE[0]->hCoreCoder[n]->q_old_inp32 = q_input_buff[n + 1]; + move16(); move16(); } } @@ -579,7 +611,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( NE_16( input_frame, len_inp_memory ) ) { - Copy_Scale_sig32_16( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, st_ivas->hSCE[0]->hCoreCoder[0]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 ) ); // Q(q_data_fx) -> Q(q_input) + Copy_Scale_sig32_16( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, st_ivas->hSCE[0]->hCoreCoder[0]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hSCE[0]->hCoreCoder[0]->q_old_inp32 ) ); // Q(q_data_fx) -> Q(q_input) st_ivas->hSCE[0]->hCoreCoder[0]->q_old_inp = 0; move16(); Copy_Scale_sig32_16( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx + sub( len_inp_memory, input_frame ), st_ivas->hSCE[0]->hCoreCoder[0]->input_buff_fx + sub( len_inp_memory, input_frame ), sub( len_inp_memory, input_frame ), sub( add( Q16, 0 ), st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 ) ); // Q(q_data_fx) -> Q(q_input) @@ -588,7 +620,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( } ELSE { - Copy_Scale_sig32_16( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, st_ivas->hSCE[0]->hCoreCoder[0]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 ) ); // Q(q_data_fx) -> Q(q_input) + Copy_Scale_sig32_16( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, st_ivas->hSCE[0]->hCoreCoder[0]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hSCE[0]->hCoreCoder[0]->q_old_inp32 ) ); // Q(q_data_fx) -> Q(q_input) st_ivas->hSCE[0]->hCoreCoder[0]->q_old_inp = 0; move16(); } @@ -600,7 +632,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( NE_16( input_frame, len_inp_memory ) ) { - Copy_Scale_sig32_16( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, st_ivas->hCPE[0]->hCoreCoder[n]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 ) ); // Q(q_data_fx) -> Q(q_input) + Copy_Scale_sig32_16( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, st_ivas->hCPE[0]->hCoreCoder[n]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hCPE[0]->hCoreCoder[n]->q_old_inp32 ) ); // Q(q_data_fx) -> Q(q_input) st_ivas->hCPE[0]->hCoreCoder[n]->q_old_inp = 0; move16(); @@ -610,7 +642,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( } ELSE { - Copy_Scale_sig32_16( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, st_ivas->hCPE[0]->hCoreCoder[n]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 ) ); // Q(q_data_fx) -> Q(q_input) + Copy_Scale_sig32_16( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, st_ivas->hCPE[0]->hCoreCoder[n]->input_buff_fx, len_inp_memory, sub( add( Q16, 0 ), st_ivas->hCPE[0]->hCoreCoder[n]->q_old_inp32 ) ); // Q(q_data_fx) -> Q(q_input) st_ivas->hCPE[0]->hCoreCoder[n]->q_old_inp = 0; move16(); } diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index d020b398a..19a850a89 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -113,7 +113,9 @@ ivas_error ivas_cpe_enc_fx( Word32 band_energies_LR_fx[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor E_MIN (Q_buffer + QSCALE - band_ener_guardbits) */ Word16 Q_buffer[2]; Word16 orig_input_fx[CPE_CHANNELS][L_FRAME48k]; + Word32 orig_input_fx32[CPE_CHANNELS][L_FRAME48k]; Word16 Q_orig_inp[CPE_CHANNELS]; + Word16 Q_orig_inp32[CPE_CHANNELS]; Word16 Etot_last_fx[CPE_CHANNELS]; Word32 tmp, input_Fs; Word16 max_bwidth, ivas_format; @@ -127,7 +129,7 @@ ivas_error ivas_cpe_enc_fx( Word16 e_old_wsp[CPE_CHANNELS], q_old_wsp; move16(); // Q_new move16(); // Q_new - Word16 q_com; + Word16 q_com, shift, q_min, gb; error = IVAS_ERR_OK; move32(); @@ -217,27 +219,32 @@ ivas_error ivas_cpe_enc_fx( #endif } - Word16 Q_min = s_min( q_data_fx, add( sts[0]->q_inp32, L_norm_arr( sts[0]->input32_fx - input_frame, input_frame ) ) ); - scale_sig32( sts[0]->input32_fx - input_frame, input_frame, sub( Q_min, sts[0]->q_inp32 ) ); + Word16 norm, Q_min = s_min( q_data_fx, add( sts[0]->q_old_inp32, L_norm_arr( sts[0]->input32_fx - input_frame, input_frame ) ) ); + norm = L_norm_arr( data_fx_ch0, input_frame ); + IF( data_fx_ch1 != NULL ) /*this may happen for cases with odd number of channels*/ + { + Q_min = s_min( Q_min, add( sts[1]->q_old_inp32, L_norm_arr( sts[1]->input32_fx - input_frame, input_frame ) ) ); + norm = s_min( norm, L_norm_arr( data_fx_ch1, input_frame ) ); + } + scale_sig32( sts[0]->input32_fx - input_frame, input_frame, sub( Q_min, sts[0]->q_old_inp32 ) ); + sts[0]->q_old_inp32 = Q_min; + move16(); Copy_Scale_sig32( data_fx_ch0, sts[0]->input32_fx, input_frame, sub( Q_min, q_data_fx ) ); // Q(Q_min) sts[0]->q_inp32 = Q_min; move16(); - Word16 norm = L_norm_arr( sts[0]->input32_fx, input_frame ); - Copy_Scale_sig32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, norm ); sts[0]->q_inp = add( sub( sts[0]->q_inp32, Q16 ), norm ); move16(); IF( data_fx_ch1 != NULL ) /*this may happen for cases with odd number of channels*/ { - Q_min = s_min( q_data_fx, add( sts[1]->q_inp32, L_norm_arr( sts[1]->input32_fx - input_frame, input_frame ) ) ); - scale_sig32( sts[1]->input32_fx - input_frame, input_frame, sub( Q_min, sts[1]->q_inp32 ) ); + scale_sig32( sts[1]->input32_fx - input_frame, input_frame, sub( Q_min, sts[1]->q_old_inp32 ) ); + sts[1]->q_old_inp32 = Q_min; + move16(); Copy_Scale_sig32( data_fx_ch1, sts[1]->input32_fx, input_frame, sub( Q_min, q_data_fx ) ); // Q(Q_min) sts[1]->q_inp32 = Q_min; move16(); - norm = L_norm_arr( sts[1]->input32_fx, input_frame ); - Copy_Scale_sig32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, norm ); sts[1]->q_inp = add( sub( sts[1]->q_inp32, Q16 ), norm ); move16(); @@ -297,8 +304,8 @@ ivas_error ivas_cpe_enc_fx( } FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Scale_sig( sts[n]->input_fx, input_frame, sub( scale_inp, sts[n]->q_inp ) ); - Scale_sig( hCPE->hFrontVad[n]->mem_decim_fx, 2 * L_FILT_MAX, sub( scale_inp, hCPE->hFrontVad[n]->q_mem_decim ) ); + scale_sig( sts[n]->input_fx, input_frame, sub( scale_inp, sts[n]->q_inp ) ); + scale_sig( hCPE->hFrontVad[n]->mem_decim_fx, 2 * L_FILT_MAX, sub( scale_inp, hCPE->hFrontVad[n]->q_mem_decim ) ); sts[n]->q_inp = scale_inp; move16(); hCPE->hFrontVad[n]->q_mem_decim = scale_inp; @@ -382,53 +389,44 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ - Word16 shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = norm_arr( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ - sts[1]->q_inp = add( sts[1]->q_inp, shift ); - move16(); - - shift = norm_arr( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); - move16(); - shift = norm_arr( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ - sts[0]->q_inp = add( sts[0]->q_inp, shift ); - move16(); - - Word16 q_inp = s_min( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), s_min( sts[1]->q_inp, sts[1]->q_old_inp ) ); - - Scale_sig( sts[1]->input_fx, input_frame, sub( q_inp, sts[1]->q_inp ) ); /* q_inp */ - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_inp, sts[1]->q_old_inp ) ); /* q_inp */ - sts[1]->q_inp = q_inp; - sts[1]->q_old_inp = q_inp; - move16(); - move16(); + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) + { + gb = find_guarded_bits_fx( sts[0]->encoderLookahead_FB ); + shift = L_norm_arr( sts[1]->old_input_signal32_fx, shl( input_frame, 1 ) ); + shift = s_min( shift, L_norm_arr( sts[0]->old_input_signal32_fx, shl( input_frame, 1 ) ) ); + + IF( LT_16( shift, gb ) ) + { + shift = sub( shift, gb ); + scale_sig32( sts[1]->input32_fx, input_frame, shift ); /* q_inp32 + shift */ + scale_sig32( sts[0]->input32_fx, input_frame, shift ); /* q_inp32 + shift */ + scale_sig32( sts[1]->old_input_signal32_fx, input_frame, shift ); /* q_old_inp32 + shift */ + scale_sig32( sts[0]->old_input_signal32_fx, input_frame, shift ); /* q_old_inp32 + shift */ + sts[1]->q_inp32 = add( sts[1]->q_inp32, shift ); + sts[0]->q_inp32 = add( sts[0]->q_inp32, shift ); + sts[1]->q_old_inp32 = add( sts[1]->q_old_inp32, shift ); + sts[0]->q_old_inp32 = add( sts[0]->q_old_inp32, shift ); + move16(); + move16(); + move16(); + move16(); + } + } - Scale_sig( sts[0]->input_fx, input_frame, sub( q_inp, sts[0]->q_inp ) ); /* q_inp */ - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_inp, sts[0]->q_old_inp ) ); /* q_inp */ - sts[0]->q_inp = q_inp; - move16(); - sts[0]->q_old_inp = q_inp; - move16(); - Scale_sig( sts[0]->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( q_inp, sub( Q15, sts[0]->exp_buf_speech_enc ) ) ); // q_inp - sts[0]->exp_buf_speech_enc = sub( Q15, q_inp ); - move16(); - stereo_switching_enc_fx( hCPE, sts[0]->old_input_signal_fx, input_frame, q_inp ); + stereo_switching_enc_fx( hCPE, sts[0]->old_input_signal32_fx, input_frame, sts[0]->q_old_inp32 ); /*----------------------------------------------------------------* * Temporal inter-channel alignment, stereo adjustment *----------------------------------------------------------------*/ - - Copy_Scale_sig_16_32_DEPREC( sts[0]->input_buff_fx, sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), Q6 ); /* Q6 + sts[0]->q_inp */ - sts[0]->q_inp32 = add( Q6, sts[0]->q_inp ); + shift = s_min( L_norm_arr( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), L_norm_arr( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ); + q_min = add( sts[0]->q_inp32, sub( shift, find_guarded_bits_fx( input_frame ) ) ); + scale_sig32( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( q_min, sts[1]->q_inp32 ) ); /* q_min */ + scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( q_min, sts[0]->q_inp32 ) ); /* q_min */ + sts[0]->q_inp32 = sts[1]->q_inp32 = sts[0]->q_old_inp32 = sts[1]->q_old_inp32 = q_min; + move16(); + move16(); move16(); - Copy_Scale_sig_16_32_DEPREC( sts[1]->input_buff_fx, sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), Q6 ); /* Q6 + sts[0]->q_inp */ - sts[1]->q_inp32 = add( Q6, sts[1]->q_inp ); move16(); stereo_tca_enc_fx( hCPE, input_frame ); @@ -449,9 +447,12 @@ ivas_error ivas_cpe_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { + Copy32( sts[n]->input32_fx, orig_input_fx32[n], input_frame ); /* sts->q_inp32 */ Copy( sts[n]->input_fx, orig_input_fx[n], input_frame ); /* sts->q_inp */ Scale_sig( orig_input_fx[n], input_frame, sub( -1, sts[n]->q_inp ) ); // Q(-1) Q_orig_inp[n] = -1; + Q_orig_inp32[n] = sts[n]->q_inp32; + move16(); move16(); IF( hCPE->hStereoICBWE != NULL ) @@ -633,10 +634,8 @@ ivas_error ivas_cpe_enc_fx( * Stereo processing * Stereo down-mix *----------------------------------------------------------------*/ - // printf("\n%f %f ", hCPE->hStereoClassif->is_speech, hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0]); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - /*flt2fix: dft_synthesize*/ test(); if ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) { @@ -657,7 +656,7 @@ ivas_error ivas_cpe_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { q_com = sub( add( L_norm_arr( sts[n]->input32_fx, input_frame ), sts[n]->q_inp32 ), 16 ); - q_com = s_min( q_com, add( norm_arr( sts[n]->old_input_signal_fx, input_frame ), sts[n]->q_old_inp ) ); + q_com = s_min( q_com, sub( add( L_norm_arr( sts[n]->old_input_signal32_fx, input_frame ), sts[n]->q_old_inp32 ), 16 ) ); q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hCPE->hStereoDft->dft_ovl ), hCPE->q_input_mem[n] ) ); if ( EQ_16( q_com, Q15 ) ) @@ -670,7 +669,7 @@ ivas_error ivas_cpe_enc_fx( sts[n]->q_inp = q_com; move16(); - scale_sig( sts[n]->old_input_signal_fx, input_frame, sub( q_com, sts[n]->q_old_inp ) ); + Copy_Scale_sig_32_16( sts[n]->old_input_signal32_fx, sts[n]->old_input_signal_fx, input_frame, sub( q_com, sts[n]->q_old_inp32 ) ); sts[n]->q_old_inp = q_com; move16(); @@ -754,29 +753,32 @@ ivas_error ivas_cpe_enc_fx( sts[1]->exp_old_inp_12k8 = Q15; move16(); } - } - test(); - IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) - { - Word16 q_min; + q_min = sts[1]->q_old_inp; move16(); q_min = s_min( q_min, sts[1]->q_inp ); q_min = s_min( q_min, sts[0]->q_old_inp ); q_min = s_min( q_min, sts[0]->q_inp ); + q_min = s_min( q_min, hCPE->q_input_mem[0] ); + q_min = s_min( q_min, hCPE->q_input_mem[1] ); shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); shift = s_min( shift, norm_arr( sts[1]->input_fx, input_frame ) ); shift = s_min( shift, norm_arr( sts[0]->old_input_signal_fx, input_frame ) ); shift = s_min( shift, norm_arr( sts[0]->input_fx, input_frame ) ); + shift = s_min( shift, norm_arr( hCPE->input_mem_fx[0], hCPE->hStereoMdct->hDft_ana->dft_ovl ) ); + shift = s_min( shift, norm_arr( hCPE->input_mem_fx[1], hCPE->hStereoMdct->hDft_ana->dft_ovl ) ); q_min = add( q_min, shift ); - scale_sig( sts[1]->input_fx, input_frame, sub( q_min, sts[1]->q_inp ) ); /* q_min */ - scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_min, sts[1]->q_old_inp ) ); /* q_min */ - scale_sig( sts[0]->input_fx, input_frame, sub( q_min, sts[0]->q_inp ) ); /* q_min */ - scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_min, sts[0]->q_old_inp ) ); /* q_min */ - + scale_sig( sts[1]->input_fx, input_frame, sub( q_min, sts[1]->q_inp ) ); /* q_min */ + scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_min, sts[1]->q_old_inp ) ); /* q_min */ + scale_sig( sts[0]->input_fx, input_frame, sub( q_min, sts[0]->q_inp ) ); /* q_min */ + scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_min, sts[0]->q_old_inp ) ); /* q_min */ + scale_sig( hCPE->input_mem_fx[0], hCPE->hStereoMdct->hDft_ana->dft_ovl, sub( q_min, hCPE->q_input_mem[0] ) ); /* q_min */ + scale_sig( hCPE->input_mem_fx[1], hCPE->hStereoMdct->hDft_ana->dft_ovl, sub( q_min, hCPE->q_input_mem[1] ) ); /* q_min */ + hCPE->q_input_mem[1] = q_min; + hCPE->q_input_mem[0] = q_min; sts[1]->q_old_inp = q_min; sts[0]->q_old_inp = q_min; sts[1]->q_inp = q_min; @@ -785,12 +787,11 @@ ivas_error ivas_cpe_enc_fx( move16(); move16(); move16(); + move16(); + move16(); } stereo_td_itd_mdct_stereo_fx( hCPE, vad_flag_dtx, vad_hover_flag, input_frame ); - - Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx - input_frame, sts[0]->input32_fx - input_frame, shl( input_frame, 1 ), sub( sts[0]->q_inp32, sts[0]->q_inp ) ); - Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx - input_frame, sts[1]->input32_fx - input_frame, shl( input_frame, 1 ), sub( sts[1]->q_inp32, sts[1]->q_inp ) ); } /*----------------------------------------------------------------* @@ -816,30 +817,28 @@ ivas_error ivas_cpe_enc_fx( Word16 out_16k_start_ind = 0, out_16k_end_ind = 0; move16(); move16(); + stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, sts[0]->input32_fx, &out_start_ind, &out_end_ind, 0, input_Fs, input_Fs, 0, NULL ); - Scale_sig32( sts[0]->input32_fx - input_frame, add( out_start_ind, input_frame ), sub( Q15, sts[0]->q_inp32 ) ); // scaling initial part of the input buffer + + scale_sig32( sts[0]->input32_fx - input_frame, add( out_start_ind, input_frame ), sub( Q15, sts[0]->q_old_inp32 ) ); // scaling initial part of the input buffer + scale_sig32( sts[0]->input32_fx + out_end_ind, sub( input_frame, out_end_ind ), sub( Q15, sts[0]->q_inp32 ) ); // scaling initial part of the input buffer sts[0]->q_inp32 = Q15; + sts[0]->q_old_inp32 = Q15; move16(); - - // Normalise the input buffer from Q15 - Word16 input_norm, q_inp32, common_q, fir_delay_len; - input_norm = L_norm_arr( sts[0]->input32_fx + out_start_ind, sub( out_end_ind, out_start_ind ) ); - q_inp32 = add( Q15, input_norm ); - fir_delay_len = NS2SA_FX2( sts[0]->input_Fs, DELAY_FIR_RESAMPL_NS ); move16(); - // Find common Q-factor between { q_inp, q_old_inp and q_inp32-16 } - common_q = s_min( s_min( sub( q_inp32, 16 ), sts[0]->q_inp ), sts[0]->q_old_inp ); + // Normalise the input buffer from Q15 + Word16 input_norm, q_inp; //, common_q, fir_delay_len; + input_norm = L_norm_arr( sts[0]->input32_fx - input_frame, shl( input_frame, 1 ) ); + q_inp = sub( add( Q15, input_norm ), 16 ); // Rescale the old input, input and FIR delay section of input buffer - scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( common_q, sts[0]->q_old_inp ) ); // q_old_inp -> common_q - Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, common_q ), Q15 ) ); // Q15 -> common_q - scale_sig( sts[0]->input_fx + out_end_ind, add( sub( input_frame, out_end_ind ), fir_delay_len ), sub( common_q, sts[0]->q_inp ) ); // q_inp -> common_q + Copy_Scale_sig32_16( sts[0]->input32_fx - input_frame, sts[0]->input_fx - input_frame, shl( input_frame, 1 ), sub( add( Q16, q_inp ), Q15 ) ); // Q15 -> q_inp // Update the Q-factors - sts[0]->q_inp = common_q; + sts[0]->q_inp = q_inp; move16(); - sts[0]->q_old_inp = common_q; + sts[0]->q_old_inp = q_inp; move16(); /* iDFT & resampling to 12.8kHz internal sampling rate */ @@ -849,7 +848,7 @@ ivas_error ivas_cpe_enc_fx( /* iDFT & resampling to 16kHz internal sampling rate for M channel */ IF( EQ_32( input_Fs, internal_Fs ) ) { - Copy32( sts[0]->input32_fx - STEREO_DFT_OVL_16k, old_inp_16k_fx[0] + L_INP_MEM - STEREO_DFT_OVL_16k, add( input_frame, STEREO_DFT_OVL_16k ) ); /* Q_inp */ + Copy32( sts[0]->input32_fx - STEREO_DFT_OVL_16k, old_inp_16k_fx[0] + L_INP_MEM - STEREO_DFT_OVL_16k, add( input_frame, STEREO_DFT_OVL_16k ) ); /* sts[0]->q_inp32 */ out_16k_start_ind = -STEREO_DFT_OVL_16k; out_16k_end_ind = add( out_16k_start_ind, add( input_frame, STEREO_DFT_OVL_16k ) ); move16(); @@ -1225,12 +1224,12 @@ ivas_error ivas_cpe_enc_fx( /* update input samples buffer */ FOR( n = 0; n < CPE_CHANNELS; n++ ) { + Copy32( orig_input_fx32[n], sts[n]->old_input_signal32_fx, input_frame ); /* Q_orig_inp32 */ + sts[n]->q_old_inp32 = Q_orig_inp32[n]; + move16(); Copy( orig_input_fx[n], sts[n]->old_input_signal_fx, input_frame ); /* Q_orig_inp */ sts[n]->q_old_inp = Q_orig_inp[n]; move16(); - Copy_Scale_sig_16_32_no_sat( sts[n]->input_fx - input_frame, sts[n]->input32_fx - input_frame, input_frame, 16 ); // duplicating the data for input32_fx - sts[n]->q_inp32 = add( Q_orig_inp[n], 16 ); - move16(); } } ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) @@ -1238,7 +1237,9 @@ ivas_error ivas_cpe_enc_fx( Copy( sts[0]->input_fx, sts[0]->old_input_signal_fx, input_frame ); /* sts[n]->q_inp */ sts[0]->q_old_inp = sts[0]->q_inp; move16(); - Copy32( sts[0]->input32_fx, sts[0]->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ + Copy32( sts[0]->input32_fx, sts[0]->old_input_signal32_fx, input_frame ); /* st->q_inp32 */ + sts[0]->q_old_inp32 = sts[0]->q_inp32; + move16(); } ELSE IF( st_ivas->hMCT == NULL ) /* note: in MCT, input buffers are updated later in ivas_mct_enc() */ { @@ -1248,7 +1249,9 @@ ivas_error ivas_cpe_enc_fx( Copy( sts[n]->input_fx, sts[n]->old_input_signal_fx, input_frame ); /* sts[n]->q_inp */ sts[n]->q_old_inp = sts[n]->q_inp; move16(); - Copy32( sts[n]->input32_fx, sts[n]->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ + Copy32( sts[n]->input32_fx, sts[n]->old_input_signal32_fx, input_frame ); /* st->q_inp32 */ + sts[n]->q_old_inp32 = sts[n]->q_inp32; + move16(); } } diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index 81c9e01ef..122ea1d75 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -167,6 +167,8 @@ ivas_error ivas_ism_enc_fx( *-----------------------------------------------------------------*/ Word16 Q_min = s_min( q_data, add( st->q_inp32, L_norm_arr( st->input32_fx - input_frame, input_frame ) ) ); scale_sig32( st->input32_fx - input_frame, input_frame, sub( Q_min, st->q_inp32 ) ); + st->q_old_inp32 = Q_min; + move16(); Copy_Scale_sig32( data[sce_id], st->input32_fx, input_frame, sub( Q_min, q_data ) ); // Q(Q_min) st->q_inp32 = Q_min; move16(); @@ -474,7 +476,9 @@ ivas_error ivas_ism_enc_fx( Copy( st->input_fx, st->old_input_signal_fx, input_frame ); /* st->q_inp */ st->q_old_inp = st->q_inp; move16(); - Copy32( st->input32_fx, st->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ + Copy32( st->input32_fx, st->old_input_signal32_fx, input_frame ); /* st->q_inp32 */ + st->q_old_inp32 = st->q_inp32; + move16(); hSCE->last_element_brate = hSCE->element_brate; /* Q0 */ move32(); diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 56f5e44db..ee9353379 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -484,6 +484,9 @@ ivas_error ivas_mct_enc_fx( Copy( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ); hCPE->hCoreCoder[n]->q_old_inp = hCPE->hCoreCoder[n]->q_inp; move16(); + Copy32( hCPE->hCoreCoder[n]->input32_fx, hCPE->hCoreCoder[n]->old_input_signal32_fx, input_frame ); + hCPE->hCoreCoder[n]->q_old_inp32 = hCPE->hCoreCoder[n]->q_inp32; + move16(); /* common encoder updates */ updt_enc_common_ivas_fx( hCPE->hCoreCoder[n], Q_new_out[cpe_id][n] ); diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index a578a3cfa..f0811aea6 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -124,6 +124,8 @@ ivas_error ivas_sce_enc_fx( Word16 Q_min = s_min( q_data_fx, add( st->q_inp32, L_norm_arr( st->input32_fx - input_frame, input_frame ) ) ); scale_sig32( st->input32_fx - input_frame, input_frame, sub( Q_min, st->q_inp32 ) ); + st->q_old_inp32 = Q_min; + move16(); Copy_Scale_sig32( data_fx, st->input32_fx, input_frame, sub( Q_min, q_data_fx ) ); // Q(Q_min) st->q_inp32 = Q_min; move16(); @@ -366,7 +368,9 @@ ivas_error ivas_sce_enc_fx( Copy( st->input_fx, st->old_input_signal_fx, input_frame ); st->q_old_inp = st->q_inp; move16(); - Copy32( st->input32_fx, st->input32_fx - input_frame, input_frame ); /* st->q_inp32 */ + Copy32( st->input32_fx, st->old_input_signal32_fx, input_frame ); /* st->q_inp32 */ + st->q_old_inp32 = st->q_inp32; + move16(); hSCE->last_element_brate = hSCE->element_brate; move32(); diff --git a/lib_enc/ivas_stereo_dft_enc_fx.c b/lib_enc/ivas_stereo_dft_enc_fx.c index 6406158b4..80c4b5a21 100644 --- a/lib_enc/ivas_stereo_dft_enc_fx.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -1030,7 +1030,7 @@ void stereo_dft_enc_analyze_fx( FOR( n = 0; n < n_channels; n++ ) { - Scale_sig( &mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); // Q(sts[n]->q_inp) + Scale_sig( &mem[n][0], dft_ovl, sub( sts[n]->q_inp, q_input_mem[n] ) ); // Q(sts[n]->q_inp) q_input_mem[n] = sts[n]->q_inp; move16(); } @@ -1115,8 +1115,7 @@ void stereo_dft_enc_analyze_fx( Word32 stereo_dft_enc_synthesize_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ - // float *output, /* o : output synthesis */ - Word32 *output_fx, /* o : output synthesis Q15 */ + Word32 *output_fx, /* o : output synthesis Q15 */ Word16 *output_start_index, Word16 *output_end_index, const Word16 chan, /* i : channel number */ @@ -1126,25 +1125,18 @@ Word32 stereo_dft_enc_synthesize_fx( Word16 *nrg_out_fx_e ) { Word16 i, j, sign; - // float *pDFT_in; Word32 *pDFT_in_fx; Word16 DFT_in_fx_e; Word16 offset, NFFT, N, ovl, zp; Word16 temp_exp; - // float fac; Word32 fac_fx; - // float *mem; Word32 *mem_fx; - // const float *trigo, *win, *win_ana; const Word16 *trigo_fx; const Word32 *win_fx; const Word16 *win_ana_fx; - // float tmp[STEREO_DFT_N_MAX_ENC]; Word32 tmp_fx[STEREO_DFT_N_MAX_ENC]; - // float nrg; Word32 nrg_fx; Word16 nrg_fx_e; - // float trigo_enc[STEREO_DFT_N_MAX_ENC / 2 + 1]; Word16 trigo_enc_fx[STEREO_DFT_N_MAX_ENC / 2 + 1]; Word16 trigo_step; Word16 scal_fac; diff --git a/lib_enc/ivas_stereo_dft_td_itd_fx.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c index c457faa4f..309ec3377 100644 --- a/lib_enc/ivas_stereo_dft_td_itd_fx.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -499,8 +499,8 @@ void stereo_td_itd_fx( Copy( shift_input, sts[ch]->input_fx, input_frame ); sts[ch]->q_inp = q_new_shift; move16(); - /*sts[ch]->q_old_inp = q_new_shift; - move16();*/ + Copy_Scale_sig_16_32_no_sat( sts[ch]->input_fx, sts[ch]->input32_fx, input_frame, sub( sts[ch]->q_inp32, sts[ch]->q_inp ) ); + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) ) { // here shift_mem has same as input_mem, no need to update q // @@ -512,6 +512,7 @@ void stereo_td_itd_fx( sts[ch]->q_old_inp = q_new_shift; move16(); Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); // Q(sts[ch]->q_inp) + Copy_Scale_sig_16_32_no_sat( shift_mem, sts[ch]->old_input_signal32_fx, input_frame, sub( sts[ch]->q_old_inp32, q_shift_mem ) ); } } } @@ -531,7 +532,7 @@ void stereo_td_itd_mdct_stereo_fx( const Word16 input_frame /* i : frame length */ ) { - Word16 i, n, q_com; + Word16 i; Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC]; Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC]; Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC]; @@ -575,37 +576,6 @@ void stereo_td_itd_mdct_stereo_fx( /*call ITD function*/ stereo_dft_enc_compute_itd_fx( hCPE, DFT_fx[0], DFT_tmp_e[0], DFT_fx[1], DFT_tmp_e[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_e, bin_nrgR_fx, bin_nrgR_e ); - q_com = MAX_16; - move16(); - - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ) ); - q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ), hCPE->hCoreCoder[n]->q_old_inp ) ); - q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl ), hCPE->q_input_mem[n] ) ); - - if ( EQ_16( q_com, Q15 ) ) - { - q_com = 0; - move16(); - } - } - - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_inp ) ); - hCPE->hCoreCoder[n]->q_inp = q_com; - move16(); - - scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_old_inp ) ); - hCPE->hCoreCoder[n]->q_old_inp = q_com; - move16(); - - scale_sig( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) ); - hCPE->q_input_mem[n] = q_com; - move16(); - } - /* Time Domain ITD compensation using extrapolation */ stereo_td_itd_fx( hStereoMdct->hItd, NULL, NULL, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem_fx, hCPE->q_input_mem ); } diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 6057ace6b..d0252a1f1 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -2088,6 +2088,10 @@ void stereo_tca_enc_fx( move16(); sts[1]->q_inp32 = sub( sts[1]->q_inp32, 2 ); move16(); + sts[0]->q_old_inp32 = sub( sts[0]->q_old_inp32, 2 ); + move16(); + sts[1]->q_old_inp32 = sub( sts[1]->q_old_inp32, 2 ); + move16(); } /* update L/R DS memories */ @@ -2319,17 +2323,17 @@ static void unclr_calc_corr_features_fx( move32(); } - hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */ + hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl_sat( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */ + hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl_sat( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); /* Q15 */ + hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl_sat( corrLagMax, 15 ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */ + hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl_sat( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */ + hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl_sat( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); /* Q15 */ + hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl_sat( corrLagMax, 15 ); /* Q15 */ move32(); /* L/M and R/M correlation */ diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 5f1208ba7..8e372b311 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -628,23 +628,6 @@ ivas_error stereo_memory_enc_fx( return error; } -static void v_multc_fixed_32_16( - const Word16 x[], /* i : Input vector Qx*/ - const Word32 c, /* i : Constant Q31*/ - Word32 y[], /* o : Output vector that contains c*x Qx*/ - const Word16 N /* i : Vector length Q0*/ -) -{ - Word16 i; - - FOR( i = 0; i < N; i++ ) - { - y[i] = Mpy_32_16_1( c, x[i] ); /* Q16+Qx */ - move32(); - } - - return; -} /*-------------------------------------------------------------------* * Function stereo_switching_enc() * @@ -653,7 +636,7 @@ static void v_multc_fixed_32_16( void stereo_switching_enc_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - Word16 old_input_signal_pri[], /* i : old input signal of primary channel q_inp*/ + Word32 old_input_signal_pri[], /* i : old input signal of primary channel q_inp*/ const Word16 input_frame, /* i : input frame length Q0*/ const Word16 q_inp ) { @@ -672,8 +655,8 @@ void stereo_switching_enc_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); /* sts[n]->q_inp */ - hCPE->q_input_mem[n] = sts[n]->q_inp; + Copy_Scale_sig32_16( sts[n]->input32_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl, 0 ); /* sts[n]->q_inp32 - 16*/ + hCPE->q_input_mem[n] = sub( sts[n]->q_inp32, 16 ); move16(); } } @@ -681,9 +664,9 @@ void stereo_switching_enc_fx( /* save original stereo input (MDCT overlap part) for both channels in unused old input of right channel for possible DFT->MDCT transition */ IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - Copy( sts[0]->input_fx + sub( (Word16) Mpy_32_32( sts[0]->input_Fs, 42949673 /* 1/50 in Q31*/ ), sts[0]->encoderLookahead_FB ), sts[1]->input_fx - shl( sts[0]->encoderLookahead_FB, 1 ), sts[0]->encoderLookahead_FB ); /* sts[0]->q_inp */ + Copy32( sts[0]->input32_fx + sub( extract_l( Mpy_32_32( sts[0]->input_Fs, 42949673 /* 1/50 in Q31*/ ) ), sts[0]->encoderLookahead_FB ), sts[1]->input32_fx - shl( sts[0]->encoderLookahead_FB, 1 ), sts[0]->encoderLookahead_FB ); /* sts[0]->q_inp32 */ - Copy( sts[1]->input_fx + sub( (Word16) Mpy_32_32( sts[1]->input_Fs, 42949673 /* 1/50 in Q31*/ ), sts[1]->encoderLookahead_FB ), sts[1]->input_fx - sts[1]->encoderLookahead_FB, sts[1]->encoderLookahead_FB ); /* sts[1]->q_inp */ + Copy32( sts[1]->input32_fx + sub( extract_l( Mpy_32_32( sts[1]->input_Fs, 42949673 /* 1/50 in Q31*/ ) ), sts[1]->encoderLookahead_FB ), sts[1]->input32_fx - sts[1]->encoderLookahead_FB, sts[1]->encoderLookahead_FB ); /* sts[1]->q_inp32 */ } @@ -694,7 +677,7 @@ void stereo_switching_enc_fx( /* window DFT synthesis overlap memory @input_Fs, primary channel */ FOR( i = 0; i < dft_ovl; i++ ) { - hCPE->hStereoDft->output_mem_dmx_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_fx[dft_ovl - 1 - i], old_input_signal_pri[input_frame - dft_ovl + i] ), add( q_inp, 1 ) ); // Q31 + q_inp - Q15 - (q_inp + 1) -> Q15 + hCPE->hStereoDft->output_mem_dmx_fx[i] = L_shl( Mpy_32_32_r( hCPE->hStereoDft->win_fx[dft_ovl - 1 - i], old_input_signal_pri[input_frame - dft_ovl + i] ), sub( 15, q_inp ) ); // Q15 move32(); } /* reset 48kHz BWE overlap memory */ @@ -728,7 +711,7 @@ void stereo_switching_enc_fx( /* update DFT synthesis overlap memory @12.8kHz */ FOR( i = 0; i < STEREO_DFT_OVL_12k8; i++ ) { - hCPE->hStereoDft->output_mem_dmx_12k8_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_12k8_fx[STEREO_DFT_OVL_12k8 - 1 - i], sts[0]->buf_speech_enc[L_FRAME32k + L_FRAME - STEREO_DFT_OVL_12k8 + i] ), q_inp + 1 ); /* Q15 */ + hCPE->hStereoDft->output_mem_dmx_12k8_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_12k8_fx[STEREO_DFT_OVL_12k8 - 1 - i], sts[0]->buf_speech_enc[L_FRAME32k + L_FRAME - STEREO_DFT_OVL_12k8 + i] ), sub( 16, sts[0]->exp_buf_speech_enc ) ); /* Q15 */ move32(); } Word16 q_dmx = Q15; @@ -816,10 +799,10 @@ void stereo_switching_enc_fx( offset = sub( sts[0]->cldfbAnaEnc->p_filter_length, sts[0]->cldfbAnaEnc->no_channels ); /* Q0 */ FOR( i = 0; i < offset; i++ ) { - sts[0]->cldfbAnaEnc->cldfb_state_fx[i] = L_deposit_h( old_input_signal_pri[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ); /* Q16+q_inp */ + sts[0]->cldfbAnaEnc->cldfb_state_fx[i] = old_input_signal_pri[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i]; /* q_inp */ move32(); } - sts[0]->cldfbAnaEnc->Q_cldfb_state = add( Q16, q_inp ); + sts[0]->cldfbAnaEnc->Q_cldfb_state = q_inp; move16(); } @@ -838,18 +821,18 @@ void stereo_switching_enc_fx( test(); IF( hCPE->hStereoTD != NULL && EQ_16( hCPE->hStereoTD->tdm_last_ratio_idx, LRTD_STEREO_LEFT_IS_PRIM ) ) { - v_multc_fixed_32_16( hCPE->hCoreCoder[1]->old_input_signal_fx + sub( input_frame, add( offset, NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) ) ), -MAX_32, sts[1]->cldfbAnaEnc->cldfb_state_fx, offset ); /* Q16+q_inp */ - sts[1]->cldfbAnaEnc->Q_cldfb_state = add( Q16, q_inp ); + v_multc_fixed( hCPE->hCoreCoder[1]->old_input_signal32_fx + sub( input_frame, add( offset, NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) ) ), -MAX_32, sts[1]->cldfbAnaEnc->cldfb_state_fx, offset ); /* Q16+q_inp */ + sts[1]->cldfbAnaEnc->Q_cldfb_state = q_inp; move16(); } ELSE { FOR( i = 0; i < offset; i++ ) { - sts[1]->cldfbAnaEnc->cldfb_state_fx[i] = L_shr( L_deposit_h( hCPE->hCoreCoder[1]->old_input_signal_fx[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ), 5 ); /* Q11+q_inp */ + sts[1]->cldfbAnaEnc->cldfb_state_fx[i] = ( hCPE->hCoreCoder[1]->old_input_signal32_fx[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ); /* q_inp */ move32(); } - sts[1]->cldfbAnaEnc->Q_cldfb_state = add( Q16 - 5, q_inp ); + sts[1]->cldfbAnaEnc->Q_cldfb_state = q_inp; move16(); } @@ -929,9 +912,9 @@ void stereo_switching_enc_fx( tmp_fx = div_s( 64, shl( sts[0]->encoderLookahead_FB, Q6 ) ); /* Q15 */ FOR( i = 0; i < sts[0]->encoderLookahead_FB; i++ ) { - sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i] = L_shr( Mpy_32_16_1( L_add( Mpy_32_16_1( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), Mpy_32_16_1( sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ), 13 ); /* q_inp32+0-15+15-15-13 */ + sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i] = ( Mpy_32_16_1( L_add( imult3216( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), imult3216( sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ) ); /* sts[0]->q_inp32 */ move32(); - sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i] = L_shr( Mpy_32_16_1( L_add( Mpy_32_16_1( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), Mpy_32_16_1( sts[1]->input32_fx[-2 * sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ), 13 ); /* q_inp32+0-15+15-15-13 */ + sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i] = ( Mpy_32_16_1( L_add( imult3216( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), imult3216( sts[1]->input32_fx[-2 * sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ) ); /* sts[0]->q_inp32 */ move32(); } /* restore continuous signal in right channel (part of old_output was used to store original left channel) */ diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 4da0bff61..3d6f23dd3 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1457,7 +1457,9 @@ typedef struct enc_core_structure Word16 q_inp32; Word16 q_inp; Word16 *old_input_signal_fx; + Word32 *old_input_signal32_fx; Word16 q_old_inp; + Word16 q_old_inp32; Word16 Q_old_wtda; SIGNAL_BUFFERS_ENC_HANDLE hSignalBuf; -- GitLab From 1315314d6dd10a3a78ae888cac411bf27d5ad0f3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 10:17:35 +0530 Subject: [PATCH 1170/1221] Fix for 3GPP issue 1548: MASA coherence codebook fixed point values Link #1548 --- lib_com/ivas_rom_com_fx.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index ffb18d6d2..e7ee30e8d 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1604,15 +1604,22 @@ const Word16 coherence_cb0_masa_Q14[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH] = // q = 21 const Word32 coherence_cb0_masa_fx[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH] = { - 100243, 534144, 1156579, 2068840, 2846464, 3531184, 4125936, 0, 253965, 864655, 1467377, - 2129448, 2977326, 3768791, 0, 0, 338480, 1189924, 2035915, 2872888, 3640026, 0, 0, 0, - 492621, 1532179, 2527278, 3470157, 0, 0, 0, 0, 499331, 1506803, 2465831, 3425697, 0, - 0, 0, 0, 503316, 1473668, 2392221, 3406404, 0, 0, 0, 0, 737778, 1970903, 3450654, 0, 0, - 0, 0, 0, 2097152, 0, 0, 0, 0, 0, 0, 0, 303038, 719742, 1122186, 1577897, 2117075, 2770337, - 3648834, 0, 419849, 932603, 1440533, 2011797, 2745172, 3571240, 0, 0, 548824, 1165177, - 1812987, 2555379, 3366138, 0, 0, 0, 695835, 1428160, 2190475, 3084910, 0, 0, 0, 0, 697093, - 1381603, 2092957, 2970406, 0, 0, 0, 0, 708417, 1396283, 2099039, 2992426, 0, 0, 0, 0, 835924, - 1728892, 2836607, 0, 0, 0, 0, 0, 2097152, 0, 0, 0, 0, 0, 0, 0 + 100244, 534145, 1156579, 2068841, 2846465, 3531185, 4125937, 0, + 253965, 864656, 1467377, 2129448, 2977327, 3768792, 0, 0, + 338480, 1189924, 2035915, 2872889, 3640027, 0, 0, 0, + 492621, 1532179, 2527278, 3470158, 0, 0, 0, 0, + 499332, 1506804, 2465831, 3425698, 0, 0, 0, 0, + 503316, 1473669, 2392221, 3406404, 0, 0, 0, 0, + 737778, 1970904, 3450654, 0, 0, 0, 0, 0, + 2097152, 0, 0, 0, 0, 0, 0, 0, + 303038, 719743, 1122186, 1577897, 2117075, 2770338, 3648835, 0, + 419850, 932604, 1440534, 2011798, 2745172, 3571240, 0, 0, + 548825, 1165178, 1812988, 2555380, 3366139, 0, 0, 0, + 695835, 1428161, 2190475, 3084911, 0, 0, 0, 0, + 697093, 1381604, 2092958, 2970406, 0, 0, 0, 0, + 708418, 1396284, 2099040, 2992426, 0, 0, 0, 0, + 835925, 1728892, 2836608, 0, 0, 0, 0, 0, + 2097152, 0, 0, 0, 0, 0, 0, 0 }; // q = 15 @@ -1626,9 +1633,11 @@ const Word16 coherence_cb1_masa_Q15[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBAN // q = 21 const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBANDS] = { - -3984, 544630, -565392, 1314704, -1320157, -11534, 541484, -583847, 1357486, -1371118, - -6081, 525546, -551551, 1362729, -1371537, -838, 533934, -540855, 1436758, -1414109, - 3565, 528692, -519883, 1513514, -1500931 + -3985, 544630, -565392, 1314705, -1320157, + -11534, 541485, -583847, 1357487, -1371118, + -6082, 525546, -551551, 1362729, -1371537, + -839, 533935, -540856, 1436759, -1414110, + 3565, 528692, -519884, 1513515, -1500932 }; /* Multi-channel input and output setups */ -- GitLab From 86df3c3d2fd583636cad66804c676d9948310497 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 10:38:23 +0530 Subject: [PATCH 1171/1221] Q fixes in inov_encode function --- lib_enc/acelp_core_switch_enc_fx.c | 3 +- lib_enc/corr_xh_fx.c | 14 +-- lib_enc/enc_gen_voic_fx.c | 2 +- lib_enc/enc_pit_exc_fx.c | 2 +- lib_enc/enc_tran_fx.c | 3 +- lib_enc/find_tar_fx.c | 135 ----------------------------- lib_enc/inov_enc_fx.c | 37 +++++--- lib_enc/prot_fx_enc.h | 16 +--- 8 files changed, 39 insertions(+), 173 deletions(-) diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 854f0ff67..4852cb567 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -6,7 +6,6 @@ #include "options.h" #include "cnst.h" #include "rom_com_fx.h" -//#include "prot_fx.h" #include "rom_com.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -630,7 +629,7 @@ static void encod_gen_voic_core_switch_ivas_fx( ELSE { weight_a_fx( A, Ap, GAMMA1, M ); /* Bandwidth expansion of A(z) filter coefficients */ - find_targets_ivas_fx( inp, hLPDmem->mem_syn, 0, &( hLPDmem->mem_w0 ), Aq, res, L_SUBFR, Ap, TILT_FAC_FX, xn, cn, h1 ); + find_targets_ivas_fx( inp, hLPDmem->mem_syn, 0, &( hLPDmem->mem_w0 ), Aq, res, L_SUBFR, Ap, TILT_FAC_FX, xn, cn, h1 ); } q_h1 = sub( 14, norm_s( h1[0] ) ); diff --git a/lib_enc/corr_xh_fx.c b/lib_enc/corr_xh_fx.c index 51165d141..5fb7c628a 100644 --- a/lib_enc/corr_xh_fx.c +++ b/lib_enc/corr_xh_fx.c @@ -133,7 +133,7 @@ void corr_xh_ivas_fx( const Word16 Qx, Word16 dn[], /* o : correlation between x[] and h[] Qdn*/ Word16 *Qdn, - const Word16 h[], /* i : impulse response (of weighted synthesis filter) (Q15 - norm_s(h[0]))*/ + const Word16 h[], /* i : impulse response (of weighted synthesis filter) (Q14 - norm_s(h[0]))*/ const Word16 L_subfr /* i : length of the subframe Q0*/ ) { @@ -152,16 +152,16 @@ void corr_xh_ivas_fx( L_maxloc = L_deposit_l( 0 ); FOR( i = k; i < L_subfr; i += STEP ) { - L_tmp = L_mac( 0, x[i], h[0] ); // Qx+(15 - norm_s(h[0])) + L_tmp = L_mac( 0, x[i], h[0] ); // Qx+(14 - norm_s(h[0])) + 1 FOR( j = i; j < L_subfr - 1; j++ ) { - L_tmp = L_mac_o( L_tmp, x[j + 1], h[j + 1 - i], &Overflow ); // Qx+(15 - norm_s(h[0])) + L_tmp = L_mac_o( L_tmp, x[j + 1], h[j + 1 - i], &Overflow ); // Qx+(14 - norm_s(h[0])) + 1 } - y32[i] = L_tmp; // Qx+(15 - norm_s(h[0])) + y32[i] = L_tmp; // Qx+(14 - norm_s(h[0])) + 1 move32(); L_tmp = L_abs( L_tmp ); - L_maxloc = L_max( L_tmp, L_maxloc ); // Qx+(15 - norm_s(h[0])) + L_maxloc = L_max( L_tmp, L_maxloc ); // Qx+(14 - norm_s(h[0])) +1 } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); @@ -176,11 +176,11 @@ void corr_xh_ivas_fx( FOR( i = 0; i < L_subfr; i++ ) { - dn[i] = round_fx( L_shl( y32[i], j ) ); // Qx+(15 - norm_s(h[0])) +j - 16 + dn[i] = round_fx( L_shl( y32[i], j ) ); // Qx+(14 - norm_s(h[0])) + 1 +j - 16 move16(); } - *Qdn = sub( add( add( Qx, sub( 15, norm_s( h[0] ) ) ), j ), 16 ); + *Qdn = sub( add( add( Qx, add( sub( 14, norm_s( h[0] ) ), 1 ) ), j ), 16 ); move16(); return; } diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index a60828a94..bb305e9c9 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -562,7 +562,7 @@ void encod_gen_voic_ivas_fx( Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); /*Q_new*/ - find_targets_ivas_new_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, + find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); q_h1 = sub( 14, norm_s( h1_fx[0] ) ); diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index f16dd80cb..e87462988 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -721,7 +721,7 @@ void enc_pit_exc_ivas_fx( Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); /* Q_new */ /* condition on target (compared to float) has been put outside the loop */ - find_targets_ivas_new_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, + find_targets_ivas_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index 865972819..c92e1b6db 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -545,7 +545,8 @@ Word16 encod_tran_ivas_fx( Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ - find_targets_ivas_new_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, + + find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index 4f24ec39f..8d3efb834 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -173,141 +173,6 @@ void find_targets_ivas_fx( Word16 *cn, /* o : target vector in residual domain Q_new*/ Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ) -{ - Word16 i; - Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */ - Word16 scale, scaleq, j, d, s, s2, tmp; - Word16 Aqs[M + 1]; - Word32 h1_32[6 * L_SUBFR]; - Word16 sf; - Word64 Ltmp64; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move16(); -#endif - /*------------------------------------------------------------------------* - * Find the target vector for excitation search: - * - * |------| res[n] - * speech[n]---| A(z) |-------- - * |------| | |--------| error[n] |------| - * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target - * exc |--------| |------| - * - * Instead of subtracting the zero-input response of filters from - * the weighted input speech, the above configuration is used to - * compute the target vector. - *-----------------------------------------------------------------------*/ - FOR( i = 0; i < M; i++ ) - { - temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */ - move16(); - } - Scale_sig( temp, M, 1 ); // scaling to make belong function output alligned //Qnew - - syn_filt_fx( 0, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); - - Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new */ - - deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new */ - - *mem_w0 = shr( *mem_w0, 1 ); // Q_new - 1 - - /*-----------------------------------------------------------------* - * Find target in residual domain (cn[]) for innovation search - *--------------------------------------------------------------*/ - IF( cn != NULL ) - { - /* first half: xn[] --> cn[] */ - temp[0] = 0; - move16(); - preemph_copy_fx( xn, cn, tilt_fac, shr( L_subfr, 1 ), temp ); - syn_filt_s_lc_fx( 1, Ap, cn, temp, shr( L_subfr, 1 ) ); /* Q_new -> Q_new - 1 */ - Residu3_lc_fx( p_Aq, M, temp, cn, shr( L_subfr, 1 ), 1 ); /* Q_new - 1 -> Q_new */ - - /* second half: res[] --> cn[] (approximated and faster) */ - Copy( &res[i_subfr + shr( L_subfr, 1 )], cn + shr( L_subfr, 1 ), shr( L_subfr, 1 ) ); /* Q_new */ - } - scale_sig( xn, L_subfr, -1 ); // Q_new - 1 - - /*---------------------------------------------------------------* - * Compute impulse response, h1[], of weighted synthesis filter * - *---------------------------------------------------------------*/ - - scale = norm_s( Ap[0] ); - scaleq = norm_s( p_Aq[0] ); - d = sub( scaleq, scale ); - IF( d >= 0 ) - { - Copy( p_Aq, Aqs, M + 1 ); /* Q12 */ - s = add( scaleq, 1 ); - s2 = shr( 16384, d ); - } - ELSE - { - Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */ - s = add( scale, 1 ); - s2 = 16384; - move16(); - } - - set32_fx( h1_32, 0, L_subfr ); - Overflow = 0; - move16(); - FOR( i = 0; i < M; i++ ) - { - Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ - FOR( j = 1; j <= i; j++ ) - { - Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ - } - h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ - move32(); - } - - Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ - FOR( j = 1; j <= M; j++ ) - { - Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ - } - h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */ - move32(); - - FOR( i = M + 1; i < L_subfr; i++ ) - { - Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_o( h1_32[i - 1], s, &Overflow ) ) ); /* Q27 */ - FOR( j = 2; j <= M; j++ ) - { - Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ - } - h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ - move32(); - } - - sf = sub( L_norm_arr( h1_32, L_subfr ), 1 ); - Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf - - tmp = 0; - move16(); - Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1 - - return; -} - -void find_targets_ivas_new_fx( - const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ - const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index Q0*/ - Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ - const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ - const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ - const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15*/ - Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ - Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ -) { Word16 i; Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */ diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index fe22ee398..62ea723a3 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -370,7 +370,7 @@ Word16 inov_encode_ivas_fx( Word16 shift, Word16 Q_new ) { - Word16 dn[2 * L_SUBFR], Qdn; + Word16 dn[2 * L_SUBFR], Qdn, Qcn; Word16 nBits, cmpl_flag; Word16 stack_pulses; Word16 g1, g2; @@ -378,7 +378,7 @@ Word16 inov_encode_ivas_fx( Word16 acelpautoc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; Word16 i, k; - Word16 Qxn, Rw_q, j, max_xn2; + Word16 Qxn, max_xn2; stack_pulses = 0; move16(); @@ -416,20 +416,22 @@ Word16 inov_encode_ivas_fx( test(); test(); + Qcn = Q_new; + move16(); IF( GT_32( core_brate, ACELP_13k20 ) && !Opt_AMR_WB && EQ_16( L_subfr, L_SUBFR ) ) { acelpautoc = 1; move16(); - Word16 q_h1 = sub( 14, norm_s( h2[0] ) ); - Scale_sig( h2, L_SUBFR, sub( 11, q_h1 ) ); /* set h2[] in Q11*/ - cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_SUBFR ); + cb_shape_fx(1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr(add(pt_pitch, 26), 6), 0, L_SUBFR); /* h2: Q11, Rw: (Rw_e)Q */ - corr_hh_ivas_fx( h2, Rw, &Rw_q, L_subfr ); // Q(Rw) = Q11-2 - E_ACELP_conv_ivas_fx( xn2, h2, cn ); // Qcn = Qxn2 + /* Rw_e = */ E_ACELP_hh_corr(h2, Rw, L_SUBFR, 3); + + E_ACELP_conv(xn2, h2, cn); /* dn_e -> Rw_e*Q_xn */ - j = E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); - Qdn = add( add( Qxn, Rw_q ), add( j, 1 ) ); + /*dn_e = */ E_ACELP_toeplitz_mul_fx(Rw, cn, dn, L_SUBFR, 1); + Qdn = Qcn; + move16(); } ELSE { @@ -442,6 +444,19 @@ Word16 inov_encode_ivas_fx( Scale_sig( h2, L_SUBFR, sub( 11, q_h1 ) ); /* set h2[] in Q11*/ cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); corr_xh_ivas_fx( xn2, Qxn, dn, &Qdn, h2, L_subfr ); // Q(dn) = Q_new+1 + IF( LT_16( Qdn, Qcn ) ) + { + scale_sig( cn, L_subfr, sub(Qdn, Qcn) ); + Qcn = Qdn; + move16(); + } + ELSE + { + scale_sig( dn, L_subfr, sub(Qcn, Qdn) ); + Qdn = Qcn; + move16(); + } + } /*-----------------------------------------------------------------* @@ -607,7 +622,7 @@ Word16 inov_encode_ivas_fx( } ELSE { - acelp_fast_fx( hBstr, nBits, dn, Qdn, cn, Q_new, h2, code, y2, L_subfr ); + acelp_fast_fx( hBstr, nBits, dn, Qdn, cn, Qcn, h2, code, y2, L_subfr ); } } ELSE IF( ( EQ_16( st_fx->idchan, 1 ) && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 7 ) ) || ( st_fx->idchan == 0 && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 3 ) ) ) @@ -618,7 +633,7 @@ Word16 inov_encode_ivas_fx( } ELSE { - acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn, Q_new, h2, code, y2, L_SUBFR ); + acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn, Qcn, h2, code, y2, L_SUBFR ); } } ELSE diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 2d7e708bb..05bb16832 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2334,22 +2334,8 @@ void find_targets_fx( Word16 *cn, /* o : target vector in residual domain Q_new*/ Word16 *h1 /* o : impulse response of weighted synthesis filter Q14*/ ); -void find_targets_ivas_fx( - const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ - const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index Q0*/ - Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ - const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ - const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ - const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15*/ - Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ - Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ -); -void find_targets_ivas_new_fx( +void find_targets_ivas_fx( const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ const Word16 i_subfr, /* i : subframe index Q0*/ -- GitLab From 89c0af8f9c3de8b0fa689f96e4280438f1cc066b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 10:48:05 +0530 Subject: [PATCH 1172/1221] Clang formatting changes --- lib_enc/acelp_core_switch_enc_fx.c | 2 +- lib_enc/corr_xh_fx.c | 2 +- lib_enc/enc_gen_voic_fx.c | 2 +- lib_enc/enc_pit_exc_fx.c | 2 +- lib_enc/enc_tran_fx.c | 2 +- lib_enc/inov_enc_fx.c | 13 ++++++------- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 4852cb567..bad70b08c 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -629,7 +629,7 @@ static void encod_gen_voic_core_switch_ivas_fx( ELSE { weight_a_fx( A, Ap, GAMMA1, M ); /* Bandwidth expansion of A(z) filter coefficients */ - find_targets_ivas_fx( inp, hLPDmem->mem_syn, 0, &( hLPDmem->mem_w0 ), Aq, res, L_SUBFR, Ap, TILT_FAC_FX, xn, cn, h1 ); + find_targets_ivas_fx( inp, hLPDmem->mem_syn, 0, &( hLPDmem->mem_w0 ), Aq, res, L_SUBFR, Ap, TILT_FAC_FX, xn, cn, h1 ); } q_h1 = sub( 14, norm_s( h1[0] ) ); diff --git a/lib_enc/corr_xh_fx.c b/lib_enc/corr_xh_fx.c index 5fb7c628a..56b22c206 100644 --- a/lib_enc/corr_xh_fx.c +++ b/lib_enc/corr_xh_fx.c @@ -161,7 +161,7 @@ void corr_xh_ivas_fx( y32[i] = L_tmp; // Qx+(14 - norm_s(h[0])) + 1 move32(); L_tmp = L_abs( L_tmp ); - L_maxloc = L_max( L_tmp, L_maxloc ); // Qx+(14 - norm_s(h[0])) +1 + L_maxloc = L_max( L_tmp, L_maxloc ); // Qx+(14 - norm_s(h[0])) +1 } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index bb305e9c9..3ff99812f 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -563,7 +563,7 @@ void encod_gen_voic_ivas_fx( Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); /*Q_new*/ find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, - res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); + res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); q_h1 = sub( 14, norm_s( h1_fx[0] ) ); Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index e87462988..bfdf46ea0 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -722,7 +722,7 @@ void enc_pit_exc_ivas_fx( /* condition on target (compared to float) has been put outside the loop */ find_targets_ivas_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, - res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); + res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2, L_subfr, sub( 11, q_h1 ) ); /*Q11*/ diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index c92e1b6db..dde834b2b 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -547,7 +547,7 @@ Word16 encod_tran_ivas_fx( find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, - res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); + res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); q_h1 = sub( 14, norm_s( h1[0] ) ); Copy_Scale_sig( h1, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 62ea723a3..d019bf474 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -422,14 +422,14 @@ Word16 inov_encode_ivas_fx( { acelpautoc = 1; move16(); - cb_shape_fx(1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr(add(pt_pitch, 26), 6), 0, L_SUBFR); + cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_SUBFR ); /* h2: Q11, Rw: (Rw_e)Q */ - /* Rw_e = */ E_ACELP_hh_corr(h2, Rw, L_SUBFR, 3); + /* Rw_e = */ E_ACELP_hh_corr( h2, Rw, L_SUBFR, 3 ); - E_ACELP_conv(xn2, h2, cn); + E_ACELP_conv( xn2, h2, cn ); /* dn_e -> Rw_e*Q_xn */ - /*dn_e = */ E_ACELP_toeplitz_mul_fx(Rw, cn, dn, L_SUBFR, 1); + /*dn_e = */ E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); Qdn = Qcn; move16(); } @@ -446,17 +446,16 @@ Word16 inov_encode_ivas_fx( corr_xh_ivas_fx( xn2, Qxn, dn, &Qdn, h2, L_subfr ); // Q(dn) = Q_new+1 IF( LT_16( Qdn, Qcn ) ) { - scale_sig( cn, L_subfr, sub(Qdn, Qcn) ); + scale_sig( cn, L_subfr, sub( Qdn, Qcn ) ); Qcn = Qdn; move16(); } ELSE { - scale_sig( dn, L_subfr, sub(Qcn, Qdn) ); + scale_sig( dn, L_subfr, sub( Qcn, Qdn ) ); Qdn = Qcn; move16(); } - } /*-----------------------------------------------------------------* -- GitLab From 0a393ee24aa2a754f068ff36f72e760f812482ba Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Wed, 7 May 2025 08:24:39 +0200 Subject: [PATCH 1173/1221] removed the pop_wmops() --- lib_enc/ivas_cpe_enc_fx.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index 19a850a89..d0a33ed09 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -336,7 +336,6 @@ ivas_error ivas_cpe_enc_fx( &q_band_energies_LR, NULL, NULL, NULL, Q_inp, Q_buffer, Q_add, &front_create_flag ) ), IVAS_ERR_OK ) ) { - pop_wmops(); return error; } @@ -370,7 +369,6 @@ ivas_error ivas_cpe_enc_fx( *----------------------------------------------------------------*/ IF( ( error = stereo_memory_enc_fx( hCPE, input_Fs, max_bwidth, ivas_format, st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) { - pop_wmops(); return error; } @@ -381,7 +379,6 @@ ivas_error ivas_cpe_enc_fx( IF( ( error = stereo_set_tdm_fx( hCPE, input_frame, sts[1]->q_inp32 ) ) != IVAS_ERR_OK ) { - pop_wmops(); return error; } @@ -919,7 +916,6 @@ ivas_error ivas_cpe_enc_fx( move16(); IF( error != IVAS_ERR_OK ) { - pop_wmops(); return error; } } @@ -994,7 +990,6 @@ ivas_error ivas_cpe_enc_fx( igf = getIgfPresent_fx( sts[n]->element_mode, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->rf_mode ); /* Q0 */ IF( ( error = IGF_Reconfig_fx( &sts[n]->hIGFEnc, igf, 0, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->element_mode, sts[n]->rf_mode ) ) != IVAS_ERR_OK ) { - pop_wmops(); return error; } } @@ -1023,7 +1018,6 @@ ivas_error ivas_cpe_enc_fx( { IF( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ) != IVAS_ERR_OK ) { - pop_wmops(); return error; } } @@ -1200,7 +1194,6 @@ ivas_error ivas_cpe_enc_fx( } IF( NE_32( ( error = ivas_core_enc_fx( NULL, hCPE, st_ivas->hMCT, n_CoreChannels, old_inp_12k8_16fx, old_inp_16k_16fx, Q_new, ener_fx, A_fx, Aw_fx, epsP_fx, epsP_fx_q, lsp_new_fx, lsp_mid_fx, vad_hover_flag, attack_flag, realBuffer_fx, imagBuffer_fx, q_re_im_buf, old_wsp_fx, e_old_wsp, loc_harm, cor_map_sum_fx, vad_flag_dtx, enerBuffer_fx, enerBuffer_fx_exp, fft_buff_fx, tdm_SM_or_LRTD_Pri, ivas_format, 0 ) ), IVAS_ERR_OK ) ) { - pop_wmops(); return error; } -- GitLab From 59ddeb18819bb6400722762c280b2ceb809eab3a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 14:54:52 +0530 Subject: [PATCH 1174/1221] Bug fixes in front vad and pre-proc front functions --- lib_enc/analy_sp_fx.c | 2 +- lib_enc/ivas_core_pre_proc_front_fx.c | 83 ++++++++------------------- lib_enc/ivas_front_vad_fx.c | 6 +- 3 files changed, 27 insertions(+), 64 deletions(-) diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index 49bb03f57..dc59ec752 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -620,7 +620,7 @@ void ivas_analy_sp_fx( *q_fr_bands = add( *q_fr_bands, exp ); move16(); - exp = sub( getScaleFactor32( band_energies, 2 * NB_BANDS ), 1 ); + exp = getScaleFactor32( band_energies, 2 * NB_BANDS ); scale_sig32( band_energies, 2 * NB_BANDS, exp ); /* q_band_energies + exp */ *q_band_energies = add( *q_band_energies, exp ); move16(); diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 4a8c4edd2..e883d9ec1 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -945,78 +945,41 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( st->idchan == 0 || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { - test(); - test(); - IF( EQ_16( element_mode, IVAS_CPE_TD ) && lr_vad_enabled && band_energies_LR_fx != NULL ) + Word16 norm; + norm = L_norm_arr( st->hFdCngEnc->msPeriodog_fx, NPART ); + IF( NE_16( norm, Q31 ) ) { - Word16 normmsPeriodog_fx = Q31, zero_flag = 0; - move16(); - move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msPeriodog_fx, NPART ); - IF( zero_flag ) - { - normmsPeriodog_fx = getScaleFactor32( st->hFdCngEnc->msPeriodog_fx, NPART ); - move16(); - } - st->hFdCngEnc->msPeriodog_fx_exp_cldfb = sub( 31, normmsPeriodog_fx ); - st->hFdCngEnc->msPeriodog_fx_exp_fft = sub( 31, normmsPeriodog_fx ); + scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, norm ); // exp:st->hFdCngEnc->msPeriodog_fx_exp-norm + st->hFdCngEnc->msPeriodog_fx_exp = sub( st->hFdCngEnc->msPeriodog_fx_exp, norm ); + st->hFdCngEnc->msPeriodog_fx_exp_cldfb = sub( st->hFdCngEnc->msPeriodog_fx_exp_cldfb, norm ); + st->hFdCngEnc->msPeriodog_fx_exp_fft = sub( st->hFdCngEnc->msPeriodog_fx_exp_fft, norm ); move16(); move16(); - Scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, normmsPeriodog_fx ); /* exp(st->hFdCngEnc->msPeriodog_fx_exp - normmsPeriodog_fx) */ - st->hFdCngEnc->msPeriodog_fx_exp = sub( st->hFdCngEnc->msPeriodog_fx_exp, normmsPeriodog_fx ); - Word16 msNoiseEst_Q = Q31; move16(); + } + norm = L_norm_arr( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + IF( NE_16( norm, Q31 ) ) + { + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, norm ); // exp:st->hFdCngEnc->msNoiseEst_old_fx_exp-norm + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, norm ); move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); - IF( zero_flag ) - { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); - scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ - st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); - move16(); - } + } + + test(); + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) && lr_vad_enabled && band_energies_LR_fx != NULL ) + { perform_noise_estimation_enc_ivas_fx( band_energies_LR_fx, sub( Q31, band_energies_LR_fx_q ), enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); } ELSE { - Word16 normmsPeriodog_fx = Q31, zero_flag = 0; - move16(); - move16(); - shift = getScaleFactor32( band_energies_fx, 2 * NB_BANDS ); - scale_sig32( band_energies_fx, 2 * NB_BANDS, shift ); - q_band_energies = add( q_band_energies, shift ); - - zero_flag = get_zero_flag( st->hFdCngEnc->msPeriodog_fx, NPART ); /* Q0 */ - IF( zero_flag ) - { - normmsPeriodog_fx = getScaleFactor32( st->hFdCngEnc->msPeriodog_fx, NPART ); - } - st->hFdCngEnc->msPeriodog_fx_exp_cldfb = sub( 31, normmsPeriodog_fx ); - st->hFdCngEnc->msPeriodog_fx_exp_fft = sub( 31, normmsPeriodog_fx ); - move16(); - move16(); - Scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, normmsPeriodog_fx ); /* exp(st->hFdCngEnc->msPeriodog_fx_exp - normmsPeriodog_fx)*/ - st->hFdCngEnc->msPeriodog_fx_exp = sub( st->hFdCngEnc->msPeriodog_fx_exp, normmsPeriodog_fx ); - move16(); - Word16 msNoiseEst_Q = Q31; - move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); /* Q0 */ - IF( zero_flag ) + norm = L_norm_arr( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); + IF( NE_16( norm, Q31 ) ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); - scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ - st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + scale_sig32( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN, norm ); // exp:st->hFdCngEnc->hFdCngCom->exp_cldfb_periodog-norm + st->hFdCngEnc->hFdCngCom->exp_cldfb_periodog = sub( st->hFdCngEnc->hFdCngCom->exp_cldfb_periodog, norm ); move16(); } - zero_flag = get_zero_flag( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); /* Q0 */ - Word16 normmsperiodog = 31; - move16(); - IF( zero_flag ) - { - normmsperiodog = getScaleFactor32( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); - } - st->hFdCngEnc->hFdCngCom->exp_cldfb_periodog = sub( 31, normmsperiodog ); - move16(); perform_noise_estimation_enc_ivas_fx( band_energies_fx, sub( Q31, q_band_energies ), enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); } diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index fff68e5a2..ab090edb8 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -241,9 +241,9 @@ ivas_error front_vad_fx( PREEMPH_FX( hFrontVad->buffer_12k8_fx + L_FFT / 2, PREEMPH_FAC, L_FRAME, &hFrontVad->mem_preemph_fx ); - Q_new = add( sub( Q_inp, Qband ), Q_add ); - Scale_sig( hFrontVad->buffer_12k8_fx, L_FFT / 2, sub( Q_new, Q_buffer[n] ) ); /* Q_new */ - Scale_sig( hFrontVad->buffer_12k8_fx + L_FFT / 2, 384 - L_FFT / 2, sub( Q_new, add( Q_inp, Qband ) ) ); /* Q_new */ + Q_new = s_min( add( add( Q_inp, Qband ), Q_add ), Q_buffer[n] ); + scale_sig( hFrontVad->buffer_12k8_fx, L_FFT / 2, sub( Q_new, Q_buffer[n] ) ); /* Q_new */ + scale_sig( hFrontVad->buffer_12k8_fx + L_FFT / 2, 3 * L_FRAME / 2 - L_FFT / 2, sub( Q_new, add( Q_inp, Qband ) ) ); /* Q_new */ Q_buffer[n] = Q_new; move16(); -- GitLab From beed21040591e3ca90fe6c83970e3e67cc2df37b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 10:57:48 +0530 Subject: [PATCH 1175/1221] Fix for 3GPP issue 1542: One bit systematic error between BASOP and float decoder MASA EXT output of energy ratios Link #1542 --- lib_dec/ivas_masa_dec_fx.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index dec4d3465..039ad4137 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -2572,13 +2572,9 @@ static void create_masa_ext_out_meta_fx( { FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) { - IF( EQ_32( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], ONE_IN_Q30 ) ) - { - hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf]--; - } - UWord8 tmp = (UWord8) L_shr( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8 ); // Q8 + UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); //Q0 move16(); - extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q8 + extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q0 move16(); } } @@ -2637,12 +2633,8 @@ static void create_masa_ext_out_meta_fx( move16(); FOR( dir = 0; dir < numDirections; dir++ ) { - /* todo: not optimal, but less invasive */ - IF( EQ_32( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], ONE_IN_Q30 ) ) - { - hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf]--; - } - UWord8 tmp = (UWord8) L_shr( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8 ); // Q8 + + UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); //Q0 move16(); extOutMeta->diffuseToTotalRatio[sf][b_new] = (UWord8) sub( extOutMeta->diffuseToTotalRatio[sf][b_new], tmp ); // Q8 move16(); -- GitLab From fb5f45affe1237b29fe3a4fbff3c636209363555 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 11:44:11 +0530 Subject: [PATCH 1176/1221] Clang formatting changes --- lib_dec/ivas_masa_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index 039ad4137..36900867e 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -2572,7 +2572,7 @@ static void create_masa_ext_out_meta_fx( { FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) { - UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); //Q0 + UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); // Q0 move16(); extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q0 move16(); @@ -2634,7 +2634,7 @@ static void create_masa_ext_out_meta_fx( FOR( dir = 0; dir < numDirections; dir++ ) { - UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); //Q0 + UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); // Q0 move16(); extOutMeta->diffuseToTotalRatio[sf][b_new] = (UWord8) sub( extOutMeta->diffuseToTotalRatio[sf][b_new], tmp ); // Q8 move16(); -- GitLab From 1f7ede4373cf94a1851008823c4dbe6bfaf0905b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 16:43:09 +0530 Subject: [PATCH 1177/1221] Fix for new stream shared --- lib_com/prot_fx.h | 6 ++++++ lib_com/tools_fx.c | 24 ++++++++++++++++++++++++ lib_dec/ivas_qmetadata_dec_fx.c | 25 ++++++++++++++++--------- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index f422d5e50..912b3b713 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9969,6 +9969,12 @@ Word16 usdequant_fx( /* Qx*/ const Word16 delta /* i: quantization step Qy*/ ); +Word32 usdequant32_fx( /* Qx*/ + const Word16 idx, /* i: quantizer index Q0*/ + const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/ + const Word32 delta /* i: quantization step Qy*/ +); + Word16 usquant_fx( /* o: index of the winning codeword */ const Word16 x, /* i: scalar value to quantize Qx*/ Word16 *xq, /* o: quantized value Qx*/ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 44a86b0eb..a4c0c5484 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -284,6 +284,30 @@ Word16 usdequant_fx( /* Qx*/ return ( g ); } +Word32 usdequant32_fx( /* Qx*/ + const Word16 idx, /* i: quantizer index Q0*/ + const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/ + const Word32 delta /* i: quantization step Qx-1*/ +) +{ + Word32 g; + Word64 L_tmp; + + /*g = idx * delta + qlow;*/ + L_tmp = W_deposit32_l( qlow ); /*Qx */ + L_tmp = W_mac_32_16( L_tmp, delta, idx ); + IF( GE_64( L_tmp, MAX_32 ) ) + { + g = MAX_32; + move32(); + } + ELSE + { + g = W_extract_l(L_tmp); /*Qx */ + } + return ( g ); +} + /*-------------------------------------------------------------------* * usquant() * diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index 6e36c7765..c1be6caf8 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -72,8 +72,7 @@ static Word16 read_coherence_data_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVA static Word16 ivas_qmetadata_raw_decode_dir_512_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const Word16 nbands, const Word16 start_band, const SPHERICAL_GRID_DATA *sph_grid16 ); static Word16 read_surround_coherence( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData ); static ivas_error read_huf( Word16 *num_bits_read, const UWord16 *bitstream, UWord16 *out, const Word16 start_pos, const Word16 len, const Word16 *huff_code, const Word16 max_len ); -const Word16 inv_dfRatio_qsteps[9] = { 0, 0, ONE_IN_Q14, 0, 5461, 0, 0, 0, 2341 }; // Q14 - +const Word32 inv_dfRatio_qsteps[9] = { 0, 0, ONE_IN_Q30, 0, 357913941, 0, 0, 0, 153391689 }; // Q30 /*-----------------------------------------------------------------------* * Global function definitions @@ -223,7 +222,7 @@ Word16 ivas_qmetadata_dec_decode( IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { Word32 diffRatio_fx, dir1ratio_fx, dir2ratio_fx; - Word16 dfRatio_fx; + Word32 dfRatio_fx; Word16 dfRatio_qsteps; diffRatio_fx = diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; // Q30 @@ -233,17 +232,25 @@ Word16 ivas_qmetadata_dec_decode( /* already encoded as total and ratios in HO-DirAC */ IF( hodirac_flag ) { - - dfRatio_fx = usdequant_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q15 + dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q31 dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx ); - dir2ratio_fx = L_shl( (Word32) dfRatio_fx, Q15 ); /*Q30*/ + dir2ratio_fx = L_shr( dfRatio_fx, 1 ); /*Q30*/ } ELSE { - dfRatio_fx = usdequant_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], shr( MAX_16, 1 ), shr( inv_dfRatio_qsteps[dfRatio_qsteps], 1 ) ); // Q15 + IF( EQ_16( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], sub( dfRatio_qsteps, 1 ) ) ) + { + dfRatio_fx = MAX_32; // Q31 + move16(); + dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx ); // Q30 + } + ELSE + { + dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], L_shr( MAX_32, 1 ), L_shr( inv_dfRatio_qsteps[dfRatio_qsteps], 1 ) ); // Q31 + dir1ratio_fx = Mpy_32_32( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30 + } - dir1ratio_fx = Mpy_32_16_1( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30 - dir2ratio_fx = L_sub( L_sub( ONE_IN_Q30, diffRatio_fx ), dir1ratio_fx ); // Q30 + dir2ratio_fx = L_sub( L_sub( ONE_IN_Q30, diffRatio_fx ), dir1ratio_fx ); // Q30 } /* Requantize the 1 - dirRatio separately for each direction to obtain inverted dirRatio index. These are used in further decoding. */ -- GitLab From 1497f24e8bc2e79aeae636a3430394d5c6828c7b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 16:47:36 +0530 Subject: [PATCH 1178/1221] Clang formatting changes --- lib_com/prot_fx.h | 6 +++--- lib_com/tools_fx.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 912b3b713..9b78b44d8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9970,9 +9970,9 @@ Word16 usdequant_fx( /* Qx*/ ); Word32 usdequant32_fx( /* Qx*/ - const Word16 idx, /* i: quantizer index Q0*/ - const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/ - const Word32 delta /* i: quantization step Qy*/ + const Word16 idx, /* i: quantizer index Q0*/ + const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/ + const Word32 delta /* i: quantization step Qy*/ ); Word16 usquant_fx( /* o: index of the winning codeword */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index a4c0c5484..14a97a034 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -303,7 +303,7 @@ Word32 usdequant32_fx( /* Qx*/ } ELSE { - g = W_extract_l(L_tmp); /*Qx */ + g = W_extract_l( L_tmp ); /*Qx */ } return ( g ); } -- GitLab From 68e750905d1ede809013fd7fd2a93764f9897fc7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 6 May 2025 21:23:11 +0530 Subject: [PATCH 1179/1221] Fix for 3GPP issue 1449: OMASA Complexity measurement crashes Link #1449 --- lib_enc/ivas_masa_enc_fx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib_enc/ivas_masa_enc_fx.c b/lib_enc/ivas_masa_enc_fx.c index ceb5dec1d..9d0579d12 100644 --- a/lib_enc/ivas_masa_enc_fx.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -2463,19 +2463,23 @@ static void reduce_metadata_further_fx( } /* Determine if to merge over frequency instead of time */ - meanRatio = 0; - move32(); + W_tmp = 0; + move64(); FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { FOR( band = 0; band < numCodingBands; band++ ) { - meanRatio = L_add( meanRatio, Mpy_32_32( hqmetadata->q_direction[0].band_data[band].energy_ratio_fx[sf], energy[sf][band] ) ); // hMasa->data.q_energy - 1 + W_tmp = W_mac_32_16( W_tmp, Mpy_32_32( hqmetadata->q_direction[0].band_data[band].energy_ratio_fx[sf], energy[sf][band] ), 1 ); // hMasa->data.q_energy } } + shift = W_norm( W_tmp ); + meanRatio = W_extract_h( W_shl( W_tmp, shift ) ); // Q:sub( add( hMasa->data.q_energy, shift ), 32 ) + shift = sub( 31, sub( add( hMasa->data.q_energy, shift ), 32 ) ); + IF( totalEnergySum != 0 ) { meanRatio = BASOP_Util_Divide3232_Scale_newton( meanRatio, totalEnergySum, &exp ); - exp = add( add( exp, 1 ), tmp2 ); // 31 - (hMasa->data.q_energy - 1) - 31 - hMasa->data.q_energy - tmp2 => 1 + tmp2 + exp = add( exp, sub( shift, sub( 31, add( hMasa->data.q_energy, tmp2 ) ) ) ); // exp + (shift - (31 - hMasa->data.q_energy - tmp2)) => 1 + tmp2 } ELSE { -- GitLab From 4fc3bd03def4d5cfdc82c15b2772ec97bf5f2c65 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 10:23:34 +0530 Subject: [PATCH 1180/1221] Fix for crash in acelp path --- lib_enc/set_impulse_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/set_impulse_fx.c b/lib_enc/set_impulse_fx.c index 9ad5f4a2c..d4dd73abe 100644 --- a/lib_enc/set_impulse_fx.c +++ b/lib_enc/set_impulse_fx.c @@ -285,10 +285,10 @@ static void convolve_tc_fx( L_sum = L_mult( g[0], h[n] ); /* Qx */ FOR( i = 1; i < len; i++ ) { - L_sum = L_mac( L_sum, g[i], h[n - i] ); /* Qx + 16 */ + L_sum = L_mac_sat( L_sum, g[i], h[n - i] ); /* Qx + 16 */ } - y[n] = round_fx( L_sum ); /* Qx */ + y[n] = round_fx_sat( L_sum ); /* Qx */ } } /*-------------------------------------------------------------------* -- GitLab From e123cac9ebda717c88eb823b15af0d206d4a6e34 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 16:54:37 +0530 Subject: [PATCH 1181/1221] Fix for decoder crash --- lib_dec/swb_tbe_dec_fx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 890e0e5c8..a541ebf7b 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -618,6 +618,7 @@ void ivas_wb_tbe_dec_fx( move16(); Word32 dummy2[HILBERT_MEM_SIZE]; Word16 f, inc; + Word64 W_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -853,17 +854,20 @@ void ivas_wb_tbe_dec_fx( move16(); /* restrict this to 21 due to the Q factor requireemnt of the random number generator (keep 1 bit headroom) */ } - prev_pow = 0; - move32(); + W_tmp = 0; + move64(); IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), 31 + 16 ); - prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ + W_tmp = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { - prev_pow = L_mac0( prev_pow, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ + W_tmp = W_mac_16_16( W_tmp, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /*Q(2*(st_fx->prev_Q_bwe_exc-16 + 1))*/ } + exp = W_norm( W_tmp ); + prev_pow = W_extract_h( W_shl( W_tmp, exp ) ); + exp = sub( add( add( shl( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), 1 ), exp ), 32 ); rescale_genWB_mem( st_fx, sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) ); @@ -901,7 +905,7 @@ void ivas_wb_tbe_dec_fx( } Lscale = root_a_over_b_fx( curr_pow, shl_r( Q_bwe_exc_ext, 1 ), prev_pow, - shl_r( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), &exp ); + exp, &exp ); FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) { -- GitLab From 813cd3820153fdcea08c1f8ff475b87afdf5e1ca Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 7 May 2025 17:52:15 +0530 Subject: [PATCH 1182/1221] Fix for 3GPP issue 1566: Complexity measurement crashes: MC7_1 encoder (core dumped) Link #1566 --- lib_dec/tonalMDCTconcealment_fx.c | 33 +++++-------------- lib_enc/ivas_mc_param_enc_fx.c | 17 ++++++++-- lib_rend/ivas_dirac_output_synthesis_dec_fx.c | 5 +-- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index b45b78ad1..5afceff55 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -1563,9 +1563,12 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( move16(); Word32 y = concealment_noise[l]; // concealment_noise_e move32(); - last_block_nrg_correct = L_add( last_block_nrg_correct, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // exp = 2 * x_exp + ld - y = L_negate( Mpy_32_32( y, y ) ); // Q31-2* concealment_noise_e - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, y, 2 * concealment_noise_e, &hTonalMDCTConc->curr_noise_nrg_exp ); // Q31- hTonalMDCTConc->curr_noise_nrg_exp + shift1 = norm_l( y ); + y = L_shl( y, shift1 ); + + last_block_nrg_correct = L_add( last_block_nrg_correct, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // exp = 2 * x_exp + ld + y = L_negate( Mpy_32_32( y, y ) ); // Q31-(2* concealment_noise_e + shift1) + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, y, shl( sub( concealment_noise_e, shift1 ), 1 ), &hTonalMDCTConc->curr_noise_nrg_exp ); // Q31- hTonalMDCTConc->curr_noise_nrg_exp move32(); } } @@ -1631,29 +1634,9 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( /* actual fadeout is done in this case */ ELSE { - Word32 num, den; - Word16 exp_num, exp_den; - - exp_num = cngLevelBackgroundTrace_bfi_e; - move16(); - exp_den = hTonalMDCTConc->curr_noise_nrg_exp; - move16(); + tmp = BASOP_Util_Divide3232_Scale( cngLevelBackgroundTrace_bfi, hTonalMDCTConc->curr_noise_nrg, &exp ); + exp = add( exp, sub( cngLevelBackgroundTrace_bfi_e, hTonalMDCTConc->curr_noise_nrg_exp ) ); - ld = norm_l( cngLevelBackgroundTrace_bfi ); - num = L_shl( cngLevelBackgroundTrace_bfi, ld ); // Q15 - exp_num + ld - exp_num = sub( exp_num, ld ); - ld = norm_l( hTonalMDCTConc->curr_noise_nrg ); - den = L_shl( hTonalMDCTConc->curr_noise_nrg, ld ); // Q15 - exp_den + ld - exp_den = sub( exp_den, ld ); - - exp = sub( exp_num, exp_den ); - - IF( GT_32( num, den ) ) - { - num = L_shr( num, 1 ); // Q31- exp -1 - exp = add( exp, 1 ); - } - tmp = div_l( num, round_fx( den ) ); tmp = Sqrt16( tmp, &exp ); g = mult_r( g, tmp ); // exponent of g = exp diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 22eacdb32..0c996b25a 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1613,9 +1613,22 @@ static void ivas_param_mc_quantize_ilds_fx( { dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e ); } + /* ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) ); */ + IF( tot_ener_fx == 0 ) + { + tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63 + tot_ener_e = -32; + move32(); + move16(); + } + IF( dmx_ener_fx == 0 ) + { + dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63 + dmx_ener_e = -32; + move32(); + move16(); + } - tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, EPSILON_FX, 0, &tot_ener_e ); - dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, EPSILON_FX, 0, &dmx_ener_e ); L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) ); tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e ); ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e ); // Q25 diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 9212e3d23..622ebf89a 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -4016,10 +4016,11 @@ void ivas_lfe_synth_with_filters_fx( } ELSE { + Flag overFlow; lfeGain_fx = extract_h( BASOP_Util_Divide3232_Scale_newton( hMasaLfeSynth->targetEneLfeSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->transportEneSmooth_fx ), &lfeGain_fx_exp ) ); /*Q(31-(lfeGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneLfeSmooth_q))-16*/ lfeGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneLfeSmooth_q ), lfeGain_fx_exp ); - lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp ); // Q15-lfeGain_fx_exp - lfeGain_fx = shl_r( lfeGain_fx, lfeGain_fx_exp ); // Q15 + lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp ); // Q15-lfeGain_fx_exp + lfeGain_fx = shl_ro( lfeGain_fx, lfeGain_fx_exp, &overFlow ); // Q15 } IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( hMasaLfeSynth->targetEneTransSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneTransSmooth_q ), /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ) ), 1 ) ) { -- GitLab From 0288d39e52a9dc7ad3e2d5fcba72a7ddbb4bd332 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 8 May 2025 16:18:54 +0530 Subject: [PATCH 1183/1221] Fix for complexity measurement CI pipeline crashes --- lib_com/gs_noisefill_fx.c | 3 +- lib_com/lpc_tools_fx.c | 2 +- lib_dec/tonalMDCTconcealment_fx.c | 43 ++++++----------------- lib_rend/ivas_objectRenderer_hrFilt_fx.c | 2 +- lib_rend/ivas_objectRenderer_sfx_fx.c | 20 +++++------ lib_rend/ivas_objectRenderer_sources_fx.c | 20 +++++------ lib_rend/ivas_prot_rend_fx.h | 6 ++-- lib_rend/ivas_stat_rend.h | 4 +-- 8 files changed, 40 insertions(+), 60 deletions(-) diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index 61aa1333c..1198fb793 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -1418,7 +1418,8 @@ void highband_exc_dct_in_ivas_fx( envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, *Q_exc, &Q_hb_exc ); #ifdef REMOVE_EVS_DUPLICATES test(); - IF( GT_16( *Q_exc, Q_hb_exc ) && GT_16( element_mode, EVS_MONO ) ) + test(); + IF( GT_16( *Q_exc, Q_hb_exc ) && GT_16( element_mode, EVS_MONO ) && exc_wo_nf != NULL ) #else IF( GT_16( *Q_exc, Q_hb_exc ) ) #endif diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index bde05b4f4..1035f017a 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -1114,7 +1114,7 @@ static void lsp_reorder( { lsp[i] = s_max( lsp[i], lsp_min ); move16(); - lsp_min = add( lsp[i], min_dist ); + lsp_min = add_sat( lsp[i], min_dist ); } /* Reverify the LSF ordering and minimum GAP in the reverse order (security) */ diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 5afceff55..f33a6c84f 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -450,17 +450,16 @@ void TonalMDCTConceal_SaveFreqSignal_ivas_fx( IF( ( nNewSamples > 0 ) && ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) ) { /* Store new data */ - hTonalMDCTConc->last_block_nrg = 0; - move32(); - + Word64 W_tmp = 0; + move64(); FOR( i = 0; i < infoIGFStartLine; i++ ) { - Word16 tmp = extract_h( mdctSpectrum[i] ); - hTonalMDCTConc->last_block_nrg = L_add( hTonalMDCTConc->last_block_nrg, - L_shr( L_mult0( tmp, tmp ), 16 ) ); // Q31-last_block_nrg_exp - move32(); + W_tmp = W_mac_32_16( W_tmp, Mpy_32_32( mdctSpectrum[i], mdctSpectrum[i] ), 1 ); // exp: mdctSpectrum_exp + mdctSpectrum_exp - 1 } - hTonalMDCTConc->last_block_nrg_exp = sub( 31, sub( shl( sub( 15, mdctSpectrum_exp ), 1 ), 16 ) ); + s = W_norm( W_tmp ); + hTonalMDCTConc->last_block_nrg = W_extract_h( W_shl( W_tmp, s ) ); // exp:add( sub( shl( mdctSpectrum_exp, 1 ), s ), 31 ) + move32(); + hTonalMDCTConc->last_block_nrg_exp = add( sub( shl( mdctSpectrum_exp, 1 ), s ), 31 ); move16(); /* Store new data */ @@ -1765,32 +1764,12 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( test(); IF( GT_32( hTonalMDCTConc->faded_signal_nrg, 0 ) && flag ) { - Word16 num_exp, den_exp; - Word32 num, den; + Word16 num_exp; + Word32 num; num = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->last_block_nrg, hTonalMDCTConc->last_block_nrg_exp, L_negate( last_block_nrg_correct ), last_block_nrg_correct_e, &num_exp ); // Q31-num_exp - - den = hTonalMDCTConc->faded_signal_nrg; // Q31 - hTonalMDCTConc->faded_signal_nrg_exp - move32(); - den_exp = hTonalMDCTConc->faded_signal_nrg_exp; - move16(); - - ld = norm_l( num ); - num = L_shl( num, ld ); // Q31-num_exp + ld - num_exp = sub( num_exp, ld ); - - ld = norm_l( den ); - den = L_shl( den, ld ); // Q31-den_exp + ld - den_exp = sub( den_exp, ld ); - - exp = sub( num_exp, den_exp ); - - IF( GT_32( num, den ) ) - { - num = L_shr( num, 1 ); // Q31- exp -1 - exp = add( exp, 1 ); - } - tmp = div_l( num, extract_h( den ) ); + tmp = BASOP_Util_Divide3232_Scale( num, hTonalMDCTConc->faded_signal_nrg, &exp ); + exp = add( exp, sub( num_exp, hTonalMDCTConc->faded_signal_nrg_exp ) ); tmp = Sqrt16( tmp, &exp ); FOR( i = 0; i < crossOverFreq; i++ ) diff --git a/lib_rend/ivas_objectRenderer_hrFilt_fx.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c index 30bf8f00a..a098aaa25 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt_fx.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -97,7 +97,7 @@ ivas_error TDREND_REND_RenderSourceHRFilt_fx( TDREND_firfilt_fx( RightOutputFrame_fx, Src_p->hrf_right_prev_fx, right_filter_e, hrf_right_delta_fx, intp_count, Src_p->mem_hrf_right_fx, subframe_length, Src_p->filterlength, Src_p->Gain_fx, Src_p->prevGain_fx ); Src_p->prevGain_fx = Src_p->Gain_fx; - move16(); + move32(); /* Copy to accumulative output frame */ v_add_32( LeftOutputFrame_fx, output_buf_fx[0], output_buf_fx[0], subframe_length ); // Same Q as Src_p->InputFrame_p_fx Q11 diff --git a/lib_rend/ivas_objectRenderer_sfx_fx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c index 210706d5b..a570273cf 100644 --- a/lib_rend/ivas_objectRenderer_sfx_fx.c +++ b/lib_rend/ivas_objectRenderer_sfx_fx.c @@ -278,8 +278,8 @@ void TDREND_firfilt_fx( Word32 *mem_fx, /* i/o: filter memory Qx */ const Word16 subframe_length, /* i : Length of signal Q0 */ const Word16 filterlength, /* i : Filter length Q0 */ - const Word16 Gain_fx, /* i : Gain Q14 */ - const Word16 prevGain_fx /* i : Previous gain Q14 */ + const Word32 Gain_fx, /* i : Gain Q30 */ + const Word32 prevGain_fx /* i : Previous gain Q30 */ ) { /* NOTE: this function is implemented with the assumption that the exponent/Q-factor of input signal will not change. */ @@ -289,15 +289,15 @@ void TDREND_firfilt_fx( Word32 *p_filter_fx; // exp(filter_e) Word16 i, j; Word32 tmp_fx; - Word16 step_fx /* Q15 */, gain_tmp_fx /* Q15 */, gain_delta_fx /* Q14 */; + Word32 step_fx /* Q31 */, gain_tmp_fx /* Q31 */, gain_delta_fx /* Q30 */; Word16 tmp_e; Word64 tmp64_fx; - gain_delta_fx = sub( Gain_fx, prevGain_fx ); // Q14 - step_fx = BASOP_Util_Divide1616_Scale( gain_delta_fx, subframe_length, &tmp_e ); // exp(tmp_e) - tmp_e = sub( tmp_e, Q14 ); - step_fx = shl_sat( step_fx, tmp_e ); // Q15 - gain_tmp_fx = shl_sat( prevGain_fx, 1 ); // Q15 + gain_delta_fx = L_sub( Gain_fx, prevGain_fx ); // Q30 + step_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( gain_delta_fx, subframe_length, &tmp_e ) ); // exp(tmp_e) + tmp_e = sub( tmp_e, Q30 ); + step_fx = L_shl_sat( step_fx, tmp_e ); // Q31 + gain_tmp_fx = L_shl_sat( prevGain_fx, 1 ); // Q31 /* Handle memory */ p_signal_fx = buffer_fx + sub( filterlength, 1 ); // Qx @@ -328,8 +328,8 @@ void TDREND_firfilt_fx( tmp_fx = W_extract_h( tmp64_fx ); // Qx /* Apply linear gain interpolation in case of abrupt gain changes */ - gain_tmp_fx = add( gain_tmp_fx, step_fx ); // Q15 - signal_fx[i] = Mpy_32_16_1( tmp_fx, gain_tmp_fx ); // Qx + gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ + signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx move32(); IF( LT_16( i, intp_count ) ) { diff --git a/lib_rend/ivas_objectRenderer_sources_fx.c b/lib_rend/ivas_objectRenderer_sources_fx.c index 7e35b80b2..cdb2d9847 100644 --- a/lib_rend/ivas_objectRenderer_sources_fx.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -275,8 +275,8 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( /* o : Length of filters */ // Q0 Word16 *itd, /* o : ITD value */ // Q0 - Word16 *Gain, - /* o : Gain value */ // Q14 + Word32 *Gain, + /* o : Gain value */ // Q30 TDREND_SRC_t *Src_p, /* i/o: Source pointer */ const Word16 subframe_update_flag ) { @@ -368,8 +368,8 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( /* Update total gains */ - *Gain = extract_h( L_shl( Mpy_32_32( L_shl( L_mult( *SrcRend_p->SrcGain_p_fx, *SrcRend_p->DirGain_p_fx ), 1 ), L_shl( L_mult( *SrcRend_p->DistGain_p_fx, hBinRendererTd->Gain_fx ), 1 ) ), 1 ) ); // Q14 - move16(); + *Gain = L_shl( Mpy_32_32( L_shl( L_mult( *SrcRend_p->SrcGain_p_fx, *SrcRend_p->DirGain_p_fx ), 1 ), L_shl( L_mult( *SrcRend_p->DistGain_p_fx, hBinRendererTd->Gain_fx ), 1 ) ), 1 ); // Q30 + move32(); /* Delta for interpolation, in case the angular step exceeds MAX_ANGULAR_STEP */ Word32 ele_tmp = Src_p->elev_prev_fx; // Q22 move32(); @@ -417,8 +417,8 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( { *itd = 0; // Q0 move16(); - *Gain = ONE_IN_Q14; // Q14 - move16(); + *Gain = ONE_IN_Q30; // Q30 + move32(); set32_fx( hrf_left, 0, *filterlength ); set32_fx( hrf_right, 0, *filterlength ); hrf_left[0] = L_shr( L_add( SrcSpatial_p->Pos_p_fx[1], ONE_IN_Q25 ), 1 ); // Q25 @@ -886,9 +886,9 @@ void TDREND_SRC_Init_fx( move32(); Src_p->elev_prev_fx = 0; // Q22 move32(); - Src_p->Gain_fx = ONE_IN_Q14; // Q14 - move16(); - Src_p->prevGain_fx = ONE_IN_Q14; // Q14 - move16(); + Src_p->Gain_fx = ONE_IN_Q30; // Q30 + move32(); + Src_p->prevGain_fx = ONE_IN_Q30; // Q30 + move32(); return; } diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 983c814aa..7cd547cb8 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -755,7 +755,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( Word16 *intp_count, /* o : Interpolation count */ Word16 *filterlength, /* o : Length of filters */ Word16 *itd, /* o : ITD value */ - Word16 *Gain, /* o : Gain value */ + Word32 *Gain, /* o : Gain value Q30 */ TDREND_SRC_t *Src_p, /* i/o: Source pointer */ const Word16 subframe_update_flag); @@ -842,8 +842,8 @@ void TDREND_firfilt_fx( Word32 *mem_fx, /* i/o: filter memory Qx */ const Word16 subframe_length, /* i : Length of signal */ const Word16 filterlength, /* i : Filter length */ - const Word16 Gain_fx, /* i : Gain Q14 */ - const Word16 prevGain_fx /* i : Previous gain Q14 */ + const Word32 Gain_fx, /* i : Gain Q30 */ + const Word32 prevGain_fx /* i : Previous gain Q30 */ ); diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 17474bfe7..90e4f5d69 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1259,8 +1259,8 @@ typedef struct Word16 hrf_right_prev_e; Word32 azim_prev_fx; Word32 elev_prev_fx; - Word16 Gain_fx; // Q14 - Word16 prevGain_fx; // Q14 + Word32 Gain_fx; // Q30 + Word32 prevGain_fx; // Q30 } TDREND_SRC_t; -- GitLab From e155b386f761bcf00066746bb25a1e599dce4efa Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 12 May 2025 14:56:02 +0530 Subject: [PATCH 1184/1221] Fix for 3GPP issue 1574: Complexity measurement crashes: ISM Link #1574 --- lib_dec/swb_tbe_dec_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index a541ebf7b..83c229a6b 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -6468,7 +6468,7 @@ void ivas_swb_tbe_dec_fx( exp_ener = norm_s( ener_fx ); tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ - prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ + prev_ener_ratio_fx = L_shr_sat( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ } IF( EQ_16( st->nbLostCmpt, 1 ) ) -- GitLab From 9dfd2133c045d7e5a0e3e8d465e78295ad0b2dc6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 12 May 2025 15:01:49 +0530 Subject: [PATCH 1185/1221] Clang formatting changes --- lib_dec/swb_tbe_dec_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 83c229a6b..bd8700063 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -6466,8 +6466,8 @@ void ivas_swb_tbe_dec_fx( { ener_fx = s_max( 1, ener_fx ); exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ prev_ener_ratio_fx = L_shr_sat( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ } -- GitLab From 8b5de0a80364e7b3dc2ed03fd0fd0a19ef9d4f90 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 12 May 2025 18:04:32 +0530 Subject: [PATCH 1186/1221] Fix for 3GPP issue 1337: energy mismatch when switching from ACELP to TCX Link #1337 --- lib_enc/swb_pre_proc_fx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 8991696e6..0e89e16c1 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -1068,8 +1068,9 @@ void swb_pre_proc_ivas_fx( { Word16 out_start_ind, out_end_ind; stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, new_swb_speech_fx, &out_start_ind, &out_end_ind, st->idchan, input_Fs, 32000, 0, NULL ); - Copy_Scale_sig32_16( new_swb_speech_fx - STEREO_DFT_OVL_MAX, new_swb_speech - STEREO_DFT_OVL_MAX, L_FRAME48k + STEREO_DFT_OVL_MAX, add( q_reImBuffer, 1 ) ); // Q0 - Copy( new_swb_speech - Sample_Delay_SWB_BWE32k, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE32k ); // Q0 + Copy_Scale_sig32_16( new_swb_speech_fx - STEREO_DFT_OVL_MAX, new_swb_speech - STEREO_DFT_OVL_MAX, L_FRAME48k + STEREO_DFT_OVL_MAX, add( st->q_inp, add( q_reImBuffer, 1 ) ) ); // st->q_inp + + Copy( new_swb_speech - Sample_Delay_SWB_BWE32k, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE32k ); // st->q_inp } } } -- GitLab From a965dd81d6b2521322b1d0cecf814f5f44adf576 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 12 May 2025 18:15:48 +0200 Subject: [PATCH 1187/1221] Extend timeout for build jobs --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b3f2be0c3..9f37f50f2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -831,7 +831,7 @@ build-codec-linux-make: when: never extends: - .build-job-linux - timeout: "10 minutes" + timeout: "100 minutes" script: - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - *activate-Werror-linux @@ -848,7 +848,7 @@ build-codec-linux-instrumented-make: when: never extends: - .build-job-linux - timeout: "10 minutes" + timeout: "100 minutes" script: - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/print-common-info.sh - bash "${CI_PROJECT_DIR}"/ivas-codec-ci/snippets/basop/update-scripts-repo.sh @@ -865,7 +865,7 @@ build-codec-linux-debugging-make: when: never extends: - .build-job-linux - timeout: "10 minutes" + timeout: "100 minutes" variables: BUILD_WITH_DEBUG_MODE_INFO: "true" script: -- GitLab From 5f77256c31f9f455f48b343692c6a7b0cae0f062 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 12 May 2025 19:44:36 +0530 Subject: [PATCH 1188/1221] Fix for 3GPP issue 1254: BASOP encoder OSBA 256 kbps: broken signal envelope Link #1254 --- lib_com/ivas_prot_fx.h | 2 +- lib_com/prot_fx.h | 46 ++++++++-------- lib_enc/igf_enc.c | 75 ++++++++++++++++++-------- lib_enc/ivas_mct_core_enc_fx.c | 31 +++++------ lib_enc/ivas_mct_enc_mct_fx.c | 14 +++-- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 51 ++++-------------- lib_enc/tcx_utils_enc_fx.c | 20 +++---- 7 files changed, 116 insertions(+), 123 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 5816c60b5..5bdbd7d73 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3341,7 +3341,7 @@ void mctStereoIGF_enc_fx( Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */ Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/ - Word16 q_powerSpecMsInv[MCT_MAX_CHANNELS], /* i : Q for powSpecMsInv_fx */ + Word16 *q_powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : Q for powSpecMsInv_fx */ Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ); diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 9b78b44d8..bbd5416da 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -10841,32 +10841,32 @@ void ProcessStereoIGF_fx( Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ Word16 q_pITFMDCTSpectrum_1, Word16 q_pITFMDCTSpectrum_2, - Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ - Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ - Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */ - const Word16 frameno, /* i : flag indicating index of current subfr. */ - const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate, /* i : element bitrate */ + Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ + Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ + Word16 *q_pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: Q of pPowerSpectrumMsInv_fx */ + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate, /* i : element bitrate */ const Word16 mct_on ); /*igf_enc.c*/ void IGFEncApplyStereo_fx( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ - Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ - const Word16 igfGridIdx, /* i : IGF grid index */ - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ - Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ - Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ - Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i : exp of inverse spectrum */ - const Word16 frameno, /* i : flag indicating index of current subfr. */ - const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate, /* i : element bitrate */ + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ + Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ + const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ + const Word16 igfGridIdx, /* i : IGF grid index */ + Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ + Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ + Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ + Word16 *q_pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: Q of pPowerSpectrumMsInv_fx */ + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i : exp of inverse spectrum */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate, /* i : element bitrate */ const Word16 mct_on ); void IGFSaveSpectrumForITF_ivas_fx( diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 9769d83b6..18995bd1d 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1002,12 +1002,12 @@ static void IGF_CalculateStereoEnvelope_fx( const Word32 *pPowerSpectrum_fx, /* i : MDCT^2 + MDST^2 spectrum, or estimate */ Word16 pPowerSpectrum_e, /* i : exponent for pPowerSpectrum_fx */ const Word32 *pPowerSpectrumMsInv_fx, /* i : inverse power spectrum */ - Word16 pPowerSpectrumMsInv_e, /* i : exponent for pPowerSpectrumMsInv_fx */ + Word16 *q_pPowerSpectrumMsInv, /* i : Q for pPowerSpectrumMsInv_fx */ const Word16 igfGridIdx, /* i : IGF grid index */ const Word16 coreMsMask[N_MAX], /* i : line wise ms Mask */ const Word16 isTransient, /* i : flag indicating if transient is detected */ - const Word16 last_core_acelp /* i : indicator if last frame was ACELP core */ -) + const Word16 last_core_acelp, /* i : indicator if last frame was ACELP core */ + const Word16 mct_on ) { IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; H_IGF_GRID hGrid; @@ -1047,6 +1047,32 @@ static void IGF_CalculateStereoEnvelope_fx( Word16 slope_e; /*stores exponent for slope_fx*/ Word16 sfbEnergyR_e; /*stores exponent for sfbEnergyR*/ Word16 tmp_e; + Word32 temp_pPowerSpectrumMsInv[N_MAX], length; + Word16 q_temp_pPowerSpectrumMsInv = Q31, i; + move16(); + + IF( pPowerSpectrumMsInv_fx != NULL ) + { + length = N_MAX; + move16(); + if ( mct_on ) + { + length = L_FRAME48k; + move16(); + } + FOR( i = 0; i < length; i++ ) + { + IF( pPowerSpectrumMsInv_fx[i] != 0 ) + { + q_temp_pPowerSpectrumMsInv = s_min( q_temp_pPowerSpectrumMsInv, add( q_pPowerSpectrumMsInv[i], norm_l( pPowerSpectrumMsInv_fx[i] ) ) ); + } + } + FOR( i = 0; i < length; i++ ) + { + temp_pPowerSpectrumMsInv[i] = L_shl( pPowerSpectrumMsInv_fx[i], sub( q_temp_pPowerSpectrumMsInv, q_pPowerSpectrumMsInv[i] ) ); + move32(); + } + } hPrivateData = &hIGFEnc->igfData; hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; @@ -1130,10 +1156,10 @@ static void IGF_CalculateStereoEnvelope_fx( norm_exp = norm_l( pMDCTSpectrumMsInv_fx[strt_cpy] ); final_exp = sub( pMDCTSpectrumMsInv_e, norm_exp ); scaled_value = L_shl( pMDCTSpectrumMsInv_fx[strt_cpy], norm_exp ); - sfbEnergyTileR_fx = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR_fx, sfbEnergyTileR_e, Mult_32_32( scaled_value, scaled_value ), shl( final_exp, 1 ), &sfbEnergyTileR_e ); /*resultant exponent is stored in sfbEnergyTileR_e*/ - sfbEnergyTileC_fx = BASOP_Util_Add_Mant32Exp( sfbEnergyTileC_fx, sfbEnergyTileC_e, pPowerSpectrumMsInv_fx[strt_cpy], pPowerSpectrumMsInv_e, &sfbEnergyTileC_e ); /*resultant exponent is stored in sfbEnergyTileC_e*/ - tileSrcSpec_fx[sub( strt_cpy, tmp )] = pPowerSpectrumMsInv_fx[strt_cpy]; /*resultant exponent is stored in tileSrcSpec_e*/ - tileSrcSpec_e = pPowerSpectrumMsInv_e; + sfbEnergyTileR_fx = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR_fx, sfbEnergyTileR_e, Mult_32_32( scaled_value, scaled_value ), shl( final_exp, 1 ), &sfbEnergyTileR_e ); /*resultant exponent is stored in sfbEnergyTileR_e*/ + sfbEnergyTileC_fx = BASOP_Util_Add_Mant32Exp( sfbEnergyTileC_fx, sfbEnergyTileC_e, pPowerSpectrumMsInv_fx[strt_cpy], sub( 31, q_pPowerSpectrumMsInv[strt_cpy] ), &sfbEnergyTileC_e ); /*resultant exponent is stored in sfbEnergyTileC_e*/ + tileSrcSpec_fx[sub( strt_cpy, tmp )] = temp_pPowerSpectrumMsInv[strt_cpy]; /*resultant exponent is stored in tileSrcSpec_e*/ + tileSrcSpec_e = sub( 31, q_temp_pPowerSpectrumMsInv ); } ELSE { @@ -2620,24 +2646,25 @@ void IGFEncApplyMono_ivas_fx( *-------------------------------------------------------------------*/ void IGFEncApplyStereo_fx( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ - Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ - const Word16 igfGridIdx, /* i : IGF grid index */ - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ - Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ - Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ - Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i : exp of inverse spectrum */ - const Word16 frameno, /* i : flag indicating index of current subfr. */ - const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate, /* i : element bitrate */ + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ + Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ + const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ + const Word16 igfGridIdx, /* i : IGF grid index */ + Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ + Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ + Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ + Word16 *q_pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: Q of pPowerSpectrumMsInv_fx */ + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i : exp of inverse spectrum */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate, /* i : element bitrate */ const Word16 mct_on ) { Word32 *pPowerSpectrumParameter_fx[NB_DIV]; /* If it is NULL it informs a function that specific handling is needed */ Word32 *pPowerSpectrumParameterMsInv_fx[NB_DIV]; + Word16 *q_pPowerSpectrumParameterMsInv_fx[NB_DIV]; Word16 coreMsMask[N_MAX]; Word16 sfb, ch, last_core_acelp; STEREO_MDCT_BAND_PARAMETERS *sfbConf; @@ -2681,6 +2708,8 @@ void IGFEncApplyStereo_fx( pPowerSpectrumParameter_fx[1] = &pPowerSpectrum_fx[1][0]; pPowerSpectrumParameterMsInv_fx[0] = pPowerSpectrumMsInv_fx[0][0]; pPowerSpectrumParameterMsInv_fx[1] = pPowerSpectrumMsInv_fx[1][0]; + q_pPowerSpectrumParameterMsInv_fx[0] = q_pPowerSpectrumMsInv_fx[0][0]; + q_pPowerSpectrumParameterMsInv_fx[1] = q_pPowerSpectrumMsInv_fx[1][0]; } ELSE { @@ -2688,6 +2717,8 @@ void IGFEncApplyStereo_fx( pPowerSpectrumParameter_fx[1] = NULL; pPowerSpectrumParameterMsInv_fx[0] = NULL; pPowerSpectrumParameterMsInv_fx[1] = NULL; + q_pPowerSpectrumParameterMsInv_fx[0] = NULL; + q_pPowerSpectrumParameterMsInv_fx[1] = NULL; } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -2696,7 +2727,7 @@ void IGFEncApplyStereo_fx( IGF_UpdateInfo( hIGFEnc[ch], igfGridIdx ); IGF_CalculateStereoEnvelope_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], sts[ch]->hTcxEnc->spectrum_e[frameno], inv_spectrum_fx[ch][frameno], exp_inv_spectrum_fx[ch], pPowerSpectrumParameter_fx[ch], exp_pPowerSpectrum_fx[ch], pPowerSpectrumParameterMsInv_fx[ch], - exp_pPowerSpectrumMsInv_fx[ch], igfGridIdx, coreMsMask, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp ); + q_pPowerSpectrumParameterMsInv_fx[ch], igfGridIdx, coreMsMask, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, mct_on ); IF( EQ_16( sts[ch]->core, TCX_20_CORE ) ) { diff --git a/lib_enc/ivas_mct_core_enc_fx.c b/lib_enc/ivas_mct_core_enc_fx.c index 0ab232dd9..71890120b 100644 --- a/lib_enc/ivas_mct_core_enc_fx.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -244,8 +244,8 @@ void ivas_mct_core_enc_fx( Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ Word16 total_side_bits; Word16 chBitRatios[MCT_MAX_CHANNELS]; - Word16 q_powSpec[MCT_MAX_CHANNELS], q_powerSpecMsInv[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; - Word16 tmp_q_powSpec[L_FRAME48k], tmp_q_powSpecInv[L_FRAME48k], *tmp_q_psi[2]; + Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; + Word16 tmp_q_powSpec[L_FRAME48k], tmp_q_powSpecInv[MCT_MAX_CHANNELS][L_FRAME48k], *tmp_q_psi[MCT_MAX_CHANNELS][2]; Word64 W_tmp; Encoder_State *sts[MCT_MAX_CHANNELS]; Encoder_State *st; @@ -285,16 +285,17 @@ void ivas_mct_core_enc_fx( inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch]; inv_mdst_spectrum_fx[ch][1] = powerSpecMsInv_fx[ch][1] = powerSpecMsInv_long_fx[ch] + N_TCX10_MAX; + set16_fx( tmp_q_powSpecInv[ch], 63, L_FRAME48k ); + + tmp_q_psi[ch][0] = tmp_q_powSpecInv[ch]; + tmp_q_psi[ch][1] = &tmp_q_powSpecInv[ch][N_TCX10_MAX]; + inv_spectrum_fx[ch][0] = inv_spectrum_long_fx[ch]; inv_spectrum_fx[ch][1] = inv_spectrum_long_fx[ch] + N_TCX10_MAX; } - set16_fx( tmp_q_powSpecInv, 63, L_FRAME48k ); set16_fx( tmp_q_powSpec, 63, L_FRAME48k ); - tmp_q_psi[0] = tmp_q_powSpecInv; - tmp_q_psi[1] = &tmp_q_powSpecInv[N_TCX10_MAX]; - FOR( ( cpe_id = 0, i = 0 ); cpe_id < nCPE; cpe_id++ ) { FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) @@ -451,7 +452,7 @@ void ivas_mct_core_enc_fx( tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); - tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + tmp_q_psi[ch][n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } @@ -465,7 +466,7 @@ void ivas_mct_core_enc_fx( tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp ); - tmp_q_psi[n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + tmp_q_psi[ch][n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); @@ -477,7 +478,7 @@ void ivas_mct_core_enc_fx( tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); - tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + tmp_q_psi[ch][n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } @@ -486,7 +487,7 @@ void ivas_mct_core_enc_fx( tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp ); - tmp_q_psi[n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + tmp_q_psi[ch][n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } @@ -529,8 +530,6 @@ void ivas_mct_core_enc_fx( { q_powSpec[ch] = Q31; move16(); - q_powerSpecMsInv[ch] = Q31; - move16(); /* NOTE: This logic has been added because using a constant headroom while computing `powSpec` and `powSpecMsInv` leads to significant precision loss, which results in poor quality. */ FOR( i = 0; i < L_FRAME48k; i++ ) { @@ -539,18 +538,12 @@ void ivas_mct_core_enc_fx( q_powSpec[ch] = s_min( q_powSpec[ch], add( tmp_q_powSpec[i], norm_l( powerSpec_fx[ch][i] ) ) ); move16(); } - IF( powerSpecMsInv_fx[ch][0][i] != 0 ) - { - q_powerSpecMsInv[ch] = s_min( q_powerSpecMsInv[ch], add( tmp_q_powSpecInv[i], norm_l( powerSpecMsInv_fx[ch][0][i] ) ) ); - move16(); - } } FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powerSpecMsInv[ch] ) ); powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i + ( n * L_subframeTCX )], q_powSpec[ch] ) ); move32(); move32(); @@ -609,7 +602,7 @@ void ivas_mct_core_enc_fx( { IF( hMCT->currBlockDataCnt > 0 ) { - mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, q_powSpec, powerSpecMsInv_fx, q_powerSpecMsInv, inv_spectrum_fx, sp_aud_decision0 ); + mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, q_powSpec, powerSpecMsInv_fx, tmp_q_psi, inv_spectrum_fx, sp_aud_decision0 ); } ELSE { diff --git a/lib_enc/ivas_mct_enc_mct_fx.c b/lib_enc/ivas_mct_enc_mct_fx.c index 94015abb7..8ff17ae01 100644 --- a/lib_enc/ivas_mct_enc_mct_fx.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -986,19 +986,19 @@ void mctStereoIGF_enc_fx( Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */ Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/ - Word16 q_powerSpecMsInv[MCT_MAX_CHANNELS], /* i : Q for powSpecMsInv_fx */ + Word16 *q_powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : Q for powSpecMsInv_fx */ Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ) { Word32 *p_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; + Word16 *q_p_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_inv_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_powerSpec_fx[NB_DIV]; Word16 b, nSubframes, L_subframeTCX; Word16 p_ch[2], n, ch, ch1, ch2; - Word16 q_pSI_ch[2]; Word16 q_pS_ch[2]; Encoder_State *p_st[NB_DIV]; Encoder_State *st; @@ -1059,12 +1059,12 @@ void mctStereoIGF_enc_fx( p_orig_spectrum_fx[1][n] = orig_spectrum_fx[ch2][n]; p_powerSpecMsInv_fx[0][n] = powerSpecMsInv_fx[ch1][n]; // q_powerSpec p_powerSpecMsInv_fx[1][n] = powerSpecMsInv_fx[ch2][n]; + q_p_powerSpecMsInv_fx[0][n] = q_powerSpecMsInv[ch1][n]; // q_powerSpec + q_p_powerSpecMsInv_fx[1][n] = q_powerSpecMsInv[ch2][n]; p_inv_spectrum_fx[0][n] = inv_spectrum_fx[ch1][n]; p_inv_spectrum_fx[1][n] = inv_spectrum_fx[ch2][n]; q_pS_ch[0] = q_powerSpec[ch1]; - q_pSI_ch[0] = q_powerSpecMsInv[ch1]; q_pS_ch[1] = q_powerSpec[ch2]; - q_pSI_ch[1] = q_powerSpecMsInv[ch2]; move16(); move16(); @@ -1072,20 +1072,18 @@ void mctStereoIGF_enc_fx( IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ) || EQ_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) { - Word16 exp_powerSpec_fx[CPE_CHANNELS], exp_powerSpecMsInv_fx[CPE_CHANNELS], exp_inv_spectrum_fx[CPE_CHANNELS]; + Word16 exp_powerSpec_fx[CPE_CHANNELS], exp_inv_spectrum_fx[CPE_CHANNELS]; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { exp_powerSpec_fx[ch] = sub( Q31, q_pS_ch[ch] ); - exp_powerSpecMsInv_fx[ch] = sub( Q31, q_pSI_ch[ch] ); exp_inv_spectrum_fx[ch] = p_st[ch]->hTcxEnc->spectrum_e[n]; move16(); move16(); - move16(); } ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum_fx, q_origSpec, q_origSpec, p_powerSpec_fx, exp_powerSpec_fx, - p_powerSpecMsInv_fx, exp_powerSpecMsInv_fx, p_inv_spectrum_fx, exp_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); + p_powerSpecMsInv_fx, q_p_powerSpecMsInv_fx, p_inv_spectrum_fx, exp_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); } ELSE { diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index 8acbc3e87..cbbc0d000 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -137,8 +137,10 @@ void stereo_mdct_core_enc_fx( Word32 *orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; /* Pointers to MDCT output for a short block (L/R) */ Word64 powerSpec64[CPE_CHANNELS][N_MAX]; Word16 exp_powerSpec64[CPE_CHANNELS][NB_DIV]; - Word32 powerSpecMsInv_long_fx[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */ + Word32 powerSpecMsInv_long_fx[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */ + Word16 q_powerSpecMsInv_long_fx[CPE_CHANNELS][N_MAX]; /*Q: MS inv power spectrum, also inverse MDST spectrum */ Word32 *powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; + Word16 *q_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; Word32 quantized_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ Word32 *quantized_spectrum_fx[CPE_CHANNELS][NB_DIV]; Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; @@ -152,8 +154,6 @@ void stereo_mdct_core_enc_fx( Word32 *p_mdst_spectrum_long_fx[CPE_CHANNELS]; Word32 mdst_spectrum_long_fx[CPE_CHANNELS][N_MAX]; Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; - Word16 exp_powSpecMsInv[MCT_MAX_CHANNELS]; - Word16 tmp_q_powSpecInv[N_MAX], *exp_powSpecInv[2]; Word64 W_tmp; Encoder_State *st, **sts; STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct; @@ -186,11 +186,6 @@ void stereo_mdct_core_enc_fx( set16_fx( exp_powerSpec64[ch], 0, NB_DIV ); } - set16_fx( tmp_q_powSpecInv, 63, N_MAX ); - - exp_powSpecInv[0] = tmp_q_powSpecInv; - exp_powSpecInv[1] = &tmp_q_powSpecInv[N_TCX10_MAX]; - sts = hCPE->hCoreCoder; hStereoMdct = hCPE->hStereoMdct; hBstr = sts[0]->hBstr; @@ -254,6 +249,9 @@ void stereo_mdct_core_enc_fx( { inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch]; inv_mdst_spectrum_fx[ch][1] = powerSpecMsInv_fx[ch][1] = powerSpecMsInv_long_fx[ch] + N_TCX10_MAX; + q_powerSpecMsInv_fx[ch][0] = q_powerSpecMsInv_long_fx[ch]; + q_powerSpecMsInv_fx[ch][1] = q_powerSpecMsInv_long_fx[ch] + N_TCX10_MAX; + set16_fx( q_powerSpecMsInv_long_fx[ch], 63, L_FRAME48k ); quantized_spectrum_fx[ch][0] = quantized_spectrum_long_fx[ch]; quantized_spectrum_fx[ch][1] = quantized_spectrum_long_fx[ch] + N_TCX10_MAX; inv_spectrum_fx[ch][0] = quantized_spectrum_fx[ch][0]; @@ -444,7 +442,7 @@ void stereo_mdct_core_enc_fx( W_tmp = W_mac_32_32( W_mult_32_32( imdct, imdct ), imdst, imdst ); // exp: 2*exp norm = W_norm( W_tmp ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*exp-norm - exp_powSpecInv[n][i] = sub( shl( exp, 1 ), norm ); + q_powerSpecMsInv_fx[ch][n][i] = sub( 31, sub( shl( exp, 1 ), norm ) ); move32(); move16(); @@ -464,7 +462,7 @@ void stereo_mdct_core_enc_fx( W_tmp = W_mult_32_32( mdct, mdct ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) (exp) norm = W_norm( W_tmp ); powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1)-norm (exp-norm) - exp_powSpecInv[n][0] = sub( exp, norm ); + q_powerSpecMsInv_fx[ch][n][0] = sub( 31, sub( exp, norm ) ); move32(); move16(); @@ -477,7 +475,7 @@ void stereo_mdct_core_enc_fx( W_tmp = W_mac_32_32( W_mult_32_32( mdst, mdst ), mdct, mdct ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) (exp) norm = W_norm( W_tmp ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1)-norm (exp-norm) - exp_powSpecInv[n][i] = sub( exp, norm ); + q_powerSpecMsInv_fx[ch][n][i] = sub( 31, sub( exp, norm ) ); move32(); move16(); } @@ -486,7 +484,7 @@ void stereo_mdct_core_enc_fx( W_tmp = W_mult_32_32( mdct, mdct ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1) (exp) norm = W_norm( W_tmp ); powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_shl( W_tmp, norm ) ); // exp: 2*(sts[ch]->hTcxEnc->spectrum_e[n]+1)-norm (exp-norm) - exp_powSpecInv[n][L_subframeTCX - 1] = sub( exp, norm ); + q_powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = sub( 31, sub( exp, norm ) ); move32(); move16(); } @@ -512,33 +510,6 @@ void stereo_mdct_core_enc_fx( move16(); } } - - /* Aligning the Q-factors */ - exp = MIN_16; - move16(); - FOR( n = 0; n < nSubframes; n++ ) - { - FOR( i = 0; i < L_subframeTCX; i++ ) - { - if ( powerSpecMsInv_fx[ch][n][i] != 0 ) - { - exp = s_max( exp, exp_powSpecInv[n][i] ); - } - } - } - IF( NE_16( exp, MIN_16 ) ) - { - FOR( n = 0; n < nSubframes; n++ ) - { - FOR( i = 0; i < L_subframeTCX; i++ ) - { - powerSpecMsInv_fx[ch][n][i] = L_shl( powerSpecMsInv_fx[ch][n][i], sub( exp_powSpecInv[n][i], exp ) ); - move32(); - } - } - } - exp_powSpecMsInv[ch] = exp; - move16(); } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) @@ -656,7 +627,7 @@ void stereo_mdct_core_enc_fx( move16(); ProcessStereoIGF_fx( hStereoMdct, sts, ms_mask, orig_spectrum_fx, sub( Q31, p_orig_spectrum_e[0] ), sub( Q31, p_orig_spectrum_e[1] ), - p_powerSpec_fx, exp_powSpec, powerSpecMsInv_fx, exp_powSpecMsInv, inv_spectrum_fx, exp_inv_spectrum, + p_powerSpec_fx, exp_powSpec, powerSpecMsInv_fx, q_powerSpecMsInv_fx, inv_spectrum_fx, exp_inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); } ELSE diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index acc52c2aa..680a69fa5 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -4029,15 +4029,15 @@ void ProcessStereoIGF_fx( Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ Word16 q_pITFMDCTSpectrum_1, Word16 q_pITFMDCTSpectrum_2, - Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ - Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrumMsInv_fx */ - Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */ - const Word16 frameno, /* i : flag indicating index of current subfr. */ - const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate, /* i : element bitrate */ + Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: exp of pPowerSpectrum_fx */ + Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ + Word16 *q_pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i/o: Q of pPowerSpectrumMsInv_fx */ + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + Word16 exp_inv_spectrum_fx[CPE_CHANNELS], /* i/o: exp of inv_spectrum_fx */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate, /* i : element bitrate */ const Word16 mct_on ) { Word16 ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; @@ -4078,7 +4078,7 @@ void ProcessStereoIGF_fx( IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno], sub( Q31, q_pITFMDCTSpectrum_2 ) ); - IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, exp_pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, exp_pPowerSpectrumMsInv_fx, + IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, exp_pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, q_pPowerSpectrumMsInv_fx, inv_spectrum_fx, exp_inv_spectrum_fx, frameno, sp_aud_decision0, element_brate, mct_on ); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) -- GitLab From 253d721065338c97b05c4b32f4fe544bb8c650ba Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 13 May 2025 11:58:42 +0530 Subject: [PATCH 1189/1221] Fix for LTV Crash: Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, 7_1_4 out --- lib_enc/ivas_stereo_mdct_core_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_stereo_mdct_core_enc_fx.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c index cbbc0d000..2a71fc34d 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc_fx.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -251,7 +251,7 @@ void stereo_mdct_core_enc_fx( inv_mdst_spectrum_fx[ch][1] = powerSpecMsInv_fx[ch][1] = powerSpecMsInv_long_fx[ch] + N_TCX10_MAX; q_powerSpecMsInv_fx[ch][0] = q_powerSpecMsInv_long_fx[ch]; q_powerSpecMsInv_fx[ch][1] = q_powerSpecMsInv_long_fx[ch] + N_TCX10_MAX; - set16_fx( q_powerSpecMsInv_long_fx[ch], 63, L_FRAME48k ); + set16_fx( q_powerSpecMsInv_long_fx[ch], 63, N_MAX ); quantized_spectrum_fx[ch][0] = quantized_spectrum_long_fx[ch]; quantized_spectrum_fx[ch][1] = quantized_spectrum_long_fx[ch] + N_TCX10_MAX; inv_spectrum_fx[ch][0] = quantized_spectrum_fx[ch][0]; -- GitLab From 9853dc8b3dc2c69104377492bdea69d721e0241d Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 13 May 2025 10:52:01 +0200 Subject: [PATCH 1190/1221] Add push/pop wmops for stereo_dmx_evs_enc --- lib_enc/ivas_stereo_dmx_evs_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_enc/ivas_stereo_dmx_evs_fx.c b/lib_enc/ivas_stereo_dmx_evs_fx.c index 13ecbba00..9d0bb92af 100644 --- a/lib_enc/ivas_stereo_dmx_evs_fx.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -1799,6 +1799,7 @@ void stereo_dmx_evs_enc_fx( Word64 W_tmp; Word16 W_tmp_q; + push_wmops( "stereo_dmx_evs_enc" ); if ( is_binaural ) { /* use of is_binaural flag is to be considered */ @@ -2149,6 +2150,7 @@ void stereo_dmx_evs_enc_fx( } Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); // Q26->Q15 + pop_wmops(); return; } -- GitLab From 430ae6cf3ae9af91659c7046cc42acf26329ee74 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 13 May 2025 12:38:38 +0200 Subject: [PATCH 1191/1221] deactivcate FIX_1439_SPEEDUP_synthesise_fb_high_band_fx --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index cbc77b6e7..1574146cc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -89,7 +89,7 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ +//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ -- GitLab From b05870404f337050d4cb7e805a8b1f1482c4326b Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 13 May 2025 14:40:11 +0200 Subject: [PATCH 1192/1221] delete FIX_1439_SPEEDUP_synthesise_fb_high_band_fx wrapped code --- lib_com/swb_tbe_com_fx.c | 46 +--------------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index c4605393d..408f75441 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7023,50 +7023,6 @@ void synthesise_fb_high_band_fx( tmp3 = add( sub( Qout, add( sub( 1, exp ), exp_tmp ) ), 16 ); /*Qout - (1 -exp +exp_tmp) + 16 */ FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef FIX_1439_SPEEDUP_synthesise_fb_high_band_fx - L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ - Word32 L_tmp32; - Word16 tmp16; - - // if (L_tmp < 0) - if ( L_tmp < 0 ) - { - L_tmp32 = L_negate( L_tmp ); - } - if ( L_tmp < 0 ) - { - L_tmp32 = L_shl_sat( L_tmp32, tmp3 ); - } - if ( L_tmp < 0 ) - { - tmp16 = extract_h( L_tmp32 ); - } - if ( L_tmp < 0 ) - { - tmp16 = negate( tmp16 ); - } - - // if (L_tmp == 0) - if ( L_tmp == 0 ) - { - tmp16 = 0; - move16(); - } - - // if (L_tmp > 0) - if ( L_tmp > 0 ) - { - L_tmp32 = L_shl_sat( L_tmp, tmp3 ); - } - if ( L_tmp > 0 ) - { - tmp16 = extract_h( L_tmp32 ); - } - - output[i] = tmp16; - move16(); - -#else L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { @@ -7077,8 +7033,8 @@ void synthesise_fb_high_band_fx( { output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); + } -#endif } return; } -- GitLab From a20cf2d141040cb2e23050cfd5902952f91c9d1f Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 13 May 2025 15:31:17 +0200 Subject: [PATCH 1193/1221] apply clang patch --- lib_com/swb_tbe_com_fx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 408f75441..85ea15e9d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7033,7 +7033,6 @@ void synthesise_fb_high_band_fx( { output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); - } } return; -- GitLab From 10325469adbe638293dd59ce6d413218af4196b9 Mon Sep 17 00:00:00 2001 From: Fabian Bauer Date: Tue, 13 May 2025 14:57:45 +0000 Subject: [PATCH 1194/1221] delete FIX_1439_SPEEDUP_synthesise_fb_high_band_fx from options --- lib_com/options.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1574146cc..cce7932de 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -89,7 +89,6 @@ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ -//#define FIX_1439_SPEEDUP_synthesise_fb_high_band_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic /*FhG: reduces maintenance complexity & reduces WMOPS & prepares STAGE2 patch*/ #define FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 /*FhG: reduces WMOPS*/ #define FIX_1481_HARDCODE_DIV /* FhG: hardcode division results in stereo_dmx_evs_init_encoder_fx() */ -- GitLab From 361e8c5a62a47569ba7f61dbaaa51f01a04b267d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 14 May 2025 08:53:17 +0530 Subject: [PATCH 1195/1221] Fix for 3GPP issue 1375: Underflow observed in the quantize_pars_fx() function in the MC param upmix Link #1375 --- lib_com/basop_util.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index dc9013a42..e52f404f6 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -2640,10 +2640,16 @@ Word32 BASOP_Util_Add_Mant32Exp /* o : normalized result mantissa */ */ if ( !a_m ) - a_e = add( b_e, 0 ); + { + a_e = b_e; + move16(); + } if ( !b_m ) - b_e = add( a_e, 0 ); + { + b_e = a_e; + move16(); + } shift = sub( a_e, b_e ); shift = s_max( -31, shift ); @@ -2664,7 +2670,10 @@ Word32 BASOP_Util_Add_Mant32Exp /* o : normalized result mantissa */ if ( shift ) L_tmp = L_shl( L_tmp, shift ); if ( L_tmp == 0 ) - a_e = add( 0, 0 ); + { + a_e = 0; + move16(); + } if ( L_tmp != 0 ) a_e = sub( a_e, shift ); *ptr_e = a_e; -- GitLab From f1dbfb661fd3759e15d0b306bed7751377c59e02 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 9 May 2025 12:05:04 +0530 Subject: [PATCH 1196/1221] Bug fix in find_targets_ivas_fx and GetEnergyCldfb --- lib_com/cldfb.c | 177 +++++++++++++++++++++++++++++++++++++++++- lib_enc/find_tar_fx.c | 10 +-- 2 files changed, 181 insertions(+), 6 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 6a9581498..bf832b640 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -60,6 +60,19 @@ static void cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs ); static void cldfb_init_proto_and_twiddles_enc_fx( HANDLE_CLDFB_FILTER_BANK hs ); +static void GetEnergyCldfb_ivas_fx( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) | pointer to the result in the core look-ahead slot */ + Word16 *sf_energyLookahead, /*!< o: pointer to the scalefactor of the result in the core look-ahead slot */ + const Word16 numLookahead, /*!< i: Q0 the number of look-ahead time-slots */ + Word16 **realValues, /*!< i: Q(sf_Values) | the real part of the CLDFB subsamples */ + Word16 **imagValues, /*!< i: Q(sf_Values) | the imaginary part of the CLDFB subsamples */ + Word16 sf_Values, /*!< i: scalefactor of the CLDFB subcamples - apply as a negated Exponent */ + Word16 numberBands, /*!< i: Q0 | number of CLDFB bands */ + Word16 numberCols, /*!< i: Q0 | number of CLDFB subsamples */ + Word32 *energyHF, /*!< o: Q31 | pointer to HF energy */ + Word16 *energyHF_Exp, /*!< o: pointer to exponent of HF energy */ + Word32 *energyValuesSum, /*!< o: Q(2*sf_Values-4) | pointer to sum array of energy values, not initialized*/ + Word16 *energyValuesSum_Exp, /*!< o: pointer to exponents of energyValuesSum, not initialized */ + TEC_ENC_HANDLE hTecEnc ); /*-------------------------------------------------------------------* * cplxMult() @@ -1552,6 +1565,168 @@ void resampleCldfb_ivas_fx( return; } +static void GetEnergyCldfb_ivas_fx( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) | pointer to the result in the core look-ahead slot */ + Word16 *sf_energyLookahead, /*!< o: pointer to the scalefactor of the result in the core look-ahead slot */ + const Word16 numLookahead, /*!< i: Q0 the number of look-ahead time-slots */ + Word16 **realValues, /*!< i: Q(sf_Values) | the real part of the CLDFB subsamples */ + Word16 **imagValues, /*!< i: Q(sf_Values) | the imaginary part of the CLDFB subsamples */ + Word16 sf_Values, /*!< i: scalefactor of the CLDFB subcamples - apply as a negated Exponent */ + Word16 numberBands, /*!< i: Q0 | number of CLDFB bands */ + Word16 numberCols, /*!< i: Q0 | number of CLDFB subsamples */ + Word32 *energyHF, /*!< o: Q31 | pointer to HF energy */ + Word16 *energyHF_Exp, /*!< o: pointer to exponent of HF energy */ + Word32 *energyValuesSum, /*!< o: Q(2*sf_Values-4) | pointer to sum array of energy values, not initialized*/ + Word16 *energyValuesSum_Exp, /*!< o: pointer to exponents of energyValuesSum, not initialized */ + TEC_ENC_HANDLE hTecEnc ) +{ + Word16 j; + Word16 k; + Word16 s; + Word16 sm; + Word32 nrg; + Word16 numberColsL; + Word16 numberBandsM; + Word16 numberBandsM20; + Word32 energyValues[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 energyValuesSumE[CLDFB_NO_CHANNELS_MAX]; + // Word16 freqTable[2] = {20, 40}; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + FOR( k = 0; k < numberCols; k++ ) + { + FOR( j = 0; j < numberBands; j++ ) + { + nrg = L_mult0( realValues[k][j], realValues[k][j] ); // Q(2*sf_Values) + nrg = L_mac0( nrg, imagValues[k][j], imagValues[k][j] ); // Q(2*sf_Values) + + energyValues[k][j] = nrg; + move32(); + } + } + + IF( GE_16( numberBands, freqTable[1] ) && hTecEnc != NULL ) + { + Word32 *tempEnergyValuesArry[CLDFB_NO_COL_MAX]; + Word16 ScaleX2; + assert( numberCols == CLDFB_NO_COL_MAX ); + FOR( j = 0; j < numberCols; j++ ) + { + tempEnergyValuesArry[j] = &energyValues[j][0]; + } + + ScaleX2 = shl( sf_Values, 1 ); + calcHiEnvLoBuff_Fix( + numberCols, + freqTable, + 1, + tempEnergyValuesArry, + hTecEnc->loBuffer, + hTecEnc->hiTempEnv, + ScaleX2 ); + } + + FOR( j = 0; j < numberBands; j++ ) + { + energyValuesSum[j] = 0; + move32(); + energyValuesSumE[j] = 31; + move16(); + FOR( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + nrg = L_shr_r( energyValues[k][j], sub( energyValuesSumE[j], 31 ) ); // Q(2*sf_Values - (energyValuesSumE[j]-31)) + IF( LT_32( L_sub( maxWord32, nrg ), energyValuesSum[j] ) ) + { + energyValuesSumE[j] = add( energyValuesSumE[j], 1 ); + move16(); + energyValuesSum[j] = L_shr_r( energyValuesSum[j], 1 ); + move32(); + nrg = L_shr_r( nrg, 1 ); + } + energyValuesSum[j] = L_add( energyValuesSum[j], nrg ); + move32(); + } + test(); + if ( j == 0 || GT_16( energyValuesSumE[j], *energyValuesSum_Exp ) ) + { + *energyValuesSum_Exp = energyValuesSumE[j]; + move16(); + } + } + FOR( j = 0; j < numberBands; j++ ) + { + energyValuesSum[j] = L_shr_r( energyValuesSum[j], sub( *energyValuesSum_Exp, energyValuesSumE[j] ) ); // Q(energyValuesSum_Exp - (2*sf_Values)) + move32(); + } + *energyValuesSum_Exp = sub( *energyValuesSum_Exp, shl( sf_Values, 1 ) ); + move16(); + + IF( GT_16( numberBands, 20 ) ) + { + numberBandsM = s_min( numberBands, 40 ); + numberBandsM20 = sub( numberBandsM, 20 ); + + numberColsL = sub( numberCols, numLookahead ); + + /* sum up CLDFB energy above 8 kHz */ + s = BASOP_util_norm_s_bands2shift( i_mult( numberColsL, numberBandsM20 ) ); + s = sub( s, 4 ); + nrg = 0; + move32(); + FOR( k = 0; k < numberColsL; k++ ) + { + FOR( j = 20; j < numberBandsM; j++ ) + { + nrg = L_add_o( nrg, L_shr_o( energyValues[k][j], s, &Overflow ), &Overflow ); + } + } + + s = sub( sub( shl( sf_Values, 1 ), 1 ), s ); + sm = sub( s_min( s, *sf_energyLookahead ), 1 ); + + *energyHF = L_add( L_shr( nrg, limitScale32( sub( s, sm ) ) ), + L_shr( *energyLookahead, sub( *sf_energyLookahead, sm ) ) ); // Q(31-(-nm)) + move32(); + + *energyHF_Exp = negate( sm ); + move16(); + + /* process look-ahead region */ + s = BASOP_util_norm_s_bands2shift( i_mult( numLookahead, numberBandsM20 ) ); + s = sub( s, 2 ); + nrg = 0; + move32(); + FOR( k = numberColsL; k < numberCols; k++ ) + { + FOR( j = 20; j < numberBandsM; j++ ) + { + nrg = L_add_o( nrg, L_shr_o( energyValues[k][j], s, &Overflow ), &Overflow ); + } + } + + s = sub( shl( sf_Values, 1 ), s ); + sm = sub( s_min( s, 44 ), 1 ); + BASOP_SATURATE_WARNING_OFF_EVS + /* nrg + 6.1e-5f => value 0x40000000, scale 44 */ + *energyLookahead = L_add_sat( L_shr_sat( nrg, sub( s, sm ) ), + L_shr_sat( 0x40000000, s_max( -31, s_min( 31, sub( 44, sm ) ) ) ) ); + move32(); + BASOP_SATURATE_WARNING_ON_EVS + *sf_energyLookahead = sm; + move16(); + + return; + } + + + *energyHF = 0x40000000; + move32(); + *energyHF_Exp = 17; + move16(); +} + void analysisCldfbEncoder_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ @@ -1613,7 +1788,7 @@ void analysisCldfbEncoder_ivas_fx( AnalysisPostSpectrumScaling_Fx( st->cldfbAnaEnc, ppBuf_Real, ppBuf_Imag, ppBuf_Real16, ppBuf_Imag16, &enerScale.lb_scale16 ); - GetEnergyCldfb( &st->energyCoreLookahead_Fx, &st->sf_energyCoreLookahead_Fx, 1, ppBuf_Real16, ppBuf_Imag16, enerScale.lb_scale16, st->cldfbAnaEnc->no_channels, st->cldfbAnaEnc->no_col, &st->currEnergyHF_fx, &st->currEnergyHF_e_fx, ppBuf_Ener, enerBuffSum_exp, st->hTECEnc ); + GetEnergyCldfb_ivas_fx( &st->energyCoreLookahead_Fx, &st->sf_energyCoreLookahead_Fx, 1, ppBuf_Real16, ppBuf_Imag16, enerScale.lb_scale16, st->cldfbAnaEnc->no_channels, st->cldfbAnaEnc->no_col, &st->currEnergyHF_fx, &st->currEnergyHF_e_fx, ppBuf_Ener, enerBuffSum_exp, st->hTECEnc ); return; } diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index 8d3efb834..989f309d2 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -219,13 +219,13 @@ void find_targets_ivas_fx( /* first half: xn[] --> cn[] */ temp[0] = 0; move16(); - preemph_copy_fx( xn, cn, tilt_fac, L_SUBFR / 2, temp ); - syn_filt_s_lc_fx( 1, Ap, cn, temp, L_SUBFR / 2 ); /* Q-1 -> Q-2 */ - Residu3_lc_fx( p_Aq, M, temp, cn, L_SUBFR / 2, 1 ); /* Q-2 -> Q-1 */ - Scale_sig( cn, L_SUBFR / 2, 1 ); + preemph_copy_fx( xn, cn, tilt_fac, L_subfr / 2, temp ); + syn_filt_s_lc_fx( 1, Ap, cn, temp, L_subfr / 2 ); /* Q-1 -> Q-2 */ + Residu3_lc_fx( p_Aq, M, temp, cn, L_subfr / 2, 1 ); /* Q-2 -> Q-1 */ + Scale_sig( cn, L_subfr / 2, 1 ); /* second half: res[] --> cn[] (approximated and faster) */ - Copy( &res[i_subfr + ( L_SUBFR / 2 )], cn + ( L_SUBFR / 2 ), L_SUBFR / 2 ); + Copy( &res[i_subfr + ( L_subfr / 2 )], cn + ( L_subfr / 2 ), L_subfr / 2 ); } /*---------------------------------------------------------------* -- GitLab From 441cc348071908a2d4030877dc8a5e3a19ac51ac Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 14 May 2025 16:29:38 +0530 Subject: [PATCH 1197/1221] Fix for 3GPP issue 1395: Stereo Encoder 32 kbps, DTX on: Plop-artefact in right Channel LTV Link #1395 --- lib_enc/ivas_stereo_switching_enc_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_enc/ivas_stereo_switching_enc_fx.c b/lib_enc/ivas_stereo_switching_enc_fx.c index 8e372b311..a54e56fb9 100644 --- a/lib_enc/ivas_stereo_switching_enc_fx.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -898,6 +898,8 @@ void stereo_switching_enc_fx( IF( sts[0]->hLPDmem != NULL ) { Copy( sts[0]->hLPDmem->old_exc, sts[1]->hLPDmem->old_exc, L_EXC_MEM ); + sts[1]->hLPDmem->q_lpd_old_exc = sts[0]->hLPDmem->q_lpd_old_exc; + move16(); } Copy( sts[0]->lsf_old_fx, sts[1]->lsf_old_fx, M ); /* Qlog2(2.56) */ Copy( sts[0]->lsp_old_fx, sts[1]->lsp_old_fx, M ); /* Q15 */ -- GitLab From 8b5e97ea53d1e52c6b09f5c24796d7cfbda19613 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 15 May 2025 12:38:43 +0530 Subject: [PATCH 1198/1221] Precision improvement in wb_vad_ivas_fx --- lib_enc/init_enc_fx.c | 2 + lib_enc/ivas_core_pre_proc_front_fx.c | 35 ++-- lib_enc/ivas_front_vad_fx.c | 14 +- lib_enc/nois_est_fx.c | 16 +- lib_enc/pitch_ol_fx.c | 13 +- lib_enc/prot_fx_enc.h | 2 +- lib_enc/stat_enc.h | 6 +- lib_enc/vad_fx.c | 258 ++++++++++++++------------ 8 files changed, 182 insertions(+), 164 deletions(-) diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 97cd57308..543a6fab9 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -377,6 +377,8 @@ ivas_error init_encoder_fx( move16(); st_fx->hVAD->L_snr_sum_vad_fx = 0; move32(); + st_fx->hVAD->q_L_snr_sum_vad = Q31; + move16(); } ELSE { diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index e883d9ec1..d358f7099 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -223,6 +223,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 res_cod_SNR_M_fx_e[STEREO_DFT_BAND_MAX]; Word16 Qfact_PS, q_lf_E_fx; Word16 enerBuffer_fx_exp_buf[CLDFB_NO_CHANNELS_MAX]; + Word32 bckr_temp[NB_BANDS]; #ifdef DEBUG_MODE_INFO Word32 *in_buff_temp; Word16 in_q_temp; @@ -781,21 +782,9 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - Word16 scale = add( L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ), st->hNoiseEst->q_enrO ); - scale = s_min( scale, fr_bands_fx_q ); - - scale_sig32( st->hNoiseEst->enrO_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_enrO ) ); - st->hNoiseEst->q_enrO = scale; - move16(); - - scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); - fr_bands_fx_q = scale; - move16(); - st->vad_flag = wb_vad_ivas_fx( st, fr_bands_fx, fr_bands_fx_q, &i, &i, &i, &snr_sum_he_fx, &localVAD_HE_SAD, &( st->flag_noisy_speech_snr ), NULL, NULL, -MAX_16, -MAX_16 ); //-100000f == max 16bit float move16(); - #ifdef DEBUG_FORCE_DIR if ( st->force_dir[0] != '\0' ) { @@ -919,13 +908,13 @@ ivas_error pre_proc_front_ivas_fx( *----------------------------------------------------------------*/ noise_est_down_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, &st->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, - &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_32fx, &st->hNoiseEst->Etot_v_h2_fx ); + &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_32fx, &st->hNoiseEst->Etot_v_h2_32fx ); test(); IF( lr_vad_enabled && st->idchan == 0 ) { - noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[0]->hNoiseEst->q_bckr, tmpN_LR_fx[0], &q_tmpN_LR[0], tmpE_LR_fx[0], &q_tmpE_LR[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_LR_fx[0] ), &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_32fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx ); - noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[1]->hNoiseEst->q_bckr, tmpN_LR_fx[1], &q_tmpN_LR[1], tmpE_LR_fx[1], &q_tmpE_LR[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_LR_fx[1] ), &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_32fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx ); + noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[0]->hNoiseEst->q_bckr, tmpN_LR_fx[0], &q_tmpN_LR[0], tmpE_LR_fx[0], &q_tmpE_LR[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_LR_fx[0] ), &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_32fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_32fx ); + noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, &hCPE->hFrontVad[1]->hNoiseEst->q_bckr, tmpN_LR_fx[1], &q_tmpN_LR[1], tmpE_LR_fx[1], &q_tmpE_LR[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_LR_fx[1] ), &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_32fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_32fx ); corr_shiftL_fx = correlation_shift_fx( hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx ); // Q15 corr_shiftR_fx = correlation_shift_fx( hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx ); // Q15 @@ -1249,7 +1238,7 @@ ivas_error pre_proc_front_ivas_fx( * Update estimated noise energy and voicing cut-off frequency *-----------------------------------------------------------------*/ - scale = s_min( Q31, s_min( add( q_tmpN, L_norm_arr( tmpN_fx, NB_BANDS ) ), add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ) ) ); + Word16 scale = s_min( Q31, s_min( add( q_tmpN, L_norm_arr( tmpN_fx, NB_BANDS ) ), add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ) ) ); scale = sub( scale, 1 ); // guard bits scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); scale_sig32( tmpN_fx, NB_BANDS, sub( scale, q_tmpN ) ); @@ -1278,7 +1267,7 @@ ivas_error pre_proc_front_ivas_fx( noise_est_ivas_fx( st, old_pitch1, tmpN_fx, epsP_fx, extract_h( Etot_fx ), *relE_fx, corr_shift_fx, tmpE_fx, q_tmpE, fr_bands_fx, fr_bands_fx_q, cor_map_sum_fx, &ncharX_fx, &sp_div_fx, &q_sp_div, &non_staX_fx, loc_harm, lf_E_fx, q_lf_E_fx, &st->hNoiseEst->harm_cor_cnt, extract_h( st->hNoiseEst->Etot_l_lp_32fx ), - st->hNoiseEst->Etot_v_h2_fx, &st->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_fx, + extract_h( st->hNoiseEst->Etot_v_h2_32fx ), &st->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_fx, hStereoClassif, NULL, st->ini_frame ); test(); @@ -1321,14 +1310,14 @@ ivas_error pre_proc_front_ivas_fx( noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[0], epsP_fx, Etot_LR_fx[0], sub( Etot_LR_fx[0], hCPE->hFrontVad[0]->lp_speech_fx ), corr_shiftL_fx, tmpE_LR_fx[0], q_tmpE_LR[0], fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], &cor_map_sum_LR_fx[0], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[0], lf_E_LR_fx_q, &hCPE->hFrontVad[0]->hNoiseEst->harm_cor_cnt, - extract_h( hCPE->hFrontVad[0]->hNoiseEst->Etot_l_lp_32fx ), hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[0]->hNoiseEst->bg_cnt, + extract_h( hCPE->hFrontVad[0]->hNoiseEst->Etot_l_lp_32fx ), extract_h( hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_32fx ), &hCPE->hFrontVad[0]->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[0], hCPE->hFrontVad[0]->ini_frame ); /* Note: the index [0] in the last argument is intended, the ini_frame counter is only maintained in the zero-th channel's VAD handle */ noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[1], epsP_fx, Etot_LR_fx[1], sub( Etot_LR_fx[1], hCPE->hFrontVad[1]->lp_speech_fx ), corr_shiftR_fx, tmpE_LR_fx[1], q_tmpE_LR[1], fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], &cor_map_sum_LR_fx[1], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[1], lf_E_LR_fx_q, &hCPE->hFrontVad[1]->hNoiseEst->harm_cor_cnt, - extract_h( hCPE->hFrontVad[1]->hNoiseEst->Etot_l_lp_32fx ), hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[1]->hNoiseEst->bg_cnt, + extract_h( hCPE->hFrontVad[1]->hNoiseEst->Etot_l_lp_32fx ), extract_h( hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_32fx ), &hCPE->hFrontVad[1]->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[1], hCPE->hFrontVad[0]->ini_frame ); } @@ -1346,14 +1335,14 @@ ivas_error pre_proc_front_ivas_fx( * Find spectral tilt * UC and VC frame selection *-----------------------------------------------------------------*/ + scale = s_min( Q31, s_min( add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ), add( fr_bands_fx_q, L_norm_arr( fr_bands_fx, 2 * NB_BANDS ) ) ) ); scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); - scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); - st->hNoiseEst->q_bckr = fr_bands_fx_q = scale; - move16(); + Copy_Scale_sig32( st->hNoiseEst->bckr_fx, bckr_temp, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); + fr_bands_fx_q = scale; move16(); - find_tilt_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, st->hNoiseEst->q_bckr, ee_fx, st->pitch, st->voicing_fx, lf_E_fx, q_lf_E_fx, + find_tilt_ivas_fx( fr_bands_fx, fr_bands_fx_q, bckr_temp, scale, ee_fx, st->pitch, st->voicing_fx, lf_E_fx, q_lf_E_fx, corr_shift_fx, st->input_bwidth, st->max_band, hp_E_fx, MODE1, &( st->bckr_tilt_lt ), st->Opt_SC_VBR ); st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, extract_h( Etot_fx ), hp_E_fx, diff --git a/lib_enc/ivas_front_vad_fx.c b/lib_enc/ivas_front_vad_fx.c index ab090edb8..b3c563863 100644 --- a/lib_enc/ivas_front_vad_fx.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -282,16 +282,6 @@ ivas_error front_vad_fx( move16(); /* wb_vad */ - Word16 scale = s_min( q_fr_bands[n], add( hFrontVads[n]->hNoiseEst->q_enrO, L_norm_arr( hFrontVads[n]->hNoiseEst->enrO_fx, NB_BANDS ) ) ); - - scale_sig32( hFrontVads[n]->hNoiseEst->enrO_fx, NB_BANDS, sub( scale, hFrontVads[n]->hNoiseEst->q_enrO ) ); // scale - hFrontVads[n]->hNoiseEst->q_enrO = scale; - move16(); - - scale_sig32( fr_bands_fx[n], 2 * NB_BANDS, sub( scale, q_fr_bands[n] ) ); // scale - q_fr_bands[n] = scale; - move16(); - hFrontVad->hVAD->vad_flag = wb_vad_ivas_fx( sts[n], fr_bands_fx[n], q_fr_bands[n], &dummy, &dummy, &dummy, &snr_sum_he_fx, &localVAD_HE_SAD[n], &dummy_short, hFrontVad->hVAD, hFrontVad->hNoiseEst, hFrontVad->lp_speech_fx, hFrontVad->lp_noise_fx ); // Q0 @@ -613,7 +603,7 @@ ivas_error front_vad_spar_fx( Word16 q_tmpN, q_tmpE; noise_est_down_ivas_fx( fr_bands_fx[0], q_fr_bands[0], hFrontVad->hNoiseEst->bckr_fx, &hFrontVad->hNoiseEst->q_bckr, tmpN_fx, &q_tmpN, tmpE_fx, &q_tmpE, st->min_band, st->max_band, - &hFrontVad->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_fx[0] ) /*q8->q24*/, &hFrontVad->hNoiseEst->Etot_last_32fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); + &hFrontVad->hNoiseEst->totalNoise_fx, L_deposit_h( Etot_fx[0] ) /*q8->q24*/, &hFrontVad->hNoiseEst->Etot_last_32fx, &hFrontVad->hNoiseEst->Etot_v_h2_32fx ); corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ @@ -755,7 +745,7 @@ ivas_error front_vad_spar_fx( noise_est_ivas_fx( st, old_pitch, tmpN_fx, epsP_fx, Etot_fx[0], sub( Etot_fx[0], hFrontVad->lp_speech_fx ), corr_shift_fx, tmpE_fx, hFrontVad->hNoiseEst->ave_enr_q, fr_bands_fx[0], q_fr_bands[0], &cor_map_sum_fx, NULL, &sp_div_fx, &Q_sp_div, &non_staX_fx, &loc_harm, - lf_E_fx[0], q_lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, extract_h( hFrontVad->hNoiseEst->Etot_l_lp_32fx ), hFrontVad->hNoiseEst->Etot_v_h2_fx, + lf_E_fx[0], q_lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, extract_h( hFrontVad->hNoiseEst->Etot_l_lp_32fx ), extract_h( hFrontVad->hNoiseEst->Etot_v_h2_32fx ), &hFrontVad->hNoiseEst->bg_cnt, st->lgBin_E_fx, &sp_floor, S_map_fx, NULL, hFrontVad, hFrontVad->ini_frame ); MVR2R_WORD16( st->pitch, st->pitch, 3 ); diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 733576975..4f178214f 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -361,13 +361,13 @@ void noise_est_init_ivas_fx( hNoiseEst->Etot_l_fx = 0; hNoiseEst->Etot_l_lp_32fx = 0; hNoiseEst->Etot_last_32fx = 0; - hNoiseEst->Etot_v_h2_fx = 0; + hNoiseEst->Etot_v_h2_32fx = 0; hNoiseEst->sign_dyn_lp_fx = 0; move16(); move16(); move16(); move16(); - move16(); + move32(); move32(); move32(); @@ -514,8 +514,8 @@ void noise_est_pre_32fx( move32(); hNoiseEst->Etot_last_32fx = Etot; // Q24 move32(); - hNoiseEst->Etot_v_h2_fx = 0; - move16(); + hNoiseEst->Etot_v_h2_32fx = 0; + move32(); Etot_lp_32fx = Etot; move32(); hNoiseEst->sign_dyn_lp_fx = 0; @@ -750,7 +750,7 @@ void noise_est_down_ivas_fx( Word16 *totalNoise, /* o : noise estimate over all critical bands */ Word32 Etot, /* i : Energy of current frame Q24*/ Word32 *Etot_last, /* i/o: Energy of last frame Q24 */ - Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ + Word32 *Etot_v_h2 /* i/o: Energy variations of noise frames Q24 */ ) { @@ -773,7 +773,7 @@ void noise_est_down_ivas_fx( L_Etot = Etot; /*Q24 for later AR1 computations*/ move32(); L_Etot_last = *Etot_last; - L_Etot_v_h2 = L_shl( *Etot_v_h2, 16 ); + L_Etot_v_h2 = *Etot_v_h2; /*-----------------------------------------------------------------* * Estimate total noise energy @@ -901,7 +901,7 @@ void noise_est_down_ivas_fx( L_Etot_v_h2 = Madd_32_16( L_tmp, L_Etot_v_h2, 32113 /* 0.98 in Q15 */ ); // Q24 /* if (*Etot_v_h2 < 0.1f) { *Etot_v_h2 = 0.1f; } */ - *Etot_v_h2 = s_max( round_fx( L_Etot_v_h2 ), 26 /* 0.1 in Q8*/ ); // Q8 + *Etot_v_h2 = L_max( L_Etot_v_h2, 1677722 /* 0.1 in Q24*/ ); // Q24 move16(); return; @@ -3494,7 +3494,7 @@ void noise_est_ivas_fx( ) */ ELSE IF( ( LT_16( hNoiseEst->act_pred_fx, 26214 /* 0.8 in Q15*/ ) && ( ( aE_bgd != 0 ) || ( PAU != 0 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 3277 /* 0.1 in q15*/ ) ) ) || ( ( LT_16( hNoiseEst->act_pred_fx, 22938 /* 0.70 in Q15 */ ) ) && ( ( aE_bgd != 0 ) || ( LT_16( non_staB, 17 * 256 /* 17.0 in Q8 */ ) ) ) && ( PAU != 0 ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 4915 /* 0.15 in Q15 */ ) ) ) || - ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) && GT_16( hNoiseEst->totalNoise_fx, 5 * 256 /* 5.0 in Q8 */ ) && LT_16( Etot, s_max( 1 * 256, add( Etot_l_lp, add( hNoiseEst->Etot_v_h2_fx, shr( hNoiseEst->Etot_v_h2_fx, 1 ) ) /* 1.5= 1.0+.5 */ ) ) ) ) || + ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) && GT_16( hNoiseEst->totalNoise_fx, 5 * 256 /* 5.0 in Q8 */ ) && LT_16( Etot, s_max( 1 * 256, add( Etot_l_lp, extract_h( L_add( hNoiseEst->Etot_v_h2_32fx, L_shr( hNoiseEst->Etot_v_h2_32fx, 1 ) ) ) /* 1.5= 1.0+.5 */ ) ) ) ) || ( GT_16( hNoiseEst->harm_cor_cnt, 50 ) && GT_16( hNoiseEst->first_noise_updt, 30 ) && ( aE_bgd != 0 ) && GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 /*.5 in Q15*/ ) ) || ( tn_ini != 0 ) ) { updt_step = 3277; diff --git a/lib_enc/pitch_ol_fx.c b/lib_enc/pitch_ol_fx.c index 91181714a..fdadcd318 100644 --- a/lib_enc/pitch_ol_fx.c +++ b/lib_enc/pitch_ol_fx.c @@ -1686,13 +1686,17 @@ void pitch_ol_ivas_fx( move16(); /* enr1 = dotp( pt2, pt2, len[j] ) + 0.01f; */ - temp = 167772 /*0.01f in Q24*/; + temp = 0; move64(); FOR( m = 0; m < len[j]; m++ ) { temp = W_mac0_16_16( temp, pt2[m], pt2[m] ); // 2*qwsp } + temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24 + + temp = W_add( temp, 167772 ); /*0.01f in Q24*/ + enr1_exp = W_norm( temp ); enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32 enr1_exp = sub( 39, enr1_exp ); // 31-(enr1_exp+24-32) @@ -1724,13 +1728,18 @@ void pitch_ol_ivas_fx( move16(); /* enr1 = dotp(pt4, pt4, len1[j]) + 0.01f; */ - temp = 167772 /*0.01f in Q24*/; + temp = 0; + move64(); move64(); FOR( m = 0; m < len1[j]; m++ ) { temp = W_mac0_16_16( temp, pt4[m], pt4[m] ); // 2*qwsp } + temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24 + + temp = W_add( temp, 167772 ); /*0.01f in Q24*/ + enr1_exp = W_norm( temp ); enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32 enr1_exp = sub( 39, enr1_exp ); // 31-(enr1_exp+24-32) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 05bb16832..1d85ae6de 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -371,7 +371,7 @@ void noise_est_down_ivas_fx( Word16 *totalNoise, /* o : noise estimate over all critical bands */ Word32 Etot, /* i : Energy of current frame Q24*/ Word32 *Etot_last, /* i/o: Energy of last frame Q24 */ - Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ + Word32 *Etot_v_h2 /* i/o: Energy variations of noise frames Q24 */ ); void noise_est_fx( diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 3d6f23dd3..1097c6a27 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -224,7 +224,8 @@ typedef struct vad_structure Word16 trigger_SID; Word16 snr_sum_vad_fx; /*Q15 */ Word16 running_avg_fx; /*Q15 */ - Word32 L_snr_sum_vad_fx; /*Q4*/ + Word32 L_snr_sum_vad_fx; // EVS:Q4, IVAS:q_L_snr_sum_vad + Word16 q_L_snr_sum_vad; Word16 hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ Word16 vad_flag; /* VAD flag */ @@ -564,7 +565,8 @@ typedef struct noise_estimation_structure Word16 lt_aEn_zero_fx; /* Q15 */ Word16 Etot_v_h2_fx; - Word16 sign_dyn_lp_fx; /*Q8*/ + Word32 Etot_v_h2_32fx; /* Q24 */ + Word16 sign_dyn_lp_fx; /*Q8*/ Word16 Etot_st_est_fx; /* Q8 Noise estimation - short term estimate of E{ Etot } */ Word16 Etot_sq_st_est_fx; /* Q2 Noise estimation - short term estimate of E{ Etot^2 } */ diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index 531265236..721a6e348 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -142,6 +142,8 @@ void wb_vad_init_ivas_fx( { hVAD->L_snr_sum_vad_fx = 0; move32(); + hVAD->q_L_snr_sum_vad = Q31; + move16(); hVAD->hangover_cnt = 0; move16(); /* Hangover counter initialized to 0 */ hVAD->nb_active_frames = ACTIVE_FRAMES_FX; @@ -1918,7 +1920,8 @@ Word16 wb_vad_ivas_fx( ) { Word16 i, flag = 0, hangover_short; - Word16 snr_sum, thr1 = 0, thr1_nb_mod, thr2 = 0, nk = 0, nc = 0, th_clean = 0; + Word16 snr_sum, thr1 = 0, thr1_nb_mod, thr2 = 0, nk = 0, th_clean = 0; + Word32 nc; Word16 lp_snr; /* Q8 */ const Word32 *pt1; const Word32 *pt2; @@ -1927,8 +1930,8 @@ Word16 wb_vad_ivas_fx( Word16 min_snr, sign_thr; Word32 L_snr, L_snr_sum; - Word32 ftmp, ftmp1, ftmp2; - Word16 m_noise_local, e_noise, e_num, m_num, snr_tmp, shift_snr, q_snr_tmp, q_snr; + Word32 ener, fr_enr, ftmp, ftmp1; + Word16 m_noise_local, e_noise, e_num, m_num, q_snr_tmp, q_snr; Word32 L_snr_tmp; Word16 snr_sumt; Word32 L_vad_thr; @@ -1947,7 +1950,7 @@ Word16 wb_vad_ivas_fx( Word16 nb_sig_snr; /* Q0 */ Word16 nv; - Word16 nv_ofs; /* Q8 */ + Word32 nv_ofs; /* Q24 */ Word32 L_snr_sum_HE_SAD; /* Q4 */ Word16 snr_sum_HE_SAD; /*Q8 log */ Word16 sign_thr_HE_SAD, min_snr_HE_SAD; @@ -1957,13 +1960,14 @@ Word16 wb_vad_ivas_fx( Word32 L_snr_sum_ol; Word16 snr_sum_ol; /* Q8 log */ - Word32 L_snr_outlier; + Word32 L_snr_outlier, L_snr_outlier_Q4; Word16 snr_outlier_index; Word32 L_accum_ener_L; Word32 L_accum_ener_H; Word16 vad_bwidth_fx; Word16 last_7k2_coder_type; - Word16 q_shift; + Word16 q_shift, q_ener, q_diff1, q_diff2; + Word16 q_L_snr_sum_ol, e_snr, f_snr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -1978,7 +1982,7 @@ Word16 wb_vad_ivas_fx( move16(); /*thr1*/ move16(); /*thr2*/ move16(); /*nk*/ - move16(); /*nc*/ + move32(); /*nc*/ move16(); /*th_clean*/ move16(); /*flag*/ @@ -2051,12 +2055,12 @@ Word16 wb_vad_ivas_fx( { nk = 3277; move16(); /*0.1 Q15 */ - nc = 4122; - move16(); /*16.1 Q8 */ - nv = 525; - move16(); /* 2.05 Q8*/ - nv_ofs = 422; - move16(); /* 1.65 Q8*/ + nc = 270113178; + move32(); /*16.1 Q24 */ + nv = 8397; + move16(); /* 2.05 Q12*/ + nv_ofs = 27682406; + move32(); /* 1.65 Q24*/ th_clean = TH16_2_FX; move16(); /* 35 Q8 */ sign_thr = 21; @@ -2085,12 +2089,12 @@ Word16 wb_vad_ivas_fx( // move16(); nk = 3277; move16(); /* 0.1 Q15 */ - nc = 4096; - move16(); /* 16.0 Q8 */ - nv = 1024; - move16(); /* 4.0 Q8 */ - nv_ofs = 294; - move16(); /*1.15 Q8*/ + nc = 268435456; + move32(); /* 16.0 Q24 */ + nv = 16384; + move16(); /* 4.0 Q12 */ + nv_ofs = 19293798; + move32(); /*1.15 Q24*/ th_clean = TH8_1_FX; move16(); /*20 Q8 */ sign_thr = 28; @@ -2203,10 +2207,6 @@ Word16 wb_vad_ivas_fx( nb_sig_snr = 20; move16(); - pt1 = fr_bands; - pt2 = fr_bands + NB_BANDS; - pt3 = hNoiseEst->bckr_fx; - L_snr_sum = L_deposit_l( 0 ); L_snr_sum_HE_SAD = L_deposit_l( 0 ); Word16 q_snr_sum = 0; @@ -2226,81 +2226,89 @@ Word16 wb_vad_ivas_fx( q_snr = 0; move16(); move16(); - q_shift = add( sub( q_fr_bands, hNoiseEst->q_bckr ), 14 - 4 ); + + pt1 = fr_bands; + pt2 = fr_bands + NB_BANDS; + pt3 = hNoiseEst->bckr_fx; + + q_ener = s_min( q_fr_bands, hNoiseEst->q_enrO ); + q_diff1 = sub( q_ener, hNoiseEst->q_enrO ); + q_diff2 = sub( q_ener, q_fr_bands ); + q_shift = add( Q31 + Q1, sub( q_ener, hNoiseEst->q_bckr ) ); + FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) { - ftmp = L_add( *pt1++, 0 ); - ftmp1 = L_add( *pt2++, 0 ); - ftmp2 = L_add( *pt3++, 0 ); + ener = L_shl( hNoiseEst->enrO_fx[i], q_diff1 ); // q_ener + ftmp = L_shl( *pt1++, q_diff2 ); // q_ener + ftmp1 = L_shl( *pt2++, q_diff2 ); // q_ener /*fr_enr = ( 0.2f * st->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 );*/ - L_tmp = Mult_32_16( hNoiseEst->enrO_fx[i], 6554 ); /* L_tmp(high word) = Qenr0fx*Q15+1 -16 -> Qener0 */ - L_tmp1 = Madd_32_16( L_tmp, ftmp, 13107 ); /* 13107 = .4 in Q15 */ - L_tmp1 = Madd_32_16( L_tmp1, ftmp1, 13107 ); /* L_tmp1 re_used a bit later for final snr[i]*/ - - L_tmp2 = Madd_32_16( L_tmp, ftmp, 9830 ); /* 9830 = 0.3 in Q15 */ - L_tmp2 = Msub_32_16( L_tmp2, ftmp1, -16384 ); /* -16384= -0.5 in Q15 */ + L_tmp = Mpy_32_16_1( ener, 13107 /* 0.2 in Q16 */ ); // q_ener+1 + fr_enr = Madd_32_16( Madd_32_16( L_tmp, ftmp, 26214 /* 0.4 in Q16 */ ), ftmp1, 26214 /* 0.4 in Q16 */ ); // q_ener+1 IF( GT_32( ftmp, ftmp1 ) ) { - /*snr[i] = ( 0.2f * st->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 ) / ftmp2 ;*/ - /*snr[i] = L_tmp1/(ftmp2) */ - IF( ftmp2 != 0 ) + /* snr[i] = ( 0.2f * hNoiseEst->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 ) / *pt3++; */ + IF( *pt3 != 0 ) { - e_num = norm_l( L_tmp1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+e_num-16 - - e_noise = norm_l( ftmp2 ); - m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 + /* Since fr_enr = 0.2f * hNoiseEst->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 */ + e_num = sub( norm_l( fr_enr ), 1 ); + m_num = extract_h( L_shl( fr_enr, e_num ) ); // q_ener+1+e_num-16 - m_num = shr( m_num, 1 ); // q_fr_bands-1+e_num-16 - shift_snr = add( sub( e_num, e_noise ), q_shift ); + e_noise = norm_l( *pt3 ); + m_noise_local = extract_h( L_shl( *pt3++, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - snr_tmp = div_s( m_num, m_noise_local ); // q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise - L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ + L_snr = L_deposit_h( div_s( m_num, m_noise_local ) ); // 31+(q_ener+1+e_num-16)-(hNoiseEst->q_bckr+e_noise-16) + q_snr_tmp = add( q_shift, sub( e_num, e_noise ) ); } ELSE { - L_snr = L_shl_o( L_tmp1, sub( Q4, q_fr_bands ), &Overflow ); // q_fr_bands -> Q4 + L_snr = Mpy_32_16_1( fr_enr, 18286 /* (1/E_MIN) in Q6 */ ); // q_ener+1+6-15 + q_snr_tmp = sub( q_ener, 8 ); } } ELSE { - /*snr[i] = ( 0.2f * st->enrO[i] + 0.3f * ftmp + 0.5f * ftmp1 ) / ftmp2 ;*/ - /*snr[i] =L_tmp2/( ftmp2 ) */ - IF( ftmp2 != 0 ) - { - e_num = norm_l( L_tmp2 ); - m_num = extract_h( L_shl( L_tmp2, e_num ) ); // q_fr_bands+e_num-16 + /* snr[i] = ( 0.2f * hNoiseEst->enrO[i] + 0.3f * ftmp + 0.5f * ftmp1 ) / *pt3++; */ + /* Since, L_tmp = 0.2f * hNoiseEst->enrO[i] */ + L_tmp = Msub_32_16( Madd_32_16( L_tmp, ftmp, 19661 /* 0.3 in Q16 */ ), ftmp1, -32768 /* -0.5 in Q16 */ ); // q_ener+1 - e_noise = norm_l( ftmp2 ); - m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 + IF( *pt3 != 0 ) + { + e_num = sub( norm_l( L_tmp ), 1 ); + m_num = extract_h( L_shl( L_tmp, e_num ) ); // q_ener+1+e_num-16 - m_num = shr( m_num, 1 ); // q_fr_bands-1+e_num-16 - shift_snr = add( sub( e_num, e_noise ), q_shift ); + e_noise = norm_l( *pt3 ); + m_noise_local = extract_h( L_shl( *pt3++, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - snr_tmp = div_s( m_num, m_noise_local ); // q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise - L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ + L_snr = L_deposit_h( div_s( m_num, m_noise_local ) ); // 31+(q_ener+1+e_num-16)-(hNoiseEst->q_bckr+e_noise-16) + q_snr_tmp = add( q_shift, sub( e_num, e_noise ) ); } ELSE { - L_snr = L_shl_o( L_tmp2, sub( Q4, q_fr_bands ), &Overflow ); // q_fr_bands -> Q4 + L_snr = Mpy_32_16_1( L_tmp, 18286 /* (1/E_MIN) in Q6 */ ); // q_ener+1+6-15 + q_snr_tmp = sub( q_ener, 8 ); } } - IF( LT_32( L_snr, 2 * ( 1 << 4 ) ) ) + if ( LT_32( L_snr, L_shl_sat( 2, q_snr_tmp ) ) ) { nb_sig_snr = sub( nb_sig_snr, 1 ); /* nb_sig_snr--; */ } - L_snr = L_max( L_snr, 1 * ( 1 << 4 ) ); /* if ( snr[i] < 1 ){snr[i] = 1;}*/ - + IF( LT_32( L_snr, L_shl_sat( 1, q_snr_tmp ) ) ) + { + L_snr = ONE_IN_Q30; + q_snr_tmp = Q30; + move32(); + move16(); + } /* snr[i] = (float)log10(snr[i]); */ Word16 exp = norm_l( L_snr ); Word16 val = Log2_norm_lc( L_shl( L_snr, exp ) ); - exp = sub( sub( 30, exp ), Q4 ); - L_snr = L_mac( L_deposit_h( exp ), val, 1 ); // Q16 - L_snr = Mpy_32_16_1( L_snr, 9864 /* log2 in Q15 */ ); // Q16 + exp = sub( sub( 30, exp ), q_snr_tmp ); + L_snr = L_mac( val, exp, ONE_IN_Q14 ); // Q15 + L_snr = Mpy_32_16_1( L_snr, 19728 /* log2 in Q16 */ ); // Q16 /* snr_sumt += snr[i];*/ L_snr_sumt = L_add( L_snr_sumt, L_snr ); // Q16 @@ -2373,22 +2381,22 @@ Word16 wb_vad_ivas_fx( L_mssnr_hov = BASOP_Util_Add_Mant32Exp( L_mssnr_hov, L_mssnr_hov_e, L_msnr, L_msnr_e, &L_mssnr_hov_e ); /*L_mssnr_hov_e mssnr_hov += msnr; */ /* recompute after he1 modifications */ - /* snr[i] = fr_enr / st->bckr[i] = L_tmp1/st->bckr[i];*/ + /* snr[i] = fr_enr / st->bckr[i] ;*/ IF( hNoiseEst->bckr_fx[i] != 0 ) { - e_num = sub( norm_l( L_tmp1 ), 1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+e_num-16 + e_num = sub( norm_l( fr_enr ), 1 ); + m_num = extract_h( L_shl( fr_enr, e_num ) ); // q_ener+1+e_num-16 e_noise = norm_l( hNoiseEst->bckr_fx[i] ); m_noise_local = extract_h( L_shl( hNoiseEst->bckr_fx[i], e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - L_snr_tmp = L_deposit_h( div_s( m_num, m_noise_local ) ); // 32+q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise - q_snr_tmp = add( 31, sub( add( q_fr_bands, e_num ), add( hNoiseEst->q_bckr, e_noise ) ) ); + L_snr_tmp = L_deposit_h( div_s( m_num, m_noise_local ) ); // 31+q_ener+1+e_num-hNoiseEst->q_bckr-e_noise + q_snr_tmp = add( 32, sub( add( q_ener, e_num ), add( hNoiseEst->q_bckr, e_noise ) ) ); } ELSE { - L_snr_tmp = Mpy_32_16_1( L_tmp1, 18286 /* 1/E_MIN in Q6 */ ); // q_fr_bands-9 - q_snr_tmp = sub( q_fr_bands, 9 ); + L_snr_tmp = Mpy_32_16_1( fr_enr, 18286 /* 1/E_MIN in Q6 */ ); // q_ener+1+6-15 + q_snr_tmp = sub( q_ener, 8 ); } /* conditional snrsum, snr_sum = snr_sum + snr[i];*/ @@ -2446,11 +2454,9 @@ Word16 wb_vad_ivas_fx( move16(); } } /* end of band loop */ - L_snr_sum = L_shl_o( L_snr_sum, sub( 4, q_snr_sum ), &Overflow ); // q_snr_sum->q4 L_snr_sum_HE_SAD = L_shl_o( L_snr_sum_HE_SAD, sub( 4, q_snr_sum_HE_SAD ), &Overflow ); // q_snr_sum_HE_SAD->q4 - L_snr_outlier = L_shl_sat( L_snr_outlier, sub( Q4, q_snr ) ); // q_snr -> Q4 - snr_sumt = extract_h( L_shl( L_snr_sumt, Q4 ) ); // Q16 -> Q4 + snr_sumt = extract_h( L_shl( L_snr_sumt, Q4 ) ); // Q16 -> Q4 test(); test(); @@ -2482,51 +2488,66 @@ Word16 wb_vad_ivas_fx( } } + L_snr_outlier_Q4 = L_shl_sat( L_snr_outlier, sub( Q4, q_snr ) ); // Q4 /* Separated SNR_SUM outlier modification */ - L_snr_sum_ol = L_snr_sum; /* snr_sum_ol = snr_sum; */ + /* snr_sum_ol = snr_sum; */ + L_snr_sum_ol = L_snr_sum; // q_snr_sum + q_L_snr_sum_ol = q_snr_sum; move32(); + move16(); test(); test(); test(); - IF( ( EQ_16( st_fx->max_band, 19 ) ) && LT_32( L_snr_outlier, MAX_SNR_OUTLIER_3_FX ) && GT_16( snr_outlier_index, 3 ) && LT_16( snr_outlier_index, MAX_SNR_OUTLIER_IND_FX ) ) + IF( ( EQ_16( st_fx->max_band, 19 ) ) && LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_3_FX ) && GT_16( snr_outlier_index, 3 ) && LT_16( snr_outlier_index, MAX_SNR_OUTLIER_IND_FX ) ) { + q_L_snr_sum_ol = s_min( add( norm_l( L_snr_sum_ol ), q_snr_sum ), add( norm_l( L_snr_outlier ), q_snr ) ); + L_tmp1 = L_shl( L_snr_sum_ol, sub( q_L_snr_sum_ol, q_snr_sum ) ); // q_L_snr_sum_ol + L_tmp2 = L_shl( L_snr_outlier, sub( q_L_snr_sum_ol, q_snr ) ); // q_L_snr_sum_ol test(); test(); IF( LT_32( L_accum_ener_H, Mult_32_16( L_accum_ener_L, INV_OUTLIER_THR_1_FX ) ) /* float:: (accum_ener_L*INV_OUTLIER_THR_1 > accum_ener_H ) !!! */ - || LT_32( L_snr_outlier, MAX_SNR_OUTLIER_1_FX ) ) + || LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_1_FX ) ) { - /* as weight1 is 1.0 we do not need to multiply here , i.e. no need to loose any precisison */ - L_snr_sum_ol = L_sub( L_snr_sum_ol, L_snr_outlier ); /*Q4 */ + /* snr_sum_ol = SNR_OUTLIER_WGHT_1 * ( snr_sum_ol - snr_outlier ); + As SNR_OUTLIER_WGHT_1 is 1.0f we do not need to multiply here , i.e. no need to loose any precisison */ + L_snr_sum_ol = L_sub( L_tmp1, L_tmp2 ); // q_L_snr_sum_ol } ELSE IF( LT_32( L_accum_ener_H, Mult_32_16( L_accum_ener_L, INV_OUTLIER_THR_2_FX ) ) /* float:: (accum_ener_L *INV_OUTLIER_THR_2 > accum_ener_H ) !!! */ - || LT_32( L_snr_outlier, MAX_SNR_OUTLIER_2_FX ) ) + || LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_2_FX ) ) { - /* L_snr_sum = SNR_OUTLIER_WGHT_2 * (snr_sum - snr_outlier); */ - - /* 1.01*x -> (1*x + 0.01*x) to not drop down to Q3 */ - L_tmp = L_sub( L_snr_sum_ol, L_snr_outlier ); - L_tmp2 = Mult_32_16( L_tmp, 20972 ); /* 0.01(in Q21)= 20972 Q4*Q21+1-16 -> Q10 */ - L_snr_sum_ol = L_add( L_tmp, L_shr( L_tmp2, 6 ) ); /* Q4 */ + /* snr_sum_ol = SNR_OUTLIER_WGHT_2 * (snr_sum_ol - snr_outlier); */ + L_snr_sum_ol = Mpy_32_32( 1084479242 /* 1.01f in Q30 */, L_sub( L_tmp1, L_tmp2 ) ); // q_L_snr_sum_ol+30-31 + q_L_snr_sum_ol = sub( q_L_snr_sum_ol, 1 ); } ELSE { - /* L_snr_sum = SNR_OUTLIER_WGHT_3 * (snr_sum - snr_outlier);*/ - /* 1.02*x -> (1*x + 0.02*x) to not drop down to Q3 */ - L_tmp = L_sub( L_snr_sum_ol, L_snr_outlier ); - L_tmp2 = Mult_32_16( L_tmp, 20972 ); /* 0.02(in Q20)= 20972 Q4*Q20+1-16 -> Q9 */ - L_snr_sum_ol = L_add( L_tmp, L_shr( L_tmp2, 5 ) ); /* Q4 */ + /* snr_sum_ol = SNR_OUTLIER_WGHT_2 * (snr_sum_ol - snr_outlier); */ + L_snr_sum_ol = Mpy_32_32( 1095216660 /* 1.02f in Q30 */, L_sub( L_tmp1, L_tmp2 ) ); // q_L_snr_sum_ol+30-31 + q_L_snr_sum_ol = sub( q_L_snr_sum_ol, 1 ); } } /*st_fx->snr_sum_vad_fx = 0.5f * st->snr_sum_vad + 0.5f * snr_sum_ol;*/ - hVAD->L_snr_sum_vad_fx = L_shr( L_add_o( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol, &Overflow ), 1 ); /*Q4*/ + q_snr_tmp = s_min( add( hVAD->q_L_snr_sum_vad, norm_l( hVAD->L_snr_sum_vad_fx ) ), add( norm_l( L_snr_sum_ol ), q_L_snr_sum_ol ) ); + /* 0.5f * st->snr_sum_vad */ + L_tmp1 = L_shl( hVAD->L_snr_sum_vad_fx, sub( sub( q_snr_tmp, 1 ), hVAD->q_L_snr_sum_vad ) ); // q_snr_tmp + /* 0.5f * snr_sum_ol */ + L_tmp2 = L_shl( L_snr_sum_ol, sub( sub( q_snr_tmp, 1 ), q_L_snr_sum_ol ) ); // q_snr_tmp + hVAD->L_snr_sum_vad_fx = L_add( L_tmp1, L_tmp2 ); // q_snr_tmp + hVAD->q_L_snr_sum_vad = q_snr_tmp; move32(); + move16(); /* snr_sum_ol = 10.0f * (float)log10( snr_sum_ol ); */ - snr_sum_ol = vad_snr_log_fx( L_snr_sum_ol, LG10 ); + e_snr = norm_l( L_snr_sum_ol ); + f_snr = Log2_norm_lc( L_shl( L_snr_sum_ol, e_snr ) ); // Q15 + e_snr = sub( sub( 30, e_snr ), q_L_snr_sum_ol ); + L_tmp = L_mac( f_snr, e_snr, ONE_IN_Q14 ); // Q15 + L_snr_sum_ol = Mpy_32_16_1( L_tmp, 24660 /* 10*log(2) in Q13 */ ); // Q13 + snr_sum_ol = extract_h( L_shl( L_snr_sum_ol, Q24 - Q13 ) ); // Q8 snr_sum = snr_sum_ol; move16(); /* note for NB no outlier modification */ @@ -2555,9 +2576,9 @@ Word16 wb_vad_ivas_fx( /*thr1 = nk * lp_snr + nc*1.0 + nv * ( st->Etot_v_h2 - nv_ofs); */ /* Linear function for noisy speech */ - L_tmp = L_shl( L_mult( sub( hNoiseEst->Etot_v_h2_fx, nv_ofs ), nv ), 7 ); /* Q8+Q8+1 +7 --> Q24 */ - L_tmp = L_mac( L_tmp, nc, (Word16) 32767 ); /* Q8+Q15+1 = Q24 */ - thr1 = mac_r( L_tmp, lp_snr, nk ); /* Q8+Q15+1 - 16 --> Q8 */ + L_tmp = L_shl( Mpy_32_16_1( L_sub( hNoiseEst->Etot_v_h2_32fx, nv_ofs ), nv ), 3 ); // Q24 (24+12-15+3) + L_tmp = L_add( L_tmp, nc ); // Q24 + thr1 = mac_r( L_tmp, lp_snr, nk ); // Q24 test(); IF( st_fx->element_mode > EVS_MONO && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) @@ -2624,33 +2645,38 @@ Word16 wb_vad_ivas_fx( test(); IF( ( LE_16( snr_outlier_index, 4 ) && ( st_fx->last_coder_type > UNVOICED ) && !st_fx->Opt_SC_VBR ) || ( LE_16( snr_outlier_index, 4 ) && ( last_7k2_coder_type > UNVOICED ) && st_fx->Opt_SC_VBR ) ) - - { - thr1_ol = sub( thr1_ol, (Word16) ( 1 << 8 ) ); /*thr1_ol = thr1 - 1.0f ; */ + /*thr1_ol = thr1 - 1.0f ; */ + thr1_ol = sub( thr1, ONE_IN_Q8 ); // Q8 + /*snr_sum_ol = 10.0f * (float)log10( hVAD->L_snr_sum_vad_fx );*/ - snr_sum_ol = vad_snr_log_fx( hVAD->L_snr_sum_vad_fx, LG10 ); /* snr in Q8 */ + e_snr = norm_l( hVAD->L_snr_sum_vad_fx ); + f_snr = Log2_norm_lc( L_shl( hVAD->L_snr_sum_vad_fx, e_snr ) ); // Q15 + e_snr = sub( sub( 30, e_snr ), hVAD->q_L_snr_sum_vad ); + L_tmp = L_mac( f_snr, e_snr, ONE_IN_Q14 ); // Q15 + L_snr_sum_ol = Mpy_32_16_1( L_tmp, 24660 /* 10*log(2) in Q13 */ ); // Q13 + snr_sum_ol = round_fx( L_shl( L_snr_sum_ol, Q24 - Q13 ) ); // Q8 } - ELSE IF( ( ( LE_16( st_fx->last_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR == 0 ) ) || - ( ( LE_16( last_7k2_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR != 0 ) ) ) - + ELSE IF( ( ( LE_16( st_fx->last_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR == 0 ) ) || + ( ( LE_16( last_7k2_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR != 0 ) ) ) { /* thr1_ol = thr1 + (float)(1.0f - 0.04f * snr_outlier); */ - L_tmp2 = Msub_32_16( (Word32) ( 1 << ( 24 - 16 ) ), L_snr_outlier, 20972 ); /* (1.0)Q24(Q8 in high 32bit word) - Q4*Q19+1 */ - tmp2 = round_fx( L_shl( L_tmp2, 16 ) ); /* high word is in Q8 */ - thr1_ol = add( thr1_ol, tmp2 ); /* (Q8 , Q8) */ + L_tmp = Mpy_32_16_1( L_snr_outlier, 20972 /*0.04f in Q19*/ ); // q_snr+19-15 + L_tmp = L_shl( L_tmp, sub( Q24 - 4, q_snr ) ); // Q24 (24-(q_nsr+4)) + tmp2 = round_fx( L_sub( ONE_IN_Q24, L_tmp ) ); // Q8 + thr1_ol = add( thr1, tmp2 ); // Q8 } ELSE { - /*thr1_ol = thr1 + max(0, (float)(0.6f - 0.01f * L_snr_outlier)); */ - thr1_ol = thr1; - move16(); - L_tmp2 = Msub_32_16( (Word32) 614, L_snr_outlier, 20972 ); /* .6*1024= */ /* 0.6 Q26(Q10 in high word) - Q4*Q21+1 */ - tmp2 = round_fx( L_shl_o( L_tmp2, 14, &Overflow ) ); /* Q10(high word)+ 14 -16 --> Q8*/ - IF( L_tmp2 > 0 ) - { - thr1_ol = add( thr1_ol, tmp2 ); /* Q24 >>16 + Q8 */ - } + /*thr1_ol = thr1 + max(0, (float)(0.6f - 0.01f * snr_outlier)); */ + /* Saturation is added in the below step for 0.04f * snr_outlier in Q24. + In case of saturation, 0.04f * snr_outlier will be much greater than 0.6f and (0.6f - 0.01f * snr_outlier) becomes negative. + max(0, (float)(0.6f - 0.01f * snr_outlier)) gives zero. Hence addition of saturation has no impact */ + L_tmp = Mpy_32_16_1( L_snr_outlier, 20972 /*0.04f in Q21*/ ); // q_snr+21-15 + L_tmp = L_shl_sat( L_tmp, sub( Q24 - 6, q_snr ) ); // Q24 (24-(q_nsr+6)) + tmp2 = round_fx( L_sub( 10066330 /* 0.6 in Q24*/, L_tmp ) ); // Q8 + tmp2 = s_max( 0, tmp2 ); // Q8 + thr1_ol = add( thr1, tmp2 ); // Q8 } } -- GitLab From 0d81dfcd22ce7ba9e51ebc2b674238a55027bde0 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 15 May 2025 12:44:47 +0530 Subject: [PATCH 1199/1221] Clang formatting changes --- lib_enc/stat_enc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 1097c6a27..caca3173e 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -565,8 +565,8 @@ typedef struct noise_estimation_structure Word16 lt_aEn_zero_fx; /* Q15 */ Word16 Etot_v_h2_fx; - Word32 Etot_v_h2_32fx; /* Q24 */ - Word16 sign_dyn_lp_fx; /*Q8*/ + Word32 Etot_v_h2_32fx; /* Q24 */ + Word16 sign_dyn_lp_fx; /*Q8*/ Word16 Etot_st_est_fx; /* Q8 Noise estimation - short term estimate of E{ Etot } */ Word16 Etot_sq_st_est_fx; /* Q2 Noise estimation - short term estimate of E{ Etot^2 } */ -- GitLab From 7e2672a529a79cc7e8a5f1037fb6b8295926e431 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 15 May 2025 14:23:40 +0530 Subject: [PATCH 1200/1221] Fix for 3GPP issue 1531: Low-bitrate OMASA shows a bit high MLD (over 10) in BASOP decoder rendering to binaural Link #1531 --- lib_dec/FEC_clas_estim_fx.c | 16 ++++-- .../ivas_dirac_dec_binaural_functions_fx.c | 49 ++++++++++++++---- lib_rend/ivas_dirac_rend_fx.c | 51 ++++++++++++------- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/lib_dec/FEC_clas_estim_fx.c b/lib_dec/FEC_clas_estim_fx.c index e56a77be1..2bd38153a 100644 --- a/lib_dec/FEC_clas_estim_fx.c +++ b/lib_dec/FEC_clas_estim_fx.c @@ -285,7 +285,17 @@ void FEC_clas_estim_fx( Corre( &pt1[pos], &pt1[pos - T0], T0, &cor_max[0] ); - T0 = mult_r_sat( add_sat( pitch[2], pitch[3] ), 256 ); + IF( NE_16( st_fx->element_mode, EVS_MONO ) ) + { + IF( LT_16( sub( pos, T0 ), sub( L_frame, L_SUBFR ) ) ) + { + T0 = mult_r_sat( add_sat( pitch[2], pitch[3] ), 256 ); + } + } + ELSE + { + T0 = mult_r_sat( add_sat( pitch[2], pitch[3] ), 256 ); + } pos_limit = sub( L_frame, L_SUBFR ); j = s_min( 1, s_max( 0, sub( pos, pos_limit ) ) ); Ltmp = L_deposit_l( cor_max[0] ); @@ -725,8 +735,8 @@ void FEC_clas_estim_fx( } /* Do the classification only - - MODE1: when the class is not transmitted in the bitstream - - MODE2: on good frames (classifier is also called for bfi=1) */ + - MODE1: when the class is not transmitted in the bitstream + - MODE2: on good frames (classifier is also called for bfi=1) */ /* update the memory of synthesis for frame class estimation */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 16fefa3bb..c47052d5f 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -3584,24 +3584,53 @@ static void matrixTransp1Mul_fx( Word16 chA, chB; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); + Word64 tmp_outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word64 tmp_outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 q_tmp_outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 q_tmp_outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word64 tmp64_1, tmp64_2; + Word16 tmp16, q_common = 63; + move16(); + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { - outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), - Are_fx[1][chA], Bre_fx[1][chB] ), - Aim_fx[0][chA], Bim_fx[0][chB] ), - Aim_fx[1][chA], Bim_fx[1][chB] ); + tmp64_1 = W_mac_32_32( W_mult_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), Are_fx[1][chA], Bre_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 ) + tmp64_2 = W_mac_32_32( W_mult_32_32( Aim_fx[0][chA], Bim_fx[0][chB] ), Aim_fx[1][chA], Bim_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 ) + tmp_outRe_fx[chA][chB] = W_add( tmp64_1, tmp64_2 ); // Q: add( add( q_A, q_B ), 1 ) + move64(); + tmp16 = W_norm( tmp_outRe_fx[chA][chB] ); + tmp_outRe_fx[chA][chB] = W_shl( tmp_outRe_fx[chA][chB], tmp16 ); // Q:add( tmp16, add( add( q_A, q_B ), 1 ) ) + move64(); + q_tmp_outRe_fx[chA][chB] = add( tmp16, add( add( q_A, q_B ), 1 ) ); + move16(); + q_common = s_min( q_tmp_outRe_fx[chA][chB], q_common ); + + + tmp64_1 = W_mac_32_32( W_mult_32_32( Are_fx[0][chA], Bim_fx[0][chB] ), Are_fx[1][chA], Bim_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 ) + tmp64_2 = W_mac_32_32( W_mult_32_32( Aim_fx[0][chA], Bre_fx[0][chB] ), Aim_fx[1][chA], Bre_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 ) + tmp_outIm_fx[chA][chB] = W_sub( tmp64_1, tmp64_2 ); // Q: add( add( q_A, q_B ), 1 ) + move64(); + tmp16 = W_norm( tmp_outIm_fx[chA][chB] ); + tmp_outIm_fx[chA][chB] = W_shl( tmp_outIm_fx[chA][chB], tmp16 ); // Q:add( tmp16, add( add( q_A, q_B ), 1 ) ) + move64(); + q_tmp_outIm_fx[chA][chB] = add( tmp16, add( add( q_A, q_B ), 1 ) ); + move16(); + q_common = s_min( q_tmp_outIm_fx[chA][chB], q_common ); + } + } + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + { + outRe_fx[chA][chB] = W_extract_h( W_shl( tmp_outRe_fx[chA][chB], sub( q_common, q_tmp_outRe_fx[chA][chB] ) ) ); move32(); - outIm_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][chA], Bim_fx[0][chB] ), - Are_fx[1][chA], Bim_fx[1][chB] ), - Aim_fx[0][chA], Bre_fx[0][chB] ), - Aim_fx[1][chA], Bre_fx[1][chB] ); + outIm_fx[chA][chB] = W_extract_h( W_shl( tmp_outIm_fx[chA][chB], sub( q_common, q_tmp_outIm_fx[chA][chB] ) ) ); move32(); } } - *q_out = sub( add( q_A, q_B ), 31 ); - + *q_out = sub( q_common, 32 ); move16(); if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) ) { diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index 06b37ff5a..063c70f66 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1754,7 +1754,7 @@ void protoSignalComputation2_fx( Word32 RealSubtract_fx, ImagSubtract_fx; Word32 left_bb_power_fx, right_bb_power_fx, total_bb_power_fx, lr_bb_power_fx; Word32 left_hi_power_fx, right_hi_power_fx, total_hi_power_fx, lr_hi_power_fx; - Word32 sum_power_fx, Left_power_fx, Right_power_fx; + Word32 sum_power_fx, Left_power_fx, Right_power_fx, Total_power_fx; Word16 q_lr_bb_power, q_lr_hi_power; Word32 lr_total_bb_ratio_fx, lr_total_hi_ratio_fx; Word32 min_sum_total_ratio_fx, min_sum_total_ratio_db_fx; @@ -2120,7 +2120,10 @@ void protoSignalComputation2_fx( #else q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); #endif - + Word16 exp_left_hi_power = 0, exp_right_hi_power = 0, exp_total_hi_power = 0, exp_temppp; + move16(); + move16(); + move16(); FOR( l = 0; l < num_freq_bands; l++ ) { #ifdef FIX_867_CLDFB_NRG_SCALE @@ -2164,19 +2167,30 @@ void protoSignalComputation2_fx( left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power #endif - IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { - left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power - right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power - // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); -#ifdef FIX_867_CLDFB_NRG_SCALE - total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power -#else - total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power -#endif + W_tmp1 = W_add( W_mult0_32_32( RealBuffer_fx[0][0][l], RealBuffer_fx[0][0][l] ), W_mult0_32_32( ImagBuffer_fx[0][0][l], ImagBuffer_fx[0][0][l] ) ); + q_shift = W_norm( W_tmp1 ); + Left_power_fx = W_extract_h( W_shl( W_tmp1, q_shift ) ); + exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) ); + + left_hi_power_fx = BASOP_Util_Add_Mant32Exp( left_hi_power_fx, exp_left_hi_power, Left_power_fx, exp_temppp, &exp_left_hi_power ); // exp:exp_left_hi_power + + W_tmp2 = W_add( W_mult0_32_32( RealBuffer_fx[1][0][l], RealBuffer_fx[1][0][l] ), W_mult0_32_32( ImagBuffer_fx[1][0][l], ImagBuffer_fx[1][0][l] ) ); + q_shift = W_norm( W_tmp2 ); + Right_power_fx = W_extract_h( W_shl( W_tmp2, q_shift ) ); + exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) ); + + right_hi_power_fx = BASOP_Util_Add_Mant32Exp( right_hi_power_fx, exp_right_hi_power, Right_power_fx, exp_temppp, &exp_right_hi_power ); // exp:exp_right_hi_power + + W_tmp2 = W_add( W_tmp1, W_tmp2 ); + q_shift = W_norm( W_tmp2 ); + Total_power_fx = W_extract_h( W_shl( W_tmp2, q_shift ) ); + exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) ); + + total_hi_power_fx = BASOP_Util_Add_Mant32Exp( total_hi_power_fx, exp_total_hi_power, Total_power_fx, exp_temppp, &exp_total_hi_power ); // exp:exp_total_hi_power } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) @@ -2185,8 +2199,8 @@ void protoSignalComputation2_fx( re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift #else - re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift - im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift + im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift #endif sum_power_fx = Madd_32_32( Mpy_32_32( re_aux, re_aux ), im_aux, im_aux ); // 2*(q_cldfb+temp_q_shift)-31 @@ -2216,7 +2230,7 @@ void protoSignalComputation2_fx( move32(); } #else - temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) { stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp @@ -2704,15 +2718,16 @@ void protoSignalComputation2_fx( lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 #ifdef FIX_867_CLDFB_NRG_SCALE - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), exp_left_hi_power, Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); move16(); - stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), exp_right_hi_power, Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); move32(); stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), exp_total_hi_power, Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); #else stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); -- GitLab From dd2dc9c9d2b82b9a51bae57f11211c15c46cbedb Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 25 Apr 2025 09:56:03 +0200 Subject: [PATCH 1201/1221] replaced the down mix channel floating point code with 64 bit fix point. WMOPS went from total 150.00 263.631 365.398 357.230 to total 150.00 244.736 315.064 308.406 for ./IVAS_cod -mc 7_1_4 128000 48 scripts/testv/stv714MC48c.wav out.128 --- lib_enc/ivas_mc_param_enc_fx.c | 123 +++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 0c996b25a..e8e3fd61a 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -29,7 +29,8 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +#define MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#define CONVERT64( x_64, y_fx, y_e ) { Word16 norm; norm=W_norm(x_64); y_fx = W_extract_h( W_shl( x_64, norm ) ); y_e = sub( sub( 35, gb ), norm ); } #include #include #include "options.h" @@ -649,10 +650,15 @@ static void ivas_param_mc_param_est_enc_fx( Word32 *p_slot_frame_f_real_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - real part */ Word32 *p_slot_frame_f_imag_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - imag part */ +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + Word64 dmx_real_64[PARAM_MC_MAX_TRANSPORT_CHANS]; + Word64 dmx_imag_64[PARAM_MC_MAX_TRANSPORT_CHANS]; +#else Word32 dmx_real_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Real Part */ Word16 dmx_real_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Real Part */ Word32 dmx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ +#endif Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE @@ -774,6 +780,26 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + Word64 real_64; + Word64 imag_64; + + real_64 = 0; + imag_64 = 0; + move64(); + move64(); + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) ); + imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) ); + p_dmx_fac_fx++; + } + dmx_real_64[ch_idx1] = real_64; + dmx_imag_64[ch_idx1] = imag_64; + move64(); + move64(); + +#else #ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE dmx_real_fx[ch_idx1] = 0; move32(); @@ -814,14 +840,33 @@ static void ivas_param_mc_param_est_enc_fx( move16(); move32(); move16(); +#endif + #endif } /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + CONVERT64(dmx_real_64[ch_idx1], a_fx, a_e ); + CONVERT64(dmx_imag_64[ch_idx1], b_fx, b_e ); + move32(); + move32(); + move16(); + move16(); +#endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + CONVERT64(dmx_real_64[ch_idx2], c_fx, c_e ); + CONVERT64(dmx_imag_64[ch_idx2], d_fx, d_e ); + move32(); + move32(); + move16(); + move16(); + +#else a_fx = dmx_real_fx[ch_idx1]; move32(); a_e = dmx_real_e[ch_idx1]; @@ -838,6 +883,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); d_e = dmx_imag_e[ch_idx2]; move16(); +#endif /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); @@ -858,7 +904,6 @@ static void ivas_param_mc_param_est_enc_fx( move32(); FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { - Word16 norm; c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band]; d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band]; move32(); @@ -870,10 +915,6 @@ static void ivas_param_mc_param_est_enc_fx( W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) ); move64(); - // convert the 64 bit fixpoint back into the 48 bit float format - norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); - Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); - Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = sub( sub( 62, gb ), norm ); } } #else @@ -953,6 +994,26 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + Word64 real_64; + Word64 imag_64; + + real_64 = 0; + imag_64 = 0; + move64(); + move64(); + + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) ); + imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) ); + p_dmx_fac_fx++; + } + dmx_real_64[ch_idx1] = real_64; + dmx_imag_64[ch_idx1] = imag_64; + move64(); + move64(); +#else #ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE dmx_real_fx[ch_idx1] = 0; move32(); @@ -997,12 +1058,22 @@ static void ivas_param_mc_param_est_enc_fx( move32(); dmx_imag_e[ch_idx1] = imag_e; move16(); +#endif + #endif } /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + CONVERT64( dmx_real_64[ch_idx1], a_fx, a_e ); + CONVERT64( dmx_imag_64[ch_idx1], b_fx, b_e ); + move32(); + move32(); + move16(); + move16(); +#else #ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; move32(); @@ -1012,9 +1083,24 @@ static void ivas_param_mc_param_est_enc_fx( move32(); b_e = dmx_imag_e[ch_idx1]; move16(); +#endif + #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + CONVERT64( dmx_real_64[ch_idx2], c_fx, c_e ); + CONVERT64( dmx_imag_64[ch_idx2], d_fx, d_e ); + move32(); + move32(); + move16(); + move16(); + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, + &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); +#else #ifndef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; move32(); @@ -1042,6 +1128,7 @@ static void ivas_param_mc_param_est_enc_fx( L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, dmx_real_fx[ch_idx2] ), add( a_e, dmx_real_e[ch_idx2] ), Mpy_32_32( b_fx, dmx_imag_fx[ch_idx2] ), add( b_e, dmx_imag_e[ch_idx2] ), &tmp_e ); Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); +#endif #endif move32(); } @@ -1075,7 +1162,6 @@ static void ivas_param_mc_param_est_enc_fx( move32(); FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) { - Word16 norm; c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band]; d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band]; move32(); @@ -1084,10 +1170,6 @@ static void ivas_param_mc_param_est_enc_fx( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) ); move64(); - // convert the 64 bit fixpoint back into the 48 bit float format - norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); - Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); - Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = sub( sub( 62, gb ), norm ); } #else FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) @@ -1135,14 +1217,6 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) { - Cy_sum_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; - move32(); - Cy_sum_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; - move16(); - Cy_sum_fx[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; - move32(); - Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; - move16(); #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move64(); @@ -1153,6 +1227,14 @@ static void ivas_param_mc_param_est_enc_fx( Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move64(); #else + Cy_sum_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move32(); + Cy_sum_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move16(); + Cy_sum_fx[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move32(); + Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move16(); Cy_sum_imag_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move32(); Cy_sum_imag_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; @@ -1174,7 +1256,7 @@ static void ivas_param_mc_param_est_enc_fx( move64(); Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move64(); -#endif +#else Cy_sum_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; move32(); Cy_sum_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; @@ -1183,6 +1265,7 @@ static void ivas_param_mc_param_est_enc_fx( move32(); Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; move16(); +#endif } } } -- GitLab From dcb916fba996abeea2e53e2a2097283282b6dc6a Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 25 Apr 2025 10:03:19 +0200 Subject: [PATCH 1202/1221] applied the clang patch --- lib_enc/ivas_mc_param_enc_fx.c | 37 +++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index e8e3fd61a..270fbeebd 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -29,8 +29,14 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ -#define MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE -#define CONVERT64( x_64, y_fx, y_e ) { Word16 norm; norm=W_norm(x_64); y_fx = W_extract_h( W_shl( x_64, norm ) ); y_e = sub( sub( 35, gb ), norm ); } +#define MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#define CONVERT64( x_64, y_fx, y_e ) \ + { \ + Word16 norm; \ + norm = W_norm( x_64 ); \ + y_fx = W_extract_h( W_shl( x_64, norm ) ); \ + y_e = sub( sub( 35, gb ), norm ); \ + } #include #include #include "options.h" @@ -650,7 +656,7 @@ static void ivas_param_mc_param_est_enc_fx( Word32 *p_slot_frame_f_real_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - real part */ Word32 *p_slot_frame_f_imag_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - imag part */ -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE Word64 dmx_real_64[PARAM_MC_MAX_TRANSPORT_CHANS]; Word64 dmx_imag_64[PARAM_MC_MAX_TRANSPORT_CHANS]; #else @@ -659,8 +665,8 @@ static void ivas_param_mc_param_est_enc_fx( Word32 dmx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ #endif - Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ - Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ + Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ + Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; @@ -780,7 +786,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE Word64 real_64; Word64 imag_64; @@ -848,9 +854,9 @@ static void ivas_param_mc_param_est_enc_fx( /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE - CONVERT64(dmx_real_64[ch_idx1], a_fx, a_e ); - CONVERT64(dmx_imag_64[ch_idx1], b_fx, b_e ); +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + CONVERT64( dmx_real_64[ch_idx1], a_fx, a_e ); + CONVERT64( dmx_imag_64[ch_idx1], b_fx, b_e ); move32(); move32(); move16(); @@ -858,9 +864,9 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE - CONVERT64(dmx_real_64[ch_idx2], c_fx, c_e ); - CONVERT64(dmx_imag_64[ch_idx2], d_fx, d_e ); +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE + CONVERT64( dmx_real_64[ch_idx2], c_fx, c_e ); + CONVERT64( dmx_imag_64[ch_idx2], d_fx, d_e ); move32(); move32(); move16(); @@ -914,7 +920,6 @@ static void ivas_param_mc_param_est_enc_fx( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) ); move64(); - } } #else @@ -994,7 +999,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE Word64 real_64; Word64 imag_64; @@ -1066,7 +1071,7 @@ static void ivas_param_mc_param_est_enc_fx( /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE CONVERT64( dmx_real_64[ch_idx1], a_fx, a_e ); CONVERT64( dmx_imag_64[ch_idx1], b_fx, b_e ); move32(); @@ -1088,7 +1093,7 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE CONVERT64( dmx_real_64[ch_idx2], c_fx, c_e ); CONVERT64( dmx_imag_64[ch_idx2], d_fx, d_e ); move32(); -- GitLab From 17ea3a460bdc04b7a9bd55d8cc947e792dfcaefe Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 25 Apr 2025 10:13:55 +0200 Subject: [PATCH 1203/1221] removed a warning. --- lib_enc/ivas_mc_param_enc_fx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 270fbeebd..f7f274b48 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -752,7 +752,10 @@ static void ivas_param_mc_param_est_enc_fx( #if defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE ) || defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE ) Word16 gb = find_guarded_bits_fx( l_ts ); +#ifndef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE Word16 add20gb = add( 20, gb ); +#endif + #endif FOR( ts = start_ts; ts < num_time_slots; ts++ ) -- GitLab From 0f7493762b47726945321f8656eb9462934a8a6d Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Fri, 25 Apr 2025 12:49:17 +0200 Subject: [PATCH 1204/1221] moved the define for the merge request into options.h. --- lib_com/options.h | 1 + lib_enc/ivas_mc_param_enc_fx.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index cbc77b6e7..8cb4f0368 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,6 +86,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ +#define MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of dmx calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Requires MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index f7f274b48..184a982d5 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -29,7 +29,6 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ -#define MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE #define CONVERT64( x_64, y_fx, y_e ) \ { \ Word16 norm; \ -- GitLab From 5babfdc8bba989670937eef2dd6d8f3ae5e4a0f3 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 28 Apr 2025 10:32:56 +0200 Subject: [PATCH 1205/1221] macro names. --- lib_com/options.h | 2 +- lib_enc/ivas_mc_param_enc_fx.c | 60 ++++++++++++++++------------------ 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 8cb4f0368..1b5760f40 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,7 +86,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ -#define MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of dmx calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Requires MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ +#define MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of dmx calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Requires MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE. */ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 184a982d5..41d15c241 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -29,7 +29,16 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ -#define CONVERT64( x_64, y_fx, y_e ) \ + +// helper macros to convert the 64 bitt accumulators into the 48 bit float format +#define CONVERT_CY( x_64, y_fx, y_e ) \ + { \ + Word16 norm; \ + norm = W_norm( x_64 ); \ + y_fx = W_extract_h( W_shl( x_64, norm ) ); \ + y_e = sub( sub( 62, gb ), norm ); \ + } +#define CONVERT_DMX( x_64, y_fx, y_e ) \ { \ Word16 norm; \ norm = W_norm( x_64 ); \ @@ -655,7 +664,7 @@ static void ivas_param_mc_param_est_enc_fx( Word32 *p_slot_frame_f_real_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - real part */ Word32 *p_slot_frame_f_imag_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - imag part */ -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word64 dmx_real_64[PARAM_MC_MAX_TRANSPORT_CHANS]; Word64 dmx_imag_64[PARAM_MC_MAX_TRANSPORT_CHANS]; #else @@ -751,7 +760,7 @@ static void ivas_param_mc_param_est_enc_fx( #if defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE ) || defined( IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE ) Word16 gb = find_guarded_bits_fx( l_ts ); -#ifndef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifndef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word16 add20gb = add( 20, gb ); #endif @@ -788,7 +797,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word64 real_64; Word64 imag_64; @@ -856,9 +865,9 @@ static void ivas_param_mc_param_est_enc_fx( /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE - CONVERT64( dmx_real_64[ch_idx1], a_fx, a_e ); - CONVERT64( dmx_imag_64[ch_idx1], b_fx, b_e ); +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE + CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e ); + CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e ); move32(); move32(); move16(); @@ -866,9 +875,9 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE - CONVERT64( dmx_real_64[ch_idx2], c_fx, c_e ); - CONVERT64( dmx_imag_64[ch_idx2], d_fx, d_e ); +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE + CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e ); + CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e ); move32(); move32(); move16(); @@ -1001,7 +1010,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word64 real_64; Word64 imag_64; @@ -1073,9 +1082,9 @@ static void ivas_param_mc_param_est_enc_fx( /* Cx for transport channels */ FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE - CONVERT64( dmx_real_64[ch_idx1], a_fx, a_e ); - CONVERT64( dmx_imag_64[ch_idx1], b_fx, b_e ); +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE + CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e ); + CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e ); move32(); move32(); move16(); @@ -1095,9 +1104,9 @@ static void ivas_param_mc_param_est_enc_fx( #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { -#ifdef MERGE_REQUEST_1472_SPEEDUIP_ivas_mc_param_enc_fx_NONBE - CONVERT64( dmx_real_64[ch_idx2], c_fx, c_e ); - CONVERT64( dmx_imag_64[ch_idx2], d_fx, d_e ); +#ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE + CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e ); + CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e ); move32(); move32(); move16(); @@ -1310,11 +1319,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( k = 0; k < nchan_input; ++k ) { #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE - Word16 norm; - // convert the 64 bit fixpoint back into the 48 bit float format - norm = W_norm( Cy_sum_real_64[cur_param_band][k][k] ); - Nrg_fx[k] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][k][k], norm ) ); - Nrg_e[k] = sub( sub( 62, gb ), norm ); + CONVERT_CY( Cy_sum_real_64[cur_param_band][k][k], Nrg_fx[k], Nrg_e[k] ); #else Nrg_fx[k] = Cy_sum_fx[cur_param_band][k][k]; move32(); @@ -1451,10 +1456,7 @@ static void ivas_param_mc_param_est_enc_fx( { FOR( ch_idx2 = 0; ch_idx2 < MAX_CICP_CHANNELS; ch_idx2++ ) { - Word16 norm; - norm = W_norm( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] ); - Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = W_extract_h( W_shl( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); - Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = sub( sub( 62, gb ), norm ); + CONVERT_CY( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); } } } @@ -1497,11 +1499,7 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ ) { #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE - Word16 norm; - // convert the 64 bit fixpoint back into the 48 bit float format - norm = W_norm( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] ); - imag_part_fx = W_extract_h( W_shl( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], norm ) ); - imag_part_e = sub( sub( 62, gb ), norm ); + CONVERT_CY( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], imag_part_fx, imag_part_e ); #else imag_part_fx = Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2]; move32(); -- GitLab From 5251c4791f48fa8ded63157ade33db356f7a9c8b Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 28 Apr 2025 10:42:27 +0200 Subject: [PATCH 1206/1221] clang patch applied. --- lib_enc/ivas_mc_param_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 41d15c241..41d35f8e3 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -31,14 +31,14 @@ *******************************************************************************************************/ // helper macros to convert the 64 bitt accumulators into the 48 bit float format -#define CONVERT_CY( x_64, y_fx, y_e ) \ +#define CONVERT_CY( x_64, y_fx, y_e ) \ { \ Word16 norm; \ norm = W_norm( x_64 ); \ y_fx = W_extract_h( W_shl( x_64, norm ) ); \ y_e = sub( sub( 62, gb ), norm ); \ } -#define CONVERT_DMX( x_64, y_fx, y_e ) \ +#define CONVERT_DMX( x_64, y_fx, y_e ) \ { \ Word16 norm; \ norm = W_norm( x_64 ); \ -- GitLab From 43fb033f99043f6723c40178cb5916e183dd7ed5 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 29 Apr 2025 10:56:24 +0200 Subject: [PATCH 1207/1221] applied some patches. --- lib_enc/ivas_mc_param_enc_fx.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 41d35f8e3..bf7e49cbb 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -36,14 +36,14 @@ Word16 norm; \ norm = W_norm( x_64 ); \ y_fx = W_extract_h( W_shl( x_64, norm ) ); \ - y_e = sub( sub( 62, gb ), norm ); \ + y_e = sub( sub62gb, norm ); \ } #define CONVERT_DMX( x_64, y_fx, y_e ) \ { \ Word16 norm; \ norm = W_norm( x_64 ); \ y_fx = W_extract_h( W_shl( x_64, norm ) ); \ - y_e = sub( sub( 35, gb ), norm ); \ + y_e = sub( sub35gb, norm ); \ } #include #include @@ -678,6 +678,8 @@ static void ivas_param_mc_param_est_enc_fx( #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word16 sub62gb; + Word16 sub35gb; #else Word32 Cy_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; Word16 Cy_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; @@ -764,6 +766,10 @@ static void ivas_param_mc_param_est_enc_fx( Word16 add20gb = add( 20, gb ); #endif +#endif +#ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE + sub35gb = sub( 35, find_guarded_bits_fx( l_ts ) ); + sub62gb = sub( 62, find_guarded_bits_fx( l_ts ) ); #endif FOR( ts = start_ts; ts < num_time_slots; ts++ ) @@ -868,21 +874,12 @@ static void ivas_param_mc_param_est_enc_fx( #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e ); CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e ); - move32(); - move32(); - move16(); - move16(); #endif FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) { #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e ); CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e ); - move32(); - move32(); - move16(); - move16(); - #else a_fx = dmx_real_fx[ch_idx1]; move32(); @@ -1085,10 +1082,6 @@ static void ivas_param_mc_param_est_enc_fx( #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e ); CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e ); - move32(); - move32(); - move16(); - move16(); #else #ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_BE a_fx = dmx_real_fx[ch_idx1]; @@ -1107,10 +1100,6 @@ static void ivas_param_mc_param_est_enc_fx( #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e ); CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e ); - move32(); - move32(); - move16(); - move16(); /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); @@ -1320,6 +1309,8 @@ static void ivas_param_mc_param_est_enc_fx( { #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE CONVERT_CY( Cy_sum_real_64[cur_param_band][k][k], Nrg_fx[k], Nrg_e[k] ); + move32(); + move16(); #else Nrg_fx[k] = Cy_sum_fx[cur_param_band][k][k]; move32(); @@ -1457,6 +1448,8 @@ static void ivas_param_mc_param_est_enc_fx( FOR( ch_idx2 = 0; ch_idx2 < MAX_CICP_CHANNELS; ch_idx2++ ) { CONVERT_CY( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + move16(); } } } @@ -1500,6 +1493,8 @@ static void ivas_param_mc_param_est_enc_fx( { #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE CONVERT_CY( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], imag_part_fx, imag_part_e ); + move32(); + move16(); #else imag_part_fx = Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2]; move32(); -- GitLab From 38547d2ea286f5d0cadcb8a30ab33dbcae3f93b0 Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Tue, 29 Apr 2025 12:09:06 +0200 Subject: [PATCH 1208/1221] applied the clang patch. --- lib_enc/ivas_mc_param_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index bf7e49cbb..3058f87f3 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -36,14 +36,14 @@ Word16 norm; \ norm = W_norm( x_64 ); \ y_fx = W_extract_h( W_shl( x_64, norm ) ); \ - y_e = sub( sub62gb, norm ); \ + y_e = sub( sub62gb, norm ); \ } #define CONVERT_DMX( x_64, y_fx, y_e ) \ { \ Word16 norm; \ norm = W_norm( x_64 ); \ y_fx = W_extract_h( W_shl( x_64, norm ) ); \ - y_e = sub( sub35gb, norm ); \ + y_e = sub( sub35gb, norm ); \ } #include #include -- GitLab From 40b6da870308be6baf24239922ed5d668769b8ca Mon Sep 17 00:00:00 2001 From: Thomas Dettbarn Date: Mon, 12 May 2025 10:40:07 +0200 Subject: [PATCH 1209/1221] inling the matrix multiplication in ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx(). --- lib_com/options.h | 1 + lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 70 ++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index cbc77b6e7..af3a65d47 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -86,6 +86,7 @@ //#define HARM_SCE_INIT #define DIV32_OPT_NEWTON /* FhG: faster 32 by 32 bit division */ #define MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE /* FhG: reduce WMOPS of Cy calculation in ivas_param_mc_param_est_enc_fx() by using 64 Bit addition. Obsoletes IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE. */ +#define MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE /* FhG: reduce WMOPS by inlining the matrix multiplications for the smoothing operation. */ #define FIX_1439_SPEEDUP_Copy_Scale_sig_16_32_no_sat /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_stereo_icBWE_dec_fx /*FhG: reduces WMOPS - bit-exact*/ #define FIX_1439_SPEEDUP_ivas_swb_tbe_dec_fx /*FhG: reduces WMOPS - bit-exact*/ diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index 6d367538d..4d4f37a02 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -30,6 +30,8 @@ *******************************************************************************************************/ +#define MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE + #include #include #include @@ -516,10 +518,14 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( Word16 mixing_matrix_buffer_e; Word32 input_f_real_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; Word32 input_f_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; +#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE + +#else Word32 output_f_real_fx[MAX_CICP_CHANNELS]; Word32 output_f_imag_fx[MAX_CICP_CHANNELS]; Word16 output_f_real_e; Word16 output_f_imag_e; +#endif Word32 diff_f_real_fx[MAX_CICP_CHANNELS]; Word32 diff_f_imag_fx[MAX_CICP_CHANNELS]; @@ -527,8 +533,12 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( set_zero_fx( input_f_real_fx, PARAM_MC_MAX_TRANSPORT_CHANS ); set_zero_fx( input_f_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS ); +#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE + +#else set_zero_fx( output_f_real_fx, MAX_CICP_CHANNELS ); set_zero_fx( output_f_imag_fx, MAX_CICP_CHANNELS ); +#endif set_zero_fx( diff_f_real_fx, MAX_CICP_CHANNELS ); set_zero_fx( diff_f_imag_fx, MAX_CICP_CHANNELS ); @@ -592,6 +602,36 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( } /* apply residual mixing */ +#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE + { + Word16 shifter; + + shifter=31-mixing_matrix_res_smooth_e; + FOR( ch_idx = 0; ch_idx < nY; ch_idx++ ) + { + int i; + Word16 idx; + Word64 temp_real, temp_imag; + + + idx = ch_idx; + temp_real = 0; + temp_imag = 0; + move64(); + move64(); + for (i=0;i Date: Mon, 12 May 2025 10:45:14 +0200 Subject: [PATCH 1210/1221] applied the clang patch. --- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 106 +++++++++---------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index 4d4f37a02..e17f6fd1e 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -30,7 +30,7 @@ *******************************************************************************************************/ -#define MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE +#define MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE #include #include @@ -518,7 +518,7 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( Word16 mixing_matrix_buffer_e; Word32 input_f_real_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; Word32 input_f_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; -#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE +#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE #else Word32 output_f_real_fx[MAX_CICP_CHANNELS]; @@ -533,7 +533,7 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( set_zero_fx( input_f_real_fx, PARAM_MC_MAX_TRANSPORT_CHANS ); set_zero_fx( input_f_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS ); -#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE +#ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE #else set_zero_fx( output_f_real_fx, MAX_CICP_CHANNELS ); @@ -603,32 +603,32 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( /* apply residual mixing */ #ifdef MERGE_REQUEST_1564_SPEEDUP_ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx_NONBE - { - Word16 shifter; - - shifter=31-mixing_matrix_res_smooth_e; - FOR( ch_idx = 0; ch_idx < nY; ch_idx++ ) - { - int i; - Word16 idx; - Word64 temp_real, temp_imag; - - - idx = ch_idx; - temp_real = 0; - temp_imag = 0; - move64(); - move64(); - for (i=0;i Date: Mon, 12 May 2025 12:49:35 +0200 Subject: [PATCH 1211/1221] the index calculation of the matrix multiplication does not require BASOP. --- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index e17f6fd1e..bd95f6f54 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -623,7 +623,7 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( { temp_real = W_add( temp_real, W_mult0_32_32( mixing_matrix_res_smooth_fx[idx], diff_f_real_fx[i] ) ); temp_imag = W_add( temp_imag, W_mult0_32_32( mixing_matrix_res_smooth_fx[idx], diff_f_imag_fx[i] ) ); - idx = add( idx, nY ); + idx += nY; } Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = W_extract_l( W_shr( temp_real, shifter ) ); Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = W_extract_l( W_shr( temp_imag, shifter ) ); @@ -692,7 +692,7 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( { temp_real = W_add( temp_real, W_mult0_32_32( mixing_matrix_smooth_fx[idx], input_f_real_fx[i] ) ); temp_imag = W_add( temp_imag, W_mult0_32_32( mixing_matrix_smooth_fx[idx], input_f_imag_fx[i] ) ); - idx = add( idx, nY ); + idx += nY; } Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add( Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band], W_extract_l( W_shr( temp_real, shifter ) ) ); Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add( Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band], W_extract_l( W_shr( temp_imag, shifter ) ) ); -- GitLab From 053425f3c77a6bc6c2e8e81187d51d061c726ca4 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 14 May 2025 12:03:56 +0200 Subject: [PATCH 1212/1221] add missing move32() instructions --- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index bd95f6f54..5b31e31a4 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -695,7 +695,9 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( idx += nY; } Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add( Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band], W_extract_l( W_shr( temp_real, shifter ) ) ); + move32(); Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add( Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band], W_extract_l( W_shr( temp_imag, shifter ) ) ); + move32(); } } #else -- GitLab From 99d73e309b999f9e14503ad9d50227b2ecd336c8 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Wed, 14 May 2025 12:11:42 +0200 Subject: [PATCH 1213/1221] formatting --- lib_dec/ivas_dirac_output_synthesis_cov_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c index 5b31e31a4..caddb5c5c 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov_fx.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -695,9 +695,9 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( idx += nY; } Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add( Cldfb_RealBuffer_fx[ch_idx][slot_idx_sfr][band], W_extract_l( W_shr( temp_real, shifter ) ) ); - move32(); + move32(); Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band] = L_add( Cldfb_ImagBuffer_fx[ch_idx][slot_idx_sfr][band], W_extract_l( W_shr( temp_imag, shifter ) ) ); - move32(); + move32(); } } #else -- GitLab From 546a923f070e69fc70b062e7b684fc16b19e423e Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 15 May 2025 16:53:59 +0530 Subject: [PATCH 1214/1221] Macros cleanup --- lib_com/cng_exc_fx.c | 28 -- lib_com/codec_tcx_common.c | 134 ------- lib_com/fd_cng_com_fx.c | 98 ----- lib_com/lsf_tools_fx.c | 294 +-------------- lib_com/prot_fx.h | 49 +-- lib_dec/ACcontextMapping_dec_fx.c | 6 - lib_dec/TonalComponentDetection_fx.c | 38 +- lib_dec/bass_psfilter_fx.c | 107 ------ lib_dec/dec_higher_acelp_fx.c | 7 - lib_dec/dec_prm_fx.c | 7 +- lib_dec/dlpc_avq_fx.c | 54 +-- lib_dec/er_dec_tcx_fx.c | 46 +-- lib_dec/er_util_fx.c | 7 +- lib_dec/hf_synth_fx.c | 4 - lib_dec/lsf_msvq_ma_dec_fx.c | 9 - lib_dec/swb_bwe_dec_hr_fx.c | 13 - lib_dec/tonalMDCTconcealment_fx.c | 49 +-- lib_enc/ACcontextMapping_enc_fx.c | 516 -------------------------- lib_enc/gs_enc_fx.c | 8 +- lib_enc/ivas_core_pre_proc_front_fx.c | 67 ---- lib_enc/lsf_msvq_ma_enc_fx.c | 12 - 21 files changed, 19 insertions(+), 1534 deletions(-) diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index b314357ad..e335e9435 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -598,11 +598,6 @@ void cng_params_postupd_fx( const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */ const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */ Word32 ho_env_circ[] /* i/o: Envelope buffer Q6 */ -#ifdef IVAS_CODE_CNG_COM - , - const Word16 element_mode, /* i : Element mode */ - const Word16 bwidth /* i : Audio bandwidth */ -#endif ) { Word16 i, j; @@ -662,15 +657,6 @@ void cng_params_postupd_fx( } Copy32( sp, env, NUM_ENV_CNG ); -#ifdef IVAS_CODE_CNG_COM - if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT ) - { - att = 0.0f; - apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - att = powf( 10, att / 10.0f ); - } - else -#endif { CNG_mode = get_cng_mode( last_active_brate ); @@ -860,11 +846,6 @@ void cng_params_upd_fx( Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */ Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */ const Word32 last_active_brate /* i : Last active bit rate Q0 */ -#ifdef IVAS_CODE_CNG_COM - , - const Word16 element_mode, /* i : Element mode */ - const Word16 bwidth /* i : Audio bandwidth */ -#endif ) { Word32 L_ener, L_tmp; @@ -986,15 +967,6 @@ void cng_params_upd_fx( } Copy32( sp, env, NUM_ENV_CNG ); -#ifdef IVAS_CODE_CNG_COM - if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT ) - { - att = 0.0f; - apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - att = powf( 10, att / 10.0f ); - } - else -#endif { CNG_mode = get_cng_mode( last_active_brate ); /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */ diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common.c index 1ebc2829c..52c7d0614 100644 --- a/lib_com/codec_tcx_common.c +++ b/lib_com/codec_tcx_common.c @@ -469,140 +469,6 @@ void tcxInvertWindowGrouping( } } -#ifdef IVAS_CODE_TCX_COM - -/*-------------------------------------------------------------------* - * tcx5SpectrumInterleaving() - * - * - *-------------------------------------------------------------------*/ - -void tcx5SpectrumInterleaving( - const int16_t tcx5Size, - float *spectrum ) -{ - int16_t i; - float interleaveBuf[N_TCX10_MAX]; - - set_f( interleaveBuf, 0.0f, N_TCX10_MAX ); - - /* group sub-windows: interleave bins according to their frequencies */ - for ( i = 0; i < tcx5Size; i++ ) - { - interleaveBuf[2 * i] = spectrum[i]; - interleaveBuf[2 * i + 1] = spectrum[tcx5Size + i]; - } - - mvr2r( interleaveBuf, spectrum, 2 * tcx5Size ); - - return; -} - - -/*-------------------------------------------------------------------* - * tcx5SpectrumDeinterleaving() - * - * - *-------------------------------------------------------------------*/ - -void tcx5SpectrumDeinterleaving( - const int16_t tcx5Size, - float *spectrum ) -{ - int16_t i; - float interleaveBuf[N_TCX10_MAX]; - - set_f( interleaveBuf, 0.0f, N_TCX10_MAX ); - - /* ungroup sub-windows: interleave bins according to their frequencies */ - for ( i = 0; i < tcx5Size; i++ ) - { - interleaveBuf[i] = spectrum[2 * i]; - interleaveBuf[tcx5Size + i] = spectrum[2 * i + 1]; - } - - mvr2r( interleaveBuf, spectrum, 2 * tcx5Size ); - - return; -} - - -/*-------------------------------------------------------------------* - * tcx5TnsGrouping() - * - * - *-------------------------------------------------------------------*/ - -void tcx5TnsGrouping( - const int16_t L_frame, /* i : frame length (TCX5) */ - const int16_t L_spec, /* i : coded spec length (TCX5, derived from filter borders*/ - float *spectrum ) -{ - /* rearrange LF sub-window lines prior to TNS synthesis filtering */ - if ( L_spec < L_frame ) - { - mvr2r( spectrum + 8, spectrum + 16, L_spec - 8 ); - mvr2r( spectrum + L_frame, spectrum + 8, 8 ); - mvr2r( spectrum + L_frame + 8, spectrum + L_spec + 8, L_spec - 8 ); - } - else - { - float buff[8]; /* Buffer for the rearrangement of LF TCX5 */ - mvr2r( spectrum + L_spec, buff, 8 ); - mvr2r( spectrum + 8, spectrum + 16, L_spec - 8 ); - mvr2r( buff, spectrum + 8, 8 ); - } - - return; -} - - -/*-------------------------------------------------------------------* - * tcx5TnsUngrouping() - * - * - *-------------------------------------------------------------------*/ - -void tcx5TnsUngrouping( - const int16_t L_frame, /* i : frame length (TCX5) */ - const int16_t L_spec, /* i : coded spec length (TCX5, derived from filter borders*/ - float *spectrum, - const int16_t enc_dec /* i : 0: encoder, else decoder */ -) -{ - /* undo rearrangement of LF sub-window lines prior to TNS analysis */ - if ( L_spec < L_frame ) - { - mvr2r( spectrum + L_spec + 8, spectrum + L_frame + 8, L_spec - 8 ); - mvr2r( spectrum + 8, spectrum + L_frame, 8 ); - mvr2r( spectrum + 16, spectrum + 8, L_spec - 8 ); - set_zero( spectrum + L_spec, L_frame - L_spec ); - set_zero( spectrum + L_frame + L_spec, L_frame - L_spec ); - } - else - { - float buff[8]; /* Buffer for the rearrangement of LF TCX5 */ - - mvr2r( spectrum + 8, buff, 8 ); - - if ( enc_dec == ENC ) - { - mvr2r( spectrum + 16, spectrum + 8, L_frame - 8 ); - mvr2r( buff, spectrum + L_frame, 8 ); - } - else - { - mvr2r( spectrum + 16, spectrum + 8, L_spec - 8 ); - mvr2r( buff, spectrum + L_spec, 8 ); - } - } - - return; -} - -#endif - - /*-------------------------------------------------------------------* * tcx5SpectrumInterleaving() * diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index 78809ed2c..872c180b5 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -1109,12 +1109,6 @@ void minimum_statistics( move16(); } } -#ifdef IVAS_CODE_CNG_COM - if ( enc_dec == DEC && element_mode == IVAS_CPE_TD ) - { - v_multc( msNoiseEst, 1.4125f, msNoiseEst, NPART_SHAPING ); - } -#endif /* Collect buffers */ Copy( msPeriodog, msPeriodogBuf + len * ( *msPeriodogBufPtr ), len ); @@ -2624,18 +2618,6 @@ void SynthesisSTFT( move16(); } /* Generate excitation */ -#ifdef IVAS_CODE_CNG_COM - PME() - if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 ) - { - for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) - { - buf[i + ( M + 1 )] += olapBuffer[i + hFdCngCom->frameSize / 4]; - } - v_multc( buf, (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize ); - } - else -#endif { FOR( i = 0; i < M + 1 + hFdCngCom->frameSize; i++ ) { @@ -2749,18 +2731,6 @@ void SynthesisSTFT_ivas_fx( move16(); } /* Generate excitation */ -#ifdef IVAS_CODE_CNG_COM - PME() - if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 ) - { - for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) - { - buf[i + ( M + 1 )] += olapBuffer[i + hFdCngCom->frameSize / 4]; - } - v_multc( buf, (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize ); - } - else -#endif { FOR( i = 0; i < M + 1 + hFdCngCom->frameSize; i++ ) { @@ -2788,74 +2758,6 @@ void SynthesisSTFT_ivas_fx( } } -#ifdef IVAS_CODE_CNG_COM -/*------------------------------------------------------------------- - * SynthesisSTFT_dirac() - * - * STFT synthesis filterbank - *-------------------------------------------------------------------*/ - -void SynthesisSTFT_dirac( - float *fftBuffer, /* i : FFT bins */ - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t samples_out, - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -) -{ - int16_t i; - float buf[M + 1 + 320], tmp; - - /* Perform IFFT */ - RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 ); - - /* Handle overlap in P/S domain for stereo */ - mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize ); - set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/ - - for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ ) - { - olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4]; - } - for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ ) - { - olapBuffer[i] = fftBuffer[i]; - } - - for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ ) - { - olapBuffer[i] = fftBuffer[i]; - } - - for ( ; i < hFdCngCom->fftlen; i++ ) - { - olapBuffer[i] = 0; - } - - /* Get time-domain signal */ - v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, samples_out ); - - /* Get excitation */ - v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize ); - tmp = buf[0]; - preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp ); - residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize ); - - /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/ - if ( samples_out < hFdCngCom->frameSize ) - { - mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 ); - } - for ( i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++ ) - { - olapBuffer[i] *= olapWin[i - 3 * hFdCngCom->frameSize / 4]; - } - - return; -} -#endif - /************************************************************************************** * Compute some values used in the bias correction of the minimum statistics algorithm * **************************************************************************************/ diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 5f0b3b57b..d60d0e999 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -3301,71 +3301,6 @@ Word16 tcxlpc_get_cdk( return cdk; } -#ifdef IVAS_MSVQ -/*--------------------------------------------------------------------------* - * dec_FDCNG_MSVQ_stage1() - * - * - *--------------------------------------------------------------------------*/ - -void dec_FDCNG_MSVQ_stage1( - int16_t j_full, /* i : index full range */ - int16_t n, /* i : dimension to generate */ - const float *invTrfMatrix, /* i : IDCT matrix for synthesis */ - const DCTTYPE idcttype, /* i : specify which IDCT */ - float *uq, /* o : synthesized stage1 vector */ - Word16 *uq_ind /* o : synthesized stage1 vector in BASOP */ -) -{ - int16_t col, segm_ind, j; - float dct_vec[FDCNG_VQ_MAX_LEN]; - float idct_vec[FDCNG_VQ_MAX_LEN]; - const Word8 *cbpW8; - const Word16 *dct_col_shift_tab; - - assert( n <= FDCNG_VQ_MAX_LEN ); - assert( n >= FDCNG_VQ_DCT_MINTRUNC ); - - segm_ind = 0; - for ( col = 1; col <= FDCNG_VQ_DCT_NSEGM; col++ ) - { - if ( j_full >= cdk1_ivas_cum_entries_per_segment[col] ) - { - segm_ind++; - } - } - - j = j_full - cdk1_ivas_cum_entries_per_segment[segm_ind]; /* j is the local segment index */ - - assert( j < cdk1_ivas_entries_per_segment[segm_ind] ); - - /* Word8 column variable Qx storage*/ - cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm_ind]; /* Word8 storage fixed ptr_init */ - cbpW8 += j * cdk1_ivas_cols_per_segment[segm_ind]; /* adaptive ptr init */ - dct_col_shift_tab = stage1_dct_col_syn_shift[segm_ind]; - - for ( col = 0; col < cdk1_ivas_cols_per_segment[segm_ind]; col++ ) - { - dct_vec[col] = (float) shl( (Word16) cbpW8[col], dct_col_shift_tab[col] ); - /* LOGIC( 1 ) , SHIFT( 1 ); - in BASOP: s_and(for W8->W16), shl() - */ - } - dctT2_N_apply_matrix( (const float *) dct_vec, idct_vec, cdk1_ivas_cols_per_segment[segm_ind], n, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, idcttype ); - - /*scale down to original fdcngvq domain and move to Q0 */ - v_multc( idct_vec, fdcng_dct_scaleF[1], idct_vec, n ); - /* fdcng_dct_scaleF[1] --> 0.0625-->scale down from search Q4 domain to Q0 , - not really relevant for BASOP loop */ - - /*add common mid fdcng vector, in fdcng bands domain */ - v_add( idct_vec, cdk1r_tr_midQ_truncQ, uq, n ); - assert( uq_ind == NULL ); - - return; -} - -#endif void msvq_dec( const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) (14Q1*1.28)*/ const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */ @@ -3374,11 +3309,7 @@ void msvq_dec( const Word16 N, /* i : Vector dimension */ const Word16 maxN, /* i : Codebook dimension */ const Word16 Idx[], /* i : Indices */ -#ifdef IVAS_MSVQ - const int16_t applyIDCT_flag, /* i : applyIDCT flag */ - const float *invTrfMatrix, /* i : matrix for IDCT synthesis */ -#endif - Word16 *uq /* o : quantized vector (14Q1*1.28)*/ + Word16 *uq /* o : quantized vector (14Q1*1.28)*/ ) { Word16 i, j, offset; @@ -3414,15 +3345,6 @@ void msvq_dec( start = offs[i]; move16(); } -#ifdef IVAS_MSVQ - test(); - IF( i == 0 && applyIDCT_flag != 0 ) - { - assert( start == 0 ); - dec_FDCNG_MSVQ_stage1( Idx[0], N, invTrfMatrix, IDCT_T2_XX_24, uq, uq_ind ); /* IDCT_T2 N=24 used for all synthesis */ - } - ELSE -#endif { /*vr_add( uq+start, cb[i]+Idx[i]*maxn, uq+start, n );, where uq = a zero vector*/ offset = i_mult2( Idx[i], N34 ); @@ -4499,217 +4421,3 @@ void create_IDCT_N_Matrix_fx( return; } -#ifdef IVAS_MSVQ - -/*-------------------------------------------------------------------* - * dctT2_N_apply_matrix() - * - * dct/idct truncated matrix appl. for DCT basis vector lengths of N - *-------------------------------------------------------------------*/ - -void dctT2_N_apply_matrix( - const float *input, /* i : input in fdcng or DCT(fdcng) domain */ - float *output, /* o : output in DCT(fdcng) or fdcng ordomain */ - const int16_t dct_dim, /* i : dct processing dim possibly truncated */ - const int16_t fdcngvq_dim, /* i : fdcng domain length */ - const float *matrix, /* i : IDCT matrix */ - const int16_t matrix_row_dim, /* i : */ - const DCTTYPE dcttype /* i : matrix operation type */ -) -{ - int16_t i, j, dim_in, dim_out; - int16_t mat_step_col, mat_step_row, mat_step_col_flag; - const float *pt_x, *pt_A; - float tmp_y[FDCNG_VQ_MAX_LEN]; - float *pt_y; - - /* non-square DCT_N and IDCT_N matrix application, - using a stored format of an IDCT_Nx(FDCNG_VQ_DCT_MAXTRUNC) matrix */ - /* efficiently parallelized in SIMD */ - - assert( dct_dim <= FDCNG_VQ_DCT_MAXTRUNC ); - assert( fdcngvq_dim <= FDCNG_VQ_MAX_LEN ); - - if ( ( dcttype & 1 ) == 0 ) /* even entries are DCTs */ - { - /* DCT_typeII 24,21 -> XX in worst case */ - dim_in = fdcngvq_dim; - dim_out = dct_dim; - mat_step_col = matrix_row_dim; /* matrix maximum storage size dependent, width of first row in matrix */ - mat_step_row = 0; - mat_step_col_flag = 1; - assert( dcttype == DCT_T2_21_XX || dcttype == DCT_T2_24_XX ); - } - else - { - assert( ( dcttype & 1 ) != 0 ); /* idct */ - dim_in = dct_dim; - dim_out = fdcngvq_dim; - mat_step_col = 1; - mat_step_row = matrix_row_dim; - mat_step_col_flag = 0; - assert( dcttype == IDCT_T2_XX_24 ); - } - - pt_y = tmp_y; - for ( i = 0; i < dim_out; i++ ) - { - pt_x = input; - *pt_y = 0; - - /* +i(DCT) or +i*maxTrunc(IDCT) */ -#define WMC_TOOL_SKIP - pt_A = &( matrix[i * ( mat_step_row + mat_step_col_flag )] ); /* ptr indexing */ - PTR_INIT( 1 ); -#undef WMC_TOOL_SKIP - for ( j = 0; j < dim_in; j++ ) - { -#define WMC_TOOL_SKIP - *pt_y += ( *pt_x++ ) * ( *pt_A ); - pt_A += mat_step_col; /* step +maxtrunc or +1 */ /* ptr indexing*/ - MAC( 1 ); -#undef WMC_TOOL_SKIP - } - pt_y++; - } - - mvr2r( tmp_y, output, dim_out ); - - return; -} - - -/*-------------------------------------------------------------------* - * extend_dctN_input() - * - * (inputN, dctN) -> idct(N_ext) idct_N matrix application loop for - * extending, extrapolating a DCT basis vector length of N to N_ext - *-------------------------------------------------------------------*/ - -void extend_dctN_input( - const float *input, /* i : input in fdcng domain */ - const float *dct_input, /* i : input in dctN(fdcng) domain */ - const int16_t in_dim, /* i : in_dim == N */ - float *ext_sig, /* o : extended output in fdcng domain */ - const int16_t out_dim, /* i : output total dim */ - float *matrix, /* i : idct synthesis matrix N rows, n_cols columns */ - const int16_t n_cols, /* i : number of columns == DCT truncation length */ - const DCTTYPE dcttype /* i : matrix operation type */ -) -{ - int16_t i, j, i_rev; - const float( *ptr )[FDCNG_VQ_DCT_MAXTRUNC] = (void *) matrix; - - /* stored format is an IDCT_Nx(FDCNG_VQ_DCT_MAXTRUNC) matrix */ - assert( in_dim < FDCNG_VQ_MAX_LEN ); - assert( out_dim <= FDCNG_VQ_MAX_LEN ); - assert( out_dim > in_dim ); - assert( n_cols == FDCNG_VQ_DCT_MAXTRUNC ); /* for *ptr[MAX_TRUNC] adressing*/ - assert( ( dcttype & 1 ) != 0 ); /* idct tables always in use for this basis vector extension */ - - mvr2r( input, ext_sig, in_dim ); /* copy initial part, i.e. only last/tail parts are extended */ - set_f( &( ext_sig[in_dim] ), 0.0, out_dim - in_dim ); - - i_rev = in_dim; /*ptr init*/ - for ( i = in_dim; i < out_dim; i++ ) - { /* for each extension sample */ - /* i = 21 22 23; - i_rev = 20 19 18; for odd dctII reflect basis vector - */ - i_rev--; - - for ( j = 0; j < n_cols; j++ ) /* for each available DCT coeff */ - { - /* DCTcoeff * reflected basis vector */ -#define WMC_TOOL_SKIP - /* pure ptr MAC operations */ - ext_sig[i] += dct_input[j] * ptr[i_rev][j]; /* sum up scaled and extended basis vector */ - MAC( 1 ); -#undef WMC_TOOL_SKIP - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * create_IDCT_N_Matrix() - * - * inititate idct24 FDCNG_VQ_DCT_MAXTRUNCx N matrix in - * RAM from a quantized compressed ROM format - *-------------------------------------------------------------------*/ - -void create_IDCT_N_Matrix( - float *inv_matrixFloatQ, /* i/o: RAM buffer */ - const int16_t N, /* i : DCT length, number of time samples */ - const int16_t n_cols, /* i : number of dct coeffs (as DCT may be truncated) */ - const int16_t alloc_size /* i : RAM buffer size in elements */ -) -{ - int16_t c, c1, r, r_flip, W16_val; - int16_t len; - int16_t mat_cpy_size; - const Word16 *absval_ptr; - const Word8 *idx_ptr; - Word16 idx; - float( *ptr )[FDCNG_VQ_DCT_MAXTRUNC] = (void *) inv_matrixFloatQ; /* fixed number of columns pointers, to simplifies adressing in ANSIC */ - - absval_ptr = unique_idctT2_24coeffsQ16; - idx_ptr = idctT2_24_compressed_idx; - len = FDCNG_VQ_MAX_LEN; - - if ( N == FDCNG_VQ_MAX_LEN_WB ) - { - absval_ptr = unique_idctT2_21coeffsQ16; - idx_ptr = idctT2_21_compressed_idx; - len = N; - } - - assert( alloc_size >= ( n_cols * len ) ); /* enough space for the full expanded IDCT matrix */ - assert( N <= len ); - - mat_cpy_size = ( n_cols ) * ( len >> 1 ); /* NB integer division of "len" */ - - if ( ( len & 1 ) != 0 ) - { /* odd sized DCT with a non-reflected center row */ - mat_cpy_size += n_cols; - } - - for ( c = 0; c < mat_cpy_size; c++ ) - { - idx = (Word16) ( idx_ptr[c] ); - W16_val = absval_ptr[abs( idx )]; - - if ( idx < 0 ) - { - W16_val = -( W16_val ); - } - inv_matrixFloatQ[c] = ( +1.52587890625e-05f ) * ( (float) W16_val ); /* 1.0/2.^16 scaling to a float-"Q0" , a scaling that is not done in BASOP */ - } - - /* for even number of coeffs DCT24, - flip symmetry for odd, even is used to save 50% IDCT Table ROM */ - /* for an odd DCT center is not flipped e.g for DCT21 */ - - assert( n_cols == FDCNG_VQ_DCT_MAXTRUNC ); - assert( ( n_cols & 1 ) == 0 ); - - for ( c = 0; c < ( n_cols ); c += 2 ) - { - c1 = c + 1; - r_flip = len - 1; - for ( r = 0; r < ( len / 2 ); r++, r_flip-- ) - { -#define WMC_TOOL_SKIP - ptr[r_flip][c] = ptr[r][c]; /* flipped */ - ptr[r_flip][c1] = -( ptr[r][c1] ); /* flipped and sign swapped */ - MOVE( 2 ); - MULT( 1 ); /* for negate */ -#undef WMC_TOOL_SKIP - } - } - - return; -} -#endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index bbd5416da..ecd190f69 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -916,11 +916,7 @@ void msvq_dec( const Word16 N, /* i : Vector dimension */ const Word16 maxN, /* i : Codebook dimension */ const Word16 Idx[], /* i : Indices */ -#ifdef IVAS_MSVQ - const int16_t applyIDCT_flag, /* i : applyIDCT flag */ - const float *invTrfMatrix, /* i : matrix for IDCT synthesis */ -#endif - Word16 *uq /* o : quantized vector (3Q12) */ + Word16 *uq /* o : quantized vector (3Q12) */ ); Word16 tcxlpc_get_cdk( @@ -6449,12 +6445,7 @@ void DetectTonalComponents( const Word16 nSamples, const Word16 nSamplesCore, Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ - Word16 element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif -); + Word16 element_mode ); void RefineTonalComponents( Word16 indexOfTonalPeak[], @@ -6474,12 +6465,7 @@ void RefineTonalComponents( const Word16 nSamples, const Word16 nSamplesCore, const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ - Word16 element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif -); + Word16 element_mode ); void ivas_RefineTonalComponents_fx( Word16 indexOfTonalPeak[], @@ -6561,20 +6547,13 @@ void TonalMDCTConceal_Detect( const Word32 pitchLag, /*IN */ Word16 *umIndices, /*OUT*/ Word16 element_mode /* IN */ -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif ); void TonalMDCTConceal_Apply( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - Word32* mdctSpectrum, /*IN/OUT*/ - Word16* mdctSpectrum_exp /*IN */ -#ifdef IVAS_CODE_MDCT_GSHAPE - , const PsychoacousticParameters* psychParamsCurrent) -#endif - ); + const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ + Word32 *mdctSpectrum, /*IN/OUT*/ + Word16 *mdctSpectrum_exp /*IN */ +); void TonalMDCTConceal_Apply_ivas_fx( TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ @@ -9137,15 +9116,8 @@ Word16 decode_lpc_avq_fx( Decoder_State *st, /* i/o: decoder state structure */ const Word16 numlpc, /* i : Number of sets of lpc */ Word16 *param_lpc /* o : lpc parameters */ -#ifdef IVAS_CODE_AVQ_LPC - , - const Word16 ch, /* i : channel */ - const Word16 element_mode, /* i : element mode */ - const Word16 sns_low_br_mode /* i : SNS low-bitrate mode */ -#endif ); -// decode_lpc_avq_ivas_fx declaration with IVAS_CODE_AVQ_LPC enabled Word16 decode_lpc_avq_ivas_fx( Decoder_State *st, /* i/o: decoder state structure */ const Word16 numlpc, /* i : Number of sets of lpc */ @@ -9369,13 +9341,6 @@ void modify_lsf( void con_tcx_fx( Decoder_State *st, /* i/o: coder memory state */ Word16 synth[] /* i/o: synth[] */ /*Q0 */ -#ifdef IVAS_CODE_CON_TCX - , - const Word16 coh, /* i : coherence of stereo signal */ - Word16 *noise_seed, /* i/o: noise seed for stereo */ - const Word16 only_left /* i : TD-PLC only in left channel */ -#endif - ); // er_scale_sync.c diff --git a/lib_dec/ACcontextMapping_dec_fx.c b/lib_dec/ACcontextMapping_dec_fx.c index 22e9fff01..acf372565 100644 --- a/lib_dec/ACcontextMapping_dec_fx.c +++ b/lib_dec/ACcontextMapping_dec_fx.c @@ -328,9 +328,6 @@ Word16 ACcontextMapping_decode2_no_mem_s17_LC( return resQBits; } -#define IVAS_CONTEXT_MAPPING -#ifdef IVAS_CONTEXT_MAPPING - /*-------------------------------------------------------------------* * RCcontextMapping_decode2_no_mem_s17_LCS() * @@ -737,6 +734,3 @@ Word16 RCcontextMapping_decode2_no_mem_s17_LCS_fx( return resQBits; } - -#endif -#undef IVAS_CONTEXT_MAPPING diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index 4b2cf0213..409b975f5 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -140,33 +140,13 @@ void DetectTonalComponents( const Word16 nSamples, const Word16 nSamplesCore, Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ - Word16 element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif -) + Word16 element_mode ) { Word16 F0; Word16 thresholdModification[L_FRAME_MAX], lastMDCTSpect_exp; Word32 pScaledMdctSpectrum[L_FRAME_MAX]; -#ifdef IVAS_CODE_MDCT_GSHAPE - Word16 nBands; - IF( psychParamsCurrent == NULL ) - { - nBands = FDNS_NPTS; - PMT( "add nBands argument to mdct_shaping_16" ) -#endif - mdct_shaping_16( lastMDCTSpectrum, nSamplesCore, nSamples, scaleFactors, scaleFactors_exp, scaleFactors_max_e, pScaledMdctSpectrum ); -#ifdef IVAS_CODE_MDCT_GSHAPE - } - ELSE - { - sns_shape_spectrum( pScaledMdctSpectrum, psychParamsCurrent, scaleFactors, nSamplesCore ); - nBands = psychParamsCurrent->nBands; - } -#endif + mdct_shaping_16( lastMDCTSpectrum, nSamplesCore, nSamples, scaleFactors, scaleFactors_exp, scaleFactors_max_e, pScaledMdctSpectrum ); lastMDCTSpect_exp = add( lastMDCTSpectrum_exp, scaleFactors_max_e ); @@ -208,12 +188,7 @@ void RefineTonalComponents( const Word16 nSamples, const Word16 nSamplesCore, const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0*/ - Word16 element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif -) + Word16 element_mode ) { Word16 newIndexOfTonalPeak[MAX_NUMBER_OF_IDX]; /*Q0*/ Word16 newLowerIndex[MAX_NUMBER_OF_IDX]; /*Q0*/ @@ -224,12 +199,7 @@ void RefineTonalComponents( DetectTonalComponents( newIndexOfTonalPeak, newLowerIndex, newUpperIndex, &newNumIndexes, lastPitchLag, currentPitchLag, lastMDCTSpectrum, - lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, nSamples, nSamplesCore, floorPowerSpectrum, element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - psychParamsCurrent -#endif - ); + lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, nSamples, nSamplesCore, floorPowerSpectrum, element_mode ); nPreservedPeaks = 0; move16(); diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index 45cf7feed..4a5ef9328 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -1124,110 +1124,3 @@ void bpf_pitch_coherence_ivas_fx( return; } - - -#ifdef ADD_BPF_ADAPT -/*---------------------------------------------------------------------* - * res_bpf_adapt() - * - * Analyze BPF output and decide if it should be applied on DFT stereo - * residual signal - *---------------------------------------------------------------------*/ - -/*! r: Decision to enable or disable BPF on DFT stereo residual */ -int16_t res_bpf_adapt( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ - const float *bpf_error_signal_8k, /* i : BPF modification signal */ - float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ -) -{ - float error_nrg; - float tmp; - float res_hb_nrg; - float bpf_error_ratio; - int16_t res_bpf_flag; - int16_t i; - int16_t i_start; - int16_t i_end; - float bw_inv; - - if ( hStereoDft->res_cod_band_max == 6 ) - { - i_start = 39; - i_end = 64; - bw_inv = 0.04f; /* 1/(64 - 39) */ - } - else - { - i_start = 28; - i_end = 40; - bw_inv = 0.083f; /* 1/(40 - 28) */ - } - - /* Measure energy of high frequency band in MDCT domain */ - res_hb_nrg = EPSILON; - for ( i = i_start; i < i_end; i++ ) - { - res_hb_nrg += res_buf[i] * res_buf[i]; - } - res_hb_nrg *= bw_inv; - res_hb_nrg = STEREO_DFT_BPF_ADAPT_ALPHA * res_hb_nrg + ( 1 - STEREO_DFT_BPF_ADAPT_ALPHA ) * hStereoDft->res_hb_nrg_mem; - hStereoDft->res_hb_nrg_mem = res_hb_nrg; - - /* Measure energy of discontinuities at subframe boundaries */ - error_nrg = 0; - for ( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) - { - tmp = bpf_error_signal_8k[i] - hStereoDft->bpf_error_signal_last; - error_nrg += tmp * tmp; - hStereoDft->bpf_error_signal_last = bpf_error_signal_8k[i + STEREO_DFT_L_SUBFR_8k - 1]; - } - error_nrg *= 0.2f; /* Division by 5 for average value */ - bpf_error_ratio = min( 2, error_nrg / res_hb_nrg ); /* Form decision variable and apply limit */ - bpf_error_ratio = STEREO_DFT_BPF_ADAPT_BETA * bpf_error_ratio + ( 1 - STEREO_DFT_BPF_ADAPT_BETA ) * hStereoDft->bpf_error_ratio_mem; - hStereoDft->bpf_error_ratio_mem = bpf_error_ratio; - - res_bpf_flag = bpf_error_ratio < 1; - - return res_bpf_flag; -} - -/*---------------------------------------------------------------------* - * bpf_pitch_coherence() - * - * Analyse pitch coherence - *---------------------------------------------------------------------*/ -void bpf_pitch_coherence( - Decoder_State *st, /* i/o: decoder state structure */ - const float pitch_buf[] /* i : pitch for every subfr [0,1,2,3] */ -) -{ - int16_t nb_subfr; - float pc, pcn1, pcn2, pcn3; - - nb_subfr = st->L_frame / L_SUBFR; - - if ( st->clas_dec > UNVOICED_CLAS && st->element_mode != EVS_MONO ) - { - pc = (float) fabs( st->old_pitch_buf[nb_subfr + 3] + st->old_pitch_buf[nb_subfr + 2] - st->old_pitch_buf[nb_subfr] - st->old_pitch_buf[nb_subfr + 1] ) * 256.0f / (float) st->L_frame; - pcn1 = K_PC_DEC * pc + C_PC_DEC; - pcn1 = max( min( pcn1, 1.0f ), 0.0f ); - - pc = (float) fabs( pitch_buf[nb_subfr - 1] + pitch_buf[nb_subfr - 2] - pitch_buf[1] - pitch_buf[0] ) * 256.0f / (float) st->L_frame; - pcn2 = K_PC_DEC * pc + C_PC_DEC; - pcn2 = max( min( pcn2, 1.0f ), 0.0f ); - - pc = (float) fabs( st->old_pitch_buf[nb_subfr + 3] + st->old_pitch_buf[nb_subfr + 2] - pitch_buf[1] - pitch_buf[0] ) * 256.0f / (float) st->L_frame; - pcn3 = K_PC_DEC * pc + C_PC_DEC; - pcn3 = max( min( pcn3, 1.0f ), 0.0f ); - - if ( pcn1 + pcn2 + pcn3 < 2.5f ) - { - st->hBPF->psf_att = 0.4f; - set_s( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); - } - } - - return; -} -#endif diff --git a/lib_dec/dec_higher_acelp_fx.c b/lib_dec/dec_higher_acelp_fx.c index aff7e5656..6144765a8 100644 --- a/lib_dec/dec_higher_acelp_fx.c +++ b/lib_dec/dec_higher_acelp_fx.c @@ -8,7 +8,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ -#define IVAS_CODE_AVQ /*-----------------------------------------------------------------* * transf_cdbk_dec() * Transform domain contribution decoding @@ -129,7 +128,6 @@ void transf_cdbk_dec_fx( * Demultiplex and decode subvectors from bit-stream *--------------------------------------------------------------*/ -#ifdef IVAS_CODE_AVQ AVQ_demuxdec_fx( st_fx, code_preQ, &nBits, 8, nq, avq_bit_sFlag, trgtSvPos ); Word16 q_Code_preQ; IF( ( st_fx->element_mode == EVS_MONO ) ) @@ -142,9 +140,6 @@ void transf_cdbk_dec_fx( q_Code_preQ = Q_AVQ_OUT; move16(); } -#else - AVQ_demuxdec_fx( st_fx, code_preQ, &nBits, 8, nq ); -#endif FOR( i = 0; i < L_SUBFR; i++ ) { code_preQ[i] = shl_o( code_preQ[i], q_Code_preQ, &Overflow ); @@ -185,7 +180,6 @@ void transf_cdbk_dec_fx( st_fx->last_nq_preQ = nq[7]; move16(); -#ifdef IVAS_CODE_AVQ /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ test(); test(); @@ -209,7 +203,6 @@ void transf_cdbk_dec_fx( st_fx->last_code_preq = code_preQ[L_SUBFR - 1]; // q_Code_preQ move16(); -#endif PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &st_fx->mem_preemp_preQ_fx ); /*--------------------------------------------------------------* * Compute normalized prequantizer excitation gain for FEC diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c index 3d277807d..16e588396 100644 --- a/lib_dec/dec_prm_fx.c +++ b/lib_dec/dec_prm_fx.c @@ -1003,12 +1003,7 @@ void dec_prm_fx( { IF( st->lpcQuantization == 0 ) { - decode_lpc_avq_fx( st, st->numlpc, param_lpc -#ifdef IVAS_CODE_AVQ_LPC - , - , , -#endif - ); + decode_lpc_avq_fx( st, st->numlpc, param_lpc ); move16(); } ELSE IF( EQ_16( st->lpcQuantization, 1 ) ) diff --git a/lib_dec/dlpc_avq_fx.c b/lib_dec/dlpc_avq_fx.c index 3d9a00b7f..07f1ea6f2 100644 --- a/lib_dec/dlpc_avq_fx.c +++ b/lib_dec/dlpc_avq_fx.c @@ -149,20 +149,11 @@ Word16 decode_lpc_avq_fx( Decoder_State *st, /* i/o: decoder state structure */ const Word16 numlpc, /* i : Number of sets of lpc */ Word16 *param_lpc /* o : lpc parameters */ -#ifdef IVAS_CODE_AVQ_LPC - , - const Word16 ch, /* i : channel */ - const Word16 element_mode, /* i : element mode */ - const Word16 sns_low_br_mode /* i : SNS low-bitrate mode */ -#endif ) { Word16 k, j; Word16 nb, qn1, qn2, avqBits, q_type; Word16 start_bit_pos; -#ifdef IVAS_CODE_AVQ_LPC - Word16 stereo_mode = 0; -#endif move16(); move16(); move16(); @@ -189,41 +180,11 @@ Word16 decode_lpc_avq_fx( param_lpc[j] = q_type; j = add( j, 1 ); } -#ifdef IVAS_CODE_AVQ_LPC - test(); - IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && k == 0 ) - { - stereo_mode = ch; - move16(); - if ( ch == 0 ) - { - stereo_mode = param_lpc[j]; - move16(); - } - param_lpc[j++] = stereo_mode; - move16(); - } -#endif /* Decode quantization indices */ IF( q_type == 0 ) { /* Absolute quantizer with 1st stage stochastic codebook */ -#ifdef IVAS_CODE_AVQ_LPC - IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) - { - IF( NE_16( stereo_mode, 3 ) ) - { - param_lpc[j] = get_next_indice_fx( st, SNS_ABS_QUANT_BITS ); - } - ELSE - { - param_lpc[j] = sub( get_next_indice_fx( st, 1 ), 2 ); - } - move16(); - } - ELSE -#endif { move16(); param_lpc[j] = get_next_indice_fx( st, 8 ); @@ -235,9 +196,6 @@ Word16 decode_lpc_avq_fx( * - we are in low bitrate mode and no joint SNS coding is used * - OR the side-SNS-is-zero flag is set for joint SNS */ -#ifdef IVAS_CODE_AVQ_LPC - IF( NE_16( element_mode, IVAS_CPE_MDCT ) || ( !( sns_low_br_mode && ( EQ_16( stereo_mode, 0 ) || EQ_16( stereo_mode, 1 ) ) && !( EQ_16( q_type, 0 ) && EQ_16( param_lpc[j - 1], -2 ) ) ) ) ) -#endif { /* 2 bits to specify Q2,Q3,Q4,ext */ qn1 = add( 2, get_next_indice_fx( st, 2 ) ); @@ -321,21 +279,11 @@ Word16 decode_lpc_avq_fx( pack4bits_fx( avqBits, st, ¶m_lpc[j] ); j = add( j, qn2 ); } -#ifdef IVAS_CODE_AVQ_LPC - ELSE - { - param_lpc[j] = 0; - j = add( j, 1 ); - param_lpc[j] = 0; - j = add( j, 1 ); - move16(); - move16(); - } -#endif } return sub( st->next_bit_pos, start_bit_pos ); } + Word16 decode_lpc_avq_ivas_fx( Decoder_State *st, /* i/o: decoder state structure */ const Word16 numlpc, /* i : Number of sets of lpc */ diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 161cefe76..3d0eab815 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -121,13 +121,6 @@ con_tcx void con_tcx_fx( Decoder_State *st, /* i/o: coder memory state */ Word16 synth[] /* i/o: synth[] Q0*/ -#ifdef IVAS_CODE_CON_TCX - , - const Word16 coh, /* i : coherence of stereo signal Q14*/ - Word16 *noise_seed, /* i/o: noise seed for stereo Q0*/ - const Word16 only_left /* i : TD-PLC only in left channel Q0*/ -#endif - ) { Word16 i, s, c, L_frame, L_subfr, fLowPassFilter, T0; @@ -558,43 +551,7 @@ void con_tcx_fx( /*-----------------------------------------------------------------* * Construct the random part of excitation *-----------------------------------------------------------------*/ -#ifdef IVAS_CODE_CON_TCX - if ( coh != -1.f ) - { - int16_t tmpSeed1; - float alpha_coh; - float random1, random2; - - tmpSeed1 = *noise_seed; - noise = buf; - - alpha_coh = sqrtf( ( 1 - coh ) / ( 1 + coh ) ); - if ( st->idchan == 1 ) - { - alpha_coh = -alpha_coh; - } - - for ( i = 0; i < L_frame + L_FIR_FER2 - 1; i++ ) - { - random1 = (float) own_random( &tmpSeed1 ); - random2 = (float) own_random( &tmpSeed1 ); - noise[i] = random1 + alpha_coh * random2; - } - - if ( st->idchan == 1 || only_left ) - { - *noise_seed = tmpSeed1; - } - for ( ; i < L_frame + ( L_frame / 2 ) + 2 * L_FIR_FER2; i++ ) - { - random1 = (float) own_random( &tmpSeed1 ); - random2 = (float) own_random( &tmpSeed1 ); - noise[i] = random1 + alpha_coh * random2; - } - } - else -#endif /*IVAS_CODE_CON_TCX*/ { tmpSeed = st->seed_acelp; move16(); @@ -1427,7 +1384,7 @@ void con_tcx_ivas_fx( /*-----------------------------------------------------------------* * Construct the random part of excitation *-----------------------------------------------------------------*/ -#ifndef IVAS_CODE_CON_TCX + IF( NE_16( coh, -16384 ) ) { Word16 tmpSeed1; @@ -1477,7 +1434,6 @@ void con_tcx_ivas_fx( } } ELSE -#endif /*IVAS_CODE_CON_TCX*/ { tmpSeed = st->seed_acelp; /*Q0*/ move16(); diff --git a/lib_dec/er_util_fx.c b/lib_dec/er_util_fx.c index 9735129ec..cecbad294 100644 --- a/lib_dec/er_util_fx.c +++ b/lib_dec/er_util_fx.c @@ -579,12 +579,7 @@ Word16 GetPLCModeDecision_fx( pitch = L_add( st->old_fpitch, 0 ); /*Q16*/ } - TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) -#endif - ); + TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode ); test(); test(); diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index 94c7d4c62..65c2e9290 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -182,11 +182,7 @@ static void hf_synthesis_fx( * calculate energy scaling factor to respect tilt of synth12k8 * (tilt: 1=voiced, -1=unvoiced) *-----------------------------------------------------------------*/ -#ifdef EVS_MONO hp400_12k8_fx( synth, L_SUBFR, hBWE_zero->mem_hp400_fx ); -#else - hp400_12k8_ivas_fx( synth, L_SUBFR, hBWE_zero->mem_hp400_fx ); -#endif /* i: mem_hp400 in Q_syn */ /* i: synth in Q_syn */ /* o: synth in Q_syn-3 */ diff --git a/lib_dec/lsf_msvq_ma_dec_fx.c b/lib_dec/lsf_msvq_ma_dec_fx.c index 61e338c9c..1b5d79c68 100644 --- a/lib_dec/lsf_msvq_ma_dec_fx.c +++ b/lib_dec/lsf_msvq_ma_dec_fx.c @@ -185,9 +185,6 @@ Word16 D_lsf_tcxlpc( M, M, indices + NumIndices, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_q ); NumIndices = add( NumIndices, TCXLPC_NUMSTAGES ); /* Q0 */ @@ -208,9 +205,6 @@ Word16 D_lsf_tcxlpc( M, M, indices + NumIndices, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_rem_q_ind ); NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES ); /* Q0 */ @@ -287,9 +281,6 @@ Word16 dec_lsf_tcxlpc( M, M, flag + 1, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_q_ind ); /* Update flag */ diff --git a/lib_dec/swb_bwe_dec_hr_fx.c b/lib_dec/swb_bwe_dec_hr_fx.c index 9fae1ded5..ff4d8bee6 100644 --- a/lib_dec/swb_bwe_dec_hr_fx.c +++ b/lib_dec/swb_bwe_dec_hr_fx.c @@ -11,7 +11,6 @@ #define Q_GUARD 1 #define Q_32_BITS 14 /* scaling of 't_audio32' */ #define MAKE_PSEUDO_FLT( v, e ) ( ( ( (Word32) ( v ) ) << 16 ) + ( e ) ) -#define AVQ_DEMUX /*-----------------------------------------------------------* * Gain_Dequant_HR() * @@ -595,11 +594,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB Nsv = ( NUM_TRANS_END_FREQ_COEF - NUM_TRANS_START_FREQ_COEF ) / WIDTH_BAND; move16(); -#ifdef AVQ_DEMUX AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq, 0, sub( Nsv, 1 ) ); -#else - AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq ); -#endif temp = add( len, NUM_TRANS_START_FREQ_COEF ); /* 't_audio' in Q8 */ t_audio_exp = 8; @@ -848,11 +843,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB /* Nsv = i / WIDTH_BAND */ Nsv = shr( i, 3 ); -#ifdef AVQ_DEMUX AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq, 0, sub( Nsv, 1 ) ); -#else - AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq ); -#endif /*---------------------------------------------------------------------* * second stage decoding *---------------------------------------------------------------------*/ @@ -889,11 +880,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB } nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); -#ifdef AVQ_DEMUX AVQ_demuxdec_fx( st_fx, x_norm1, &nBits, Nsv2, nq2, 0, sub( Nsv2, 1 ) ); -#else - AVQ_demuxdec_fx( st_fx, x_norm1, &nBits, Nsv2, nq2 ); -#endif } /*---------------------------------------------------------------------* diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index f33a6c84f..fd6cf7835 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -873,12 +873,7 @@ static void CalcPowerSpecAndDetectTonalComponents( Word32 secondLastMDCT[], // Q31-secondLastMDCT_exp Word16 secondLastMDCT_exp, Word32 const pitchLag, /*15Q16*/ - Word16 element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif -) + Word16 element_mode ) { Word16 nSamples; Word16 i; @@ -968,20 +963,9 @@ static void CalcPowerSpecAndDetectTonalComponents( /* here mdct_shaping() is intentionally used rather then mdct_shaping_16() */ -#ifdef IVAS_CODE_MDCT_GSHAPE - IF( psychParamsCurrent == NULL ) -#endif { mdct_shaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, invScaleFactors_exp ); } -#ifdef IVAS_CODE_MDCT_GSHAPE - ELSE - { - PMTE() - sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore ); - nBands = psychParamsCurrent->nBands; - } -#endif FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ ) { powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[FDNS_NPTS - 1] ), invScaleFactors_exp[FDNS_NPTS - 1] ); // powerSpectrum_exp+ 2*invScaleFactors_exp -15 @@ -1034,12 +1018,7 @@ void TonalMDCTConceal_Detect( const TonalMDCTConcealPtr hTonalMDCTConc, const Word32 pitchLag, /*15Q16*/ Word16 *numIndices, - Word16 element_mode -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif -) + Word16 element_mode ) { Word32 secondLastMDST[L_FRAME_MAX]; Word32 secondLastMDCT[L_FRAME_MAX]; @@ -1111,9 +1090,6 @@ void TonalMDCTConceal_Detect( { /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */ /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */ -#ifdef IVAS_CODE_MDCT_GSHAPE - IF( psychParamsCurrent == NULL ) -#endif { nSamples = hTonalMDCTConc->nNonZeroSamples; move16(); @@ -1121,13 +1097,6 @@ void TonalMDCTConceal_Detect( hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp, hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum ); } -#ifdef IVAS_CODE_MDCT_GSHAPE - ELSE - { - sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore ); - nBands = psychParamsCurrent->nBands; - } -#endif powerSpectrum_exp = getScaleFactor32( powerSpectrum, nSamples ); powerSpectrum_exp = sub( powerSpectrum_exp, 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/ @@ -2532,10 +2501,6 @@ void TonalMDCTConceal_Apply( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ Word32 *mdctSpectrum, // Q31-*mdctSpectrum_exp /*IN/OUT*/ Word16 *mdctSpectrum_exp /*IN */ -#ifdef IVAS_CODE_MDCT_GSHAPE - , - const PsychoacousticParameters *psychParamsCurrent -#endif ) { Word16 i, l, exp; @@ -2553,22 +2518,12 @@ void TonalMDCTConceal_Apply( move16(); assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples ); -#ifdef IVAS_CODE_MDCT_GSHAPE - IF( psychParamsCurrent == NULL ) -#endif { mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp, hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum ); } -#ifdef IVAS_CODE_MDCT_GSHAPE - ELSE - { - sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore ); - nBands = psychParamsCurrent->nBands; - } -#endif phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */ pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted; diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 43bd30fd4..5003712b7 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -1826,519 +1826,3 @@ Word16 RCcontextMapping_encode2_estimate_bandWise_fx( return bandBits; } - - -#ifdef IVAS_CODE_RANGE_CODER - -/*-------------------------------------------------------------------* - * RCcontextMapping_encode2_estimate_no_mem_s17_LCS() - * - * Range coder bit-estimation - *-------------------------------------------------------------------*/ - -int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( - int16_t *x, /* Spectral coefficients */ - const int16_t nt, /* L - size of spectrum (no. of spectral coefficients) */ - int16_t *lastnz_out, - int16_t *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ - const int16_t target, /* Target bits */ - int16_t *stop, - int16_t mode, - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ -) -{ - /* Common variables */ - int16_t a1, b1; - int16_t k, pki, lev1; - uint16_t t; - int16_t lastnz, lastnz2; - int16_t rateFlag; - float bit_estimate; - int16_t symbol; - const uint8_t *lookup; - float nbits2; - - /* Initialization */ - bit_estimate = 2.0f; - nbits2 = 0.f; - - /* bits to encode lastnz */ - k = 1; - - while ( k < nt / 2 ) - { - bit_estimate++; - k = k << 1; - /* check while condition */ - } - - nbits2 = bit_estimate; - - if ( hm_cfg ) - { - int16_t a1_i, b1_i; - int16_t stop2; - int16_t total_output_bits; - int16_t nt_half; - int32_t c[2], *ctx; - int32_t p1, p2; - int16_t ii[2]; - int16_t idx1, idx2, idx; - int16_t numPeakIndicesOrig = 0, numHoleIndices = 0; /* only to avoid compiler warning */ - - /* Rate flag */ - if ( target > 400 ) - { - rateFlag = 2 << NBITS_CONTEXT; /* Select context-A for higher bitrates */ - } - else - { - rateFlag = 0; /* Select context-B for lower bitrates */ - } - - nt_half = nt >> 1; - stop2 = 0; - c[0] = c[1] = 0; - - /* Find last non-zero tuple in the mapped domain signal */ - lastnz = find_last_nz_pair( x, nt, hm_cfg ); - - lastnz2 = 2; - - /* mapped domain */ - numPeakIndicesOrig = hm_cfg->numPeakIndices; - hm_cfg->numPeakIndices = min( hm_cfg->numPeakIndices, lastnz ); - numHoleIndices = lastnz - hm_cfg->numPeakIndices; - - /* Mark hole indices beyond lastnz as pruned */ - for ( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) - { - hm_cfg->holeIndices[k] = hm_cfg->holeIndices[k] + nt; - } - - ii[0] = numPeakIndicesOrig; - ii[1] = 0; - - p1 = p2 = 0; /* to avoid compilation warnings */ - - /* Main Loop through the 2-tuples */ - for ( k = 0; k < lastnz; k += 2 ) - { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); - - idx = min( idx1, idx2 ); - - /* Get context */ - ctx = &c[p1 | p2]; - - t = (uint16_t) ( *ctx + rateFlag ); - t += ( nt_half >= idx ) ? 0 : ( 1 << NBITS_CONTEXT ); - - /* Init current 2-tuple encoding */ - a1 = (int16_t) abs( x[a1_i] ); - b1 = (int16_t) abs( x[b1_i] ); - lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* Signs Bits */ - bit_estimate += min( a1, 1 ); - bit_estimate += min( b1, 1 ); - - /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ - lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* check while condition */ - /* MSBs coding */ - while ( max( a1, b1 ) >= A_THRES ) - { - pki = lookup[lev1]; /* ESC symbol */ - - bit_estimate = bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; - bit_estimate += 2; /* Add 2 LSB bits corresponding to the bit-plane */ - - ( a1 ) >>= 1; - ( b1 ) >>= 1; - - lev1 = min( lev1 + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* check while condition */ - } - - pki = lookup[lev1]; - - symbol = a1 + A_THRES * b1; - bit_estimate = bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; - - /* Should we truncate? */ - if ( bit_estimate > target ) - { - stop2 = 1; - - if ( *stop ) - { - break; - } - } - else - { - lastnz2 = b1_i + 1; - nbits2 = bit_estimate; - } - - /* Update context for next 2-tuple */ - if ( p1 == p2 ) /* peak-peak or hole-hole context */ - { - lev1 >>= NBITS_CONTEXT + NBITS_RATEQ; - - if ( lev1 <= 0 ) - { - t = 1 + ( a1 + b1 ) * ( lev1 + 2 ); - } - else - { - t = 13 + lev1; - } - - *ctx = ( *ctx & 0xf ) * 16 + t; - } - else - { - /* mixed context */ - - if ( idx1 & 1 ) - { - /* update first context */ - c[p1] = update_mixed_context( c[p1], (int16_t) abs( x[a1_i] ) ); - } - - if ( idx2 & 1 ) - { - /* update second context */ - c[p2] = update_mixed_context( c[p2], (int16_t) abs( x[b1_i] ) ); - } - } - - } /*end of the 2-tuples loop*/ - - total_output_bits = (int16_t) ( bit_estimate + 0.5f ); - if ( *stop ) - { - total_output_bits = (int16_t) ( nbits2 + 0.5f ); - } - - if ( stop2 ) - { - stop2 = total_output_bits; - } - *nEncoded = lastnz2; - *stop = stop2; /* If zero, it means no overflow occured during bit-estimation */ - *lastnz_out = lastnz; - - /* Restore hole indices beyond lastnz */ - for ( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) - { - hm_cfg->holeIndices[k] = hm_cfg->holeIndices[k] - nt; - } - hm_cfg->numPeakIndices = numPeakIndicesOrig; - - return (int16_t) ( nbits2 + 0.5f ); - } - else /* if (!hm_cfg) */ - { - int16_t esc_nb, cp, rateQ; - uint16_t s; - int16_t tot_bits2; - int16_t overflow_flag = 0; - - /* Rate flag */ - if ( target > 400 ) - { - rateFlag = 2; - } - else - { - rateFlag = 0; /* Select context-B for lower bitrates */ - } - - t = 0; - s = 0; - cp = 0; - lastnz = 1; - lastnz2 = 0; - tot_bits2 = 0; - - /* Find last non-zero tuple in the mapped domain signal */ - for ( lastnz = ( nt - 2 ); lastnz >= 0; lastnz -= 2 ) - { - if ( ( x[lastnz] != 0 ) || ( x[lastnz + 1] != 0 ) ) - { - break; - } - } - lastnz += 2; - if ( lastnz < 2 ) - { - lastnz = 2; /* At least one tuple is coded */ - } - - lastnz2 = 2; - - /* Main Loop through the 2-tuples */ - for ( k = 0; k < lastnz; k += 2 ) - { - /* Init current 2-tuple encoding */ - a1 = (int16_t) abs( x[k] ); - b1 = (int16_t) abs( x[k + 1] ); - lev1 = 0; - esc_nb = 0; - rateQ = rateFlag + ( k > ( nt >> 1 ) ); - - /* Signs Bits */ - bit_estimate += min( a1, 1 ); - bit_estimate += min( b1, 1 ); - - /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ - lookup = &ari_lookup_s17_LC[t + ( rateQ << NBITS_CONTEXT )]; - - /* check while condition */ - /* MSBs coding */ - while ( max( a1, b1 ) >= A_THRES ) - { - pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; - - bit_estimate = bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; - bit_estimate += 2; /* Add 2 LSB bits corresponding to the bit-plane */ - - ( a1 ) >>= 1; - ( b1 ) >>= 1; - - lev1++; - esc_nb = min( lev1, 3 ); - - /* check while condition */ - } - - pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; - - symbol = a1 + A_THRES * b1; - bit_estimate = bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; - - /* Should we truncate? */ - if ( bit_estimate > target ) /* Overflow occured */ - { - overflow_flag = 1; - } - else - { - if ( abs( x[k] ) || abs( x[k + 1] ) ) /* No overflow & non-zero tuple */ - { - nbits2 = bit_estimate; - lastnz2 = k + 2; - } - } - - /* Update context for next 2-tuple */ - if ( esc_nb < 2 ) - { - cp = 1 + ( a1 + b1 ) * ( esc_nb + 1 ); - } - else - { - cp = 12 + esc_nb; - } - /*shift old bits and replace last 4 bits*/ - s = ( s << 4 ) + cp; - t = s & 0xFF; - - } /*end of the 2-tuples loop*/ - - tot_bits2 = (int16_t) ( nbits2 + 0.5f ); - if ( lastnz2 < lastnz ) /* Overflow occured because unable to code all tuples */ - { - overflow_flag = 1; - } - if ( mode == -1 ) - { - tot_bits2 = (int16_t) ( bit_estimate + 0.5f ); - } - if ( overflow_flag == 0 ) /* No overflow */ - { - *stop = 0; - } - else /* Overflow */ - { - if ( *stop ) - { - *stop = tot_bits2; - } - else - { - *stop = (int16_t) ( bit_estimate + 0.5f ); - } - } - - *lastnz_out = lastnz; - *nEncoded = lastnz2; - /* Safety mechanism to avoid overflow */ - if ( lastnz2 == 2 && overflow_flag == 1 ) - { - for ( k = 0; k < lastnz2; k++ ) - { - x[k] = 0; - } - } - - return tot_bits2; - } -} - -/*-------------------------------------------------------------------* - * RCcontextMapping_encode2_estimate_bandWise_start() - * - * Range coder - start bandwise bit-estimation - *-------------------------------------------------------------------*/ - -int16_t RCcontextMapping_encode2_estimate_bandWise_start( - int16_t *x, - const int16_t nt, - const int16_t target, - HANDLE_RC_CONTEXT_MEM hContextMem ) -{ - int16_t i, k; - - /* Rate flag */ - if ( target > 400 ) - { - hContextMem->rateFlag = 2 << NBITS_CONTEXT; - } - else - { - hContextMem->rateFlag = 0; - } - - hContextMem->bit_estimate = 2.0f; - - /* Init */ - hContextMem->nt_half = nt >> 1; - - /* bits to encode lastnz */ - k = 1; - - while ( k < hContextMem->nt_half ) - { - hContextMem->bit_estimate++; - - k = k << 1; - /* check while condition */ - } - - /* bits to encode lastnz */ - hContextMem->nbits_old = (int16_t) hContextMem->bit_estimate; - - hContextMem->ctx = 0; - hContextMem->lastnz = 2; - - /* Find last non-zero tuple */ - - for ( i = nt; i >= 4; i -= 2 ) - { - - if ( x[i - 2] != 0 || x[i - 1] != 0 ) - { - hContextMem->lastnz = i; - break; - } - } - - return (int16_t) hContextMem->bit_estimate; -} - -/*-------------------------------------------------------------------* - * RCcontextMapping_encode2_estimate_bandWise() - * - * Range coder - bandwise bit-estimation - *-------------------------------------------------------------------*/ - -int16_t RCcontextMapping_encode2_estimate_bandWise( - int16_t *x, - const int16_t start_line, - const int16_t end_line, - HANDLE_RC_CONTEXT_MEM hContextMem ) -{ - int16_t a1, b1, a1_i, b1_i; - int16_t k, pki, lev1; - uint16_t t; - int16_t bandBits = 0; - int16_t total_output_bits; /* No. of bits after finalization */ - int16_t symbol; - const uint8_t *lookup; - int16_t idx; - - /* Main Loop through the 2-tuples */ - /*hContextMem->nt_half = end_line >> 1;*/ - for ( k = start_line; k < min( hContextMem->lastnz, end_line ); k += 2 ) - { - a1_i = k; - b1_i = k + 1; - - idx = k; - - /* Get context */ - t = hContextMem->ctx + hContextMem->rateFlag; - t += ( hContextMem->nt_half >= idx ) ? 0 : ( 1 << NBITS_CONTEXT ); - - /* Init current 2-tuple encoding */ - a1 = (int16_t) abs( x[a1_i] ); - b1 = (int16_t) abs( x[b1_i] ); - lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* Signs Bits */ - hContextMem->bit_estimate += min( a1, 1 ); - hContextMem->bit_estimate += min( b1, 1 ); - - /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ - lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* check while condition */ - /* MSBs coding */ - while ( max( a1, b1 ) >= A_THRES ) - { - pki = lookup[lev1]; - hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; - hContextMem->bit_estimate += 2; /* Add the 2 LSB bits that were shifted out */ - - ( a1 ) >>= 1; - ( b1 ) >>= 1; - - lev1 = min( lev1 + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - /* check while condition */ - } - - pki = lookup[lev1]; - symbol = a1 + A_THRES * b1; /* MSB symbol */ - hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; - - /* Update context */ - lev1 >>= NBITS_CONTEXT + NBITS_RATEQ; - - if ( lev1 <= 0 ) - { - t = 1 + ( a1 + b1 ) * ( lev1 + 2 ); - } - else - { - t = 13 + lev1; - } - - hContextMem->ctx = ( hContextMem->ctx & 0xf ) * 16 + t; - - } /*end of the 2-tuples loop*/ - total_output_bits = (int16_t) ( hContextMem->bit_estimate + 0.5f ); - - bandBits = total_output_bits - hContextMem->nbits_old; - hContextMem->nbits_old = total_output_bits; - - return bandBits; -} - -#endif diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 77470c255..7bf52970d 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -78,13 +78,7 @@ void encod_audio_fx( * Encode GSC attack flag (used to reduce possible pre-echo) * Encode GSC SWB speech flag *---------------------------------------------------------------*/ -#ifdef GSC_IVAS // TVB -->>>>>> - test(); - IF( ( st_fx->element_mode > EVS_MONO ) && st_fx->idchan == 0 ) - { - push_indice( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); - } -#endif + IF( attack_flag > 0 ) { push_indice( hBstr, IND_GSC_ATTACK, 1, 1 ); diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index d358f7099..76640e7a7 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -58,10 +58,6 @@ static void calculate_energy_buffer_ivas_fx( CPE_ENC_HANDLE hCPE, Word32 enerBuffer_dft[], const Word16 no_channels, const Word32 input_Fs, Word16 enerBuffer_dft_e[] ); -#ifdef IVAS_FIXED_ENC -static void calculate_energy_buffer_fx( CPE_ENC_HANDLE hCPE, Word64 enerBuffer_dft_fx[], Word16 *enerBuffer_dft_q_fx, const Word16 no_channels, const Word32 input_Fs ); -#endif - /*-------------------------------------------------------------------* * pre_proc_front_ivas() * @@ -1684,69 +1680,6 @@ ivas_error pre_proc_front_ivas_fx( return error; } -#ifdef IVAS_FIXED_ENC -/*-------------------------------------------------------------------* - * calculate_energy_buffer_fx() - * - * calculate DFT-based energies - *--------------------------------------------------------------------*/ - -static void calculate_energy_buffer_fx( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - Word64 enerBuffer_dft_fx[], /* o : energy buffer */ - Word16 *enerBuffer_dft_q_fx, - const Word16 no_channels, /* i : no. of used CLDFB channels */ - const Word32 input_Fs /* i : input sampling rate */ -) -{ - Word16 i, j; - Word64 nrg_DMX_fx[CLDFB_NO_CHANNELS_MAX]; - Word64 *p_nrg_DMX_fx; - Word32 *pDFT_DMX_fx; - Word16 *pDFT_DMX_q_fx; - Word32 chan_width_bins_fx; - Word16 band_res_dft_fx, chan_width_f_fx, start, stop; - - Word16 temp_q1 = norm_l( input_Fs ) - 1; - Word16 temp_q2 = norm_s( hCPE->hStereoDft->NFFT ); - - band_res_dft_fx = div_l( L_shl( input_Fs, temp_q1 ), shl( hCPE->hStereoDft->NFFT, temp_q2 ) ); - chan_width_f_fx = 24000 / CLDFB_NO_CHANNELS_MAX; - chan_width_bins_fx = L_shl( (Word32) div_s( chan_width_f_fx, band_res_dft_fx ), ( sub( add( temp_q1, 1 ), temp_q2 ) ) ); // Q16 - - pDFT_DMX_fx = hCPE->hStereoDft->DFT_fx[0]; - pDFT_DMX_q_fx = hCPE->hStereoDft->DFT_q_fx; - start = 1; - p_nrg_DMX_fx = nrg_DMX_fx; - - *p_nrg_DMX_fx = Mpy_32_32( pDFT_DMX_fx[0], pDFT_DMX_fx[0] ); - - FOR( i = 0; i < no_channels; i++ ) - { - stop = (Word16) ( L_add( Mpy_32_16_1( chan_width_bins_fx, add( i, 1 ) ), 1 ) >> 1 ); - FOR( j = start; j < stop; j++ ) - { - *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, Mpy_32_32( pDFT_DMX_fx[2 * j], pDFT_DMX_fx[2 * j] ) ); - *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, Mpy_32_32( pDFT_DMX_fx[2 * j + 1], pDFT_DMX_fx[2 * j + 1] ) ); - } - enerBuffer_dft_q_fx[i] = 2 * pDFT_DMX_q_fx[i] - 31; - start = stop; - p_nrg_DMX_fx++; - } - - FOR( i = 0; i < no_channels; i++ ) /* Consider only used channels, dependent on Fs */ - { - enerBuffer_dft_fx[i] = nrg_DMX_fx[i] / 3; - } - - /* Set remaining entries of enerBuffer to zero */ - FOR( ; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - enerBuffer_dft_fx[i] = 0; - } - return; -} -#endif /*-------------------------------------------------------------------* * calculate_energy_buffer() * diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index 8f6a21d03..593efa784 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -570,9 +570,6 @@ Word16 Q_lsf_tcxlpc_fx( lpcorder, lpcorder, indices + NumIndices, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_q ); NumIndices = add( NumIndices, TCXLPC_NUMSTAGES ); @@ -617,9 +614,6 @@ Word16 Q_lsf_tcxlpc_fx( lpcorder, lpcorder, indices + NumIndices, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_rem_q_ind ); NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES ); @@ -724,9 +718,6 @@ Word16 Q_lsf_tcxlpc_ivas_fx( lpcorder, lpcorder, indices + NumIndices, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_q ); NumIndices = add( NumIndices, TCXLPC_NUMSTAGES ); @@ -772,9 +763,6 @@ Word16 Q_lsf_tcxlpc_ivas_fx( lpcorder, lpcorder, indices + NumIndices, -#ifdef IVAS_MSVQ - 0, NULL, -#endif lsf_rem_q_ind ); NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES ); -- GitLab From cd5178b3818c86d3bd2b1668cb03ec2ffd9da4cb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 16 May 2025 08:59:14 +0530 Subject: [PATCH 1215/1221] Fix for 3GPP issue 1583: Very high MLD for ParamMC 5.1+4 at 96kbps 16kHz input Link #1583 --- lib_enc/ivas_mc_param_enc_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/ivas_mc_param_enc_fx.c b/lib_enc/ivas_mc_param_enc_fx.c index 3058f87f3..7f74f78f9 100644 --- a/lib_enc/ivas_mc_param_enc_fx.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -768,8 +768,8 @@ static void ivas_param_mc_param_est_enc_fx( #endif #ifdef MERGE_REQUEST_1378_SPEEDUP_ivas_mc_param_enc_fx_NONBE - sub35gb = sub( 35, find_guarded_bits_fx( l_ts ) ); - sub62gb = sub( 62, find_guarded_bits_fx( l_ts ) ); + sub35gb = sub( 32, sub( 11, find_guarded_bits_fx( l_ts ) ) ); // 31 - (((11 - gb) + 31 + norm) - 32) + sub62gb = sub( 63, shl( sub( 11, find_guarded_bits_fx( l_ts ) ), 1 ) ); // 31 - ((2*(11 - gb) + norm) - 32) #endif FOR( ts = start_ts; ts < num_time_slots; ts++ ) -- GitLab From 4ed5935ef4fe8baca2b1119da638f3ad497fbdb1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 15 May 2025 17:49:55 +0530 Subject: [PATCH 1216/1221] Fix for 3GPP issue 1517: SBA Decoder: Differences for binaural rendered signals at 64 kbit/s Link #1517 --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 16fefa3bb..e7881ba53 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1265,12 +1265,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric temp64 = W_add( W_mult0_32_32( tempRe, tempRe ), W_mult0_32_32( tempIm, tempIm ) ); // 2q exp1 = W_norm( temp64 ); temp64 = W_shl( temp64, exp1 ); // 2q + exp1 - subFrameSumEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameSumEne_fx[bin], subFrameTotalEne_e[bin], W_extract_h( temp64 ), sub( exp /* 63 - 2q */, exp1 ) /*31 - (2q + exp1 - 32)*/, &subFrameTotalEne_e[bin] ); + subFrameSumEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameSumEne_fx[bin], subFrameSumEne_e[bin], W_extract_h( temp64 ), sub( exp /* 63 - 2q */, exp1 ) /*31 - (2q + exp1 - 32)*/, &subFrameSumEne_e[bin] ); move32(); } } FOR( bin = 0; bin < nBins; bin++ ) { + subFrameTotalEne_e[bin] = sub( subFrameTotalEne_e[bin], 1 ); + move16(); temp = L_shl_sat( subFrameTotalEne_fx[bin], sub( subFrameTotalEne_e[bin], subFrameSumEne_e[bin] ) ); // subFrameSumEne_e[bin] IF( GT_32( subFrameSumEne_fx[bin], temp ) ) { -- GitLab From 8b3835aed14dd4a3aa0d3436db146b0a3fb1f8f7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 16 May 2025 12:26:14 +0530 Subject: [PATCH 1217/1221] Fix for 3GPP issue 1469: Somewhat high MLD on a single MASA selection test material case with BASOP decoder Link #1469 --- lib_com/prot_fx.h | 2 +- lib_com/stat_noise_uv_mod_fx.c | 58 +++++++++++++++++++--------------- lib_dec/acelp_core_dec_fx.c | 6 ++++ lib_dec/stat_noise_uv_dec_fx.c | 2 +- lib_enc/acelp_core_enc_fx.c | 5 +-- lib_enc/prot_fx_enc.h | 2 +- lib_enc/stat_noise_uv_enc_fx.c | 2 +- 7 files changed, 45 insertions(+), 32 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 6d3e28de2..a1e633c17 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -8234,7 +8234,7 @@ void stat_noise_uv_mod_ivas_fx( const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr Q=15*/ Word16 *Aq, /* o : A(z) quantized for the 4 subframes Q=12*/ Word16 *exc2, /* i/o: excitation buffer Q=Q_exc*/ - Word16 Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ + Word16 *Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ const Word16 bfi, /* i : Bad frame indicator */ Word32 *ge_sm, /* i/o: smoothed excitation gain Q=Q_stat_noise_ge (6)*/ Word16 *uv_count, /* i/o: unvoiced counter */ diff --git a/lib_com/stat_noise_uv_mod_fx.c b/lib_com/stat_noise_uv_mod_fx.c index 67ca21cd2..c259745f2 100644 --- a/lib_com/stat_noise_uv_mod_fx.c +++ b/lib_com/stat_noise_uv_mod_fx.c @@ -330,7 +330,6 @@ void stat_noise_uv_mod_fx( } } } - /*--------------------------------------------------------------------* * stat_noise_uv_mod() * @@ -345,7 +344,7 @@ void stat_noise_uv_mod_ivas_fx( const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr Q=15*/ Word16 *Aq, /* o : A(z) quantized for the 4 subframes Q=12*/ Word16 *exc2, /* i/o: excitation buffer Q=Q_exc*/ - Word16 Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ + Word16 *Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ const Word16 bfi, /* i : Bad frame indicator */ Word32 *ge_sm, /* i/o: smoothed excitation gain Q=Q_stat_noise_ge (6)*/ Word16 *uv_count, /* i/o: unvoiced counter */ @@ -370,8 +369,9 @@ void stat_noise_uv_mod_ivas_fx( Word16 oldlsp_mix[M]; Word16 midlsp_mix[M]; Word16 newlsp_mix[M]; - Word16 beta; /* Q15 */ - Word16 Noimix_fract; /* (noimix_fac - 1.0) in Q15 */ + Word16 beta; /* Q15 */ + Word16 Noimix_fract; /* (noimix_fac - 1.0) in Q15 */ + Word32 L_Noimix_fract; /* (noimix_fac - 1.0) in Q15 */ /* noimix_fax * x <-> x + Noimix_fract * x */ Word16 i_subfr; Word16 i, k; @@ -382,7 +382,8 @@ void stat_noise_uv_mod_ivas_fx( Word32 L_tmp_res, L_tmp, L_tmp3, L_Ge; Word16 En_shift, Tmp; - Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/ + Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/ + Word32 L_Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/ #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -437,9 +438,9 @@ void stat_noise_uv_mod_ivas_fx( Copy( exc2, Exc2_local, L_FRAME ); /* bound Q for internal use, optimization possible */ - Q_local = s_min( 11, s_max( -1, Q_exc ) ); + Q_local = s_min( 11, s_max( -1, *Q_exc ) ); /* local excitation Q and incoming excitation Q*/ - Qdiff = sub( Q_local, Q_exc ); + Qdiff = sub( Q_local, *Q_exc ); /* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */ Scale_sig( Exc2_local, L_FRAME, Qdiff ); /* current excitation Q and previous stat_noise states Q */ @@ -539,14 +540,11 @@ void stat_noise_uv_mod_ivas_fx( L_tmp_res = L_mac( 0, alpha, alpha ); L_tmp_res = L_mac( L_tmp_res, alpha_m1, alpha_m1 ); tmp_den = round_fx( L_Frac_sqrtQ31( L_tmp_res ) ); - - tmp_nom = sub( 32767, tmp_den ); - tmp_shift = norm_s( tmp_den ); - tmp_den = shl( tmp_den, tmp_shift ); - tmp_res = div_s( tmp_nom, tmp_den ); - - Noimix_fract = shr( tmp_res, tmp_shift ); /* float value is in range 0.0 to 0.42 */ - + Word16 exp_sqr = 0; + move16(); + tmp_res = BASOP_Util_Divide1616_Scale( 32767, tmp_den, &exp_sqr ); // 15-exp_sqr + Noimix_fract = tmp_res; // 15-exp_sqr + move16(); /* L_Ge might be 0 in unvoiced WB */ L_Ge = L_max( L_Ge, 1 ); tmp_shift = norm_l( L_Ge ); @@ -555,9 +553,7 @@ void stat_noise_uv_mod_ivas_fx( L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */ L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */ L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */ - tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */ - - Noimix_fract = extract_l( Mult_32_16( L_tmp_res, Noimix_fract ) ); /*15+15-15 */ + L_Noimix_fract = Mult_32_16( L_tmp_res, Noimix_fract ); /*15+15-exp_sqr-15 =15-exp_sqr */ FOR( i = 0; i < L_FRAME; i++ ) { @@ -573,18 +569,27 @@ void stat_noise_uv_mod_ivas_fx( randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/ randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), sub( 1, *Q_stat_noise_ge ) ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */ - L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */ - L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */ - L_tmp3 = Mult_32_16( L_tmp, Noimix_fract ); /* Q_local+16+15-15 */ - L_tmp = L_add_sat( L_tmp3, L_shl_sat( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */ - Exc2_local[i] = extract_h( L_tmp ); /*Q_local */ + L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */ + L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */ + L_tmp3 = Mult_32_32( L_tmp, L_Noimix_fract ); /* Q_local+16+15-exp_sqr-15 =Q_local +1 */ + L_Exc2_local[i] = L_add( L_shr( L_tmp3, 1 ), Mpy_32_32( L_tmp, L_tmp_res ) ); // Q_local + 16 +15 -31 = Q_local + move32(); + } + Word32 max_val; + maximum_abs_32_fx( L_Exc2_local, L_FRAME, &max_val ); + Word16 shift = 0; + move16(); + IF( GT_32( max_val, ONE_IN_Q15 ) ) + { + shift = norm_l( max_val ); + shift = sub( Q31 - Q15, shift ); + *Q_exc = sub( Q_local, shift ); // Q_exc = Q_local -shift move16(); } *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */ move16(); - Qdiff = sub( Q_exc, Q_local ); /* local excitation and incoming excitation */ - Scale_sig( Exc2_local, L_FRAME, Qdiff ); - Copy( Exc2_local, exc2, L_FRAME ); + + Copy_Scale_sig_32_16( L_Exc2_local, exc2, L_FRAME, negate( shift ) ); // Q_exc /*--------------------------------------------------------------------* * Generate low-pass filtered version of ISP coefficients @@ -635,6 +640,7 @@ void stat_noise_uv_mod_ivas_fx( } } } + /*---------------------------------------------------------------------------* * calc_tilt() * diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 2c72bba78..2fff712f9 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1165,7 +1165,13 @@ ivas_error acelp_core_dec_fx( test(); IF( !( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) && NE_16( st->nelp_mode_dec, 1 ) && !( EQ_16( st->element_mode, IVAS_SCE ) && tdm_low_rate_mode ) ) { + Word16 temp_q_exc = st->Q_exc; + move16(); stat_noise_uv_dec_fx( st, lsp_new_fx, lsp_mid_fx, Aq_fx, exc2_fx, uc_two_stage_flag ); + IF( NE_16( temp_q_exc, st->Q_exc ) ) + { + scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM + st->L_frame, sub( st->Q_exc, temp_q_exc ) ); + } } /*------------------------------------------------------------* diff --git a/lib_dec/stat_noise_uv_dec_fx.c b/lib_dec/stat_noise_uv_dec_fx.c index d2fa36b9b..4e4d7ca30 100644 --- a/lib_dec/stat_noise_uv_dec_fx.c +++ b/lib_dec/stat_noise_uv_dec_fx.c @@ -76,7 +76,7 @@ void stat_noise_uv_dec_fx( IF( !st_fx->Opt_AMR_WB ) { - stat_noise_uv_mod_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq, exc2, st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count, &st_fx->act_count, + stat_noise_uv_mod_ivas_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq, exc2, &st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count, &st_fx->act_count, st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index ceba860a1..6ba21136e 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -1449,8 +1449,9 @@ ivas_error acelp_core_enc_ivas_fx( { /* exc2 buffer is needed only for updating of Aq[] which is needed for core switching */ Copy( exc_fx, exc2_fx, st->L_frame ); // Q_new - - stat_noise_uv_enc_ivas_fx( st, epsP, lsp_new, lsp_mid, Aq, exc2_fx, uc_two_stage_flag, Q_new ); + Word16 q_exc2 = Q_new; + move16(); + stat_noise_uv_enc_ivas_fx( st, epsP, lsp_new, lsp_mid, Aq, exc2_fx, uc_two_stage_flag, &q_exc2 ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 968ab0082..72137bdce 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -2189,7 +2189,7 @@ void stat_noise_uv_enc_ivas_fx( Word16 *Aq, /* i : A(z) quantized for the 4 subframes Q=12 */ Word16 *exc2, /* i/o: excitation buffer Q=Q_stat_noise */ const Word16 uc_two_stage_flag, /* o : flag undicating two-stage UC */ - Word16 Q_new ); + Word16 *Q_new ); void analy_sp_fx( const Word16 element_mode, /* i : element mode */ diff --git a/lib_enc/stat_noise_uv_enc_fx.c b/lib_enc/stat_noise_uv_enc_fx.c index 1445559a1..24932542c 100644 --- a/lib_enc/stat_noise_uv_enc_fx.c +++ b/lib_enc/stat_noise_uv_enc_fx.c @@ -118,7 +118,7 @@ void stat_noise_uv_enc_ivas_fx( Word16 *Aq, /* i : A(z) quantized for the 4 subframes Q=12 */ Word16 *exc2, /* i/o: excitation buffer Q=Q_stat_noise */ const Word16 uc_two_stage_flag, /* o : flag undicating two-stage UC */ - Word16 Q_new ) + Word16 *Q_new ) { Word16 noisiness = 0; move16(); -- GitLab From 2af7b50f076aabae91b52c2ba32beca40c9b892a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 16 May 2025 12:32:36 +0530 Subject: [PATCH 1218/1221] Clang formatting changes --- lib_com/prot_fx.h | 2 +- lib_dec/stat_noise_uv_dec_fx.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index a1e633c17..c7d35daca 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -8234,7 +8234,7 @@ void stat_noise_uv_mod_ivas_fx( const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr Q=15*/ Word16 *Aq, /* o : A(z) quantized for the 4 subframes Q=12*/ Word16 *exc2, /* i/o: excitation buffer Q=Q_exc*/ - Word16 *Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ + Word16 *Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ const Word16 bfi, /* i : Bad frame indicator */ Word32 *ge_sm, /* i/o: smoothed excitation gain Q=Q_stat_noise_ge (6)*/ Word16 *uv_count, /* i/o: unvoiced counter */ diff --git a/lib_dec/stat_noise_uv_dec_fx.c b/lib_dec/stat_noise_uv_dec_fx.c index 4e4d7ca30..e2dc1460e 100644 --- a/lib_dec/stat_noise_uv_dec_fx.c +++ b/lib_dec/stat_noise_uv_dec_fx.c @@ -77,9 +77,9 @@ void stat_noise_uv_dec_fx( IF( !st_fx->Opt_AMR_WB ) { stat_noise_uv_mod_ivas_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq, exc2, &st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count, &st_fx->act_count, - st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, - &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, - &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); + st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, + &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, + &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); } -- GitLab From 0a38b3a4e97fbdf7641bec3ca9173bf1e4131295 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 16 May 2025 14:45:18 +0530 Subject: [PATCH 1219/1221] Fix for EVS bitexactness issue --- lib_dec/stat_noise_uv_dec_fx.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib_dec/stat_noise_uv_dec_fx.c b/lib_dec/stat_noise_uv_dec_fx.c index e2dc1460e..c87e30ffe 100644 --- a/lib_dec/stat_noise_uv_dec_fx.c +++ b/lib_dec/stat_noise_uv_dec_fx.c @@ -76,10 +76,20 @@ void stat_noise_uv_dec_fx( IF( !st_fx->Opt_AMR_WB ) { - stat_noise_uv_mod_ivas_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq, exc2, &st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count, &st_fx->act_count, - st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, - &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, - &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); + IF( st_fx->element_mode > EVS_MONO ) + { + stat_noise_uv_mod_ivas_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq, exc2, &st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count, &st_fx->act_count, + st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, + &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, + &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); + } + ELSE + { + stat_noise_uv_mod_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq, exc2, st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count, &st_fx->act_count, + st_fx->lspold_s_fx, &st_fx->noimix_seed, &st_fx->min_alpha_fx, + &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, + &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); + } } -- GitLab From edf16d3595f305d00d4c2a70b2ae48b4f2b7ed93 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 16 May 2025 16:15:17 +0530 Subject: [PATCH 1220/1221] Fix for 3GPP issue 1533: Slightly high MLD for one case of MASA LTV EXT output in BASOP decoder Link #1533 --- lib_dec/ivas_stereo_cng_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 6b8a8f949..8ec147ff7 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -1368,8 +1368,8 @@ static void FindEmEs_fx( temp_q = 0; move16(); } - log_res = BASOP_Util_Log2( square_res ); - es_em_fx = Mpy_32_32( log_res, 1616107501 ); // 25+30-31 + log_res = L_add( BASOP_Util_Log2( square_res ), L_shl( temp_q, Q25 ) ); + es_em_fx = Mpy_32_32( log_res, 1616107501 /* 5 * (ln(2)/ln(10)) */ ); // 25+30-31 /* long-term estimate */ *lt_es_em_fx = L_add( Mpy_32_32( 858993459, *lt_es_em_fx ), Mpy_32_32( 1288490188, es_em_fx ) ); /* Q24 */ move32(); -- GitLab From 720708ed980a4b3b7974661673a6a13b924bedac Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 19 May 2025 11:35:14 +0530 Subject: [PATCH 1221/1221] Removal of unused float functions and replacing C datatypes with Basop Datatypes --- lib_com/bitstream.c | 66 ++--- lib_com/core_com_config.c | 6 +- lib_com/ivas_cnst.h | 8 +- lib_com/longarith.c | 4 +- lib_com/prot_fx.h | 463 +++++++++++++------------------- lib_com/tns_base.c | 82 +----- lib_com/tools.c | 195 +++----------- lib_com/tools_fx.c | 14 +- lib_dec/dec_acelp_tcx_main_fx.c | 2 +- lib_enc/acelp_core_enc_fx.c | 3 - lib_enc/evs_enc_fx.c | 2 +- lib_enc/prot_fx_enc.h | 1 - lib_enc/rom_enc.h | 1 - lib_rend/ivas_rom_rend.h | 4 - lib_rend/ivas_rom_rend_fx.c | 36 --- 15 files changed, 290 insertions(+), 597 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index d8d4563ed..385000139 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -100,7 +100,7 @@ static Word16 rate2AMRWB_IOmode( *-------------------------------------------------------------------*/ Word16 rate2EVSmode_float( const Word32 brate, /* i : bitrate */ - int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ + Word16 *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ ) { if ( is_amr_wb != NULL ) @@ -575,8 +575,8 @@ Word16 get_ivas_max_num_indices_fx( *-----------------------------------------------------------------------*/ /*! r: maximum number of indices */ -int16_t get_BWE_max_num_indices( - const int32_t extl_brate /* i : extensiona layer bitrate */ +Word16 get_BWE_max_num_indices( + const Word32 extl_brate /* i : extensiona layer bitrate */ ) { /* set the maximum number of indices in the BWE */ @@ -787,10 +787,10 @@ Word16 get_ivas_max_num_indices_metadata_fx( void move_indices( INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ - const int16_t nb_indices /* i : number of moved indices */ + const Word16 nb_indices /* i : number of moved indices */ ) { - int16_t i; + Word16 i; if ( new_ind_list < old_ind_list ) { @@ -1092,14 +1092,14 @@ ivas_error push_next_bits( *-------------------------------------------------------------------*/ /*! r: result: index of the indice in the list, -1 if not found */ -int16_t find_indice( +Word16 find_indice( BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ - const int16_t id, /* i : ID of the indice */ - uint16_t *value, /* o : value of the quantized indice */ - int16_t *nb_bits /* o : number of bits used to quantize the indice */ + const Word16 id, /* i : ID of the indice */ + UWord16 *value, /* o : value of the quantized indice */ + Word16 *nb_bits /* o : number of bits used to quantize the indice */ ) { - int16_t i; + Word16 i; for ( i = 0; i < hBstr->nb_ind_tot; i++ ) { @@ -1122,12 +1122,12 @@ int16_t find_indice( *-------------------------------------------------------------------*/ /*! r: number of deleted indices */ -uint16_t delete_indice( +UWord16 delete_indice( BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ - const int16_t id /* i : ID of the indice */ + const Word16 id /* i : ID of the indice */ ) { - int16_t i, j; + Word16 i, j; j = 0; for ( i = 0; i < hBstr->nb_ind_tot; i++ ) @@ -1168,14 +1168,14 @@ uint16_t delete_indice( *-------------------------------------------------------------------*/ /*! r: value of the indice */ -uint16_t get_next_indice( +UWord16 get_next_indice( Decoder_State *st, /* i/o: decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ) { - uint16_t value; - int16_t i; - int32_t nbits_total; + UWord16 value; + Word16 i; + Word32 nbits_total; assert( nb_bits <= 16 ); @@ -1207,11 +1207,11 @@ uint16_t get_next_indice( *-------------------------------------------------------------------*/ /*! r: value of the indice */ -uint16_t get_next_indice_1( +UWord16 get_next_indice_1( Decoder_State *st /* i/o: decoder state structure */ ) { - int32_t nbits_total; + Word32 nbits_total; nbits_total = st->total_brate / FRAMES_PER_SEC; /* detect corrupted bitstream */ if ( ( st->next_bit_pos + 1 > nbits_total && st->codec_mode == MODE1 ) || @@ -1233,7 +1233,7 @@ uint16_t get_next_indice_1( void get_next_indice_tmp( Decoder_State *st, /* o : decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ) { /* update the position in the bitstream */ @@ -1249,15 +1249,15 @@ void get_next_indice_tmp( *-------------------------------------------------------------------*/ /*! r: value of the indice */ -uint16_t get_indice( +UWord16 get_indice( Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos, /* i : absolute position in the bitstream (update after the read) */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ + Word16 pos, /* i : absolute position in the bitstream (update after the read) */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ) { - uint16_t value; - int16_t i; - int32_t nbits_total; + UWord16 value; + Word16 i; + Word32 nbits_total; assert( nb_bits <= 16 ); @@ -1584,9 +1584,9 @@ ivas_error write_indices_ivas_fx( *-------------------------------------------------------------------*/ static void decoder_selectCodec( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bit0 /* i : first bit */ + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bit0 /* i : first bit */ ) { /* set the AMR-WB IO flag */ @@ -1724,7 +1724,7 @@ void ivas_set_bitstream_pointers( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { - int16_t k, num_bits; + Word16 k, num_bits; Decoder_State **sts; num_bits = 0; @@ -1734,7 +1734,7 @@ void ivas_set_bitstream_pointers( { sts = st_ivas->hSCE[k]->hCoreCoder; sts[0]->bit_stream = st_ivas->bit_stream + num_bits; - num_bits += (int16_t) ( st_ivas->hSCE[k]->element_brate / FRAMES_PER_SEC ); + num_bits += (Word16) ( st_ivas->hSCE[k]->element_brate / FRAMES_PER_SEC ); } /* set bitstream pointers for CPEs */ @@ -1742,7 +1742,7 @@ void ivas_set_bitstream_pointers( { sts = st_ivas->hCPE[k]->hCoreCoder; sts[0]->bit_stream = st_ivas->bit_stream + num_bits; - num_bits += (int16_t) ( st_ivas->hCPE[k]->element_brate / FRAMES_PER_SEC ); + num_bits += (Word16) ( st_ivas->hCPE[k]->element_brate / FRAMES_PER_SEC ); } return; diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index f75f28a18..152870be7 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -492,12 +492,12 @@ Word16 sr2fscale_fx( return extract_l( Mpy_32_16_1( sr_core, FSCALE_DENOM_BY_12800_Q15 ) ); /*Q0*/ } -int16_t sr2fscale( - const int32_t sr_core /* i : internal sampling rate */ +Word16 sr2fscale( + const Word32 sr_core /* i : internal sampling rate */ ) { - return (int16_t) ( ( FSCALE_DENOM * sr_core ) / 12800 ); + return (Word16) ( ( FSCALE_DENOM * sr_core ) / 12800 ); } Word32 getCoreSamplerateMode2( diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 9243b3f50..097ba1789 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -509,8 +509,8 @@ enum #define STEREO_DFT32MS_N_NS FRAME_SIZE_NS /* 20 ms */ #define STEREO_DFT32MS_OVL_NS 3125000L /* 3.125ms - Overlap for the outer edges of windows on decoder */ #define STEREO_DFT32MS_OVL2_NS 9375000L /* 9.375ms - Overlap for the inner edges of windows on decoder */ -#define STEREO_DFT32MS_WIN_CENTER_NS ( int32_t )( ( FRAME_SIZE_NS + STEREO_DFT32MS_OVL_NS ) * 0.5f ) /* 11.5625ms - mid point of the two windows wrt the left edge of overlap */ -#define STEREO_DFT32MS_ZP_NS ( int32_t )( 0.5f * ( STEREO_DFT32MS_N_NS - STEREO_DFT32MS_WIN_CENTER_NS - ( STEREO_DFT32MS_OVL2_NS * 0.5f ) ) ) /* 2 sided zp calculated such that window size is satisfied */ +#define STEREO_DFT32MS_WIN_CENTER_NS ( Word32 )( ( FRAME_SIZE_NS + STEREO_DFT32MS_OVL_NS ) * 0.5f ) /* 11.5625ms - mid point of the two windows wrt the left edge of overlap */ +#define STEREO_DFT32MS_ZP_NS ( Word32 )( 0.5f * ( STEREO_DFT32MS_N_NS - STEREO_DFT32MS_WIN_CENTER_NS - ( STEREO_DFT32MS_OVL2_NS * 0.5f ) ) ) /* 2 sided zp calculated such that window size is satisfied */ #define STEREO_DFT32MS_OVL_MAX NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) #define STEREO_DFT32MS_OVL2_MAX NS2SA( 48000, STEREO_DFT32MS_OVL2_NS ) @@ -799,7 +799,7 @@ enum fea_names #define L_DEC_MEM_LEN_ICA L_NCSHIFTMAX + ( N_MAX_SHIFT_CHANGE + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 #define L_FRAME_DS NS2SA( CORR_INTER_FS, FRAME_SIZE_NS ) #define L_XCORRMEM_DS NS2SA( CORR_INTER_FS, 2 * ( ACELP_LOOK_NS ) ) -#define L_NCSHIFT_DS ( int16_t )( ( ( int32_t )(CORR_INTER_FS) *L_NCSHIFTMAX ) / 48000L ) +#define L_NCSHIFT_DS ( Word16 )( ( ( Word32 )(CORR_INTER_FS) *L_NCSHIFTMAX ) / 48000L ) #define L_SAMPLES_LA_NS 625000L #define L_MEM_RECALC_TBE_16K NS2SA( 16000, L_MEM_RECALC_TBE_NS ) @@ -1446,7 +1446,7 @@ typedef struct { typedef struct { Word32 value[81]; - unsigned short length[81]; + UWord16 length[81]; } HUFF_ELEMENTS; typedef struct { diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 72a763de3..c5ace652c 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -64,14 +64,14 @@ void longadd( assert( lena >= lenb ); for ( h = 0; h < lenb; h++ ) { - carry += ( (uint32_t) a[h] ) + ( (uint32_t) b[h] ); + carry += ( (UWord32) a[h] ) + ( (UWord32) b[h] ); a[h] = (UWord16) carry; carry = carry >> 16; } for ( ; h < lena; h++ ) { - carry = ( (uint32_t) a[h] ) + carry; + carry = ( (UWord32) a[h] ) + carry; a[h] = (UWord16) carry; carry = carry >> 16; } diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c7d35daca..498be3137 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -72,9 +72,6 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif -#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) -#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) - #ifndef ABSVAL #define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) #endif @@ -1576,19 +1573,19 @@ Word16 gsc_gainQ_fx( ); Word16 gsc_gainQ_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ const Word16 y_gain4[], /* i : Energy per band */ // Q12 Word16 y_gainQ[], /* o : quantized energy per band */ // Q12 - const int32_t core_brate, /* i : Core rate */ - const int16_t coder_type, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t L_frame, /* i : frame length */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int32_t core_brate_inp /* i : true core bitrate */ + const Word32 core_brate, /* i : Core rate */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 L_frame, /* i : frame length */ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word32 core_brate_inp /* i : true core bitrate */ ); // frame_ener.c @@ -1779,7 +1776,7 @@ void Ener_per_band_comp_ivas_fx( const Word16 Q_exc, /* i : frame length */ const Word16 Mband, /* i : Max band */ const Word16 Eflag, /* i : flag of highest band */ - const int16_t L_frame /* i : frame length */ + const Word16 L_frame /* i : frame length */ ); void Ener_per_band_comp_ivas_fx_2( const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */ @@ -2633,7 +2630,7 @@ void Interpolate_allpass_steep_fx( void Interpolate_allpass_steep_fx32( const Word32 *in_fx, /* i : input array of size N */ Word32 *mem_fx, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ + const Word16 N, /* i : number of input samples */ Word32 *out_fx /* o : output array of size 2*N */ ); @@ -2647,7 +2644,7 @@ void interpolate_3_over_2_allpass_fx( void interpolate_3_over_2_allpass_fx32( const Word32 *input, /* i : input signal Qx */ - const int16_t len, /* i : number of input samples */ + const Word16 len, /* i : number of input samples */ Word32 *out, /* o : output signal */ Word32 *mem /* i/o: memory */ ); @@ -2931,16 +2928,16 @@ void tbe_celp_exc( ); void tbe_celp_exc_ivas( - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const Word16 L_frame_fx, /* i : Frame lenght */ - const int16_t L_subfr, /* i : subframe length */ - const Word16 i_subfr_fx, /* i : sub frame */ - const Word16 T0_fx, /* i : Integer pitch */ - const Word16 T0_frac_fx, /* i : Fractional part of the pitch */ - Word16 *error_fx, /* i/o: Error */ - Word16 *bwe_exc_fx, /* i/o: bandwitdh extension signal */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 L_frame_fx, /* i : Frame lenght */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 i_subfr_fx, /* i : sub frame */ + const Word16 T0_fx, /* i : Integer pitch */ + const Word16 T0_frac_fx, /* i : Fractional part of the pitch */ + Word16 *error_fx, /* i/o: Error */ + Word16 *bwe_exc_fx, /* i/o: bandwitdh extension signal */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ ); void flip_and_downmix_generic_fx( @@ -3159,8 +3156,8 @@ void GenSHBSynth_fx32( Word32 *shb_syn_speech_32k, /* o : output highband component */ Word32 Hilbert_Mem[], /* i/o: memory */ Word32 state_lsyn_filt_shb_local[], /* i/o: memory */ - const int16_t L_frame, /* i : ACELP frame length */ - int16_t *syn_dm_phase ); + const Word16 L_frame, /* i : ACELP frame length */ + Word16 *syn_dm_phase ); void ScaleShapedSHB_fx( const Word16 length, /* i : SHB overlap length */ @@ -3245,7 +3242,7 @@ void wb_tbe_extras_reset_synth_fx( Word16 state_lsyn_filt_shb[], Word16 state_ls #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic void elliptic_bpf_48k_generic_fx( #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 - const int16_t element_mode, + const Word16 element_mode, #endif Word16 IsUpsampled3, Word16 input_fx[], /* i : input signal Q_input_fx*/ @@ -3280,7 +3277,7 @@ void synthesise_fb_high_band_fx( Word16 Qout #ifdef FIX_1439_SPEEDUP_SIMPLIFY_elliptic_bpf_48k_generic_STAGE2 , - int16_t element_mode + Word16 element_mode #endif ); @@ -3747,8 +3744,8 @@ void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value ); -void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); -void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); +void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue ); +void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value ); /*tns_base.h*/ /** Reset TNS data. @@ -4113,8 +4110,8 @@ void cng_params_upd_ivas_fx( const Word16 element_mode, /* i : Element mode */ const Word16 bwidth /* i : Audio bandwidth */ ); -int16_t get_cng_mode( - const int32_t last_active_brate /* i : last active bitrate */ +Word16 get_cng_mode( + const Word32 last_active_brate /* i : last active bitrate */ ); // core_com_config.c @@ -4301,12 +4298,12 @@ void lpc2mdct( void lpc2mdct_2( Word16 *lpcCoeffs, - const int16_t lpcOrder, + const Word16 lpcOrder, Word16 mdct_gains_fx[], Word16 mdct_gains_e[], Word16 mdct_inv_gains_fx[], Word16 mdct_inv_gains_e[], - const int16_t length ); + const Word16 length ); void mdct_shaping( Word32 x[], @@ -4941,25 +4938,25 @@ void cb_shape_fx( // longarith.c void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ + UWord16 a[], /* i/o: vector of the length lena */ + const UWord16 b[], /* i/o: vector of the length lenb */ + const Word16 lena, /* i/o: length of vector a[] */ + const Word16 lenb /* i/o: length of vector b[] */ ); void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ + UWord16 a[], /* i : vector of the length lena */ + const Word16 b, /* i : number of bit positions to shift right */ + UWord16 d[], /* o : vector of the length lend */ + Word16 lena, /* i : length of vector a[] */ + const Word16 lend /* i : length of vector d[] */ ); void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ + const UWord16 a[], /* i : vector of the length len */ + const Word16 b, /* i : number of bit positions to shift left */ + UWord16 d[], /* o : vector of the length len */ + const Word16 len /* i : length of vector a[] and d[] */ ); void longshr( @@ -5637,7 +5634,7 @@ void enhancer_fx( void enhancer_ivas_fx( const Word16 codec_mode, /* i : flag indicating Codec Mode */ const Word32 core_brate, /* i : decoder bitrate */ - const int16_t cbk_index, /* i : */ + const Word16 cbk_index, /* i : */ const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ const Word16 coder_type, /* i : coder type */ const Word16 i_subfr, /* i : subframe number */ @@ -6398,11 +6395,11 @@ void ivas_RefineTonalComponents_fx( const PsychoacousticParameters *psychParamsCurrent ); ivas_error PsychoacousticParameters_Init( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t nBins, /* i : Number of bins (spectral lines) */ - const int8_t nBands, /* i : Number of spectrum subbands */ - const int16_t isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ - const int16_t isWarped, /* i : Flag indicating if the scale is linear or warped */ + const Word32 sr_core, /* i : sampling rate of core-coder */ + const Word16 nBins, /* i : Number of bins (spectral lines) */ + const Word8 nBands, /* i : Number of spectrum subbands */ + const Word16 isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ + const Word16 isWarped, /* i : Flag indicating if the scale is linear or warped */ PsychoacousticParameters *pPsychParams ); // TonalIMDCTconcealment_fx.c @@ -8279,17 +8276,17 @@ Word16 FEC_synchro_exc_fx( ); void decod_unvoiced_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 coder_type, /* Q0 i : coding type */ - Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ - Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ - Word16 *voice_factors_fx, /* Q15 o : voicing factors */ - Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ - Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ + const Word16 coder_type, /* Q0 i : coding type */ + Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ + Word16 *voice_factors_fx, /* Q15 o : voicing factors */ + Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ + Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ Word16 *gain_buf ); // gaus_dec_fx.c @@ -8473,10 +8470,10 @@ void mode_switch_decoder_LPD_ivas_fx( // ari_hm_dec.c -int16_t DecodeIndex( +Word16 DecodeIndex( Decoder_State *st, - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t *PeriodicityIndex ); + const Word16 Bandwidth, /* o : NB, 1: (S)WB */ + Word16 *PeriodicityIndex ); Word16 DecodeIndex_fx( Decoder_State *st, @@ -8553,7 +8550,7 @@ void IGFSCFDecoderReset( void IGFSCFDecoderDecode( IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ Decoder_State *st, /* i/o: pointer to decoder state */ - int16_t *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ + Word16 *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ const Word16 igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ const Word16 indepFlag /* i : if 1 on input the decoder will be forced to reset, if 0 on input the decoder will be forced to encode without a reset */ @@ -8681,11 +8678,11 @@ Word16 DecodeTnsData_ivas_fx( // parametr_bitmapping.c using ivas void GetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nParams, + const Word16 nParams, void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ); + Word16 **pStream, + Word16 *pnSize, + Word16 *pnBits ); void GetParameters_fx( ParamsBitMap const *paramsBitMap, @@ -8705,10 +8702,10 @@ void EncodeTnsData_ivas_fx( void SetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nParams, + const Word16 nParams, void *pParameter, - const int16_t **pStream, - int16_t *pnSize ); + const Word16 **pStream, + Word16 *pnSize ); void SetParameters_fx( ParamsBitMap const *paramsBitMap, @@ -8719,18 +8716,18 @@ void SetParameters_fx( void WriteToBitstream( ParamsBitMap const *paramsBitMap, - const int16_t nParams, - const int16_t **pStream, - int16_t *pnSize, + const Word16 nParams, + const Word16 **pStream, + Word16 *pnSize, BSTR_ENC_HANDLE hBstr, - int16_t *pnBits ); + Word16 *pnBits ); void ReadFromBitstream( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, Decoder_State *st, - int16_t **pStream, - int16_t *pnSize ); + Word16 **pStream, + Word16 *pnSize ); void ReadFromBitstream_fx( ParamsBitMap const *paramsBitMap, @@ -9289,7 +9286,7 @@ void v_add_fx( const Word32 x1[], /* i : Input vector 1 */ const Word32 x2[], /* i : Input vector 2 */ Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ + const Word16 N /* i : Vector length */ ); void v_shr_16( @@ -9343,10 +9340,10 @@ void configureCldfb_ivas_fx( ); // dec4t64.c void dec_acelp_fast_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t cdk_index, /* i : codebook index */ - Word16 code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 cdk_index, /* i : codebook index */ + Word16 code[], /* o : algebraic (fixed) codebook excitation */ + const Word16 L_subfr /* i : subframe length */ ); // codec_tcx_common.c void tcx5SpectrumInterleaving_fx( @@ -9384,7 +9381,7 @@ void cldfbAnalysis_ivas_fx( const Word32 *timeIn_fx, /* i : time buffer Qx */ Word32 **realBuffer_fx, /* o : real value buffer Qx - 5*/ Word32 **imagBuffer_fx, /* o : imag value buffer QX - 5*/ - const int16_t samplesToProcess, /* i : samples to process */ + const Word16 samplesToProcess, /* i : samples to process */ HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ ); @@ -9403,7 +9400,7 @@ void cldfbSynthesis_ivas_fx( // bass_psfilter.c void addBassPostFilter_ivas_fx( const Word32 *harm_timeIn_fx, - const int16_t samplesToProcess, + const Word16 samplesToProcess, Word32 **rAnalysis_fx, Word32 **iAnalysis_fx, HANDLE_CLDFB_FILTER_BANK cldfb ); @@ -9563,8 +9560,8 @@ void fd_bwe_dec_init_fx( void stereo_dft_dec_open( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t nchan_transport /* i : number of transport channels */ + const Word32 output_Fs, /* i : output sampling rate */ + const Word16 nchan_transport /* i : number of transport channels */ ); void ivas_bw_switching_pre_proc_fx( @@ -10260,8 +10257,8 @@ void dctT2_N_apply_matrix_fx( ); Word32 sum2_f_32_fx( - const Word32 *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ + const Word32 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ Word16 gb ); Word32 sum2_32_fx( @@ -10411,10 +10408,10 @@ void generate_stereo_masking_noise_fx( Word16 Q_syn, Decoder_State *st, /* i/o: decoder state structure */ STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t fadeOut, /* i : only fade out of previous state */ + const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel */ + const Word16 fadeOut, /* i : only fade out of previous state */ STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ + const Word16 nchan_out /* i : number of output channels */ ); void SynthesisSTFT_fx( @@ -10422,10 +10419,10 @@ void SynthesisSTFT_fx( Word32 *timeDomainOutput, Word32 *olapBuffer, const Word16 *olapWin, - const int16_t tcx_transition, + const Word16 tcx_transition, HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t element_mode, /* i : element mode */ - const int16_t nchan_out /* i : number of output channels */ + const Word16 element_mode, /* i : element mode */ + const Word16 nchan_out /* i : number of output channels */ ); void FdCng_decodeSID_ivas_fx( @@ -10807,7 +10804,7 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */ const Word32 *u_fx, /* i : target signal */ const Word16 u_e, /* i : exp for target signal */ - const int16_t maxC_st1, /* i : number of candidates in stage1 */ + const Word16 maxC_st1, /* i : number of candidates in stage1 */ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */ ); @@ -10880,69 +10877,42 @@ void WriteToBitstream_ivas_fx( * MODE1 prototypes *----------------------------------------------------------------------------------*/ -/*! r: inverse square root of input value */ -float inv_sqrt( - const float x /* i : input value */ -); - /*! r: output random value */ -int16_t own_random( - int16_t *seed /* i/o: random seed */ -); - -/*! r: sign of x (+1/-1) */ -float sign( - const float x /* i : input value of x */ +Word16 own_random( + Word16 *seed /* i/o: random seed */ ); -/*! r: logarithm2 of x */ -float log2_f( - const float x /* i : input value of x */ -); - -int16_t norm_ul_float( - uint32_t UL_var1 ); +Word16 norm_ul_float( + UWord32 UL_var1 ); /*! r: sum of all vector elements */ -int16_t sum_s( - const int16_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ +Word16 sum_s( + const Word16 *vec, /* i : input vector */ + const Word16 lvec /* i : length of input vector */ ); /*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all squared vector elements */ -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ +Word32 sum_l( + const Word32 *vec, /* i : input vector */ + const Word16 lvec /* i : length of input vector */ ); void set_c( - int8_t y[], /* i/o: Vector to set */ - const int8_t a, /* i : Value to set the vector to */ - const int32_t N /* i : Length of the vector */ + Word8 y[], /* i/o: Vector to set */ + const Word8 a, /* i : Value to set the vector to */ + const Word32 N /* i : Length of the vector */ ); void set_s( - int16_t y[], /* i/o: Vector to set */ - const int16_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ + Word16 y[], /* i/o: Vector to set */ + const Word16 a, /* i : Value to set the vector to */ + const Word16 N /* i : Lenght of the vector */ ); void set_l( - int32_t y[], /* i/o: Vector to set */ - const int32_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Length of the vector */ -); - -void set_f( - float y[], /* i/o: Vector to set */ - const float a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ + Word32 y[], /* i/o: Vector to set */ + const Word32 a, /* i : Value to set the vector to */ + const Word16 N /* i : Length of the vector */ ); void set_zero_fx( @@ -10959,52 +10929,26 @@ void set16_zero_fx( ); void set_zero( - float *vec, /* o : input vector */ - const int16_t lvec /* i : length of the vector */ + float *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ ); void mvr2r( const float x[], /* i : input vector */ float y[], /* o : output vector */ - const int16_t n /* i : vector size */ + const Word16 n /* i : vector size */ ); void mvs2s( - const int16_t x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ + const Word16 x[], /* i : input vector */ + Word16 y[], /* o : output vector */ + const Word16 n /* i : vector size */ ); void mvl2l( - const int32_t x[], /* i : input vector */ - int32_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ + const Word32 x[], /* i : input vector */ + Word32 y[], /* o : output vector */ + const Word16 n /* i : vector size */ ); Word16 maximumAbs_l( @@ -11014,63 +10958,22 @@ Word16 maximumAbs_l( ); /*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum_s( - const int16_t *vec, /* i : Input vector */ - const int16_t lvec, /* i : Vector length */ - int16_t *min_val /* o : minimum value in the input vector */ -); - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -); - -/*! r: vector mean */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: dot product of x[] and y[] */ -float dotp( - const float x[], /* i : vector x[] */ - const float y[], /* i : vector y[] */ - const int16_t n /* i : vector length */ -); - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_sub( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 - vector 2 */ - const int16_t N /* i : Vector length */ +Word16 minimum_s( + const Word16 *vec, /* i : Input vector */ + const Word16 lvec, /* i : Vector length */ + Word16 *min_val /* o : minimum value in the input vector */ ); /*! r: dequanzited gain */ float usdequant( - const int16_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ + const Word16 idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ ); void sort( - uint16_t *x, /* i/o: Vector to be sorted */ - uint16_t len /* i/o: vector length */ + UWord16 *x, /* i/o: Vector to be sorted */ + UWord16 len /* i/o: vector length */ ); void sort_l( @@ -11081,9 +10984,9 @@ void sort_l( ivas_error push_indice( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t id, /* i : ID of the indice */ - uint16_t value, /* i : value of the quantized indice */ - int16_t nb_bits /* i : number of bits used to quantize the indice */ + Word16 id, /* i : ID of the indice */ + UWord16 value, /* i : value of the quantized indice */ + Word16 nb_bits /* i : number of bits used to quantize the indice */ ); ivas_error push_next_indice( @@ -11105,8 +11008,8 @@ Word16 get_ivas_max_num_indices_fx( ); /*! r: maximum number of indices */ -int16_t get_BWE_max_num_indices( - const int32_t extl_brate /* i : extensiona layer bitrate */ +Word16 get_BWE_max_num_indices( + const Word32 extl_brate /* i : extensiona layer bitrate */ ); /*! r: maximum number of indices */ @@ -11115,9 +11018,9 @@ Word16 get_ivas_max_num_indices_metadata_fx( const Word32 ivas_total_brate /* i : IVAS total bitrate */ ); ivas_error ind_list_realloc( - INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ - const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ - Encoder_Struct *st_ivas /* i : IVAS encoder structure */ + INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ + const Word16 max_num_indices, /* i : new maximum number of allowed indices in the list */ + Encoder_Struct *st_ivas /* i : IVAS encoder structure */ ); ivas_error check_ind_list_limits( @@ -11127,44 +11030,44 @@ ivas_error check_ind_list_limits( void move_indices( INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ - const int16_t nb_indices /* i : number of moved indices */ + const Word16 nb_indices /* i : number of moved indices */ ); /*! r: index of the indice in the list, -1 if not found */ -int16_t find_indice( +Word16 find_indice( BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ - const int16_t id, /* i : ID of the indice */ - uint16_t *value, /* o : value of the quantized indice */ - int16_t *nb_bits /* o : number of bits used to quantize the indice */ + const Word16 id, /* i : ID of the indice */ + UWord16 *value, /* o : value of the quantized indice */ + Word16 *nb_bits /* o : number of bits used to quantize the indice */ ); /*! r: number of deleted indices */ -uint16_t delete_indice( +UWord16 delete_indice( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t id /* i : ID of the indice */ + const Word16 id /* i : ID of the indice */ ); /*! r: value of the indice */ -uint16_t get_next_indice( +UWord16 get_next_indice( Decoder_State *st, /* i/o: decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ); /*! r: value of the indice */ -uint16_t get_next_indice_1( +UWord16 get_next_indice_1( Decoder_State *st /* i/o: decoder state structure */ ); void get_next_indice_tmp( Decoder_State *st, /* o : decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ); /*! r: value of the indice */ -uint16_t get_indice( +UWord16 get_indice( Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos, /* i : absolute position in the bitstream */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ + Word16 pos, /* i : absolute position in the bitstream */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ); void reset_indices_dec( @@ -11173,7 +11076,7 @@ void reset_indices_dec( Word16 rate2EVSmode_float( const Word32 brate, /* i : bitrate */ - int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ + Word16 *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ ); @@ -11200,13 +11103,13 @@ void mdct_switching_dec_fx( Decoder_State *st /* i/o: decoder state structure */ ); -int16_t print_disclaimer( +Word16 print_disclaimer( FILE *fPtr ); void fft_rel( - float x[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ + float x[], /* i/o: input/output vector */ + const Word16 n, /* i : vector length */ + const Word16 m /* i : log2 of vector length */ ); void preemph_ivas_fx( @@ -11219,8 +11122,8 @@ void preemph_ivas_fx( void create_offset( UWord32 *offset_scale1, UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ); + const Word16 mode, + const Word16 prediction_flag ); void BASOP_cfft_ivas( Word32 *re, /* i/o: real part */ @@ -11465,31 +11368,31 @@ void writeTCXWindowing_fx( ); void writeLPCparam( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const int16_t param_lpc[], /* i : LPC parameters to write */ - const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ - const int16_t no_param_lpc, /* i : number of LPC parameters */ - int16_t *nbits_lpc /* o : LPC bits written */ + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 param_lpc[], /* i : LPC parameters to write */ + const Word16 bits_param_lpc[], /* i : bits per LPC parameter */ + const Word16 no_param_lpc, /* i : number of LPC parameters */ + Word16 *nbits_lpc /* o : LPC bits written */ ); -void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); -void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); -void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); -void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); +void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue ); +void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value ); +void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue ); +void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value ); -int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue ); +Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue ); -int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue ); -int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue ); +Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue ); -int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); +Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index ); -int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); -int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index ); +Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue ); void ResetTnsData_flt( STnsData *pTnsData ); @@ -11542,7 +11445,7 @@ void analysisCldfbEncoder_ivas_fx( ivas_error openCldfb_ivas( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ - const int32_t sampling_rate, /* i : sampling rate */ + const Word32 sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 82de45023..5e18430be 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -809,43 +809,19 @@ static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const /* TNS filter coefficients */ -int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ) +Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue ) { assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); } -// int16_t GetSWBTCX10TnsFilterCoeffBits_flt( const int16_t value, const int16_t index ) -//{ -// assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); -// return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); -// } - -// int16_t EncodeSWBTCX10TnsFilterCoeff_flt( const int16_t value, const int16_t index ) -//{ -// assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); -// return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); -// } - -int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ) +Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue ) { assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); } -// int16_t GetWBTCX20TnsFilterCoeffBits_flt( const int16_t value, const int16_t index ) -//{ -// assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); -// return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); -// } - -// int16_t EncodeWBTCX20TnsFilterCoeff_flt( const int16_t value, const int16_t index ) -//{ -// assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); -// return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); -// } - -int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ) +Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue ) { assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) ); return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); @@ -854,49 +830,25 @@ int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, /* TNS filter order */ -// void const *GetTnsFilterOrder_flt( void const *p, const int16_t index, int16_t *pValue ) -//{ -// *pValue = ( (STnsFilter const *) p )[index].order; -// return ( (STnsFilter const *) p )[index].coefIndex; -// } - -// void *SetTnsFilterOrder_flt( void *p, const int16_t index, const int16_t value ) -//{ -// ( (STnsFilter *) p )[index].order = value; -// return ( (STnsFilter *) p )[index].coefIndex; -// } - -// int16_t GetTnsFilterOrderBitsSWBTCX20_flt( const int16_t value, const int16_t index ) -//{ -// (void) index; -// return GetBitsFromTable( value - 1, codesTnsOrderTCX20, nTnsOrderCodes ); -// } - -// int16_t EncodeTnsFilterOrderSWBTCX20_flt( const int16_t value, const int16_t index ) -//{ -// (void) index; -// return EncodeUsingTable( value - 1, codesTnsOrderTCX20, nTnsOrderCodes ); -// } - -int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ) +Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue ) { (void) index; return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); } -int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ) +Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index ) { (void) index; return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes ); } -int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ) +Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index ) { (void) index; return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes ); } -int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ) +Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue ) { (void) index; return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); @@ -1105,42 +1057,36 @@ void *SetTnsEnabled( void *p, const Word16 index, const Word16 value ) /* Number of TNS filters */ -void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ) +void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue ) { - *pValue = (int16_t) abs( ( (STnsData const *) p )[index].nFilters ); + *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters ); return ( (STnsData const *) p )[index].filter; } -void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ) +void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value ) { - ( (STnsData *) p )[index].nFilters = (int16_t) abs( value ); + ( (STnsData *) p )[index].nFilters = (Word16) abs( value ); return ( (STnsData *) p )[index].filter; } -int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ) +Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue ) { (void) index; return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); } /* TNS on whitened spectra flag */ -void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ) +void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue ) { *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0; return NULL; } -void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ) +void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value ) { ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value; return NULL; } -// void const *GetTnsEnabledSingleFilter( void const *p, const int16_t index, int16_t *pValue ) -//{ -// *pValue = ( (STnsData const *) p )[index].nFilters != 0 ? 1 : 0; -// return ( (STnsData const *) p )[index].filter; -// } - void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue ) { move16(); diff --git a/lib_com/tools.c b/lib_com/tools.c index f7303c6f3..9166d16eb 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -47,51 +47,23 @@ *------------------------------------------------------------------*/ /*! r: output random value */ -int16_t own_random( - int16_t *seed /* i/o: random seed */ +Word16 own_random( + Word16 *seed /* i/o: random seed */ ) { - *seed = (int16_t) ( *seed * 31821L + 13849L ); + *seed = (Word16) ( *seed * 31821L + 13849L ); return ( *seed ); } /*--------------------------------------------------------------------- - * sign() + * norm_ul_float() * *---------------------------------------------------------------------*/ -/*! r: sign of x (+1/-1) */ -float sign( - const float x /* i : input value of x */ -) +Word16 norm_ul_float( UWord32 UL_var1 ) { - if ( x < 0.0f ) - { - return -1.0f; - } - else - { - return 1.0f; - } -} - -/*--------------------------------------------------------------------- - * log2_f() - * - *---------------------------------------------------------------------*/ - -/*! r: logarithm2 of x */ -float log2_f( - const float x /* i : input value of x */ -) -{ - return (float) ( log( x ) / log( 2.0f ) ); -} - -int16_t norm_ul_float( uint32_t UL_var1 ) -{ - int16_t var_out; + Word16 var_out; if ( UL_var1 == 0 ) { @@ -99,7 +71,7 @@ int16_t norm_ul_float( uint32_t UL_var1 ) } else { - for ( var_out = 0; UL_var1 < (uint32_t) 0x80000000U; var_out++ ) + for ( var_out = 0; UL_var1 < (UWord32) 0x80000000U; var_out++ ) { UL_var1 <<= 1; } @@ -118,13 +90,13 @@ int16_t norm_ul_float( uint32_t UL_var1 ) *---------------------------------------------------------------------*/ /*! r: sum of all vector elements */ -int16_t sum_s( - const int16_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ +Word16 sum_s( + const Word16 *vec, /* i : input vector */ + const Word16 lvec /* i : length of input vector */ ) { - int16_t i; - int16_t tmp; + Word16 i; + Word16 tmp; tmp = 0; for ( i = 0; i < lvec; i++ ) @@ -182,7 +154,7 @@ Word32 sum2_f_16_gb_fx( const Word16 lvec, /* i : length of input vector */ Word16 gb ) { - int16_t i; + Word16 i; Word32 tmp; tmp = 0; @@ -311,7 +283,6 @@ Word32 sum2_32_fx( /*-------------------------------------------------------------------* * set_c() * set_s() - * set_f() * set_l() * set_d() * @@ -319,12 +290,12 @@ Word32 sum2_32_fx( *-------------------------------------------------------------------*/ void set_c( - int8_t y[], /* i/o: Vector to set */ - const int8_t a, /* i : Value to set the vector to */ - const int32_t N /* i : Length of the vector */ + Word8 y[], /* i/o: Vector to set */ + const Word8 a, /* i : Value to set the vector to */ + const Word32 N /* i : Length of the vector */ ) { - int16_t i; + Word16 i; for ( i = 0; i < N; i++ ) { @@ -336,12 +307,12 @@ void set_c( void set_s( - int16_t y[], /* i/o: Vector to set */ - const int16_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Length of the vector */ + Word16 y[], /* i/o: Vector to set */ + const Word16 a, /* i : Value to set the vector to */ + const Word16 N /* i : Length of the vector */ ) { - int16_t i; + Word16 i; for ( i = 0; i < N; i++ ) { @@ -353,28 +324,12 @@ void set_s( void set_l( - int32_t y[], /* i/o: Vector to set */ - const int32_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Length of the vector */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = a; - } - - return; -} - -void set_f( - float y[], /* i/o: Vector to set */ - const float a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ + Word32 y[], /* i/o: Vector to set */ + const Word32 a, /* i : Value to set the vector to */ + const Word16 N /* i : Length of the vector */ ) { - int16_t i; + Word16 i; for ( i = 0; i < N; i++ ) { @@ -391,11 +346,11 @@ void set_f( *---------------------------------------------------------------------*/ void set_zero( - float *vec, /* o : input vector */ - const int16_t lvec /* i : length of the vector */ + float *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ ) { - int16_t i; + Word16 i; for ( i = 0; i < lvec; i++ ) { @@ -409,8 +364,6 @@ void set_zero( /*---------------------------------------------------------------------* * mvr2r() * mvs2s() - * mvr2s() - * mvs2r() * mvr2d() * mvd2r() * @@ -420,10 +373,10 @@ void set_zero( void mvr2r( const float x[], /* i : input vector */ float y[], /* o : output vector */ - const int16_t n /* i : vector size */ + const Word16 n /* i : vector size */ ) { - int16_t i; + Word16 i; if ( n <= 0 ) { @@ -450,12 +403,12 @@ void mvr2r( } void mvs2s( - const int16_t x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ + const Word16 x[], /* i : input vector */ + Word16 y[], /* o : output vector */ + const Word16 n /* i : vector size */ ) { - int16_t i; + Word16 i; if ( n <= 0 ) { @@ -482,12 +435,12 @@ void mvs2s( } void mvl2l( - const int32_t x[], /* i : input vector */ - int32_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ + const Word32 x[], /* i : input vector */ + Word32 y[], /* o : output vector */ + const Word16 n /* i : vector size */ ) { - int16_t i; + Word16 i; if ( n <= 0 ) { @@ -687,32 +640,6 @@ Word16 minimum_l( return ind; } -/*---------------------------------------------------------------------* - * dotp() - * - * Dot product of vector x[] and vector y[] - *---------------------------------------------------------------------*/ - -/*! r: dot product of x[] and y[] */ -float dotp( - const float x[], /* i : vector x[] */ - const float y[], /* i : vector y[] */ - const int16_t n /* i : vector length */ -) -{ - int16_t i; - float suma; - - suma = x[0] * y[0]; - - for ( i = 1; i < n; i++ ) - { - suma += x[i] * y[i]; - } - - return suma; -} - /*---------------------------------------------------------------------* * dotp() * @@ -800,20 +727,6 @@ Word32 dotp_fixed_32( return W_extract_l( suma ); } -/*---------------------------------------------------------------------* - * inv_sqrt() - * - * Find the inverse square root of the input value - *---------------------------------------------------------------------*/ - -/*! r: inverse square root of input value */ -float inv_sqrt( - const float x /* i : input value */ -) -{ - return (float) ( 1.0 / sqrt( x ) ); -} - /*-------------------------------------------------------------------* * v_add_w64() * @@ -839,32 +752,8 @@ void v_add_w64( return; } - -/*-------------------------------------------------------------------* - * v_sub() - * - * Subtraction of two vectors sample by sample - *-------------------------------------------------------------------*/ - -void v_sub( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 - vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] - x2[i]; - } - - return; -} - /*-------------------------------------------------------------------* - * v_sub() + * v_sub_fixed() * * Subtraction of two vectors sample by sample *-------------------------------------------------------------------*/ @@ -977,9 +866,9 @@ void v_multc_fixed_16_16( *-------------------------------------------------------------------*/ float usdequant( - const int16_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ + const Word16 idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ ) { float g; diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 14a97a034..77e779efd 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -241,9 +241,9 @@ void fix2f_16( Word16 *var_fix, float *var_flt, Word32 expo ) #undef WMC_TOOL_SKIP -int16_t norm_ul( uint32_t UL_var1 ) +Word16 norm_ul( UWord32 UL_var1 ) { - int16_t var_out; + Word16 var_out; if ( UL_var1 == 0 ) { @@ -251,7 +251,7 @@ int16_t norm_ul( uint32_t UL_var1 ) } else { - for ( var_out = 0; UL_var1 < (uint32_t) 0x80000000U; var_out++ ) + for ( var_out = 0; UL_var1 < (UWord32) 0x80000000U; var_out++ ) { UL_var1 <<= 1; } @@ -997,7 +997,7 @@ void scale_sig( } /*---------------------------------------------------------------------* - * mean() + * mean_fx() * *---------------------------------------------------------------------*/ Word16 mean_fx( /* o : mean of vector */ @@ -2171,7 +2171,7 @@ Word16 own_random2_fx( Word16 seed ) } /*--------------------------------------------------------------------- - * sign() + * sign_fx() * *---------------------------------------------------------------------*/ @@ -4207,7 +4207,7 @@ Word16 lin_interp_ivas_fx( } /*--------------------------------------------------------------------- - * sign() + * sign_l() * *---------------------------------------------------------------------*/ @@ -4245,7 +4245,7 @@ void v_mult16_fixed( } /*---------------------------------------------------------------------* - * set_zero() + * set_zero_fx() * * Set a vector vec[] of dimension lvec to zero *---------------------------------------------------------------------*/ diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c index 21bf7cf12..eea558914 100644 --- a/lib_dec/dec_acelp_tcx_main_fx.c +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -364,7 +364,7 @@ Word16 dec_acelp_tcx_frame_fx( { /* Copy back parameters from previous frame, because there is a high risk they are corrupt * DO concealment with configuration used in previous frame */ - st->m_frame_type = (uint8_t) m_frame_type; + st->m_frame_type = (UWord8) m_frame_type; move16(); st->bwidth = bwidth; move16(); diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 6ba21136e..f942a19ff 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -38,7 +38,6 @@ ivas_error acelp_core_enc_fx( Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ Word16 *unbits_fx, /* o : number of unused bits Q0*/ STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new, const Word16 shift ) { @@ -107,8 +106,6 @@ ivas_error acelp_core_enc_fx( * Initialization *------------------------------------------------------------------*/ - (void) tdm_lsfQ_PCh; - Es_pred_fx = 0; move16(); diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index 624ec20fc..8e9a82378 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -269,7 +269,7 @@ ivas_error evs_enc_fx( IF( EQ_16( st->core, ACELP_CORE ) ) { acelp_core_enc_fx( st, inp, ener, A, Aw, epsP_h, epsP_l, lsp_new, lsp_mid, vad_hover_flag, - attack_flag, bwe_exc_extended, voice_factors, old_syn_12k8_16k, pitch_buf, &unbits, NULL, NULL, Q_new, shift ); + attack_flag, bwe_exc_extended, voice_factors, old_syn_12k8_16k, pitch_buf, &unbits, NULL, Q_new, shift ); } /*---------------------------------------------------------------------* * HQ core encoding diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 72137bdce..d3528370f 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -61,7 +61,6 @@ ivas_error acelp_core_enc_fx( Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ Word16 *unbits_fx, /* o : number of unused bits Q0*/ STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new, const Word16 shift diff --git a/lib_enc/rom_enc.h b/lib_enc/rom_enc.h index 35fd3027d..7da1da92a 100644 --- a/lib_enc/rom_enc.h +++ b/lib_enc/rom_enc.h @@ -52,7 +52,6 @@ extern const Word16 W_HIST_S_FX[DTX_HIST_SIZE]; /* CNG & DTX - table for calcula extern const Word16 bwd_start_bin[]; // Q0 extern const Word16 bwd_end_bin[]; // Q0 -extern const float h_fir[]; /* 2nd order fir filter for wsp, decimation by 2 */ extern const Word16 h_fir_fx[]; /* 2nd order fir filter for wsp, decimation by 2 Q15*/ extern const Word16 preemphCompensation_fx[]; // Q11 diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index f62440749..7f9cfb57a 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -121,10 +121,6 @@ extern const Word32 ivas_reverb_default_fc_fx[]; /*Q-16*/ extern const Word32 ivas_reverb_default_RT60_fx[]; /*Q-26*/ extern const Word32 ivas_reverb_default_DSR_fx[]; /*Q-30*/ -extern const float ivas_reverb_default_fc[]; -extern const float ivas_reverb_default_RT60[]; -extern const float ivas_reverb_default_DSR[]; - extern const Word32 release_cnst_table[4][201]; // Q31 /*----------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_rom_rend_fx.c b/lib_rend/ivas_rom_rend_fx.c index 4f101582c..d14be4afe 100644 --- a/lib_rend/ivas_rom_rend_fx.c +++ b/lib_rend/ivas_rom_rend_fx.c @@ -561,42 +561,6 @@ const Word32 ivas_reverb_default_DSR_fx[IVAS_REVERB_DEFAULT_N_BANDS] /*Q30*/ = 66, 30, 28 }; -const float ivas_reverb_default_fc[IVAS_REVERB_DEFAULT_N_BANDS] = -{ - 20.0f, 25.0f, 31.5f, 40.0f, - 50.0f, 63.0f, 80.0f, 100.0f, - 125.0f, 160.0f, 200.0f, 250.0f, - 315.0f, 400.0f, 500.0f, 630.0f, - 800.0f, 1000.0f, 1250.0f, 1600.0f, - 2000.0f, 2500.0f, 3150.0f, 4000.0f, - 5000.0f, 6300.0f, 8000.0f, 10000.0f, - 12500.0f, 16000.0f, 20000.0f -}; - -const float ivas_reverb_default_RT60[IVAS_REVERB_DEFAULT_N_BANDS] = -{ - 1.3622f, 1.4486f, 1.3168f, 1.5787f, - 1.4766f, 1.3954f, 1.2889f, 1.3462f, - 1.0759f, 1.0401f, 1.097f, 1.085f, - 1.091f, 1.0404f, 1.0499f, 1.0699f, - 1.1028f, 1.1714f, 1.1027f, 1.0666f, - 1.055f, 1.0553f, 1.0521f, 1.0569f, - 1.0421f, 0.97822f, 0.80487f, 0.75944f, - 0.71945f, 0.61682f, 0.60031f -}; - -const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = -{ - 1.8811e-08f, 2.1428e-08f, 1.3972e-08f, 1.51e-08f, - 1.287e-08f, 1.8747e-08f, 2.413e-08f, 3.9927e-08f, - 8.9719e-08f, 1.902e-07f, 3.702e-07f, 6.1341e-07f, - 7.1432e-07f, 6.5331e-07f, 4.6094e-07f, 5.4683e-07f, - 7.0134e-07f, 6.856e-07f, 7.114e-07f, 6.9604e-07f, - 5.2939e-07f, 5.699e-07f, 6.1773e-07f, 5.7488e-07f, - 4.7748e-07f, 2.7213e-07f, 1.3681e-07f, 1.0941e-07f, - 6.2001e-08f, 2.8483e-08f, 2.6267e-08f -}; - const Word32 release_cnst_table[4][201] = // Q31 { { -- GitLab

_n&{;fz|`1@GU;D;srF34?SE9(La!Qu{r%a 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�Ne1fd(1(o3-+fYkokZPoY{}@#5 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⪼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

2?(XMZ*hq$byJY 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%0DRm4mzn|d$=!AqK9lZt{2T`LA_{Dli^SEL7u=D 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

_n&{;fz|`1@GU;D;srF34?SE9(La!Qu{r%a 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�Ne1fd(1(o3-+fYkokZPoY{}@#5 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⪼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

2?(XMZ*hq$byJY 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%0DRm4mzn|d$=!AqK9lZt{2T`LA_{Dli^SEL7u=D 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